|
@@ -1,28 +1,128 @@
|
|
|
<template>
|
|
|
- <div v-if="rtcStore.callStatus === 'incoming'" class="call-box">
|
|
|
- <div>{{ rtcStore.imSate.callName }} 呼叫你</div>
|
|
|
- <button @click="accept">接听</button>
|
|
|
- <button @click="reject">拒接</button>
|
|
|
- </div>
|
|
|
-
|
|
|
- <div v-if="rtcStore.callStatus === 'dialing'">
|
|
|
- 正在呼叫 {{ rtcStore.callTarget?.name || '对方' }}...
|
|
|
- <button @click="cancel">取消</button>
|
|
|
- </div>
|
|
|
+ <div v-if="visible" class="weixin-call-modal">
|
|
|
+ <div class="caller-info">
|
|
|
+ <img class="avatar" :src="callAvatar || defaultAvatar" alt="头像" />
|
|
|
+ <div class="name">{{ callName || '未知用户' }}</div>
|
|
|
+ <div class="status">{{ statusText }}</div>
|
|
|
+ </div>
|
|
|
+ <div class="btn-group">
|
|
|
+ <!-- 来电状态显示接听/拒绝按钮 -->
|
|
|
+ <template v-if="!inCall">
|
|
|
+ <button class="btn reject" @click="$emit('reject')">拒绝</button>
|
|
|
+ <button class="btn accept" @click="$emit('accept')">接听</button>
|
|
|
+ </template>
|
|
|
|
|
|
- <div v-if="rtcStore.callStatus === 'in-call'">
|
|
|
- 通话中...
|
|
|
- <button @click="hangup">挂断</button>
|
|
|
+ <!-- 通话中状态显示挂断按钮 -->
|
|
|
+ <template v-else>
|
|
|
+ <button class="btn hangup" @click="$emit('hangup')">挂断</button>
|
|
|
+ </template>
|
|
|
+ </div>
|
|
|
</div>
|
|
|
</template>
|
|
|
|
|
|
<script setup>
|
|
|
- import { useWebRTCStore } from "@/stores/modules/webrtcStore";
|
|
|
- const rtcStore = useWebRTCStore();
|
|
|
+ import { defineProps, computed } from "vue";
|
|
|
+
|
|
|
+ const props = defineProps({
|
|
|
+ visible: Boolean, // 是否显示弹窗
|
|
|
+ inCall: Boolean, // 是否通话中
|
|
|
+ callName: String, // 来电人姓名
|
|
|
+ callAvatar: String, // 来电人头像
|
|
|
+ });
|
|
|
+
|
|
|
+ const defaultAvatar = "https://example.com/default-avatar.png";
|
|
|
|
|
|
- const accept = () => rtcStore.acceptCall(false);
|
|
|
- const reject = () => rtcStore.rejectCall(false);
|
|
|
- const cancel = () => rtcStore.cancelCall(false);
|
|
|
- const hangup = () => rtcStore.hangup();
|
|
|
+ const statusText = computed(() => {
|
|
|
+ if (!props.inCall) {
|
|
|
+ return "正在语音通话请求...";
|
|
|
+ } else {
|
|
|
+ return "通话中...";
|
|
|
+ }
|
|
|
+ });
|
|
|
</script>
|
|
|
+
|
|
|
+ <style scoped>
|
|
|
+ .weixin-call-modal {
|
|
|
+ position: fixed;
|
|
|
+ inset: 0;
|
|
|
+ background-color: rgba(0, 0, 0, 0.85);
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+ z-index: 9999;
|
|
|
+ color: white;
|
|
|
+ }
|
|
|
+
|
|
|
+ .caller-info {
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ align-items: center;
|
|
|
+ margin-bottom: 80px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .avatar {
|
|
|
+ width: 80px;
|
|
|
+ height: 80px;
|
|
|
+ border-radius: 50%;
|
|
|
+ margin-bottom: 16px;
|
|
|
+ border: 2px solid rgba(255, 255, 255, 0.2);
|
|
|
+ }
|
|
|
+
|
|
|
+ .name {
|
|
|
+ font-size: 20px;
|
|
|
+ font-weight: bold;
|
|
|
+ margin-bottom: 8px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .status {
|
|
|
+ font-size: 14px;
|
|
|
+ color: #ccc;
|
|
|
+ }
|
|
|
+
|
|
|
+ .btn-group {
|
|
|
+ display: flex;
|
|
|
+ gap: 60px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .btn {
|
|
|
+ width: 64px;
|
|
|
+ height: 64px;
|
|
|
+ border-radius: 50%;
|
|
|
+ border: none;
|
|
|
+ font-size: 14px;
|
|
|
+ color: white;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+ cursor: pointer;
|
|
|
+ user-select: none;
|
|
|
+ outline: none;
|
|
|
+ transition: background-color 0.3s ease;
|
|
|
+ }
|
|
|
+
|
|
|
+ .btn.accept {
|
|
|
+ background-color: #4cd964; /* 绿色接听 */
|
|
|
+ }
|
|
|
+
|
|
|
+ .btn.accept:hover {
|
|
|
+ background-color: #40c150;
|
|
|
+ }
|
|
|
+
|
|
|
+ .btn.reject {
|
|
|
+ background-color: #ff3b30; /* 红色拒绝 */
|
|
|
+ }
|
|
|
+
|
|
|
+ .btn.reject:hover {
|
|
|
+ background-color: #e02d22;
|
|
|
+ }
|
|
|
+
|
|
|
+ .btn.hangup {
|
|
|
+ background-color: #ff3b30;
|
|
|
+ }
|
|
|
+
|
|
|
+ .btn.hangup:hover {
|
|
|
+ background-color: #e02d22;
|
|
|
+ }
|
|
|
+ </style>
|
|
|
|