|
@@ -1,13 +1,372 @@
|
|
|
<template>
|
|
|
- <div class="scan-other">scan-other</div>
|
|
|
+ <div class="scan-other">
|
|
|
+ <div class="part-box part-box-filter part-box-flex">
|
|
|
+ <el-form
|
|
|
+ ref="modalFormComp"
|
|
|
+ :model="modalForm"
|
|
|
+ :rules="rules"
|
|
|
+ label-position="left"
|
|
|
+ label-width="85px"
|
|
|
+ inline
|
|
|
+ >
|
|
|
+ <el-form-item prop="roomOrClass" label="考场/班级:">
|
|
|
+ <room-class-select
|
|
|
+ v-model="modalForm.roomOrClass"
|
|
|
+ placeholder="请选择考场/班级"
|
|
|
+ :disabled="isScaning"
|
|
|
+ >
|
|
|
+ </room-class-select>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item prop="fileType" label="文件类型:">
|
|
|
+ <file-type-select
|
|
|
+ v-model="modalForm.fileType"
|
|
|
+ placeholder="请选择文件类型"
|
|
|
+ :disabled="isScaning"
|
|
|
+ >
|
|
|
+ </file-type-select>
|
|
|
+ </el-form-item>
|
|
|
+ </el-form>
|
|
|
+ <div class="part-box-action">
|
|
|
+ <el-button :disabled="!canClear" type="danger" @click="clearStage"
|
|
|
+ >清空</el-button
|
|
|
+ >
|
|
|
+ <el-button
|
|
|
+ :disabled="!canSave"
|
|
|
+ :loading="saving"
|
|
|
+ type="primary"
|
|
|
+ @click="toSave"
|
|
|
+ >保存</el-button
|
|
|
+ >
|
|
|
+ <el-button
|
|
|
+ type="primary"
|
|
|
+ :loading="scanStatus === 'SCAN'"
|
|
|
+ :disabled="!canScan"
|
|
|
+ @click="toScan"
|
|
|
+ >
|
|
|
+ {{ statusDesc[scanStatus] }}
|
|
|
+ </el-button>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div class="part-box part-box-pad">
|
|
|
+ <el-table ref="TableList" size="medium" :data="dataList">
|
|
|
+ <el-table-column
|
|
|
+ prop="文件名"
|
|
|
+ label="任务名称"
|
|
|
+ min-width="300"
|
|
|
+ ></el-table-column>
|
|
|
+ <el-table-column
|
|
|
+ prop="roomOrClass"
|
|
|
+ label="考场/班级"
|
|
|
+ min-width="160"
|
|
|
+ ></el-table-column>
|
|
|
+ <el-table-column
|
|
|
+ prop="fileType"
|
|
|
+ label="文件类型"
|
|
|
+ width="160"
|
|
|
+ ></el-table-column>
|
|
|
+ </el-table>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <!-- SelectBatchNoDialog -->
|
|
|
+ <select-batch-no-dialog
|
|
|
+ ref="SelectBatchNoDialog"
|
|
|
+ @confirm="saveScanData"
|
|
|
+ ></select-batch-no-dialog>
|
|
|
+ </div>
|
|
|
</template>
|
|
|
|
|
|
<script>
|
|
|
+import {
|
|
|
+ getPreUploadFiles,
|
|
|
+ saveOutputImage,
|
|
|
+ clearDir,
|
|
|
+ getDirScanFile,
|
|
|
+} from "../../../plugins/imageOcr";
|
|
|
+import db from "../../../plugins/db";
|
|
|
+import { evokeScanner } from "../../../plugins/scanner";
|
|
|
+
|
|
|
+import FileTypeSelect from "@/components/base/FileTypeSelect.vue";
|
|
|
+import RoomClassSelect from "@/components/base/RoomClassSelect.vue";
|
|
|
+import SelectBatchNoDialog from "../components/SelectBatchNoDialog.vue";
|
|
|
+
|
|
|
+import timeMixins from "@/mixins/setTimeMixins";
|
|
|
+import log4js from "@/plugins/logger";
|
|
|
+import { randomCode } from "@/plugins/utils";
|
|
|
+import { getStageDir } from "@/plugins/env";
|
|
|
+const logger = log4js.getLogger("scan");
|
|
|
+
|
|
|
export default {
|
|
|
name: "scan-other",
|
|
|
+ components: { RoomClassSelect, FileTypeSelect, SelectBatchNoDialog },
|
|
|
+ mixins: [timeMixins],
|
|
|
data() {
|
|
|
- return {};
|
|
|
+ return {
|
|
|
+ task: this.$ls.get("task", {}),
|
|
|
+ scanStatus: "INIT",
|
|
|
+ scanStageList: [],
|
|
|
+ statusDesc: {
|
|
|
+ INIT: "开始扫描",
|
|
|
+ SCAN: "扫描中",
|
|
|
+ FINISH: "继续扫描",
|
|
|
+ },
|
|
|
+ user: this.$ls.get("user", {}),
|
|
|
+ saving: false,
|
|
|
+ maxCacheCount: 120,
|
|
|
+ scanCount: 0,
|
|
|
+ modalForm: {
|
|
|
+ roomOrClass: "",
|
|
|
+ fileType: "",
|
|
|
+ },
|
|
|
+ rules: {
|
|
|
+ roomOrClass: [
|
|
|
+ {
|
|
|
+ required: true,
|
|
|
+ message: "请选择考场/班级",
|
|
|
+ trigger: "change",
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ fileType: [
|
|
|
+ {
|
|
|
+ required: true,
|
|
|
+ message: "请选择文件类型",
|
|
|
+ trigger: "change",
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ },
|
|
|
+ // 非等待模式:delayMode:0
|
|
|
+ looping: false,
|
|
|
+ stageDir: getStageDir(),
|
|
|
+ };
|
|
|
+ },
|
|
|
+ computed: {
|
|
|
+ paperCount() {
|
|
|
+ return this.scanStageList.length;
|
|
|
+ },
|
|
|
+ canSave() {
|
|
|
+ return this.scanStatus === "FINISH" && this.paperCount > 0;
|
|
|
+ },
|
|
|
+ canScan() {
|
|
|
+ return (
|
|
|
+ this.scanStatus !== "SCAN" && this.paperCount <= this.maxCacheCount
|
|
|
+ );
|
|
|
+ },
|
|
|
+ canClear() {
|
|
|
+ return this.paperCount > 0;
|
|
|
+ },
|
|
|
+ isScaning() {
|
|
|
+ return this.scanStatus === "SCAN";
|
|
|
+ },
|
|
|
+ IS_DELAY_MODE() {
|
|
|
+ return this.GLOBAL.delayMode === 1;
|
|
|
+ },
|
|
|
+ },
|
|
|
+ beforeDestroy() {
|
|
|
+ this.stopLoopScaningFile();
|
|
|
+ },
|
|
|
+ methods: {
|
|
|
+ initData() {
|
|
|
+ this.scanStageList = [];
|
|
|
+ this.scanStatus = "INIT";
|
|
|
+ this.scanCount = 0;
|
|
|
+ },
|
|
|
+ clearFiles() {
|
|
|
+ clearDir(this.stageDir);
|
|
|
+ },
|
|
|
+ async goBackHandle() {
|
|
|
+ if (this.scanStageList.length) {
|
|
|
+ const res = await this.$confirm(
|
|
|
+ `当前存在未保存的扫描数据,确定要退出吗?`,
|
|
|
+ "警告",
|
|
|
+ {
|
|
|
+ type: "warning",
|
|
|
+ }
|
|
|
+ ).catch(() => {});
|
|
|
+ if (res !== "confirm") return;
|
|
|
+ }
|
|
|
+
|
|
|
+ logger.info(`99退出扫描`);
|
|
|
+ },
|
|
|
+ // scan
|
|
|
+ async toScan() {
|
|
|
+ if (!this.canScan) {
|
|
|
+ this.$message.error("已超过最大缓存数量,请先保存数据再继续扫描!");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ const valid = await this.$refs.modalFormComp.validate().catch(() => {});
|
|
|
+ if (!valid) return;
|
|
|
+
|
|
|
+ if (this.scanStatus === "INIT") {
|
|
|
+ this.startTask();
|
|
|
+ } else {
|
|
|
+ this.continueTask();
|
|
|
+ }
|
|
|
+ },
|
|
|
+ startTask() {
|
|
|
+ logger.info(`01开始扫描`);
|
|
|
+ this.continueTask();
|
|
|
+ },
|
|
|
+ continueTask() {
|
|
|
+ this.scanStatus = "SCAN";
|
|
|
+ if (this.IS_DELAY_MODE) {
|
|
|
+ this.evokeScanExe();
|
|
|
+ } else {
|
|
|
+ this.evokeScanExeNotDelay();
|
|
|
+ }
|
|
|
+ },
|
|
|
+ async evokeScanExe() {
|
|
|
+ logger.info("02唤起扫描仪");
|
|
|
+ await evokeScanner(this.GLOBAL.input).catch((error) => {
|
|
|
+ console.error(error);
|
|
|
+ });
|
|
|
+
|
|
|
+ // 缓存已扫描的数据
|
|
|
+ const res = getPreUploadFiles(this.GLOBAL.input, true);
|
|
|
+ if (!res.succeed) {
|
|
|
+ logger.error(`03扫描仪停止,故障:${res.errorMsg}`);
|
|
|
+ this.$message.error(res.errorMsg);
|
|
|
+ this.scanStatus = "FINISH";
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ logger.info(`03扫描仪停止,扫描数:${res.data.length}`);
|
|
|
+ await this.stageScanImage(res.data);
|
|
|
+ this.scanStatus = "FINISH";
|
|
|
+ logger.info(`03-1完成条码解析`);
|
|
|
+ },
|
|
|
+ async evokeScanExeNotDelay() {
|
|
|
+ logger.info("02唤起扫描仪");
|
|
|
+ this.looping = true;
|
|
|
+ this.loopScaningFile();
|
|
|
+
|
|
|
+ await evokeScanner(this.GLOBAL.input).catch((error) => {
|
|
|
+ console.error(error);
|
|
|
+ });
|
|
|
+ this.stopLoopScaningFile();
|
|
|
+ await this.getScaningFile();
|
|
|
+
|
|
|
+ const scanCount = this.scanStageList.length - this.scanCount;
|
|
|
+ this.scanCount = this.scanStageList.length;
|
|
|
+
|
|
|
+ // 已扫描的数据
|
|
|
+ const res = getPreUploadFiles(this.GLOBAL.input);
|
|
|
+ this.scanStatus = "FINISH";
|
|
|
+ if (!res.succeed) {
|
|
|
+ logger.error(
|
|
|
+ `03扫描仪停止,扫描数:${scanCount},故障:${res.errorMsg}`
|
|
|
+ );
|
|
|
+ this.$message.error(res.errorMsg);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ logger.info(`03扫描仪停止,扫描数:${scanCount}`);
|
|
|
+ },
|
|
|
+ async stageScanImage(imageList) {
|
|
|
+ for (let i = 0, len = imageList.length; i < len; i++) {
|
|
|
+ const fileInfo = {
|
|
|
+ id: randomCode(16),
|
|
|
+ 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: imageList[i].frontFile,
|
|
|
+ versoOriginImgPath: imageList[i].versoFile,
|
|
|
+ isFormal: 0,
|
|
|
+ studentName: "",
|
|
|
+ studentCode: "",
|
|
|
+ ocrArea: "",
|
|
|
+ fileType: this.modalForm.fileType,
|
|
|
+ roomOrClass: this.modalForm.roomOrClass,
|
|
|
+ batchNo: "",
|
|
|
+ clientUserId: this.user.id,
|
|
|
+ clientUsername: this.user.loginName,
|
|
|
+ clientUserLoginTime: this.user.loginTime,
|
|
|
+ };
|
|
|
+
|
|
|
+ this.scanStageList.push(fileInfo);
|
|
|
+ }
|
|
|
+ },
|
|
|
+ async saveScanItem(fileInfo) {
|
|
|
+ const ouputImageList = saveOutputImage(
|
|
|
+ [fileInfo.frontOriginImgPath, fileInfo.versoOriginImgPath],
|
|
|
+ {
|
|
|
+ courseCode: this.task.courseCode,
|
|
|
+ }
|
|
|
+ );
|
|
|
+
|
|
|
+ fileInfo.frontOriginImgPath = ouputImageList[0];
|
|
|
+ fileInfo.versoOriginImgPath = ouputImageList[1];
|
|
|
+
|
|
|
+ await db.saveUploadInfo(fileInfo);
|
|
|
+ },
|
|
|
+ toSave() {
|
|
|
+ if (!this.scanStageList.length) {
|
|
|
+ this.$message.error("当前无要保存的数据!");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ this.$refs.selectBatchNoDialog.open();
|
|
|
+ },
|
|
|
+ async saveScanData(batchNo) {
|
|
|
+ if (this.saving) return;
|
|
|
+ this.saving = true;
|
|
|
+
|
|
|
+ // TODO: 使用批量保存,有时间再做
|
|
|
+ logger.info(`04-1开始保存数据`);
|
|
|
+ for (let i = 0, len = this.scanStageList.length; i < len; i++) {
|
|
|
+ const fileInfo = this.scanStageList[i];
|
|
|
+ fileInfo.batchNo = batchNo;
|
|
|
+
|
|
|
+ let res = true;
|
|
|
+ await this.saveScanItem(fileInfo).catch((err) => {
|
|
|
+ res = false;
|
|
|
+ console.error(err);
|
|
|
+ logger.error(`04-1保存数据错误,${err}`);
|
|
|
+ });
|
|
|
+ if (!res) {
|
|
|
+ this.saving = false;
|
|
|
+ this.$message.error("保存数据错误,请重新尝试!");
|
|
|
+ return Promise.reject();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ this.$message.success("保存成功!");
|
|
|
+ this.saving = false;
|
|
|
+ logger.info(`04-2保存数据成功`);
|
|
|
+ this.clearFiles();
|
|
|
+ this.initData();
|
|
|
+ },
|
|
|
+ // delay mode
|
|
|
+ // 实时获取扫描图片
|
|
|
+ async loopScaningFile() {
|
|
|
+ this.clearSetTs();
|
|
|
+ if (!this.looping) return;
|
|
|
+ await this.getScaningFile();
|
|
|
+
|
|
|
+ this.addSetTime(this.loopScaningFile, 1 * 1000);
|
|
|
+ },
|
|
|
+ stopLoopScaningFile() {
|
|
|
+ this.clearSetTs();
|
|
|
+ this.looping = false;
|
|
|
+ },
|
|
|
+ async getScaningFile() {
|
|
|
+ const newScanFiles = getDirScanFile(this.GLOBAL.input);
|
|
|
+ await this.stageScanImage(newScanFiles);
|
|
|
+ },
|
|
|
+ // table action
|
|
|
+ async clearStage() {
|
|
|
+ const res = await this.$confirm(`确定要清空所有数据吗?`, "警告", {
|
|
|
+ type: "warning",
|
|
|
+ }).catch(() => {});
|
|
|
+ if (res !== "confirm") return;
|
|
|
+
|
|
|
+ this.clearFiles();
|
|
|
+ this.initData();
|
|
|
+
|
|
|
+ logger.info(`99数据清空`);
|
|
|
+ this.$message.success("数据已清空!");
|
|
|
+ },
|
|
|
},
|
|
|
- methods: {},
|
|
|
};
|
|
|
</script>
|