fix: 密码放到面板设置界面

This commit is contained in:
ssongliu 2023-02-14 18:15:10 +08:00 committed by ssongliu
parent eb2bfb80cf
commit 97c4410227
11 changed files with 176 additions and 143 deletions

View File

@ -131,7 +131,7 @@ const getTitle = (key: string) => {
case 'nginx':
return i18n.global.t('website.website');
case 'mysql':
return 'Mysql ' + i18n.global.t('menu.database');
return 'MySQL ' + i18n.global.t('menu.database');
case 'redis':
return 'Redis ' + i18n.global.t('menu.database');
}

View File

@ -256,7 +256,7 @@ export default {
backupList: 'Backup list',
backList: 'Return',
loadBackup: 'Import the backup',
setting: 'Mysql Settings',
setting: 'MySQL Settings',
remoteAccess: 'Remote access',
changePassword: 'Password change',
changePasswordHelper:

View File

@ -19,7 +19,7 @@ const databaseRouter = {
children: [
{
path: 'mysql',
name: 'Mysql',
name: 'MySQL',
component: () => import('@/views/database/mysql/index.vue'),
hidden: true,
meta: {

View File

@ -61,7 +61,7 @@ const toPage = (key: string) => {
router.push({ name: 'Website' });
}
if (key === 'database') {
router.push({ name: 'Mysql' });
router.push({ name: 'MySQL' });
}
};

View File

@ -13,7 +13,7 @@ import RouterButton from '@/components/router-button/index.vue';
const buttons = [
{
label: 'Mysql',
label: 'MySQL',
path: '/databases/mysql',
},
{

View File

@ -1,6 +1,6 @@
<template>
<div v-loading="loading">
<LayoutContent :title="'Mysql ' + $t('menu.database')">
<LayoutContent :title="'MySQL ' + $t('menu.database')">
<template #app>
<AppStatus
:app-key="'mysql'"
@ -112,7 +112,7 @@
v-if="mysqlStatus != 'Running' && !isOnSetting && mysqlIsExist && !loading"
class="mask-prompt"
>
<span style="font-size: 14px">{{ $t('commons.service.serviceNotStarted', ['Mysql']) }}</span>
<span style="font-size: 14px">{{ $t('commons.service.serviceNotStarted', ['MySQL']) }}</span>
</el-card>
<Setting ref="settingRef" style="margin-top: 20px" />

View File

@ -1,6 +1,6 @@
<template>
<div v-show="onSetting">
<LayoutContent :title="'Mysql ' + $t('database.setting')" :reload="true">
<LayoutContent :title="'MySQL ' + $t('database.setting')" :reload="true">
<template #buttons>
<el-button type="primary" :plain="activeName !== 'conf'" @click="changeTab('conf')">
{{ $t('database.confChange') }}

View File

@ -19,6 +19,16 @@
</el-input>
</el-form-item>
<el-form-item :label="$t('setting.passwd')" :rules="Rules.requiredInput" prop="password">
<el-input type="password" clearable disabled v-model="form.password">
<template #append>
<el-button icon="Setting" @click="onChangePassword">
{{ $t('commons.button.set') }}
</el-button>
</template>
</el-input>
</el-form-item>
<el-form-item :label="$t('setting.theme')" :rules="Rules.requiredSelect" prop="theme">
<el-radio-group
@change="onSave(panelFormRef, 'Theme', form.theme)"
@ -96,6 +106,7 @@
</el-form>
</template>
</LayoutContent>
<Password ref="passwordRef" />
</div>
</template>
@ -109,6 +120,7 @@ import { GlobalStore } from '@/store';
import { useI18n } from 'vue-i18n';
import { useTheme } from '@/hooks/use-theme';
import { MsgError, MsgSuccess } from '@/utils/message';
import Password from '@/views/setting/panel/password/index.vue';
const loading = ref(false);
const i18n = useI18n();
@ -120,6 +132,7 @@ type FormInstance = InstanceType<typeof ElForm>;
const form = reactive({
userName: '',
password: '',
email: '',
sessionTimeout: 0,
localTime: '',
@ -134,9 +147,12 @@ const TIME_COUNT = ref(10);
const count = ref();
const show = ref();
const passwordRef = ref();
const search = async () => {
const res = await getSettingInfo();
form.userName = res.data.userName;
form.password = '******';
form.sessionTimeout = Number(res.data.sessionTimeout);
form.localTime = res.data.localTime;
form.panelName = res.data.panelName;
@ -146,6 +162,10 @@ const search = async () => {
};
const panelFormRef = ref<FormInstance>();
const onChangePassword = () => {
passwordRef.value.acceptParams({ complexityVerification: form.complexityVerification });
};
const onSave = async (formEl: FormInstance | undefined, key: string, val: any) => {
if (!formEl) return;
const result = await formEl.validateField(key.replace(key[0], key[0].toLowerCase()), callback);

View File

@ -0,0 +1,134 @@
<template>
<div v-loading="loading">
<el-drawer v-model="passwordVisiable" :destroy-on-close="true" :close-on-click-modal="false" size="30%">
<template #header>
<DrawerHeader :header="$t('setting.changePassword')" :back="handleClose" />
</template>
<el-form ref="passFormRef" label-position="top" :model="passForm" :rules="passRules">
<el-row type="flex" justify="center">
<el-col :span="22">
<el-form-item :label="$t('setting.oldPassword')" prop="oldPassword">
<el-input type="password" show-password clearable v-model="passForm.oldPassword" />
</el-form-item>
<el-form-item
v-if="complexityVerification === 'disable'"
:label="$t('setting.newPassword')"
prop="newPassword"
>
<el-input type="password" show-password clearable v-model="passForm.newPassword" />
</el-form-item>
<el-form-item
v-if="complexityVerification === 'enable'"
:label="$t('setting.newPassword')"
prop="newPasswordComplexity"
>
<el-input
type="password"
show-password
clearable
v-model="passForm.newPasswordComplexity"
/>
</el-form-item>
<el-form-item :label="$t('setting.retryPassword')" prop="retryPassword">
<el-input type="password" show-password clearable v-model="passForm.retryPassword" />
</el-form-item>
</el-col>
</el-row>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button :disabled="loading" @click="passwordVisiable = false">
{{ $t('commons.button.cancel') }}
</el-button>
<el-button :disabled="loading" type="primary" @click="submitChangePassword(passFormRef)">
{{ $t('commons.button.confirm') }}
</el-button>
</span>
</template>
</el-drawer>
</div>
</template>
<script lang="ts" setup>
import { Rules } from '@/global/form-rules';
import i18n from '@/lang';
import router from '@/routers';
import { MsgError, MsgSuccess } from '@/utils/message';
import { FormInstance } from 'element-plus';
import { GlobalStore } from '@/store';
import { reactive, ref } from 'vue';
import { updatePassword } from '@/api/modules/setting';
const globalStore = GlobalStore();
const passFormRef = ref<FormInstance>();
const passRules = reactive({
oldPassword: [Rules.requiredInput],
newPassword: [
Rules.requiredInput,
{ min: 6, message: i18n.global.t('commons.rule.commonPassword'), trigger: 'blur' },
],
newPasswordComplexity: [Rules.requiredInput, Rules.password],
retryPassword: [Rules.requiredInput, { validator: checkPassword, trigger: 'blur' }],
});
const loading = ref(false);
const passwordVisiable = ref<boolean>(false);
const passForm = reactive({
oldPassword: '',
newPassword: '',
newPasswordComplexity: '',
retryPassword: '',
});
const complexityVerification = ref();
interface DialogProps {
complexityVerification: string;
}
const acceptParams = (params: DialogProps): void => {
complexityVerification.value = params.complexityVerification;
passForm.oldPassword = '';
passForm.newPassword = '';
passForm.newPasswordComplexity = '';
passForm.retryPassword = '';
passwordVisiable.value = true;
};
function checkPassword(rule: any, value: any, callback: any) {
let password = complexityVerification.value === 'disable' ? passForm.newPassword : passForm.newPasswordComplexity;
if (password !== passForm.retryPassword) {
return callback(new Error(i18n.global.t('commons.rule.rePassword')));
}
callback();
}
const submitChangePassword = async (formEl: FormInstance | undefined) => {
if (!formEl) return;
formEl.validate(async (valid) => {
if (!valid) return;
let password =
complexityVerification.value === 'disable' ? passForm.newPassword : passForm.newPasswordComplexity;
if (password === passForm.oldPassword) {
MsgError(i18n.global.t('setting.duplicatePassword'));
return;
}
loading.value = true;
await updatePassword({ oldPassword: passForm.oldPassword, newPassword: password })
.then(() => {
loading.value = false;
passwordVisiable.value = false;
MsgSuccess(i18n.global.t('commons.msg.operationSuccess'));
router.push({ name: 'login', params: { code: '' } });
globalStore.setLogStatus(false);
})
.catch(() => {
loading.value = false;
});
});
};
const handleClose = () => {
passwordVisiable.value = false;
};
defineExpose({
acceptParams,
});
</script>

View File

@ -6,16 +6,6 @@
<el-row>
<el-col :span="1"><br /></el-col>
<el-col :span="10">
<el-form-item :label="$t('setting.passwd')" :rules="Rules.requiredInput" prop="password">
<el-input type="password" clearable disabled v-model="form.password">
<template #append>
<el-button icon="Setting" @click="onChangePassword">
{{ $t('commons.button.set') }}
</el-button>
</template>
</el-input>
</el-form-item>
<el-form-item :label="$t('setting.panelPort')" :rules="Rules.port" prop="serverPort">
<el-input clearable v-model.number="form.serverPort">
<template #append>
@ -118,14 +108,11 @@
</el-form>
</template>
</LayoutContent>
<el-dialog
v-model="timeoutVisiable"
:destroy-on-close="true"
:close-on-click-modal="false"
:title="$t('setting.expirationTime')"
width="30%"
>
<el-form ref="timeoutFormRef" label-width="80px" label-position="left" :model="timeoutForm">
<el-drawer v-model="timeoutVisiable" :destroy-on-close="true" :close-on-click-modal="false" size="30%">
<template #header>
<DrawerHeader :header="$t('setting.expirationTime')" :back="handleClose" />
</template>
<el-form ref="timeoutFormRef" label-position="top" :model="timeoutForm">
<el-form-item :label="$t('setting.days')" prop="days" :rules="Rules.number">
<el-input clearable v-model.number="timeoutForm.days" />
<span class="input-help">{{ $t('setting.expirationHelper') }}</span>
@ -139,54 +126,7 @@
</el-button>
</span>
</template>
</el-dialog>
<el-dialog
v-model="passwordVisiable"
:destroy-on-close="true"
:close-on-click-modal="false"
:title="$t('setting.changePassword')"
width="30%"
>
<el-form
v-loading="dialogLoading"
ref="passFormRef"
label-width="80px"
label-position="left"
:model="passForm"
:rules="passRules"
>
<el-form-item :label="$t('setting.oldPassword')" prop="oldPassword">
<el-input type="password" show-password clearable v-model="passForm.oldPassword" />
</el-form-item>
<el-form-item
v-if="form.complexityVerification === 'disable'"
:label="$t('setting.newPassword')"
prop="newPassword"
>
<el-input type="password" show-password clearable v-model="passForm.newPassword" />
</el-form-item>
<el-form-item
v-if="form.complexityVerification === 'enable'"
:label="$t('setting.newPassword')"
prop="newPasswordComplexity"
>
<el-input type="password" show-password clearable v-model="passForm.newPasswordComplexity" />
</el-form-item>
<el-form-item :label="$t('setting.retryPassword')" prop="retryPassword">
<el-input type="password" show-password clearable v-model="passForm.retryPassword" />
</el-form-item>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button :disabled="dialogLoading" @click="passwordVisiable = false">
{{ $t('commons.button.cancel') }}
</el-button>
<el-button :disabled="dialogLoading" type="primary" @click="submitChangePassword(passFormRef)">
{{ $t('commons.button.confirm') }}
</el-button>
</span>
</template>
</el-dialog>
</el-drawer>
</div>
</template>
@ -195,37 +135,15 @@ import { ref, reactive, onMounted } from 'vue';
import { ElForm, ElMessageBox } from 'element-plus';
import { Setting } from '@/api/interface/setting';
import LayoutContent from '@/layout/layout-content.vue';
import { updatePassword, updateSetting, getMFA, bindMFA, getSettingInfo, updatePort } from '@/api/modules/setting';
import DrawerHeader from '@/components/drawer-header/index.vue';
import { updateSetting, getMFA, bindMFA, getSettingInfo, updatePort } from '@/api/modules/setting';
import i18n from '@/lang';
import { Rules } from '@/global/form-rules';
import { dateFormatSimple } from '@/utils/util';
import { GlobalStore } from '@/store';
import router from '@/routers';
import { MsgError, MsgSuccess } from '@/utils/message';
import { MsgSuccess } from '@/utils/message';
const loading = ref(false);
const globalStore = GlobalStore();
const passFormRef = ref<FormInstance>();
const passRules = reactive({
oldPassword: [Rules.requiredInput],
newPassword: [
Rules.requiredInput,
{ min: 6, message: i18n.global.t('commons.rule.commonPassword'), trigger: 'blur' },
],
newPasswordComplexity: [Rules.requiredInput, Rules.password],
retryPassword: [Rules.requiredInput, { validator: checkPassword, trigger: 'blur' }],
});
const dialogLoading = ref(false);
const passwordVisiable = ref<boolean>(false);
const passForm = reactive({
oldPassword: '',
newPassword: '',
newPasswordComplexity: '',
retryPassword: '',
});
const form = reactive({
password: '',
serverPort: 9999,
securityEntrance: '',
expirationDays: 0,
@ -243,7 +161,6 @@ const timeoutForm = reactive({
const search = async () => {
const res = await getSettingInfo();
form.password = '******';
form.serverPort = Number(res.data.serverPort);
form.securityEntrance = res.data.securityEntrance;
form.expirationDays = Number(res.data.expirationDays);
@ -292,14 +209,6 @@ function callback(error: any) {
return;
}
}
function checkPassword(rule: any, value: any, callback: any) {
let password = form.complexityVerification === 'disable' ? passForm.newPassword : passForm.newPasswordComplexity;
if (password !== passForm.retryPassword) {
return callback(new Error(i18n.global.t('commons.rule.rePassword')));
}
callback();
}
const onSavePort = async (formEl: FormInstance | undefined, key: string, val: any) => {
if (!formEl) return;
const result = await formEl.validateField(key.replace(key[0], key[0].toLowerCase()), callback);
@ -328,40 +237,6 @@ const onSavePort = async (formEl: FormInstance | undefined, key: string, val: an
});
});
};
const onChangePassword = async () => {
passForm.oldPassword = '';
passForm.newPassword = '';
passForm.newPasswordComplexity = '';
passForm.retryPassword = '';
passwordVisiable.value = true;
};
const submitChangePassword = async (formEl: FormInstance | undefined) => {
if (!formEl) return;
formEl.validate(async (valid) => {
if (!valid) return;
let password =
form.complexityVerification === 'disable' ? passForm.newPassword : passForm.newPasswordComplexity;
if (password === passForm.oldPassword) {
MsgError(i18n.global.t('setting.duplicatePassword'));
return;
}
dialogLoading.value = true;
await updatePassword({ oldPassword: passForm.oldPassword, newPassword: password })
.then(() => {
dialogLoading.value = false;
passwordVisiable.value = false;
MsgSuccess(i18n.global.t('commons.msg.operationSuccess'));
router.push({ name: 'login', params: { code: '' } });
globalStore.setLogStatus(false);
})
.catch(() => {
dialogLoading.value = false;
});
});
};
const handleMFA = async () => {
console.log('dawdwda');
if (form.mfaStatus === 'enable') {
@ -384,6 +259,10 @@ const handleMFA = async () => {
}
};
const handleClose = () => {
timeoutVisiable.value = false;
};
const onBind = async () => {
loading.value = true;
await bindMFA({ code: mfaCode.value, secret: otp.secret })

2
go.mod
View File

@ -5,6 +5,7 @@ go 1.18
require (
gitee.com/openeuler/go-gitee v0.0.0-20220530104019-3af895bc380c
github.com/aliyun/aliyun-oss-go-sdk v2.2.5+incompatible
github.com/antihax/optional v1.0.0
github.com/aws/aws-sdk-go v1.44.99
github.com/compose-spec/compose-go v1.6.0
github.com/creack/pty v1.1.18
@ -63,7 +64,6 @@ require (
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 // indirect
github.com/aliyun/alibaba-cloud-sdk-go v1.61.1755 // indirect
github.com/andybalholm/brotli v1.0.4 // indirect
github.com/antihax/optional v1.0.0 // indirect
github.com/cenkalti/backoff/v4 v4.1.3 // indirect
github.com/cespare/xxhash v1.1.0 // indirect
github.com/cespare/xxhash/v2 v2.1.2 // indirect