import { useMemo, useState } from "react"; import { Link, useLocation, useSearchParams } from "react-router-dom"; import { useQuery } from "@tanstack/react-query"; import { fetchPurchaseRequests, type PurchaseRequestStatus, type PurchaseRequestSummary, } from "../api/purchaseRequests"; import { PageHeader } from "../components/common/PageHeader"; import { StatusBadge } from "../components/common/StatusBadge"; import { PageScaffold } from "../components/patterns/PageScaffold"; import { Tabs, TabsList, TabsTrigger } from "../components/ui/tabs"; import { resolvePurchaseDisplayCode } from "../lib/approvalDisplay"; import { joinBusinessMeta } from "../lib/businessDisplay"; import { resolveErrorMessage } from "../lib/resolveErrorMessage"; const STATUS_TABS: Array<{ value: PurchaseRequestStatus; label: string }> = [ { value: "draft", label: "草稿" }, { value: "reviewing", label: "审批中" }, { value: "approved", label: "已通过" }, { value: "rejected", label: "已驳回" }, { value: "cancelled", label: "已取消" }, ]; function isPurchaseStatus(value: string | null): value is PurchaseRequestStatus { return ["draft", "reviewing", "approved", "rejected", "cancelled"].includes(value ?? ""); } function formatCurrency(value: string | null | undefined, currencyCode = "CNY") { const amount = Number(value ?? 0); if (!Number.isFinite(amount)) { return "-"; } return new Intl.NumberFormat("zh-CN", { style: "currency", currency: currencyCode }).format(amount); } function formatDate(value: string | null | undefined) { return value ? value.slice(0, 10) : "-"; } function PurchaseRequestCard({ item, currentMobileSource, }: { item: PurchaseRequestSummary; currentMobileSource: string; }) { const displayCode = resolvePurchaseDisplayCode(item); return (
{displayCode}
{joinBusinessMeta([ item.title || null, item.applicant?.name ? `申请人:${item.applicant.name}` : null, item.updatedAt ? `更新:${formatDate(item.updatedAt)}` : null, ])}
{joinBusinessMeta([ `金额:${formatCurrency(item.totalAmount, item.currencyCode)}`, item.supplier?.name ? `供应商:${item.supplier.name}` : null, item.expectedDeliveryDate ? `到货:${formatDate(item.expectedDeliveryDate)}` : null, ])}
); } export function MobilePurchaseRequestsPage() { const location = useLocation(); const [searchParams, setSearchParams] = useSearchParams(); const [status, setStatus] = useState(() => { const queryStatus = searchParams.get("status"); return isPurchaseStatus(queryStatus) ? queryStatus : "draft"; }); const currentMobileSource = useMemo(() => { const params = new URLSearchParams(location.search); params.set("status", status); const query = params.toString(); return `${location.pathname}${query ? `?${query}` : ""}`; }, [location.pathname, location.search, status]); const listQuery = useQuery({ queryKey: ["mobile", "purchase-requests", status], queryFn: () => fetchPurchaseRequests({ mine: true, status, page: 1, pageSize: 20 }), }); function handleStatusChange(value: string) { if (!isPurchaseStatus(value)) { return; } setStatus(value); const nextParams = new URLSearchParams(searchParams); nextParams.set("status", value); setSearchParams(nextParams, { replace: true }); } const items = listQuery.data?.items ?? []; const totalAmount = useMemo( () => items.reduce((sum, item) => sum + Number(item.totalAmount ?? 0), 0), [items], ); return (
当前列表
{listQuery.data?.total ?? 0}
当前金额
{formatCurrency(String(totalAmount))}
{STATUS_TABS.map((item) => ( {item.label} ))}
{listQuery.isLoading ?
加载中...
: null} {listQuery.isError ? (
{resolveErrorMessage(listQuery.error)}
) : null} {!listQuery.isLoading && !listQuery.isError && !items.length ? (
暂无采购申请
) : null} {items.map((item) => ( ))}
); } export default MobilePurchaseRequestsPage;