From 8521290ee4a337a2093032859b512fb90fa807cb Mon Sep 17 00:00:00 2001
From: BianLzhaoMin <11485688+bianliangzhaomin123@user.noreply.gitee.com>
Date: Sun, 4 Jan 2026 10:21:30 +0800
Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E5=AF=86=E7=A0=81=E6=A0=A1?=
=?UTF-8?q?=E9=AA=8C?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/utils/validate.js | 113 ++++++++++++++++-----
src/views/system/user/index.vue | 9 +-
src/views/system/user/profile/resetPwd.vue | 92 ++++++++++-------
3 files changed, 144 insertions(+), 70 deletions(-)
diff --git a/src/utils/validate.js b/src/utils/validate.js
index 6a4c0c5..de0b290 100644
--- a/src/utils/validate.js
+++ b/src/utils/validate.js
@@ -5,30 +5,33 @@
* @returns {Boolean}
*/
export function isPathMatch(pattern, path) {
- const regexPattern = pattern.replace(/\//g, '\\/').replace(/\*\*/g, '.*').replace(/\*/g, '[^\\/]*')
- const regex = new RegExp(`^${regexPattern}$`)
- return regex.test(path)
+ const regexPattern = pattern
+ .replace(/\//g, '\\/')
+ .replace(/\*\*/g, '.*')
+ .replace(/\*/g, '[^\\/]*')
+ const regex = new RegExp(`^${regexPattern}$`)
+ return regex.test(path)
}
/**
- * 判断value字符串是否为空
+ * 判断value字符串是否为空
* @param {string} value
* @returns {Boolean}
*/
export function isEmpty(value) {
- if (value == null || value == "" || value == undefined || value == "undefined") {
- return true
- }
- return false
+ if (value == null || value == '' || value == undefined || value == 'undefined') {
+ return true
+ }
+ return false
}
/**
- * 判断url是否是http或https
+ * 判断url是否是http或https
* @param {string} url
* @returns {Boolean}
*/
export function isHttp(url) {
- return url.indexOf('http://') !== -1 || url.indexOf('https://') !== -1
+ return url.indexOf('http://') !== -1 || url.indexOf('https://') !== -1
}
/**
@@ -37,7 +40,7 @@ export function isHttp(url) {
* @returns {Boolean}
*/
export function isExternal(path) {
- return /^(https?:|mailto:|tel:)/.test(path)
+ return /^(https?:|mailto:|tel:)/.test(path)
}
/**
@@ -45,8 +48,8 @@ export function isExternal(path) {
* @returns {Boolean}
*/
export function validUsername(str) {
- const valid_map = ['admin', 'editor']
- return valid_map.indexOf(str.trim()) >= 0
+ const valid_map = ['admin', 'editor']
+ return valid_map.indexOf(str.trim()) >= 0
}
/**
@@ -54,8 +57,9 @@ export function validUsername(str) {
* @returns {Boolean}
*/
export function validURL(url) {
- const reg = /^(https?|ftp):\/\/([a-zA-Z0-9.-]+(:[a-zA-Z0-9.&%$-]+)*@)*((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9][0-9]?)(\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3}|([a-zA-Z0-9-]+\.)*[a-zA-Z0-9-]+\.(com|edu|gov|int|mil|net|org|biz|arpa|info|name|pro|aero|coop|museum|[a-zA-Z]{2}))(:[0-9]+)*(\/($|[a-zA-Z0-9.,?'\\+&%$#=~_-]+))*$/
- return reg.test(url)
+ const reg =
+ /^(https?|ftp):\/\/([a-zA-Z0-9.-]+(:[a-zA-Z0-9.&%$-]+)*@)*((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9][0-9]?)(\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3}|([a-zA-Z0-9-]+\.)*[a-zA-Z0-9-]+\.(com|edu|gov|int|mil|net|org|biz|arpa|info|name|pro|aero|coop|museum|[a-zA-Z]{2}))(:[0-9]+)*(\/($|[a-zA-Z0-9.,?'\\+&%$#=~_-]+))*$/
+ return reg.test(url)
}
/**
@@ -63,8 +67,8 @@ export function validURL(url) {
* @returns {Boolean}
*/
export function validLowerCase(str) {
- const reg = /^[a-z]+$/
- return reg.test(str)
+ const reg = /^[a-z]+$/
+ return reg.test(str)
}
/**
@@ -72,8 +76,8 @@ export function validLowerCase(str) {
* @returns {Boolean}
*/
export function validUpperCase(str) {
- const reg = /^[A-Z]+$/
- return reg.test(str)
+ const reg = /^[A-Z]+$/
+ return reg.test(str)
}
/**
@@ -81,8 +85,8 @@ export function validUpperCase(str) {
* @returns {Boolean}
*/
export function validAlphabets(str) {
- const reg = /^[A-Za-z]+$/
- return reg.test(str)
+ const reg = /^[A-Za-z]+$/
+ return reg.test(str)
}
/**
@@ -90,8 +94,9 @@ export function validAlphabets(str) {
* @returns {Boolean}
*/
export function validEmail(email) {
- const reg = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/
- return reg.test(email)
+ const reg =
+ /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/
+ return reg.test(email)
}
/**
@@ -99,7 +104,7 @@ export function validEmail(email) {
* @returns {Boolean}
*/
export function isString(str) {
- return typeof str === 'string' || str instanceof String
+ return typeof str === 'string' || str instanceof String
}
/**
@@ -107,8 +112,60 @@ export function isString(str) {
* @returns {Boolean}
*/
export function isArray(arg) {
- if (typeof Array.isArray === 'undefined') {
- return Object.prototype.toString.call(arg) === '[object Array]'
- }
- return Array.isArray(arg)
+ if (typeof Array.isArray === 'undefined') {
+ return Object.prototype.toString.call(arg) === '[object Array]'
+ }
+ return Array.isArray(arg)
+}
+
+/**
+ * 验证新密码(用于 Element UI 表单验证规则)
+ * @param {Object} rule 验证规则对象
+ * @param {string} value 密码值
+ * @param {Function} callback 回调函数
+ */
+export function validateNewPassword(rule, value, callback) {
+ if (!value) {
+ callback(new Error('密码不能为空'))
+ return
+ }
+ // 1. 检查密码长度
+ if (value.length < 8 || value.length > 16) {
+ callback(new Error('密码长度应为8至16位,且必须包含大小写字母及数字及特殊字符!'))
+ return
+ }
+ // 2. 检查密码复杂度
+ const hasUpperCase = /[A-Z]/.test(value)
+ const hasLowerCase = /[a-z]/.test(value)
+ const hasDigit = /\d/.test(value)
+ const hasSpecialChar = /[!@#$%^&*(),.?":{}|<>]/.test(value)
+ if (!hasUpperCase || !hasLowerCase || !hasDigit || !hasSpecialChar) {
+ callback(new Error('密码长度应为8至16位,且必须包含大小写字母及数字及特殊字符!'))
+ return
+ }
+ callback() // 验证成功
+}
+
+/**
+ * 同步验证新密码(用于 $prompt 的 inputValidator 等场景)
+ * @param {string} value 密码值
+ * @returns {string|boolean} 返回错误信息字符串或 true(验证通过)
+ */
+export function validateNewPasswordSync(value) {
+ if (!value) {
+ return '密码不能为空'
+ }
+ // 1. 检查密码长度
+ if (value.length < 8 || value.length > 16) {
+ return '密码长度应为8至16位,且必须包含大小写字母及数字及特殊字符!'
+ }
+ // 2. 检查密码复杂度
+ const hasUpperCase = /[A-Z]/.test(value)
+ const hasLowerCase = /[a-z]/.test(value)
+ const hasDigit = /\d/.test(value)
+ const hasSpecialChar = /[!@#$%^&*(),.?":{}|<>]/.test(value)
+ if (!hasUpperCase || !hasLowerCase || !hasDigit || !hasSpecialChar) {
+ return '密码长度应为8至16位,且必须包含大小写字母及数字及特殊字符!'
+ }
+ return true
}
diff --git a/src/views/system/user/index.vue b/src/views/system/user/index.vue
index cc2afbe..08162ae 100644
--- a/src/views/system/user/index.vue
+++ b/src/views/system/user/index.vue
@@ -531,6 +531,7 @@ import 'splitpanes/dist/splitpanes.css'
import CryptoUtil from '../../../api/crypto.js'
import ComDialog from '@/components/ComDialog/index.vue'
import ComButton from '@/components/ComButton/index.vue'
+import { validateNewPasswordSync } from '@/utils/validate'
const router = useRouter()
const appStore = useAppStore()
@@ -769,13 +770,7 @@ function handleResetPwd(row) {
confirmButtonText: '确定',
cancelButtonText: '取消',
closeOnClickModal: false,
- inputPattern: /^.{5,20}$/,
- inputErrorMessage: '用户密码长度必须介于 5 和 20 之间',
- inputValidator: (value) => {
- if (/<|>|"|'|\||\\/.test(value)) {
- return '不能包含非法字符:< > " \' \\\ |'
- }
- },
+ inputValidator: validateNewPasswordSync,
})
.then(({ value }) => {
resetUserPwd(row.userId, value).then((response) => {
diff --git a/src/views/system/user/profile/resetPwd.vue b/src/views/system/user/profile/resetPwd.vue
index 73c6b18..e26db71 100644
--- a/src/views/system/user/profile/resetPwd.vue
+++ b/src/views/system/user/profile/resetPwd.vue
@@ -1,59 +1,81 @@
-
-
-
-
-
-
-
-
-
-
-
- 保存
- 关闭
-
-
+
+
+
+
+
+
+
+
+
+
+
+ 保存
+ 关闭
+
+