Commit 1e8845ce6d229130ae4a804e578d52cf20f5fa15
1 parent
e869aaee
【功能新增】AI:增加 AI 对话,与 tool 的打通
Showing
10 changed files
with
147 additions
and
33 deletions
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/model/AiToolController.java
| 1 | 1 | package cn.iocoder.yudao.module.ai.controller.admin.model; |
| 2 | 2 | |
| 3 | +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; | |
| 3 | 4 | import cn.iocoder.yudao.framework.common.pojo.CommonResult; |
| 4 | 5 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 5 | 6 | import cn.iocoder.yudao.framework.common.util.object.BeanUtils; |
| ... | ... | @@ -17,8 +18,10 @@ import org.springframework.security.access.prepost.PreAuthorize; |
| 17 | 18 | import org.springframework.validation.annotation.Validated; |
| 18 | 19 | import org.springframework.web.bind.annotation.*; |
| 19 | 20 | |
| 20 | -import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; | |
| 21 | +import java.util.List; | |
| 21 | 22 | |
| 23 | +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; | |
| 24 | +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList; | |
| 22 | 25 | |
| 23 | 26 | @Tag(name = "管理后台 - AI 工具") |
| 24 | 27 | @RestController |
| ... | ... | @@ -30,14 +33,14 @@ public class AiToolController { |
| 30 | 33 | private AiToolService toolService; |
| 31 | 34 | |
| 32 | 35 | @PostMapping("/create") |
| 33 | - @Operation(summary = "创建AI 工具") | |
| 36 | + @Operation(summary = "创建工具") | |
| 34 | 37 | @PreAuthorize("@ss.hasPermission('ai:tool:create')") |
| 35 | 38 | public CommonResult<Long> createTool(@Valid @RequestBody AiToolSaveReqVO createReqVO) { |
| 36 | 39 | return success(toolService.createTool(createReqVO)); |
| 37 | 40 | } |
| 38 | 41 | |
| 39 | 42 | @PutMapping("/update") |
| 40 | - @Operation(summary = "更新AI 工具") | |
| 43 | + @Operation(summary = "更新工具") | |
| 41 | 44 | @PreAuthorize("@ss.hasPermission('ai:tool:update')") |
| 42 | 45 | public CommonResult<Boolean> updateTool(@Valid @RequestBody AiToolSaveReqVO updateReqVO) { |
| 43 | 46 | toolService.updateTool(updateReqVO); |
| ... | ... | @@ -45,7 +48,7 @@ public class AiToolController { |
| 45 | 48 | } |
| 46 | 49 | |
| 47 | 50 | @DeleteMapping("/delete") |
| 48 | - @Operation(summary = "删除AI 工具") | |
| 51 | + @Operation(summary = "删除工具") | |
| 49 | 52 | @Parameter(name = "id", description = "编号", required = true) |
| 50 | 53 | @PreAuthorize("@ss.hasPermission('ai:tool:delete')") |
| 51 | 54 | public CommonResult<Boolean> deleteTool(@RequestParam("id") Long id) { |
| ... | ... | @@ -54,7 +57,7 @@ public class AiToolController { |
| 54 | 57 | } |
| 55 | 58 | |
| 56 | 59 | @GetMapping("/get") |
| 57 | - @Operation(summary = "获得AI 工具") | |
| 60 | + @Operation(summary = "获得工具") | |
| 58 | 61 | @Parameter(name = "id", description = "编号", required = true, example = "1024") |
| 59 | 62 | @PreAuthorize("@ss.hasPermission('ai:tool:query')") |
| 60 | 63 | public CommonResult<AiToolRespVO> getTool(@RequestParam("id") Long id) { |
| ... | ... | @@ -63,11 +66,19 @@ public class AiToolController { |
| 63 | 66 | } |
| 64 | 67 | |
| 65 | 68 | @GetMapping("/page") |
| 66 | - @Operation(summary = "获得AI 工具分页") | |
| 69 | + @Operation(summary = "获得工具分页") | |
| 67 | 70 | @PreAuthorize("@ss.hasPermission('ai:tool:query')") |
| 68 | 71 | public CommonResult<PageResult<AiToolRespVO>> getToolPage(@Valid AiToolPageReqVO pageReqVO) { |
| 69 | 72 | PageResult<AiToolDO> pageResult = toolService.getToolPage(pageReqVO); |
| 70 | 73 | return success(BeanUtils.toBean(pageResult, AiToolRespVO.class)); |
| 71 | 74 | } |
| 72 | 75 | |
| 76 | + @GetMapping("/simple-list") | |
| 77 | + @Operation(summary = "获得工具列表") | |
| 78 | + public CommonResult<List<AiToolRespVO>> getToolSimpleList() { | |
| 79 | + List<AiToolDO> list = toolService.getToolListByStatus(CommonStatusEnum.ENABLE.getStatus()); | |
| 80 | + return success(convertList(list, tool -> new AiToolRespVO() | |
| 81 | + .setId(tool.getId()).setName(tool.getName()))); | |
| 82 | + } | |
| 83 | + | |
| 73 | 84 | } |
| 74 | 85 | \ No newline at end of file | ... | ... |
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/model/vo/chatRole/AiChatRoleRespVO.java
| ... | ... | @@ -49,6 +49,9 @@ public class AiChatRoleRespVO implements VO { |
| 49 | 49 | @Schema(description = "引用的知识库编号列表", example = "1,2,3") |
| 50 | 50 | private List<Long> knowledgeIds; |
| 51 | 51 | |
| 52 | + @Schema(description = "引用的工具编号列表", example = "1,2,3") | |
| 53 | + private List<Long> toolIds; | |
| 54 | + | |
| 52 | 55 | @Schema(description = "是否公开", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") |
| 53 | 56 | private Boolean publicStatus; |
| 54 | 57 | ... | ... |
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/model/vo/chatRole/AiChatRoleSaveMyReqVO.java
| ... | ... | @@ -34,4 +34,7 @@ public class AiChatRoleSaveMyReqVO { |
| 34 | 34 | @Schema(description = "引用的知识库编号列表", example = "1,2,3") |
| 35 | 35 | private List<Long> knowledgeIds; |
| 36 | 36 | |
| 37 | + @Schema(description = "引用的工具编号列表", example = "1,2,3") | |
| 38 | + private List<Long> toolIds; | |
| 39 | + | |
| 37 | 40 | } |
| 38 | 41 | \ No newline at end of file | ... | ... |
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/model/vo/chatRole/AiChatRoleSaveReqVO.java
| ... | ... | @@ -47,6 +47,9 @@ public class AiChatRoleSaveReqVO { |
| 47 | 47 | @Schema(description = "引用的知识库编号列表", example = "1,2,3") |
| 48 | 48 | private List<Long> knowledgeIds; |
| 49 | 49 | |
| 50 | + @Schema(description = "引用的工具编号列表", example = "1,2,3") | |
| 51 | + private List<Long> toolIds; | |
| 52 | + | |
| 50 | 53 | @Schema(description = "是否公开", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") |
| 51 | 54 | @NotNull(message = "是否公开不能为空") |
| 52 | 55 | private Boolean publicStatus; | ... | ... |
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/dal/dataobject/model/AiChatRoleDO.java
| ... | ... | @@ -74,6 +74,13 @@ public class AiChatRoleDO extends BaseDO { |
| 74 | 74 | */ |
| 75 | 75 | @TableField(typeHandler = LongListTypeHandler.class) |
| 76 | 76 | private List<Long> knowledgeIds; |
| 77 | + /** | |
| 78 | + * 引用的工具编号列表 | |
| 79 | + * | |
| 80 | + * 关联 {@link AiToolDO#getId()} 字段 | |
| 81 | + */ | |
| 82 | + @TableField(typeHandler = LongListTypeHandler.class) | |
| 83 | + private List<Long> toolIds; | |
| 77 | 84 | |
| 78 | 85 | /** |
| 79 | 86 | * 是否公开 | ... | ... |
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/dal/mysql/model/AiToolMapper.java
| ... | ... | @@ -7,6 +7,8 @@ import cn.iocoder.yudao.module.ai.controller.admin.model.vo.tool.AiToolPageReqVO |
| 7 | 7 | import cn.iocoder.yudao.module.ai.dal.dataobject.model.AiToolDO; |
| 8 | 8 | import org.apache.ibatis.annotations.Mapper; |
| 9 | 9 | |
| 10 | +import java.util.List; | |
| 11 | + | |
| 10 | 12 | /** |
| 11 | 13 | * AI 工具 Mapper |
| 12 | 14 | * |
| ... | ... | @@ -24,4 +26,10 @@ public interface AiToolMapper extends BaseMapperX<AiToolDO> { |
| 24 | 26 | .orderByDesc(AiToolDO::getId)); |
| 25 | 27 | } |
| 26 | 28 | |
| 29 | + default List<AiToolDO> selectListByStatus(Integer status) { | |
| 30 | + return selectList(new LambdaQueryWrapperX<AiToolDO>() | |
| 31 | + .eq(AiToolDO::getStatus, status) | |
| 32 | + .orderByDesc(AiToolDO::getId)); | |
| 33 | + } | |
| 34 | + | |
| 27 | 35 | } |
| 28 | 36 | \ No newline at end of file | ... | ... |
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/service/chat/AiChatMessageServiceImpl.java
| ... | ... | @@ -7,7 +7,6 @@ import cn.iocoder.yudao.framework.ai.core.enums.AiPlatformEnum; |
| 7 | 7 | import cn.iocoder.yudao.framework.ai.core.util.AiUtils; |
| 8 | 8 | import cn.iocoder.yudao.framework.common.pojo.CommonResult; |
| 9 | 9 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 10 | -import cn.iocoder.yudao.framework.common.util.collection.SetUtils; | |
| 11 | 10 | import cn.iocoder.yudao.framework.common.util.object.BeanUtils; |
| 12 | 11 | import cn.iocoder.yudao.framework.tenant.core.util.TenantUtils; |
| 13 | 12 | import cn.iocoder.yudao.module.ai.controller.admin.chat.vo.message.AiChatMessagePageReqVO; |
| ... | ... | @@ -19,6 +18,7 @@ import cn.iocoder.yudao.module.ai.dal.dataobject.chat.AiChatMessageDO; |
| 19 | 18 | import cn.iocoder.yudao.module.ai.dal.dataobject.knowledge.AiKnowledgeDocumentDO; |
| 20 | 19 | import cn.iocoder.yudao.module.ai.dal.dataobject.model.AiChatRoleDO; |
| 21 | 20 | import cn.iocoder.yudao.module.ai.dal.dataobject.model.AiModelDO; |
| 21 | +import cn.iocoder.yudao.module.ai.dal.dataobject.model.AiToolDO; | |
| 22 | 22 | import cn.iocoder.yudao.module.ai.dal.mysql.chat.AiChatMessageMapper; |
| 23 | 23 | import cn.iocoder.yudao.module.ai.enums.ErrorCodeConstants; |
| 24 | 24 | import cn.iocoder.yudao.module.ai.service.knowledge.AiKnowledgeDocumentService; |
| ... | ... | @@ -27,6 +27,7 @@ import cn.iocoder.yudao.module.ai.service.knowledge.bo.AiKnowledgeSegmentSearchR |
| 27 | 27 | import cn.iocoder.yudao.module.ai.service.knowledge.bo.AiKnowledgeSegmentSearchRespBO; |
| 28 | 28 | import cn.iocoder.yudao.module.ai.service.model.AiChatRoleService; |
| 29 | 29 | import cn.iocoder.yudao.module.ai.service.model.AiModelService; |
| 30 | +import cn.iocoder.yudao.module.ai.service.model.AiToolService; | |
| 30 | 31 | import jakarta.annotation.Resource; |
| 31 | 32 | import lombok.extern.slf4j.Slf4j; |
| 32 | 33 | import org.springframework.ai.chat.messages.Message; |
| ... | ... | @@ -50,6 +51,7 @@ import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionU |
| 50 | 51 | import static cn.iocoder.yudao.framework.common.pojo.CommonResult.error; |
| 51 | 52 | import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; |
| 52 | 53 | import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList; |
| 54 | +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; | |
| 53 | 55 | import static cn.iocoder.yudao.module.ai.enums.ErrorCodeConstants.CHAT_CONVERSATION_NOT_EXISTS; |
| 54 | 56 | import static cn.iocoder.yudao.module.ai.enums.ErrorCodeConstants.CHAT_MESSAGE_NOT_EXIST; |
| 55 | 57 | |
| ... | ... | @@ -82,6 +84,8 @@ public class AiChatMessageServiceImpl implements AiChatMessageService { |
| 82 | 84 | private AiKnowledgeSegmentService knowledgeSegmentService; |
| 83 | 85 | @Resource |
| 84 | 86 | private AiKnowledgeDocumentService knowledgeDocumentService; |
| 87 | + @Resource | |
| 88 | + private AiToolService toolService; | |
| 85 | 89 | |
| 86 | 90 | @Transactional(rollbackFor = Exception.class) |
| 87 | 91 | public AiChatMessageSendRespVO sendMessage(AiChatMessageSendReqVO sendReqVO, Long userId) { |
| ... | ... | @@ -118,11 +122,13 @@ public class AiChatMessageServiceImpl implements AiChatMessageService { |
| 118 | 122 | String newContent = chatResponse.getResult().getOutput().getText(); |
| 119 | 123 | chatMessageMapper.updateById(new AiChatMessageDO().setId(assistantMessage.getId()).setContent(newContent)); |
| 120 | 124 | // 3.4 响应结果 |
| 121 | - List<AiChatMessageRespVO.KnowledgeSegment> segments = BeanUtils.toBean(knowledgeSegments, AiChatMessageRespVO.KnowledgeSegment.class, | |
| 125 | + List<AiChatMessageRespVO.KnowledgeSegment> segments = BeanUtils.toBean(knowledgeSegments, | |
| 126 | + AiChatMessageRespVO.KnowledgeSegment.class, | |
| 122 | 127 | segment -> { |
| 123 | - AiKnowledgeDocumentDO document = knowledgeDocumentService.getKnowledgeDocument(segment.getDocumentId()); | |
| 124 | - segment.setDocumentName(document != null ? document.getName() : null); | |
| 125 | - }); | |
| 128 | + AiKnowledgeDocumentDO document = knowledgeDocumentService | |
| 129 | + .getKnowledgeDocument(segment.getDocumentId()); | |
| 130 | + segment.setDocumentName(document != null ? document.getName() : null); | |
| 131 | + }); | |
| 126 | 132 | return new AiChatMessageSendRespVO() |
| 127 | 133 | .setSend(BeanUtils.toBean(userMessage, AiChatMessageSendRespVO.Message.class)) |
| 128 | 134 | .setReceive(BeanUtils.toBean(assistantMessage, AiChatMessageSendRespVO.Message.class) |
| ... | ... | @@ -130,7 +136,8 @@ public class AiChatMessageServiceImpl implements AiChatMessageService { |
| 130 | 136 | } |
| 131 | 137 | |
| 132 | 138 | @Override |
| 133 | - public Flux<CommonResult<AiChatMessageSendRespVO>> sendChatMessageStream(AiChatMessageSendReqVO sendReqVO, Long userId) { | |
| 139 | + public Flux<CommonResult<AiChatMessageSendRespVO>> sendChatMessageStream(AiChatMessageSendReqVO sendReqVO, | |
| 140 | + Long userId) { | |
| 134 | 141 | // 1.1 校验对话存在 |
| 135 | 142 | AiChatConversationDO conversation = chatConversationService |
| 136 | 143 | .validateChatConversationExists(sendReqVO.getConversationId()); |
| ... | ... | @@ -143,7 +150,8 @@ public class AiChatMessageServiceImpl implements AiChatMessageService { |
| 143 | 150 | StreamingChatModel chatModel = modalService.getChatModel(model.getId()); |
| 144 | 151 | |
| 145 | 152 | // 2. 知识库找回 |
| 146 | - List<AiKnowledgeSegmentSearchRespBO> knowledgeSegments = recallKnowledgeSegment(sendReqVO.getContent(), conversation); | |
| 153 | + List<AiKnowledgeSegmentSearchRespBO> knowledgeSegments = recallKnowledgeSegment(sendReqVO.getContent(), | |
| 154 | + conversation); | |
| 147 | 155 | |
| 148 | 156 | // 3. 插入 user 发送消息 |
| 149 | 157 | AiChatMessageDO userMessage = createChatMessage(conversation.getId(), null, model, |
| ... | ... | @@ -167,7 +175,8 @@ public class AiChatMessageServiceImpl implements AiChatMessageService { |
| 167 | 175 | if (StrUtil.isEmpty(contentBuffer)) { |
| 168 | 176 | segments = BeanUtils.toBean(knowledgeSegments, AiChatMessageRespVO.KnowledgeSegment.class, |
| 169 | 177 | segment -> TenantUtils.executeIgnore(() -> { |
| 170 | - AiKnowledgeDocumentDO document = knowledgeDocumentService.getKnowledgeDocument(segment.getDocumentId()); | |
| 178 | + AiKnowledgeDocumentDO document = knowledgeDocumentService | |
| 179 | + .getKnowledgeDocument(segment.getDocumentId()); | |
| 171 | 180 | segment.setDocumentName(document != null ? document.getName() : null); |
| 172 | 181 | })); |
| 173 | 182 | } |
| ... | ... | @@ -192,7 +201,7 @@ public class AiChatMessageServiceImpl implements AiChatMessageService { |
| 192 | 201 | } |
| 193 | 202 | |
| 194 | 203 | private List<AiKnowledgeSegmentSearchRespBO> recallKnowledgeSegment(String content, |
| 195 | - AiChatConversationDO conversation) { | |
| 204 | + AiChatConversationDO conversation) { | |
| 196 | 205 | // 1. 查询聊天角色 |
| 197 | 206 | if (conversation == null || conversation.getRoleId() == null) { |
| 198 | 207 | return Collections.emptyList(); |
| ... | ... | @@ -212,8 +221,8 @@ public class AiChatMessageServiceImpl implements AiChatMessageService { |
| 212 | 221 | } |
| 213 | 222 | |
| 214 | 223 | private Prompt buildPrompt(AiChatConversationDO conversation, List<AiChatMessageDO> messages, |
| 215 | - List<AiKnowledgeSegmentSearchRespBO> knowledgeSegments, | |
| 216 | - AiModelDO model, AiChatMessageSendReqVO sendReqVO) { | |
| 224 | + List<AiKnowledgeSegmentSearchRespBO> knowledgeSegments, | |
| 225 | + AiModelDO model, AiChatMessageSendReqVO sendReqVO) { | |
| 217 | 226 | List<Message> chatMessages = new ArrayList<>(); |
| 218 | 227 | // 1.1 System Context 角色设定 |
| 219 | 228 | if (StrUtil.isNotBlank(conversation.getSystemMessage())) { |
| ... | ... | @@ -236,11 +245,18 @@ public class AiChatMessageServiceImpl implements AiChatMessageService { |
| 236 | 245 | chatMessages.add(new UserMessage(String.format(KNOWLEDGE_USER_MESSAGE_TEMPLATE, reference))); |
| 237 | 246 | } |
| 238 | 247 | |
| 239 | - // 2. 构建 ChatOptions 对象 | |
| 248 | + // 2.1 查询 tool 工具 | |
| 249 | + Set<String> toolNames = null; | |
| 250 | + if (conversation.getRoleId() != null) { | |
| 251 | + AiChatRoleDO chatRole = chatRoleService.getChatRole(conversation.getRoleId()); | |
| 252 | + if (chatRole != null && CollUtil.isNotEmpty(chatRole.getToolIds())) { | |
| 253 | + toolNames = convertSet(toolService.getToolList(chatRole.getToolIds()), AiToolDO::getName); | |
| 254 | + } | |
| 255 | + } | |
| 256 | + // 2.2 构建 ChatOptions 对象 | |
| 240 | 257 | AiPlatformEnum platform = AiPlatformEnum.validatePlatform(model.getPlatform()); |
| 241 | 258 | ChatOptions chatOptions = AiUtils.buildChatOptions(platform, model.getModel(), |
| 242 | - conversation.getTemperature(), conversation.getMaxTokens(), | |
| 243 | - SetUtils.asSet("directory_list", "weather_query")); | |
| 259 | + conversation.getTemperature(), conversation.getMaxTokens(), toolNames); | |
| 244 | 260 | return new Prompt(chatMessages, chatOptions); |
| 245 | 261 | } |
| 246 | 262 | |
| ... | ... | @@ -255,8 +271,8 @@ public class AiChatMessageServiceImpl implements AiChatMessageService { |
| 255 | 271 | * @return 消息上下文 |
| 256 | 272 | */ |
| 257 | 273 | private List<AiChatMessageDO> filterContextMessages(List<AiChatMessageDO> messages, |
| 258 | - AiChatConversationDO conversation, | |
| 259 | - AiChatMessageSendReqVO sendReqVO) { | |
| 274 | + AiChatConversationDO conversation, | |
| 275 | + AiChatMessageSendReqVO sendReqVO) { | |
| 260 | 276 | if (conversation.getMaxContexts() == null || ObjUtil.notEqual(sendReqVO.getUseContext(), Boolean.TRUE)) { |
| 261 | 277 | return Collections.emptyList(); |
| 262 | 278 | } |
| ... | ... | @@ -285,9 +301,9 @@ public class AiChatMessageServiceImpl implements AiChatMessageService { |
| 285 | 301 | } |
| 286 | 302 | |
| 287 | 303 | private AiChatMessageDO createChatMessage(Long conversationId, Long replyId, |
| 288 | - AiModelDO model, Long userId, Long roleId, | |
| 289 | - MessageType messageType, String content, Boolean useContext, | |
| 290 | - List<AiKnowledgeSegmentSearchRespBO> knowledgeSegments) { | |
| 304 | + AiModelDO model, Long userId, Long roleId, | |
| 305 | + MessageType messageType, String content, Boolean useContext, | |
| 306 | + List<AiKnowledgeSegmentSearchRespBO> knowledgeSegments) { | |
| 291 | 307 | AiChatMessageDO message = new AiChatMessageDO().setConversationId(conversationId).setReplyId(replyId) |
| 292 | 308 | .setModel(model.getModel()).setModelId(model.getId()).setUserId(userId).setRoleId(roleId) |
| 293 | 309 | .setType(messageType.getValue()).setContent(content).setUseContext(useContext) | ... | ... |
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/service/model/AiChatRoleServiceImpl.java
| ... | ... | @@ -39,11 +39,15 @@ public class AiChatRoleServiceImpl implements AiChatRoleService { |
| 39 | 39 | |
| 40 | 40 | @Resource |
| 41 | 41 | private AiKnowledgeService knowledgeService; |
| 42 | + @Resource | |
| 43 | + private AiToolService toolService; | |
| 42 | 44 | |
| 43 | 45 | @Override |
| 44 | 46 | public Long createChatRole(AiChatRoleSaveReqVO createReqVO) { |
| 45 | 47 | // 校验文档 |
| 46 | 48 | validateDocuments(createReqVO.getKnowledgeIds()); |
| 49 | + // 校验工具 | |
| 50 | + validateTools(createReqVO.getToolIds()); | |
| 47 | 51 | |
| 48 | 52 | // 保存角色 |
| 49 | 53 | AiChatRoleDO chatRole = BeanUtils.toBean(createReqVO, AiChatRoleDO.class); |
| ... | ... | @@ -55,6 +59,8 @@ public class AiChatRoleServiceImpl implements AiChatRoleService { |
| 55 | 59 | public Long createChatRoleMy(AiChatRoleSaveMyReqVO createReqVO, Long userId) { |
| 56 | 60 | // 校验文档 |
| 57 | 61 | validateDocuments(createReqVO.getKnowledgeIds()); |
| 62 | + // 校验工具 | |
| 63 | + validateTools(createReqVO.getToolIds()); | |
| 58 | 64 | |
| 59 | 65 | // 保存角色 |
| 60 | 66 | AiChatRoleDO chatRole = BeanUtils.toBean(createReqVO, AiChatRoleDO.class).setUserId(userId) |
| ... | ... | @@ -69,6 +75,8 @@ public class AiChatRoleServiceImpl implements AiChatRoleService { |
| 69 | 75 | validateChatRoleExists(updateReqVO.getId()); |
| 70 | 76 | // 校验文档 |
| 71 | 77 | validateDocuments(updateReqVO.getKnowledgeIds()); |
| 78 | + // 校验工具 | |
| 79 | + validateTools(updateReqVO.getToolIds()); | |
| 72 | 80 | |
| 73 | 81 | // 更新角色 |
| 74 | 82 | AiChatRoleDO updateObj = BeanUtils.toBean(updateReqVO, AiChatRoleDO.class); |
| ... | ... | @@ -84,6 +92,8 @@ public class AiChatRoleServiceImpl implements AiChatRoleService { |
| 84 | 92 | } |
| 85 | 93 | // 校验文档 |
| 86 | 94 | validateDocuments(updateReqVO.getKnowledgeIds()); |
| 95 | + // 校验工具 | |
| 96 | + validateTools(updateReqVO.getToolIds()); | |
| 87 | 97 | |
| 88 | 98 | // 更新 |
| 89 | 99 | AiChatRoleDO updateObj = BeanUtils.toBean(updateReqVO, AiChatRoleDO.class); |
| ... | ... | @@ -103,6 +113,19 @@ public class AiChatRoleServiceImpl implements AiChatRoleService { |
| 103 | 113 | knowledgeIds.forEach(knowledgeService::validateKnowledgeExists); |
| 104 | 114 | } |
| 105 | 115 | |
| 116 | + /** | |
| 117 | + * 校验工具是否存在 | |
| 118 | + * | |
| 119 | + * @param toolIds 工具编号列表 | |
| 120 | + */ | |
| 121 | + private void validateTools(List<Long> toolIds) { | |
| 122 | + if (CollUtil.isEmpty(toolIds)) { | |
| 123 | + return; | |
| 124 | + } | |
| 125 | + // 遍历校验每个工具是否存在 | |
| 126 | + toolIds.forEach(toolService::validateToolExists); | |
| 127 | + } | |
| 128 | + | |
| 106 | 129 | @Override |
| 107 | 130 | public void deleteChatRole(Long id) { |
| 108 | 131 | // 校验存在 | ... | ... |
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/service/model/AiToolService.java
| ... | ... | @@ -6,6 +6,9 @@ import cn.iocoder.yudao.module.ai.controller.admin.model.vo.tool.AiToolSaveReqVO |
| 6 | 6 | import cn.iocoder.yudao.module.ai.dal.dataobject.model.AiToolDO; |
| 7 | 7 | import jakarta.validation.Valid; |
| 8 | 8 | |
| 9 | +import java.util.Collection; | |
| 10 | +import java.util.List; | |
| 11 | + | |
| 9 | 12 | /** |
| 10 | 13 | * AI 工具 Service 接口 |
| 11 | 14 | * |
| ... | ... | @@ -14,7 +17,7 @@ import jakarta.validation.Valid; |
| 14 | 17 | public interface AiToolService { |
| 15 | 18 | |
| 16 | 19 | /** |
| 17 | - * 创建AI 工具 | |
| 20 | + * 创建工具 | |
| 18 | 21 | * |
| 19 | 22 | * @param createReqVO 创建信息 |
| 20 | 23 | * @return 编号 |
| ... | ... | @@ -22,33 +25,56 @@ public interface AiToolService { |
| 22 | 25 | Long createTool(@Valid AiToolSaveReqVO createReqVO); |
| 23 | 26 | |
| 24 | 27 | /** |
| 25 | - * 更新AI 工具 | |
| 28 | + * 更新工具 | |
| 26 | 29 | * |
| 27 | 30 | * @param updateReqVO 更新信息 |
| 28 | 31 | */ |
| 29 | 32 | void updateTool(@Valid AiToolSaveReqVO updateReqVO); |
| 30 | 33 | |
| 31 | 34 | /** |
| 32 | - * 删除AI 工具 | |
| 35 | + * 删除工具 | |
| 33 | 36 | * |
| 34 | 37 | * @param id 编号 |
| 35 | 38 | */ |
| 36 | 39 | void deleteTool(Long id); |
| 37 | 40 | |
| 38 | 41 | /** |
| 39 | - * 获得AI 工具 | |
| 42 | + * 校验工具是否存在 | |
| 40 | 43 | * |
| 41 | 44 | * @param id 编号 |
| 42 | - * @return AI 工具 | |
| 45 | + */ | |
| 46 | + void validateToolExists(Long id); | |
| 47 | + | |
| 48 | + /** | |
| 49 | + * 获得工具 | |
| 50 | + * | |
| 51 | + * @param id 编号 | |
| 52 | + * @return 工具 | |
| 43 | 53 | */ |
| 44 | 54 | AiToolDO getTool(Long id); |
| 45 | 55 | |
| 46 | 56 | /** |
| 47 | - * 获得AI 工具分页 | |
| 57 | + * 获得工具列表 | |
| 58 | + * | |
| 59 | + * @param ids 编号列表 | |
| 60 | + * @return 工具列表 | |
| 61 | + */ | |
| 62 | + List<AiToolDO> getToolList(Collection<Long> ids); | |
| 63 | + | |
| 64 | + /** | |
| 65 | + * 获得工具分页 | |
| 48 | 66 | * |
| 49 | 67 | * @param pageReqVO 分页查询 |
| 50 | - * @return AI 工具分页 | |
| 68 | + * @return 工具分页 | |
| 51 | 69 | */ |
| 52 | 70 | PageResult<AiToolDO> getToolPage(AiToolPageReqVO pageReqVO); |
| 53 | 71 | |
| 72 | + /** | |
| 73 | + * 获得工具列表 | |
| 74 | + * | |
| 75 | + * @param status 状态 | |
| 76 | + * @return 工具列表 | |
| 77 | + */ | |
| 78 | + List<AiToolDO> getToolListByStatus(Integer status); | |
| 79 | + | |
| 54 | 80 | } |
| 55 | 81 | \ No newline at end of file | ... | ... |
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/service/model/AiToolServiceImpl.java
| ... | ... | @@ -12,6 +12,9 @@ import org.springframework.beans.factory.NoSuchBeanDefinitionException; |
| 12 | 12 | import org.springframework.stereotype.Service; |
| 13 | 13 | import org.springframework.validation.annotation.Validated; |
| 14 | 14 | |
| 15 | +import java.util.Collection; | |
| 16 | +import java.util.List; | |
| 17 | + | |
| 15 | 18 | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; |
| 16 | 19 | import static cn.iocoder.yudao.module.ai.enums.ErrorCodeConstants.TOOL_NAME_NOT_EXISTS; |
| 17 | 20 | import static cn.iocoder.yudao.module.ai.enums.ErrorCodeConstants.TOOL_NOT_EXISTS; |
| ... | ... | @@ -59,7 +62,8 @@ public class AiToolServiceImpl implements AiToolService { |
| 59 | 62 | toolMapper.deleteById(id); |
| 60 | 63 | } |
| 61 | 64 | |
| 62 | - private void validateToolExists(Long id) { | |
| 65 | + @Override | |
| 66 | + public void validateToolExists(Long id) { | |
| 63 | 67 | if (toolMapper.selectById(id) == null) { |
| 64 | 68 | throw exception(TOOL_NOT_EXISTS); |
| 65 | 69 | } |
| ... | ... | @@ -79,8 +83,18 @@ public class AiToolServiceImpl implements AiToolService { |
| 79 | 83 | } |
| 80 | 84 | |
| 81 | 85 | @Override |
| 86 | + public List<AiToolDO> getToolList(Collection<Long> ids) { | |
| 87 | + return toolMapper.selectBatchIds(ids); | |
| 88 | + } | |
| 89 | + | |
| 90 | + @Override | |
| 82 | 91 | public PageResult<AiToolDO> getToolPage(AiToolPageReqVO pageReqVO) { |
| 83 | 92 | return toolMapper.selectPage(pageReqVO); |
| 84 | 93 | } |
| 85 | 94 | |
| 95 | + @Override | |
| 96 | + public List<AiToolDO> getToolListByStatus(Integer status) { | |
| 97 | + return toolMapper.selectListByStatus(status); | |
| 98 | + } | |
| 99 | + | |
| 86 | 100 | } |
| 87 | 101 | \ No newline at end of file | ... | ... |