From 6d892643ba4dbcbc47023274c7f71da2a015ecd3 Mon Sep 17 00:00:00 2001 From: Mrx <18278715334@163.com> Date: Tue, 2 Jun 2026 12:26:22 +0800 Subject: [PATCH] f --- .../domains/api/services/processors/1.json | 6 + internal/domains/api/services/processors/1.md | 16 +++ .../domains/api/services/processors/2.json | 14 +++ internal/domains/api/services/processors/2.md | 14 +++ .../processors/ivyz/ivyz8i9j_processor.go | 44 ++++--- .../processors/ivyz/ivyz8i9j_transform.go | 108 ++++++++++++++++++ .../domains/api/services/processors/jrzq/1.md | 20 ---- .../processors/jrzq/jrzq3c9R_processor.go | 51 ++++----- .../processors/jrzq/jrzq3c9R_transform.go | 20 ++++ 9 files changed, 228 insertions(+), 65 deletions(-) create mode 100644 internal/domains/api/services/processors/1.json create mode 100644 internal/domains/api/services/processors/1.md create mode 100644 internal/domains/api/services/processors/2.json create mode 100644 internal/domains/api/services/processors/2.md create mode 100644 internal/domains/api/services/processors/ivyz/ivyz8i9j_transform.go delete mode 100644 internal/domains/api/services/processors/jrzq/1.md create mode 100644 internal/domains/api/services/processors/jrzq/jrzq3c9R_transform.go diff --git a/internal/domains/api/services/processors/1.json b/internal/domains/api/services/processors/1.json new file mode 100644 index 0000000..eeeeabc --- /dev/null +++ b/internal/domains/api/services/processors/1.json @@ -0,0 +1,6 @@ +{ + "result":{ + "score": 87, + "riskCode": "11001-3|21001-2" + } +} \ No newline at end of file diff --git a/internal/domains/api/services/processors/1.md b/internal/domains/api/services/processors/1.md new file mode 100644 index 0000000..38c856a --- /dev/null +++ b/internal/domains/api/services/processors/1.md @@ -0,0 +1,16 @@ +riskCode码result 参数说明 +参数名 类型 说明 +score Number 分数区间 0-100,分数越高表明风险越大 +riskCode 风险码 21001、21002、 +11001、11002、11003、11004、11005、 +12001、12002、 +1 低风险 2 中风险 3 高风险 +21001 疑似恶意借贷 恶意多方借贷、以贷养贷、蓄意制造借贷纠纷等违规行为 +21002 疑似职业撸囗子 职业从事网络贷款撸口子,无还款意愿的恶意行为 +11001 疑似涉黑涉赌 涉嫌参与传销、在线赌博等违法行为 +11002 疑似网络投机 参与在线外汇、虚拟币、石油贵金属等风险投机行为 +11003 疑似营销欺诈 在网络平台运营活动中,组团薅羊毛、套利等违规行为 +11004 疑似黑中介包装 介包装伪造冒用资料、黑产中介圈团成员、老赖反催收等 +11005 疑似恶意套现 信用卡恶意套现、第三方平台消费分期套现等违规行为 +12001 疑似黑产设备 存在模拟器、多开、群控、代理等作弊行为的黑产设备 +12002 疑似黑产账号 疑似黑产组织非法包装的手机号、身份证、支付等账号 diff --git a/internal/domains/api/services/processors/2.json b/internal/domains/api/services/processors/2.json new file mode 100644 index 0000000..2f3b58b --- /dev/null +++ b/internal/domains/api/services/processors/2.json @@ -0,0 +1,14 @@ + + +{ + "sjbq_zlbz": "0", + "sjbq_ychy": "0", + "sjbq_xjzl": "0", + "sjbq_ymd": "0", + "sjbq_sfcy": "0", + "sjbq_ycxw": "0", + "sjbq_sxxw": "0", + "sjbq_zfyc": "0", + "sjbq_qtyc": "0", + "sjbq_swhjyc": "0" +} diff --git a/internal/domains/api/services/processors/2.md b/internal/domains/api/services/processors/2.md new file mode 100644 index 0000000..431f719 --- /dev/null +++ b/internal/domains/api/services/processors/2.md @@ -0,0 +1,14 @@ +## 返回字段说明 + +| 检测项目 | 字段名 | 检测结果 | +|---------|--------|---------| +| 资料包装中介 | sjbq_zlbz | 0:未命中;1:命中;介包装伪造冒用资料、黑产中介圈团成员、老赖反催收等 | +| 异常行业 | sjbq_ychy | 0:未命中;1:命中;涉嫌参与传销、在线赌博等违法行为 | +| 虚假资料 | sjbq_xjzl | 0:未命中;1:命中;疑似黑产组织非法包装的手机号、身份证、支付等账号 | +| 羊毛党 | sjbq_ymd | 0:未命中;1:命中;在网络平台运营活动中,组团薅羊毛、套利等违规行为 | +| 身份信息存疑 | sjbq_sfcy | 0:未命中;1:命中;存在模拟器、多开、群控、代理等作弊行为的黑产设备 | +| 严重异常行为 | sjbq_ycxw | 0:未命中;1:命中;参与在线外汇、虚拟币、石油贵金属等风险投机行为 | +| 失信行为 | sjbq_sxxw | 0:未命中;1:命中;职业从事网络贷款撸口子,无还款意愿的恶意行为 | +| 支付异常行为 | sjbq_zfyc | 0:未命中;1:命中;信用卡恶意套现、第三方平台消费分期套现等违规行为 | +| 其他异常行为 | sjbq_qtyc | 0:未命中;1:命中;恶意多方借贷、以贷养贷、蓄意制造借贷纠纷等违规行为 | +| 上网环境异常 | sjbq_swhjyc | 0:未命中;1:命中;对应风险码 11001、11002、11004、12001、12002 | \ No newline at end of file diff --git a/internal/domains/api/services/processors/ivyz/ivyz8i9j_processor.go b/internal/domains/api/services/processors/ivyz/ivyz8i9j_processor.go index e67a504..ec66a6a 100644 --- a/internal/domains/api/services/processors/ivyz/ivyz8i9j_processor.go +++ b/internal/domains/api/services/processors/ivyz/ivyz8i9j_processor.go @@ -7,7 +7,7 @@ import ( "tyapi-server/internal/domains/api/dto" "tyapi-server/internal/domains/api/services/processors" - "tyapi-server/internal/infrastructure/external/xingwei" + "tyapi-server/internal/infrastructure/external/nuoer" ) // ProcessIVYZ8I9JRequest IVYZ8I9J API处理方法 - 互联网行为推测 @@ -21,27 +21,37 @@ func ProcessIVYZ8I9JRequest(ctx context.Context, params []byte, deps *processors return nil, errors.Join(processors.ErrInvalidParam, err) } - // 构建请求数据,将项目规范的字段名转换为 XingweiService 需要的字段名 - reqData := map[string]interface{}{ - "name": paramsDto.Name, - "idCardNum": paramsDto.IDCard, - "phoneNumber": paramsDto.MobileNo, + body := map[string]string{ + "name": paramsDto.Name, + "idCard": paramsDto.IDCard, + "mobile": paramsDto.MobileNo, } - // 调用行为数据API,使用指定的project_id - projectID := "CDJ-1074522823015198720" - respBytes, err := deps.XingweiService.CallAPI(ctx, projectID, reqData) + nuoerDoCheckAPIKey := "kunyu_fix_v3_tg_model" + ApiPath := "/v1/doCheck" + + resp, err := deps.NuoerService.CallAPI(ctx, nuoerDoCheckAPIKey, ApiPath, body) if err != nil { - if errors.Is(err, xingwei.ErrNotFound) { - return nil, errors.Join(processors.ErrNotFound, err) - } else if errors.Is(err, xingwei.ErrDatasource) { + if errors.Is(err, nuoer.ErrDatasource) { return nil, errors.Join(processors.ErrDatasource, err) - } else if errors.Is(err, xingwei.ErrSystem) { - return nil, errors.Join(processors.ErrSystem, err) - } else { - return nil, errors.Join(processors.ErrSystem, err) } + if errors.Is(err, nuoer.ErrNotFound) { + return nil, errors.Join(processors.ErrNotFound, err) + } + return nil, errors.Join(processors.ErrSystem, err) } - return respBytes, nil + // 将响应数据序列化为 JSON + respBytes, err := json.Marshal(resp.Data) + if err != nil { + return nil, errors.Join(processors.ErrSystem, err) + } + + // 使用 transform 函数转换响应数据 + transformedBytes, err := IVYZ8I9JTransformResponseFromBytes(respBytes) + if err != nil { + return nil, errors.Join(processors.ErrSystem, err) + } + + return transformedBytes, nil } diff --git a/internal/domains/api/services/processors/ivyz/ivyz8i9j_transform.go b/internal/domains/api/services/processors/ivyz/ivyz8i9j_transform.go new file mode 100644 index 0000000..5991cf8 --- /dev/null +++ b/internal/domains/api/services/processors/ivyz/ivyz8i9j_transform.go @@ -0,0 +1,108 @@ +package ivyz + +import ( + "encoding/json" + "strings" + + "github.com/tidwall/gjson" +) + +// RiskCodeMapping 风险码到字段的映射 +// 注意:一个风险码可能映射到多个字段 +var RiskCodeMapping = map[string][]string{ + "11001": {"sjbq_ychy", "sjbq_swhjyc"}, // 疑似涉黑涉诈 → 异常行业、上网环境异常 + "11002": {"sjbq_ycxw", "sjbq_qtyc", "sjbq_swhjyc"}, // 疑似网络投机 → 严重异常行为、其他异常行为、上网环境异常 + "11003": {"sjbq_ymd"}, // 疑似营销欺诈 → 羊毛党 + "11004": {"sjbq_zlbz", "sjbq_swhjyc"}, // 疑似黑中介包装 → 资料包装中介、上网环境异常 + "11005": {"sjbq_zfyc"}, // 疑似恶意套现 → 支付异常行为 + "12001": {"sjbq_sfcy", "sjbq_swhjyc"}, // 疑似黑产设备 → 身份信息存疑、上网环境异常 + "12002": {"sjbq_xjzl", "sjbq_swhjyc"}, // 疑似黑产账号 → 虚假资料、上网环境异常 + "21001": {"sjbq_ycxw"}, // 疑似恶意借贷 → 严重异常行为 + "21002": {"sjbq_sxxw"}, // 疑似职业撸口子 → 失信行为 +} + +// IVYZ8I9JTransformResponseFromBytes 将包含 riskCode 的格式转换为多个布尔字段格式 +func IVYZ8I9JTransformResponseFromBytes(respBytes []byte) ([]byte, error) { + // 获取 result 字段中的 riskCode + riskCodeResult := gjson.GetBytes(respBytes, "result.riskCode") + if !riskCodeResult.Exists() { + // 如果没有 riskCode 字段,返回默认值 + return createDefaultResponse() + } + + riskCode := riskCodeResult.String() + result, err := parseRiskCodeToFields(riskCode) + if err != nil { + return createDefaultResponse() + } + + return json.Marshal(result) +} + +// parseRiskCodeToFields 解析 riskCode 并转换为多个字段 +// riskCode 格式: "11001-3|21001-2" +// 其中 "11001" 是风险码,"3" 是风险等级(1低风险、2中风险、3高风险) +// 只要风险码存在,就认为命中并映射到对应字段 +func parseRiskCodeToFields(riskCode string) (map[string]string, error) { + // 初始化所有字段为 "0" + result := map[string]string{ + "sjbq_zlbz": "0", // 资料包装中介 - 对应 11004 疑似黑中介包装 + "sjbq_ychy": "0", // 异常行业 - 对应 11001 疑似涉黑涉诈 + "sjbq_xjzl": "0", // 虚假资料 - 对应 12002 疑似黑产账号 + "sjbq_ymd": "0", // 羊毛党 - 对应 11003 疑似营销欺诈 + "sjbq_sfcy": "0", // 身份信息存疑 - 对应 12001 疑似黑产设备 + "sjbq_ycxw": "0", // 严重异常行为 - 对应 21001 疑似恶意借贷 + "sjbq_sxxw": "0", // 失信行为 - 对应 21002 疑似职业撸口子 + "sjbq_zfyc": "0", // 支付异常行为 - 对应 11005 疑似恶意套现 + "sjbq_qtyc": "0", // 其他异常行为 - 对应 11002 疑似网络涉赌 + "sjbq_swhjyc": "0", // 上网环境异常 - 对应 11001/11004/11002 涉黑涉诈/黑中介包装/网络涉赌 + } + + if riskCode == "" || riskCode == "-1" { + return result, nil + } + + // 分割多个风险码(用 | 分隔) + riskCodes := strings.Split(riskCode, "|") + for _, rc := range riskCodes { + rc = strings.TrimSpace(rc) + if rc == "" { + continue + } + + // 解析风险码和风险等级(用 - 分隔) + parts := strings.Split(rc, "-") + if len(parts) < 1 { + continue + } + + code := parts[0] + + // 只要风险码存在,就认为命中(不管风险等级是 1、2 还是 3) + // 一个风险码可能映射到多个字段 + if fieldNames, ok := RiskCodeMapping[code]; ok { + for _, fieldName := range fieldNames { + result[fieldName] = "1" + } + } + } + + return result, nil +} + +// createDefaultResponse 创建默认响应(所有字段为 "0") +func createDefaultResponse() ([]byte, error) { + result := map[string]string{ + "sjbq_zlbz": "0", + "sjbq_ychy": "0", + "sjbq_xjzl": "0", + "sjbq_ymd": "0", + "sjbq_sfcy": "0", + "sjbq_ycxw": "0", + "sjbq_sxxw": "0", + "sjbq_zfyc": "0", + "sjbq_qtyc": "0", + "sjbq_swhjyc": "0", + } + return json.Marshal(result) +} diff --git a/internal/domains/api/services/processors/jrzq/1.md b/internal/domains/api/services/processors/jrzq/1.md deleted file mode 100644 index 3b9b432..0000000 --- a/internal/domains/api/services/processors/jrzq/1.md +++ /dev/null @@ -1,20 +0,0 @@ - { - "scoreywbase": "728" -} -{ - "result": { - "score": "40.49" - } -} - - - -{ - "result": { - "score": "50.46" - } -} - -{ - "scoreywbase": "665" -} \ No newline at end of file diff --git a/internal/domains/api/services/processors/jrzq/jrzq3c9R_processor.go b/internal/domains/api/services/processors/jrzq/jrzq3c9R_processor.go index aa141c4..2e7ec8d 100644 --- a/internal/domains/api/services/processors/jrzq/jrzq3c9R_processor.go +++ b/internal/domains/api/services/processors/jrzq/jrzq3c9R_processor.go @@ -7,10 +7,10 @@ import ( "tyapi-server/internal/domains/api/dto" "tyapi-server/internal/domains/api/services/processors" - "tyapi-server/internal/infrastructure/external/zhicha" + "tyapi-server/internal/infrastructure/external/nuoer" ) -// ProcessJRZQ3c9RRequest JRZQ3c9R API处理方法 - 支付行为指数 +// ProcessJRZQ3c9RRequest JRZQ3C9R API处理方法 - 支付行为指数 func ProcessJRZQ3C9RRequest(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) { var paramsDto dto.JRZQ3C9RReq if err := json.Unmarshal(params, ¶msDto); err != nil { @@ -21,42 +21,37 @@ func ProcessJRZQ3C9RRequest(ctx context.Context, params []byte, deps *processors return nil, errors.Join(processors.ErrInvalidParam, err) } - encryptedName, err := deps.ZhichaService.Encrypt(paramsDto.Name) - if err != nil { - return nil, errors.Join(processors.ErrSystem, err) + body := map[string]string{ + "name": paramsDto.Name, + "idCard": paramsDto.IDCard, + "mobile": paramsDto.MobileNo, } - encryptedIDCard, err := deps.ZhichaService.Encrypt(paramsDto.IDCard) - if err != nil { - return nil, errors.Join(processors.ErrSystem, err) - } + nuoerDoCheckAPIKey := "paymentTagS26" + ApiPath := "/v1/doCheck" - encryptedMobileNo, err := deps.ZhichaService.Encrypt(paramsDto.MobileNo) + resp, err := deps.NuoerService.CallAPI(ctx, nuoerDoCheckAPIKey, ApiPath, body) if err != nil { - return nil, errors.Join(processors.ErrSystem, err) - } - - reqData := map[string]interface{}{ - "name": encryptedName, - "idCard": encryptedIDCard, - "phone": encryptedMobileNo, - "authorized": paramsDto.Authorized, - } - - respData, err := deps.ZhichaService.CallAPI(ctx, "ZCI036", reqData) - if err != nil { - if errors.Is(err, zhicha.ErrDatasource) { + if errors.Is(err, nuoer.ErrDatasource) { return nil, errors.Join(processors.ErrDatasource, err) - } else { - return nil, errors.Join(processors.ErrSystem, err) } + if errors.Is(err, nuoer.ErrNotFound) { + return nil, errors.Join(processors.ErrNotFound, err) + } + return nil, errors.Join(processors.ErrSystem, err) } - // 将响应数据转换为JSON字节 - respBytes, err := json.Marshal(respData) + // 将响应数据序列化为 JSON + respBytes, err := json.Marshal(resp.Data) if err != nil { return nil, errors.Join(processors.ErrSystem, err) } - return respBytes, nil + // 使用 transform 函数转换响应数据,展开 result 字段 + transformedBytes, err := JRZQ3C9RTransformResponseFromBytes(respBytes) + if err != nil { + return nil, errors.Join(processors.ErrSystem, err) + } + + return transformedBytes, nil } diff --git a/internal/domains/api/services/processors/jrzq/jrzq3c9R_transform.go b/internal/domains/api/services/processors/jrzq/jrzq3c9R_transform.go new file mode 100644 index 0000000..b468a82 --- /dev/null +++ b/internal/domains/api/services/processors/jrzq/jrzq3c9R_transform.go @@ -0,0 +1,20 @@ +package jrzq + +import ( + "github.com/tidwall/gjson" +) + +// JRZQ3C9RTransformResponseFromBytes 从字节数组转换响应数据,将 result 字段展开到根级别 +// respBytes: 原始响应数据的字节数组 +// Returns: 转换后的数据字节数组 +func JRZQ3C9RTransformResponseFromBytes(respBytes []byte) ([]byte, error) { + // 使用 gjson 获取 result 字段 + resultResult := gjson.GetBytes(respBytes, "result") + if !resultResult.Exists() { + // 如果没有 result 字段,直接返回原始数据 + return respBytes, nil + } + + // 返回 result 字段的原始 JSON + return []byte(resultResult.Raw), nil +}