package mysql import ( "context" "time" "hyapp/pkg/appcode" "hyapp/pkg/xerr" "hyapp/services/wallet-service/internal/domain/ledger" ) // GetHostRevenueStats 的“钻石收益/送礼人数”只读主播周期钻石流水; // POINT 是可兑换资产,任务奖励、Agency 分成和提现退回都不能被误算成收礼钻石。 func (r *Repository) GetHostRevenueStats(ctx context.Context, query ledger.HostRevenueStatsQuery) (ledger.HostRevenueStats, error) { if r == nil || r.db == nil { return ledger.HostRevenueStats{}, xerr.New(xerr.Unavailable, "mysql repository is not configured") } var stats ledger.HostRevenueStats startCycle := time.UnixMilli(query.StartAtMS).UTC().Format("2006-01") endCycle := time.UnixMilli(query.EndAtMS - 1).UTC().Format("2006-01") // (app_code,user_id,cycle_key,created_at_ms) 索引先限定单主播和最多 13 个周期, // 再在已收敛的送礼流水上按时间求和/去重,不扫全表也不解析大 JSON 字段。 if err := r.db.QueryRowContext(ctx, ` SELECT COALESCE(SUM(diamond_delta), 0), COUNT(DISTINCT CASE WHEN sender_user_id > 0 THEN sender_user_id END) FROM host_period_diamond_entries FORCE INDEX (idx_host_period_diamond_entries_user_cycle) WHERE app_code = ? AND user_id = ? AND cycle_key BETWEEN ? AND ? AND created_at_ms >= ? AND created_at_ms < ?`, appcode.FromContext(ctx), query.HostUserID, startCycle, endCycle, query.StartAtMS, query.EndAtMS, ).Scan(&stats.DiamondEarnings, &stats.GiftSenders); err != nil { return ledger.HostRevenueStats{}, err } // “已兑换”保留现有 POINT 资产口径,但只计用户主动兑金币、转币商和平台提现首次冻结; // 审核扣 frozen 、驳回释放和其他 POINT 变动不重复计入。 if err := r.db.QueryRowContext(ctx, ` SELECT COALESCE(SUM(-e.available_delta), 0) FROM wallet_entries e FORCE INDEX (idx_wallet_entries_asset_user_time) INNER JOIN wallet_transactions t ON t.app_code = e.app_code AND t.transaction_id = e.transaction_id WHERE e.app_code = ? AND e.user_id = ? AND e.asset_type = ? AND e.created_at_ms >= ? AND e.created_at_ms < ? AND e.available_delta < 0 AND t.biz_type IN (?, ?, ?)`, appcode.FromContext(ctx), query.HostUserID, ledger.AssetPoint, query.StartAtMS, query.EndAtMS, bizTypePointExchangeToCoin, bizTypePointTransferToCoinSeller, bizTypeSalaryWithdrawalFreeze, ).Scan(&stats.DiamondExchanged); err != nil { return ledger.HostRevenueStats{}, err } return stats, nil }