From 40f12ac1cf2f9533df0cd18dc25ce206ee9fcb96 Mon Sep 17 00:00:00 2001 From: Mrx <18278715334@163.com> Date: Tue, 19 May 2026 17:21:16 +0800 Subject: [PATCH] f --- .../processors/qygl/qygl4b2e_processor.go | 117 ++++++++++--- .../processors/qygl/qygl7d9a_processor.go | 155 +++++++++++++++--- .../processors/qygl/qygl8b4d_processor.go | 152 ++++++++++++++--- 3 files changed, 359 insertions(+), 65 deletions(-) diff --git a/internal/domains/api/services/processors/qygl/qygl4b2e_processor.go b/internal/domains/api/services/processors/qygl/qygl4b2e_processor.go index 1f94d0e..a5b3e69 100644 --- a/internal/domains/api/services/processors/qygl/qygl4b2e_processor.go +++ b/internal/domains/api/services/processors/qygl/qygl4b2e_processor.go @@ -8,10 +8,31 @@ import ( "tyapi-server/internal/domains/api/dto" "tyapi-server/internal/domains/api/services/processors" + "tyapi-server/internal/infrastructure/external/shujubao" ) +// QYGL4B2EItem 返回列表项 +type QYGL4B2EItem struct { + PublishTime string `json:"publish_time"` + CaseType string `json:"case_type"` + ID int64 `json:"id"` + Department string `json:"department"` + TaxpayerName string `json:"taxpayer_name"` +} + +// QYGL4B2EResponse 最终返回结构 +type QYGL4B2EResponse struct { + Total int64 `json:"total"` + Items []QYGL4B2EItem `json:"items"` +} + // ProcessQYGL4B2ERequest QYGL4B2E API处理方法 - 税收违法 -func ProcessQYGL4B2ERequest(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) { +func ProcessQYGL4B2ERequest( + ctx context.Context, + params []byte, + deps *processors.ProcessorDependencies, +) ([]byte, error) { + var paramsDto dto.QYGL5A3CReq if err := json.Unmarshal(params, ¶msDto); err != nil { return nil, errors.Join(processors.ErrSystem, err) @@ -21,39 +42,89 @@ func ProcessQYGL4B2ERequest(ctx context.Context, params []byte, deps *processors return nil, errors.Join(processors.ErrInvalidParam, err) } - // 设置默认值 + // 默认值 pageSize := paramsDto.PageSize if pageSize == 0 { - pageSize = int64(20) + pageSize = 20 } pageNum := paramsDto.PageNum if pageNum == 0 { - pageNum = int64(1) + pageNum = 1 } - // 构建API调用参数 - apiParams := map[string]string{ - "keyword": paramsDto.EntCode, - "pageSize": strconv.FormatInt(pageSize, 10), - "pageNum": strconv.FormatInt(pageNum, 10), + // 调用外部接口 + reqParams := map[string]interface{}{ + "key": "c67673dd2e92deb2d2ec91b87bb0a81c", + "creditCode": paramsDto.EntCode, } - // 调用天眼查API - 税收违法 - response, err := deps.TianYanChaService.CallAPI(ctx, "TaxContravention", apiParams) - if err != nil { - return nil, convertTianYanChaError(err) - } - - // 检查天眼查API调用是否成功 - if !response.Success { - return nil, errors.Join(processors.ErrDatasource, errors.New(response.Message)) - } - - // 返回天眼查响应数据 - respBytes, err := json.Marshal(response.Data) + apiPath := "/communication/personal/10233" + data, err := deps.ShujubaoService.CallAPI(ctx, apiPath, reqParams) if err != nil { + if errors.Is(err, shujubao.ErrDatasource) { + return nil, errors.Join(processors.ErrDatasource, err) + } + if errors.Is(err, shujubao.ErrQueryEmpty) { + return nil, errors.Join(processors.ErrNotFound, err) + } return nil, errors.Join(processors.ErrSystem, err) } - return respBytes, nil + // 原始返回结构处理 - data 是 map[string]interface{} 类型 + dataMap, ok := data.(map[string]interface{}) + if !ok { + return nil, errors.Join(processors.ErrSystem, errors.New("data不是map类型")) + } + + // 提取 total + total := int64(0) + if v, ok := dataMap["total"]; ok { + switch val := v.(type) { + case float64: + total = int64(val) + case int: + total = int64(val) + case string: + total, _ = strconv.ParseInt(val, 10, 64) + } + } + + // 提取 items 数组 + srcItems := make([]map[string]interface{}, 0) + if v, ok := dataMap["items"]; ok { + if arr, ok := v.([]interface{}); ok { + for _, item := range arr { + if itemMap, ok := item.(map[string]interface{}); ok { + srcItems = append(srcItems, itemMap) + } + } + } + } + + // 构造返回数据 + resp := QYGL4B2EResponse{ + Total: total, + Items: make([]QYGL4B2EItem, 0, len(srcItems)), + } + + getString := func(item map[string]interface{}, key string) string { + if v, ok := item[key]; ok { + if str, ok := v.(string); ok { + return str + } + } + return "" + } + + for i, v := range srcItems { + resp.Items = append(resp.Items, QYGL4B2EItem{ + ID: int64(i + 1), + TaxpayerName: getString(v, "entityName"), + Department: getString(v, "belongDepartment"), + CaseType: getString(v, "caseType"), + PublishTime: getString(v, "illegalTime"), + }) + } + + return json.Marshal(resp) } diff --git a/internal/domains/api/services/processors/qygl/qygl7d9a_processor.go b/internal/domains/api/services/processors/qygl/qygl7d9a_processor.go index 32d6a7d..efc2379 100644 --- a/internal/domains/api/services/processors/qygl/qygl7d9a_processor.go +++ b/internal/domains/api/services/processors/qygl/qygl7d9a_processor.go @@ -8,8 +8,59 @@ import ( "tyapi-server/internal/domains/api/dto" "tyapi-server/internal/domains/api/services/processors" + "tyapi-server/internal/infrastructure/external/shujubao" ) +/* +## 返回字段说明 + +| 返回值字段 | 字段类型 | 字段说明 | 备注 | +|------------|----------|----------|------| +| total | Number | int(11) | 总数 | +| items | Array | | | +| _child | Object | | | +| taxIdNumber | String | varchar(150) | 纳税人识别号 | +| newOwnTaxBalance | String | varchar(20) | 当前新发生欠税余额 | +| ownTaxAmount | String | varchar(50) | 欠税金额 | +| publishDate | String | 日期 | 发布时间 | +| ownTaxBalance | String | varchar(20) | 欠税余额 | +| type | String | varchar(10) | 税务类型 | +| personIdNumber | String | varchar(150) | 证件号码 | +| taxCategory | String | varchar(255) | 欠税税种 | +| taxpayerType | String | varchar(10) | 纳税人类型 | +| personIdName | String | varchar(50) | 法人证件名称 | +| name | String | varchar(255) | 纳税人名称 | +| location | String | varchar(150) | 经营地点 | +| department | String | varchar(200) | 税务机关 | +| regType | String | varchar(50) | 注册类型 | +| legalpersonName | String | varchar(150) | 法人或负责人名称 | +*/ + +// QYGL7D9AItem 返回列表项 +type QYGL7D9AItem struct { + TaxIdNumber string `json:"taxIdNumber"` + NewOwnTaxBalance string `json:"newOwnTaxBalance"` + OwnTaxAmount string `json:"ownTaxAmount"` + PublishDate string `json:"publishDate"` + OwnTaxBalance string `json:"ownTaxBalance"` + Type string `json:"type"` + PersonIdNumber string `json:"personIdNumber"` + TaxCategory string `json:"taxCategory"` + TaxpayerType string `json:"taxpayerType"` + PersonIdName string `json:"personIdName"` + Name string `json:"name"` + Location string `json:"location"` + Department string `json:"department"` + RegType string `json:"regType"` + LegalpersonName string `json:"legalpersonName"` +} + +// QYGL7D9AResponse 最终返回结构 +type QYGL7D9AResponse struct { + Total int64 `json:"total"` + Items []QYGL7D9AItem `json:"items"` +} + // ProcessQYGL7D9ARequest QYGL7D9A API处理方法 - 欠税公告 func ProcessQYGL7D9ARequest(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) { var paramsDto dto.QYGL5A3CReq @@ -21,39 +72,99 @@ func ProcessQYGL7D9ARequest(ctx context.Context, params []byte, deps *processors return nil, errors.Join(processors.ErrInvalidParam, err) } - // 设置默认值 + // 默认值 pageSize := paramsDto.PageSize if pageSize == 0 { - pageSize = int64(20) + pageSize = 20 } pageNum := paramsDto.PageNum if pageNum == 0 { - pageNum = int64(1) + pageNum = 1 } - // 构建API调用参数 - apiParams := map[string]string{ - "keyword": paramsDto.EntCode, - "pageSize": strconv.FormatInt(pageSize, 10), - "pageNum": strconv.FormatInt(pageNum, 10), + // 调用外部接口 + reqParams := map[string]interface{}{ + "key": "9ad1365cb0580863a239b0255649fb1a", + "creditCode": paramsDto.EntCode, } - // 调用天眼查API - 欠税公告 - response, err := deps.TianYanChaService.CallAPI(ctx, "OwnTax", apiParams) - if err != nil { - return nil, convertTianYanChaError(err) - } - - // 检查天眼查API调用是否成功 - if !response.Success { - return nil, errors.Join(processors.ErrDatasource, errors.New(response.Message)) - } - - // 返回天眼查响应数据 - respBytes, err := json.Marshal(response.Data) + apiPath := "/communication/personal/10235" + data, err := deps.ShujubaoService.CallAPI(ctx, apiPath, reqParams) if err != nil { + if errors.Is(err, shujubao.ErrDatasource) { + return nil, errors.Join(processors.ErrDatasource, err) + } + if errors.Is(err, shujubao.ErrQueryEmpty) { + return nil, errors.Join(processors.ErrNotFound, err) + } return nil, errors.Join(processors.ErrSystem, err) } - return respBytes, nil + // 原始返回结构处理 - data 是 map[string]interface{} 类型 + dataMap, ok := data.(map[string]interface{}) + if !ok { + return nil, errors.Join(processors.ErrSystem, errors.New("data不是map类型")) + } + + // 提取 total + totalStr := "" + if v, ok := dataMap["total"]; ok { + if str, ok := v.(string); ok { + totalStr = str + } + } + + // 提取 items 数组 + srcItems := make([]map[string]interface{}, 0) + if v, ok := dataMap["items"]; ok { + if arr, ok := v.([]interface{}); ok { + for _, item := range arr { + if itemMap, ok := item.(map[string]interface{}); ok { + srcItems = append(srcItems, itemMap) + } + } + } + } + + // 构造返回数据(缺失字段留空字符串) + resp := QYGL7D9AResponse{ + Total: 0, + Items: make([]QYGL7D9AItem, 0, len(srcItems)), + } + + getString := func(item map[string]interface{}, key string) string { + if v, ok := item[key]; ok { + if str, ok := v.(string); ok { + return str + } + } + return "" + } + + for _, v := range srcItems { + resp.Items = append(resp.Items, QYGL7D9AItem{ + TaxIdNumber: getString(v, "taxpayerCode"), + NewOwnTaxBalance: getString(v, "thisOwedAmount"), + OwnTaxAmount: getString(v, "totalOwedAmount"), + PublishDate: getString(v, "publishDate"), + OwnTaxBalance: getString(v, "beforeOwedAmount"), + Type: getString(v, "taxBureauType"), + PersonIdNumber: "", + TaxCategory: getString(v, "taxOwedType"), + TaxpayerType: "", + PersonIdName: "", + Name: getString(v, "entityName"), + Location: getString(v, "businessAddress"), + Department: getString(v, "taxBureauName"), + RegType: "", + LegalpersonName: getString(v, "legalPerson"), + }) + } + + // total 转 int64 + if totalStr != "" { + resp.Total, _ = strconv.ParseInt(totalStr, 10, 64) + } + + return json.Marshal(resp) } diff --git a/internal/domains/api/services/processors/qygl/qygl8b4d_processor.go b/internal/domains/api/services/processors/qygl/qygl8b4d_processor.go index 35e3e10..037e27f 100644 --- a/internal/domains/api/services/processors/qygl/qygl8b4d_processor.go +++ b/internal/domains/api/services/processors/qygl/qygl8b4d_processor.go @@ -8,8 +8,50 @@ import ( "tyapi-server/internal/domains/api/dto" "tyapi-server/internal/domains/api/services/processors" + "tyapi-server/internal/infrastructure/external/shujubao" ) +/* +## 返回字段说明 + +| 字段名 | 类型 | 说明 | +|--------|------|------| +| items | array | 融资历史记录列表,无记录时为空数组 | +| items[].round | string | 融资轮次 | +| items[].amount | string | 融资金额 | +| items[].date | string | 融资日期,格式:YYYY-MM-DD | +| items[].investors | array of string | 投资方列表 | +| items[].postValuation | string | 融资后估值 | +| items[].preValuation | string | 融资前估值 | +| items[].currency | string | 币种 | +| items[].intro | string | 项目简介 | +| items[].shareRatio | string | 持股比例 | +| total | integer | 符合条件的融资记录总数,无记录时为 0 | +| pageNum | integer | 当前页码 | +| pageSize | integer | 每页记录条数 | +*/ + +// QYGL8B4DItem 融资历史单项 +type QYGL8B4DItem struct { + Round string `json:"round"` + Amount string `json:"amount"` + Date string `json:"date"` + Investors []string `json:"investors"` + PostValuation string `json:"postValuation"` + PreValuation string `json:"preValuation"` + Currency string `json:"currency"` + Intro string `json:"intro"` + ShareRatio string `json:"shareRatio"` +} + +// QYGL8B4DResponse 融资历史返回结构 +type QYGL8B4DResponse struct { + Items []QYGL8B4DItem `json:"items"` + Total int64 `json:"total"` + PageNum int64 `json:"pageNum"` + PageSize int64 `json:"pageSize"` +} + // ProcessQYGL8B4DRequest QYGL8B4D API处理方法 - 融资历史 func ProcessQYGL8B4DRequest(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) { var paramsDto dto.QYGL8B4DReq @@ -21,7 +63,7 @@ func ProcessQYGL8B4DRequest(ctx context.Context, params []byte, deps *processors return nil, errors.Join(processors.ErrInvalidParam, err) } - // 设置默认值 + // 默认值 pageSize := paramsDto.PageSize if pageSize == 0 { pageSize = int64(20) @@ -31,29 +73,99 @@ func ProcessQYGL8B4DRequest(ctx context.Context, params []byte, deps *processors pageNum = int64(1) } - // 构建API调用参数 - apiParams := map[string]string{ - "keyword": paramsDto.EntCode, - "pageSize": strconv.FormatInt(pageSize, 10), - "pageNum": strconv.FormatInt(pageNum, 10), + // 调用外部接口 + reqParams := map[string]interface{}{ + "key": "8887a17748d767b0a1f417171108873f", + "creditCode": paramsDto.EntCode, } - // 调用天眼查API - 融资历史 - response, err := deps.TianYanChaService.CallAPI(ctx, "FinancingHistory", apiParams) - if err != nil { - return nil, convertTianYanChaError(err) - } - - // 检查天眼查API调用是否成功 - if !response.Success { - return nil, errors.Join(processors.ErrDatasource, errors.New(response.Message)) - } - - // 返回天眼查响应数据 - respBytes, err := json.Marshal(response.Data) + apiPath := "/communication/personal/10435" + data, err := deps.ShujubaoService.CallAPI(ctx, apiPath, reqParams) if err != nil { + if errors.Is(err, shujubao.ErrDatasource) { + return nil, errors.Join(processors.ErrDatasource, err) + } + if errors.Is(err, shujubao.ErrQueryEmpty) { + return nil, errors.Join(processors.ErrNotFound, err) + } return nil, errors.Join(processors.ErrSystem, err) } - return respBytes, nil + // 原始返回结构处理 - data 是 map[string]interface{} 类型 + dataMap, ok := data.(map[string]interface{}) + if !ok { + return nil, errors.Join(processors.ErrSystem, errors.New("data不是map类型")) + } + + // 提取 page 对象中的 totalRecords + totalRecords := "" + if page, ok := dataMap["page"].(map[string]interface{}); ok { + if v, ok := page["totalRecords"]; ok { + if str, ok := v.(string); ok { + totalRecords = str + } + } + } + + // 提取 records 数组(不是 items) + records := make([]map[string]interface{}, 0) + if v, ok := dataMap["records"]; ok { + if arr, ok := v.([]interface{}); ok { + for _, item := range arr { + if itemMap, ok := item.(map[string]interface{}); ok { + records = append(records, itemMap) + } + } + } + } + + // 构造返回数据 + resp := QYGL8B4DResponse{ + Items: make([]QYGL8B4DItem, 0, len(records)), + PageNum: pageNum, + PageSize: pageSize, + } + + for _, item := range records { + // 提取字段,使用类型断言 + getString := func(key string) string { + if v, ok := item[key]; ok { + if str, ok := v.(string); ok { + return str + } + } + return "" + } + + investAmount := getString("investAmount") + afterValuation := getString("afterInvestValuation") + + // 计算持股比例:持股比例 = 本轮投资金额 / 投后估值 × 100% + shareRatio := "" + investAmountFloat, err1 := strconv.ParseFloat(investAmount, 64) + afterValuationFloat, err2 := strconv.ParseFloat(afterValuation, 64) + if err1 == nil && err2 == nil && afterValuationFloat > 0 { + ratio := investAmountFloat / afterValuationFloat * 100 + shareRatio = strconv.FormatFloat(ratio, 'f', 2, 64) // 保留两位小数 + } + + resp.Items = append(resp.Items, QYGL8B4DItem{ + Round: getString("financingRound"), + Amount: investAmount, + Date: getString("financingDate"), + Investors: []string{getString("financingRoundInvestor")}, + PostValuation: afterValuation, + PreValuation: getString("beforeInvestValuation"), + Currency: getString("currency"), + Intro: "", + ShareRatio: shareRatio, + }) + } + + // total + if totalRecords != "" { + resp.Total, _ = strconv.ParseInt(totalRecords, 10, 64) + } + + return json.Marshal(resp) }