feat: WC2026 赛事 seed、生产上线初始化脚本与目录归档
重构 seed 为 WC2026 72 场小组赛与 48 强优胜盘;新增 production 模式仅保留 admin 与赛事示例;提供 prod-init-db 全量重置脚本;管理端 i18n 分包与赛事归档能力。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -806,6 +806,34 @@ export class AgentsService {
|
||||
return this.getDirectPlayerDetail(agentId, playerId);
|
||||
}
|
||||
|
||||
async deleteDirectPlayer(agentId: bigint, playerId: bigint) {
|
||||
await this.requireDirectPlayer(agentId, playerId);
|
||||
|
||||
const betCount = await this.prisma.bet.count({
|
||||
where: {
|
||||
userId: playerId,
|
||||
status: 'PENDING',
|
||||
},
|
||||
});
|
||||
if (betCount > 0) {
|
||||
throw appBadRequest('PLAYER_HAS_PENDING_BETS');
|
||||
}
|
||||
|
||||
const wallet = await this.prisma.wallet.findUnique({ where: { userId: playerId } });
|
||||
if (wallet) {
|
||||
const available = new Decimal(wallet.availableBalance);
|
||||
const frozen = new Decimal(wallet.frozenBalance);
|
||||
if (available.gt(0) || frozen.gt(0)) {
|
||||
throw appBadRequest('PLAYER_HAS_BALANCE');
|
||||
}
|
||||
}
|
||||
|
||||
return this.prisma.user.update({
|
||||
where: { id: playerId },
|
||||
data: { deletedAt: new Date(), status: 'SUSPENDED' },
|
||||
});
|
||||
}
|
||||
|
||||
async listAgentsAdmin(params?: {
|
||||
page?: number;
|
||||
pageSize?: number;
|
||||
@@ -1696,9 +1724,18 @@ export class AgentsService {
|
||||
return user;
|
||||
}
|
||||
|
||||
async getPortalAgentDirectPlayers(rootAgentId: bigint, targetAgentId: bigint) {
|
||||
async getPortalAgentDirectPlayers(
|
||||
rootAgentId: bigint,
|
||||
targetAgentId: bigint,
|
||||
opts?: { page?: number; pageSize?: number },
|
||||
) {
|
||||
await this.assertDescendantAgent(rootAgentId, targetAgentId);
|
||||
const players = await this.getDirectPlayers(targetAgentId);
|
||||
const page = Math.max(1, opts?.page ?? 1);
|
||||
const pageSize = Math.min(100, Math.max(1, opts?.pageSize ?? 20));
|
||||
const { items: players, total } = await this.getDirectPlayers(targetAgentId, {
|
||||
page,
|
||||
pageSize,
|
||||
});
|
||||
const profile = await this.prisma.agentProfile.findUnique({
|
||||
where: { userId: targetAgentId },
|
||||
select: {
|
||||
@@ -1714,7 +1751,7 @@ export class AgentsService {
|
||||
players.map((p) => ({ id: BigInt(p.id), parentId: targetAgentId })),
|
||||
parentCashbackMap,
|
||||
);
|
||||
return players.map((p) => ({
|
||||
const mapped = players.map((p) => ({
|
||||
...p,
|
||||
parentAgentId: targetKey,
|
||||
parentAgentUsername,
|
||||
@@ -1722,18 +1759,30 @@ export class AgentsService {
|
||||
inChain: true,
|
||||
isDirect: targetKey === rootKey,
|
||||
}));
|
||||
return { items: mapped, total, page, pageSize };
|
||||
}
|
||||
|
||||
async getDirectPlayers(agentId: bigint) {
|
||||
const rows = await this.prisma.user.findMany({
|
||||
where: { parentId: agentId, userType: 'PLAYER', deletedAt: null },
|
||||
include: {
|
||||
wallet: true,
|
||||
usedInvite: { select: { code: true } },
|
||||
},
|
||||
orderBy: { createdAt: 'desc' },
|
||||
});
|
||||
return rows.map((u) => ({
|
||||
async getDirectPlayers(
|
||||
agentId: bigint,
|
||||
opts?: { page?: number; pageSize?: number },
|
||||
) {
|
||||
const where = { parentId: agentId, userType: 'PLAYER' as const, deletedAt: null };
|
||||
const page = Math.max(1, opts?.page ?? 1);
|
||||
const pageSize = Math.min(100, Math.max(1, opts?.pageSize ?? 20));
|
||||
const [total, rows] = await Promise.all([
|
||||
this.prisma.user.count({ where }),
|
||||
this.prisma.user.findMany({
|
||||
where,
|
||||
include: {
|
||||
wallet: true,
|
||||
usedInvite: { select: { code: true } },
|
||||
},
|
||||
orderBy: { createdAt: 'desc' },
|
||||
skip: (page - 1) * pageSize,
|
||||
take: pageSize,
|
||||
}),
|
||||
]);
|
||||
const items = rows.map((u) => ({
|
||||
id: u.id.toString(),
|
||||
username: u.username,
|
||||
status: u.status,
|
||||
@@ -1746,6 +1795,7 @@ export class AgentsService {
|
||||
}
|
||||
: undefined,
|
||||
}));
|
||||
return { items, total, page, pageSize };
|
||||
}
|
||||
|
||||
async getChildAgents(agentId: bigint) {
|
||||
|
||||
Reference in New Issue
Block a user