Files
urbanLifeline/urbanLifelineWeb/packages/workcase_wechat/pages/meeting/Meeting/Meeting.uvue
2025-12-22 19:16:53 +08:00

191 lines
5.1 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<!-- #ifdef APP -->
<scroll-view style="flex:1">
<!-- #endif -->
<view class="page">
<!-- 自定义导航栏 -->
<view class="nav" :style="{ paddingTop: headerPaddingTop + 'px', height: headerTotalHeight + 'px' }">
<view class="nav-back" @tap="goBack">
<text class="nav-back-icon">←</text>
</view>
<text class="nav-title">视频会议</text>
<view class="nav-capsule"></view>
</view>
<!-- 会议内容区 -->
<view class="meeting-container" :style="{ marginTop: headerTotalHeight + 'px' }">
<!-- 会议信息 -->
<view class="meeting-info" v-if="!isInMeeting">
<view class="meeting-icon">
<text class="icon-text">📹</text>
</view>
<text class="meeting-name">{{ meetingName || '视频会议' }}</text>
<text class="meeting-desc">与客服进行实时视频沟通</text>
<view class="meeting-actions">
<view class="join-btn" @tap="joinMeeting">
<text class="join-text">加入会议</text>
</view>
</view>
<view class="meeting-tips">
<text class="tip-item">• 请确保网络连接稳定</text>
<text class="tip-item">• 允许摄像头和麦克风权限</text>
<text class="tip-item">• 建议在安静环境下进行会议</text>
</view>
</view>
<!-- 会议中状态 -->
<view class="in-meeting" v-else>
<!-- Jitsi Meet iframe 容器 -->
<web-view v-if="iframeUrl" :src="iframeUrl" class="meeting-webview"></web-view>
<!-- 会议控制栏 -->
<view class="meeting-controls">
<view class="control-btn" :class="{ active: isMuted }" @tap="toggleMute">
<text class="control-icon">{{ isMuted ? '🔇' : '🔊' }}</text>
<text class="control-label">{{ isMuted ? '取消静音' : '静音' }}</text>
</view>
<view class="control-btn" :class="{ active: isVideoOff }" @tap="toggleVideo">
<text class="control-icon">{{ isVideoOff ? '📷' : '📹' }}</text>
<text class="control-label">{{ isVideoOff ? '开启视频' : '关闭视频' }}</text>
</view>
<view class="control-btn leave-btn" @tap="leaveMeeting">
<text class="control-icon">📞</text>
<text class="control-label">离开会议</text>
</view>
</view>
</view>
</view>
</view>
<!-- #ifdef APP -->
</scroll-view>
<!-- #endif -->
</template>
<script setup lang="ts">
import { ref, onMounted } from 'vue'
import type { VideoMeetingVO } from '@/types/workcase'
// 响应式数据
const headerPaddingTop = ref<number>(44)
const headerTotalHeight = ref<number>(88)
const roomId = ref<string>('')
const workcaseId = ref<string>('')
const meetingName = ref<string>('视频会议')
const isInMeeting = ref<boolean>(false)
const iframeUrl = ref<string>('')
const isMuted = ref<boolean>(false)
const isVideoOff = ref<boolean>(false)
// 会议信息
const meeting = ref<VideoMeetingVO>({})
// 生命周期
onMounted(() => {
uni.getSystemInfo({
success: (res) => {
// #ifdef MP-WEIXIN
try {
const menuButtonInfo = uni.getMenuButtonBoundingClientRect()
headerPaddingTop.value = menuButtonInfo.top
headerTotalHeight.value = menuButtonInfo.bottom + 8
} catch (e) {
headerPaddingTop.value = res.statusBarHeight || 44
headerTotalHeight.value = (res.statusBarHeight || 44) + 44
}
// #endif
// #ifndef MP-WEIXIN
headerPaddingTop.value = res.statusBarHeight || 44
headerTotalHeight.value = (res.statusBarHeight || 44) + 44
// #endif
}
})
// 获取页面参数
const pages = getCurrentPages()
const currentPage = pages[pages.length - 1] as any
if (currentPage && currentPage.options) {
roomId.value = currentPage.options.roomId || ''
workcaseId.value = currentPage.options.workcaseId || ''
}
loadMeetingInfo()
})
// 加载会议信息
function loadMeetingInfo() {
console.log('加载会议信息:', roomId.value)
// TODO: 调用 workcaseChatAPI 获取会议信息
}
// 加入会议
function joinMeeting() {
uni.showLoading({ title: '正在加入会议...' })
// 模拟加入会议
setTimeout(() => {
uni.hideLoading()
isInMeeting.value = true
// TODO: 实际调用API创建/加入会议获取iframeUrl
// iframeUrl.value = meeting.value.iframeUrl || ''
uni.showToast({
title: '已加入会议',
icon: 'success'
})
}, 1000)
}
// 离开会议
function leaveMeeting() {
uni.showModal({
title: '离开会议',
content: '确定要离开当前会议吗?',
success: (res) => {
if (res.confirm) {
isInMeeting.value = false
iframeUrl.value = ''
uni.showToast({
title: '已离开会议',
icon: 'success'
})
}
}
})
}
// 切换静音
function toggleMute() {
isMuted.value = !isMuted.value
// TODO: 调用Jitsi API控制静音
}
// 切换视频
function toggleVideo() {
isVideoOff.value = !isVideoOff.value
// TODO: 调用Jitsi API控制视频
}
// 返回上一页
function goBack() {
if (isInMeeting.value) {
uni.showModal({
title: '离开会议',
content: '返回将离开当前会议,确定吗?',
success: (res) => {
if (res.confirm) {
uni.navigateBack()
}
}
})
} else {
uni.navigateBack()
}
}
</script>
<style lang="scss" scoped>
@import "./Meeting.scss";
</style>