Commit 3f460dc620b306f995768354cdc6be227072b947
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<AiKnowledgeSegment | @@ -25,8 +25,8 @@ public interface AiKnowledgeSegmentMapper extends BaseMapperX<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 | } |