<template>
  <div class="group-scan">
    <div class="home-header">
      <div class="head-logo">
        <h1>试卷采集</h1>
      </div>
      <div class="head-back">
        <i-button type="default" @click="goBack"
          ><i class="icon-font icon-left"></i>返回</i-button
        >
      </div>
    </div>
    <div class="home-body">
      <div class="home-main home-main-split">
        <div
          class="scan-list student-list"
          id="student-list"
          v-if="studentSerialList.length"
        >
          <div
            v-for="(student, index) in studentSerialList"
            :key="index"
            :class="[
              'student-item',
              {
                'student-current': student.isCurrent,
                'student-over': student.isClient
              }
            ]"
          >
            <span>{{ student.name }}</span>
            <span>{{ student.examNumber }}</span>
          </div>
          <div class="scan-btns">
            <i-button type="primary" @click="scanOver" :disabled="holding"
              >扫描完毕</i-button
            >
            <i-button type="primary" @click="allReScan">整包重扫</i-button>
          </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>
    </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"
      @on-hand-input="examNumberValid"
      ref="ScanExceptionDialog"
    ></scan-exception-dialog>
  </div>
</template>

<script>
const fs = require("fs");
import { getStudentGroupByExamNumber } from "../api";
import {
  decodeImageCode,
  getEarliestFile,
  saveFormalImage
} from "../../../plugins/imageOcr";
import { formatDate } from "../../../plugins/utils";
import ScanAreaDialog from "../components/ScanAreaDialog";
import ScanExceptionDialog from "../components/ScanExceptionDialog";

export default {
  name: "group-scan",
  components: { ScanAreaDialog, ScanExceptionDialog },
  data() {
    return {
      isWaiting: true,
      students: [],
      curStudent: {},
      curCollectConfig: {},
      curException: {
        showAction: true,
        message: ""
      },
      setT: "",
      holding: false,
      curImage: {
        url: "",
        name: ""
      }
    };
  },
  computed: {
    user() {
      return this.$store.state.user;
    },
    curSubject() {
      return this.$store.state.curSubject;
    },
    studentSerialList() {
      return this.students.sort((a, b) => {
        if (a.isClient) return -1;
        if (b.isClient) return 1;
        if (a.isCurrent) return -1;
        if (b.isCurrent) return 1;
        return 0;
      });
    },
    scanNo() {
      return this.students.filter(item => item.isClient).length;
    },
    taskNo() {
      return this.students.length;
    },
    isFinished() {
      return this.taskNo && this.scanNo === this.taskNo;
    }
  },
  mounted() {
    this.getInitFile();
    // this.curImage = {
    //   name: "1901130043.jpg",
    //   url: "E:\\newspace\\msyj-client\\in\\1901130043.jpg"
    // };
  },
  methods: {
    getInitFile() {
      if (this.isFinished) {
        this.isWaiting = true;
        if (this.setT) clearTimeout(this.setT);
        return;
      }
      this.curImage = getEarliestFile();

      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.holding = false;
      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: "" };
      if (!this.students.length) {
        const students = await getStudentGroupByExamNumber(examNumber);
        if (students && students.length) {
          this.students = students.map(item => {
            return {
              ...item,
              isClient: false,
              isCurrent: false,
              isManual: false,
              collectConfig: null
            };
          });
        } else {
          validInfo = {
            valid: false,
            message: "学生数据没有上传，请重新采集！"
          };
          return validInfo;
        }
        // 请求远程当前学生所在组的所有学生信息。
        // 通过当前学生examNumber获取到的学生列表为空时，抛出异常
      }

      this.curStudent = this.students.find(
        item => item.examNumber === examNumber
      );
      if (!this.curStudent) {
        validInfo = {
          valid: false,
          message: "当前考场没有当前学生，请重新采集！"
        };
      } else {
        this.curStudent.isCurrent = true;
      }
      return validInfo;
    },
    async toSaveStudent(examNumber, type) {
      await saveFormalImage(
        this.curImage.url,
        {
          workId: this.user.workId,
          subjectId: this.curSubject.id,
          examNumber
        },
        this.getCurCollectConfig()
      );
      this.curStudent = Object.assign(this.curStudent, {
        isCurrent: false,
        isClient: true,
        isManual: type === "MANUAL"
      });

      // 删除扫描文件，继续开始下一个任务
      fs.unlinkSync(this.curImage.url);
      this.restartInitFile();
    },
    checkAllStudentIsClient() {
      return !this.students.some(item => !item.isClient);
    },
    async scanOver() {
      if (this.holding) return;
      this.holding = true;
      if (!this.checkAllStudentIsClient()) {
        this.$Message.error("当前考场试卷没有扫完！");
        this.holding = false;
        return;
      }
      // 添加上传任务
      for (let i = 0, len = this.students.length; i < len; i++) {
        const curStudent = this.students[i];
        await this.$parent.addUploadTask({
          workId: this.user.workId,
          workName: this.user.workName,
          subjectId: this.curSubject.id,
          subjectName: this.curSubject.name,
          examNumber: curStudent.examNumber,
          studentName: curStudent.name,
          siteCode: curStudent.siteCode,
          roomCode: curStudent.roomCode,
          createdTime: formatDate(),
          isManual: curStudent.isManual,
          clientUserId: this.user.id,
          clientUsername: this.user.name,
          clientUserLoginTime: this.user.clientUserLoginTime
        });
      }

      this.allReScan();
    },
    allReScan() {
      this.students = [];
      this.restartInitFile();
    },
    getCurCollectConfig() {
      return this.curStudent.collectConfig || this.curSubject.collectConfig;
    },
    // 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);
        }
      });
    }
  },
  beforeDestroy() {
    if (this.setT) clearTimeout(this.setT);
  }
};
</script>
