浏览代码

试题上传修改

zhangjie 2 年之前
父节点
当前提交
cd1e2d2d1e
共有 2 个文件被更改,包括 194 次插入3 次删除
  1. 164 0
      src/components/UploadButton.vue
  2. 30 3
      src/modules/question/components/QuestionImportEdit.vue

+ 164 - 0
src/components/UploadButton.vue

@@ -0,0 +1,164 @@
+<template>
+  <el-upload
+    :action="uploadUrl"
+    :headers="headers"
+    :max-size="maxSize"
+    :format="format"
+    :accept="accept"
+    :data="uploadDataDict"
+    :before-upload="handleBeforeUpload"
+    :on-error="handleError"
+    :on-success="handleSuccess"
+    :http-request="upload"
+    :disabled="disabled"
+    :show-file-list="false"
+    style="display: inline-block; margin: 0 10px"
+    ref="UploadComp"
+  >
+    <el-button
+      :type="btnType"
+      :icon="btnIcon"
+      :loading="loading"
+      :disabled="disabled"
+      >{{ btnContent }}</el-button
+    >
+  </el-upload>
+</template>
+
+<script>
+import { fileMD5 } from "@/plugins/md5";
+import { $httpWithMsg } from "@/plugins/axios";
+
+export default {
+  name: "UploadButton",
+  props: {
+    btnIcon: {
+      type: String,
+    },
+    btnType: {
+      type: String,
+      default: "default",
+    },
+    btnContent: {
+      type: String,
+    },
+    accept: {
+      type: String,
+    },
+    format: {
+      type: Array,
+      default() {
+        return ["xlsx", "xls"];
+      },
+    },
+    uploadUrl: {
+      type: String,
+      required: true,
+    },
+    uploadData: {
+      type: Object,
+      default() {
+        return {};
+      },
+    },
+    maxSize: {
+      type: Number,
+      default: 20 * 1024 * 1024,
+    },
+    addFilenameParam: {
+      type: String,
+      default: "filename",
+    },
+    disabled: { type: Boolean, default: false },
+  },
+  data() {
+    return {
+      headers: {
+        md5: "",
+      },
+      res: {},
+      loading: false,
+      uploadDataDict: {},
+    };
+  },
+  methods: {
+    checkFileFormat(fileType) {
+      const _file_format = fileType.split(".").pop().toLocaleLowerCase();
+      return this.format.length
+        ? this.format.some((item) => item.toLocaleLowerCase() === _file_format)
+        : true;
+    },
+    async handleBeforeUpload(file) {
+      this.uploadDataDict = {
+        ...this.uploadData,
+      };
+      this.uploadDataDict[this.addFilenameParam] = file.name;
+
+      if (!this.checkFileFormat(file.name)) {
+        this.handleFormatError();
+        return Promise.reject();
+      }
+
+      if (file.size > this.maxSize) {
+        this.handleExceededSize();
+        return Promise.reject();
+      }
+
+      const md5 = await fileMD5(file);
+      this.headers["md5"] = md5;
+      this.loading = true;
+
+      return true;
+    },
+    upload(options) {
+      if (!options.file) return Promise.reject("文件丢失");
+
+      let formData = new FormData();
+      Object.entries(options.data).forEach(([k, v]) => {
+        formData.append(k, v);
+      });
+      formData.append("file", options.file);
+      this.$emit("uploading");
+
+      return $httpWithMsg.post(options.action, formData, {
+        headers: options.headers,
+      });
+    },
+    handleError(error) {
+      this.loading = false;
+      this.res = {
+        success: false,
+        message: error.response.data.desc,
+      };
+      this.uploadDataDict = {};
+      this.$refs.UploadComp.clearFiles();
+      this.$emit("upload-error", error);
+    },
+    handleSuccess(res) {
+      this.loading = false;
+      this.res = {
+        success: true,
+        message: "导入成功!",
+      };
+      this.$emit("upload-success", res);
+    },
+    handleFormatError() {
+      const content = "只支持文件格式为" + this.format.join("/");
+      this.res = {
+        success: false,
+        message: content,
+      };
+      this.$emit("valid-error", this.res);
+    },
+    handleExceededSize() {
+      const content =
+        "文件大小不能超过" + Math.floor(this.maxSize / (1024 * 1024)) + "M";
+      this.res = {
+        success: false,
+        message: content,
+      };
+      this.$emit("valid-error", this.res);
+    },
+  },
+};
+</script>

+ 30 - 3
src/modules/question/components/QuestionImportEdit.vue

@@ -17,11 +17,21 @@
           <h2>文件上传</h2>
         </div>
         <div>
+          <upload-button
+            btn-content="重新上传文件"
+            btn-icon="icon icon-import"
+            :disabled="loading"
+            :upload-data="uploadData"
+            :upload-url="uploadUrl"
+            :format="importFileTypes"
+            @valid-error="uploadError"
+            @upload-error="uploadError"
+            @upload-success="uploaded"
+          ></upload-button>
           <el-button
             size="small"
             type="danger"
-            plain
-            icon="icon icon-back"
+            icon="icon icon-back-white"
             @click="cancel"
             >返回</el-button
           >
@@ -112,6 +122,7 @@
 
 import { calcSum, deepCopy, objTypeOf, randomCode } from "@/plugins/utils";
 import QuestionImportPaperEdit from "./QuestionImportPaperEdit.vue";
+import UploadButton from "@/components/UploadButton.vue";
 import { isAnEmptyRichText } from "@/utils/utils";
 import {
   questionImportPaperSave,
@@ -136,7 +147,7 @@ const questionInfoField = [
 
 export default {
   name: "QuestionExportEdit",
-  components: { QuestionImportPaperEdit, ImportFileDialog },
+  components: { QuestionImportPaperEdit, ImportFileDialog, UploadButton },
   props: {
     data: {
       type: Object,
@@ -166,6 +177,10 @@ export default {
       // upload answer
       uploadAnswerUrl: `${QUESTION_API}/word/parse/import`,
       uploadAnswerData: {},
+      // word upload
+      uploadData: {},
+      importFileTypes: ["docx", "doc"],
+      uploadUrl: `${QUESTION_API}/word/parse/struct`,
     };
   },
   methods: {
@@ -173,6 +188,7 @@ export default {
       await this.getCourseProperty();
       // this.paperData = deepCopy(paperParseData);
       // this.paperRichJson = deepCopy(paperRichTextJson);
+      this.uploadData = { courseId: this.data.importData.courseId };
       this.paperRichJson = deepCopy(this.data.richText);
       this.paperData = deepCopy(this.data.detailInfo);
       this.transformDataInfo();
@@ -656,6 +672,17 @@ export default {
       );
       this.questionKey = randomCode();
     },
+    // word upload
+    uploaded(res) {
+      this.$message.success("上传成功!");
+      this.paperRichJson = deepCopy(res.data.richText);
+      this.paperData = deepCopy(res.data.detailInfo);
+      this.transformDataInfo();
+      this.questionKey = randomCode();
+    },
+    uploadError(error) {
+      this.$message.error(error.message);
+    },
   },
 };
 </script>