feat:更新dev代码

This commit is contained in:
leilei
2025-11-21 16:04:30 +08:00
parent a894367dcc
commit 5bf4998cbd
11 changed files with 662 additions and 303 deletions

View File

@@ -0,0 +1,43 @@
name: Deploy To Dev
on:
push:
branches:
- 'dev'
jobs:
deploy:
runs-on: gx-dev01
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Copy specific directory to runner's host machine
run: |
TARGET_DIR="./dist"
# 检查 dist 目录是否存在
if [ ! -d "$TARGET_DIR" ]; then
echo "Error: The source directory '$TARGET_DIR' does not exist in the repository."
# 如果目录不存在,报错并退出当前步骤
exit 1
fi
cp -r ./dist/* /data/xsy-www/
- name: Find and restart the app container
run: |
# 1. 使用 docker ps 过滤包含 'xsy-lighttpd' 服务的容器
# 2. 提取容器 ID 或名称
CONTAINER_ID=$(docker ps -a --filter "name=xsy-lighttpd" --format "{{.ID}}")
if [ -z "$CONTAINER_ID" ]; then
echo "Error: Could not find any container matching name 'app1'."
exit 1
else
echo "Found container ID: $CONTAINER_ID. Restarting..."
# 使用标准的 docker restart 命令
docker restart "$CONTAINER_ID"
echo "Container restarted successfully."
fi

BIN
dist.zip

Binary file not shown.

View File

@@ -84,7 +84,6 @@ const clickJoin = async () => {
router.push({ router.push({
path: '/conferencingRoom', path: '/conferencingRoom',
query:{ query:{
type:2,//创建房间,加入房间 2
room_uid:socketInformation.value.room_uid room_uid:socketInformation.value.room_uid
} }
}) })

View File

@@ -349,7 +349,6 @@ function handleFileUploadMessage(payload, topic){
const messageStr = payload.toString() const messageStr = payload.toString()
const data = JSON.parse(messageStr) const data = JSON.parse(messageStr)
// emitter.emit('fileUploadStatus') // emitter.emit('fileUploadStatus')
console.log(data,'data文件转换完成预览通知')
const userId = JSON.parse(sessionStorage.getItem('userData'))?.uid const userId = JSON.parse(sessionStorage.getItem('userData'))?.uid
if(dialogFileVisible.value){ if(dialogFileVisible.value){
dialogFileVisible.value = false dialogFileVisible.value = false
@@ -422,7 +421,7 @@ function handlePdfMessage(payload, topic){
case 'converting': case 'converting':
break break
case 'completed': case 'completed':
getConvertedFile(data.task_id) getConvertedFile(data.task_id,data.room_uid)
break break
case 'failed': case 'failed':
break break
@@ -436,12 +435,12 @@ function handlePdfMessage(payload, topic){
} }
// 获取转换后的文件 // 获取转换后的文件
const getConvertedFile = async (taskId) => { const getConvertedFile = async (taskId,roomId) => {
try { try {
if (!taskId) { if (!taskId) {
throw new Error('任务ID不存在') throw new Error('任务ID不存在')
} }
const fileRes = await getConvertStatusApi(taskId,props.roomId) const fileRes = await getConvertStatusApi(taskId,roomId)
} catch (err) { } catch (err) {
console.error('获取转换文件失败:', err) console.error('获取转换文件失败:', err)
handleError('获取转换文件失败', err) handleError('获取转换文件失败', err)

View File

@@ -457,6 +457,7 @@ const loading = ref(false);
let lastPublishTime = 0; let lastPublishTime = 0;
const publishThrottleTime = 100; // 100ms 节流 const publishThrottleTime = 100; // 100ms 节流
// 鼠标状态跟踪 // 鼠标状态跟踪
const mouseState = reactive({ const mouseState = reactive({
isDrawing: false, isDrawing: false,
@@ -1150,6 +1151,7 @@ async function initMqttFilePreview(){
isMqttFilePreview.value = true isMqttFilePreview.value = true
// 订阅主题 // 订阅主题
emitter.emit('subscribeToFilePreviewTopic',{roomId:roomId.value}) emitter.emit('subscribeToFilePreviewTopic',{roomId:roomId.value})
emitter.emit('roomces',{roomId:roomId.value})
} catch (error) { } catch (error) {
console.error('MQTT连接失败:', error) console.error('MQTT连接失败:', error)
ElMessage.error('文件上传服务连接失败') ElMessage.error('文件上传服务连接失败')
@@ -1904,9 +1906,6 @@ function handleRemoteWhiteboardOpen(data) {
// 处理远程关闭白板 // 处理远程关闭白板
function handleRemoteWhiteboardClose(data) { function handleRemoteWhiteboardClose(data) {
ElMessage.info(`${data.senderName || data.sender} 关闭了白板`); ElMessage.info(`${data.senderName || data.sender} 关闭了白板`);
// if(data.roomType == '1'){
// isWhiteboardActive.value = false;
// }
//当远程用户关闭白板时,如果本地有屏幕共享,确保屏幕共享重新显示 //当远程用户关闭白板时,如果本地有屏幕共享,确保屏幕共享重新显示
nextTick(() => { nextTick(() => {
if (hasActiveScreenShare.value && !isWhiteboardActive.value) { if (hasActiveScreenShare.value && !isWhiteboardActive.value) {
@@ -1953,7 +1952,6 @@ function publishWhiteboardMessage(type, payload = {}) {
try { try {
const message = { const message = {
type, type,
roomType: route.query.type,//用于判断是参与者还是发起者
roomId: roomId.value, roomId: roomId.value,
sender: hostUid.value, sender: hostUid.value,
senderName: hostUid.value, senderName: hostUid.value,
@@ -2115,22 +2113,34 @@ function setupRoomListeners() {
} }
// 事件处理函数 // 事件处理函数
/**
* 处理房间连接成功事件
* 1. 初始化房间ID
* 2. 初始化各种MQTT连接白板、激光笔、文件上传等
* 3. 更新连接状态
* 4. 初始化已存在的远程参与者
*/
async function handleConnected() { async function handleConnected() {
// 设置当前房间ID
roomId.value = room.name roomId.value = room.name
await initMqtt();
await initToLaserPointerMqtt(); // 初始化各种MQTT服务
await initMqttFileUploadSucc() ; await initMqtt(); // 白板MQTT
await initMqttFileConversionStatus(); await initToLaserPointerMqtt(); // 激光笔MQTT
await initMqttFilePreview(); await initMqttFileUploadSucc(); // 文件上传成功MQTT
await initMqttEnlargeVideo(); await initMqttFileConversionStatus(); // 文件转换状态MQTT
await initMqttFilePreview(); // 文件预览MQTT
await initMqttEnlargeVideo(); // 视频放大MQTT
// 更新连接状态
status.value = false; status.value = false;
ElMessage.success('已成功连接到房间'); ElMessage.success('已成功连接到房间');
// 初始化现有远程参与者
// 初始化已存在的远程参与者
room.remoteParticipants.forEach(participant => { room.remoteParticipants.forEach(participant => {
addRemoteParticipant(participant); addRemoteParticipant(participant); // 添加参与者
setupParticipantListeners(participant); setupParticipantListeners(participant); // 设置监听器
// 立即检查并更新参与者的轨道状态 updateParticipantTracks(participant); // 更新轨道状态
updateParticipantTracks(participant);
}); });
} }
@@ -2840,34 +2850,6 @@ function handleScreenShareEnded() {
room.localParticipant.off('screenShareEnded', handleScreenShareEnded); room.localParticipant.off('screenShareEnded', handleScreenShareEnded);
} }
async function joinRoomBtn() {
try {
loading.value = true; // 开始加载
status.value = true; // 确保显示加载状态
const res = await getRoomToken({max_participants: 20});
if(res.meta.code != 200){
ElMessage.error(res.meta.message);
loading.value = false;
return;
}
const token = res.data.access_token;
roomName.value = res.data.room.name
if (!token) {
throw new Error('获取 token 失败');
}
setupRoomListeners();
await room.connect(wsURL, token, {
autoSubscribe: true,
});
} catch (error) {
ElMessage.error(`连接失败: ${error.message}`);
status.value = true;
} finally {
loading.value = false; // 无论成功失败都结束加载
}
}
// 离开会议函数 // 离开会议函数
async function leaveRoom() { async function leaveRoom() {
try { try {
@@ -3105,18 +3087,14 @@ onUnmounted(() => {
} }
}); });
onMounted(async () => { onMounted(async () => {
if(route.query.type == '1'){ try {
await joinRoomBtn() loading.value = true; // 开始加载
hostUid.value = roomStore.userUid status.value = true; // 确保显示加载状态
// 邀请用户参与房间
if(room.name){
await getInvite(room.name,{participants:[{user_uid:roomStore.detailUid,display_name:roomStore.detailName}], participant_role: "participant"})
}
} else {
const res = await getTokenApi(route.query.room_uid) const res = await getTokenApi(route.query.room_uid)
if(res.meta.code == 200){ if(res.meta.code == 200){
const token = res.data.access_token; const token = res.data.access_token;
hostUid.value = res.data.user_uid hostUid.value = res.data.user_uid
roomName.value = res.data.room_name
await nextTick(); await nextTick();
setupRoomListeners(); setupRoomListeners();
await room.connect(wsURL, token, { await room.connect(wsURL, token, {
@@ -3126,6 +3104,11 @@ onMounted(async () => {
ElMessage.error(res.meta.message); ElMessage.error(res.meta.message);
return; return;
} }
} catch (error) {
ElMessage.error(`连接失败: ${error.message}`);
status.value = true;
} finally {
loading.value = false; // 无论成功失败都结束加载
} }
}); });
</script> </script>

View File

@@ -42,7 +42,7 @@
<div class="screen-share-video"> <div class="screen-share-video">
<!-- 放大视频模式 --> <!-- 放大视频模式 -->
<div v-if="enlargedParticipant" class="enlarged-video-container"> <div v-if="enlargedParticipant" class="enlarged-video-container">
<div class="video-wrapper enlarged-video-wrapper" style='border:1px solid red'> <div class="video-wrapper enlarged-video-wrapper">
<video <video
v-if="enlargedParticipant.hasCameraTrack" v-if="enlargedParticipant.hasCameraTrack"
:ref="el => setEnlargedVideoRef(el)" :ref="el => setEnlargedVideoRef(el)"

View File

@@ -4,6 +4,14 @@
<Login @loginSuccess="handleLoginSuccess" /> <Login @loginSuccess="handleLoginSuccess" />
</div> </div>
<div v-else> <div v-else>
<!-- 加载状态 -->
<div v-if="loading" class="loading-container">
<div class="loading-content">
<el-icon class="loading-icon"><Loading /></el-icon>
<p>正在创建房间请稍候...</p>
</div>
</div>
<!-- 音频元素 --> <!-- 音频元素 -->
<audio ref="localAudio" autoplay muted class="audio-element"></audio> <audio ref="localAudio" autoplay muted class="audio-element"></audio>
<div id="audio"></div> <div id="audio"></div>
@@ -11,24 +19,16 @@
<div v-if="!status" class="meeting-container"> <div v-if="!status" class="meeting-container">
<!-- 视频容器 --> <!-- 视频容器 -->
<div class="video-layout" :class="{ <div class="video-layout" :class="{
'screen-sharing-active': hasActiveScreenShare || isWhiteboardActive || enlargedParticipant, 'screen-sharing-active': hasActiveContent,
'enlarged-mode': enlargedParticipant 'enlarged-mode': enlargedParticipant
}"> }">
<!-- 左侧共享屏幕/白板/放大视频区域 --> <!-- 左侧共享屏幕/白板/放大视频区域 -->
<div class="screen-share-area" v-if="hasActiveScreenShare || isWhiteboardActive || enlargedParticipant"> <div class="screen-share-area" v-if="hasActiveContent">
<div class="screen-share-header"> <div class="screen-share-header">
<h3 v-if="enlargedParticipant"> <h3>{{ currentTopLayerTitle }}</h3>
<span v-if="enlargedParticipant.identity === hostUid">我的放大视频</span> <div class="sharing-user" v-if="screenSharingUser">
<span v-else>放大视图 - {{ enlargedParticipant.identity }}</span> <span> {{ screenSharingUser }} 共享</span>
</h3>
<h3 v-else-if="isWhiteboardActive">共享白板</h3>
<h3 v-else>共享屏幕</h3>
<div class="sharing-user" v-if="!enlargedParticipant">
<span v-if="isWhiteboardActive || hasActiveScreenShare">
{{ screenSharingUser }} 共享
</span>
</div> </div>
<!-- v-if="enlargedParticipant && enlargedParticipant.identity === hostUid" -->
<el-button <el-button
v-if="enlargedParticipant && enlargedParticipant.identity === hostUid" v-if="enlargedParticipant && enlargedParticipant.identity === hostUid"
@click="closeEnlargedView" @click="closeEnlargedView"
@@ -36,11 +36,17 @@
size="small" size="small"
class="close-enlarge-btn" class="close-enlarge-btn"
> >
<!-- 关闭放大 -->
<img src="@/assets/images/shrink.png" style='width:16px;height:15px' alt="" /> <img src="@/assets/images/shrink.png" style='width:16px;height:15px' alt="" />
</el-button> </el-button>
</div> </div>
<div class="screen-share-video"> <div class="screen-share-video">
<!-- 内容层级容器 -->
<div class="content-layers-container">
<!-- 桌面共享或放大视频层 -->
<div v-if="hasScreenShareOrEnlarged"
class="content-layer screen-video-layer"
:class="{ 'active-layer': isScreenVideoTopLayer }">
<!-- 放大视频模式 --> <!-- 放大视频模式 -->
<div v-if="enlargedParticipant" class="enlarged-video-container"> <div v-if="enlargedParticipant" class="enlarged-video-container">
<div class="video-wrapper enlarged-video-wrapper"> <div class="video-wrapper enlarged-video-wrapper">
@@ -83,16 +89,6 @@
</div> </div>
</div> </div>
<!-- 白板模式 -->
<div v-else-if="isWhiteboardActive" class="whiteboard-container">
<tabulaRase
ref="whiteboardRef"
:roomId="roomId"
:userId="hostUid"
class="whiteboard-component"
/>
</div>
<!-- 屏幕共享模式 --> <!-- 屏幕共享模式 -->
<div v-else class="video-wrapper screen-share-wrapper"> <div v-else class="video-wrapper screen-share-wrapper">
<!-- 激光笔 Canvas --> <!-- 激光笔 Canvas -->
@@ -129,7 +125,20 @@
</span> </span>
</div> </div>
</div> </div>
</div>
<!-- 白板层 -->
<div v-if="isWhiteboardActive"
class="content-layer whiteboard-layer"
:class="{ 'active-layer': isWhiteboardTopLayer }">
<tabulaRase
ref="whiteboardRef"
:roomId="roomId"
:userId="hostUid"
class="whiteboard-component"
/>
</div>
</div>
</div> </div>
</div> </div>
@@ -212,7 +221,7 @@
</div> </div>
<div class="video-wrapper"> <div class="video-wrapper">
<div class="video-tracks"> <div class="video-tracks">
<!-- 摄像头视频 - 使用 ref 绑定 --> <!-- 摄像头视频 -->
<video <video
v-if="participant.hasCameraTrack" v-if="participant.hasCameraTrack"
:ref="el => setParticipantVideoRef(el, participant.identity, 'camera')" :ref="el => setParticipantVideoRef(el, participant.identity, 'camera')"
@@ -248,6 +257,7 @@
<!-- 固定在底部的控制按钮 --> <!-- 固定在底部的控制按钮 -->
<div class="fixed-controls"> <div class="fixed-controls">
<div class="controls-container"> <div class="controls-container">
<!-- 摄像头和麦克风 -->
<div class="microphone-control-group"> <div class="microphone-control-group">
<el-button @click="toggleCamera" :type="cameraEnabled ? 'danger' : 'info'" class="control-btn microphone-btn" size="large"> <el-button @click="toggleCamera" :type="cameraEnabled ? 'danger' : 'info'" class="control-btn microphone-btn" size="large">
{{ cameraEnabled ? '关闭摄像头' : '开启摄像头' }} {{ cameraEnabled ? '关闭摄像头' : '开启摄像头' }}
@@ -306,6 +316,8 @@
</template> </template>
</el-dropdown> </el-dropdown>
</div> </div>
<!-- 屏幕共享按钮 -->
<el-button <el-button
@click="toggleScreenShare" @click="toggleScreenShare"
:type="isScreenSharing ? 'danger' : (isGlobalScreenSharing ? 'primary' : 'info')" :type="isScreenSharing ? 'danger' : (isGlobalScreenSharing ? 'primary' : 'info')"
@@ -317,10 +329,11 @@
<span v-else-if="isGlobalScreenSharing">他人共享中</span> <span v-else-if="isGlobalScreenSharing">他人共享中</span>
<span v-else>共享屏幕</span> <span v-else>共享屏幕</span>
</el-button> </el-button>
<!-- 白板按钮 - 移除禁用条件 -->
<el-button <el-button
@click="toggleWhiteboard" @click="toggleWhiteboard"
:type="isWhiteboardActive ? 'danger' : 'info'" :type="isWhiteboardActive ? 'danger' : 'info'"
:disabled="cameraEnabled || !canWhiteboardShare"
class="control-btn" class="control-btn"
size="large" size="large"
> >
@@ -438,10 +451,13 @@ const enlargedVideo = ref(null); // 放大视频元素引用
const enlargedLaserPointerCanvas = ref(null); // 放大视频激光笔 Canvas const enlargedLaserPointerCanvas = ref(null); // 放大视频激光笔 Canvas
const enlargedLaserPointerContext = ref(null); // 放大视频激光笔上下文 const enlargedLaserPointerContext = ref(null); // 放大视频激光笔上下文
const lastActivatedLayer = ref(''); // 记录最后激活的图层:'screenVideo' 或 'whiteboard'
const loading = ref(false);
// 路径更新节流处理 // 路径更新节流处理
let lastPublishTime = 0; let lastPublishTime = 0;
const publishThrottleTime = 100; // 100ms 节流 const publishThrottleTime = 100; // 100ms 节流
// 鼠标状态跟踪 // 鼠标状态跟踪
const mouseState = reactive({ const mouseState = reactive({
isDrawing: false, isDrawing: false,
@@ -467,7 +483,8 @@ const laserPointerConfig = reactive({
const WHITEBOARD_MESSAGE_TYPES = { const WHITEBOARD_MESSAGE_TYPES = {
OPEN: 'open_whiteboard', OPEN: 'open_whiteboard',
CLOSE: 'close_whiteboard', CLOSE: 'close_whiteboard',
SYNC: 'sync_whiteboard' SYNC: 'sync_whiteboard',
ACTIVATE_LAYER: 'activate_layer'//图层激活消息
}; };
// 在 script 中添加激光笔消息类型和同步功能 // 在 script 中添加激光笔消息类型和同步功能
const LASER_POINTER_MESSAGE_TYPES = { const LASER_POINTER_MESSAGE_TYPES = {
@@ -480,6 +497,52 @@ const VIDEO_ENLARGE_MESSAGE_TYPES = {
SHRINK: 'shrink_video' SHRINK: 'shrink_video'
}; };
//判断是否有活动内容
const hasActiveContent = computed(() => {
return hasScreenShareOrEnlarged.value || isWhiteboardActive.value;
});
// 是否有桌面共享或放大视频
const hasScreenShareOrEnlarged = computed(() => {
return hasActiveScreenShare.value || enlargedParticipant.value;
});
// 判断各图层是否为顶层
const isScreenVideoTopLayer = computed(() => {
return hasScreenShareOrEnlarged.value && lastActivatedLayer.value === 'screenVideo';
});
const isWhiteboardTopLayer = computed(() => {
return isWhiteboardActive.value && lastActivatedLayer.value === 'whiteboard';
});
// 当前顶层标题
const currentTopLayerTitle = computed(() => {
if (hasScreenShareOrEnlarged.value && isScreenVideoTopLayer.value) {
if (enlargedParticipant.value) {
if (enlargedParticipant.value.identity === hostUid.value) {
return '我的放大视频';
} else {
return `放大视图 - ${enlargedParticipant.value.identity}`;
}
} else {
return '共享屏幕';
}
} else if (isWhiteboardActive.value && isWhiteboardTopLayer.value) {
return '共享白板';
} else {
// 默认显示第一个活动的内容
if (hasScreenShareOrEnlarged.value) {
if (enlargedParticipant.value) return '放大视频';
return '共享屏幕';
}
if (isWhiteboardActive.value) return '共享白板';
return '共享内容';
}
});
const participantCount = computed(() => { const participantCount = computed(() => {
return remoteParticipants.value.size + 1; // 包括自己 return remoteParticipants.value.size + 1; // 包括自己
}); });
@@ -508,7 +571,8 @@ const canScreenShare = computed(() => {
// 是否允许白板共享 // 是否允许白板共享
const canWhiteboardShare = computed(() => { const canWhiteboardShare = computed(() => {
return !enlargedParticipant.value; // return !enlargedParticipant.value;
return true; // 白板现在完全独立,没有限制
}); });
// 添加一个计算属性来显示屏幕共享状态提示 // 添加一个计算属性来显示屏幕共享状态提示
@@ -556,6 +620,38 @@ const room = new Room({
emitter.on('whiteboardFailed',whiteboardFailedHandle); emitter.on('whiteboardFailed',whiteboardFailedHandle);
// 激活图层函数
function activateLayer(layerType, isLocalAction = true) {
const oldLayer = lastActivatedLayer.value;
lastActivatedLayer.value = layerType;
// 如果是本地操作通过MQTT通知其他用户
if (isLocalAction) {
publishLayerActivation(layerType);
}
}
// 发布图层激活消息
function publishLayerActivation(layerType) {
try {
const message = {
type: WHITEBOARD_MESSAGE_TYPES.ACTIVATE_LAYER,
roomId: roomId.value,
sender: hostUid.value,
senderName: hostUid.value,
timestamp: Date.now(),
payload: {
layerType: layerType,
hasScreenShare: hasActiveScreenShare.value,
hasEnlargedVideo: !!enlargedParticipant.value,
hasWhiteboard: isWhiteboardActive.value
}
};
mqttClient.publish(`xSynergy/shareWhiteboard/${room.name}`, message);
} catch (error) {
console.error('发布图层激活消息失败:', error);
}
}
/** 登录成功回调 */ /** 登录成功回调 */
function handleLoginSuccess() { function handleLoginSuccess() {
showLogin.value = false; showLogin.value = false;
@@ -589,10 +685,10 @@ function enlargeParticipant(participant) {
ElMessage.info('已自动停止屏幕共享,开启视频放大模式'); ElMessage.info('已自动停止屏幕共享,开启视频放大模式');
} }
// 如果正在使用白板,自动退出 // 如果正在使用白板,自动退出
if (isWhiteboardActive.value) { // if (isWhiteboardActive.value) {
exitWhiteboard(); // exitWhiteboard();
ElMessage.info('已自动退出白板,开启视频放大模式'); // ElMessage.info('已自动退出白板,开启视频放大模式');
} // }
// 如果正在放大其他用户,先关闭 // 如果正在放大其他用户,先关闭
if (enlargedParticipant.value && enlargedParticipant.value.identity !== hostUid.value) { if (enlargedParticipant.value && enlargedParticipant.value.identity !== hostUid.value) {
@@ -600,6 +696,7 @@ function enlargeParticipant(participant) {
} }
enlargedParticipant.value = participant; enlargedParticipant.value = participant;
activateLayer('screenVideo', true); // 激活屏幕视频图层
ElMessage.success(`已放大您的视频`); ElMessage.success(`已放大您的视频`);
// 发布放大消息给其他用户 // 发布放大消息给其他用户
@@ -1053,7 +1150,9 @@ async function initMqttFilePreview(){
await mqttClient.connect(clientId) await mqttClient.connect(clientId)
isMqttFilePreview.value = true isMqttFilePreview.value = true
// 订阅主题 // 订阅主题
console.log('执行了一次')
emitter.emit('subscribeToFilePreviewTopic',{roomId:roomId.value}) emitter.emit('subscribeToFilePreviewTopic',{roomId:roomId.value})
emitter.emit('roomces',{roomId:roomId.value})
} catch (error) { } catch (error) {
console.error('MQTT连接失败:', error) console.error('MQTT连接失败:', error)
ElMessage.error('文件上传服务连接失败') ElMessage.error('文件上传服务连接失败')
@@ -1762,6 +1861,9 @@ function handleWhiteboardMessage(payload, topic) {
case WHITEBOARD_MESSAGE_TYPES.SYNC: case WHITEBOARD_MESSAGE_TYPES.SYNC:
handleWhiteboardSync(data); handleWhiteboardSync(data);
break; break;
case WHITEBOARD_MESSAGE_TYPES.ACTIVATE_LAYER:
handleRemoteLayerActivation(data);
break;
default: default:
console.warn('未知的白板消息类型:', data.type); console.warn('未知的白板消息类型:', data.type);
} }
@@ -1770,19 +1872,36 @@ function handleWhiteboardMessage(payload, topic) {
} }
} }
// 处理远程图层激活
function handleRemoteLayerActivation(data) {
const { layerType, hasScreenShare, hasEnlargedVideo, hasWhiteboard } = data.payload;
// 根据远程状态更新本地图层激活
if (layerType === 'screenVideo' && (hasScreenShare || hasEnlargedVideo)) {
// 只有当远程用户确实有屏幕共享或放大视频时才激活
activateLayer('screenVideo', false);
// console.log('远程激活屏幕视频层');
} else if (layerType === 'whiteboard' && hasWhiteboard) {
// 只有当远程用户确实有白板时才激活
activateLayer('whiteboard', false);
// console.log('远程激活白板层');
}
}
// 处理远程打开白板 // 处理远程打开白板
function handleRemoteWhiteboardOpen(data) { function handleRemoteWhiteboardOpen(data) {
ElMessage.info(`${data.senderName || data.sender} 开启了白板`); ElMessage.info(`${data.senderName || data.sender} 开启了白板`);
isWhiteboardActive.value = true; isWhiteboardActive.value = true;
// 当远程用户开启白板时,激活白板图层
activateLayer('whiteboard', false);
// 如果正在屏幕共享,自动停止 // 如果正在屏幕共享,自动停止
if (isScreenSharing.value) { // if (isScreenSharing.value) {
room.localParticipant.setScreenShareEnabled(false); // room.localParticipant.setScreenShareEnabled(false);
isScreenSharing.value = false; // isScreenSharing.value = false;
} // }
// 如果正在放大视图,自动关闭 // 如果正在放大视图,自动关闭
if (enlargedParticipant.value) { // if (enlargedParticipant.value) {
closeEnlargedView(); // closeEnlargedView();
} // }
} }
// 处理远程关闭白板 // 处理远程关闭白板
@@ -1791,6 +1910,17 @@ function handleRemoteWhiteboardClose(data) {
// if(data.roomType == '1'){ // if(data.roomType == '1'){
// isWhiteboardActive.value = false; // isWhiteboardActive.value = false;
// } // }
//当远程用户关闭白板时,如果本地有屏幕共享,确保屏幕共享重新显示
nextTick(() => {
if (hasActiveScreenShare.value && !isWhiteboardActive.value) {
activateLayer('screenVideo',false);
// 确保屏幕共享视频元素重新附加轨道
if (activeScreenShareTrack.value && screenShareVideo.value) {
attachTrackToVideo(screenShareVideo.value, activeScreenShareTrack.value);
}
}
});
} }
// 处理白板同步消息 // 处理白板同步消息
@@ -1815,8 +1945,11 @@ async function handleConfirmSelection(userInfo){
ElMessage.error('请选择加入房间的人员') ElMessage.error('请选择加入房间的人员')
return return
} }
const joinUserIds = userInfo.map(item => item.uid) const joinUserInfo = userInfo.map(item => ({
await getInvite(room.name,{user_uids:joinUserIds, participant_role: "participant"}) user_uid: item.uid,
display_name: item.name
}));
await getInvite(room.name,{participants:joinUserInfo, participant_role: "participant"})
} }
function publishWhiteboardMessage(type, payload = {}) { function publishWhiteboardMessage(type, payload = {}) {
@@ -1863,18 +1996,19 @@ async function toggleWhiteboard() {
async function startWhiteboard() { async function startWhiteboard() {
try { try {
// 如果正在屏幕共享,先停止 // 如果正在屏幕共享,先停止
if (isScreenSharing.value) { // if (isScreenSharing.value) {
await room.localParticipant.setScreenShareEnabled(false); // await room.localParticipant.setScreenShareEnabled(false);
isScreenSharing.value = false; // isScreenSharing.value = false;
ElMessage.info('已停止屏幕共享,开启白板'); // ElMessage.info('已停止屏幕共享,开启白板');
} // }
// 如果正在放大视图,先关闭 // 如果正在放大视图,先关闭
if (enlargedParticipant.value) { // if (enlargedParticipant.value) {
closeEnlargedView(); // closeEnlargedView();
} // }
// 激活白板状态 // 激活白板状态
isWhiteboardActive.value = true; isWhiteboardActive.value = true;
activateLayer('whiteboard', true); // 激活白板图层
const success = publishWhiteboardMessage(WHITEBOARD_MESSAGE_TYPES.OPEN, { const success = publishWhiteboardMessage(WHITEBOARD_MESSAGE_TYPES.OPEN, {
action: 'open', action: 'open',
whiteboardId: roomId.value, whiteboardId: roomId.value,
@@ -1905,6 +2039,10 @@ async function exitWhiteboard() {
if (whiteboardRef.value && whiteboardRef.value.cleanup) { if (whiteboardRef.value && whiteboardRef.value.cleanup) {
whiteboardRef.value.cleanup(); whiteboardRef.value.cleanup();
} }
// 如果关闭的是当前顶层,且还有屏幕共享或放大视频,则激活屏幕视频层
if (lastActivatedLayer.value === 'whiteboard' && hasScreenShareOrEnlarged.value) {
activateLayer('screenVideo',false);
}
ElMessage.success('已退出白板'); ElMessage.success('已退出白板');
} catch (error) { } catch (error) {
if (error !== 'cancel') { if (error !== 'cancel') {
@@ -1980,22 +2118,34 @@ function setupRoomListeners() {
} }
// 事件处理函数 // 事件处理函数
/**
* 处理房间连接成功事件
* 1. 初始化房间ID
* 2. 初始化各种MQTT连接白板、激光笔、文件上传等
* 3. 更新连接状态
* 4. 初始化已存在的远程参与者
*/
async function handleConnected() { async function handleConnected() {
// 设置当前房间ID
roomId.value = room.name roomId.value = room.name
await initMqtt();
await initToLaserPointerMqtt(); // 初始化各种MQTT服务
await initMqttFileUploadSucc() ; await initMqtt(); // 白板MQTT
await initMqttFileConversionStatus(); await initToLaserPointerMqtt(); // 激光笔MQTT
await initMqttFilePreview(); await initMqttFileUploadSucc(); // 文件上传成功MQTT
await initMqttEnlargeVideo(); await initMqttFileConversionStatus(); // 文件转换状态MQTT
await initMqttFilePreview(); // 文件预览MQTT
await initMqttEnlargeVideo(); // 视频放大MQTT
// 更新连接状态
status.value = false; status.value = false;
ElMessage.success('已成功连接到房间'); ElMessage.success('已成功连接到房间');
// 初始化现有远程参与者
// 初始化已存在的远程参与者
room.remoteParticipants.forEach(participant => { room.remoteParticipants.forEach(participant => {
addRemoteParticipant(participant); addRemoteParticipant(participant); // 添加参与者
setupParticipantListeners(participant); setupParticipantListeners(participant); // 设置监听器
// 立即检查并更新参与者的轨道状态 updateParticipantTracks(participant); // 更新轨道状态
updateParticipantTracks(participant);
}); });
} }
@@ -2026,6 +2176,10 @@ function handleTrackSubscribed(track, publication, participant) {
// 设置全局屏幕共享用户 // 设置全局屏幕共享用户
globalScreenSharingUser.value = participant.identity; globalScreenSharingUser.value = participant.identity;
isGlobalScreenSharing.value = true; isGlobalScreenSharing.value = true;
// 如果是远程用户的屏幕共享,激活屏幕视频层
if (participant.identity !== hostUid.value) {
activateLayer('screenVideo', false);
}
} }
// 立即附加到视频元素(如果元素已存在) // 立即附加到视频元素(如果元素已存在)
@@ -2208,6 +2362,10 @@ function updateScreenShareState(participant, track) {
// 有新的屏幕共享轨道 // 有新的屏幕共享轨道
screenSharingUser.value = participant.identity; screenSharingUser.value = participant.identity;
activeScreenShareTrack.value = track; activeScreenShareTrack.value = track;
// 重要:确保屏幕共享层被激活(如果白板已关闭)
if (!isWhiteboardActive.value) {
activateLayer('screenVideo',false);
}
// 附加到屏幕共享视频元素 // 附加到屏幕共享视频元素
if (screenShareVideo.value) { if (screenShareVideo.value) {
attachTrackToVideo(screenShareVideo.value, track); attachTrackToVideo(screenShareVideo.value, track);
@@ -2658,10 +2816,10 @@ async function toggleScreenShare() {
ElMessage.error('当前处于视频放大模式,无法进行屏幕共享'); ElMessage.error('当前处于视频放大模式,无法进行屏幕共享');
return; return;
} }
if(isWhiteboardActive.value){ // if(isWhiteboardActive.value){
ElMessage.error('请先关闭白板'); // ElMessage.error('请先关闭白板');
return; // return;
} // }
// 检查是否已经有其他用户在共享屏幕 // 检查是否已经有其他用户在共享屏幕
if (!isScreenSharing.value && isGlobalScreenSharing.value && globalScreenSharingUser.value !== hostUid.value) { if (!isScreenSharing.value && isGlobalScreenSharing.value && globalScreenSharingUser.value !== hostUid.value) {
ElMessage.error(`当前 ${globalScreenSharingUser.value} 正在共享屏幕,请等待其结束后再共享`); ElMessage.error(`当前 ${globalScreenSharingUser.value} 正在共享屏幕,请等待其结束后再共享`);
@@ -2682,6 +2840,7 @@ async function toggleScreenShare() {
// 设置全局屏幕共享状态 // 设置全局屏幕共享状态
globalScreenSharingUser.value = hostUid.value; globalScreenSharingUser.value = hostUid.value;
isGlobalScreenSharing.value = true; isGlobalScreenSharing.value = true;
activateLayer('screenVideo', true);// 激活屏幕视频图层
ElMessage.success('屏幕共享已开始'); ElMessage.success('屏幕共享已开始');
} }
} catch (error) { } catch (error) {
@@ -2696,28 +2855,6 @@ function handleScreenShareEnded() {
room.localParticipant.off('screenShareEnded', handleScreenShareEnded); room.localParticipant.off('screenShareEnded', handleScreenShareEnded);
} }
async function joinRoomBtn() {
try {
const res = await getRoomToken({max_participants: 20});
if(res.meta.code != 200){
ElMessage.error(res.meta.message);
return;
}
const token = res.data.access_token;
roomName.value = res.data.room.name
if (!token) {
throw new Error('获取 token 失败');
}
setupRoomListeners();
await room.connect(wsURL, token, {
autoSubscribe: true,
});
} catch (error) {
ElMessage.error(`连接失败: ${error.message}`);
status.value = true;
}
}
// 离开会议函数 // 离开会议函数
async function leaveRoom() { async function leaveRoom() {
try { try {
@@ -2900,6 +3037,30 @@ watch(enlargedParticipant, (newVal) => {
cleanupEnlargedLaserPointer(); cleanupEnlargedLaserPointer();
} }
}); });
// 监听屏幕共享或放大视频状态变化
watch(hasScreenShareOrEnlarged, (newVal) => {
if (newVal && !lastActivatedLayer.value) {
// 如果首次有屏幕共享或放大视频,且没有激活图层,则激活
activateLayer('screenVideo',false);
} else if (!newVal && lastActivatedLayer.value === 'screenVideo') {
// 如果屏幕视频层关闭且当前激活的是它,则检查是否有白板
if (isWhiteboardActive.value) {
activateLayer('whiteboard',false);
} else {
lastActivatedLayer.value = '';
}
}
});
// 监听白板状态变化
watch(isWhiteboardActive, (newVal) => {
if (newVal && !lastActivatedLayer.value) {
// 如果首次有白板,且没有激活图层,则激活
activateLayer('whiteboard',false);
}
});
// 添加专门的关闭激光笔函数 // 添加专门的关闭激光笔函数
function closeLaserPointer() { function closeLaserPointer() {
isLaserPointerActive.value = false; isLaserPointerActive.value = false;
@@ -2914,6 +3075,34 @@ function closeLaserPointer() {
ElMessage.info('屏幕共享已结束,激光笔已自动关闭'); ElMessage.info('屏幕共享已结束,激光笔已自动关闭');
} }
async function joinRoomBtn() {
try {
loading.value = true; // 开始加载
status.value = true; // 确保显示加载状态
const res = await getRoomToken({max_participants: 20});
if(res.meta.code != 200){
ElMessage.error(res.meta.message);
loading.value = false;
return;
}
const token = res.data.access_token;
roomName.value = res.data.room.name
if (!token) {
throw new Error('获取 token 失败');
}
setupRoomListeners();
await room.connect(wsURL, token, {
autoSubscribe: true,
});
} catch (error) {
ElMessage.error(`连接失败: ${error.message}`);
status.value = true;
} finally {
loading.value = false; // 无论成功失败都结束加载
}
}
// 在组件卸载时也清理资源 // 在组件卸载时也清理资源
onUnmounted(() => { onUnmounted(() => {
window.removeEventListener('resize', resizeLaserPointerCanvas); window.removeEventListener('resize', resizeLaserPointerCanvas);
@@ -2931,15 +3120,9 @@ onUnmounted(() => {
} }
}); });
onMounted(async () => { onMounted(async () => {
if(route.query.type == '1'){
await joinRoomBtn()
hostUid.value = roomStore.userUid
// 邀请用户参与房间
if(room.name){
await getInvite(room.name,{user_uids:[roomStore.detailUid], participant_role: "participant"})
}
} else {
const res = await getTokenApi(route.query.room_uid) const res = await getTokenApi(route.query.room_uid)
console.log(res,'res++--++')
if(res.meta.code == 200){ if(res.meta.code == 200){
const token = res.data.access_token; const token = res.data.access_token;
hostUid.value = res.data.user_uid hostUid.value = res.data.user_uid
@@ -2952,11 +3135,140 @@ onMounted(async () => {
ElMessage.error(res.meta.message); ElMessage.error(res.meta.message);
return; return;
} }
}
// if(route.query.type == '1'){
// await joinRoomBtn()
// hostUid.value = roomStore.userUid
// } else {
// const res = await getTokenApi(route.query.room_uid)
// if(res.meta.code == 200){
// const token = res.data.access_token;
// hostUid.value = res.data.user_uid
// await nextTick();
// setupRoomListeners();
// await room.connect(wsURL, token, {
// autoSubscribe: true,
// });
// }else{
// ElMessage.error(res.meta.message);
// return;
// }
// }
}); });
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.loading-container {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(15, 15, 26, 0.95);
backdrop-filter: blur(10px);
display: flex;
align-items: center;
justify-content: center;
z-index: 9999;
}
.loading-content {
text-align: center;
color: #ffffff;
}
.loading-icon {
font-size: 48px;
color: #409eff;
margin-bottom: 16px;
animation: spin 1s linear infinite;
}
.loading-content p {
margin: 0;
font-size: 16px;
color: #a0a0b0;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
/* 内容层级容器 */
.content-layers-container {
position: relative;
width: 100%;
height: 100%;
}
/* 内容图层通用样式 */
.content-layer {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
transition: all 0.3s ease;
/* 默认图层在底层 */
z-index: 1;
/* 激活的图层在最顶层 */
&.active-layer {
z-index: 10;
}
}
/* 屏幕视频层(桌面共享或放大视频) */
.screen-video-layer {
.enlarged-video-wrapper,
.screen-share-wrapper {
width: 100%;
height: 95%;
}
.enlarged-video-element,
.screen-share-element {
width: 100%;
height: 100%;
object-fit: contain;
background: #000;
border-radius: 8px;
}
}
/* 白板层 */
.whiteboard-layer {
.whiteboard-component {
width: 100%;
height: 100%;
}
}
/* 当图层非激活状态时的视觉提示 */
.content-layer:not(.active-layer) {
opacity: 0;
pointer-events: none; /* 非激活图层不接受交互 */
visibility: hidden;
}
/* 激活图层完全显示 */
.content-layer.active-layer {
opacity: 1;
visibility: visible;
}
/* 激光笔 Canvas 样式 */
.laser-pointer-canvas {
position: absolute;
top: 0;
left: 0;
z-index: 20; /* 激光笔在所有内容之上 */
pointer-events: auto;
cursor: crosshair;
}
.enlarged-laser-canvas { .enlarged-laser-canvas {
position: absolute; position: absolute;
top: 0; top: 0;
@@ -3048,14 +3360,14 @@ onMounted(async () => {
// } // }
/* 激光笔 Canvas 样式 */ /* 激光笔 Canvas 样式 */
.laser-pointer-canvas { // .laser-pointer-canvas {
position: absolute; // position: absolute;
top: 0; // top: 0;
left: 0; // left: 0;
z-index: 10; // z-index: 10;
pointer-events: auto; // pointer-events: auto;
cursor: crosshair; // cursor: crosshair;
} // }
/* 激光笔状态指示器 */ /* 激光笔状态指示器 */
.laser-pointer-indicator { .laser-pointer-indicator {
color: #ff0000; color: #ff0000;
@@ -3206,7 +3518,7 @@ body {
} }
.screen-share-element { .screen-share-element {
width: 100%; width: 100%;
height: 100%; height: 96%;
object-fit: contain; object-fit: contain;
background: #000; background: #000;
border-radius: 8px; border-radius: 8px;
@@ -3501,7 +3813,7 @@ body {
} }
.microphone-control-group .dropdown-btn { .microphone-control-group .dropdown-btn {
width: 36px; width: 36px;
height: 36px; height: 40px;
} }
.controls-container { .controls-container {
gap: 6px; gap: 6px;

View File

@@ -53,7 +53,6 @@
@mousemove="handleEnlargedCanvasMouseMove" @mousemove="handleEnlargedCanvasMouseMove"
@mouseup="handleEnlargedCanvasMouseUp" @mouseup="handleEnlargedCanvasMouseUp"
@mouseleave="handleEnlargedCanvasMouseLeave" @mouseleave="handleEnlargedCanvasMouseLeave"
style='border:1px solid red'
></canvas> ></canvas>
<video <video
v-if="enlargedParticipant.hasCameraTrack" v-if="enlargedParticipant.hasCameraTrack"

View File

@@ -53,7 +53,6 @@
@mousemove="handleEnlargedCanvasMouseMove" @mousemove="handleEnlargedCanvasMouseMove"
@mouseup="handleEnlargedCanvasMouseUp" @mouseup="handleEnlargedCanvasMouseUp"
@mouseleave="handleEnlargedCanvasMouseLeave" @mouseleave="handleEnlargedCanvasMouseLeave"
style='border:1px solid red'
></canvas> ></canvas>
<video <video
v-if="enlargedParticipant.hasCameraTrack" v-if="enlargedParticipant.hasCameraTrack"
@@ -100,7 +99,6 @@
@mousemove="handleCanvasMouseMove" @mousemove="handleCanvasMouseMove"
@mouseup="handleCanvasMouseUp" @mouseup="handleCanvasMouseUp"
@mouseleave="handleCanvasMouseLeave" @mouseleave="handleCanvasMouseLeave"
style='border:1px solid red'
></canvas> ></canvas>
<div class="video-tracks"> <div class="video-tracks">
<!-- 屏幕共享视频 --> <!-- 屏幕共享视频 -->

View File

@@ -1,6 +1,5 @@
<template> <template>
<div> <div>
<div class="left-list" v-loading="leftListLoading || loading"> <div class="left-list" v-loading="leftListLoading || loading">
<div class="list-tab"> <div class="list-tab">
<div <div
@@ -107,7 +106,7 @@
:key="indexs" :key="indexs"
> >
{{ {{
items.display_name + (items.display_name || items.user_uid) +
(indexs + 1 == item.all_participants.length (indexs + 1 == item.all_participants.length
? '' ? ''
: '、') : '、')
@@ -311,7 +310,9 @@ const updateDetail = (item) => {
* 触底加载 * 触底加载
*/ */
const infinite = () => { const infinite = () => {
console.log('外面的加载')
if (state.more) { if (state.more) {
console.log(state.more,'state.more执行了')
state.queryFrom.page++ state.queryFrom.page++
getList() getList()
} }

View File

@@ -53,7 +53,7 @@
:key="indexs" :key="indexs"
> >
{{ {{
items.display_name + (items.display_name || items.user_uid) +
(indexs + 1 == detail.all_participants.length (indexs + 1 == detail.all_participants.length
? '' ? ''
: '、') : '、')
@@ -98,7 +98,7 @@
<div class="content-file-list"> <div class="content-file-list">
<el-scrollbar <el-scrollbar
class="file-list" class="file-list"
height="calc(100vh - 380px)" height="calc(100vh - 390px)"
> >
<div <div
class="file-list-content" class="file-list-content"
@@ -203,8 +203,13 @@
</div> </div>
</div> </div>
<div class="user-card-btn"> <div class="user-card-btn">
<el-button type="info" @click="clickInitiate"> <el-button
发起协作 type="info"
@click="clickInitiate"
:loading="initiateLoading"
:disabled="initiateLoading"
>
{{ initiateLoading ? '正在发起邀请' : '发起协作' }}
</el-button> </el-button>
</div> </div>
</div> </div>
@@ -215,7 +220,6 @@
</div> </div>
</el-col> </el-col>
</el-row> </el-row>
<!-- <el-dialog <!-- <el-dialog
v-model="inviteDialog" v-model="inviteDialog"
title="远程协作" title="远程协作"
@@ -265,7 +269,7 @@ import leftTab from './components/leftTab/index.vue'
import AssistWx from './components/assistWx/index.vue' import AssistWx from './components/assistWx/index.vue'
import BrowseFile from '@/views/conferencingRoom/components/fileUpload/browseFile.vue' import BrowseFile from '@/views/conferencingRoom/components/fileUpload/browseFile.vue'
import { getInfo } from '@/api/login.js' import { getInfo } from '@/api/login.js'
import { getStatusApi ,getFileListApi ,getvideoUrlApi} from '@/api/conferencingRoom.js' import { getStatusApi ,getFileListApi ,getvideoUrlApi,getRoomToken,getInvite} from '@/api/conferencingRoom.js'
import { ElMessage } from 'element-plus' import { ElMessage } from 'element-plus'
import { useRoute, useRouter } from 'vue-router' import { useRoute, useRouter } from 'vue-router'
import { useRoomStore } from '@/stores/modules/room' import { useRoomStore } from '@/stores/modules/room'
@@ -289,6 +293,7 @@ const state = reactive({
socketInformation: null, socketInformation: null,
inviteDialog: false, inviteDialog: false,
cooperation: import.meta.env.VITE_APP_COOPERATION_TYPE, cooperation: import.meta.env.VITE_APP_COOPERATION_TYPE,
initiateLoading: false,
}) })
const userLoading = ref(false); // 用户信息加载状态 const userLoading = ref(false); // 用户信息加载状态
//文件预览 //文件预览
@@ -299,8 +304,10 @@ const isEmptyObject = (obj) => {
} }
/** 发起协作邀请 */ /** 发起协作邀请 */
const clickInitiate = () => { const clickInitiate = async () => {
state.initiateLoading = true
let userData = null let userData = null
try {
try { try {
userData = JSON.parse(sessionStorage.getItem('userData')) || null userData = JSON.parse(sessionStorage.getItem('userData')) || null
} catch (e) { } catch (e) {
@@ -325,12 +332,29 @@ const clickInitiate = () => {
roomStore.setUserUid(userData.uid) roomStore.setUserUid(userData.uid)
roomStore.setDetailUid(state.detail.uid) roomStore.setDetailUid(state.detail.uid)
roomStore.setDetailName(state.detail.name) roomStore.setDetailName(state.detail.name)
//创建房间
const res = await getRoomToken({max_participants: 20});
if(res.meta.code != 200){
ElMessage.error(res.meta.message);
return;
}
if(res.data.room.uid){
await getInvite(res.data.room.uid,{participants:[{user_uid:state.detail.uid,display_name:state.detail.name}], participant_role: "participant"})
}
router.push({ router.push({
path: '/conferencingRoom', path: '/conferencingRoom',
query:{ query:{
type:1//创建房间,加入房间 2 room_uid:res.data.room.uid
} }
}) })
} catch (error) {
console.error('发起协作失败:', error)
ElMessage.error('发起协作失败,请重试')
} finally {
// 无论成功失败,都重置按钮状态
state.initiateLoading = false
}
} }
/** 修改展示列表 */ /** 修改展示列表 */
@@ -472,7 +496,7 @@ function handlePreview(file) {
// 暴露给模板 // 暴露给模板
const { detail, weekName, tabValue, isShow, load, loadText, isLinkKnow, socketInformation, inviteDialog, cooperation,isShowLoading } = toRefs(state) const { detail, weekName, tabValue, isShow, load, loadText, isLinkKnow, socketInformation, inviteDialog, cooperation,isShowLoading ,initiateLoading } = toRefs(state)
// onMounted(async () => { // onMounted(async () => {
// await mqttClient.connect(`room${Math.random().toString(16).substr(2, 8)}`); // await mqttClient.connect(`room${Math.random().toString(16).substr(2, 8)}`);
// const res = await userStore.getInfo() // const res = await userStore.getInfo()
@@ -494,9 +518,10 @@ const { detail, weekName, tabValue, isShow, load, loadText, isLinkKnow, socketIn
} }
.app-container { .app-container {
padding: 20px; // padding: 20px;
// margin: 0 17px; // margin: 0 17px;
// height: calc(100vh - 50px); height: calc(100vh - 50px);
overflow: auto;
} }
.message-null { .message-null {
@@ -505,9 +530,8 @@ const { detail, weekName, tabValue, isShow, load, loadText, isLinkKnow, socketIn
} }
.right-content { .right-content {
height: calc(100vh - 40px); height: calc(100vh - 90px);
background: #f4f9ff; background: #f4f9ff;
.right-content-title { .right-content-title {
@extend .flex; @extend .flex;
justify-content: space-between; justify-content: space-between;
@@ -529,6 +553,7 @@ const { detail, weekName, tabValue, isShow, load, loadText, isLinkKnow, socketIn
.right-content-file { .right-content-file {
width: calc(100% - 30px); width: calc(100% - 30px);
height:calc(100% - 230px);
margin: 0 15px 15px; margin: 0 15px 15px;
} }
@@ -545,7 +570,7 @@ const { detail, weekName, tabValue, isShow, load, loadText, isLinkKnow, socketIn
.content-file-video { .content-file-video {
.file-video-bottom { .file-video-bottom {
width: 100%; width: 100%;
height: calc(100vh - 350px); height: calc(100vh - 360px);
padding: 15px; padding: 15px;
background: #fff; background: #fff;