feat(phase2e-2): 会议内聊天面板落地(Task 12)

- 新增 ChatPanel 组件:右侧抽屉式聊天 UI,支持发送/加载更早消息/未读清零
- store/meeting.js:扩展 chatHasMore/chatUnreadCount/chatHistoryLoaded 等状态与 loadMoreChats/markChatsRead 动作;WS 消息到达时按 id 去重
- room.vue:替换临时 toast 占位为 ChatPanel,绑定未读徽标、成员展示名映射;watch unread 自动在面板打开时清零
- 后端:SendChat WS 广播与 REST 响应补充 user_name/user_avatar,聊天面板无需额外查询即可展示昵称

Made-with: Cursor
This commit is contained in:
bujinyuan
2026-04-22 15:16:17 +08:00
parent 59f824ad27
commit 1222bf551d
5 changed files with 605 additions and 17 deletions

View File

@@ -127,17 +127,23 @@ func participantToDTO(p *model.MeetingParticipant) *dto.MeetingParticipantDTO {
}
// chatToDTO 将 model.MeetingChat 转 DTO
func chatToDTO(m *model.MeetingChat) *dto.MeetingChatDTO {
// userMap 可选:若提供则附带 user_name / user_avatar否则为空
func chatToDTO(m *model.MeetingChat, userMap map[int64]service.UserDisplayInfo) *dto.MeetingChatDTO {
if m == nil {
return nil
}
return &dto.MeetingChatDTO{
d := &dto.MeetingChatDTO{
ID: m.ID,
RoomID: m.RoomID,
UserID: m.UserID,
Content: m.Content,
CreatedAt: m.CreatedAt.Format("2006-01-02 15:04:05"),
}
if info, ok := userMap[m.UserID]; ok {
d.UserName = info.Name
d.UserAvatar = info.Avatar
}
return d
}
// ====== REST API ======
@@ -398,7 +404,8 @@ func (ctl *MeetingController) SendChat(c *gin.Context) {
ctl.handleError(c, err, "发送会议聊天失败")
return
}
utils.ResponseCreated(c, dto.SendMeetingChatResponse{Message: *chatToDTO(msg)})
userMap := ctl.meetingService.ResolveUsersDisplay(c.Request.Context(), []int64{msg.UserID})
utils.ResponseCreated(c, dto.SendMeetingChatResponse{Message: *chatToDTO(msg, userMap)})
}
// ListChats GET /api/v1/meeting/rooms/:code/chats?before_id=&limit=
@@ -419,9 +426,14 @@ func (ctl *MeetingController) ListChats(c *gin.Context) {
ctl.handleError(c, err, "获取会议聊天失败")
return
}
userIDs := make([]int64, 0, len(msgs))
for i := range msgs {
userIDs = append(userIDs, msgs[i].UserID)
}
userMap := ctl.meetingService.ResolveUsersDisplay(c.Request.Context(), userIDs)
list := make([]dto.MeetingChatDTO, 0, len(msgs))
for i := range msgs {
list = append(list, *chatToDTO(&msgs[i]))
list = append(list, *chatToDTO(&msgs[i], userMap))
}
utils.ResponseOK(c, dto.ListMeetingChatsResponse{List: list, HasMore: hasMore})
}