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

这个提交包含在:
2026-05-30 21:44:16 +08:00
父节点 eea2af7718
当前提交 16fd9bdf52
共修改 25 个文件,包含 834 行新增和 543 行删除
+58 -39
查看文件
@@ -798,6 +798,14 @@ export function AssetRegistryPage() {
setIsCreatingAsset(false);
setSelectedAssetId(assetId);
};
const returnToAssetList = () => {
setIsCreatingAsset(false);
setSelectedAssetId("");
const next = new URLSearchParams(searchParams);
next.delete("id");
setSearchParams(next, { replace: true });
};
const isAssetDetailMode = isCreatingAsset || Boolean(selectedAssetId);
return (
<ListWorkspace>
@@ -805,17 +813,26 @@ export function AssetRegistryPage() {
title="资产台账"
actions={
<div className="flex flex-wrap gap-2">
<Button type="button" variant="secondary" onClick={() => navigate("/mobile/assets/scan") }>
移动扫码查找
</Button>
<Button type="button" variant={showLedgerTools ? "default" : "secondary"} onClick={() => setShowLedgerTools((value) => !value)}>
台账工具
</Button>
{isAssetDetailMode ? (
<Button type="button" variant="secondary" onClick={returnToAssetList}>
返回列表
</Button>
) : (
<>
<Button type="button" variant="secondary" onClick={() => navigate("/mobile/assets/scan") }>
移动扫码查找
</Button>
<Button type="button" variant={showLedgerTools ? "default" : "secondary"} onClick={() => setShowLedgerTools((value) => !value)}>
台账工具
</Button>
</>
)}
</div>
}
/>
<div className={showLedgerTools ? "grid gap-6 xl:grid-cols-[380px_minmax(0,1fr)]" : "grid gap-6"}>
{!isAssetDetailMode ? (
<div className="grid gap-6">
{showLedgerTools ? (
<div className="card-std space-y-4 p-4 md:p-5" data-testid="asset-ledger-tools">
<div className="rounded-lg border border-slate-200 bg-slate-50 p-3 text-sm text-slate-600">
@@ -1025,17 +1042,13 @@ export function AssetRegistryPage() {
<div className="space-y-3 md:hidden">
{orderedAssetItems.length ? (
orderedAssetItems.map((item) => (
<button
data-testid="asset-mobile-row"
type="button"
key={item.id}
onClick={() => selectAsset(item.id)}
className={`w-full rounded-lg border p-3 text-left ${
item.id === selectedAssetId && !isCreatingAsset
? "border-zinc-400 bg-zinc-50"
: "border-zinc-200 bg-white"
}`}
>
<button
data-testid="asset-mobile-row"
type="button"
key={item.id}
onClick={() => selectAsset(item.id)}
className="w-full rounded-lg border border-zinc-200 bg-white p-3 text-left"
>
<div className="flex items-start justify-between gap-3">
<div className="min-w-0">
<div className="truncate text-sm font-semibold text-zinc-900">
@@ -1065,9 +1078,10 @@ export function AssetRegistryPage() {
<div>
<div className="text-zinc-400">位置</div>
<div className="mt-0.5 truncate text-zinc-700">{item.location ?? "-"}</div>
</div>
</div>
</button>
</div>
</div>
<div className="mt-3 text-sm font-medium text-primary">查看详情</div>
</button>
))
) : (
<div className="rounded-lg border border-zinc-200 p-4 text-sm text-zinc-500">暂无资产卡片</div>
@@ -1079,17 +1093,18 @@ export function AssetRegistryPage() {
<tr>
<TableHead>资产</TableHead>
<TableHead>类型</TableHead>
<TableHead>责任链</TableHead>
<TableHead>位置</TableHead>
<TableHead>状态</TableHead>
</tr>
<TableHead>责任链</TableHead>
<TableHead>位置</TableHead>
<TableHead>状态</TableHead>
<TableHead className="w-24 text-right">操作</TableHead>
</tr>
</TableHeader>
<TableBody>
{orderedAssetItems.length ? (
orderedAssetItems.map((item) => (
<TableRow data-testid="asset-row" key={item.id} onClick={() => {
selectAsset(item.id);
}} className={item.id === selectedAssetId && !isCreatingAsset ? "bg-zinc-50" : "cursor-pointer"}>
<TableRow data-testid="asset-row" key={item.id} onClick={() => {
selectAsset(item.id);
}} className="cursor-pointer">
<TableCell>
<div className="font-medium text-zinc-900">
<CompactAssetNo value={item.assetNo} />
@@ -1107,12 +1122,17 @@ export function AssetRegistryPage() {
<div>{formatTextWithCompactLongNumbers(item.location ?? "-")}</div>
<div className="text-xs text-zinc-500">盘点 {item.lastVerifiedAt ? formatDisplayDateTime(item.lastVerifiedAt) : "未登记"}</div>
</TableCell>
<TableCell><StatusBadge status={item.status} /></TableCell>
</TableRow>
<TableCell><StatusBadge status={item.status} /></TableCell>
<TableCell className="text-right">
<Button type="button" size="sm" variant="secondary" onClick={() => selectAsset(item.id)}>
查看详情
</Button>
</TableCell>
</TableRow>
))
) : (
<TableRow>
<TableCell colSpan={5} className="py-4 text-zinc-500">
<TableCell colSpan={6} className="py-4 text-zinc-500">
暂无资产卡片
</TableCell>
</TableRow>
@@ -1121,11 +1141,12 @@ export function AssetRegistryPage() {
</Table>
</PrimaryTable>
</>
) : null}
</FilterBar>
{selectedAssetId || isCreatingAsset ? (
<div className="card-std space-y-4 p-4 md:p-5">
) : null}
</FilterBar>
</div>
</div>
) : (
<div className="card-std space-y-4 p-4 md:p-5">
{selectedAssetId && !isCreatingAsset && assetDetailQuery.isLoading ? <TableSkeleton columns={2} rows={8} /> : null}
{selectedAssetId && !isCreatingAsset && assetDetailQuery.isError ? (
<p className="rounded-lg border border-red-200 bg-red-50 px-3 py-2 text-sm text-red-600">{resolveError(assetDetailQuery.error)}</p>
@@ -1559,9 +1580,7 @@ export function AssetRegistryPage() {
</>
) : null}
</div>
) : null}
</div>
</div>
)}
</ListWorkspace>
);
}