hookehuyr

调整单击节点操作逻辑

......@@ -14,14 +14,16 @@
:beforeAdd="handleBeforeAdd"
:afterAdd="handleAfterAdd"
@dragend-node="onDragEndNode"
@dblclick-node="onDblclickNode"
@dblclick-node="onDblClickNode"
@dblclick-edge="onDblClickEdge"
:activityConfig="state.activityConfig"
:controlConfig="state.controlConfig"
:toolbarButtonHandler="toolbarButtonHandler"
>
<!-- :activityConfig="state.activityConfig" -->
<!-- @click-node="onClickNode" -->
<!-- 左侧菜单 -->
<template v-slot:menu>
<vue-flow-edit-menu-group label="活动节点" value>
<!-- <vue-flow-edit-menu-group label="活动节点" value>
<vue-flow-edit-menu
v-for="(value, key) in state.activityConfig"
:key="key"
......@@ -34,8 +36,8 @@
</div>
</template>
</vue-flow-edit-menu>
</vue-flow-edit-menu-group>
<vue-flow-edit-menu-group label="控制节点" value>
</vue-flow-edit-menu-group> -->
<vue-flow-edit-menu-group label="操作节点" value>
<!-- 注意 key 值的绑定 -->
<vue-flow-edit-menu
v-for="(value, key) in state.controlConfig"
......@@ -50,18 +52,18 @@
</template>
</vue-flow-edit-menu>
</vue-flow-edit-menu-group>
<vue-flow-edit-menu-group
<!-- <vue-flow-edit-menu-group
v-for="(group, groupIndex) in state.menuData"
:label="group.label"
:key="groupIndex"
value
:value="true"
>
<vue-flow-edit-menu
v-for="(menu, menuIndex) in group.menus"
:key="menuIndex"
:model="menu"
/>
</vue-flow-edit-menu-group>
</vue-flow-edit-menu-group> -->
</template>
<!-- 右侧表单 -->
<template v-slot:model>
......@@ -182,7 +184,7 @@
<el-form-item label="活动副标题">
<el-input v-model="state.detailModel.desc" />
</el-form-item>
<el-form-item label="活动类型">
<!-- <el-form-item label="活动类型">
<el-select v-model="state.detailModel.activity">
<el-option
v-for="(value, key) in state.activityConfig"
......@@ -191,7 +193,7 @@
:value="key"
/>
</el-select>
</el-form-item>
</el-form-item> -->
</template>
</el-form>
</template>
......@@ -241,6 +243,7 @@ interface myObj {
source: string;
id: string;
label: string;
control: string;
}
interface myEvent {
......@@ -294,42 +297,44 @@ export default {
]
}
],
activityConfig: {
advertisement: {
text: "广告宣传1",
desc: "通过广告宣传新品",
color: "#9283ed",
img: "https://cdn.ipadbiz.cn/oa/advertisement-node.svg"
},
coupon: {
text: "优惠券",
desc: "发放奖励优惠券",
color: "#ed8383",
img: "https://cdn.ipadbiz.cn/oa/coupon-node.svg"
},
crowd: {
text: "用户反馈",
desc: "收集用户反馈信息",
color: "#92dba8",
img: "https://cdn.ipadbiz.cn/oa/crowd-node.svg"
}
},
// activityConfig: {
// advertisement: {
// text: "广告宣传1",
// desc: "通过广告宣传新品",
// color: "#9283ed",
// img: "https://cdn.ipadbiz.cn/oa/advertisement-node.svg"
// },
// coupon: {
// text: "优惠券",
// desc: "发放奖励优惠券",
// color: "#ed8383",
// img: "https://cdn.ipadbiz.cn/oa/coupon-node.svg"
// },
// crowd: {
// text: "用户反馈",
// desc: "收集用户反馈信息",
// color: "#92dba8",
// img: "https://cdn.ipadbiz.cn/oa/crowd-node.svg"
// }
// },
controlConfig: {
start: {
id: "start-node",
text: "开始",
desc: "描述文字",
desc: "开始",
color: "#9283ed",
img: "https://cdn.ipadbiz.cn/oa/advertisement-node.svg"
},
stop: {
text: "中止",
desc: "描述文字",
flow: {
text: "流程节点",
desc: "流程节点",
color: "#ed8383",
img: "https://cdn.ipadbiz.cn/oa/coupon-node.svg"
},
end: {
id: "end-node",
text: "结束",
desc: "描述文字",
desc: "结束",
color: "#92dba8",
img: "https://cdn.ipadbiz.cn/oa/crowd-node.svg"
}
......@@ -444,7 +449,17 @@ export default {
*
* @param {Object} e - The event object
*/
function onDblclickNode(e: myEvent) {
function onDblClickNode(e: myEvent) {
const model = G6.Util.clone(e.item.get("model"));
model.style = model.style || {};
model.labelCfg = model.labelCfg || { style: {} };
model.data = model.data ? model.data : {};
state.detailModel = model;
editor.openModel();
}
function onClickNode(e: myEvent) {
const model = G6.Util.clone(e.item.get("model"));
model.style = model.style || {};
model.labelCfg = model.labelCfg || { style: {} };
......@@ -542,13 +557,13 @@ export default {
}
}
if (type === "node") {
if (model.id === "start-node" || model.id === "end-node") {
if (model.control === "start" || model.control === "end") {
const data = editor.editorState.graph.save();
for (let i = 0; i < data.nodes.length; i++) {
const node = data.nodes[i];
if (node.id === model.id) {
if (node.control === model.control) {
ElNotification.error(
`只能有一个${model.id === "start-node" ? "开始" : "结束"}节点`
`只能有一个${model.control === "start" ? "开始" : "结束"}节点`
);
return Promise.reject("reject");
}
......@@ -564,6 +579,8 @@ export default {
* @param {type} type - The type of the event.
*/
function handleAfterAdd(model: myObj, type: string) {
console.log('handleAfterAdd', model);
// TODO: 因为resize会重新绘制,所以可能需要保存操作
if (type === 'node') {
console.log(`新增节点`);
......@@ -591,6 +608,18 @@ export default {
*/
function logData(): void {
let { nodes, edges } = editor.editorState.graph.save();
// console.log("nodes", nodes);
// console.log("edges", edges);
// 使用时需要把自定义节点的类型带过去 activity/control
nodes.forEach((node: { [x: string]: string; shape: string; }) => {
if (node.shape === "activity") {
node['shape'] = 'activity_' + node['activity'];
}
if (node.shape === "control") {
node['shape'] = 'control_' + node['control'];
}
});
nodes = nodes.map(
({ data, id, label, shape, x, y, text, desc, img }) => ({
data,
......@@ -610,17 +639,32 @@ export default {
target,
targetAnchor
}));
console.log(JSON.stringify({ nodes, edges }, null, 2));
// console.log(JSON.stringify({ nodes, edges }, null, 2));
console.log(nodes);
console.log(edges);
}
/**
* 格式化工具栏按钮
*
* @param {Array} buttons - The array of buttons to be filtered
* @return {Array} - The filtered array of buttons
*/
function toolbarButtonHandler(buttons: any[]): Array<any> {
// TAG:测试隐藏缩略图
let map = buttons.filter(item => item.key !== "miniMapSwitcher");
return map;
}
return {
state,
showGrid: true, // 是否开启网格
showMiniMap: true, // 是否开启缩略图
showMiniMap: false, // 是否开启缩略图
showMultipleSelect: true, // 编辑器是否可以多选
onDblclickNode,
onClickNode,
onDblClickNode,
onDragEndNode,
onDblClickEdge,
cancel,
......@@ -639,6 +683,7 @@ export default {
onConfirmUserView,
logData,
toolbarButtonHandler,
onRef: (e: any) => (editor = e),
staticPath
......
/*
* @Date: 2023-10-27 09:29:48
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2023-11-15 15:56:03
* @FilePath: /vue-flow-editor/doc/data.js
* @Description: 初始化结构,数据都是固定的
*/
export const AppData = {
"nodes": [
nodes: [
{
"id": "123456",
"x": 590,
"y": 100,
"text": "广告宣传",
"desc": "通过广告短频宣传",
"activity": "advertisement", // 自定义节点的类型
id: 'start-node',
x: 225,
y: 100,
text: '开始',
desc: '',
control: 'start',
},
{
"id": "2323456789",
"x": 1020,
"y": 100,
"text": "优惠券",
"desc": "发送奖励优惠券",
"activity": "coupon",
id: '5353453523',
x: 225,
y: 210,
text: '流程节点',
desc: '',
control: 'flow',
},
{
"id": "23234567891",
"x": 130,
"y": 130,
"text": "开始",
"desc": "发布",
"control": "start",
id: 'end-node',
x: 225,
y: 335,
text: '结束',
desc: '',
control: 'end',
},
{
"data": {},
"id": "start-node",
"label": "开始",
"shape": "ellipse",
"x": 380,
"y": 100
},
{
"data": {},
"id": "1588848310120",
"label": "主管审批",
"shape": "rect",
"x": 380,
"y": 180
},
{
"data": {},
"id": "1588848322179",
"label": "经理审批",
"shape": "rect",
"x": 380,
"y": 260
},
{
"data": {},
"id": "1588848338211",
"label": "金额>2万",
"shape": "diamond",
"x": 380,
"y": 340
},
{
"data": {},
"id": "1588848351476",
"label": "财务打款",
"shape": "rect",
"x": 380,
"y": 460
},
{
"data": {},
"id": "end-node",
"label": "结束",
"shape": "ellipse",
"x": 380,
"y": 540
},
{
"data": {},
"id": "1588848397511",
"label": "VIP审批",
"shape": "rect",
"x": 590,
"y": 340
},
{
"data": {
test: 100
},
"id": "1588848436694",
"label": "金额>10万1",
"shape": "diamond",
"x": 780,
"y": 340
},
{
"data": {},
"id": "1588848449431",
"label": "CEO审批",
"shape": "rect",
"x": 960,
"y": 460
}
],
"edges": [
edges: [
{
"source": "start-node",
"sourceAnchor": 2,
"target": "1588848310120",
"targetAnchor": 0
source: 'start-node',
sourceAnchor: 2,
target: '5353453523',
targetAnchor: 0,
},
{
"source": "1588848310120",
"sourceAnchor": 2,
"target": "1588848322179",
"targetAnchor": 0
source: '5353453523',
sourceAnchor: 2,
target: 'end-node',
targetAnchor: 0,
},
{
"source": "1588848322179",
"sourceAnchor": 2,
"target": "1588848338211",
"targetAnchor": 0
},
{
"source": "1588848338211",
"sourceAnchor": 2,
"target": "1588848351476",
"targetAnchor": 0
},
{
"source": "1588848351476",
"sourceAnchor": 2,
"target": "end-node",
"targetAnchor": 0
},
{
"source": "1588848338211",
"sourceAnchor": 3,
"target": "1588848397511",
"targetAnchor": 1
},
{
"source": "1588848436694",
"sourceAnchor": 3,
"target": "1588848449431",
"targetAnchor": 0
},
{
"source": "1588848449431",
"sourceAnchor": 1,
"target": "1588848351476",
"targetAnchor": 3
},
{
"source": "1588848436694",
"sourceAnchor": 2,
"target": "1588848351476",
"targetAnchor": 3
},
{
"source": "1588848397511",
"sourceAnchor": 3,
"target": "1588848436694",
"targetAnchor": 1
},
{
"source": "start-node",
"sourceAnchor": 3,
"target": "123456",
"targetAnchor": 1
},
{
"source": "123456",
"sourceAnchor": 3,
"target": "2323456789",
"targetAnchor": 1
},
{
"source": "2323456789",
"sourceAnchor": 3,
"target": "end-node",
"targetAnchor": 3
}
]
],
}
......
......@@ -7,9 +7,9 @@ export default {
name: 'vue-flow-editor',
props: {
data: {type: Object}, // 渲染的数据
grid: {type: Boolean, default: true}, // 是否需要网格
miniMap: {type: Boolean, default: false}, // 是否需要缩略图
disabledDragEdge:{type: Boolean}, // 禁用拖拽连线功能
grid: {type: Boolean, default: true}, // 是否需要网格
miniMap: {type: Boolean, default: false}, // 是否需要缩略图
disabledDragEdge:{type: Boolean}, // 禁用拖拽连线功能
disabledUndo: {type: Boolean}, // 禁用撤销以及重做功能
editorTitle: {type: String}, // 编辑器标题
......@@ -29,8 +29,8 @@ export default {
beforeAdd: {type: Function}, // 添加前校验
afterAdd: {type: Function}, // 添加后动作
// TAG: 自定义节点 - 前端注入类型
activityConfig: {type: Object}, // 注册活动节点
controlConfig: {type: Object}, // 注册活动节点
activityConfig: {type: Object}, // 注册活动节点
controlConfig: {type: Object}, // 注册活动节点
},
setup(props, context) {
......@@ -56,6 +56,9 @@ export default {
editorState.graph = graph
commander.init(graph)
graph.on('node:click', (e) => {
context.emit('click-node', e)
})
graph.on('node:dblclick', (e) => {
context.emit('dblclick-node', e)
})
......