feat(admin,api,player): settlement stats, team crests, MS fields and list bet summary
This commit is contained in:
@@ -68,6 +68,11 @@ export class OutrightService {
|
||||
market,
|
||||
openCount,
|
||||
);
|
||||
const [titleZh, titleEn, titleMs] = await Promise.all([
|
||||
this.getOutrightTitle(m.id, 'zh-CN'),
|
||||
this.getOutrightTitle(m.id, 'en-US'),
|
||||
this.getOutrightTitle(m.id, 'ms-MY'),
|
||||
]);
|
||||
return {
|
||||
id: m.id.toString(),
|
||||
leagueId: league.id.toString(),
|
||||
@@ -75,6 +80,9 @@ export class OutrightService {
|
||||
leagueZh,
|
||||
leagueEn,
|
||||
matchName: m.matchName ?? '',
|
||||
titleZh: titleZh || m.matchName || '',
|
||||
titleEn: titleEn || m.matchName || '',
|
||||
titleMs,
|
||||
status: m.status,
|
||||
selectionCount,
|
||||
canImportCanonical: leagueCode === WC2026_LEAGUE_CODE,
|
||||
@@ -154,6 +162,12 @@ export class OutrightService {
|
||||
),
|
||||
);
|
||||
|
||||
const [titleZh, titleEn, titleMs] = await Promise.all([
|
||||
this.getOutrightTitle(match.id, 'zh-CN'),
|
||||
this.getOutrightTitle(match.id, 'en-US'),
|
||||
this.getOutrightTitle(match.id, 'ms-MY'),
|
||||
]);
|
||||
|
||||
return {
|
||||
id: match.id.toString(),
|
||||
leagueId: match.leagueId.toString(),
|
||||
@@ -161,6 +175,9 @@ export class OutrightService {
|
||||
leagueZh,
|
||||
leagueEn,
|
||||
matchName: match.matchName ?? '',
|
||||
titleZh: titleZh || match.matchName || '',
|
||||
titleEn: titleEn || match.matchName || '',
|
||||
titleMs,
|
||||
status: match.status,
|
||||
marketId: fullMarket.id.toString(),
|
||||
marketStatus: fullMarket.status,
|
||||
@@ -177,6 +194,7 @@ export class OutrightService {
|
||||
leagueId: bigint;
|
||||
titleZh: string;
|
||||
titleEn: string;
|
||||
titleMs?: string;
|
||||
status?: string;
|
||||
isHot?: boolean;
|
||||
displayOrder?: number;
|
||||
@@ -189,13 +207,14 @@ export class OutrightService {
|
||||
|
||||
const placeholder = await this.ensurePlaceholderTeam();
|
||||
const status = data.status ?? 'PUBLISHED';
|
||||
const matchName = this.resolveOutrightMatchName(data);
|
||||
const match = await this.prisma.match.create({
|
||||
data: {
|
||||
leagueId: data.leagueId,
|
||||
homeTeamId: placeholder.id,
|
||||
awayTeamId: placeholder.id,
|
||||
isOutright: true,
|
||||
matchName: data.titleEn || data.titleZh,
|
||||
matchName,
|
||||
startTime: data.startTime ?? new Date('2030-01-01T00:00:00Z'),
|
||||
status,
|
||||
publishTime: status === 'PUBLISHED' ? new Date() : undefined,
|
||||
@@ -204,6 +223,11 @@ export class OutrightService {
|
||||
},
|
||||
});
|
||||
|
||||
await this.upsertOutrightTitles(match.id, {
|
||||
zh: data.titleZh,
|
||||
en: data.titleEn,
|
||||
ms: data.titleMs,
|
||||
});
|
||||
await this.ensureOutrightMarket(match.id);
|
||||
return this.getForAdmin(match.id);
|
||||
}
|
||||
@@ -217,15 +241,35 @@ export class OutrightService {
|
||||
displayOrder?: number;
|
||||
titleZh?: string;
|
||||
titleEn?: string;
|
||||
titleMs?: string;
|
||||
},
|
||||
) {
|
||||
const match = await this.getOutrightMatchOrThrow(matchId);
|
||||
const status = data.status ?? match.status;
|
||||
|
||||
let matchName = data.matchName?.trim();
|
||||
const titlesTouched =
|
||||
data.titleZh !== undefined ||
|
||||
data.titleEn !== undefined ||
|
||||
data.titleMs !== undefined;
|
||||
if (titlesTouched) {
|
||||
const [curZh, curEn, curMs] = await Promise.all([
|
||||
this.getOutrightTitle(matchId, 'zh-CN'),
|
||||
this.getOutrightTitle(matchId, 'en-US'),
|
||||
this.getOutrightTitle(matchId, 'ms-MY'),
|
||||
]);
|
||||
const zh = data.titleZh !== undefined ? data.titleZh : curZh;
|
||||
const en = data.titleEn !== undefined ? data.titleEn : curEn;
|
||||
const ms = data.titleMs !== undefined ? data.titleMs : curMs;
|
||||
await this.upsertOutrightTitles(matchId, { zh, en, ms });
|
||||
matchName = this.resolveOutrightMatchName({ titleZh: zh, titleEn: en, titleMs: ms });
|
||||
}
|
||||
|
||||
await this.prisma.match.update({
|
||||
where: { id: matchId },
|
||||
data: {
|
||||
status,
|
||||
matchName: data.matchName,
|
||||
matchName: matchName !== undefined ? matchName : undefined,
|
||||
isHot: data.isHot,
|
||||
displayOrder: data.displayOrder,
|
||||
publishTime:
|
||||
@@ -490,7 +534,18 @@ export class OutrightService {
|
||||
|
||||
if (!selections.length) continue;
|
||||
|
||||
const [titleZh, titleEn, titleMs] = await Promise.all([
|
||||
this.getOutrightTitle(match.id, 'zh-CN'),
|
||||
this.getOutrightTitle(match.id, 'en-US'),
|
||||
this.getOutrightTitle(match.id, 'ms-MY'),
|
||||
]);
|
||||
const localizedTitle = this.pickOutrightTitleForLocale(locale, {
|
||||
zh: titleZh,
|
||||
en: titleEn,
|
||||
ms: titleMs,
|
||||
});
|
||||
const title =
|
||||
localizedTitle ||
|
||||
match.matchName?.trim() ||
|
||||
`*${leagueName || 'Outright'} ${locale.startsWith('zh') ? '冠军' : 'Winner'}`;
|
||||
|
||||
@@ -625,4 +680,76 @@ export class OutrightService {
|
||||
});
|
||||
return row?.value ?? '';
|
||||
}
|
||||
|
||||
private async getOutrightTitle(matchId: bigint, locale: string): Promise<string> {
|
||||
const row = await this.prisma.entityTranslation.findFirst({
|
||||
where: {
|
||||
entityType: 'MATCH',
|
||||
entityId: matchId,
|
||||
locale,
|
||||
fieldName: 'title',
|
||||
},
|
||||
});
|
||||
return row?.value?.trim() ?? '';
|
||||
}
|
||||
|
||||
private resolveOutrightMatchName(data: {
|
||||
titleZh?: string;
|
||||
titleEn?: string;
|
||||
titleMs?: string;
|
||||
}): string {
|
||||
return (
|
||||
data.titleEn?.trim() ||
|
||||
data.titleZh?.trim() ||
|
||||
data.titleMs?.trim() ||
|
||||
'Outright'
|
||||
);
|
||||
}
|
||||
|
||||
private pickOutrightTitleForLocale(
|
||||
locale: string,
|
||||
titles: { zh: string; en: string; ms: string },
|
||||
): string {
|
||||
if (locale === 'ms-MY' || locale.startsWith('ms')) {
|
||||
return titles.ms || titles.en || titles.zh;
|
||||
}
|
||||
if (locale.startsWith('zh')) {
|
||||
return titles.zh || titles.en || titles.ms;
|
||||
}
|
||||
return titles.en || titles.zh || titles.ms;
|
||||
}
|
||||
|
||||
private async upsertOutrightTitles(
|
||||
matchId: bigint,
|
||||
titles: { zh?: string; en?: string; ms?: string },
|
||||
) {
|
||||
const entries: Array<[string, string | undefined]> = [
|
||||
['zh-CN', titles.zh],
|
||||
['en-US', titles.en],
|
||||
['ms-MY', titles.ms],
|
||||
];
|
||||
for (const [locale, raw] of entries) {
|
||||
if (raw === undefined) continue;
|
||||
const value = raw.trim();
|
||||
if (!value) continue;
|
||||
await this.prisma.entityTranslation.upsert({
|
||||
where: {
|
||||
entityType_entityId_locale_fieldName: {
|
||||
entityType: 'MATCH',
|
||||
entityId: matchId,
|
||||
locale,
|
||||
fieldName: 'title',
|
||||
},
|
||||
},
|
||||
create: {
|
||||
entityType: 'MATCH',
|
||||
entityId: matchId,
|
||||
locale,
|
||||
fieldName: 'title',
|
||||
value,
|
||||
},
|
||||
update: { value },
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user