dusenyao 3 лет назад
Родитель
Сommit
0d3669c342

+ 1 - 1
.eslintrc.js

@@ -329,7 +329,7 @@ module.exports = {
     'block-scoped-var': 0,
     'computed-property-spacing': [0, 'never'],
     'consistent-return': 0,
-    'consistent-this': [2, 'that'],
+    'consistent-this': 0,
     'default-case': 0,
     'dot-notation': [
       0,

+ 3 - 0
src/icons/svg/hang-up.svg

@@ -0,0 +1,3 @@
+<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M20.4655 15.8529C20.2138 16.1045 19.8455 16.1999 19.5034 16.102L17.1299 15.4231C16.8191 15.3342 16.5721 15.0977 16.4699 14.791L15.6537 12.3422C15.6537 12.3422 14.201 11.3626 12.221 11.3626C10.2411 11.3627 8.79655 12.3423 8.79655 12.3423L7.9804 14.7906C7.87813 15.0975 7.63095 15.3341 7.3199 15.4229L4.93838 16.1025C4.59633 16.2001 4.22835 16.1047 3.97687 15.8532L2.21973 14.096C1.32489 13.2012 1.50977 11.7237 2.64372 11.162C4.97267 10.0082 8.79447 8.42385 12.221 8.42389C15.6476 8.42389 19.4694 10.0082 21.7983 11.162C22.9323 11.7238 23.1171 13.2012 22.2223 14.096L20.4655 15.8529Z" stroke="white" stroke-width="1.46939" stroke-linejoin="round"/>
+</svg>

+ 11 - 27
src/router/index.js

@@ -18,6 +18,7 @@ const routes = [
     path: '/404',
     component: () => import('@/views/404')
   },
+  // 外部跳转
   {
     path: '/EnterSys',
     beforeEnter: (to, from, next) => {
@@ -37,6 +38,7 @@ const routes = [
         });
     }
   },
+  // 首页
   {
     path: '/',
     component: Layout,
@@ -63,6 +65,7 @@ const routes = [
       }
     ]
   },
+  // 新建课程 分步表单
   {
     path: '/create_course_step_table',
     component: Layout,
@@ -91,6 +94,7 @@ const routes = [
       }
     ]
   },
+  // 课程列表 -> 学生列表
   {
     path: '/student_list',
     component: Layout,
@@ -102,39 +106,19 @@ const routes = [
       }
     ]
   },
-  // {
-  //   path: '/cs_item_detail',
-  //   component: Layout,
-  //   redirect: '/cs_item_detail/index/:id',
-  //   children: [
-  //     {
-  //       path: '/cs_item_detail/index/:id',
-  //       name: 'CSItemDetail',
-  //       component: () => import('@/views/teacher/cs_item_detail')
-  //     }
-  //   ]
-  // },
-  // {
-  //   path: '/add_course',
-  //   component: Layout,
-  //   redirect: '/add_course/index',
-  //   children: [
-  //     {
-  //       path: '/add_course/index',
-  //       name: 'AddCourse',
-  //       component: () => import('@/views/teacher/add_course')
-  //     }
-  //   ]
-  // },
+  // 直播
   {
     path: '/live',
     component: Layout,
-    redirect: '/live/teacher',
+    redirect: '/live/student',
     children: [
       {
         path: '/live/teacher',
-        name: 'TeacherLive',
-        component: () => import('@/views/live')
+        component: () => import('@/views/live/teacher')
+      },
+      {
+        path: '/live/student',
+        component: () => import('@/views/live/student')
       }
     ]
   },

+ 217 - 0
src/views/live/common.js

@@ -0,0 +1,217 @@
+import { Message } from 'element-ui';
+
+/**
+ * WebSDK 实例化对象
+ */
+export let rtc;
+
+/**
+ * 初始化SDK方法
+ * @param { Object } data 初始化SDK所需参数
+ * @returns { Object } Rtc
+ */
+export function initSDK(data) {
+  rtc = new Rtc(data);
+  return rtc;
+}
+
+/**
+ * 查询直播是否开启
+ */
+export function getLiveStat(obj) {
+  rtc.getLiveStat(obj);
+}
+
+/**
+ * 下麦操作
+ * @param { String } uid
+ */
+export function handsDown(Object) {
+  rtc.handsDown(Object);
+}
+
+/**
+ * 上麦更新
+ * @param { Object } stream
+ */
+function updateMcResult(stid, pid) {
+  // 上麦更新是在两种情况下执行
+  // 1.推流成功之后将自己的麦序更新为3;系统会广播 speak_context 事件,其他用户监听该事件后更新对应的业务展示状态;
+  // 2.不能创建本地流或者推流失败,更新自己的麦序为0。
+  rtc.updateMcResult({
+    pid,
+    stid,
+    success: function (data) {
+      console.log('更新上麦结果请求成功,此处可处理应用层逻辑', data);
+    },
+    fail: function (data) {
+      console.log('更新上麦结果请求失败:' + JSON.stringify(data));
+    }
+  });
+}
+
+/**
+ * 推送本地流
+ */
+export function publishStream(streamName) {
+  rtc.publish({
+    streamName,
+    // 推流成功,更新上麦结果
+    success: stream => {
+      console.log('推流成功', stream);
+      updateMcResult(stream.id(), 1);
+    },
+    fail: str => {
+      // 推流失败,更新上麦结果
+      console.log('推流失败,更新上麦结果', str);
+      updateMcResult('', 0);
+    }
+  });
+}
+
+/**
+ * 创建本地流
+ */
+export function createLocalStream() {
+  const createData = {
+    video: true,
+    audio: true
+  };
+  rtc.createLocalStream({
+    streamName: 'main',
+    createData,
+    success: function (stream) {
+      console.log('创建本地流成功', stream);
+      // 创建本地流成功,将流展示到id为 live 的dom元素盒子中
+      stream.show('live');
+      publishStream('main'); // 如果需要立即推流,执行 publish 方法
+    },
+    fail: function (data) {
+      // 创建本地流失败,应用层处理
+      Message({
+        type: 'error',
+        message: '创建本地流失败:' + data
+      });
+    }
+  });
+}
+
+/**
+ * 结束本地流
+ */
+export function closeVideo(streamName) {
+  rtc.closeVideo({
+    streamName,
+    success: function () {
+      console.log('结束本地流成功');
+    },
+    fail: function (str) {
+      console.log(str);
+    }
+  });
+}
+
+/**
+ * 关闭本地流声音
+ */
+export function pauseAudio() {
+  rtc.pauseAudio({
+    streamName: 'main',
+    success: function () {
+      console.log('关闭本地流声音成功');
+    },
+    fail: function (str) {
+      console.log(str);
+    }
+  });
+}
+
+/**
+ * 开启本地流声音
+ */
+export function playAudio() {
+  rtc.playAudio({
+    streamName: 'main',
+    success: function (data) {
+      console.log(data);
+      console.log('开启本地流声音成功');
+    },
+    fail: function (str) {
+      console.log(str);
+    }
+  });
+}
+
+/**
+ * 关闭本地流视频画面
+ */
+export function pauseVideo() {
+  rtc.pauseVideo({
+    streamName: 'main',
+    success: function () {
+      console.log('关闭本地流视频画面成功');
+    },
+    fail: function (str) {
+      console.log(str);
+    }
+  });
+}
+
+/**
+ * 开启本地流视频画面
+ */
+export function playVideo() {
+  rtc.playVideo({
+    streamName: 'main',
+    success: function () {
+      console.log('开启本地流视频画面成功');
+    },
+    fail: function (str) {
+      console.log(str);
+    }
+  });
+}
+
+/**
+ * 获取设备列表
+ */
+export function getDevice() {
+  rtc.getDevice({
+    success: function (data) {
+      console.log('获取成功', data);
+    },
+    fail: function (str) {
+      console.log('直播关闭状态或查询直播失败', str);
+    }
+  });
+}
+
+/**
+ * 房间配置项更新
+ * @param {Object} option 房间配置项 (具体看2.0 https://doc.bokecc.com/class/developer/web/chat.html),以键值对的形式传
+ */
+export function roomUpdate(option) {
+  rtc.roomUpdate(option);
+}
+
+// 聊天组件
+
+/**
+ * 发送聊天
+ * @param {String} msg length不能超过 400
+ */
+export function sendMsg(msg) {
+  rtc.sendMsg(msg);
+}
+
+// 文档
+
+/**
+ * 变更画笔
+ */
+export function drawChange(action, value) {
+  rtc.drawChange({
+    action,
+    value
+  });
+}

+ 710 - 0
src/views/live/student/index.vue

@@ -0,0 +1,710 @@
+<template>
+  <div class="live">
+    <!--顶部-->
+    <div class="live-top">
+      <div class="live-title">
+        <div class="live-title-name">{{ roomInfo.cs_item_name }} {{ roomInfo.task_name }}</div>
+        <div>
+          <el-button @click="exitRoom">退出房间</el-button>
+        </div>
+      </div>
+      <div class="live-course-name">{{ roomInfo.course_name }}</div>
+      <div class="live-teacher">
+        <span class="live-teacher-name">
+          <svg-icon icon-class="person" />{{ roomInfo.teacher_name }}
+        </span>
+        <span><svg-icon icon-class="people" />{{ roomInfo.student_count }}</span>
+      </div>
+    </div>
+    <!-- 主容器 -->
+    <div class="live-container">
+      <!-- 左侧 -->
+      <div class="live-container-left">
+        <div v-show="callLoading" class="loading">
+          <div class="loading-wrapper">
+            <p class="loading-title">教师邀请您连麦中</p>
+            <div>
+              <!-- <el-button
+                type="success"
+                icon="el-icon-phone-outline"
+                circle
+                @click="inviteAccept"
+              ></el-button> -->
+            </div>
+          </div>
+        </div>
+        <div v-show="connect" id="student"></div>
+        <div v-show="isDraw" id="draw-parent">
+          <div v-show="isDrawSetting" class="draw-setting">
+            <span class="brush-shape">
+              <svg-icon icon-class="brush-shape" />
+            </span>
+            <span
+              v-for="item in drawColorList"
+              :key="item"
+              :class="['draw-color', item === '#FF4747' ? 'current' : '']"
+              :style="{ 'background-color': item }"
+            ></span>
+            <span v-for="item in drawThicknessList" :key="item" class="draw-thickness">
+              <span :style="{ width: item * 2 + 'px', height: item * 2 + 'px' }"></span>
+            </span>
+            <span class="brush-clear">
+              <svg-icon icon-class="clear" />
+            </span>
+          </div>
+        </div>
+        <div class="button-group">
+          <div class="button-group-left"></div>
+          <div class="button-group-right"></div>
+        </div>
+        <div class="live-container-left-chat">
+          <div class="chat-top">
+            <span>聊天</span>
+          </div>
+          <div class="chat-window">
+            <ul class="chat-window-ul">
+              <li v-for="(item, i) in chatList" :key="i">
+                <div class="msg-normal">
+                  <span>{{ item.username }}: </span>
+                  <span>{{ item.msg }}</span>
+                </div>
+              </li>
+            </ul>
+          </div>
+          <div class="chat-speak">
+            <el-input
+              v-model="msg"
+              placeholder="输入发言"
+              maxlength="400"
+              @keydown.enter.native="sendMsg"
+            >
+              <el-button slot="append" @click="sendMsg">发送</el-button>
+            </el-input>
+          </div>
+        </div>
+      </div>
+      <!-- 右侧 -->
+      <div class="live-container-right">
+        <div class="live-teacher-lens" @mouseover="liveWrapperOver" @mouseout="liveWrapperOut">
+          <div id="live"></div>
+          <div v-show="liveMenuShow" class="live-wrapper">
+            <div>
+              {{ roomInfo.teacher_name }}
+            </div>
+            <div></div>
+          </div>
+        </div>
+        <div class="student-list">
+          <div class="student-list-title">学生列表</div>
+          <ul>
+            <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="item.student_image_url" />
+                <span class="name">{{ item.student_name }}</span>
+              </div>
+            </li>
+          </ul>
+        </div>
+      </div>
+    </div>
+
+    <!-- 学员当前推送资料 -->
+    <cur-material
+      :task-id="task_id"
+      :dialog-visible-material="dialogVisibleMaterial"
+      :material-id="material_id"
+      :material-name="material_name"
+      :material-type="material_type"
+      :material-picture-url="material_picture_url"
+      @dialogMaterialClose="dialogMaterialClose"
+    />
+  </div>
+</template>
+
+<script>
+import {
+  GetLiveRoomStudentList,
+  StudentExitLiveRoom,
+  GetCurMaterialSent,
+  GetLiveRoomInfo
+} from '@/api/live';
+import CurMaterial from '@/components/live/CurMaterial.vue';
+import * as common from './live';
+
+export default {
+  name: 'Live',
+  components: {
+    CurMaterial
+  },
+  data() {
+    return {
+      task_id: this.$route.query.task_id,
+      room_user_id: this.$route.query.room_user_id,
+      // 已连接
+      connect: false,
+      // 等待接通
+      callLoading: false,
+      dialogVisibleMaterial: false,
+      // 资料信息
+      material_id: '',
+      material_name: '',
+      material_type: '',
+      material_picture_url: '',
+      // 定时器
+      timer: null,
+      rtc: null,
+      roomData: {
+        desc: '直播间标题',
+        name: '姓名',
+        user: {
+          id: '',
+          name: '',
+          role: 'talker',
+          rommid: ''
+        },
+        max_users: 1,
+        allow_chat: true,
+        allow_audio: true,
+        allow_speak: true
+      },
+      roomInfo: {
+        room_id: '',
+        video_mode: 1,
+        task_name: '',
+        cs_item_name: '',
+        course_name: '',
+        teacher_name: '',
+        student_count: 0
+      },
+      loadedNumber: 0,
+      speakData: {},
+      roomContext: {},
+      msg: '',
+      chatList: [],
+      isDrawSetting: false,
+      drawColorList: ['#FF4747', '#343434', '#628EFF', '#FFCA0E'],
+      drawThicknessList: ['1', '3', '5'],
+      // 直播间学员列表
+      student_list: [],
+      // 直播状态
+      liveStat: false,
+      liveMenuShow: false
+    };
+  },
+  computed: {
+    // 画板模式
+    isDraw() {
+      return !this.connect && !this.callLoading;
+    }
+  },
+  watch: {
+    loadedNumber(newVal) {
+      if (newVal === 5) {
+        this.initSDK();
+        this.$loading().close();
+      }
+    }
+  },
+  created() {
+    this.downloadWebSDK();
+    this.getLiveRoomStudentList();
+    this.getLiveRoomInfo();
+  },
+  mounted() {
+    this.getCurMaterialSent();
+    this.getLiveRoomStudentListPolling();
+  },
+  beforeDestroy() {
+    // 清除所有定时器
+    // let end = setInterval(() => {}, 1000);
+    // for (let i = 1; i <= end; i++) {
+    //   clearInterval(i);
+    // }
+    clearInterval(this.timer);
+    StudentExitLiveRoom({ task_id: this.task_id, room_user_id: this.room_user_id });
+  },
+  methods: {
+    // 加载直播所需 SDK,加载完成后才能初始化
+    downloadWebSDK() {
+      this.$loading({
+        text: '加载直播所需SDK中...',
+        background: '#fff'
+      });
+      let script = this.createScript('https://class.csslcloud.net/static/dist/js/websdk_4.0.js');
+      let link = this.createLink('https://class.csslcloud.net/static/SDK/docSDK/draw.css');
+
+      link.onload = () => {
+        this.loadedNumber += 1;
+      };
+
+      script.onload = () => {
+        let scriptArray = [
+          'https://class.csslcloud.net/static/dist/js/classMode.js',
+          'https://class.csslcloud.net/static/dist/js/classUpdateChat.js',
+          'https://image.csslcloud.net/js/dpc.js'
+        ];
+        for (let i = 0; i < scriptArray.length; i++) {
+          let classMode = this.createScript(scriptArray[i]);
+          classMode.onload = () => {
+            this.loadedNumber += 1;
+          };
+        }
+      };
+
+      let jq = this.createScript('https://class.csslcloud.net/static/js/jquery/jquery.min.js');
+      jq.onload = () => {
+        let classMode = this.createScript(
+          'https://class.csslcloud.net/static/SDK/docSDK/drawSdk_3.0.js'
+        );
+        classMode.onload = () => {
+          this.loadedNumber += 1;
+        };
+      };
+    },
+
+    createScript(url) {
+      let script = document.createElement('script');
+      script.type = 'text/javascript';
+      script.src = url;
+      document.getElementsByTagName('body')[0].appendChild(script);
+      return script;
+    },
+
+    createLink(url) {
+      let link = document.createElement('link');
+      link.rel = 'stylesheet';
+      link.href = url;
+      document.getElementsByTagName('body')[0].appendChild(link);
+      return link;
+    },
+
+    initSDK() {
+      const { live_room_sys_user_id, room_id, session_id } = this.$route.query;
+      this.rtc = common.initSDK({
+        userid: live_room_sys_user_id,
+        roomid: room_id,
+        sessionid: session_id
+      });
+      common.initListener(this); // 注册监听事件
+      window.rtc = this.rtc;
+      this.getLiveStat();
+    },
+
+    getLiveRoomInfo() {
+      GetLiveRoomInfo({ task_id: this.task_id }).then(
+        ({
+          room_id,
+          video_mode,
+          task_name,
+          cs_item_name,
+          course_name,
+          teacher_name,
+          student_count
+        }) => {
+          this.roomInfo = {
+            room_id,
+            video_mode,
+            task_name,
+            cs_item_name,
+            course_name,
+            teacher_name,
+            student_count
+          };
+        }
+      );
+    },
+
+    exitRoom() {
+      StudentExitLiveRoom({ task_id: this.task_id, room_user_id: this.room_user_id }).then(() => {
+        this.$router.push('/');
+      });
+    },
+
+    getLiveStat() {
+      common.getLiveStat({
+        success: data => {
+          this.liveStat = data.started;
+        },
+        fail: str => {
+          this.liveStat = false;
+          console.log('直播关闭状态或查询直播失败', str);
+        }
+      });
+    },
+
+    // 发消息
+    sendMsg() {
+      common.sendMsg(this.msg);
+      this.msg = '';
+    },
+
+    getDevice() {
+      common.getDevice();
+    },
+
+    inviteAccept() {
+      common.inviteAccept();
+    },
+
+    getLiveRoomStudentList() {
+      GetLiveRoomStudentList({ task_id: this.task_id }).then(({ student_list }) => {
+        this.student_list = student_list;
+      });
+    },
+
+    getLiveRoomStudentListPolling() {
+      this.timer = setInterval(() => {
+        this.getLiveRoomStudentList();
+      }, 5000);
+    },
+
+    // 弹出框方法
+    dialogMaterialClose() {
+      this.dialogVisibleMaterial = false;
+      this.getCurMaterialSent();
+    },
+
+    liveWrapperOver() {
+      this.liveMenuShow = true;
+    },
+
+    liveWrapperOut() {
+      this.liveMenuShow = false;
+    },
+
+    getCurMaterialSent() {
+      const timer = setInterval(() => {
+        GetCurMaterialSent({ task_id: this.task_id })
+          .then(({ material_id, material_name, material_type, material_picture_url }) => {
+            if (material_id !== undefined && material_id.length > 0) {
+              this.dialogVisibleMaterial = true;
+              this.material_id = material_id;
+              this.material_name = material_name;
+              this.material_type = material_type;
+              this.material_picture_url = material_picture_url;
+              clearInterval(timer);
+            }
+          })
+          .catch(() => {
+            clearInterval(timer);
+          });
+      }, 2000);
+    }
+  }
+};
+</script>
+
+<style lang="scss">
+@import '~@/styles/mixin.scss';
+$live-bc: #3d3938;
+
+.live {
+  @include container;
+
+  // 顶部
+  &-top {
+    background-color: #fff;
+    padding: 24px 32px;
+    border-top-left-radius: 8px;
+    border-top-right-radius: 8px;
+
+    .live-title {
+      display: flex;
+      justify-content: space-between;
+
+      &-name {
+        font-size: 22px;
+      }
+
+      .el-button {
+        border-radius: 4px;
+        padding: 7px 12px;
+      }
+    }
+
+    .live-course-name {
+      font-size: 14px;
+      color: #737373;
+      line-height: 30px;
+    }
+
+    .live-teacher {
+      margin-top: 12px;
+
+      .svg-icon {
+        margin-right: 8px;
+      }
+
+      &-name {
+        margin-right: 60px;
+      }
+    }
+  }
+
+  // 主容器
+  &-container {
+    display: flex;
+    justify-content: left;
+
+    &-left {
+      width: 832px;
+      background-color: #fff;
+      border-radius: 8px;
+
+      .loading {
+        position: relative;
+        width: 100%;
+        height: 468px;
+        color: #fff;
+        background-color: #646464;
+        display: flex;
+        justify-content: center;
+        align-items: center;
+
+        &-wrapper {
+          text-align: center;
+
+          .loading-title {
+            margin-bottom: 24px;
+          }
+        }
+      }
+
+      #student {
+        width: 100%;
+        height: 468px;
+        border: 1px solid #ccc;
+        position: relative;
+        background-color: $live-bc;
+      }
+
+      #draw-parent {
+        width: 100%;
+        height: 468px;
+        border: 1px solid #ccc;
+        position: relative;
+        background-color: $live-bc;
+        overflow: hidden;
+
+        // 设置屏幕画笔
+        .draw-setting {
+          position: absolute;
+          bottom: 13px;
+          left: 22px;
+          z-index: 9999;
+          background-color: #a0a0a0;
+          padding: 6px;
+          border-radius: 40px;
+          height: 40px;
+          width: 275px;
+          line-height: 28px;
+
+          & > span {
+            display: inline-block;
+            text-align: center;
+            margin-right: 10px;
+          }
+
+          & > span.brush-shape {
+            width: 28px;
+            height: 28px;
+            border-radius: 50%;
+            background-color: #fff;
+            cursor: pointer;
+          }
+
+          .draw-color {
+            position: relative;
+            top: 5px;
+            height: 18px;
+            width: 18px;
+            border-radius: 50%;
+            cursor: pointer;
+          }
+
+          .current::after {
+            content: '';
+            position: absolute;
+            bottom: -7px;
+            left: 7px;
+            width: 4px;
+            height: 4px;
+            border-radius: 50%;
+            background-color: #292929;
+          }
+
+          .draw-thickness {
+            height: 18px;
+            width: 18px;
+            cursor: pointer;
+            display: inline-flex;
+            flex-direction: column;
+            justify-content: center;
+            vertical-align: middle;
+            align-items: center;
+
+            span {
+              border-radius: 50%;
+              background-color: #000;
+            }
+          }
+
+          & > .brush-clear {
+            width: 28px;
+            height: 28px;
+            border-radius: 50%;
+            background-color: #666;
+            cursor: pointer;
+            margin-right: 0;
+          }
+        }
+      }
+
+      .button-group {
+        display: flex;
+        justify-content: space-between;
+        height: 48px;
+        background-color: #4d4d4d;
+        padding: 0 15px;
+        border-bottom-left-radius: 5px;
+
+        .svg-icon {
+          font-size: 20px;
+        }
+
+        &-left {
+          > span {
+            display: inline-block;
+            height: 100%;
+            padding: 14px 16px;
+            cursor: pointer;
+
+            &:active,
+            &:hover {
+              background-color: #3d3d3d;
+            }
+          }
+        }
+      }
+
+      // 聊天窗口
+      &-chat {
+        height: 278px;
+        border: 1px solid #ccc;
+        border-bottom-left-radius: 8px;
+        display: flex;
+        flex-direction: column;
+        justify-content: space-between;
+
+        .chat-top {
+          display: flex;
+          justify-content: space-between;
+          padding: 15px 15px 10px;
+          border-bottom: 1px solid #e6e6e6;
+          color: #959595;
+
+          label {
+            cursor: pointer;
+          }
+
+          .allow-chat {
+            margin-right: 12px;
+          }
+        }
+
+        .chat-window {
+          position: relative;
+          width: 100%;
+          height: 100%;
+          overflow: hidden;
+
+          &-ul {
+            position: absolute;
+            top: 0;
+            left: 0;
+            width: 100%;
+            height: 100%;
+            overflow: auto;
+
+            .msg-normal {
+              padding: 7px 16px;
+            }
+          }
+        }
+
+        .chat-speak {
+          padding: 16px;
+        }
+      }
+    }
+
+    &-right {
+      padding: 8px;
+      background-color: #2c2c2c;
+      border-end-end-radius: 8px;
+
+      .live-teacher-lens {
+        position: relative;
+        overflow: hidden;
+
+        #live {
+          width: 352px;
+          height: 198px;
+          background-color: $live-bc;
+        }
+
+        .live-wrapper {
+          position: absolute;
+          bottom: 0;
+          height: 40px;
+          width: 100%;
+          background-color: #000;
+          opacity: 0.7;
+          color: #fff;
+          line-height: 40px;
+          padding: 0 16px;
+        }
+      }
+
+      .student-list {
+        width: 100%;
+        padding: 24px 16px;
+        margin-top: 2px;
+        height: calc(100% - 200px);
+        background-color: #2c2c2c;
+        font-size: 14px;
+        color: #fff;
+
+        &-title {
+          margin-bottom: 16px;
+        }
+
+        li {
+          display: flex;
+          margin-bottom: 16px;
+
+          .student-list-left {
+            flex: 7;
+
+            .name {
+              vertical-align: super;
+              margin-left: 8px;
+            }
+          }
+
+          .student-list-right {
+            flex: 3;
+
+            .svg-icon {
+              font-size: 18px;
+              cursor: pointer;
+              margin-top: 7px;
+              margin-right: 8px;
+            }
+          }
+        }
+      }
+    }
+  }
+}
+</style>

+ 247 - 0
src/views/live/student/live.js

@@ -0,0 +1,247 @@
+import { Message } from 'element-ui';
+import { GetLiveRoomInfo } from '@/api/live';
+import { rtc, publishStream, closeVideo } from '@/views/live/common';
+export { initSDK, sendMsg, getLiveStat, getDevice } from '@/views/live/common';
+
+// 连麦
+
+/**
+ * 学生端接受老师的上麦邀请,同意上麦
+ */
+export function inviteAccept() {
+  rtc.inviteAccept({
+    success: function (str) {
+      console.log('接受邀请成功', str);
+    },
+    fail: function (data) {
+      console.log('接受邀请失败', data);
+    }
+  });
+}
+
+/**
+ * 申请连麦
+ */
+export function handsUp(data) {
+  rtc.handsUp(data);
+}
+
+/**
+ * 取消订阅远程流
+ */
+function unSubscribeStream(stream) {
+  rtc.unSubscribeStream({
+    unSubStream: stream,
+    success: function (str) {
+      console.log('取消订阅流成功', str);
+    },
+
+    fail: function (str) {
+      console.log(str);
+    }
+  });
+}
+
+/**
+ * 初始化监听事件
+ */
+export function initListener(vue) {
+  rtc.on('login_success', data => {
+    console.log('登录成功', data);
+    Message({
+      message: '登录成功',
+      type: 'success'
+    });
+    vue.roomData = data;
+    // 初始化画板需要的数据
+    let canvasInitData = {
+      allowDraw: false, // 是否具有书写画笔权限(讲师权限) true / false
+      id: 'draw-parent',
+      pptDisplay: 1, // 文档展示方式。默认0,按窗口  1,按宽度
+      liveId: data.live.status === 1 ? data.live.id : '' // 如果直播已经开始,需将直播 id 传入 sdk 中
+    };
+    // 初始化画板
+    rtc.canvasInit(canvasInitData);
+  });
+
+  rtc.on('login_failed', data => {
+    console.log('登录失败', data);
+    Message({
+      message: '登录失败:' + JSON.stringify(data),
+      type: 'warning'
+    });
+  });
+
+  // 教师 必须在加入房间成功的事件回调里创建本地流
+  rtc.on('conference_join', () => {
+    console.log('加入房间成功');
+  });
+
+  rtc.on('conference_join_failed', err => {
+    // 加入房间失败  err为错误原因
+    console.log('加入房间失败', err);
+  });
+
+  // 新增订阅流事件
+  rtc.on('allow_sub', function (stream) {
+    if (stream.isMixed()) {
+      console.log('是混合流,不订阅');
+    } else {
+      // 订阅远程流
+      rtc.trySubscribeStream({
+        tryStream: stream,
+        success: function (stream) {
+          // 订阅流成功
+          let streamType = stream.streamType();
+          console.log('订阅流成功', streamType);
+          let id = streamType === 0 ? 'live' : 'student';
+          stream.show(id, 'contain'); // 将流显示到指定 id 的盒子中
+
+          if (streamType === 1 || streamType === 10) {
+            vue.connect = true;
+            vue.callLoading = false;
+          }
+        },
+        fail: function (err) {
+          console.log('订阅流失败', err);
+        }
+      });
+    }
+  });
+
+  // 推流前查询直播状态失败,导致没有推流
+  rtc.on('local_stream_publish_failed', function () {
+    console.log('推流前查询直播状态失败,导致没有推流');
+    Message({
+      message: '推流前查询直播状态失败,导致没有推流',
+      type: 'warning'
+    });
+  });
+
+  // 房间全量信息事件(人员进出时广播)
+  rtc.on('room_context', roomData => {
+    vue.roomContext = JSON.parse(roomData);
+    vue.getLiveRoomStudentList();
+    console.log('房间全量信息事件(人员进出时广播)', JSON.parse(roomData));
+  });
+
+  rtc.on('publish_stream', str => {
+    console.log('直播已开启', str);
+    vue.liveStat = true;
+  });
+
+  rtc.on('end_stream', str => {
+    console.log('直播已关闭', str);
+    vue.liveStat = false;
+  });
+
+  rtc.on('switch_user_settings', settingData => {
+    // 单个用户配置监听
+    console.log(settingData);
+  });
+
+  // 人员列表事件(人员麦序变化时广播)
+  rtc.on('speak_context', speakData => {
+    vue.speakData = JSON.parse(speakData);
+    console.log('人员列表事件(人员麦序变化时广播)', JSON.parse(speakData));
+  });
+
+  rtc.on('switch_settings', data => {
+    console.log('房间设置事件', data); // 房间设置事件
+  });
+
+  rtc.on('publishStreamErr', data => {
+    console.log('推流意外终止:' + data.streamName);
+    // 直播开启状态下,尝试重推这条流
+  });
+
+  // 视频无法自动播放
+  rtc.on('playError', data => {
+    console.log('视频无法自动播放', data);
+  });
+
+  // 用户退出房间通知其他人员事件
+  rtc.on('exit_room_user', function (data) {
+    console.log('用户退出房间通知其他人员事件', data);
+  });
+
+  // 监听通知移除流事件
+  rtc.on('stream_removed', function (stream) {
+    console.log('监听通知移除流事件');
+    vue.connect = false;
+  });
+
+  // 停止订阅流
+  rtc.on('unSub', function (stream) {
+    console.log('停止订阅流');
+    unSubscribeStream(stream);
+  });
+
+  /**
+   * 排麦监听事件
+   */
+
+  // 监听自己被邀请事件
+  rtc.on('inviteUp', uid => {
+    console.log('监听自己被邀请事件', uid);
+    vue.callLoading = true;
+  });
+
+  rtc.on('mcDown', () => {
+    closeVideo('picture');
+    vue.connect = false;
+  });
+
+  rtc.on('createLocalStream', () => {
+    // 创建本地流推流
+    GetLiveRoomInfo({ task_id: vue.task_id }).then(({ video_mode }) => {
+      console.log('创建本地流推流');
+      const createData = {
+        video: video_mode === 1,
+        audio: true
+      };
+      rtc.createLocalStream({
+        streamName: 'picture',
+        createData,
+        success: function (stream) {
+          vue.connect = true;
+          vue.callLoading = false;
+          console.log('创建本地流成功', stream);
+          // 创建本地流成功,将流展示到id为 student 的dom元素盒子中
+          stream.show('student');
+          publishStream('picture'); // 如果需要立即推流,执行 publish 方法
+        },
+        fail: function (data) {
+          console.log('创建本地流失败,应用层处理', data);
+          // 创建本地流失败,应用层处理
+          Message({
+            type: 'error',
+            message: '创建本地流失败:' + data
+          });
+        }
+      });
+    });
+  });
+
+  /**
+   * 监听聊天事件
+   */
+  rtc.on('chat_message', data => {
+    let dat = JSON.parse(data);
+    console.log(dat);
+    // 敏感词过滤:如果发送的聊天消息被系统判定包含敏感词,则只有发送者能收到本条消息,房间内其他人都不会收到这条聊天消息。
+    // 如果返回消息中有 isFilterChat 字段(消息不包含敏感词返回数据中无isFilterChat字段),且isFilterChat的值为1,则说明该消息包含敏感字,除发送者外其他人不会收到这条消息。
+    if (dat.isFilterChat && dat.isFilterChat === 1) {
+      return;
+    }
+    vue.chatList.push(dat);
+  });
+
+  rtc.on('allowChatChange', function (data) {
+    let msg = data.settings.allow_chat ? '开言' : '禁言';
+    Message({
+      type: 'success',
+      message: `全体${msg}成功`
+    });
+  });
+}

+ 0 - 0
src/views/live/CompleteList.vue → src/views/live/teacher/CompleteList.vue


+ 39 - 105
src/views/live/index.vue → src/views/live/teacher/index.vue

@@ -5,14 +5,11 @@
       <div class="live-title">
         <div class="live-title-name">{{ roomInfo.cs_item_name }} {{ roomInfo.task_name }}</div>
         <div>
-          <!-- <el-button @click="playAudio">开启本地流声音</el-button> -->
-          <template v-if="userType === 'TEACHER'">
-            <el-button v-if="!liveStat" @click="startLive">开启直播</el-button>
-            <el-button v-if="liveStat" icon="el-icon-switch-button" @click="closeLiveRoom">
-              结束直播
-            </el-button>
-            <el-button v-if="liveStat" @click="publishStream">推流</el-button>
-          </template>
+          <el-button v-if="!liveStat" @click="startLive">开启直播</el-button>
+          <el-button v-if="liveStat" icon="el-icon-switch-button" @click="closeLiveRoom">
+            结束直播
+          </el-button>
+          <el-button v-if="liveStat" @click="publishStream">推流</el-button>
         </div>
       </div>
       <div class="live-course-name">{{ roomInfo.course_name }}</div>
@@ -30,9 +27,11 @@
         <div v-show="callLoading" class="loading">
           <div class="loading-wrapper">
             <p class="loading-title">正在呼叫,等待对方接通...</p>
-            <!-- <div>
-                <el-button type="danger" icon="el-icon-phone-outline" circle></el-button>
-              </div> -->
+            <div>
+              <el-button type="danger" circle>
+                <svg-icon icon-class="hang-up" />
+              </el-button>
+            </div>
           </div>
         </div>
         <div v-show="connect" id="student"></div>
@@ -57,24 +56,22 @@
         </div>
         <div class="button-group">
           <div class="button-group-left">
-            <template v-if="userType === 'TEACHER'">
-              <span title="屏幕共享" @click="publishShareStream">
-                <svg-icon icon-class="share" />
-              </span>
-              <span title="白板" @click="showDrawSetting">
-                <svg-icon icon-class="draw" />
-              </span>
-              <span title="课件推送" @click="dialogVisible = true">
-                <svg-icon icon-class="push" />
-              </span>
-            </template>
+            <span title="屏幕共享" @click="publishShareStream">
+              <svg-icon icon-class="share" />
+            </span>
+            <span title="白板" @click="showDrawSetting">
+              <svg-icon icon-class="draw" />
+            </span>
+            <span title="课件推送" @click="dialogVisible = true">
+              <svg-icon icon-class="push" />
+            </span>
           </div>
           <div class="button-group-right"></div>
         </div>
         <div class="live-container-left-chat">
           <div class="chat-top">
             <span>聊天</span>
-            <label v-if="userType === 'TEACHER'" @click="chatBans">
+            <label @click="chatBans">
               <input v-model="roomData.allow_chat" type="checkbox" class="allow-chat" />
               <span>禁言</span>
             </label>
@@ -103,7 +100,11 @@
       </div>
       <!-- 右侧 -->
       <div class="live-container-right">
-        <div class="live-teacher-lens" @mouseover="liveWrapperOver" @mouseout="liveWrapperOut">
+        <div
+          class="live-teacher-lens"
+          @mouseover="liveMenuShow = true"
+          @mouseout="liveMenuShow = false"
+        >
           <div id="live"></div>
           <div v-show="liveMenuShow" class="live-wrapper">
             <div>
@@ -121,11 +122,9 @@
                 <span class="name">{{ item.student_name }}</span>
               </div>
               <div class="student-list-right">
-                <template v-if="userType === 'TEACHER'">
-                  <svg-icon icon-class="video" @click="invite(item.room_user_id, 1)" />
-                  <svg-icon icon-class="voice" @click="invite(item.room_user_id, 2)" />
-                  <span @click="handsDown(item.room_user_id)"> 下麦 </span>
-                </template>
+                <svg-icon icon-class="video" @click="invite(item.room_user_id, 1)" />
+                <svg-icon icon-class="voice" @click="invite(item.room_user_id, 2)" />
+                <span @click="handsDown(item.room_user_id)"> 下麦 </span>
               </div>
             </li>
           </ul>
@@ -135,7 +134,6 @@
 
     <!-- 推送资料 -->
     <select-material
-      v-if="userType === 'TEACHER'"
       :dialog-visible="dialogVisible"
       :task-id="task_id"
       @dialogClose="dialogClose"
@@ -144,36 +142,16 @@
 
     <!-- 教师查看当前完成列表 -->
     <complete-list
-      v-if="userType === 'TEACHER'"
       :task-id="task_id"
       :dialog-visible-complete="dialogVisibleComplete"
       @dialogCompleteClose="dialogCompleteClose"
     />
-
-    <!-- 学员当前推送资料 -->
-    <cur-material
-      v-if="userType === 'STUDENT'"
-      :task-id="task_id"
-      :dialog-visible-material="dialogVisibleMaterial"
-      :material-id="material_id"
-      :material-name="material_name"
-      :material-type="material_type"
-      :material-picture-url="material_picture_url"
-      @dialogMaterialClose="dialogMaterialClose"
-    />
   </div>
 </template>
 
 <script>
-import {
-  GetLiveRoomStudentList,
-  StudentExitLiveRoom,
-  GetCurMaterialSent,
-  CloseLiveRoom,
-  GetLiveRoomInfo
-} from '@/api/live';
+import { GetLiveRoomStudentList, CloseLiveRoom, GetLiveRoomInfo } from '@/api/live';
 import SelectMaterial from '@/components/live/SelectMaterial.vue';
-import CurMaterial from '@/components/live/CurMaterial.vue';
 import CompleteList from './CompleteList.vue';
 import * as common from './live';
 
@@ -181,24 +159,16 @@ export default {
   name: 'Live',
   components: {
     SelectMaterial,
-    CurMaterial,
     CompleteList
   },
   data() {
     return {
-      userType: this.$store.state.user.user_type,
       task_id: this.$route.query.task_id,
-      // 已连接
+      // 连麦
       connect: false,
       // 等待接通
       callLoading: false,
       dialogVisible: false,
-      dialogVisibleMaterial: false,
-      // 资料信息
-      material_id: '',
-      material_name: '',
-      material_type: '',
-      material_picture_url: '',
       // 学员完成
       dialogVisibleComplete: false,
       // 定时器
@@ -283,9 +253,7 @@ export default {
       },
       true
     );
-    if (this.userType === 'STUDENT') {
-      this.getCurMaterialSent();
-    }
+    this.getLiveRoomStudentListPolling();
   },
   beforeDestroy() {
     // 清除所有定时器
@@ -293,6 +261,7 @@ export default {
     // for (let i = 1; i <= end; i++) {
     //   clearInterval(i);
     // }
+    clearInterval(this.timer);
     CloseLiveRoom({ task_id: this.task_id });
   },
   methods: {
@@ -357,8 +326,8 @@ export default {
         roomid: room_id,
         sessionid: session_id
       });
-      const that = this;
-      common.initListener(that); // 注册监听事件
+      common.initListener(this); // 注册监听事件
+      window.rtc = this.rtc;
       this.getLiveStat();
     },
 
@@ -416,7 +385,7 @@ export default {
 
     // 关闭桌面共享
     unPubShareStream() {
-      this.rtc.unPubShareStream();
+      common.unPubShareStream();
     },
 
     // 老师邀请学生上麦
@@ -497,20 +466,17 @@ export default {
       });
     },
 
-    studentExitLiveRoom(room_user_id) {
-      StudentExitLiveRoom({ task_id: this.task_id, room_user_id }).then(() => {
+    getLiveRoomStudentListPolling() {
+      this.timer = setInterval(() => {
         this.getLiveRoomStudentList();
-      });
+      }, 5000);
     },
 
+    // 弹出框方法
     publishStream() {
       common.publishStream('main');
     },
 
-    playAudio() {
-      common.playAudio();
-    },
-
     dialogClose() {
       this.dialogVisible = false;
     },
@@ -520,40 +486,8 @@ export default {
       this.dialogVisibleComplete = true;
     },
 
-    dialogMaterialClose() {
-      this.dialogVisibleMaterial = false;
-      this.getCurMaterialSent();
-    },
-
     dialogCompleteClose() {
       this.dialogVisibleComplete = false;
-    },
-
-    liveWrapperOver() {
-      this.liveMenuShow = true;
-    },
-
-    liveWrapperOut() {
-      this.liveMenuShow = false;
-    },
-
-    getCurMaterialSent() {
-      const timer = setInterval(() => {
-        GetCurMaterialSent({ task_id: this.task_id })
-          .then(({ material_id, material_name, material_type, material_picture_url }) => {
-            if (material_id !== undefined && material_id.length > 0) {
-              this.dialogVisibleMaterial = true;
-              this.material_id = material_id;
-              this.material_name = material_name;
-              this.material_type = material_type;
-              this.material_picture_url = material_picture_url;
-              clearInterval(timer);
-            }
-          })
-          .catch(() => {
-            clearInterval(timer);
-          });
-      }, 2000);
     }
   }
 };

+ 37 - 318
src/views/live/live.js → src/views/live/teacher/live.js

@@ -1,136 +1,18 @@
 import { Message } from 'element-ui';
-import store from '@/store';
-import { GetLiveRoomInfo } from '@/api/live';
-
-/**
- * WebSDK 实例化对象
- */
-let rtc;
-
-/**
- * @method initSDK
- * 初始化SDK方法
- * @param { object } data 初始化SDK所需参数
- * @returns { object }
- */
-export function initSDK(data) {
-  rtc = new Rtc(data);
-  return rtc;
-}
-
-/**
- * 推送本地流
- * @method publishStream
- */
-export function publishStream(streamName) {
-  rtc.publish({
-    streamName,
-    // 推流成功,更新上麦结果
-    success: function (stream) {
-      console.log('推流成功', stream);
-      rtc.updateMcResult({
-        pid: 1,
-        stid: stream.id(),
-        success: function (data) {
-          console.log('更新上麦结果请求成功,此处可处理应用层逻辑', data);
-        },
-        fail: function (data) {
-          console.log('更新上麦结果请求失败:' + JSON.stringify(data));
-        }
-      });
-    },
-    fail: function (str) {
-      // 推流失败,更新上麦结果
-      console.log('推流失败,更新上麦结果', str);
-    }
-  });
-}
-
-/**
- * 查询直播是否开启
- */
-export function getLiveStat(obj) {
-  rtc.getLiveStat(obj);
-}
-
-/**
- * 开启直播
- * @method startLive
- */
-export function startLive() {
-  rtc.startLive({
-    success(data) {
-      console.log(data);
-      publishStream('main'); // 如果需要立即推流,执行 publish 方法
-      Message({
-        message: '开启直播成功',
-        type: 'success'
-      });
-    },
-    fail(data) {
-      Message({
-        message: `开启直播失败:${data}`,
-        type: 'warning'
-      });
-    }
-  });
-}
-
-/**
- * 创建本地流
- * @method createLocalStram
- */
-export function createLocalStream() {
-  const createData = {
-    video: true,
-    audio: true
-  };
-  rtc.createLocalStream({
-    streamName: 'main',
-    createData,
-    success: function (stream) {
-      console.log('创建本地流成功', stream);
-      // 创建本地流成功,将流展示到id为 live 的dom元素盒子中
-      stream.show('live');
-      publishStream('main'); // 如果需要立即推流,执行 publish 方法
-      // getLiveStat({
-      //   success: function (data) {
-      //     console.log(data.started);
-      //   },
-      //   fail: function (str) {
-      //     // startLive();
-      //   }
-      // });
-    },
-    fail: function (data) {
-      // 创建本地流失败,应用层处理
-      Message({
-        type: 'error',
-        message: '创建本地流失败:' + data
-      });
-    }
-  });
-}
-
-/**
- * 结束本地流
- * @method closeVideo
- */
-export function closeVideo(streamName) {
-  rtc.closeVideo({
-    streamName,
-    success: function () {
-      console.log('结束本地流成功');
-    },
-    fail: function (str) {
-      console.log(str);
-    }
-  });
-}
+import { rtc, publishStream, createLocalStream } from '@/views/live/common';
+export {
+  initSDK,
+  getLiveStat,
+  roomUpdate,
+  sendMsg,
+  drawChange,
+  getDevice,
+  publishStream,
+  handsDown
+} from '@/views/live/common';
 
 /**
  * 初始化监听事件
- * @method initListener
  */
 export function initListener(vue) {
   rtc.on('login_success', data => {
@@ -142,7 +24,7 @@ export function initListener(vue) {
     vue.roomData = data;
     // 初始化画板需要的数据
     let canvasInitData = {
-      allowDraw: store.state.user.user_type === 'TEACHER', // 是否具有书写画笔权限(讲师权限) true / false
+      allowDraw: true, // 是否具有书写画笔权限(讲师权限) true / false
       id: 'draw-parent',
       pptDisplay: 1, // 文档展示方式。默认0,按窗口  1,按宽度
       liveId: data.live.status === 1 ? data.live.id : '' // 如果直播已经开始,需将直播 id 传入 sdk 中
@@ -159,13 +41,10 @@ export function initListener(vue) {
     });
   });
 
-  // 必须在加入房间成功的“conference_join”事件回调里创建本地流
+  // 教师 必须在加入房间成功的事件回调里创建本地流
   rtc.on('conference_join', () => {
     console.log('加入房间成功');
-    // 有监听就是加入房间成功
-    if (store.state.user.user_type === 'TEACHER') {
-      createLocalStream();
-    }
+    createLocalStream();
   });
 
   rtc.on('conference_join_failed', err => {
@@ -187,7 +66,6 @@ export function initListener(vue) {
           // let hasVideo = stream.hasVideo();
           console.log('订阅流成功', streamType);
           let id = streamType === 0 ? 'live' : 'student';
-          // 有视频才显示
           stream.show(id, 'contain'); // 将流显示到指定 id 的盒子中
 
           if (streamType === 1 || streamType === 10) {
@@ -262,12 +140,6 @@ export function initListener(vue) {
     console.log('视频无法自动播放', data);
   });
 
-  // 用户退出房间通知其他人员事件
-  rtc.on('exit_room_user', function (data) {
-    console.log('用户退出房间通知其他人员事件', data);
-    vue.studentExitLiveRoom(data.id);
-  });
-
   // 监听通知移除流事件
   rtc.on('stream_removed', function (stream) {
     console.log('监听通知移除流事件');
@@ -306,41 +178,6 @@ export function initListener(vue) {
     });
   });
 
-  rtc.on('mcDown', () => {
-    closeVideo('picture');
-    vue.connect = false;
-  });
-
-  rtc.on('createLocalStream', () => {
-    // 创建本地流推流
-    GetLiveRoomInfo({ task_id: vue.task_id }).then(({ video_mode }) => {
-      console.log('创建本地流推流');
-      const createData = {
-        video: video_mode === 1,
-        audio: true
-      };
-      rtc.createLocalStream({
-        streamName: 'picture',
-        createData,
-        success: function (stream) {
-          vue.connect = true;
-          console.log('创建本地流成功', stream);
-          // 创建本地流成功,将流展示到id为 student 的dom元素盒子中
-          stream.show('student');
-          publishStream('picture'); // 如果需要立即推流,执行 publish 方法
-        },
-        fail: function (data) {
-          console.log('创建本地流失败,应用层处理', data);
-          // 创建本地流失败,应用层处理
-          Message({
-            type: 'error',
-            message: '创建本地流失败:' + data
-          });
-        }
-      });
-    });
-  });
-
   /**
    * 监听聊天事件
    */
@@ -365,8 +202,29 @@ export function initListener(vue) {
 }
 
 /**
+ * 开启直播
+ */
+export function startLive() {
+  rtc.startLive({
+    success(data) {
+      console.log(data);
+      publishStream('main'); // 如果需要立即推流,执行 publish 方法
+      Message({
+        message: '开启直播成功',
+        type: 'success'
+      });
+    },
+    fail(data) {
+      Message({
+        message: `开启直播失败:${data}`,
+        type: 'warning'
+      });
+    }
+  });
+}
+
+/**
  * 结束直播
- * @method stopLive
  */
 export function stopLive() {
   rtc.stopLive({
@@ -386,85 +244,6 @@ export function stopLive() {
 }
 
 /**
- * 关闭本地流声音
- * @method pauseAudio
- */
-export function pauseAudio() {
-  rtc.pauseAudio({
-    streamName: 'main',
-    success: function () {
-      console.log('关闭本地流声音成功');
-    },
-    fail: function (str) {
-      console.log(str);
-    }
-  });
-}
-
-/**
- * 开启本地流声音
- * @method playAudio
- */
-export function playAudio() {
-  rtc.playAudio({
-    streamName: 'main',
-    success: function (data) {
-      console.log(data);
-      console.log('开启本地流声音成功');
-    },
-    fail: function (str) {
-      console.log(str);
-    }
-  });
-}
-
-/**
- * 关闭本地流视频画面
- * @method pauseVideo
- */
-export function pauseVideo() {
-  rtc.pauseVideo({
-    streamName: 'main',
-    success: function () {
-      console.log('关闭本地流视频画面成功');
-    },
-    fail: function (str) {
-      console.log(str);
-    }
-  });
-}
-
-/**
- * 开启本地流视频画面
- * @method playVideo
- */
-export function playVideo() {
-  rtc.playVideo({
-    streamName: 'main',
-    success: function () {
-      console.log('开启本地流视频画面成功');
-    },
-    fail: function (str) {
-      console.log(str);
-    }
-  });
-}
-
-/**
- * 获取设备列表
- */
-export function getDevice() {
-  rtc.getDevice({
-    success: function (data) {
-      console.log('获取成功', data);
-    },
-    fail: function (str) {
-      console.log('直播关闭状态或查询直播失败', str);
-    }
-  });
-}
-
-/**
  * 推送桌面共享
  */
 export function publishShareStream() {
@@ -501,7 +280,7 @@ export function liveRecord(status) {
   });
 }
 
-// 
+// 
 
 /**
  * 老师端发起邀请,邀请学生上麦。(举手模式)
@@ -522,63 +301,3 @@ export function invite(uid) {
     }
   });
 }
-
-/**
- * 申请连麦
- * @method handsUp
- */
-export function handsUp(data) {
-  rtc.handsUp(data);
-}
-
-/**
- * 下麦操作
- * @param { String } uid
- */
-export function handsDown(Object) {
-  rtc.handsDown(Object);
-}
-
-/**
- * 学生端接受老师的上麦邀请,同意上麦
- */
-export function inviteAccept() {
-  rtc.inviteAccept({
-    success: function (str) {
-      console.log('接受邀请成功', str);
-    },
-    fail: function (data) {
-      console.log('接受邀请失败', data);
-    }
-  });
-}
-
-// 聊天组件
-
-/**
- * 发送聊天
- * @param {String} msg length不能超过 400
- */
-export function sendMsg(msg) {
-  rtc.sendMsg(msg);
-}
-
-/**
- * 房间配置项更新
- * @param {Object} option 房间配置项 (具体看2.0 https://doc.bokecc.com/class/developer/web/chat.html),以键值对的形式传
- */
-export function roomUpdate(option) {
-  rtc.roomUpdate(option);
-}
-
-// 文档
-
-/**
- * 变更画笔
- */
-export function drawChange(action, value) {
-  rtc.drawChange({
-    action,
-    value
-  });
-}

+ 0 - 228
src/views/teacher/add_course/AddCourse.vue

@@ -1,228 +0,0 @@
-<template>
-  <div class="information">
-    <el-form
-      ref="form"
-      :model="form"
-      :rules="formRules"
-      label-width="130px"
-      label-position="left"
-      hide-required-asterisk
-    >
-      <el-form-item :label="$t('Learn_Course_Cover') + ':'" class="information-cover">
-        <el-upload
-          action="no"
-          class="avatar-uploader"
-          :http-request="upload"
-          :before-upload="beforeUpload"
-          :show-file-list="false"
-          accept="image/*"
-        >
-          <img v-if="form.imageUrl" :src="form.imageUrl" class="avatar" />
-          <i v-else class="el-icon-plus avatar-uploader-icon"></i>
-        </el-upload>
-        <span class="line-middle auto"><a @click="automatically">自动生成功能</a></span>
-      </el-form-item>
-      <el-form-item :label="$t('Learn_Course_Name') + ':'" prop="name">
-        <el-input v-model="form.name" type="text" class="name-input"></el-input>
-      </el-form-item>
-      <el-form-item label="课程介绍:">
-        <el-input
-          v-model="form.intro"
-          type="textarea"
-          class="introduce-textarea"
-          resize="none"
-          rows="6"
-        ></el-input>
-      </el-form-item>
-      <el-form-item label="授课教师:">
-        <el-button @click="addTeacher">添加教师</el-button>
-      </el-form-item>
-      <el-form-item label="时间:">
-        <el-date-picker
-          v-model="form.begin_date"
-          value-format="yyyy-MM-dd"
-          type="date"
-          placeholder="添加开始日期"
-        />
-        <span class="horizontal-bar">-</span>
-        <el-date-picker
-          v-model="form.end_date"
-          value-format="yyyy-MM-dd"
-          type="date"
-          placeholder="添加截止日期"
-        />
-      </el-form-item>
-      <el-form-item label="开班学员数:">
-        <el-input
-          v-model.number="form.student_count_start"
-          type="text"
-          class="people-input"
-        ></el-input>
-      </el-form-item>
-      <el-form-item label="最大学员数:">
-        <el-input
-          v-model.number="form.student_count_max"
-          type="text"
-          class="people-input"
-        ></el-input>
-        <el-checkbox v-model="form.is_auto_close" class="student-checkbox">
-          人数满足自动封班
-        </el-checkbox>
-      </el-form-item>
-      <el-form-item label="类型:">
-        <el-checkbox v-model="form.is_opened">公开课</el-checkbox>
-        <el-checkbox v-model="form.is_need_apply">需申请</el-checkbox>
-      </el-form-item>
-      <el-form-item label="机构:" prop="mechanism">
-        <el-select v-model="form.mechanism" placeholder="请选择">
-          <el-option
-            v-for="item in org_list"
-            :key="item.id"
-            :value="item.id"
-            :label="item.name"
-          ></el-option>
-        </el-select>
-      </el-form-item>
-      <el-form-item>
-        <el-button @click="cancel">取消</el-button>
-        <el-button type="primary" @click="confirm">确定</el-button>
-      </el-form-item>
-    </el-form>
-  </div>
-</template>
-
-<script>
-import { updateWordPack } from '@/utils/i18n';
-import { fileUpload } from '@/api/app';
-import { getMyOrgList } from '@/api/list';
-import { CreateCourse } from '@/api/course';
-
-export default {
-  data() {
-    return {
-      org_list: [],
-      form: {
-        imageUrl: '',
-        picture_id: '',
-        name: '',
-        intro: '',
-        teacher_ids: '',
-        begin_date: '',
-        end_date: '',
-        is_auto_close: false,
-        student_count_start: '',
-        student_count_max: '',
-        is_opened: false,
-        is_need_apply: false,
-        mechanism: ''
-      },
-      formRules: {
-        name: { required: true, message: '课程名称不能为空', trigger: 'blur' },
-        mechanism: { required: true, message: '机构不能为空', trigger: 'change' }
-      }
-    };
-  },
-  created() {
-    getMyOrgList().then(response => {
-      this.org_list = response.org_list;
-    });
-    updateWordPack({
-      word_key_list: ['Learn_Course_Cover', 'Learn_Course_Name']
-    });
-  },
-  methods: {
-    cancel() {
-      this.$router.go(-1);
-    },
-    confirm() {
-      this.$refs.form.validate(valid => {
-        if (valid) {
-          CreateCourse(this.form).then(response => {
-            if (response.status === 1) {
-              this.$message.success('创建课程成功!');
-              this.$router.push('/');
-            }
-          });
-        } else {
-          return false;
-        }
-      });
-    },
-    // 自动生成功能
-    automatically() {
-      this.$message.info('该功能暂未实现!');
-    },
-    addTeacher() {
-      this.$message.info('该功能暂未实现!');
-    },
-    beforeUpload(file) {
-      let isImage = /^image/.test(file.type);
-      if (!isImage) {
-        this.$message.error('上传的文件不是图片,请重新上传!');
-      }
-      return isImage;
-    },
-    upload(file) {
-      fileUpload('Open', file).then(({ file_info_list }) => {
-        if (file_info_list.length > 0) {
-          const { file_url, file_id } = file_info_list[0];
-          this.form.imageUrl = file_url;
-          this.form.picture_id = file_id;
-        }
-      });
-    }
-  }
-};
-</script>
-
-<style lang="scss">
-.information {
-  &-title {
-    margin-bottom: 15px;
-    font-weight: 700;
-  }
-
-  &-cover {
-    .el-form-item__label {
-      @extend .line-middle;
-    }
-  }
-
-  .el-form-item__label {
-    font-size: 16px;
-  }
-
-  .name-input,
-  .introduce-textarea {
-    width: 530px;
-  }
-
-  .people-input,
-  .mechanism-input {
-    width: 185px;
-  }
-
-  .student-checkbox {
-    margin-left: 28px;
-  }
-
-  .horizontal-bar {
-    margin: 0 24px;
-  }
-
-  .el-button {
-    width: 140px;
-    height: 40px;
-  }
-}
-
-.line-middle {
-  line-height: 90px;
-}
-
-.auto {
-  display: inline-block;
-  vertical-align: text-bottom;
-  margin-left: 38px;
-}
-</style>

+ 0 - 27
src/views/teacher/add_course/index.vue

@@ -1,27 +0,0 @@
-<template>
-  <div class="course">
-    <add-course />
-  </div>
-</template>
-
-<script>
-import addCourse from './AddCourse';
-
-export default {
-  components: {
-    addCourse
-  },
-  data() {
-    return {};
-  },
-  methods: {}
-};
-</script>
-
-<style lang="scss">
-@import '~@/styles/mixin.scss';
-
-.course {
-  @include container;
-}
-</style>

+ 0 - 37
src/views/teacher/add_course/step/step_course_set_course_details.vue

@@ -1,37 +0,0 @@
-<template>
-  <div class="course-details">
-    <div class="course-details-title"></div>
-    <div class="course-details-body">
-      <div>课程详情</div>
-      <div class="course-de">
-        <el-button type="info" plain @click="setStep">上一步</el-button>
-        <el-button type="info" plain>保存</el-button>
-        <el-button type="primary">发布</el-button>
-      </div>
-    </div>
-  </div>
-</template>
-
-<script>
-export default {
-  created() {},
-  methods: {
-    setStep() {
-      this.$emit('set-step', 'courseInformation');
-    }
-  }
-};
-</script>
-
-<style lang="scss" scoped>
-.course-details {
-  &-title {
-    width: 100%;
-    height: 120px;
-  }
-  &-body {
-    display: flex;
-    justify-content: space-between;
-  }
-}
-</style>

+ 0 - 404
src/views/teacher/cs_item_detail/ClassroomTask.vue

@@ -1,404 +0,0 @@
-<template>
-  <div class="classroom-task-container">
-    <div>
-      <span>{{ $t('Learn_Classroom_Tasks') }}</span>
-    </div>
-    <div class="classroom-task">
-      <el-timeline>
-        <!--课前任务-->
-        <el-timeline-item :timestamp="$t('Learn_PreClass_Tasks')" color="#F02828" placement="top">
-          <el-card v-for="(list, i) in preTaskList" :key="i">
-            <el-collapse>
-              <el-collapse-item>
-                <template slot="title">
-                  <el-row class="classroom-task-title">
-                    <el-col :span="4">{{ list.name }}</el-col>
-                    <el-col :span="12" class="title-date">2021-3-23</el-col>
-                    <el-col :span="8" class="t-right">
-                      {{ $t('Learn_Completed') }}
-                      {{ list.student_count_finish_task }}/{{ list.student_count }}
-                    </el-col>
-                  </el-row>
-                </template>
-
-                <el-row>
-                  <el-col :span="24">{{ list.content }}</el-col>
-                </el-row>
-                <div class="line">
-                  <span>{{ $t('Learn_Courseware') }}:</span>
-                  <span>
-                    <el-tag
-                      v-for="courseware in list.courseware_list"
-                      :key="courseware.id"
-                      class="courseware-tag"
-                      type="info"
-                      >{{ courseware.name }}</el-tag
-                    >
-                  </span>
-                </div>
-
-                <div class="line">
-                  <span>{{ $t('Learn_Enclosure') }}:</span>
-                  <span>
-                    <el-tag
-                      v-for="(accessory, j) in list.accessory_list"
-                      :key="j"
-                      class="accessory-tag"
-                      type="info"
-                    >
-                      <a :href="accessory.file_url" target="_blank">{{ accessory.file_name }}</a>
-                    </el-tag>
-                  </span>
-                </div>
-
-                <div>
-                  <span>{{ $t('Learn_Completion') }}:</span>
-                  <el-row>
-                    <el-col :span="19">
-                      <circle-progress
-                        :total-count="list.student_count"
-                        :finish-count="list.student_count_finish_task"
-                      />
-                    </el-col>
-                    <el-col :span="5" class="t-right">
-                      {{ $t('Learn_Completed') }}
-                      {{ list.student_count_finish_task }}/{{ list.student_count }}
-                    </el-col>
-                  </el-row>
-                </div>
-              </el-collapse-item>
-            </el-collapse>
-          </el-card>
-        </el-timeline-item>
-        <!--课中任务-->
-        <el-timeline-item :timestamp="$t('Learn_Tasks_In_Class')" color="#F02828" placement="top">
-          <el-card v-for="(list, i) in midTaskList" :key="i">
-            <el-collapse>
-              <el-collapse-item>
-                <template slot="title">
-                  <el-row class="classroom-task-title">
-                    <el-col :span="4">{{ list.name }}</el-col>
-                    <el-col :span="12" class="title-date">2021-3-23</el-col>
-                    <el-col :span="8" class="t-right">
-                      {{ $t('Learn_Completed') }}
-                      {{ list.student_count_finish_task }}/{{ list.student_count }}
-                    </el-col>
-                  </el-row>
-                </template>
-
-                <el-row>
-                  <el-col :span="24">{{ list.content }}</el-col>
-                </el-row>
-                <div class="line">
-                  <span>{{ $t('Learn_Courseware') }}:</span>
-                  <span>
-                    <el-tag
-                      v-for="courseware in list.courseware_list"
-                      :key="courseware.id"
-                      class="courseware-tag"
-                      type="info"
-                      >{{ courseware.name }}</el-tag
-                    >
-                  </span>
-                </div>
-
-                <div class="line">
-                  <span>{{ $t('Learn_Enclosure') }}:</span>
-                  <span>
-                    <el-tag
-                      v-for="(accessory, j) in list.accessory_list"
-                      :key="j"
-                      class="accessory-tag"
-                      type="info"
-                    >
-                      <a :href="accessory.file_url" target="_blank">{{ accessory.file_name }}</a>
-                    </el-tag>
-                  </span>
-                </div>
-                <div>
-                  <span>{{ $t('Learn_Completion') }}:</span>
-                  <el-row>
-                    <el-col :span="19">
-                      <circle-progress
-                        :total-count="list.student_count"
-                        :finish-count="list.student_count_finish_task"
-                      />
-                    </el-col>
-                    <el-col :span="5" class="t-right">
-                      {{ $t('Learn_Completed') }}
-                      {{ list.student_count_finish_task }}/{{ list.student_count }}
-                    </el-col>
-                  </el-row>
-                </div>
-              </el-collapse-item>
-            </el-collapse>
-          </el-card>
-        </el-timeline-item>
-        <!--课后任务-->
-        <el-timeline-item
-          :timestamp="$t('Learn_After_Class_Tasks')"
-          color="#F02828"
-          placement="top"
-        >
-          <el-card v-for="(list, i) in afterTaskList" :key="i">
-            <el-collapse>
-              <el-collapse-item>
-                <template slot="title">
-                  <el-row class="classroom-task-title">
-                    <el-col :span="4">{{ list.name }}</el-col>
-                    <el-col :span="12" class="title-date">2021-3-23</el-col>
-                    <el-col :span="8" class="t-right">
-                      {{ $t('Learn_Completed') }}
-                      {{ list.student_count_finish_task }}/{{ list.student_count }}
-                    </el-col>
-                  </el-row>
-                </template>
-
-                <el-row>
-                  <el-col :span="24">{{ list.content }}</el-col>
-                </el-row>
-                <div class="line">
-                  <span>{{ $t('Learn_Courseware') }}:</span>
-                  <span>
-                    <el-tag
-                      v-for="courseware in list.courseware_list"
-                      :key="courseware.id"
-                      class="courseware-tag"
-                      type="info"
-                      >{{ courseware.name }}</el-tag
-                    >
-                  </span>
-                </div>
-
-                <div class="line">
-                  <span>{{ $t('Learn_Enclosure') }}:</span>
-                  <span>
-                    <el-tag
-                      v-for="(accessory, j) in list.accessory_list"
-                      :key="j"
-                      class="accessory-tag"
-                      type="info"
-                    >
-                      <a :href="accessory.file_url" target="_blank">{{ accessory.file_name }}</a>
-                    </el-tag>
-                  </span>
-                </div>
-                <div>
-                  <span>{{ $t('Learn_Completion') }}:</span>
-                  <el-row>
-                    <el-col :span="19">
-                      <circle-progress
-                        :total-count="list.student_count"
-                        :finish-count="list.student_count_finish_task"
-                      />
-                    </el-col>
-                    <el-col :span="5" class="t-right">
-                      {{ $t('Learn_Completed') }}
-                      {{ list.student_count_finish_task }}/{{ list.student_count }}
-                    </el-col>
-                  </el-row>
-                </div>
-              </el-collapse-item>
-            </el-collapse>
-          </el-card>
-        </el-timeline-item>
-      </el-timeline>
-    </div>
-
-    <!--右侧线上课件,回传文件-->
-    <div class="classroom-courseware">
-      <div class="classroom-courseware-container">
-        <div class="internet-courseware">
-          <div>线上课件:</div>
-          <div class="internet-courseware-content"></div>
-        </div>
-        <div class="return-file">
-          <div>回传文件:</div>
-          <div class="return-file-content"></div>
-        </div>
-      </div>
-    </div>
-  </div>
-</template>
-
-<script>
-import CircleProgress from '@/common/CircleProgress';
-
-export default {
-  name: 'ClassroomTask',
-  components: {
-    CircleProgress
-  },
-  props: {
-    preTaskList: {
-      type: Array,
-      default: () => {
-        return [];
-      }
-    },
-    midTaskList: {
-      type: Array,
-      default: () => {
-        return [];
-      }
-    },
-    afterTaskList: {
-      type: Array,
-      default: () => {
-        return [];
-      }
-    }
-  },
-  data() {
-    return {
-      dashoffset: 0
-    };
-  }
-};
-</script>
-
-<style lang="scss">
-@import '~@/styles/mixin.scss';
-$card-radius: 18px;
-
-.classroom-task-container {
-  padding-top: 20px;
-  .classroom-task {
-    width: 70%;
-    display: inline-block;
-    margin-top: 17px;
-    padding-right: 5px;
-    .classroom-task-title {
-      width: 560px;
-      .title-date {
-        color: #8f8f8f;
-      }
-    }
-  }
-  .el-timeline {
-    .el-timeline-item__timestamp.is-top {
-      color: #f02828;
-      font-size: 16px;
-    }
-    .el-timeline-item__node {
-      width: 13px;
-      height: 13px;
-      top: 3px;
-    }
-    .el-timeline-item__tail {
-      top: 12px;
-    }
-
-    .el-card,
-    .el-collapse-item__wrap {
-      background-color: #f7f7f7;
-      .el-collapse-item__content {
-        padding: 15px 24px 9px;
-        color: #000;
-        // 课堂任务详情样式
-        .el-row:not(:first-child) .el-col {
-          word-break: break-all;
-          height: 36px;
-          line-height: 36px;
-          margin: 6px 0;
-        }
-        .courseware-tag {
-          @include el-tag;
-
-          margin-right: 10px;
-        }
-        .accessory-tag {
-          @extend .courseware-tag;
-        }
-        .line {
-          word-break: break-all;
-          height: 36px;
-          line-height: 36px;
-          margin: 6px 0;
-        }
-      }
-    }
-
-    .el-card.is-always-shadow,
-    .el-card.is-hover-shadow:focus,
-    .el-card.is-hover-shadow:hover {
-      box-shadow: 0 0;
-      border-radius: $card-radius + 2px;
-    }
-
-    .el-card__body {
-      padding: 0;
-      background-color: #f7f7f7;
-      .el-collapse-item__header {
-        height: 22px;
-        line-height: 22px;
-        background-color: #f0f0f0;
-
-        &.focusing:focus:not(:hover) {
-          color: #000;
-        }
-      }
-
-      .el-collapse-item > div:first-child {
-        background-color: #f0f0f0;
-        padding: 10px 20px;
-        border-radius: $card-radius;
-      }
-    }
-  }
-
-  // 课堂任务 -> 课件
-  .classroom-courseware {
-    display: inline-block;
-    width: 30%;
-    padding-top: 30px;
-    vertical-align: top;
-
-    &-container {
-      border: 1px solid #606060;
-      width: 276px;
-      min-height: 262px;
-      margin-left: 24px;
-      border-radius: 17px;
-      padding: 23px 27px;
-      position: relative;
-
-      &::after {
-        content: '';
-        width: 20px;
-        height: 20px;
-        display: inline-block;
-        border-bottom: 1px solid #606060;
-        border-right: 1px solid #606060;
-        position: absolute;
-        bottom: -10.5px;
-        left: 50%;
-        transform: translateX(-50%) rotate(45deg);
-        background-color: #fff;
-      }
-
-      .return-file-content {
-        padding: 15px 0;
-        .el-tag {
-          width: 100%;
-          &:not(:first-child) {
-            margin-top: 18px;
-          }
-        }
-      }
-
-      .internet-courseware {
-        &-content {
-          @extend .return-file-content;
-
-          min-height: 100px;
-        }
-      }
-
-      .el-tag.el-tag--info {
-        @include el-tag;
-      }
-    }
-  }
-}
-</style>

+ 0 - 158
src/views/teacher/cs_item_detail/index.vue

@@ -1,158 +0,0 @@
-<template>
-  <div class="cs-item-detail-container">
-    <div>
-      <span>{{ $t('Learn_Lecture_Details') }}</span>
-      <div class="cs-item-info">
-        <el-row>
-          <el-col :span="18">
-            {{ CSItemInfoBox.date_stamp }} {{ CSItemInfoBox.minute_space }}
-          </el-col>
-          <el-col :span="6" class="t-right">
-            {{
-              CSItemInfoBox.finish_status === 0
-                ? $t('Learn_Task_No_Started')
-                : CSItemInfoBox.finish_status === 1
-                ? $t('Learn_Task_Has_Begun')
-                : $t('Learn_Task_Over')
-            }}
-          </el-col>
-        </el-row>
-        <el-row class="cs-item-name">
-          <el-col>{{ CSItemInfoBox.name }}</el-col>
-        </el-row>
-        <el-row class="cs-item-class-name">
-          <el-col :span="20">{{ CSItemInfoBox.class_name }}</el-col>
-          <el-col :span="4">
-            <el-button plain @click.prevent="jumpLiveRoom">{{ $t('Learn_Enter_Live') }}</el-button>
-          </el-col>
-        </el-row>
-      </div>
-    </div>
-    <classroom-task
-      :pre-task-list="CSItemInfoBox.pre_task_list"
-      :mid-task-list="CSItemInfoBox.mid_task_list"
-      :after-task-list="CSItemInfoBox.after_task_list"
-    />
-    <!--学习资料-->
-    <div class="learning-material">
-      <div class="learning-material-title">{{ $t('Learn_Materials') }}</div>
-      <div>
-        <el-row>
-          <el-col class="learning-material-upload" :span="24">
-            <el-upload action="/">
-              <el-button>{{ $t('Learn_Upload') }}</el-button>
-            </el-upload>
-          </el-col>
-        </el-row>
-        <el-tag
-          v-for="(list, i) in CSItemInfoBox.learning_material_list"
-          :key="i"
-          class="learning-material-tag"
-          type="info"
-        >
-          <a :href="list.file_url" target="_blank">{{ list.file_url }}</a>
-        </el-tag>
-      </div>
-    </div>
-  </div>
-</template>
-
-<script>
-import { getCSItemInfoBox } from '@/api/table';
-import ClassroomTask from './ClassroomTask';
-import { updateWordPack } from '@/utils/i18n';
-
-export default {
-  components: {
-    ClassroomTask
-  },
-  data() {
-    return {
-      id: this.$route.params.id,
-      CSItemInfoBox: {
-        class_name: '',
-        date_stamp: '',
-        finish_status: 0,
-        minute_space: '',
-        name: '',
-        pre_task_list: [],
-        mid_task_list: [],
-        after_task_list: [],
-        learning_material_list: []
-      }
-    };
-  },
-  created() {
-    updateWordPack({
-      word_key_list: [
-        'Learn_Task_No_Started',
-        'Learn_Task_Has_Begun',
-        'Learn_Task_Over',
-        'Learn_Lecture_Details',
-        'Learn_Enter_Live',
-        'Learn_Materials',
-        'Learn_Upload',
-        'Learn_Classroom_Tasks',
-        'Learn_PreClass_Tasks',
-        'Learn_Tasks_In_Class',
-        'Learn_After_Class_Tasks',
-        'Learn_Completed',
-        'Learn_Courseware',
-        'Learn_Enclosure',
-        'Learn_Completion'
-      ]
-    });
-
-    getCSItemInfoBox({ id: this.id }).then(response => {
-      this.CSItemInfoBox = Object.assign(this.CSItemInfoBox, response);
-    });
-  },
-  methods: {
-    jumpLiveRoom() {}
-  }
-};
-</script>
-
-<style lang="scss" scoped>
-@import '~@/styles/mixin.scss';
-
-.cs-item-detail-container {
-  @include container;
-
-  .cs-item-info {
-    width: 100%;
-    height: 122px;
-    padding: 15px 28px 20px 45px;
-    margin-top: 11px;
-    background-color: #eee;
-
-    .cs-item-name {
-      padding: 16px 0;
-    }
-    .cs-item-class-name {
-      color: #a4a4a4;
-      .el-button {
-        position: absolute;
-        top: -24px;
-        right: 0;
-      }
-    }
-  }
-}
-
-.learning-material {
-  &-title {
-    padding-top: 12px;
-  }
-  &-tag {
-    @include el-tag;
-
-    margin: 16px 12px 0 0;
-    height: 40px;
-    line-height: 40px;
-  }
-  &-upload {
-    padding-top: 27px;
-  }
-}
-</style>

+ 3 - 7
src/views/teacher/main/TaskList.vue

@@ -107,10 +107,10 @@ export default {
       if (type === 10) {
         CreateEnterLiveRoomSession({
           task_id
-        }).then(({ live_room_sys_user_id, room_id, session_id }) => {
+        }).then(({ live_room_sys_user_id, room_id, session_id, room_user_id }) => {
           this.$router.push({
-            path: '/live',
-            query: { live_room_sys_user_id, room_id, session_id, task_id }
+            path: `/live/${this.$store.state.user.user_type === 'TEACHER' ? 'teacher' : 'student'}`,
+            query: { live_room_sys_user_id, room_id, session_id, task_id, room_user_id }
           });
         });
       } else {
@@ -125,10 +125,6 @@ export default {
       GetMyDayTaskList({ date_stamp: formatDate(this.date) }).then(response => {
         this.task_group_list = response.task_group_list;
       });
-    },
-    // 跳转到讲次详情
-    routerPush(id) {
-      this.$router.push({ path: `/cs_item_detail/index/${id}` });
     }
   }
 };