lex-xin vor 3 Jahren
Ursprung
Commit
89ed5447ba

Datei-Diff unterdrückt, da er zu groß ist
+ 0 - 0
dist/assets/index-legacy.1951fda0.js


Datei-Diff unterdrückt, da er zu groß ist
+ 0 - 0
dist/assets/index-legacy.466333ca.js


Datei-Diff unterdrückt, da er zu groß ist
+ 0 - 0
dist/assets/index-legacy.5844f888.js


Datei-Diff unterdrückt, da er zu groß ist
+ 0 - 0
dist/assets/index.1880f592.js


Datei-Diff unterdrückt, da er zu groß ist
+ 0 - 0
dist/assets/index.6c06920a.js


Datei-Diff unterdrückt, da er zu groß ist
+ 0 - 0
dist/assets/index.a9e5652f.js


Datei-Diff unterdrückt, da er zu groß ist
+ 0 - 0
dist/assets/index.b94cb86f.css


Datei-Diff unterdrückt, da er zu groß ist
+ 0 - 0
dist/assets/index.fe1ff7f3.js


+ 2 - 2
dist/index.html

@@ -6,7 +6,7 @@
     <meta name="viewport" content="width=device-width, initial-scale=1.0" />
     <title>管乐迷</title>
     
-    <script type="module" crossorigin src="./assets/index.9cdbdc0c.js"></script>
+    <script type="module" crossorigin src="./assets/index.6c06920a.js"></script>
     <link rel="modulepreload" href="./assets/vendor.fef4890b.js">
     <link rel="stylesheet" href="./assets/index.cd9189f2.css">
     <script type="module">!function(){try{new Function("m","return import(m)")}catch(o){console.warn("vite: loading legacy build because dynamic import is unsupported, syntax error above should be ignored");var e=document.getElementById("vite-legacy-polyfill"),n=document.createElement("script");n.src=e.src,n.onload=function(){System.import(document.getElementById('vite-legacy-entry').getAttribute('data-src'))},document.body.appendChild(n)}}();</script>
@@ -131,6 +131,6 @@
     </script>
     <script nomodule>!function(){var e=document,t=e.createElement("script");if(!("noModule"in t)&&"onbeforeload"in t){var n=!1;e.addEventListener("beforeload",(function(e){if(e.target===t)n=!0;else if(!e.target.hasAttribute("nomodule")||!n)return;e.preventDefault()}),!0),t.type="module",t.src=".",e.head.appendChild(t),t.remove()}}();</script>
     <script nomodule id="vite-legacy-polyfill" src="./assets/polyfills-legacy.3fc2007f.js"></script>
-    <script nomodule id="vite-legacy-entry" data-src="./assets/index-legacy.297f709c.js">System.import(document.getElementById('vite-legacy-entry').getAttribute('data-src'))</script>
+    <script nomodule id="vite-legacy-entry" data-src="./assets/index-legacy.1951fda0.js">System.import(document.getElementById('vite-legacy-entry').getAttribute('data-src'))</script>
   </body>
 </html>

+ 131 - 110
src/components/live-broadcast/index.tsx

@@ -1,186 +1,204 @@
-import { defineComponent, ref } from 'vue'
-import * as RTC from '@rongcloud/plugin-rtc'
-import Header from './header'
-import ActionBar, { state as ActionBarRuntime } from './action-bar'
-import VideoStatus from './video-status'
-import { state } from '/src/state'
-import event, { LIVE_EVENT_MESSAGE } from './event'
-import runtime, * as RuntimeUtils from './runtime'
-import Chronography from './chronography'
-import runtimeModel, * as RuntimeModelUtils from '/src/components/live-message/model/runtime'
-import { requireMedia } from './helpers'
-import styles from './index.module.less'
-import request from '/src/helpers/request'
+import { defineComponent, ref } from "vue";
+import * as RTC from "@rongcloud/plugin-rtc";
+import Header from "./header";
+import ActionBar, { state as ActionBarRuntime } from "./action-bar";
+import VideoStatus from "./video-status";
+import { state } from "/src/state";
+import event, { LIVE_EVENT_MESSAGE } from "./event";
+import runtime, * as RuntimeUtils from "./runtime";
+import Chronography from "./chronography";
+import runtimeModel, * as RuntimeModelUtils from "/src/components/live-message/model/runtime";
+import { requireMedia } from "./helpers";
+import styles from "./index.module.less";
+import request from "/src/helpers/request";
+import dayjs from "dayjs";
 
-const videoRef = ref<HTMLVideoElement | null>(null)
+const videoRef = ref<HTMLVideoElement | null>(null);
 
-let microphoneAudioTrack: RTC.RCLocalTrack
-let cameraVideoTrack: RTC.RCLocalTrack
+let microphoneAudioTrack: RTC.RCLocalTrack;
+let cameraVideoTrack: RTC.RCLocalTrack;
 
 export default defineComponent({
-  name: 'LiveBroadcast',
+  name: "LiveBroadcast",
   data() {
     return {
       headerStatus: false,
       initAudioUsers: [],
-    }
+    };
   },
   computed: {
     isLive() {
-      console.log(runtime.videoStatus)
-      if (runtime.videoStatus === 'liveing') {
+      console.log(runtime.videoStatus);
+      if (runtime.videoStatus === "liveing") {
         setTimeout(() => {
-          this.headerStatus = true
-        }, 3000)
+          this.headerStatus = true;
+        }, 3000);
       } else {
-        this.headerStatus = false
+        this.headerStatus = false;
       }
-      return runtime.videoStatus === 'liveing'
+      return runtime.videoStatus === "liveing";
     },
   },
   async mounted() {
-    this.initializeRoom()
-    RuntimeUtils.loopSyncLike()
-    event.on(LIVE_EVENT_MESSAGE['RC:Chatroom:Like'], this.onLikeMessage)
-    window.onbeforeunload = this.beforeunload
+    this.initializeRoom();
+    RuntimeUtils.loopSyncLike();
+    event.on(LIVE_EVENT_MESSAGE["RC:Chatroom:Like"], this.onLikeMessage);
+    window.onbeforeunload = this.beforeunload;
     // window.addEventListener('focus', this.visibilitychange)
     // window.addEventListener('blur', this.visibilitychange)
   },
   beforeUnmount() {
-    event.off(LIVE_EVENT_MESSAGE['RC:Chatroom:Like'], this.onLikeMessage)
-    window.onbeforeunload = null
+    event.off(LIVE_EVENT_MESSAGE["RC:Chatroom:Like"], this.onLikeMessage);
+    window.onbeforeunload = null;
     // window.removeEventListener('focus', this.visibilitychange)
     // window.removeEventListener('blur', this.visibilitychange)
   },
   methods: {
     visibilitychange(evt: FocusEvent) {
-      console.log(evt)
-      if (evt.type === 'focus') {
-        document.exitPictureInPicture()
-        document.body.click()
+      console.log(evt);
+      if (evt.type === "focus") {
+        document.exitPictureInPicture();
+        document.body.click();
       }
-      if (evt.type === 'blur') {
-        runtime.videoRef?.requestPictureInPicture()
+      if (evt.type === "blur") {
+        runtime.videoRef?.requestPictureInPicture();
       }
     },
     beforeunload() {
-      if (runtime.videoStatus === 'liveing') {
-        return '当前正在直播中是否确认关闭页面?'
+      if (runtime.videoStatus === "liveing") {
+        return "当前正在直播中是否确认关闭页面?";
       }
     },
     onLikeMessage(msg: any) {
-      runtime.likeCount += msg.counts
+      runtime.likeCount += msg.counts;
     },
     getDeviceByDeviceType(type: RuntimeUtils.TrackType) {
-      const videoDeviceId = localStorage.getItem(RuntimeUtils.VIDEO_DEVICE_ID)
-      const audioDeviceId = localStorage.getItem(RuntimeUtils.AUDIO_DEVICE_ID)
-      const audioDeviceId2 = localStorage.getItem(RuntimeUtils.AUDIO_DEVICE_ID2)
-      if (type === 'camera') {
+      const videoDeviceId = localStorage.getItem(RuntimeUtils.VIDEO_DEVICE_ID);
+      const audioDeviceId = localStorage.getItem(RuntimeUtils.AUDIO_DEVICE_ID);
+      const audioDeviceId2 = localStorage.getItem(
+        RuntimeUtils.AUDIO_DEVICE_ID2
+      );
+      if (type === "camera") {
         if (videoDeviceId) {
           return (
             runtime.cameras.find(
               (camera) => camera.deviceId === videoDeviceId
             ) || runtime.cameras[0]
-          )
+          );
         }
-        return runtime.cameras[0]
+        return runtime.cameras[0];
       }
       if (audioDeviceId) {
         return (
           runtime.microphones.find(
             (microphone) => microphone.deviceId === audioDeviceId
           ) || runtime.microphones[0]
-        )
+        );
       }
       if (audioDeviceId2) {
         return (
           runtime.microphones.find(
             (microphone) => microphone.deviceId === audioDeviceId2
           ) || runtime.microphones[0]
-        )
+        );
       }
-      return runtime.microphones[0]
+      return runtime.microphones[0];
     },
     async FetchUserDetails(userIds: string[]) {
       try {
         const res = await request.post(
-          '/api-web/imLiveBroadcastRoom/queryBaseUserInfo',
+          "/api-web/imLiveBroadcastRoom/queryBaseUserInfo",
           {
-            requestType: 'json',
+            requestType: "json",
             data: userIds,
           }
-        )
-        return res.data
+        );
+        return res.data;
       } catch (error) {}
-      return []
+      return [];
     },
     async initializeRoom() {
-      if (!state.user) throw Error('请先登录')
-      let initAudioUsers: any[] = []
+      if (!state.user) throw Error("请先登录");
+      let initAudioUsers: any[] = [];
       try {
-        runtime.likeCount = state.user?.likeNum || 0
-        runtime.lookCount = state.user?.lookNum || 0
+        runtime.likeCount = state.user?.likeNum || 0;
+        runtime.lookCount = state.user?.lookNum || 0;
         const isLiveing =
-          sessionStorage.getItem(RuntimeUtils.START_LIVE_STATUS) === 'liveing'
+          sessionStorage.getItem(RuntimeUtils.START_LIVE_STATUS) === "liveing";
         // IM连接
-        await RuntimeUtils.connectIM(state.user?.imToken)
-        runtime.videoRef = videoRef.value
+        await RuntimeUtils.connectIM(state.user?.imToken);
+        runtime.videoRef = videoRef.value;
         // 获取设备
-        await RuntimeUtils.getMicrophones()
-        await RuntimeUtils.getCameras()
+        await RuntimeUtils.getMicrophones();
+        await RuntimeUtils.getCameras();
         // 设置播放设备
-        RuntimeUtils.setSelectCamera(this.getDeviceByDeviceType('camera'))
+        RuntimeUtils.setSelectCamera(this.getDeviceByDeviceType("camera"));
         RuntimeUtils.setSelectMicrophone(
-          this.getDeviceByDeviceType('microphone')
-        )
+          this.getDeviceByDeviceType("microphone")
+        );
         // RuntimeUtils.setSelectMicrophone2(this.getDeviceByDeviceType('microphone2'))
-        cameraVideoTrack = await RuntimeUtils.getTrack('camera')
-        runtime.videoRef && cameraVideoTrack.play(runtime.videoRef)
+        cameraVideoTrack = await RuntimeUtils.getTrack("camera");
+        runtime.videoRef && cameraVideoTrack.play(runtime.videoRef);
         // await RuntimeUtils.setTrack([cameraVideoTrack], 'camera', isLiveing)
         // await RuntimeUtils.getTrack('microphone')
-        microphoneAudioTrack = await RuntimeUtils.getTrack('microphone')
+        microphoneAudioTrack = await RuntimeUtils.getTrack("microphone");
         // microphoneAudioTrack.play()
         // console.log(microphoneAudioTrack)
         // console.log(runtime.deviceStatus)
-        runtime.videoStatus = 'stream'
+        runtime.videoStatus = "stream";
+        const _this = this;
         const join = await RuntimeUtils.joinRoom(
           state.user?.roomUid,
           RTC.RCLivingType.VIDEO,
           {
             onMessageReceive(name, content) {
-              console.log(name, content)
+              console.log(name, content);
             },
             onKickOff(byServer: boolean) {
-              console.log(byServer)
+              console.log(byServer);
             },
             async onTrackPublish(tracks: RTC.RCRemoteTrack[]) {
-              const subscribeRes = await join?.room?.subscribe(tracks)
-              console.log(subscribeRes)
+              const subscribeRes = await join?.room?.subscribe(tracks);
+              console.log(subscribeRes, "subscribeRes");
               if (
                 subscribeRes?.code &&
                 subscribeRes.code !== RTC.RCRTCCode.SUCCESS
               ) {
-                console.log('资源订阅失败 ->', subscribeRes.code)
+                console.log("资源订阅失败 ->", subscribeRes.code);
               }
             },
             onTrackUnpublish(tracks: RTC.RCRemoteTrack[]) {
-              console.log(tracks)
-              event.emit(LIVE_EVENT_MESSAGE['RM:RTC:TrackUnpublish'], tracks)
+              event.emit(LIVE_EVENT_MESSAGE["RM:RTC:TrackUnpublish"], tracks);
             },
             onSwitchRole(userId: string, role: RTC.RCRTCLiveRole) {
-              event.emit(LIVE_EVENT_MESSAGE['RM:RTC:SwitchRole'], {
+              event.emit(LIVE_EVENT_MESSAGE["RM:RTC:SwitchRole"], {
                 userId,
                 role,
-              })
+              });
             },
-            onTrackReady(track: RTC.RCRemoteTrack) {
+            async onTrackReady(track: RTC.RCRemoteTrack) {
               if (track.isAudioTrack()) {
                 // 音轨不需要传递播放控件
-                track.play()
-                const userId = track.getUserId()
+                track.play();
+                const userId = track.getUserId();
+
+                // 当流变化时,更新连麦用户列表
+                const joinUser = runtimeModel.joinList[userId];
+                console.log(joinUser, "joinUser");
+                if (!joinUser) {
+                  console.log(runtimeModel.lookList, "runtimeModel.lookList");
+                  const userInfo = runtimeModel.lookList[userId];
+                  const list = userInfo
+                    ? userInfo
+                    : await _this.FetchUserDetails([userId]);
+                  console.log(list, "list");
+                }
+                // if (runtimeModel.joinList || runtimeModel.lookList) {
+
+                // }
                 const trackUser = initAudioUsers.find(
                   (user: any) => user.userId == Number(userId)
-                )
+                );
                 // console.log(trackUser, initAudioUsers, userId)
                 if (trackUser) {
                   runtimeModel.joinList[userId] = {
@@ -188,64 +206,67 @@ export default defineComponent({
                     id: userId,
                     name: trackUser.userName,
                     userRoomType: 4,
-                  }
+                  };
+                  initAudioUsers = initAudioUsers.filter(
+                    (user: any) => user.userId != Number(userId)
+                  );
                 }
               }
             },
             onUserJoin(userIds: string[]) {
-              console.log('onUserJoin', userIds)
+              console.log("onUserJoin", userIds);
             },
             onUserLeave(userIds: string[]) {
-              event.emit(LIVE_EVENT_MESSAGE['RM:RTC:UserLeave'], userIds)
-              console.log('onUserLeave', userIds)
+              event.emit(LIVE_EVENT_MESSAGE["RM:RTC:UserLeave"], userIds);
+              console.log("onUserLeave", userIds);
             },
           }
-        )
+        );
         // RuntimeUtils.sendMessage({}, 'Welcome')
-        const userIds: string[] | undefined = join?.room?.getRemoteUserIds()
+        const userIds: string[] | undefined = join?.room?.getRemoteUserIds();
         // console.log('userIds', userIds)
         if (userIds && userIds.length) {
-          const list = await this.FetchUserDetails(userIds)
-          initAudioUsers.push(...list)
+          const list = await this.FetchUserDetails(userIds);
+          initAudioUsers.push(...list);
         }
         const remoteTracks: RTC.RCRemoteTrack[] | undefined =
-          join?.room?.getRemoteTracks()
+          join?.room?.getRemoteTracks();
         if (remoteTracks) {
-          await join?.room?.subscribe(remoteTracks)
+          await join?.room?.subscribe(remoteTracks);
         }
         if (join.room && join.code === RTC.RCRTCCode.SUCCESS) {
-          runtime.joinedRoom = join.room
+          runtime.joinedRoom = join.room;
           join.room.registerReportListener({
             onStateReport(report) {
-              event.emit('onStateReport', report)
+              event.emit("onStateReport", report);
               // console.log('onStateReport', report)
             },
-          })
+          });
         }
         if (isLiveing) {
-          await RuntimeUtils.startLive(false)
-          runtime.videoStatus = 'liveing'
+          await RuntimeUtils.startLive(false);
+          runtime.videoStatus = "liveing";
         } else {
-          await RuntimeUtils.setTrack([cameraVideoTrack], 'camera', false)
+          await RuntimeUtils.setTrack([cameraVideoTrack], "camera", false);
           await RuntimeUtils.setTrack(
             [microphoneAudioTrack],
-            'microphone',
+            "microphone",
             false
-          )
+          );
         }
-        const volume = localStorage.getItem(RuntimeUtils.AUDIO_DEVICE_VOLUME)
+        const volume = localStorage.getItem(RuntimeUtils.AUDIO_DEVICE_VOLUME);
         if (volume) {
-          ActionBarRuntime.volume = parseInt(volume)
-          RuntimeUtils.setVolume(parseInt(volume))
+          ActionBarRuntime.volume = parseInt(volume);
+          RuntimeUtils.setVolume(parseInt(volume));
         }
       } catch (error) {
-        runtime.videoStatus = 'error'
-        console.log(error)
+        runtime.videoStatus = "error";
+        console.log(error);
       }
     },
     closeLive() {
       // removeMedia(runtime.mediaStreams, runtime.mediaStreamTrack)
-      runtime.videoStatus = 'stream'
+      runtime.videoStatus = "stream";
     },
   },
   render() {
@@ -256,18 +277,18 @@ export default defineComponent({
           <Header
             class={[
               styles.headerContent,
-              this.headerStatus ? styles['header-top'] : null,
+              this.headerStatus ? styles["header-top"] : null,
             ]}
           />
         </div>
         <div class={styles.video}>
           <video ref={videoRef}></video>
           {!runtime.screenShareStatus ? <VideoStatus /> : null}
-          {runtime.videoStatus === 'liveing' ? <Chronography /> : null}
+          {runtime.videoStatus === "liveing" ? <Chronography /> : null}
         </div>
         <ActionBar />
         {/* <div>video: {runtime.videoStatus}, imStatus: {runtime.imConnectStatus}</div> */}
       </div>
-    )
+    );
   },
-})
+});

+ 147 - 111
src/components/live-message/model/index.module.less

@@ -1,111 +1,147 @@
-.itemContent {
-  padding: 16px 16px 5px;
-  display: flex;
-  color: var(--live-color);
-  & > img {
-    width: 28px;
-    height: 28px;
-    margin-right: 8px;
-  }
-}
-
-
-.itemInfo {
-  width: 100%;
-}
-
-.itemName {
-  display: flex;
-  justify-content: space-between;
-  align-items: center;
-  padding-top: 3px;
-  .userName {
-    font-size: 15px;
-    line-height: 22px;
-    // display: flex;
-    align-items: center;
-    font-weight: 500;
-  }
-  .name-style {
-    line-height: 24px;
-    color: var(--live-text-color);
-  }
-  .rightTime {
-    font-size: 12px;
-  }
-  :global {
-    .el-tag--default {
-      border-radius: 20px;
-      margin-right: 8px;
-      height: 20px;
-
-      // padding: 0 12px;
-      // line-height: 20px;
-      // color: var(--live-color);
-      // background: var(--message-color);
-      // border-color: var(--message-color);
-    }
-  }
-}
-.itemText {
-  font-size: 15px;
-  line-height: 20px;
-  &.active {
-    color: var(--live-text-color);
-  }
-}
-
-.joinText {
-  display: flex;
-  justify-content: space-between;
-  align-items: center;
-  .join {
-    display: flex;
-    align-items: center;
-  }
-}
-
-.btn {
-  font-size: 13px;
-  line-height: 20px;
-  background-color: var(--live-light-color);
-  border-color: var(--live-light-color);
-  text-align: center;
-  padding: 3px 15px 1px;
-  border-radius: 2px;
-  cursor: pointer;
-  color: var(--live-color);
-  text-decoration: none;
-  &.downBtn {
-    background-color: transparent;
-    border-color: var(--live-light-color);
-    color: var(--live-light-color);
-  }
-}
-
-.loadingStyle {
-  position: absolute;
-  left: 0;
-  right: 0;
-  top: 0;
-  bottom: 0;
-}
-
-
-.slide-top-enter-active {
-  opacity: 0;
-  animation-name: error-num;
-  animation-duration: 0.5s;
-  animation-fill-mode: forwards;
-  animation-delay: 0.1s;
-}
-@keyframes error-num {
-	0% {
-		transform: translateY(30px);
-		opacity: 0;
-	}
-	100% {
-		transform: translateY(0);
-		opacity: 1;
-	}
-}
+.itemContent {
+  padding: 16px 16px 5px;
+  display: flex;
+  color: var(--live-color);
+  & > img {
+    width: 28px;
+    height: 28px;
+    margin-right: 8px;
+  }
+}
+
+.itemInfo {
+  width: 100%;
+}
+
+.itemName {
+  display: flex;
+  justify-content: space-between;
+  align-items: flex-start;
+  padding-top: 3px;
+  .userName {
+    font-size: 15px;
+    line-height: 22px;
+    // display: flex;
+    align-items: center;
+    font-weight: 500;
+    padding-right: 15px;
+    text-align: justify;
+  }
+  .name-style {
+    line-height: 24px;
+    color: var(--live-text-color);
+  }
+  .rightTime {
+    font-size: 12px;
+    line-height: 22px;
+  }
+  :global {
+    .el-tag--default {
+      border-radius: 20px;
+      margin-right: 8px;
+      height: 20px;
+
+      // padding: 0 12px;
+      // line-height: 20px;
+      // color: var(--live-color);
+      // background: var(--message-color);
+      // border-color: var(--message-color);
+    }
+  }
+}
+.itemText {
+  font-size: 15px;
+  line-height: 20px;
+  word-break: break-all;
+  &.active {
+    color: var(--live-text-color);
+  }
+}
+
+.joinText {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  .join {
+    display: flex;
+    align-items: center;
+  }
+}
+
+.btn {
+  font-size: 13px;
+  line-height: 20px;
+  background-color: var(--live-light-color);
+  border-color: var(--live-light-color);
+  text-align: center;
+  padding: 3px 15px 1px;
+  border-radius: 2px;
+  cursor: pointer;
+  color: var(--live-color);
+  text-decoration: none;
+  &.downBtn {
+    background-color: transparent;
+    border-color: var(--live-light-color);
+    color: var(--live-light-color);
+  }
+}
+
+.loadingStyle {
+  position: absolute;
+  left: 0;
+  right: 0;
+  top: 0;
+  bottom: 0;
+}
+
+.slide-top-enter-active {
+  opacity: 0;
+  animation-name: error-num;
+  animation-duration: 0.5s;
+  animation-fill-mode: forwards;
+  animation-delay: 0.1s;
+}
+@keyframes error-num {
+  0% {
+    transform: translateY(30px);
+    opacity: 0;
+  }
+  100% {
+    transform: translateY(0);
+    opacity: 1;
+  }
+}
+
+.refresh {
+  position: absolute;
+  bottom: 10px;
+  right: 15px;
+  width: 40px;
+  height: 40px;
+  background: #fff;
+  display: flex;
+  border-radius: 50%;
+  align-items: center;
+  justify-content: center;
+}
+
+.refresh-animation {
+  animation: animation 1s linear infinite;
+}
+.refreshStart {
+  animation-play-state: running;
+}
+.refreshStop {
+  animation-play-state: paused;
+}
+@keyframes animation {
+  0% {
+    transform: rotate(0deg);
+  }
+  50% {
+    transform: rotate(180deg);
+  }
+  100% {
+    transform: rotate(360deg);
+  }
+}

+ 250 - 109
src/components/live-message/model/join-model.tsx

@@ -1,12 +1,15 @@
 import { defineComponent } from "vue";
-import styles from './index.module.less'
-import { ElButton } from 'element-plus'
-import event, { LIVE_EVENT_MESSAGE } from '/src/components/live-broadcast/event';
-import { state } from '/src/state'
-import dayjs from 'dayjs';
+import styles from "./index.module.less";
+import { ElButton } from "element-plus";
+import event, {
+  LIVE_EVENT_MESSAGE,
+} from "/src/components/live-broadcast/event";
+import { state } from "/src/state";
+import dayjs from "dayjs";
 import Empty from "/src/components/empty";
-import runtime, * as RuntimeUtils from '/src/components/live-broadcast/runtime'
-import runtimeModel, * as RuntimeModelUtils from '/src/components/live-message/model/runtime'
+import runtime, * as RuntimeUtils from "/src/components/live-broadcast/runtime";
+import runtimeModel, * as RuntimeModelUtils from "/src/components/live-message/model/runtime";
+import request from "/src/helpers/request";
 
 export default defineComponent({
   data() {
@@ -15,23 +18,24 @@ export default defineComponent({
       loadingJoin: false, // 连麦列表状态
       upStatus: false,
       downStatus: false,
-    }
+      refreshStatus: false, // 刷新状态
+    };
   },
   computed: {
     count() {
-      let count = 0
+      let count = 0;
       for (const key in runtimeModel.joinList) {
         if (Object.prototype.hasOwnProperty.call(runtimeModel.joinList, key)) {
           const item = runtimeModel.joinList[key];
           if (item.userRoomType === 4) {
-            count += 1
+            count += 1;
           }
           if (count > 3) {
-            break
+            break;
           }
         }
       }
-      return count
+      return count;
     },
   },
   mounted() {
@@ -40,100 +44,112 @@ export default defineComponent({
     // 2 老师邀请
     // 3 学生申请
     // 4 连麦中
-    event.on(LIVE_EVENT_MESSAGE['RC:Chatroom:SeatApply'], this.onSeatApply);
-    event.on(LIVE_EVENT_MESSAGE['RC:Chatroom:SeatResponse'], this.onSeatApply);
-    event.on(LIVE_EVENT_MESSAGE['RM:RTC:UserLeave'], this.onSeatApply);
-    event.on(LIVE_EVENT_MESSAGE['RC:Chatroom:downSeat'], this.onDownSeat);
-    event.on(LIVE_EVENT_MESSAGE['RM:RTC:SwitchRole'], this.onSwitchRole);
-    event.on(LIVE_EVENT_MESSAGE['RC:Chatroom:Leave'], this.onLeave); // 移动端接收的消息
-    event.on(LIVE_EVENT_MESSAGE['RC:LookerLoginOut'], this.onLeave); // 后台接收的消息
+    event.on(LIVE_EVENT_MESSAGE["RC:Chatroom:SeatApply"], this.onSeatApply);
+    event.on(LIVE_EVENT_MESSAGE["RC:Chatroom:SeatResponse"], this.onSeatApply);
+    event.on(LIVE_EVENT_MESSAGE["RM:RTC:UserLeave"], this.onSeatApply);
+    event.on(LIVE_EVENT_MESSAGE["RC:Chatroom:downSeat"], this.onDownSeat);
+    event.on(LIVE_EVENT_MESSAGE["RM:RTC:SwitchRole"], this.onSwitchRole);
+    // event.on(LIVE_EVENT_MESSAGE["RC:Chatroom:Leave"], this.onLeave); // 移动端接收的消息
+    event.on(LIVE_EVENT_MESSAGE["RC:LookerLoginOut"], this.onLeave); // 后台接收的消息
   },
   unmounted() {
-    event.off(LIVE_EVENT_MESSAGE['RC:Chatroom:SeatApply'], this.onSeatApply);
-    event.off(LIVE_EVENT_MESSAGE['RC:Chatroom:SeatResponse'], this.onSeatApply);
-    event.off(LIVE_EVENT_MESSAGE['RM:RTC:UserLeave'], this.onSeatApply);
-    event.off(LIVE_EVENT_MESSAGE['RM:RTC:SwitchRole'], this.onSwitchRole);
-    event.off(LIVE_EVENT_MESSAGE['RC:Chatroom:Leave'], this.onLeave); // 移动端接收的消息
-    event.off(LIVE_EVENT_MESSAGE['RC:LookerLoginOut'], this.onLeave); // 后台接收的消息
+    event.off(LIVE_EVENT_MESSAGE["RC:Chatroom:SeatApply"], this.onSeatApply);
+    event.off(LIVE_EVENT_MESSAGE["RC:Chatroom:SeatResponse"], this.onSeatApply);
+    event.off(LIVE_EVENT_MESSAGE["RM:RTC:UserLeave"], this.onSeatApply);
+    event.off(LIVE_EVENT_MESSAGE["RM:RTC:SwitchRole"], this.onSwitchRole);
+    // event.off(LIVE_EVENT_MESSAGE["RC:Chatroom:Leave"], this.onLeave); // 移动端接收的消息
+    event.off(LIVE_EVENT_MESSAGE["RC:LookerLoginOut"], this.onLeave); // 后台接收的消息
   },
   methods: {
     async onLeave(value: any) {
       // 学生离开时处理
-      const userId = value.userId || value.fromUserId
-      if(runtimeModel.joinList[userId]) {
-        RuntimeModelUtils.removeJoin(userId)
+      const userId = value.userId || value.fromUserId;
+      if (runtimeModel.joinList[userId]) {
+        RuntimeModelUtils.removeJoin(userId);
       }
-      if(runtimeModel.lookList[userId]) {
-        RuntimeModelUtils.removeLook(userId)
+      if (runtimeModel.lookList[userId]) {
+        RuntimeModelUtils.removeLook(userId);
 
         // 判断是否有学生
-        runtime.lookCount = runtime.lookCount - 1 >= 0 ? runtime.lookCount - 1 : 0
+        runtime.lookCount =
+          runtime.lookCount - 1 >= 0 ? runtime.lookCount - 1 : 0;
       }
       // 同步移动端观看人数
-      await RuntimeUtils.sendMessage({ count: runtime.lookCount }, 'MemberCount')
+      await RuntimeUtils.sendMessage(
+        { count: runtime.lookCount },
+        "MemberCount"
+      );
+
+      // this.onRefresh();
     },
     onSeatApply(evt: any) {
       // console.log(evt, 'onSeatApply joinModel')
       if (Array.isArray(evt)) {
         for (const id of evt) {
-          console.log('onSeatApply', id)
-          RuntimeModelUtils.removeJoin(id)
+          console.log("onSeatApply", id);
+          RuntimeModelUtils.removeJoin(id);
         }
-        return
+        return;
       }
-      const response = evt.$EventMessage.messageType === 'RC:Chatroom:SeatResponse'
-      const userRoomType = response ? 4 : 3
+      const response =
+        evt.$EventMessage.messageType === "RC:Chatroom:SeatResponse";
+      const userRoomType = response ? 4 : 3;
       // if(evt.$EventMessage.messageType === 'RC:Chatroom:SeatResponse')
-      const sendTime = dayjs(evt.$EventMessage.sentTime || new Date()).format('HH:mm:ss')
+      const sendTime = dayjs(evt.$EventMessage.sentTime || new Date()).format(
+        "HH:mm:ss"
+      );
       let tempObj = {
         name: evt.audienceName,
         id: String(evt.audienceId),
         system: 1,
         isSelf: false,
-        content: '',
-        sendTime
-      }
+        content: "",
+        sendTime,
+      };
       // 申请连麦
       if (evt.type === 3) {
-        console.log(evt, '申请连麦')
+        console.log(evt, "申请连麦");
         const params = {
           name: evt.audienceName,
           id: evt.audienceId,
           userRoomType: userRoomType,
           type: evt.type,
-        }
-        RuntimeModelUtils.addJoin(evt.audienceId, params)
-        RuntimeModelUtils.addLook(evt.audienceId, params)
+        };
+        RuntimeModelUtils.addJoin(evt.audienceId, params);
+        RuntimeModelUtils.addLook(evt.audienceId, params);
 
-        tempObj.content = response ? '同意了连麦申请' : '发起了连麦申请'
+        tempObj.content = response ? "同意了连麦申请" : "发起了连麦申请";
         RuntimeModelUtils.addMessage(tempObj);
-        event.emit('MESSAGE:Change')
+        event.emit("MESSAGE:Change");
       }
       // 取消连麦
       if (evt.type === 4) {
-        console.log(evt, '取消连麦')
+        console.log(evt, "取消连麦");
         if (runtimeModel.joinList[evt.audienceId]) {
-          RuntimeModelUtils.removeJoin(evt.audienceId)
+          RuntimeModelUtils.removeJoin(evt.audienceId);
         }
         if (runtimeModel.lookList[evt.audienceId]) {
-          let userLook = runtimeModel.lookList[evt.audienceId]
-          userLook.userRoomType = 1
-          RuntimeModelUtils.addLook(evt.audienceId, userLook)
+          let userLook = runtimeModel.lookList[evt.audienceId];
+          userLook.userRoomType = 1;
+          RuntimeModelUtils.addLook(evt.audienceId, userLook);
         }
 
         //
-        tempObj.content = response ? '拒绝了连麦申请' : '取消了连麦申请'
+        tempObj.content = response ? "拒绝了连麦申请" : "取消了连麦申请";
         RuntimeModelUtils.addMessage(tempObj);
-        event.emit('MESSAGE:Change')
-      }
+        event.emit("MESSAGE:Change");
 
+        setTimeout(() => {
+          this.onRefresh();
+        }, 500);
+      }
     },
     agree(item: any) {
       if (this.count > 3 || this.upStatus) {
-        console.log(true, 2323)
-        return
+        console.log(true, 2323);
+        return;
       }
-      this.upStatus = true
+      this.upStatus = true;
       const data = {
         ...item,
         audienceName: item.name,
@@ -142,20 +158,19 @@ export default defineComponent({
         teacherName: state.user?.speakerName,
         userRoomType: 4,
         type: 1,
-      }
-      RuntimeModelUtils.addJoin(item.id, data)
-      RuntimeModelUtils.addLook(item.id, data)
-      RuntimeUtils.sendMessage(data, 'SeatResponse')
-
+      };
+      RuntimeModelUtils.addJoin(item.id, data);
+      RuntimeModelUtils.addLook(item.id, data);
+      RuntimeUtils.sendMessage(data, "SeatResponse");
       setTimeout(() => {
-        this.upStatus = false
+        this.upStatus = false;
       }, 300);
     },
     refuse(item: any) {
-      if(this.downStatus) {
-        return
+      if (this.downStatus) {
+        return;
       }
-      this.downStatus = true
+      this.downStatus = true;
       const data = {
         ...item,
         audienceName: item.name,
@@ -164,75 +179,201 @@ export default defineComponent({
         teacherName: state.user?.speakerName,
         userRoomType: 4,
         type: 5,
-      }
-      RuntimeModelUtils.addJoin(item.id, data)
-      RuntimeUtils.sendMessage(data, 'SeatApply')
+      };
+      RuntimeModelUtils.addJoin(item.id, data);
+      RuntimeUtils.sendMessage(data, "SeatApply");
       setTimeout(() => {
-        this.downStatus = false
-      }, 300);
+        this.downStatus = false;
+      }, 50000);
     },
     onDownSeat(evt: any) {
-      console.log(evt, 'onDownSeat')
+      this.downStatus = false;
+      console.log(evt, "onDownSeat");
       if (runtimeModel.joinList[evt.audienceId]) {
-        const users = runtimeModel.joinList[evt.audienceId]
-        const sendTime = dayjs(new Date()).format('HH:mm:ss')
-        console.log(evt.$EventMessage.senderUserId, state.user?.speakerId, 'onDownSeat')
-        let message = users.type == 5 ? '被报下麦' : '取消了连麦申请'
+        const users = runtimeModel.joinList[evt.audienceId];
+        const sendTime = dayjs(new Date()).format("HH:mm:ss");
+        console.log(
+          evt.$EventMessage.senderUserId,
+          state.user?.speakerId,
+          "onDownSeat"
+        );
+        let message = users.type == 5 ? "被抱下麦" : "取消了连麦申请";
         let tempObj = {
           name: evt.audienceName,
           id: evt.audienceId,
           system: 1,
           isSelf: false,
           content: message,
-          sendTime
-        }
+          sendTime,
+        };
         RuntimeModelUtils.addMessage(tempObj);
-        event.emit('MESSAGE:Change')
+        event.emit("MESSAGE:Change");
 
-        RuntimeModelUtils.removeJoin(evt.audienceId)
+        RuntimeModelUtils.removeJoin(evt.audienceId);
       }
     },
     onSwitchRole(evt: any) {
-      console.log(evt, 'onSwitchRole')
+      console.log(evt, "onSwitchRole");
       if (runtimeModel.lookList[evt.userId] && evt.role === 2) {
-        let userLook = runtimeModel.lookList[evt.userId]
-        userLook.userRoomType = 1
-        RuntimeModelUtils.addLook(evt.userId, userLook)
+        let userLook = runtimeModel.lookList[evt.userId];
+        userLook.userRoomType = 1;
+        RuntimeModelUtils.addLook(evt.userId, userLook);
       }
-    }
+    },
+    async onRefresh() {
+      // 刷新连麦列表
+      console.log(runtime.joinedRoom?.getRemoteUserIds(), "remoteUserIds");
+      this.refreshStatus = true;
+      const userIds: string[] | undefined =
+        runtime.joinedRoom?.getRemoteUserIds();
+      const noJoinUserIds = userIds?.filter((item: string) => {
+        return !runtimeModel.joinList[item];
+      });
+      const noLookList = noJoinUserIds?.filter((item: string) => {
+        return !runtimeModel.lookList[item];
+      });
+      const inLookList = noJoinUserIds?.filter((item: string) => {
+        return runtimeModel.lookList[item];
+      });
+      const joinUserList = inLookList?.map((item: any) => {
+        const user = runtimeModel.lookList[item];
+        user.userRoomType = 4;
+        return user;
+      });
+      console.log(joinUserList);
+      if (noLookList && noLookList?.length > 0) {
+        const fetchList = await this.FetchUserDetails(noLookList);
+        console.log(fetchList, "fetchList");
+        fetchList.forEach((item: any) => {
+          joinUserList?.push({
+            name: item.userName,
+            id: item.userId,
+            sendTime: dayjs(new Date()).format("HH:mm:ss"),
+            userRoomType: 4,
+            type: 1,
+          });
+        });
+      }
+      // 判断是否在连麦列表中
+      if (joinUserList && joinUserList?.length > 0) {
+        joinUserList?.forEach((item: any) => {
+          RuntimeModelUtils.addJoin(item.id, item);
+        });
+      }
+      setTimeout(() => {
+        this.refreshStatus = false;
+      }, 300);
+    },
+    async FetchUserDetails(userIds: string[]) {
+      try {
+        const res = await request.post(
+          "/api-web/imLiveBroadcastRoom/queryBaseUserInfo",
+          {
+            requestType: "json",
+            data: userIds,
+          }
+        );
+        return res.data;
+      } catch (error) {}
+      return [];
+    },
   },
   render() {
-    const list = Object.values(runtimeModel.joinList)
+    const list = Object.values(runtimeModel.joinList);
     return (
-      <div style={{ minHeight: '100%', position: 'relative' }}>
-        {list.length > 0 ? list.map((item: any) => (
-          <div class={styles.itemContent}>
-            <div class={styles.itemInfo}>
-              <div class={styles.itemName}>
-                <p class={styles.userName}>
-                  <span class={styles['name-style']}>{item.name}</span>
-                  {item.userRoomType !== 4 ? <span style={{ paddingLeft: '10px' }}>申请连麦</span> : <span style={{ paddingLeft: '10px', color: 'var(--live-text-color)' }}>正在连麦</span>}
-                </p>
-                {item.userRoomType !== 4 ? (
+      <div style={{ minHeight: "100%", position: "relative" }}>
+        {list.length > 0 ? (
+          list.map((item: any) => (
+            <div class={styles.itemContent}>
+              <div class={styles.itemInfo}>
+                <div class={styles.itemName}>
+                  <p class={styles.userName}>
+                    <span class={styles["name-style"]}>{item.name}</span>
+                    {item.userRoomType !== 4 ? (
+                      <span style={{ paddingLeft: "10px" }}>申请连麦</span>
+                    ) : (
+                      <span
+                        style={{
+                          paddingLeft: "10px",
+                          color: "var(--live-text-color)",
+                        }}
+                      >
+                        正在连麦
+                      </span>
+                    )}
+                  </p>
+                  {item.userRoomType !== 4 ? (
                     <div class={styles.joinText}>
-                      <div class={styles.join}>
-                        {/* 申请连麦 */}
-                      </div>
-                      <ElButton size="small" type="primary" disabled={this.count > 3} class={styles.btn} onClick={() => this.agree(item)}>上麦</ElButton>
+                      <div class={styles.join}>{/* 申请连麦 */}</div>
+                      <ElButton
+                        size="small"
+                        type="primary"
+                        disabled={this.count > 3}
+                        class={styles.btn}
+                        onClick={() => this.agree(item)}
+                      >
+                        上麦
+                      </ElButton>
                     </div>
                   ) : (
                     <div class={styles.joinText}>
-                      <div class={styles.join}>
-                        {/* 正在连麦 */}
-                      </div>
-                      <ElButton size="small" plain class={[styles.btn, styles.downBtn]} onClick={() => this.refuse(item)}>下麦</ElButton>
+                      <div class={styles.join}>{/* 正在连麦 */}</div>
+                      <ElButton
+                        loading={this.downStatus}
+                        size="small"
+                        plain
+                        class={[styles.btn, styles.downBtn]}
+                        onClick={() => this.refuse(item)}
+                      >
+                        下麦
+                      </ElButton>
                     </div>
                   )}
+                </div>
+              </div>
+            </div>
+          ))
+        ) : this.loadingJoin ? (
+          <div class={styles.loadingStyle}>
+            <div
+              class="el-loading-mask"
+              style="background-color: rgba(0, 0, 0, 0.8);"
+            >
+              <div class="el-loading-spinner">
+                <svg class="circular" viewBox="25 25 50 50">
+                  <circle
+                    class="path"
+                    cx="50"
+                    cy="50"
+                    r="20"
+                    fill="none"
+                  ></circle>
+                </svg>
               </div>
             </div>
           </div>
-        )) : this.loadingJoin ? <div class={styles.loadingStyle}><div class="el-loading-mask" style="background-color: rgba(0, 0, 0, 0.8);"><div class="el-loading-spinner"><svg class="circular" viewBox="25 25 50 50"><circle class="path" cx="50" cy="50" r="20" fill="none"></circle></svg></div></div></div> : <Empty style={{ paddingTop: '120px' }} text="暂无学员发起连麦!" icon="noData-no-join" />}
+        ) : (
+          <Empty
+            style={{ paddingTop: "120px" }}
+            text="暂无学员发起连麦!"
+            icon="noData-no-join"
+          />
+        )}
+        {/* <div
+          class={[
+            styles.refresh,
+            styles["refresh-animation"],
+            this.refreshStatus ? styles.refreshStart : styles.refreshStop,
+          ]}
+          onClick={this.onRefresh}
+        >
+          <SvgIcon
+            name="message-refresh"
+            color={"#01A79E"}
+            style={{ width: "20px", height: "20px" }}
+          />
+        </div> */}
       </div>
-    )
-  }
-})
+    );
+  },
+});

+ 127 - 60
src/components/live-message/model/look-model.tsx

@@ -1,12 +1,14 @@
 import { defineComponent } from "vue";
-import { ElButton } from 'element-plus'
-import runtime, * as RuntimeUtils from '/src/components/live-broadcast/runtime'
-import styles from './index.module.less'
-import event, { LIVE_EVENT_MESSAGE } from '/src/components/live-broadcast/event';
-import { state } from '/src/state'
-import dayjs from 'dayjs';
+import { ElButton } from "element-plus";
+import runtime, * as RuntimeUtils from "/src/components/live-broadcast/runtime";
+import styles from "./index.module.less";
+import event, {
+  LIVE_EVENT_MESSAGE,
+} from "/src/components/live-broadcast/event";
+import { state } from "/src/state";
+import dayjs from "dayjs";
 import Empty from "/src/components/empty";
-import runtimeModel, * as RuntimeModelUtils from '/src/components/live-message/model/runtime'
+import runtimeModel, * as RuntimeModelUtils from "/src/components/live-message/model/runtime";
 import request from "/src/helpers/request";
 
 export default defineComponent({
@@ -14,61 +16,70 @@ export default defineComponent({
     return {
       loadingLook: false, // 观看列表状态
       upStatus: false,
-      downStatus: false
-    }
+      downStatus: false,
+    };
   },
   computed: {
     count() {
-      let count = 0
+      let count = 0;
       for (const key in runtimeModel.lookList) {
         if (Object.prototype.hasOwnProperty.call(runtimeModel.lookList, key)) {
           const item = runtimeModel.lookList[key];
           if (item.userRoomType === 2 || item.userRoomType === 4) {
-            count += 1
+            count += 1;
           }
           if (count > 3) {
-            break
+            break;
           }
         }
       }
-      return count
+      return count;
     },
   },
   async mounted() {
-    await this._init()
-    this.loadingLook = true
+    await this._init();
+    this.loadingLook = true;
     event.on(LIVE_EVENT_MESSAGE["RC:Chatroom:Welcome"], this.onWelcome);
-    event.on(LIVE_EVENT_MESSAGE["RC:Chatroom:MemberCountUp"], this.onMemberCount);
+    event.on(
+      LIVE_EVENT_MESSAGE["RC:Chatroom:MemberCountUp"],
+      this.onMemberCount
+    );
     setTimeout(() => {
       this.loadingLook = false;
-    })
+    });
   },
   beforeUnmount() {
     event.off(LIVE_EVENT_MESSAGE["RC:Chatroom:Welcome"], this.onWelcome);
-    event.off(LIVE_EVENT_MESSAGE["RC:Chatroom:MemberCountUp"], this.onMemberCount);
+    event.off(
+      LIVE_EVENT_MESSAGE["RC:Chatroom:MemberCountUp"],
+      this.onMemberCount
+    );
   },
   methods: {
     async _init() {
       try {
-        const roomUid = sessionStorage.getItem('roomUid')
-        const res = await request.get(`/api-web/imLiveBroadcastRoom/queryRoomUserInfo`, {
-          params: {
-            roomUid: roomUid,
+        const roomUid = sessionStorage.getItem("roomUid");
+        const res = await request.get(
+          `/api-web/imLiveBroadcastRoom/queryRoomUserInfo`,
+          {
+            params: {
+              roomUid: roomUid,
+            },
           }
-        })
-        const resList = res.data
+        );
+        const resList = res.data;
         resList.forEach((item: any) => {
           // 判断是已经,存在学生
-          if(!runtimeModel.lookList[item.userId]) {
+          if (!runtimeModel.lookList[item.userId]) {
             runtimeModel.lookList[item.userId] = {
               id: item.userId,
               name: item.userName,
               type: 3,
               userRoomType: 1,
-              time: dayjs().format('YYYY-MM-DD HH:mm:ss'),
-            }
+              time: dayjs().format("YYYY-MM-DD HH:mm:ss"),
+            };
           }
-        })
+        });
       } catch {
         //
       }
@@ -77,39 +88,45 @@ export default defineComponent({
      * 当后端发送人数消息时,更新人数
      */
     onMemberCount(evt: any) {
-      runtime.lookCount = evt.content.count || 0
-      RuntimeUtils.sendMessage({ count: runtime.lookCount }, 'MemberCount')
+      runtime.lookCount = evt.content.count || 0;
+      RuntimeUtils.sendMessage({ count: runtime.lookCount }, "MemberCount");
     },
     async onWelcome(value: any) {
       // console.log(value)
       if (value && value.user) {
-        const sendTime = dayjs(value.$EventMessage.sentTime || new Date()).format('HH:mm:ss')
+        const sendTime = dayjs(
+          value.$EventMessage.sentTime || new Date()
+        ).format("HH:mm:ss");
         let tempObj = {
           name: value.user.name,
           id: value.user.id,
           sendTime,
           userRoomType: 1,
-          type: 3
-        }
+          type: 3,
+        };
         // 判断是否有同一个人
         let isExist = runtimeModel.lookList[tempObj.id] ? true : false;
         if (!isExist) {
           RuntimeModelUtils.addLook(tempObj.id, tempObj);
-          console.log('添加观看人员', tempObj)
+          console.log("添加观看人员", tempObj);
           // runtime.lookCount += 1;
         }
 
         // 同步移动端观看人数
         // await RuntimeUtils.sendMessage({ count: runtime.lookCount }, 'MemberCount')
 
-        this.loadingLook = false
+        this.loadingLook = false;
       }
     },
     async onUpLook(item: any) {
       try {
-        console.log(this.count, runtimeModel.lookList, 'this.count, runtimeModel.lookList')
-        if(this.count > 3) {
-          return
+        console.log(
+          this.count,
+          runtimeModel.lookList,
+          "this.count, runtimeModel.lookList"
+        );
+        if (this.count > 3) {
+          return;
         }
         // RC:Chatroom:SeatResponse type teacherName teacherId audienceName audienceId
         // 操作类型 1 主讲人同意 2 主讲人拒绝 3 观众同意 4 观众拒绝
@@ -127,10 +144,10 @@ export default defineComponent({
           teacherId: String(state.user?.id),
           teacherName: state.user?.speakerName,
           userRoomType: 2,
-          type: 1
-        }
+          type: 1,
+        };
         item.userRoomType = 2;
-        await RuntimeUtils.sendMessage(data, 'SeatApply')
+        await RuntimeUtils.sendMessage(data, "SeatApply");
       } catch {
         //
       }
@@ -144,31 +161,81 @@ export default defineComponent({
           teacherId: String(state.user?.id),
           teacherName: state.user?.speakerName,
           type: 5,
-        }
-        RuntimeModelUtils.addJoin(item.id, data)
-        RuntimeUtils.sendMessage(data, 'SeatApply')
-      } catch {
-      }
+        };
+        RuntimeModelUtils.addJoin(item.id, data);
+        RuntimeUtils.sendMessage(data, "SeatApply");
+      } catch {}
     },
   },
   render() {
-    const list = Object.values(runtimeModel.lookList)
+    const list = Object.values(runtimeModel.lookList);
     return (
       <div>
-        {list.length > 0 ? list.map((item : any) => (
-          <div class={styles.itemContent}>
-            <div class={styles.itemInfo} >
-              <div class={styles.itemName}>
-                <p class={styles.userName}>
-                  <span class={styles['name-style']}>{item.name}</span>
-                </p>
-                {/* 1、最多三个人上麦;2、老师主动邀请;3、没有开始直播 */}
-                {item.userRoomType !== 4 ? <ElButton size="small" type="primary" disabled={this.count > 3 || item.userRoomType === 2 || runtime.videoStatus !== 'liveing'} class={styles.btn} onClick={() => this.onUpLook(item)}>上麦</ElButton> : <ElButton size="small" plain class={[styles.btn, styles.downBtn]} onClick={() => this.onDownLook(item)}>下麦</ElButton>}
+        {list.length > 0 ? (
+          list.map((item: any) => (
+            <div class={styles.itemContent}>
+              <div class={styles.itemInfo}>
+                <div class={styles.itemName}>
+                  <p class={styles.userName}>
+                    <span class={styles["name-style"]}>{item.name}</span>
+                  </p>
+                  {/* 1、最多三个人上麦;2、老师主动邀请;3、没有开始直播 */}
+                  {item.userRoomType !== 4 ? (
+                    <ElButton
+                      size="small"
+                      type="primary"
+                      disabled={
+                        this.count > 3 ||
+                        item.userRoomType === 2 ||
+                        item.userRoomType === 3 ||
+                        runtime.videoStatus !== "liveing"
+                      }
+                      class={styles.btn}
+                      onClick={() => this.onUpLook(item)}
+                    >
+                      上麦
+                    </ElButton>
+                  ) : (
+                    <ElButton
+                      size="small"
+                      plain
+                      class={[styles.btn, styles.downBtn]}
+                      onClick={() => this.onDownLook(item)}
+                    >
+                      下麦
+                    </ElButton>
+                  )}
+                </div>
+              </div>
+            </div>
+          ))
+        ) : this.loadingLook ? (
+          <div class={styles.loadingStyle}>
+            <div
+              class="el-loading-mask"
+              style="background-color: rgba(0, 0, 0, 0.8);"
+            >
+              <div class="el-loading-spinner">
+                <svg class="circular" viewBox="25 25 50 50">
+                  <circle
+                    class="path"
+                    cx="50"
+                    cy="50"
+                    r="20"
+                    fill="none"
+                  ></circle>
+                </svg>
               </div>
             </div>
           </div>
-        )) : this.loadingLook ? <div class={styles.loadingStyle} ><div class="el-loading-mask" style="background-color: rgba(0, 0, 0, 0.8);"><div class="el-loading-spinner"><svg class="circular" viewBox="25 25 50 50"><circle class="path" cx="50" cy="50" r="20" fill="none"></circle></svg></div></div></div> : <Empty style={{ paddingTop: '120px' }} text="暂无学员观看!" icon="noData-no-user" />}
+        ) : (
+          <Empty
+            style={{ paddingTop: "120px" }}
+            text="暂无学员观看!"
+            icon="noData-no-user"
+          />
+        )}
       </div>
-    )
-  }
-})
+    );
+  },
+});

+ 2 - 0
src/icons/message/refresh.svg

@@ -0,0 +1,2 @@
+<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1653536814949" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2842" xmlns:xlink="http://www.w3.org/1999/xlink" width="64" height="64"><defs><style type="text/css">@font-face { font-family: feedback-iconfont; src: url("//at.alicdn.com/t/font_1031158_u69w8yhxdu.woff2?t=1630033759944") format("woff2"), url("//at.alicdn.com/t/font_1031158_u69w8yhxdu.woff?t=1630033759944") format("woff"), url("//at.alicdn.com/t/font_1031158_u69w8yhxdu.ttf?t=1630033759944") format("truetype"); }
+</style></defs><path d="M87.552 225.645714l59.318857 46.665143c76.434286-113.078857 228.790857-198.217143 364.982857-198.217143 165.668571 0 336.749714 122.075429 401.042286 264.045715-50.249143 18.870857-140.288 95.451429-140.288 95.451428L1023.634286 614.4V511.853714C1023.707429 229.668571 794.038857 0 511.853714 0a511.268571 511.268571 0 0 0-424.301714 225.645714z m31.158857 454.948572C168.96 661.430857 251.026286 590.262857 251.026286 590.262857L0 409.453714v102.4c0 282.185143 229.668571 511.853714 511.853714 511.853715a511.268571 511.268571 0 0 0 424.374857-225.645715l-58.587428-44.032c-76.434286 113.005714-229.449143 197.924571-365.787429 197.924572-165.668571 0-328.850286-129.462857-393.142857-271.36z" p-id="2843"></path></svg>

Einige Dateien werden nicht angezeigt, da zu viele Dateien in diesem Diff geändert wurden.