ocpview-plus 1.2.7 → 1.2.8

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ocpview-plus",
3
- "version": "1.2.7",
3
+ "version": "1.2.8",
4
4
  "title": "ocpviewPlus",
5
5
  "description": "A high quality Service UI components Library with Vue.js",
6
6
  "homepage": "",
@@ -219,6 +219,159 @@ export default {
219
219
  },
220
220
 
221
221
  methods:{
222
+ loadDynamicConfig() {
223
+ try {
224
+ const postData = {
225
+ modulecode: this.myConfig.modulecode,
226
+ moduleid: this.myConfig.modulecode
227
+ };
228
+
229
+ this.asyncPost(
230
+ this.uiconfig.resources,
231
+ "uiconfigs.getPageConfig",
232
+ postData,
233
+ (data) => {
234
+ if (!data || !this.uiconfig) {
235
+ console.log('1 没有配置数据')
236
+ return;
237
+ }
238
+
239
+ this.mergeDynamicConfig(
240
+ this.uiconfig,
241
+ data
242
+ );
243
+ }
244
+ ,function(data) {
245
+ console.error(data)
246
+ },function(data) {
247
+ console.error(data)
248
+ });
249
+ } catch (e) {
250
+ console.error('动态配置加载失败', e);
251
+ }
252
+ },
253
+
254
+ /**
255
+ * 通用递归合并配置
256
+ * @param {Object} localConfig 本地 config(this.uiconfig)
257
+ * @param {Object} serverConfig 接口返回 config
258
+ */
259
+
260
+ mergeDynamicConfig(localConfig, serverConfig) {
261
+ if (!localConfig || !serverConfig) {
262
+ console.log('1 没有配置数据')
263
+ return;
264
+ }
265
+
266
+ // ✅ 1️⃣ 处理 billQueryConfig
267
+ if (
268
+ localConfig.billQueryConfig.gridConfig.items &&
269
+ serverConfig.billQueryConfig.gridConfig.items
270
+ ) {
271
+ this.mergeFlatItems(
272
+ localConfig.billQueryConfig.gridConfig.items,
273
+ serverConfig.billQueryConfig.gridConfig.items
274
+ );
275
+ }
276
+
277
+ // ✅ 2️⃣ 处理 detailConfig
278
+ if (localConfig.detailConfig && serverConfig.detailConfig) {
279
+ this.mergeDetailConfig(
280
+ localConfig.detailConfig,
281
+ serverConfig.detailConfig
282
+ );
283
+ }
284
+ },
285
+
286
+ mergeDetailConfig(localDetail, serverDetail) {
287
+
288
+ // ✅ formsConfig
289
+ if (
290
+ localDetail.formsConfig.items &&
291
+ serverDetail.formsConfig.items
292
+ ) {
293
+ this.mergeContainerItems(
294
+ localDetail.formsConfig.items,
295
+ serverDetail.formsConfig.items
296
+ );
297
+ }
298
+
299
+ // ✅ billDetailConfig
300
+ if (
301
+ localDetail.billDetailConfig.items &&
302
+ serverDetail.billDetailConfig.items
303
+ ) {
304
+ this.mergeContainerItems(
305
+ localDetail.billDetailConfig.items,
306
+ serverDetail.billDetailConfig.items
307
+ );
308
+ }
309
+ },
310
+
311
+ mergeContainerItems(localContainers, serverContainers) {
312
+
313
+ const containerMap = this.buildItemMap(localContainers);
314
+
315
+ serverContainers.forEach(serverContainer => {
316
+
317
+ const localContainer = containerMap.get(serverContainer.name);
318
+ if (!localContainer) {
319
+ console.log('2 没有配置localcontainer')
320
+ return;
321
+ }
322
+
323
+ // ✅ 合并容器自身属性
324
+ Object.assign(localContainer, serverContainer);
325
+
326
+ // ✅ 如果有子字段
327
+ if (
328
+ Array.isArray(localContainer.items) &&
329
+ Array.isArray(serverContainer.items)
330
+ ) {
331
+ this.mergeFlatItems(
332
+ localContainer.items,
333
+ serverContainer.items
334
+ );
335
+ }
336
+ });
337
+ },
338
+
339
+ mergeFlatItems(localItems, serverItems) {
340
+ const fieldMap = this.buildItemMap(localItems);
341
+
342
+ serverItems.forEach(serverItem => {
343
+ const localItem = fieldMap.get(serverItem.name);
344
+ console.log(serverItem.name, localItem)
345
+ if (localItem) {
346
+ console.log('合并前', localItem)
347
+ Object.assign(localItem, serverItem);
348
+ console.log('merge后', JSON.stringify(this.uiconfig))
349
+ this.uiconfig = Object.assign({}, this.uiconfig);
350
+ }
351
+ });
352
+ },
353
+
354
+ buildItemMap(items, map = new Map()) {
355
+ if (!Array.isArray(items)) return map;
356
+
357
+ items.forEach(item => {
358
+ if (!item) {
359
+ console.log('3 没有配置数据')
360
+ return;
361
+ }
362
+
363
+ if (item.name) {
364
+ map.set(item.name, item);
365
+ }
366
+
367
+ if (Array.isArray(item.items)) {
368
+ this.buildItemMap(item.items, map);
369
+ }
370
+ });
371
+
372
+ return map;
373
+ },
374
+
222
375
  getCurlAnchorData() {
223
376
  let tmp = [];
224
377
  this.anchorData.forEach(el => {
@@ -460,7 +460,7 @@ export default {
460
460
  this.$refs.form.setReadOnly(true);
461
461
  let temp = this.$refs.form.getData();
462
462
  this.treeSeletedNode =[temp];
463
- //this.initTree(true);
463
+ // this.initTree(true);
464
464
  this.$refs.tree.updateNode(temp,'U');
465
465
  if (!this.showTree) {
466
466
  this.$refs.grid.refurbish();
@@ -1,52 +1,297 @@
1
+ <template>
2
+ <Tree
3
+ ref="tree"
4
+ :data="innerData"
5
+ v-bind="$attrs"
6
+ >
7
+ <template #title="slotProps">
8
+ <component :is="{ render: () => renderWrapper(slotProps) }" />
9
+ </template>
10
+ </Tree>
11
+ </template>
12
+
1
13
  <script>
2
- import { h } from 'vue'
3
- import { Tree } from 'view-ui-plus'
14
+ import { h } from "vue"
15
+ import { Tree } from "view-ui-plus"
4
16
 
5
17
  export default {
6
- name: 'CompatTree',
7
18
 
8
- components: {
9
- Tree
10
- },
19
+ name: "CompatTree",
20
+
21
+ components: { Tree },
11
22
 
12
23
  props: {
24
+
13
25
  data: {
14
26
  type: Array,
15
- required: true
27
+ default: () => []
16
28
  },
29
+
17
30
  render: {
18
31
  type: Function,
19
32
  default: null
20
33
  }
34
+
35
+ },
36
+
37
+
38
+ data() {
39
+
40
+ return {
41
+
42
+ innerData: []
43
+
44
+ }
45
+
46
+ },
47
+
48
+ watch: {
49
+
50
+ // ⚠️ 不使用 deep watch,否则树结构会卡死
51
+ data: {
52
+
53
+ immediate: true,
54
+
55
+ handler(val) {
56
+
57
+ if (Array.isArray(val)) {
58
+ console.log("watch data triggered")
59
+ // 复制引用,避免父子互相影响
60
+ this.innerData = [...val]
61
+
62
+ } else {
63
+
64
+ this.innerData = []
65
+
66
+ }
67
+
68
+ }
69
+
70
+ }
71
+
72
+ },
73
+
74
+ computed: {
75
+
76
+ /**
77
+ * Vue2 Tree flatState 兼容
78
+ */
79
+ flatState() {
80
+
81
+ const list = []
82
+ console.log("flatState computing")
83
+ const walk = (nodes) => {
84
+
85
+ if (!Array.isArray(nodes)) return
86
+
87
+ for (const n of nodes) {
88
+
89
+ list.push({ node: n })
90
+
91
+ if (Array.isArray(n.children)) {
92
+
93
+ walk(n.children)
94
+
95
+ }
96
+
97
+ }
98
+
99
+ }
100
+
101
+ walk(this.innerData)
102
+
103
+ return list
104
+
105
+ }
106
+
21
107
  },
22
108
 
23
109
  methods: {
24
110
 
25
- // 👇 renderWrapper 就放在这里(methods 里)
111
+ /**
112
+ * Vue2 render(h) 兼容
113
+ */
26
114
  renderWrapper(slotProps) {
115
+
27
116
  const nodeRender =
28
117
  slotProps.data.render || this.render
29
118
 
30
119
  if (!nodeRender) {
120
+
31
121
  return slotProps.data.title
122
+
32
123
  }
33
124
 
34
- return nodeRender(h, slotProps)
125
+ return nodeRender(h, {
126
+ root: slotProps.root,
127
+ node: slotProps.node,
128
+ data: slotProps.data
129
+ })
130
+
131
+ },
132
+
133
+ /**
134
+ * 获取选中节点
135
+ */
136
+ getSelectedNodes() {
137
+
138
+ return this.$refs.tree?.getSelectedNodes?.() || []
139
+
140
+ },
141
+
142
+ /**
143
+ * 获取checkbox节点
144
+ */
145
+ getCheckedNodes() {
146
+
147
+ return this.$refs.tree?.getCheckedNodes?.() || []
148
+
149
+ },
150
+
151
+ /**
152
+ * 全部展开
153
+ */
154
+ expandAll() {
155
+
156
+ this.$refs.tree?.expandAll?.()
157
+
158
+ },
159
+
160
+ /**
161
+ * 全部收起
162
+ */
163
+ collapseAll() {
164
+
165
+ this.$refs.tree?.collapseAll?.()
166
+
167
+ },
168
+
169
+ /**
170
+ * 设置树数据
171
+ */
172
+ setData(data) {
173
+
174
+ this.innerData =
175
+ Array.isArray(data)
176
+ ? [...data]
177
+ : []
178
+
179
+
180
+ },
181
+
182
+ /**
183
+ * 刷新树
184
+ */
185
+ refurbish() {
186
+
187
+ const tmp = [...this.innerData]
188
+
189
+ this.innerData = []
190
+
191
+ this.$nextTick(() => {
192
+
193
+ this.innerData = tmp
194
+
195
+ })
196
+
197
+ },
198
+
199
+ /**
200
+ * 获取root节点
201
+ */
202
+ getRootNodes() {
203
+
204
+ return this.innerData
205
+
206
+ },
207
+
208
+ /**
209
+ * 更新节点
210
+ */
211
+ updateNode(data, flag) {
212
+
213
+ const idField = "id"
214
+ console.log("updateNode called", data, flag)
215
+ const findNode = (list, id) => {
216
+
217
+ for (const node of list) {
218
+
219
+ if (node[idField] === id) {
220
+
221
+ return node
222
+
223
+ }
224
+
225
+ if (Array.isArray(node.children)) {
226
+
227
+ const res =
228
+ findNode(node.children, id)
229
+
230
+ if (res) return res
231
+
232
+ }
233
+
234
+ }
235
+
236
+ return null
237
+
238
+ }
239
+
240
+ if (flag === "U") {
241
+
242
+ const node =
243
+ findNode(this.innerData, data[idField])
244
+
245
+ if (node) {
246
+
247
+ Object.assign(node, data)
248
+
249
+ }
250
+
251
+ }
252
+
253
+ if (flag === "D") {
254
+
255
+ const removeNode = (list, id) => {
256
+
257
+ const index =
258
+ list.findIndex(
259
+ n => n[idField] === id
260
+ )
261
+
262
+ if (index > -1) {
263
+
264
+ list.splice(index, 1)
265
+
266
+ return true
267
+
268
+ }
269
+
270
+ for (const n of list) {
271
+
272
+ if (
273
+ Array.isArray(n.children) &&
274
+ removeNode(n.children, id)
275
+ ) {
276
+
277
+ return true
278
+
279
+ }
280
+
281
+ }
282
+
283
+ return false
284
+
285
+ }
286
+
287
+ removeNode(this.innerData, data[idField])
288
+
289
+ }
290
+
291
+
35
292
  }
36
293
 
37
294
  }
295
+
38
296
  }
39
297
  </script>
40
-
41
- <template>
42
- <Tree :data="data" selectable>
43
- <template #title="slotProps">
44
- <!-- 这里调用 renderWrapper -->
45
- <component
46
- :is="{
47
- render: () => renderWrapper(slotProps)
48
- }"
49
- />
50
- </template>
51
- </Tree>
52
- </template>