lw-cdp-ui 1.2.32 → 1.2.34

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.
@@ -20,6 +20,7 @@
20
20
  <nodeEdit :lf="logicFlow"
21
21
  :drawerShow="drawerShow"
22
22
  :nodeData="clickNode"
23
+ :nodesDataConfig="nodesDataConfig"
23
24
  @onClose="nodeEditClose" />
24
25
  </template>
25
26
 
@@ -91,24 +92,15 @@ export default {
91
92
  return []
92
93
  }
93
94
  },
94
- /**
95
- * 节点配置初始化数据
96
- */
97
- nodeDatas: {
98
- type: Object,
99
- default: () => {
100
- return nodeDatas
101
- }
102
- },
103
95
  /**
104
96
  * 节点配置
105
97
  */
106
- configNodesList: {
107
- type: Object,
108
- default: () => {
109
- return configNodesList
110
- }
111
- },
98
+ // configNodesList: {
99
+ // type: Object,
100
+ // default: () => {
101
+ // return configNodesList
102
+ // }
103
+ // },
112
104
  /**
113
105
  * 是否显示默认节点
114
106
  */
@@ -130,6 +122,26 @@ export default {
130
122
  type: Array,
131
123
  default: []
132
124
  },
125
+ /**
126
+ * 节点数据配置
127
+ * 对应的就是nodeDatas目录下的数据结构
128
+ * source: { // 节点名
129
+ formConfig: { // 表单配置
130
+ formItems: [{ // 表单项配置,写你要覆盖的参数
131
+ name: 'from', // name 指定你要覆盖的名称
132
+ component: 'select',
133
+ options: {
134
+ items: [{ label: '订单', value: 'order' }, { label: '会员', value: 'member' }],
135
+ placeholder: '请输入节点名称'
136
+ },
137
+ }]
138
+ }
139
+ }
140
+ */
141
+ nodesDataConfig: {
142
+ type: Object,
143
+ default: {}
144
+ },
133
145
  /**
134
146
  * apiNodes - 接口返回的节点数组,用于与内容节点合并。
135
147
  * @type {Array<Object>}
@@ -1,7 +1,5 @@
1
1
  <template>
2
- <lw-form-mini ref="dataFormRef"
3
- :config="config"
4
- v-model="dataForm">
2
+ <lw-form-mini ref="dataFormRef" :config="config" v-model="dataForm">
5
3
  <!-- 定时器 表单自定义部分 -->
6
4
  <template #dateCron>
7
5
  <lwCronSelect v-model="dataForm.cron" />
@@ -9,28 +7,30 @@
9
7
 
10
8
  <!-- et2l 表单自定义部分 -->
11
9
  <template #KeyableSource>
12
- <lwTableForm :config="base.configKeyableSource"
13
- v-model="dataForm.from" />
10
+ <lwTableForm :config="base.configKeyableSource" v-model="dataForm.from" />
14
11
  </template>
12
+
15
13
  <template #MapAction>
16
- <lwTableForm :config="base.configMapAction"
17
- v-model="dataForm.with">
18
- <template #sourceField="{row}">
19
- <el-input v-if="row.type == 'direct'"
20
- size="small"
21
- v-model="row.from"
22
- placeholder="来源字段" />
23
- <el-select v-else
24
- v-model="row.from"
25
- multiple
26
- filterable
27
- allow-create
28
- size="small"
29
- default-first-option
30
- :reserve-keyword="false"
31
- placeholder="来源字段"
32
- style="width: 100%">
33
- </el-select>
14
+ <lwTableForm :config="base.configMapAction" v-model="dataForm.with">
15
+ <template #sourceField="{ row }">
16
+ <el-input
17
+ v-if="row.type === 'direct'"
18
+ size="small"
19
+ v-model="row.from"
20
+ placeholder="来源字段"
21
+ />
22
+ <el-select
23
+ v-else
24
+ v-model="row.from"
25
+ multiple
26
+ filterable
27
+ allow-create
28
+ size="small"
29
+ default-first-option
30
+ :reserve-keyword="false"
31
+ placeholder="来源字段"
32
+ style="width: 100%"
33
+ />
34
34
  </template>
35
35
  </lwTableForm>
36
36
  </template>
@@ -40,111 +40,39 @@
40
40
  </template>
41
41
 
42
42
  <script>
43
- import nodeDatas from '../nodesData/index.js'
44
43
  export default {
45
- name: 'basicSettings',
46
- data() {
47
- return {
48
- dataForm: {},
49
- ...nodeDatas
50
- }
51
- },
44
+ name: "BasicSettings",
52
45
  props: {
53
46
  modelValue: {
54
47
  type: Object,
55
- default: () => {
56
- return {}
57
- }
48
+ default: () => ({}),
58
49
  },
59
- lf: {
50
+ config: {
60
51
  type: Object,
61
- default: () => { }
52
+ default: () => ({}),
62
53
  },
63
- type: {
64
- type: String,
65
- default: ''
66
- }
54
+ },
55
+ data() {
56
+ return {
57
+ dataForm: {},
58
+ };
67
59
  },
68
60
  watch: {
69
61
  modelValue: {
70
62
  handler(val) {
71
63
  if (val) {
72
- this.dataForm = val
64
+ this.dataForm = val;
73
65
  }
74
-
75
66
  },
76
67
  immediate: true,
77
- deep: true
68
+ deep: true,
78
69
  },
79
70
  dataForm: {
80
- handler(val, old) {
81
- if (Object.keys(old).length > 0) {
82
- this.$emit('update:modelValue', val)
83
- }
84
-
71
+ handler(val, oldVal) {
72
+ this.$emit("update:modelValue", val)
85
73
  },
86
- deep: true
87
- }
88
- },
89
- computed: {
90
- config() {
91
- let config = {
92
- labelWidth: '70px',
93
- labelPosition: 'top',
94
- formItems: [
95
- {
96
- label: '节点名称',
97
- name: 'name',
98
- value: '',
99
- component: 'input',
100
- options: {
101
- placeholder: '请输入节点名称',
102
- },
103
- span: 24
104
- }
105
- ]
106
- }
107
-
108
- // 拿到对应节点的表单配置
109
- let nodeConfig = nodeDatas[this.type]?.formConfig || {}
110
- // 复制数据 防止修改表单配置影响全局
111
- nodeConfig = JSON.parse(JSON.stringify(nodeConfig))
112
- if (nodeConfig?.labelWidth) {
113
- config.labelWidth = nodeConfig.labelWidth
114
- }
115
- if (nodeConfig?.labelPosition) {
116
- config.labelPosition = nodeConfig.labelPosition
117
- }
118
-
119
- // 处理需要接口的内容
120
- if (!this.$store.state[`lwFlow_${this.type}`]) {
121
- this.$store.state[`lwFlow_${this.type}`] = {}
122
- }
123
- nodeConfig?.formItems?.forEach(async item => {
124
- if (item?.options?.items) {
125
- if (item.api) {
126
- let items = await item.api(this.$http)
127
- item.options.items = items || []
128
- }
129
-
130
- // 全局化选项内容 用于回显数据
131
- if (item?.options?.name) {
132
- this.$store.state[`lwFlow_${this.type}`][`${item.name}.${item.options.name}`] = item?.options?.items || ''
133
- } else {
134
- this.$store.state[`lwFlow_${this.type}`][item.name] = item?.options?.items || ''
135
- }
136
- }
137
- })
138
-
139
- if (nodeConfig?.formItems) {
140
- config.formItems = nodeConfig.formItems
141
- }
142
-
143
- return config
144
- }
74
+ deep: true,
75
+ },
145
76
  },
146
- methods: {
147
- }
148
- }
149
-
150
- </script>
77
+ };
78
+ </script>
@@ -34,13 +34,11 @@
34
34
  </template>
35
35
 
36
36
  <script>
37
- import nodeDatas from '../nodesData/index.js'
38
37
  export default {
39
38
  name: 'basicSettings',
40
39
  data() {
41
40
  return {
42
41
  dataForm: {},
43
- ...nodeDatas,
44
42
  behaviorIdOptions: [],
45
43
  dataModelFields: [],
46
44
  }
@@ -52,14 +50,10 @@ export default {
52
50
  return {}
53
51
  }
54
52
  },
55
- lf: {
53
+ config: {
56
54
  type: Object,
57
- default: () => { }
55
+ default: () => ({}),
58
56
  },
59
- type: {
60
- type: String,
61
- default: ''
62
- }
63
57
  },
64
58
  watch: {
65
59
  modelValue: {
@@ -82,61 +76,6 @@ export default {
82
76
  deep: true
83
77
  }
84
78
  },
85
- computed: {
86
- config() {
87
- let config = {
88
- labelWidth: '70px',
89
- labelPosition: 'top',
90
- formItems: [
91
- {
92
- label: '节点名称',
93
- name: 'name',
94
- value: '',
95
- component: 'input',
96
- options: {
97
- placeholder: '请输入节点名称',
98
- },
99
- span: 24
100
- }
101
- ]
102
- }
103
-
104
- // 拿到对应节点的表单配置
105
- let nodeConfig = nodeDatas[this.type]?.formConfig || {}
106
- if (nodeConfig?.labelWidth) {
107
- config.labelWidth = nodeConfig.labelWidth
108
- }
109
- if (nodeConfig?.labelPosition) {
110
- config.labelPosition = nodeConfig.labelPosition
111
- }
112
-
113
- // 处理需要接口的内容
114
- if (!this.$store.state[`lwFlow_${this.type}`]) {
115
- this.$store.state[`lwFlow_${this.type}`] = {}
116
- }
117
- nodeConfig?.formItems?.forEach(async item => {
118
- if (item?.options?.items) {
119
- if (item.api) {
120
- let items = await item.api(this.$http)
121
- item.options.items = items || []
122
- }
123
-
124
- // 全局化选项内容 用于回显数据
125
- if (item?.options?.name) {
126
- this.$store.state[`lwFlow_${this.type}`][`${item.name}.${item.options.name}`] = item?.options?.items || ''
127
- } else {
128
- this.$store.state[`lwFlow_${this.type}`][item.name] = item?.options?.items || ''
129
- }
130
- }
131
- })
132
-
133
- if (nodeConfig?.formItems) {
134
- config.formItems = nodeConfig.formItems
135
- }
136
-
137
- return config
138
- }
139
- },
140
79
  methods: {
141
80
  // 获取事件列表
142
81
  async getBehaviorList() {
@@ -11,6 +11,9 @@
11
11
  accordion>
12
12
  <el-collapse-item title="基础信息"
13
13
  name="basicInfo">
14
+ <!-- 说明:
15
+ 此处如果对应的节点没有特别的处理直接使用 basicSettings 就可
16
+ 如果这个节点有特别的操作 请自定义节点组件 以防默认组件过于庞大-->
14
17
 
15
18
  <!-- 营销目标 -->
16
19
  <template v-if="['audience_receive'].includes(nodeData.type)">
@@ -22,21 +25,18 @@
22
25
  <template v-if="['event_receive'].includes(nodeData.type)">
23
26
  <eventReceive ref="dataFormRef"
24
27
  v-model="dataForm.properties.data"
25
- :type="nodeData.type"
26
- :lf="lf" />
28
+ :config="config" />
27
29
  </template>
28
30
  <template v-if="['sms'].includes(nodeData.type)">
29
31
  <sms ref="dataFormRef"
30
32
  v-model="dataForm.properties.data"
31
- :type="nodeData.type"
32
- :lf="lf" />
33
+ :config="config" />
33
34
  </template>
34
35
  <!-- 默认 -->
35
36
  <template v-else>
36
37
  <basicSettings ref="dataFormRef"
37
38
  v-model="dataForm.properties.data"
38
- :type="nodeData.type"
39
- :lf="lf" />
39
+ :config="config" />
40
40
  </template>
41
41
 
42
42
  </el-collapse-item>
@@ -67,6 +67,8 @@ import sms from './sms.vue'
67
67
  import basicSettings from './basicSettings.vue'
68
68
  import styleSettings from './styleSettings.vue'
69
69
 
70
+ import nodeDatas from '../nodesData/index.js'
71
+
70
72
  export default {
71
73
  name: 'drawerForm',
72
74
  components: {
@@ -78,6 +80,7 @@ export default {
78
80
  },
79
81
  props: {
80
82
  nodeData: { type: Object, default: () => { } },
83
+ nodesDataConfig: { type: Object, default: () => { } },
81
84
  lf: {
82
85
  type: Object,
83
86
  default: () => { }
@@ -98,6 +101,7 @@ export default {
98
101
  data() {
99
102
  return {
100
103
  activeName: 'basicInfo',
104
+ ...nodeDatas,
101
105
  dataForm: {
102
106
  text: { value: '' },
103
107
  properties: {
@@ -108,6 +112,155 @@ export default {
108
112
  isShow: false
109
113
  }
110
114
  },
115
+ computed: {
116
+ config() {
117
+
118
+ /**
119
+ * 深度合并两个对象
120
+ * @param {Object} target 基础对象
121
+ * @param {Object} source 覆盖的对象
122
+ * @returns {Object} 合并后的对象
123
+ */
124
+ function deepMerge(target, source) {
125
+ // 如果 target 不是对象,则直接返回 source(注意:这里假设 source 一定有意义)
126
+ if (typeof target !== 'object' || target === null) {
127
+ return source;
128
+ }
129
+
130
+ // 遍历 source 的每个属性
131
+ for (const key in source) {
132
+ if (source.hasOwnProperty(key)) {
133
+ const sourceValue = source[key];
134
+ const targetValue = target[key];
135
+
136
+ // 特殊处理 formItems 数组
137
+ if (key === 'formItems' && Array.isArray(sourceValue)) {
138
+ target[key] = mergeFormItems(targetValue, sourceValue);
139
+ } else if (Array.isArray(sourceValue)) {
140
+ // 非 formItems 数组直接覆盖(也可根据需要扩展其他数组的合并规则)
141
+ target[key] = sourceValue.slice();
142
+ } else if (typeof sourceValue === 'object' && sourceValue !== null) {
143
+ // 如果 target 中对应属性不是对象,则先置为空对象
144
+ if (typeof targetValue !== 'object' || targetValue === null) {
145
+ target[key] = {};
146
+ }
147
+ // 递归合并对象
148
+ target[key] = deepMerge(target[key], sourceValue);
149
+ } else {
150
+ // 基本数据类型直接覆盖
151
+ target[key] = sourceValue;
152
+ }
153
+
154
+ }
155
+ }
156
+ return target;
157
+ }
158
+
159
+ /**
160
+ * 对 formItems 数组进行合并
161
+ * @param {Array} baseItems 基础 formItems 数组(可能为空)
162
+ * @param {Array} overrideItems 覆盖的 formItems 数组
163
+ * @returns {Array} 合并后的 formItems 数组
164
+ */
165
+ function mergeFormItems(baseItems, overrideItems) {
166
+ // 如果基础数据不存在或不是数组,则初始化为空数组
167
+ if (!Array.isArray(baseItems)) {
168
+ baseItems = [];
169
+ }
170
+
171
+ // 遍历覆盖数组中的每一项
172
+ overrideItems.forEach(overrideItem => {
173
+ let matched = false;
174
+ // 遍历基础数组中所有 name 相同的项
175
+ baseItems.forEach((baseItem, index) => {
176
+ if (baseItem.name === overrideItem.name) {
177
+ // 如果覆盖项设置了 hideHandle,则只有在 hideHandle 值相同的情况下才进行合并
178
+ if (overrideItem.hasOwnProperty('hideHandle')) {
179
+ if (baseItem.hideHandle === overrideItem.hideHandle) {
180
+ baseItems[index] = deepMerge(baseItem, overrideItem);
181
+ matched = true;
182
+ }
183
+ } else {
184
+ // 如果没有设置 hideHandle,则覆盖所有 name 相同的项
185
+ baseItems[index] = deepMerge(baseItem, overrideItem);
186
+ matched = true;
187
+ }
188
+ }
189
+ });
190
+ // 如果没有找到匹配项,则直接添加新的项(深拷贝以防引用问题)
191
+ if (!matched) {
192
+ baseItems.push(JSON.parse(JSON.stringify(overrideItem)));
193
+ }
194
+ });
195
+
196
+ return baseItems;
197
+ }
198
+
199
+
200
+ // 默认配置
201
+ let config = {
202
+ labelWidth: '70px',
203
+ labelPosition: 'top',
204
+ formItems: [
205
+ {
206
+ label: '节点名称',
207
+ name: 'name',
208
+ value: '',
209
+ component: 'input',
210
+ options: {
211
+ placeholder: '请输入节点名称'
212
+ },
213
+ span: 24
214
+ }
215
+ ]
216
+ };
217
+
218
+ // 注意:基础数据以 nodeDatas 为主,节点配置(nodesDataConfig)覆盖其中的对应字段
219
+ let nodeDatasMerge = deepMerge(
220
+ nodeDatas,
221
+ this.nodesDataConfig
222
+ );
223
+
224
+ // 取出对应节点的表单配置
225
+ let nodeConfig = nodeDatasMerge[this.nodeData.type]?.formConfig || {};
226
+ // 深拷贝,避免直接修改全局配置
227
+ nodeConfig = JSON.parse(JSON.stringify(nodeConfig));
228
+
229
+ if (nodeConfig?.labelWidth) {
230
+ config.labelWidth = nodeConfig.labelWidth;
231
+ }
232
+ if (nodeConfig?.labelPosition) {
233
+ config.labelPosition = nodeConfig.labelPosition;
234
+ }
235
+
236
+ // 处理需要接口的内容
237
+ if (!this.$store.state[`lwFlow_${this.nodeData.type}`]) {
238
+ this.$store.state[`lwFlow_${this.nodeData.type}`] = {};
239
+ }
240
+ nodeConfig?.formItems?.forEach(async item => {
241
+ if (item?.options?.items) {
242
+ if (item.api) {
243
+ let items = await item.api(this.$http);
244
+ item.options.items = items || [];
245
+ }
246
+ // 全局化选项内容 用于回显数据
247
+ if (item?.options?.name) {
248
+ this.$store.state[`lwFlow_${this.nodeData.type}`][`${item.name}.${item.options.name}`] =
249
+ item?.options?.items || '';
250
+ } else {
251
+ this.$store.state[`lwFlow_${this.nodeData.type}`][item.name] =
252
+ item?.options?.items || '';
253
+ }
254
+ }
255
+ });
256
+
257
+ if (nodeConfig?.formItems) {
258
+ config.formItems = nodeConfig.formItems;
259
+ }
260
+ return config;
261
+ }
262
+
263
+ },
111
264
  methods: {
112
265
  async onSubmit() {
113
266
  await this.$refs.dataFormRef.$refs.dataFormRef.validate();
@@ -1,7 +1,7 @@
1
1
  <template>
2
2
  <lw-form-mini ref="dataFormRef"
3
- :config="config"
4
- v-model="dataForm">
3
+ :config="config"
4
+ v-model="dataForm">
5
5
  <template #capabilityIdSelect>
6
6
  <el-select v-model="dataForm.capabilityId"
7
7
  filterable
@@ -25,13 +25,11 @@
25
25
  </template>
26
26
 
27
27
  <script>
28
- import nodeDatas from '../nodesData/index.js'
29
28
  export default {
30
29
  name: 'basicSettings',
31
30
  data() {
32
31
  return {
33
32
  dataForm: {},
34
- ...nodeDatas,
35
33
  communicates: [],
36
34
  content: ''
37
35
  }
@@ -43,14 +41,10 @@ export default {
43
41
  return {}
44
42
  }
45
43
  },
46
- lf: {
44
+ config: {
47
45
  type: Object,
48
- default: () => { }
46
+ default: () => ({}),
49
47
  },
50
- type: {
51
- type: String,
52
- default: ''
53
- }
54
48
  },
55
49
  watch: {
56
50
  modelValue: {
@@ -73,61 +67,7 @@ export default {
73
67
  deep: true
74
68
  }
75
69
  },
76
- computed: {
77
- config() {
78
- let config = {
79
- labelWidth: '70px',
80
- labelPosition: 'top',
81
- formItems: [
82
- {
83
- label: '节点名称',
84
- name: 'name',
85
- value: '',
86
- component: 'input',
87
- options: {
88
- placeholder: '请输入节点名称',
89
- },
90
- span: 24
91
- }
92
- ]
93
- }
94
-
95
- // 拿到对应节点的表单配置
96
- let nodeConfig = nodeDatas[this.type]?.formConfig || {}
97
- if (nodeConfig?.labelWidth) {
98
- config.labelWidth = nodeConfig.labelWidth
99
- }
100
- if (nodeConfig?.labelPosition) {
101
- config.labelPosition = nodeConfig.labelPosition
102
- }
103
-
104
- // 处理需要接口的内容
105
- if (!this.$store.state[`lwFlow_${this.type}`]) {
106
- this.$store.state[`lwFlow_${this.type}`] = {}
107
- }
108
- nodeConfig?.formItems?.forEach(async item => {
109
- if (item?.options?.items) {
110
- if (item.api) {
111
- let items = await item.api(this.$http)
112
- item.options.items = items || []
113
- }
114
70
 
115
- // 全局化选项内容 用于回显数据
116
- if (item?.options?.name) {
117
- this.$store.state[`lwFlow_${this.type}`][`${item.name}.${item.options.name}`] = item?.options?.items || ''
118
- } else {
119
- this.$store.state[`lwFlow_${this.type}`][item.name] = item?.options?.items || ''
120
- }
121
- }
122
- })
123
-
124
- if (nodeConfig?.formItems) {
125
- config.formItems = nodeConfig.formItems
126
- }
127
-
128
- return config
129
- }
130
- },
131
71
  methods: {
132
72
  async getCommunicate() {
133
73
  const params = { fields: "name,budgetSetting", expression: "" };
@@ -73,6 +73,18 @@ export default {
73
73
  },
74
74
  rowKey: 'id',
75
75
  formItems: [
76
+
77
+ {
78
+ label: '来源字段',
79
+ name: 'from',
80
+ value: '',
81
+ minWidth: '80',
82
+ component: 'sourceField',
83
+ options: {
84
+ placeholder: '请输入'
85
+ },
86
+ rules: [{ required: true, message: '不能为空', trigger: 'blur' }]
87
+ },
76
88
  {
77
89
  label: '映射类型',
78
90
  name: 'type',
@@ -94,17 +106,6 @@ export default {
94
106
  },
95
107
  rules: [{ required: true, message: '不能为空', trigger: 'blur' }]
96
108
  },
97
- {
98
- label: '来源字段',
99
- name: 'from',
100
- value: '',
101
- minWidth: '80',
102
- component: 'sourceField',
103
- options: {
104
- placeholder: '请输入'
105
- },
106
- rules: [{ required: true, message: '不能为空', trigger: 'blur' }]
107
- },
108
109
  {
109
110
  label: '目标字段',
110
111
  name: 'into',