更新
This commit is contained in:
@@ -3,18 +3,10 @@
|
||||
<el-card>
|
||||
<template #header>
|
||||
<div class="card-header">
|
||||
<span>患者端测试 - 接听来电</span>
|
||||
<span>医疗助理端 - 接听来电</span>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<el-alert
|
||||
type="info"
|
||||
:closable="false"
|
||||
class="mb-4"
|
||||
>
|
||||
<p>此页面用于测试音视频通话功能</p>
|
||||
<p>页面打开后会自动初始化患者端,等待医生端发起通话</p>
|
||||
</el-alert>
|
||||
|
||||
<div v-if="!initialized" class="init-section">
|
||||
<el-alert
|
||||
@@ -48,18 +40,21 @@
|
||||
<el-icon class="mr-2" :class="{ 'animate-pulse': hasIncomingCall }">
|
||||
<Phone />
|
||||
</el-icon>
|
||||
<span>{{ hasIncomingCall ? '收到来电!' : '患者端已初始化,等待来电...' }}</span>
|
||||
<span>{{ hasIncomingCall ? '收到来电!' : '医疗助理端已初始化,等待来电...' }}</span>
|
||||
</div>
|
||||
</template>
|
||||
<div class="mt-2">
|
||||
<p><strong>患者ID:</strong> {{ currentUserId }}</p>
|
||||
<p><strong>医疗助理ID:</strong> {{ currentUserId }}</p>
|
||||
<p><strong>状态:</strong> {{ hasIncomingCall ? '来电中' : '在线' }}</p>
|
||||
<p v-if="hasIncomingCall && incomingCallInfo">
|
||||
<strong>通话类型:</strong> 视频通话
|
||||
<strong>通话类型:</strong> {{ incomingCallInfo.isGroup ? '群组视频通话' : '视频通话' }}
|
||||
</p>
|
||||
</div>
|
||||
</el-alert>
|
||||
|
||||
<!-- 调试信息 -->
|
||||
|
||||
|
||||
<!-- 来电操作按钮 -->
|
||||
<div v-if="hasIncomingCall" class="call-actions mt-4">
|
||||
<el-button
|
||||
@@ -89,8 +84,23 @@
|
||||
</el-button>
|
||||
</div>
|
||||
|
||||
<div id="call-container" class="call-container">
|
||||
<TUICallKit v-if="initialized" />
|
||||
<div v-if="hasIncomingCall || callConnected" id="call-container" class="call-container">
|
||||
<TUICallKit />
|
||||
</div>
|
||||
|
||||
<div v-else-if="initialized" class="waiting-container">
|
||||
<el-empty description="等待来电中...">
|
||||
<template #image>
|
||||
<el-icon :size="80" color="#909399">
|
||||
<Phone />
|
||||
</el-icon>
|
||||
</template>
|
||||
</el-empty>
|
||||
</div>
|
||||
|
||||
<!-- 隐藏的 TUICallKit,用于接收来电信号 -->
|
||||
<div v-show="false">
|
||||
<TUICallKit v-if="initialized && !hasIncomingCall && !callConnected" />
|
||||
</div>
|
||||
</el-card>
|
||||
</div>
|
||||
@@ -99,7 +109,7 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, onUnmounted, computed, onMounted } from 'vue'
|
||||
import { Phone } from '@element-plus/icons-vue'
|
||||
import { TUICallKitAPI, TUICallKit, STATUS } from '@trtc/calls-uikit-vue'
|
||||
import { TUICallKitServer, TUICallKit, STATUS } from '@tencentcloud/call-uikit-vue'
|
||||
import { ElMessage, ElNotification } from 'element-plus'
|
||||
import request from '@/utils/request'
|
||||
import useUserStore from '@/stores/modules/user'
|
||||
@@ -115,39 +125,69 @@ const loading = ref(false)
|
||||
const initialized = ref(false)
|
||||
const currentUserId = ref('')
|
||||
const hasIncomingCall = ref(false)
|
||||
const callConnected = ref(false) // 添加通话连接状态
|
||||
const incomingCallInfo = ref<any>(null)
|
||||
const statusCheckTimer = ref<any>(null)
|
||||
|
||||
// 页面加载时自动初始化
|
||||
onMounted(() => {
|
||||
initPatient()
|
||||
})
|
||||
|
||||
// 定时检查状态(作为备用方案)
|
||||
const startStatusCheck = () => {
|
||||
if (statusCheckTimer.value) {
|
||||
clearInterval(statusCheckTimer.value)
|
||||
}
|
||||
|
||||
statusCheckTimer.value = setInterval(() => {
|
||||
// 这里可以添加状态检查逻辑
|
||||
console.log('定时检查 - 当前时间:', new Date().toLocaleTimeString())
|
||||
}, 5000)
|
||||
}
|
||||
|
||||
// 监听状态变化
|
||||
const handleStatusChange = ({ oldStatus, newStatus }: any) => {
|
||||
console.log('通话状态变化:', { oldStatus, newStatus })
|
||||
console.log('========================================')
|
||||
console.log('=== 通话状态变化回调触发 ===')
|
||||
console.log('oldStatus:', oldStatus)
|
||||
console.log('newStatus:', newStatus)
|
||||
console.log('STATUS 常量:', STATUS)
|
||||
console.log('========================================')
|
||||
|
||||
// 收到来电邀请
|
||||
// 收到来电邀请(与聊天组件同一套 SDK:@tencentcloud/call-uikit-vue)
|
||||
if (newStatus === STATUS.BE_INVITED) {
|
||||
console.log('>>> 收到来电邀请')
|
||||
hasIncomingCall.value = true
|
||||
incomingCallInfo.value = { oldStatus, newStatus }
|
||||
|
||||
// 显示来电通知
|
||||
ElNotification({
|
||||
title: '来电提醒',
|
||||
message: '收到视频通话请求',
|
||||
type: 'info',
|
||||
duration: 0, // 不自动关闭
|
||||
duration: 0,
|
||||
position: 'top-right'
|
||||
})
|
||||
|
||||
ElMessage.success('收到来电,请点击接听按钮')
|
||||
}
|
||||
|
||||
// 通话结束,回到空闲状态
|
||||
if (newStatus === STATUS.IDLE && hasIncomingCall.value) {
|
||||
// 通话接通
|
||||
if (newStatus === STATUS.CALLING_C2C_VIDEO || newStatus === STATUS.CALLING_GROUP_VIDEO) {
|
||||
console.log('>>> 通话已接通')
|
||||
ElMessage.success('通话已接通')
|
||||
hasIncomingCall.value = false
|
||||
incomingCallInfo.value = null
|
||||
ElMessage.info('通话已结束')
|
||||
callConnected.value = true // 设置通话连接状态
|
||||
}
|
||||
|
||||
// 通话结束,回到空闲状态(STATUS.IDLE 与聊天组件一致)
|
||||
if (newStatus === STATUS.IDLE) {
|
||||
if (hasIncomingCall.value || callConnected.value) {
|
||||
console.log('>>> 通话已结束')
|
||||
hasIncomingCall.value = false
|
||||
callConnected.value = false
|
||||
incomingCallInfo.value = null
|
||||
ElMessage.info('通话已结束')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -160,9 +200,11 @@ const initPatient = async () => {
|
||||
throw new Error('未获取到当前用户ID,请重新登录')
|
||||
}
|
||||
|
||||
console.log('=== 开始初始化医疗助理端 ===')
|
||||
console.log('当前用户ID:', patientId)
|
||||
ElMessage.info('正在获取签名...')
|
||||
|
||||
// 获取患者签名
|
||||
// 获取医疗助理签名
|
||||
const result = await request.get({
|
||||
url: '/tcm.diagnosis/getDoctorSignature',
|
||||
params: {
|
||||
@@ -177,35 +219,70 @@ const initPatient = async () => {
|
||||
const { sdkAppId, userId, userSig } = result
|
||||
currentUserId.value = userId
|
||||
|
||||
console.log('患者签名获取成功:', { userId, sdkAppId, userSigLength: userSig.length })
|
||||
console.log('医疗助理签名获取成功:', { userId, sdkAppId, userSigLength: userSig.length })
|
||||
console.log('完整签名信息:', result)
|
||||
ElMessage.info('正在初始化通话组件...')
|
||||
|
||||
// 设置状态变化回调
|
||||
TUICallKitAPI.setCallback({
|
||||
statusChanged: handleStatusChange
|
||||
})
|
||||
// 与聊天组件一致:使用 @tencentcloud/call-uikit-vue 的 TUICallKitServer(正式打包可收视频)
|
||||
console.log('=== 开始调用 TUICallKitServer.init ===')
|
||||
|
||||
// 初始化(注意:SDKAppID必须是数字类型)
|
||||
await TUICallKitAPI.init({
|
||||
userID: userId,
|
||||
userSig: userSig,
|
||||
SDKAppID: Number(sdkAppId) // 转换为数字类型
|
||||
})
|
||||
if (!TUICallKitServer || typeof TUICallKitServer.init !== 'function') {
|
||||
throw new Error('TUICallKitServer 未正确加载,请刷新页面重试')
|
||||
}
|
||||
|
||||
try {
|
||||
await TUICallKitServer.init({
|
||||
userID: userId,
|
||||
userSig: userSig,
|
||||
SDKAppID: Number(sdkAppId)
|
||||
})
|
||||
} catch (initError: any) {
|
||||
console.warn('TUICallKitServer.init 出现错误,但继续执行:', initError)
|
||||
}
|
||||
|
||||
console.log('=== TUICallKitServer.init 完成 ===')
|
||||
|
||||
const callbacks = {
|
||||
statusChanged: handleStatusChange,
|
||||
onError: (error: any) => {
|
||||
console.error('=== TUICallKit 错误回调 ===', error)
|
||||
ElMessage.error(`通话错误: ${error?.message || '未知错误'}`)
|
||||
},
|
||||
onInvited: (inviteData: any) => {
|
||||
console.log('=== 收到邀请回调 (onInvited) ===', inviteData)
|
||||
ElMessage.info('收到通话邀请 (onInvited)')
|
||||
},
|
||||
afterCalling: () => {
|
||||
console.log('=== afterCalling 回调 ===')
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
TUICallKitServer.setCallback(callbacks)
|
||||
} catch (callbackError: any) {
|
||||
console.warn('设置回调时出现错误,但继续执行:', callbackError)
|
||||
}
|
||||
|
||||
console.log('回调设置完成')
|
||||
|
||||
console.log('TUICallKitAPI.init 完成')
|
||||
console.log('已注册状态监听回调')
|
||||
ElMessage.info('等待初始化完成...')
|
||||
|
||||
// 等待初始化完成
|
||||
await new Promise(resolve => setTimeout(resolve, 2000))
|
||||
|
||||
initialized.value = true
|
||||
ElMessage.success('患者端初始化成功,等待来电...')
|
||||
ElMessage.success('医疗助理端初始化成功,等待来电...')
|
||||
|
||||
console.log('患者端初始化完成,userId:', userId)
|
||||
console.log('=== 医疗助理端初始化完成 ===')
|
||||
console.log('userId:', userId)
|
||||
console.log('等待来电中...')
|
||||
console.log('请在医生端发起群组通话,目标用户ID应该是:', userId)
|
||||
|
||||
// 启动状态检查
|
||||
startStatusCheck()
|
||||
|
||||
} catch (error: any) {
|
||||
console.error('初始化失败:', error)
|
||||
console.error('=== 初始化失败 ===', error)
|
||||
ElMessage.error(error.message || '初始化失败')
|
||||
} finally {
|
||||
loading.value = false
|
||||
@@ -216,9 +293,10 @@ const initPatient = async () => {
|
||||
const acceptCall = async () => {
|
||||
try {
|
||||
console.log('接听来电')
|
||||
await TUICallKitAPI.accept()
|
||||
await TUICallKitServer.accept()
|
||||
ElMessage.success('已接听通话')
|
||||
hasIncomingCall.value = false
|
||||
callConnected.value = true // 设置通话连接状态
|
||||
} catch (error: any) {
|
||||
console.error('接听失败:', error)
|
||||
ElMessage.error(error.message || '接听失败')
|
||||
@@ -229,7 +307,7 @@ const acceptCall = async () => {
|
||||
const rejectCall = async () => {
|
||||
try {
|
||||
console.log('拒绝来电')
|
||||
await TUICallKitAPI.reject()
|
||||
await TUICallKitServer.reject()
|
||||
ElMessage.info('已拒绝通话')
|
||||
hasIncomingCall.value = false
|
||||
incomingCallInfo.value = null
|
||||
@@ -243,14 +321,20 @@ const reset = () => {
|
||||
initialized.value = false
|
||||
currentUserId.value = ''
|
||||
hasIncomingCall.value = false
|
||||
callConnected.value = false
|
||||
incomingCallInfo.value = null
|
||||
}
|
||||
|
||||
// 组件卸载时清理
|
||||
onUnmounted(() => {
|
||||
if (statusCheckTimer.value) {
|
||||
clearInterval(statusCheckTimer.value)
|
||||
}
|
||||
|
||||
if (initialized.value) {
|
||||
// 清理资源
|
||||
hasIncomingCall.value = false
|
||||
callConnected.value = false
|
||||
incomingCallInfo.value = null
|
||||
}
|
||||
})
|
||||
@@ -287,6 +371,25 @@ onUnmounted(() => {
|
||||
}
|
||||
|
||||
.call-container {
|
||||
width: 100%;
|
||||
height: 500px;
|
||||
margin-top: 20px;
|
||||
background: #f5f5f5;
|
||||
border-radius: 8px;
|
||||
display: flex;
|
||||
align-items: stretch;
|
||||
justify-content: stretch;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.call-container > * {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.waiting-container {
|
||||
width: 100%;
|
||||
min-height: 500px;
|
||||
margin-top: 20px;
|
||||
@@ -295,7 +398,6 @@ onUnmounted(() => {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/* 确保 TUICallKit 组件正确显示 */
|
||||
@@ -312,6 +414,50 @@ onUnmounted(() => {
|
||||
}
|
||||
}
|
||||
|
||||
/* 强制 TUICallKit 组件撑满容器 */
|
||||
:deep(.TUICallKit) {
|
||||
width: 100% !important;
|
||||
height: 100% !important;
|
||||
position: relative !important;
|
||||
}
|
||||
|
||||
:deep(.tui-call-kit) {
|
||||
width: 100% !important;
|
||||
height: 100% !important;
|
||||
}
|
||||
|
||||
:deep(.tui-call-kit-mini) {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
/* 隐藏 TUICallKit 的默认最小化窗口 */
|
||||
:deep(.tui-call-kit-window) {
|
||||
width: 100% !important;
|
||||
height: 100% !important;
|
||||
min-height: 500px !important;
|
||||
}
|
||||
|
||||
/* 确保视频容器撑满 */
|
||||
:deep(.tui-video-container) {
|
||||
width: 100% !important;
|
||||
height: 100% !important;
|
||||
}
|
||||
|
||||
:deep(.tui-call-kit-video) {
|
||||
width: 100% !important;
|
||||
height: 100% !important;
|
||||
}
|
||||
|
||||
/* 隐藏所有可能的最小化或浮窗样式 */
|
||||
:deep([class*="mini"]) {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
:deep([class*="float"]) {
|
||||
width: 100% !important;
|
||||
height: 100% !important;
|
||||
}
|
||||
|
||||
.mb-4 {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
@@ -361,4 +507,26 @@ onUnmounted(() => {
|
||||
:deep(.el-alert__description li) {
|
||||
margin: 4px 0;
|
||||
}
|
||||
|
||||
.debug-info {
|
||||
font-size: 14px;
|
||||
line-height: 1.8;
|
||||
}
|
||||
|
||||
.debug-info code {
|
||||
background: #f5f5f5;
|
||||
padding: 2px 6px;
|
||||
border-radius: 3px;
|
||||
color: #e6a23c;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.debug-info ul {
|
||||
margin: 8px 0;
|
||||
padding-left: 20px;
|
||||
}
|
||||
|
||||
.debug-info li {
|
||||
margin: 4px 0;
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user