f
This commit is contained in:
@@ -19,6 +19,12 @@ service main {
|
|||||||
|
|
||||||
@handler getAppVersion
|
@handler getAppVersion
|
||||||
get /app/version returns (getAppVersionResp)
|
get /app/version returns (getAppVersionResp)
|
||||||
|
|
||||||
|
@doc(
|
||||||
|
summary: "获取APP全局配置"
|
||||||
|
)
|
||||||
|
@handler getAppConfig
|
||||||
|
get /app/config returns (GetAppConfigResp)
|
||||||
}
|
}
|
||||||
|
|
||||||
type (
|
type (
|
||||||
@@ -35,3 +41,13 @@ type (
|
|||||||
WgtUrl string `json:"wgtUrl"`
|
WgtUrl string `json:"wgtUrl"`
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type (
|
||||||
|
AppQueryConfig {
|
||||||
|
RetentionDays int64 `json:"retention_days"` // 查询结果保留天数
|
||||||
|
}
|
||||||
|
|
||||||
|
GetAppConfigResp {
|
||||||
|
Query AppQueryConfig `json:"query"` // 查询相关配置
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|||||||
17
app/main/api/internal/handler/app/getappconfighandler.go
Normal file
17
app/main/api/internal/handler/app/getappconfighandler.go
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
package app
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"bdrp-server/app/main/api/internal/logic/app"
|
||||||
|
"bdrp-server/app/main/api/internal/svc"
|
||||||
|
"bdrp-server/common/result"
|
||||||
|
)
|
||||||
|
|
||||||
|
func GetAppConfigHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||||
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
l := app.NewGetAppConfigLogic(r.Context(), svcCtx)
|
||||||
|
resp, err := l.GetAppConfig()
|
||||||
|
result.HttpResult(r, w, resp, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -899,6 +899,12 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {
|
|||||||
|
|
||||||
server.AddRoutes(
|
server.AddRoutes(
|
||||||
[]rest.Route{
|
[]rest.Route{
|
||||||
|
{
|
||||||
|
// 获取APP全局配置
|
||||||
|
Method: http.MethodGet,
|
||||||
|
Path: "/app/config",
|
||||||
|
Handler: app.GetAppConfigHandler(serverCtx),
|
||||||
|
},
|
||||||
{
|
{
|
||||||
Method: http.MethodGet,
|
Method: http.MethodGet,
|
||||||
Path: "/app/version",
|
Path: "/app/version",
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ func (l *AdminBatchUnfreezeAgentCommissionLogic) AdminBatchUnfreezeAgentCommissi
|
|||||||
// 计算总金额
|
// 计算总金额
|
||||||
var totalAmount float64
|
var totalAmount float64
|
||||||
for _, commission := range commissions {
|
for _, commission := range commissions {
|
||||||
totalAmount += commission.Amount
|
totalAmount = roundMoney(totalAmount + commission.Amount)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 开始事务
|
// 开始事务
|
||||||
@@ -96,16 +96,16 @@ func (l *AdminBatchUnfreezeAgentCommissionLogic) AdminBatchUnfreezeAgentCommissi
|
|||||||
|
|
||||||
// 累加到对应代理商的钱包数据
|
// 累加到对应代理商的钱包数据
|
||||||
if wallet, exists := agentWalletMap[commission.AgentId]; exists {
|
if wallet, exists := agentWalletMap[commission.AgentId]; exists {
|
||||||
wallet.Balance += commission.Amount
|
wallet.Balance = roundMoney(wallet.Balance + commission.Amount)
|
||||||
wallet.FrozenBalance -= commission.Amount
|
wallet.FrozenBalance = roundMoney(wallet.FrozenBalance - commission.Amount)
|
||||||
} else {
|
} else {
|
||||||
// 查询该代理商的钱包
|
// 查询该代理商的钱包
|
||||||
wallet, err := l.svcCtx.AgentWalletModel.FindOneByAgentId(ctx, commission.AgentId)
|
wallet, err := l.svcCtx.AgentWalletModel.FindOneByAgentId(ctx, commission.AgentId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
wallet.Balance += commission.Amount
|
wallet.Balance = roundMoney(wallet.Balance + commission.Amount)
|
||||||
wallet.FrozenBalance -= commission.Amount
|
wallet.FrozenBalance = roundMoney(wallet.FrozenBalance - commission.Amount)
|
||||||
agentWalletMap[commission.AgentId] = wallet
|
agentWalletMap[commission.AgentId] = wallet
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
package admin_agent
|
package admin_agent
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bdrp-server/app/main/model"
|
||||||
|
"bdrp-server/common/xerr"
|
||||||
"context"
|
"context"
|
||||||
"database/sql"
|
"database/sql"
|
||||||
"time"
|
"time"
|
||||||
"bdrp-server/app/main/model"
|
|
||||||
"bdrp-server/common/xerr"
|
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"github.com/zeromicro/go-zero/core/stores/sqlx"
|
"github.com/zeromicro/go-zero/core/stores/sqlx"
|
||||||
@@ -164,7 +164,7 @@ func (l *AdminReviewBankCardWithdrawalLogic) approveBankCardWithdrawal(ctx conte
|
|||||||
frozenBalanceBefore := wallet.FrozenBalance
|
frozenBalanceBefore := wallet.FrozenBalance
|
||||||
|
|
||||||
// 更新钱包(减少冻结余额)
|
// 更新钱包(减少冻结余额)
|
||||||
wallet.FrozenBalance -= record.Amount
|
wallet.FrozenBalance = roundMoney(wallet.FrozenBalance - record.Amount)
|
||||||
if err := l.svcCtx.AgentWalletModel.UpdateWithVersion(ctx, session, wallet); err != nil {
|
if err := l.svcCtx.AgentWalletModel.UpdateWithVersion(ctx, session, wallet); err != nil {
|
||||||
return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "更新钱包失败: %v", err)
|
return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "更新钱包失败: %v", err)
|
||||||
}
|
}
|
||||||
@@ -175,14 +175,14 @@ func (l *AdminReviewBankCardWithdrawalLogic) approveBankCardWithdrawal(ctx conte
|
|||||||
session,
|
session,
|
||||||
wallet.AgentId,
|
wallet.AgentId,
|
||||||
model.WalletTransactionTypeWithdraw,
|
model.WalletTransactionTypeWithdraw,
|
||||||
-record.Amount, // 变动金额(负数表示减少)
|
roundMoney(-record.Amount), // 变动金额(负数表示减少)
|
||||||
wallet.Balance, // 变动前余额(不变)
|
roundMoney(wallet.Balance), // 变动前余额(不变)
|
||||||
wallet.Balance, // 变动后余额(不变)
|
roundMoney(wallet.Balance), // 变动后余额(不变)
|
||||||
frozenBalanceBefore, // 变动前冻结余额
|
roundMoney(frozenBalanceBefore), // 变动前冻结余额
|
||||||
wallet.FrozenBalance, // 变动后冻结余额
|
roundMoney(wallet.FrozenBalance), // 变动后冻结余额
|
||||||
record.WithdrawNo, // 关联交易ID
|
record.WithdrawNo, // 关联交易ID
|
||||||
0, // 关联用户ID
|
0, // 关联用户ID
|
||||||
"提现审核通过", // 备注
|
"提现审核通过", // 备注
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -234,8 +234,8 @@ func (l *AdminReviewBankCardWithdrawalLogic) rejectWithdrawal(ctx context.Contex
|
|||||||
frozenBalanceBefore := wallet.FrozenBalance
|
frozenBalanceBefore := wallet.FrozenBalance
|
||||||
|
|
||||||
// 更新钱包(余额增加,冻结余额减少)
|
// 更新钱包(余额增加,冻结余额减少)
|
||||||
wallet.Balance += record.Amount
|
wallet.Balance = roundMoney(wallet.Balance + record.Amount)
|
||||||
wallet.FrozenBalance -= record.Amount
|
wallet.FrozenBalance = roundMoney(wallet.FrozenBalance - record.Amount)
|
||||||
if err := l.svcCtx.AgentWalletModel.UpdateWithVersion(ctx, session, wallet); err != nil {
|
if err := l.svcCtx.AgentWalletModel.UpdateWithVersion(ctx, session, wallet); err != nil {
|
||||||
return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "更新钱包失败: %v", err)
|
return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "更新钱包失败: %v", err)
|
||||||
}
|
}
|
||||||
@@ -246,14 +246,14 @@ func (l *AdminReviewBankCardWithdrawalLogic) rejectWithdrawal(ctx context.Contex
|
|||||||
session,
|
session,
|
||||||
wallet.AgentId,
|
wallet.AgentId,
|
||||||
model.WalletTransactionTypeUnfreeze,
|
model.WalletTransactionTypeUnfreeze,
|
||||||
record.Amount, // 变动金额(正数表示增加)
|
roundMoney(record.Amount), // 变动金额(正数表示增加)
|
||||||
balanceBefore, // 变动前余额
|
roundMoney(balanceBefore), // 变动前余额
|
||||||
wallet.Balance, // 变动后余额
|
roundMoney(wallet.Balance), // 变动后余额
|
||||||
frozenBalanceBefore, // 变动前冻结余额
|
roundMoney(frozenBalanceBefore), // 变动前冻结余额
|
||||||
wallet.FrozenBalance, // 变动后冻结余额
|
roundMoney(wallet.FrozenBalance), // 变动后冻结余额
|
||||||
record.WithdrawNo, // 关联交易ID
|
record.WithdrawNo, // 关联交易ID
|
||||||
0, // 关联用户ID
|
0, // 关联用户ID
|
||||||
"提现拒绝,解冻资金", // 备注
|
"提现拒绝,解冻资金", // 备注
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -295,7 +295,7 @@ func (l *AdminReviewBankCardWithdrawalLogic) completeWithdrawalSuccess(ctx conte
|
|||||||
frozenBalanceBefore := wallet.FrozenBalance
|
frozenBalanceBefore := wallet.FrozenBalance
|
||||||
|
|
||||||
// 更新钱包(减少冻结余额)
|
// 更新钱包(减少冻结余额)
|
||||||
wallet.FrozenBalance -= record.Amount
|
wallet.FrozenBalance = roundMoney(wallet.FrozenBalance - record.Amount)
|
||||||
if err := l.svcCtx.AgentWalletModel.UpdateWithVersion(ctx, session, wallet); err != nil {
|
if err := l.svcCtx.AgentWalletModel.UpdateWithVersion(ctx, session, wallet); err != nil {
|
||||||
return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "更新钱包失败: %v", err)
|
return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "更新钱包失败: %v", err)
|
||||||
}
|
}
|
||||||
@@ -306,14 +306,14 @@ func (l *AdminReviewBankCardWithdrawalLogic) completeWithdrawalSuccess(ctx conte
|
|||||||
session,
|
session,
|
||||||
wallet.AgentId,
|
wallet.AgentId,
|
||||||
model.WalletTransactionTypeWithdraw,
|
model.WalletTransactionTypeWithdraw,
|
||||||
-record.Amount, // 变动金额(负数表示减少)
|
roundMoney(-record.Amount), // 变动金额(负数表示减少)
|
||||||
wallet.Balance, // 变动前余额(不变)
|
roundMoney(wallet.Balance), // 变动前余额(不变)
|
||||||
wallet.Balance, // 变动后余额(不变)
|
roundMoney(wallet.Balance), // 变动后余额(不变)
|
||||||
frozenBalanceBefore, // 变动前冻结余额
|
roundMoney(frozenBalanceBefore), // 变动前冻结余额
|
||||||
wallet.FrozenBalance, // 变动后冻结余额
|
roundMoney(wallet.FrozenBalance), // 变动后冻结余额
|
||||||
record.WithdrawNo, // 关联交易ID
|
record.WithdrawNo, // 关联交易ID
|
||||||
0, // 关联用户ID
|
0, // 关联用户ID
|
||||||
"提现成功", // 备注
|
"提现成功", // 备注
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -365,8 +365,8 @@ func (l *AdminReviewBankCardWithdrawalLogic) completeWithdrawalFailure(ctx conte
|
|||||||
frozenBalanceBefore := wallet.FrozenBalance
|
frozenBalanceBefore := wallet.FrozenBalance
|
||||||
|
|
||||||
// 更新钱包(余额增加,冻结余额减少)
|
// 更新钱包(余额增加,冻结余额减少)
|
||||||
wallet.Balance += record.Amount
|
wallet.Balance = roundMoney(wallet.Balance + record.Amount)
|
||||||
wallet.FrozenBalance -= record.Amount
|
wallet.FrozenBalance = roundMoney(wallet.FrozenBalance - record.Amount)
|
||||||
if err := l.svcCtx.AgentWalletModel.UpdateWithVersion(ctx, session, wallet); err != nil {
|
if err := l.svcCtx.AgentWalletModel.UpdateWithVersion(ctx, session, wallet); err != nil {
|
||||||
return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "更新钱包失败: %v", err)
|
return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "更新钱包失败: %v", err)
|
||||||
}
|
}
|
||||||
@@ -377,14 +377,14 @@ func (l *AdminReviewBankCardWithdrawalLogic) completeWithdrawalFailure(ctx conte
|
|||||||
session,
|
session,
|
||||||
wallet.AgentId,
|
wallet.AgentId,
|
||||||
model.WalletTransactionTypeUnfreeze,
|
model.WalletTransactionTypeUnfreeze,
|
||||||
record.Amount, // 变动金额(正数表示增加)
|
roundMoney(record.Amount), // 变动金额(正数表示增加)
|
||||||
balanceBefore, // 变动前余额
|
roundMoney(balanceBefore), // 变动前余额
|
||||||
wallet.Balance, // 变动后余额
|
roundMoney(wallet.Balance), // 变动后余额
|
||||||
frozenBalanceBefore, // 变动前冻结余额
|
roundMoney(frozenBalanceBefore), // 变动前冻结余额
|
||||||
wallet.FrozenBalance, // 变动后冻结余额
|
roundMoney(wallet.FrozenBalance), // 变动后冻结余额
|
||||||
record.WithdrawNo, // 关联交易ID
|
record.WithdrawNo, // 关联交易ID
|
||||||
0, // 关联用户ID
|
0, // 关联用户ID
|
||||||
"提现失败,解冻资金", // 备注
|
"提现失败,解冻资金", // 备注
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"math"
|
||||||
|
|
||||||
"bdrp-server/app/main/api/internal/svc"
|
"bdrp-server/app/main/api/internal/svc"
|
||||||
"bdrp-server/app/main/api/internal/types"
|
"bdrp-server/app/main/api/internal/types"
|
||||||
@@ -14,6 +15,10 @@ import (
|
|||||||
"github.com/zeromicro/go-zero/core/stores/sqlx"
|
"github.com/zeromicro/go-zero/core/stores/sqlx"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func roundMoney(v float64) float64 {
|
||||||
|
return math.Round(v*100) / 100
|
||||||
|
}
|
||||||
|
|
||||||
type AdminUpdateAgentWalletBalanceLogic struct {
|
type AdminUpdateAgentWalletBalanceLogic struct {
|
||||||
logx.Logger
|
logx.Logger
|
||||||
ctx context.Context
|
ctx context.Context
|
||||||
@@ -47,7 +52,8 @@ func (l *AdminUpdateAgentWalletBalanceLogic) AdminUpdateAgentWalletBalance(req *
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 计算新余额
|
// 计算新余额
|
||||||
newBalance := wallet.Balance + req.Amount
|
adjustAmount := roundMoney(req.Amount)
|
||||||
|
newBalance := roundMoney(wallet.Balance + adjustAmount)
|
||||||
|
|
||||||
// 校验余额不能为负数
|
// 校验余额不能为负数
|
||||||
if newBalance < 0 {
|
if newBalance < 0 {
|
||||||
@@ -68,20 +74,20 @@ func (l *AdminUpdateAgentWalletBalanceLogic) AdminUpdateAgentWalletBalance(req *
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 创建钱包交易流水记录(手动调整)
|
// 创建钱包交易流水记录(手动调整)
|
||||||
remark := fmt.Sprintf("管理员手动调整余额,金额: %.2f", req.Amount)
|
remark := fmt.Sprintf("管理员手动调整余额,金额: %.2f", adjustAmount)
|
||||||
transErr := l.svcCtx.AgentService.CreateWalletTransaction(
|
transErr := l.svcCtx.AgentService.CreateWalletTransaction(
|
||||||
transCtx,
|
transCtx,
|
||||||
session,
|
session,
|
||||||
req.AgentId,
|
req.AgentId,
|
||||||
model.WalletTransactionTypeAdjust,
|
model.WalletTransactionTypeAdjust,
|
||||||
req.Amount, // 变动金额(正数表示增加,负数表示减少)
|
adjustAmount, // 变动金额(正数表示增加,负数表示减少)
|
||||||
balanceBefore, // 变动前余额
|
roundMoney(balanceBefore), // 变动前余额
|
||||||
wallet.Balance, // 变动后余额
|
roundMoney(wallet.Balance), // 变动后余额
|
||||||
frozenBalanceBefore, // 变动前冻结余额
|
roundMoney(frozenBalanceBefore), // 变动前冻结余额
|
||||||
wallet.FrozenBalance, // 变动后冻结余额(保持不变)
|
roundMoney(wallet.FrozenBalance), // 变动后冻结余额(保持不变)
|
||||||
"", // 关联交易ID(无关联)
|
"", // 关联交易ID(无关联)
|
||||||
0, // 关联用户ID(无关联)
|
0, // 关联用户ID(无关联)
|
||||||
remark, // 备注
|
remark, // 备注
|
||||||
)
|
)
|
||||||
if transErr != nil {
|
if transErr != nil {
|
||||||
l.Logger.Errorf("创建代理钱包流水记录失败: %+v", transErr)
|
l.Logger.Errorf("创建代理钱包流水记录失败: %+v", transErr)
|
||||||
@@ -89,7 +95,7 @@ func (l *AdminUpdateAgentWalletBalanceLogic) AdminUpdateAgentWalletBalance(req *
|
|||||||
}
|
}
|
||||||
|
|
||||||
l.Logger.Infof("代理钱包余额变更 - AgentId: %d, 原余额: %.2f, 变更金额: %.2f, 新余额: %.2f",
|
l.Logger.Infof("代理钱包余额变更 - AgentId: %d, 原余额: %.2f, 变更金额: %.2f, 新余额: %.2f",
|
||||||
req.AgentId, balanceBefore, req.Amount, wallet.Balance)
|
req.AgentId, roundMoney(balanceBefore), adjustAmount, roundMoney(wallet.Balance))
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
@@ -101,7 +107,7 @@ func (l *AdminUpdateAgentWalletBalanceLogic) AdminUpdateAgentWalletBalance(req *
|
|||||||
|
|
||||||
resp = &types.AdminUpdateAgentWalletBalanceResp{
|
resp = &types.AdminUpdateAgentWalletBalanceResp{
|
||||||
Success: true,
|
Success: true,
|
||||||
Balance: newBalance,
|
Balance: roundMoney(newBalance),
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
package agent
|
package agent
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
|
||||||
"database/sql"
|
|
||||||
"fmt"
|
|
||||||
"time"
|
|
||||||
"bdrp-server/app/main/model"
|
"bdrp-server/app/main/model"
|
||||||
"bdrp-server/common/ctxdata"
|
"bdrp-server/common/ctxdata"
|
||||||
"bdrp-server/common/xerr"
|
"bdrp-server/common/xerr"
|
||||||
"bdrp-server/pkg/lzkit/lzUtils"
|
"bdrp-server/pkg/lzkit/lzUtils"
|
||||||
|
"context"
|
||||||
|
"database/sql"
|
||||||
|
"fmt"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/cenkalti/backoff/v4"
|
"github.com/cenkalti/backoff/v4"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
@@ -56,6 +56,8 @@ func (l *AgentWithdrawalLogic) AgentWithdrawal(req *types.WithdrawalReq) (*types
|
|||||||
agentID int64
|
agentID int64
|
||||||
)
|
)
|
||||||
var finalWithdrawAmount float64 // 实际到账金额
|
var finalWithdrawAmount float64 // 实际到账金额
|
||||||
|
withdrawAmount := roundMoney(req.Amount)
|
||||||
|
|
||||||
// 使用事务处理核心操作
|
// 使用事务处理核心操作
|
||||||
err := l.svcCtx.AgentModel.Trans(l.ctx, func(ctx context.Context, session sqlx.Session) error {
|
err := l.svcCtx.AgentModel.Trans(l.ctx, func(ctx context.Context, session sqlx.Session) error {
|
||||||
userID, err := ctxdata.GetUidFromCtx(l.ctx)
|
userID, err := ctxdata.GetUidFromCtx(l.ctx)
|
||||||
@@ -89,7 +91,7 @@ func (l *AgentWithdrawalLogic) AgentWithdrawal(req *types.WithdrawalReq) (*types
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 校验可提现金额
|
// 校验可提现金额
|
||||||
if req.Amount > agentWallet.Balance {
|
if withdrawAmount > roundMoney(agentWallet.Balance) {
|
||||||
return errors.Wrapf(xerr.NewErrMsg("您可提现的余额不足"), "获取用户ID失败")
|
return errors.Wrapf(xerr.NewErrMsg("您可提现的余额不足"), "获取用户ID失败")
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -97,7 +99,7 @@ func (l *AgentWithdrawalLogic) AgentWithdrawal(req *types.WithdrawalReq) (*types
|
|||||||
outBizNo = "W_" + l.svcCtx.AlipayService.GenerateOutTradeNo()
|
outBizNo = "W_" + l.svcCtx.AlipayService.GenerateOutTradeNo()
|
||||||
|
|
||||||
// 冻结资金(事务内操作)
|
// 冻结资金(事务内操作)
|
||||||
if err = l.freezeFunds(session, agentWallet, req.Amount); err != nil {
|
if err = l.freezeFunds(session, agentWallet, withdrawAmount); err != nil {
|
||||||
return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "资金冻结失败: %v", err)
|
return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "资金冻结失败: %v", err)
|
||||||
}
|
}
|
||||||
yearMonth := int64(time.Now().Year()*100 + int(time.Now().Month()))
|
yearMonth := int64(time.Now().Year()*100 + int(time.Now().Month()))
|
||||||
@@ -111,14 +113,14 @@ func (l *AgentWithdrawalLogic) AgentWithdrawal(req *types.WithdrawalReq) (*types
|
|||||||
)
|
)
|
||||||
|
|
||||||
// 统一扣税逻辑:所有提现都按6%收取税收
|
// 统一扣税逻辑:所有提现都按6%收取税收
|
||||||
exemptionAmount = 0 // 免税金额 = 0
|
exemptionAmount = 0 // 免税金额 = 0
|
||||||
TaxStatus = model.TaxStatusPending // 扣税状态 = 待扣税
|
TaxStatus = model.TaxStatusPending // 扣税状态 = 待扣税
|
||||||
taxDeductionPart = req.Amount // 应税金额 = 提现金额
|
taxDeductionPart = withdrawAmount // 应税金额 = 提现金额
|
||||||
taxAmount = taxDeductionPart * taxRate // 应缴税费 = 应税金额 * 税率
|
taxAmount = roundMoney(taxDeductionPart * taxRate) // 应缴税费 = 应税金额 * 税率
|
||||||
finalWithdrawAmount = req.Amount - taxAmount // 实际到账金额 = 提现金额 - 应缴税费
|
finalWithdrawAmount = roundMoney(withdrawAmount - taxAmount) // 实际到账金额 = 提现金额 - 应缴税费
|
||||||
|
|
||||||
// 创建提现记录(初始状态为处理中)
|
// 创建提现记录(初始状态为处理中)
|
||||||
withdrawalID, err := l.createWithdrawalRecord(session, agentModel.Id, req.PayeeAccount, req.PayeeName, req.Amount, finalWithdrawAmount, taxAmount, outBizNo)
|
withdrawalID, err := l.createWithdrawalRecord(session, agentModel.Id, req.PayeeAccount, req.PayeeName, withdrawAmount, finalWithdrawAmount, taxAmount, outBizNo)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "创建提现记录失败: %v", err)
|
return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "创建提现记录失败: %v", err)
|
||||||
}
|
}
|
||||||
@@ -127,7 +129,7 @@ func (l *AgentWithdrawalLogic) AgentWithdrawal(req *types.WithdrawalReq) (*types
|
|||||||
AgentId: agentModel.Id,
|
AgentId: agentModel.Id,
|
||||||
YearMonth: yearMonth,
|
YearMonth: yearMonth,
|
||||||
WithdrawalId: withdrawalID,
|
WithdrawalId: withdrawalID,
|
||||||
WithdrawalAmount: req.Amount,
|
WithdrawalAmount: withdrawAmount,
|
||||||
ExemptionAmount: exemptionAmount,
|
ExemptionAmount: exemptionAmount,
|
||||||
TaxableAmount: taxDeductionPart,
|
TaxableAmount: taxDeductionPart,
|
||||||
TaxRate: taxRate,
|
TaxRate: taxRate,
|
||||||
@@ -153,7 +155,7 @@ func (l *AgentWithdrawalLogic) AgentWithdrawal(req *types.WithdrawalReq) (*types
|
|||||||
withdrawRes.Status = WithdrawStatusProcessing
|
withdrawRes.Status = WithdrawStatusProcessing
|
||||||
withdrawRes.FailMsg = ""
|
withdrawRes.FailMsg = ""
|
||||||
|
|
||||||
l.Logger.Infof("支付宝提现申请成功 outBizNo:%s agentId:%d amount:%f", outBizNo, agentID, req.Amount)
|
l.Logger.Infof("支付宝提现申请成功 outBizNo:%s agentId:%d amount:%f", outBizNo, agentID, withdrawAmount)
|
||||||
return withdrawRes, nil
|
return withdrawRes, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -193,6 +195,7 @@ func (l *AgentWithdrawalLogic) mapAlipayError(code string) string {
|
|||||||
if msg, ok := errorMapping[code]; ok {
|
if msg, ok := errorMapping[code]; ok {
|
||||||
return msg
|
return msg
|
||||||
}
|
}
|
||||||
|
l.Logger.Infof("未匹配到支付宝错误码 code:%s", code)
|
||||||
return "系统错误,请联系客服"
|
return "系统错误,请联系客服"
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -204,9 +207,9 @@ func (l *AgentWithdrawalLogic) createWithdrawalRecord(session sqlx.Session, agen
|
|||||||
WithdrawNo: outBizNo,
|
WithdrawNo: outBizNo,
|
||||||
PayeeAccount: payeeAccount,
|
PayeeAccount: payeeAccount,
|
||||||
PayeeName: sql.NullString{String: payeeName, Valid: true}, // 设置收款人姓名
|
PayeeName: sql.NullString{String: payeeName, Valid: true}, // 设置收款人姓名
|
||||||
Amount: amount,
|
Amount: roundMoney(amount),
|
||||||
ActualAmount: finalWithdrawAmount,
|
ActualAmount: roundMoney(finalWithdrawAmount),
|
||||||
TaxAmount: taxAmount,
|
TaxAmount: roundMoney(taxAmount),
|
||||||
Status: StatusProcessing,
|
Status: StatusProcessing,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -219,8 +222,8 @@ func (l *AgentWithdrawalLogic) createWithdrawalRecord(session sqlx.Session, agen
|
|||||||
|
|
||||||
// 冻结资金(事务内操作)
|
// 冻结资金(事务内操作)
|
||||||
func (l *AgentWithdrawalLogic) freezeFunds(session sqlx.Session, wallet *model.AgentWallet, amount float64) error {
|
func (l *AgentWithdrawalLogic) freezeFunds(session sqlx.Session, wallet *model.AgentWallet, amount float64) error {
|
||||||
wallet.Balance -= amount
|
wallet.Balance = roundMoney(wallet.Balance - amount)
|
||||||
wallet.FrozenBalance += amount
|
wallet.FrozenBalance = roundMoney(wallet.FrozenBalance + amount)
|
||||||
err := l.svcCtx.AgentWalletModel.UpdateWithVersion(l.ctx, session, wallet)
|
err := l.svcCtx.AgentWalletModel.UpdateWithVersion(l.ctx, session, wallet)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -296,8 +299,8 @@ func (l *AgentWithdrawalLogic) updateWithdrawalStatus(outBizNo string, status in
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
wallet.Balance += record.Amount
|
wallet.Balance = roundMoney(wallet.Balance + record.Amount)
|
||||||
wallet.FrozenBalance -= record.Amount
|
wallet.FrozenBalance = roundMoney(wallet.FrozenBalance - record.Amount)
|
||||||
if err := l.svcCtx.AgentWalletModel.UpdateWithVersion(ctx, session, wallet); err != nil {
|
if err := l.svcCtx.AgentWalletModel.UpdateWithVersion(ctx, session, wallet); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -320,7 +323,7 @@ func (l *AgentWithdrawalLogic) updateWithdrawalStatus(outBizNo string, status in
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
wallet.FrozenBalance -= record.Amount
|
wallet.FrozenBalance = roundMoney(wallet.FrozenBalance - record.Amount)
|
||||||
if err := l.svcCtx.AgentWalletModel.UpdateWithVersion(ctx, session, wallet); err != nil {
|
if err := l.svcCtx.AgentWalletModel.UpdateWithVersion(ctx, session, wallet); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
package agent
|
package agent
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bdrp-server/app/main/model"
|
||||||
|
"bdrp-server/common/ctxdata"
|
||||||
|
"bdrp-server/common/xerr"
|
||||||
"context"
|
"context"
|
||||||
"database/sql"
|
"database/sql"
|
||||||
"regexp"
|
"regexp"
|
||||||
"time"
|
"time"
|
||||||
"bdrp-server/app/main/model"
|
|
||||||
"bdrp-server/common/ctxdata"
|
|
||||||
"bdrp-server/common/xerr"
|
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"github.com/zeromicro/go-zero/core/stores/sqlx"
|
"github.com/zeromicro/go-zero/core/stores/sqlx"
|
||||||
@@ -57,6 +57,8 @@ func (l *BankCardWithdrawalLogic) BankCardWithdrawal(req *types.BankCardWithdraw
|
|||||||
return nil, errors.Wrapf(xerr.NewErrMsg("开户支行不能为空"), "开户支行验证失败")
|
return nil, errors.Wrapf(xerr.NewErrMsg("开户支行不能为空"), "开户支行验证失败")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
withdrawAmount := roundMoney(req.Amount)
|
||||||
|
|
||||||
// 使用事务处理核心操作
|
// 使用事务处理核心操作
|
||||||
err = l.svcCtx.AgentModel.Trans(l.ctx, func(ctx context.Context, session sqlx.Session) error {
|
err = l.svcCtx.AgentModel.Trans(l.ctx, func(ctx context.Context, session sqlx.Session) error {
|
||||||
userID, err := ctxdata.GetUidFromCtx(l.ctx)
|
userID, err := ctxdata.GetUidFromCtx(l.ctx)
|
||||||
@@ -90,12 +92,12 @@ func (l *BankCardWithdrawalLogic) BankCardWithdrawal(req *types.BankCardWithdraw
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 校验可提现金额
|
// 校验可提现金额
|
||||||
if req.Amount > agentWallet.Balance {
|
if withdrawAmount > roundMoney(agentWallet.Balance) {
|
||||||
return errors.Wrapf(xerr.NewErrMsg("您可提现的余额不足"), "余额不足")
|
return errors.Wrapf(xerr.NewErrMsg("您可提现的余额不足"), "余额不足")
|
||||||
}
|
}
|
||||||
|
|
||||||
// 最低提现金额验证
|
// 最低提现金额验证
|
||||||
if req.Amount < 50 {
|
if withdrawAmount < 50 {
|
||||||
return errors.Wrapf(xerr.NewErrMsg("提现金额不能低于50元"), "金额验证失败")
|
return errors.Wrapf(xerr.NewErrMsg("提现金额不能低于50元"), "金额验证失败")
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -103,7 +105,7 @@ func (l *BankCardWithdrawalLogic) BankCardWithdrawal(req *types.BankCardWithdraw
|
|||||||
outBizNo = "BC_" + l.svcCtx.AlipayService.GenerateOutTradeNo()
|
outBizNo = "BC_" + l.svcCtx.AlipayService.GenerateOutTradeNo()
|
||||||
|
|
||||||
// 冻结资金(事务内操作)
|
// 冻结资金(事务内操作)
|
||||||
if err = l.freezeFunds(session, agentWallet, req.Amount); err != nil {
|
if err = l.freezeFunds(session, agentWallet, withdrawAmount); err != nil {
|
||||||
return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "资金冻结失败: %v", err)
|
return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "资金冻结失败: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -118,14 +120,14 @@ func (l *BankCardWithdrawalLogic) BankCardWithdrawal(req *types.BankCardWithdraw
|
|||||||
)
|
)
|
||||||
|
|
||||||
// 统一扣税逻辑:所有提现都按6%收取税收
|
// 统一扣税逻辑:所有提现都按6%收取税收
|
||||||
exemptionAmount = 0 // 免税金额 = 0
|
exemptionAmount = 0 // 免税金额 = 0
|
||||||
TaxStatus = model.TaxStatusPending // 扣税状态 = 待扣税
|
TaxStatus = model.TaxStatusPending // 扣税状态 = 待扣税
|
||||||
taxDeductionPart = req.Amount // 应税金额 = 提现金额
|
taxDeductionPart = withdrawAmount // 应税金额 = 提现金额
|
||||||
taxAmount = taxDeductionPart * taxRate // 应缴税费 = 应税金额 * 税率
|
taxAmount = roundMoney(taxDeductionPart * taxRate) // 应缴税费 = 应税金额 * 税率
|
||||||
finalWithdrawAmount = req.Amount - taxAmount // 实际到账金额 = 提现金额 - 应缴税费
|
finalWithdrawAmount = roundMoney(withdrawAmount - taxAmount) // 实际到账金额 = 提现金额 - 应缴税费
|
||||||
|
|
||||||
// 创建提现记录(初始状态为申请中,提现类型为银行卡)
|
// 创建提现记录(初始状态为申请中,提现类型为银行卡)
|
||||||
withdrawalID, err := l.createBankCardWithdrawalRecord(session, agentModel.Id, req.BankCardNo, req.BankName, agentRealName.Name, req.Amount, finalWithdrawAmount, taxAmount, outBizNo)
|
withdrawalID, err := l.createBankCardWithdrawalRecord(session, agentModel.Id, req.BankCardNo, req.BankName, agentRealName.Name, withdrawAmount, finalWithdrawAmount, taxAmount, outBizNo)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "创建提现记录失败: %v", err)
|
return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "创建提现记录失败: %v", err)
|
||||||
}
|
}
|
||||||
@@ -135,7 +137,7 @@ func (l *BankCardWithdrawalLogic) BankCardWithdrawal(req *types.BankCardWithdraw
|
|||||||
AgentId: agentModel.Id,
|
AgentId: agentModel.Id,
|
||||||
YearMonth: yearMonth,
|
YearMonth: yearMonth,
|
||||||
WithdrawalId: withdrawalID,
|
WithdrawalId: withdrawalID,
|
||||||
WithdrawalAmount: req.Amount,
|
WithdrawalAmount: withdrawAmount,
|
||||||
ExemptionAmount: exemptionAmount,
|
ExemptionAmount: exemptionAmount,
|
||||||
TaxableAmount: taxDeductionPart,
|
TaxableAmount: taxDeductionPart,
|
||||||
TaxRate: taxRate,
|
TaxRate: taxRate,
|
||||||
@@ -160,7 +162,7 @@ func (l *BankCardWithdrawalLogic) BankCardWithdrawal(req *types.BankCardWithdraw
|
|||||||
withdrawRes.Status = WithdrawStatusProcessing
|
withdrawRes.Status = WithdrawStatusProcessing
|
||||||
withdrawRes.FailMsg = ""
|
withdrawRes.FailMsg = ""
|
||||||
|
|
||||||
l.Logger.Infof("银行卡提现申请成功 outBizNo:%s agentId:%d amount:%f", outBizNo, agentID, req.Amount)
|
l.Logger.Infof("银行卡提现申请成功 outBizNo:%s agentId:%d amount:%f", outBizNo, agentID, withdrawAmount)
|
||||||
return withdrawRes, nil
|
return withdrawRes, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -171,9 +173,9 @@ func (l *BankCardWithdrawalLogic) createBankCardWithdrawalRecord(session sqlx.Se
|
|||||||
WithdrawType: WithdrawTypeBankCard, // 银行卡提现
|
WithdrawType: WithdrawTypeBankCard, // 银行卡提现
|
||||||
WithdrawNo: outBizNo,
|
WithdrawNo: outBizNo,
|
||||||
PayeeAccount: bankCardNo, // 银行卡号存储在PayeeAccount字段
|
PayeeAccount: bankCardNo, // 银行卡号存储在PayeeAccount字段
|
||||||
Amount: amount,
|
Amount: roundMoney(amount),
|
||||||
ActualAmount: finalWithdrawAmount,
|
ActualAmount: roundMoney(finalWithdrawAmount),
|
||||||
TaxAmount: taxAmount,
|
TaxAmount: roundMoney(taxAmount),
|
||||||
Status: StatusProcessing, // 申请中状态
|
Status: StatusProcessing, // 申请中状态
|
||||||
BankCardNo: sql.NullString{String: bankCardNo, Valid: true},
|
BankCardNo: sql.NullString{String: bankCardNo, Valid: true},
|
||||||
BankName: sql.NullString{String: bankName, Valid: true},
|
BankName: sql.NullString{String: bankName, Valid: true},
|
||||||
@@ -194,8 +196,8 @@ func (l *BankCardWithdrawalLogic) freezeFunds(session sqlx.Session, wallet *mode
|
|||||||
frozenBalanceBefore := wallet.FrozenBalance
|
frozenBalanceBefore := wallet.FrozenBalance
|
||||||
|
|
||||||
// 更新钱包余额
|
// 更新钱包余额
|
||||||
wallet.Balance -= amount
|
wallet.Balance = roundMoney(wallet.Balance - amount)
|
||||||
wallet.FrozenBalance += amount
|
wallet.FrozenBalance = roundMoney(wallet.FrozenBalance + amount)
|
||||||
err := l.svcCtx.AgentWalletModel.UpdateWithVersion(l.ctx, session, wallet)
|
err := l.svcCtx.AgentWalletModel.UpdateWithVersion(l.ctx, session, wallet)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -207,7 +209,7 @@ func (l *BankCardWithdrawalLogic) freezeFunds(session sqlx.Session, wallet *mode
|
|||||||
session,
|
session,
|
||||||
wallet.AgentId,
|
wallet.AgentId,
|
||||||
model.WalletTransactionTypeFreeze,
|
model.WalletTransactionTypeFreeze,
|
||||||
amount, // 变动金额
|
roundMoney(amount), // 变动金额
|
||||||
balanceBefore, // 变动前余额
|
balanceBefore, // 变动前余额
|
||||||
wallet.Balance, // 变动后余额
|
wallet.Balance, // 变动后余额
|
||||||
frozenBalanceBefore, // 变动前冻结余额
|
frozenBalanceBefore, // 变动前冻结余额
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import (
|
|||||||
"bdrp-server/app/main/model"
|
"bdrp-server/app/main/model"
|
||||||
"bdrp-server/common/ctxdata"
|
"bdrp-server/common/ctxdata"
|
||||||
"bdrp-server/common/xerr"
|
"bdrp-server/common/xerr"
|
||||||
|
"math"
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"github.com/zeromicro/go-zero/core/mr"
|
"github.com/zeromicro/go-zero/core/mr"
|
||||||
@@ -32,6 +33,10 @@ func NewGetAgentProductConfigLogic(ctx context.Context, svcCtx *svc.ServiceConte
|
|||||||
type AgentProductConfigResp struct {
|
type AgentProductConfigResp struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func roundMoney(v float64) float64 {
|
||||||
|
return math.Round(v*100) / 100
|
||||||
|
}
|
||||||
|
|
||||||
func (l *GetAgentProductConfigLogic) GetAgentProductConfig() (resp *types.AgentProductConfigResp, err error) {
|
func (l *GetAgentProductConfigLogic) GetAgentProductConfig() (resp *types.AgentProductConfigResp, err error) {
|
||||||
userID, err := ctxdata.GetUidFromCtx(l.ctx)
|
userID, err := ctxdata.GetUidFromCtx(l.ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -81,10 +86,10 @@ func (l *GetAgentProductConfigLogic) GetAgentProductConfig() (resp *types.AgentP
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
agentProductConfig.ProductID = config.ProductId
|
agentProductConfig.ProductID = config.ProductId
|
||||||
agentProductConfig.CostPrice = agentProductConfigModel.CostPrice
|
agentProductConfig.CostPrice = roundMoney(agentProductConfigModel.CostPrice)
|
||||||
agentProductConfig.PriceRangeMin = agentProductConfigModel.PriceRangeMin
|
agentProductConfig.PriceRangeMin = roundMoney(agentProductConfigModel.PriceRangeMin)
|
||||||
agentProductConfig.PriceRangeMax = agentProductConfigModel.PriceRangeMax
|
agentProductConfig.PriceRangeMax = roundMoney(agentProductConfigModel.PriceRangeMax)
|
||||||
agentProductConfig.PPricingStandard = agentProductConfigModel.PricingStandard
|
agentProductConfig.PPricingStandard = roundMoney(agentProductConfigModel.PricingStandard)
|
||||||
agentProductConfig.POverpricingRatio = agentProductConfigModel.OverpricingRatio
|
agentProductConfig.POverpricingRatio = agentProductConfigModel.OverpricingRatio
|
||||||
|
|
||||||
// 看推广人是否有上级,上级是否有这个配置权限,上级是否有相关配置
|
// 看推广人是否有上级,上级是否有这个配置权限,上级是否有相关配置
|
||||||
@@ -119,10 +124,10 @@ func (l *GetAgentProductConfigLogic) GetAgentProductConfig() (resp *types.AgentP
|
|||||||
cancel(membershipConfigErr)
|
cancel(membershipConfigErr)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
agentProductConfig.CostPrice += membershipUserConfigModel.PriceIncreaseAmount
|
agentProductConfig.CostPrice = roundMoney(agentProductConfig.CostPrice + membershipUserConfigModel.PriceIncreaseAmount)
|
||||||
agentProductConfig.PriceRangeMin += membershipUserConfigModel.PriceIncreaseAmount
|
agentProductConfig.PriceRangeMin = roundMoney(agentProductConfig.PriceRangeMin + membershipUserConfigModel.PriceIncreaseAmount)
|
||||||
agentProductConfig.APricingStandard = membershipUserConfigModel.PriceRangeFrom
|
agentProductConfig.APricingStandard = roundMoney(membershipUserConfigModel.PriceRangeFrom)
|
||||||
agentProductConfig.APricingEnd = membershipUserConfigModel.PriceRangeTo
|
agentProductConfig.APricingEnd = roundMoney(membershipUserConfigModel.PriceRangeTo)
|
||||||
agentProductConfig.AOverpricingRatio = membershipUserConfigModel.PriceRatio
|
agentProductConfig.AOverpricingRatio = membershipUserConfigModel.PriceRatio
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
51
app/main/api/internal/logic/app/getappconfiglogic.go
Normal file
51
app/main/api/internal/logic/app/getappconfiglogic.go
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
package app
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
|
"bdrp-server/app/main/api/internal/svc"
|
||||||
|
"bdrp-server/app/main/api/internal/types"
|
||||||
|
"bdrp-server/app/main/model"
|
||||||
|
|
||||||
|
"github.com/zeromicro/go-zero/core/logx"
|
||||||
|
)
|
||||||
|
|
||||||
|
type GetAppConfigLogic struct {
|
||||||
|
logx.Logger
|
||||||
|
ctx context.Context
|
||||||
|
svcCtx *svc.ServiceContext
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewGetAppConfigLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetAppConfigLogic {
|
||||||
|
return &GetAppConfigLogic{
|
||||||
|
Logger: logx.WithContext(ctx),
|
||||||
|
ctx: ctx,
|
||||||
|
svcCtx: svcCtx,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *GetAppConfigLogic) GetAppConfig() (resp *types.GetAppConfigResp, err error) {
|
||||||
|
const defaultRetentionDays int64 = 30
|
||||||
|
retentionDays := defaultRetentionDays
|
||||||
|
|
||||||
|
retentionConfig, findErr := l.svcCtx.QueryCleanupConfigModel.FindOneByConfigKey(l.ctx, "retention_days")
|
||||||
|
if findErr != nil {
|
||||||
|
if findErr != model.ErrNotFound {
|
||||||
|
l.Errorf("获取 APP 配置 retention_days 失败: %+v", findErr)
|
||||||
|
}
|
||||||
|
} else if retentionConfig.Status == 1 {
|
||||||
|
parsedDays, parseErr := strconv.ParseInt(retentionConfig.ConfigValue, 10, 64)
|
||||||
|
if parseErr != nil || parsedDays <= 0 {
|
||||||
|
l.Errorf("解析 APP 配置 retention_days 失败, value=%s, err=%+v", retentionConfig.ConfigValue, parseErr)
|
||||||
|
} else {
|
||||||
|
retentionDays = parsedDays
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return &types.GetAppConfigResp{
|
||||||
|
Query: types.AppQueryConfig{
|
||||||
|
RetentionDays: retentionDays,
|
||||||
|
},
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
@@ -1,14 +1,15 @@
|
|||||||
package pay
|
package pay
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
|
||||||
"database/sql"
|
|
||||||
"net/http"
|
|
||||||
"strings"
|
|
||||||
"time"
|
|
||||||
"bdrp-server/app/main/api/internal/svc"
|
"bdrp-server/app/main/api/internal/svc"
|
||||||
"bdrp-server/app/main/model"
|
"bdrp-server/app/main/model"
|
||||||
"bdrp-server/common/globalkey"
|
"bdrp-server/common/globalkey"
|
||||||
|
"context"
|
||||||
|
"database/sql"
|
||||||
|
"math"
|
||||||
|
"net/http"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/Masterminds/squirrel"
|
"github.com/Masterminds/squirrel"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
@@ -17,10 +18,15 @@ import (
|
|||||||
"github.com/zeromicro/go-zero/core/stores/sqlx"
|
"github.com/zeromicro/go-zero/core/stores/sqlx"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func roundMoney(v float64) float64 {
|
||||||
|
return math.Round(v*100) / 100
|
||||||
|
}
|
||||||
|
|
||||||
// HandleCommissionAndWalletDeduction 处理退款后的佣金状态更新和钱包金额扣除
|
// HandleCommissionAndWalletDeduction 处理退款后的佣金状态更新和钱包金额扣除
|
||||||
// refundAmount 为本次实际退款金额(单位:元),从代理侧总共需要承担的金额
|
// refundAmount 为本次实际退款金额(单位:元),从代理侧总共需要承担的金额
|
||||||
// 该函数会优先冲减当前订单相关的佣金(基于 RefundedAmount),不足部分再从钱包余额/冻结余额中扣除
|
// 该函数会优先冲减当前订单相关的佣金(基于 RefundedAmount),不足部分再从钱包余额/冻结余额中扣除
|
||||||
func HandleCommissionAndWalletDeduction(ctx context.Context, svcCtx *svc.ServiceContext, session sqlx.Session, order *model.Order, refundAmount float64) error {
|
func HandleCommissionAndWalletDeduction(ctx context.Context, svcCtx *svc.ServiceContext, session sqlx.Session, order *model.Order, refundAmount float64) error {
|
||||||
|
refundAmount = roundMoney(refundAmount)
|
||||||
if refundAmount <= 0 {
|
if refundAmount <= 0 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -52,7 +58,7 @@ func HandleCommissionAndWalletDeduction(ctx context.Context, svcCtx *svc.Service
|
|||||||
|
|
||||||
// 1. 先在佣金记录上做冲减:增加 RefundedAmount,必要时将状态置为已退款
|
// 1. 先在佣金记录上做冲减:增加 RefundedAmount,必要时将状态置为已退款
|
||||||
for _, commission := range commissions {
|
for _, commission := range commissions {
|
||||||
available := commission.Amount - commission.RefundedAmount
|
available := roundMoney(commission.Amount - commission.RefundedAmount)
|
||||||
if available <= 0 {
|
if available <= 0 {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@@ -66,11 +72,12 @@ func HandleCommissionAndWalletDeduction(ctx context.Context, svcCtx *svc.Service
|
|||||||
if currentRefund > remainRefundAmount {
|
if currentRefund > remainRefundAmount {
|
||||||
currentRefund = remainRefundAmount
|
currentRefund = remainRefundAmount
|
||||||
}
|
}
|
||||||
|
currentRefund = roundMoney(currentRefund)
|
||||||
|
|
||||||
// 更新佣金的已退款金额
|
// 更新佣金的已退款金额
|
||||||
commission.RefundedAmount += currentRefund
|
commission.RefundedAmount = roundMoney(commission.RefundedAmount + currentRefund)
|
||||||
// 如果这条佣金已经被完全冲减,则标记为已退款
|
// 如果这条佣金已经被完全冲减,则标记为已退款
|
||||||
if commission.RefundedAmount >= commission.Amount {
|
if commission.RefundedAmount >= roundMoney(commission.Amount) {
|
||||||
commission.Status = 2
|
commission.Status = 2
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -92,9 +99,9 @@ func HandleCommissionAndWalletDeduction(ctx context.Context, svcCtx *svc.Service
|
|||||||
wa = &walletAdjust{agentId: commission.AgentId}
|
wa = &walletAdjust{agentId: commission.AgentId}
|
||||||
walletAdjustMap[commission.AgentId] = wa
|
walletAdjustMap[commission.AgentId] = wa
|
||||||
}
|
}
|
||||||
wa.amount += currentRefund
|
wa.amount = roundMoney(wa.amount + currentRefund)
|
||||||
|
|
||||||
remainRefundAmount -= currentRefund
|
remainRefundAmount = roundMoney(remainRefundAmount - currentRefund)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2. 再按代理维度,从钱包(冻结余额/可用余额)中扣除对应金额
|
// 2. 再按代理维度,从钱包(冻结余额/可用余额)中扣除对应金额
|
||||||
@@ -115,19 +122,19 @@ func HandleCommissionAndWalletDeduction(ctx context.Context, svcCtx *svc.Service
|
|||||||
frozenBalanceBefore := wallet.FrozenBalance
|
frozenBalanceBefore := wallet.FrozenBalance
|
||||||
|
|
||||||
// 优先从冻结余额中扣除(与原先“冻结佣金优先使用冻结余额”的设计一致)
|
// 优先从冻结余额中扣除(与原先“冻结佣金优先使用冻结余额”的设计一致)
|
||||||
deduct := wa.amount
|
deduct := roundMoney(wa.amount)
|
||||||
if wallet.FrozenBalance >= deduct {
|
if wallet.FrozenBalance >= deduct {
|
||||||
wallet.FrozenBalance -= deduct
|
wallet.FrozenBalance = roundMoney(wallet.FrozenBalance - deduct)
|
||||||
} else {
|
} else {
|
||||||
remaining := deduct - wallet.FrozenBalance
|
remaining := roundMoney(deduct - wallet.FrozenBalance)
|
||||||
wallet.FrozenBalance = 0
|
wallet.FrozenBalance = 0
|
||||||
// 可用余额可以为负数,由业务承担风险
|
// 可用余额可以为负数,由业务承担风险
|
||||||
wallet.Balance -= remaining
|
wallet.Balance = roundMoney(wallet.Balance - remaining)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 变动后余额和冻结余额
|
// 变动后余额和冻结余额
|
||||||
balanceAfter := wallet.Balance
|
balanceAfter := roundMoney(wallet.Balance)
|
||||||
frozenBalanceAfter := wallet.FrozenBalance
|
frozenBalanceAfter := roundMoney(wallet.FrozenBalance)
|
||||||
// 更新钱包
|
// 更新钱包
|
||||||
var updateWalletErr error
|
var updateWalletErr error
|
||||||
if session != nil {
|
if session != nil {
|
||||||
@@ -145,7 +152,7 @@ func HandleCommissionAndWalletDeduction(ctx context.Context, svcCtx *svc.Service
|
|||||||
session,
|
session,
|
||||||
wa.agentId,
|
wa.agentId,
|
||||||
model.WalletTransactionTypeRefund,
|
model.WalletTransactionTypeRefund,
|
||||||
-wa.amount*-1, // 钱包流水金额为负数
|
roundMoney(-wa.amount*-1), // 钱包流水金额为负数
|
||||||
balanceBefore,
|
balanceBefore,
|
||||||
balanceAfter,
|
balanceAfter,
|
||||||
frozenBalanceBefore,
|
frozenBalanceBefore,
|
||||||
@@ -348,7 +355,7 @@ func (l *WechatPayRefundCallbackLogic) WechatPayRefundCallback(w http.ResponseWr
|
|||||||
var refundAmountYuan float64
|
var refundAmountYuan float64
|
||||||
if notification.Amount != nil && notification.Amount.Refund != nil {
|
if notification.Amount != nil && notification.Amount.Refund != nil {
|
||||||
// 微信退款金额单位为分,这里转换为元
|
// 微信退款金额单位为分,这里转换为元
|
||||||
refundAmountYuan = float64(*notification.Amount.Refund) / 100.0
|
refundAmountYuan = roundMoney(float64(*notification.Amount.Refund) / 100.0)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 4. 根据订单号前缀处理不同类型的订单
|
// 4. 根据订单号前缀处理不同类型的订单
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
package service
|
package service
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
|
||||||
"crypto/rand"
|
|
||||||
"bdrp-server/app/main/api/internal/config"
|
"bdrp-server/app/main/api/internal/config"
|
||||||
"bdrp-server/app/main/model"
|
"bdrp-server/app/main/model"
|
||||||
"bdrp-server/pkg/lzkit/lzUtils"
|
"bdrp-server/pkg/lzkit/lzUtils"
|
||||||
|
"context"
|
||||||
|
"crypto/rand"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
@@ -217,12 +217,19 @@ func (a *AliPayService) AliTransfer(
|
|||||||
|
|
||||||
// 构造转账请求
|
// 构造转账请求
|
||||||
req := alipay.FundTransUniTransfer{
|
req := alipay.FundTransUniTransfer{
|
||||||
OutBizNo: outBizNo,
|
OutBizNo: outBizNo,
|
||||||
TransAmount: lzUtils.ToAlipayAmount(amount), // 金额格式转换
|
TransAmount: lzUtils.ToAlipayAmount(amount), // 金额格式转换
|
||||||
ProductCode: "TRANS_ACCOUNT_NO_PWD", // 单笔无密转账到支付宝账户
|
ProductCode: "TRANS_ACCOUNT_NO_PWD", // 单笔无密转账到支付宝账户
|
||||||
BizScene: "DIRECT_TRANSFER", // 单笔转账
|
BizScene: "DIRECT_TRANSFER", // 单笔转账
|
||||||
OrderTitle: "账户提现", // 转账标题
|
OrderTitle: "账户提现", // 转账标题
|
||||||
Remark: remark,
|
Remark: remark,
|
||||||
|
TransferSceneName: "业务结算",
|
||||||
|
TransferSceneReportInfo: []*alipay.TransferSceneReportInfo{
|
||||||
|
{
|
||||||
|
InfoType: "结算款项名称",
|
||||||
|
InfoContent: "向代理商转账支付代理费用",
|
||||||
|
},
|
||||||
|
},
|
||||||
PayeeInfo: &alipay.PayeeInfo{
|
PayeeInfo: &alipay.PayeeInfo{
|
||||||
Identity: payeeAccount,
|
Identity: payeeAccount,
|
||||||
IdentityType: "ALIPAY_LOGON_ID", // 根据账户类型选择:
|
IdentityType: "ALIPAY_LOGON_ID", // 根据账户类型选择:
|
||||||
|
|||||||
@@ -1317,6 +1317,10 @@ type AgentWithdrawalListItem struct {
|
|||||||
PayeeName string `json:"payee_name"` // 收款人姓名
|
PayeeName string `json:"payee_name"` // 收款人姓名
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type AppQueryConfig struct {
|
||||||
|
RetentionDays int64 `json:"retention_days"` // 查询结果保留天数
|
||||||
|
}
|
||||||
|
|
||||||
type AuthorizationDocumentInfo struct {
|
type AuthorizationDocumentInfo struct {
|
||||||
DocumentId int64 `json:"documentId"` // 授权书ID
|
DocumentId int64 `json:"documentId"` // 授权书ID
|
||||||
UserId int64 `json:"userId"` // 用户ID
|
UserId int64 `json:"userId"` // 用户ID
|
||||||
@@ -1504,6 +1508,10 @@ type GetAgentSubordinateListResp struct {
|
|||||||
List []AgentSubordinateList `json:"list"` // 查询列表
|
List []AgentSubordinateList `json:"list"` // 查询列表
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type GetAppConfigResp struct {
|
||||||
|
Query AppQueryConfig `json:"query"` // 查询相关配置
|
||||||
|
}
|
||||||
|
|
||||||
type GetAuthorizationDocumentByOrderReq struct {
|
type GetAuthorizationDocumentByOrderReq struct {
|
||||||
OrderId int64 `json:"orderId" validate:"required"` // 订单ID
|
OrderId int64 `json:"orderId" validate:"required"` // 订单ID
|
||||||
}
|
}
|
||||||
|
|||||||
4
go.mod
4
go.mod
@@ -25,7 +25,7 @@ require (
|
|||||||
github.com/samber/lo v1.50.0
|
github.com/samber/lo v1.50.0
|
||||||
github.com/shopspring/decimal v1.4.0
|
github.com/shopspring/decimal v1.4.0
|
||||||
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e
|
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e
|
||||||
github.com/smartwalle/alipay/v3 v3.2.23
|
github.com/smartwalle/alipay/v3 v3.2.29-0.20251230233706-e15a4853bc1c
|
||||||
github.com/sony/sonyflake v1.2.0
|
github.com/sony/sonyflake v1.2.0
|
||||||
github.com/stretchr/testify v1.11.1
|
github.com/stretchr/testify v1.11.1
|
||||||
github.com/tidwall/gjson v1.18.0
|
github.com/tidwall/gjson v1.18.0
|
||||||
@@ -81,7 +81,7 @@ require (
|
|||||||
github.com/prometheus/procfs v0.15.1 // indirect
|
github.com/prometheus/procfs v0.15.1 // indirect
|
||||||
github.com/robfig/cron/v3 v3.0.1 // indirect
|
github.com/robfig/cron/v3 v3.0.1 // indirect
|
||||||
github.com/smartwalle/ncrypto v1.0.4 // indirect
|
github.com/smartwalle/ncrypto v1.0.4 // indirect
|
||||||
github.com/smartwalle/ngx v1.0.9 // indirect
|
github.com/smartwalle/ngx v1.0.12 // indirect
|
||||||
github.com/smartwalle/nsign v1.0.9 // indirect
|
github.com/smartwalle/nsign v1.0.9 // indirect
|
||||||
github.com/spaolacci/murmur3 v1.1.0 // indirect
|
github.com/spaolacci/murmur3 v1.1.0 // indirect
|
||||||
github.com/spf13/cast v1.7.0 // indirect
|
github.com/spf13/cast v1.7.0 // indirect
|
||||||
|
|||||||
8
go.sum
8
go.sum
@@ -237,12 +237,12 @@ github.com/shopspring/decimal v1.4.0 h1:bxl37RwXBklmTi0C79JfXCEBD1cqqHt0bbgBAGFp
|
|||||||
github.com/shopspring/decimal v1.4.0/go.mod h1:gawqmDU56v4yIKSwfBSFip1HdCCXN8/+DMd9qYNcwME=
|
github.com/shopspring/decimal v1.4.0/go.mod h1:gawqmDU56v4yIKSwfBSFip1HdCCXN8/+DMd9qYNcwME=
|
||||||
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e h1:MRM5ITcdelLK2j1vwZ3Je0FKVCfqOLp5zO6trqMLYs0=
|
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e h1:MRM5ITcdelLK2j1vwZ3Je0FKVCfqOLp5zO6trqMLYs0=
|
||||||
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e/go.mod h1:XV66xRDqSt+GTGFMVlhk3ULuV0y9ZmzeVGR4mloJI3M=
|
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e/go.mod h1:XV66xRDqSt+GTGFMVlhk3ULuV0y9ZmzeVGR4mloJI3M=
|
||||||
github.com/smartwalle/alipay/v3 v3.2.23 h1:i1VwJeu70EmwpsXXz6GZZnMAtRx5MTfn2dPoql/L3zE=
|
github.com/smartwalle/alipay/v3 v3.2.29-0.20251230233706-e15a4853bc1c h1:o48e92wOA4wuoWHtugNBU2wizp9ui4skQNcpqxcvgsM=
|
||||||
github.com/smartwalle/alipay/v3 v3.2.23/go.mod h1:lVqFiupPf8YsAXaq5JXcwqnOUC2MCF+2/5vub+RlagE=
|
github.com/smartwalle/alipay/v3 v3.2.29-0.20251230233706-e15a4853bc1c/go.mod h1:dwPyjY5y17qUsDrsVYCQqmDBtQ/qpvY8JmQMvuJYGLQ=
|
||||||
github.com/smartwalle/ncrypto v1.0.4 h1:P2rqQxDepJwgeO5ShoC+wGcK2wNJDmcdBOWAksuIgx8=
|
github.com/smartwalle/ncrypto v1.0.4 h1:P2rqQxDepJwgeO5ShoC+wGcK2wNJDmcdBOWAksuIgx8=
|
||||||
github.com/smartwalle/ncrypto v1.0.4/go.mod h1:Dwlp6sfeNaPMnOxMNayMTacvC5JGEVln3CVdiVDgbBk=
|
github.com/smartwalle/ncrypto v1.0.4/go.mod h1:Dwlp6sfeNaPMnOxMNayMTacvC5JGEVln3CVdiVDgbBk=
|
||||||
github.com/smartwalle/ngx v1.0.9 h1:pUXDvWRZJIHVrCKA1uZ15YwNti+5P4GuJGbpJ4WvpMw=
|
github.com/smartwalle/ngx v1.0.12 h1:jcoCyu/0HtQ1y/gbiSLzqOUZcHnVLlKOmm0awRF7Mcg=
|
||||||
github.com/smartwalle/ngx v1.0.9/go.mod h1:mx/nz2Pk5j+RBs7t6u6k22MPiBG/8CtOMpCnALIG8Y0=
|
github.com/smartwalle/ngx v1.0.12/go.mod h1:mx/nz2Pk5j+RBs7t6u6k22MPiBG/8CtOMpCnALIG8Y0=
|
||||||
github.com/smartwalle/nsign v1.0.9 h1:8poAgG7zBd8HkZy9RQDwasC6XZvJpDGQWSjzL2FZL6E=
|
github.com/smartwalle/nsign v1.0.9 h1:8poAgG7zBd8HkZy9RQDwasC6XZvJpDGQWSjzL2FZL6E=
|
||||||
github.com/smartwalle/nsign v1.0.9/go.mod h1:eY6I4CJlyNdVMP+t6z1H6Jpd4m5/V+8xi44ufSTxXgc=
|
github.com/smartwalle/nsign v1.0.9/go.mod h1:eY6I4CJlyNdVMP+t6z1H6Jpd4m5/V+8xi44ufSTxXgc=
|
||||||
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
|
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
|
||||||
|
|||||||
Reference in New Issue
Block a user