From d622cd0187d6688afe375487c8e0fbc5fcc408af Mon Sep 17 00:00:00 2001 From: yyg-max <175597134+yyg-max@users.noreply.github.com> Date: Sun, 15 Mar 2026 15:13:58 +0800 Subject: [PATCH 1/2] feat: leaderboard hide disabled users --- internal/apps/leaderboard/logic.go | 6 +++--- internal/apps/leaderboard/utils.go | 2 +- internal/model/users.go | 6 +++--- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/internal/apps/leaderboard/logic.go b/internal/apps/leaderboard/logic.go index ba0a155c..ba292a82 100644 --- a/internal/apps/leaderboard/logic.go +++ b/internal/apps/leaderboard/logic.go @@ -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 } @@ -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 } diff --git a/internal/apps/leaderboard/utils.go b/internal/apps/leaderboard/utils.go index 0e8ff65b..541fb34e 100644 --- a/internal/apps/leaderboard/utils.go +++ b/internal/apps/leaderboard/utils.go @@ -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 { diff --git a/internal/model/users.go b/internal/model/users.go index 14578316..f38b8c11 100644 --- a/internal/model/users.go +++ b/internal/model/users.go @@ -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"` @@ -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"` From 0fba4cafb50f10ee5d9be8b32f71c1903517dc25 Mon Sep 17 00:00:00 2001 From: yyg-max <175597134+yyg-max@users.noreply.github.com> Date: Tue, 17 Mar 2026 17:05:35 +0800 Subject: [PATCH 2/2] feat: Distribute and transfer to join the limit --- internal/apps/payment/routers.go | 45 ++++++++++++++++++-------------- internal/service/payment.go | 2 +- 2 files changed, 26 insertions(+), 21 deletions(-) diff --git a/internal/apps/payment/routers.go b/internal/apps/payment/routers.go index 71a23a6c..c66d2ce9 100644 --- a/internal/apps/payment/routers.go +++ b/internal/apps/payment/routers.go @@ -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() @@ -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, @@ -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 } diff --git a/internal/service/payment.go b/internal/service/payment.go index 57e934c1..7606b9ba 100644 --- a/internal/service/payment.go +++ b/internal/service/payment.go @@ -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)").