# 数据校验工具使用说明

## 概述

这是一个灵活、可扩展的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<ValidationParam> 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<ValidationParam> 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<String> errors = result.getErrors();
}
```

### 3. 使用ValidateMethod进行专业校验（兼容旧方式）

```java
List<ValidationParam> 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<ValidationParam> 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<User> register(@RequestBody Map<String, Object> params) {
    // 定义校验规则（使用枚举，更简洁）
    List<ValidationParam> 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<User> 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. 枚举方式和实例方式可以并存，但推荐统一使用枚举方式

