import { defineStore } from 'pinia' import { DictDataApi, type DictDataVO } from '@/api/system/dict' export type { DictDataVO } /** * 字典 store:把字典项缓存在内存,页面用 getDictOptions / getDictLabel 取 * * 数据来源 `/admin-api/system/dict-data/list?dictType=xxx`(不分页)。 * * ⚠️ 取字典是**异步**的:`getDictOptions()` 首次调用只返回 `[]` 并触发加载, * 数据回来后靠 `dictMap` 的响应式更新驱动依赖它的 computed 重算。 * 所以调用方必须写在 `computed` 里(如 `DictTag` 组件), * **不能在 `onMounted` 里调一次再把结果存进普通变量**——那样拿到的是空数组。 * * ⚠️ 请求失败被静默吞掉并缓存为空数组:字典加载失败不应该让整个页面报错, * `getDictLabel` 找不到就回退成原始值(数字/字符串原样显示)。 */ export const useDictStore = defineStore('dict', () => { /** dictType → 字典项 */ const dictMap = ref>({}) /** 正在请求中的 dictType,避免并发重复请求 */ const loading = new Set() async function loadDict(dictType: string): Promise { if (!dictType) return [] if (dictMap.value[dictType]) return dictMap.value[dictType] if (loading.has(dictType)) return [] loading.add(dictType) try { const list = await DictDataApi.getDictDataList(dictType) dictMap.value[dictType] = list || [] } catch (e) { dictMap.value[dictType] = [] } finally { loading.delete(dictType) } return dictMap.value[dictType] } function getDictOptions(dictType: string): DictDataVO[] { if (!dictMap.value[dictType]) loadDict(dictType) return dictMap.value[dictType] || [] } /** 取字典显示文案;没有字典时回退原始值 */ function getDictLabel(dictType: string, value: any): string { if (value === undefined || value === null || value === '') return '' const item = getDictOptions(dictType).find((d) => String(d.value) === String(value)) return item ? item.label : String(value) } /** 清空缓存(登出、或字典页增删改后强制重取) */ function reset() { dictMap.value = {} } return { dictMap, loadDict, getDictOptions, getDictLabel, reset } })