mirror of
https://github.com/Melorise/nPanel.git
synced 2026-11-07 14:49:35 +00:00
Revert "fix: remove redundant account settings page"
This reverts commit c45ab0a487.
This commit is contained in:
@@ -50,6 +50,18 @@ const settingRouter = {
|
||||
adminOnly: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
path: 'account',
|
||||
name: 'Account',
|
||||
component: () => import('@/views/setting/account/index.vue'),
|
||||
hidden: true,
|
||||
meta: {
|
||||
parent: 'menu.settings',
|
||||
title: 'setting.user',
|
||||
activeMenu: '/settings',
|
||||
adminOnly: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
path: 'alert',
|
||||
name: 'Alert',
|
||||
|
||||
@@ -0,0 +1,183 @@
|
||||
<template>
|
||||
<div v-loading="loading">
|
||||
<LayoutContent :title="$t('setting.user')" :divider="true">
|
||||
<template #main>
|
||||
<el-row>
|
||||
<el-col :span="1"><br /></el-col>
|
||||
<el-col :xs="24" :sm="20" :md="15" :lg="12" :xl="12">
|
||||
<el-form ref="formRef" :model="form" :rules="rules" :label-position="isMobile ? 'top' : 'left'" label-width="150px">
|
||||
<input
|
||||
class="hidden-autofill-field"
|
||||
type="text"
|
||||
name="username"
|
||||
autocomplete="username"
|
||||
tabindex="-1"
|
||||
/>
|
||||
<input
|
||||
class="hidden-autofill-field"
|
||||
type="password"
|
||||
name="password"
|
||||
autocomplete="current-password"
|
||||
tabindex="-1"
|
||||
/>
|
||||
<el-form-item :label="$t('commons.login.username')" prop="name">
|
||||
<el-input v-model.trim="form.name" name="profile-name" autocomplete="username" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('setting.newPassword')" prop="password">
|
||||
<el-input
|
||||
v-model.trim="form.password"
|
||||
type="password"
|
||||
show-password
|
||||
clearable
|
||||
name="profile-new-password"
|
||||
autocomplete="new-password"
|
||||
/>
|
||||
<span class="input-help">{{ $t('setting.passwordEmptyTip') }}</span>
|
||||
</el-form-item>
|
||||
<el-form-item v-if="form.password" :label="$t('setting.oldPassword')" prop="oldPassword">
|
||||
<el-input
|
||||
v-model.trim="form.oldPassword"
|
||||
type="password"
|
||||
show-password
|
||||
clearable
|
||||
name="profile-old-password"
|
||||
autocomplete="current-password"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item v-if="form.password" :label="$t('setting.retryPassword')" prop="retryPassword">
|
||||
<el-input
|
||||
v-model.trim="form.retryPassword"
|
||||
type="password"
|
||||
show-password
|
||||
clearable
|
||||
name="profile-retry-password"
|
||||
autocomplete="new-password"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" :disabled="loading" @click="onSubmit">
|
||||
{{ $t('commons.button.save') }}
|
||||
</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</template>
|
||||
</LayoutContent>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { onMounted, reactive, ref } from 'vue';
|
||||
import { ElMessageBox, FormInstance } from 'element-plus';
|
||||
import { useRouter } from 'vue-router';
|
||||
import { Login } from '@/api/interface/auth';
|
||||
import { getUserInfo, updateUserInfo } from '@/api/modules/auth';
|
||||
import { getSettingBaseInfo } from '@/api/modules/setting';
|
||||
import { Rules } from '@/global/form-rules';
|
||||
import i18n from '@/lang';
|
||||
import { useGlobalStore } from '@/composables/useGlobalStore';
|
||||
import { MsgError, MsgSuccess } from '@/utils/message';
|
||||
|
||||
const router = useRouter();
|
||||
const { globalStore, entrance, isMobile } = useGlobalStore();
|
||||
const loading = ref(false);
|
||||
const complexityVerification = ref(false);
|
||||
const originalName = ref('');
|
||||
const formRef = ref<FormInstance>();
|
||||
const form = reactive({
|
||||
id: 0,
|
||||
name: '',
|
||||
password: '',
|
||||
oldPassword: '',
|
||||
retryPassword: '',
|
||||
});
|
||||
|
||||
const validatePassword = (_rule: unknown, value: string, callback: (error?: Error) => void) => {
|
||||
if (!value) {
|
||||
callback();
|
||||
return;
|
||||
}
|
||||
if (value.includes(' ')) {
|
||||
callback(new Error(i18n.global.t('setting.noSpace')));
|
||||
return;
|
||||
}
|
||||
if (complexityVerification.value && !/^(?![\d]+$)(?![a-zA-Z]+$)(?![^\da-zA-Z]+$).{8,30}$/.test(value)) {
|
||||
callback(new Error(i18n.global.t('commons.rule.complexityPassword')));
|
||||
return;
|
||||
}
|
||||
callback();
|
||||
};
|
||||
|
||||
const validateRepeatedPassword = (_rule: unknown, value: string, callback: (error?: Error) => void) => {
|
||||
if (value !== form.password) {
|
||||
callback(new Error(i18n.global.t('commons.rule.rePassword')));
|
||||
return;
|
||||
}
|
||||
callback();
|
||||
};
|
||||
|
||||
const rules = reactive({
|
||||
name: [Rules.requiredInput, Rules.noSpace],
|
||||
password: [{ validator: validatePassword, trigger: 'blur' }],
|
||||
oldPassword: [Rules.requiredInput],
|
||||
retryPassword: [{ validator: validateRepeatedPassword, trigger: 'blur' }],
|
||||
});
|
||||
|
||||
const load = async () => {
|
||||
loading.value = true;
|
||||
try {
|
||||
const [userRes, settingRes] = await Promise.all([getUserInfo(), getSettingBaseInfo()]);
|
||||
form.id = userRes.data.id;
|
||||
form.name = userRes.data.name;
|
||||
originalName.value = userRes.data.name;
|
||||
complexityVerification.value = settingRes.data.complexityVerification === 'Enable';
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
const onSubmit = async () => {
|
||||
if (!formRef.value) return;
|
||||
const fields = ['name', 'password'];
|
||||
if (form.password) {
|
||||
fields.push('oldPassword', 'retryPassword');
|
||||
}
|
||||
const valid = await formRef.value.validateField(fields, () => {});
|
||||
if (!valid) return;
|
||||
|
||||
const needReLogin = form.name !== originalName.value || !!form.password;
|
||||
if (!needReLogin) return;
|
||||
if (form.password && form.password === form.oldPassword) {
|
||||
MsgError(i18n.global.t('setting.duplicatePassword'));
|
||||
return;
|
||||
}
|
||||
try {
|
||||
await ElMessageBox.confirm(i18n.global.t('setting.userChangeHelper'), i18n.global.t('setting.userChange'), {
|
||||
confirmButtonText: i18n.global.t('commons.button.confirm'),
|
||||
cancelButtonText: i18n.global.t('commons.button.cancel'),
|
||||
});
|
||||
} catch {
|
||||
return;
|
||||
}
|
||||
|
||||
const request: Login.AuthInfoUpdate = {
|
||||
id: form.id,
|
||||
name: form.name,
|
||||
password: form.password,
|
||||
oldPassword: form.oldPassword,
|
||||
};
|
||||
loading.value = true;
|
||||
try {
|
||||
await updateUserInfo(request);
|
||||
MsgSuccess(i18n.global.t('commons.msg.operationSuccess'));
|
||||
globalStore.setLogStatus(false);
|
||||
globalStore.clearAuthInfo();
|
||||
await router.push({ name: 'entrance', params: { code: entrance.value } });
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
onMounted(load);
|
||||
</script>
|
||||
@@ -21,6 +21,10 @@ const buttons = computed<RouterButton[]>(() => {
|
||||
label: i18n.global.t('setting.panel'),
|
||||
path: '/settings/panel',
|
||||
},
|
||||
{
|
||||
label: i18n.global.t('setting.user'),
|
||||
path: '/settings/account',
|
||||
},
|
||||
]
|
||||
: []),
|
||||
...(globalStore.hasPermission('alert_view')
|
||||
|
||||
Reference in New Issue
Block a user