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

这个提交包含在:
2026-05-27 22:23:45 +08:00
父节点 8b3db8fa4e
当前提交 c5eb27eac8
共修改 18 个文件,包含 1379 行新增和 96 行删除
+35 -2
查看文件
@@ -1,4 +1,4 @@
import { useEffect, useRef, useState } from "react";
import { useEffect, useMemo, useRef, useState } from "react";
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import { isApiError } from "../api/types";
import { mapApiErrorMessage } from "../api/errorMessages";
@@ -436,6 +436,16 @@ export function InvoicePoolPage() {
const totalPages = Math.max(1, Math.ceil((listQuery.data?.total ?? 0) / PAGE_SIZE));
const detail = detailQuery.data;
const invoiceStats = useMemo(() => {
const items = listQuery.data?.items ?? [];
return {
total: listQuery.data?.total ?? 0,
pending: items.filter((item) => item.status === "pending_ocr").length,
failed: items.filter((item) => item.status === "ocr_failed").length,
available: items.filter((item) => item.status === "available").length,
bound: items.filter((item) => item.status === "bound").length,
};
}, [listQuery.data?.items, listQuery.data?.total]);
const canEditDetail = Boolean(
detail &&
(canManageInvoice ||
@@ -449,7 +459,7 @@ export function InvoicePoolPage() {
<ListWorkspace>
<WorkspaceHeader
title="票据中心"
subtitle="上传、识别、绑定。"
subtitle="上传、识别、绑定和异常复核集中处理。"
actions={
<DropdownMenu>
<DropdownMenuTrigger asChild>
@@ -480,6 +490,29 @@ export function InvoicePoolPage() {
</p>
) : null}
<div className="finance-status-strip" data-testid="invoice-pool-summary">
<div className="finance-metric-card">
<div className="finance-metric-card__label">票据总数</div>
<div className="finance-metric-card__value">{invoiceStats.total}</div>
</div>
<div className="finance-metric-card">
<div className="finance-metric-card__label">识别中</div>
<div className="finance-metric-card__value">{invoiceStats.pending}</div>
</div>
<div className="finance-metric-card">
<div className="finance-metric-card__label">识别失败</div>
<div className="finance-metric-card__value">{invoiceStats.failed}</div>
</div>
<div className="finance-metric-card">
<div className="finance-metric-card__label">可绑定</div>
<div className="finance-metric-card__value">{invoiceStats.available}</div>
</div>
<div className="finance-metric-card">
<div className="finance-metric-card__label">已绑定</div>
<div className="finance-metric-card__value">{invoiceStats.bound}</div>
</div>
</div>
<InvoiceUploadCard
selectedFiles={selectedFiles}
setSelectedFiles={setSelectedFiles}