package mysql import ( "context" "strings" "hyapp/pkg/appcode" roomservice "hyapp/services/room-service/internal/room/service" ) // ListRoomContributionRank 读取单房间用户周期贡献 TopN。 // 该查询只命中周期统计表索引,不扫描 command log、outbox 或 Room Cell 快照。 func (r *Repository) ListRoomContributionRank(ctx context.Context, query roomservice.RoomContributionRankQuery) (roomservice.RoomContributionRankPage, error) { app := appcode.Normalize(query.AppCode) if app == "" { app = appcode.FromContext(ctx) } roomID := strings.TrimSpace(query.RoomID) period := strings.TrimSpace(query.Period) limit := query.Limit if limit <= 0 { limit = 20 } var total int64 if err := r.db.QueryRowContext(ctx, `SELECT COUNT(*) FROM room_user_contribution_period_stats WHERE app_code = ? AND room_id = ? AND period = ? AND period_start_ms = ?`, app, roomID, period, query.PeriodStartMS, ).Scan(&total); err != nil { return roomservice.RoomContributionRankPage{}, err } rows, err := r.db.QueryContext(ctx, `SELECT user_id, gift_value, updated_at_ms FROM room_user_contribution_period_stats WHERE app_code = ? AND room_id = ? AND period = ? AND period_start_ms = ? ORDER BY gift_value DESC, last_gift_at_ms DESC, user_id ASC LIMIT ?`, app, roomID, period, query.PeriodStartMS, limit, ) if err != nil { return roomservice.RoomContributionRankPage{}, err } defer rows.Close() items := make([]roomservice.RoomContributionRankEntry, 0, limit) for rows.Next() { var item roomservice.RoomContributionRankEntry if err := rows.Scan(&item.UserID, &item.GiftValue, &item.UpdatedAtMS); err != nil { return roomservice.RoomContributionRankPage{}, err } item.Rank = int64(len(items)) + 1 item.Score = item.GiftValue items = append(items, item) } if err := rows.Err(); err != nil { return roomservice.RoomContributionRankPage{}, err } return roomservice.RoomContributionRankPage{ Items: items, Total: total, }, nil }