@@ -0,0 +1,156 @@
|
||||
package activityser
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strconv"
|
||||
|
||||
"91porn-server/app/appg"
|
||||
"91porn-server/common/db"
|
||||
"91porn-server/common/log"
|
||||
"91porn-server/common/stderr"
|
||||
"91porn-server/models/v/txnmod"
|
||||
"91porn-server/models/v/usermod"
|
||||
"91porn-server/models/v/walletmod"
|
||||
)
|
||||
|
||||
// DeductType 扣款类型
|
||||
type DeductType int
|
||||
|
||||
const (
|
||||
DeductGold DeductType = 1 // 金币
|
||||
DeductIntegral DeductType = 2 // 积分
|
||||
DeductLotteryTimes DeductType = 3 // 抽奖免费次数
|
||||
)
|
||||
|
||||
// DeductReq 扣款请求
|
||||
type DeductReq struct {
|
||||
UserId string `json:"userId" binding:"required"`
|
||||
DeductType DeductType `json:"deductType" binding:"required"`
|
||||
Amount int64 `json:"amount" binding:"required"`
|
||||
ActivityId string `json:"activityId"`
|
||||
Remark string `json:"remark"`
|
||||
}
|
||||
|
||||
// Deduct 活动扣款
|
||||
func Deduct(ctx context.Context, req *DeductReq) (stderr.Code, error) {
|
||||
uid, err := strconv.ParseUint(req.UserId, 10, 64)
|
||||
if err != nil {
|
||||
return stderr.ErrParamError, fmt.Errorf("invalid userId: %s", req.UserId)
|
||||
}
|
||||
u, err := usermod.FindUserByUID(uid)
|
||||
if err != nil {
|
||||
return stderr.Failure, fmt.Errorf("查询用户异常: %w", err)
|
||||
}
|
||||
if u == nil {
|
||||
return stderr.ErrParamError, fmt.Errorf("用户不存在: %s", req.UserId)
|
||||
}
|
||||
|
||||
if req.Amount <= 0 {
|
||||
return stderr.ErrParamError, fmt.Errorf("扣款数量必须大于0")
|
||||
}
|
||||
|
||||
w, err := walletmod.GetWallet(uid)
|
||||
if err != nil {
|
||||
return stderr.Failure, fmt.Errorf("查询钱包异常: %w", err)
|
||||
}
|
||||
if w == nil {
|
||||
w = &walletmod.Wallet{}
|
||||
}
|
||||
|
||||
desc := req.Remark
|
||||
|
||||
switch req.DeductType {
|
||||
case DeductGold:
|
||||
if w.Amount < req.Amount {
|
||||
return stderr.InsufficientGold, fmt.Errorf("金币余额不足,当前%d,需要%d", w.Amount, req.Amount)
|
||||
}
|
||||
return deductGold(ctx, uid, u, req, desc)
|
||||
case DeductIntegral:
|
||||
if w.Integral < req.Amount {
|
||||
return stderr.InsufficientPoint, fmt.Errorf("积分余额不足,当前%d,需要%d", w.Integral, req.Amount)
|
||||
}
|
||||
return deductIntegral(ctx, uid, u, req, desc)
|
||||
case DeductLotteryTimes:
|
||||
if w.LotteryTimes < req.Amount {
|
||||
return stderr.InsufficientLotteryFreeTimes, fmt.Errorf("抽奖免费次数不足,当前%d,需要%d", w.LotteryTimes, req.Amount)
|
||||
}
|
||||
return deductLotteryTimes(ctx, uid, u, req, desc)
|
||||
default:
|
||||
return stderr.ErrParamError, fmt.Errorf("不支持的扣款类型: %d", req.DeductType)
|
||||
}
|
||||
}
|
||||
|
||||
func deductGold(ctx context.Context, uid uint64, u *usermod.User, req *DeductReq, desc string) (stderr.Code, error) {
|
||||
amount := req.Amount
|
||||
|
||||
err := appg.VideoDB.Trans(func(t *db.MongoTool) error {
|
||||
w, err := walletmod.DebitAmount(t, amount, uid)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
log.InfoX(ctx, "活动扣款-扣除金币", log.Any("uid", uid), log.Any("amount", amount), log.Any("activityId", req.ActivityId))
|
||||
return txnmod.InsertTransactionLog(t, &txnmod.TransactionLog{
|
||||
UID: uid,
|
||||
Amount: -amount,
|
||||
ActualAmount: float64(-amount),
|
||||
TranType: txnmod.ActivityDeductGold.Key(),
|
||||
TranTypeInt: int64(txnmod.ActivityDeductGold),
|
||||
Desc: fmt.Sprintf("%s-扣除%d金币", desc, amount),
|
||||
SysType: u.SysType,
|
||||
RealAmount: w.RealAmount(),
|
||||
})
|
||||
})
|
||||
if err != nil {
|
||||
return stderr.InsufficientGold, fmt.Errorf("金币余额不足")
|
||||
}
|
||||
return stderr.Success, nil
|
||||
}
|
||||
|
||||
func deductIntegral(ctx context.Context, uid uint64, u *usermod.User, req *DeductReq, desc string) (stderr.Code, error) {
|
||||
integral := req.Amount
|
||||
|
||||
err := appg.VideoDB.Trans(func(t *db.MongoTool) error {
|
||||
_, err := walletmod.DebitIntegral(t, integral, uid)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
log.InfoX(ctx, "活动扣款-扣除积分", log.Any("uid", uid), log.Any("integral", integral), log.Any("activityId", req.ActivityId))
|
||||
return txnmod.InsertTransactionLog(t, &txnmod.TransactionLog{
|
||||
UID: uid,
|
||||
Integral: -integral,
|
||||
TranType: txnmod.ActivityDeductIntegral.Key(),
|
||||
TranTypeInt: int64(txnmod.ActivityDeductIntegral),
|
||||
Desc: fmt.Sprintf("%s-扣除%d积分", desc, integral),
|
||||
SysType: u.SysType,
|
||||
})
|
||||
})
|
||||
if err != nil {
|
||||
return stderr.InsufficientPoint, fmt.Errorf("积分余额不足")
|
||||
}
|
||||
return stderr.Success, nil
|
||||
}
|
||||
|
||||
func deductLotteryTimes(ctx context.Context, uid uint64, u *usermod.User, req *DeductReq, desc string) (stderr.Code, error) {
|
||||
times := req.Amount
|
||||
|
||||
err := appg.VideoDB.Trans(func(t *db.MongoTool) error {
|
||||
_, err := walletmod.DebitLotteryTimes(t, times, uid)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
log.InfoX(ctx, "活动扣款-扣除抽奖免费次数", log.Any("uid", uid), log.Any("times", times), log.Any("activityId", req.ActivityId))
|
||||
return txnmod.InsertTransactionLog(t, &txnmod.TransactionLog{
|
||||
UID: uid,
|
||||
Amount: -times,
|
||||
TranType: txnmod.ActivityDeductLotteryTimes.Key(),
|
||||
TranTypeInt: int64(txnmod.ActivityDeductLotteryTimes),
|
||||
Desc: fmt.Sprintf("%s-扣除抽奖免费%d次", desc, times),
|
||||
SysType: u.SysType,
|
||||
})
|
||||
})
|
||||
if err != nil {
|
||||
return stderr.InsufficientLotteryFreeTimes, fmt.Errorf("抽奖免费次数不足")
|
||||
}
|
||||
return stderr.Success, nil
|
||||
}
|
||||
Reference in New Issue
Block a user