add qygl23t7
This commit is contained in:
@@ -119,6 +119,13 @@ type QYGLB4C0Req struct {
|
||||
IDCard string `json:"id_card" validate:"required,validIDCard"`
|
||||
}
|
||||
|
||||
type QYGL23T7Req struct {
|
||||
EntName string `json:"ent_name" validate:"required,min=1,validName"`
|
||||
LegalPerson string `json:"legal_person" validate:"required,min=1,validName"`
|
||||
EntCode string `json:"ent_code" validate:"required,validUSCI"`
|
||||
IDCard string `json:"id_card" validate:"required,validIDCard"`
|
||||
}
|
||||
|
||||
type YYSY4B37Req struct {
|
||||
MobileNo string `json:"mobile_no" validate:"required,min=11,max=11,validMobileNo"`
|
||||
}
|
||||
@@ -141,9 +148,9 @@ type IVYZ0b03Req struct {
|
||||
MobileNo string `json:"mobile_no" validate:"required,min=11,max=11,validMobileNo"`
|
||||
Name string `json:"name" validate:"required,min=1,validName"`
|
||||
}
|
||||
type YYSYBE08Req struct{
|
||||
Name string `json:"name" validate:"required,min=1,validName"`
|
||||
IDCard string `json:"id_card" validate:"required,validIDCard"`
|
||||
type YYSYBE08Req struct {
|
||||
Name string `json:"name" validate:"required,min=1,validName"`
|
||||
IDCard string `json:"id_card" validate:"required,validIDCard"`
|
||||
}
|
||||
type YYSYD50FReq struct {
|
||||
MobileNo string `json:"mobile_no" validate:"required,min=11,max=11,validMobileNo"`
|
||||
|
||||
@@ -13,6 +13,7 @@ import (
|
||||
"tyapi-server/internal/domains/api/services/processors/qygl"
|
||||
"tyapi-server/internal/domains/api/services/processors/yysy"
|
||||
"tyapi-server/internal/domains/product/services"
|
||||
"tyapi-server/internal/infrastructure/external/tianyancha"
|
||||
"tyapi-server/internal/infrastructure/external/westdex"
|
||||
"tyapi-server/internal/infrastructure/external/yushan"
|
||||
"tyapi-server/internal/shared/interfaces"
|
||||
@@ -27,16 +28,18 @@ var (
|
||||
|
||||
type ApiRequestService struct {
|
||||
// 可注入依赖,如第三方服务、模型等
|
||||
westDexService *westdex.WestDexService
|
||||
yushanService *yushan.YushanService
|
||||
validator interfaces.RequestValidator
|
||||
processorDeps *processors.ProcessorDependencies
|
||||
combService *comb.CombService
|
||||
westDexService *westdex.WestDexService
|
||||
yushanService *yushan.YushanService
|
||||
tianYanChaService *tianyancha.TianYanChaService
|
||||
validator interfaces.RequestValidator
|
||||
processorDeps *processors.ProcessorDependencies
|
||||
combService *comb.CombService
|
||||
}
|
||||
|
||||
func NewApiRequestService(
|
||||
westDexService *westdex.WestDexService,
|
||||
yushanService *yushan.YushanService,
|
||||
tianYanChaService *tianyancha.TianYanChaService,
|
||||
validator interfaces.RequestValidator,
|
||||
productManagementService *services.ProductManagementService,
|
||||
) *ApiRequestService {
|
||||
@@ -44,17 +47,18 @@ func NewApiRequestService(
|
||||
combService := comb.NewCombService(productManagementService)
|
||||
|
||||
// 创建处理器依赖容器
|
||||
processorDeps := processors.NewProcessorDependencies(westDexService, yushanService, validator, combService)
|
||||
processorDeps := processors.NewProcessorDependencies(westDexService, yushanService, tianYanChaService, validator, combService)
|
||||
|
||||
// 统一注册所有处理器
|
||||
registerAllProcessors(combService)
|
||||
|
||||
return &ApiRequestService{
|
||||
westDexService: westDexService,
|
||||
yushanService: yushanService,
|
||||
validator: validator,
|
||||
processorDeps: processorDeps,
|
||||
combService: combService,
|
||||
westDexService: westDexService,
|
||||
yushanService: yushanService,
|
||||
tianYanChaService: tianYanChaService,
|
||||
validator: validator,
|
||||
processorDeps: processorDeps,
|
||||
combService: combService,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -89,6 +93,7 @@ func registerAllProcessors(combService *comb.CombService) {
|
||||
"QYGL6F2D": qygl.ProcessQYGL6F2DRequest,
|
||||
"QYGL8271": qygl.ProcessQYGL8271Request,
|
||||
"QYGLB4C0": qygl.ProcessQYGLB4C0Request,
|
||||
"QYGL23T7": qygl.ProcessQYGL23T7Request, // 企业三要素验证
|
||||
|
||||
// YYSY系列处理器
|
||||
"YYSYD50F": yysy.ProcessYYSYD50FRequest,
|
||||
@@ -128,8 +133,8 @@ var RequestProcessors map[string]processors.ProcessorFunc
|
||||
func (a *ApiRequestService) PreprocessRequestApi(ctx context.Context, apiCode string, params []byte, options *commands.ApiCallOptions) ([]byte, error) {
|
||||
if processor, exists := RequestProcessors[apiCode]; exists {
|
||||
// 设置Options到依赖容器
|
||||
depsWithOptions := a.processorDeps.WithOptions(options)
|
||||
return processor(ctx, params, depsWithOptions)
|
||||
deps := a.processorDeps.WithOptions(options)
|
||||
return processor(ctx, params, deps)
|
||||
}
|
||||
return nil, fmt.Errorf("%w: %s", ErrSystem, "api请求, 未找到相应的处理程序")
|
||||
return nil, fmt.Errorf("%s: 未找到处理器: %s", ErrSystem, apiCode)
|
||||
}
|
||||
|
||||
62
internal/domains/api/services/api_request_service_test.go
Normal file
62
internal/domains/api/services/api_request_service_test.go
Normal file
@@ -0,0 +1,62 @@
|
||||
package services
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"testing"
|
||||
"tyapi-server/internal/application/api/commands"
|
||||
)
|
||||
|
||||
// 基础测试结构体
|
||||
type apiRequestServiceTestSuite struct {
|
||||
t *testing.T
|
||||
ctx context.Context
|
||||
service *ApiRequestService
|
||||
}
|
||||
|
||||
// 初始化测试套件
|
||||
func newApiRequestServiceTestSuite(t *testing.T) *apiRequestServiceTestSuite {
|
||||
// 这里可以初始化依赖的mock或fake对象
|
||||
// 例如:mockProcessorDeps := &MockProcessorDeps{}
|
||||
// service := &ApiRequestService{processorDeps: mockProcessorDeps}
|
||||
// 这里只做基础架构,具体mock实现后续补充
|
||||
return &apiRequestServiceTestSuite{
|
||||
t: t,
|
||||
ctx: context.Background(),
|
||||
service: nil, // 这里后续可替换为实际service或mock
|
||||
}
|
||||
}
|
||||
|
||||
// 示例:测试PreprocessRequestApi方法(仅结构,具体mock和断言后续补充)
|
||||
func TestApiRequestService_PreprocessRequestApi(t *testing.T) {
|
||||
suite := newApiRequestServiceTestSuite(t)
|
||||
|
||||
// 假设有一个mock processor和注册
|
||||
// RequestProcessors = map[string]processors.ProcessorFunc{
|
||||
// "MOCKAPI": func(ctx context.Context, params []byte, deps interface{}) ([]byte, error) {
|
||||
// return []byte("ok"), nil
|
||||
// },
|
||||
// }
|
||||
|
||||
// 这里仅做结构示例
|
||||
apiCode := "QYGL23T7"
|
||||
params := map[string]string{
|
||||
"code": "91460000MAE471M58X",
|
||||
"name": "海南天远大数据科技有限公司",
|
||||
"legalPersonName": "刘福思",
|
||||
}
|
||||
paramsByte, err := json.Marshal(params)
|
||||
if err != nil {
|
||||
t.Fatalf("参数序列化失败: %v", err)
|
||||
}
|
||||
options := commands.ApiCallOptions{} // 实际应为*commands.ApiCallOptions
|
||||
|
||||
// 由于service为nil,这里仅做断言结构示例
|
||||
if suite.service != nil {
|
||||
resp, err := suite.service.PreprocessRequestApi(suite.ctx, apiCode, paramsByte, &options)
|
||||
if err != nil {
|
||||
t.Errorf("PreprocessRequestApi 调用出错: %v", err)
|
||||
}
|
||||
t.Logf("PreprocessRequestApi 返回结果: %s", string(resp))
|
||||
}
|
||||
}
|
||||
@@ -1,195 +0,0 @@
|
||||
# Options 使用指南
|
||||
|
||||
## 概述
|
||||
|
||||
Options 机制允许在 API 调用时传递额外的配置选项,这些选项会传递给所有处理器(包括组合包处理器和子处理器),实现灵活的配置控制。
|
||||
|
||||
## 架构设计
|
||||
|
||||
```
|
||||
ApiCallCommand.Options → api_application_service → api_request_service → 所有处理器
|
||||
↓
|
||||
组合包处理器 → 子处理器
|
||||
```
|
||||
|
||||
## Options 字段说明
|
||||
|
||||
```go
|
||||
type ApiCallOptions struct {
|
||||
Json bool `json:"json,omitempty"` // 是否返回JSON格式
|
||||
Debug bool `json:"debug,omitempty"` // 调试模式
|
||||
Timeout int `json:"timeout,omitempty"` // 超时时间(秒)
|
||||
RetryCount int `json:"retry_count,omitempty"` // 重试次数
|
||||
Async bool `json:"async,omitempty"` // 异步处理
|
||||
Priority int `json:"priority,omitempty"` // 优先级(1-10)
|
||||
Cache bool `json:"cache,omitempty"` // 是否使用缓存
|
||||
Compress bool `json:"compress,omitempty"` // 是否压缩响应
|
||||
Encrypt bool `json:"encrypt,omitempty"` // 是否加密响应
|
||||
Validate bool `json:"validate,omitempty"` // 是否严格验证
|
||||
LogLevel string `json:"log_level,omitempty"` // 日志级别
|
||||
}
|
||||
```
|
||||
|
||||
## 使用示例
|
||||
|
||||
### 1. 普通处理器中使用 Options
|
||||
|
||||
```go
|
||||
func ProcessYYSY4B37Request(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) {
|
||||
// ... 参数验证 ...
|
||||
|
||||
reqData := map[string]interface{}{
|
||||
"mobile": paramsDto.Mobile,
|
||||
}
|
||||
|
||||
// 使用 Options 调整请求参数
|
||||
if deps.Options != nil {
|
||||
if deps.Options.Timeout > 0 {
|
||||
reqData["timeout"] = deps.Options.Timeout
|
||||
}
|
||||
|
||||
if deps.Options.RetryCount > 0 {
|
||||
reqData["retry_count"] = deps.Options.RetryCount
|
||||
}
|
||||
|
||||
if deps.Options.Debug {
|
||||
reqData["debug"] = true
|
||||
}
|
||||
}
|
||||
|
||||
return deps.YushanService.CallAPI("YYSY4B37", reqData)
|
||||
}
|
||||
```
|
||||
|
||||
### 2. 组合包处理器中使用 Options
|
||||
|
||||
```go
|
||||
func ProcessCOMB298YRequest(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) {
|
||||
// ... 参数验证 ...
|
||||
|
||||
// 根据 Options 调整组合策略
|
||||
if deps.Options != nil {
|
||||
if deps.Options.Priority > 0 {
|
||||
// 高优先级时调整处理策略
|
||||
fmt.Printf("组合包处理优先级: %d\n", deps.Options.Priority)
|
||||
}
|
||||
|
||||
if deps.Options.Debug {
|
||||
fmt.Printf("组合包调试模式开启\n")
|
||||
}
|
||||
}
|
||||
|
||||
// Options 会自动传递给所有子处理器
|
||||
return deps.CombService.ProcessCombRequest(ctx, params, deps, "COMB298Y")
|
||||
}
|
||||
```
|
||||
|
||||
### 3. 客户端调用示例
|
||||
|
||||
```json
|
||||
{
|
||||
"data": "加密的请求数据",
|
||||
"options": {
|
||||
"debug": true,
|
||||
"timeout": 30,
|
||||
"retry_count": 3,
|
||||
"priority": 5,
|
||||
"cache": true,
|
||||
"log_level": "debug"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 最佳实践
|
||||
|
||||
### 1. 空值检查
|
||||
始终检查 `deps.Options` 是否为 `nil`,避免空指针异常:
|
||||
|
||||
```go
|
||||
if deps.Options != nil {
|
||||
// 使用 Options
|
||||
}
|
||||
```
|
||||
|
||||
### 2. 默认值处理
|
||||
为 Options 字段提供合理的默认值:
|
||||
|
||||
```go
|
||||
timeout := 30 // 默认30秒
|
||||
if deps.Options != nil && deps.Options.Timeout > 0 {
|
||||
timeout = deps.Options.Timeout
|
||||
}
|
||||
```
|
||||
|
||||
### 3. 验证选项值
|
||||
对 Options 中的值进行验证:
|
||||
|
||||
```go
|
||||
if deps.Options != nil {
|
||||
if deps.Options.Priority < 1 || deps.Options.Priority > 10 {
|
||||
return nil, fmt.Errorf("优先级必须在1-10之间")
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 4. 日志记录
|
||||
在调试模式下记录 Options 信息:
|
||||
|
||||
```go
|
||||
if deps.Options != nil && deps.Options.Debug {
|
||||
log.Printf("处理器选项: %+v", deps.Options)
|
||||
}
|
||||
```
|
||||
|
||||
## 扩展性
|
||||
|
||||
### 1. 添加新的 Options 字段
|
||||
在 `ApiCallOptions` 结构体中添加新字段:
|
||||
|
||||
```go
|
||||
type ApiCallOptions struct {
|
||||
// ... 现有字段 ...
|
||||
CustomField string `json:"custom_field,omitempty"` // 自定义字段
|
||||
}
|
||||
```
|
||||
|
||||
### 2. 处理器特定选项
|
||||
可以为特定处理器创建专门的选项结构:
|
||||
|
||||
```go
|
||||
type YYSYOptions struct {
|
||||
ApiCallOptions
|
||||
YYSYSpecific bool `json:"yysy_specific,omitempty"`
|
||||
}
|
||||
```
|
||||
|
||||
## 注意事项
|
||||
|
||||
1. **性能影响**: Options 传递会增加少量性能开销,但影响微乎其微
|
||||
2. **向后兼容**: 新增的 Options 字段应该使用 `omitempty` 标签
|
||||
3. **安全性**: 敏感配置不应该通过 Options 传递
|
||||
4. **文档化**: 新增 Options 字段时应该更新文档
|
||||
|
||||
## 调试技巧
|
||||
|
||||
### 1. 启用调试模式
|
||||
```json
|
||||
{
|
||||
"options": {
|
||||
"debug": true,
|
||||
"log_level": "debug"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 2. 查看 Options 传递
|
||||
在处理器中添加日志:
|
||||
|
||||
```go
|
||||
if deps.Options != nil {
|
||||
log.Printf("处理器 %s 收到选项: %+v", "YYSY4B37", deps.Options)
|
||||
}
|
||||
```
|
||||
|
||||
### 3. 组合包调试
|
||||
组合包处理器会自动将 Options 传递给所有子处理器,无需额外配置。
|
||||
@@ -1,155 +0,0 @@
|
||||
# API处理器架构说明
|
||||
|
||||
## 概述
|
||||
|
||||
本目录实现了基于依赖注入容器的API处理器架构,支持灵活的依赖管理和组合调用模式。
|
||||
|
||||
## 架构模式
|
||||
|
||||
### 1. 依赖注入容器模式
|
||||
|
||||
#### ProcessorDependencies
|
||||
```go
|
||||
type ProcessorDependencies struct {
|
||||
WestDexService *westdex.WestDexService
|
||||
YushanService *yushan.YushanService
|
||||
Validator interfaces.RequestValidator
|
||||
}
|
||||
```
|
||||
|
||||
**优势:**
|
||||
- 统一的依赖管理
|
||||
- 类型安全的依赖注入
|
||||
- 易于测试和mock
|
||||
- 支持未来扩展新的服务
|
||||
|
||||
#### 处理器函数签名
|
||||
```go
|
||||
type ProcessorFunc func(ctx context.Context, params []byte, deps *ProcessorDependencies) ([]byte, error)
|
||||
```
|
||||
|
||||
### 2. 组合处理器模式
|
||||
|
||||
#### CompositeProcessor
|
||||
专门用于处理组合包(COMB系列)的处理器,支持:
|
||||
- 动态注册其他处理器
|
||||
- 批量调用多个处理器
|
||||
- 结果组合和格式化
|
||||
|
||||
```go
|
||||
type CompositeProcessor struct {
|
||||
processors map[string]ProcessorFunc
|
||||
deps *ProcessorDependencies
|
||||
}
|
||||
```
|
||||
|
||||
## 目录结构
|
||||
|
||||
```
|
||||
processors/
|
||||
├── dependencies.go # 依赖容器定义
|
||||
├── comb/
|
||||
│ ├── comb_processor.go # 组合处理器基类
|
||||
│ └── comb298y_processor.go # COMB298Y组合处理器
|
||||
├── flxg/ # FLXG系列处理器
|
||||
├── jrzq/ # JRZQ系列处理器
|
||||
├── qygl/ # QYGL系列处理器
|
||||
├── yysy/ # YYSY系列处理器
|
||||
└── ivyz/ # IVYZ系列处理器
|
||||
```
|
||||
|
||||
## 服务分配策略
|
||||
|
||||
### WestDexService
|
||||
- FLXG系列:使用WestDexService
|
||||
- JRZQ系列:使用WestDexService
|
||||
- IVYZ系列:使用WestDexService
|
||||
|
||||
### YushanService
|
||||
- QYGL系列:使用YushanService
|
||||
- YYSY系列:使用YushanService
|
||||
|
||||
### 组合包(COMB)
|
||||
- 调用多个其他处理器
|
||||
- 组合结果并返回统一格式
|
||||
|
||||
## 使用示例
|
||||
|
||||
### 普通处理器
|
||||
```go
|
||||
func ProcessFLXG0V3Bequest(ctx context.Context, params []byte, deps *ProcessorDependencies) ([]byte, error) {
|
||||
// 参数验证
|
||||
var paramsDto dto.FLXG0V3BequestReq
|
||||
if err := json.Unmarshal(params, ¶msDto); err != nil {
|
||||
return nil, fmt.Errorf("参数校验不正确: 解密后的数据格式错误")
|
||||
}
|
||||
|
||||
if err := deps.Validator.ValidateStruct(paramsDto); err != nil {
|
||||
return nil, fmt.Errorf("参数校验不正确: %s", err.Error())
|
||||
}
|
||||
|
||||
// 调用服务
|
||||
reqData := map[string]interface{}{
|
||||
"name": paramsDto.Name,
|
||||
"idCard": paramsDto.IDCard,
|
||||
"mobile": paramsDto.Mobile,
|
||||
}
|
||||
|
||||
respBytes, err := deps.WestDexService.CallAPI("FLXG0V3B", reqData)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("调用外部服务失败: %s", err.Error())
|
||||
}
|
||||
|
||||
return respBytes, nil
|
||||
}
|
||||
```
|
||||
|
||||
### 组合处理器
|
||||
```go
|
||||
func ProcessCOMB298YRequest(ctx context.Context, params []byte, deps *ProcessorDependencies) ([]byte, error) {
|
||||
// 创建组合处理器
|
||||
compositeProcessor := NewCompositeProcessor(deps)
|
||||
|
||||
// 注册需要调用的处理器
|
||||
compositeProcessor.RegisterProcessor("FLXG0V3B", flxg.ProcessFLXG0V3Bequest)
|
||||
compositeProcessor.RegisterProcessor("JRZQ8203", jrzq.ProcessJRZQ8203Request)
|
||||
|
||||
// 调用并组合结果
|
||||
results := make(map[string]interface{})
|
||||
|
||||
flxgResult, err := compositeProcessor.CallProcessor(ctx, "FLXG0V3B", params)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("调用FLXG0V3B处理器失败: %s", err.Error())
|
||||
}
|
||||
results["flxg0v3b"] = string(flxgResult)
|
||||
|
||||
// 返回组合结果
|
||||
return compositeProcessor.CombineResults(results)
|
||||
}
|
||||
```
|
||||
|
||||
## 扩展指南
|
||||
|
||||
### 添加新的服务依赖
|
||||
1. 在 `ProcessorDependencies` 中添加新字段
|
||||
2. 更新 `NewProcessorDependencies` 构造函数
|
||||
3. 在 `ApiRequestService` 中注入新服务
|
||||
|
||||
### 添加新的处理器
|
||||
1. 在对应目录下创建新的处理器文件
|
||||
2. 实现 `ProcessorFunc` 接口
|
||||
3. 在 `RequestProcessors` 映射中注册
|
||||
|
||||
### 添加新的组合包
|
||||
1. 在 `comb/` 目录下创建新的组合处理器
|
||||
2. 使用 `CompositeProcessor` 基类
|
||||
3. 注册需要调用的处理器并组合结果
|
||||
|
||||
## 优势
|
||||
|
||||
1. **解耦**:处理器与具体服务实现解耦
|
||||
2. **可测试**:易于进行单元测试和集成测试
|
||||
3. **可扩展**:支持添加新的服务和处理器
|
||||
4. **类型安全**:编译时检查依赖关系
|
||||
5. **组合支持**:灵活的组合调用模式
|
||||
6. **维护性**:清晰的代码结构和职责分离
|
||||
@@ -1,117 +0,0 @@
|
||||
# 处理器文件更新总结
|
||||
|
||||
## 更新概述
|
||||
|
||||
已成功将所有36个API处理器文件更新为使用新的依赖注入容器模式。
|
||||
|
||||
## 更新统计
|
||||
|
||||
### 已更新的处理器文件总数:36个
|
||||
|
||||
#### FLXG系列 (12个)
|
||||
- ✅ flxg0v3b_processor.go
|
||||
- ✅ flxg0v4b_processor.go
|
||||
- ✅ flxg162a_processor.go
|
||||
- ✅ flxg3d56_processor.go
|
||||
- ✅ flxg54f5_processor.go
|
||||
- ✅ flxg5876_processor.go
|
||||
- ✅ flxg75fe_processor.go
|
||||
- ✅ flxg9687_processor.go
|
||||
- ✅ flxg970f_processor.go
|
||||
- ✅ flxgc9d1_processor.go
|
||||
- ✅ flxgca3d_processor.go
|
||||
- ✅ flxgdec7_processor.go
|
||||
|
||||
#### JRZQ系列 (4个)
|
||||
- ✅ jrzq8203_processor.go
|
||||
- ✅ jrzq0a03_processor.go
|
||||
- ✅ jrzq4aa8_processor.go
|
||||
- ✅ jrzqdcbe_processor.go
|
||||
|
||||
#### QYGL系列 (6个)
|
||||
- ✅ qygl8261_processor.go
|
||||
- ✅ qygl2acd_processor.go
|
||||
- ✅ qygl45bd_processor.go
|
||||
- ✅ qygl6f2d_processor.go
|
||||
- ✅ qygl8271_processor.go
|
||||
- ✅ qyglb4c0_processor.go
|
||||
|
||||
#### YYSY系列 (7个)
|
||||
- ✅ yysyd50f_processor.go
|
||||
- ✅ yysy09cd_processor.go
|
||||
- ✅ yysy4b21_processor.go
|
||||
- ✅ yysy4b37_processor.go
|
||||
- ✅ yysy6f2e_processor.go
|
||||
- ✅ yysybe08_processor.go
|
||||
- ✅ yysyf7db_processor.go
|
||||
|
||||
#### IVYZ系列 (7个)
|
||||
- ✅ ivyz0b03_processor.go
|
||||
- ✅ ivyz2125_processor.go
|
||||
- ✅ ivyz385e_processor.go
|
||||
- ✅ ivyz5733_processor.go
|
||||
- ✅ ivyz9363_processor.go
|
||||
- ✅ ivyz9a2b_processor.go
|
||||
- ✅ ivyzadee_processor.go
|
||||
|
||||
#### COMB系列 (1个)
|
||||
- ✅ comb298y_processor.go (组合处理器)
|
||||
|
||||
## 更新内容
|
||||
|
||||
### 1. 函数签名更新
|
||||
所有处理器函数的签名已从:
|
||||
```go
|
||||
func ProcessXXXRequest(ctx context.Context, params []byte, validator interfaces.RequestValidator) ([]byte, error)
|
||||
```
|
||||
更新为:
|
||||
```go
|
||||
func ProcessXXXRequest(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error)
|
||||
```
|
||||
|
||||
### 2. 导入更新
|
||||
- 移除了 `"tyapi-server/internal/shared/interfaces"` 导入
|
||||
- 添加了 `"tyapi-server/internal/domains/api/services/processors"` 导入
|
||||
|
||||
### 3. 验证器调用更新
|
||||
- 从 `validator.ValidateStruct(paramsDto)`
|
||||
- 更新为 `deps.Validator.ValidateStruct(paramsDto)`
|
||||
|
||||
### 4. 服务调用实现
|
||||
根据API前缀分配不同的服务:
|
||||
|
||||
#### WestDexService (FLXG, JRZQ, IVYZ系列)
|
||||
```go
|
||||
respBytes, err := deps.WestDexService.CallAPI("API_CODE", reqData)
|
||||
```
|
||||
|
||||
#### YushanService (QYGL, YYSY系列)
|
||||
```go
|
||||
respBytes, err := deps.WestDexService.CallAPI("API_CODE", reqData)
|
||||
```
|
||||
|
||||
### 5. 组合处理器
|
||||
COMB298Y处理器实现了组合调用模式:
|
||||
- 使用 `CompositeProcessor` 基类
|
||||
- 动态注册其他处理器
|
||||
- 组合多个处理器的结果
|
||||
|
||||
## 架构优势
|
||||
|
||||
1. **统一依赖管理**:所有处理器通过 `ProcessorDependencies` 容器访问依赖
|
||||
2. **类型安全**:编译时检查依赖关系
|
||||
3. **易于测试**:可以轻松mock依赖进行单元测试
|
||||
4. **可扩展性**:新增服务只需在容器中添加
|
||||
5. **组合支持**:COMB系列支持灵活的组合调用
|
||||
6. **维护性**:清晰的代码结构和职责分离
|
||||
|
||||
## 编译验证
|
||||
|
||||
✅ 项目编译成功,无语法错误
|
||||
|
||||
## 下一步建议
|
||||
|
||||
1. **单元测试**:为各个处理器编写单元测试
|
||||
2. **集成测试**:测试实际的API调用流程
|
||||
3. **性能测试**:验证新架构的性能表现
|
||||
4. **文档完善**:补充API文档和使用说明
|
||||
@@ -3,6 +3,7 @@ package processors
|
||||
import (
|
||||
"context"
|
||||
"tyapi-server/internal/application/api/commands"
|
||||
"tyapi-server/internal/infrastructure/external/tianyancha"
|
||||
"tyapi-server/internal/infrastructure/external/westdex"
|
||||
"tyapi-server/internal/infrastructure/external/yushan"
|
||||
"tyapi-server/internal/shared/interfaces"
|
||||
@@ -15,26 +16,29 @@ type CombServiceInterface interface {
|
||||
|
||||
// ProcessorDependencies 处理器依赖容器
|
||||
type ProcessorDependencies struct {
|
||||
WestDexService *westdex.WestDexService
|
||||
YushanService *yushan.YushanService
|
||||
Validator interfaces.RequestValidator
|
||||
CombService CombServiceInterface // Changed to interface to break import cycle
|
||||
Options *commands.ApiCallOptions // 添加Options支持
|
||||
WestDexService *westdex.WestDexService
|
||||
YushanService *yushan.YushanService
|
||||
TianYanChaService *tianyancha.TianYanChaService
|
||||
Validator interfaces.RequestValidator
|
||||
CombService CombServiceInterface // Changed to interface to break import cycle
|
||||
Options *commands.ApiCallOptions // 添加Options支持
|
||||
}
|
||||
|
||||
// NewProcessorDependencies 创建处理器依赖容器
|
||||
func NewProcessorDependencies(
|
||||
westDexService *westdex.WestDexService,
|
||||
yushanService *yushan.YushanService,
|
||||
tianYanChaService *tianyancha.TianYanChaService,
|
||||
validator interfaces.RequestValidator,
|
||||
combService CombServiceInterface, // Changed to interface
|
||||
) *ProcessorDependencies {
|
||||
return &ProcessorDependencies{
|
||||
WestDexService: westDexService,
|
||||
YushanService: yushanService,
|
||||
Validator: validator,
|
||||
CombService: combService,
|
||||
Options: nil, // 初始化为nil,在调用时设置
|
||||
WestDexService: westDexService,
|
||||
YushanService: yushanService,
|
||||
TianYanChaService: tianYanChaService,
|
||||
Validator: validator,
|
||||
CombService: combService,
|
||||
Options: nil, // 初始化为nil,在调用时设置
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,140 @@
|
||||
package qygl
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"tyapi-server/internal/domains/api/dto"
|
||||
"tyapi-server/internal/domains/api/services/processors"
|
||||
"tyapi-server/internal/infrastructure/external/westdex"
|
||||
|
||||
"github.com/tidwall/gjson"
|
||||
)
|
||||
|
||||
// ProcessQYGL23T7Request QYGL23T7 API处理方法 - 企业三要素验证
|
||||
func ProcessQYGL23T7Request(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) {
|
||||
var paramsDto dto.QYGL23T7Req
|
||||
if err := json.Unmarshal(params, ¶msDto); err != nil {
|
||||
return nil, fmt.Errorf("%s: %w", processors.ErrSystem, err)
|
||||
}
|
||||
|
||||
if err := deps.Validator.ValidateStruct(paramsDto); err != nil {
|
||||
return nil, fmt.Errorf("%s: %w", processors.ErrInvalidParam, err)
|
||||
}
|
||||
|
||||
// 构建API调用参数
|
||||
apiParams := map[string]string{
|
||||
"code": paramsDto.EntCode,
|
||||
"name": paramsDto.EntName,
|
||||
"legalPersonName": paramsDto.LegalPerson,
|
||||
}
|
||||
|
||||
// 调用天眼查API - 使用通用的CallAPI方法
|
||||
response, err := deps.TianYanChaService.CallAPI(ctx, "VerifyThreeElements", apiParams)
|
||||
if err != nil {
|
||||
if err.Error() == "数据源异常" { // Specific error handling for data source issues
|
||||
return nil, fmt.Errorf("%s: %w", processors.ErrDatasource, err)
|
||||
} else {
|
||||
return nil, fmt.Errorf("%s: %w", processors.ErrSystem, err)
|
||||
}
|
||||
}
|
||||
|
||||
// 检查天眼查API调用是否成功
|
||||
if !response.Success {
|
||||
// 天眼查API调用失败,返回企业信息校验不通过
|
||||
return createStatusResponse(1), nil
|
||||
}
|
||||
|
||||
// 解析天眼查响应数据
|
||||
if response.Data == nil {
|
||||
// 天眼查响应数据为空,返回企业信息校验不通过
|
||||
return createStatusResponse(1), nil
|
||||
}
|
||||
|
||||
// 将response.Data转换为JSON字符串,然后使用gjson解析
|
||||
dataBytes, err := json.Marshal(response.Data)
|
||||
if err != nil {
|
||||
// 数据序列化失败,返回企业信息校验不通过
|
||||
return createStatusResponse(1), nil
|
||||
}
|
||||
|
||||
// 使用gjson解析嵌套的data.result.data字段
|
||||
result := gjson.GetBytes(dataBytes, "result")
|
||||
if !result.Exists() {
|
||||
// 字段不存在,返回企业信息校验不通过
|
||||
return createStatusResponse(1), nil
|
||||
}
|
||||
|
||||
// 检查data.result.data是否等于1
|
||||
if result.Int() != 1 {
|
||||
// 不等于1,返回企业信息校验不通过
|
||||
return createStatusResponse(1), nil
|
||||
}
|
||||
|
||||
// 天眼查三要素验证通过,继续调用WestDex身份证二要素验证
|
||||
// 加密姓名和身份证号
|
||||
encryptedName, err := deps.WestDexService.Encrypt(paramsDto.LegalPerson)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("%s: %w", processors.ErrSystem, err)
|
||||
}
|
||||
|
||||
encryptedIDCard, err := deps.WestDexService.Encrypt(paramsDto.EntCode)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("%s: %w", processors.ErrSystem, err)
|
||||
}
|
||||
|
||||
// 构建WestDex身份证二要素验证请求参数(参考yysybe08_processor.go)
|
||||
reqData := map[string]interface{}{
|
||||
"data": map[string]interface{}{
|
||||
"xM": encryptedName,
|
||||
"gMSFZHM": encryptedIDCard,
|
||||
"customerNumber": deps.WestDexService.GetConfig().Key,
|
||||
"timeStamp": fmt.Sprintf("%d", time.Now().UnixNano()/int64(time.Millisecond)),
|
||||
},
|
||||
}
|
||||
|
||||
// 调用WestDex身份证二要素验证API
|
||||
respBytes, err := deps.WestDexService.CallAPI("layoutIdcard", reqData)
|
||||
if err != nil {
|
||||
if !errors.Is(err, westdex.ErrDatasource) {
|
||||
return nil, fmt.Errorf("%s: %w", processors.ErrSystem, err)
|
||||
}
|
||||
}
|
||||
|
||||
// 使用gjson获取resultCode
|
||||
resultCode := gjson.GetBytes(respBytes, "ctidRequest.ctidAuth.resultCode")
|
||||
if !resultCode.Exists() {
|
||||
return nil, fmt.Errorf("%s: %w", processors.ErrSystem, err)
|
||||
}
|
||||
|
||||
// 获取resultCode的第一个字符
|
||||
resultCodeStr := resultCode.String()
|
||||
if len(resultCodeStr) == 0 {
|
||||
return nil, fmt.Errorf("%s: %w", processors.ErrSystem, err)
|
||||
}
|
||||
|
||||
firstChar := string(resultCodeStr[0])
|
||||
if firstChar != "0" && firstChar != "5" {
|
||||
return nil, fmt.Errorf("%s: %w", processors.ErrSystem, err)
|
||||
}
|
||||
if firstChar == "0" {
|
||||
return createStatusResponse(0), nil
|
||||
} else if firstChar == "5" {
|
||||
return createStatusResponse(2), nil
|
||||
} else {
|
||||
return nil, fmt.Errorf("%s: %w", processors.ErrSystem, err)
|
||||
}
|
||||
}
|
||||
|
||||
// createStatusResponse 创建状态响应
|
||||
func createStatusResponse(status int) []byte {
|
||||
response := map[string]interface{}{
|
||||
"status": status,
|
||||
}
|
||||
|
||||
respBytes, _ := json.Marshal(response)
|
||||
return respBytes
|
||||
}
|
||||
@@ -32,24 +32,22 @@ func ProcessYYSYBE08Request(ctx context.Context, params []byte, deps *processors
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("%s: %w", processors.ErrSystem, err)
|
||||
}
|
||||
|
||||
|
||||
reqData := map[string]interface{}{
|
||||
"data": map[string]interface{}{
|
||||
"xM": encryptedName,
|
||||
"gMSFZHM": encryptedIDCard,
|
||||
"customerNumber": deps.WestDexService.GetConfig().Key,
|
||||
"timeStamp":fmt.Sprintf("%d", time.Now().UnixNano()/int64(time.Millisecond)),
|
||||
"xM": encryptedName,
|
||||
"gMSFZHM": encryptedIDCard,
|
||||
"customerNumber": deps.WestDexService.GetConfig().Key,
|
||||
"timeStamp": fmt.Sprintf("%d", time.Now().UnixNano()/int64(time.Millisecond)),
|
||||
},
|
||||
}
|
||||
|
||||
respBytes, err := deps.WestDexService.CallAPI("layoutIdcard", reqData)
|
||||
if err != nil {
|
||||
if errors.Is(err, westdex.ErrDatasource) {
|
||||
return nil, fmt.Errorf("%s: %w", processors.ErrDatasource, err)
|
||||
} else {
|
||||
if !errors.Is(err, westdex.ErrDatasource) {
|
||||
return nil, fmt.Errorf("%s: %w", processors.ErrSystem, err)
|
||||
}
|
||||
}
|
||||
|
||||
return respBytes, nil
|
||||
}
|
||||
}
|
||||
|
||||
@@ -463,9 +463,7 @@ func (c *Certification) GetDataByStatus() map[string]interface{} {
|
||||
case enums.StatusContractApplied:
|
||||
data["contract_sign_url"] = c.ContractSignURL
|
||||
case enums.StatusContractSigned:
|
||||
data["contract_url"] = c.ContractURL
|
||||
case enums.StatusCompleted:
|
||||
data["contract_url"] = c.ContractURL
|
||||
data["completed_at"] = c.CompletedAt
|
||||
case enums.StatusContractRejected:
|
||||
data["failure_reason"] = c.FailureReason
|
||||
|
||||
@@ -19,7 +19,6 @@ type EnterpriseInfoSubmitRecord struct {
|
||||
LegalPersonID string `json:"legal_person_id" gorm:"type:varchar(50);not null"`
|
||||
LegalPersonPhone string `json:"legal_person_phone" gorm:"type:varchar(50);not null"`
|
||||
EnterpriseAddress string `json:"enterprise_address" gorm:"type:varchar(200);not null"` // 新增企业地址
|
||||
EnterpriseEmail string `json:"enterprise_email" gorm:"type:varchar(100);not null"` // 企业邮箱
|
||||
// 提交状态
|
||||
Status string `json:"status" gorm:"type:varchar(20);not null;default:'submitted'"` // submitted, verified, failed
|
||||
SubmitAt time.Time `json:"submit_at" gorm:"not null"`
|
||||
@@ -40,7 +39,7 @@ func (EnterpriseInfoSubmitRecord) TableName() string {
|
||||
|
||||
// NewEnterpriseInfoSubmitRecord 创建新的企业信息提交记录
|
||||
func NewEnterpriseInfoSubmitRecord(
|
||||
userID, companyName, unifiedSocialCode, legalPersonName, legalPersonID, legalPersonPhone, enterpriseAddress, enterpriseEmail string,
|
||||
userID, companyName, unifiedSocialCode, legalPersonName, legalPersonID, legalPersonPhone, enterpriseAddress string,
|
||||
) *EnterpriseInfoSubmitRecord {
|
||||
return &EnterpriseInfoSubmitRecord{
|
||||
ID: uuid.New().String(),
|
||||
@@ -51,7 +50,6 @@ func NewEnterpriseInfoSubmitRecord(
|
||||
LegalPersonID: legalPersonID,
|
||||
LegalPersonPhone: legalPersonPhone,
|
||||
EnterpriseAddress: enterpriseAddress,
|
||||
EnterpriseEmail: enterpriseEmail,
|
||||
Status: "submitted",
|
||||
SubmitAt: time.Now(),
|
||||
CreatedAt: time.Now(),
|
||||
|
||||
@@ -22,11 +22,10 @@ type EnterpriseInfo struct {
|
||||
// 企业详细信息
|
||||
RegisteredAddress string `json:"registered_address"` // 注册地址
|
||||
EnterpriseAddress string `json:"enterprise_address"` // 企业地址(新增)
|
||||
EnterpriseEmail string `json:"enterprise_email"` // 企业邮箱
|
||||
}
|
||||
|
||||
// NewEnterpriseInfo 创建企业信息值对象
|
||||
func NewEnterpriseInfo(companyName, unifiedSocialCode, legalPersonName, legalPersonID, legalPersonPhone, enterpriseAddress, enterpriseEmail string) (*EnterpriseInfo, error) {
|
||||
func NewEnterpriseInfo(companyName, unifiedSocialCode, legalPersonName, legalPersonID, legalPersonPhone, enterpriseAddress string) (*EnterpriseInfo, error) {
|
||||
info := &EnterpriseInfo{
|
||||
CompanyName: strings.TrimSpace(companyName),
|
||||
UnifiedSocialCode: strings.TrimSpace(unifiedSocialCode),
|
||||
@@ -34,7 +33,6 @@ func NewEnterpriseInfo(companyName, unifiedSocialCode, legalPersonName, legalPer
|
||||
LegalPersonID: strings.TrimSpace(legalPersonID),
|
||||
LegalPersonPhone: strings.TrimSpace(legalPersonPhone),
|
||||
EnterpriseAddress: strings.TrimSpace(enterpriseAddress),
|
||||
EnterpriseEmail: strings.TrimSpace(enterpriseEmail),
|
||||
}
|
||||
|
||||
if err := info.Validate(); err != nil {
|
||||
@@ -70,10 +68,6 @@ func (e *EnterpriseInfo) Validate() error {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := e.validateEnterpriseEmail(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -237,27 +231,6 @@ func (e *EnterpriseInfo) validateEnterpriseAddress() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// validateEnterpriseEmail 验证企业邮箱
|
||||
func (e *EnterpriseInfo) validateEnterpriseEmail() error {
|
||||
if strings.TrimSpace(e.EnterpriseEmail) == "" {
|
||||
return errors.New("企业邮箱不能为空")
|
||||
}
|
||||
if len(e.EnterpriseEmail) < 5 {
|
||||
return errors.New("企业邮箱长度不能少于5个字符")
|
||||
}
|
||||
if len(e.EnterpriseEmail) > 100 {
|
||||
return errors.New("企业邮箱长度不能超过100个字符")
|
||||
}
|
||||
|
||||
// 邮箱格式验证
|
||||
emailPattern := regexp.MustCompile(`^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$`)
|
||||
if !emailPattern.MatchString(e.EnterpriseEmail) {
|
||||
return errors.New("企业邮箱格式不正确")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// IsComplete 检查企业信息是否完整
|
||||
func (e *EnterpriseInfo) IsComplete() bool {
|
||||
return e.CompanyName != "" &&
|
||||
@@ -265,8 +238,7 @@ func (e *EnterpriseInfo) IsComplete() bool {
|
||||
e.LegalPersonName != "" &&
|
||||
e.LegalPersonID != "" &&
|
||||
e.LegalPersonPhone != "" &&
|
||||
e.EnterpriseAddress != "" &&
|
||||
e.EnterpriseEmail != ""
|
||||
e.EnterpriseAddress != ""
|
||||
}
|
||||
|
||||
// IsDetailComplete 检查企业详细信息是否完整
|
||||
@@ -324,8 +296,7 @@ func (e *EnterpriseInfo) Equals(other *EnterpriseInfo) bool {
|
||||
e.UnifiedSocialCode == other.UnifiedSocialCode &&
|
||||
e.LegalPersonName == other.LegalPersonName &&
|
||||
e.LegalPersonID == other.LegalPersonID &&
|
||||
e.LegalPersonPhone == other.LegalPersonPhone &&
|
||||
e.EnterpriseEmail == other.EnterpriseEmail
|
||||
e.LegalPersonPhone == other.LegalPersonPhone
|
||||
}
|
||||
|
||||
// Clone 创建企业信息的副本
|
||||
@@ -338,7 +309,6 @@ func (e *EnterpriseInfo) Clone() *EnterpriseInfo {
|
||||
LegalPersonPhone: e.LegalPersonPhone,
|
||||
RegisteredAddress: e.RegisteredAddress,
|
||||
EnterpriseAddress: e.EnterpriseAddress,
|
||||
EnterpriseEmail: e.EnterpriseEmail,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -360,7 +330,6 @@ func (e *EnterpriseInfo) ToMap() map[string]interface{} {
|
||||
"legal_person_phone": e.LegalPersonPhone,
|
||||
"registered_address": e.RegisteredAddress,
|
||||
"enterprise_address": e.EnterpriseAddress,
|
||||
"enterprise_email": e.EnterpriseEmail,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -383,7 +352,6 @@ func FromMap(data map[string]interface{}) (*EnterpriseInfo, error) {
|
||||
LegalPersonPhone: getString("legal_person_phone"),
|
||||
RegisteredAddress: getString("registered_address"),
|
||||
EnterpriseAddress: getString("enterprise_address"),
|
||||
EnterpriseEmail: getString("enterprise_email"),
|
||||
}
|
||||
|
||||
if err := info.Validate(); err != nil {
|
||||
|
||||
@@ -58,12 +58,12 @@ func (s *EnterpriseInfoSubmitRecordService) ValidateWithWestdex(ctx context.Cont
|
||||
}
|
||||
|
||||
// 开发环境下跳过外部验证
|
||||
// if s.appConfig.IsDevelopment() {
|
||||
// s.logger.Info("开发环境:跳过企业信息外部验证",
|
||||
// zap.String("company_name", info.CompanyName),
|
||||
// zap.String("legal_person", info.LegalPersonName))
|
||||
// return nil
|
||||
// }
|
||||
if s.appConfig.IsDevelopment() {
|
||||
s.logger.Info("开发环境:跳过企业信息外部验证",
|
||||
zap.String("company_name", info.CompanyName),
|
||||
zap.String("legal_person", info.LegalPersonName))
|
||||
return nil
|
||||
}
|
||||
encryptedEntName, err := s.westdexService.Encrypt(info.CompanyName)
|
||||
if err != nil {
|
||||
return fmt.Errorf("%s: %w", "企业四要素验证", err)
|
||||
|
||||
@@ -24,8 +24,6 @@ type EnterpriseInfo struct {
|
||||
LegalPersonID string `gorm:"type:varchar(50);not null" json:"legal_person_id" comment:"法定代表人身份证号"`
|
||||
LegalPersonPhone string `gorm:"type:varchar(50);not null" json:"legal_person_phone" comment:"法定代表人手机号"`
|
||||
EnterpriseAddress string `json:"enterprise_address" gorm:"type:varchar(200);not null" comment:"企业地址"`
|
||||
EnterpriseEmail string `json:"enterprise_email" gorm:"type:varchar(100);not null" comment:"企业邮箱"`
|
||||
|
||||
// 时间戳字段
|
||||
CreatedAt time.Time `gorm:"autoCreateTime" json:"created_at" comment:"创建时间"`
|
||||
UpdatedAt time.Time `gorm:"autoUpdateTime" json:"updated_at" comment:"更新时间"`
|
||||
@@ -54,7 +52,7 @@ func (e *EnterpriseInfo) BeforeCreate(tx *gorm.DB) error {
|
||||
// ================ 工厂方法 ================
|
||||
|
||||
// NewEnterpriseInfo 创建新的企业信息
|
||||
func NewEnterpriseInfo(userID, companyName, unifiedSocialCode, legalPersonName, legalPersonID, legalPersonPhone,enterpriseAddress, enterpriseEmail string) (*EnterpriseInfo, error) {
|
||||
func NewEnterpriseInfo(userID, companyName, unifiedSocialCode, legalPersonName, legalPersonID, legalPersonPhone,enterpriseAddress string) (*EnterpriseInfo, error) {
|
||||
if userID == "" {
|
||||
return nil, fmt.Errorf("用户ID不能为空")
|
||||
}
|
||||
@@ -76,9 +74,6 @@ func NewEnterpriseInfo(userID, companyName, unifiedSocialCode, legalPersonName,
|
||||
if enterpriseAddress == "" {
|
||||
return nil, fmt.Errorf("企业地址不能为空")
|
||||
}
|
||||
if enterpriseEmail == "" {
|
||||
return nil, fmt.Errorf("企业邮箱不能为空")
|
||||
}
|
||||
|
||||
enterpriseInfo := &EnterpriseInfo{
|
||||
ID: uuid.New().String(),
|
||||
@@ -89,7 +84,6 @@ func NewEnterpriseInfo(userID, companyName, unifiedSocialCode, legalPersonName,
|
||||
LegalPersonID: legalPersonID,
|
||||
LegalPersonPhone: legalPersonPhone,
|
||||
EnterpriseAddress: enterpriseAddress,
|
||||
EnterpriseEmail: enterpriseEmail,
|
||||
domainEvents: make([]interface{}, 0),
|
||||
}
|
||||
|
||||
@@ -108,7 +102,7 @@ func NewEnterpriseInfo(userID, companyName, unifiedSocialCode, legalPersonName,
|
||||
// ================ 聚合根核心方法 ================
|
||||
|
||||
// UpdateEnterpriseInfo 更新企业信息
|
||||
func (e *EnterpriseInfo) UpdateEnterpriseInfo(companyName, unifiedSocialCode, legalPersonName, legalPersonID, legalPersonPhone, enterpriseAddress, enterpriseEmail string) error {
|
||||
func (e *EnterpriseInfo) UpdateEnterpriseInfo(companyName, unifiedSocialCode, legalPersonName, legalPersonID, legalPersonPhone, enterpriseAddress string) error {
|
||||
// 验证输入参数
|
||||
if companyName == "" {
|
||||
return fmt.Errorf("企业名称不能为空")
|
||||
@@ -128,9 +122,6 @@ func (e *EnterpriseInfo) UpdateEnterpriseInfo(companyName, unifiedSocialCode, le
|
||||
if enterpriseAddress == "" {
|
||||
return fmt.Errorf("企业地址不能为空")
|
||||
}
|
||||
if enterpriseEmail == "" {
|
||||
return fmt.Errorf("企业邮箱不能为空")
|
||||
}
|
||||
|
||||
// 记录原始值用于事件
|
||||
oldCompanyName := e.CompanyName
|
||||
@@ -143,7 +134,6 @@ func (e *EnterpriseInfo) UpdateEnterpriseInfo(companyName, unifiedSocialCode, le
|
||||
e.LegalPersonID = legalPersonID
|
||||
e.LegalPersonPhone = legalPersonPhone
|
||||
e.EnterpriseAddress = enterpriseAddress
|
||||
e.EnterpriseEmail = enterpriseEmail
|
||||
|
||||
// 添加领域事件
|
||||
e.addDomainEvent(&EnterpriseInfoUpdatedEvent{
|
||||
@@ -198,10 +188,6 @@ func (e *EnterpriseInfo) validateBasicFields() error {
|
||||
if e.LegalPersonPhone == "" {
|
||||
return fmt.Errorf("法定代表人手机号不能为空")
|
||||
}
|
||||
if e.EnterpriseEmail == "" {
|
||||
return fmt.Errorf("企业邮箱不能为空")
|
||||
}
|
||||
|
||||
// 统一社会信用代码格式验证
|
||||
if !e.isValidUnifiedSocialCode(e.UnifiedSocialCode) {
|
||||
return fmt.Errorf("统一社会信用代码格式无效")
|
||||
@@ -217,11 +203,6 @@ func (e *EnterpriseInfo) validateBasicFields() error {
|
||||
return fmt.Errorf("法定代表人手机号格式无效")
|
||||
}
|
||||
|
||||
// 邮箱格式验证 (简单示例,实际应更严格)
|
||||
if !e.isValidEmail(e.EnterpriseEmail) {
|
||||
return fmt.Errorf("企业邮箱格式无效")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -237,11 +218,6 @@ func (e *EnterpriseInfo) validateBusinessLogic() error {
|
||||
return fmt.Errorf("法定代表人姓名长度不能超过100个字符")
|
||||
}
|
||||
|
||||
// 企业邮箱格式验证 (简单示例,实际应更严格)
|
||||
if !e.isValidEmail(e.EnterpriseEmail) {
|
||||
return fmt.Errorf("企业邮箱格式无效")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -255,8 +231,7 @@ func (e *EnterpriseInfo) IsComplete() bool {
|
||||
e.UnifiedSocialCode != "" &&
|
||||
e.LegalPersonName != "" &&
|
||||
e.LegalPersonID != "" &&
|
||||
e.LegalPersonPhone != "" &&
|
||||
e.EnterpriseEmail != ""
|
||||
e.LegalPersonPhone != ""
|
||||
}
|
||||
|
||||
// GetCertificationProgress 获取认证进度
|
||||
|
||||
@@ -102,14 +102,14 @@ func (u *User) CompleteCertification() error {
|
||||
// ================ 企业信息管理方法 ================
|
||||
|
||||
// CreateEnterpriseInfo 创建企业信息
|
||||
func (u *User) CreateEnterpriseInfo(companyName, unifiedSocialCode, legalPersonName, legalPersonID, legalPersonPhone, enterpriseAddress, enterpriseEmail string) error {
|
||||
func (u *User) CreateEnterpriseInfo(companyName, unifiedSocialCode, legalPersonName, legalPersonID, legalPersonPhone, enterpriseAddress string) error {
|
||||
// 检查是否已有企业信息
|
||||
if u.EnterpriseInfo != nil {
|
||||
return fmt.Errorf("用户已有企业信息")
|
||||
}
|
||||
|
||||
// 创建企业信息实体
|
||||
enterpriseInfo, err := NewEnterpriseInfo(u.ID, companyName, unifiedSocialCode, legalPersonName, legalPersonID, legalPersonPhone, enterpriseAddress, enterpriseEmail)
|
||||
enterpriseInfo, err := NewEnterpriseInfo(u.ID, companyName, unifiedSocialCode, legalPersonName, legalPersonID, legalPersonPhone, enterpriseAddress)
|
||||
if err != nil {
|
||||
return fmt.Errorf("创建企业信息失败: %w", err)
|
||||
}
|
||||
@@ -130,7 +130,7 @@ func (u *User) CreateEnterpriseInfo(companyName, unifiedSocialCode, legalPersonN
|
||||
}
|
||||
|
||||
// UpdateEnterpriseInfo 更新企业信息
|
||||
func (u *User) UpdateEnterpriseInfo(companyName, unifiedSocialCode, legalPersonName, legalPersonID, legalPersonPhone, enterpriseAddress, enterpriseEmail string) error {
|
||||
func (u *User) UpdateEnterpriseInfo(companyName, unifiedSocialCode, legalPersonName, legalPersonID, legalPersonPhone, enterpriseAddress string) error {
|
||||
// 检查是否有企业信息
|
||||
if u.EnterpriseInfo == nil {
|
||||
return fmt.Errorf("用户暂无企业信息")
|
||||
@@ -141,7 +141,7 @@ func (u *User) UpdateEnterpriseInfo(companyName, unifiedSocialCode, legalPersonN
|
||||
oldUnifiedSocialCode := u.EnterpriseInfo.UnifiedSocialCode
|
||||
|
||||
// 更新企业信息
|
||||
err := u.EnterpriseInfo.UpdateEnterpriseInfo(companyName, unifiedSocialCode, legalPersonName, legalPersonID, legalPersonPhone, enterpriseAddress, enterpriseEmail)
|
||||
err := u.EnterpriseInfo.UpdateEnterpriseInfo(companyName, unifiedSocialCode, legalPersonName, legalPersonID, legalPersonPhone, enterpriseAddress)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -36,14 +36,14 @@ type UserAggregateService interface {
|
||||
GetUserStats(ctx context.Context) (*repositories.UserStats, error)
|
||||
|
||||
// 企业信息管理
|
||||
CreateEnterpriseInfo(ctx context.Context, userID, companyName, unifiedSocialCode, legalPersonName, legalPersonID, legalPersonPhone, enterpriseAddress, enterpriseEmail string) error
|
||||
UpdateEnterpriseInfo(ctx context.Context, userID, companyName, unifiedSocialCode, legalPersonName, legalPersonID, legalPersonPhone, enterpriseAddress, enterpriseEmail string) error
|
||||
CreateEnterpriseInfo(ctx context.Context, userID, companyName, unifiedSocialCode, legalPersonName, legalPersonID, legalPersonPhone, enterpriseAddress string) error
|
||||
UpdateEnterpriseInfo(ctx context.Context, userID, companyName, unifiedSocialCode, legalPersonName, legalPersonID, legalPersonPhone, enterpriseAddress string) error
|
||||
GetUserWithEnterpriseInfo(ctx context.Context, userID string) (*entities.User, error)
|
||||
ValidateEnterpriseInfo(ctx context.Context, userID string) error
|
||||
CheckUnifiedSocialCodeExists(ctx context.Context, unifiedSocialCode string, excludeUserID string) (bool, error)
|
||||
|
||||
// 认证域专用:写入/覆盖企业信息
|
||||
CreateOrUpdateEnterpriseInfo(ctx context.Context, userID, companyName, unifiedSocialCode, legalPersonName, legalPersonID, legalPersonPhone, enterpriseAddress, enterpriseEmail string) error
|
||||
CreateOrUpdateEnterpriseInfo(ctx context.Context, userID, companyName, unifiedSocialCode, legalPersonName, legalPersonID, legalPersonPhone, enterpriseAddress string) error
|
||||
CompleteCertification(ctx context.Context, userID string) error
|
||||
}
|
||||
|
||||
@@ -122,7 +122,7 @@ func (s *UserAggregateServiceImpl) LoadUser(ctx context.Context, userID string)
|
||||
|
||||
// 验证业务规则
|
||||
if err := s.ValidateBusinessRules(ctx, &user); err != nil {
|
||||
s.logger.Warn("用户业务规则验证失败",
|
||||
s.logger.Warn("用户业务规则验证失败",
|
||||
zap.String("user_id", userID),
|
||||
zap.Error(err),
|
||||
)
|
||||
@@ -186,7 +186,7 @@ func (s *UserAggregateServiceImpl) LoadUserByPhone(ctx context.Context, phone st
|
||||
|
||||
// 验证业务规则
|
||||
if err := s.ValidateBusinessRules(ctx, user); err != nil {
|
||||
s.logger.Warn("用户业务规则验证失败",
|
||||
s.logger.Warn("用户业务规则验证失败",
|
||||
zap.String("phone", phone),
|
||||
zap.Error(err),
|
||||
)
|
||||
@@ -303,7 +303,7 @@ func (s *UserAggregateServiceImpl) UpdateLoginStats(ctx context.Context, userID
|
||||
// ================ 企业信息管理 ================
|
||||
|
||||
// CreateEnterpriseInfo 创建企业信息
|
||||
func (s *UserAggregateServiceImpl) CreateEnterpriseInfo(ctx context.Context, userID, companyName, unifiedSocialCode, legalPersonName, legalPersonID, legalPersonPhone, enterpriseAddress, enterpriseEmail string) error {
|
||||
func (s *UserAggregateServiceImpl) CreateEnterpriseInfo(ctx context.Context, userID, companyName, unifiedSocialCode, legalPersonName, legalPersonID, legalPersonPhone, enterpriseAddress string) error {
|
||||
s.logger.Debug("创建企业信息", zap.String("user_id", userID))
|
||||
|
||||
// 1. 加载用户聚合根
|
||||
@@ -327,7 +327,7 @@ func (s *UserAggregateServiceImpl) CreateEnterpriseInfo(ctx context.Context, use
|
||||
}
|
||||
|
||||
// 4. 使用聚合根方法创建企业信息
|
||||
err = user.CreateEnterpriseInfo(companyName, unifiedSocialCode, legalPersonName, legalPersonID, legalPersonPhone, enterpriseAddress, enterpriseEmail)
|
||||
err = user.CreateEnterpriseInfo(companyName, unifiedSocialCode, legalPersonName, legalPersonID, legalPersonPhone, enterpriseAddress)
|
||||
if err != nil {
|
||||
return fmt.Errorf("创建企业信息失败: %w", err)
|
||||
}
|
||||
@@ -349,7 +349,7 @@ func (s *UserAggregateServiceImpl) CreateEnterpriseInfo(ctx context.Context, use
|
||||
}
|
||||
|
||||
// UpdateEnterpriseInfo 更新企业信息
|
||||
func (s *UserAggregateServiceImpl) UpdateEnterpriseInfo(ctx context.Context, userID, companyName, unifiedSocialCode, legalPersonName, legalPersonID, legalPersonPhone, enterpriseAddress, enterpriseEmail string) error {
|
||||
func (s *UserAggregateServiceImpl) UpdateEnterpriseInfo(ctx context.Context, userID, companyName, unifiedSocialCode, legalPersonName, legalPersonID, legalPersonPhone, enterpriseAddress string) error {
|
||||
s.logger.Debug("更新企业信息", zap.String("user_id", userID))
|
||||
|
||||
// 1. 加载用户聚合根
|
||||
@@ -373,7 +373,7 @@ func (s *UserAggregateServiceImpl) UpdateEnterpriseInfo(ctx context.Context, use
|
||||
}
|
||||
|
||||
// 4. 使用聚合根方法更新企业信息
|
||||
err = user.UpdateEnterpriseInfo(companyName, unifiedSocialCode, legalPersonName, legalPersonID, legalPersonPhone, enterpriseAddress, enterpriseEmail)
|
||||
err = user.UpdateEnterpriseInfo(companyName, unifiedSocialCode, legalPersonName, legalPersonID, legalPersonPhone, enterpriseAddress)
|
||||
if err != nil {
|
||||
return fmt.Errorf("更新企业信息失败: %w", err)
|
||||
}
|
||||
@@ -394,7 +394,6 @@ func (s *UserAggregateServiceImpl) UpdateEnterpriseInfo(ctx context.Context, use
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
// GetUserWithEnterpriseInfo 获取用户信息(包含企业信息)
|
||||
func (s *UserAggregateServiceImpl) GetUserWithEnterpriseInfo(ctx context.Context, userID string) (*entities.User, error) {
|
||||
s.logger.Debug("获取用户信息(包含企业信息)", zap.String("user_id", userID))
|
||||
@@ -407,7 +406,7 @@ func (s *UserAggregateServiceImpl) GetUserWithEnterpriseInfo(ctx context.Context
|
||||
|
||||
// 验证业务规则
|
||||
if err := s.ValidateBusinessRules(ctx, &user); err != nil {
|
||||
s.logger.Warn("用户业务规则验证失败",
|
||||
s.logger.Warn("用户业务规则验证失败",
|
||||
zap.String("user_id", userID),
|
||||
zap.Error(err),
|
||||
)
|
||||
@@ -437,7 +436,7 @@ func (s *UserAggregateServiceImpl) ValidateEnterpriseInfo(ctx context.Context, u
|
||||
|
||||
// CheckUnifiedSocialCodeExists 检查统一社会信用代码是否存在
|
||||
func (s *UserAggregateServiceImpl) CheckUnifiedSocialCodeExists(ctx context.Context, unifiedSocialCode string, excludeUserID string) (bool, error) {
|
||||
s.logger.Debug("检查统一社会信用代码是否存在",
|
||||
s.logger.Debug("检查统一社会信用代码是否存在",
|
||||
zap.String("unified_social_code", unifiedSocialCode),
|
||||
zap.String("exclude_user_id", excludeUserID),
|
||||
)
|
||||
@@ -455,12 +454,12 @@ func (s *UserAggregateServiceImpl) CheckUnifiedSocialCodeExists(ctx context.Cont
|
||||
}
|
||||
|
||||
if exists {
|
||||
s.logger.Info("统一社会信用代码已存在",
|
||||
s.logger.Info("统一社会信用代码已存在",
|
||||
zap.String("unified_social_code", unifiedSocialCode),
|
||||
zap.String("exclude_user_id", excludeUserID),
|
||||
)
|
||||
} else {
|
||||
s.logger.Debug("统一社会信用代码不存在",
|
||||
s.logger.Debug("统一社会信用代码不存在",
|
||||
zap.String("unified_social_code", unifiedSocialCode),
|
||||
)
|
||||
}
|
||||
@@ -471,20 +470,20 @@ func (s *UserAggregateServiceImpl) CheckUnifiedSocialCodeExists(ctx context.Cont
|
||||
// CreateOrUpdateEnterpriseInfo 认证域专用:写入/覆盖企业信息
|
||||
func (s *UserAggregateServiceImpl) CreateOrUpdateEnterpriseInfo(
|
||||
ctx context.Context,
|
||||
userID, companyName, unifiedSocialCode, legalPersonName, legalPersonID, legalPersonPhone, enterpriseAddress, enterpriseEmail string,
|
||||
userID, companyName, unifiedSocialCode, legalPersonName, legalPersonID, legalPersonPhone, enterpriseAddress string,
|
||||
) error {
|
||||
user, err := s.LoadUser(ctx, userID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("用户不存在: %w", err)
|
||||
}
|
||||
if user.EnterpriseInfo == nil {
|
||||
enterpriseInfo, err := entities.NewEnterpriseInfo(userID, companyName, unifiedSocialCode, legalPersonName, legalPersonID, legalPersonPhone, enterpriseAddress, enterpriseEmail)
|
||||
enterpriseInfo, err := entities.NewEnterpriseInfo(userID, companyName, unifiedSocialCode, legalPersonName, legalPersonID, legalPersonPhone, enterpriseAddress)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
user.EnterpriseInfo = enterpriseInfo
|
||||
} else {
|
||||
err := user.EnterpriseInfo.UpdateEnterpriseInfo(companyName, unifiedSocialCode, legalPersonName, legalPersonID, legalPersonPhone, enterpriseAddress, enterpriseEmail)
|
||||
err := user.EnterpriseInfo.UpdateEnterpriseInfo(companyName, unifiedSocialCode, legalPersonName, legalPersonID, legalPersonPhone, enterpriseAddress)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -504,7 +503,7 @@ func (s *UserAggregateServiceImpl) CompleteCertification(ctx context.Context, us
|
||||
|
||||
// ListUsers 获取用户列表
|
||||
func (s *UserAggregateServiceImpl) ListUsers(ctx context.Context, query *queries.ListUsersQuery) ([]*entities.User, int64, error) {
|
||||
s.logger.Debug("获取用户列表",
|
||||
s.logger.Debug("获取用户列表",
|
||||
zap.Int("page", query.Page),
|
||||
zap.Int("page_size", query.PageSize),
|
||||
)
|
||||
@@ -516,7 +515,7 @@ func (s *UserAggregateServiceImpl) ListUsers(ctx context.Context, query *queries
|
||||
return nil, 0, fmt.Errorf("查询用户列表失败: %w", err)
|
||||
}
|
||||
|
||||
s.logger.Info("用户列表查询成功",
|
||||
s.logger.Info("用户列表查询成功",
|
||||
zap.Int("count", len(users)),
|
||||
zap.Int64("total", total),
|
||||
)
|
||||
@@ -535,7 +534,7 @@ func (s *UserAggregateServiceImpl) GetUserStats(ctx context.Context) (*repositor
|
||||
return nil, fmt.Errorf("查询用户统计信息失败: %w", err)
|
||||
}
|
||||
|
||||
s.logger.Info("用户统计信息查询成功",
|
||||
s.logger.Info("用户统计信息查询成功",
|
||||
zap.Int64("total_users", stats.TotalUsers),
|
||||
zap.Int64("active_users", stats.ActiveUsers),
|
||||
zap.Int64("certified_users", stats.CertifiedUsers),
|
||||
@@ -556,7 +555,7 @@ func (s *UserAggregateServiceImpl) publishDomainEvents(ctx context.Context, user
|
||||
for _, event := range events {
|
||||
// 这里需要将领域事件转换为标准事件格式
|
||||
// 暂时跳过,后续可以完善事件转换逻辑
|
||||
s.logger.Debug("发布领域事件",
|
||||
s.logger.Debug("发布领域事件",
|
||||
zap.String("user_id", user.ID),
|
||||
zap.Any("event", event),
|
||||
)
|
||||
@@ -566,4 +565,4 @@ func (s *UserAggregateServiceImpl) publishDomainEvents(ctx context.Context, user
|
||||
user.ClearDomainEvents()
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user