lw-cdp-ui 1.1.16 → 1.1.18

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.
@@ -171,13 +171,13 @@ export default {
171
171
  */
172
172
  const changeCron = () => {
173
173
  emit('update:modelValue', showInput.value)
174
+ emit('change')
174
175
  }
175
176
 
176
177
  /**
177
178
  * 确定选择,生成最终的cron表达式
178
179
  */
179
180
  const changeOk = () => {
180
- console.log(setData.value.timeData)
181
181
  const time = setData.value.timeData ? setData.value.timeData.split(':') : ['*', '*', '*']
182
182
  dataList.value[0] = time[2] === "*" ? time[2] : parseInt(time[2], 10).toString()
183
183
  dataList.value[1] = time[1] === "*" ? time[1] : parseInt(time[1], 10).toString()
@@ -194,6 +194,7 @@ export default {
194
194
  showInput.value = `${dataList.value[0]} ${dataList.value[1]} ${dataList.value[2]} ${dataList.value[3]} ${dataList.value[4]} ${dataList.value[5]}`
195
195
 
196
196
  emit('update:modelValue', showInput.value)
197
+ emit('change')
197
198
  visible.value = false
198
199
  }
199
200
 
@@ -209,4 +210,9 @@ export default {
209
210
  }
210
211
  }
211
212
  }
212
- </script>
213
+ </script>
214
+ <style lang="scss" scoped>
215
+ .select-model{
216
+ display: flex;
217
+ }
218
+ </style>
@@ -47,7 +47,7 @@
47
47
 
48
48
  <el-tooltip class="box-item"
49
49
  effect="dark"
50
- :content="lf.extension.miniMap.isShow ? '查看缩略图' : '关闭缩略图'"
50
+ content="缩略图(点击展开,再次点击关闭)"
51
51
  placement="bottom-end">
52
52
  <el-button plain
53
53
  @click="showMiniMap"
@@ -64,8 +64,10 @@
64
64
  export default {
65
65
  name: 'lfControl',
66
66
  props: {
67
- lf: Object || String,
68
- catTurboData: Boolean
67
+ lf: {
68
+ type: Object,
69
+ default: () => { }
70
+ }
69
71
  },
70
72
  data() {
71
73
  return {
@@ -97,6 +99,7 @@ export default {
97
99
  reset() {
98
100
  this.$props.lf.resetZoom();
99
101
  this.$props.lf.resetTranslate();
102
+ this.$props.lf.translateCenter()
100
103
  },
101
104
  undo() {
102
105
  this.$props.lf.undo();
@@ -110,9 +113,6 @@ export default {
110
113
  catData() {
111
114
  this.$emit('catData');
112
115
  },
113
- catTurboData() {
114
- this.$emit('catTurboData');
115
- },
116
116
  showMiniMap() {
117
117
  const { lf } = this.$props;
118
118
  if (lf.extension.miniMap.isShow) {
@@ -1,7 +1,6 @@
1
1
  <template>
2
2
  <div class="node-panel">
3
- <el-collapse v-model="activeName"
4
- accordion>
3
+ <el-collapse accordion>
5
4
  <el-collapse-item v-for="item in nodeList"
6
5
  :title="item.title"
7
6
  :name="item.title">
@@ -26,14 +25,13 @@
26
25
  * 节点面板
27
26
  */
28
27
  export default {
29
- name: 'NodePanel',
28
+ name: 'lfNodePanel',
30
29
  props: {
31
30
  lf: Object,
32
31
  nodeList: Array,
33
32
  },
34
33
  methods: {
35
34
  dragNode(item) {
36
- console.log(item)
37
35
  this.$props.lf.dnd.startDrag({
38
36
  type: item.type,
39
37
  })
@@ -12,6 +12,13 @@
12
12
  v-if="logicFlow"
13
13
  :lf="logicFlow"
14
14
  :nodeList="nodeList" />
15
+
16
+ <!-- 属性编辑 -->
17
+ <nodeEdit :lf="logicFlow"
18
+ :drawerShow="drawerShow"
19
+ :nodeData="clickNode"
20
+ @onClose="nodeEditClose"/>
21
+
15
22
  </div>
16
23
 
17
24
  </template>
@@ -29,62 +36,113 @@ import lfNodePanel from './components/lfNodePanel.vue'
29
36
  // 自定义节点
30
37
  import basisStart from './nodes/basisStart'
31
38
  import basisEnd from './nodes/basisEnd'
39
+ import nodeCustom from './nodes/custom'
40
+
41
+ // 节点编辑
42
+ import nodeEdit from './nodeEdit/index.vue'
32
43
  export default {
33
44
  components: {
34
45
  lfControl,
35
- lfNodePanel
46
+ lfNodePanel,
47
+ nodeEdit
36
48
  },
37
49
  props: {
38
- modelvalue: {
50
+ /**
51
+ * 流程图的数据,包括节点和边的配置。
52
+ * - `nodes`:一个数组,包含流程图中的所有节点。每个节点都有唯一的`id`、类型(`type`)以及位置(`x`, `y`)。
53
+ * - `edges`:一个数组,描述了节点之间的连接关系。每条边都有类型(`type`)以及源节点(`sourceNodeId`)和目标节点(`targetNodeId`)的标识。
54
+ * - `nodes.properties` 节点数据配置
55
+ * - `nodes.properties.data` 节点自定义数据配置 默认: data: {name:'节点名称'}
56
+ * - `nodes.properties.style` 节点自定义样式,具体参数看\nodeEdit\basicSettings.vue
57
+ * @example
58
+ * ```javascript
59
+ * {
60
+ * nodes: [
61
+ * { id: '21', type: 'end', x: 100, y: 200, properties: { data: name: '结束' } },
62
+ * { id: '50', type: 'start', x: 300, y: 400 }
63
+ * ],
64
+ * edges: [
65
+ * { type: 'polyline', sourceNodeId: '50', targetNodeId: '21' }
66
+ * ]
67
+ * }
68
+ * ```
69
+ */
70
+ modelValue: {
39
71
  type: Object,
40
72
  default: () => {
41
- return {
42
- // 节点
43
- nodes: [
44
- {
45
- id: '21',
46
- type: 'rect',
47
- x: 100,
48
- y: 200,
49
- text: 'rect node',
50
- },
51
- {
52
- id: '50',
53
- type: 'circle',
54
- x: 300,
55
- y: 400,
56
- text: 'circle node',
57
- },
58
- ],
59
- // 边
60
- edges: [
61
- {
62
- type: 'polyline',
63
- sourceNodeId: '50',
64
- targetNodeId: '21',
65
- },
66
- ],
67
- }
73
+ return {}
68
74
  }
69
75
  },
70
76
  /**
71
- * apiNodes - 接口返回的节点的数组。请求到到将与内容节点合并。
72
- * @type {Array}
77
+ * 是否显示默认节点
78
+ */
79
+ showDefaultNode: {
80
+ type: Boolean,
81
+ default: true
82
+ },
83
+ /**
84
+ * apiNodes - 接口返回的节点数组,用于与内容节点合并。
85
+ * @type {Array<Object>}
73
86
  * @default []
87
+ * @property {string} name - 节点名称
88
+ * @property {string} category - 节点类别
89
+ * @property {number} index - 节点索引
90
+ * @property {number} groupIndex - 节点组索引
91
+ * @property {string} groupId - 节点组ID
92
+ * @property {string} groupName - 节点组名称
93
+ * @property {string} type - 节点类型
94
+ * @property {boolean} enabled - 节点是否启用
95
+ * @property {string} icon - 节点图标
96
+ * @property {string} themeColor - 节点主题颜色
97
+ * @property {string} background - 节点背景色
74
98
  */
75
99
  apiNodes: {
76
100
  type: Array,
77
101
  default: []
78
102
  },
79
103
  /**
80
- * 配置项对象,用于设置流程图的网格属性。
81
- * @property {Object} grid - 网格配置对象。
82
- * @property {number} grid.size - 网格大小,默认为10。
83
- * @property {boolean} grid.visible - 是否显示网格,默认为true。
84
- * @property {string} grid.type - 网格类型,默认为'mesh'。
85
- * @property {Object} grid.config - 网格配置详情。
86
- * @property {string} grid.config.color - 网格颜色,默认为'#f0f0f0'。
87
- * @property {number} grid.config.thickness - 网格线厚度,默认为0.5。
104
+ * 流程图初始化属性配置。
105
+ * @property {Object} grid - 网格配置对象,包含网格大小、是否显示、类型及详细配置。
106
+ * @property {HTMLElement} container - 图的DOM容器。
107
+ * @property {number} [width] - 画布宽度,默认使用容器宽度。
108
+ * @property {number} [height] - 画布高度,默认使用容器高度。
109
+ * @property {boolean|BackgroundConfig} [background=false] - 背景配置,默认无背景。
110
+ * @property {number|boolean|GridOptions} [grid=false] - 网格配置,false表示不开启网格。
111
+ * @property {boolean} [partial=false] - 是否开启局部渲染功能。
112
+ * @property {Keyboard.KeyboardDef} [keyboard] - 自定义键盘配置。
113
+ * @property {Partial<LogicFlow.Theme>} [style] - 样式配置。
114
+ * @property {EdgeType} [edgeType='polyline'] - 边的类型,默认为'polyline'。
115
+ * @property {boolean} [isSilentMode=false] - 是否仅浏览不可编辑模式。
116
+ * @property {boolean} [stopScrollGraph=false] - 是否禁止鼠标滚动移动画布。
117
+ * @property {boolean} [stopZoomGraph=false] - 是否禁止缩放画布。
118
+ * @property {boolean|string|[number, number, number, number]} [stopMoveGraph=false] - 是否禁止拖动画布。
119
+ * @property {boolean|Partial<AnimationConfig>} [animation] - 动画配置。
120
+ * @property {boolean} [history=true] - 是否开启历史记录功能。
121
+ * @property {string[]} [disabledPlugins] - 禁用加载的插件。
122
+ * @property {boolean} [snapline=true] - 是否启用节点辅助对齐线。
123
+ * @property {GuardsConfig} [guards] - 守卫函数配置。
124
+ * @property {string[]} [disabledTools] - 禁止启用的内置工具。
125
+ * @property {boolean} [adjustEdge=true] - 是否允许调整边。
126
+ * @property {boolean} [adjustEdgeStartAndEnd=false] - 是否允许拖动边的端点来调整连线。
127
+ * @property {boolean} [adjustNodePosition=true] - 是否允许拖动节点。
128
+ * @property {boolean} [hideAnchors=false] - 是否隐藏节点的锚点。
129
+ * @property {boolean} [outline=false] - 节点选择状态下外侧的选框是否展示。
130
+ * @property {boolean} [hoverOutline=true] - 鼠标hover时是否显示节点的外框。
131
+ * @property {boolean} [nodeSelectedOutline=true] - 节点被选中时是否显示节点的外框。
132
+ * @property {boolean} [edgeSelectedOutline=true] - 边被选中时是否显示边的外框。
133
+ * @property {boolean} [nodeTextEdit=true] - 允许节点文本编辑。
134
+ * @property {boolean} [edgeTextEdit=true] - 允许边文本编辑。
135
+ * @property {boolean} [textEdit=true] - 是否开启文本编辑。
136
+ * @property {boolean} [nodeTextDraggable=false] - 允许节点文本拖拽。
137
+ * @property {boolean} [edgeTextDraggable=false] - 允许边文本拖拽。
138
+ * @property {string} [multipleSelectKey] - 多选按键配置。
139
+ * @property {function} [idGenerator] - 自定义创建节点、连线时生成id规则。
140
+ * @property {EdgeGeneratorType} [edgeGenerator] - 连接节点及移动边时边的生成规则。
141
+ * @property {ExtensionConstructor[]} [plugins] - 加载的插件。
142
+ * @property {boolean} [autoExpand=true] - 节点拖动靠近画布边缘时是否自动扩充画布。
143
+ * @property {OverlapMode} [overlapMode] - 元素重合的堆叠模式。
144
+ * @property {function} [customTrajectory] - 自定义连线轨迹。
145
+ * @property {any} [pluginsOptions] - 插件初始化选项。
88
146
  */
89
147
  options: {
90
148
  type: Object,
@@ -105,9 +163,23 @@ export default {
105
163
  }
106
164
  }
107
165
  },
166
+ watch: {
167
+ modelValue: {
168
+ handler(val, old) {
169
+ // 第一次初始化
170
+ if (!old) {
171
+ this.init()
172
+ // this.logicFlow.renderRawData(val)
173
+ }
174
+ },
175
+ deep: true
176
+ }
177
+ },
108
178
  data() {
109
179
  return {
110
- logicFlow: null
180
+ logicFlow: null,
181
+ drawerShow: false,
182
+ clickNode: null,
111
183
  }
112
184
  },
113
185
  computed: {
@@ -115,7 +187,7 @@ export default {
115
187
  // 基础节点
116
188
  let baseList = [
117
189
  {
118
- title: '流程控制',
190
+ title: '基础流程',
119
191
  list: [
120
192
  {
121
193
  name: '开始',
@@ -143,8 +215,13 @@ export default {
143
215
  }
144
216
  list[item.groupName].list.push(item)
145
217
  })
146
- console.log(list)
147
- return Object.values(list).length > 0 ? Object.values(list) : baseList
218
+
219
+ if (this.showDefaultNode) {
220
+ baseList = [...baseList, ...Object.values(list)]
221
+ } else {
222
+ baseList = Object.values(list)
223
+ }
224
+ return baseList
148
225
  }
149
226
  },
150
227
  mounted() {
@@ -155,7 +232,7 @@ export default {
155
232
  * 初始化
156
233
  * 传入数据初始化、右键菜单初始化
157
234
  */
158
- init() {
235
+ async init() {
159
236
  this.logicFlow = new LogicFlow({
160
237
  container: this.$refs.container,
161
238
  // 注册组件
@@ -163,8 +240,9 @@ export default {
163
240
  ...this.options
164
241
  })
165
242
  this.initMenu()
166
- this.initNode()
167
- this.logicFlow.render(this.modelvalue)
243
+ await this.initNode()
244
+ this.logicFlow.render(this.modelValue)
245
+ this.bindEvent()
168
246
  // 内容移动到中心
169
247
  this.logicFlow.translateCenter()
170
248
  },
@@ -174,6 +252,7 @@ export default {
174
252
  initMenu() {
175
253
  let _this = this
176
254
  this.logicFlow.extension.menu.setMenuConfig({
255
+ // 节点
177
256
  nodeMenu: [
178
257
  {
179
258
  text: "删除",
@@ -184,10 +263,18 @@ export default {
184
263
  {
185
264
  text: '编辑',
186
265
  callback(node) {
266
+ _this.nodeEditOpen(node)
187
267
  _this.$emit('edit', node)
188
268
  },
189
269
  },
270
+ {
271
+ text: "复制",
272
+ callback: (node) => {
273
+ this.logicFlow.cloneNode(node.id);
274
+ },
275
+ },
190
276
  ],
277
+ // 连线菜单
191
278
  edgeMenu: [
192
279
  {
193
280
  text: "删除",
@@ -198,22 +285,110 @@ export default {
198
285
  {
199
286
  text: '编辑',
200
287
  callback(edge) {
288
+ _this.nodeEditOpen(edge)
201
289
  _this.$emit('edit', edge)
202
290
  },
203
291
  },
204
- ], // 删除默认的边右键菜单
205
- graphMenu: [], // 覆盖默认的边右键菜单,与false表现一样
292
+ {
293
+ text: '直线',
294
+ callback(edge) {
295
+ // 切换边类型
296
+ _this.logicFlow.changeEdgeType(edge.id, "line")
297
+ },
298
+ },
299
+ {
300
+ text: '曲线',
301
+ callback(edge) {
302
+ // 切换边类型
303
+ _this.logicFlow.changeEdgeType(edge.id, "bezier")
304
+ },
305
+ },
306
+ {
307
+ text: '折线',
308
+ callback(edge) {
309
+ _this.logicFlow.changeEdgeType(edge.id, "polyline")
310
+ },
311
+ },
312
+ ], // 全局右键菜单
313
+ graphMenu: [
314
+ // {
315
+ // text: '全局直线',
316
+ // callback() {
317
+ // // 切换边类型
318
+ // _this.logicFlow.setDefaultEdgeType("line")
319
+ // },
320
+ // },
321
+ // {
322
+ // text: '全局曲线',
323
+ // callback() {
324
+ // // 切换边类型
325
+ // _this.logicFlow.setDefaultEdgeType("bezier")
326
+ // },
327
+ // },
328
+ // {
329
+ // text: '全局折线',
330
+ // callback() {
331
+ // _this.logicFlow.setDefaultEdgeType("polyline")
332
+ // },
333
+ // },
334
+ ]
206
335
  });
207
336
  },
208
337
  /**
209
- * 初始化自定义节点
338
+ * 初始化节点
210
339
  * 该函数用于初始化基础节点,包括开始节点(basisStart)和结束节点(basisEnd)。
211
340
  * @param {Object} logicFlow - 逻辑流对象,用于操作节点。
212
341
  */
213
- initNode() {
214
- basisStart(this.logicFlow)
215
- basisEnd(this.logicFlow)
216
- }
342
+ async initNode() {
343
+ for (const x of this.nodeList) {
344
+ for (const node of x.list) {
345
+ switch (node.type) {
346
+ case 'start':
347
+ await basisStart(this.logicFlow);
348
+ break;
349
+ case 'end':
350
+ await basisEnd(this.logicFlow);
351
+ break;
352
+ default:
353
+ await nodeCustom(this.logicFlow, node);
354
+ break;
355
+ }
356
+ }
357
+ }
358
+ },
359
+ /**
360
+ * 节点绑定事件
361
+ */
362
+ bindEvent() {
363
+ this.logicFlow.on('node:dbclick', ({ data }) => {
364
+ this.nodeEditOpen(data)
365
+ })
366
+ this.logicFlow.on('edge:dbclick', ({ data }) => {
367
+ this.nodeEditOpen(data)
368
+ })
369
+ this.logicFlow.on('blank:click', () => {
370
+ this.drawerShow = false
371
+ })
372
+
373
+ // 数据变更监听
374
+ this.logicFlow.on('history:change', ({ data }) => {
375
+ let { undos } = data
376
+ // 返回所有历史数据
377
+ this.$emit('change', undos)
378
+ // 同步最后数据
379
+ this.$emit('update:modelValue', undos[undos.length - 1])
380
+ })
381
+ },
382
+ // 关闭属性抽屉
383
+ nodeEditClose() {
384
+ this.drawerShow = false
385
+ },
386
+ // 打开属性抽屉
387
+ nodeEditOpen(data) {
388
+ this.clickNode = data
389
+ this.drawerShow = true
390
+ },
391
+
217
392
  },
218
393
  }
219
394
  </script>
@@ -235,7 +410,7 @@ export default {
235
410
  z-index: 88;
236
411
  }
237
412
  :deep(.lf-menu) {
238
- width: 80px;
413
+ width: 85px;
239
414
  border-radius: var(--el-popover-border-radius);
240
415
  padding: var(--el-popover-padding);
241
416
  z-index: var(--el-index-popper);
@@ -270,4 +445,64 @@ export default {
270
445
  }
271
446
  }
272
447
  }
448
+ // 开始节点样式
449
+ :deep(.lw-flow-node-start) {
450
+ width: 100%;
451
+ height: 100%;
452
+ border: 2px solid #39bcc5;
453
+ border-radius: 100px;
454
+ font-size: 14px;
455
+ color: #39bcc5;
456
+ display: flex;
457
+ align-items: center;
458
+ justify-content: center;
459
+ }
460
+ // 结束节点样式
461
+ :deep(.lw-flow-node-end) {
462
+ width: 100%;
463
+ height: 100%;
464
+ border: 2px solid #e64210;
465
+ border-radius: 100px;
466
+ font-size: 14px;
467
+ color: #e64210;
468
+ display: flex;
469
+ align-items: center;
470
+ justify-content: center;
471
+ }
472
+ // 自定义节点样式
473
+ :deep(.lw-flow-node-custom) {
474
+ width: 100%;
475
+ height: 100%;
476
+ overflow: hidden;
477
+ background: #ffffff;
478
+ border-radius: 6px;
479
+ box-shadow: 0 0 8px rgba($color: #000000, $alpha: 0.2);
480
+ .top-name {
481
+ padding: 5px 10px;
482
+ display: flex;
483
+ align-items: center;
484
+ gap: 5px;
485
+ color: var(--el-text-color-regular);
486
+ line-height: 20px;
487
+ font-size: var(--el-popover-font-size);
488
+ border: 1px solid #39bcc5;
489
+ border-top: 10px solid #39bcc5;
490
+ border-bottom: 0;
491
+ }
492
+ .bottom-content {
493
+ height: calc(100% - 40px);
494
+ overflow: auto;
495
+ background-color: #ffffff;
496
+ border: 1px solid #39bcc5;
497
+ border-top: 0;
498
+ border-radius: 0 0 6px 6px;
499
+ padding: 10px;
500
+ font-size: 12px;
501
+ color: var(--el-text-color-regular);
502
+ display: flex;
503
+ flex-direction: column;
504
+ gap: 5px;
505
+ line-height: 14px;
506
+ }
507
+ }
273
508
  </style>
@@ -0,0 +1,100 @@
1
+ <template>
2
+ <lw-form ref="dataFormRef"
3
+ :config="config"
4
+ v-model="dataForm">
5
+
6
+ <!-- 定时器 表单部分 -->
7
+ <template #dateCron>
8
+ <lwCronSelect v-model="dataForm.cron" />
9
+ </template>
10
+ <span></span>
11
+ </lw-form>
12
+ </template>
13
+
14
+ <script>
15
+ import nodeDatas from '../nodesData/index.js'
16
+ export default {
17
+ name: 'basicSettings',
18
+ data() {
19
+ return {
20
+ dataForm: {}
21
+ }
22
+ },
23
+ props: {
24
+ modelValue: {
25
+ type: Object,
26
+ default: () => {
27
+ return {}
28
+ }
29
+ },
30
+ lf: {
31
+ type: Object,
32
+ default: () => { }
33
+ },
34
+ type: {
35
+ type: String,
36
+ default: ''
37
+ }
38
+ },
39
+ watch: {
40
+ modelValue: {
41
+ handler(val) {
42
+ this.dataForm = val
43
+ },
44
+ deep: true
45
+ },
46
+ dataForm: {
47
+ handler(val) {
48
+ this.$emit('update:modelValue', val)
49
+ },
50
+ deep: true
51
+ }
52
+ },
53
+ computed: {
54
+ config() {
55
+ let config = {
56
+ labelWidth: '70px',
57
+ labelPosition: 'top',
58
+ formItems: [
59
+ {
60
+ label: '节点名称',
61
+ name: 'name',
62
+ value: '',
63
+ component: 'input',
64
+ options: {
65
+ placeholder: '请输入节点名称',
66
+ },
67
+ span: 24
68
+ }
69
+ ]
70
+ }
71
+
72
+ // 拿到对应节点的表单配置
73
+ let nodeConfig = nodeDatas[this.type]?.formConfig || {}
74
+ if (nodeConfig?.labelWidth) {
75
+ config.labelWidth = nodeConfig.labelWidth
76
+ }
77
+ if (nodeConfig?.labelPosition) {
78
+ config.labelPosition = nodeConfig.labelPosition
79
+ }
80
+ if (nodeConfig?.formItems) {
81
+ config.formItems = nodeConfig.formItems
82
+ }
83
+
84
+ return config
85
+ }
86
+ },
87
+ methods: {
88
+ changeFontWeight() {
89
+ this.dataForm.fontWeight = this.dataForm.fontWeight === 'bold' ? 'normal' : 'bold'
90
+ },
91
+ changeTextDecoration() {
92
+ this.dataForm.textDecoration = this.dataForm.textDecoration === 'underline' ? 'none' : 'underline'
93
+ },
94
+ changeFontStyle() {
95
+ this.dataForm.fontStyle = this.dataForm.fontStyle === 'italic' ? 'normal' : 'italic'
96
+ },
97
+ }
98
+ }
99
+
100
+ </script>