统一业务台账首屏布局(05-30-fix-payment-ledger-layout-consistency)
这个提交包含在:
@@ -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) => {
|
||||
|
||||
在新工单中引用
屏蔽一个用户