f
This commit is contained in:
@@ -1,9 +1,6 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"bdqr-server/app/main/api/internal/config"
|
||||
tianyuanapi "bdqr-server/app/main/api/internal/service/tianyuanapi_sdk"
|
||||
"bdqr-server/app/main/model"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
@@ -14,6 +11,10 @@ import (
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
"bdqr-server/app/main/api/internal/config"
|
||||
tianyuanapi "bdqr-server/app/main/api/internal/service/tianyuanapi_sdk"
|
||||
"bdqr-server/app/main/model"
|
||||
|
||||
"github.com/Masterminds/squirrel"
|
||||
"github.com/tidwall/gjson"
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
@@ -24,6 +25,33 @@ func convertTianyuanResponse(resp *tianyuanapi.Response) ([]byte, error) {
|
||||
return json.Marshal(resp.Data)
|
||||
}
|
||||
|
||||
// convertTianyuanBundleResponse 检测并转换组合包响应
|
||||
// 如果响应是组合包格式(包含 "responses" 字段),则转换为统一格式
|
||||
// 否则直接返回原始响应数据
|
||||
func convertTianyuanBundleResponse(resp *tianyuanapi.Response) ([]byte, error) {
|
||||
// 先将响应数据转换为 JSON 字节
|
||||
respData, err := json.Marshal(resp.Data)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("序列化响应数据失败: %v", err)
|
||||
}
|
||||
|
||||
// 检测是否是组合包响应格式(包含 "responses" 字段)
|
||||
if gjson.GetBytes(respData, "responses").Exists() {
|
||||
// 这是组合包响应,转换为统一格式
|
||||
bundleResults, convertErr := convertBundleResponseToStandard(respData)
|
||||
if convertErr != nil {
|
||||
// 转换失败,返回原始数据并记录错误
|
||||
logx.Errorf("转换组合包响应失败: %v", convertErr)
|
||||
return respData, nil
|
||||
}
|
||||
// 转换成功,返回转换后的 JSON
|
||||
return json.Marshal(bundleResults)
|
||||
}
|
||||
|
||||
// 不是组合包响应,直接返回原始数据
|
||||
return respData, nil
|
||||
}
|
||||
|
||||
// 生成认证时间范围:当前时间前后两天的YYYYMMDD-YYMMDD格式
|
||||
func generateAuthDateRange() string {
|
||||
now := time.Now()
|
||||
@@ -32,20 +60,84 @@ func generateAuthDateRange() string {
|
||||
return fmt.Sprintf("%s-%s", start, end)
|
||||
}
|
||||
|
||||
// callTianyuanApiWithLog 调用天元API并记录日志
|
||||
func (a *ApiRequestService) callTianyuanApiWithLog(ctx context.Context, featureID, apiID string, params map[string]interface{}) (*tianyuanapi.Response, error) {
|
||||
startTime := time.Now()
|
||||
resp, err := a.tianyuanapi.CallInterface(apiID, params)
|
||||
responseTime := time.Since(startTime).Milliseconds()
|
||||
|
||||
// 如果没有提供featureID,尝试从缓存中获取
|
||||
if featureID == "" {
|
||||
a.apiFeatureMapMutex.RLock()
|
||||
featureID = a.apiFeatureMapCache[apiID]
|
||||
a.apiFeatureMapMutex.RUnlock()
|
||||
}
|
||||
|
||||
// 构建调用记录选项
|
||||
callStatus := int64(0) // 默认失败
|
||||
errorCode := ""
|
||||
errorMessage := ""
|
||||
responseData := interface{}(nil)
|
||||
transactionID := ""
|
||||
|
||||
if err != nil {
|
||||
// 调用失败
|
||||
errorMessage = err.Error()
|
||||
// 尝试从错误信息中提取错误码
|
||||
if code := tianyuanapi.GetCodeByError(err); code != -1 {
|
||||
errorCode = fmt.Sprintf("%d", code)
|
||||
}
|
||||
} else {
|
||||
// 调用成功
|
||||
callStatus = 1
|
||||
responseData = resp.Data
|
||||
transactionID = resp.TransactionID
|
||||
}
|
||||
|
||||
// 异步记录调用日志(避免影响主流程)
|
||||
go func() {
|
||||
logOpts := CallLogOptions{
|
||||
FeatureID: featureID,
|
||||
ApiID: apiID,
|
||||
CallStatus: callStatus,
|
||||
ResponseTime: responseTime,
|
||||
ErrorCode: errorCode,
|
||||
ErrorMessage: errorMessage,
|
||||
RequestParams: params,
|
||||
ResponseData: responseData,
|
||||
TransactionID: transactionID,
|
||||
}
|
||||
if recordErr := a.tianyuanapiCallLogService.RecordCall(context.Background(), logOpts); recordErr != nil {
|
||||
logx.Errorf("记录天元API调用日志失败,api_id=%s, err=%v", apiID, recordErr)
|
||||
}
|
||||
}()
|
||||
|
||||
return resp, err
|
||||
}
|
||||
|
||||
type ApiRequestService struct {
|
||||
config config.Config
|
||||
featureModel model.FeatureModel
|
||||
productFeatureModel model.ProductFeatureModel
|
||||
tianyuanapi *tianyuanapi.Client
|
||||
config config.Config
|
||||
featureModel model.FeatureModel
|
||||
productFeatureModel model.ProductFeatureModel
|
||||
userFeatureWhitelistModel model.UserFeatureWhitelistModel
|
||||
whitelistService *WhitelistService
|
||||
tianyuanapi *tianyuanapi.Client
|
||||
tianyuanapiCallLogService *TianyuanapiCallLogService
|
||||
apiFeatureMapCache map[string]string // apiID -> featureID 缓存
|
||||
apiFeatureMapMutex sync.RWMutex
|
||||
}
|
||||
|
||||
// NewApiRequestService 是一个构造函数,用于初始化 ApiRequestService
|
||||
func NewApiRequestService(c config.Config, featureModel model.FeatureModel, productFeatureModel model.ProductFeatureModel, tianyuanapi *tianyuanapi.Client) *ApiRequestService {
|
||||
func NewApiRequestService(c config.Config, featureModel model.FeatureModel, productFeatureModel model.ProductFeatureModel, userFeatureWhitelistModel model.UserFeatureWhitelistModel, tianyuanapi *tianyuanapi.Client, tianyuanapiCallLogService *TianyuanapiCallLogService, whitelistService *WhitelistService) *ApiRequestService {
|
||||
return &ApiRequestService{
|
||||
config: c,
|
||||
featureModel: featureModel,
|
||||
productFeatureModel: productFeatureModel,
|
||||
tianyuanapi: tianyuanapi,
|
||||
config: c,
|
||||
featureModel: featureModel,
|
||||
productFeatureModel: productFeatureModel,
|
||||
userFeatureWhitelistModel: userFeatureWhitelistModel,
|
||||
tianyuanapi: tianyuanapi,
|
||||
tianyuanapiCallLogService: tianyuanapiCallLogService,
|
||||
whitelistService: whitelistService,
|
||||
apiFeatureMapCache: make(map[string]string),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,10 +149,76 @@ type APIResponseData struct {
|
||||
Error string `json:"error,omitempty"`
|
||||
}
|
||||
|
||||
// BundleResponseItem 组合包响应中的单个项
|
||||
type BundleResponseItem struct {
|
||||
ApiCode string `json:"api_code"`
|
||||
Success bool `json:"success"`
|
||||
Data json.RawMessage `json:"data"`
|
||||
Error string `json:"error,omitempty"`
|
||||
}
|
||||
|
||||
// BundleResponse 组合包响应结构
|
||||
type BundleResponse struct {
|
||||
Responses []BundleResponseItem `json:"responses"`
|
||||
}
|
||||
|
||||
// convertBundleResponseToStandard 将组合包响应格式转换为统一格式
|
||||
func convertBundleResponseToStandard(bundleResp []byte) ([]APIResponseData, error) {
|
||||
var bundle BundleResponse
|
||||
if err := json.Unmarshal(bundleResp, &bundle); err != nil {
|
||||
return nil, fmt.Errorf("解析组合包响应失败: %v", err)
|
||||
}
|
||||
|
||||
timestamp := time.Now().Format("2006-01-02 15:04:05")
|
||||
var result []APIResponseData
|
||||
|
||||
for _, item := range bundle.Responses {
|
||||
apiResp := APIResponseData{
|
||||
ApiID: item.ApiCode,
|
||||
Success: item.Success,
|
||||
Timestamp: timestamp,
|
||||
}
|
||||
|
||||
// 处理 data 字段
|
||||
if len(item.Data) > 0 {
|
||||
// 如果 data 是 null 的 JSON 字符串,转换为 null
|
||||
if string(item.Data) == "null" {
|
||||
apiResp.Data = []byte("null")
|
||||
} else {
|
||||
apiResp.Data = item.Data
|
||||
}
|
||||
} else {
|
||||
apiResp.Data = []byte("null")
|
||||
}
|
||||
|
||||
// 处理 error 字段
|
||||
if !item.Success && item.Error != "" {
|
||||
apiResp.Error = item.Error
|
||||
}
|
||||
|
||||
result = append(result, apiResp)
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// ProcessRequests 处理请求
|
||||
func (a *ApiRequestService) ProcessRequests(params []byte, productID string) ([]byte, error) {
|
||||
var ctx, cancel = context.WithCancel(context.Background())
|
||||
func (a *ApiRequestService) ProcessRequests(ctx context.Context, params []byte, productID string) ([]byte, error) {
|
||||
var cancel context.CancelFunc
|
||||
ctx, cancel = context.WithCancel(ctx)
|
||||
defer cancel()
|
||||
|
||||
// 从params中提取id_card,用于白名单检查
|
||||
idCard := gjson.GetBytes(params, "id_card").String()
|
||||
|
||||
// 查询白名单(如果提供了id_card),集中由 WhitelistService 处理
|
||||
var whitelistedFeatureApiIds map[string]bool
|
||||
if a.whitelistService != nil {
|
||||
whitelistedFeatureApiIds, _ = a.whitelistService.GetWhitelistedFeatureApisByIdCard(ctx, idCard)
|
||||
} else {
|
||||
whitelistedFeatureApiIds = make(map[string]bool)
|
||||
}
|
||||
|
||||
build := a.productFeatureModel.SelectBuilder().Where(squirrel.Eq{
|
||||
"product_id": productID,
|
||||
})
|
||||
@@ -85,6 +243,13 @@ func (a *ApiRequestService) ProcessRequests(params []byte, productID string) ([]
|
||||
if len(featureList) == 0 {
|
||||
return nil, errors.New("处理请求错误,产品无对应接口功能")
|
||||
}
|
||||
|
||||
// 缓存apiID到featureID的映射关系,供后续调用记录使用
|
||||
a.apiFeatureMapMutex.Lock()
|
||||
for _, feature := range featureList {
|
||||
a.apiFeatureMapCache[feature.ApiId] = feature.Id
|
||||
}
|
||||
a.apiFeatureMapMutex.Unlock()
|
||||
var (
|
||||
wg sync.WaitGroup
|
||||
resultsCh = make(chan APIResponseData, len(featureList))
|
||||
@@ -109,6 +274,18 @@ func (a *ApiRequestService) ProcessRequests(params []byte, productID string) ([]
|
||||
Success: false,
|
||||
}
|
||||
timestamp := time.Now().Format("2006-01-02 15:04:05")
|
||||
|
||||
// 检查是否在白名单中
|
||||
if whitelistedFeatureApiIds[feature.ApiId] {
|
||||
// 在白名单中,返回空结构(data 为 null),保持与正常返回结构一致
|
||||
// 直接设置 data 为 null 的 JSON 字节
|
||||
result.Data = []byte("null")
|
||||
result.Success = true
|
||||
result.Timestamp = timestamp
|
||||
resultsCh <- result
|
||||
return
|
||||
}
|
||||
|
||||
var (
|
||||
resp json.RawMessage
|
||||
preprocessErr error
|
||||
@@ -118,7 +295,7 @@ func (a *ApiRequestService) ProcessRequests(params []byte, productID string) ([]
|
||||
tryCount := 0
|
||||
for {
|
||||
tryCount++
|
||||
resp, preprocessErr = a.PreprocessRequestApi(params, feature.ApiId)
|
||||
resp, preprocessErr = a.PreprocessRequestApi(ctx, params, feature.ApiId)
|
||||
if preprocessErr == nil {
|
||||
break
|
||||
}
|
||||
@@ -153,10 +330,49 @@ func (a *ApiRequestService) ProcessRequests(params []byte, productID string) ([]
|
||||
close(resultsCh)
|
||||
close(errorsCh)
|
||||
}()
|
||||
// 收集所有结果并合并z
|
||||
// 收集所有结果并合并
|
||||
var responseData []APIResponseData
|
||||
for result := range resultsCh {
|
||||
responseData = append(responseData, result)
|
||||
if result.Success && len(result.Data) > 0 {
|
||||
// 先检查是否是已拆开的组合包(统一格式数组)
|
||||
// 特征:是数组格式,且第一个元素包含 "apiID"、"success"、"timestamp" 字段
|
||||
firstItem := gjson.GetBytes(result.Data, "0")
|
||||
if firstItem.Exists() {
|
||||
firstApiID := firstItem.Get("apiID")
|
||||
firstSuccess := firstItem.Get("success")
|
||||
firstTimestamp := firstItem.Get("timestamp")
|
||||
// 如果第一个元素有 apiID、success、timestamp 字段,说明是已拆开的组合包
|
||||
if firstApiID.Exists() && firstSuccess.Exists() && firstTimestamp.Exists() {
|
||||
// 这是已拆开的组合包(统一格式数组),直接展开添加到结果中
|
||||
var bundleResults []APIResponseData
|
||||
if err := json.Unmarshal(result.Data, &bundleResults); err == nil {
|
||||
responseData = append(responseData, bundleResults...)
|
||||
continue
|
||||
}
|
||||
// 解析失败,作为普通响应处理
|
||||
}
|
||||
}
|
||||
|
||||
// 检查是否包含 "responses" 字段(未拆开的组合包)
|
||||
if gjson.GetBytes(result.Data, "responses").Exists() {
|
||||
// 这是未拆开的组合包响应,需要转换
|
||||
bundleResults, convertErr := convertBundleResponseToStandard(result.Data)
|
||||
if convertErr != nil {
|
||||
// 转换失败,记录错误但保留原始结果
|
||||
logx.Errorf("转换组合包响应失败: %v", convertErr)
|
||||
responseData = append(responseData, result)
|
||||
} else {
|
||||
// 转换成功,用转换后的结果替换原始结果
|
||||
responseData = append(responseData, bundleResults...)
|
||||
}
|
||||
} else {
|
||||
// 普通响应,直接添加
|
||||
responseData = append(responseData, result)
|
||||
}
|
||||
} else {
|
||||
// 失败或空响应,直接添加
|
||||
responseData = append(responseData, result)
|
||||
}
|
||||
}
|
||||
if atomic.LoadInt32(&errorCount) >= int32(errorLimit) {
|
||||
var allErrors []error
|
||||
@@ -175,7 +391,7 @@ func (a *ApiRequestService) ProcessRequests(params []byte, productID string) ([]
|
||||
}
|
||||
|
||||
// ------------------------------------请求处理器--------------------------
|
||||
var requestProcessors = map[string]func(*ApiRequestService, []byte) ([]byte, error){
|
||||
var requestProcessors = map[string]func(*ApiRequestService, context.Context, []byte) ([]byte, error){
|
||||
"PersonEnterprisePro": (*ApiRequestService).ProcessPersonEnterpriseProRequest,
|
||||
"BehaviorRiskScan": (*ApiRequestService).ProcessBehaviorRiskScanRequest,
|
||||
"YYSYBE08": (*ApiRequestService).ProcessYYSYBE08Request,
|
||||
@@ -208,19 +424,20 @@ var requestProcessors = map[string]func(*ApiRequestService, []byte) ([]byte, err
|
||||
"JRZQ7F1A": (*ApiRequestService).ProcessJRZQ7F1ARequest,
|
||||
"IVYZ3P9M": (*ApiRequestService).ProcessIVYZ3P9MRequest,
|
||||
"JRZQ6F2A": (*ApiRequestService).ProcessJRZQ6F2ARequest,
|
||||
"COMBQN12": (*ApiRequestService).ProcessCOMBQN12Request,
|
||||
}
|
||||
|
||||
// PreprocessRequestApi 调用指定的请求处理函数
|
||||
func (a *ApiRequestService) PreprocessRequestApi(params []byte, apiID string) ([]byte, error) {
|
||||
func (a *ApiRequestService) PreprocessRequestApi(ctx context.Context, params []byte, apiID string) ([]byte, error) {
|
||||
if processor, exists := requestProcessors[apiID]; exists {
|
||||
return processor(a, params) // 调用 ApiRequestService 方法
|
||||
return processor(a, ctx, params) // 调用 ApiRequestService 方法
|
||||
}
|
||||
|
||||
return nil, errors.New("api请求, 未找到相应的处理程序")
|
||||
}
|
||||
|
||||
// PersonEnterprisePro 人企业关系加强版
|
||||
func (a *ApiRequestService) ProcessPersonEnterpriseProRequest(params []byte) ([]byte, error) {
|
||||
func (a *ApiRequestService) ProcessPersonEnterpriseProRequest(ctx context.Context, params []byte) ([]byte, error) {
|
||||
idCard := gjson.GetBytes(params, "id_card")
|
||||
// 设置最大调用次数上限
|
||||
maxApiCalls := 20 // 允许最多查询20个企业
|
||||
@@ -229,7 +446,7 @@ func (a *ApiRequestService) ProcessPersonEnterpriseProRequest(params []byte) ([]
|
||||
return nil, errors.New("api请求, PersonEnterprisePro, 获取相关参数失败")
|
||||
}
|
||||
|
||||
resp, err := a.tianyuanapi.CallInterface("QYGLB4C0", map[string]interface{}{
|
||||
resp, err := a.callTianyuanApiWithLog(ctx, "", "QYGLB4C0", map[string]interface{}{
|
||||
"id_card": idCard.String(),
|
||||
})
|
||||
if err != nil {
|
||||
@@ -431,7 +648,7 @@ func (a *ApiRequestService) ProcessPersonEnterpriseProRequest(params []byte) ([]
|
||||
}
|
||||
|
||||
// 调用QYGL8271接口获取企业涉诉信息
|
||||
lawsuitResp, err := a.tianyuanapi.CallInterface("QYGL8271", map[string]interface{}{
|
||||
lawsuitResp, err := a.callTianyuanApiWithLog(ctx, "", "QYGL8271", map[string]interface{}{
|
||||
"ent_name": orgName.String(),
|
||||
"ent_code": creditCode.String(),
|
||||
"auth_date": generateAuthDateRange(),
|
||||
@@ -555,14 +772,14 @@ func (a *ApiRequestService) ProcessPersonEnterpriseProRequest(params []byte) ([]
|
||||
}
|
||||
|
||||
// ProcesFLXG0V4BRequest 个人司法涉诉(详版)
|
||||
func (a *ApiRequestService) ProcessFLXG0V4BRequest(params []byte) ([]byte, error) {
|
||||
func (a *ApiRequestService) ProcessFLXG0V4BRequest(ctx context.Context, params []byte) ([]byte, error) {
|
||||
name := gjson.GetBytes(params, "name")
|
||||
idCard := gjson.GetBytes(params, "id_card")
|
||||
if !name.Exists() || !idCard.Exists() {
|
||||
return nil, errors.New("api请求, FLXG0V4B, 获取相关参数失败")
|
||||
}
|
||||
|
||||
resp, err := a.tianyuanapi.CallInterface("FLXG0V4B", map[string]interface{}{
|
||||
resp, err := a.callTianyuanApiWithLog(ctx, "", "FLXG0V4B", map[string]interface{}{
|
||||
"name": name.String(),
|
||||
"id_card": idCard.String(),
|
||||
"auth_date": generateAuthDateRange(),
|
||||
@@ -578,13 +795,13 @@ func (a *ApiRequestService) ProcessFLXG0V4BRequest(params []byte) ([]byte, error
|
||||
}
|
||||
|
||||
// ProcessFLXG0687Request 反诈反赌核验
|
||||
func (a *ApiRequestService) ProcessFLXG0687Request(params []byte) ([]byte, error) {
|
||||
func (a *ApiRequestService) ProcessFLXG0687Request(ctx context.Context, params []byte) ([]byte, error) {
|
||||
idCard := gjson.GetBytes(params, "id_card")
|
||||
if !idCard.Exists() {
|
||||
return nil, errors.New("api请求, FLXG0687, 获取相关参数失败")
|
||||
}
|
||||
|
||||
resp, err := a.tianyuanapi.CallInterface("FLXG0687", map[string]interface{}{
|
||||
resp, err := a.callTianyuanApiWithLog(ctx, "", "FLXG0687", map[string]interface{}{
|
||||
"id_card": idCard.String(),
|
||||
})
|
||||
|
||||
@@ -606,7 +823,7 @@ func (a *ApiRequestService) ProcessFLXG0687Request(params []byte) ([]byte, error
|
||||
}
|
||||
|
||||
// ProcessFLXG3D56Request 违约失信
|
||||
func (a *ApiRequestService) ProcessFLXG3D56Request(params []byte) ([]byte, error) {
|
||||
func (a *ApiRequestService) ProcessFLXG3D56Request(ctx context.Context, params []byte) ([]byte, error) {
|
||||
name := gjson.GetBytes(params, "name")
|
||||
idCard := gjson.GetBytes(params, "id_card")
|
||||
mobile := gjson.GetBytes(params, "mobile")
|
||||
@@ -614,7 +831,7 @@ func (a *ApiRequestService) ProcessFLXG3D56Request(params []byte) ([]byte, error
|
||||
return nil, errors.New("api请求, FLXG3D56, 获取相关参数失败")
|
||||
}
|
||||
|
||||
resp, err := a.tianyuanapi.CallInterface("FLXG3D56", map[string]interface{}{
|
||||
resp, err := a.callTianyuanApiWithLog(ctx, "", "FLXG3D56", map[string]interface{}{
|
||||
"name": name.String(),
|
||||
"id_card": idCard.String(),
|
||||
"mobile_no": mobile.String(),
|
||||
@@ -661,14 +878,14 @@ func (a *ApiRequestService) ProcessFLXG3D56Request(params []byte) ([]byte, error
|
||||
}
|
||||
|
||||
// ProcessIVYZ5733Request 婚姻状况
|
||||
func (a *ApiRequestService) ProcessIVYZ5733Request(params []byte) ([]byte, error) {
|
||||
func (a *ApiRequestService) ProcessIVYZ5733Request(ctx context.Context, params []byte) ([]byte, error) {
|
||||
idCard := gjson.GetBytes(params, "id_card")
|
||||
name := gjson.GetBytes(params, "name")
|
||||
if !idCard.Exists() || !name.Exists() {
|
||||
return nil, errors.New("api请求, IVYZ5733, 获取相关参数失败")
|
||||
}
|
||||
|
||||
resp, err := a.tianyuanapi.CallInterface("IVYZ5733", map[string]interface{}{
|
||||
resp, err := a.callTianyuanApiWithLog(ctx, "", "IVYZ5733", map[string]interface{}{
|
||||
"id_card": idCard.String(),
|
||||
"name": name.String(),
|
||||
})
|
||||
@@ -717,14 +934,14 @@ func (a *ApiRequestService) ProcessIVYZ5733Request(params []byte) ([]byte, error
|
||||
}
|
||||
|
||||
// ProcessIVYZ9A2BRequest 学历查询
|
||||
func (a *ApiRequestService) ProcessIVYZ9A2BRequest(params []byte) ([]byte, error) {
|
||||
func (a *ApiRequestService) ProcessIVYZ9A2BRequest(ctx context.Context, params []byte) ([]byte, error) {
|
||||
idCard := gjson.GetBytes(params, "id_card")
|
||||
name := gjson.GetBytes(params, "name")
|
||||
if !idCard.Exists() || !name.Exists() {
|
||||
return nil, errors.New("api请求, IVYZ9A2B, 获取相关参数失败")
|
||||
}
|
||||
|
||||
resp, err := a.tianyuanapi.CallInterface("IVYZ9A2B", map[string]interface{}{
|
||||
resp, err := a.callTianyuanApiWithLog(ctx, "", "IVYZ9A2B", map[string]interface{}{
|
||||
"id_card": idCard.String(),
|
||||
"name": name.String(),
|
||||
})
|
||||
@@ -788,14 +1005,14 @@ func (a *ApiRequestService) ProcessIVYZ9A2BRequest(params []byte) ([]byte, error
|
||||
}
|
||||
|
||||
// ProcessYYSYBE08Request 二要素
|
||||
func (a *ApiRequestService) ProcessYYSYBE08Request(params []byte) ([]byte, error) {
|
||||
func (a *ApiRequestService) ProcessYYSYBE08Request(ctx context.Context, params []byte) ([]byte, error) {
|
||||
name := gjson.GetBytes(params, "name")
|
||||
idCard := gjson.GetBytes(params, "id_card")
|
||||
if !name.Exists() || !idCard.Exists() {
|
||||
return nil, errors.New("api请求, YYSYBE08, 获取相关参数失败")
|
||||
}
|
||||
|
||||
resp, err := a.tianyuanapi.CallInterface("YYSYBE08", map[string]interface{}{
|
||||
resp, err := a.callTianyuanApiWithLog(ctx, "", "YYSYBE08", map[string]interface{}{
|
||||
"name": name.String(),
|
||||
"id_card": idCard.String(),
|
||||
})
|
||||
@@ -829,7 +1046,7 @@ func (a *ApiRequestService) ProcessYYSYBE08Request(params []byte) ([]byte, error
|
||||
}
|
||||
|
||||
// ProcessJRZQ0A03Request 借贷申请
|
||||
func (a *ApiRequestService) ProcessJRZQ0A03Request(params []byte) ([]byte, error) {
|
||||
func (a *ApiRequestService) ProcessJRZQ0A03Request(ctx context.Context, params []byte) ([]byte, error) {
|
||||
name := gjson.GetBytes(params, "name")
|
||||
idCard := gjson.GetBytes(params, "id_card")
|
||||
mobile := gjson.GetBytes(params, "mobile")
|
||||
@@ -837,7 +1054,7 @@ func (a *ApiRequestService) ProcessJRZQ0A03Request(params []byte) ([]byte, error
|
||||
return nil, errors.New("api请求, JRZQ0A03, 获取相关参数失败")
|
||||
}
|
||||
|
||||
resp, err := a.tianyuanapi.CallInterface("JRZQ0A03", map[string]interface{}{
|
||||
resp, err := a.callTianyuanApiWithLog(ctx, "", "JRZQ0A03", map[string]interface{}{
|
||||
"name": name.String(),
|
||||
"id_card": idCard.String(),
|
||||
"mobile_no": mobile.String(),
|
||||
@@ -886,7 +1103,7 @@ func (a *ApiRequestService) ProcessJRZQ0A03Request(params []byte) ([]byte, error
|
||||
}
|
||||
|
||||
// ProcessJRZQ8203Request 借贷行为
|
||||
func (a *ApiRequestService) ProcessJRZQ8203Request(params []byte) ([]byte, error) {
|
||||
func (a *ApiRequestService) ProcessJRZQ8203Request(ctx context.Context, params []byte) ([]byte, error) {
|
||||
name := gjson.GetBytes(params, "name")
|
||||
idCard := gjson.GetBytes(params, "id_card")
|
||||
mobile := gjson.GetBytes(params, "mobile")
|
||||
@@ -894,7 +1111,7 @@ func (a *ApiRequestService) ProcessJRZQ8203Request(params []byte) ([]byte, error
|
||||
return nil, errors.New("api请求, JRZQ8203, 获取相关参数失败")
|
||||
}
|
||||
|
||||
resp, err := a.tianyuanapi.CallInterface("JRZQ8203", map[string]interface{}{
|
||||
resp, err := a.callTianyuanApiWithLog(ctx, "", "JRZQ8203", map[string]interface{}{
|
||||
"name": name.String(),
|
||||
"id_card": idCard.String(),
|
||||
"mobile_no": mobile.String(),
|
||||
@@ -943,7 +1160,7 @@ func (a *ApiRequestService) ProcessJRZQ8203Request(params []byte) ([]byte, error
|
||||
}
|
||||
|
||||
// ProcessJRZQ4AA8Request 还款压力
|
||||
func (a *ApiRequestService) ProcessJRZQ4AA8Request(params []byte) ([]byte, error) {
|
||||
func (a *ApiRequestService) ProcessJRZQ4AA8Request(ctx context.Context, params []byte) ([]byte, error) {
|
||||
idCard := gjson.GetBytes(params, "id_card")
|
||||
name := gjson.GetBytes(params, "name")
|
||||
mobile := gjson.GetBytes(params, "mobile")
|
||||
@@ -951,7 +1168,7 @@ func (a *ApiRequestService) ProcessJRZQ4AA8Request(params []byte) ([]byte, error
|
||||
return nil, errors.New("api请求, JRZQ4AA8, 获取相关参数失败")
|
||||
}
|
||||
|
||||
resp, err := a.tianyuanapi.CallInterface("JRZQ4AA8", map[string]interface{}{
|
||||
resp, err := a.callTianyuanApiWithLog(ctx, "", "JRZQ4AA8", map[string]interface{}{
|
||||
"id_card": idCard.String(),
|
||||
"name": name.String(),
|
||||
"mobile_no": mobile.String(),
|
||||
@@ -992,7 +1209,7 @@ func (a *ApiRequestService) ProcessJRZQ4AA8Request(params []byte) ([]byte, error
|
||||
}
|
||||
|
||||
// ProcessQYGL8271Request 企业涉诉
|
||||
func (a *ApiRequestService) ProcessQYGL8271Request(params []byte) ([]byte, error) {
|
||||
func (a *ApiRequestService) ProcessQYGL8271Request(ctx context.Context, params []byte) ([]byte, error) {
|
||||
entName := gjson.GetBytes(params, "ent_name")
|
||||
entCode := gjson.GetBytes(params, "ent_code")
|
||||
|
||||
@@ -1000,7 +1217,7 @@ func (a *ApiRequestService) ProcessQYGL8271Request(params []byte) ([]byte, error
|
||||
return nil, errors.New("api请求, QYGL8271, 获取相关参数失败")
|
||||
}
|
||||
|
||||
resp, err := a.tianyuanapi.CallInterface("QYGL8271", map[string]interface{}{
|
||||
resp, err := a.callTianyuanApiWithLog(ctx, "", "QYGL8271", map[string]interface{}{
|
||||
"ent_name": entName.String(),
|
||||
"ent_code": entCode.String(),
|
||||
})
|
||||
@@ -1052,13 +1269,13 @@ func (a *ApiRequestService) ProcessQYGL8271Request(params []byte) ([]byte, error
|
||||
}
|
||||
|
||||
// ProcessQYGL6F2DRequest 人企关联
|
||||
func (a *ApiRequestService) ProcessQYGL6F2DRequest(params []byte) ([]byte, error) {
|
||||
func (a *ApiRequestService) ProcessQYGL6F2DRequest(ctx context.Context, params []byte) ([]byte, error) {
|
||||
idCard := gjson.GetBytes(params, "id_card")
|
||||
if !idCard.Exists() {
|
||||
return nil, errors.New("api请求, QYGL6F2D, 获取相关参数失败")
|
||||
}
|
||||
|
||||
resp, err := a.tianyuanapi.CallInterface("QYGL6F2D", map[string]interface{}{
|
||||
resp, err := a.callTianyuanApiWithLog(ctx, "", "QYGL6F2D", map[string]interface{}{
|
||||
"id_card": idCard.String(),
|
||||
})
|
||||
|
||||
@@ -1093,13 +1310,13 @@ func (a *ApiRequestService) ProcessQYGL6F2DRequest(params []byte) ([]byte, error
|
||||
}
|
||||
|
||||
// ProcessQCXG7A2BRequest 名下车辆
|
||||
func (a *ApiRequestService) ProcessQCXG7A2BRequest(params []byte) ([]byte, error) {
|
||||
func (a *ApiRequestService) ProcessQCXG7A2BRequest(ctx context.Context, params []byte) ([]byte, error) {
|
||||
idCard := gjson.GetBytes(params, "id_card")
|
||||
if !idCard.Exists() {
|
||||
return nil, errors.New("api请求, QCXG7A2B, 获取相关参数失败")
|
||||
}
|
||||
|
||||
resp, err := a.tianyuanapi.CallInterface("QCXG7A2B", map[string]interface{}{
|
||||
resp, err := a.callTianyuanApiWithLog(ctx, "", "QCXG7A2B", map[string]interface{}{
|
||||
"id_card": idCard.String(),
|
||||
})
|
||||
|
||||
@@ -1111,7 +1328,7 @@ func (a *ApiRequestService) ProcessQCXG7A2BRequest(params []byte) ([]byte, error
|
||||
}
|
||||
|
||||
// ProcessYYSY09CDRequest 三要素
|
||||
func (a *ApiRequestService) ProcessYYSY09CDRequest(params []byte) ([]byte, error) {
|
||||
func (a *ApiRequestService) ProcessYYSY09CDRequest(ctx context.Context, params []byte) ([]byte, error) {
|
||||
name := gjson.GetBytes(params, "name")
|
||||
idCard := gjson.GetBytes(params, "id_card")
|
||||
mobile := gjson.GetBytes(params, "mobile")
|
||||
@@ -1119,7 +1336,7 @@ func (a *ApiRequestService) ProcessYYSY09CDRequest(params []byte) ([]byte, error
|
||||
return nil, errors.New("api请求, YYSY09CD, 获取相关参数失败")
|
||||
}
|
||||
|
||||
resp, err := a.tianyuanapi.CallInterface("YYSY09CD", map[string]interface{}{
|
||||
resp, err := a.callTianyuanApiWithLog(ctx, "", "YYSY09CD", map[string]interface{}{
|
||||
"name": name.String(),
|
||||
"id_card": idCard.String(),
|
||||
"mobile_no": mobile.String(),
|
||||
@@ -1154,7 +1371,7 @@ func (a *ApiRequestService) ProcessYYSY09CDRequest(params []byte) ([]byte, error
|
||||
}
|
||||
|
||||
// ProcessBehaviorRiskScanRequest 行为风险扫描
|
||||
func (a *ApiRequestService) ProcessBehaviorRiskScanRequest(params []byte) ([]byte, error) {
|
||||
func (a *ApiRequestService) ProcessBehaviorRiskScanRequest(ctx context.Context, params []byte) ([]byte, error) {
|
||||
name := gjson.GetBytes(params, "name")
|
||||
idCard := gjson.GetBytes(params, "id_card")
|
||||
|
||||
@@ -1176,7 +1393,7 @@ func (a *ApiRequestService) ProcessBehaviorRiskScanRequest(params []byte) ([]byt
|
||||
// 反赌反诈
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
respBytes, err := a.ProcessFLXG0687Request(params)
|
||||
respBytes, err := a.ProcessFLXG0687Request(ctx, params)
|
||||
results <- apiResult{name: "anti_fraud_gaming", data: respBytes, err: err}
|
||||
}()
|
||||
|
||||
@@ -1221,7 +1438,7 @@ func (a *ApiRequestService) ProcessBehaviorRiskScanRequest(params []byte) ([]byt
|
||||
}
|
||||
|
||||
// ProcessDWBG8B4DRequest 谛听多维报告
|
||||
func (a *ApiRequestService) ProcessDWBG8B4DRequest(params []byte) ([]byte, error) {
|
||||
func (a *ApiRequestService) ProcessDWBG8B4DRequest(ctx context.Context, params []byte) ([]byte, error) {
|
||||
name := gjson.GetBytes(params, "name")
|
||||
idCard := gjson.GetBytes(params, "id_card")
|
||||
mobile := gjson.GetBytes(params, "mobile")
|
||||
@@ -1230,7 +1447,7 @@ func (a *ApiRequestService) ProcessDWBG8B4DRequest(params []byte) ([]byte, error
|
||||
return nil, errors.New("api请求, DWBG8B4D, 获取相关参数失败")
|
||||
}
|
||||
|
||||
resp, err := a.tianyuanapi.CallInterface("DWBG8B4D", map[string]interface{}{
|
||||
resp, err := a.callTianyuanApiWithLog(ctx, "", "DWBG8B4D", map[string]interface{}{
|
||||
"name": name.String(),
|
||||
"id_card": idCard.String(),
|
||||
"mobile_no": mobile.String(),
|
||||
@@ -1246,7 +1463,7 @@ func (a *ApiRequestService) ProcessDWBG8B4DRequest(params []byte) ([]byte, error
|
||||
}
|
||||
|
||||
// ProcessDWBG6A2CRequest 司南报告服务
|
||||
func (a *ApiRequestService) ProcessDWBG6A2CRequest(params []byte) ([]byte, error) {
|
||||
func (a *ApiRequestService) ProcessDWBG6A2CRequest(ctx context.Context, params []byte) ([]byte, error) {
|
||||
name := gjson.GetBytes(params, "name")
|
||||
idCard := gjson.GetBytes(params, "id_card")
|
||||
mobile := gjson.GetBytes(params, "mobile")
|
||||
@@ -1255,7 +1472,7 @@ func (a *ApiRequestService) ProcessDWBG6A2CRequest(params []byte) ([]byte, error
|
||||
return nil, errors.New("api请求, DWBG6A2C, 获取相关参数失败")
|
||||
}
|
||||
|
||||
resp, err := a.tianyuanapi.CallInterface("DWBG6A2C", map[string]interface{}{
|
||||
resp, err := a.callTianyuanApiWithLog(ctx, "", "DWBG6A2C", map[string]interface{}{
|
||||
"name": name.String(),
|
||||
"id_card": idCard.String(),
|
||||
"mobile_no": mobile.String(),
|
||||
@@ -1271,7 +1488,7 @@ func (a *ApiRequestService) ProcessDWBG6A2CRequest(params []byte) ([]byte, error
|
||||
}
|
||||
|
||||
// ProcessJRZQ4B6CRequest 探针C风险评估
|
||||
func (a *ApiRequestService) ProcessJRZQ4B6CRequest(params []byte) ([]byte, error) {
|
||||
func (a *ApiRequestService) ProcessJRZQ4B6CRequest(ctx context.Context, params []byte) ([]byte, error) {
|
||||
name := gjson.GetBytes(params, "name")
|
||||
idCard := gjson.GetBytes(params, "id_card")
|
||||
mobile := gjson.GetBytes(params, "mobile")
|
||||
@@ -1279,7 +1496,7 @@ func (a *ApiRequestService) ProcessJRZQ4B6CRequest(params []byte) ([]byte, error
|
||||
return nil, errors.New("api请求, JRZQ4B6C, 获取相关参数失败")
|
||||
}
|
||||
|
||||
resp, err := a.tianyuanapi.CallInterface("JRZQ4B6C", map[string]interface{}{
|
||||
resp, err := a.callTianyuanApiWithLog(ctx, "", "JRZQ4B6C", map[string]interface{}{
|
||||
"name": name.String(),
|
||||
"id_card": idCard.String(),
|
||||
"mobile_no": mobile.String(),
|
||||
@@ -1295,7 +1512,7 @@ func (a *ApiRequestService) ProcessJRZQ4B6CRequest(params []byte) ([]byte, error
|
||||
}
|
||||
|
||||
// ProcessJRZQ09J8Request 收入评估
|
||||
func (a *ApiRequestService) ProcessJRZQ09J8Request(params []byte) ([]byte, error) {
|
||||
func (a *ApiRequestService) ProcessJRZQ09J8Request(ctx context.Context, params []byte) ([]byte, error) {
|
||||
name := gjson.GetBytes(params, "name")
|
||||
idCard := gjson.GetBytes(params, "id_card")
|
||||
mobile := gjson.GetBytes(params, "mobile")
|
||||
@@ -1303,7 +1520,7 @@ func (a *ApiRequestService) ProcessJRZQ09J8Request(params []byte) ([]byte, error
|
||||
return nil, errors.New("api请求, JRZQ09J8, 获取相关参数失败")
|
||||
}
|
||||
|
||||
resp, err := a.tianyuanapi.CallInterface("JRZQ09J8", map[string]interface{}{
|
||||
resp, err := a.callTianyuanApiWithLog(ctx, "", "JRZQ09J8", map[string]interface{}{
|
||||
"name": name.String(),
|
||||
"id_card": idCard.String(),
|
||||
"mobile_no": mobile.String(),
|
||||
@@ -1319,7 +1536,7 @@ func (a *ApiRequestService) ProcessJRZQ09J8Request(params []byte) ([]byte, error
|
||||
}
|
||||
|
||||
// ProcessJRZQ5E9FRequest 借选指数
|
||||
func (a *ApiRequestService) ProcessJRZQ5E9FRequest(params []byte) ([]byte, error) {
|
||||
func (a *ApiRequestService) ProcessJRZQ5E9FRequest(ctx context.Context, params []byte) ([]byte, error) {
|
||||
name := gjson.GetBytes(params, "name")
|
||||
idCard := gjson.GetBytes(params, "id_card")
|
||||
mobile := gjson.GetBytes(params, "mobile")
|
||||
@@ -1327,7 +1544,7 @@ func (a *ApiRequestService) ProcessJRZQ5E9FRequest(params []byte) ([]byte, error
|
||||
return nil, errors.New("api请求, JRZQ5E9F, 获取相关参数失败")
|
||||
}
|
||||
|
||||
resp, err := a.tianyuanapi.CallInterface("JRZQ5E9F", map[string]interface{}{
|
||||
resp, err := a.callTianyuanApiWithLog(ctx, "", "JRZQ5E9F", map[string]interface{}{
|
||||
"name": name.String(),
|
||||
"id_card": idCard.String(),
|
||||
"mobile_no": mobile.String(),
|
||||
@@ -1343,13 +1560,13 @@ func (a *ApiRequestService) ProcessJRZQ5E9FRequest(params []byte) ([]byte, error
|
||||
}
|
||||
|
||||
// ProcessQYGL3F8ERequest 人企关系加强版2
|
||||
func (a *ApiRequestService) ProcessQYGL3F8ERequest(params []byte) ([]byte, error) {
|
||||
func (a *ApiRequestService) ProcessQYGL3F8ERequest(ctx context.Context, params []byte) ([]byte, error) {
|
||||
idCard := gjson.GetBytes(params, "id_card")
|
||||
if !idCard.Exists() {
|
||||
return nil, errors.New("api请求, QYGL3F8E, 获取相关参数失败")
|
||||
}
|
||||
|
||||
resp, err := a.tianyuanapi.CallInterface("QYGL3F8E", map[string]interface{}{
|
||||
resp, err := a.callTianyuanApiWithLog(ctx, "", "QYGL3F8E", map[string]interface{}{
|
||||
"id_card": idCard.String(),
|
||||
})
|
||||
|
||||
@@ -1362,14 +1579,14 @@ func (a *ApiRequestService) ProcessQYGL3F8ERequest(params []byte) ([]byte, error
|
||||
}
|
||||
|
||||
// ProcessIVYZ81NCRequest 婚姻,登记时间版
|
||||
func (a *ApiRequestService) ProcessIVYZ81NCRequest(params []byte) ([]byte, error) {
|
||||
func (a *ApiRequestService) ProcessIVYZ81NCRequest(ctx context.Context, params []byte) ([]byte, error) {
|
||||
name := gjson.GetBytes(params, "name")
|
||||
idCard := gjson.GetBytes(params, "id_card")
|
||||
if !name.Exists() || !idCard.Exists() {
|
||||
return nil, errors.New("api请求, IVYZ81NC, 获取相关参数失败")
|
||||
}
|
||||
|
||||
resp, err := a.tianyuanapi.CallInterface("IVYZ81NC", map[string]interface{}{
|
||||
resp, err := a.callTianyuanApiWithLog(ctx, "", "IVYZ81NC", map[string]interface{}{
|
||||
"name": name.String(),
|
||||
"id_card": idCard.String(),
|
||||
})
|
||||
@@ -1383,14 +1600,14 @@ func (a *ApiRequestService) ProcessIVYZ81NCRequest(params []byte) ([]byte, error
|
||||
}
|
||||
|
||||
// ProcessIVYZ7F3ARequest 学历查询版B
|
||||
func (a *ApiRequestService) ProcessIVYZ7F3ARequest(params []byte) ([]byte, error) {
|
||||
func (a *ApiRequestService) ProcessIVYZ7F3ARequest(ctx context.Context, params []byte) ([]byte, error) {
|
||||
idCard := gjson.GetBytes(params, "id_card")
|
||||
name := gjson.GetBytes(params, "name")
|
||||
if !idCard.Exists() || !name.Exists() {
|
||||
return nil, errors.New("api请求, IVYZ7F3A, 获取相关参数失败")
|
||||
}
|
||||
|
||||
resp, err := a.tianyuanapi.CallInterface("IVYZ7F3A", map[string]interface{}{
|
||||
resp, err := a.callTianyuanApiWithLog(ctx, "", "IVYZ7F3A", map[string]interface{}{
|
||||
"id_card": idCard.String(),
|
||||
"name": name.String(),
|
||||
"authorized": "1",
|
||||
@@ -1405,7 +1622,7 @@ func (a *ApiRequestService) ProcessIVYZ7F3ARequest(params []byte) ([]byte, error
|
||||
}
|
||||
|
||||
// ProcessDWBG7F3ARequest 多头借贷行业风险版
|
||||
func (a *ApiRequestService) ProcessDWBG7F3ARequest(params []byte) ([]byte, error) {
|
||||
func (a *ApiRequestService) ProcessDWBG7F3ARequest(ctx context.Context, params []byte) ([]byte, error) {
|
||||
name := gjson.GetBytes(params, "name")
|
||||
idCard := gjson.GetBytes(params, "id_card")
|
||||
mobile := gjson.GetBytes(params, "mobile")
|
||||
@@ -1413,7 +1630,7 @@ func (a *ApiRequestService) ProcessDWBG7F3ARequest(params []byte) ([]byte, error
|
||||
return nil, errors.New("api请求, DWBG7F3A, 获取相关参数失败")
|
||||
}
|
||||
|
||||
resp, err := a.tianyuanapi.CallInterface("DWBG7F3A", map[string]interface{}{
|
||||
resp, err := a.callTianyuanApiWithLog(ctx, "", "DWBG7F3A", map[string]interface{}{
|
||||
"name": name.String(),
|
||||
"id_card": idCard.String(),
|
||||
"mobile_no": mobile.String(),
|
||||
@@ -1428,7 +1645,7 @@ func (a *ApiRequestService) ProcessDWBG7F3ARequest(params []byte) ([]byte, error
|
||||
}
|
||||
|
||||
// ProcessJRZQ8A2DRequest 特殊名单验证B
|
||||
func (a *ApiRequestService) ProcessJRZQ8A2DRequest(params []byte) ([]byte, error) {
|
||||
func (a *ApiRequestService) ProcessJRZQ8A2DRequest(ctx context.Context, params []byte) ([]byte, error) {
|
||||
name := gjson.GetBytes(params, "name")
|
||||
idCard := gjson.GetBytes(params, "id_card")
|
||||
mobile := gjson.GetBytes(params, "mobile")
|
||||
@@ -1436,7 +1653,7 @@ func (a *ApiRequestService) ProcessJRZQ8A2DRequest(params []byte) ([]byte, error
|
||||
return nil, errors.New("api请求, JRZQ8A2D, 获取相关参数失败")
|
||||
}
|
||||
|
||||
resp, err := a.tianyuanapi.CallInterface("JRZQ8A2D", map[string]interface{}{
|
||||
resp, err := a.callTianyuanApiWithLog(ctx, "", "JRZQ8A2D", map[string]interface{}{
|
||||
"name": name.String(),
|
||||
"id_card": idCard.String(),
|
||||
"mobile_no": mobile.String(),
|
||||
@@ -1452,13 +1669,13 @@ func (a *ApiRequestService) ProcessJRZQ8A2DRequest(params []byte) ([]byte, error
|
||||
}
|
||||
|
||||
// ProcessYYSY8B1CRequest 手机在网时长B
|
||||
func (a *ApiRequestService) ProcessYYSY8B1CRequest(params []byte) ([]byte, error) {
|
||||
func (a *ApiRequestService) ProcessYYSY8B1CRequest(ctx context.Context, params []byte) ([]byte, error) {
|
||||
mobile := gjson.GetBytes(params, "mobile")
|
||||
if !mobile.Exists() {
|
||||
return nil, errors.New("api请求, YYSY8B1C, 获取相关参数失败")
|
||||
}
|
||||
|
||||
resp, err := a.tianyuanapi.CallInterface("YYSY8B1C", map[string]interface{}{
|
||||
resp, err := a.callTianyuanApiWithLog(ctx, "", "YYSY8B1C", map[string]interface{}{
|
||||
"mobile_no": mobile.String(),
|
||||
})
|
||||
|
||||
@@ -1471,13 +1688,13 @@ func (a *ApiRequestService) ProcessYYSY8B1CRequest(params []byte) ([]byte, error
|
||||
}
|
||||
|
||||
// ProcessYYSY7D3ERequest 携号转网查询
|
||||
func (a *ApiRequestService) ProcessYYSY7D3ERequest(params []byte) ([]byte, error) {
|
||||
func (a *ApiRequestService) ProcessYYSY7D3ERequest(ctx context.Context, params []byte) ([]byte, error) {
|
||||
mobile := gjson.GetBytes(params, "mobile")
|
||||
if !mobile.Exists() {
|
||||
return nil, errors.New("api请求, YYSY7D3E, 获取相关参数失败")
|
||||
}
|
||||
|
||||
resp, err := a.tianyuanapi.CallInterface("YYSY7D3E", map[string]interface{}{
|
||||
resp, err := a.callTianyuanApiWithLog(ctx, "", "YYSY7D3E", map[string]interface{}{
|
||||
"mobile_no": mobile.String(),
|
||||
})
|
||||
|
||||
@@ -1490,7 +1707,7 @@ func (a *ApiRequestService) ProcessYYSY7D3ERequest(params []byte) ([]byte, error
|
||||
}
|
||||
|
||||
// ProcessFLXG7E8FRequest 个人司法涉诉查询
|
||||
func (a *ApiRequestService) ProcessFLXG7E8FRequest(params []byte) ([]byte, error) {
|
||||
func (a *ApiRequestService) ProcessFLXG7E8FRequest(ctx context.Context, params []byte) ([]byte, error) {
|
||||
idCard := gjson.GetBytes(params, "id_card")
|
||||
name := gjson.GetBytes(params, "name")
|
||||
mobile := gjson.GetBytes(params, "mobile")
|
||||
@@ -1498,7 +1715,7 @@ func (a *ApiRequestService) ProcessFLXG7E8FRequest(params []byte) ([]byte, error
|
||||
return nil, errors.New("api请求, FLXG7E8F, 获取相关参数失败")
|
||||
}
|
||||
|
||||
resp, err := a.tianyuanapi.CallInterface("FLXG7E8F", map[string]interface{}{
|
||||
resp, err := a.callTianyuanApiWithLog(ctx, "", "FLXG7E8F", map[string]interface{}{
|
||||
"id_card": idCard.String(),
|
||||
"name": name.String(),
|
||||
"mobile_no": mobile.String(),
|
||||
@@ -1513,7 +1730,7 @@ func (a *ApiRequestService) ProcessFLXG7E8FRequest(params []byte) ([]byte, error
|
||||
}
|
||||
|
||||
// ProcessIVYZ8I9JRequest 互联网行为推测
|
||||
func (a *ApiRequestService) ProcessIVYZ8I9JRequest(params []byte) ([]byte, error) {
|
||||
func (a *ApiRequestService) ProcessIVYZ8I9JRequest(ctx context.Context, params []byte) ([]byte, error) {
|
||||
idCard := gjson.GetBytes(params, "id_card")
|
||||
name := gjson.GetBytes(params, "name")
|
||||
mobile := gjson.GetBytes(params, "mobile")
|
||||
@@ -1521,7 +1738,7 @@ func (a *ApiRequestService) ProcessIVYZ8I9JRequest(params []byte) ([]byte, error
|
||||
return nil, errors.New("api请求, IVYZ8I9J, 获取相关参数失败")
|
||||
}
|
||||
|
||||
resp, err := a.tianyuanapi.CallInterface("IVYZ8I9J", map[string]interface{}{
|
||||
resp, err := a.callTianyuanApiWithLog(ctx, "", "IVYZ8I9J", map[string]interface{}{
|
||||
"id_card": idCard.String(),
|
||||
"name": name.String(),
|
||||
"mobile_no": mobile.String(),
|
||||
@@ -1536,7 +1753,7 @@ func (a *ApiRequestService) ProcessIVYZ8I9JRequest(params []byte) ([]byte, error
|
||||
}
|
||||
|
||||
// ProcessJRZQ7F1ARequest 全景雷达
|
||||
func (a *ApiRequestService) ProcessJRZQ7F1ARequest(params []byte) ([]byte, error) {
|
||||
func (a *ApiRequestService) ProcessJRZQ7F1ARequest(ctx context.Context, params []byte) ([]byte, error) {
|
||||
name := gjson.GetBytes(params, "name")
|
||||
idCard := gjson.GetBytes(params, "id_card")
|
||||
mobile := gjson.GetBytes(params, "mobile")
|
||||
@@ -1544,7 +1761,7 @@ func (a *ApiRequestService) ProcessJRZQ7F1ARequest(params []byte) ([]byte, error
|
||||
return nil, errors.New("api请求, JRZQ7F1A, 获取相关参数失败")
|
||||
}
|
||||
|
||||
resp, err := a.tianyuanapi.CallInterface("JRZQ7F1A", map[string]interface{}{
|
||||
resp, err := a.callTianyuanApiWithLog(ctx, "", "JRZQ7F1A", map[string]interface{}{
|
||||
"name": name.String(),
|
||||
"id_card": idCard.String(),
|
||||
"mobile_no": mobile.String(),
|
||||
@@ -1560,14 +1777,14 @@ func (a *ApiRequestService) ProcessJRZQ7F1ARequest(params []byte) ([]byte, error
|
||||
}
|
||||
|
||||
// ProcessIVYZ3P9MRequest 学历实时查询
|
||||
func (a *ApiRequestService) ProcessIVYZ3P9MRequest(params []byte) ([]byte, error) {
|
||||
func (a *ApiRequestService) ProcessIVYZ3P9MRequest(ctx context.Context, params []byte) ([]byte, error) {
|
||||
idCard := gjson.GetBytes(params, "id_card")
|
||||
name := gjson.GetBytes(params, "name")
|
||||
if !idCard.Exists() || !name.Exists() {
|
||||
return nil, errors.New("api请求, IVYZ3P9M, 获取相关参数失败")
|
||||
}
|
||||
|
||||
resp, err := a.tianyuanapi.CallInterface("IVYZ3P9M", map[string]interface{}{
|
||||
resp, err := a.callTianyuanApiWithLog(ctx, "", "IVYZ3P9M", map[string]interface{}{
|
||||
"id_card": idCard.String(),
|
||||
"name": name.String(),
|
||||
})
|
||||
@@ -1580,7 +1797,7 @@ func (a *ApiRequestService) ProcessIVYZ3P9MRequest(params []byte) ([]byte, error
|
||||
}
|
||||
|
||||
// ProcessJRZQ6F2ARequest 借贷申请
|
||||
func (a *ApiRequestService) ProcessJRZQ6F2ARequest(params []byte) ([]byte, error) {
|
||||
func (a *ApiRequestService) ProcessJRZQ6F2ARequest(ctx context.Context, params []byte) ([]byte, error) {
|
||||
name := gjson.GetBytes(params, "name")
|
||||
idCard := gjson.GetBytes(params, "id_card")
|
||||
mobile := gjson.GetBytes(params, "mobile")
|
||||
@@ -1588,7 +1805,7 @@ func (a *ApiRequestService) ProcessJRZQ6F2ARequest(params []byte) ([]byte, error
|
||||
return nil, errors.New("api请求, JRZQ6F2A, 获取相关参数失败")
|
||||
}
|
||||
|
||||
resp, err := a.tianyuanapi.CallInterface("JRZQ6F2A", map[string]interface{}{
|
||||
resp, err := a.callTianyuanApiWithLog(ctx, "", "JRZQ6F2A", map[string]interface{}{
|
||||
"name": name.String(),
|
||||
"id_card": idCard.String(),
|
||||
"mobile_no": mobile.String(),
|
||||
@@ -1600,3 +1817,27 @@ func (a *ApiRequestService) ProcessJRZQ6F2ARequest(params []byte) ([]byte, error
|
||||
|
||||
return convertTianyuanResponse(resp)
|
||||
}
|
||||
|
||||
// ProcessCOMBQN12Request 全能入职背调报告(标准版) - 组合包
|
||||
func (a *ApiRequestService) ProcessCOMBQN12Request(ctx context.Context, params []byte) ([]byte, error) {
|
||||
name := gjson.GetBytes(params, "name")
|
||||
idCard := gjson.GetBytes(params, "id_card")
|
||||
mobile := gjson.GetBytes(params, "mobile")
|
||||
if !name.Exists() || !idCard.Exists() || !mobile.Exists() {
|
||||
return nil, errors.New("api请求, COMBQN12, 获取相关参数失败")
|
||||
}
|
||||
|
||||
resp, err := a.callTianyuanApiWithLog(ctx, "", "COMBQN12", map[string]interface{}{
|
||||
"name": name.String(),
|
||||
"id_card": idCard.String(),
|
||||
"mobile_no": mobile.String(),
|
||||
"authorized": "1",
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 使用组合包响应转换函数,自动检测并转换
|
||||
return convertTianyuanBundleResponse(resp)
|
||||
}
|
||||
|
||||
216
app/main/api/internal/service/tianyuanapiCallLogService.go
Normal file
216
app/main/api/internal/service/tianyuanapiCallLogService.go
Normal file
@@ -0,0 +1,216 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"bdqr-server/app/main/model"
|
||||
"context"
|
||||
"database/sql"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/Masterminds/squirrel"
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
|
||||
// TianyuanapiCallLogService 天元API调用记录服务
|
||||
type TianyuanapiCallLogService struct {
|
||||
tianyuanapiCallLogModel model.TianyuanapiCallLogModel
|
||||
featureModel model.FeatureModel
|
||||
}
|
||||
|
||||
// NewTianyuanapiCallLogService 创建天元API调用记录服务
|
||||
func NewTianyuanapiCallLogService(
|
||||
tianyuanapiCallLogModel model.TianyuanapiCallLogModel,
|
||||
featureModel model.FeatureModel,
|
||||
) *TianyuanapiCallLogService {
|
||||
return &TianyuanapiCallLogService{
|
||||
tianyuanapiCallLogModel: tianyuanapiCallLogModel,
|
||||
featureModel: featureModel,
|
||||
}
|
||||
}
|
||||
|
||||
// CallLogOptions 调用记录选项
|
||||
type CallLogOptions struct {
|
||||
FeatureID string // 功能ID
|
||||
ApiID string // API标识(如:YYSYBE08)
|
||||
OrderID string // 订单ID(可选)
|
||||
QueryID string // 查询ID(可选)
|
||||
CallStatus int64 // 调用状态:0=失败,1=成功
|
||||
ResponseTime int64 // 响应耗时(毫秒)
|
||||
ErrorCode string // 错误码(失败时)
|
||||
ErrorMessage string // 错误信息(失败时)
|
||||
RequestParams interface{} // 请求参数(可选)
|
||||
ResponseData interface{} // 响应数据(可选)
|
||||
TransactionID string // 天元API流水号
|
||||
}
|
||||
|
||||
// RecordCall 记录天元API调用
|
||||
func (s *TianyuanapiCallLogService) RecordCall(ctx context.Context, opts CallLogOptions) error {
|
||||
// 1. 获取feature的成本价
|
||||
costPrice := 0.00
|
||||
if opts.CallStatus == 1 { // 只有成功才计算成本
|
||||
if opts.FeatureID == "" {
|
||||
logx.Infof("记录API调用时feature_id为空,api_id=%s,无法获取成本价", opts.ApiID)
|
||||
} else {
|
||||
feature, err := s.featureModel.FindOne(ctx, opts.FeatureID)
|
||||
if err == nil {
|
||||
costPrice = feature.CostPrice
|
||||
logx.Infof("记录API调用 - feature_id=%s, api_id=%s, cost_price=%f", opts.FeatureID, opts.ApiID, costPrice)
|
||||
} else {
|
||||
logx.Errorf("查询feature成本价失败,feature_id=%s, api_id=%s, err=%v", opts.FeatureID, opts.ApiID, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 2. 转换参数和响应为JSON字符串
|
||||
var requestParamsStr, responseDataStr *string
|
||||
if opts.RequestParams != nil {
|
||||
if bytes, err := json.Marshal(opts.RequestParams); err == nil {
|
||||
jsonStr := string(bytes)
|
||||
requestParamsStr = &jsonStr
|
||||
}
|
||||
}
|
||||
if opts.ResponseData != nil {
|
||||
// 只记录响应数据的前1000个字符,避免存储过大
|
||||
if bytes, err := json.Marshal(opts.ResponseData); err == nil {
|
||||
jsonStr := string(bytes)
|
||||
if len(jsonStr) > 1000 {
|
||||
jsonStr = jsonStr[:1000] + "...[truncated]"
|
||||
}
|
||||
responseDataStr = &jsonStr
|
||||
}
|
||||
}
|
||||
|
||||
// 3. 构建调用记录
|
||||
callTime := time.Now()
|
||||
deleteTime := sql.NullTime{}
|
||||
callLog := &model.TianyuanapiCallLog{
|
||||
FeatureId: opts.FeatureID,
|
||||
ApiId: opts.ApiID,
|
||||
OrderId: sql.NullString{},
|
||||
QueryId: sql.NullString{},
|
||||
CallStatus: opts.CallStatus,
|
||||
CallTime: callTime,
|
||||
ResponseTime: sql.NullInt64{},
|
||||
CostPrice: costPrice,
|
||||
ErrorCode: sql.NullString{},
|
||||
ErrorMessage: sql.NullString{},
|
||||
RequestParams: sql.NullString{},
|
||||
ResponseData: sql.NullString{},
|
||||
TransactionId: sql.NullString{},
|
||||
CreateTime: callTime,
|
||||
UpdateTime: callTime,
|
||||
DeleteTime: deleteTime,
|
||||
DelState: 0,
|
||||
Version: 0,
|
||||
}
|
||||
|
||||
// 4. 填充可选字段
|
||||
if opts.OrderID != "" {
|
||||
callLog.OrderId = sql.NullString{String: opts.OrderID, Valid: true}
|
||||
}
|
||||
if opts.QueryID != "" {
|
||||
callLog.QueryId = sql.NullString{String: opts.QueryID, Valid: true}
|
||||
}
|
||||
if opts.ResponseTime > 0 {
|
||||
callLog.ResponseTime = sql.NullInt64{Int64: opts.ResponseTime, Valid: true}
|
||||
}
|
||||
if opts.ErrorCode != "" {
|
||||
callLog.ErrorCode = sql.NullString{String: opts.ErrorCode, Valid: true}
|
||||
}
|
||||
if opts.ErrorMessage != "" {
|
||||
callLog.ErrorMessage = sql.NullString{String: opts.ErrorMessage, Valid: true}
|
||||
}
|
||||
if requestParamsStr != nil {
|
||||
callLog.RequestParams = sql.NullString{String: *requestParamsStr, Valid: true}
|
||||
}
|
||||
if responseDataStr != nil {
|
||||
callLog.ResponseData = sql.NullString{String: *responseDataStr, Valid: true}
|
||||
}
|
||||
if opts.TransactionID != "" {
|
||||
callLog.TransactionId = sql.NullString{String: opts.TransactionID, Valid: true}
|
||||
}
|
||||
|
||||
// 5. 插入记录
|
||||
_, err := s.tianyuanapiCallLogModel.Insert(ctx, nil, callLog)
|
||||
if err != nil {
|
||||
logx.Errorf("插入天元API调用记录失败,feature_id=%s, api_id=%s, err=%v", opts.FeatureID, opts.ApiID, err)
|
||||
return fmt.Errorf("插入调用记录失败: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetStatistics 获取统计信息
|
||||
type StatisticsFilter struct {
|
||||
FeatureID string // 功能ID
|
||||
ApiID string // API标识
|
||||
StartDate time.Time // 开始日期
|
||||
EndDate time.Time // 结束日期
|
||||
}
|
||||
|
||||
// Statistics 统计信息
|
||||
type Statistics struct {
|
||||
TotalCalls int64 // 总调用次数
|
||||
SuccessCalls int64 // 成功次数
|
||||
FailedCalls int64 // 失败次数
|
||||
TotalCost float64 // 总成本(成功调用的成本之和)
|
||||
}
|
||||
|
||||
// GetStatistics 获取统计信息
|
||||
func (s *TianyuanapiCallLogService) GetStatistics(ctx context.Context, filter StatisticsFilter) (*Statistics, error) {
|
||||
builder := s.tianyuanapiCallLogModel.SelectBuilder()
|
||||
|
||||
// 添加过滤条件
|
||||
if filter.FeatureID != "" {
|
||||
builder = builder.Where(squirrel.Eq{"feature_id": filter.FeatureID})
|
||||
}
|
||||
if filter.ApiID != "" {
|
||||
builder = builder.Where(squirrel.Eq{"api_id": filter.ApiID})
|
||||
}
|
||||
if !filter.StartDate.IsZero() {
|
||||
builder = builder.Where(squirrel.GtOrEq{"call_time": filter.StartDate})
|
||||
logx.Infof("API成本统计 - 开始时间: %v", filter.StartDate)
|
||||
}
|
||||
if !filter.EndDate.IsZero() {
|
||||
builder = builder.Where(squirrel.Lt{"call_time": filter.EndDate})
|
||||
logx.Infof("API成本统计 - 结束时间: %v", filter.EndDate)
|
||||
}
|
||||
|
||||
// 统计总调用次数
|
||||
totalCalls, err := s.tianyuanapiCallLogModel.FindCount(ctx, builder, "id")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("统计总调用次数失败: %w", err)
|
||||
}
|
||||
logx.Infof("API成本统计 - 总调用次数: %d", totalCalls)
|
||||
|
||||
// 统计成功次数
|
||||
successBuilder := builder.Where(squirrel.Eq{"call_status": 1})
|
||||
successCalls, err := s.tianyuanapiCallLogModel.FindCount(ctx, successBuilder, "id")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("统计成功次数失败: %w", err)
|
||||
}
|
||||
logx.Infof("API成本统计 - 成功调用次数: %d", successCalls)
|
||||
|
||||
// 统计失败次数
|
||||
failedCalls := totalCalls - successCalls
|
||||
|
||||
// 统计总成本(仅成功调用)
|
||||
// 先打印SQL以便调试(复制builder避免影响后续查询)
|
||||
debugBuilder := successBuilder
|
||||
query, values, _ := debugBuilder.Columns("IFNULL(SUM(cost_price),0)").Where("del_state = ?", 0).ToSql()
|
||||
logx.Infof("API成本统计 - SQL: %s, 参数: %v", query, values)
|
||||
|
||||
totalCost, err := s.tianyuanapiCallLogModel.FindSum(ctx, successBuilder, "cost_price")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("统计总成本失败: %w", err)
|
||||
}
|
||||
logx.Infof("API成本统计 - 总成本: %f", totalCost)
|
||||
|
||||
return &Statistics{
|
||||
TotalCalls: totalCalls,
|
||||
SuccessCalls: successCalls,
|
||||
FailedCalls: failedCalls,
|
||||
TotalCost: totalCost,
|
||||
}, nil
|
||||
}
|
||||
570
app/main/api/internal/service/whitelistService.go
Normal file
570
app/main/api/internal/service/whitelistService.go
Normal file
@@ -0,0 +1,570 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"strings"
|
||||
|
||||
"bdqr-server/app/main/api/internal/config"
|
||||
"bdqr-server/app/main/model"
|
||||
"bdqr-server/common/xerr"
|
||||
"bdqr-server/pkg/lzkit/crypto"
|
||||
"bdqr-server/pkg/lzkit/lzUtils"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
"github.com/zeromicro/go-zero/core/stores/sqlx"
|
||||
)
|
||||
|
||||
// WhitelistService 白名单领域服务,集中处理白名单相关的业务逻辑
|
||||
type WhitelistService struct {
|
||||
config config.Config
|
||||
UserFeatureWhitelistModel model.UserFeatureWhitelistModel
|
||||
WhitelistOrderModel model.WhitelistOrderModel
|
||||
WhitelistOrderItemModel model.WhitelistOrderItemModel
|
||||
QueryModel model.QueryModel
|
||||
FeatureModel model.FeatureModel
|
||||
}
|
||||
|
||||
// NewWhitelistService 创建白名单服务
|
||||
func NewWhitelistService(
|
||||
c config.Config,
|
||||
userFeatureWhitelistModel model.UserFeatureWhitelistModel,
|
||||
whitelistOrderModel model.WhitelistOrderModel,
|
||||
whitelistOrderItemModel model.WhitelistOrderItemModel,
|
||||
queryModel model.QueryModel,
|
||||
featureModel model.FeatureModel,
|
||||
) *WhitelistService {
|
||||
return &WhitelistService{
|
||||
config: c,
|
||||
UserFeatureWhitelistModel: userFeatureWhitelistModel,
|
||||
WhitelistOrderModel: whitelistOrderModel,
|
||||
WhitelistOrderItemModel: whitelistOrderItemModel,
|
||||
QueryModel: queryModel,
|
||||
FeatureModel: featureModel,
|
||||
}
|
||||
}
|
||||
|
||||
// EnsureFreeWhitelist 免费下架:如果还没有生效白名单,则创建一条免费白名单记录
|
||||
func (s *WhitelistService) EnsureFreeWhitelist(
|
||||
ctx context.Context,
|
||||
session sqlx.Session,
|
||||
idCard string,
|
||||
feature *model.Feature,
|
||||
userId string,
|
||||
orderId string,
|
||||
) error {
|
||||
// 检查是否已存在生效白名单
|
||||
builder := s.UserFeatureWhitelistModel.SelectBuilder().
|
||||
Where("id_card = ? AND feature_id = ?", idCard, feature.Id)
|
||||
records, err := s.UserFeatureWhitelistModel.FindAll(ctx, builder, "")
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "查询白名单记录失败")
|
||||
}
|
||||
for _, r := range records {
|
||||
if r.Status == 1 {
|
||||
// 已经下架,直接返回
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
wl := &model.UserFeatureWhitelist{
|
||||
Id: uuid.NewString(),
|
||||
IdCard: idCard,
|
||||
FeatureId: feature.Id,
|
||||
FeatureApiId: feature.ApiId,
|
||||
UserId: userId,
|
||||
OrderId: lzUtils.StringToNullString(orderId),
|
||||
WhitelistOrderId: lzUtils.StringToNullString(""),
|
||||
Amount: 0,
|
||||
Status: 1,
|
||||
}
|
||||
|
||||
_, err = s.UserFeatureWhitelistModel.Insert(ctx, session, wl)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "创建免费白名单记录失败")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// CreateWhitelistByPaidOrder 根据已支付的白名单订单,创建对应的白名单记录
|
||||
func (s *WhitelistService) CreateWhitelistByPaidOrder(
|
||||
ctx context.Context,
|
||||
session sqlx.Session,
|
||||
order *model.Order,
|
||||
whitelistOrder *model.WhitelistOrder,
|
||||
) error {
|
||||
if whitelistOrder.Status != 2 {
|
||||
// 只处理已支付状态
|
||||
return nil
|
||||
}
|
||||
|
||||
itemBuilder := s.WhitelistOrderItemModel.SelectBuilder().
|
||||
Where("order_id = ?", whitelistOrder.Id)
|
||||
items, err := s.WhitelistOrderItemModel.FindAll(ctx, itemBuilder, "")
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "查询白名单订单明细失败")
|
||||
}
|
||||
|
||||
for _, item := range items {
|
||||
wl := &model.UserFeatureWhitelist{
|
||||
Id: uuid.NewString(),
|
||||
IdCard: whitelistOrder.IdCard,
|
||||
FeatureId: item.FeatureId,
|
||||
FeatureApiId: item.FeatureApiId,
|
||||
UserId: whitelistOrder.UserId,
|
||||
OrderId: lzUtils.StringToNullString(order.Id),
|
||||
WhitelistOrderId: lzUtils.StringToNullString(whitelistOrder.Id),
|
||||
Amount: item.Price,
|
||||
Status: 1,
|
||||
}
|
||||
if _, err := s.UserFeatureWhitelistModel.Insert(ctx, session, wl); err != nil {
|
||||
return errors.Wrap(err, "创建白名单记录失败")
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetWhitelistedFeatureApisByIdCard 获取某个身份证号已下架的 feature_api_id 集合
|
||||
func (s *WhitelistService) GetWhitelistedFeatureApisByIdCard(
|
||||
ctx context.Context,
|
||||
idCard string,
|
||||
) (map[string]bool, error) {
|
||||
result := make(map[string]bool)
|
||||
if s == nil {
|
||||
return result, nil
|
||||
}
|
||||
if idCard == "" {
|
||||
return result, nil
|
||||
}
|
||||
|
||||
builder := s.UserFeatureWhitelistModel.SelectBuilder().
|
||||
Where("id_card = ? AND status = ?", idCard, 1)
|
||||
list, err := s.UserFeatureWhitelistModel.FindAll(ctx, builder, "")
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "查询白名单失败")
|
||||
}
|
||||
|
||||
for _, wl := range list {
|
||||
result[wl.FeatureApiId] = true
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// CheckWhitelistExists 检查指定身份证号和模块是否已有生效的白名单记录
|
||||
func (s *WhitelistService) CheckWhitelistExists(
|
||||
ctx context.Context,
|
||||
idCard string,
|
||||
featureId string,
|
||||
) (bool, error) {
|
||||
if idCard == "" || featureId == "" {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
builder := s.UserFeatureWhitelistModel.SelectBuilder().
|
||||
Where("id_card = ? AND feature_id = ? AND status = ?", idCard, featureId, 1)
|
||||
list, err := s.UserFeatureWhitelistModel.FindAll(ctx, builder, "")
|
||||
if err != nil {
|
||||
return false, errors.Wrap(err, "查询白名单记录失败")
|
||||
}
|
||||
|
||||
return len(list) > 0, nil
|
||||
}
|
||||
|
||||
// ProcessOfflineFeature 统一下架处理:处理免费下架或检查付费下架
|
||||
// 返回:needPay(是否需要支付), amount(金额), whitelistCreated(是否已创建白名单)
|
||||
func (s *WhitelistService) ProcessOfflineFeature(
|
||||
ctx context.Context,
|
||||
session sqlx.Session,
|
||||
idCard string,
|
||||
featureApiId string,
|
||||
userId string,
|
||||
orderId string,
|
||||
) (needPay bool, amount float64, whitelistCreated bool, err error) {
|
||||
// 1. 提取主模块ID并查询feature信息
|
||||
mainApiId := s.extractMainApiId(featureApiId)
|
||||
feature, err := s.getFeatureByApiId(ctx, mainApiId)
|
||||
if err != nil {
|
||||
return false, 0, false, err
|
||||
}
|
||||
|
||||
// 2. 不支持下架的模块:whitelist_price < 0 表示该模块不开放下架功能
|
||||
if feature.WhitelistPrice < 0 {
|
||||
return false, 0, false, errors.Wrapf(xerr.NewErrMsg("该模块不支持下架"), "")
|
||||
}
|
||||
|
||||
// 3. 检查是否已有白名单
|
||||
exists, err := s.CheckWhitelistExists(ctx, idCard, feature.Id)
|
||||
if err != nil {
|
||||
return false, 0, false, err
|
||||
}
|
||||
if exists {
|
||||
// 已有白名单,直接返回成功
|
||||
return false, 0, true, nil
|
||||
}
|
||||
|
||||
price := feature.WhitelistPrice
|
||||
|
||||
// 4. 免费下架:直接创建白名单记录(whitelist_price = 0)
|
||||
if price <= 0 {
|
||||
if err := s.EnsureFreeWhitelist(ctx, session, idCard, feature, userId, orderId); err != nil {
|
||||
return false, 0, false, err
|
||||
}
|
||||
return false, 0, true, nil
|
||||
}
|
||||
|
||||
// 5. 付费下架:检查是否已有支付成功的订单
|
||||
paidOrderId, err := s.findPaidWhitelistOrder(ctx, userId, idCard, feature.Id)
|
||||
if err != nil {
|
||||
return false, 0, false, err
|
||||
}
|
||||
|
||||
// 6. 如果已有支付成功订单,补创建白名单记录
|
||||
if paidOrderId != "" {
|
||||
if err := s.createWhitelistFromPaidOrder(ctx, session, idCard, feature, userId, orderId, paidOrderId, price); err != nil {
|
||||
return false, 0, false, err
|
||||
}
|
||||
return false, price, true, nil
|
||||
}
|
||||
|
||||
// 7. 需要支付
|
||||
return true, price, false, nil
|
||||
}
|
||||
|
||||
// extractMainApiId 提取主模块ID(去掉下划线后的部分)
|
||||
func (s *WhitelistService) extractMainApiId(featureApiId string) string {
|
||||
if idx := strings.Index(featureApiId, "_"); idx > 0 {
|
||||
return featureApiId[:idx]
|
||||
}
|
||||
return featureApiId
|
||||
}
|
||||
|
||||
// getFeatureByApiId 根据API ID查询feature信息
|
||||
func (s *WhitelistService) getFeatureByApiId(ctx context.Context, apiId string) (*model.Feature, error) {
|
||||
feature, err := s.FeatureModel.FindOneByApiId(ctx, apiId)
|
||||
if err != nil {
|
||||
if errors.Is(err, model.ErrNotFound) {
|
||||
return nil, errors.Wrap(err, "模块不存在")
|
||||
}
|
||||
return nil, errors.Wrap(err, "查询模块信息失败")
|
||||
}
|
||||
return feature, nil
|
||||
}
|
||||
|
||||
// findPaidWhitelistOrder 查找已支付的白名单订单中是否包含指定feature
|
||||
// 返回:paidOrderId(如果找到已支付订单),error
|
||||
func (s *WhitelistService) findPaidWhitelistOrder(
|
||||
ctx context.Context,
|
||||
userId string,
|
||||
idCard string,
|
||||
featureId string,
|
||||
) (string, error) {
|
||||
orderBuilder := s.WhitelistOrderModel.SelectBuilder().
|
||||
Where("user_id = ? AND id_card = ? AND status = ?", userId, idCard, 2) // 2表示已支付
|
||||
orders, err := s.WhitelistOrderModel.FindAll(ctx, orderBuilder, "")
|
||||
if err != nil {
|
||||
return "", errors.Wrap(err, "查询白名单订单失败")
|
||||
}
|
||||
|
||||
// 查找已支付订单中是否包含该feature
|
||||
for _, order := range orders {
|
||||
itemBuilder := s.WhitelistOrderItemModel.SelectBuilder().
|
||||
Where("order_id = ? AND feature_id = ?", order.Id, featureId)
|
||||
items, itemErr := s.WhitelistOrderItemModel.FindAll(ctx, itemBuilder, "")
|
||||
if itemErr != nil {
|
||||
return "", errors.Wrap(itemErr, "查询白名单订单明细失败")
|
||||
}
|
||||
if len(items) > 0 {
|
||||
return order.Id, nil
|
||||
}
|
||||
}
|
||||
|
||||
return "", nil
|
||||
}
|
||||
|
||||
// createWhitelistFromPaidOrder 根据已支付订单创建白名单记录
|
||||
func (s *WhitelistService) createWhitelistFromPaidOrder(
|
||||
ctx context.Context,
|
||||
session sqlx.Session,
|
||||
idCard string,
|
||||
feature *model.Feature,
|
||||
userId string,
|
||||
orderId string,
|
||||
paidOrderId string,
|
||||
price float64,
|
||||
) error {
|
||||
wl := &model.UserFeatureWhitelist{
|
||||
Id: uuid.NewString(),
|
||||
IdCard: idCard,
|
||||
FeatureId: feature.Id,
|
||||
FeatureApiId: feature.ApiId,
|
||||
UserId: userId,
|
||||
OrderId: lzUtils.StringToNullString(orderId),
|
||||
WhitelistOrderId: lzUtils.StringToNullString(paidOrderId),
|
||||
Amount: price,
|
||||
Status: 1, // 生效
|
||||
}
|
||||
if _, err := s.UserFeatureWhitelistModel.Insert(ctx, session, wl); err != nil {
|
||||
return errors.Wrap(err, "根据已支付订单创建白名单记录失败")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeleteFeatureFromQueryData 从报告数据中删除指定模块的数据
|
||||
// queryId: 查询记录ID(Query表的ID)
|
||||
// featureApiId: 要删除的模块API标识
|
||||
func (s *WhitelistService) DeleteFeatureFromQueryData(
|
||||
ctx context.Context,
|
||||
session sqlx.Session,
|
||||
queryId string,
|
||||
featureApiId string,
|
||||
) error {
|
||||
// 1. 获取查询记录
|
||||
queryModel, err := s.getQueryModel(ctx, queryId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if queryModel == nil {
|
||||
// 报告不存在或数据为空,直接返回成功
|
||||
return nil
|
||||
}
|
||||
|
||||
// 2. 解密并解析报告数据
|
||||
mainApiId := s.extractMainApiId(featureApiId)
|
||||
dataArray, key, err := s.decryptQueryData(queryModel)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 3. 清空对应模块的数据(将 data 字段设置为 null)
|
||||
modifiedArray, hasModified := s.clearFeatureData(dataArray, mainApiId)
|
||||
if !hasModified {
|
||||
logx.Infof("删除报告数据:查询记录 %s 中未找到模块 %s 的数据,跳过删除", queryId, featureApiId)
|
||||
return nil
|
||||
}
|
||||
|
||||
// 4. 重新加密并更新数据库
|
||||
if err := s.updateQueryData(ctx, session, queryModel, modifiedArray, key); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
logx.Infof("删除报告数据成功:查询记录 %s,模块 %s,已将对应模块的 data 字段设置为 null", queryId, featureApiId)
|
||||
return nil
|
||||
}
|
||||
|
||||
// getQueryModel 获取查询记录,如果不存在或数据为空则返回nil
|
||||
func (s *WhitelistService) getQueryModel(ctx context.Context, queryId string) (*model.Query, error) {
|
||||
queryModel, err := s.QueryModel.FindOne(ctx, queryId)
|
||||
if err != nil {
|
||||
if errors.Is(err, model.ErrNotFound) {
|
||||
logx.Infof("删除报告数据:查询记录 %s 不存在,跳过删除", queryId)
|
||||
return nil, nil
|
||||
}
|
||||
return nil, errors.Wrap(err, "查询报告记录失败")
|
||||
}
|
||||
|
||||
// 如果报告数据为空,直接返回
|
||||
if !queryModel.QueryData.Valid || queryModel.QueryData.String == "" {
|
||||
logx.Infof("删除报告数据:查询记录 %s 对应的报告数据为空,跳过删除", queryId)
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
return queryModel, nil
|
||||
}
|
||||
|
||||
// decryptQueryData 解密并解析报告数据
|
||||
func (s *WhitelistService) decryptQueryData(queryModel *model.Query) ([]map[string]interface{}, []byte, error) {
|
||||
// 获取加密密钥
|
||||
secretKey := s.config.Encrypt.SecretKey
|
||||
key, decodeErr := hex.DecodeString(secretKey)
|
||||
if decodeErr != nil {
|
||||
return nil, nil, errors.Wrap(decodeErr, "获取AES密钥失败")
|
||||
}
|
||||
|
||||
// 解密报告数据
|
||||
decryptedData, decryptErr := crypto.AesDecrypt(queryModel.QueryData.String, key)
|
||||
if decryptErr != nil {
|
||||
return nil, nil, errors.Wrap(decryptErr, "解密报告数据失败")
|
||||
}
|
||||
|
||||
// 解析JSON数组
|
||||
var dataArray []map[string]interface{}
|
||||
unmarshalErr := json.Unmarshal(decryptedData, &dataArray)
|
||||
if unmarshalErr != nil {
|
||||
return nil, nil, errors.Wrap(unmarshalErr, "解析报告数据失败")
|
||||
}
|
||||
|
||||
return dataArray, key, nil
|
||||
}
|
||||
|
||||
// clearFeatureData 清空指定模块的数据(将 data 字段设置为 null)
|
||||
// 返回修改后的数组和是否进行了修改
|
||||
func (s *WhitelistService) clearFeatureData(dataArray []map[string]interface{}, mainApiId string) ([]map[string]interface{}, bool) {
|
||||
modifiedArray := make([]map[string]interface{}, 0, len(dataArray))
|
||||
hasModified := false
|
||||
|
||||
for _, item := range dataArray {
|
||||
// 深拷贝 item,避免修改原数据
|
||||
newItem := make(map[string]interface{})
|
||||
for k, v := range item {
|
||||
newItem[k] = v
|
||||
}
|
||||
|
||||
apiID, ok := item["apiID"].(string)
|
||||
if !ok {
|
||||
// 如果apiID不存在或类型不对,保留原样
|
||||
modifiedArray = append(modifiedArray, newItem)
|
||||
continue
|
||||
}
|
||||
|
||||
// 提取主模块ID进行比较
|
||||
itemMainApiId := s.extractMainApiId(apiID)
|
||||
|
||||
// 如果主模块ID匹配,将 data 字段设置为 null
|
||||
if itemMainApiId == mainApiId {
|
||||
newItem["data"] = nil
|
||||
hasModified = true
|
||||
}
|
||||
|
||||
modifiedArray = append(modifiedArray, newItem)
|
||||
}
|
||||
|
||||
return modifiedArray, hasModified
|
||||
}
|
||||
|
||||
// updateQueryData 重新加密并更新数据库
|
||||
func (s *WhitelistService) updateQueryData(
|
||||
ctx context.Context,
|
||||
session sqlx.Session,
|
||||
queryModel *model.Query,
|
||||
filteredArray []map[string]interface{},
|
||||
key []byte,
|
||||
) error {
|
||||
// 重新序列化
|
||||
filteredBytes, marshalErr := json.Marshal(filteredArray)
|
||||
if marshalErr != nil {
|
||||
return errors.Wrap(marshalErr, "序列化过滤后的报告数据失败")
|
||||
}
|
||||
|
||||
// 重新加密
|
||||
encryptedData, encryptErr := crypto.AesEncrypt(filteredBytes, key)
|
||||
if encryptErr != nil {
|
||||
return errors.Wrap(encryptErr, "加密过滤后的报告数据失败")
|
||||
}
|
||||
|
||||
// 更新数据库
|
||||
queryModel.QueryData = sql.NullString{
|
||||
String: encryptedData,
|
||||
Valid: true,
|
||||
}
|
||||
updateErr := s.QueryModel.UpdateWithVersion(ctx, session, queryModel)
|
||||
if updateErr != nil {
|
||||
return errors.Wrap(updateErr, "更新报告数据失败")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// CheckQueryDataContainsFeature 检查报告数据中是否包含指定的模块
|
||||
// 返回 true 表示包含该模块,false 表示不包含(已删除)
|
||||
func (s *WhitelistService) CheckQueryDataContainsFeature(
|
||||
ctx context.Context,
|
||||
queryId string,
|
||||
featureApiId string,
|
||||
) (bool, error) {
|
||||
// 1. 获取查询记录
|
||||
queryModel, err := s.getQueryModel(ctx, queryId)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
if queryModel == nil {
|
||||
// 报告不存在,认为数据已删除
|
||||
return false, nil
|
||||
}
|
||||
|
||||
// 2. 解密并解析报告数据
|
||||
mainApiId := s.extractMainApiId(featureApiId)
|
||||
dataArray, _, err := s.decryptQueryData(queryModel)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
// 3. 检查数据中是否包含该模块(且 data 不为 null)
|
||||
for _, item := range dataArray {
|
||||
apiID, ok := item["apiID"].(string)
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
// 提取主模块ID进行比较
|
||||
itemMainApiId := s.extractMainApiId(apiID)
|
||||
if itemMainApiId == mainApiId {
|
||||
// 找到了该模块,检查 data 字段
|
||||
dataValue, exists := item["data"]
|
||||
if !exists || dataValue == nil {
|
||||
// data 字段不存在或为 null,认为数据已删除
|
||||
return false, nil
|
||||
}
|
||||
// data 字段存在且不为 null,认为数据存在
|
||||
return true, nil
|
||||
}
|
||||
}
|
||||
|
||||
// 未找到该模块的数据,说明已删除
|
||||
return false, nil
|
||||
}
|
||||
|
||||
// ProcessPaidWhitelistOrder 处理已支付的白名单订单:创建白名单记录并删除报告数据
|
||||
// order: 支付订单(Order表)
|
||||
// whitelistOrder: 白名单订单(WhitelistOrder表)
|
||||
func (s *WhitelistService) ProcessPaidWhitelistOrder(
|
||||
ctx context.Context,
|
||||
session sqlx.Session,
|
||||
order *model.Order,
|
||||
whitelistOrder *model.WhitelistOrder,
|
||||
) error {
|
||||
if whitelistOrder.Status != 2 {
|
||||
// 只处理已支付状态
|
||||
return nil
|
||||
}
|
||||
|
||||
// 查询订单明细
|
||||
itemBuilder := s.WhitelistOrderItemModel.SelectBuilder().
|
||||
Where("order_id = ?", whitelistOrder.Id)
|
||||
items, err := s.WhitelistOrderItemModel.FindAll(ctx, itemBuilder, "")
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "查询白名单订单明细失败")
|
||||
}
|
||||
|
||||
// 为每个明细创建白名单记录并删除报告数据
|
||||
for _, item := range items {
|
||||
// 创建白名单记录
|
||||
wl := &model.UserFeatureWhitelist{
|
||||
Id: uuid.NewString(),
|
||||
IdCard: whitelistOrder.IdCard,
|
||||
FeatureId: item.FeatureId,
|
||||
FeatureApiId: item.FeatureApiId,
|
||||
UserId: whitelistOrder.UserId,
|
||||
OrderId: lzUtils.StringToNullString(""), // 查询订单ID,如果有的话会在后续步骤中设置
|
||||
WhitelistOrderId: lzUtils.StringToNullString(whitelistOrder.Id),
|
||||
Amount: item.Price,
|
||||
Status: 1, // 生效
|
||||
}
|
||||
if _, err := s.UserFeatureWhitelistModel.Insert(ctx, session, wl); err != nil {
|
||||
return errors.Wrap(err, "创建白名单记录失败")
|
||||
}
|
||||
|
||||
// 尝试删除报告数据
|
||||
// 注意:由于支付回调时可能不知道具体的查询订单ID,这里先尝试根据 id_card 查找
|
||||
// 如果找不到对应的报告,就跳过删除步骤(不影响主流程)
|
||||
// 实际的报告数据删除应该在 OfflineFeature 接口中完成(如果提供了 orderId)
|
||||
// 这里暂时不删除,因为无法确定是哪个具体的查询订单
|
||||
logx.Infof("白名单订单支付成功:订单 %s,模块 %s,已创建白名单记录。如需删除报告数据,请在 OfflineFeature 接口中提供查询订单ID", whitelistOrder.OrderNo, item.FeatureApiId)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user