OfflineExamUpload.vue 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. <template>
  2. <div>
  3. <Upload :headers="headers" :data="{fileType: fileType}" :before-upload="handleBeforeUpload" :action="'/api/ecs_oe_student/offlineExam/submitPaper?examRecordDataId='+course.examRecordDataId" :max-size="1024*30" :format="['pdf','zip']" accept="application/zip,application/pdf" :on-format-error="handleFormatError" :on-exceeded-size="handleMaxSize" :on-success="handleSuccess" :on-error="handleError" :show-upload-list="false">
  4. <Button icon="ios-cloud-upload-outline" class="qm-primary-button" style="width: 100%;">上传作答</Button>
  5. </Upload>
  6. <div v-if="file !== null">待上传文件: {{ file.name }}
  7. <Button :loading="loadingStatus">{{ loadingStatus ? '上传中...' : '上传' }}</Button>
  8. </div>
  9. </div>
  10. </template>
  11. <script>
  12. export default {
  13. name: "EcsOfflineUpload",
  14. data() {
  15. return {
  16. headers: {
  17. token: window.localStorage.getItem("token"),
  18. key: window.localStorage.getItem("key")
  19. },
  20. file: null,
  21. fileType: null,
  22. loadingStatus: false
  23. };
  24. },
  25. props: {
  26. course: Object
  27. },
  28. methods: {
  29. fileFormatCheck(file, resolve, reject) {
  30. function getMimetype(signature) {
  31. switch (signature) {
  32. case "89504E47":
  33. return "image/png";
  34. case "47494638":
  35. return "image/gif";
  36. case "25504446":
  37. return "application/pdf";
  38. case "FFD8FFDB":
  39. case "FFD8FFE0":
  40. case "FFD8FFE1":
  41. return "image/jpeg";
  42. case "504B0304":
  43. return "application/zip";
  44. case "504B34":
  45. return "application/zip";
  46. default:
  47. return "Unknown filetype";
  48. }
  49. }
  50. const filereader = new FileReader();
  51. let uploads = [];
  52. filereader.onloadend = evt => {
  53. if (evt.target.readyState === FileReader.DONE) {
  54. const uint = new Uint8Array(evt.target.result);
  55. let bytes = [];
  56. uint.forEach(byte => {
  57. bytes.push(byte.toString(16));
  58. });
  59. const hex = bytes.join("").toUpperCase();
  60. uploads.push({
  61. filename: file.name,
  62. filetype: file.type ? file.type : "Unknown/Extension missing",
  63. binaryFileType: getMimetype(hex),
  64. hex: hex
  65. });
  66. if (
  67. ["application/zip", "application/pdf"].includes(getMimetype(hex))
  68. ) {
  69. resolve();
  70. } else {
  71. console.log("binary file type check: not zip or pdf");
  72. this.$Notice.warning({
  73. title: "作答文件损坏",
  74. desc: file.name + " 文件无法以 .zip 或 .pdf 读取。"
  75. });
  76. this.file = null;
  77. this.loadingStatus = false;
  78. reject();
  79. }
  80. }
  81. };
  82. const blob = file.slice(0, 4);
  83. filereader.readAsArrayBuffer(blob);
  84. },
  85. handleSuccess() {
  86. this.file = null;
  87. this.loadingStatus = false;
  88. this.$Message.success("上传成功");
  89. this.$emit("reloadList");
  90. },
  91. handleError() {
  92. this.file = null;
  93. this.loadingStatus = false;
  94. this.$Message.error("上传失败");
  95. },
  96. handleFormatError(file) {
  97. this.$Notice.warning({
  98. title: "作答文件格式不对",
  99. desc: file.name + " 文件格式不对,请选择 .zip 或 .pdf 文件。"
  100. });
  101. },
  102. handleMaxSize(file) {
  103. this.$Notice.warning({
  104. title: "超出文件大小限制",
  105. desc: file.name + " 太大,作答文件不能超过30M."
  106. });
  107. },
  108. handleBeforeUpload(file) {
  109. if (file.type.includes("/pdf")) {
  110. this.fileType = "pdf";
  111. } else if (file.type.includes("/zip")) {
  112. this.fileType = "zip";
  113. }
  114. this.file = file;
  115. this.loadingStatus = true;
  116. return new Promise((resolve, reject) =>
  117. this.fileFormatCheck(file, resolve, reject)
  118. );
  119. }
  120. }
  121. };
  122. </script>
  123. <style lang="postcss">
  124. .list .ivu-upload-select {
  125. width: 100%;
  126. }
  127. </style>