feat(admin): 仪表盘重构、代理线路修复与后台体验优化
Some checks failed
lotteryadmin CI / build (push) Has been cancelled

- 各角色仪表盘:KPI 可点击跳转、快捷入口、去重冗余区块,代理/站点降级 analytics
- 代理线路:创建玩家权限、侧栏搜索、深链 URL、档案保存与删除预检等修复
- 统一密码最短 6 位;代理模块表格/侧栏背景色一致(admin-table-inset)
- 报表、钱包、对账、开奖、结算、配置等模块结构与 i18n 同步更新
This commit is contained in:
2026-06-26 14:39:22 +08:00
parent 7d075ceb62
commit 0d984b00f0
126 changed files with 7423 additions and 7084 deletions

View File

@@ -1,6 +1,6 @@
"use client";
import { ArrowRight, Eye } from "lucide-react";
import { ArrowRight, Banknote, Check, Eye } from "lucide-react";
import { useTranslation } from "react-i18next";
import type { SettlementBillRow } from "@/api/admin-agent-settlement";
@@ -16,9 +16,8 @@ import {
formatSignedSettlementMoney,
} from "@/modules/settlement/settlement-signed-money";
import { formatDashboardMoneyMinor } from "@/modules/dashboard/use-dashboard-analytics";
import {
describeBillPaymentDirection,
} from "@/modules/settlement/settlement-bill-display";
import { describeBillPaymentDirection } from "@/modules/settlement/settlement-bill-display";
import { settlementBillOperableByBoundAgent } from "@/modules/settlement/settlement-bill-operable";
import {
formatPlatformPartyLabel,
SettlementDashCell,
@@ -44,7 +43,11 @@ type SettlementBillsTableProps = {
currencyCode: string;
billTypeFilter?: BillTypeFilter;
emptyMessage?: string;
canOperate?: boolean;
boundAgentId?: number | null;
onOpenDetail: (billId: number) => void;
onConfirmBill?: (row: SettlementBillRow) => void;
onPayBill?: (row: SettlementBillRow) => void;
};
function billRowTone(row: SettlementBillRow): string {
@@ -120,7 +123,11 @@ export function SettlementBillsTable({
currencyCode,
billTypeFilter = "all",
emptyMessage,
canOperate = false,
boundAgentId = null,
onOpenDetail,
onConfirmBill,
onPayBill,
}: SettlementBillsTableProps): React.ReactElement {
const { t } = useTranslation(["settlementCenter", "agents", "common"]);
@@ -173,8 +180,44 @@ export function SettlementBillsTable({
</TableHeader>
<TableBody>
{rows.map((row) => {
const isPlayerBill = row.bill_type === "player";
const direction = describeBillPaymentDirection(row, t);
const operable =
canOperate &&
settlementBillOperableByBoundAgent(row, boundAgentId ? { id: boundAgentId } : null);
const canConfirm = operable && row.status === "pending_confirm";
const canPay =
operable &&
["confirmed", "partial_paid", "overdue"].includes(row.status) &&
row.unpaid_amount > 0;
const rowActions = [
...(canConfirm && onConfirmBill
? [
{
key: "confirm",
label: t("billsPanel.confirmOneBtn", { defaultValue: "确认" }),
icon: Check,
onClick: () => onConfirmBill(row),
},
]
: []),
...(canPay && onPayBill
? [
{
key: "pay",
label: t("billsPanel.payBtn", { defaultValue: "收付" }),
icon: Banknote,
onClick: () => onPayBill(row),
},
]
: []),
{
key: "detail",
label: t("actions.detail", { defaultValue: "详情" }),
icon: Eye,
onClick: () => onOpenDetail(row.id),
},
];
return (
<TableRow key={row.id} className={billRowTone(row)}>
@@ -268,16 +311,7 @@ export function SettlementBillsTable({
className="sticky right-0 z-10 bg-card text-center shadow-[-1px_0_0_rgba(203,213,225,0.7)]"
onClick={(e) => e.stopPropagation()}
>
<AdminRowActionsMenu
actions={[
{
key: "detail",
label: t("actions.detail", { defaultValue: "详情" }),
icon: Eye,
onClick: () => onOpenDetail(row.id),
},
]}
/>
<AdminRowActionsMenu actions={rowActions} />
</TableCell>
</TableRow>
);