hookehuyr

调整单击节点操作逻辑

...@@ -14,14 +14,16 @@ ...@@ -14,14 +14,16 @@
14 :beforeAdd="handleBeforeAdd" 14 :beforeAdd="handleBeforeAdd"
15 :afterAdd="handleAfterAdd" 15 :afterAdd="handleAfterAdd"
16 @dragend-node="onDragEndNode" 16 @dragend-node="onDragEndNode"
17 - @dblclick-node="onDblclickNode" 17 + @dblclick-node="onDblClickNode"
18 @dblclick-edge="onDblClickEdge" 18 @dblclick-edge="onDblClickEdge"
19 - :activityConfig="state.activityConfig"
20 :controlConfig="state.controlConfig" 19 :controlConfig="state.controlConfig"
20 + :toolbarButtonHandler="toolbarButtonHandler"
21 > 21 >
22 + <!-- :activityConfig="state.activityConfig" -->
23 + <!-- @click-node="onClickNode" -->
22 <!-- 左侧菜单 --> 24 <!-- 左侧菜单 -->
23 <template v-slot:menu> 25 <template v-slot:menu>
24 - <vue-flow-edit-menu-group label="活动节点" value> 26 + <!-- <vue-flow-edit-menu-group label="活动节点" value>
25 <vue-flow-edit-menu 27 <vue-flow-edit-menu
26 v-for="(value, key) in state.activityConfig" 28 v-for="(value, key) in state.activityConfig"
27 :key="key" 29 :key="key"
...@@ -34,8 +36,8 @@ ...@@ -34,8 +36,8 @@
34 </div> 36 </div>
35 </template> 37 </template>
36 </vue-flow-edit-menu> 38 </vue-flow-edit-menu>
37 - </vue-flow-edit-menu-group> 39 + </vue-flow-edit-menu-group> -->
38 - <vue-flow-edit-menu-group label="控制节点" value> 40 + <vue-flow-edit-menu-group label="操作节点" value>
39 <!-- 注意 key 值的绑定 --> 41 <!-- 注意 key 值的绑定 -->
40 <vue-flow-edit-menu 42 <vue-flow-edit-menu
41 v-for="(value, key) in state.controlConfig" 43 v-for="(value, key) in state.controlConfig"
...@@ -50,18 +52,18 @@ ...@@ -50,18 +52,18 @@
50 </template> 52 </template>
51 </vue-flow-edit-menu> 53 </vue-flow-edit-menu>
52 </vue-flow-edit-menu-group> 54 </vue-flow-edit-menu-group>
53 - <vue-flow-edit-menu-group 55 + <!-- <vue-flow-edit-menu-group
54 v-for="(group, groupIndex) in state.menuData" 56 v-for="(group, groupIndex) in state.menuData"
55 :label="group.label" 57 :label="group.label"
56 :key="groupIndex" 58 :key="groupIndex"
57 - value 59 + :value="true"
58 > 60 >
59 <vue-flow-edit-menu 61 <vue-flow-edit-menu
60 v-for="(menu, menuIndex) in group.menus" 62 v-for="(menu, menuIndex) in group.menus"
61 :key="menuIndex" 63 :key="menuIndex"
62 :model="menu" 64 :model="menu"
63 /> 65 />
64 - </vue-flow-edit-menu-group> 66 + </vue-flow-edit-menu-group> -->
65 </template> 67 </template>
66 <!-- 右侧表单 --> 68 <!-- 右侧表单 -->
67 <template v-slot:model> 69 <template v-slot:model>
...@@ -182,7 +184,7 @@ ...@@ -182,7 +184,7 @@
182 <el-form-item label="活动副标题"> 184 <el-form-item label="活动副标题">
183 <el-input v-model="state.detailModel.desc" /> 185 <el-input v-model="state.detailModel.desc" />
184 </el-form-item> 186 </el-form-item>
185 - <el-form-item label="活动类型"> 187 + <!-- <el-form-item label="活动类型">
186 <el-select v-model="state.detailModel.activity"> 188 <el-select v-model="state.detailModel.activity">
187 <el-option 189 <el-option
188 v-for="(value, key) in state.activityConfig" 190 v-for="(value, key) in state.activityConfig"
...@@ -191,7 +193,7 @@ ...@@ -191,7 +193,7 @@
191 :value="key" 193 :value="key"
192 /> 194 />
193 </el-select> 195 </el-select>
194 - </el-form-item> 196 + </el-form-item> -->
195 </template> 197 </template>
196 </el-form> 198 </el-form>
197 </template> 199 </template>
...@@ -241,6 +243,7 @@ interface myObj { ...@@ -241,6 +243,7 @@ interface myObj {
241 source: string; 243 source: string;
242 id: string; 244 id: string;
243 label: string; 245 label: string;
246 + control: string;
244 } 247 }
245 248
246 interface myEvent { 249 interface myEvent {
...@@ -294,42 +297,44 @@ export default { ...@@ -294,42 +297,44 @@ export default {
294 ] 297 ]
295 } 298 }
296 ], 299 ],
297 - activityConfig: { 300 + // activityConfig: {
298 - advertisement: { 301 + // advertisement: {
299 - text: "广告宣传1", 302 + // text: "广告宣传1",
300 - desc: "通过广告宣传新品", 303 + // desc: "通过广告宣传新品",
301 - color: "#9283ed", 304 + // color: "#9283ed",
302 - img: "https://cdn.ipadbiz.cn/oa/advertisement-node.svg" 305 + // img: "https://cdn.ipadbiz.cn/oa/advertisement-node.svg"
303 - }, 306 + // },
304 - coupon: { 307 + // coupon: {
305 - text: "优惠券", 308 + // text: "优惠券",
306 - desc: "发放奖励优惠券", 309 + // desc: "发放奖励优惠券",
307 - color: "#ed8383", 310 + // color: "#ed8383",
308 - img: "https://cdn.ipadbiz.cn/oa/coupon-node.svg" 311 + // img: "https://cdn.ipadbiz.cn/oa/coupon-node.svg"
309 - }, 312 + // },
310 - crowd: { 313 + // crowd: {
311 - text: "用户反馈", 314 + // text: "用户反馈",
312 - desc: "收集用户反馈信息", 315 + // desc: "收集用户反馈信息",
313 - color: "#92dba8", 316 + // color: "#92dba8",
314 - img: "https://cdn.ipadbiz.cn/oa/crowd-node.svg" 317 + // img: "https://cdn.ipadbiz.cn/oa/crowd-node.svg"
315 - } 318 + // }
316 - }, 319 + // },
317 controlConfig: { 320 controlConfig: {
318 start: { 321 start: {
322 + id: "start-node",
319 text: "开始", 323 text: "开始",
320 - desc: "描述文字", 324 + desc: "开始",
321 color: "#9283ed", 325 color: "#9283ed",
322 img: "https://cdn.ipadbiz.cn/oa/advertisement-node.svg" 326 img: "https://cdn.ipadbiz.cn/oa/advertisement-node.svg"
323 }, 327 },
324 - stop: { 328 + flow: {
325 - text: "中止", 329 + text: "流程节点",
326 - desc: "描述文字", 330 + desc: "流程节点",
327 color: "#ed8383", 331 color: "#ed8383",
328 img: "https://cdn.ipadbiz.cn/oa/coupon-node.svg" 332 img: "https://cdn.ipadbiz.cn/oa/coupon-node.svg"
329 }, 333 },
330 end: { 334 end: {
335 + id: "end-node",
331 text: "结束", 336 text: "结束",
332 - desc: "描述文字", 337 + desc: "结束",
333 color: "#92dba8", 338 color: "#92dba8",
334 img: "https://cdn.ipadbiz.cn/oa/crowd-node.svg" 339 img: "https://cdn.ipadbiz.cn/oa/crowd-node.svg"
335 } 340 }
...@@ -444,7 +449,17 @@ export default { ...@@ -444,7 +449,17 @@ export default {
444 * 449 *
445 * @param {Object} e - The event object 450 * @param {Object} e - The event object
446 */ 451 */
447 - function onDblclickNode(e: myEvent) { 452 + function onDblClickNode(e: myEvent) {
453 + const model = G6.Util.clone(e.item.get("model"));
454 + model.style = model.style || {};
455 + model.labelCfg = model.labelCfg || { style: {} };
456 +
457 + model.data = model.data ? model.data : {};
458 + state.detailModel = model;
459 + editor.openModel();
460 + }
461 +
462 + function onClickNode(e: myEvent) {
448 const model = G6.Util.clone(e.item.get("model")); 463 const model = G6.Util.clone(e.item.get("model"));
449 model.style = model.style || {}; 464 model.style = model.style || {};
450 model.labelCfg = model.labelCfg || { style: {} }; 465 model.labelCfg = model.labelCfg || { style: {} };
...@@ -542,13 +557,13 @@ export default { ...@@ -542,13 +557,13 @@ export default {
542 } 557 }
543 } 558 }
544 if (type === "node") { 559 if (type === "node") {
545 - if (model.id === "start-node" || model.id === "end-node") { 560 + if (model.control === "start" || model.control === "end") {
546 const data = editor.editorState.graph.save(); 561 const data = editor.editorState.graph.save();
547 for (let i = 0; i < data.nodes.length; i++) { 562 for (let i = 0; i < data.nodes.length; i++) {
548 const node = data.nodes[i]; 563 const node = data.nodes[i];
549 - if (node.id === model.id) { 564 + if (node.control === model.control) {
550 ElNotification.error( 565 ElNotification.error(
551 - `只能有一个${model.id === "start-node" ? "开始" : "结束"}节点` 566 + `只能有一个${model.control === "start" ? "开始" : "结束"}节点`
552 ); 567 );
553 return Promise.reject("reject"); 568 return Promise.reject("reject");
554 } 569 }
...@@ -564,6 +579,8 @@ export default { ...@@ -564,6 +579,8 @@ export default {
564 * @param {type} type - The type of the event. 579 * @param {type} type - The type of the event.
565 */ 580 */
566 function handleAfterAdd(model: myObj, type: string) { 581 function handleAfterAdd(model: myObj, type: string) {
582 + console.log('handleAfterAdd', model);
583 +
567 // TODO: 因为resize会重新绘制,所以可能需要保存操作 584 // TODO: 因为resize会重新绘制,所以可能需要保存操作
568 if (type === 'node') { 585 if (type === 'node') {
569 console.log(`新增节点`); 586 console.log(`新增节点`);
...@@ -591,6 +608,18 @@ export default { ...@@ -591,6 +608,18 @@ export default {
591 */ 608 */
592 function logData(): void { 609 function logData(): void {
593 let { nodes, edges } = editor.editorState.graph.save(); 610 let { nodes, edges } = editor.editorState.graph.save();
611 + // console.log("nodes", nodes);
612 + // console.log("edges", edges);
613 + // 使用时需要把自定义节点的类型带过去 activity/control
614 + nodes.forEach((node: { [x: string]: string; shape: string; }) => {
615 + if (node.shape === "activity") {
616 + node['shape'] = 'activity_' + node['activity'];
617 + }
618 + if (node.shape === "control") {
619 + node['shape'] = 'control_' + node['control'];
620 + }
621 + });
622 +
594 nodes = nodes.map( 623 nodes = nodes.map(
595 ({ data, id, label, shape, x, y, text, desc, img }) => ({ 624 ({ data, id, label, shape, x, y, text, desc, img }) => ({
596 data, 625 data,
...@@ -610,17 +639,32 @@ export default { ...@@ -610,17 +639,32 @@ export default {
610 target, 639 target,
611 targetAnchor 640 targetAnchor
612 })); 641 }));
613 - console.log(JSON.stringify({ nodes, edges }, null, 2)); 642 + // console.log(JSON.stringify({ nodes, edges }, null, 2));
643 + console.log(nodes);
644 + console.log(edges);
645 + }
646 +
647 + /**
648 + * 格式化工具栏按钮
649 + *
650 + * @param {Array} buttons - The array of buttons to be filtered
651 + * @return {Array} - The filtered array of buttons
652 + */
653 + function toolbarButtonHandler(buttons: any[]): Array<any> {
654 + // TAG:测试隐藏缩略图
655 + let map = buttons.filter(item => item.key !== "miniMapSwitcher");
656 + return map;
614 } 657 }
615 658
616 return { 659 return {
617 state, 660 state,
618 661
619 showGrid: true, // 是否开启网格 662 showGrid: true, // 是否开启网格
620 - showMiniMap: true, // 是否开启缩略图 663 + showMiniMap: false, // 是否开启缩略图
621 showMultipleSelect: true, // 编辑器是否可以多选 664 showMultipleSelect: true, // 编辑器是否可以多选
622 665
623 - onDblclickNode, 666 + onClickNode,
667 + onDblClickNode,
624 onDragEndNode, 668 onDragEndNode,
625 onDblClickEdge, 669 onDblClickEdge,
626 cancel, 670 cancel,
...@@ -639,6 +683,7 @@ export default { ...@@ -639,6 +683,7 @@ export default {
639 onConfirmUserView, 683 onConfirmUserView,
640 684
641 logData, 685 logData,
686 + toolbarButtonHandler,
642 687
643 onRef: (e: any) => (editor = e), 688 onRef: (e: any) => (editor = e),
644 staticPath 689 staticPath
......
1 +/*
2 + * @Date: 2023-10-27 09:29:48
3 + * @LastEditors: hookehuyr hookehuyr@gmail.com
4 + * @LastEditTime: 2023-11-15 15:56:03
5 + * @FilePath: /vue-flow-editor/doc/data.js
6 + * @Description: 初始化结构,数据都是固定的
7 + */
1 export const AppData = { 8 export const AppData = {
2 - "nodes": [ 9 + nodes: [
3 { 10 {
4 - "id": "123456", 11 + id: 'start-node',
5 - "x": 590, 12 + x: 225,
6 - "y": 100, 13 + y: 100,
7 - "text": "广告宣传", 14 + text: '开始',
8 - "desc": "通过广告短频宣传", 15 + desc: '',
9 - "activity": "advertisement", // 自定义节点的类型 16 + control: 'start',
10 }, 17 },
11 { 18 {
12 - "id": "2323456789", 19 + id: '5353453523',
13 - "x": 1020, 20 + x: 225,
14 - "y": 100, 21 + y: 210,
15 - "text": "优惠券", 22 + text: '流程节点',
16 - "desc": "发送奖励优惠券", 23 + desc: '',
17 - "activity": "coupon", 24 + control: 'flow',
18 }, 25 },
19 { 26 {
20 - "id": "23234567891", 27 + id: 'end-node',
21 - "x": 130, 28 + x: 225,
22 - "y": 130, 29 + y: 335,
23 - "text": "开始", 30 + text: '结束',
24 - "desc": "发布", 31 + desc: '',
25 - "control": "start", 32 + control: 'end',
26 }, 33 },
27 - {
28 - "data": {},
29 - "id": "start-node",
30 - "label": "开始",
31 - "shape": "ellipse",
32 - "x": 380,
33 - "y": 100
34 - },
35 - {
36 - "data": {},
37 - "id": "1588848310120",
38 - "label": "主管审批",
39 - "shape": "rect",
40 - "x": 380,
41 - "y": 180
42 - },
43 - {
44 - "data": {},
45 - "id": "1588848322179",
46 - "label": "经理审批",
47 - "shape": "rect",
48 - "x": 380,
49 - "y": 260
50 - },
51 - {
52 - "data": {},
53 - "id": "1588848338211",
54 - "label": "金额>2万",
55 - "shape": "diamond",
56 - "x": 380,
57 - "y": 340
58 - },
59 - {
60 - "data": {},
61 - "id": "1588848351476",
62 - "label": "财务打款",
63 - "shape": "rect",
64 - "x": 380,
65 - "y": 460
66 - },
67 - {
68 - "data": {},
69 - "id": "end-node",
70 - "label": "结束",
71 - "shape": "ellipse",
72 - "x": 380,
73 - "y": 540
74 - },
75 - {
76 - "data": {},
77 - "id": "1588848397511",
78 - "label": "VIP审批",
79 - "shape": "rect",
80 - "x": 590,
81 - "y": 340
82 - },
83 - {
84 - "data": {
85 - test: 100
86 - },
87 - "id": "1588848436694",
88 - "label": "金额>10万1",
89 - "shape": "diamond",
90 - "x": 780,
91 - "y": 340
92 - },
93 - {
94 - "data": {},
95 - "id": "1588848449431",
96 - "label": "CEO审批",
97 - "shape": "rect",
98 - "x": 960,
99 - "y": 460
100 - }
101 ], 34 ],
102 - "edges": [ 35 + edges: [
103 { 36 {
104 - "source": "start-node", 37 + source: 'start-node',
105 - "sourceAnchor": 2, 38 + sourceAnchor: 2,
106 - "target": "1588848310120", 39 + target: '5353453523',
107 - "targetAnchor": 0 40 + targetAnchor: 0,
108 }, 41 },
109 { 42 {
110 - "source": "1588848310120", 43 + source: '5353453523',
111 - "sourceAnchor": 2, 44 + sourceAnchor: 2,
112 - "target": "1588848322179", 45 + target: 'end-node',
113 - "targetAnchor": 0 46 + targetAnchor: 0,
114 }, 47 },
115 - { 48 + ],
116 - "source": "1588848322179",
117 - "sourceAnchor": 2,
118 - "target": "1588848338211",
119 - "targetAnchor": 0
120 - },
121 - {
122 - "source": "1588848338211",
123 - "sourceAnchor": 2,
124 - "target": "1588848351476",
125 - "targetAnchor": 0
126 - },
127 - {
128 - "source": "1588848351476",
129 - "sourceAnchor": 2,
130 - "target": "end-node",
131 - "targetAnchor": 0
132 - },
133 - {
134 - "source": "1588848338211",
135 - "sourceAnchor": 3,
136 - "target": "1588848397511",
137 - "targetAnchor": 1
138 - },
139 - {
140 - "source": "1588848436694",
141 - "sourceAnchor": 3,
142 - "target": "1588848449431",
143 - "targetAnchor": 0
144 - },
145 - {
146 - "source": "1588848449431",
147 - "sourceAnchor": 1,
148 - "target": "1588848351476",
149 - "targetAnchor": 3
150 - },
151 - {
152 - "source": "1588848436694",
153 - "sourceAnchor": 2,
154 - "target": "1588848351476",
155 - "targetAnchor": 3
156 - },
157 - {
158 - "source": "1588848397511",
159 - "sourceAnchor": 3,
160 - "target": "1588848436694",
161 - "targetAnchor": 1
162 - },
163 - {
164 - "source": "start-node",
165 - "sourceAnchor": 3,
166 - "target": "123456",
167 - "targetAnchor": 1
168 - },
169 - {
170 - "source": "123456",
171 - "sourceAnchor": 3,
172 - "target": "2323456789",
173 - "targetAnchor": 1
174 - },
175 - {
176 - "source": "2323456789",
177 - "sourceAnchor": 3,
178 - "target": "end-node",
179 - "targetAnchor": 3
180 - }
181 - ]
182 } 49 }
......
...@@ -7,9 +7,9 @@ export default { ...@@ -7,9 +7,9 @@ export default {
7 name: 'vue-flow-editor', 7 name: 'vue-flow-editor',
8 props: { 8 props: {
9 data: {type: Object}, // 渲染的数据 9 data: {type: Object}, // 渲染的数据
10 - grid: {type: Boolean, default: true}, // 是否需要网格 10 + grid: {type: Boolean, default: true}, // 是否需要网格
11 - miniMap: {type: Boolean, default: false}, // 是否需要缩略图 11 + miniMap: {type: Boolean, default: false}, // 是否需要缩略图
12 - disabledDragEdge:{type: Boolean}, // 禁用拖拽连线功能 12 + disabledDragEdge:{type: Boolean}, // 禁用拖拽连线功能
13 disabledUndo: {type: Boolean}, // 禁用撤销以及重做功能 13 disabledUndo: {type: Boolean}, // 禁用撤销以及重做功能
14 editorTitle: {type: String}, // 编辑器标题 14 editorTitle: {type: String}, // 编辑器标题
15 15
...@@ -29,8 +29,8 @@ export default { ...@@ -29,8 +29,8 @@ export default {
29 beforeAdd: {type: Function}, // 添加前校验 29 beforeAdd: {type: Function}, // 添加前校验
30 afterAdd: {type: Function}, // 添加后动作 30 afterAdd: {type: Function}, // 添加后动作
31 // TAG: 自定义节点 - 前端注入类型 31 // TAG: 自定义节点 - 前端注入类型
32 - activityConfig: {type: Object}, // 注册活动节点 32 + activityConfig: {type: Object}, // 注册活动节点
33 - controlConfig: {type: Object}, // 注册活动节点 33 + controlConfig: {type: Object}, // 注册活动节点
34 }, 34 },
35 setup(props, context) { 35 setup(props, context) {
36 36
...@@ -56,6 +56,9 @@ export default { ...@@ -56,6 +56,9 @@ export default {
56 editorState.graph = graph 56 editorState.graph = graph
57 commander.init(graph) 57 commander.init(graph)
58 58
59 + graph.on('node:click', (e) => {
60 + context.emit('click-node', e)
61 + })
59 graph.on('node:dblclick', (e) => { 62 graph.on('node:dblclick', (e) => {
60 context.emit('dblclick-node', e) 63 context.emit('dblclick-node', e)
61 }) 64 })
......