diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysLoginController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysLoginController.java index caebb39727..ec02c7a7b7 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysLoginController.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysLoginController.java @@ -87,6 +87,7 @@ public class SysLoginController ajax.put("user", user); ajax.put("roles", roles); ajax.put("permissions", permissions); + ajax.put("pwdChrtype", getSysAccountChrtype()); ajax.put("isDefaultModifyPwd", initPasswordIsModify(user.getPwdUpdateDate())); ajax.put("isPasswordExpired", passwordIsExpiration(user.getPwdUpdateDate())); return ajax; @@ -104,7 +105,13 @@ public class SysLoginController List menus = menuService.selectMenuTreeByUserId(userId); return AjaxResult.success(menuService.buildMenus(menus)); } - + + // 获取用户密码自定义配置规则 + public String getSysAccountChrtype() + { + return Convert.toStr(configService.selectConfigByKey("sys.account.chrtype"), "0"); + } + // 检查初始密码是否提醒修改 public boolean initPasswordIsModify(Date pwdUpdateDate) { diff --git a/ruoyi-ui/src/store/modules/user.js b/ruoyi-ui/src/store/modules/user.js index e6439e0259..a90767108a 100644 --- a/ruoyi-ui/src/store/modules/user.js +++ b/ruoyi-ui/src/store/modules/user.js @@ -1,5 +1,6 @@ import store from '@/store' import router from '@/router' +import cache from '@/plugins/cache' import { MessageBox, } from 'element-ui' import { login, logout, getInfo } from '@/api/login' import { getToken, setToken, removeToken } from '@/utils/auth' @@ -79,6 +80,7 @@ const user = { commit('SET_NAME', user.userName) commit('SET_NICK_NAME', user.nickName) commit('SET_AVATAR', avatar) + cache.session.set('pwrChrtype', res.pwdChrtype) /* 初始密码提示 */ if(res.isDefaultModifyPwd) { MessageBox.confirm('您的密码还是初始密码,请修改密码!', '安全提示', { confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning' }).then(() => { diff --git a/ruoyi-ui/src/utils/passwordRule.js b/ruoyi-ui/src/utils/passwordRule.js new file mode 100644 index 0000000000..dd56f81c4b --- /dev/null +++ b/ruoyi-ui/src/utils/passwordRule.js @@ -0,0 +1,71 @@ +/** + * 密码强度规则 + * 根据参数 chrtype 动态生成校验规则 + * + * chrtype 说明: + * 0 - 任意字符(默认) + * 1 - 纯数字(0-9) + * 2 - 纯字母(a-z / A-Z) + * 3 - 字母 + 数字(必须同时包含) + * 4 - 字母 + 数字 + 特殊字符(必须同时包含,特殊字符:~!@#$%^&*()-=_+) + */ +import cache from '@/plugins/cache' + +// 各类型对应的正则、错误提示 +const PWD_RULES = { + '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 default { + data() { + return { + // 密码限制类型 + pwdChrType: cache.session.get('pwrChrtype') || '0' + } + }, + computed: { + // 默认密码校验 + pwdValidator() { + const rule = PWD_RULES[this.pwdChrType] || 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函数 + pwdPromptValidator() { + const rule = PWD_RULES['0'] + return (value) => { + if (!value || value.length < 6 || value.length > 20) { + return '密码长度必须介于 6 和 20 之间' + } + if (!rule.pattern.test(value)) { + return rule.message + } + } + }, + // 个人中心密码校验 + infoPwdValidator() { + const rule = PWD_RULES[this.pwdChrType] || 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' } + ] + }, + // 注册页面密码校验 + registerPwdValidator() { + 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' } + ] + } + } +} diff --git a/ruoyi-ui/src/views/register.vue b/ruoyi-ui/src/views/register.vue index 73f865f3b3..6dbfa8743b 100644 --- a/ruoyi-ui/src/views/register.vue +++ b/ruoyi-ui/src/views/register.vue @@ -7,7 +7,7 @@ - + import { getCodeImg, register } from "@/api/login" +import passwordRule from "@/utils/passwordRule" import defaultSettings from '@/settings' export default { - name: "Register", + mixins: [passwordRule], data() { - const equalToPassword = (rule, value, callback) => { - if (this.registerForm.password !== value) { - callback(new Error("两次输入的密码不一致")) - } else { - callback() - } - } return { title: process.env.VUE_APP_TITLE, footerContent: defaultSettings.footerContent, @@ -91,24 +85,31 @@ export default { code: "", uuid: "" }, - registerRules: { + loading: false, + captchaEnabled: true + } + }, + computed: { + registerRules() { + return { username: [ { 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" } + { required: true, message: "请再次输入您的密码", trigger: "blur" }, + { + validator: (rule, value, callback) => { + if (this.registerForm.password !== value) { + callback(new Error("两次输入的密码不一致")) + } else { + callback() + } + }, trigger: "blur" + } ], code: [{ required: true, trigger: "change", message: "请输入验证码" }] - }, - loading: false, - captchaEnabled: true + } } }, created() { diff --git a/ruoyi-ui/src/views/system/user/index.vue b/ruoyi-ui/src/views/system/user/index.vue index 7d3f940af1..b6fd14d835 100644 --- a/ruoyi-ui/src/views/system/user/index.vue +++ b/ruoyi-ui/src/views/system/user/index.vue @@ -1,476 +1,467 @@ - - - + + + diff --git a/ruoyi-ui/src/views/system/user/profile/resetPwd.vue b/ruoyi-ui/src/views/system/user/profile/resetPwd.vue index acfdff1dc7..edbb2275ce 100644 --- a/ruoyi-ui/src/views/system/user/profile/resetPwd.vue +++ b/ruoyi-ui/src/views/system/user/profile/resetPwd.vue @@ -1,69 +1,70 @@ - - - + + + diff --git a/sql/ry_20260321.sql b/sql/ry_20260417.sql similarity index 99% rename from sql/ry_20260321.sql rename to sql/ry_20260417.sql index 903fcaa453..bf2c1a76ad 100644 --- a/sql/ry_20260321.sql +++ b/sql/ry_20260417.sql @@ -553,6 +553,7 @@ insert into sys_config values(5, '账号自助-是否开启用户注册功能', insert into sys_config values(6, '用户登录-黑名单列表', 'sys.login.blackIPList', '', 'Y', 'admin', sysdate(), '', null, '设置登录IP黑名单限制,多个匹配项以;分隔,支持匹配(*通配、网段)'); insert into sys_config values(7, '用户管理-初始密码修改策略', 'sys.account.initPasswordModify', '1', 'Y', 'admin', sysdate(), '', null, '0:初始密码修改策略关闭,没有任何提示,1:提醒用户,如果未修改初始密码,则在登录时就会提醒修改密码对话框'); insert into sys_config values(8, '用户管理-账号密码更新周期', 'sys.account.passwordValidateDays', '0', 'Y', 'admin', sysdate(), '', null, '密码更新周期(填写数字,数据初始化值为0不限制,若修改必须为大于0小于365的正整数),如果超过这个周期登录系统时,则在登录时就会提醒修改密码对话框'); +insert into sys_config values(9, '用户管理-密码字符范围', 'sys.account.chrtype', '0', 'Y', 'admin', sysdate(), '', null, '默认任意字符范围,0任意(密码可以输入任意字符),1数字(密码只能为0-9数字),2英文字母(密码只能为a-z和A-Z字母),3字母和数字(密码必须包含字母,数字),4字母数字和特殊字符(目前支持的特殊字符包括:~!@#$%^&*()-=_+)'); -- ----------------------------