This commit is contained in:
2026-03-10 17:28:04 +08:00
parent 9a7bda9527
commit 4cd3954574
12 changed files with 1938 additions and 11 deletions

View File

@@ -2,7 +2,9 @@ package processors
import (
"context"
"tyapi-server/internal/application/api/commands"
"tyapi-server/internal/domains/api/repositories"
"tyapi-server/internal/infrastructure/external/alicloud"
"tyapi-server/internal/infrastructure/external/jiguang"
"tyapi-server/internal/infrastructure/external/muzi"
@@ -42,6 +44,9 @@ type ProcessorDependencies struct {
CombService CombServiceInterface // Changed to interface to break import cycle
Options *commands.ApiCallOptions // 添加Options支持
CallContext *CallContext // 添加CallApi调用上下文
// 企业报告记录仓储,用于持久化 QYGLJ1U9 生成的企业报告
ReportRepo repositories.ReportRepository
}
// NewProcessorDependencies 创建处理器依赖容器
@@ -58,6 +63,7 @@ func NewProcessorDependencies(
shumaiService *shumai.ShumaiService,
validator interfaces.RequestValidator,
combService CombServiceInterface, // Changed to interface
reportRepo repositories.ReportRepository,
) *ProcessorDependencies {
return &ProcessorDependencies{
WestDexService: westDexService,
@@ -74,6 +80,7 @@ func NewProcessorDependencies(
CombService: combService,
Options: nil, // 初始化为nil在调用时设置
CallContext: nil, // 初始化为nil在调用时设置
ReportRepo: reportRepo,
}
}

View File

@@ -0,0 +1,180 @@
package qygl
import (
"context"
"crypto/rand"
"encoding/hex"
"encoding/json"
"errors"
"fmt"
"net/url"
"sync"
"time"
"tyapi-server/internal/domains/api/dto"
"tyapi-server/internal/domains/api/entities"
"tyapi-server/internal/domains/api/services/processors"
)
// ProcessQYGLJ1U9Request 企业全景报告处理器:并发调用企业全量(QYGLUY3S)、股权全景(QYGLJ0Q1)、司法涉诉(QYGL5S1I)
// 然后复用 qyglj1u9_processor_build.go 中的 buildReport / map* 逻辑生成企业报告结构
func ProcessQYGLJ1U9Request(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) {
// 复用 QYGLUY3S 的入参结构:企业名称/注册号/统一社会信用代码
var p dto.QYGLUY3SReq
if err := json.Unmarshal(params, &p); err != nil {
return nil, errors.Join(processors.ErrSystem, err)
}
if err := deps.Validator.ValidateStruct(p); err != nil {
return nil, errors.Join(processors.ErrInvalidParam, err)
}
// 并发调用三个已有处理器
type apiResult struct {
key string
data map[string]interface{}
err error
}
resultsCh := make(chan apiResult, 3)
var wg sync.WaitGroup
call := func(key string, req interface{}, fn func(context.Context, []byte, *processors.ProcessorDependencies) ([]byte, error)) {
wg.Add(1)
go func() {
defer wg.Done()
b, err := json.Marshal(req)
if err != nil {
resultsCh <- apiResult{key: key, err: err}
return
}
resp, err := fn(ctx, b, deps)
if err != nil {
resultsCh <- apiResult{key: key, err: err}
return
}
var m map[string]interface{}
if err := json.Unmarshal(resp, &m); err != nil {
resultsCh <- apiResult{key: key, err: err}
return
}
resultsCh <- apiResult{key: key, data: m}
}()
}
// 企业全量信息核验V2QYGLUY3S
call("jiguangFull", map[string]interface{}{
"ent_name": p.EntName,
"ent_reg_no": p.EntRegno,
"ent_code": p.EntCode,
}, ProcessQYGLUY3SRequest)
// 企业股权结构全景QYGLJ0Q1
call("equityPanorama", map[string]interface{}{
"ent_name": p.EntName,
"ent_code": p.EntCode,
}, ProcessQYGLJ0Q1Request)
// 企业司法涉诉V2QYGL5S1I
call("judicialCertFull", map[string]interface{}{
"ent_name": p.EntName,
"ent_code": p.EntCode,
}, ProcessQYGL5S1IRequest)
wg.Wait()
close(resultsCh)
var jiguang, judicial, equity map[string]interface{}
for r := range resultsCh {
if r.err != nil {
// 任一关键数据源异常,则返回系统错误(也可以根据需求做降级)
return nil, errors.Join(processors.ErrSystem, fmt.Errorf("%s 调用失败: %w", r.key, r.err))
}
switch r.key {
case "jiguangFull":
jiguang = r.data
case "judicialCertFull":
judicial = r.data
case "equityPanorama":
equity = r.data
}
}
if jiguang == nil {
jiguang = map[string]interface{}{}
}
if judicial == nil {
judicial = map[string]interface{}{}
}
if equity == nil {
equity = map[string]interface{}{}
}
// 复用构建逻辑生成企业报告结构
report := buildReport(jiguang, judicial, equity)
// 为报告生成唯一编号并缓存,供后续通过编号查看
reportID := saveQYGLReport(report)
report["reportId"] = reportID
// 持久化企业报告记录到数据库(忽略持久化失败,不影响接口主流程)
if deps.ReportRepo != nil {
reqJSON, _ := json.Marshal(p)
reportJSON, _ := json.Marshal(report)
_ = deps.ReportRepo.Create(ctx, &entities.Report{
ReportID: reportID,
Type: "enterprise",
ApiCode: "QYGLJ1U9",
EntName: p.EntName,
EntCode: p.EntCode,
RequestParams: string(reqJSON),
ReportData: string(reportJSON),
})
}
// 为报告补充前端查看链接,供调用方直接跳转到企业报告页面(通过编号访问)
report["reportUrl"] = buildQYGLReportURLByID(reportID)
out, err := json.Marshal(report)
if err != nil {
return nil, errors.Join(processors.ErrSystem, err)
}
return out, nil
}
// 内存中的企业报告缓存(简单实现,进程重启后清空)
var qyglReportStore = struct {
sync.RWMutex
data map[string]map[string]interface{}
}{
data: make(map[string]map[string]interface{}),
}
// saveQYGLReport 保存报告并返回生成的编号
func saveQYGLReport(report map[string]interface{}) string {
id := generateQYGLReportID()
qyglReportStore.Lock()
qyglReportStore.data[id] = report
qyglReportStore.Unlock()
return id
}
// GetQYGLReport 根据编号获取报告(供页面渲染使用)
func GetQYGLReport(id string) (map[string]interface{}, bool) {
qyglReportStore.RLock()
defer qyglReportStore.RUnlock()
r, ok := qyglReportStore.data[id]
return r, ok
}
// generateQYGLReportID 生成短编号
func generateQYGLReportID() string {
b := make([]byte, 8)
if _, err := rand.Read(b); err == nil {
return hex.EncodeToString(b)
}
// 随机数失败时退化为时间戳
return fmt.Sprintf("%d", time.Now().UnixNano())
}
// buildQYGLReportURLByID 构造企业报告前端查看链接(通过编号查看)
func buildQYGLReportURLByID(id string) string {
return "/reports/qygl/" + url.PathEscape(id)
}

File diff suppressed because it is too large Load Diff