import { Fragment, useMemo, useState } from "react"; import { ChevronDown, ChevronRight, ChevronsDownUp, ListFilter, Search, X, ArrowUpRight, } from "lucide-react"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; import type { RegionalInventoryStats } from "../types"; import { Picker, unique, useMobile } from "./shared"; import { ExportButton } from "./export"; import { InventoryExplorer } from "./InventoryExplorer"; import { groupInventory, INVENTORY_TYPES, inventoryColumn, inventoryTotals, type InventoryScope, } from "./inventory-view"; type Inspect = (scope: InventoryScope) => void; export function InventoryNumber({ rows, label, inspect, }: { rows: RegionalInventoryStats[]; label: string; inspect: Inspect; }) { const total = inventoryTotals(rows); if (!total.quantity) return 0; return (
{(total.pending > 0 || total.abnormal > 0) && (
{total.pending > 0 && ( )} {total.abnormal > 0 && ( )}
)}
); } export function InventorySection({ inventory, inspect, subject, }: { subject: string | null; inventory: RegionalInventoryStats[]; inspect: Inspect; }) { const mobile = useMobile(); const [query, setQuery] = useState(""); const [filters, setFilters] = useState({ region: "", city: "", brand: "" }); const [filterOpen, setFilterOpen] = useState(false); const [expanded, setExpanded] = useState>(new Set()); const [expandedType, setExpandedType] = useState(""); const filtered = useMemo( () => inventory.filter( (row) => Object.entries(filters).every( ([key, value]) => !value || row[key as keyof typeof filters] === value, ) && (!query.trim() || [ row.region, row.city, row.brand, row.type, row.model, inventoryColumn(row.type), ] .join(" ") .toLowerCase() .includes(query.trim().toLowerCase())), ), [inventory, filters, query], ); const rows = filtered; const groups = groupInventory(rows, "region"); const brands = unique( filtered .filter((row) => inventoryColumn(row.type) === expandedType) .map((row) => row.brand), ); const hasBrandColumns = Boolean(expandedType) && brands.length > 0; const columns = INVENTORY_TYPES.flatMap((type) => [ { key: type, title: expandedType === type && brands.length ? "小计" : type, type, brand: "", }, ...(expandedType === type ? brands.map((brand) => ({ key: `${type}-${brand}`, title: brand, type, brand, })) : []), ]); const activeCount = Object.values(filters).filter(Boolean).length; const total = inventoryTotals(rows); const toggleRegion = (region: string) => setExpanded((old) => { const next = new Set(old); if (next.has(region)) next.delete(region); else next.add(region); return next; }); const cellRows = ( records: RegionalInventoryStats[], type: string, brand: string, ) => records.filter( (row) => inventoryColumn(row.type) === type && (!brand || row.brand === brand), ); const renderCells = (records: RegionalInventoryStats[], label: string) => ( <> {columns.map((col) => ( ))} ); if (mobile) return ; return (

库存统计

地区 × 车型总览,展开城市核对库存

{query || activeCount ? "筛选库存" : "总库存"}
inventoryColumn(String(value)), }, { key: "model", label: "原始型号" }, { key: "quantity", label: "库存" }, { key: "available", label: "可运营" }, { key: "awaiting", label: "待运营" }, { key: "abnormal", label: "异动" }, { key: "pending", label: "待交车" }, ]} filename="库存统计" sheetName="库存" />
{filterOpen && (
row.region))} change={(region) => setFilters((old) => ({ ...old, region, city: "" })) } /> !filters.region || row.region === filters.region, ) .map((row) => row.city), )} change={(city) => setFilters((old) => ({ ...old, city }))} /> row.brand))} change={(brand) => setFilters((old) => ({ ...old, brand }))} />
)} {activeCount > 0 && (
{Object.values(filters).filter(Boolean).join(" / ")}
)}
{INVENTORY_TYPES.map((type) => { const counts = inventoryTotals(cellRows(rows, type, "")); return ( ); })}
地区合计与车型合计均为当前筛选范围 点击车型展开品牌 · 点击数字查看明细
{!rows.length ? (
暂无匹配库存

尝试切换车型或调整筛选条件

) : (
{INVENTORY_TYPES.map((type) => ( ))} {hasBrandColumns && ( {brands.map((brand) => ( ))} )} {groups.map((group) => ( {renderCells( group.cities.flatMap((city) => city.rows), group.name, )} {expanded.has(group.name) && group.cities.map((city) => ( {renderCells(city.rows, `${group.name} / ${city.name}`)} ))} ))} {renderCells(rows, "当前库存合计")}
区域展开城市,车型展开品牌,点击库存数量查看构成与车辆明细
区域 / 城市 总库存
小计 {brand}
{city.name}
当前范围合计
)}
); }