lex-xin 3 년 전
부모
커밋
67c6e676ef

+ 1 - 0
src/components/live-broadcast/event.ts

@@ -15,6 +15,7 @@ export const LIVE_EVENT_MESSAGE = {
   'RC:Chatroom:Leave': 'Leave',
   'RC:ForcedOffline': 'ForcedOffline',
   'RC:LookerLoginOut': 'LookerLoginOut',
+  'RC:Chatroom:downSeat': 'DownSeat',
 }
 
 export default mitt()

+ 175 - 175
src/components/live-broadcast/index.tsx

@@ -1,175 +1,175 @@
-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 { removeMedia } from './helpers'
-import styles from './index.module.less'
-
-const videoRef = ref<HTMLVideoElement | null>(null)
-
-let microphoneAudioTrack: RTC.RCLocalTrack
-let cameraVideoTrack: RTC.RCLocalTrack
-
-export default defineComponent({
-  name: 'LiveBroadcast',
-  data() {
-    return {
-      headerStatus: false
-    }
-  },
-  computed: {
-    isLive() {
-      console.log(runtime.videoStatus)
-      if(runtime.videoStatus === 'liveing') {
-        setTimeout(() => {
-          this.headerStatus = true
-        }, 3000);
-      } else {
-        this.headerStatus = false
-      }
-      return runtime.videoStatus === 'liveing'
-    }
-  },
-  async mounted() {
-    this.initializeRoom()
-    RuntimeUtils.loopSyncLike()
-    event.on(LIVE_EVENT_MESSAGE['RC:Chatroom:Like'], this.onLikeMessage)
-    window.onbeforeunload = this.beforeunload
-  },
-  beforeUnmount() {
-    event.off(LIVE_EVENT_MESSAGE['RC:Chatroom:Like'], this.onLikeMessage)
-    window.onbeforeunload = null
-  },
-  methods: {
-    beforeunload() {
-      if (runtime.videoStatus === 'liveing') {
-        return '当前正在直播中是否确认关闭页面?'
-      }
-    },
-    onLikeMessage(msg: any) {
-      runtime.likeCount += msg.counts
-    },
-    getDeviceByDeviceType(type: RuntimeUtils.TrackType) {
-      const videoDeviceId = localStorage.getItem(RuntimeUtils.VIDEO_DEVICE_ID)
-      const audioDeviceId = localStorage.getItem(RuntimeUtils.AUDIO_DEVICE_ID)
-      if (type === 'camera') {
-        if (videoDeviceId) {
-          return runtime.cameras.find(camera => camera.deviceId === videoDeviceId) || runtime.cameras[0]
-        }
-        return runtime.cameras[0]
-      }
-      if (audioDeviceId) {
-        return runtime.microphones.find(microphone => microphone.deviceId === audioDeviceId) || runtime.microphones[0]
-      }
-      return runtime.microphones[0]
-    },
-    async initializeRoom () {
-      if (!state.user) throw Error('请先登录')
-      try {
-        runtime.likeCount = state.user?.likeNum || 0
-        runtime.lookCount = state.user?.lookNum || 0
-        const isLiveing = sessionStorage.getItem(RuntimeUtils.START_LIVE_STATUS) === 'liveing'
-        // IM连接
-        await RuntimeUtils.connectIM(state.user?.imToken)
-        runtime.videoRef = videoRef.value
-        // 获取设备
-        await RuntimeUtils.getMicrophones()
-        await RuntimeUtils.getCameras()
-        // 设置播放设备
-        RuntimeUtils.setSelectCamera(this.getDeviceByDeviceType('camera'))
-        RuntimeUtils.setSelectMicrophone(this.getDeviceByDeviceType('microphone'))
-        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.play()
-        // console.log(microphoneAudioTrack)
-        // console.log(runtime.deviceStatus)
-        runtime.videoStatus = 'stream'
-        const join = await RuntimeUtils.joinRoom(state.user?.roomUid, RTC.RCLivingType.VIDEO, {
-          onMessageReceive(name, content) {
-            console.log(name, content)
-          },
-          onKickOff(byServer: boolean) {
-            console.log(byServer)
-          },
-          async onTrackPublish (tracks: RTC.RCRemoteTrack[]) {
-            const subscribeRes = await join?.room?.subscribe(tracks)
-            console.log(subscribeRes)
-            if (subscribeRes?.code && subscribeRes.code !== RTC.RCRTCCode.SUCCESS) {
-              console.log('资源订阅失败 ->', subscribeRes.code)
-            }
-          },
-          onTrackUnpublish(tracks: RTC.RCRemoteTrack[]) {
-            console.log(tracks)
-            event.emit(LIVE_EVENT_MESSAGE['RM:RTC:TrackUnpublish'], tracks)
-          },
-          onSwitchRole(userId: string, role: RTC.RCRTCLiveRole) {
-            event.emit(LIVE_EVENT_MESSAGE['RM:RTC:SwitchRole'], {
-              userId,
-              role,
-            })
-          },
-          onTrackReady (track: RTC.RCRemoteTrack) {
-            if (track.isAudioTrack()) {
-              // 音轨不需要传递播放控件
-              track.play()
-            }
-          },
-          onUserJoin (userIds: string[]) {
-            console.log('onUserJoin', userIds)
-          },
-          onUserLeave (userIds: string[]) {
-            event.emit(LIVE_EVENT_MESSAGE['RM:RTC:UserLeave'], userIds)
-            console.log('onUserLeave', userIds)
-          },
-        })
-        if (join.room && join.code === RTC.RCRTCCode.SUCCESS) {
-          runtime.joinedRoom = join.room
-        }
-        if (isLiveing) {
-          await RuntimeUtils.startLive(false)
-          runtime.videoStatus = 'liveing'
-        } else {
-          await RuntimeUtils.setTrack([cameraVideoTrack], 'camera', false)
-          await RuntimeUtils.setTrack([microphoneAudioTrack], 'microphone', false)
-        }
-        const volume =localStorage.getItem(RuntimeUtils.AUDIO_DEVICE_VOLUME)
-        if (volume) {
-          ActionBarRuntime.volume = parseInt(volume)
-          RuntimeUtils.setVolume(parseInt(volume))
-        }
-      } catch (error) {
-        runtime.videoStatus = 'error'
-        console.log(error)
-      }
-    },
-    closeLive() {
-      // removeMedia(runtime.mediaStreams, runtime.mediaStreamTrack)
-      runtime.videoStatus = 'stream'
-    }
-  },
-  render() {
-    return (
-      <div class={styles.main}>
-        {this.isLive ? null : null}
-        <div class={[styles.headerSection]}>
-          <Header class={[styles.headerContent, this.headerStatus ? styles["header-top"] : null]} />
-        </div>
-        <div class={styles.video}>
-          <video ref={videoRef}></video>
-          {!runtime.screenShareStatus ? <VideoStatus/> : null}
-          {runtime.videoStatus === 'liveing' ? <Chronography/> : null}
-        </div>
-        <ActionBar/>
-        {/* <div>video: {runtime.videoStatus}, imStatus: {runtime.imConnectStatus}</div> */}
-      </div>
-    )
-  }
-})
+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 { removeMedia } from './helpers'
+import styles from './index.module.less'
+
+const videoRef = ref<HTMLVideoElement | null>(null)
+
+let microphoneAudioTrack: RTC.RCLocalTrack
+let cameraVideoTrack: RTC.RCLocalTrack
+
+export default defineComponent({
+  name: 'LiveBroadcast',
+  data() {
+    return {
+      headerStatus: false
+    }
+  },
+  computed: {
+    isLive() {
+      console.log(runtime.videoStatus)
+      if(runtime.videoStatus === 'liveing') {
+        setTimeout(() => {
+          this.headerStatus = true
+        }, 3000);
+      } else {
+        this.headerStatus = false
+      }
+      return runtime.videoStatus === 'liveing'
+    }
+  },
+  async mounted() {
+    this.initializeRoom()
+    RuntimeUtils.loopSyncLike()
+    event.on(LIVE_EVENT_MESSAGE['RC:Chatroom:Like'], this.onLikeMessage)
+    window.onbeforeunload = this.beforeunload
+  },
+  beforeUnmount() {
+    event.off(LIVE_EVENT_MESSAGE['RC:Chatroom:Like'], this.onLikeMessage)
+    window.onbeforeunload = null
+  },
+  methods: {
+    beforeunload() {
+      if (runtime.videoStatus === 'liveing') {
+        return '当前正在直播中是否确认关闭页面?'
+      }
+    },
+    onLikeMessage(msg: any) {
+      runtime.likeCount += msg.counts
+    },
+    getDeviceByDeviceType(type: RuntimeUtils.TrackType) {
+      const videoDeviceId = localStorage.getItem(RuntimeUtils.VIDEO_DEVICE_ID)
+      const audioDeviceId = localStorage.getItem(RuntimeUtils.AUDIO_DEVICE_ID)
+      if (type === 'camera') {
+        if (videoDeviceId) {
+          return runtime.cameras.find(camera => camera.deviceId === videoDeviceId) || runtime.cameras[0]
+        }
+        return runtime.cameras[0]
+      }
+      if (audioDeviceId) {
+        return runtime.microphones.find(microphone => microphone.deviceId === audioDeviceId) || runtime.microphones[0]
+      }
+      return runtime.microphones[0]
+    },
+    async initializeRoom () {
+      if (!state.user) throw Error('请先登录')
+      try {
+        runtime.likeCount = state.user?.likeNum || 0
+        runtime.lookCount = state.user?.lookNum || 0
+        const isLiveing = sessionStorage.getItem(RuntimeUtils.START_LIVE_STATUS) === 'liveing'
+        // IM连接
+        await RuntimeUtils.connectIM(state.user?.imToken)
+        runtime.videoRef = videoRef.value
+        // 获取设备
+        await RuntimeUtils.getMicrophones()
+        await RuntimeUtils.getCameras()
+        // 设置播放设备
+        RuntimeUtils.setSelectCamera(this.getDeviceByDeviceType('camera'))
+        RuntimeUtils.setSelectMicrophone(this.getDeviceByDeviceType('microphone'))
+        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.play()
+        // console.log(microphoneAudioTrack)
+        // console.log(runtime.deviceStatus)
+        runtime.videoStatus = 'stream'
+        const join = await RuntimeUtils.joinRoom(state.user?.roomUid, RTC.RCLivingType.VIDEO, {
+          onMessageReceive(name, content) {
+            console.log(name, content)
+          },
+          onKickOff(byServer: boolean) {
+            console.log(byServer)
+          },
+          async onTrackPublish (tracks: RTC.RCRemoteTrack[]) {
+            const subscribeRes = await join?.room?.subscribe(tracks)
+            console.log(subscribeRes)
+            if (subscribeRes?.code && subscribeRes.code !== RTC.RCRTCCode.SUCCESS) {
+              console.log('资源订阅失败 ->', subscribeRes.code)
+            }
+          },
+          onTrackUnpublish(tracks: RTC.RCRemoteTrack[]) {
+            console.log(tracks)
+            event.emit(LIVE_EVENT_MESSAGE['RM:RTC:TrackUnpublish'], tracks)
+          },
+          onSwitchRole(userId: string, role: RTC.RCRTCLiveRole) {
+            event.emit(LIVE_EVENT_MESSAGE['RM:RTC:SwitchRole'], {
+              userId,
+              role,
+            })
+          },
+          onTrackReady (track: RTC.RCRemoteTrack) {
+            if (track.isAudioTrack()) {
+              // 音轨不需要传递播放控件
+              track.play()
+            }
+          },
+          onUserJoin (userIds: string[]) {
+            console.log('onUserJoin', userIds)
+          },
+          onUserLeave (userIds: string[]) {
+            event.emit(LIVE_EVENT_MESSAGE['RM:RTC:UserLeave'], userIds)
+            console.log('onUserLeave', userIds)
+          },
+        })
+        if (join.room && join.code === RTC.RCRTCCode.SUCCESS) {
+          runtime.joinedRoom = join.room
+        }
+        if (isLiveing) {
+          await RuntimeUtils.startLive(false)
+          runtime.videoStatus = 'liveing'
+        } else {
+          await RuntimeUtils.setTrack([cameraVideoTrack], 'camera', false)
+          await RuntimeUtils.setTrack([microphoneAudioTrack], 'microphone', false)
+        }
+        const volume =localStorage.getItem(RuntimeUtils.AUDIO_DEVICE_VOLUME)
+        if (volume) {
+          ActionBarRuntime.volume = parseInt(volume)
+          RuntimeUtils.setVolume(parseInt(volume))
+        }
+      } catch (error) {
+        runtime.videoStatus = 'error'
+        console.log(error)
+      }
+    },
+    closeLive() {
+      // removeMedia(runtime.mediaStreams, runtime.mediaStreamTrack)
+      runtime.videoStatus = 'stream'
+    }
+  },
+  render() {
+    return (
+      <div class={styles.main}>
+        {this.isLive ? null : null}
+        <div class={[styles.headerSection]}>
+          <Header class={[styles.headerContent, this.headerStatus ? styles["header-top"] : null]} />
+        </div>
+        <div class={styles.video}>
+          <video ref={videoRef}></video>
+          {!runtime.screenShareStatus ? <VideoStatus/> : null}
+          {runtime.videoStatus === 'liveing' ? <Chronography/> : null}
+        </div>
+        <ActionBar/>
+        {/* <div>video: {runtime.videoStatus}, imStatus: {runtime.imConnectStatus}</div> */}
+      </div>
+    )
+  }
+})

+ 9 - 3
src/components/live-broadcast/runtime.ts

@@ -76,7 +76,8 @@ const runtime = reactive({
     microphone: 'init',
     camera: 'init',
     screen: 'init'
-  } as DeviceStatus
+  } as DeviceStatus,
+  syncLikeTimer: null as any
 })
 
 export default runtime
@@ -514,7 +515,8 @@ export const closeLive = async (remove = false) => {
  * 同步点赞数量
  */
 export const loopSyncLike = async () => {
-  if ((runtime.likeCount !== runtime.lastLikeCount || runtime.likeCount === 0) && state.user) {
+  // (runtime.likeCount !== runtime.lastLikeCount || runtime.likeCount === 0) &&
+  if (state.user) {
     try {
       await request.get('/api-web/imLiveBroadcastRoom/syncLike', {
         hideLoading: true,
@@ -528,7 +530,7 @@ export const loopSyncLike = async () => {
       sendMessage({ count: runtime.likeCount }, 'LikeCount')
     } catch (error) {}
   }
-  setTimeout(() => {
+  runtime.syncLikeTimer = setTimeout(() => {
     loopSyncLike()
   }, 1000 * 10)
 }
@@ -627,6 +629,10 @@ export const toggleDevice = async (trackType: TrackType) => {
 
 export const leaveIMRoom = async () => {
   await closeLive(true)
+  leaveIMRoomAndClear()
+}
+
+export const leaveIMRoomAndClear = async () => {
   if (runtime.joinedRoom) {
     // @ts-ignore
     await runtime.rtcClient?.leaveRoom(runtime.joinedRoom)

+ 14 - 8
src/components/live-message/model/join-model.tsx

@@ -43,6 +43,7 @@ export default defineComponent({
     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); // 后台接收的消息
@@ -170,24 +171,29 @@ export default defineComponent({
         this.downStatus = false
       }, 300);
     },
-    onSwitchRole(evt: any) {
-      console.log(evt, 'onSwitchRole')
-      if (runtimeModel.joinList[evt.userId] && evt.role === 2) {
-        const user = runtimeModel.joinList[evt.userId]
+    onDownSeat(evt: any) {
+      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 ? '被报下麦' : '取消了连麦申请'
         let tempObj = {
-          name: user.audienceName,
-          id: user.audienceId,
+          name: evt.audienceName,
+          id: evt.audienceId,
           system: 1,
           isSelf: false,
-          content: '发起了连麦申请',
+          content: message,
           sendTime
         }
         RuntimeModelUtils.addMessage(tempObj);
         event.emit('MESSAGE:Change')
 
-        RuntimeModelUtils.removeJoin(evt.userId)
+        RuntimeModelUtils.removeJoin(evt.audienceId)
       }
+    },
+    onSwitchRole(evt: any) {
+      console.log(evt, 'onSwitchRole')
       if (runtimeModel.lookList[evt.userId] && evt.role === 2) {
         let userLook = runtimeModel.lookList[evt.userId]
         userLook.userRoomType = 1

+ 1 - 0
src/components/live-message/model/message-model.tsx

@@ -43,6 +43,7 @@ export default defineComponent({
         await request.post('/api-auth/exit', { data: {} });
         RuntimeUtilCast.closeDevice('camera')
         RuntimeUtilCast.closeDevice('microphone')
+        runtimeCast.syncLikeTimer && clearTimeout(runtimeCast.syncLikeTimer)
         state.user = null
         removeToken();
         (this as any).$router.push({

+ 107 - 98
src/helpers/request.ts

@@ -1,98 +1,107 @@
-import { getToken, removeToken } from './../utils/auth';
-import { extend } from 'umi-request'
-import { ElMessage } from 'element-plus'
-import cleanDeep from 'clean-deep'
-import router from '../router';
-import { showLoading, hideLoading } from '../utils/loading'
-// import { setLogout } from 'src/actions/users'
-// import store from 'src/store'
-
-export interface SearchInitParams {
-  rows?: string | number;
-  page?: string | number;
-}
-
-export interface InitSearchRespones {
-  data: {
-    rows: any[],
-    [key: string]: any
-  },
-  [key: string]: any
-}
-
-const request = extend({
-  requestType: 'form',
-  timeout: 10000
-})
-
-request.interceptors.request.use((url, options: any) => {
-  let hideLoading = options.hideLoading || false
-  if(!hideLoading) {
-    showLoading()
-  }
-  const Authorization = getToken()
-  const tenantId = (localStorage.getItem('tenantId') || '')
-  const organId = (localStorage.getItem('organId') || '')
-  const authHeaders: any = {}
-  if (Authorization && !['/api-auth/usernameLogin', '/api-auth/smsLogin', '/api-auth/code/sendSms'].includes(url)) {
-    authHeaders.Authorization = Authorization
-  }
-  if (tenantId) {
-    authHeaders.tenantId = tenantId
-  }
-  if (organId) {
-    authHeaders.organId = organId
-  }
-  return {
-    url,
-    options: {
-      ...options,
-      params: cleanDeep(options.params),
-      headers: {
-        ...options.headers,
-        ...authHeaders
-      }
-    }
-  }
-})
-
-request.interceptors.response.use(async (res, options) => {
-  setTimeout(() => {
-    hideLoading()
-  }, 200)
-  let hideMessage = options.hideMessage || false
-  const url = new URL(res.url)
-  if (res.status > 299 || res.status < 200) {
-    const msg = '服务器错误,状态码' + res.status
-    if (!hideMessage) {
-      ElMessage.error(msg)
-    }
-    throw new Error(msg)
-  }
-  const data = await res.clone().json()
-  if (data.code !== 200 && data.errCode !== 0) {
-    const msg = data.msg || '处理失败,请重试'
-    if(data.code === 401 || data.code === 403) {
-      if(!hideMessage) {
-        ElMessage.error(`登录过期,请重新登录!`)
-      }
-      removeToken()
-      router.push(`/login`)
-    }
-    if(data.code === 404) {
-      if(!hideMessage) {
-        ElMessage.error(`请求资源不存在!`)
-      }
-      router.push('/404')
-    }
-    if (!(data.code === 403 || data.code === 401)) {
-      if (!hideMessage) {
-        ElMessage.error(msg)
-      }
-    }
-    throw new Error(msg)
-  }
-  return res
-})
-
-export default request
+import { getToken, removeToken } from './../utils/auth';
+import { extend } from 'umi-request'
+import { ElMessage } from 'element-plus'
+import cleanDeep from 'clean-deep'
+import router from '../router';
+import { showLoading, hideLoading } from '../utils/loading'
+import runtime, * as RuntimeUtils from '../components/live-broadcast/runtime';
+import { state } from '../state';
+// import { setLogout } from 'src/actions/users'
+// import store from 'src/store'
+
+export interface SearchInitParams {
+  rows?: string | number;
+  page?: string | number;
+}
+
+export interface InitSearchRespones {
+  data: {
+    rows: any[],
+    [key: string]: any
+  },
+  [key: string]: any
+}
+
+const request = extend({
+  requestType: 'form',
+  timeout: 10000
+})
+
+request.interceptors.request.use((url, options: any) => {
+  let hideLoading = options.hideLoading || false
+  if(!hideLoading) {
+    showLoading()
+  }
+  const Authorization = getToken()
+  const tenantId = (localStorage.getItem('tenantId') || '')
+  const organId = (localStorage.getItem('organId') || '')
+  const authHeaders: any = {}
+  if (Authorization && !['/api-auth/usernameLogin', '/api-auth/smsLogin', '/api-auth/code/sendSms'].includes(url)) {
+    authHeaders.Authorization = Authorization
+  }
+  if (tenantId) {
+    authHeaders.tenantId = tenantId
+  }
+  if (organId) {
+    authHeaders.organId = organId
+  }
+  return {
+    url,
+    options: {
+      ...options,
+      params: cleanDeep(options.params),
+      headers: {
+        ...options.headers,
+        ...authHeaders
+      }
+    }
+  }
+})
+
+request.interceptors.response.use(async (res, options) => {
+  setTimeout(() => {
+    hideLoading()
+  }, 200)
+  let hideMessage = options.hideMessage || false
+  const url = new URL(res.url)
+  if (res.status > 299 || res.status < 200) {
+    const msg = '服务器错误,状态码' + res.status
+    if (!hideMessage) {
+      ElMessage.error(msg)
+    }
+    throw new Error(msg)
+  }
+  const data = await res.clone().json()
+  if (data.code !== 200 && data.errCode !== 0) {
+    const msg = data.msg || '处理失败,请重试'
+    if(data.code === 401 || data.code === 403) {
+      if(!hideMessage) {
+        ElMessage.error(`登录过期,请重新登录!`)
+      }
+      try {
+        await RuntimeUtils.leaveIMRoomAndClear()
+        RuntimeUtils.closeDevice('camera')
+        RuntimeUtils.closeDevice('microphone')
+        state.user = null
+      } catch {}
+      runtime.syncLikeTimer && clearTimeout(runtime.syncLikeTimer)
+      removeToken()
+      router.push(`/login`)
+    }
+    if(data.code === 404) {
+      if(!hideMessage) {
+        ElMessage.error(`请求资源不存在!`)
+      }
+      router.push('/404')
+    }
+    if (!(data.code === 403 || data.code === 401)) {
+      if (!hideMessage) {
+        ElMessage.error(msg)
+      }
+    }
+    throw new Error(msg)
+  }
+  return res
+})
+
+export default request

+ 66 - 65
src/pages/home/header/index.tsx

@@ -1,65 +1,66 @@
-import { defineComponent } from "vue";
-import { ElDropdownMenu, ElDropdown, ElDropdownItem, ElMessage } from "element-plus";
-import router from "/src/router";
-import styles from './index.module.less';
-import request from '/src/helpers/request';
-import runtime, * as RuntimeUtils from "/src/components/live-broadcast/runtime";
-import { removeToken } from "/src/utils/auth";
-import { removeMedia } from '/src/components/live-broadcast/helpers'
-import { state } from '/src/state'
-import userLogo from '/src/assets/home/placehorder-icon.png'
-
-export default defineComponent({
-  methods: {
-    async loginOut() {
-      try {
-        await RuntimeUtils.leaveIMRoom()
-        await request.post('/api-auth/exit', { data: {} });
-        RuntimeUtils.closeDevice('camera')
-        RuntimeUtils.closeDevice('microphone')
-        state.user = null
-        ElMessage.success('退出成功');
-        removeToken();
-        (this as any).$router.push({
-          path: '/login',
-          query: {
-            ...this.$route.query
-          }
-        });
-      } catch(e) {
-        // TODO: handle error
-      }
-    }
-  },
-  render() {
-    return (
-      <div class={styles.liveHeader}>
-        <div class={styles.liveHeaderLeft}>
-          <div class={styles.liveHeaderLeftIcon}>
-            <img class={styles.liveLogo} src={state.user?.tenantLogo} alt=""/>
-            {state.user?.tenantName}
-          </div>
-          <div class={styles.liveHeaderLeftText}>
-            《{state.user?.roomTitle}》
-          </div>
-        </div>
-        <ElDropdown trigger={'hover'}
-          // @ts-ignore
-          vSlots={{
-            dropdown: () => (
-              <ElDropdownMenu>
-                <ElDropdownItem command="1" onClick={this.loginOut}>
-                  <span>安全退出</span>
-                </ElDropdownItem>
-              </ElDropdownMenu>
-            )
-          }}>
-          <div class={styles.avatarWrapper}>
-            {state.user?.speakerPic ? <img class={styles.userAvatar} src={state.user?.speakerPic} /> : <img class={styles.userAvatar} src={userLogo} />}
-            <span>{ state.user?.speakerName }</span>
-          </div>
-        </ElDropdown>
-      </div>
-    )
-  }
-})
+import { defineComponent } from "vue";
+import { ElDropdownMenu, ElDropdown, ElDropdownItem, ElMessage } from "element-plus";
+import router from "/src/router";
+import styles from './index.module.less';
+import request from '/src/helpers/request';
+import runtime, * as RuntimeUtils from "/src/components/live-broadcast/runtime";
+import { removeToken } from "/src/utils/auth";
+import { removeMedia } from '/src/components/live-broadcast/helpers'
+import { state } from '/src/state'
+import userLogo from '/src/assets/home/placehorder-icon.png'
+
+export default defineComponent({
+  methods: {
+    async loginOut() {
+      try {
+        await RuntimeUtils.leaveIMRoom()
+        await request.post('/api-auth/exit', { data: {} });
+        RuntimeUtils.closeDevice('camera')
+        RuntimeUtils.closeDevice('microphone')
+        state.user = null
+        runtime.syncLikeTimer && clearTimeout(runtime.syncLikeTimer)
+        ElMessage.success('退出成功');
+        removeToken();
+        (this as any).$router.push({
+          path: '/login',
+          query: {
+            ...this.$route.query
+          }
+        });
+      } catch(e) {
+        // TODO: handle error
+      }
+    }
+  },
+  render() {
+    return (
+      <div class={styles.liveHeader}>
+        <div class={styles.liveHeaderLeft}>
+          <div class={styles.liveHeaderLeftIcon}>
+            <img class={styles.liveLogo} src={state.user?.tenantLogo} alt=""/>
+            {state.user?.tenantName}
+          </div>
+          <div class={styles.liveHeaderLeftText}>
+            《{state.user?.roomTitle}》
+          </div>
+        </div>
+        <ElDropdown trigger={'hover'}
+          // @ts-ignore
+          vSlots={{
+            dropdown: () => (
+              <ElDropdownMenu>
+                <ElDropdownItem command="1" onClick={this.loginOut}>
+                  <span>安全退出</span>
+                </ElDropdownItem>
+              </ElDropdownMenu>
+            )
+          }}>
+          <div class={styles.avatarWrapper}>
+            {state.user?.speakerPic ? <img class={styles.userAvatar} src={state.user?.speakerPic} /> : <img class={styles.userAvatar} src={userLogo} />}
+            <span>{ state.user?.speakerName }</span>
+          </div>
+        </ElDropdown>
+      </div>
+    )
+  }
+})

+ 2 - 1
src/pages/login/index.tsx

@@ -5,6 +5,7 @@ import request from "/src/helpers/request";
 import { removeToken, setToken } from "/src/utils/auth";
 import LogoPng from '././../../assets/home/logo.png'
 import FromBg from './images/from-bg.png'
+import qs from 'query-string'
 
 
 export default defineComponent({
@@ -113,7 +114,7 @@ export default defineComponent({
             sessionStorage.setItem('details',JSON.stringify(details.data))
             ElMessage.success('登录成功')
             // this.$router.push(this.redirect || '/')
-            window.location.href = window.location.origin + '/live/?roomUid=' + roomUid + '&time=' + new Date().getTime()
+            window.location.href = window.location.origin + '/live/?' + qs.stringify({ roomUid: roomUid, time: new Date().getTime() })
           } catch (error) {
             // console.log(error)
             removeToken()