聊天室完成

This commit is contained in:
2025-12-24 16:32:06 +08:00
parent 898da3a2c6
commit ad03f3f2db
16 changed files with 432 additions and 53 deletions

View File

@@ -9,7 +9,7 @@
<button
v-for="room in filteredRooms.slice(0, 8)"
:key="room.roomId"
@click="selectRoom(room.roomId!); toggleSidebar()"
@click="selectRoom(room)"
class="sidebar-icon-btn"
:class="{ active: currentRoomId === room.roomId }"
:title="room.roomName"
@@ -55,7 +55,7 @@
:key="room.roomId"
class="room-item"
:class="{ active: currentRoomId === room.roomId }"
@click="selectRoom(room.roomId!)"
@click="selectRoom(room)"
>
<!-- 头像 -->
<div class="room-avatar">
@@ -85,21 +85,28 @@
<!-- 主聊天区域 -->
<main class="chat-main" :class="{ 'sidebar-open': isSidebarOpen }">
<template v-if="currentRoomId">
<ChatRoom
ref="chatRoomRef"
:messages="messages"
:current-user-id="loginDomain.user.userId"
:room-name="currentRoom?.roomName"
:meeting-url="currentMeetingUrl"
:show-meeting="showMeetingIframe"
:file-download-url="FILE_DOWNLOAD_URL"
:has-more="hasMore"
:loading-more="loadingMore"
@send-message="handleSendMessage"
@start-meeting="startMeeting"
@download-file="downloadFile"
@load-more="loadMoreMessages"
>
<div class="chat-room-wrapper">
<!-- 自动填充加载遮罩 -->
<div v-if="autoFilling" class="auto-fill-mask">
<div class="loading-spinner"></div>
<div class="loading-text">正在加载历史消息...</div>
</div>
<ChatRoom
ref="chatRoomRef"
:messages="messages"
:current-user-id="loginDomain.user.userId"
:room-name="currentRoom?.roomName"
:meeting-url="currentMeetingUrl"
:show-meeting="showMeetingIframe"
:file-download-url="FILE_DOWNLOAD_URL"
:has-more="hasMore"
:loading-more="loadingMore"
@send-message="handleSendMessage"
@start-meeting="startMeeting"
@download-file="downloadFile"
@load-more="loadMoreMessages"
>
<template #header>
<div class="chat-room-header">
<div class="header-left">
@@ -123,6 +130,7 @@
</ElButton>
</template>
</ChatRoom>
</div>
</template>
<!-- 空状态 -->
@@ -193,6 +201,8 @@ const userType = true //web端固定这个
const loading = ref(false)
const messageLoading = ref(false)
const loadingMore = ref(false)
// 自动填充加载状态
const autoFilling = ref(false)
// 分页状态
const PAGE_SIZE = 5
@@ -242,9 +252,11 @@ const fetchChatRooms = async () => {
loading.value = true
try {
const result = await workcaseChatAPI.getChatRoomPage({
filter: { status: 'active' },
filter: {
status: 'active'
},
pageParam: { page: 1, pageSize: 100, total: 0 }
}, loginDomain.user.userId)
})
if (result.success && result.pageDomain) {
chatRooms.value = result.pageDomain.dataList || []
}
@@ -258,24 +270,25 @@ const fetchChatRooms = async () => {
}
// 选择聊天室
const selectRoom = async (roomId: string) => {
currentRoomId.value = roomId
const selectRoom = async (room: ChatRoomVO) => {
currentRoomId.value = room.roomId!
// 自动加入聊天室成员表(如果不存在)
try {
const memberData: TbChatRoomMemberDTO = {
roomId: roomId,
roomId: room.roomId,
userId: loginDomain.user.userId,
userName: loginDomain.userInfo.username,
userType: 'staff'
}
await workcaseChatAPI.addChatRoomMember(memberData)
room.unreadCount = 0
} catch (error) {
// 已存在成员或其他错误,忽略
console.debug('加入聊天室:', error)
}
loadMessages(roomId)
loadMessages(room.roomId!)
}
// 加载消息初始加载page1后端降序返回
@@ -296,6 +309,9 @@ const loadMessages = async (roomId: string) => {
// 后端降序返回,需要反转后显示(早的在上,新的在下)
const dataList = result.pageDomain.dataList || []
messages.value = [...dataList].reverse()
// 首次加载后自动填充消息直到出现滚动条
await autoFillMessages(roomId)
}
// 加载完成后滚动到底部
scrollToBottom()
@@ -307,6 +323,85 @@ const loadMessages = async (roomId: string) => {
}
}
// 自动填充消息直到出现滚动条
const autoFillMessages = async (roomId: string) => {
autoFilling.value = true
console.log('[autoFill] 开始检查消息高度, hasMore:', hasMore.value, 'messages:', messages.value.length)
// 等待DOM渲染
await nextTick()
await new Promise(resolve => setTimeout(resolve, 300))
let attempts = 0
const maxAttempts = 20
while (hasMore.value && attempts < maxAttempts) {
attempts++
const container = chatRoomRef.value?.$el?.querySelector?.('.messages-container')
const messagesList = chatRoomRef.value?.$el?.querySelector?.('.messages-list')
if (!container || !messagesList) {
console.warn('[autoFill] 找不到容器或消息列表')
break
}
// 容器高度(可视区域)
const containerHeight = container.clientHeight
// 消息列表实际高度(内容)
const listHeight = messagesList.offsetHeight
const fillPercent = containerHeight > 0 ? Math.round(listHeight / containerHeight * 100) : 0
console.log(`[autoFill] 第${attempts}次检查 - 容器高度: ${containerHeight}px, 列表高度: ${listHeight}px, 填充率: ${fillPercent}%, 消息数: ${messages.value.length}`)
// 判断是否已经溢出(列表高度 >= 容器高度)
if (containerHeight > 0 && listHeight >= containerHeight) {
console.log(`[autoFill] ✓ 列表已溢出(${fillPercent}%),可以滚动!停止加载`)
break
}
// 内容不足,继续加载下一页
console.log('[autoFill] → 内容不足,继续加载历史消息...')
const nextPage = currentPage.value + 1
const result = await workcaseChatAPI.getChatMessagePage({
filter: { roomId },
pageParam: { page: nextPage, pageSize: PAGE_SIZE }
})
if (result.success && result.pageDomain) {
const pageInfo = result.pageDomain.pageParam
const actualTotalPages = pageInfo?.totalPages || 1
const dataList = result.pageDomain.dataList || []
if (dataList.length > 0) {
currentPage.value = nextPage
hasMore.value = actualTotalPages > currentPage.value
// 反转后插入到列表前面
const reversedList = [...dataList].reverse()
messages.value.unshift(...reversedList)
console.log(`[autoFill] ✓ 加载第${nextPage}页完成, 新增${dataList.length}条, 总消息数: ${messages.value.length}`)
await nextTick()
await new Promise(resolve => setTimeout(resolve, 200))
} else {
hasMore.value = false
break
}
} else {
break
}
}
if (attempts >= maxAttempts) {
console.warn('[autoFill] ⚠ 达到最大尝试次数')
}
console.log(`[autoFill] 自动填充结束 - 共尝试${attempts}次, 最终消息数: ${messages.value.length}, hasMore: ${hasMore.value}`)
autoFilling.value = false
}
// 加载更多历史消息(滚动到顶部触发)
const loadMoreMessages = async () => {
if (!currentRoomId.value || loadingMore.value || !hasMore.value) return