js实现可拖拽可导出json格式在python中执行的可视化工作流笔记
2025年ai agent兴起了,以coze为代码的工作流火了,不用写代码,通过可视化拖拽节点的形式生成一个json格式工作流,最后在后端工作流引擎中执行,今天我们以js实现前端工作流绘制拖拽连线,后端python执行工作流输出结果为例。

前端
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>可视化工作流编辑器</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/jsplumb/2.15.6/jsplumb.css">
<style>
#canvas {
position: relative;
width: 800px;
height: 600px;
border: 1px solid #000;
background-color: #fafafa;
}
.node {
position: absolute;
width: 120px;
height: 60px;
background-color: #f0f0f0;
border: 1px solid #ccc;
text-align: center;
line-height: 30px;
cursor: move;
padding: 5px;
font-size: 12px;
}
.node input {
width: 100%;
box-sizing: border-box;
}
.button-group {
margin-top: 10px;
}
</style>
</head>
<body>
<div id="canvas"></div>
<div class="button-group">
<button id="addFunction">添加函数节点</button>
<button id="addIfElse">添加 If-Else 节点</button>
<button id="save">保存工作流</button>
</div>
<script type="text/javascript" src="//repo.bfw.wiki/bfwrepo/js/jsplumb.min.js"></script>
<script >
jsPlumb.ready(function () {
var instance = jsPlumb.getInstance({
Container: "canvas",
Connector: ["Bezier", { curviness: 50 }],
PaintStyle: { stroke: "#666", strokeWidth: 2 }
});
var nodes = [];
var connections = [];
// 添加节点通用函数
function addNode(type, x, y) {
var id = "node" + Date.now(); // 使用时间戳确保唯一性
var node = document.createElement("div");
node.className = "node";
node.id = id;
node.style.left = x + "px";
node.style.top = y + "px";
// 节点内容:函数名输入框和参数输入框
var funcNameInput = document.createElement("input");
funcNameInput.placeholder = "函数名";
var paramsInput = document.createElement("input");
paramsInput.placeholder = type === "ifelse" ? "条件 (如 x > 5)" : "参数 (如 a, b)";
node.appendChild(funcNameInput);
node.appendChild(paramsInput);
document.getElementById("canvas").appendChild(node);
instance.draggable(node);
nodes.push({ id: id, type: type, funcName: "", params: "" });
// 添加端点
if (type === "function") {
instance.addEndpoint(node, {
anchor: "Top",
endpoint: "Dot",
paintStyle: { fill: "blue" },
isSource: false,
isTarget: true
});
instance.addEndpoint(node, {
anchor: "Bottom",
endpoint: "Dot",
paintStyle: { fill: "blue" },
isSource: true,
isTarget: false
});
} else if (type === "ifelse") {
instance.addEndpoint(node, {
anchor: "Top",
...点击查看剩余70%
网友评论