From af3b59f8e248e71887f8ce5ed4be4b77d7d13662 Mon Sep 17 00:00:00 2001 From: wangdongbo <949818794@qq.com> Date: Wed, 28 Jan 2026 17:51:31 +0800 Subject: [PATCH] =?UTF-8?q?IM=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pages.json | 26 ++++-- pages/message/index.vue | 31 ++++++- pages/message/message.vue | 174 +++++++++++++++++++------------------- utils/tim-chat.js | 121 ++++++++++++++++++++------ 4 files changed, 230 insertions(+), 122 deletions(-) diff --git a/pages.json b/pages.json index fe4f1ed..8a0fc3c 100644 --- a/pages.json +++ b/pages.json @@ -44,12 +44,6 @@ "navigationBarTitleText": "新增档案" } }, - { - "path": "pages/article/article-list", - "style": { - "navigationBarTitleText": "健康宣教" - } - }, { "path": "pages/health/list", "style": { @@ -99,5 +93,25 @@ "navigationBarBackgroundColor": "#065bd6", "backgroundColor": "#065bd6" }, + "tabBar": { + "color": "#666666", + "selectedColor": "#007aff", + "backgroundColor": "#ffffff", + "borderStyle": "white", + "list": [ + { + "pagePath": "pages/home/home", + "iconPath": "static/tabbar/home.png", + "selectedIconPath": "static/tabbar/home_selected.png", + "text": "消息" + }, + { + "pagePath": "pages/message/message", + "iconPath": "static/tabbar/cart.png", + "selectedIconPath": "static/tabbar/cart_selected.png", + "text": "咨询" + } + ] + }, "uniIdRouter": {} } \ No newline at end of file diff --git a/pages/message/index.vue b/pages/message/index.vue index ec8628d..79bfd3e 100644 --- a/pages/message/index.vue +++ b/pages/message/index.vue @@ -400,6 +400,25 @@ const initTIMCallbacks = async () => { nextTick(() => { scrollToBottom(true); }); + + // 立即标记会话为已读,确保未读数为0 + if (timChatManager.tim && timChatManager.isLoggedIn && chatInfo.value.conversationID) { + timChatManager.tim + .setMessageRead({ + conversationID: chatInfo.value.conversationID, + }) + .then(() => { + console.log("✓ 收到新消息后已标记为已读"); + // 触发会话列表更新,确保未读数为0 + timChatManager.triggerCallback('onConversationListUpdated', { + conversationID: chatInfo.value.conversationID, + unreadCount: 0 + }); + }) + .catch((error) => { + console.error("✗ 标记已读失败:", error); + }); + } } }); @@ -538,21 +557,27 @@ const loadMessageList = async () => { timChatManager.enterConversation(chatInfo.value.conversationID || "test1"); - // 标记会话为已读 + // 标记会话为已读 - 确保清空未读数 if ( timChatManager.tim && timChatManager.isLoggedIn && chatInfo.value.conversationID ) { + console.log("标记会话为已读:", chatInfo.value.conversationID); timChatManager.tim .setMessageRead({ conversationID: chatInfo.value.conversationID, }) .then(() => { - console.log("会话已标记为已读:", chatInfo.value.conversationID); + console.log("✓ 会话已标记为已读:", chatInfo.value.conversationID); + // 触发会话列表更新回调,通知消息列表页面清空未读数 + timChatManager.triggerCallback('onConversationListUpdated', { + conversationID: chatInfo.value.conversationID, + unreadCount: 0 + }); }) .catch((error) => { - console.error("标记会话已读失败:", error); + console.error("✗ 标记会话已读失败:", error); }); } }; diff --git a/pages/message/message.vue b/pages/message/message.vue index c58b9c4..00ecde5 100644 --- a/pages/message/message.vue +++ b/pages/message/message.vue @@ -16,7 +16,6 @@ > 加载中... - { } }; -// 提取消息预览文本 -const extractMessagePreview = (message) => { - if (!message) return "暂无消息"; - - const payload = message.payload; - if (!payload) return "暂无消息"; - - // 文本消息 - if (message.type === "TIMTextElem") { - return payload.text || "暂无消息"; - } - - // 图片消息 - if (message.type === "TIMImageElem") { - return "[图片]"; - } - - // 语音消息 - if (message.type === "TIMSoundElem") { - return "[语音]"; - } - - // 视频消息 - if (message.type === "TIMVideoFileElem") { - return "[视频]"; - } - - // 文件消息 - if (message.type === "TIMFileElem") { - return "[文件]"; - } - - // 自定义消息 - if (message.type === "TIMCustomElem") { - const description = payload.description; - if (description === "SYSTEM_NOTIFICATION") { - return "[系统消息]"; - } - return "[消息]"; - } - - return "暂无消息"; -}; - // 设置会话列表监听,实时更新列表 const setupConversationListener = () => { if (!globalTimChatManager) return; @@ -223,58 +178,74 @@ const setupConversationListener = () => { globalTimChatManager.setCallback("onConversationListUpdated", (eventData) => { console.log("会话列表更新事件:", eventData); - // 如果是新消息导致的会话更新 - if ( - eventData.reason === "NEW_MESSAGE_RECEIVED_IN_CURRENT_CONVERSATION" || - eventData.reason === "NEW_MESSAGE_RECEIVED" - ) { - const conversation = eventData.conversation; - if (!conversation) return; - - const conversationID = conversation.conversationID; - const conversationIndex = conversationList.value.findIndex( + // 处理单个会话更新(标记已读的情况) + if (eventData && !Array.isArray(eventData) && eventData.conversationID) { + const conversationID = eventData.conversationID; + const existingIndex = conversationList.value.findIndex( (conv) => conv.conversationID === conversationID ); - if (conversationIndex !== -1) { - // 更新现有会话 - const existingConversation = conversationList.value[conversationIndex]; - existingConversation.lastMessage = - conversation.lastMessage || "暂无消息"; - existingConversation.lastMessageTime = - conversation.lastMessageTime || Date.now(); - existingConversation.unreadCount = conversation.unreadCount || 0; - - // 将该会话移到顶部 - const [updatedConversation] = conversationList.value.splice( - conversationIndex, - 1 - ); - conversationList.value.unshift(updatedConversation); - - console.log("已更新会话:", existingConversation.name); - } else { - // 新会话,添加到列表顶部 - conversationList.value.unshift({ - conversationID: conversationID, - groupID: conversation.groupID || conversationID.replace("GROUP", ""), - name: conversation.name || "问诊群聊", - avatar: conversation.avatar || "/static/default-avatar.png", - lastMessage: conversation.lastMessage || "暂无消息", - lastMessageTime: conversation.lastMessageTime || Date.now(), - unreadCount: conversation.unreadCount || 0, - }); - - console.log("已添加新会话"); + if (existingIndex !== -1) { + // 更新未读数 + if (eventData.unreadCount !== undefined) { + conversationList.value[existingIndex].unreadCount = + eventData.unreadCount; + console.log( + `已清空会话未读数: ${conversationList.value[existingIndex].name}, unreadCount: ${eventData.unreadCount}` + ); + } } + return; } + + // eventData 是一个数组,包含所有更新的会话 + if (!eventData || !Array.isArray(eventData)) { + console.warn("会话列表更新事件数据格式错误"); + return; + } + + // 过滤出群聊会话 + const groupConversations = eventData.filter( + (conv) => conv.conversationID && conv.conversationID.startsWith("GROUP") + ); + + console.log(`收到 ${groupConversations.length} 个群聊会话更新`); + + // 更新会话列表 - 使用 tim-chat.js 中的格式化方法 + groupConversations.forEach((updatedConv) => { + const conversationID = updatedConv.conversationID; + const existingIndex = conversationList.value.findIndex( + (conv) => conv.conversationID === conversationID + ); + + // 使用 TimChatManager 的格式化方法 + const conversationData = + globalTimChatManager.formatConversationData(updatedConv); + + if (existingIndex !== -1) { + // 更新现有会话 + conversationList.value[existingIndex] = conversationData; + console.log( + `已更新会话: ${conversationData.name}, unreadCount: ${conversationData.unreadCount}` + ); + } else { + // 添加新会话 + conversationList.value.push(conversationData); + console.log(`已添加新会话: ${conversationData.name}`); + } + }); + + // 按最后消息时间排序(最新的在前) + conversationList.value.sort( + (a, b) => b.lastMessageTime - a.lastMessageTime + ); }); // 监听消息接收事件(用于更新未读数) globalTimChatManager.setCallback("onMessageReceived", (message) => { console.log("消息列表页面收到新消息:", message); - // 找到对应的会话并更新未读数 + // 找到对应的会话 const conversationID = message.conversationID; const conversationIndex = conversationList.value.findIndex( (conv) => conv.conversationID === conversationID @@ -282,9 +253,27 @@ const setupConversationListener = () => { if (conversationIndex !== -1) { const conversation = conversationList.value[conversationIndex]; - // 只更新未读数,其他信息由 onConversationListUpdated 事件处理 + + // 检查当前页面栈,判断用户是否正在查看该会话 + const pages = getCurrentPages(); + const currentPage = pages[pages.length - 1]; + const isViewingConversation = + currentPage?.route === "pages/message/index"; + + // 如果用户正在查看该会话,不增加未读数 + if (isViewingConversation) { + console.log("用户正在查看该会话,不增加未读数"); + return; + } + + // 只在用户不在聊天页面时才增加未读数 conversation.unreadCount = (conversation.unreadCount || 0) + 1; - console.log("已更新会话未读数:", conversation.name); + console.log( + "已更新会话未读数:", + conversation.name, + "unreadCount:", + conversation.unreadCount + ); } }); }; @@ -335,6 +324,15 @@ const formatMessageTime = (timestamp) => { const handleClickConversation = (conversation) => { console.log("点击会话:", conversation); + // 立即清空本地未读数(优化用户体验) + const conversationIndex = conversationList.value.findIndex( + (conv) => conv.conversationID === conversation.conversationID + ); + if (conversationIndex !== -1) { + conversationList.value[conversationIndex].unreadCount = 0; + console.log("已清空本地未读数:", conversation.name); + } + // 跳转到聊天页面 uni.navigateTo({ url: `/pages/message/index?conversationID=${conversation.conversationID}&groupID=${conversation.groupID}`, diff --git a/utils/tim-chat.js b/utils/tim-chat.js index 4ed5d28..dd60bd9 100644 --- a/utils/tim-chat.js +++ b/utils/tim-chat.js @@ -1017,14 +1017,12 @@ class TimChatManager { reject(new Error('TIM实例不存在')) return } - if (!this.isLoggedIn) { console.log('SDK未ready,等待SDK初始化...') let waitTime = 0 const maxWaitTime = 30000 // 最多等待30秒 const checkInterval = 1000 // 每秒检查一次 let timeoutHandle = null - const checkSDKReady = () => { if (this.isLoggedIn) { console.log('SDK已ready,开始获取群聊列表') @@ -1036,15 +1034,12 @@ class TimChatManager { reject(new Error('SDK初始化超时,请检查网络连接')) } else { waitTime += checkInterval - console.log(`等待SDK就绪... (${Math.floor(waitTime / 1000)}/${Math.floor(maxWaitTime / 1000)}秒)`) timeoutHandle = setTimeout(checkSDKReady, checkInterval) } } - checkSDKReady() return } - this.getGroupListInternal().then(resolve).catch(reject) }) } @@ -2488,32 +2483,22 @@ class TimChatManager { return message } + // 格式化最后一条消息(支持更多消息类型) formatLastMessage(message) { try { switch (message.type) { case 'TIMTextElem': - return message.payload.text || '[文本消息]' + return message.payload?.text || '[文本消息]' case 'TIMImageElem': return '[图片]' case 'TIMSoundElem': return '[语音]' + case 'TIMVideoFileElem': + return '[视频]' + case 'TIMFileElem': + return '[文件]' case 'TIMCustomElem': - try { - const customData = JSON.parse(message.payload.data) - if (customData.messageType === 'symptom') { - return '[病情描述]' - } else if (customData.messageType === 'prescription') { - return '[处方单]' - } else if (customData.messageType === 'refill') { - return '[续方申请]' - } else if (customData.messageType === 'survey') { - return '[问卷调查]' - } else { - return customData.content || '[自定义消息]' - } - } catch (error) { - return '[自定义消息]' - } + return this.formatCustomMessage(message.payload) default: return '[未知消息类型]' } @@ -2523,6 +2508,85 @@ class TimChatManager { } } + // 格式化自定义消息 + formatCustomMessage(payload) { + try { + if (!payload || !payload.data) { + return '[自定义消息]' + } + + const customData = typeof payload.data === 'string' + ? JSON.parse(payload.data) + : payload.data + + const messageType = customData.messageType || customData.type + + const messageTypeMap = { + system_message: '[系统消息]', + symptom: '[病情描述]', + prescription: '[处方单]', + refill: '[续方申请]', + survey: '[问卷调查]', + article: '[文章]', + consult_pending: '患者向团队发起咨询,请在1小时内接诊', + consult_rejected: '咨询已被拒绝', + consult_timeout: '咨询已超时自动关闭', + consult_accepted: '已接诊,会话已开始', + consult_ended: '已结束当前会话', + } + + return messageTypeMap[messageType] || customData.content || '[自定义消息]' + } catch (error) { + console.error('格式化自定义消息失败:', error) + return '[自定义消息]' + } + } + + // 格式化会话数据(用于会话列表) + formatConversationData(conversation) { + try { + const conversationID = conversation.conversationID + const groupName = conversation.groupProfile?.name || '' + const [doctorId, patientName] = groupName.split('|') + const groupID = conversationID.replace('GROUP', '') + + // 解析最后一条消息 + let lastMessage = '暂无消息' + let lastMessageTime = Date.now() + + if (conversation.lastMessage) { + const msg = conversation.lastMessage + lastMessageTime = (msg.lastTime || msg.time || 0) * 1000 + lastMessage = this.formatLastMessage(msg) + } + + return { + conversationID, + groupID, + name: patientName ? `${patientName}的问诊` : groupName || '问诊群聊', + avatar: '/static/default-avatar.png', + lastMessage, + lastMessageTime, + unreadCount: conversation.unreadCount || 0, + doctorId, + patientName, + } + } catch (error) { + console.error('格式化会话数据失败:', error) + return { + conversationID: conversation.conversationID, + groupID: conversation.conversationID?.replace('GROUP', '') || '', + name: '问诊群聊', + avatar: '/static/default-avatar.png', + lastMessage: '暂无消息', + lastMessageTime: Date.now(), + unreadCount: 0, + doctorId: '', + patientName: '', + } + } + } + getImageUrl(imageFile) { // 处理 tempFiles 数组格式 if (imageFile?.tempFiles?.length > 0) { @@ -2600,7 +2664,10 @@ class TimChatManager { // 标记会话为已读 markConversationAsRead(conversationID) { - if (!this.tim || !this.isLoggedIn) return + if (!this.tim || !this.isLoggedIn) { + console.log('⚠️ TIM未初始化或未登录,无法标记会话已读'); + return; + } try { let formattedConversationID = conversationID @@ -2608,18 +2675,22 @@ class TimChatManager { formattedConversationID = `GROUP${conversationID}` } + console.log('📖 标记会话为已读:', formattedConversationID); + this.tim.setMessageRead({ conversationID: formattedConversationID }).then(() => { + console.log('✓ 会话已标记为已读:', formattedConversationID); + // 触发会话列表更新回调,通知消息列表页面清空未读数 this.triggerCallback('onConversationListUpdated', { conversationID: formattedConversationID, unreadCount: 0 }) }).catch(error => { - console.error('标记会话已读失败:', error) + console.error('✗ 标记会话已读失败:', error) }) } catch (error) { - console.error('标记会话已读异常:', error) + console.error('✗ 标记会话已读异常:', error) } }