lex-xin 3 年之前
父节点
当前提交
17bedcbc07

+ 1 - 1
src/components/empty/index.module.less

@@ -4,7 +4,7 @@
   text-align: center;
   color: #A4A6A9;
   font-size: 14px;
-  padding-top: 20px;
+  padding: 20px 0;
   .icon {
     width: 126px;
     height: 89px;

+ 8 - 2
src/components/live-broadcast/action-bar.tsx

@@ -7,7 +7,13 @@ export default defineComponent({
   name: 'LiveBroadcast-ActionBar',
   data() {
     return {
-      volume: 20,
+      volume: 30,
+    }
+  },
+  methods: {
+    volumeChange(value: number) {
+      this.volume = value
+      RuntimeUtils.setVolume(value)
     }
   },
   render() {
@@ -46,7 +52,7 @@ export default defineComponent({
               dropdown: () => (
                 <div class={styles.volumeSlider}>
                   <SvgIcon class={styles.volumeIcon} name="message-voice" color="#fff" />
-                  <ElSlider modelValue={this.volume} size="small" input-size="small" />
+                  <ElSlider modelValue={this.volume} onInput={this.volumeChange} size="small" />
                 </div>
               )
             }}

+ 12 - 0
src/components/live-broadcast/runtime.ts

@@ -72,6 +72,7 @@ const Events = RongIMLib.Events
  */
  const { MESSAGES, ...RestMessage } = Events
  RongIMLib.addEventListener(Events.MESSAGES, (evt: MessageEvent) => {
+   console.log(evt, '收到消息')
    const { messages } = evt
    for (const message of messages) {
      if (LIVE_EVENT_MESSAGE[message.messageType]) {
@@ -118,6 +119,17 @@ const Events = RongIMLib.Events
  }
 
 /**
+ * 设置声音
+ * @param video
+ * @param Value 声音大小
+ */
+export const setVolume = (value: number) => {
+  if(runtime.videoRef) {
+    runtime.videoRef.volume = value / 100
+  }
+}
+
+/**
  * 设置video视频流
  */
 

+ 82 - 24
src/components/live-message/item-list.tsx

@@ -8,6 +8,17 @@ import Empty from "../empty";
 import LookModel from './model/look-model';
 import JoinModel from './model/join-model';
 import MessageModel from './model/message-model';
+import { state } from '/src/state'
+const svg = `
+        <path class="path" d="
+          M 30 15
+          L 28 17
+          M 25.61 25.61
+          A 15 15, 0, 0, 1, 15 30
+          A 15 15, 0, 1, 1, 27.99 7.5
+          L 15 15
+        " style="stroke-width: 4px; fill: rgba(0, 0, 0, 0)"/>
+      `
 
 type itemType = 'message' | 'join' | 'look'
 
@@ -20,52 +31,99 @@ export default defineComponent({
   },
   data() {
     return {
-      lookList: [] as any[],
+      messageList: [] as any[], // 回复学生列表
+      joinList: [] as any[], // 连麦学生列表
+      lookList: [] as any[], // 观看学生列表
     }
   },
   mounted() {
     event.on(LIVE_EVENT_MESSAGE["RC:Chatroom:Welcome"], this.onWelcome);
-    event.on(LIVE_EVENT_MESSAGE["RC:TxtMsg"], this.onmessage);
+    event.on(LIVE_EVENT_MESSAGE["RC:TxtMsg"], this.onMessage);
   },
   methods: {
-    onmessage(val: any) {
-      console.log(val);
+    onMessage(value: any) {
+      if (value && value.user) {
+        console.log(state.user)
+        console.log(value)
+        const sendTime = dayjs(value.$EventMessage.sentTime || new Date()).format('HH:mm:ss')
+
+        let tempObj = {
+          name: value.user?.name,
+          id: value.user.id,
+          isSelf: false,
+          content: value.content,
+          sendTime
+        }
+        // 判断是否是主播
+        if (value.user.id === state.user.id) {
+          tempObj.isSelf = true
+        }
+        this.messageList.push(tempObj);
+      }
+      console.log(this.messageList)
     },
     onWelcome(value: any) {
       console.log(value)
-      const sendTime = dayjs(value.$EventMessage.sentTime || new Date()).format('HH:mm:ss')
-      let tempObj = {
-        name: value.user.name,
-        id: value.user.id,
-        sendTime
+      if (value && value.user) {
+        const sendTime = dayjs(value.$EventMessage.sentTime || new Date()).format('HH:mm:ss')
+        let tempObj = {
+          name: value.user.name,
+          id: value.user.id,
+          sendTime
+        }
+        // 判断是否有同一个人
+        let isExist = false;
+        this.lookList.forEach((item: any) => {
+          if (item.id === tempObj.id) {
+            isExist = true
+          }
+        })
+        if (!isExist) {
+          this.lookList.push(tempObj);
+        }
       }
-      this.lookList.push(tempObj);
     }
   },
   beforeUnmount() {
     event.off(LIVE_EVENT_MESSAGE["RC:Chatroom:Welcome"], this.onmessage);
     event.off(LIVE_EVENT_MESSAGE["RC:TxtMsg"], this.onmessage);
   },
+  computed: {
+    loading() {
+      switch (this.type) {
+        case 'message':
+          return this.messageList.length === 0
+        case 'join':
+          return this.joinList.length === 0
+        case 'look':
+          return this.lookList.length === 0
+        default:
+          return false
+      }
+    }
+  },
   render() {
     return (
-      <div>
-        { this.type === 'message' ?
-          this.lookList && this.lookList.length > 0 ? this.lookList.map(item => (
-            <MessageModel />
-          )) : <Empty text="暂无学员互动!" icon="noData-no-message" />
-        : null }
+      <div style={{ minHeight: '100%' }} v-loading={this.loading} element-loading-spinner={svg}
+        element-loading-svg-view-box="-10, -10, 50, 50"
+        element-loading-background="rgba(0, 0, 0, 0.8)">
+        {this.type === 'message' ?
+          this.messageList && this.messageList.length > 0 ? this.messageList.map(item => (
+            <MessageModel data={this.messageList} />
+          )) : this.loading ? null : <Empty text="暂无学员互动!" icon="noData-no-message" />
+          : null}
 
-        { this.type === 'join' ?
-          this.lookList && this.lookList.length > 0 ? this.lookList.map(item => (
-            <JoinModel />
-          )) : <Empty text="暂无学员发起连麦!" icon="noData-no-join" />
-        : null }
+        {this.type === 'join' ?
+          this.joinList && this.joinList.length > 0 ? this.joinList.map(item => (
+            <JoinModel data={this.joinList} />
+          )) : this.loading ? null : <Empty text="暂无学员发起连麦!" icon="noData-no-join" />
+          : null}
 
-        { this.type === 'look' ?
+        {this.type === 'look' ?
           this.lookList && this.lookList.length > 0 ? this.lookList.map(item => (
             <LookModel data={this.lookList} />
-          )) : <Empty text="暂无学员观看!" icon="noData-no-user" />
-        : null }
+          )) : this.loading ? null : <Empty text="暂无学员观看!" icon="noData-no-user" />
+          : null}
       </div>
     )
   }

+ 3 - 0
src/components/live-message/model/index.module.less

@@ -45,6 +45,9 @@
 .itemText {
   font-size: 14px;
   line-height: 20px;
+  &.active {
+    color: #00D6C9;
+  }
 }
 
 .joinText {

+ 5 - 4
src/components/live-message/model/message-model.tsx

@@ -1,4 +1,5 @@
 import { defineComponent } from "vue";
+import { ElTag } from "element-plus";
 import styles from './index.module.less'
 
 export default defineComponent({
@@ -16,11 +17,11 @@ export default defineComponent({
             <img src="/src/assets/home/placehorder-icon.png" alt="" />
             <div class={styles.itemInfo}>
               <div class={styles.itemName}>
-                <p class={styles.userName}>唐老师 <ElTag >主播</ElTag></p>
-                <p class={styles.rightTime}>18:30:00</p>
+                <p class={styles.userName}>{item.name} {item.isSelf ? <ElTag>主播</ElTag> : null}</p>
+                <p class={styles.rightTime}>{ item.sendTime }</p>
               </div>
-              <div class={styles.itemText}>
-                请问老师,我在乐团学习长笛已经2年了,目前可以把1-4级都熟练吹奏,接下来要怎么继续提高呢?
+              <div class={[styles.itemText, item.isSelf ? styles.active : null]}>
+                { item.content }
               </div>
             </div>
           </div>

+ 3 - 2
src/helpers/request.ts

@@ -60,6 +60,7 @@ request.interceptors.response.use(async (res, options) => {
   setTimeout(() => {
     hideLoading()
   }, 200)
+  console.log(res, options, 'res')
   const url = new URL(res.url)
   if (res.status > 299 || res.status < 200) {
     const msg = '服务器错误,状态码' + res.status
@@ -71,8 +72,8 @@ request.interceptors.response.use(async (res, options) => {
     const msg = data.msg || '处理失败,请重试'
     if(data.code === 401 || data.code === 403) {
       ElMessage.error(`登录过期,请重新登录!`)
-      removeToken()
-      router.push('/login')
+      const url = window.location.href.split('#')[0]
+      router.push(`/login?redirect=${url}`)
     }
     if(data.code === 404) {
       ElMessage.error(`请求资源不存在!`)

+ 52 - 1
src/main.ts

@@ -1,5 +1,5 @@
 import { createApp } from 'vue'
-import ElementPlus from 'element-plus'
+import ElementPlus, { MessageParamsTyped } from 'element-plus'
 import 'virtual:svg-icons-register'
 import 'element-plus/dist/index.css'
 import App from './App.vue'
@@ -10,6 +10,57 @@ import './permission'
 // import './icons' // icon
 import './base.css'
 
+import {
+  ElMessage
+} from 'element-plus'
+const showMessage = Symbol('showMessage')
+class DonMessage {
+  success(options: any, single = true) {
+    this[showMessage]('success', options, single)
+  }
+  warning(options: any, single = true) {
+    this[showMessage]('warning', options, single)
+  }
+  info(options: any, single = true) {
+    this[showMessage]('info', options, single)
+  }
+  error(options: any, single = true) {
+      this[showMessage]('error', options, single)
+  }
+  [showMessage](type: any, options: any, single: any) {
+    let params = {
+      message: options,
+      offset: 90
+    }
+    if (single) {
+      // 判断是否已存在Message
+      if (document.getElementsByClassName('el-message').length === 0) {
+        messageAction(type, options)
+      }
+    } else {
+      messageAction(type, options)
+    }
+  }
+}
+function messageAction(type: any, options: MessageParamsTyped | undefined) {
+  switch (type) {
+    case 'success':
+      ElMessage.success(options)
+      break
+    case 'warning':
+      ElMessage.warning(options)
+      break
+    case 'info':
+      ElMessage.info(options)
+      break
+    case 'error':
+      ElMessage.error(options)
+      break
+  }
+}
+// 命名根据需要,DonMessage只是在文章中使用
+// export const $message = new DonMessage()
+
 createApp(App)
   .use(ElementPlus)
   .use(SvgIcon)

+ 7 - 0
src/pages/home/header/index.tsx

@@ -3,14 +3,21 @@ import { ElDropdownMenu, ElDropdown, ElDropdownItem, ElMessage } from "element-p
 import router from "/src/router";
 import styles from './index.module.less';
 import request from '/src/helpers/request';
+import runtime from "/src/components/live-broadcast/runtime";
 import { removeToken } from "/src/utils/auth";
+import { removeMedia } from '/src/components/live-broadcast/helpers'
 
 export default defineComponent({
   methods: {
     async loginOut() {
       try {
         await request.post('/api-auth/exit', { data: {} });
+        removeMedia(runtime.mediaStreams, runtime.mediaStreamTrack)
+        runtime.activeTracks.camera?.destroy()
+        runtime.activeTracks.microphone?.destroy()
         ElMessage.success('退出成功');
+        // console.log(this)
+        // this.$message.success('退出成功');
         removeToken();
         (this as any).$router.push('/login');
       } catch(e) {

二进制
src/pages/login/images/login-bg.jpg


+ 1 - 1
src/pages/login/index.module.less

@@ -159,7 +159,7 @@ body {
   display: flex;
   align-items: center;
   justify-content: center;
-  // background: url("./images/login-bg.png") no-repeat center left #202129;
+  background: url("./images/login-bg.jpg") no-repeat center left #202129;
   background-color: #202129;
   background-size: cover;
 

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

@@ -37,11 +37,14 @@ export default defineComponent({
         ]
       },
       passwordType: "password",
-      redirect: undefined,
+      redirect: undefined as any,
       isSaveUserInfo: true
     }
   },
   mounted() {
+    if (this.$route.query.redirect) {
+      this.redirect = this.$route.query.redirect;
+    }
     this.loginForm.username = localStorage.getItem('username');
     this.loginForm.password = localStorage.getItem('password');
   },
@@ -82,7 +85,8 @@ export default defineComponent({
             console.log(token);
             setToken(token)
             ElMessage.success('登录成功')
-            this.$router.push({ path: "/home" });
+            this.$router.push(this.redirect || '/')
+            // this.$router.push({ path: "/home" });
             console.log(res)
           } catch (error) {
             // console.log(error)

+ 3 - 1
src/permission.ts

@@ -44,6 +44,7 @@ router.beforeEach(async (to, from, next) => {
             ElMessage.error(error.msg);
           }
           removeToken();
+          // ?redirect=${to.fullPath}
           next(`/login`);
           NProgress.done();
         }
@@ -56,7 +57,8 @@ router.beforeEach(async (to, from, next) => {
       next();
     } else {
       // other pages that do not have permission to access are redirected to the login page.
-      next(`/login`);
+      next(`/login?redirect=${to.fullPath}`);
+      NProgress.done();
     }
   }
 });