Files
weather-data/weather-data-ui/src/composables/useRegionCache.ts
T

60 lines
1.6 KiB
TypeScript
Raw Normal View History

/**
* 地区数据模块级单例缓存。
* 首次调用时 fetch /region.csv 并构建 idMap 和 parentMap
* 后续调用直接返回缓存,SPA 生命周期内只加载一次。
*/
interface RegionItem {
id: number;
parentId: number;
level: number;
name: string;
}
interface RegionCache {
/** id → RegionItem,用于表格列的 id→name 转换 */
idMap: Map<number, RegionItem>;
/** parentId → children[],用于省/市/区下拉联动 O(1) 查找 */
parentMap: Map<number, RegionItem[]>;
/** 所有地区平铺数组 */
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<RegionCache> {
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<number, RegionItem>();
const parentMap = new Map<number, RegionItem[]>();
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;
}