mirror of
https://gitcode.com/yangzongzhuan/RuoYi-Vue3.git
synced 2026-05-22 19:08:37 +00:00
用户密码支持自定义配置规则
This commit is contained in:
@@ -1,4 +1,5 @@
|
|||||||
import router from '@/router'
|
import router from '@/router'
|
||||||
|
import cache from '@/plugins/cache'
|
||||||
import { ElMessageBox } from 'element-plus'
|
import { ElMessageBox } from 'element-plus'
|
||||||
import { login, logout, getInfo } from '@/api/login'
|
import { login, logout, getInfo } from '@/api/login'
|
||||||
import { getToken, setToken, removeToken } from '@/utils/auth'
|
import { getToken, setToken, removeToken } from '@/utils/auth'
|
||||||
@@ -65,6 +66,7 @@ const useUserStore = defineStore(
|
|||||||
this.name = user.userName || ''
|
this.name = user.userName || ''
|
||||||
this.nickName = user.nickName || ''
|
this.nickName = user.nickName || ''
|
||||||
this.avatar = avatar
|
this.avatar = avatar
|
||||||
|
cache.session.set('pwrChrtype', res.pwdChrtype)
|
||||||
/* 初始密码提示 */
|
/* 初始密码提示 */
|
||||||
if(res.isDefaultModifyPwd) {
|
if(res.isDefaultModifyPwd) {
|
||||||
ElMessageBox.confirm('您的密码还是初始密码,请修改密码!', '安全提示', { confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning' }).then(() => {
|
ElMessageBox.confirm('您的密码还是初始密码,请修改密码!', '安全提示', { confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning' }).then(() => {
|
||||||
|
|||||||
@@ -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<string> = ref(cache.session.get('pwrChrtype') || '0')
|
||||||
|
|
||||||
|
// 各类型对应的正则、错误提示
|
||||||
|
const PWD_RULES: Record<string, { pattern: RegExp; message: string }> = {
|
||||||
|
'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
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -13,7 +13,7 @@
|
|||||||
<template #prefix><svg-icon icon-class="user" class="el-input__icon input-icon" /></template>
|
<template #prefix><svg-icon icon-class="user" class="el-input__icon input-icon" /></template>
|
||||||
</el-input>
|
</el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item prop="password">
|
<el-form-item prop="password" :rules="registerPwdValidator">
|
||||||
<el-input
|
<el-input
|
||||||
v-model="registerForm.password"
|
v-model="registerForm.password"
|
||||||
type="password"
|
type="password"
|
||||||
@@ -79,12 +79,14 @@
|
|||||||
import { ElMessageBox } from "element-plus"
|
import { ElMessageBox } from "element-plus"
|
||||||
import { getCodeImg, register } from "@/api/login"
|
import { getCodeImg, register } from "@/api/login"
|
||||||
import defaultSettings from '@/settings'
|
import defaultSettings from '@/settings'
|
||||||
|
import { usePasswordRule } from "@/utils/passwordRule"
|
||||||
import type { RegisterForm } from '@/types/api/login'
|
import type { RegisterForm } from '@/types/api/login'
|
||||||
|
|
||||||
const title = import.meta.env.VITE_APP_TITLE
|
const title = import.meta.env.VITE_APP_TITLE
|
||||||
const footerContent = defaultSettings.footerContent
|
const footerContent = defaultSettings.footerContent
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
const { proxy } = getCurrentInstance()
|
const { proxy } = getCurrentInstance()
|
||||||
|
const { registerPwdValidator } = usePasswordRule()
|
||||||
|
|
||||||
const registerForm = ref<RegisterForm>({
|
const registerForm = ref<RegisterForm>({
|
||||||
username: "",
|
username: "",
|
||||||
@@ -107,11 +109,6 @@ const registerRules = {
|
|||||||
{ required: true, trigger: "blur", message: "请输入您的账号" },
|
{ required: true, trigger: "blur", message: "请输入您的账号" },
|
||||||
{ min: 2, max: 20, message: "用户账号长度必须介于 2 和 20 之间", trigger: "blur" }
|
{ 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: [
|
confirmPassword: [
|
||||||
{ required: true, trigger: "blur", message: "请再次输入您的密码" },
|
{ required: true, trigger: "blur", message: "请再次输入您的密码" },
|
||||||
{ required: true, validator: equalToPassword, trigger: "blur" }
|
{ required: true, validator: equalToPassword, trigger: "blur" }
|
||||||
|
|||||||
@@ -123,7 +123,7 @@
|
|||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item v-if="form.userId == undefined" label="用户密码" prop="password">
|
<el-form-item v-if="form.userId == undefined" label="用户密码" prop="password" :rules="pwdValidator">
|
||||||
<el-input v-model="form.password" placeholder="请输入用户密码" type="password" maxlength="20" show-password />
|
<el-input v-model="form.password" placeholder="请输入用户密码" type="password" maxlength="20" show-password />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
@@ -187,6 +187,7 @@
|
|||||||
import TreePanel from "@/components/TreePanel/index.vue"
|
import TreePanel from "@/components/TreePanel/index.vue"
|
||||||
import ExcelImportDialog from "@/components/ExcelImportDialog/index.vue"
|
import ExcelImportDialog from "@/components/ExcelImportDialog/index.vue"
|
||||||
import UserViewDrawer from "./view.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 { changeUserStatus, listUser, resetUserPwd, delUser, getUser, updateUser, addUser, deptTreeSelect } from "@/api/system/user"
|
||||||
import type { SysUser, UserQueryParams, UserFormDataResult } from '@/types/api/system/user'
|
import type { SysUser, UserQueryParams, UserFormDataResult } from '@/types/api/system/user'
|
||||||
import type { SysRole } from '@/types/api/system/role'
|
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 router = useRouter()
|
||||||
const { proxy } = getCurrentInstance()
|
const { proxy } = getCurrentInstance()
|
||||||
|
const { pwdValidator, pwdPromptValidator } = usePasswordRule()
|
||||||
const { sys_normal_disable, sys_user_sex } = useDict("sys_normal_disable", "sys_user_sex")
|
const { sys_normal_disable, sys_user_sex } = useDict("sys_normal_disable", "sys_user_sex")
|
||||||
|
|
||||||
const userList = ref<SysUser[]>([])
|
const userList = ref<SysUser[]>([])
|
||||||
@@ -236,7 +238,6 @@ const data = reactive({
|
|||||||
rules: {
|
rules: {
|
||||||
userName: [{ required: true, message: "用户名称不能为空", trigger: "blur" }, { min: 2, max: 20, message: "用户名称长度必须介于 2 和 20 之间", trigger: "blur" }],
|
userName: [{ required: true, message: "用户名称不能为空", trigger: "blur" }, { min: 2, max: 20, message: "用户名称长度必须介于 2 和 20 之间", trigger: "blur" }],
|
||||||
nickName: [{ required: true, message: "用户昵称不能为空", 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"] }],
|
email: [{ type: "email", message: "请输入正确的邮箱地址", trigger: ["blur", "change"] }],
|
||||||
phonenumber: [{ pattern: /^1[3|4|5|6|7|8|9][0-9]\d{8}$/, message: "请输入正确的手机号码", trigger: "blur" }]
|
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) {
|
function handleResetPwd(row: SysUser) {
|
||||||
proxy.$prompt('请输入"' + row.userName + '"的新密码', "提示", {
|
proxy.$prompt(`请输入「${row.userName}」的新密码`, "重置密码", {
|
||||||
confirmButtonText: "确定",
|
confirmButtonText: "确定",
|
||||||
cancelButtonText: "取消",
|
cancelButtonText: "取消",
|
||||||
closeOnClickModal: false,
|
closeOnClickModal: false,
|
||||||
inputPattern: /^.{5,20}$/,
|
inputValidator: pwdPromptValidator
|
||||||
inputErrorMessage: "用户密码长度必须介于 5 和 20 之间",
|
|
||||||
inputValidator: (value: string) => {
|
|
||||||
if (/<|>|"|'|\||\\/.test(value)) {
|
|
||||||
return "不能包含非法字符:< > \" ' \\\ |"
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
},
|
|
||||||
}).then(({ value }: { value: string }) => {
|
}).then(({ value }: { value: string }) => {
|
||||||
resetUserPwd(row.userId!, value).then(() => {
|
resetUserPwd(row.userId!, value).then(() => {
|
||||||
proxy.$modal.msgSuccess("修改成功,新密码是:" + value)
|
proxy.$modal.msgSuccess("修改成功,新密码是:" + value)
|
||||||
|
|||||||
@@ -3,11 +3,11 @@
|
|||||||
<el-form-item label="旧密码" prop="oldPassword">
|
<el-form-item label="旧密码" prop="oldPassword">
|
||||||
<el-input v-model="user.oldPassword" placeholder="请输入旧密码" type="password" show-password />
|
<el-input v-model="user.oldPassword" placeholder="请输入旧密码" type="password" show-password />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="新密码" prop="newPassword">
|
<el-form-item label="新密码" prop="newPassword" :rules="infoPwdValidator">
|
||||||
<el-input v-model="user.newPassword" placeholder="请输入新密码" type="password" show-password />
|
<el-input v-model="user.newPassword" placeholder="请输入新密码" type="password" show-password />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="确认密码" prop="confirmPassword">
|
<el-form-item label="确认密码" prop="confirmPassword">
|
||||||
<el-input v-model="user.confirmPassword" placeholder="请确认新密码" type="password" show-password/>
|
<el-input v-model="user.confirmPassword" placeholder="请确认新密码" type="password" show-password />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
<el-button type="primary" @click="submit">保存</el-button>
|
<el-button type="primary" @click="submit">保存</el-button>
|
||||||
@@ -17,9 +17,11 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
import { usePasswordRule } from "@/utils/passwordRule"
|
||||||
import { updateUserPwd } from "@/api/system/user"
|
import { updateUserPwd } from "@/api/system/user"
|
||||||
|
|
||||||
const { proxy } = getCurrentInstance()
|
const { proxy } = getCurrentInstance()
|
||||||
|
const { infoPwdValidator } = usePasswordRule()
|
||||||
|
|
||||||
interface UserProfilePwd {
|
interface UserProfilePwd {
|
||||||
// 旧密码
|
// 旧密码
|
||||||
@@ -46,7 +48,6 @@ const equalToPassword = (rule: any, value: string, callback: (error?: Error) =>
|
|||||||
|
|
||||||
const rules = {
|
const rules = {
|
||||||
oldPassword: [{ required: true, message: "旧密码不能为空", trigger: "blur" }],
|
oldPassword: [{ required: true, message: "旧密码不能为空", trigger: "blur" }],
|
||||||
newPassword: [{ required: true, message: "新密码不能为空", trigger: "blur" }, { min: 6, max: 20, message: "长度在 6 到 20 个字符", trigger: "blur" }, { pattern: /^[^<>"'|\\]+$/, message: "不能包含非法字符:< > \" ' \\\ |", trigger: "blur" }],
|
|
||||||
confirmPassword: [{ required: true, message: "确认密码不能为空", trigger: "blur" }, { required: true, validator: equalToPassword, trigger: "blur" }]
|
confirmPassword: [{ required: true, message: "确认密码不能为空", trigger: "blur" }, { required: true, validator: equalToPassword, trigger: "blur" }]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user