| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182 |
- import { ref } from 'vue';
- import { useSystemApi } from '@/api/system';
- export interface DictItem {
- dictType: string;
- dictValue: string;
- dictLabel: string;
- isDefault?: number;
- }
- // 字典全局缓存,避免多页面或多组件切换时重复请求
- const dictCache = new Map<string, DictItem[]>();
- const pendingRequests = new Map<string, Promise<DictItem[]>>();
- /**
- * 获取系统字典并提供回显方法的 Hook
- * @param args 字典类型参数数组,例如: 'sci_leader_type', 'sys_user_sex'
- * @returns { dicts, getDictLabel }
- */
- export function useDict(...args: string[]) {
- const { getDictDataByType } = useSystemApi();
-
- // 用于响应式绑定到视图的字典集合
- const dicts = ref<Record<string, DictItem[]>>({});
- args.forEach((dictType) => {
- // 默认初始化为空数组,防页面渲染时为空报错
- dicts.value[dictType] = [];
-
- // 如果已有缓存,直接使用缓存
- if (dictCache.has(dictType)) {
- dicts.value[dictType] = dictCache.get(dictType)!;
- } else {
- // 如果没有缓存,检查是否在请求中,避免并发时重复请求相同的字典
- let req = pendingRequests.get(dictType);
- if (!req) {
- req = getDictDataByType(dictType)
- .then((res: any) => {
- // 解析出字典数组列表 (兼容不同拦截器返回的结构)
- const values = res?.data?.values || [];
- // 存入缓存
- dictCache.set(dictType, values);
- return values;
- })
- .catch((err: any) => {
- console.error(`获取字典 [${dictType}] 失败:`, err);
- return [];
- })
- .finally(() => {
- // 请求结束,无论成功或失败都清除 pending 状态
- pendingRequests.delete(dictType);
- });
- pendingRequests.set(dictType, req);
- }
-
- // 等待请求结束并赋值给响应式对象
- req.then((values: DictItem[]) => {
- dicts.value[dictType] = values;
- });
- }
- });
- /**
- * 字典回显方法
- * @param dictType 字典类型
- * @param dictValue 字典值
- * @returns 匹配的字典标签 (dictLabel),如果没有匹配到则返回原值
- */
- const getDictLabel = (dictType: string, dictValue: string | number | undefined | null) => {
- if (dictValue === undefined || dictValue === null || dictValue === '') {
- return '';
- }
- const list = dicts.value[dictType] || dictCache.get(dictType) || [];
- const item = list.find((item: DictItem) => item.dictValue == dictValue);
- return item ? item.dictLabel : dictValue;
- };
- return {
- dicts,
- getDictLabel,
- };
- }
|