From 950ee7e47b7ad86223ed961c4dd25dedc209bf74 Mon Sep 17 00:00:00 2001
From: Hhd <17835559578@163.com>
Date: Tue, 11 Mar 2025 17:56:42 +0800
Subject: [PATCH 1/2] =?UTF-8?q?=E3=80=90=E6=96=B0=E5=A2=9E=E5=8A=9F?=
=?UTF-8?q?=E8=83=BD=E3=80=91=E6=96=B0=E5=A2=9EDemo=E6=A8=A1=E5=9D=97?=
=?UTF-8?q?=EF=BC=8C=E5=AE=9E=E7=8E=B0=E4=BD=BF=E7=94=A8cdn=E5=BC=95?=
=?UTF-8?q?=E5=85=A5tinyflow=E4=B8=8E=E5=90=8E=E5=8F=B0=E7=9A=84=E5=AE=8C?=
=?UTF-8?q?=E6=95=B4=E4=BA=A4=E4=BA=92=E6=B5=81=E7=A8=8B?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
tinyflow-java-demo/demo_zh.md | 9 +
tinyflow-java-demo/pom.xml | 96 +++++++++
tinyflow-java-demo/sql/test-ai.sql | 41 ++++
.../com/tinyflow/demo/TestAiApplication.java | 15 ++
.../java/com/tinyflow/demo/common/Result.java | 22 ++
.../demo/controller/WorkFlowController.java | 50 +++++
.../demo/service/IWorkFlowService.java | 17 ++
.../service/impl/WorkFlowServiceImpl.java | 37 ++++
.../src/main/resources/application.yml | 9 +
.../src/main/resources/static/index.html | 73 +++++++
.../src/main/resources/static/workflow.html | 200 ++++++++++++++++++
11 files changed, 569 insertions(+)
create mode 100644 tinyflow-java-demo/demo_zh.md
create mode 100644 tinyflow-java-demo/pom.xml
create mode 100644 tinyflow-java-demo/sql/test-ai.sql
create mode 100644 tinyflow-java-demo/src/main/java/com/tinyflow/demo/TestAiApplication.java
create mode 100644 tinyflow-java-demo/src/main/java/com/tinyflow/demo/common/Result.java
create mode 100644 tinyflow-java-demo/src/main/java/com/tinyflow/demo/controller/WorkFlowController.java
create mode 100644 tinyflow-java-demo/src/main/java/com/tinyflow/demo/service/IWorkFlowService.java
create mode 100644 tinyflow-java-demo/src/main/java/com/tinyflow/demo/service/impl/WorkFlowServiceImpl.java
create mode 100644 tinyflow-java-demo/src/main/resources/application.yml
create mode 100644 tinyflow-java-demo/src/main/resources/static/index.html
create mode 100644 tinyflow-java-demo/src/main/resources/static/workflow.html
diff --git a/tinyflow-java-demo/demo_zh.md b/tinyflow-java-demo/demo_zh.md
new file mode 100644
index 0000000..8b247bf
--- /dev/null
+++ b/tinyflow-java-demo/demo_zh.md
@@ -0,0 +1,9 @@
+# Tinyflow-java-demo
+
+Tinyflow-java-demo 是一个使用Spring Boot开发的tinyflow-ai的Demo,实现了前后端的整体交互逻辑
+
+前端使用cdn引入,是一个前后端一体项目
+
+# 使用步骤
+1. 导入数据库文件
+2. 启动后直接访问http://127.0.0.1:8080即可
\ No newline at end of file
diff --git a/tinyflow-java-demo/pom.xml b/tinyflow-java-demo/pom.xml
new file mode 100644
index 0000000..0a91f10
--- /dev/null
+++ b/tinyflow-java-demo/pom.xml
@@ -0,0 +1,96 @@
+
+
+ 4.0.0
+ com.thrgoldyo.xeasywork
+ tinyflow-java-demo
+ 0.0.1-SNAPSHOT
+ tinyflow-java-demo
+ tinyflow-java-demo
+
+ 1.8
+ UTF-8
+ UTF-8
+ 2.6.13
+
+
+
+ org.springframework.boot
+ spring-boot-starter-data-jpa
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+
+ com.mysql
+ mysql-connector-j
+ runtime
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+ org.projectlombok
+ lombok
+ provided
+
+
+ dev.tinyflow
+ tinyflow-java
+ 0.0.1
+
+
+ com.agentsflex
+ agents-flex-bom
+ 1.0.0-rc.6
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-dependencies
+ ${spring-boot.version}
+ pom
+ import
+
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 3.8.1
+
+ 1.8
+ 1.8
+ UTF-8
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+ ${spring-boot.version}
+
+ com.tinyflow.demo.TinyflowJavaDemoApplication
+ true
+
+
+
+ repackage
+
+ repackage
+
+
+
+
+
+
+
+
diff --git a/tinyflow-java-demo/sql/test-ai.sql b/tinyflow-java-demo/sql/test-ai.sql
new file mode 100644
index 0000000..4c5a475
--- /dev/null
+++ b/tinyflow-java-demo/sql/test-ai.sql
@@ -0,0 +1,41 @@
+/*
+ Navicat Premium Data Transfer
+
+ Source Server : localhost
+ Source Server Type : MySQL
+ Source Server Version : 80033
+ Source Host : localhost:3306
+ Source Schema : test-ai
+
+ Target Server Type : MySQL
+ Target Server Version : 80033
+ File Encoding : 65001
+
+ Date: 11/03/2025 17:50:00
+*/
+
+SET NAMES utf8mb4;
+SET FOREIGN_KEY_CHECKS = 0;
+
+-- ----------------------------
+-- Table structure for workflows
+-- ----------------------------
+DROP TABLE IF EXISTS `workflows`;
+CREATE TABLE `workflows` (
+ `id` int(0) NOT NULL AUTO_INCREMENT,
+ `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
+ `app_id` int(0) NULL DEFAULT NULL,
+ `graph` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL,
+ PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 8 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;
+
+-- ----------------------------
+-- Records of workflows
+-- ----------------------------
+INSERT INTO `workflows` VALUES (1, '测试模型', 1, '{\"nodes\":[{\"id\":\"2\",\"type\":\"llmNode\",\"data\":{\"title\":\"大模型\",\"description\":\"处理大模型相关问题\",\"expand\":true,\"outputDefs\":[{\"id\":\"pyiig8ntGWZhVdVz\",\"dataType\":\"Object\",\"name\":\"param\",\"children\":[{\"id\":\"1\",\"name\":\"newParam1\",\"dataType\":\"String\"},{\"id\":\"2\",\"name\":\"newParam2\",\"dataType\":\"String\"}]}]},\"position\":{\"x\":550,\"y\":50},\"measured\":{\"width\":355,\"height\":687},\"selected\":false},{\"id\":\"3\",\"type\":\"startNode\",\"data\":{\"title\":\"开始节点\",\"description\":\"开始定义输入参数\",\"expand\":true},\"position\":{\"x\":115,\"y\":50},\"measured\":{\"width\":306,\"height\":200},\"selected\":false,\"dragging\":false},{\"id\":\"4\",\"type\":\"endNode\",\"data\":{\"title\":\"结束节点\",\"description\":\"结束定义输出参数\",\"expand\":true},\"position\":{\"x\":1156,\"y\":48},\"measured\":{\"width\":306,\"height\":200},\"selected\":true,\"dragging\":false}],\"viewport\":{\"x\":250,\"y\":100,\"zoom\":1},\"edges\":[{\"markerEnd\":{\"type\":\"arrowclosed\",\"width\":20,\"height\":20},\"source\":\"3\",\"target\":\"2\",\"id\":\"xy-edge__3-2\",\"selected\":false},{\"markerEnd\":{\"type\":\"arrowclosed\",\"width\":20,\"height\":20},\"source\":\"2\",\"target\":\"4\",\"id\":\"xy-edge__2-4\",\"selected\":false}]}');
+INSERT INTO `workflows` VALUES (2, 'test', 1, '{\"nodes\":[{\"id\":\"node_rovJujZGFnxF6rrM\",\"position\":{\"x\":80,\"y\":34},\"data\":{\"title\":\"开始节点\",\"description\":\"开始定义输入参数\"},\"type\":\"startNode\",\"selected\":false,\"measured\":{\"width\":306,\"height\":126}},{\"id\":\"node_YLO7yeEzpC25M3RG\",\"position\":{\"x\":919,\"y\":17},\"data\":{\"title\":\"结束节点\",\"description\":\"结束定义输出参数\"},\"type\":\"endNode\",\"selected\":false,\"measured\":{\"width\":306,\"height\":126}},{\"id\":\"node_fQPb4qDBl4VjcCMW\",\"position\":{\"x\":509,\"y\":32},\"data\":{\"title\":\"搜索引擎\",\"description\":\"通过搜索引擎搜索内容\",\"outputDefs\":[{\"name\":\"documents\",\"dataType\":\"Array\",\"nameDisabled\":true,\"dataTypeDisabled\":true,\"addChildDisabled\":true,\"children\":[{\"name\":\"title\",\"dataType\":\"String\",\"nameDisabled\":true,\"dataTypeDisabled\":true,\"id\":\"IF141xtLDoOg6uH8\"},{\"name\":\"content\",\"dataType\":\"String\",\"nameDisabled\":true,\"dataTypeDisabled\":true,\"id\":\"DGxm7RFOq2R8cyF6\"},{\"name\":\"documentId\",\"dataType\":\"Number\",\"nameDisabled\":true,\"dataTypeDisabled\":true,\"id\":\"1ZETL84STnkJeMPi\"},{\"name\":\"knowledgeId\",\"dataType\":\"Number\",\"nameDisabled\":true,\"dataTypeDisabled\":true,\"id\":\"E4OqcLEjtvDk76Hk\"}],\"id\":\"LEdA0XTx5bHrEaMf\"}]},\"type\":\"searchEngineNode\",\"selected\":false,\"measured\":{\"width\":306,\"height\":126},\"dragging\":false}],\"edges\":[],\"viewport\":{\"x\":250,\"y\":100,\"zoom\":1}}');
+INSERT INTO `workflows` VALUES (3, '测试输出', 1, '{\"nodes\":[{\"id\":\"node_82BjuWLD2POIHUF2\",\"position\":{\"x\":29,\"y\":174},\"data\":{\"title\":\"开始节点\",\"description\":\"开始定义输入参数\",\"expand\":true,\"parameters\":[{\"id\":\"g3qfdWpJAsAiHoZx\",\"name\":\"test\",\"required\":true},{\"id\":\"4yGuWCCRLSR7IU9o\",\"name\":\"a\",\"required\":true}]},\"type\":\"startNode\",\"selected\":false,\"measured\":{\"width\":306,\"height\":241},\"dragging\":false},{\"id\":\"node_XUwEBFWaJT6inhm3\",\"position\":{\"x\":513,\"y\":176},\"data\":{\"title\":\"结束节点\",\"description\":\"结束定义输出参数\",\"expand\":true,\"outputDefs\":[{\"id\":\"CNZ8dn2u62EqAGGP\",\"ref\":\"node_82BjuWLD2POIHUF2.test\",\"name\":\"test\"},{\"id\":\"PC2L4oNEerMxKHMx\",\"name\":\"aa\",\"ref\":\"node_82BjuWLD2POIHUF2.a\"}]},\"type\":\"endNode\",\"selected\":false,\"measured\":{\"width\":347,\"height\":241},\"dragging\":false}],\"edges\":[{\"markerEnd\":{\"type\":\"arrowclosed\",\"width\":20,\"height\":20},\"source\":\"node_82BjuWLD2POIHUF2\",\"target\":\"node_XUwEBFWaJT6inhm3\",\"id\":\"xy-edge__node_82BjuWLD2POIHUF2-node_XUwEBFWaJT6inhm3\",\"selected\":false}],\"viewport\":{\"x\":250,\"y\":100,\"zoom\":1}}');
+INSERT INTO `workflows` VALUES (7, 'test111', 1, '{\"nodes\":[{\"id\":\"node_yt0FdnTZcpx08fkg\",\"position\":{\"x\":-139,\"y\":104},\"data\":{\"title\":\"开始节点\",\"description\":\"开始定义输入参数\",\"expand\":true,\"parameters\":[{\"id\":\"qbYVQuFK8345rBl0\",\"name\":\"arr\",\"dataType\":\"Array\",\"required\":true}]},\"type\":\"startNode\",\"selected\":false,\"measured\":{\"width\":306,\"height\":209},\"dragging\":false},{\"id\":\"node_W0GdwxOZECvn4IiN\",\"position\":{\"x\":358,\"y\":105},\"data\":{\"title\":\"动态代码\",\"description\":\"动态执行代码\",\"expand\":true,\"engine\":\"groovy\",\"outputDefs\":[{\"id\":\"FBLNSiKI4PTNXuyn\",\"dataType\":\"Array\",\"name\":\"res\"}],\"parameters\":[{\"id\":\"u7tW4zSGrz1pfQnE\",\"name\":\"rows\",\"ref\":\"node_yt0FdnTZcpx08fkg.arr\"}],\"code\":\"// 获取最大列数\\n def maxColumns = rows*.size().max()\\n \\n // 创建一个新的列表存储列数据\\n def columns = (0..\\n rows.collect { it[idx] }\\n }\\n \\n return columns\"},\"type\":\"codeNode\",\"selected\":false,\"measured\":{\"width\":340,\"height\":589},\"dragging\":false},{\"id\":\"node_MYOX6bPCuYOlkkbm\",\"position\":{\"x\":788.789291416276,\"y\":105.7264251502344},\"data\":{\"title\":\"结束节点\",\"description\":\"结束定义输出参数\",\"expand\":true,\"outputDefs\":[{\"id\":\"9VvoSIplMZGBN3e6\",\"name\":\"输出\",\"ref\":\"node_W0GdwxOZECvn4IiN.res\"}]},\"type\":\"endNode\",\"selected\":true,\"measured\":{\"width\":342,\"height\":209},\"dragging\":false}],\"edges\":[{\"markerEnd\":{\"type\":\"arrowclosed\",\"width\":20,\"height\":20},\"source\":\"node_yt0FdnTZcpx08fkg\",\"target\":\"node_W0GdwxOZECvn4IiN\",\"id\":\"xy-edge__node_yt0FdnTZcpx08fkg-node_W0GdwxOZECvn4IiN\",\"selected\":false},{\"markerEnd\":{\"type\":\"arrowclosed\",\"width\":20,\"height\":20},\"source\":\"node_W0GdwxOZECvn4IiN\",\"target\":\"node_MYOX6bPCuYOlkkbm\",\"id\":\"xy-edge__node_W0GdwxOZECvn4IiN-node_MYOX6bPCuYOlkkbm\",\"selected\":false}],\"viewport\":{\"x\":474.67384867114697,\"y\":91.46615240660833,\"zoom\":1.3195079107728944}}');
+INSERT INTO `workflows` VALUES (8, '测试保存', 1, '{\"nodes\":[{\"id\":\"node_q294Rop7Y5Mn7kVS\",\"position\":{\"x\":-67,\"y\":30},\"data\":{\"title\":\"开始节点\",\"description\":\"开始定义输入参数\"},\"type\":\"startNode\",\"selected\":false,\"measured\":{\"width\":306,\"height\":126}},{\"id\":\"node_ljPC7bL85VsDR5GM\",\"position\":{\"x\":520,\"y\":59},\"data\":{\"title\":\"循环\",\"description\":\"用于循环执行任务\"},\"type\":\"loopNode\",\"selected\":false,\"measured\":{\"width\":306,\"height\":126},\"dragging\":false},{\"id\":\"node_6NkeJWpoAiVEeSfT\",\"position\":{\"x\":884,\"y\":64},\"data\":{\"title\":\"大模型\",\"description\":\"使用大模型处理问题\"},\"type\":\"llmNode\",\"selected\":false,\"measured\":{\"width\":306,\"height\":126},\"dragging\":false},{\"id\":\"node_Mu2UKDuvV3bKp8lL\",\"position\":{\"x\":1288,\"y\":256},\"data\":{\"title\":\"知识库\",\"description\":\"通过知识库获取内容\",\"outputDefs\":[{\"name\":\"documents\",\"dataType\":\"Array\",\"nameDisabled\":true,\"dataTypeDisabled\":true,\"addChildDisabled\":true,\"children\":[{\"name\":\"title\",\"dataType\":\"String\",\"nameDisabled\":true,\"dataTypeDisabled\":true,\"id\":\"AOZBWOsAeNCMWhWO\"},{\"name\":\"content\",\"dataType\":\"String\",\"nameDisabled\":true,\"dataTypeDisabled\":true,\"id\":\"XuqdUHlSy9m5JyaJ\"},{\"name\":\"documentId\",\"dataType\":\"Number\",\"nameDisabled\":true,\"dataTypeDisabled\":true,\"id\":\"hNtTHi5YI2IVnu3n\"},{\"name\":\"knowledgeId\",\"dataType\":\"Number\",\"nameDisabled\":true,\"dataTypeDisabled\":true,\"id\":\"1VnKZuMe8hKCpkGW\"}],\"id\":\"Q7ODTl3f9X2vGdH0\"}]},\"type\":\"knowledgeNode\",\"selected\":false,\"measured\":{\"width\":306,\"height\":126},\"dragging\":false},{\"id\":\"node_CzPf0au4aE3naghj\",\"position\":{\"x\":1426,\"y\":603},\"data\":{\"title\":\"结束节点\",\"description\":\"结束定义输出参数\"},\"type\":\"endNode\",\"selected\":true,\"measured\":{\"width\":306,\"height\":126},\"dragging\":false}],\"edges\":[{\"markerEnd\":{\"type\":\"arrowclosed\",\"width\":20,\"height\":20},\"source\":\"node_q294Rop7Y5Mn7kVS\",\"target\":\"node_ljPC7bL85VsDR5GM\",\"id\":\"xy-edge__node_q294Rop7Y5Mn7kVS-node_ljPC7bL85VsDR5GM\",\"selected\":false},{\"markerEnd\":{\"type\":\"arrowclosed\",\"width\":20,\"height\":20},\"source\":\"node_ljPC7bL85VsDR5GM\",\"target\":\"node_6NkeJWpoAiVEeSfT\",\"id\":\"xy-edge__node_ljPC7bL85VsDR5GM-node_6NkeJWpoAiVEeSfT\",\"selected\":false},{\"markerEnd\":{\"type\":\"arrowclosed\",\"width\":20,\"height\":20},\"source\":\"node_6NkeJWpoAiVEeSfT\",\"target\":\"node_Mu2UKDuvV3bKp8lL\",\"id\":\"xy-edge__node_6NkeJWpoAiVEeSfT-node_Mu2UKDuvV3bKp8lL\",\"selected\":false},{\"markerEnd\":{\"type\":\"arrowclosed\",\"width\":20,\"height\":20},\"source\":\"node_Mu2UKDuvV3bKp8lL\",\"target\":\"node_CzPf0au4aE3naghj\",\"id\":\"xy-edge__node_Mu2UKDuvV3bKp8lL-node_CzPf0au4aE3naghj\"}],\"viewport\":{\"x\":250,\"y\":100,\"zoom\":1}}');
+
+SET FOREIGN_KEY_CHECKS = 1;
diff --git a/tinyflow-java-demo/src/main/java/com/tinyflow/demo/TestAiApplication.java b/tinyflow-java-demo/src/main/java/com/tinyflow/demo/TestAiApplication.java
new file mode 100644
index 0000000..5007da1
--- /dev/null
+++ b/tinyflow-java-demo/src/main/java/com/tinyflow/demo/TestAiApplication.java
@@ -0,0 +1,15 @@
+package com.tinyflow.demo;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+import javax.annotation.PostConstruct;
+
+@SpringBootApplication
+public class TestAiApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(TestAiApplication.class, args);
+ }
+
+}
diff --git a/tinyflow-java-demo/src/main/java/com/tinyflow/demo/common/Result.java b/tinyflow-java-demo/src/main/java/com/tinyflow/demo/common/Result.java
new file mode 100644
index 0000000..95708ba
--- /dev/null
+++ b/tinyflow-java-demo/src/main/java/com/tinyflow/demo/common/Result.java
@@ -0,0 +1,22 @@
+package com.tinyflow.demo.common;
+
+public class Result {
+
+ private final Integer code;
+ private final String msg;
+ private final Object data;
+
+ public Result(int code, String msg, Object data) {
+ this.code = code;
+ this.msg = msg;
+ this.data = data;
+ }
+
+ public static Result success(Object data) {
+ return new Result(200, "成功", data);
+ }
+
+ public static Result success() {
+ return success(null);
+ }
+}
diff --git a/tinyflow-java-demo/src/main/java/com/tinyflow/demo/controller/WorkFlowController.java b/tinyflow-java-demo/src/main/java/com/tinyflow/demo/controller/WorkFlowController.java
new file mode 100644
index 0000000..51b2158
--- /dev/null
+++ b/tinyflow-java-demo/src/main/java/com/tinyflow/demo/controller/WorkFlowController.java
@@ -0,0 +1,50 @@
+package com.tinyflow.demo.controller;
+
+import com.alibaba.fastjson.JSONObject;
+import com.tinyflow.demo.service.IWorkFlowService;
+import dev.tinyflow.core.Tinyflow;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.*;
+
+import javax.annotation.Resource;
+import java.util.List;
+import java.util.Map;
+
+@Controller
+@CrossOrigin
+public class WorkFlowController {
+
+ @Resource
+ private IWorkFlowService workFlowService;
+
+ @PostMapping("/workflow/save")
+ public ResponseEntity save(@RequestBody JSONObject wf) {
+ if (wf.containsKey("id") && wf.getString("id") != null && !"".equals(wf.getString("id"))) {
+ workFlowService.update(wf);
+ } else {
+ workFlowService.save(wf);
+ }
+ return new ResponseEntity<>("Success", HttpStatus.OK);
+ }
+
+ @GetMapping("/workflow/get")
+ public ResponseEntity