/** * 地区数据模块级单例缓存。 * 首次调用时 fetch /region.csv 并构建 idMap 和 parentMap, * 后续调用直接返回缓存,SPA 生命周期内只加载一次。 */ interface RegionItem { id: number; parentId: number; level: number; name: string; } interface RegionCache { /** id → RegionItem,用于表格列的 id→name 转换 */ idMap: Map; /** parentId → children[],用于省/市/区下拉联动 O(1) 查找 */ parentMap: Map; /** 所有地区平铺数组 */ list: RegionItem[]; } let _cache: RegionCache | null = null; function parseCSV(text: string): RegionItem[] { const lines = text.split("\n").filter((l) => l.trim()); const headers = lines[0].split(",").map((h) => h.trim()); return lines.slice(1).map((line) => { const cols = line.split(",").map((c) => c.trim()); const obj: any = {}; headers.forEach((h, i) => { obj[h] = h === "name" ? cols[i] : Number(cols[i]); }); return obj as RegionItem; }); } export async function useRegionCache(): Promise { if (_cache) return _cache; const res = await fetch("/region.csv"); if (!res.ok) throw new Error("地区数据加载失败"); const text = await res.text(); const list = parseCSV(text); const idMap = new Map(); const parentMap = new Map(); for (const item of list) { idMap.set(item.id, item); if (!parentMap.has(item.parentId)) { parentMap.set(item.parentId, []); } parentMap.get(item.parentId)!.push(item); } _cache = { idMap, parentMap, list }; return _cache; }