n20-common-lib 1.2.1 → 1.2.4

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 (186) hide show
  1. package/README.md +3 -27
  2. package/package.json +87 -87
  3. package/src/_qiankun/index.js +113 -113
  4. package/src/_qiankun/postMessage.js +48 -48
  5. package/src/assets/css/_coreLib.scss +35 -35
  6. package/src/assets/css/cl-anchor.scss +23 -23
  7. package/src/assets/css/cl-approve-card.scss +58 -58
  8. package/src/assets/css/cl-dialog.scss +99 -99
  9. package/src/assets/css/cl-drag-list.scss +22 -22
  10. package/src/assets/css/cl-empty.scss +10 -10
  11. package/src/assets/css/cl-expandable-pane.scss +26 -25
  12. package/src/assets/css/cl-expandable.scss +24 -23
  13. package/src/assets/css/cl-file-upload-table.scss +11 -11
  14. package/src/assets/css/cl-filter.scss +4 -4
  15. package/src/assets/css/cl-flow-step.scss +185 -185
  16. package/src/assets/css/cl-footer-box.scss +10 -10
  17. package/src/assets/css/cl-form-item.scss +331 -322
  18. package/src/assets/css/cl-general-card.scss +11 -11
  19. package/src/assets/css/cl-layout-aside.scss +88 -96
  20. package/src/assets/css/cl-layout-content.scss +16 -16
  21. package/src/assets/css/cl-layout-header.scss +73 -73
  22. package/src/assets/css/cl-layout-tabs.scss +87 -87
  23. package/src/assets/css/cl-layout.scss +97 -97
  24. package/src/assets/css/cl-login-temporary.scss +37 -37
  25. package/src/assets/css/cl-message.scss +75 -75
  26. package/src/assets/css/cl-more-tab.scss +98 -98
  27. package/src/assets/css/cl-nav-menu.scss +5 -5
  28. package/src/assets/css/cl-pagination.scss +65 -65
  29. package/src/assets/css/cl-secondary-tab.scss +39 -39
  30. package/src/assets/css/cl-showcolumn.scss +23 -23
  31. package/src/assets/css/cl-sifting.scss +51 -51
  32. package/src/assets/css/cl-statis.scss +42 -42
  33. package/src/assets/css/cl-step.scss +73 -73
  34. package/src/assets/css/cl-suspend.scss +19 -19
  35. package/src/assets/css/cl-tertiary-tab.scss +9 -9
  36. package/src/assets/css/cl-upload.scss +41 -41
  37. package/src/assets/css/cl-worn-pagination.scss +50 -50
  38. package/src/assets/css/el-button.scss +173 -169
  39. package/src/assets/css/el-table.scss +79 -79
  40. package/src/assets/css/element-variables.scss +1061 -1061
  41. package/src/assets/css/element.dev.scss +21 -21
  42. package/src/assets/css/font-icon.scss +26 -26
  43. package/src/assets/css/index.dev.scss +4 -4
  44. package/src/assets/css/index.scss +11 -11
  45. package/src/assets/css/normalize.scss +726 -723
  46. package/src/assets/css/rootvar.scss +139 -139
  47. package/src/assets/css/select.scss +25 -25
  48. package/src/assets/css/title-pop.scss +4 -4
  49. package/src/assets/getJsonc.js +50 -50
  50. package/src/assets/realUrl.js +12 -12
  51. package/src/components/Anchor/AnchorItem.vue +29 -29
  52. package/src/components/Anchor/index.vue +185 -185
  53. package/src/components/ApprovalButtons/index.vue +232 -232
  54. package/src/components/ApprovalCard/index.vue +128 -128
  55. package/src/components/ApprovalRecord/approvalImg.vue +39 -39
  56. package/src/components/ApprovalRecord/index.vue +59 -59
  57. package/src/components/Button/button-group.vue +150 -150
  58. package/src/components/Button/icon-group-button.vue +61 -61
  59. package/src/components/Button/index.vue +56 -56
  60. package/src/components/CascaderArea/index.vue +81 -0
  61. package/src/components/ContentLoading/index.vue +41 -41
  62. package/src/components/ContentNull/index.vue +19 -19
  63. package/src/components/DatePicker/index.vue +27 -27
  64. package/src/components/DatePicker/por.vue +169 -169
  65. package/src/components/Dialog/index.vue +26 -26
  66. package/src/components/Dialog/indexO.vue +116 -116
  67. package/src/components/DragList/index.vue +68 -68
  68. package/src/components/Empty/img/abnormal.svg +108 -108
  69. package/src/components/Empty/img/dispose.svg +71 -71
  70. package/src/components/Empty/img/empty.svg +57 -57
  71. package/src/components/Empty/img/general.svg +58 -58
  72. package/src/components/Empty/img/lock.svg +57 -57
  73. package/src/components/Empty/img/network.svg +59 -59
  74. package/src/components/Empty/img/relevant.svg +68 -68
  75. package/src/components/Empty/img/search.svg +72 -72
  76. package/src/components/Empty/index.vue +92 -92
  77. package/src/components/Expandable/index.vue +49 -49
  78. package/src/components/Expandable/main.vue +52 -52
  79. package/src/components/FileUploadTable/index.vue +484 -484
  80. package/src/components/Filters/index.vue +363 -358
  81. package/src/components/Filters/indexO.vue +104 -104
  82. package/src/components/FlowStep/index.vue +68 -68
  83. package/src/components/FooterBox/index.vue +21 -21
  84. package/src/components/GeneralCard/index.vue +15 -15
  85. package/src/components/InputNumber/index.vue +153 -153
  86. package/src/components/InputNumber/numberRange.vue +47 -47
  87. package/src/components/InputSearch/index.vue +75 -75
  88. package/src/components/Layout/AsideNav/index.vue +144 -144
  89. package/src/components/Layout/HeaderWrap/changePwd.vue +215 -215
  90. package/src/components/Layout/HeaderWrap/index.vue +333 -336
  91. package/src/components/Layout/HeaderWrap/noticePop.vue +300 -300
  92. package/src/components/Layout/SubContent/index.vue +131 -131
  93. package/src/components/Layout/TabsNav/index.vue +170 -170
  94. package/src/components/Layout/index.vue +529 -529
  95. package/src/components/Layout/utils.js +12 -12
  96. package/src/components/LoginTemporary/form.vue +537 -511
  97. package/src/components/LoginTemporary/index.vue +122 -122
  98. package/src/components/LoginTemporary/qrcode.vue +90 -90
  99. package/src/components/LoginTemporary/retrievePw.vue +28 -28
  100. package/src/components/LoginTemporary/utils.js +73 -73
  101. package/src/components/MicroApp/index.js +67 -67
  102. package/src/components/MicroFrame/index.vue +95 -95
  103. package/src/components/MoreTab/index.vue +232 -232
  104. package/src/components/NavMenu/index.vue +60 -60
  105. package/src/components/NstcG6Components/NstcDialog/NstcDialog.vue +184 -184
  106. package/src/components/PageLayout/page.vue +15 -15
  107. package/src/components/Pagination/index.vue +96 -96
  108. package/src/components/SecondaryTab/index.vue +58 -58
  109. package/src/components/SelectLazy/index.vue +75 -75
  110. package/src/components/SelectTree/SelectTreeLazy.vue +241 -241
  111. package/src/components/SelectTree/index.vue +205 -208
  112. package/src/components/ShowColumn/index.vue +204 -188
  113. package/src/components/Sifting/index.vue +99 -99
  114. package/src/components/Statis/index.vue +97 -97
  115. package/src/components/Statis/statisItem.vue +54 -54
  116. package/src/components/Statis/statisPopover.vue +55 -55
  117. package/src/components/Step/index.vue +38 -38
  118. package/src/components/Suspend/index.vue +72 -72
  119. package/src/components/Table/index.vue +170 -131
  120. package/src/components/Table/indexO.vue +149 -149
  121. package/src/components/Task/index.vue +26 -26
  122. package/src/components/TertiaryTab/index.vue +53 -53
  123. package/src/components/TimePicker/index.vue +28 -28
  124. package/src/components/Upload/index.vue +242 -242
  125. package/src/components/WornPagination/index.vue +73 -73
  126. package/src/directives/VClickOutside/index.js +19 -19
  127. package/src/directives/VHas/index.js +32 -27
  128. package/src/directives/VMove/index.js +42 -42
  129. package/src/directives/VTitle/index.js +56 -56
  130. package/src/directives/VTitle/tooltip.vue +21 -21
  131. package/src/index.js +218 -225
  132. package/src/plugins/CompatibleOld/index.js +57 -57
  133. package/src/plugins/Print/index.js +4 -4
  134. package/src/plugins/Print/print-js/.babelrc +12 -12
  135. package/src/plugins/Print/print-js/LICENSE +21 -21
  136. package/src/plugins/Print/print-js/README.md +98 -98
  137. package/src/plugins/Print/print-js/dist/print.css +96 -96
  138. package/src/plugins/Print/print-js/dist/print.js +990 -990
  139. package/src/plugins/Print/print-js/package.json +60 -60
  140. package/src/plugins/Print/print-js/src/index.d.ts +45 -45
  141. package/src/plugins/Print/print-js/src/index.js +10 -10
  142. package/src/plugins/Print/print-js/src/js/browser.js +33 -33
  143. package/src/plugins/Print/print-js/src/js/functions.js +103 -103
  144. package/src/plugins/Print/print-js/src/js/html.js +70 -70
  145. package/src/plugins/Print/print-js/src/js/image.js +48 -48
  146. package/src/plugins/Print/print-js/src/js/init.js +168 -168
  147. package/src/plugins/Print/print-js/src/js/json.js +109 -109
  148. package/src/plugins/Print/print-js/src/js/modal.js +62 -62
  149. package/src/plugins/Print/print-js/src/js/pdf.js +62 -62
  150. package/src/plugins/Print/print-js/src/js/print.js +102 -102
  151. package/src/plugins/Print/print-js/src/js/raw-html.js +15 -15
  152. package/src/plugins/Print/print-js/src/sass/index.scss +13 -13
  153. package/src/plugins/Print/print-js/src/sass/modules/_colors.scss +9 -9
  154. package/src/plugins/Print/print-js/src/sass/partials/_modal.scss +40 -40
  155. package/src/plugins/Print/print-js/src/sass/partials/_spinner.scss +45 -45
  156. package/src/plugins/Print/print.js +2 -2
  157. package/src/plugins/Print/print.scss +1 -1
  158. package/src/plugins/SetMenuTree/index.vue +41 -41
  159. package/src/plugins/SetMenuTree/logoIcon.vue +37 -37
  160. package/src/plugins/SetMenuTree/setmenutree.vue +427 -427
  161. package/src/plugins/SetMenuTree/utils.js +74 -74
  162. package/src/plugins/Sign/InfosecNetSignCNGAgent.min.js +2000 -2000
  163. package/src/plugins/Sign/index.js +65 -65
  164. package/src/plugins/Sign/sign.js +1 -1
  165. package/src/plugins/setTabsForSub.js +2 -2
  166. package/src/utils/auth.js +53 -53
  167. package/src/utils/axios.js +203 -203
  168. package/src/utils/downloadBlob.js +19 -19
  169. package/src/utils/forEachs.js +16 -16
  170. package/src/utils/getScrollContainer.js +43 -43
  171. package/src/utils/i18n/cn2hk.json +1270 -1270
  172. package/src/utils/i18n/index.js +54 -54
  173. package/src/utils/list2tree.js +36 -36
  174. package/src/utils/msgboxPor.js +26 -26
  175. package/src/utils/print.js +161 -161
  176. package/src/utils/relaNo.js +69 -35
  177. package/src/utils/repairElementUI.js +66 -66
  178. package/src/utils/urlToGo.js +82 -82
  179. package/style/css/normalize.scss +726 -723
  180. package/style/index.css +1 -1
  181. package/style/index.css.map +1 -1
  182. package/style/pageDemo/demo-1.vue +131 -130
  183. package/style/pageDemo/demo-2.vue +35 -35
  184. package/style/pageDemo/demo-3.vue +22 -22
  185. package/style/pageDemo/seeCode.js +20 -20
  186. package/style/server-config.jsonc +596 -663
@@ -1,427 +1,427 @@
1
- <template>
2
- <div class="flex-box" style="height: 420px">
3
- <div class="flex-column bd-r" style="width: 300px; height: 100%">
4
- <div class="flex-box flex-v">
5
- <span>导航菜单树</span>
6
- <el-button
7
- class="m-l-auto"
8
- type="primary"
9
- size="mini"
10
- @click="saveMenuTree"
11
- >保存菜单树</el-button
12
- >
13
- <el-button class="m-r-s" plain size="mini" @click="addFF"
14
- >新建目录</el-button
15
- >
16
- </div>
17
- <el-tree
18
- ref="menu-tree"
19
- class="flex-item p-t p-b"
20
- :data="menuTree"
21
- :props="{
22
- children: 'children',
23
- label: 'label'
24
- }"
25
- node-key="menuid"
26
- highlight-current
27
- draggable
28
- style="overflow: auto"
29
- @node-click="clickMenu"
30
- >
31
- <span
32
- slot-scope="{ node, data }"
33
- class="menu-item flex-item flex-box flex-lr flex-v"
34
- >
35
- <span>
36
- <logoIcon
37
- v-if="data.logo"
38
- :logo="data.logo"
39
- width="14px"
40
- style="vertical-align: bottom"
41
- />
42
- {{ node.label || '未命名...' }}</span
43
- >
44
- <span class="menu-item-btn m-r">
45
- <el-button
46
- v-title="'新增下级'"
47
- icon="el-icon-document-add"
48
- plain
49
- onlyicon
50
- size="mini"
51
- @click.stop="() => appendMenu(data)"
52
- />
53
- <el-button
54
- v-title="'删除本级和下级'"
55
- icon="el-icon-document-delete"
56
- plain
57
- onlyicon
58
- size="mini"
59
- @click.stop="() => removeMenu(node, data)"
60
- />
61
- </span>
62
- </span>
63
- </el-tree>
64
- </div>
65
- <div class="flex-item p-l flex-column" style="height: 100%">
66
- <div style="line-height: 28px">菜单/按钮详情</div>
67
- <div class="flex-item p-t p-b flex-box flex-c">
68
- <el-form
69
- v-if="activeMenu.menuid"
70
- ref="menu-form"
71
- label-width="6em"
72
- label-position="right"
73
- :model="activeMenu"
74
- >
75
- <el-form-item
76
- label="名称:"
77
- prop="label"
78
- :rules="[
79
- { required: true, message: '请输入名称', trigger: 'blur' }
80
- ]"
81
- >
82
- <el-input v-model="activeMenu.label" class="w-224" />
83
- </el-form-item>
84
- <el-form-item label="属性:">
85
- <el-select v-model="activeMenu.resType" class="w-224">
86
- <el-option value="1" label="左边栏菜单" />
87
- <el-option value="2" label="隐藏菜单" />
88
- <el-option value="3" label="权限按钮" />
89
- </el-select>
90
- </el-form-item>
91
-
92
- <el-form-item
93
- v-if="activeMenu.resType === '1'"
94
- label="所属模块"
95
- prop="appNo"
96
- :rules="[
97
- { required: true, message: '请输入所属模块', trigger: 'blur' }
98
- ]"
99
- >
100
- <el-input
101
- v-model="activeMenu.appNo"
102
- class="w-224"
103
- @change="(val) => setAppNo(val, activeMenu)"
104
- />
105
- </el-form-item>
106
-
107
- <template v-if="['1', '2'].includes(activeMenu.resType)">
108
- <el-form-item
109
- label="访问路径:"
110
- prop="pageurl"
111
- :rules="[
112
- { required: true, message: '请输入访问路径', trigger: 'blur' }
113
- ]"
114
- >
115
- <el-input v-model="activeMenu.pageurl" class="w-224" />
116
- </el-form-item>
117
- <el-form-item label="图标:">
118
- <div class="flex-box">
119
- <logoIcon :logo="activeMenu.logo" />
120
- <div class="m-r-s">
121
- <el-button plain size="mini" @click="sltLogoV = true"
122
- >选择图标</el-button
123
- >
124
- </div>
125
- <el-upload
126
- action="http://nstc.com.cn"
127
- accept="image/*"
128
- :show-file-list="false"
129
- :http-request="(req) => uploadFile(req, activeMenu)"
130
- >
131
- <el-button slot="trigger" plain size="mini"
132
- >上传图标</el-button
133
- >
134
- </el-upload>
135
- </div>
136
- </el-form-item>
137
- <el-form-item label="快捷菜单: ">
138
- <template slot="label">
139
- <span>快捷菜单:</span>
140
- </template>
141
- <el-switch
142
- v-model="activeMenu.isDisplay"
143
- v-title="'是否作为门户首页的快捷入口的备选项'"
144
- active-value="1"
145
- inactive-value="0"
146
- active-text="是"
147
- inactive-text="否"
148
- inline
149
- :width="46"
150
- />
151
- </el-form-item>
152
- </template>
153
- <el-form-item v-if="activeMenu.treeno" label="权限编码:">
154
- <div class="w-224 flex-box">
155
- <el-input class="flex-item" :value="activeMenu.treeno" readonly />
156
- </div>
157
- </el-form-item>
158
- </el-form>
159
- </div>
160
- </div>
161
- <el-dialog
162
- title="选择图标"
163
- :visible.sync="sltLogoV"
164
- width="714px"
165
- append-to-body
166
- >
167
- <div class="overflow">
168
- <div
169
- v-for="(item, i) in logosClass"
170
- :key="i"
171
- class="m-icon-item flex-column left m-l m-r"
172
- :class="{ active: sltIcon === item }"
173
- style="width: 80px; height: 120px"
174
- @click="sltIcon = item"
175
- >
176
- <div class="text-c" style="font-size: 32px">
177
- <i :class="item"></i>
178
- </div>
179
- <div class="m-t text-c">{{ item }}</div>
180
- </div>
181
- </div>
182
- <div class="dialog-footer">
183
- <el-button type="primary" @click="sltLogo">确认</el-button>
184
- <el-button @click="closeSltLogo">取消</el-button>
185
- </div>
186
- </el-dialog>
187
- </div>
188
- </template>
189
-
190
- <script>
191
- /* eslint-disable no-unused-vars */
192
-
193
- import { nanoid } from 'nanoid'
194
- import forEachs from '../../utils/forEachs'
195
- import list2tree from '../../utils/list2tree'
196
- import { treeSource2menutree, menutree2treeSource } from './utils'
197
- import logoIcon from './logoIcon.vue'
198
-
199
- export default {
200
- components: {
201
- logoIcon
202
- },
203
- filters: {
204
- typeF(v) {}
205
- },
206
- props: {
207
- setNew: {
208
- type: Boolean,
209
- default: true
210
- }
211
- },
212
- data() {
213
- this.menuidMax = 0
214
- return {
215
- menuTree: [],
216
- activeMenu: {},
217
- exKeys: [],
218
- sltLogoV: false,
219
- sltIcon: undefined,
220
- logosClass: [
221
- 'el-icon-s-home',
222
- 'el-icon-s-cooperation',
223
- 'el-icon-s-order',
224
- 'el-icon-s-management',
225
- 'el-icon-s-marketing',
226
- 'el-icon-s-comment',
227
- 'el-icon-menu',
228
- 'el-icon-s-grid',
229
- 'el-icon-s-data',
230
- 'el-icon-date',
231
- 'el-icon-pie-chart',
232
- 'el-icon-loading'
233
- ]
234
- }
235
- },
236
- created() {
237
- if (this.setNew) {
238
- this.getMenuTree()
239
- } else {
240
- this.getTreeSource()
241
- }
242
- },
243
- methods: {
244
- getMenuTree() {
245
- this.$axios
246
- .get('/server-assets/menutree.json', null, { noMsg: true })
247
- .then((res) => {
248
- this.menuTree = res.map((c) => c)
249
- })
250
- .catch(this.getTreeSource())
251
- },
252
- getTreeSource() {
253
- this.$axios.get('/json/treeSource.json').then((res) => {
254
- this.menuTree = treeSource2menutree(res)
255
- })
256
- },
257
- saveMenuTree() {
258
- this.$msgboxPor({
259
- title: '保存菜单树',
260
- message: '保存菜单树会覆盖原有的菜单树, 确定要保存吗?',
261
- type: 'warning',
262
- confirmButtonText: '确定',
263
- cancelButtonText: '取消'
264
- }).then(() => {
265
- this.saveMenuTreeAs()
266
- })
267
- },
268
- saveMenuTreeAs() {
269
- let menuTree = JSON.parse(JSON.stringify(this.menuTree))
270
- forEachs(menuTree, (item, i, arr) => {
271
- item.status = '1'
272
- item.sortnum = (i + 1).toString()
273
- item.path = null
274
-
275
- item?.children?.forEach((c) => {
276
- c.pmid = item.menuid
277
- c.parentTreeNo = item.treeno
278
- })
279
-
280
- if (['1', '2'].includes(item.resType)) {
281
- item.isSearch = '1'
282
- } else {
283
- item.isSearch = '0'
284
- item.pageurl = null
285
- }
286
- })
287
-
288
- if (this.setNew) {
289
- this.setMenuTree(menuTree)
290
- } else {
291
- this.setTreeSource(menuTree)
292
- }
293
- },
294
- setMenuTree(menuTree) {
295
- this.$axios.post('/set-file', {
296
- fileName: 'server-assets/menutree.json',
297
- fileContent: JSON.stringify(menuTree, null, 2)
298
- })
299
- },
300
- setTreeSource(menuTree) {
301
- let treeSource = menutree2treeSource(menuTree)
302
- this.$axios.post('/set-file', {
303
- fileName: 'json/treeSource.json',
304
- fileContent: JSON.stringify(treeSource, null, 2)
305
- })
306
- },
307
- addFF() {
308
- this.menuidMax = this.menuidMax + 1
309
- let menu = {
310
- menuid: this.menuidMax /* * -1 */,
311
- appNo: '',
312
- label: '',
313
- treeno: '',
314
- pageurl: '',
315
- sortnum: 0,
316
- resType: '1',
317
- isDisplay: '1',
318
- children: []
319
- }
320
- this.menuTree.unshift(menu)
321
-
322
- this.$nextTick(() => {
323
- this.activeMenu = menu
324
- this.$refs['menu-tree'].setCurrentKey(menu.menuid)
325
- })
326
- },
327
- appendMenu(data) {
328
- this.menuidMax = this.menuidMax + 1
329
- let appNo = data.appNo
330
-
331
- let menu = {
332
- menuid: this.menuidMax /* * -1 */,
333
- appNo: appNo,
334
- label: '',
335
- treeno: appNo + '-' + nanoid(8),
336
- pageurl: '',
337
- sortnum: undefined,
338
- resType: '3',
339
- isDisplay: '0'
340
- }
341
-
342
- data.children || this.$set(data, 'children', [])
343
-
344
- if (data.children.length === 0) {
345
- menu.sortnum = '1'
346
- data.children.push(menu)
347
- } else {
348
- let lastC = data.children[data.children.length - 1]
349
- let sortnum = Number(lastC.sortnum) + 1
350
- menu.sortnum = sortnum.toString()
351
-
352
- data.children.push(menu)
353
- }
354
-
355
- this.$nextTick(() => {
356
- this.activeMenu = menu
357
- this.$refs['menu-tree'].setCurrentKey(menu.menuid)
358
- })
359
- },
360
- removeMenu(node, data) {
361
- this.$msgboxPor({
362
- title: '删除菜单/按钮',
363
- message: '确定要删除吗?',
364
- type: 'warning',
365
- confirmButtonText: '确定',
366
- cancelButtonText: '取消'
367
- }).then(() => {
368
- let children = node.parent.data.children || node.parent.data
369
- let index = children.findIndex((d) => d.menuid === data.menuid)
370
- index !== -1 && children.splice(index, 1)
371
- })
372
- },
373
- clickMenu(data) {
374
- this.activeMenu = data
375
- },
376
- setAppNo(val, menu) {
377
- if (val && !menu.treeno) {
378
- menu.treeno = val + '-' + nanoid(8)
379
- }
380
- },
381
- uploadFile(req, menu) {
382
- let fR = new FileReader()
383
- fR.onload = (e) => {
384
- menu.logo = e.target.result
385
- }
386
- fR.readAsDataURL(req.file)
387
- },
388
- closeSltLogo() {
389
- this.sltIcon = undefined
390
- this.sltLogoV = false
391
- },
392
- sltLogo() {
393
- this.activeMenu.logo = this.sltIcon
394
- this.sltLogoV = false
395
- },
396
- submitForm() {
397
- this.$refs['menu-form'].validate((valid) => {
398
- if (valid) {
399
- Object.assign(this.activeMenu, this.activeMenu)
400
- }
401
- })
402
- }
403
- }
404
- }
405
- </script>
406
- <style scoped>
407
- .menu-item .menu-item-btn {
408
- display: none;
409
- }
410
- .menu-item:hover .menu-item-btn {
411
- display: block;
412
- }
413
-
414
- .m-icon-item {
415
- cursor: pointer;
416
- }
417
- .m-icon-item:hover {
418
- color: var(--color-primary);
419
- }
420
- .m-icon-item.active {
421
- color: var(--color-primary);
422
- }
423
-
424
- .hint {
425
- color: var(--color-text-placeholder);
426
- }
427
- </style>
1
+ <template>
2
+ <div class="flex-box" style="height: 420px">
3
+ <div class="flex-column bd-r" style="width: 300px; height: 100%">
4
+ <div class="flex-box flex-v">
5
+ <span>导航菜单树</span>
6
+ <el-button
7
+ class="m-l-auto"
8
+ type="primary"
9
+ size="mini"
10
+ @click="saveMenuTree"
11
+ >保存菜单树</el-button
12
+ >
13
+ <el-button class="m-r-s" plain size="mini" @click="addFF"
14
+ >新建目录</el-button
15
+ >
16
+ </div>
17
+ <el-tree
18
+ ref="menu-tree"
19
+ class="flex-item p-t p-b"
20
+ :data="menuTree"
21
+ :props="{
22
+ children: 'children',
23
+ label: 'label'
24
+ }"
25
+ node-key="menuid"
26
+ highlight-current
27
+ draggable
28
+ style="overflow: auto"
29
+ @node-click="clickMenu"
30
+ >
31
+ <span
32
+ slot-scope="{ node, data }"
33
+ class="menu-item flex-item flex-box flex-lr flex-v"
34
+ >
35
+ <span>
36
+ <logoIcon
37
+ v-if="data.logo"
38
+ :logo="data.logo"
39
+ width="14px"
40
+ style="vertical-align: bottom"
41
+ />
42
+ {{ node.label || '未命名...' }}</span
43
+ >
44
+ <span class="menu-item-btn m-r">
45
+ <el-button
46
+ v-title="'新增下级'"
47
+ icon="el-icon-document-add"
48
+ plain
49
+ onlyicon
50
+ size="mini"
51
+ @click.stop="() => appendMenu(data)"
52
+ />
53
+ <el-button
54
+ v-title="'删除本级和下级'"
55
+ icon="el-icon-document-delete"
56
+ plain
57
+ onlyicon
58
+ size="mini"
59
+ @click.stop="() => removeMenu(node, data)"
60
+ />
61
+ </span>
62
+ </span>
63
+ </el-tree>
64
+ </div>
65
+ <div class="flex-item p-l flex-column" style="height: 100%">
66
+ <div style="line-height: 28px">菜单/按钮详情</div>
67
+ <div class="flex-item p-t p-b flex-box flex-c">
68
+ <el-form
69
+ v-if="activeMenu.menuid"
70
+ ref="menu-form"
71
+ label-width="6em"
72
+ label-position="right"
73
+ :model="activeMenu"
74
+ >
75
+ <el-form-item
76
+ label="名称:"
77
+ prop="label"
78
+ :rules="[
79
+ { required: true, message: '请输入名称', trigger: 'blur' }
80
+ ]"
81
+ >
82
+ <el-input v-model="activeMenu.label" class="w-224" />
83
+ </el-form-item>
84
+ <el-form-item label="属性:">
85
+ <el-select v-model="activeMenu.resType" class="w-224">
86
+ <el-option value="1" label="左边栏菜单" />
87
+ <el-option value="2" label="隐藏菜单" />
88
+ <el-option value="3" label="权限按钮" />
89
+ </el-select>
90
+ </el-form-item>
91
+
92
+ <el-form-item
93
+ v-if="activeMenu.resType === '1'"
94
+ label="所属模块"
95
+ prop="appNo"
96
+ :rules="[
97
+ { required: true, message: '请输入所属模块', trigger: 'blur' }
98
+ ]"
99
+ >
100
+ <el-input
101
+ v-model="activeMenu.appNo"
102
+ class="w-224"
103
+ @change="(val) => setAppNo(val, activeMenu)"
104
+ />
105
+ </el-form-item>
106
+
107
+ <template v-if="['1', '2'].includes(activeMenu.resType)">
108
+ <el-form-item
109
+ label="访问路径:"
110
+ prop="pageurl"
111
+ :rules="[
112
+ { required: true, message: '请输入访问路径', trigger: 'blur' }
113
+ ]"
114
+ >
115
+ <el-input v-model="activeMenu.pageurl" class="w-224" />
116
+ </el-form-item>
117
+ <el-form-item label="图标:">
118
+ <div class="flex-box">
119
+ <logoIcon :logo="activeMenu.logo" />
120
+ <div class="m-r-s">
121
+ <el-button plain size="mini" @click="sltLogoV = true"
122
+ >选择图标</el-button
123
+ >
124
+ </div>
125
+ <el-upload
126
+ action="http://nstc.com.cn"
127
+ accept="image/*"
128
+ :show-file-list="false"
129
+ :http-request="(req) => uploadFile(req, activeMenu)"
130
+ >
131
+ <el-button slot="trigger" plain size="mini"
132
+ >上传图标</el-button
133
+ >
134
+ </el-upload>
135
+ </div>
136
+ </el-form-item>
137
+ <el-form-item label="快捷菜单: ">
138
+ <template slot="label">
139
+ <span>快捷菜单:</span>
140
+ </template>
141
+ <el-switch
142
+ v-model="activeMenu.isDisplay"
143
+ v-title="'是否作为门户首页的快捷入口的备选项'"
144
+ active-value="1"
145
+ inactive-value="0"
146
+ active-text="是"
147
+ inactive-text="否"
148
+ inline
149
+ :width="46"
150
+ />
151
+ </el-form-item>
152
+ </template>
153
+ <el-form-item v-if="activeMenu.treeno" label="权限编码:">
154
+ <div class="w-224 flex-box">
155
+ <el-input class="flex-item" :value="activeMenu.treeno" readonly />
156
+ </div>
157
+ </el-form-item>
158
+ </el-form>
159
+ </div>
160
+ </div>
161
+ <el-dialog
162
+ title="选择图标"
163
+ :visible.sync="sltLogoV"
164
+ width="714px"
165
+ append-to-body
166
+ >
167
+ <div class="overflow">
168
+ <div
169
+ v-for="(item, i) in logosClass"
170
+ :key="i"
171
+ class="m-icon-item flex-column left m-l m-r"
172
+ :class="{ active: sltIcon === item }"
173
+ style="width: 80px; height: 120px"
174
+ @click="sltIcon = item"
175
+ >
176
+ <div class="text-c" style="font-size: 32px">
177
+ <i :class="item"></i>
178
+ </div>
179
+ <div class="m-t text-c">{{ item }}</div>
180
+ </div>
181
+ </div>
182
+ <div class="dialog-footer">
183
+ <el-button type="primary" @click="sltLogo">确认</el-button>
184
+ <el-button @click="closeSltLogo">取消</el-button>
185
+ </div>
186
+ </el-dialog>
187
+ </div>
188
+ </template>
189
+
190
+ <script>
191
+ /* eslint-disable no-unused-vars */
192
+
193
+ import { nanoid } from 'nanoid'
194
+ import forEachs from '../../utils/forEachs'
195
+ import list2tree from '../../utils/list2tree'
196
+ import { treeSource2menutree, menutree2treeSource } from './utils'
197
+ import logoIcon from './logoIcon.vue'
198
+
199
+ export default {
200
+ components: {
201
+ logoIcon
202
+ },
203
+ filters: {
204
+ typeF(v) {}
205
+ },
206
+ props: {
207
+ setNew: {
208
+ type: Boolean,
209
+ default: true
210
+ }
211
+ },
212
+ data() {
213
+ this.menuidMax = 0
214
+ return {
215
+ menuTree: [],
216
+ activeMenu: {},
217
+ exKeys: [],
218
+ sltLogoV: false,
219
+ sltIcon: undefined,
220
+ logosClass: [
221
+ 'el-icon-s-home',
222
+ 'el-icon-s-cooperation',
223
+ 'el-icon-s-order',
224
+ 'el-icon-s-management',
225
+ 'el-icon-s-marketing',
226
+ 'el-icon-s-comment',
227
+ 'el-icon-menu',
228
+ 'el-icon-s-grid',
229
+ 'el-icon-s-data',
230
+ 'el-icon-date',
231
+ 'el-icon-pie-chart',
232
+ 'el-icon-loading'
233
+ ]
234
+ }
235
+ },
236
+ created() {
237
+ if (this.setNew) {
238
+ this.getMenuTree()
239
+ } else {
240
+ this.getTreeSource()
241
+ }
242
+ },
243
+ methods: {
244
+ getMenuTree() {
245
+ this.$axios
246
+ .get('/server-assets/menutree.json', null, { noMsg: true })
247
+ .then((res) => {
248
+ this.menuTree = res.map((c) => c)
249
+ })
250
+ .catch(this.getTreeSource())
251
+ },
252
+ getTreeSource() {
253
+ this.$axios.get('/json/treeSource.json').then((res) => {
254
+ this.menuTree = treeSource2menutree(res)
255
+ })
256
+ },
257
+ saveMenuTree() {
258
+ this.$msgboxPor({
259
+ title: '保存菜单树',
260
+ message: '保存菜单树会覆盖原有的菜单树, 确定要保存吗?',
261
+ type: 'warning',
262
+ confirmButtonText: '确定',
263
+ cancelButtonText: '取消'
264
+ }).then(() => {
265
+ this.saveMenuTreeAs()
266
+ })
267
+ },
268
+ saveMenuTreeAs() {
269
+ let menuTree = JSON.parse(JSON.stringify(this.menuTree))
270
+ forEachs(menuTree, (item, i, arr) => {
271
+ item.status = '1'
272
+ item.sortnum = (i + 1).toString()
273
+ item.path = null
274
+
275
+ item?.children?.forEach((c) => {
276
+ c.pmid = item.menuid
277
+ c.parentTreeNo = item.treeno
278
+ })
279
+
280
+ if (['1', '2'].includes(item.resType)) {
281
+ item.isSearch = '1'
282
+ } else {
283
+ item.isSearch = '0'
284
+ item.pageurl = null
285
+ }
286
+ })
287
+
288
+ if (this.setNew) {
289
+ this.setMenuTree(menuTree)
290
+ } else {
291
+ this.setTreeSource(menuTree)
292
+ }
293
+ },
294
+ setMenuTree(menuTree) {
295
+ this.$axios.post('/set-file', {
296
+ fileName: 'server-assets/menutree.json',
297
+ fileContent: JSON.stringify(menuTree, null, 2)
298
+ })
299
+ },
300
+ setTreeSource(menuTree) {
301
+ let treeSource = menutree2treeSource(menuTree)
302
+ this.$axios.post('/set-file', {
303
+ fileName: 'json/treeSource.json',
304
+ fileContent: JSON.stringify(treeSource, null, 2)
305
+ })
306
+ },
307
+ addFF() {
308
+ this.menuidMax = this.menuidMax + 1
309
+ let menu = {
310
+ menuid: this.menuidMax /* * -1 */,
311
+ appNo: '',
312
+ label: '',
313
+ treeno: '',
314
+ pageurl: '',
315
+ sortnum: 0,
316
+ resType: '1',
317
+ isDisplay: '1',
318
+ children: []
319
+ }
320
+ this.menuTree.unshift(menu)
321
+
322
+ this.$nextTick(() => {
323
+ this.activeMenu = menu
324
+ this.$refs['menu-tree'].setCurrentKey(menu.menuid)
325
+ })
326
+ },
327
+ appendMenu(data) {
328
+ this.menuidMax = this.menuidMax + 1
329
+ let appNo = data.appNo
330
+
331
+ let menu = {
332
+ menuid: this.menuidMax /* * -1 */,
333
+ appNo: appNo,
334
+ label: '',
335
+ treeno: appNo + '-' + nanoid(8),
336
+ pageurl: '',
337
+ sortnum: undefined,
338
+ resType: '3',
339
+ isDisplay: '0'
340
+ }
341
+
342
+ data.children || this.$set(data, 'children', [])
343
+
344
+ if (data.children.length === 0) {
345
+ menu.sortnum = '1'
346
+ data.children.push(menu)
347
+ } else {
348
+ let lastC = data.children[data.children.length - 1]
349
+ let sortnum = Number(lastC.sortnum) + 1
350
+ menu.sortnum = sortnum.toString()
351
+
352
+ data.children.push(menu)
353
+ }
354
+
355
+ this.$nextTick(() => {
356
+ this.activeMenu = menu
357
+ this.$refs['menu-tree'].setCurrentKey(menu.menuid)
358
+ })
359
+ },
360
+ removeMenu(node, data) {
361
+ this.$msgboxPor({
362
+ title: '删除菜单/按钮',
363
+ message: '确定要删除吗?',
364
+ type: 'warning',
365
+ confirmButtonText: '确定',
366
+ cancelButtonText: '取消'
367
+ }).then(() => {
368
+ let children = node.parent.data.children || node.parent.data
369
+ let index = children.findIndex((d) => d.menuid === data.menuid)
370
+ index !== -1 && children.splice(index, 1)
371
+ })
372
+ },
373
+ clickMenu(data) {
374
+ this.activeMenu = data
375
+ },
376
+ setAppNo(val, menu) {
377
+ if (val && !menu.treeno) {
378
+ menu.treeno = val + '-' + nanoid(8)
379
+ }
380
+ },
381
+ uploadFile(req, menu) {
382
+ let fR = new FileReader()
383
+ fR.onload = (e) => {
384
+ menu.logo = e.target.result
385
+ }
386
+ fR.readAsDataURL(req.file)
387
+ },
388
+ closeSltLogo() {
389
+ this.sltIcon = undefined
390
+ this.sltLogoV = false
391
+ },
392
+ sltLogo() {
393
+ this.activeMenu.logo = this.sltIcon
394
+ this.sltLogoV = false
395
+ },
396
+ submitForm() {
397
+ this.$refs['menu-form'].validate((valid) => {
398
+ if (valid) {
399
+ Object.assign(this.activeMenu, this.activeMenu)
400
+ }
401
+ })
402
+ }
403
+ }
404
+ }
405
+ </script>
406
+ <style scoped>
407
+ .menu-item .menu-item-btn {
408
+ display: none;
409
+ }
410
+ .menu-item:hover .menu-item-btn {
411
+ display: block;
412
+ }
413
+
414
+ .m-icon-item {
415
+ cursor: pointer;
416
+ }
417
+ .m-icon-item:hover {
418
+ color: var(--color-primary);
419
+ }
420
+ .m-icon-item.active {
421
+ color: var(--color-primary);
422
+ }
423
+
424
+ .hint {
425
+ color: var(--color-text-placeholder);
426
+ }
427
+ </style>