dusenyao 4 gadi atpakaļ
vecāks
revīzija
41d01314f9

+ 15 - 0
src/api/course.js

@@ -256,3 +256,18 @@ export function UpdateTask(data) {
     data
   });
 }
+
+/**
+ * 得到课程详情
+ * @param {Object} data {id 课次ID}
+ */
+export function GetCourseInfoBox(data) {
+  let params = getRequestParams('cominfo_query-course_query-GetCourseInfoBox');
+
+  return request({
+    method: 'post',
+    url: process.env.VUE_APP_LearnWebSI,
+    params,
+    data
+  });
+}

+ 15 - 0
src/api/live.js

@@ -135,3 +135,18 @@ export function GetLiveRoomInfo(data) {
     data
   });
 }
+
+/**
+ * 得到完成了推送课件的学员列表
+ * @param {Object} data
+ */
+export function GetStudentList_FinishMaterial(data) {
+  let params = getRequestParams('live_room-live_room_dispatch-GetStudentList_FinishMaterial');
+
+  return request({
+    method: 'post',
+    url: process.env.VUE_APP_LearnWebSI,
+    params,
+    data
+  });
+}

+ 9 - 0
src/components/live/CurMaterial.vue

@@ -6,6 +6,8 @@
     title="当前推送课件"
     @close="dialogMaterialClose"
   >
+    <div class="material-name">{{ materialName }}</div>
+
     <template v-if="materialType === 'COURSEWARE'">
       <question :context="context" />
     </template>
@@ -169,5 +171,12 @@ export default {
 
 .cur-material {
   @include dialog;
+
+  .material-name {
+    font-size: 16px;
+    font-weight: 700;
+    color: #000;
+    margin-bottom: 16px;
+  }
 }
 </style>

+ 5 - 0
src/layouts/index.vue

@@ -26,6 +26,11 @@ export default {
     key() {
       return this.$route.path;
     }
+  },
+  created() {
+    window.onerror = function (msg, source, lineno, colno, error) {
+      if (msg === 'Script error.' && lineno === 0 && colno === 0) return true;
+    };
   }
 };
 </script>

+ 13 - 5
src/views/live/student/index.vue

@@ -46,8 +46,11 @@
               <div class="student-audio">
                 <el-avatar
                   icon="el-icon-user"
-                  :src="invite ? roomInfo.teacher_image_url : inviteImageURL"
+                  :src="invite ? roomInfo.teacher_image_url : connectStudent.student_image_url"
                 />
+                <span class="connect-name">
+                  {{ invite ? roomInfo.teacher_name : connectStudent.student_name }}
+                </span>
                 <el-button v-show="invite" type="danger" circle @click="handsDown">
                   <svg-icon icon-class="hang-up" />
                 </el-button>
@@ -168,7 +171,7 @@ export default {
       // 已连接
       connect: false,
       invite: false,
-      inviteImageURL: '',
+      connectStudent: '',
       // 等待接通
       callLoading: false,
       dialogVisibleMaterial: false,
@@ -202,7 +205,8 @@ export default {
         cs_item_name: '',
         course_name: '',
         teacher_name: '',
-        student_count: 0
+        student_count: 0,
+        teacher_image_url: ''
       },
       loadedNumber: 0,
       speakData: {},
@@ -502,11 +506,15 @@ $live-bc: #3d3938;
           justify-content: center;
           align-items: center;
 
+          .connect-name {
+            color: #fff;
+            margin: 24px 0;
+          }
+
           > .el-avatar {
             width: 96px;
             height: 96px;
             line-height: 96px;
-            margin-bottom: 24px;
 
             &--icon {
               font-size: 36px;
@@ -580,7 +588,7 @@ $live-bc: #3d3938;
             vertical-align: middle;
             align-items: center;
 
-            span {
+            > span {
               border-radius: 50%;
               background-color: #000;
             }

+ 12 - 2
src/views/live/student/live.js

@@ -129,11 +129,19 @@ export function initListener(vue) {
 
   rtc.on('publish_stream', str => {
     console.log('直播已开启', str);
+    Message({
+      type: 'success',
+      message: '直播已开启'
+    });
     vue.liveStat = true;
   });
 
   rtc.on('end_stream', str => {
     console.log('直播已关闭', str);
+    Message({
+      type: 'success',
+      message: '直播已关闭'
+    });
     vue.liveStat = false;
   });
 
@@ -167,7 +175,7 @@ export function initListener(vue) {
     console.log('监听通知移除流事件');
     vue.connect = false;
     vue.remoteStreamType = -1;
-    vue.inviteImageURL = '';
+    vue.connectStudent = '';
   });
 
   // 停止订阅流
@@ -254,12 +262,14 @@ export function initListener(vue) {
 
   // 接收自定义消息
   rtc.on('publish_message', function (data) {
+    // 连接中途下麦
     if (data.type === 'handsDown-load' && data.uid === vue.room_user_id) {
       vue.callLoading = false;
     }
 
+    // 连麦信息
     if (data.type === 'inviteImage') {
-      vue.inviteImageURL = data.imageURL;
+      vue.connectStudent = data.connectStudent;
     }
   });
 }

+ 113 - 29
src/views/live/teacher/CompleteList.vue

@@ -6,29 +6,48 @@
     title="答题统计"
     @close="dialogCompleteClose"
   >
-    <template v-if="material_type === 'COURSEWARE'">
-      <question :context="context" />
-    </template>
-    <template v-else>
-      <!-- pdf -->
-      <template v-if="fileType === 'pdf'">
-        <pdf v-for="i in numPages" :key="i" :src="pdfSrc" :page="i"></pdf>
-      </template>
+    <div class="complete-list-top">
+      <div class="material-name">{{ material_name }}</div>
+      <div class="student-list">
+        <i class="el-icon-arrow-left" />
+        <div class="avatar-list">
+          <el-avatar
+            v-for="item in student_list"
+            :key="item.student_id"
+            size="small"
+            :class="{ active: curStudent === item.student_id }"
+            :src="item.student_image_url"
+          />
+        </div>
+        <i class="el-icon-arrow-right" />
+      </div>
+    </div>
 
-      <template v-else-if="isImage(fileType)">
-        <el-image fit="contain" :src="file_url_https" />
+    <div class="complete-list-container">
+      <template v-if="material_type === 'COURSEWARE'">
+        <question :context="context" />
       </template>
+      <template v-else>
+        <!-- pdf -->
+        <template v-if="fileType === 'pdf'">
+          <pdf v-for="i in numPages" :key="i" :src="pdfSrc" :page="i"></pdf>
+        </template>
+
+        <template v-else-if="isImage(fileType)">
+          <el-image fit="contain" :src="file_url_https" />
+        </template>
 
-      <template v-else-if="fileType !== 'pdf'">
-        <iframe
-          :src="'https://view.officeapps.live.com/op/view.aspx?src=' + `${file_url_https}`"
-          width="100%"
-          height="490px"
-          scrolling="no"
-        >
-        </iframe>
+        <template v-else-if="fileType !== 'pdf'">
+          <iframe
+            :src="'https://view.officeapps.live.com/op/view.aspx?src=' + `${file_url_https}`"
+            width="100%"
+            height="490px"
+            scrolling="no"
+          >
+          </iframe>
+        </template>
       </template>
-    </template>
+    </div>
 
     <div slot="footer"></div>
   </el-dialog>
@@ -36,7 +55,7 @@
 
 <script>
 import pdf from 'vue-pdf';
-import { GetCurMaterialSent } from '@/api/live';
+import { GetCurMaterialSent, GetStudentList_FinishMaterial } from '@/api/live';
 import { GetCoursewareContent_View } from '@/api/course';
 import { GetFileStoreInfo } from '@/api/app';
 
@@ -64,7 +83,10 @@ export default {
       file_relative_path: '',
       file_url_https: '',
       pdfSrc: '',
-      numPages: 1
+      numPages: 1,
+      student_list: [],
+      curStudent: '',
+      listTimer: null
     };
   },
   computed: {
@@ -79,13 +101,25 @@ export default {
     dialogVisibleComplete(newVal) {
       if (newVal) {
         this.getCurMaterialSent();
+      } else {
+        // 对话框,关闭时清理
+        clearInterval(this.listTimer);
+        this.material_id = '';
+        this.material_name = '';
+        this.student_list = [];
       }
     },
-    material_id() {
-      if (this.material_type === 'COURSEWARE') {
-        this.getCoursewareContent_View();
-      } else {
-        this.getFileStoreInfo();
+    material_id(newVal) {
+      if (newVal) {
+        this.listTimer = setInterval(() => {
+          this.getStudentList_FinishMaterial();
+        }, 3000);
+
+        if (this.material_type === 'COURSEWARE') {
+          this.getCoursewareContent_View();
+        } else {
+          this.getFileStoreInfo();
+        }
       }
     }
   },
@@ -103,6 +137,20 @@ export default {
       );
     },
 
+    getStudentList_FinishMaterial() {
+      GetStudentList_FinishMaterial({
+        task_id: this.taskId,
+        material_id: this.material_id,
+        material_type: this.material_type
+      })
+        .then(({ student_list }) => {
+          this.student_list = student_list;
+        })
+        .catch(() => {
+          clearInterval(this.listTimer);
+        });
+    },
+
     getCoursewareContent_View() {
       GetCoursewareContent_View({ id: this.material_id }).then(res => {
         if (res.content) {
@@ -163,9 +211,45 @@ export default {
 .complete-list {
   @include dialog;
 
-  .el-image {
-    width: 100%;
-    height: calc(100% - 4px);
+  &-top {
+    .material-name {
+      font-size: 16px;
+      font-weight: 700;
+      color: #000;
+      margin-bottom: 16px;
+    }
+
+    .student-list {
+      display: flex;
+      justify-content: space-between;
+      height: 32px;
+      align-items: center;
+      margin-bottom: 24px;
+      overflow: hidden;
+
+      .avatar-list {
+        width: calc(100% - 48px);
+
+        .el-avatar {
+          cursor: pointer;
+        }
+      }
+
+      > i {
+        font-size: 18px;
+        cursor: pointer;
+      }
+    }
+  }
+
+  &-container {
+    overflow: auto;
+    height: calc(55vh - 105px);
+
+    .el-image {
+      width: 100%;
+      height: calc(100% - 4px);
+    }
   }
 }
 </style>

+ 30 - 6
src/views/live/teacher/index.vue

@@ -26,7 +26,9 @@
       <div class="live-container-left">
         <div v-show="callLoading" class="loading">
           <div class="loading-wrapper">
-            <p class="loading-title">正在呼叫,等待对方接通...</p>
+            <p class="loading-title">
+              正在呼叫【{{ connectStudent.student_name }}】,等待对方接通...
+            </p>
             <div>
               <el-button type="danger" circle @click="handsDown('loading')">
                 <svg-icon icon-class="hang-up" />
@@ -45,6 +47,7 @@
             <template v-else>
               <div class="student-audio">
                 <el-avatar icon="el-icon-user" :src="connectStudent.student_image_url" />
+                <span class="connect-name">{{ connectStudent.student_name }}</span>
                 <el-button type="danger" circle @click="handsDown">
                   <svg-icon icon-class="hang-up" />
                 </el-button>
@@ -375,16 +378,15 @@ export default {
       GetLiveRoomInfo({ task_id: this.task_id })
         .then(({ video_mode }) => {
           let uid = student.room_user_id;
-          let imageURL = student.student_image_url;
           if (video_mode === mode) {
-            common.invite(uid, imageURL);
+            this.inviteStudent(uid, student);
           } else {
             common.roomUpdate({
               video_mode: mode,
               roomUpdateSuccess: data => {
                 console.log(data, '连麦音视频模式更新请求成功!');
                 this.roomInfo.video_mode = mode;
-                common.invite(uid, imageURL);
+                this.inviteStudent(uid, student);
               },
               roomUpdateFailed: data => {
                 this.callLoading = false;
@@ -400,6 +402,24 @@ export default {
         });
     },
 
+    inviteStudent(uid, connectStudent) {
+      common.invite({
+        uid,
+        success: str => {
+          console.log('邀请上麦成功', str);
+          common.sendPublishMessage({
+            type: 'inviteImage',
+            connectStudent
+          });
+        },
+        fail: data => {
+          console.log('邀请上麦失败:', data);
+          this.callLoading = false;
+          this.$message.error(`邀请上麦失败:${data.errorMsg}`);
+        }
+      });
+    },
+
     // 下麦
     handsDown(type) {
       common.handsDown({
@@ -596,11 +616,15 @@ $live-bc: #3d3938;
           justify-content: center;
           align-items: center;
 
-          .el-avatar {
+          .connect-name {
+            color: #fff;
+            margin: 24px 0;
+          }
+
+          > .el-avatar {
             width: 96px;
             height: 96px;
             line-height: 96px;
-            margin-bottom: 24px;
 
             &--icon {
               font-size: 36px;

+ 4 - 20
src/views/live/teacher/live.js

@@ -1,5 +1,5 @@
 import { Message } from 'element-ui';
-import { rtc, publishStream, createLocalStream, sendPublishMessage } from '@/views/live/common';
+import { rtc, publishStream, createLocalStream } from '@/views/live/common';
 export {
   initSDK,
   downloadWebSDK,
@@ -296,24 +296,8 @@ export function liveRecord(status) {
 
 /**
  * 老师端发起邀请,邀请学生上麦。(举手模式)
- * @param {String} uid 被邀请用户id
+ * @param {Object} object
  */
-export function invite(uid, imageURL) {
-  rtc.invite({
-    uid: uid,
-    success: function (str) {
-      console.log('邀请上麦成功', str);
-      sendPublishMessage({
-        type: 'inviteImage',
-        imageURL
-      });
-    },
-    fail: function (data) {
-      console.log(data);
-      Message({
-        type: 'error',
-        message: `邀请上麦失败:${data.errorMsg}`
-      });
-    }
-  });
+export function invite(object) {
+  rtc.invite(object);
 }

+ 1 - 1
src/views/teacher/create_course/step_table/CreateTask.vue

@@ -33,7 +33,7 @@
                 <el-dropdown-item class="dropdown-menu" :command="{ id: item.id, type: 'edit' }">
                   <span>编辑</span><svg-icon icon-class="edit" />
                 </el-dropdown-item>
-                <el-dropdown-item class="dropdown-menu" :command="{ id: item.id, type: 'delete ' }">
+                <el-dropdown-item class="dropdown-menu" :command="{ id: item.id, type: 'delete' }">
                   <span>删除</span><svg-icon icon-class="delete" />
                 </el-dropdown-item>
               </el-dropdown-menu>

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

@@ -174,10 +174,10 @@ export default {
   }
 
   &-container {
-    margin: 16px 0;
+    margin-top: 16px;
     border-radius: 8px;
     width: 100%;
-    min-height: calc(100vh - 515px);
+    min-height: calc(100vh - 522px);
     background-color: #fff;
 
     &-title {
@@ -240,7 +240,7 @@ export default {
             padding: 16px 24px;
             border: 1px solid #ccc;
             border-radius: 8px;
-            margin-right: 15px;
+            margin: 10px 15px 10px 0;
             background-color: #fff4e3;
 
             > div {

+ 0 - 2
src/views/teacher/main/index.vue

@@ -68,8 +68,6 @@ export default {
 .main-container {
   @include container;
 
-  height: calc(100% - 19px);
-
   // 切换菜单
   .menu {
     width: 318px;