fix
This commit is contained in:
@@ -6,10 +6,9 @@
|
||||
|
||||
```
|
||||
internal/shared/validator/
|
||||
├── validator.go # HTTP请求验证器主逻辑
|
||||
├── validator.go # 统一校验器主逻辑(包含所有功能)
|
||||
├── custom_validators.go # 自定义验证器实现
|
||||
├── translations.go # 中文翻译
|
||||
├── business.go # 业务逻辑验证接口
|
||||
└── README.md # 使用说明
|
||||
```
|
||||
|
||||
@@ -22,9 +21,9 @@ internal/shared/validator/
|
||||
- 统一的错误响应格式
|
||||
|
||||
### 2. 业务逻辑验证
|
||||
- 独立的业务验证器
|
||||
- 可在任何地方调用的验证方法
|
||||
- 独立的业务验证方法,可在任何地方调用
|
||||
- 丰富的预定义验证规则
|
||||
- 与标签验证使用相同的校验逻辑
|
||||
|
||||
### 3. 自定义验证规则
|
||||
- 手机号验证 (`phone`)
|
||||
@@ -106,35 +105,32 @@ type ProductCommand struct {
|
||||
|
||||
### 3. 业务逻辑验证
|
||||
|
||||
在Service中使用:
|
||||
在Service中使用统一的校验方法:
|
||||
|
||||
```go
|
||||
import "tyapi-server/internal/shared/validator"
|
||||
|
||||
type UserService struct {
|
||||
businessValidator *validator.BusinessValidator
|
||||
}
|
||||
|
||||
func NewUserService() *UserService {
|
||||
return &UserService{
|
||||
businessValidator: validator.NewBusinessValidator(),
|
||||
}
|
||||
// 不再需要单独的businessValidator
|
||||
}
|
||||
|
||||
func (s *UserService) ValidateUserData(phone, password string) error {
|
||||
// 验证手机号
|
||||
if err := s.businessValidator.ValidatePhone(phone); err != nil {
|
||||
// 直接使用包级别的校验方法
|
||||
if err := validator.ValidatePhone(phone); err != nil {
|
||||
return fmt.Errorf("手机号验证失败: %w", err)
|
||||
}
|
||||
|
||||
// 验证密码强度
|
||||
if err := s.businessValidator.ValidatePassword(password); err != nil {
|
||||
if err := validator.ValidatePassword(password); err != nil {
|
||||
return fmt.Errorf("密码验证失败: %w", err)
|
||||
}
|
||||
|
||||
// 验证结构体
|
||||
userData := UserData{Phone: phone, Password: password}
|
||||
if err := s.businessValidator.ValidateStruct(userData); err != nil {
|
||||
// 也可以使用结构体验证
|
||||
userData := struct {
|
||||
Phone string `validate:"phone"`
|
||||
Password string `validate:"strong_password"`
|
||||
}{Phone: phone, Password: password}
|
||||
|
||||
if err := validator.GetGlobalValidator().Struct(userData); err != nil {
|
||||
return fmt.Errorf("用户数据验证失败: %w", err)
|
||||
}
|
||||
|
||||
@@ -142,13 +138,12 @@ func (s *UserService) ValidateUserData(phone, password string) error {
|
||||
}
|
||||
|
||||
func (s *UserService) ValidateEnterpriseInfo(code, idCard string) error {
|
||||
// 验证统一社会信用代码
|
||||
if err := s.businessValidator.ValidateSocialCreditCode(code); err != nil {
|
||||
// 直接使用包级别的校验方法
|
||||
if err := validator.ValidateSocialCreditCode(code); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 验证身份证号
|
||||
if err := s.businessValidator.ValidateIDCard(idCard); err != nil {
|
||||
if err := validator.ValidateIDCard(idCard); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -156,6 +151,27 @@ func (s *UserService) ValidateEnterpriseInfo(code, idCard string) error {
|
||||
}
|
||||
```
|
||||
|
||||
### 4. 处理器中的验证
|
||||
|
||||
在API处理器中,可以直接使用结构体验证:
|
||||
|
||||
```go
|
||||
// 在 flxg5a3b_processor.go 中
|
||||
func ProcessFLXG5A3BRequest(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) {
|
||||
var paramsDto dto.FLXG5A3BReq
|
||||
if err := json.Unmarshal(params, ¶msDto); err != nil {
|
||||
return nil, errors.Join(processors.ErrSystem, err)
|
||||
}
|
||||
|
||||
// 使用统一的校验器验证
|
||||
if err := deps.Validator.ValidateStruct(paramsDto); err != nil {
|
||||
return nil, errors.Join(processors.ErrInvalidParam, err)
|
||||
}
|
||||
|
||||
// ... 继续业务逻辑
|
||||
}
|
||||
```
|
||||
|
||||
## 🔧 可用的验证规则
|
||||
|
||||
### 标准验证规则
|
||||
@@ -208,23 +224,33 @@ fx.Provide(
|
||||
),
|
||||
```
|
||||
|
||||
业务验证器可以在需要时创建:
|
||||
|
||||
```go
|
||||
bv := validator.NewBusinessValidator()
|
||||
```
|
||||
|
||||
## 📝 最佳实践
|
||||
|
||||
1. **DTO验证**: 在DTO中使用binding标签进行声明式验证
|
||||
2. **业务验证**: 在业务逻辑中使用BusinessValidator进行程序化验证
|
||||
3. **错误处理**: 验证错误会自动返回统一格式的HTTP响应
|
||||
4. **性能**: 验证器实例可以复用,建议在依赖注入中管理
|
||||
2. **业务验证**: 在业务逻辑中直接使用 `validator.ValidateXXX()` 方法
|
||||
3. **统一性**: 所有校验都使用同一个校验器实例,确保规则一致
|
||||
4. **错误处理**: 验证错误会自动返回统一格式的HTTP响应
|
||||
|
||||
## 🧪 测试示例
|
||||
|
||||
参考 `examples/validator_usage.go` 文件中的完整使用示例。
|
||||
```go
|
||||
// 测试自定义校验规则
|
||||
func TestCustomValidators(t *testing.T) {
|
||||
validator.InitGlobalValidator()
|
||||
|
||||
// 测试手机号验证
|
||||
err := validator.ValidatePhone("13800138000")
|
||||
if err != nil {
|
||||
t.Errorf("有效手机号验证失败: %v", err)
|
||||
}
|
||||
|
||||
err = validator.ValidatePhone("12345")
|
||||
if err == nil {
|
||||
t.Error("无效手机号应该验证失败")
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
这个验证器包提供了完整的验证解决方案,既可以用于HTTP请求的自动验证,也可以在业务逻辑中进行程序化验证,确保数据的完整性和正确性。
|
||||
这个验证器包现在提供了完整的统一解决方案,既可以用于HTTP请求的自动验证,也可以在业务逻辑中进行程序化验证,确保数据的完整性和正确性。
|
||||
Reference in New Issue
Block a user