dict.ts
2.28 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
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<Record<string, DictDataVO[]>>({})
/** 正在请求中的 dictType,避免并发重复请求 */
const loading = new Set<string>()
async function loadDict(dictType: string): Promise<DictDataVO[]> {
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 }
})