Commit 17103201142db3317a73cfdad4f422a689cbeeb9

Authored by YunaiV
1 parent 12b82b72

【优化】AI:对话的头像交给前端拼接

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 6 import cn.iocoder.yudao.framework.common.pojo.PageResult;
7 7 import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
8 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 13 import cn.iocoder.yudao.module.ai.dal.dataobject.chat.AiChatConversationDO;
13 14 import cn.iocoder.yudao.module.ai.dal.dataobject.chat.AiChatMessageDO;
14 15 import cn.iocoder.yudao.module.ai.dal.dataobject.model.AiChatRoleDO;
15 16 import cn.iocoder.yudao.module.ai.service.chat.AiChatConversationService;
16 17 import cn.iocoder.yudao.module.ai.service.chat.AiChatMessageService;
17 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 19 import io.swagger.v3.oas.annotations.Operation;
21 20 import io.swagger.v3.oas.annotations.Parameter;
22 21 import io.swagger.v3.oas.annotations.tags.Tag;
... ... @@ -34,7 +33,6 @@ import java.util.List;
34 33 import java.util.Map;
35 34  
36 35 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
37   -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
38 36 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
39 37 import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
40 38  
... ... @@ -51,9 +49,6 @@ public class AiChatMessageController {
51 49 @Resource
52 50 private AiChatRoleService chatRoleService;
53 51  
54   - @Resource
55   - private AdminUserApi adminUserApi;
56   -
57 52 @Operation(summary = "发送消息(段式)", description = "一次性返回,响应较慢")
58 53 @PostMapping("/send")
59 54 public CommonResult<AiChatMessageRespVO> sendMessage(@Validated @RequestBody AiChatMessageSendReqVO sendReqVO) {
... ... @@ -77,17 +72,7 @@ public class AiChatMessageController {
77 72 return success(Collections.emptyList());
78 73 }
79 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 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 44  
45 45 // ========== 仅在【对话管理】时加载 ==========
46 46  
47   - @Schema(description = "用户头像", requiredMode = Schema.RequiredMode.REQUIRED, example = "http://xxx")
48   - private String userAvatar;
49   -
50 47 @Schema(description = "角色名字", example = "小黄")
51 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 17 @Mapper
18 18 public interface AiChatConversationMapper extends BaseMapperX<AiChatConversationDO> {
19 19  
20   - // TODO @fan:建议这里不排序哈;交给他们前端排序
21 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 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 9 import cn.iocoder.yudao.framework.common.pojo.PageResult;
10 10 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
11 11 import cn.iocoder.yudao.module.ai.ErrorCodeConstants;
12   -import cn.iocoder.yudao.module.ai.controller.admin.chat.vo.conversation.AiChatConversationPageReqVO;
13 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 13 import cn.iocoder.yudao.module.ai.controller.admin.chat.vo.message.AiChatMessageRespVO;
27 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 17 import cn.iocoder.yudao.module.ai.dal.dataobject.chat.AiChatMessageDO;
29 18 import cn.iocoder.yudao.module.ai.dal.dataobject.model.AiChatModelDO;
30 19 import cn.iocoder.yudao.module.ai.dal.dataobject.model.AiChatRoleDO;
31 20 import cn.iocoder.yudao.module.ai.dal.mysql.chat.AiChatMessageMapper;
  21 +import cn.iocoder.yudao.module.ai.service.model.AiApiKeyService;
32 22 import cn.iocoder.yudao.module.ai.service.model.AiChatModelService;
33 23 import cn.iocoder.yudao.module.ai.service.model.AiChatRoleService;
  24 +import jakarta.annotation.Resource;
34 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 31 import org.springframework.stereotype.Service;
36 32 import org.springframework.transaction.annotation.Transactional;
37 33 import reactor.core.publisher.Flux;
... ... @@ -70,9 +66,6 @@ public class AiChatMessageServiceImpl implements AiChatMessageService {
70 66 @Resource
71 67 private AiApiKeyService apiKeyService;
72 68  
73   - @Resource
74   - private AdminUserApi adminUserApi;
75   -
76 69 @Transactional(rollbackFor = Exception.class)
77 70 public AiChatMessageRespVO sendMessage(AiChatMessageSendReqVO req) {
78 71 return null; // TODO 芋艿:一起改
... ... @@ -124,7 +117,6 @@ public class AiChatMessageServiceImpl implements AiChatMessageService {
124 117 AiChatModelDO model = chatModalService.validateChatModel(conversation.getModelId());
125 118 StreamingChatClient chatClient = apiKeyService.getStreamingChatClient(model.getKeyId());
126 119 // 1.3 获取用户头像、角色头像
127   - AdminUserRespDTO user = adminUserApi.getUser(SecurityFrameworkUtils.getLoginUserId());
128 120 AiChatRoleDO role = conversation.getRoleId() != null ? chatRoleService.getChatRole(conversation.getRoleId()) : null;
129 121  
130 122 // 2. 插入 user 发送消息
... ... @@ -147,11 +139,8 @@ public class AiChatMessageServiceImpl implements AiChatMessageService {
147 139 newContent = StrUtil.nullToDefault(newContent, ""); // 避免 null 的 情况
148 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 144 }).doOnComplete(() -> {
156 145 chatMessageMapper.updateById(new AiChatMessageDO().setId(assistantMessage.getId()).setContent(contentBuffer.toString()));
157 146 }).doOnError(throwable -> {
... ...