lw-cdp-ui 1.2.43 → 1.2.44

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.
@@ -21,7 +21,9 @@
21
21
  :drawerShow="drawerShow"
22
22
  :nodeData="clickNode"
23
23
  :nodesDataConfig="nodesDataConfig"
24
- @onClose="nodeEditClose" />
24
+ :tableFieldsList="tableFieldsList"
25
+ @onClose="nodeEditClose"
26
+ @changedFieldValue="changedFieldValue"/>
25
27
  </template>
26
28
 
27
29
  </div>
@@ -142,6 +144,11 @@ export default {
142
144
  type: Object,
143
145
  default: {}
144
146
  },
147
+ // 用于接受更改数据表后,对应的表字段信息,此值属于定制化设置所需字段时使用
148
+ tableFieldsList:{
149
+ type: Object,
150
+ default: {}
151
+ },
145
152
  /**
146
153
  * apiNodes - 接口返回的节点数组,用于与内容节点合并。
147
154
  * @type {Array<Object>}
@@ -617,9 +624,14 @@ export default {
617
624
  }
618
625
  }
619
626
  return Object.keys(errorNodes).length === 0;
620
- }
627
+ },
621
628
 
629
+ changedFieldValue(val){
630
+ this.$emit('changedFieldValue',val)
631
+ }
622
632
  },
633
+
634
+
623
635
  }
624
636
  </script>
625
637
 
@@ -1,7 +1,8 @@
1
1
  <template>
2
2
  <lw-form-mini ref="dataFormRef"
3
3
  :config="config"
4
- v-model="dataForm">
4
+ v-model="dataForm"
5
+ @changedFieldValue="changedFieldValue">
5
6
  <!-- 定时器 表单自定义部分 -->
6
7
  <template #dateCron>
7
8
  <lwCronSelect v-model="dataForm.cron" />
@@ -34,9 +35,40 @@
34
35
  </template>
35
36
  </lwTableForm>
36
37
  </template>
37
-
38
+ <!-- 所需字段 自定义设置 -->
39
+ <template #cols>
40
+ <div style="width: 100%;display: flex;">
41
+ <el-input v-model="dataForm.cols" placeholder="来源字段" />
42
+ <el-button type="primary" style="margin-left:5px ;" @click="openFieldChoice">选择字段</el-button>
43
+ </div>
44
+ </template>
38
45
  <span></span>
39
46
  </lw-form-mini>
47
+
48
+ <!-- 字段选择弹框 -->
49
+ <el-dialog
50
+ v-model="dialogVisible"
51
+ title="字段选择"
52
+ width="500"
53
+ :before-close="handleClose"
54
+ >
55
+ <el-table :data="tableFieldsList?.from || []"
56
+ row-key="name"
57
+ @selection-change="handleSelectionChange">
58
+ <el-table-column type="selection" width="55" />
59
+ <el-table-column property="name" label="id" width="150" />
60
+ <el-table-column property="aliasName" label="名称" width="200" />
61
+ <el-table-column property="type" label="类型" />
62
+ </el-table>
63
+ <template #footer>
64
+ <div class="dialog-footer">
65
+ <el-button @click="cancel">取消</el-button>
66
+ <el-button type="primary" @click="confirm">
67
+ 确认
68
+ </el-button>
69
+ </div>
70
+ </template>
71
+ </el-dialog>
40
72
  </template>
41
73
 
42
74
  <script>
@@ -44,6 +76,14 @@ import nodeDatas from '../nodesData/index.js'
44
76
  export default {
45
77
  name: "BasicSettings",
46
78
  props: {
79
+ nodeData: {
80
+ type: Object,
81
+ default: () => { }
82
+ },
83
+ tableFieldsList: {
84
+ type: Object,
85
+ default: () => { }
86
+ },
47
87
  modelValue: {
48
88
  type: Object,
49
89
  default: () => ({}),
@@ -57,8 +97,35 @@ export default {
57
97
  return {
58
98
  ...nodeDatas,
59
99
  dataForm: {},
100
+ dialogVisible:false,
101
+ multipleSelection:[]
60
102
  };
61
103
  },
104
+ methods:{
105
+ changedFieldValue(val){
106
+ this.$emit('changedFieldValue',val)
107
+ },
108
+ openFieldChoice(){
109
+ this.dialogVisible = true
110
+ },
111
+ handleSelectionChange(val){
112
+ this.multipleSelection = val
113
+ },
114
+ cancel(){
115
+ this.dialogVisible = false
116
+ this.multipleSelection = this.dataForm.cols.split(',')
117
+ },
118
+ confirm(){
119
+ this.dialogVisible = false
120
+ if(!this.dataForm.cols)this.dataForm.cols = ''
121
+ const idsInMultipleSelection = []
122
+ this.multipleSelection.map(it=>{
123
+ idsInMultipleSelection.push(it.name)
124
+ })
125
+ this.dataForm.cols = `${this.dataForm.cols}${this.dataForm.cols===''?'':','}${[...new Set(idsInMultipleSelection)].join(',')}`
126
+ this.dataForm.cols = [...new Set(this.dataForm.cols.split(','))].join(',')
127
+ }
128
+ },
62
129
  watch: {
63
130
  modelValue: {
64
131
  handler(val) {
@@ -4,13 +4,22 @@
4
4
  direction="rtl"
5
5
  :append-to-body="true"
6
6
  :size="600"
7
- :before-close="close">
7
+ :before-close="close"
8
+ >
8
9
  <div v-if="isShow"
9
10
  class="drawer-form">
10
11
  <el-collapse v-model="activeName"
11
12
  accordion>
12
13
  <el-collapse-item title="基础信息"
13
14
  name="basicInfo">
15
+ <!-- 基础信息 -->
16
+ <basicSettings ref="dataFormRef"
17
+ v-model="dataForm.properties.data"
18
+ :config="basicConfig"
19
+ @changedFieldValue="changedFieldValue"/>
20
+ </el-collapse-item>
21
+ <el-collapse-item title="节点信息"
22
+ name="nodeInfo">
14
23
  <!-- 说明:
15
24
  此处如果对应的节点没有特别的处理直接使用 basicSettings 就可
16
25
  如果这个节点有特别的操作 请自定义节点组件 以防默认组件过于庞大-->
@@ -36,10 +45,14 @@
36
45
  <template v-else>
37
46
  <basicSettings ref="dataFormRef"
38
47
  v-model="dataForm.properties.data"
39
- :config="config" />
48
+ :config="config"
49
+ :nodeData="nodeData"
50
+ :tableFieldsList="tableFieldsList"
51
+ @changedFieldValue="changedFieldValue"/>
40
52
  </template>
41
53
 
42
54
  </el-collapse-item>
55
+
43
56
  <el-collapse-item title="样式设置"
44
57
  name="styleSettings">
45
58
  <!-- 基础设置 -->
@@ -81,6 +94,7 @@ export default {
81
94
  props: {
82
95
  nodeData: { type: Object, default: () => { } },
83
96
  nodesDataConfig: { type: Object, default: () => { } },
97
+ tableFieldsList: { type: Object, default: () => { } },
84
98
  lf: {
85
99
  type: Object,
86
100
  default: () => { }
@@ -109,7 +123,8 @@ export default {
109
123
  style: {},
110
124
  }
111
125
  },
112
- isShow: false
126
+ isShow: false,
127
+
113
128
  }
114
129
  },
115
130
  computed: {
@@ -258,10 +273,190 @@ export default {
258
273
  config.formItems = nodeConfig.formItems;
259
274
  }
260
275
  return config;
261
- }
276
+ },
277
+ basicConfig() {
278
+
279
+ /**
280
+ * 深度合并两个对象
281
+ * @param {Object} target 基础对象
282
+ * @param {Object} source 覆盖的对象
283
+ * @returns {Object} 合并后的对象
284
+ */
285
+ function deepMerge(target, source) {
286
+ // 如果 target 不是对象,则直接返回 source(注意:这里假设 source 一定有意义)
287
+ if (typeof target !== 'object' || target === null) {
288
+ return source;
289
+ }
290
+
291
+ // 遍历 source 的每个属性
292
+ for (const key in source) {
293
+ if (source.hasOwnProperty(key)) {
294
+ const sourceValue = source[key];
295
+ const targetValue = target[key];
296
+
297
+ // 特殊处理 formItems 数组
298
+ if (key === 'formItems' && Array.isArray(sourceValue)) {
299
+ target[key] = mergeFormItems(targetValue, sourceValue);
300
+ } else if (Array.isArray(sourceValue)) {
301
+ // 非 formItems 数组直接覆盖(也可根据需要扩展其他数组的合并规则)
302
+ target[key] = sourceValue.slice();
303
+ } else if (typeof sourceValue === 'object' && sourceValue !== null) {
304
+ // 如果 target 中对应属性不是对象,则先置为空对象
305
+ if (typeof targetValue !== 'object' || targetValue === null) {
306
+ target[key] = {};
307
+ }
308
+ // 递归合并对象
309
+ target[key] = deepMerge(target[key], sourceValue);
310
+ } else {
311
+ // 基本数据类型直接覆盖
312
+ target[key] = sourceValue;
313
+ }
314
+
315
+ }
316
+ }
317
+ return target;
318
+ }
319
+
320
+ /**
321
+ * 对 formItems 数组进行合并
322
+ * @param {Array} baseItems 基础 formItems 数组(可能为空)
323
+ * @param {Array} overrideItems 覆盖的 formItems 数组
324
+ * @returns {Array} 合并后的 formItems 数组
325
+ */
326
+ function mergeFormItems(baseItems, overrideItems) {
327
+ // 如果基础数据不存在或不是数组,则初始化为空数组
328
+ if (!Array.isArray(baseItems)) {
329
+ baseItems = [];
330
+ }
331
+
332
+ // 遍历覆盖数组中的每一项
333
+ overrideItems.forEach(overrideItem => {
334
+ let matched = false;
335
+ // 遍历基础数组中所有 name 相同的项
336
+ baseItems.forEach((baseItem, index) => {
337
+ if (baseItem.name === overrideItem.name) {
338
+ // 如果覆盖项设置了 hideHandle,则只有在 hideHandle 值相同的情况下才进行合并
339
+ if (overrideItem.hasOwnProperty('hideHandle')) {
340
+ if (baseItem.hideHandle === overrideItem.hideHandle) {
341
+ baseItems[index] = deepMerge(baseItem, overrideItem);
342
+ matched = true;
343
+ }
344
+ } else {
345
+ // 如果没有设置 hideHandle,则覆盖所有 name 相同的项
346
+ baseItems[index] = deepMerge(baseItem, overrideItem);
347
+ matched = true;
348
+ }
349
+ }
350
+ });
351
+ // 如果没有找到匹配项,则直接添加新的项(深拷贝以防引用问题)
352
+ if (!matched) {
353
+ baseItems.push(JSON.parse(JSON.stringify(overrideItem)));
354
+ }
355
+ });
356
+
357
+ return baseItems;
358
+ }
359
+
360
+
361
+ // 默认配置
362
+ let config={
363
+ labelWidth: '70px',
364
+ labelPosition: 'top',
365
+ formItems: [
366
+ {
367
+ label: '节点名称',
368
+ name: 'name',
369
+ value: '',
370
+ component: 'input',
371
+ options: {
372
+ placeholder: '请输入节点名称'
373
+ },
374
+ span: 24
375
+ },
376
+ {
377
+ label: '节点并行度',
378
+ name: 'para',
379
+ value: '',
380
+ component: 'number',
381
+ options: {
382
+ placeholder: '请输入节点并行度'
383
+ },
384
+ span: 24
385
+ },
386
+ {
387
+ label: '节点标签',
388
+ name: 'tags',
389
+ value: '',
390
+ component: 'tags',
391
+ // options: {
392
+ // placeholder: '请输入节点标签'
393
+ // },
394
+ span: 24
395
+ },
396
+
397
+ {
398
+ label: '描述信息',
399
+ name: 'desp',
400
+ value: '',
401
+ component: 'input',
402
+ options: {
403
+ placeholder: '请输入描述信息'
404
+ },
405
+ span: 24
406
+ },
407
+ ]
408
+ }
409
+
410
+ // 注意:基础数据以 nodeDatas 为主,节点配置(nodesDataConfig)覆盖其中的对应字段
411
+ let nodeDatasMerge = deepMerge(
412
+ nodeDatas,
413
+ this.nodesDataConfig
414
+ );
415
+
416
+ // 取出对应节点的表单配置
417
+ let nodeConfig = nodeDatasMerge?.basicNode?.formConfig || {};
418
+ // 深拷贝,避免直接修改全局配置
419
+ nodeConfig = JSON.parse(JSON.stringify(nodeConfig));
420
+
421
+ if (nodeConfig?.labelWidth) {
422
+ config.labelWidth = nodeConfig.labelWidth;
423
+ }
424
+ if (nodeConfig?.labelPosition) {
425
+ config.labelPosition = nodeConfig.labelPosition;
426
+ }
427
+
428
+ // 处理需要接口的内容
429
+ if (!this.$store.state[`lwFlow_${this.nodeData.type}`]) {
430
+ this.$store.state[`lwFlow_${this.nodeData.type}`] = {};
431
+ }
432
+ nodeConfig?.formItems?.forEach(async item => {
433
+ if (item?.options?.items) {
434
+ if (item.api) {
435
+ let items = await item.api(this.$http);
436
+ item.options.items = items || [];
437
+ }
438
+ // 全局化选项内容 用于回显数据
439
+ if (item?.options?.name) {
440
+ this.$store.state[`lwFlow_${this.nodeData.type}`][`${item.name}.${item.options.name}`] =
441
+ item?.options?.items || '';
442
+ } else {
443
+ this.$store.state[`lwFlow_${this.nodeData.type}`][item.name] =
444
+ item?.options?.items || '';
445
+ }
446
+ }
447
+ });
448
+
449
+ if (nodeConfig?.formItems) {
450
+ config.formItems = nodeConfig.formItems;
451
+ }
452
+ return config;
453
+ },
262
454
 
263
455
  },
264
456
  methods: {
457
+ changedFieldValue(val){
458
+ this.$emit('changedFieldValue',val)
459
+ },
265
460
  async onSubmit() {
266
461
  await this.$refs.dataFormRef.$refs.dataFormRef.validate();
267
462
  const { id } = this.dataForm
@@ -0,0 +1,82 @@
1
+ /**
2
+ * ET2L数据读取源节点 SOURCE 配置数据
3
+ */
4
+
5
+ export default {
6
+ // 暂无显示需求
7
+ nodeHtml: [],
8
+ // 目标节点校验
9
+ targetRules: [
10
+ {
11
+ message: '目标节点只允许一个上级连接',
12
+ validate: (sourceNode, targetNode, sourceAnchor, targetAnchor) => {
13
+ let { edges } = targetNode.graphModel
14
+ let { id } = targetNode
15
+
16
+ let number = [...edges].filter((item) => {
17
+ let { targetNodeId } = { ...item }
18
+ return targetNodeId == id
19
+ })
20
+ return number.length < 1
21
+ }
22
+ }
23
+ ],
24
+ // 表单内容
25
+ formConfig:{
26
+ labelWidth: '70px',
27
+ labelPosition: 'top',
28
+ formItems: [
29
+ {
30
+ label: '节点名称',
31
+ name: 'name',
32
+ value: '',
33
+ component: 'input',
34
+ options: {
35
+ placeholder: '请输入节点名称'
36
+ },
37
+ span: 24
38
+ },
39
+ {
40
+ label: '节点并行度',
41
+ name: 'para',
42
+ value: '',
43
+ component: 'number',
44
+ options: {
45
+ placeholder: '请输入节点并行度'
46
+ },
47
+ span: 24
48
+ },
49
+ {
50
+ label: '节点标签',
51
+ name: 'tags',
52
+ value: '',
53
+ component: 'tags',
54
+ // options: {
55
+ // placeholder: '请输入节点标签'
56
+ // },
57
+ span: 24
58
+ },
59
+
60
+ {
61
+ label: '描述信息',
62
+ name: 'desp',
63
+ value: '',
64
+ component: 'input',
65
+ options: {
66
+ placeholder: '请输入描述信息'
67
+ },
68
+ span: 24
69
+ },
70
+ {
71
+ label: '输出名称',
72
+ name: 'into',
73
+ value: '',
74
+ component: 'select',
75
+ options: {
76
+ placeholder: '请选择输出名称'
77
+ },
78
+ span: 24
79
+ }
80
+ ]
81
+ }
82
+ }
@@ -26,17 +26,6 @@ export default {
26
26
  labelWidth: '70px',
27
27
  labelPosition: 'top',
28
28
  formItems: [
29
- {
30
- label: '节点名称',
31
- name: 'name',
32
- value: '',
33
- component: 'input',
34
- options: {
35
- placeholder: '请输入节点名称'
36
- },
37
- span: 24,
38
- rules: [{ required: true, message: '不能为空', trigger: 'blur' }]
39
- },
40
29
  {
41
30
  label: '运行模式',
42
31
  name: 'mode',
@@ -64,65 +53,6 @@ export default {
64
53
  ]
65
54
  }
66
55
  },
67
- {
68
- label: '数据表名',
69
- name: 'from',
70
- value: '',
71
- component: 'input',
72
- options: {
73
- placeholder: '请输入数据表名'
74
- },
75
- tips: '非SQL模式必须填写',
76
- span: 24,
77
- hideHandle: '$.mode == "sql"',
78
- rules: [{ required: true, message: '不能为空', trigger: 'blur' }]
79
- },
80
- {
81
- label: '数据表名',
82
- name: 'from',
83
- value: '',
84
- component: 'input',
85
- options: {
86
- placeholder: '请输入数据表名'
87
- },
88
- tips: '非SQL模式必须填写',
89
- span: 24,
90
- hideHandle: '$.mode != "sql"'
91
- },
92
- {
93
- label: '所需字段',
94
- name: 'cols',
95
- value: '',
96
- component: 'input',
97
- options: {
98
- placeholder: '请输入所需字段'
99
- },
100
- tips: '多个字段采用逗号分隔,为空时选取所有字段,支持AS关键字。',
101
- span: 24
102
- },
103
- {
104
- label: '关联字段',
105
- name: 'with',
106
- value: '',
107
- component: 'input',
108
- options: {
109
- placeholder: '请输入关联字段'
110
- },
111
- span: 24,
112
- hideHandle: '$.mode != "expand" && $.mode != "collap"',
113
- rules: [{ required: true, message: '不能为空', trigger: 'blur' }]
114
- },
115
- {
116
- label: '关联字段',
117
- name: 'with',
118
- value: '',
119
- component: 'input',
120
- options: {
121
- placeholder: '请输入关联字段'
122
- },
123
- span: 24,
124
- hideHandle: '$.mode == "expand" || $.mode == "collap"'
125
- },
126
56
  {
127
57
  label: '折叠排序方式',
128
58
  name: 'sort',
@@ -157,27 +87,19 @@ export default {
157
87
  span: 24
158
88
  },
159
89
  {
160
- label: '输出名称',
161
- name: 'into',
90
+ label: '数据表名来源',
91
+ name: 'fromNameSource',
162
92
  value: '',
163
- component: 'input',
93
+ component: 'select',
164
94
  options: {
165
- placeholder: '请输入输出名称'
95
+ placeholder: '请输选择数据表名来源',
96
+ items:[
97
+ {value:'hive',label:'hive'},
98
+ {value:'lake',label:'lake'},
99
+ ]
166
100
  },
167
101
  span: 24,
168
- rules: [{ required: true, message: '不能为空', trigger: 'blur' }]
169
102
  },
170
- {
171
- label: '描述信息',
172
- name: 'desp',
173
- value: '',
174
- component: 'input',
175
- options: {
176
- type: 'textarea',
177
- placeholder: '请输入'
178
- },
179
- span: 24
180
- }
181
103
  ]
182
104
  }
183
105
  }
@@ -23,6 +23,7 @@ import timer from './datas/timer'
23
23
  import audience_receive from './datas/audienceReceive'
24
24
  import event_receive from './datas/eventReceive'
25
25
  import sms from './datas/sms'
26
+ import basicNode from './datas/basicNode'
26
27
 
27
28
  export default {
28
29
  base,
@@ -37,5 +38,6 @@ export default {
37
38
  timer,
38
39
  audience_receive,
39
40
  event_receive,
40
- sms
41
+ sms,
42
+ basicNode
41
43
  }
@@ -103,6 +103,7 @@
103
103
  :collapse-tags-tooltip="item?.options?.collapseTagsTooltip"
104
104
  :disabled="item?.options.disabled"
105
105
  filterable
106
+ @change="handlerSelectChange(item,objItem.value)"
106
107
  style="width: 100%;">
107
108
  <el-option v-for="option in item?.options.items"
108
109
  :key="option.value"
@@ -290,6 +291,16 @@ export default {
290
291
  },
291
292
  },
292
293
  methods: {
294
+ handlerSelectChange(item,val){
295
+ const res = {
296
+ changeField:item.name,
297
+ changeLabel:item.label,
298
+ changeValue:item.value,
299
+ }
300
+
301
+ this.$emit("changedFieldValue", res)
302
+
303
+ },
293
304
  flattenObject(obj, key, defaultValue = '') {
294
305
  if (!key || !obj) { return false }
295
306
  const keys = key.split('.'); // 将路径拆分成数组
@@ -55,7 +55,8 @@
55
55
  <FormItem v-else
56
56
  :item="item"
57
57
  :form="form"
58
- :index="index">
58
+ :index="index"
59
+ @changedFieldValue="changedFieldValue">
59
60
  <!-- 没有组件是component值 就是插槽名称 -->
60
61
  <template v-if="!['input', 'upload', 'checkbox', 'checkboxGroup', 'switch', 'select', 'treeSelect', 'cascader', 'date', 'number', 'radio', 'color', 'rate', 'slider','tags', 'divider'].includes(item.component)"
61
62
  v-slot:[item.component]>
@@ -329,6 +330,9 @@ export default {
329
330
  titleNameDividers.forEach(divider => {
330
331
  observer.observe(divider);
331
332
  });
333
+ },
334
+ changedFieldValue(val){
335
+ this.$emit("changedFieldValue", val)
332
336
  }
333
337
  }
334
338
  }
@@ -291,6 +291,7 @@ export default {
291
291
  //横向滚动
292
292
  scrollInit() {
293
293
  const scrollDiv = document.querySelector('.context-menu-list')
294
+ if (!scrollDiv) { return false }
294
295
  scrollDiv.addEventListener('mousewheel', handler, false) || scrollDiv.addEventListener("DOMMouseScroll", handler, false)
295
296
  function handler(event) {
296
297
  const detail = event.wheelDelta || event.detail;
@@ -364,6 +364,7 @@ export default {
364
364
  for (const key in param.data) {
365
365
  data.append(key, param.data[key]);
366
366
  }
367
+ console.log(apiObj)
367
368
  apiObj(data, {
368
369
  onUploadProgress: e => {
369
370
  this.file.percentage = parseInt(((e.loaded / e.total) * 100) | 0, 10)