feat(admin): 管理端列表分页、控制台图表与赛事导入

- 玩家/代理/赛事/注单/审计列表分页,默认每页 10 条,无页面滚动条布局

- ECharts 控制台概览、注单管理中文化与列宽优化

- zhibo 赛事字段迁移与导入,玩家编辑可改所属代理

- 管理端 API 分页与 dashboard 统计接口

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-06-03 13:49:31 +08:00
parent 2c356b2048
commit 80adc0e928
45 changed files with 6564 additions and 499 deletions

View File

@@ -0,0 +1,120 @@
export interface PlayerCreateForm {
username: string;
password: string;
confirmPassword: string;
parentId: string;
phone: string;
email: string;
initialDeposit: number;
remark: string;
}
export interface PlayerEditForm {
id: string;
username: string;
status: string;
parentId: string;
parentUsername: string | null;
availableBalance: string;
frozenBalance: string;
betCount: number;
totalStake: string;
totalReturn: string;
createdAt: string;
lastLoginAt: string | null;
loginFailCount: number;
phone: string;
email: string;
}
export interface PlayerRow {
id: string;
username: string;
status: string;
locale: string;
parentId: string | null;
parentUsername: string | null;
phone: string | null;
email: string | null;
availableBalance: string;
frozenBalance: string;
lastLoginAt: string | null;
betCount: number;
totalStake: string;
totalReturn: string;
createdAt: string;
}
export interface PlayerDetail extends PlayerRow {
loginFailCount: number;
lockedUntil: string | null;
updatedAt: string;
}
export function emptyPlayerCreateForm(): PlayerCreateForm {
return {
username: '',
password: 'Player@123',
confirmPassword: 'Player@123',
parentId: '',
phone: '',
email: '',
initialDeposit: 0,
remark: '',
};
}
export function emptyPlayerEditForm(): PlayerEditForm {
return {
id: '',
username: '',
status: 'ACTIVE',
parentId: '',
parentUsername: null,
availableBalance: '0',
frozenBalance: '0',
betCount: 0,
totalStake: '0',
totalReturn: '0',
createdAt: '',
lastLoginAt: null,
loginFailCount: 0,
phone: '',
email: '',
};
}
export function editFormFromDetail(d: PlayerDetail): PlayerEditForm {
return {
id: d.id,
username: d.username,
status: d.status,
parentId: d.parentId ?? '',
parentUsername: d.parentUsername,
availableBalance: d.availableBalance,
frozenBalance: d.frozenBalance,
betCount: d.betCount,
totalStake: d.totalStake,
totalReturn: d.totalReturn,
createdAt: d.createdAt,
lastLoginAt: d.lastLoginAt,
loginFailCount: d.loginFailCount,
phone: d.phone ?? '',
email: d.email ?? '',
};
}
export function buildCreatePlayerPayload(form: PlayerCreateForm) {
if (!form.username.trim()) throw new Error('请填写用户名');
if (form.password.length < 8) throw new Error('密码至少 8 位');
if (form.password !== form.confirmPassword) throw new Error('两次密码不一致');
return {
username: form.username.trim(),
password: form.password,
parentId: form.parentId || undefined,
phone: form.phone.trim() || undefined,
email: form.email.trim() || undefined,
initialDeposit: form.initialDeposit > 0 ? form.initialDeposit : undefined,
remark: form.remark.trim() || undefined,
};
}