dusenyao 3 tahun lalu
induk
melakukan
f888fbaed6

+ 45 - 0
src/api/live.js

@@ -225,3 +225,48 @@ export function StopGroup(data) {
     data
   });
 }
+
+/**
+ * 加入分组(教师端)
+ * @param {Object} data {task_id 任务ID, group_id 小组ID}
+ */
+export function JoinGroup_Teacher(data) {
+  let params = getRequestParams('live_room-live_room_dispatch-JoinGroup_Teacher');
+
+  return request({
+    method: 'post',
+    url: process.env.VUE_APP_LearnWebSI,
+    params,
+    data
+  });
+}
+
+/**
+ * 退出当前分组(教师端)
+ * @param {Object} data {task_id 任务ID}
+ */
+export function ExitCurGroup_Teacher(data) {
+  let params = getRequestParams('live_room-live_room_dispatch-ExitCurGroup_Teacher');
+
+  return request({
+    method: 'post',
+    url: process.env.VUE_APP_LearnWebSI,
+    params,
+    data
+  });
+}
+
+/**
+ * 得到我加入的分组信息(教师端)
+ * @param {Object} data {task_id 任务ID}
+ */
+export function GetMyGroupInfo_Teacher(data) {
+  let params = getRequestParams('live_room-live_room_dispatch-GetMyGroupInfo_Teacher');
+
+  return request({
+    method: 'post',
+    url: process.env.VUE_APP_LearnWebSI,
+    params,
+    data
+  });
+}

+ 5 - 2
src/views/live/student/group.js

@@ -81,6 +81,7 @@ export function initListener(vue) {
           }
           if (streamType === 0) {
             stream.show('live', 'contain'); // 将流显示到指定 id 的元素中
+            vue.is_teacher_in_group = true;
           }
         },
         fail: function (err) {
@@ -155,7 +156,9 @@ export function initListener(vue) {
   // 监听通知移除流事件
   rtc.on('stream_removed', stream => {
     console.log('监听通知移除流事件');
-    console.log(stream.id());
+    if (stream.streamType() === 0) {
+      vue.is_teacher_in_group = false;
+    }
     let num = vue.streamList.findIndex(el => el.id() === stream.id());
     if (num !== -1) {
       vue.streamList.splice(num, 1);
@@ -190,7 +193,7 @@ export function initListener(vue) {
     // 创建本地流推流
     console.log('创建本地流推流');
     const createData = {
-      video: true,
+      video: false,
       audio: true
     };
     rtc.createLocalStream({

+ 15 - 5
src/views/live/student/group.vue

@@ -66,8 +66,13 @@
           @mouseover="liveMenuShow = true"
           @mouseout="liveMenuShow = false"
         >
-          <div id="live">
-            <el-image v-if="!teacherExist" :src="roomInfo.teacher_image_url" fit="contain" />
+          <div class="live-container">
+            <div v-show="is_teacher_in_group" id="live" />
+            <el-image
+              v-show="!is_teacher_in_group"
+              :src="roomInfo.teacher_image_url"
+              fit="contain"
+            />
           </div>
           <div :style="{ bottom: liveMenuShow ? '0' : '-40px' }" class="live-wrapper">
             <div>
@@ -107,7 +112,6 @@ export default {
     return {
       task_id: this.$route.query.task_id,
       room_user_id: this.$route.query.live_room_sys_user_id,
-      teacherExist: false,
       // 定时器
       timer: null,
       rtc: null,
@@ -145,7 +149,8 @@ export default {
       student_list: [],
       // 直播状态
       liveStat: false,
-      liveMenuShow: false
+      liveMenuShow: false,
+      is_teacher_in_group: false
     };
   },
   watch: {
@@ -446,11 +451,16 @@ $live-bc: #3d3938;
         position: relative;
         overflow: hidden;
 
-        #live {
+        .live-container {
           width: 352px;
           height: 198px;
           background-color: $live-bc;
 
+          #live {
+            width: 100%;
+            height: 100%;
+          }
+
           .el-image {
             width: 100%;
             height: 100%;

+ 42 - 14
src/views/live/teacher/group.js

@@ -1,12 +1,12 @@
 import { Message } from 'element-ui';
-import { rtc, updateMcResult } from '@/views/live/common';
+import { rtc, updateMcResult, createScript } from '@/views/live/common';
 export {
   initSDK,
-  downloadWebSDK,
   sendMsg,
   getDevice,
   sendPublishMessage,
-  closeVideo
+  closeVideo,
+  roomUpdate
 } from '@/views/live/common';
 
 /**
@@ -56,6 +56,21 @@ function createLocalStream() {
 }
 
 /**
+ * 取消订阅远程流
+ */
+export function unSubscribeStream(stream) {
+  rtc.unSubscribeStream({
+    unSubStream: stream,
+    success: function (str) {
+      console.log('取消订阅流成功', str);
+    },
+    fail: function (str) {
+      console.log(str);
+    }
+  });
+}
+
+/**
  * 初始化监听事件
  */
 export function initListener(vue) {
@@ -98,8 +113,11 @@ export function initListener(vue) {
         success: function (stream) {
           // 订阅流成功
           let streamType = stream.streamType();
+
           console.log('订阅流成功', streamType);
-          stream.show('student', 'contain'); // 将流显示到指定 id 的盒子中
+          if (streamType === 10) {
+            vue.streamList.push(stream);
+          }
         },
         fail: function (err) {
           console.log('订阅流失败', err);
@@ -170,21 +188,16 @@ export function initListener(vue) {
   // 监听通知移除流事件
   rtc.on('stream_removed', stream => {
     console.log('监听通知移除流事件');
+    let num = vue.streamList.findIndex(el => el.id() === stream.id());
+    if (num !== -1) {
+      vue.streamList.splice(num, 1);
+    }
   });
 
   // 停止订阅流
   rtc.on('unSub', function (stream) {
     console.log('停止订阅流', stream);
-    rtc.unSubscribeStream({
-      unSubStream: stream,
-      success: function (stream) {
-        console.log('取消订阅流成功', stream.id());
-      },
-
-      fail: function (str) {
-        console.log(str);
-      }
-    });
+    unSubscribeStream(stream);
   });
 
   // 用户退出房间通知其他人员事件
@@ -231,3 +244,18 @@ export function initListener(vue) {
     });
   });
 }
+
+// 加载直播所需 SDK,加载完成后才能初始化
+export function downloadWebSDK(vue) {
+  createScript('https://class.csslcloud.net/sdk/websdk/hdRtc-6.7.2.js').onload = () => {
+    let scriptArray = [
+      'https://class.csslcloud.net/static/dist/js/classMode.js',
+      'https://class.csslcloud.net/static/dist/js/classUpdateChat.js'
+    ];
+    for (let i = 0; i < scriptArray.length; i++) {
+      createScript(scriptArray[i]).onload = () => {
+        vue.loadedNumber += 1;
+      };
+    }
+  };
+}

+ 107 - 25
src/views/live/teacher/group.vue

@@ -6,6 +6,7 @@
         <div class="live-title-name">{{ roomInfo.cs_item_name }} {{ roomInfo.task_name }}</div>
         <div>
           <el-button @click="stopGroup">结束群组讨论</el-button>
+          <el-button v-show="isGroup" @click="exitCurGroup_Teacher">退出小组讨论</el-button>
         </div>
       </div>
       <div class="live-course-name">{{ roomInfo.course_name }}</div>
@@ -20,9 +21,9 @@
     <div class="live-container">
       <!-- 左侧 -->
       <div class="live-container-left">
-        <div class="group">
+        <div v-show="!isGroup" class="group">
           <template v-for="(item, i) in group_list">
-            <div :key="item.room_id" class="group-list">
+            <div :key="item.room_id" class="group-list" @click="enterGroup(item.group_id)">
               <div class="group-serial">{{ i + 1 }}</div>
               <div class="group-list-avatar">
                 <el-avatar
@@ -35,6 +36,14 @@
             </div>
           </template>
         </div>
+        <div v-show="isGroup" class="group-discussion">
+          <div
+            v-for="(item, i) in streamList"
+            :id="`group-${i}`"
+            :key="item.id()"
+            class="group-box"
+          ></div>
+        </div>
         <div class="button-group">
           <div class="button-group-left">
             <span class="stop-group" @click="stopGroup">结束群组讨论</span>
@@ -89,15 +98,25 @@
         <div class="student-list">
           <div class="student-list-title">小组列表</div>
           <ul>
-            <template v-for="item in group_list">
-              <li v-for="el in item.student_list" :key="el.student_id">
+            <template v-if="isGroup">
+              <li v-for="item in student_list" :key="item.room_user_id">
                 <div class="student-list-left">
-                  <el-avatar icon="el-icon-user" size="small" :src="el.student_image_url" />
-                  <span class="name">{{ el.student_name }}</span>
+                  <el-avatar icon="el-icon-user" size="small" :src="item.student_image_url" />
+                  <span class="name">{{ item.student_name }}</span>
                 </div>
-                <div class="student-list-right"></div>
               </li>
             </template>
+            <template v-else>
+              <template v-for="item in group_list">
+                <li v-for="el in item.student_list" :key="el.student_id">
+                  <div class="student-list-left">
+                    <el-avatar icon="el-icon-user" size="small" :src="el.student_image_url" />
+                    <span class="name">{{ el.student_name }}</span>
+                  </div>
+                  <div class="student-list-right"></div>
+                </li>
+              </template>
+            </template>
           </ul>
         </div>
       </div>
@@ -111,14 +130,18 @@ import {
   StudentExitLiveRoom,
   StopGroup,
   GetGroupInfo_Teacher,
-  CreateEnterLiveRoomSession
+  CreateEnterLiveRoomSession,
+  JoinGroup_Teacher,
+  ExitCurGroup_Teacher,
+  GetMyGroupInfo_Teacher
 } from '@/api/live';
-import * as common from './live';
+import * as common from './group';
 
 export default {
   data() {
     return {
       task_id: this.$route.query.task_id,
+      isGroup: false,
       // 定时器
       timer: null,
       rtc: null,
@@ -155,29 +178,39 @@ export default {
       live_room_sys_user_id: '',
       // 直播状态
       liveStat: false,
-      liveMenuShow: false
+      liveMenuShow: false,
+      room_id: '',
+      session_id: '',
+      streamList: [],
+      student_list: []
     };
   },
   watch: {
     loadedNumber(newVal) {
-      if (newVal === 5) {
-        common.createScript(
-          'https://class.csslcloud.net/static/SDK/docSDK/drawSdk_3.0.js'
-        ).onload = () => {
-          const { room_id, session_id } = this.$route.query;
-          this.rtc = common.initSDK({
-            userid: this.live_room_sys_user_id,
-            roomid: room_id,
-            sessionid: session_id
-          });
-          common.initListener(this); // 注册监听事件
-          this.$loading().close();
-        };
+      if (newVal === 2) {
+        console.log(this.room_id);
+        if (!this.room_id || !this.session_id) {
+          return;
+        }
+        console.log(1);
+        this.rtc = common.initSDK({
+          userid: this.live_room_sys_user_id,
+          roomid: this.room_id,
+          sessionid: this.session_id
+        });
+        common.initListener(this); // 注册监听事件
+        this.loadedNumber = 0;
+      }
+    },
+    streamList(newVal) {
+      if (newVal.length > 0) {
+        this.$nextTick(() => {
+          newVal[newVal.length - 1].show(`group-${newVal.length - 1}`);
+        });
       }
     }
   },
   created() {
-    // common.downloadWebSDK(this);
     this.getLiveRoomInfo();
     GetGroupInfo_Teacher({ task_id: this.task_id }).then(
       ({ live_room_sys_user_id, group_list }) => {
@@ -187,8 +220,10 @@ export default {
     );
   },
   beforeDestroy() {
-    clearInterval(this.timer);
     common.closeVideo('main');
+    this.streamList.forEach(item => {
+      common.unSubscribeStream(item);
+    });
   },
   methods: {
     getLiveRoomInfo() {
@@ -256,6 +291,35 @@ export default {
           });
         });
       });
+    },
+
+    enterGroup(group_id) {
+      JoinGroup_Teacher({ task_id: this.task_id, group_id })
+        .then(({ room_id, session_id }) => {
+          console.log(room_id, session_id);
+          this.room_id = room_id;
+          this.session_id = session_id;
+          common.downloadWebSDK(this);
+          this.isGroup = true;
+          return GetMyGroupInfo_Teacher({ task_id: this.task_id });
+        })
+        .then(({ student_list }) => {
+          this.student_list = student_list;
+        });
+    },
+
+    exitCurGroup_Teacher() {
+      ExitCurGroup_Teacher({ task_id: this.task_id }).then(() => {
+        this.isGroup = false;
+        this.room_id = '';
+        this.session_id = '';
+        common.closeVideo('main');
+        this.streamList.forEach(item => {
+          common.unSubscribeStream(item);
+        });
+        this.streamList = [];
+        this.$message.success('退出小组讨论成功');
+      });
     }
   }
 };
@@ -334,6 +398,7 @@ $live-bc: #3d3938;
           width: 253px;
           height: 144px;
           margin-right: 8px;
+          cursor: pointer;
 
           &-avatar {
             display: flex;
@@ -358,6 +423,23 @@ $live-bc: #3d3938;
         }
       }
 
+      // 分组讨论
+      .group-discussion {
+        display: flex;
+        flex-wrap: wrap;
+        width: 100%;
+        height: 468px;
+        position: relative;
+        background-color: $live-bc;
+        overflow: hidden;
+
+        .group-box {
+          width: 256px;
+          height: 144px;
+          margin: 8px;
+        }
+      }
+
       .button-group {
         display: flex;
         justify-content: space-between;