feat(admin+api): 列表页子路由重构、结算历史与充值截图清理
赛事/代理管理从表格展开改为子路由详情页;结算页增加预览弹窗与历史记录;媒体库支持截图存储统计与自动/手动清理;Player 端充值截图压缩为 WebP 300KB。
This commit is contained in:
@@ -388,6 +388,83 @@ export class SettlementService {
|
||||
};
|
||||
}
|
||||
|
||||
async getActivePreview(
|
||||
matchId: bigint,
|
||||
opts?: { page?: number; pageSize?: number },
|
||||
) {
|
||||
const batch = await this.prisma.settlementBatch.findFirst({
|
||||
where: { matchId, status: 'PREVIEW' },
|
||||
orderBy: { createdAt: 'desc' },
|
||||
});
|
||||
if (!batch) return null;
|
||||
|
||||
const existingScore = await this.prisma.matchScore.findUnique({
|
||||
where: { matchId },
|
||||
});
|
||||
const computation = await this.computePreviewComputation(matchId, {
|
||||
htHome: batch.htHomeScore ?? 0,
|
||||
htAway: batch.htAwayScore ?? 0,
|
||||
ftHome: batch.ftHomeScore ?? 0,
|
||||
ftAway: batch.ftAwayScore ?? 0,
|
||||
homeCorners: batch.homeCorners ?? null,
|
||||
awayCorners: batch.awayCorners ?? null,
|
||||
homeYellowCards: batch.homeYellowCards ?? null,
|
||||
awayYellowCards: batch.awayYellowCards ?? null,
|
||||
homeRedCards: batch.homeRedCards ?? null,
|
||||
awayRedCards: batch.awayRedCards ?? null,
|
||||
homeCards: batch.homeCards ?? null,
|
||||
awayCards: batch.awayCards ?? null,
|
||||
winnerTeamId: existingScore?.winnerTeamId ?? null,
|
||||
});
|
||||
|
||||
return this.buildPreviewResponse(computation, batch, opts);
|
||||
}
|
||||
|
||||
async getMatchSettlementHistory(matchId: bigint) {
|
||||
const batches = await this.prisma.settlementBatch.findMany({
|
||||
where: { matchId, status: 'CONFIRMED' },
|
||||
orderBy: { confirmedAt: 'desc' },
|
||||
});
|
||||
|
||||
const operatorIds = batches
|
||||
.map((b) => b.operatorId)
|
||||
.filter((id): id is bigint => id !== null);
|
||||
|
||||
const operators =
|
||||
operatorIds.length > 0
|
||||
? await this.prisma.user.findMany({
|
||||
where: { id: { in: operatorIds } },
|
||||
select: { id: true, username: true },
|
||||
})
|
||||
: [];
|
||||
|
||||
const operatorMap = new Map(operators.map((o) => [o.id.toString(), o.username]));
|
||||
|
||||
return batches.map((b) => ({
|
||||
id: b.id.toString(),
|
||||
batchNo: b.batchNo,
|
||||
htHomeScore: b.htHomeScore,
|
||||
htAwayScore: b.htAwayScore,
|
||||
ftHomeScore: b.ftHomeScore,
|
||||
ftAwayScore: b.ftAwayScore,
|
||||
homeCorners: b.homeCorners,
|
||||
awayCorners: b.awayCorners,
|
||||
homeYellowCards: b.homeYellowCards,
|
||||
awayYellowCards: b.awayYellowCards,
|
||||
homeRedCards: b.homeRedCards,
|
||||
awayRedCards: b.awayRedCards,
|
||||
homeCards: b.homeCards,
|
||||
awayCards: b.awayCards,
|
||||
totalBets: b.totalBets,
|
||||
totalPayout: b.totalPayout.toString(),
|
||||
totalRefund: b.totalRefund.toString(),
|
||||
confirmedAt: b.confirmedAt?.toISOString() ?? null,
|
||||
isResettle: b.isResettle,
|
||||
reason: b.reason,
|
||||
operatorUsername: b.operatorId ? operatorMap.get(b.operatorId.toString()) ?? '—' : '—',
|
||||
}));
|
||||
}
|
||||
|
||||
private buildPreviewResponse(
|
||||
computation: {
|
||||
scoreInput: ScoreInput;
|
||||
|
||||
Reference in New Issue
Block a user