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)
|
||||
if err != nil {
|
||||
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.Error(err))
|
||||
return nil, ErrSystem
|
||||
|
||||
@@ -187,6 +187,9 @@ type YYSYXF7JReq struct {
|
||||
type QCXGA8V3Req struct {
|
||||
VinCode string `json:"vin_code" validate:"required"`
|
||||
}
|
||||
type QCXGCP77Req struct {
|
||||
VinCode string `json:"vin_code" validate:"required"`
|
||||
}
|
||||
|
||||
type YYSYP72DReq struct {
|
||||
MobileNo string `json:"mobile_no" validate:"required,min=11,max=11,validMobileNo"`
|
||||
|
||||
@@ -414,6 +414,7 @@ func registerAllProcessors(combService *comb.CombService) {
|
||||
"QYGLVR76": qygl.ProcessQYGLVR76Request, //名下企业诺尔
|
||||
"QCXG1S2L": qcxg.ProcessQCXG1S2LRequest, //车辆车五项信息核验V2
|
||||
"QCXGA8V3": qcxg.ProcessQCXGA8V3Request, //全国车辆配置查验(车五项+使用性质+承保)
|
||||
"QCXGCP77": qcxg.ProcessQCXGCP77Request, //全国车辆配置查验(车辆详情)
|
||||
"QCXG6U5G": qcxg.ProcessQCXG6U5GRequest, //名下车辆核验
|
||||
// DWBG系列处理器 - 多维报告
|
||||
"DWBG6A2C": dwbg.ProcessDWBG6A2CRequest,
|
||||
|
||||
@@ -338,6 +338,7 @@ func (s *FormConfigServiceImpl) getDTOStruct(ctx context.Context, apiCode string
|
||||
"YYSYXF7J": &dto.YYSYXF7JReq{}, //手机消费区间验证
|
||||
"QCXG1S2L": &dto.QCXG1S2LReq{}, //车辆车五项信息核验V2
|
||||
"QCXGA8V3": &dto.QCXGA8V3Req{}, //全国车辆配置查验(车五项+使用性质+承保)
|
||||
"QCXGCP77": &dto.QCXGCP77Req{}, //全国车辆配置查验(车辆详情)
|
||||
"JRZQ5T8S": &dto.JRZQ5T8SReq{}, //借贷意向验证V22
|
||||
"JRZQT57Z": &dto.JRZQT57ZReq{}, //团伙欺诈风险识别
|
||||
"IVYZX7J9": &dto.IVYZX7J9Req{}, //学历核验政务
|
||||
|
||||
@@ -40,10 +40,9 @@ func ProcessIVYZ5E3FRequest(ctx context.Context, params []byte, deps *processors
|
||||
respData, err := deps.ZhichaService.CallAPI(ctx, "ZCI029", 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)
|
||||
return fallback5E3FViaHy87(ctx, deps, paramsDto.Name, paramsDto.IDCard)
|
||||
}
|
||||
return nil, errors.Join(processors.ErrSystem, err)
|
||||
}
|
||||
|
||||
// 将响应数据转换为JSON字节
|
||||
|
||||
@@ -40,57 +40,24 @@ func ProcessIVYZ81NCRequest(ctx context.Context, params []byte, deps *processors
|
||||
respData, err := deps.ZhichaService.CallAPI(ctx, "ZCI029", 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)
|
||||
return fallback81NCViaHy87(ctx, deps, paramsDto.Name, paramsDto.IDCard)
|
||||
}
|
||||
return nil, errors.Join(processors.ErrSystem, err)
|
||||
}
|
||||
|
||||
// 解析响应数据,期望格式为 {"state": "1"}
|
||||
var stateResp struct {
|
||||
State string `json:"state"`
|
||||
State string `json:"state"`
|
||||
RegTime string `json:"regTime"`
|
||||
}
|
||||
|
||||
// 将 respData 转换为 JSON 字节再解析
|
||||
respDataBytes, err := json.Marshal(respData)
|
||||
if err != nil {
|
||||
return nil, errors.Join(processors.ErrSystem, err)
|
||||
}
|
||||
|
||||
if err := json.Unmarshal(respDataBytes, &stateResp); err != nil {
|
||||
return nil, errors.Join(processors.ErrSystem, err)
|
||||
}
|
||||
|
||||
// 根据 state 值转换为 81nc 格式
|
||||
var opType, opTypeDesc string
|
||||
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)
|
||||
opType, opTypeDesc := zhichaStateTo81NCOp(stateResp.State)
|
||||
return json.Marshal(build81NCResponse(stateResp.RegTime, opType, opTypeDesc))
|
||||
}
|
||||
|
||||
@@ -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