diff --git a/yudao-module-ai/yudao-module-ai-api/src/main/java/cn/iocoder/yudao/module/ai/enums/ErrorCodeConstants.java b/yudao-module-ai/yudao-module-ai-api/src/main/java/cn/iocoder/yudao/module/ai/enums/ErrorCodeConstants.java index 5ac6d2ae9e..2b236e6f6a 100644 --- a/yudao-module-ai/yudao-module-ai-api/src/main/java/cn/iocoder/yudao/module/ai/enums/ErrorCodeConstants.java +++ b/yudao-module-ai/yudao-module-ai-api/src/main/java/cn/iocoder/yudao/module/ai/enums/ErrorCodeConstants.java @@ -60,5 +60,6 @@ public interface ErrorCodeConstants { ErrorCode KNOWLEDGE_DOCUMENT_FILE_READ_FAIL = new ErrorCode(1_022_008_102, "文档加载失败!"); ErrorCode KNOWLEDGE_SEGMENT_NOT_EXISTS = new ErrorCode(1_022_008_202, "段落不存在!"); + ErrorCode KNOWLEDGE_SEGMENT_CONTENT_TOO_LONG = new ErrorCode(1_022_008_203, "内容 Token 数为 {},超过最大限制 {}"); } diff --git a/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/knowledge/AiKnowledgeController.java b/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/knowledge/AiKnowledgeController.java index df49395750..f3dc6f022e 100644 --- a/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/knowledge/AiKnowledgeController.java +++ b/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/knowledge/AiKnowledgeController.java @@ -13,6 +13,7 @@ import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.annotation.Resource; import jakarta.validation.Valid; +import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; @@ -30,6 +31,7 @@ public class AiKnowledgeController { @GetMapping("/page") @Operation(summary = "获取知识库分页") + @PreAuthorize("@ss.hasPermission('ai:knowledge:query')") public CommonResult> getKnowledgePage(@Valid AiKnowledgePageReqVO pageReqVO) { PageResult pageResult = knowledgeService.getKnowledgePage(pageReqVO); @@ -39,6 +41,7 @@ public class AiKnowledgeController { @GetMapping("/get") @Operation(summary = "获得知识库") @Parameter(name = "id", description = "编号", required = true, example = "1024") + @PreAuthorize("@ss.hasPermission('ai:knowledge:query')") public CommonResult getKnowledge(@RequestParam("id") Long id) { AiKnowledgeDO knowledge = knowledgeService.getKnowledge(id); return success(BeanUtils.toBean(knowledge, AiKnowledgeRespVO.class)); @@ -46,12 +49,14 @@ public class AiKnowledgeController { @PostMapping("/create") @Operation(summary = "创建知识库") + @PreAuthorize("@ss.hasPermission('ai:knowledge:create')") public CommonResult createKnowledge(@RequestBody @Valid AiKnowledgeSaveReqVO createReqVO) { return success(knowledgeService.createKnowledge(createReqVO)); } @PutMapping("/update") @Operation(summary = "更新知识库") + @PreAuthorize("@ss.hasPermission('ai:knowledge:update')") public CommonResult updateKnowledge(@RequestBody @Valid AiKnowledgeSaveReqVO updateReqVO) { knowledgeService.updateKnowledge(updateReqVO); return success(true); diff --git a/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/knowledge/AiKnowledgeDocumentController.java b/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/knowledge/AiKnowledgeDocumentController.java index e828615ea1..cca856fe17 100644 --- a/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/knowledge/AiKnowledgeDocumentController.java +++ b/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/knowledge/AiKnowledgeDocumentController.java @@ -15,6 +15,7 @@ import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.annotation.Resource; import jakarta.validation.Valid; +import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; @@ -22,7 +23,6 @@ import java.util.List; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; -// TODO @芋艿:增加权限标识 @Tag(name = "管理后台 - AI 知识库文档") @RestController @RequestMapping("/ai/knowledge/document") @@ -34,6 +34,7 @@ public class AiKnowledgeDocumentController { @GetMapping("/page") @Operation(summary = "获取文档分页") + @PreAuthorize("@ss.hasPermission('ai:knowledge:query')") public CommonResult> getKnowledgeDocumentPage( @Valid AiKnowledgeDocumentPageReqVO pageReqVO) { PageResult pageResult = documentService.getKnowledgeDocumentPage(pageReqVO); @@ -42,6 +43,7 @@ public class AiKnowledgeDocumentController { @GetMapping("/get") @Operation(summary = "获取文档详情") + @PreAuthorize("@ss.hasPermission('ai:knowledge:query')") public CommonResult getKnowledgeDocument(@RequestParam("id") Long id) { AiKnowledgeDocumentDO document = documentService.getKnowledgeDocument(id); return success(BeanUtils.toBean(document, AiKnowledgeDocumentRespVO.class)); @@ -49,6 +51,7 @@ public class AiKnowledgeDocumentController { @PostMapping("/create") @Operation(summary = "新建文档(单个)") + @PreAuthorize("@ss.hasPermission('ai:knowledge:create')") public CommonResult createKnowledgeDocument(@RequestBody @Valid AiKnowledgeDocumentCreateReqVO reqVO) { Long id = documentService.createKnowledgeDocument(reqVO); return success(id); @@ -56,6 +59,7 @@ public class AiKnowledgeDocumentController { @PostMapping("/create-list") @Operation(summary = "新建文档(多个)") + @PreAuthorize("@ss.hasPermission('ai:knowledge:create')") public CommonResult> createKnowledgeDocumentList( @RequestBody @Valid AiKnowledgeDocumentCreateListReqVO reqVO) { List ids = documentService.createKnowledgeDocumentList(reqVO); @@ -64,6 +68,7 @@ public class AiKnowledgeDocumentController { @PutMapping("/update") @Operation(summary = "更新文档") + @PreAuthorize("@ss.hasPermission('ai:knowledge:update')") public CommonResult updateKnowledgeDocument(@Valid @RequestBody AiKnowledgeDocumentUpdateReqVO reqVO) { documentService.updateKnowledgeDocument(reqVO); return success(true); @@ -71,10 +76,19 @@ public class AiKnowledgeDocumentController { @PutMapping("/update-status") @Operation(summary = "更新文档状态") + @PreAuthorize("@ss.hasPermission('ai:knowledge:update')") public CommonResult updateKnowledgeDocumentStatus( @Valid @RequestBody AiKnowledgeDocumentUpdateStatusReqVO reqVO) { documentService.updateKnowledgeDocumentStatus(reqVO); return success(true); } + @DeleteMapping("/delete") + @Operation(summary = "删除文档") + @PreAuthorize("@ss.hasPermission('ai:knowledge:delete')") + public CommonResult deleteKnowledgeDocument(@RequestParam("id") Long id) { + documentService.deleteKnowledgeDocument(id); + return success(true); + } + } diff --git a/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/knowledge/AiKnowledgeSegmentController.java b/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/knowledge/AiKnowledgeSegmentController.java index 06b61708f0..34f324491b 100644 --- a/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/knowledge/AiKnowledgeSegmentController.java +++ b/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/knowledge/AiKnowledgeSegmentController.java @@ -19,6 +19,7 @@ import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.annotation.Resource; import jakarta.validation.Valid; import org.hibernate.validator.constraints.URL; +import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; @@ -29,7 +30,6 @@ import java.util.Map; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; -// TODO @芋艿:增加权限标识 @Tag(name = "管理后台 - AI 知识库段落") @RestController @RequestMapping("/ai/knowledge/segment") @@ -38,27 +38,45 @@ public class AiKnowledgeSegmentController { @Resource private AiKnowledgeSegmentService segmentService; - @Resource private AiKnowledgeDocumentService documentService; + @GetMapping("/get") + @Operation(summary = "获取段落详情") + @Parameter(name = "id", description = "段落编号", required = true, example = "1024") + @PreAuthorize("@ss.hasPermission('ai:knowledge:query')") + public CommonResult getKnowledgeSegment(@RequestParam("id") Long id) { + AiKnowledgeSegmentDO segment = segmentService.getKnowledgeSegment(id); + return success(BeanUtils.toBean(segment, AiKnowledgeSegmentRespVO.class)); + } + @GetMapping("/page") @Operation(summary = "获取段落分页") + @PreAuthorize("@ss.hasPermission('ai:knowledge:query')") public CommonResult> getKnowledgeSegmentPage( @Valid AiKnowledgeSegmentPageReqVO pageReqVO) { PageResult pageResult = segmentService.getKnowledgeSegmentPage(pageReqVO); return success(BeanUtils.toBean(pageResult, AiKnowledgeSegmentRespVO.class)); } + @PostMapping("/create") + @Operation(summary = "创建段落") + @PreAuthorize("@ss.hasPermission('ai:knowledge:create')") + public CommonResult createKnowledgeSegment(@Valid @RequestBody AiKnowledgeSegmentSaveReqVO createReqVO) { + return success(segmentService.createKnowledgeSegment(createReqVO)); + } + @PutMapping("/update") @Operation(summary = "更新段落内容") - public CommonResult updateKnowledgeSegment(@Valid @RequestBody AiKnowledgeSegmentUpdateReqVO reqVO) { + @PreAuthorize("@ss.hasPermission('ai:knowledge:update')") + public CommonResult updateKnowledgeSegment(@Valid @RequestBody AiKnowledgeSegmentSaveReqVO reqVO) { segmentService.updateKnowledgeSegment(reqVO); return success(true); } @PutMapping("/update-status") @Operation(summary = "启禁用段落内容") + @PreAuthorize("@ss.hasPermission('ai:knowledge:update')") public CommonResult updateKnowledgeSegmentStatus( @Valid @RequestBody AiKnowledgeSegmentUpdateStatusReqVO reqVO) { segmentService.updateKnowledgeSegmentStatus(reqVO); @@ -71,6 +89,7 @@ public class AiKnowledgeSegmentController { @Parameter(name = "url", description = "文档 URL", required = true), @Parameter(name = "segmentMaxTokens", description = "分段的最大 Token 数", required = true) }) + @PreAuthorize("@ss.hasPermission('ai:knowledge:query')") public CommonResult> splitContent( @RequestParam("url") @URL String url, @RequestParam(value = "segmentMaxTokens") Integer segmentMaxTokens) { @@ -81,6 +100,7 @@ public class AiKnowledgeSegmentController { @GetMapping("/get-process-list") @Operation(summary = "获取文档处理列表") @Parameter(name = "documentIds", description = "文档编号列表", required = true, example = "1,2,3") + @PreAuthorize("@ss.hasPermission('ai:knowledge:query')") public CommonResult> getKnowledgeSegmentProcessList( @RequestParam("documentIds") List documentIds) { List list = segmentService.getKnowledgeSegmentProcessList(documentIds); @@ -89,6 +109,7 @@ public class AiKnowledgeSegmentController { @GetMapping("/search") @Operation(summary = "搜索段落内容") + @PreAuthorize("@ss.hasPermission('ai:knowledge:query')") public CommonResult> searchKnowledgeSegment( @Valid AiKnowledgeSegmentSearchReqVO reqVO) { // 1. 搜索段落 diff --git a/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/knowledge/vo/segment/AiKnowledgeSegmentPageReqVO.java b/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/knowledge/vo/segment/AiKnowledgeSegmentPageReqVO.java index 8be3db501b..f53d5be076 100644 --- a/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/knowledge/vo/segment/AiKnowledgeSegmentPageReqVO.java +++ b/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/knowledge/vo/segment/AiKnowledgeSegmentPageReqVO.java @@ -1,6 +1,8 @@ package cn.iocoder.yudao.module.ai.controller.admin.knowledge.vo.segment; +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; import cn.iocoder.yudao.framework.common.pojo.PageParam; +import cn.iocoder.yudao.framework.common.validation.InEnum; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; @@ -8,13 +10,14 @@ import lombok.Data; @Data public class AiKnowledgeSegmentPageReqVO extends PageParam { - @Schema(description = "分段状态", example = "1") - private Integer status; - @Schema(description = "文档编号", example = "1") private Integer documentId; @Schema(description = "分段内容关键字", example = "Java 开发") - private String keyword; + private String content; + + @Schema(description = "分段状态", example = "1") + @InEnum(CommonStatusEnum.class) + private Integer status; } diff --git a/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/knowledge/vo/segment/AiKnowledgeSegmentUpdateReqVO.java b/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/knowledge/vo/segment/AiKnowledgeSegmentUpdateReqVO.java deleted file mode 100644 index 2fc7a3141f..0000000000 --- a/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/knowledge/vo/segment/AiKnowledgeSegmentUpdateReqVO.java +++ /dev/null @@ -1,17 +0,0 @@ -package cn.iocoder.yudao.module.ai.controller.admin.knowledge.vo.segment; - -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Data; - - -@Schema(description = "管理后台 - AI 更新 知识库段落 request VO") -@Data -public class AiKnowledgeSegmentUpdateReqVO { - - @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "24790") - private Long id; - - @Schema(description = "切片内容", requiredMode = Schema.RequiredMode.REQUIRED, example = "Java 开发手册") - private String content; - -} diff --git a/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/dal/mysql/knowledge/AiKnowledgeSegmentMapper.java b/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/dal/mysql/knowledge/AiKnowledgeSegmentMapper.java index fab5572ceb..a2a4e15b6d 100644 --- a/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/dal/mysql/knowledge/AiKnowledgeSegmentMapper.java +++ b/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/dal/mysql/knowledge/AiKnowledgeSegmentMapper.java @@ -25,8 +25,8 @@ public interface AiKnowledgeSegmentMapper extends BaseMapperX selectPage(AiKnowledgeSegmentPageReqVO reqVO) { return selectPage(reqVO, new LambdaQueryWrapperX() .eq(AiKnowledgeSegmentDO::getDocumentId, reqVO.getDocumentId()) + .likeIfPresent(AiKnowledgeSegmentDO::getContent, reqVO.getContent()) .eqIfPresent(AiKnowledgeSegmentDO::getStatus, reqVO.getStatus()) - .likeIfPresent(AiKnowledgeSegmentDO::getContent, reqVO.getKeyword()) .orderByDesc(AiKnowledgeSegmentDO::getId)); } diff --git a/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/service/knowledge/AiKnowledgeDocumentService.java b/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/service/knowledge/AiKnowledgeDocumentService.java index 32720ed6a5..8ff137b331 100644 --- a/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/service/knowledge/AiKnowledgeDocumentService.java +++ b/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/service/knowledge/AiKnowledgeDocumentService.java @@ -74,6 +74,13 @@ public interface AiKnowledgeDocumentService { */ void updateKnowledgeDocumentRetrievalCountIncr(Collection ids); + /** + * 删除文档 + * + * @param id 文档编号 + */ + void deleteKnowledgeDocument(Long id); + /** * 校验文档是否存在 * diff --git a/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/service/knowledge/AiKnowledgeDocumentServiceImpl.java b/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/service/knowledge/AiKnowledgeDocumentServiceImpl.java index a04bf80221..b1513a9bd4 100644 --- a/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/service/knowledge/AiKnowledgeDocumentServiceImpl.java +++ b/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/service/knowledge/AiKnowledgeDocumentServiceImpl.java @@ -149,6 +149,19 @@ public class AiKnowledgeDocumentServiceImpl implements AiKnowledgeDocumentServic } } + @Override + @Transactional(rollbackFor = Exception.class) + public void deleteKnowledgeDocument(Long id) { + // 1. 校验存在 + validateKnowledgeDocumentExists(id); + + // 2. 删除 + knowledgeDocumentMapper.deleteById(id); + + // 3. 删除对应的段落 + knowledgeSegmentService.deleteKnowledgeSegmentByDocumentId(id); + } + @Override public void updateKnowledgeDocumentRetrievalCountIncr(Collection ids) { if (CollUtil.isEmpty(ids)) { diff --git a/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/service/knowledge/AiKnowledgeSegmentService.java b/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/service/knowledge/AiKnowledgeSegmentService.java index ce79c8dd00..15ab941fe8 100644 --- a/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/service/knowledge/AiKnowledgeSegmentService.java +++ b/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/service/knowledge/AiKnowledgeSegmentService.java @@ -3,7 +3,7 @@ package cn.iocoder.yudao.module.ai.service.knowledge; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.module.ai.controller.admin.knowledge.vo.segment.AiKnowledgeSegmentPageReqVO; import cn.iocoder.yudao.module.ai.controller.admin.knowledge.vo.segment.AiKnowledgeSegmentProcessRespVO; -import cn.iocoder.yudao.module.ai.controller.admin.knowledge.vo.segment.AiKnowledgeSegmentUpdateReqVO; +import cn.iocoder.yudao.module.ai.controller.admin.knowledge.vo.segment.AiKnowledgeSegmentSaveReqVO; import cn.iocoder.yudao.module.ai.controller.admin.knowledge.vo.segment.AiKnowledgeSegmentUpdateStatusReqVO; import cn.iocoder.yudao.module.ai.dal.dataobject.knowledge.AiKnowledgeSegmentDO; import cn.iocoder.yudao.module.ai.service.knowledge.bo.AiKnowledgeSegmentSearchReqBO; @@ -19,6 +19,14 @@ import java.util.List; */ public interface AiKnowledgeSegmentService { + /** + * 获取知识库段落详情 + * + * @param id 段落编号 + * @return 段落详情 + */ + AiKnowledgeSegmentDO getKnowledgeSegment(Long id); + /** * 获取段落分页 * @@ -46,12 +54,20 @@ public interface AiKnowledgeSegmentService { createKnowledgeSegmentBySplitContent(documentId, content); } + /** + * 创建知识库段落 + * + * @param createReqVO 创建信息 + * @return 段落编号 + */ + Long createKnowledgeSegment(AiKnowledgeSegmentSaveReqVO createReqVO); + /** * 更新段落的内容 * * @param reqVO 更新内容 */ - void updateKnowledgeSegment(AiKnowledgeSegmentUpdateReqVO reqVO); + void updateKnowledgeSegment(AiKnowledgeSegmentSaveReqVO reqVO); /** * 更新段落的状态 diff --git a/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/service/knowledge/AiKnowledgeSegmentServiceImpl.java b/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/service/knowledge/AiKnowledgeSegmentServiceImpl.java index eefad0bc8b..adf1616cb0 100644 --- a/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/service/knowledge/AiKnowledgeSegmentServiceImpl.java +++ b/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/service/knowledge/AiKnowledgeSegmentServiceImpl.java @@ -34,6 +34,7 @@ import java.util.Objects; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList; import static cn.iocoder.yudao.module.ai.enums.ErrorCodeConstants.KNOWLEDGE_SEGMENT_NOT_EXISTS; +import static cn.iocoder.yudao.module.ai.enums.ErrorCodeConstants.KNOWLEDGE_SEGMENT_CONTENT_TOO_LONG; /** * AI 知识库分片 Service 实现类 @@ -98,20 +99,20 @@ public class AiKnowledgeSegmentServiceImpl implements AiKnowledgeSegmentService } @Override - public void updateKnowledgeSegment(AiKnowledgeSegmentUpdateReqVO reqVO) { + public void updateKnowledgeSegment(AiKnowledgeSegmentSaveReqVO reqVO) { // 1. 校验 - AiKnowledgeSegmentDO segment = validateKnowledgeSegmentExists(reqVO.getId()); + AiKnowledgeSegmentDO oldSegment = validateKnowledgeSegmentExists(reqVO.getId()); // 2. 删除向量 - VectorStore vectorStore = getVectorStoreById(segment.getKnowledgeId()); - deleteVectorStore(vectorStore, segment); + VectorStore vectorStore = getVectorStoreById(oldSegment.getKnowledgeId()); + deleteVectorStore(vectorStore, oldSegment); // 3.1 更新切片 - AiKnowledgeSegmentDO segmentDO = BeanUtils.toBean(reqVO, AiKnowledgeSegmentDO.class); - segmentMapper.updateById(segmentDO); + AiKnowledgeSegmentDO newSegment = BeanUtils.toBean(reqVO, AiKnowledgeSegmentDO.class); + segmentMapper.updateById(newSegment); // 3.2 重新向量化,必须开启状态 - if (CommonStatusEnum.isEnable(segmentDO.getStatus())) { - writeVectorStore(vectorStore, segmentDO, new Document(segmentDO.getContent())); + if (CommonStatusEnum.isEnable(oldSegment.getStatus())) { + writeVectorStore(vectorStore, newSegment, new Document(newSegment.getContent())); } } @@ -143,7 +144,7 @@ public class AiKnowledgeSegmentServiceImpl implements AiKnowledgeSegmentService segmentMapper.updateById(new AiKnowledgeSegmentDO().setId(reqVO.getId()).setStatus(reqVO.getStatus())); // 4. 更新向量 - if (Objects.equals(reqVO.getStatus(), CommonStatusEnum.ENABLE.getStatus())) { + if (CommonStatusEnum.isEnable(reqVO.getStatus())) { writeVectorStore(vectorStore, segment, new Document(segment.getContent())); } else { deleteVectorStore(vectorStore, segment); @@ -183,7 +184,8 @@ public class AiKnowledgeSegmentServiceImpl implements AiKnowledgeSegmentService List documents = vectorStore.similaritySearch(SearchRequest.builder() .query(reqBO.getContent()) .topK(ObjUtil.defaultIfNull(reqBO.getTopK(), knowledge.getTopK())) - .similarityThreshold(ObjUtil.defaultIfNull(reqBO.getSimilarityThreshold(), knowledge.getSimilarityThreshold())) + .similarityThreshold( + ObjUtil.defaultIfNull(reqBO.getSimilarityThreshold(), knowledge.getSimilarityThreshold())) .filterExpression(new FilterExpressionBuilder() .eq(VECTOR_STORE_METADATA_KNOWLEDGE_ID, reqBO.getKnowledgeId()).build()) .build()); @@ -202,7 +204,7 @@ public class AiKnowledgeSegmentServiceImpl implements AiKnowledgeSegmentService // 4. 构建结果 List result = convertList(segments, segment -> { - Document document = CollUtil.findOne(documents, // 找到对应的文档 + Document document = CollUtil.findOne(documents, // 找到对应的文档 doc -> Objects.equals(doc.getId(), segment.getVectorId())); if (document == null) { return null; @@ -210,8 +212,7 @@ public class AiKnowledgeSegmentServiceImpl implements AiKnowledgeSegmentService return BeanUtils.toBean(segment, AiKnowledgeSegmentSearchRespBO.class) .setScore(document.getScore()); }); - result.sort((o1, o2) - -> Double.compare(o2.getScore(), o1.getScore())); // 按照分数降序排序 + result.sort((o1, o2) -> Double.compare(o2.getScore(), o1.getScore())); // 按照分数降序排序 return result; } @@ -280,4 +281,35 @@ public class AiKnowledgeSegmentServiceImpl implements AiKnowledgeSegmentService return segmentMapper.selectProcessList(documentIds); } + @Override + public Long createKnowledgeSegment(AiKnowledgeSegmentSaveReqVO createReqVO) { + // 1.1 校验文档是否存在 + AiKnowledgeDocumentDO document = knowledgeDocumentService + .validateKnowledgeDocumentExists(createReqVO.getDocumentId()); + // 1.2 获取知识库信息 + AiKnowledgeDO knowledge = knowledgeService.validateKnowledgeExists(document.getKnowledgeId()); + // 1.3 校验 token 熟练 + Integer tokens = tokenCountEstimator.estimate(createReqVO.getContent()); + if (tokens > document.getSegmentMaxTokens()) { + throw exception(KNOWLEDGE_SEGMENT_CONTENT_TOO_LONG, tokens, document.getSegmentMaxTokens()); + } + + // 2. 保存段落 + AiKnowledgeSegmentDO segment = BeanUtils.toBean(createReqVO, AiKnowledgeSegmentDO.class) + .setKnowledgeId(knowledge.getId()).setDocumentId(document.getId()) + .setContentLength(createReqVO.getContent().length()).setTokens(tokens) + .setVectorId(AiKnowledgeSegmentDO.VECTOR_ID_EMPTY) + .setRetrievalCount(0).setStatus(CommonStatusEnum.ENABLE.getStatus()); + segmentMapper.insert(segment); + + // 3. 向量化 + writeVectorStore(getVectorStoreById(knowledge), segment, new Document(segment.getContent())); + return segment.getId(); + } + + @Override + public AiKnowledgeSegmentDO getKnowledgeSegment(Long id) { + return validateKnowledgeSegmentExists(id); + } + }