Commit 3f460dc620b306f995768354cdc6be227072b947

Authored by YunaiV
1 parent 5f5e77a3

【功能新增】AI:新增知识库分段的新增

Showing 11 changed files with 136 additions and 41 deletions
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 { @@ -60,5 +60,6 @@ public interface ErrorCodeConstants {
60 ErrorCode KNOWLEDGE_DOCUMENT_FILE_READ_FAIL = new ErrorCode(1_022_008_102, "文档加载失败!"); 60 ErrorCode KNOWLEDGE_DOCUMENT_FILE_READ_FAIL = new ErrorCode(1_022_008_102, "文档加载失败!");
61 61
62 ErrorCode KNOWLEDGE_SEGMENT_NOT_EXISTS = new ErrorCode(1_022_008_202, "段落不存在!"); 62 ErrorCode KNOWLEDGE_SEGMENT_NOT_EXISTS = new ErrorCode(1_022_008_202, "段落不存在!");
  63 + ErrorCode KNOWLEDGE_SEGMENT_CONTENT_TOO_LONG = new ErrorCode(1_022_008_203, "内容 Token 数为 {},超过最大限制 {}");
63 64
64 } 65 }
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; @@ -13,6 +13,7 @@ import io.swagger.v3.oas.annotations.Parameter;
13 import io.swagger.v3.oas.annotations.tags.Tag; 13 import io.swagger.v3.oas.annotations.tags.Tag;
14 import jakarta.annotation.Resource; 14 import jakarta.annotation.Resource;
15 import jakarta.validation.Valid; 15 import jakarta.validation.Valid;
  16 +import org.springframework.security.access.prepost.PreAuthorize;
16 import org.springframework.validation.annotation.Validated; 17 import org.springframework.validation.annotation.Validated;
17 import org.springframework.web.bind.annotation.*; 18 import org.springframework.web.bind.annotation.*;
18 19
@@ -30,6 +31,7 @@ public class AiKnowledgeController { @@ -30,6 +31,7 @@ public class AiKnowledgeController {
30 31
31 @GetMapping("/page") 32 @GetMapping("/page")
32 @Operation(summary = "获取知识库分页") 33 @Operation(summary = "获取知识库分页")
  34 + @PreAuthorize("@ss.hasPermission('ai:knowledge:query')")
33 public CommonResult<PageResult<AiKnowledgeRespVO>> getKnowledgePage(@Valid AiKnowledgePageReqVO pageReqVO) { 35 public CommonResult<PageResult<AiKnowledgeRespVO>> getKnowledgePage(@Valid AiKnowledgePageReqVO pageReqVO) {
34 36
35 PageResult<AiKnowledgeDO> pageResult = knowledgeService.getKnowledgePage(pageReqVO); 37 PageResult<AiKnowledgeDO> pageResult = knowledgeService.getKnowledgePage(pageReqVO);
@@ -39,6 +41,7 @@ public class AiKnowledgeController { @@ -39,6 +41,7 @@ public class AiKnowledgeController {
39 @GetMapping("/get") 41 @GetMapping("/get")
40 @Operation(summary = "获得知识库") 42 @Operation(summary = "获得知识库")
41 @Parameter(name = "id", description = "编号", required = true, example = "1024") 43 @Parameter(name = "id", description = "编号", required = true, example = "1024")
  44 + @PreAuthorize("@ss.hasPermission('ai:knowledge:query')")
42 public CommonResult<AiKnowledgeRespVO> getKnowledge(@RequestParam("id") Long id) { 45 public CommonResult<AiKnowledgeRespVO> getKnowledge(@RequestParam("id") Long id) {
43 AiKnowledgeDO knowledge = knowledgeService.getKnowledge(id); 46 AiKnowledgeDO knowledge = knowledgeService.getKnowledge(id);
44 return success(BeanUtils.toBean(knowledge, AiKnowledgeRespVO.class)); 47 return success(BeanUtils.toBean(knowledge, AiKnowledgeRespVO.class));
@@ -46,12 +49,14 @@ public class AiKnowledgeController { @@ -46,12 +49,14 @@ public class AiKnowledgeController {
46 49
47 @PostMapping("/create") 50 @PostMapping("/create")
48 @Operation(summary = "创建知识库") 51 @Operation(summary = "创建知识库")
  52 + @PreAuthorize("@ss.hasPermission('ai:knowledge:create')")
49 public CommonResult<Long> createKnowledge(@RequestBody @Valid AiKnowledgeSaveReqVO createReqVO) { 53 public CommonResult<Long> createKnowledge(@RequestBody @Valid AiKnowledgeSaveReqVO createReqVO) {
50 return success(knowledgeService.createKnowledge(createReqVO)); 54 return success(knowledgeService.createKnowledge(createReqVO));
51 } 55 }
52 56
53 @PutMapping("/update") 57 @PutMapping("/update")
54 @Operation(summary = "更新知识库") 58 @Operation(summary = "更新知识库")
  59 + @PreAuthorize("@ss.hasPermission('ai:knowledge:update')")
55 public CommonResult<Boolean> updateKnowledge(@RequestBody @Valid AiKnowledgeSaveReqVO updateReqVO) { 60 public CommonResult<Boolean> updateKnowledge(@RequestBody @Valid AiKnowledgeSaveReqVO updateReqVO) {
56 knowledgeService.updateKnowledge(updateReqVO); 61 knowledgeService.updateKnowledge(updateReqVO);
57 return success(true); 62 return success(true);
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; @@ -15,6 +15,7 @@ import io.swagger.v3.oas.annotations.Operation;
15 import io.swagger.v3.oas.annotations.tags.Tag; 15 import io.swagger.v3.oas.annotations.tags.Tag;
16 import jakarta.annotation.Resource; 16 import jakarta.annotation.Resource;
17 import jakarta.validation.Valid; 17 import jakarta.validation.Valid;
  18 +import org.springframework.security.access.prepost.PreAuthorize;
18 import org.springframework.validation.annotation.Validated; 19 import org.springframework.validation.annotation.Validated;
19 import org.springframework.web.bind.annotation.*; 20 import org.springframework.web.bind.annotation.*;
20 21
@@ -22,7 +23,6 @@ import java.util.List; @@ -22,7 +23,6 @@ import java.util.List;
22 23
23 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; 24 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
24 25
25 -// TODO @芋艿:增加权限标识  
26 @Tag(name = "管理后台 - AI 知识库文档") 26 @Tag(name = "管理后台 - AI 知识库文档")
27 @RestController 27 @RestController
28 @RequestMapping("/ai/knowledge/document") 28 @RequestMapping("/ai/knowledge/document")
@@ -34,6 +34,7 @@ public class AiKnowledgeDocumentController { @@ -34,6 +34,7 @@ public class AiKnowledgeDocumentController {
34 34
35 @GetMapping("/page") 35 @GetMapping("/page")
36 @Operation(summary = "获取文档分页") 36 @Operation(summary = "获取文档分页")
  37 + @PreAuthorize("@ss.hasPermission('ai:knowledge:query')")
37 public CommonResult<PageResult<AiKnowledgeDocumentRespVO>> getKnowledgeDocumentPage( 38 public CommonResult<PageResult<AiKnowledgeDocumentRespVO>> getKnowledgeDocumentPage(
38 @Valid AiKnowledgeDocumentPageReqVO pageReqVO) { 39 @Valid AiKnowledgeDocumentPageReqVO pageReqVO) {
39 PageResult<AiKnowledgeDocumentDO> pageResult = documentService.getKnowledgeDocumentPage(pageReqVO); 40 PageResult<AiKnowledgeDocumentDO> pageResult = documentService.getKnowledgeDocumentPage(pageReqVO);
@@ -42,6 +43,7 @@ public class AiKnowledgeDocumentController { @@ -42,6 +43,7 @@ public class AiKnowledgeDocumentController {
42 43
43 @GetMapping("/get") 44 @GetMapping("/get")
44 @Operation(summary = "获取文档详情") 45 @Operation(summary = "获取文档详情")
  46 + @PreAuthorize("@ss.hasPermission('ai:knowledge:query')")
45 public CommonResult<AiKnowledgeDocumentRespVO> getKnowledgeDocument(@RequestParam("id") Long id) { 47 public CommonResult<AiKnowledgeDocumentRespVO> getKnowledgeDocument(@RequestParam("id") Long id) {
46 AiKnowledgeDocumentDO document = documentService.getKnowledgeDocument(id); 48 AiKnowledgeDocumentDO document = documentService.getKnowledgeDocument(id);
47 return success(BeanUtils.toBean(document, AiKnowledgeDocumentRespVO.class)); 49 return success(BeanUtils.toBean(document, AiKnowledgeDocumentRespVO.class));
@@ -49,6 +51,7 @@ public class AiKnowledgeDocumentController { @@ -49,6 +51,7 @@ public class AiKnowledgeDocumentController {
49 51
50 @PostMapping("/create") 52 @PostMapping("/create")
51 @Operation(summary = "新建文档(单个)") 53 @Operation(summary = "新建文档(单个)")
  54 + @PreAuthorize("@ss.hasPermission('ai:knowledge:create')")
52 public CommonResult<Long> createKnowledgeDocument(@RequestBody @Valid AiKnowledgeDocumentCreateReqVO reqVO) { 55 public CommonResult<Long> createKnowledgeDocument(@RequestBody @Valid AiKnowledgeDocumentCreateReqVO reqVO) {
53 Long id = documentService.createKnowledgeDocument(reqVO); 56 Long id = documentService.createKnowledgeDocument(reqVO);
54 return success(id); 57 return success(id);
@@ -56,6 +59,7 @@ public class AiKnowledgeDocumentController { @@ -56,6 +59,7 @@ public class AiKnowledgeDocumentController {
56 59
57 @PostMapping("/create-list") 60 @PostMapping("/create-list")
58 @Operation(summary = "新建文档(多个)") 61 @Operation(summary = "新建文档(多个)")
  62 + @PreAuthorize("@ss.hasPermission('ai:knowledge:create')")
59 public CommonResult<List<Long>> createKnowledgeDocumentList( 63 public CommonResult<List<Long>> createKnowledgeDocumentList(
60 @RequestBody @Valid AiKnowledgeDocumentCreateListReqVO reqVO) { 64 @RequestBody @Valid AiKnowledgeDocumentCreateListReqVO reqVO) {
61 List<Long> ids = documentService.createKnowledgeDocumentList(reqVO); 65 List<Long> ids = documentService.createKnowledgeDocumentList(reqVO);
@@ -64,6 +68,7 @@ public class AiKnowledgeDocumentController { @@ -64,6 +68,7 @@ public class AiKnowledgeDocumentController {
64 68
65 @PutMapping("/update") 69 @PutMapping("/update")
66 @Operation(summary = "更新文档") 70 @Operation(summary = "更新文档")
  71 + @PreAuthorize("@ss.hasPermission('ai:knowledge:update')")
67 public CommonResult<Boolean> updateKnowledgeDocument(@Valid @RequestBody AiKnowledgeDocumentUpdateReqVO reqVO) { 72 public CommonResult<Boolean> updateKnowledgeDocument(@Valid @RequestBody AiKnowledgeDocumentUpdateReqVO reqVO) {
68 documentService.updateKnowledgeDocument(reqVO); 73 documentService.updateKnowledgeDocument(reqVO);
69 return success(true); 74 return success(true);
@@ -71,10 +76,19 @@ public class AiKnowledgeDocumentController { @@ -71,10 +76,19 @@ public class AiKnowledgeDocumentController {
71 76
72 @PutMapping("/update-status") 77 @PutMapping("/update-status")
73 @Operation(summary = "更新文档状态") 78 @Operation(summary = "更新文档状态")
  79 + @PreAuthorize("@ss.hasPermission('ai:knowledge:update')")
74 public CommonResult<Boolean> updateKnowledgeDocumentStatus( 80 public CommonResult<Boolean> updateKnowledgeDocumentStatus(
75 @Valid @RequestBody AiKnowledgeDocumentUpdateStatusReqVO reqVO) { 81 @Valid @RequestBody AiKnowledgeDocumentUpdateStatusReqVO reqVO) {
76 documentService.updateKnowledgeDocumentStatus(reqVO); 82 documentService.updateKnowledgeDocumentStatus(reqVO);
77 return success(true); 83 return success(true);
78 } 84 }
79 85
  86 + @DeleteMapping("/delete")
  87 + @Operation(summary = "删除文档")
  88 + @PreAuthorize("@ss.hasPermission('ai:knowledge:delete')")
  89 + public CommonResult<Boolean> deleteKnowledgeDocument(@RequestParam("id") Long id) {
  90 + documentService.deleteKnowledgeDocument(id);
  91 + return success(true);
  92 + }
  93 +
80 } 94 }
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; @@ -19,6 +19,7 @@ import io.swagger.v3.oas.annotations.tags.Tag;
19 import jakarta.annotation.Resource; 19 import jakarta.annotation.Resource;
20 import jakarta.validation.Valid; 20 import jakarta.validation.Valid;
21 import org.hibernate.validator.constraints.URL; 21 import org.hibernate.validator.constraints.URL;
  22 +import org.springframework.security.access.prepost.PreAuthorize;
22 import org.springframework.validation.annotation.Validated; 23 import org.springframework.validation.annotation.Validated;
23 import org.springframework.web.bind.annotation.*; 24 import org.springframework.web.bind.annotation.*;
24 25
@@ -29,7 +30,6 @@ import java.util.Map; @@ -29,7 +30,6 @@ import java.util.Map;
29 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; 30 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
30 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; 31 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
31 32
32 -// TODO @芋艿:增加权限标识  
33 @Tag(name = "管理后台 - AI 知识库段落") 33 @Tag(name = "管理后台 - AI 知识库段落")
34 @RestController 34 @RestController
35 @RequestMapping("/ai/knowledge/segment") 35 @RequestMapping("/ai/knowledge/segment")
@@ -38,27 +38,45 @@ public class AiKnowledgeSegmentController { @@ -38,27 +38,45 @@ public class AiKnowledgeSegmentController {
38 38
39 @Resource 39 @Resource
40 private AiKnowledgeSegmentService segmentService; 40 private AiKnowledgeSegmentService segmentService;
41 -  
42 @Resource 41 @Resource
43 private AiKnowledgeDocumentService documentService; 42 private AiKnowledgeDocumentService documentService;
44 43
  44 + @GetMapping("/get")
  45 + @Operation(summary = "获取段落详情")
  46 + @Parameter(name = "id", description = "段落编号", required = true, example = "1024")
  47 + @PreAuthorize("@ss.hasPermission('ai:knowledge:query')")
  48 + public CommonResult<AiKnowledgeSegmentRespVO> getKnowledgeSegment(@RequestParam("id") Long id) {
  49 + AiKnowledgeSegmentDO segment = segmentService.getKnowledgeSegment(id);
  50 + return success(BeanUtils.toBean(segment, AiKnowledgeSegmentRespVO.class));
  51 + }
  52 +
45 @GetMapping("/page") 53 @GetMapping("/page")
46 @Operation(summary = "获取段落分页") 54 @Operation(summary = "获取段落分页")
  55 + @PreAuthorize("@ss.hasPermission('ai:knowledge:query')")
47 public CommonResult<PageResult<AiKnowledgeSegmentRespVO>> getKnowledgeSegmentPage( 56 public CommonResult<PageResult<AiKnowledgeSegmentRespVO>> getKnowledgeSegmentPage(
48 @Valid AiKnowledgeSegmentPageReqVO pageReqVO) { 57 @Valid AiKnowledgeSegmentPageReqVO pageReqVO) {
49 PageResult<AiKnowledgeSegmentDO> pageResult = segmentService.getKnowledgeSegmentPage(pageReqVO); 58 PageResult<AiKnowledgeSegmentDO> pageResult = segmentService.getKnowledgeSegmentPage(pageReqVO);
50 return success(BeanUtils.toBean(pageResult, AiKnowledgeSegmentRespVO.class)); 59 return success(BeanUtils.toBean(pageResult, AiKnowledgeSegmentRespVO.class));
51 } 60 }
52 61
  62 + @PostMapping("/create")
  63 + @Operation(summary = "创建段落")
  64 + @PreAuthorize("@ss.hasPermission('ai:knowledge:create')")
  65 + public CommonResult<Long> createKnowledgeSegment(@Valid @RequestBody AiKnowledgeSegmentSaveReqVO createReqVO) {
  66 + return success(segmentService.createKnowledgeSegment(createReqVO));
  67 + }
  68 +
53 @PutMapping("/update") 69 @PutMapping("/update")
54 @Operation(summary = "更新段落内容") 70 @Operation(summary = "更新段落内容")
55 - public CommonResult<Boolean> updateKnowledgeSegment(@Valid @RequestBody AiKnowledgeSegmentUpdateReqVO reqVO) { 71 + @PreAuthorize("@ss.hasPermission('ai:knowledge:update')")
  72 + public CommonResult<Boolean> updateKnowledgeSegment(@Valid @RequestBody AiKnowledgeSegmentSaveReqVO reqVO) {
56 segmentService.updateKnowledgeSegment(reqVO); 73 segmentService.updateKnowledgeSegment(reqVO);
57 return success(true); 74 return success(true);
58 } 75 }
59 76
60 @PutMapping("/update-status") 77 @PutMapping("/update-status")
61 @Operation(summary = "启禁用段落内容") 78 @Operation(summary = "启禁用段落内容")
  79 + @PreAuthorize("@ss.hasPermission('ai:knowledge:update')")
62 public CommonResult<Boolean> updateKnowledgeSegmentStatus( 80 public CommonResult<Boolean> updateKnowledgeSegmentStatus(
63 @Valid @RequestBody AiKnowledgeSegmentUpdateStatusReqVO reqVO) { 81 @Valid @RequestBody AiKnowledgeSegmentUpdateStatusReqVO reqVO) {
64 segmentService.updateKnowledgeSegmentStatus(reqVO); 82 segmentService.updateKnowledgeSegmentStatus(reqVO);
@@ -71,6 +89,7 @@ public class AiKnowledgeSegmentController { @@ -71,6 +89,7 @@ public class AiKnowledgeSegmentController {
71 @Parameter(name = "url", description = "文档 URL", required = true), 89 @Parameter(name = "url", description = "文档 URL", required = true),
72 @Parameter(name = "segmentMaxTokens", description = "分段的最大 Token 数", required = true) 90 @Parameter(name = "segmentMaxTokens", description = "分段的最大 Token 数", required = true)
73 }) 91 })
  92 + @PreAuthorize("@ss.hasPermission('ai:knowledge:query')")
74 public CommonResult<List<AiKnowledgeSegmentRespVO>> splitContent( 93 public CommonResult<List<AiKnowledgeSegmentRespVO>> splitContent(
75 @RequestParam("url") @URL String url, 94 @RequestParam("url") @URL String url,
76 @RequestParam(value = "segmentMaxTokens") Integer segmentMaxTokens) { 95 @RequestParam(value = "segmentMaxTokens") Integer segmentMaxTokens) {
@@ -81,6 +100,7 @@ public class AiKnowledgeSegmentController { @@ -81,6 +100,7 @@ public class AiKnowledgeSegmentController {
81 @GetMapping("/get-process-list") 100 @GetMapping("/get-process-list")
82 @Operation(summary = "获取文档处理列表") 101 @Operation(summary = "获取文档处理列表")
83 @Parameter(name = "documentIds", description = "文档编号列表", required = true, example = "1,2,3") 102 @Parameter(name = "documentIds", description = "文档编号列表", required = true, example = "1,2,3")
  103 + @PreAuthorize("@ss.hasPermission('ai:knowledge:query')")
84 public CommonResult<List<AiKnowledgeSegmentProcessRespVO>> getKnowledgeSegmentProcessList( 104 public CommonResult<List<AiKnowledgeSegmentProcessRespVO>> getKnowledgeSegmentProcessList(
85 @RequestParam("documentIds") List<Long> documentIds) { 105 @RequestParam("documentIds") List<Long> documentIds) {
86 List<AiKnowledgeSegmentProcessRespVO> list = segmentService.getKnowledgeSegmentProcessList(documentIds); 106 List<AiKnowledgeSegmentProcessRespVO> list = segmentService.getKnowledgeSegmentProcessList(documentIds);
@@ -89,6 +109,7 @@ public class AiKnowledgeSegmentController { @@ -89,6 +109,7 @@ public class AiKnowledgeSegmentController {
89 109
90 @GetMapping("/search") 110 @GetMapping("/search")
91 @Operation(summary = "搜索段落内容") 111 @Operation(summary = "搜索段落内容")
  112 + @PreAuthorize("@ss.hasPermission('ai:knowledge:query')")
92 public CommonResult<List<AiKnowledgeSegmentSearchRespVO>> searchKnowledgeSegment( 113 public CommonResult<List<AiKnowledgeSegmentSearchRespVO>> searchKnowledgeSegment(
93 @Valid AiKnowledgeSegmentSearchReqVO reqVO) { 114 @Valid AiKnowledgeSegmentSearchReqVO reqVO) {
94 // 1. 搜索段落 115 // 1. 搜索段落
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/knowledge/vo/segment/AiKnowledgeSegmentPageReqVO.java
1 package cn.iocoder.yudao.module.ai.controller.admin.knowledge.vo.segment; 1 package cn.iocoder.yudao.module.ai.controller.admin.knowledge.vo.segment;
2 2
  3 +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
3 import cn.iocoder.yudao.framework.common.pojo.PageParam; 4 import cn.iocoder.yudao.framework.common.pojo.PageParam;
  5 +import cn.iocoder.yudao.framework.common.validation.InEnum;
4 import io.swagger.v3.oas.annotations.media.Schema; 6 import io.swagger.v3.oas.annotations.media.Schema;
5 import lombok.Data; 7 import lombok.Data;
6 8
@@ -8,13 +10,14 @@ import lombok.Data; @@ -8,13 +10,14 @@ import lombok.Data;
8 @Data 10 @Data
9 public class AiKnowledgeSegmentPageReqVO extends PageParam { 11 public class AiKnowledgeSegmentPageReqVO extends PageParam {
10 12
11 - @Schema(description = "分段状态", example = "1")  
12 - private Integer status;  
13 -  
14 @Schema(description = "文档编号", example = "1") 13 @Schema(description = "文档编号", example = "1")
15 private Integer documentId; 14 private Integer documentId;
16 15
17 @Schema(description = "分段内容关键字", example = "Java 开发") 16 @Schema(description = "分段内容关键字", example = "Java 开发")
18 - private String keyword; 17 + private String content;
  18 +
  19 + @Schema(description = "分段状态", example = "1")
  20 + @InEnum(CommonStatusEnum.class)
  21 + private Integer status;
19 22
20 } 23 }
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/knowledge/vo/segment/AiKnowledgeSegmentUpdateReqVO.java deleted
1 -package cn.iocoder.yudao.module.ai.controller.admin.knowledge.vo.segment;  
2 -  
3 -import io.swagger.v3.oas.annotations.media.Schema;  
4 -import lombok.Data;  
5 -  
6 -  
7 -@Schema(description = "管理后台 - AI 更新 知识库段落 request VO")  
8 -@Data  
9 -public class AiKnowledgeSegmentUpdateReqVO {  
10 -  
11 - @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "24790")  
12 - private Long id;  
13 -  
14 - @Schema(description = "切片内容", requiredMode = Schema.RequiredMode.REQUIRED, example = "Java 开发手册")  
15 - private String content;  
16 -  
17 -}  
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&lt;AiKnowledgeSegment @@ -25,8 +25,8 @@ public interface AiKnowledgeSegmentMapper extends BaseMapperX&lt;AiKnowledgeSegment
25 default PageResult<AiKnowledgeSegmentDO> selectPage(AiKnowledgeSegmentPageReqVO reqVO) { 25 default PageResult<AiKnowledgeSegmentDO> selectPage(AiKnowledgeSegmentPageReqVO reqVO) {
26 return selectPage(reqVO, new LambdaQueryWrapperX<AiKnowledgeSegmentDO>() 26 return selectPage(reqVO, new LambdaQueryWrapperX<AiKnowledgeSegmentDO>()
27 .eq(AiKnowledgeSegmentDO::getDocumentId, reqVO.getDocumentId()) 27 .eq(AiKnowledgeSegmentDO::getDocumentId, reqVO.getDocumentId())
  28 + .likeIfPresent(AiKnowledgeSegmentDO::getContent, reqVO.getContent())
28 .eqIfPresent(AiKnowledgeSegmentDO::getStatus, reqVO.getStatus()) 29 .eqIfPresent(AiKnowledgeSegmentDO::getStatus, reqVO.getStatus())
29 - .likeIfPresent(AiKnowledgeSegmentDO::getContent, reqVO.getKeyword())  
30 .orderByDesc(AiKnowledgeSegmentDO::getId)); 30 .orderByDesc(AiKnowledgeSegmentDO::getId));
31 } 31 }
32 32
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/service/knowledge/AiKnowledgeDocumentService.java
@@ -75,6 +75,13 @@ public interface AiKnowledgeDocumentService { @@ -75,6 +75,13 @@ public interface AiKnowledgeDocumentService {
75 void updateKnowledgeDocumentRetrievalCountIncr(Collection<Long> ids); 75 void updateKnowledgeDocumentRetrievalCountIncr(Collection<Long> ids);
76 76
77 /** 77 /**
  78 + * 删除文档
  79 + *
  80 + * @param id 文档编号
  81 + */
  82 + void deleteKnowledgeDocument(Long id);
  83 +
  84 + /**
78 * 校验文档是否存在 85 * 校验文档是否存在
79 * 86 *
80 * @param id 文档编号 87 * @param id 文档编号
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/service/knowledge/AiKnowledgeDocumentServiceImpl.java
@@ -150,6 +150,19 @@ public class AiKnowledgeDocumentServiceImpl implements AiKnowledgeDocumentServic @@ -150,6 +150,19 @@ public class AiKnowledgeDocumentServiceImpl implements AiKnowledgeDocumentServic
150 } 150 }
151 151
152 @Override 152 @Override
  153 + @Transactional(rollbackFor = Exception.class)
  154 + public void deleteKnowledgeDocument(Long id) {
  155 + // 1. 校验存在
  156 + validateKnowledgeDocumentExists(id);
  157 +
  158 + // 2. 删除
  159 + knowledgeDocumentMapper.deleteById(id);
  160 +
  161 + // 3. 删除对应的段落
  162 + knowledgeSegmentService.deleteKnowledgeSegmentByDocumentId(id);
  163 + }
  164 +
  165 + @Override
153 public void updateKnowledgeDocumentRetrievalCountIncr(Collection<Long> ids) { 166 public void updateKnowledgeDocumentRetrievalCountIncr(Collection<Long> ids) {
154 if (CollUtil.isEmpty(ids)) { 167 if (CollUtil.isEmpty(ids)) {
155 return; 168 return;
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; @@ -3,7 +3,7 @@ package cn.iocoder.yudao.module.ai.service.knowledge;
3 import cn.iocoder.yudao.framework.common.pojo.PageResult; 3 import cn.iocoder.yudao.framework.common.pojo.PageResult;
4 import cn.iocoder.yudao.module.ai.controller.admin.knowledge.vo.segment.AiKnowledgeSegmentPageReqVO; 4 import cn.iocoder.yudao.module.ai.controller.admin.knowledge.vo.segment.AiKnowledgeSegmentPageReqVO;
5 import cn.iocoder.yudao.module.ai.controller.admin.knowledge.vo.segment.AiKnowledgeSegmentProcessRespVO; 5 import cn.iocoder.yudao.module.ai.controller.admin.knowledge.vo.segment.AiKnowledgeSegmentProcessRespVO;
6 -import cn.iocoder.yudao.module.ai.controller.admin.knowledge.vo.segment.AiKnowledgeSegmentUpdateReqVO; 6 +import cn.iocoder.yudao.module.ai.controller.admin.knowledge.vo.segment.AiKnowledgeSegmentSaveReqVO;
7 import cn.iocoder.yudao.module.ai.controller.admin.knowledge.vo.segment.AiKnowledgeSegmentUpdateStatusReqVO; 7 import cn.iocoder.yudao.module.ai.controller.admin.knowledge.vo.segment.AiKnowledgeSegmentUpdateStatusReqVO;
8 import cn.iocoder.yudao.module.ai.dal.dataobject.knowledge.AiKnowledgeSegmentDO; 8 import cn.iocoder.yudao.module.ai.dal.dataobject.knowledge.AiKnowledgeSegmentDO;
9 import cn.iocoder.yudao.module.ai.service.knowledge.bo.AiKnowledgeSegmentSearchReqBO; 9 import cn.iocoder.yudao.module.ai.service.knowledge.bo.AiKnowledgeSegmentSearchReqBO;
@@ -20,6 +20,14 @@ import java.util.List; @@ -20,6 +20,14 @@ import java.util.List;
20 public interface AiKnowledgeSegmentService { 20 public interface AiKnowledgeSegmentService {
21 21
22 /** 22 /**
  23 + * 获取知识库段落详情
  24 + *
  25 + * @param id 段落编号
  26 + * @return 段落详情
  27 + */
  28 + AiKnowledgeSegmentDO getKnowledgeSegment(Long id);
  29 +
  30 + /**
23 * 获取段落分页 31 * 获取段落分页
24 * 32 *
25 * @param pageReqVO 分页查询 33 * @param pageReqVO 分页查询
@@ -47,11 +55,19 @@ public interface AiKnowledgeSegmentService { @@ -47,11 +55,19 @@ public interface AiKnowledgeSegmentService {
47 } 55 }
48 56
49 /** 57 /**
  58 + * 创建知识库段落
  59 + *
  60 + * @param createReqVO 创建信息
  61 + * @return 段落编号
  62 + */
  63 + Long createKnowledgeSegment(AiKnowledgeSegmentSaveReqVO createReqVO);
  64 +
  65 + /**
50 * 更新段落的内容 66 * 更新段落的内容
51 * 67 *
52 * @param reqVO 更新内容 68 * @param reqVO 更新内容
53 */ 69 */
54 - void updateKnowledgeSegment(AiKnowledgeSegmentUpdateReqVO reqVO); 70 + void updateKnowledgeSegment(AiKnowledgeSegmentSaveReqVO reqVO);
55 71
56 /** 72 /**
57 * 更新段落的状态 73 * 更新段落的状态
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; @@ -34,6 +34,7 @@ import java.util.Objects;
34 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; 34 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
35 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList; 35 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
36 import static cn.iocoder.yudao.module.ai.enums.ErrorCodeConstants.KNOWLEDGE_SEGMENT_NOT_EXISTS; 36 import static cn.iocoder.yudao.module.ai.enums.ErrorCodeConstants.KNOWLEDGE_SEGMENT_NOT_EXISTS;
  37 +import static cn.iocoder.yudao.module.ai.enums.ErrorCodeConstants.KNOWLEDGE_SEGMENT_CONTENT_TOO_LONG;
37 38
38 /** 39 /**
39 * AI 知识库分片 Service 实现类 40 * AI 知识库分片 Service 实现类
@@ -98,20 +99,20 @@ public class AiKnowledgeSegmentServiceImpl implements AiKnowledgeSegmentService @@ -98,20 +99,20 @@ public class AiKnowledgeSegmentServiceImpl implements AiKnowledgeSegmentService
98 } 99 }
99 100
100 @Override 101 @Override
101 - public void updateKnowledgeSegment(AiKnowledgeSegmentUpdateReqVO reqVO) { 102 + public void updateKnowledgeSegment(AiKnowledgeSegmentSaveReqVO reqVO) {
102 // 1. 校验 103 // 1. 校验
103 - AiKnowledgeSegmentDO segment = validateKnowledgeSegmentExists(reqVO.getId()); 104 + AiKnowledgeSegmentDO oldSegment = validateKnowledgeSegmentExists(reqVO.getId());
104 105
105 // 2. 删除向量 106 // 2. 删除向量
106 - VectorStore vectorStore = getVectorStoreById(segment.getKnowledgeId());  
107 - deleteVectorStore(vectorStore, segment); 107 + VectorStore vectorStore = getVectorStoreById(oldSegment.getKnowledgeId());
  108 + deleteVectorStore(vectorStore, oldSegment);
108 109
109 // 3.1 更新切片 110 // 3.1 更新切片
110 - AiKnowledgeSegmentDO segmentDO = BeanUtils.toBean(reqVO, AiKnowledgeSegmentDO.class);  
111 - segmentMapper.updateById(segmentDO); 111 + AiKnowledgeSegmentDO newSegment = BeanUtils.toBean(reqVO, AiKnowledgeSegmentDO.class);
  112 + segmentMapper.updateById(newSegment);
112 // 3.2 重新向量化,必须开启状态 113 // 3.2 重新向量化,必须开启状态
113 - if (CommonStatusEnum.isEnable(segmentDO.getStatus())) {  
114 - writeVectorStore(vectorStore, segmentDO, new Document(segmentDO.getContent())); 114 + if (CommonStatusEnum.isEnable(oldSegment.getStatus())) {
  115 + writeVectorStore(vectorStore, newSegment, new Document(newSegment.getContent()));
115 } 116 }
116 } 117 }
117 118
@@ -143,7 +144,7 @@ public class AiKnowledgeSegmentServiceImpl implements AiKnowledgeSegmentService @@ -143,7 +144,7 @@ public class AiKnowledgeSegmentServiceImpl implements AiKnowledgeSegmentService
143 segmentMapper.updateById(new AiKnowledgeSegmentDO().setId(reqVO.getId()).setStatus(reqVO.getStatus())); 144 segmentMapper.updateById(new AiKnowledgeSegmentDO().setId(reqVO.getId()).setStatus(reqVO.getStatus()));
144 145
145 // 4. 更新向量 146 // 4. 更新向量
146 - if (Objects.equals(reqVO.getStatus(), CommonStatusEnum.ENABLE.getStatus())) { 147 + if (CommonStatusEnum.isEnable(reqVO.getStatus())) {
147 writeVectorStore(vectorStore, segment, new Document(segment.getContent())); 148 writeVectorStore(vectorStore, segment, new Document(segment.getContent()));
148 } else { 149 } else {
149 deleteVectorStore(vectorStore, segment); 150 deleteVectorStore(vectorStore, segment);
@@ -183,7 +184,8 @@ public class AiKnowledgeSegmentServiceImpl implements AiKnowledgeSegmentService @@ -183,7 +184,8 @@ public class AiKnowledgeSegmentServiceImpl implements AiKnowledgeSegmentService
183 List<Document> documents = vectorStore.similaritySearch(SearchRequest.builder() 184 List<Document> documents = vectorStore.similaritySearch(SearchRequest.builder()
184 .query(reqBO.getContent()) 185 .query(reqBO.getContent())
185 .topK(ObjUtil.defaultIfNull(reqBO.getTopK(), knowledge.getTopK())) 186 .topK(ObjUtil.defaultIfNull(reqBO.getTopK(), knowledge.getTopK()))
186 - .similarityThreshold(ObjUtil.defaultIfNull(reqBO.getSimilarityThreshold(), knowledge.getSimilarityThreshold())) 187 + .similarityThreshold(
  188 + ObjUtil.defaultIfNull(reqBO.getSimilarityThreshold(), knowledge.getSimilarityThreshold()))
187 .filterExpression(new FilterExpressionBuilder() 189 .filterExpression(new FilterExpressionBuilder()
188 .eq(VECTOR_STORE_METADATA_KNOWLEDGE_ID, reqBO.getKnowledgeId()).build()) 190 .eq(VECTOR_STORE_METADATA_KNOWLEDGE_ID, reqBO.getKnowledgeId()).build())
189 .build()); 191 .build());
@@ -202,7 +204,7 @@ public class AiKnowledgeSegmentServiceImpl implements AiKnowledgeSegmentService @@ -202,7 +204,7 @@ public class AiKnowledgeSegmentServiceImpl implements AiKnowledgeSegmentService
202 204
203 // 4. 构建结果 205 // 4. 构建结果
204 List<AiKnowledgeSegmentSearchRespBO> result = convertList(segments, segment -> { 206 List<AiKnowledgeSegmentSearchRespBO> result = convertList(segments, segment -> {
205 - Document document = CollUtil.findOne(documents, // 找到对应的文档 207 + Document document = CollUtil.findOne(documents, // 找到对应的文档
206 doc -> Objects.equals(doc.getId(), segment.getVectorId())); 208 doc -> Objects.equals(doc.getId(), segment.getVectorId()));
207 if (document == null) { 209 if (document == null) {
208 return null; 210 return null;
@@ -210,8 +212,7 @@ public class AiKnowledgeSegmentServiceImpl implements AiKnowledgeSegmentService @@ -210,8 +212,7 @@ public class AiKnowledgeSegmentServiceImpl implements AiKnowledgeSegmentService
210 return BeanUtils.toBean(segment, AiKnowledgeSegmentSearchRespBO.class) 212 return BeanUtils.toBean(segment, AiKnowledgeSegmentSearchRespBO.class)
211 .setScore(document.getScore()); 213 .setScore(document.getScore());
212 }); 214 });
213 - result.sort((o1, o2)  
214 - -> Double.compare(o2.getScore(), o1.getScore())); // 按照分数降序排序 215 + result.sort((o1, o2) -> Double.compare(o2.getScore(), o1.getScore())); // 按照分数降序排序
215 return result; 216 return result;
216 } 217 }
217 218
@@ -280,4 +281,35 @@ public class AiKnowledgeSegmentServiceImpl implements AiKnowledgeSegmentService @@ -280,4 +281,35 @@ public class AiKnowledgeSegmentServiceImpl implements AiKnowledgeSegmentService
280 return segmentMapper.selectProcessList(documentIds); 281 return segmentMapper.selectProcessList(documentIds);
281 } 282 }
282 283
  284 + @Override
  285 + public Long createKnowledgeSegment(AiKnowledgeSegmentSaveReqVO createReqVO) {
  286 + // 1.1 校验文档是否存在
  287 + AiKnowledgeDocumentDO document = knowledgeDocumentService
  288 + .validateKnowledgeDocumentExists(createReqVO.getDocumentId());
  289 + // 1.2 获取知识库信息
  290 + AiKnowledgeDO knowledge = knowledgeService.validateKnowledgeExists(document.getKnowledgeId());
  291 + // 1.3 校验 token 熟练
  292 + Integer tokens = tokenCountEstimator.estimate(createReqVO.getContent());
  293 + if (tokens > document.getSegmentMaxTokens()) {
  294 + throw exception(KNOWLEDGE_SEGMENT_CONTENT_TOO_LONG, tokens, document.getSegmentMaxTokens());
  295 + }
  296 +
  297 + // 2. 保存段落
  298 + AiKnowledgeSegmentDO segment = BeanUtils.toBean(createReqVO, AiKnowledgeSegmentDO.class)
  299 + .setKnowledgeId(knowledge.getId()).setDocumentId(document.getId())
  300 + .setContentLength(createReqVO.getContent().length()).setTokens(tokens)
  301 + .setVectorId(AiKnowledgeSegmentDO.VECTOR_ID_EMPTY)
  302 + .setRetrievalCount(0).setStatus(CommonStatusEnum.ENABLE.getStatus());
  303 + segmentMapper.insert(segment);
  304 +
  305 + // 3. 向量化
  306 + writeVectorStore(getVectorStoreById(knowledge), segment, new Document(segment.getContent()));
  307 + return segment.getId();
  308 + }
  309 +
  310 + @Override
  311 + public AiKnowledgeSegmentDO getKnowledgeSegment(Long id) {
  312 + return validateKnowledgeSegmentExists(id);
  313 + }
  314 +
283 } 315 }