From e28a2a404e0a8394b192db1ef92b4ed7e84fba9e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E6=95=B0=E6=8D=AE=E5=B0=8F=E7=8E=8B=E5=AD=90?=
 <dataprince@163.com>
Date: Thu, 29 Feb 2024 11:05:33 +0800
Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=20=E6=AD=A3=E5=88=99?=
 =?UTF-8?q?=E5=B7=A5=E5=85=B7=E7=B1=BB=20=E5=AD=97=E7=AC=A6=E4=B8=B2?=
 =?UTF-8?q?=E6=8F=90=E5=8F=96=20=E5=AD=97=E7=AC=A6=E4=B8=B2=E6=A0=A1?=
 =?UTF-8?q?=E9=AA=8C?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../common/core/constant/RegexConstants.java  |  49 ++++++++
 .../core/factory/RegexPatternPoolFactory.java |  52 +++++++++
 .../common/core/utils/regex/RegexUtils.java   |  30 +++++
 .../core/utils/regex/RegexValidator.java      | 105 ++++++++++++++++++
 .../ruoyi/system/domain/bo/SysDictTypeBo.java |   3 +-
 5 files changed, 238 insertions(+), 1 deletion(-)
 create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/RegexConstants.java
 create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/factory/RegexPatternPoolFactory.java
 create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/regex/RegexUtils.java
 create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/regex/RegexValidator.java

diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/RegexConstants.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/RegexConstants.java
new file mode 100644
index 0000000..8b8d0ca
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/RegexConstants.java
@@ -0,0 +1,49 @@
+package com.ruoyi.common.core.constant;
+
+import cn.hutool.core.lang.RegexPool;
+
+/**
+ * 常用正则表达式字符串
+ * <p>
+ * 常用正则表达式集合,更多正则见: https://any86.github.io/any-rule/
+ *
+ * @author Feng
+ */
+public interface RegexConstants extends RegexPool {
+
+    /**
+     * 字典类型必须以字母开头,且只能为(小写字母,数字,下滑线)
+     */
+    public static final String DICTIONARY_TYPE = "^[a-z][a-z0-9_]*$";
+
+    /**
+     * 身份证号码(后6位)
+     */
+    public static final String ID_CARD_LAST_6 = "^(([0-2][1-9])|10|20|30|31)\\d{3}[0-9Xx]$";
+
+    /**
+     * QQ号码
+     */
+    public static final String QQ_NUMBER = "^[1-9][0-9]\\d{4,9}$";
+
+    /**
+     * 邮政编码
+     */
+    public static final String POSTAL_CODE = "^[1-9]\\d{5}$";
+
+    /**
+     * 注册账号
+     */
+    public static final String ACCOUNT = "^[a-zA-Z][a-zA-Z0-9_]{4,15}$";
+
+    /**
+     * 密码:包含至少8个字符,包括大写字母、小写字母、数字和特殊字符
+     */
+    public static final String PASSWORD = "^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d)(?=.*[@$!%*?&])[A-Za-z\\d@$!%*?&]{8,}$";
+
+    /**
+     * 通用状态(0表示正常,1表示停用)
+     */
+    public static final String STATUS = "^[01]$";
+
+}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/factory/RegexPatternPoolFactory.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/factory/RegexPatternPoolFactory.java
new file mode 100644
index 0000000..5b71957
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/factory/RegexPatternPoolFactory.java
@@ -0,0 +1,52 @@
+package com.ruoyi.common.core.factory;
+
+import cn.hutool.core.lang.PatternPool;
+import com.ruoyi.common.core.constant.RegexConstants;
+
+import java.util.regex.Pattern;
+
+/**
+ * 正则表达式模式池工厂
+ * <p>初始化的时候将正则表达式加入缓存池当中</p>
+ * <p>提高正则表达式的性能,避免重复编译相同的正则表达式</p>
+ *
+ * @author 21001
+ */
+public class RegexPatternPoolFactory extends PatternPool {
+
+    /**
+     * 字典类型必须以字母开头,且只能为(小写字母,数字,下滑线)
+     */
+    public static final Pattern DICTIONARY_TYPE = get(RegexConstants.DICTIONARY_TYPE);
+
+    /**
+     * 身份证号码(后6位)
+     */
+    public static final Pattern ID_CARD_LAST_6 = get(RegexConstants.ID_CARD_LAST_6);
+
+    /**
+     * QQ号码
+     */
+    public static final Pattern QQ_NUMBER = get(RegexConstants.QQ_NUMBER);
+
+    /**
+     * 邮政编码
+     */
+    public static final Pattern POSTAL_CODE = get(RegexConstants.POSTAL_CODE);
+
+    /**
+     * 注册账号
+     */
+    public static final Pattern ACCOUNT = get(RegexConstants.ACCOUNT);
+
+    /**
+     * 密码:包含至少8个字符,包括大写字母、小写字母、数字和特殊字符
+     */
+    public static final Pattern PASSWORD = get(RegexConstants.PASSWORD);
+
+    /**
+     * 通用状态(0表示正常,1表示停用)
+     */
+    public static final Pattern STATUS = get(RegexConstants.STATUS);
+
+}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/regex/RegexUtils.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/regex/RegexUtils.java
new file mode 100644
index 0000000..e35f024
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/regex/RegexUtils.java
@@ -0,0 +1,30 @@
+package com.ruoyi.common.core.utils.regex;
+
+
+import cn.hutool.core.util.ReUtil;
+import com.ruoyi.common.core.constant.RegexConstants;
+
+/**
+ * 正则相关工具类
+ *
+ * @author Feng
+ */
+public final class RegexUtils extends ReUtil {
+
+    /**
+     * 从输入字符串中提取匹配的部分,如果没有匹配则返回默认值
+     *
+     * @param input        要提取的输入字符串
+     * @param regex        用于匹配的正则表达式,可以使用 {@link RegexConstants} 中定义的常量
+     * @param defaultInput 如果没有匹配时返回的默认值
+     * @return 如果找到匹配的部分,则返回匹配的部分,否则返回默认值
+     */
+    public static String extractFromString(String input, String regex, String defaultInput) {
+        try {
+            return ReUtil.get(regex, input, 1);
+        } catch (Exception e) {
+            return defaultInput;
+        }
+    }
+
+}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/regex/RegexValidator.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/regex/RegexValidator.java
new file mode 100644
index 0000000..a20bc6c
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/regex/RegexValidator.java
@@ -0,0 +1,105 @@
+package com.ruoyi.common.core.utils.regex;
+
+import cn.hutool.core.exceptions.ValidateException;
+import cn.hutool.core.lang.Validator;
+import com.ruoyi.common.core.factory.RegexPatternPoolFactory;
+
+import java.util.regex.Pattern;
+
+/**
+ * 正则字段校验器
+ * 主要验证字段非空、是否为满足指定格式等
+ *
+ * @author Feng
+ */
+public class RegexValidator extends Validator {
+
+    /**
+     * 字典类型必须以字母开头,且只能为(小写字母,数字,下滑线)
+     */
+    public static final Pattern DICTIONARY_TYPE = RegexPatternPoolFactory.DICTIONARY_TYPE;
+
+    /**
+     * 身份证号码(后6位)
+     */
+    public static final Pattern ID_CARD_LAST_6 = RegexPatternPoolFactory.ID_CARD_LAST_6;
+
+    /**
+     * QQ号码
+     */
+    public static final Pattern QQ_NUMBER = RegexPatternPoolFactory.QQ_NUMBER;
+
+    /**
+     * 邮政编码
+     */
+    public static final Pattern POSTAL_CODE = RegexPatternPoolFactory.POSTAL_CODE;
+
+    /**
+     * 注册账号
+     */
+    public static final Pattern ACCOUNT = RegexPatternPoolFactory.ACCOUNT;
+
+    /**
+     * 密码:包含至少8个字符,包括大写字母、小写字母、数字和特殊字符
+     */
+    public static final Pattern PASSWORD = RegexPatternPoolFactory.PASSWORD;
+
+    /**
+     * 通用状态(0表示正常,1表示停用)
+     */
+    public static final Pattern STATUS = RegexPatternPoolFactory.STATUS;
+
+
+    /**
+     * 检查输入的账号是否匹配预定义的规则
+     *
+     * @param value 要验证的账号
+     * @return 如果账号符合规则,返回 true;否则,返回 false。
+     */
+    public static boolean isAccount(CharSequence value) {
+        return isMatchRegex(ACCOUNT, value);
+    }
+
+    /**
+     * 验证输入的账号是否符合规则,如果不符合,则抛出 ValidateException 异常
+     *
+     * @param value    要验证的账号
+     * @param errorMsg 验证失败时抛出的异常消息
+     * @param <T>      CharSequence 的子类型
+     * @return 如果验证通过,返回输入的账号
+     * @throws ValidateException 如果验证失败
+     */
+    public static <T extends CharSequence> T validateAccount(T value, String errorMsg) throws ValidateException {
+        if (!isAccount(value)) {
+            throw new ValidateException(errorMsg);
+        }
+        return value;
+    }
+
+    /**
+     * 检查输入的状态是否匹配预定义的规则
+     *
+     * @param value 要验证的状态
+     * @return 如果状态符合规则,返回 true;否则,返回 false。
+     */
+    public static boolean isStatus(CharSequence value) {
+        return isMatchRegex(STATUS, value);
+    }
+
+    /**
+     * 验证输入的状态是否符合规则,如果不符合,则抛出 ValidateException 异常
+     *
+     * @param value    要验证的状态
+     * @param errorMsg 验证失败时抛出的异常消息
+     * @param <T>      CharSequence 的子类型
+     * @return 如果验证通过,返回输入的状态
+     * @throws ValidateException 如果验证失败
+     */
+    public static <T extends CharSequence> T validateStatus(T value, String errorMsg) throws ValidateException {
+        if (!isStatus(value)) {
+            throw new ValidateException(errorMsg);
+        }
+        return value;
+    }
+
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/bo/SysDictTypeBo.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/bo/SysDictTypeBo.java
index 76a70c7..e41b64c 100644
--- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/bo/SysDictTypeBo.java
+++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/bo/SysDictTypeBo.java
@@ -1,5 +1,6 @@
 package com.ruoyi.system.domain.bo;
 
+import com.ruoyi.common.core.constant.RegexConstants;
 import com.ruoyi.common.orm.core.domain.BaseEntity;
 import com.ruoyi.system.domain.SysDictType;
 import io.github.linpeilie.annotations.AutoMapper;
@@ -37,7 +38,7 @@ public class SysDictTypeBo extends BaseEntity {
      */
     @NotBlank(message = "字典类型不能为空")
     @Size(min = 0, max = 100, message = "字典类型类型长度不能超过{max}个字符")
-    @Pattern(regexp = "^[a-z][a-z0-9_]*$", message = "字典类型必须以字母开头,且只能为(小写字母,数字,下滑线)")
+    @Pattern(regexp = RegexConstants.DICTIONARY_TYPE, message = "字典类型必须以字母开头,且只能为(小写字母,数字,下滑线)")
     private String dictType;
 
     /**