vue2-client 1.4.9 → 1.4.10

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 (101) hide show
  1. package/.env +15 -15
  2. package/.eslintrc.js +82 -82
  3. package/CHANGELOG.md +4 -0
  4. package/index.js +30 -30
  5. package/package.json +1 -1
  6. package/src/base-client/components/common/AddressSearchCombobox/AddressSearchCombobox.vue +225 -225
  7. package/src/base-client/components/common/AmapMarker/AmapPointRendering.vue +113 -113
  8. package/src/base-client/components/common/CitySelect/CitySelect.vue +244 -244
  9. package/src/base-client/components/common/CitySelect/index.js +3 -3
  10. package/src/base-client/components/common/CitySelect/index.md +109 -109
  11. package/src/base-client/components/common/CreateQuery/CreateQuery.vue +591 -591
  12. package/src/base-client/components/common/CreateQuery/CreateQueryItem.vue +777 -777
  13. package/src/base-client/components/common/CreateSimpleFormQuery/CreateSimpleFormQuery.vue +310 -310
  14. package/src/base-client/components/common/CreateSimpleFormQuery/CreateSimpleFormQueryItem.vue +553 -553
  15. package/src/base-client/components/common/FormGroupQuery/FormGroupQuery.vue +165 -165
  16. package/src/base-client/components/common/JSONToTree/jsontotree.vue +275 -275
  17. package/src/base-client/components/common/PersonSetting/PersonSetting.vue +210 -210
  18. package/src/base-client/components/common/PersonSetting/index.js +3 -3
  19. package/src/base-client/components/common/Upload/index.js +3 -3
  20. package/src/base-client/components/common/XAddForm/XAddForm.vue +354 -354
  21. package/src/base-client/components/common/XAddNativeForm/XAddNativeForm.vue +327 -327
  22. package/src/base-client/components/common/XCard/XCard.vue +64 -64
  23. package/src/base-client/components/common/XForm/XForm.vue +274 -274
  24. package/src/base-client/components/common/XForm/XFormItem.vue +389 -389
  25. package/src/base-client/components/common/XFormTable/XFormTable.vue +2 -1
  26. package/src/base-client/components/common/XFormTable/index.md +96 -96
  27. package/src/base-client/components/common/XTable/XTable.vue +262 -262
  28. package/src/base-client/components/system/QueryParamsDetailsView/QueryParamsDetailsView.vue +281 -281
  29. package/src/base-client/components/ticket/TicketDetailsView/TicketDetailsView.vue +807 -807
  30. package/src/base-client/components/ticket/TicketDetailsView/index.md +29 -29
  31. package/src/base-client/components/ticket/TicketDetailsView/part/TicketDetailsFlow.vue +260 -260
  32. package/src/base-client/components/ticket/TicketSubmitSuccessView/TicketSubmitSuccessView.vue +532 -532
  33. package/src/base-client/components/ticket/TicketSubmitSuccessView/index.md +29 -29
  34. package/src/base-client/plugins/AppData.js +69 -69
  35. package/src/base-client/plugins/GetLoginInfoService.js +179 -179
  36. package/src/base-client/plugins/PagedList.js +177 -177
  37. package/src/base-client/plugins/compatible/LoginServiceOA.js +20 -20
  38. package/src/base-client/plugins/i18n-extend.js +32 -32
  39. package/src/components/Ellipsis/index.md +38 -38
  40. package/src/components/NumberInfo/index.md +43 -43
  41. package/src/components/STable/README.md +341 -341
  42. package/src/components/STable/index.js +318 -318
  43. package/src/components/Trend/index.md +45 -45
  44. package/src/components/checkbox/ColorCheckbox.vue +157 -157
  45. package/src/components/checkbox/ImgCheckbox.vue +163 -163
  46. package/src/components/exception/ExceptionPage.vue +70 -70
  47. package/src/components/form/FormRow.vue +52 -52
  48. package/src/components/index.js +36 -36
  49. package/src/components/menu/SideMenu.vue +62 -62
  50. package/src/components/menu/menu.js +273 -273
  51. package/src/components/setting/Setting.vue +235 -235
  52. package/src/components/table/StandardTable.vue +141 -141
  53. package/src/components/table/advance/ActionColumns.vue +158 -158
  54. package/src/components/table/advance/SearchArea.vue +355 -355
  55. package/src/components/tool/AStepItem.vue +60 -60
  56. package/src/components/tool/AvatarList.vue +68 -68
  57. package/src/components/tool/Drawer.vue +142 -142
  58. package/src/components/tool/TagSelect.vue +83 -83
  59. package/src/components/transition/PageToggleTransition.vue +97 -97
  60. package/src/config/CreateQueryConfig.js +307 -307
  61. package/src/config/replacer/resolve.config.js +67 -67
  62. package/src/layouts/AdminLayout.vue +174 -174
  63. package/src/layouts/header/AdminHeader.vue +104 -104
  64. package/src/layouts/header/HeaderNotice.vue +167 -167
  65. package/src/layouts/header/HeaderSearch.vue +67 -67
  66. package/src/layouts/header/InstitutionDetail.vue +181 -181
  67. package/src/layouts/tabs/TabsHead.vue +190 -190
  68. package/src/layouts/tabs/TabsView.vue +379 -379
  69. package/src/mock/goods/index.js +108 -108
  70. package/src/pages/CreateQueryPage.vue +65 -65
  71. package/src/pages/report/ReportTable.js +124 -124
  72. package/src/pages/report/ReportTableHome.vue +28 -28
  73. package/src/pages/resourceManage/orgListManage.vue +98 -98
  74. package/src/pages/system/dictionary/index.vue +43 -43
  75. package/src/pages/system/file/index.vue +317 -317
  76. package/src/pages/system/queryParams/index.vue +43 -43
  77. package/src/router/async/config.async.js +27 -27
  78. package/src/router/async/router.map.js +2 -0
  79. package/src/router/index.js +27 -27
  80. package/src/services/api/DictionaryDetailsViewApi.js +6 -6
  81. package/src/services/api/LogDetailsViewApi.js +10 -10
  82. package/src/services/api/QueryParamsDetailsViewApi.js +6 -6
  83. package/src/services/api/TicketDetailsViewApi.js +34 -34
  84. package/src/services/api/commonTempTable.js +10 -10
  85. package/src/services/api/index.js +17 -17
  86. package/src/services/api/manage.js +8 -8
  87. package/src/services/api/restTools.js +24 -24
  88. package/src/store/mutation-types.js +2 -2
  89. package/src/theme/default/nprogress.less +76 -76
  90. package/src/theme/default/style.less +47 -47
  91. package/src/utils/colors.js +103 -103
  92. package/src/utils/excel/Blob.js +180 -180
  93. package/src/utils/excel/Export2Excel.js +141 -141
  94. package/src/utils/formatter.js +68 -68
  95. package/src/utils/i18n.js +80 -80
  96. package/src/utils/request.js +225 -225
  97. package/src/utils/routerUtil.js +364 -364
  98. package/src/utils/theme-color-replacer-extend.js +91 -91
  99. package/src/utils/themeUtil.js +100 -100
  100. package/src/utils/util.js +230 -230
  101. package/vue.config.js +2 -2
@@ -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.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.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
+ }