ff
This commit is contained in:
@@ -1019,6 +1019,10 @@ type QYGL5F6AReq struct {
|
||||
IDCard string `json:"id_card" validate:"required,validIDCard"`
|
||||
}
|
||||
|
||||
type QYGLVR76Req struct {
|
||||
IDCard string `json:"id_card" validate:"required,validIDCard"`
|
||||
}
|
||||
|
||||
type IVYZ6G7HReq struct {
|
||||
Name string `json:"name" validate:"required,min=1,validName"`
|
||||
IDCard string `json:"id_card" validate:"required,validIDCard"`
|
||||
|
||||
@@ -384,6 +384,7 @@ func registerAllProcessors(combService *comb.CombService) {
|
||||
"QCXGY7F2": qcxg.ProcessQCXGY7F2Request, // 二手车VIN估值 10443
|
||||
"QCXG3M7Z": qcxg.ProcessQCXG3M7ZRequest, //人车关系核验(ETC)10093 月更
|
||||
"QCXGM4CL": qcxg.ProcessQCXGM4CLRequest, //名下车辆诺尔
|
||||
"QYGLVR76": qygl.ProcessQYGLVR76Request, //名下企业诺尔
|
||||
// DWBG系列处理器 - 多维报告
|
||||
"DWBG6A2C": dwbg.ProcessDWBG6A2CRequest,
|
||||
"DWBG8B4D": dwbg.ProcessDWBG8B4DRequest,
|
||||
|
||||
@@ -288,6 +288,7 @@ func (s *FormConfigServiceImpl) getDTOStruct(ctx context.Context, apiCode string
|
||||
"QYGL2YSB": &dto.QYGL2YSBReq{}, //企业二要素认证shumai
|
||||
"QYGLDG77": &dto.QYGLDG77Req{}, //企业对公打款认证shumai
|
||||
"QCXGM4CL": &dto.QCXGM4CLReq{}, //名下车辆诺尔
|
||||
"QYGLVR76": &dto.QYGLVR76Req{}, //名下企业诺尔
|
||||
}
|
||||
|
||||
// 优先返回已配置的DTO
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,17 +0,0 @@
|
||||
## 响应示例
|
||||
|
||||
### 成功响应
|
||||
|
||||
```json
|
||||
{
|
||||
"currently_overdue": "2",
|
||||
"max_overdue_amt": "1-1000",
|
||||
"acc_sleep": "14",
|
||||
"currently_performance": "12",
|
||||
"result_code": "1",
|
||||
"max_overdue_days": "16-30",
|
||||
"latest_overdue_time": "2023-05",
|
||||
"acc_exc": "0"
|
||||
|
||||
}
|
||||
```
|
||||
@@ -1,19 +0,0 @@
|
||||
|
||||
# result 参数说明
|
||||
| 参数名 | 类型 | 说明 |
|
||||
| ---- | ---- | ---- |
|
||||
| score | Number | 分数区间 0-100,分数越高表明风险越大 |
|
||||
| riskCode | String | 风险码,可选值:21001、21002、11001、11002、11003、11004、11005、12001、12002<br>风险等级:1 低风险、2 中风险、3 高风险 |
|
||||
|
||||
# riskCode风险标签编码说明
|
||||
| 编码 | 标签名称 | 描述说明 |
|
||||
| ---- | ---- | ---- |
|
||||
| 21001 | 疑似恶意借贷 | 恶意多方借贷、以贷养贷、蓄意制造借贷纠纷等违规行为 |
|
||||
| 21002 | 疑似职业撸口子 | 职业从事网络贷款撸口子,无还款意愿的恶意行为 |
|
||||
| 11001 | 疑似涉黑涉赌 | 涉嫌参与传销、在线赌博等违法行为 |
|
||||
| 11002 | 疑似网络投机 | 参与在线外汇、虚拟币、石油贵金属等风险投机行为 |
|
||||
| 11003 | 疑似营销欺诈 | 在网络平台运营活动中,组团薅羊毛、套利等违规行为 |
|
||||
| 11004 | 疑似黑中介包装 | 中介包装伪造冒用资料、黑产中介圈团成员、老赖反催收等 |
|
||||
| 11005 | 疑似恶意套现 | 信用卡恶意套现、第三方平台消费分期套现等违规行为 |
|
||||
| 12001 | 疑似黑产设备 | 存在模拟器、多开、群控、代理等作弊行为的黑产设备 |
|
||||
| 12002 | 疑似黑产账号 | 疑似黑产组织非法包装的手机号、身份证、支付等账号 |
|
||||
@@ -1,14 +0,0 @@
|
||||
{
|
||||
"result": {
|
||||
"acc_exc": "0",
|
||||
"acc_sleep": "14",
|
||||
"result_code": "1",
|
||||
"max_overdue_amt": "1-1000",
|
||||
"max_overdue_days": "16-30",
|
||||
"currently_overdue": "2",
|
||||
"latest_overdue_time": "2023-05",
|
||||
"currently_performance": "12"
|
||||
},
|
||||
"busiMsg": "success",
|
||||
"busiCode": 10
|
||||
}
|
||||
@@ -4,13 +4,10 @@ import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"math"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"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"
|
||||
)
|
||||
|
||||
// ProcessJRZQ8B3CRequest JRZQ8B3C API处理方法 - 个人消费能力等级
|
||||
@@ -24,173 +21,37 @@ func ProcessJRZQ8B3CRequest(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 := "consumerTagV1"
|
||||
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": "1",
|
||||
}
|
||||
|
||||
respData, err := deps.ZhichaService.CallAPI(ctx, "ZCI034", reqData)
|
||||
if err != nil {
|
||||
if errors.Is(err, zhicha.ErrDatasource) {
|
||||
if errors.Is(err, nuoer.ErrDatasource) {
|
||||
return nil, errors.Join(processors.ErrDatasource, err)
|
||||
} else {
|
||||
}
|
||||
if errors.Is(err, nuoer.ErrNotFound) {
|
||||
return nil, errors.Join(processors.ErrNotFound, err)
|
||||
}
|
||||
return nil, errors.Join(processors.ErrSystem, err)
|
||||
}
|
||||
|
||||
rawData, ok := resp.Data.(map[string]interface{})
|
||||
if !ok {
|
||||
return nil, errors.Join(processors.ErrSystem, errors.New("响应格式错误"))
|
||||
}
|
||||
|
||||
personIncomeIndex := "-1"
|
||||
if m, ok := respData.(map[string]interface{}); ok {
|
||||
personIncomeIndex = mapTap010ToIncomeIndex(m["tap010"], paramsDto.IDCard)
|
||||
}
|
||||
result := mapNuoerConsumerTagToResponse(rawData)
|
||||
|
||||
respPayload := map[string]interface{}{
|
||||
"personincome_index_2.0": personIncomeIndex,
|
||||
}
|
||||
|
||||
respBytes, err := json.Marshal(respPayload)
|
||||
respBytes, err := json.Marshal(result)
|
||||
if err != nil {
|
||||
return nil, errors.Join(processors.ErrSystem, err)
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
@@ -0,0 +1,104 @@
|
||||
package jrzq
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
)
|
||||
|
||||
type consumerTagScoreInterval struct {
|
||||
min float64
|
||||
max float64
|
||||
minInclusive bool
|
||||
maxInclusive bool
|
||||
output string
|
||||
}
|
||||
|
||||
// nuoer score 取值范围 350-850,按 50 分一档映射为 10 档 personincome_index_2.0(100-1000)。
|
||||
var consumerTagScoreIntervals = []consumerTagScoreInterval{
|
||||
{min: 350, max: 400, minInclusive: true, maxInclusive: false, output: "100"},
|
||||
{min: 400, max: 450, minInclusive: true, maxInclusive: false, output: "200"},
|
||||
{min: 450, max: 500, minInclusive: true, maxInclusive: false, output: "300"},
|
||||
{min: 500, max: 550, minInclusive: true, maxInclusive: false, output: "400"},
|
||||
{min: 550, max: 600, minInclusive: true, maxInclusive: false, output: "500"},
|
||||
{min: 600, max: 650, minInclusive: true, maxInclusive: false, output: "600"},
|
||||
{min: 650, max: 700, minInclusive: true, maxInclusive: false, output: "700"},
|
||||
{min: 700, max: 750, minInclusive: true, maxInclusive: false, output: "800"},
|
||||
{min: 750, max: 800, minInclusive: true, maxInclusive: false, output: "900"},
|
||||
{min: 800, max: 850, minInclusive: true, maxInclusive: true, output: "1000"},
|
||||
}
|
||||
|
||||
// mapNuoerConsumerTagToResponse 将 nuoer data(2json.md)转为 JRZQ8B3C 对外结构(1json.md)。
|
||||
func mapNuoerConsumerTagToResponse(data map[string]interface{}) map[string]interface{} {
|
||||
score, ok := extractConsumerTagScore(data)
|
||||
return map[string]interface{}{
|
||||
"personincome_index_2.0": mapConsumerTagScoreToIncomeIndex(score, ok),
|
||||
}
|
||||
}
|
||||
|
||||
func extractConsumerTagScore(data map[string]interface{}) (float64, bool) {
|
||||
if data == nil {
|
||||
return 0, false
|
||||
}
|
||||
payload := data
|
||||
if result, ok := data["result"].(map[string]interface{}); ok {
|
||||
payload = result
|
||||
}
|
||||
return parseConsumerTagScore(payload["score"])
|
||||
}
|
||||
|
||||
func parseConsumerTagScore(v interface{}) (float64, bool) {
|
||||
if v == nil {
|
||||
return 0, false
|
||||
}
|
||||
switch val := v.(type) {
|
||||
case float64:
|
||||
return val, true
|
||||
case int:
|
||||
return float64(val), true
|
||||
case int64:
|
||||
return float64(val), true
|
||||
case string:
|
||||
if val == "" {
|
||||
return 0, false
|
||||
}
|
||||
f, err := strconv.ParseFloat(val, 64)
|
||||
if err != nil {
|
||||
return 0, false
|
||||
}
|
||||
return f, true
|
||||
default:
|
||||
return 0, false
|
||||
}
|
||||
}
|
||||
|
||||
func mapConsumerTagScoreToIncomeIndex(score float64, ok bool) string {
|
||||
if !ok {
|
||||
return "-1"
|
||||
}
|
||||
if score < 350 {
|
||||
return "-1"
|
||||
}
|
||||
if score > 850 {
|
||||
return "1000"
|
||||
}
|
||||
for _, rule := range consumerTagScoreIntervals {
|
||||
if consumerTagScoreInInterval(score, rule) {
|
||||
return rule.output
|
||||
}
|
||||
}
|
||||
return "-1"
|
||||
}
|
||||
|
||||
func consumerTagScoreInInterval(score float64, rule consumerTagScoreInterval) bool {
|
||||
if rule.minInclusive {
|
||||
if score < rule.min {
|
||||
return false
|
||||
}
|
||||
} else if score <= rule.min {
|
||||
return false
|
||||
}
|
||||
|
||||
if rule.maxInclusive {
|
||||
return score <= rule.max
|
||||
}
|
||||
return score < rule.max
|
||||
}
|
||||
@@ -4,11 +4,10 @@ import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"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"
|
||||
)
|
||||
|
||||
// ProcessQYGL5F6ARequest QYGL5F6A API处理方法 - 企业相关查询
|
||||
@@ -21,27 +20,34 @@ func ProcessQYGL5F6ARequest(ctx context.Context, params []byte, deps *processors
|
||||
if err := deps.Validator.ValidateStruct(paramsDto); err != nil {
|
||||
return nil, errors.Join(processors.ErrInvalidParam, err)
|
||||
}
|
||||
fmt.Println("paramsDto", paramsDto)
|
||||
|
||||
// 构建请求数据,将项目规范的字段名转换为 XingweiService 需要的字段名
|
||||
reqData := map[string]interface{}{
|
||||
"idCardNum": paramsDto.IDCard,
|
||||
body := map[string]string{
|
||||
"idCard": paramsDto.IDCard,
|
||||
}
|
||||
|
||||
// 调用行为数据API,使用指定的project_id
|
||||
projectID := "CDJ-1101695397213958144"
|
||||
fmt.Println("reqData", reqData)
|
||||
respBytes, err := deps.XingweiService.CallAPI(ctx, projectID, reqData)
|
||||
nuoerDoCheckAPIKey := "idRelationV101"
|
||||
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 {
|
||||
}
|
||||
if errors.Is(err, nuoer.ErrNotFound) {
|
||||
return nil, errors.Join(processors.ErrNotFound, err)
|
||||
}
|
||||
return nil, errors.Join(processors.ErrSystem, err)
|
||||
}
|
||||
|
||||
rawData, ok := resp.Data.(map[string]interface{})
|
||||
if !ok {
|
||||
return nil, errors.Join(processors.ErrSystem, errors.New("响应格式错误"))
|
||||
}
|
||||
|
||||
result := mapNuoerIdRelationToEntReportResponse(rawData)
|
||||
|
||||
respBytes, err := json.Marshal(result)
|
||||
if err != nil {
|
||||
return nil, errors.Join(processors.ErrSystem, err)
|
||||
}
|
||||
|
||||
return respBytes, nil
|
||||
|
||||
@@ -0,0 +1,95 @@
|
||||
package qygl
|
||||
|
||||
var qygl5f6aBasicInfoFields = []string{
|
||||
"regStatus", "estiblishTime", "regCapital", "industry", "staffList", "type",
|
||||
"regCapitalCurrency", "legalPersonName", "regNumber", "creditCode", "name",
|
||||
"companyOrgType", "base",
|
||||
}
|
||||
|
||||
// mapNuoerIdRelationToEntReportResponse 将 nuoer data(2json.md)转为 QYGL5F6A 对外结构(1json.md):
|
||||
// 解包 result,映射 datalist 项,并包装为 ent_report_001.queryResult.items。
|
||||
func mapNuoerIdRelationToEntReportResponse(data map[string]interface{}) map[string]interface{} {
|
||||
items := make([]interface{}, 0)
|
||||
if data != nil {
|
||||
payload := unwrapNuoerIdRelationData(data)
|
||||
rawList := asSlice(payload["datalist"])
|
||||
items = make([]interface{}, 0, len(rawList))
|
||||
for _, item := range rawList {
|
||||
if mapped := mapQygl5f6aItem(asMap(item)); mapped != nil {
|
||||
items = append(items, mapped)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return map[string]interface{}{
|
||||
"ent_report_001": map[string]interface{}{
|
||||
"queryResult": map[string]interface{}{
|
||||
"items": items,
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func mapQygl5f6aItem(item map[string]interface{}) map[string]interface{} {
|
||||
if len(item) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
out := make(map[string]interface{}, 8)
|
||||
for _, key := range []string{"orgName", "pName", "relationship"} {
|
||||
if val, ok := item[key]; ok && val != nil {
|
||||
out[key] = val
|
||||
}
|
||||
}
|
||||
|
||||
if basicInfo := mapQygl5f6aBasicInfo(asMap(item["basicInfo"])); isNonemptyMap(basicInfo) {
|
||||
out["basicInfo"] = basicInfo
|
||||
}
|
||||
stockHolder := pickFields(asMap(item["stockHolderItem"]), qygl6f2dStockHolderFields)
|
||||
if !isNonemptyMap(stockHolder) {
|
||||
stockHolder = pickFields(asMap(item["his_stockHolderItem"]), qygl6f2dStockHolderFields)
|
||||
}
|
||||
if isNonemptyMap(stockHolder) {
|
||||
out["stockHolderItem"] = stockHolder
|
||||
}
|
||||
if adminPenalty := mapNuoerIdRelationRecords(item["adminPenalty"], qygl6f2dAdminPenaltyFields); len(adminPenalty) > 0 {
|
||||
out["adminPenalty"] = adminPenalty
|
||||
}
|
||||
if executedPerson := mapNuoerIdRelationRecords(item["executedPerson"], qygl6f2dExecutedPersonFields); len(executedPerson) > 0 {
|
||||
out["executedPerson"] = executedPerson
|
||||
}
|
||||
if dishonestExecutedPerson := mapNuoerIdRelationRecords(item["dishonestExecutedPerson"], qygl6f2dDishonestExecutedPersonFields); len(dishonestExecutedPerson) > 0 {
|
||||
out["dishonestExecutedPerson"] = dishonestExecutedPerson
|
||||
}
|
||||
|
||||
return out
|
||||
}
|
||||
|
||||
func mapQygl5f6aBasicInfo(src map[string]interface{}) map[string]interface{} {
|
||||
if len(src) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
basicInfo := pickFields(src, qygl5f6aBasicInfoFields)
|
||||
if staffList, ok := basicInfo["staffList"]; !ok || isEmptyValue(staffList) {
|
||||
if hisStaffList := src["his_staffList"]; !isEmptyValue(hisStaffList) {
|
||||
basicInfo["staffList"] = hisStaffList
|
||||
} else {
|
||||
delete(basicInfo, "staffList")
|
||||
}
|
||||
}
|
||||
return basicInfo
|
||||
}
|
||||
|
||||
func isEmptyValue(v interface{}) bool {
|
||||
if v == nil {
|
||||
return true
|
||||
}
|
||||
if m, ok := v.(map[string]interface{}); ok {
|
||||
return len(m) == 0
|
||||
}
|
||||
if s, ok := v.([]interface{}); ok {
|
||||
return len(s) == 0
|
||||
}
|
||||
return false
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
package qygl
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
|
||||
"tyapi-server/internal/domains/api/dto"
|
||||
"tyapi-server/internal/domains/api/services/processors"
|
||||
"tyapi-server/internal/infrastructure/external/nuoer"
|
||||
)
|
||||
|
||||
// ProcessQYGLVR76Request QYGLVR76 API处理方法 -人企关联诺尔
|
||||
func ProcessQYGLVR76Request(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) {
|
||||
var paramsDto dto.QYGLVR76Req
|
||||
if err := json.Unmarshal(params, ¶msDto); err != nil {
|
||||
return nil, errors.Join(processors.ErrSystem, err)
|
||||
}
|
||||
|
||||
if err := deps.Validator.ValidateStruct(paramsDto); err != nil {
|
||||
return nil, errors.Join(processors.ErrInvalidParam, err)
|
||||
}
|
||||
|
||||
body := map[string]string{
|
||||
"idCard": paramsDto.IDCard,
|
||||
}
|
||||
|
||||
nuoerDoCheckAPIKey := "idRelationV101"
|
||||
ApiPath := "/v1/doCheck"
|
||||
|
||||
resp, err := deps.NuoerService.CallAPI(ctx, nuoerDoCheckAPIKey, ApiPath, body)
|
||||
if err != nil {
|
||||
if errors.Is(err, nuoer.ErrDatasource) {
|
||||
return nil, errors.Join(processors.ErrDatasource, err)
|
||||
}
|
||||
if errors.Is(err, nuoer.ErrNotFound) {
|
||||
return nil, errors.Join(processors.ErrNotFound, err)
|
||||
}
|
||||
return nil, errors.Join(processors.ErrSystem, err)
|
||||
}
|
||||
|
||||
respBytes, err := json.Marshal(resp.Data)
|
||||
if err != nil {
|
||||
return nil, errors.Join(processors.ErrSystem, err)
|
||||
}
|
||||
|
||||
return respBytes, nil
|
||||
}
|
||||
Reference in New Issue
Block a user