53 lines
2.5 KiB
Go
53 lines
2.5 KiB
Go
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
|
||
}
|