diff --git a/schoolNewsServ/common/common-util/src/main/java/org/xyzh/common/utils/validation/README.md b/schoolNewsServ/common/common-util/src/main/java/org/xyzh/common/utils/validation/README.md new file mode 100644 index 0000000..463c4e6 --- /dev/null +++ b/schoolNewsServ/common/common-util/src/main/java/org/xyzh/common/utils/validation/README.md @@ -0,0 +1,380 @@ +# 数据校验工具使用说明 + +## 概述 + +这是一个灵活、可扩展的Java数据校验工具,支持对对象和Map进行多种类型的校验。 + +## 核心组件 + +### 1. ValidationParam - 校验参数对象 +定义字段的校验规则,支持: +- 字段名称和中文标签 +- 是否必传 +- 字段类型校验 +- 字符串长度限制 +- 数字范围限制 +- 正则表达式校验 +- 自定义校验函数 +- 预定义的校验方法(ValidateMethod) + +### 2. ValidationResult - 校验结果对象 +保存校验结果,包含: +- 是否校验通过 +- 错误信息列表 +- 第一个错误信息 +- 错误数量统计 + +### 3. ValidationUtils - 校验工具类 +执行校验逻辑,提供: +- 校验Java对象 +- 校验Map对象 +- 快捷方法:`requiredString()`, `requiredNumber()`, `email()`, `phone()` + +### 4. ValidateMethod - 校验方法接口 +预定义的专业校验方法,已实现: +- **PasswordValidateMethod** - 密码校验 +- **IdCardValidateMethod** - 身份证号校验 +- **PhoneValidateMethod** - 手机号码校验 +- **EmailValidateMethod** - 邮箱地址校验 +- **UrlValidateMethod** - URL链接校验 +- **BankCardValidateMethod** - 银行卡号校验 +- **ChineseValidateMethod** - 中文字符校验 + +### 5. ValidateMethodType - 校验方法类型枚举 ⭐推荐使用 +枚举类型指向预定义的校验方法,使用更简洁: +- **PASSWORD** - 密码校验(6-20位,字母+数字) +- **STRONG_PASSWORD** - 强密码校验(8-20位,大小写+数字+特殊字符) +- **ID_CARD** - 身份证号校验 +- **PHONE** - 手机号码校验(中国大陆) +- **PHONE_LOOSE** - 手机号码校验(支持大陆/香港/台湾) +- **EMAIL** - 邮箱地址校验 +- **URL** - URL链接校验 +- **HTTPS_URL** - HTTPS链接校验 +- **BANK_CARD** - 银行卡号校验 +- **CHINESE** - 中文字符校验(纯中文) +- **CHINESE_WITH_PUNCTUATION** - 中文字符校验(允许标点) + +## 基本使用示例 + +### 1. 使用枚举类型校验(⭐推荐) + +```java +List params = Arrays.asList( + ValidationParam.builder() + .fieldName("password") + .fieldLabel("密码") + .required() + .validateMethod(ValidateMethodType.PASSWORD) // 使用枚举 + .build(), + + ValidationParam.builder() + .fieldName("email") + .fieldLabel("邮箱") + .required() + .validateMethod(ValidateMethodType.EMAIL) // 使用枚举 + .build(), + + ValidationParam.builder() + .fieldName("phone") + .fieldLabel("手机号") + .required() + .validateMethod(ValidateMethodType.PHONE) // 使用枚举 + .build(), + + ValidationParam.builder() + .fieldName("idCard") + .fieldLabel("身份证号") + .required() + .validateMethod(ValidateMethodType.ID_CARD) // 使用枚举 + .build() +); + +ValidationResult result = ValidationUtils.validateMap(data, params); +if (!result.isValid()) { + System.out.println(result.getFirstError()); +} +``` + +### 2. 简单字段校验 + +```java +List params = Arrays.asList( + ValidationUtils.requiredString("username", "用户名", 3, 20), + ValidationUtils.email("email", "邮箱", true), + ValidationUtils.phone("phone", "手机号", false) +); + +// 校验对象 +ValidationResult result = ValidationUtils.validate(userObject, params); + +// 校验Map +ValidationResult result = ValidationUtils.validateMap(userMap, params); + +// 检查结果 +if (result.isValid()) { + // 校验通过 +} else { + // 获取错误信息 + String firstError = result.getFirstError(); + String allErrors = result.getAllErrors(); + List errors = result.getErrors(); +} +``` + +### 3. 使用ValidateMethod进行专业校验(兼容旧方式) + +```java +List params = Arrays.asList( + // 方式1:使用枚举(推荐) + ValidationParam.builder() + .fieldName("password") + .fieldLabel("密码") + .required() + .validateMethod(ValidateMethodType.STRONG_PASSWORD) // 使用预定义的强密码 + .build(), + + // 方式2:直接实例化(如需自定义参数) + ValidationParam.builder() + .fieldName("password2") + .fieldLabel("自定义密码") + .required() + .validateMethod(new PasswordValidateMethod(8, 20, true, true, true, true)) + .build(), + + // 身份证号校验 + ValidationParam.builder() + .fieldName("idCard") + .fieldLabel("身份证号") + .required() + .validateMethod(new IdCardValidateMethod()) + .build(), + + // 手机号校验 + ValidationParam.builder() + .fieldName("phone") + .fieldLabel("手机号") + .required() + .validateMethod(new PhoneValidateMethod()) + .build(), + + // 限制域名的邮箱校验 + ValidationParam.builder() + .fieldName("email") + .fieldLabel("邮箱") + .required() + .validateMethod(new EmailValidateMethod(new String[]{"company.com"})) + .build() +); + +ValidationResult result = ValidationUtils.validateMap(data, params); +``` + +### 4. 自定义校验 + +```java +ValidationParam param = ValidationParam.builder() + .fieldName("age") + .fieldLabel("年龄") + .required() + .customValidator(value -> { + Integer age = (Integer) value; + return age >= 18 && age <= 60; + }) + .customErrorMessage("年龄必须在18-60岁之间") + .build(); +``` + +### 5. 复合校验 + +```java +List params = Arrays.asList( + ValidationParam.builder() + .fieldName("username") + .fieldLabel("用户名") + .required() + .fieldType(String.class) + .minLength(3) + .maxLength(20) + .pattern("^[a-zA-Z0-9_]+$") + .patternDesc("只能包含字母、数字和下划线") + .build(), + + ValidationParam.builder() + .fieldName("password") + .fieldLabel("密码") + .required() + .minLength(6) + .validateMethod(new PasswordValidateMethod()) + .build() +); +``` + +## 预定义校验方法详解 + +### PasswordValidateMethod - 密码校验 + +```java +// 默认规则:6-20位,必须包含字母和数字 +new PasswordValidateMethod() + +// 自定义规则 +new PasswordValidateMethod( + 8, // 最小长度 + 20, // 最大长度 + true, // 需要大写字母 + true, // 需要小写字母 + true, // 需要数字 + true // 需要特殊字符 +) +``` + +### IdCardValidateMethod - 身份证号校验 + +```java +// 支持15位和18位身份证号 +// 自动校验:格式、省份代码、出生日期、校验码 +new IdCardValidateMethod() +``` + +### PhoneValidateMethod - 手机号码校验 + +```java +// 严格模式:仅中国大陆手机号 +new PhoneValidateMethod() + +// 宽松模式:支持大陆、香港、台湾 +new PhoneValidateMethod(false) +``` + +### EmailValidateMethod - 邮箱地址校验 + +```java +// 允许所有域名 +new EmailValidateMethod() + +// 限制特定域名 +new EmailValidateMethod(new String[]{"company.com", "example.com"}) +``` + +### UrlValidateMethod - URL链接校验 + +```java +// 允许HTTP和HTTPS +new UrlValidateMethod() + +// 仅允许HTTPS +new UrlValidateMethod(true) +``` + +### BankCardValidateMethod - 银行卡号校验 + +```java +// 使用Luhn算法校验银行卡号 +new BankCardValidateMethod() +``` + +### ChineseValidateMethod - 中文字符校验 + +```java +// 仅纯中文字符 +new ChineseValidateMethod() + +// 允许中文标点符号 +new ChineseValidateMethod(true) +``` + +## 在Controller中使用 + +```java +@PostMapping("/register") +public ResultDomain register(@RequestBody Map params) { + // 定义校验规则(使用枚举,更简洁) + List validationParams = Arrays.asList( + ValidationParam.builder() + .fieldName("username") + .fieldLabel("用户名") + .required() + .minLength(3) + .maxLength(20) + .build(), + + ValidationParam.builder() + .fieldName("password") + .fieldLabel("密码") + .required() + .validateMethod(ValidateMethodType.PASSWORD) // 使用枚举! + .build(), + + ValidationParam.builder() + .fieldName("email") + .fieldLabel("邮箱") + .required() + .validateMethod(ValidateMethodType.EMAIL) // 使用枚举! + .build(), + + ValidationParam.builder() + .fieldName("phone") + .fieldLabel("手机号") + .required() + .validateMethod(ValidateMethodType.PHONE) // 使用枚举! + .build() + ); + + // 执行校验 + ValidationResult validationResult = ValidationUtils.validateMap(params, validationParams); + + if (!validationResult.isValid()) { + ResultDomain result = new ResultDomain<>(); + result.fail(validationResult.getFirstError()); + return result; + } + + // 校验通过,继续业务逻辑 + // ... +} +``` + +## 自定义ValidateMethod + +如需添加新的校验方法,只需实现`ValidateMethod`接口: + +```java +public class CustomValidateMethod implements ValidateMethod { + + @Override + public boolean validate(Object value) { + // 实现校验逻辑 + return true; + } + + @Override + public String getErrorMessage() { + return "自定义错误信息"; + } + + @Override + public String getName() { + return "自定义校验"; + } +} +``` + +## 优势 + +1. **简洁性**:使用枚举类型,无需每次new对象 ⭐ +2. **灵活性**:支持多种校验方式组合使用 +3. **可扩展性**:易于添加新的校验方法 +4. **可读性**:Builder模式让代码清晰易懂 +5. **可复用性**:预定义的校验方法可在项目中重复使用 +6. **专业性**:内置多种常用的专业校验算法(身份证、银行卡等) +7. **类型安全**:枚举类型提供编译时类型检查 + +## 注意事项 + +1. **推荐使用枚举类型**:`ValidateMethodType` 比直接 `new` 对象更简洁 +2. 校验顺序:必填 -> 类型 -> 长度/范围 -> 正则 -> 自定义 -> ValidateMethodType -> ValidateMethod +3. ValidateMethod和customValidator可以同时使用,都会执行 +4. 当值为null且非必填时,会跳过后续所有校验 +5. 错误信息会累积,可以获取所有错误或只获取第一个错误 +6. 枚举方式和实例方式可以并存,但推荐统一使用枚举方式 + diff --git a/schoolNewsServ/common/common-util/src/main/java/org/xyzh/common/utils/validation/ValidationParam.java b/schoolNewsServ/common/common-util/src/main/java/org/xyzh/common/utils/validation/ValidationParam.java new file mode 100644 index 0000000..49616ee --- /dev/null +++ b/schoolNewsServ/common/common-util/src/main/java/org/xyzh/common/utils/validation/ValidationParam.java @@ -0,0 +1,276 @@ +package org.xyzh.common.utils.validation; + +import org.xyzh.common.utils.validation.method.ValidateMethod; +import org.xyzh.common.utils.validation.method.ValidateMethodType; + +import java.util.function.Predicate; + +/** + * @description 校验参数对象,定义字段的校验规则 + * @filename ValidationParam.java + * @author yslg + * @copyright xyzh + * @since 2025-10-16 + */ +public class ValidationParam { + + /** + * @description 字段名称 + */ + private String fieldName; + + /** + * @description 字段中文名称(用于错误提示) + */ + private String fieldLabel; + + /** + * @description 是否必传 + */ + private boolean required; + + /** + * @description 字段类型 + */ + private Class fieldType; + + /** + * @description 最小长度(字符串) + */ + private Integer minLength; + + /** + * @description 最大长度(字符串) + */ + private Integer maxLength; + + /** + * @description 最小值(数字) + */ + private Number minValue; + + /** + * @description 最大值(数字) + */ + private Number maxValue; + + /** + * @description 正则表达式 + */ + private String pattern; + + /** + * @description 正则表达式描述(用于错误提示) + */ + private String patternDesc; + + /** + * @description 自定义校验函数 + */ + private Predicate customValidator; + + /** + * @description 自定义校验失败消息 + */ + private String customErrorMessage; + + /** + * @description 是否允许为空字符串(默认不允许) + */ + private boolean allowEmpty = false; + + /** + * @description 校验方法(使用预定义的校验方法) + */ + private ValidateMethod validateMethod; + + /** + * @description 校验方法类型枚举 + */ + private ValidateMethodType validateMethodType; + + /** + * @description 校验方法配置参数(用于需要自定义参数的校验方法) + */ + private Object[] methodParams; + + // 私有构造函数,使用Builder模式 + private ValidationParam() { + } + + public String getFieldName() { + return fieldName; + } + + public String getFieldLabel() { + return fieldLabel; + } + + public boolean isRequired() { + return required; + } + + public Class getFieldType() { + return fieldType; + } + + public Integer getMinLength() { + return minLength; + } + + public Integer getMaxLength() { + return maxLength; + } + + public Number getMinValue() { + return minValue; + } + + public Number getMaxValue() { + return maxValue; + } + + public String getPattern() { + return pattern; + } + + public String getPatternDesc() { + return patternDesc; + } + + public Predicate getCustomValidator() { + return customValidator; + } + + public String getCustomErrorMessage() { + return customErrorMessage; + } + + public boolean isAllowEmpty() { + return allowEmpty; + } + + public ValidateMethod getValidateMethod() { + return validateMethod; + } + + public ValidateMethodType getValidateMethodType() { + return validateMethodType; + } + + public Object[] getMethodParams() { + return methodParams; + } + + /** + * @description Builder类用于构建ValidationParam对象 + */ + public static class Builder { + private ValidationParam param = new ValidationParam(); + + public Builder fieldName(String fieldName) { + param.fieldName = fieldName; + return this; + } + + public Builder fieldLabel(String fieldLabel) { + param.fieldLabel = fieldLabel; + return this; + } + + public Builder required(boolean required) { + param.required = required; + return this; + } + + public Builder required() { + param.required = true; + return this; + } + + public Builder fieldType(Class fieldType) { + param.fieldType = fieldType; + return this; + } + + public Builder minLength(Integer minLength) { + param.minLength = minLength; + return this; + } + + public Builder maxLength(Integer maxLength) { + param.maxLength = maxLength; + return this; + } + + public Builder minValue(Number minValue) { + param.minValue = minValue; + return this; + } + + public Builder maxValue(Number maxValue) { + param.maxValue = maxValue; + return this; + } + + public Builder pattern(String pattern) { + param.pattern = pattern; + return this; + } + + public Builder patternDesc(String patternDesc) { + param.patternDesc = patternDesc; + return this; + } + + public Builder customValidator(Predicate customValidator) { + param.customValidator = customValidator; + return this; + } + + public Builder customErrorMessage(String customErrorMessage) { + param.customErrorMessage = customErrorMessage; + return this; + } + + public Builder allowEmpty(boolean allowEmpty) { + param.allowEmpty = allowEmpty; + return this; + } + + public Builder validateMethod(ValidateMethod validateMethod) { + param.validateMethod = validateMethod; + return this; + } + + public Builder validateMethod(ValidateMethodType methodType) { + param.validateMethodType = methodType; + return this; + } + + public Builder validateMethod(ValidateMethodType methodType, Object... params) { + param.validateMethodType = methodType; + param.methodParams = params; + return this; + } + + public ValidationParam build() { + if (param.fieldName == null || param.fieldName.isEmpty()) { + throw new IllegalArgumentException("fieldName不能为空"); + } + if (param.fieldLabel == null || param.fieldLabel.isEmpty()) { + param.fieldLabel = param.fieldName; + } + return param; + } + } + + /** + * @description 创建Builder对象 + * @return Builder + */ + public static Builder builder() { + return new Builder(); + } +} + diff --git a/schoolNewsServ/common/common-util/src/main/java/org/xyzh/common/utils/validation/ValidationResult.java b/schoolNewsServ/common/common-util/src/main/java/org/xyzh/common/utils/validation/ValidationResult.java new file mode 100644 index 0000000..fb83f52 --- /dev/null +++ b/schoolNewsServ/common/common-util/src/main/java/org/xyzh/common/utils/validation/ValidationResult.java @@ -0,0 +1,96 @@ +package org.xyzh.common.utils.validation; + +import java.util.ArrayList; +import java.util.List; + +/** + * @description 校验结果类 + * @filename ValidationResult.java + * @author yslg + * @copyright xyzh + * @since 2025-10-16 + */ +public class ValidationResult { + + /** + * @description 是否校验通过 + */ + private boolean valid; + + /** + * @description 错误信息列表 + */ + private List errors; + + /** + * @description 第一个错误信息 + */ + private String firstError; + + public ValidationResult() { + this.valid = true; + this.errors = new ArrayList<>(); + } + + public boolean isValid() { + return valid; + } + + public void setValid(boolean valid) { + this.valid = valid; + } + + public List getErrors() { + return errors; + } + + public String getFirstError() { + return firstError; + } + + /** + * @description 添加错误信息 + * @param error 错误信息 + */ + public void addError(String error) { + this.valid = false; + this.errors.add(error); + if (this.firstError == null) { + this.firstError = error; + } + } + + /** + * @description 获取所有错误信息的字符串 + * @return 错误信息字符串 + */ + public String getAllErrors() { + return String.join("; ", errors); + } + + /** + * @description 是否有错误 + * @return boolean + */ + public boolean hasErrors() { + return !valid; + } + + /** + * @description 获取错误数量 + * @return 错误数量 + */ + public int getErrorCount() { + return errors.size(); + } + + @Override + public String toString() { + return "ValidationResult{" + + "valid=" + valid + + ", errorCount=" + errors.size() + + ", errors=" + errors + + '}'; + } +} + diff --git a/schoolNewsServ/common/common-util/src/main/java/org/xyzh/common/utils/validation/ValidationUtils.java b/schoolNewsServ/common/common-util/src/main/java/org/xyzh/common/utils/validation/ValidationUtils.java new file mode 100644 index 0000000..281de98 --- /dev/null +++ b/schoolNewsServ/common/common-util/src/main/java/org/xyzh/common/utils/validation/ValidationUtils.java @@ -0,0 +1,321 @@ +package org.xyzh.common.utils.validation; + +import org.xyzh.common.utils.validation.method.ValidateMethod; + +import java.lang.reflect.Field; +import java.util.List; +import java.util.Map; +import java.util.regex.Pattern; + +/** + * @description 校验工具类 + * @filename ValidationUtils.java + * @author yslg + * @copyright xyzh + * @since 2025-10-16 + */ +public class ValidationUtils { + + /** + * @description 校验对象 + * @param obj 待校验的对象 + * @param validationParams 校验参数列表 + * @return ValidationResult 校验结果 + */ + public static ValidationResult validate(Object obj, List validationParams) { + ValidationResult result = new ValidationResult(); + + if (obj == null) { + result.addError("待校验对象不能为null"); + return result; + } + + if (validationParams == null || validationParams.isEmpty()) { + return result; + } + + for (ValidationParam param : validationParams) { + try { + Object fieldValue = getFieldValue(obj, param.getFieldName()); + validateField(param, fieldValue, result); + } catch (Exception e) { + result.addError(param.getFieldLabel() + "字段获取失败: " + e.getMessage()); + } + } + + return result; + } + + /** + * @description 校验Map对象 + * @param map 待校验的Map + * @param validationParams 校验参数列表 + * @return ValidationResult 校验结果 + */ + public static ValidationResult validateMap(Map map, List validationParams) { + ValidationResult result = new ValidationResult(); + + if (map == null) { + result.addError("待校验Map不能为null"); + return result; + } + + if (validationParams == null || validationParams.isEmpty()) { + return result; + } + + for (ValidationParam param : validationParams) { + Object fieldValue = map.get(param.getFieldName()); + validateField(param, fieldValue, result); + } + + return result; + } + + /** + * @description 校验单个字段 + * @param param 校验参数 + * @param fieldValue 字段值 + * @param result 校验结果 + */ + private static void validateField(ValidationParam param, Object fieldValue, ValidationResult result) { + String fieldLabel = param.getFieldLabel(); + + // 1. 必填校验 + if (param.isRequired()) { + if (fieldValue == null) { + result.addError(fieldLabel + "不能为空"); + return; + } + if (fieldValue instanceof String) { + String strValue = (String) fieldValue; + if (!param.isAllowEmpty() && strValue.trim().isEmpty()) { + result.addError(fieldLabel + "不能为空字符串"); + return; + } + } + } + + // 如果值为null且非必填,跳过后续校验 + if (fieldValue == null) { + return; + } + + // 2. 类型校验 + if (param.getFieldType() != null) { + if (!param.getFieldType().isAssignableFrom(fieldValue.getClass())) { + result.addError(fieldLabel + "类型错误,期望类型: " + param.getFieldType().getSimpleName() + + ", 实际类型: " + fieldValue.getClass().getSimpleName()); + return; + } + } + + // 3. 字符串长度校验 + if (fieldValue instanceof String) { + String strValue = (String) fieldValue; + if (param.getMinLength() != null && strValue.length() < param.getMinLength()) { + result.addError(fieldLabel + "长度不能少于" + param.getMinLength() + "个字符"); + } + if (param.getMaxLength() != null && strValue.length() > param.getMaxLength()) { + result.addError(fieldLabel + "长度不能超过" + param.getMaxLength() + "个字符"); + } + } + + // 4. 数字范围校验 + if (fieldValue instanceof Number) { + double numValue = ((Number) fieldValue).doubleValue(); + if (param.getMinValue() != null && numValue < param.getMinValue().doubleValue()) { + result.addError(fieldLabel + "不能小于" + param.getMinValue()); + } + if (param.getMaxValue() != null && numValue > param.getMaxValue().doubleValue()) { + result.addError(fieldLabel + "不能大于" + param.getMaxValue()); + } + } + + // 5. 正则表达式校验 + if (param.getPattern() != null && fieldValue instanceof String) { + String strValue = (String) fieldValue; + if (!Pattern.matches(param.getPattern(), strValue)) { + String errorMsg = fieldLabel + "格式不正确"; + if (param.getPatternDesc() != null) { + errorMsg += "," + param.getPatternDesc(); + } + result.addError(errorMsg); + } + } + + // 6. 自定义校验 + if (param.getCustomValidator() != null) { + try { + if (!param.getCustomValidator().test(fieldValue)) { + String errorMsg = param.getCustomErrorMessage(); + if (errorMsg == null || errorMsg.isEmpty()) { + errorMsg = fieldLabel + "校验失败"; + } + result.addError(errorMsg); + } + } catch (Exception e) { + result.addError(fieldLabel + "自定义校验异常: " + e.getMessage()); + } + } + + // 7. 使用ValidateMethod校验(枚举类型) + if (param.getValidateMethodType() != null) { + try { + ValidateMethod method = param.getValidateMethodType().createInstance(); + if (!method.validate(fieldValue)) { + String errorMsg = method.getErrorMessage(); + if (errorMsg != null && !errorMsg.isEmpty()) { + result.addError(errorMsg); + } else { + result.addError(fieldLabel + "校验失败"); + } + } + } catch (Exception e) { + result.addError(fieldLabel + "校验异常: " + e.getMessage()); + } + } + + // 8. 使用ValidateMethod校验(直接传入实例,保留兼容性) + if (param.getValidateMethod() != null) { + try { + if (!param.getValidateMethod().validate(fieldValue)) { + String errorMsg = param.getValidateMethod().getErrorMessage(); + if (errorMsg != null && !errorMsg.isEmpty()) { + result.addError(errorMsg); + } else { + result.addError(fieldLabel + "校验失败"); + } + } + } catch (Exception e) { + result.addError(fieldLabel + "校验异常: " + e.getMessage()); + } + } + } + + /** + * @description 获取对象字段值(支持getter方法和直接访问) + * @param obj 对象 + * @param fieldName 字段名 + * @return 字段值 + * @throws Exception 异常 + */ + private static Object getFieldValue(Object obj, String fieldName) throws Exception { + if (obj instanceof Map) { + return ((Map) obj).get(fieldName); + } + + Class clazz = obj.getClass(); + + // 首先尝试getter方法 + try { + String getterName = "get" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1); + return clazz.getMethod(getterName).invoke(obj); + } catch (NoSuchMethodException e) { + // getter方法不存在,尝试直接访问字段 + try { + Field field = clazz.getDeclaredField(fieldName); + field.setAccessible(true); + return field.get(obj); + } catch (NoSuchFieldException ex) { + // 尝试父类 + Class superClass = clazz.getSuperclass(); + if (superClass != null) { + Field field = superClass.getDeclaredField(fieldName); + field.setAccessible(true); + return field.get(obj); + } + throw ex; + } + } + } + + /** + * @description 快速创建必填字符串校验参数 + * @param fieldName 字段名 + * @param fieldLabel 字段标签 + * @return ValidationParam + */ + public static ValidationParam requiredString(String fieldName, String fieldLabel) { + return ValidationParam.builder() + .fieldName(fieldName) + .fieldLabel(fieldLabel) + .required() + .fieldType(String.class) + .build(); + } + + /** + * @description 快速创建必填字符串校验参数(带长度限制) + * @param fieldName 字段名 + * @param fieldLabel 字段标签 + * @param minLength 最小长度 + * @param maxLength 最大长度 + * @return ValidationParam + */ + public static ValidationParam requiredString(String fieldName, String fieldLabel, int minLength, int maxLength) { + return ValidationParam.builder() + .fieldName(fieldName) + .fieldLabel(fieldLabel) + .required() + .fieldType(String.class) + .minLength(minLength) + .maxLength(maxLength) + .build(); + } + + /** + * @description 快速创建必填数字校验参数 + * @param fieldName 字段名 + * @param fieldLabel 字段标签 + * @param minValue 最小值 + * @param maxValue 最大值 + * @return ValidationParam + */ + public static ValidationParam requiredNumber(String fieldName, String fieldLabel, Number minValue, Number maxValue) { + return ValidationParam.builder() + .fieldName(fieldName) + .fieldLabel(fieldLabel) + .required() + .minValue(minValue) + .maxValue(maxValue) + .build(); + } + + /** + * @description 快速创建邮箱校验参数 + * @param fieldName 字段名 + * @param fieldLabel 字段标签 + * @param required 是否必填 + * @return ValidationParam + */ + public static ValidationParam email(String fieldName, String fieldLabel, boolean required) { + return ValidationParam.builder() + .fieldName(fieldName) + .fieldLabel(fieldLabel) + .required(required) + .fieldType(String.class) + .pattern("^[A-Za-z0-9+_.-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}$") + .patternDesc("请输入有效的邮箱地址") + .build(); + } + + /** + * @description 快速创建手机号校验参数 + * @param fieldName 字段名 + * @param fieldLabel 字段标签 + * @param required 是否必填 + * @return ValidationParam + */ + public static ValidationParam phone(String fieldName, String fieldLabel, boolean required) { + return ValidationParam.builder() + .fieldName(fieldName) + .fieldLabel(fieldLabel) + .required(required) + .fieldType(String.class) + .pattern("^1[3-9]\\d{9}$") + .patternDesc("请输入有效的手机号码") + .build(); + } +} + diff --git a/schoolNewsServ/common/common-util/src/main/java/org/xyzh/common/utils/validation/method/BankCardValidateMethod.java b/schoolNewsServ/common/common-util/src/main/java/org/xyzh/common/utils/validation/method/BankCardValidateMethod.java new file mode 100644 index 0000000..46ab28b --- /dev/null +++ b/schoolNewsServ/common/common-util/src/main/java/org/xyzh/common/utils/validation/method/BankCardValidateMethod.java @@ -0,0 +1,71 @@ +package org.xyzh.common.utils.validation.method; + +/** + * @description 银行卡号校验方法(Luhn算法) + * @filename BankCardValidateMethod.java + * @author yslg + * @copyright xyzh + * @since 2025-10-16 + */ +public class BankCardValidateMethod implements ValidateMethod { + + @Override + public boolean validate(Object value) { + if (value == null || !(value instanceof String)) { + return false; + } + + String cardNumber = ((String) value).replaceAll("\\s", ""); + + // 长度校验(银行卡号通常为16-19位) + if (cardNumber.length() < 16 || cardNumber.length() > 19) { + return false; + } + + // 数字校验 + if (!cardNumber.matches("^\\d+$")) { + return false; + } + + // Luhn算法校验 + return luhnCheck(cardNumber); + } + + /** + * @description Luhn算法校验(银行卡校验算法) + * @param cardNumber 银行卡号 + * @return boolean 是否通过校验 + */ + private boolean luhnCheck(String cardNumber) { + int sum = 0; + boolean alternate = false; + + // 从右向左遍历 + for (int i = cardNumber.length() - 1; i >= 0; i--) { + int digit = Character.getNumericValue(cardNumber.charAt(i)); + + if (alternate) { + digit *= 2; + if (digit > 9) { + digit = digit - 9; + } + } + + sum += digit; + alternate = !alternate; + } + + return sum % 10 == 0; + } + + @Override + public String getErrorMessage() { + return "请输入有效的银行卡号"; + } + + @Override + public String getName() { + return "银行卡号校验"; + } +} + diff --git a/schoolNewsServ/common/common-util/src/main/java/org/xyzh/common/utils/validation/method/ChineseValidateMethod.java b/schoolNewsServ/common/common-util/src/main/java/org/xyzh/common/utils/validation/method/ChineseValidateMethod.java new file mode 100644 index 0000000..e4b5290 --- /dev/null +++ b/schoolNewsServ/common/common-util/src/main/java/org/xyzh/common/utils/validation/method/ChineseValidateMethod.java @@ -0,0 +1,54 @@ +package org.xyzh.common.utils.validation.method; + +import java.util.regex.Pattern; + +/** + * @description 中文字符校验方法 + * @filename ChineseValidateMethod.java + * @author yslg + * @copyright xyzh + * @since 2025-10-16 + */ +public class ChineseValidateMethod implements ValidateMethod { + + // 中文字符正则(包括中文标点符号) + private static final Pattern CHINESE_PATTERN = Pattern.compile("^[\u4e00-\u9fa5]+$"); + + private final boolean allowPunctuation; // 是否允许中文标点符号 + + public ChineseValidateMethod() { + this.allowPunctuation = false; + } + + public ChineseValidateMethod(boolean allowPunctuation) { + this.allowPunctuation = allowPunctuation; + } + + @Override + public boolean validate(Object value) { + if (value == null || !(value instanceof String)) { + return false; + } + + String str = (String) value; + + if (allowPunctuation) { + // 允许中文字符和中文标点符号 + return Pattern.matches("^[\u4e00-\u9fa5\\u3000-\\u303f]+$", str); + } else { + // 仅允许纯中文字符 + return CHINESE_PATTERN.matcher(str).matches(); + } + } + + @Override + public String getErrorMessage() { + return allowPunctuation ? "请输入中文字符" : "请输入纯中文字符(不含标点符号)"; + } + + @Override + public String getName() { + return "中文字符校验"; + } +} + diff --git a/schoolNewsServ/common/common-util/src/main/java/org/xyzh/common/utils/validation/method/EmailValidateMethod.java b/schoolNewsServ/common/common-util/src/main/java/org/xyzh/common/utils/validation/method/EmailValidateMethod.java new file mode 100644 index 0000000..26792fd --- /dev/null +++ b/schoolNewsServ/common/common-util/src/main/java/org/xyzh/common/utils/validation/method/EmailValidateMethod.java @@ -0,0 +1,77 @@ +package org.xyzh.common.utils.validation.method; + +import java.util.regex.Pattern; + +/** + * @description 邮箱校验方法 + * @filename EmailValidateMethod.java + * @author yslg + * @copyright xyzh + * @since 2025-10-16 + */ +public class EmailValidateMethod implements ValidateMethod { + + // 邮箱正则表达式 + private static final Pattern EMAIL_PATTERN = Pattern.compile( + "^[A-Za-z0-9+_.-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}$" + ); + + private final String[] allowedDomains; // 允许的域名列表 + + /** + * @description 默认构造函数,允许所有域名 + */ + public EmailValidateMethod() { + this.allowedDomains = null; + } + + /** + * @description 限制域名的构造函数 + * @param allowedDomains 允许的域名列表,例如:["company.com", "example.com"] + */ + public EmailValidateMethod(String[] allowedDomains) { + this.allowedDomains = allowedDomains; + } + + @Override + public boolean validate(Object value) { + if (value == null || !(value instanceof String)) { + return false; + } + + String email = ((String) value).trim().toLowerCase(); + + // 基本格式校验 + if (!EMAIL_PATTERN.matcher(email).matches()) { + return false; + } + + // 域名限制校验 + if (allowedDomains != null && allowedDomains.length > 0) { + boolean domainMatched = false; + for (String domain : allowedDomains) { + if (email.endsWith("@" + domain.toLowerCase())) { + domainMatched = true; + break; + } + } + return domainMatched; + } + + return true; + } + + @Override + public String getErrorMessage() { + if (allowedDomains != null && allowedDomains.length > 0) { + return "请输入有效的邮箱地址(仅支持: " + String.join(", ", allowedDomains) + ")"; + } + return "请输入有效的邮箱地址"; + } + + @Override + public String getName() { + return "邮箱校验"; + } +} + diff --git a/schoolNewsServ/common/common-util/src/main/java/org/xyzh/common/utils/validation/method/IdCardValidateMethod.java b/schoolNewsServ/common/common-util/src/main/java/org/xyzh/common/utils/validation/method/IdCardValidateMethod.java new file mode 100644 index 0000000..1db0504 --- /dev/null +++ b/schoolNewsServ/common/common-util/src/main/java/org/xyzh/common/utils/validation/method/IdCardValidateMethod.java @@ -0,0 +1,198 @@ +package org.xyzh.common.utils.validation.method; + +import java.util.HashMap; +import java.util.Map; +import java.util.regex.Pattern; + +/** + * @description 身份证号码校验方法(支持15位和18位身份证) + * @filename IdCardValidateMethod.java + * @author yslg + * @copyright xyzh + * @since 2025-10-16 + */ +public class IdCardValidateMethod implements ValidateMethod { + + // 加权因子 + private static final int[] WEIGHT = {7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2}; + + // 校验码对应值 + private static final char[] VALIDATE_CODE = {'1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2'}; + + // 省份代码 + private static final Map PROVINCE_CODES = new HashMap<>(); + + static { + PROVINCE_CODES.put("11", "北京"); + PROVINCE_CODES.put("12", "天津"); + PROVINCE_CODES.put("13", "河北"); + PROVINCE_CODES.put("14", "山西"); + PROVINCE_CODES.put("15", "内蒙古"); + PROVINCE_CODES.put("21", "辽宁"); + PROVINCE_CODES.put("22", "吉林"); + PROVINCE_CODES.put("23", "黑龙江"); + PROVINCE_CODES.put("31", "上海"); + PROVINCE_CODES.put("32", "江苏"); + PROVINCE_CODES.put("33", "浙江"); + PROVINCE_CODES.put("34", "安徽"); + PROVINCE_CODES.put("35", "福建"); + PROVINCE_CODES.put("36", "江西"); + PROVINCE_CODES.put("37", "山东"); + PROVINCE_CODES.put("41", "河南"); + PROVINCE_CODES.put("42", "湖北"); + PROVINCE_CODES.put("43", "湖南"); + PROVINCE_CODES.put("44", "广东"); + PROVINCE_CODES.put("45", "广西"); + PROVINCE_CODES.put("46", "海南"); + PROVINCE_CODES.put("50", "重庆"); + PROVINCE_CODES.put("51", "四川"); + PROVINCE_CODES.put("52", "贵州"); + PROVINCE_CODES.put("53", "云南"); + PROVINCE_CODES.put("54", "西藏"); + PROVINCE_CODES.put("61", "陕西"); + PROVINCE_CODES.put("62", "甘肃"); + PROVINCE_CODES.put("63", "青海"); + PROVINCE_CODES.put("64", "宁夏"); + PROVINCE_CODES.put("65", "新疆"); + PROVINCE_CODES.put("71", "台湾"); + PROVINCE_CODES.put("81", "香港"); + PROVINCE_CODES.put("82", "澳门"); + } + + @Override + public boolean validate(Object value) { + if (value == null || !(value instanceof String)) { + return false; + } + + String idCard = ((String) value).toUpperCase(); + + // 长度校验 + if (idCard.length() != 15 && idCard.length() != 18) { + return false; + } + + // 格式校验 + if (idCard.length() == 15) { + return validate15IdCard(idCard); + } else { + return validate18IdCard(idCard); + } + } + + /** + * @description 校验15位身份证 + */ + private boolean validate15IdCard(String idCard) { + // 15位身份证格式:省(2位)市(2位)县(2位)年(2位)月(2位)日(2位)顺序号(3位) + if (!Pattern.matches("^\\d{15}$", idCard)) { + return false; + } + + // 省份代码校验 + String provinceCode = idCard.substring(0, 2); + if (!PROVINCE_CODES.containsKey(provinceCode)) { + return false; + } + + // 出生日期校验 + String year = "19" + idCard.substring(6, 8); + String month = idCard.substring(8, 10); + String day = idCard.substring(10, 12); + + return validateDate(year, month, day); + } + + /** + * @description 校验18位身份证 + */ + private boolean validate18IdCard(String idCard) { + // 18位身份证格式:省(2位)市(2位)县(2位)年(4位)月(2位)日(2位)顺序号(3位)校验码(1位) + if (!Pattern.matches("^\\d{17}[0-9Xx]$", idCard)) { + return false; + } + + // 省份代码校验 + String provinceCode = idCard.substring(0, 2); + if (!PROVINCE_CODES.containsKey(provinceCode)) { + return false; + } + + // 出生日期校验 + String year = idCard.substring(6, 10); + String month = idCard.substring(10, 12); + String day = idCard.substring(12, 14); + + if (!validateDate(year, month, day)) { + return false; + } + + // 校验码校验 + return validateCheckCode(idCard); + } + + /** + * @description 校验日期是否合法 + */ + private boolean validateDate(String year, String month, String day) { + try { + int y = Integer.parseInt(year); + int m = Integer.parseInt(month); + int d = Integer.parseInt(day); + + // 年份范围:1900-当前年份 + int currentYear = java.time.Year.now().getValue(); + if (y < 1900 || y > currentYear) { + return false; + } + + // 月份范围:1-12 + if (m < 1 || m > 12) { + return false; + } + + // 日期范围 + int[] daysInMonth = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; + + // 闰年2月29天 + if (isLeapYear(y)) { + daysInMonth[1] = 29; + } + + return d >= 1 && d <= daysInMonth[m - 1]; + } catch (NumberFormatException e) { + return false; + } + } + + /** + * @description 判断是否为闰年 + */ + private boolean isLeapYear(int year) { + return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0); + } + + /** + * @description 校验18位身份证的校验码 + */ + private boolean validateCheckCode(String idCard) { + int sum = 0; + for (int i = 0; i < 17; i++) { + sum += (idCard.charAt(i) - '0') * WEIGHT[i]; + } + + char checkCode = VALIDATE_CODE[sum % 11]; + return checkCode == idCard.charAt(17); + } + + @Override + public String getErrorMessage() { + return "请输入有效的身份证号码(15位或18位)"; + } + + @Override + public String getName() { + return "身份证号码校验"; + } +} + diff --git a/schoolNewsServ/common/common-util/src/main/java/org/xyzh/common/utils/validation/method/PasswordValidateMethod.java b/schoolNewsServ/common/common-util/src/main/java/org/xyzh/common/utils/validation/method/PasswordValidateMethod.java new file mode 100644 index 0000000..0abc6e1 --- /dev/null +++ b/schoolNewsServ/common/common-util/src/main/java/org/xyzh/common/utils/validation/method/PasswordValidateMethod.java @@ -0,0 +1,121 @@ +package org.xyzh.common.utils.validation.method; + +import java.util.regex.Pattern; + +/** + * @description 密码校验方法 + * @filename PasswordValidateMethod.java + * @author yslg + * @copyright xyzh + * @since 2025-10-16 + */ +public class PasswordValidateMethod implements ValidateMethod { + + private final int minLength; + private final int maxLength; + private final boolean requireUpperCase; + private final boolean requireLowerCase; + private final boolean requireDigit; + private final boolean requireSpecialChar; + + /** + * @description 默认密码规则:6-20位,必须包含字母和数字 + */ + public PasswordValidateMethod() { + this(6, 20, false, false, true, false); + } + + /** + * @description 自定义密码规则 + * @param minLength 最小长度 + * @param maxLength 最大长度 + * @param requireUpperCase 是否需要大写字母 + * @param requireLowerCase 是否需要小写字母 + * @param requireDigit 是否需要数字 + * @param requireSpecialChar 是否需要特殊字符 + */ + public PasswordValidateMethod(int minLength, int maxLength, + boolean requireUpperCase, boolean requireLowerCase, + boolean requireDigit, boolean requireSpecialChar) { + this.minLength = minLength; + this.maxLength = maxLength; + this.requireUpperCase = requireUpperCase; + this.requireLowerCase = requireLowerCase; + this.requireDigit = requireDigit; + this.requireSpecialChar = requireSpecialChar; + } + + @Override + public boolean validate(Object value) { + if (value == null || !(value instanceof String)) { + return false; + } + + String password = (String) value; + + // 长度校验 + if (password.length() < minLength || password.length() > maxLength) { + return false; + } + + // 大写字母校验 + if (requireUpperCase && !Pattern.compile("[A-Z]").matcher(password).find()) { + return false; + } + + // 小写字母校验 + if (requireLowerCase && !Pattern.compile("[a-z]").matcher(password).find()) { + return false; + } + + // 数字校验 + if (requireDigit && !Pattern.compile("[0-9]").matcher(password).find()) { + return false; + } + + // 特殊字符校验 + if (requireSpecialChar && !Pattern.compile("[!@#$%^&*()_+\\-=\\[\\]{};':\"\\\\|,.<>/?]").matcher(password).find()) { + return false; + } + + return true; + } + + @Override + public String getErrorMessage() { + StringBuilder msg = new StringBuilder("密码必须是"); + msg.append(minLength).append("-").append(maxLength).append("位"); + + if (requireUpperCase || requireLowerCase || requireDigit || requireSpecialChar) { + msg.append(",且包含"); + boolean first = true; + + if (requireUpperCase) { + msg.append("大写字母"); + first = false; + } + if (requireLowerCase) { + if (!first) msg.append("、"); + msg.append("小写字母"); + first = false; + } + if (requireDigit) { + if (!first) msg.append("、"); + msg.append("数字"); + first = false; + } + if (requireSpecialChar) { + if (!first) msg.append("、"); + msg.append("特殊字符"); + } + } + + return msg.toString(); + } + + @Override + public String getName() { + return "密码校验"; + } +} + diff --git a/schoolNewsServ/common/common-util/src/main/java/org/xyzh/common/utils/validation/method/PhoneValidateMethod.java b/schoolNewsServ/common/common-util/src/main/java/org/xyzh/common/utils/validation/method/PhoneValidateMethod.java new file mode 100644 index 0000000..dce9399 --- /dev/null +++ b/schoolNewsServ/common/common-util/src/main/java/org/xyzh/common/utils/validation/method/PhoneValidateMethod.java @@ -0,0 +1,65 @@ +package org.xyzh.common.utils.validation.method; + +import java.util.regex.Pattern; + +/** + * @description 手机号码校验方法 + * @filename PhoneValidateMethod.java + * @author yslg + * @copyright xyzh + * @since 2025-10-16 + */ +public class PhoneValidateMethod implements ValidateMethod { + + // 中国大陆手机号正则 + private static final Pattern CHINA_PHONE_PATTERN = Pattern.compile("^1[3-9]\\d{9}$"); + + // 香港手机号正则 + private static final Pattern HK_PHONE_PATTERN = Pattern.compile("^[5-9]\\d{7}$"); + + // 台湾手机号正则 + private static final Pattern TW_PHONE_PATTERN = Pattern.compile("^09\\d{8}$"); + + private final boolean strictMode; // 严格模式,只验证中国大陆手机号 + + public PhoneValidateMethod() { + this.strictMode = true; + } + + public PhoneValidateMethod(boolean strictMode) { + this.strictMode = strictMode; + } + + @Override + public boolean validate(Object value) { + if (value == null || !(value instanceof String)) { + return false; + } + + String phone = (String) value; + + // 去除空格和横线 + phone = phone.replaceAll("[\\s-]", ""); + + if (strictMode) { + // 严格模式:只验证中国大陆手机号 + return CHINA_PHONE_PATTERN.matcher(phone).matches(); + } else { + // 宽松模式:支持大陆、香港、台湾手机号 + return CHINA_PHONE_PATTERN.matcher(phone).matches() + || HK_PHONE_PATTERN.matcher(phone).matches() + || TW_PHONE_PATTERN.matcher(phone).matches(); + } + } + + @Override + public String getErrorMessage() { + return strictMode ? "请输入有效的手机号码" : "请输入有效的手机号码(支持大陆、香港、台湾)"; + } + + @Override + public String getName() { + return "手机号码校验"; + } +} + diff --git a/schoolNewsServ/common/common-util/src/main/java/org/xyzh/common/utils/validation/method/UrlValidateMethod.java b/schoolNewsServ/common/common-util/src/main/java/org/xyzh/common/utils/validation/method/UrlValidateMethod.java new file mode 100644 index 0000000..bce640f --- /dev/null +++ b/schoolNewsServ/common/common-util/src/main/java/org/xyzh/common/utils/validation/method/UrlValidateMethod.java @@ -0,0 +1,60 @@ +package org.xyzh.common.utils.validation.method; + +import java.util.regex.Pattern; + +/** + * @description URL校验方法 + * @filename UrlValidateMethod.java + * @author yslg + * @copyright xyzh + * @since 2025-10-16 + */ +public class UrlValidateMethod implements ValidateMethod { + + // URL正则表达式 + private static final Pattern URL_PATTERN = Pattern.compile( + "^(https?|ftp)://[a-zA-Z0-9+&@#/%?=~_|!:,.;-]*[a-zA-Z0-9+&@#/%=~_|-]$" + ); + + private final boolean requireHttps; // 是否要求HTTPS + + public UrlValidateMethod() { + this.requireHttps = false; + } + + public UrlValidateMethod(boolean requireHttps) { + this.requireHttps = requireHttps; + } + + @Override + public boolean validate(Object value) { + if (value == null || !(value instanceof String)) { + return false; + } + + String url = ((String) value).trim(); + + // 基本格式校验 + if (!URL_PATTERN.matcher(url).matches()) { + return false; + } + + // HTTPS校验 + if (requireHttps && !url.startsWith("https://")) { + return false; + } + + return true; + } + + @Override + public String getErrorMessage() { + return requireHttps ? "请输入有效的HTTPS链接" : "请输入有效的URL"; + } + + @Override + public String getName() { + return "URL校验"; + } +} + diff --git a/schoolNewsServ/common/common-util/src/main/java/org/xyzh/common/utils/validation/method/ValidateMethod.java b/schoolNewsServ/common/common-util/src/main/java/org/xyzh/common/utils/validation/method/ValidateMethod.java new file mode 100644 index 0000000..ec77de9 --- /dev/null +++ b/schoolNewsServ/common/common-util/src/main/java/org/xyzh/common/utils/validation/method/ValidateMethod.java @@ -0,0 +1,31 @@ +package org.xyzh.common.utils.validation.method; + +/** + * @description 校验方法接口,定义不同类型的校验方式 + * @filename ValidateMethod.java + * @author yslg + * @copyright xyzh + * @since 2025-10-16 + */ +public interface ValidateMethod { + + /** + * @description 校验方法 + * @param value 待校验的值 + * @return boolean 是否校验通过 + */ + boolean validate(Object value); + + /** + * @description 获取校验失败的错误提示信息 + * @return String 错误提示信息 + */ + String getErrorMessage(); + + /** + * @description 获取校验方法的名称 + * @return String 校验方法名称 + */ + String getName(); +} + diff --git a/schoolNewsServ/common/common-util/src/main/java/org/xyzh/common/utils/validation/method/ValidateMethodType.java b/schoolNewsServ/common/common-util/src/main/java/org/xyzh/common/utils/validation/method/ValidateMethodType.java new file mode 100644 index 0000000..930c964 --- /dev/null +++ b/schoolNewsServ/common/common-util/src/main/java/org/xyzh/common/utils/validation/method/ValidateMethodType.java @@ -0,0 +1,133 @@ +package org.xyzh.common.utils.validation.method; + +import java.util.function.Supplier; + +/** + * @description 校验方法类型枚举 + * @filename ValidateMethodType.java + * @author yslg + * @copyright xyzh + * @since 2025-10-16 + */ +public enum ValidateMethodType { + + /** + * 密码校验(默认:6-20位,必须包含字母和数字) + */ + PASSWORD("密码校验", PasswordValidateMethod.class, PasswordValidateMethod::new), + + /** + * 强密码校验(8-20位,必须包含大小写字母、数字和特殊字符) + */ + STRONG_PASSWORD("强密码校验", PasswordValidateMethod.class, + () -> new PasswordValidateMethod(8, 20, true, true, true, true)), + + /** + * 身份证号校验(支持15位和18位) + */ + ID_CARD("身份证号校验", IdCardValidateMethod.class, IdCardValidateMethod::new), + + /** + * 手机号码校验(中国大陆) + */ + PHONE("手机号码校验", PhoneValidateMethod.class, PhoneValidateMethod::new), + + /** + * 手机号码校验(宽松模式,支持大陆、香港、台湾) + */ + PHONE_LOOSE("手机号码校验(宽松)", PhoneValidateMethod.class, + () -> new PhoneValidateMethod(false)), + + /** + * 邮箱地址校验 + */ + EMAIL("邮箱地址校验", EmailValidateMethod.class, EmailValidateMethod::new), + + /** + * URL链接校验 + */ + URL("URL链接校验", UrlValidateMethod.class, UrlValidateMethod::new), + + /** + * HTTPS链接校验 + */ + HTTPS_URL("HTTPS链接校验", UrlValidateMethod.class, + () -> new UrlValidateMethod(true)), + + /** + * 银行卡号校验 + */ + BANK_CARD("银行卡号校验", BankCardValidateMethod.class, BankCardValidateMethod::new), + + /** + * 中文字符校验(纯中文) + */ + CHINESE("中文字符校验", ChineseValidateMethod.class, ChineseValidateMethod::new), + + /** + * 中文字符校验(允许标点符号) + */ + CHINESE_WITH_PUNCTUATION("中文字符校验(含标点)", ChineseValidateMethod.class, + () -> new ChineseValidateMethod(true)); + + /** + * 校验方法名称 + */ + private final String name; + + /** + * 校验方法实现类 + */ + private final Class methodClass; + + /** + * 校验方法实例提供者 + */ + private final Supplier methodSupplier; + + ValidateMethodType(String name, Class methodClass, + Supplier methodSupplier) { + this.name = name; + this.methodClass = methodClass; + this.methodSupplier = methodSupplier; + } + + /** + * @description 获取校验方法名称 + * @return String + */ + public String getName() { + return name; + } + + /** + * @description 获取校验方法实现类 + * @return Class + */ + public Class getMethodClass() { + return methodClass; + } + + /** + * @description 创建校验方法实例 + * @return ValidateMethod + */ + public ValidateMethod createInstance() { + return methodSupplier.get(); + } + + /** + * @description 根据名称获取枚举 + * @param name 名称 + * @return ValidateMethodType + */ + public static ValidateMethodType fromName(String name) { + for (ValidateMethodType type : values()) { + if (type.getName().equals(name)) { + return type; + } + } + return null; + } +} +