Commit 17103201142db3317a73cfdad4f422a689cbeeb9
1 parent
12b82b72
【优化】AI:对话的头像交给前端拼接
Showing
4 changed files
with
17 additions
and
52 deletions
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/chat/AiChatMessageController.java
| @@ -6,17 +6,16 @@ import cn.iocoder.yudao.framework.common.pojo.CommonResult; | @@ -6,17 +6,16 @@ import cn.iocoder.yudao.framework.common.pojo.CommonResult; | ||
| 6 | import cn.iocoder.yudao.framework.common.pojo.PageResult; | 6 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 7 | import cn.iocoder.yudao.framework.common.util.collection.MapUtils; | 7 | import cn.iocoder.yudao.framework.common.util.collection.MapUtils; |
| 8 | import cn.iocoder.yudao.framework.common.util.object.BeanUtils; | 8 | import cn.iocoder.yudao.framework.common.util.object.BeanUtils; |
| 9 | -import cn.iocoder.yudao.module.ai.controller.admin.chat.vo.conversation.AiChatConversationPageReqVO; | ||
| 10 | -import cn.iocoder.yudao.module.ai.controller.admin.chat.vo.conversation.AiChatConversationRespVO; | ||
| 11 | -import cn.iocoder.yudao.module.ai.controller.admin.chat.vo.message.*; | 9 | +import cn.iocoder.yudao.module.ai.controller.admin.chat.vo.message.AiChatMessagePageReqVO; |
| 10 | +import cn.iocoder.yudao.module.ai.controller.admin.chat.vo.message.AiChatMessageRespVO; | ||
| 11 | +import cn.iocoder.yudao.module.ai.controller.admin.chat.vo.message.AiChatMessageSendReqVO; | ||
| 12 | +import cn.iocoder.yudao.module.ai.controller.admin.chat.vo.message.AiChatMessageSendRespVO; | ||
| 12 | import cn.iocoder.yudao.module.ai.dal.dataobject.chat.AiChatConversationDO; | 13 | import cn.iocoder.yudao.module.ai.dal.dataobject.chat.AiChatConversationDO; |
| 13 | import cn.iocoder.yudao.module.ai.dal.dataobject.chat.AiChatMessageDO; | 14 | import cn.iocoder.yudao.module.ai.dal.dataobject.chat.AiChatMessageDO; |
| 14 | import cn.iocoder.yudao.module.ai.dal.dataobject.model.AiChatRoleDO; | 15 | import cn.iocoder.yudao.module.ai.dal.dataobject.model.AiChatRoleDO; |
| 15 | import cn.iocoder.yudao.module.ai.service.chat.AiChatConversationService; | 16 | import cn.iocoder.yudao.module.ai.service.chat.AiChatConversationService; |
| 16 | import cn.iocoder.yudao.module.ai.service.chat.AiChatMessageService; | 17 | import cn.iocoder.yudao.module.ai.service.chat.AiChatMessageService; |
| 17 | import cn.iocoder.yudao.module.ai.service.model.AiChatRoleService; | 18 | import cn.iocoder.yudao.module.ai.service.model.AiChatRoleService; |
| 18 | -import cn.iocoder.yudao.module.system.api.user.AdminUserApi; | ||
| 19 | -import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; | ||
| 20 | import io.swagger.v3.oas.annotations.Operation; | 19 | import io.swagger.v3.oas.annotations.Operation; |
| 21 | import io.swagger.v3.oas.annotations.Parameter; | 20 | import io.swagger.v3.oas.annotations.Parameter; |
| 22 | import io.swagger.v3.oas.annotations.tags.Tag; | 21 | import io.swagger.v3.oas.annotations.tags.Tag; |
| @@ -34,7 +33,6 @@ import java.util.List; | @@ -34,7 +33,6 @@ import java.util.List; | ||
| 34 | import java.util.Map; | 33 | import java.util.Map; |
| 35 | 34 | ||
| 36 | import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; | 35 | import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; |
| 37 | -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList; | ||
| 38 | import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; | 36 | import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; |
| 39 | import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; | 37 | import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; |
| 40 | 38 | ||
| @@ -51,9 +49,6 @@ public class AiChatMessageController { | @@ -51,9 +49,6 @@ public class AiChatMessageController { | ||
| 51 | @Resource | 49 | @Resource |
| 52 | private AiChatRoleService chatRoleService; | 50 | private AiChatRoleService chatRoleService; |
| 53 | 51 | ||
| 54 | - @Resource | ||
| 55 | - private AdminUserApi adminUserApi; | ||
| 56 | - | ||
| 57 | @Operation(summary = "发送消息(段式)", description = "一次性返回,响应较慢") | 52 | @Operation(summary = "发送消息(段式)", description = "一次性返回,响应较慢") |
| 58 | @PostMapping("/send") | 53 | @PostMapping("/send") |
| 59 | public CommonResult<AiChatMessageRespVO> sendMessage(@Validated @RequestBody AiChatMessageSendReqVO sendReqVO) { | 54 | public CommonResult<AiChatMessageRespVO> sendMessage(@Validated @RequestBody AiChatMessageSendReqVO sendReqVO) { |
| @@ -77,17 +72,7 @@ public class AiChatMessageController { | @@ -77,17 +72,7 @@ public class AiChatMessageController { | ||
| 77 | return success(Collections.emptyList()); | 72 | return success(Collections.emptyList()); |
| 78 | } | 73 | } |
| 79 | List<AiChatMessageDO> messageList = chatMessageService.getChatMessageListByConversationId(conversationId); | 74 | List<AiChatMessageDO> messageList = chatMessageService.getChatMessageListByConversationId(conversationId); |
| 80 | - if (CollUtil.isEmpty(messageList)) { | ||
| 81 | - return success(Collections.emptyList()); | ||
| 82 | - } | ||
| 83 | - | ||
| 84 | - // 拼接数据 | ||
| 85 | - Map<Long, AiChatRoleDO> roleMap = chatRoleService.getChatRoleMap(convertSet(messageList, AiChatMessageDO::getRoleId)); | ||
| 86 | - AdminUserRespDTO user = adminUserApi.getUser(getLoginUserId()); | ||
| 87 | - return success(BeanUtils.toBean(messageList, AiChatMessageRespVO.class, respVO -> { | ||
| 88 | - MapUtils.findAndThen(roleMap, respVO.getRoleId(), role -> respVO.setRoleAvatar(role.getAvatar())); | ||
| 89 | - respVO.setUserAvatar(user.getAvatar()); | ||
| 90 | - })); | 75 | + return success(BeanUtils.toBean(messageList, AiChatMessageRespVO.class)); |
| 91 | } | 76 | } |
| 92 | 77 | ||
| 93 | @Operation(summary = "删除消息") | 78 | @Operation(summary = "删除消息") |
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/chat/vo/message/AiChatMessageRespVO.java
| @@ -44,13 +44,7 @@ public class AiChatMessageRespVO { | @@ -44,13 +44,7 @@ public class AiChatMessageRespVO { | ||
| 44 | 44 | ||
| 45 | // ========== 仅在【对话管理】时加载 ========== | 45 | // ========== 仅在【对话管理】时加载 ========== |
| 46 | 46 | ||
| 47 | - @Schema(description = "用户头像", requiredMode = Schema.RequiredMode.REQUIRED, example = "http://xxx") | ||
| 48 | - private String userAvatar; | ||
| 49 | - | ||
| 50 | @Schema(description = "角色名字", example = "小黄") | 47 | @Schema(description = "角色名字", example = "小黄") |
| 51 | private String roleName; | 48 | private String roleName; |
| 52 | 49 | ||
| 53 | - @Schema(description = "角色头像", requiredMode = Schema.RequiredMode.REQUIRED, example = "https://www.iocoder.cn/1.png") | ||
| 54 | - private String roleAvatar; | ||
| 55 | - | ||
| 56 | } | 50 | } |
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/dal/mysql/chat/AiChatConversationMapper.java
| @@ -17,11 +17,8 @@ import java.util.List; | @@ -17,11 +17,8 @@ import java.util.List; | ||
| 17 | @Mapper | 17 | @Mapper |
| 18 | public interface AiChatConversationMapper extends BaseMapperX<AiChatConversationDO> { | 18 | public interface AiChatConversationMapper extends BaseMapperX<AiChatConversationDO> { |
| 19 | 19 | ||
| 20 | - // TODO @fan:建议这里不排序哈;交给他们前端排序 | ||
| 21 | default List<AiChatConversationDO> selectListByUserId(Long userId) { | 20 | default List<AiChatConversationDO> selectListByUserId(Long userId) { |
| 22 | - return selectList(new LambdaQueryWrapperX<AiChatConversationDO>() | ||
| 23 | - .eq(AiChatConversationDO::getUserId, userId) | ||
| 24 | - .orderByAsc(AiChatConversationDO::getCreateTime)); | 21 | + return selectList(AiChatConversationDO::getUserId, userId); |
| 25 | } | 22 | } |
| 26 | 23 | ||
| 27 | default List<AiChatConversationDO> selectListByUserIdAndPinned(Long userId, boolean pinned) { | 24 | default List<AiChatConversationDO> selectListByUserIdAndPinned(Long userId, boolean pinned) { |
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/service/chat/AiChatMessageServiceImpl.java
| @@ -9,29 +9,25 @@ import cn.iocoder.yudao.framework.common.pojo.CommonResult; | @@ -9,29 +9,25 @@ import cn.iocoder.yudao.framework.common.pojo.CommonResult; | ||
| 9 | import cn.iocoder.yudao.framework.common.pojo.PageResult; | 9 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 10 | import cn.iocoder.yudao.framework.common.util.object.BeanUtils; | 10 | import cn.iocoder.yudao.framework.common.util.object.BeanUtils; |
| 11 | import cn.iocoder.yudao.module.ai.ErrorCodeConstants; | 11 | import cn.iocoder.yudao.module.ai.ErrorCodeConstants; |
| 12 | -import cn.iocoder.yudao.module.ai.controller.admin.chat.vo.conversation.AiChatConversationPageReqVO; | ||
| 13 | import cn.iocoder.yudao.module.ai.controller.admin.chat.vo.message.AiChatMessagePageReqVO; | 12 | import cn.iocoder.yudao.module.ai.controller.admin.chat.vo.message.AiChatMessagePageReqVO; |
| 14 | -import cn.iocoder.yudao.module.ai.controller.admin.chat.vo.message.AiChatMessageSendRespVO; | ||
| 15 | -import cn.iocoder.yudao.module.ai.dal.dataobject.chat.AiChatConversationDO; | ||
| 16 | -import cn.iocoder.yudao.module.ai.service.model.AiApiKeyService; | ||
| 17 | -import cn.iocoder.yudao.module.system.api.user.AdminUserApi; | ||
| 18 | -import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; | ||
| 19 | -import jakarta.annotation.Resource; | ||
| 20 | -import org.springframework.ai.chat.ChatResponse; | ||
| 21 | -import org.springframework.ai.chat.StreamingChatClient; | ||
| 22 | -import org.springframework.ai.chat.messages.*; | ||
| 23 | -import org.springframework.ai.chat.prompt.ChatOptions; | ||
| 24 | -import org.springframework.ai.chat.prompt.Prompt; | ||
| 25 | -import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils; | ||
| 26 | import cn.iocoder.yudao.module.ai.controller.admin.chat.vo.message.AiChatMessageRespVO; | 13 | import cn.iocoder.yudao.module.ai.controller.admin.chat.vo.message.AiChatMessageRespVO; |
| 27 | import cn.iocoder.yudao.module.ai.controller.admin.chat.vo.message.AiChatMessageSendReqVO; | 14 | import cn.iocoder.yudao.module.ai.controller.admin.chat.vo.message.AiChatMessageSendReqVO; |
| 15 | +import cn.iocoder.yudao.module.ai.controller.admin.chat.vo.message.AiChatMessageSendRespVO; | ||
| 16 | +import cn.iocoder.yudao.module.ai.dal.dataobject.chat.AiChatConversationDO; | ||
| 28 | import cn.iocoder.yudao.module.ai.dal.dataobject.chat.AiChatMessageDO; | 17 | import cn.iocoder.yudao.module.ai.dal.dataobject.chat.AiChatMessageDO; |
| 29 | import cn.iocoder.yudao.module.ai.dal.dataobject.model.AiChatModelDO; | 18 | import cn.iocoder.yudao.module.ai.dal.dataobject.model.AiChatModelDO; |
| 30 | import cn.iocoder.yudao.module.ai.dal.dataobject.model.AiChatRoleDO; | 19 | import cn.iocoder.yudao.module.ai.dal.dataobject.model.AiChatRoleDO; |
| 31 | import cn.iocoder.yudao.module.ai.dal.mysql.chat.AiChatMessageMapper; | 20 | import cn.iocoder.yudao.module.ai.dal.mysql.chat.AiChatMessageMapper; |
| 21 | +import cn.iocoder.yudao.module.ai.service.model.AiApiKeyService; | ||
| 32 | import cn.iocoder.yudao.module.ai.service.model.AiChatModelService; | 22 | import cn.iocoder.yudao.module.ai.service.model.AiChatModelService; |
| 33 | import cn.iocoder.yudao.module.ai.service.model.AiChatRoleService; | 23 | import cn.iocoder.yudao.module.ai.service.model.AiChatRoleService; |
| 24 | +import jakarta.annotation.Resource; | ||
| 34 | import lombok.extern.slf4j.Slf4j; | 25 | import lombok.extern.slf4j.Slf4j; |
| 26 | +import org.springframework.ai.chat.ChatResponse; | ||
| 27 | +import org.springframework.ai.chat.StreamingChatClient; | ||
| 28 | +import org.springframework.ai.chat.messages.*; | ||
| 29 | +import org.springframework.ai.chat.prompt.ChatOptions; | ||
| 30 | +import org.springframework.ai.chat.prompt.Prompt; | ||
| 35 | import org.springframework.stereotype.Service; | 31 | import org.springframework.stereotype.Service; |
| 36 | import org.springframework.transaction.annotation.Transactional; | 32 | import org.springframework.transaction.annotation.Transactional; |
| 37 | import reactor.core.publisher.Flux; | 33 | import reactor.core.publisher.Flux; |
| @@ -70,9 +66,6 @@ public class AiChatMessageServiceImpl implements AiChatMessageService { | @@ -70,9 +66,6 @@ public class AiChatMessageServiceImpl implements AiChatMessageService { | ||
| 70 | @Resource | 66 | @Resource |
| 71 | private AiApiKeyService apiKeyService; | 67 | private AiApiKeyService apiKeyService; |
| 72 | 68 | ||
| 73 | - @Resource | ||
| 74 | - private AdminUserApi adminUserApi; | ||
| 75 | - | ||
| 76 | @Transactional(rollbackFor = Exception.class) | 69 | @Transactional(rollbackFor = Exception.class) |
| 77 | public AiChatMessageRespVO sendMessage(AiChatMessageSendReqVO req) { | 70 | public AiChatMessageRespVO sendMessage(AiChatMessageSendReqVO req) { |
| 78 | return null; // TODO 芋艿:一起改 | 71 | return null; // TODO 芋艿:一起改 |
| @@ -124,7 +117,6 @@ public class AiChatMessageServiceImpl implements AiChatMessageService { | @@ -124,7 +117,6 @@ public class AiChatMessageServiceImpl implements AiChatMessageService { | ||
| 124 | AiChatModelDO model = chatModalService.validateChatModel(conversation.getModelId()); | 117 | AiChatModelDO model = chatModalService.validateChatModel(conversation.getModelId()); |
| 125 | StreamingChatClient chatClient = apiKeyService.getStreamingChatClient(model.getKeyId()); | 118 | StreamingChatClient chatClient = apiKeyService.getStreamingChatClient(model.getKeyId()); |
| 126 | // 1.3 获取用户头像、角色头像 | 119 | // 1.3 获取用户头像、角色头像 |
| 127 | - AdminUserRespDTO user = adminUserApi.getUser(SecurityFrameworkUtils.getLoginUserId()); | ||
| 128 | AiChatRoleDO role = conversation.getRoleId() != null ? chatRoleService.getChatRole(conversation.getRoleId()) : null; | 120 | AiChatRoleDO role = conversation.getRoleId() != null ? chatRoleService.getChatRole(conversation.getRoleId()) : null; |
| 129 | 121 | ||
| 130 | // 2. 插入 user 发送消息 | 122 | // 2. 插入 user 发送消息 |
| @@ -147,11 +139,8 @@ public class AiChatMessageServiceImpl implements AiChatMessageService { | @@ -147,11 +139,8 @@ public class AiChatMessageServiceImpl implements AiChatMessageService { | ||
| 147 | newContent = StrUtil.nullToDefault(newContent, ""); // 避免 null 的 情况 | 139 | newContent = StrUtil.nullToDefault(newContent, ""); // 避免 null 的 情况 |
| 148 | contentBuffer.append(newContent); | 140 | contentBuffer.append(newContent); |
| 149 | // 响应结果 | 141 | // 响应结果 |
| 150 | - AiChatMessageSendRespVO.Message send = BeanUtils.toBean(userMessage, AiChatMessageSendRespVO.Message.class, | ||
| 151 | - o -> o.setUserAvatar(user.getAvatar())); | ||
| 152 | - AiChatMessageSendRespVO.Message receive = BeanUtils.toBean(assistantMessage, AiChatMessageSendRespVO.Message.class, | ||
| 153 | - o -> o.setRoleAvatar(role != null ? role.getAvatar() : null)).setContent(newContent); | ||
| 154 | - return success(new AiChatMessageSendRespVO().setSend(send).setReceive(receive)); | 142 | + return success(new AiChatMessageSendRespVO().setSend(BeanUtils.toBean(userMessage, AiChatMessageSendRespVO.Message.class)) |
| 143 | + .setReceive(BeanUtils.toBean(assistantMessage, AiChatMessageSendRespVO.Message.class).setContent(newContent))); | ||
| 155 | }).doOnComplete(() -> { | 144 | }).doOnComplete(() -> { |
| 156 | chatMessageMapper.updateById(new AiChatMessageDO().setId(assistantMessage.getId()).setContent(contentBuffer.toString())); | 145 | chatMessageMapper.updateById(new AiChatMessageDO().setId(assistantMessage.getId()).setContent(contentBuffer.toString())); |
| 157 | }).doOnError(throwable -> { | 146 | }).doOnError(throwable -> { |