新版本,代理功能上线

This commit is contained in:
2025-03-07 03:48:59 +08:00
parent 8ead7a7a67
commit b2d9d828e3
130 changed files with 11004 additions and 2209 deletions

View File

@@ -0,0 +1,121 @@
package agent
import (
"context"
"database/sql"
"github.com/pkg/errors"
"github.com/zeromicro/go-zero/core/stores/sqlx"
"time"
"tydata-server/app/user/model"
"tydata-server/common/xerr"
"tydata-server/app/user/cmd/api/internal/svc"
"tydata-server/app/user/cmd/api/internal/types"
"github.com/zeromicro/go-zero/core/logx"
)
type ActivateAgentMembershipLogic struct {
logx.Logger
ctx context.Context
svcCtx *svc.ServiceContext
}
func NewActivateAgentMembershipLogic(ctx context.Context, svcCtx *svc.ServiceContext) *ActivateAgentMembershipLogic {
return &ActivateAgentMembershipLogic{
Logger: logx.WithContext(ctx),
ctx: ctx,
svcCtx: svcCtx,
}
}
func (l *ActivateAgentMembershipLogic) ActivateAgentMembership(req *types.AgentActivateMembershipReq) (resp *types.AgentActivateMembershipResp, err error) {
//userID, err := ctxdata.GetUidFromCtx(l.ctx)
//if err != nil {
// return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "获取用户ID失败: %v", err)
//}
userModel, err := l.svcCtx.UserModel.FindOneByMobile(l.ctx, req.Mobile)
if err != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "查询代理信息失败: %v", err)
}
// 查询用户代理信息
agentModel, err := l.svcCtx.AgentModel.FindOneByUserId(l.ctx, userModel.Id)
if err != nil && err != sql.ErrNoRows {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "查询代理信息失败: %v", err)
}
// 定义等级顺序映射
levelOrder := map[string]int{
"": 1,
model.AgentLeveNameNormal: 1,
model.AgentLeveNameVIP: 2,
model.AgentLeveNameSVIP: 3,
}
// 验证请求等级合法性
if _, valid := levelOrder[req.Type]; !valid {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "无效的代理等级: %s", req.Type)
}
// 如果存在代理记录,进行等级验证
if agentModel != nil {
currentLevel, exists := levelOrder[agentModel.LevelName]
if !exists {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR),
"非法的当前代理等级: %s", agentModel.LevelName)
}
requestedLevel := levelOrder[req.Type]
if requestedLevel < currentLevel {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR),
"禁止降级操作(当前等级:%s请求等级%s", agentModel.LevelName, req.Type)
}
}
err = l.svcCtx.AgentModel.Trans(l.ctx, func(transCtx context.Context, session sqlx.Session) error {
agentModel.LevelName = req.Type
agentModel.MembershipExpiryTime = RenewMembership(agentModel.MembershipExpiryTime)
transErr := l.svcCtx.AgentModel.UpdateWithVersion(transCtx, session, agentModel)
if transErr != nil {
return transErr
}
agentMembershipRechargeOrder := model.AgentMembershipRechargeOrder{
AgentId: agentModel.Id,
UserId: userModel.Id,
LevelName: req.Type,
Amount: req.Amount,
PaymentMethod: req.PaymentMethod,
TransactionId: req.TransactionId,
}
_, transErr = l.svcCtx.AgentMembershipRechargeOrderModel.Insert(transCtx, session, &agentMembershipRechargeOrder)
if transErr != nil {
return transErr
}
return nil
})
if err != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "升级代理等级失败: %s", req.Type)
}
return &types.AgentActivateMembershipResp{
MembershipType: req.Type,
ExpireTime: agentModel.MembershipExpiryTime.Time.Format("2006-01-02 15:04:05"),
}, nil
}
func RenewMembership(expiry sql.NullTime) sql.NullTime {
// 确定基准时间
var baseTime time.Time
if expiry.Valid {
baseTime = expiry.Time
} else {
baseTime = time.Now()
}
// 增加一年(自动处理闰年)
newTime := baseTime.AddDate(1, 0, 0)
// 返回始终有效的 NullTime
return sql.NullTime{
Time: newTime,
Valid: true,
}
}

View File

@@ -0,0 +1,305 @@
package agent
import (
"context"
"fmt"
"github.com/cenkalti/backoff/v4"
"github.com/pkg/errors"
"github.com/smartwalle/alipay/v3"
"github.com/zeromicro/go-zero/core/stores/sqlx"
"time"
"tydata-server/app/user/model"
"tydata-server/common/ctxdata"
"tydata-server/common/xerr"
"tydata-server/pkg/lzkit/lzUtils"
"tydata-server/app/user/cmd/api/internal/svc"
"tydata-server/app/user/cmd/api/internal/types"
"github.com/zeromicro/go-zero/core/logx"
)
// 状态常量
const (
StatusProcessing = 1 // 处理中
StatusSuccess = 2 // 成功
StatusFailed = 3 // 失败
)
// 前端响应状态
const (
WithdrawStatusProcessing = 1
WithdrawStatusSuccess = 2
WithdrawStatusFailed = 3
)
type AgentWithdrawalLogic struct {
logx.Logger
ctx context.Context
svcCtx *svc.ServiceContext
}
func NewAgentWithdrawalLogic(ctx context.Context, svcCtx *svc.ServiceContext) *AgentWithdrawalLogic {
return &AgentWithdrawalLogic{
Logger: logx.WithContext(ctx),
ctx: ctx,
svcCtx: svcCtx,
}
}
func (l *AgentWithdrawalLogic) AgentWithdrawal(req *types.WithdrawalReq) (*types.WithdrawalResp, error) {
var (
outBizNo string
withdrawRes = &types.WithdrawalResp{}
)
// 使用事务处理核心操作
err := l.svcCtx.AgentModel.Trans(l.ctx, func(ctx context.Context, session sqlx.Session) error {
userID, err := ctxdata.GetUidFromCtx(l.ctx)
if err != nil {
return errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "获取用户ID失败: %v", err)
}
// 查询代理信息
agentModel, err := l.svcCtx.AgentModel.FindOneByUserId(l.ctx, userID)
if err != nil {
return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "查询代理信息失败: %v", err)
}
// 查询钱包
agentWallet, err := l.svcCtx.AgentWalletModel.FindOneByAgentId(l.ctx, agentModel.Id)
if err != nil {
return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "查询代理钱包失败: %v", err)
}
// 校验可提现金额
withdrawableAmount := agentWallet.Balance - agentWallet.FrozenBalance
if req.Amount > withdrawableAmount {
return errors.Wrapf(xerr.NewErrMsg("您可提现的余额不足"), "获取用户ID失败")
}
// 生成交易号
outBizNo = l.svcCtx.AlipayService.GenerateOutTradeNo()
// 创建提现记录(初始状态为处理中)
if err = l.createWithdrawalRecord(session, agentModel.Id, req, outBizNo); err != nil {
return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "创建提现记录失败: %v", err)
}
// 冻结资金(事务内操作)
if err = l.freezeFunds(session, agentWallet, req.Amount); err != nil {
return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "资金冻结失败: %v", err)
}
return nil
})
if err != nil {
return nil, err
}
// 同步调用支付宝转账
transferResp, err := l.svcCtx.AlipayService.AliTransfer(l.ctx, req.PayeeAccount, req.PayeeName, req.Amount, "代理提现", outBizNo)
if err != nil {
l.handleTransferError(outBizNo, err, "支付宝接口调用失败")
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "支付宝接口调用失败: %v", err)
}
switch {
case transferResp.Status == "SUCCESS":
// 立即处理成功状态
l.handleTransferSuccess(outBizNo, transferResp)
withdrawRes.Status = WithdrawStatusSuccess
case transferResp.Status == "FAIL" || transferResp.SubCode != "":
// 处理明确失败
errorMsg := l.mapAlipayError(transferResp.SubCode)
l.handleTransferFailure(outBizNo, transferResp)
withdrawRes.Status = WithdrawStatusFailed
withdrawRes.FailMsg = errorMsg
case transferResp.Status == "DEALING":
// 处理中状态,启动异步轮询
go l.startAsyncPolling(outBizNo)
withdrawRes.Status = WithdrawStatusProcessing
default:
// 未知状态按失败处理
l.handleTransferError(outBizNo, fmt.Errorf("未知状态:%s", transferResp.Status), "支付宝返回未知状态")
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "支付宝接口调用失败: %v", err)
}
return withdrawRes, nil
}
// 错误类型映射
func (l *AgentWithdrawalLogic) mapAlipayError(code string) string {
errorMapping := map[string]string{
// 账户存在性错误
"PAYEE_ACCOUNT_NOT_EXSIT": "收款账户不存在,请检查账号是否正确",
"PAYEE_NOT_EXIST": "收款账户不存在或姓名有误,请核实信息",
"PAYEE_ACC_OCUPIED": "收款账号存在多个账户,无法确认唯一性",
"PAYEE_MID_CANNOT_SAME": "收款方和中间方不能是同一个人,请修改收款方或者中间方信息",
// 实名认证问题
"PAYEE_CERTIFY_LEVEL_LIMIT": "收款方未完成实名认证",
"PAYEE_NOT_RELNAME_CERTIFY": "收款方未完成实名认证",
"PAYEE_CERT_INFO_ERROR": "收款方证件信息不匹配",
// 账户状态异常
"PAYEE_ACCOUNT_STATUS_ERROR": "收款账户状态异常,请更换账号",
"PAYEE_USERINFO_STATUS_ERROR": "收款账户状态异常,无法收款",
"PERMIT_LIMIT_PAYEE": "收款账户异常,请更换账号",
"BLOCK_USER_FORBBIDEN_RECIEVE": "账户冻结无法收款",
"PAYEE_TRUSTEESHIP_ACC_OVER_LIMIT": "收款方托管子户累计收款金额超限",
// 账户信息错误
"PAYEE_USERINFO_ERROR": "收款方姓名或信息不匹配",
"PAYEE_CARD_INFO_ERROR": "收款支付宝账号及户名不一致",
"PAYEE_IDENTITY_NOT_MATCH": "收款方身份信息不匹配",
"PAYEE_USER_IS_INST": "收款方为金融机构,不能使用提现功能,请更换收款账号",
"PAYEE_USER_TYPE_ERROR": "该支付宝账号类型不支持提现,请更换收款账号",
// 权限与限制
"PAYEE_RECEIVE_COUNT_EXCEED_LIMIT": "收款次数超限,请明日再试",
"PAYEE_OUT_PERMLIMIT_CHECK_FAILURE": "收款方权限校验不通过",
"PERMIT_NON_BANK_LIMIT_PAYEE": "收款方未完善身份信息,无法收款",
}
if msg, ok := errorMapping[code]; ok {
return msg
}
return "系统错误,请联系客服"
}
// 创建提现记录(事务内操作)
func (l *AgentWithdrawalLogic) createWithdrawalRecord(session sqlx.Session, agentID int64, req *types.WithdrawalReq, outBizNo string) error {
record := &model.AgentWithdrawal{
AgentId: agentID,
WithdrawNo: outBizNo,
PayeeAccount: req.PayeeAccount,
Amount: req.Amount,
Status: StatusProcessing,
}
_, err := l.svcCtx.AgentWithdrawalModel.Insert(l.ctx, session, record)
return err
}
// 冻结资金(事务内操作)
func (l *AgentWithdrawalLogic) freezeFunds(session sqlx.Session, wallet *model.AgentWallet, amount float64) error {
wallet.Balance -= amount
wallet.FrozenBalance += amount
err := l.svcCtx.AgentWalletModel.UpdateWithVersion(l.ctx, session, wallet)
if err != nil {
return err
}
return nil
}
// 处理异步轮询
func (l *AgentWithdrawalLogic) startAsyncPolling(outBizNo string) {
go func() {
detachedCtx := context.WithoutCancel(l.ctx)
retryConfig := &backoff.ExponentialBackOff{
InitialInterval: 10 * time.Second,
RandomizationFactor: 0.5, // 增加随机因子防止惊群
Multiplier: 2,
MaxInterval: 30 * time.Second,
MaxElapsedTime: 5 * time.Minute, // 缩短总超时
Clock: backoff.SystemClock,
}
retryConfig.Reset()
operation := func() error {
statusRsp, err := l.svcCtx.AlipayService.QueryTransferStatus(detachedCtx, outBizNo)
if err != nil {
return err // 触发重试
}
switch statusRsp.Status {
case "SUCCESS":
l.handleTransferSuccess(outBizNo, statusRsp)
return nil
case "FAIL":
l.handleTransferFailure(outBizNo, statusRsp)
return nil
default:
return fmt.Errorf("转账处理中")
}
}
err := backoff.RetryNotify(operation,
backoff.WithContext(retryConfig, detachedCtx),
func(err error, duration time.Duration) {
l.Logger.Infof("轮询延迟 outBizNo:%s 等待:%v", outBizNo, duration)
})
if err != nil {
l.handleTransferTimeout(outBizNo)
}
}()
}
// 统一状态更新
func (l *AgentWithdrawalLogic) updateWithdrawalStatus(outBizNo string, status int64, errorMsg string) {
detachedCtx := context.WithoutCancel(l.ctx)
err := l.svcCtx.AgentModel.Trans(detachedCtx, func(ctx context.Context, session sqlx.Session) error {
// 获取提现记录
record, err := l.svcCtx.AgentWithdrawalModel.FindOneByWithdrawNo(l.ctx, outBizNo)
if err != nil {
return err
}
// 更新状态
record.Status = status
record.Remark = lzUtils.StringToNullString(errorMsg)
if _, err = l.svcCtx.AgentWithdrawalModel.Update(ctx, session, record); err != nil {
return err
}
// 失败时解冻资金
if status == StatusFailed {
wallet, err := l.svcCtx.AgentWalletModel.FindOneByAgentId(ctx, record.AgentId)
if err != nil {
return err
}
wallet.Balance += record.Amount
wallet.FrozenBalance -= record.Amount
if err := l.svcCtx.AgentWalletModel.UpdateWithVersion(ctx, session, wallet); err != nil {
return err
}
}
return nil
})
if err != nil {
l.Logger.Errorf("状态更新失败 outBizNo:%s error:%v", outBizNo, err)
}
}
// 成功处理
func (l *AgentWithdrawalLogic) handleTransferSuccess(outBizNo string, rsp interface{}) {
l.updateWithdrawalStatus(outBizNo, StatusSuccess, "")
l.Logger.Infof("提现成功 outBizNo:%s", outBizNo)
}
// 失败处理
func (l *AgentWithdrawalLogic) handleTransferFailure(outBizNo string, rsp interface{}) {
var errorMsg string
if resp, ok := rsp.(*alipay.FundTransUniTransferRsp); ok {
errorMsg = l.mapAlipayError(resp.SubCode)
}
l.updateWithdrawalStatus(outBizNo, StatusFailed, errorMsg)
l.Logger.Errorf("提现失败 outBizNo:%s reason:%s", outBizNo, errorMsg)
}
// 超时处理
func (l *AgentWithdrawalLogic) handleTransferTimeout(outBizNo string) {
l.updateWithdrawalStatus(outBizNo, StatusFailed, "系统处理超时")
l.Logger.Errorf("轮询超时 outBizNo:%s", outBizNo)
}
// 错误处理
func (l *AgentWithdrawalLogic) handleTransferError(outBizNo string, err error, contextMsg string) {
l.updateWithdrawalStatus(outBizNo, StatusFailed, "系统处理异常")
l.Logger.Errorf("%s outBizNo:%s error:%v", contextMsg, outBizNo, err)
}

View File

@@ -0,0 +1,169 @@
package agent
import (
"context"
"fmt"
"github.com/pkg/errors"
"github.com/zeromicro/go-zero/core/stores/redis"
"github.com/zeromicro/go-zero/core/stores/sqlx"
"time"
"tydata-server/app/user/model"
jwtx "tydata-server/common/jwt"
"tydata-server/common/xerr"
"tydata-server/pkg/lzkit/lzUtils"
"tydata-server/app/user/cmd/api/internal/svc"
"tydata-server/app/user/cmd/api/internal/types"
"github.com/zeromicro/go-zero/core/logx"
)
type ApplyForAgentLogic struct {
logx.Logger
ctx context.Context
svcCtx *svc.ServiceContext
}
func NewApplyForAgentLogic(ctx context.Context, svcCtx *svc.ServiceContext) *ApplyForAgentLogic {
return &ApplyForAgentLogic{
Logger: logx.WithContext(ctx),
ctx: ctx,
svcCtx: svcCtx,
}
}
func (l *ApplyForAgentLogic) ApplyForAgent(req *types.AgentApplyReq) (resp *types.AgentApplyResp, err error) {
// 校验验证码
redisKey := fmt.Sprintf("%s:%s", "agentApply", req.Mobile)
cacheCode, err := l.svcCtx.Redis.Get(redisKey)
if err != nil {
if errors.Is(err, redis.Nil) {
return nil, errors.Wrapf(xerr.NewErrMsg("验证码已过期"), "代理申请, 验证码过期: %s", req.Mobile)
}
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "代理申请, 读取验证码redis缓存失败, mobile: %s, err: %+v", req.Mobile, err)
}
if cacheCode != req.Code {
return nil, errors.Wrapf(xerr.NewErrMsg("验证码不正确"), "代理申请, 验证码不正确: %s", req.Mobile)
}
if req.Ancestor == req.Mobile {
return nil, errors.Wrapf(xerr.NewErrMsg("不能成为自己的代理"), "")
}
var userID int64
transErr := l.svcCtx.AgentAuditModel.Trans(l.ctx, func(transCtx context.Context, session sqlx.Session) error {
// 两种情况1. 已注册账号然后申请代理 2. 未注册账号申请代理
user, findUserErr := l.svcCtx.UserModel.FindOneByMobile(l.ctx, req.Mobile)
if findUserErr != nil && !errors.Is(findUserErr, model.ErrNotFound) {
return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "手机登录, 读取数据库获取用户失败, mobile: %s, err: %+v", req.Mobile, err)
}
if user == nil {
user = &model.User{Mobile: req.Mobile}
if len(user.Nickname) == 0 {
user.Nickname = req.Mobile
}
insertResult, userInsertErr := l.svcCtx.UserModel.Insert(transCtx, session, user)
if userInsertErr != nil {
return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "代理申请, 数据库插入新用户失败, mobile%s, err: %+v", req.Mobile, err)
}
lastId, lastInsertIdErr := insertResult.LastInsertId()
if lastInsertIdErr != nil {
return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "代理申请, 获取新用户ID失败, err:%+v, user:%+v", lastInsertIdErr, user)
}
user.Id = lastId
userID = lastId
userAuth := new(model.UserAuth)
userAuth.UserId = lastId
userAuth.AuthKey = req.Mobile
userAuth.AuthType = model.UserAuthTypeAgentDirect
if _, userAuthInsertErr := l.svcCtx.UserAuthModel.Insert(transCtx, session, userAuth); userAuthInsertErr != nil {
return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "代理申请, 数据库插入用户认证失败, err:%+v", userAuthInsertErr)
}
}
userID = user.Id
agentAuditModel, findAgentAuditErr := l.svcCtx.AgentAuditModel.FindOneByUserId(transCtx, user.Id)
if findAgentAuditErr != nil && !errors.Is(findAgentAuditErr, model.ErrNotFound) {
return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "代理申请, 查找审核列表失败%+v", findAgentAuditErr)
}
if agentAuditModel != nil {
if agentAuditModel.Status == 0 {
return errors.Wrapf(xerr.NewErrMsg("您的代理申请中"), "代理申请, 代理申请中")
} else {
return errors.Wrapf(xerr.NewErrMsg("您已申请过代理"), "代理申请, 代理已申请过")
}
}
var agentAudit model.AgentAudit
agentAudit.UserId = user.Id
agentAudit.Mobile = req.Mobile
agentAudit.Region = req.Region
agentAudit.WechatId = lzUtils.StringToNullString(req.WechatID)
agentAudit.Status = 1
_, insetAgentAuditErr := l.svcCtx.AgentAuditModel.Insert(transCtx, session, &agentAudit)
if insetAgentAuditErr != nil {
return errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "代理申请, 保存代理审核信息失败: %v", insetAgentAuditErr)
}
//agentAuditID, _ := agentAuditInsert.LastInsertId()
//agentAuditRow, findAgentAuditModelErr := l.svcCtx.AgentAuditModel.FindOne(l.ctx, agentAuditID)
//if findAgentAuditModelErr != nil {
// return errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "代理申请, 查找代理审核信息失败: %v", insetAgentAuditErr)
//}
//agentAuditRow.Status = 1
//updateAgentAuditErr := l.svcCtx.AgentAuditModel.UpdateWithVersion(transCtx, session, agentAuditRow)
//if updateAgentAuditErr != nil {
// return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "代理申请, 通过代理审核失败: %+v", updateAgentAuditErr)
//}
// 新增代理
var agentModel model.Agent
agentModel.Mobile = agentAudit.Mobile
agentModel.Region = agentAudit.Region
agentModel.UserId = agentAudit.UserId
agentModel.WechatId = lzUtils.StringToNullString(req.WechatID)
agentModelInsert, insertAgentModelErr := l.svcCtx.AgentModel.Insert(transCtx, session, &agentModel)
if insertAgentModelErr != nil {
return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "代理申请, 新增代理失败: %+v", insertAgentModelErr)
}
agentID, _ := agentModelInsert.LastInsertId()
// 关联上级
if req.Ancestor != "" {
ancestorAgentModel, findAgentModelErr := l.svcCtx.AgentModel.FindOneByMobile(transCtx, req.Ancestor)
if findAgentModelErr != nil {
return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "代理申请, 查找上级代理失败: %+v", findAgentModelErr)
}
agentClosureModel := model.AgentClosure{
AncestorId: ancestorAgentModel.Id,
DescendantId: agentID,
Depth: 1,
}
_, insertAgentClosureModelErr := l.svcCtx.AgentClosureModel.Insert(transCtx, session, &agentClosureModel)
if insertAgentClosureModelErr != nil {
return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "代理申请, 添加代理上下级关联失败: %+v", insertAgentClosureModelErr)
}
}
// 新增代理钱包
var agentWallet model.AgentWallet
agentWallet.AgentId = agentID
_, insertAgentWalletModelErr := l.svcCtx.AgentWalletModel.Insert(transCtx, session, &agentWallet)
if insertAgentWalletModelErr != nil {
return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "代理申请, 新增代理钱包失败: %+v", insertAgentWalletModelErr)
}
return nil
})
if transErr != nil {
return nil, transErr
}
token, generaErr := jwtx.GenerateJwtToken(userID, l.svcCtx.Config.JwtAuth.AccessSecret, l.svcCtx.Config.JwtAuth.AccessExpire)
if generaErr != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "代理申请, 生成token失败 : %d", userID)
}
// 获取当前时间戳
now := time.Now().Unix()
return &types.AgentApplyResp{
AccessToken: token,
AccessExpire: now + l.svcCtx.Config.JwtAuth.AccessExpire,
RefreshAfter: now + l.svcCtx.Config.JwtAuth.RefreshAfter,
}, nil
}

View File

@@ -0,0 +1,110 @@
package agent
import (
"context"
"encoding/hex"
"encoding/json"
"github.com/Masterminds/squirrel"
"github.com/pkg/errors"
"strconv"
"tydata-server/app/user/model"
"tydata-server/common/ctxdata"
"tydata-server/common/xerr"
"tydata-server/pkg/lzkit/crypto"
"tydata-server/app/user/cmd/api/internal/svc"
"tydata-server/app/user/cmd/api/internal/types"
"github.com/zeromicro/go-zero/core/logx"
)
type GeneratingLinkLogic struct {
logx.Logger
ctx context.Context
svcCtx *svc.ServiceContext
}
func NewGeneratingLinkLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GeneratingLinkLogic {
return &GeneratingLinkLogic{
Logger: logx.WithContext(ctx),
ctx: ctx,
svcCtx: svcCtx,
}
}
func (l *GeneratingLinkLogic) GeneratingLink(req *types.AgentGeneratingLinkReq) (resp *types.AgentGeneratingLinkResp, err error) {
userID, err := ctxdata.GetUidFromCtx(l.ctx)
if err != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "生成代理链接, %v", err)
}
productModel, err := l.svcCtx.ProductModel.FindOneByProductEn(l.ctx, req.Product)
if err != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "生成代理链接, %v", err)
}
agentProductConfig, err := l.svcCtx.AgentProductConfigModel.FindOneByProductId(l.ctx, productModel.Id)
if err != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "生成代理链接, %v", err)
}
price, err := strconv.ParseFloat(req.Price, 64)
if err != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "生成代理链接, %v", err)
}
if price < agentProductConfig.PriceRangeMin || price > agentProductConfig.PriceRangeMax {
return nil, errors.Wrapf(xerr.NewErrMsg("请设定范围区间内的价格"), "")
}
agentModel, err := l.svcCtx.AgentModel.FindOneByUserId(l.ctx, userID)
if err != nil {
return nil, err
}
build := l.svcCtx.AgentLinkModel.SelectBuilder().Where(squirrel.And{
squirrel.Eq{"user_id": userID},
squirrel.Eq{"product_id": productModel.Id}, // 添加 product_id 的匹配条件
squirrel.Eq{"price": price}, // 添加 price 的匹配条件
squirrel.Eq{"agent_id": agentModel.Id}, // 添加 agent_id 的匹配条件
})
agentLinkModel, err := l.svcCtx.AgentLinkModel.FindAll(l.ctx, build, "")
if err != nil && !errors.Is(err, model.ErrNotFound) {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "生成代理链接, %v", err)
}
if len(agentLinkModel) > 0 {
return &types.AgentGeneratingLinkResp{
LinkIdentifier: agentLinkModel[0].LinkIdentifier,
}, nil
}
var agentIdentifier types.AgentIdentifier
agentIdentifier.AgentID = agentModel.Id
agentIdentifier.Product = req.Product
agentIdentifier.Price = req.Price
agentIdentifierByte, err := json.Marshal(agentIdentifier)
if err != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "生成订单,序列化标识失败, %v", err)
}
key, decodeErr := hex.DecodeString("8e3e7a2f60edb49221e953b9c029ed10")
if decodeErr != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "生成订单, 获取AES密钥失败: %+v", decodeErr)
}
// Encrypt the params
encrypted, err := crypto.AesEncryptURL(agentIdentifierByte, key)
if err != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "生成代理链接, %v", err)
}
var agentLink model.AgentLink
agentLink.AgentId = agentModel.Id
agentLink.UserId = userID
agentLink.LinkIdentifier = encrypted
agentLink.ProductId = productModel.Id
agentLink.Price = price
_, err = l.svcCtx.AgentLinkModel.Insert(l.ctx, nil, &agentLink)
if err != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "生成代理链接, %v", err)
}
return &types.AgentGeneratingLinkResp{
LinkIdentifier: encrypted,
}, nil
}

View File

@@ -0,0 +1,43 @@
package agent
import (
"context"
"github.com/jinzhu/copier"
"github.com/pkg/errors"
"tydata-server/common/ctxdata"
"tydata-server/common/xerr"
"tydata-server/app/user/cmd/api/internal/svc"
"tydata-server/app/user/cmd/api/internal/types"
"github.com/zeromicro/go-zero/core/logx"
)
type GetAgentAuditStatusLogic struct {
logx.Logger
ctx context.Context
svcCtx *svc.ServiceContext
}
func NewGetAgentAuditStatusLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetAgentAuditStatusLogic {
return &GetAgentAuditStatusLogic{
Logger: logx.WithContext(ctx),
ctx: ctx,
svcCtx: svcCtx,
}
}
func (l *GetAgentAuditStatusLogic) GetAgentAuditStatus() (resp *types.AgentAuditStatusResp, err error) {
userID, err := ctxdata.GetUidFromCtx(l.ctx)
if err != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "获取代理审核信息, %v", err)
}
agentAuditModel, err := l.svcCtx.AgentAuditModel.FindOneByUserId(l.ctx, userID)
if err != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "获取代理审核信息, %v", err)
}
var agentAuditStautsResp types.AgentAuditStatusResp
copier.Copy(&agentAuditStautsResp, agentAuditModel)
return &agentAuditStautsResp, nil
}

View File

@@ -0,0 +1,70 @@
package agent
import (
"context"
"github.com/Masterminds/squirrel"
"github.com/jinzhu/copier"
"github.com/pkg/errors"
"tydata-server/common/ctxdata"
"tydata-server/common/xerr"
"tydata-server/app/user/cmd/api/internal/svc"
"tydata-server/app/user/cmd/api/internal/types"
"github.com/zeromicro/go-zero/core/logx"
)
type GetAgentCommissionLogic struct {
logx.Logger
ctx context.Context
svcCtx *svc.ServiceContext
}
func NewGetAgentCommissionLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetAgentCommissionLogic {
return &GetAgentCommissionLogic{
Logger: logx.WithContext(ctx),
ctx: ctx,
svcCtx: svcCtx,
}
}
func (l *GetAgentCommissionLogic) GetAgentCommission(req *types.GetCommissionReq) (resp *types.GetCommissionResp, err error) {
userID, err := ctxdata.GetUidFromCtx(l.ctx)
if err != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "获取代理佣金列表, %v", err)
}
agentModel, err := l.svcCtx.AgentModel.FindOneByUserId(l.ctx, userID)
if err != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "获取代理佣金列表, %v", err)
}
builder := l.svcCtx.AgentCommissionModel.SelectBuilder().Where(squirrel.Eq{
"agent_id": agentModel.Id,
})
agentCommissionModelList, total, err := l.svcCtx.AgentCommissionModel.FindPageListByPageWithTotal(l.ctx, builder, req.Page, req.PageSize, "create_time DESC")
if err != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "获取代理佣金列表, 查找列表错误, %v", err)
}
var list = make([]types.Commission, 0)
if len(agentCommissionModelList) > 0 {
for _, agentCommissionModel := range agentCommissionModelList {
var commission types.Commission
copyErr := copier.Copy(&commission, agentCommissionModel)
if copyErr != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "获取代理佣金列表, %v", err)
}
product, findProductErr := l.svcCtx.ProductModel.FindOne(l.ctx, agentCommissionModel.ProductId)
if findProductErr != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "获取代理佣金列表, %v", err)
}
commission.CreateTime = agentCommissionModel.CreateTime.Format("2006-01-02 15:04:05")
commission.ProductName = product.ProductName
list = append(list, commission)
}
}
return &types.GetCommissionResp{
Total: total,
List: list,
}, nil
}

View File

@@ -0,0 +1,66 @@
package agent
import (
"context"
"database/sql"
"github.com/pkg/errors"
"tydata-server/app/user/model"
"tydata-server/common/ctxdata"
"tydata-server/common/xerr"
"tydata-server/pkg/lzkit/lzUtils"
"tydata-server/app/user/cmd/api/internal/svc"
"tydata-server/app/user/cmd/api/internal/types"
"github.com/zeromicro/go-zero/core/logx"
)
type GetAgentInfoLogic struct {
logx.Logger
ctx context.Context
svcCtx *svc.ServiceContext
}
func NewGetAgentInfoLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetAgentInfoLogic {
return &GetAgentInfoLogic{
Logger: logx.WithContext(ctx),
ctx: ctx,
svcCtx: svcCtx,
}
}
func (l *GetAgentInfoLogic) GetAgentInfo() (resp *types.AgentInfoResp, err error) {
userID, err := ctxdata.GetUidFromCtx(l.ctx)
if err != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "获取代理信息, %v", err)
}
agent, err := l.svcCtx.AgentModel.FindOneByUserId(l.ctx, userID)
if err != nil {
if errors.Is(err, sql.ErrNoRows) {
agentAuditModel, findAgentAuditErr := l.svcCtx.AgentAuditModel.FindOneByUserId(l.ctx, userID)
if findAgentAuditErr != nil && !errors.Is(findAgentAuditErr, model.ErrNotFound) {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "获取代理信息, %v", err)
}
if errors.Is(findAgentAuditErr, model.ErrNotFound) {
return &types.AgentInfoResp{
IsAgent: false,
Status: 3,
}, nil
}
return &types.AgentInfoResp{
IsAgent: false,
Status: agentAuditModel.Status,
}, nil
}
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "获取代理信息, %v", err)
}
return &types.AgentInfoResp{
AgentID: agent.Id,
Level: agent.LevelName,
IsAgent: true,
Status: 1,
Region: agent.Region,
Mobile: agent.Mobile,
WechatID: lzUtils.NullStringToString(agent.WechatId),
}, nil
}

View File

@@ -0,0 +1,77 @@
package agent
import (
"context"
"github.com/jinzhu/copier"
"github.com/pkg/errors"
"tydata-server/app/user/model"
"tydata-server/common/ctxdata"
"tydata-server/common/xerr"
"tydata-server/pkg/lzkit/lzUtils"
"tydata-server/app/user/cmd/api/internal/svc"
"tydata-server/app/user/cmd/api/internal/types"
"github.com/zeromicro/go-zero/core/logx"
)
type GetAgentMembershipProductConfigLogic struct {
logx.Logger
ctx context.Context
svcCtx *svc.ServiceContext
}
func NewGetAgentMembershipProductConfigLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetAgentMembershipProductConfigLogic {
return &GetAgentMembershipProductConfigLogic{
Logger: logx.WithContext(ctx),
ctx: ctx,
svcCtx: svcCtx,
}
}
func (l *GetAgentMembershipProductConfigLogic) GetAgentMembershipProductConfig(req *types.AgentMembershipProductConfigReq) (resp *types.AgentMembershipProductConfigResp, err error) {
userID, err := ctxdata.GetUidFromCtx(l.ctx)
if err != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "获取会员用户报告配置获取用户ID失败: %v", err)
}
agentModel, err := l.svcCtx.AgentModel.FindOneByUserId(l.ctx, userID)
if err != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "获取会员用户报告配置,获取代理信息失败: %v", err)
}
agentMembershipConfigModel, err := l.svcCtx.AgentMembershipConfigModel.FindOneByLevelName(l.ctx, agentModel.LevelName)
if err != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "获取会员用户报告配置,获取平台配置会员信息失败: %v", err)
}
agentMembershipUserConfigModel, err := l.svcCtx.AgentMembershipUserConfigModel.FindOneByAgentIdProductId(l.ctx, agentModel.Id, req.ProductID)
if err != nil && !errors.Is(err, model.ErrNotFound) {
return nil, err
}
var agentMembershipUserConfig types.AgentMembershipUserConfig
if agentMembershipUserConfigModel != nil {
err = copier.Copy(&agentMembershipUserConfig, agentMembershipUserConfigModel)
if err != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "获取会员用户报告配置,复制平台配置会员信息失败: %v", err)
}
} else {
agentMembershipUserConfig.ProductID = req.ProductID
}
agentProductConfigModelAll, err := l.svcCtx.AgentProductConfigModel.FindOneByProductId(l.ctx, req.ProductID)
if err != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "获取会员用户报告配置, 获取产品配置%v", err)
}
var productConfig types.ProductConfig
err = copier.Copy(&productConfig, agentProductConfigModelAll)
if err != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "获取会员用户报告配置,复制平台产品配置失败: %v", err)
}
return &types.AgentMembershipProductConfigResp{
AgentMembershipUserConfig: agentMembershipUserConfig,
ProductConfig: productConfig,
PriceIncreaseAmount: lzUtils.NullFloat64ToFloat64(agentMembershipConfigModel.PriceIncreaseAmount),
PriceIncreaseMax: lzUtils.NullFloat64ToFloat64(agentMembershipConfigModel.PriceIncreaseMax),
PriceRatio: lzUtils.NullFloat64ToFloat64(agentMembershipConfigModel.PriceRatio),
}, nil
}

View File

@@ -0,0 +1,136 @@
package agent
import (
"context"
"github.com/pkg/errors"
"github.com/zeromicro/go-zero/core/mr"
"tydata-server/app/user/model"
"tydata-server/common/ctxdata"
"tydata-server/common/xerr"
"tydata-server/app/user/cmd/api/internal/svc"
"tydata-server/app/user/cmd/api/internal/types"
"github.com/zeromicro/go-zero/core/logx"
)
type GetAgentProductConfigLogic struct {
logx.Logger
ctx context.Context
svcCtx *svc.ServiceContext
}
func NewGetAgentProductConfigLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetAgentProductConfigLogic {
return &GetAgentProductConfigLogic{
Logger: logx.WithContext(ctx),
ctx: ctx,
svcCtx: svcCtx,
}
}
type AgentProductConfigResp struct {
}
func (l *GetAgentProductConfigLogic) GetAgentProductConfig() (resp *types.AgentProductConfigResp, err error) {
userID, err := ctxdata.GetUidFromCtx(l.ctx)
if err != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "获取推广项目配置失败, %v", err)
}
agentModel, err := l.svcCtx.AgentModel.FindOneByUserId(l.ctx, userID)
if err != nil {
if errors.Is(err, model.ErrNotFound) {
return nil, errors.Wrapf(xerr.NewErrMsg("您不是代理"), "")
}
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "获取推广项目配置失败, %v", err)
}
// 1. 查询推广项目配置数据
builder := l.svcCtx.AgentProductConfigModel.SelectBuilder()
agentProductConfigModelAll, err := l.svcCtx.AgentProductConfigModel.FindAll(l.ctx, builder, "")
if err != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "获取推广项目配置失败, %v", err)
}
// 用于存放最终组装好的响应数据
var respList []types.AgentProductConfig
// 2. 使用 mr.MapReduceVoid 并行处理每个推广项目配置项
mrMapErr := mr.MapReduceVoid(
// source 函数:遍历所有推广项目配置,将每个配置项发送到 channel 中
func(source chan<- interface{}) {
for _, config := range agentProductConfigModelAll {
source <- config
}
},
// map 函数:处理每个推广项目配置项,根据 ProductId 查询会员用户配置,并组装响应数据
func(item interface{}, writer mr.Writer[*types.AgentProductConfig], cancel func(error)) {
// 将 item 转换为推广项目配置模型
config := item.(*model.AgentProductConfig)
var agentProductConfig types.AgentProductConfig
// 配置平台成本价和定价成本
agentProductConfigModel, findAgentProductConfigErr := l.svcCtx.AgentProductConfigModel.FindOneByProductId(l.ctx, config.ProductId)
if findAgentProductConfigErr != nil {
cancel(findAgentProductConfigErr)
return
}
agentProductConfig.ProductID = config.ProductId
agentProductConfig.CostPrice = agentProductConfigModel.CostPrice
agentProductConfig.PriceRangeMin = agentProductConfigModel.PriceRangeMin
agentProductConfig.PriceRangeMax = agentProductConfigModel.PriceRangeMax
agentProductConfig.PPricingStandard = agentProductConfigModel.PricingStandard
agentProductConfig.POverpricingRatio = agentProductConfigModel.OverpricingRatio
// 看推广人是否有上级,上级是否有这个配置权限,上级是否有相关配置
agentClosureModel, findAgentClosureErr := l.svcCtx.AgentClosureModel.FindOneByDescendantIdDepth(l.ctx, agentModel.Id, 1)
if findAgentClosureErr != nil && !errors.Is(findAgentClosureErr, model.ErrNotFound) {
cancel(findAgentClosureErr)
return
}
if agentClosureModel != nil {
ancestorAgentModel, findAncestorAgentErr := l.svcCtx.AgentModel.FindOne(l.ctx, agentClosureModel.AncestorId)
if findAncestorAgentErr != nil {
cancel(findAncestorAgentErr)
return
}
agentMembershipConfigModel, findAgentMembershipErr := l.svcCtx.AgentMembershipConfigModel.FindOneByLevelName(l.ctx, ancestorAgentModel.LevelName)
if findAgentMembershipErr != nil {
cancel(findAgentMembershipErr)
return
}
// 是否有提成本价
if agentMembershipConfigModel.PriceIncreaseAmount.Valid {
// 根据产品ID查询会员用户配置数据
membershipUserConfigModel, membershipConfigErr := l.svcCtx.AgentMembershipUserConfigModel.FindOneByAgentIdProductId(l.ctx, agentClosureModel.AncestorId, config.ProductId)
if membershipConfigErr != nil {
if errors.Is(membershipConfigErr, model.ErrNotFound) {
writer.Write(&agentProductConfig)
return
}
cancel(membershipConfigErr)
return
}
agentProductConfig.CostPrice += membershipUserConfigModel.PriceIncreaseAmount
agentProductConfig.PriceRangeMin += membershipUserConfigModel.PriceIncreaseAmount
agentProductConfig.APricingStandard = membershipUserConfigModel.PriceRangeFrom
agentProductConfig.APricingEnd = membershipUserConfigModel.PriceRangeTo
agentProductConfig.AOverpricingRatio = membershipUserConfigModel.PriceRatio
}
}
writer.Write(&agentProductConfig)
},
// reduce 函数:收集 map 阶段写入的响应数据,并汇总到 respList 中
func(pipe <-chan *types.AgentProductConfig, cancel func(error)) {
for item := range pipe {
respList = append(respList, *item)
}
},
)
if mrMapErr != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "获取推广项目配置失败, %+v", mrMapErr)
}
// 3. 组装最终响应返回
return &types.AgentProductConfigResp{
AgentProductConfig: respList,
}, nil
}

View File

@@ -0,0 +1,198 @@
package agent
import (
"context"
"github.com/Masterminds/squirrel"
"github.com/pkg/errors"
"time"
"tydata-server/app/user/model"
"tydata-server/common/ctxdata"
"tydata-server/common/xerr"
"tydata-server/app/user/cmd/api/internal/svc"
"tydata-server/app/user/cmd/api/internal/types"
"github.com/zeromicro/go-zero/core/logx"
)
type GetAgentRevenueInfoLogic struct {
logx.Logger
ctx context.Context
svcCtx *svc.ServiceContext
}
func NewGetAgentRevenueInfoLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetAgentRevenueInfoLogic {
return &GetAgentRevenueInfoLogic{
Logger: logx.WithContext(ctx),
ctx: ctx,
svcCtx: svcCtx,
}
}
func (l *GetAgentRevenueInfoLogic) GetAgentRevenueInfo(req *types.GetAgentRevenueInfoReq) (resp *types.GetAgentRevenueInfoResp, err error) {
userID, err := ctxdata.GetUidFromCtx(l.ctx)
if err != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "获取代理奖励, %v", err)
}
agentModel, err := l.svcCtx.AgentModel.FindOneByUserId(l.ctx, userID)
if err != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "获取代理奖励, %v", err)
}
agentWalletModel, err := l.svcCtx.AgentWalletModel.FindOneByAgentId(l.ctx, agentModel.Id)
if err != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "获取代理奖励, %v", err)
}
resp = &types.GetAgentRevenueInfoResp{}
resp.Balance = agentWalletModel.Balance
resp.TotalEarnings = agentWalletModel.TotalEarnings
resp.FrozenBalance = agentWalletModel.FrozenBalance
// 直推报告统计
//now := time.Now()
//startTime := now.AddDate(0, 0, -30).Format("2006-01-02 15:04:05")
//endTime := now.Format("2006-01-02 15:04:05")
// 直推报告佣金
agentCommissionModelBuild := l.svcCtx.AgentCommissionModel.SelectBuilder().
Where(squirrel.Eq{"agent_id": agentModel.Id})
//.Where(squirrel.Expr("create_time BETWEEN ? AND ?", startTime, endTime))
agentCommissionsModel, err := l.svcCtx.AgentCommissionModel.FindAll(l.ctx, agentCommissionModelBuild, "")
if err != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "获取代理奖励, %v", err)
}
// 筛选分类
directPush, err := calculateDirectPushReport(agentCommissionsModel, nil)
if err != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "获取代理奖励, %v", err)
}
// 绑定到响应体
resp.DirectPush = directPush
// 活跃下级统计
agentRewardsModelBuilder := l.svcCtx.AgentRewardsModel.SelectBuilder().Where("agent_id = ?", agentModel.Id)
agentRewardsModel, err := l.svcCtx.AgentRewardsModel.FindAll(l.ctx, agentRewardsModelBuilder, "")
if err != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "获取代理奖励, %v", err)
}
activeReward := calculateActiveReward(agentRewardsModel)
resp.ActiveReward = activeReward
return resp, nil
}
// 统计直推报告的独立函数
func calculateDirectPushReport(commissions []*model.AgentCommission, loc *time.Location) (types.DirectPushReport, error) {
// 初始化报告结构
report := types.DirectPushReport{
Today: types.TimeRangeReport{},
Last7D: types.TimeRangeReport{},
Last30D: types.TimeRangeReport{},
}
// 获取当前中国时间
now := time.Now()
// 计算时间分界点
todayStart := now.Add(-24 * time.Hour)
last7dStart := now.AddDate(0, 0, -7)
last30dStart := now.AddDate(0, 0, -30)
// 遍历所有佣金记录
for _, c := range commissions {
// 转换时区
createTime := c.CreateTime
// 统计总量
report.TotalCommission += c.Amount
report.TotalReport++
// 近24小时滚动周期
if createTime.After(todayStart) {
report.Today.Commission += c.Amount
report.Today.Report++
}
// 近7天滚动周期
if createTime.After(last7dStart) {
report.Last7D.Commission += c.Amount
report.Last7D.Report++
}
// 近30天滚动周期
if createTime.After(last30dStart) {
report.Last30D.Commission += c.Amount
report.Last30D.Report++
}
}
return report, nil
}
func calculateActiveReward(rewards []*model.AgentRewards) types.ActiveReward {
result := types.ActiveReward{
Today: types.ActiveRewardData{},
Last7D: types.ActiveRewardData{},
Last30D: types.ActiveRewardData{},
}
now := time.Now()
todayStart := now.Add(-24 * time.Hour) // 近24小时
last7dStart := now.AddDate(0, 0, -7) // 近7天
last30dStart := now.AddDate(0, 0, -30) // 近30天
for _, r := range rewards {
createTime := r.CreateTime
amount := r.Amount
// 总奖励累加
result.TotalReward += amount
// 时间范围判断
isToday := createTime.After(todayStart)
isLast7d := createTime.After(last7dStart)
isLast30d := createTime.After(last30dStart)
// 类型分类统计
switch r.Type {
case model.AgentRewardsTypeDescendantWithdraw:
addToPeriods(&result, amount, isToday, isLast7d, isLast30d, "withdraw")
case model.AgentRewardsTypeDescendantNewActive:
addToPeriods(&result, amount, isToday, isLast7d, isLast30d, "new_active")
case model.AgentRewardsTypeDescendantUpgradeSvip, model.AgentRewardsTypeDescendantUpgradeVip:
addToPeriods(&result, amount, isToday, isLast7d, isLast30d, "upgrade")
case model.AgentRewardsTypeDescendantPromotion:
addToPeriods(&result, amount, isToday, isLast7d, isLast30d, "promotion")
}
}
return result
}
// 统一处理时间段累加
func addToPeriods(res *types.ActiveReward, amount float64, today, last7d, last30d bool, t string) {
if today {
addToData(&res.Today, amount, t)
}
if last7d {
addToData(&res.Last7D, amount, t)
}
if last30d {
addToData(&res.Last30D, amount, t)
}
}
// 分类添加具体字段
func addToData(data *types.ActiveRewardData, amount float64, t string) {
switch t {
case "withdraw":
data.SubWithdrawReward += amount
case "new_active":
data.NewActiveReward += amount
case "upgrade":
data.SubUpgradeReward += amount
case "promotion":
data.SubPromoteReward += amount
}
}

View File

@@ -0,0 +1,67 @@
package agent
import (
"context"
"github.com/Masterminds/squirrel"
"github.com/jinzhu/copier"
"github.com/pkg/errors"
"tydata-server/common/ctxdata"
"tydata-server/common/xerr"
"tydata-server/app/user/cmd/api/internal/svc"
"tydata-server/app/user/cmd/api/internal/types"
"github.com/zeromicro/go-zero/core/logx"
)
type GetAgentRewardsLogic struct {
logx.Logger
ctx context.Context
svcCtx *svc.ServiceContext
}
func NewGetAgentRewardsLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetAgentRewardsLogic {
return &GetAgentRewardsLogic{
Logger: logx.WithContext(ctx),
ctx: ctx,
svcCtx: svcCtx,
}
}
func (l *GetAgentRewardsLogic) GetAgentRewards(req *types.GetRewardsReq) (resp *types.GetRewardsResp, err error) {
userID, err := ctxdata.GetUidFromCtx(l.ctx)
if err != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "获取代理奖励列表, %v", err)
}
agentModel, err := l.svcCtx.AgentModel.FindOneByUserId(l.ctx, userID)
if err != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "获取代理奖励列表, %v", err)
}
builder := l.svcCtx.AgentRewardsModel.SelectBuilder().Where(squirrel.Eq{
"agent_id": agentModel.Id,
})
agentRewardsModelList, total, err := l.svcCtx.AgentRewardsModel.FindPageListByPageWithTotal(l.ctx, builder, req.Page, req.PageSize, "create_time DESC")
if err != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "获取代理奖励列表, 查找列表错误, %v", err)
}
var list = make([]types.Rewards, 0)
if len(agentRewardsModelList) > 0 {
for _, agentRewardsModel := range agentRewardsModelList {
var rewards types.Rewards
copyErr := copier.Copy(&rewards, agentRewardsModel)
if copyErr != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "获取代理奖励列表, %v", err)
}
rewards.CreateTime = agentRewardsModel.CreateTime.Format("2006-01-02 15:04:05")
list = append(list, rewards)
}
}
return &types.GetRewardsResp{
Total: total,
List: list,
}, nil
return
}

View File

@@ -0,0 +1,65 @@
package agent
import (
"context"
"github.com/Masterminds/squirrel"
"github.com/jinzhu/copier"
"github.com/pkg/errors"
"tydata-server/common/ctxdata"
"tydata-server/common/xerr"
"tydata-server/app/user/cmd/api/internal/svc"
"tydata-server/app/user/cmd/api/internal/types"
"github.com/zeromicro/go-zero/core/logx"
)
type GetAgentWithdrawalLogic struct {
logx.Logger
ctx context.Context
svcCtx *svc.ServiceContext
}
func NewGetAgentWithdrawalLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetAgentWithdrawalLogic {
return &GetAgentWithdrawalLogic{
Logger: logx.WithContext(ctx),
ctx: ctx,
svcCtx: svcCtx,
}
}
func (l *GetAgentWithdrawalLogic) GetAgentWithdrawal(req *types.GetWithdrawalReq) (resp *types.GetWithdrawalResp, err error) {
userID, err := ctxdata.GetUidFromCtx(l.ctx)
if err != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "获取代理提现列表, %v", err)
}
agentModel, err := l.svcCtx.AgentModel.FindOneByUserId(l.ctx, userID)
if err != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "获取代理提现列表, %v", err)
}
builder := l.svcCtx.AgentWithdrawalModel.SelectBuilder().Where(squirrel.Eq{
"agent_id": agentModel.Id,
})
agentWithdrawalModelList, total, err := l.svcCtx.AgentWithdrawalModel.FindPageListByPageWithTotal(l.ctx, builder, req.Page, req.PageSize, "create_time DESC")
if err != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "获取代理提现列表, 查找列表错误, %v", err)
}
var list = make([]types.Withdrawal, 0)
if len(agentWithdrawalModelList) > 0 {
for _, agentWithdrawalModel := range agentWithdrawalModelList {
var withdrawal types.Withdrawal
copyErr := copier.Copy(&withdrawal, agentWithdrawalModel)
if copyErr != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "获取代理提现列表, %v", err)
}
withdrawal.CreateTime = agentWithdrawalModel.CreateTime.Format("2006-01-02 15:04:05")
list = append(list, withdrawal)
}
}
return &types.GetWithdrawalResp{
Total: total,
List: list,
}, nil
}

View File

@@ -0,0 +1,45 @@
package agent
import (
"context"
"github.com/jinzhu/copier"
"github.com/pkg/errors"
"tydata-server/common/xerr"
"tydata-server/app/user/cmd/api/internal/svc"
"tydata-server/app/user/cmd/api/internal/types"
"github.com/zeromicro/go-zero/core/logx"
)
type GetLinkDataLogic struct {
logx.Logger
ctx context.Context
svcCtx *svc.ServiceContext
}
func NewGetLinkDataLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetLinkDataLogic {
return &GetLinkDataLogic{
Logger: logx.WithContext(ctx),
ctx: ctx,
svcCtx: svcCtx,
}
}
func (l *GetLinkDataLogic) GetLinkData(req *types.GetLinkDataReq) (resp *types.GetLinkDataResp, err error) {
agentLinkModel, err := l.svcCtx.AgentLinkModel.FindOneByLinkIdentifier(l.ctx, req.LinkIdentifier)
if err != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "获取代理链接数据, %v", err)
}
productModel, err := l.svcCtx.ProductModel.FindOne(l.ctx, agentLinkModel.ProductId)
if err != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "获取代理链接数据, %v", err)
}
var product types.Product
copier.Copy(&product, productModel)
product.SellPrice = agentLinkModel.Price
return &types.GetLinkDataResp{
Product: product,
}, nil
}

View File

@@ -0,0 +1,63 @@
package agent
import (
"context"
"github.com/jinzhu/copier"
"github.com/pkg/errors"
"tydata-server/app/user/model"
"tydata-server/common/ctxdata"
"tydata-server/common/xerr"
"tydata-server/app/user/cmd/api/internal/svc"
"tydata-server/app/user/cmd/api/internal/types"
"github.com/zeromicro/go-zero/core/logx"
)
type SaveAgentMembershipUserConfigLogic struct {
logx.Logger
ctx context.Context
svcCtx *svc.ServiceContext
}
func NewSaveAgentMembershipUserConfigLogic(ctx context.Context, svcCtx *svc.ServiceContext) *SaveAgentMembershipUserConfigLogic {
return &SaveAgentMembershipUserConfigLogic{
Logger: logx.WithContext(ctx),
ctx: ctx,
svcCtx: svcCtx,
}
}
func (l *SaveAgentMembershipUserConfigLogic) SaveAgentMembershipUserConfig(req *types.SaveAgentMembershipUserConfigReq) error {
userID, err := ctxdata.GetUidFromCtx(l.ctx)
if err != nil {
return errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "保存会员代理报告配置获取用户ID失败: %v", err)
}
agentModel, err := l.svcCtx.AgentModel.FindOneByUserId(l.ctx, userID)
if err != nil {
return errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "保存会员代理报告配置: %v", err)
}
agentMembershipUserConfigModel, err := l.svcCtx.AgentMembershipUserConfigModel.FindOneByAgentIdProductId(l.ctx, agentModel.Id, req.ProductID)
if err != nil && !errors.Is(err, model.ErrNotFound) {
return err
}
err = copier.Copy(&agentMembershipUserConfigModel, &req)
if err != nil {
return errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "保存会员代理报告配置: %v", err)
}
if agentMembershipUserConfigModel == nil {
agentMembershipUserConfigModel.UserId = userID
agentMembershipUserConfigModel.AgentId = agentModel.Id
_, err = l.svcCtx.AgentMembershipUserConfigModel.Insert(l.ctx, nil, agentMembershipUserConfigModel)
if err != nil {
return errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "保存会员代理报告配置: %v", err)
}
} else {
_, err = l.svcCtx.AgentMembershipUserConfigModel.Update(l.ctx, nil, agentMembershipUserConfigModel)
if err != nil {
return errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "保存会员代理报告配置: %v", err)
}
}
return nil
}

View File

@@ -50,7 +50,7 @@ func (l *SendSmsLogic) SendSms(req *types.SendSmsReq) error {
// 发送短信
smsResp, err := l.sendSmsRequest(req.Mobile, code)
if err != nil {
return errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "短信发送, 调用阿里客户端失败: %+v", err)
return errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "短信发送, 调用阿里客户端失败: %v", err)
}
if *smsResp.Body.Code != "OK" {
return errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "短信发送, 阿里客户端响应失败: %s", *smsResp.Body.Message)
@@ -59,12 +59,12 @@ func (l *SendSmsLogic) SendSms(req *types.SendSmsReq) error {
// 将验证码保存到 Redis设置过期时间
err = l.svcCtx.Redis.Setex(codeKey, code, l.svcCtx.Config.VerifyCode.ValidTime) // 验证码有效期5分钟
if err != nil {
return errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "短信发送, 验证码设置过期时间失败: %+v", err)
return errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "短信发送, 验证码设置过期时间失败: %v", err)
}
// 在 Redis 中设置 1 分钟的标记,限制重复请求
err = l.svcCtx.Redis.Setex(limitCodeKey, code, 60) // 标记 1 分钟内不能重复请求
if err != nil {
return errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "短信发送, 验证码设置限制重复请求失败: %+v", err)
return errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "短信发送, 验证码设置限制重复请求失败: %v", err)
}
return nil
}

View File

@@ -4,6 +4,7 @@ import (
"context"
"github.com/smartwalle/alipay/v3"
"net/http"
"os"
"time"
"tydata-server/pkg/lzkit/lzUtils"
@@ -26,9 +27,13 @@ func NewAlipayCallbackLogic(ctx context.Context, svcCtx *svc.ServiceContext) *Al
}
func (l *AlipayCallbackLogic) AlipayCallback(w http.ResponseWriter, r *http.Request) error {
env := os.Getenv("ENV")
if env == "development" {
return nil
}
notification, err := l.svcCtx.AlipayService.HandleAliPaymentNotification(r)
if err != nil {
logx.Errorf("支付宝支付回调,%+v", err)
logx.Errorf("支付宝支付回调,%v", err)
return nil
}
order, findOrderErr := l.svcCtx.OrderModel.FindOneByOrderNo(l.ctx, notification.OutTradeNo)

View File

@@ -8,6 +8,7 @@ import (
"github.com/pkg/errors"
"github.com/zeromicro/go-zero/core/logx"
"github.com/zeromicro/go-zero/core/stores/sqlx"
"os"
"tydata-server/app/user/cmd/api/internal/svc"
"tydata-server/app/user/cmd/api/internal/types"
"tydata-server/app/user/model"
@@ -48,12 +49,12 @@ func (l *PaymentLogic) Payment(req *types.PaymentReq) (resp *types.PaymentResp,
var data types.QueryCacheLoad
err = json.Unmarshal([]byte(cache), &data)
if err != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "生成订单, 解析缓存内容失败, %+v", err)
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "生成订单, 解析缓存内容失败, %v", err)
}
product, err := l.svcCtx.ProductModel.FindOneByProductEn(l.ctx, data.Product)
if err != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "生成订单, 查找产品错误: %+v", err)
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "生成订单, 查找产品错误: %v", err)
}
secretKey := l.svcCtx.Config.Encrypt.SecretKey
key, decodeErr := hex.DecodeString(secretKey)
@@ -71,16 +72,28 @@ func (l *PaymentLogic) Payment(req *types.PaymentReq) (resp *types.PaymentResp,
var prepayData interface{}
var outTradeNo string
var amount float64
var orderAmount float64
user, err := l.svcCtx.UserModel.FindOne(l.ctx, userID)
if err != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "生成订单, 获取用户信息失败: %+v", err)
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "生成订单, 获取用户信息失败: %v", err)
}
if data.AgentIdentifier != "" {
agentLinkModel, findAgentLinkErr := l.svcCtx.AgentLinkModel.FindOneByLinkIdentifier(l.ctx, data.AgentIdentifier)
if findAgentLinkErr != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "生成订单, 获取代理订单失败: %+v", findAgentLinkErr)
}
amount = agentLinkModel.Price
orderAmount = agentLinkModel.Price
} else {
amount = product.SellPrice
orderAmount = product.SellPrice
}
if user.Inside == 1 {
amount = 0.01
} else {
amount = product.SellPrice
}
var createOrderErr error
if req.PayMethod == "wechat" {
outTradeNo = l.svcCtx.WechatPayService.GenerateOutTradeNo()
@@ -103,16 +116,16 @@ func (l *PaymentLogic) Payment(req *types.PaymentReq) (resp *types.PaymentResp,
ProductId: product.Id,
PaymentPlatform: req.PayMethod,
PaymentScene: "app",
Amount: amount,
Amount: orderAmount,
Status: "pending",
}
orderInsertResult, insertOrderErr := l.svcCtx.OrderModel.Insert(ctx, session, &order)
if insertOrderErr != nil {
return errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "生成订单, 保存订单失败: %+v", insertOrderErr)
return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "生成订单, 保存订单失败: %+v", insertOrderErr)
}
insertedOrderID, lastInsertIdErr := orderInsertResult.LastInsertId()
if lastInsertIdErr != nil {
return errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "生成订单, 获取保存订单ID失败: %+v", lastInsertIdErr)
return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "生成订单, 获取保存订单ID失败: %+v", lastInsertIdErr)
}
orderID = insertedOrderID
query := model.Query{
@@ -124,14 +137,32 @@ func (l *PaymentLogic) Payment(req *types.PaymentReq) (resp *types.PaymentResp,
}
_, insertQueryErr := l.svcCtx.QueryModel.Insert(l.ctx, session, &query)
if insertQueryErr != nil {
return insertQueryErr
return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "生成订单, 保存查询失败: %+v", lastInsertIdErr)
}
if data.AgentIdentifier != "" {
agent, parsingErr := l.agentParsing(data.AgentIdentifier)
if parsingErr != nil {
return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "生成订单, 解析代理标识符失败: %+v", parsingErr)
}
var agentOrder model.AgentOrder
agentOrder.OrderId = orderID
agentOrder.AgentId = agent.AgentID
_, agentOrderInsert := l.svcCtx.AgentOrderModel.Insert(ctx, session, &agentOrder)
if agentOrderInsert != nil {
return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "生成订单, 保存代理订单失败: %+v", agentOrderInsert)
}
}
return nil
})
if transErr != nil {
return nil, transErr
}
env := os.Getenv("ENV")
if env == "development" {
if asyncErr := l.svcCtx.AsynqService.SendQueryTask(orderID); asyncErr != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "生成订单, 异步订单调用失败: %+v", asyncErr)
}
}
switch v := prepayData.(type) {
case string:
// 如果 prepayData 是字符串类型,直接返回
@@ -140,3 +171,21 @@ func (l *PaymentLogic) Payment(req *types.PaymentReq) (resp *types.PaymentResp,
return &types.PaymentResp{PrepayData: prepayData, OrderID: orderID}, nil
}
}
func (l *PaymentLogic) agentParsing(agentIdentifier string) (*types.AgentIdentifier, error) {
key, decodeErr := hex.DecodeString("8e3e7a2f60edb49221e953b9c029ed10")
if decodeErr != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 获取AES密钥失败: %+v", decodeErr)
}
// Encrypt the params
encrypted, err := crypto.AesDecryptURL(agentIdentifier, key)
if err != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, %v", err)
}
var agentIdentifierStruct types.AgentIdentifier
err = json.Unmarshal(encrypted, &agentIdentifierStruct)
if err != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务,反序列化失败 %v", err)
}
return &agentIdentifierStruct, nil
}

View File

@@ -28,7 +28,7 @@ func NewWechatPayCallbackLogic(ctx context.Context, svcCtx *svc.ServiceContext)
func (l *WechatPayCallbackLogic) WechatPayCallback(w http.ResponseWriter, r *http.Request) error {
notification, err := l.svcCtx.WechatPayService.HandleWechatPayNotification(l.ctx, r)
if err != nil {
logx.Errorf("微信支付回调,%+v", err)
logx.Errorf("微信支付回调,%v", err)
return nil
}
order, findOrderErr := l.svcCtx.OrderModel.FindOneByOrderNo(l.ctx, *notification.OutTradeNo)

View File

@@ -25,7 +25,7 @@ func NewWechatPayRefundCallbackLogic(ctx context.Context, svcCtx *svc.ServiceCon
func (l *WechatPayRefundCallbackLogic) WechatPayRefundCallback(w http.ResponseWriter, r *http.Request) error {
notification, err := l.svcCtx.WechatPayService.HandleRefundNotification(l.ctx, r)
if err != nil {
logx.Errorf("微信退款回调,%+v", err)
logx.Errorf("微信退款回调,%v", err)
return nil
}
order, findOrderErr := l.svcCtx.OrderModel.FindOneByOrderNo(l.ctx, *notification.OutTradeNo)

View File

@@ -32,7 +32,7 @@ func NewGetProductByEnLogic(ctx context.Context, svcCtx *svc.ServiceContext) *Ge
func (l *GetProductByEnLogic) GetProductByEn(req *types.GetProductByEnRequest) (resp *types.ProductResponse, err error) {
productModel, err := l.svcCtx.ProductModel.FindOneByProductEn(l.ctx, req.ProductEn)
if err != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "产品查询, 查找产品错误: %+v", err)
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "产品查询, 查找产品错误: %v", err)
}
build := l.svcCtx.ProductFeatureModel.SelectBuilder().Where(squirrel.Eq{
@@ -40,12 +40,12 @@ func (l *GetProductByEnLogic) GetProductByEn(req *types.GetProductByEnRequest) (
})
productFeatureAll, err := l.svcCtx.ProductFeatureModel.FindAll(l.ctx, build, "")
if err != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "产品查询, 查找产品关联错误: %+v", err)
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "产品查询, 查找产品关联错误: %v", err)
}
var product types.Product
err = copier.Copy(&product, productModel)
if err != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "用户信息, 用户信息结构体复制失败, %+v", err)
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "用户信息, 用户信息结构体复制失败, %v", err)
}
mr.MapReduceVoid(func(source chan<- interface{}) {
for _, productFeature := range productFeatureAll {

View File

@@ -1,140 +0,0 @@
package query
import (
"context"
"encoding/hex"
"encoding/json"
"fmt"
"github.com/pkg/errors"
"github.com/zeromicro/go-zero/core/stores/redis"
"time"
"tydata-server/app/user/cmd/api/internal/service"
"tydata-server/common/ctxdata"
"tydata-server/common/xerr"
"tydata-server/pkg/lzkit/crypto"
"tydata-server/pkg/lzkit/validator"
"tydata-server/app/user/cmd/api/internal/svc"
"tydata-server/app/user/cmd/api/internal/types"
"github.com/zeromicro/go-zero/core/logx"
)
type BackgroundCheckLogic struct {
logx.Logger
ctx context.Context
svcCtx *svc.ServiceContext
}
func NewBackgroundCheckLogic(ctx context.Context, svcCtx *svc.ServiceContext) *BackgroundCheckLogic {
return &BackgroundCheckLogic{
Logger: logx.WithContext(ctx),
ctx: ctx,
svcCtx: svcCtx,
}
}
func (l *BackgroundCheckLogic) BackgroundCheck(req *types.QueryReq) (resp *types.QueryResp, err error) {
userID, getUidErr := ctxdata.GetUidFromCtx(l.ctx)
if getUidErr != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "人事背调, 获取用户信息失败, %+v", getUidErr)
}
// 1、AES解密
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(req.Data, key)
if aesDecryptErr != nil || len(decryptData) == 0 {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "人事背调, 解密失败: %+v", decodeErr)
}
// 2、校验
var data types.BackgroundCheckReq
if unmarshalErr := json.Unmarshal(decryptData, &data); unmarshalErr != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "人事背调, 解密后的数据格式不正确: %+v", unmarshalErr)
}
if validatorErr := validator.Validate(data); validatorErr != nil {
return nil, errors.Wrapf(xerr.NewErrCodeMsg(xerr.PARAM_VERIFICATION_ERROR, validatorErr.Error()), "人事背调, 参数不正确: %+v", validatorErr)
}
if data.Name == "刘福思" && data.IDCard == "45262419980929047X" && data.Mobile == "17776203797" {
// 缓存
queryCache := types.QueryCache{
Name: data.Name,
IDCard: data.IDCard,
Mobile: data.Mobile,
Product: "backgroundcheck",
}
jsonData, marshalErr := json.Marshal(queryCache)
if marshalErr != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "婚恋评估, 序列化参数失败: %+v", marshalErr)
}
outTradeNo := l.svcCtx.WechatPayService.GenerateOutTradeNo()
redisKey := fmt.Sprintf("%d:%s", userID, outTradeNo)
cacheErr := l.svcCtx.Redis.SetexCtx(l.ctx, redisKey, string(jsonData), int(2*time.Hour))
if cacheErr != nil {
return nil, cacheErr
}
return &types.QueryResp{Id: outTradeNo}, nil
}
// 校验验证码
codeRedisKey := fmt.Sprintf("%s:%s", "query", data.Mobile)
cacheCode, err := l.svcCtx.Redis.Get(codeRedisKey)
if err != nil {
if errors.Is(err, redis.Nil) {
return nil, errors.Wrapf(xerr.NewErrMsg("验证码已过期"), "人事背调, 验证码过期: %s", data.Mobile)
}
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "人事背调, 读取验证码redis缓存失败, mobile: %s, err: %+v", data.Mobile, err)
}
if cacheCode != data.Code {
return nil, errors.Wrapf(xerr.NewErrMsg("验证码不正确"), "人事背调, 验证码不正确: %s", data.Mobile)
}
// 3、二要素三要素核验
//twoVerification := service.TwoFactorVerificationRequest{
// Name: data.Name,
// IDCard: data.IDCard,
//}
//verification, err := l.svcCtx.VerificationService.TwoFactorVerification(twoVerification)
//if err != nil {
// return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "人事背调, 二要素验证失败: %+v", err)
//}
//if !verification.Passed {
// return nil, errors.Wrapf(xerr.NewErrCodeMsg(xerr.SERVER_COMMON_ERROR, verification.Err.Error()), "人事背调, 二要素验证不通过: %+v", err)
//}
// 3、二要素三要素核验
threeVerification := service.ThreeFactorVerificationRequest{
Name: data.Name,
IDCard: data.IDCard,
Mobile: data.Mobile,
}
verification, err := l.svcCtx.VerificationService.ThreeFactorVerification(threeVerification)
if err != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "人事背调, 三要素验证失败: %+v", err)
}
if !verification.Passed {
return nil, errors.Wrapf(xerr.NewErrCodeMsg(xerr.SERVER_COMMON_ERROR, verification.Err.Error()), "人事背调, 三要素验证不通过: %+v", err)
}
// 缓存
queryCache := types.QueryCache{
Name: data.Name,
IDCard: data.IDCard,
Mobile: data.Mobile,
Product: "backgroundcheck",
}
jsonData, marshalErr := json.Marshal(queryCache)
if marshalErr != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "人事背调, 序列化参数失败: %+v", marshalErr)
}
outTradeNo := l.svcCtx.WechatPayService.GenerateOutTradeNo()
redisKey := fmt.Sprintf("%d:%s", userID, outTradeNo)
cacheErr := l.svcCtx.Redis.SetexCtx(l.ctx, redisKey, string(jsonData), int(2*time.Hour))
if cacheErr != nil {
return nil, cacheErr
}
return &types.QueryResp{Id: outTradeNo}, nil
}

View File

@@ -1,140 +0,0 @@
package query
import (
"context"
"encoding/hex"
"encoding/json"
"fmt"
"github.com/pkg/errors"
"github.com/zeromicro/go-zero/core/stores/redis"
"time"
"tydata-server/app/user/cmd/api/internal/service"
"tydata-server/common/ctxdata"
"tydata-server/common/xerr"
"tydata-server/pkg/lzkit/crypto"
"tydata-server/pkg/lzkit/validator"
"tydata-server/app/user/cmd/api/internal/svc"
"tydata-server/app/user/cmd/api/internal/types"
"github.com/zeromicro/go-zero/core/logx"
)
type CompanyInfoLogic struct {
logx.Logger
ctx context.Context
svcCtx *svc.ServiceContext
}
func NewCompanyInfoLogic(ctx context.Context, svcCtx *svc.ServiceContext) *CompanyInfoLogic {
return &CompanyInfoLogic{
Logger: logx.WithContext(ctx),
ctx: ctx,
svcCtx: svcCtx,
}
}
func (l *CompanyInfoLogic) CompanyInfo(req *types.QueryReq) (resp *types.QueryResp, err error) {
userID, getUidErr := ctxdata.GetUidFromCtx(l.ctx)
if getUidErr != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "企业报告, 获取用户信息失败, %+v", getUidErr)
}
// 1、AES解密
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(req.Data, key)
if aesDecryptErr != nil || len(decryptData) == 0 {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "企业报告, 解密失败: %+v", decodeErr)
}
// 2、校验
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)
}
if data.Name == "刘福思" && data.IDCard == "45262419980929047X" && data.Mobile == "17776203797" {
// 缓存
queryCache := types.QueryCache{
Name: data.Name,
IDCard: data.IDCard,
Mobile: data.Mobile,
Product: "companyinfo",
}
jsonData, marshalErr := json.Marshal(queryCache)
if marshalErr != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "婚恋评估, 序列化参数失败: %+v", marshalErr)
}
outTradeNo := l.svcCtx.WechatPayService.GenerateOutTradeNo()
redisKey := fmt.Sprintf("%d:%s", userID, outTradeNo)
cacheErr := l.svcCtx.Redis.SetexCtx(l.ctx, redisKey, string(jsonData), int(2*time.Hour))
if cacheErr != nil {
return nil, cacheErr
}
return &types.QueryResp{Id: outTradeNo}, nil
}
// 校验验证码
codeRedisKey := fmt.Sprintf("%s:%s", "query", data.Mobile)
cacheCode, err := l.svcCtx.Redis.Get(codeRedisKey)
if err != nil {
if errors.Is(err, redis.Nil) {
return nil, errors.Wrapf(xerr.NewErrMsg("验证码已过期"), "企业报告, 验证码过期: %s", data.Mobile)
}
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "企业报告, 读取验证码redis缓存失败, mobile: %s, err: %+v", data.Mobile, err)
}
if cacheCode != data.Code {
return nil, errors.Wrapf(xerr.NewErrMsg("验证码不正确"), "企业报告, 验证码不正确: %s", data.Mobile)
}
// 3、二要素三要素核验
//twoVerification := service.TwoFactorVerificationRequest{
// Name: data.Name,
// IDCard: data.IDCard,
//}
//verification, err := l.svcCtx.VerificationService.TwoFactorVerification(twoVerification)
//if err != nil {
// return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "企业报告, 二要素验证失败: %+v", err)
//}
//if !verification.Passed {
// return nil, errors.Wrapf(xerr.NewErrCodeMsg(xerr.SERVER_COMMON_ERROR, verification.Err.Error()), "企业报告, 二要素验证不通过: %+v", err)
//}
// 3、二要素三要素核验
threeVerification := service.ThreeFactorVerificationRequest{
Name: data.Name,
IDCard: data.IDCard,
Mobile: data.Mobile,
}
verification, err := l.svcCtx.VerificationService.ThreeFactorVerification(threeVerification)
if err != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "企业报告, 三要素验证失败: %+v", err)
}
if !verification.Passed {
return nil, errors.Wrapf(xerr.NewErrCodeMsg(xerr.SERVER_COMMON_ERROR, verification.Err.Error()), "企业报告, 三要素验证不通过: %+v", err)
}
// 缓存
queryCache := types.QueryCache{
Name: data.Name,
IDCard: data.IDCard,
Mobile: data.Mobile,
Product: "companyinfo",
}
jsonData, marshalErr := json.Marshal(queryCache)
if marshalErr != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "企业报告, 序列化参数失败: %+v", marshalErr)
}
outTradeNo := l.svcCtx.WechatPayService.GenerateOutTradeNo()
redisKey := fmt.Sprintf("%d:%s", userID, outTradeNo)
cacheErr := l.svcCtx.Redis.SetexCtx(l.ctx, redisKey, string(jsonData), int(2*time.Hour))
if cacheErr != nil {
return nil, cacheErr
}
return &types.QueryResp{Id: outTradeNo}, nil
}

View File

@@ -1,141 +0,0 @@
package query
import (
"context"
"encoding/hex"
"encoding/json"
"fmt"
"github.com/pkg/errors"
"github.com/zeromicro/go-zero/core/stores/redis"
"time"
"tydata-server/app/user/cmd/api/internal/service"
"tydata-server/common/ctxdata"
"tydata-server/common/xerr"
"tydata-server/pkg/lzkit/crypto"
"tydata-server/pkg/lzkit/validator"
"tydata-server/app/user/cmd/api/internal/svc"
"tydata-server/app/user/cmd/api/internal/types"
"github.com/zeromicro/go-zero/core/logx"
)
type HomeServiceLogic struct {
logx.Logger
ctx context.Context
svcCtx *svc.ServiceContext
}
func NewHomeServiceLogic(ctx context.Context, svcCtx *svc.ServiceContext) *HomeServiceLogic {
return &HomeServiceLogic{
Logger: logx.WithContext(ctx),
ctx: ctx,
svcCtx: svcCtx,
}
}
func (l *HomeServiceLogic) HomeService(req *types.QueryReq) (resp *types.QueryResp, err error) {
userID, getUidErr := ctxdata.GetUidFromCtx(l.ctx)
if getUidErr != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "家政服务, 获取用户信息失败, %+v", getUidErr)
}
// 1、AES解密
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(req.Data, key)
if aesDecryptErr != nil || len(decryptData) == 0 {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "家政服务, 解密失败: %+v", decodeErr)
}
// 2、校验
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)
}
if data.Name == "刘福思" && data.IDCard == "45262419980929047X" && data.Mobile == "17776203797" {
// 缓存
queryCache := types.QueryCache{
Name: data.Name,
IDCard: data.IDCard,
Mobile: data.Mobile,
Product: "homeservice",
}
jsonData, marshalErr := json.Marshal(queryCache)
if marshalErr != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "婚恋评估, 序列化参数失败: %+v", marshalErr)
}
outTradeNo := l.svcCtx.WechatPayService.GenerateOutTradeNo()
redisKey := fmt.Sprintf("%d:%s", userID, outTradeNo)
cacheErr := l.svcCtx.Redis.SetexCtx(l.ctx, redisKey, string(jsonData), int(2*time.Hour))
if cacheErr != nil {
return nil, cacheErr
}
return &types.QueryResp{Id: outTradeNo}, nil
}
// 校验验证码
codeRedisKey := fmt.Sprintf("%s:%s", "query", data.Mobile)
cacheCode, err := l.svcCtx.Redis.Get(codeRedisKey)
if err != nil {
if errors.Is(err, redis.Nil) {
return nil, errors.Wrapf(xerr.NewErrMsg("验证码已过期"), "家政服务, 验证码过期: %s", data.Mobile)
}
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "家政服务, 读取验证码redis缓存失败, mobile: %s, err: %+v", data.Mobile, err)
}
if cacheCode != data.Code {
return nil, errors.Wrapf(xerr.NewErrMsg("验证码不正确"), "家政服务, 验证码不正确: %s", data.Mobile)
}
// 3、二要素三要素核验
//twoVerification := service.TwoFactorVerificationRequest{
// Name: data.Name,
// IDCard: data.IDCard,
//}
//verification, err := l.svcCtx.VerificationService.TwoFactorVerification(twoVerification)
//if err != nil {
// return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "家政服务, 二要素验证失败: %+v", err)
//}
//if !verification.Passed {
// return nil, errors.Wrapf(xerr.NewErrCodeMsg(xerr.SERVER_COMMON_ERROR, verification.Err.Error()), "家政服务, 二要素验证不通过: %+v", err)
//}
// 3、二要素三要素核验
threeVerification := service.ThreeFactorVerificationRequest{
Name: data.Name,
IDCard: data.IDCard,
Mobile: data.Mobile,
}
verification, err := l.svcCtx.VerificationService.ThreeFactorVerification(threeVerification)
if err != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "家政服务, 三要素验证失败: %+v", err)
}
if !verification.Passed {
return nil, errors.Wrapf(xerr.NewErrCodeMsg(xerr.SERVER_COMMON_ERROR, verification.Err.Error()), "家政服务, 三要素验证不通过: %+v", err)
}
// 缓存
queryCache := types.QueryCache{
Name: data.Name,
IDCard: data.IDCard,
Mobile: data.Mobile,
Product: "homeservice",
}
jsonData, marshalErr := json.Marshal(queryCache)
if marshalErr != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "家政服务, 序列化参数失败: %+v", marshalErr)
}
outTradeNo := l.svcCtx.WechatPayService.GenerateOutTradeNo()
redisKey := fmt.Sprintf("%d:%s", userID, outTradeNo)
cacheErr := l.svcCtx.Redis.SetexCtx(l.ctx, redisKey, string(jsonData), int(2*time.Hour))
if cacheErr != nil {
return nil, cacheErr
}
return &types.QueryResp{Id: outTradeNo}, nil
}

View File

@@ -1,142 +0,0 @@
package query
import (
"context"
"encoding/hex"
"encoding/json"
"fmt"
"github.com/pkg/errors"
"github.com/zeromicro/go-zero/core/logx"
"github.com/zeromicro/go-zero/core/stores/redis"
"time"
"tydata-server/app/user/cmd/api/internal/service"
"tydata-server/app/user/cmd/api/internal/svc"
"tydata-server/app/user/cmd/api/internal/types"
"tydata-server/common/ctxdata"
"tydata-server/common/xerr"
"tydata-server/pkg/lzkit/crypto"
"tydata-server/pkg/lzkit/validator"
)
type MarriageLogic struct {
logx.Logger
ctx context.Context
svcCtx *svc.ServiceContext
}
func NewMarriageLogic(ctx context.Context, svcCtx *svc.ServiceContext) *MarriageLogic {
return &MarriageLogic{
Logger: logx.WithContext(ctx),
ctx: ctx,
svcCtx: svcCtx,
}
}
const MERRIAGE = "marriage"
func (l *MarriageLogic) Marriage(req *types.QueryReq) (resp *types.QueryResp, err error) {
userID, getUidErr := ctxdata.GetUidFromCtx(l.ctx)
if getUidErr != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "婚恋评估, 获取用户信息失败, %+v", getUidErr)
}
// 1、AES解密
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(req.Data, key)
if aesDecryptErr != nil || len(decryptData) == 0 {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "婚恋评估, 解密失败: %+v", decodeErr)
}
// 2、校验
var data types.MarriageReq
if unmarshalErr := json.Unmarshal(decryptData, &data); unmarshalErr != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "婚恋评估, 解密后的数据格式不正确: %+v", unmarshalErr)
}
if validatorErr := validator.Validate(data); validatorErr != nil {
return nil, errors.Wrapf(xerr.NewErrCodeMsg(xerr.PARAM_VERIFICATION_ERROR, validatorErr.Error()), "婚恋评估, 参数不正确: %+v", validatorErr)
}
if data.Name == "刘福思" && data.IDCard == "45262419980929047X" && data.Mobile == "17776203797" {
// 缓存
queryCache := types.QueryCache{
Name: data.Name,
IDCard: data.IDCard,
Mobile: data.Mobile,
Product: MERRIAGE,
}
jsonData, marshalErr := json.Marshal(queryCache)
if marshalErr != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "婚恋评估, 序列化参数失败: %+v", marshalErr)
}
outTradeNo := l.svcCtx.WechatPayService.GenerateOutTradeNo()
redisKey := fmt.Sprintf("%d:%s", userID, outTradeNo)
cacheErr := l.svcCtx.Redis.SetexCtx(l.ctx, redisKey, string(jsonData), int(2*time.Hour))
if cacheErr != nil {
return nil, cacheErr
}
return &types.QueryResp{Id: outTradeNo}, nil
}
// 校验验证码
codeRedisKey := fmt.Sprintf("%s:%s", "query", data.Mobile)
cacheCode, err := l.svcCtx.Redis.Get(codeRedisKey)
if err != nil {
if errors.Is(err, redis.Nil) {
return nil, errors.Wrapf(xerr.NewErrMsg("验证码已过期"), "婚恋评估, 验证码过期: %s", data.Mobile)
}
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "婚恋评估, 读取验证码redis缓存失败, mobile: %s, err: %+v", data.Mobile, err)
}
if cacheCode != data.Code {
return nil, errors.Wrapf(xerr.NewErrMsg("验证码不正确"), "婚恋评估, 验证码不正确: %s", data.Mobile)
}
//// 3、二要素核验
//twoVerification := service.TwoFactorVerificationRequest{
// Name: data.Name,
// IDCard: data.IDCard,
//}
//verification, err := l.svcCtx.VerificationService.TwoFactorVerification(twoVerification)
//if err != nil {
// return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "婚恋评估, 二要素验证失败: %+v", err)
//}
//if !verification.Passed {
// return nil, errors.Wrapf(xerr.NewErrCodeMsg(xerr.SERVER_COMMON_ERROR, verification.Err.Error()), "婚恋评估, 二要素验证不通过: %+v", err)
//}
// 3、三要素核验
threeVerification := service.ThreeFactorVerificationRequest{
Name: data.Name,
IDCard: data.IDCard,
Mobile: data.Mobile,
}
verification, err := l.svcCtx.VerificationService.ThreeFactorVerification(threeVerification)
if err != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "婚恋评估, 三要素验证失败: %+v", err)
}
if !verification.Passed {
return nil, errors.Wrapf(xerr.NewErrCodeMsg(xerr.SERVER_COMMON_ERROR, verification.Err.Error()), "婚恋评估, 三要素验证不通过: %+v", err)
}
// 缓存
queryCache := types.QueryCache{
Name: data.Name,
IDCard: data.IDCard,
Mobile: data.Mobile,
Product: MERRIAGE,
}
jsonData, marshalErr := json.Marshal(queryCache)
if marshalErr != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "婚恋评估, 序列化参数失败: %+v", marshalErr)
}
outTradeNo := l.svcCtx.WechatPayService.GenerateOutTradeNo()
redisKey := fmt.Sprintf("%d:%s", userID, outTradeNo)
cacheErr := l.svcCtx.Redis.SetexCtx(l.ctx, redisKey, string(jsonData), int(2*time.Hour))
if cacheErr != nil {
return nil, cacheErr
}
return &types.QueryResp{Id: outTradeNo}, nil
}

View File

@@ -1,140 +0,0 @@
package query
import (
"context"
"encoding/hex"
"encoding/json"
"fmt"
"github.com/pkg/errors"
"github.com/zeromicro/go-zero/core/stores/redis"
"time"
"tydata-server/app/user/cmd/api/internal/service"
"tydata-server/common/ctxdata"
"tydata-server/common/xerr"
"tydata-server/pkg/lzkit/crypto"
"tydata-server/pkg/lzkit/validator"
"tydata-server/app/user/cmd/api/internal/svc"
"tydata-server/app/user/cmd/api/internal/types"
"github.com/zeromicro/go-zero/core/logx"
)
type PreLoanBackgroundCheckLogic struct {
logx.Logger
ctx context.Context
svcCtx *svc.ServiceContext
}
func NewPreLoanBackgroundCheckLogic(ctx context.Context, svcCtx *svc.ServiceContext) *PreLoanBackgroundCheckLogic {
return &PreLoanBackgroundCheckLogic{
Logger: logx.WithContext(ctx),
ctx: ctx,
svcCtx: svcCtx,
}
}
func (l *PreLoanBackgroundCheckLogic) PreLoanBackgroundCheck(req *types.QueryReq) (resp *types.QueryResp, err error) {
userID, getUidErr := ctxdata.GetUidFromCtx(l.ctx)
if getUidErr != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "贷前背调, 获取用户信息失败, %+v", getUidErr)
}
// 1、AES解密
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(req.Data, key)
if aesDecryptErr != nil || len(decryptData) == 0 {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "贷前背调, 解密失败: %+v", decodeErr)
}
// 2、校验
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)
}
if data.Name == "刘福思" && data.IDCard == "45262419980929047X" && data.Mobile == "17776203797" {
// 缓存
queryCache := types.QueryCache{
Name: data.Name,
IDCard: data.IDCard,
Mobile: data.Mobile,
Product: "preloanbackgroundcheck",
}
jsonData, marshalErr := json.Marshal(queryCache)
if marshalErr != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "婚恋评估, 序列化参数失败: %+v", marshalErr)
}
outTradeNo := l.svcCtx.WechatPayService.GenerateOutTradeNo()
redisKey := fmt.Sprintf("%d:%s", userID, outTradeNo)
cacheErr := l.svcCtx.Redis.SetexCtx(l.ctx, redisKey, string(jsonData), int(2*time.Hour))
if cacheErr != nil {
return nil, cacheErr
}
return &types.QueryResp{Id: outTradeNo}, nil
}
// 校验验证码
codeRedisKey := fmt.Sprintf("%s:%s", "query", data.Mobile)
cacheCode, err := l.svcCtx.Redis.Get(codeRedisKey)
if err != nil {
if errors.Is(err, redis.Nil) {
return nil, errors.Wrapf(xerr.NewErrMsg("验证码已过期"), "贷前背调, 验证码过期: %s", data.Mobile)
}
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "贷前背调, 读取验证码redis缓存失败, mobile: %s, err: %+v", data.Mobile, err)
}
if cacheCode != data.Code {
return nil, errors.Wrapf(xerr.NewErrMsg("验证码不正确"), "贷前背调, 验证码不正确: %s", data.Mobile)
}
// 3、二要素三要素核验
//twoVerification := service.TwoFactorVerificationRequest{
// Name: data.Name,
// IDCard: data.IDCard,
//}
//verification, err := l.svcCtx.VerificationService.TwoFactorVerification(twoVerification)
//if err != nil {
// return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "贷前背调, 二要素验证失败: %+v", err)
//}
//if !verification.Passed {
// return nil, errors.Wrapf(xerr.NewErrCodeMsg(xerr.SERVER_COMMON_ERROR, verification.Err.Error()), "贷前背调, 二要素验证不通过: %+v", err)
//}
// 3、二要素三要素核验
threeVerification := service.ThreeFactorVerificationRequest{
Name: data.Name,
IDCard: data.IDCard,
Mobile: data.Mobile,
}
verification, err := l.svcCtx.VerificationService.ThreeFactorVerification(threeVerification)
if err != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "贷前背调, 三要素验证失败: %+v", err)
}
if !verification.Passed {
return nil, errors.Wrapf(xerr.NewErrCodeMsg(xerr.SERVER_COMMON_ERROR, verification.Err.Error()), "贷前背调, 三要素验证不通过: %+v", err)
}
// 缓存
queryCache := types.QueryCache{
Name: data.Name,
IDCard: data.IDCard,
Mobile: data.Mobile,
Product: "preloanbackgroundcheck",
}
jsonData, marshalErr := json.Marshal(queryCache)
if marshalErr != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "贷前背调, 序列化参数失败: %+v", marshalErr)
}
outTradeNo := l.svcCtx.WechatPayService.GenerateOutTradeNo()
redisKey := fmt.Sprintf("%d:%s", userID, outTradeNo)
cacheErr := l.svcCtx.Redis.SetexCtx(l.ctx, redisKey, string(jsonData), int(2*time.Hour))
if cacheErr != nil {
return nil, cacheErr
}
return &types.QueryResp{Id: outTradeNo}, nil
}

View File

@@ -38,13 +38,13 @@ func (l *QueryDetailByOrderIdLogic) QueryDetailByOrderId(req *types.QueryDetailB
// 获取订单信息
order, err := l.svcCtx.OrderModel.FindOne(l.ctx, req.OrderId)
if err != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "报告查询, 查找报告错误: %+v", err)
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "报告查询, 查找报告错误: %v", err)
}
// 创建渐进式延迟策略实例
progressiveDelayOrder, err := delay.New(200*time.Millisecond, 3*time.Second, 10*time.Second, 1.5)
if err != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "初始化渐进式延迟策略失败: %+v", err)
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "初始化渐进式延迟策略失败: %v", err)
}
// 等待订单状态变为 "paid"
@@ -63,7 +63,7 @@ func (l *QueryDetailByOrderIdLogic) QueryDetailByOrderId(req *types.QueryDetailB
// 再次查找订单
order, err = l.svcCtx.OrderModel.FindOne(l.ctx, req.OrderId)
if err != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "报告查询, 查找订单错误: %+v", err)
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "报告查询, 查找订单错误: %v", err)
}
}
if order.Status != "paid" {
@@ -72,13 +72,13 @@ func (l *QueryDetailByOrderIdLogic) QueryDetailByOrderId(req *types.QueryDetailB
// 获取报告信息
queryModel, err := l.svcCtx.QueryModel.FindOneByOrderId(l.ctx, req.OrderId)
if err != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "报告查询, 查找报告错误: %+v", err)
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "报告查询, 查找报告错误: %v", err)
}
// 创建渐进式延迟实例
progressiveDelayQuery, err := delay.New(200*time.Millisecond, 3*time.Second, 10*time.Second, 1.5)
if err != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "初始化渐进式延迟策略失败: %+v", err)
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "初始化渐进式延迟策略失败: %v", err)
}
// 等待 queryModel.QueryState 不再是 "pending"
@@ -97,7 +97,7 @@ func (l *QueryDetailByOrderIdLogic) QueryDetailByOrderId(req *types.QueryDetailB
// 再次查询 report 状态
queryModel, err = l.svcCtx.QueryModel.FindOneByOrderId(l.ctx, req.OrderId)
if err != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "报告查询, 查找报告错误: %+v", err)
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "报告查询, 查找报告错误: %v", err)
}
}
@@ -114,7 +114,7 @@ func (l *QueryDetailByOrderIdLogic) QueryDetailByOrderId(req *types.QueryDetailB
secretKey := l.svcCtx.Config.Encrypt.SecretKey
key, decodeErr := hex.DecodeString(secretKey)
if decodeErr != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "报告查询, 获取AES解密解药失败, %+v", err)
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "报告查询, 获取AES解密解药失败, %v", err)
}
processParamsErr := ProcessQueryParams(queryModel.QueryParams, &query.QueryParams, key)
if processParamsErr != nil {
@@ -131,11 +131,11 @@ func (l *QueryDetailByOrderIdLogic) QueryDetailByOrderId(req *types.QueryDetailB
// 复制报告数据
err = copier.Copy(&query, queryModel)
if err != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "报告查询, 报告结构体复制失败, %+v", err)
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "报告查询, 报告结构体复制失败, %v", err)
}
product, err := l.svcCtx.ProductModel.FindOne(l.ctx, queryModel.ProductId)
if err != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "报告查询, 获取商品信息失败, %+v", err)
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "报告查询, 获取商品信息失败, %v", err)
}
query.ProductName = product.ProductName
return &types.QueryDetailByOrderIdResp{

View File

@@ -34,13 +34,13 @@ func (l *QueryDetailByOrderNoLogic) QueryDetailByOrderNo(req *types.QueryDetailB
// 获取订单信息
order, err := l.svcCtx.OrderModel.FindOneByOrderNo(l.ctx, req.OrderNo)
if err != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "报告查询, 查找报告错误: %+v", err)
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "报告查询, 查找报告错误: %v", err)
}
// 创建渐进式延迟策略实例
progressiveDelayOrder, err := delay.New(200*time.Millisecond, 3*time.Second, 10*time.Second, 1.5)
if err != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "初始化渐进式延迟策略失败: %+v", err)
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "初始化渐进式延迟策略失败: %v", err)
}
// 等待订单状态变为 "paid"
@@ -59,7 +59,7 @@ func (l *QueryDetailByOrderNoLogic) QueryDetailByOrderNo(req *types.QueryDetailB
// 再次查找订单
order, err = l.svcCtx.OrderModel.FindOneByOrderNo(l.ctx, req.OrderNo)
if err != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "报告查询, 查找订单错误: %+v", err)
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "报告查询, 查找订单错误: %v", err)
}
}
if order.Status != "paid" {
@@ -68,13 +68,13 @@ func (l *QueryDetailByOrderNoLogic) QueryDetailByOrderNo(req *types.QueryDetailB
// 获取报告信息
queryModel, err := l.svcCtx.QueryModel.FindOneByOrderId(l.ctx, order.Id)
if err != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "报告查询, 查找报告错误: %+v", err)
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "报告查询, 查找报告错误: %v", err)
}
// 创建渐进式延迟实例
progressiveDelayQuery, err := delay.New(200*time.Millisecond, 3*time.Second, 10*time.Second, 1.5)
if err != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "初始化渐进式延迟策略失败: %+v", err)
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "初始化渐进式延迟策略失败: %v", err)
}
// 等待 queryModel.QueryState 不再是 "pending"
@@ -93,7 +93,7 @@ func (l *QueryDetailByOrderNoLogic) QueryDetailByOrderNo(req *types.QueryDetailB
// 再次查询 report 状态
queryModel, err = l.svcCtx.QueryModel.FindOneByOrderId(l.ctx, order.Id)
if err != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "报告查询, 查找报告错误: %+v", err)
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "报告查询, 查找报告错误: %v", err)
}
}
@@ -110,7 +110,7 @@ func (l *QueryDetailByOrderNoLogic) QueryDetailByOrderNo(req *types.QueryDetailB
secretKey := l.svcCtx.Config.Encrypt.SecretKey
key, decodeErr := hex.DecodeString(secretKey)
if decodeErr != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "报告查询, 获取AES解密解药失败, %+v", err)
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "报告查询, 获取AES解密解药失败, %v", err)
}
processParamsErr := ProcessQueryParams(queryModel.QueryParams, &query.QueryParams, key)
if processParamsErr != nil {
@@ -127,11 +127,11 @@ func (l *QueryDetailByOrderNoLogic) QueryDetailByOrderNo(req *types.QueryDetailB
// 复制报告数据
err = copier.Copy(&query, queryModel)
if err != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "报告查询, 报告结构体复制失败, %+v", err)
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "报告查询, 报告结构体复制失败, %v", err)
}
product, err := l.svcCtx.ProductModel.FindOne(l.ctx, queryModel.ProductId)
if err != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "报告查询, 获取商品信息失败, %+v", err)
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "报告查询, 获取商品信息失败, %v", err)
}
query.ProductName = product.ProductName
return &types.QueryDetailByOrderNoResp{

View File

@@ -33,7 +33,7 @@ func NewQueryDetailLogic(ctx context.Context, svcCtx *svc.ServiceContext) *Query
func (l *QueryDetailLogic) QueryDetail(req *types.QueryDetailReq) (resp *types.QueryDetailResp, err error) {
queryModel, err := l.svcCtx.QueryModel.FindOne(l.ctx, req.Id)
if err != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "报告查询, 查找报告错误: %+v", err)
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "报告查询, 查找报告错误: %v", err)
}
var query types.Query
@@ -42,7 +42,7 @@ func (l *QueryDetailLogic) QueryDetail(req *types.QueryDetailReq) (resp *types.Q
secretKey := l.svcCtx.Config.Encrypt.SecretKey
key, decodeErr := hex.DecodeString(secretKey)
if decodeErr != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "报告查询, 获取AES解密解药失败, %+v", err)
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "报告查询, 获取AES解密解药失败, %v", err)
}
if lzUtils.NullStringToString(queryModel.QueryData) != "" {
queryData, decryptErr := crypto.AesDecrypt(lzUtils.NullStringToString(queryModel.QueryData), key)
@@ -56,11 +56,11 @@ func (l *QueryDetailLogic) QueryDetail(req *types.QueryDetailReq) (resp *types.Q
}
err = copier.Copy(&query, queryModel)
if err != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "报告查询, 报告结构体复制失败, %+v", err)
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "报告查询, 报告结构体复制失败, %v", err)
}
product, err := l.svcCtx.ProductModel.FindOne(l.ctx, queryModel.ProductId)
if err != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "报告查询, 获取商品信息失败, %+v", err)
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "报告查询, 获取商品信息失败, %v", err)
}
query.ProductName = product.ProductName
return &types.QueryDetailResp{

View File

@@ -60,7 +60,7 @@ func (l *QueryExampleLogic) QueryExample(req *types.QueryExampleReq) (resp *type
secretKey := l.svcCtx.Config.Encrypt.SecretKey
key, decodeErr := hex.DecodeString(secretKey)
if decodeErr != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "示例报告, 获取AES解密解药失败, %+v", err)
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "示例报告, 获取AES解密解药失败, %v", err)
}
processParamsErr := ProcessQueryParams(queryModel.QueryParams, &query.QueryParams, key)
if processParamsErr != nil {
@@ -77,11 +77,11 @@ func (l *QueryExampleLogic) QueryExample(req *types.QueryExampleReq) (resp *type
// 复制报告数据
err = copier.Copy(&query, queryModel)
if err != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "示例报告, 报告结构体复制失败, %+v", err)
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "示例报告, 报告结构体复制失败, %v", err)
}
product, err := l.svcCtx.ProductModel.FindOne(l.ctx, queryModel.ProductId)
if err != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "示例报告, 获取商品信息失败, %+v", err)
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "示例报告, 获取商品信息失败, %v", err)
}
query.ProductName = product.ProductName
return &types.QueryExampleResp{

View File

@@ -38,7 +38,7 @@ func (l *QueryListLogic) QueryList(req *types.QueryListReq) (resp *types.QueryLi
})
orderList, total, err := l.svcCtx.OrderModel.FindPageListByPageWithTotal(l.ctx, build, req.Page, req.PageSize, "create_time DESC")
if err != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "报告列表查询, 查找订单列表错误, %+v", err)
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "报告列表查询, 查找订单列表错误, %v", err)
}
var list []types.Query
@@ -54,11 +54,11 @@ func (l *QueryListLogic) QueryList(req *types.QueryListReq) (resp *types.QueryLi
query.UpdateTime = queryModel.UpdateTime.Format("2006-01-02 15:04:05")
copyErr := copier.Copy(&query, queryModel)
if copyErr != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "报告列表查询, 报告结构体复制失败, %+v", err)
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "报告列表查询, 报告结构体复制失败, %v", err)
}
product, findProductErr := l.svcCtx.ProductModel.FindOne(l.ctx, queryModel.ProductId)
if findProductErr != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "报告列表查询, 获取商品信息失败, %+v", err)
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "报告列表查询, 获取商品信息失败, %v", err)
}
query.ProductName = product.ProductName
list = append(list, query)

View File

@@ -41,17 +41,17 @@ func (l *QueryProvisionalOrderLogic) QueryProvisionalOrder(req *types.QueryProvi
var data types.QueryCache
err = json.Unmarshal([]byte(cache), &data)
if err != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "获取临时订单, 解析缓存内容失败, %+v", err)
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "获取临时订单, 解析缓存内容失败, %v", err)
}
productModel, err := l.svcCtx.ProductModel.FindOneByProductEn(l.ctx, data.Product)
if err != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "获取临时订单, 查找产品错误: %+v", err)
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "获取临时订单, 查找产品错误: %v", err)
}
var product types.Product
err = copier.Copy(&product, productModel)
if err != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "获取临时订单, 用户信息结构体复制失败: %+v", err)
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "获取临时订单, 用户信息结构体复制失败: %v", err)
}
return &types.QueryProvisionalOrderResp{
Name: data.Name,

View File

@@ -29,7 +29,7 @@ func (l *QueryRetryLogic) QueryRetry(req *types.QueryRetryReq) (resp *types.Quer
query, err := l.svcCtx.QueryModel.FindOne(l.ctx, req.Id)
if err != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "报告查询重试, 查找报告失败, %+v", err)
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "报告查询重试, 查找报告失败, %v", err)
}
if query.QueryState == "success" {
return nil, errors.Wrapf(xerr.NewErrCodeMsg(xerr.LOGIN_FAILED, "该报告不能重试"), "报告查询重试, 该报告不能重试, %d", query.Id)

View File

@@ -0,0 +1,27 @@
package query
import (
"context"
"tydata-server/app/user/cmd/api/internal/svc"
"tydata-server/app/user/cmd/api/internal/types"
"github.com/zeromicro/go-zero/core/logx"
)
type QueryServiceAgentLogic struct {
logx.Logger
ctx context.Context
svcCtx *svc.ServiceContext
}
func NewQueryServiceAgentLogic(ctx context.Context, svcCtx *svc.ServiceContext) *QueryServiceAgentLogic {
return &QueryServiceAgentLogic{
Logger: logx.WithContext(ctx),
ctx: ctx,
svcCtx: svcCtx,
}
}
func (l *QueryServiceAgentLogic) QueryServiceAgent(req *types.QueryServiceReq) (resp *types.QueryServiceResp, err error) {
return &types.QueryServiceResp{}, nil
}

View File

@@ -7,9 +7,12 @@ import (
"fmt"
"github.com/pkg/errors"
"github.com/zeromicro/go-zero/core/stores/redis"
"github.com/zeromicro/go-zero/core/stores/sqlx"
"time"
"tydata-server/app/user/cmd/api/internal/service"
"tydata-server/app/user/model"
"tydata-server/common/ctxdata"
jwtx "tydata-server/common/jwt"
"tydata-server/common/xerr"
"tydata-server/pkg/lzkit/crypto"
"tydata-server/pkg/lzkit/validator"
@@ -35,9 +38,32 @@ func NewQueryServiceLogic(ctx context.Context, svcCtx *svc.ServiceContext) *Quer
}
func (l *QueryServiceLogic) QueryService(req *types.QueryServiceReq) (resp *types.QueryServiceResp, err error) {
if req.AgentIdentifier != "" {
l.ctx = context.WithValue(l.ctx, "agentIdentifier", req.AgentIdentifier)
return l.PreprocessLogic(req, req.Product)
}
return l.PreprocessLogic(req, req.Product)
}
//func (l *QueryServiceLogic) agentParsing(req *types.QueryServiceReq) (*types.AgentIdentifier, error) {
// key, decodeErr := hex.DecodeString("8e3e7a2f60edb49221e953b9c029ed10")
// if decodeErr != nil {
// return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 获取AES密钥失败: %+v", decodeErr)
// }
//
// encrypted, err := crypto.AesDecryptURL(req.Product, key)
// if err != nil {
// return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, %v", err)
// }
// var agentIdentifier types.AgentIdentifier
// err = json.Unmarshal(encrypted, &agentIdentifier)
// if err != nil {
// return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务,反序列化失败 %v", err)
// }
// l.ctx = context.WithValue(l.ctx, "agent", req.Agent)
// return &agentIdentifier, nil
//}
var productProcessors = map[string]func(*QueryServiceLogic, *types.QueryServiceReq) (*types.QueryServiceResp, error){
"marriage": (*QueryServiceLogic).ProcessMarriageLogic,
"homeservice": (*QueryServiceLogic).ProcessHomeServiceLogic,
@@ -72,10 +98,6 @@ func (l *QueryServiceLogic) PreprocessLogic(req *types.QueryServiceReq, product
return nil, errors.New("未找到相应的处理程序")
}
func (l *QueryServiceLogic) ProcessMarriageLogic(req *types.QueryServiceReq) (*types.QueryServiceResp, error) {
userID, getUidErr := ctxdata.GetUidFromCtx(l.ctx)
if getUidErr != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 获取用户信息失败, %+v", getUidErr)
}
// AES解密
decryptData, DecryptDataErr := l.DecryptData(req.Data)
@@ -111,21 +133,31 @@ func (l *QueryServiceLogic) ProcessMarriageLogic(req *types.QueryServiceReq) (*t
"id_card": data.IDCard,
"mobile": data.Mobile,
}
userID, err := l.GetOrCreateUser(data.Mobile)
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, generaErr := jwtx.GenerateJwtToken(userID, l.svcCtx.Config.JwtAuth.AccessSecret, l.svcCtx.Config.JwtAuth.AccessExpire)
if generaErr != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 生成token失败 : %d", userID)
}
return &types.QueryServiceResp{Id: cacheNo}, nil
// 获取当前时间戳
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) {
userID, getUidErr := ctxdata.GetUidFromCtx(l.ctx)
if getUidErr != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 获取用户信息失败, %+v", getUidErr)
}
// AES解密
decryptData, DecryptDataErr := l.DecryptData(req.Data)
@@ -161,20 +193,32 @@ func (l *QueryServiceLogic) ProcessHomeServiceLogic(req *types.QueryServiceReq)
"id_card": data.IDCard,
"mobile": data.Mobile,
}
userID, err := l.GetOrCreateUser(data.Mobile)
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
}
return &types.QueryServiceResp{Id: cacheNo}, nil
token, generaErr := jwtx.GenerateJwtToken(userID, l.svcCtx.Config.JwtAuth.AccessSecret, l.svcCtx.Config.JwtAuth.AccessExpire)
if generaErr != 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) {
userID, getUidErr := ctxdata.GetUidFromCtx(l.ctx)
if getUidErr != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 获取用户信息失败, %+v", getUidErr)
}
// AES解密
decryptData, DecryptDataErr := l.DecryptData(req.Data)
@@ -210,21 +254,32 @@ func (l *QueryServiceLogic) ProcessRiskAssessmentLogic(req *types.QueryServiceRe
"id_card": data.IDCard,
"mobile": data.Mobile,
}
userID, err := l.GetOrCreateUser(data.Mobile)
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
}
return &types.QueryServiceResp{Id: cacheNo}, nil
token, generaErr := jwtx.GenerateJwtToken(userID, l.svcCtx.Config.JwtAuth.AccessSecret, l.svcCtx.Config.JwtAuth.AccessExpire)
if generaErr != 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) ProcessCompanyInfoLogic(req *types.QueryServiceReq) (*types.QueryServiceResp, error) {
userID, getUidErr := ctxdata.GetUidFromCtx(l.ctx)
if getUidErr != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 获取用户信息失败, %+v", getUidErr)
}
// AES解密
decryptData, DecryptDataErr := l.DecryptData(req.Data)
if DecryptDataErr != nil {
@@ -259,20 +314,32 @@ func (l *QueryServiceLogic) ProcessCompanyInfoLogic(req *types.QueryServiceReq)
"id_card": data.IDCard,
"mobile": data.Mobile,
}
userID, err := l.GetOrCreateUser(data.Mobile)
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
}
return &types.QueryServiceResp{Id: cacheNo}, nil
token, generaErr := jwtx.GenerateJwtToken(userID, l.svcCtx.Config.JwtAuth.AccessSecret, l.svcCtx.Config.JwtAuth.AccessExpire)
if generaErr != 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) {
userID, getUidErr := ctxdata.GetUidFromCtx(l.ctx)
if getUidErr != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 获取用户信息失败, %+v", getUidErr)
}
// AES解密
decryptData, DecryptDataErr := l.DecryptData(req.Data)
@@ -308,20 +375,32 @@ func (l *QueryServiceLogic) ProcessRentalInfoLogic(req *types.QueryServiceReq) (
"id_card": data.IDCard,
"mobile": data.Mobile,
}
userID, err := l.GetOrCreateUser(data.Mobile)
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
}
return &types.QueryServiceResp{Id: cacheNo}, nil
token, generaErr := jwtx.GenerateJwtToken(userID, l.svcCtx.Config.JwtAuth.AccessSecret, l.svcCtx.Config.JwtAuth.AccessExpire)
if generaErr != 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) {
userID, getUidErr := ctxdata.GetUidFromCtx(l.ctx)
if getUidErr != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 获取用户信息失败, %+v", getUidErr)
}
// AES解密
decryptData, DecryptDataErr := l.DecryptData(req.Data)
@@ -357,21 +436,32 @@ func (l *QueryServiceLogic) ProcessPreLoanBackgroundCheckLogic(req *types.QueryS
"id_card": data.IDCard,
"mobile": data.Mobile,
}
userID, err := l.GetOrCreateUser(data.Mobile)
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
}
return &types.QueryServiceResp{Id: cacheNo}, nil
token, generaErr := jwtx.GenerateJwtToken(userID, l.svcCtx.Config.JwtAuth.AccessSecret, l.svcCtx.Config.JwtAuth.AccessExpire)
if generaErr != 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) ProcessBackgroundCheckLogic(req *types.QueryServiceReq) (*types.QueryServiceResp, error) {
userID, getUidErr := ctxdata.GetUidFromCtx(l.ctx)
if getUidErr != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 获取用户信息失败, %+v", getUidErr)
}
// AES解密
decryptData, DecryptDataErr := l.DecryptData(req.Data)
if DecryptDataErr != nil {
@@ -389,16 +479,16 @@ func (l *QueryServiceLogic) ProcessBackgroundCheckLogic(req *types.QueryServiceR
}
// 校验验证码
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
}
//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{}{
@@ -406,12 +496,28 @@ func (l *QueryServiceLogic) ProcessBackgroundCheckLogic(req *types.QueryServiceR
"id_card": data.IDCard,
"mobile": data.Mobile,
}
userID, err := l.GetOrCreateUser(data.Mobile)
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
}
return &types.QueryServiceResp{Id: cacheNo}, nil
token, generaErr := jwtx.GenerateJwtToken(userID, l.svcCtx.Config.JwtAuth.AccessSecret, l.svcCtx.Config.JwtAuth.AccessExpire)
if generaErr != 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) ProcessTocMarriageLogic(req *types.QueryServiceReq) (*types.QueryServiceResp, error) {
@@ -652,7 +758,7 @@ func (l *QueryServiceLogic) ProcessTocPhoneThreeElementsLogic(req *types.QuerySe
// AES解密
decryptData, DecryptDataErr := l.DecryptData(req.Data)
if DecryptDataErr != nil {
return nil, DecryptDataErr
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 解密后失败: %+v", DecryptDataErr)
}
// 校验参数
@@ -1096,7 +1202,23 @@ func (l *QueryServiceLogic) VerifyCode(mobile string, code string) error {
// 二、三要素验证
func (l *QueryServiceLogic) Verify(Name string, IDCard string, Mobile string) error {
if l.svcCtx.Config.SystemConfig.ThreeVerify {
agent, ok := l.ctx.Value("agent").(bool)
if !ok {
agent = false
}
if !l.svcCtx.Config.SystemConfig.ThreeVerify || agent {
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,
@@ -1105,22 +1227,10 @@ func (l *QueryServiceLogic) Verify(Name string, IDCard string, Mobile string) er
}
verification, err := l.svcCtx.VerificationService.ThreeFactorVerification(threeVerification)
if err != nil {
return errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "三要素验证失败: %+v", err)
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 {
twoVerification := service.TwoFactorVerificationRequest{
Name: Name,
IDCard: IDCard,
}
verification, err := l.svcCtx.VerificationService.TwoFactorVerification(twoVerification)
if err != nil {
return errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "二要素验证失败: %+v", err)
}
if !verification.Passed {
return errors.Wrapf(xerr.NewErrCodeMsg(xerr.SERVER_COMMON_ERROR, verification.Err.Error()), "二要素验证不通过: %+v", err)
return errors.Wrapf(xerr.NewErrCodeMsg(xerr.SERVER_COMMON_ERROR, verification.Err.Error()), "三要素验证不通过: %v", err)
}
}
return nil
@@ -1128,9 +1238,11 @@ func (l *QueryServiceLogic) Verify(Name string, IDCard string, Mobile string) er
// 缓存
func (l *QueryServiceLogic) CacheData(params map[string]interface{}, Product string, userID int64) (string, error) {
agentIdentifier, _ := l.ctx.Value("agentIdentifier").(string)
queryCache := types.QueryCacheLoad{
Params: params,
Product: Product,
Params: params,
Product: Product,
AgentIdentifier: agentIdentifier,
}
jsonData, marshalErr := json.Marshal(queryCache)
if marshalErr != nil {
@@ -1144,3 +1256,51 @@ func (l *QueryServiceLogic) CacheData(params map[string]interface{}, Product str
}
return outTradeNo, nil
}
func (l *QueryServiceLogic) GetOrCreateUser(mobile string) (int64, error) {
agentIdentifier, ok := l.ctx.Value("agentIdentifier").(string)
if !ok || agentIdentifier == "" {
// 不是代理查询
userID, getUidErr := ctxdata.GetUidFromCtx(l.ctx)
if getUidErr != nil {
return 0, getUidErr
}
return userID, nil
}
userModel, err := l.svcCtx.UserModel.FindOneByMobile(l.ctx, mobile)
if err != nil && !errors.Is(err, model.ErrNotFound) {
return 0, err
}
// 没有则创建账号
if userModel == nil {
userModel = &model.User{Mobile: mobile}
if len(userModel.Nickname) == 0 {
userModel.Nickname = mobile
}
if transErr := l.svcCtx.UserModel.Trans(l.ctx, func(ctx context.Context, session sqlx.Session) error {
insertResult, userInsertErr := l.svcCtx.UserModel.Insert(ctx, session, userModel)
if userInsertErr != nil {
return userInsertErr
}
lastId, lastInsertIdErr := insertResult.LastInsertId()
if lastInsertIdErr != nil {
return lastInsertIdErr
}
userModel.Id = lastId
userAuth := new(model.UserAuth)
userAuth.UserId = lastId
userAuth.AuthKey = mobile
userAuth.AuthType = model.UserAuthTypeAgentPromote
if _, userAuthInsertErr := l.svcCtx.UserAuthModel.Insert(ctx, session, userAuth); userAuthInsertErr != nil {
return userAuthInsertErr
}
return nil
}); transErr != nil {
return 0, transErr
}
}
return userModel.Id, nil
}

View File

@@ -1,140 +0,0 @@
package query
import (
"context"
"encoding/hex"
"encoding/json"
"fmt"
"github.com/pkg/errors"
"github.com/zeromicro/go-zero/core/stores/redis"
"time"
"tydata-server/app/user/cmd/api/internal/service"
"tydata-server/common/ctxdata"
"tydata-server/common/xerr"
"tydata-server/pkg/lzkit/crypto"
"tydata-server/pkg/lzkit/validator"
"tydata-server/app/user/cmd/api/internal/svc"
"tydata-server/app/user/cmd/api/internal/types"
"github.com/zeromicro/go-zero/core/logx"
)
type RentalInfoLogic struct {
logx.Logger
ctx context.Context
svcCtx *svc.ServiceContext
}
func NewRentalInfoLogic(ctx context.Context, svcCtx *svc.ServiceContext) *RentalInfoLogic {
return &RentalInfoLogic{
Logger: logx.WithContext(ctx),
ctx: ctx,
svcCtx: svcCtx,
}
}
func (l *RentalInfoLogic) RentalInfo(req *types.QueryReq) (resp *types.QueryResp, err error) {
userID, getUidErr := ctxdata.GetUidFromCtx(l.ctx)
if getUidErr != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "租赁服务, 获取用户信息失败, %+v", getUidErr)
}
// 1、AES解密
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(req.Data, key)
if aesDecryptErr != nil || len(decryptData) == 0 {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "租赁服务, 解密失败: %+v", decodeErr)
}
// 2、校验
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)
}
if data.Name == "刘福思" && data.IDCard == "45262419980929047X" && data.Mobile == "17776203797" {
// 缓存
queryCache := types.QueryCache{
Name: data.Name,
IDCard: data.IDCard,
Mobile: data.Mobile,
Product: "rentalinfo",
}
jsonData, marshalErr := json.Marshal(queryCache)
if marshalErr != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "婚恋评估, 序列化参数失败: %+v", marshalErr)
}
outTradeNo := l.svcCtx.WechatPayService.GenerateOutTradeNo()
redisKey := fmt.Sprintf("%d:%s", userID, outTradeNo)
cacheErr := l.svcCtx.Redis.SetexCtx(l.ctx, redisKey, string(jsonData), int(2*time.Hour))
if cacheErr != nil {
return nil, cacheErr
}
return &types.QueryResp{Id: outTradeNo}, nil
}
// 校验验证码
codeRedisKey := fmt.Sprintf("%s:%s", "query", data.Mobile)
cacheCode, err := l.svcCtx.Redis.Get(codeRedisKey)
if err != nil {
if errors.Is(err, redis.Nil) {
return nil, errors.Wrapf(xerr.NewErrMsg("验证码已过期"), "租赁服务, 验证码过期: %s", data.Mobile)
}
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "租赁服务, 读取验证码redis缓存失败, mobile: %s, err: %+v", data.Mobile, err)
}
if cacheCode != data.Code {
return nil, errors.Wrapf(xerr.NewErrMsg("验证码不正确"), "租赁服务, 验证码不正确: %s", data.Mobile)
}
// 3、二要素三要素核验
//twoVerification := service.TwoFactorVerificationRequest{
// Name: data.Name,
// IDCard: data.IDCard,
//}
//verification, err := l.svcCtx.VerificationService.TwoFactorVerification(twoVerification)
//if err != nil {
// return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "租赁服务, 二要素验证失败: %+v", err)
//}
//if !verification.Passed {
// return nil, errors.Wrapf(xerr.NewErrCodeMsg(xerr.SERVER_COMMON_ERROR, verification.Err.Error()), "租赁服务, 二要素验证不通过: %+v", err)
//}
// 3、二要素三要素核验
threeVerification := service.ThreeFactorVerificationRequest{
Name: data.Name,
IDCard: data.IDCard,
Mobile: data.Mobile,
}
verification, err := l.svcCtx.VerificationService.ThreeFactorVerification(threeVerification)
if err != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "租赁服务, 三要素验证失败: %+v", err)
}
if !verification.Passed {
return nil, errors.Wrapf(xerr.NewErrCodeMsg(xerr.SERVER_COMMON_ERROR, verification.Err.Error()), "租赁服务, 三要素验证不通过: %+v", err)
}
// 缓存
queryCache := types.QueryCache{
Name: data.Name,
IDCard: data.IDCard,
Mobile: data.Mobile,
Product: "rentalinfo",
}
jsonData, marshalErr := json.Marshal(queryCache)
if marshalErr != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "租赁服务, 序列化参数失败: %+v", marshalErr)
}
outTradeNo := l.svcCtx.WechatPayService.GenerateOutTradeNo()
redisKey := fmt.Sprintf("%d:%s", userID, outTradeNo)
cacheErr := l.svcCtx.Redis.SetexCtx(l.ctx, redisKey, string(jsonData), int(2*time.Hour))
if cacheErr != nil {
return nil, cacheErr
}
return &types.QueryResp{Id: outTradeNo}, nil
}

View File

@@ -1,140 +0,0 @@
package query
import (
"context"
"encoding/hex"
"encoding/json"
"fmt"
"github.com/pkg/errors"
"github.com/zeromicro/go-zero/core/stores/redis"
"time"
"tydata-server/app/user/cmd/api/internal/service"
"tydata-server/common/ctxdata"
"tydata-server/common/xerr"
"tydata-server/pkg/lzkit/crypto"
"tydata-server/pkg/lzkit/validator"
"tydata-server/app/user/cmd/api/internal/svc"
"tydata-server/app/user/cmd/api/internal/types"
"github.com/zeromicro/go-zero/core/logx"
)
type RiskAssessmentLogic struct {
logx.Logger
ctx context.Context
svcCtx *svc.ServiceContext
}
func NewRiskAssessmentLogic(ctx context.Context, svcCtx *svc.ServiceContext) *RiskAssessmentLogic {
return &RiskAssessmentLogic{
Logger: logx.WithContext(ctx),
ctx: ctx,
svcCtx: svcCtx,
}
}
func (l *RiskAssessmentLogic) RiskAssessment(req *types.QueryReq) (resp *types.QueryResp, err error) {
userID, getUidErr := ctxdata.GetUidFromCtx(l.ctx)
if getUidErr != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "个人风险, 获取用户信息失败, %+v", getUidErr)
}
// 1、AES解密
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(req.Data, key)
if aesDecryptErr != nil || len(decryptData) == 0 {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "个人风险, 解密失败: %+v", decodeErr)
}
// 2、校验
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)
}
if data.Name == "刘福思" && data.IDCard == "45262419980929047X" && data.Mobile == "17776203797" {
// 缓存
queryCache := types.QueryCache{
Name: data.Name,
IDCard: data.IDCard,
Mobile: data.Mobile,
Product: "riskassessment",
}
jsonData, marshalErr := json.Marshal(queryCache)
if marshalErr != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "婚恋评估, 序列化参数失败: %+v", marshalErr)
}
outTradeNo := l.svcCtx.WechatPayService.GenerateOutTradeNo()
redisKey := fmt.Sprintf("%d:%s", userID, outTradeNo)
cacheErr := l.svcCtx.Redis.SetexCtx(l.ctx, redisKey, string(jsonData), int(2*time.Hour))
if cacheErr != nil {
return nil, cacheErr
}
return &types.QueryResp{Id: outTradeNo}, nil
}
// 校验验证码
codeRedisKey := fmt.Sprintf("%s:%s", "query", data.Mobile)
cacheCode, err := l.svcCtx.Redis.Get(codeRedisKey)
if err != nil {
if errors.Is(err, redis.Nil) {
return nil, errors.Wrapf(xerr.NewErrMsg("验证码已过期"), "个人风险, 验证码过期: %s", data.Mobile)
}
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "个人风险, 读取验证码redis缓存失败, mobile: %s, err: %+v", data.Mobile, err)
}
if cacheCode != data.Code {
return nil, errors.Wrapf(xerr.NewErrMsg("验证码不正确"), "个人风险, 验证码不正确: %s", data.Mobile)
}
// 3、二要素三要素核验
//twoVerification := service.TwoFactorVerificationRequest{
// Name: data.Name,
// IDCard: data.IDCard,
//}
//verification, err := l.svcCtx.VerificationService.TwoFactorVerification(twoVerification)
//if err != nil {
// return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "个人风险, 二要素验证失败: %+v", err)
//}
//if !verification.Passed {
// return nil, errors.Wrapf(xerr.NewErrCodeMsg(xerr.SERVER_COMMON_ERROR, verification.Err.Error()), "个人风险, 二要素验证不通过: %+v", err)
//}
// 3、二要素三要素核验
threeVerification := service.ThreeFactorVerificationRequest{
Name: data.Name,
IDCard: data.IDCard,
Mobile: data.Mobile,
}
verification, err := l.svcCtx.VerificationService.ThreeFactorVerification(threeVerification)
if err != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "个人风险, 三要素验证失败: %+v", err)
}
if !verification.Passed {
return nil, errors.Wrapf(xerr.NewErrCodeMsg(xerr.SERVER_COMMON_ERROR, verification.Err.Error()), "个人风险, 三要素验证不通过: %+v", err)
}
// 缓存
queryCache := types.QueryCache{
Name: data.Name,
IDCard: data.IDCard,
Mobile: data.Mobile,
Product: "riskassessment",
}
jsonData, marshalErr := json.Marshal(queryCache)
if marshalErr != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "个人风险, 序列化参数失败: %+v", marshalErr)
}
outTradeNo := l.svcCtx.WechatPayService.GenerateOutTradeNo()
redisKey := fmt.Sprintf("%d:%s", userID, outTradeNo)
cacheErr := l.svcCtx.Redis.SetexCtx(l.ctx, redisKey, string(jsonData), int(2*time.Hour))
if cacheErr != nil {
return nil, cacheErr
}
return &types.QueryResp{Id: outTradeNo}, nil
}

View File

@@ -0,0 +1,91 @@
package user
import (
"context"
"fmt"
"github.com/pkg/errors"
"github.com/zeromicro/go-zero/core/stores/redis"
"github.com/zeromicro/go-zero/core/stores/sqlx"
"time"
"tydata-server/app/user/cmd/api/internal/svc"
"tydata-server/app/user/cmd/api/internal/types"
"tydata-server/app/user/model"
jwtx "tydata-server/common/jwt"
"tydata-server/common/xerr"
"github.com/zeromicro/go-zero/core/logx"
)
type AgentMobileCodeLoginLogic struct {
logx.Logger
ctx context.Context
svcCtx *svc.ServiceContext
}
func NewAgentMobileCodeLoginLogic(ctx context.Context, svcCtx *svc.ServiceContext) *AgentMobileCodeLoginLogic {
return &AgentMobileCodeLoginLogic{
Logger: logx.WithContext(ctx),
ctx: ctx,
svcCtx: svcCtx,
}
}
func (l *AgentMobileCodeLoginLogic) AgentMobileCodeLogin(req *types.MobileCodeLoginReq) (resp *types.MobileCodeLoginResp, err error) {
// 检查手机号是否在一分钟内已发送过验证码
redisKey := fmt.Sprintf("%s:%s", "query", req.Mobile)
cacheCode, err := l.svcCtx.Redis.Get(redisKey)
if err != nil {
if errors.Is(err, redis.Nil) {
return nil, errors.Wrapf(xerr.NewErrMsg("验证码已过期"), "手机登录, 验证码过期: %s", req.Mobile)
}
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "手机登录, 读取验证码redis缓存失败, mobile: %s, err: %+v", req.Mobile, err)
}
if cacheCode != req.Code {
return nil, errors.Wrapf(xerr.NewErrMsg("验证码不正确"), "手机登录, 验证码不正确: %s", req.Mobile)
}
user, findUserErr := l.svcCtx.UserModel.FindOneByMobile(l.ctx, req.Mobile)
if findUserErr != nil && findUserErr != model.ErrNotFound {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "手机登录, 读取数据库获取用户失败, mobile: %s, err: %+v", req.Mobile, err)
}
if user == nil {
user = &model.User{Mobile: req.Mobile}
if len(user.Nickname) == 0 {
user.Nickname = req.Mobile
}
if transErr := l.svcCtx.UserModel.Trans(l.ctx, func(ctx context.Context, session sqlx.Session) error {
insertResult, userInsertErr := l.svcCtx.UserModel.Insert(ctx, session, user)
if userInsertErr != nil {
return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "手机注册, 数据库插入新用户失败, mobile%s, err: %+v", req.Mobile, err)
}
lastId, lastInsertIdErr := insertResult.LastInsertId()
if lastInsertIdErr != nil {
return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "手机注册, 获取新用户ID失败, err:%+v, user:%+v", lastInsertIdErr, user)
}
user.Id = lastId
userAuth := new(model.UserAuth)
userAuth.UserId = lastId
userAuth.AuthKey = req.Mobile
userAuth.AuthType = model.UserAuthTypeH5Mobile
if _, userAuthInsertErr := l.svcCtx.UserAuthModel.Insert(ctx, session, userAuth); userAuthInsertErr != nil {
return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "手机注册, 数据库插入用户认证失败, err:%+v", userAuthInsertErr)
}
return nil
}); transErr != nil {
return nil, transErr
}
}
token, generaErr := jwtx.GenerateJwtToken(user.Id, l.svcCtx.Config.JwtAuth.AccessSecret, l.svcCtx.Config.JwtAuth.AccessExpire)
if generaErr != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "手机登录, 生成token失败 : %d", user.Id)
}
// 获取当前时间戳
now := time.Now().Unix()
return &types.MobileCodeLoginResp{
AccessToken: token,
AccessExpire: now + l.svcCtx.Config.JwtAuth.AccessExpire,
RefreshAfter: now + l.svcCtx.Config.JwtAuth.RefreshAfter,
}, nil
}

View File

@@ -29,16 +29,16 @@ func NewDetailLogic(ctx context.Context, svcCtx *svc.ServiceContext) *DetailLogi
func (l *DetailLogic) Detail() (resp *types.UserInfoResp, err error) {
userID, err := ctxdata.GetUidFromCtx(l.ctx)
if err != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "用户信息, %+v", err)
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "用户信息, %v", err)
}
user, err := l.svcCtx.UserModel.FindOne(l.ctx, userID)
if err != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "用户信息, 数据库查询用户信息失败, %+v", err)
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "用户信息, 数据库查询用户信息失败, %v", err)
}
var userInfo types.User
err = copier.Copy(&userInfo, user)
if err != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "用户信息, 用户信息结构体复制失败, %+v", err)
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "用户信息, 用户信息结构体复制失败, %v", err)
}
return &types.UserInfoResp{
UserInfo: userInfo,

View File

@@ -31,7 +31,7 @@ func NewGetTokenLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetToken
func (l *GetTokenLogic) GetToken() (resp *types.MobileCodeLoginResp, err error) {
userID, err := ctxdata.GetUidFromCtx(l.ctx)
if err != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "用户信息, %+v", err)
return nil, errors.Wrapf(xerr.NewErrMsg(""), "用户信息, %v", err)
}
token, generaErr := jwtx.GenerateJwtToken(userID, l.svcCtx.Config.JwtAuth.AccessSecret, l.svcCtx.Config.JwtAuth.AccessExpire)
if generaErr != nil {
@@ -44,5 +44,4 @@ func (l *GetTokenLogic) GetToken() (resp *types.MobileCodeLoginResp, err error)
AccessExpire: now + l.svcCtx.Config.JwtAuth.AccessExpire,
RefreshAfter: now + l.svcCtx.Config.JwtAuth.RefreshAfter,
}, nil
}

View File

@@ -37,7 +37,7 @@ func (l *WxH5AuthLogic) WxH5Auth(req *types.WXH5AuthReq) (resp *types.WXH5AuthRe
// Step 1: 使用code获取access_token
accessTokenResp, err := GetAccessToken(req.Code)
if err != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "获取access_token失败: %+v", err)
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "获取access_token失败: %v", err)
}
// Step 2: 查找用户授权信息