feat(admin): 管理端列表分页、控制台图表与赛事导入
- 玩家/代理/赛事/注单/审计列表分页,默认每页 10 条,无页面滚动条布局 - ECharts 控制台概览、注单管理中文化与列宽优化 - zhibo 赛事字段迁移与导入,玩家编辑可改所属代理 - 管理端 API 分页与 dashboard 统计接口 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
64
apps/api/src/domains/catalog/zhibo-match.mapper.ts
Normal file
64
apps/api/src/domains/catalog/zhibo-match.mapper.ts
Normal file
@@ -0,0 +1,64 @@
|
||||
import { Prisma } from '@prisma/client';
|
||||
import type { ZhiboLeagueExport, ZhiboMatchExport, ZhiboTeamExport } from './zhibo-match.types';
|
||||
|
||||
const LOCALE_MAP: Record<string, string> = {
|
||||
zh: 'zh-CN',
|
||||
en: 'en-US',
|
||||
ms: 'ms-MY',
|
||||
};
|
||||
|
||||
export function slugTeamCode(name: string): string {
|
||||
return name
|
||||
.normalize('NFD')
|
||||
.replace(/[\u0300-\u036f]/g, '')
|
||||
.replace(/[^a-zA-Z0-9]+/g, '_')
|
||||
.replace(/^_|_$/g, '')
|
||||
.toUpperCase()
|
||||
.slice(0, 48) || 'TEAM';
|
||||
}
|
||||
|
||||
export function teamCodeFromExport(team: ZhiboTeamExport): string {
|
||||
if (team.id != null) return `ZIBO_${team.id}`;
|
||||
return `NAME_${slugTeamCode(team.name)}`;
|
||||
}
|
||||
|
||||
export function leagueCodeFromExport(league: ZhiboLeagueExport): string {
|
||||
if (league.en.includes('World Cup 2026')) return 'WC2026';
|
||||
return slugTeamCode(league.en).slice(0, 32);
|
||||
}
|
||||
|
||||
export function translationsFromZhiboNames(
|
||||
names: ZhiboTeamExport['names'],
|
||||
fallbackEn: string,
|
||||
): Record<string, string> {
|
||||
const out: Record<string, string> = {};
|
||||
for (const [key, locale] of Object.entries(LOCALE_MAP)) {
|
||||
const v = names[key as keyof typeof names];
|
||||
if (typeof v === 'string' && v.trim()) out[locale] = v.trim();
|
||||
}
|
||||
if (!out['en-US'] && fallbackEn) out['en-US'] = fallbackEn;
|
||||
if (!out['zh-CN'] && names.zh) out['zh-CN'] = names.zh;
|
||||
return out;
|
||||
}
|
||||
|
||||
export function resolveStartTime(kickoff: ZhiboMatchExport['kickoff']): Date {
|
||||
if (kickoff.utcIso) return new Date(kickoff.utcIso);
|
||||
return new Date(kickoff.utcTimeStart * 1000);
|
||||
}
|
||||
|
||||
export function resolveInternalStatus(item: ZhiboMatchExport): string {
|
||||
if (!item.isPublished || item.status.state === 'off') return 'DRAFT';
|
||||
return 'PUBLISHED';
|
||||
}
|
||||
|
||||
export function resolveIsHot(item: ZhiboMatchExport): boolean {
|
||||
return (item.status.isHot ?? 0) > 0;
|
||||
}
|
||||
|
||||
export function toKickoffJson(kickoff: ZhiboMatchExport['kickoff']): Prisma.InputJsonValue {
|
||||
return kickoff as unknown as Prisma.InputJsonValue;
|
||||
}
|
||||
|
||||
export function toVenueJson(venue: ZhiboMatchExport['venue']): Prisma.InputJsonValue {
|
||||
return venue as unknown as Prisma.InputJsonValue;
|
||||
}
|
||||
Reference in New Issue
Block a user