From cee484403a94584ef1fb55bbac641f7bcbfaf6d8 Mon Sep 17 00:00:00 2001
From: Administrator <15274802129@163.com>
Date: Wed, 08 Apr 2026 11:25:21 +0800
Subject: [PATCH] feat(ai): 添加智能体对话功能和相关实体映射

---
 src/main/java/cc/mrbird/febs/ai/entity/AiTalk.java                                      |    3 
 src/main/java/cc/mrbird/febs/ai/mapper/AiKnowledgeFileMapper.java                       |    8 
 src/main/java/cc/mrbird/febs/ai/service/impl/AiTalkItemServiceImpl.java                 |    2 
 src/main/java/cc/mrbird/febs/ai/req/agent/AgentInitDto.java                             |   17 +
 src/main/java/cc/mrbird/febs/ai/entity/AiAgentKnowledge.java                            |   29 ++
 src/main/java/cc/mrbird/febs/ai/req/agent/AiRequestDto.java                             |   25 ++
 src/main/java/cc/mrbird/febs/ai/service/impl/AiAgentServiceImpl.java                    |  185 +++++++++++++++++
 src/main/java/cc/mrbird/febs/ai/req/agent/AgentSendInitVo.java                          |   15 +
 src/main/java/cc/mrbird/febs/ai/req/agent/AitalkItemStreamVo.java                       |   16 +
 src/main/java/cc/mrbird/febs/ai/service/AiAgentService.java                             |   11 
 src/main/java/cc/mrbird/febs/ai/entity/AiKnowledgeFile.java                             |   37 +++
 src/main/java/cc/mrbird/febs/ai/mapper/AiAgentKnowledgeMapper.java                      |    8 
 src/main/java/cc/mrbird/febs/ai/strategy/Impl/HsLlmStrategyServiceImpl.java             |    6 
 src/main/java/cc/mrbird/febs/ai/entity/AiTalkItem.java                                  |    2 
 src/main/java/cc/mrbird/febs/ai/req/agent/AgentSaveContextDto.java                      |   26 ++
 src/main/java/cc/mrbird/febs/ai/service/impl/AiTalkServiceImpl.java                     |    2 
 src/main/java/cc/mrbird/febs/ai/service/AiTalkItemService.java                          |    2 
 src/main/java/cc/mrbird/febs/ai/strategy/LlmStrategyService.java                        |    3 
 src/main/java/cc/mrbird/febs/ai/req/agent/AitalkItemStreamDto.java                      |   20 ++
 src/main/java/cc/mrbird/febs/ai/req/talk/ApiTalkDto.java                                |    2 
 src/main/java/cc/mrbird/febs/ai/strategy/Impl/AliApplicationLlmStrategyServiceImpl.java |    6 
 src/main/java/cc/mrbird/febs/ai/strategy/Impl/AliLlmStrategyServiceImpl.java            |  115 +++++++++++
 src/main/java/cc/mrbird/febs/ai/controller/agent/ApiAgentController.java                |   37 +++
 23 files changed, 557 insertions(+), 20 deletions(-)

diff --git a/src/main/java/cc/mrbird/febs/ai/controller/agent/ApiAgentController.java b/src/main/java/cc/mrbird/febs/ai/controller/agent/ApiAgentController.java
index 6655c9f..721abc6 100644
--- a/src/main/java/cc/mrbird/febs/ai/controller/agent/ApiAgentController.java
+++ b/src/main/java/cc/mrbird/febs/ai/controller/agent/ApiAgentController.java
@@ -1,8 +1,6 @@
 package cc.mrbird.febs.ai.controller.agent;
 
-import cc.mrbird.febs.ai.req.agent.AiAgentInitDto;
-import cc.mrbird.febs.ai.req.agent.ApiAgentCategoryAllDto;
-import cc.mrbird.febs.ai.req.agent.ApiAgentPageDto;
+import cc.mrbird.febs.ai.req.agent.*;
 import cc.mrbird.febs.ai.req.productCategory.ApiProductCategoryAllDto;
 import cc.mrbird.febs.ai.res.agent.AiAgentInitVo;
 import cc.mrbird.febs.ai.res.agent.ApiAgentCategoryVo;
@@ -10,6 +8,7 @@
 import cc.mrbird.febs.ai.res.productCategory.ApiProductCategoryVo;
 import cc.mrbird.febs.ai.service.AiAgentService;
 import cc.mrbird.febs.common.entity.FebsResponse;
+import cn.hutool.core.util.StrUtil;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import io.swagger.annotations.ApiResponse;
@@ -18,6 +17,7 @@
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.*;
+import reactor.core.publisher.Flux;
 
 import javax.servlet.http.HttpServletRequest;
 
@@ -55,7 +55,7 @@
         return service.agentList(dto);
     }
 
-    @ApiOperation(value = "初始化智能体", notes = "初始化智能体")
+    @ApiOperation(value = "详情", notes = "详情")
     @ApiResponses({
             @ApiResponse(code = 200, message = "success", response = AiAgentInitVo.class)
     })
@@ -65,6 +65,35 @@
         return service.initAgent(dto);
     }
 
+    @ApiOperation(value = "初始化对话", notes = "初始化对话")
+    @ApiResponses({
+            @ApiResponse(code = 200, message = "success", response = AgentSendInitVo.class)
+    })
+    @PostMapping(value = "/initSend", produces = "application/json")
+    public FebsResponse initSend(@RequestBody @Validated AgentInitDto dto) {
+
+        return service.initSend(dto);
+    }
+
+    @ApiOperation(value = "保存对话消息", notes = "保存对话消息")
+    @PostMapping(value = "/saveContext")
+    public FebsResponse saveContext(@RequestBody @Validated AgentSaveContextDto dto) {
+
+        return service.saveContext(dto);
+    }
+
+    @ApiOperation("AI回答(流式)")
+    @ApiResponses({
+            @ApiResponse(code = 200, message = "流式响应", response = AitalkItemStreamVo.class),
+    })
+    @PostMapping("/aiAnswer")
+    public Flux<FebsResponse> aiAnswer(@RequestBody @Validated AitalkItemStreamDto dto) {
+        if (StrUtil.isEmpty(dto.getTalkId()) || StrUtil.isEmpty(dto.getReqContext())|| StrUtil.isEmpty(dto.getReqContext())){
+            return Flux.just(new FebsResponse().fail().message("参数异常"));
+        }
+        return service.aiAnswer(dto);
+    }
+
 
 
 }
diff --git a/src/main/java/cc/mrbird/febs/ai/entity/AiAgentKnowledge.java b/src/main/java/cc/mrbird/febs/ai/entity/AiAgentKnowledge.java
new file mode 100644
index 0000000..9662b93
--- /dev/null
+++ b/src/main/java/cc/mrbird/febs/ai/entity/AiAgentKnowledge.java
@@ -0,0 +1,29 @@
+package cc.mrbird.febs.ai.entity;
+
+import cc.mrbird.febs.common.entity.AiBaseEntity;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+
+import java.util.Date;
+
+@Data
+@TableName("ai_agent_knowledge")
+public class AiAgentKnowledge extends AiBaseEntity {
+
+
+    /** 公司ID */
+    private String companyId;
+    
+    /** 名称 */
+    private String name;
+    
+    /** 知识创建时间 */
+    private Date knowledgeCreateTime;
+
+    /** 智能体ID */
+    private String agentId;
+
+    /** 知识库ID */
+    private String knowledgeId;
+
+}
diff --git a/src/main/java/cc/mrbird/febs/ai/entity/AiKnowledgeFile.java b/src/main/java/cc/mrbird/febs/ai/entity/AiKnowledgeFile.java
new file mode 100644
index 0000000..8b87af5
--- /dev/null
+++ b/src/main/java/cc/mrbird/febs/ai/entity/AiKnowledgeFile.java
@@ -0,0 +1,37 @@
+package cc.mrbird.febs.ai.entity;
+
+import cc.mrbird.febs.common.entity.AiBaseEntity;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+
+@Data
+@TableName("ai_knowledge_file")
+public class AiKnowledgeFile extends AiBaseEntity {
+    /**
+     * 状态:0-上传服务器,1-应用数据,2-知识库 3-成功
+     */
+    private Integer state;
+    /**
+     * 文件ID
+     */
+    private String jobId;
+    /**
+     * 文件ID
+     */
+    private String fileId;
+
+    /**
+     * 文件存储路径
+     */
+    private String savePath;
+
+    /**
+     * 文件名称
+     */
+    private String name;
+
+    /**
+     * 公司ID
+     */
+    private String companyId;
+}
diff --git a/src/main/java/cc/mrbird/febs/ai/entity/AiTalk.java b/src/main/java/cc/mrbird/febs/ai/entity/AiTalk.java
index b324bb2..558065c 100644
--- a/src/main/java/cc/mrbird/febs/ai/entity/AiTalk.java
+++ b/src/main/java/cc/mrbird/febs/ai/entity/AiTalk.java
@@ -27,4 +27,7 @@
      * 用户ID (UUID)
      */
     private String memberId;
+
+    /** 智能体ID */
+    private String agentId;
 }
diff --git a/src/main/java/cc/mrbird/febs/ai/entity/AiTalkItem.java b/src/main/java/cc/mrbird/febs/ai/entity/AiTalkItem.java
index 8526911..f2fd0c0 100644
--- a/src/main/java/cc/mrbird/febs/ai/entity/AiTalkItem.java
+++ b/src/main/java/cc/mrbird/febs/ai/entity/AiTalkItem.java
@@ -30,7 +30,7 @@
     /**
      * 类型 1-用户提问 2-AI回答
      */
-    private Integer type;
+    private String type;
 
     /**
      * 内容
diff --git a/src/main/java/cc/mrbird/febs/ai/mapper/AiAgentKnowledgeMapper.java b/src/main/java/cc/mrbird/febs/ai/mapper/AiAgentKnowledgeMapper.java
new file mode 100644
index 0000000..b820f39
--- /dev/null
+++ b/src/main/java/cc/mrbird/febs/ai/mapper/AiAgentKnowledgeMapper.java
@@ -0,0 +1,8 @@
+package cc.mrbird.febs.ai.mapper;
+
+import cc.mrbird.febs.ai.entity.AiAgent;
+import cc.mrbird.febs.ai.entity.AiAgentKnowledge;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+public interface AiAgentKnowledgeMapper extends BaseMapper<AiAgentKnowledge> {
+}
diff --git a/src/main/java/cc/mrbird/febs/ai/mapper/AiKnowledgeFileMapper.java b/src/main/java/cc/mrbird/febs/ai/mapper/AiKnowledgeFileMapper.java
new file mode 100644
index 0000000..83ce4a6
--- /dev/null
+++ b/src/main/java/cc/mrbird/febs/ai/mapper/AiKnowledgeFileMapper.java
@@ -0,0 +1,8 @@
+package cc.mrbird.febs.ai.mapper;
+
+import cc.mrbird.febs.ai.entity.AiAgentKnowledge;
+import cc.mrbird.febs.ai.entity.AiKnowledgeFile;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+public interface AiKnowledgeFileMapper extends BaseMapper<AiKnowledgeFile> {
+}
diff --git a/src/main/java/cc/mrbird/febs/ai/req/agent/AgentInitDto.java b/src/main/java/cc/mrbird/febs/ai/req/agent/AgentInitDto.java
new file mode 100644
index 0000000..bb13ff9
--- /dev/null
+++ b/src/main/java/cc/mrbird/febs/ai/req/agent/AgentInitDto.java
@@ -0,0 +1,17 @@
+package cc.mrbird.febs.ai.req.agent;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import javax.validation.constraints.NotBlank;
+
+@Data
+@ApiModel(value = "AgentInitDto", description = "参数")
+public class AgentInitDto {
+
+    @NotBlank(message = "智能体不能为空")
+    @ApiModelProperty(value = "智能体ID", example = "you_ke_*****")
+    private String id;
+}
+
diff --git a/src/main/java/cc/mrbird/febs/ai/req/agent/AgentSaveContextDto.java b/src/main/java/cc/mrbird/febs/ai/req/agent/AgentSaveContextDto.java
new file mode 100644
index 0000000..a1c084a
--- /dev/null
+++ b/src/main/java/cc/mrbird/febs/ai/req/agent/AgentSaveContextDto.java
@@ -0,0 +1,26 @@
+package cc.mrbird.febs.ai.req.agent;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import javax.validation.constraints.NotBlank;
+
+@Data
+@ApiModel(value = "AgentSaveContextDto", description = "参数")
+public class AgentSaveContextDto {
+    /**
+     * 用户对话ID (UUID)
+     */
+    @NotBlank(message = "会话ID不能为空")
+    @ApiModelProperty(value = "会话ID", example = "10")
+    private String talkId;
+
+    @NotBlank(message = "类型不能为空")
+    @ApiModelProperty(value = "类型 ai:assistant ,用户:user", example = "assistant")
+    private String type;
+
+    @NotBlank(message = "内容不能为空")
+    @ApiModelProperty(value = "内容", example = "10")
+    private String content;
+}
diff --git a/src/main/java/cc/mrbird/febs/ai/req/agent/AgentSendInitVo.java b/src/main/java/cc/mrbird/febs/ai/req/agent/AgentSendInitVo.java
new file mode 100644
index 0000000..f32b29f
--- /dev/null
+++ b/src/main/java/cc/mrbird/febs/ai/req/agent/AgentSendInitVo.java
@@ -0,0 +1,15 @@
+package cc.mrbird.febs.ai.req.agent;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import javax.validation.constraints.NotBlank;
+
+@Data
+@ApiModel(value = "AgentSendInitVo", description = "参数")
+public class AgentSendInitVo {
+
+    @ApiModelProperty(value = "会话ID", example = "1")
+    private String talkId;
+}
diff --git a/src/main/java/cc/mrbird/febs/ai/req/agent/AiRequestDto.java b/src/main/java/cc/mrbird/febs/ai/req/agent/AiRequestDto.java
new file mode 100644
index 0000000..43d084f
--- /dev/null
+++ b/src/main/java/cc/mrbird/febs/ai/req/agent/AiRequestDto.java
@@ -0,0 +1,25 @@
+package cc.mrbird.febs.ai.req.agent;
+
+import com.alibaba.dashscope.common.Message;
+import lombok.Data;
+
+import java.util.List;
+
+@Data
+public class AiRequestDto {
+
+    private List<Message> messages;
+
+    private List<String> knowledgeIds ;
+
+    private List<String> fileIds;
+
+    private String prompt;
+
+    private String rolePrompt;
+
+    private String talkId;
+
+    private String companyId;
+
+}
\ No newline at end of file
diff --git a/src/main/java/cc/mrbird/febs/ai/req/agent/AitalkItemStreamDto.java b/src/main/java/cc/mrbird/febs/ai/req/agent/AitalkItemStreamDto.java
new file mode 100644
index 0000000..f92a372
--- /dev/null
+++ b/src/main/java/cc/mrbird/febs/ai/req/agent/AitalkItemStreamDto.java
@@ -0,0 +1,20 @@
+package cc.mrbird.febs.ai.req.agent;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import javax.validation.constraints.NotBlank;
+
+@Data
+@ApiModel(value = "AitalkItemStreamDto", description = "参数")
+public class AitalkItemStreamDto {
+
+    @NotBlank(message = "会话不能为空")
+    @ApiModelProperty(value = "会话ID", example = "10")
+    private String talkId;
+
+    @NotBlank(message = "内容不能为空")
+    @ApiModelProperty(value = "内容", example = "10")
+    private String reqContext;
+}
diff --git a/src/main/java/cc/mrbird/febs/ai/req/agent/AitalkItemStreamVo.java b/src/main/java/cc/mrbird/febs/ai/req/agent/AitalkItemStreamVo.java
new file mode 100644
index 0000000..e52878a
--- /dev/null
+++ b/src/main/java/cc/mrbird/febs/ai/req/agent/AitalkItemStreamVo.java
@@ -0,0 +1,16 @@
+package cc.mrbird.febs.ai.req.agent;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+@Data
+@ApiModel(value = "AitalkItemStreamVo", description = "参数")
+public class AitalkItemStreamVo {
+
+    @ApiModelProperty(value = "消息")
+    private String content;
+
+    @ApiModelProperty(value = "思考")
+    private String reasoningContent;
+}
diff --git a/src/main/java/cc/mrbird/febs/ai/req/talk/ApiTalkDto.java b/src/main/java/cc/mrbird/febs/ai/req/talk/ApiTalkDto.java
index 5276b6c..19a80f0 100644
--- a/src/main/java/cc/mrbird/febs/ai/req/talk/ApiTalkDto.java
+++ b/src/main/java/cc/mrbird/febs/ai/req/talk/ApiTalkDto.java
@@ -23,7 +23,7 @@
 
     @NotNull(message = "类型不能为空")
     @ApiModelProperty(value = "类型 1-用户提问 2-AI回答", example = "10")
-    private Integer type;
+    private String type;
 
     @ApiModelProperty(value = "会话ID", example = "10")
     private String talkId;
diff --git a/src/main/java/cc/mrbird/febs/ai/service/AiAgentService.java b/src/main/java/cc/mrbird/febs/ai/service/AiAgentService.java
index 355af3b..9126027 100644
--- a/src/main/java/cc/mrbird/febs/ai/service/AiAgentService.java
+++ b/src/main/java/cc/mrbird/febs/ai/service/AiAgentService.java
@@ -1,11 +1,10 @@
 package cc.mrbird.febs.ai.service;
 
 import cc.mrbird.febs.ai.entity.AiAgent;
-import cc.mrbird.febs.ai.req.agent.AiAgentInitDto;
-import cc.mrbird.febs.ai.req.agent.ApiAgentCategoryAllDto;
-import cc.mrbird.febs.ai.req.agent.ApiAgentPageDto;
+import cc.mrbird.febs.ai.req.agent.*;
 import cc.mrbird.febs.common.entity.FebsResponse;
 import com.baomidou.mybatisplus.extension.service.IService;
+import reactor.core.publisher.Flux;
 
 public interface AiAgentService extends IService<AiAgent> {
 
@@ -14,4 +13,10 @@
     FebsResponse agentList(ApiAgentPageDto dto);
 
     FebsResponse initAgent(AiAgentInitDto dto);
+
+    FebsResponse initSend(AgentInitDto dto);
+
+    FebsResponse saveContext(AgentSaveContextDto dto);
+
+    Flux<FebsResponse> aiAnswer(AitalkItemStreamDto dto);
 }
diff --git a/src/main/java/cc/mrbird/febs/ai/service/AiTalkItemService.java b/src/main/java/cc/mrbird/febs/ai/service/AiTalkItemService.java
index e3f81c7..618764d 100644
--- a/src/main/java/cc/mrbird/febs/ai/service/AiTalkItemService.java
+++ b/src/main/java/cc/mrbird/febs/ai/service/AiTalkItemService.java
@@ -10,7 +10,7 @@
 
 public interface AiTalkItemService extends IService<AiTalkItem> {
 
-    void add(String id,String companyId, int code, String context, String memberUuid, DateTime date);
+    void add(String id,String companyId, String code, String context, String memberUuid, DateTime date);
 
     FebsResponse historyPage(ApiTalkItemPageDto dto);
 
diff --git a/src/main/java/cc/mrbird/febs/ai/service/impl/AiAgentServiceImpl.java b/src/main/java/cc/mrbird/febs/ai/service/impl/AiAgentServiceImpl.java
index f600f6d..532f828 100644
--- a/src/main/java/cc/mrbird/febs/ai/service/impl/AiAgentServiceImpl.java
+++ b/src/main/java/cc/mrbird/febs/ai/service/impl/AiAgentServiceImpl.java
@@ -3,23 +3,25 @@
 import cc.mrbird.febs.ai.entity.*;
 import cc.mrbird.febs.ai.enumerates.AiCommonEnum;
 import cc.mrbird.febs.ai.enumerates.ProductCategoryLevelEnum;
-import cc.mrbird.febs.ai.mapper.AiAgentCategoryMapper;
-import cc.mrbird.febs.ai.mapper.AiAgentMapper;
-import cc.mrbird.febs.ai.mapper.AiAgentStartQuestionMapper;
-import cc.mrbird.febs.ai.req.agent.AiAgentInitDto;
-import cc.mrbird.febs.ai.req.agent.ApiAgentCategoryAllDto;
-import cc.mrbird.febs.ai.req.agent.ApiAgentPageDto;
+import cc.mrbird.febs.ai.mapper.*;
+import cc.mrbird.febs.ai.req.agent.*;
 import cc.mrbird.febs.ai.res.agent.AiAgentInitVo;
 import cc.mrbird.febs.ai.res.agent.ApiAgentCategoryVo;
 import cc.mrbird.febs.ai.res.agent.ApiAgentVo;
 import cc.mrbird.febs.ai.res.product.ApiProductVo;
 import cc.mrbird.febs.ai.res.productCategory.ApiProductCategoryVo;
 import cc.mrbird.febs.ai.service.AiAgentService;
+import cc.mrbird.febs.ai.strategy.LlmStrategyFactory;
+import cc.mrbird.febs.ai.strategy.enumerates.LlmStrategyEnum;
+import cc.mrbird.febs.ai.utils.UUID;
 import cc.mrbird.febs.common.entity.FebsResponse;
 import cc.mrbird.febs.common.exception.FebsException;
+import cc.mrbird.febs.common.utils.LoginUserUtil;
 import cn.hutool.core.bean.BeanUtil;
 import cn.hutool.core.collection.CollUtil;
 import cn.hutool.core.util.StrUtil;
+import com.alibaba.dashscope.common.Message;
+import com.alibaba.dashscope.common.Role;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
@@ -27,8 +29,10 @@
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.stereotype.Service;
+import reactor.core.publisher.Flux;
 
 import java.util.ArrayList;
+import java.util.Date;
 import java.util.List;
 
 @Slf4j
@@ -39,6 +43,12 @@
     private final AiAgentMapper aiAgentMapper;
     private final AiAgentCategoryMapper aiAgentCategoryMapper;
     private final AiAgentStartQuestionMapper aiAgentStartQuestionMapper;
+    private final AiTalkMapper aiTalkMapper;
+    private final AiTalkItemMapper aiTalkItemMapper;
+    private final AiCompanyMapper aiCompanyMapper;
+    private final AiAgentKnowledgeMapper aiAgentKnowledgeMapper;
+    private final AiKnowledgeFileMapper aiKnowledgeFileMapper;
+    private final LlmStrategyFactory llmStrategyFactory;
 
     @Override
     public FebsResponse allCategoryList(ApiAgentCategoryAllDto dto) {
@@ -98,4 +108,167 @@
 
         return new FebsResponse().success().data(vo);
     }
+
+    @Override
+    public FebsResponse initSend(AgentInitDto dto) {
+
+
+        String memberUuid = LoginUserUtil.getLoginUser().getMemberUuid();
+
+        AgentSendInitVo vo = new AgentSendInitVo();
+
+        String agentId = dto.getId();
+        //获取智能体信息
+        AiAgent aiAgent = aiAgentMapper.selectById(agentId);
+        if (aiAgent == null) {
+
+            throw new FebsException("智能体不存在");
+        }
+        if (aiAgent.getState() != 1){
+
+            throw new FebsException("智能体未启用");
+        }
+        String companyId = aiAgent.getCompanyId();
+        /**
+         * 新增一个会话记录
+         */
+        AiTalk entity = new AiTalk();
+        entity.setId(UUID.getSimpleUUIDString());
+        entity.setCompanyId(companyId);
+        entity.setMemberId(memberUuid);
+        entity.setAgentId(agentId);
+        entity.setCreatedTime(new Date());
+        aiTalkMapper.insert(entity);
+
+        vo.setTalkId(entity.getId());
+        return new FebsResponse().success().data(vo);
+    }
+
+    @Override
+    public FebsResponse saveContext(AgentSaveContextDto dto) {
+        String talkId = dto.getTalkId();
+        String type = dto.getType();
+        String content = dto.getContent();
+
+        AiTalk aiTalk = aiTalkMapper.selectById(talkId);
+        if (aiTalk == null) {
+            throw new FebsException("会话不存在");
+        }
+        //保存会话记录
+        AiTalkItem aiTalkItem = new AiTalkItem();
+        aiTalkItem.setId(UUID.getSimpleUUIDString());
+        aiTalkItem.setCompanyId(aiTalk.getCompanyId());
+        aiTalkItem.setTalkId(aiTalk.getId());
+        aiTalkItem.setType(type);
+        aiTalkItem.setContext(content);
+        aiTalkItem.setCreatedTime(new Date());
+        aiTalkItemMapper.insert(aiTalkItem);
+
+        return new FebsResponse().success();
+    }
+
+    @Override
+    public Flux<FebsResponse> aiAnswer(AitalkItemStreamDto dto) {
+        String talkId = dto.getTalkId();
+        String reqContext = dto.getReqContext();
+
+        AiTalk aiTalk = aiTalkMapper.selectById(talkId);
+        if (aiTalk == null) {
+            throw new FebsException("会话不存在");
+        }
+        String agentId = aiTalk.getAgentId();
+        AiAgent aiAgent = aiAgentMapper.selectById(agentId);
+
+        //判断字符是否足够
+        String companyId = aiTalk.getCompanyId();
+        AiCompany aiCompany = aiCompanyMapper.selectById(companyId);
+        if (aiCompany == null) {
+            throw new FebsException("知识库异常");
+        }
+        //获取智能体绑定的知识库
+        List<String> knowledgeIds = new ArrayList<>();
+        String knowledgeId = aiCompany.getKnowledgeId();
+        knowledgeIds.add(knowledgeId);
+
+        //获取智能体绑定的查询文件
+        List<String> fileIds = new ArrayList<>();
+        List<AiAgentKnowledge> aiAgentKnowledges = aiAgentKnowledgeMapper.selectList(
+                Wrappers.lambdaQuery(AiAgentKnowledge.class)
+                        .select(AiAgentKnowledge::getKnowledgeId)
+                        .eq(AiAgentKnowledge::getAgentId, agentId)
+                        .eq(AiAgentKnowledge::getCompanyId, companyId)
+        );
+        if (CollUtil.isNotEmpty(aiAgentKnowledges)){
+            List<String> aiKnowledgeIds = new ArrayList<>();
+            for (AiAgentKnowledge aiAgentKnowledge : aiAgentKnowledges){
+                aiKnowledgeIds.add(aiAgentKnowledge.getKnowledgeId());
+            }
+            if (CollUtil.isNotEmpty(aiKnowledgeIds)){
+                List<AiKnowledgeFile> aiKnowledges = aiKnowledgeFileMapper.selectList(
+                        Wrappers.lambdaQuery(AiKnowledgeFile.class)
+                                .select(AiKnowledgeFile::getFileId)
+                                .in(AiKnowledgeFile::getId, aiKnowledgeIds)
+                );
+                if (CollUtil.isNotEmpty(aiKnowledges)){
+                    for (AiKnowledgeFile aiKnowledge : aiKnowledges){
+                        fileIds.add(aiKnowledge.getFileId());
+                    }
+                }
+            }
+        }
+
+
+        AiRequestDto aiRequestDto = new AiRequestDto();
+        aiRequestDto.setTalkId(talkId);
+        String prompt = aiAgent.getPrompt();
+        aiRequestDto.setRolePrompt(prompt);
+//        List<Message> messages = new ArrayList<>();
+//        messages.add(Message.builder().role(Role.SYSTEM.getValue()).content(prompt).build());
+
+        //获取对话记录
+        List<Message> messages = new ArrayList<>();
+        List<AiTalkItem> aiTalkItemList = aiTalkItemMapper.selectList(
+                Wrappers.lambdaQuery(AiTalkItem.class)
+                        .eq(AiTalkItem::getTalkId, talkId)
+                        .orderByAsc(AiTalkItem::getCreatedTime)
+        );
+        if (CollUtil.isNotEmpty(aiTalkItemList)){
+            messages = getMessages(messages,aiTalkItemList);
+        }
+        for (
+                Message message : messages
+        ){
+            log.info("上下文内容:{},{}", message.getRole(),message.getContent());
+        }
+        aiRequestDto.setMessages(messages);
+        aiRequestDto.setKnowledgeIds(knowledgeIds);
+        aiRequestDto.setFileIds(fileIds);
+        aiRequestDto.setPrompt(reqContext);
+        aiRequestDto.setCompanyId(companyId);
+        //日志输出详细的请求参数的每一个属性
+        log.info("请求参数:{}", aiRequestDto.getPrompt());
+        log.info("请求参数:{}", aiRequestDto);
+
+
+        String modelName = LlmStrategyEnum.getName(2);
+        return llmStrategyFactory.getCalculationStrategyMap().get(modelName).llmInvokeStreamingNoThink(aiRequestDto);
+    }
+
+    private List<Message> getMessages(List<Message> messages, List<AiTalkItem> aiTalkItemList) {
+        for (AiTalkItem item : aiTalkItemList){
+            if (StrUtil.equals(item.getType(), Role.USER.getValue())){
+                messages.add(Message.builder()
+                        .role(Role.USER.getValue())
+                        .content(item.getContext())
+                        .build());
+            }
+            if (StrUtil.equals(item.getType(),Role.ASSISTANT.getValue())){
+                messages.add(Message.builder()
+                        .role(Role.ASSISTANT.getValue())
+                        .content(item.getContext())
+                        .build());
+            }
+        }
+        return messages;
+    }
 }
diff --git a/src/main/java/cc/mrbird/febs/ai/service/impl/AiTalkItemServiceImpl.java b/src/main/java/cc/mrbird/febs/ai/service/impl/AiTalkItemServiceImpl.java
index a7c7531..76ed725 100644
--- a/src/main/java/cc/mrbird/febs/ai/service/impl/AiTalkItemServiceImpl.java
+++ b/src/main/java/cc/mrbird/febs/ai/service/impl/AiTalkItemServiceImpl.java
@@ -26,7 +26,7 @@
 
     private final AiTalkItemMapper aiTalkItemMapper;
     @Override
-    public void add(String id,String companyId, int code, String context, String memberUuid, DateTime date) {
+    public void add(String id,String companyId, String code, String context, String memberUuid, DateTime date) {
         AiTalkItem aiTalkItem = new AiTalkItem();
         aiTalkItem.setId(UUID.getSimpleUUIDString());
         aiTalkItem.setCompanyId(companyId);
diff --git a/src/main/java/cc/mrbird/febs/ai/service/impl/AiTalkServiceImpl.java b/src/main/java/cc/mrbird/febs/ai/service/impl/AiTalkServiceImpl.java
index 1480379..9fe4d0a 100644
--- a/src/main/java/cc/mrbird/febs/ai/service/impl/AiTalkServiceImpl.java
+++ b/src/main/java/cc/mrbird/febs/ai/service/impl/AiTalkServiceImpl.java
@@ -92,7 +92,7 @@
     public FebsResponse talkOpen(ApiTalkDto dto) {
         String talkId = dto.getTalkId();
         String context = dto.getContext();
-        Integer type = dto.getType();
+        String type = dto.getType();
         String reasoningContent = dto.getReasoningContent();
         String memberUuid = LoginUserUtil.getLoginUser().getMemberUuid();
         String companyId = LoginUserUtil.getLoginUser().getCompanyId();
diff --git a/src/main/java/cc/mrbird/febs/ai/strategy/Impl/AliApplicationLlmStrategyServiceImpl.java b/src/main/java/cc/mrbird/febs/ai/strategy/Impl/AliApplicationLlmStrategyServiceImpl.java
index 2ccbf79..8560721 100644
--- a/src/main/java/cc/mrbird/febs/ai/strategy/Impl/AliApplicationLlmStrategyServiceImpl.java
+++ b/src/main/java/cc/mrbird/febs/ai/strategy/Impl/AliApplicationLlmStrategyServiceImpl.java
@@ -1,6 +1,7 @@
 package cc.mrbird.febs.ai.strategy.Impl;
 
 import cc.mrbird.febs.ai.enumerates.AiTypeEnum;
+import cc.mrbird.febs.ai.req.agent.AiRequestDto;
 import cc.mrbird.febs.ai.strategy.LlmStrategyService;
 import cc.mrbird.febs.ai.strategy.enumerates.LlmApplicationAppIdEnum;
 import cc.mrbird.febs.ai.strategy.enumerates.LlmStrategyContextEnum;
@@ -255,4 +256,9 @@
                     throw new FebsException(StrUtil.format("百炼工作流输出失败:{}",error));
                 });
     }
+
+    @Override
+    public Flux<FebsResponse> llmInvokeStreamingNoThink(AiRequestDto aiRequestDto) {
+        return null;
+    }
 }
diff --git a/src/main/java/cc/mrbird/febs/ai/strategy/Impl/AliLlmStrategyServiceImpl.java b/src/main/java/cc/mrbird/febs/ai/strategy/Impl/AliLlmStrategyServiceImpl.java
index a82ad94..f47744d 100644
--- a/src/main/java/cc/mrbird/febs/ai/strategy/Impl/AliLlmStrategyServiceImpl.java
+++ b/src/main/java/cc/mrbird/febs/ai/strategy/Impl/AliLlmStrategyServiceImpl.java
@@ -1,21 +1,26 @@
 package cc.mrbird.febs.ai.strategy.Impl;
 
+import cc.mrbird.febs.ai.req.agent.AiRequestDto;
 import cc.mrbird.febs.ai.strategy.LlmStrategyService;
 import cc.mrbird.febs.ai.strategy.enumerates.LlmStrategyContextEnum;
 import cc.mrbird.febs.ai.strategy.param.LlmStrategyDto;
 import cc.mrbird.febs.common.entity.FebsResponse;
 import cc.mrbird.febs.common.exception.FebsException;
 import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.util.ObjectUtil;
 import cn.hutool.core.util.StrUtil;
 import cn.hutool.json.JSONUtil;
 import com.alibaba.dashscope.aigc.generation.Generation;
 import com.alibaba.dashscope.aigc.generation.GenerationParam;
 import com.alibaba.dashscope.aigc.generation.GenerationResult;
+import com.alibaba.dashscope.app.*;
 import com.alibaba.dashscope.common.Message;
 import com.alibaba.dashscope.common.Role;
 import com.alibaba.dashscope.exception.InputRequiredException;
 import com.alibaba.dashscope.exception.NoApiKeyException;
+import com.alibaba.dashscope.utils.JsonUtils;
 import io.reactivex.Flowable;
+import lombok.extern.slf4j.Slf4j;
 import org.springframework.stereotype.Component;
 import reactor.core.publisher.Flux;
 
@@ -24,14 +29,21 @@
 import java.util.HashMap;
 import java.util.List;
 
+@Slf4j
 @Component("AliLlmStrategyService")
 public class AliLlmStrategyServiceImpl implements LlmStrategyService {
 
     private GenerationParam generationParam;
 
-    private static final String apiKey = "sk-babdcf8799144134915cee2683794b2f";
+    private static final String apiKey = "sk-a2323eba1e584066b3a536aefa804970";
     private static final String model = "qwen-plus";
-//    private static final String model = "qwen3-14b-ft-202509031002-7446";
+
+
+    private ApplicationParam applicationParam;
+    private ApplicationParam applicationParamSummary;
+
+    private static final String appId = "a5d38240f6b94da6b7f1f7fbe563f50c";
+    private static final String SummaryAppId = "19da84392c534db5b2e3f10e698758ab";
 
     @PostConstruct
     public void init() {
@@ -41,6 +53,18 @@
                 // 模型列表:https://help.aliyun.com/zh/model-studio/getting-started/models
                 .model(model)
                 .resultFormat(GenerationParam.ResultFormat.MESSAGE)
+                .build();
+
+        this.applicationParam = ApplicationParam.builder()
+                // 若没有配置环境变量,可用百炼API Key将下行替换为:.apiKey("sk-xxx")。但不建议在生产环境中直接将API Key硬编码到代码中,以减少API Key泄露风险。
+                .apiKey(apiKey)
+                .appId(appId)
+                .build();
+
+        this.applicationParamSummary = ApplicationParam.builder()
+                // 若没有配置环境变量,可用百炼API Key将下行替换为:.apiKey("sk-xxx")。但不建议在生产环境中直接将API Key硬编码到代码中,以减少API Key泄露风险。
+                .apiKey(apiKey)
+                .appId(SummaryAppId)
                 .build();
     }
 
@@ -175,4 +199,91 @@
                     throw new FebsException(StrUtil.format("百炼大模型输出失败:{}",error));
                 });
     }
+
+    @Override
+    public Flux<FebsResponse> llmInvokeStreamingNoThink(AiRequestDto dto) {
+        long startTime = System.currentTimeMillis();
+        if (ObjectUtil.isEmpty(dto)){
+            throw new FebsException("参数异常");
+        }
+        String talkId = dto.getTalkId();
+
+        String rolePrompt = dto.getRolePrompt();
+        List<Message> messages = dto.getMessages();
+        HashMap<String, Object> userPromptParams = new HashMap<>();
+        userPromptParams.put("role_prompt", rolePrompt);
+        if(CollUtil.isNotEmpty( messages)){
+            userPromptParams.put("message_list", messages);
+        }
+        HashMap<String, Object> bizParams = new HashMap<>();
+        bizParams.put("user_prompt_params", userPromptParams);
+
+        List<String> knowledgeIds = dto.getKnowledgeIds();
+        List<String> fileIds = dto.getFileIds();
+        String prompt = dto.getPrompt();
+
+        Application application = new Application();
+        applicationParam.setPrompt(prompt);
+        applicationParam.setBizParams(JsonUtils.toJsonObject( bizParams));
+        // 获取当前的系统时间
+        applicationParam.setEnableSystemTime( true);
+        // 增量输出
+        applicationParam.setIncrementalOutput( true);
+        // 思考过程
+        applicationParam.setEnableThinking( false);
+        // 多轮对话
+//        applicationParam.setMessages(messages);
+        // 上下文seesionId
+//        String sessionId = (String) redisCache.getCacheObject(talkId);
+//        if (ObjectUtil.isNotEmpty(sessionId)){
+//            applicationParam.setSessionId(talkId);
+//        }
+
+        RagOptions ragOptions = null;
+        if (CollUtil.isEmpty(fileIds)){
+            ragOptions = RagOptions.builder()
+                    .pipelineIds(knowledgeIds)
+                    .build();
+        }else{
+            ragOptions = RagOptions.builder()
+                    .pipelineIds(knowledgeIds)
+                    .fileIds(fileIds)
+                    .build();
+        }
+        applicationParam.setRagOptions(ragOptions);
+        Flowable<ApplicationResult> result;
+        try {
+            result = application.streamCall(applicationParam);
+        } catch (NoApiKeyException | InputRequiredException e) {
+
+            throw new FebsException(StrUtil.format("百炼大模型输出失败:{}",e.getMessage()));
+        }
+        return Flux.from(result)
+                .map(message -> {
+                    HashMap<String, Object> stringStringHashMap = new HashMap<>();
+                    if (!message.getOutput().getFinishReason().equals("stop")){
+                        stringStringHashMap.put(LlmStrategyContextEnum.CONTENT.name(),message.getOutput().getText());
+                    }
+                    if (message.getOutput().getFinishReason().equals("stop")){
+                        log.info("百炼大模型输出:{}",message.getOutput().getSessionId());
+                        List<ApplicationUsage.ModelUsage> models = message.getUsage().getModels();
+                        long outputTokens = models.stream().mapToLong(ApplicationUsage.ModelUsage::getOutputTokens).sum();
+                        log.info("百炼大模型输出:{}",outputTokens);
+                        long inputTokens = models.stream().mapToLong(ApplicationUsage.ModelUsage::getInputTokens).sum();
+                        log.info("百炼大模型输出:{}",inputTokens);
+                        stringStringHashMap.put("inputTokens:",inputTokens);
+                        stringStringHashMap.put("outputTokens:",outputTokens);
+                        stringStringHashMap.put(LlmStrategyContextEnum.CONTENT.name(),message.getOutput().getText());
+                    }
+
+                    return new FebsResponse().success().data(stringStringHashMap);
+                })
+                .doOnComplete(() -> {
+                    long endTime = System.currentTimeMillis();
+                    System.out.println("百炼大模型输出:" + (endTime - startTime) + "毫秒");
+                })
+                .doOnError(error -> {
+                    throw new FebsException(StrUtil.format("百炼大模型输出失败:{}",error));
+                });
+    }
 }
diff --git a/src/main/java/cc/mrbird/febs/ai/strategy/Impl/HsLlmStrategyServiceImpl.java b/src/main/java/cc/mrbird/febs/ai/strategy/Impl/HsLlmStrategyServiceImpl.java
index 4cb18dd..f0dec93 100644
--- a/src/main/java/cc/mrbird/febs/ai/strategy/Impl/HsLlmStrategyServiceImpl.java
+++ b/src/main/java/cc/mrbird/febs/ai/strategy/Impl/HsLlmStrategyServiceImpl.java
@@ -1,5 +1,6 @@
 package cc.mrbird.febs.ai.strategy.Impl;
 
+import cc.mrbird.febs.ai.req.agent.AiRequestDto;
 import cc.mrbird.febs.ai.strategy.LlmStrategyService;
 import cc.mrbird.febs.ai.strategy.enumerates.LlmStrategyContextEnum;
 import cc.mrbird.febs.ai.strategy.param.LlmStrategyDto;
@@ -201,4 +202,9 @@
                     throw new FebsException(StrUtil.format("火山大模型流式调用AI服务失:{}",throwable));
                 });
     }
+
+    @Override
+    public Flux<FebsResponse> llmInvokeStreamingNoThink(AiRequestDto aiRequestDto) {
+        return null;
+    }
 }
diff --git a/src/main/java/cc/mrbird/febs/ai/strategy/LlmStrategyService.java b/src/main/java/cc/mrbird/febs/ai/strategy/LlmStrategyService.java
index 28e1540..312ee82 100644
--- a/src/main/java/cc/mrbird/febs/ai/strategy/LlmStrategyService.java
+++ b/src/main/java/cc/mrbird/febs/ai/strategy/LlmStrategyService.java
@@ -1,5 +1,6 @@
 package cc.mrbird.febs.ai.strategy;
 
+import cc.mrbird.febs.ai.req.agent.AiRequestDto;
 import cc.mrbird.febs.ai.strategy.param.LlmStrategyDto;
 import cc.mrbird.febs.common.entity.FebsResponse;
 import reactor.core.publisher.Flux;
@@ -13,4 +14,6 @@
     Flux<FebsResponse> llmInvokeStreamingWithThink(List<LlmStrategyDto> dto);
 
     Flux<FebsResponse> llmInvokeStreamingNoThink(List<LlmStrategyDto> dto);
+
+    Flux<FebsResponse> llmInvokeStreamingNoThink(AiRequestDto aiRequestDto);
 }

--
Gitblit v1.9.1