Browse Source

使用vue-data-dict简化数据字典使用

RuoYi 4 years ago
parent
commit
a10384c009
28 changed files with 505 additions and 326 deletions
  1. 22 0
      ruoyi-modules/ruoyi-gen/src/main/java/com/ruoyi/gen/util/VelocityUtils.java
  2. 21 34
      ruoyi-modules/ruoyi-gen/src/main/resources/vm/vue/index-tree.vue.vm
  3. 21 34
      ruoyi-modules/ruoyi-gen/src/main/resources/vm/vue/index.vue.vm
  4. 21 0
      ruoyi-ui/src/components/DictData/index.js
  5. 10 10
      ruoyi-ui/src/components/DictTag/index.vue
  6. 3 0
      ruoyi-ui/src/main.js
  7. 82 0
      ruoyi-ui/src/utils/dict/Dict.js
  8. 17 0
      ruoyi-ui/src/utils/dict/DictConverter.js
  9. 13 0
      ruoyi-ui/src/utils/dict/DictData.js
  10. 38 0
      ruoyi-ui/src/utils/dict/DictMeta.js
  11. 51 0
      ruoyi-ui/src/utils/dict/DictOptions.js
  12. 33 0
      ruoyi-ui/src/utils/dict/index.js
  13. 18 2
      ruoyi-ui/src/utils/ruoyi.js
  14. 19 28
      ruoyi-ui/src/views/monitor/job/index.vue
  15. 11 20
      ruoyi-ui/src/views/monitor/job/log.vue
  16. 10 14
      ruoyi-ui/src/views/system/config/index.vue
  17. 10 14
      ruoyi-ui/src/views/system/dept/index.vue
  18. 10 14
      ruoyi-ui/src/views/system/dict/data.vue
  19. 10 14
      ruoyi-ui/src/views/system/dict/index.vue
  20. 6 10
      ruoyi-ui/src/views/system/logininfor/index.vue
  21. 14 23
      ruoyi-ui/src/views/system/menu/index.vue
  22. 15 24
      ruoyi-ui/src/views/system/notice/index.vue
  23. 12 21
      ruoyi-ui/src/views/system/operlog/index.vue
  24. 10 14
      ruoyi-ui/src/views/system/post/index.vue
  25. 2 6
      ruoyi-ui/src/views/system/role/authUser.vue
  26. 9 13
      ruoyi-ui/src/views/system/role/index.vue
  27. 2 8
      ruoyi-ui/src/views/system/role/selectUser.vue
  28. 15 23
      ruoyi-ui/src/views/system/user/index.vue

+ 22 - 0
ruoyi-modules/ruoyi-gen/src/main/java/com/ruoyi/gen/util/VelocityUtils.java

@@ -58,6 +58,7 @@ public class VelocityUtils
58 58
         velocityContext.put("permissionPrefix", getPermissionPrefix(moduleName, businessName));
59 59
         velocityContext.put("columns", genTable.getColumns());
60 60
         velocityContext.put("table", genTable);
61
+        velocityContext.put("dicts", getDicts(genTable));
61 62
         setMenuVelocityContext(velocityContext, genTable);
62 63
         if (GenConstants.TPL_TREE.equals(tplCategory))
63 64
         {
@@ -261,6 +262,27 @@ public class VelocityUtils
261 262
     }
262 263
 
263 264
     /**
265
+     * 根据列类型获取字典组
266
+     * 
267
+     * @param genTable 业务表对象
268
+     * @return 返回字典组
269
+     */
270
+    public static String getDicts(GenTable genTable)
271
+    {
272
+        List<GenTableColumn> columns = genTable.getColumns();
273
+        List<String> dicts = new ArrayList<String>();
274
+        for (GenTableColumn column : columns)
275
+        {
276
+            if (!column.isSuperColumn() && StringUtils.isNotEmpty(column.getDictType()) && StringUtils.equalsAny(
277
+                    column.getHtmlType(), new String[] { GenConstants.HTML_SELECT, GenConstants.HTML_RADIO }))
278
+            {
279
+                dicts.add("'" + column.getDictType() + "'");
280
+            }
281
+        }
282
+        return StringUtils.join(dicts, ", ");
283
+    }
284
+
285
+    /**
264 286
      * 获取权限前缀
265 287
      *
266 288
      * @param moduleName 模块名称

+ 21 - 34
ruoyi-modules/ruoyi-gen/src/main/resources/vm/vue/index-tree.vue.vm

@@ -25,10 +25,10 @@
25 25
       <el-form-item label="${comment}" prop="${column.javaField}">
26 26
         <el-select v-model="queryParams.${column.javaField}" placeholder="请选择${comment}" clearable size="small">
27 27
           <el-option
28
-            v-for="dict in ${column.javaField}Options"
29
-            :key="dict.dictValue"
30
-            :label="dict.dictLabel"
31
-            :value="dict.dictValue"
28
+            v-for="dict in dict.type.${dictType}"
29
+            :key="dict.value"
30
+            :label="dict.label"
31
+            :value="dict.value"
32 32
           />
33 33
         </el-select>
34 34
       </el-form-item>
@@ -108,7 +108,7 @@
108 108
 #elseif($column.list && "" != $column.dictType)
109 109
       <el-table-column label="${comment}" align="center" prop="${javaField}">
110 110
         <template slot-scope="scope">
111
-          <dict-tag :options="${javaField}Options" :value="scope.row.${javaField}"/>
111
+          <dict-tag :options="dict.type.${column.dictType}" :value="scope.row.${javaField}"/>
112 112
         </template>
113 113
       </el-table-column>
114 114
 #elseif($column.list && "" != $javaField)
@@ -184,10 +184,10 @@
184 184
         <el-form-item label="${comment}" prop="${field}">
185 185
           <el-select v-model="form.${field}" placeholder="请选择${comment}">
186 186
             <el-option
187
-              v-for="dict in ${field}Options"
188
-              :key="dict.dictValue"
189
-              :label="dict.dictLabel"
190
-              #if($column.javaType == "Integer" || $column.javaType == "Long"):value="parseInt(dict.dictValue)"#else:value="dict.dictValue"#end
187
+              v-for="dict in dict.type.${dictType}"
188
+              :key="dict.value"
189
+              :label="dict.label"
190
+              #if($column.javaType == "Integer" || $column.javaType == "Long"):value="parseInt(dict.value)"#else:value="dict.value"#end
191 191
 
192 192
             ></el-option>
193 193
           </el-select>
@@ -202,10 +202,10 @@
202 202
         <el-form-item label="${comment}">
203 203
           <el-checkbox-group v-model="form.${field}">
204 204
             <el-checkbox
205
-              v-for="dict in ${field}Options"
206
-              :key="dict.dictValue"
207
-              :label="dict.dictValue">
208
-              {{dict.dictLabel}}
205
+              v-for="dict in dict.type.${dictType}"
206
+              :key="dict.value"
207
+              :label="dict.value">
208
+              {{dict.label}}
209 209
             </el-checkbox>
210 210
           </el-checkbox-group>
211 211
         </el-form-item>
@@ -219,11 +219,11 @@
219 219
         <el-form-item label="${comment}">
220 220
           <el-radio-group v-model="form.${field}">
221 221
             <el-radio
222
-              v-for="dict in ${field}Options"
223
-              :key="dict.dictValue"
224
-              #if($column.javaType == "Integer" || $column.javaType == "Long"):label="parseInt(dict.dictValue)"#else:label="dict.dictValue"#end
222
+              v-for="dict in dict.type.${dictType}"
223
+              :key="dict.value"
224
+              #if($column.javaType == "Integer" || $column.javaType == "Long"):label="parseInt(dict.value)"#else:label="dict.value"#end
225 225
 
226
-            >{{dict.dictLabel}}</el-radio>
226
+            >{{dict.label}}</el-radio>
227 227
           </el-radio-group>
228 228
         </el-form-item>
229 229
 #elseif($column.htmlType == "radio" && $dictType)
@@ -265,6 +265,9 @@ import "@riophae/vue-treeselect/dist/vue-treeselect.css";
265 265
 
266 266
 export default {
267 267
   name: "${BusinessName}",
268
+#if(${dicts} != '')
269
+  dicts: [${dicts}],
270
+#end
268 271
   components: {
269 272
     Treeselect
270 273
   },
@@ -283,16 +286,7 @@ export default {
283 286
       // 是否显示弹出层
284 287
       open: false,
285 288
 #foreach ($column in $columns)
286
-#set($parentheseIndex=$column.columnComment.indexOf("("))
287
-#if($parentheseIndex != -1)
288
-#set($comment=$column.columnComment.substring(0, $parentheseIndex))
289
-#else
290
-#set($comment=$column.columnComment)
291
-#end
292
-#if(${column.dictType} != '')
293
-      // $comment字典
294
-      ${column.javaField}Options: [],
295
-#elseif($column.htmlType == "datetime" && $column.queryType == "BETWEEN")
289
+#if($column.htmlType == "datetime" && $column.queryType == "BETWEEN")
296 290
 #set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
297 291
       // $comment时间范围
298 292
       daterange${AttrName}: [],
@@ -330,13 +324,6 @@ export default {
330 324
   },
331 325
   created() {
332 326
     this.getList();
333
-#foreach ($column in $columns)
334
-#if(${column.dictType} != '')
335
-    this.getDicts("${column.dictType}").then(response => {
336
-      this.${column.javaField}Options = response.data;
337
-    });
338
-#end
339
-#end
340 327
   },
341 328
   methods: {
342 329
     /** 查询${functionName}列表 */

+ 21 - 34
ruoyi-modules/ruoyi-gen/src/main/resources/vm/vue/index.vue.vm

@@ -25,10 +25,10 @@
25 25
       <el-form-item label="${comment}" prop="${column.javaField}">
26 26
         <el-select v-model="queryParams.${column.javaField}" placeholder="请选择${comment}" clearable size="small">
27 27
           <el-option
28
-            v-for="dict in ${column.javaField}Options"
29
-            :key="dict.dictValue"
30
-            :label="dict.dictLabel"
31
-            :value="dict.dictValue"
28
+            v-for="dict in dict.type.${dictType}"
29
+            :key="dict.value"
30
+            :label="dict.label"
31
+            :value="dict.value"
32 32
           />
33 33
         </el-select>
34 34
       </el-form-item>
@@ -136,7 +136,7 @@
136 136
 #elseif($column.list && "" != $column.dictType)
137 137
       <el-table-column label="${comment}" align="center" prop="${javaField}">
138 138
         <template slot-scope="scope">
139
-          <dict-tag :options="${javaField}Options" :value="scope.row.${javaField}"/>
139
+          <dict-tag :options="dict.type.${column.dictType}" :value="scope.row.${javaField}"/>
140 140
         </template>
141 141
       </el-table-column>
142 142
 #elseif($column.list && "" != $javaField)
@@ -205,10 +205,10 @@
205 205
         <el-form-item label="${comment}" prop="${field}">
206 206
           <el-select v-model="form.${field}" placeholder="请选择${comment}">
207 207
             <el-option
208
-              v-for="dict in ${field}Options"
209
-              :key="dict.dictValue"
210
-              :label="dict.dictLabel"
211
-              #if($column.javaType == "Integer" || $column.javaType == "Long"):value="parseInt(dict.dictValue)"#else:value="dict.dictValue"#end
208
+              v-for="dict in dict.type.${dictType}"
209
+              :key="dict.value"
210
+              :label="dict.label"
211
+              #if($column.javaType == "Integer" || $column.javaType == "Long"):value="parseInt(dict.value)"#else:value="dict.value"#end
212 212
 
213 213
             ></el-option>
214 214
           </el-select>
@@ -223,10 +223,10 @@
223 223
         <el-form-item label="${comment}">
224 224
           <el-checkbox-group v-model="form.${field}">
225 225
             <el-checkbox
226
-              v-for="dict in ${field}Options"
227
-              :key="dict.dictValue"
228
-              :label="dict.dictValue">
229
-              {{dict.dictLabel}}
226
+              v-for="dict in dict.type.${dictType}"
227
+              :key="dict.value"
228
+              :label="dict.value">
229
+              {{dict.label}}
230 230
             </el-checkbox>
231 231
           </el-checkbox-group>
232 232
         </el-form-item>
@@ -240,11 +240,11 @@
240 240
         <el-form-item label="${comment}">
241 241
           <el-radio-group v-model="form.${field}">
242 242
             <el-radio
243
-              v-for="dict in ${field}Options"
244
-              :key="dict.dictValue"
245
-              #if($column.javaType == "Integer" || $column.javaType == "Long"):label="parseInt(dict.dictValue)"#else:label="dict.dictValue"#end
243
+              v-for="dict in dict.type.${dictType}"
244
+              :key="dict.value"
245
+              #if($column.javaType == "Integer" || $column.javaType == "Long"):label="parseInt(dict.value)"#else:label="dict.value"#end
246 246
 
247
-            >{{dict.dictLabel}}</el-radio>
247
+            >{{dict.label}}</el-radio>
248 248
           </el-radio-group>
249 249
         </el-form-item>
250 250
 #elseif($column.htmlType == "radio" && $dictType)
@@ -316,6 +316,9 @@ import { list${BusinessName}, get${BusinessName}, del${BusinessName}, add${Busin
316 316
 
317 317
 export default {
318 318
   name: "${BusinessName}",
319
+#if(${dicts} != '')
320
+  dicts: [${dicts}],
321
+#end
319 322
   data() {
320 323
     return {
321 324
       // 遮罩层
@@ -345,16 +348,7 @@ export default {
345 348
       // 是否显示弹出层
346 349
       open: false,
347 350
 #foreach ($column in $columns)
348
-#set($parentheseIndex=$column.columnComment.indexOf("("))
349
-#if($parentheseIndex != -1)
350
-#set($comment=$column.columnComment.substring(0, $parentheseIndex))
351
-#else
352
-#set($comment=$column.columnComment)
353
-#end
354
-#if(${column.dictType} != '')
355
-      // $comment字典
356
-      ${column.javaField}Options: [],
357
-#elseif($column.htmlType == "datetime" && $column.queryType == "BETWEEN")
351
+#if($column.htmlType == "datetime" && $column.queryType == "BETWEEN")
358 352
 #set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
359 353
       // $comment时间范围
360 354
       daterange${AttrName}: [],
@@ -394,13 +388,6 @@ export default {
394 388
   },
395 389
   created() {
396 390
     this.getList();
397
-#foreach ($column in $columns)
398
-#if(${column.dictType} != '')
399
-    this.getDicts("${column.dictType}").then(response => {
400
-      this.${column.javaField}Options = response.data;
401
-    });
402
-#end
403
-#end
404 391
   },
405 392
   methods: {
406 393
     /** 查询${functionName}列表 */

+ 21 - 0
ruoyi-ui/src/components/DictData/index.js

@@ -0,0 +1,21 @@
1
+import Vue from 'vue'
2
+import DataDict from '@/utils/dict'
3
+import { getDicts as getDicts } from '@/api/system/dict/data'
4
+
5
+function install() {
6
+  Vue.use(DataDict, {
7
+    metas: {
8
+      '*': {
9
+        labelField: 'dictLabel',
10
+        valueField: 'dictValue',
11
+        request(dictMeta) {
12
+          return getDicts(dictMeta.type).then(res => res.data)
13
+        },
14
+      },
15
+    },
16
+  })
17
+}
18
+
19
+export default {
20
+  install,
21
+}

+ 10 - 10
ruoyi-ui/src/components/DictTag/index.vue

@@ -1,23 +1,23 @@
1 1
 <template>
2 2
   <div>
3 3
     <template v-for="(item, index) in options">
4
-      <template v-if="values.includes(item.dictValue)">
4
+      <template v-if="values.includes(item.value)">
5 5
         <span
6
-          v-if="item.listClass == 'default' || item.listClass == ''"
7
-          :key="item.dictValue"
6
+          v-if="item.raw.listClass == 'default' || item.raw.listClass == ''"
7
+          :key="item.value"
8 8
           :index="index"
9
-          :class="item.cssClass"
10
-          >{{ item.dictLabel }}</span
9
+          :class="item.raw.cssClass"
10
+          >{{ item.label }}</span
11 11
         >
12 12
         <el-tag
13 13
           v-else
14 14
           :disable-transitions="true"
15
-          :key="item.dictValue"
15
+          :key="item.value"
16 16
           :index="index"
17
-          :type="item.listClass == 'primary' ? '' : item.listClass"
18
-          :class="item.cssClass"
17
+          :type="item.raw.listClass == 'primary' ? '' : item.raw.listClass"
18
+          :class="item.raw.cssClass"
19 19
         >
20
-          {{ item.dictLabel }}
20
+          {{ item.label }}
21 21
         </el-tag>
22 22
       </template>
23 23
     </template>
@@ -49,4 +49,4 @@ export default {
49 49
 .el-tag + .el-tag {
50 50
   margin-left: 10px;
51 51
 }
52
-</style>
52
+</style>

+ 3 - 0
ruoyi-ui/src/main.js

@@ -31,6 +31,8 @@ import ImageUpload from "@/components/ImageUpload"
31 31
 import DictTag from '@/components/DictTag'
32 32
 // 头部标签组件
33 33
 import VueMeta from 'vue-meta'
34
+// 字典数据组件
35
+import DictData from '@/components/DictData'
34 36
 
35 37
 // 全局方法挂载
36 38
 Vue.prototype.getDicts = getDicts
@@ -65,6 +67,7 @@ Vue.component('ImageUpload', ImageUpload)
65 67
 
66 68
 Vue.use(directive)
67 69
 Vue.use(VueMeta)
70
+DictData.install()
68 71
 
69 72
 /**
70 73
  * If you don't want to use mock-server

+ 82 - 0
ruoyi-ui/src/utils/dict/Dict.js

@@ -0,0 +1,82 @@
1
+import Vue from 'vue'
2
+import { mergeRecursive } from "@/utils/ruoyi";
3
+import DictMeta from './DictMeta'
4
+import DictData from './DictData'
5
+
6
+const DEFAULT_DICT_OPTIONS = {
7
+  types: [],
8
+}
9
+
10
+/**
11
+ * @classdesc 字典
12
+ * @property {Object} label 标签对象,内部属性名为字典类型名称
13
+ * @property {Object} dict 字段数组,内部属性名为字典类型名称
14
+ * @property {Array.<DictMeta>} _dictMetas 字典元数据数组
15
+ */
16
+export default class Dict {
17
+  constructor() {
18
+    this.owner = null
19
+    this.label = {}
20
+    this.type = {}
21
+  }
22
+
23
+  init(options) {
24
+    if (options instanceof Array) {
25
+      options = { types: options }
26
+    }
27
+    const opts = mergeRecursive(DEFAULT_DICT_OPTIONS, options)
28
+    if (opts.types === undefined) {
29
+      throw new Error('need dict types')
30
+    }
31
+    const ps = []
32
+    this._dictMetas = opts.types.map(t => DictMeta.parse(t))
33
+    this._dictMetas.forEach(dictMeta => {
34
+      const type = dictMeta.type
35
+      Vue.set(this.label, type, {})
36
+      Vue.set(this.type, type, [])
37
+      if (dictMeta.lazy) {
38
+        return
39
+      }
40
+      ps.push(loadDict(this, dictMeta))
41
+    })
42
+    return Promise.all(ps)
43
+  }
44
+
45
+  /**
46
+   * 重新加载字典
47
+   * @param {String} type 字典类型
48
+   */
49
+  reloadDict(type) {
50
+    const dictMeta = this._dictMetas.find(e => e.type === type)
51
+    if (dictMeta === undefined) {
52
+      return Promise.reject(`the dict meta of ${type} was not found`)
53
+    }
54
+    return loadDict(this, dictMeta)
55
+  }
56
+}
57
+
58
+/**
59
+ * 加载字典
60
+ * @param {Dict} dict 字典
61
+ * @param {DictMeta} dictMeta 字典元数据
62
+ * @returns {Promise}
63
+ */
64
+function loadDict(dict, dictMeta) {
65
+  return dictMeta.request(dictMeta)
66
+    .then(response => {
67
+      const type = dictMeta.type
68
+      let dicts = dictMeta.responseConverter(response, dictMeta)
69
+      if (!(dicts instanceof Array)) {
70
+        console.error('the return of responseConverter must be Array.<DictData>')
71
+        dicts = []
72
+      } else if (dicts.filter(d => d instanceof DictData).length !== dicts.length) {
73
+        console.error('the type of elements in dicts must be DictData')
74
+        dicts = []
75
+      }
76
+      dict.type[type].splice(0, Number.MAX_SAFE_INTEGER, ...dicts)
77
+      dicts.forEach(d => {
78
+        Vue.set(dict.label[type], d.value, d.label)
79
+      })
80
+      return dicts
81
+    })
82
+}

+ 17 - 0
ruoyi-ui/src/utils/dict/DictConverter.js

@@ -0,0 +1,17 @@
1
+import DictOptions from './DictOptions'
2
+import DictData from './DictData'
3
+
4
+export default function(dict, dictMeta) {
5
+  const label = determineDictField(dict, dictMeta.labelField, ...DictOptions.DEFAULT_LABEL_FIELDS)
6
+  const value = determineDictField(dict, dictMeta.valueField, ...DictOptions.DEFAULT_VALUE_FIELDS)
7
+  return new DictData(dict[label], dict[value], dict)
8
+}
9
+
10
+/**
11
+ * 确定字典字段
12
+ * @param {DictData} dict
13
+ * @param  {...String} fields
14
+ */
15
+function determineDictField(dict, ...fields) {
16
+  return fields.find(f => Object.prototype.hasOwnProperty.call(dict, f))
17
+}

+ 13 - 0
ruoyi-ui/src/utils/dict/DictData.js

@@ -0,0 +1,13 @@
1
+/**
2
+ * @classdesc 字典数据
3
+ * @property {String} label 标签
4
+ * @property {*} value 标签
5
+ * @property {Object} raw 原始数据
6
+ */
7
+export default class DictData {
8
+  constructor(label, value, raw) {
9
+    this.label = label
10
+    this.value = value
11
+    this.raw = raw
12
+  }
13
+}

+ 38 - 0
ruoyi-ui/src/utils/dict/DictMeta.js

@@ -0,0 +1,38 @@
1
+import { mergeRecursive } from "@/utils/ruoyi";
2
+import DictOptions from './DictOptions'
3
+
4
+/**
5
+ * @classdesc 字典元数据
6
+ * @property {String} type 类型
7
+ * @property {Function} request 请求
8
+ * @property {String} label 标签字段
9
+ * @property {String} value 值字段
10
+ */
11
+export default class DictMeta {
12
+  constructor(options) {
13
+    this.type = options.type
14
+    this.request = options.request,
15
+    this.responseConverter = options.responseConverter
16
+    this.labelField = options.labelField
17
+    this.valueField = options.valueField
18
+    this.lazy = options.lazy === true
19
+  }
20
+}
21
+
22
+
23
+/**
24
+ * 解析字典元数据
25
+ * @param {Object} options
26
+ * @returns {DictMeta}
27
+ */
28
+DictMeta.parse= function(options) {
29
+  let opts = null
30
+  if (typeof options === 'string') {
31
+    opts = DictOptions.metas[options] || {}
32
+    opts.type = options
33
+  } else if (typeof options === 'object') {
34
+    opts = options
35
+  }
36
+  opts = mergeRecursive(DictOptions.metas['*'], opts)
37
+  return new DictMeta(opts)
38
+}

+ 51 - 0
ruoyi-ui/src/utils/dict/DictOptions.js

@@ -0,0 +1,51 @@
1
+import { mergeRecursive } from "@/utils/ruoyi";
2
+import dictConverter from './DictConverter'
3
+
4
+export const options = {
5
+  metas: {
6
+    '*': {
7
+      /**
8
+       * 字典请求,方法签名为function(dictMeta: DictMeta): Promise
9
+       */
10
+      request: (dictMeta) => {
11
+        console.log(`load dict ${dictMeta.type}`)
12
+        return Promise.resolve([])
13
+      },
14
+      /**
15
+       * 字典响应数据转换器,方法签名为function(response: Object, dictMeta: DictMeta): DictData
16
+       */
17
+      responseConverter,
18
+      labelField: 'label',
19
+      valueField: 'value',
20
+    },
21
+  },
22
+  /**
23
+   * 默认标签字段
24
+   */
25
+  DEFAULT_LABEL_FIELDS: ['label', 'name', 'title'],
26
+  /**
27
+   * 默认值字段
28
+   */
29
+  DEFAULT_VALUE_FIELDS: ['value', 'id', 'uid', 'key'],
30
+}
31
+
32
+/**
33
+ * 映射字典
34
+ * @param {Object} response 字典数据
35
+ * @param {DictMeta} dictMeta 字典元数据
36
+ * @returns {DictData}
37
+ */
38
+function responseConverter(response, dictMeta) {
39
+  const dicts = response.content instanceof Array ? response.content : response
40
+  if (dicts === undefined) {
41
+    console.warn(`no dict data of "${dictMeta.type}" found in the response`)
42
+    return []
43
+  }
44
+  return dicts.map(d => dictConverter(d, dictMeta))
45
+}
46
+
47
+export function mergeOptions(src) {
48
+  mergeRecursive(options, src)
49
+}
50
+
51
+export default options

+ 33 - 0
ruoyi-ui/src/utils/dict/index.js

@@ -0,0 +1,33 @@
1
+import Dict from './Dict'
2
+import { mergeOptions } from './DictOptions'
3
+
4
+export default function(Vue, options) {
5
+  mergeOptions(options)
6
+  Vue.mixin({
7
+    data() {
8
+      if (this.$options.dicts === undefined || this.$options.dicts === null) {
9
+        return {}
10
+      }
11
+      const dict = new Dict()
12
+      dict.owner = this
13
+      return {
14
+        dict
15
+      }
16
+    },
17
+    created() {
18
+      if (!(this.dict instanceof Dict)) {
19
+        return
20
+      }
21
+      options.onCreated && options.onCreated(this.dict)
22
+      this.dict.init(this.$options.dicts).then(() => {
23
+        options.onReady && options.onReady(this.dict)
24
+        this.$nextTick(() => {
25
+          this.$emit('dictReady', this.dict)
26
+          if (this.$options.methods && this.$options.methods.onDictReady instanceof Function) {
27
+            this.$options.methods.onDictReady.call(this, this.dict)
28
+          }
29
+        })
30
+      })
31
+    },
32
+  })
33
+}

+ 18 - 2
ruoyi-ui/src/utils/ruoyi.js

@@ -72,8 +72,8 @@ export function addDateRange(params, dateRange, propName) {
72 72
 export function selectDictLabel(datas, value) {
73 73
 	var actions = [];
74 74
 	Object.keys(datas).some((key) => {
75
-		if (datas[key].dictValue == ('' + value)) {
76
-			actions.push(datas[key].dictLabel);
75
+		if (datas[key].value == ('' + value)) {
76
+			actions.push(datas[key].label);
77 77
 			return true;
78 78
 		}
79 79
 	})
@@ -122,6 +122,22 @@ export function praseStrEmpty(str) {
122 122
 	return str;
123 123
 }
124 124
 
125
+// 数据合并
126
+export function mergeRecursive(source, target) {
127
+    for (var p in target) {
128
+        try {
129
+            if (target[p].constructor == Object) {
130
+                source[p] = mergeRecursive(source[p], target[p]);
131
+            } else {
132
+                source[p] = target[p];
133
+            }
134
+        } catch(e) {
135
+            source[p] = target[p];
136
+        }
137
+    }
138
+    return source;
139
+};
140
+
125 141
 /**
126 142
  * 构造树型结构数据
127 143
  * @param {*} data 数据源

+ 19 - 28
ruoyi-ui/src/views/monitor/job/index.vue

@@ -13,20 +13,20 @@
13 13
       <el-form-item label="任务组名" prop="jobGroup">
14 14
         <el-select v-model="queryParams.jobGroup" placeholder="请选择任务组名" clearable size="small">
15 15
           <el-option
16
-            v-for="dict in jobGroupOptions"
17
-            :key="dict.dictValue"
18
-            :label="dict.dictLabel"
19
-            :value="dict.dictValue"
16
+            v-for="dict in dict.type.sys_job_group"
17
+            :key="dict.value"
18
+            :label="dict.label"
19
+            :value="dict.value"
20 20
           />
21 21
         </el-select>
22 22
       </el-form-item>
23 23
       <el-form-item label="任务状态" prop="status">
24 24
         <el-select v-model="queryParams.status" placeholder="请选择任务状态" clearable size="small">
25 25
           <el-option
26
-            v-for="dict in statusOptions"
27
-            :key="dict.dictValue"
28
-            :label="dict.dictLabel"
29
-            :value="dict.dictValue"
26
+            v-for="dict in dict.type.sys_job_status"
27
+            :key="dict.value"
28
+            :label="dict.label"
29
+            :value="dict.value"
30 30
           />
31 31
         </el-select>
32 32
       </el-form-item>
@@ -98,7 +98,7 @@
98 98
       <el-table-column label="任务名称" align="center" prop="jobName" :show-overflow-tooltip="true" />
99 99
       <el-table-column label="任务组名" align="center" prop="jobGroup">
100 100
         <template slot-scope="scope">
101
-          <dict-tag :options="jobGroupOptions" :value="scope.row.jobGroup"/>
101
+          <dict-tag :options="dict.type.sys_job_group" :value="scope.row.jobGroup"/>
102 102
         </template>
103 103
       </el-table-column>
104 104
       <el-table-column label="调用目标字符串" align="center" prop="invokeTarget" :show-overflow-tooltip="true" />
@@ -167,10 +167,10 @@
167 167
             <el-form-item label="任务分组" prop="jobGroup">
168 168
               <el-select v-model="form.jobGroup" placeholder="请选择">
169 169
                 <el-option
170
-                  v-for="dict in jobGroupOptions"
171
-                  :key="dict.dictValue"
172
-                  :label="dict.dictLabel"
173
-                  :value="dict.dictValue"
170
+                  v-for="dict in dict.type.sys_job_group"
171
+                  :key="dict.value"
172
+                  :label="dict.label"
173
+                  :value="dict.value"
174 174
                 ></el-option>
175 175
               </el-select>
176 176
             </el-form-item>
@@ -224,10 +224,10 @@
224 224
             <el-form-item label="状态">
225 225
               <el-radio-group v-model="form.status">
226 226
                 <el-radio
227
-                  v-for="dict in statusOptions"
228
-                  :key="dict.dictValue"
229
-                  :label="dict.dictValue"
230
-                >{{dict.dictLabel}}</el-radio>
227
+                  v-for="dict in dict.type.sys_job_status"
228
+                  :key="dict.value"
229
+                  :label="dict.value"
230
+                >{{dict.label}}</el-radio>
231 231
               </el-radio-group>
232 232
             </el-form-item>
233 233
           </el-col>
@@ -300,6 +300,7 @@ import Crontab from '@/components/Crontab'
300 300
 export default {
301 301
   components: { Crontab },
302 302
   name: "Job",
303
+  dicts: ['sys_job_group', 'sys_job_status'],
303 304
   data() {
304 305
     return {
305 306
       // 遮罩层
@@ -326,10 +327,6 @@ export default {
326 327
       openCron: false,
327 328
       // 传入的表达式
328 329
       expression: "",
329
-      // 任务组名字典
330
-      jobGroupOptions: [],
331
-      // 状态字典
332
-      statusOptions: [],
333 330
       // 查询参数
334 331
       queryParams: {
335 332
         pageNum: 1,
@@ -356,12 +353,6 @@ export default {
356 353
   },
357 354
   created() {
358 355
     this.getList();
359
-    this.getDicts("sys_job_group").then(response => {
360
-      this.jobGroupOptions = response.data;
361
-    });
362
-    this.getDicts("sys_job_status").then(response => {
363
-      this.statusOptions = response.data;
364
-    });
365 356
   },
366 357
   methods: {
367 358
     /** 查询定时任务列表 */
@@ -375,7 +366,7 @@ export default {
375 366
     },
376 367
     // 任务组名字典翻译
377 368
     jobGroupFormat(row, column) {
378
-      return this.selectDictLabel(this.jobGroupOptions, row.jobGroup);
369
+      return this.selectDictLabel(this.dict.type.sys_job_group, row.jobGroup);
379 370
     },
380 371
     // 取消按钮
381 372
     cancel() {

+ 11 - 20
ruoyi-ui/src/views/monitor/job/log.vue

@@ -20,10 +20,10 @@
20 20
           style="width: 240px"
21 21
         >
22 22
           <el-option
23
-            v-for="dict in jobGroupOptions"
24
-            :key="dict.dictValue"
25
-            :label="dict.dictLabel"
26
-            :value="dict.dictValue"
23
+            v-for="dict in dict.type.sys_job_group"
24
+            :key="dict.value"
25
+            :label="dict.label"
26
+            :value="dict.value"
27 27
           />
28 28
         </el-select>
29 29
       </el-form-item>
@@ -36,10 +36,10 @@
36 36
           style="width: 240px"
37 37
         >
38 38
           <el-option
39
-            v-for="dict in statusOptions"
40
-            :key="dict.dictValue"
41
-            :label="dict.dictLabel"
42
-            :value="dict.dictValue"
39
+            v-for="dict in dict.type.sys_common_status"
40
+            :key="dict.value"
41
+            :label="dict.label"
42
+            :value="dict.value"
43 43
           />
44 44
         </el-select>
45 45
       </el-form-item>
@@ -111,14 +111,14 @@
111 111
       <el-table-column label="任务名称" align="center" prop="jobName" :show-overflow-tooltip="true" />
112 112
       <el-table-column label="任务组名" align="center" prop="jobGroup" :show-overflow-tooltip="true">
113 113
         <template slot-scope="scope">
114
-          <dict-tag :options="jobGroupOptions" :value="scope.row.jobGroup"/>
114
+          <dict-tag :options="dict.type.sys_job_group" :value="scope.row.jobGroup"/>
115 115
         </template>
116 116
       </el-table-column>
117 117
       <el-table-column label="调用目标字符串" align="center" prop="invokeTarget" :show-overflow-tooltip="true" />
118 118
       <el-table-column label="日志信息" align="center" prop="jobMessage" :show-overflow-tooltip="true" />
119 119
       <el-table-column label="执行状态" align="center" prop="status">
120 120
         <template slot-scope="scope">
121
-          <dict-tag :options="statusOptions" :value="scope.row.status"/>
121
+          <dict-tag :options="dict.type.sys_common_status" :value="scope.row.status"/>
122 122
         </template>
123 123
       </el-table-column>
124 124
       <el-table-column label="执行时间" align="center" prop="createTime" width="180">
@@ -189,6 +189,7 @@ import { listJobLog, delJobLog, cleanJobLog } from "@/api/monitor/jobLog";
189 189
 
190 190
 export default {
191 191
   name: "JobLog",
192
+  dicts: ['sys_common_status', 'sys_job_group'],
192 193
   data() {
193 194
     return {
194 195
       // 遮罩层
@@ -209,10 +210,6 @@ export default {
209 210
       dateRange: [],
210 211
       // 表单参数
211 212
       form: {},
212
-      // 执行状态字典
213
-      statusOptions: [],
214
-      // 任务组名字典
215
-      jobGroupOptions: [],
216 213
       // 查询参数
217 214
       queryParams: {
218 215
         pageNum: 1,
@@ -234,12 +231,6 @@ export default {
234 231
     } else {
235 232
       this.getList();
236 233
     }
237
-    this.getDicts("sys_common_status").then(response => {
238
-      this.statusOptions = response.data;
239
-    });
240
-    this.getDicts("sys_job_group").then(response => {
241
-      this.jobGroupOptions = response.data;
242
-    });
243 234
   },
244 235
   methods: {
245 236
     /** 查询调度日志列表 */

+ 10 - 14
ruoyi-ui/src/views/system/config/index.vue

@@ -24,10 +24,10 @@
24 24
       <el-form-item label="系统内置" prop="configType">
25 25
         <el-select v-model="queryParams.configType" placeholder="系统内置" clearable size="small">
26 26
           <el-option
27
-            v-for="dict in typeOptions"
28
-            :key="dict.dictValue"
29
-            :label="dict.dictLabel"
30
-            :value="dict.dictValue"
27
+            v-for="dict in dict.type.sys_yes_no"
28
+            :key="dict.value"
29
+            :label="dict.label"
30
+            :value="dict.value"
31 31
           />
32 32
         </el-select>
33 33
       </el-form-item>
@@ -113,7 +113,7 @@
113 113
       <el-table-column label="参数键值" align="center" prop="configValue" />
114 114
       <el-table-column label="系统内置" align="center" prop="configType">
115 115
         <template slot-scope="scope">
116
-          <dict-tag :options="typeOptions" :value="scope.row.configType"/>
116
+          <dict-tag :options="dict.type.sys_yes_no" :value="scope.row.configType"/>
117 117
         </template>
118 118
       </el-table-column>
119 119
       <el-table-column label="备注" align="center" prop="remark" :show-overflow-tooltip="true" />
@@ -165,10 +165,10 @@
165 165
         <el-form-item label="系统内置" prop="configType">
166 166
           <el-radio-group v-model="form.configType">
167 167
             <el-radio
168
-              v-for="dict in typeOptions"
169
-              :key="dict.dictValue"
170
-              :label="dict.dictValue"
171
-            >{{dict.dictLabel}}</el-radio>
168
+              v-for="dict in dict.type.sys_yes_no"
169
+              :key="dict.value"
170
+              :label="dict.value"
171
+            >{{dict.label}}</el-radio>
172 172
           </el-radio-group>
173 173
         </el-form-item>
174 174
         <el-form-item label="备注" prop="remark">
@@ -188,6 +188,7 @@ import { listConfig, getConfig, delConfig, addConfig, updateConfig, refreshCache
188 188
 
189 189
 export default {
190 190
   name: "Config",
191
+  dicts: ['sys_yes_no'],
191 192
   data() {
192 193
     return {
193 194
       // 遮罩层
@@ -208,8 +209,6 @@ export default {
208 209
       title: "",
209 210
       // 是否显示弹出层
210 211
       open: false,
211
-      // 类型数据字典
212
-      typeOptions: [],
213 212
       // 日期范围
214 213
       dateRange: [],
215 214
       // 查询参数
@@ -238,9 +237,6 @@ export default {
238 237
   },
239 238
   created() {
240 239
     this.getList();
241
-    this.getDicts("sys_yes_no").then(response => {
242
-      this.typeOptions = response.data;
243
-    });
244 240
   },
245 241
   methods: {
246 242
     /** 查询参数列表 */

+ 10 - 14
ruoyi-ui/src/views/system/dept/index.vue

@@ -13,10 +13,10 @@
13 13
       <el-form-item label="状态" prop="status">
14 14
         <el-select v-model="queryParams.status" placeholder="部门状态" clearable size="small">
15 15
           <el-option
16
-            v-for="dict in statusOptions"
17
-            :key="dict.dictValue"
18
-            :label="dict.dictLabel"
19
-            :value="dict.dictValue"
16
+            v-for="dict in dict.type.sys_normal_disable"
17
+            :key="dict.value"
18
+            :label="dict.label"
19
+            :value="dict.value"
20 20
           />
21 21
         </el-select>
22 22
       </el-form-item>
@@ -61,7 +61,7 @@
61 61
       <el-table-column prop="orderNum" label="排序" width="200"></el-table-column>
62 62
       <el-table-column prop="status" label="状态" width="100">
63 63
         <template slot-scope="scope">
64
-          <dict-tag :options="statusOptions" :value="scope.row.status"/>
64
+          <dict-tag :options="dict.type.sys_normal_disable" :value="scope.row.status"/>
65 65
         </template>
66 66
       </el-table-column>
67 67
       <el-table-column label="创建时间" align="center" prop="createTime" width="200">
@@ -135,10 +135,10 @@
135 135
             <el-form-item label="部门状态">
136 136
               <el-radio-group v-model="form.status">
137 137
                 <el-radio
138
-                  v-for="dict in statusOptions"
139
-                  :key="dict.dictValue"
140
-                  :label="dict.dictValue"
141
-                >{{dict.dictLabel}}</el-radio>
138
+                  v-for="dict in dict.type.sys_normal_disable"
139
+                  :key="dict.value"
140
+                  :label="dict.value"
141
+                >{{dict.label}}</el-radio>
142 142
               </el-radio-group>
143 143
             </el-form-item>
144 144
           </el-col>
@@ -159,6 +159,7 @@ import "@riophae/vue-treeselect/dist/vue-treeselect.css";
159 159
 
160 160
 export default {
161 161
   name: "Dept",
162
+  dicts: ['sys_normal_disable'],
162 163
   components: { Treeselect },
163 164
   data() {
164 165
     return {
@@ -180,8 +181,6 @@ export default {
180 181
       refreshTable: true,
181 182
       // 是否展开
182 183
       expand: false,
183
-      // 状态数据字典
184
-      statusOptions: [],
185 184
       // 查询参数
186 185
       queryParams: {
187 186
         deptName: undefined,
@@ -219,9 +218,6 @@ export default {
219 218
   },
220 219
   created() {
221 220
     this.getList();
222
-    this.getDicts("sys_normal_disable").then(response => {
223
-      this.statusOptions = response.data;
224
-    });
225 221
   },
226 222
   methods: {
227 223
     /** 查询部门列表 */

+ 10 - 14
ruoyi-ui/src/views/system/dict/data.vue

@@ -23,10 +23,10 @@
23 23
       <el-form-item label="状态" prop="status">
24 24
         <el-select v-model="queryParams.status" placeholder="数据状态" clearable size="small">
25 25
           <el-option
26
-            v-for="dict in statusOptions"
27
-            :key="dict.dictValue"
28
-            :label="dict.dictLabel"
29
-            :value="dict.dictValue"
26
+            v-for="dict in dict.type.sys_normal_disable"
27
+            :key="dict.value"
28
+            :label="dict.label"
29
+            :value="dict.value"
30 30
           />
31 31
         </el-select>
32 32
       </el-form-item>
@@ -95,7 +95,7 @@
95 95
       <el-table-column label="字典排序" align="center" prop="dictSort" />
96 96
       <el-table-column label="状态" align="center" prop="status">
97 97
         <template slot-scope="scope">
98
-          <dict-tag :options="statusOptions" :value="scope.row.status"/>
98
+          <dict-tag :options="dict.type.sys_normal_disable" :value="scope.row.status"/>
99 99
         </template>
100 100
       </el-table-column>
101 101
       <el-table-column label="备注" align="center" prop="remark" :show-overflow-tooltip="true" />
@@ -163,10 +163,10 @@
163 163
         <el-form-item label="状态" prop="status">
164 164
           <el-radio-group v-model="form.status">
165 165
             <el-radio
166
-              v-for="dict in statusOptions"
167
-              :key="dict.dictValue"
168
-              :label="dict.dictValue"
169
-            >{{dict.dictLabel}}</el-radio>
166
+              v-for="dict in dict.type.sys_normal_disable"
167
+              :key="dict.value"
168
+              :label="dict.value"
169
+            >{{dict.label}}</el-radio>
170 170
           </el-radio-group>
171 171
         </el-form-item>
172 172
         <el-form-item label="备注" prop="remark">
@@ -187,6 +187,7 @@ import { listType, getType } from "@/api/system/dict/type";
187 187
 
188 188
 export default {
189 189
   name: "Data",
190
+  dicts: ['sys_normal_disable'],
190 191
   data() {
191 192
     return {
192 193
       // 遮罩层
@@ -236,8 +237,6 @@ export default {
236 237
           label: "危险"
237 238
         }
238 239
       ],
239
-      // 状态数据字典
240
-      statusOptions: [],
241 240
       // 类型数据字典
242 241
       typeOptions: [],
243 242
       // 查询参数
@@ -268,9 +267,6 @@ export default {
268 267
     const dictId = this.$route.params && this.$route.params.dictId;
269 268
     this.getType(dictId);
270 269
     this.getTypeList();
271
-    this.getDicts("sys_normal_disable").then(response => {
272
-      this.statusOptions = response.data;
273
-    });
274 270
   },
275 271
   methods: {
276 272
     /** 查询字典类型详细 */

+ 10 - 14
ruoyi-ui/src/views/system/dict/index.vue

@@ -30,10 +30,10 @@
30 30
           style="width: 240px"
31 31
         >
32 32
           <el-option
33
-            v-for="dict in statusOptions"
34
-            :key="dict.dictValue"
35
-            :label="dict.dictLabel"
36
-            :value="dict.dictValue"
33
+            v-for="dict in dict.type.sys_normal_disable"
34
+            :key="dict.value"
35
+            :label="dict.label"
36
+            :value="dict.value"
37 37
           />
38 38
         </el-select>
39 39
       </el-form-item>
@@ -124,7 +124,7 @@
124 124
       </el-table-column>
125 125
       <el-table-column label="状态" align="center" prop="status">
126 126
         <template slot-scope="scope">
127
-          <dict-tag :options="statusOptions" :value="scope.row.status"/>
127
+          <dict-tag :options="dict.type.sys_normal_disable" :value="scope.row.status"/>
128 128
         </template>
129 129
       </el-table-column>
130 130
       <el-table-column label="备注" align="center" prop="remark" :show-overflow-tooltip="true" />
@@ -173,10 +173,10 @@
173 173
         <el-form-item label="状态" prop="status">
174 174
           <el-radio-group v-model="form.status">
175 175
             <el-radio
176
-              v-for="dict in statusOptions"
177
-              :key="dict.dictValue"
178
-              :label="dict.dictValue"
179
-            >{{dict.dictLabel}}</el-radio>
176
+              v-for="dict in dict.type.sys_normal_disable"
177
+              :key="dict.value"
178
+              :label="dict.value"
179
+            >{{dict.label}}</el-radio>
180 180
           </el-radio-group>
181 181
         </el-form-item>
182 182
         <el-form-item label="备注" prop="remark">
@@ -196,6 +196,7 @@ import { listType, getType, delType, addType, updateType, refreshCache } from "@
196 196
 
197 197
 export default {
198 198
   name: "Dict",
199
+  dicts: ['sys_normal_disable'],
199 200
   data() {
200 201
     return {
201 202
       // 遮罩层
@@ -216,8 +217,6 @@ export default {
216 217
       title: "",
217 218
       // 是否显示弹出层
218 219
       open: false,
219
-      // 状态数据字典
220
-      statusOptions: [],
221 220
       // 日期范围
222 221
       dateRange: [],
223 222
       // 查询参数
@@ -243,9 +242,6 @@ export default {
243 242
   },
244 243
   created() {
245 244
     this.getList();
246
-    this.getDicts("sys_normal_disable").then(response => {
247
-      this.statusOptions = response.data;
248
-    });
249 245
   },
250 246
   methods: {
251 247
     /** 查询字典类型列表 */

+ 6 - 10
ruoyi-ui/src/views/system/logininfor/index.vue

@@ -30,10 +30,10 @@
30 30
           style="width: 240px"
31 31
         >
32 32
           <el-option
33
-            v-for="dict in statusOptions"
34
-            :key="dict.dictValue"
35
-            :label="dict.dictLabel"
36
-            :value="dict.dictValue"
33
+            v-for="dict in dict.type.sys_common_status"
34
+            :key="dict.value"
35
+            :label="dict.label"
36
+            :value="dict.value"
37 37
           />
38 38
         </el-select>
39 39
       </el-form-item>
@@ -97,7 +97,7 @@
97 97
       <el-table-column label="地址" align="center" prop="ipaddr" width="130" :show-overflow-tooltip="true" />
98 98
       <el-table-column label="登录状态" align="center" prop="status">
99 99
         <template slot-scope="scope">
100
-          <dict-tag :options="statusOptions" :value="scope.row.status"/>
100
+          <dict-tag :options="dict.type.sys_common_status" :value="scope.row.status"/>
101 101
         </template>
102 102
       </el-table-column>
103 103
       <el-table-column label="描述" align="center" prop="msg" />
@@ -123,6 +123,7 @@ import { list, delLogininfor, cleanLogininfor } from "@/api/system/logininfor";
123 123
 
124 124
 export default {
125 125
   name: "Logininfor",
126
+  dicts: ['sys_common_status'],
126 127
   data() {
127 128
     return {
128 129
       // 遮罩层
@@ -137,8 +138,6 @@ export default {
137 138
       total: 0,
138 139
       // 表格数据
139 140
       list: [],
140
-      // 状态数据字典
141
-      statusOptions: [],
142 141
       // 日期范围
143 142
       dateRange: [],
144 143
       // 默认排序
@@ -155,9 +154,6 @@ export default {
155 154
   },
156 155
   created() {
157 156
     this.getList();
158
-    this.getDicts("sys_common_status").then(response => {
159
-      this.statusOptions = response.data;
160
-    });
161 157
   },
162 158
   methods: {
163 159
     /** 查询登录日志列表 */

+ 14 - 23
ruoyi-ui/src/views/system/menu/index.vue

@@ -13,10 +13,10 @@
13 13
       <el-form-item label="状态" prop="status">
14 14
         <el-select v-model="queryParams.status" placeholder="菜单状态" clearable size="small">
15 15
           <el-option
16
-            v-for="dict in statusOptions"
17
-            :key="dict.dictValue"
18
-            :label="dict.dictLabel"
19
-            :value="dict.dictValue"
16
+            v-for="dict in dict.type.sys_normal_disable"
17
+            :key="dict.value"
18
+            :label="dict.label"
19
+            :value="dict.value"
20 20
           />
21 21
         </el-select>
22 22
       </el-form-item>
@@ -68,7 +68,7 @@
68 68
       <el-table-column prop="component" label="组件路径" :show-overflow-tooltip="true"></el-table-column>
69 69
       <el-table-column prop="status" label="状态" width="80">
70 70
         <template slot-scope="scope">
71
-          <dict-tag :options="statusOptions" :value="scope.row.status"/>
71
+          <dict-tag :options="dict.type.sys_normal_disable" :value="scope.row.status"/>
72 72
         </template>
73 73
       </el-table-column>
74 74
       <el-table-column label="创建时间" align="center" prop="createTime">
@@ -240,10 +240,10 @@
240 240
               </span>
241 241
               <el-radio-group v-model="form.visible">
242 242
                 <el-radio
243
-                  v-for="dict in visibleOptions"
244
-                  :key="dict.dictValue"
245
-                  :label="dict.dictValue"
246
-                >{{dict.dictLabel}}</el-radio>
243
+                  v-for="dict in dict.type.sys_show_hide"
244
+                  :key="dict.value"
245
+                  :label="dict.value"
246
+                >{{dict.label}}</el-radio>
247 247
               </el-radio-group>
248 248
             </el-form-item>
249 249
           </el-col>
@@ -257,10 +257,10 @@
257 257
               </span>
258 258
               <el-radio-group v-model="form.status">
259 259
                 <el-radio
260
-                  v-for="dict in statusOptions"
261
-                  :key="dict.dictValue"
262
-                  :label="dict.dictValue"
263
-                >{{dict.dictLabel}}</el-radio>
260
+                  v-for="dict in dict.type.sys_normal_disable"
261
+                  :key="dict.value"
262
+                  :label="dict.value"
263
+                >{{dict.label}}</el-radio>
264 264
               </el-radio-group>
265 265
             </el-form-item>
266 266
           </el-col>
@@ -282,6 +282,7 @@ import IconSelect from "@/components/IconSelect";
282 282
 
283 283
 export default {
284 284
   name: "Menu",
285
+  dicts: ['sys_show_hide', 'sys_normal_disable'],
285 286
   components: { Treeselect, IconSelect },
286 287
   data() {
287 288
     return {
@@ -301,10 +302,6 @@ export default {
301 302
       isExpandAll: false,
302 303
       // 重新渲染表格状态
303 304
       refreshTable: true,
304
-      // 显示状态数据字典
305
-      visibleOptions: [],
306
-      // 菜单状态数据字典
307
-      statusOptions: [],
308 305
       // 查询参数
309 306
       queryParams: {
310 307
         menuName: undefined,
@@ -328,12 +325,6 @@ export default {
328 325
   },
329 326
   created() {
330 327
     this.getList();
331
-    this.getDicts("sys_show_hide").then(response => {
332
-      this.visibleOptions = response.data;
333
-    });
334
-    this.getDicts("sys_normal_disable").then(response => {
335
-      this.statusOptions = response.data;
336
-    });
337 328
   },
338 329
   methods: {
339 330
     // 选择图标

+ 15 - 24
ruoyi-ui/src/views/system/notice/index.vue

@@ -22,10 +22,10 @@
22 22
       <el-form-item label="类型" prop="noticeType">
23 23
         <el-select v-model="queryParams.noticeType" placeholder="公告类型" clearable size="small">
24 24
           <el-option
25
-            v-for="dict in typeOptions"
26
-            :key="dict.dictValue"
27
-            :label="dict.dictLabel"
28
-            :value="dict.dictValue"
25
+            v-for="dict in dict.type.sys_notice_type"
26
+            :key="dict.value"
27
+            :label="dict.label"
28
+            :value="dict.value"
29 29
           />
30 30
         </el-select>
31 31
       </el-form-item>
@@ -82,12 +82,12 @@
82 82
       />
83 83
       <el-table-column label="公告类型" align="center" prop="noticeType" width="100">
84 84
         <template slot-scope="scope">
85
-          <dict-tag :options="typeOptions" :value="scope.row.noticeType"/>
85
+          <dict-tag :options="dict.type.sys_notice_type" :value="scope.row.noticeType"/>
86 86
         </template>
87 87
       </el-table-column>
88 88
       <el-table-column label="状态" align="center" prop="status" width="100">
89 89
         <template slot-scope="scope">
90
-          <dict-tag :options="statusOptions" :value="scope.row.status"/>
90
+          <dict-tag :options="dict.type.sys_notice_status" :value="scope.row.status"/>
91 91
         </template>
92 92
       </el-table-column>
93 93
       <el-table-column label="创建者" align="center" prop="createBy" width="100" />
@@ -137,10 +137,10 @@
137 137
             <el-form-item label="公告类型" prop="noticeType">
138 138
               <el-select v-model="form.noticeType" placeholder="请选择">
139 139
                 <el-option
140
-                  v-for="dict in typeOptions"
141
-                  :key="dict.dictValue"
142
-                  :label="dict.dictLabel"
143
-                  :value="dict.dictValue"
140
+                  v-for="dict in dict.type.sys_notice_type"
141
+                  :key="dict.value"
142
+                  :label="dict.label"
143
+                  :value="dict.value"
144 144
                 ></el-option>
145 145
               </el-select>
146 146
             </el-form-item>
@@ -149,10 +149,10 @@
149 149
             <el-form-item label="状态">
150 150
               <el-radio-group v-model="form.status">
151 151
                 <el-radio
152
-                  v-for="dict in statusOptions"
153
-                  :key="dict.dictValue"
154
-                  :label="dict.dictValue"
155
-                >{{dict.dictLabel}}</el-radio>
152
+                  v-for="dict in dict.type.sys_notice_status"
153
+                  :key="dict.value"
154
+                  :label="dict.value"
155
+                >{{dict.label}}</el-radio>
156 156
               </el-radio-group>
157 157
             </el-form-item>
158 158
           </el-col>
@@ -176,6 +176,7 @@ import { listNotice, getNotice, delNotice, addNotice, updateNotice } from "@/api
176 176
 
177 177
 export default {
178 178
   name: "Notice",
179
+  dicts: ['sys_notice_status', 'sys_notice_type'],
179 180
   data() {
180 181
     return {
181 182
       // 遮罩层
@@ -196,10 +197,6 @@ export default {
196 197
       title: "",
197 198
       // 是否显示弹出层
198 199
       open: false,
199
-      // 类型数据字典
200
-      statusOptions: [],
201
-      // 状态数据字典
202
-      typeOptions: [],
203 200
       // 查询参数
204 201
       queryParams: {
205 202
         pageNum: 1,
@@ -223,12 +220,6 @@ export default {
223 220
   },
224 221
   created() {
225 222
     this.getList();
226
-    this.getDicts("sys_notice_status").then(response => {
227
-      this.statusOptions = response.data;
228
-    });
229
-    this.getDicts("sys_notice_type").then(response => {
230
-      this.typeOptions = response.data;
231
-    });
232 223
   },
233 224
   methods: {
234 225
     /** 查询公告列表 */

+ 12 - 21
ruoyi-ui/src/views/system/operlog/index.vue

@@ -30,10 +30,10 @@
30 30
           style="width: 240px"
31 31
         >
32 32
           <el-option
33
-            v-for="dict in typeOptions"
34
-            :key="dict.dictValue"
35
-            :label="dict.dictLabel"
36
-            :value="dict.dictValue"
33
+            v-for="dict in dict.type.sys_oper_type"
34
+            :key="dict.value"
35
+            :label="dict.label"
36
+            :value="dict.value"
37 37
           />
38 38
         </el-select>
39 39
       </el-form-item>
@@ -46,10 +46,10 @@
46 46
           style="width: 240px"
47 47
         >
48 48
           <el-option
49
-            v-for="dict in statusOptions"
50
-            :key="dict.dictValue"
51
-            :label="dict.dictLabel"
52
-            :value="dict.dictValue"
49
+            v-for="dict in dict.type.sys_common_status"
50
+            :key="dict.value"
51
+            :label="dict.label"
52
+            :value="dict.value"
53 53
           />
54 54
         </el-select>
55 55
       </el-form-item>
@@ -112,7 +112,7 @@
112 112
       <el-table-column label="系统模块" align="center" prop="title" />
113 113
       <el-table-column label="操作类型" align="center" prop="businessType">
114 114
         <template slot-scope="scope">
115
-          <dict-tag :options="typeOptions" :value="scope.row.businessType"/>
115
+          <dict-tag :options="dict.type.sys_oper_type" :value="scope.row.businessType"/>
116 116
         </template>
117 117
       </el-table-column>
118 118
       <el-table-column label="请求方式" align="center" prop="requestMethod" />
@@ -120,7 +120,7 @@
120 120
       <el-table-column label="主机" align="center" prop="operIp" width="130" :show-overflow-tooltip="true" />
121 121
       <el-table-column label="操作状态" align="center" prop="status">
122 122
         <template slot-scope="scope">
123
-          <dict-tag :options="statusOptions" :value="scope.row.status"/>
123
+          <dict-tag :options="dict.type.sys_common_status" :value="scope.row.status"/>
124 124
         </template>
125 125
       </el-table-column>
126 126
       <el-table-column label="操作日期" align="center" prop="operTime" sortable="custom" :sort-orders="['descending', 'ascending']" width="180">
@@ -198,6 +198,7 @@ import { list, delOperlog, cleanOperlog } from "@/api/system/operlog";
198 198
 
199 199
 export default {
200 200
   name: "Operlog",
201
+  dicts: ['sys_oper_type', 'sys_common_status'],
201 202
   data() {
202 203
     return {
203 204
       // 遮罩层
@@ -214,10 +215,6 @@ export default {
214 215
       list: [],
215 216
       // 是否显示弹出层
216 217
       open: false,
217
-      // 类型数据字典
218
-      typeOptions: [],
219
-      // 类型数据字典
220
-      statusOptions: [],
221 218
       // 日期范围
222 219
       dateRange: [],
223 220
       // 默认排序
@@ -237,12 +234,6 @@ export default {
237 234
   },
238 235
   created() {
239 236
     this.getList();
240
-    this.getDicts("sys_oper_type").then(response => {
241
-      this.typeOptions = response.data;
242
-    });
243
-    this.getDicts("sys_common_status").then(response => {
244
-      this.statusOptions = response.data;
245
-    });
246 237
   },
247 238
   methods: {
248 239
     /** 查询登录日志 */
@@ -257,7 +248,7 @@ export default {
257 248
     },
258 249
     // 操作日志类型字典翻译
259 250
     typeFormat(row, column) {
260
-      return this.selectDictLabel(this.typeOptions, row.businessType);
251
+      return this.selectDictLabel(this.dict.type.sys_oper_type, row.businessType);
261 252
     },
262 253
     /** 搜索按钮操作 */
263 254
     handleQuery() {

+ 10 - 14
ruoyi-ui/src/views/system/post/index.vue

@@ -22,10 +22,10 @@
22 22
       <el-form-item label="状态" prop="status">
23 23
         <el-select v-model="queryParams.status" placeholder="岗位状态" clearable size="small">
24 24
           <el-option
25
-            v-for="dict in statusOptions"
26
-            :key="dict.dictValue"
27
-            :label="dict.dictLabel"
28
-            :value="dict.dictValue"
25
+            v-for="dict in dict.type.sys_normal_disable"
26
+            :key="dict.value"
27
+            :label="dict.label"
28
+            :value="dict.value"
29 29
           />
30 30
         </el-select>
31 31
       </el-form-item>
@@ -89,7 +89,7 @@
89 89
       <el-table-column label="岗位排序" align="center" prop="postSort" />
90 90
       <el-table-column label="状态" align="center" prop="status">
91 91
         <template slot-scope="scope">
92
-          <dict-tag :options="statusOptions" :value="scope.row.status"/>
92
+          <dict-tag :options="dict.type.sys_normal_disable" :value="scope.row.status"/>
93 93
         </template>
94 94
       </el-table-column>
95 95
       <el-table-column label="创建时间" align="center" prop="createTime" width="180">
@@ -140,10 +140,10 @@
140 140
         <el-form-item label="岗位状态" prop="status">
141 141
           <el-radio-group v-model="form.status">
142 142
             <el-radio
143
-              v-for="dict in statusOptions"
144
-              :key="dict.dictValue"
145
-              :label="dict.dictValue"
146
-            >{{dict.dictLabel}}</el-radio>
143
+              v-for="dict in dict.type.sys_normal_disable"
144
+              :key="dict.value"
145
+              :label="dict.value"
146
+            >{{dict.label}}</el-radio>
147 147
           </el-radio-group>
148 148
         </el-form-item>
149 149
         <el-form-item label="备注" prop="remark">
@@ -163,6 +163,7 @@ import { listPost, getPost, delPost, addPost, updatePost } from "@/api/system/po
163 163
 
164 164
 export default {
165 165
   name: "Post",
166
+  dicts: ['sys_normal_disable'],
166 167
   data() {
167 168
     return {
168 169
       // 遮罩层
@@ -183,8 +184,6 @@ export default {
183 184
       title: "",
184 185
       // 是否显示弹出层
185 186
       open: false,
186
-      // 状态数据字典
187
-      statusOptions: [],
188 187
       // 查询参数
189 188
       queryParams: {
190 189
         pageNum: 1,
@@ -211,9 +210,6 @@ export default {
211 210
   },
212 211
   created() {
213 212
     this.getList();
214
-    this.getDicts("sys_normal_disable").then(response => {
215
-      this.statusOptions = response.data;
216
-    });
217 213
   },
218 214
   methods: {
219 215
     /** 查询岗位列表 */

+ 2 - 6
ruoyi-ui/src/views/system/role/authUser.vue

@@ -69,7 +69,7 @@
69 69
       <el-table-column label="手机" prop="phonenumber" :show-overflow-tooltip="true" />
70 70
       <el-table-column label="状态" align="center" prop="status">
71 71
         <template slot-scope="scope">
72
-          <dict-tag :options="statusOptions" :value="scope.row.status"/>
72
+          <dict-tag :options="dict.type.sys_normal_disable" :value="scope.row.status"/>
73 73
         </template>
74 74
       </el-table-column>
75 75
       <el-table-column label="创建时间" align="center" prop="createTime" width="180">
@@ -107,6 +107,7 @@ import selectUser from "./selectUser";
107 107
 
108 108
 export default {
109 109
   name: "AuthUser",
110
+  dicts: ['sys_normal_disable'],
110 111
   components: { selectUser },
111 112
   data() {
112 113
     return {
@@ -122,8 +123,6 @@ export default {
122 123
       total: 0,
123 124
       // 用户表格数据
124 125
       userList: [],
125
-      // 状态数据字典
126
-      statusOptions: [],
127 126
       // 查询参数
128 127
       queryParams: {
129 128
         pageNum: 1,
@@ -139,9 +138,6 @@ export default {
139 138
     if (roleId) {
140 139
       this.queryParams.roleId = roleId;
141 140
       this.getList();
142
-      this.getDicts("sys_normal_disable").then(response => {
143
-        this.statusOptions = response.data;
144
-      });
145 141
     }
146 142
   },
147 143
   methods: {

+ 9 - 13
ruoyi-ui/src/views/system/role/index.vue

@@ -30,10 +30,10 @@
30 30
           style="width: 240px"
31 31
         >
32 32
           <el-option
33
-            v-for="dict in statusOptions"
34
-            :key="dict.dictValue"
35
-            :label="dict.dictLabel"
36
-            :value="dict.dictValue"
33
+            v-for="dict in dict.type.sys_normal_disable"
34
+            :key="dict.value"
35
+            :label="dict.label"
36
+            :value="dict.value"
37 37
           />
38 38
         </el-select>
39 39
       </el-form-item>
@@ -182,10 +182,10 @@
182 182
         <el-form-item label="状态">
183 183
           <el-radio-group v-model="form.status">
184 184
             <el-radio
185
-              v-for="dict in statusOptions"
186
-              :key="dict.dictValue"
187
-              :label="dict.dictValue"
188
-            >{{dict.dictLabel}}</el-radio>
185
+              v-for="dict in dict.type.sys_normal_disable"
186
+              :key="dict.value"
187
+              :label="dict.value"
188
+            >{{dict.label}}</el-radio>
189 189
           </el-radio-group>
190 190
         </el-form-item>
191 191
         <el-form-item label="菜单权限">
@@ -264,6 +264,7 @@ import { treeselect as deptTreeselect, roleDeptTreeselect } from "@/api/system/d
264 264
 
265 265
 export default {
266 266
   name: "Role",
267
+  dicts: ['sys_normal_disable'],
267 268
   data() {
268 269
     return {
269 270
       // 遮罩层
@@ -292,8 +293,6 @@ export default {
292 293
       deptNodeAll: false,
293 294
       // 日期范围
294 295
       dateRange: [],
295
-      // 状态数据字典
296
-      statusOptions: [],
297 296
       // 数据范围选项
298 297
       dataScopeOptions: [
299 298
         {
@@ -351,9 +350,6 @@ export default {
351 350
   },
352 351
   created() {
353 352
     this.getList();
354
-    this.getDicts("sys_normal_disable").then(response => {
355
-      this.statusOptions = response.data;
356
-    });
357 353
   },
358 354
   methods: {
359 355
     /** 查询角色列表 */

+ 2 - 8
ruoyi-ui/src/views/system/role/selectUser.vue

@@ -34,7 +34,7 @@
34 34
         <el-table-column label="手机" prop="phonenumber" :show-overflow-tooltip="true" />
35 35
         <el-table-column label="状态" align="center" prop="status">
36 36
           <template slot-scope="scope">
37
-            <dict-tag :options="statusOptions" :value="scope.row.status"/>
37
+            <dict-tag :options="dict.type.sys_normal_disable" :value="scope.row.status"/>
38 38
           </template>
39 39
         </el-table-column>
40 40
         <el-table-column label="创建时间" align="center" prop="createTime" width="180">
@@ -61,6 +61,7 @@
61 61
 <script>
62 62
 import { unallocatedUserList, authUserSelectAll } from "@/api/system/role";
63 63
 export default {
64
+  dicts: ['sys_normal_disable'],
64 65
   props: {
65 66
     // 角色编号
66 67
     roleId: {
@@ -77,8 +78,6 @@ export default {
77 78
       total: 0,
78 79
       // 未授权用户数据
79 80
       userList: [],
80
-      // 状态数据字典
81
-      statusOptions: [],
82 81
       // 查询参数
83 82
       queryParams: {
84 83
         pageNum: 1,
@@ -89,11 +88,6 @@ export default {
89 88
       }
90 89
     };
91 90
   },
92
-  created() {
93
-    this.getDicts("sys_normal_disable").then(response => {
94
-      this.statusOptions = response.data;
95
-    });
96
-  },
97 91
   methods: {
98 92
     // 显示弹框
99 93
     show() {

+ 15 - 23
ruoyi-ui/src/views/system/user/index.vue

@@ -57,10 +57,10 @@
57 57
               style="width: 240px"
58 58
             >
59 59
               <el-option
60
-                v-for="dict in statusOptions"
61
-                :key="dict.dictValue"
62
-                :label="dict.dictLabel"
63
-                :value="dict.dictValue"
60
+                v-for="dict in dict.type.sys_normal_disable"
61
+                :key="dict.value"
62
+                :label="dict.label"
63
+                :value="dict.value"
64 64
               />
65 65
             </el-select>
66 66
           </el-form-item>
@@ -250,10 +250,10 @@
250 250
             <el-form-item label="用户性别">
251 251
               <el-select v-model="form.sex" placeholder="请选择">
252 252
                 <el-option
253
-                  v-for="dict in sexOptions"
254
-                  :key="dict.dictValue"
255
-                  :label="dict.dictLabel"
256
-                  :value="dict.dictValue"
253
+                  v-for="dict in dict.type.sys_user_sex"
254
+                  :key="dict.value"
255
+                  :label="dict.label"
256
+                  :value="dict.value"
257 257
                 ></el-option>
258 258
               </el-select>
259 259
             </el-form-item>
@@ -262,10 +262,10 @@
262 262
             <el-form-item label="状态">
263 263
               <el-radio-group v-model="form.status">
264 264
                 <el-radio
265
-                  v-for="dict in statusOptions"
266
-                  :key="dict.dictValue"
267
-                  :label="dict.dictValue"
268
-                >{{dict.dictLabel}}</el-radio>
265
+                  v-for="dict in dict.type.sys_normal_disable"
266
+                  :key="dict.value"
267
+                  :label="dict.value"
268
+                >{{dict.label}}</el-radio>
269 269
               </el-radio-group>
270 270
             </el-form-item>
271 271
           </el-col>
@@ -353,6 +353,7 @@ import "@riophae/vue-treeselect/dist/vue-treeselect.css";
353 353
 
354 354
 export default {
355 355
   name: "User",
356
+  dicts: ['sys_normal_disable', 'sys_user_sex'],
356 357
   components: { Treeselect },
357 358
   data() {
358 359
     return {
@@ -382,10 +383,6 @@ export default {
382 383
       initPassword: undefined,
383 384
       // 日期范围
384 385
       dateRange: [],
385
-      // 状态数据字典
386
-      statusOptions: [],
387
-      // 性别状态字典
388
-      sexOptions: [],
389 386
       // 岗位选项
390 387
       postOptions: [],
391 388
       // 角色选项
@@ -433,7 +430,8 @@ export default {
433 430
       // 表单校验
434 431
       rules: {
435 432
         userName: [
436
-          { required: true, message: "用户名称不能为空", trigger: "blur" }
433
+          { required: true, message: "用户名称不能为空", trigger: "blur" },
434
+          { min: 2, max: 20, message: '用户名称长度必须介于 2 和 20 之间', trigger: 'blur' }
437 435
         ],
438 436
         nickName: [
439 437
           { required: true, message: "用户昵称不能为空", trigger: "blur" }
@@ -468,12 +466,6 @@ export default {
468 466
   created() {
469 467
     this.getList();
470 468
     this.getTreeselect();
471
-    this.getDicts("sys_normal_disable").then(response => {
472
-      this.statusOptions = response.data;
473
-    });
474
-    this.getDicts("sys_user_sex").then(response => {
475
-      this.sexOptions = response.data;
476
-    });
477 469
     this.getConfigKey("sys.user.initPassword").then(response => {
478 470
       this.initPassword = response.msg;
479 471
     });