This commit is contained in:
2026-02-12 15:16:54 +08:00
parent 07bf234b30
commit ca6dcc1b24
21 changed files with 2594 additions and 111 deletions

View File

@@ -60,7 +60,8 @@ type APIResponseData struct {
}
// ProcessRequests 处理请求
func (a *ApiRequestService) ProcessRequests(params []byte, productID int64) ([]APIResponseData, error) {
// orderNo: 当前查询对应的订单号用于为异步车辆类接口生成回调地址return_url
func (a *ApiRequestService) ProcessRequests(params []byte, productID int64, orderNo string) ([]APIResponseData, error) {
var ctx, cancel = context.WithCancel(context.Background())
defer cancel()
build := a.productFeatureModel.SelectBuilder().Where(squirrel.Eq{
@@ -87,6 +88,19 @@ func (a *ApiRequestService) ProcessRequests(params []byte, productID int64) ([]A
if len(featureList) == 0 {
return nil, errors.New("处理请求错误,产品无对应接口功能")
}
// 在原始 params 上附加 order_no供异步车辆类接口自动生成回调地址使用
var baseParams map[string]interface{}
if err := json.Unmarshal(params, &baseParams); err != nil {
return nil, fmt.Errorf("解析查询参数失败: %w", err)
}
if orderNo != "" {
baseParams["order_no"] = orderNo
}
paramsWithOrder, err := json.Marshal(baseParams)
if err != nil {
return nil, fmt.Errorf("序列化查询参数失败: %w", err)
}
var (
wg sync.WaitGroup
resultsCh = make(chan APIResponseData, len(featureList))
@@ -120,7 +134,7 @@ func (a *ApiRequestService) ProcessRequests(params []byte, productID int64) ([]A
tryCount := 0
for {
tryCount++
resp, preprocessErr = a.PreprocessRequestApi(params, feature.ApiId)
resp, preprocessErr = a.PreprocessRequestApi(paramsWithOrder, feature.ApiId)
if preprocessErr == nil {
break
}
@@ -213,6 +227,23 @@ var requestProcessors = map[string]func(*ApiRequestService, []byte) ([]byte, err
"QCXG3Z3L": (*ApiRequestService).ProcessQCXG3Z3LRequest,
"QCXGP00W": (*ApiRequestService).ProcessQCXGP00WRequest,
"QCXG6B4E": (*ApiRequestService).ProcessQCXG6B4ERequest,
// 核验工具verify feature.md
"IVYZ9K7F": (*ApiRequestService).ProcessIVYZ9K7FRequest,
"IVYZA1B3": (*ApiRequestService).ProcessIVYZA1B3Request,
"IVYZ6M8P": (*ApiRequestService).ProcessIVYZ6M8PRequest,
"JRZQ8B3C": (*ApiRequestService).ProcessJRZQ8B3CRequest,
"YYSY3M8S": (*ApiRequestService).ProcessYYSY3M8SRequest,
"YYSYK9R4": (*ApiRequestService).ProcessYYSYK9R4Request,
"YYSYF2T7": (*ApiRequestService).ProcessYYSYF2T7Request,
"YYSYK8R3": (*ApiRequestService).ProcessYYSYK8R3Request,
"YYSYS9W1": (*ApiRequestService).ProcessYYSYS9W1Request,
"YYSYE7V5": (*ApiRequestService).ProcessYYSYE7V5Request,
"YYSYP0T4": (*ApiRequestService).ProcessYYSYP0T4Request,
"YYSY6F2B": (*ApiRequestService).ProcessYYSY6F2BRequest,
"YYSY9E4A": (*ApiRequestService).ProcessYYSY9E4ARequest,
"QYGL5F6A": (*ApiRequestService).ProcessQYGL5F6ARequest,
"JRZQACAB": (*ApiRequestService).ProcessJRZQACABRequest,
"JRZQ0B6Y": (*ApiRequestService).ProcessJRZQ0B6YRequest,
}
// PreprocessRequestApi 调用指定的请求处理函数
@@ -1235,10 +1266,12 @@ func (a *ApiRequestService) ProcessQCXG5U0ZRequest(params []byte) ([]byte, error
}
func (a *ApiRequestService) ProcessQCXG1U4URequest(params []byte) ([]byte, error) {
body := buildVehicleBody(params, []string{"vin_code", "return_url", "image_url"}, nil)
if body["vin_code"] == nil || body["return_url"] == nil || body["image_url"] == nil {
return nil, errors.New("api请求, QCXG1U4U, 缺少必填参数 vin_code/return_url/image_url")
body := buildVehicleBody(params, []string{"vin_code", "image_url"}, nil)
orderNo := gjson.GetBytes(params, "order_no").String()
if body["vin_code"] == nil || body["image_url"] == nil || orderNo == "" {
return nil, errors.New("api请求, QCXG1U4U, 缺少必填参数 vin_code/image_url/order_no")
}
body["return_url"] = a.buildVehicleCallbackURL(orderNo, "QCXG1U4U")
resp, err := a.tianyuanapi.CallInterface("QCXG1U4U", body)
if err != nil {
return nil, err
@@ -1283,10 +1316,12 @@ func (a *ApiRequestService) ProcessQCXG4I1ZRequest(params []byte) ([]byte, error
}
func (a *ApiRequestService) ProcessQCXG3Y6BRequest(params []byte) ([]byte, error) {
body := buildVehicleBody(params, []string{"vin_code", "return_url"}, nil)
if body["vin_code"] == nil || body["return_url"] == nil {
return nil, errors.New("api请求, QCXG3Y6B, 缺少必填参数 vin_code/return_url")
body := buildVehicleBody(params, []string{"vin_code"}, nil)
orderNo := gjson.GetBytes(params, "order_no").String()
if body["vin_code"] == nil || orderNo == "" {
return nil, errors.New("api请求, QCXG3Y6B, 缺少必填参数 vin_code/order_no")
}
body["return_url"] = a.buildVehicleCallbackURL(orderNo, "QCXG3Y6B")
resp, err := a.tianyuanapi.CallInterface("QCXG3Y6B", body)
if err != nil {
return nil, err
@@ -1295,10 +1330,12 @@ func (a *ApiRequestService) ProcessQCXG3Y6BRequest(params []byte) ([]byte, error
}
func (a *ApiRequestService) ProcessQCXG3Z3LRequest(params []byte) ([]byte, error) {
body := buildVehicleBody(params, []string{"vin_code", "return_url"}, nil)
if body["vin_code"] == nil || body["return_url"] == nil {
return nil, errors.New("api请求, QCXG3Z3L, 缺少必填参数 vin_code/return_url")
body := buildVehicleBody(params, []string{"vin_code"}, nil)
orderNo := gjson.GetBytes(params, "order_no").String()
if body["vin_code"] == nil || orderNo == "" {
return nil, errors.New("api请求, QCXG3Z3L, 缺少必填参数 vin_code/order_no")
}
body["return_url"] = a.buildVehicleCallbackURL(orderNo, "QCXG3Z3L")
resp, err := a.tianyuanapi.CallInterface("QCXG3Z3L", body)
if err != nil {
return nil, err
@@ -1308,10 +1345,10 @@ func (a *ApiRequestService) ProcessQCXG3Z3LRequest(params []byte) ([]byte, error
func (a *ApiRequestService) ProcessQCXGP00WRequest(params []byte) ([]byte, error) {
vin := gjson.GetBytes(params, "vin_code")
returnURL := gjson.GetBytes(params, "return_url")
orderNo := gjson.GetBytes(params, "order_no").String()
vlphoto := gjson.GetBytes(params, "vlphoto_data")
if !vin.Exists() || vin.String() == "" || !returnURL.Exists() || returnURL.String() == "" || !vlphoto.Exists() || vlphoto.String() == "" {
return nil, errors.New("api请求, QCXGP00W, 缺少必填参数 vin_code/return_url/vlphoto_data")
if !vin.Exists() || vin.String() == "" || orderNo == "" || !vlphoto.Exists() || vlphoto.String() == "" {
return nil, errors.New("api请求, QCXGP00W, 缺少必填参数 vin_code/order_no/vlphoto_data")
}
key, err := hex.DecodeString(a.config.Encrypt.SecretKey)
if err != nil {
@@ -1323,7 +1360,7 @@ func (a *ApiRequestService) ProcessQCXGP00WRequest(params []byte) ([]byte, error
}
resp, err := a.tianyuanapi.CallInterface("QCXGP00W", map[string]interface{}{
"vin_code": vin.String(),
"return_url": returnURL.String(),
"return_url": a.buildVehicleCallbackURL(orderNo, "QCXGP00W"),
"data": encData,
})
if err != nil {
@@ -1334,14 +1371,17 @@ func (a *ApiRequestService) ProcessQCXGP00WRequest(params []byte) ([]byte, error
func (a *ApiRequestService) ProcessQCXG6B4ERequest(params []byte) ([]byte, error) {
vin := gjson.GetBytes(params, "vin_code")
auth := gjson.GetBytes(params, "authorized")
if !vin.Exists() || vin.String() == "" || !auth.Exists() {
return nil, errors.New("api请求, QCXG6B4E, 缺少 vin_code 或 authorized")
if !vin.Exists() || vin.String() == "" {
return nil, errors.New("api请求, QCXG6B4E, 缺少 vin_code")
}
auth := gjson.GetBytes(params, "authorized").String()
if auth == "" {
auth = "1"
}
// 天远文档字段名为 VINCode、Authorized
resp, err := a.tianyuanapi.CallInterface("QCXG6B4E", map[string]interface{}{
"VINCode": vin.String(),
"Authorized": auth.String(),
"Authorized": auth,
})
if err != nil {
return nil, err
@@ -1349,6 +1389,68 @@ func (a *ApiRequestService) ProcessQCXG6B4ERequest(params []byte) ([]byte, error
return convertTianyuanResponse(resp)
}
// processVerifyPassThrough 核验类接口:缓存 params 已含 mobile_no/id_card/name 等,原样传天远
func (a *ApiRequestService) processVerifyPassThrough(params []byte, apiID string) ([]byte, error) {
var m map[string]interface{}
if err := json.Unmarshal(params, &m); err != nil {
return nil, fmt.Errorf("api请求, %s, 解析参数失败: %w", apiID, err)
}
resp, err := a.tianyuanapi.CallInterface(apiID, m)
if err != nil {
return nil, err
}
return convertTianyuanResponse(resp)
}
func (a *ApiRequestService) ProcessIVYZ9K7FRequest(params []byte) ([]byte, error) {
return a.processVerifyPassThrough(params, "IVYZ9K7F")
}
func (a *ApiRequestService) ProcessIVYZA1B3Request(params []byte) ([]byte, error) {
return a.processVerifyPassThrough(params, "IVYZA1B3")
}
func (a *ApiRequestService) ProcessIVYZ6M8PRequest(params []byte) ([]byte, error) {
return a.processVerifyPassThrough(params, "IVYZ6M8P")
}
func (a *ApiRequestService) ProcessJRZQ8B3CRequest(params []byte) ([]byte, error) {
return a.processVerifyPassThrough(params, "JRZQ8B3C")
}
func (a *ApiRequestService) ProcessYYSY3M8SRequest(params []byte) ([]byte, error) {
return a.processVerifyPassThrough(params, "YYSY3M8S")
}
func (a *ApiRequestService) ProcessYYSYK9R4Request(params []byte) ([]byte, error) {
return a.processVerifyPassThrough(params, "YYSYK9R4")
}
func (a *ApiRequestService) ProcessYYSYF2T7Request(params []byte) ([]byte, error) {
return a.processVerifyPassThrough(params, "YYSYF2T7")
}
func (a *ApiRequestService) ProcessYYSYK8R3Request(params []byte) ([]byte, error) {
return a.processVerifyPassThrough(params, "YYSYK8R3")
}
func (a *ApiRequestService) ProcessYYSYS9W1Request(params []byte) ([]byte, error) {
return a.processVerifyPassThrough(params, "YYSYS9W1")
}
func (a *ApiRequestService) ProcessYYSYE7V5Request(params []byte) ([]byte, error) {
return a.processVerifyPassThrough(params, "YYSYE7V5")
}
func (a *ApiRequestService) ProcessYYSYP0T4Request(params []byte) ([]byte, error) {
return a.processVerifyPassThrough(params, "YYSYP0T4")
}
func (a *ApiRequestService) ProcessYYSY6F2BRequest(params []byte) ([]byte, error) {
return a.processVerifyPassThrough(params, "YYSY6F2B")
}
func (a *ApiRequestService) ProcessYYSY9E4ARequest(params []byte) ([]byte, error) {
return a.processVerifyPassThrough(params, "YYSY9E4A")
}
func (a *ApiRequestService) ProcessQYGL5F6ARequest(params []byte) ([]byte, error) {
return a.processVerifyPassThrough(params, "QYGL5F6A")
}
func (a *ApiRequestService) ProcessJRZQACABRequest(params []byte) ([]byte, error) {
return a.processVerifyPassThrough(params, "JRZQACAB")
}
func (a *ApiRequestService) ProcessJRZQ0B6YRequest(params []byte) ([]byte, error) {
return a.processVerifyPassThrough(params, "JRZQ0B6Y")
}
// buildVehicleBody 从 params 中取 required 与 optional 键,仅非空才写入 body
func buildVehicleBody(params []byte, required, optional []string) map[string]interface{} {
body := make(map[string]interface{})
@@ -1367,6 +1469,18 @@ func buildVehicleBody(params []byte, required, optional []string) map[string]int
return body
}
// buildVehicleCallbackURL 生成车辆类接口的异步回调地址
// 当前使用 AdminPromotion.URLDomain 作为域名配置,路径固定为 /api/v1/tianyuan/vehicle/callback
// 并通过查询参数携带 order_no 与 api_id 以便后端识别具体查询与模块。
func (a *ApiRequestService) buildVehicleCallbackURL(orderNo, apiID string) string {
base := strings.TrimRight(a.config.AdminPromotion.URLDomain, "/")
if base == "" {
// 兜底:如果未配置 URLDomain则使用相对路径交给网关/部署层补全域名
return fmt.Sprintf("/api/v1/tianyuan/vehicle/callback?order_no=%s&api_id=%s", orderNo, apiID)
}
return fmt.Sprintf("%s/api/v1/tianyuan/vehicle/callback?order_no=%s&api_id=%s", base, orderNo, apiID)
}
// ProcessQCXG7A2BRequest 名下车辆
func (a *ApiRequestService) ProcessQCXG7A2BRequest(params []byte) ([]byte, error) {
idCard := gjson.GetBytes(params, "id_card")