74 lines
2.3 KiB
Go
74 lines
2.3 KiB
Go
package invite
|
|
|
|
import (
|
|
"context"
|
|
"strings"
|
|
)
|
|
|
|
type inviteRankRow struct {
|
|
UserID int64
|
|
Nickname string
|
|
Avatar string
|
|
InviteCount int64
|
|
RewardGoldCoins int64
|
|
}
|
|
|
|
// GetRank 返回累计邀请排行榜。排行榜不按月重置。
|
|
func (s *InviteService) GetRank(ctx context.Context, user AuthUser, limit int) (*InviteRankResponse, error) {
|
|
limit = normalizeInviteRankLimit(limit)
|
|
rows := make([]inviteRankRow, 0, limit)
|
|
if err := s.repo.DB.WithContext(ctx).Raw(`
|
|
SELECT
|
|
invite_rank.user_id AS user_id,
|
|
COALESCE(NULLIF(user_info.user_nickname, ''), invite_code.account, '') AS nickname,
|
|
COALESCE(user_info.user_avatar, '') AS avatar,
|
|
invite_rank.invite_count AS invite_count,
|
|
COALESCE(reward_rank.reward_gold_coins, 0) AS reward_gold_coins
|
|
FROM (
|
|
SELECT inviter_user_id AS user_id, COUNT(1) AS invite_count
|
|
FROM invite_campaign_relation
|
|
WHERE sys_origin = ? AND eligible_status = ?
|
|
GROUP BY inviter_user_id
|
|
) invite_rank
|
|
LEFT JOIN (
|
|
SELECT target_user_id AS user_id, COALESCE(SUM(gold_amount), 0) AS reward_gold_coins
|
|
FROM invite_campaign_reward_log
|
|
WHERE sys_origin = ? AND status = ? AND target_user_id = inviter_user_id
|
|
GROUP BY target_user_id
|
|
) reward_rank ON reward_rank.user_id = invite_rank.user_id
|
|
LEFT JOIN user_base_info user_info ON user_info.id = invite_rank.user_id
|
|
LEFT JOIN invite_code_mapping invite_code ON invite_code.user_id = invite_rank.user_id
|
|
ORDER BY invite_rank.invite_count DESC, reward_gold_coins DESC, invite_rank.user_id ASC
|
|
LIMIT ?
|
|
`, user.SysOrigin, relationStatusEligible, user.SysOrigin, rewardLogStatusSuccess, limit).Scan(&rows).Error; err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
items := make([]InviteRankItem, 0, len(rows))
|
|
for index, row := range rows {
|
|
items = append(items, InviteRankItem{
|
|
Rank: index + 1,
|
|
UserID: row.UserID,
|
|
Nickname: strings.TrimSpace(row.Nickname),
|
|
Avatar: strings.TrimSpace(row.Avatar),
|
|
InviteCount: row.InviteCount,
|
|
RewardGoldCoins: row.RewardGoldCoins,
|
|
})
|
|
}
|
|
return &InviteRankResponse{
|
|
SysOrigin: user.SysOrigin,
|
|
Limit: limit,
|
|
Items: items,
|
|
}, nil
|
|
}
|
|
|
|
func normalizeInviteRankLimit(limit int) int {
|
|
if limit <= 0 {
|
|
return defaultInviteRankLimit
|
|
}
|
|
if limit > maxInviteRankLimit {
|
|
return maxInviteRankLimit
|
|
}
|
|
return limit
|
|
}
|