Browse Source

智能体上传文件

lamphua 1 week ago
parent
commit
6463daafd7

+ 23
- 0
llm-back/ruoyi-llm/src/main/java/com/ruoyi/web/llm/controller/CmcAgentController.java View File

@@ -1,7 +1,9 @@
1 1
 package com.ruoyi.web.llm.controller;
2 2
 
3
+import java.io.IOException;
3 4
 import java.util.List;
4 5
 import javax.servlet.http.HttpServletResponse;
6
+
5 7
 import org.springframework.beans.factory.annotation.Autowired;
6 8
 import org.springframework.web.bind.annotation.GetMapping;
7 9
 import org.springframework.web.bind.annotation.PostMapping;
@@ -19,6 +21,7 @@ import com.ruoyi.llm.domain.CmcAgent;
19 21
 import com.ruoyi.llm.service.ICmcAgentService;
20 22
 import com.ruoyi.common.utils.poi.ExcelUtil;
21 23
 import com.ruoyi.common.core.page.TableDataInfo;
24
+import org.springframework.web.multipart.MultipartFile;
22 25
 
23 26
 /**
24 27
  * 智能体Controller
@@ -65,6 +68,26 @@ public class CmcAgentController extends BaseController
65 68
         return success(cmcAgentService.selectCmcAgentByAgentId(agentId));
66 69
     }
67 70
 
71
+    /**
72
+     * 上传单文件
73
+     * @return
74
+     */
75
+    @PostMapping("/upload")
76
+    public AjaxResult upload(MultipartFile file, String agentName) throws IOException
77
+    {
78
+        return success(cmcAgentService.uploadDocument(file, agentName));
79
+    }
80
+
81
+    /**
82
+     * 上传多文件
83
+     * @return
84
+     */
85
+    @PostMapping("/uploadList")
86
+    public AjaxResult uploadList(MultipartFile[] fileList, String agentName) throws IOException
87
+    {
88
+        return success(cmcAgentService.uploadDocumentList(fileList, agentName));
89
+    }
90
+
68 91
     /**
69 92
      * 新增智能体
70 93
      */

+ 5
- 23
llm-back/ruoyi-llm/src/main/java/com/ruoyi/web/llm/controller/CmcDocumentController.java View File

@@ -9,6 +9,7 @@ import javax.servlet.http.HttpServletResponse;
9 9
 import com.alibaba.fastjson2.JSONObject;
10 10
 import com.ruoyi.common.config.RuoYiConfig;
11 11
 import com.ruoyi.common.utils.SnowFlake;
12
+import com.ruoyi.llm.domain.CmcChat;
12 13
 import org.springframework.beans.factory.annotation.Autowired;
13 14
 import org.springframework.web.bind.annotation.GetMapping;
14 15
 import org.springframework.web.bind.annotation.PostMapping;
@@ -77,29 +78,10 @@ public class CmcDocumentController extends BaseController
77 78
      * 上传外部文件
78 79
      * @return
79 80
      */
80
-    @GetMapping("/upload")
81
-    public JSONObject upload(MultipartFile[] fileList) throws IOException {
82
-        File profilePath = new File( RuoYiConfig.getProfile() + "/upload/rag/document" );
83
-        if (!profilePath.exists())
84
-            profilePath.mkdirs();
85
-        String chatId = new SnowFlake().generateId();
86
-        JSONObject jsonObject = new JSONObject();
87
-        jsonObject.put("chatId", chatId);
88
-        List<String> filenames = new ArrayList<>();
89
-        for (MultipartFile file : fileList) {
90
-            File transferFile = new File(profilePath + File.separator + file.getOriginalFilename());
91
-            if (!transferFile.exists()) {
92
-                file.transferTo(transferFile);
93
-            }
94
-            CmcDocument cmcDocument = new CmcDocument();
95
-            cmcDocument.setDocumentId(new SnowFlake().generateId());
96
-            cmcDocument.setChatId(chatId);
97
-            cmcDocument.setPath(file.getOriginalFilename());
98
-            cmcDocumentService.insertCmcDocument(cmcDocument);
99
-            filenames.add(file.getOriginalFilename());
100
-        }
101
-        jsonObject.put("filenames", filenames);
102
-        return jsonObject;
81
+    @PostMapping("/upload")
82
+    public AjaxResult upload(MultipartFile[] fileList) throws IOException
83
+    {
84
+        return success(cmcDocumentService.uploadDocument(fileList));
103 85
     }
104 86
 
105 87
     /**

+ 1
- 4
llm-back/ruoyi-llm/src/main/java/com/ruoyi/web/llm/controller/McpController.java View File

@@ -46,7 +46,6 @@ public class McpController extends BaseController
46 46
         ChatModel chatModel = ChatModel.of("http://192.168.28.188:8000/v1/chat/completions")
47 47
                 .provider("openai")
48 48
                 .model("Qwen2.5-1.5B-Instruct")
49
-                .apiKey("1")
50 49
                 .defaultToolsAdd(clientProvider)
51 50
                 .build();
52 51
         ChatResponse response = chatModel.prompt(question).call();
@@ -106,16 +105,14 @@ public class McpController extends BaseController
106 105
         ChatModel chatModel = ChatModel.of("http://192.168.28.188:8000/v1/chat/completions")
107 106
                 .provider("openai")
108 107
                 .model("DeepSeek-R1-Distill-Qwen-1.5B")
109
-                .apiKey("1")
110 108
                 .defaultToolsAdd(clientProvider)
111 109
                 .build();
112 110
         File profilePath = new File( RuoYiConfig.getProfile() + "/upload/knowledge");
113 111
         if (!profilePath.exists())
114 112
             profilePath.mkdirs();
115 113
         File transferFile = new File( profilePath + File.separator + file.getOriginalFilename());
116
-        if (!transferFile.exists()) {
114
+        if (!transferFile.exists())
117 115
             file.transferTo(transferFile);
118
-        }
119 116
         Map<String,Object> path = new HashMap<>();
120 117
         path.put("document", transferFile.getPath());
121 118
         String content = clientProvider.callToolAsText("openDocument", path).getContent();

+ 2
- 2
llm-back/ruoyi-llm/src/main/java/com/ruoyi/web/llm/controller/SessionController.java View File

@@ -40,9 +40,9 @@ public class SessionController extends BaseController
40 40
      * 调用LLM+RAG(外部文件)生成回答
41 41
      */
42 42
     @GetMapping("/answerWithDocument")
43
-    public Flux<AssistantMessage> answerWithDocument(String chatId, String question) throws IOException
43
+    public Flux<AssistantMessage> answerWithDocument(String topicId, String chatId, String question) throws IOException
44 44
     {
45
-        return langChainMilvusService.generateAnswerWithDocument(embeddingModel, chatId, question, "http://192.168.28.188:8000/v1/chat/completions");
45
+        return langChainMilvusService.generateAnswerWithDocument(embeddingModel, topicId, chatId, question, "http://192.168.28.188:8000/v1/chat/completions");
46 46
     }
47 47
 
48 48
 }

+ 1
- 1
llm-back/ruoyi-llm/src/main/java/com/ruoyi/web/llm/service/ILangChainMilvusService.java View File

@@ -47,6 +47,6 @@ public interface ILangChainMilvusService {
47 47
      * 调用LLM+RAG(外部文件)生成回答
48 48
      * @return
49 49
      */
50
-    public Flux<AssistantMessage> generateAnswerWithDocument(EmbeddingModel embeddingModel, String chatId, String question, String llmServiceUrl) throws IOException;
50
+    public Flux<AssistantMessage> generateAnswerWithDocument(EmbeddingModel embeddingModel, String topicId, String chatId, String question, String llmServiceUrl) throws IOException;
51 51
 
52 52
 }

+ 2
- 5
llm-back/ruoyi-llm/src/main/java/com/ruoyi/web/llm/service/impl/LangChainMilvusServiceImpl.java View File

@@ -63,9 +63,8 @@ public class LangChainMilvusServiceImpl implements ILangChainMilvusService
63 63
         if (!profilePath.exists())
64 64
             profilePath.mkdirs();
65 65
         File transferFile = new File( profilePath + File.separator + file.getOriginalFilename());
66
-        if (!transferFile.exists()) {
66
+        if (!transferFile.exists())
67 67
             file.transferTo(transferFile);
68
-        }
69 68
         List<TextSegment> segments = splitDocument(file.getOriginalFilename(), transferFile);
70 69
 
71 70
         // 提取文本和生成嵌入
@@ -148,7 +147,6 @@ public class LangChainMilvusServiceImpl implements ILangChainMilvusService
148 147
         ChatModel chatModel = ChatModel.of(llmServiceUrl)
149 148
                 .provider("openai")
150 149
                 .model("Qwen2.5-1.5B-Instruct")
151
-                .apiKey("1")
152 150
                 .build();
153 151
 
154 152
         if (topicId != null) {
@@ -191,8 +189,7 @@ public class LangChainMilvusServiceImpl implements ILangChainMilvusService
191 189
      * 调用LLM生成回答
192 190
      */
193 191
     @Override
194
-    public Flux<AssistantMessage> generateAnswerWithDocument(EmbeddingModel embeddingModel, String chatId, String question, String llmServiceUrl) throws IOException {
195
-        String topicId = cmcChatService.selectCmcChatByChatId(chatId).getTopicId();
192
+    public Flux<AssistantMessage> generateAnswerWithDocument(EmbeddingModel embeddingModel, String topicId, String chatId, String question, String llmServiceUrl) throws IOException {
196 193
         CmcDocument cmcDocument = new CmcDocument();
197 194
         cmcDocument.setChatId(chatId);
198 195
         List<CmcDocument> documentList = cmcDocumentService.selectCmcDocumentList(cmcDocument);

+ 20
- 0
llm-back/ruoyi-system/src/main/java/com/ruoyi/llm/service/ICmcAgentService.java View File

@@ -1,7 +1,11 @@
1 1
 package com.ruoyi.llm.service;
2 2
 
3
+import java.io.IOException;
3 4
 import java.util.List;
5
+
6
+import com.alibaba.fastjson2.JSONObject;
4 7
 import com.ruoyi.llm.domain.CmcAgent;
8
+import org.springframework.web.multipart.MultipartFile;
5 9
 
6 10
 /**
7 11
  * 智能体Service接口
@@ -27,6 +31,22 @@ public interface ICmcAgentService
27 31
      */
28 32
     public List<CmcAgent> selectCmcAgentList(CmcAgent cmcAgent);
29 33
 
34
+    /**
35
+     * 上传单文件
36
+     *
37
+     * @param file 文件
38
+     * @return 结果
39
+     */
40
+    public String uploadDocument(MultipartFile file, String agentName) throws IOException;
41
+
42
+    /**
43
+     * 上传多文件
44
+     *
45
+     * @param fileList 文件
46
+     * @return 结果
47
+     */
48
+    public String uploadDocumentList(MultipartFile[] fileList, String agentName) throws IOException;
49
+
30 50
     /**
31 51
      * 新增智能体
32 52
      * 

+ 12
- 0
llm-back/ruoyi-system/src/main/java/com/ruoyi/llm/service/ICmcDocumentService.java View File

@@ -1,7 +1,11 @@
1 1
 package com.ruoyi.llm.service;
2 2
 
3
+import java.io.IOException;
3 4
 import java.util.List;
5
+
6
+import com.alibaba.fastjson2.JSONObject;
4 7
 import com.ruoyi.llm.domain.CmcDocument;
8
+import org.springframework.web.multipart.MultipartFile;
5 9
 
6 10
 /**
7 11
  * cmc聊天附件Service接口
@@ -27,6 +31,14 @@ public interface ICmcDocumentService
27 31
      */
28 32
     public List<CmcDocument> selectCmcDocumentList(CmcDocument cmcDocument);
29 33
 
34
+    /**
35
+     * 上传外部文件
36
+     *
37
+     * @param fileList 文件
38
+     * @return 结果
39
+     */
40
+    public JSONObject uploadDocument(MultipartFile[] fileList) throws IOException;
41
+
30 42
     /**
31 43
      * 新增cmc聊天附件
32 44
      * 

+ 42
- 0
llm-back/ruoyi-system/src/main/java/com/ruoyi/llm/service/impl/CmcAgentServiceImpl.java View File

@@ -1,12 +1,17 @@
1 1
 package com.ruoyi.llm.service.impl;
2 2
 
3
+import java.io.File;
4
+import java.io.IOException;
3 5
 import java.util.List;
6
+
7
+import com.ruoyi.common.config.RuoYiConfig;
4 8
 import com.ruoyi.common.utils.DateUtils;
5 9
 import org.springframework.beans.factory.annotation.Autowired;
6 10
 import org.springframework.stereotype.Service;
7 11
 import com.ruoyi.llm.mapper.CmcAgentMapper;
8 12
 import com.ruoyi.llm.domain.CmcAgent;
9 13
 import com.ruoyi.llm.service.ICmcAgentService;
14
+import org.springframework.web.multipart.MultipartFile;
10 15
 
11 16
 /**
12 17
  * 智能体Service业务层处理
@@ -44,6 +49,43 @@ public class CmcAgentServiceImpl implements ICmcAgentService
44 49
         return cmcAgentMapper.selectCmcAgentList(cmcAgent);
45 50
     }
46 51
 
52
+    /**
53
+     * 上传单文件
54
+     *
55
+     * @param file 文件
56
+     * @return 结果
57
+     */
58
+    @Override
59
+    public String uploadDocument(MultipartFile file, String agentName) throws IOException {
60
+        File profilePath = new File( RuoYiConfig.getProfile() + "/upload/agent/" + agentName);
61
+        if (!profilePath.exists())
62
+            profilePath.mkdirs();
63
+        File transferFile = new File(profilePath + File.separator + file.getOriginalFilename());
64
+        if (!transferFile.exists())
65
+            file.transferTo(transferFile);
66
+        String[] filenameSplit = file.getOriginalFilename().split("\\.");
67
+        return "/upload/agent/" + agentName + File.separator + file.getOriginalFilename().replace(filenameSplit[filenameSplit.length - 2], filenameSplit[filenameSplit.length - 2] + "_" + agentName);
68
+    }
69
+
70
+    /**
71
+     * 上传多文件
72
+     *
73
+     * @param fileList 文件
74
+     * @return 结果
75
+     */
76
+    @Override
77
+    public String uploadDocumentList(MultipartFile[] fileList, String agentName) throws IOException {
78
+        File profilePath = new File( RuoYiConfig.getProfile() + "/upload/agent/" + agentName);
79
+        if (!profilePath.exists())
80
+            profilePath.mkdirs();
81
+        for (MultipartFile file : fileList) {
82
+            File transferFile = new File(profilePath + File.separator + file.getOriginalFilename());
83
+            if (!transferFile.exists())
84
+                file.transferTo(transferFile);
85
+        }
86
+        return "上传成功";
87
+    }
88
+
47 89
     /**
48 90
      * 新增智能体
49 91
      * 

+ 34
- 0
llm-back/ruoyi-system/src/main/java/com/ruoyi/llm/service/impl/CmcDocumentServiceImpl.java View File

@@ -1,11 +1,18 @@
1 1
 package com.ruoyi.llm.service.impl;
2 2
 
3
+import java.io.File;
4
+import java.io.IOException;
3 5
 import java.util.List;
6
+
7
+import com.alibaba.fastjson2.JSONObject;
8
+import com.ruoyi.common.config.RuoYiConfig;
9
+import com.ruoyi.common.utils.SnowFlake;
4 10
 import org.springframework.beans.factory.annotation.Autowired;
5 11
 import org.springframework.stereotype.Service;
6 12
 import com.ruoyi.llm.mapper.CmcDocumentMapper;
7 13
 import com.ruoyi.llm.domain.CmcDocument;
8 14
 import com.ruoyi.llm.service.ICmcDocumentService;
15
+import org.springframework.web.multipart.MultipartFile;
9 16
 
10 17
 /**
11 18
  * cmc聊天附件Service业务层处理
@@ -55,6 +62,33 @@ public class CmcDocumentServiceImpl implements ICmcDocumentService
55 62
         return cmcDocumentMapper.insertCmcDocument(cmcDocument);
56 63
     }
57 64
 
65
+    /**
66
+     * 上传外部文件
67
+     *
68
+     * @param fileList 文件
69
+     * @return 结果
70
+     */
71
+    @Override
72
+    public JSONObject uploadDocument(MultipartFile[] fileList) throws IOException {
73
+        File profilePath = new File( RuoYiConfig.getProfile() + "/upload/rag/document" );
74
+        if (!profilePath.exists())
75
+            profilePath.mkdirs();
76
+        String chatId = new SnowFlake().generateId();
77
+        JSONObject jsonObject = new JSONObject();
78
+        jsonObject.put("chatId", chatId);
79
+        for (MultipartFile file : fileList) {
80
+            File transferFile = new File(profilePath + File.separator + file.getOriginalFilename());
81
+            if (!transferFile.exists())
82
+                file.transferTo(transferFile);
83
+            CmcDocument cmcDocument = new CmcDocument();
84
+            cmcDocument.setDocumentId(new SnowFlake().generateId());
85
+            cmcDocument.setChatId(chatId);
86
+            cmcDocument.setPath(file.getOriginalFilename());
87
+            cmcDocumentMapper.insertCmcDocument(cmcDocument);
88
+        }
89
+        return jsonObject;
90
+    }
91
+
58 92
     /**
59 93
      * 修改cmc聊天附件
60 94
      * 

+ 7
- 7
llm-ui/src/views/llm/chat/index.vue View File

@@ -1,8 +1,8 @@
1 1
 <!--
2 2
  * @Author: ysh
3 3
  * @Date: 2025-04-07 14:14:05
4
- * @LastEditors: Please set LastEditors
5
- * @LastEditTime: 2025-07-22 16:07:39
4
+ * @LastEditors: wrh
5
+ * @LastEditTime: 2025-07-22 17:44:45
6 6
 -->
7 7
 <template>
8 8
   <div class="app-container">
@@ -321,7 +321,7 @@ const showNewChatWelcome = ref(false);
321 321
 const fileInput = ref(null);
322 322
 const selectedFiles = ref([]);
323 323
 const isUploading = ref(false);
324
-const documentChartId = ref('');
324
+const documentChatId = ref('');
325 325
 const messageFileMap = ref(new Map()); // 存储消息对应的文件列表,key为chartId
326 326
 
327 327
 const classifiedRecent = ref({
@@ -466,7 +466,7 @@ const sendMessage = async () => {
466 466
     input: inputMessage.value,
467 467
     topicId: currentTopicId.value,
468 468
     inputTime: proxy.parseTime(new Date(), '{y}-{m}-{d}'),
469
-    chatId: documentChartId.value || null
469
+    chatId: documentChatId.value || null
470 470
   };
471 471
 
472 472
   // 添加用户消息到聊天记录
@@ -475,10 +475,10 @@ const sendMessage = async () => {
475 475
   inputMessage.value = '';
476 476
 
477 477
   // 暂存文件上传ID,用于后续查询
478
-  const uploadedFileId = documentChartId.value;
478
+  const uploadedFileId = documentChatId.value;
479 479
 
480 480
   // 清空文档chartId,确保每次上传只对下一条消息有效
481
-  documentChartId.value = '';
481
+  documentChatId.value = '';
482 482
 
483 483
   // 清空已上传的文件列表
484 484
   selectedFiles.value = [];
@@ -590,7 +590,7 @@ const handleFileSelect = async (event) => {
590 590
     try {
591 591
       isUploading.value = true;
592 592
       let res = await uploadDocument(files);
593
-      documentChartId.value = res.chatId;
593
+      documentChatId.value = res.data.chatId;
594 594
       // 上传成功后,将文件添加到已上传列表
595 595
       selectedFiles.value = [...selectedFiles.value, ...files];
596 596
       ElMessage.success(`成功上传 ${files.length} 个文件`);

Loading…
Cancel
Save