|
@@ -8,6 +8,7 @@ import user from '~/store/user';
|
|
|
import { createSocket, socketSend } from '~/utils/ws';
|
|
|
import type { TSocketRes } from '~/utils/ws';
|
|
|
import { formatTimestamp } from '~/utils/time';
|
|
|
+import { CHAT_STATUS, CHAT_OPERATION } from '~/types';
|
|
|
let dyaw_xlfw_zxhd = $ref<type_dyaw_xlfw_zxhd | undefined>()
|
|
|
let dyaw_xlfw_zxhd_list = $ref<type_dyaw_xlfw_zxhd[] | undefined>()
|
|
|
|
|
@@ -215,18 +216,10 @@ function handleQueryArchives() {
|
|
|
}
|
|
|
|
|
|
// ==========
|
|
|
-// chat audit/video
|
|
|
+// chat audio/video
|
|
|
// ==========
|
|
|
-let rtcInstance: {
|
|
|
- client?: IAgoraRTCClient;
|
|
|
- localAudioTrack?: IMicrophoneAudioTrack;
|
|
|
- localVideoTrack?: ICameraVideoTrack
|
|
|
-} = {
|
|
|
- client: undefined,
|
|
|
- localAudioTrack: undefined,
|
|
|
- localVideoTrack: undefined,
|
|
|
-}
|
|
|
|
|
|
+let RtcDialogRef = $ref<typeof import("~/components/rtc-dialog/index.vue")['default']>()
|
|
|
|
|
|
const ws2 = createSocket(
|
|
|
{ teacher: user.user_id, student: '*' },
|
|
@@ -234,180 +227,28 @@ const ws2 = createSocket(
|
|
|
message(socketRes: TSocketRes<type_dyaw_xlfw_zxhd_log & { operate: CHAT_OPERATION }>) {
|
|
|
if (socketRes.from_client_name.endsWith('student')) {
|
|
|
// infoList.push(socketRes.content)
|
|
|
- console.log('');
|
|
|
if (socketRes.content.dxzl_tea_user_id === user.user_id) {
|
|
|
console.log('operate:', socketRes.content.operate);
|
|
|
- switch (socketRes.content.operate) {
|
|
|
- case CHAT_OPERATION.START:
|
|
|
- auditChatStatus = CHAT_STATUS.WAITING_YOU_ACCEPT
|
|
|
- ChatAudioRef!.open()
|
|
|
- break;
|
|
|
- case CHAT_OPERATION.CANCEL:
|
|
|
- ChatAudioRef!.close()
|
|
|
- break;
|
|
|
- case CHAT_OPERATION.ACCEPT:
|
|
|
- auditChatStatus = CHAT_STATUS.CHATING
|
|
|
- break;
|
|
|
- case CHAT_OPERATION.DENY:
|
|
|
- ChatAudioRef!.close()
|
|
|
- break;
|
|
|
- case CHAT_OPERATION.END:
|
|
|
- ChatAudioRef!.close()
|
|
|
- break;
|
|
|
- default:
|
|
|
- break;
|
|
|
- }
|
|
|
+ RtcDialogRef!.publisher(ws2, socketRes.content.operate)
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
)
|
|
|
|
|
|
-enum CHAT_STATUS { 'WAITING_YOU_ACCEPT', 'WAITING_OTHERS_ACCEPT', 'WAITING_BUSY', 'CHATING' }
|
|
|
-enum CHAT_OPERATION { 'START', 'CANCEL', 'ACCEPT', 'DENY', 'END' }
|
|
|
-let auditChatStatus = $ref<CHAT_STATUS>(CHAT_STATUS.WAITING_OTHERS_ACCEPT)
|
|
|
|
|
|
-const ChatAudioRef = $ref<typeof import("~/components/chat-dialog/index.vue")['default']>()
|
|
|
-const ChatVideoRef = $ref<typeof import("~/components/chat-dialog/index.vue")['default']>()
|
|
|
-
|
|
|
-
|
|
|
-async function handleAuditChatStart() {
|
|
|
- try {
|
|
|
- let rtcOptions
|
|
|
- await request({
|
|
|
- url: '/dyaw/xlfw_zxhd/get_rtc_token',
|
|
|
- data: {
|
|
|
- dxz_id: dyaw_xlfw_zxhd?.dxz_id
|
|
|
- }
|
|
|
- }).then(async res => {
|
|
|
- if (res.code === '1') {
|
|
|
- let resp: { jgim_roomid: string; rtc_appid: string; rtc_token: string } = res.data.one_info
|
|
|
- rtcOptions = {
|
|
|
- appId: resp.rtc_appid,
|
|
|
- channel: resp.jgim_roomid,
|
|
|
- token: resp.rtc_token,
|
|
|
- uid: user.user_id
|
|
|
- }
|
|
|
|
|
|
- let client = rtcInstance.client = AgoraRTC.createClient({ mode: "rtc", codec: "vp8" });
|
|
|
-
|
|
|
- client.on("user-published", async (user, mediaType) => {
|
|
|
- // 发起订阅
|
|
|
- await client.subscribe(user, mediaType);
|
|
|
-
|
|
|
- // 如果订阅的是音频轨道
|
|
|
- if (mediaType === "audio") {
|
|
|
- const audioTrack = user.audioTrack;
|
|
|
- // 自动播放音频
|
|
|
- audioTrack?.play();
|
|
|
- } else {
|
|
|
- const videoTrack = user.videoTrack;
|
|
|
- // 自动播放视频
|
|
|
- videoTrack?.play(RemotePlayerContainerRef as HTMLElement);
|
|
|
- }
|
|
|
- });
|
|
|
+async function handleAudioChatStart() {
|
|
|
+ RtcDialogRef!.open(dyaw_xlfw_zxhd,'audio')
|
|
|
+}
|
|
|
|
|
|
- await rtcInstance.client.join(rtcOptions.appId, rtcOptions.channel, rtcOptions?.token, rtcOptions.uid);
|
|
|
- rtcInstance.localAudioTrack = await AgoraRTC.createMicrophoneAudioTrack();
|
|
|
- // rtcInstance.localVideoTrack = await AgoraRTC.createCameraVideoTrack();
|
|
|
- await rtcInstance.client.publish([rtcInstance.localAudioTrack]);
|
|
|
- // rtcInstance.localVideoTrack.play(LocalPlayerContainerRef as HTMLElement);
|
|
|
- }
|
|
|
- })
|
|
|
- ChatAudioRef!.open()
|
|
|
- socketSend(ws2, {
|
|
|
- dxzl_stu_user_id: dyaw_xlfw_zxhd!.dxz_stu_user_id,
|
|
|
- dxzl_tea_user_id: dyaw_xlfw_zxhd!.dxz_tea_user_id,
|
|
|
- operate: CHAT_OPERATION.START,
|
|
|
- rtcOptions
|
|
|
- })
|
|
|
- } catch (error) {
|
|
|
- console.error(error);
|
|
|
- }
|
|
|
|
|
|
-}
|
|
|
-function handleAuditChatCancel() {
|
|
|
- socketSend(ws2, {
|
|
|
- dxzl_stu_user_id: dyaw_xlfw_zxhd!.dxz_stu_user_id,
|
|
|
- dxzl_tea_user_id: dyaw_xlfw_zxhd!.dxz_tea_user_id,
|
|
|
- operate: CHAT_OPERATION.CANCEL
|
|
|
- })
|
|
|
- ChatAudioRef!.close()
|
|
|
-}
|
|
|
-function handleAuditChatAccept() {
|
|
|
- socketSend(ws2, {
|
|
|
- dxzl_stu_user_id: dyaw_xlfw_zxhd!.dxz_stu_user_id,
|
|
|
- dxzl_tea_user_id: dyaw_xlfw_zxhd!.dxz_tea_user_id,
|
|
|
- operate: CHAT_OPERATION.ACCEPT
|
|
|
- })
|
|
|
- // ChatAudioRef!.close()
|
|
|
- auditChatStatus = CHAT_STATUS.CHATING
|
|
|
-}
|
|
|
-function handleAuditChatDeny() {
|
|
|
- socketSend(ws2, {
|
|
|
- dxzl_stu_user_id: dyaw_xlfw_zxhd!.dxz_stu_user_id,
|
|
|
- dxzl_tea_user_id: dyaw_xlfw_zxhd!.dxz_tea_user_id,
|
|
|
- operate: CHAT_OPERATION.DENY
|
|
|
- })
|
|
|
- ChatAudioRef!.close()
|
|
|
-}
|
|
|
-function handleAuditChatEnd() {
|
|
|
- socketSend(ws2, {
|
|
|
- dxzl_stu_user_id: dyaw_xlfw_zxhd!.dxz_stu_user_id,
|
|
|
- dxzl_tea_user_id: dyaw_xlfw_zxhd!.dxz_tea_user_id,
|
|
|
- operate: CHAT_OPERATION.END
|
|
|
- })
|
|
|
- ChatAudioRef!.close()
|
|
|
-}
|
|
|
|
|
|
|
|
|
-const LocalPlayerContainerRef = $ref<HTMLElement>()
|
|
|
-const RemotePlayerContainerRef = $ref<HTMLElement>()
|
|
|
async function handleVideoChatStart() {
|
|
|
- await request({
|
|
|
- url: '/dyaw/xlfw_zxhd/get_rtc_token',
|
|
|
- data: {
|
|
|
- dxz_id: dyaw_xlfw_zxhd?.dxz_id
|
|
|
- }
|
|
|
- }).then(async res => {
|
|
|
- if (res.code === '1') {
|
|
|
- let resp: { jgim_roomid: string; rtc_appid: string; rtc_token: string } = res.data.one_info
|
|
|
- const rtcOptions = {
|
|
|
- appId: resp.rtc_appid,
|
|
|
- channel: resp.jgim_roomid,
|
|
|
- token: resp.rtc_token,
|
|
|
- uid: user.user_id
|
|
|
- }
|
|
|
-
|
|
|
- let client = rtcInstance.client = AgoraRTC.createClient({ mode: "rtc", codec: "vp8" });
|
|
|
-
|
|
|
- client.on("user-published", async (user, mediaType) => {
|
|
|
- // 发起订阅
|
|
|
- await client.subscribe(user, mediaType);
|
|
|
-
|
|
|
- // 如果订阅的是音频轨道
|
|
|
- if (mediaType === "audio") {
|
|
|
- const audioTrack = user.audioTrack;
|
|
|
- // 自动播放音频
|
|
|
- audioTrack?.play();
|
|
|
- } else {
|
|
|
- const videoTrack = user.videoTrack;
|
|
|
- // 自动播放视频
|
|
|
- videoTrack?.play(RemotePlayerContainerRef as HTMLElement);
|
|
|
- }
|
|
|
- });
|
|
|
|
|
|
- await rtcInstance.client.join(rtcOptions.appId, rtcOptions.channel, rtcOptions?.token, rtcOptions.uid);
|
|
|
- rtcInstance.localAudioTrack = await AgoraRTC.createMicrophoneAudioTrack();
|
|
|
- rtcInstance.localVideoTrack = await AgoraRTC.createCameraVideoTrack();
|
|
|
- await rtcInstance.client.publish([rtcInstance.localAudioTrack, rtcInstance.localVideoTrack]);
|
|
|
- rtcInstance.localVideoTrack.play(LocalPlayerContainerRef as HTMLElement);
|
|
|
- }
|
|
|
- })
|
|
|
- ChatVideoRef!.open()
|
|
|
}
|
|
|
|
|
|
-let RtcDialogRef = $ref<typeof import("~/components/rtc-dialog/index.vue")['default']>()
|
|
|
</script>
|
|
|
|
|
|
<template>
|
|
@@ -435,7 +276,7 @@ let RtcDialogRef = $ref<typeof import("~/components/rtc-dialog/index.vue")['defa
|
|
|
:d="item"></info-item>
|
|
|
</div>
|
|
|
<div class="bg-white h-180px p-5px flex flex-col justify-between">
|
|
|
- <tinymce-area v-model="inputValue" ref="TinyRef" @click:audit="handleAuditChatStart"
|
|
|
+ <tinymce-area v-model="inputValue" ref="TinyRef" @click:audio="handleAudioChatStart"
|
|
|
@click:video="handleVideoChatStart"></tinymce-area>
|
|
|
<div class="flex justify-end">
|
|
|
<div class="bg-pink-300 text-sm text-white w-80px h-32px flex_center rounded-2xl cursor-pointer"
|
|
@@ -472,70 +313,7 @@ let RtcDialogRef = $ref<typeof import("~/components/rtc-dialog/index.vue")['defa
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
- <chat-dialog ref="ChatAudioRef">
|
|
|
- <div class="h-full flex_center flex-col text-light-50 space-y-4">
|
|
|
- <el-avatar :size="158" :src="dyaw_xlfw_zxhd?.dxx_user_avatar"></el-avatar>
|
|
|
- <div>{{ dyaw_xlfw_zxhd?.dxz_stu_user_realname }}</div>
|
|
|
- <!-- <div class="text-hex-909090 flex_center flex-col space-y-2 h-16"> -->
|
|
|
- <div class="text-hex-909090 flex_center flex-col space-y-2 h-16"
|
|
|
- v-show="auditChatStatus === CHAT_STATUS.WAITING_OTHERS_ACCEPT">
|
|
|
- <div>正在等待对方接受邀请</div>
|
|
|
- <i:line-md:loading-alt-loop class="text-xl" />
|
|
|
- </div>
|
|
|
- <div class="text-hex-909090 flex_center flex-col space-y-2 h-16"
|
|
|
- v-show="auditChatStatus === CHAT_STATUS.WAITING_YOU_ACCEPT">
|
|
|
- <div>邀请你语音通话...</div>
|
|
|
- </div>
|
|
|
- <div class="text-hex-909090 flex_center flex-col space-y-2 h-16"
|
|
|
- v-show="auditChatStatus === CHAT_STATUS.WAITING_BUSY">
|
|
|
- <div class="text-red-500">对方忙线中请等待</div>
|
|
|
- <div class="text-red-500">当前排队:{{ 4 }}</div>
|
|
|
- <i:line-md:loading-alt-loop class="text-xl" />
|
|
|
- </div>
|
|
|
- <div class="text-hex-909090 flex_center flex-col space-y-2 h-16" v-show="auditChatStatus === CHAT_STATUS.CHATING">
|
|
|
- <div>正在通话中</div>
|
|
|
- <div>{{ '00:30' }}</div>
|
|
|
- </div>
|
|
|
- <!-- </div> -->
|
|
|
-
|
|
|
- <div class="pt-16 text-xl flex justify-around w-full">
|
|
|
- <div v-show="auditChatStatus === CHAT_STATUS.WAITING_YOU_ACCEPT"
|
|
|
- class="bg-green-600 w-12 h-12 rounded-1 cursor-pointer flex items-center justify-around"
|
|
|
- @click="handleAuditChatAccept">
|
|
|
- <i:ic:baseline-phone />
|
|
|
- </div>
|
|
|
- <div v-show="auditChatStatus === CHAT_STATUS.WAITING_YOU_ACCEPT"
|
|
|
- class="bg-red-600 w-12 h-12 rounded-1 cursor-pointer flex items-center justify-around"
|
|
|
- @click="handleAuditChatDeny">
|
|
|
- <i:mdi:phone-hangup />
|
|
|
- </div>
|
|
|
- <div v-show="auditChatStatus === CHAT_STATUS.CHATING"
|
|
|
- class="bg-hex-efefef text-hex-272636 w-12 h-12 rounded-1 cursor-pointer flex items-center justify-around"
|
|
|
- @click="">
|
|
|
- <i:ant-design:audio-outlined v-show="true" />
|
|
|
- <i:ant-design:audio-muted-outlined v-show="false" />
|
|
|
- </div>
|
|
|
- <div v-show="auditChatStatus === CHAT_STATUS.CHATING"
|
|
|
- class="bg-red-600 w-12 h-12 rounded-1 cursor-pointer flex items-center justify-around"
|
|
|
- @click="handleAuditChatEnd">
|
|
|
- <i:ic:outline-close></i:ic:outline-close>
|
|
|
- </div>
|
|
|
- <div
|
|
|
- v-show="auditChatStatus === CHAT_STATUS.WAITING_OTHERS_ACCEPT || auditChatStatus === CHAT_STATUS.WAITING_BUSY"
|
|
|
- class="bg-red-600 w-12 h-12 rounded-1 cursor-pointer flex items-center justify-around"
|
|
|
- @click="handleAuditChatCancel">
|
|
|
- <i:ic:outline-close></i:ic:outline-close>
|
|
|
- </div>
|
|
|
-
|
|
|
- </div>
|
|
|
- </div>
|
|
|
-
|
|
|
- </chat-dialog>
|
|
|
|
|
|
- <chat-dialog>
|
|
|
- <div ref="LocalPlayerContainerRef"></div>
|
|
|
- <div ref="RemotePlayerContainerRef"></div>
|
|
|
- </chat-dialog>
|
|
|
|
|
|
<rtc-dialog ref="RtcDialogRef"></rtc-dialog>
|
|
|
|