<template>
  <div class="home">
    <header class="header">
      <div class="school-logo">
        <img
          v-show="logoPath"
          class="logo-size"
          :src="logoPath"
          alt="school logo"
          style="background: linear-gradient(to bottom, #38f6f5 0%, #8efdf4 100%);"
          @load="e => (e.target.style = '')"
        />
      </div>
      <a
        class="close"
        style="border-bottom-left-radius: 6px;"
        @click="closeApp"
      >
        关闭
      </a>
    </header>

    <div class="center">
      <div class="content">
        <div style="display:flex;">
          <a
            v-if="allowLoginType.includes('STUDENT_CODE')"
            key="STUDENT_CODE"
            :class="[
              'qm-big-text',
              'login-type',
              loginType === 'STUDENT_CODE' && 'active-type',
              allowLoginType.length === 1 && 'single-login-type',
            ]"
            style="border-top-left-radius: 6px"
            @click="loginType = 'STUDENT_CODE'"
          >
            {{ QECSConfig.STUDENT_CODE_LOGIN_ALIAS }}
          </a>
          <a
            v-if="allowLoginType.includes('IDENTITY_NUMBER')"
            key="IDENTITY_NUMBER"
            :class="[
              'qm-big-text',
              'login-type',
              loginType !== 'STUDENT_CODE' && 'active-type',
              allowLoginType.length === 1 && 'single-login-type',
            ]"
            style="border-top-right-radius: 6px"
            @click="loginType = 'STUDENT_IDENTITY_NUMBER'"
          >
            {{ QECSConfig.IDENTITY_NUMBER_LOGIN_ALIAS }}
          </a>
          <a
            v-if="allowLoginType.length === 0"
            key="loading"
            :class="['qm-big-text', 'login-type']"
          >
            loading...
          </a>
        </div>

        <div class="qm-title-text" style="margin: 40px 0 20px 0">
          {{ productName }}
        </div>

        <div style="margin: 0 40px 40px 40px">
          <i-form ref="loginForm" :model="loginForm" :rules="loginFormRule">
            <i-form-item
              prop="accountValue"
              style="margin-bottom:35px;height:42px"
            >
              <i-input
                v-model="loginForm.accountValue"
                type="text"
                size="large"
              >
                <i-icon slot="prepend" type="ios-person"></i-icon>
              </i-input>
            </i-form-item>
            <i-form-item prop="password" style="margin-bottom:35px;height:42px">
              <i-input
                v-model="loginForm.password"
                type="password"
                size="large"
                @on-enter="loginForuser"
              >
                <i-icon slot="prepend" type="ios-lock"></i-icon>
              </i-input>
            </i-form-item>
            <i-form-item style="position: relative">
              <div
                v-if="errorInfo !== ''"
                style="position: absolute; top: -37px; width: 100%"
              >
                <i-alert type="error" show-icon>{{ errorInfo }}</i-alert>
              </div>
              <i-button
                size="large"
                class="qm-primary-button"
                long
                :disabled="disableLoginBtn"
                :loading="loginBtnLoading"
                @click="loginForuser"
              >
                {{ newVersionAvailable ? "点击更新版本" : "登录" }}
              </i-button>
            </i-form-item>
          </i-form>
        </div>
      </div>
    </div>

    <footer class="footer">
      <div style="position: absolute; right: 20px; bottom: 20px;">
        版本: {{ VUE_APP_GIT_REPO_VERSION }}
      </div>
      <DevTools />
    </footer>
  </div>
</template>

<script>
import moment from "moment";
import { mapMutations } from "vuex";
import { FACE_API_MODEL_PATH } from "@/constants/constants";
import DevTools from "./DevTools.vue";
import nativeExe, { fileExists } from "@/utils/nativeExe";
import {
  EPCC_DOMAIN,
  VUE_APP_CONFIG_FILE_SEVER_URL,
} from "@/constants/constants";
import UA, { chromeUA } from "@/utils/ua.js";
import { createLog, createUserLog } from "@/utils/logger";

// 检测devtools.  仅在chrome 72+ 有效。
let element = new Image();
Object.defineProperty(element, "id", {
  get: function() {
    // console.log("trigger devtools log");
    window._hmt.push([
      "_trackEvent",
      "控制台打开",
      window.location.href,
      "|||" +
        localStorage.getItem("domain") +
        "|||" +
        localStorage.getItem("key"),
    ]);
    return null;
  },
});

/**
 * 在任何组件需要强制退出，做以下步骤
 * 1. this.$Message.info()
 * 2. this.$router.push("/login"+domain);
 * 因为在/login里会删除localStorage的token，而在router.beforeEach会检查是否有token，达到退出的目的。
 */

export default {
  name: "Login",
  components: {
    DevTools,
  },
  data() {
    return {
      domainInUrl:
        this.$route.params.domain ||
        window.location.hostname.split(".")[0] + ".ecs.qmth.com.cn",
      QECSConfig: {},
      loginType: "STUDENT_CODE",
      errorInfo: "",
      loginForm: {
        accountValue: "",
        password: "",
      },
      loginFormRule: {
        accountValue: [
          {
            required: true,
            message: "请填写登录账号",
            trigger: "blur",
          },
        ],
        password: [
          {
            required: true,
            message: "请填写密码",
            trigger: "blur",
          },
        ],
      },
      loginBtnLoading: false,
      isElectron: true,
      disableLoginBtnBecauseRemoteApp: true,
      disableLoginBtnBecauseVCam: true,
      disableLoginBtnBecauseAppVersionChecker: false,
      disableLoginBtnBecauseRefreshServiceWorker: false,
      disableLoginBtnBecauseNotAllowedNative: true,
      newVersionAvailable: false,
      VUE_APP_GIT_REPO_VERSION: process.env.VUE_APP_GIT_REPO_VERSION,
    };
  },
  computed: {
    logoPath() {
      // "!/progressive/true/format/webp"
      return this.QECSConfig.LOGO_FILE_URL ? this.QECSConfig.LOGO_FILE_URL : "";
    },
    productName() {
      return this.QECSConfig.OE_STUDENT_SYS_NAME || "远程教育网络考试";
    },
    allowLoginType() {
      return (
        (this.QECSConfig.LOGIN_TYPE && this.QECSConfig.LOGIN_TYPE.split(",")) ||
        []
      );
    },
    schoolDomain() {
      const domain = this.domainInUrl;
      if (!domain || !domain.includes("qmth.com.cn")) {
        this.$Message.error({
          content: "机构地址出错，请关闭程序后再登录。",
          duration: 15,
          closable: true,
        });
      }
      return domain;
    },
    isEPCC() {
      return this.schoolDomain === EPCC_DOMAIN;
    },
    usernameInputPlaceholder() {
      if (this.loginType === "STUDENT_CODE") {
        return "请输入学号";
      } else {
        return "请输入身份证号";
      }
    },
    passwordInputPlaceholder() {
      if (this.loginType === "STUDENT_CODE") {
        return "初始密码为身份证号后6位";
      } else {
        return "初始密码为身份证号后6位";
      }
    },
    disableLoginBtn() {
      // console.log(
      //   this.isElectron,
      //   this.disableLoginBtnBecauseRemoteApp,
      //   this.disableLoginBtnBecauseVCam,
      //   this.disableLoginBtnBecauseAppVersionChecker
      // );
      return (
        (this.isElectron &&
          (this.disableLoginBtnBecauseRemoteApp ||
            this.disableLoginBtnBecauseVCam)) ||
        this.disableLoginBtnBecauseAppVersionChecker ||
        this.disableLoginBtnBecauseRefreshServiceWorker ||
        this.disableLoginBtnBecauseNotAllowedNative
      );
    },
  },
  async mounted() {
    // this.testServiceWorker();

    this.examShellStats();
    // await this.checkNewVersion();
    if (localStorage.getItem("__swReload")) {
      localStorage.removeItem("__swReload");
      this.$Message.info({
        content: "正在更新版本...",
      });
      this.disableLoginBtnBecauseRefreshServiceWorker = true;
      await new Promise(resolve => {
        setTimeout(() => {
          resolve();
        }, 2000);
      });
      location.reload(true);
    }
    // manual precache for models
    fetch(
      FACE_API_MODEL_PATH + "tiny_face_detector_model-weights_manifest.json"
    );
    fetch(FACE_API_MODEL_PATH + "face_landmark_68_model-weights_manifest.json");
    fetch(FACE_API_MODEL_PATH + "face_expression_model-weights_manifest.json");
    // alread precached
    // fetch("/models/tiny_face_detector_model-shard1");
    // fetch("/models/face_landmark_68_model-shard1");

    // this.checkNewVersionInterval = setInterval(() => {
    //   if (window.__newSWAvailable) {
    //     this.newVersionAvailable = true;
    //   }
    // }, 1000);
    this.checkNewVersionListener = document.addEventListener(
      "__newSWAvailable",
      () => {
        this.newVersionAvailable = true;
      },
      { once: true }
    );
    if (this.isEPCC) {
      const redirectUrl = new URLSearchParams(location.search).get(
        "redirectUrl"
      );
      if (redirectUrl) {
        sessionStorage.setItem("redirectUrl", redirectUrl);
      }
      this.login();
    }
  },
  async created() {
    createLog({
      currentPage: "登录页面",
      action: "page created",
      UA: navigator.userAgent,
    });
    if (navigator.connection) {
      console.log("UA: ", navigator.userAgent);
      console.log(
        "_trackEvent",
        "登录页面",
        `当前网速: ${Number(navigator.connection.downlink).toPrecision(
          1
        )}Mib; 网络延迟: ${Number(navigator.connection.rtt).toPrecision(1)}ms`
      );
      window._hmt.push([
        "_trackEvent",
        "登录页面",
        `当前网速: ${Number(navigator.connection.downlink).toPrecision(
          1
        )}Mib; 网络延迟: ${Number(navigator.connection.rtt).toPrecision(1)}ms`,
      ]);
    }
    if (this.isEPCC) {
      this.$Spin.show({
        render: () => {
          return <div style="font-size: 44px">正在登录...</div>;
        },
      });
    }

    this.isElectron = typeof nodeRequire != "undefined";

    if (
      navigator.userAgent.indexOf("WOW64") != -1 ||
      navigator.userAgent.indexOf("Win64") != -1
    ) {
      window._hmt.push(["_trackEvent", "登录页面", "64Bit OS"]);
    } else {
      window._hmt.push(["_trackEvent", "登录页面", "非64Bit OS"]);
    }

    this.$Message.config({
      duration: 15,
      size: "large",
      closable: true, // 没有影响到所有的组件。。。  https://github.com/iview/iview/issues/2962
    });

    window.sessionStorage.removeItem("token");
    window.sessionStorage.clear();
    window.localStorage.removeItem("key");
    if (localStorage.getItem("user-for-reload")) {
      const lsUser = JSON.parse(localStorage.getItem("user-for-reload"));
      this.loginForm.accountValue =
        lsUser.studentCode ||
        (lsUser.studentCodeList && lsUser.studentCodeList[0]);
      this.loginForm.password =
        process.env.NODE_ENV === "production" ? "" : "180613";
    }

    if (
      [
        "xjtu.ecs.qmth.com.cn",
        "ccnu.ecs.qmth.com.cn",
        "snnu.ecs.qmth.com.cn",
        "swjtu.ecs.qmth.com.cn",
      ].includes(this.$route.params.domain)
    ) {
      if (
        typeof nodeRequire == "undefined" ||
        !window.nodeRequire("fs").existsSync("multiCamera.exe")
      ) {
        this.disableLoginBtnBecauseAppVersionChecker = true;
        this.$Message.error({
          content: "请与学校申请最新的客户端，进行考试！",
          duration: 2 * 24 * 60 * 60,
        });
      }
    }

    if (["cup.ecs.qmth.com.cn"].includes(this.$route.params.domain)) {
      // console.log(UA.getBrowser(), chromeUA);
      if (
        UA.getBrowser().name !== "electron-exam-shell" ||
        (UA.getBrowser().major !== "2" && UA.getBrowser().major !== "1") ||
        chromeUA.major < "58"
      ) {
        this.disableLoginBtnBecauseAppVersionChecker = true;
        this.$Message.error({
          content: "请与学校申请最新的客户端，进行考试！",
          duration: 2 * 24 * 60 * 60,
        });
      }
    }

    // if (
    //   ["cugr.ecs.qmth.com.cn", "sdu.ecs.qmth.com.cn"].includes(
    //     this.$route.params.domain
    //   )
    // ) {
    //   // console.log(UA.getBrowser(), chromeUA);
    //   if (
    //     UA.getBrowser().name !== "electron-exam-shell" ||
    //     UA.getBrowser().major !== "2" ||
    //     chromeUA.major < "76"
    //   ) {
    //     this.disableLoginBtnBecauseAppVersionChecker = true;
    //     this.$Message.error({
    //       content: "请与学校申请最新的客户端，进行考试！",
    //       duration: 2 * 24 * 60 * 60,
    //     });
    //   }
    // }

    await this.checkElectronConfig();
    await this.checkVCam();
    await this.checkAllowedClient();

    if (
      this.allowLoginType.length === 1 &&
      this.allowLoginType[0] === "IDENTITY_NUMBER"
    ) {
      this.loginType = "STUDENT_IDENTITY_NUMBER";
    }
  },
  beforeDestroy() {
    clearTimeout(this.loginTimeout);
    // clearInterval(this.checkNewVersionInterval);
    document.removeEventListener(
      "__newSWAvailable",
      this.checkNewVersionListener
    );
  },
  methods: {
    ...mapMutations(["updateUser", "updateTimeDifference", "updateQECSConfig"]),
    testServiceWorker() {
      if ("serviceWorker" in navigator) {
        // Register service worker
        navigator.serviceWorker
          .register("/service-worker-test.js")
          .then(function(reg) {
            console.log("Registration OK!. Scope is " + reg.scope);
          })
          .catch(function(err) {
            console.error("Registration FAILED! " + err);
          });
      }
    },
    async loginForuser() {
      // 供user点击的 login 方法。主要是保护 login 方法，不因为user重复点击，多个请求不按预期时间进行。
      createLog({ currentPage: "登录页面", action: "点击登录按钮" });
      if (this.loginBtnLoading) {
        return;
      }
      this.loginBtnLoading = true;
      const before = Date.now();

      try {
        await this.login();
      } finally {
        const end = Date.now();
        this.loginTimeout = setTimeout(() => {
          this.loginBtnLoading = false;
        }, 10 * 1000 - (end - before));
      }
    },
    async login() {
      // epcc立即登录
      if (!this.isEPCC && this.disableLoginBtn) {
        return;
      }

      try {
        const hasNewVersion = await this.checkNewVersion();
        if (hasNewVersion) return;
      } catch (error) {
        console.log("检测新版本出错");
      }

      let loginResponse;
      if (!this.isEPCC) {
        // https://www.cnblogs.com/weiqinl/p/6708993.html
        const valid = await this.$refs.loginForm.validate();
        if (!valid) {
          return;
        }

        let repPara = this.loginForm;
        // 以下网络请求失败，直接报网络异常错误
        loginResponse = await this.$http.post("/api/ecs_core/auth/login", {
          ...repPara,
          accountType: this.loginType,
          domain: this.schoolDomain,
          alwaysOK: true,
        });
      } else {
        loginResponse = await this.epccLogin();
        if (!loginResponse) {
          return;
        } else {
          loginResponse.data = { content: loginResponse.data, code: "200" }; // 和老接口的always ok保持一致
        }
      }
      let data = loginResponse.data;
      // if (
      //   Math.abs() >
      //   5 * 60 * 1000
      // ) {
      //   window._hmt.push(["_trackEvent", "登录页面", "本机时间误差过大"]);
      //   this.$Message.error({
      //     content: "与服务器时间差异超过5分钟，请校准本机时间之后再重试！",
      //     duration: 30
      //   });
      //   throw "与服务器时间差异超过5分钟，请校准本机时间之后再重试！";
      // }

      this.updateTimeDifference(
        moment(loginResponse.headers.date).diff(moment())
      );
      if (data.code == "200") {
        data = data.content;
        this.errorInfo = "";
        //缓存用户信息
        window.sessionStorage.setItem("token", data.token);
        window.localStorage.setItem("key", data.key);
        window.localStorage.setItem("domain", this.schoolDomain);

        try {
          const student = (await this.$http.get(
            "/api/ecs_core/student/getStudentInfoBySession"
          )).data;
          const specialty = (await this.$http.get(
            "/api/ecs_exam_work/exam_student/specialtyNameList/"
          )).data;
          const user = {
            ...data,
            ...student,
            specialty: specialty.join(),
            schoolDomain: this.schoolDomain,
          };
          this.updateUser(user);
          window.localStorage.setItem("user-for-reload", JSON.stringify(user));

          window._hmt.push([
            "_trackEvent",
            "登录页面",
            "登录",
            this.$route.query.LogoutReason,
          ]);
          const alreadyInExam = await this.checkExamInProgress();
          window._hmt.push(["_trackEvent", "登录页面", "登录成功"]);
          createUserLog({ action: "登录成功" });
          if (alreadyInExam) {
            this.logger({ action: "断点续考", detail: "登录页面" });
            window._hmt.push([
              "_trackEvent",
              "登录页面",
              "断点续考",
              "重新登录",
            ]);
            return;
          }
          this.$router.push("/online-exam");
          let userIds = JSON.parse(localStorage.getItem("userIds"));
          userIds = [...new Set(userIds).add(user.id)];
          localStorage.setItem("userIds", JSON.stringify(userIds));

          // 学习中心机器
          // (JSON.parse(localStorage.getItem("userIds")) || []).length > 5;

          this.$Spin.hide();
        } catch (error) {
          window._hmt.push([
            "_trackEvent",
            "登录页面",
            "登录失败",
            "getStudentInfoBySession失败",
          ]);
          this.logger({ action: "登录失败" });
          this.$Message.error({
            content: "获取学生信息失败，请重试！",
            duration: 15,
            closable: true,
          });
          if (this.isEPCC) {
            this.$Spin.hide();
            this.logout();
          }
        }
      } else {
        window._hmt.push(["_trackEvent", "登录页面", "登录失败", data.desc]);
        createLog({ currentPage: "登录页面", action: "登录失败" });
        this.errorInfo = data.desc;
      }
    },
    async checkNewVersion() {
      let myHeaders = new Headers();
      myHeaders.append("Content-Type", "application/javascript");
      myHeaders.append("Cache-Control", "no-cache");
      const response = await fetch(
        document.scripts[document.scripts.length - 1].src + "?x" + Date.now(),
        {
          method: process.env.NODE_ENV === "development" ? "GET" : "HEAD",
          headers: myHeaders,
        }
      );
      if (!response.ok || this.newVersionAvailable) {
        if (
          response.ok &&
          this.newVersionAvailable &&
          localStorage.getItem("__swReload")
        ) {
          window._hmt.push([
            "_trackEvent",
            "登录页面",
            "service worker刷新失败",
          ]);
          this.$Message.destroy();
          this.$Message.info({
            content: "请重新打开程序。",
            duration: 2 * 24 * 60 * 60,
          });
          return true;
        }
        window._hmt.push([
          "_trackEvent",
          "登录页面",
          "新版本发布后，客户端自动刷新",
        ]);
        this.$Message.info({
          content: "正在获取新版本...",
        });
        localStorage.setItem("__swReload", "anything");
        this.disableLoginBtnBecauseRefreshServiceWorker = true;
        await new Promise(resolve => {
          setTimeout(() => {
            resolve();
          }, 1000);
        });
        location.reload(true);

        return true;
      }
    },
    async checkElectronConfig() {
      try {
        const fileSever = VUE_APP_CONFIG_FILE_SEVER_URL;

        const res = await fetch(
          fileSever +
            "/org_properties/byOrgDomain/" +
            this.domainInUrl +
            "/studentClientConfig.json" +
            "?" +
            Date.now() +
            Math.random()
        );
        if (res.ok) {
          const json = await res.json();
          this.QECSConfig = json;
          this.updateQECSConfig(json);
        } else {
          this.$Message.error({
            content: "获取远程配置文件出错，请重新打开程序！",
            duration: 15,
            closable: true,
          });
          return;
        }
      } catch (e) {
        this.$Message.error({
          content: "获取远程配置文件出错，请重新打开程序！",
          duration: 15,
          closable: true,
        });
        return;
      }

      await this.checkRemoteApp();
    },
    async checkRemoteApp() {
      if (typeof nodeRequire == "undefined") {
        return;
      }

      async function checkRemoteAppTxt() {
        let applicationNames;
        try {
          const fs = window.nodeRequire("fs");
          try {
            applicationNames = fs.readFileSync(
              "remoteApplication.txt",
              "utf-8"
            );
          } catch (error) {
            console.log(error);
            window._hmt.push([
              "_trackEvent",
              "登录页面",
              "读取remoteApplication.txt出错--0",
            ]);
            await new Promise(resolve2 => setTimeout(() => resolve2(), 3000));
            applicationNames = fs.readFileSync(
              "remoteApplication.txt",
              "utf-8"
            );
          }
        } catch (error) {
          console.log(error);
          createLog({
            currentPage: "登录页面",
            errorType: "e-01",
            error: error.message,
            detail: applicationNames,
          });
          window._hmt.push([
            "_trackEvent",
            "登录页面",
            "读取remoteApplication.txt出错",
          ]);
          this.$Message.error({
            content: "系统检测出错(e-01)，请退出程序后重试！",
            duration: 2 * 24 * 60 * 60,
          });
          return;
        }
        if (applicationNames && applicationNames.trim()) {
          let names = applicationNames
            .replace("qq", "QQ")
            .replace("teamviewer", "TeamViewer")
            .replace("lookmypc", "LookMyPC")
            .replace("xt", "协通")
            .replace("winaw32", "Symantec PCAnywhere")
            .replace("pcaquickconnect", "Symantec PCAnywhere")
            .replace("sessioncontroller", "Symantec PCAnywhere")
            .replace(/sunloginclient/gi, "向日葵")
            .replace("wemeetapp", "腾讯会议");

          names = [...new Set(names.split(",").map(v => v.trim()))].join("，");
          this.disableLoginBtnBecauseRemoteApp = true;
          this.$Message.info({
            content: "在考试期间，请关掉" + names + "软件，诚信考试。",
            duration: 2 * 24 * 60 * 60,
          });
        } else {
          this.disableLoginBtnBecauseRemoteApp = false;
        }
      }
      //如果配置中配置了 DISABLE_REMOTE_ASSISTANCE
      if (
        this.QECSConfig.PREVENT_CHEATING_CONFIG.includes(
          "DISABLE_REMOTE_ASSISTANCE"
        )
      ) {
        let exe = "Project1.exe";
        if (fileExists("Project2.exe")) {
          const remoteAppName =
            "qq;teamviewer;lookmypc;xt;winaw32;pcaquickconnect;sessioncontroller;sunloginclient;wemeetapp";
          exe = `Project2.exe "${remoteAppName}" `;
        }
        await nativeExe(exe, checkRemoteAppTxt.bind(this));
      } else {
        this.disableLoginBtnBecauseRemoteApp = false;
      }
    },
    async checkVCam() {
      if (typeof nodeRequire == "undefined") {
        return;
      }

      const vcamList = [
        "17GuaGua Cam",
        "91KBOX",
        // "ASUS Virtual Camera",
        "e2eSoft iVCam",
        "e2eSoft VCam",
        "FaceRig Virtual Camera",
        // "Lenovo Virtual Camera",
        "MagicCamera Capture",
        "MeiSe",
        "Virtual Cam",
        "YY伴侣",
        "WebcamMax Capture",
        "Wecam",
        "Vcam ",
        "softcam",
        "Vandate Virtual Camera",
        "video2webcam",
        "VCDCut Pro",
        "9158虚拟视频",
        "9158Capture",
        "Insta360 Virtual Camera",
        "无他直播伴侣PC客户端",
        "无他相机电脑版",
        "mobiola webcamera",
        "艾米秀宝(ImiShowBox)",
        "video2Webcam",
        "飞翔虚拟视频",
        "魔力秀",
      ];

      async function checkVCamTxt() {
        let applicationNames;
        try {
          const fs = window.nodeRequire("fs");
          try {
            applicationNames = fs.readFileSync("CameraInfo.txt", "utf-8");
          } catch (error) {
            console.log(error);
            window._hmt.push([
              "_trackEvent",
              "登录页面",
              "CameraInfo.txt出错--0",
            ]);
            await new Promise(resolve2 => setTimeout(() => resolve2(), 3000));
            applicationNames = fs.readFileSync("CameraInfo.txt", "utf-8");
          }
        } catch (error) {
          console.log(error);
          createLog({
            currentPage: "登录页面",
            errorType: "e-02",
            error: error.message,
            detail: applicationNames,
          });
          window._hmt.push([
            "_trackEvent",
            "登录页面",
            "读取CameraInfo.txt出错",
          ]);
          this.$Message.error({
            content: "系统检测出错(e-02)，请退出程序后重试！",
            duration: 2 * 24 * 60 * 60,
          });
          return;
        }
        this.disableLoginBtnBecauseVCam = false;
        if (applicationNames && applicationNames.trim()) {
          for (const vc of vcamList) {
            if (applicationNames.toUpperCase().includes(vc.toUpperCase())) {
              this.disableLoginBtnBecauseVCam = true;
              this.$Message.info({
                content:
                  "在考试期间，请关掉" + "虚拟摄像头" + "软件，诚信考试。",
                duration: 2 * 24 * 60 * 60,
              });
              console.log(applicationNames);
            }
          }
        }
      }
      //如果配置中配置了 DISABLE_VIRTUAL_CAMERA
      if (
        this.QECSConfig.PREVENT_CHEATING_CONFIG.includes(
          "DISABLE_VIRTUAL_CAMERA"
        )
      ) {
        await nativeExe("multiCamera.exe", checkVCamTxt.bind(this));
      } else {
        this.disableLoginBtnBecauseVCam = false;
      }
    },
    async checkAllowedClient() {
      if (process.env.VUE_APP_SKIP_CHECK_NATIVE === "true") {
        console.log(
          "环境检查: process.env.VUE_APP_SKIP_CHECK_NATIVE === " +
            process.env.VUE_APP_SKIP_CHECK_NATIVE,
          " 允许浏览器访问"
        );
        this.disableLoginBtnBecauseNotAllowedNative = false;
        return;
      }
      // if (!this.FE_FEATURE_ALLOW_CHECK) {
      //   this.disableLoginBtnBecauseNotAllowedNative = false;
      //   return;
      // }
      /**
       * 本应用仅处理学生端的请求。不做跳转，不管浏览器类型。
       * 允许NATIVE/允许BROWSER，在以下场景中能访问：学生端/移动端浏览器
       */
      // if (
      //   this.QECSConfig.LOGIN_SUPPORT.includes("BROWSER") &&
      //   this.QECSConfig.LOGIN_SUPPORT.includes("NATIVE")
      // ) {
      //   // FIXME: 暂时允许选择浏览器的可以在浏览器中访问
      //   this.disableLoginBtnBecauseNotAllowedNative = false;
      //   return;
      // } else
      if (this.QECSConfig.LOGIN_SUPPORT.includes("NATIVE")) {
        // 检测是否是学生端。 检测是否有node。检测是否能node调用。
        const hasShell = UA.getBrowser().name === "electron-exam-shell";
        const hasNode = typeof nodeRequire !== "undefined";
        let hasFs = false;
        let hasReadFileSync = false;
        if (hasShell && hasNode) {
          const fs = window.nodeRequire("fs");
          if (fs && typeof fs.readFileSync === "function") {
            hasFs = true;
            hasReadFileSync = true;
            this.disableLoginBtnBecauseNotAllowedNative = false;
          }
        }
        if (this.disableLoginBtnBecauseNotAllowedNative) {
          window._hmt.push([
            "_trackEvent",
            "登录页面",
            "不允许访问-" +
              JSON.stringify({
                hasShell,
                hasNode,
                hasFs,
                hasReadFileSync,
              }),
          ]);
          this.$Message.error({
            content: "请与学校申请最新的客户端，进行考试！",
            duration: 2 * 24 * 60 * 60,
          });
        }
        // } else if (this.QECSConfig.LOGIN_SUPPORT.includes("BROWSER")) {
        //   const hasShell = UA.getBrowser().name === "electron-exam-shell";
        //   if (hasShell) {
        //     if (this.disableLoginBtnBecauseNotAllowedNative) {
        //       window._hmt.push([
        //         "_trackEvent",
        //         "登录页面",
        //         "不允许访问-不允许在考生端中访问只设定移动端浏览器访问的设置",
        //       ]);
        //       this.$Message.error({
        //         content: "本考试不支持在考生端中进行！",
        //         duration: 2 * 24 * 60 * 60,
        //       });
        //     }
        //   }
        //   // TODO: redirect to wap site
        //   // if(chromeUA.major < "66") { } // 到移动端去判断
        //   return;
      } else {
        this.$Message.error({
          content: "本考试不支持在考生端中进行！",
          duration: 2 * 24 * 60 * 60,
        });
      }
    },
    closeApp() {
      console.log("关闭应用");
      window.close();
    },
    examShellStats() {
      const shellVersion = window.navigator.userAgent
        .split(" ")
        .find(v => v.startsWith("electron-exam-shell/"));
      const chromeVersion = window.navigator.userAgent
        .split(" ")
        .find(v => v.startsWith("Chrome/"));
      if (shellVersion) {
        window._hmt.push([
          "_trackEvent",
          "登录页面",
          "学生端版本",
          shellVersion + "/" + chromeVersion,
        ]);
      } else {
        if (chromeVersion) {
          window._hmt.push([
            "_trackEvent",
            "登录页面",
            "学生端版本/chrome",
            chromeVersion,
          ]);
        } else {
          window._hmt.push([
            "_trackEvent",
            "登录页面",
            "学生端版本/其他浏览器",
            window.navigator.userAgent,
          ]);
        }
      }
    },
    async epccLogin() {
      const {
        accountType,
        accountValue,
        rootOrgId,
        appId,
        timestamp,
        token,
        redirectUrl,
      } = this.$route.query;

      if (
        accountType &&
        accountValue &&
        rootOrgId &&
        appId &&
        timestamp &&
        token &&
        redirectUrl
      ) {
        try {
          const response = await this.$http.post(
            "/api/ecs_core/auth/thirdPartyStudentAccess" + location.search
          );
          return response;
        } catch (error) {
          window._hmt.push(["_trackEvent", "第三方登录页面", "接口出错", ""]);
          this.$Spin.hide();
          this.logout();
        }
      } else {
        this.$Spin.hide();
        this.logout();
      }
    },
  },
};
</script>

<style scoped>
.home {
  display: flex;
  flex-direction: column;
  height: 100vh;
}

.school-logo {
  justify-self: flex-start;
  margin-left: 100px;
}

.logo-size {
  height: 100px;
  width: 400px;
  object-fit: cover;
}

.header {
  min-height: 120px;
  display: grid;
  align-items: center;
  justify-items: center;
}

.center {
  background-image: url("https://cdn.qmth.com.cn/ui/ecs-client-bg.jpg!/progressive/true");
  background-position: center;
  background-repeat: no-repeat;
  background-size: cover;
  width: 100vw;
  min-height: 600px;
}

.content {
  margin-top: 100px;
  margin-left: 65%;
  width: 300px;
  border-radius: 6px;
  background-color: white;
  display: grid;
  grid-template-areas: "";
}

.login-type {
  flex: 1;
  line-height: 40px;
  background-color: #eeeeee;
}

.active-type {
  background-color: #ffffff;
}
.single-login-type {
  border-top-left-radius: 6px;
  border-top-right-radius: 6px;
}

.close {
  position: absolute;
  top: 0;
  right: 0;
  background-color: #eeeeee;
  color: #999999;
  width: 80px;
  height: 40px;
  line-height: 40px;
}

.close:hover {
  color: #444444;
}

.footer {
  position: relative;
}
</style>

<style>
.ivu-message-notice-content-text {
  font-size: 32px;
}
.ivu-message-notice-content-text i.ivu-icon {
  font-size: 32px;
}
</style>
