first commit

This commit is contained in:
2026-02-08 16:19:37 +08:00
commit 958df98745
569 changed files with 61311 additions and 0 deletions

View File

@@ -0,0 +1,139 @@
package agent
import (
"context"
"database/sql"
"sim-server/app/main/api/internal/svc"
"sim-server/app/main/api/internal/types"
"sim-server/app/main/model"
"sim-server/common/ctxdata"
"sim-server/common/xerr"
"sim-server/pkg/lzkit/crypto"
"github.com/google/uuid"
"github.com/pkg/errors"
"github.com/zeromicro/go-zero/core/logx"
"github.com/zeromicro/go-zero/core/stores/sqlx"
)
type CreateWithdrawLogic struct {
logx.Logger
ctx context.Context
svcCtx *svc.ServiceContext
}
func NewCreateWithdrawLogic(ctx context.Context, svcCtx *svc.ServiceContext) *CreateWithdrawLogic {
return &CreateWithdrawLogic{
Logger: logx.WithContext(ctx),
ctx: ctx,
svcCtx: svcCtx,
}
}
func (l *CreateWithdrawLogic) CreateWithdraw(req *types.CreateWithdrawReq) (resp *types.CreateWithdrawResp, err error) {
// 1. 获取当前用户ID代理ID
userId, err := ctxdata.GetUidFromCtx(l.ctx)
if err != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "获取用户信息失败: %v", err)
}
// 2. 查询代理信息
agent, err := l.svcCtx.AgentModel.FindOneByUserId(l.ctx, userId)
if err != nil {
if errors.Is(err, model.ErrNotFound) {
return nil, errors.Wrap(xerr.NewErrCode(xerr.CUSTOM_ERROR), "您还不是代理,无法申请提现")
}
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询代理信息失败: %v", err)
}
// 3. 查询钱包信息
wallet, err := l.svcCtx.AgentWalletModel.FindOneByAgentId(l.ctx, agent.Id)
if err != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询钱包信息失败: %v", err)
}
// 4. 验证提现金额
if req.WithdrawAmount <= 0 {
return nil, errors.Wrap(xerr.NewErrCode(xerr.REUQEST_PARAM_ERROR), "提现金额必须大于0")
}
minWithdraw := 100.00 // 最低提现金额100元
if req.WithdrawAmount < minWithdraw {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.REUQEST_PARAM_ERROR), "最低提现金额为%.2f元", minWithdraw)
}
if wallet.Balance < req.WithdrawAmount {
return nil, errors.Wrap(xerr.NewErrCode(xerr.CUSTOM_ERROR), "可用余额不足")
}
// 5. 加密银行卡号
encryptedCardNumber, err := crypto.AesEncrypt([]byte(req.BankCardNumber), []byte(l.svcCtx.Config.Encrypt.SecretKey))
if err != nil {
logx.Errorf("加密银行卡号失败: %v", err)
return nil, errors.Wrap(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "加密银行卡号失败")
}
// 6. 生成提现记录ID
withdrawId := uuid.NewString()
// 7. 解密代理手机号(用于冗余存储)
agentMobile, err := crypto.DecryptMobile(agent.Mobile, l.svcCtx.Config.Encrypt.SecretKey)
if err != nil {
logx.Errorf("解密代理手机号失败: %v", err)
agentMobile = ""
}
// 8. 开启事务处理
err = l.svcCtx.AgentWalletModel.Trans(l.ctx, func(ctx context.Context, session sqlx.Session) error {
// 8.1 冻结提现金额
wallet.Balance -= req.WithdrawAmount
wallet.FrozenAmount += req.WithdrawAmount
// 使用版本号乐观锁更新
err := l.svcCtx.AgentWalletModel.UpdateWithVersion(ctx, session, wallet)
if err != nil {
return errors.Wrapf(err, "冻结金额失败")
}
// 8.2 创建提现记录
withdrawRecord := &model.AgentWithdraw{
Id: withdrawId,
AgentId: agent.Id,
WithdrawAmount: req.WithdrawAmount,
TaxAmount: 0.00,
ActualAmount: 0.00,
FrozenAmount: req.WithdrawAmount,
AccountName: req.AccountName,
BankCardNumber: req.BankCardNumber,
BankCardNumberEncrypted: sql.NullString{String: string(encryptedCardNumber), Valid: true},
BankBranch: sql.NullString{String: req.BankBranch, Valid: req.BankBranch != ""},
Status: 0,
}
// 冗余存储代理手机号和编码
if agentMobile != "" {
withdrawRecord.AgentMobile = sql.NullString{String: agentMobile, Valid: true}
}
if agent.AgentCode > 0 {
withdrawRecord.AgentCode = sql.NullInt64{Int64: agent.AgentCode, Valid: true}
}
_, err = l.svcCtx.AgentWithdrawModel.Insert(ctx, session, withdrawRecord)
if err != nil {
return errors.Wrapf(err, "创建提现记录失败")
}
return nil
})
if err != nil {
return nil, errors.Wrap(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), err.Error())
}
logx.Infof("代理 %s 申请提现成功,提现金额: %.2f", agent.Id, req.WithdrawAmount)
return &types.CreateWithdrawResp{
WithdrawId: withdrawId,
}, nil
}