2 Commits e7d4fb3aea ... 06eb3d5c20

Author SHA1 Message Date
  zhangenzhi 06eb3d5c20 补充提交 1 month ago
  zhangenzhi f65f4c1b45 bug修复,功能开发 1 month ago
31 changed files with 776 additions and 128 deletions
  1. 3 3
      pavis-module-aigc/.flattened-pom.xml
  2. 10 0
      pavis-module-aigc/src/main/java/com/pavis/admin/aigc/common/dto/EmbeddingR.java
  3. 83 0
      pavis-module-aigc/src/main/java/com/pavis/admin/aigc/common/utils/FloatArrayTypeHandler.java
  4. 73 0
      pavis-module-aigc/src/main/java/com/pavis/admin/aigc/core/SpringContextHolder.java
  5. 17 0
      pavis-module-aigc/src/main/java/com/pavis/admin/aigc/model/entity/DocChunkDO.java
  6. 3 23
      pavis-module-aigc/src/main/java/com/pavis/admin/aigc/model/req/AgentReq.java
  7. 9 0
      pavis-module-aigc/src/main/java/com/pavis/admin/aigc/model/req/DocChunkReq.java
  8. 4 0
      pavis-module-aigc/src/main/java/com/pavis/admin/aigc/model/req/ModelReq.java
  9. 59 0
      pavis-module-aigc/src/main/java/com/pavis/admin/aigc/model/req/SimilaritySearchReq.java
  10. 9 0
      pavis-module-aigc/src/main/java/com/pavis/admin/aigc/model/resp/DocChunkResp.java
  11. 69 0
      pavis-module-aigc/src/main/java/com/pavis/admin/aigc/model/resp/SimilaritySearchResp.java
  12. 28 0
      pavis-module-aigc/src/main/java/com/pavis/admin/aigc/service/AgentService.java
  13. 7 1
      pavis-module-aigc/src/main/java/com/pavis/admin/aigc/service/DocChunkService.java
  14. 2 0
      pavis-module-aigc/src/main/java/com/pavis/admin/aigc/service/KnowledgeService.java
  15. 50 0
      pavis-module-aigc/src/main/java/com/pavis/admin/aigc/service/impl/AgentServiceImpl.java
  16. 0 1
      pavis-module-aigc/src/main/java/com/pavis/admin/aigc/service/impl/AigcAppServiceImpl.java
  17. 116 1
      pavis-module-aigc/src/main/java/com/pavis/admin/aigc/service/impl/DocChunkServiceImpl.java
  18. 47 26
      pavis-module-aigc/src/main/java/com/pavis/admin/aigc/service/impl/DocServiceImpl.java
  19. 20 1
      pavis-module-aigc/src/main/java/com/pavis/admin/aigc/service/impl/EmbedStoreServiceImpl.java
  20. 71 58
      pavis-module-aigc/src/main/java/com/pavis/admin/aigc/service/impl/KnowledgeServiceImpl.java
  21. 6 0
      pavis-module-aigc/src/main/java/com/pavis/admin/aigc/service/impl/ModelServiceImpl.java
  22. 3 3
      pavis-module-system/src/main/java/com/pavis/admin/auth/AbstractLoginHandler.java
  23. 0 1
      pavis-module-system/src/main/java/com/pavis/admin/auth/handler/PhoneLoginHandler.java
  24. 25 1
      pavis-webapi/src/main/java/com/pavis/admin/controller/aigc/AgentController.java
  25. 15 1
      pavis-webapi/src/main/java/com/pavis/admin/controller/aigc/DocChunkController.java
  26. 25 1
      pavis-webapi/src/main/java/com/pavis/admin/controller/aigc/EmbedStoreController.java
  27. 10 1
      pavis-webapi/src/main/java/com/pavis/admin/controller/aigc/KnowledgeController.java
  28. 7 0
      pavis-webapi/src/main/java/com/pavis/admin/controller/aigc/ModelController.java
  29. 3 5
      pavis-webapi/src/main/java/com/pavis/admin/controller/common/CaptchaController.java
  30. 1 1
      pavis-webapi/src/main/resources/config/application-prod.yml
  31. 1 0
      pavis-webapi/src/main/resources/db/changelog/mysql/main_table.sql

+ 3 - 3
pavis-module-aigc/.flattened-pom.xml

@@ -48,17 +48,17 @@
     <dependency>
     <dependency>
       <groupId>dev.langchain4j</groupId>
       <groupId>dev.langchain4j</groupId>
       <artifactId>langchain4j</artifactId>
       <artifactId>langchain4j</artifactId>
-      <version>${langchain4j-core.version}</version>
+      <version>${langchain4j.version}</version>
     </dependency>
     </dependency>
     <dependency>
     <dependency>
       <groupId>dev.langchain4j</groupId>
       <groupId>dev.langchain4j</groupId>
       <artifactId>langchain4j-core</artifactId>
       <artifactId>langchain4j-core</artifactId>
-      <version>${langchain4j-core.version}</version>
+      <version>${langchain4j.version}</version>
     </dependency>
     </dependency>
     <dependency>
     <dependency>
       <groupId>dev.langchain4j</groupId>
       <groupId>dev.langchain4j</groupId>
       <artifactId>langchain4j-open-ai</artifactId>
       <artifactId>langchain4j-open-ai</artifactId>
-      <version>${langchain4j-core.version}</version>
+      <version>${langchain4j.version}</version>
     </dependency>
     </dependency>
     <dependency>
     <dependency>
       <groupId>dev.langchain4j</groupId>
       <groupId>dev.langchain4j</groupId>

+ 10 - 0
pavis-module-aigc/src/main/java/com/pavis/admin/aigc/common/dto/EmbeddingR.java

@@ -16,6 +16,9 @@
 
 
 package com.pavis.admin.aigc.common.dto;
 package com.pavis.admin.aigc.common.dto;
 
 
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.pavis.admin.aigc.common.utils.FloatArrayTypeHandler;
+import io.swagger.v3.oas.annotations.media.Schema;
 import lombok.Data;
 import lombok.Data;
 import lombok.experimental.Accessors;
 import lombok.experimental.Accessors;
 
 
@@ -46,4 +49,11 @@ public class EmbeddingR {
      * Embedding后切片的文本
      * Embedding后切片的文本
      */
      */
     private String text;
     private String text;
+
+    /**
+     * 向量嵌入(float数组)
+     */
+    @Schema(description = "向量嵌入,存储为JSON格式的float数组")
+    // @TableField(typeHandler = FloatArrayTypeHandler.class)
+    private float[] vector;
 }
 }

+ 83 - 0
pavis-module-aigc/src/main/java/com/pavis/admin/aigc/common/utils/FloatArrayTypeHandler.java

@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2022-present zez Authors. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.pavis.admin.aigc.common.utils;
+
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.apache.ibatis.type.BaseTypeHandler;
+import org.apache.ibatis.type.JdbcType;
+
+import java.sql.CallableStatement;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+
+public class FloatArrayTypeHandler extends BaseTypeHandler<float[]> {
+
+    private final ObjectMapper objectMapper = new ObjectMapper();
+
+    @Override
+    public void setNonNullParameter(PreparedStatement ps,
+                                    int i,
+                                    float[] parameter,
+                                    JdbcType jdbcType) throws SQLException {
+        try {
+            ps.setString(i, objectMapper.writeValueAsString(parameter));
+        } catch (Exception e) {
+            throw new SQLException("Error converting float[] to JSON", e);
+        }
+    }
+
+    @Override
+    public float[] getNullableResult(ResultSet rs, String columnName) throws SQLException {
+        String json = rs.getString(columnName);
+        if (json == null) {
+            return null;
+        }
+        try {
+            return objectMapper.readValue(json, new TypeReference<float[]>() {});
+        } catch (Exception e) {
+            throw new SQLException("Error converting JSON to float[]", e);
+        }
+    }
+
+    @Override
+    public float[] getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
+        String json = rs.getString(columnIndex);
+        if (json == null) {
+            return null;
+        }
+        try {
+            return objectMapper.readValue(json, new TypeReference<float[]>() {});
+        } catch (Exception e) {
+            throw new SQLException("Error converting JSON to float[]", e);
+        }
+    }
+
+    @Override
+    public float[] getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
+        String json = cs.getString(columnIndex);
+        if (json == null) {
+            return null;
+        }
+        try {
+            return objectMapper.readValue(json, new TypeReference<float[]>() {});
+        } catch (Exception e) {
+            throw new SQLException("Error converting JSON to float[]", e);
+        }
+    }
+}

+ 73 - 0
pavis-module-aigc/src/main/java/com/pavis/admin/aigc/core/SpringContextHolder.java

@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2024 LangChat. TyCoding All Rights Reserved.
+ *
+ * Licensed under the GNU Affero General Public License, Version 3 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.gnu.org/licenses/agpl-3.0.html
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.pavis.admin.aigc.core;
+
+import org.springframework.beans.BeansException;
+import org.springframework.beans.factory.config.BeanDefinition;
+import org.springframework.beans.factory.support.BeanDefinitionBuilder;
+import org.springframework.beans.factory.support.BeanDefinitionRegistry;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
+import org.springframework.context.ApplicationEvent;
+import org.springframework.stereotype.Service;
+
+/**
+ * @author tycoding
+ * @since 2024/1/19
+ */
+@Service
+public class SpringContextHolder implements ApplicationContextAware {
+
+    private static ApplicationContext applicationContext = null;
+
+    public static void publishEvent(ApplicationEvent event) {
+        if (applicationContext == null) {
+            return;
+        }
+        applicationContext.publishEvent(event);
+    }
+
+    public <T> T getBean(Class<T> requiredType) {
+        return applicationContext.getBean(requiredType);
+    }
+
+    @Override
+    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
+        SpringContextHolder.applicationContext = applicationContext;
+    }
+
+    public void registerBean(String beanName, Object beanInstance) {
+        BeanDefinitionRegistry beanDefinitionRegistry = (BeanDefinitionRegistry)applicationContext
+            .getAutowireCapableBeanFactory();
+
+        BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder
+            .genericBeanDefinition((Class<Object>)beanInstance.getClass(), () -> beanInstance);
+
+        BeanDefinition beanDefinition = beanDefinitionBuilder.getRawBeanDefinition();
+
+        beanDefinitionRegistry.registerBeanDefinition(beanName, beanDefinition);
+    }
+
+    public void unregisterBean(String beanName) {
+        BeanDefinitionRegistry beanDefinitionRegistry = (BeanDefinitionRegistry)applicationContext
+            .getAutowireCapableBeanFactory();
+
+        if (beanDefinitionRegistry.containsBeanDefinition(beanName)) {
+            beanDefinitionRegistry.removeBeanDefinition(beanName);
+        }
+    }
+}

+ 17 - 0
pavis-module-aigc/src/main/java/com/pavis/admin/aigc/model/entity/DocChunkDO.java

@@ -1,10 +1,14 @@
 package com.pavis.admin.aigc.model.entity;
 package com.pavis.admin.aigc.model.entity;
 
 
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.pavis.admin.aigc.common.utils.FloatArrayTypeHandler;
+import io.swagger.v3.oas.annotations.media.Schema;
 import lombok.Data;
 import lombok.Data;
 
 
 import com.baomidou.mybatisplus.annotation.TableName;
 import com.baomidou.mybatisplus.annotation.TableName;
 
 
 import com.pavis.admin.common.model.entity.BaseDO;
 import com.pavis.admin.common.model.entity.BaseDO;
+import lombok.NoArgsConstructor;
 
 
 import java.io.Serial;
 import java.io.Serial;
 import java.math.BigDecimal;
 import java.math.BigDecimal;
@@ -16,6 +20,7 @@ import java.math.BigDecimal;
  * @since 2025/05/26 17:28
  * @since 2025/05/26 17:28
  */
  */
 @Data
 @Data
+@NoArgsConstructor
 @TableName("aigc_doc_chunk")
 @TableName("aigc_doc_chunk")
 public class DocChunkDO extends BaseDO {
 public class DocChunkDO extends BaseDO {
 
 
@@ -76,4 +81,16 @@ public class DocChunkDO extends BaseDO {
      * 文档名称
      * 文档名称
      */
      */
     private String name;
     private String name;
+
+    /**
+     * 向量嵌入(float数组)
+     */
+    @Schema(description = "向量嵌入,存储为JSON格式的float数组")
+    // @TableField(typeHandler = FloatArrayTypeHandler.class)
+    private String vector;
+
+    // public DocChunkDO(float[] vector, String content) {
+    //     this.vector = vector;
+    //     this.content = content;
+    // }
 }
 }

+ 3 - 23
pavis-module-aigc/src/main/java/com/pavis/admin/aigc/model/req/AgentReq.java

@@ -65,12 +65,6 @@ public class AgentReq implements Serializable {
     @Length(max = 65535, message = "智能体提示词长度不能超过 {max} 个字符")
     @Length(max = 65535, message = "智能体提示词长度不能超过 {max} 个字符")
     private String systemPrompt;
     private String systemPrompt;
 
 
-    /**
-     * 关联模型ID
-     */
-    @Schema(description = "关联模型ID")
-    @NotNull(message = "关联模型ID不能为空")
-    private Long modelId;
 
 
     /**
     /**
      * 状态(1:启用;0:禁用)
      * 状态(1:启用;0:禁用)
@@ -80,23 +74,9 @@ public class AgentReq implements Serializable {
     private Integer status;
     private Integer status;
 
 
     /**
     /**
-     * 运行时状态
+     * 模型ID
      */
      */
-    @Schema(description = "运行时状态")
-    @NotNull(message = "运行时状态不能为空")
-    private String runtimeStatus;
-
-    /**
-     * 创建人
-     */
-    @Schema(description = "创建人")
-    @NotNull(message = "创建人不能为空")
-    private Long createUser;
+    @Schema(description = "模型ID")
+    private Long modelId;
 
 
-    /**
-     * 创建时间
-     */
-    @Schema(description = "创建时间")
-    @NotNull(message = "创建时间不能为空")
-    private LocalDateTime createTime;
 }
 }

+ 9 - 0
pavis-module-aigc/src/main/java/com/pavis/admin/aigc/model/req/DocChunkReq.java

@@ -1,5 +1,7 @@
 package com.pavis.admin.aigc.model.req;
 package com.pavis.admin.aigc.model.req;
 
 
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.pavis.admin.aigc.common.utils.FloatArrayTypeHandler;
 import jakarta.validation.constraints.*;
 import jakarta.validation.constraints.*;
 
 
 import lombok.Data;
 import lombok.Data;
@@ -60,6 +62,13 @@ public class DocChunkReq implements Serializable {
     @Length(max = 65535, message = "切片内容长度不能超过 {max} 个字符")
     @Length(max = 65535, message = "切片内容长度不能超过 {max} 个字符")
     private String content;
     private String content;
 
 
+    /**
+     * 向量嵌入(float数组)
+     */
+    @Schema(description = "向量嵌入,存储为JSON格式的float数组")
+    @TableField(typeHandler = FloatArrayTypeHandler.class)
+    private float[] vector;
+
     // /**
     // /**
     //  * 创建人
     //  * 创建人
     //  */
     //  */

+ 4 - 0
pavis-module-aigc/src/main/java/com/pavis/admin/aigc/model/req/ModelReq.java

@@ -98,6 +98,10 @@ public class ModelReq implements Serializable {
     @Schema(description = "核心采样概率")
     @Schema(description = "核心采样概率")
     private Double topP;
     private Double topP;
 
 
+    /**
+     * 向量维度
+     */
+    private Integer dimension;
     // /**
     // /**
     //  * 创建人
     //  * 创建人
     //  */
     //  */

+ 59 - 0
pavis-module-aigc/src/main/java/com/pavis/admin/aigc/model/req/SimilaritySearchReq.java

@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2022-present zez Authors. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.pavis.admin.aigc.model.req;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 相似性搜索请求类,用于封装相似性搜索的请求参数
+ */
+@Data
+@NoArgsConstructor
+public class SimilaritySearchReq {
+
+    /**
+     * 搜索框中的关键词
+     */
+    @Schema(description = "搜索关键词", example = "人工智能")
+    private String keyword;
+
+    /**
+     * 最大结果数量
+     */
+    @Schema(description = "最大结果数量,默认5")
+    private Integer maxResults = 5;
+
+    /**
+     * 最小相似度分数
+     */
+    @Schema(description = "最小相似度分数,默认0")
+    private Double minScore = 0D;
+
+    /**
+     * 知识库ID,用于指定搜索的知识库范围
+     */
+    @Schema(description = "知识库ID")
+    private Long knowledgeId;
+
+    /**
+     * 文档ID,用于指定搜索的文档范围
+     */
+    @Schema(description = "文档ID")
+    private Long documentId;
+}

+ 9 - 0
pavis-module-aigc/src/main/java/com/pavis/admin/aigc/model/resp/DocChunkResp.java

@@ -1,5 +1,7 @@
 package com.pavis.admin.aigc.model.resp;
 package com.pavis.admin.aigc.model.resp;
 
 
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.pavis.admin.aigc.common.utils.FloatArrayTypeHandler;
 import lombok.Data;
 import lombok.Data;
 
 
 import io.swagger.v3.oas.annotations.media.Schema;
 import io.swagger.v3.oas.annotations.media.Schema;
@@ -98,4 +100,11 @@ public class DocChunkResp extends BaseResp {
      * 文档名称
      * 文档名称
      */
      */
     private String name;
     private String name;
+
+    /**
+     * 向量嵌入(float数组)
+     */
+    @Schema(description = "向量嵌入,存储为JSON格式的float数组")
+    @TableField(typeHandler = FloatArrayTypeHandler.class)
+    private float[] vector;
 }
 }

+ 69 - 0
pavis-module-aigc/src/main/java/com/pavis/admin/aigc/model/resp/SimilaritySearchResp.java

@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2022-present zez Authors. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.pavis.admin.aigc.model.resp;
+
+import com.pavis.admin.aigc.model.entity.DocDO;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 相似性搜索响应类,用于封装相似性搜索的结果
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class SimilaritySearchResp {
+
+    /**
+     * 嵌入ID
+     */
+    @Schema(description = "嵌入ID")
+    private Long embeddingId;
+
+    /**
+     * 相似度分数
+     */
+    @Schema(description = "相似度分数", example = "0.95")
+    private Double score;
+
+    /**
+     * 文本片段
+     */
+    @Schema(description = "文本片段", example = "这是与查询相关的文本内容")
+    private String segment;
+
+    /**
+     * 向量
+     */
+    @Schema(description = "向量", example = "[0.1, 0.2, 0.3, ...]")
+    private float[] vector;
+
+    /**
+     * 关联的文档信息
+     */
+    @Schema(description = "嵌入关联的文档信息")
+    private DocDO document;
+
+    public SimilaritySearchResp(Long embeddingId, Double score, String segment, DocDO document) {
+        this.embeddingId = embeddingId;
+        this.score = score;
+        this.segment = segment;
+        this.document = document;
+    }
+}

+ 28 - 0
pavis-module-aigc/src/main/java/com/pavis/admin/aigc/service/AgentService.java

@@ -1,5 +1,8 @@
 package com.pavis.admin.aigc.service;
 package com.pavis.admin.aigc.service;
 
 
+import com.pavis.admin.aigc.model.entity.AgentKnowledgeDO;
+import com.pavis.admin.aigc.model.entity.KnowledgeDO;
+import com.pavis.admin.aigc.model.entity.ToolDO;
 import top.continew.starter.extension.crud.service.BaseService;
 import top.continew.starter.extension.crud.service.BaseService;
 import com.pavis.admin.aigc.model.query.AgentQuery;
 import com.pavis.admin.aigc.model.query.AgentQuery;
 import com.pavis.admin.aigc.model.req.AgentReq;
 import com.pavis.admin.aigc.model.req.AgentReq;
@@ -30,4 +33,29 @@ public interface AgentService extends BaseService<AgentResp, AgentDetailResp, Ag
      * @return 可用的智能体列表
      * @return 可用的智能体列表
      */
      */
     List<AgentResp> getAll();
     List<AgentResp> getAll();
+
+    /**
+     * 根据智能体ID获取关联知识库
+     *
+     * @param agentId 智能体ID
+     * @return 智能体关联知识库
+     */
+    KnowledgeDO selAgentKnowList(Long agentId);
+
+    /**
+     * 根据智能体ID获取tool
+     *
+     * @param agentId 智能体ID
+     * @return tool详情
+     */
+    List<ToolDO> selTool(Long agentId);
+
+    /**
+     * 删除智能体关联工具
+     *
+     * @param toolId 工具类Id
+     */
+    void delToolToAgent(Long toolId);
+
+
 }
 }

+ 7 - 1
pavis-module-aigc/src/main/java/com/pavis/admin/aigc/service/DocChunkService.java

@@ -1,15 +1,21 @@
 package com.pavis.admin.aigc.service;
 package com.pavis.admin.aigc.service;
 
 
+import com.pavis.admin.aigc.model.req.SimilaritySearchReq;
+import com.pavis.admin.aigc.model.resp.SimilaritySearchResp;
 import top.continew.starter.extension.crud.service.BaseService;
 import top.continew.starter.extension.crud.service.BaseService;
 import com.pavis.admin.aigc.model.query.DocChunkQuery;
 import com.pavis.admin.aigc.model.query.DocChunkQuery;
 import com.pavis.admin.aigc.model.req.DocChunkReq;
 import com.pavis.admin.aigc.model.req.DocChunkReq;
 import com.pavis.admin.aigc.model.resp.DocChunkDetailResp;
 import com.pavis.admin.aigc.model.resp.DocChunkDetailResp;
 import com.pavis.admin.aigc.model.resp.DocChunkResp;
 import com.pavis.admin.aigc.model.resp.DocChunkResp;
 
 
+import java.util.List;
+
 /**
 /**
  * 文档切片业务接口
  * 文档切片业务接口
  *
  *
  * @author semi
  * @author semi
  * @since 2025/05/26 17:28
  * @since 2025/05/26 17:28
  */
  */
-public interface DocChunkService extends BaseService<DocChunkResp, DocChunkDetailResp, DocChunkQuery, DocChunkReq> {}
+public interface DocChunkService extends BaseService<DocChunkResp, DocChunkDetailResp, DocChunkQuery, DocChunkReq> {
+    List<SimilaritySearchResp> SimilaritySearch(SimilaritySearchReq req);
+}

+ 2 - 0
pavis-module-aigc/src/main/java/com/pavis/admin/aigc/service/KnowledgeService.java

@@ -20,6 +20,8 @@ public interface KnowledgeService extends BaseService<KnowledgeResp, KnowledgeDe
 
 
     void addDocs(DocDO data);
     void addDocs(DocDO data);
 
 
+    void delKnowAndDocAndSlice(Long knowId);
+
     // void addDocsSlice(DocChunkDO data);
     // void addDocsSlice(DocChunkDO data);
 
 
     // void updateDocs(DocDO data);
     // void updateDocs(DocDO data);

+ 50 - 0
pavis-module-aigc/src/main/java/com/pavis/admin/aigc/service/impl/AgentServiceImpl.java

@@ -1,16 +1,27 @@
 package com.pavis.admin.aigc.service.impl;
 package com.pavis.admin.aigc.service.impl;
 
 
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.pavis.admin.aigc.mapper.AgentKnowledgeMapper;
 import com.pavis.admin.aigc.mapper.AgentMapper;
 import com.pavis.admin.aigc.mapper.AgentMapper;
+import com.pavis.admin.aigc.mapper.AgentToolMapper;
+import com.pavis.admin.aigc.mapper.KnowledgeMapper;
+import com.pavis.admin.aigc.mapper.ToolMapper;
 import com.pavis.admin.aigc.model.entity.AgentDO;
 import com.pavis.admin.aigc.model.entity.AgentDO;
+import com.pavis.admin.aigc.model.entity.AgentKnowledgeDO;
+import com.pavis.admin.aigc.model.entity.AgentToolDO;
+import com.pavis.admin.aigc.model.entity.KnowledgeDO;
+import com.pavis.admin.aigc.model.entity.ToolDO;
 import com.pavis.admin.aigc.model.query.AgentQuery;
 import com.pavis.admin.aigc.model.query.AgentQuery;
 import com.pavis.admin.aigc.model.req.AgentReq;
 import com.pavis.admin.aigc.model.req.AgentReq;
 import com.pavis.admin.aigc.model.resp.AgentDetailResp;
 import com.pavis.admin.aigc.model.resp.AgentDetailResp;
 import com.pavis.admin.aigc.model.resp.AgentResp;
 import com.pavis.admin.aigc.model.resp.AgentResp;
 import com.pavis.admin.aigc.service.AgentService;
 import com.pavis.admin.aigc.service.AgentService;
+import jakarta.annotation.Resource;
 import lombok.RequiredArgsConstructor;
 import lombok.RequiredArgsConstructor;
 import org.springframework.stereotype.Service;
 import org.springframework.stereotype.Service;
 import top.continew.starter.extension.crud.service.BaseServiceImpl;
 import top.continew.starter.extension.crud.service.BaseServiceImpl;
 
 
+import java.util.ArrayList;
 import java.util.List;
 import java.util.List;
 
 
 /**
 /**
@@ -22,6 +33,18 @@ import java.util.List;
 @Service
 @Service
 @RequiredArgsConstructor
 @RequiredArgsConstructor
 public class AgentServiceImpl extends BaseServiceImpl<AgentMapper, AgentDO, AgentResp, AgentDetailResp, AgentQuery, AgentReq> implements AgentService {
 public class AgentServiceImpl extends BaseServiceImpl<AgentMapper, AgentDO, AgentResp, AgentDetailResp, AgentQuery, AgentReq> implements AgentService {
+    @Resource
+    private AgentKnowledgeMapper agentKnowledgeMapper;
+
+    @Resource
+    private KnowledgeMapper knowledgeMapper;
+
+    @Resource
+    private AgentToolMapper agentToolMapper;
+
+    @Resource
+    private ToolMapper toolMapper;
+
     @Override
     @Override
     public AgentResp getByCode(String agentCode) {
     public AgentResp getByCode(String agentCode) {
         return baseMapper.selectByCode(agentCode);
         return baseMapper.selectByCode(agentCode);
@@ -31,4 +54,31 @@ public class AgentServiceImpl extends BaseServiceImpl<AgentMapper, AgentDO, Agen
     public List<AgentResp> getAll() {
     public List<AgentResp> getAll() {
         return baseMapper.selectAgentList();
         return baseMapper.selectAgentList();
     }
     }
+
+    @Override
+    public KnowledgeDO selAgentKnowList(Long agentId) {
+        // 获取knowledgeId
+        AgentKnowledgeDO agentKnowledge = agentKnowledgeMapper.selectOne(new QueryWrapper<AgentKnowledgeDO>()
+                .eq("agent_id", agentId));
+        // 获取知识库详情
+        return knowledgeMapper.selectById(agentKnowledge.getKnowledgeId());
+    }
+
+    @Override
+    public List<ToolDO> selTool(Long agentId) {
+        List<ToolDO> list = new ArrayList<>();
+        List<AgentToolDO> agentToolList = agentToolMapper.selectList(new QueryWrapper<AgentToolDO>()
+                .eq("agent_id", agentId));
+        if (!agentToolList.isEmpty()) {
+            for (AgentToolDO agentToolDO : agentToolList) {
+                list.add(toolMapper.selectById(agentToolDO.getToolId()));
+            }
+        }
+        return list;
+    }
+
+    public void delToolToAgent(Long toolId){
+        toolMapper.delete(new QueryWrapper<ToolDO>()
+                .eq("tool_id",toolId));
+    }
 }
 }

+ 0 - 1
pavis-module-aigc/src/main/java/com/pavis/admin/aigc/service/impl/AigcAppServiceImpl.java

@@ -37,7 +37,6 @@ import jakarta.annotation.PostConstruct;
 import lombok.RequiredArgsConstructor;
 import lombok.RequiredArgsConstructor;
 
 
 import lombok.extern.slf4j.Slf4j;
 import lombok.extern.slf4j.Slf4j;
-import org.springframework.stereotype.Component;
 import org.springframework.stereotype.Service;
 import org.springframework.stereotype.Service;
 
 
 import top.continew.starter.core.exception.BusinessException;
 import top.continew.starter.core.exception.BusinessException;

+ 116 - 1
pavis-module-aigc/src/main/java/com/pavis/admin/aigc/service/impl/DocChunkServiceImpl.java

@@ -1,9 +1,24 @@
 package com.pavis.admin.aigc.service.impl;
 package com.pavis.admin.aigc.service.impl;
 
 
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.pavis.admin.aigc.mapper.DocMapper;
+import com.pavis.admin.aigc.model.entity.DocDO;
+import com.pavis.admin.aigc.model.req.SimilaritySearchReq;
+import com.pavis.admin.aigc.model.resp.SimilaritySearchResp;
+import dev.langchain4j.data.embedding.Embedding;
+import dev.langchain4j.data.segment.TextSegment;
+import dev.langchain4j.model.embedding.EmbeddingModel;
+import dev.langchain4j.store.embedding.CosineSimilarity;
+import dev.langchain4j.store.embedding.EmbeddingStore;
+import dev.langchain4j.store.embedding.RelevanceScore;
+import jakarta.annotation.Resource;
 import lombok.RequiredArgsConstructor;
 import lombok.RequiredArgsConstructor;
 
 
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.data.redis.core.RedisTemplate;
 import org.springframework.stereotype.Service;
 import org.springframework.stereotype.Service;
 
 
+import top.continew.starter.cache.redisson.util.RedisUtils;
 import top.continew.starter.extension.crud.service.BaseServiceImpl;
 import top.continew.starter.extension.crud.service.BaseServiceImpl;
 import com.pavis.admin.aigc.mapper.DocChunkMapper;
 import com.pavis.admin.aigc.mapper.DocChunkMapper;
 import com.pavis.admin.aigc.model.entity.DocChunkDO;
 import com.pavis.admin.aigc.model.entity.DocChunkDO;
@@ -13,6 +28,14 @@ import com.pavis.admin.aigc.model.resp.DocChunkDetailResp;
 import com.pavis.admin.aigc.model.resp.DocChunkResp;
 import com.pavis.admin.aigc.model.resp.DocChunkResp;
 import com.pavis.admin.aigc.service.DocChunkService;
 import com.pavis.admin.aigc.service.DocChunkService;
 
 
+import java.util.ArrayList;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.PriorityQueue;
+import java.util.stream.Collectors;
+
 /**
 /**
  * 文档切片业务实现
  * 文档切片业务实现
  *
  *
@@ -21,4 +44,96 @@ import com.pavis.admin.aigc.service.DocChunkService;
  */
  */
 @Service
 @Service
 @RequiredArgsConstructor
 @RequiredArgsConstructor
-public class DocChunkServiceImpl extends BaseServiceImpl<DocChunkMapper, DocChunkDO, DocChunkResp, DocChunkDetailResp, DocChunkQuery, DocChunkReq> implements DocChunkService {}
+@Slf4j
+public class DocChunkServiceImpl extends BaseServiceImpl<DocChunkMapper, DocChunkDO, DocChunkResp, DocChunkDetailResp, DocChunkQuery, DocChunkReq> implements DocChunkService {
+    // @Resource
+    // private EmbeddingModel embeddingModel;
+
+    @Resource
+    private DocMapper docMapper;
+
+    @Resource
+    private DocServiceImpl docService;
+
+    public List<SimilaritySearchResp> SimilaritySearch(SimilaritySearchReq req) {
+        EmbeddingModel embeddingModel = docService.getEmbeddingModel(req.getKnowledgeId());
+        // 向量化搜索文本
+        Embedding keywordEmbedding = embeddingModel.embed(req.getKeyword()).content();
+
+        // 从数据库查询嵌入数据
+        List<DocChunkDO> embeddings;
+        LambdaQueryWrapper<DocChunkDO> queryWrapper = new LambdaQueryWrapper<>();
+        if (req.getDocumentId() != null) {
+            queryWrapper.eq(DocChunkDO::getDocId, req.getDocumentId());
+        } else if (req.getKnowledgeId() != null) {
+            LambdaQueryWrapper<DocDO> docQueryWrapper = new LambdaQueryWrapper<>();
+            docQueryWrapper.eq(DocDO::getKnowledgeId, req.getKnowledgeId());
+            List<DocDO> documents = docMapper.selectList(docQueryWrapper);
+            List<Long> documentIds = documents.stream().map(DocDO::getId).collect(Collectors.toList());
+            if (!documentIds.isEmpty()) {
+                queryWrapper.in(DocChunkDO::getDocId, documentIds);
+            } else {
+                queryWrapper.eq(DocChunkDO::getId, -1L); // 无匹配的文档 ID 时查询无结果
+            }
+        }
+        embeddings = baseMapper.selectList(queryWrapper);
+
+        Map<Long, DocDO> documentMap = new HashMap<>();
+        if (!embeddings.isEmpty()) {
+            List<Long> documentIds = embeddings.stream()
+                    .map(DocChunkDO::getDocId)
+                    .distinct()
+                    .collect(Collectors.toList());
+            if (!documentIds.isEmpty()) {
+                List<DocDO> documents = docMapper.selectByIds(documentIds);
+                documentMap = documents.stream().collect(Collectors.toMap(DocDO::getId, document -> document));
+            }
+        }
+
+        // 比较器
+        Comparator<SimilaritySearchResp> comparator = Comparator.comparingDouble(SimilaritySearchResp::getScore);
+        PriorityQueue<SimilaritySearchResp> matches = new PriorityQueue<>(comparator);
+
+        // 初步构建查询结果
+        for (DocChunkDO embedding : embeddings) {
+            // log.info("向量库存储内容:{}",RedisUtils.get("embedding:" + embedding.getEmbedStoreId()));
+            // 计算相似度
+            float[] vector = stringToFloatArray(embedding.getVector());
+            double cosineSimilarity = CosineSimilarity.between(new Embedding(vector), keywordEmbedding);
+            // double cosineSimilarity = CosineSimilarity.between(new Embedding(embedding.getVector()), keywordEmbedding);
+            double score = RelevanceScore.fromCosineSimilarity(cosineSimilarity);
+
+            DocDO document = documentMap.get(embedding.getDocId());
+            if (score >= req.getMinScore() && document != null) {
+                SimilaritySearchResp resp = new SimilaritySearchResp(embedding.getId(), score, embedding
+                        .getContent(), document);
+                if (matches.size() < req.getMaxResults()) {
+                    matches.add(resp);
+                } else if (matches.peek() != null && score > matches.peek().getScore()) {
+                    matches.poll();
+                    matches.add(resp);
+                }
+            }
+        }
+
+        // 进一步构建查询结果
+        List<SimilaritySearchResp> resps = new ArrayList<>(matches);
+        resps.sort(comparator.reversed());
+        return resps;
+    }
+
+    public static float[] stringToFloatArray(String input) {
+        String[] parts = input.split(",");
+        float[] result = new float[parts.length];
+
+        try {
+            for (int i = 0; i < parts.length; i++) {
+                result[i] = Float.parseFloat(parts[i].trim());
+            }
+        } catch (NumberFormatException e) {
+            System.err.println("输入的字符串格式不正确: " + input);
+            throw e;
+        }
+        return result;
+    }
+}

+ 47 - 26
pavis-module-aigc/src/main/java/com/pavis/admin/aigc/service/impl/DocServiceImpl.java

@@ -15,7 +15,6 @@ import com.pavis.admin.aigc.model.resp.KnowledgeResp;
 import com.pavis.admin.aigc.service.KnowledgeService;
 import com.pavis.admin.aigc.service.KnowledgeService;
 import dev.langchain4j.data.document.Document;
 import dev.langchain4j.data.document.Document;
 import dev.langchain4j.data.document.DocumentSplitter;
 import dev.langchain4j.data.document.DocumentSplitter;
-import dev.langchain4j.data.document.loader.FileSystemDocumentLoader;
 import dev.langchain4j.data.document.loader.UrlDocumentLoader;
 import dev.langchain4j.data.document.loader.UrlDocumentLoader;
 import dev.langchain4j.data.document.parser.apache.tika.ApacheTikaDocumentParser;
 import dev.langchain4j.data.document.parser.apache.tika.ApacheTikaDocumentParser;
 import dev.langchain4j.data.embedding.Embedding;
 import dev.langchain4j.data.embedding.Embedding;
@@ -24,7 +23,6 @@ import dev.langchain4j.model.embedding.EmbeddingModel;
 import dev.langchain4j.store.embedding.EmbeddingStore;
 import dev.langchain4j.store.embedding.EmbeddingStore;
 import jakarta.annotation.Resource;
 import jakarta.annotation.Resource;
 import lombok.AllArgsConstructor;
 import lombok.AllArgsConstructor;
-import lombok.RequiredArgsConstructor;
 
 
 import lombok.extern.slf4j.Slf4j;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.stereotype.Service;
 import org.springframework.stereotype.Service;
@@ -68,29 +66,36 @@ public class DocServiceImpl extends BaseServiceImpl<DocMapper, DocDO, DocResp, D
 
 
     @Override
     @Override
     public void embedDocsSlice(DocDO data, String url) {
     public void embedDocsSlice(DocDO data, String url) {
-        List<EmbeddingR> list = embeddingDocs(new ChatReq()
-                .setDocsName(data.getName())
-                .setKnowledgeId(data.getKnowledgeId().toString())
-                .setUrl(url));
-        list.forEach(i -> {
-            DocChunkDO docChunkDO = new DocChunkDO();
-            docChunkDO.setKnowledgeId(data.getKnowledgeId());
-            docChunkDO.setDocId(data.getId());
-            docChunkDO.setEmbedStoreId(i.getVectorId());
-            docChunkDO.setContent(i.getText());
-            docChunkDO.setCreateUser(data.getCreateUser());
-            docChunkDO.setWordNum(i.getText().length());
-            docChunkDO.setName(data.getName());
-            // knowledgeService.addDocsSlice(docChunkDO);
-            docChunkMapper.insert(docChunkDO);
-        });
-
-        DocDO docDO = new DocDO();
-        docDO.setId(data.getId());
-        docDO.setVectorStatus("completed");
-        docDO.setSliceNum(list.size());
-        docDO.setUpdateUser(data.getCreateUser());
-        baseMapper.updateById(docDO);
+            List<EmbeddingR> list = embeddingDocs(new ChatReq().setDocsName(data.getName())
+                    .setKnowledgeId(data.getKnowledgeId().toString())
+                    .setUrl(url));
+            list.forEach(i -> {
+                DocChunkDO docChunkDO = new DocChunkDO();
+                docChunkDO.setKnowledgeId(data.getKnowledgeId());
+                docChunkDO.setDocId(data.getId());
+                docChunkDO.setEmbedStoreId(i.getVectorId());
+                docChunkDO.setContent(i.getText());
+                docChunkDO.setCreateUser(data.getCreateUser());
+                docChunkDO.setWordNum(i.getText().length());
+                docChunkDO.setName(data.getName());
+                docChunkDO.setVector(floatArrayToString(i.getVector()));
+                // knowledgeService.addDocsSlice(docChunkDO);
+                docChunkMapper.insert(docChunkDO);
+
+                DocDO docDO = new DocDO();
+                docDO.setId(data.getId());
+                docDO.setVectorStatus("during"); // 训练中
+                docDO.setSliceNum(0);
+                docDO.setUpdateUser(data.getCreateUser());
+                baseMapper.updateById(docDO);
+            });
+
+            DocDO docDO = new DocDO();
+            docDO.setId(data.getId());
+            docDO.setVectorStatus("completed"); // 已完成
+            docDO.setSliceNum(list.size());
+            docDO.setUpdateUser(data.getCreateUser());
+            baseMapper.updateById(docDO);
     }
     }
 
 
     public List<EmbeddingR> embeddingDocs(ChatReq req) {
     public List<EmbeddingR> embeddingDocs(ChatReq req) {
@@ -108,7 +113,7 @@ public class DocServiceImpl extends BaseServiceImpl<DocMapper, DocDO, DocResp, D
             List<String> ids = embeddingStore.addAll(embeddings, segments);
             List<String> ids = embeddingStore.addAll(embeddings, segments);
 
 
             for (int i = 0; i < ids.size(); i++) {
             for (int i = 0; i < ids.size(); i++) {
-                list.add(new EmbeddingR().setVectorId(ids.get(i)).setText(segments.get(i).text()));
+                list.add(new EmbeddingR().setVectorId(ids.get(i)).setText(segments.get(i).text()).setVector(embeddings.get(i).vector()));
             }
             }
         } catch (Exception e) {
         } catch (Exception e) {
             e.printStackTrace();
             e.printStackTrace();
@@ -155,4 +160,20 @@ public class DocServiceImpl extends BaseServiceImpl<DocMapper, DocDO, DocResp, D
         // remove from docSlice
         // remove from docSlice
         aigcKnowledgeService.removeSlicesOfDoc(docsId);
         aigcKnowledgeService.removeSlicesOfDoc(docsId);
     }
     }
+
+    public static String floatArrayToString(float[] array) {
+        if (array == null) {
+            return null;
+        }
+
+        StringBuilder sb = new StringBuilder();
+        for (int i = 0; i < array.length; i++) {
+            sb.append(array[i]);
+            if (i < array.length - 1) {
+                sb.append(",");
+            }
+        }
+
+        return sb.toString();
+    }
 }
 }

+ 20 - 1
pavis-module-aigc/src/main/java/com/pavis/admin/aigc/service/impl/EmbedStoreServiceImpl.java

@@ -1,8 +1,21 @@
 package com.pavis.admin.aigc.service.impl;
 package com.pavis.admin.aigc.service.impl;
 
 
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.pavis.admin.aigc.mapper.DocMapper;
+import com.pavis.admin.aigc.model.entity.DocChunkDO;
+import com.pavis.admin.aigc.model.entity.DocDO;
+import com.pavis.admin.aigc.model.req.SimilaritySearchReq;
+import com.pavis.admin.aigc.model.resp.SimilaritySearchResp;
+import com.pavis.admin.aigc.service.DocService;
+import dev.langchain4j.data.embedding.Embedding;
+import dev.langchain4j.model.embedding.EmbeddingModel;
+import dev.langchain4j.store.embedding.CosineSimilarity;
+import dev.langchain4j.store.embedding.RelevanceScore;
+import jakarta.annotation.Resource;
 import lombok.RequiredArgsConstructor;
 import lombok.RequiredArgsConstructor;
 
 
 import lombok.extern.slf4j.Slf4j;
 import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.stereotype.Service;
 
 
 import top.continew.starter.extension.crud.service.BaseServiceImpl;
 import top.continew.starter.extension.crud.service.BaseServiceImpl;
@@ -14,7 +27,13 @@ import com.pavis.admin.aigc.model.resp.EmbedStoreDetailResp;
 import com.pavis.admin.aigc.model.resp.EmbedStoreResp;
 import com.pavis.admin.aigc.model.resp.EmbedStoreResp;
 import com.pavis.admin.aigc.service.EmbedStoreService;
 import com.pavis.admin.aigc.service.EmbedStoreService;
 
 
+import java.util.ArrayList;
+import java.util.Comparator;
+import java.util.HashMap;
 import java.util.List;
 import java.util.List;
+import java.util.Map;
+import java.util.PriorityQueue;
+import java.util.stream.Collectors;
 
 
 /**
 /**
  * 向量存储配置业务实现
  * 向量存储配置业务实现
@@ -26,12 +45,12 @@ import java.util.List;
 @Slf4j
 @Slf4j
 @RequiredArgsConstructor
 @RequiredArgsConstructor
 public class EmbedStoreServiceImpl extends BaseServiceImpl<EmbedStoreMapper, EmbedStoreDO, EmbedStoreResp, EmbedStoreDetailResp, EmbedStoreQuery, EmbedStoreReq> implements EmbedStoreService {
 public class EmbedStoreServiceImpl extends BaseServiceImpl<EmbedStoreMapper, EmbedStoreDO, EmbedStoreResp, EmbedStoreDetailResp, EmbedStoreQuery, EmbedStoreReq> implements EmbedStoreService {
-
     @Override
     @Override
     public List<EmbedStoreResp> selEmbedStore() {
     public List<EmbedStoreResp> selEmbedStore() {
         return baseMapper.selEmbedStore();
         return baseMapper.selEmbedStore();
     }
     }
 
 
+
     // @Override
     // @Override
     // @Transactional
     // @Transactional
     // public void clearDocSlices(String docsId) {
     // public void clearDocSlices(String docsId) {

+ 71 - 58
pavis-module-aigc/src/main/java/com/pavis/admin/aigc/service/impl/KnowledgeServiceImpl.java

@@ -1,6 +1,7 @@
 package com.pavis.admin.aigc.service.impl;
 package com.pavis.admin.aigc.service.impl;
 
 
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.pavis.admin.aigc.mapper.DocChunkMapper;
 import com.pavis.admin.aigc.mapper.DocChunkMapper;
 import com.pavis.admin.aigc.mapper.DocMapper;
 import com.pavis.admin.aigc.mapper.DocMapper;
@@ -12,6 +13,7 @@ import lombok.extern.slf4j.Slf4j;
 import org.springframework.stereotype.Service;
 import org.springframework.stereotype.Service;
 
 
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.transaction.annotation.Transactional;
+import top.continew.starter.cache.redisson.util.RedisUtils;
 import top.continew.starter.extension.crud.service.BaseServiceImpl;
 import top.continew.starter.extension.crud.service.BaseServiceImpl;
 import com.pavis.admin.aigc.mapper.KnowledgeMapper;
 import com.pavis.admin.aigc.mapper.KnowledgeMapper;
 import com.pavis.admin.aigc.model.entity.KnowledgeDO;
 import com.pavis.admin.aigc.model.entity.KnowledgeDO;
@@ -47,81 +49,92 @@ public class KnowledgeServiceImpl extends BaseServiceImpl<KnowledgeMapper, Knowl
     public void addDocs(DocDO data) {
     public void addDocs(DocDO data) {
         aigcDocsMapper.insert(data);
         aigcDocsMapper.insert(data);
     }
     }
+    @Override
+    @Transactional
+    public void delKnowAndDocAndSlice(Long knowId) {
+        // 1. 根据知识库ID删除知识库,文件和切片
+        aigcDocsSliceMapper.delete(new QueryWrapper<DocChunkDO>()
+                .eq("knowledge_id", knowId));
+        aigcDocsMapper.delete(new QueryWrapper<DocDO>()
+                .eq("knowledge_id", knowId));
+        baseMapper.deleteById(knowId);
 
 
-    // @Override
-    // @Transactional
-    // public void addDocsSlice(DocChunkDO data) {
-    //     aigcDocsSliceMapper.insert(data);
-    // }
-
-    // @Override
-    // @Transactional
-    // public void updateDocs(DocDO data) {
-    //     aigcDocsMapper.updateById(data);
-    // }
-
-    // @Override
-    // @Transactional
-    // public void addDocs(AigcDocs data) {
-    //     data.setCreateTime(new Date());
-    //     aigcDocsMapper.insert(data);
-    // }
-
-    // @Override
-    // @Transactional
-    // public void updateDocs(AigcDocs data) {
-    //     aigcDocsMapper.updateById(data);
-    // }
-
-    // @Override
-    // @Transactional
-    // public void addDocsSlice(AigcDocsSlice data) {
-    //     data.setCreateTime(new Date())
-    //             .setWordNum(data.getContent().length())
-    //             .setStatus(true)
-    //     ;
-    //     aigcDocsSliceMapper.insert(data);
-    // }
+    }
 
 
-    // @Override
-    // @Transactional
-    // public void updateDocsSlice(AigcDocsSlice data) {
-    //     aigcDocsSliceMapper.updateById(data);
-    // }
+// @Override
+// @Transactional
+// public void addDocsSlice(DocChunkDO data) {
+//     aigcDocsSliceMapper.insert(data);
+// }
+
+// @Override
+// @Transactional
+// public void updateDocs(DocDO data) {
+//     aigcDocsMapper.updateById(data);
+// }
+
+// @Override
+// @Transactional
+// public void addDocs(AigcDocs data) {
+//     data.setCreateTime(new Date());
+//     aigcDocsMapper.insert(data);
+// }
+
+// @Override
+// @Transactional
+// public void updateDocs(AigcDocs data) {
+//     aigcDocsMapper.updateById(data);
+// }
+
+// @Override
+// @Transactional
+// public void addDocsSlice(AigcDocsSlice data) {
+//     data.setCreateTime(new Date())
+//             .setWordNum(data.getContent().length())
+//             .setStatus(true)
+//     ;
+//     aigcDocsSliceMapper.insert(data);
+// }
+
+// @Override
+// @Transactional
+// public void updateDocsSlice(AigcDocsSlice data) {
+//     aigcDocsSliceMapper.updateById(data);
+// }
 
 
     @Override
     @Override
     public List<String> listSliceVectorIdsOfDoc(String docsId) {
     public List<String> listSliceVectorIdsOfDoc(String docsId) {
         LambdaQueryWrapper<DocChunkDO> selectWrapper = Wrappers.<DocChunkDO>lambdaQuery()
         LambdaQueryWrapper<DocChunkDO> selectWrapper = Wrappers.<DocChunkDO>lambdaQuery()
-            .select(DocChunkDO::getEmbedStoreId)
-            .eq(DocChunkDO::getDocId, docsId);
+                .select(DocChunkDO::getEmbedStoreId)
+                .eq(DocChunkDO::getDocId, docsId);
         List<String> vectorIds = aigcDocsSliceMapper.selectList(selectWrapper)
         List<String> vectorIds = aigcDocsSliceMapper.selectList(selectWrapper)
-            .stream()
-            .map(DocChunkDO::getEmbedStoreId)
-            .toList();
+                .stream()
+                .map(DocChunkDO::getEmbedStoreId)
+                .toList();
         log.debug("slices of doc: [{}], count: [{}]", docsId, vectorIds.size());
         log.debug("slices of doc: [{}], count: [{}]", docsId, vectorIds.size());
         return vectorIds;
         return vectorIds;
     }
     }
 
 
-    // @Override
-    // public List<AigcDocs> getDocsByKb(String knowledgeId) {
-    //     return aigcDocsMapper.selectList(Wrappers.<AigcDocs>lambdaQuery()
-    //             .eq(AigcDocs::getKnowledgeId, knowledgeId));
-    // }
+// @Override
+// public List<AigcDocs> getDocsByKb(String knowledgeId) {
+//     return aigcDocsMapper.selectList(Wrappers.<AigcDocs>lambdaQuery()
+//             .eq(AigcDocs::getKnowledgeId, knowledgeId));
+// }
 
 
     // @Override
     // @Override
-    // @Transactional
-    // public void removeKnowledge(String knowledgeId) {
-    //     baseMapper.deleteById(knowledgeId);
-    //     // del docs & docsSlice
-    //     List<String> docsIds = getDocsByKb(knowledgeId).stream().map(AigcDocs::getId).toList();
-    //     docsIds.forEach(this::removeSlicesOfDoc);
-    // }
-    //
+// @Transactional
+// public void removeKnowledge(String knowledgeId) {
+//     baseMapper.deleteById(knowledgeId);
+//     // del docs & docsSlice
+//     List<String> docsIds = getDocsByKb(knowledgeId).stream().map(AigcDocs::getId).toList();
+//     docsIds.forEach(this::removeSlicesOfDoc);
+// }
+//
     @Override
     @Override
     @Transactional
     @Transactional
     public void removeSlicesOfDoc(String docsId) {
     public void removeSlicesOfDoc(String docsId) {
         LambdaQueryWrapper<DocChunkDO> deleteWrapper = Wrappers.<DocChunkDO>lambdaQuery()
         LambdaQueryWrapper<DocChunkDO> deleteWrapper = Wrappers.<DocChunkDO>lambdaQuery()
-            .eq(DocChunkDO::getDocId, docsId);
+                .eq(DocChunkDO::getDocId, docsId);
         int count = aigcDocsSliceMapper.delete(deleteWrapper);
         int count = aigcDocsSliceMapper.delete(deleteWrapper);
         log.debug("remove all slices of doc: [{}], count: [{}]", docsId, count);
         log.debug("remove all slices of doc: [{}], count: [{}]", docsId, count);
     }
     }

+ 6 - 0
pavis-module-aigc/src/main/java/com/pavis/admin/aigc/service/impl/ModelServiceImpl.java

@@ -6,6 +6,7 @@ import cn.hutool.core.util.StrUtil;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.pavis.admin.aigc.constant.ModelConst;
 import com.pavis.admin.aigc.constant.ModelConst;
+import com.pavis.admin.aigc.core.SpringContextHolder;
 import com.pavis.admin.aigc.core.llm.provider.build.ModelBuildHandler;
 import com.pavis.admin.aigc.core.llm.provider.build.ModelBuildHandler;
 import com.pavis.admin.aigc.enums.ModelTypeEnum;
 import com.pavis.admin.aigc.enums.ModelTypeEnum;
 import com.pavis.admin.aigc.mapper.ModelSecretMapper;
 import com.pavis.admin.aigc.mapper.ModelSecretMapper;
@@ -15,6 +16,7 @@ import dev.langchain4j.model.chat.StreamingChatLanguageModel;
 import dev.langchain4j.model.embedding.EmbeddingModel;
 import dev.langchain4j.model.embedding.EmbeddingModel;
 import dev.langchain4j.model.image.ImageModel;
 import dev.langchain4j.model.image.ImageModel;
 import jakarta.annotation.PostConstruct;
 import jakarta.annotation.PostConstruct;
+import jakarta.annotation.Resource;
 import lombok.RequiredArgsConstructor;
 import lombok.RequiredArgsConstructor;
 
 
 import lombok.extern.slf4j.Slf4j;
 import lombok.extern.slf4j.Slf4j;
@@ -59,6 +61,9 @@ public class ModelServiceImpl extends BaseServiceImpl<ModelMapper, ModelDO, Mode
     private final Map<String, EmbeddingModel> embeddingModelMap = new ConcurrentHashMap<>();
     private final Map<String, EmbeddingModel> embeddingModelMap = new ConcurrentHashMap<>();
     private final Map<String, ImageModel> imageModelMap = new ConcurrentHashMap<>();
     private final Map<String, ImageModel> imageModelMap = new ConcurrentHashMap<>();
 
 
+    @Resource
+    private SpringContextHolder contextHolder;
+
     public void insModelAndSecret(ModelReq modelReq) {
     public void insModelAndSecret(ModelReq modelReq) {
         // 1. 将modelReq部分字段cope到modelDO实体中,并进行insert
         // 1. 将modelReq部分字段cope到modelDO实体中,并进行insert
         ModelDO modelDO = new ModelDO();
         ModelDO modelDO = new ModelDO();
@@ -98,6 +103,7 @@ public class ModelServiceImpl extends BaseServiceImpl<ModelMapper, ModelDO, Mode
             if (modelDO != null) {
             if (modelDO != null) {
                 modelSecretMapper.delete(new QueryWrapper<ModelSecretDO>().eq("model_id", modelDO.getId()));
                 modelSecretMapper.delete(new QueryWrapper<ModelSecretDO>().eq("model_id", modelDO.getId()));
                 baseMapper.deleteById(id);
                 baseMapper.deleteById(id);
+                contextHolder.unregisterBean(id.toString());
             }
             }
         }
         }
     }
     }

+ 3 - 3
pavis-module-system/src/main/java/com/pavis/admin/auth/AbstractLoginHandler.java

@@ -107,10 +107,10 @@ public abstract class AbstractLoginHandler<T extends LoginReq> implements LoginH
      */
      */
     protected void checkUserStatus(UserDO user) {
     protected void checkUserStatus(UserDO user) {
         CheckUtils.throwIfEqual(DisEnableStatusEnum.DISABLE, user.getStatus(), "此账号已被禁用,如有疑问,请联系管理员");
         CheckUtils.throwIfEqual(DisEnableStatusEnum.DISABLE, user.getStatus(), "此账号已被禁用,如有疑问,请联系管理员");
-        DeptDO dept=new DeptDO();
-        if(user.getDeptId()!=null) {
+        DeptDO dept = new DeptDO();
+        if (user.getDeptId() != null) {
             dept = deptService.getById(user.getDeptId());
             dept = deptService.getById(user.getDeptId());
-        }else {
+        } else {
             dept = deptService.getById(1);
             dept = deptService.getById(1);
         }
         }
         CheckUtils.throwIfEqual(DisEnableStatusEnum.DISABLE, dept.getStatus(), "此账号所属部门已被禁用,如有疑问,请联系管理员");
         CheckUtils.throwIfEqual(DisEnableStatusEnum.DISABLE, dept.getStatus(), "此账号所属部门已被禁用,如有疑问,请联系管理员");

+ 0 - 1
pavis-module-system/src/main/java/com/pavis/admin/auth/handler/PhoneLoginHandler.java

@@ -8,7 +8,6 @@ import com.pavis.admin.system.model.entity.UserRoleDO;
 import com.pavis.admin.system.service.UserRoleService;
 import com.pavis.admin.system.service.UserRoleService;
 import jakarta.annotation.Resource;
 import jakarta.annotation.Resource;
 import jakarta.servlet.http.HttpServletRequest;
 import jakarta.servlet.http.HttpServletRequest;
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
 import org.springframework.stereotype.Component;
 import com.pavis.admin.auth.AbstractLoginHandler;
 import com.pavis.admin.auth.AbstractLoginHandler;
 import com.pavis.admin.auth.enums.AuthTypeEnum;
 import com.pavis.admin.auth.enums.AuthTypeEnum;

+ 25 - 1
pavis-webapi/src/main/java/com/pavis/admin/controller/aigc/AgentController.java

@@ -1,5 +1,9 @@
 package com.pavis.admin.controller.aigc;
 package com.pavis.admin.controller.aigc;
 
 
+import com.pavis.admin.aigc.model.entity.AgentKnowledgeDO;
+import com.pavis.admin.aigc.model.entity.KnowledgeDO;
+import com.pavis.admin.aigc.model.entity.ToolDO;
+import io.swagger.v3.oas.annotations.Operation;
 import top.continew.starter.extension.crud.enums.Api;
 import top.continew.starter.extension.crud.enums.Api;
 
 
 import io.swagger.v3.oas.annotations.tags.Tag;
 import io.swagger.v3.oas.annotations.tags.Tag;
@@ -14,6 +18,8 @@ import com.pavis.admin.aigc.model.resp.AgentDetailResp;
 import com.pavis.admin.aigc.model.resp.AgentResp;
 import com.pavis.admin.aigc.model.resp.AgentResp;
 import com.pavis.admin.aigc.service.AgentService;
 import com.pavis.admin.aigc.service.AgentService;
 
 
+import java.util.List;
+
 /**
 /**
  * 智能体管理 API
  * 智能体管理 API
  *
  *
@@ -23,4 +29,22 @@ import com.pavis.admin.aigc.service.AgentService;
 @Tag(name = "AIGC智能体管理 API")
 @Tag(name = "AIGC智能体管理 API")
 @RestController
 @RestController
 @CrudRequestMapping(value = "/aigc/agent", api = {Api.PAGE, Api.GET, Api.CREATE, Api.UPDATE, Api.DELETE, Api.EXPORT})
 @CrudRequestMapping(value = "/aigc/agent", api = {Api.PAGE, Api.GET, Api.CREATE, Api.UPDATE, Api.DELETE, Api.EXPORT})
-public class AgentController extends BaseController<AgentService, AgentResp, AgentDetailResp, AgentQuery, AgentReq> {}
+public class AgentController extends BaseController<AgentService, AgentResp, AgentDetailResp, AgentQuery, AgentReq> {
+    @Operation(summary = "根据智能体ID获取关联知识库Know", description = "根据智能体ID获取关联知识库Know")
+    @PostMapping(value = "/selAgentKnowList/{agentId}")
+    public KnowledgeDO selAgentKnowList(@PathVariable Long agentId) {
+        return baseService.selAgentKnowList(agentId);
+    }
+
+    @Operation(summary = "根据智能体ID获取关联工具tool", description = "根据智能体ID获取关联工具tool")
+    @PostMapping(value = "/selTool/{agentId}")
+    public List<ToolDO> selTool(@PathVariable Long agentId) {
+        return baseService.selTool(agentId);
+    }
+
+    @Operation(summary = "根据工具ID删除智能体关联工具tool", description = "根据工具ID删除智能体关联工具tool")
+    @PostMapping(value = "/delToolToAgent/{toolId}")
+    public void delToolToAgent(@PathVariable Long toolId) {
+        baseService.delToolToAgent(toolId);
+    }
+}

+ 15 - 1
pavis-webapi/src/main/java/com/pavis/admin/controller/aigc/DocChunkController.java

@@ -1,5 +1,11 @@
 package com.pavis.admin.controller.aigc;
 package com.pavis.admin.controller.aigc;
 
 
+import com.pavis.admin.aigc.core.SpringContextHolder;
+import com.pavis.admin.aigc.event.ProviderRefreshEvent;
+import com.pavis.admin.aigc.model.req.ModelReq;
+import com.pavis.admin.aigc.model.req.SimilaritySearchReq;
+import com.pavis.admin.aigc.model.resp.SimilaritySearchResp;
+import io.swagger.v3.oas.annotations.Operation;
 import top.continew.starter.extension.crud.enums.Api;
 import top.continew.starter.extension.crud.enums.Api;
 
 
 import io.swagger.v3.oas.annotations.tags.Tag;
 import io.swagger.v3.oas.annotations.tags.Tag;
@@ -14,6 +20,8 @@ import com.pavis.admin.aigc.model.resp.DocChunkDetailResp;
 import com.pavis.admin.aigc.model.resp.DocChunkResp;
 import com.pavis.admin.aigc.model.resp.DocChunkResp;
 import com.pavis.admin.aigc.service.DocChunkService;
 import com.pavis.admin.aigc.service.DocChunkService;
 
 
+import java.util.List;
+
 /**
 /**
  * 文档切片管理 API
  * 文档切片管理 API
  *
  *
@@ -23,4 +31,10 @@ import com.pavis.admin.aigc.service.DocChunkService;
 @Tag(name = "AIGC文档切片管理 API")
 @Tag(name = "AIGC文档切片管理 API")
 @RestController
 @RestController
 @CrudRequestMapping(value = "/aigc/docChunk", api = {Api.PAGE, Api.GET, Api.CREATE, Api.UPDATE, Api.DELETE, Api.EXPORT})
 @CrudRequestMapping(value = "/aigc/docChunk", api = {Api.PAGE, Api.GET, Api.CREATE, Api.UPDATE, Api.DELETE, Api.EXPORT})
-public class DocChunkController extends BaseController<DocChunkService, DocChunkResp, DocChunkDetailResp, DocChunkQuery, DocChunkReq> {}
+public class DocChunkController extends BaseController<DocChunkService, DocChunkResp, DocChunkDetailResp, DocChunkQuery, DocChunkReq> {
+    @Operation(summary = "向量搜索接口", description = "向量搜素接口")
+    @PostMapping(value = "/insModelAndSecret")
+    public List<SimilaritySearchResp> insModelAndSecret(@RequestBody SimilaritySearchReq req) {
+        return baseService.SimilaritySearch(req);
+    }
+}

+ 25 - 1
pavis-webapi/src/main/java/com/pavis/admin/controller/aigc/EmbedStoreController.java

@@ -1,15 +1,23 @@
 package com.pavis.admin.controller.aigc;
 package com.pavis.admin.controller.aigc;
 
 
+import com.pavis.admin.aigc.core.SpringContextHolder;
+import com.pavis.admin.aigc.event.EmbeddingRefreshEvent;
 import com.pavis.admin.aigc.model.query.EmbedStoreQuery;
 import com.pavis.admin.aigc.model.query.EmbedStoreQuery;
 import com.pavis.admin.aigc.model.req.EmbedStoreReq;
 import com.pavis.admin.aigc.model.req.EmbedStoreReq;
 import com.pavis.admin.aigc.model.resp.EmbedStoreDetailResp;
 import com.pavis.admin.aigc.model.resp.EmbedStoreDetailResp;
 import com.pavis.admin.aigc.model.resp.EmbedStoreResp;
 import com.pavis.admin.aigc.model.resp.EmbedStoreResp;
 import com.pavis.admin.aigc.service.EmbedStoreService;
 import com.pavis.admin.aigc.service.EmbedStoreService;
 import com.pavis.admin.common.controller.BaseController;
 import com.pavis.admin.common.controller.BaseController;
+import io.swagger.v3.oas.annotations.Operation;
 import io.swagger.v3.oas.annotations.tags.Tag;
 import io.swagger.v3.oas.annotations.tags.Tag;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestBody;
 import org.springframework.web.bind.annotation.RestController;
 import org.springframework.web.bind.annotation.RestController;
 import top.continew.starter.extension.crud.annotation.CrudRequestMapping;
 import top.continew.starter.extension.crud.annotation.CrudRequestMapping;
 import top.continew.starter.extension.crud.enums.Api;
 import top.continew.starter.extension.crud.enums.Api;
+import top.continew.starter.extension.crud.model.resp.IdResp;
+import top.continew.starter.extension.crud.validation.CrudValidationGroup;
 
 
 /**
 /**
  * 向量存储配置管理 API
  * 向量存储配置管理 API
@@ -21,4 +29,20 @@ import top.continew.starter.extension.crud.enums.Api;
 @RestController
 @RestController
 @CrudRequestMapping(value = "/aigc/embedStore", api = {Api.PAGE, Api.GET, Api.CREATE, Api.UPDATE, Api.DELETE,
 @CrudRequestMapping(value = "/aigc/embedStore", api = {Api.PAGE, Api.GET, Api.CREATE, Api.UPDATE, Api.DELETE,
     Api.EXPORT})
     Api.EXPORT})
-public class EmbedStoreController extends BaseController<EmbedStoreService, EmbedStoreResp, EmbedStoreDetailResp, EmbedStoreQuery, EmbedStoreReq> {}
+public class EmbedStoreController extends BaseController<EmbedStoreService, EmbedStoreResp, EmbedStoreDetailResp, EmbedStoreQuery, EmbedStoreReq> {
+    @Override
+    @Operation(summary = "新增重载数据", description = "新增重载数据")
+    public IdResp<Long> create(@Validated(CrudValidationGroup.Create.class) @RequestBody EmbedStoreReq req) {
+        IdResp<Long> longIdResp = super.create(req);
+        SpringContextHolder.publishEvent(new EmbeddingRefreshEvent(req));
+        return longIdResp;
+    }
+
+    @Override
+    @Operation(summary = "更新重载数据", description = "更新重载数据")
+    public void update(@Validated(CrudValidationGroup.Create.class) @RequestBody EmbedStoreReq req,
+                       @PathVariable("id") Long id) {
+        super.update(req, id);
+        SpringContextHolder.publishEvent(new EmbeddingRefreshEvent(req));
+    }
+}

+ 10 - 1
pavis-webapi/src/main/java/com/pavis/admin/controller/aigc/KnowledgeController.java

@@ -1,5 +1,6 @@
 package com.pavis.admin.controller.aigc;
 package com.pavis.admin.controller.aigc;
 
 
+import io.swagger.v3.oas.annotations.Operation;
 import top.continew.starter.extension.crud.enums.Api;
 import top.continew.starter.extension.crud.enums.Api;
 
 
 import io.swagger.v3.oas.annotations.tags.Tag;
 import io.swagger.v3.oas.annotations.tags.Tag;
@@ -14,6 +15,8 @@ import com.pavis.admin.aigc.model.resp.KnowledgeDetailResp;
 import com.pavis.admin.aigc.model.resp.KnowledgeResp;
 import com.pavis.admin.aigc.model.resp.KnowledgeResp;
 import com.pavis.admin.aigc.service.KnowledgeService;
 import com.pavis.admin.aigc.service.KnowledgeService;
 
 
+import java.util.List;
+
 /**
 /**
  * AIGC知识库管理 API
  * AIGC知识库管理 API
  *
  *
@@ -24,4 +27,10 @@ import com.pavis.admin.aigc.service.KnowledgeService;
 @RestController
 @RestController
 @CrudRequestMapping(value = "/aigc/knowledge", api = {Api.PAGE, Api.GET, Api.CREATE, Api.UPDATE, Api.DELETE,
 @CrudRequestMapping(value = "/aigc/knowledge", api = {Api.PAGE, Api.GET, Api.CREATE, Api.UPDATE, Api.DELETE,
     Api.EXPORT})
     Api.EXPORT})
-public class KnowledgeController extends BaseController<KnowledgeService, KnowledgeResp, KnowledgeDetailResp, KnowledgeQuery, KnowledgeReq> {}
+public class KnowledgeController extends BaseController<KnowledgeService, KnowledgeResp, KnowledgeDetailResp, KnowledgeQuery, KnowledgeReq> {
+    @Operation(summary = "(新)知识库删除接口", description = "(新)知识库删除接口")
+    @PostMapping(value = "/delKnowAndDocAndSlice/{knowledgeId}")
+    public void delModelAndSecrt(@PathVariable Long knowledgeId) {
+        baseService.delKnowAndDocAndSlice(knowledgeId);
+    }
+}

+ 7 - 0
pavis-webapi/src/main/java/com/pavis/admin/controller/aigc/ModelController.java

@@ -1,6 +1,9 @@
 package com.pavis.admin.controller.aigc;
 package com.pavis.admin.controller.aigc;
 
 
+import com.pavis.admin.aigc.core.SpringContextHolder;
+import com.pavis.admin.aigc.event.ProviderRefreshEvent;
 import io.swagger.v3.oas.annotations.Operation;
 import io.swagger.v3.oas.annotations.Operation;
+import jakarta.annotation.Resource;
 import top.continew.starter.extension.crud.enums.Api;
 import top.continew.starter.extension.crud.enums.Api;
 
 
 import io.swagger.v3.oas.annotations.tags.Tag;
 import io.swagger.v3.oas.annotations.tags.Tag;
@@ -31,6 +34,8 @@ public class ModelController extends BaseController<ModelService, ModelResp, Mod
     @PostMapping(value = "/insModelAndSecret")
     @PostMapping(value = "/insModelAndSecret")
     public void insModelAndSecret(@RequestBody ModelReq modelReq) {
     public void insModelAndSecret(@RequestBody ModelReq modelReq) {
         baseService.insModelAndSecret(modelReq);
         baseService.insModelAndSecret(modelReq);
+        // 重新加载模型
+        SpringContextHolder.publishEvent(new ProviderRefreshEvent(modelReq));
     }
     }
 
 
     @Operation(summary = "模型和配置查询接口", description = "模型和配置查询接口")
     @Operation(summary = "模型和配置查询接口", description = "模型和配置查询接口")
@@ -43,6 +48,8 @@ public class ModelController extends BaseController<ModelService, ModelResp, Mod
     @PostMapping(value = "/updateModelAndSecrt")
     @PostMapping(value = "/updateModelAndSecrt")
     public void updateModelAndSecrt(@RequestBody ModelResp modelResp) {
     public void updateModelAndSecrt(@RequestBody ModelResp modelResp) {
         baseService.updateModelAndSecrt(modelResp);
         baseService.updateModelAndSecrt(modelResp);
+        // 重新加载模型
+        SpringContextHolder.publishEvent(new ProviderRefreshEvent(modelResp));
     }
     }
 
 
     @Operation(summary = "模型和配置删除接口", description = "模型和配置删除接口")
     @Operation(summary = "模型和配置删除接口", description = "模型和配置删除接口")

+ 3 - 5
pavis-webapi/src/main/java/com/pavis/admin/controller/common/CaptchaController.java

@@ -25,7 +25,6 @@ import jakarta.validation.constraints.Pattern;
 import lombok.RequiredArgsConstructor;
 import lombok.RequiredArgsConstructor;
 import org.dromara.sms4j.api.SmsBlend;
 import org.dromara.sms4j.api.SmsBlend;
 import org.dromara.sms4j.api.entity.SmsResponse;
 import org.dromara.sms4j.api.entity.SmsResponse;
-import org.dromara.sms4j.comm.constant.SupplierConstant;
 import org.dromara.sms4j.core.factory.SmsFactory;
 import org.dromara.sms4j.core.factory.SmsFactory;
 import org.springframework.http.HttpHeaders;
 import org.springframework.http.HttpHeaders;
 import org.springframework.validation.annotation.Validated;
 import org.springframework.validation.annotation.Validated;
@@ -44,7 +43,6 @@ import top.continew.starter.core.autoconfigure.project.ProjectProperties;
 import top.continew.starter.core.util.TemplateUtils;
 import top.continew.starter.core.util.TemplateUtils;
 import top.continew.starter.core.validation.CheckUtils;
 import top.continew.starter.core.validation.CheckUtils;
 import top.continew.starter.core.validation.ValidationUtils;
 import top.continew.starter.core.validation.ValidationUtils;
-import top.continew.starter.core.validation.constraints.Mobile;
 import top.continew.starter.log.annotation.Log;
 import top.continew.starter.log.annotation.Log;
 import top.continew.starter.messaging.mail.util.MailUtils;
 import top.continew.starter.messaging.mail.util.MailUtils;
 import top.continew.starter.ratelimiter.annotation.RateLimiter;
 import top.continew.starter.ratelimiter.annotation.RateLimiter;
@@ -198,7 +196,7 @@ public class CaptchaController {
             // 行为验证码校验
             // 行为验证码校验
             ResponseModel verificationRes = behaviorCaptchaService.verification(captchaReq);
             ResponseModel verificationRes = behaviorCaptchaService.verification(captchaReq);
             ValidationUtils.throwIfNotEqual(verificationRes.getRepCode(), RepCodeEnum.SUCCESS.getCode(), verificationRes
             ValidationUtils.throwIfNotEqual(verificationRes.getRepCode(), RepCodeEnum.SUCCESS.getCode(), verificationRes
-                    .getRepMsg());
+                .getRepMsg());
             CaptchaProperties.CaptchaSms captchaSms = captchaProperties.getSms();
             CaptchaProperties.CaptchaSms captchaSms = captchaProperties.getSms();
             // 生成验证码
             // 生成验证码
             captcha = RandomUtil.randomNumbers(captchaSms.getLength());
             captcha = RandomUtil.randomNumbers(captchaSms.getLength());
@@ -206,8 +204,8 @@ public class CaptchaController {
             // 获取短信配置
             // 获取短信配置
             SmsConfigDO smsConfig = smsConfigService.getDefaultConfig();
             SmsConfigDO smsConfig = smsConfigService.getDefaultConfig();
             SmsBlend smsBlend = smsConfig != null
             SmsBlend smsBlend = smsConfig != null
-                    ? SmsFactory.getBySupplier(smsConfig.getSupplier())
-                    : SmsFactory.getSmsBlend();
+                ? SmsFactory.getBySupplier(smsConfig.getSupplier())
+                : SmsFactory.getSmsBlend();
             Map<String, String> messageMap = MapUtil.newHashMap(2, true);
             Map<String, String> messageMap = MapUtil.newHashMap(2, true);
             messageMap.put(captchaSms.getCodeKey(), captcha);
             messageMap.put(captchaSms.getCodeKey(), captcha);
             messageMap.put(captchaSms.getTimeKey(), String.valueOf(expirationInMinutes));
             messageMap.put(captchaSms.getTimeKey(), String.valueOf(expirationInMinutes));

+ 1 - 1
pavis-webapi/src/main/resources/config/application-prod.yml

@@ -6,7 +6,7 @@ project:
 --- ### 服务器配置
 --- ### 服务器配置
 server:
 server:
   # HTTP 端口(默认 8080)
   # HTTP 端口(默认 8080)
-  port: 5555
+  port: 8080
 
 
 --- ### Spring AI 配置
 --- ### Spring AI 配置
 spring:
 spring:

+ 1 - 0
pavis-webapi/src/main/resources/db/changelog/mysql/main_table.sql

@@ -579,6 +579,7 @@ CREATE TABLE IF NOT EXISTS `aigc_doc_chunk`
     `create_time`     DATETIME        NOT NULL COMMENT '创建时间',
     `create_time`     DATETIME        NOT NULL COMMENT '创建时间',
     `update_user`     BIGINT        DEFAULT NULL COMMENT '修改人',
     `update_user`     BIGINT        DEFAULT NULL COMMENT '修改人',
     `update_time`     DATETIME      DEFAULT NULL COMMENT '修改时间',
     `update_time`     DATETIME      DEFAULT NULL COMMENT '修改时间',
+    `vector` json DEFAULT NULL COMMENT '向量嵌入(float数组)',
     PRIMARY KEY (`id`),
     PRIMARY KEY (`id`),
     KEY `idx_embed_store_id` (`embed_store_id`),
     KEY `idx_embed_store_id` (`embed_store_id`),
     KEY `idx_doc_id` (`doc_id`),
     KEY `idx_doc_id` (`doc_id`),