dusenyao 4 سال پیش
والد
کامیت
77e594ab40

+ 18 - 17
.vscode/javascript.code-snippets

@@ -1,18 +1,19 @@
 {
-	// Place your gcls_sys_learn_web 工作区 snippets here. Each snippet is defined under a snippet name and has a scope, prefix, body and
-	// description. Add comma separated ids of the languages where the snippet is applicable in the scope field. If scope
-	// is left empty or omitted, the snippet gets applied to all languages. The prefix is what is
-	// used to trigger the snippet and the body will be expanded and inserted. Possible variables are:
-	// $1, $2 for tab stops, $0 for the final cursor position, and ${1:label}, ${2:another} for placeholders.
-	// Placeholders with the same ids are connected.
-	// Example:
-	// "Print to console": {
-	// 	"scope": "javascript,typescript",
-	// 	"prefix": "log",
-	// 	"body": [
-	// 		"console.log('$1');",
-	// 		"$2"
-	// 	],
-	// 	"description": "Log output to console"
-	// }
-}
+  "api request": {
+    "scope": "javascript,typescript",
+    "prefix": "api",
+    "body": [
+      "export function n(data) {",
+      "  let params = getRequestParams('$1');",
+      "",
+      "  return request({",
+      "    method: 'post',",
+      "    url: process.env$2,",
+      "    params,",
+      "    data",
+      "  });",
+      "}"
+    ],
+    "description": "api 请求基本格式"
+  }
+}

+ 45 - 0
src/api/live.js

@@ -44,3 +44,48 @@ export function StudentExitLiveRoom(data) {
     data
   });
 }
+
+/**
+ * 得到可以推送的资料列表(课件或文档)
+ * @param {Object} data { task_id 任务ID }
+ */
+export function GetMaterialListForSendToStudent(data) {
+  let params = getRequestParams('live_room-live_room_dispatch-GetMaterialListForSendToStudent');
+
+  return request({
+    method: 'post',
+    url: process.env.VUE_APP_LearnWebSI,
+    params,
+    data
+  });
+}
+
+/**
+ * 推送资料
+ * @param {Object} data
+ */
+export function SendMaterial(data) {
+  let params = getRequestParams('live_room-live_room_dispatch-SendMaterial');
+
+  return request({
+    method: 'post',
+    url: process.env.VUE_APP_LearnWebSI,
+    params,
+    data
+  });
+}
+
+/**
+ * 获取当前推送的资料
+ * @param {Object} data {task_id 任务ID}
+ */
+export function GetCurMaterialSent(data) {
+  let params = getRequestParams('live_room-live_room_dispatch-GetCurMaterialSent');
+
+  return request({
+    method: 'post',
+    url: process.env.VUE_APP_LearnWebSI,
+    params,
+    data
+  });
+}

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

@@ -0,0 +1,73 @@
+<template>
+  <el-dialog
+    class="cur-material"
+    :visible="dialogVisibleMaterial"
+    width="900px"
+    title="当前推送课件"
+    @close="dialogMaterialClose"
+  >
+    {{ materialName }}
+    <!-- <question :context="context" /> -->
+  </el-dialog>
+</template>
+
+<script>
+import { GetCoursewareContent_View } from '@/api/course';
+
+export default {
+  props: {
+    dialogVisibleMaterial: {
+      default: false,
+      type: Boolean
+    },
+    materialId: {
+      default: '',
+      type: String
+    },
+    materialName: {
+      default: '',
+      type: String
+    },
+    materialType: {
+      default: '',
+      type: String
+    },
+    materialPictureUrl: {
+      default: '',
+      type: String
+    }
+  },
+  data() {
+    return {
+      context: null
+    };
+  },
+  methods: {
+    dialogMaterialClose() {
+      this.$emit('dialogMaterialClose');
+    },
+    getCoursewareContent_View() {
+      GetCoursewareContent_View({ id: this.materialId }).then(res => {
+        if (res.content) {
+          this.context = {
+            id: this.currentCourse,
+            ui_type: JSON.parse(res.content).question.ui_type,
+            sort_number: 1,
+            content: JSON.parse(res.content)
+          };
+        } else {
+          this.context = null;
+        }
+      });
+    }
+  }
+};
+</script>
+
+<style lang="scss">
+@import '~@/styles/mixin.scss';
+
+.cur-material {
+  @include dialog;
+}
+</style>

+ 114 - 0
src/components/live/SelectMaterial.vue

@@ -0,0 +1,114 @@
+<template>
+  <div>
+    <el-dialog
+      class="select-material"
+      :visible="dialogVisible"
+      width="900px"
+      title="课件推送"
+      @close="dialogClose"
+    >
+      <div v-for="item in material_list" :key="item.material_id" class="material">
+        <el-image fit="contain" :src="item.material_picture_url" />
+        <div class="material-info">
+          <div class="material-info-name">{{ item.material_name }}</div>
+          <div class="material-info-push">
+            <div></div>
+            <el-button type="primary" @click="sendMaterial(item.material_id, item.material_type)">
+              <svg-icon icon-class="push" />
+            </el-button>
+          </div>
+        </div>
+      </div>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import { GetMaterialListForSendToStudent, SendMaterial } from '@/api/live';
+
+export default {
+  props: {
+    dialogVisible: {
+      default: false,
+      type: Boolean
+    },
+    taskId: {
+      default: '',
+      type: String
+    }
+  },
+  data() {
+    return {
+      material_list: []
+    };
+  },
+  watch: {
+    dialogVisible(newVal) {
+      if (newVal) {
+        this.getMaterialListForSendToStudent();
+      }
+    }
+  },
+  methods: {
+    getMaterialListForSendToStudent() {
+      GetMaterialListForSendToStudent({ task_id: this.taskId }).then(({ material_list }) => {
+        this.material_list = material_list;
+      });
+    },
+    sendMaterial(material_id, material_type) {
+      SendMaterial({ task_id: this.taskId, material_id, material_type }).then(() => {
+        this.$message.success('课件推送成功');
+        this.$emit('dialogPush');
+      });
+    },
+    dialogClose() {
+      this.$emit('dialogClose');
+    }
+  }
+};
+</script>
+
+<style lang="scss">
+@import '~@/styles/mixin.scss';
+$list-h: 120px;
+
+.select-material {
+  @include dialog;
+
+  .el-dialog__body {
+    overflow-y: auto;
+  }
+
+  .material {
+    display: flex;
+    border: 1px solid #d9d9d9;
+    padding: 16px;
+    margin-bottom: 16px;
+
+    .el-image {
+      width: 192px;
+      height: $list-h;
+    }
+
+    &-info {
+      flex: 6;
+      height: $list-h;
+      margin-left: 16px;
+      display: flex;
+      flex-direction: column;
+      justify-content: space-between;
+
+      &-name {
+        font-size: 18px;
+        font-weight: 700;
+      }
+
+      &-push {
+        width: 100%;
+        display: flex;
+        justify-content: space-between;
+      }
+    }
+  }
+}
+</style>

+ 5 - 0
src/icons/svg/edit.svg

@@ -0,0 +1,5 @@
+<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M20 11.5V7L15.5 2H5C4.44771 2 4 2.44771 4 3V21C4 21.5523 4.44771 22 5 22H11" stroke="#333333" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
+<path d="M16 22L21 17L19 15L14 20V22H16Z" stroke="#333333" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
+<path d="M15 2V7H20" stroke="#333333" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
+</svg>

+ 14 - 0
src/styles/mixin.scss

@@ -52,3 +52,17 @@
     }
   }
 }
+
+@mixin dialog {
+  .el-dialog {
+    &__body {
+      padding: 15px 20px 0;
+      height: 55vh;
+      color: $color;
+    }
+
+    &__title {
+      font-weight: 700;
+    }
+  }
+}

+ 69 - 0
src/views/live/CompleteList.vue

@@ -0,0 +1,69 @@
+<template>
+  <el-dialog
+    class="complete-list"
+    :visible="dialogVisibleComplete"
+    width="900px"
+    title="答题统计"
+    @close="dialogCompleteClose"
+  >
+    {{ material_name }}
+  </el-dialog>
+</template>
+
+<script>
+import { GetCurMaterialSent } from '@/api/live';
+
+export default {
+  props: {
+    dialogVisibleComplete: {
+      default: false,
+      type: Boolean
+    },
+    taskId: {
+      default: '',
+      type: String
+    }
+  },
+  data() {
+    return {
+      material_id: '',
+      material_name: '',
+      material_type: '',
+      material_picture_url: ''
+    };
+  },
+  watch: {
+    dialogVisibleComplete(newVal) {
+      if (newVal) {
+        this.getCurMaterialSent();
+      }
+    }
+  },
+  methods: {
+    getCurMaterialSent() {
+      GetCurMaterialSent({ task_id: this.taskId }).then(
+        ({ material_id, material_name, material_type, material_picture_url }) => {
+          if (material_id !== undefined && material_id.length > 0) {
+            this.material_id = material_id;
+            this.material_name = material_name;
+            this.material_type = material_type;
+            this.material_picture_url = material_picture_url;
+          }
+        }
+      );
+    },
+
+    dialogCompleteClose() {
+      this.$emit('dialogCompleteClose');
+    }
+  }
+};
+</script>
+
+<style lang="scss">
+@import '~@/styles/mixin.scss';
+
+.complete-list {
+  @include dialog;
+}
+</style>

+ 90 - 27
src/views/live/index.vue

@@ -41,23 +41,16 @@
         </div>
         <div class="button-group">
           <div class="button-group-left">
-            <span v-if="userType === 'TEACHER'" @click="publishShareStream">
+            <span v-if="userType === 'TEACHER'" title="屏幕共享" @click="publishShareStream">
               <svg-icon icon-class="share" />
             </span>
-            <span v-if="userType === 'TEACHER'" @click="showDrawSetting">
-              <svg-icon icon-class="draw"></svg-icon>
+            <span v-if="userType === 'TEACHER'" title="白板" @click="showDrawSetting">
+              <svg-icon icon-class="draw" />
             </span>
-            <span v-if="userType === 'TEACHER'">
-              <svg-icon icon-class="push"></svg-icon>
+            <span v-if="userType === 'TEACHER'" title="课件推送" @click="dialogVisible = true">
+              <svg-icon icon-class="push" />
             </span>
           </div>
-          <!-- <el-button>群组讨论</el-button>
-            <el-button>推送课件</el-button> -->
-          <!-- <el-button @click="showDrawSetting">屏幕画笔</el-button>
-          </div>
-          <div>
-            <el-button @click="publishShareStream">共享屏幕</el-button>
-          </div> -->
           <div class="button-group-right"></div>
         </div>
         <div class="live-container-left-chat">
@@ -112,20 +105,64 @@
         </div>
       </div>
     </div>
+
+    <!-- 推送资料 -->
+    <select-material
+      v-if="userType === 'TEACHER'"
+      :dialog-visible="dialogVisible"
+      :task-id="task_id"
+      @dialogClose="dialogClose"
+      @dialogPush="dialogPush"
+    />
+
+    <complete-list
+      v-if="userType === 'TEACHER'"
+      :task-id="task_id"
+      :dialog-visible-complete="dialogVisibleComplete"
+      @dialogCompleteClose="dialogCompleteClose"
+    />
+
+    <cur-material
+      v-if="userType === 'STUDENT'"
+      :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 } from '@/api/live';
+import { GetLiveRoomStudentList, StudentExitLiveRoom, GetCurMaterialSent } 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';
 
 export default {
   name: 'Live',
+  components: {
+    SelectMaterial,
+    CurMaterial,
+    CompleteList
+  },
   data() {
     return {
       userType: this.$store.state.user.user_type,
       task_id: this.$route.query.task_id,
       connection: false,
+      dialogVisible: false,
+      dialogVisibleMaterial: false,
+      material_id: '',
+      material_name: '',
+      material_type: '',
+      material_picture_url: '',
+      // 学员完成
+      dialogVisibleComplete: false,
+      // 定时器
+      timer: null,
       rtc: null,
       roomData: {
         desc: '直播间标题',
@@ -187,9 +224,9 @@ export default {
       },
       true
     );
-  },
-  beforeDestroy() {
-    // document.querySelector('script[src="https://image.csslcloud.net/js/dpc.js"]').remove();
+    if (this.userType === 'STUDENT') {
+      this.getCurMaterialSent();
+    }
   },
   methods: {
     // 加载直播所需 SDK,加载完成后才能初始化
@@ -337,6 +374,41 @@ export default {
 
     publishStream() {
       common.publishStream('main');
+    },
+
+    dialogClose() {
+      this.dialogVisible = false;
+    },
+
+    dialogPush() {
+      this.dialogVisible = false;
+      this.dialogVisibleComplete = true;
+    },
+
+    dialogMaterialClose() {
+      this.dialogVisibleMaterial = false;
+      this.getCurMaterialSent();
+    },
+
+    dialogCompleteClose() {
+      this.dialogVisibleComplete = 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);
+            }
+          }
+        );
+      }, 2000);
     }
   }
 };
@@ -398,6 +470,7 @@ $live-bc: #3d3938;
         border: 1px solid #ccc;
         position: relative;
         background-color: $live-bc;
+        overflow: hidden;
 
         // 设置屏幕画笔
         .draw-setting {
@@ -479,7 +552,6 @@ $live-bc: #3d3938;
         height: 48px;
         background-color: #4d4d4d;
         padding: 0 15px;
-        border-bottom-right-radius: 5px;
         border-bottom-left-radius: 5px;
 
         .svg-icon {
@@ -593,17 +665,8 @@ $live-bc: #3d3938;
   }
 
   .el-button {
-    background-color: #ececec;
-    border-radius: 8px;
+    border-radius: 4px;
     padding: 7px 12px;
   }
-
-  .el-dropdown + .el-dropdown {
-    margin-left: 10px;
-  }
-
-  .el-dropdown + .el-button {
-    margin-left: 10px;
-  }
 }
 </style>

+ 6 - 0
src/views/teacher/main/CurriculaList.vue

@@ -74,6 +74,9 @@
                   <svg-icon icon-class="more"></svg-icon>
                 </span>
                 <el-dropdown-menu slot="dropdown">
+                  <el-dropdown-item @click.native="edit(row.id)">
+                    <svg-icon icon-class="edit" /> Edit
+                  </el-dropdown-item>
                   <el-dropdown-item @click.native="studentList(row.id)">
                     <svg-icon icon-class="students" /> Students
                   </el-dropdown-item>
@@ -212,6 +215,9 @@ export default {
     },
     studentList(id) {
       this.$router.push(`/student_list/index/${id}`);
+    },
+    edit(id) {
+      this.$router.push(`/create_course_step_table/course_info?id=${id}`);
     }
   }
 };