Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions internal/apps/leaderboard/logic.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ func getUserRank(ctx context.Context, userID uint64) (*UserRankResponse, error)

// 查询用户余额
var user model.User
if err := db.DB(ctx).Select("id, available_balance").Where("id = ?", userID).First(&user).Error; err != nil {
if err := db.DB(ctx).Select("id, available_balance").Where("id = ? AND is_active = ?", userID, true).First(&user).Error; err != nil {
return nil, err
}

Expand All @@ -77,8 +77,8 @@ func getUserRank(ctx context.Context, userID uint64) (*UserRankResponse, error)
// 即:余额更高,或余额相同但 id 更小
var rank int64
if err := db.DB(ctx).Model(&model.User{}).
Where("(available_balance > ?) OR (available_balance = ? AND id < ?)",
user.AvailableBalance, user.AvailableBalance, userID).
Where("is_active = ? AND ((available_balance > ?) OR (available_balance = ? AND id < ?))",
true, user.AvailableBalance, user.AvailableBalance, userID).
Count(&rank).Error; err != nil {
return nil, err
}
Expand Down
2 changes: 1 addition & 1 deletion internal/apps/leaderboard/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ func getCacheTTL(ctx context.Context) time.Duration {
func queryLeaderboard(ctx context.Context, req *ListRequest) ([]LeaderboardEntry, int64, error) {
offset := (req.Page - 1) * req.PageSize

baseQuery := db.DB(ctx).Model(&model.User{})
baseQuery := db.DB(ctx).Model(&model.User{}).Where("is_active = ?", true)

var total int64
if err := baseQuery.Count(&total).Error; err != nil {
Expand Down
45 changes: 25 additions & 20 deletions internal/apps/payment/routers.go
Original file line number Diff line number Diff line change
Expand Up @@ -381,12 +381,16 @@ func MerchantDistribute(c *gin.Context) {
return errors.New(CannotTransferToSelf)
}

// 获取商户支付配置(用于计算分发费率和分数)
// 获取商户支付配置
var merchantPayConfig model.UserPayConfig
if err := merchantPayConfig.GetByPayScore(tx, merchantUser.PayScore); err != nil {
return errors.New(PayConfigNotFound)
}

if err := service.CheckDailyLimit(tx, merchantUser.ID, req.Amount, merchantPayConfig.DailyLimit); err != nil {
return err
}

_, recipientAmount, distributePercent := service.CalculateFee(req.Amount, merchantPayConfig.DistributeRate)
merchantScore := req.Amount.Mul(merchantPayConfig.ScoreRate).Round(0).IntPart()

Expand Down Expand Up @@ -669,21 +673,20 @@ func Transfer(c *gin.Context) {
return err
}

var payer model.User
if err := tx.Clauses(clause.Locking{Strength: "UPDATE", Options: "NOWAIT"}).
Where("id = ?", currentUser.ID).
First(&payer).Error; err != nil {
// 获取转账人支付配置
var payerPayConfig model.UserPayConfig
if err := payerPayConfig.GetByPayScore(tx, currentUser.PayScore); err != nil {
return err
}

if payer.AvailableBalance.LessThan(req.Amount) {
return errors.New(common.InsufficientBalance)
if err := service.CheckDailyLimit(tx, currentUser.ID, req.Amount, payerPayConfig.DailyLimit); err != nil {
return err
}

// 创建转账订单
order := model.Order{
OrderName: "转账",
PayerUserID: payer.ID,
PayerUserID: currentUser.ID,
PayeeUserID: recipient.ID,
Amount: req.Amount,
Status: model.OrderStatusSuccess,
Expand All @@ -698,22 +701,24 @@ func Transfer(c *gin.Context) {
}

// 扣减付款人余额
if err := tx.Model(&model.User{}).
Where("id = ?", payer.ID).
UpdateColumns(map[string]interface{}{
"available_balance": gorm.Expr("available_balance - ?", req.Amount),
"total_transfer": gorm.Expr("total_transfer + ?", req.Amount),
}).Error; err != nil {
if err := service.UpdateBalance(tx, service.BalanceUpdateOptions{
UserID: currentUser.ID,
Amount: req.Amount,
Operation: service.BalanceDeduct,
TotalField: "total_transfer",
CheckBalance: true,
}); err != nil {
return err
}

// 增加收款人余额
if err := tx.Model(&model.User{}).
Where("id = ?", recipient.ID).
UpdateColumns(map[string]interface{}{
"available_balance": gorm.Expr("available_balance + ?", req.Amount),
"total_receive": gorm.Expr("total_receive + ?", req.Amount),
}).Error; err != nil {
if err := service.UpdateBalance(tx, service.BalanceUpdateOptions{
UserID: recipient.ID,
Amount: req.Amount,
Operation: service.BalanceAdd,
TotalField: "total_receive",
CheckBalance: false,
}); err != nil {
return err
}

Expand Down
6 changes: 3 additions & 3 deletions internal/model/users.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ type LeaderboardUser struct {
}

type User struct {
ID uint64 `json:"id" gorm:"primaryKey;index:idx_users_avail_bal_id,priority:2"`
ID uint64 `json:"id" gorm:"primaryKey;index:idx_users_active_bal_id,priority:3"`
Username string `json:"username" gorm:"size:64;uniqueIndex"`
Nickname string `json:"nickname" gorm:"size:100"`
AvatarUrl string `json:"avatar_url" gorm:"size:100"`
Expand All @@ -104,8 +104,8 @@ type User struct {
TotalTransfer decimal.Decimal `json:"total_transfer" gorm:"type:numeric(20,2);default:0"`
TotalCommunity decimal.Decimal `json:"total_community" gorm:"type:numeric(20,2);default:0"`
CommunityBalance decimal.Decimal `json:"community_balance" gorm:"type:numeric(20,2);default:0"`
AvailableBalance decimal.Decimal `json:"available_balance" gorm:"type:numeric(20,2);default:0;index:idx_users_avail_bal_id,priority:1"`
IsActive bool `json:"is_active" gorm:"default:true"`
AvailableBalance decimal.Decimal `json:"available_balance" gorm:"type:numeric(20,2);default:0;index:idx_users_active_bal_id,priority:2"`
IsActive bool `json:"is_active" gorm:"default:true;index:idx_users_active_bal_id,priority:1"`
IsAdmin bool `json:"is_admin" gorm:"default:false"`
LastLoginAt time.Time `json:"last_login_at" gorm:"index"`
CreatedAt time.Time `json:"created_at" gorm:"autoCreateTime;index"`
Expand Down
2 changes: 1 addition & 1 deletion internal/service/payment.go
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ func GetTodayUsedAmount(db *gorm.DB, userID uint64) (decimal.Decimal, error) {
Where("payer_user_id = ? AND status = ? AND type IN ? AND trade_time >= ? AND trade_time < ?",
userID,
model.OrderStatusSuccess,
[]model.OrderType{model.OrderTypePayment, model.OrderTypeOnline},
[]model.OrderType{model.OrderTypePayment, model.OrderTypeOnline, model.OrderTypeDistribute, model.OrderTypeTransfer},
todayStart,
todayEnd).
Select("COALESCE(SUM(amount), 0)").
Expand Down
Loading