优化财务与管理页视觉 Wave4(05-27-pc-finance-admin-visual-wave4)

这个提交包含在:
2026-05-27 22:23:45 +08:00
父节点 8b3db8fa4e
当前提交 c5eb27eac8
共修改 18 个文件,包含 1379 行新增和 96 行删除
+21 -7
查看文件
@@ -40,6 +40,13 @@ export function WorkflowDefinitionsPage() {
const items = listQuery.data?.items ?? [];
const scopedItems = useMemo(() => items.filter((item) => item.entityType === entityType), [items, entityType]);
const selected = useMemo(() => scopedItems.find((item) => item.id === selectedId) ?? scopedItems[0] ?? null, [scopedItems, selectedId]);
const workflowStats = {
total: items.length,
scoped: scopedItems.length,
draft: items.filter((item) => item.status === "draft").length,
published: items.filter((item) => item.status === "published").length,
archived: items.filter((item) => item.status === "archived").length,
};
useEffect(() => {
if (!selected) return;
@@ -86,9 +93,16 @@ export function WorkflowDefinitionsPage() {
return (
<ListWorkspace>
<WorkspaceHeader title="流程定义" subtitle="线性流程的版本化治理;报销继续由审批规则投影。" />
<div className="grid gap-6 xl:grid-cols-[220px,280px,1fr]">
<div className="card-std space-y-3 p-4 md:p-5">
<WorkspaceHeader title="流程定义" subtitle="线性流程版本治理,发布动作需确认。" />
<div className="finance-status-strip" data-testid="workflow-definitions-summary">
<div className="finance-metric-card"><div className="finance-metric-card__label">定义总数</div><div className="finance-metric-card__value">{workflowStats.total}</div></div>
<div className="finance-metric-card"><div className="finance-metric-card__label">当前业务域</div><div className="finance-metric-card__value">{workflowStats.scoped}</div></div>
<div className="finance-metric-card"><div className="finance-metric-card__label">草稿</div><div className="finance-metric-card__value">{workflowStats.draft}</div></div>
<div className="finance-metric-card"><div className="finance-metric-card__label">已发布</div><div className="finance-metric-card__value">{workflowStats.published}</div></div>
<div className="finance-metric-card"><div className="finance-metric-card__label">已归档</div><div className="finance-metric-card__value">{workflowStats.archived}</div></div>
</div>
<div className="admin-workspace-grid">
<div className="admin-command-panel space-y-3">
<Label>业务域</Label>
<select className="select-std" value={entityType} onChange={(event) => setEntityType(event.target.value as WorkflowDefinitionEditorModel["entityType"])}>
{ENTITY_TYPES.map((item) => <option key={item} value={item}>{item}</option>)}
@@ -96,11 +110,11 @@ export function WorkflowDefinitionsPage() {
{entityType !== "reimbursement" ? <Button type="button" onClick={() => createMutation.mutate()}>创建草稿</Button> : null}
</div>
<div className="card-std space-y-3 p-4 md:p-5">
<div className="admin-command-panel space-y-3">
<h3 className="text-base font-semibold text-zinc-900">版本列表</h3>
<div className="space-y-2">
{scopedItems.map((item) => (
<button key={item.id} type="button" className={selected?.id === item.id ? "w-full rounded-lg border border-primary bg-primary/5 px-3 py-3 text-left" : "w-full rounded-lg border border-zinc-200 px-3 py-3 text-left hover:bg-zinc-50"} onClick={() => setSelectedId(item.id)}>
<button key={item.id} type="button" className={selected?.id === item.id ? "finance-list-card finance-list-card--active" : "finance-list-card"} onClick={() => setSelectedId(item.id)}>
<div className="font-medium text-zinc-900">v{item.version} · {item.name}</div>
<div className="text-xs text-zinc-500">{item.status} · {item.source}</div>
</button>
@@ -109,7 +123,7 @@ export function WorkflowDefinitionsPage() {
</div>
</div>
<div className="card-std space-y-4 p-4 md:p-5">
<div className="admin-command-panel space-y-4">
{selected ? (
<>
<div className="flex flex-wrap items-center justify-between gap-3">
@@ -157,7 +171,7 @@ export function WorkflowDefinitionsPage() {
</div>
<div className="space-y-3">
{steps.map((step, index) => (
<div key={step.id} className="rounded-lg border border-zinc-200 p-4">
<div key={step.id} className="detail-evidence-card">
<div className="grid gap-3 md:grid-cols-3">
<Input value={step.id} disabled={selected.status !== "draft"} onChange={(event) => setSteps((prev) => prev.map((item, itemIndex) => itemIndex === index ? { ...item, id: event.target.value } : item))} />
<Input value={step.name} disabled={selected.status !== "draft"} onChange={(event) => setSteps((prev) => prev.map((item, itemIndex) => itemIndex === index ? { ...item, name: event.target.value } : item))} />