فهرست منبع

离线考试:上传组件拆分

Michael Wang 7 سال پیش
والد
کامیت
9f8a55bdd3

+ 1 - 1
src/features/OfflineExam/OfflineExamHome.vue

@@ -6,7 +6,7 @@
     </Breadcrumb>
 
     <div class="home">
-      <ecs-offline-list :courses="courses"></ecs-offline-list>
+      <ecs-offline-list :courses="courses" @reloadList="reloadList"></ecs-offline-list>
     </div>
   </main-layout>
 </template>

+ 9 - 119
src/features/OfflineExam/OfflineExamList.vue

@@ -34,14 +34,7 @@
                 <i-button class="qm-primary-button">
                   <a class="qm-primary-button" href="https://ecs-static.qmth.com.cn/offline-exam/答题卡.zip" download>下载答题卡</a>
                 </i-button>
-                <div>
-                  <Upload :headers="headers" :data="{fileType: fileType}" :before-upload="handleBeforeUpload" :action="'/api/offline_exam/'+course.examRecordId+'/submit'" :max-size="1024*30" :format="['pdf','zip']" :on-format-error="handleFormatError" :on-exceeded-size="handleMaxSize" :on-success="handleSuccess" :on-error="handleError" :show-upload-list="false">
-                    <Button type="ghost" icon="ios-cloud-upload-outline" class="qm-primary-button" style="width: 100%;">上传作答</Button>
-                  </Upload>
-                  <div v-if="file !== null">待上传文件: {{ file.name }}
-                    <Button type="text" @click="upload" :loading="loadingStatus">{{ loadingStatus ? '上传中...' : '上传' }}</Button>
-                  </div>
-                </div>
+                <ecs-offline-exam-upload :course="course" @reloadList="reloadList"></ecs-offline-exam-upload>
               </div>
 
               <div v-else style="display: grid; grid-gap: 10px">
@@ -66,121 +59,21 @@
 
 <script>
 import { TK_SERVER_URL } from "@/constants/constants.js";
+import OfflineExamUpload from "./OfflineExamUpload.vue";
 
 export default {
   name: "EcsOfflineList",
   data() {
     return {
-      tk_server_url: TK_SERVER_URL,
-      headers: {
-        token: window.localStorage.getItem("token"),
-        key: window.localStorage.getItem("key")
-      },
-      file: null,
-      fileType: null,
-      loadingStatus: false
+      tk_server_url: TK_SERVER_URL
     };
   },
   props: {
-    courses: Array,
-    reloadList: Function
+    courses: Array
   },
   methods: {
-    fileFormatCheck(file, resolve, reject) {
-      console.time("FileOpen");
-      function getMimetype(signature) {
-        switch (signature) {
-          case "89504E47":
-            return "image/png";
-          case "47494638":
-            return "image/gif";
-          case "25504446":
-            return "application/pdf";
-          case "FFD8FFDB":
-          case "FFD8FFE0":
-          case "FFD8FFE1":
-            return "image/jpeg";
-          case "504B0304":
-            return "application/zip";
-          default:
-            return "Unknown filetype";
-        }
-      }
-
-      const filereader = new FileReader();
-      let uploads = [];
-      filereader.onloadend = evt => {
-        if (evt.target.readyState === FileReader.DONE) {
-          const uint = new Uint8Array(evt.target.result);
-          let bytes = [];
-          uint.forEach(byte => {
-            bytes.push(byte.toString(16));
-          });
-          const hex = bytes.join("").toUpperCase();
-          uploads.push({
-            filename: file.name,
-            filetype: file.type ? file.type : "Unknown/Extension missing",
-            binaryFileType: getMimetype(hex),
-            hex: hex
-          });
-
-          if (
-            ["application/zip", "application/pdf"].includes(getMimetype(hex))
-          ) {
-            resolve();
-          } else {
-            console.log("binary file type check: not zip or pdf");
-            this.$Notice.warning({
-              title: "作答文件损坏",
-              desc: file.name + " 文件无法以 .zip 或 .pdf 读取。"
-            });
-            this.file = null;
-            this.loadingStatus = false;
-            reject();
-          }
-        }
-        console.timeEnd("FileOpen");
-      };
-      const blob = file.slice(0, 4);
-      filereader.readAsArrayBuffer(blob);
-    },
-    upload(file) {
-      this.file = file;
-      return false;
-    },
-    handleSuccess() {
-      this.file = null;
-      this.loadingStatus = false;
-      this.$Message.success("上传成功");
-    },
-    handleError() {
-      this.file = null;
-      this.loadingStatus = false;
-      this.$Message.error("上传失败");
-    },
-    handleFormatError(file) {
-      this.$Notice.warning({
-        title: "作答文件格式不对",
-        desc: file.name + " 文件格式不对,请选择 .zip 或 .pdf 文件。"
-      });
-    },
-    handleMaxSize(file) {
-      this.$Notice.warning({
-        title: "超出文件大小限制",
-        desc: file.name + " 太大,作答文件不能超过30M."
-      });
-    },
-    handleBeforeUpload(file) {
-      if (file.type.includes("/pdf")) {
-        this.fileType = "pdf";
-      } else if (file.type.includes("/zip")) {
-        this.fileType = "zip";
-      }
-      this.file = file;
-      this.loadingStatus = true;
-      return new Promise((resolve, reject) =>
-        this.fileFormatCheck(file, resolve, reject)
-      );
+    async reloadList() {
+      this.$emit("reloadList");
     },
     async enterExam(course) {
       await this.$http.get("/api/offline_exam/start", {
@@ -201,6 +94,9 @@ export default {
         course.paperId +
         "?isback=true";
     }
+  },
+  components: {
+    "ecs-offline-exam-upload": OfflineExamUpload
   }
 };
 </script>
@@ -223,9 +119,3 @@ export default {
   padding: 10px;
 }
 </style>
-
-<style lang="postcss">
-.list .ivu-upload-select {
-  width: 100%;
-}
-</style>

+ 129 - 0
src/features/OfflineExam/OfflineExamUpload.vue

@@ -0,0 +1,129 @@
+<template>
+  <div>
+    <Upload :headers="headers" :data="{fileType: fileType}" :before-upload="handleBeforeUpload" :action="'/api/offline_exam/'+course.examRecordId+'/submit'" :max-size="1024*30" :format="['pdf','zip']" :on-format-error="handleFormatError" :on-exceeded-size="handleMaxSize" :on-success="handleSuccess" :on-error="handleError" :show-upload-list="false">
+      <Button type="ghost" icon="ios-cloud-upload-outline" class="qm-primary-button" style="width: 100%;">上传作答</Button>
+    </Upload>
+    <div v-if="file !== null">待上传文件: {{ file.name }}
+      <Button type="text" :loading="loadingStatus">{{ loadingStatus ? '上传中...' : '上传' }}</Button>
+    </div>
+  </div>
+</template>
+
+<script>
+export default {
+  name: "EcsOfflineUpload",
+  data() {
+    return {
+      headers: {
+        token: window.localStorage.getItem("token"),
+        key: window.localStorage.getItem("key")
+      },
+      file: null,
+      fileType: null,
+      loadingStatus: false
+    };
+  },
+  props: {
+    course: Object
+  },
+  methods: {
+    fileFormatCheck(file, resolve, reject) {
+      function getMimetype(signature) {
+        switch (signature) {
+          case "89504E47":
+            return "image/png";
+          case "47494638":
+            return "image/gif";
+          case "25504446":
+            return "application/pdf";
+          case "FFD8FFDB":
+          case "FFD8FFE0":
+          case "FFD8FFE1":
+            return "image/jpeg";
+          case "504B0304":
+            return "application/zip";
+          default:
+            return "Unknown filetype";
+        }
+      }
+
+      const filereader = new FileReader();
+      let uploads = [];
+      filereader.onloadend = evt => {
+        if (evt.target.readyState === FileReader.DONE) {
+          const uint = new Uint8Array(evt.target.result);
+          let bytes = [];
+          uint.forEach(byte => {
+            bytes.push(byte.toString(16));
+          });
+          const hex = bytes.join("").toUpperCase();
+          uploads.push({
+            filename: file.name,
+            filetype: file.type ? file.type : "Unknown/Extension missing",
+            binaryFileType: getMimetype(hex),
+            hex: hex
+          });
+
+          if (
+            ["application/zip", "application/pdf"].includes(getMimetype(hex))
+          ) {
+            resolve();
+          } else {
+            console.log("binary file type check: not zip or pdf");
+            this.$Notice.warning({
+              title: "作答文件损坏",
+              desc: file.name + " 文件无法以 .zip 或 .pdf 读取。"
+            });
+            this.file = null;
+            this.loadingStatus = false;
+            reject();
+          }
+        }
+      };
+      const blob = file.slice(0, 4);
+      filereader.readAsArrayBuffer(blob);
+    },
+    handleSuccess() {
+      this.file = null;
+      this.loadingStatus = false;
+      this.$Message.success("上传成功");
+      this.$emit("reloadList");
+    },
+    handleError() {
+      this.file = null;
+      this.loadingStatus = false;
+      this.$Message.error("上传失败");
+    },
+    handleFormatError(file) {
+      this.$Notice.warning({
+        title: "作答文件格式不对",
+        desc: file.name + " 文件格式不对,请选择 .zip 或 .pdf 文件。"
+      });
+    },
+    handleMaxSize(file) {
+      this.$Notice.warning({
+        title: "超出文件大小限制",
+        desc: file.name + " 太大,作答文件不能超过30M."
+      });
+    },
+    handleBeforeUpload(file) {
+      if (file.type.includes("/pdf")) {
+        this.fileType = "pdf";
+      } else if (file.type.includes("/zip")) {
+        this.fileType = "zip";
+      }
+      this.file = file;
+      this.loadingStatus = true;
+      return new Promise((resolve, reject) =>
+        this.fileFormatCheck(file, resolve, reject)
+      );
+    }
+  }
+};
+</script>
+
+<style lang="postcss">
+.list .ivu-upload-select {
+  width: 100%;
+}
+</style>