Dict.js 2.3 KB

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