统一业务台账首屏布局(05-30-fix-payment-ledger-layout-consistency)

这个提交包含在:
2026-05-30 21:44:16 +08:00
父节点 eea2af7718
当前提交 16fd9bdf52
共修改 25 个文件,包含 834 行新增和 543 行删除
+78 -59
查看文件
@@ -935,6 +935,18 @@ export function PurchaseRequestsPage() {
);
const detailEvidenceHint = detail ? resolvePurchaseEvidenceHint(detail) : null;
const detailNextStepText = detail ? resolvePurchaseNextStep(detail) : "";
const isPurchaseDetailMode = Boolean(selectedId);
const openPurchaseDetail = (id: string) => {
setSelectedId(id);
setHydratedDetailId("");
};
const returnToPurchaseList = () => {
setSelectedId("");
setHydratedDetailId("");
const next = new URLSearchParams(searchParams);
next.delete("id");
setSearchParams(next, { replace: true });
};
return (
<ListWorkspace>
@@ -942,16 +954,37 @@ export function PurchaseRequestsPage() {
<WorkspaceHeader
title="采购申请"
actions={
canCreate ? (
<Button
data-testid="purchase-requests-create"
disabled={createMutation.isPending}
onClick={() => createMutation.mutate()}
type="button"
>
{createMutation.isPending ? "创建中..." : "新建采购"}
</Button>
) : undefined
<div className="flex flex-wrap gap-2">
{isPurchaseDetailMode ? (
<Button type="button" variant="secondary" onClick={returnToPurchaseList}>
返回列表
</Button>
) : (
<>
{canCreate ? (
<Button
data-testid="purchase-requests-create"
disabled={createMutation.isPending}
onClick={() => createMutation.mutate()}
type="button"
>
{createMutation.isPending ? "创建中..." : "新建采购"}
</Button>
) : null}
{canShowLedgerTools ? (
<Button
data-testid="purchase-ledger-tools"
type="button"
variant={showAdvancedTools ? "default" : "secondary"}
onClick={() => setShowLedgerTools((current) => !current)}
>
<Wrench aria-hidden className="mr-1 size-4" />
台账工具
</Button>
) : null}
</>
)}
</div>
}
/>
@@ -961,6 +994,8 @@ export function PurchaseRequestsPage() {
</p>
) : null}
{!isPurchaseDetailMode ? (
<>
<FilterBar className="ops-command-bar space-y-3 !p-3 md:!p-3.5">
<div className="ops-command-bar__row">
<div className="min-w-0">
@@ -990,18 +1025,6 @@ export function PurchaseRequestsPage() {
<span className="rounded-full bg-slate-100 px-2.5 py-1 text-xs font-medium text-slate-600">
{mine ? "我相关" : "全范围"}
</span>
{canShowLedgerTools ? (
<Button
data-testid="purchase-ledger-tools"
size="sm"
type="button"
variant={showAdvancedTools ? "default" : "secondary"}
onClick={() => setShowLedgerTools((current) => !current)}
>
<Wrench aria-hidden className="mr-1 size-4" />
台账工具
</Button>
) : null}
</div>
</div>
@@ -1119,18 +1142,13 @@ export function PurchaseRequestsPage() {
purchaseItems.map((item) => {
const evidenceHint = resolvePurchaseEvidenceHint(item);
return (
<button
data-testid="purchase-request-mobile-row"
key={item.id}
type="button"
className={`w-full rounded-lg border p-3 text-left ${
item.id === selectedId ? "border-zinc-400 bg-zinc-50" : "border-zinc-200 bg-white"
}`}
onClick={() => {
setSelectedId(item.id);
setHydratedDetailId("");
}}
>
<button
data-testid="purchase-request-mobile-row"
key={item.id}
type="button"
className="w-full rounded-lg border border-zinc-200 bg-white p-3 text-left"
onClick={() => openPurchaseDetail(item.id)}
>
<div className="flex items-start justify-between gap-3">
<div className="min-w-0">
<div className="truncate text-sm font-semibold text-zinc-900">
@@ -1161,10 +1179,11 @@ export function PurchaseRequestsPage() {
? `${formatTextWithCompactLongNumbers(item.project.projectNo)} · ${item.project.name}`
: "未关联项目"}
</div>
<div className={`mt-0.5 ${evidenceHint.className}`}>{evidenceHint.label}</div>
</div>
</div>
</button>
<div className={`mt-0.5 ${evidenceHint.className}`}>{evidenceHint.label}</div>
</div>
</div>
<div className="mt-3 text-sm font-medium text-primary">{resolvePurchaseRowActionLabel(item.status)}</div>
</button>
);
})
) : (
@@ -1190,10 +1209,11 @@ export function PurchaseRequestsPage() {
purchaseItems.map((item) => {
const evidenceHint = resolvePurchaseEvidenceHint(item);
return (
<TableRow
key={item.id}
className={item.id === selectedId ? "bg-zinc-50" : undefined}
>
<TableRow
key={item.id}
className="cursor-pointer"
onClick={() => openPurchaseDetail(item.id)}
>
<TableCell>
<div className="font-medium text-zinc-900">
<CompactBusinessCode value={resolvePurchaseDisplayCode(item)} />
@@ -1233,11 +1253,10 @@ export function PurchaseRequestsPage() {
size="sm"
type="button"
variant={["draft", "rejected"].includes(item.status) ? "default" : "secondary"}
onClick={(event) => {
event.stopPropagation();
setSelectedId(item.id);
setHydratedDetailId("");
}}
onClick={(event) => {
event.stopPropagation();
openPurchaseDetail(item.id);
}}
>
{resolvePurchaseRowActionLabel(item.status)}
</Button>
@@ -1261,16 +1280,17 @@ export function PurchaseRequestsPage() {
</>
) : null}
<Pagination
page={page}
totalPages={totalPages}
onPageChange={setPage}
testIdPrefix="purchase-requests"
/>
</div>
{selectedId ? (
<div className="card-std space-y-5 p-4 md:p-5">
<Pagination
page={page}
totalPages={totalPages}
onPageChange={setPage}
testIdPrefix="purchase-requests"
/>
</div>
</div>
</>
) : (
<div className="card-std space-y-5 p-4 md:p-5">
{selectedId && detailQuery.isLoading ? <TableSkeleton columns={3} rows={8} /> : null}
{selectedId && detailQuery.isError ? (
@@ -2050,8 +2070,7 @@ export function PurchaseRequestsPage() {
</>
) : null}
</div>
) : null}
</div>
)}
<ActionConfirmDialog
open={Boolean(submitPrecheckConfirm)}
onOpenChange={(open) => {