From f89993e1af360228052bd2b7fa5bf4e7cef18631 Mon Sep 17 00:00:00 2001 From: RuoYi Date: Fri, 17 Apr 2026 13:11:38 +0800 Subject: [PATCH] =?UTF-8?q?=E7=94=A8=E6=88=B7=E5=AF=86=E7=A0=81=E6=94=AF?= =?UTF-8?q?=E6=8C=81=E8=87=AA=E5=AE=9A=E4=B9=89=E9=85=8D=E7=BD=AE=E8=A7=84?= =?UTF-8?q?=E5=88=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/store/modules/user.ts | 2 + src/utils/passwordRule.ts | 73 ++++++++++++++++++++++ src/views/register.vue | 9 +-- src/views/system/user/index.vue | 16 ++--- src/views/system/user/profile/resetPwd.vue | 29 ++++----- 5 files changed, 98 insertions(+), 31 deletions(-) create mode 100644 src/utils/passwordRule.ts diff --git a/src/store/modules/user.ts b/src/store/modules/user.ts index 81ae263..8492d9b 100644 --- a/src/store/modules/user.ts +++ b/src/store/modules/user.ts @@ -1,4 +1,5 @@ import router from '@/router' +import cache from '@/plugins/cache' import { ElMessageBox } from 'element-plus' import { login, logout, getInfo } from '@/api/login' import { getToken, setToken, removeToken } from '@/utils/auth' @@ -65,6 +66,7 @@ const useUserStore = defineStore( this.name = user.userName || '' this.nickName = user.nickName || '' this.avatar = avatar + cache.session.set('pwrChrtype', res.pwdChrtype) /* 初始密码提示 */ if(res.isDefaultModifyPwd) { ElMessageBox.confirm('您的密码还是初始密码,请修改密码!', '安全提示', { confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning' }).then(() => { diff --git a/src/utils/passwordRule.ts b/src/utils/passwordRule.ts new file mode 100644 index 0000000..c333f2f --- /dev/null +++ b/src/utils/passwordRule.ts @@ -0,0 +1,73 @@ +/** + * 密码强度规则 + * 根据参数 chrtype 动态生成校验规则 + * + * chrtype 说明: + * 0 - 任意字符(默认) + * 1 - 纯数字(0-9) + * 2 - 纯字母(a-z / A-Z) + * 3 - 字母 + 数字(必须同时包含) + * 4 - 字母 + 数字 + 特殊字符(必须同时包含,特殊字符:~!@#$%^&*()-=_+) + */ + +import cache from '@/plugins/cache' + +// 密码限制类型 +const pwdChrType: Ref = ref(cache.session.get('pwrChrtype') || '0') + +// 各类型对应的正则、错误提示 +const PWD_RULES: Record = { + '0': { pattern: /^[^<>"'|\\]+$/, message: '密码不能包含非法字符:< > " \' \\ |' }, + '1': { pattern: /^[0-9]+$/, message: '密码只能为数字(0-9)' }, + '2': { pattern: /^[a-zA-Z]+$/, message: '密码只能为英文字母(a-z、A-Z)' }, + '3': { pattern: /^(?=.*[a-zA-Z])(?=.*[0-9])[a-zA-Z0-9]+$/, message: '密码必须同时包含字母和数字' }, + '4': { pattern: /^(?=.*[A-Za-z])(?=.*\d)(?=.*[~!@#$%^&*()\-=_+])[A-Za-z\d~!@#$%^&*()\-=_+]+$/, message: '密码必须同时包含字母、数字和特殊字符(~!@#$%^&*()-=_+)' } +} + +export function usePasswordRule() { + // 默认密码校验 + const pwdValidator = computed(() => { + const rule = PWD_RULES[pwdChrType.value] || PWD_RULES['0'] + return [ + { required: true, message: '密码不能为空', trigger: 'blur' }, + { min: 6, max: 20, message: '密码长度必须介于 6 和 20 之间', trigger: 'blur' }, + { pattern: rule.pattern, message: rule.message, trigger: 'blur' } + ] + }) + // 校验prompt的inputValidator函数 + const pwdPromptValidator = (value: string) => { + const rule = PWD_RULES['0'] + if (!value || value.length < 6 || value.length > 20) { + return '密码长度必须介于 6 和 20 之间' + } + if (!rule.pattern.test(value)) { + return rule.message + } + } + // 个人中心密码校验 + const infoPwdValidator = computed(() => { + const rule = PWD_RULES[pwdChrType.value] || PWD_RULES['0'] + return [ + { required: true, message: '新密码不能为空', trigger: 'blur' }, + { min: 6, max: 20, message: '新密码长度必须介于 6 和 20 之间', trigger: 'blur' }, + { pattern: rule.pattern, message: rule.message, trigger: 'blur' } + ] + }) + // 注册页面密码校验 + const registerPwdValidator = computed(() => { + const rule = PWD_RULES['0'] + return [ + { required: true, message: '请输入您的密码', trigger: 'blur' }, + { min: 6, max: 20, message: '用户密码长度必须介于 6 和 20 之间', trigger: 'blur' }, + { pattern: rule.pattern, message: rule.message, trigger: 'blur' } + ] + }) + + return { + pwdChrType, + pwdValidator, + infoPwdValidator, + pwdPromptValidator, + registerPwdValidator + } +} diff --git a/src/views/register.vue b/src/views/register.vue index f6056b0..f6c7ab7 100644 --- a/src/views/register.vue +++ b/src/views/register.vue @@ -13,7 +13,7 @@ - + ({ username: "", @@ -107,11 +109,6 @@ const registerRules = { { required: true, trigger: "blur", message: "请输入您的账号" }, { min: 2, max: 20, message: "用户账号长度必须介于 2 和 20 之间", trigger: "blur" } ], - password: [ - { required: true, trigger: "blur", message: "请输入您的密码" }, - { min: 5, max: 20, message: "用户密码长度必须介于 5 和 20 之间", trigger: "blur" }, - { pattern: /^[^<>"'|\\]+$/, message: "不能包含非法字符:< > \" ' \\\ |", trigger: "blur" } - ], confirmPassword: [ { required: true, trigger: "blur", message: "请再次输入您的密码" }, { required: true, validator: equalToPassword, trigger: "blur" } diff --git a/src/views/system/user/index.vue b/src/views/system/user/index.vue index a26f41d..6019b6a 100644 --- a/src/views/system/user/index.vue +++ b/src/views/system/user/index.vue @@ -123,7 +123,7 @@ - + @@ -187,6 +187,7 @@ import TreePanel from "@/components/TreePanel/index.vue" import ExcelImportDialog from "@/components/ExcelImportDialog/index.vue" import UserViewDrawer from "./view.vue" +import { usePasswordRule } from "@/utils/passwordRule" import { changeUserStatus, listUser, resetUserPwd, delUser, getUser, updateUser, addUser, deptTreeSelect } from "@/api/system/user" import type { SysUser, UserQueryParams, UserFormDataResult } from '@/types/api/system/user' import type { SysRole } from '@/types/api/system/role' @@ -195,6 +196,7 @@ import type { TreeSelect, TableShowColumns, AjaxResult } from '@/types/api/commo const router = useRouter() const { proxy } = getCurrentInstance() +const { pwdValidator, pwdPromptValidator } = usePasswordRule() const { sys_normal_disable, sys_user_sex } = useDict("sys_normal_disable", "sys_user_sex") const userList = ref([]) @@ -236,7 +238,6 @@ const data = reactive({ rules: { userName: [{ required: true, message: "用户名称不能为空", trigger: "blur" }, { min: 2, max: 20, message: "用户名称长度必须介于 2 和 20 之间", trigger: "blur" }], nickName: [{ required: true, message: "用户昵称不能为空", trigger: "blur" }], - password: [{ required: true, message: "用户密码不能为空", trigger: "blur" }, { min: 5, max: 20, message: "用户密码长度必须介于 5 和 20 之间", trigger: "blur" }, { pattern: /^[^<>"'|\\]+$/, message: "不能包含非法字符:< > \" ' \\\ |", trigger: "blur" }], email: [{ type: "email", message: "请输入正确的邮箱地址", trigger: ["blur", "change"] }], phonenumber: [{ pattern: /^1[3|4|5|6|7|8|9][0-9]\d{8}$/, message: "请输入正确的手机号码", trigger: "blur" }] } @@ -348,18 +349,11 @@ function handleAuthRole(row: SysUser) { /** 重置密码按钮操作 */ function handleResetPwd(row: SysUser) { - proxy.$prompt('请输入"' + row.userName + '"的新密码', "提示", { + proxy.$prompt(`请输入「${row.userName}」的新密码`, "重置密码", { confirmButtonText: "确定", cancelButtonText: "取消", closeOnClickModal: false, - inputPattern: /^.{5,20}$/, - inputErrorMessage: "用户密码长度必须介于 5 和 20 之间", - inputValidator: (value: string) => { - if (/<|>|"|'|\||\\/.test(value)) { - return "不能包含非法字符:< > \" ' \\\ |" - } - return true - }, + inputValidator: pwdPromptValidator }).then(({ value }: { value: string }) => { resetUserPwd(row.userId!, value).then(() => { proxy.$modal.msgSuccess("修改成功,新密码是:" + value) diff --git a/src/views/system/user/profile/resetPwd.vue b/src/views/system/user/profile/resetPwd.vue index 9b93387..aca7435 100644 --- a/src/views/system/user/profile/resetPwd.vue +++ b/src/views/system/user/profile/resetPwd.vue @@ -1,25 +1,27 @@