web聊天室数据同步修改

This commit is contained in:
2025-12-24 15:02:23 +08:00
parent 1fd26dcf1a
commit 898da3a2c6
16 changed files with 691 additions and 53 deletions

View File

@@ -108,10 +108,11 @@
</template>
<script setup lang="ts">
import { ref, reactive, computed, nextTick, onMounted } from 'vue'
import { ref, reactive, computed, nextTick, onMounted, onUnmounted, watch } from 'vue'
import WorkcaseCreator from '@/components/WorkcaseCreator/WorkcaseCreator.uvue'
import type { ChatRoomMessageVO, CustomerVO, ChatMemberVO, TbChatRoomMessageDTO } from '@/types/workcase'
import { workcaseChatAPI } from '@/api/workcase'
import { wsClient } from '@/utils/websocket'
// 响应式数据
const headerPaddingTop = ref<number>(44)
@@ -232,6 +233,24 @@ onMounted(() => {
loadChatRoom()
loadDefaultWorkers()
loadChatMembers()
initWebSocket()
})
// 组件卸载时断开WebSocket
onUnmounted(() => {
disconnectWebSocket()
})
// 监听roomId变化切换聊天室时重新订阅
watch(roomId, (newRoomId, oldRoomId) => {
if (oldRoomId && newRoomId !== oldRoomId) {
// 取消旧聊天室订阅
wsClient.unsubscribe(`/topic/chat/${oldRoomId}`)
}
if (newRoomId && wsClient.isConnected()) {
// 订阅新聊天室
wsClient.subscribe(`/topic/chat/${newRoomId}`, handleNewMessage)
}
})
// 加载聊天室
@@ -443,6 +462,73 @@ function startMeeting() {
function goBack() {
uni.navigateBack()
}
// ==================== WebSocket连接管理 ====================
// 初始化WebSocket连接
async function initWebSocket() {
try {
const token = uni.getStorageSync('token') || ''
if (!token) {
console.warn('[chatRoom] 未找到token跳过WebSocket连接')
return
}
// 构建WebSocket URL
const protocol = 'wss:' // 生产环境使用wss
const host = 'your-domain.com' // 需要替换为实际域名
const wsUrl = `${protocol}//${host}/api/urban-lifeline/workcase/ws/chat-sockjs?token=${encodeURIComponent(token)}`
console.log('[chatRoom] 开始连接WebSocket')
await wsClient.connect(wsUrl, token)
// 订阅当前聊天室消息频道
if (roomId.value) {
wsClient.subscribe(`/topic/chat/${roomId.value}`, handleNewMessage)
console.log('[chatRoom] WebSocket连接成功已订阅聊天室:', roomId.value)
}
} catch (error) {
console.error('[chatRoom] WebSocket连接失败:', error)
}
}
// 断开WebSocket连接
function disconnectWebSocket() {
try {
if (roomId.value) {
wsClient.unsubscribe(`/topic/chat/${roomId.value}`)
}
wsClient.disconnect()
console.log('[chatRoom] WebSocket已断开')
} catch (error) {
console.error('[chatRoom] 断开WebSocket失败:', error)
}
}
// 处理接收到的新消息
function handleNewMessage(message: ChatRoomMessageVO) {
console.log('[chatRoom] 收到新消息:', message)
// 避免重复添加自己发送的消息自己发送的消息已经通过sendMessage添加到列表
if (message.senderId === currentUserId.value) {
console.log('[chatRoom] 跳过自己发送的消息')
return
}
// 检查消息是否已存在(避免重复)
const exists = messages.some(m => m.messageId === message.messageId)
if (exists) {
console.log('[chatRoom] 消息已存在,跳过')
return
}
// 添加新消息到列表
messages.push(message)
nextTick(() => scrollToBottom())
// 可以添加消息提示音或震动
// uni.vibrateShort()
}
</script>
<style lang="scss" scoped>

View File

@@ -50,9 +50,10 @@
</template>
<script setup lang="ts">
import { ref, onMounted } from 'vue'
import { ref, onMounted, onUnmounted } from 'vue'
import { workcaseChatAPI } from '@/api'
import type { ChatRoomVO, TbChatRoomDTO, PageRequest } from '@/types'
import type { ChatRoomVO, TbChatRoomDTO, PageRequest, ChatRoomMessageVO } from '@/types'
import { wsClient } from '@/utils/websocket'
// 导航栏
const navPaddingTop = ref<number>(0)
@@ -86,6 +87,12 @@ onMounted(() => {
// #endif
loadChatRooms()
initWebSocket()
})
// 组件卸载时断开WebSocket
onUnmounted(() => {
disconnectWebSocket()
})
// 加载聊天室列表
@@ -170,6 +177,63 @@ function enterRoom(room: ChatRoomVO) {
function goBack() {
uni.navigateBack()
}
// ==================== WebSocket连接管理 ====================
// 初始化WebSocket连接
async function initWebSocket() {
try {
const token = uni.getStorageSync('token') || ''
if (!token) {
console.warn('[chatRoomList] 未找到token跳过WebSocket连接')
return
}
// 构建WebSocket URL
const protocol = 'wss:' // 生产环境使用wss
const host = 'your-domain.com' // 需要替换为实际域名
const wsUrl = `${protocol}//${host}/api/urban-lifeline/workcase/ws/chat-sockjs?token=${encodeURIComponent(token)}`
console.log('[chatRoomList] 开始连接WebSocket')
await wsClient.connect(wsUrl, token)
// 订阅聊天室列表更新频道
wsClient.subscribe('/topic/chat/list-update', handleListUpdate)
console.log('[chatRoomList] WebSocket连接成功已订阅列表更新频道')
} catch (error) {
console.error('[chatRoomList] WebSocket连接失败:', error)
}
}
// 断开WebSocket连接
function disconnectWebSocket() {
try {
wsClient.disconnect()
console.log('[chatRoomList] WebSocket已断开')
} catch (error) {
console.error('[chatRoomList] 断开WebSocket失败:', error)
}
}
// 处理列表更新消息
function handleListUpdate(message: ChatRoomMessageVO) {
console.log('[chatRoomList] 收到列表更新消息:', message)
// 更新对应聊天室的lastMessage和lastMessageTime
const roomIndex = chatRooms.value.findIndex((r: ChatRoomVO) => r.roomId === message.roomId)
if (roomIndex !== -1) {
chatRooms.value[roomIndex] = {
...chatRooms.value[roomIndex],
lastMessage: message.content || '',
lastMessageTime: message.sendTime || ''
}
// 将更新的聊天室移到列表顶部
const updatedRoom = chatRooms.value[roomIndex]
chatRooms.value.splice(roomIndex, 1)
chatRooms.value.unshift(updatedRoom)
}
}
</script>
<style lang="scss" scoped>