zhangjie 1 rok pred
rodič
commit
82e9defa0c

+ 10 - 0
src/assets/styles/element-ui-costom.scss

@@ -685,3 +685,13 @@
     margin: 3px;
   }
 }
+
+.el-notification {
+  .el-notification__content {
+    p {
+      word-break: break-all;
+      max-height: 300px;
+      overflow: hidden;
+    }
+  }
+}

+ 14 - 2
src/assets/styles/pages.scss

@@ -25,7 +25,6 @@
         }
       }
       &-foot {
-        text-align: right;
         margin: 0 -16px;
         padding: 16px 24px 0;
         border-top: 1px solid #f0f0f0;
@@ -148,19 +147,23 @@
       vertical-align: top;
       margin: 5px 10px;
       font-size: 14px;
+      cursor: pointer;
 
       > p {
+        border-radius: 4px;
+        padding: 0 10px;
+        height: 20px;
         line-height: 20px;
         text-align: center;
         overflow: hidden;
         text-overflow: ellipsis;
         white-space: nowrap;
+        background-color: #fff;
       }
       .el-image {
         height: 100px;
         width: 100px;
         overflow: hidden;
-        cursor: pointer;
       }
       img {
         transition: 0.3s transform;
@@ -168,6 +171,15 @@
       img:hover {
         transform: scale(1.1, 1.2);
       }
+      > p:hover {
+        background-color: #d9ecff;
+      }
+
+      &.is-active {
+        > p {
+          background-color: #d9ecff;
+        }
+      }
     }
   }
 }

+ 9 - 2
src/components/SecSelect.vue

@@ -5,7 +5,7 @@
         v-model.trim="filter.semesterId"
         placeholder="学期"
         default-select
-        :clearable="!defaultSelectExam"
+        :clearable="seClearable"
         @default-selected="semesterDefaultSelect"
         @change="semesterChange"
       ></semester-select>
@@ -14,7 +14,7 @@
       <exam-select
         v-model="filter.examId"
         :semester-id="filter.semesterId"
-        :clearable="!defaultSelectExam || !defaultSelectCourse"
+        :clearable="seClearable"
         :default-select="defaultSelectExam || defaultSelectCourse"
         @default-selected="examDefaultSelect"
         @change="examChange"
@@ -69,6 +69,13 @@ export default {
       selectData: {},
     };
   },
+  computed: {
+    seClearable() {
+      if (this.defaultSelectCourse) return false;
+      if (this.defaultSelectExam) return false;
+      return true;
+    },
+  },
   watch: {
     filter: {
       deep: true,

+ 84 - 61
src/modules/client/components/ScanTaskProcessDialog.vue

@@ -9,6 +9,7 @@
       :show-close="false"
       append-to-body
       @open="dialogOpen"
+      @closed="dialogClosed"
     >
       <div class="scan-head" slot="title">
         <h3>
@@ -30,7 +31,7 @@
         <div
           v-for="item in scanStageList"
           :key="item.frontOriginImgPath"
-          class="scan-image-item"
+          :class="['scan-image-item', { 'is-active': item.selected }]"
         >
           <el-image
             :src="`file://${item.frontOriginImgPath}`"
@@ -38,21 +39,25 @@
             lazy
             @click="toViewPaper(item)"
           ></el-image>
-          <p v-if="item.studentCode" :title="item.studentCode">
+          <p :title="item.studentCode" @click="toSelect(item)">
             {{ item.studentCode }}
           </p>
         </div>
       </div>
 
       <div class="box-justify" slot="footer">
-        <el-button :disabled="!canSave" type="danger" @click="clearStage"
-          >清空数据</el-button
-        >
+        <div>
+          <el-button :disabled="!canSave" type="danger" @click="deleteStage"
+            >删除数据</el-button
+          >
+          <el-button :disabled="!canSave" type="danger" @click="clearStage"
+            >清空数据</el-button
+          >
+        </div>
         <el-button
           type="primary"
           :loading="scanStatus === 'SCAN'"
-          :disabled="scanStatus === 'FINISH'"
-          @click="startTask"
+          @click="toScan"
         >
           {{ statusDesc[scanStatus] }}
         </el-button>
@@ -61,7 +66,7 @@
           :disabled="!canSave"
           :loading="saving"
           type="primary"
-          @click="saveScanImage"
+          @click="toSave"
           >保存</el-button
         >
       </div>
@@ -120,11 +125,13 @@ export default {
       statusDesc: {
         INIT: "开始扫描",
         SCAN: "扫描中",
-        FINISH: "扫描完成",
+        FINISH: "继续扫描",
       },
       user: this.$ls.get("user", {}),
       scanHistoryList: [],
       saving: false,
+      maxCacheCount: 120,
+      lastStudentCode: "",
     };
   },
   computed: {
@@ -135,6 +142,7 @@ export default {
   },
   methods: {
     initData() {
+      this.lastStudentCode = "";
       this.scanStageList = [];
       this.scanStatus = "INIT";
     },
@@ -142,6 +150,9 @@ export default {
       logger.info(`00进入扫描`);
       this.initData();
     },
+    dialogClosed() {
+      this.clearFiles();
+    },
     async close() {
       if (this.scanStageList.length) {
         const res = await this.$confirm(
@@ -161,13 +172,23 @@ export default {
     open() {
       this.modalIsShow = true;
     },
+    toScan() {
+      if (this.scanStatus === "INIT") {
+        this.startTask();
+      } else {
+        this.continueTask();
+      }
+    },
     startTask() {
       logger.info(`01开始扫描`);
-      this.clearData();
       this.scanStageList = [];
       this.scanStatus = "SCAN";
       this.evokeScanExe();
     },
+    continueTask() {
+      this.scanStatus = "SCAN";
+      this.evokeScanExe();
+    },
     async evokeScanExe() {
       logger.info("02唤起扫描仪");
       await evokeScanner(this.GLOBAL.input).catch((error) => {
@@ -179,84 +200,83 @@ export default {
       if (!res.succeed) {
         logger.error(`03扫描仪停止,故障:${res.errorMsg}`);
         this.$message.error(res.errorMsg);
-        this.scanStatus = "INIT";
+        this.scanStatus = "FINISH";
         return;
       }
       logger.info(`03扫描仪停止,扫描数:${res.data.length}`);
+      await this.stageScanImage(res.data);
       this.scanStatus = "FINISH";
-      this.stageScanImage(res.data);
-      if (this.task.isFormal) {
-        await this.checkFirstHasCode();
+      logger.info(`03-1完成条码解析`);
+
+      if (this.task.isFormal && !this.scanStageList[0].studentCode) {
+        this.$refs.HandleInputDialog.open();
       }
     },
-    stageScanImage(imageList) {
-      this.scanStageList = imageList.map((item) => {
-        return {
+    async stageScanImage(imageList) {
+      const ocrAreaContent = JSON.stringify(this.ocrArea);
+      for (let i = 0, len = imageList.length; i < len; i++) {
+        const fileInfo = {
           taskId: this.task.id,
           schoolId: this.task.schoolId,
           semesterId: this.task.semesterId,
           examId: this.task.examId,
           courseCode: this.task.courseCode,
           courseName: this.task.courseName,
-          frontOriginImgPath: item.frontFile,
-          versoOriginImgPath: item.versoFile,
+          frontOriginImgPath: imageList[i].frontFile,
+          versoOriginImgPath: imageList[i].versoFile,
           isFormal: this.task.isFormal ? 1 : 0,
           studentCode: "",
           ocrArea: "",
           clientUserId: this.user.id,
           clientUsername: this.user.loginName,
           clientUserLoginTime: this.user.loginTime,
+          selected: false,
         };
-      });
-    },
-    async checkFirstHasCode() {
-      const fileInfo = this.scanStageList[0];
-      if (!fileInfo) return;
 
-      const code = await decodeImageCode(
-        fileInfo.frontOriginImgPath,
-        this.ocrArea
-      ).catch((err) => {
-        console.error(err);
-        logger.error(`04-2条码解析失败,${err}`);
-      });
+        if (this.task.isFormal) {
+          const code = await decodeImageCode(
+            fileInfo.frontOriginImgPath,
+            this.ocrArea
+          ).catch((err) => {
+            console.error(err);
+            logger.error(`03条码解析失败,${err}`);
+          });
+          fileInfo.studentCode = code || this.lastStudentCode;
+          fileInfo.ocrArea = ocrAreaContent;
 
-      if (code) {
-        fileInfo.studentCode = code;
-        this.updateStudentCode();
-      } else {
-        this.$refs.HandleInputDialog.open();
+          if (fileInfo.studentCode) {
+            this.lastStudentCode = fileInfo.studentCode;
+          }
+        }
+
+        this.scanStageList.push(fileInfo);
       }
     },
     handleConfirm(code) {
       this.scanStageList[0].studentCode = code;
       this.updateStudentCode();
     },
-    async updateStudentCode() {
-      if (!this.task.isFormal) return;
-
+    updateStudentCode() {
       let lastStudentCode = this.scanStageList[0].studentCode;
-      const ocrAreaContent = JSON.stringify(this.ocrArea);
-      for (let i = 0, len = this.scanStageList.length; i < len; i++) {
+      for (let i = 1, len = this.scanStageList.length; i < len; i++) {
         const fileInfo = this.scanStageList[i];
-        if (!i) fileInfo.ocrArea = ocrAreaContent;
-
-        const code = await decodeImageCode(
-          fileInfo.frontOriginImgPath,
-          this.ocrArea
-        ).catch((err) => {
-          console.error(err);
-          logger.error(`03条码解析失败,${err}`);
-        });
-        fileInfo.studentCode = code || lastStudentCode;
-        fileInfo.ocrArea = ocrAreaContent;
-
-        if (fileInfo.studentCode) {
-          lastStudentCode = fileInfo.studentCode;
-        }
+        fileInfo.studentCode = fileInfo.studentCode || lastStudentCode;
+        lastStudentCode = fileInfo.studentCode;
       }
     },
     // scan relate
+    async deleteStage() {
+      if (!this.scanStageList.some((item) => item.selected)) {
+        this.$message.error("请选择要删除的数据!");
+        return;
+      }
+      const res = await this.$confirm(`确定要删除选中数据吗?`, "警告", {
+        type: "warning",
+      }).catch(() => {});
+      if (res !== "confirm") return;
+
+      this.scanStageList = this.scanStageList.filter((item) => !item.selected);
+    },
     async clearStage() {
       const res = await this.$confirm(`确定要清空数据吗?`, "警告", {
         type: "warning",
@@ -265,11 +285,11 @@ export default {
 
       this.scanStageList = [];
       this.scanStatus = "INIT";
-      this.clearData();
+      this.clearFiles();
       logger.info(`99数据清空`);
       this.$message.success("数据已清空!");
     },
-    async saveScanImage() {
+    async toSave() {
       if (!this.scanStageList.length) {
         this.$message.error("当前无要保存的数据!");
         return;
@@ -297,7 +317,7 @@ export default {
         );
 
         fileInfo.frontOriginImgPath = ouputImageList[0];
-        fileInfo.versoOriginImgPath = ouputImageList[0];
+        fileInfo.versoOriginImgPath = ouputImageList[1];
 
         let res = true;
         await db.saveUploadInfo(fileInfo).catch((err) => {
@@ -315,11 +335,11 @@ export default {
       this.$message.success("保存成功!");
       this.saving = false;
       logger.info(`04-2保存数据成功`);
-      this.clearData();
+      this.clearFiles();
       this.scanStatus = "INIT";
       this.scanStageList = [];
     },
-    clearData() {
+    clearFiles() {
       clearDir(this.GLOBAL.input);
     },
     async getScanHistory() {
@@ -346,6 +366,9 @@ export default {
       this.setCurPaper(imgItem);
       this.$refs.SimpleImagePreview.open();
     },
+    toSelect(imgItem) {
+      imgItem.selected = !imgItem.selected;
+    },
     setCurPaper(imgItem) {
       this.curPaper = {
         ...imgItem,

+ 11 - 4
src/modules/client/views/Scan.vue

@@ -44,7 +44,9 @@
                   <i class="icon icon-person-grid"></i>
                   <span>考生总数</span>
                 </div>
-                <div class="task-info-cont">{{ task.studentCount }}</div>
+                <div class="task-info-cont">
+                  {{ task.studentCount || "0" }}
+                </div>
               </div>
               <div class="task-info-item">
                 <div class="task-info-title">
@@ -52,9 +54,9 @@
                   <span>已扫人数<span class="mlr-1">/</span>张数</span>
                 </div>
                 <div class="task-info-cont">
-                  <span>{{ task.scanStudentCount }}</span>
+                  <span>{{ task.scanStudentCount || "0" }}</span>
                   <span class="mlr-1">/</span>
-                  <span>{{ task.scanCount }}</span>
+                  <span>{{ task.scanCount || "0" }}</span>
                 </div>
               </div>
               <div class="task-info-item">
@@ -66,7 +68,8 @@
               </div>
             </div>
           </div>
-          <div class="task-part-foot">
+          <div class="task-part-foot box-justify">
+            <div class="tips-info tips-error">待上传:{{ unuploadNo }}</div>
             <div class="task-btn" @click="toScan(true)">
               <span>开始扫描</span>
               <i class="icon icon-narrow-right"></i>
@@ -140,6 +143,9 @@ export default {
       if (!studentCount) return 0;
       return ((scanStudentCount * 100) / studentCount).toFixed(2) * 1;
     },
+    unuploadNo() {
+      return this.$store.state.client.unuploadNo;
+    },
   },
   mounted() {
     this.$store.commit("setBreadcrumbs", [{ url: "Scan", name: "扫描" }]);
@@ -147,6 +153,7 @@ export default {
   },
   methods: {
     async search() {
+      this.task = {};
       const res = await taskInfos(this.filter);
       this.task = { ...res, semesterId: this.filter.semesterId };
       this.searchFilter = { ...this.filter };

+ 1 - 4
src/modules/login/views/Login.vue

@@ -76,10 +76,7 @@ export default {
   name: "login",
   data() {
     return {
-      schools: [
-        // { code: "test-school-1", name: "学校1" },
-        // { code: "test-school-2", name: "学校2" },
-      ],
+      schools: [],
       loginModel: {
         schoolCode: "",
         type: "ACCOUNT",

+ 6 - 2
src/plugins/axios.js

@@ -20,8 +20,12 @@ const addLog = (datas, type) => {
     const msg = `${datas.config.url},请求成功`;
     logger.info(msg);
   } else {
-    const msg = `${datas.config.url},请求错误,错误信息:${datas.response.data.status} - ${datas.response.data.message}`;
-    logger.error(msg);
+    if (datas.config && datas.response) {
+      const msg = `${datas.config?.url},请求错误,错误信息:${datas.response.data.status} - ${datas.response.data.message}`;
+      logger.error(msg);
+    } else {
+      logger.error(datas.message || "请求错误");
+    }
   }
 };
 

+ 6 - 3
src/views/Home.vue

@@ -49,12 +49,15 @@ export default {
   },
   created() {
     this.initUploadTask();
-    // this.updateUnuploadCount();
+    this.updateUnuploadCount();
   },
   computed: {
     breadcrumbs() {
       return this.$store.state.breadcrumbs;
     },
+    unuploadNo() {
+      return this.$store.state.client.unuploadNo;
+    },
   },
   methods: {
     // unupload count
@@ -67,8 +70,8 @@ export default {
       }, 2 * 1000);
     },
     toBack() {
-      if (this.$route.name === "Scan") {
-        this.$confirm("确定要退出采集吗?", "提示", {
+      if (this.$route.name === "Scan" && this.unuploadNo) {
+        this.$confirm("当前还有数据未上传,确定要退出采集吗?", "提示", {
           type: "warning",
         })
           .then(() => {