feat(player): 注册账号、登录双模式与移动端性能优化

注册必填 7-32 位账号,手机号区号/本地号分存;登录默认账号模式并支持切换手机号登录;Player i18n 拆包与赛事接口优化。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-06-12 10:56:51 +08:00
parent 83f0f380c5
commit 312c3c5816
35 changed files with 1944 additions and 1394 deletions

View File

@@ -162,12 +162,24 @@ export class PlayerController {
@Headers('x-locale') headerLocale?: string,
) {
const locale = userLocale || headerLocale || 'zh-CN';
const [banners, announcements, hotMatches, todayMatches] = await Promise.all([
const [banners, announcements, allMatches] = await Promise.all([
this.content.listActive('BANNER', locale),
this.content.listActiveAnnouncements(locale),
this.matches.listPublished(locale),
this.matches.listPublished(locale),
this.matches.listPublished(locale, undefined, { includeMarkets: false }),
]);
const now = new Date();
const isKickoffToday = (startTime: string) => {
const d = new Date(startTime);
return (
d.getFullYear() === now.getFullYear() &&
d.getMonth() === now.getMonth() &&
d.getDate() === now.getDate()
);
};
const hotMatches = (allMatches as Array<{ isHot?: boolean }>).filter((m) => m.isHot);
const todayMatches = (allMatches as Array<{ startTime: string }>).filter((m) =>
isKickoffToday(m.startTime),
);
return jsonResponse({
banners,
announcements,
@@ -175,7 +187,7 @@ export class PlayerController {
ticker: announcements,
/** @deprecated 使用 announcements */
notices: announcements,
hotMatches: (hotMatches as Array<{ isHot?: boolean }>).filter((m) => m.isHot),
hotMatches,
todayMatches,
});
}
@@ -186,9 +198,18 @@ export class PlayerController {
@CurrentUser('locale') userLocale: string | undefined,
@Headers('x-locale') headerLocale: string | undefined,
@Query('leagueId') leagueId?: string,
@Query('scope') scope?: string,
) {
const locale = userLocale || headerLocale || 'zh-CN';
const items = await this.matches.listPublished(locale, leagueId ? BigInt(leagueId) : undefined);
const lid = leagueId ? BigInt(leagueId) : undefined;
if (scope === 'parlay') {
const items = await this.matches.listPublished(locale, lid, {
includeMarkets: true,
parlayMarketsOnly: true,
});
return jsonResponse(items);
}
const items = await this.matches.listPublished(locale, lid, { includeMarkets: false });
return jsonResponse(items);
}
@@ -246,8 +267,15 @@ export class PlayerController {
@CurrentUser('locale') locale: string,
@Query('status') status?: string,
@Query('page') page?: string,
@Query('matchId') matchId?: string,
) {
const result = await this.bets.getUserBets(userId, status, page ? parseInt(page) : 1);
const result = await this.bets.getUserBets(
userId,
status,
page ? parseInt(page, 10) : 1,
20,
matchId ? BigInt(matchId) : undefined,
);
const items = await this.matches.enrichBetsForHistory(result.items, locale);
return jsonResponse({ ...result, items });
}