From 8954f59cd7b846c2a4c57f1e1d796b305f2da56f Mon Sep 17 00:00:00 2001
From: zengxb <648669796@qq.com>
Date: Thu, 26 Feb 2026 14:36:33 +0800
Subject: [PATCH] =?UTF-8?q?context:=E5=B7=A5=E4=BD=9C=E6=B5=81=E5=92=8CAi?=
=?UTF-8?q?=20Chat=E5=AF=B9=E8=AF=9D=E6=B6=88=E6=81=AF=E5=8A=9F=E8=83=BD?=
=?UTF-8?q?=E6=95=B4=E5=90=88?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
docs/script/sql/ruoyi-ai-v3_mysql8.sql | 14 ++
docs/script/sql/workFlow-v3.0.sql | 10 --
ruoyi-common/ruoyi-common-chat/pom.xml | 6 +
.../common/chat}/base/ThreadContext.java | 8 +-
.../chat}/domain/bo/chat/ChatMessageBo.java | 13 +-
.../chat/domain/bo/chat/ChatModelBo.java | 2 +-
.../chat/domain/dto/request/ChatRequest.java | 20 +++
.../chat/domain/dto/request/ReSumeRunner.java | 19 +++
.../domain/dto/request/WorkFlowRunner.java | 15 ++
.../chat}/domain/vo/chat/ChatMessageVo.java | 9 +-
.../chat/domain/vo/chat/ChatModelVo.java | 2 +-
.../ruoyi/common/chat}/entity/BaseEntity.java | 2 +-
.../org/ruoyi/common/chat}/entity/User.java | 4 +-
.../{domain => }/entity/chat/ChatContext.java | 2 +-
.../common/chat}/entity/chat/ChatMessage.java | 7 +-
.../{domain => }/entity/chat/ChatModel.java | 2 +-
.../entity/image/ImageContext.java | 2 +-
.../ruoyi/common/chat}/enums/BaseEnum.java | 2 +-
.../ruoyi/common/chat}/enums/ErrorEnum.java | 2 +-
.../ruoyi/common/chat}/enums/RoleType.java | 3 +-
.../common/chat}/enums/UserStatusEnum.java | 2 +-
.../chat/factory/ChatServiceFactory.java | 2 +-
.../chat/factory/ImageServiceFactory.java | 2 +-
.../chat}/IChatModelService.java | 2 +-
.../chat}/IChatService.java | 4 +-
.../AbstractChatMessageService.java | 59 ++++++++
.../chatMessage}/IChatMessageService.java | 6 +-
.../image}/IImageGenerationService.java | 4 +-
.../workFlow/IWorkFlowStarterService.java | 33 +++++
.../common/sse/core/SseEmitterManager.java | 2 +-
ruoyi-modules/ruoyi-aiflow/pom.xml | 6 -
.../org/ruoyi/workflow/base/BaseResponse.java | 2 +-
.../controller/WorkflowController.java | 4 +-
.../controller/WorkflowRuntimeController.java | 2 +-
.../dto/workflow/WorkflowResumeReq.java | 2 +
.../workflow/dto/workflow/WorkflowRunReq.java | 1 +
.../org/ruoyi/workflow/entity/Workflow.java | 1 +
.../workflow/entity/WorkflowComponent.java | 1 +
.../ruoyi/workflow/entity/WorkflowEdge.java | 1 +
.../ruoyi/workflow/entity/WorkflowNode.java | 1 +
.../workflow/entity/WorkflowRuntime.java | 1 +
.../workflow/entity/WorkflowRuntimeNode.java | 1 +
.../ruoyi/workflow/enums/AiModelStatus.java | 1 +
.../workflow/enums/WfIODataTypeEnum.java | 1 +
.../workflow/helper/SSEEmitterHelper.java | 2 +-
.../service/WorkflowComponentService.java | 4 +-
.../workflow/service/WorkflowEdgeService.java | 2 +-
.../workflow/service/WorkflowNodeService.java | 2 +-
.../service/WorkflowRuntimeNodeService.java | 4 +-
.../service/WorkflowRuntimeService.java | 6 +-
.../workflow/service/WorkflowService.java | 6 +-
.../ruoyi/workflow/util/PrivilegeUtil.java | 4 +-
.../workflow/util/WorkflowMessageUtil.java | 37 +++++
.../workflow/workflow/WfNodeIODataUtil.java | 2 +-
.../org/ruoyi/workflow/workflow/WfState.java | 6 +-
.../workflow/workflow/WorkflowEngine.java | 21 ++-
.../workflow/WorkflowGraphBuilder.java | 2 +-
.../workflow/workflow/WorkflowStarter.java | 27 ++--
.../ruoyi/workflow/workflow/WorkflowUtil.java | 66 +++++----
.../workflow/node/AbstractWfNode.java | 30 +++-
.../node/httpRequest/HttpRequestNode.java | 10 ++
.../node/humanFeedBack/HumanFeedbackNode.java | 1 +
.../workflow/node/image/ImageNode.java | 5 +
.../workflow/node/mailSend/MailSendNode.java | 138 ++++++++++++------
.../workflow/node/start/StartNode.java | 4 +-
.../chat/ChatMessageController.java | 6 +-
.../controller/chat/ChatModelController.java | 2 +-
.../ruoyi/factory/EmbeddingModelFactory.java | 2 +-
.../ruoyi/mapper/chat/ChatMessageMapper.java | 4 +-
.../ruoyi/mapper/chat/ChatModelMapper.java | 2 +-
.../impl/AbstractStreamingChatService.java | 91 ++++++------
.../chat/impl/ChatMessageServiceImpl.java | 8 +-
.../chat/impl/ChatModelServiceImpl.java | 4 +-
.../service/chat/impl/ChatServiceFacade.java | 7 +-
.../impl/memory/ChatMemoryUsageExample.java | 2 +-
.../memory/PersistentChatMemoryStore.java | 2 +-
.../impl/GraphExtractionServiceImpl.java | 2 +-
.../image/AbstractImageGenerationService.java | 4 +-
.../impl/KnowledgeAttachServiceImpl.java | 2 +-
79 files changed, 548 insertions(+), 254 deletions(-)
delete mode 100644 docs/script/sql/workFlow-v3.0.sql
rename {ruoyi-modules/ruoyi-aiflow/src/main/java/org/ruoyi/workflow => ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat}/base/ThreadContext.java (94%)
rename {ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi => ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat}/domain/bo/chat/ChatMessageBo.java (90%)
create mode 100644 ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/domain/dto/request/ReSumeRunner.java
create mode 100644 ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/domain/dto/request/WorkFlowRunner.java
rename {ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi => ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat}/domain/vo/chat/ChatMessageVo.java (94%)
rename {ruoyi-modules/ruoyi-aiflow/src/main/java/org/ruoyi/workflow => ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat}/entity/BaseEntity.java (95%)
rename {ruoyi-modules/ruoyi-aiflow/src/main/java/org/ruoyi/workflow => ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat}/entity/User.java (95%)
rename ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/{domain => }/entity/chat/ChatContext.java (96%)
rename {ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/domain => ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat}/entity/chat/ChatMessage.java (87%)
rename ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/{domain => }/entity/chat/ChatModel.java (96%)
rename ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/{domain => }/entity/image/ImageContext.java (94%)
rename {ruoyi-modules/ruoyi-aiflow/src/main/java/org/ruoyi/workflow => ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat}/enums/BaseEnum.java (84%)
rename {ruoyi-modules/ruoyi-aiflow/src/main/java/org/ruoyi/workflow => ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat}/enums/ErrorEnum.java (99%)
rename {ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi => ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat}/enums/RoleType.java (84%)
rename {ruoyi-modules/ruoyi-aiflow/src/main/java/org/ruoyi/workflow => ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat}/enums/UserStatusEnum.java (93%)
rename ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/{Service => service/chat}/IChatModelService.java (97%)
rename ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/{Service => service/chat}/IChatService.java (79%)
create mode 100644 ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/service/chatMessage/AbstractChatMessageService.java
rename {ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/service/chat => ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/service/chatMessage}/IChatMessageService.java (92%)
rename ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/{Service => service/image}/IImageGenerationService.java (74%)
create mode 100644 ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/service/workFlow/IWorkFlowStarterService.java
create mode 100644 ruoyi-modules/ruoyi-aiflow/src/main/java/org/ruoyi/workflow/util/WorkflowMessageUtil.java
diff --git a/docs/script/sql/ruoyi-ai-v3_mysql8.sql b/docs/script/sql/ruoyi-ai-v3_mysql8.sql
index e7aec981..6d85a2ef 100644
--- a/docs/script/sql/ruoyi-ai-v3_mysql8.sql
+++ b/docs/script/sql/ruoyi-ai-v3_mysql8.sql
@@ -3647,3 +3647,17 @@ INSERT INTO `test_tree` VALUES (12, '000000', 10, 108, 3, '子节点88', 0, 103,
INSERT INTO `test_tree` VALUES (13, '000000', 10, 108, 3, '子节点99', 0, 103, '2026-02-03 05:14:54', 1, NULL, NULL, 0);
SET FOREIGN_KEY_CHECKS = 1;
+
+INSERT INTO `t_workflow_component` (`id`, `uuid`, `name`, `title`, `remark`, `display_order`, `is_enable`, `create_time`, `update_time`, `is_deleted`, `tenant_id`) VALUES (17, '5cd68dccbbb411f0bb7840c2ba9a7fbc', 'Start', '开始', '流程由此开始', 0, 1, '2025-11-07 16:32:49', '2025-11-07 16:32:49', 0, '000000');
+INSERT INTO `t_workflow_component` (`id`, `uuid`, `name`, `title`, `remark`, `display_order`, `is_enable`, `create_time`, `update_time`, `is_deleted`, `tenant_id`) VALUES (18, '5cd6ac69bbb411f0bb7840c2ba9a7fbc', 'End', '结束', '流程由此结束', 0, 1, '2025-11-07 16:32:49', '2025-11-07 16:32:49', 0, '000000');
+INSERT INTO `t_workflow_component` (`id`, `uuid`, `name`, `title`, `remark`, `display_order`, `is_enable`, `create_time`, `update_time`, `is_deleted`, `tenant_id`) VALUES (19, '5cd6c8eabbb411f0bb7840c2ba9a7fbc', 'Answer', '生成回答', '调用大语言模型回答问题', 0, 1, '2025-11-07 16:32:49', '2025-11-07 16:32:49', 0, '000000');
+INSERT INTO `t_workflow_component` (`id`, `uuid`, `name`, `title`, `remark`, `display_order`, `is_enable`, `create_time`, `update_time`, `is_deleted`, `tenant_id`) VALUES (20, '0b4369bb60dc46d6bd84ceb4e36184dc', 'KeywordExtractor', '关键词提取', '从文本中提取关键词', 0, 1, '2025-12-26 16:30:05', '2025-12-26 16:30:05', 0, '000000');
+INSERT INTO `t_workflow_component` (`id`, `uuid`, `name`, `title`, `remark`, `display_order`, `is_enable`, `create_time`, `update_time`, `is_deleted`, `tenant_id`) VALUES (21, 'bb00fc2f52c74fec82ee3f99725b56bb', 'Switcher', '条件分支', '根据条件执行不同分支', 0, 1, '2025-12-26 16:30:46', '2025-12-26 16:30:46', 0, '000000');
+INSERT INTO `t_workflow_component` (`id`, `uuid`, `name`, `title`, `remark`, `display_order`, `is_enable`, `create_time`, `update_time`, `is_deleted`, `tenant_id`) VALUES (22, 'f37dbcb8f0d5464d90fbb22774490a56', 'HumanFeedback', '人类', '人机沟通', 0, 1, '2025-12-30 17:37:14', '2025-12-30 17:37:14', 0, '000000');
+INSERT INTO `t_workflow_component` (`id`, `uuid`, `name`, `title`, `remark`, `display_order`, `is_enable`, `create_time`, `update_time`, `is_deleted`, `tenant_id`) VALUES (23, 'af9d6d7b9c9b47f990ad25ec84912b73', 'Tongyiwanx', '阿里图像生成', '使用通义万相生成图像', 0, 1, '2025-12-26 16:32:25', '2025-12-26 16:32:25', 0, '000000');
+INSERT INTO `t_workflow_component` (`id`, `uuid`, `name`, `title`, `remark`, `display_order`, `is_enable`, `create_time`, `update_time`, `is_deleted`, `tenant_id`) VALUES (24, 'a1e2c9d4b8f04e1a9c3d6f8e2a7b1c9d', 'MailSend', '发送邮箱', '发送邮箱', 0, 1, '2025-12-30 17:37:14', '2025-12-30 17:37:14', 0, '000000');
+INSERT INTO `t_workflow_component` (`id`, `uuid`, `name`, `title`, `remark`, `display_order`, `is_enable`, `create_time`, `update_time`, `is_deleted`, `tenant_id`) VALUES (25, 'f1e2d3c4b5a67890f1e2d3c4b5a6f1e2', 'HttpRequest', '请求节点', '请求节点', 0, 1, '2025-12-30 17:37:14', '2025-12-30 17:37:14', 0, '000000');
+INSERT INTO `chat_model` (`id`, `category`, `model_name`, `provider_code`, `model_describe`, `model_price`, `model_type`, `model_show`, `model_free`, `priority`, `api_host`, `api_key`, `create_dept`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`, `tenant_id`) VALUES (2022565766560468994, 'Tongyiwanx', 'wan2.5-t2i-preview', 'Tongyiwanx', 'wan2.5-t2i-preview', 1, '1', 'Y', 'Y', 1, 'https://dashscope.aliyuncs.com/api/v1/services/aigc/multimodal-generation/generation', 'skxxxx', 103, 1, '2026-02-14 14:57:11', 1, '2026-02-14 14:57:11', '通义万相文生图', 0);
+INSERT INTO `sys_menu` (`menu_id`, `menu_name`, `parent_id`, `order_num`, `path`, `component`, `query_param`, `is_frame`, `is_cache`, `menu_type`, `visible`, `status`, `perms`, `icon`, `create_dept`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (2021046920636690433, '流程管理', 0, 0, 'flow', '', NULL, 1, 0, 'M', '0', '0', NULL, 'ph:user-fill', 103, 1, '2026-02-10 10:21:50', 1, '2026-02-10 15:59:28', '');
+INSERT INTO `sys_menu` (`menu_id`, `menu_name`, `parent_id`, `order_num`, `path`, `component`, `query_param`, `is_frame`, `is_cache`, `menu_type`, `visible`, `status`, `perms`, `icon`, `create_dept`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (2021047050391678978, '工作流编排', 2021046920636690433, 0, 'aiflowengine', 'aiflow/index', NULL, 1, 0, 'C', '0', '0', '', 'ph:user-fill', 103, 1, '2026-02-10 10:22:21', 1, '2026-02-10 16:04:41', '');
+
diff --git a/docs/script/sql/workFlow-v3.0.sql b/docs/script/sql/workFlow-v3.0.sql
deleted file mode 100644
index f7573338..00000000
--- a/docs/script/sql/workFlow-v3.0.sql
+++ /dev/null
@@ -1,10 +0,0 @@
-INSERT INTO `ruoyi-ai-v3`.`t_workflow_component` (`id`, `uuid`, `name`, `title`, `remark`, `display_order`, `is_enable`, `create_time`, `update_time`, `is_deleted`, `tenant_id`) VALUES (17, '5cd68dccbbb411f0bb7840c2ba9a7fbc', 'Start', '开始', '流程由此开始', 0, 1, '2025-11-07 16:32:49', '2025-11-07 16:32:49', 0, '000000');
-INSERT INTO `ruoyi-ai-v3`.`t_workflow_component` (`id`, `uuid`, `name`, `title`, `remark`, `display_order`, `is_enable`, `create_time`, `update_time`, `is_deleted`, `tenant_id`) VALUES (18, '5cd6ac69bbb411f0bb7840c2ba9a7fbc', 'End', '结束', '流程由此结束', 0, 1, '2025-11-07 16:32:49', '2025-11-07 16:32:49', 0, '000000');
-INSERT INTO `ruoyi-ai-v3`.`t_workflow_component` (`id`, `uuid`, `name`, `title`, `remark`, `display_order`, `is_enable`, `create_time`, `update_time`, `is_deleted`, `tenant_id`) VALUES (19, '5cd6c8eabbb411f0bb7840c2ba9a7fbc', 'Answer', '生成回答', '调用大语言模型回答问题', 0, 1, '2025-11-07 16:32:49', '2025-11-07 16:32:49', 0, '000000');
-INSERT INTO `ruoyi-ai-v3`.`t_workflow_component` (`id`, `uuid`, `name`, `title`, `remark`, `display_order`, `is_enable`, `create_time`, `update_time`, `is_deleted`, `tenant_id`) VALUES (20, '0b4369bb60dc46d6bd84ceb4e36184dc', 'KeywordExtractor', '关键词提取', '从文本中提取关键词', 0, 1, '2025-12-26 16:30:05', '2025-12-26 16:30:05', 0, '000000');
-INSERT INTO `ruoyi-ai-v3`.`t_workflow_component` (`id`, `uuid`, `name`, `title`, `remark`, `display_order`, `is_enable`, `create_time`, `update_time`, `is_deleted`, `tenant_id`) VALUES (21, 'bb00fc2f52c74fec82ee3f99725b56bb', 'Switcher', '条件分支', '根据条件执行不同分支', 0, 1, '2025-12-26 16:30:46', '2025-12-26 16:30:46', 0, '000000');
-INSERT INTO `ruoyi-ai-v3`.`t_workflow_component` (`id`, `uuid`, `name`, `title`, `remark`, `display_order`, `is_enable`, `create_time`, `update_time`, `is_deleted`, `tenant_id`) VALUES (22, 'f37dbcb8f0d5464d90fbb22774490a56', 'HumanFeedback', '人类', '人机沟通', 0, 1, '2025-12-30 17:37:14', '2025-12-30 17:37:14', 0, '000000');
-INSERT INTO `ruoyi-ai-v3`.`t_workflow_component` (`id`, `uuid`, `name`, `title`, `remark`, `display_order`, `is_enable`, `create_time`, `update_time`, `is_deleted`, `tenant_id`) VALUES (23, 'af9d6d7b9c9b47f990ad25ec84912b73', 'Tongyiwanx', '阿里图像生成', '使用通义万相生成图像', 0, 1, '2025-12-26 16:32:25', '2025-12-26 16:32:25', 0, '000000');
-INSERT INTO `ruoyi-ai-v3`.`t_workflow_component` (`id`, `uuid`, `name`, `title`, `remark`, `display_order`, `is_enable`, `create_time`, `update_time`, `is_deleted`, `tenant_id`) VALUES (24, 'a1e2c9d4b8f04e1a9c3d6f8e2a7b1c9d', 'MailSend', '发送邮箱', '发送邮箱', 0, 1, '2025-12-30 17:37:14', '2025-12-30 17:37:14', 0, '000000');
-INSERT INTO `ruoyi-ai-v3`.`t_workflow_component` (`id`, `uuid`, `name`, `title`, `remark`, `display_order`, `is_enable`, `create_time`, `update_time`, `is_deleted`, `tenant_id`) VALUES (25, 'f1e2d3c4b5a67890f1e2d3c4b5a6f1e2', 'HttpRequest', '请求节点', '请求节点', 0, 1, '2025-12-30 17:37:14', '2025-12-30 17:37:14', 0, '000000');
-INSERT INTO `ruoyi-ai-v3`.`chat_model` (`id`, `category`, `model_name`, `provider_code`, `model_describe`, `model_price`, `model_type`, `model_show`, `model_free`, `priority`, `api_host`, `api_key`, `create_dept`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`, `tenant_id`) VALUES (2022565766560468994, 'Tongyiwanx', 'wan2.5-t2i-preview', 'Tongyiwanx', 'wan2.5-t2i-preview', 1, '1', 'Y', 'Y', 1, 'https://dashscope.aliyuncs.com/api/v1/services/aigc/multimodal-generation/generation', 'Bearer sk-f4550b0e138c488cbfcafe3d61f800a5', 103, 1, '2026-02-14 14:57:11', 1, '2026-02-14 14:57:11', '通义万相文生图', 0);
diff --git a/ruoyi-common/ruoyi-common-chat/pom.xml b/ruoyi-common/ruoyi-common-chat/pom.xml
index 0db3c41c..06e38185 100644
--- a/ruoyi-common/ruoyi-common-chat/pom.xml
+++ b/ruoyi-common/ruoyi-common-chat/pom.xml
@@ -62,6 +62,12 @@
org.ruoyi
ruoyi-common-tenant
+
+
+ io.swagger.core.v3
+ swagger-annotations
+ ${swagger-annotations.version}
+
diff --git a/ruoyi-modules/ruoyi-aiflow/src/main/java/org/ruoyi/workflow/base/ThreadContext.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/base/ThreadContext.java
similarity index 94%
rename from ruoyi-modules/ruoyi-aiflow/src/main/java/org/ruoyi/workflow/base/ThreadContext.java
rename to ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/base/ThreadContext.java
index d74eb104..7605307d 100644
--- a/ruoyi-modules/ruoyi-aiflow/src/main/java/org/ruoyi/workflow/base/ThreadContext.java
+++ b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/base/ThreadContext.java
@@ -1,14 +1,14 @@
-package org.ruoyi.workflow.base;
+package org.ruoyi.common.chat.base;
import cn.dev33.satoken.stp.StpUtil;
import org.apache.commons.lang3.StringUtils;
+import org.ruoyi.common.chat.entity.User;
+import org.ruoyi.common.chat.enums.UserStatusEnum;
import org.ruoyi.common.core.domain.model.LoginUser;
import org.ruoyi.common.core.exception.base.BaseException;
import org.ruoyi.common.satoken.utils.LoginHelper;
-import org.ruoyi.workflow.entity.User;
-import org.ruoyi.workflow.enums.UserStatusEnum;
-import static org.ruoyi.workflow.enums.ErrorEnum.A_USER_NOT_FOUND;
+import static org.ruoyi.common.chat.enums.ErrorEnum.A_USER_NOT_FOUND;
/**
* 线程上下文适配器,统一接入 Sa-Token 登录态。
diff --git a/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/domain/bo/chat/ChatMessageBo.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/domain/bo/chat/ChatMessageBo.java
similarity index 90%
rename from ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/domain/bo/chat/ChatMessageBo.java
rename to ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/domain/bo/chat/ChatMessageBo.java
index 9d44fcaa..2cbb051b 100644
--- a/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/domain/bo/chat/ChatMessageBo.java
+++ b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/domain/bo/chat/ChatMessageBo.java
@@ -1,13 +1,14 @@
-package org.ruoyi.domain.bo.chat;
+package org.ruoyi.common.chat.domain.bo.chat;
-import org.ruoyi.common.core.validate.AddGroup;
-import org.ruoyi.common.core.validate.EditGroup;
-import org.ruoyi.domain.entity.chat.ChatMessage;
-import org.ruoyi.common.mybatis.core.domain.BaseEntity;
import io.github.linpeilie.annotations.AutoMapper;
+import jakarta.validation.constraints.NotNull;
import lombok.Data;
import lombok.EqualsAndHashCode;
-import jakarta.validation.constraints.*;
+import org.ruoyi.common.chat.entity.chat.ChatMessage;
+import org.ruoyi.common.core.validate.AddGroup;
+import org.ruoyi.common.core.validate.EditGroup;
+import org.ruoyi.common.mybatis.core.domain.BaseEntity;
+
/**
* 聊天消息业务对象 chat_message
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/domain/bo/chat/ChatModelBo.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/domain/bo/chat/ChatModelBo.java
index 8807503c..4d97dd05 100644
--- a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/domain/bo/chat/ChatModelBo.java
+++ b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/domain/bo/chat/ChatModelBo.java
@@ -4,7 +4,7 @@ import io.github.linpeilie.annotations.AutoMapper;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import lombok.EqualsAndHashCode;
-import org.ruoyi.common.chat.domain.entity.chat.ChatModel;
+import org.ruoyi.common.chat.entity.chat.ChatModel;
import org.ruoyi.common.core.validate.EditGroup;
import org.ruoyi.common.mybatis.core.domain.BaseEntity;
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/domain/dto/request/ChatRequest.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/domain/dto/request/ChatRequest.java
index 1b36ae42..8d13339e 100644
--- a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/domain/dto/request/ChatRequest.java
+++ b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/domain/dto/request/ChatRequest.java
@@ -21,6 +21,21 @@ public class ChatRequest {
@NotEmpty(message = "传入的模型不能为空")
private String model;
+ /**
+ * 工作流请求体
+ */
+ private WorkFlowRunner workFlowRunner;
+
+ /**
+ * 人机交互信息体
+ */
+ private ReSumeRunner reSumeRunner;
+
+ /**
+ * 是否启用工作流
+ */
+ private Boolean enableWorkFlow;
+
/**
* 会话id
*/
@@ -41,6 +56,11 @@ public class ChatRequest {
*/
private Long uuid;
+ /**
+ * 是否为人机交互用户继续输入
+ */
+ private Boolean isResume;
+
/**
* 是否启用深度思考
*/
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/domain/dto/request/ReSumeRunner.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/domain/dto/request/ReSumeRunner.java
new file mode 100644
index 00000000..65b39fd0
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/domain/dto/request/ReSumeRunner.java
@@ -0,0 +1,19 @@
+package org.ruoyi.common.chat.domain.dto.request;
+
+import lombok.Data;
+
+/**
+ * 人机交互输入信息
+ */
+@Data
+public class ReSumeRunner {
+ /**
+ * 运行节点UUID
+ */
+ private String runtimeUuid;
+
+ /**
+ * 人机交互用户输入信息
+ */
+ private String feedbackContent;
+}
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/domain/dto/request/WorkFlowRunner.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/domain/dto/request/WorkFlowRunner.java
new file mode 100644
index 00000000..fff727ec
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/domain/dto/request/WorkFlowRunner.java
@@ -0,0 +1,15 @@
+package org.ruoyi.common.chat.domain.dto.request;
+
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * 工作流请求体信息
+ */
+@Data
+public class WorkFlowRunner {
+ private List inputs;
+ private String uuid;
+}
diff --git a/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/domain/vo/chat/ChatMessageVo.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/domain/vo/chat/ChatMessageVo.java
similarity index 94%
rename from ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/domain/vo/chat/ChatMessageVo.java
rename to ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/domain/vo/chat/ChatMessageVo.java
index 7a548865..17f4d707 100644
--- a/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/domain/vo/chat/ChatMessageVo.java
+++ b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/domain/vo/chat/ChatMessageVo.java
@@ -1,18 +1,17 @@
-package org.ruoyi.domain.vo.chat;
+package org.ruoyi.common.chat.domain.vo.chat;
-import org.ruoyi.domain.entity.chat.ChatMessage;
import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
import cn.idev.excel.annotation.ExcelProperty;
-import org.ruoyi.common.excel.annotation.ExcelDictFormat;
-import org.ruoyi.common.excel.convert.ExcelDictConvert;
import io.github.linpeilie.annotations.AutoMapper;
import lombok.Data;
+import org.ruoyi.common.chat.entity.chat.ChatMessage;
+import org.ruoyi.common.excel.annotation.ExcelDictFormat;
+import org.ruoyi.common.excel.convert.ExcelDictConvert;
import java.io.Serial;
import java.io.Serializable;
-
/**
* 聊天消息视图对象 chat_message
*
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/domain/vo/chat/ChatModelVo.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/domain/vo/chat/ChatModelVo.java
index 77ba3328..f79f9f23 100644
--- a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/domain/vo/chat/ChatModelVo.java
+++ b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/domain/vo/chat/ChatModelVo.java
@@ -5,7 +5,7 @@ import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
import cn.idev.excel.annotation.ExcelProperty;
import io.github.linpeilie.annotations.AutoMapper;
import lombok.Data;
-import org.ruoyi.common.chat.domain.entity.chat.ChatModel;
+import org.ruoyi.common.chat.entity.chat.ChatModel;
import java.io.Serial;
import java.io.Serializable;
diff --git a/ruoyi-modules/ruoyi-aiflow/src/main/java/org/ruoyi/workflow/entity/BaseEntity.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/BaseEntity.java
similarity index 95%
rename from ruoyi-modules/ruoyi-aiflow/src/main/java/org/ruoyi/workflow/entity/BaseEntity.java
rename to ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/BaseEntity.java
index b657eb16..e9630ff2 100644
--- a/ruoyi-modules/ruoyi-aiflow/src/main/java/org/ruoyi/workflow/entity/BaseEntity.java
+++ b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/BaseEntity.java
@@ -1,4 +1,4 @@
-package org.ruoyi.workflow.entity;
+package org.ruoyi.common.chat.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
diff --git a/ruoyi-modules/ruoyi-aiflow/src/main/java/org/ruoyi/workflow/entity/User.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/User.java
similarity index 95%
rename from ruoyi-modules/ruoyi-aiflow/src/main/java/org/ruoyi/workflow/entity/User.java
rename to ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/User.java
index 20ac4dc0..dadedf9a 100644
--- a/ruoyi-modules/ruoyi-aiflow/src/main/java/org/ruoyi/workflow/entity/User.java
+++ b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/User.java
@@ -1,11 +1,11 @@
-package org.ruoyi.workflow.entity;
+package org.ruoyi.common.chat.entity;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
-import org.ruoyi.workflow.enums.UserStatusEnum;
+import org.ruoyi.common.chat.enums.UserStatusEnum;
import java.time.LocalDateTime;
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/domain/entity/chat/ChatContext.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/chat/ChatContext.java
similarity index 96%
rename from ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/domain/entity/chat/ChatContext.java
rename to ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/chat/ChatContext.java
index 13a5b4b9..f90abd82 100644
--- a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/domain/entity/chat/ChatContext.java
+++ b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/chat/ChatContext.java
@@ -1,4 +1,4 @@
-package org.ruoyi.common.chat.domain.entity.chat;
+package org.ruoyi.common.chat.entity.chat;
import dev.langchain4j.model.chat.response.StreamingChatResponseHandler;
import jakarta.validation.constraints.NotNull;
diff --git a/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/domain/entity/chat/ChatMessage.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/chat/ChatMessage.java
similarity index 87%
rename from ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/domain/entity/chat/ChatMessage.java
rename to ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/chat/ChatMessage.java
index 905f74fb..c0055bd4 100644
--- a/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/domain/entity/chat/ChatMessage.java
+++ b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/chat/ChatMessage.java
@@ -1,9 +1,10 @@
-package org.ruoyi.domain.entity.chat;
+package org.ruoyi.common.chat.entity.chat;
-import org.ruoyi.common.tenant.core.TenantEntity;
-import com.baomidou.mybatisplus.annotation.*;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.EqualsAndHashCode;
+import org.ruoyi.common.tenant.core.TenantEntity;
import java.io.Serial;
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/domain/entity/chat/ChatModel.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/chat/ChatModel.java
similarity index 96%
rename from ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/domain/entity/chat/ChatModel.java
rename to ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/chat/ChatModel.java
index 9edee32f..4fc63bfd 100644
--- a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/domain/entity/chat/ChatModel.java
+++ b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/chat/ChatModel.java
@@ -1,4 +1,4 @@
-package org.ruoyi.common.chat.domain.entity.chat;
+package org.ruoyi.common.chat.entity.chat;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/domain/entity/image/ImageContext.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/image/ImageContext.java
similarity index 94%
rename from ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/domain/entity/image/ImageContext.java
rename to ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/image/ImageContext.java
index 4bf42c61..60be2739 100644
--- a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/domain/entity/image/ImageContext.java
+++ b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/image/ImageContext.java
@@ -1,4 +1,4 @@
-package org.ruoyi.common.chat.domain.entity.image;
+package org.ruoyi.common.chat.entity.image;
import jakarta.validation.constraints.Max;
import jakarta.validation.constraints.Min;
diff --git a/ruoyi-modules/ruoyi-aiflow/src/main/java/org/ruoyi/workflow/enums/BaseEnum.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/enums/BaseEnum.java
similarity index 84%
rename from ruoyi-modules/ruoyi-aiflow/src/main/java/org/ruoyi/workflow/enums/BaseEnum.java
rename to ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/enums/BaseEnum.java
index 66a2fb63..902adf45 100644
--- a/ruoyi-modules/ruoyi-aiflow/src/main/java/org/ruoyi/workflow/enums/BaseEnum.java
+++ b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/enums/BaseEnum.java
@@ -1,4 +1,4 @@
-package org.ruoyi.workflow.enums;
+package org.ruoyi.common.chat.enums;
import com.baomidou.mybatisplus.annotation.IEnum;
diff --git a/ruoyi-modules/ruoyi-aiflow/src/main/java/org/ruoyi/workflow/enums/ErrorEnum.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/enums/ErrorEnum.java
similarity index 99%
rename from ruoyi-modules/ruoyi-aiflow/src/main/java/org/ruoyi/workflow/enums/ErrorEnum.java
rename to ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/enums/ErrorEnum.java
index f9de801e..06095cec 100644
--- a/ruoyi-modules/ruoyi-aiflow/src/main/java/org/ruoyi/workflow/enums/ErrorEnum.java
+++ b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/enums/ErrorEnum.java
@@ -1,4 +1,4 @@
-package org.ruoyi.workflow.enums;
+package org.ruoyi.common.chat.enums;
import lombok.Getter;
diff --git a/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/enums/RoleType.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/enums/RoleType.java
similarity index 84%
rename from ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/enums/RoleType.java
rename to ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/enums/RoleType.java
index cb550975..daaaaaa2 100644
--- a/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/enums/RoleType.java
+++ b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/enums/RoleType.java
@@ -1,4 +1,4 @@
-package org.ruoyi.enums;
+package org.ruoyi.common.chat.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;
@@ -18,6 +18,7 @@ public enum RoleType {
ASSISTANT("assistant"),
FUNCTION("function"),
TOOL("tool"),
+ WORKFLOW("workFlow")
;
private final String name;
diff --git a/ruoyi-modules/ruoyi-aiflow/src/main/java/org/ruoyi/workflow/enums/UserStatusEnum.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/enums/UserStatusEnum.java
similarity index 93%
rename from ruoyi-modules/ruoyi-aiflow/src/main/java/org/ruoyi/workflow/enums/UserStatusEnum.java
rename to ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/enums/UserStatusEnum.java
index 2be9a950..2b2cca43 100644
--- a/ruoyi-modules/ruoyi-aiflow/src/main/java/org/ruoyi/workflow/enums/UserStatusEnum.java
+++ b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/enums/UserStatusEnum.java
@@ -1,4 +1,4 @@
-package org.ruoyi.workflow.enums;
+package org.ruoyi.common.chat.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/factory/ChatServiceFactory.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/factory/ChatServiceFactory.java
index ee884357..6e91254a 100644
--- a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/factory/ChatServiceFactory.java
+++ b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/factory/ChatServiceFactory.java
@@ -1,6 +1,6 @@
package org.ruoyi.common.chat.factory;
-import org.ruoyi.common.chat.Service.IChatService;
+import org.ruoyi.common.chat.service.chat.IChatService;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/factory/ImageServiceFactory.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/factory/ImageServiceFactory.java
index e7ba4160..52d3731b 100644
--- a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/factory/ImageServiceFactory.java
+++ b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/factory/ImageServiceFactory.java
@@ -1,6 +1,6 @@
package org.ruoyi.common.chat.factory;
-import org.ruoyi.common.chat.Service.IImageGenerationService;
+import org.ruoyi.common.chat.service.image.IImageGenerationService;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/Service/IChatModelService.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/service/chat/IChatModelService.java
similarity index 97%
rename from ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/Service/IChatModelService.java
rename to ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/service/chat/IChatModelService.java
index edb7ed52..3c362a52 100644
--- a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/Service/IChatModelService.java
+++ b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/service/chat/IChatModelService.java
@@ -1,4 +1,4 @@
-package org.ruoyi.common.chat.Service;
+package org.ruoyi.common.chat.service.chat;
import org.ruoyi.common.chat.domain.bo.chat.ChatModelBo;
import org.ruoyi.common.chat.domain.vo.chat.ChatModelVo;
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/Service/IChatService.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/service/chat/IChatService.java
similarity index 79%
rename from ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/Service/IChatService.java
rename to ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/service/chat/IChatService.java
index 01a02567..de9f13ca 100644
--- a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/Service/IChatService.java
+++ b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/service/chat/IChatService.java
@@ -1,7 +1,7 @@
-package org.ruoyi.common.chat.Service;
+package org.ruoyi.common.chat.service.chat;
import jakarta.validation.Valid;
-import org.ruoyi.common.chat.domain.entity.chat.ChatContext;
+import org.ruoyi.common.chat.entity.chat.ChatContext;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
/**
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/service/chatMessage/AbstractChatMessageService.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/service/chatMessage/AbstractChatMessageService.java
new file mode 100644
index 00000000..687605eb
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/service/chatMessage/AbstractChatMessageService.java
@@ -0,0 +1,59 @@
+package org.ruoyi.common.chat.service.chatMessage;
+
+import org.ruoyi.common.chat.domain.bo.chat.ChatMessageBo;
+import org.ruoyi.common.chat.domain.dto.request.ChatRequest;
+import org.ruoyi.common.chat.domain.vo.chat.ChatModelVo;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+
+/**
+ * 聊天信息抽象基类 - 保存聊天信息
+ *
+ * @author Zengxb
+ * @date 2026-02-24
+ */
+public abstract class AbstractChatMessageService {
+
+ /**
+ * 创建日志对象
+ */
+ Logger log = LoggerFactory.getLogger(AbstractChatMessageService.class);
+
+ @Autowired
+ private IChatMessageService chatMessageService;
+
+ /**
+ * 保存聊天信息
+ */
+ public void saveChatMessage(ChatRequest chatRequest, Long userId, String content, String role, ChatModelVo chatModelVo){
+ try {
+ // 验证必要的上下文信息
+ if (chatRequest == null || userId == null) {
+ log.warn("缺少必要的聊天上下文信息,无法保存消息");
+ return;
+ }
+
+ // 创建ChatMessageBo对象
+ ChatMessageBo messageBO = new ChatMessageBo();
+ messageBO.setUserId(userId);
+ messageBO.setSessionId(chatRequest.getSessionId());
+ messageBO.setContent(content);
+ messageBO.setRole(role);
+ messageBO.setModelName(chatRequest.getModel());
+ messageBO.setBillingType(chatModelVo.getModelType());
+ messageBO.setRemark(null);
+
+ chatMessageService.insertByBo(messageBO);
+ } catch (Exception e) {
+ log.error("保存{}聊天消息时出错: {}", getProviderName(), e.getMessage(), e);
+ }
+ }
+
+ /**
+ * 获取服务提供商名称
+ */
+ protected String getProviderName(){
+ return "默认工作流大模型";
+ }
+}
diff --git a/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/service/chat/IChatMessageService.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/service/chatMessage/IChatMessageService.java
similarity index 92%
rename from ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/service/chat/IChatMessageService.java
rename to ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/service/chatMessage/IChatMessageService.java
index 3289b5f2..98e31a40 100644
--- a/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/service/chat/IChatMessageService.java
+++ b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/service/chatMessage/IChatMessageService.java
@@ -1,10 +1,10 @@
-package org.ruoyi.service.chat;
+package org.ruoyi.common.chat.service.chatMessage;
+import org.ruoyi.common.chat.domain.bo.chat.ChatMessageBo;
import org.ruoyi.common.chat.domain.dto.ChatMessageDTO;
+import org.ruoyi.common.chat.domain.vo.chat.ChatMessageVo;
import org.ruoyi.common.mybatis.core.page.PageQuery;
import org.ruoyi.common.mybatis.core.page.TableDataInfo;
-import org.ruoyi.domain.bo.chat.ChatMessageBo;
-import org.ruoyi.domain.vo.chat.ChatMessageVo;
import java.util.Collection;
import java.util.List;
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/Service/IImageGenerationService.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/service/image/IImageGenerationService.java
similarity index 74%
rename from ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/Service/IImageGenerationService.java
rename to ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/service/image/IImageGenerationService.java
index 237afed1..3be0a84f 100644
--- a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/Service/IImageGenerationService.java
+++ b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/service/image/IImageGenerationService.java
@@ -1,7 +1,7 @@
-package org.ruoyi.common.chat.Service;
+package org.ruoyi.common.chat.service.image;
import jakarta.validation.Valid;
-import org.ruoyi.common.chat.domain.entity.image.ImageContext;
+import org.ruoyi.common.chat.entity.image.ImageContext;
/**
* 公共文生图接口
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/service/workFlow/IWorkFlowStarterService.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/service/workFlow/IWorkFlowStarterService.java
new file mode 100644
index 00000000..4001b67f
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/service/workFlow/IWorkFlowStarterService.java
@@ -0,0 +1,33 @@
+package org.ruoyi.common.chat.service.workFlow;
+
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import org.ruoyi.common.chat.entity.User;
+import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
+
+import java.util.List;
+
+/**
+ * 工作流启动Service接口
+ *
+ * @author Zengxb
+ * @date 2026-02-24
+ */
+public interface IWorkFlowStarterService {
+
+ /**
+ * 启动工作流
+ * @param user 用户
+ * @param workflowUuid 工作流UUID
+ * @param userInputs 用户输入信息
+ * @return 流式输出结果
+ */
+ SseEmitter streaming(User user, String workflowUuid, List userInputs, Long sessionId);
+
+ /**
+ * 恢复工作流
+ * @param runtimeUuid 运行时UUID
+ * @param userInput 用户输入
+ * @param sseEmitter SSE连接对象
+ */
+ void resumeFlow(String runtimeUuid, String userInput, SseEmitter sseEmitter);
+}
diff --git a/ruoyi-common/ruoyi-common-sse/src/main/java/org/ruoyi/common/sse/core/SseEmitterManager.java b/ruoyi-common/ruoyi-common-sse/src/main/java/org/ruoyi/common/sse/core/SseEmitterManager.java
index d111c875..4e7a5481 100644
--- a/ruoyi-common/ruoyi-common-sse/src/main/java/org/ruoyi/common/sse/core/SseEmitterManager.java
+++ b/ruoyi-common/ruoyi-common-sse/src/main/java/org/ruoyi/common/sse/core/SseEmitterManager.java
@@ -65,7 +65,7 @@ public class SseEmitterManager {
emitter.onCompletion(() -> {
SseEmitter remove = emitters.remove(token);
if (remove != null) {
- remove.complete();
+// remove.complete();
}
});
emitter.onTimeout(() -> {
diff --git a/ruoyi-modules/ruoyi-aiflow/pom.xml b/ruoyi-modules/ruoyi-aiflow/pom.xml
index 34d46d62..d7a147c8 100644
--- a/ruoyi-modules/ruoyi-aiflow/pom.xml
+++ b/ruoyi-modules/ruoyi-aiflow/pom.xml
@@ -81,12 +81,6 @@
-
- io.swagger.core.v3
- swagger-annotations
- ${swagger-annotations.version}
-
-
com.google.api-client
google-api-client
diff --git a/ruoyi-modules/ruoyi-aiflow/src/main/java/org/ruoyi/workflow/base/BaseResponse.java b/ruoyi-modules/ruoyi-aiflow/src/main/java/org/ruoyi/workflow/base/BaseResponse.java
index d6220abd..c84389bc 100644
--- a/ruoyi-modules/ruoyi-aiflow/src/main/java/org/ruoyi/workflow/base/BaseResponse.java
+++ b/ruoyi-modules/ruoyi-aiflow/src/main/java/org/ruoyi/workflow/base/BaseResponse.java
@@ -1,7 +1,7 @@
package org.ruoyi.workflow.base;
import lombok.Data;
-import org.ruoyi.workflow.enums.ErrorEnum;
+import org.ruoyi.common.chat.enums.ErrorEnum;
import java.io.Serializable;
diff --git a/ruoyi-modules/ruoyi-aiflow/src/main/java/org/ruoyi/workflow/controller/WorkflowController.java b/ruoyi-modules/ruoyi-aiflow/src/main/java/org/ruoyi/workflow/controller/WorkflowController.java
index d92f79d8..61037520 100644
--- a/ruoyi-modules/ruoyi-aiflow/src/main/java/org/ruoyi/workflow/controller/WorkflowController.java
+++ b/ruoyi-modules/ruoyi-aiflow/src/main/java/org/ruoyi/workflow/controller/WorkflowController.java
@@ -5,8 +5,8 @@ import io.swagger.v3.oas.annotations.Operation;
import jakarta.annotation.Resource;
import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.NotNull;
+import org.ruoyi.common.chat.base.ThreadContext;
import org.ruoyi.common.core.domain.R;
-import org.ruoyi.workflow.base.ThreadContext;
import org.ruoyi.workflow.dto.workflow.*;
import org.ruoyi.workflow.entity.WorkflowComponent;
import org.ruoyi.workflow.service.WorkflowComponentService;
@@ -72,7 +72,7 @@ public class WorkflowController {
@Operation(summary = "流式响应")
@PostMapping(value = "/run", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public SseEmitter sseAsk(@RequestBody WorkflowRunReq runReq) {
- return workflowStarter.streaming(ThreadContext.getCurrentUser(), runReq.getUuid(), runReq.getInputs());
+ return workflowStarter.streaming(ThreadContext.getCurrentUser(), runReq.getUuid(), runReq.getInputs(),runReq.getSessionId());
}
@GetMapping("/mine/search")
diff --git a/ruoyi-modules/ruoyi-aiflow/src/main/java/org/ruoyi/workflow/controller/WorkflowRuntimeController.java b/ruoyi-modules/ruoyi-aiflow/src/main/java/org/ruoyi/workflow/controller/WorkflowRuntimeController.java
index 34fc0065..2d384aaa 100644
--- a/ruoyi-modules/ruoyi-aiflow/src/main/java/org/ruoyi/workflow/controller/WorkflowRuntimeController.java
+++ b/ruoyi-modules/ruoyi-aiflow/src/main/java/org/ruoyi/workflow/controller/WorkflowRuntimeController.java
@@ -30,7 +30,7 @@ public class WorkflowRuntimeController {
@Operation(summary = "接收用户输入以继续执行剩余流程")
@PostMapping(value = "/resume/{runtimeUuid}")
public R resume(@PathVariable String runtimeUuid, @RequestBody WorkflowResumeReq resumeReq) {
- workflowStarter.resumeFlow(runtimeUuid, resumeReq.getFeedbackContent());
+ workflowStarter.resumeFlow(runtimeUuid, resumeReq.getFeedbackContent(), resumeReq.getSseEmitter());
return R.ok();
}
diff --git a/ruoyi-modules/ruoyi-aiflow/src/main/java/org/ruoyi/workflow/dto/workflow/WorkflowResumeReq.java b/ruoyi-modules/ruoyi-aiflow/src/main/java/org/ruoyi/workflow/dto/workflow/WorkflowResumeReq.java
index 27680932..c1b64829 100644
--- a/ruoyi-modules/ruoyi-aiflow/src/main/java/org/ruoyi/workflow/dto/workflow/WorkflowResumeReq.java
+++ b/ruoyi-modules/ruoyi-aiflow/src/main/java/org/ruoyi/workflow/dto/workflow/WorkflowResumeReq.java
@@ -1,8 +1,10 @@
package org.ruoyi.workflow.dto.workflow;
import lombok.Data;
+import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
@Data
public class WorkflowResumeReq {
private String feedbackContent;
+ private SseEmitter sseEmitter;
}
diff --git a/ruoyi-modules/ruoyi-aiflow/src/main/java/org/ruoyi/workflow/dto/workflow/WorkflowRunReq.java b/ruoyi-modules/ruoyi-aiflow/src/main/java/org/ruoyi/workflow/dto/workflow/WorkflowRunReq.java
index 54a32a03..40ca0fcc 100644
--- a/ruoyi-modules/ruoyi-aiflow/src/main/java/org/ruoyi/workflow/dto/workflow/WorkflowRunReq.java
+++ b/ruoyi-modules/ruoyi-aiflow/src/main/java/org/ruoyi/workflow/dto/workflow/WorkflowRunReq.java
@@ -9,6 +9,7 @@ import java.util.List;
public class WorkflowRunReq {
private List inputs;
private String uuid;
+ private Long sessionId;
}
diff --git a/ruoyi-modules/ruoyi-aiflow/src/main/java/org/ruoyi/workflow/entity/Workflow.java b/ruoyi-modules/ruoyi-aiflow/src/main/java/org/ruoyi/workflow/entity/Workflow.java
index 4334b069..4a43e674 100644
--- a/ruoyi-modules/ruoyi-aiflow/src/main/java/org/ruoyi/workflow/entity/Workflow.java
+++ b/ruoyi-modules/ruoyi-aiflow/src/main/java/org/ruoyi/workflow/entity/Workflow.java
@@ -5,6 +5,7 @@ import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
+import org.ruoyi.common.chat.entity.BaseEntity;
import java.io.Serial;
diff --git a/ruoyi-modules/ruoyi-aiflow/src/main/java/org/ruoyi/workflow/entity/WorkflowComponent.java b/ruoyi-modules/ruoyi-aiflow/src/main/java/org/ruoyi/workflow/entity/WorkflowComponent.java
index d75e92c8..c60b06bc 100644
--- a/ruoyi-modules/ruoyi-aiflow/src/main/java/org/ruoyi/workflow/entity/WorkflowComponent.java
+++ b/ruoyi-modules/ruoyi-aiflow/src/main/java/org/ruoyi/workflow/entity/WorkflowComponent.java
@@ -5,6 +5,7 @@ import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
+import org.ruoyi.common.chat.entity.BaseEntity;
import java.io.Serial;
diff --git a/ruoyi-modules/ruoyi-aiflow/src/main/java/org/ruoyi/workflow/entity/WorkflowEdge.java b/ruoyi-modules/ruoyi-aiflow/src/main/java/org/ruoyi/workflow/entity/WorkflowEdge.java
index 0a9bffda..6c44c70d 100644
--- a/ruoyi-modules/ruoyi-aiflow/src/main/java/org/ruoyi/workflow/entity/WorkflowEdge.java
+++ b/ruoyi-modules/ruoyi-aiflow/src/main/java/org/ruoyi/workflow/entity/WorkflowEdge.java
@@ -5,6 +5,7 @@ import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
+import org.ruoyi.common.chat.entity.BaseEntity;
import java.io.Serial;
diff --git a/ruoyi-modules/ruoyi-aiflow/src/main/java/org/ruoyi/workflow/entity/WorkflowNode.java b/ruoyi-modules/ruoyi-aiflow/src/main/java/org/ruoyi/workflow/entity/WorkflowNode.java
index cc15504a..e4261aab 100644
--- a/ruoyi-modules/ruoyi-aiflow/src/main/java/org/ruoyi/workflow/entity/WorkflowNode.java
+++ b/ruoyi-modules/ruoyi-aiflow/src/main/java/org/ruoyi/workflow/entity/WorkflowNode.java
@@ -5,6 +5,7 @@ import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
+import org.ruoyi.common.chat.entity.BaseEntity;
import java.io.Serial;
diff --git a/ruoyi-modules/ruoyi-aiflow/src/main/java/org/ruoyi/workflow/entity/WorkflowRuntime.java b/ruoyi-modules/ruoyi-aiflow/src/main/java/org/ruoyi/workflow/entity/WorkflowRuntime.java
index 557de3f4..dada5dea 100644
--- a/ruoyi-modules/ruoyi-aiflow/src/main/java/org/ruoyi/workflow/entity/WorkflowRuntime.java
+++ b/ruoyi-modules/ruoyi-aiflow/src/main/java/org/ruoyi/workflow/entity/WorkflowRuntime.java
@@ -5,6 +5,7 @@ import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
+import org.ruoyi.common.chat.entity.BaseEntity;
import java.io.Serial;
diff --git a/ruoyi-modules/ruoyi-aiflow/src/main/java/org/ruoyi/workflow/entity/WorkflowRuntimeNode.java b/ruoyi-modules/ruoyi-aiflow/src/main/java/org/ruoyi/workflow/entity/WorkflowRuntimeNode.java
index 271d9eb7..a472b5a1 100644
--- a/ruoyi-modules/ruoyi-aiflow/src/main/java/org/ruoyi/workflow/entity/WorkflowRuntimeNode.java
+++ b/ruoyi-modules/ruoyi-aiflow/src/main/java/org/ruoyi/workflow/entity/WorkflowRuntimeNode.java
@@ -5,6 +5,7 @@ import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
+import org.ruoyi.common.chat.entity.BaseEntity;
import java.io.Serial;
diff --git a/ruoyi-modules/ruoyi-aiflow/src/main/java/org/ruoyi/workflow/enums/AiModelStatus.java b/ruoyi-modules/ruoyi-aiflow/src/main/java/org/ruoyi/workflow/enums/AiModelStatus.java
index 0dec4a94..f49c3f88 100644
--- a/ruoyi-modules/ruoyi-aiflow/src/main/java/org/ruoyi/workflow/enums/AiModelStatus.java
+++ b/ruoyi-modules/ruoyi-aiflow/src/main/java/org/ruoyi/workflow/enums/AiModelStatus.java
@@ -2,6 +2,7 @@ package org.ruoyi.workflow.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;
+import org.ruoyi.common.chat.enums.BaseEnum;
@Getter
@AllArgsConstructor
diff --git a/ruoyi-modules/ruoyi-aiflow/src/main/java/org/ruoyi/workflow/enums/WfIODataTypeEnum.java b/ruoyi-modules/ruoyi-aiflow/src/main/java/org/ruoyi/workflow/enums/WfIODataTypeEnum.java
index 8f8989c6..2ca638dc 100644
--- a/ruoyi-modules/ruoyi-aiflow/src/main/java/org/ruoyi/workflow/enums/WfIODataTypeEnum.java
+++ b/ruoyi-modules/ruoyi-aiflow/src/main/java/org/ruoyi/workflow/enums/WfIODataTypeEnum.java
@@ -2,6 +2,7 @@ package org.ruoyi.workflow.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;
+import org.ruoyi.common.chat.enums.BaseEnum;
import java.util.Arrays;
diff --git a/ruoyi-modules/ruoyi-aiflow/src/main/java/org/ruoyi/workflow/helper/SSEEmitterHelper.java b/ruoyi-modules/ruoyi-aiflow/src/main/java/org/ruoyi/workflow/helper/SSEEmitterHelper.java
index 4d432c07..61b3dda0 100644
--- a/ruoyi-modules/ruoyi-aiflow/src/main/java/org/ruoyi/workflow/helper/SSEEmitterHelper.java
+++ b/ruoyi-modules/ruoyi-aiflow/src/main/java/org/ruoyi/workflow/helper/SSEEmitterHelper.java
@@ -5,9 +5,9 @@ import com.google.common.cache.CacheBuilder;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
+import org.ruoyi.common.chat.entity.User;
import org.ruoyi.workflow.cosntant.AdiConstant;
import org.ruoyi.workflow.cosntant.RedisKeyConstant;
-import org.ruoyi.workflow.entity.User;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
diff --git a/ruoyi-modules/ruoyi-aiflow/src/main/java/org/ruoyi/workflow/service/WorkflowComponentService.java b/ruoyi-modules/ruoyi-aiflow/src/main/java/org/ruoyi/workflow/service/WorkflowComponentService.java
index 04e3b03c..c1790738 100644
--- a/ruoyi-modules/ruoyi-aiflow/src/main/java/org/ruoyi/workflow/service/WorkflowComponentService.java
+++ b/ruoyi-modules/ruoyi-aiflow/src/main/java/org/ruoyi/workflow/service/WorkflowComponentService.java
@@ -7,11 +7,11 @@ import com.baomidou.mybatisplus.extension.toolkit.ChainWrappers;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
+import org.ruoyi.common.chat.enums.ErrorEnum;
import org.ruoyi.common.core.exception.base.BaseException;
import org.ruoyi.workflow.dto.workflow.WfComponentReq;
import org.ruoyi.workflow.dto.workflow.WfComponentSearchReq;
import org.ruoyi.workflow.entity.WorkflowComponent;
-import org.ruoyi.workflow.enums.ErrorEnum;
import org.ruoyi.workflow.mapper.WorkflowComponentMapper;
import org.ruoyi.workflow.util.PrivilegeUtil;
import org.ruoyi.workflow.util.UuidUtil;
@@ -26,7 +26,7 @@ import java.util.List;
import static org.ruoyi.workflow.cosntant.RedisKeyConstant.WORKFLOW_COMPONENTS;
import static org.ruoyi.workflow.cosntant.RedisKeyConstant.WORKFLOW_COMPONENT_START_KEY;
-import static org.ruoyi.workflow.enums.ErrorEnum.C_WF_COMPONENT_DELETED_FAIL_BY_USED;
+import static org.ruoyi.common.chat.enums.ErrorEnum.C_WF_COMPONENT_DELETED_FAIL_BY_USED;
@Slf4j
@Service
diff --git a/ruoyi-modules/ruoyi-aiflow/src/main/java/org/ruoyi/workflow/service/WorkflowEdgeService.java b/ruoyi-modules/ruoyi-aiflow/src/main/java/org/ruoyi/workflow/service/WorkflowEdgeService.java
index 63cc3530..624482b8 100644
--- a/ruoyi-modules/ruoyi-aiflow/src/main/java/org/ruoyi/workflow/service/WorkflowEdgeService.java
+++ b/ruoyi-modules/ruoyi-aiflow/src/main/java/org/ruoyi/workflow/service/WorkflowEdgeService.java
@@ -5,10 +5,10 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.baomidou.mybatisplus.extension.toolkit.ChainWrappers;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
+import org.ruoyi.common.chat.enums.ErrorEnum;
import org.ruoyi.common.core.exception.base.BaseException;
import org.ruoyi.workflow.dto.workflow.WfEdgeReq;
import org.ruoyi.workflow.entity.WorkflowEdge;
-import org.ruoyi.workflow.enums.ErrorEnum;
import org.ruoyi.workflow.mapper.WorkflowEdgeMapper;
import org.ruoyi.workflow.util.MPPageUtil;
import org.ruoyi.workflow.util.UuidUtil;
diff --git a/ruoyi-modules/ruoyi-aiflow/src/main/java/org/ruoyi/workflow/service/WorkflowNodeService.java b/ruoyi-modules/ruoyi-aiflow/src/main/java/org/ruoyi/workflow/service/WorkflowNodeService.java
index e99bd8fd..f56ac479 100644
--- a/ruoyi-modules/ruoyi-aiflow/src/main/java/org/ruoyi/workflow/service/WorkflowNodeService.java
+++ b/ruoyi-modules/ruoyi-aiflow/src/main/java/org/ruoyi/workflow/service/WorkflowNodeService.java
@@ -6,12 +6,12 @@ import com.baomidou.mybatisplus.extension.toolkit.ChainWrappers;
import com.fasterxml.jackson.databind.node.ObjectNode;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
+import org.ruoyi.common.chat.enums.ErrorEnum;
import org.ruoyi.common.core.exception.base.BaseException;
import org.ruoyi.workflow.dto.workflow.WfNodeDto;
import org.ruoyi.workflow.entity.Workflow;
import org.ruoyi.workflow.entity.WorkflowComponent;
import org.ruoyi.workflow.entity.WorkflowNode;
-import org.ruoyi.workflow.enums.ErrorEnum;
import org.ruoyi.workflow.enums.WfIODataTypeEnum;
import org.ruoyi.workflow.mapper.WorkflowNodeMapper;
import org.ruoyi.workflow.util.JsonUtil;
diff --git a/ruoyi-modules/ruoyi-aiflow/src/main/java/org/ruoyi/workflow/service/WorkflowRuntimeNodeService.java b/ruoyi-modules/ruoyi-aiflow/src/main/java/org/ruoyi/workflow/service/WorkflowRuntimeNodeService.java
index 43c73207..63aa6d4b 100644
--- a/ruoyi-modules/ruoyi-aiflow/src/main/java/org/ruoyi/workflow/service/WorkflowRuntimeNodeService.java
+++ b/ruoyi-modules/ruoyi-aiflow/src/main/java/org/ruoyi/workflow/service/WorkflowRuntimeNodeService.java
@@ -4,9 +4,9 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.baomidou.mybatisplus.extension.toolkit.ChainWrappers;
import com.fasterxml.jackson.databind.node.ObjectNode;
import lombok.extern.slf4j.Slf4j;
-import org.ruoyi.workflow.base.ThreadContext;
+import org.ruoyi.common.chat.base.ThreadContext;
+import org.ruoyi.common.chat.entity.User;
import org.ruoyi.workflow.dto.workflow.WfRuntimeNodeDto;
-import org.ruoyi.workflow.entity.User;
import org.ruoyi.workflow.entity.WorkflowRuntimeNode;
import org.ruoyi.workflow.mapper.WorkflowRuntimeNodeMapper;
import org.ruoyi.workflow.util.JsonUtil;
diff --git a/ruoyi-modules/ruoyi-aiflow/src/main/java/org/ruoyi/workflow/service/WorkflowRuntimeService.java b/ruoyi-modules/ruoyi-aiflow/src/main/java/org/ruoyi/workflow/service/WorkflowRuntimeService.java
index 330974a9..ddd3f3fb 100644
--- a/ruoyi-modules/ruoyi-aiflow/src/main/java/org/ruoyi/workflow/service/WorkflowRuntimeService.java
+++ b/ruoyi-modules/ruoyi-aiflow/src/main/java/org/ruoyi/workflow/service/WorkflowRuntimeService.java
@@ -7,13 +7,13 @@ import com.fasterxml.jackson.databind.node.ObjectNode;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
-import org.ruoyi.workflow.base.ThreadContext;
+import org.ruoyi.common.chat.base.ThreadContext;
+import org.ruoyi.common.chat.entity.User;
+import org.ruoyi.common.chat.enums.ErrorEnum;
import org.ruoyi.workflow.dto.workflow.WfRuntimeNodeDto;
import org.ruoyi.workflow.dto.workflow.WfRuntimeResp;
-import org.ruoyi.workflow.entity.User;
import org.ruoyi.workflow.entity.Workflow;
import org.ruoyi.workflow.entity.WorkflowRuntime;
-import org.ruoyi.workflow.enums.ErrorEnum;
import org.ruoyi.workflow.mapper.WorkflowRunMapper;
import org.ruoyi.workflow.util.JsonUtil;
import org.ruoyi.workflow.util.MPPageUtil;
diff --git a/ruoyi-modules/ruoyi-aiflow/src/main/java/org/ruoyi/workflow/service/WorkflowService.java b/ruoyi-modules/ruoyi-aiflow/src/main/java/org/ruoyi/workflow/service/WorkflowService.java
index 439ffba4..926dc12b 100644
--- a/ruoyi-modules/ruoyi-aiflow/src/main/java/org/ruoyi/workflow/service/WorkflowService.java
+++ b/ruoyi-modules/ruoyi-aiflow/src/main/java/org/ruoyi/workflow/service/WorkflowService.java
@@ -6,15 +6,15 @@ import com.baomidou.mybatisplus.extension.toolkit.ChainWrappers;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
+import org.ruoyi.common.chat.base.ThreadContext;
+import org.ruoyi.common.chat.entity.User;
+import org.ruoyi.common.chat.enums.ErrorEnum;
import org.ruoyi.common.core.exception.base.BaseException;
-import org.ruoyi.workflow.base.ThreadContext;
import org.ruoyi.workflow.dto.workflow.WfEdgeReq;
import org.ruoyi.workflow.dto.workflow.WfNodeDto;
import org.ruoyi.workflow.dto.workflow.WorkflowResp;
import org.ruoyi.workflow.dto.workflow.WorkflowUpdateReq;
-import org.ruoyi.workflow.entity.User;
import org.ruoyi.workflow.entity.Workflow;
-import org.ruoyi.workflow.enums.ErrorEnum;
import org.ruoyi.workflow.mapper.WorkflowMapper;
import org.ruoyi.workflow.util.MPPageUtil;
import org.ruoyi.workflow.util.PrivilegeUtil;
diff --git a/ruoyi-modules/ruoyi-aiflow/src/main/java/org/ruoyi/workflow/util/PrivilegeUtil.java b/ruoyi-modules/ruoyi-aiflow/src/main/java/org/ruoyi/workflow/util/PrivilegeUtil.java
index 7ad0dc7a..7480cbfe 100644
--- a/ruoyi-modules/ruoyi-aiflow/src/main/java/org/ruoyi/workflow/util/PrivilegeUtil.java
+++ b/ruoyi-modules/ruoyi-aiflow/src/main/java/org/ruoyi/workflow/util/PrivilegeUtil.java
@@ -1,9 +1,9 @@
package org.ruoyi.workflow.util;
import com.baomidou.mybatisplus.extension.conditions.query.QueryChainWrapper;
+import org.ruoyi.common.chat.base.ThreadContext;
+import org.ruoyi.common.chat.enums.ErrorEnum;
import org.ruoyi.common.core.exception.base.BaseException;
-import org.ruoyi.workflow.base.ThreadContext;
-import org.ruoyi.workflow.enums.ErrorEnum;
import static org.ruoyi.workflow.cosntant.AdiConstant.*;
diff --git a/ruoyi-modules/ruoyi-aiflow/src/main/java/org/ruoyi/workflow/util/WorkflowMessageUtil.java b/ruoyi-modules/ruoyi-aiflow/src/main/java/org/ruoyi/workflow/util/WorkflowMessageUtil.java
new file mode 100644
index 00000000..4ae71e3b
--- /dev/null
+++ b/ruoyi-modules/ruoyi-aiflow/src/main/java/org/ruoyi/workflow/util/WorkflowMessageUtil.java
@@ -0,0 +1,37 @@
+package org.ruoyi.workflow.util;
+
+import org.ruoyi.common.chat.domain.dto.request.ChatRequest;
+import org.ruoyi.common.chat.domain.vo.chat.ChatModelVo;
+import org.ruoyi.common.chat.enums.RoleType;
+import lombok.extern.slf4j.Slf4j;
+import org.ruoyi.common.core.utils.SpringUtils;
+import org.ruoyi.workflow.workflow.WfState;
+import org.ruoyi.workflow.workflow.WorkflowUtil;
+
+/**
+ * 工作流消息工具类
+ *
+ * @author Zengxb
+ * @date 2026-02-26
+ */
+@Slf4j
+public class WorkflowMessageUtil {
+
+ /**
+ * 保存工作流消息公共方法(对话使用)
+ * @param wfState 工作流实例状态
+ * @param message 消息
+ */
+ public static void saveWorkflowMessage(WfState wfState, String message) {
+ Long sessionId = wfState.getSessionId();
+ Long userId = wfState.getUserId();
+
+ if (sessionId != null && userId != null) {
+ ChatRequest chatRequest = new ChatRequest();
+ chatRequest.setSessionId(sessionId);
+ WorkflowUtil workflowUtil = SpringUtils.getBean(WorkflowUtil.class);
+ workflowUtil.saveChatMessage(chatRequest, userId, message, RoleType.WORKFLOW.getName(), new ChatModelVo());
+ }
+ }
+
+}
diff --git a/ruoyi-modules/ruoyi-aiflow/src/main/java/org/ruoyi/workflow/workflow/WfNodeIODataUtil.java b/ruoyi-modules/ruoyi-aiflow/src/main/java/org/ruoyi/workflow/workflow/WfNodeIODataUtil.java
index 61828568..9bedc711 100644
--- a/ruoyi-modules/ruoyi-aiflow/src/main/java/org/ruoyi/workflow/workflow/WfNodeIODataUtil.java
+++ b/ruoyi-modules/ruoyi-aiflow/src/main/java/org/ruoyi/workflow/workflow/WfNodeIODataUtil.java
@@ -4,8 +4,8 @@ import cn.hutool.core.collection.CollUtil;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import org.apache.commons.collections4.CollectionUtils;
+import org.ruoyi.common.chat.enums.ErrorEnum;
import org.ruoyi.common.core.exception.base.BaseException;
-import org.ruoyi.workflow.enums.ErrorEnum;
import org.ruoyi.workflow.enums.WfIODataTypeEnum;
import org.ruoyi.workflow.util.JsonUtil;
import org.ruoyi.workflow.workflow.data.NodeIOData;
diff --git a/ruoyi-modules/ruoyi-aiflow/src/main/java/org/ruoyi/workflow/workflow/WfState.java b/ruoyi-modules/ruoyi-aiflow/src/main/java/org/ruoyi/workflow/workflow/WfState.java
index 97962a71..d0595803 100644
--- a/ruoyi-modules/ruoyi-aiflow/src/main/java/org/ruoyi/workflow/workflow/WfState.java
+++ b/ruoyi-modules/ruoyi-aiflow/src/main/java/org/ruoyi/workflow/workflow/WfState.java
@@ -4,8 +4,8 @@ import lombok.Getter;
import lombok.Setter;
import org.bsc.langgraph4j.langchain4j.generators.StreamingChatGenerator;
import org.bsc.langgraph4j.state.AgentState;
+import org.ruoyi.common.chat.entity.User;
import org.ruoyi.workflow.dto.workflow.WfRuntimeNodeDto;
-import org.ruoyi.workflow.entity.User;
import org.ruoyi.workflow.entity.WorkflowNode;
import org.ruoyi.workflow.workflow.data.NodeIOData;
import org.ruoyi.workflow.workflow.node.AbstractWfNode;
@@ -28,6 +28,7 @@ public class WfState {
private Long userId;
private String tokenValue;
private SseEmitter sseEmitter;
+ private Long sessionId;
//Source node uuid => target node uuid list
private Map> edges = new HashMap<>();
@@ -59,13 +60,14 @@ public class WfState {
*/
private Set interruptNodes = new HashSet<>();
- public WfState(User user, List input, String uuid, Long userId, String tokenValue, SseEmitter sseEmitter) {
+ public WfState(User user, List input, String uuid, Long userId, String tokenValue, SseEmitter sseEmitter, Long sessionId) {
this.input = input;
this.user = user;
this.uuid = uuid;
this.userId = userId;
this.tokenValue = tokenValue;
this.sseEmitter = sseEmitter;
+ this.sessionId = sessionId;
}
/**
diff --git a/ruoyi-modules/ruoyi-aiflow/src/main/java/org/ruoyi/workflow/workflow/WorkflowEngine.java b/ruoyi-modules/ruoyi-aiflow/src/main/java/org/ruoyi/workflow/workflow/WorkflowEngine.java
index f84b2164..20a3e783 100644
--- a/ruoyi-modules/ruoyi-aiflow/src/main/java/org/ruoyi/workflow/workflow/WorkflowEngine.java
+++ b/ruoyi-modules/ruoyi-aiflow/src/main/java/org/ruoyi/workflow/workflow/WorkflowEngine.java
@@ -3,6 +3,8 @@ package org.ruoyi.workflow.workflow;
import cn.hutool.core.collection.CollStreamUtil;
import cn.hutool.core.collection.CollUtil;
import com.fasterxml.jackson.databind.node.ObjectNode;
+import lombok.Getter;
+import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.Pair;
@@ -13,16 +15,18 @@ import org.bsc.langgraph4j.langchain4j.generators.StreamingChatGenerator;
import org.bsc.langgraph4j.state.AgentState;
import org.bsc.langgraph4j.state.StateSnapshot;
import org.bsc.langgraph4j.streaming.StreamingOutput;
+import org.ruoyi.common.chat.entity.User;
+import org.ruoyi.common.chat.enums.ErrorEnum;
import org.ruoyi.common.core.exception.base.BaseException;
import org.ruoyi.workflow.base.NodeInputConfigTypeHandler;
import org.ruoyi.workflow.dto.workflow.WfRuntimeNodeDto;
import org.ruoyi.workflow.dto.workflow.WfRuntimeResp;
import org.ruoyi.workflow.entity.*;
-import org.ruoyi.workflow.enums.ErrorEnum;
import org.ruoyi.workflow.helper.SSEEmitterHelper;
import org.ruoyi.workflow.service.WorkflowRuntimeNodeService;
import org.ruoyi.workflow.service.WorkflowRuntimeService;
import org.ruoyi.workflow.util.JsonUtil;
+import org.ruoyi.workflow.util.WorkflowMessageUtil;
import org.ruoyi.workflow.workflow.data.NodeIOData;
import org.ruoyi.workflow.workflow.def.WfNodeIO;
import org.ruoyi.workflow.workflow.def.WfNodeParamRef;
@@ -34,7 +38,7 @@ import java.util.function.Function;
import static org.bsc.langgraph4j.StateGraph.END;
import static org.ruoyi.workflow.cosntant.AdiConstant.WorkflowConstant.*;
-import static org.ruoyi.workflow.enums.ErrorEnum.*;
+import static org.ruoyi.common.chat.enums.ErrorEnum.*;
@Slf4j
public class WorkflowEngine {
@@ -45,7 +49,9 @@ public class WorkflowEngine {
private final SSEEmitterHelper sseEmitterHelper;
private final WorkflowRuntimeService workflowRuntimeService;
private final WorkflowRuntimeNodeService workflowRuntimeNodeService;
+ @Getter
private CompiledGraph app;
+ @Setter
private SseEmitter sseEmitter;
private User user;
private WfState wfState;
@@ -68,7 +74,7 @@ public class WorkflowEngine {
this.workflowRuntimeNodeService = workflowRuntimeNodeService;
}
- public void run(User user, List userInputs, SseEmitter sseEmitter, Long userId, String tokenValue) {
+ public void run(User user, List userInputs, SseEmitter sseEmitter, Long userId, String tokenValue, Long sessionId) {
this.user = user;
this.sseEmitter = sseEmitter;
log.info("WorkflowEngine run,userId:{},workflowUuid:{},userInputs:{}", user.getId(), workflow.getUuid(), userInputs);
@@ -86,7 +92,7 @@ public class WorkflowEngine {
Pair> startAndEnds = findStartAndEndNode();
WorkflowNode startNode = startAndEnds.getLeft();
List wfInputs = getAndCheckUserInput(userInputs, startNode);
- this.wfState = new WfState(user, wfInputs, runtimeUuid,userId, tokenValue, sseEmitter);
+ this.wfState = new WfState(user, wfInputs, runtimeUuid,userId, tokenValue, sseEmitter, sessionId);
workflowRuntimeService.updateInput(this.wfRuntimeResp.getId(), wfState);
@@ -122,6 +128,8 @@ public class WorkflowEngine {
String intTip = WorkflowUtil.getHumanFeedbackTip(nextNode, wfNodes);
//将等待输入信息[事件与提示词]发送到到客户端
SSEEmitterHelper.parseAndSendPartialMsg(sseEmitter, "[NODE_WAIT_FEEDBACK_BY_" + nextNode + "]", intTip);
+ // 保存提示信息到Chat信息记录中(对话使用)
+ WorkflowMessageUtil.saveWorkflowMessage(wfState, intTip);
InterruptedFlow.RUNTIME_TO_GRAPH.put(wfState.getUuid(), this);
//更新状�?
wfState.setProcessStatus(WORKFLOW_PROCESS_STATUS_WAITING_INPUT);
@@ -241,6 +249,7 @@ public class WorkflowEngine {
Map strMap = new HashMap<>();
strMap.put("ck", chunk);
// SSEEmitterHelper.parseAndSendPartialMsg(sseEmitter, "[NODE_CHUNK_" + node + "]", strMap.toString());
+
SSEEmitterHelper.parseAndSendPartialMsg(sseEmitter, "[NODE_CHUNK_" + node + "]", chunk);
} else {
AbstractWfNode abstractWfNode = wfState.getCompletedNodes().stream()
@@ -349,8 +358,4 @@ public class WorkflowEngine {
return Pair.of(startNode, endNodes);
}
-
- public CompiledGraph getApp() {
- return app;
- }
}
diff --git a/ruoyi-modules/ruoyi-aiflow/src/main/java/org/ruoyi/workflow/workflow/WorkflowGraphBuilder.java b/ruoyi-modules/ruoyi-aiflow/src/main/java/org/ruoyi/workflow/workflow/WorkflowGraphBuilder.java
index aa11b4b5..55241376 100644
--- a/ruoyi-modules/ruoyi-aiflow/src/main/java/org/ruoyi/workflow/workflow/WorkflowGraphBuilder.java
+++ b/ruoyi-modules/ruoyi-aiflow/src/main/java/org/ruoyi/workflow/workflow/WorkflowGraphBuilder.java
@@ -5,11 +5,11 @@ import org.apache.commons.lang3.StringUtils;
import org.bsc.langgraph4j.GraphStateException;
import org.bsc.langgraph4j.StateGraph;
import org.bsc.langgraph4j.serializer.std.ObjectStreamStateSerializer;
+import org.ruoyi.common.chat.enums.ErrorEnum;
import org.ruoyi.common.core.exception.base.BaseException;
import org.ruoyi.workflow.entity.WorkflowComponent;
import org.ruoyi.workflow.entity.WorkflowEdge;
import org.ruoyi.workflow.entity.WorkflowNode;
-import org.ruoyi.workflow.enums.ErrorEnum;
import java.util.*;
import java.util.function.Function;
diff --git a/ruoyi-modules/ruoyi-aiflow/src/main/java/org/ruoyi/workflow/workflow/WorkflowStarter.java b/ruoyi-modules/ruoyi-aiflow/src/main/java/org/ruoyi/workflow/workflow/WorkflowStarter.java
index 7865af51..95885ed1 100644
--- a/ruoyi-modules/ruoyi-aiflow/src/main/java/org/ruoyi/workflow/workflow/WorkflowStarter.java
+++ b/ruoyi-modules/ruoyi-aiflow/src/main/java/org/ruoyi/workflow/workflow/WorkflowStarter.java
@@ -4,6 +4,8 @@ import cn.dev33.satoken.stp.StpUtil;
import com.fasterxml.jackson.databind.node.ObjectNode;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
+import org.ruoyi.common.chat.entity.User;
+import org.ruoyi.common.chat.service.workFlow.IWorkFlowStarterService;
import org.ruoyi.common.core.exception.base.BaseException;
import org.ruoyi.common.satoken.utils.LoginHelper;
import org.ruoyi.common.sse.core.SseEmitterManager;
@@ -12,17 +14,16 @@ import org.ruoyi.workflow.helper.SSEEmitterHelper;
import org.ruoyi.workflow.service.*;
import org.springframework.context.annotation.Lazy;
import org.springframework.scheduling.annotation.Async;
-import org.springframework.stereotype.Component;
+import org.springframework.stereotype.Service;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
import java.util.List;
-import static org.ruoyi.workflow.cosntant.AdiConstant.SSE_TIMEOUT;
-import static org.ruoyi.workflow.enums.ErrorEnum.*;
+import static org.ruoyi.common.chat.enums.ErrorEnum.*;
@Slf4j
-@Component
-public class WorkflowStarter {
+@Service
+public class WorkflowStarter implements IWorkFlowStarterService {
@Lazy
@Resource
@@ -52,8 +53,7 @@ public class WorkflowStarter {
@Resource
private SseEmitterManager sseEmitterManager;
-
- public SseEmitter streaming(User user, String workflowUuid, List userInputs) {
+ public SseEmitter streaming(User user, String workflowUuid, List userInputs, Long sessionId) {
// 获取用户ID
Long userId = LoginHelper.getUserId();
// 获取登录Token
@@ -71,12 +71,12 @@ public class WorkflowStarter {
sseEmitterHelper.sendErrorAndComplete(user.getId(), sseEmitter, A_WF_DISABLED.getInfo());
return sseEmitter;
}
- self.asyncRun(user, workflow, userInputs, sseEmitter, userId, tokenValue);
+ self.asyncRun(user, workflow, userInputs, sseEmitter, userId, tokenValue, sessionId);
return sseEmitter;
}
@Async
- public void asyncRun(User user, Workflow workflow, List userInputs, SseEmitter sseEmitter, Long userId, String tokenValue) {
+ public void asyncRun(User user, Workflow workflow, List userInputs, SseEmitter sseEmitter, Long userId, String tokenValue, Long sessionId) {
log.info("WorkflowEngine run,userId:{},workflowUuid:{},userInputs:{}", user.getId(), workflow.getUuid(), userInputs);
List components = workflowComponentService.getAllEnable();
List nodes = workflowNodeService.lambdaQuery()
@@ -90,17 +90,20 @@ public class WorkflowStarter {
WorkflowEngine workflowEngine = new WorkflowEngine(workflow,
sseEmitterHelper, components, nodes, edges,
workflowRuntimeService, workflowRuntimeNodeService);
- workflowEngine.run(user, userInputs, sseEmitter, userId, tokenValue);
+ workflowEngine.run(user, userInputs, sseEmitter, userId, tokenValue, sessionId);
}
@Async
- public void resumeFlow(String runtimeUuid, String userInput) {
+ public void resumeFlow(String runtimeUuid, String userInput, SseEmitter sseEmitter) {
WorkflowEngine workflowEngine = InterruptedFlow.RUNTIME_TO_GRAPH.get(runtimeUuid);
if (null == workflowEngine) {
log.error("工作流恢复执行时失败,runtime:{}", runtimeUuid);
throw new BaseException(A_WF_RESUME_FAIL.getInfo());
}
+ // 如果SSE连接对象不为空传入该对象(Chat调用工作流对话使用)
+ if (null != sseEmitter){
+ workflowEngine.setSseEmitter(sseEmitter);
+ }
workflowEngine.resume(userInput);
}
-
}
diff --git a/ruoyi-modules/ruoyi-aiflow/src/main/java/org/ruoyi/workflow/workflow/WorkflowUtil.java b/ruoyi-modules/ruoyi-aiflow/src/main/java/org/ruoyi/workflow/workflow/WorkflowUtil.java
index 63a13845..c34962c0 100644
--- a/ruoyi-modules/ruoyi-aiflow/src/main/java/org/ruoyi/workflow/workflow/WorkflowUtil.java
+++ b/ruoyi-modules/ruoyi-aiflow/src/main/java/org/ruoyi/workflow/workflow/WorkflowUtil.java
@@ -11,12 +11,14 @@ import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.bsc.langgraph4j.langchain4j.generators.StreamingChatGenerator;
import org.bsc.langgraph4j.state.AgentState;
-import org.ruoyi.common.chat.Service.IChatModelService;
-import org.ruoyi.common.chat.Service.IChatService;
-import org.ruoyi.common.chat.Service.IImageGenerationService;
+import org.ruoyi.common.chat.enums.RoleType;
+import org.ruoyi.common.chat.service.chat.IChatModelService;
+import org.ruoyi.common.chat.service.chat.IChatService;
+import org.ruoyi.common.chat.service.chatMessage.AbstractChatMessageService;
+import org.ruoyi.common.chat.service.image.IImageGenerationService;
import org.ruoyi.common.chat.domain.dto.request.ChatRequest;
-import org.ruoyi.common.chat.domain.entity.chat.ChatContext;
-import org.ruoyi.common.chat.domain.entity.image.ImageContext;
+import org.ruoyi.common.chat.entity.chat.ChatContext;
+import org.ruoyi.common.chat.entity.image.ImageContext;
import org.ruoyi.common.chat.domain.vo.chat.ChatModelVo;
import org.ruoyi.common.chat.factory.ChatServiceFactory;
import org.ruoyi.common.chat.factory.ImageServiceFactory;
@@ -28,6 +30,7 @@ import org.ruoyi.workflow.workflow.data.NodeIOData;
import org.ruoyi.workflow.workflow.data.NodeIODataContent;
import org.ruoyi.workflow.workflow.def.WfNodeParamRef;
import org.springframework.stereotype.Component;
+import org.springframework.stereotype.Service;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
import java.util.*;
@@ -35,8 +38,8 @@ import java.util.*;
import static org.ruoyi.workflow.cosntant.AdiConstant.WorkflowConstant.DEFAULT_OUTPUT_PARAM_NAME;
@Slf4j
-@Component
-public class WorkflowUtil {
+@Service
+public class WorkflowUtil extends AbstractChatMessageService {
@Resource
private ChatServiceFactory chatServiceFactory;
@@ -123,11 +126,38 @@ public class WorkflowUtil {
// 根据 category 获取对应的 ChatService(不使用计费代理,工作流场景单独计费)
IChatService chatService = chatServiceFactory.getOriginalService(category);
+ // 获取用户信息和Token以及SSe连接对象(对话接口需要使用)
+ Long sessionId = wfState.getSessionId();
+ Long userId = wfState.getUserId();
+ String tokenValue = wfState.getTokenValue();
+ SseEmitter sseEmitter = wfState.getSseEmitter();
+
+ // 构建 ruoyi-ai 的 ChatRequest
+ List chatMessages = new ArrayList<>();
+ addUserMessage(node, state.getInputs(), chatMessages);
+ chatMessages.addAll(systemMessage);
+
+ // 定义模型调用对象
+ ChatRequest chatRequest = new ChatRequest();
+ // 目前工作流深度思考成员变量只能写死
+ chatRequest.setSessionId(sessionId);
+ chatRequest.setEnableThinking(false);
+ chatRequest.setModel(modelName);
+ chatRequest.setChatMessages(chatMessages);
+
+ // 构建流式生成器
StreamingChatGenerator streamingGenerator = StreamingChatGenerator.builder()
.mapResult(response -> {
String responseTxt = response.aiMessage().text();
log.info("llm response:{}", responseTxt);
+ // 会话ID不为空时插入数据库
+ if (sessionId != null){
+ // 保存助手回复消息
+ saveChatMessage(chatRequest, userId, responseTxt, RoleType.ASSISTANT.getName(), chatModelVo);
+ log.info("{}消息结束,已保存到数据库", getProviderName());
+ }
+
// 传递所有输入数据 + 添加 LLM 输出
wfState.getNodeStateByNodeUuid(node.getUuid()).ifPresent(item -> {
List outputs = new ArrayList<>(item.getInputs());
@@ -142,24 +172,9 @@ public class WorkflowUtil {
.startingState(state)
.build();
- // 获取用户信息和Token以及SSe连接对象(对话接口需要使用)
- Long userId = wfState.getUserId();
- String tokenValue = wfState.getTokenValue();
- SseEmitter sseEmitter = wfState.getSseEmitter();
+ // 构建流式回调响应器
StreamingChatResponseHandler handler = streamingGenerator.handler();
- // 构建 ruoyi-ai 的 ChatRequest
- List chatMessages = new ArrayList<>();
- addUserMessage(node, state.getInputs(), chatMessages);
- chatMessages.addAll(systemMessage);
-
- // 定义模型调用对象
- ChatRequest chatRequest = new ChatRequest();
- // 目前工作流深度思考成员变量只能写死
- chatRequest.setEnableThinking(false);
- chatRequest.setModel(modelName);
- chatRequest.setChatMessages(chatMessages);
-
//构建聊天对话上下文参数
ChatContext chatContext = ChatContext.builder()
.chatModelVo(chatModelVo)
@@ -231,9 +246,9 @@ public class WorkflowUtil {
throw new IllegalArgumentException("模型不存在: " + modelName);
}
// 根据模型名称找到模型实体
- String modelVoCategory = chatModelVo.getCategory();
+ String category = chatModelVo.getProviderCode();
// 根据 category 获取对应的 IImageGenerationService(不使用计费代理,工作流场景单独计费)
- IImageGenerationService imageService = imageServiceFactory.getOriginalService(modelVoCategory);
+ IImageGenerationService imageService = imageServiceFactory.getOriginalService(category);
// 构建文生图上下文对象
ImageContext imageContext = ImageContext.builder()
.chatModelVo(chatModelVo)
@@ -244,5 +259,4 @@ public class WorkflowUtil {
// 调用LLM 生成图片
return imageService.generateImage(imageContext);
}
-
}
diff --git a/ruoyi-modules/ruoyi-aiflow/src/main/java/org/ruoyi/workflow/workflow/node/AbstractWfNode.java b/ruoyi-modules/ruoyi-aiflow/src/main/java/org/ruoyi/workflow/workflow/node/AbstractWfNode.java
index d3262971..700071f0 100644
--- a/ruoyi-modules/ruoyi-aiflow/src/main/java/org/ruoyi/workflow/workflow/node/AbstractWfNode.java
+++ b/ruoyi-modules/ruoyi-aiflow/src/main/java/org/ruoyi/workflow/workflow/node/AbstractWfNode.java
@@ -6,18 +6,19 @@ import lombok.Data;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.SerializationUtils;
-import org.apache.commons.lang3.StringUtils;
+import org.ruoyi.common.chat.domain.dto.request.ChatRequest;
+import org.ruoyi.common.chat.domain.vo.chat.ChatModelVo;
+import org.ruoyi.common.chat.enums.RoleType;
import org.ruoyi.common.core.exception.base.BaseException;
import org.ruoyi.workflow.base.NodeInputConfigTypeHandler;
import org.ruoyi.workflow.entity.WorkflowComponent;
import org.ruoyi.workflow.entity.WorkflowNode;
import org.ruoyi.workflow.enums.WfIODataTypeEnum;
+import org.ruoyi.workflow.helper.SSEEmitterHelper;
import org.ruoyi.workflow.util.JsonUtil;
import org.ruoyi.workflow.util.SpringUtil;
-import org.ruoyi.workflow.workflow.NodeProcessResult;
-import org.ruoyi.workflow.workflow.WfNodeInputConfig;
-import org.ruoyi.workflow.workflow.WfNodeState;
-import org.ruoyi.workflow.workflow.WfState;
+import org.ruoyi.workflow.util.WorkflowMessageUtil;
+import org.ruoyi.workflow.workflow.*;
import org.ruoyi.workflow.workflow.data.NodeIOData;
import org.ruoyi.workflow.workflow.def.WfNodeIO;
import org.ruoyi.workflow.workflow.def.WfNodeParamRef;
@@ -31,8 +32,8 @@ import java.util.function.Consumer;
import java.util.stream.Collectors;
import static org.ruoyi.workflow.cosntant.AdiConstant.WorkflowConstant.*;
-import static org.ruoyi.workflow.enums.ErrorEnum.A_WF_NODE_CONFIG_ERROR;
-import static org.ruoyi.workflow.enums.ErrorEnum.A_WF_NODE_CONFIG_NOT_FOUND;
+import static org.ruoyi.common.chat.enums.ErrorEnum.A_WF_NODE_CONFIG_ERROR;
+import static org.ruoyi.common.chat.enums.ErrorEnum.A_WF_NODE_CONFIG_NOT_FOUND;
/**
* 节点实例-运行时
@@ -225,4 +226,19 @@ public abstract class AbstractWfNode {
return nodeConfig;
}
+ /**
+ * 会话消息保存方法
+ */
+ public void saveSessionMessage(WfState wfState, String message) {
+ WorkflowMessageUtil.saveWorkflowMessage(wfState, message);
+ }
+
+ /**
+ * 发送SSe消息
+ * @param message 信息
+ */
+ public void sendSseEvent(String message){
+ String nodeUuid = node.getUuid();
+ SSEEmitterHelper.parseAndSendPartialMsg(wfState.getSseEmitter(), "[NODE_CHUNK_" + nodeUuid + "]", message);
+ }
}
diff --git a/ruoyi-modules/ruoyi-aiflow/src/main/java/org/ruoyi/workflow/workflow/node/httpRequest/HttpRequestNode.java b/ruoyi-modules/ruoyi-aiflow/src/main/java/org/ruoyi/workflow/workflow/node/httpRequest/HttpRequestNode.java
index 16fc5f71..10248aeb 100644
--- a/ruoyi-modules/ruoyi-aiflow/src/main/java/org/ruoyi/workflow/workflow/node/httpRequest/HttpRequestNode.java
+++ b/ruoyi-modules/ruoyi-aiflow/src/main/java/org/ruoyi/workflow/workflow/node/httpRequest/HttpRequestNode.java
@@ -63,6 +63,11 @@ public class HttpRequestNode extends AbstractWfNode {
List outputs = new ArrayList<>();
outputs.add(NodeIOData.createByText("output", "HTTP响应", response));
+ // 保存成功会话信息
+ String message = "HTTP响应:" + response;
+ saveSessionMessage(wfState, message);
+ // 发送驱动消息事件
+ sendSseEvent(message);
return NodeProcessResult.builder().content(outputs).build();
} catch (Exception e) {
@@ -73,6 +78,11 @@ public class HttpRequestNode extends AbstractWfNode {
errorOutputs.add(NodeIOData.createByText("output", "错误", ""));
errorOutputs.add(NodeIOData.createByText("error", "HTTP请求错误", e.getMessage()));
+ // 保存失败会话信息
+ String message = "HTTP响应失败:" + e.getMessage();
+ saveSessionMessage(wfState, message);
+ // 发送驱动消息事件
+ sendSseEvent(message);
return NodeProcessResult.builder().content(errorOutputs).build();
}
}
diff --git a/ruoyi-modules/ruoyi-aiflow/src/main/java/org/ruoyi/workflow/workflow/node/humanFeedBack/HumanFeedbackNode.java b/ruoyi-modules/ruoyi-aiflow/src/main/java/org/ruoyi/workflow/workflow/node/humanFeedBack/HumanFeedbackNode.java
index ea5b918d..bf14b716 100644
--- a/ruoyi-modules/ruoyi-aiflow/src/main/java/org/ruoyi/workflow/workflow/node/humanFeedBack/HumanFeedbackNode.java
+++ b/ruoyi-modules/ruoyi-aiflow/src/main/java/org/ruoyi/workflow/workflow/node/humanFeedBack/HumanFeedbackNode.java
@@ -7,6 +7,7 @@ import org.ruoyi.workflow.entity.WorkflowNode;
import org.ruoyi.workflow.workflow.NodeProcessResult;
import org.ruoyi.workflow.workflow.WfNodeState;
import org.ruoyi.workflow.workflow.WfState;
+import org.ruoyi.workflow.workflow.WorkflowUtil;
import org.ruoyi.workflow.workflow.data.NodeIOData;
import org.ruoyi.workflow.workflow.node.AbstractWfNode;
diff --git a/ruoyi-modules/ruoyi-aiflow/src/main/java/org/ruoyi/workflow/workflow/node/image/ImageNode.java b/ruoyi-modules/ruoyi-aiflow/src/main/java/org/ruoyi/workflow/workflow/node/image/ImageNode.java
index 095e4acd..4b887ad7 100644
--- a/ruoyi-modules/ruoyi-aiflow/src/main/java/org/ruoyi/workflow/workflow/node/image/ImageNode.java
+++ b/ruoyi-modules/ruoyi-aiflow/src/main/java/org/ruoyi/workflow/workflow/node/image/ImageNode.java
@@ -51,6 +51,11 @@ public class ImageNode extends AbstractWfNode {
Integer seed = nodeConfigObj.getSeed();
// 调用LLM生成图片(后续可以将图片保存到OSS中)
String imageUrl = workflowUtil.buildTextToImage(modelName, prompt, size, seed);
+ // 保存成功信息
+ String message = "图片生成地址:" + imageUrl;
+ saveSessionMessage(wfState, message);
+ // 发送驱动消息事件
+ sendSseEvent(message);
// 创建节点参数对象
NodeIOData nodeIOData = NodeIOData.createByText("output", "image", imageUrl);
// 添加到输出列表以便给后续节点使用
diff --git a/ruoyi-modules/ruoyi-aiflow/src/main/java/org/ruoyi/workflow/workflow/node/mailSend/MailSendNode.java b/ruoyi-modules/ruoyi-aiflow/src/main/java/org/ruoyi/workflow/workflow/node/mailSend/MailSendNode.java
index c006cbe4..0ae6a197 100644
--- a/ruoyi-modules/ruoyi-aiflow/src/main/java/org/ruoyi/workflow/workflow/node/mailSend/MailSendNode.java
+++ b/ruoyi-modules/ruoyi-aiflow/src/main/java/org/ruoyi/workflow/workflow/node/mailSend/MailSendNode.java
@@ -1,5 +1,7 @@
package org.ruoyi.workflow.workflow.node.mailSend;
+import com.alibaba.fastjson.JSONObject;
+import com.alibaba.fastjson.JSONValidator;
import jakarta.mail.internet.MimeMessage;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
@@ -31,6 +33,12 @@ public class MailSendNode extends AbstractWfNode {
try {
MailSendNodeConfig config = checkAndGetConfig(MailSendNodeConfig.class);
List inputs = state.getInputs();
+ // 获取输入信息
+ String input = getDataFromInput(inputs);
+ // 判断是否为JSON格式(LLM输出转换 由LLM生成格式)
+ if (StringUtils.isNotBlank(input) && isJson(input)) {
+ config = JSONObject.parseObject(input, MailSendNodeConfig.class);
+ }
// 安全获取模板(使用 defaultString 避免 null)
String subjectTemplate = StringUtils.defaultString(config.getSubject());
@@ -49,15 +57,7 @@ public class MailSendNode extends AbstractWfNode {
content = WorkflowUtil.renderTemplate(contentTemplate, inputs);
} else {
// 优先使用 output,如果没有则使用 input
- content = inputs.stream()
- .filter(item -> "output".equals(item.getName()))
- .map(NodeIOData::valueToString)
- .findFirst()
- .orElseGet(() -> inputs.stream()
- .filter(item -> "input".equals(item.getName()))
- .map(NodeIOData::valueToString)
- .findFirst()
- .orElse(""));
+ content = getDataFromInput(inputs);
}
// 将换行符转换为 HTML 换行
@@ -84,9 +84,9 @@ public class MailSendNode extends AbstractWfNode {
// 设置收件人
String[] toArray = Arrays.stream(toMails.split(","))
- .map(String::trim)
- .filter(StringUtils::isNotBlank)
- .toArray(String[]::new);
+ .map(String::trim)
+ .filter(StringUtils::isNotBlank)
+ .toArray(String[]::new);
if (toArray.length == 0) {
throw new IllegalArgumentException("收件人邮箱列表为空");
}
@@ -95,9 +95,9 @@ public class MailSendNode extends AbstractWfNode {
// 设置抄送(如有)
if (StringUtils.isNotBlank(ccMails)) {
String[] ccArray = Arrays.stream(ccMails.split(","))
- .map(String::trim)
- .filter(StringUtils::isNotBlank)
- .toArray(String[]::new);
+ .map(String::trim)
+ .filter(StringUtils::isNotBlank)
+ .toArray(String[]::new);
if (ccArray.length > 0) {
helper.setCc(ccArray);
}
@@ -111,25 +111,31 @@ public class MailSendNode extends AbstractWfNode {
mailSender.send(message);
log.info("Email sent successfully to: {}", toMails);
+ // 保存成功会话信息
+ String resultMessage = "发送邮箱成功";
+ saveSessionMessage(wfState, resultMessage);
+ // 发送驱动消息事件
+ sendSseEvent(resultMessage);
+
// 构造输出:统一输出为 output 参数
List outputs = new java.util.ArrayList<>();
// 优先使用 output,如果没有则使用 input(但重命名为 output)
inputs.stream()
- .filter(item -> "output".equals(item.getName()))
- .findFirst()
- .ifPresentOrElse(
- outputs::add,
- () -> inputs.stream()
- .filter(item -> "input".equals(item.getName()))
- .findFirst()
- .ifPresent(inputParam -> {
- String title = inputParam.getContent() != null && inputParam.getContent().getTitle() != null
- ? inputParam.getContent().getTitle() : "";
- NodeIOData outputParam = NodeIOData.createByText("output", title, inputParam.valueToString());
- outputs.add(outputParam);
- })
- );
+ .filter(item -> "output".equals(item.getName()))
+ .findFirst()
+ .ifPresentOrElse(
+ outputs::add,
+ () -> inputs.stream()
+ .filter(item -> "input".equals(item.getName()))
+ .findFirst()
+ .ifPresent(inputParam -> {
+ String title = inputParam.getContent() != null && inputParam.getContent().getTitle() != null
+ ? inputParam.getContent().getTitle() : "";
+ NodeIOData outputParam = NodeIOData.createByText("output", title, resultMessage);
+ outputs.add(outputParam);
+ })
+ );
return NodeProcessResult.builder().content(outputs).build();
@@ -138,23 +144,29 @@ public class MailSendNode extends AbstractWfNode {
// 异常时也统一输出为 output 参数,添加错误信息
List errorOutputs = new java.util.ArrayList<>();
- state.getInputs().stream()
- .filter(item -> "output".equals(item.getName()))
- .findFirst()
- .ifPresentOrElse(
- errorOutputs::add,
- () -> state.getInputs().stream()
- .filter(item -> "input".equals(item.getName()))
- .findFirst()
- .ifPresent(inputParam -> {
- String title = inputParam.getContent() != null && inputParam.getContent().getTitle() != null
- ? inputParam.getContent().getTitle() : "";
- NodeIOData outputParam = NodeIOData.createByText("output", title, inputParam.valueToString());
- errorOutputs.add(outputParam);
- })
- );
+ // 保存失败会话信息
+ String resultMessage = "发送邮箱失败: " + e.getMessage();
+ saveSessionMessage(wfState, resultMessage);
+ // 发送驱动消息事件
+ sendSseEvent(resultMessage);
- errorOutputs.add(NodeIOData.createByText("error", "mail", e.getMessage()));
+ state.getInputs().stream()
+ .filter(item -> "output".equals(item.getName()))
+ .findFirst()
+ .ifPresentOrElse(
+ errorOutputs::add,
+ () -> state.getInputs().stream()
+ .filter(item -> "input".equals(item.getName()))
+ .findFirst()
+ .ifPresent(inputParam -> {
+ String title = inputParam.getContent() != null && inputParam.getContent().getTitle() != null
+ ? inputParam.getContent().getTitle() : "";
+ NodeIOData outputParam = NodeIOData.createByText("output", title, resultMessage);
+ errorOutputs.add(outputParam);
+ })
+ );
+
+ errorOutputs.add(NodeIOData.createByText("error", "mail", resultMessage));
return NodeProcessResult.builder().content(errorOutputs).build();
}
}
@@ -174,4 +186,40 @@ public class MailSendNode extends AbstractWfNode {
return sender;
}
+
+ /**
+ * 获取信息
+ * @param inputs 用户输入
+ * @return 返回输入信息
+ */
+ public String getDataFromInput(List inputs) {
+ return inputs.stream()
+ .filter(item -> "output".equals(item.getName()))
+ .map(NodeIOData::valueToString)
+ .findFirst()
+ .orElseGet(() -> inputs.stream()
+ .filter(item -> "input".equals(item.getName()))
+ .map(NodeIOData::valueToString)
+ .findFirst()
+ .orElse(""));
+ }
+
+ /**
+ * 判断字符串是否为合法的 JSON 格式
+ *
+ * @param str 待检测的字符串
+ * @return true 表示是合法 JSON (包括 JSONObject, JSONArray, 或基本类型值)
+ */
+ public static boolean isJson(String str) {
+ if (str == null || str.trim().isEmpty()) {
+ return false;
+ }
+ // 使用 try-with-resources 正确处理 JSONValidator 资源关闭
+ try (JSONValidator validator = JSONValidator.from(str.trim())) {
+ return validator.getType() == JSONValidator.Type.Object;
+ } catch (Exception e) {
+ log.warn("JSON格式校验失败: {}", e.getMessage());
+ return false;
+ }
+ }
}
diff --git a/ruoyi-modules/ruoyi-aiflow/src/main/java/org/ruoyi/workflow/workflow/node/start/StartNode.java b/ruoyi-modules/ruoyi-aiflow/src/main/java/org/ruoyi/workflow/workflow/node/start/StartNode.java
index 6f5df29e..e9ccc2be 100644
--- a/ruoyi-modules/ruoyi-aiflow/src/main/java/org/ruoyi/workflow/workflow/node/start/StartNode.java
+++ b/ruoyi-modules/ruoyi-aiflow/src/main/java/org/ruoyi/workflow/workflow/node/start/StartNode.java
@@ -16,8 +16,8 @@ import org.ruoyi.workflow.workflow.node.AbstractWfNode;
import java.util.List;
import static org.ruoyi.workflow.cosntant.AdiConstant.WorkflowConstant.DEFAULT_OUTPUT_PARAM_NAME;
-import static org.ruoyi.workflow.enums.ErrorEnum.A_WF_NODE_CONFIG_ERROR;
-import static org.ruoyi.workflow.enums.ErrorEnum.A_WF_NODE_CONFIG_NOT_FOUND;
+import static org.ruoyi.common.chat.enums.ErrorEnum.A_WF_NODE_CONFIG_ERROR;
+import static org.ruoyi.common.chat.enums.ErrorEnum.A_WF_NODE_CONFIG_NOT_FOUND;
@Slf4j
public class StartNode extends AbstractWfNode {
diff --git a/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/controller/chat/ChatMessageController.java b/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/controller/chat/ChatMessageController.java
index c24de577..7d85cdb1 100644
--- a/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/controller/chat/ChatMessageController.java
+++ b/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/controller/chat/ChatMessageController.java
@@ -6,7 +6,9 @@ import lombok.RequiredArgsConstructor;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.constraints.*;
import cn.dev33.satoken.annotation.SaCheckPermission;
-import org.ruoyi.service.chat.IChatMessageService;
+import org.ruoyi.common.chat.domain.bo.chat.ChatMessageBo;
+import org.ruoyi.common.chat.domain.vo.chat.ChatMessageVo;
+import org.ruoyi.common.chat.service.chatMessage.IChatMessageService;
import org.springframework.web.bind.annotation.*;
import org.springframework.validation.annotation.Validated;
import org.ruoyi.common.idempotent.annotation.RepeatSubmit;
@@ -18,8 +20,6 @@ import org.ruoyi.common.core.validate.AddGroup;
import org.ruoyi.common.core.validate.EditGroup;
import org.ruoyi.common.log.enums.BusinessType;
import org.ruoyi.common.excel.utils.ExcelUtil;
-import org.ruoyi.domain.vo.chat.ChatMessageVo;
-import org.ruoyi.domain.bo.chat.ChatMessageBo;
import org.ruoyi.common.mybatis.core.page.TableDataInfo;
/**
diff --git a/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/controller/chat/ChatModelController.java b/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/controller/chat/ChatModelController.java
index 06212c1d..15884158 100644
--- a/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/controller/chat/ChatModelController.java
+++ b/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/controller/chat/ChatModelController.java
@@ -6,7 +6,7 @@ import lombok.RequiredArgsConstructor;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.constraints.*;
import cn.dev33.satoken.annotation.SaCheckPermission;
-import org.ruoyi.common.chat.Service.IChatModelService;
+import org.ruoyi.common.chat.service.chat.IChatModelService;
import org.ruoyi.common.chat.domain.bo.chat.ChatModelBo;
import org.ruoyi.common.chat.domain.vo.chat.ChatModelVo;
import org.ruoyi.enums.ModelType;
diff --git a/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/factory/EmbeddingModelFactory.java b/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/factory/EmbeddingModelFactory.java
index 0aecf556..41ae8160 100644
--- a/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/factory/EmbeddingModelFactory.java
+++ b/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/factory/EmbeddingModelFactory.java
@@ -2,7 +2,7 @@ package org.ruoyi.factory;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
-import org.ruoyi.common.chat.Service.IChatModelService;
+import org.ruoyi.common.chat.service.chat.IChatModelService;
import org.ruoyi.common.chat.domain.vo.chat.ChatModelVo;
import org.ruoyi.service.embed.BaseEmbedModelService;
import org.ruoyi.service.embed.MultiModalEmbedModelService;
diff --git a/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/mapper/chat/ChatMessageMapper.java b/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/mapper/chat/ChatMessageMapper.java
index 63793d19..51ad8651 100644
--- a/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/mapper/chat/ChatMessageMapper.java
+++ b/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/mapper/chat/ChatMessageMapper.java
@@ -1,7 +1,7 @@
package org.ruoyi.mapper.chat;
-import org.ruoyi.domain.entity.chat.ChatMessage;
-import org.ruoyi.domain.vo.chat.ChatMessageVo;
+import org.ruoyi.common.chat.domain.vo.chat.ChatMessageVo;
+import org.ruoyi.common.chat.entity.chat.ChatMessage;
import org.ruoyi.common.mybatis.core.mapper.BaseMapperPlus;
/**
diff --git a/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/mapper/chat/ChatModelMapper.java b/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/mapper/chat/ChatModelMapper.java
index 50c296a4..ee93917a 100644
--- a/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/mapper/chat/ChatModelMapper.java
+++ b/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/mapper/chat/ChatModelMapper.java
@@ -1,6 +1,6 @@
package org.ruoyi.mapper.chat;
-import org.ruoyi.common.chat.domain.entity.chat.ChatModel;
+import org.ruoyi.common.chat.entity.chat.ChatModel;
import org.ruoyi.common.chat.domain.vo.chat.ChatModelVo;
import org.ruoyi.common.mybatis.core.mapper.BaseMapperPlus;
diff --git a/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/service/chat/impl/AbstractStreamingChatService.java b/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/service/chat/impl/AbstractStreamingChatService.java
index 75894c9a..7d8b1a30 100644
--- a/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/service/chat/impl/AbstractStreamingChatService.java
+++ b/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/service/chat/impl/AbstractStreamingChatService.java
@@ -24,17 +24,20 @@ import org.ruoyi.agent.WebSearchAgent;
import org.ruoyi.agent.tool.ExecuteSqlQueryTool;
import org.ruoyi.agent.tool.QueryAllTablesTool;
import org.ruoyi.agent.tool.QueryTableSchemaTool;
-import org.ruoyi.common.chat.Service.IChatService;
+import org.ruoyi.common.chat.base.ThreadContext;
+import org.ruoyi.common.chat.domain.dto.request.ReSumeRunner;
+import org.ruoyi.common.chat.domain.dto.request.WorkFlowRunner;
+import org.ruoyi.common.chat.enums.RoleType;
+import org.ruoyi.common.chat.service.chat.IChatService;
import org.ruoyi.common.chat.domain.dto.request.ChatRequest;
-import org.ruoyi.common.chat.domain.entity.chat.ChatContext;
+import org.ruoyi.common.chat.entity.chat.ChatContext;
import org.ruoyi.common.chat.domain.vo.chat.ChatModelVo;
+import org.ruoyi.common.chat.service.chatMessage.AbstractChatMessageService;
+import org.ruoyi.common.chat.service.workFlow.IWorkFlowStarterService;
import org.ruoyi.common.core.utils.ObjectUtils;
import org.ruoyi.common.core.utils.SpringUtils;
import org.ruoyi.common.core.utils.StringUtils;
import org.ruoyi.common.sse.utils.SseMessageUtils;
-import org.ruoyi.domain.bo.chat.ChatMessageBo;
-import org.ruoyi.enums.RoleType;
-import org.ruoyi.service.chat.IChatMessageService;
import org.ruoyi.service.chat.impl.memory.PersistentChatMemoryStore;
import org.springframework.util.CollectionUtils;
import org.springframework.validation.annotation.Validated;
@@ -58,7 +61,7 @@ import java.util.concurrent.ConcurrentHashMap;
*/
@Slf4j
@Validated
-public abstract class AbstractStreamingChatService implements IChatService {
+public abstract class AbstractStreamingChatService extends AbstractChatMessageService implements IChatService {
/**
* 默认保留的消息窗口大小(用于长期记忆)
@@ -76,6 +79,11 @@ public abstract class AbstractStreamingChatService implements IChatService {
*/
private static final Map