作者 dong

资料管理界面后端增删改查及导入功能

1 package org.jeecg.modules.airag.app.controller; 1 package org.jeecg.modules.airag.app.controller;
2 2
3 -import java.lang.reflect.Field;  
4 -import java.util.Arrays;  
5 -import java.util.List;  
6 -import javax.servlet.http.HttpServletRequest;  
7 -import javax.servlet.http.HttpServletResponse;  
8 -import javax.sql.DataSource;  
9 -import java.sql.Connection; // PostgreSQL JDBC 连接  
10 -import java.sql.PreparedStatement;  
11 -import java.sql.ResultSet;  
12 -import java.sql.ResultSetMetaData;  
13 -import java.sql.SQLException;  
14 -import java.util.ArrayList;  
15 -import java.util.HashMap;  
16 -import java.util.List;  
17 -import java.util.Map;  
18 -  
19 -import dev.langchain4j.store.embedding.EmbeddingStore; // LangChain4j 的 EmbeddingStore 接口  
20 -import dev.langchain4j.store.embedding.pgvector.PgVectorEmbeddingStore;  
21 -import dev.langchain4j.data.embedding.Embedding;  
22 -import dev.langchain4j.data.segment.TextSegment;  
23 -import dev.langchain4j.model.embedding.EmbeddingModel;  
24 -import dev.langchain4j.model.output.Response;  
25 -import dev.langchain4j.store.embedding.EmbeddingMatch;  
26 -import dev.langchain4j.store.embedding.EmbeddingSearchRequest;  
27 -import dev.langchain4j.store.embedding.EmbeddingSearchResult;  
28 -import dev.langchain4j.store.embedding.EmbeddingStore;  
29 -import dev.langchain4j.store.embedding.pgvector.PgVectorEmbeddingStore;  
30 -import org.jeecg.common.api.vo.Result;  
31 -import org.jeecg.common.system.query.QueryGenerator;  
32 -  
33 -import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; 3 +import cn.hutool.core.lang.generator.SnowflakeGenerator;
34 import com.baomidou.mybatisplus.core.metadata.IPage; 4 import com.baomidou.mybatisplus.core.metadata.IPage;
35 import com.baomidou.mybatisplus.extension.plugins.pagination.Page; 5 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
  6 +import io.swagger.v3.oas.annotations.Operation;
  7 +import io.swagger.v3.oas.annotations.tags.Tag;
36 import lombok.extern.slf4j.Slf4j; 8 import lombok.extern.slf4j.Slf4j;
37 -  
38 -//import org.jeecg.modules.airag.app.config.PostgreEmbeddingStore;  
39 -import org.jeecg.modules.airag.app.entity.Embeddings; 9 +import org.apache.poi.xwpf.usermodel.*;
  10 +import org.apache.shiro.authz.annotation.RequiresPermissions;
  11 +import org.jeecg.common.api.vo.Result;
  12 +import org.jeecg.common.aspect.annotation.AutoLog;
40 import org.jeecg.modules.airag.app.entity.Embeddings; 13 import org.jeecg.modules.airag.app.entity.Embeddings;
41 import org.jeecg.modules.airag.app.service.IEmbeddingsService; 14 import org.jeecg.modules.airag.app.service.IEmbeddingsService;
42 -import org.jeecg.common.system.base.controller.JeecgController;  
43 -import org.jeecg.modules.airag.app.utils.AiModelUtils;  
44 -import org.jeecg.modules.airag.llm.entity.AiragModel;  
45 -import org.jeecg.modules.airag.llm.handler.EmbeddingHandler;  
46 import org.springframework.beans.factory.annotation.Autowired; 15 import org.springframework.beans.factory.annotation.Autowired;
47 -import org.springframework.beans.factory.annotation.Qualifier;  
48 -import org.springframework.boot.jdbc.DataSourceBuilder;  
49 import org.springframework.web.bind.annotation.*; 16 import org.springframework.web.bind.annotation.*;
  17 +import org.springframework.web.multipart.MultipartFile;
50 import org.springframework.web.servlet.ModelAndView; 18 import org.springframework.web.servlet.ModelAndView;
51 -import io.swagger.v3.oas.annotations.tags.Tag;  
52 -import io.swagger.v3.oas.annotations.Operation;  
53 -import org.jeecg.common.aspect.annotation.AutoLog;  
54 -import org.apache.shiro.authz.annotation.RequiresPermissions;  
55 19
56 - /**  
57 - * @Description: Embeddings  
58 - * @Author: jeecg-boot  
59 - * @Date: 2025-05-26  
60 - * @Version: V1.0  
61 - */ 20 +import javax.servlet.http.HttpServletRequest;
  21 +import javax.servlet.http.HttpServletResponse;
  22 +import java.sql.SQLException;
  23 +import java.util.*;
  24 +
  25 +/**
  26 +* @Description: Embeddings
  27 +* @Author: jeecg-boot
  28 +* @Date: 2025-05-26
  29 +* @Version: V1.0
  30 +*/
62 @Tag(name="Embeddings") 31 @Tag(name="Embeddings")
63 @RestController 32 @RestController
64 @RequestMapping("/embeddings/embeddings") 33 @RequestMapping("/embeddings/embeddings")
@@ -67,75 +36,83 @@ public class EmbeddingsController { @@ -67,75 +36,83 @@ public class EmbeddingsController {
67 @Autowired 36 @Autowired
68 private IEmbeddingsService embeddingsService; 37 private IEmbeddingsService embeddingsService;
69 38
70 - @Autowired 39 + /*@Autowired
71 private AiModelUtils aiModelUtils; 40 private AiModelUtils aiModelUtils;
72 -  
73 - @Autowired  
74 - private EmbeddingHandler embeddingHandler;  
75 - 41 +*/
76 42
77 /** 43 /**
78 * 分页列表查询 44 * 分页列表查询
79 * 45 *
80 - * @param Embeddings 46 + * @param embeddings
81 * @param pageNo 47 * @param pageNo
82 * @param pageSize 48 * @param pageSize
83 * @param req 49 * @param req
84 * @return 50 * @return
85 */ 51 */
86 //@AutoLog(value = "Embeddings-分页列表查询") 52 //@AutoLog(value = "Embeddings-分页列表查询")
87 - @Operation(summary="Embeddings-分页列表查询") 53 + @Operation(summary = "Embeddings-分页列表查询")
88 @GetMapping(value = "/list") 54 @GetMapping(value = "/list")
89 - public Result<IPage<Embeddings>> queryPageList(Embeddings Embeddings,  
90 - @RequestParam(name="pageNo", defaultValue="1") Integer pageNo,  
91 - @RequestParam(name="pageSize", defaultValue="10") Integer pageSize, 55 + public Result<IPage<Embeddings>> queryPageList(Embeddings embeddings,
  56 + @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
  57 + @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,
92 HttpServletRequest req) throws NoSuchFieldException, IllegalAccessException, SQLException { 58 HttpServletRequest req) throws NoSuchFieldException, IllegalAccessException, SQLException {
93 -// AiragModel airagModel = new AiragModel();  
94 -// airagModel.setId("1925730210204721154");  
95 -// airagModel.setProvider("OLLAMA");  
96 -// airagModel.setModelName("nomic-embed-text");  
97 -// airagModel.setBaseUrl("http://localhost:11434");  
98 -// EmbeddingStore<TextSegment> embedStore = embeddingHandler.getEmbedStore(airagModel);  
99 -// embeddingHandler.searchEmbedding()  
100 - Response<Embedding> embedding = aiModelUtils.getEmbedding("1925730210204721154", "33333");  
101 -  
102 - List<Embeddings> records = embeddingsService.findAll(); 59 + //Response<Embedding> embedding = aiModelUtils.getEmbedding("1925730210204721154", "33333");
  60 +
  61 + List<Embeddings> records = embeddingsService.findAll(embeddings);
103 for (Embeddings record : records) { 62 for (Embeddings record : records) {
104 System.out.println("record = " + record); 63 System.out.println("record = " + record);
105 } 64 }
106 Page<Embeddings> page = new Page<Embeddings>(pageNo, pageSize); 65 Page<Embeddings> page = new Page<Embeddings>(pageNo, pageSize);
107 page.setRecords(records); 66 page.setRecords(records);
108 return Result.OK(page); 67 return Result.OK(page);
109 -  
110 } 68 }
111 69
112 /** 70 /**
113 * 添加 71 * 添加
114 * 72 *
115 - * @param Embeddings 73 + * @param embeddings
116 * @return 74 * @return
117 */ 75 */
118 @AutoLog(value = "Embeddings-添加") 76 @AutoLog(value = "Embeddings-添加")
119 - @Operation(summary="Embeddings-添加")  
120 - @RequiresPermissions("Embeddings:Embeddings:add") 77 + @Operation(summary = "Embeddings-添加")
  78 + @RequiresPermissions("embeddings:embeddings:add")
121 @PostMapping(value = "/add") 79 @PostMapping(value = "/add")
122 - public Result<String> add(@RequestBody Embeddings Embeddings) { 80 + public Result<String> add(@RequestBody Embeddings embeddings) {
123 // embeddingsService.save(Embeddings); 81 // embeddingsService.save(Embeddings);
  82 + // 1. 构建完整的metadata
  83 + Map<String, Object> metadata = new HashMap<>();
  84 + SnowflakeGenerator snowflakeGenerator = new SnowflakeGenerator();
  85 + String knowledgeId = String.valueOf(snowflakeGenerator.next());
  86 + metadata.put("knowledgeId", knowledgeId); // 使用前端传入的知识库ID
  87 + metadata.put("docName", embeddings.getDocName());
  88 + String docId = String.valueOf(snowflakeGenerator.next());
  89 + metadata.put("docId", docId); // 自动生成唯一文档ID
  90 + metadata.put("index", "0"); // 默认索引位置为0
  91 + // 2. 设置到embeddings对象
  92 + embeddings.setMetadata(metadata);
  93 +
  94 + /*// 3. 生成向量嵌入(实际项目中应调用嵌入模型API)
  95 + embeddings.setEmbedding(generateEmbedding(embeddings.getText()));
  96 +*/
  97 + System.out.println(new SnowflakeGenerator().next());
  98 +
  99 + embeddingsService.insert(embeddings);
124 return Result.OK("添加成功!"); 100 return Result.OK("添加成功!");
125 } 101 }
126 102
127 /** 103 /**
128 * 编辑 104 * 编辑
129 * 105 *
130 - * @param Embeddings 106 + * @param embeddings
131 * @return 107 * @return
132 */ 108 */
133 @AutoLog(value = "Embeddings-编辑") 109 @AutoLog(value = "Embeddings-编辑")
134 - @Operation(summary="Embeddings-编辑")  
135 - @RequiresPermissions("Embeddings:Embeddings:edit")  
136 - @RequestMapping(value = "/edit", method = {RequestMethod.PUT,RequestMethod.POST})  
137 - public Result<String> edit(@RequestBody Embeddings Embeddings) { 110 + @Operation(summary = "Embeddings-编辑")
  111 + @RequiresPermissions("embeddings:embeddings:edit")
  112 + @RequestMapping(value = "/edit", method = {RequestMethod.PUT, RequestMethod.POST})
  113 + public Result<String> edit(@RequestBody Embeddings embeddings) {
138 // embeddingsService.updateById(Embeddings); 114 // embeddingsService.updateById(Embeddings);
  115 + embeddingsService.update(embeddings);
139 return Result.OK("编辑成功!"); 116 return Result.OK("编辑成功!");
140 } 117 }
141 118
@@ -146,11 +123,12 @@ public class EmbeddingsController { @@ -146,11 +123,12 @@ public class EmbeddingsController {
146 * @return 123 * @return
147 */ 124 */
148 @AutoLog(value = "Embeddings-通过id删除") 125 @AutoLog(value = "Embeddings-通过id删除")
149 - @Operation(summary="Embeddings-通过id删除")  
150 - @RequiresPermissions("Embeddings:Embeddings:delete") 126 + @Operation(summary = "Embeddings-通过id删除")
  127 + @RequiresPermissions("embeddings:embeddings:delete")
151 @DeleteMapping(value = "/delete") 128 @DeleteMapping(value = "/delete")
152 - public Result<String> delete(@RequestParam(name="id",required=true) String id) {  
153 -// embeddingsService.removeById(id); 129 + public Result<String> delete(@RequestParam(name = "id", required = true) String id) {
  130 + //embeddingsService.removeById(id);
  131 + embeddingsService.deleteById(id);
154 return Result.OK("删除成功!"); 132 return Result.OK("删除成功!");
155 } 133 }
156 134
@@ -161,10 +139,10 @@ public class EmbeddingsController { @@ -161,10 +139,10 @@ public class EmbeddingsController {
161 * @return 139 * @return
162 */ 140 */
163 @AutoLog(value = "Embeddings-批量删除") 141 @AutoLog(value = "Embeddings-批量删除")
164 - @Operation(summary="Embeddings-批量删除")  
165 - @RequiresPermissions("Embeddings:Embeddings:deleteBatch") 142 + @Operation(summary = "Embeddings-批量删除")
  143 + @RequiresPermissions("embeddings:embeddings:deleteBatch")
166 @DeleteMapping(value = "/deleteBatch") 144 @DeleteMapping(value = "/deleteBatch")
167 - public Result<String> deleteBatch(@RequestParam(name="ids",required=true) String ids) { 145 + public Result<String> deleteBatch(@RequestParam(name = "ids", required = true) String ids) {
168 // this.embeddingsService.removeByIds(Arrays.asList(ids.split(","))); 146 // this.embeddingsService.removeByIds(Arrays.asList(ids.split(",")));
169 return Result.OK("批量删除成功!"); 147 return Result.OK("批量删除成功!");
170 } 148 }
@@ -176,13 +154,14 @@ public class EmbeddingsController { @@ -176,13 +154,14 @@ public class EmbeddingsController {
176 * @return 154 * @return
177 */ 155 */
178 //@AutoLog(value = "Embeddings-通过id查询") 156 //@AutoLog(value = "Embeddings-通过id查询")
179 - @Operation(summary="Embeddings-通过id查询") 157 + @Operation(summary = "Embeddings-通过id查询")
180 @GetMapping(value = "/queryById") 158 @GetMapping(value = "/queryById")
181 - public Result<Embeddings> queryById(@RequestParam(name="id",required=true) String id) { 159 + public Result<Embeddings> queryById(@RequestParam(name = "id", required = true) String id) {
182 // Embeddings Embeddings = embeddingsService.getById(id); 160 // Embeddings Embeddings = embeddingsService.getById(id);
183 // if(Embeddings==null) { 161 // if(Embeddings==null) {
184 // return Result.error("未找到对应数据"); 162 // return Result.error("未找到对应数据");
185 // } 163 // }
  164 + embeddingsService.findById(id);
186 return Result.OK(); 165 return Result.OK();
187 } 166 }
188 167
@@ -208,7 +187,109 @@ public class EmbeddingsController { @@ -208,7 +187,109 @@ public class EmbeddingsController {
208 @RequiresPermissions("Embeddings:Embeddings:importExcel") 187 @RequiresPermissions("Embeddings:Embeddings:importExcel")
209 @RequestMapping(value = "/importExcel", method = RequestMethod.POST) 188 @RequestMapping(value = "/importExcel", method = RequestMethod.POST)
210 public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) { 189 public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
  190 +
  191 +
211 return null; 192 return null;
212 } 193 }
213 194
  195 +
  196 + // EmbeddingsController.java 新增方法
  197 + @AutoLog(value = "Embeddings-导入Word文档")
  198 + @Operation(summary = "Embeddings-导入Word文档")
  199 + @RequiresPermissions("embeddings:embeddings:importWord")
  200 + @PostMapping(value = "/importWord")
  201 + public Result<Map<String, Object>> importWord(@RequestParam(value = "file", required = false) MultipartFile file) {
  202 + try {
  203 + // 1. 验证文件
  204 + if (file.isEmpty()) {
  205 + return Result.error("上传文件为空");
  206 + }
  207 +
  208 + String fileName = file.getOriginalFilename();
  209 + String fileExtension = fileName.substring(fileName.lastIndexOf(".") + 1).toLowerCase();
  210 +
  211 + if (!"doc".equals(fileExtension) && !"docx".equals(fileExtension)) {
  212 + return Result.error("仅支持.doc和.docx格式的Word文档");
  213 + }
  214 +
  215 +
  216 + if (fileName != null) {
  217 + // 去掉后缀
  218 + int dotIndex = fileName.lastIndexOf('.');
  219 + fileName = fileName.substring(0, dotIndex);
  220 + }
  221 +
  222 +
  223 + // 2. 解析Word文档
  224 + String fullContent = readFullWordContent(file);
  225 +
  226 + if (fullContent.isEmpty()) {
  227 + return Result.error("文档内容为空,无法导入");
  228 + }
  229 +
  230 + // 3. 准备元数据
  231 + SnowflakeGenerator snowflakeGenerator = new SnowflakeGenerator();
  232 + String knowledgeId = String.valueOf(snowflakeGenerator.next());
  233 + String docId = String.valueOf(snowflakeGenerator.next());
  234 + String docName = fileName;
  235 +
  236 + Map<String, Object> metadata = new HashMap<>();
  237 + metadata.put("knowledgeId", knowledgeId);
  238 + metadata.put("docName", docName);
  239 + metadata.put("docId", docId);
  240 +
  241 + // 4. 创建并保存Embeddings对象
  242 + Embeddings embeddings = new Embeddings();
  243 +
  244 + embeddings.setText(fullContent);
  245 + embeddings.setId(UUID.randomUUID().toString());
  246 + embeddings.setMetadata(metadata);
  247 + // 设置向量嵌入(实际项目中应调用模型API)
  248 + embeddings.setEmbedding(generateRandomEmbedding());
  249 +
  250 + // 保存到数据库
  251 + embeddingsService.insert(embeddings);
  252 + return Result.OK("导入成功");
  253 +
  254 + } catch (Exception e) {
  255 + log.error("Word导入失败", e);
  256 + return Result.error("导入失败: " + e.getMessage());
  257 + }
  258 + }
  259 +
  260 + // 读取整个Word内容作为单个字符串
  261 + private String readFullWordContent(MultipartFile file) throws Exception {
  262 + try (XWPFDocument doc = new XWPFDocument(file.getInputStream())) {
  263 + StringBuilder fullContent = new StringBuilder();
  264 +
  265 + // 读取所有段落文本
  266 + for (XWPFParagraph p : doc.getParagraphs()) {
  267 + fullContent.append(p.getText()).append("\n");
  268 + }
  269 +
  270 + // 读取所有表格文本
  271 + for (XWPFTable table : doc.getTables()) {
  272 + for (XWPFTableRow row : table.getRows()) {
  273 + for (XWPFTableCell cell : row.getTableCells()) {
  274 + fullContent.append(cell.getText()).append("\t");
  275 + }
  276 + fullContent.append("\n");
  277 + }
  278 + }
  279 +
  280 + return fullContent.toString();
  281 + }
  282 + }
  283 +
  284 +
  285 + // 生成随机向量(1536维)
  286 + private float[] generateRandomEmbedding() {
  287 + float[] embedding = new float[768];
  288 + Random random = new Random();
  289 + for (int i = 0; i < embedding.length; i++) {
  290 + embedding[i] = random.nextFloat() * 2 - 1;
  291 + }
  292 + return embedding;
  293 +
  294 + }
214 } 295 }
@@ -19,4 +19,11 @@ public class Embeddings { @@ -19,4 +19,11 @@ public class Embeddings {
19 private Map<String, Object> metadata; 19 private Map<String, Object> metadata;
20 20
21 private Double similarity; 21 private Double similarity;
  22 + // 添加 docName 字段(仅用于接收前端数据)
  23 + private String docName;
  24 + private String knowledgeId; // 新增知识库ID字段
  25 + private String docId; // 新增文档ID字段
  26 + private String index; // 新增索引位置字段
  27 +
  28 +
22 } 29 }
1 package org.jeecg.modules.airag.app.mapper; 1 package org.jeecg.modules.airag.app.mapper;
2 2
  3 +import cn.hutool.core.lang.generator.SnowflakeGenerator;
  4 +import com.alibaba.fastjson2.JSONObject;
3 import com.fasterxml.jackson.core.JsonProcessingException; 5 import com.fasterxml.jackson.core.JsonProcessingException;
4 import com.fasterxml.jackson.core.type.TypeReference; 6 import com.fasterxml.jackson.core.type.TypeReference;
5 import com.fasterxml.jackson.databind.ObjectMapper; 7 import com.fasterxml.jackson.databind.ObjectMapper;
6 import com.pgvector.PGvector; 8 import com.pgvector.PGvector;
7 import lombok.extern.slf4j.Slf4j; 9 import lombok.extern.slf4j.Slf4j;
8 import org.apache.commons.lang3.StringUtils; 10 import org.apache.commons.lang3.StringUtils;
9 -import org.apache.shiro.dao.DataAccessException;  
10 import org.jeecg.modules.airag.app.entity.Embeddings; 11 import org.jeecg.modules.airag.app.entity.Embeddings;
  12 +import org.postgresql.util.PGobject;
11 import org.springframework.stereotype.Component; 13 import org.springframework.stereotype.Component;
12 14
13 import java.sql.*; 15 import java.sql.*;
14 -import java.util.ArrayList;  
15 -import java.util.Collections;  
16 -import java.util.List;  
17 -import java.util.Map; 16 +import java.util.*;
18 17
19 @Component 18 @Component
20 @Slf4j 19 @Slf4j
@@ -31,9 +30,16 @@ public class PgVectorMapper { @@ -31,9 +30,16 @@ public class PgVectorMapper {
31 } 30 }
32 31
33 // 查询所有向量记录 32 // 查询所有向量记录
34 - public List<Embeddings> findAll() { 33 + public List<Embeddings> findAll(Embeddings embeddings) {
35 List<Embeddings> results = new ArrayList<>(); 34 List<Embeddings> results = new ArrayList<>();
36 String sql = "SELECT * FROM embeddings"; 35 String sql = "SELECT * FROM embeddings";
  36 + if (StringUtils.isNotBlank(embeddings.getId())){
  37 + sql += " WHERE embedding_id = '" + embeddings.getId() + "'";
  38 + }
  39 +
  40 + if(StringUtils.isNotBlank(embeddings.getText())){
  41 + sql += " where text = '" + embeddings.getText() + "'";
  42 + }
37 43
38 try (Connection conn = getConnection(); 44 try (Connection conn = getConnection();
39 PreparedStatement stmt = conn.prepareStatement(sql); 45 PreparedStatement stmt = conn.prepareStatement(sql);
@@ -50,13 +56,13 @@ public class PgVectorMapper { @@ -50,13 +56,13 @@ public class PgVectorMapper {
50 } 56 }
51 57
52 // 根据ID查询单个向量记录 58 // 根据ID查询单个向量记录
53 - public Embeddings findById(Long id) {  
54 - String sql = "SELECT * FROM embeddings WHERE id = ?"; 59 + public Embeddings findById(String id) {
  60 + String sql = "SELECT * FROM embeddings WHERE embedding_id = ?";
55 61
56 try (Connection conn = getConnection(); 62 try (Connection conn = getConnection();
57 PreparedStatement stmt = conn.prepareStatement(sql)) { 63 PreparedStatement stmt = conn.prepareStatement(sql)) {
58 64
59 - stmt.setLong(1, id); 65 + stmt.setString(1, id);
60 try (ResultSet rs = stmt.executeQuery()) { 66 try (ResultSet rs = stmt.executeQuery()) {
61 if (rs.next()) { 67 if (rs.next()) {
62 return mapRowToEmbeddings(rs); 68 return mapRowToEmbeddings(rs);
@@ -71,14 +77,30 @@ public class PgVectorMapper { @@ -71,14 +77,30 @@ public class PgVectorMapper {
71 77
72 // 插入新向量记录 78 // 插入新向量记录
73 public int insert(Embeddings record) { 79 public int insert(Embeddings record) {
74 - String sql = "INSERT INTO embeddings (id, embedding, metadata) VALUES (?, ?, ?::jsonb)"; 80 + /* Map<String, Object> metadata = new LinkedHashMap<>();
  81 +
  82 + // 按固定顺序添加字段
  83 + metadata.put("docId", UUID.randomUUID().toString());
  84 + metadata.put("knowledgeId", getKnowledgeId(record)); // 使用统一方法获取
  85 + metadata.put("docName", record.getDocName());
  86 + metadata.put("index", 0); // 确保是整数
  87 + record.setMetadata(metadata);
  88 +
  89 + // 自动生成向量(这里需要调用嵌入模型)
  90 + float[] embedding = generateEmbedding(record.getText());
  91 + record.setEmbedding(embedding);*/
  92 +
  93 +
  94 + String sql = "INSERT INTO embeddings (embedding_id, embedding, text, metadata) VALUES (?, ?, ?, ?::jsonb)";
75 95
76 try (Connection conn = getConnection(); 96 try (Connection conn = getConnection();
77 PreparedStatement stmt = conn.prepareStatement(sql)) { 97 PreparedStatement stmt = conn.prepareStatement(sql)) {
78 98
79 - stmt.setString(1, record.getId()); 99 + stmt.setString(1, UUID.randomUUID().toString());
  100 +// stmt.setObject(2, new PGvector(record.getEmbedding()));
80 stmt.setObject(2, new PGvector(record.getEmbedding())); 101 stmt.setObject(2, new PGvector(record.getEmbedding()));
81 - stmt.setString(3, toJson(record.getMetadata())); 102 + stmt.setObject(3, record.getText());
  103 + stmt.setObject(4, toJson(record.getMetadata()));
82 104
83 return stmt.executeUpdate(); 105 return stmt.executeUpdate();
84 } catch (SQLException e) { 106 } catch (SQLException e) {
@@ -89,14 +111,27 @@ public class PgVectorMapper { @@ -89,14 +111,27 @@ public class PgVectorMapper {
89 111
90 // 更新向量记录 112 // 更新向量记录
91 public int update(Embeddings record) { 113 public int update(Embeddings record) {
92 - String sql = "UPDATE embeddings SET embedding = ?, metadata = ?::jsonb WHERE id = ?"; 114 + String sql = "UPDATE embeddings SET embedding = ?, metadata = ?, text = ?::jsonb WHERE embedding_id = ?";
93 115
94 try (Connection conn = getConnection(); 116 try (Connection conn = getConnection();
95 PreparedStatement stmt = conn.prepareStatement(sql)) { 117 PreparedStatement stmt = conn.prepareStatement(sql)) {
96 118
  119 + JSONObject mataData = new JSONObject();
  120 + SnowflakeGenerator snowflakeGenerator = new SnowflakeGenerator();
  121 + String knowledgeId = String.valueOf(snowflakeGenerator.next());
  122 + mataData.put("knowledgeId", knowledgeId); // 使用前端传入的知识库ID
  123 + mataData.put("docName", record.getDocName());
  124 + String docId = String.valueOf(snowflakeGenerator.next());
  125 + mataData.put("docId", docId); // 自动生成唯一文档ID
  126 + mataData.put("index", "0");
  127 +
  128 + PGobject jsonObject = new PGobject();
  129 + jsonObject.setType("json");
  130 + jsonObject.setValue(mataData.toJSONString());
97 stmt.setObject(1, new PGvector(record.getEmbedding())); 131 stmt.setObject(1, new PGvector(record.getEmbedding()));
98 - stmt.setString(2, toJson(record.getMetadata()));  
99 - stmt.setString(3, record.getId()); 132 + stmt.setObject(2, jsonObject);
  133 + stmt.setObject(3, record.getText());
  134 + stmt.setString(4, record.getId());
100 135
101 return stmt.executeUpdate(); 136 return stmt.executeUpdate();
102 } catch (SQLException e) { 137 } catch (SQLException e) {
@@ -106,13 +141,13 @@ public class PgVectorMapper { @@ -106,13 +141,13 @@ public class PgVectorMapper {
106 } 141 }
107 142
108 // 根据ID删除向量记录 143 // 根据ID删除向量记录
109 - public int deleteById(Long id) {  
110 - String sql = "DELETE FROM embeddings WHERE id = ?"; 144 + public int deleteById(String id) {
  145 + String sql = "DELETE FROM embeddings WHERE embedding_id = ?";
111 146
112 try (Connection conn = getConnection(); 147 try (Connection conn = getConnection();
113 PreparedStatement stmt = conn.prepareStatement(sql)) { 148 PreparedStatement stmt = conn.prepareStatement(sql)) {
114 149
115 - stmt.setLong(1, id); 150 + stmt.setString(1, id);
116 return stmt.executeUpdate(); 151 return stmt.executeUpdate();
117 } catch (SQLException e) { 152 } catch (SQLException e) {
118 log.error("删除向量记录失败, ID: {}", id, e); 153 log.error("删除向量记录失败, ID: {}", id, e);
@@ -176,4 +211,31 @@ public class PgVectorMapper { @@ -176,4 +211,31 @@ public class PgVectorMapper {
176 return Collections.emptyMap(); 211 return Collections.emptyMap();
177 } 212 }
178 } 213 }
  214 +
  215 + /*// 自动生成嵌入向量的方法(需根据您的嵌入模型实现)
  216 + private float[] generateEmbedding(String text) {
  217 + // 改为生成 768 维向量
  218 + float[] embedding = new float[768]; // OpenAI 标准维度是 1536,这里改为 768
  219 +
  220 + // 实际项目中应调用嵌入模型 API
  221 + // 例如:return embeddingClient.generate(text, 768);
  222 +
  223 + // 临时实现:生成随机向量(仅用于演示)
  224 + log.warn("使用随机向量生成 - 实际项目中应替换为真实模型调用");
  225 + Random random = new Random();
  226 + for (int i = 0; i < embedding.length; i++) {
  227 + embedding[i] = random.nextFloat() * 2 - 1;
  228 + }
  229 + return embedding;
  230 + }
  231 +
  232 + private String getKnowledgeId(Embeddings record) {
  233 + // 1. 优先使用前端传入的knowledgeId(如果存在)
  234 + if (record.getMetadata() != null && record.getMetadata().containsKey("knowledgeId")) {
  235 + return String.valueOf(record.getMetadata().get("knowledgeId"));
  236 + }
  237 +
  238 + // 2. 使用配置的默认值
  239 + return "default_knowledge"; // 实际应从配置读取
  240 + }*/
179 } 241 }
1 package org.jeecg.modules.airag.app.service; 1 package org.jeecg.modules.airag.app.service;
2 2
3 //import org.jeecg.modules.demo.test.entity.Test; 3 //import org.jeecg.modules.demo.test.entity.Test;
4 -import org.jeecg.modules.airag.app.entity.Test;  
5 4
6 -import com.baomidou.mybatisplus.extension.service.IService;  
7 import org.jeecg.modules.airag.app.entity.Embeddings; 5 import org.jeecg.modules.airag.app.entity.Embeddings;
8 6
9 import java.util.List; 7 import java.util.List;
@@ -16,5 +14,9 @@ import java.util.List; @@ -16,5 +14,9 @@ import java.util.List;
16 */ 14 */
17 public interface IEmbeddingsService { 15 public interface IEmbeddingsService {
18 16
19 - List<Embeddings> findAll(); 17 + List<Embeddings> findAll(Embeddings embeddings);
  18 + int deleteById(String id);
  19 + int insert(Embeddings record);
  20 + int update(Embeddings record);
  21 + Embeddings findById(String id);
20 } 22 }
1 package org.jeecg.modules.airag.app.service.impl; 1 package org.jeecg.modules.airag.app.service.impl;
2 2
3 -import org.jeecg.modules.airag.app.entity.Test;  
4 import org.jeecg.modules.airag.app.entity.Embeddings; 3 import org.jeecg.modules.airag.app.entity.Embeddings;
5 -import org.jeecg.modules.airag.app.mapper.EmbeddingsMapper;  
6 import org.jeecg.modules.airag.app.mapper.PgVectorMapper; 4 import org.jeecg.modules.airag.app.mapper.PgVectorMapper;
7 import org.jeecg.modules.airag.app.service.IEmbeddingsService; 5 import org.jeecg.modules.airag.app.service.IEmbeddingsService;
8 import org.springframework.beans.factory.annotation.Autowired; 6 import org.springframework.beans.factory.annotation.Autowired;
9 import org.springframework.stereotype.Service; 7 import org.springframework.stereotype.Service;
10 8
11 -import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;  
12 -  
13 import java.util.List; 9 import java.util.List;
14 10
15 /** 11 /**
@@ -22,8 +18,27 @@ import java.util.List; @@ -22,8 +18,27 @@ import java.util.List;
22 public class IEmbeddingsServiceImpl implements IEmbeddingsService { 18 public class IEmbeddingsServiceImpl implements IEmbeddingsService {
23 @Autowired 19 @Autowired
24 private PgVectorMapper pgVectorMapper; 20 private PgVectorMapper pgVectorMapper;
  21 +
  22 + @Override
  23 + public List<Embeddings> findAll(Embeddings embeddings) {
  24 + return pgVectorMapper.findAll(embeddings);
  25 + }
  26 +
  27 + public int deleteById(String id) {
  28 + return pgVectorMapper.deleteById(id);
  29 + }
  30 +
  31 + public int insert(Embeddings record) {
  32 + return pgVectorMapper.insert(record);
  33 + }
  34 +
  35 + @Override
  36 + public int update(Embeddings record) {
  37 + return pgVectorMapper.update(record);
  38 + }
  39 +
25 @Override 40 @Override
26 - public List<Embeddings> findAll() {  
27 - return pgVectorMapper.findAll(); 41 + public Embeddings findById(String id) {
  42 + return pgVectorMapper.findById(id);
28 } 43 }
29 } 44 }