feat: 添加财务摘要接口,更新管理员抽奖模块和导航,优化权限管理逻辑

This commit is contained in:
2026-05-11 16:21:22 +08:00
parent f083b28fc6
commit b539bf0660
57 changed files with 2134 additions and 108 deletions

View File

@@ -0,0 +1,16 @@
import { ModuleScaffold } from "@/components/admin/module-scaffold";
import { auditModuleMeta } from "@/modules/audit/meta";
import { AuditLogsConsole } from "@/modules/audit/audit-logs-console";
import type { Metadata } from "next";
export const metadata: Metadata = {
title: auditModuleMeta.title,
};
export default function AdminAuditLogsPage() {
return (
<ModuleScaffold className="w-full max-w-none">
<AuditLogsConsole />
</ModuleScaffold>
);
}

View File

@@ -0,0 +1,13 @@
import { DrawFinanceConsole } from "@/modules/draws/draw-finance-console";
import type { Metadata } from "next";
export const metadata: Metadata = {
title: "期号收支",
};
export default async function AdminDrawFinancePage(props: {
params: Promise<{ drawId: string }>;
}) {
const { drawId } = await props.params;
return <DrawFinanceConsole drawId={drawId} />;
}

View File

@@ -0,0 +1,14 @@
import { DrawPublishConsole } from "@/modules/draws/draw-publish-console";
import type { Metadata } from "next";
export const metadata: Metadata = {
title: "开奖结果发布",
};
/** PRD §11.4:与 `POST /api/v1/admin/draws/{draw}/result-batches/{batch}/publish` 联调页 */
export default async function AdminDrawPublishBatchPage(props: {
params: Promise<{ drawId: string; batchId: string }>;
}) {
const { drawId, batchId } = await props.params;
return <DrawPublishConsole drawId={drawId} batchId={batchId} />;
}

View File

@@ -1,8 +1,9 @@
import { DrawPublishConsole } from "@/modules/draws/draw-publish-console";
import { redirect } from "next/navigation";
export default async function AdminDrawPublishPage(props: {
/** 兼容旧链接:发布页统一为 `/publish/[batchId]`(与接口动词一致)。 */
export default async function AdminDrawReviewBatchRedirectPage(props: {
params: Promise<{ drawId: string; batchId: string }>;
}) {
const { drawId, batchId } = await props.params;
return <DrawPublishConsole drawId={drawId} batchId={batchId} />;
redirect(`/admin/draws/${drawId}/publish/${batchId}`);
}

View File

@@ -1,5 +1,6 @@
import { ModuleScaffold } from "@/components/admin/module-scaffold";
import { playersModuleMeta } from "@/modules/players/meta";
import { PlayersConsole } from "@/modules/players/players-console";
import type { Metadata } from "next";
export const metadata: Metadata = {
@@ -8,14 +9,8 @@ export const metadata: Metadata = {
export default function AdminPlayersPage() {
return (
<ModuleScaffold>
<p className="text-sm text-zinc-500 dark:text-zinc-400">
{" "}
<code className="rounded bg-zinc-100 px-1 py-0.5 font-mono text-xs dark:bg-zinc-800">
src/modules/players
</code>{" "}
</p>
<ModuleScaffold className="w-full max-w-none">
<PlayersConsole />
</ModuleScaffold>
);
}

View File

@@ -0,0 +1,16 @@
import { ModuleScaffold } from "@/components/admin/module-scaffold";
import { reconcileModuleMeta } from "@/modules/reconcile/meta";
import { ReconcileConsole } from "@/modules/reconcile/reconcile-console";
import type { Metadata } from "next";
export const metadata: Metadata = {
title: reconcileModuleMeta.title,
};
export default function AdminReconcilePage() {
return (
<ModuleScaffold className="w-full max-w-none">
<ReconcileConsole />
</ModuleScaffold>
);
}

View File

@@ -0,0 +1,16 @@
import { ModuleScaffold } from "@/components/admin/module-scaffold";
import { reportsModuleMeta } from "@/modules/reports/meta";
import { ReportsConsole } from "@/modules/reports/reports-console";
import type { Metadata } from "next";
export const metadata: Metadata = {
title: reportsModuleMeta.title,
};
export default function AdminReportsPage() {
return (
<ModuleScaffold className="w-full max-w-none">
<ReportsConsole />
</ModuleScaffold>
);
}

View File

@@ -0,0 +1,22 @@
import { ModuleScaffold } from "@/components/admin/module-scaffold";
import { ServiceDeskConsole } from "@/modules/service-desk/service-desk-console";
import { serviceDeskModuleMeta } from "@/modules/service-desk/meta";
import type { Metadata } from "next";
export const metadata: Metadata = {
title: serviceDeskModuleMeta.title,
};
export default function AdminServiceDeskPage() {
return (
<ModuleScaffold className="w-full max-w-none">
<div className="mb-8 space-y-2">
<h1 className="text-2xl font-semibold tracking-tight">{serviceDeskModuleMeta.title}</h1>
<p className="text-muted-foreground max-w-3xl text-sm leading-relaxed">
{serviceDeskModuleMeta.description}
</p>
</div>
<ServiceDeskConsole />
</ModuleScaffold>
);
}

View File

@@ -1,5 +1,6 @@
import { ModuleScaffold } from "@/components/admin/module-scaffold";
import { ticketsModuleMeta } from "@/modules/tickets/meta";
import { PlayerTicketsConsole } from "@/modules/tickets/player-tickets-console";
import type { Metadata } from "next";
export const metadata: Metadata = {
@@ -8,14 +9,8 @@ export const metadata: Metadata = {
export default function AdminTicketsPage() {
return (
<ModuleScaffold>
<p className="text-sm text-zinc-500 dark:text-zinc-400">
{" "}
<code className="rounded bg-zinc-100 px-1 py-0.5 font-mono text-xs dark:bg-zinc-800">
src/modules/tickets
</code>{" "}
</p>
<ModuleScaffold className="w-full max-w-none">
<PlayerTicketsConsole />
</ModuleScaffold>
);
}

View File

@@ -0,0 +1,12 @@
import type { ReactNode } from "react";
import { WalletSubnav } from "@/modules/wallet/wallet-subnav";
export default function AdminWalletLayout({ children }: { children: ReactNode }) {
return (
<div className="w-full max-w-none">
<WalletSubnav />
{children}
</div>
);
}

View File

@@ -1,16 +1,5 @@
import { ModuleScaffold } from "@/components/admin/module-scaffold";
import { walletModuleMeta } from "@/modules/wallet/meta";
import { WalletConsole } from "@/modules/wallet/wallet-console";
import type { Metadata } from "next";
import { redirect } from "next/navigation";
export const metadata: Metadata = {
title: walletModuleMeta.title,
};
export default function AdminWalletPage() {
return (
<ModuleScaffold className="w-full max-w-none">
<WalletConsole />
</ModuleScaffold>
);
export default function AdminWalletIndexPage() {
redirect("/admin/wallet/transactions");
}

View File

@@ -0,0 +1,16 @@
import { ModuleScaffold } from "@/components/admin/module-scaffold";
import { walletModuleMeta } from "@/modules/wallet/meta";
import { PlayerWalletPanel } from "@/modules/wallet/wallet-console";
import type { Metadata } from "next";
export const metadata: Metadata = {
title: `${walletModuleMeta.title} · 玩家钱包`,
};
export default function AdminWalletPlayerPage() {
return (
<ModuleScaffold className="w-full max-w-none">
<PlayerWalletPanel />
</ModuleScaffold>
);
}

View File

@@ -0,0 +1,16 @@
import { ModuleScaffold } from "@/components/admin/module-scaffold";
import { walletModuleMeta } from "@/modules/wallet/meta";
import { WalletTxnsPanel } from "@/modules/wallet/wallet-console";
import type { Metadata } from "next";
export const metadata: Metadata = {
title: `${walletModuleMeta.title} · 流水`,
};
export default function AdminWalletTransactionsPage() {
return (
<ModuleScaffold className="w-full max-w-none">
<WalletTxnsPanel />
</ModuleScaffold>
);
}

View File

@@ -0,0 +1,16 @@
import { ModuleScaffold } from "@/components/admin/module-scaffold";
import { walletModuleMeta } from "@/modules/wallet/meta";
import { TransferOrdersPanel } from "@/modules/wallet/wallet-console";
import type { Metadata } from "next";
export const metadata: Metadata = {
title: `${walletModuleMeta.title} · 转账单`,
};
export default function AdminWalletTransferOrdersPage() {
return (
<ModuleScaffold className="w-full max-w-none">
<TransferOrdersPanel />
</ModuleScaffold>
);
}