import { mqttClient } from "./mqtt"; import { getWhiteboardShapes, getWhiteboardHistory } from "@/views/custom/api"; import { useMeterStore } from '@/stores/modules/meter'; import { encode, decode } from '@msgpack/msgpack' import { ElMessage } from 'element-plus'; import { emitter } from "@/utils/bus.js"; const meterStore = useMeterStore(); meterStore.initUdid(); let isRemote = false; let canvasInstance = null; // 获取本地缓存 userData function getLocalUserData() { const dataStr = sessionStorage.getItem('userData'); if (!dataStr) return null; try { return JSON.parse(dataStr); } catch (e) { console.error("解析 userData 失败:", e); return null; } } export const WhiteboardSync = { async init(canvas, roomUid) { if (!canvas || !roomUid) return; canvasInstance = canvas; const localUser = getLocalUserData(); const localUid = localUser?.uid; try { // 先连接 MQTT await mqttClient.connect(meterStore.getSudid()); // 获取历史数据 const res = await getWhiteboardHistory({ after_timestamp: 0 }, roomUid); if (res.meta.code === 200 && res.data.shapes.length > 0) { canvasInstance.addShape(res.data.shapes); }else if(res.meta.code === 401){ emitter.emit('whiteboardFailed',true); } // 订阅当前房间 const topic = `xsynergy/room/${roomUid}/whiteboard/#`; mqttClient.subscribe(topic, async (shapeData) => { const shapeDataNew = JSON.parse(shapeData.toString()) // const shapeDataNew = decode(message); try { isRemote = true; // 如果 shape 来自本地用户,则跳过 if (shapeDataNew.user_uid === localUid) return; const res = await getWhiteboardHistory({ after_timestamp: shapeDataNew.created_at }, roomUid); if (res.meta.code === 200) { canvasInstance.addShape(res.data.shapes); } else { ElMessage.error("获取历史数据失败"); console.error("获取历史数据失败"); } } catch (e) { console.error("处理MQTT数据失败:", e); } finally { isRemote = false; } }); } catch (err) { console.log("初始化多人同步失败:", err) // console.error("❌ 连接或订阅失败:", err); } // 监听画布事件:新增图形 canvas.on('drawingEnd', async (shape) => { // 如果来自远程,或不是需要同步的类型,跳过 if (isRemote || !['pencil', 'line', 'rectangle', 'circle', 'eraser'].includes(shape.type)) return; // 如果是本地用户自己的 shape,则不调用接口 if (shape.user_uid && shape.user_uid === localUid) return; shape.room_uid = roomUid; try { await getWhiteboardShapes(shape, roomUid); } catch (err) { ElMessage.error("提交形状失败"); console.error("提交形状失败:", err); } }); // 监听画布事件:清空 canvas.on('clear', async () => { if (!isRemote) { try { // TODO: 调用接口,后端再发 MQTT // await clearWhiteboard(roomUid); } catch (err) { console.error("提交清空失败:", err); } } }); }, };