feat: 支持账号导入与强制改密
- 新增账号导入模板下载、导入校验和默认密码重置标记 - 支持管理员重置密码并在登录后强制跳转修改密码 - 管理端与用户中心接入强密码校验和密码重置流程
This commit is contained in:
@@ -1,36 +1,66 @@
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue';
|
||||
import { computed, ref, watch } from 'vue';
|
||||
import { useRoute } from 'vue-router';
|
||||
|
||||
import { Profile } from '@easyflow/common-ui';
|
||||
import { useUserStore } from '@easyflow/stores';
|
||||
|
||||
import { $t } from '#/locales';
|
||||
|
||||
import ProfileBase from './base-setting.vue';
|
||||
import ProfileNotificationSetting from './notification-setting.vue';
|
||||
import ProfilePasswordSetting from './password-setting.vue';
|
||||
import ProfileSecuritySetting from './security-setting.vue';
|
||||
|
||||
const route = useRoute();
|
||||
const userStore = useUserStore();
|
||||
|
||||
const tabsValue = ref<string>('basic');
|
||||
|
||||
const tabs = ref([
|
||||
{
|
||||
label: '基本设置',
|
||||
value: 'basic',
|
||||
const forcePasswordChange = computed(() => {
|
||||
return !!userStore.userInfo?.passwordResetRequired || route.query.force === '1';
|
||||
});
|
||||
|
||||
const tabs = computed(() => {
|
||||
if (forcePasswordChange.value) {
|
||||
return [
|
||||
{
|
||||
label: $t('settingsConfig.updatePwd'),
|
||||
value: 'password',
|
||||
},
|
||||
];
|
||||
}
|
||||
return [
|
||||
{
|
||||
label: '基本设置',
|
||||
value: 'basic',
|
||||
},
|
||||
{
|
||||
label: '安全设置',
|
||||
value: 'security',
|
||||
},
|
||||
{
|
||||
label: '修改密码',
|
||||
value: 'password',
|
||||
},
|
||||
{
|
||||
label: '新消息提醒',
|
||||
value: 'notice',
|
||||
},
|
||||
];
|
||||
});
|
||||
|
||||
watch(
|
||||
() => [route.query.force, route.query.tab, userStore.userInfo?.passwordResetRequired],
|
||||
() => {
|
||||
if (forcePasswordChange.value) {
|
||||
tabsValue.value = 'password';
|
||||
return;
|
||||
}
|
||||
tabsValue.value = (route.query.tab as string) || 'basic';
|
||||
},
|
||||
{
|
||||
label: '安全设置',
|
||||
value: 'security',
|
||||
},
|
||||
{
|
||||
label: '修改密码',
|
||||
value: 'password',
|
||||
},
|
||||
{
|
||||
label: '新消息提醒',
|
||||
value: 'notice',
|
||||
},
|
||||
]);
|
||||
{ immediate: true },
|
||||
);
|
||||
</script>
|
||||
<template>
|
||||
<Profile
|
||||
|
||||
@@ -2,48 +2,75 @@
|
||||
import type { EasyFlowFormSchema } from '#/adapter/form';
|
||||
|
||||
import { computed, ref } from 'vue';
|
||||
import { useRoute, useRouter } from 'vue-router';
|
||||
|
||||
import { ProfilePasswordSetting, z } from '@easyflow/common-ui';
|
||||
import { preferences } from '@easyflow/preferences';
|
||||
import { useUserStore } from '@easyflow/stores';
|
||||
|
||||
import { ElMessage } from 'element-plus';
|
||||
|
||||
import { api } from '#/api/request';
|
||||
import { $t } from '#/locales';
|
||||
import { useAuthStore } from '#/store';
|
||||
import { isStrongPassword } from '#/utils/password-policy';
|
||||
|
||||
const profilePasswordSettingRef = ref();
|
||||
const authStore = useAuthStore();
|
||||
const route = useRoute();
|
||||
const router = useRouter();
|
||||
const userStore = useUserStore();
|
||||
|
||||
const isForcedPasswordChange = computed(() => {
|
||||
return !!userStore.userInfo?.passwordResetRequired || route.query.force === '1';
|
||||
});
|
||||
|
||||
const formSchema = computed((): EasyFlowFormSchema[] => {
|
||||
return [
|
||||
{
|
||||
fieldName: 'oldPassword',
|
||||
label: '旧密码',
|
||||
fieldName: 'password',
|
||||
label: $t('sysAccount.oldPwd'),
|
||||
component: 'EasyFlowInputPassword',
|
||||
componentProps: {
|
||||
placeholder: '请输入旧密码',
|
||||
placeholder: $t('sysAccount.oldPwd') + $t('common.isRequired'),
|
||||
},
|
||||
},
|
||||
{
|
||||
fieldName: 'newPassword',
|
||||
label: '新密码',
|
||||
label: $t('sysAccount.newPwd'),
|
||||
component: 'EasyFlowInputPassword',
|
||||
componentProps: {
|
||||
passwordStrength: true,
|
||||
placeholder: '请输入新密码',
|
||||
placeholder: $t('sysAccount.newPwd') + $t('common.isRequired'),
|
||||
},
|
||||
renderComponentContent() {
|
||||
return {
|
||||
strengthText: () => $t('sysAccount.passwordStrongTip'),
|
||||
};
|
||||
},
|
||||
rules: z
|
||||
.string({ required_error: $t('sysAccount.newPwd') + $t('common.isRequired') })
|
||||
.min(1, { message: $t('sysAccount.newPwd') + $t('common.isRequired') })
|
||||
.refine((value) => isStrongPassword(value), {
|
||||
message: $t('sysAccount.passwordStrongTip'),
|
||||
}),
|
||||
},
|
||||
{
|
||||
fieldName: 'confirmPassword',
|
||||
label: '确认密码',
|
||||
label: $t('sysAccount.confirmPwd'),
|
||||
component: 'EasyFlowInputPassword',
|
||||
componentProps: {
|
||||
passwordStrength: true,
|
||||
placeholder: '请再次输入新密码',
|
||||
placeholder: $t('sysAccount.repeatPwd'),
|
||||
},
|
||||
dependencies: {
|
||||
rules(values) {
|
||||
const { newPassword } = values;
|
||||
return z
|
||||
.string({ required_error: '请再次输入新密码' })
|
||||
.min(1, { message: '请再次输入新密码' })
|
||||
.string({ required_error: $t('sysAccount.repeatPwd') })
|
||||
.min(1, { message: $t('sysAccount.repeatPwd') })
|
||||
.refine((value) => value === newPassword, {
|
||||
message: '两次输入的密码不一致',
|
||||
message: $t('sysAccount.notSamePwd'),
|
||||
});
|
||||
},
|
||||
triggerFields: ['newPassword'],
|
||||
@@ -52,12 +79,29 @@ const formSchema = computed((): EasyFlowFormSchema[] => {
|
||||
];
|
||||
});
|
||||
|
||||
function handleSubmit() {
|
||||
ElMessage.success('密码修改成功');
|
||||
const updateLoading = ref(false);
|
||||
async function handleSubmit(values: any) {
|
||||
updateLoading.value = true;
|
||||
try {
|
||||
const res = await api.post('/userCenter/sysAccount/updatePassword', values);
|
||||
if (res.errorCode === 0) {
|
||||
ElMessage.success($t('message.success'));
|
||||
const userInfo = await authStore.fetchUserInfo();
|
||||
if (isForcedPasswordChange.value) {
|
||||
await router.replace(
|
||||
userInfo?.homePath || preferences.app.defaultHomePath || '/',
|
||||
);
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
updateLoading.value = false;
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<template>
|
||||
<ProfilePasswordSetting
|
||||
:button-loading="updateLoading"
|
||||
:button-text="$t('button.update')"
|
||||
ref="profilePasswordSettingRef"
|
||||
class="w-1/3"
|
||||
:form-schema="formSchema"
|
||||
|
||||
Reference in New Issue
Block a user