f
This commit is contained in:
@@ -335,7 +335,7 @@ func (s *ApiApplicationServiceImpl) validateApiCall(ctx context.Context, cmd *co
|
|||||||
parentApiUser, err := s.apiUserService.LoadApiUserByUserId(ctx, link.ParentUserID)
|
parentApiUser, err := s.apiUserService.LoadApiUserByUserId(ctx, link.ParentUserID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
s.logger.Error("加载主账号API用户失败",
|
s.logger.Error("加载主账号API用户失败",
|
||||||
zap.String("child_user_id", apiUser.UserId),
|
zap.String("child_user_id", apiUser.UserId),hjk,mgumygi,b
|
||||||
zap.String("parent_user_id", link.ParentUserID),
|
zap.String("parent_user_id", link.ParentUserID),
|
||||||
zap.Error(err))
|
zap.Error(err))
|
||||||
return nil, ErrSystem
|
return nil, ErrSystem
|
||||||
|
|||||||
@@ -187,6 +187,9 @@ type YYSYXF7JReq struct {
|
|||||||
type QCXGA8V3Req struct {
|
type QCXGA8V3Req struct {
|
||||||
VinCode string `json:"vin_code" validate:"required"`
|
VinCode string `json:"vin_code" validate:"required"`
|
||||||
}
|
}
|
||||||
|
type QCXGCP77Req struct {
|
||||||
|
VinCode string `json:"vin_code" validate:"required"`
|
||||||
|
}
|
||||||
|
|
||||||
type YYSYP72DReq struct {
|
type YYSYP72DReq struct {
|
||||||
MobileNo string `json:"mobile_no" validate:"required,min=11,max=11,validMobileNo"`
|
MobileNo string `json:"mobile_no" validate:"required,min=11,max=11,validMobileNo"`
|
||||||
|
|||||||
@@ -414,6 +414,7 @@ func registerAllProcessors(combService *comb.CombService) {
|
|||||||
"QYGLVR76": qygl.ProcessQYGLVR76Request, //名下企业诺尔
|
"QYGLVR76": qygl.ProcessQYGLVR76Request, //名下企业诺尔
|
||||||
"QCXG1S2L": qcxg.ProcessQCXG1S2LRequest, //车辆车五项信息核验V2
|
"QCXG1S2L": qcxg.ProcessQCXG1S2LRequest, //车辆车五项信息核验V2
|
||||||
"QCXGA8V3": qcxg.ProcessQCXGA8V3Request, //全国车辆配置查验(车五项+使用性质+承保)
|
"QCXGA8V3": qcxg.ProcessQCXGA8V3Request, //全国车辆配置查验(车五项+使用性质+承保)
|
||||||
|
"QCXGCP77": qcxg.ProcessQCXGCP77Request, //全国车辆配置查验(车辆详情)
|
||||||
"QCXG6U5G": qcxg.ProcessQCXG6U5GRequest, //名下车辆核验
|
"QCXG6U5G": qcxg.ProcessQCXG6U5GRequest, //名下车辆核验
|
||||||
// DWBG系列处理器 - 多维报告
|
// DWBG系列处理器 - 多维报告
|
||||||
"DWBG6A2C": dwbg.ProcessDWBG6A2CRequest,
|
"DWBG6A2C": dwbg.ProcessDWBG6A2CRequest,
|
||||||
|
|||||||
@@ -338,6 +338,7 @@ func (s *FormConfigServiceImpl) getDTOStruct(ctx context.Context, apiCode string
|
|||||||
"YYSYXF7J": &dto.YYSYXF7JReq{}, //手机消费区间验证
|
"YYSYXF7J": &dto.YYSYXF7JReq{}, //手机消费区间验证
|
||||||
"QCXG1S2L": &dto.QCXG1S2LReq{}, //车辆车五项信息核验V2
|
"QCXG1S2L": &dto.QCXG1S2LReq{}, //车辆车五项信息核验V2
|
||||||
"QCXGA8V3": &dto.QCXGA8V3Req{}, //全国车辆配置查验(车五项+使用性质+承保)
|
"QCXGA8V3": &dto.QCXGA8V3Req{}, //全国车辆配置查验(车五项+使用性质+承保)
|
||||||
|
"QCXGCP77": &dto.QCXGCP77Req{}, //全国车辆配置查验(车辆详情)
|
||||||
"JRZQ5T8S": &dto.JRZQ5T8SReq{}, //借贷意向验证V22
|
"JRZQ5T8S": &dto.JRZQ5T8SReq{}, //借贷意向验证V22
|
||||||
"JRZQT57Z": &dto.JRZQT57ZReq{}, //团伙欺诈风险识别
|
"JRZQT57Z": &dto.JRZQT57ZReq{}, //团伙欺诈风险识别
|
||||||
"IVYZX7J9": &dto.IVYZX7J9Req{}, //学历核验政务
|
"IVYZX7J9": &dto.IVYZX7J9Req{}, //学历核验政务
|
||||||
|
|||||||
@@ -40,10 +40,9 @@ func ProcessIVYZ5E3FRequest(ctx context.Context, params []byte, deps *processors
|
|||||||
respData, err := deps.ZhichaService.CallAPI(ctx, "ZCI029", reqData)
|
respData, err := deps.ZhichaService.CallAPI(ctx, "ZCI029", reqData)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if errors.Is(err, zhicha.ErrDatasource) {
|
if errors.Is(err, zhicha.ErrDatasource) {
|
||||||
return nil, errors.Join(processors.ErrDatasource, err)
|
return fallback5E3FViaHy87(ctx, deps, paramsDto.Name, paramsDto.IDCard)
|
||||||
} else {
|
|
||||||
return nil, errors.Join(processors.ErrSystem, err)
|
|
||||||
}
|
}
|
||||||
|
return nil, errors.Join(processors.ErrSystem, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 将响应数据转换为JSON字节
|
// 将响应数据转换为JSON字节
|
||||||
|
|||||||
@@ -40,57 +40,24 @@ func ProcessIVYZ81NCRequest(ctx context.Context, params []byte, deps *processors
|
|||||||
respData, err := deps.ZhichaService.CallAPI(ctx, "ZCI029", reqData)
|
respData, err := deps.ZhichaService.CallAPI(ctx, "ZCI029", reqData)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if errors.Is(err, zhicha.ErrDatasource) {
|
if errors.Is(err, zhicha.ErrDatasource) {
|
||||||
return nil, errors.Join(processors.ErrDatasource, err)
|
return fallback81NCViaHy87(ctx, deps, paramsDto.Name, paramsDto.IDCard)
|
||||||
} else {
|
}
|
||||||
return nil, errors.Join(processors.ErrSystem, err)
|
return nil, errors.Join(processors.ErrSystem, err)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// 解析响应数据,期望格式为 {"state": "1"}
|
|
||||||
var stateResp struct {
|
var stateResp struct {
|
||||||
State string `json:"state"`
|
State string `json:"state"`
|
||||||
RegTime string `json:"regTime"`
|
RegTime string `json:"regTime"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// 将 respData 转换为 JSON 字节再解析
|
|
||||||
respDataBytes, err := json.Marshal(respData)
|
respDataBytes, err := json.Marshal(respData)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Join(processors.ErrSystem, err)
|
return nil, errors.Join(processors.ErrSystem, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := json.Unmarshal(respDataBytes, &stateResp); err != nil {
|
if err := json.Unmarshal(respDataBytes, &stateResp); err != nil {
|
||||||
return nil, errors.Join(processors.ErrSystem, err)
|
return nil, errors.Join(processors.ErrSystem, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 根据 state 值转换为 81nc 格式
|
opType, opTypeDesc := zhichaStateTo81NCOp(stateResp.State)
|
||||||
var opType, opTypeDesc string
|
return json.Marshal(build81NCResponse(stateResp.RegTime, opType, opTypeDesc))
|
||||||
switch stateResp.State {
|
|
||||||
case "1": // 已婚
|
|
||||||
opType = "IA"
|
|
||||||
opTypeDesc = "结婚"
|
|
||||||
case "2": // 未婚/未在民政局登记
|
|
||||||
opType = "INR"
|
|
||||||
opTypeDesc = "匹配不成功"
|
|
||||||
case "3": // 离异
|
|
||||||
opType = "IB"
|
|
||||||
opTypeDesc = "离婚"
|
|
||||||
default:
|
|
||||||
opType = "INR"
|
|
||||||
opTypeDesc = "匹配不成功"
|
|
||||||
}
|
|
||||||
|
|
||||||
// 构建 81nc 格式响应
|
|
||||||
result := map[string]interface{}{
|
|
||||||
"code": "0",
|
|
||||||
"data": map[string]interface{}{
|
|
||||||
"op_date": stateResp.RegTime,
|
|
||||||
"op_type": opType,
|
|
||||||
"op_type_desc": opTypeDesc,
|
|
||||||
},
|
|
||||||
"message": "成功",
|
|
||||||
"seqNo": "",
|
|
||||||
}
|
|
||||||
|
|
||||||
// 返回 81nc 格式响应
|
|
||||||
return json.Marshal(result)
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,148 @@
|
|||||||
|
package ivyz
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
|
|
||||||
|
"tyapi-server/internal/domains/api/services/processors"
|
||||||
|
"tyapi-server/internal/infrastructure/external/nuoer"
|
||||||
|
)
|
||||||
|
|
||||||
|
const hy87MarriageAPIKey = "qualificateMarry"
|
||||||
|
const hy87MarriageAPIPath = "/v1/doCheck"
|
||||||
|
|
||||||
|
// queryHy87MarriageStatus 调用 IVYZHY87 同源诺尔婚姻状态接口。
|
||||||
|
// status: 0=未婚, 1=已婚, 2=离异, 3=婚姻冷静期
|
||||||
|
func queryHy87MarriageStatus(ctx context.Context, deps *processors.ProcessorDependencies, name, idCard string) (int, error) {
|
||||||
|
if deps.NuoerService == nil {
|
||||||
|
return 0, errors.Join(processors.ErrSystem, errors.New("诺尔服务未初始化"))
|
||||||
|
}
|
||||||
|
|
||||||
|
body := map[string]string{
|
||||||
|
"idCard": idCard,
|
||||||
|
"name": name,
|
||||||
|
}
|
||||||
|
|
||||||
|
resp, err := deps.NuoerService.CallAPI(ctx, hy87MarriageAPIKey, hy87MarriageAPIPath, body)
|
||||||
|
if err != nil {
|
||||||
|
if errors.Is(err, nuoer.ErrNotFound) {
|
||||||
|
return 0, errors.Join(processors.ErrNotFound, err)
|
||||||
|
}
|
||||||
|
if errors.Is(err, nuoer.ErrDatasource) {
|
||||||
|
return 0, errors.Join(processors.ErrDatasource, err)
|
||||||
|
}
|
||||||
|
return 0, errors.Join(processors.ErrSystem, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return parseHy87MarriageStatus(resp.Data)
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseHy87MarriageStatus(data interface{}) (int, error) {
|
||||||
|
dataBytes, err := json.Marshal(data)
|
||||||
|
if err != nil {
|
||||||
|
return 0, errors.Join(processors.ErrSystem, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
var parsed struct {
|
||||||
|
Result struct {
|
||||||
|
Status int `json:"status"`
|
||||||
|
} `json:"result"`
|
||||||
|
}
|
||||||
|
if err := json.Unmarshal(dataBytes, &parsed); err != nil {
|
||||||
|
return 0, errors.Join(processors.ErrSystem, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return parsed.Result.Status, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// hy87StatusTo5E3FState 将 HY87 婚姻状态映射为 5E3F 的 state 字段。
|
||||||
|
// 5E3F: 1=已婚, 2=未婚/未在民政局登记, 3=离异
|
||||||
|
func hy87StatusTo5E3FState(status int) string {
|
||||||
|
switch status {
|
||||||
|
case 1:
|
||||||
|
return "1"
|
||||||
|
case 2:
|
||||||
|
return "3"
|
||||||
|
case 3:
|
||||||
|
return "1"
|
||||||
|
default:
|
||||||
|
return "2"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func build5E3FResponseFromHy87(status int) map[string]string {
|
||||||
|
return map[string]string{
|
||||||
|
"state": hy87StatusTo5E3FState(status),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func zhichaStateTo81NCOp(state string) (opType, opTypeDesc string) {
|
||||||
|
switch state {
|
||||||
|
case "1":
|
||||||
|
return "IA", "结婚"
|
||||||
|
case "2":
|
||||||
|
return "INR", "匹配不成功"
|
||||||
|
case "3":
|
||||||
|
return "IB", "离婚"
|
||||||
|
default:
|
||||||
|
return "INR", "匹配不成功"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func hy87StatusTo81NCOp(status int) (opType, opTypeDesc string) {
|
||||||
|
switch status {
|
||||||
|
case 1:
|
||||||
|
return "IA", "结婚"
|
||||||
|
case 2:
|
||||||
|
return "IB", "离婚"
|
||||||
|
case 3:
|
||||||
|
return "IA", "结婚"
|
||||||
|
default:
|
||||||
|
return "INR", "匹配不成功"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func build81NCResponse(opDate, opType, opTypeDesc string) map[string]interface{} {
|
||||||
|
return map[string]interface{}{
|
||||||
|
"code": "0",
|
||||||
|
"data": map[string]interface{}{
|
||||||
|
"op_date": opDate,
|
||||||
|
"op_type": opType,
|
||||||
|
"op_type_desc": opTypeDesc,
|
||||||
|
},
|
||||||
|
"message": "成功",
|
||||||
|
"seqNo": "",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func build81NCResponseFromHy87(status int) map[string]interface{} {
|
||||||
|
opType, opTypeDesc := hy87StatusTo81NCOp(status)
|
||||||
|
return build81NCResponse("", opType, opTypeDesc)
|
||||||
|
}
|
||||||
|
|
||||||
|
func fallback5E3FViaHy87(ctx context.Context, deps *processors.ProcessorDependencies, name, idCard string) ([]byte, error) {
|
||||||
|
status, err := queryHy87MarriageStatus(ctx, deps, name, idCard)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
respBytes, err := json.Marshal(build5E3FResponseFromHy87(status))
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Join(processors.ErrSystem, err)
|
||||||
|
}
|
||||||
|
return respBytes, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func fallback81NCViaHy87(ctx context.Context, deps *processors.ProcessorDependencies, name, idCard string) ([]byte, error) {
|
||||||
|
status, err := queryHy87MarriageStatus(ctx, deps, name, idCard)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
respBytes, err := json.Marshal(build81NCResponseFromHy87(status))
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Join(processors.ErrSystem, err)
|
||||||
|
}
|
||||||
|
return respBytes, nil
|
||||||
|
}
|
||||||
@@ -0,0 +1,77 @@
|
|||||||
|
package ivyz
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestHy87StatusTo5E3FState(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
status int
|
||||||
|
want string
|
||||||
|
}{
|
||||||
|
{0, "2"},
|
||||||
|
{1, "1"},
|
||||||
|
{2, "3"},
|
||||||
|
{3, "1"},
|
||||||
|
{9, "2"},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
if got := hy87StatusTo5E3FState(tt.status); got != tt.want {
|
||||||
|
t.Fatalf("status %d => %q, want %q", tt.status, got, tt.want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestHy87StatusTo81NCOp(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
status int
|
||||||
|
wantType string
|
||||||
|
wantTypeDesc string
|
||||||
|
}{
|
||||||
|
{0, "INR", "匹配不成功"},
|
||||||
|
{1, "IA", "结婚"},
|
||||||
|
{2, "IB", "离婚"},
|
||||||
|
{3, "IA", "结婚"},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
gotType, gotDesc := hy87StatusTo81NCOp(tt.status)
|
||||||
|
if gotType != tt.wantType || gotDesc != tt.wantTypeDesc {
|
||||||
|
t.Fatalf("status %d => (%q, %q), want (%q, %q)", tt.status, gotType, gotDesc, tt.wantType, tt.wantTypeDesc)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestParseHy87MarriageStatus(t *testing.T) {
|
||||||
|
data := map[string]interface{}{
|
||||||
|
"result": map[string]interface{}{
|
||||||
|
"status": float64(1),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
status, err := parseHy87MarriageStatus(data)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("parseHy87MarriageStatus() error = %v", err)
|
||||||
|
}
|
||||||
|
if status != 1 {
|
||||||
|
t.Fatalf("status = %d, want 1", status)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestBuild81NCResponseFromHy87(t *testing.T) {
|
||||||
|
resp := build81NCResponseFromHy87(2)
|
||||||
|
data, ok := resp["data"].(map[string]interface{})
|
||||||
|
if !ok {
|
||||||
|
t.Fatalf("data type = %T, want map[string]interface{}", resp["data"])
|
||||||
|
}
|
||||||
|
if data["op_type"] != "IB" || data["op_type_desc"] != "离婚" || data["op_date"] != "" {
|
||||||
|
t.Fatalf("unexpected 81nc response: %#v", resp)
|
||||||
|
}
|
||||||
|
|
||||||
|
respBytes, err := json.Marshal(resp)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("json.Marshal() error = %v", err)
|
||||||
|
}
|
||||||
|
if string(respBytes) == "" {
|
||||||
|
t.Fatal("empty response bytes")
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
package qcxg
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
|
|
||||||
|
"tyapi-server/internal/domains/api/dto"
|
||||||
|
"tyapi-server/internal/domains/api/services/processors"
|
||||||
|
"tyapi-server/internal/infrastructure/external/haiyuapi"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ProcessQCXGCP77Request QCXGCP77 全国车辆配置查验(车辆详情)API 处理方法(海宇API)
|
||||||
|
func ProcessQCXGCP77Request(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) {
|
||||||
|
var paramsDto dto.QCXGCP77Req
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
|
||||||
|
if deps.HaiyuapiService == nil {
|
||||||
|
return nil, errors.Join(processors.ErrSystem, errors.New("海宇API服务未初始化"))
|
||||||
|
}
|
||||||
|
|
||||||
|
reqParams := map[string]interface{}{
|
||||||
|
"vin_code": paramsDto.VinCode,
|
||||||
|
}
|
||||||
|
|
||||||
|
respBytes, err := deps.HaiyuapiService.CallAPI(ctx, "QCXGCP77", reqParams)
|
||||||
|
if err != nil {
|
||||||
|
if errors.Is(err, haiyuapi.ErrNotFound) {
|
||||||
|
return nil, errors.Join(processors.ErrNotFound, err)
|
||||||
|
}
|
||||||
|
if errors.Is(err, haiyuapi.ErrDatasource) {
|
||||||
|
return nil, errors.Join(processors.ErrDatasource, err)
|
||||||
|
}
|
||||||
|
return nil, errors.Join(processors.ErrSystem, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return respBytes, nil
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user