bri-components 1.5.21 → 1.6.0

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 (153) hide show
  1. package/README.md +83 -83
  2. package/lib/styles/bundle.css +12 -12
  3. package/lib/styles/font/fontello.svg +31 -31
  4. package/package.json +125 -125
  5. package/src/components/Error/Error403.vue +42 -42
  6. package/src/components/Error/Error404.vue +40 -40
  7. package/src/components/Error/Error500.vue +51 -51
  8. package/src/components/Error/error.less +162 -162
  9. package/src/components/Error/errorBack.vue +40 -40
  10. package/src/components/controls/DshControlInput.vue +195 -195
  11. package/src/components/controls/base/BriUpload/BriUpload.vue +434 -434
  12. package/src/components/controls/base/BriUpload/BriUploadImage.vue +377 -377
  13. package/src/components/controls/base/BriUpload/uploadList.vue +727 -727
  14. package/src/components/controls/base/BriUpload/uploadMixin.js +446 -446
  15. package/src/components/controls/base/DshCascader/DshCascader.vue +215 -215
  16. package/src/components/controls/base/DshCascader/components/cascaderModal.vue +366 -366
  17. package/src/components/controls/base/DshCascader/components/cascaderPicker.vue +416 -416
  18. package/src/components/controls/base/DshCascader/components/cascaderSimple.vue +141 -141
  19. package/src/components/controls/base/DshCascader/components/cascaderTree.vue +151 -151
  20. package/src/components/controls/base/DshCoordinates.vue +585 -577
  21. package/src/components/controls/base/DshDate/DshDate.vue +191 -191
  22. package/src/components/controls/base/DshDate/DshDaterange.vue +186 -186
  23. package/src/components/controls/base/DshDivider.vue +201 -201
  24. package/src/components/controls/base/DshEditor.vue +274 -274
  25. package/src/components/controls/base/DshInput/BriInputs.vue +166 -166
  26. package/src/components/controls/base/DshInput/DshInput.vue +260 -260
  27. package/src/components/controls/base/DshNumber/BriInputNumber/BriInputNumber.vue +435 -435
  28. package/src/components/controls/base/DshNumber/BriInputNumber/mixins/emitter.js +34 -34
  29. package/src/components/controls/base/DshNumber/BriInputNumber/mixins/form.js +14 -14
  30. package/src/components/controls/base/DshNumber/BriInputNumber/utils/assist.js +322 -322
  31. package/src/components/controls/base/DshNumber/DshNumber.vue +143 -143
  32. package/src/components/controls/base/DshNumber/DshNumberange.vue +109 -109
  33. package/src/components/controls/base/DshSelect/DshCheckbox.vue +168 -168
  34. package/src/components/controls/base/DshSelect/DshSelect.vue +180 -180
  35. package/src/components/controls/base/DshSelect/DshSelectAll.vue +269 -269
  36. package/src/components/controls/base/DshSwitch/DshSwitch.vue +115 -115
  37. package/src/components/controls/control.less +324 -324
  38. package/src/components/controls/controlMap.js +117 -117
  39. package/src/components/controls/extra/DshColor.vue +81 -81
  40. package/src/components/controls/extra/DshThemeColor.vue +100 -100
  41. package/src/components/controls/extra/DshThemeIcon.vue +122 -122
  42. package/src/components/controls/mixins/cascaderMixin.js +325 -325
  43. package/src/components/controls/mixins/cascaderPickerMixin.js +227 -227
  44. package/src/components/controls/mixins/cascaderTableMixin.js +130 -130
  45. package/src/components/controls/mixins/controlMixin.js +393 -393
  46. package/src/components/controls/mixins/dateMixin.js +149 -149
  47. package/src/components/controls/mixins/flatTableMixin.js +111 -111
  48. package/src/components/controls/mixins/numberMixin.js +112 -112
  49. package/src/components/controls/mixins/selectMixin.js +233 -233
  50. package/src/components/controls/mixins/switchMixin.js +87 -87
  51. package/src/components/controls/mixins/userAndDepartMixin.js +260 -260
  52. package/src/components/controls/senior/DshLabels.vue +333 -333
  53. package/src/components/controls/senior/DshPackage.vue +57 -57
  54. package/src/components/controls/senior/cascaderTable.vue +213 -213
  55. package/src/components/controls/senior/correlation.vue +135 -135
  56. package/src/components/controls/senior/flatTable.vue +138 -138
  57. package/src/components/controls/senior/selectDepartments.vue +399 -399
  58. package/src/components/controls/senior/selectUsers/departMenu.vue +293 -293
  59. package/src/components/controls/senior/selectUsers/selectUsers.vue +712 -712
  60. package/src/components/controls/special/DshBack.vue +42 -42
  61. package/src/components/controls/special/DshUndeveloped.vue +41 -41
  62. package/src/components/form/DshAdvSearch.vue +510 -510
  63. package/src/components/form/DshDefaultSearch.vue +260 -260
  64. package/src/components/form/DshForm.vue +494 -494
  65. package/src/components/form/searchMixin.js +376 -376
  66. package/src/components/list/BriCard.vue +95 -95
  67. package/src/components/list/BriTable.vue +205 -205
  68. package/src/components/list/BriTree.vue +529 -529
  69. package/src/components/list/BriTreeItem.vue +163 -163
  70. package/src/components/list/DshBox/DshBox.vue +219 -219
  71. package/src/components/list/DshBox/DshCard.vue +446 -446
  72. package/src/components/list/DshBox/DshCrossTable.vue +827 -827
  73. package/src/components/list/DshBox/DshList.vue +404 -404
  74. package/src/components/list/DshBox/DshPanel.vue +669 -669
  75. package/src/components/list/DshBox/DshSingleData.vue +119 -119
  76. package/src/components/list/DshBox/DshTable.vue +239 -239
  77. package/src/components/list/DshCascaderTable.vue +115 -115
  78. package/src/components/list/DshFlatTable.vue +337 -337
  79. package/src/components/list/DshPage.vue +194 -194
  80. package/src/components/list/DshTreeTable.vue +113 -113
  81. package/src/components/list/common/importModal.vue +243 -243
  82. package/src/components/list/common/quoteListModal.vue +206 -206
  83. package/src/components/list/mixins/DshCascaderTableMixin.js +278 -278
  84. package/src/components/list/mixins/DshFlatTableMixin.js +509 -509
  85. package/src/components/list/mixins/DshTreeTableMixin.js +286 -286
  86. package/src/components/list/mixins/tableBaseMixin.js +1653 -1653
  87. package/src/components/list/mixins/treeTableBaseMixin.js +145 -145
  88. package/src/components/other/BriAvatar.vue +166 -166
  89. package/src/components/other/BriCode.vue +125 -125
  90. package/src/components/other/BriCollapseTree.vue +207 -207
  91. package/src/components/other/BriGantt.vue +1087 -1087
  92. package/src/components/other/BriIframe.vue +116 -116
  93. package/src/components/other/BriLoading.vue +171 -171
  94. package/src/components/other/BriSvg.vue +27 -27
  95. package/src/components/other/DshColorPanel.vue +128 -128
  96. package/src/components/other/DshMenuNav.vue +188 -188
  97. package/src/components/small/BriButton.vue +71 -71
  98. package/src/components/small/BriDrawer.vue +169 -169
  99. package/src/components/small/BriTooltip.vue +87 -87
  100. package/src/components/small/DshBtnModal.vue +68 -68
  101. package/src/components/small/DshButtons.vue +324 -324
  102. package/src/components/small/DshDropdown.vue +225 -225
  103. package/src/components/small/DshIcons.vue +59 -59
  104. package/src/components/small/DshListRender.js +21 -21
  105. package/src/components/small/DshModal.vue +160 -160
  106. package/src/components/small/DshSteps.vue +141 -141
  107. package/src/components/small/DshTabs.vue +598 -598
  108. package/src/components/small/DshTabsSet.vue +309 -309
  109. package/src/components/small/DshTags.vue +251 -251
  110. package/src/components/small/DshTitle.vue +50 -50
  111. package/src/components/small/render.js +20 -20
  112. package/src/components/unit/DshFormUnit.vue +398 -398
  113. package/src/components/unit/DshListUnit.vue +115 -115
  114. package/src/components/unit/unitMixin.js +86 -86
  115. package/src/data/index.js +4 -4
  116. package/src/index.js +285 -285
  117. package/src/styles/bundle.css +12 -12
  118. package/src/styles/components/BriButton.less +307 -307
  119. package/src/styles/components/BriTable.less +344 -344
  120. package/src/styles/components/DshModal.less +257 -257
  121. package/src/styles/components/index.less +3 -3
  122. package/src/styles/global/animate.less +11 -11
  123. package/src/styles/global/base.less +45 -45
  124. package/src/styles/global/box.less +186 -186
  125. package/src/styles/global/control.less +122 -122
  126. package/src/styles/global/flex.less +282 -282
  127. package/src/styles/global/global.less +8 -8
  128. package/src/styles/global/text.less +59 -59
  129. package/src/styles/global/variables.less +85 -85
  130. package/src/styles/iconfont/iconfont.css +254 -254
  131. package/src/styles/iconfont/iconfont.json +422 -422
  132. package/src/styles/iconfont/iconfont.svg +137 -137
  133. package/src/styles/index.less +26 -26
  134. package/src/styles/reset-easytable.less +21 -21
  135. package/src/styles/reset-iview-controls.less +145 -145
  136. package/src/styles/reset-iview-other.less +49 -49
  137. package/src/styles/reset-iview-variables.less +43 -43
  138. package/src/styles/reset.less +45 -45
  139. package/src/utils/index.js +3 -5
  140. package/lib/0.bri-components.min.js +0 -1
  141. package/lib/1.bri-components.min.js +0 -1
  142. package/lib/10.bri-components.min.js +0 -1
  143. package/lib/11.bri-components.min.js +0 -1
  144. package/lib/2.bri-components.min.js +0 -1
  145. package/lib/3.bri-components.min.js +0 -1
  146. package/lib/4.bri-components.min.js +0 -1
  147. package/lib/5.bri-components.min.js +0 -1
  148. package/lib/6.bri-components.min.js +0 -1
  149. package/lib/7.bri-components.min.js +0 -1
  150. package/lib/8.bri-components.min.js +0 -1
  151. package/lib/9.bri-components.min.js +0 -1
  152. package/lib/bri-components.min.js +0 -18
  153. package/src/utils/table.js +0 -175
@@ -1,529 +1,529 @@
1
- <template>
2
- <div class="BriTree">
3
- <div class="BriTree-action">
4
- <dsh-buttons
5
- class="BriTree-action-create"
6
- :list="$getOperationList(['createNode'])"
7
- @click="$dispatchEvent($event)"
8
- ></dsh-buttons>
9
- </div>
10
-
11
- <div class="BriTree-tree">
12
- <Tree
13
- :data="treeData"
14
- :render="renderContent"
15
- ></Tree>
16
- </div>
17
-
18
- <!-- 添加节点弹窗 -->
19
- <dsh-modal
20
- class="BriTree-modal"
21
- v-model="treeFormShow"
22
- mode="custom"
23
- :propsObj="treeFormPropsObj"
24
- >
25
- <div class="BriTree-modal-content">
26
- <dsh-form
27
- ref="treeForm"
28
- :formList="treeFormList"
29
- :formData="treeFormData"
30
- :labelStyle="{ width: '80px' }"
31
- ></dsh-form>
32
-
33
- <dsh-buttons
34
- class="BriTree-modal-content-btns"
35
- :list="$getOperationList(['clickNodeCancel', 'clickNodeConfirm'])"
36
- @click="$dispatchEvent($event, { data: treeFormData })"
37
- ></dsh-buttons>
38
- </div>
39
- </dsh-modal>
40
- </div>
41
- </template>
42
-
43
- <script>
44
- import { resourceData } from "../../data/index.js";
45
-
46
- const loop = (arr) => {
47
- return arr.map(item => {
48
- return {
49
- ...item,
50
- isEdit: false,
51
- children: loop(item.children || [])
52
- };
53
- });
54
- };
55
- export default {
56
- name: "BriTree",
57
- props: {
58
- data: Array,
59
- // 树形级联类别:cascader dropdown
60
- resType: {
61
- type: String,
62
- default: "dropdown"
63
- },
64
- showKey: {
65
- type: Boolean,
66
- default: false
67
- },
68
- useColor: {
69
- type: Boolean,
70
- default: false
71
- },
72
- useCustomKey: {
73
- type: Boolean,
74
- default: true
75
- }
76
- },
77
- model: {
78
- prop: "data",
79
- event: "on-change"
80
- },
81
- data () {
82
- return {
83
- colorMap: resourceData.colorMap,
84
- operationMap: {
85
- createNode: {
86
- name: "添加节点",
87
- icon: "ios-add",
88
- type: "createNode",
89
- btnType: "primary",
90
- style: "padding: 0 7px;",
91
- event: "clickAddNode"
92
- },
93
- deleteNode: {
94
- name: "删除",
95
- icon: "ios-remove",
96
- size: "20",
97
- type: "deleteNode",
98
- event: "clickDeleteNode"
99
- },
100
- clickNodeName: {
101
- name: "点击名字",
102
- type: "clickNodeName",
103
- event: "clickNodeName"
104
- },
105
- onBlur: {
106
- name: "失去焦点",
107
- type: "onBlur",
108
- event: "onBlur"
109
- },
110
- clickColor: {
111
- name: "点击颜色",
112
- type: "clickColor",
113
- event: "clickColor"
114
- },
115
- clickNodeCancel: {
116
- name: "取消",
117
- type: "clickNodeCancel",
118
- event: "clickNodeCancel",
119
- btnType: "default",
120
- class: "z-default"
121
- },
122
- clickNodeConfirm: {
123
- name: "确认",
124
- type: "clickNodeConfirm",
125
- event: "clickNodeConfirm",
126
- btnType: "primary",
127
- class: "z-primary"
128
- }
129
- },
130
- treeData: [],
131
-
132
- // 添加节点弹窗
133
- treeFormShow: false,
134
- treeFormPropsObj: {
135
- title: "添加节点",
136
- class: "bri-modal-center"
137
- },
138
- treeFormData: {
139
- _key: "",
140
- name: "",
141
- description: ""
142
- },
143
- treeFormNode: null
144
- };
145
- },
146
- computed: {
147
- colorArr () {
148
- return Object.values(this.colorMap);
149
- },
150
- colorArrMap () {
151
- return Object.keys(this.colorMap).reduce((obj, item) => {
152
- return { ...obj, [this.colorMap[item]]: item };
153
- }, {});
154
- },
155
- treeFormList () {
156
- let list = [
157
- {
158
- _key: "name",
159
- _name: "名称",
160
- _type: "text",
161
- _default: "未命名节点",
162
- _line: true,
163
- _required: true
164
- },
165
- {
166
- _key: "_key",
167
- _name: "唯一标识",
168
- _type: "text",
169
- _textType: "key",
170
- _line: true,
171
- _required: true
172
- },
173
- {
174
- _key: "description",
175
- _name: "描述",
176
- _type: "textarea",
177
- _line: true,
178
- _required: false
179
- }
180
- ];
181
-
182
- return this.useCustomKey ? list : list.slice(0, 1);
183
- }
184
- },
185
- created () {
186
- this.treeData = loop(this.data);
187
- },
188
- methods: {
189
- // 点击添加节点按钮
190
- clickAddNode (item, node, a) {
191
- this.treeFormData = {
192
- _key: "",
193
- name: "未命名节点",
194
- description: ""
195
- };
196
- this.treeFormNode = node;
197
- this.treeFormShow = true;
198
- },
199
- clickNodeCancel () {
200
- this.treeFormData = {
201
- _key: "",
202
- name: "未命名节点",
203
- description: ""
204
- };
205
- this.treeFormNode = null;
206
- this.treeFormShow = false;
207
- this.onChange();
208
- },
209
- clickNodeConfirm () {
210
- this.$refs.treeForm.$refs.form.validate(valid => {
211
- if (valid) {
212
- this.createNode(this.treeFormData, this.treeFormNode && this.treeFormNode.data);
213
- this.treeFormShow = false;
214
- } else {
215
- this.$formRulesWarning();
216
- }
217
- });
218
- this.onChange();
219
- },
220
- // 点击删除节点按钮
221
- clickDeleteNode (item, { root, node, data }) {
222
- this.$Modal.confirm({
223
- title: "警告",
224
- content: `确定删除 ‘${data.name}’
225
- ${node && node.children && node.children.length ? "及其所有子" : ""}节点吗?`,
226
- onOk: () => {
227
- this.deleteNode(root, node, data);
228
- }
229
- });
230
- },
231
- // 添加节点
232
- createNode (value, data) {
233
- let obj = {
234
- ...value,
235
- color: this.colorArrMap[this.colorArr[this.treeData.length % this.colorArr.length]],
236
- expand: true,
237
- isEdit: false,
238
- children: []
239
- };
240
- if (!this.useCustomKey) {
241
- obj._key = this.createKey(data);
242
- }
243
- if (data) {
244
- const children = data.children || [];
245
- children.push(obj);
246
- this.$set(data, "children", children);
247
- } else {
248
- this.treeData.push(obj);
249
- }
250
- this.onChange();
251
- },
252
- // 移除节点
253
- deleteNode (root, node, data) {
254
- let rootObj = root.find(el => el === node);
255
- let parentKey = rootObj && rootObj.parent;
256
- if (parentKey || parentKey === 0) {
257
- const parent = root.find(el => el.nodeKey === parentKey).node;
258
- const index = parent.children.indexOf(data);
259
- parent.children.splice(index, 1);
260
- } else {
261
- const index = this.treeData.indexOf(data);
262
- this.treeData.splice(index, 1);
263
- }
264
- this.onChange();
265
- },
266
- // 生成key
267
- createKey (data) {
268
- let digits = 4;
269
- // let parentKey = "";
270
- if (data) {
271
- // parentKey = data._key;
272
- if (data.children && data.children.length) {
273
- data = data.children;
274
- } else {
275
- return this.$encodeB36(1, digits);
276
- // return parentKey + this.$encodeB36(1, digits);
277
- }
278
- } else {
279
- data = this.treeData;
280
- if (!data.length) {
281
- return this.$encodeB36(1, digits);
282
- }
283
- }
284
- // let key = data[data.length - 1]._key.slice(-4);
285
- const maxKey = Math.max(...data.map(item => item._key)); // 增加移动功能后
286
-
287
- // let key = data[data.length - 1]._key;
288
- return this.$encodeB36(this.$decodeB36(maxKey) + 1, digits);
289
- // return parentKey + this.$encodeB36(this.$decodeB36(key) + 1, digits);
290
- },
291
- // clickNodeName blur 时
292
- onBlur (item, { data }) {
293
- if (!data.name) {
294
- data.name = data.oldName;
295
- }
296
- data.isEdit = false;
297
- this.$emit("on-change", this.treeData);
298
- },
299
- clickNodeName (item, { data }) {
300
- data.oldName = data.name;
301
- data.isEdit = true;
302
- },
303
- clickColor ({ data }, color) {
304
- data.color = this.colorArrMap[color];
305
- this.$emit("on-change", this.treeData);
306
- },
307
- // 渲染函数
308
- renderContent (h, { root, node, data }) {
309
- return h("div", {
310
- style: {
311
- display: "inline-flex",
312
- width: "100%",
313
- height: "36px",
314
- lineHeight: "33px",
315
- border: "1px solid rgba(211, 215, 228, 0.5)",
316
- borderRadius: "4px",
317
- justifyContent: "space-between"
318
- }
319
- }, [
320
- h("div", {
321
- style: { flex: 1, overflowX: "auto", display: "flex", alignItems: "center", overflowY: "hidden", padding: "0 5px" }
322
- }, [
323
- this.resType === "dropdown" ? h("Icon", {
324
- props: {
325
- type: "md-arrow-round-up",
326
- size: "14"
327
- },
328
- style: {
329
- margin: "0 2px",
330
- color: "#999"
331
- },
332
- on: {
333
- click: () => {
334
- this.handleUp(data);
335
- }
336
- }
337
- }) : "",
338
- this.resType === "dropdown" ? h("Icon", {
339
- props: {
340
- type: "md-arrow-round-down",
341
- size: "14"
342
- },
343
- style: {
344
- margin: "0 2px",
345
- color: "#999"
346
- },
347
- on: {
348
- click: () => {
349
- this.handleDown(data);
350
- }
351
- }
352
- }) : "",
353
- h("dsh-color-panel", {
354
- props: {
355
- dropdownObj: {
356
- icon: "md-arrow-dropdown-circle",
357
- color: this.colorMap[data.color] || this.colorMap["color-default"]
358
- },
359
- menuClass: "BriTree-dropdown-menu",
360
- list: this.colorArr
361
- },
362
- style: {
363
- margin: "0 2px"
364
- },
365
- on: {
366
- click: (color) => this.clickColor({ root, node, data }, color)
367
- }
368
- }),
369
-
370
- data.isEdit
371
- ? h("Input", {
372
- props: {
373
- value: data.name,
374
- placeholder: "请输入节点名称",
375
- size: "small"
376
- },
377
- directives: [{name: "focus"}],
378
- style: {
379
- width: "200px"
380
- },
381
- on: {
382
- input: (val) => {
383
- data.name = val;
384
- },
385
- "on-blur": () => this.$dispatchEvent(this.operationMap.onBlur, { root, node, data })
386
- }
387
- })
388
- : [
389
- h("span", {
390
- style: {
391
- verticalAlign: "middle",
392
- paddingLeft: "3px",
393
- flex: 1,
394
- overflow: "auto"
395
- },
396
- on: {
397
- click: () => this.$dispatchEvent(this.operationMap.clickNodeName, { root, node, data })
398
- }
399
- }, data.name),
400
- this.showKey ? h("span", {
401
- style: {
402
- marginLeft: "20px",
403
- fontSize: "12px",
404
- color: "#999"
405
- }
406
- }, data._key) : undefined
407
- ]
408
- ]),
409
- h("div", {
410
- style: { marginLeft: "10px" }
411
- }, ["createNode", "deleteNode"]
412
- .map(type => this.operationMap[type])
413
- .filter(operatonItem => !!operatonItem && ((this.resType === "dropdown") ? (operatonItem.type !== "createNode") : true))
414
- .map(btnItem => {
415
- return h("Icon", {
416
- props: ({
417
- size: btnItem.size || 20,
418
- type: btnItem.icon
419
- }),
420
- style: {
421
- margin: "0 2px",
422
- color: "#999"
423
- },
424
- on: {
425
- click: () => { this.$dispatchEvent(btnItem, { root, node, data }); }
426
- }
427
- }, btnItem.name);
428
- })
429
- )
430
- ]);
431
- },
432
- // 上移动
433
- handleUp (data) {
434
- const index = this.treeData.findIndex(item => item._key === data._key);
435
- if (index > 0) {
436
- const prevData = {...this.treeData[index - 1]};
437
- this.treeData.splice(index - 1, 1);
438
- this.treeData.splice(index, 0, prevData);
439
- this.onChange();
440
- }
441
- },
442
- handleDown (data) {
443
- const index = this.treeData.findIndex(item => item._key === data._key);
444
- if (index < this.treeData.length - 1) {
445
- const nextData = {...this.treeData[index]};
446
- this.treeData.splice(index, 1);
447
- this.treeData.splice(index + 1, 0, nextData);
448
- this.onChange();
449
- }
450
- },
451
- // 双向数据绑定
452
- onChange () {
453
- this.$emit("on-change", this.transformResData(this.treeData));
454
- },
455
-
456
- /* 工具方法 */
457
- // 过滤掉不必要数据
458
- transformResData (list) {
459
- return list.map(item => {
460
- return {
461
- _key: item._key,
462
- name: item.name,
463
- color: item.color,
464
- children: this.transformResData(item.children || [])
465
- };
466
- });
467
- }
468
- }
469
- };
470
- </script>
471
-
472
- <style lang="less">
473
- .BriTree {
474
- max-width: 1200px;
475
- min-width: 720px;
476
- height: 100%;
477
- margin: 0px auto;
478
- background: #fff;
479
- display: flex;
480
- flex-direction: column;
481
-
482
- &-action {
483
- padding: 10px;
484
- display: flex;
485
- justify-content: flex-end;
486
-
487
- &-create {
488
- display: flex;
489
- flex-direction: row;
490
- align-items: center;
491
-
492
- .ivu-icon {
493
- font-size: 20px;
494
- font-weight: bold;
495
- margin-right: -10px;
496
- vertical-align: middle;
497
- transform: translate(0, -1px);
498
- }
499
- }
500
- }
501
-
502
- &-tree {
503
- width: 100%;
504
- flex: 1;
505
- min-height: 0px;
506
- overflow: auto;
507
-
508
- .ivu-tree-title {
509
- width: calc(100% - 18px);
510
- }
511
- .ivu-tree-arrow {
512
- margin-top: 5px;
513
- }
514
- }
515
-
516
- &-modal {
517
- &-content {
518
- &-btns {
519
- .dsh-padding20();
520
- text-align: right;
521
- }
522
- }
523
- }
524
-
525
- &-dropdown-menu {
526
- width: 242px!important;
527
- }
528
- }
529
- </style>
1
+ <template>
2
+ <div class="BriTree">
3
+ <div class="BriTree-action">
4
+ <dsh-buttons
5
+ class="BriTree-action-create"
6
+ :list="$getOperationList(['createNode'])"
7
+ @click="$dispatchEvent($event)"
8
+ ></dsh-buttons>
9
+ </div>
10
+
11
+ <div class="BriTree-tree">
12
+ <Tree
13
+ :data="treeData"
14
+ :render="renderContent"
15
+ ></Tree>
16
+ </div>
17
+
18
+ <!-- 添加节点弹窗 -->
19
+ <dsh-modal
20
+ class="BriTree-modal"
21
+ v-model="treeFormShow"
22
+ mode="custom"
23
+ :propsObj="treeFormPropsObj"
24
+ >
25
+ <div class="BriTree-modal-content">
26
+ <dsh-form
27
+ ref="treeForm"
28
+ :formList="treeFormList"
29
+ :formData="treeFormData"
30
+ :labelStyle="{ width: '80px' }"
31
+ ></dsh-form>
32
+
33
+ <dsh-buttons
34
+ class="BriTree-modal-content-btns"
35
+ :list="$getOperationList(['clickNodeCancel', 'clickNodeConfirm'])"
36
+ @click="$dispatchEvent($event, { data: treeFormData })"
37
+ ></dsh-buttons>
38
+ </div>
39
+ </dsh-modal>
40
+ </div>
41
+ </template>
42
+
43
+ <script>
44
+ import { resourceData } from "../../data/index.js";
45
+
46
+ const loop = (arr) => {
47
+ return arr.map(item => {
48
+ return {
49
+ ...item,
50
+ isEdit: false,
51
+ children: loop(item.children || [])
52
+ };
53
+ });
54
+ };
55
+ export default {
56
+ name: "BriTree",
57
+ props: {
58
+ data: Array,
59
+ // 树形级联类别:cascader dropdown
60
+ resType: {
61
+ type: String,
62
+ default: "dropdown"
63
+ },
64
+ showKey: {
65
+ type: Boolean,
66
+ default: false
67
+ },
68
+ useColor: {
69
+ type: Boolean,
70
+ default: false
71
+ },
72
+ useCustomKey: {
73
+ type: Boolean,
74
+ default: true
75
+ }
76
+ },
77
+ model: {
78
+ prop: "data",
79
+ event: "on-change"
80
+ },
81
+ data () {
82
+ return {
83
+ colorMap: resourceData.colorMap,
84
+ operationMap: {
85
+ createNode: {
86
+ name: "添加节点",
87
+ icon: "ios-add",
88
+ type: "createNode",
89
+ btnType: "primary",
90
+ style: "padding: 0 7px;",
91
+ event: "clickAddNode"
92
+ },
93
+ deleteNode: {
94
+ name: "删除",
95
+ icon: "ios-remove",
96
+ size: "20",
97
+ type: "deleteNode",
98
+ event: "clickDeleteNode"
99
+ },
100
+ clickNodeName: {
101
+ name: "点击名字",
102
+ type: "clickNodeName",
103
+ event: "clickNodeName"
104
+ },
105
+ onBlur: {
106
+ name: "失去焦点",
107
+ type: "onBlur",
108
+ event: "onBlur"
109
+ },
110
+ clickColor: {
111
+ name: "点击颜色",
112
+ type: "clickColor",
113
+ event: "clickColor"
114
+ },
115
+ clickNodeCancel: {
116
+ name: "取消",
117
+ type: "clickNodeCancel",
118
+ event: "clickNodeCancel",
119
+ btnType: "default",
120
+ class: "z-default"
121
+ },
122
+ clickNodeConfirm: {
123
+ name: "确认",
124
+ type: "clickNodeConfirm",
125
+ event: "clickNodeConfirm",
126
+ btnType: "primary",
127
+ class: "z-primary"
128
+ }
129
+ },
130
+ treeData: [],
131
+
132
+ // 添加节点弹窗
133
+ treeFormShow: false,
134
+ treeFormPropsObj: {
135
+ title: "添加节点",
136
+ class: "bri-modal-center"
137
+ },
138
+ treeFormData: {
139
+ _key: "",
140
+ name: "",
141
+ description: ""
142
+ },
143
+ treeFormNode: null
144
+ };
145
+ },
146
+ computed: {
147
+ colorArr () {
148
+ return Object.values(this.colorMap);
149
+ },
150
+ colorArrMap () {
151
+ return Object.keys(this.colorMap).reduce((obj, item) => {
152
+ return { ...obj, [this.colorMap[item]]: item };
153
+ }, {});
154
+ },
155
+ treeFormList () {
156
+ let list = [
157
+ {
158
+ _key: "name",
159
+ _name: "名称",
160
+ _type: "text",
161
+ _default: "未命名节点",
162
+ _line: true,
163
+ _required: true
164
+ },
165
+ {
166
+ _key: "_key",
167
+ _name: "唯一标识",
168
+ _type: "text",
169
+ _textType: "key",
170
+ _line: true,
171
+ _required: true
172
+ },
173
+ {
174
+ _key: "description",
175
+ _name: "描述",
176
+ _type: "textarea",
177
+ _line: true,
178
+ _required: false
179
+ }
180
+ ];
181
+
182
+ return this.useCustomKey ? list : list.slice(0, 1);
183
+ }
184
+ },
185
+ created () {
186
+ this.treeData = loop(this.data);
187
+ },
188
+ methods: {
189
+ // 点击添加节点按钮
190
+ clickAddNode (item, node, a) {
191
+ this.treeFormData = {
192
+ _key: "",
193
+ name: "未命名节点",
194
+ description: ""
195
+ };
196
+ this.treeFormNode = node;
197
+ this.treeFormShow = true;
198
+ },
199
+ clickNodeCancel () {
200
+ this.treeFormData = {
201
+ _key: "",
202
+ name: "未命名节点",
203
+ description: ""
204
+ };
205
+ this.treeFormNode = null;
206
+ this.treeFormShow = false;
207
+ this.onChange();
208
+ },
209
+ clickNodeConfirm () {
210
+ this.$refs.treeForm.$refs.form.validate(valid => {
211
+ if (valid) {
212
+ this.createNode(this.treeFormData, this.treeFormNode && this.treeFormNode.data);
213
+ this.treeFormShow = false;
214
+ } else {
215
+ this.$formRulesWarning();
216
+ }
217
+ });
218
+ this.onChange();
219
+ },
220
+ // 点击删除节点按钮
221
+ clickDeleteNode (item, { root, node, data }) {
222
+ this.$Modal.confirm({
223
+ title: "警告",
224
+ content: `确定删除 ‘${data.name}’
225
+ ${node && node.children && node.children.length ? "及其所有子" : ""}节点吗?`,
226
+ onOk: () => {
227
+ this.deleteNode(root, node, data);
228
+ }
229
+ });
230
+ },
231
+ // 添加节点
232
+ createNode (value, data) {
233
+ let obj = {
234
+ ...value,
235
+ color: this.colorArrMap[this.colorArr[this.treeData.length % this.colorArr.length]],
236
+ expand: true,
237
+ isEdit: false,
238
+ children: []
239
+ };
240
+ if (!this.useCustomKey) {
241
+ obj._key = this.createKey(data);
242
+ }
243
+ if (data) {
244
+ const children = data.children || [];
245
+ children.push(obj);
246
+ this.$set(data, "children", children);
247
+ } else {
248
+ this.treeData.push(obj);
249
+ }
250
+ this.onChange();
251
+ },
252
+ // 移除节点
253
+ deleteNode (root, node, data) {
254
+ let rootObj = root.find(el => el === node);
255
+ let parentKey = rootObj && rootObj.parent;
256
+ if (parentKey || parentKey === 0) {
257
+ const parent = root.find(el => el.nodeKey === parentKey).node;
258
+ const index = parent.children.indexOf(data);
259
+ parent.children.splice(index, 1);
260
+ } else {
261
+ const index = this.treeData.indexOf(data);
262
+ this.treeData.splice(index, 1);
263
+ }
264
+ this.onChange();
265
+ },
266
+ // 生成key
267
+ createKey (data) {
268
+ let digits = 4;
269
+ // let parentKey = "";
270
+ if (data) {
271
+ // parentKey = data._key;
272
+ if (data.children && data.children.length) {
273
+ data = data.children;
274
+ } else {
275
+ return this.$encodeB36(1, digits);
276
+ // return parentKey + this.$encodeB36(1, digits);
277
+ }
278
+ } else {
279
+ data = this.treeData;
280
+ if (!data.length) {
281
+ return this.$encodeB36(1, digits);
282
+ }
283
+ }
284
+ // let key = data[data.length - 1]._key.slice(-4);
285
+ const maxKey = Math.max(...data.map(item => item._key)); // 增加移动功能后
286
+
287
+ // let key = data[data.length - 1]._key;
288
+ return this.$encodeB36(this.$decodeB36(maxKey) + 1, digits);
289
+ // return parentKey + this.$encodeB36(this.$decodeB36(key) + 1, digits);
290
+ },
291
+ // clickNodeName blur 时
292
+ onBlur (item, { data }) {
293
+ if (!data.name) {
294
+ data.name = data.oldName;
295
+ }
296
+ data.isEdit = false;
297
+ this.$emit("on-change", this.treeData);
298
+ },
299
+ clickNodeName (item, { data }) {
300
+ data.oldName = data.name;
301
+ data.isEdit = true;
302
+ },
303
+ clickColor ({ data }, color) {
304
+ data.color = this.colorArrMap[color];
305
+ this.$emit("on-change", this.treeData);
306
+ },
307
+ // 渲染函数
308
+ renderContent (h, { root, node, data }) {
309
+ return h("div", {
310
+ style: {
311
+ display: "inline-flex",
312
+ width: "100%",
313
+ height: "36px",
314
+ lineHeight: "33px",
315
+ border: "1px solid rgba(211, 215, 228, 0.5)",
316
+ borderRadius: "4px",
317
+ justifyContent: "space-between"
318
+ }
319
+ }, [
320
+ h("div", {
321
+ style: { flex: 1, overflowX: "auto", display: "flex", alignItems: "center", overflowY: "hidden", padding: "0 5px" }
322
+ }, [
323
+ this.resType === "dropdown" ? h("Icon", {
324
+ props: {
325
+ type: "md-arrow-round-up",
326
+ size: "14"
327
+ },
328
+ style: {
329
+ margin: "0 2px",
330
+ color: "#999"
331
+ },
332
+ on: {
333
+ click: () => {
334
+ this.handleUp(data);
335
+ }
336
+ }
337
+ }) : "",
338
+ this.resType === "dropdown" ? h("Icon", {
339
+ props: {
340
+ type: "md-arrow-round-down",
341
+ size: "14"
342
+ },
343
+ style: {
344
+ margin: "0 2px",
345
+ color: "#999"
346
+ },
347
+ on: {
348
+ click: () => {
349
+ this.handleDown(data);
350
+ }
351
+ }
352
+ }) : "",
353
+ h("dsh-color-panel", {
354
+ props: {
355
+ dropdownObj: {
356
+ icon: "md-arrow-dropdown-circle",
357
+ color: this.colorMap[data.color] || this.colorMap["color-default"]
358
+ },
359
+ menuClass: "BriTree-dropdown-menu",
360
+ list: this.colorArr
361
+ },
362
+ style: {
363
+ margin: "0 2px"
364
+ },
365
+ on: {
366
+ click: (color) => this.clickColor({ root, node, data }, color)
367
+ }
368
+ }),
369
+
370
+ data.isEdit
371
+ ? h("Input", {
372
+ props: {
373
+ value: data.name,
374
+ placeholder: "请输入节点名称",
375
+ size: "small"
376
+ },
377
+ directives: [{name: "focus"}],
378
+ style: {
379
+ width: "200px"
380
+ },
381
+ on: {
382
+ input: (val) => {
383
+ data.name = val;
384
+ },
385
+ "on-blur": () => this.$dispatchEvent(this.operationMap.onBlur, { root, node, data })
386
+ }
387
+ })
388
+ : [
389
+ h("span", {
390
+ style: {
391
+ verticalAlign: "middle",
392
+ paddingLeft: "3px",
393
+ flex: 1,
394
+ overflow: "auto"
395
+ },
396
+ on: {
397
+ click: () => this.$dispatchEvent(this.operationMap.clickNodeName, { root, node, data })
398
+ }
399
+ }, data.name),
400
+ this.showKey ? h("span", {
401
+ style: {
402
+ marginLeft: "20px",
403
+ fontSize: "12px",
404
+ color: "#999"
405
+ }
406
+ }, data._key) : undefined
407
+ ]
408
+ ]),
409
+ h("div", {
410
+ style: { marginLeft: "10px" }
411
+ }, ["createNode", "deleteNode"]
412
+ .map(type => this.operationMap[type])
413
+ .filter(operatonItem => !!operatonItem && ((this.resType === "dropdown") ? (operatonItem.type !== "createNode") : true))
414
+ .map(btnItem => {
415
+ return h("Icon", {
416
+ props: ({
417
+ size: btnItem.size || 20,
418
+ type: btnItem.icon
419
+ }),
420
+ style: {
421
+ margin: "0 2px",
422
+ color: "#999"
423
+ },
424
+ on: {
425
+ click: () => { this.$dispatchEvent(btnItem, { root, node, data }); }
426
+ }
427
+ }, btnItem.name);
428
+ })
429
+ )
430
+ ]);
431
+ },
432
+ // 上移动
433
+ handleUp (data) {
434
+ const index = this.treeData.findIndex(item => item._key === data._key);
435
+ if (index > 0) {
436
+ const prevData = {...this.treeData[index - 1]};
437
+ this.treeData.splice(index - 1, 1);
438
+ this.treeData.splice(index, 0, prevData);
439
+ this.onChange();
440
+ }
441
+ },
442
+ handleDown (data) {
443
+ const index = this.treeData.findIndex(item => item._key === data._key);
444
+ if (index < this.treeData.length - 1) {
445
+ const nextData = {...this.treeData[index]};
446
+ this.treeData.splice(index, 1);
447
+ this.treeData.splice(index + 1, 0, nextData);
448
+ this.onChange();
449
+ }
450
+ },
451
+ // 双向数据绑定
452
+ onChange () {
453
+ this.$emit("on-change", this.transformResData(this.treeData));
454
+ },
455
+
456
+ /* 工具方法 */
457
+ // 过滤掉不必要数据
458
+ transformResData (list) {
459
+ return list.map(item => {
460
+ return {
461
+ _key: item._key,
462
+ name: item.name,
463
+ color: item.color,
464
+ children: this.transformResData(item.children || [])
465
+ };
466
+ });
467
+ }
468
+ }
469
+ };
470
+ </script>
471
+
472
+ <style lang="less">
473
+ .BriTree {
474
+ max-width: 1200px;
475
+ min-width: 720px;
476
+ height: 100%;
477
+ margin: 0px auto;
478
+ background: #fff;
479
+ display: flex;
480
+ flex-direction: column;
481
+
482
+ &-action {
483
+ padding: 10px;
484
+ display: flex;
485
+ justify-content: flex-end;
486
+
487
+ &-create {
488
+ display: flex;
489
+ flex-direction: row;
490
+ align-items: center;
491
+
492
+ .ivu-icon {
493
+ font-size: 20px;
494
+ font-weight: bold;
495
+ margin-right: -10px;
496
+ vertical-align: middle;
497
+ transform: translate(0, -1px);
498
+ }
499
+ }
500
+ }
501
+
502
+ &-tree {
503
+ width: 100%;
504
+ flex: 1;
505
+ min-height: 0px;
506
+ overflow: auto;
507
+
508
+ .ivu-tree-title {
509
+ width: calc(100% - 18px);
510
+ }
511
+ .ivu-tree-arrow {
512
+ margin-top: 5px;
513
+ }
514
+ }
515
+
516
+ &-modal {
517
+ &-content {
518
+ &-btns {
519
+ .dsh-padding20();
520
+ text-align: right;
521
+ }
522
+ }
523
+ }
524
+
525
+ &-dropdown-menu {
526
+ width: 242px!important;
527
+ }
528
+ }
529
+ </style>