dusenyao 3 роки тому
батько
коміт
a75bd3285d

+ 101 - 0
src/common/show_file/index.vue

@@ -0,0 +1,101 @@
+<template>
+  <el-dialog
+    class="show-file"
+    :visible="dialogVisibleShowFile"
+    width="900px"
+    title="查看文件"
+    @close="dialogShowFileClose"
+  >
+    <template v-if="fileType === 'pdf'">
+      <pdf v-for="i in numPages" :key="i" :src="pdfSrc" :page="i" />
+    </template>
+
+    <template v-else-if="isImage(fileType)">
+      <div class="image-parent">
+        <el-image fit="contain" :src="fileUrl" />
+      </div>
+    </template>
+
+    <template v-else>
+      <iframe
+        :src="'https://view.officeapps.live.com/op/view.aspx?src=' + `${fileUrl}`"
+        width="100%"
+        height="490px"
+        scrolling="no"
+      />
+    </template>
+
+    <div slot="footer">
+      <el-button @click="dialogShowFileClose">关闭</el-button>
+    </div>
+  </el-dialog>
+</template>
+
+<script>
+import pdf from 'vue-pdf';
+
+export default {
+  components: { pdf },
+  props: {
+    fileName: {
+      default: '',
+      type: String
+    },
+    fileUrl: {
+      default: '',
+      type: String
+    }
+  },
+  data() {
+    return {
+      dialogVisibleShowFile: false,
+      pdfSrc: '',
+      numPages: 1
+    };
+  },
+  computed: {
+    fileType() {
+      return this.fileName.slice(this.fileName.lastIndexOf('.') + 1, this.fileName.length);
+    }
+  },
+  methods: {
+    getNumPages(url) {
+      let loadingTask = pdf.createLoadingTask(url);
+      loadingTask.promise
+        .then(pdf => {
+          this.pdfSrc = loadingTask;
+          this.numPages = pdf.numPages;
+        })
+        .catch(err => {
+          console.error('pdf加载失败', err);
+          this.$message.error('pdf加载失败');
+        });
+    },
+
+    showDialog() {
+      this.dialogVisibleShowFile = true;
+    },
+
+    dialogShowFileClose() {
+      this.dialogVisibleShowFile = false;
+    },
+
+    isImage(type) {
+      return ['jpeg', 'gif', 'jpg', 'png', 'bmp', 'pic', 'svg'].includes(type);
+    }
+  }
+};
+</script>
+
+<style lang="scss">
+@import '~@/styles/mixin.scss';
+
+.show-file {
+  @include dialog;
+
+  .image-parent {
+    display: flex;
+    justify-content: center;
+  }
+}
+</style>

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

@@ -24,21 +24,20 @@
     </template>
     <template v-else>
       <template v-if="fileType === 'pdf'">
-        <pdf v-for="i in numPages" :key="i" :src="pdfSrc" :page="i"></pdf>
+        <pdf v-for="i in numPages" :key="i" :src="pdfSrc" :page="i" />
       </template>
 
       <template v-else-if="isImage(fileType)">
         <el-image fit="contain" :src="file_url_https" />
       </template>
 
-      <template v-if="fileType !== 'pdf'">
+      <template v-else>
         <iframe
           :src="'https://view.officeapps.live.com/op/view.aspx?src=' + `${file_url_https}`"
           width="100%"
           height="490px"
           scrolling="no"
-        >
-        </iframe>
+        />
       </template>
     </template>
 
@@ -182,19 +181,25 @@ export default {
     },
 
     finishMyMaterial() {
-      if (this.materialType === 'COURSEWARE' && !this.$refs.courseware.handleBookIsDone()) {
+      if (this.materialType === 'COURSEWARE' && this.exam_answer.length === 0) {
         this.$message.warning('请完成课件');
         return;
       }
+      const loading = this.$loading();
       FinishMyMaterial({
         task_id: this.taskId,
         material_id: this.materialId,
         material_type: this.materialType,
         exam_answer: this.exam_answer
-      }).then(() => {
-        this.$message.success('完成推送资料成功');
-        this.$emit('dialogMaterialClose');
-      });
+      })
+        .then(() => {
+          this.$message.success('完成推送资料成功');
+          this.$emit('dialogMaterialClose');
+        })
+        .finally(() => {
+          loading.close();
+          this.exam_answer = '';
+        });
     },
 
     isImage(type) {

+ 10 - 1
src/utils/validate.js

@@ -10,7 +10,7 @@ export function isExternal(path) {
 /**
  * @description 只允许输入两位小数
  * @param {String} value
- * @returns Number
+ * @returns { Number }
  */
 export function twoDecimal(value) {
   if (!value) {
@@ -23,3 +23,12 @@ export function twoDecimal(value) {
   val = val.replace(/^(\-)*(\d+)\.(\d\d).*$/, '$1$2.$3'); // 只能输入两位小数
   return val;
 }
+
+/**
+ * 是否为允许的文件类型
+ * @param {String} fileName
+ */
+export function isAllowFileType(fileName) {
+  let suffix = fileName.slice(fileName.lastIndexOf('.') + 1, fileName.length);
+  return ['mp3', 'mp4', 'doc', 'docx', 'pdf', 'ppt', 'xls', 'jpg', 'gif', 'png'].includes(suffix);
+}

+ 4 - 0
src/views/live/teacher/index.vue

@@ -748,8 +748,12 @@ export default {
 
     // 弹出框方法
     dialogGroup() {
+      const loading = this.$loading({
+        text: '正在进行分组,请等待...'
+      });
       // 开始分组讨论
       StartGroup({ task_id: this.task_id, group_count: this.group_count }).then(() => {
+        loading.close();
         this.$message.success('开启分组讨论成功');
         this.$router.push({
           path: '/live/teacher/group',

+ 6 - 1
src/views/task_details/TaskTop.vue

@@ -13,7 +13,7 @@
         color="#fff"
         :title="item.file_name"
       >
-        <a :href="item.file_url" target="_blank">{{ item.file_name }}</a>
+        <span @click="emitViewFile(item.file_name, item.file_url)">{{ item.file_name }}</span>
       </el-tag>
     </div>
   </div>
@@ -33,6 +33,11 @@ export default {
       },
       type: Object
     }
+  },
+  methods: {
+    emitViewFile(fileName, fileUrl) {
+      this.$emit('viewFile', fileName, fileUrl);
+    }
   }
 };
 </script>

+ 29 - 6
src/views/task_details/student/index.vue

@@ -1,6 +1,6 @@
 <template>
   <div v-loading="loading" class="task-detail">
-    <task-top :item-info="itemInfo" />
+    <task-top :item-info="itemInfo" @viewFile="viewFile" />
 
     <div class="task-detail-main">
       <div class="time-type">{{ timeType }}任务 {{ name }}</div>
@@ -34,7 +34,7 @@
             color="#fff"
             :title="item.file_name"
           >
-            <a :href="item.file_url" target="_blank">{{ item.file_name }}</a>
+            <span @click="viewFile(item.file_name, item.file_url)">{{ item.file_name }}</span>
           </el-tag>
         </div>
       </div>
@@ -50,7 +50,7 @@
                 color="#fff"
                 :title="item.file_name"
               >
-                <a :href="item.file_url" target="_blank">{{ item.file_name }}</a>
+                <span @click="viewFile(item.file_name, item.file_url)">{{ item.file_name }}</span>
               </el-tag>
             </div>
           </div>
@@ -109,7 +109,7 @@
       <template v-else>
         <div class="submit-homework">
           <span class="label">提交作业</span>
-          <el-upload action="no" :http-request="upload" multiple :show-file-list="false" accept="*">
+          <el-upload action="no" :http-request="upload" multiple :show-file-list="false">
             <el-button><svg-icon icon-class="upload" /> 上传文件</el-button>
           </el-upload>
         </div>
@@ -149,6 +149,8 @@
       :dialog-visible="dialogVisible"
       @dialogClose="dialogClose"
     />
+
+    <show-file ref="file" :file-name="showCurFileName" :file-url="showCurFileUrl" />
   </div>
 </template>
 
@@ -156,15 +158,18 @@
 import TaskTop from '../TaskTop.vue';
 import FinishCourseware from '@/components/course/FinishCourseware.vue';
 import CompletionView from '@/components/course/CompletionView.vue';
+import ShowFile from '@/common/show_file';
 import { fileUpload, FileDownload } from '@/api/app';
 import { CreateEnterLiveRoomSession } from '@/api/live';
 import { GetTaskInfo, FillMyTaskExecuteInfo_Student } from '@/api/course';
+import { isAllowFileType } from '@/utils/validate';
 
 export default {
   components: {
     FinishCourseware,
     TaskTop,
-    CompletionView
+    CompletionView,
+    ShowFile
   },
   data() {
     return {
@@ -193,7 +198,9 @@ export default {
       my_execute_info: {},
       student_remark: '',
       student_score: 0,
-      loading: false
+      loading: false,
+      showCurFileName: '',
+      showCurFileUrl: ''
     };
   },
   computed: {
@@ -256,6 +263,12 @@ export default {
   },
   methods: {
     upload(file) {
+      let fileName = file.file.name;
+      if (!isAllowFileType(fileName)) {
+        this.$message.warning(`文件:【${fileName}】文件类型,不允许上传`);
+        return;
+      }
+
       fileUpload('Open', file).then(({ file_info_list }) => {
         if (file_info_list.length > 0) {
           let { file_id, file_name, file_url } = file_info_list[0];
@@ -274,6 +287,12 @@ export default {
       });
     },
 
+    viewFile(fileName, fileUrl) {
+      this.showCurFileName = fileName;
+      this.showCurFileUrl = fileUrl;
+      this.$refs.file.showDialog();
+    },
+
     fillTaskExecuteInfo_Student() {
       let homework_file_id_list = [];
       this.file_list.forEach(item => {
@@ -356,6 +375,10 @@ $bor-color: #d9d9d9;
     border-radius: 4px;
     margin: 0 8px 6px 0;
     border-color: $bor-color;
+
+    > span {
+      cursor: pointer;
+    }
   }
 
   &-main {

+ 20 - 5
src/views/task_details/teacher/index.vue

@@ -1,6 +1,6 @@
 <template>
   <div v-loading="loading" class="teacher-task-detail">
-    <task-top :item-info="itemInfo" />
+    <task-top :item-info="itemInfo" @viewFile="viewFile" />
 
     <div class="teacher-task-detail-main">
       <div class="student-finish-situation">
@@ -55,7 +55,7 @@
           <div class="title">文档列表</div>
           <div>
             <el-tag v-for="item in accessory_list" :key="item.file_id" :title="item.file_name">
-              <a :href="item.file_url" target="_blank">{{ item.file_name }}</a>
+              <span @click="viewFile(item.file_name, item.file_url)">{{ item.file_name }}</span>
             </el-tag>
           </div>
           <div class="title">作业列表</div>
@@ -66,7 +66,7 @@
               color="#fff"
               :title="item.file_name"
             >
-              <a :href="item.file_url" target="_blank">{{ item.file_name }}</a>
+              <span @click="viewFile(item.file_name, item.file_url)">{{ item.file_name }}</span>
             </el-tag>
           </div>
           <div class="title">学生留言</div>
@@ -103,11 +103,14 @@
       :dialog-visible="dialogVisible"
       @dialogClose="dialogClose"
     />
+
+    <show-file ref="file" :file-name="showCurFileName" :file-url="showCurFileUrl" />
   </div>
 </template>
 
 <script>
 import CompletionView from '@/components/course/CompletionView.vue';
+import ShowFile from '@/common/show_file';
 import TaskTop from '../TaskTop.vue';
 import {
   GetTaskInfo,
@@ -116,7 +119,7 @@ import {
 } from '@/api/course';
 
 export default {
-  components: { CompletionView, TaskTop },
+  components: { CompletionView, TaskTop, ShowFile },
   data() {
     return {
       id: this.$route.params.id,
@@ -152,7 +155,9 @@ export default {
       dialogVisible: false,
       curCoursewareId: '',
       loading: false,
-      student_list_height: 490
+      student_list_height: 490,
+      showCurFileName: '',
+      showCurFileUrl: ''
     };
   },
   created() {
@@ -246,6 +251,12 @@ export default {
       this.dialogVisible = false;
     },
 
+    viewFile(fileName, fileUrl) {
+      this.showCurFileName = fileName;
+      this.showCurFileUrl = fileUrl;
+      this.$refs.file.showDialog();
+    },
+
     buttonName() {
       let list = this.student_list;
       if (list.length <= 0) return '';
@@ -293,6 +304,10 @@ $bor-color: #d9d9d9;
     border-radius: 4px;
     margin: 0 8px 6px 0;
     border-color: $bor-color;
+
+    > span {
+      cursor: pointer;
+    }
   }
 
   &-main {