Selaa lähdekoodia

信息状态(已读/未读)

mazhenhang 1 kuukausi sitten
vanhempi
commit
3c8d081864

+ 115 - 14
LiangZhiYUMao/pages/message/chat.vue

@@ -154,13 +154,9 @@
             
             <!-- 消息状态(自己的消息) -->
             <view v-if="msg.fromUserId === userId" class="message-status">
-              <text v-if="msg.sendStatus === 1" class="sending">发送中...</text>
-              <text v-else-if="msg.sendStatus === 2">已送达</text>
-              <text v-else-if="msg.sendStatus === 3" class="read">已读</text>
-              <view v-else-if="msg.sendStatus === 4" class="failed-group">
-                <text class="failed">发送失败</text>
-                <text class="retry-btn" @click.stop="retryMessage(msg)">重试</text>
-              </view>
+              <text v-if="msg.sendStatus === 4" class="status-failed">发送失败</text>
+              <text v-else-if="msg.isPeerRead" class="status-read">已读</text>
+              <text v-else class="status-unread">未读</text>
             </view>
           </view>
         </view>
@@ -426,6 +422,15 @@ export default {
     // 初始化在线状态监听(HTTP 轮询方式)
     this.initOnlineStatusPolling();
     
+    // 等待一下确保 TIM 完全初始化后再监听已读回执
+    setTimeout(() => {
+      // 监听已读回执
+      this.listenMessageReadReceipt();
+      
+      // 标记当前会话的消息为已读
+      this.markConversationRead();
+    }, 500);
+    
     // 如果有预设消息,自动发送
     if (options.message) {
       const message = decodeURIComponent(options.message);
@@ -734,7 +739,8 @@ export default {
               });
             }
             
-            // 标记已读
+            // 标记已读(通知对方:我已阅读他发送的消息)
+            console.log('📖 收到新消息,标记会话已读:', this.conversationID);
             timManager.setMessageRead(this.conversationID);
           }
         });
@@ -828,6 +834,18 @@ export default {
         content = '[视频]';
       }
       
+      // 对于自己发送的消息,isPeerRead 需要特殊处理
+      // 不能直接使用 timMsg.isPeerRead,因为 setMessageRead() 会影响这个值
+      // 只有真正收到 MESSAGE_READ_BY_PEER 事件时才应该标记为已读
+      let isPeerRead = false;
+      if (timMsg.from === this.userId) {
+        // 自己发送的消息,默认未读,只有收到已读回执事件时才更新
+        isPeerRead = false;
+      } else {
+        // 对方发送的消息,不需要 isPeerRead 字段
+        isPeerRead = false;
+      }
+      
       return {
         messageId: timMsg.ID,
         fromUserId: timMsg.from,
@@ -840,7 +858,8 @@ export default {
         sendStatus: sendStatus,
         sendTime: new Date(timMsg.time * 1000),
         isRecalled: timMsg.isRevoked,
-        fromUserName: timMsg.from === this.userId ? '我' : this.targetUserName
+        fromUserName: timMsg.from === this.userId ? '我' : this.targetUserName,
+        isPeerRead: isPeerRead // 对方是否已读(只对自己发送的消息有意义)
       };
     },
     /**
@@ -884,6 +903,78 @@ export default {
         return false;
       }
     },
+    
+    /**
+     * 监听已读回执
+     */
+    listenMessageReadReceipt() {
+      if (!timManager.tim || !timManager.tim.TIM) {
+        console.warn('⚠️ TIM 未初始化或 TIM 对象不完整,无法监听已读回执');
+        return;
+      }
+      
+      const TIM = timManager.tim.TIM;
+      
+      // 监听消息已读回执事件
+      const handleMessageReadByPeer = (event) => {
+        console.log('📖 收到已读回执事件:', event);
+        console.log('   - 事件数据:', JSON.stringify(event.data));
+        
+        // event.data 包含已读的消息列表
+        if (event.data && Array.isArray(event.data)) {
+          event.data.forEach(item => {
+            console.log('   - 处理会话:', item.conversationID, '当前会话:', this.conversationID);
+            
+            // 只处理当前会话的消息
+            if (item.conversationID === this.conversationID) {
+              console.log('✅ 对方已阅读当前会话的消息');
+              
+              let updatedCount = 0;
+              
+              // 更新本地消息列表中所有未读消息的状态
+              this.messages.forEach((msg, index) => {
+                // 只更新自己发送的且未被标记为已读的消息
+                if (msg.fromUserId === this.userId && !msg.isPeerRead && msg.sendStatus !== 4) {
+                  this.$set(this.messages[index], 'isPeerRead', true);
+                  updatedCount++;
+                  console.log(`   - 消息 ${msg.messageId} 已标记为已读`);
+                }
+              });
+              
+              console.log(`✅ 共更新 ${updatedCount} 条消息为已读状态`);
+            }
+          });
+        }
+      };
+      
+      this.handleMessageReadByPeer = handleMessageReadByPeer;
+      timManager.tim.on(TIM.EVENT.MESSAGE_READ_BY_PEER, handleMessageReadByPeer);
+      console.log('✅ 已监听消息已读回执');
+    },
+    
+    /**
+     * 标记当前会话的消息为已读
+     * 注意:这会通知对方"我已阅读他发送的消息",触发对方的 MESSAGE_READ_BY_PEER 事件
+     */
+    async markConversationRead() {
+      try {
+        if (!timManager.tim || !this.conversationID) {
+          console.warn('⚠️ TIM 未初始化或会话ID为空');
+          return;
+        }
+        
+        console.log('📖 标记会话已读:', this.conversationID);
+        
+        // 调用 TIM SDK 标记会话已读
+        // 这会通知对方:他发送给我的消息已被阅读
+        await timManager.tim.setMessageRead({ conversationID: this.conversationID });
+        
+        console.log('✅ 会话已标记为已读,已通知对方');
+      } catch (error) {
+        console.error('❌ 标记会话已读失败:', error);
+      }
+    },
+    
     /**
      * 发送文本消息
      */
@@ -2158,6 +2249,13 @@ export default {
       timPresenceManager.offStatusChange(this.targetUserId, this.onlineStatusCallback);
       console.log('✅ 已清理 WebSocket 监听');
     }
+    
+    // 清理已读回执监听
+    if (this.handleMessageReadByPeer && timManager.tim) {
+      const TIM = timManager.tim.TIM;
+      timManager.tim.off(TIM.EVENT.MESSAGE_READ_BY_PEER, this.handleMessageReadByPeer);
+      console.log('✅ 已清理已读回执监听');
+    }
   }
 };
 </script>
@@ -2491,17 +2589,20 @@ export default {
 
 .message-status {
   text-align: right;
-  font-size: 24rpx;
+  font-size: 22rpx;
+  color: #999;
+  margin-top: 8rpx;
+}
+
+.message-status .status-unread {
   color: #999;
-  margin-top: 5rpx;
-  
 }
 
-.message-status .read {
+.message-status .status-read {
   color: #07c160;
 }
 
-.message-status .failed {
+.message-status .status-failed {
   color: #fa5151;
 }
 

+ 3 - 0
LiangZhiYUMao/pages/message/index.vue

@@ -654,6 +654,9 @@ export default {
           console.log('🚫 已过滤拉黑用户:', this.blacklistUsers);
         }
         
+        // 加载完会话列表后,立即查询一次在线状态
+        await this.refreshOnlineStatus();
+        
       } catch (e) {
         console.error('❌ 加载会话列表失败:', e);
         console.error('❌ 错误详情:', e.message || e);

+ 4 - 4
LiangZhiYUMao/utils/tim-presence-manager.js

@@ -98,8 +98,8 @@ class TIMPresenceManager {
    * 监听 TIM 连接状态变更
    */
   listenTIMConnectionStatus() {
-    if (!timManager.tim) {
-      console.warn('⚠️ TIM 未初始化,无法监听连接状态');
+    if (!timManager.tim || !timManager.tim.TIM) {
+      console.warn('⚠️ TIM 未初始化或 TIM 对象不完整,无法监听连接状态');
       return;
     }
     
@@ -134,8 +134,8 @@ class TIMPresenceManager {
    * 监听 TIM 用户状态更新(好友状态)
    */
   listenTIMUserStatus() {
-    if (!timManager.tim) {
-      console.warn('⚠️ TIM 未初始化,无法监听用户状态');
+    if (!timManager.tim || !timManager.tim.TIM) {
+      console.warn('⚠️ TIM 未初始化或 TIM 对象不完整,无法监听用户状态');
       return;
     }