fix add 修改钱包余额

This commit is contained in:
2026-01-04 16:10:47 +08:00
parent ba2624e310
commit 64b758a36d
12 changed files with 387 additions and 71 deletions

View File

@@ -0,0 +1,30 @@
package admin_agent
import (
"net/http"
"tydata-server/app/main/api/internal/logic/admin_agent"
"tydata-server/app/main/api/internal/svc"
"tydata-server/app/main/api/internal/types"
"tydata-server/common/result"
"tydata-server/pkg/lzkit/validator"
"github.com/zeromicro/go-zero/rest/httpx"
)
func AdminUpdateAgentWalletBalanceHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var req types.AdminUpdateAgentWalletBalanceReq
if err := httpx.Parse(r, &req); err != nil {
result.ParamErrorResult(r, w, err)
return
}
if err := validator.Validate(req); err != nil {
result.ParamValidateErrorResult(r, w, err)
return
}
l := admin_agent.NewAdminUpdateAgentWalletBalanceLogic(r.Context(), svcCtx)
resp, err := l.AdminUpdateAgentWalletBalance(&req)
result.HttpResult(r, w, resp, err)
}
}

View File

@@ -137,6 +137,11 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {
Path: "/wallet/:agent_id",
Handler: admin_agent.AdminGetAgentWalletHandler(serverCtx),
},
{
Method: http.MethodPost,
Path: "/wallet/update-balance",
Handler: admin_agent.AdminUpdateAgentWalletBalanceHandler(serverCtx),
},
}...,
),
rest.WithPrefix("/api/v1/admin/agent"),

View File

@@ -2,6 +2,7 @@ package admin_agent
import (
"context"
"time"
"tydata-server/app/main/api/internal/svc"
"tydata-server/app/main/api/internal/types"
@@ -37,6 +38,20 @@ func (l *AdminGetAgentCommissionListLogic) AdminGetAgentCommissionList(req *type
builder = builder.Where(squirrel.Eq{"status": *req.Status})
}
// 时间范围筛选
if req.CreateTimeStart != nil && *req.CreateTimeStart != "" {
startTime, err := time.Parse("2006-01-02 15:04:05", *req.CreateTimeStart)
if err == nil {
builder = builder.Where(squirrel.GtOrEq{"create_time": startTime})
}
}
if req.CreateTimeEnd != nil && *req.CreateTimeEnd != "" {
endTime, err := time.Parse("2006-01-02 15:04:05", *req.CreateTimeEnd)
if err == nil {
builder = builder.Where(squirrel.LtOrEq{"create_time": endTime})
}
}
// 先查出所有product_id对应的product_name如有product_name筛选需反查id
if req.ProductName != nil && *req.ProductName != "" {
// 支持模糊匹配产品名称

View File

@@ -36,6 +36,9 @@ func (l *AdminGetAgentWithdrawalListLogic) AdminGetAgentWithdrawalList(req *type
if req.WithdrawNo != nil && *req.WithdrawNo != "" {
builder = builder.Where(squirrel.Eq{"withdraw_no": *req.WithdrawNo})
}
if req.WithdrawType != nil {
builder = builder.Where(squirrel.Eq{"withdraw_type": *req.WithdrawType})
}
list, total, err := l.svcCtx.AgentWithdrawalModel.FindPageListByPageWithTotal(l.ctx, builder, req.Page, req.PageSize, "create_time DESC")
if err != nil {
return nil, err
@@ -49,7 +52,7 @@ func (l *AdminGetAgentWithdrawalListLogic) AdminGetAgentWithdrawalList(req *type
item.Remark = v.Remark.String
}
item.CreateTime = v.CreateTime.Format("2006-01-02 15:04:05")
// 手动设置银行卡信息copier不会自动处理sql.NullString
item.WithdrawType = v.WithdrawType
if v.BankCardNo.Valid {
@@ -61,7 +64,7 @@ func (l *AdminGetAgentWithdrawalListLogic) AdminGetAgentWithdrawalList(req *type
if v.PayeeName.Valid {
item.PayeeName = v.PayeeName.String
}
items = append(items, item)
}
resp = &types.AdminGetAgentWithdrawalListResp{

View File

@@ -24,9 +24,9 @@ const (
// 状态常量
const (
StatusPending = 1 // 申请中/处理中
StatusSuccess = 2 // 成功
StatusFailed = 3 // 失败
StatusPending = 1 // 申请中/处理中
StatusSuccess = 2 // 成功
StatusFailed = 3 // 失败
)
// 提现类型常量
@@ -80,9 +80,9 @@ func (l *AdminReviewBankCardWithdrawalLogic) AdminReviewBankCardWithdrawal(req *
return errors.Wrapf(xerr.NewErrMsg("该提现记录已处理,无法重复操作"), "状态验证失败")
}
// 验证提现类型
if record.WithdrawType != WithdrawTypeBankCard {
return errors.Wrapf(xerr.NewErrMsg("该记录不是银行卡提现,无法审核"), "提现类型验证失败")
// 验证提现类型(支持银行卡和支付宝提现)
if record.WithdrawType != WithdrawTypeBankCard && record.WithdrawType != WithdrawTypeAlipay {
return errors.Wrapf(xerr.NewErrMsg("提现类型不正确"), "提现类型验证失败")
}
if req.Action == ReviewActionApprove {
@@ -104,6 +104,49 @@ func (l *AdminReviewBankCardWithdrawalLogic) AdminReviewBankCardWithdrawal(req *
// 确认提现
func (l *AdminReviewBankCardWithdrawalLogic) approveWithdrawal(ctx context.Context, session sqlx.Session, record *model.AgentWithdrawal) error {
// 根据提现类型执行不同的操作
if record.WithdrawType == WithdrawTypeAlipay {
// 支付宝提现:先调用支付宝转账接口
return l.approveAlipayWithdrawal(ctx, session, record)
} else {
// 银行卡提现:直接更新状态为成功(线下转账)
return l.approveBankCardWithdrawal(ctx, session, record)
}
}
// 确认支付宝提现
func (l *AdminReviewBankCardWithdrawalLogic) approveAlipayWithdrawal(ctx context.Context, session sqlx.Session, record *model.AgentWithdrawal) error {
// 同步调用支付宝转账
transferResp, err := l.svcCtx.AlipayService.AliTransfer(ctx, record.PayeeAccount, record.PayeeName.String, record.ActualAmount, "公司提现", record.WithdrawNo)
if err != nil {
l.Logger.Errorf("【支付宝转账失败】withdrawNo:%s error:%v", record.WithdrawNo, err)
return errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "支付宝接口调用失败: %v", err)
}
switch {
case transferResp.Status == "SUCCESS":
// 立即处理成功状态
return l.completeWithdrawalSuccess(ctx, session, record)
case transferResp.Status == "FAIL" || transferResp.SubCode != "":
// 处理明确失败
errorMsg := l.mapAlipayError(transferResp.SubCode)
return l.completeWithdrawalFailure(ctx, session, record, errorMsg)
case transferResp.Status == "DEALING":
// 处理中状态,更新为处理中但不标记为最终状态
record.Remark = sql.NullString{String: "支付宝转账处理中", Valid: true}
if _, err := l.svcCtx.AgentWithdrawalModel.Update(ctx, session, record); err != nil {
return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "更新提现记录失败: %v", err)
}
l.Logger.Infof("支付宝提现审核通过,转账处理中 withdrawalId:%d withdrawNo:%s", record.Id, record.WithdrawNo)
return nil
default:
// 未知状态按失败处理
return l.completeWithdrawalFailure(ctx, session, record, "支付宝返回未知状态")
}
}
// 确认银行卡提现
func (l *AdminReviewBankCardWithdrawalLogic) approveBankCardWithdrawal(ctx context.Context, session sqlx.Session, record *model.AgentWithdrawal) error {
// 更新提现记录状态为成功
record.Status = StatusSuccess
record.Remark = sql.NullString{String: "管理员确认提现", Valid: true}
@@ -185,3 +228,126 @@ func (l *AdminReviewBankCardWithdrawalLogic) rejectWithdrawal(ctx context.Contex
l.Logger.Infof("银行卡提现拒绝 withdrawalId:%d amount:%f reason:%s", record.Id, record.Amount, remark)
return nil
}
// 完成提现成功(支付宝转账成功后调用)
func (l *AdminReviewBankCardWithdrawalLogic) completeWithdrawalSuccess(ctx context.Context, session sqlx.Session, record *model.AgentWithdrawal) error {
// 更新提现记录状态为成功
record.Status = StatusSuccess
record.Remark = sql.NullString{String: "支付宝转账成功", Valid: true}
if _, err := l.svcCtx.AgentWithdrawalModel.Update(ctx, session, record); err != nil {
return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "更新提现记录失败: %v", err)
}
// 解冻资金并扣除FrozenBalance -= amount, Balance不变
wallet, err := l.svcCtx.AgentWalletModel.FindOneByAgentId(ctx, record.AgentId)
if err != nil {
return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "查询钱包失败: %v", err)
}
wallet.FrozenBalance -= record.Amount
if err := l.svcCtx.AgentWalletModel.UpdateWithVersion(ctx, session, wallet); err != nil {
return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "更新钱包失败: %v", err)
}
// 更新扣税记录状态为成功
taxModel, err := l.svcCtx.AgentWithdrawalTaxModel.FindOneByWithdrawalId(ctx, record.Id)
if err != nil {
return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "查询扣税记录失败: %v", err)
}
if taxModel.TaxStatus == model.TaxStatusPending {
taxModel.TaxStatus = model.TaxStatusSuccess // 扣税状态 = 成功
taxModel.TaxTime = sql.NullTime{Time: time.Now(), Valid: true}
if err := l.svcCtx.AgentWithdrawalTaxModel.UpdateWithVersion(ctx, session, taxModel); err != nil {
return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "更新扣税记录失败: %v", err)
}
}
// 提现成功后,给上级代理发放提现奖励
withdrawRewardErr := l.svcCtx.AgentService.GiveWithdrawReward(ctx, record.AgentId, record.Amount, session)
if withdrawRewardErr != nil {
l.Logger.Errorf("发放提现奖励失败代理ID%d提现金额%f错误%+v", record.AgentId, record.Amount, withdrawRewardErr)
// 提现奖励失败不影响主流程,只记录日志
} else {
l.Logger.Infof("发放提现奖励成功代理ID%d提现金额%f", record.AgentId, record.Amount)
}
l.Logger.Infof("支付宝提现成功 withdrawalId:%d withdrawNo:%s", record.Id, record.WithdrawNo)
return nil
}
// 完成提现失败(支付宝转账失败后调用)
func (l *AdminReviewBankCardWithdrawalLogic) completeWithdrawalFailure(ctx context.Context, session sqlx.Session, record *model.AgentWithdrawal, errorMsg string) error {
// 更新提现记录状态为失败
record.Status = StatusFailed
record.Remark = sql.NullString{String: errorMsg, Valid: true}
if _, err := l.svcCtx.AgentWithdrawalModel.Update(ctx, session, record); err != nil {
return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "更新提现记录失败: %v", err)
}
// 解冻资金FrozenBalance -= amount, Balance += amount
wallet, err := l.svcCtx.AgentWalletModel.FindOneByAgentId(ctx, record.AgentId)
if err != nil {
return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "查询钱包失败: %v", err)
}
wallet.Balance += record.Amount
wallet.FrozenBalance -= record.Amount
if err := l.svcCtx.AgentWalletModel.UpdateWithVersion(ctx, session, wallet); err != nil {
return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "更新钱包失败: %v", err)
}
// 更新扣税记录状态为失败
taxModel, err := l.svcCtx.AgentWithdrawalTaxModel.FindOneByWithdrawalId(ctx, record.Id)
if err != nil {
return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "查询扣税记录失败: %v", err)
}
if taxModel.TaxStatus == model.TaxStatusPending {
taxModel.TaxStatus = model.TaxStatusFailed // 扣税状态 = 失败
taxModel.TaxTime = sql.NullTime{Time: time.Now(), Valid: true}
if err := l.svcCtx.AgentWithdrawalTaxModel.UpdateWithVersion(ctx, session, taxModel); err != nil {
return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "更新扣税记录失败: %v", err)
}
}
l.Logger.Infof("支付宝提现失败 withdrawalId:%d withdrawNo:%s reason:%s", record.Id, record.WithdrawNo, errorMsg)
return nil
}
// 错误类型映射
func (l *AdminReviewBankCardWithdrawalLogic) 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 "系统错误,请联系客服"
}

View File

@@ -0,0 +1,83 @@
package admin_agent
import (
"context"
"errors"
"fmt"
"tydata-server/app/main/api/internal/svc"
"tydata-server/app/main/api/internal/types"
"tydata-server/app/main/model"
"tydata-server/common/xerr"
"github.com/zeromicro/go-zero/core/logx"
"github.com/zeromicro/go-zero/core/stores/sqlx"
)
type AdminUpdateAgentWalletBalanceLogic struct {
logx.Logger
ctx context.Context
svcCtx *svc.ServiceContext
}
func NewAdminUpdateAgentWalletBalanceLogic(ctx context.Context, svcCtx *svc.ServiceContext) *AdminUpdateAgentWalletBalanceLogic {
return &AdminUpdateAgentWalletBalanceLogic{
Logger: logx.WithContext(ctx),
ctx: ctx,
svcCtx: svcCtx,
}
}
func (l *AdminUpdateAgentWalletBalanceLogic) AdminUpdateAgentWalletBalance(req *types.AdminUpdateAgentWalletBalanceReq) (resp *types.AdminUpdateAgentWalletBalanceResp, err error) {
// 参数校验
if req.AgentId <= 0 {
return nil, xerr.NewErrMsg("代理ID无效")
}
if req.Amount == 0 {
return nil, xerr.NewErrMsg("修改金额不能为0")
}
// 查询代理钱包信息
wallet, err := l.svcCtx.AgentWalletModel.FindOneByAgentId(l.ctx, req.AgentId)
if err != nil {
if errors.Is(err, model.ErrNotFound) {
return nil, xerr.NewErrMsg("代理钱包不存在")
}
return nil, err
}
// 计算新余额
newBalance := wallet.Balance + req.Amount
// 校验余额不能为负数
if newBalance < 0 {
return nil, xerr.NewErrMsg(fmt.Sprintf("操作后余额不能为负数,当前余额: %.2f,操作金额: %.2f", wallet.Balance, req.Amount))
}
// 更新余额
updateErr := l.svcCtx.AgentWalletModel.Trans(l.ctx, func(transCtx context.Context, session sqlx.Session) error {
// 使用版本号更新
wallet.Balance = newBalance
err := l.svcCtx.AgentWalletModel.UpdateWithVersion(transCtx, session, wallet)
if err != nil {
return err
}
// TODO: 这里可以添加记录余额变更日志的逻辑
l.Logger.Infof("代理钱包余额变更 - AgentId: %d, 原余额: %.2f, 变更金额: %.2f, 新余额: %.2f",
req.AgentId, wallet.Balance-req.Amount, req.Amount, newBalance)
return nil
})
if updateErr != nil {
l.Logger.Errorf("更新代理钱包余额失败: %+v", updateErr)
return nil, xerr.NewErrMsg("更新余额失败")
}
resp = &types.AdminUpdateAgentWalletBalanceResp{
Success: true,
Balance: newBalance,
}
return
}

View File

@@ -53,6 +53,7 @@ func (l *AgentWithdrawalLogic) AgentWithdrawal(req *types.WithdrawalReq) (*types
var (
outBizNo string
withdrawRes = &types.WithdrawalResp{}
agentID int64
)
var finalWithdrawAmount float64 // 实际到账金额
// 使用事务处理核心操作
@@ -67,6 +68,7 @@ func (l *AgentWithdrawalLogic) AgentWithdrawal(req *types.WithdrawalReq) (*types
if err != nil {
return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "查询代理信息失败: %v", err)
}
agentID = agentModel.Id // 保存agentId用于日志
agentRealName, err := l.svcCtx.AgentRealNameModel.FindOneByAgentId(l.ctx, agentModel.Id)
if err != nil {
if errors.Is(err, model.ErrNotFound) {
@@ -109,14 +111,14 @@ func (l *AgentWithdrawalLogic) AgentWithdrawal(req *types.WithdrawalReq) (*types
)
// 统一扣税逻辑所有提现都按6%收取税收
exemptionAmount = 0 // 免税金额 = 0
TaxStatus = model.TaxStatusPending // 扣税状态 = 待扣税
taxDeductionPart = req.Amount // 应税金额 = 提现金额
taxAmount = taxDeductionPart * taxRate // 应缴税费 = 应税金额 * 税率
finalWithdrawAmount = req.Amount - taxAmount // 实际到账金额 = 提现金额 - 应缴税费
exemptionAmount = 0 // 免税金额 = 0
TaxStatus = model.TaxStatusPending // 扣税状态 = 待扣税
taxDeductionPart = req.Amount // 应税金额 = 提现金额
taxAmount = taxDeductionPart * taxRate // 应缴税费 = 应税金额 * 税率
finalWithdrawAmount = req.Amount - taxAmount // 实际到账金额 = 提现金额 - 应缴税费
// 创建提现记录(初始状态为处理中)
withdrawalID, err := l.createWithdrawalRecord(session, agentModel.Id, req.PayeeAccount, req.Amount, finalWithdrawAmount, taxAmount, outBizNo)
withdrawalID, err := l.createWithdrawalRecord(session, agentModel.Id, req.PayeeAccount, req.PayeeName, req.Amount, finalWithdrawAmount, taxAmount, outBizNo)
if err != nil {
return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "创建提现记录失败: %v", err)
}
@@ -146,34 +148,12 @@ func (l *AgentWithdrawalLogic) AgentWithdrawal(req *types.WithdrawalReq) (*types
return nil, err
}
// 同步调用支付宝转账
transferResp, err := l.svcCtx.AlipayService.AliTransfer(l.ctx, req.PayeeAccount, req.PayeeName, finalWithdrawAmount, "公司提现", outBizNo)
if err != nil {
l.Logger.Errorf("【支付宝转账失败】outBizNo:%s error:%v", outBizNo, err)
l.handleTransferError(outBizNo, err, "支付宝接口调用失败")
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "支付宝接口调用失败: %v", err)
}
// 支付宝提现不再直接调用转账接口,改为先申请后审核
// 直接返回申请中状态,等待管理员审核
withdrawRes.Status = WithdrawStatusProcessing
withdrawRes.FailMsg = ""
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)
}
l.Logger.Infof("支付宝提现申请成功 outBizNo:%s agentId:%d amount:%f", outBizNo, agentID, req.Amount)
return withdrawRes, nil
}
@@ -217,12 +197,13 @@ func (l *AgentWithdrawalLogic) mapAlipayError(code string) string {
}
// 创建提现记录(事务内操作)
func (l *AgentWithdrawalLogic) createWithdrawalRecord(session sqlx.Session, agentID int64, payeeAccount string, amount float64, finalWithdrawAmount float64, taxAmount float64, outBizNo string) (int64, error) {
func (l *AgentWithdrawalLogic) createWithdrawalRecord(session sqlx.Session, agentID int64, payeeAccount string, payeeName string, amount float64, finalWithdrawAmount float64, taxAmount float64, outBizNo string) (int64, error) {
record := &model.AgentWithdrawal{
AgentId: agentID,
WithdrawType: 1, // 支付宝提现
WithdrawNo: outBizNo,
PayeeAccount: payeeAccount,
PayeeName: sql.NullString{String: payeeName, Valid: true}, // 设置收款人姓名
Amount: amount,
ActualAmount: finalWithdrawAmount,
TaxAmount: taxAmount,

View File

@@ -118,11 +118,11 @@ func (l *BankCardWithdrawalLogic) BankCardWithdrawal(req *types.BankCardWithdraw
)
// 统一扣税逻辑所有提现都按6%收取税收
exemptionAmount = 0 // 免税金额 = 0
TaxStatus = model.TaxStatusPending // 扣税状态 = 待扣税
taxDeductionPart = req.Amount // 应税金额 = 提现金额
taxAmount = taxDeductionPart * taxRate // 应缴税费 = 应税金额 * 税率
finalWithdrawAmount = req.Amount - taxAmount // 实际到账金额 = 提现金额 - 应缴税费
exemptionAmount = 0 // 免税金额 = 0
TaxStatus = model.TaxStatusPending // 扣税状态 = 待扣税
taxDeductionPart = req.Amount // 应税金额 = 提现金额
taxAmount = taxDeductionPart * taxRate // 应缴税费 = 应税金额 * 税率
finalWithdrawAmount = req.Amount - taxAmount // 实际到账金额 = 提现金额 - 应缴税费
// 创建提现记录(初始状态为申请中,提现类型为银行卡)
withdrawalID, err := l.createBankCardWithdrawalRecord(session, agentModel.Id, req.BankCardNo, req.BankName, agentRealName.Name, req.Amount, finalWithdrawAmount, taxAmount, outBizNo)

View File

@@ -62,7 +62,7 @@ func (l *GetBankCardInfoLogic) GetBankCardInfo(req *types.GetBankCardInfoReq) (r
builder := l.svcCtx.AgentWithdrawalModel.SelectBuilder()
builder = builder.Where(squirrel.Eq{"agent_id": agentModel.Id})
builder = builder.Where(squirrel.Eq{"withdraw_type": 2}) // 银行卡提现
builder = builder.Where(squirrel.Eq{"status": 2}) // 成功状态
builder = builder.Where(squirrel.Eq{"status": 2}) // 成功状态
builder = builder.OrderBy("create_time DESC")
builder = builder.Limit(1)

View File

@@ -35,7 +35,6 @@ func NewUnfreezeCommissionHandler(svcCtx *svc.ServiceContext) *UnfreezeCommissio
func (l *UnfreezeCommissionHandler) ProcessTask(ctx context.Context, t *asynq.Task) error {
now := time.Now()
logx.Infof("%s - 开始执行佣金解冻任务", now.Format("2006-01-02 15:04:05"))
// 解析任务payload获取佣金ID
var payload types.MsgUnfreezeCommissionPayload
if err := json.Unmarshal(t.Payload(), &payload); err != nil {

View File

@@ -224,12 +224,14 @@ type AdminGetAgentCommissionDeductionListResp struct {
}
type AdminGetAgentCommissionListReq struct {
Page int64 `form:"page"` // 页码
PageSize int64 `form:"pageSize"` // 每页数量
AgentId *int64 `form:"agent_id,optional"` // 代理ID可选
OrderId *int64 `form:"order_id,optional"` // 订单ID可选
ProductName *string `form:"product_name,optional"` // 产品名(可选)
Status *int64 `form:"status,optional"` // 状态(可选)
Page int64 `form:"page"` // 页码
PageSize int64 `form:"pageSize"` // 每页数量
AgentId *int64 `form:"agent_id,optional"` // 代理ID可选
OrderId *int64 `form:"order_id,optional"` // 订单ID可选
ProductName *string `form:"product_name,optional"` // 产品名(可选)
Status *int64 `form:"status,optional"` // 状态(可选)
CreateTimeStart *string `form:"create_time_start,optional"` // 创建时间开始(可选)
CreateTimeEnd *string `form:"create_time_end,optional"` // 创建时间结束(可选)
}
type AdminGetAgentCommissionListResp struct {
@@ -362,11 +364,12 @@ type AdminGetAgentWalletResp struct {
}
type AdminGetAgentWithdrawalListReq struct {
Page int64 `form:"page"` // 页码
PageSize int64 `form:"pageSize"` // 每页数量
AgentId *int64 `form:"agent_id,optional"` // 代理ID可选
Status *int64 `form:"status,optional"` // 状态(可选)
WithdrawNo *string `form:"withdraw_no,optional"` // 提现单号(可选)
Page int64 `form:"page"` // 页码
PageSize int64 `form:"pageSize"` // 每页数量
AgentId *int64 `form:"agent_id,optional"` // 代理ID可选
Status *int64 `form:"status,optional"` // 状态(可选)
WithdrawNo *string `form:"withdraw_no,optional"` // 提现单号(可选)
WithdrawType *int64 `form:"withdraw_type,optional"` // 提现类型可选1-支付宝,2-银行卡
}
type AdminGetAgentWithdrawalListResp struct {
@@ -849,6 +852,16 @@ type AdminUpdateAgentProductionConfigResp struct {
Success bool `json:"success"` // 是否成功
}
type AdminUpdateAgentWalletBalanceReq struct {
AgentId int64 `json:"agent_id"` // 代理ID
Amount float64 `json:"amount"` // 修改金额(正数增加,负数减少)
}
type AdminUpdateAgentWalletBalanceResp struct {
Success bool `json:"success"` // 是否成功
Balance float64 `json:"balance"` // 修改后的余额
}
type AdminUpdateApiReq struct {
Id int64 `path:"id"`
ApiName string `json:"api_name"`