123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119 |
- <template>
- <div class="remain-time">剩余时间 {{ remainTimeFormatted }}</div>
- </template>
- <script>
- import moment from "moment";
- import { createNamespacedHelpers } from "vuex";
- const { mapMutations } = createNamespacedHelpers("examingHomeModule");
- export default {
- name: "RemainTime",
- data() {
- return {
- remainTime: null
- };
- },
- async mounted() {
- this.heartbeatErrorNum = 0;
- this.getRemainTimeFromServer();
- this.heartbeatInterval = setInterval(() => {
- this.getRemainTimeFromServer();
- }, 60 * 1000);
- this.remainTimeInterval = setInterval(() => {
- if (this.remainTime > 0) {
- this.remainTime = this.remainTime - 1000;
- }
- }, 1000);
- },
- beforeDestroy() {
- this.clearIntervals();
- },
- methods: {
- ...mapMutations(["setShouldSubmitPaper", "updateRemainTime"]),
- async getRemainTimeFromServer() {
- if (this.$route.name !== "OnlineExamingHome") {
- // 非考试页,不继续发心跳。可能退出后再进,导致心跳多发一次。可能会话已过期。
- return;
- }
- try {
- const res = await this.$http.get(
- "/api/ecs_oe_student/examControl/examHeartbeat"
- );
- if (/\d+/.test(res.data)) {
- if (res.data <= 0) {
- this.setShouldSubmitPaper();
- }
- if (this.remainTime === null) {
- // 仅当剩余考试时间没有被初始化才使用服务器时间。否则使用本机时间。
- this.remainTime = res.data;
- }
- this.heartbeatErrorNum = 0;
- } else {
- this.$Message.error("服务器返回的心跳结果不是数字");
- }
- } catch (error) {
- if (
- error.response &&
- error.response.data &&
- error.response.data.desc &&
- error.response.data.desc.includes("会话已过期,请离开考试")
- ) {
- window._hmt.push([
- "_trackEvent",
- "正在考试页面",
- "心跳",
- "失败-会话过期"
- ]);
- this.serverLog(
- "debug/S-008002",
- `心跳失败-会话过期 => 考试剩余时间:${this.remainTime / 1000}`
- );
- } else {
- window._hmt.push(["_trackEvent", "正在考试页面", "心跳", "失败"]);
- this.serverLog(
- "debug/S-008003",
- `心跳失败 => 考试剩余时间:${this.remainTime / 1000} => ${error}`
- );
- }
- this.heartbeatErrorNum++;
- if (this.heartbeatErrorNum >= 10) {
- // 心跳异常10次则退出考试
- clearInterval(this.heartbeatInterval);
- clearInterval(this.remainTimeInterval);
- this.$Modal.error({
- title: "网络连接异常",
- content: "退出考试",
- onOk: () => {
- this.$router.push("/login/" + localStorage.getItem("domain"));
- }
- });
- return;
- }
- this.retryHeartbeatTimeout = setTimeout(
- () => this.getRemainTimeFromServer(),
- 10 * 1000
- );
- }
- },
- clearIntervals() {
- clearInterval(this.heartbeatInterval);
- clearInterval(this.remainTimeInterval);
- clearTimeout(this.retryHeartbeatTimeout);
- }
- },
- computed: {
- remainTimeFormatted: function() {
- return moment.utc(this.remainTime).format("HH:mm:ss");
- }
- },
- watch: {
- remainTime(val) {
- if (val !== null && val === 0) {
- this.setShouldSubmitPaper();
- }
- this.updateRemainTime(val);
- }
- }
- };
- </script>
|