Compare commits

...

13 Commits

Author SHA1 Message Date
Mrx
e246271a24 f 2026-04-23 18:18:47 +08:00
Mrx
a1024ed4b2 f 2026-04-23 17:59:23 +08:00
Mrx
d6b78a5d6d Merge branch 'main' of http://1.117.67.95:3000/team/tyapi-server 2026-04-23 10:55:02 +08:00
Mrx
61c6cc4f35 370982199012037272 2026-04-23 10:55:01 +08:00
cdd1e00745 Merge branch 'main' of http://1.117.67.95:3000/team/tyapi-server 2026-04-21 21:03:56 +08:00
46ba4e048c f 2026-04-21 21:02:02 +08:00
Mrx
3156539319 f 2026-04-21 17:03:03 +08:00
Mrx
dad8abad16 f 2026-04-21 16:24:57 +08:00
Mrx
5f62261c11 f 2026-04-21 16:23:35 +08:00
a0b2105339 f 2026-04-20 19:41:29 +08:00
83e71ae81b f 2026-04-20 19:11:49 +08:00
8675961207 Merge branch 'main' of http://1.117.67.95:3000/team/tyapi-server 2026-04-20 18:45:35 +08:00
4bd6f51728 f 2026-04-20 18:45:34 +08:00
17 changed files with 1649 additions and 66 deletions

View File

@@ -499,6 +499,12 @@ type IVYZ7F3AReq struct {
Name string `json:"name" validate:"required,min=1,validName"` Name string `json:"name" validate:"required,min=1,validName"`
Authorized string `json:"authorized" validate:"required,oneof=0 1"` Authorized string `json:"authorized" validate:"required,oneof=0 1"`
} }
type IVYZRAX1Req struct {
Name string `json:"name" validate:"required,min=1,validName"`
IDCard string `json:"id_card" validate:"required,validIDCard"`
MobileNo string `json:"mobile_no" validate:"required,min=11,max=11,validMobileNo"`
Authorized string `json:"authorized" validate:"required,oneof=0 1"`
}
type IVYZ3P9MReq struct { type IVYZ3P9MReq struct {
IDCard string `json:"id_card" validate:"required,validIDCard"` IDCard string `json:"id_card" validate:"required,validIDCard"`

View File

@@ -330,6 +330,9 @@ func registerAllProcessors(combService *comb.CombService) {
"IVYZ38SR": ivyz.ProcessIVYZ38SRRequest, //婚姻状态核验(双人) "IVYZ38SR": ivyz.ProcessIVYZ38SRRequest, //婚姻状态核验(双人)
"IVYZ48SR": ivyz.ProcessIVYZ48SRRequest, //婚姻状态核验V2双人 "IVYZ48SR": ivyz.ProcessIVYZ48SRRequest, //婚姻状态核验V2双人
"IVYZ5E22": ivyz.ProcessIVYZ5E22Request, //双人婚姻评估查询zhicha版本 "IVYZ5E22": ivyz.ProcessIVYZ5E22Request, //双人婚姻评估查询zhicha版本
"IVYZRAX1": ivyz.ProcessIVYZRAX1Request, //融安信用分
"IVYZRAX2": ivyz.ProcessIVYZRAX2Request,//融御反欺诈分
// COMB系列处理器 - 只注册有自定义逻辑的组合包 // COMB系列处理器 - 只注册有自定义逻辑的组合包
"COMB86PM": comb.ProcessCOMB86PMRequest, // 有自定义逻辑重命名ApiCode "COMB86PM": comb.ProcessCOMB86PMRequest, // 有自定义逻辑重命名ApiCode

View File

@@ -276,6 +276,8 @@ func (s *FormConfigServiceImpl) getDTOStruct(ctx context.Context, apiCode string
"IVYZ5E22": &dto.IVYZ5E22Req{}, //双人婚姻评估查询zhicha版本 "IVYZ5E22": &dto.IVYZ5E22Req{}, //双人婚姻评估查询zhicha版本
"DWBG5SAM": &dto.DWBG5SAMReq{}, //天远指迷报告 "DWBG5SAM": &dto.DWBG5SAMReq{}, //天远指迷报告
"QYGLDJ33": &dto.QYGLDJ33Req{}, //企业年报信息核验 "QYGLDJ33": &dto.QYGLDJ33Req{}, //企业年报信息核验
"IVYZRAX1": &dto.IVYZRAX1Req{},//融安信用分
"IVYZRAX2": &dto.IVYZRAX1Req{},//融御反欺诈
} }
// 优先返回已配置的DTO // 优先返回已配置的DTO

View File

@@ -25,7 +25,7 @@ func ProcessFLXG0V4BRequest(ctx context.Context, params []byte, deps *processors
return nil, errors.Join(processors.ErrInvalidParam, err) return nil, errors.Join(processors.ErrInvalidParam, err)
} }
// 去掉司法案件案件去掉身份证号码 // 去掉司法案件案件去掉身份证号码
if paramsDto.IDCard == "350681198611130611" || paramsDto.IDCard == "622301200006250550" || paramsDto.IDCard == "320682198910134998" || paramsDto.IDCard == "640102198708020925" || paramsDto.IDCard == "420624197310234034" || paramsDto.IDCard == "350104198501184416" || paramsDto.IDCard == "410521198606018056" { if paramsDto.IDCard == "350681198611130611" || paramsDto.IDCard == "370982199012037272" || paramsDto.IDCard == "622301200006250550" || paramsDto.IDCard == "320682198910134998" || paramsDto.IDCard == "640102198708020925" || paramsDto.IDCard == "420624197310234034" || paramsDto.IDCard == "350104198501184416" || paramsDto.IDCard == "410521198606018056" || paramsDto.IDCard == "410482198504029333" || paramsDto.IDCard == "370982199012037272" {
return nil, errors.Join(processors.ErrNotFound, errors.New("查询为空")) return nil, errors.Join(processors.ErrNotFound, errors.New("查询为空"))
} }
encryptedName, err := deps.WestDexService.Encrypt(paramsDto.Name) encryptedName, err := deps.WestDexService.Encrypt(paramsDto.Name)

View File

@@ -20,7 +20,7 @@ func ProcessFLXG5A3BRequest(ctx context.Context, params []byte, deps *processors
if err := deps.Validator.ValidateStruct(paramsDto); err != nil { if err := deps.Validator.ValidateStruct(paramsDto); err != nil {
return nil, errors.Join(processors.ErrInvalidParam, err) return nil, errors.Join(processors.ErrInvalidParam, err)
} }
if paramsDto.IDCard == "350681198611130611" || paramsDto.IDCard == "622301200006250550" || paramsDto.IDCard == "320682198910134998" || paramsDto.IDCard == "640102198708020925" || paramsDto.IDCard == "420624197310234034" || paramsDto.IDCard == "350104198501184416" || paramsDto.IDCard == "410521198606018056" || paramsDto.IDCard == "410482198504029333" { if paramsDto.IDCard == "350681198611130611" || paramsDto.IDCard == "370982199012037272" || paramsDto.IDCard == "622301200006250550" || paramsDto.IDCard == "320682198910134998" || paramsDto.IDCard == "640102198708020925" || paramsDto.IDCard == "420624197310234034" || paramsDto.IDCard == "350104198501184416" || paramsDto.IDCard == "410521198606018056" || paramsDto.IDCard == "410482198504029333" || paramsDto.IDCard == "370982199012037272" {
return nil, errors.Join(processors.ErrNotFound, errors.New("查询为空")) return nil, errors.Join(processors.ErrNotFound, errors.New("查询为空"))
} }
encryptedName, err := deps.ZhichaService.Encrypt(paramsDto.Name) encryptedName, err := deps.ZhichaService.Encrypt(paramsDto.Name)

View File

@@ -7,7 +7,7 @@ import (
"tyapi-server/internal/domains/api/dto" "tyapi-server/internal/domains/api/dto"
"tyapi-server/internal/domains/api/services/processors" "tyapi-server/internal/domains/api/services/processors"
"tyapi-server/internal/infrastructure/external/xingwei" "tyapi-server/internal/infrastructure/external/zhicha"
) )
// ProcessFLXG7E8FRequest FLXG7E8F API处理方法 - 个人司法数据查询 // ProcessFLXG7E8FRequest FLXG7E8F API处理方法 - 个人司法数据查询
@@ -20,30 +20,225 @@ func ProcessFLXG7E8FRequest(ctx context.Context, params []byte, deps *processors
if err := deps.Validator.ValidateStruct(paramsDto); err != nil { if err := deps.Validator.ValidateStruct(paramsDto); err != nil {
return nil, errors.Join(processors.ErrInvalidParam, err) return nil, errors.Join(processors.ErrInvalidParam, err)
} }
if paramsDto.IDCard == "350681198611130611" || paramsDto.IDCard == "622301200006250550" || paramsDto.IDCard == "320682198910134998" || paramsDto.IDCard == "640102198708020925" || paramsDto.IDCard == "420624197310234034" || paramsDto.IDCard == "350104198501184416" || paramsDto.IDCard == "410521198606018056" || paramsDto.IDCard == "410482198504029333" { if paramsDto.IDCard == "350681198611130611" || paramsDto.IDCard == "370982199012037272" || paramsDto.IDCard == "622301200006250550" || paramsDto.IDCard == "320682198910134998" || paramsDto.IDCard == "640102198708020925" || paramsDto.IDCard == "420624197310234034" || paramsDto.IDCard == "350104198501184416" || paramsDto.IDCard == "410521198606018056" || paramsDto.IDCard == "410482198504029333" || paramsDto.IDCard == "370982199012037272" {
return nil, errors.Join(processors.ErrNotFound, errors.New("查询为空")) return nil, errors.Join(processors.ErrNotFound, errors.New("查询为空"))
} }
// 构建请求数据,将项目规范的字段名转换为 XingweiService 需要的字段名
reqData := map[string]interface{}{ encryptedName, err := deps.ZhichaService.Encrypt(paramsDto.Name)
"name": paramsDto.Name, if err != nil {
"idCardNum": paramsDto.IDCard, return nil, errors.Join(processors.ErrSystem, err)
"phoneNumber": paramsDto.MobileNo,
} }
// 调用行为数据API使用指定的project_id encryptedIDCard, err := deps.ZhichaService.Encrypt(paramsDto.IDCard)
projectID := "CDJ-1101695378264092672"
respBytes, err := deps.XingweiService.CallAPI(ctx, projectID, reqData)
if err != nil { if err != nil {
if errors.Is(err, xingwei.ErrNotFound) {
return nil, errors.Join(processors.ErrNotFound, err)
} else if errors.Is(err, xingwei.ErrDatasource) {
return nil, errors.Join(processors.ErrDatasource, err)
} else if errors.Is(err, xingwei.ErrSystem) {
return nil, errors.Join(processors.ErrSystem, err) return nil, errors.Join(processors.ErrSystem, err)
}
reqData := map[string]interface{}{
"name": encryptedName,
"idCard": encryptedIDCard,
"authorized": "1",
}
respData, err := deps.ZhichaService.CallAPI(ctx, "ZCI006", reqData)
if err != nil {
if errors.Is(err, zhicha.ErrDatasource) {
return nil, errors.Join(processors.ErrDatasource, err)
} else { } else {
return nil, errors.Join(processors.ErrSystem, err) return nil, errors.Join(processors.ErrSystem, err)
} }
} }
respMap, ok := respData.(map[string]interface{})
if !ok {
return nil, errors.Join(processors.ErrSystem, errors.New("响应格式错误"))
}
result := map[string]interface{}{
"judicial_data": mapFLXG5A3BToJudicialData(respMap),
}
respBytes, err := json.Marshal(result)
if err != nil {
return nil, errors.Join(processors.ErrSystem, err)
}
return respBytes, nil return respBytes, nil
} }
func mapFLXG5A3BToJudicialData(resp map[string]interface{}) map[string]interface{} {
judicialData := map[string]interface{}{
"consumptionRestrictionList": mapXgbzxrToConsumptionRestriction(asSlice(resp["xgbzxr"])),
"breachCaseList": mapSxbzxrToBreachCaseList(asSlice(resp["sxbzxr"])),
"lawsuitStat": normalizeLawsuitStat(asMap(resp["entout"])),
}
return judicialData
}
func mapXgbzxrToConsumptionRestriction(items []interface{}) []map[string]interface{} {
result := make([]map[string]interface{}, 0, len(items))
for _, item := range items {
m := asMap(item)
if len(m) == 0 {
continue
}
result = append(result, map[string]interface{}{
"caseNumber": m["ah"],
"id": m["id"],
"issueDate": m["fbrq"],
"executiveCourt": m["zxfy"],
"fileDate": m["larq"],
})
}
return result
}
func mapSxbzxrToBreachCaseList(items []interface{}) []map[string]interface{} {
result := make([]map[string]interface{}, 0, len(items))
for _, item := range items {
m := asMap(item)
if len(m) == 0 {
continue
}
result = append(result, map[string]interface{}{
"caseNumber": m["ah"],
"issueDate": m["fbrq"],
"id": m["id"],
"fileDate": m["larq"],
"fulfillStatus": m["lxqk"],
"estimatedJudgementAmount": m["pjje_gj"],
"province": m["sf"],
"sex": m["xb"],
"concreteDetails": m["xwqx"],
"obligation": m["yw"],
"executiveCourt": m["zxfy"],
"enforcementBasisOrganization": m["zxyjdw"],
"enforcementBasisNumber": m["zxyjwh"],
})
}
return result
}
func normalizeLawsuitStat(entout map[string]interface{}) map[string]interface{} {
lawsuitStat := defaultLawsuitStat()
for k, v := range entout {
switch k {
case "cases_tree":
lawsuitStat[k] = normalizeCasesTree(asMap(v))
case "count":
lawsuitStat[k] = normalizeCount(asMap(v))
case "preservation", "administrative", "civil", "implement", "criminal", "bankrupt":
lawsuitStat[k] = normalizeCaseSection(asMap(v))
default:
lawsuitStat[k] = v
}
}
return lawsuitStat
}
func defaultLawsuitStat() map[string]interface{} {
return map[string]interface{}{
"crc": 0,
"cases_tree": normalizeCasesTree(map[string]interface{}{}),
"count": normalizeCount(map[string]interface{}{}),
"preservation": normalizeCaseSection(map[string]interface{}{}),
"administrative": normalizeCaseSection(map[string]interface{}{}),
"civil": normalizeCaseSection(map[string]interface{}{}),
"implement": normalizeCaseSection(map[string]interface{}{}),
"criminal": normalizeCaseSection(map[string]interface{}{}),
"bankrupt": normalizeCaseSection(map[string]interface{}{}),
}
}
func normalizeCasesTree(src map[string]interface{}) map[string]interface{} {
dst := map[string]interface{}{
"administrative": []interface{}{},
"criminal": []interface{}{},
"civil": []interface{}{},
}
for _, key := range []string{"administrative", "criminal", "civil"} {
if v, ok := src[key]; ok {
dst[key] = asSlice(v)
}
}
return dst
}
func normalizeCaseSection(src map[string]interface{}) map[string]interface{} {
dst := map[string]interface{}{
"cases": []interface{}{},
"count": normalizeCount(map[string]interface{}{}),
}
if v, ok := src["cases"]; ok {
dst["cases"] = asSlice(v)
}
if v, ok := src["count"]; ok {
dst["count"] = normalizeCount(asMap(v))
}
return dst
}
func normalizeCount(src map[string]interface{}) map[string]interface{} {
dst := map[string]interface{}{
"money_yuangao": 0,
"area_stat": "",
"count_jie_beigao": 0,
"count_total": 0,
"money_wei_yuangao": 0,
"count_wei_total": 0,
"money_wei_beigao": 0,
"count_other": 0,
"money_beigao": 0,
"count_yuangao": 0,
"money_jie_other": 0,
"money_total": 0,
"money_wei_total": 0,
"count_wei_yuangao": 0,
"ay_stat": "",
"count_beigao": 0,
"money_jie_yuangao": 0,
"jafs_stat": "",
"money_jie_beigao": 0,
"count_wei_beigao": 0,
"count_jie_other": 0,
"count_jie_total": 0,
"count_wei_other": 0,
"money_other": 0,
"count_jie_yuangao": 0,
"money_jie_total": 0,
"money_wei_other": 0,
"money_wei_percent": 0,
"larq_stat": "",
}
for k, v := range src {
dst[k] = v
}
return dst
}
func asMap(v interface{}) map[string]interface{} {
if v == nil {
return map[string]interface{}{}
}
if m, ok := v.(map[string]interface{}); ok {
return m
}
return map[string]interface{}{}
}
func asSlice(v interface{}) []interface{} {
if v == nil {
return []interface{}{}
}
if s, ok := v.([]interface{}); ok {
return s
}
return []interface{}{}
}

View File

@@ -20,7 +20,7 @@ func ProcessFLXGCA3DRequest(ctx context.Context, params []byte, deps *processors
if err := deps.Validator.ValidateStruct(paramsDto); err != nil { if err := deps.Validator.ValidateStruct(paramsDto); err != nil {
return nil, errors.Join(processors.ErrInvalidParam, err) return nil, errors.Join(processors.ErrInvalidParam, err)
} }
if paramsDto.IDCard == "350681198611130611" || paramsDto.IDCard == "622301200006250550" || paramsDto.IDCard == "320682198910134998" || paramsDto.IDCard == "640102198708020925" || paramsDto.IDCard == "420624197310234034" || paramsDto.IDCard == "350104198501184416" || paramsDto.IDCard == "410521198606018056" { if paramsDto.IDCard == "350681198611130611" || paramsDto.IDCard == "370982199012037272" || paramsDto.IDCard == "622301200006250550" || paramsDto.IDCard == "320682198910134998" || paramsDto.IDCard == "640102198708020925" || paramsDto.IDCard == "420624197310234034" || paramsDto.IDCard == "350104198501184416" || paramsDto.IDCard == "410521198606018056" || paramsDto.IDCard == "410482198504029333" || paramsDto.IDCard == "370982199012037272" {
return nil, errors.Join(processors.ErrNotFound, errors.New("查询为空")) return nil, errors.Join(processors.ErrNotFound, errors.New("查询为空"))
} }
encryptedName, err := deps.WestDexService.Encrypt(paramsDto.Name) encryptedName, err := deps.WestDexService.Encrypt(paramsDto.Name)

View File

@@ -25,7 +25,7 @@ func ProcessFLXGDEA9Request(ctx context.Context, params []byte, deps *processors
if err != nil { if err != nil {
return nil, errors.Join(processors.ErrSystem, err) return nil, errors.Join(processors.ErrSystem, err)
} }
if paramsDto.IDCard == "350681198611130611" || paramsDto.IDCard == "622301200006250550" || paramsDto.IDCard == "320682198910134998" || paramsDto.IDCard == "640102198708020925" || paramsDto.IDCard == "420624197310234034" || paramsDto.IDCard == "350104198501184416" || paramsDto.IDCard == "410521198606018056" { if paramsDto.IDCard == "350681198611130611" || paramsDto.IDCard == "370982199012037272" || paramsDto.IDCard == "622301200006250550" || paramsDto.IDCard == "320682198910134998" || paramsDto.IDCard == "640102198708020925" || paramsDto.IDCard == "420624197310234034" || paramsDto.IDCard == "350104198501184416" || paramsDto.IDCard == "410521198606018056" || paramsDto.IDCard == "410482198504029333" || paramsDto.IDCard == "370982199012037272" {
return nil, errors.Join(processors.ErrNotFound, errors.New("查询为空")) return nil, errors.Join(processors.ErrNotFound, errors.New("查询为空"))
} }
encryptedIDCard, err := deps.ZhichaService.Encrypt(paramsDto.IDCard) encryptedIDCard, err := deps.ZhichaService.Encrypt(paramsDto.IDCard)

View File

@@ -0,0 +1,68 @@
package ivyz
import (
"context"
"encoding/json"
"errors"
"tyapi-server/internal/domains/api/dto"
"tyapi-server/internal/domains/api/services/processors"
"tyapi-server/internal/infrastructure/external/zhicha"
)
// ProcessIVYZRAX1Request IVYZRAX1 API处理方法 - 融安信用分
func ProcessIVYZRAX1Request(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) {
var paramsDto dto.IVYZRAX1Req
if err := json.Unmarshal(params, &paramsDto); err != nil {
return nil, errors.Join(processors.ErrSystem, err)
}
if err := deps.Validator.ValidateStruct(paramsDto); err != nil {
return nil, errors.Join(processors.ErrInvalidParam, err)
}
// encryptedName, err := deps.ZhichaService.Encrypt(paramsDto.Name)
// if err != nil {
// return nil, errors.Join(processors.ErrSystem, err)
// }
// encryptedIDCard, err := deps.ZhichaService.Encrypt(paramsDto.IDCard)
// if err != nil {
// return nil, errors.Join(processors.ErrSystem, err)
// }
// encryptedMoblie, err := deps.ZhichaService.Encrypt(paramsDto.MobileNo)
// if err != nil {
// return nil, errors.Join(processors.ErrSystem, err)
// }
md5Name := deps.ZhichaService.MD5(paramsDto.Name)
md5IDCard := deps.ZhichaService.MD5(paramsDto.IDCard)
md5Mobile := deps.ZhichaService.MD5(paramsDto.MobileNo)
reqData := map[string]interface{}{
// "name": encryptedName,
// "idCard": encryptedIDCard,
// "phone": encryptedMoblie,
"authorized": paramsDto.Authorized,
"name": md5Name,
"idCard": md5IDCard,
"phone": md5Mobile,
}
respData, err := deps.ZhichaService.CallAPI(ctx, "ZCI084", reqData)
if err != nil {
if errors.Is(err, zhicha.ErrDatasource) {
return nil, errors.Join(processors.ErrDatasource, err)
} else {
return nil, errors.Join(processors.ErrSystem, err)
}
}
// 将响应数据转换为JSON字节
respBytes, err := json.Marshal(respData)
if err != nil {
return nil, errors.Join(processors.ErrSystem, err)
}
return respBytes, nil
}

View File

@@ -0,0 +1,68 @@
package ivyz
import (
"context"
"encoding/json"
"errors"
"tyapi-server/internal/domains/api/dto"
"tyapi-server/internal/domains/api/services/processors"
"tyapi-server/internal/infrastructure/external/zhicha"
)
// ProcessIVYZRAX2Request IVYZRAX2 API处理方法 - 融御反欺诈分
func ProcessIVYZRAX2Request(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) {
var paramsDto dto.IVYZRAX1Req
if err := json.Unmarshal(params, &paramsDto); err != nil {
return nil, errors.Join(processors.ErrSystem, err)
}
if err := deps.Validator.ValidateStruct(paramsDto); err != nil {
return nil, errors.Join(processors.ErrInvalidParam, err)
}
// encryptedName, err := deps.ZhichaService.Encrypt(paramsDto.Name)
// if err != nil {
// return nil, errors.Join(processors.ErrSystem, err)
// }
// encryptedIDCard, err := deps.ZhichaService.Encrypt(paramsDto.IDCard)
// if err != nil {
// return nil, errors.Join(processors.ErrSystem, err)
// }
// encryptedMoblie, err := deps.ZhichaService.Encrypt(paramsDto.MobileNo)
// if err != nil {
// return nil, errors.Join(processors.ErrSystem, err)
// }
md5Name := deps.ZhichaService.MD5(paramsDto.Name)
md5IDCard := deps.ZhichaService.MD5(paramsDto.IDCard)
md5Mobile := deps.ZhichaService.MD5(paramsDto.MobileNo)
reqData := map[string]interface{}{
// "name": encryptedName,
// "idCard": encryptedIDCard,
// "phone": encryptedMoblie,
"authorized": paramsDto.Authorized,
"name": md5Name,
"idCard": md5IDCard,
"phone": md5Mobile,
}
respData, err := deps.ZhichaService.CallAPI(ctx, "ZCI083", reqData)
if err != nil {
if errors.Is(err, zhicha.ErrDatasource) {
return nil, errors.Join(processors.ErrDatasource, err)
} else {
return nil, errors.Join(processors.ErrSystem, err)
}
}
// 将响应数据转换为JSON字节
respBytes, err := json.Marshal(respData)
if err != nil {
return nil, errors.Join(processors.ErrSystem, err)
}
return respBytes, nil
}

View File

@@ -4,13 +4,15 @@ import (
"context" "context"
"encoding/json" "encoding/json"
"errors" "errors"
"math"
"strconv"
"tyapi-server/internal/domains/api/dto" "tyapi-server/internal/domains/api/dto"
"tyapi-server/internal/domains/api/services/processors" "tyapi-server/internal/domains/api/services/processors"
"tyapi-server/internal/infrastructure/external/xingwei" "tyapi-server/internal/infrastructure/external/zhicha"
) )
// ProcessJRZQ0L85Request JRZQ0L85 API处理方法 - xingwei service // ProcessJRZQ0L85Request JRZQ0L85 API处理方法 - 个人信用分
func ProcessJRZQ0L85Request(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) { func ProcessJRZQ0L85Request(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) {
var paramsDto dto.JRZQ0L85Req var paramsDto dto.JRZQ0L85Req
if err := json.Unmarshal(params, &paramsDto); err != nil { if err := json.Unmarshal(params, &paramsDto); err != nil {
@@ -21,27 +23,100 @@ func ProcessJRZQ0L85Request(ctx context.Context, params []byte, deps *processors
return nil, errors.Join(processors.ErrInvalidParam, err) return nil, errors.Join(processors.ErrInvalidParam, err)
} }
// 构建请求数据,将项目规范的字段名转换为 XingweiService 需要的字段名 encryptedName, err := deps.ZhichaService.Encrypt(paramsDto.Name)
reqData := map[string]interface{}{ if err != nil {
"name": paramsDto.Name, return nil, errors.Join(processors.ErrSystem, err)
"idCardNum": paramsDto.IDCard,
"phoneNumber": paramsDto.MobileNo,
} }
// 调用行为数据API使用指定的project_id encryptedIDCard, err := deps.ZhichaService.Encrypt(paramsDto.IDCard)
projectID := "CDJ-1101695364016041984"
respBytes, err := deps.XingweiService.CallAPI(ctx, projectID, reqData)
if err != nil { if err != nil {
if errors.Is(err, xingwei.ErrNotFound) {
return nil, errors.Join(processors.ErrNotFound, err)
} else if errors.Is(err, xingwei.ErrDatasource) {
return nil, errors.Join(processors.ErrDatasource, err)
} else if errors.Is(err, xingwei.ErrSystem) {
return nil, errors.Join(processors.ErrSystem, err) return nil, errors.Join(processors.ErrSystem, err)
}
encryptedMobileNo, err := deps.ZhichaService.Encrypt(paramsDto.MobileNo)
if err != nil {
return nil, errors.Join(processors.ErrSystem, err)
}
reqData := map[string]interface{}{
"name": encryptedName,
"idCard": encryptedIDCard,
"phone": encryptedMobileNo,
"authorized": "1",
}
respData, err := deps.ZhichaService.CallAPI(ctx, "ZCI021", reqData)
if err != nil {
if errors.Is(err, zhicha.ErrDatasource) {
return nil, errors.Join(processors.ErrDatasource, err)
} else { } else {
return nil, errors.Join(processors.ErrSystem, err) return nil, errors.Join(processors.ErrSystem, err)
} }
} }
score := "-1"
if m, ok := respData.(map[string]interface{}); ok {
if raw, exists := m["xyp_cpl0081"]; exists {
if v, ok := parseToFloat64(raw); ok {
score = mapXypToGeneralScore(v)
}
}
}
result := map[string]interface{}{
"score_120_General": score,
}
respBytes, err := json.Marshal(result)
if err != nil {
return nil, errors.Join(processors.ErrSystem, err)
}
return respBytes, nil return respBytes, nil
} }
func parseToFloat64(v interface{}) (float64, bool) {
switch value := v.(type) {
case float64:
return value, true
case string:
if value == "" {
return 0, false
}
f, err := strconv.ParseFloat(value, 64)
if err != nil {
return 0, false
}
return f, true
case json.Number:
f, err := value.Float64()
if err != nil {
return 0, false
}
return f, true
default:
return 0, false
}
}
func mapXypToGeneralScore(xyp float64) string {
// xyp_cpl0081: 0~1值越大风险越高
// score_120_General: 300~900值越大信用越好。
if xyp < 0 {
xyp = 0
}
if xyp > 1 {
xyp = 1
}
score := 900 - xyp*600
scoreInt := int(math.Round(score))
if scoreInt < 300 {
scoreInt = 300
}
if scoreInt > 900 {
scoreInt = 900
}
return strconv.Itoa(scoreInt)
}

View File

@@ -0,0 +1,833 @@
package jrzq
var jrzq6F2AVariableKeys = []string{
"flag_applyloanstr",
"als_d7_id_pdl_allnum",
"als_d7_id_pdl_orgnum",
"als_d7_id_caon_allnum",
"als_d7_id_caon_orgnum",
"als_d7_id_rel_allnum",
"als_d7_id_rel_orgnum",
"als_d7_id_caoff_allnum",
"als_d7_id_caoff_orgnum",
"als_d7_id_cooff_allnum",
"als_d7_id_cooff_orgnum",
"als_d7_id_af_allnum",
"als_d7_id_af_orgnum",
"als_d7_id_coon_allnum",
"als_d7_id_coon_orgnum",
"als_d7_id_oth_allnum",
"als_d7_id_oth_orgnum",
"als_d7_id_bank_selfnum",
"als_d7_id_bank_allnum",
"als_d7_id_bank_tra_allnum",
"als_d7_id_bank_ret_allnum",
"als_d7_id_bank_orgnum",
"als_d7_id_bank_tra_orgnum",
"als_d7_id_bank_ret_orgnum",
"als_d7_id_bank_week_allnum",
"als_d7_id_bank_week_orgnum",
"als_d7_id_bank_night_allnum",
"als_d7_id_bank_night_orgnum",
"als_d7_id_nbank_selfnum",
"als_d7_id_nbank_allnum",
"als_d7_id_nbank_p2p_allnum",
"als_d7_id_nbank_mc_allnum",
"als_d7_id_nbank_ca_allnum",
"als_d7_id_nbank_cf_allnum",
"als_d7_id_nbank_com_allnum",
"als_d7_id_nbank_oth_allnum",
"als_d7_id_nbank_nsloan_allnum",
"als_d7_id_nbank_autofin_allnum",
"als_d7_id_nbank_sloan_allnum",
"als_d7_id_nbank_cons_allnum",
"als_d7_id_nbank_finlea_allnum",
"als_d7_id_nbank_else_allnum",
"als_d7_id_nbank_orgnum",
"als_d7_id_nbank_p2p_orgnum",
"als_d7_id_nbank_mc_orgnum",
"als_d7_id_nbank_ca_orgnum",
"als_d7_id_nbank_cf_orgnum",
"als_d7_id_nbank_com_orgnum",
"als_d7_id_nbank_oth_orgnum",
"als_d7_id_nbank_nsloan_orgnum",
"als_d7_id_nbank_autofin_orgnum",
"als_d7_id_nbank_sloan_orgnum",
"als_d7_id_nbank_cons_orgnum",
"als_d7_id_nbank_finlea_orgnum",
"als_d7_id_nbank_else_orgnum",
"als_d7_id_nbank_week_allnum",
"als_d7_id_nbank_week_orgnum",
"als_d7_id_nbank_night_allnum",
"als_d7_id_nbank_night_orgnum",
"als_d7_cell_pdl_allnum",
"als_d7_cell_pdl_orgnum",
"als_d7_cell_caon_allnum",
"als_d7_cell_caon_orgnum",
"als_d7_cell_rel_allnum",
"als_d7_cell_rel_orgnum",
"als_d7_cell_caoff_allnum",
"als_d7_cell_caoff_orgnum",
"als_d7_cell_cooff_allnum",
"als_d7_cell_cooff_orgnum",
"als_d7_cell_af_allnum",
"als_d7_cell_af_orgnum",
"als_d7_cell_coon_allnum",
"als_d7_cell_coon_orgnum",
"als_d7_cell_oth_allnum",
"als_d7_cell_oth_orgnum",
"als_d7_cell_bank_selfnum",
"als_d7_cell_bank_allnum",
"als_d7_cell_bank_tra_allnum",
"als_d7_cell_bank_ret_allnum",
"als_d7_cell_bank_orgnum",
"als_d7_cell_bank_tra_orgnum",
"als_d7_cell_bank_ret_orgnum",
"als_d7_cell_bank_week_allnum",
"als_d7_cell_bank_week_orgnum",
"als_d7_cell_bank_night_allnum",
"als_d7_cell_bank_night_orgnum",
"als_d7_cell_nbank_selfnum",
"als_d7_cell_nbank_allnum",
"als_d7_cell_nbank_p2p_allnum",
"als_d7_cell_nbank_mc_allnum",
"als_d7_cell_nbank_ca_allnum",
"als_d7_cell_nbank_cf_allnum",
"als_d7_cell_nbank_com_allnum",
"als_d7_cell_nbank_oth_allnum",
"als_d7_cell_nbank_nsloan_allnum",
"als_d7_cell_nbank_autofin_allnum",
"als_d7_cell_nbank_sloan_allnum",
"als_d7_cell_nbank_cons_allnum",
"als_d7_cell_nbank_finlea_allnum",
"als_d7_cell_nbank_else_allnum",
"als_d7_cell_nbank_orgnum",
"als_d7_cell_nbank_p2p_orgnum",
"als_d7_cell_nbank_mc_orgnum",
"als_d7_cell_nbank_ca_orgnum",
"als_d7_cell_nbank_cf_orgnum",
"als_d7_cell_nbank_com_orgnum",
"als_d7_cell_nbank_oth_orgnum",
"als_d7_cell_nbank_nsloan_orgnum",
"als_d7_cell_nbank_autofin_orgnum",
"als_d7_cell_nbank_sloan_orgnum",
"als_d7_cell_nbank_cons_orgnum",
"als_d7_cell_nbank_finlea_orgnum",
"als_d7_cell_nbank_else_orgnum",
"als_d7_cell_nbank_week_allnum",
"als_d7_cell_nbank_week_orgnum",
"als_d7_cell_nbank_night_allnum",
"als_d7_cell_nbank_night_orgnum",
"als_d15_id_pdl_allnum",
"als_d15_id_pdl_orgnum",
"als_d15_id_caon_allnum",
"als_d15_id_caon_orgnum",
"als_d15_id_rel_allnum",
"als_d15_id_rel_orgnum",
"als_d15_id_caoff_allnum",
"als_d15_id_caoff_orgnum",
"als_d15_id_cooff_allnum",
"als_d15_id_cooff_orgnum",
"als_d15_id_af_allnum",
"als_d15_id_af_orgnum",
"als_d15_id_coon_allnum",
"als_d15_id_coon_orgnum",
"als_d15_id_oth_allnum",
"als_d15_id_oth_orgnum",
"als_d15_id_bank_selfnum",
"als_d15_id_bank_allnum",
"als_d15_id_bank_tra_allnum",
"als_d15_id_bank_ret_allnum",
"als_d15_id_bank_orgnum",
"als_d15_id_bank_tra_orgnum",
"als_d15_id_bank_ret_orgnum",
"als_d15_id_bank_week_allnum",
"als_d15_id_bank_week_orgnum",
"als_d15_id_bank_night_allnum",
"als_d15_id_bank_night_orgnum",
"als_d15_id_nbank_selfnum",
"als_d15_id_nbank_allnum",
"als_d15_id_nbank_p2p_allnum",
"als_d15_id_nbank_mc_allnum",
"als_d15_id_nbank_ca_allnum",
"als_d15_id_nbank_cf_allnum",
"als_d15_id_nbank_com_allnum",
"als_d15_id_nbank_oth_allnum",
"als_d15_id_nbank_nsloan_allnum",
"als_d15_id_nbank_autofin_allnum",
"als_d15_id_nbank_sloan_allnum",
"als_d15_id_nbank_cons_allnum",
"als_d15_id_nbank_finlea_allnum",
"als_d15_id_nbank_else_allnum",
"als_d15_id_nbank_orgnum",
"als_d15_id_nbank_p2p_orgnum",
"als_d15_id_nbank_mc_orgnum",
"als_d15_id_nbank_ca_orgnum",
"als_d15_id_nbank_cf_orgnum",
"als_d15_id_nbank_com_orgnum",
"als_d15_id_nbank_oth_orgnum",
"als_d15_id_nbank_nsloan_orgnum",
"als_d15_id_nbank_autofin_orgnum",
"als_d15_id_nbank_sloan_orgnum",
"als_d15_id_nbank_cons_orgnum",
"als_d15_id_nbank_finlea_orgnum",
"als_d15_id_nbank_else_orgnum",
"als_d15_id_nbank_week_allnum",
"als_d15_id_nbank_week_orgnum",
"als_d15_id_nbank_night_allnum",
"als_d15_id_nbank_night_orgnum",
"als_d15_cell_pdl_allnum",
"als_d15_cell_pdl_orgnum",
"als_d15_cell_caon_allnum",
"als_d15_cell_caon_orgnum",
"als_d15_cell_rel_allnum",
"als_d15_cell_rel_orgnum",
"als_d15_cell_caoff_allnum",
"als_d15_cell_caoff_orgnum",
"als_d15_cell_cooff_allnum",
"als_d15_cell_cooff_orgnum",
"als_d15_cell_af_allnum",
"als_d15_cell_af_orgnum",
"als_d15_cell_coon_allnum",
"als_d15_cell_coon_orgnum",
"als_d15_cell_oth_allnum",
"als_d15_cell_oth_orgnum",
"als_d15_cell_bank_selfnum",
"als_d15_cell_bank_allnum",
"als_d15_cell_bank_tra_allnum",
"als_d15_cell_bank_ret_allnum",
"als_d15_cell_bank_orgnum",
"als_d15_cell_bank_tra_orgnum",
"als_d15_cell_bank_ret_orgnum",
"als_d15_cell_bank_week_allnum",
"als_d15_cell_bank_week_orgnum",
"als_d15_cell_bank_night_allnum",
"als_d15_cell_bank_night_orgnum",
"als_d15_cell_nbank_selfnum",
"als_d15_cell_nbank_allnum",
"als_d15_cell_nbank_p2p_allnum",
"als_d15_cell_nbank_mc_allnum",
"als_d15_cell_nbank_ca_allnum",
"als_d15_cell_nbank_cf_allnum",
"als_d15_cell_nbank_com_allnum",
"als_d15_cell_nbank_oth_allnum",
"als_d15_cell_nbank_nsloan_allnum",
"als_d15_cell_nbank_autofin_allnum",
"als_d15_cell_nbank_sloan_allnum",
"als_d15_cell_nbank_cons_allnum",
"als_d15_cell_nbank_finlea_allnum",
"als_d15_cell_nbank_else_allnum",
"als_d15_cell_nbank_orgnum",
"als_d15_cell_nbank_p2p_orgnum",
"als_d15_cell_nbank_mc_orgnum",
"als_d15_cell_nbank_ca_orgnum",
"als_d15_cell_nbank_cf_orgnum",
"als_d15_cell_nbank_com_orgnum",
"als_d15_cell_nbank_oth_orgnum",
"als_d15_cell_nbank_nsloan_orgnum",
"als_d15_cell_nbank_autofin_orgnum",
"als_d15_cell_nbank_sloan_orgnum",
"als_d15_cell_nbank_cons_orgnum",
"als_d15_cell_nbank_finlea_orgnum",
"als_d15_cell_nbank_else_orgnum",
"als_d15_cell_nbank_week_allnum",
"als_d15_cell_nbank_week_orgnum",
"als_d15_cell_nbank_night_allnum",
"als_d15_cell_nbank_night_orgnum",
"als_m1_id_pdl_allnum",
"als_m1_id_pdl_orgnum",
"als_m1_id_caon_allnum",
"als_m1_id_caon_orgnum",
"als_m1_id_rel_allnum",
"als_m1_id_rel_orgnum",
"als_m1_id_caoff_allnum",
"als_m1_id_caoff_orgnum",
"als_m1_id_cooff_allnum",
"als_m1_id_cooff_orgnum",
"als_m1_id_af_allnum",
"als_m1_id_af_orgnum",
"als_m1_id_coon_allnum",
"als_m1_id_coon_orgnum",
"als_m1_id_oth_allnum",
"als_m1_id_oth_orgnum",
"als_m1_id_bank_selfnum",
"als_m1_id_bank_allnum",
"als_m1_id_bank_tra_allnum",
"als_m1_id_bank_ret_allnum",
"als_m1_id_bank_orgnum",
"als_m1_id_bank_tra_orgnum",
"als_m1_id_bank_ret_orgnum",
"als_m1_id_bank_week_allnum",
"als_m1_id_bank_week_orgnum",
"als_m1_id_bank_night_allnum",
"als_m1_id_bank_night_orgnum",
"als_m1_id_nbank_selfnum",
"als_m1_id_nbank_allnum",
"als_m1_id_nbank_p2p_allnum",
"als_m1_id_nbank_mc_allnum",
"als_m1_id_nbank_ca_allnum",
"als_m1_id_nbank_cf_allnum",
"als_m1_id_nbank_com_allnum",
"als_m1_id_nbank_oth_allnum",
"als_m1_id_nbank_nsloan_allnum",
"als_m1_id_nbank_autofin_allnum",
"als_m1_id_nbank_sloan_allnum",
"als_m1_id_nbank_cons_allnum",
"als_m1_id_nbank_finlea_allnum",
"als_m1_id_nbank_else_allnum",
"als_m1_id_nbank_orgnum",
"als_m1_id_nbank_p2p_orgnum",
"als_m1_id_nbank_mc_orgnum",
"als_m1_id_nbank_ca_orgnum",
"als_m1_id_nbank_cf_orgnum",
"als_m1_id_nbank_com_orgnum",
"als_m1_id_nbank_oth_orgnum",
"als_m1_id_nbank_nsloan_orgnum",
"als_m1_id_nbank_autofin_orgnum",
"als_m1_id_nbank_sloan_orgnum",
"als_m1_id_nbank_cons_orgnum",
"als_m1_id_nbank_finlea_orgnum",
"als_m1_id_nbank_else_orgnum",
"als_m1_id_nbank_week_allnum",
"als_m1_id_nbank_week_orgnum",
"als_m1_id_nbank_night_allnum",
"als_m1_id_nbank_night_orgnum",
"als_m1_cell_pdl_allnum",
"als_m1_cell_pdl_orgnum",
"als_m1_cell_caon_allnum",
"als_m1_cell_caon_orgnum",
"als_m1_cell_rel_allnum",
"als_m1_cell_rel_orgnum",
"als_m1_cell_caoff_allnum",
"als_m1_cell_caoff_orgnum",
"als_m1_cell_cooff_allnum",
"als_m1_cell_cooff_orgnum",
"als_m1_cell_af_allnum",
"als_m1_cell_af_orgnum",
"als_m1_cell_coon_allnum",
"als_m1_cell_coon_orgnum",
"als_m1_cell_oth_allnum",
"als_m1_cell_oth_orgnum",
"als_m1_cell_bank_selfnum",
"als_m1_cell_bank_allnum",
"als_m1_cell_bank_tra_allnum",
"als_m1_cell_bank_ret_allnum",
"als_m1_cell_bank_orgnum",
"als_m1_cell_bank_tra_orgnum",
"als_m1_cell_bank_ret_orgnum",
"als_m1_cell_bank_week_allnum",
"als_m1_cell_bank_week_orgnum",
"als_m1_cell_bank_night_allnum",
"als_m1_cell_bank_night_orgnum",
"als_m1_cell_nbank_selfnum",
"als_m1_cell_nbank_allnum",
"als_m1_cell_nbank_p2p_allnum",
"als_m1_cell_nbank_mc_allnum",
"als_m1_cell_nbank_ca_allnum",
"als_m1_cell_nbank_cf_allnum",
"als_m1_cell_nbank_com_allnum",
"als_m1_cell_nbank_oth_allnum",
"als_m1_cell_nbank_nsloan_allnum",
"als_m1_cell_nbank_autofin_allnum",
"als_m1_cell_nbank_sloan_allnum",
"als_m1_cell_nbank_cons_allnum",
"als_m1_cell_nbank_finlea_allnum",
"als_m1_cell_nbank_else_allnum",
"als_m1_cell_nbank_orgnum",
"als_m1_cell_nbank_p2p_orgnum",
"als_m1_cell_nbank_mc_orgnum",
"als_m1_cell_nbank_ca_orgnum",
"als_m1_cell_nbank_cf_orgnum",
"als_m1_cell_nbank_com_orgnum",
"als_m1_cell_nbank_oth_orgnum",
"als_m1_cell_nbank_nsloan_orgnum",
"als_m1_cell_nbank_autofin_orgnum",
"als_m1_cell_nbank_sloan_orgnum",
"als_m1_cell_nbank_cons_orgnum",
"als_m1_cell_nbank_finlea_orgnum",
"als_m1_cell_nbank_else_orgnum",
"als_m1_cell_nbank_week_allnum",
"als_m1_cell_nbank_week_orgnum",
"als_m1_cell_nbank_night_allnum",
"als_m1_cell_nbank_night_orgnum",
"als_m3_id_max_inteday",
"als_m3_id_min_inteday",
"als_m3_id_tot_mons",
"als_m3_id_avg_monnum",
"als_m3_id_max_monnum",
"als_m3_id_min_monnum",
"als_m3_id_pdl_allnum",
"als_m3_id_pdl_orgnum",
"als_m3_id_caon_allnum",
"als_m3_id_caon_orgnum",
"als_m3_id_rel_allnum",
"als_m3_id_rel_orgnum",
"als_m3_id_caoff_allnum",
"als_m3_id_caoff_orgnum",
"als_m3_id_cooff_allnum",
"als_m3_id_cooff_orgnum",
"als_m3_id_af_allnum",
"als_m3_id_af_orgnum",
"als_m3_id_coon_allnum",
"als_m3_id_coon_orgnum",
"als_m3_id_oth_allnum",
"als_m3_id_oth_orgnum",
"als_m3_id_bank_selfnum",
"als_m3_id_bank_allnum",
"als_m3_id_bank_tra_allnum",
"als_m3_id_bank_ret_allnum",
"als_m3_id_bank_orgnum",
"als_m3_id_bank_tra_orgnum",
"als_m3_id_bank_ret_orgnum",
"als_m3_id_bank_tot_mons",
"als_m3_id_bank_avg_monnum",
"als_m3_id_bank_max_monnum",
"als_m3_id_bank_min_monnum",
"als_m3_id_bank_max_inteday",
"als_m3_id_bank_min_inteday",
"als_m3_id_bank_week_allnum",
"als_m3_id_bank_week_orgnum",
"als_m3_id_bank_night_allnum",
"als_m3_id_bank_night_orgnum",
"als_m3_id_nbank_selfnum",
"als_m3_id_nbank_allnum",
"als_m3_id_nbank_p2p_allnum",
"als_m3_id_nbank_mc_allnum",
"als_m3_id_nbank_ca_allnum",
"als_m3_id_nbank_cf_allnum",
"als_m3_id_nbank_com_allnum",
"als_m3_id_nbank_oth_allnum",
"als_m3_id_nbank_nsloan_allnum",
"als_m3_id_nbank_autofin_allnum",
"als_m3_id_nbank_sloan_allnum",
"als_m3_id_nbank_cons_allnum",
"als_m3_id_nbank_finlea_allnum",
"als_m3_id_nbank_else_allnum",
"als_m3_id_nbank_orgnum",
"als_m3_id_nbank_p2p_orgnum",
"als_m3_id_nbank_mc_orgnum",
"als_m3_id_nbank_ca_orgnum",
"als_m3_id_nbank_cf_orgnum",
"als_m3_id_nbank_com_orgnum",
"als_m3_id_nbank_oth_orgnum",
"als_m3_id_nbank_nsloan_orgnum",
"als_m3_id_nbank_autofin_orgnum",
"als_m3_id_nbank_sloan_orgnum",
"als_m3_id_nbank_cons_orgnum",
"als_m3_id_nbank_finlea_orgnum",
"als_m3_id_nbank_else_orgnum",
"als_m3_id_nbank_tot_mons",
"als_m3_id_nbank_avg_monnum",
"als_m3_id_nbank_max_monnum",
"als_m3_id_nbank_min_monnum",
"als_m3_id_nbank_max_inteday",
"als_m3_id_nbank_min_inteday",
"als_m3_id_nbank_week_allnum",
"als_m3_id_nbank_week_orgnum",
"als_m3_id_nbank_night_allnum",
"als_m3_id_nbank_night_orgnum",
"als_m3_cell_max_inteday",
"als_m3_cell_min_inteday",
"als_m3_cell_tot_mons",
"als_m3_cell_avg_monnum",
"als_m3_cell_max_monnum",
"als_m3_cell_min_monnum",
"als_m3_cell_pdl_allnum",
"als_m3_cell_pdl_orgnum",
"als_m3_cell_caon_allnum",
"als_m3_cell_caon_orgnum",
"als_m3_cell_rel_allnum",
"als_m3_cell_rel_orgnum",
"als_m3_cell_caoff_allnum",
"als_m3_cell_caoff_orgnum",
"als_m3_cell_cooff_allnum",
"als_m3_cell_cooff_orgnum",
"als_m3_cell_af_allnum",
"als_m3_cell_af_orgnum",
"als_m3_cell_coon_allnum",
"als_m3_cell_coon_orgnum",
"als_m3_cell_oth_allnum",
"als_m3_cell_oth_orgnum",
"als_m3_cell_bank_selfnum",
"als_m3_cell_bank_allnum",
"als_m3_cell_bank_tra_allnum",
"als_m3_cell_bank_ret_allnum",
"als_m3_cell_bank_orgnum",
"als_m3_cell_bank_tra_orgnum",
"als_m3_cell_bank_ret_orgnum",
"als_m3_cell_bank_tot_mons",
"als_m3_cell_bank_avg_monnum",
"als_m3_cell_bank_max_monnum",
"als_m3_cell_bank_min_monnum",
"als_m3_cell_bank_max_inteday",
"als_m3_cell_bank_min_inteday",
"als_m3_cell_bank_week_allnum",
"als_m3_cell_bank_week_orgnum",
"als_m3_cell_bank_night_allnum",
"als_m3_cell_bank_night_orgnum",
"als_m3_cell_nbank_selfnum",
"als_m3_cell_nbank_allnum",
"als_m3_cell_nbank_p2p_allnum",
"als_m3_cell_nbank_mc_allnum",
"als_m3_cell_nbank_ca_allnum",
"als_m3_cell_nbank_cf_allnum",
"als_m3_cell_nbank_com_allnum",
"als_m3_cell_nbank_oth_allnum",
"als_m3_cell_nbank_nsloan_allnum",
"als_m3_cell_nbank_autofin_allnum",
"als_m3_cell_nbank_sloan_allnum",
"als_m3_cell_nbank_cons_allnum",
"als_m3_cell_nbank_finlea_allnum",
"als_m3_cell_nbank_else_allnum",
"als_m3_cell_nbank_orgnum",
"als_m3_cell_nbank_p2p_orgnum",
"als_m3_cell_nbank_mc_orgnum",
"als_m3_cell_nbank_ca_orgnum",
"als_m3_cell_nbank_cf_orgnum",
"als_m3_cell_nbank_com_orgnum",
"als_m3_cell_nbank_oth_orgnum",
"als_m3_cell_nbank_nsloan_orgnum",
"als_m3_cell_nbank_autofin_orgnum",
"als_m3_cell_nbank_sloan_orgnum",
"als_m3_cell_nbank_cons_orgnum",
"als_m3_cell_nbank_finlea_orgnum",
"als_m3_cell_nbank_else_orgnum",
"als_m3_cell_nbank_tot_mons",
"als_m3_cell_nbank_avg_monnum",
"als_m3_cell_nbank_max_monnum",
"als_m3_cell_nbank_min_monnum",
"als_m3_cell_nbank_max_inteday",
"als_m3_cell_nbank_min_inteday",
"als_m3_cell_nbank_week_allnum",
"als_m3_cell_nbank_week_orgnum",
"als_m3_cell_nbank_night_allnum",
"als_m3_cell_nbank_night_orgnum",
"als_m6_id_max_inteday",
"als_m6_id_min_inteday",
"als_m6_id_tot_mons",
"als_m6_id_avg_monnum",
"als_m6_id_max_monnum",
"als_m6_id_min_monnum",
"als_m6_id_pdl_allnum",
"als_m6_id_pdl_orgnum",
"als_m6_id_caon_allnum",
"als_m6_id_caon_orgnum",
"als_m6_id_rel_allnum",
"als_m6_id_rel_orgnum",
"als_m6_id_caoff_allnum",
"als_m6_id_caoff_orgnum",
"als_m6_id_cooff_allnum",
"als_m6_id_cooff_orgnum",
"als_m6_id_af_allnum",
"als_m6_id_af_orgnum",
"als_m6_id_coon_allnum",
"als_m6_id_coon_orgnum",
"als_m6_id_oth_allnum",
"als_m6_id_oth_orgnum",
"als_m6_id_bank_selfnum",
"als_m6_id_bank_allnum",
"als_m6_id_bank_tra_allnum",
"als_m6_id_bank_ret_allnum",
"als_m6_id_bank_orgnum",
"als_m6_id_bank_tra_orgnum",
"als_m6_id_bank_ret_orgnum",
"als_m6_id_bank_tot_mons",
"als_m6_id_bank_avg_monnum",
"als_m6_id_bank_max_monnum",
"als_m6_id_bank_min_monnum",
"als_m6_id_bank_max_inteday",
"als_m6_id_bank_min_inteday",
"als_m6_id_bank_week_allnum",
"als_m6_id_bank_week_orgnum",
"als_m6_id_bank_night_allnum",
"als_m6_id_bank_night_orgnum",
"als_m6_id_nbank_selfnum",
"als_m6_id_nbank_allnum",
"als_m6_id_nbank_p2p_allnum",
"als_m6_id_nbank_mc_allnum",
"als_m6_id_nbank_ca_allnum",
"als_m6_id_nbank_cf_allnum",
"als_m6_id_nbank_com_allnum",
"als_m6_id_nbank_oth_allnum",
"als_m6_id_nbank_nsloan_allnum",
"als_m6_id_nbank_autofin_allnum",
"als_m6_id_nbank_sloan_allnum",
"als_m6_id_nbank_cons_allnum",
"als_m6_id_nbank_finlea_allnum",
"als_m6_id_nbank_else_allnum",
"als_m6_id_nbank_orgnum",
"als_m6_id_nbank_p2p_orgnum",
"als_m6_id_nbank_mc_orgnum",
"als_m6_id_nbank_ca_orgnum",
"als_m6_id_nbank_cf_orgnum",
"als_m6_id_nbank_com_orgnum",
"als_m6_id_nbank_oth_orgnum",
"als_m6_id_nbank_nsloan_orgnum",
"als_m6_id_nbank_autofin_orgnum",
"als_m6_id_nbank_sloan_orgnum",
"als_m6_id_nbank_cons_orgnum",
"als_m6_id_nbank_finlea_orgnum",
"als_m6_id_nbank_else_orgnum",
"als_m6_id_nbank_tot_mons",
"als_m6_id_nbank_avg_monnum",
"als_m6_id_nbank_max_monnum",
"als_m6_id_nbank_min_monnum",
"als_m6_id_nbank_max_inteday",
"als_m6_id_nbank_min_inteday",
"als_m6_id_nbank_week_allnum",
"als_m6_id_nbank_week_orgnum",
"als_m6_id_nbank_night_allnum",
"als_m6_id_nbank_night_orgnum",
"als_m6_cell_max_inteday",
"als_m6_cell_min_inteday",
"als_m6_cell_tot_mons",
"als_m6_cell_avg_monnum",
"als_m6_cell_max_monnum",
"als_m6_cell_min_monnum",
"als_m6_cell_pdl_allnum",
"als_m6_cell_pdl_orgnum",
"als_m6_cell_caon_allnum",
"als_m6_cell_caon_orgnum",
"als_m6_cell_rel_allnum",
"als_m6_cell_rel_orgnum",
"als_m6_cell_caoff_allnum",
"als_m6_cell_caoff_orgnum",
"als_m6_cell_cooff_allnum",
"als_m6_cell_cooff_orgnum",
"als_m6_cell_af_allnum",
"als_m6_cell_af_orgnum",
"als_m6_cell_coon_allnum",
"als_m6_cell_coon_orgnum",
"als_m6_cell_oth_allnum",
"als_m6_cell_oth_orgnum",
"als_m6_cell_bank_selfnum",
"als_m6_cell_bank_allnum",
"als_m6_cell_bank_tra_allnum",
"als_m6_cell_bank_ret_allnum",
"als_m6_cell_bank_orgnum",
"als_m6_cell_bank_tra_orgnum",
"als_m6_cell_bank_ret_orgnum",
"als_m6_cell_bank_tot_mons",
"als_m6_cell_bank_avg_monnum",
"als_m6_cell_bank_max_monnum",
"als_m6_cell_bank_min_monnum",
"als_m6_cell_bank_max_inteday",
"als_m6_cell_bank_min_inteday",
"als_m6_cell_bank_week_allnum",
"als_m6_cell_bank_week_orgnum",
"als_m6_cell_bank_night_allnum",
"als_m6_cell_bank_night_orgnum",
"als_m6_cell_nbank_selfnum",
"als_m6_cell_nbank_allnum",
"als_m6_cell_nbank_p2p_allnum",
"als_m6_cell_nbank_mc_allnum",
"als_m6_cell_nbank_ca_allnum",
"als_m6_cell_nbank_cf_allnum",
"als_m6_cell_nbank_com_allnum",
"als_m6_cell_nbank_oth_allnum",
"als_m6_cell_nbank_nsloan_allnum",
"als_m6_cell_nbank_autofin_allnum",
"als_m6_cell_nbank_sloan_allnum",
"als_m6_cell_nbank_cons_allnum",
"als_m6_cell_nbank_finlea_allnum",
"als_m6_cell_nbank_else_allnum",
"als_m6_cell_nbank_orgnum",
"als_m6_cell_nbank_p2p_orgnum",
"als_m6_cell_nbank_mc_orgnum",
"als_m6_cell_nbank_ca_orgnum",
"als_m6_cell_nbank_cf_orgnum",
"als_m6_cell_nbank_com_orgnum",
"als_m6_cell_nbank_oth_orgnum",
"als_m6_cell_nbank_nsloan_orgnum",
"als_m6_cell_nbank_autofin_orgnum",
"als_m6_cell_nbank_sloan_orgnum",
"als_m6_cell_nbank_cons_orgnum",
"als_m6_cell_nbank_finlea_orgnum",
"als_m6_cell_nbank_else_orgnum",
"als_m6_cell_nbank_tot_mons",
"als_m6_cell_nbank_avg_monnum",
"als_m6_cell_nbank_max_monnum",
"als_m6_cell_nbank_min_monnum",
"als_m6_cell_nbank_max_inteday",
"als_m6_cell_nbank_min_inteday",
"als_m6_cell_nbank_week_allnum",
"als_m6_cell_nbank_week_orgnum",
"als_m6_cell_nbank_night_allnum",
"als_m6_cell_nbank_night_orgnum",
"als_m12_id_max_inteday",
"als_m12_id_min_inteday",
"als_m12_id_tot_mons",
"als_m12_id_avg_monnum",
"als_m12_id_max_monnum",
"als_m12_id_min_monnum",
"als_m12_id_pdl_allnum",
"als_m12_id_pdl_orgnum",
"als_m12_id_caon_allnum",
"als_m12_id_caon_orgnum",
"als_m12_id_rel_allnum",
"als_m12_id_rel_orgnum",
"als_m12_id_caoff_allnum",
"als_m12_id_caoff_orgnum",
"als_m12_id_cooff_allnum",
"als_m12_id_cooff_orgnum",
"als_m12_id_af_allnum",
"als_m12_id_af_orgnum",
"als_m12_id_coon_allnum",
"als_m12_id_coon_orgnum",
"als_m12_id_oth_allnum",
"als_m12_id_oth_orgnum",
"als_m12_id_bank_selfnum",
"als_m12_id_bank_allnum",
"als_m12_id_bank_tra_allnum",
"als_m12_id_bank_ret_allnum",
"als_m12_id_bank_orgnum",
"als_m12_id_bank_tra_orgnum",
"als_m12_id_bank_ret_orgnum",
"als_m12_id_bank_tot_mons",
"als_m12_id_bank_avg_monnum",
"als_m12_id_bank_max_monnum",
"als_m12_id_bank_min_monnum",
"als_m12_id_bank_max_inteday",
"als_m12_id_bank_min_inteday",
"als_m12_id_bank_week_allnum",
"als_m12_id_bank_week_orgnum",
"als_m12_id_bank_night_allnum",
"als_m12_id_bank_night_orgnum",
"als_m12_id_nbank_selfnum",
"als_m12_id_nbank_allnum",
"als_m12_id_nbank_p2p_allnum",
"als_m12_id_nbank_mc_allnum",
"als_m12_id_nbank_ca_allnum",
"als_m12_id_nbank_cf_allnum",
"als_m12_id_nbank_com_allnum",
"als_m12_id_nbank_oth_allnum",
"als_m12_id_nbank_nsloan_allnum",
"als_m12_id_nbank_autofin_allnum",
"als_m12_id_nbank_sloan_allnum",
"als_m12_id_nbank_cons_allnum",
"als_m12_id_nbank_finlea_allnum",
"als_m12_id_nbank_else_allnum",
"als_m12_id_nbank_orgnum",
"als_m12_id_nbank_p2p_orgnum",
"als_m12_id_nbank_mc_orgnum",
"als_m12_id_nbank_ca_orgnum",
"als_m12_id_nbank_cf_orgnum",
"als_m12_id_nbank_com_orgnum",
"als_m12_id_nbank_oth_orgnum",
"als_m12_id_nbank_nsloan_orgnum",
"als_m12_id_nbank_autofin_orgnum",
"als_m12_id_nbank_sloan_orgnum",
"als_m12_id_nbank_cons_orgnum",
"als_m12_id_nbank_finlea_orgnum",
"als_m12_id_nbank_else_orgnum",
"als_m12_id_nbank_tot_mons",
"als_m12_id_nbank_avg_monnum",
"als_m12_id_nbank_max_monnum",
"als_m12_id_nbank_min_monnum",
"als_m12_id_nbank_max_inteday",
"als_m12_id_nbank_min_inteday",
"als_m12_id_nbank_week_allnum",
"als_m12_id_nbank_week_orgnum",
"als_m12_id_nbank_night_allnum",
"als_m12_id_nbank_night_orgnum",
"als_m12_cell_max_inteday",
"als_m12_cell_min_inteday",
"als_m12_cell_tot_mons",
"als_m12_cell_avg_monnum",
"als_m12_cell_max_monnum",
"als_m12_cell_min_monnum",
"als_m12_cell_pdl_allnum",
"als_m12_cell_pdl_orgnum",
"als_m12_cell_caon_allnum",
"als_m12_cell_caon_orgnum",
"als_m12_cell_rel_allnum",
"als_m12_cell_rel_orgnum",
"als_m12_cell_caoff_allnum",
"als_m12_cell_caoff_orgnum",
"als_m12_cell_cooff_allnum",
"als_m12_cell_cooff_orgnum",
"als_m12_cell_af_allnum",
"als_m12_cell_af_orgnum",
"als_m12_cell_coon_allnum",
"als_m12_cell_coon_orgnum",
"als_m12_cell_oth_allnum",
"als_m12_cell_oth_orgnum",
"als_m12_cell_bank_selfnum",
"als_m12_cell_bank_allnum",
"als_m12_cell_bank_tra_allnum",
"als_m12_cell_bank_ret_allnum",
"als_m12_cell_bank_orgnum",
"als_m12_cell_bank_tra_orgnum",
"als_m12_cell_bank_ret_orgnum",
"als_m12_cell_bank_tot_mons",
"als_m12_cell_bank_avg_monnum",
"als_m12_cell_bank_max_monnum",
"als_m12_cell_bank_min_monnum",
"als_m12_cell_bank_max_inteday",
"als_m12_cell_bank_min_inteday",
"als_m12_cell_bank_week_allnum",
"als_m12_cell_bank_week_orgnum",
"als_m12_cell_bank_night_allnum",
"als_m12_cell_bank_night_orgnum",
"als_m12_cell_nbank_selfnum",
"als_m12_cell_nbank_allnum",
"als_m12_cell_nbank_p2p_allnum",
"als_m12_cell_nbank_mc_allnum",
"als_m12_cell_nbank_ca_allnum",
"als_m12_cell_nbank_cf_allnum",
"als_m12_cell_nbank_com_allnum",
"als_m12_cell_nbank_oth_allnum",
"als_m12_cell_nbank_nsloan_allnum",
"als_m12_cell_nbank_autofin_allnum",
"als_m12_cell_nbank_sloan_allnum",
"als_m12_cell_nbank_cons_allnum",
"als_m12_cell_nbank_finlea_allnum",
"als_m12_cell_nbank_else_allnum",
"als_m12_cell_nbank_orgnum",
"als_m12_cell_nbank_p2p_orgnum",
"als_m12_cell_nbank_mc_orgnum",
"als_m12_cell_nbank_ca_orgnum",
"als_m12_cell_nbank_cf_orgnum",
"als_m12_cell_nbank_com_orgnum",
"als_m12_cell_nbank_oth_orgnum",
"als_m12_cell_nbank_nsloan_orgnum",
"als_m12_cell_nbank_autofin_orgnum",
"als_m12_cell_nbank_sloan_orgnum",
"als_m12_cell_nbank_cons_orgnum",
"als_m12_cell_nbank_finlea_orgnum",
"als_m12_cell_nbank_else_orgnum",
"als_m12_cell_nbank_tot_mons",
"als_m12_cell_nbank_avg_monnum",
"als_m12_cell_nbank_max_monnum",
"als_m12_cell_nbank_min_monnum",
"als_m12_cell_nbank_max_inteday",
"als_m12_cell_nbank_min_inteday",
"als_m12_cell_nbank_week_allnum",
"als_m12_cell_nbank_week_orgnum",
"als_m12_cell_nbank_night_allnum",
"als_m12_cell_nbank_night_orgnum",
"als_fst_id_bank_inteday",
"als_fst_id_nbank_inteday",
"als_fst_cell_bank_inteday",
"als_fst_cell_nbank_inteday",
"als_lst_id_bank_inteday",
"als_lst_id_bank_consnum",
"als_lst_id_bank_csinteday",
"als_lst_id_nbank_inteday",
"als_lst_id_nbank_consnum",
"als_lst_id_nbank_csinteday",
"als_lst_cell_bank_inteday",
"als_lst_cell_bank_consnum",
"als_lst_cell_bank_csinteday",
"als_lst_cell_nbank_inteday",
"als_lst_cell_nbank_consnum",
"als_lst_cell_nbank_csinteday",
}
var jrzq6F2AKeySet = func() map[string]struct{} {
m := make(map[string]struct{}, len(jrzq6F2AVariableKeys))
for _, key := range jrzq6F2AVariableKeys {
m[key] = struct{}{}
}
return m
}()

View File

@@ -4,10 +4,11 @@ import (
"context" "context"
"encoding/json" "encoding/json"
"errors" "errors"
"strings"
"tyapi-server/internal/domains/api/dto" "tyapi-server/internal/domains/api/dto"
"tyapi-server/internal/domains/api/services/processors" "tyapi-server/internal/domains/api/services/processors"
"tyapi-server/internal/infrastructure/external/xingwei" "tyapi-server/internal/infrastructure/external/zhicha"
) )
// ProcessJRZQ6F2ARequest JRZQ6F2A API处理方法 - 借贷申请记录 // ProcessJRZQ6F2ARequest JRZQ6F2A API处理方法 - 借贷申请记录
@@ -21,27 +22,196 @@ func ProcessJRZQ6F2ARequest(ctx context.Context, params []byte, deps *processors
return nil, errors.Join(processors.ErrInvalidParam, err) return nil, errors.Join(processors.ErrInvalidParam, err)
} }
// 构建请求数据,将项目规范的字段名转换为 XingweiService 需要的字段名 encryptedName, err := deps.ZhichaService.Encrypt(paramsDto.Name)
reqData := map[string]interface{}{ if err != nil {
"name": paramsDto.Name, return nil, errors.Join(processors.ErrSystem, err)
"idCardNum": paramsDto.IDCard,
"phoneNumber": paramsDto.MobileNo,
} }
// 调用行为数据API使用指定的project_id encryptedIDCard, err := deps.ZhichaService.Encrypt(paramsDto.IDCard)
projectID := "CDJ-1101695369065984000"
respBytes, err := deps.XingweiService.CallAPI(ctx, projectID, reqData)
if err != nil { if err != nil {
if errors.Is(err, xingwei.ErrNotFound) {
return nil, errors.Join(processors.ErrNotFound, err)
} else if errors.Is(err, xingwei.ErrDatasource) {
return nil, errors.Join(processors.ErrDatasource, err)
} else if errors.Is(err, xingwei.ErrSystem) {
return nil, errors.Join(processors.ErrSystem, err) return nil, errors.Join(processors.ErrSystem, err)
}
encryptedMobileNo, err := deps.ZhichaService.Encrypt(paramsDto.MobileNo)
if err != nil {
return nil, errors.Join(processors.ErrSystem, err)
}
reqData := map[string]interface{}{
"name": encryptedName,
"idCard": encryptedIDCard,
"phone": encryptedMobileNo,
"authorized": "1",
}
respData, err := deps.ZhichaService.CallAPI(ctx, "ZCI017", reqData)
if err != nil {
if errors.Is(err, zhicha.ErrDatasource) {
return nil, errors.Join(processors.ErrDatasource, err)
} else { } else {
return nil, errors.Join(processors.ErrSystem, err) return nil, errors.Join(processors.ErrSystem, err)
} }
} }
respMap, ok := respData.(map[string]interface{})
if !ok {
return nil, errors.Join(processors.ErrSystem, errors.New("响应格式错误"))
}
result := mapJRZQ3C7BToJRZQ6F2A(respMap)
respBytes, err := json.Marshal(result)
if err != nil {
return nil, errors.Join(processors.ErrSystem, err)
}
return respBytes, nil return respBytes, nil
} }
func mapJRZQ3C7BToJRZQ6F2A(src map[string]interface{}) map[string]interface{} {
variableValue := buildDefaultVariableValue()
// 如果源已经是平铺字段,优先直接覆盖,兼容不同返回形态。
copyDirectFlattenFields(variableValue, src)
periods := []string{"d7", "d15", "m1", "m3", "m6", "m12"}
for _, period := range periods {
periodData := asMap(src[period])
if len(periodData) == 0 {
continue
}
for _, scope := range []string{"id", "cell"} {
scopeData := asMap(periodData[scope])
if len(scopeData) == 0 {
continue
}
flattenPeriodScope(variableValue, period, scope, scopeData)
}
}
return map[string]interface{}{
"risk_screen_v2": map[string]interface{}{
"fulinHitFlag": 1,
"models": []interface{}{},
"variables": []interface{}{map[string]interface{}{"variableName": "bairong_applyloan_extend", "variableValue": variableValue}},
"code": "OK",
"decision": "accept",
"propertyValidations": []interface{}{},
"strategies": []interface{}{},
"scenes": []interface{}{},
"validateInfo": map[string]interface{}{"productCodes": []interface{}{}},
"id": "",
"message": "业务处理成功!",
"knowledge": map[string]interface{}{},
},
}
}
func flattenPeriodScope(target map[string]interface{}, period, scope string, scopeData map[string]interface{}) {
basePrefix := "als_" + period + "_" + scope + "_"
// 先处理 scope 级基础字段(例如 tot_mons/max_monnum/min_monnum/avg_monnum
copyScalarFields(target, basePrefix, scopeData)
for key, raw := range scopeData {
child := asMap(raw)
if len(child) == 0 {
continue
}
sectionPrefix := basePrefix + key + "_"
copyScalarFields(target, sectionPrefix, child)
// 对周末字段做兼容命名映射
copyAliasIfPresent(target, sectionPrefix, child, "weekend_allnum", "week_allnum")
copyAliasIfPresent(target, sectionPrefix, child, "weekend_orgnum", "week_orgnum")
// 对 top_* 与 *_d 字段做兜底映射,尽可能补齐常用 allnum/orgnum
if _, ok := target[sectionPrefix+"allnum"]; !ok {
copyAliasIfPresent(target, sectionPrefix, child, "top_allnum", "allnum")
copyAliasIfPresent(target, sectionPrefix, child, "allnum_d", "allnum")
}
if _, ok := target[sectionPrefix+"orgnum"]; !ok {
copyAliasIfPresent(target, sectionPrefix, child, "top_orgnum", "orgnum")
copyAliasIfPresent(target, sectionPrefix, child, "orgnum_d", "orgnum")
}
}
}
func copyScalarFields(target map[string]interface{}, prefix string, src map[string]interface{}) {
for k, v := range src {
if isScalar(v) {
setVariableField(target, prefix+normalizeMetricName(k), v)
}
}
}
func copyAliasIfPresent(target map[string]interface{}, prefix string, src map[string]interface{}, from, to string) {
if v, ok := src[from]; ok && isScalar(v) {
setVariableField(target, prefix+to, v)
}
}
func copyDirectFlattenFields(target map[string]interface{}, src map[string]interface{}) {
for k, v := range src {
if !isScalar(v) {
continue
}
// 允许直接覆盖文档字段以及兼容字段
setVariableField(target, k, v)
}
}
func normalizeMetricName(name string) string {
switch name {
case "weekend_allnum":
return "week_allnum"
case "weekend_orgnum":
return "week_orgnum"
default:
return strings.TrimSpace(name)
}
}
func isScalar(v interface{}) bool {
switch v.(type) {
case nil:
return false
case string, bool, float64, int, int32, int64, uint, uint32, uint64:
return true
default:
return false
}
}
func asMap(v interface{}) map[string]interface{} {
if v == nil {
return map[string]interface{}{}
}
if m, ok := v.(map[string]interface{}); ok {
return m
}
return map[string]interface{}{}
}
func buildDefaultVariableValue() map[string]interface{} {
m := make(map[string]interface{}, len(jrzq6F2AVariableKeys)+3)
for _, key := range jrzq6F2AVariableKeys {
m[key] = ""
}
// 兼容历史示例中出现的附加字段
m["als_Flag_applyloanstr"] = "1"
m["code"] = "00"
m["swift_number"] = ""
m["flag_applyloanstr"] = "1"
return m
}
func setVariableField(target map[string]interface{}, key string, value interface{}) {
_, inDoc := jrzq6F2AKeySet[key]
if inDoc || key == "als_Flag_applyloanstr" || key == "code" || key == "swift_number" {
target[key] = value
}
}

View File

@@ -4,10 +4,13 @@ import (
"context" "context"
"encoding/json" "encoding/json"
"errors" "errors"
"math"
"strconv"
"strings"
"tyapi-server/internal/domains/api/dto" "tyapi-server/internal/domains/api/dto"
"tyapi-server/internal/domains/api/services/processors" "tyapi-server/internal/domains/api/services/processors"
"tyapi-server/internal/infrastructure/external/xingwei" "tyapi-server/internal/infrastructure/external/zhicha"
) )
// ProcessJRZQ8B3CRequest JRZQ8B3C API处理方法 - 个人消费能力等级 // ProcessJRZQ8B3CRequest JRZQ8B3C API处理方法 - 个人消费能力等级
@@ -21,27 +24,173 @@ func ProcessJRZQ8B3CRequest(ctx context.Context, params []byte, deps *processors
return nil, errors.Join(processors.ErrInvalidParam, err) return nil, errors.Join(processors.ErrInvalidParam, err)
} }
// 构建请求数据,将项目规范的字段名转换为 XingweiService 需要的字段名 encryptedName, err := deps.ZhichaService.Encrypt(paramsDto.Name)
reqData := map[string]interface{}{ if err != nil {
"name": paramsDto.Name, return nil, errors.Join(processors.ErrSystem, err)
"idCardNum": paramsDto.IDCard,
"phoneNumber": paramsDto.MobileNo,
} }
// 调用行为数据API使用指定的project_id encryptedIDCard, err := deps.ZhichaService.Encrypt(paramsDto.IDCard)
projectID := "CDJ-1101695392528920576"
respBytes, err := deps.XingweiService.CallAPI(ctx, projectID, reqData)
if err != nil { if err != nil {
if errors.Is(err, xingwei.ErrNotFound) {
return nil, errors.Join(processors.ErrNotFound, err)
} else if errors.Is(err, xingwei.ErrDatasource) {
return nil, errors.Join(processors.ErrDatasource, err)
} else if errors.Is(err, xingwei.ErrSystem) {
return nil, errors.Join(processors.ErrSystem, err) return nil, errors.Join(processors.ErrSystem, err)
}
encryptedMobileNo, err := deps.ZhichaService.Encrypt(paramsDto.MobileNo)
if err != nil {
return nil, errors.Join(processors.ErrSystem, err)
}
reqData := map[string]interface{}{
"name": encryptedName,
"idCard": encryptedIDCard,
"phone": encryptedMobileNo,
"authorized": "1",
}
respData, err := deps.ZhichaService.CallAPI(ctx, "ZCI034", reqData)
if err != nil {
if errors.Is(err, zhicha.ErrDatasource) {
return nil, errors.Join(processors.ErrDatasource, err)
} else { } else {
return nil, errors.Join(processors.ErrSystem, err) return nil, errors.Join(processors.ErrSystem, err)
} }
} }
personIncomeIndex := "-1"
if m, ok := respData.(map[string]interface{}); ok {
personIncomeIndex = mapTap010ToIncomeIndex(m["tap010"], paramsDto.IDCard)
}
respPayload := map[string]interface{}{
"personincome_index_2.0": personIncomeIndex,
}
respBytes, err := json.Marshal(respPayload)
if err != nil {
return nil, errors.Join(processors.ErrSystem, err)
}
return respBytes, nil return respBytes, nil
} }
type incomeTier struct {
Score int
Low float64
High float64 // 上界闭区间math.Inf(1) 表示正无穷
}
var incomeTiers = []incomeTier{
{Score: 100, Low: 1000, High: 2000},
{Score: 200, Low: 2000, High: 4000},
{Score: 300, Low: 4000, High: 6000},
{Score: 400, Low: 6000, High: 8000},
{Score: 500, Low: 8000, High: 10000},
{Score: 600, Low: 10000, High: 12000},
{Score: 700, Low: 12000, High: 15000},
{Score: 800, Low: 15000, High: 20000},
{Score: 900, Low: 20000, High: 25000},
{Score: 1000, Low: 25000, High: math.Inf(1)},
}
func mapTap010ToIncomeIndex(rawTap010 interface{}, idCard string) string {
tap010, ok := parseTap010Level(rawTap010)
if !ok {
return "-1"
}
mappedLow, mappedHigh := expandTap010Range(tap010)
candidateScores := intersectedTierScores(mappedLow, mappedHigh)
if len(candidateScores) == 0 {
return "-1"
}
seed := stableSeedFromIDCard(idCard)
score := candidateScores[seed%len(candidateScores)]
return strconv.Itoa(score)
}
func parseTap010Level(v interface{}) (int, bool) {
switch value := v.(type) {
case string:
value = strings.TrimSpace(value)
if value == "" {
return 0, false
}
n, err := strconv.Atoi(value)
if err != nil {
return 0, false
}
if n < 1 || n > 4 {
return 0, false
}
return n, true
case float64:
n := int(value)
if value != float64(n) || n < 1 || n > 4 {
return 0, false
}
return n, true
default:
return 0, false
}
}
func expandTap010Range(level int) (float64, float64) {
// tap010 原区间:
// 1:(0,500) 2:[500,1000) 3:[1000,3000) 4:[3000,+inf)
// 按比例放大 9 倍映射到收入尺度,满足示例: (0,500)->(0,4500)
switch level {
case 1:
return 0, 4500
case 2:
return 4500, 9000
case 3:
return 9000, 27000
case 4:
return 27000, math.Inf(1)
default:
return 0, 0
}
}
func intersectedTierScores(low, high float64) []int {
scores := make([]int, 0, len(incomeTiers))
for _, t := range incomeTiers {
if isRangeIntersect(low, high, t.Low, t.High) {
scores = append(scores, t.Score)
}
}
return scores
}
func isRangeIntersect(aLow, aHigh, bLow, bHigh float64) bool {
return aLow <= bHigh && bLow <= aHigh
}
func stableSeedFromIDCard(idCard string) int {
if len(idCard) == 0 {
return 0
}
runes := []rune(idCard)
start := len(runes) - 4
if start < 0 {
start = 0
}
seed := 0
for _, r := range runes[start:] {
switch {
case r >= '0' && r <= '9':
seed = seed*11 + int(r-'0')
case r == 'X' || r == 'x':
seed = seed*11 + 10
default:
seed = seed*11 + int(r)%11
}
}
if seed < 0 {
return -seed
}
return seed
}

View File

@@ -47,8 +47,6 @@ func ProcessJRZQO7L1Request(ctx context.Context, params []byte, deps *processors
"city": null, "city": null,
} }
// 使用 WithSkipCode201Check 不跳过 201 错误检查,当 Code == "201" 时返回错误
// ctx = zhicha.WithSkipCode201Check(ctx)
respData, err := deps.ZhichaService.CallAPI(ctx, "ZCI080", reqData) respData, err := deps.ZhichaService.CallAPI(ctx, "ZCI080", reqData)
if err != nil { if err != nil {
if errors.Is(err, zhicha.ErrDatasource) { if errors.Is(err, zhicha.ErrDatasource) {

View File

@@ -4,9 +4,11 @@ import (
"bytes" "bytes"
"crypto/aes" "crypto/aes"
"crypto/cipher" "crypto/cipher"
"crypto/md5"
"encoding/base64" "encoding/base64"
"encoding/hex" "encoding/hex"
"fmt" "fmt"
"io"
) )
const ( const (
@@ -119,3 +121,10 @@ func pkcs7Unpadding(src []byte) ([]byte, error) {
return src[:length-unpadding], nil return src[:length-unpadding], nil
} }
// MD5 使用MD5加密数据返回十六进制字符串
func MD5(data string) string {
h := md5.New()
io.WriteString(h, data)
return hex.EncodeToString(h.Sum(nil))
}

View File

@@ -212,11 +212,12 @@ func (z *ZhichaService) CallAPI(ctx context.Context, proID string, params map[st
// 201 表示查询为空兼容其它情况如果data也为空则返回空对象 // 201 表示查询为空兼容其它情况如果data也为空则返回空对象
if zhichaResp.Code == "201" { if zhichaResp.Code == "201" {
// 先做类型断言
dataMap, ok := zhichaResp.Data.(map[string]interface{}) dataMap, ok := zhichaResp.Data.(map[string]interface{})
if ok && len(dataMap) > 0 { if ok {
// 即使是 {},也原样返回
return dataMap, nil return dataMap, nil
} }
// 兜底:防止解密异常
return map[string]interface{}{}, nil return map[string]interface{}{}, nil
} }
@@ -315,6 +316,12 @@ func (z *ZhichaService) Decrypt(encryptedData string) (string, error) {
return string(unpadded), nil return string(unpadded), nil
} }
// MD5 对字符串进行MD5加密并返回32位小写十六进制字符串
func (z *ZhichaService) MD5(data string) string {
hash := md5.Sum([]byte(data))
return hex.EncodeToString(hash[:])
}
// pkcs7Padding 使用PKCS7填充数据 // pkcs7Padding 使用PKCS7填充数据
func (z *ZhichaService) pkcs7Padding(src []byte, blockSize int) []byte { func (z *ZhichaService) pkcs7Padding(src []byte, blockSize int) []byte {
padding := blockSize - len(src)%blockSize padding := blockSize - len(src)%blockSize