Browse Source

feat: 新增字典映射功能

lujialiang 2 weeks ago
parent
commit
c967332684
2 changed files with 76 additions and 1 deletions
  1. 2 1
      src/enum/index.ts
  2. 74 0
      src/store/modules/dict/index.ts

+ 2 - 1
src/enum/index.ts

@@ -3,5 +3,6 @@ export enum SetupStoreId {
   Theme = 'theme-store',
   Auth = 'auth-store',
   Route = 'route-store',
-  Tab = 'tab-store'
+  Tab = 'tab-store',
+  Dict = 'dict-store'
 }

+ 74 - 0
src/store/modules/dict/index.ts

@@ -0,0 +1,74 @@
+import { defineStore } from 'pinia';
+import { reactive } from 'vue';
+import { SetupStoreId } from '@/enum';
+import { getDicts } from '@/service/api';
+
+interface dictItem {
+  label: string;
+  value: string;
+}
+
+interface StoreState {
+  dictionaries: { [key: string]: dictItem[] };
+  loading: boolean;
+  errors: Error | null;
+  pendingRequests: Map<any, any>;
+}
+
+export const useDictStore = defineStore(SetupStoreId.Dict, () => {
+  const store = reactive<StoreState>({
+    dictionaries: {},
+    loading: false,
+    errors: null,
+    pendingRequests: new Map() // 用于跟踪正在进行的请求
+  });
+  async function loadDict(type: string) {
+    if (store.dictionaries[type]) return store.dictionaries[type];
+
+    // 检查是否有正在进行的相同请求
+    if (store.pendingRequests.has(type)) {
+      return store.pendingRequests.get(type);
+    }
+
+    store.loading = true;
+    store.errors = null;
+
+    // 创建一个新的 Promise 来跟踪这个请求
+    const requestPromise = getDicts(type)
+      .then(({ data }) => {
+        store.dictionaries[type] = data;
+        return data;
+      })
+      .catch(error => {
+        store.errors = error;
+        throw error;
+      })
+      .finally(() => {
+        store.loading = false;
+        store.pendingRequests.delete(type); // 请求完成后移除
+      });
+
+    // 将请求存储在 pendingRequests 中
+    store.pendingRequests.set(type, requestPromise);
+
+    // 返回请求的 Promise
+    return requestPromise;
+  }
+
+  function findNameByValue(options: dictItem[], value: string, separator: string = ',') {
+    return options.flatMap(option => (option.value === value ? option.label : [])).join(separator);
+  }
+
+  function findNameByDict(dictKey: string, value: string, separator: string = ',') {
+    if (store.dictionaries[dictKey]) {
+      return findNameByValue(store.dictionaries[dictKey], value, separator);
+    }
+    loadDict(dictKey);
+    return '-';
+  }
+  return {
+    loadDict,
+    findNameByDict,
+    findNameByValue
+  };
+});