"use client"; import { useCallback, useEffect, useState } from "react"; import { AdminLayout } from "@/components/layout/admin-layout"; import { PageHeader } from "@/components/layout/page-header"; import { Skeleton } from "@/components/ui/skeleton"; import { ErrorBanner } from "@/components/ui/error-banner"; import { SecondaryButton } from "@/components/ui/primary-button"; import { PrimaryButton } from "@/components/ui/primary-button"; import { InputField } from "@/components/ui/input-field"; import { SelectField } from "@/components/ui/select-field"; import { Card } from "@/components/ui/card"; import { adminGetMarkupConfigs, adminUpdateMarkupConfig, } from "@/lib/frontend/api-client"; import { formatDateTime, formatPercent, formatUSD } from "@/lib/frontend/format"; import { useAuth } from "@/hooks/use-auth"; import type { DataPageStatus, MarkupConfig, MarkupType } from "@/lib/frontend/types"; const PAGE_SIZE = 10; function formatMarkupSummary(row: MarkupConfig): string { if (row.markup_type === "fixed") { const amount = row.markup_fixed_amount ?? 0; return amount > 0 ? `固定 ${formatUSD(amount)}` : "未配置"; } return row.markup_percent > 0 ? formatPercent(row.markup_percent) : "0%"; } export default function AdminMarkupPage() { const { token, user } = useAuth(); const [status, setStatus] = useState("loading"); const [rows, setRows] = useState([]); const [total, setTotal] = useState(0); const [page, setPage] = useState(1); const [keyword, setKeyword] = useState(""); const [editing, setEditing] = useState(null); const [markupType, setMarkupType] = useState("percent"); const [percent, setPercent] = useState(""); const [fixedAmount, setFixedAmount] = useState(""); const [remark, setRemark] = useState(""); const [saving, setSaving] = useState(false); const [fieldError, setFieldError] = useState(); const load = useCallback( async (p: number, kw: string) => { if (!token) return; setStatus("loading"); const res = await adminGetMarkupConfigs("", token, p, PAGE_SIZE, kw); if (res.code !== 0) { setStatus("error"); return; } setRows(res.data.list); setTotal(res.data.total); setStatus(res.data.total === 0 ? "empty" : "success"); }, [token], ); useEffect(() => { void load(page, keyword); }, [load, page, keyword]); const openEdit = (row: MarkupConfig) => { setEditing(row); setMarkupType(row.markup_type); setPercent(String(row.markup_percent)); setFixedAmount( row.markup_fixed_amount !== null ? String(row.markup_fixed_amount) : "", ); setRemark(row.remark ?? ""); setFieldError(undefined); }; const handleSave = async () => { if (!editing || !token || !user) return; if (markupType === "percent") { const n = Number(percent); if (Number.isNaN(n) || n < 0 || n > 30) { setFieldError("加价比例须在 0~30% 之间"); return; } } else { const n = Number(fixedAmount); if (Number.isNaN(n) || n < 0) { setFieldError("固定加价金额须 ≥ 0"); return; } } setSaving(true); const res = await adminUpdateMarkupConfig("", token, editing.customer_id, { markup_type: markupType, markup_percent: markupType === "percent" ? Number(percent) : undefined, markup_fixed_amount: markupType === "fixed" ? Number(fixedAmount) : undefined, remark, }); setSaving(false); if (res.code !== 0) { setFieldError(res.message); return; } setRows((list) => list.map((r) => (r.customer_id === res.data.customer_id ? res.data : r)), ); setEditing(null); }; const totalPages = Math.max(1, Math.ceil(total / PAGE_SIZE)); return ( { setPage(1); setKeyword(e.target.value); }} /> } /> {status === "loading" && (
{Array.from({ length: 5 }).map((_, i) => ( ))}
)} {status === "error" && ( void load(page, keyword)}> 重试 } > 加载加价配置失败 )} {status === "empty" && ( 未找到匹配的客户 )} {status === "success" && (
{rows.map((row) => ( ))}
客户 ID 加价方式 加价规则 操作人 备注 更新时间 操作
{row.customer_id} {row.markup_type === "fixed" ? "固定金额" : "百分比"} {formatMarkupSummary(row)} {row.operator_id || "—"} {row.remark || "—"} {row.operator_id ? formatDateTime(row.updated_at) : "—"} openEdit(row)}> 编辑
共 {total} 条,第 {page} / {totalPages} 页
setPage((p) => Math.max(1, p - 1))} > 上一页 = totalPages} onClick={() => setPage((p) => p + 1)} > 下一页
)} {editing && (
!saving && setEditing(null)} >
e.stopPropagation()} >

编辑加价 · {editing.customer_id}

百分比仅对运费加价(上限 30%);固定金额为每档报价叠加固定金额。

setMarkupType(e.target.value as MarkupType) } /> {markupType === "percent" ? ( setPercent(e.target.value)} /> ) : ( setFixedAmount(e.target.value)} /> )} setRemark(e.target.value)} />
setEditing(null)}> 取消 void handleSave()}> 保存
)}
); }