删除ai模块
This commit is contained in:
@@ -102,8 +102,8 @@ export default {
|
|||||||
return {
|
return {
|
||||||
codeUrl: "",
|
codeUrl: "",
|
||||||
loginForm: {
|
loginForm: {
|
||||||
username: "admin",
|
username: "",
|
||||||
password: "admin123",
|
password: "",
|
||||||
rememberMe: false,
|
rememberMe: false,
|
||||||
code: "",
|
code: "",
|
||||||
uuid: ""
|
uuid: ""
|
||||||
|
|||||||
7
pom.xml
7
pom.xml
@@ -198,13 +198,6 @@
|
|||||||
<version>${ruoyi.version}</version>
|
<version>${ruoyi.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.springframework.ai</groupId>
|
|
||||||
<artifactId>spring-ai-bom</artifactId>
|
|
||||||
<version>${spring-ai.version}</version>
|
|
||||||
<type>pom</type>
|
|
||||||
<scope>import</scope>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<!--hutool工具包-->
|
<!--hutool工具包-->
|
||||||
<dependency>
|
<dependency>
|
||||||
|
|||||||
@@ -54,56 +54,6 @@
|
|||||||
<artifactId>ruoyi-generator</artifactId>
|
<artifactId>ruoyi-generator</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.springframework.ai</groupId>
|
|
||||||
<artifactId>spring-ai-starter-model-openai</artifactId>
|
|
||||||
</dependency>
|
|
||||||
<!--向量化-->
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.springframework.ai</groupId>
|
|
||||||
<artifactId>spring-ai-vector-store</artifactId>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.springframework.ai</groupId>
|
|
||||||
<artifactId>spring-ai-mariadb-store</artifactId>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.springframework.ai</groupId>
|
|
||||||
<artifactId>spring-ai-advisors-vector-store</artifactId>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<!--PDF文档处理-->
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.springframework.ai</groupId>
|
|
||||||
<artifactId>spring-ai-pdf-document-reader</artifactId>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.springframework.ai</groupId>
|
|
||||||
<artifactId>spring-ai-jsoup-document-reader</artifactId>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.springframework.ai</groupId>
|
|
||||||
<artifactId>spring-ai-markdown-document-reader</artifactId>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.springframework.ai</groupId>
|
|
||||||
<artifactId>spring-ai-tika-document-reader</artifactId>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<!-- MariaDB 驱动 -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.mariadb.jdbc</groupId>
|
|
||||||
<artifactId>mariadb-java-client</artifactId>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<!--MCP-->
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.springframework.ai</groupId>
|
|
||||||
<artifactId>spring-ai-starter-mcp-client</artifactId>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.github.dathlin</groupId>
|
<groupId>com.github.dathlin</groupId>
|
||||||
<artifactId>HslCommunication</artifactId>
|
<artifactId>HslCommunication</artifactId>
|
||||||
|
|||||||
@@ -1,120 +0,0 @@
|
|||||||
package com.ruoyi.ai.chat.config;
|
|
||||||
|
|
||||||
import com.alibaba.druid.spring.boot3.autoconfigure.DruidDataSourceBuilder;
|
|
||||||
import com.mysql.cj.jdbc.MysqlDataSource;
|
|
||||||
import com.ruoyi.ai.chat.service.impl.InSqlMemory;
|
|
||||||
import com.ruoyi.ai.util.service.BasStockToolService;
|
|
||||||
import com.ruoyi.ai.util.service.ToolService;
|
|
||||||
import org.mariadb.jdbc.MariaDbDataSource;
|
|
||||||
import org.springframework.ai.chat.client.ChatClient;
|
|
||||||
import org.springframework.ai.chat.client.advisor.MessageChatMemoryAdvisor;
|
|
||||||
import org.springframework.ai.chat.client.advisor.SimpleLoggerAdvisor;
|
|
||||||
import org.springframework.ai.chat.client.advisor.vectorstore.QuestionAnswerAdvisor;
|
|
||||||
import org.springframework.ai.chat.memory.ChatMemory;
|
|
||||||
import org.springframework.ai.embedding.EmbeddingModel;
|
|
||||||
import org.springframework.ai.openai.OpenAiChatModel;
|
|
||||||
import org.springframework.ai.openai.OpenAiEmbeddingModel;
|
|
||||||
import org.springframework.ai.openai.api.OpenAiApi;
|
|
||||||
import org.springframework.ai.tool.ToolCallback;
|
|
||||||
import org.springframework.ai.tool.ToolCallbackProvider;
|
|
||||||
import org.springframework.ai.vectorstore.SearchRequest;
|
|
||||||
import org.springframework.ai.vectorstore.SimpleVectorStore;
|
|
||||||
import org.springframework.ai.vectorstore.VectorStore;
|
|
||||||
import org.springframework.ai.vectorstore.mariadb.MariaDBVectorStore;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
|
||||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
|
||||||
import org.springframework.boot.jdbc.DataSourceBuilder;
|
|
||||||
import org.springframework.context.annotation.Bean;
|
|
||||||
import org.springframework.context.annotation.Configuration;
|
|
||||||
import org.springframework.jdbc.core.JdbcTemplate;
|
|
||||||
|
|
||||||
import javax.sql.DataSource;
|
|
||||||
import java.sql.SQLException;
|
|
||||||
|
|
||||||
@Configuration
|
|
||||||
public class ChatModelConfig {
|
|
||||||
|
|
||||||
|
|
||||||
private String system = "你是福来瑞达仓库助手,有自动分配功能 自动分配功能逻辑如下:根据仓库id查询库存,找到某一个库存,生成对应的作业";
|
|
||||||
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
@ConditionalOnProperty(
|
|
||||||
name = "spring.ai.enable", // 配置项名称
|
|
||||||
havingValue = "true", // 期望的值
|
|
||||||
matchIfMissing = false // 配置不存在时是否匹配(false=不注册)
|
|
||||||
)
|
|
||||||
public ChatClient chatClient(OpenAiChatModel openAiChatModel, ChatMemory chatMemory, BasStockToolService toolService/*, ToolCallbackProvider toolCallbackProvider*/) {
|
|
||||||
return ChatClient
|
|
||||||
//使用的模型
|
|
||||||
.builder(openAiChatModel)
|
|
||||||
//设置系统信息
|
|
||||||
.defaultSystem(system)
|
|
||||||
//打印日志
|
|
||||||
.defaultAdvisors(new SimpleLoggerAdvisor())
|
|
||||||
//上下文记忆
|
|
||||||
.defaultAdvisors(MessageChatMemoryAdvisor.builder(chatMemory).build())
|
|
||||||
//实用工具
|
|
||||||
.defaultTools(toolService)
|
|
||||||
//mcp工具
|
|
||||||
//.defaultToolCallbacks(toolCallbackProvider)
|
|
||||||
.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 聊天历史内存
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
@Bean
|
|
||||||
@ConditionalOnProperty(
|
|
||||||
name = "spring.ai.enable", // 配置项名称
|
|
||||||
havingValue = "true", // 期望的值
|
|
||||||
matchIfMissing = false // 配置不存在时是否匹配(false=不注册)
|
|
||||||
)
|
|
||||||
public ChatMemory chatMemory() {
|
|
||||||
return new InSqlMemory();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
@ConditionalOnProperty(
|
|
||||||
name = "spring.ai.enable", // 配置项名称
|
|
||||||
havingValue = "true", // 期望的值
|
|
||||||
matchIfMissing = false // 配置不存在时是否匹配(false=不注册)
|
|
||||||
)
|
|
||||||
@ConfigurationProperties("spring.datasource.druid.slave")
|
|
||||||
public MariaDbDataSource dataSource() throws SQLException {
|
|
||||||
return DataSourceBuilder.create().username("root")
|
|
||||||
.type(MariaDbDataSource.class)
|
|
||||||
.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
@ConditionalOnProperty(
|
|
||||||
name = "spring.ai.enable", // 配置项名称
|
|
||||||
havingValue = "true", // 期望的值
|
|
||||||
matchIfMissing = false // 配置不存在时是否匹配(false=不注册)
|
|
||||||
)
|
|
||||||
public VectorStore vectorStore(MariaDbDataSource dataSource, EmbeddingModel embeddingModel) throws SQLException {
|
|
||||||
JdbcTemplate customJdbcTemplate = new JdbcTemplate(dataSource);
|
|
||||||
return MariaDBVectorStore.builder(customJdbcTemplate, embeddingModel)
|
|
||||||
.dimensions(1024) // Optional: defaults to 1536
|
|
||||||
.distanceType(MariaDBVectorStore.MariaDBDistanceType.COSINE) // Optional: defaults to COSINE
|
|
||||||
.schemaName("test_ai") // Optional: defaults to null
|
|
||||||
.vectorTableName("custom_vectors") // Optional: defaults to "vector_store"
|
|
||||||
.contentFieldName("text") // Optional: defaults to "content"
|
|
||||||
.embeddingFieldName("embedding") // Optional: defaults to "embedding"
|
|
||||||
.idFieldName("doc_id") // Optional: defaults to "id"
|
|
||||||
.metadataFieldName("meta") // Optional: defaults to "metadata"
|
|
||||||
.initializeSchema(true) // Optional: defaults to false
|
|
||||||
.schemaValidation(true) // Optional: defaults to false
|
|
||||||
.removeExistingVectorStoreTable(false) // Optional: defaults to false
|
|
||||||
.maxDocumentBatchSize(10000) // Optional: defaults to 10000
|
|
||||||
.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,36 +0,0 @@
|
|||||||
package com.ruoyi.ai.chat.controller;
|
|
||||||
|
|
||||||
import com.ruoyi.ai.chat.domain.CustomMessage;
|
|
||||||
import com.ruoyi.ai.chat.service.ChatService;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.web.bind.annotation.*;
|
|
||||||
import reactor.core.publisher.Flux;
|
|
||||||
|
|
||||||
@RestController
|
|
||||||
@RequestMapping("/api/chat")
|
|
||||||
public class ChatDemoController {
|
|
||||||
@Autowired
|
|
||||||
private ChatService chatService;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 流式调用
|
|
||||||
* @param customMessage
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
@RequestMapping(produces = "text/html;charset=utf-8")
|
|
||||||
public Flux<String> chat(@RequestBody CustomMessage customMessage) {
|
|
||||||
return chatService.chatByUserContent(customMessage);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 知识库调用
|
|
||||||
* @param customMessage
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
@RequestMapping(value = "/knowledgeBase", produces = "text/html;charset=utf-8")
|
|
||||||
public Flux<String> chatByKnowledgeBase(@RequestBody CustomMessage customMessage) {
|
|
||||||
return chatService.chatByVectorStore(customMessage);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,65 +0,0 @@
|
|||||||
package com.ruoyi.ai.chat.controller;
|
|
||||||
|
|
||||||
import org.springframework.ai.document.Document;
|
|
||||||
import org.springframework.ai.openai.OpenAiEmbeddingModel;
|
|
||||||
import org.springframework.ai.reader.ExtractedTextFormatter;
|
|
||||||
import org.springframework.ai.reader.pdf.PagePdfDocumentReader;
|
|
||||||
import org.springframework.ai.reader.pdf.config.PdfDocumentReaderConfig;
|
|
||||||
import org.springframework.ai.vectorstore.SearchRequest;
|
|
||||||
import org.springframework.ai.vectorstore.VectorStore;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.core.io.FileSystemResource;
|
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
@RestController
|
|
||||||
@RequestMapping("/api/embedding")
|
|
||||||
public class EmbeddingDemoController {
|
|
||||||
|
|
||||||
@Autowired(required = false)
|
|
||||||
private OpenAiEmbeddingModel embeddingModel;
|
|
||||||
|
|
||||||
@Autowired(required = false)
|
|
||||||
private VectorStore vectorStore;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 测试Embedding
|
|
||||||
* @param message
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
@RequestMapping("/demo")
|
|
||||||
public float[] demo(String message) {
|
|
||||||
FileSystemResource fileSystemResource = new FileSystemResource("D:\\Program Files\\Tencent\\xwechat_files\\lhq1329816987_ff0c\\msg\\file\\2025-08\\加减数显电子标签V5.0-广播通信协议7色款 2023.02.27.pdf");
|
|
||||||
PagePdfDocumentReader reader = new PagePdfDocumentReader(fileSystemResource, PdfDocumentReaderConfig.builder()
|
|
||||||
.withPageExtractedTextFormatter(ExtractedTextFormatter.defaults())
|
|
||||||
.withPagesPerDocument(1) // 每1页PDF作为一个Document
|
|
||||||
.build());
|
|
||||||
// 2.读取PDF文档,拆分为Document
|
|
||||||
List<Document> documents = reader.read();
|
|
||||||
// 3.写入向量库
|
|
||||||
vectorStore.add(documents);
|
|
||||||
// 4.配置搜索请求
|
|
||||||
SearchRequest request = SearchRequest.builder()
|
|
||||||
.query(message) // 搜索内容
|
|
||||||
.topK(1) // 返回的相似文档数量
|
|
||||||
.similarityThreshold(0.6) // 相似度阈值
|
|
||||||
.filterExpression("file_name == '加减数显电子标签V5.0-广播通信协议7色款 2023.02.27.pdf'") // 过滤条件,后续可以传入多个文档
|
|
||||||
.build();
|
|
||||||
// 5.从向量库中搜索
|
|
||||||
List<Document> docs = vectorStore.similaritySearch(request);
|
|
||||||
if (docs == null) {
|
|
||||||
System.out.println("没有搜索到任何内容");
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
for (Document doc : docs) {
|
|
||||||
System.out.println(doc.getId());
|
|
||||||
System.out.println(doc.getScore());
|
|
||||||
System.out.println(doc.getText());
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
package com.ruoyi.ai.chat.domain;
|
|
||||||
|
|
||||||
import lombok.AllArgsConstructor;
|
|
||||||
import lombok.Data;
|
|
||||||
import lombok.NoArgsConstructor;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
@Data
|
|
||||||
@AllArgsConstructor
|
|
||||||
@NoArgsConstructor
|
|
||||||
public class CustomMessage {
|
|
||||||
|
|
||||||
private String message;
|
|
||||||
|
|
||||||
private String conversationId;
|
|
||||||
|
|
||||||
private String type;
|
|
||||||
|
|
||||||
private List<HashMap<String, String>> files;
|
|
||||||
}
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
package com.ruoyi.ai.chat.service;
|
|
||||||
|
|
||||||
import com.ruoyi.ai.chat.domain.CustomMessage;
|
|
||||||
import reactor.core.publisher.Flux;
|
|
||||||
|
|
||||||
public interface ChatService {
|
|
||||||
Flux<String> chatByVectorStore(CustomMessage customMessage);
|
|
||||||
Flux<String> chatByUserContent(CustomMessage customMessage);
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,133 +0,0 @@
|
|||||||
package com.ruoyi.ai.chat.service.impl;
|
|
||||||
|
|
||||||
import cn.hutool.core.convert.Convert;
|
|
||||||
import cn.hutool.core.util.IdUtil;
|
|
||||||
import com.ruoyi.ai.chat.domain.CustomMessage;
|
|
||||||
import com.ruoyi.ai.chat.service.ChatService;
|
|
||||||
import com.ruoyi.ai.conversation.domain.Conversations;
|
|
||||||
import com.ruoyi.ai.conversation.service.IConversationsService;
|
|
||||||
import com.ruoyi.ai.message.domain.ChatMessage;
|
|
||||||
import com.ruoyi.ai.message.service.IChatMessageService;
|
|
||||||
import com.ruoyi.common.utils.SecurityUtils;
|
|
||||||
import org.springframework.ai.chat.client.ChatClient;
|
|
||||||
import org.springframework.ai.chat.client.advisor.vectorstore.QuestionAnswerAdvisor;
|
|
||||||
import org.springframework.ai.chat.memory.ChatMemory;
|
|
||||||
import org.springframework.ai.chat.prompt.PromptTemplate;
|
|
||||||
import org.springframework.ai.document.Document;
|
|
||||||
import org.springframework.ai.openai.OpenAiChatModel;
|
|
||||||
import org.springframework.ai.template.st.StTemplateRenderer;
|
|
||||||
import org.springframework.ai.vectorstore.SearchRequest;
|
|
||||||
import org.springframework.ai.vectorstore.VectorStore;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.stereotype.Service;
|
|
||||||
import reactor.core.publisher.Flux;
|
|
||||||
|
|
||||||
import java.util.Date;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
@Service
|
|
||||||
public class ChatServiceImpl implements ChatService {
|
|
||||||
|
|
||||||
@Autowired(required = false)
|
|
||||||
private ChatClient chatClient;
|
|
||||||
@Autowired(required = false)
|
|
||||||
private OpenAiChatModel openAiChatModel;
|
|
||||||
@Autowired(required = false)
|
|
||||||
private ChatMemory chatMemory;
|
|
||||||
@Autowired(required = false)
|
|
||||||
private VectorStore vectorStore;
|
|
||||||
@Autowired(required = false)
|
|
||||||
private IChatMessageService chatMessageService;
|
|
||||||
@Autowired(required = false)
|
|
||||||
private IConversationsService conversationsService;
|
|
||||||
|
|
||||||
// 定义问答模板
|
|
||||||
private final String PROMPT_BLUEPRINT = """
|
|
||||||
严格参考提供的上下文回答查询:
|
|
||||||
{context}
|
|
||||||
Query:
|
|
||||||
{query}
|
|
||||||
如果您从提供的上下文中没有任何答案,只需说:
|
|
||||||
很抱歉,我没有您要找的信息。
|
|
||||||
""";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 与AI进行聊天对话
|
|
||||||
*
|
|
||||||
* @param customMessage 用户消息对象,包含消息内容和会话ID
|
|
||||||
* @return Flux<String> 流式返回AI响应内容
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public Flux<String> chatByVectorStore(CustomMessage customMessage) {
|
|
||||||
// 生成唯一会话ID
|
|
||||||
Long sessionId = IdUtil.getSnowflakeNextId();
|
|
||||||
//修改会话
|
|
||||||
Conversations conversations = conversationsService.selectConversationsById(Convert.toLong(customMessage.getConversationId()));
|
|
||||||
conversations.setLastInteractionAt(new Date());
|
|
||||||
conversations.setTitle(customMessage.getMessage());
|
|
||||||
conversationsService.updateConversations(conversations);
|
|
||||||
// 用于收集完整的AI响应
|
|
||||||
PromptTemplate customPromptTemplate = PromptTemplate.builder()
|
|
||||||
.renderer(StTemplateRenderer.builder().startDelimiterToken('<').endDelimiterToken('>').build())
|
|
||||||
.template("""
|
|
||||||
<query>
|
|
||||||
|
|
||||||
Context information is below.
|
|
||||||
|
|
||||||
---------------------
|
|
||||||
<question_answer_context>
|
|
||||||
---------------------
|
|
||||||
|
|
||||||
Given the context information and no prior knowledge, answer the query.
|
|
||||||
|
|
||||||
Follow these rules:
|
|
||||||
|
|
||||||
1. If the answer is not in the context, just say that you don't know.
|
|
||||||
2. Avoid statements like "Based on the context..." or "The provided information...".
|
|
||||||
""")
|
|
||||||
.build();
|
|
||||||
|
|
||||||
String question = customMessage.getMessage();
|
|
||||||
|
|
||||||
QuestionAnswerAdvisor qaAdvisor = QuestionAnswerAdvisor.builder(vectorStore)
|
|
||||||
.promptTemplate(customPromptTemplate)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
|
|
||||||
// 收集每个流式数据块
|
|
||||||
return chatClient.prompt(question)
|
|
||||||
.advisors(a -> a.param(ChatMemory.CONVERSATION_ID, customMessage.getConversationId()))
|
|
||||||
.advisors(qaAdvisor)
|
|
||||||
.stream()
|
|
||||||
.content();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 与AI进行聊天对话
|
|
||||||
*
|
|
||||||
* @param customMessage 用户消息对象,包含消息内容和会话ID
|
|
||||||
* @return Flux<String> 流式返回AI响应内容
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public Flux<String> chatByUserContent(CustomMessage customMessage) {
|
|
||||||
if (chatClient == null){
|
|
||||||
return Flux.just("未开启聊天模型");
|
|
||||||
}
|
|
||||||
|
|
||||||
// 生成唯一会话ID
|
|
||||||
Long sessionId = IdUtil.getSnowflakeNextId();
|
|
||||||
//修改会话
|
|
||||||
Conversations conversations = conversationsService.selectConversationsById(Convert.toLong(customMessage.getConversationId()));
|
|
||||||
conversations.setLastInteractionAt(new Date());
|
|
||||||
conversations.setTitle(customMessage.getMessage());
|
|
||||||
conversationsService.updateConversations(conversations);
|
|
||||||
|
|
||||||
// 收集每个流式数据块
|
|
||||||
return chatClient.prompt(customMessage.getMessage())
|
|
||||||
.advisors(a -> a.param(ChatMemory.CONVERSATION_ID, customMessage.getConversationId()))
|
|
||||||
.stream()
|
|
||||||
.content();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,89 +0,0 @@
|
|||||||
package com.ruoyi.ai.chat.service.impl;
|
|
||||||
|
|
||||||
import cn.hutool.core.convert.Convert;
|
|
||||||
import com.ruoyi.ai.message.domain.ChatMessage;
|
|
||||||
import com.ruoyi.ai.chat.domain.CustomMessage;
|
|
||||||
import com.ruoyi.ai.message.service.IChatMessageService;
|
|
||||||
import com.ruoyi.common.utils.SecurityUtils;
|
|
||||||
import org.springframework.ai.chat.memory.ChatMemory;
|
|
||||||
import org.springframework.ai.chat.messages.AssistantMessage;
|
|
||||||
import org.springframework.ai.chat.messages.Message;
|
|
||||||
import org.springframework.ai.chat.messages.UserMessage;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
@Component
|
|
||||||
public class InSqlMemory implements ChatMemory {
|
|
||||||
@Autowired
|
|
||||||
private IChatMessageService chatMessageService;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void add(String conversationId, List<Message> messages) {
|
|
||||||
for (Message message : messages) {
|
|
||||||
CustomMessage customMessage = new CustomMessage();
|
|
||||||
customMessage.setConversationId(conversationId);
|
|
||||||
customMessage.setMessage(message.getText());
|
|
||||||
String role = "";
|
|
||||||
switch (message.getMessageType()) {
|
|
||||||
case USER:
|
|
||||||
role = "user";
|
|
||||||
customMessage.setType(role);
|
|
||||||
insertUserMessage(customMessage);
|
|
||||||
break;
|
|
||||||
case ASSISTANT:
|
|
||||||
role = "assistant";
|
|
||||||
customMessage.setType(role);
|
|
||||||
insertUserMessage(customMessage);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
role = "unknown";
|
|
||||||
break;
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<Message> get(String conversationId) {
|
|
||||||
ChatMessage chatMessageParam = new ChatMessage();
|
|
||||||
chatMessageParam.setConversationId(Convert.toLong(conversationId));
|
|
||||||
List<ChatMessage> chatMessages = chatMessageService.selectChatMessageList(chatMessageParam);
|
|
||||||
|
|
||||||
List<Message> messages = new ArrayList<>();
|
|
||||||
for (ChatMessage chatMessage : chatMessages) {
|
|
||||||
switch (chatMessage.getRole()) {
|
|
||||||
case "user":
|
|
||||||
messages.add(new UserMessage(chatMessage.getContent()));
|
|
||||||
break;
|
|
||||||
case "assistant":
|
|
||||||
messages.add(new AssistantMessage(chatMessage.getContent()));
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
throw new IllegalArgumentException("Unknown role: " + chatMessage.getRole());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//System.out.println("message 查询结果数量: " + (messages != null ? messages.size() : 0));
|
|
||||||
return messages;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void clear(String conversationId) {
|
|
||||||
chatMessageService.deleteChatMessageByConversationId(conversationId);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 保存用户消息到数据库
|
|
||||||
* @param customMessage 用户消息对象
|
|
||||||
*/
|
|
||||||
private void insertUserMessage(CustomMessage customMessage) {
|
|
||||||
ChatMessage chatMessage = new ChatMessage();
|
|
||||||
chatMessage.setContent(customMessage.getMessage());
|
|
||||||
chatMessage.setRole(customMessage.getType());
|
|
||||||
chatMessage.setSessionId(0L);
|
|
||||||
chatMessage.setConversationId(Convert.toLong(customMessage.getConversationId()));
|
|
||||||
//chatMessage.setCreateDept(SecurityUtils.getDeptId());
|
|
||||||
chatMessageService.insertChatMessage(chatMessage);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,116 +0,0 @@
|
|||||||
package com.ruoyi.ai.conversation.controller;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import cn.hutool.core.convert.Convert;
|
|
||||||
import com.ruoyi.common.utils.SecurityUtils;
|
|
||||||
import jakarta.servlet.http.HttpServletResponse;
|
|
||||||
import org.springframework.security.access.prepost.PreAuthorize;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
|
||||||
import org.springframework.web.bind.annotation.PutMapping;
|
|
||||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
|
||||||
import org.springframework.web.bind.annotation.PathVariable;
|
|
||||||
import org.springframework.web.bind.annotation.RequestBody;
|
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
|
||||||
import com.ruoyi.common.annotation.Log;
|
|
||||||
import com.ruoyi.common.core.controller.BaseController;
|
|
||||||
import com.ruoyi.common.core.domain.AjaxResult;
|
|
||||||
import com.ruoyi.common.enums.BusinessType;
|
|
||||||
import com.ruoyi.ai.conversation.domain.Conversations;
|
|
||||||
import com.ruoyi.ai.conversation.service.IConversationsService;
|
|
||||||
import com.ruoyi.ai.message.domain.ChatMessage;
|
|
||||||
import com.ruoyi.ai.message.service.IChatMessageService;
|
|
||||||
import com.ruoyi.common.utils.poi.ExcelUtil;
|
|
||||||
import com.ruoyi.common.core.page.TableDataInfo;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* RAG项目会话管理Controller
|
|
||||||
*
|
|
||||||
* @author ruoyi
|
|
||||||
* @date 2025-08-27
|
|
||||||
*/
|
|
||||||
@RestController
|
|
||||||
@RequestMapping("/ai/conversations")
|
|
||||||
public class ConversationsController extends BaseController
|
|
||||||
{
|
|
||||||
@Autowired
|
|
||||||
private IConversationsService conversationsService;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private IChatMessageService chatMessageService;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 查询RAG项目会话管理列表
|
|
||||||
*/
|
|
||||||
@PreAuthorize("@ss.hasPermi('ai:conversations:list')")
|
|
||||||
@GetMapping("/list")
|
|
||||||
public TableDataInfo list(Conversations conversations)
|
|
||||||
{
|
|
||||||
startPage();
|
|
||||||
conversations.setUserId(Convert.toStr(SecurityUtils.getUserId()));
|
|
||||||
List<Conversations> list = conversationsService.selectConversationsList(conversations);
|
|
||||||
return getDataTable(list);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 导出RAG项目会话管理列表
|
|
||||||
*/
|
|
||||||
@PreAuthorize("@ss.hasPermi('ai:conversations:export')")
|
|
||||||
@Log(title = "RAG项目会话管理", businessType = BusinessType.EXPORT)
|
|
||||||
@PostMapping("/export")
|
|
||||||
public void export(HttpServletResponse response, Conversations conversations)
|
|
||||||
{
|
|
||||||
List<Conversations> list = conversationsService.selectConversationsList(conversations);
|
|
||||||
ExcelUtil<Conversations> util = new ExcelUtil<Conversations>(Conversations.class);
|
|
||||||
util.exportExcel(response, list, "RAG项目会话管理数据");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取RAG项目会话管理详细信息
|
|
||||||
*/
|
|
||||||
@PreAuthorize("@ss.hasPermi('ai:conversations:query')")
|
|
||||||
@GetMapping(value = "/{id}")
|
|
||||||
public AjaxResult getInfo(@PathVariable("id") Long id)
|
|
||||||
{
|
|
||||||
return success(conversationsService.selectConversationsById(id));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 新增RAG项目会话管理
|
|
||||||
*/
|
|
||||||
@PreAuthorize("@ss.hasPermi('ai:conversations:add')")
|
|
||||||
@Log(title = "RAG项目会话管理", businessType = BusinessType.INSERT)
|
|
||||||
@PostMapping
|
|
||||||
public AjaxResult add(@RequestBody Conversations conversations)
|
|
||||||
{
|
|
||||||
conversationsService.insertConversations(conversations);
|
|
||||||
return AjaxResult.success(conversations.getId());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 修改RAG项目会话管理
|
|
||||||
*/
|
|
||||||
@PreAuthorize("@ss.hasPermi('ai:conversations:edit')")
|
|
||||||
@Log(title = "RAG项目会话管理", businessType = BusinessType.UPDATE)
|
|
||||||
@PutMapping
|
|
||||||
public AjaxResult edit(@RequestBody Conversations conversations)
|
|
||||||
{
|
|
||||||
return toAjax(conversationsService.updateConversations(conversations));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 删除RAG项目会话管理
|
|
||||||
*/
|
|
||||||
@PreAuthorize("@ss.hasPermi('ai:conversations:remove')")
|
|
||||||
@Log(title = "RAG项目会话管理", businessType = BusinessType.DELETE)
|
|
||||||
@DeleteMapping("/{ids}")
|
|
||||||
public AjaxResult remove(@PathVariable Long[] ids)
|
|
||||||
{
|
|
||||||
return toAjax(conversationsService.deleteConversationsByIds(ids));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,207 +0,0 @@
|
|||||||
package com.ruoyi.ai.conversation.domain;
|
|
||||||
|
|
||||||
import java.util.Date;
|
|
||||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
|
||||||
import org.apache.commons.lang3.builder.ToStringBuilder;
|
|
||||||
import org.apache.commons.lang3.builder.ToStringStyle;
|
|
||||||
import com.ruoyi.common.annotation.Excel;
|
|
||||||
import com.ruoyi.common.core.domain.BaseEntity;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* RAG项目会话管理对象 conversations
|
|
||||||
*
|
|
||||||
* @author ruoyi
|
|
||||||
* @date 2025-08-27
|
|
||||||
*/
|
|
||||||
public class Conversations extends BaseEntity
|
|
||||||
{
|
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
|
|
||||||
/** 会话内部唯一ID */
|
|
||||||
private Long id;
|
|
||||||
|
|
||||||
/** 外部会话标识(sessionId) */
|
|
||||||
@Excel(name = "外部会话标识", readConverterExp = "s=essionId")
|
|
||||||
private String sessionId;
|
|
||||||
|
|
||||||
/** 用户唯一ID */
|
|
||||||
@Excel(name = "用户唯一ID")
|
|
||||||
private String userId;
|
|
||||||
|
|
||||||
/** 会话标题 */
|
|
||||||
@Excel(name = "会话标题")
|
|
||||||
private String title;
|
|
||||||
|
|
||||||
/** 会话状态 */
|
|
||||||
@Excel(name = "会话状态")
|
|
||||||
private String status;
|
|
||||||
|
|
||||||
/** 会话元数据(JSON格式) */
|
|
||||||
@Excel(name = "会话元数据", readConverterExp = "J=SON格式")
|
|
||||||
private String metadata;
|
|
||||||
|
|
||||||
/** 首次查询内容 */
|
|
||||||
@Excel(name = "首次查询内容")
|
|
||||||
private String firstQuery;
|
|
||||||
|
|
||||||
/** 消息总数 */
|
|
||||||
@Excel(name = "消息总数")
|
|
||||||
private Long messageCount;
|
|
||||||
|
|
||||||
/** 累计Token消耗 */
|
|
||||||
@Excel(name = "累计Token消耗")
|
|
||||||
private Long tokenUsage;
|
|
||||||
|
|
||||||
/** 会话创建时间 */
|
|
||||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
|
||||||
@Excel(name = "会话创建时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
|
|
||||||
private Date createdAt;
|
|
||||||
|
|
||||||
/** 最后更新时间 */
|
|
||||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
|
||||||
@Excel(name = "最后更新时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
|
|
||||||
private Date updatedAt;
|
|
||||||
|
|
||||||
/** 最后交互时间 */
|
|
||||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
|
||||||
@Excel(name = "最后交互时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
|
|
||||||
private Date lastInteractionAt;
|
|
||||||
|
|
||||||
public void setId(Long id)
|
|
||||||
{
|
|
||||||
this.id = id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Long getId()
|
|
||||||
{
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setSessionId(String sessionId)
|
|
||||||
{
|
|
||||||
this.sessionId = sessionId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getSessionId()
|
|
||||||
{
|
|
||||||
return sessionId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setUserId(String userId)
|
|
||||||
{
|
|
||||||
this.userId = userId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getUserId()
|
|
||||||
{
|
|
||||||
return userId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setTitle(String title)
|
|
||||||
{
|
|
||||||
this.title = title;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getTitle()
|
|
||||||
{
|
|
||||||
return title;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setStatus(String status)
|
|
||||||
{
|
|
||||||
this.status = status;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getStatus()
|
|
||||||
{
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setMetadata(String metadata)
|
|
||||||
{
|
|
||||||
this.metadata = metadata;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getMetadata()
|
|
||||||
{
|
|
||||||
return metadata;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setFirstQuery(String firstQuery)
|
|
||||||
{
|
|
||||||
this.firstQuery = firstQuery;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getFirstQuery()
|
|
||||||
{
|
|
||||||
return firstQuery;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setMessageCount(Long messageCount)
|
|
||||||
{
|
|
||||||
this.messageCount = messageCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Long getMessageCount()
|
|
||||||
{
|
|
||||||
return messageCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setTokenUsage(Long tokenUsage)
|
|
||||||
{
|
|
||||||
this.tokenUsage = tokenUsage;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Long getTokenUsage()
|
|
||||||
{
|
|
||||||
return tokenUsage;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setCreatedAt(Date createdAt)
|
|
||||||
{
|
|
||||||
this.createdAt = createdAt;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Date getCreatedAt()
|
|
||||||
{
|
|
||||||
return createdAt;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setUpdatedAt(Date updatedAt)
|
|
||||||
{
|
|
||||||
this.updatedAt = updatedAt;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Date getUpdatedAt()
|
|
||||||
{
|
|
||||||
return updatedAt;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setLastInteractionAt(Date lastInteractionAt)
|
|
||||||
{
|
|
||||||
this.lastInteractionAt = lastInteractionAt;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Date getLastInteractionAt()
|
|
||||||
{
|
|
||||||
return lastInteractionAt;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
|
|
||||||
.append("id", getId())
|
|
||||||
.append("sessionId", getSessionId())
|
|
||||||
.append("userId", getUserId())
|
|
||||||
.append("title", getTitle())
|
|
||||||
.append("status", getStatus())
|
|
||||||
.append("metadata", getMetadata())
|
|
||||||
.append("firstQuery", getFirstQuery())
|
|
||||||
.append("messageCount", getMessageCount())
|
|
||||||
.append("tokenUsage", getTokenUsage())
|
|
||||||
.append("createdAt", getCreatedAt())
|
|
||||||
.append("updatedAt", getUpdatedAt())
|
|
||||||
.append("lastInteractionAt", getLastInteractionAt())
|
|
||||||
.toString();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,61 +0,0 @@
|
|||||||
package com.ruoyi.ai.conversation.mapper;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import com.ruoyi.ai.conversation.domain.Conversations;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* RAG项目会话管理Mapper接口
|
|
||||||
*
|
|
||||||
* @author ruoyi
|
|
||||||
* @date 2025-08-27
|
|
||||||
*/
|
|
||||||
public interface ConversationsMapper
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* 查询RAG项目会话管理
|
|
||||||
*
|
|
||||||
* @param id RAG项目会话管理主键
|
|
||||||
* @return RAG项目会话管理
|
|
||||||
*/
|
|
||||||
public Conversations selectConversationsById(Long id);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 查询RAG项目会话管理列表
|
|
||||||
*
|
|
||||||
* @param conversations RAG项目会话管理
|
|
||||||
* @return RAG项目会话管理集合
|
|
||||||
*/
|
|
||||||
public List<Conversations> selectConversationsList(Conversations conversations);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 新增RAG项目会话管理
|
|
||||||
*
|
|
||||||
* @param conversations RAG项目会话管理
|
|
||||||
* @return 结果
|
|
||||||
*/
|
|
||||||
public int insertConversations(Conversations conversations);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 修改RAG项目会话管理
|
|
||||||
*
|
|
||||||
* @param conversations RAG项目会话管理
|
|
||||||
* @return 结果
|
|
||||||
*/
|
|
||||||
public int updateConversations(Conversations conversations);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 删除RAG项目会话管理
|
|
||||||
*
|
|
||||||
* @param id RAG项目会话管理主键
|
|
||||||
* @return 结果
|
|
||||||
*/
|
|
||||||
public int deleteConversationsById(Long id);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 批量删除RAG项目会话管理
|
|
||||||
*
|
|
||||||
* @param ids 需要删除的数据主键集合
|
|
||||||
* @return 结果
|
|
||||||
*/
|
|
||||||
public int deleteConversationsByIds(Long[] ids);
|
|
||||||
}
|
|
||||||
@@ -1,61 +0,0 @@
|
|||||||
package com.ruoyi.ai.conversation.service;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import com.ruoyi.ai.conversation.domain.Conversations;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* RAG项目会话管理Service接口
|
|
||||||
*
|
|
||||||
* @author ruoyi
|
|
||||||
* @date 2025-08-27
|
|
||||||
*/
|
|
||||||
public interface IConversationsService
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* 查询RAG项目会话管理
|
|
||||||
*
|
|
||||||
* @param id RAG项目会话管理主键
|
|
||||||
* @return RAG项目会话管理
|
|
||||||
*/
|
|
||||||
public Conversations selectConversationsById(Long id);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 查询RAG项目会话管理列表
|
|
||||||
*
|
|
||||||
* @param conversations RAG项目会话管理
|
|
||||||
* @return RAG项目会话管理集合
|
|
||||||
*/
|
|
||||||
public List<Conversations> selectConversationsList(Conversations conversations);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 新增RAG项目会话管理
|
|
||||||
*
|
|
||||||
* @param conversations RAG项目会话管理
|
|
||||||
* @return 结果
|
|
||||||
*/
|
|
||||||
public int insertConversations(Conversations conversations);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 修改RAG项目会话管理
|
|
||||||
*
|
|
||||||
* @param conversations RAG项目会话管理
|
|
||||||
* @return 结果
|
|
||||||
*/
|
|
||||||
public int updateConversations(Conversations conversations);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 批量删除RAG项目会话管理
|
|
||||||
*
|
|
||||||
* @param ids 需要删除的RAG项目会话管理主键集合
|
|
||||||
* @return 结果
|
|
||||||
*/
|
|
||||||
public int deleteConversationsByIds(Long[] ids);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 删除RAG项目会话管理信息
|
|
||||||
*
|
|
||||||
* @param id RAG项目会话管理主键
|
|
||||||
* @return 结果
|
|
||||||
*/
|
|
||||||
public int deleteConversationsById(Long id);
|
|
||||||
}
|
|
||||||
@@ -1,101 +0,0 @@
|
|||||||
package com.ruoyi.ai.conversation.service.impl;
|
|
||||||
|
|
||||||
import java.util.Date;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import cn.hutool.core.convert.Convert;
|
|
||||||
import com.ruoyi.common.utils.SecurityUtils;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.stereotype.Service;
|
|
||||||
import com.ruoyi.ai.conversation.mapper.ConversationsMapper;
|
|
||||||
import com.ruoyi.ai.conversation.domain.Conversations;
|
|
||||||
import com.ruoyi.ai.conversation.service.IConversationsService;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* RAG项目会话管理Service业务层处理
|
|
||||||
*
|
|
||||||
* @author ruoyi
|
|
||||||
* @date 2025-08-27
|
|
||||||
*/
|
|
||||||
@Service
|
|
||||||
public class ConversationsServiceImpl implements IConversationsService
|
|
||||||
{
|
|
||||||
@Autowired
|
|
||||||
private ConversationsMapper conversationsMapper;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 查询RAG项目会话管理
|
|
||||||
*
|
|
||||||
* @param id RAG项目会话管理主键
|
|
||||||
* @return RAG项目会话管理
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public Conversations selectConversationsById(Long id)
|
|
||||||
{
|
|
||||||
return conversationsMapper.selectConversationsById(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 查询RAG项目会话管理列表
|
|
||||||
*
|
|
||||||
* @param conversations RAG项目会话管理
|
|
||||||
* @return RAG项目会话管理
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public List<Conversations> selectConversationsList(Conversations conversations)
|
|
||||||
{
|
|
||||||
return conversationsMapper.selectConversationsList(conversations);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 新增RAG项目会话管理
|
|
||||||
*
|
|
||||||
* @param conversations RAG项目会话管理
|
|
||||||
* @return 结果
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public int insertConversations(Conversations conversations)
|
|
||||||
{
|
|
||||||
conversations.setUserId(Convert.toStr(SecurityUtils.getUserId()));
|
|
||||||
conversations.setCreatedAt(new Date());
|
|
||||||
conversations.setUpdatedAt(new Date());
|
|
||||||
conversations.setSessionId(Convert.toStr(SecurityUtils.getUserId()));
|
|
||||||
return conversationsMapper.insertConversations(conversations);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 修改RAG项目会话管理
|
|
||||||
*
|
|
||||||
* @param conversations RAG项目会话管理
|
|
||||||
* @return 结果
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public int updateConversations(Conversations conversations)
|
|
||||||
{
|
|
||||||
return conversationsMapper.updateConversations(conversations);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 批量删除RAG项目会话管理
|
|
||||||
*
|
|
||||||
* @param ids 需要删除的RAG项目会话管理主键
|
|
||||||
* @return 结果
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public int deleteConversationsByIds(Long[] ids)
|
|
||||||
{
|
|
||||||
return conversationsMapper.deleteConversationsByIds(ids);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 删除RAG项目会话管理信息
|
|
||||||
*
|
|
||||||
* @param id RAG项目会话管理主键
|
|
||||||
* @return 结果
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public int deleteConversationsById(Long id)
|
|
||||||
{
|
|
||||||
return conversationsMapper.deleteConversationsById(id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,104 +0,0 @@
|
|||||||
package com.ruoyi.ai.message.controller;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import jakarta.servlet.http.HttpServletResponse;
|
|
||||||
import org.springframework.security.access.prepost.PreAuthorize;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
|
||||||
import org.springframework.web.bind.annotation.PutMapping;
|
|
||||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
|
||||||
import org.springframework.web.bind.annotation.PathVariable;
|
|
||||||
import org.springframework.web.bind.annotation.RequestBody;
|
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
|
||||||
import com.ruoyi.common.annotation.Log;
|
|
||||||
import com.ruoyi.common.core.controller.BaseController;
|
|
||||||
import com.ruoyi.common.core.domain.AjaxResult;
|
|
||||||
import com.ruoyi.common.enums.BusinessType;
|
|
||||||
import com.ruoyi.ai.message.domain.ChatMessage;
|
|
||||||
import com.ruoyi.ai.message.service.IChatMessageService;
|
|
||||||
import com.ruoyi.common.utils.poi.ExcelUtil;
|
|
||||||
import com.ruoyi.common.core.page.TableDataInfo;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 聊天消息Controller
|
|
||||||
*
|
|
||||||
* @author ruoyi
|
|
||||||
* @date 2025-08-27
|
|
||||||
*/
|
|
||||||
@RestController
|
|
||||||
@RequestMapping("/ai/message")
|
|
||||||
public class ChatMessageController extends BaseController
|
|
||||||
{
|
|
||||||
@Autowired
|
|
||||||
private IChatMessageService chatMessageService;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 查询聊天消息列表
|
|
||||||
*/
|
|
||||||
@PreAuthorize("@ss.hasPermi('ai:message:list')")
|
|
||||||
@GetMapping("/list")
|
|
||||||
public TableDataInfo list(ChatMessage chatMessage)
|
|
||||||
{
|
|
||||||
startPage();
|
|
||||||
List<ChatMessage> list = chatMessageService.selectChatMessageList(chatMessage);
|
|
||||||
return getDataTable(list);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 导出聊天消息列表
|
|
||||||
*/
|
|
||||||
@PreAuthorize("@ss.hasPermi('ai:message:export')")
|
|
||||||
@Log(title = "聊天消息", businessType = BusinessType.EXPORT)
|
|
||||||
@PostMapping("/export")
|
|
||||||
public void export(HttpServletResponse response, ChatMessage chatMessage)
|
|
||||||
{
|
|
||||||
List<ChatMessage> list = chatMessageService.selectChatMessageList(chatMessage);
|
|
||||||
ExcelUtil<ChatMessage> util = new ExcelUtil<ChatMessage>(ChatMessage.class);
|
|
||||||
util.exportExcel(response, list, "聊天消息数据");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取聊天消息详细信息
|
|
||||||
*/
|
|
||||||
@PreAuthorize("@ss.hasPermi('ai:message:query')")
|
|
||||||
@GetMapping(value = "/{id}")
|
|
||||||
public AjaxResult getInfo(@PathVariable("id") Long id)
|
|
||||||
{
|
|
||||||
return success(chatMessageService.selectChatMessageById(id));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 新增聊天消息
|
|
||||||
*/
|
|
||||||
@PreAuthorize("@ss.hasPermi('ai:message:add')")
|
|
||||||
@Log(title = "聊天消息", businessType = BusinessType.INSERT)
|
|
||||||
@PostMapping
|
|
||||||
public AjaxResult add(@RequestBody ChatMessage chatMessage)
|
|
||||||
{
|
|
||||||
return toAjax(chatMessageService.insertChatMessage(chatMessage));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 修改聊天消息
|
|
||||||
*/
|
|
||||||
@PreAuthorize("@ss.hasPermi('ai:message:edit')")
|
|
||||||
@Log(title = "聊天消息", businessType = BusinessType.UPDATE)
|
|
||||||
@PutMapping
|
|
||||||
public AjaxResult edit(@RequestBody ChatMessage chatMessage)
|
|
||||||
{
|
|
||||||
return toAjax(chatMessageService.updateChatMessage(chatMessage));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 删除聊天消息
|
|
||||||
*/
|
|
||||||
@PreAuthorize("@ss.hasPermi('ai:message:remove')")
|
|
||||||
@Log(title = "聊天消息", businessType = BusinessType.DELETE)
|
|
||||||
@DeleteMapping("/{ids}")
|
|
||||||
public AjaxResult remove(@PathVariable Long[] ids)
|
|
||||||
{
|
|
||||||
return toAjax(chatMessageService.deleteChatMessageByIds(ids));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,163 +0,0 @@
|
|||||||
package com.ruoyi.ai.message.domain;
|
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
|
||||||
import org.apache.commons.lang3.builder.ToStringBuilder;
|
|
||||||
import org.apache.commons.lang3.builder.ToStringStyle;
|
|
||||||
import com.ruoyi.common.annotation.Excel;
|
|
||||||
import com.ruoyi.common.core.domain.BaseEntity;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 聊天消息对象 chat_message
|
|
||||||
*
|
|
||||||
* @author ruoyi
|
|
||||||
* @date 2025-08-27
|
|
||||||
*/
|
|
||||||
public class ChatMessage extends BaseEntity
|
|
||||||
{
|
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
|
|
||||||
/** 主键 */
|
|
||||||
private Long id;
|
|
||||||
|
|
||||||
/** 会话组id */
|
|
||||||
@Excel(name = "会话组id")
|
|
||||||
private Long sessionId;
|
|
||||||
|
|
||||||
/** 会话id */
|
|
||||||
@Excel(name = "会话id")
|
|
||||||
private Long conversationId;
|
|
||||||
|
|
||||||
/** 消息内容 */
|
|
||||||
@Excel(name = "消息内容")
|
|
||||||
private String content;
|
|
||||||
|
|
||||||
/** 对话角色 */
|
|
||||||
@Excel(name = "对话角色")
|
|
||||||
private String role;
|
|
||||||
|
|
||||||
/** 扣除金额 */
|
|
||||||
@Excel(name = "扣除金额")
|
|
||||||
private BigDecimal deductCost;
|
|
||||||
|
|
||||||
/** 累计 Tokens */
|
|
||||||
@Excel(name = "累计 Tokens")
|
|
||||||
private Long totalTokens;
|
|
||||||
|
|
||||||
/** 模型名称 */
|
|
||||||
@Excel(name = "模型名称")
|
|
||||||
private String modelName;
|
|
||||||
|
|
||||||
/** 创建部门 */
|
|
||||||
@Excel(name = "创建部门")
|
|
||||||
private Long createDept;
|
|
||||||
|
|
||||||
public void setId(Long id)
|
|
||||||
{
|
|
||||||
this.id = id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Long getId()
|
|
||||||
{
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setSessionId(Long sessionId)
|
|
||||||
{
|
|
||||||
this.sessionId = sessionId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Long getSessionId()
|
|
||||||
{
|
|
||||||
return sessionId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setConversationId(Long conversationId)
|
|
||||||
{
|
|
||||||
this.conversationId = conversationId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Long getConversationId()
|
|
||||||
{
|
|
||||||
return conversationId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setContent(String content)
|
|
||||||
{
|
|
||||||
this.content = content;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getContent()
|
|
||||||
{
|
|
||||||
return content;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setRole(String role)
|
|
||||||
{
|
|
||||||
this.role = role;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getRole()
|
|
||||||
{
|
|
||||||
return role;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setDeductCost(BigDecimal deductCost)
|
|
||||||
{
|
|
||||||
this.deductCost = deductCost;
|
|
||||||
}
|
|
||||||
|
|
||||||
public BigDecimal getDeductCost()
|
|
||||||
{
|
|
||||||
return deductCost;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setTotalTokens(Long totalTokens)
|
|
||||||
{
|
|
||||||
this.totalTokens = totalTokens;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Long getTotalTokens()
|
|
||||||
{
|
|
||||||
return totalTokens;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setModelName(String modelName)
|
|
||||||
{
|
|
||||||
this.modelName = modelName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getModelName()
|
|
||||||
{
|
|
||||||
return modelName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setCreateDept(Long createDept)
|
|
||||||
{
|
|
||||||
this.createDept = createDept;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Long getCreateDept()
|
|
||||||
{
|
|
||||||
return createDept;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
|
|
||||||
.append("id", getId())
|
|
||||||
.append("sessionId", getSessionId())
|
|
||||||
.append("conversationId", getConversationId())
|
|
||||||
.append("content", getContent())
|
|
||||||
.append("role", getRole())
|
|
||||||
.append("deductCost", getDeductCost())
|
|
||||||
.append("totalTokens", getTotalTokens())
|
|
||||||
.append("modelName", getModelName())
|
|
||||||
.append("createDept", getCreateDept())
|
|
||||||
.append("createBy", getCreateBy())
|
|
||||||
.append("createTime", getCreateTime())
|
|
||||||
.append("updateBy", getUpdateBy())
|
|
||||||
.append("updateTime", getUpdateTime())
|
|
||||||
.append("remark", getRemark())
|
|
||||||
.toString();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,63 +0,0 @@
|
|||||||
package com.ruoyi.ai.message.mapper;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import com.ruoyi.ai.message.domain.ChatMessage;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 聊天消息Mapper接口
|
|
||||||
*
|
|
||||||
* @author ruoyi
|
|
||||||
* @date 2025-08-27
|
|
||||||
*/
|
|
||||||
public interface ChatMessageMapper
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* 查询聊天消息
|
|
||||||
*
|
|
||||||
* @param id 聊天消息主键
|
|
||||||
* @return 聊天消息
|
|
||||||
*/
|
|
||||||
public ChatMessage selectChatMessageById(Long id);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 查询聊天消息列表
|
|
||||||
*
|
|
||||||
* @param chatMessage 聊天消息
|
|
||||||
* @return 聊天消息集合
|
|
||||||
*/
|
|
||||||
public List<ChatMessage> selectChatMessageList(ChatMessage chatMessage);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 新增聊天消息
|
|
||||||
*
|
|
||||||
* @param chatMessage 聊天消息
|
|
||||||
* @return 结果
|
|
||||||
*/
|
|
||||||
public int insertChatMessage(ChatMessage chatMessage);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 修改聊天消息
|
|
||||||
*
|
|
||||||
* @param chatMessage 聊天消息
|
|
||||||
* @return 结果
|
|
||||||
*/
|
|
||||||
public int updateChatMessage(ChatMessage chatMessage);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 删除聊天消息
|
|
||||||
*
|
|
||||||
* @param id 聊天消息主键
|
|
||||||
* @return 结果
|
|
||||||
*/
|
|
||||||
public int deleteChatMessageById(Long id);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 批量删除聊天消息
|
|
||||||
*
|
|
||||||
* @param ids 需要删除的数据主键集合
|
|
||||||
* @return 结果
|
|
||||||
*/
|
|
||||||
public int deleteChatMessageByIds(Long[] ids);
|
|
||||||
|
|
||||||
void deleteChatMessageByConversationId(String conversationId);
|
|
||||||
}
|
|
||||||
@@ -1,63 +0,0 @@
|
|||||||
package com.ruoyi.ai.message.service;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import com.ruoyi.ai.message.domain.ChatMessage;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 聊天消息Service接口
|
|
||||||
*
|
|
||||||
* @author ruoyi
|
|
||||||
* @date 2025-08-27
|
|
||||||
*/
|
|
||||||
public interface IChatMessageService
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* 查询聊天消息
|
|
||||||
*
|
|
||||||
* @param id 聊天消息主键
|
|
||||||
* @return 聊天消息
|
|
||||||
*/
|
|
||||||
public ChatMessage selectChatMessageById(Long id);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 查询聊天消息列表
|
|
||||||
*
|
|
||||||
* @param chatMessage 聊天消息
|
|
||||||
* @return 聊天消息集合
|
|
||||||
*/
|
|
||||||
public List<ChatMessage> selectChatMessageList(ChatMessage chatMessage);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 新增聊天消息
|
|
||||||
*
|
|
||||||
* @param chatMessage 聊天消息
|
|
||||||
* @return 结果
|
|
||||||
*/
|
|
||||||
public int insertChatMessage(ChatMessage chatMessage);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 修改聊天消息
|
|
||||||
*
|
|
||||||
* @param chatMessage 聊天消息
|
|
||||||
* @return 结果
|
|
||||||
*/
|
|
||||||
public int updateChatMessage(ChatMessage chatMessage);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 批量删除聊天消息
|
|
||||||
*
|
|
||||||
* @param ids 需要删除的聊天消息主键集合
|
|
||||||
* @return 结果
|
|
||||||
*/
|
|
||||||
public int deleteChatMessageByIds(Long[] ids);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 删除聊天消息信息
|
|
||||||
*
|
|
||||||
* @param id 聊天消息主键
|
|
||||||
* @return 结果
|
|
||||||
*/
|
|
||||||
public int deleteChatMessageById(Long id);
|
|
||||||
|
|
||||||
void deleteChatMessageByConversationId(String conversationId);
|
|
||||||
}
|
|
||||||
@@ -1,101 +0,0 @@
|
|||||||
package com.ruoyi.ai.message.service.impl;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import com.ruoyi.common.utils.DateUtils;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.stereotype.Service;
|
|
||||||
import com.ruoyi.ai.message.mapper.ChatMessageMapper;
|
|
||||||
import com.ruoyi.ai.message.domain.ChatMessage;
|
|
||||||
import com.ruoyi.ai.message.service.IChatMessageService;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 聊天消息Service业务层处理
|
|
||||||
*
|
|
||||||
* @author ruoyi
|
|
||||||
* @date 2025-08-27
|
|
||||||
*/
|
|
||||||
@Service
|
|
||||||
public class ChatMessageServiceImpl implements IChatMessageService
|
|
||||||
{
|
|
||||||
@Autowired
|
|
||||||
private ChatMessageMapper chatMessageMapper;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 查询聊天消息
|
|
||||||
*
|
|
||||||
* @param id 聊天消息主键
|
|
||||||
* @return 聊天消息
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public ChatMessage selectChatMessageById(Long id)
|
|
||||||
{
|
|
||||||
return chatMessageMapper.selectChatMessageById(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 查询聊天消息列表
|
|
||||||
*
|
|
||||||
* @param chatMessage 聊天消息
|
|
||||||
* @return 聊天消息
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public List<ChatMessage> selectChatMessageList(ChatMessage chatMessage)
|
|
||||||
{
|
|
||||||
return chatMessageMapper.selectChatMessageList(chatMessage);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 新增聊天消息
|
|
||||||
*
|
|
||||||
* @param chatMessage 聊天消息
|
|
||||||
* @return 结果
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public int insertChatMessage(ChatMessage chatMessage)
|
|
||||||
{
|
|
||||||
chatMessage.setCreateTime(DateUtils.getNowDate());
|
|
||||||
return chatMessageMapper.insertChatMessage(chatMessage);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 修改聊天消息
|
|
||||||
*
|
|
||||||
* @param chatMessage 聊天消息
|
|
||||||
* @return 结果
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public int updateChatMessage(ChatMessage chatMessage)
|
|
||||||
{
|
|
||||||
chatMessage.setUpdateTime(DateUtils.getNowDate());
|
|
||||||
return chatMessageMapper.updateChatMessage(chatMessage);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 批量删除聊天消息
|
|
||||||
*
|
|
||||||
* @param ids 需要删除的聊天消息主键
|
|
||||||
* @return 结果
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public int deleteChatMessageByIds(Long[] ids)
|
|
||||||
{
|
|
||||||
return chatMessageMapper.deleteChatMessageByIds(ids);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 删除聊天消息信息
|
|
||||||
*
|
|
||||||
* @param id 聊天消息主键
|
|
||||||
* @return 结果
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public int deleteChatMessageById(Long id)
|
|
||||||
{
|
|
||||||
return chatMessageMapper.deleteChatMessageById(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void deleteChatMessageByConversationId(String conversationId) {
|
|
||||||
chatMessageMapper.deleteChatMessageByConversationId(conversationId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
package com.ruoyi.ai.util.domain;
|
|
||||||
|
|
||||||
import lombok.AllArgsConstructor;
|
|
||||||
import lombok.Data;
|
|
||||||
import lombok.NoArgsConstructor;
|
|
||||||
import org.springframework.ai.tool.annotation.ToolParam;
|
|
||||||
|
|
||||||
@Data
|
|
||||||
@AllArgsConstructor
|
|
||||||
@NoArgsConstructor
|
|
||||||
public class ToolParamQuery {
|
|
||||||
|
|
||||||
@ToolParam(required = false,description = "地区")
|
|
||||||
private String currentTimeRegion;
|
|
||||||
}
|
|
||||||
@@ -1,43 +0,0 @@
|
|||||||
package com.ruoyi.ai.util.service;
|
|
||||||
|
|
||||||
import com.ruoyi.stock.stock.domain.BasStock;
|
|
||||||
import com.ruoyi.stock.stock.service.IBasStockService;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
import org.springframework.ai.tool.annotation.Tool;
|
|
||||||
import org.springframework.ai.tool.annotation.ToolParam;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
@Component
|
|
||||||
@Slf4j
|
|
||||||
public class BasStockToolService {
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private IBasStockService basStockService;
|
|
||||||
|
|
||||||
|
|
||||||
@Tool(description = "根据仓库id查询库存信息")
|
|
||||||
public List<BasStock> getStockInfo(@ToolParam(required = true, description = "仓库id") String warehouseId) {
|
|
||||||
BasStock basStock = new BasStock();
|
|
||||||
basStock.setWarehouseId(warehouseId);
|
|
||||||
List<BasStock> basStocks = basStockService.selectBasStockListApi(basStock);
|
|
||||||
return basStocks;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Tool(description = "根据库存id生成作业")
|
|
||||||
public String createMydoJob(@ToolParam(required = true, description = "库存id") String stockId) {
|
|
||||||
log.info("库存:{},已生成作业",stockId);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Tool(description = "根据单据状态查询单据")
|
|
||||||
public String selectInStockInfo(@ToolParam(required = true, description = "单据状态") String status) {
|
|
||||||
log.info("根据单据状态查询单据:{},已生成作业",status);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
package com.ruoyi.ai.util.service;
|
|
||||||
|
|
||||||
import cn.hutool.core.date.DateUtil;
|
|
||||||
import org.springframework.ai.tool.annotation.Tool;
|
|
||||||
import org.springframework.ai.tool.annotation.ToolParam;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
|
|
||||||
@Component
|
|
||||||
public class ToolService {
|
|
||||||
|
|
||||||
|
|
||||||
@Tool(description = "根据地区,获取当前时间")
|
|
||||||
public String getCurrentTime(@ToolParam(required = false, description = "地区") String currentTimeRegion) {
|
|
||||||
System.out.println("getCurrentTime"+currentTimeRegion);
|
|
||||||
return DateUtil.format(DateUtil.date(), "yyyy-MM-dd HH:mm:ss");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Tool(description = "根据地区,获取当前天气")
|
|
||||||
public String getTQ(@ToolParam(required = false, description = "地区") String currentTimeRegion) {
|
|
||||||
System.out.println("getTQ"+currentTimeRegion);
|
|
||||||
return "特大台风";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Tool(description = "根据地区,获取当前温度")
|
|
||||||
public String getWD(@ToolParam(required = false, description = "地区") String currentTimeRegion) {
|
|
||||||
System.out.println("getWD"+currentTimeRegion);
|
|
||||||
return "500摄氏度";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
package com.ruoyi.ai.vector.controller;
|
|
||||||
|
|
||||||
import com.ruoyi.ai.vector.service.DataVectorService;
|
|
||||||
import com.ruoyi.common.core.domain.AjaxResult;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
|
||||||
|
|
||||||
@RestController
|
|
||||||
@RequestMapping("/api/vector")
|
|
||||||
public class DataVectorController {
|
|
||||||
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private DataVectorService dataVectorService;
|
|
||||||
@RequestMapping("/demo")
|
|
||||||
public AjaxResult demo(MultipartFile file) {
|
|
||||||
return dataVectorService.demo(file);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@RequestMapping("/searchDemo")
|
|
||||||
public AjaxResult searchDemo(String message) {
|
|
||||||
return dataVectorService.searchDemo(message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,104 +0,0 @@
|
|||||||
package com.ruoyi.ai.vector.controller;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import jakarta.servlet.http.HttpServletResponse;
|
|
||||||
import org.springframework.security.access.prepost.PreAuthorize;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
|
||||||
import org.springframework.web.bind.annotation.PutMapping;
|
|
||||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
|
||||||
import org.springframework.web.bind.annotation.PathVariable;
|
|
||||||
import org.springframework.web.bind.annotation.RequestBody;
|
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
|
||||||
import com.ruoyi.common.annotation.Log;
|
|
||||||
import com.ruoyi.common.core.controller.BaseController;
|
|
||||||
import com.ruoyi.common.core.domain.AjaxResult;
|
|
||||||
import com.ruoyi.common.enums.BusinessType;
|
|
||||||
import com.ruoyi.ai.vector.domain.KnowledgeFile;
|
|
||||||
import com.ruoyi.ai.vector.service.IKnowledgeFileService;
|
|
||||||
import com.ruoyi.common.utils.poi.ExcelUtil;
|
|
||||||
import com.ruoyi.common.core.page.TableDataInfo;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 知识库文件Controller
|
|
||||||
*
|
|
||||||
* @author ruoyi
|
|
||||||
* @date 2025-09-02
|
|
||||||
*/
|
|
||||||
@RestController
|
|
||||||
@RequestMapping("/api/fileVector")
|
|
||||||
public class KnowledgeFileController extends BaseController
|
|
||||||
{
|
|
||||||
@Autowired
|
|
||||||
private IKnowledgeFileService knowledgeFileService;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 查询知识库文件列表
|
|
||||||
*/
|
|
||||||
@PreAuthorize("@ss.hasPermi('api:fileVector:list')")
|
|
||||||
@GetMapping("/list")
|
|
||||||
public TableDataInfo list(KnowledgeFile knowledgeFile)
|
|
||||||
{
|
|
||||||
startPage();
|
|
||||||
List<KnowledgeFile> list = knowledgeFileService.selectKnowledgeFileList(knowledgeFile);
|
|
||||||
return getDataTable(list);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 导出知识库文件列表
|
|
||||||
*/
|
|
||||||
@PreAuthorize("@ss.hasPermi('api:fileVector:export')")
|
|
||||||
@Log(title = "知识库文件", businessType = BusinessType.EXPORT)
|
|
||||||
@PostMapping("/export")
|
|
||||||
public void export(HttpServletResponse response, KnowledgeFile knowledgeFile)
|
|
||||||
{
|
|
||||||
List<KnowledgeFile> list = knowledgeFileService.selectKnowledgeFileList(knowledgeFile);
|
|
||||||
ExcelUtil<KnowledgeFile> util = new ExcelUtil<KnowledgeFile>(KnowledgeFile.class);
|
|
||||||
util.exportExcel(response, list, "知识库文件数据");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取知识库文件详细信息
|
|
||||||
*/
|
|
||||||
@PreAuthorize("@ss.hasPermi('api:fileVector:query')")
|
|
||||||
@GetMapping(value = "/{id}")
|
|
||||||
public AjaxResult getInfo(@PathVariable("id") Long id)
|
|
||||||
{
|
|
||||||
return success(knowledgeFileService.selectKnowledgeFileById(id));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 新增知识库文件
|
|
||||||
*/
|
|
||||||
@PreAuthorize("@ss.hasPermi('api:fileVector:add')")
|
|
||||||
@Log(title = "知识库文件", businessType = BusinessType.INSERT)
|
|
||||||
@PostMapping
|
|
||||||
public AjaxResult add(@RequestBody KnowledgeFile knowledgeFile)
|
|
||||||
{
|
|
||||||
return toAjax(knowledgeFileService.insertKnowledgeFile(knowledgeFile));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 修改知识库文件
|
|
||||||
*/
|
|
||||||
@PreAuthorize("@ss.hasPermi('api:fileVector:edit')")
|
|
||||||
@Log(title = "知识库文件", businessType = BusinessType.UPDATE)
|
|
||||||
@PutMapping
|
|
||||||
public AjaxResult edit(@RequestBody KnowledgeFile knowledgeFile)
|
|
||||||
{
|
|
||||||
return toAjax(knowledgeFileService.updateKnowledgeFile(knowledgeFile));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 删除知识库文件
|
|
||||||
*/
|
|
||||||
@PreAuthorize("@ss.hasPermi('api:fileVector:remove')")
|
|
||||||
@Log(title = "知识库文件", businessType = BusinessType.DELETE)
|
|
||||||
@DeleteMapping("/{ids}")
|
|
||||||
public AjaxResult remove(@PathVariable Long[] ids)
|
|
||||||
{
|
|
||||||
return toAjax(knowledgeFileService.deleteKnowledgeFileByIds(ids));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,207 +0,0 @@
|
|||||||
package com.ruoyi.ai.vector.domain;
|
|
||||||
|
|
||||||
import java.util.Date;
|
|
||||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
|
||||||
import org.apache.commons.lang3.builder.ToStringBuilder;
|
|
||||||
import org.apache.commons.lang3.builder.ToStringStyle;
|
|
||||||
import com.ruoyi.common.annotation.Excel;
|
|
||||||
import com.ruoyi.common.core.domain.BaseEntity;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 知识库文件对象 knowledge_file
|
|
||||||
*
|
|
||||||
* @author ruoyi
|
|
||||||
* @date 2025-09-02
|
|
||||||
*/
|
|
||||||
public class KnowledgeFile extends BaseEntity
|
|
||||||
{
|
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
|
|
||||||
/** 文件唯一标识 */
|
|
||||||
private Long id;
|
|
||||||
|
|
||||||
/** 关联的知识库ID */
|
|
||||||
@Excel(name = "关联的知识库ID")
|
|
||||||
private Long knowledgeBaseId;
|
|
||||||
|
|
||||||
/** 文件名 */
|
|
||||||
@Excel(name = "文件名")
|
|
||||||
private String fileName;
|
|
||||||
|
|
||||||
/** 文件存储路径 */
|
|
||||||
@Excel(name = "文件存储路径")
|
|
||||||
private String filePath;
|
|
||||||
|
|
||||||
/** 文件大小,单位字节 */
|
|
||||||
@Excel(name = "文件大小,单位字节")
|
|
||||||
private Long fileSize;
|
|
||||||
|
|
||||||
/** 文件类型,如txt、pdf等 */
|
|
||||||
@Excel(name = "文件类型,如txt、pdf等")
|
|
||||||
private String fileType;
|
|
||||||
|
|
||||||
/** 文件描述 */
|
|
||||||
@Excel(name = "文件描述")
|
|
||||||
private String description;
|
|
||||||
|
|
||||||
/** 向量化 */
|
|
||||||
@Excel(name = "向量化")
|
|
||||||
private Long isVectorized;
|
|
||||||
|
|
||||||
/** 向量化完成时间 */
|
|
||||||
@JsonFormat(pattern = "yyyy-MM-dd")
|
|
||||||
@Excel(name = "向量化完成时间", width = 30, dateFormat = "yyyy-MM-dd")
|
|
||||||
private Date vectorizedTime;
|
|
||||||
|
|
||||||
/** 上传时间 */
|
|
||||||
@JsonFormat(pattern = "yyyy-MM-dd")
|
|
||||||
@Excel(name = "上传时间", width = 30, dateFormat = "yyyy-MM-dd")
|
|
||||||
private Date uploadTime;
|
|
||||||
|
|
||||||
/** 更新时间 */
|
|
||||||
@JsonFormat(pattern = "yyyy-MM-dd")
|
|
||||||
@Excel(name = "更新时间", width = 30, dateFormat = "yyyy-MM-dd")
|
|
||||||
private Date updatedAt;
|
|
||||||
|
|
||||||
/** 是否可用 */
|
|
||||||
@Excel(name = "是否可用")
|
|
||||||
private Long isDeleted;
|
|
||||||
|
|
||||||
public void setId(Long id)
|
|
||||||
{
|
|
||||||
this.id = id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Long getId()
|
|
||||||
{
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setKnowledgeBaseId(Long knowledgeBaseId)
|
|
||||||
{
|
|
||||||
this.knowledgeBaseId = knowledgeBaseId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Long getKnowledgeBaseId()
|
|
||||||
{
|
|
||||||
return knowledgeBaseId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setFileName(String fileName)
|
|
||||||
{
|
|
||||||
this.fileName = fileName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getFileName()
|
|
||||||
{
|
|
||||||
return fileName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setFilePath(String filePath)
|
|
||||||
{
|
|
||||||
this.filePath = filePath;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getFilePath()
|
|
||||||
{
|
|
||||||
return filePath;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setFileSize(Long fileSize)
|
|
||||||
{
|
|
||||||
this.fileSize = fileSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Long getFileSize()
|
|
||||||
{
|
|
||||||
return fileSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setFileType(String fileType)
|
|
||||||
{
|
|
||||||
this.fileType = fileType;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getFileType()
|
|
||||||
{
|
|
||||||
return fileType;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setDescription(String description)
|
|
||||||
{
|
|
||||||
this.description = description;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getDescription()
|
|
||||||
{
|
|
||||||
return description;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setIsVectorized(Long isVectorized)
|
|
||||||
{
|
|
||||||
this.isVectorized = isVectorized;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Long getIsVectorized()
|
|
||||||
{
|
|
||||||
return isVectorized;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setVectorizedTime(Date vectorizedTime)
|
|
||||||
{
|
|
||||||
this.vectorizedTime = vectorizedTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Date getVectorizedTime()
|
|
||||||
{
|
|
||||||
return vectorizedTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setUploadTime(Date uploadTime)
|
|
||||||
{
|
|
||||||
this.uploadTime = uploadTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Date getUploadTime()
|
|
||||||
{
|
|
||||||
return uploadTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setUpdatedAt(Date updatedAt)
|
|
||||||
{
|
|
||||||
this.updatedAt = updatedAt;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Date getUpdatedAt()
|
|
||||||
{
|
|
||||||
return updatedAt;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setIsDeleted(Long isDeleted)
|
|
||||||
{
|
|
||||||
this.isDeleted = isDeleted;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Long getIsDeleted()
|
|
||||||
{
|
|
||||||
return isDeleted;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
|
|
||||||
.append("id", getId())
|
|
||||||
.append("knowledgeBaseId", getKnowledgeBaseId())
|
|
||||||
.append("fileName", getFileName())
|
|
||||||
.append("filePath", getFilePath())
|
|
||||||
.append("fileSize", getFileSize())
|
|
||||||
.append("fileType", getFileType())
|
|
||||||
.append("description", getDescription())
|
|
||||||
.append("isVectorized", getIsVectorized())
|
|
||||||
.append("vectorizedTime", getVectorizedTime())
|
|
||||||
.append("uploadTime", getUploadTime())
|
|
||||||
.append("updatedAt", getUpdatedAt())
|
|
||||||
.append("isDeleted", getIsDeleted())
|
|
||||||
.toString();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,61 +0,0 @@
|
|||||||
package com.ruoyi.ai.vector.mapper;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import com.ruoyi.ai.vector.domain.KnowledgeFile;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 知识库文件Mapper接口
|
|
||||||
*
|
|
||||||
* @author ruoyi
|
|
||||||
* @date 2025-09-02
|
|
||||||
*/
|
|
||||||
public interface KnowledgeFileMapper
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* 查询知识库文件
|
|
||||||
*
|
|
||||||
* @param id 知识库文件主键
|
|
||||||
* @return 知识库文件
|
|
||||||
*/
|
|
||||||
public KnowledgeFile selectKnowledgeFileById(Long id);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 查询知识库文件列表
|
|
||||||
*
|
|
||||||
* @param knowledgeFile 知识库文件
|
|
||||||
* @return 知识库文件集合
|
|
||||||
*/
|
|
||||||
public List<KnowledgeFile> selectKnowledgeFileList(KnowledgeFile knowledgeFile);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 新增知识库文件
|
|
||||||
*
|
|
||||||
* @param knowledgeFile 知识库文件
|
|
||||||
* @return 结果
|
|
||||||
*/
|
|
||||||
public int insertKnowledgeFile(KnowledgeFile knowledgeFile);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 修改知识库文件
|
|
||||||
*
|
|
||||||
* @param knowledgeFile 知识库文件
|
|
||||||
* @return 结果
|
|
||||||
*/
|
|
||||||
public int updateKnowledgeFile(KnowledgeFile knowledgeFile);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 删除知识库文件
|
|
||||||
*
|
|
||||||
* @param id 知识库文件主键
|
|
||||||
* @return 结果
|
|
||||||
*/
|
|
||||||
public int deleteKnowledgeFileById(Long id);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 批量删除知识库文件
|
|
||||||
*
|
|
||||||
* @param ids 需要删除的数据主键集合
|
|
||||||
* @return 结果
|
|
||||||
*/
|
|
||||||
public int deleteKnowledgeFileByIds(Long[] ids);
|
|
||||||
}
|
|
||||||
@@ -1,147 +0,0 @@
|
|||||||
package com.ruoyi.ai.vector.service;
|
|
||||||
|
|
||||||
import com.ruoyi.common.core.domain.AjaxResult;
|
|
||||||
import org.springframework.ai.document.Document;
|
|
||||||
import org.springframework.ai.reader.ExtractedTextFormatter;
|
|
||||||
import org.springframework.ai.reader.JsonReader;
|
|
||||||
import org.springframework.ai.reader.TextReader;
|
|
||||||
import org.springframework.ai.reader.jsoup.JsoupDocumentReader;
|
|
||||||
import org.springframework.ai.reader.jsoup.config.JsoupDocumentReaderConfig;
|
|
||||||
import org.springframework.ai.reader.markdown.MarkdownDocumentReader;
|
|
||||||
import org.springframework.ai.reader.markdown.config.MarkdownDocumentReaderConfig;
|
|
||||||
import org.springframework.ai.reader.pdf.PagePdfDocumentReader;
|
|
||||||
import org.springframework.ai.reader.pdf.config.PdfDocumentReaderConfig;
|
|
||||||
import org.springframework.ai.reader.tika.TikaDocumentReader;
|
|
||||||
import org.springframework.ai.vectorstore.VectorStore;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.core.io.FileSystemResource;
|
|
||||||
import org.springframework.core.io.Resource;
|
|
||||||
import org.springframework.stereotype.Service;
|
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
@Service
|
|
||||||
public class DataVectorService {
|
|
||||||
|
|
||||||
@Autowired(required = false)
|
|
||||||
private VectorStore vectorStore;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 向量化文件
|
|
||||||
*
|
|
||||||
* @param file
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
public AjaxResult demo(MultipartFile file) {
|
|
||||||
String originalFilename = file.getOriginalFilename();
|
|
||||||
//取出文件后缀
|
|
||||||
String suffix = originalFilename.substring(originalFilename.lastIndexOf(".") + 1);
|
|
||||||
Resource resource = file.getResource();
|
|
||||||
List<Document> list;
|
|
||||||
switch (suffix) {
|
|
||||||
case "json":
|
|
||||||
|
|
||||||
list = readJson(resource);
|
|
||||||
break;
|
|
||||||
case "txt":
|
|
||||||
//整个文本
|
|
||||||
list = readTxt(resource);
|
|
||||||
//文本拆分
|
|
||||||
break;
|
|
||||||
case "html":
|
|
||||||
list = readHtml(resource);
|
|
||||||
break;
|
|
||||||
case "md":
|
|
||||||
list = readMd(resource);
|
|
||||||
break;
|
|
||||||
case "pdf":
|
|
||||||
//页面
|
|
||||||
list = readPdf(resource);
|
|
||||||
|
|
||||||
//段落
|
|
||||||
|
|
||||||
break;
|
|
||||||
case "doc":
|
|
||||||
case "docx":
|
|
||||||
list = readDoc(resource);
|
|
||||||
break;
|
|
||||||
case "ppt":
|
|
||||||
case "pptx":
|
|
||||||
list = readPpt(resource);
|
|
||||||
break;
|
|
||||||
|
|
||||||
|
|
||||||
default:
|
|
||||||
return AjaxResult.error("不支持的文件格式");
|
|
||||||
}
|
|
||||||
// 3.写入向量库
|
|
||||||
vectorStore.add(list);
|
|
||||||
return AjaxResult.success();
|
|
||||||
}
|
|
||||||
|
|
||||||
private List<Document> readPpt(Resource resource) {
|
|
||||||
TikaDocumentReader tikaDocumentReader = new TikaDocumentReader(resource);
|
|
||||||
return tikaDocumentReader.read();
|
|
||||||
}
|
|
||||||
|
|
||||||
private List<Document> readDoc(Resource resource) {
|
|
||||||
TikaDocumentReader tikaDocumentReader = new TikaDocumentReader(resource);
|
|
||||||
return tikaDocumentReader.read();
|
|
||||||
}
|
|
||||||
|
|
||||||
private List<Document> readMd(Resource resource) {
|
|
||||||
MarkdownDocumentReaderConfig config = MarkdownDocumentReaderConfig.builder()
|
|
||||||
.withHorizontalRuleCreateDocument(true)
|
|
||||||
.withIncludeCodeBlock(false)
|
|
||||||
.withIncludeBlockquote(false)
|
|
||||||
.withAdditionalMetadata("filename", "code.md")
|
|
||||||
.build();
|
|
||||||
|
|
||||||
MarkdownDocumentReader reader = new MarkdownDocumentReader(resource, config);
|
|
||||||
return reader.read();
|
|
||||||
}
|
|
||||||
|
|
||||||
private List<Document> readHtml(Resource resource) {
|
|
||||||
JsoupDocumentReaderConfig config = JsoupDocumentReaderConfig.builder()
|
|
||||||
.selector("article p") // Extract paragraphs within <article> tags
|
|
||||||
.charset("ISO-8859-1") // Use ISO-8859-1 encoding
|
|
||||||
.includeLinkUrls(true) // Include link URLs in metadata
|
|
||||||
.metadataTags(List.of("author", "date")) // Extract author and date meta tags
|
|
||||||
.additionalMetadata("source", "my-page.html") // Add custom metadata
|
|
||||||
.build();
|
|
||||||
|
|
||||||
JsoupDocumentReader reader = new JsoupDocumentReader(resource, config);
|
|
||||||
return reader.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
private List<Document> readTxt(Resource resource) {
|
|
||||||
TextReader textReader = new TextReader(resource);
|
|
||||||
textReader.getCustomMetadata().put("filename", "text-source.txt");
|
|
||||||
|
|
||||||
return textReader.read();
|
|
||||||
}
|
|
||||||
|
|
||||||
private List<Document> readJson(Resource resource) {
|
|
||||||
JsonReader jsonReader = new JsonReader(resource, "description", "content");
|
|
||||||
return jsonReader.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
private List<Document> readPdf(Resource resource) {
|
|
||||||
// 1.创建PDF的读取器
|
|
||||||
PagePdfDocumentReader reader = new PagePdfDocumentReader(
|
|
||||||
resource, // 文件源
|
|
||||||
PdfDocumentReaderConfig.builder()
|
|
||||||
.withPageExtractedTextFormatter(ExtractedTextFormatter.defaults())
|
|
||||||
.withPagesPerDocument(1) // 每1页PDF作为一个Document
|
|
||||||
.build()
|
|
||||||
);
|
|
||||||
// 2.读取PDF文档,拆分为Document
|
|
||||||
return reader.read();
|
|
||||||
}
|
|
||||||
|
|
||||||
public AjaxResult searchDemo(String message) {
|
|
||||||
List<Document> documents = vectorStore.similaritySearch(message);
|
|
||||||
return AjaxResult.success(documents);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,61 +0,0 @@
|
|||||||
package com.ruoyi.ai.vector.service;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import com.ruoyi.ai.vector.domain.KnowledgeFile;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 知识库文件Service接口
|
|
||||||
*
|
|
||||||
* @author ruoyi
|
|
||||||
* @date 2025-09-02
|
|
||||||
*/
|
|
||||||
public interface IKnowledgeFileService
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* 查询知识库文件
|
|
||||||
*
|
|
||||||
* @param id 知识库文件主键
|
|
||||||
* @return 知识库文件
|
|
||||||
*/
|
|
||||||
public KnowledgeFile selectKnowledgeFileById(Long id);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 查询知识库文件列表
|
|
||||||
*
|
|
||||||
* @param knowledgeFile 知识库文件
|
|
||||||
* @return 知识库文件集合
|
|
||||||
*/
|
|
||||||
public List<KnowledgeFile> selectKnowledgeFileList(KnowledgeFile knowledgeFile);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 新增知识库文件
|
|
||||||
*
|
|
||||||
* @param knowledgeFile 知识库文件
|
|
||||||
* @return 结果
|
|
||||||
*/
|
|
||||||
public int insertKnowledgeFile(KnowledgeFile knowledgeFile);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 修改知识库文件
|
|
||||||
*
|
|
||||||
* @param knowledgeFile 知识库文件
|
|
||||||
* @return 结果
|
|
||||||
*/
|
|
||||||
public int updateKnowledgeFile(KnowledgeFile knowledgeFile);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 批量删除知识库文件
|
|
||||||
*
|
|
||||||
* @param ids 需要删除的知识库文件主键集合
|
|
||||||
* @return 结果
|
|
||||||
*/
|
|
||||||
public int deleteKnowledgeFileByIds(Long[] ids);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 删除知识库文件信息
|
|
||||||
*
|
|
||||||
* @param id 知识库文件主键
|
|
||||||
* @return 结果
|
|
||||||
*/
|
|
||||||
public int deleteKnowledgeFileById(Long id);
|
|
||||||
}
|
|
||||||
@@ -1,93 +0,0 @@
|
|||||||
package com.ruoyi.ai.vector.service.impl;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.stereotype.Service;
|
|
||||||
import com.ruoyi.ai.vector.mapper.KnowledgeFileMapper;
|
|
||||||
import com.ruoyi.ai.vector.domain.KnowledgeFile;
|
|
||||||
import com.ruoyi.ai.vector.service.IKnowledgeFileService;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 知识库文件Service业务层处理
|
|
||||||
*
|
|
||||||
* @author ruoyi
|
|
||||||
* @date 2025-09-02
|
|
||||||
*/
|
|
||||||
@Service
|
|
||||||
public class KnowledgeFileServiceImpl implements IKnowledgeFileService
|
|
||||||
{
|
|
||||||
@Autowired
|
|
||||||
private KnowledgeFileMapper knowledgeFileMapper;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 查询知识库文件
|
|
||||||
*
|
|
||||||
* @param id 知识库文件主键
|
|
||||||
* @return 知识库文件
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public KnowledgeFile selectKnowledgeFileById(Long id)
|
|
||||||
{
|
|
||||||
return knowledgeFileMapper.selectKnowledgeFileById(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 查询知识库文件列表
|
|
||||||
*
|
|
||||||
* @param knowledgeFile 知识库文件
|
|
||||||
* @return 知识库文件
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public List<KnowledgeFile> selectKnowledgeFileList(KnowledgeFile knowledgeFile)
|
|
||||||
{
|
|
||||||
return knowledgeFileMapper.selectKnowledgeFileList(knowledgeFile);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 新增知识库文件
|
|
||||||
*
|
|
||||||
* @param knowledgeFile 知识库文件
|
|
||||||
* @return 结果
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public int insertKnowledgeFile(KnowledgeFile knowledgeFile)
|
|
||||||
{
|
|
||||||
return knowledgeFileMapper.insertKnowledgeFile(knowledgeFile);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 修改知识库文件
|
|
||||||
*
|
|
||||||
* @param knowledgeFile 知识库文件
|
|
||||||
* @return 结果
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public int updateKnowledgeFile(KnowledgeFile knowledgeFile)
|
|
||||||
{
|
|
||||||
return knowledgeFileMapper.updateKnowledgeFile(knowledgeFile);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 批量删除知识库文件
|
|
||||||
*
|
|
||||||
* @param ids 需要删除的知识库文件主键
|
|
||||||
* @return 结果
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public int deleteKnowledgeFileByIds(Long[] ids)
|
|
||||||
{
|
|
||||||
return knowledgeFileMapper.deleteKnowledgeFileByIds(ids);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 删除知识库文件信息
|
|
||||||
*
|
|
||||||
* @param id 知识库文件主键
|
|
||||||
* @return 结果
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public int deleteKnowledgeFileById(Long id)
|
|
||||||
{
|
|
||||||
return knowledgeFileMapper.deleteKnowledgeFileById(id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -369,6 +369,7 @@ public class ToWcsServiceImpl implements IToWcsService {
|
|||||||
MydoJob mydoJob = mydoJobService.selectMydoJobByJobId(reMaterialParam.getJobId());
|
MydoJob mydoJob = mydoJobService.selectMydoJobByJobId(reMaterialParam.getJobId());
|
||||||
mydoJob.setClassId("取货无货");
|
mydoJob.setClassId("取货无货");
|
||||||
mydoJobService.updateMydoJob(mydoJob);
|
mydoJobService.updateMydoJob(mydoJob);
|
||||||
|
|
||||||
return AjaxResult.success();
|
return AjaxResult.success();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -548,13 +548,11 @@ public class MydoJobServiceImpl implements IMydoJobService {
|
|||||||
log.error("任务不存在");
|
log.error("任务不存在");
|
||||||
return AjaxResult.error(jobId+"任务不存在");
|
return AjaxResult.error(jobId+"任务不存在");
|
||||||
}
|
}
|
||||||
if ("3".equals(job.getStatus())){
|
if ("1".equals(job.getStatus()) || "2".equals(job.getStatus())){
|
||||||
AjaxResult ajaxResult = iToWcsService.cancelTaskByTaskNo(job);
|
AjaxResult ajaxResult = iToWcsService.cancelTaskByTaskNo(job);
|
||||||
if(!ajaxResult.isSuccess()){
|
if(!ajaxResult.isSuccess()){
|
||||||
return AjaxResult.error(jobId+"任务取消失败");
|
return AjaxResult.error(jobId+"任务取消失败");
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if ("1".equals(job.getStatus()) || "3".equals(job.getStatus())){
|
|
||||||
MydoJobDetail mydoJobDetail = new MydoJobDetail();
|
MydoJobDetail mydoJobDetail = new MydoJobDetail();
|
||||||
mydoJobDetail.setJobId(jobId);
|
mydoJobDetail.setJobId(jobId);
|
||||||
List<MydoJobDetail> mydoJobDetails = mydoJobDetailService.selectMydoJobDetailList(mydoJobDetail);
|
List<MydoJobDetail> mydoJobDetails = mydoJobDetailService.selectMydoJobDetailList(mydoJobDetail);
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ spring:
|
|||||||
druid:
|
druid:
|
||||||
# 主库数据源
|
# 主库数据源
|
||||||
master:
|
master:
|
||||||
url: jdbc:sqlserver://127.0.0.1:1433;databaseName=FT541-wms;encrypt=true;trustServerCertificate=true;
|
url: jdbc:sqlserver://172.19.1.119:1433;databaseName=FT541-wms;encrypt=true;trustServerCertificate=true;
|
||||||
username: sa
|
username: sa
|
||||||
password: Flrd0914.
|
password: Flrd0914.
|
||||||
# 从库数据源
|
# 从库数据源
|
||||||
|
|||||||
@@ -71,7 +71,7 @@ spring:
|
|||||||
# redis 配置
|
# redis 配置
|
||||||
redis:
|
redis:
|
||||||
# 地址
|
# 地址
|
||||||
host: 127.0.0.1
|
host: 172.19.1.119
|
||||||
# 端口,默认为6379
|
# 端口,默认为6379
|
||||||
port: 6379
|
port: 6379
|
||||||
# 数据库索引
|
# 数据库索引
|
||||||
@@ -91,40 +91,6 @@ spring:
|
|||||||
# #连接池最大阻塞等待时间(使用负值表示没有限制)
|
# #连接池最大阻塞等待时间(使用负值表示没有限制)
|
||||||
max-wait: -1ms
|
max-wait: -1ms
|
||||||
|
|
||||||
ai:
|
|
||||||
enable: false
|
|
||||||
openai:
|
|
||||||
api-key: sk-dzftrybcpjujsjgehjgtsjzjuhqxciosldcncjtlazxvjams # 密钥key
|
|
||||||
base-url: https://api.siliconflow.cn # 产商地址
|
|
||||||
#对话模型
|
|
||||||
chat:
|
|
||||||
options:
|
|
||||||
model: deepseek-ai/DeepSeek-V3.1 # 大模型名称
|
|
||||||
embedding:
|
|
||||||
options:
|
|
||||||
model: Qwen/Qwen3-Embedding-8B
|
|
||||||
dimensions: 1024
|
|
||||||
#MCP
|
|
||||||
# mcp:
|
|
||||||
# client:
|
|
||||||
# toolcallback:
|
|
||||||
# enabled: true
|
|
||||||
# name: mcp-client
|
|
||||||
# stdio:
|
|
||||||
# servers-configuration: classpath:/mcp-server-config.json # MCP服务配置
|
|
||||||
# enabled: true
|
|
||||||
# type: ASYNC
|
|
||||||
# sse:
|
|
||||||
# connections:
|
|
||||||
# author-info-server:
|
|
||||||
# url: http://localhost:9090
|
|
||||||
#向量数据库
|
|
||||||
vectorstore:
|
|
||||||
mariadb:
|
|
||||||
initialize-schema: true
|
|
||||||
distance-type: COSINE
|
|
||||||
dimensions: 1024
|
|
||||||
|
|
||||||
|
|
||||||
# token配置
|
# token配置
|
||||||
token:
|
token:
|
||||||
@@ -177,4 +143,4 @@ xss:
|
|||||||
|
|
||||||
|
|
||||||
license:
|
license:
|
||||||
enabled: true
|
enabled: false
|
||||||
|
|||||||
@@ -102,8 +102,8 @@ export default {
|
|||||||
return {
|
return {
|
||||||
codeUrl: "",
|
codeUrl: "",
|
||||||
loginForm: {
|
loginForm: {
|
||||||
username: "admin",
|
username: "",
|
||||||
password: "admin123",
|
password: "",
|
||||||
rememberMe: false,
|
rememberMe: false,
|
||||||
code: "",
|
code: "",
|
||||||
uuid: ""
|
uuid: ""
|
||||||
|
|||||||
@@ -131,7 +131,7 @@
|
|||||||
<!-- 排序 -->
|
<!-- 排序 -->
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item label="排序" prop="orderNum">
|
<el-form-item label="排序" prop="orderNum">
|
||||||
<el-input-number v-model="form.orderNum" controls-position="right" :min="0" />
|
<el-input v-model.number="form.orderNum" placeholder="请输入排序" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
@@ -143,7 +143,7 @@
|
|||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<!-- 联系电话 -->
|
<!-- 联系电话 -->
|
||||||
<el-col :span="12">
|
<el-col :span="12">ev
|
||||||
<el-form-item label="联系电话" prop="phone">
|
<el-form-item label="联系电话" prop="phone">
|
||||||
<el-input v-model="form.phone" placeholder="请输入联系电话" maxlength="11" />
|
<el-input v-model="form.phone" placeholder="请输入联系电话" maxlength="11" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|||||||
Reference in New Issue
Block a user