fix: use lucky gift stats for admin summary

This commit is contained in:
zhx 2026-06-03 00:05:38 +08:00
parent 679d068a82
commit dc28441e1b
2 changed files with 46 additions and 12 deletions

View File

@ -663,6 +663,9 @@ type luckyDrawPoolStatDelta struct {
BaseRewardCoins int64
RoomAtmosphereRewardCoins int64
ActivitySubsidyCoins int64
PendingDraws int64
GrantedDraws int64
FailedDraws int64
UserIDs map[int64]struct{}
RoomIDs map[string]struct{}
}
@ -713,14 +716,17 @@ func (r *Repository) upsertLuckyDrawPoolStatsSnapshotDelta(ctx context.Context,
unique_users = unique_users + VALUES(unique_users),
unique_rooms = unique_rooms + VALUES(unique_rooms),
total_spent_coins = total_spent_coins + VALUES(total_spent_coins),
total_reward_coins = total_reward_coins + VALUES(total_reward_coins),
base_reward_coins = base_reward_coins + VALUES(base_reward_coins),
room_atmosphere_reward_coins = room_atmosphere_reward_coins + VALUES(room_atmosphere_reward_coins),
activity_subsidy_coins = activity_subsidy_coins + VALUES(activity_subsidy_coins),
updated_at_ms = VALUES(updated_at_ms)`,
total_reward_coins = total_reward_coins + VALUES(total_reward_coins),
base_reward_coins = base_reward_coins + VALUES(base_reward_coins),
room_atmosphere_reward_coins = room_atmosphere_reward_coins + VALUES(room_atmosphere_reward_coins),
activity_subsidy_coins = activity_subsidy_coins + VALUES(activity_subsidy_coins),
pending_draws = pending_draws + VALUES(pending_draws),
granted_draws = granted_draws + VALUES(granted_draws),
failed_draws = failed_draws + VALUES(failed_draws),
updated_at_ms = VALUES(updated_at_ms)`,
key.AppCode, key.PoolID, key.GiftID, delta.TotalDraws, uniqueUsers, uniqueRooms, delta.TotalSpentCoins,
delta.TotalRewardCoins, delta.BaseRewardCoins, delta.RoomAtmosphereRewardCoins, delta.ActivitySubsidyCoins,
int64(0), int64(0), int64(0), nowMS, nowMS,
delta.PendingDraws, delta.GrantedDraws, delta.FailedDraws, nowMS, nowMS,
)
return err
}
@ -742,6 +748,7 @@ type luckyDrawStatsRecord struct {
BaseRewardCoins int64
RoomAtmosphereRewardCoins int64
ActivitySubsidyCoins int64
RewardStatus string
CreatedAtMS int64
}
@ -775,7 +782,8 @@ func (r *Repository) RefreshLuckyGiftAdminStatsSnapshots(ctx context.Context, no
rows, err := tx.QueryContext(ctx, `
SELECT app_code, draw_id, pool_id, gift_id, user_id, room_id, coin_spent,
total_reward_coins, base_reward_coins, room_atmosphere_reward_coins, activity_subsidy_coins,
effective_reward_coins, base_reward_coins, room_atmosphere_reward_coins, activity_subsidy_coins,
reward_status,
created_at_ms
FROM lucky_draw_records FORCE INDEX (idx_lucky_draw_created)
WHERE app_code = ?
@ -791,7 +799,7 @@ func (r *Repository) RefreshLuckyGiftAdminStatsSnapshots(ctx context.Context, no
var record luckyDrawStatsRecord
if err := rows.Scan(&record.AppCode, &record.DrawID, &record.PoolID, &record.GiftID, &record.UserID, &record.RoomID,
&record.TotalSpentCoins, &record.TotalRewardCoins, &record.BaseRewardCoins,
&record.RoomAtmosphereRewardCoins, &record.ActivitySubsidyCoins, &record.CreatedAtMS); err != nil {
&record.RoomAtmosphereRewardCoins, &record.ActivitySubsidyCoins, &record.RewardStatus, &record.CreatedAtMS); err != nil {
return 0, err
}
records = append(records, record)
@ -824,6 +832,14 @@ func (r *Repository) RefreshLuckyGiftAdminStatsSnapshots(ctx context.Context, no
delta.BaseRewardCoins += record.BaseRewardCoins
delta.RoomAtmosphereRewardCoins += record.RoomAtmosphereRewardCoins
delta.ActivitySubsidyCoins += record.ActivitySubsidyCoins
switch record.RewardStatus {
case domain.StatusPending:
delta.PendingDraws++
case domain.StatusGranted:
delta.GrantedDraws++
case domain.StatusFailed:
delta.FailedDraws++
}
if record.UserID > 0 {
delta.UserIDs[record.UserID] = struct{}{}
}
@ -1818,7 +1834,8 @@ func (r *Repository) getLuckyGiftDrawSummaryFromStats(ctx context.Context, query
summary.PoolID = query.PoolID
err := r.db.QueryRowContext(ctx, `
SELECT total_draws, unique_users, unique_rooms, total_spent_coins, total_reward_coins,
base_reward_coins, room_atmosphere_reward_coins, activity_subsidy_coins
base_reward_coins, room_atmosphere_reward_coins, activity_subsidy_coins,
pending_draws, granted_draws, failed_draws
FROM lucky_draw_pool_stats
WHERE app_code = ? AND pool_id = ? AND gift_id = ?`,
appcode.FromContext(ctx), query.PoolID, strings.TrimSpace(query.GiftID),
@ -1831,6 +1848,9 @@ func (r *Repository) getLuckyGiftDrawSummaryFromStats(ctx context.Context, query
&summary.BaseRewardCoins,
&summary.RoomAtmosphereRewardCoins,
&summary.ActivitySubsidyCoins,
&summary.PendingDraws,
&summary.GrantedDraws,
&summary.FailedDraws,
)
if errors.Is(err, sql.ErrNoRows) {
return summary, nil
@ -1838,9 +1858,6 @@ func (r *Repository) getLuckyGiftDrawSummaryFromStats(ctx context.Context, query
if err != nil {
return domain.DrawSummary{}, err
}
if err := r.loadLuckyGiftDrawStatusCounts(ctx, query, &summary); err != nil {
return domain.DrawSummary{}, err
}
if summary.TotalSpentCoins > 0 {
summary.ActualRTPPPM = summary.TotalRewardCoins * luckyPPMScale / summary.TotalSpentCoins
}

View File

@ -115,6 +115,7 @@ func TestRefreshLuckyGiftAdminStatsSnapshotsAdvancesCursorByBatch(t *testing.T)
t.Fatalf("first refresh should process one row, got %d", processed)
}
assertLuckyStatsTotal(t, repository, "", 1, 100, 300)
assertLuckyStatsStatus(t, repository, "", 0, 1, 0)
assertLuckyStatsCursor(t, repository, 100, "draw_001")
processed, err = repository.RefreshLuckyGiftAdminStatsSnapshots(ctx, 400, 10)
@ -125,6 +126,7 @@ func TestRefreshLuckyGiftAdminStatsSnapshotsAdvancesCursorByBatch(t *testing.T)
t.Fatalf("second refresh should process remaining row, got %d", processed)
}
assertLuckyStatsTotal(t, repository, "", 2, 250, 300)
assertLuckyStatsStatus(t, repository, "", 1, 1, 0)
assertLuckyStatsCursor(t, repository, 200, "draw_002")
}
@ -166,6 +168,21 @@ func assertLuckyStatsTotal(t *testing.T, repository *Repository, giftID string,
}
}
func assertLuckyStatsStatus(t *testing.T, repository *Repository, giftID string, wantPending int64, wantGranted int64, wantFailed int64) {
t.Helper()
var pending, granted, failed int64
if err := repository.db.QueryRowContext(context.Background(), `
SELECT pending_draws, granted_draws, failed_draws
FROM lucky_draw_pool_stats
WHERE app_code = 'lalu' AND pool_id = 'lucky' AND gift_id = ?`, giftID,
).Scan(&pending, &granted, &failed); err != nil {
t.Fatalf("read stats status: %v", err)
}
if pending != wantPending || granted != wantGranted || failed != wantFailed {
t.Fatalf("stats status mismatch: pending=%d granted=%d failed=%d want pending=%d granted=%d failed=%d", pending, granted, failed, wantPending, wantGranted, wantFailed)
}
}
func assertLuckyStatsCursor(t *testing.T, repository *Repository, wantCreatedAtMS int64, wantDrawID string) {
t.Helper()
var createdAtMS int64