feat: split admin dashboard, improve match ops, and player closed-match UX
Admin: add match/player overview sub-nav; refine settlement flow and league match management UI; improve action button enabled/disabled styles; enhance logo upload and outright odds sync. API: expose matchPhase/bettingOpen for closed matches; league publish guards; settlement preview with auto score save; outright team auto-sync. Player: watermark for closed/settled states; keep match and bet details visible; remove default login credentials. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -252,7 +252,7 @@ export class AgentsService {
|
||||
playerId,
|
||||
amount,
|
||||
operatorId,
|
||||
remark,
|
||||
remark ?? '管理员上分',
|
||||
requestId,
|
||||
);
|
||||
const player = await this.prisma.user.findUnique({
|
||||
@@ -277,7 +277,7 @@ export class AgentsService {
|
||||
playerId,
|
||||
amount,
|
||||
operatorId,
|
||||
remark,
|
||||
remark ?? '管理员下分',
|
||||
requestId,
|
||||
);
|
||||
const player = await this.prisma.user.findUnique({
|
||||
@@ -432,7 +432,7 @@ export class AgentsService {
|
||||
|
||||
await this.assertAgentDepositLimits(agentId, amt);
|
||||
|
||||
await this.wallet.deposit(playerId, amt, agentId, remark ?? 'Agent deposit', requestId);
|
||||
await this.wallet.deposit(playerId, amt, agentId, remark ?? '代理上分', requestId);
|
||||
await this.recalculateUsedCredit(agentId);
|
||||
|
||||
return { success: true };
|
||||
@@ -443,10 +443,11 @@ export class AgentsService {
|
||||
playerId: bigint,
|
||||
amount: number,
|
||||
requestId: string,
|
||||
remark?: string,
|
||||
) {
|
||||
await this.requireDirectPlayer(agentId, playerId);
|
||||
|
||||
await this.wallet.withdraw(playerId, amount, agentId, 'Agent withdraw', requestId);
|
||||
await this.wallet.withdraw(playerId, amount, agentId, remark ?? '代理下分', requestId);
|
||||
await this.recalculateUsedCredit(agentId);
|
||||
|
||||
return { success: true };
|
||||
@@ -1481,11 +1482,27 @@ export class AgentsService {
|
||||
}
|
||||
|
||||
async getSubtreeAgentIds(agentId: bigint) {
|
||||
const descendants = await this.prisma.agentClosure.findMany({
|
||||
where: { ancestorId: agentId },
|
||||
select: { descendantId: true },
|
||||
});
|
||||
return descendants.map((d) => d.descendantId);
|
||||
const ids: bigint[] = [];
|
||||
const queue: bigint[] = [agentId];
|
||||
const seen = new Set<string>();
|
||||
|
||||
while (queue.length > 0) {
|
||||
const current = queue.shift()!;
|
||||
const key = current.toString();
|
||||
if (seen.has(key)) continue;
|
||||
seen.add(key);
|
||||
ids.push(current);
|
||||
|
||||
const children = await this.prisma.agentProfile.findMany({
|
||||
where: { parentAgentId: current },
|
||||
select: { userId: true },
|
||||
});
|
||||
for (const child of children) {
|
||||
queue.push(child.userId);
|
||||
}
|
||||
}
|
||||
|
||||
return ids;
|
||||
}
|
||||
|
||||
async getReportSummary(agentId: bigint) {
|
||||
|
||||
Reference in New Issue
Block a user