vue2-client 1.7.0 → 1.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (126) hide show
  1. package/.env +15 -15
  2. package/CHANGELOG.md +31 -1
  3. package/Components.md +60 -0
  4. package/index.js +39 -30
  5. package/package.json +4 -2
  6. package/src/base-client/components/common/AddressSearchCombobox/AddressSearchCombobox.vue +316 -316
  7. package/src/base-client/components/common/CitySelect/CitySelect.vue +247 -247
  8. package/src/base-client/components/common/CreateQuery/CreateQuery.vue +669 -667
  9. package/src/base-client/components/common/CreateQuery/CreateQueryItem.vue +735 -733
  10. package/src/base-client/components/common/CreateSimpleFormQuery/CreateSimpleFormQuery.vue +466 -468
  11. package/src/base-client/components/common/CreateSimpleFormQuery/CreateSimpleFormQueryItem.vue +510 -508
  12. package/src/base-client/components/common/FormGroupEdit/FormGroupEdit.vue +144 -146
  13. package/src/base-client/components/common/FormGroupQuery/FormGroupQuery.vue +165 -165
  14. package/src/base-client/components/common/JSONToTree/jsontotree.vue +275 -275
  15. package/src/base-client/components/common/Upload/Upload.vue +168 -168
  16. package/src/base-client/components/common/XAddForm/XAddForm.vue +72 -325
  17. package/src/base-client/components/common/XAddNativeForm/XAddNativeForm.vue +365 -279
  18. package/src/base-client/components/common/XAddNativeForm/index.md +96 -56
  19. package/src/base-client/components/common/XCard/XCard.vue +64 -64
  20. package/src/base-client/components/common/XDataDrawer/XDataDrawer.vue +180 -0
  21. package/src/base-client/components/common/XDataDrawer/index.js +3 -0
  22. package/src/base-client/components/common/XDataDrawer/index.md +41 -0
  23. package/src/base-client/components/common/XForm/XForm.vue +178 -180
  24. package/src/base-client/components/common/XForm/XFormItem.vue +521 -513
  25. package/src/base-client/components/common/XForm/XTreeSelect.vue +184 -184
  26. package/src/base-client/components/common/XFormCol/XFormCol.vue +38 -38
  27. package/src/base-client/components/common/XFormTable/XFormTable.vue +356 -344
  28. package/src/base-client/components/common/XFormTable/index.md +97 -97
  29. package/src/base-client/components/common/XImportExcel/XImportExcel.vue +132 -132
  30. package/src/base-client/components/common/XTable/XTable.vue +519 -506
  31. package/src/base-client/components/common/XTreeOne/XTreeOne.vue +111 -111
  32. package/src/base-client/components/system/DictionaryDetailsView/DictionaryDetailsView.vue +231 -231
  33. package/src/base-client/components/system/QueryParamsDetailsView/QueryParamsDetailsView.vue +281 -281
  34. package/src/base-client/components/ticket/TicketDetailsView/TicketDetailsView.vue +807 -807
  35. package/src/base-client/components/ticket/TicketDetailsView/index.md +29 -29
  36. package/src/base-client/components/ticket/TicketDetailsView/part/TicketDetailsFlow.vue +260 -260
  37. package/src/base-client/components/ticket/TicketSubmitSuccessView/TicketSubmitSuccessView.vue +532 -532
  38. package/src/base-client/components/ticket/TicketSubmitSuccessView/index.md +29 -29
  39. package/src/base-client/plugins/AppData.js +76 -76
  40. package/src/base-client/plugins/GetLoginInfoService.js +179 -179
  41. package/src/base-client/plugins/PagedList.js +177 -177
  42. package/src/base-client/plugins/compatible/LoginServiceOA.js +20 -20
  43. package/src/base-client/plugins/i18n-extend.js +32 -32
  44. package/src/components/Ellipsis/Ellipsis.vue +65 -65
  45. package/src/components/Ellipsis/index.md +38 -38
  46. package/src/components/NumberInfo/index.md +43 -43
  47. package/src/components/STable/README.md +341 -341
  48. package/src/components/STable/index.js +318 -318
  49. package/src/components/Trend/index.md +45 -45
  50. package/src/components/checkbox/ColorCheckbox.vue +157 -157
  51. package/src/components/checkbox/ImgCheckbox.vue +163 -163
  52. package/src/components/exception/ExceptionPage.vue +70 -70
  53. package/src/components/form/FormRow.vue +52 -52
  54. package/src/components/index.js +36 -36
  55. package/src/components/menu/SideMenu.vue +62 -62
  56. package/src/components/menu/menu.js +273 -273
  57. package/src/components/page/header/index.less +40 -40
  58. package/src/components/setting/Setting.vue +235 -235
  59. package/src/components/table/StandardTable.vue +141 -141
  60. package/src/components/table/advance/ActionColumns.vue +158 -158
  61. package/src/components/table/advance/SearchArea.vue +355 -355
  62. package/src/components/tool/AStepItem.vue +60 -60
  63. package/src/components/tool/AvatarList.vue +68 -68
  64. package/src/components/tool/Drawer.vue +142 -142
  65. package/src/components/tool/TagSelect.vue +83 -83
  66. package/src/components/transition/PageToggleTransition.vue +97 -97
  67. package/src/config/CreateQueryConfig.js +307 -307
  68. package/src/config/default/admin.config.js +18 -18
  69. package/src/config/default/setting.config.js +3 -1
  70. package/src/config/replacer/resolve.config.js +67 -67
  71. package/src/layouts/CommonLayout.vue +42 -42
  72. package/src/layouts/ComponentLayoutOne.vue +47 -47
  73. package/src/layouts/PageLayout.vue +151 -151
  74. package/src/layouts/SinglePageView.vue +116 -116
  75. package/src/layouts/footer/PageFooter.vue +49 -49
  76. package/src/layouts/header/AdminHeader.vue +134 -134
  77. package/src/layouts/header/HeaderAvatar.vue +64 -64
  78. package/src/layouts/header/HeaderNotice.vue +176 -176
  79. package/src/layouts/header/HeaderSearch.vue +67 -67
  80. package/src/layouts/header/InstitutionDetail.vue +181 -181
  81. package/src/layouts/header/index.less +92 -92
  82. package/src/layouts/tabs/TabsHead.vue +190 -190
  83. package/src/layouts/tabs/TabsView.vue +379 -379
  84. package/src/mock/goods/index.js +108 -108
  85. package/src/pages/CreateQueryPage.vue +84 -84
  86. package/src/pages/login/Login.vue +369 -369
  87. package/src/pages/report/ReportTable.js +124 -124
  88. package/src/pages/report/ReportTableHome.vue +28 -28
  89. package/src/pages/resourceManage/orgListManage.vue +98 -98
  90. package/src/pages/system/dictionary/index.vue +43 -43
  91. package/src/pages/system/file/index.vue +317 -317
  92. package/src/pages/system/monitor/loginInfor/index.vue +36 -36
  93. package/src/pages/system/monitor/operLog/index.vue +36 -36
  94. package/src/pages/system/settings/index.vue +126 -126
  95. package/src/pages/system/settings/modifyPassword.vue +109 -109
  96. package/src/router/async/config.async.js +28 -28
  97. package/src/router/async/router.map.js +66 -66
  98. package/src/router/guards.js +52 -12
  99. package/src/router/index.js +27 -27
  100. package/src/services/api/DictionaryDetailsViewApi.js +6 -6
  101. package/src/services/api/LogDetailsViewApi.js +10 -10
  102. package/src/services/api/QueryParamsDetailsViewApi.js +6 -6
  103. package/src/services/api/TicketDetailsViewApi.js +34 -34
  104. package/src/services/api/cas.js +79 -79
  105. package/src/services/api/common.js +137 -137
  106. package/src/services/api/commonTempTable.js +10 -10
  107. package/src/services/api/index.js +17 -17
  108. package/src/services/api/logininfor/index.js +6 -6
  109. package/src/services/api/manage.js +8 -8
  110. package/src/services/apiService.js +14 -14
  111. package/src/services/user.js +67 -67
  112. package/src/store/modules/index.js +4 -4
  113. package/src/theme/default/nprogress.less +76 -76
  114. package/src/theme/default/style.less +58 -58
  115. package/src/utils/EncryptUtil.js +53 -53
  116. package/src/utils/colors.js +107 -107
  117. package/src/utils/excel/Blob.js +180 -180
  118. package/src/utils/excel/Export2Excel.js +141 -141
  119. package/src/utils/formatter.js +68 -68
  120. package/src/utils/i18n.js +80 -80
  121. package/src/utils/login.js +138 -0
  122. package/src/utils/map-utils.js +37 -37
  123. package/src/utils/theme-color-replacer-extend.js +91 -91
  124. package/src/utils/themeUtil.js +100 -100
  125. package/src/utils/util.js +230 -230
  126. package/vue.config.js +106 -106
@@ -1,62 +1,62 @@
1
- <template>
2
- <a-layout-sider
3
- :theme="sideTheme"
4
- :class="['side-menu', 'beauty-scroll', isMobile ? null : 'shadow']"
5
- width="256px"
6
- :collapsible="collapsible"
7
- v-model="collapsed"
8
- :trigger="null">
9
- <div :class="['logo', theme]">
10
- <router-link to="/dashboard/workplace">
11
- <img :src="logoSrc" alt="logo">
12
- <h1 :style="{ fontWeight: 'bold', fontSize: systemNameFontSize }">{{ systemName }}</h1>
13
- </router-link>
14
- </div>
15
- <i-menu :theme="theme" :collapsed="collapsed" :options="menuData" @select="onSelect" class="menu"/>
16
- </a-layout-sider>
17
- </template>
18
-
19
- <script>
20
- import IMenu from './menu'
21
- import { mapState } from 'vuex'
22
- export default {
23
- name: 'SideMenu',
24
- components: { IMenu },
25
- props: {
26
- collapsible: {
27
- type: Boolean,
28
- required: false,
29
- default: false
30
- },
31
- collapsed: {
32
- type: Boolean,
33
- required: false,
34
- default: false
35
- },
36
- menuData: {
37
- type: Array,
38
- required: true
39
- },
40
- theme: {
41
- type: String,
42
- required: false,
43
- default: 'dark'
44
- }
45
- },
46
- computed: {
47
- sideTheme () {
48
- return this.theme === 'light' ? this.theme : 'dark'
49
- },
50
- ...mapState('setting', ['isMobile', 'systemName', 'logoSrc', 'systemNameFontSize'])
51
- },
52
- methods: {
53
- onSelect (obj) {
54
- this.$emit('menuSelect', obj)
55
- }
56
- }
57
- }
58
- </script>
59
-
60
- <style lang="less" scoped>
61
- @import "index";
62
- </style>
1
+ <template>
2
+ <a-layout-sider
3
+ :theme="sideTheme"
4
+ :class="['side-menu', 'beauty-scroll', isMobile ? null : 'shadow']"
5
+ width="256px"
6
+ :collapsible="collapsible"
7
+ v-model="collapsed"
8
+ :trigger="null">
9
+ <div :class="['logo', theme]">
10
+ <router-link to="/dashboard/workplace">
11
+ <img :src="logoSrc" alt="logo">
12
+ <h1 :style="{ fontWeight: 'bold', fontSize: systemNameFontSize }">{{ systemName }}</h1>
13
+ </router-link>
14
+ </div>
15
+ <i-menu :theme="theme" :collapsed="collapsed" :options="menuData" @select="onSelect" class="menu"/>
16
+ </a-layout-sider>
17
+ </template>
18
+
19
+ <script>
20
+ import IMenu from './menu'
21
+ import { mapState } from 'vuex'
22
+ export default {
23
+ name: 'SideMenu',
24
+ components: { IMenu },
25
+ props: {
26
+ collapsible: {
27
+ type: Boolean,
28
+ required: false,
29
+ default: false
30
+ },
31
+ collapsed: {
32
+ type: Boolean,
33
+ required: false,
34
+ default: false
35
+ },
36
+ menuData: {
37
+ type: Array,
38
+ required: true
39
+ },
40
+ theme: {
41
+ type: String,
42
+ required: false,
43
+ default: 'dark'
44
+ }
45
+ },
46
+ computed: {
47
+ sideTheme () {
48
+ return this.theme === 'light' ? this.theme : 'dark'
49
+ },
50
+ ...mapState('setting', ['isMobile', 'systemName', 'logoSrc', 'systemNameFontSize'])
51
+ },
52
+ methods: {
53
+ onSelect (obj) {
54
+ this.$emit('menuSelect', obj)
55
+ }
56
+ }
57
+ }
58
+ </script>
59
+
60
+ <style lang="less" scoped>
61
+ @import "index";
62
+ </style>
@@ -1,273 +1,273 @@
1
- /**
2
- * 该插件可根据菜单配置自动生成 ANTD menu组件
3
- * menuOptions示例:
4
- * [
5
- * {
6
- * name: '菜单名称',
7
- * path: '菜单路由',
8
- * meta: {
9
- * icon: '菜单图标',
10
- * invisible: 'boolean, 是否不可见, 默认 false',
11
- * },
12
- * children: [子菜单配置]
13
- * },
14
- * {
15
- * name: '菜单名称',
16
- * path: '菜单路由',
17
- * meta: {
18
- * icon: '菜单图标',
19
- * invisible: 'boolean, 是否不可见, 默认 false',
20
- * },
21
- * children: [子菜单配置]
22
- * }
23
- * ]
24
- *
25
- * i18n: 国际化配置。系统默认会根据 options route配置的 path 和 name 生成英文以及中文的国际化配置,如需自定义或增加其他语言,配置
26
- * 此项即可。如:
27
- * i18n: {
28
- * messages: {
29
- * CN: {dashboard: {name: '监控中心'}}
30
- * HK: {dashboard: {name: '監控中心'}}
31
- * }
32
- * }
33
- **/
34
- import Menu from 'ant-design-vue/es/menu'
35
- import Icon from 'ant-design-vue/es/icon'
36
- import fastEqual from 'fast-deep-equal'
37
- import { getI18nKey } from '@vue2-client/utils/routerUtil'
38
- import { mapMutations } from 'vuex'
39
-
40
- const { Item, SubMenu } = Menu
41
-
42
- const resolvePath = (path, params = {}) => {
43
- let _path = path
44
- Object.entries(params).forEach(([key, value]) => {
45
- _path = _path.replace(new RegExp(`:${key}`, 'g'), value)
46
- })
47
- return _path
48
- }
49
-
50
- const toRoutesMap = (routes) => {
51
- const map = {}
52
- routes.forEach(route => {
53
- map[route.fullPath] = route
54
- if (route.children && route.children.length > 0) {
55
- const childrenMap = toRoutesMap(route.children)
56
- Object.assign(map, childrenMap)
57
- }
58
- })
59
- return map
60
- }
61
-
62
- export default {
63
- name: 'IMenu',
64
- props: {
65
- options: {
66
- type: Array,
67
- required: true
68
- },
69
- theme: {
70
- type: String,
71
- required: false,
72
- default: 'dark'
73
- },
74
- mode: {
75
- type: String,
76
- required: false,
77
- default: 'inline'
78
- },
79
- collapsed: {
80
- type: Boolean,
81
- required: false,
82
- default: false
83
- },
84
- i18n: Object,
85
- openKeys: Array
86
- },
87
- data () {
88
- return {
89
- selectedKeys: [],
90
- sOpenKeys: [],
91
- cachedOpenKeys: []
92
- }
93
- },
94
- computed: {
95
- menuTheme () {
96
- return this.theme === 'light' ? this.theme : 'dark'
97
- },
98
- routesMap () {
99
- return toRoutesMap(this.options)
100
- }
101
- },
102
- created () {
103
- this.updateMenu()
104
- if (this.options.length > 0 && !this.options[0].fullPath) {
105
- this.formatOptions(this.options, '')
106
- }
107
- // 自定义国际化配置
108
- if (this.i18n && this.i18n.messages) {
109
- const messages = this.i18n.messages
110
- Object.keys(messages).forEach(key => {
111
- this.$i18n.mergeLocaleMessage(key, messages[key])
112
- })
113
- }
114
- },
115
- watch: {
116
- options (val) {
117
- if (val.length > 0 && !val[0].fullPath) {
118
- this.formatOptions(this.options, '')
119
- }
120
- },
121
- i18n (val) {
122
- if (val && val.messages) {
123
- const messages = this.i18n.messages
124
- Object.keys(messages).forEach(key => {
125
- this.$i18n.mergeLocaleMessage(key, messages[key])
126
- })
127
- }
128
- },
129
- collapsed (val) {
130
- if (val) {
131
- this.cachedOpenKeys = this.sOpenKeys
132
- this.sOpenKeys = []
133
- } else {
134
- this.sOpenKeys = this.cachedOpenKeys
135
- }
136
- },
137
- '$route': function () {
138
- if (this.$route.meta && this.$route.meta.singlePage) {
139
- this.setSingle(this.$route)
140
- }
141
- this.updateMenu()
142
- },
143
- sOpenKeys (val) {
144
- this.$emit('openChange', val)
145
- this.$emit('update:openKeys', val)
146
- }
147
- },
148
- methods: {
149
- ...mapMutations('account', ['setSingle']),
150
- renderIcon: function (h, icon, key) {
151
- if (this.$scopedSlots.icon && icon && icon !== 'none') {
152
- const vnodes = this.$scopedSlots.icon({ icon, key })
153
- vnodes.forEach(vnode => {
154
- vnode.data.class = vnode.data.class ? vnode.data.class : []
155
- vnode.data.class.push('anticon')
156
- })
157
- return vnodes
158
- }
159
- return !icon || icon === 'none' ? null : h(Icon, { props: { type: icon } })
160
- },
161
- renderMenuItem: function (h, menu) {
162
- let tag = 'router-link'
163
- const path = resolvePath(menu.fullPath, menu.meta.params)
164
- let config = { props: { to: { path, query: menu.meta.query } }, attrs: { style: 'overflow:hidden;white-space:normal;text-overflow:clip;' } }
165
- if (menu.meta && menu.meta.link) {
166
- tag = 'a'
167
- config = { attrs: { style: 'overflow:hidden;white-space:normal;text-overflow:clip;', href: menu.meta.link, target: '_blank' } }
168
- }
169
- return h(
170
- Item, { key: menu.fullPath },
171
- [
172
- h(tag, config,
173
- [
174
- this.renderIcon(h, menu.meta ? menu.meta.icon : 'none', menu.fullPath),
175
- this.$t(getI18nKey(menu.fullPath))
176
- ]
177
- )
178
- ]
179
- )
180
- },
181
- renderSubMenu: function (h, menu) {
182
- const this_ = this
183
- const subItem = [h('span', { slot: 'title', attrs: { style: 'overflow:hidden;white-space:normal;text-overflow:clip;' } },
184
- [
185
- this.renderIcon(h, menu.meta ? menu.meta.icon : 'none', menu.fullPath),
186
- this.$t(getI18nKey(menu.fullPath))
187
- ]
188
- )]
189
- const itemArr = []
190
- menu.children.forEach(function (item) {
191
- itemArr.push(this_.renderItem(h, item))
192
- })
193
- return h(SubMenu, { key: menu.fullPath },
194
- subItem.concat(itemArr)
195
- )
196
- },
197
- renderItem: function (h, menu) {
198
- const meta = menu.meta
199
- if (!meta || !meta.invisible) {
200
- let renderChildren = false
201
- const children = menu.children
202
- if (children !== undefined) {
203
- for (let i = 0; i < children.length; i++) {
204
- const childMeta = children[i].meta
205
- if (!childMeta || !childMeta.invisible) {
206
- renderChildren = true
207
- break
208
- }
209
- }
210
- }
211
- return (menu.children && renderChildren) ? this.renderSubMenu(h, menu) : this.renderMenuItem(h, menu)
212
- }
213
- },
214
- renderMenu: function (h, menuTree) {
215
- const this_ = this
216
- const menuArr = []
217
- menuTree.forEach(function (menu, i) {
218
- menuArr.push(this_.renderItem(h, menu, '0', i))
219
- })
220
- return menuArr
221
- },
222
- formatOptions (options, parentPath) {
223
- options.forEach(route => {
224
- const isFullPath = route.path.substring(0, 1) === '/'
225
- route.fullPath = isFullPath ? route.path : parentPath + '/' + route.path
226
- if (route.children) {
227
- this.formatOptions(route.children, route.fullPath)
228
- }
229
- })
230
- },
231
- updateMenu () {
232
- this.selectedKeys = this.getSelectedKeys()
233
- let openKeys = this.selectedKeys.filter(item => item !== '')
234
- openKeys = openKeys.slice(0, openKeys.length - 1)
235
- if (!fastEqual(openKeys, this.sOpenKeys)) {
236
- this.collapsed || this.mode === 'horizontal' ? this.cachedOpenKeys = openKeys : this.sOpenKeys = openKeys
237
- }
238
- },
239
- getSelectedKeys () {
240
- let matches = this.$route.matched
241
- const route = matches[matches.length - 1]
242
- let chose = this.routesMap[route.path]
243
- if (chose && chose.meta && chose.meta.highlight) {
244
- chose = this.routesMap[chose.meta.highlight]
245
- const resolve = this.$router.resolve({ path: chose.fullPath })
246
- matches = (resolve.resolved && resolve.resolved.matched) || matches
247
- }
248
- return matches.map(item => item.path)
249
- }
250
- },
251
- render (h) {
252
- return h(
253
- Menu,
254
- {
255
- props: {
256
- theme: this.menuTheme,
257
- mode: this.$props.mode,
258
- selectedKeys: this.selectedKeys,
259
- openKeys: this.openKeys ? this.openKeys : this.sOpenKeys
260
- },
261
- on: {
262
- 'update:openKeys': (val) => {
263
- this.sOpenKeys = val
264
- },
265
- click: (obj) => {
266
- obj.selectedKeys = [obj.key]
267
- this.$emit('select', obj)
268
- }
269
- }
270
- }, this.renderMenu(h, this.options)
271
- )
272
- }
273
- }
1
+ /**
2
+ * 该插件可根据菜单配置自动生成 ANTD menu组件
3
+ * menuOptions示例:
4
+ * [
5
+ * {
6
+ * name: '菜单名称',
7
+ * path: '菜单路由',
8
+ * meta: {
9
+ * icon: '菜单图标',
10
+ * invisible: 'boolean, 是否不可见, 默认 false',
11
+ * },
12
+ * children: [子菜单配置]
13
+ * },
14
+ * {
15
+ * name: '菜单名称',
16
+ * path: '菜单路由',
17
+ * meta: {
18
+ * icon: '菜单图标',
19
+ * invisible: 'boolean, 是否不可见, 默认 false',
20
+ * },
21
+ * children: [子菜单配置]
22
+ * }
23
+ * ]
24
+ *
25
+ * i18n: 国际化配置。系统默认会根据 options route配置的 path 和 name 生成英文以及中文的国际化配置,如需自定义或增加其他语言,配置
26
+ * 此项即可。如:
27
+ * i18n: {
28
+ * messages: {
29
+ * CN: {dashboard: {name: '监控中心'}}
30
+ * HK: {dashboard: {name: '監控中心'}}
31
+ * }
32
+ * }
33
+ **/
34
+ import Menu from 'ant-design-vue/es/menu'
35
+ import Icon from 'ant-design-vue/es/icon'
36
+ import fastEqual from 'fast-deep-equal'
37
+ import { getI18nKey } from '@vue2-client/utils/routerUtil'
38
+ import { mapMutations } from 'vuex'
39
+
40
+ const { Item, SubMenu } = Menu
41
+
42
+ const resolvePath = (path, params = {}) => {
43
+ let _path = path
44
+ Object.entries(params).forEach(([key, value]) => {
45
+ _path = _path.replace(new RegExp(`:${key}`, 'g'), value)
46
+ })
47
+ return _path
48
+ }
49
+
50
+ const toRoutesMap = (routes) => {
51
+ const map = {}
52
+ routes.forEach(route => {
53
+ map[route.fullPath] = route
54
+ if (route.children && route.children.length > 0) {
55
+ const childrenMap = toRoutesMap(route.children)
56
+ Object.assign(map, childrenMap)
57
+ }
58
+ })
59
+ return map
60
+ }
61
+
62
+ export default {
63
+ name: 'IMenu',
64
+ props: {
65
+ options: {
66
+ type: Array,
67
+ required: true
68
+ },
69
+ theme: {
70
+ type: String,
71
+ required: false,
72
+ default: 'dark'
73
+ },
74
+ mode: {
75
+ type: String,
76
+ required: false,
77
+ default: 'inline'
78
+ },
79
+ collapsed: {
80
+ type: Boolean,
81
+ required: false,
82
+ default: false
83
+ },
84
+ i18n: Object,
85
+ openKeys: Array
86
+ },
87
+ data () {
88
+ return {
89
+ selectedKeys: [],
90
+ sOpenKeys: [],
91
+ cachedOpenKeys: []
92
+ }
93
+ },
94
+ computed: {
95
+ menuTheme () {
96
+ return this.theme === 'light' ? this.theme : 'dark'
97
+ },
98
+ routesMap () {
99
+ return toRoutesMap(this.options)
100
+ }
101
+ },
102
+ created () {
103
+ this.updateMenu()
104
+ if (this.options.length > 0 && !this.options[0].fullPath) {
105
+ this.formatOptions(this.options, '')
106
+ }
107
+ // 自定义国际化配置
108
+ if (this.i18n && this.i18n.messages) {
109
+ const messages = this.i18n.messages
110
+ Object.keys(messages).forEach(key => {
111
+ this.$i18n.mergeLocaleMessage(key, messages[key])
112
+ })
113
+ }
114
+ },
115
+ watch: {
116
+ options (val) {
117
+ if (val.length > 0 && !val[0].fullPath) {
118
+ this.formatOptions(this.options, '')
119
+ }
120
+ },
121
+ i18n (val) {
122
+ if (val && val.messages) {
123
+ const messages = this.i18n.messages
124
+ Object.keys(messages).forEach(key => {
125
+ this.$i18n.mergeLocaleMessage(key, messages[key])
126
+ })
127
+ }
128
+ },
129
+ collapsed (val) {
130
+ if (val) {
131
+ this.cachedOpenKeys = this.sOpenKeys
132
+ this.sOpenKeys = []
133
+ } else {
134
+ this.sOpenKeys = this.cachedOpenKeys
135
+ }
136
+ },
137
+ '$route': function () {
138
+ if (this.$route.meta && this.$route.meta.singlePage) {
139
+ this.setSingle(this.$route)
140
+ }
141
+ this.updateMenu()
142
+ },
143
+ sOpenKeys (val) {
144
+ this.$emit('openChange', val)
145
+ this.$emit('update:openKeys', val)
146
+ }
147
+ },
148
+ methods: {
149
+ ...mapMutations('account', ['setSingle']),
150
+ renderIcon: function (h, icon, key) {
151
+ if (this.$scopedSlots.icon && icon && icon !== 'none') {
152
+ const vnodes = this.$scopedSlots.icon({ icon, key })
153
+ vnodes.forEach(vnode => {
154
+ vnode.data.class = vnode.data.class ? vnode.data.class : []
155
+ vnode.data.class.push('anticon')
156
+ })
157
+ return vnodes
158
+ }
159
+ return !icon || icon === 'none' ? null : h(Icon, { props: { type: icon } })
160
+ },
161
+ renderMenuItem: function (h, menu) {
162
+ let tag = 'router-link'
163
+ const path = resolvePath(menu.fullPath, menu.meta.params)
164
+ let config = { props: { to: { path, query: menu.meta.query } }, attrs: { style: 'overflow:hidden;white-space:normal;text-overflow:clip;' } }
165
+ if (menu.meta && menu.meta.link) {
166
+ tag = 'a'
167
+ config = { attrs: { style: 'overflow:hidden;white-space:normal;text-overflow:clip;', href: menu.meta.link, target: '_blank' } }
168
+ }
169
+ return h(
170
+ Item, { key: menu.fullPath },
171
+ [
172
+ h(tag, config,
173
+ [
174
+ this.renderIcon(h, menu.meta ? menu.meta.icon : 'none', menu.fullPath),
175
+ this.$t(getI18nKey(menu.fullPath))
176
+ ]
177
+ )
178
+ ]
179
+ )
180
+ },
181
+ renderSubMenu: function (h, menu) {
182
+ const this_ = this
183
+ const subItem = [h('span', { slot: 'title', attrs: { style: 'overflow:hidden;white-space:normal;text-overflow:clip;' } },
184
+ [
185
+ this.renderIcon(h, menu.meta ? menu.meta.icon : 'none', menu.fullPath),
186
+ this.$t(getI18nKey(menu.fullPath))
187
+ ]
188
+ )]
189
+ const itemArr = []
190
+ menu.children.forEach(function (item) {
191
+ itemArr.push(this_.renderItem(h, item))
192
+ })
193
+ return h(SubMenu, { key: menu.fullPath },
194
+ subItem.concat(itemArr)
195
+ )
196
+ },
197
+ renderItem: function (h, menu) {
198
+ const meta = menu.meta
199
+ if (!meta || !meta.invisible) {
200
+ let renderChildren = false
201
+ const children = menu.children
202
+ if (children !== undefined) {
203
+ for (let i = 0; i < children.length; i++) {
204
+ const childMeta = children[i].meta
205
+ if (!childMeta || !childMeta.invisible) {
206
+ renderChildren = true
207
+ break
208
+ }
209
+ }
210
+ }
211
+ return (menu.children && renderChildren) ? this.renderSubMenu(h, menu) : this.renderMenuItem(h, menu)
212
+ }
213
+ },
214
+ renderMenu: function (h, menuTree) {
215
+ const this_ = this
216
+ const menuArr = []
217
+ menuTree.forEach(function (menu, i) {
218
+ menuArr.push(this_.renderItem(h, menu, '0', i))
219
+ })
220
+ return menuArr
221
+ },
222
+ formatOptions (options, parentPath) {
223
+ options.forEach(route => {
224
+ const isFullPath = route.path.substring(0, 1) === '/'
225
+ route.fullPath = isFullPath ? route.path : parentPath + '/' + route.path
226
+ if (route.children) {
227
+ this.formatOptions(route.children, route.fullPath)
228
+ }
229
+ })
230
+ },
231
+ updateMenu () {
232
+ this.selectedKeys = this.getSelectedKeys()
233
+ let openKeys = this.selectedKeys.filter(item => item !== '')
234
+ openKeys = openKeys.slice(0, openKeys.length - 1)
235
+ if (!fastEqual(openKeys, this.sOpenKeys)) {
236
+ this.collapsed || this.mode === 'horizontal' ? this.cachedOpenKeys = openKeys : this.sOpenKeys = openKeys
237
+ }
238
+ },
239
+ getSelectedKeys () {
240
+ let matches = this.$route.matched
241
+ const route = matches[matches.length - 1]
242
+ let chose = this.routesMap[route.path]
243
+ if (chose && chose.meta && chose.meta.highlight) {
244
+ chose = this.routesMap[chose.meta.highlight]
245
+ const resolve = this.$router.resolve({ path: chose.fullPath })
246
+ matches = (resolve.resolved && resolve.resolved.matched) || matches
247
+ }
248
+ return matches.map(item => item.path)
249
+ }
250
+ },
251
+ render (h) {
252
+ return h(
253
+ Menu,
254
+ {
255
+ props: {
256
+ theme: this.menuTheme,
257
+ mode: this.$props.mode,
258
+ selectedKeys: this.selectedKeys,
259
+ openKeys: this.openKeys ? this.openKeys : this.sOpenKeys
260
+ },
261
+ on: {
262
+ 'update:openKeys': (val) => {
263
+ this.sOpenKeys = val
264
+ },
265
+ click: (obj) => {
266
+ obj.selectedKeys = [obj.key]
267
+ this.$emit('select', obj)
268
+ }
269
+ }
270
+ }, this.renderMenu(h, this.options)
271
+ )
272
+ }
273
+ }