lsc 2 months ago
parent
commit
d9013a226d
1 changed files with 188 additions and 73 deletions
  1. 188 73
      src/views/Student/index.vue

+ 188 - 73
src/views/Student/index.vue

@@ -570,6 +570,10 @@ const yMessage = ref<any | null>(null)
 const yTimerState = ref<any | null>(null)
 const yLaserState = ref<any | null>(null)
 const yWritingBoardState = ref<any | null>(null)
+// 独立的数组存储特殊类型的消息
+const yTimerMessages = ref<any | null>(null)
+const yLaserMessages = ref<any | null>(null)
+const yWritingBoardMessages = ref<any | null>(null)
 const providerSocket = ref<WebsocketProvider | null>(null)
 // 学生端画图同步数据
 const writingBoardSyncDataURL = ref<string | null>(null)
@@ -1206,11 +1210,26 @@ const clearAllSyncStates = () => {
     if (props.type == '1' && isCreator.value && docSocket.value) {
       console.log('🧹 创建老师退出,清空所有同步状态')
       docSocket.value.transact(() => {
-        // 清空消息
+        // 清空普通消息
         const messageArray = docSocket.value?.getArray?.('message')
         if (messageArray) {
           messageArray.delete(0, messageArray.length)
         }
+        // 清空计时器消息数组
+        const timerMessagesArray = docSocket.value?.getArray?.('timerMessages')
+        if (timerMessagesArray) {
+          timerMessagesArray.delete(0, timerMessagesArray.length)
+        }
+        // 清空激光笔消息数组
+        const laserMessagesArray = docSocket.value?.getArray?.('laserMessages')
+        if (laserMessagesArray) {
+          laserMessagesArray.delete(0, laserMessagesArray.length)
+        }
+        // 清空画图消息数组
+        const writingBoardMessagesArray = docSocket.value?.getArray?.('writingBoardMessages')
+        if (writingBoardMessagesArray) {
+          writingBoardMessagesArray.delete(0, writingBoardMessagesArray.length)
+        }
         // 清空计时器状态
         const timerStateMap = docSocket.value?.getMap?.('timerState')
         if (timerStateMap) {
@@ -2515,87 +2534,135 @@ const checkIsCreator = () => {
  * 初始化消息监听
  */
 const messageInit = () => {
+  if (!docSocket.value) return
 
-
-  if (docSocket.value && !yMessage.value) {
-    console.log('获取message', docSocket.value, yMessage.value)
+  // 初始化普通消息数组(只保留最后一条)
+  if (!yMessage.value) {
+    console.log('初始化普通消息数组')
     yMessage.value = docSocket.value.getArray('message')
     yMessage.value.observe((e: any) => {
-      // 执行清空数据
-      // 数据同步完成后,清理超过40分钟的消息数据
-      const messages = yMessage.value.toArray()
-      console.log('messages', messages)
-      console.log('messagesLength', messages.length)
-      // 如果是首次进入且是创建者,清空所有同步状态
-      if ((isFirstEnter.value || messages.length > 2000) && isCreator.value && docSocket.value) {
-        console.log('🧹 首次进入且为创建者或消息条数超2000,保留最新2000条消息,其他同步状态全部清空')
+      e.changes.added.forEach((i: any) => {
+        const message = i.content.getContent()[0]
+        console.log('yMessage', message)
+        if (message.mId !== mId.value) {
+          getMessages(message)
+        }
+      })
+    })
+  }
+
+  // 初始化计时器消息数组
+  if (!yTimerMessages.value) {
+    console.log('初始化计时器消息数组')
+    yTimerMessages.value = docSocket.value.getArray('timerMessages')
+    yTimerMessages.value.observe((e: any) => {
+      // 检查数组长度,如果超过2000条,清理旧数据
+      if (yTimerMessages.value && yTimerMessages.value.length > 2000 && isCreator.value && docSocket.value) {
+        const excessCount = yTimerMessages.value.length - 2000
         docSocket.value.transact(() => {
-          // 只保留最新2000条消息
-          const messageArray = docSocket.value?.getArray?.('message')
-          if (messageArray && messageArray.length > 2000) {
-            messageArray.delete(0, messageArray.length - 2000)
-          }
-          // 清空计时器状态
-          const timerStateMap = docSocket.value?.getMap?.('timerState')
-          if (timerStateMap) {
-            timerStateMap.clear()
-          }
-          // 清空激光笔状态
-          const laserStateMap = docSocket.value?.getMap?.('laserState')
-          if (laserStateMap) {
-            laserStateMap.clear()
-          }
-          // 清空画图状态
-          const writingBoardStateMap = docSocket.value?.getMap?.('writingBoardState')
-          if (writingBoardStateMap) {
-            writingBoardStateMap.clear()
-          }
+          yTimerMessages.value.delete(0, excessCount)
         })
-        // 标记已不再是首次进入
-        isFirstEnter.value = false
+        console.log(`🧹 清理了 ${excessCount} 条计时器消息,保留最新2000条`)
       }
-      if (messages.length > 0) {
-        const now = Date.now()
-        const messagesToKeep: any[] = []
-
-        for (let i = messages.length - 1; i >= 0; i--) {
-          const message = messages[i]
-          if (message && typeof message === 'object' && message.timestamp) {
-            const messageTime = new Date(message.timestamp).getTime()
-            if (now - messageTime <= SYNC_DATA_MAX_AGE) {
-              messagesToKeep.unshift(message)
-            }
-          }
+      
+      e.changes.added.forEach((i: any) => {
+        const message = i.content.getContent()[0]
+        if (message.mId !== mId.value) {
+          getMessages(message)
         }
+      })
+    })
+  }
 
-        // 如果有需要清理的消息
-        if (messagesToKeep.length < messages.length) {
-          // 修复报错:docSocket.value 可能为 null
-          if (docSocket.value) {
-            docSocket.value.transact(() => {
-              yMessage.value.delete(0, messages.length)
-              messagesToKeep.forEach((msg: any) => yMessage.value.push([msg]))
-            })
-            console.log(`🧹 清理了 ${messages.length - messagesToKeep.length} 条超过40分钟的消息`)
-          }
-        }
+  // 初始化激光笔消息数组
+  if (!yLaserMessages.value) {
+    console.log('初始化激光笔消息数组')
+    yLaserMessages.value = docSocket.value.getArray('laserMessages')
+    yLaserMessages.value.observe((e: any) => {
+      // 检查数组长度,如果超过2000条,清理旧数据
+      if (yLaserMessages.value && yLaserMessages.value.length > 2000 && isCreator.value && docSocket.value) {
+        const excessCount = yLaserMessages.value.length - 2000
+        docSocket.value.transact(() => {
+          yLaserMessages.value.delete(0, excessCount)
+        })
+        console.log(`🧹 清理了 ${excessCount} 条激光笔消息,保留最新2000条`)
       }
+      
+      e.changes.added.forEach((i: any) => {
+        const message = i.content.getContent()[0]
+        if (message.mId !== mId.value) {
+          getMessages(message)
+        }
+      })
+    })
+  }
 
+  // 初始化画图消息数组
+  if (!yWritingBoardMessages.value) {
+    console.log('初始化画图消息数组')
+    yWritingBoardMessages.value = docSocket.value.getArray('writingBoardMessages')
+    yWritingBoardMessages.value.observe((e: any) => {
+      // 检查数组长度,如果超过2000条,清理旧数据
+      if (yWritingBoardMessages.value && yWritingBoardMessages.value.length > 2000 && isCreator.value && docSocket.value) {
+        const excessCount = yWritingBoardMessages.value.length - 2000
+        docSocket.value.transact(() => {
+          yWritingBoardMessages.value.delete(0, excessCount)
+        })
+        console.log(`🧹 清理了 ${excessCount} 条画图消息,保留最新2000条`)
+      }
+      
       e.changes.added.forEach((i: any) => {
         const message = i.content.getContent()[0]
-        console.log('yMessage', message)
-        // const _nowTime = new Date()
-        // const _msgTime = new Date(message.timestamp)
-        if (
-          // (_nowTime as any) - (_msgTime as any) <= 1000 * 10 &&
-          message.mId !== mId.value
-        ) {
-          // 10秒内且不是自己发的消息
+        if (message.mId !== mId.value) {
           getMessages(message)
         }
       })
     })
   }
+
+  // 如果是首次进入且是创建者,清空所有同步状态
+  if (isFirstEnter.value && isCreator.value && docSocket.value) {
+    console.log('🧹 首次进入且为创建者,清空所有同步状态')
+    docSocket.value.transact(() => {
+      // 清空普通消息(只保留最后一条的逻辑在 sendMessage 中处理)
+      const messageArray = docSocket.value?.getArray?.('message')
+      if (messageArray) {
+        messageArray.delete(0, messageArray.length)
+      }
+      // 清空计时器消息数组
+      const timerMessagesArray = docSocket.value?.getArray?.('timerMessages')
+      if (timerMessagesArray) {
+        timerMessagesArray.delete(0, timerMessagesArray.length)
+      }
+      // 清空激光笔消息数组
+      const laserMessagesArray = docSocket.value?.getArray?.('laserMessages')
+      if (laserMessagesArray) {
+        laserMessagesArray.delete(0, laserMessagesArray.length)
+      }
+      // 清空画图消息数组
+      const writingBoardMessagesArray = docSocket.value?.getArray?.('writingBoardMessages')
+      if (writingBoardMessagesArray) {
+        writingBoardMessagesArray.delete(0, writingBoardMessagesArray.length)
+      }
+      // 清空计时器状态
+      const timerStateMap = docSocket.value?.getMap?.('timerState')
+      if (timerStateMap) {
+        timerStateMap.clear()
+      }
+      // 清空激光笔状态
+      const laserStateMap = docSocket.value?.getMap?.('laserState')
+      if (laserStateMap) {
+        laserStateMap.clear()
+      }
+      // 清空画图状态
+      const writingBoardStateMap = docSocket.value?.getMap?.('writingBoardState')
+      if (writingBoardStateMap) {
+        writingBoardStateMap.clear()
+      }
+    })
+    // 标记已不再是首次进入
+    isFirstEnter.value = false
+  }
   // 初始化计时器状态 Map 并监听
   if (docSocket.value && !yTimerState.value) {
     yTimerState.value = docSocket.value.getMap('timerState')
@@ -2657,18 +2724,66 @@ const messageInit = () => {
   }
 }
 
+/**
+ * 判断是否为特殊类型的消息(计时器、激光笔、画图)
+ */
+const isSpecialMessageType = (type: string): boolean => {
+  const timerTypes = ['timer_start', 'timer_pause', 'timer_reset', 'timer_stop', 'timer_finish', 'timer_update']
+  const laserTypes = ['laser_toggle', 'laser_move']
+  const writingBoardTypes = ['writing_board_update', 'writing_board_close', 'writing_board_blackboard']
+  return timerTypes.includes(type) || laserTypes.includes(type) || writingBoardTypes.includes(type)
+}
+
+/**
+ * 获取消息类型对应的数组
+ */
+const getMessageArrayByType = (type: string): any | null => {
+  const timerTypes = ['timer_start', 'timer_pause', 'timer_reset', 'timer_stop', 'timer_finish', 'timer_update']
+  const laserTypes = ['laser_toggle', 'laser_move']
+  const writingBoardTypes = ['writing_board_update', 'writing_board_close', 'writing_board_blackboard']
+  
+  if (timerTypes.includes(type)) {
+    return yTimerMessages.value
+  }
+  if (laserTypes.includes(type)) {
+    return yLaserMessages.value
+  }
+  if (writingBoardTypes.includes(type)) {
+    return yWritingBoardMessages.value
+  }
+  return null
+}
+
 /**
  * 发送消息
  */
 const sendMessage = (obj: any) => {
-  if (docSocket.value && yMessage.value) {
-    const message = obj
-    obj.timestamp = new Date().toISOString()
-    obj.mId = mId.value
-    docSocket.value.transact(() => {
-      yMessage.value.push([message])
-    })
-  }
+  if (!docSocket.value) return
+  
+  const message = obj
+  message.timestamp = new Date().toISOString()
+  message.mId = mId.value
+  
+  const messageType = message.type
+  const isSpecial = isSpecialMessageType(messageType)
+  
+  docSocket.value.transact(() => {
+    if (isSpecial) {
+      // 特殊类型消息:存储到对应的独立数组
+      const targetArray = getMessageArrayByType(messageType)
+      if (targetArray) {
+        targetArray.push([message])
+      }
+    }
+    else {
+      // 普通消息:只保留最后一条
+      if (yMessage.value) {
+        // 清空数组,只保留新消息
+        yMessage.value.delete(0, yMessage.value.length)
+        yMessage.value.push([message])
+      }
+    }
+  })
 }
 
 /**