context:工作流和Ai Chat对话消息功能整合

This commit is contained in:
zengxb
2026-02-26 14:36:33 +08:00
parent d6e4a50d6e
commit 8954f59cd7
79 changed files with 548 additions and 254 deletions

View File

@@ -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); 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; 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', '');

View File

@@ -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);

View File

@@ -62,6 +62,12 @@
<groupId>org.ruoyi</groupId> <groupId>org.ruoyi</groupId>
<artifactId>ruoyi-common-tenant</artifactId> <artifactId>ruoyi-common-tenant</artifactId>
</dependency> </dependency>
<dependency>
<groupId>io.swagger.core.v3</groupId>
<artifactId>swagger-annotations</artifactId>
<version>${swagger-annotations.version}</version>
</dependency>
</dependencies> </dependencies>
</project> </project>

View File

@@ -1,14 +1,14 @@
package org.ruoyi.workflow.base; package org.ruoyi.common.chat.base;
import cn.dev33.satoken.stp.StpUtil; import cn.dev33.satoken.stp.StpUtil;
import org.apache.commons.lang3.StringUtils; 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.domain.model.LoginUser;
import org.ruoyi.common.core.exception.base.BaseException; import org.ruoyi.common.core.exception.base.BaseException;
import org.ruoyi.common.satoken.utils.LoginHelper; 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 登录态 * 线程上下文适配器统一接入 Sa-Token 登录态

View File

@@ -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 io.github.linpeilie.annotations.AutoMapper;
import jakarta.validation.constraints.NotNull;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; 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 * 聊天消息业务对象 chat_message

View File

@@ -4,7 +4,7 @@ import io.github.linpeilie.annotations.AutoMapper;
import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.NotNull;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; 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.core.validate.EditGroup;
import org.ruoyi.common.mybatis.core.domain.BaseEntity; import org.ruoyi.common.mybatis.core.domain.BaseEntity;

View File

@@ -21,6 +21,21 @@ public class ChatRequest {
@NotEmpty(message = "传入的模型不能为空") @NotEmpty(message = "传入的模型不能为空")
private String model; private String model;
/**
* 工作流请求体
*/
private WorkFlowRunner workFlowRunner;
/**
* 人机交互信息体
*/
private ReSumeRunner reSumeRunner;
/**
* 是否启用工作流
*/
private Boolean enableWorkFlow;
/** /**
* 会话id * 会话id
*/ */
@@ -41,6 +56,11 @@ public class ChatRequest {
*/ */
private Long uuid; private Long uuid;
/**
* 是否为人机交互用户继续输入
*/
private Boolean isResume;
/** /**
* 是否启用深度思考 * 是否启用深度思考
*/ */

View File

@@ -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;
}

View File

@@ -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<ObjectNode> inputs;
private String uuid;
}

View File

@@ -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.ExcelIgnoreUnannotated;
import cn.idev.excel.annotation.ExcelProperty; 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 io.github.linpeilie.annotations.AutoMapper;
import lombok.Data; 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.Serial;
import java.io.Serializable; import java.io.Serializable;
/** /**
* 聊天消息视图对象 chat_message * 聊天消息视图对象 chat_message
* *

View File

@@ -5,7 +5,7 @@ import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
import cn.idev.excel.annotation.ExcelProperty; import cn.idev.excel.annotation.ExcelProperty;
import io.github.linpeilie.annotations.AutoMapper; import io.github.linpeilie.annotations.AutoMapper;
import lombok.Data; 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.Serial;
import java.io.Serializable; import java.io.Serializable;

View File

@@ -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.IdType;
import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableField;

View File

@@ -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.TableField;
import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import org.ruoyi.workflow.enums.UserStatusEnum; import org.ruoyi.common.chat.enums.UserStatusEnum;
import java.time.LocalDateTime; import java.time.LocalDateTime;

View File

@@ -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 dev.langchain4j.model.chat.response.StreamingChatResponseHandler;
import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.NotNull;

View File

@@ -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.TableId;
import com.baomidou.mybatisplus.annotation.*; import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import org.ruoyi.common.tenant.core.TenantEntity;
import java.io.Serial; import java.io.Serial;

View File

@@ -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.TableId;
import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.annotation.TableName;

View File

@@ -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.Max;
import jakarta.validation.constraints.Min; import jakarta.validation.constraints.Min;

View File

@@ -1,4 +1,4 @@
package org.ruoyi.workflow.enums; package org.ruoyi.common.chat.enums;
import com.baomidou.mybatisplus.annotation.IEnum; import com.baomidou.mybatisplus.annotation.IEnum;

View File

@@ -1,4 +1,4 @@
package org.ruoyi.workflow.enums; package org.ruoyi.common.chat.enums;
import lombok.Getter; import lombok.Getter;

View File

@@ -1,4 +1,4 @@
package org.ruoyi.enums; package org.ruoyi.common.chat.enums;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Getter; import lombok.Getter;
@@ -18,6 +18,7 @@ public enum RoleType {
ASSISTANT("assistant"), ASSISTANT("assistant"),
FUNCTION("function"), FUNCTION("function"),
TOOL("tool"), TOOL("tool"),
WORKFLOW("workFlow")
; ;
private final String name; private final String name;

View File

@@ -1,4 +1,4 @@
package org.ruoyi.workflow.enums; package org.ruoyi.common.chat.enums;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Getter; import lombok.Getter;

View File

@@ -1,6 +1,6 @@
package org.ruoyi.common.chat.factory; 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.beans.BeansException;
import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware; import org.springframework.context.ApplicationContextAware;

View File

@@ -1,6 +1,6 @@
package org.ruoyi.common.chat.factory; 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.beans.BeansException;
import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware; import org.springframework.context.ApplicationContextAware;

View File

@@ -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.bo.chat.ChatModelBo;
import org.ruoyi.common.chat.domain.vo.chat.ChatModelVo; import org.ruoyi.common.chat.domain.vo.chat.ChatModelVo;

View File

@@ -1,7 +1,7 @@
package org.ruoyi.common.chat.Service; package org.ruoyi.common.chat.service.chat;
import jakarta.validation.Valid; 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; import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
/** /**

View File

@@ -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 "默认工作流大模型";
}
}

View File

@@ -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.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.PageQuery;
import org.ruoyi.common.mybatis.core.page.TableDataInfo; 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.Collection;
import java.util.List; import java.util.List;

View File

@@ -1,7 +1,7 @@
package org.ruoyi.common.chat.Service; package org.ruoyi.common.chat.service.image;
import jakarta.validation.Valid; import jakarta.validation.Valid;
import org.ruoyi.common.chat.domain.entity.image.ImageContext; import org.ruoyi.common.chat.entity.image.ImageContext;
/** /**
* 公共文生图接口 * 公共文生图接口

View File

@@ -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<ObjectNode> userInputs, Long sessionId);
/**
* 恢复工作流
* @param runtimeUuid 运行时UUID
* @param userInput 用户输入
* @param sseEmitter SSE连接对象
*/
void resumeFlow(String runtimeUuid, String userInput, SseEmitter sseEmitter);
}

View File

@@ -65,7 +65,7 @@ public class SseEmitterManager {
emitter.onCompletion(() -> { emitter.onCompletion(() -> {
SseEmitter remove = emitters.remove(token); SseEmitter remove = emitters.remove(token);
if (remove != null) { if (remove != null) {
remove.complete(); // remove.complete();
} }
}); });
emitter.onTimeout(() -> { emitter.onTimeout(() -> {

View File

@@ -81,12 +81,6 @@
</dependency> </dependency>
<dependency>
<groupId>io.swagger.core.v3</groupId>
<artifactId>swagger-annotations</artifactId>
<version>${swagger-annotations.version}</version>
</dependency>
<dependency> <dependency>
<groupId>com.google.api-client</groupId> <groupId>com.google.api-client</groupId>
<artifactId>google-api-client</artifactId> <artifactId>google-api-client</artifactId>

View File

@@ -1,7 +1,7 @@
package org.ruoyi.workflow.base; package org.ruoyi.workflow.base;
import lombok.Data; import lombok.Data;
import org.ruoyi.workflow.enums.ErrorEnum; import org.ruoyi.common.chat.enums.ErrorEnum;
import java.io.Serializable; import java.io.Serializable;

View File

@@ -5,8 +5,8 @@ import io.swagger.v3.oas.annotations.Operation;
import jakarta.annotation.Resource; import jakarta.annotation.Resource;
import jakarta.validation.constraints.Min; import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.NotNull;
import org.ruoyi.common.chat.base.ThreadContext;
import org.ruoyi.common.core.domain.R; import org.ruoyi.common.core.domain.R;
import org.ruoyi.workflow.base.ThreadContext;
import org.ruoyi.workflow.dto.workflow.*; import org.ruoyi.workflow.dto.workflow.*;
import org.ruoyi.workflow.entity.WorkflowComponent; import org.ruoyi.workflow.entity.WorkflowComponent;
import org.ruoyi.workflow.service.WorkflowComponentService; import org.ruoyi.workflow.service.WorkflowComponentService;
@@ -72,7 +72,7 @@ public class WorkflowController {
@Operation(summary = "流式响应") @Operation(summary = "流式响应")
@PostMapping(value = "/run", produces = MediaType.TEXT_EVENT_STREAM_VALUE) @PostMapping(value = "/run", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public SseEmitter sseAsk(@RequestBody WorkflowRunReq runReq) { 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") @GetMapping("/mine/search")

View File

@@ -30,7 +30,7 @@ public class WorkflowRuntimeController {
@Operation(summary = "接收用户输入以继续执行剩余流程") @Operation(summary = "接收用户输入以继续执行剩余流程")
@PostMapping(value = "/resume/{runtimeUuid}") @PostMapping(value = "/resume/{runtimeUuid}")
public R resume(@PathVariable String runtimeUuid, @RequestBody WorkflowResumeReq resumeReq) { public R resume(@PathVariable String runtimeUuid, @RequestBody WorkflowResumeReq resumeReq) {
workflowStarter.resumeFlow(runtimeUuid, resumeReq.getFeedbackContent()); workflowStarter.resumeFlow(runtimeUuid, resumeReq.getFeedbackContent(), resumeReq.getSseEmitter());
return R.ok(); return R.ok();
} }

View File

@@ -1,8 +1,10 @@
package org.ruoyi.workflow.dto.workflow; package org.ruoyi.workflow.dto.workflow;
import lombok.Data; import lombok.Data;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
@Data @Data
public class WorkflowResumeReq { public class WorkflowResumeReq {
private String feedbackContent; private String feedbackContent;
private SseEmitter sseEmitter;
} }

View File

@@ -9,6 +9,7 @@ import java.util.List;
public class WorkflowRunReq { public class WorkflowRunReq {
private List<ObjectNode> inputs; private List<ObjectNode> inputs;
private String uuid; private String uuid;
private Long sessionId;
} }

View File

@@ -5,6 +5,7 @@ import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import org.ruoyi.common.chat.entity.BaseEntity;
import java.io.Serial; import java.io.Serial;

View File

@@ -5,6 +5,7 @@ import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import org.ruoyi.common.chat.entity.BaseEntity;
import java.io.Serial; import java.io.Serial;

View File

@@ -5,6 +5,7 @@ import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import org.ruoyi.common.chat.entity.BaseEntity;
import java.io.Serial; import java.io.Serial;

View File

@@ -5,6 +5,7 @@ import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import org.ruoyi.common.chat.entity.BaseEntity;
import java.io.Serial; import java.io.Serial;

View File

@@ -5,6 +5,7 @@ import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import org.ruoyi.common.chat.entity.BaseEntity;
import java.io.Serial; import java.io.Serial;

View File

@@ -5,6 +5,7 @@ import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import org.ruoyi.common.chat.entity.BaseEntity;
import java.io.Serial; import java.io.Serial;

View File

@@ -2,6 +2,7 @@ package org.ruoyi.workflow.enums;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Getter; import lombok.Getter;
import org.ruoyi.common.chat.enums.BaseEnum;
@Getter @Getter
@AllArgsConstructor @AllArgsConstructor

View File

@@ -2,6 +2,7 @@ package org.ruoyi.workflow.enums;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Getter; import lombok.Getter;
import org.ruoyi.common.chat.enums.BaseEnum;
import java.util.Arrays; import java.util.Arrays;

View File

@@ -5,9 +5,9 @@ import com.google.common.cache.CacheBuilder;
import jakarta.annotation.Resource; import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.ruoyi.common.chat.entity.User;
import org.ruoyi.workflow.cosntant.AdiConstant; import org.ruoyi.workflow.cosntant.AdiConstant;
import org.ruoyi.workflow.cosntant.RedisKeyConstant; import org.ruoyi.workflow.cosntant.RedisKeyConstant;
import org.ruoyi.workflow.entity.User;
import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter; import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;

View File

@@ -7,11 +7,11 @@ import com.baomidou.mybatisplus.extension.toolkit.ChainWrappers;
import jakarta.annotation.Resource; import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.ruoyi.common.chat.enums.ErrorEnum;
import org.ruoyi.common.core.exception.base.BaseException; import org.ruoyi.common.core.exception.base.BaseException;
import org.ruoyi.workflow.dto.workflow.WfComponentReq; import org.ruoyi.workflow.dto.workflow.WfComponentReq;
import org.ruoyi.workflow.dto.workflow.WfComponentSearchReq; import org.ruoyi.workflow.dto.workflow.WfComponentSearchReq;
import org.ruoyi.workflow.entity.WorkflowComponent; import org.ruoyi.workflow.entity.WorkflowComponent;
import org.ruoyi.workflow.enums.ErrorEnum;
import org.ruoyi.workflow.mapper.WorkflowComponentMapper; import org.ruoyi.workflow.mapper.WorkflowComponentMapper;
import org.ruoyi.workflow.util.PrivilegeUtil; import org.ruoyi.workflow.util.PrivilegeUtil;
import org.ruoyi.workflow.util.UuidUtil; 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_COMPONENTS;
import static org.ruoyi.workflow.cosntant.RedisKeyConstant.WORKFLOW_COMPONENT_START_KEY; 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 @Slf4j
@Service @Service

View File

@@ -5,10 +5,10 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.baomidou.mybatisplus.extension.toolkit.ChainWrappers; import com.baomidou.mybatisplus.extension.toolkit.ChainWrappers;
import jakarta.annotation.Resource; import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.ruoyi.common.chat.enums.ErrorEnum;
import org.ruoyi.common.core.exception.base.BaseException; import org.ruoyi.common.core.exception.base.BaseException;
import org.ruoyi.workflow.dto.workflow.WfEdgeReq; import org.ruoyi.workflow.dto.workflow.WfEdgeReq;
import org.ruoyi.workflow.entity.WorkflowEdge; import org.ruoyi.workflow.entity.WorkflowEdge;
import org.ruoyi.workflow.enums.ErrorEnum;
import org.ruoyi.workflow.mapper.WorkflowEdgeMapper; import org.ruoyi.workflow.mapper.WorkflowEdgeMapper;
import org.ruoyi.workflow.util.MPPageUtil; import org.ruoyi.workflow.util.MPPageUtil;
import org.ruoyi.workflow.util.UuidUtil; import org.ruoyi.workflow.util.UuidUtil;

View File

@@ -6,12 +6,12 @@ import com.baomidou.mybatisplus.extension.toolkit.ChainWrappers;
import com.fasterxml.jackson.databind.node.ObjectNode; import com.fasterxml.jackson.databind.node.ObjectNode;
import jakarta.annotation.Resource; import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.ruoyi.common.chat.enums.ErrorEnum;
import org.ruoyi.common.core.exception.base.BaseException; import org.ruoyi.common.core.exception.base.BaseException;
import org.ruoyi.workflow.dto.workflow.WfNodeDto; import org.ruoyi.workflow.dto.workflow.WfNodeDto;
import org.ruoyi.workflow.entity.Workflow; import org.ruoyi.workflow.entity.Workflow;
import org.ruoyi.workflow.entity.WorkflowComponent; import org.ruoyi.workflow.entity.WorkflowComponent;
import org.ruoyi.workflow.entity.WorkflowNode; import org.ruoyi.workflow.entity.WorkflowNode;
import org.ruoyi.workflow.enums.ErrorEnum;
import org.ruoyi.workflow.enums.WfIODataTypeEnum; import org.ruoyi.workflow.enums.WfIODataTypeEnum;
import org.ruoyi.workflow.mapper.WorkflowNodeMapper; import org.ruoyi.workflow.mapper.WorkflowNodeMapper;
import org.ruoyi.workflow.util.JsonUtil; import org.ruoyi.workflow.util.JsonUtil;

View File

@@ -4,9 +4,9 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.baomidou.mybatisplus.extension.toolkit.ChainWrappers; import com.baomidou.mybatisplus.extension.toolkit.ChainWrappers;
import com.fasterxml.jackson.databind.node.ObjectNode; import com.fasterxml.jackson.databind.node.ObjectNode;
import lombok.extern.slf4j.Slf4j; 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.dto.workflow.WfRuntimeNodeDto;
import org.ruoyi.workflow.entity.User;
import org.ruoyi.workflow.entity.WorkflowRuntimeNode; import org.ruoyi.workflow.entity.WorkflowRuntimeNode;
import org.ruoyi.workflow.mapper.WorkflowRuntimeNodeMapper; import org.ruoyi.workflow.mapper.WorkflowRuntimeNodeMapper;
import org.ruoyi.workflow.util.JsonUtil; import org.ruoyi.workflow.util.JsonUtil;

View File

@@ -7,13 +7,13 @@ import com.fasterxml.jackson.databind.node.ObjectNode;
import jakarta.annotation.Resource; import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils; 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.WfRuntimeNodeDto;
import org.ruoyi.workflow.dto.workflow.WfRuntimeResp; import org.ruoyi.workflow.dto.workflow.WfRuntimeResp;
import org.ruoyi.workflow.entity.User;
import org.ruoyi.workflow.entity.Workflow; import org.ruoyi.workflow.entity.Workflow;
import org.ruoyi.workflow.entity.WorkflowRuntime; import org.ruoyi.workflow.entity.WorkflowRuntime;
import org.ruoyi.workflow.enums.ErrorEnum;
import org.ruoyi.workflow.mapper.WorkflowRunMapper; import org.ruoyi.workflow.mapper.WorkflowRunMapper;
import org.ruoyi.workflow.util.JsonUtil; import org.ruoyi.workflow.util.JsonUtil;
import org.ruoyi.workflow.util.MPPageUtil; import org.ruoyi.workflow.util.MPPageUtil;

Some files were not shown because too many files have changed in this diff Show More