新增功能

This commit is contained in:
Your Name
2026-03-04 15:32:30 +08:00
parent a07e844c47
commit ab77f5488d
2266 changed files with 177942 additions and 3444 deletions
+350
View File
@@ -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>