新增功能
This commit is contained in:
@@ -0,0 +1,350 @@
|
||||
<template>
|
||||
<div class="patient-test">
|
||||
<el-card>
|
||||
<template #header>
|
||||
<div class="card-header">
|
||||
<span>患者端测试 - 接听来电</span>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<el-alert
|
||||
type="info"
|
||||
:closable="false"
|
||||
class="mb-4"
|
||||
>
|
||||
<p>此页面用于测试音视频通话功能</p>
|
||||
<p>使用方法:</p>
|
||||
<ol>
|
||||
<li>在此页面初始化患者端</li>
|
||||
<li>在另一个浏览器窗口登录医生端</li>
|
||||
<li>医生端发起通话</li>
|
||||
<li>此页面会收到来电提示</li>
|
||||
</ol>
|
||||
</el-alert>
|
||||
|
||||
<el-form :model="form" label-width="100px" v-if="!initialized">
|
||||
<el-form-item label="患者ID">
|
||||
<el-input
|
||||
v-model="form.patientId"
|
||||
placeholder="输入患者ID,如:1"
|
||||
style="width: 300px;"
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item>
|
||||
<el-button
|
||||
type="primary"
|
||||
@click="initPatient"
|
||||
:loading="loading"
|
||||
>
|
||||
初始化患者端
|
||||
</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<div v-if="initialized" class="status">
|
||||
<el-alert
|
||||
:type="hasIncomingCall ? 'warning' : 'success'"
|
||||
:closable="false"
|
||||
>
|
||||
<template #title>
|
||||
<div class="flex items-center">
|
||||
<el-icon class="mr-2" :class="{ 'animate-pulse': hasIncomingCall }">
|
||||
<Phone />
|
||||
</el-icon>
|
||||
<span>{{ hasIncomingCall ? '收到来电!' : '患者端已初始化,等待来电...' }}</span>
|
||||
</div>
|
||||
</template>
|
||||
<div class="mt-2">
|
||||
<p><strong>患者ID:</strong> {{ currentUserId }}</p>
|
||||
<p><strong>状态:</strong> {{ hasIncomingCall ? '来电中' : '在线' }}</p>
|
||||
<p v-if="hasIncomingCall && incomingCallInfo">
|
||||
<strong>通话类型:</strong> 视频通话
|
||||
</p>
|
||||
</div>
|
||||
</el-alert>
|
||||
|
||||
<!-- 来电操作按钮 -->
|
||||
<div v-if="hasIncomingCall" class="call-actions mt-4">
|
||||
<el-button
|
||||
type="success"
|
||||
size="large"
|
||||
@click="acceptCall"
|
||||
:icon="Phone"
|
||||
>
|
||||
接听
|
||||
</el-button>
|
||||
<el-button
|
||||
type="danger"
|
||||
size="large"
|
||||
@click="rejectCall"
|
||||
>
|
||||
拒绝
|
||||
</el-button>
|
||||
</div>
|
||||
|
||||
<el-button
|
||||
v-else
|
||||
type="danger"
|
||||
@click="reset"
|
||||
class="mt-4"
|
||||
>
|
||||
重置
|
||||
</el-button>
|
||||
</div>
|
||||
|
||||
<div id="call-container" class="call-container">
|
||||
<TUICallKit v-if="initialized" />
|
||||
</div>
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, onUnmounted } from 'vue'
|
||||
import { Phone } from '@element-plus/icons-vue'
|
||||
import { TUICallKitAPI, TUICallKit, STATUS } from '@trtc/calls-uikit-vue'
|
||||
import { ElMessage, ElNotification } from 'element-plus'
|
||||
import request from '@/utils/request'
|
||||
|
||||
const form = ref({
|
||||
patientId: '1'
|
||||
})
|
||||
|
||||
const loading = ref(false)
|
||||
const initialized = ref(false)
|
||||
const currentUserId = ref('')
|
||||
const hasIncomingCall = ref(false)
|
||||
const incomingCallInfo = ref<any>(null)
|
||||
|
||||
// 监听状态变化
|
||||
const handleStatusChange = ({ oldStatus, newStatus }: any) => {
|
||||
console.log('通话状态变化:', { oldStatus, newStatus })
|
||||
|
||||
// 收到来电邀请
|
||||
if (newStatus === STATUS.BE_INVITED) {
|
||||
hasIncomingCall.value = true
|
||||
incomingCallInfo.value = { oldStatus, newStatus }
|
||||
|
||||
// 显示来电通知
|
||||
ElNotification({
|
||||
title: '来电提醒',
|
||||
message: '收到视频通话请求',
|
||||
type: 'info',
|
||||
duration: 0, // 不自动关闭
|
||||
position: 'top-right'
|
||||
})
|
||||
|
||||
ElMessage.success('收到来电,请点击接听按钮')
|
||||
}
|
||||
|
||||
// 通话结束,回到空闲状态
|
||||
if (newStatus === STATUS.IDLE && hasIncomingCall.value) {
|
||||
hasIncomingCall.value = false
|
||||
incomingCallInfo.value = null
|
||||
ElMessage.info('通话已结束')
|
||||
}
|
||||
}
|
||||
|
||||
const initPatient = async () => {
|
||||
try {
|
||||
loading.value = true
|
||||
|
||||
ElMessage.info('正在获取签名...')
|
||||
|
||||
// 获取患者签名
|
||||
const result = await request.get({
|
||||
url: '/tcm.diagnosis/getPatientSignature',
|
||||
params: {
|
||||
patient_id: form.value.patientId
|
||||
}
|
||||
})
|
||||
|
||||
if (!result) {
|
||||
throw new Error('获取签名失败')
|
||||
}
|
||||
|
||||
const { sdkAppId, userId, userSig } = result
|
||||
currentUserId.value = userId
|
||||
|
||||
console.log('患者签名获取成功:', { userId, sdkAppId, userSigLength: userSig.length })
|
||||
ElMessage.info('正在初始化通话组件...')
|
||||
|
||||
// 设置状态变化回调
|
||||
TUICallKitAPI.setCallback({
|
||||
statusChanged: handleStatusChange
|
||||
})
|
||||
|
||||
// 初始化(注意:SDKAppID必须是数字类型)
|
||||
await TUICallKitAPI.init({
|
||||
userID: userId,
|
||||
userSig: userSig,
|
||||
SDKAppID: Number(sdkAppId) // 转换为数字类型
|
||||
})
|
||||
|
||||
console.log('TUICallKitAPI.init 完成')
|
||||
console.log('已注册状态监听回调')
|
||||
ElMessage.info('等待初始化完成...')
|
||||
|
||||
// 等待初始化完成
|
||||
await new Promise(resolve => setTimeout(resolve, 2000))
|
||||
|
||||
initialized.value = true
|
||||
ElMessage.success('患者端初始化成功,等待来电...')
|
||||
|
||||
console.log('患者端初始化完成,userId:', userId)
|
||||
|
||||
} catch (error: any) {
|
||||
console.error('初始化失败:', error)
|
||||
ElMessage.error(error.message || '初始化失败')
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
// 接听来电
|
||||
const acceptCall = async () => {
|
||||
try {
|
||||
console.log('接听来电')
|
||||
await TUICallKitAPI.accept()
|
||||
ElMessage.success('已接听通话')
|
||||
hasIncomingCall.value = false
|
||||
} catch (error: any) {
|
||||
console.error('接听失败:', error)
|
||||
ElMessage.error(error.message || '接听失败')
|
||||
}
|
||||
}
|
||||
|
||||
// 拒绝来电
|
||||
const rejectCall = async () => {
|
||||
try {
|
||||
console.log('拒绝来电')
|
||||
await TUICallKitAPI.reject()
|
||||
ElMessage.info('已拒绝通话')
|
||||
hasIncomingCall.value = false
|
||||
incomingCallInfo.value = null
|
||||
} catch (error: any) {
|
||||
console.error('拒绝失败:', error)
|
||||
ElMessage.error(error.message || '拒绝失败')
|
||||
}
|
||||
}
|
||||
|
||||
const reset = () => {
|
||||
initialized.value = false
|
||||
currentUserId.value = ''
|
||||
hasIncomingCall.value = false
|
||||
incomingCallInfo.value = null
|
||||
form.value.patientId = '1'
|
||||
}
|
||||
|
||||
// 组件卸载时清理
|
||||
onUnmounted(() => {
|
||||
if (initialized.value) {
|
||||
// 清理资源
|
||||
hasIncomingCall.value = false
|
||||
incomingCallInfo.value = null
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.patient-test {
|
||||
padding: 20px;
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.card-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
font-size: 18px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.status {
|
||||
margin: 20px 0;
|
||||
}
|
||||
|
||||
.call-actions {
|
||||
display: flex;
|
||||
gap: 16px;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.call-container {
|
||||
width: 100%;
|
||||
min-height: 500px;
|
||||
margin-top: 20px;
|
||||
background: #f5f5f5;
|
||||
border-radius: 8px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/* 确保 TUICallKit 组件正确显示 */
|
||||
:deep(.call-container) {
|
||||
.tui-call-kit {
|
||||
width: 100%;
|
||||
height: 500px;
|
||||
}
|
||||
|
||||
video {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
}
|
||||
}
|
||||
|
||||
.mb-4 {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.mt-2 {
|
||||
margin-top: 8px;
|
||||
}
|
||||
|
||||
.mt-4 {
|
||||
margin-top: 16px;
|
||||
}
|
||||
|
||||
.mr-2 {
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
.flex {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.items-center {
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.animate-pulse {
|
||||
animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
|
||||
}
|
||||
|
||||
@keyframes pulse {
|
||||
0%, 100% {
|
||||
opacity: 1;
|
||||
}
|
||||
50% {
|
||||
opacity: 0.5;
|
||||
}
|
||||
}
|
||||
|
||||
:deep(.el-alert__description) {
|
||||
margin-top: 8px;
|
||||
}
|
||||
|
||||
:deep(.el-alert__description ol) {
|
||||
margin: 8px 0;
|
||||
padding-left: 20px;
|
||||
}
|
||||
|
||||
:deep(.el-alert__description li) {
|
||||
margin: 4px 0;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user