zhangjie 5 жил өмнө
parent
commit
758517cccc

+ 1 - 1
.env

@@ -1,2 +1,2 @@
 NODE_ENV=development
-VUE_APP_DOMAIN=http://localhost:9000/apis
+VUE_APP_DOMAIN=http://localhost:9000

BIN
extra/database/org.rdb


+ 0 - 10
src/api.js

@@ -1,10 +0,0 @@
-import { $post, $get } from "@/plugins/axios";
-
-export const login = datas => {
-  return $get("/api/user/login", datas);
-  // return Promise.resolve({ id: 1, name: "demo" });
-};
-export const login1 = datas => {
-  return $post("/user/login", datas);
-  // return Promise.resolve({ id: 1, name: "demo" });
-};

+ 3 - 0
src/mixins/uploadTaskMixin.js

@@ -55,6 +55,9 @@ export default {
           }, 5 * 1000);
         }
       });
+    },
+    stopUpload() {
+      this.uploadTask && this.uploadTask.stopUploadTask();
     }
   }
 };

+ 16 - 13
src/modules/client/api.js

@@ -1,33 +1,36 @@
-import { $get, $post } from "@/plugins/axios";
+import { $post, $get } from "@/plugins/axios";
 
 export const uploadFormalImage = (options, datas, config) => {
+  const pathInfo = options.imageEnc ? "image/uploadsheet" : "ms-sheet";
   return $post(
-    `/api/file/image/uploadsheet/${options.examId}/${options.subjectId}/${options.examNumber}`,
+    `/api/file/${pathInfo}/${options.examId}/${options.subjectId}/${options.examNumber}`,
     datas,
     config
   );
 };
 export const uploadSliceImage = (options, datas, config) => {
+  const pathInfo = options.imageEnc ? "image/upload" : "ms-slice";
   return $post(
-    `/api/file/image/upload/${options.examId}/${options.subjectId}/${options.examNumber}`,
+    `/api/file/${pathInfo}/${options.examId}/${options.subjectId}/${options.examNumber}`,
     datas,
     config
   );
 };
-export const getStudentGroupByExamNumber = datas => {
-  return $post("/backend/course/updateCourseStatus", datas);
+export const getStudentGroupByExamNumber = examNumber => {
+  return $get(`/api/exam/listStudents/${examNumber}`);
+};
+export const getStudentByExamNumber = examNumber => {
+  return $get(`/api/exam/getStudent/${examNumber}`);
 };
 export const uploadStudent = datas => {
   return $post(`/api/upload/student/${datas.subjectId}`, datas);
 };
 export const saveCollectLog = datas => {
-  return $post(`/marklog/saveCollectLog`, { ...datas, workId: datas.examId });
-};
-
-// course-manage
-export const courseList = datas => {
-  return $get("/backend/course/listCoursePage", datas);
+  return $post(`/api/marklog/saveCollectLog`, {
+    ...datas,
+    workId: datas.examId
+  });
 };
-export const updateCourseStatus = ({ id, status }) => {
-  return $post("/backend/course/updateCourseStatus", { id, status });
+export const getLevelList = examId => {
+  return $get(`/api/exam/getLevel/${examId}`);
 };

+ 59 - 21
src/modules/client/components/ScanExceptionDialog.vue

@@ -29,38 +29,63 @@
       </div>
 
       <div class="exception-form" v-if="curException.showAction">
-        <i-form
+        <Form
           ref="modalFormComp"
           :model="modalForm"
           :rules="rules"
           :label-width="0"
           inline
         >
-          <form-item prop="examNumber">
+          <FormItem prop="examNumber">
             <div class="input-append">
-              <i-input
+              <Input
                 size="default"
                 v-model.trim="modalForm.examNumber"
                 placeholder="请扫码输入"
                 style="width: 220px;"
                 autofocus
+                v-code-input.prevent="{ inputOver }"
+                v-if="scanType === 'SCAN'"
               >
-                ></i-input
+                ></Input
               >
+              <Input
+                size="default"
+                v-model.trim="modalForm.examNumber"
+                placeholder="请在此输入考号"
+                style="width: 220px;"
+                @on-blur="checkStudent"
+                autofocus
+                v-else
+              >
+              </Input>
             </div>
-          </form-item>
-          <form-item :label-width="0">
-            <i-button size="default" type="primary" @click="toHandInput"
-              >手工绑定</i-button
-            >
-            <i-button size="default" type="primary" @click="toRescan"
-              >重新采集</i-button
-            >
-            <i-button size="default" type="default" @click="toReset"
-              ><i class="icon-font icon-setting"></i>重新配置</i-button
-            >
-          </form-item>
-        </i-form>
+          </FormItem>
+          <FormItem>
+            <Input
+              v-model="modalForm.studentName"
+              placeholder="姓名"
+              readonly
+            ></Input>
+          </FormItem>
+          <FormItem>
+            <Button type="primary" @click="confirm">确认</Button>
+          </FormItem>
+        </Form>
+        <div class="exception-actions" v-if="scanType === 'SCAN'">
+          <Button size="default" type="primary" @click="toHandInput"
+            >手工绑定</Button
+          >
+          <Button size="default" type="primary" @click="toRescan"
+            >重新采集</Button
+          >
+          <Button size="default" type="default" @click="toReset"
+            ><i class="icon-font icon-setting"></i>重新配置</Button
+          >
+        </div>
+      </div>
+      <div class="exception-actions" v-else>
+        <Button size="default" type="primary" @click="toRescan">确定</Button>
       </div>
     </div>
   </Modal>
@@ -68,6 +93,7 @@
 
 <script>
 import Cropper from "cropperjs";
+import { getStudentByExamNumber } from "../api";
 
 export default {
   name: "scan-exception-dialog",
@@ -96,8 +122,10 @@ export default {
       modalIsShow: false,
       cropper: "",
       spinStyle: {},
+      scanType: "SCAN",
       modalForm: {
-        examNumber: ""
+        examNumber: "",
+        studentName: ""
       },
       rules: {
         examNumber: [
@@ -144,6 +172,14 @@ export default {
         }
       });
     },
+    inputOver(code) {
+      this.modalForm.examNumber = code;
+      this.checkStudent();
+    },
+    async checkStudent() {
+      const data = await getStudentByExamNumber(this.modalForm.examNumber);
+      this.modalForm.studentName = data.name;
+    },
     cancel() {
       this.modalIsShow = false;
     },
@@ -158,11 +194,13 @@ export default {
       this.$emit("on-rescan");
       this.cancel();
     },
-    async toHandInput() {
+    toHandInput() {
+      this.scanType = "MANUAL";
+    },
+    async confirm() {
       const valid = await this.$refs.modalFormComp.validate();
       if (!valid) return;
-      this.$emit("on-hand-input", this.modalForm.examNumber, "MANUAL");
-      this.cancel();
+      this.$emit("confirm", this.modalForm, this.scanType);
     }
   },
   beforeDestroy() {

+ 8 - 0
src/modules/client/store.js

@@ -1,6 +1,8 @@
 import db from "../../plugins/db";
 
 const state = {
+  clientConfig: {},
+  curLevel: "",
   camera: "", // 相机编号
   curSubject: {},
   scanArea: {},
@@ -10,6 +12,12 @@ const state = {
 };
 
 const mutations = {
+  setClientConfig(state, clientConfig) {
+    state.clientConfig = Object.assign({}, state.clientConfig, clientConfig);
+  },
+  setCurLevel(state, curLevel) {
+    state.curLevel = curLevel;
+  },
   setCamera(state, camera) {
     state.camera = camera;
   },

+ 17 - 4
src/modules/client/views/CheckInfo.vue

@@ -47,7 +47,8 @@
 </template>
 
 <script>
-import { mapState } from "vuex";
+import { mapState, mapMutations } from "vuex";
+import { getLevelList } from "../api";
 
 export default {
   name: "check-info",
@@ -75,9 +76,20 @@ export default {
     };
   },
   computed: {
-    ...mapState("client", ["curSubject"])
+    ...mapState("client", ["curSubject", "curLevel"]),
+    user() {
+      return this.$store.state.user;
+    }
+  },
+  mounted() {
+    this.modalForm.level = this.curLevel;
+    // this.getLevels()
   },
   methods: {
+    ...mapMutations("client", ["setCurLevel"]),
+    async getLevels() {
+      this.levels = await getLevelList(this.user.examId);
+    },
     async save() {
       const valid = await this.$refs.modalFormComp.validate();
       if (!valid) return;
@@ -85,8 +97,9 @@ export default {
     },
     confirm() {
       this.modalIsShow = false;
-      // const scanName = this.config.isPackageMode ? "GroupScan" : "LineScan";
-      // this.$router.push({ name: scanName });
+      this.setCurLevel(this.modalFsorm.level);
+      const scanName = this.config.isPackageMode ? "GroupScan" : "LineScan";
+      this.$router.push({ name: scanName });
     }
   }
 };

+ 11 - 9
src/modules/client/views/GroupScan.vue

@@ -64,7 +64,7 @@
       :cur-exception="curException"
       @on-reset="resetConfig"
       @on-rescan="restartInitFile"
-      @on-hand-input="examNumberValid"
+      @confirm="examNumberValid"
       ref="ScanExceptionDialog"
     ></scan-exception-dialog>
   </div>
@@ -81,6 +81,7 @@ import {
 import { deepCopy } from "../../../plugins/utils";
 import ScanAreaDialog from "../components/ScanAreaDialog";
 import ScanExceptionDialog from "../components/ScanExceptionDialog";
+import { mapState } from "vuex";
 
 export default {
   name: "group-scan",
@@ -125,12 +126,10 @@ export default {
     };
   },
   computed: {
+    ...mapState("client", ["curSubject", "clientConfig", "curLevel"]),
     user() {
       return this.$store.state.user;
     },
-    curSubject() {
-      return this.$store.state.curSubject;
-    },
     studentSerialList() {
       return [...this.students].sort((a, b) => {
         if (a.isClient) return -1;
@@ -249,7 +248,7 @@ export default {
         // 未解析到考号异常
         this.curException = {
           showAction: true,
-          message: "条形码解析错误!",
+          message: "该图片无法识别,请处理!",
           collectConfig: this.getCurCollectConfig()
         };
         this.$refs.ScanExceptionDialog.open();
@@ -288,7 +287,7 @@ export default {
         } else {
           validInfo = {
             valid: false,
-            message: "学生数据没有上传,请重新采集!"
+            message: "无该考生,请处理!"
           };
           return validInfo;
         }
@@ -303,7 +302,7 @@ export default {
       if (!this.curStudent) {
         validInfo = {
           valid: false,
-          message: "当前考场没有当前学生,请重新采集!"
+          message: "该考生不属于该考场,请处理!"
         };
       } else {
         this.curStudent.isCurrent = true;
@@ -322,7 +321,7 @@ export default {
         this.getCurCollectConfig()
       ).catch(error => {
         const content = `${this.curStudent.name}的试卷保存失败,请重新扫描!`;
-        this.$Notice.error({ title: "错误提示", desc: content, duration: 5 });
+        this.$Notice.error({ title: "错误提示", desc: content, duration: 0 });
       });
 
       if (result) {
@@ -366,6 +365,8 @@ export default {
           formalImgPath: curStudent.formalImgPath,
           sliceImgPath: curStudent.sliceImgPath,
           isManual: curStudent.isManual,
+          imageEnc: this.clientConfig.imageEnc,
+          level: this.curLevel,
           clientUserId: this.user.id,
           clientUsername: this.user.name,
           clientUserLoginTime: this.user.loginTime
@@ -376,6 +377,7 @@ export default {
     },
     allReScan() {
       this.students = [];
+      this.historyList = [];
       this.restartInitFile();
     },
     getCurCollectConfig() {
@@ -384,7 +386,7 @@ export default {
     // history
     updateHistory(curStudent) {
       const student = deepCopy(curStudent);
-      if (this.historyList.length >= this.historyLimit) {
+      if (this.historyList.length >= this.students.length) {
         this.historyList.pop();
       }
       this.historyList.unshift(student);

+ 328 - 4
src/modules/client/views/LineScan.vue

@@ -1,15 +1,339 @@
 <template>
-  <div class="line-scan">
-    line-scan
+  <div class="line-scan scan">
+    <div class="scan-task task-list">
+      <div
+        :class="[
+          'task-item',
+          {
+            'task-current': curStudent.isCurrent,
+            'task-over': curStudent.isClient
+          }
+        ]"
+      >
+        <span>{{ curStudent.name }}</span>
+        <span>{{ curStudent.examNumber }}</span>
+      </div>
+    </div>
+    <div class="scan-image">
+      <div class="scan-main scan-waiting" v-if="isWaiting">
+        <p class="scan-waiting-icon"></p>
+        <p class="scan-waiting-tips">等待采集试卷</p>
+      </div>
+      <div class="scan-main scan-picture" v-else>
+        <img class="img-contain" :src="curImage.url" :alt="curImage.name" />
+      </div>
+    </div>
+    <div class="scan-history">
+      <div
+        class="history-item"
+        v-for="(task, tindex) in historyList"
+        :key="tindex"
+      >
+        <p class="history-item-title">
+          <span>{{ task.name }}</span
+          ><span>{{ task.examNumber }}</span>
+        </p>
+        <div class="history-item-body">
+          <img :src="task.url" :alt="task.name" />
+        </div>
+      </div>
+    </div>
+
+    <!-- reset current image scan area dialog -->
+    <scan-area-dialog
+      :cur-image="curImage"
+      :cur-collect-config="curCollectConfig"
+      @confirm="studentConfigChange"
+      ref="ScanAreaDialog"
+    ></scan-area-dialog>
+    <!-- scan exception dialog -->
+    <scan-exception-dialog
+      :cur-image="curImage"
+      :cur-exception="curException"
+      @on-reset="resetConfig"
+      @on-rescan="restartInitFile"
+      @confirm="examNumberValid"
+      ref="ScanExceptionDialog"
+    ></scan-exception-dialog>
   </div>
 </template>
 
 <script>
+const fs = require("fs");
+import { getStudentByExamNumber } from "../api";
+import {
+  decodeImageCode,
+  getEarliestFile,
+  saveOutputImage
+} from "../../../plugins/imageOcr";
+import { deepCopy } from "../../../plugins/utils";
+import ScanAreaDialog from "../components/ScanAreaDialog";
+import ScanExceptionDialog from "../components/ScanExceptionDialog";
+import { mapState } from "vuex";
+
 export default {
   name: "line-scan",
+  components: { ScanAreaDialog, ScanExceptionDialog },
   data() {
-    return {};
+    return {
+      isWaiting: true,
+      students: [],
+      curStudent: {},
+      curCollectConfig: {},
+      curException: {
+        showAction: true,
+        message: ""
+      },
+      historyLimit: 30,
+      historyList: [
+        {
+          name: "张一二三",
+          examNumber: "1901040084",
+          url:
+            "http://127.0.0.1:9000/api/file/image/download/31/1/734/1?random=676176fc-24cd-407a-a7bc-fabc49bd2dbc"
+        },
+        {
+          name: "张一二三",
+          examNumber: "1901040084",
+          url:
+            "http://127.0.0.1:9000/api/file/image/download/31/1/733/1?random=e2966291-ffba-4b19-985d-0cad9ae1b75b"
+        },
+        {
+          name: "张一二三",
+          examNumber: "1901040084",
+          url:
+            "http://127.0.0.1:9000/api/file/image/download/31/1/731/1?random=b305c27c-76d0-4477-a1ef-c9b8554a4671"
+        }
+      ],
+      setT: "",
+      holding: false,
+      curImage: {
+        url: "",
+        name: ""
+      }
+    };
+  },
+  computed: {
+    ...mapState("client", ["curSubject", "clientConfig", "curLevel"]),
+    user() {
+      return this.$store.state.user;
+    }
+  },
+  mounted() {
+    if (!this.curSubject || !this.curSubject.collectConfig) {
+      this.$Message.error("请先完成采集设置!");
+      return;
+    }
+    // this.getInitFile();
+    // this.test();
+  },
+  methods: {
+    async test() {
+      this.curImage = getEarliestFile();
+      const codeAreas = {
+        codeArea: {
+          x: 0,
+          y: 0,
+          width: 717.12,
+          height: 673.92,
+          rotate: 0,
+          scaleX: 1,
+          scaleY: 1,
+          codeRotate: 90
+        },
+        coverArea: {
+          x: 518.4,
+          y: 345.6,
+          width: 4147.2,
+          height: 2764.8,
+          rotate: 0,
+          scaleX: 1,
+          scaleY: 1
+        },
+        tailorArea: {
+          x: 518.4,
+          y: 345.6,
+          width: 4147.2,
+          height: 2764.8,
+          rotate: 0,
+          scaleX: 1,
+          scaleY: 1
+        },
+        imageRotate: 0
+      };
+      const examNumber = await decodeImageCode(
+        this.curImage.url,
+        codeAreas.codeArea
+      ).catch(error => {
+        const content = `图像:${this.curImage.name},解析错误,错误信息:${error}`;
+
+        this.$Notice.error({ title: "错误提示", desc: content, duration: 0 });
+      });
+      console.log(examNumber);
+    },
+    getInitFile() {
+      this.curImage = getEarliestFile(this.GLOBAL.input);
+
+      if (this.curImage.url) {
+        if (this.setT) clearTimeout(this.setT);
+        this.isWaiting = false;
+        this.$nextTick(() => {
+          this.startDecodeTask(this.curSubject.collectConfig.codeArea);
+        });
+      } else {
+        this.setT = setTimeout(() => {
+          this.getInitFile();
+        }, 1000);
+      }
+    },
+    restartInitFile() {
+      this.isWaiting = true;
+      this.curStudent = {};
+      if (this.setT) clearTimeout(this.setT);
+      this.curImage = { url: "", name: "" };
+
+      this.$nextTick(() => {
+        this.getInitFile();
+      });
+    },
+    async startDecodeTask(codeArea) {
+      const examNumber = await decodeImageCode(
+        this.curImage.url,
+        codeArea
+      ).catch(error => {
+        const content = `图像:${this.curImage.name},解析错误,错误信息:${error}`;
+        this.$Notice.error({ title: "错误提示", desc: content, duration: 0 });
+      });
+
+      if (examNumber) {
+        this.examNumberValid(examNumber);
+      } else {
+        // 未解析到考号异常
+        this.curException = {
+          showAction: true,
+          message: "该图片无法识别,请处理!",
+          collectConfig: this.getCurCollectConfig()
+        };
+        this.$refs.ScanExceptionDialog.open();
+      }
+    },
+    async examNumberValid(examNumber, type = "AUTO") {
+      const validRes = await this.checkStudentValid(examNumber);
+      if (validRes.valid) {
+        // 保存扫描到的试卷
+        this.toSaveStudent(examNumber, type);
+      } else {
+        // 考号不合法异常
+        this.curException = {
+          showAction: false,
+          message: validRes.message
+        };
+        this.$refs.ScanExceptionDialog.open();
+      }
+    },
+    async checkStudentValid(examNumber) {
+      let validInfo = { valid: true, message: "" };
+      const curStudent = await getStudentByExamNumber(
+        examNumber
+      ).catch(() => {});
+
+      if (!curStudent) {
+        validInfo = {
+          valid: false,
+          message: "无该考生,请处理!"
+        };
+      } else {
+        this.curStudent = {
+          ...curStudent,
+          imgPath: this.curImage.url,
+          isClient: false,
+          isCurrent: true,
+          isManual: false,
+          collectConfig: null
+        };
+      }
+      return validInfo;
+    },
+    async toSaveStudent(examNumber, type) {
+      const result = await saveOutputImage(
+        this.curImage.url,
+        {
+          workId: this.user.workId,
+          subjectId: this.curSubject.id,
+          examNumber
+        },
+        this.getCurCollectConfig()
+      ).catch(error => {
+        const content = `${this.curStudent.name}的试卷保存失败,请重新扫描!`;
+        this.$Notice.error({ title: "错误提示", desc: content, duration: 0 });
+      });
+
+      if (result) {
+        this.curStudent = Object.assign(this.curStudent, {
+          isClient: true,
+          formalImgPath: result.outputFormalPath,
+          sliceImgPath: result.outputSlicelPath,
+          isManual: type === "MANUAL"
+        });
+        await this.appendUploadTask();
+        this.updateHistory(this.curStudent);
+      }
+      // 删除扫描文件,继续开始下一个任务
+      fs.unlinkSync(this.curImage.url);
+      this.restartInitFile();
+    },
+    async appendUploadTask() {
+      await this.$parent.addUploadTask({
+        id: null,
+        examId: this.user.examId,
+        examName: this.user.examName,
+        subjectId: this.curSubject.id,
+        subjectName: this.curSubject.name,
+        examNumber: this.curStudent.examNumber,
+        studentName: this.curStudent.name,
+        siteCode: this.curStudent.siteCode,
+        roomCode: this.curStudent.roomCode,
+        formalImgPath: this.curStudent.formalImgPath,
+        sliceImgPath: this.curStudent.sliceImgPath,
+        isManual: this.curStudent.isManual,
+        imageEnc: this.clientConfig.imageEnc,
+        level: this.curLevel,
+        clientUserId: this.user.id,
+        clientUsername: this.user.name,
+        clientUserLoginTime: this.user.loginTime
+      });
+    },
+    getCurCollectConfig() {
+      return this.curStudent.collectConfig || this.curSubject.collectConfig;
+    },
+    // history
+    updateHistory(curStudent) {
+      const student = deepCopy(curStudent);
+      if (this.historyList.length >= this.historyLimit) {
+        this.historyList.pop();
+      }
+      this.historyList.unshift(student);
+    },
+    // scan-exception
+    resetConfig() {
+      this.curCollectConfig = this.getCurCollectConfig();
+      this.$refs.ScanAreaDialog.open();
+    },
+    studentConfigChange(setting) {
+      this.curStudent.collectConfig = setting;
+      this.startDecodeTask(setting.codeArea);
+    },
+    goBack() {
+      this.$confirm({
+        content: "当前正处于采集状态,确定要退出吗?",
+        onOk: () => {
+          this.$router.go(-1);
+        }
+      });
+    }
   },
-  methods: {}
+  beforeDestroy() {
+    if (this.setT) clearTimeout(this.setT);
+  }
 };
 </script>

+ 9 - 4
src/modules/client/views/ScanArea.vue

@@ -37,7 +37,7 @@ export default {
     };
   },
   computed: {
-    ...mapState("client", ["curSubject"])
+    ...mapState("client", ["curSubject", "clientConfig"])
   },
   mounted() {
     this.curSetting = this.curSubject.collectConfig || {};
@@ -62,9 +62,14 @@ export default {
       });
       this.updateCurSubject(curSubject);
 
-      this.$router.push({ name: "CheckInfo" });
-      // const scanName = this.config.isPackageMode ? "GroupScan" : "LineScan";
-      // this.$router.push({ name: scanName });
+      if (this.clientConfig.isLevelKnown) {
+        this.$router.push({ name: "CheckInfo" });
+      } else {
+        const scanName = this.clientConfig.isPackageMode
+          ? "GroupScan"
+          : "LineScan";
+        this.$router.push({ name: scanName });
+      }
     }
   },
   beforeDestroy() {

+ 2 - 1
src/plugins/db.js

@@ -21,7 +21,7 @@ function init() {
 }
 
 function saveUploadInfo(params) {
-  const sql = `INSERT INTO scan (examId, examName, subjectId, subjectName, examNumber, studentName, siteCode, roomCode, formalImgPath, sliceImgPath,isManual, clientUserId, clientUsername, clientUserLoginTime, isUpload,createdTime, fininshTime) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)`;
+  const sql = `INSERT INTO scan (examId, examName, subjectId, subjectName, examNumber, studentName, siteCode, roomCode, formalImgPath, sliceImgPath,isManual,imageEnc, clientUserId, clientUsername, clientUserLoginTime, isUpload,createdTime, fininshTime) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)`;
   const datas = [
     params.examId,
     params.examName,
@@ -34,6 +34,7 @@ function saveUploadInfo(params) {
     params.formalImgPath,
     params.sliceImgPath,
     params.isManual,
+    params.imageEnc,
     params.clientUserId,
     params.clientUsername,
     params.clientUserLoginTime,

+ 4 - 1
src/plugins/env.js

@@ -77,12 +77,15 @@ function makeDirSync(pathContent) {
 
 function initConfigData(data) {
   let configData = { ...data };
+  if (!configData.input) configData.input = getInputDir();
+
+  if (process.env.NODE_ENV === "development") return configData;
+
   const configPath = path.join(homePath, "config.json");
   if (fs.existsSync(configPath)) {
     configData = JSON.parse(fs.readFileSync(configPath, "utf8"));
     if (!configData.input) configData.input = getInputDir();
   } else {
-    if (!configData.input) configData.input = getInputDir();
     fs.writeFileSync(configPath, JSON.stringify(configData), "utf8");
   }
 

+ 3 - 20
src/plugins/imageOcr.js

@@ -73,11 +73,7 @@ function decodeImageCode(imgPath, codeArea) {
  * @param {Object} collectConfig 裁剪区域
  */
 async function saveOutputImage(imgPath, paperInfo, collectConfig) {
-  const outputFormalPath = await saveFormalImage(
-    imgPath,
-    paperInfo,
-    collectConfig
-  ).catch(() => {});
+  const outputFormalPath = saveFormalImage(imgPath, paperInfo);
   const outputSlicelPath = await saveSliceImage(
     imgPath,
     paperInfo,
@@ -89,22 +85,9 @@ async function saveOutputImage(imgPath, paperInfo, collectConfig) {
   return Promise.reject("试卷保存失败");
 }
 
-function saveFormalImage(imgPath, paperInfo, collectConfig) {
+function saveFormalImage(imgPath, paperInfo) {
   const outputFormalPath = getOutputImagePath(paperInfo, "formal");
-  const { tailorArea } = collectConfig;
-
-  let imgObj = gm(imgPath);
-  // formal图:只裁切边缘,不覆盖信息
-  imgObj.crop(tailorArea.width, tailorArea.height, tailorArea.x, tailorArea.y);
-
-  return new Promise((resolve, reject) => {
-    imgObj.write(outputFormalPath, function(err) {
-      if (err) {
-        reject(err);
-      }
-      resolve(outputFormalPath);
-    });
-  });
+  fs.copyFileSync(imgPath, outputFormalPath);
 }
 
 function saveSliceImage(imgPath, paperInfo, collectConfig) {

+ 18 - 9
src/plugins/imageUpload.js

@@ -25,6 +25,7 @@ function toUploadImg(options, type) {
 
   const file = new File([buffer], options.examNumber + ".jpg");
   formData.append("file", file);
+  formData.append("level", options.level);
 
   return type === "formal"
     ? uploadFormalImage(options, formData, { headers: { md5 } })
@@ -72,22 +73,26 @@ class UploadTask {
   }
 
   async startUploadTask() {
-    if (!this.taskList.length) {
-      this.stopUploadTask();
+    this.taskRunning = true;
+    this.runUploadTask();
+  }
+
+  async runUploadTask() {
+    if (!this.taskList.length || !this.taskRunning) {
+      this.overUploadTask();
       return;
     }
-    this.taskRunning = true;
     const curTask = this.getCurTask();
 
-    const uploadReq = [
+    const uploadRequest = [
       toUploadImg(curTask, "formal"),
       toUploadImg(curTask, "slice")
     ];
-    const uploadResult = await Promise.all(uploadReq).catch(() => {});
+    const uploadResult = await Promise.all(uploadRequest).catch(() => {});
 
     if (uploadResult) {
-      const updateReq = [toUploadStudent(curTask), saveCollectLog(curTask)];
-      const updateResult = await Promise.all(updateReq).catch(() => {});
+      const updateRequest = [toUploadStudent(curTask), saveCollectLog(curTask)];
+      const updateResult = await Promise.all(updateRequest).catch(() => {});
 
       if (updateResult) {
         this.uploadSuccessCallback(curTask);
@@ -95,15 +100,19 @@ class UploadTask {
     }
 
     this.setT = setTimeout(() => {
-      this.startUploadTask();
+      this.runUploadTask();
     }, 200);
   }
 
-  stopUploadTask() {
+  overUploadTask() {
     this.taskRunning = false;
     if (this.setT) clearTimeout(this.setT);
     this.uploadTaskOverCallback && this.uploadTaskOverCallback();
   }
+  stopUploadTask() {
+    this.taskRunning = false;
+    this.taskList = [];
+  }
 }
 
 export default UploadTask;

+ 2 - 5
src/views/Home.vue

@@ -45,13 +45,12 @@
 </template>
 
 <script>
-import authUnvalidMixin from "../mixins/authUnvalidMixin";
 import uploadTaskMixin from "../mixins/uploadTaskMixin";
 import { mapState } from "vuex";
 
 export default {
   name: "home",
-  mixins: [authUnvalidMixin, uploadTaskMixin],
+  mixins: [uploadTaskMixin],
   data() {
     return {
       showProgress: false,
@@ -69,8 +68,6 @@ export default {
   },
   created() {
     this.examName = this.$ls.get("user", { examName: "" }).examName;
-    // TODO:遵循file-upload项目的逻辑
-    // this.initUploadProgress();
   },
   methods: {
     logout() {
@@ -79,7 +76,7 @@ export default {
     }
   },
   beforeDestroy() {
-    // this.stopUpload();
+    this.stopUpload();
   }
 };
 </script>

+ 10 - 3
src/views/Login.vue

@@ -41,8 +41,7 @@
 import { username, password } from "@/plugins/formRules";
 import initStoreMixin from "../mixins/initStoreMixin";
 import { formatDate } from "../plugins/utils";
-
-import { login } from "@/api";
+import { $get } from "@/plugins/axios";
 
 export default {
   name: "login",
@@ -75,7 +74,10 @@ export default {
 
       if (this.isSubmit) return;
       this.isSubmit = true;
-      const data = await login(this.loginModel).catch(() => {});
+      const data = await $get(
+        "/api/user/login",
+        this.loginModel
+      ).catch(() => {});
       this.isSubmit = false;
       if (!data) return;
 
@@ -86,6 +88,11 @@ export default {
 
       this.$ls.set("user", data);
       this.$store.commit("setUser", data);
+      this.$store.commit("client/setClientConfig", {
+        imageEnc: data.imageEnc,
+        isPackageMode: data.isPackageMode,
+        isLevelKnown: data.isLevelKnown
+      });
       this.$router.push({
         name: "Subject"
       });