Files
qnc-server-v3/app/main/api/internal/logic/query/queryservicelogic.md
2026-05-21 20:56:04 +08:00

40 KiB
Raw Blame History

package query

import ( "context" "database/sql" "encoding/hex" "encoding/json" "fmt" "os" "time" "tyc-server/app/main/api/internal/service" "tyc-server/app/main/model" "tyc-server/common/ctxdata" "tyc-server/common/globalkey" "tyc-server/common/xerr" "tyc-server/pkg/captcha" "tyc-server/pkg/lzkit/crypto" "tyc-server/pkg/lzkit/validator"

"github.com/pkg/errors"
"github.com/zeromicro/go-zero/core/stores/redis"

"tyc-server/app/main/api/internal/svc"
"tyc-server/app/main/api/internal/types"

"github.com/zeromicro/go-zero/core/logx"

)

type QueryServiceLogic struct { logx.Logger ctx context.Context svcCtx *svc.ServiceContext }

func NewQueryServiceLogic(ctx context.Context, svcCtx *svc.ServiceContext) *QueryServiceLogic { return &QueryServiceLogic{ Logger: logx.WithContext(ctx), ctx: ctx, svcCtx: svcCtx, } }

func (l *QueryServiceLogic) QueryService(req *types.QueryServiceReq) (resp *types.QueryServiceResp, err error) { if req.AgentIdentifier != "" { l.ctx = context.WithValue(l.ctx, "agentIdentifier", req.AgentIdentifier) } else if req.App { l.ctx = context.WithValue(l.ctx, "app", req.App) } return l.PreprocessLogic(req, req.Product) }

// queryHandlerFunc 通用查询 handler解密后的数据 + 产品名 -> 校验并返回待缓存的 params // 新增产品时只需在 productHandlers 里加一行并选用已有 handler 类型即可,无需再写 ProcessXxx type queryHandlerFunc func(l *QueryServiceLogic, decryptData []byte, product string) (map[string]interface{}, error)

var productHandlers = map[string]queryHandlerFunc{ "marriage": runMarriageReq, "homeservice": runMarriageReq, "riskassessment": runMarriageReq, "companyinfo": runMarriageReq, "rentalinfo": runMarriageReq, "preloanbackgroundcheck": runMarriageReq, "backgroundcheck": runBackgroundCheckReq, "personalData": runMarriageReq, "toc_PersonalBadRecord": runPersonalBadRecordReq, "toc_PersonalLawsuit": runMarriageReq, "toc_EnterpriseLawsuit": runEntLawsuitReq, // 人企关系加强版:仅身份证号 "toc_PersonEnterprisePro": runPersonEnterpriseProReq, // 新司法涉诉类产品 "toc_EnterpriseLawsuitQYGL66SL": runEnterpriseLawsuitSimpleReq, "toc_LimitHighExecuted": runLimitHighExecutedReq, "toc_DishonestExecutedPerson": runDishonestExecutedReq, "toc_Marriage": runMarriageReq, "toc_PersonalMarriageStatus": runMarriageReq, "toc_MarriageStatusRegisterTime": runMarriageReq, "toc_MarriageStatusSupplement": runMarriageReq, "toc_MarriageStatusVerify": runMarriageReq, "toc_DualMarriageStatusRegisterTime": runDualMarriageReq, "toc_VehiclesUnderName": runMarriageReq, "toc_VehiclesUnderNamePlate": runMarriageReq, "toc_PersonVehicleVerification": runPersonVehicleVerificationReq, "toc_PersonVehicleVerificationDetail": runPersonVehicleVerificationReq, // 车辆类产品(按 md 传参) "toc_VehiclesUnderNameCount": runVehiclesUnderNameCountReq, "toc_VehicleStaticInfo": runVehicleVinCodeReq, "toc_VehicleMileageMixed": runVehicleMileageMixedReq, "toc_VehicleVinValuation": runVehicleVinValuationReq, "toc_VehicleTransferSimple": runVehicleTransferSimpleReq, "toc_VehicleTransferDetail": runVehicleVinCodeReq, "toc_VehicleMaintenanceSimple": runVehicleMaintenanceSimpleReq, "toc_VehicleMaintenanceDetail": runVehicleMaintenanceDetailReq, "toc_VehicleClaimDetail": runVehicleClaimDetailReq, "toc_VehicleClaimVerify": runVehicleClaimVerifyReq, // 核验工具verify feature.md "toc_PoliceTwoFactors": runVerifyAuthTwoReq, "toc_PoliceThreeFactors": runVerifyAuthThreeReq, "toc_ProfessionalCertificate": runVerifyCertReq, "toc_PersonalConsumptionCapacityLevel": runVerifyConsumptionReq, // 个人消费能力(沿用现有 product_en "toc_OperatorTwoFactors": runVerifyYysTwoReq, "toc_MobileThreeFactors": runVerifyYysThreeReq, "toc_NumberRecycle": runVerifyMobileOnlyReq, "toc_MobileEmptyCheck": runVerifyMobileOnlyReq, "toc_MobilePortability": runVerifyMobileOnlyReq, "toc_MobileOnlineStatus": runVerifyMobileOnlyReq, "toc_MobileOnlineDuration": runVerifyMobileOnlyReq, "toc_MobileAttribution": runVerifyMobileOnlyReq, "toc_MobileConsumptionRange": runVerifyYysConsumptionReq, "toc_EnterpriseRelation": runVerifyEntRelationReq, "toc_BankcardFourFactors": runVerifyBankFourReq, "toc_BankcardBlacklist": runVerifyBankBlackReq, }

// productHasSmsCode 表示该 product 解密后的请求结构体中是否包含必填短信验证码 Code。 // 有 Code 的产品在「获取验证码」时已经做了滑块,这里不再强制要求 CaptchaVerifyParam。 // 其他产品(无 Code在查询时必须传并校验 CaptchaVerifyParam防止跳过图形验证 // 微信小程序X-Platform: wxmini见 ctxdata.GetPlatformFromCtx不嵌入 H5 滑块,由 PreprocessLogic 跳过图形校验。 func productHasSmsCode(product string) bool { switch product { case "marriage", "homeservice", "riskassessment", "companyinfo", "rentalinfo", "preloanbackgroundcheck", "personalData", "toc_PersonalLawsuit", "toc_EnterpriseLawsuit", "toc_Marriage", "toc_PersonalMarriageStatus", "toc_MarriageStatusRegisterTime", "toc_MarriageStatusSupplement", "toc_MarriageStatusVerify", "toc_DualMarriageStatusRegisterTime", "toc_VehiclesUnderName", "toc_VehiclesUnderNamePlate": return true default: return false } }

func (l *QueryServiceLogic) PreprocessLogic(req *types.QueryServiceReq, product string) (*types.QueryServiceResp, error) { // 无短信验证码 Code 的 product查询前必须传并校验滑块微信小程序端跳过依赖登录态与 X-Platform requireCaptcha := !productHasSmsCode(product) if requireCaptcha { if plat, platErr := ctxdata.GetPlatformFromCtx(l.ctx); platErr == nil && plat == model.PlatformWxMini { requireCaptcha = false } } if requireCaptcha { if req.CaptchaVerifyParam == "" { return nil, errors.Wrapf(xerr.NewErrMsg("请完成图形验证"), "product %s requires captcha", product) } cfg := l.svcCtx.Config.Captcha if err := captcha.Verify(captcha.Config{ AccessKeyID: cfg.AccessKeyID, AccessKeySecret: cfg.AccessKeySecret, EndpointURL: cfg.EndpointURL, SceneID: cfg.SceneID, }, req.CaptchaVerifyParam); err != nil { return nil, err } }

decryptData, err := l.DecryptData(req.Data)
if err != nil {
	return nil, err
}
handler, exists := productHandlers[product]
if !exists {
	return nil, errors.New("未找到相应的处理程序")
}
params, err := handler(l, decryptData, product)
if err != nil {
	return nil, err
}
return l.commonQueryTail(params, product)

}

// commonQueryTail 通用收尾:写缓存、生成 token 并返回 func (l *QueryServiceLogic) commonQueryTail(params map[string]interface{}, product string) (*types.QueryServiceResp, error) { userID, err := l.GetOrCreateUser() if err != nil { return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 处理用户失败: %v", err) } cacheNo, cacheDataErr := l.CacheData(params, product, userID) if cacheDataErr != nil { return nil, cacheDataErr } token, err := l.svcCtx.UserService.GeneralUserToken(l.ctx, userID, model.UserTypeNormal) if err != nil { return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 生成token失败 : %d", userID) } now := time.Now().Unix() return &types.QueryServiceResp{ Id: cacheNo, AccessToken: token, AccessExpire: now + l.svcCtx.Config.JwtAuth.AccessExpire, RefreshAfter: now + l.svcCtx.Config.JwtAuth.RefreshAfter, }, nil }

// runMarriageReq 姓名+身份证+手机+验证码 类产品(婚恋、家政、司法涉诉、婚姻状况、名下车辆等) func runMarriageReq(l *QueryServiceLogic, decryptData []byte, product string) (map[string]interface{}, error) { var data types.MarriageReq if unmarshalErr := json.Unmarshal(decryptData, &data); unmarshalErr != nil { return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 解密后的数据格式不正确: %+v", unmarshalErr) } if validatorErr := validator.Validate(data); validatorErr != nil { return nil, errors.Wrapf(xerr.NewErrCodeMsg(xerr.PARAM_VERIFICATION_ERROR, validatorErr.Error()), "查询服务, 参数不正确: %+v", validatorErr) } if verifyCodeErr := l.VerifyCode(data.Mobile, data.Code); verifyCodeErr != nil { return nil, verifyCodeErr } if verifyErr := l.Verify(data.Name, data.IDCard, data.Mobile); verifyErr != nil { return nil, verifyErr } return map[string]interface{}{ "name": data.Name, "id_card": data.IDCard, "mobile": data.Mobile, }, nil }

func runBackgroundCheckReq(l *QueryServiceLogic, decryptData []byte, product string) (map[string]interface{}, error) { var data types.BackgroundCheckReq if unmarshalErr := json.Unmarshal(decryptData, &data); unmarshalErr != nil { return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 解密后的数据格式不正确: %+v", unmarshalErr) } if validatorErr := validator.Validate(data); validatorErr != nil { return nil, errors.Wrapf(xerr.NewErrCodeMsg(xerr.PARAM_VERIFICATION_ERROR, validatorErr.Error()), "查询服务, 参数不正确: %+v", validatorErr) } if verifyErr := l.Verify(data.Name, data.IDCard, data.Mobile); verifyErr != nil { return nil, verifyErr } return map[string]interface{}{ "name": data.Name, "id_card": data.IDCard, "mobile": data.Mobile, }, nil }

// runEntLawsuitReq 企业司法涉诉:企业名称+统一社会信用代码+手机+验证码 func runEntLawsuitReq(l *QueryServiceLogic, decryptData []byte, product string) (map[string]interface{}, error) { var data types.EntLawsuitReq if unmarshalErr := json.Unmarshal(decryptData, &data); unmarshalErr != nil { return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 解密后的数据格式不正确: %+v", unmarshalErr) } if validatorErr := validator.Validate(data); validatorErr != nil { return nil, errors.Wrapf(xerr.NewErrCodeMsg(xerr.PARAM_VERIFICATION_ERROR, validatorErr.Error()), "查询服务, 参数不正确: %+v", validatorErr) } if verifyCodeErr := l.VerifyCode(data.Mobile, data.Code); verifyCodeErr != nil { return nil, verifyCodeErr } return map[string]interface{}{ "ent_name": data.EntName, "ent_code": data.EntCode, "mobile": data.Mobile, }, nil }

// 企业司法涉诉简版 QYGL66SL仅企业名称auth_date 与授权文件编码由后端自动生成 func runEnterpriseLawsuitSimpleReq(l *QueryServiceLogic, decryptData []byte, product string) (map[string]interface{}, error) { var data types.EnterpriseLawsuitSimpleReq if unmarshalErr := json.Unmarshal(decryptData, &data); unmarshalErr != nil { return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 解密后的数据格式不正确: %+v", unmarshalErr) } if validatorErr := validator.Validate(data); validatorErr != nil { return nil, errors.Wrapf(xerr.NewErrCodeMsg(xerr.PARAM_VERIFICATION_ERROR, validatorErr.Error()), "查询服务, 参数不正确: %+v", validatorErr) } now := time.Now() start := now.AddDate(0, 0, -7) end := now.AddDate(0, 0, 7) authDate := fmt.Sprintf("%s-%s", start.Format("20060102"), end.Format("20060102")) return map[string]interface{}{ "ent_name": data.EntName, "auth_date": authDate, "auth_authorize_file_code": "AUTHTYC0001", }, nil }

// 限高被执行人 FLXG3A9B func runLimitHighExecutedReq(l *QueryServiceLogic, decryptData []byte, product string) (map[string]interface{}, error) { var data types.LimitHighExecutedReq if unmarshalErr := json.Unmarshal(decryptData, &data); unmarshalErr != nil { return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 解密后的数据格式不正确: %+v", unmarshalErr) } if validatorErr := validator.Validate(data); validatorErr != nil { return nil, errors.Wrapf(xerr.NewErrCodeMsg(xerr.PARAM_VERIFICATION_ERROR, validatorErr.Error()), "查询服务, 参数不正确: %+v", validatorErr) } auth := data.Authorized if auth == "" { auth = "1" } return map[string]interface{}{ "name": data.Name, "id_card": data.IDCard, "mobile_no": data.Mobile, "authorized": auth, }, nil }

// 本人不良 FLXGDEA9姓名 + 身份证(授权由 ApiRequest 默认传 1 func runPersonalBadRecordReq(l *QueryServiceLogic, decryptData []byte, product string) (map[string]interface{}, error) { var data types.PersonalBadRecordReq if unmarshalErr := json.Unmarshal(decryptData, &data); unmarshalErr != nil { return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 解密后的数据格式不正确: %+v", unmarshalErr) } if validatorErr := validator.Validate(data); validatorErr != nil { return nil, errors.Wrapf(xerr.NewErrCodeMsg(xerr.PARAM_VERIFICATION_ERROR, validatorErr.Error()), "查询服务, 参数不正确: %+v", validatorErr) } return map[string]interface{}{ "name": data.Name, "id_card": data.IDCard, }, nil }

// 失信被执行人 QYGL2S0W func runDishonestExecutedReq(l *QueryServiceLogic, decryptData []byte, product string) (map[string]interface{}, error) { var data types.DishonestExecutedReq if unmarshalErr := json.Unmarshal(decryptData, &data); unmarshalErr != nil { return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 解密后的数据格式不正确: %+v", unmarshalErr) } if validatorErr := validator.Validate(data); validatorErr != nil { return nil, errors.Wrapf(xerr.NewErrCodeMsg(xerr.PARAM_VERIFICATION_ERROR, validatorErr.Error()), "查询服务, 参数不正确: %+v", validatorErr) } tp := data.Type if tp == "" { tp = "per" } return map[string]interface{}{ "type": tp, "name": data.Name, "id_card": data.IDCard, }, nil }

// runDualMarriageReq 双人婚姻状态:男方/女方姓名+身份证+手机+验证码 func runDualMarriageReq(l *QueryServiceLogic, decryptData []byte, product string) (map[string]interface{}, error) { var data types.TocDualMarriageReq if unmarshalErr := json.Unmarshal(decryptData, &data); unmarshalErr != nil { return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 解密后的数据格式不正确: %+v", unmarshalErr) } if validatorErr := validator.Validate(data); validatorErr != nil { return nil, errors.Wrapf(xerr.NewErrCodeMsg(xerr.PARAM_VERIFICATION_ERROR, validatorErr.Error()), "查询服务, 参数不正确: %+v", validatorErr) } if verifyCodeErr := l.VerifyCode(data.Mobile, data.Code); verifyCodeErr != nil { return nil, verifyCodeErr } if verifyErr := l.VerifyTwo(data.NameMan, data.IDCardMan); verifyErr != nil { return nil, verifyErr } if verifyErr := l.VerifyTwo(data.NameWoman, data.IDCardWoman); verifyErr != nil { return nil, verifyErr } return map[string]interface{}{ "name": data.NameMan, "id_card": data.IDCardMan, "mobile": data.Mobile, "name_man": data.NameMan, "id_card_man": data.IDCardMan, "name_woman": data.NameWoman, "id_card_woman": data.IDCardWoman, }, nil }

// runPersonVehicleVerificationReq 人车核验简版:姓名+号牌类型+车牌号 func runPersonVehicleVerificationReq(l *QueryServiceLogic, decryptData []byte, product string) (map[string]interface{}, error) { var data types.TocPersonVehicleVerification if unmarshalErr := json.Unmarshal(decryptData, &data); unmarshalErr != nil { return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 解密后的数据格式不正确: %+v", unmarshalErr) } if validatorErr := validator.Validate(data); validatorErr != nil { return nil, errors.Wrapf(xerr.NewErrCodeMsg(xerr.PARAM_VERIFICATION_ERROR, validatorErr.Error()), "查询服务, 参数不正确: %+v", validatorErr) }

return map[string]interface{}{
	"name":          data.Name,
	"plate_no":      data.CarLicense,
	"carplate_type": data.CarType,
}, nil

}

// runVehiclesUnderNameCountReq 名下车辆(数量) QCXG4D2E仅 user_type + id_card func runVehiclesUnderNameCountReq(l *QueryServiceLogic, decryptData []byte, product string) (map[string]interface{}, error) { var data types.TocVehiclesUnderNameCountReq if unmarshalErr := json.Unmarshal(decryptData, &data); unmarshalErr != nil { return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 解密后的数据格式不正确: %+v", unmarshalErr) } if validatorErr := validator.Validate(data); validatorErr != nil { return nil, errors.Wrapf(xerr.NewErrCodeMsg(xerr.PARAM_VERIFICATION_ERROR, validatorErr.Error()), "查询服务, 参数不正确: %+v", validatorErr) } userType := data.UserType if userType == "" { userType = "1" } return map[string]interface{}{ "user_type": userType, "id_card": data.IDCard, }, nil }

// runVehicleVinCodeReq 仅 vin_code车辆静态信息、过户详版等 func runVehicleVinCodeReq(l *QueryServiceLogic, decryptData []byte, product string) (map[string]interface{}, error) { var data types.TocVehicleVinCodeReq if unmarshalErr := json.Unmarshal(decryptData, &data); unmarshalErr != nil { return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 解密后的数据格式不正确: %+v", unmarshalErr) } if validatorErr := validator.Validate(data); validatorErr != nil { return nil, errors.Wrapf(xerr.NewErrCodeMsg(xerr.PARAM_VERIFICATION_ERROR, validatorErr.Error()), "查询服务, 参数不正确: %+v", validatorErr) } if data.Mobile != "" && data.Code != "" { if verifyCodeErr := l.VerifyCode(data.Mobile, data.Code); verifyCodeErr != nil { return nil, verifyCodeErr } } return map[string]interface{}{ "vin_code": data.VinCode, }, nil }

// runVehicleMileageMixedReq 车辆里程记录(混合) QCXG1U4U func runVehicleMileageMixedReq(l *QueryServiceLogic, decryptData []byte, product string) (map[string]interface{}, error) { var data types.TocVehicleMileageMixedReq if unmarshalErr := json.Unmarshal(decryptData, &data); unmarshalErr != nil { return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 解密后的数据格式不正确: %+v", unmarshalErr) } if validatorErr := validator.Validate(data); validatorErr != nil { return nil, errors.Wrapf(xerr.NewErrCodeMsg(xerr.PARAM_VERIFICATION_ERROR, validatorErr.Error()), "查询服务, 参数不正确: %+v", validatorErr) } if data.Mobile != "" && data.Code != "" { if verifyCodeErr := l.VerifyCode(data.Mobile, data.Code); verifyCodeErr != nil { return nil, verifyCodeErr } } // 回调地址由后端在 ApiRequestService 中统一生成,此处不再下发 return_url return map[string]interface{}{ "vin_code": data.VinCode, "image_url": data.ImageURL, }, nil }

// runVehicleVinValuationReq 二手车VIN估值 QCXGY7F2仅必填 func runVehicleVinValuationReq(l *QueryServiceLogic, decryptData []byte, product string) (map[string]interface{}, error) { var data types.TocVehicleVinValuationReq if unmarshalErr := json.Unmarshal(decryptData, &data); unmarshalErr != nil { return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 解密后的数据格式不正确: %+v", unmarshalErr) } if validatorErr := validator.Validate(data); validatorErr != nil { return nil, errors.Wrapf(xerr.NewErrCodeMsg(xerr.PARAM_VERIFICATION_ERROR, validatorErr.Error()), "查询服务, 参数不正确: %+v", validatorErr) } if data.Mobile != "" && data.Code != "" { if verifyCodeErr := l.VerifyCode(data.Mobile, data.Code); verifyCodeErr != nil { return nil, verifyCodeErr } } return map[string]interface{}{ "vin_code": data.VinCode, "vehicle_location": data.VehicleLocation, "first_registrationdate": data.FirstRegistrationDate, }, nil }

// runVehicleTransferSimpleReq 车辆过户简版 QCXG1H7Y仅必填 vin_code func runVehicleTransferSimpleReq(l *QueryServiceLogic, decryptData []byte, product string) (map[string]interface{}, error) { var data types.TocVehicleTransferSimpleReq if unmarshalErr := json.Unmarshal(decryptData, &data); unmarshalErr != nil { return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 解密后的数据格式不正确: %+v", unmarshalErr) } if validatorErr := validator.Validate(data); validatorErr != nil { return nil, errors.Wrapf(xerr.NewErrCodeMsg(xerr.PARAM_VERIFICATION_ERROR, validatorErr.Error()), "查询服务, 参数不正确: %+v", validatorErr) } if data.Mobile != "" && data.Code != "" { if verifyCodeErr := l.VerifyCode(data.Mobile, data.Code); verifyCodeErr != nil { return nil, verifyCodeErr } } return map[string]interface{}{"vin_code": data.VinCode}, nil }

// runVehicleMaintenanceSimpleReq 车辆维保简版 QCXG3Y6B仅必填 vin_code回调地址后端自动生成 func runVehicleMaintenanceSimpleReq(l *QueryServiceLogic, decryptData []byte, product string) (map[string]interface{}, error) { var data types.TocVehicleMaintenanceSimpleReq if unmarshalErr := json.Unmarshal(decryptData, &data); unmarshalErr != nil { return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 解密后的数据格式不正确: %+v", unmarshalErr) } if validatorErr := validator.Validate(data); validatorErr != nil { return nil, errors.Wrapf(xerr.NewErrCodeMsg(xerr.PARAM_VERIFICATION_ERROR, validatorErr.Error()), "查询服务, 参数不正确: %+v", validatorErr) } if data.Mobile != "" && data.Code != "" { if verifyCodeErr := l.VerifyCode(data.Mobile, data.Code); verifyCodeErr != nil { return nil, verifyCodeErr } } // 回调地址由后端在 ApiRequestService 中统一生成,此处不再下发 return_url return map[string]interface{}{ "vin_code": data.VinCode, }, nil }

// runVehicleMaintenanceDetailReq 车辆维保详细版 QCXG3Z3L仅必填 vin_code回调地址后端自动生成 func runVehicleMaintenanceDetailReq(l *QueryServiceLogic, decryptData []byte, product string) (map[string]interface{}, error) { var data types.TocVehicleMaintenanceDetailReq if unmarshalErr := json.Unmarshal(decryptData, &data); unmarshalErr != nil { return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 解密后的数据格式不正确: %+v", unmarshalErr) } if validatorErr := validator.Validate(data); validatorErr != nil { return nil, errors.Wrapf(xerr.NewErrCodeMsg(xerr.PARAM_VERIFICATION_ERROR, validatorErr.Error()), "查询服务, 参数不正确: %+v", validatorErr) } if data.Mobile != "" && data.Code != "" { if verifyCodeErr := l.VerifyCode(data.Mobile, data.Code); verifyCodeErr != nil { return nil, verifyCodeErr } } // 回调地址由后端在 ApiRequestService 中统一生成,此处不再下发 return_url return map[string]interface{}{ "vin_code": data.VinCode, }, nil }

// runVehicleClaimDetailReq 车辆出险详版 QCXGP00W仅必填 vin_code, vlphoto_data回调地址后端自动生成vlphoto_data 由 API 层加密为 data func runVehicleClaimDetailReq(l *QueryServiceLogic, decryptData []byte, product string) (map[string]interface{}, error) { var data types.TocVehicleClaimDetailReq if unmarshalErr := json.Unmarshal(decryptData, &data); unmarshalErr != nil { return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 解密后的数据格式不正确: %+v", unmarshalErr) } if validatorErr := validator.Validate(data); validatorErr != nil { return nil, errors.Wrapf(xerr.NewErrCodeMsg(xerr.PARAM_VERIFICATION_ERROR, validatorErr.Error()), "查询服务, 参数不正确: %+v", validatorErr) } if data.Mobile != "" && data.Code != "" { if verifyCodeErr := l.VerifyCode(data.Mobile, data.Code); verifyCodeErr != nil { return nil, verifyCodeErr } } // 回调地址由后端在 ApiRequestService 中统一生成,此处不再下发 return_url return map[string]interface{}{ "vin_code": data.VinCode, "vlphoto_data": data.VlphotoData, }, nil }

// runVehicleClaimVerifyReq 车辆出险记录核验 QCXG6B4E func runVehicleClaimVerifyReq(l *QueryServiceLogic, decryptData []byte, product string) (map[string]interface{}, error) { var data types.TocVehicleClaimVerifyReq if unmarshalErr := json.Unmarshal(decryptData, &data); unmarshalErr != nil { return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 解密后的数据格式不正确: %+v", unmarshalErr) } if validatorErr := validator.Validate(data); validatorErr != nil { return nil, errors.Wrapf(xerr.NewErrCodeMsg(xerr.PARAM_VERIFICATION_ERROR, validatorErr.Error()), "查询服务, 参数不正确: %+v", validatorErr) } if data.Mobile != "" && data.Code != "" { if verifyCodeErr := l.VerifyCode(data.Mobile, data.Code); verifyCodeErr != nil { return nil, verifyCodeErr } } auth := data.Authorized if auth == "" { auth = "1" } return map[string]interface{}{ "vin_code": data.VINCode, "authorized": auth, }, nil }

// runPersonEnterpriseProReq 人企关系加强版预查询:仅身份证号 func runPersonEnterpriseProReq(l *QueryServiceLogic, decryptData []byte, product string) (map[string]interface{}, error) { var data types.TocPersonEnterpriseProReq if unmarshalErr := json.Unmarshal(decryptData, &data); unmarshalErr != nil { return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 解密后的数据格式不正确: %+v", unmarshalErr) } if validatorErr := validator.Validate(data); validatorErr != nil { return nil, errors.Wrapf(xerr.NewErrCodeMsg(xerr.PARAM_VERIFICATION_ERROR, validatorErr.Error()), "查询服务, 参数不正确: %+v", validatorErr) } return map[string]interface{}{ "id_card": data.IDCard, }, nil }

// --------------- 核验工具 handlers --------------- func runVerifyAuthTwoReq(l *QueryServiceLogic, decryptData []byte, product string) (map[string]interface{}, error) { var data types.TocVerifyAuthTwoReq if err := json.Unmarshal(decryptData, &data); err != nil { return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 解密后的数据格式不正确: %+v", err) } if err := validator.Validate(data); err != nil { return nil, errors.Wrapf(xerr.NewErrCodeMsg(xerr.PARAM_VERIFICATION_ERROR, err.Error()), "查询服务, 参数不正确: %+v", err) } return map[string]interface{}{"mobile_no": data.MobileNo, "id_card": data.IDCard, "name": data.Name}, nil }

func runVerifyAuthThreeReq(l *QueryServiceLogic, decryptData []byte, product string) (map[string]interface{}, error) { var data types.TocVerifyAuthThreeReq if err := json.Unmarshal(decryptData, &data); err != nil { return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 解密后的数据格式不正确: %+v", err) } if err := validator.Validate(data); err != nil { return nil, errors.Wrapf(xerr.NewErrCodeMsg(xerr.PARAM_VERIFICATION_ERROR, err.Error()), "查询服务, 参数不正确: %+v", err) } return map[string]interface{}{"photo_data": data.PhotoData, "id_card": data.IDCard, "name": data.Name}, nil }

func runVerifyCertReq(l *QueryServiceLogic, decryptData []byte, product string) (map[string]interface{}, error) { var data types.TocVerifyCertReq if err := json.Unmarshal(decryptData, &data); err != nil { return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 解密后的数据格式不正确: %+v", err) } if err := validator.Validate(data); err != nil { return nil, errors.Wrapf(xerr.NewErrCodeMsg(xerr.PARAM_VERIFICATION_ERROR, err.Error()), "查询服务, 参数不正确: %+v", err) } return map[string]interface{}{"id_card": data.IDCard, "name": data.Name}, nil }

func runVerifyConsumptionReq(l *QueryServiceLogic, decryptData []byte, product string) (map[string]interface{}, error) { var data types.TocVerifyConsumptionReq if err := json.Unmarshal(decryptData, &data); err != nil { return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 解密后的数据格式不正确: %+v", err) } if err := validator.Validate(data); err != nil { return nil, errors.Wrapf(xerr.NewErrCodeMsg(xerr.PARAM_VERIFICATION_ERROR, err.Error()), "查询服务, 参数不正确: %+v", err) } return map[string]interface{}{"mobile_no": data.MobileNo, "id_card": data.IDCard, "name": data.Name}, nil }

func runVerifyYysTwoReq(l *QueryServiceLogic, decryptData []byte, product string) (map[string]interface{}, error) { var data types.TocVerifyYysTwoReq if err := json.Unmarshal(decryptData, &data); err != nil { return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 解密后的数据格式不正确: %+v", err) } if err := validator.Validate(data); err != nil { return nil, errors.Wrapf(xerr.NewErrCodeMsg(xerr.PARAM_VERIFICATION_ERROR, err.Error()), "查询服务, 参数不正确: %+v", err) } return map[string]interface{}{"mobile_no": data.MobileNo, "name": data.Name}, nil }

func runVerifyYysThreeReq(l *QueryServiceLogic, decryptData []byte, product string) (map[string]interface{}, error) { var data types.TocVerifyYysThreeReq if err := json.Unmarshal(decryptData, &data); err != nil { return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 解密后的数据格式不正确: %+v", err) } if err := validator.Validate(data); err != nil { return nil, errors.Wrapf(xerr.NewErrCodeMsg(xerr.PARAM_VERIFICATION_ERROR, err.Error()), "查询服务, 参数不正确: %+v", err) } return map[string]interface{}{"mobile_no": data.MobileNo, "id_card": data.IDCard, "name": data.Name}, nil }

func runVerifyMobileOnlyReq(l *QueryServiceLogic, decryptData []byte, product string) (map[string]interface{}, error) { var data types.TocVerifyMobileOnlyReq if err := json.Unmarshal(decryptData, &data); err != nil { return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 解密后的数据格式不正确: %+v", err) } if err := validator.Validate(data); err != nil { return nil, errors.Wrapf(xerr.NewErrCodeMsg(xerr.PARAM_VERIFICATION_ERROR, err.Error()), "查询服务, 参数不正确: %+v", err) } return map[string]interface{}{"mobile_no": data.MobileNo}, nil }

func runVerifyYysConsumptionReq(l *QueryServiceLogic, decryptData []byte, product string) (map[string]interface{}, error) { var data types.TocVerifyYysConsumptionReq if err := json.Unmarshal(decryptData, &data); err != nil { return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 解密后的数据格式不正确: %+v", err) } if err := validator.Validate(data); err != nil { return nil, errors.Wrapf(xerr.NewErrCodeMsg(xerr.PARAM_VERIFICATION_ERROR, err.Error()), "查询服务, 参数不正确: %+v", err) } return map[string]interface{}{"mobile_no": data.MobileNo, "authorized": data.Authorized}, nil }

func runVerifyEntRelationReq(l *QueryServiceLogic, decryptData []byte, product string) (map[string]interface{}, error) { var data types.TocVerifyEntRelationReq if err := json.Unmarshal(decryptData, &data); err != nil { return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 解密后的数据格式不正确: %+v", err) } out := map[string]interface{}{} if data.IDCard != "" { out["id_card"] = data.IDCard } return out, nil }

func runVerifyBankFourReq(l *QueryServiceLogic, decryptData []byte, product string) (map[string]interface{}, error) { var data types.TocVerifyBankFourReq if err := json.Unmarshal(decryptData, &data); err != nil { return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 解密后的数据格式不正确: %+v", err) } if err := validator.Validate(data); err != nil { return nil, errors.Wrapf(xerr.NewErrCodeMsg(xerr.PARAM_VERIFICATION_ERROR, err.Error()), "查询服务, 参数不正确: %+v", err) } return map[string]interface{}{ "mobile_no": data.MobileNo, "id_card": data.IDCard, "bank_card": data.BankCard, "name": data.Name, }, nil }

func runVerifyBankBlackReq(l *QueryServiceLogic, decryptData []byte, product string) (map[string]interface{}, error) { var data types.TocVerifyBankBlackReq if err := json.Unmarshal(decryptData, &data); err != nil { return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 解密后的数据格式不正确: %+v", err) } if err := validator.Validate(data); err != nil { return nil, errors.Wrapf(xerr.NewErrCodeMsg(xerr.PARAM_VERIFICATION_ERROR, err.Error()), "查询服务, 参数不正确: %+v", err) } return map[string]interface{}{ "mobile_no": data.MobileNo, "id_card": data.IDCard, "name": data.Name, "bank_card": data.BankCard, }, nil }

func (l *QueryServiceLogic) DecryptData(data string) ([]byte, error) { secretKey := l.svcCtx.Config.Encrypt.SecretKey key, decodeErr := hex.DecodeString(secretKey) if decodeErr != nil { return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "密钥获取失败: %+v", decodeErr) } decryptData, aesDecryptErr := crypto.AesDecrypt(data, key) if aesDecryptErr != nil || len(decryptData) == 0 { return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "解密失败: %+v", aesDecryptErr) } return decryptData, nil }

// 校验验证码(开发环境 ENV=development 可跳过) func (l *QueryServiceLogic) VerifyCode(mobile string, code string) error { if os.Getenv("ENV") == "development" { return nil } secretKey := l.svcCtx.Config.Encrypt.SecretKey encryptedMobile, err := crypto.EncryptMobile(mobile, secretKey) if err != nil { return errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "加密手机号失败: %+v", err) } codeRedisKey := fmt.Sprintf("%s:%s", "query", encryptedMobile) cacheCode, err := l.svcCtx.Redis.Get(codeRedisKey) if err != nil { if errors.Is(err, redis.Nil) { return errors.Wrapf(xerr.NewErrMsg("验证码已过期"), "验证码过期: %s", mobile) } return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "读取验证码redis缓存失败, mobile: %s, err: %+v", mobile, err) } if cacheCode != code { return errors.Wrapf(xerr.NewErrMsg("验证码不正确"), "验证码不正确: %s", mobile) } return nil }

func (l *QueryServiceLogic) IsAgentQuery() bool { agentID, _ := l.ctx.Value("agentIdentifier").(string) return agentID != "" }

// 二要素验证(仅姓名+身份证号)(开发环境不调用验证 API func (l *QueryServiceLogic) VerifyTwo(Name string, IDCard string) error { if os.Getenv("ENV") == "development" { return nil } twoVerification := service.TwoFactorVerificationRequest{ Name: Name, IDCard: IDCard, } verification, err := l.svcCtx.VerificationService.TwoFactorVerification(twoVerification) if err != nil { return errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "二要素验证失败: %v", err) } if !verification.Passed { return errors.Wrapf(xerr.NewErrCodeMsg(xerr.SERVER_COMMON_ERROR, verification.Err.Error()), "二要素验证不通过: %v", err) } return nil }

// 按代理/非代理切换要素验证:代理走三要素;非代理走二要素(开发环境不调用验证 API func (l *QueryServiceLogic) Verify(Name string, IDCard string, Mobile string) error { if os.Getenv("ENV") == "development" { return nil } if !l.IsAgentQuery() { twoVerification := service.TwoFactorVerificationRequest{ Name: Name, IDCard: IDCard, } verification, err := l.svcCtx.VerificationService.TwoFactorVerification(twoVerification) if err != nil { return errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "二要素验证失败: %v", err) } if !verification.Passed { return errors.Wrapf(xerr.NewErrCodeMsg(xerr.SERVER_COMMON_ERROR, verification.Err.Error()), "二要素验证不通过: %v", err) } } else { // 三要素验证 if Mobile == "" { return errors.Wrapf(xerr.NewErrCodeMsg(xerr.PARAM_VERIFICATION_ERROR, "手机号不能为空"), "三要素验证参数不正确: mobile为空") } threeVerification := service.ThreeFactorVerificationRequest{ Name: Name, IDCard: IDCard, Mobile: Mobile, } verification, err := l.svcCtx.VerificationService.ThreeFactorVerification(threeVerification) if err != nil { return errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "三要素验证失败: %v", err) } if !verification.Passed { return errors.Wrapf(xerr.NewErrCodeMsg(xerr.SERVER_COMMON_ERROR, verification.Err.Error()), "三要素验证不通过: %v", err) } } return nil }

// 缓存 func (l QueryServiceLogic) CacheData(params map[string]interface{}, Product string, userID int64) (string, error) { agentIdentifier, _ := l.ctx.Value("agentIdentifier").(string) secretKey := l.svcCtx.Config.Encrypt.SecretKey key, decodeErr := hex.DecodeString(secretKey) if decodeErr != nil { return "", errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 获取AES密钥失败: %+v", decodeErr) } paramsMarshal, marshalErr := json.Marshal(params) if marshalErr != nil { return "", errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 序列化参数失败: %+v", marshalErr) } encryptParams, aesEncryptErr := crypto.AesEncrypt(paramsMarshal, key) if aesEncryptErr != nil { return "", errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 加密参数失败: %+v", aesEncryptErr) } queryCache := types.QueryCacheLoad{ Params: encryptParams, Product: Product, AgentIdentifier: agentIdentifier, } jsonData, marshalErr := json.Marshal(queryCache) if marshalErr != nil { return "", errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 序列化参数失败: %+v", marshalErr) } outTradeNo := "Q_" + l.svcCtx.AlipayService.GenerateOutTradeNo() redisKey := fmt.Sprintf(types.QueryCacheKey, userID, outTradeNo) cacheErr := l.svcCtx.Redis.SetexCtx(l.ctx, redisKey, string(jsonData), int(2time.Hour)) if cacheErr != nil { return "", cacheErr }

// 写入 query_user_record用于后台按被查询人姓名/身份证/手机号追溯订单(见 query_user_record.sql 说明 1
nameStr, _ := params["name"].(string)
idCardStr, _ := params["id_card"].(string)
mobileStr, _ := params["mobile"].(string)
if nameStr != "" || idCardStr != "" || mobileStr != "" {
	var encName, encIdCard, encMobile string
	if nameStr != "" {
		encName, _ = crypto.AesEcbEncrypt([]byte(nameStr), key)
	}
	if idCardStr != "" {
		encIdCard, _ = crypto.EncryptIDCard(idCardStr, key)
	}
	if mobileStr != "" {
		encMobile, _ = crypto.EncryptMobile(mobileStr, secretKey)
	}
	agentIdent := sql.NullString{}
	if agentIdentifier != "" {
		agentIdent = sql.NullString{String: agentIdentifier, Valid: true}
	}
	rec := &model.QueryUserRecord{
		DeleteTime:      sql.NullTime{},
		DelState:        globalkey.DelStateNo,
		Version:         0,
		UserId:          userID,
		Name:            encName,
		IdCard:          encIdCard,
		Mobile:          encMobile,
		Product:         Product,
		QueryNo:         outTradeNo,
		OrderId:         0,
		PlatformOrderId: sql.NullString{},
		AgentIdentifier: agentIdent,
	}
	_, insertErr := l.svcCtx.QueryUserRecordModel.Insert(l.ctx, nil, rec)
	if insertErr != nil {
		logx.WithContext(l.ctx).Errorf("CacheData 写入 query_user_record 失败: %v", insertErr)
	}
}

return outTradeNo, nil

}

// GetOrCreateUser 获取或创建用户 // 1. 如果上下文中已有用户ID直接返回 // 2. 如果是代理查询或APP请求创建新用户 // 3. 其他情况返回未登录错误 func (l *QueryServiceLogic) GetOrCreateUser() (int64, error) { // 尝试获取用户ID claims, err := ctxdata.GetClaimsFromCtx(l.ctx) if err != nil { return 0, err } userID := claims.UserId return userID, nil

// // 如果不是未登录错误,说明是其他错误,直接返回
// if !ctxdata.IsNoUserIdError(err) {
// 	return 0, err
// }

// // 检查是否是代理查询或APP请求
// isAgentQuery := false
// if agentID, ok := l.ctx.Value("agentIdentifier").(string); ok && agentID != "" {
// 	isAgentQuery = true
// }
// if app, ok := l.ctx.Value("app").(bool); ok && app {
// 	isAgentQuery = true
// }

// // 如果不是代理查询或APP请求返回未登录错误
// if !isAgentQuery {
// 	return 0, ctxdata.ErrNoUserIdInCtx
// }

// // 创建新用户
// return l.svcCtx.UserService.RegisterUUIDUser(l.ctx)

}