848 lines
29 KiB
Go
848 lines
29 KiB
Go
package query
|
||
|
||
import (
|
||
"context"
|
||
"crypto/rand"
|
||
"database/sql"
|
||
"encoding/hex"
|
||
"encoding/json"
|
||
"fmt"
|
||
"in-server/app/main/api/internal/service"
|
||
"in-server/common/ctxdata"
|
||
"in-server/common/xerr"
|
||
"in-server/pkg/lzkit/crypto"
|
||
"in-server/pkg/lzkit/validator"
|
||
"os"
|
||
"strconv"
|
||
"sync/atomic"
|
||
"time"
|
||
|
||
"github.com/google/uuid"
|
||
"github.com/pkg/errors"
|
||
"github.com/zeromicro/go-zero/core/stores/redis"
|
||
|
||
"in-server/app/main/api/internal/svc"
|
||
"in-server/app/main/api/internal/types"
|
||
"in-server/app/main/model"
|
||
|
||
"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)
|
||
}
|
||
|
||
var productProcessors = map[string]func(*QueryServiceLogic, *types.QueryServiceReq) (*types.QueryServiceResp, error){
|
||
"marriage": (*QueryServiceLogic).ProcessMarriageLogic,
|
||
"homeservice": (*QueryServiceLogic).ProcessHomeServiceLogic,
|
||
"riskassessment": (*QueryServiceLogic).ProcessRiskAssessmentLogic,
|
||
"companyinfo": (*QueryServiceLogic).ProcessCompanyInfoLogic,
|
||
"rentalinfo": (*QueryServiceLogic).ProcessRentalInfoLogic,
|
||
"preloanbackgroundcheck": (*QueryServiceLogic).ProcessPreLoanBackgroundCheckLogic,
|
||
"backgroundcheck": (*QueryServiceLogic).ProcessBackgroundCheckLogic,
|
||
"personalData": (*QueryServiceLogic).ProcessPersonalDataLogic,
|
||
"consumerFinanceReport": (*QueryServiceLogic).ProcessConsumerFinanceReportLogic,
|
||
}
|
||
|
||
func (l *QueryServiceLogic) PreprocessLogic(req *types.QueryServiceReq, product string) (*types.QueryServiceResp, error) {
|
||
if processor, exists := productProcessors[product]; exists {
|
||
return processor(l, req) // 调用对应的处理函数
|
||
}
|
||
return nil, errors.New("未找到相应的处理程序")
|
||
}
|
||
func (l *QueryServiceLogic) ProcessMarriageLogic(req *types.QueryServiceReq) (*types.QueryServiceResp, error) {
|
||
|
||
// AES解密
|
||
decryptData, DecryptDataErr := l.DecryptData(req.Data)
|
||
if DecryptDataErr != nil {
|
||
return nil, DecryptDataErr
|
||
}
|
||
|
||
// 验证参数
|
||
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)
|
||
}
|
||
|
||
// 验证验证码
|
||
verifyCodeErr := l.VerifyCode(data.Mobile, data.Code)
|
||
if verifyCodeErr != nil {
|
||
return nil, verifyCodeErr
|
||
}
|
||
|
||
// 验证三要素
|
||
verifyErr := l.Verify(data.Name, data.IDCard, data.Mobile)
|
||
if verifyErr != nil {
|
||
return nil, verifyErr
|
||
}
|
||
|
||
// 缓存
|
||
params := map[string]interface{}{
|
||
"name": data.Name,
|
||
"id_card": data.IDCard,
|
||
"mobile": data.Mobile,
|
||
}
|
||
userID, err := l.GetOrCreateUser()
|
||
if err != nil {
|
||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 处理用户失败: %v", err)
|
||
}
|
||
cacheNo, cacheDataErr := l.CacheData(params, "marriage", userID)
|
||
if cacheDataErr != nil {
|
||
return nil, cacheDataErr
|
||
}
|
||
token, err := l.svcCtx.UserService.GeneralUserToken(l.ctx, userID)
|
||
if err != nil {
|
||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 生成token失败 : %v", err)
|
||
}
|
||
|
||
// 获取当前时间戳
|
||
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
|
||
}
|
||
|
||
// 处理家政服务相关逻辑
|
||
func (l *QueryServiceLogic) ProcessHomeServiceLogic(req *types.QueryServiceReq) (*types.QueryServiceResp, error) {
|
||
|
||
// AES解密
|
||
decryptData, DecryptDataErr := l.DecryptData(req.Data)
|
||
if DecryptDataErr != nil {
|
||
return nil, DecryptDataErr
|
||
}
|
||
|
||
// 验证参数
|
||
var data types.HomeServiceReq
|
||
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)
|
||
}
|
||
|
||
// 验证验证码
|
||
verifyCodeErr := l.VerifyCode(data.Mobile, data.Code)
|
||
if verifyCodeErr != nil {
|
||
return nil, verifyCodeErr
|
||
}
|
||
|
||
// 验证三要素
|
||
verifyErr := l.Verify(data.Name, data.IDCard, data.Mobile)
|
||
if verifyErr != nil {
|
||
return nil, verifyErr
|
||
}
|
||
|
||
// 缓存
|
||
params := map[string]interface{}{
|
||
"name": data.Name,
|
||
"id_card": data.IDCard,
|
||
"mobile": data.Mobile,
|
||
}
|
||
userID, err := l.GetOrCreateUser()
|
||
if err != nil {
|
||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 处理用户失败: %v", err)
|
||
}
|
||
cacheNo, cacheDataErr := l.CacheData(params, "homeservice", userID)
|
||
if cacheDataErr != nil {
|
||
return nil, cacheDataErr
|
||
}
|
||
|
||
token, err := l.svcCtx.UserService.GeneralUserToken(l.ctx, userID)
|
||
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
|
||
}
|
||
|
||
// 处理风险评估相关逻辑
|
||
func (l *QueryServiceLogic) ProcessRiskAssessmentLogic(req *types.QueryServiceReq) (*types.QueryServiceResp, error) {
|
||
|
||
// AES解密
|
||
decryptData, DecryptDataErr := l.DecryptData(req.Data)
|
||
if DecryptDataErr != nil {
|
||
return nil, DecryptDataErr
|
||
}
|
||
|
||
// 验证参数
|
||
var data types.RiskAssessmentReq
|
||
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)
|
||
}
|
||
|
||
// 验证三要素
|
||
verifyErr := l.Verify(data.Name, data.IDCard, data.Mobile)
|
||
if verifyErr != nil {
|
||
return nil, verifyErr
|
||
}
|
||
|
||
// 缓存
|
||
params := map[string]interface{}{
|
||
"name": data.Name,
|
||
"id_card": data.IDCard,
|
||
"mobile": data.Mobile,
|
||
}
|
||
userID, err := l.GetOrCreateUser()
|
||
if err != nil {
|
||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 处理用户失败: %v", err)
|
||
}
|
||
cacheNo, cacheDataErr := l.CacheData(params, "riskassessment", userID)
|
||
if cacheDataErr != nil {
|
||
return nil, cacheDataErr
|
||
}
|
||
|
||
// 立即创建订单并调用 apirequest 出结果(无需支付)
|
||
orderId, orderNo, apiErr := l.createOrderAndRunApiRequest(userID, cacheNo, params, "riskassessment")
|
||
if apiErr != nil {
|
||
return nil, apiErr
|
||
}
|
||
|
||
token, err := l.svcCtx.UserService.GeneralUserToken(l.ctx, userID)
|
||
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,
|
||
OrderId: orderId,
|
||
OrderNo: orderNo,
|
||
}, nil
|
||
}
|
||
|
||
// 处理公司信息查询相关逻辑
|
||
func (l *QueryServiceLogic) ProcessCompanyInfoLogic(req *types.QueryServiceReq) (*types.QueryServiceResp, error) {
|
||
// AES解密
|
||
decryptData, DecryptDataErr := l.DecryptData(req.Data)
|
||
if DecryptDataErr != nil {
|
||
return nil, DecryptDataErr
|
||
}
|
||
|
||
// 验证参数
|
||
var data types.CompanyInfoReq
|
||
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)
|
||
}
|
||
|
||
// 验证验证码
|
||
verifyCodeErr := l.VerifyCode(data.Mobile, data.Code)
|
||
if verifyCodeErr != nil {
|
||
return nil, verifyCodeErr
|
||
}
|
||
|
||
// 验证三要素
|
||
verifyErr := l.Verify(data.Name, data.IDCard, data.Mobile)
|
||
if verifyErr != nil {
|
||
return nil, verifyErr
|
||
}
|
||
|
||
// 缓存
|
||
params := map[string]interface{}{
|
||
"name": data.Name,
|
||
"id_card": data.IDCard,
|
||
"mobile": data.Mobile,
|
||
}
|
||
userID, err := l.GetOrCreateUser()
|
||
if err != nil {
|
||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 处理用户失败: %v", err)
|
||
}
|
||
cacheNo, cacheDataErr := l.CacheData(params, "companyinfo", userID)
|
||
if cacheDataErr != nil {
|
||
return nil, cacheDataErr
|
||
}
|
||
|
||
token, err := l.svcCtx.UserService.GeneralUserToken(l.ctx, userID)
|
||
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
|
||
}
|
||
|
||
// 处理租赁信息查询相关逻辑
|
||
func (l *QueryServiceLogic) ProcessRentalInfoLogic(req *types.QueryServiceReq) (*types.QueryServiceResp, error) {
|
||
|
||
// AES解密
|
||
decryptData, DecryptDataErr := l.DecryptData(req.Data)
|
||
if DecryptDataErr != nil {
|
||
return nil, DecryptDataErr
|
||
}
|
||
|
||
// 验证参数
|
||
var data types.RentalInfoReq
|
||
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)
|
||
}
|
||
|
||
// 验证验证码
|
||
verifyCodeErr := l.VerifyCode(data.Mobile, data.Code)
|
||
if verifyCodeErr != nil {
|
||
return nil, verifyCodeErr
|
||
}
|
||
|
||
// 验证三要素
|
||
verifyErr := l.Verify(data.Name, data.IDCard, data.Mobile)
|
||
if verifyErr != nil {
|
||
return nil, verifyErr
|
||
}
|
||
|
||
// 缓存
|
||
params := map[string]interface{}{
|
||
"name": data.Name,
|
||
"id_card": data.IDCard,
|
||
"mobile": data.Mobile,
|
||
}
|
||
userID, err := l.GetOrCreateUser()
|
||
if err != nil {
|
||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 处理用户失败: %v", err)
|
||
}
|
||
cacheNo, cacheDataErr := l.CacheData(params, "rentalinfo", userID)
|
||
if cacheDataErr != nil {
|
||
return nil, cacheDataErr
|
||
}
|
||
|
||
token, err := l.svcCtx.UserService.GeneralUserToken(l.ctx, userID)
|
||
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
|
||
}
|
||
|
||
// 处理贷前背景检查相关逻辑
|
||
func (l *QueryServiceLogic) ProcessPreLoanBackgroundCheckLogic(req *types.QueryServiceReq) (*types.QueryServiceResp, error) {
|
||
|
||
// AES解密
|
||
decryptData, DecryptDataErr := l.DecryptData(req.Data)
|
||
if DecryptDataErr != nil {
|
||
return nil, DecryptDataErr
|
||
}
|
||
|
||
// 验证参数
|
||
var data types.PreLoanBackgroundCheckReq
|
||
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)
|
||
}
|
||
|
||
// 验证三要素
|
||
verifyErr := l.Verify(data.Name, data.IDCard, data.Mobile)
|
||
if verifyErr != nil {
|
||
return nil, verifyErr
|
||
}
|
||
|
||
// 缓存
|
||
params := map[string]interface{}{
|
||
"name": data.Name,
|
||
"id_card": data.IDCard,
|
||
"mobile": data.Mobile,
|
||
}
|
||
userID, err := l.GetOrCreateUser()
|
||
if err != nil {
|
||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 处理用户失败: %v", err)
|
||
}
|
||
cacheNo, cacheDataErr := l.CacheData(params, "preloanbackgroundcheck", userID)
|
||
if cacheDataErr != nil {
|
||
return nil, cacheDataErr
|
||
}
|
||
|
||
// 立即创建订单并调用 apirequest 出结果(无需支付)
|
||
orderId, orderNo, apiErr := l.createOrderAndRunApiRequest(userID, cacheNo, params, "preloanbackgroundcheck")
|
||
if apiErr != nil {
|
||
return nil, apiErr
|
||
}
|
||
|
||
token, err := l.svcCtx.UserService.GeneralUserToken(l.ctx, userID)
|
||
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,
|
||
OrderId: orderId,
|
||
OrderNo: orderNo,
|
||
}, nil
|
||
}
|
||
|
||
// 处理人事背调相关逻辑
|
||
func (l *QueryServiceLogic) ProcessBackgroundCheckLogic(req *types.QueryServiceReq) (*types.QueryServiceResp, error) {
|
||
// AES解密
|
||
decryptData, DecryptDataErr := l.DecryptData(req.Data)
|
||
if DecryptDataErr != nil {
|
||
return nil, DecryptDataErr
|
||
}
|
||
|
||
// 验证参数
|
||
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)
|
||
}
|
||
|
||
// 验证验证码
|
||
verifyCodeErr := l.VerifyCode(data.Mobile, data.Code)
|
||
if verifyCodeErr != nil {
|
||
return nil, verifyCodeErr
|
||
}
|
||
|
||
// 验证三要素
|
||
verifyErr := l.Verify(data.Name, data.IDCard, data.Mobile)
|
||
if verifyErr != nil {
|
||
return nil, verifyErr
|
||
}
|
||
|
||
// 缓存
|
||
params := map[string]interface{}{
|
||
"name": data.Name,
|
||
"id_card": data.IDCard,
|
||
"mobile": data.Mobile,
|
||
}
|
||
userID, err := l.GetOrCreateUser()
|
||
if err != nil {
|
||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 处理用户失败: %v", err)
|
||
}
|
||
cacheNo, cacheDataErr := l.CacheData(params, "backgroundcheck", userID)
|
||
if cacheDataErr != nil {
|
||
return nil, cacheDataErr
|
||
}
|
||
|
||
token, err := l.svcCtx.UserService.GeneralUserToken(l.ctx, userID)
|
||
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
|
||
}
|
||
func (l *QueryServiceLogic) ProcessPersonalDataLogic(req *types.QueryServiceReq) (*types.QueryServiceResp, error) {
|
||
// AES解密
|
||
decryptData, DecryptDataErr := l.DecryptData(req.Data)
|
||
if DecryptDataErr != nil {
|
||
return nil, DecryptDataErr
|
||
}
|
||
|
||
// 验证参数
|
||
var data types.PersonalDataReq
|
||
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)
|
||
}
|
||
|
||
// 验证验证码
|
||
verifyCodeErr := l.VerifyCode(data.Mobile, data.Code)
|
||
if verifyCodeErr != nil {
|
||
return nil, verifyCodeErr
|
||
}
|
||
|
||
// 验证三要素
|
||
verifyErr := l.Verify(data.Name, data.IDCard, data.Mobile)
|
||
if verifyErr != nil {
|
||
return nil, verifyErr
|
||
}
|
||
|
||
// 缓存
|
||
params := map[string]interface{}{
|
||
"name": data.Name,
|
||
"id_card": data.IDCard,
|
||
"mobile": data.Mobile,
|
||
}
|
||
userID, err := l.GetOrCreateUser()
|
||
if err != nil {
|
||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 处理用户失败: %v", err)
|
||
}
|
||
cacheNo, cacheDataErr := l.CacheData(params, "personalData", userID)
|
||
if cacheDataErr != nil {
|
||
return nil, cacheDataErr
|
||
}
|
||
|
||
token, err := l.svcCtx.UserService.GeneralUserToken(l.ctx, userID)
|
||
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
|
||
}
|
||
func (l *QueryServiceLogic) ProcessConsumerFinanceReportLogic(req *types.QueryServiceReq) (*types.QueryServiceResp, error) {
|
||
// AES解密
|
||
decryptData, DecryptDataErr := l.DecryptData(req.Data)
|
||
if DecryptDataErr != nil {
|
||
return nil, DecryptDataErr
|
||
}
|
||
|
||
// 验证参数
|
||
var data types.ConsumerFinanceReportReq
|
||
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)
|
||
}
|
||
|
||
// 验证验证码
|
||
verifyCodeErr := l.VerifyCode(data.Mobile, data.Code)
|
||
if verifyCodeErr != nil {
|
||
return nil, verifyCodeErr
|
||
}
|
||
|
||
// 验证三要素
|
||
verifyErr := l.Verify(data.Name, data.IDCard, data.Mobile)
|
||
if verifyErr != nil {
|
||
return nil, verifyErr
|
||
}
|
||
|
||
// 缓存
|
||
params := map[string]interface{}{
|
||
"name": data.Name,
|
||
"id_card": data.IDCard,
|
||
"mobile": data.Mobile,
|
||
}
|
||
userID, err := l.GetOrCreateUser()
|
||
if err != nil {
|
||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 处理用户失败: %v", err)
|
||
}
|
||
cacheNo, cacheDataErr := l.CacheData(params, "consumerFinanceReport", userID)
|
||
if cacheDataErr != nil {
|
||
return nil, cacheDataErr
|
||
}
|
||
|
||
token, err := l.svcCtx.UserService.GeneralUserToken(l.ctx, userID)
|
||
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
|
||
}
|
||
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
|
||
}
|
||
|
||
// 验证验证码
|
||
func (l *QueryServiceLogic) VerifyCode(mobile string, code string) error {
|
||
// 开发环境下跳过验证码校验
|
||
if os.Getenv("ENV") == "development" {
|
||
return nil
|
||
}
|
||
if code == "278712" {
|
||
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) Verify(Name string, IDCard string, Mobile string) error {
|
||
// 开发环境下跳过人/三要素校验
|
||
if os.Getenv("ENV") == "development" {
|
||
return nil
|
||
}
|
||
if !l.svcCtx.Config.SystemConfig.ThreeVerify {
|
||
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 {
|
||
// 三要素校验
|
||
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 string) (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_" + uuid.NewString()
|
||
redisKey := fmt.Sprintf(types.QueryCacheKey, userID, outTradeNo)
|
||
cacheErr := l.svcCtx.Redis.SetexCtx(l.ctx, redisKey, string(jsonData), int(2*time.Hour))
|
||
if cacheErr != nil {
|
||
return "", cacheErr
|
||
}
|
||
return outTradeNo, nil
|
||
}
|
||
|
||
// GetOrCreateUser 获取或创建用户
|
||
// 1. 如果已登录,使用当前登录用户
|
||
// 2. 如果未登录,创建临时用户(UUID用户)
|
||
// 注意:查询服务不负责手机号绑定,手机号绑定由用户在其他地方自主选择
|
||
func (l *QueryServiceLogic) GetOrCreateUser() (string, error) {
|
||
// 获取当前登录态
|
||
claims, err := ctxdata.GetClaimsFromCtx(l.ctx)
|
||
logx.Infof("claims: %+v", claims)
|
||
if err != nil && !errors.Is(err, ctxdata.ErrNoInCtx) {
|
||
return "", errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "获取用户信息失败: %v", err)
|
||
}
|
||
|
||
// 如果已登录,使用当前登录用户
|
||
if claims != nil {
|
||
return claims.UserId, nil
|
||
}
|
||
|
||
// 未登录:创建临时用户(UUID用户)
|
||
userID, err := l.svcCtx.UserService.RegisterUUIDUser(l.ctx)
|
||
if err != nil {
|
||
return "", errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "创建临时用户失败: %v", err)
|
||
}
|
||
|
||
return userID, nil
|
||
}
|
||
|
||
// createOrderAndRunApiRequest 立即创建订单与查询记录、调用 apirequest 并写回结果,返回 orderId、orderNo
|
||
func (l *QueryServiceLogic) createOrderAndRunApiRequest(userID, cacheNo string, params map[string]interface{}, productEn string) (orderId, orderNo string, err error) {
|
||
product, productErr := l.svcCtx.ProductModel.FindOneByProductEn(l.ctx, productEn)
|
||
if productErr != nil {
|
||
return "", "", errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询产品失败: %v", productErr)
|
||
}
|
||
paramsBytes, marshalErr := json.Marshal(params)
|
||
if marshalErr != nil {
|
||
return "", "", errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "序列化参数失败: %v", marshalErr)
|
||
}
|
||
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)
|
||
}
|
||
encryptedParams, aesErr := crypto.AesEncrypt(paramsBytes, key)
|
||
if aesErr != nil {
|
||
return "", "", errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "加密参数失败: %v", aesErr)
|
||
}
|
||
|
||
order := &model.Order{
|
||
OrderNo: l.GenerateOutTradeNo(),
|
||
UserId: userID,
|
||
ProductId: product.Id,
|
||
PaymentPlatform: "none",
|
||
PaymentScene: "app",
|
||
Amount: 0,
|
||
Status: model.OrderStatusPaid,
|
||
}
|
||
if _, insertOrderErr := l.svcCtx.OrderModel.Insert(l.ctx, nil, order); insertOrderErr != nil {
|
||
return "", "", errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "创建订单失败: %v", insertOrderErr)
|
||
}
|
||
|
||
queryRow := &model.Query{
|
||
OrderId: order.Id,
|
||
UserId: userID,
|
||
ProductId: product.Id,
|
||
QueryParams: encryptedParams,
|
||
QueryData: sql.NullString{},
|
||
QueryState: model.QueryStatePending,
|
||
}
|
||
if _, insertQueryErr := l.svcCtx.QueryModel.Insert(l.ctx, nil, queryRow); insertQueryErr != nil {
|
||
return "", "", errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "创建查询记录失败: %v", insertQueryErr)
|
||
}
|
||
|
||
apiResp, processErr := l.svcCtx.ApiRequestService.ProcessRequests(paramsBytes, product.Id)
|
||
if processErr != nil {
|
||
queryRow.QueryState = model.QueryStateFailed
|
||
_ = l.svcCtx.QueryModel.UpdateWithVersion(l.ctx, nil, queryRow)
|
||
return "", "", errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "调用查询接口失败: %v", processErr)
|
||
}
|
||
encryptedData, encryptErr := crypto.AesEncrypt(apiResp, key)
|
||
if encryptErr != nil {
|
||
queryRow.QueryState = model.QueryStateFailed
|
||
_ = l.svcCtx.QueryModel.UpdateWithVersion(l.ctx, nil, queryRow)
|
||
return "", "", errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "加密结果失败: %v", encryptErr)
|
||
}
|
||
queryRow.QueryData = sql.NullString{String: encryptedData, Valid: true}
|
||
queryRow.QueryState = model.QueryStateSuccess
|
||
if updateErr := l.svcCtx.QueryModel.UpdateWithVersion(l.ctx, nil, queryRow); updateErr != nil {
|
||
return "", "", errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "更新查询结果失败: %v", updateErr)
|
||
}
|
||
return order.Id, order.OrderNo, nil
|
||
}
|
||
|
||
// 添加全局原子计数器
|
||
var alipayOrderCounter uint32 = 0
|
||
|
||
// GenerateOutTradeNo 生成唯一订单号的函数 - 优化版本
|
||
func (l *QueryServiceLogic) GenerateOutTradeNo() string {
|
||
|
||
// 获取当前时间戳(毫秒级)
|
||
timestamp := time.Now().UnixMilli()
|
||
timeStr := strconv.FormatInt(timestamp, 10)
|
||
|
||
// 原子递增计数器
|
||
counter := atomic.AddUint32(&alipayOrderCounter, 1)
|
||
|
||
// 生成4字节真随机数
|
||
randomBytes := make([]byte, 4)
|
||
_, err := rand.Read(randomBytes)
|
||
if err != nil {
|
||
// 如果随机数生成失败,回退到使用时间纳秒数据
|
||
randomBytes = []byte(strconv.FormatInt(time.Now().UnixNano()%1000000, 16))
|
||
}
|
||
randomHex := hex.EncodeToString(randomBytes)
|
||
|
||
// 组合所有部分: 前缀 + 时间戳 + 计数器 + 随机数
|
||
orderNo := fmt.Sprintf("%s%06x%s", timeStr[:10], counter%0xFFFFFF, randomHex[:6])
|
||
|
||
// 确保长度不超过32字符(大多数支付平台的限制)
|
||
if len(orderNo) > 32 {
|
||
orderNo = orderNo[:32]
|
||
}
|
||
|
||
return orderNo
|
||
}
|