zhangjie преди 4 години
родител
ревизия
4c1b2ff72e
променени са 34 файла, в които са добавени 197 реда и са изтрити 101 реда
  1. 1 0
      .gitignore
  2. 10 0
      dev-proxy.copy.js
  3. 4 0
      src/api/invigilation.js
  4. 2 2
      src/constant/constants.js
  5. 18 1
      src/features/Login/Login.vue
  6. 8 2
      src/features/invigilation/ExamInvigilation/ExamInvigilation.vue
  7. 1 1
      src/features/invigilation/ExamReport/BreachDetailDialog.vue
  8. 1 1
      src/features/invigilation/ExamReport/ExceptionDetailDialog.vue
  9. 1 1
      src/features/invigilation/ExamReport/ReportAbsent.vue
  10. 1 1
      src/features/invigilation/ExamReport/ReportBreach.vue
  11. 1 1
      src/features/invigilation/ExamReport/ReportCancalBreach.vue
  12. 2 2
      src/features/invigilation/ExamReport/ReportException.vue
  13. 1 1
      src/features/invigilation/ExamReport/ReportReexam.vue
  14. 1 1
      src/features/invigilation/ExamReport/ReportStatistics.vue
  15. 2 3
      src/features/invigilation/InvigilationDetail/InvigilationDetail.vue
  16. 1 1
      src/features/invigilation/OnlinePatrol/OnlinePatrol.vue
  17. 8 5
      src/features/invigilation/OnlinePatrol/PatrolWarningDetail.vue
  18. 1 1
      src/features/invigilation/ProgressDetail/ProgressDetail.vue
  19. 3 2
      src/features/invigilation/RealtimeMonitoring/ExamBatchDialog.vue
  20. 43 36
      src/features/invigilation/RealtimeMonitoring/RealtimeMonitoring.vue
  21. 2 3
      src/features/invigilation/RealtimeMonitoring/VideoCommunication.vue
  22. 49 10
      src/features/invigilation/RealtimeMonitoring/WarningDetail.vue
  23. 2 2
      src/features/invigilation/ReexamApply/ReexamApply.vue
  24. 2 2
      src/features/invigilation/ReexamChecked/ReexamChecked.vue
  25. 2 2
      src/features/invigilation/ReexamPending/ReexamPending.vue
  26. 1 1
      src/features/invigilation/StudentLogManage/StudentLogDetailDialog.vue
  27. 2 2
      src/features/invigilation/StudentLogManage/StudentLogManage.vue
  28. 3 9
      src/features/invigilation/WarningManage/WarningManage.vue
  29. 3 3
      src/features/invigilation/common/InvigilationStudent.vue
  30. 0 1
      src/features/invigilation/common/SummaryLine.vue
  31. 9 0
      src/store/modules/invigilation.js
  32. 2 1
      src/styles/base.scss
  33. 1 1
      src/views/Layout/components/AppFooter.vue
  34. 9 2
      vue.config.js

+ 1 - 0
.gitignore

@@ -1,6 +1,7 @@
 .DS_Store
 node_modules
 /dist
+dev-proxy.js
 
 # local env files
 .env.local

+ 10 - 0
dev-proxy.copy.js

@@ -0,0 +1,10 @@
+module.exports = {
+  "/api": {
+    target: "http://192.168.10.36:9222/",
+    changeOrigin: true,
+  },
+  "/file": {
+    target: "http://192.168.10.36:9222/",
+    changeOrigin: true,
+  },
+};

+ 4 - 0
src/api/invigilation.js

@@ -11,6 +11,10 @@ export function getUserMonitorKey(recordId) {
     {}
   );
 }
+// live url domain
+export function getLiveDomains() {
+  return httpApp.post("/api/admin/sys/getPlayUrls", {});
+}
 // exam-invigilation
 export function examInvigilationCount() {
   return httpApp.post("/api/admin/report/examination_monitor/count", {});

+ 2 - 2
src/constant/constants.js

@@ -30,9 +30,9 @@ export const BOOLEAN_INVERSE_TYPE = {
 };
 // 考生在线状态
 export const STUDENT_ONLINE_STATUS = {
-  FIRST_PREPARE: "待考",
+  FIRST_PREPARE: "待考",
   EXAMING: "考试中",
-  BREAK_OFF: "异常",
+  BREAK_OFF: "通讯故障",
 };
 // 推流通讯
 export const STUDENT_EXAM_STATUS = {

+ 18 - 1
src/features/Login/Login.vue

@@ -85,7 +85,11 @@
         </div>
       </div>
     </div>
-    <div class="footer">Copyright © www.qmth.com.cn, All Rights Reserved.</div>
+    <div class="footer">
+      Copyright ©
+      <a href="http://www.qmth.com.cn" target="_blank">www.qmth.com.cn</a>, All
+      Rights Reserved.
+    </div>
   </div>
 </template>
 
@@ -126,6 +130,16 @@ export default {
             });
             // console.log(res);
             // localStorage.setItem("themis-user", res.data);
+
+            const user = this.$store.state.user;
+            const needLiveUrl =
+              user.roleCodes.includes("SUPER_ADMIN") ||
+              user.roleCodes.includes("ADMIN") ||
+              user.roleCodes.includes("INSPECTION") ||
+              user.roleCodes.includes("INVIGILATE");
+            if (needLiveUrl)
+              await this.$store.dispatch("invigilation/fetchLiveDomains");
+
             this.$message({
               message: "登录成功",
               type: "success",
@@ -292,6 +306,9 @@ export default {
   text-align: center;
   width: 100%;
   color: #fff;
+  a {
+    color: #fff;
+  }
 }
 </style>
 <style lang="scss">

+ 8 - 2
src/features/invigilation/ExamInvigilation/ExamInvigilation.vue

@@ -253,6 +253,7 @@ import {
   examInvigilationVideoRandomList,
   examInvigilationWarnMessage,
 } from "@/api/invigilation";
+import { mapState } from "vuex";
 
 export default {
   name: "exam-invigilation",
@@ -291,6 +292,7 @@ export default {
     };
   },
   computed: {
+    ...mapState("invigilation", ["liveDomains"]),
     isFullScreen() {
       return this.$store.state.isFullScreen;
     },
@@ -372,8 +374,12 @@ export default {
     },
     async getVideoList() {
       const res = await examInvigilationVideoRandomList({ randomNum: 4 });
-      this.students = res.data.data.map((item) => {
-        item.liveUrl = `http://live.qmth.com.cn/live/${item.monitorLiveUrl.toLowerCase()}.flv`;
+      const domainLen = this.liveDomains.length;
+      this.students = res.data.data.map((item, index) => {
+        const domain = domainLen ? this.liveDomains[index % domainLen] : "";
+        item.liveUrl = item.monitorLiveUrl
+          ? `${domain}/live/${item.monitorLiveUrl.toLowerCase()}.flv`
+          : "";
         return item;
       });
     },

+ 1 - 1
src/features/invigilation/ExamReport/BreachDetailDialog.vue

@@ -29,7 +29,7 @@
         layout="prev, pager, next,total,sizes,jumper"
         :current-page="current"
         :total="total"
-        :page-size="size"
+        :page-size.sync="size"
         @size-change="toPage(1)"
         @current-change="toPage"
       >

+ 1 - 1
src/features/invigilation/ExamReport/ExceptionDetailDialog.vue

@@ -31,7 +31,7 @@
         layout="prev, pager, next,total,sizes,jumper"
         :current-page="current"
         :total="total"
-        :page-size="size"
+        :page-size.sync="size"
         @size-change="toPage(1)"
         @current-change="toPage"
       >

+ 1 - 1
src/features/invigilation/ExamReport/ReportAbsent.vue

@@ -23,7 +23,7 @@
         layout="prev, pager, next,total,sizes,jumper"
         :current-page="current"
         :total="total"
-        :page-size="size"
+        :page-size.sync="size"
         @size-change="toPage(1)"
         @current-change="toPage"
       >

+ 1 - 1
src/features/invigilation/ExamReport/ReportBreach.vue

@@ -41,7 +41,7 @@
         layout="prev, pager, next,total,sizes,jumper"
         :current-page="current"
         :total="total"
-        :page-size="size"
+        :page-size.sync="size"
         @size-change="toPage(1)"
         @current-change="toPage"
       >

+ 1 - 1
src/features/invigilation/ExamReport/ReportCancalBreach.vue

@@ -41,7 +41,7 @@
         layout="prev, pager, next,total,sizes,jumper"
         :current-page="current"
         :total="total"
-        :page-size="size"
+        :page-size.sync="size"
         @size-change="toPage(1)"
         @current-change="toPage"
       >

+ 2 - 2
src/features/invigilation/ExamReport/ReportException.vue

@@ -19,7 +19,7 @@
       <el-table-column prop="exceptionCount" label="次数"></el-table-column>
       <el-table-column
         prop="exceptionTotalTime"
-        label="累积持续时长(单位:分钟)"
+        label="累积持续时长(单位:分钟)"
       ></el-table-column>
       <el-table-column label="操作">
         <template slot-scope="scope">
@@ -39,7 +39,7 @@
         layout="prev, pager, next,total,sizes,jumper"
         :current-page="current"
         :total="total"
-        :page-size="size"
+        :page-size.sync="size"
         @size-change="toPage(1)"
         @current-change="toPage"
       >

+ 1 - 1
src/features/invigilation/ExamReport/ReportReexam.vue

@@ -23,7 +23,7 @@
         layout="prev, pager, next,total,sizes,jumper"
         :current-page="current"
         :total="total"
-        :page-size="size"
+        :page-size.sync="size"
         @size-change="toPage(1)"
         @current-change="toPage"
       >

+ 1 - 1
src/features/invigilation/ExamReport/ReportStatistics.vue

@@ -37,7 +37,7 @@
         layout="prev, pager, next,total,sizes,jumper"
         :current-page="current"
         :total="total"
-        :page-size="size"
+        :page-size.sync="size"
         @size-change="toPage(1)"
         @current-change="toPage"
       >

+ 2 - 3
src/features/invigilation/InvigilationDetail/InvigilationDetail.vue

@@ -172,7 +172,6 @@
           class="part-filter-info-main"
           data-type="complete"
           :exam-id="filter.examId"
-          v-if="filter.examId"
         ></summary-line>
       </div>
     </div>
@@ -206,7 +205,7 @@
           </span>
         </template>
       </el-table-column>
-      <el-table-column label="操作">
+      <el-table-column label="操作" width="100" fixed="right">
         <template slot-scope="scope">
           <el-button
             class="btn-table-icon"
@@ -224,7 +223,7 @@
         layout="prev, pager, next,total,sizes,jumper"
         :current-page="current"
         :total="total"
-        :page-size="size"
+        :page-size.sync="size"
         @size-change="toPage(1)"
         @current-change="toPage"
       >

+ 1 - 1
src/features/invigilation/OnlinePatrol/OnlinePatrol.vue

@@ -198,7 +198,7 @@
         layout="prev, pager, next,total,sizes,jumper"
         :current-page="current"
         :total="total"
-        :page-size="size"
+        :page-size.sync="size"
         @size-change="toPage(1)"
         @current-change="toPage"
       >

+ 8 - 5
src/features/invigilation/OnlinePatrol/PatrolWarningDetail.vue

@@ -203,7 +203,7 @@ export default {
     };
   },
   computed: {
-    ...mapState("invigilation", ["detailIds"]),
+    ...mapState("invigilation", ["detailIds", "liveDomains"]),
   },
   watch: {
     $route: {
@@ -224,12 +224,15 @@ export default {
     },
     async getStudentVideo() {
       const res = await warningStudentDetail({ recordId: this.recordId });
-      const records = res.data.data.map((item) => {
-        item.src = `http://live.qmth.com.cn/live/${item.liveUrl.toLowerCase()}.flv`;
+      const records = res.data.data.map((item, index) => {
+        const domain = this.liveDomains[index] || "";
+        item.liveUrl = item.liveUrl
+          ? `${domain}/live/${item.liveUrl.toLowerCase()}.flv`
+          : "";
         item.name = item.source;
         return item;
       });
-      console.log(records.map((item) => item.src));
+      console.log(records.map((item) => item.liveUrl));
       this.firstViewVideo = records[0] || {};
       this.secondViewVideo = records[2] || {};
 
@@ -333,7 +336,7 @@ export default {
       console.log(this.detailIds[index]);
 
       this.$router.replace({
-        name: "WarningDetail",
+        name: "PatrolWarningDetail",
         params: {
           recordId: this.detailIds[index],
         },

+ 1 - 1
src/features/invigilation/ProgressDetail/ProgressDetail.vue

@@ -111,7 +111,7 @@
         layout="prev, pager, next,total,sizes,jumper"
         :current-page="current"
         :total="total"
-        :page-size="size"
+        :page-size.sync="size"
         @size-change="toPage(1)"
         @current-change="toPage"
       >

+ 3 - 2
src/features/invigilation/RealtimeMonitoring/ExamBatchDialog.vue

@@ -64,10 +64,11 @@ export default {
           (item) => item.id === this.initExamid
         );
       } else {
-        // 优先取当前第一个正在考试的考试,没有则取记录第一条数据
+        // 优先取当前第一个正在考试的考试
         selectedExam = this.examBatchs.find((item) => item.isExaming);
-        selectedExam = selectedExam || this.examBatchs[0];
       }
+      // 默认记录没有时,取记录第一条数据
+      selectedExam = selectedExam || this.examBatchs[0];
 
       this.examBatchId = selectedExam && selectedExam.id;
 

+ 43 - 36
src/features/invigilation/RealtimeMonitoring/RealtimeMonitoring.vue

@@ -48,7 +48,6 @@
           class="part-filter-info-main"
           data-type="trouble"
           :exam-id="filter.examId"
-          v-if="filter.examId"
           ref="SummaryLine"
         ></summary-line>
         <div class="part-filter-info-sub" v-if="!this.IS_INSPECTION">
@@ -138,19 +137,21 @@
           <el-dropdown
             @command="viewingAngleChange"
             style="margin-right: 10px;"
+            trigger="click"
             v-if="pageType === '1'"
           >
             <el-button type="primary"
-              >{{ curViewingAngle.name || "切换视角"
-              }}<i class="el-icon-arrow-down el-icon--right"></i
+              >切换视频源<i class="el-icon-arrow-down el-icon--right"></i
             ></el-button>
             <el-dropdown-menu slot="dropdown">
               <el-dropdown-item
                 v-for="item in viewingAngles"
                 :key="item.code"
                 :command="item"
-                >切换{{ item.name }}</el-dropdown-item
+                :class="{ 'color-primary': item.code === curViewingAngle.code }"
               >
+                {{ item.name }}
+              </el-dropdown-item>
             </el-dropdown-menu>
           </el-dropdown>
           <!-- <el-button
@@ -219,7 +220,7 @@
           </span>
         </template>
       </el-table-column>
-      <el-table-column label="操作" width="125">
+      <el-table-column label="操作" width="125" fixed="right">
         <template slot-scope="scope">
           <el-button
             :class="[
@@ -238,16 +239,17 @@
       <div
         class="invigilation-student-item"
         v-for="item in dataList"
-        :key="item.examStudentId"
+        :key="item.examRecordId"
       >
         <invigilation-student :data="item"></invigilation-student>
       </div>
     </div>
 
-    <div class="part-page" v-if="total > size">
+    <div class="part-page">
       <el-pagination
         background
-        layout="prev, pager, next,total,sizes,jumper"
+        hide-on-single-page
+        layout="prev, pager, next,total,jumper"
         :current-page="current"
         :total="total"
         :page-size="size"
@@ -273,7 +275,6 @@
 
 <script>
 import {
-  invigilateList,
   invigilateVideoList,
   invigilateExamFinish,
   monitorCallCount,
@@ -292,7 +293,7 @@ import {
   CLIENT_WEBSOCKET_STATUS,
   MONITOR_STATUS_SOURCE,
 } from "@/constant/constants";
-import { mapMutations, mapActions } from "vuex";
+import { mapState, mapMutations, mapActions } from "vuex";
 
 export default {
   name: "realtime-monitoring",
@@ -328,7 +329,6 @@ export default {
       communicationCount: 0,
       curExamBatch: {},
       curViewingAngle: {},
-      noticeCaches: {},
       current: 1,
       total: 0,
       size: 24,
@@ -341,16 +341,20 @@ export default {
       dataList: [],
       viewingAngles: [
         {
-          code: "1",
-          name: "第一视角",
+          code: "client_camera",
+          name: "电脑摄像头",
         },
         {
-          code: "2",
-          name: "第二视角",
+          code: "client_screen",
+          name: "电脑屏幕",
         },
         {
-          code: "3",
-          name: "第三视角",
+          code: "mobile_first",
+          name: "手机主机位",
+        },
+        {
+          code: "mobile_second",
+          name: "手机辅机位",
         },
       ],
     };
@@ -367,6 +371,9 @@ export default {
       this.toDetail({ examRecordId: id });
     };
   },
+  computed: {
+    ...mapState("invigilation", ["liveDomains"]),
+  },
   methods: {
     ...mapActions("invigilation", ["updateDetailIds"]),
     ...mapMutations("invigilation", ["setDetailIds"]),
@@ -400,6 +407,7 @@ export default {
       if (!examBatch) return;
       this.filter.examId = examBatch.id;
       this.curExamBatch = examBatch;
+
       this.toSearch();
 
       if (!this.IS_INSPECTION) {
@@ -422,7 +430,6 @@ export default {
     },
     pageTypeChange(pageType) {
       this.pageType = pageType;
-      this.toPage(1);
       this.multipleSelection = [];
     },
     viewingAngleChange(data) {
@@ -436,20 +443,19 @@ export default {
         pageSize: this.size,
       };
 
-      let res = null;
-      if (this.pageType === "0") {
-        res = await invigilateList(datas);
-        this.dataList = res.data.data.records.map((item) => {
-          item.label = `${item.identity} ${item.courseName}(${item.courseCode}) ${item.name}`;
-          return item;
-        });
-      } else {
-        res = await invigilateVideoList(datas);
-        this.dataList = res.data.data.records.map((item) => {
-          item.liveUrl = `http://live.qmth.com.cn/live/${item.monitorLiveUrl.toLowerCase()}.flv`;
-          return item;
-        });
-      }
+      const res = await invigilateVideoList(datas);
+      const domainLen = this.liveDomains.length;
+      this.dataList = res.data.data.records.map((item, index) => {
+        const domain = domainLen ? this.liveDomains[index % domainLen] : "";
+        item.label = `${item.identity} ${item.courseName}(${item.courseCode}) ${item.name}`;
+        item.liveUrl = item.monitorLiveUrl
+          ? `${domain}/live/${item.monitorLiveUrl.toLowerCase()}.flv`
+          : "";
+
+        return item;
+      });
+
+      this.hasNewWarning = this.dataList.some((item) => item.warningNew);
       this.total = res.data.data.total;
     },
     toPage(page) {
@@ -463,7 +469,7 @@ export default {
       if (this.total > this.size) {
         this.updateDetailIds({
           filterData: this.filter,
-          fetchFunc: invigilateList,
+          fetchFunc: invigilateVideoList,
         });
       } else {
         const ids = this.dataList.map((item) => item.examRecordId);
@@ -480,12 +486,13 @@ export default {
     },
     async fetchWarningNotice() {
       if (!this.filter.examId) return;
+      let noticeCaches = {};
 
       const res = await invigilationWarningMessage(this.filter.examId);
       res.data.data.forEach((item) => {
         const stdKey = item.examRecordId;
-        if (!this.noticeCaches[stdKey]) {
-          this.noticeCaches[stdKey] = item;
+        if (!noticeCaches[stdKey]) {
+          noticeCaches[stdKey] = item;
           this.$notify({
             duration: 5 * 1000,
             dangerouslyUseHTMLString: true,
@@ -533,7 +540,7 @@ export default {
       if (!result) return;
 
       await invigilateExamFinish(this.filter.examId);
-      this.toPage(1);
+      this.$refs.ExamBatchDialog.getExamList();
       this.$message({
         type: "success",
         message: "操作成功!",

+ 2 - 3
src/features/invigilation/RealtimeMonitoring/VideoCommunication.vue

@@ -46,7 +46,7 @@
         layout="prev, pager, next,total,sizes,jumper"
         :current-page="current"
         :total="total"
-        :page-size="size"
+        :page-size.sync="size"
         @size-change="toPage(1)"
         @current-change="toPage"
       >
@@ -103,7 +103,6 @@ export default {
       size: 100,
       setT: null,
       loopRunning: false,
-      appId: "1400411036",
       userMonitor: {},
       client: null,
       localStream: null,
@@ -145,7 +144,7 @@ export default {
       this.userMonitor = res.data.data;
       this.client = createClient({
         mode: "live",
-        sdkAppId: this.appId,
+        sdkAppId: this.userMonitor.appId,
         userId: this.userMonitor.monitorUserId,
         userSig: this.userMonitor.monitorUserSig,
       });

+ 49 - 10
src/features/invigilation/RealtimeMonitoring/WarningDetail.vue

@@ -324,17 +324,18 @@ export default {
       secondViewVideoReady: false,
       holding: false,
       // communication
-      appId: "1400411036",
       userMonitor: {},
       client: null,
       localStream: null,
       dialogVisible: false,
       isWaiting: true,
-      setT: null,
+      subscribeSetT: null,
+      loopRunning: false,
+      loopSetTs: [],
     };
   },
   computed: {
-    ...mapState("invigilation", ["detailIds"]),
+    ...mapState("invigilation", ["detailIds", "liveDomains"]),
   },
   watch: {
     $route: {
@@ -352,15 +353,51 @@ export default {
       await this.getInvigilateDetail().catch(() => {});
       await this.getStudentVideo().catch(() => {});
       this.holding = false;
+
+      // 学生正在考试,开启定时更新
+      if (this.detailInfo.statusCode === "ANSWERING") {
+        this.loopRunning = true;
+        this.clearLoopSetTs();
+        this.loopSetTs.push(
+          setTimeout(() => {
+            this.timerUpdatePage();
+          }, 10 * 1000)
+        );
+      } else {
+        this.loopRunning = false;
+        this.clearLoopSetTs();
+      }
+    },
+    clearLoopSetTs() {
+      if (!this.loopSetTs.length) return;
+      this.loopSetTs.forEach((sett) => {
+        clearTimeout(sett);
+      });
+      this.loopSetTs = [];
+    },
+    async timerUpdatePage() {
+      this.clearLoopSetTs();
+      if (!this.loopRunning) return;
+
+      await this.getInvigilateDetail().catch(() => {});
+
+      this.loopSetTs.push(
+        setTimeout(() => {
+          this.timerUpdatePage();
+        }, 10 * 1000)
+      );
     },
     async getStudentVideo() {
       const res = await warningStudentDetail({ recordId: this.recordId });
-      const records = res.data.data.map((item) => {
-        item.src = `http://live.qmth.com.cn/live/${item.liveUrl.toLowerCase()}.flv`;
+      const records = res.data.data.map((item, index) => {
+        const domain = this.liveDomains[index] || "";
+        item.liveUrl = item.liveUrl
+          ? `${domain}/live/${item.liveUrl.toLowerCase()}.flv`
+          : "";
         item.name = item.source;
         return item;
       });
-      console.log(records.map((item) => item.src));
+      console.log(records.map((item) => item.liveUrl));
       this.firstViewVideo = records[0] || {};
       this.secondViewVideo = records[2] || {};
 
@@ -529,7 +566,7 @@ export default {
       this.userMonitor = res.data.data;
       this.client = createClient({
         mode: "live",
-        sdkAppId: this.appId,
+        sdkAppId: this.userMonitor.appId,
         userId: this.userMonitor.monitorUserId,
         userSig: this.userMonitor.monitorUserSig,
       });
@@ -546,7 +583,7 @@ export default {
         const remoteStream = event.stream;
 
         // 延迟订阅视频
-        this.setT = setTimeout(() => {
+        this.subscribeSetT = setTimeout(() => {
           this.client
             .subscribe(remoteStream, { audio: true, video: true })
             .then(() => {
@@ -614,7 +651,7 @@ export default {
       this.localStream.play("communication-guest", { muted: true });
     },
     async hangup() {
-      if (this.setT) clearTimeout(this.setT);
+      if (this.subscribeSetT) clearTimeout(this.subscribeSetT);
 
       this.$refs.SecondTimer.end();
 
@@ -650,7 +687,9 @@ export default {
     },
   },
   beforeDestroy() {
-    if (this.setT) clearTimeout(this.setT);
+    this.loopRunning = false;
+    this.clearLoopSetTs();
+    if (this.subscribeSetT) clearTimeout(this.subscribeSetT);
     if (this.client) {
       this.client.leave();
       this.client.off("*");

+ 2 - 2
src/features/invigilation/ReexamApply/ReexamApply.vue

@@ -85,7 +85,7 @@
       <el-table-column prop="name" label="姓名"></el-table-column>
       <el-table-column prop="courseName" label="科目名称"></el-table-column>
       <el-table-column prop="courseCode" label="科目代码"></el-table-column>
-      <el-table-column label="操作">
+      <el-table-column label="操作" width="100">
         <template slot-scope="scope">
           <el-button
             class="btn-table-icon"
@@ -103,7 +103,7 @@
         layout="prev, pager, next,total,sizes,jumper"
         :current-page="current"
         :total="total"
-        :page-size="size"
+        :page-size.sync="size"
         @size-change="toPage(1)"
         @current-change="toPage"
       >

+ 2 - 2
src/features/invigilation/ReexamChecked/ReexamChecked.vue

@@ -119,7 +119,7 @@
         label="审核结果"
       ></el-table-column>
       <el-table-column prop="auditingName" label="审核人"></el-table-column>
-      <el-table-column label="操作">
+      <el-table-column label="操作" width="100" fixed="right">
         <template slot-scope="scope">
           <el-button
             class="btn-table-icon"
@@ -137,7 +137,7 @@
         layout="prev, pager, next,total,sizes,jumper"
         :current-page="current"
         :total="total"
-        :page-size="size"
+        :page-size.sync="size"
         @size-change="toPage(1)"
         @current-change="toPage"
       >

+ 2 - 2
src/features/invigilation/ReexamPending/ReexamPending.vue

@@ -121,7 +121,7 @@
       <el-table-column prop="reason" label="申请理由"></el-table-column>
       <el-table-column prop="applyTime" label="申请时间"></el-table-column>
       <el-table-column prop="applyName" label="申请人"></el-table-column>
-      <el-table-column label="操作">
+      <el-table-column label="操作" width="100" fixed="right">
         <template slot-scope="scope">
           <el-button
             class="btn-table-icon"
@@ -139,7 +139,7 @@
         layout="prev, pager, next,total,sizes,jumper"
         :current-page="current"
         :total="total"
-        :page-size="size"
+        :page-size.sync="size"
         @size-change="toPage(1)"
         @current-change="toPage"
       >

+ 1 - 1
src/features/invigilation/StudentLogManage/StudentLogDetailDialog.vue

@@ -21,7 +21,7 @@
         layout="prev, pager, next,total,sizes,jumper"
         :current-page="current"
         :total="total"
-        :page-size="size"
+        :page-size.sync="size"
         @size-change="toPage(1)"
         @current-change="toPage"
       >

+ 2 - 2
src/features/invigilation/StudentLogManage/StudentLogManage.vue

@@ -94,7 +94,7 @@
           {{ scope.row.courseName }}({{ scope.row.courseCode }})
         </span>
       </el-table-column>
-      <el-table-column label="操作">
+      <el-table-column label="操作" width="100">
         <template slot-scope="scope">
           <el-button
             class="btn-table-icon"
@@ -112,7 +112,7 @@
         layout="prev, pager, next,total,sizes,jumper"
         :current-page="current"
         :total="total"
-        :page-size="size"
+        :page-size.sync="size"
         @size-change="toPage(1)"
         @current-change="toPage"
       >

+ 3 - 9
src/features/invigilation/WarningManage/WarningManage.vue

@@ -167,7 +167,7 @@
           </span>
         </template>
       </el-table-column>
-      <el-table-column label="操作">
+      <el-table-column label="操作" width="100" fixed="right">
         <template slot-scope="scope">
           <el-button
             class="btn-table-icon"
@@ -185,7 +185,7 @@
         layout="prev, pager, next,total,sizes,jumper"
         :current-page="current"
         :total="total"
-        :page-size="size"
+        :page-size.sync="size"
         @size-change="toPage(1)"
         @current-change="toPage"
       >
@@ -324,13 +324,7 @@ export default {
       this.$message.success("操作成功!");
       this.getList();
     },
-    async toDetail(row) {
-      if (!row.approveStatus) {
-        await clearInvigilationUnreadWarningList({
-          approveStatus: 1,
-          warningIds: [row.warningId],
-        });
-      }
+    toDetail(row) {
       const router = this.IS_INVIGILATE
         ? "WarningDetail"
         : "InvigilationWarningDetail";

+ 3 - 3
src/features/invigilation/common/InvigilationStudent.vue

@@ -48,8 +48,8 @@ export default {
       return [
         "invigilation-student",
         {
-          "invigilation-student-warning": this.data.warning,
-          "invigilation-student-netbreak": this.data.netbreak,
+          "invigilation-student-breach": !this.data.breachStatus,
+          "invigilation-student-netbreak": this.data.statusCode === "BREAK_OFF",
         },
       ];
     },
@@ -64,7 +64,7 @@ export default {
   position: relative;
   margin-bottom: 20px;
 
-  &-warning {
+  &-breach {
     &::before {
       content: "";
       display: block;

+ 0 - 1
src/features/invigilation/common/SummaryLine.vue

@@ -91,7 +91,6 @@ export default {
   props: {
     examId: {
       type: String,
-      required: true,
     },
     dataType: {
       type: String,

+ 9 - 0
src/store/modules/invigilation.js

@@ -2,6 +2,7 @@ import {
   invigilateCount,
   invigilationWarningCount,
   reexamPendingCount,
+  getLiveDomains,
 } from "@/api/invigilation";
 
 const state = {
@@ -20,6 +21,7 @@ const state = {
     },
   },
   detailIds: [],
+  liveDomains: [],
 };
 
 const mutations = {
@@ -35,6 +37,9 @@ const mutations = {
   setDetailIds(state, detailIds) {
     state.detailIds = detailIds;
   },
+  setLiveDomains(state, liveDomains) {
+    state.liveDomains = liveDomains;
+  },
 };
 
 const actions = {
@@ -59,6 +64,10 @@ const actions = {
     const ids = res.data.data.records.map((item) => item.examRecordId);
     commit("setDetailIds", [...new Set(ids)]);
   },
+  async fetchLiveDomains({ commit }) {
+    const res = await getLiveDomains();
+    commit("setLiveDomains", res.data.data || []);
+  },
 };
 
 export default { namespaced: true, state, mutations, actions };

+ 2 - 1
src/styles/base.scss

@@ -38,7 +38,7 @@ body {
 }
 
 // fomate
-.color-primay {
+.color-primary {
   color: #1886fe;
 }
 .color-success {
@@ -417,6 +417,7 @@ body {
       width: 100%;
       height: 100%;
       border-radius: 6px;
+      background-color: #e8edf3;
     }
   }
   .student-video {

+ 1 - 1
src/views/Layout/components/AppFooter.vue

@@ -2,7 +2,7 @@
   <div class="app-footer">
     <p>
       Copyright ©
-      <a href="http:\\www.qmth.com.cn" target="_blank">www.qmth.com.cn</a> , All
+      <a href="http://www.qmth.com.cn" target="_blank">www.qmth.com.cn</a> , All
       Rights Reserved.
     </p>
   </div>

+ 9 - 2
vue.config.js

@@ -1,4 +1,4 @@
-let proxy = {
+const defProxy = {
   "/api": {
     // target: "http://192.168.10.26:6001/",
     target: "http://192.168.10.36:9222/",
@@ -13,11 +13,18 @@ let proxy = {
   },
 };
 
+let devProxy = null;
+try {
+  devProxy = require("./dev-proxy");
+} catch (error) {
+  console.log(error);
+}
+
 var webpack = require("webpack");
 module.exports = {
   lintOnSave: process.env.NODE_ENV !== "production" ? true : "error",
   devServer: {
-    proxy,
+    proxy: devProxy || defProxy,
   },
   configureWebpack: {
     devtool: "source-map",