feat(admin): 同步单赛事筛选与排序功能 (从 main 分支)

This commit is contained in:
2026-06-18 17:46:39 +08:00
parent b0dc56db1c
commit 5fbb1fd1f6
6 changed files with 197 additions and 4 deletions

View File

@@ -556,6 +556,8 @@ export class MatchesService {
locale?: string;
page?: number;
pageSize?: number;
hasBets?: string;
orderBy?: string;
},
) {
const where: Prisma.MatchWhereInput = {
@@ -574,6 +576,70 @@ export class MatchesService {
}
const page = Math.max(1, opts.page ?? 1);
const pageSize = Math.min(100, Math.max(1, opts.pageSize ?? 20));
if (opts.hasBets === 'true' || opts.orderBy === 'betCount' || opts.orderBy === 'totalStake') {
const allRows = await this.prisma.match.findMany({
where,
include: { homeTeam: true, awayTeam: true },
});
const locale = opts.locale ?? 'zh-CN';
const betStatsMap = await this.betStatsForMatches(allRows.map((m) => m.id));
const itemsWithStats = await Promise.all(
allRows.map(async (m) => {
const [homeTeamName, awayTeamName] = await Promise.all([
this.getTranslation('TEAM', m.homeTeamId, locale),
this.getTranslation('TEAM', m.awayTeamId, locale),
]);
const raw = betStatsMap.get(m.id.toString());
const betCount = raw?.betCount ?? 0;
const totalStake = raw?.totalStake ?? '0';
const pendingBets = raw?.pendingCount ?? 0;
return {
id: m.id.toString(),
status: m.status,
isOutright: m.isOutright,
isHot: m.isHot,
displayOrder: m.displayOrder,
startTime: m.startTime,
matchName: m.matchName,
homeTeamName,
awayTeamName,
homeTeam: { code: m.homeTeam.code },
awayTeam: { code: m.awayTeam.code },
betCount,
totalStake,
pendingBets,
};
}),
);
let filteredItems = itemsWithStats;
if (opts.hasBets === 'true') {
filteredItems = itemsWithStats.filter((item) => item.betCount > 0);
}
if (opts.orderBy === 'betCount') {
filteredItems.sort((a, b) => b.betCount - a.betCount);
} else if (opts.orderBy === 'totalStake') {
filteredItems.sort((a, b) => {
const stakeA = parseFloat(a.totalStake);
const stakeB = parseFloat(b.totalStake);
return stakeB - stakeA;
});
} else {
filteredItems.sort((a, b) => {
if (a.displayOrder !== b.displayOrder) {
return a.displayOrder - b.displayOrder;
}
return new Date(b.startTime).getTime() - new Date(a.startTime).getTime();
});
}
const total = filteredItems.length;
const paginatedItems = filteredItems.slice((page - 1) * pageSize, page * pageSize);
return { items: paginatedItems, total, page, pageSize };
}
const [total, rows] = await Promise.all([
this.prisma.match.count({ where }),
this.prisma.match.findMany({