Parcourir la source

前端:登录login检测虚拟摄像头;重构调用exe的方法

Michael Wang il y a 5 ans
Parent
commit
18f837b2f9
2 fichiers modifiés avec 146 ajouts et 88 suppressions
  1. 135 88
      src/features/Login/Login.vue
  2. 11 0
      src/utils/nativeExe.js

+ 135 - 88
src/features/Login/Login.vue

@@ -116,6 +116,7 @@ import moment from "moment";
 import { mapMutations } from "vuex";
 import { FACE_API_MODEL_PATH } from "@/constants/constants";
 import DevTools from "./DevTools.vue";
+import nativeExe from "@/utils/nativeExe";
 /**
  * 在任何组件需要强制退出,做以下步骤
  * 1. this.$Message.info()
@@ -152,8 +153,11 @@ export default {
           },
         ],
       },
-      disableLoginBtn: true,
       loginBtnLoading: false,
+      isElectron: true,
+      disableLoginBtnBecauseRemoteApp: true,
+      disableLoginBtnBecauseVCam: true,
+      disableLoginBtnBecauseNoRemoteAppChecker: false,
       newVersionAvailable: false,
       VUE_APP_GIT_REPO_VERSION: process.env.VUE_APP_GIT_REPO_VERSION,
     };
@@ -188,6 +192,8 @@ export default {
     }, 1000);
   },
   async created() {
+    this.isElectron = typeof nodeRequire != "undefined";
+
     if (
       navigator.userAgent.indexOf("WOW64") != -1 ||
       navigator.userAgent.indexOf("Win64") != -1
@@ -222,21 +228,24 @@ export default {
         "swjtu.ecs.qmth.com.cn",
       ].includes(this.$route.params.domain)
     ) {
-      this.disableLoginBtn = true;
       if (
         typeof nodeRequire == "undefined" ||
         !window.nodeRequire("fs").existsSync("multiCamera.exe")
       ) {
+        this.disableLoginBtnBecauseNoRemoteAppChecker = true;
         this.$Message.error({
           content: "请与学校申请最新的客户端,进行考试!",
           duration: 2 * 24 * 60 * 60,
         });
-
-        return; // 避免 disableLoginBtn 被覆盖
       }
     }
 
-    this.checkElectronConfig();
+    await this.checkElectronConfig();
+    await this.checkVCam();
+
+    if (this.allowLoginType === "IDENTITY_NUMBER") {
+      this.loginType = "STUDENT_IDENTITY_NUMBER";
+    }
   },
   beforeDestroy() {
     clearTimeout(this.loginTimeout);
@@ -248,18 +257,14 @@ export default {
       if (this.disableLoginBtn) {
         return;
       }
-      this.disableLoginBtn = true;
-      await this.checkNewVersion();
       this.loginBtnLoading = true;
+      await this.checkNewVersion();
       this.loginTimeout = setTimeout(() => {
-        this.disableLoginBtn = false;
         this.loginBtnLoading = false;
       }, 10 * 1000);
       // https://www.cnblogs.com/weiqinl/p/6708993.html
       const valid = await this.$refs.loginForm.validate();
-      if (valid) {
-        console.log("form validated. start login...");
-      } else {
+      if (!valid) {
         return;
       }
 
@@ -438,99 +443,133 @@ export default {
       }
     },
     async checkElectronConfig() {
-      if (typeof nodeRequire != "undefined") {
-        this.checkQECSConfigTimes = this.checkQECSConfigTimes || 1;
-        if (this.checkQECSConfigTimes >= 10) {
+      try {
+        const fileSever =
+          location.hostname === "ecs.qmth.com.cn"
+            ? "https://ecs-static.qmth.com.cn"
+            : "https://ecs-test-static.qmth.com.cn";
+
+        const res = await fetch(
+          fileSever +
+            "/org_properties/byOrgDomain/" +
+            this.domainInUrl +
+            "/studentClientConfig.json"
+        );
+        if (res.ok) {
+          const json = await res.json();
+          this.QECSConfig = json;
+        } else {
           this.$Message.error({
-            content: "解析本地配置文件出错,请重新打开程序或联系老师!",
+            content: "获取远程配置文件出错,请重新刷新网页!",
             duration: 15,
             closable: true,
           });
           return;
         }
-        if (!window.QECSConfig) {
-          this.checkQECSConfigTimes++;
-          setTimeout(() => {
-            this.checkElectronConfig();
-          }, 1000);
+      } catch (e) {
+        this.$Message.error({
+          content: "获取远程配置文件出错,请重新刷新网页!",
+          duration: 15,
+          closable: true,
+        });
+        return;
+      }
+
+      await this.checkRemoteApp();
+    },
+    async checkRemoteApp() {
+      if (typeof nodeRequire == "undefined") {
+        return;
+      }
+
+      function checkRemoteAppTxt() {
+        let applicationNames;
+        try {
+          const fs = window.nodeRequire("fs");
+          applicationNames = fs.readFileSync("remoteApplication.txt", "utf-8");
+        } catch (error) {
+          this.$Message.error({
+            content: "系统检测出错,请退出程序后重试!",
+            duration: 2 * 24 * 60 * 60,
+          });
           return;
         }
-        this.QECSConfig = window.QECSConfig;
-
-        var that = this;
-        var fs = window.nodeRequire("fs");
-
-        //如果配置中配置了  checkRemoteControl:true
-        if (
-          window.QECSConfig.PREVENT_CHEATING_CONFIG.includes[
-            "DISABLE_REMOTE_ASSISTANCE"
-          ]
-        ) {
-          window.nodeRequire("node-cmd").get("Project1.exe", function() {
-            var applicationNames;
-            try {
-              applicationNames = fs.readFileSync(
-                "remoteApplication.txt",
-                "utf-8"
-              );
-            } catch (error) {
-              that.$Message.error({
-                content: "系统检测出错,请退出程序后重试!",
-                duration: 2 * 24 * 60 * 60,
-              });
-              return;
-            }
-            if (applicationNames && applicationNames.trim()) {
-              that.disableLoginBtn = true;
-              that.$Message.info({
-                content:
-                  "在考试期间,请关掉" +
-                  applicationNames.trim() +
-                  "软件,诚信考试。",
-                duration: 2 * 24 * 60 * 60,
-              });
-            } else {
-              that.disableLoginBtn = false;
-            }
+        if (applicationNames && applicationNames.trim()) {
+          this.disableLoginBtnBecauseRemoteApp = true;
+          this.$Message.info({
+            content:
+              "在考试期间,请关掉" +
+              applicationNames.trim() +
+              "软件,诚信考试。",
+            duration: 2 * 24 * 60 * 60,
           });
         } else {
-          that.disableLoginBtn = false;
+          this.disableLoginBtnBecauseRemoteApp = false;
         }
-      } else {
-        this.disableLoginBtn = false;
+      }
+      //如果配置中配置了 DISABLE_REMOTE_ASSISTANCE
+      if (
+        this.QECSConfig.PREVENT_CHEATING_CONFIG.includes[
+          "DISABLE_REMOTE_ASSISTANCE"
+        ]
+      ) {
+        await nativeExe("Project1.exe", checkRemoteAppTxt.bind(this));
+      }
+    },
+    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伴侣",
+      ];
+
+      function checkVCamTxt() {
+        let applicationNames;
         try {
-          const fileSever =
-            location.hostname === "ecs.qmth.com.cn"
-              ? "https://ecs-static.qmth.com.cn"
-              : "https://ecs-test-static.qmth.com.cn";
-
-          const res = await fetch(
-            fileSever +
-              "/org_properties/byOrgDomain/" +
-              this.domainInUrl +
-              "/studentClientConfig.json"
-          );
-          if (res.ok) {
-            const json = await res.json();
-            this.QECSConfig = json;
-          } else {
-            this.$Message.error({
-              content: "获取远程配置文件出错,请重新刷新网页!",
-              duration: 15,
-              closable: true,
-            });
-          }
-        } catch (e) {
+          const fs = window.nodeRequire("fs");
+          applicationNames = fs.readFileSync("CameraInfo.txt", "utf-8");
+        } catch (error) {
           this.$Message.error({
-            content: "获取远程配置文件出错,请重新刷新网页!",
-            duration: 15,
-            closable: true,
+            content: "系统检测出错,请退出程序后重试!",
+            duration: 2 * 24 * 60 * 60,
           });
+          return;
+        }
+        if (applicationNames && applicationNames.trim()) {
+          for (const vc of vcamList) {
+            if (applicationNames.includes(vc)) {
+              this.disableLoginBtnBecauseVCam = true;
+              this.$Message.info({
+                content:
+                  "在考试期间,请关掉" + "虚拟摄像头" + "软件,诚信考试。",
+                duration: 2 * 24 * 60 * 60,
+              });
+              console.log(applicationNames);
+            }
+          }
+        } else {
+          this.disableLoginBtnBecauseVCam = false;
         }
       }
-
-      if (this.allowLoginType === "IDENTITY_NUMBER") {
-        this.loginType = "STUDENT_IDENTITY_NUMBER";
+      //如果配置中配置了 DISABLE_VIRTUAL_CAMERA
+      if (
+        this.QECSConfig.PREVENT_CHEATING_CONFIG.includes[
+          "DISABLE_VIRTUAL_CAMERA"
+        ]
+      ) {
+        await nativeExe("multiCamera.exe", checkVCamTxt.bind(this));
       }
     },
     closeApp() {
@@ -575,6 +614,14 @@ export default {
         return "初始密码为身份证号后6位";
       }
     },
+    disableLoginBtn() {
+      return (
+        this.isElectron &&
+        (this.disableLoginBtnBecauseRemoteApp ||
+          this.disableLoginBtnBecauseVCam ||
+          this.disableLoginBtnBecauseNoRemoteAppChecker)
+      );
+    },
   },
   components: {
     DevTools,

+ 11 - 0
src/utils/nativeExe.js

@@ -0,0 +1,11 @@
+export default function async(exeName, cb) {
+  if (typeof nodeRequire == "undefined") {
+    throw "不在Electron中,调用 " + exeName + " 失败";
+  }
+  return new Promise(resolve => {
+    window.nodeRequire("node-cmd").get(exeName, async () => {
+      await cb();
+      resolve();
+    });
+  });
+}