@netang/quasar 0.1.68 → 0.1.71

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 (247) hide show
  1. package/.editorconfig +12 -12
  2. package/_docs/docs/components/field-table.md +58 -58
  3. package/_docs/docs/components/field-tree.md +21 -21
  4. package/_docs/docs/components/table.md +24 -24
  5. package/_docs/docs/utils/table.md +196 -196
  6. package/components/dialog/img-viewer/index.vue +657 -657
  7. package/components/dialog/index.vue +372 -372
  8. package/components/drawer/index.vue +303 -303
  9. package/components/editor-code/index.vue +325 -325
  10. package/components/empty/index.vue +80 -80
  11. package/components/field-date/index.vue +850 -850
  12. package/components/field-table/index.vue +1277 -1277
  13. package/components/field-tree/index.vue +754 -754
  14. package/components/img/index.vue +211 -211
  15. package/components/mixed-table/index.vue +532 -532
  16. package/components/mixed-table-splitter/index.vue +377 -377
  17. package/components/power-page/index.vue +94 -94
  18. package/components/private/components/move-to-tree/index.vue +154 -154
  19. package/components/private/edit-power-data/index.vue +846 -846
  20. package/components/private/table-visible-columns-button/index.vue +114 -114
  21. package/components/render/index.vue +123 -123
  22. package/components/search/index.vue +231 -231
  23. package/components/search-item/index.vue +212 -212
  24. package/components/select/index.vue +177 -177
  25. package/components/splitter/index.vue +422 -422
  26. package/components/table/index.vue +513 -513
  27. package/components/table-column-fixed/index.vue +110 -110
  28. package/components/table-summary/index.vue +107 -107
  29. package/components/toolbar/index.vue +146 -146
  30. package/components/tree/index.vue +1728 -1728
  31. package/components/uploader/index.vue +188 -188
  32. package/components/uploader-query/index.vue +892 -883
  33. package/docs/404.html +33 -33
  34. package/docs/assets/404.html-60b35caa.js +1 -1
  35. package/docs/assets/404.html-d1e63d77.js +1 -1
  36. package/docs/assets/alert.html-b2a2a72f.js +5 -5
  37. package/docs/assets/alert.html-ba46d137.js +1 -1
  38. package/docs/assets/app-9f30aa4b.js +6 -6
  39. package/docs/assets/area.html-01b9b58d.js +42 -42
  40. package/docs/assets/area.html-9a4fce6a.js +1 -1
  41. package/docs/assets/arr.html-145d27e7.js +1 -1
  42. package/docs/assets/arr.html-674e65ab.js +11 -11
  43. package/docs/assets/auth.html-579fa830.js +1 -1
  44. package/docs/assets/auth.html-8544ed95.js +8 -8
  45. package/docs/assets/bus.html-c71254aa.js +1 -1
  46. package/docs/assets/bus.html-dc7d3d19.js +6 -6
  47. package/docs/assets/column-title.html-c735cb5a.js +3 -3
  48. package/docs/assets/column-title.html-e9316762.js +1 -1
  49. package/docs/assets/confirm.html-ddfdc27f.js +10 -10
  50. package/docs/assets/confirm.html-ef3e2bef.js +1 -1
  51. package/docs/assets/copy.html-d20345b6.js +1 -1
  52. package/docs/assets/copy.html-ef8c8571.js +13 -13
  53. package/docs/assets/data.html-6432175d.js +30 -30
  54. package/docs/assets/data.html-a3b05d5b.js +1 -1
  55. package/docs/assets/dialog.html-1f698e5a.js +1 -1
  56. package/docs/assets/dialog.html-62902b83.js +68 -68
  57. package/docs/assets/dialog.html-baea77c9.js +1 -1
  58. package/docs/assets/dialog.html-bb082fc4.js +1 -1
  59. package/docs/assets/dict.html-1311da3d.js +23 -23
  60. package/docs/assets/dict.html-b96fbf0c.js +1 -1
  61. package/docs/assets/dictOptions.html-7c4f40a5.js +1 -1
  62. package/docs/assets/dictOptions.html-fb99d175.js +5 -5
  63. package/docs/assets/dragger.html-668d3efa.js +1 -1
  64. package/docs/assets/dragger.html-749d585a.js +1 -1
  65. package/docs/assets/editor-code.html-6ab26ea9.js +1 -1
  66. package/docs/assets/editor-code.html-d196205d.js +1 -1
  67. package/docs/assets/empty.html-1c139131.js +1 -1
  68. package/docs/assets/empty.html-1e9c441d.js +1 -1
  69. package/docs/assets/field-date.html-069fdb13.js +1 -1
  70. package/docs/assets/field-date.html-ad204aa9.js +1 -1
  71. package/docs/assets/field-table.html-ce480f03.js +1 -1
  72. package/docs/assets/field-table.html-d9236160.js +1 -1
  73. package/docs/assets/field-text.html-7277c62f.js +1 -1
  74. package/docs/assets/field-text.html-ccb4cecf.js +1 -1
  75. package/docs/assets/field-tree.html-519bfb45.js +1 -1
  76. package/docs/assets/field-tree.html-fdc748d6.js +1 -1
  77. package/docs/assets/form.html-2b562c37.js +2 -2
  78. package/docs/assets/form.html-75104cd5.js +1 -1
  79. package/docs/assets/framework-204010b2.js +5 -5
  80. package/docs/assets/getData.html-990e3787.js +1 -1
  81. package/docs/assets/getData.html-bb72025f.js +34 -34
  82. package/docs/assets/getFile.html-42368004.js +1 -1
  83. package/docs/assets/getFile.html-99abd054.js +3 -3
  84. package/docs/assets/getImage.html-3429c5a1.js +1 -1
  85. package/docs/assets/getImage.html-4d886d83.js +3 -3
  86. package/docs/assets/getTime.html-7435f922.js +1 -1
  87. package/docs/assets/getTime.html-b37f49eb.js +20 -20
  88. package/docs/assets/img.html-7d1da657.js +1 -1
  89. package/docs/assets/img.html-fbea1105.js +1 -1
  90. package/docs/assets/index.html-1695dd7c.js +1 -1
  91. package/docs/assets/index.html-65a4aa67.js +1 -1
  92. package/docs/assets/index.html-7b98d5bd.js +1 -1
  93. package/docs/assets/index.html-c01f2648.js +1 -1
  94. package/docs/assets/input-number.html-0b250d2a.js +1 -1
  95. package/docs/assets/input-number.html-a8eb0378.js +1 -1
  96. package/docs/assets/list-menu-item.html-7f1b4611.js +1 -1
  97. package/docs/assets/list-menu-item.html-84ed5ab8.js +1 -1
  98. package/docs/assets/list-menu.html-28b4163f.js +1 -1
  99. package/docs/assets/list-menu.html-cb6ba95b.js +1 -1
  100. package/docs/assets/loading.html-dae9e39d.js +6 -6
  101. package/docs/assets/loading.html-dc74c9e6.js +1 -1
  102. package/docs/assets/notify.html-e6c4c514.js +1 -1
  103. package/docs/assets/notify.html-f2c4d914.js +8 -8
  104. package/docs/assets/power-page.html-32e02f82.js +1 -1
  105. package/docs/assets/power-page.html-485e77da.js +1 -1
  106. package/docs/assets/power.html-d258cc19.js +93 -93
  107. package/docs/assets/power.html-e490bd32.js +1 -1
  108. package/docs/assets/previewImage.html-6a6b4245.js +1 -1
  109. package/docs/assets/previewImage.html-c5b7e945.js +2 -2
  110. package/docs/assets/price.html-1882c548.js +19 -19
  111. package/docs/assets/price.html-94d3f5be.js +1 -1
  112. package/docs/assets/price.html-d213df0f.js +1 -1
  113. package/docs/assets/price.html-deaf880f.js +1 -1
  114. package/docs/assets/render.html-8efcbdd4.js +1 -1
  115. package/docs/assets/render.html-df228e38.js +1 -1
  116. package/docs/assets/rule.html-2cd57fc2.js +13 -13
  117. package/docs/assets/rule.html-61662001.js +1 -1
  118. package/docs/assets/ruleValid.html-04fe2552.js +1 -1
  119. package/docs/assets/ruleValid.html-e0a776af.js +14 -14
  120. package/docs/assets/search-0782d0d1.svg +1 -1
  121. package/docs/assets/search-item.html-3f75394c.js +1 -1
  122. package/docs/assets/search-item.html-4e942ecd.js +1 -1
  123. package/docs/assets/search.html-2807043e.js +1 -1
  124. package/docs/assets/search.html-c24f8806.js +1 -1
  125. package/docs/assets/select.html-00d0607c.js +1 -1
  126. package/docs/assets/select.html-de7731f5.js +1 -1
  127. package/docs/assets/splitter.html-56f51a70.js +1 -1
  128. package/docs/assets/splitter.html-f5c836d7.js +1 -1
  129. package/docs/assets/style-161e43ab.css +1 -1
  130. package/docs/assets/symbols.html-a6aea4bf.js +1 -1
  131. package/docs/assets/symbols.html-b1f65bad.js +21 -21
  132. package/docs/assets/table-column-fixed.html-3a69e7b2.js +1 -1
  133. package/docs/assets/table-column-fixed.html-e763c38b.js +1 -1
  134. package/docs/assets/table-pagination.html-236934d3.js +1 -1
  135. package/docs/assets/table-pagination.html-c37ee2ac.js +1 -1
  136. package/docs/assets/table-splitter.html-07eab15c.js +1 -1
  137. package/docs/assets/table-splitter.html-7670ee65.js +1 -1
  138. package/docs/assets/table-summary.html-04db434f.js +1 -1
  139. package/docs/assets/table-summary.html-943c65a0.js +1 -1
  140. package/docs/assets/table.html-36253ad7.js +1 -1
  141. package/docs/assets/table.html-7f9c5d1b.js +38 -38
  142. package/docs/assets/table.html-93d53dc8.js +1 -1
  143. package/docs/assets/table.html-ac99b9cb.js +1 -1
  144. package/docs/assets/thumbnail.html-bab1976b.js +1 -1
  145. package/docs/assets/thumbnail.html-eb64e5e8.js +1 -1
  146. package/docs/assets/timestamp.html-4e54f79b.js +13 -13
  147. package/docs/assets/timestamp.html-d0e1b88a.js +1 -1
  148. package/docs/assets/toast.html-58ecbe21.js +1 -1
  149. package/docs/assets/toast.html-c9b9d36b.js +6 -6
  150. package/docs/assets/toolbar.html-83d9f97c.js +1 -1
  151. package/docs/assets/toolbar.html-ff7b8c92.js +1 -1
  152. package/docs/assets/tree.html-d07cbe79.js +23 -23
  153. package/docs/assets/tree.html-ea04193e.js +1 -1
  154. package/docs/assets/uploader-query.html-05590718.js +1 -1
  155. package/docs/assets/uploader-query.html-3175bac5.js +1 -1
  156. package/docs/assets/uploader.html-36da4394.js +2 -2
  157. package/docs/assets/uploader.html-6b5f3079.js +1 -1
  158. package/docs/assets/uploader.html-b9340b57.js +1 -1
  159. package/docs/assets/uploader.html-bc1c22e3.js +1 -1
  160. package/docs/assets/value-format.html-8ae3d47d.js +1 -1
  161. package/docs/assets/value-format.html-afa99b3d.js +1 -1
  162. package/docs/components/column-title.html +35 -35
  163. package/docs/components/data.html +62 -62
  164. package/docs/components/dialog.html +33 -33
  165. package/docs/components/dragger.html +33 -33
  166. package/docs/components/editor-code.html +33 -33
  167. package/docs/components/empty.html +33 -33
  168. package/docs/components/field-date.html +33 -33
  169. package/docs/components/field-table.html +33 -33
  170. package/docs/components/field-text.html +33 -33
  171. package/docs/components/field-tree.html +33 -33
  172. package/docs/components/img.html +33 -33
  173. package/docs/components/input-number.html +33 -33
  174. package/docs/components/list-menu-item.html +33 -33
  175. package/docs/components/list-menu.html +33 -33
  176. package/docs/components/power-page.html +33 -33
  177. package/docs/components/price.html +33 -33
  178. package/docs/components/render.html +33 -33
  179. package/docs/components/search-item.html +33 -33
  180. package/docs/components/search.html +33 -33
  181. package/docs/components/select.html +33 -33
  182. package/docs/components/splitter.html +33 -33
  183. package/docs/components/table-column-fixed.html +33 -33
  184. package/docs/components/table-pagination.html +33 -33
  185. package/docs/components/table-splitter.html +33 -33
  186. package/docs/components/table-summary.html +33 -33
  187. package/docs/components/table.html +33 -33
  188. package/docs/components/thumbnail.html +33 -33
  189. package/docs/components/toolbar.html +33 -33
  190. package/docs/components/uploader-query.html +33 -33
  191. package/docs/components/uploader.html +33 -33
  192. package/docs/components/value-format.html +33 -33
  193. package/docs/index.html +33 -33
  194. package/docs/utils/alert.html +37 -37
  195. package/docs/utils/area.html +74 -74
  196. package/docs/utils/arr.html +43 -43
  197. package/docs/utils/auth.html +40 -40
  198. package/docs/utils/bus.html +38 -38
  199. package/docs/utils/confirm.html +42 -42
  200. package/docs/utils/copy.html +45 -45
  201. package/docs/utils/dialog.html +100 -100
  202. package/docs/utils/dict.html +55 -55
  203. package/docs/utils/dictOptions.html +37 -37
  204. package/docs/utils/form.html +34 -34
  205. package/docs/utils/getData.html +66 -66
  206. package/docs/utils/getFile.html +35 -35
  207. package/docs/utils/getImage.html +35 -35
  208. package/docs/utils/getTime.html +52 -52
  209. package/docs/utils/index.html +33 -33
  210. package/docs/utils/loading.html +38 -38
  211. package/docs/utils/notify.html +40 -40
  212. package/docs/utils/power.html +125 -125
  213. package/docs/utils/previewImage.html +34 -34
  214. package/docs/utils/price.html +51 -51
  215. package/docs/utils/rule.html +45 -45
  216. package/docs/utils/ruleValid.html +46 -46
  217. package/docs/utils/symbols.html +53 -53
  218. package/docs/utils/table.html +70 -70
  219. package/docs/utils/timestamp.html +45 -45
  220. package/docs/utils/toast.html +38 -38
  221. package/docs/utils/tree.html +55 -55
  222. package/docs/utils/uploader.html +34 -34
  223. package/package.json +24 -24
  224. package/sass/common.scss +179 -179
  225. package/sass/index.scss +13 -13
  226. package/sass/quasar/field.scss +250 -250
  227. package/sass/quasar/table.scss +168 -168
  228. package/sass/variables.scss +140 -140
  229. package/utils/$form.js +72 -72
  230. package/utils/$power.js +1411 -1411
  231. package/utils/$render.js +75 -75
  232. package/utils/$search.js +416 -416
  233. package/utils/$table.js +1199 -1193
  234. package/utils/$tree.js +664 -664
  235. package/utils/config.js +57 -57
  236. package/utils/dialog.js +36 -36
  237. package/utils/dict.js +21 -21
  238. package/utils/getFile.js +41 -41
  239. package/utils/getImage.js +176 -176
  240. package/utils/getTime.js +113 -113
  241. package/utils/index.js +65 -65
  242. package/utils/previewImage.js +14 -14
  243. package/utils/timestamp.js +18 -18
  244. package/utils/uploader/qiniu.js +320 -320
  245. package/utils/uploader.js +1625 -1625
  246. package/utils/useFileUrl.js +25 -25
  247. package/utils/useSearch.js +499 -499
package/utils/$tree.js CHANGED
@@ -1,664 +1,664 @@
1
- import $n_has from 'lodash/has'
2
- import $n_get from 'lodash/get'
3
- import $n_isNil from 'lodash/isNil'
4
- import $n_findIndex from 'lodash/findIndex'
5
- import $n_cloneDeep from 'lodash/cloneDeep'
6
-
7
- import $n_router from '@netang/utils/vue/router'
8
-
9
- import $n_isValidArray from '@netang/utils/isValidArray'
10
- import $n_isValidObject from '@netang/utils/isValidObject'
11
- import $n_isValidString from '@netang/utils/isValidString'
12
- import $n_hasId from '@netang/utils/hasId'
13
- import $n_http from '@netang/utils/http'
14
- import $n_run from '@netang/utils/run'
15
- import $n_storage from '@netang/utils/storage'
16
-
17
- import $n_toast from './toast'
18
- import $n_confirm from './confirm'
19
- import $n_alert from './alert'
20
-
21
- import { isRef, watch, inject, ref, computed } from 'vue'
22
-
23
- import { NPowerKey } from './symbols'
24
-
25
- /**
26
- * 获取节点
27
- */
28
- function getTreeNode(data, nodeId) {
29
- for (const item of data) {
30
-
31
- if (item.id === nodeId) {
32
- return item
33
- }
34
-
35
- // 如果是父节点
36
- if (item.children.length) {
37
- const res = getTreeNode(item.children, nodeId)
38
- if (res) {
39
- return res
40
- }
41
- }
42
- }
43
-
44
- return false
45
- }
46
-
47
- /**
48
- * 获取子节点
49
- */
50
- function getChildren(data, callback) {
51
- for (const item of data) {
52
- if ($n_run(callback)(item) === false) {
53
- return false
54
- }
55
- // 如果是父节点
56
- if (item.children.length) {
57
- const res = getChildren(item.children, callback)
58
- if (res === false) {
59
- return false
60
- }
61
- }
62
- }
63
- return true
64
- }
65
-
66
- /**
67
- * 创建树实例
68
- */
69
- function create(options) {
70
-
71
- const {
72
- // 路由路径
73
- path,
74
- // 路由参数
75
- query,
76
- // 树节点列表
77
- nodes,
78
- // 树展开节点
79
- expanded,
80
- // 菜单参数
81
- menu: menuOptions,
82
- // 初始表单数据
83
- initFormData,
84
- // 表单数据
85
- formData,
86
- // 重新加载
87
- reload,
88
- // 是否开启展开节点缓存
89
- cache,
90
- } = Object.assign({
91
- // 路由路径
92
- path: '',
93
- // 路由参数
94
- query: {},
95
- // 菜单参数
96
- menu: {},
97
- // 是否开启展开节点缓存
98
- cache: false,
99
- }, options)
100
-
101
- // 获取权限注入
102
- const $power = $n_has(options, '$power') ? options.$power : inject(NPowerKey)
103
- const hasPowr = !! $power
104
-
105
- // 获取权限路由
106
- const $route = $n_isValidString(path) ?
107
- // 如果为自定义路由
108
- $n_router.resolve({
109
- path,
110
- query,
111
- })
112
- // 否则获取当前路由
113
- : (hasPowr ? $power.getRoute() : $n_router.getRoute())
114
-
115
- // 权限按钮
116
- const powerBtns = hasPowr ? $power.powerBtns : ref([])
117
-
118
- // 是否有展开节点
119
- const hasExpanded = ! $n_isNil(expanded) && isRef(expanded)
120
-
121
- // 如果开启展开节点缓存
122
- if (hasExpanded && cache) {
123
-
124
- // 设置树展开节点初始缓存
125
- expanded.value = getExpandedCache(expanded.value)
126
-
127
- /**
128
- * 监听树展开节点
129
- */
130
- watch(expanded, function(val) {
131
- // 设置树展开节点缓存
132
- setExpandedCache(val)
133
- })
134
- }
135
-
136
- // 获取菜单状态
137
- const menuStatus = computed(function() {
138
-
139
- const o = Object.assign({
140
- updateName: 'update',
141
- moveName: 'move',
142
- copyName: 'copy',
143
- deleteName: 'realdel',
144
- statusName: 'status'
145
- }, menuOptions)
146
-
147
- const maps = {}
148
- maps[o.updateName] = 'update'
149
- maps[o.moveName] = 'move'
150
- maps[o.copyName] = 'copy'
151
- maps[o.deleteName] = 'delete'
152
- maps[o.statusName] = 'status'
153
-
154
- const allPowerBtn = {}
155
- for (const item of powerBtns.value) {
156
- if ($n_has(maps, $n_get(item, 'name'))) {
157
- allPowerBtn[maps[item.name]] = item
158
- }
159
- }
160
-
161
- return {
162
- all: $n_isValidObject(allPowerBtn),
163
- update: $n_has(allPowerBtn, 'update'),
164
- move: $n_has(allPowerBtn, 'move'),
165
- copy: $n_has(allPowerBtn, 'copy'),
166
- delete: $n_has(allPowerBtn, 'delete'),
167
- status: $n_has(allPowerBtn, 'status'),
168
- allPowerBtn,
169
- }
170
- })
171
-
172
- /**
173
- * 获取节点
174
- */
175
- function getNode(nodeId) {
176
- return getTreeNode(nodes.value, nodeId)
177
- }
178
-
179
- /**
180
- * 格式化节点
181
- */
182
- function formatNode(attr) {
183
-
184
- // 设置属性
185
- attr = Object.assign({}, attr)
186
-
187
- return {
188
- attr,
189
- id: attr.id,
190
- label: attr.title,
191
- children: [],
192
- }
193
- }
194
-
195
- /**
196
- * 更新节点
197
- */
198
- function updateNode(data) {
199
-
200
- // 获取 id
201
- const id = $n_get(formData.value, 'id')
202
-
203
- // 更新表单数据
204
- formData.value = Object.assign({}, formData.value, data)
205
-
206
- // 获取节点数据
207
- const nodeItem = getNode(data.id)
208
-
209
- // 如果为更新节点
210
- if (id) {
211
- if (nodeItem) {
212
- Object.assign(nodeItem, {
213
- attr: Object.assign({}, formData.value),
214
- label: formData.value.title,
215
- })
216
- }
217
-
218
- // 否则为新增节点
219
- } else if (
220
- // 如果为新增节点
221
- $n_get(data, 'id')
222
- // 没有节点存在
223
- && ! nodeItem
224
- ) {
225
- // 获取父级节点
226
- const parentNodeItem = getNode(formData.value.pid)
227
- if (! parentNodeItem) {
228
- return
229
- }
230
-
231
- // 新增节点
232
- parentNodeItem.children.push(formatNode(formData.value))
233
- }
234
- }
235
-
236
- /**
237
- * 删除节点
238
- */
239
- function deleteNode({ id, attr }) {
240
-
241
- // 获取父节点数据
242
- const parentNodeItem = getNode(attr.pid)
243
- if (! parentNodeItem) {
244
- return
245
- }
246
-
247
- // 获取节点索引
248
- const nodeIndex = $n_findIndex(parentNodeItem.children, { id })
249
- if (nodeIndex > -1) {
250
- parentNodeItem.children.splice(nodeIndex, 1)
251
- }
252
- }
253
-
254
- /**
255
- * 确认菜单
256
- */
257
- function confirmMenu(callback) {
258
- // 确认框
259
- $n_confirm({
260
- message: '确认要执行该操作吗?',
261
- })
262
- // 点击确认执行
263
- .onOk(callback)
264
- }
265
-
266
- /**
267
- * 菜单点击
268
- */
269
- function menuClick(options) {
270
-
271
- // 参数
272
- const o = Object.assign({
273
- // 菜单类型
274
- type: '',
275
- // 节点
276
- node: null,
277
- }, options)
278
-
279
- // 菜单类型
280
- switch (o.type) {
281
-
282
- // 添加下级
283
- case 'update':
284
- // 更新表单数据
285
- formData.value = Object.assign({}, initFormData, {
286
- pid: o.node.attr.id,
287
- })
288
- break
289
-
290
- // 复制
291
- case 'copy':
292
- // 确认菜单
293
- confirmMenu(async function() {
294
-
295
- if (! $n_get(menuStatus.value, 'allPowerBtn.copy.url')) {
296
- console.error('没有找到复制地址')
297
- return
298
- }
299
-
300
- // 复制的当前节点的属性
301
- const newAttr = Object.assign({}, o.node.attr, {
302
- title: '【复制】' + o.node.attr.title,
303
- })
304
-
305
- // 复制列表
306
- const copyLists = [ newAttr ]
307
-
308
- // 是否复制叶子节点
309
- const isLeafNode = ! o.node.children.length
310
-
311
- // 如果复制的是父级节点
312
- if (! isLeafNode) {
313
- getChildren(o.node.children, function(item) {
314
- copyLists.push(item.attr)
315
- })
316
- }
317
-
318
- // 请求 - 复制
319
- const { status, data: res } = await $n_http({
320
- url: menuStatus.value.allPowerBtn.copy.url,
321
- data: {
322
- data: copyLists,
323
- },
324
- })
325
- if (! status) {
326
- return
327
- }
328
-
329
- // 如果复制的是叶子节点
330
- if (isLeafNode) {
331
-
332
- // 如果返回了 id
333
- if ($n_hasId(res)) {
334
-
335
- // 更新数据
336
- Object.assign(newAttr, res)
337
-
338
- // 获取该叶子节点的父级节点
339
- const parentNodeItem = getNode(newAttr.pid)
340
- if (! parentNodeItem) {
341
- return
342
- }
343
-
344
- // 新增节点
345
- parentNodeItem.children.push(formatNode(newAttr))
346
-
347
- // 否则重新加载列表
348
- } else {
349
- reload()
350
- }
351
-
352
- // 否则重新加载列表
353
- } else {
354
- reload()
355
- }
356
-
357
- // 轻提示
358
- $n_toast({
359
- type: 'positive',
360
- message: '复制成功',
361
- })
362
- })
363
- break
364
-
365
- // 删除
366
- case 'delete':
367
-
368
- // 如果有子节点
369
- if (o.node.children.length) {
370
- // 提示框
371
- $n_alert({
372
- message: '请先删除该节点下的子节点',
373
- })
374
- return
375
- }
376
-
377
- if (! $n_get(menuStatus.value, 'allPowerBtn.delete.url')) {
378
- console.error('没有找到删除地址')
379
- return
380
- }
381
-
382
- // 确认菜单
383
- confirmMenu(async function() {
384
-
385
- // 请求 - 删除
386
- const { status } = await $n_http({
387
- url: menuStatus.value.allPowerBtn.delete.url,
388
- data: {
389
- id: o.node.id,
390
- },
391
- })
392
- if (! status) {
393
- return
394
- }
395
-
396
- // 删除节点
397
- deleteNode(o.node)
398
-
399
- // 轻提示
400
- $n_toast({
401
- type: 'positive',
402
- message: '删除成功',
403
- })
404
- })
405
- break
406
-
407
- // 全部禁用
408
- case 'statusDisable':
409
- // 全部正常
410
- case 'statusNormal':
411
-
412
- if (! $n_get(menuStatus.value, 'allPowerBtn.status.url')) {
413
- console.error('没有找到状态地址')
414
- return
415
- }
416
-
417
- // 确认菜单
418
- confirmMenu(async function() {
419
-
420
- // 设置状态 ids
421
- const statusIds = [ o.node.id ]
422
-
423
- // 新状态
424
- const newStatus = o.type === 'statusNormal' ? 1 : 0
425
-
426
- // 是否叶子节点
427
- const isLeafNode = ! o.node.children.length
428
-
429
- // 如果复制的是父级节点
430
- if (! isLeafNode) {
431
- getChildren(o.node.children, function(item) {
432
- statusIds.push(item.id)
433
- })
434
- }
435
-
436
- // 请求 - 全部禁用/正常
437
- const { status } = await $n_http({
438
- url: menuStatus.value.allPowerBtn.status.url,
439
- data: {
440
- // ids
441
- ids: statusIds,
442
- // 新状态值
443
- status: newStatus,
444
- },
445
- })
446
- if (! status) {
447
- return
448
- }
449
-
450
- // 设置当前节点状态
451
- o.node.attr.status = newStatus
452
-
453
- // 如果是父级节点
454
- if (! isLeafNode) {
455
- getChildren(o.node.children, function(item) {
456
- item.attr.status = newStatus
457
- })
458
- }
459
-
460
- // 轻提示
461
- $n_toast({
462
- type: 'positive',
463
- message: '恭喜您,操作成功',
464
- })
465
- })
466
- break
467
- }
468
- }
469
-
470
- /**
471
- * 获取展开节点缓存
472
- */
473
- function getExpandedCache(defaultValue = []) {
474
- // 获取展开节点缓存
475
- const res = $n_storage.get('tree_expanded_' + $route.fullPath)
476
- return $n_isValidArray(res) ? res : defaultValue
477
- }
478
-
479
- /**
480
- * 设置展开节点缓存
481
- */
482
- function setExpandedCache(expanded) {
483
- // 设置展开节点缓存(永久缓存)
484
- $n_storage.set('tree_expanded_' + $route.fullPath, expanded, 0)
485
- }
486
-
487
- /**
488
- * 展开全部
489
- */
490
- function expandAll() {
491
-
492
- // 展开节点 ids
493
- const ids = []
494
-
495
- function getChildren(data) {
496
- for (const { id, children } of data) {
497
- ids.push(id)
498
- if ($n_isValidArray(children)) {
499
- getChildren(children)
500
- }
501
- }
502
- }
503
-
504
- if ($n_isValidArray(nodes.value)) {
505
- getChildren(nodes.value)
506
- }
507
-
508
- // 设置展开节点数组
509
- expanded.value = ids
510
- }
511
-
512
- /**
513
- * 收起全部
514
- */
515
- function collapseAll() {
516
- // 设置展开节点数组
517
- expanded.value = [0]
518
- }
519
-
520
- /**
521
- * 判断节点能否被拖拽
522
- */
523
- function allowDrag(draggingNode) {
524
- return $n_hasId(draggingNode.id)
525
- }
526
-
527
- /**
528
- * 拖拽时判定目标节点能否被放置, type 参数: top / inner / bottom / none ( 目标节点上方 / 目标节点内部 / 目标节点下方 / 无任何操作 )
529
- */
530
- function allowDrop(draggingNode, dropNode, dropType) {
531
- return dropType === 'inner'
532
- || $n_hasId(dropNode.id)
533
- }
534
-
535
- /**
536
- * 树节点拖拽结束
537
- */
538
- async function nodeDragEnd(draggingNode, dropNode, dropType, doDrop) {
539
- if (dropType !== 'none') {
540
-
541
- if (! $n_get(menuStatus.value, 'allPowerBtn.move.url')) {
542
-
543
- // 提示框
544
- $n_alert({
545
- message: '没有找到移动地址',
546
- })
547
-
548
- return
549
- }
550
-
551
- // 克隆当前树列表数据
552
- const nodesClone = $n_cloneDeep(nodes.value)
553
-
554
- // 开始拖拽
555
- const children = doDrop()
556
- if (children === false) {
557
- return
558
- }
559
-
560
- // 修改拖拽节点的父级 id
561
- draggingNode.attr.pid =
562
- // 如果拖动节点 在 目标节点的 内部
563
- dropType === 'inner' ?
564
- // 将拖动节点的 pid 改为 目标节点的 id
565
- dropNode.attr.id
566
- // 将拖动节点的 pid 改为 目标节点的 pid
567
- : dropNode.attr.pid
568
-
569
- // 移动列表
570
- const moveLists = []
571
-
572
- // 当前拖拽节点在新列表中的索引
573
- let dropIndex = $n_findIndex(children, e => e.id === draggingNode.id)
574
- if (dropIndex > -1) {
575
-
576
- if (
577
- // 如果拖拽到目标节点下方
578
- dropType === 'bottom'
579
- // 并且拖拽节点当前的位置不是第一个
580
- && dropIndex > 0
581
- ) {
582
- dropIndex--
583
- }
584
-
585
- for (let i = dropIndex; i < children.length; i++) {
586
- const { attr } = children[i]
587
- attr.sort = i + 1
588
- moveLists.push({
589
- id: attr.id,
590
- pid: attr.pid,
591
- sort: attr.sort,
592
- })
593
- }
594
-
595
- // 如果有移动列表
596
- if (moveLists.length) {
597
-
598
- // 请求 - 移动
599
- const { status } = await $n_http({
600
- url: menuStatus.value.allPowerBtn.move.url,
601
- data: {
602
- data: moveLists,
603
- },
604
- })
605
-
606
- // 移动成功
607
- if (status) {
608
- return
609
- }
610
- }
611
- }
612
-
613
- // 移动失败, 还原数据
614
- nodes.value = nodesClone
615
- }
616
- }
617
-
618
- return {
619
- // 当前路由全路径
620
- routeFullPath: $route.fullPath,
621
- // 当前路由路径
622
- routePath: $route.path,
623
- // 当前路由参数
624
- routeQuery: $route.query,
625
- // 菜单状态
626
- menuStatus,
627
- // 获取当前路由
628
- getRoute() {
629
- return $route
630
- },
631
- // 获取节点
632
- getNode,
633
- // 更新节点
634
- updateNode,
635
- // 删除节点
636
- deleteNode,
637
- // 菜单点击
638
- menuClick,
639
- // 获取展开节点缓存
640
- getExpandedCache,
641
- // 设置展开节点缓存
642
- setExpandedCache,
643
- // 展开全部
644
- expandAll,
645
- // 收起全部
646
- collapseAll,
647
- // 判断节点能否被拖拽
648
- allowDrag,
649
- // 拖拽时判定目标节点能否被放置, type 参数: top / inner / bottom / none ( 目标节点上方 / 目标节点内部 / 目标节点下方 / 无任何操作 )
650
- allowDrop,
651
- // 树节点拖拽结束
652
- nodeDragEnd,
653
- }
654
- }
655
-
656
- /**
657
- * 树业务
658
- */
659
- const $tree = {
660
- // 创建树实例
661
- create,
662
- }
663
-
664
- export default $tree
1
+ import $n_has from 'lodash/has'
2
+ import $n_get from 'lodash/get'
3
+ import $n_isNil from 'lodash/isNil'
4
+ import $n_findIndex from 'lodash/findIndex'
5
+ import $n_cloneDeep from 'lodash/cloneDeep'
6
+
7
+ import $n_router from '@netang/utils/vue/router'
8
+
9
+ import $n_isValidArray from '@netang/utils/isValidArray'
10
+ import $n_isValidObject from '@netang/utils/isValidObject'
11
+ import $n_isValidString from '@netang/utils/isValidString'
12
+ import $n_hasId from '@netang/utils/hasId'
13
+ import $n_http from '@netang/utils/http'
14
+ import $n_run from '@netang/utils/run'
15
+ import $n_storage from '@netang/utils/storage'
16
+
17
+ import $n_toast from './toast'
18
+ import $n_confirm from './confirm'
19
+ import $n_alert from './alert'
20
+
21
+ import { isRef, watch, inject, ref, computed } from 'vue'
22
+
23
+ import { NPowerKey } from './symbols'
24
+
25
+ /**
26
+ * 获取节点
27
+ */
28
+ function getTreeNode(data, nodeId) {
29
+ for (const item of data) {
30
+
31
+ if (item.id === nodeId) {
32
+ return item
33
+ }
34
+
35
+ // 如果是父节点
36
+ if (item.children.length) {
37
+ const res = getTreeNode(item.children, nodeId)
38
+ if (res) {
39
+ return res
40
+ }
41
+ }
42
+ }
43
+
44
+ return false
45
+ }
46
+
47
+ /**
48
+ * 获取子节点
49
+ */
50
+ function getChildren(data, callback) {
51
+ for (const item of data) {
52
+ if ($n_run(callback)(item) === false) {
53
+ return false
54
+ }
55
+ // 如果是父节点
56
+ if (item.children.length) {
57
+ const res = getChildren(item.children, callback)
58
+ if (res === false) {
59
+ return false
60
+ }
61
+ }
62
+ }
63
+ return true
64
+ }
65
+
66
+ /**
67
+ * 创建树实例
68
+ */
69
+ function create(options) {
70
+
71
+ const {
72
+ // 路由路径
73
+ path,
74
+ // 路由参数
75
+ query,
76
+ // 树节点列表
77
+ nodes,
78
+ // 树展开节点
79
+ expanded,
80
+ // 菜单参数
81
+ menu: menuOptions,
82
+ // 初始表单数据
83
+ initFormData,
84
+ // 表单数据
85
+ formData,
86
+ // 重新加载
87
+ reload,
88
+ // 是否开启展开节点缓存
89
+ cache,
90
+ } = Object.assign({
91
+ // 路由路径
92
+ path: '',
93
+ // 路由参数
94
+ query: {},
95
+ // 菜单参数
96
+ menu: {},
97
+ // 是否开启展开节点缓存
98
+ cache: false,
99
+ }, options)
100
+
101
+ // 获取权限注入
102
+ const $power = $n_has(options, '$power') ? options.$power : inject(NPowerKey)
103
+ const hasPowr = !! $power
104
+
105
+ // 获取权限路由
106
+ const $route = $n_isValidString(path) ?
107
+ // 如果为自定义路由
108
+ $n_router.resolve({
109
+ path,
110
+ query,
111
+ })
112
+ // 否则获取当前路由
113
+ : (hasPowr ? $power.getRoute() : $n_router.getRoute())
114
+
115
+ // 权限按钮
116
+ const powerBtns = hasPowr ? $power.powerBtns : ref([])
117
+
118
+ // 是否有展开节点
119
+ const hasExpanded = ! $n_isNil(expanded) && isRef(expanded)
120
+
121
+ // 如果开启展开节点缓存
122
+ if (hasExpanded && cache) {
123
+
124
+ // 设置树展开节点初始缓存
125
+ expanded.value = getExpandedCache(expanded.value)
126
+
127
+ /**
128
+ * 监听树展开节点
129
+ */
130
+ watch(expanded, function(val) {
131
+ // 设置树展开节点缓存
132
+ setExpandedCache(val)
133
+ })
134
+ }
135
+
136
+ // 获取菜单状态
137
+ const menuStatus = computed(function() {
138
+
139
+ const o = Object.assign({
140
+ updateName: 'update',
141
+ moveName: 'move',
142
+ copyName: 'copy',
143
+ deleteName: 'realdel',
144
+ statusName: 'status'
145
+ }, menuOptions)
146
+
147
+ const maps = {}
148
+ maps[o.updateName] = 'update'
149
+ maps[o.moveName] = 'move'
150
+ maps[o.copyName] = 'copy'
151
+ maps[o.deleteName] = 'delete'
152
+ maps[o.statusName] = 'status'
153
+
154
+ const allPowerBtn = {}
155
+ for (const item of powerBtns.value) {
156
+ if ($n_has(maps, $n_get(item, 'name'))) {
157
+ allPowerBtn[maps[item.name]] = item
158
+ }
159
+ }
160
+
161
+ return {
162
+ all: $n_isValidObject(allPowerBtn),
163
+ update: $n_has(allPowerBtn, 'update'),
164
+ move: $n_has(allPowerBtn, 'move'),
165
+ copy: $n_has(allPowerBtn, 'copy'),
166
+ delete: $n_has(allPowerBtn, 'delete'),
167
+ status: $n_has(allPowerBtn, 'status'),
168
+ allPowerBtn,
169
+ }
170
+ })
171
+
172
+ /**
173
+ * 获取节点
174
+ */
175
+ function getNode(nodeId) {
176
+ return getTreeNode(nodes.value, nodeId)
177
+ }
178
+
179
+ /**
180
+ * 格式化节点
181
+ */
182
+ function formatNode(attr) {
183
+
184
+ // 设置属性
185
+ attr = Object.assign({}, attr)
186
+
187
+ return {
188
+ attr,
189
+ id: attr.id,
190
+ label: attr.title,
191
+ children: [],
192
+ }
193
+ }
194
+
195
+ /**
196
+ * 更新节点
197
+ */
198
+ function updateNode(data) {
199
+
200
+ // 获取 id
201
+ const id = $n_get(formData.value, 'id')
202
+
203
+ // 更新表单数据
204
+ formData.value = Object.assign({}, formData.value, data)
205
+
206
+ // 获取节点数据
207
+ const nodeItem = getNode(data.id)
208
+
209
+ // 如果为更新节点
210
+ if (id) {
211
+ if (nodeItem) {
212
+ Object.assign(nodeItem, {
213
+ attr: Object.assign({}, formData.value),
214
+ label: formData.value.title,
215
+ })
216
+ }
217
+
218
+ // 否则为新增节点
219
+ } else if (
220
+ // 如果为新增节点
221
+ $n_get(data, 'id')
222
+ // 没有节点存在
223
+ && ! nodeItem
224
+ ) {
225
+ // 获取父级节点
226
+ const parentNodeItem = getNode(formData.value.pid)
227
+ if (! parentNodeItem) {
228
+ return
229
+ }
230
+
231
+ // 新增节点
232
+ parentNodeItem.children.push(formatNode(formData.value))
233
+ }
234
+ }
235
+
236
+ /**
237
+ * 删除节点
238
+ */
239
+ function deleteNode({ id, attr }) {
240
+
241
+ // 获取父节点数据
242
+ const parentNodeItem = getNode(attr.pid)
243
+ if (! parentNodeItem) {
244
+ return
245
+ }
246
+
247
+ // 获取节点索引
248
+ const nodeIndex = $n_findIndex(parentNodeItem.children, { id })
249
+ if (nodeIndex > -1) {
250
+ parentNodeItem.children.splice(nodeIndex, 1)
251
+ }
252
+ }
253
+
254
+ /**
255
+ * 确认菜单
256
+ */
257
+ function confirmMenu(callback) {
258
+ // 确认框
259
+ $n_confirm({
260
+ message: '确认要执行该操作吗?',
261
+ })
262
+ // 点击确认执行
263
+ .onOk(callback)
264
+ }
265
+
266
+ /**
267
+ * 菜单点击
268
+ */
269
+ function menuClick(options) {
270
+
271
+ // 参数
272
+ const o = Object.assign({
273
+ // 菜单类型
274
+ type: '',
275
+ // 节点
276
+ node: null,
277
+ }, options)
278
+
279
+ // 菜单类型
280
+ switch (o.type) {
281
+
282
+ // 添加下级
283
+ case 'update':
284
+ // 更新表单数据
285
+ formData.value = Object.assign({}, initFormData, {
286
+ pid: o.node.attr.id,
287
+ })
288
+ break
289
+
290
+ // 复制
291
+ case 'copy':
292
+ // 确认菜单
293
+ confirmMenu(async function() {
294
+
295
+ if (! $n_get(menuStatus.value, 'allPowerBtn.copy.url')) {
296
+ console.error('没有找到复制地址')
297
+ return
298
+ }
299
+
300
+ // 复制的当前节点的属性
301
+ const newAttr = Object.assign({}, o.node.attr, {
302
+ title: '【复制】' + o.node.attr.title,
303
+ })
304
+
305
+ // 复制列表
306
+ const copyLists = [ newAttr ]
307
+
308
+ // 是否复制叶子节点
309
+ const isLeafNode = ! o.node.children.length
310
+
311
+ // 如果复制的是父级节点
312
+ if (! isLeafNode) {
313
+ getChildren(o.node.children, function(item) {
314
+ copyLists.push(item.attr)
315
+ })
316
+ }
317
+
318
+ // 请求 - 复制
319
+ const { status, data: res } = await $n_http({
320
+ url: menuStatus.value.allPowerBtn.copy.url,
321
+ data: {
322
+ data: copyLists,
323
+ },
324
+ })
325
+ if (! status) {
326
+ return
327
+ }
328
+
329
+ // 如果复制的是叶子节点
330
+ if (isLeafNode) {
331
+
332
+ // 如果返回了 id
333
+ if ($n_hasId(res)) {
334
+
335
+ // 更新数据
336
+ Object.assign(newAttr, res)
337
+
338
+ // 获取该叶子节点的父级节点
339
+ const parentNodeItem = getNode(newAttr.pid)
340
+ if (! parentNodeItem) {
341
+ return
342
+ }
343
+
344
+ // 新增节点
345
+ parentNodeItem.children.push(formatNode(newAttr))
346
+
347
+ // 否则重新加载列表
348
+ } else {
349
+ reload()
350
+ }
351
+
352
+ // 否则重新加载列表
353
+ } else {
354
+ reload()
355
+ }
356
+
357
+ // 轻提示
358
+ $n_toast({
359
+ type: 'positive',
360
+ message: '复制成功',
361
+ })
362
+ })
363
+ break
364
+
365
+ // 删除
366
+ case 'delete':
367
+
368
+ // 如果有子节点
369
+ if (o.node.children.length) {
370
+ // 提示框
371
+ $n_alert({
372
+ message: '请先删除该节点下的子节点',
373
+ })
374
+ return
375
+ }
376
+
377
+ if (! $n_get(menuStatus.value, 'allPowerBtn.delete.url')) {
378
+ console.error('没有找到删除地址')
379
+ return
380
+ }
381
+
382
+ // 确认菜单
383
+ confirmMenu(async function() {
384
+
385
+ // 请求 - 删除
386
+ const { status } = await $n_http({
387
+ url: menuStatus.value.allPowerBtn.delete.url,
388
+ data: {
389
+ id: o.node.id,
390
+ },
391
+ })
392
+ if (! status) {
393
+ return
394
+ }
395
+
396
+ // 删除节点
397
+ deleteNode(o.node)
398
+
399
+ // 轻提示
400
+ $n_toast({
401
+ type: 'positive',
402
+ message: '删除成功',
403
+ })
404
+ })
405
+ break
406
+
407
+ // 全部禁用
408
+ case 'statusDisable':
409
+ // 全部正常
410
+ case 'statusNormal':
411
+
412
+ if (! $n_get(menuStatus.value, 'allPowerBtn.status.url')) {
413
+ console.error('没有找到状态地址')
414
+ return
415
+ }
416
+
417
+ // 确认菜单
418
+ confirmMenu(async function() {
419
+
420
+ // 设置状态 ids
421
+ const statusIds = [ o.node.id ]
422
+
423
+ // 新状态
424
+ const newStatus = o.type === 'statusNormal' ? 1 : 0
425
+
426
+ // 是否叶子节点
427
+ const isLeafNode = ! o.node.children.length
428
+
429
+ // 如果复制的是父级节点
430
+ if (! isLeafNode) {
431
+ getChildren(o.node.children, function(item) {
432
+ statusIds.push(item.id)
433
+ })
434
+ }
435
+
436
+ // 请求 - 全部禁用/正常
437
+ const { status } = await $n_http({
438
+ url: menuStatus.value.allPowerBtn.status.url,
439
+ data: {
440
+ // ids
441
+ ids: statusIds,
442
+ // 新状态值
443
+ status: newStatus,
444
+ },
445
+ })
446
+ if (! status) {
447
+ return
448
+ }
449
+
450
+ // 设置当前节点状态
451
+ o.node.attr.status = newStatus
452
+
453
+ // 如果是父级节点
454
+ if (! isLeafNode) {
455
+ getChildren(o.node.children, function(item) {
456
+ item.attr.status = newStatus
457
+ })
458
+ }
459
+
460
+ // 轻提示
461
+ $n_toast({
462
+ type: 'positive',
463
+ message: '恭喜您,操作成功',
464
+ })
465
+ })
466
+ break
467
+ }
468
+ }
469
+
470
+ /**
471
+ * 获取展开节点缓存
472
+ */
473
+ function getExpandedCache(defaultValue = []) {
474
+ // 获取展开节点缓存
475
+ const res = $n_storage.get('tree_expanded_' + $route.fullPath)
476
+ return $n_isValidArray(res) ? res : defaultValue
477
+ }
478
+
479
+ /**
480
+ * 设置展开节点缓存
481
+ */
482
+ function setExpandedCache(expanded) {
483
+ // 设置展开节点缓存(永久缓存)
484
+ $n_storage.set('tree_expanded_' + $route.fullPath, expanded, 0)
485
+ }
486
+
487
+ /**
488
+ * 展开全部
489
+ */
490
+ function expandAll() {
491
+
492
+ // 展开节点 ids
493
+ const ids = []
494
+
495
+ function getChildren(data) {
496
+ for (const { id, children } of data) {
497
+ ids.push(id)
498
+ if ($n_isValidArray(children)) {
499
+ getChildren(children)
500
+ }
501
+ }
502
+ }
503
+
504
+ if ($n_isValidArray(nodes.value)) {
505
+ getChildren(nodes.value)
506
+ }
507
+
508
+ // 设置展开节点数组
509
+ expanded.value = ids
510
+ }
511
+
512
+ /**
513
+ * 收起全部
514
+ */
515
+ function collapseAll() {
516
+ // 设置展开节点数组
517
+ expanded.value = [0]
518
+ }
519
+
520
+ /**
521
+ * 判断节点能否被拖拽
522
+ */
523
+ function allowDrag(draggingNode) {
524
+ return $n_hasId(draggingNode.id)
525
+ }
526
+
527
+ /**
528
+ * 拖拽时判定目标节点能否被放置, type 参数: top / inner / bottom / none ( 目标节点上方 / 目标节点内部 / 目标节点下方 / 无任何操作 )
529
+ */
530
+ function allowDrop(draggingNode, dropNode, dropType) {
531
+ return dropType === 'inner'
532
+ || $n_hasId(dropNode.id)
533
+ }
534
+
535
+ /**
536
+ * 树节点拖拽结束
537
+ */
538
+ async function nodeDragEnd(draggingNode, dropNode, dropType, doDrop) {
539
+ if (dropType !== 'none') {
540
+
541
+ if (! $n_get(menuStatus.value, 'allPowerBtn.move.url')) {
542
+
543
+ // 提示框
544
+ $n_alert({
545
+ message: '没有找到移动地址',
546
+ })
547
+
548
+ return
549
+ }
550
+
551
+ // 克隆当前树列表数据
552
+ const nodesClone = $n_cloneDeep(nodes.value)
553
+
554
+ // 开始拖拽
555
+ const children = doDrop()
556
+ if (children === false) {
557
+ return
558
+ }
559
+
560
+ // 修改拖拽节点的父级 id
561
+ draggingNode.attr.pid =
562
+ // 如果拖动节点 在 目标节点的 内部
563
+ dropType === 'inner' ?
564
+ // 将拖动节点的 pid 改为 目标节点的 id
565
+ dropNode.attr.id
566
+ // 将拖动节点的 pid 改为 目标节点的 pid
567
+ : dropNode.attr.pid
568
+
569
+ // 移动列表
570
+ const moveLists = []
571
+
572
+ // 当前拖拽节点在新列表中的索引
573
+ let dropIndex = $n_findIndex(children, e => e.id === draggingNode.id)
574
+ if (dropIndex > -1) {
575
+
576
+ if (
577
+ // 如果拖拽到目标节点下方
578
+ dropType === 'bottom'
579
+ // 并且拖拽节点当前的位置不是第一个
580
+ && dropIndex > 0
581
+ ) {
582
+ dropIndex--
583
+ }
584
+
585
+ for (let i = dropIndex; i < children.length; i++) {
586
+ const { attr } = children[i]
587
+ attr.sort = i + 1
588
+ moveLists.push({
589
+ id: attr.id,
590
+ pid: attr.pid,
591
+ sort: attr.sort,
592
+ })
593
+ }
594
+
595
+ // 如果有移动列表
596
+ if (moveLists.length) {
597
+
598
+ // 请求 - 移动
599
+ const { status } = await $n_http({
600
+ url: menuStatus.value.allPowerBtn.move.url,
601
+ data: {
602
+ data: moveLists,
603
+ },
604
+ })
605
+
606
+ // 移动成功
607
+ if (status) {
608
+ return
609
+ }
610
+ }
611
+ }
612
+
613
+ // 移动失败, 还原数据
614
+ nodes.value = nodesClone
615
+ }
616
+ }
617
+
618
+ return {
619
+ // 当前路由全路径
620
+ routeFullPath: $route.fullPath,
621
+ // 当前路由路径
622
+ routePath: $route.path,
623
+ // 当前路由参数
624
+ routeQuery: $route.query,
625
+ // 菜单状态
626
+ menuStatus,
627
+ // 获取当前路由
628
+ getRoute() {
629
+ return $route
630
+ },
631
+ // 获取节点
632
+ getNode,
633
+ // 更新节点
634
+ updateNode,
635
+ // 删除节点
636
+ deleteNode,
637
+ // 菜单点击
638
+ menuClick,
639
+ // 获取展开节点缓存
640
+ getExpandedCache,
641
+ // 设置展开节点缓存
642
+ setExpandedCache,
643
+ // 展开全部
644
+ expandAll,
645
+ // 收起全部
646
+ collapseAll,
647
+ // 判断节点能否被拖拽
648
+ allowDrag,
649
+ // 拖拽时判定目标节点能否被放置, type 参数: top / inner / bottom / none ( 目标节点上方 / 目标节点内部 / 目标节点下方 / 无任何操作 )
650
+ allowDrop,
651
+ // 树节点拖拽结束
652
+ nodeDragEnd,
653
+ }
654
+ }
655
+
656
+ /**
657
+ * 树业务
658
+ */
659
+ const $tree = {
660
+ // 创建树实例
661
+ create,
662
+ }
663
+
664
+ export default $tree