浏览代码

feat: 字典回显

Gaokun Wang 3 周之前
父节点
当前提交
a261015d62

+ 17 - 1
src/api/module/system/dict.ts

@@ -11,13 +11,29 @@ class DictApi {
   }
 
   /**
-   * @name 查询列表
+   * @name 查询分页
    * @returns returns
    */
   static page = (params: DictQuery): Promise<ResultData<any>> => {
     return http.get<DictVO>({ url: '/system/dict/page', params })
   }
 
+  /**
+   * @name 查询列表
+   * @returns returns
+   */
+  static list = (params: DictBo): Promise<ResultData<any>> => {
+    return http.get<DictVO>({ url: '/system/dict/list', params })
+  }
+
+  /**
+   * @name 查询列表
+   * @returns returns
+   */
+  static map = (): Promise<ResultData<any>> => {
+    return http.get<DictVO>({ url: '/system/dict/map' })
+  }
+
   /**
    * @name 添加
    * @returns returns

+ 4 - 2
src/components/TreeFilter/index.vue

@@ -11,7 +11,7 @@
       <el-tree
         v-if="reload"
         ref="treeRef"
-        default-expand-all
+        :default-expand-all="expandAll"
         :node-key="id"
         :data="multiple ? treeData : treeAllData"
         :show-checkbox="multiple"
@@ -51,13 +51,15 @@ interface OrgTreeProps {
   label?: string // 显示的label ==> 非必传,默认为 “label”
   multiple?: boolean // 是否为多选 ==> 非必传,默认为 false
   defaultValue?: any // 默认选中的值 ==> 非必传
+  expandAll?: boolean // 展开所有节点
 }
 const loading = ref(false)
 
 const props = withDefaults(defineProps<OrgTreeProps>(), {
   id: 'id',
   label: 'label',
-  multiple: false
+  multiple: false,
+  expandAll: false
 })
 
 const defaultProps = {

+ 1 - 0
src/hooks/index.ts

@@ -1,2 +1,3 @@
 export * from './useTable'
 export * from './useSelection'
+export * from './useDictOptions'

+ 13 - 0
src/hooks/useDictOptions.ts

@@ -0,0 +1,13 @@
+import { computed } from 'vue'
+import { useOptionsStore } from '@/stores/modules/options'
+import { DictVO } from '@/api/interface/system/dict'
+
+/**
+ * 自定义 Hook,用于从 store 中获取字典选项
+ * @param dictName 字典名称
+ * @returns 返回字典选项
+ */
+export const useDictOptions = (dictLabel: string) => {
+  const optionsStore = useOptionsStore()
+  return computed<DictVO[]>(() => optionsStore.getDictOptions(dictLabel) || [])
+}

+ 4 - 1
src/router/modules/dynamicRouter.ts

@@ -1,6 +1,7 @@
 import { LOGIN_URL } from '@/constants'
 import router from '@/router'
 import { useAuthStore, useUserStore } from '@/stores'
+import { useOptionsStore } from '@/stores/modules/options'
 import type { RouteRecordRaw } from 'vue-router'
 
 // 引入 views 文件夹下所有 vue 文件
@@ -12,12 +13,14 @@ const modules = import.meta.glob('@/views/**/*.vue')
 export const initDynamicRouter = async () => {
   const userStore = useUserStore()
   const authStore = useAuthStore()
+  const optionsStore = useOptionsStore()
 
   try {
     if (authStore.isLoaded) return
     await authStore.setMenuList()
+    optionsStore.setReloadOptions()
+    await optionsStore.setAllDictMap()
     await authStore.setLoaded()
-
     // 3.添加动态路由
     authStore.flatMenuListGet.forEach((item: Menu.MenuOptions) => {
       if (item.children) delete item.children

+ 19 - 3
src/stores/modules/options.ts

@@ -1,12 +1,28 @@
 import { DictVO } from '@/api/interface/system/dict'
 import { pinia } from '../index'
-export const useOptionsStore = defineStore('eco-keep-alive', {
+import DictApi from '@/api/module/system/dict'
+export const useOptionsStore = defineStore('eco-dict-options', {
   state: () => ({
     isLoaded: false as boolean,
     dictOptions: {} as Record<string, DictVO[]>
   }),
-  getters: {},
-  actions: {},
+  getters: {
+    getDictOptionsAll: state => state.dictOptions
+  },
+  actions: {
+    async setAllDictMap() {
+      if (this.isLoaded) return
+      const { data } = await DictApi.map()
+      this.dictOptions = data
+      this.isLoaded = true
+    },
+    getDictOptions(dictLabel: string) {
+      return this.dictOptions[dictLabel] || []
+    },
+    setReloadOptions() {
+      this.isLoaded = false
+    }
+  },
   persist: true
 })
 

+ 20 - 51
src/views/system/dict/components/DictDrawer.vue

@@ -10,14 +10,7 @@
       </slot>
     </template>
 
-    <el-form
-      ref="ruleFormRef"
-      label-width="100px"
-      label-suffix=" :"
-      label-position="top"
-      :rules="rules"
-      :model="drawerProps.row"
-      @submit.enter.prevent="handleConfirm">
+    <el-form ref="ruleFormRef" label-width="100px" label-suffix=" :" :rules="rules" :model="drawerProps.row" @submit.enter.prevent="handleConfirm">
       <el-form-item label="上级字典" prop="parentId">
         <el-tree-select
           v-model="drawerProps.row.parentId"
@@ -29,6 +22,11 @@
           :default-expand-all="true"
           :props="treeProps" />
       </el-form-item>
+      <el-form-item label="字典类型" prop="category">
+        <el-radio-group v-model="drawerProps.row.category">
+          <el-radio-button :value="item.dictValue" v-for="(item, index) in dictTypes" :key="index" :label="item.dictLabel" />
+        </el-radio-group>
+      </el-form-item>
       <el-form-item label="字典标签" prop="dictLabel">
         <el-input v-model="drawerProps.row.dictLabel" placeholder="字典标签" clearable />
       </el-form-item>
@@ -39,16 +37,15 @@
         <el-input-number v-model="drawerProps.row.orderNum" :precision="0" :min="1" :max="999999" />
       </el-form-item>
       <el-form-item label="状态" prop="status">
-        <el-radio-group v-model="drawerProps.row.status" default-value="1">
-          <el-radio-button label="启用" value="1" />
-          <el-radio-button label="停用" value="0" />
+        <el-radio-group v-model="drawerProps.row.status">
+          <el-radio-button :value="item.dictValue" v-for="(item, index) in commonStatus" :key="index" :label="item.dictLabel" />
         </el-radio-group>
       </el-form-item>
       <el-form-item label="回显样式" prop="callbackShowStyle">
         <el-radio-group v-model="drawerProps.row.callbackShowStyle">
-          <el-radio :value="item.value" v-for="item in tagsTypeOptions" :key="item.label">
-            <el-tag :type="item.value">
-              {{ item.label }}
+          <el-radio :value="item.dictValue" v-for="item in callbackShowStyles" :key="item.dictLabel" :label="item.dictLabel">
+            <el-tag :type="item.dictValue">
+              {{ item.dictLabel }}
             </el-tag>
           </el-radio>
         </el-radio-group>
@@ -71,46 +68,19 @@
 import { DictBo, DictTreeVO } from '@/api/interface/system/dict'
 import DictApi from '@/api/module/system/dict'
 import { ResultEnum } from '@/enums/HttpEnum'
-export interface Options {
-  id?: number
-  label: string
-  value: string
-}
-/**
- * 标签类型
- * @type {[Options,Options]}
- */
-const tagsTypeOptions: Options[] = [
-  {
-    id: 1,
-    label: 'Default',
-    value: 'primary'
-  },
-  {
-    id: 2,
-    label: 'Success',
-    value: 'success'
-  },
-  {
-    id: 3,
-    label: 'Info',
-    value: 'info'
-  },
-  {
-    id: 4,
-    label: 'Warning',
-    value: 'warning'
-  },
-  {
-    id: 5,
-    label: 'Danger',
-    value: 'danger'
-  }
-]
+import { useDictOptions } from '@/hooks'
+
+const commonStatus = useDictOptions('COMMON_STATUS')
+const callbackShowStyles = useDictOptions('CALLBACK_SHOW_STYLE')
+const dictTypes = useDictOptions('DICT_TYPE')
+
 import { FormInstance } from 'element-plus'
 const rules = reactive({
   name: [{ required: true, message: '请填写组织名称' }],
   parentId: [{ required: true, message: '请选择上级' }],
+  dictLabel: [{ required: true, message: '请填写字典标签' }],
+  dictValue: [{ required: true, message: '请填写字典值' }],
+  category: [{ required: true, message: '请选择字典类型' }],
   orderNum: [{ required: true, message: '排序不能为空' }],
   status: [{ required: true, message: '状态不能为空' }]
 })
@@ -144,7 +114,6 @@ const acceptParams = (params: EcoDrawerProps) => {
   drawerProps.value = params
   drawerVisible.value = true
   loadTree()
-  console.log(drawerProps.value.row.parentId)
 }
 
 const loadTree = () => {

+ 10 - 1
src/views/system/dict/index.vue

@@ -23,7 +23,7 @@
         </template>
       </ProTable>
     </div>
-    <DictDrawer ref="drawerRef" @submit="refreshTree" />
+    <DictDrawer ref="drawerRef" @submit="refreshTree" size="40%" />
   </div>
 </template>
 <script lang="tsx" setup name="DIctManage">
@@ -33,6 +33,7 @@ import DictDrawer from './components/DictDrawer.vue'
 import TreeFilter from '@/components/TreeFilter/index.vue'
 import { ColumnProps, ProTableInstance, SearchProps } from '@/components/ProTable/interface'
 import { OrgFormBo } from '@/api/interface/system/org'
+import { useDictOptions } from '@/hooks'
 const initParam = reactive({ dictId: '', parentId: '' })
 
 const selectTreeId = ref<string>('')
@@ -58,6 +59,14 @@ const columns: ColumnProps<RoleInfo>[] = [
   { type: 'selection', width: 60 },
   { prop: 'dictLabel', label: '字典标签' },
   { prop: 'dictValue', label: '字典值' },
+  {
+    prop: 'status',
+    label: '状态',
+    tag: true,
+    enum: useDictOptions('COMMON_STATUS'),
+    width: 80,
+    fieldNames: { label: 'dictLabel', value: 'status', tagType: 'callbackShowStyle' }
+  },
   { prop: 'orderNum', label: '排序' },
   { prop: 'remark', label: '备注' },
   { prop: 'createByName', label: '创建人' },

+ 5 - 4
src/views/system/org/components/OrgDrawer.vue

@@ -29,9 +29,8 @@
         <el-input-number v-model="drawerProps.row.orderNum" :precision="0" :min="1" :max="999999" />
       </el-form-item>
       <el-form-item label="状态" prop="status">
-        <el-radio-group v-model="drawerProps.row.status">
-          <el-radio-button label="启用" value="1" />
-          <el-radio-button label="停用" value="0" />
+        <el-radio-group v-model="drawerProps.row.status" default-value="1">
+          <el-radio-button :value="item.dictValue" v-for="(item, index) in commonStatus" :key="index" :label="item.dictLabel" />
         </el-radio-group>
       </el-form-item>
       <el-form-item label="负责人" prop="leader">
@@ -55,8 +54,10 @@
 import { OrgTreeVO, OrgFormBo } from '@/api/interface/system/org'
 import OrgApi from '@/api/module/system/org'
 import { ResultEnum } from '@/enums/HttpEnum'
-
 import { FormInstance } from 'element-plus'
+import { useDictOptions } from '@/hooks'
+
+const commonStatus = useDictOptions('COMMON_STATUS')
 const rules = reactive({
   name: [{ required: true, message: '请填写组织名称' }],
   parentId: [{ required: true, message: '请选择上级' }],