浏览代码

feat(student): 增加 slideIndex 独立消息通道防止被覆盖

为 yMessage 新增 slideIndex 独立消息通道,避免该类型消息被其他普通消息覆盖。同时调整消息监听和追平逻辑,分别处理 latest 和 slideIndex 两类消息,确保幻灯片索引消息能正常同步。
lsc 8 小时之前
父节点
当前提交
2d5a3ad1b1
共有 1 个文件被更改,包括 36 次插入 和 10 次删除
  1. 36 10
      src/views/Student/index.vue

+ 36 - 10
src/views/Student/index.vue

@@ -3283,7 +3283,6 @@ const messageInit = () => {
   yMessage.value.observe((e: any) => {
     // 同时兼容 keysChanged 和 changes.keys(不同 Yjs 版本/事件结构)
     const changed = e.keysChanged || e.changes?.keys
-    // ★ 打印每个 key 的 action(add/update/delete)和 oldValue
     const keysMap = e.keys || e.changes?.keys
     if (keysMap && keysMap.get) {
       for (const [key, info] of keysMap.entries()) {
@@ -3291,21 +3290,37 @@ const messageInit = () => {
       }
     }
     console.log('🔗 yMessage observe 触发, changed keys:', changed ? Array.from(changed) : 'null')
-    if (!changed || !changed.has('latest')) return
-    const message = yMessage.value!.get('latest')
-    console.log('🔗 yMessage latest:', message, '当前 mId:', mId.value)
-    if (message && message.mId !== mId.value) {
-      getMessages(message)
+    if (!changed) return
+    // slideIndex 独立通道
+    if (changed.has('slideIndex')) {
+      const slideMsg = yMessage.value!.get('slideIndex')
+      console.log('🔗 yMessage slideIndex:', slideMsg, '当前 mId:', mId.value)
+      if (slideMsg && slideMsg.mId !== mId.value) {
+        getMessages(slideMsg)
+      }
+    }
+    // 其他普通消息
+    if (changed.has('latest')) {
+      const message = yMessage.value!.get('latest')
+      console.log('🔗 yMessage latest:', message, '当前 mId:', mId.value)
+      if (message && message.mId !== mId.value) {
+        getMessages(message)
+      }
     }
   })
 
-  // ★ 追平:连接建立后立即读取当前 latest,
+  // ★ 追平:连接建立后立即读取当前 latest 和 slideIndex,
   // 防止老师在学生 observe 注册之前发的消息丢失(尤其是当前所在幻灯片)
   const latest = yMessage.value.get('latest')
   if (latest && latest.mId !== mId.value) {
     console.log('🔗 追平当前 latest 消息:', latest)
     getMessages(latest)
   }
+  const slideIdx = yMessage.value.get('slideIndex')
+  if (slideIdx && slideIdx.mId !== mId.value) {
+    console.log('🔗 追平当前 slideIndex 消息:', slideIdx)
+    getMessages(slideIdx)
+  }
 
   // 计时器消息数组
   yTimerMessages.value = doc.getArray('timerMessages')
@@ -3635,8 +3650,13 @@ const sendMessage = (obj: any) => {
     else {
       // 普通消息:只保留最后一条
       if (yMessage.value) {
-        // 用 Map.set 代替 Array.delete+push,只产生 1 条 update
-        yMessage.value.set('latest', message)
+        if (messageType === 'slideIndex') {
+          // slideIndex 单独通道,防止被其他消息挤掉
+          yMessage.value.set('slideIndex', message)
+        }
+        else {
+          yMessage.value.set('latest', message)
+        }
       }
       else {
         console.warn('⚠️ sendMessage: yMessage.value 为 null,消息未写入! type:', messageType, 'docSocket:', !!docSocket.value)
@@ -4575,7 +4595,7 @@ const createWebSocketConnection = async (type = 1) => {
         }
       }
 
-      // catch-up:读取服务器同步过来的 latest 消息
+      // catch-up:读取服务器同步过来的 latest 和 slideIndex 消息
       if (yMessage.value) {
         const latest = yMessage.value.get('latest')
         console.log('🔗 synced catch-up latest:', latest)
@@ -4583,6 +4603,12 @@ const createWebSocketConnection = async (type = 1) => {
           console.log('🔗 synced catch-up: 处理 latest 消息', latest.type)
           getMessages(latest)
         }
+        const slideIdx = yMessage.value.get('slideIndex')
+        console.log('🔗 synced catch-up slideIndex:', slideIdx)
+        if (slideIdx && slideIdx.mId !== mId.value) {
+          console.log('🔗 synced catch-up: 处理 slideIndex 消息', slideIdx.slideIndex)
+          getMessages(slideIdx)
+        }
       }
 
       // catch-up:读取计时器、激光笔、画图状态