فهرست منبع

epcc 客户端开考限流

Michael Wang 5 سال پیش
والد
کامیت
cde129d9ea
1فایلهای تغییر یافته به همراه75 افزوده شده و 4 حذف شده
  1. 75 4
      src/features/OnlineExam/OnlineExamList.vue

+ 75 - 4
src/features/OnlineExam/OnlineExamList.vue

@@ -28,12 +28,18 @@
             >
               <i-button
                 class="qm-primary-button qm-primary-button-padding-fix"
-                :disabled="
-                  !courseInBetween(course) || course.allowExamCount < 1
+                :disabled="disableTheCourse(course)"
+                @click="
+                  () => {
+                    if (isEpcc) {
+                      raceEnter(course);
+                    } else {
+                      enterExam(course);
+                    }
+                  }
                 "
-                @click="enterExam(course)"
               >
-                进入考试
+                进入考试{{ isEpcc && countdown > 0 ? `(${countdown})` : "" }}
               </i-button>
               <i-poptip
                 v-if="!isEpcc"
@@ -120,6 +126,7 @@ export default {
       processingMessage: "",
       cid: null,
       shouldShowCheckEnvModal: false,
+      countdown: 0,
     };
   },
   computed: {
@@ -134,6 +141,7 @@ export default {
   beforeDestroy() {
     this.toggleFaceCheckModal(false);
     clearInterval(this.intervalID);
+    clearInterval(this.countdownInterval);
   },
   methods: {
     ...mapMutations(["toggleFaceCheckModal"]),
@@ -146,6 +154,69 @@ export default {
         moment(course.endTime)
       );
     },
+    disableTheCourse(course) {
+      return (
+        !this.courseInBetween(course) ||
+        course.allowExamCount < 1 ||
+        (this.isEpcc && this.countdown > 0)
+      );
+    },
+    raceEnter(course) {
+      const successRatePerMinute = [
+        0.1,
+        0.15,
+        0.2,
+        0.25,
+        0.3,
+        0.35,
+        0.4,
+        0.45,
+        0.5,
+        0.6,
+        0.7,
+        0.8,
+        0.9,
+        1,
+      ]; // 30秒步进
+      const minutesAfterCourseStart = Math.floor(
+        moment(this.getNow()).diff(moment(course.startTime), "seconds") / 30
+      );
+      let idx = 0;
+      if (minutesAfterCourseStart < 0) {
+        idx = 0;
+      } else if (
+        minutesAfterCourseStart >= 0 &&
+        minutesAfterCourseStart < successRatePerMinute.length
+      ) {
+        idx = minutesAfterCourseStart;
+      } else {
+        idx = successRatePerMinute.length - 1;
+      }
+      if (Math.random() > 1 - successRatePerMinute[idx]) {
+        this.enterExam(course);
+        // return true;
+      } else {
+        this.$Modal.warning({
+          title: "提示",
+          content: "考试人员过多,请稍等2分钟再试。",
+          onOk: () => {
+            clearInterval(this.countdownInterval);
+            this.countdown = 10;
+            this.countdownInterval = setInterval(() => {
+              this.countdown--;
+            }, 1 * 1000);
+            // this.enterExam(course);
+          },
+        });
+        // this.$Message.warning({
+        //   content: "考试人员过多,请稍等2分钟再试",
+        //   duration: 10,
+        //   closable: true,
+        // });
+
+        // return false;
+      }
+    },
     async enterExam(course, alreadyChecked) {
       this.spinShow = true;
       this.processingMessage = "正在检测断点续考信息...";