R92 A5-A6 修复手机报销列表并补自动化回归

这个提交包含在:
2026-05-05 22:16:48 +08:00
父节点 9d8c7e0478
当前提交 5cd52ee061
共修改 3 个文件,包含 434 行新增和 1 行删除
+86 -1
查看文件
@@ -587,7 +587,92 @@ export function ReimbursementsPage() {
{!listQuery.isLoading && !listQuery.isError ? (
<>
<PrimaryTable>
<div className="space-y-3 md:hidden" data-testid="reimbursements-mobile-list">
{items.length ? (
items.map((item) => {
const canSelectRow = Boolean(
item.pendingWorkflow?.task?.id && item.pendingWorkflow.allowedActions.includes("approve"),
);
const actionLabel = ["draft", "rejected"].includes(item.status) ? "继续编辑" : "查看详情";
return (
<article
className="card-std space-y-3 p-4"
data-testid="reimbursement-mobile-card"
key={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">
{item.formNumber || item.id}
</div>
<div className="mt-1 text-xs text-zinc-500">{item.reimbursementDate ?? "未填写日期"}</div>
</div>
<StatusBadge className="shrink-0" status={item.status} />
</div>
{item.project ? (
<div className="rounded-lg bg-zinc-50 px-3 py-2 text-xs text-zinc-600">
项目:{item.project.projectNo} · {item.project.name}
</div>
) : null}
<div className="grid grid-cols-2 gap-3 text-sm">
<div>
<div className="text-xs text-zinc-500">金额</div>
<div className="font-semibold text-zinc-900">
{item.totalAmount != null
? new Intl.NumberFormat("zh-CN", { style: "currency", currency: "CNY" }).format(
Number(item.totalAmount),
)
: "-"}
</div>
</div>
<div>
<div className="text-xs text-zinc-500">报销人</div>
<div className="truncate font-medium text-zinc-900">{item.owner?.name ?? "-"}</div>
</div>
</div>
{item.pendingWorkflow?.task?.id ? (
<div className="rounded-lg border border-amber-200 bg-amber-50 px-3 py-2 text-xs text-amber-700">
当前待办:{item.pendingWorkflow.task.stepName}
</div>
) : null}
<div className="flex items-center gap-2 pt-1">
{batchMode ? (
<label className="flex min-h-10 items-center gap-2 rounded-lg border border-zinc-200 px-3 text-sm text-zinc-700">
<input
type="checkbox"
checked={selectedReimbursementIds.includes(item.id)}
disabled={!canSelectRow}
onChange={() => toggleBatchSelection(item.id)}
aria-label={`选择报销单 ${item.formNumber ?? item.id}`}
/>
选择
</label>
) : null}
<Button asChild className="min-h-10 flex-1" size="sm" variant="secondary">
<Link
to={`/reimbursements/${item.id}`}
data-testid="reimbursement-mobile-detail-link"
>
{actionLabel}
</Link>
</Button>
</div>
</article>
);
})
) : (
<div className="rounded-xl border border-dashed border-zinc-300 px-4 py-8 text-center text-sm text-zinc-500">
暂无数据
</div>
)}
</div>
<PrimaryTable className="hidden md:block">
<table className="w-full border-collapse text-left" data-testid="reimbursements-table">
<thead className="table-header">
<tr>