|
@@ -1,629 +1,222 @@
|
|
|
<template>
|
|
|
- <div class="exam-invigilation">
|
|
|
- <div class="invigilation-analysis">
|
|
|
- <div class="part-box-head">
|
|
|
- <div class="part-box-head-left"><h1>考情监控</h1></div>
|
|
|
- <div class="part-box-head-right" @click="exitFullscreen">
|
|
|
- <i class="icon icon-full-screen"></i>退出全屏
|
|
|
+ <div class="exam-invigilation invi-container">
|
|
|
+ <div class="invi-body">
|
|
|
+ <h1 class="invi-body-title">考情监控</h1>
|
|
|
+ <div class="invi-summary">
|
|
|
+ <div class="invi-summary-item">
|
|
|
+ <h4>在线考试人数</h4>
|
|
|
+ <p>
|
|
|
+ <animate-number :value="summary.onlineCount"></animate-number>
|
|
|
+ </p>
|
|
|
</div>
|
|
|
- </div>
|
|
|
- <div class="invigilation-summary">
|
|
|
- <div class="invigilation-summary-item">
|
|
|
- <div class="part-box">
|
|
|
- <h5>
|
|
|
- <span>在线(人)</span>
|
|
|
- <el-popover
|
|
|
- placement="top-start"
|
|
|
- popper-class="warning-popover"
|
|
|
- width="200"
|
|
|
- trigger="hover"
|
|
|
- content="当前在线考试人数。"
|
|
|
- >
|
|
|
- <i class="el-icon-question" slot="reference"></i>
|
|
|
- </el-popover>
|
|
|
- </h5>
|
|
|
- <p>{{ monitorCount.onlineCount }}</p>
|
|
|
- </div>
|
|
|
+ <div class="invi-summary-item">
|
|
|
+ <h4>考试中人数</h4>
|
|
|
+ <p>
|
|
|
+ <animate-number :value="summary.examingCount"></animate-number>
|
|
|
+ </p>
|
|
|
</div>
|
|
|
- <div class="invigilation-summary-item">
|
|
|
- <div class="part-box">
|
|
|
- <h5>
|
|
|
- <span>待考(人)</span>
|
|
|
- <el-popover
|
|
|
- placement="top-start"
|
|
|
- popper-class="warning-popover"
|
|
|
- width="200"
|
|
|
- trigger="hover"
|
|
|
- content="已进入待考界面等待开考的考生。"
|
|
|
- >
|
|
|
- <i class="el-icon-question" slot="reference"></i>
|
|
|
- </el-popover>
|
|
|
- </h5>
|
|
|
- <p>{{ monitorCount.waitingCount }}</p>
|
|
|
- </div>
|
|
|
+ <div class="invi-summary-item">
|
|
|
+ <h4>待考人数</h4>
|
|
|
+ <p>
|
|
|
+ <animate-number :value="summary.waitingCount"></animate-number>
|
|
|
+ </p>
|
|
|
</div>
|
|
|
- <div class="invigilation-summary-item">
|
|
|
- <div class="part-box">
|
|
|
- <h5>
|
|
|
- <span>考试中(人)</span>
|
|
|
- <el-popover
|
|
|
- placement="top-start"
|
|
|
- popper-class="warning-popover"
|
|
|
- width="200"
|
|
|
- trigger="hover"
|
|
|
- content="正在答题的考生。"
|
|
|
- >
|
|
|
- <i class="el-icon-question" slot="reference"></i>
|
|
|
- </el-popover>
|
|
|
- </h5>
|
|
|
- <p>{{ monitorCount.examingCount }}</p>
|
|
|
- </div>
|
|
|
+ <div class="invi-summary-item">
|
|
|
+ <h4>预警总数</h4>
|
|
|
+ <p><animate-number :value="summary.warnCount"></animate-number></p>
|
|
|
</div>
|
|
|
- <div class="invigilation-summary-item">
|
|
|
- <div class="part-box">
|
|
|
- <h5>
|
|
|
- <span>通讯故障</span>
|
|
|
- <el-popover
|
|
|
- placement="top-start"
|
|
|
- popper-class="warning-popover"
|
|
|
- width="200"
|
|
|
- trigger="hover"
|
|
|
- content="考生端出现断网、断电、软硬件故障等异常导致考生端与监考端无法正常连接的考生。"
|
|
|
- >
|
|
|
- <i class="el-icon-question" slot="reference"></i>
|
|
|
- </el-popover>
|
|
|
- </h5>
|
|
|
- <p
|
|
|
- :class="{
|
|
|
- 'color-danger': monitorCount.exceptionCountChange > 0,
|
|
|
- 'color-success': monitorCount.exceptionCountChange < 0,
|
|
|
- }"
|
|
|
- >
|
|
|
- {{ monitorCount.exceptionCount }}
|
|
|
- <i
|
|
|
- :class="[
|
|
|
- 'icon',
|
|
|
- {
|
|
|
- 'icon-arrows-up': monitorCount.exceptionCountChange > 0,
|
|
|
- 'icon-arrows-down': monitorCount.exceptionCountChange < 0,
|
|
|
- },
|
|
|
- ]"
|
|
|
- ></i>
|
|
|
- </p>
|
|
|
- </div>
|
|
|
+ <div class="invi-summary-item">
|
|
|
+ <h4>违纪总数</h4>
|
|
|
+ <p>
|
|
|
+ <animate-number :value="summary.breachCount"></animate-number>
|
|
|
+ </p>
|
|
|
</div>
|
|
|
- <div class="invigilation-summary-item">
|
|
|
- <div class="part-box">
|
|
|
- <h5>
|
|
|
- <span>预警</span>
|
|
|
- <el-popover
|
|
|
- placement="top-start"
|
|
|
- popper-class="warning-popover"
|
|
|
- width="200"
|
|
|
- trigger="hover"
|
|
|
- content="实时预警数量及升跌趋势(后1分钟增量与前1分钟增量对比,大于为升势,小于为跌势)。"
|
|
|
- >
|
|
|
- <i class="el-icon-question" slot="reference"></i>
|
|
|
- </el-popover>
|
|
|
- </h5>
|
|
|
- <p
|
|
|
- :class="{
|
|
|
- 'color-danger': monitorCount.warnCountChange > 0,
|
|
|
- 'color-success': monitorCount.warnCountChange < 0,
|
|
|
- }"
|
|
|
- >
|
|
|
- {{ monitorCount.warnCount }}
|
|
|
- <i
|
|
|
- :class="[
|
|
|
- 'icon',
|
|
|
- {
|
|
|
- 'icon-arrows-up': monitorCount.warnCountChange > 0,
|
|
|
- 'icon-arrows-down': monitorCount.warnCountChange < 0,
|
|
|
- },
|
|
|
- ]"
|
|
|
- ></i>
|
|
|
- </p>
|
|
|
+ </div>
|
|
|
+ <div class="invi-analysis">
|
|
|
+ <div class="invi-analysis-item">
|
|
|
+ <div class="invi-analysis-box invi-time">
|
|
|
+ <h2 class="invi-analysis-title">考生在线/预警时间趋势</h2>
|
|
|
+ <div class="invi-time-chart invi-chart">
|
|
|
+ <vue-charts
|
|
|
+ v-if="inviTimeChartOption"
|
|
|
+ :options="inviTimeChartOption"
|
|
|
+ autoresize
|
|
|
+ ></vue-charts>
|
|
|
+ </div>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
- <div class="invigilation-online part-box">
|
|
|
- <h3 class="invigilation-part-title">
|
|
|
- <span>各机构在线考试人数分布</span>
|
|
|
- <el-popover
|
|
|
- placement="top-start"
|
|
|
- popper-class="warning-popover"
|
|
|
- width="200"
|
|
|
- trigger="hover"
|
|
|
- content="各二级子机构当前在线考试人数分布。"
|
|
|
- >
|
|
|
- <i class="el-icon-question" slot="reference"></i>
|
|
|
- </el-popover>
|
|
|
- </h3>
|
|
|
- <echart-render
|
|
|
- :chart-data="onlineData"
|
|
|
- chart-type="bar"
|
|
|
- ></echart-render>
|
|
|
- </div>
|
|
|
- <div class="invigilation-warning">
|
|
|
- <el-row :gutter="20">
|
|
|
- <el-col :span="12">
|
|
|
- <div class="part-box">
|
|
|
- <h3 class="invigilation-part-title">
|
|
|
- <span>机构预警分布</span>
|
|
|
- <el-popover
|
|
|
- placement="top-start"
|
|
|
- popper-class="warning-popover"
|
|
|
- width="200"
|
|
|
- trigger="hover"
|
|
|
- content="各二级子机构当前预警数量分布。"
|
|
|
- >
|
|
|
- <i class="el-icon-question" slot="reference"></i>
|
|
|
- </el-popover>
|
|
|
- </h3>
|
|
|
- <echart-render
|
|
|
- :chart-data="orgWarningData"
|
|
|
- chart-type="pieAnnulus"
|
|
|
- ></echart-render>
|
|
|
+ <div class="invi-analysis invi-analysis-2">
|
|
|
+ <div class="invi-analysis-item">
|
|
|
+ <div class="invi-analysis-box invi-types">
|
|
|
+ <h2 class="invi-analysis-title">预警类型排行</h2>
|
|
|
+ <div class="invi-types-table">
|
|
|
+ <table class="invi-table">
|
|
|
+ <colgroup>
|
|
|
+ <col width="70" />
|
|
|
+ <col width="120" />
|
|
|
+ <col width="20" />
|
|
|
+ </colgroup>
|
|
|
+ <tr v-for="item in inviTypesList" :key="item.id">
|
|
|
+ <td>{{ item.type }}</td>
|
|
|
+ <td>
|
|
|
+ <el-progress
|
|
|
+ :stroke-width="6"
|
|
|
+ :show-text="false"
|
|
|
+ :percentage="item.percentage"
|
|
|
+ ></el-progress>
|
|
|
+ </td>
|
|
|
+ <td>{{ item.warnCount }}</td>
|
|
|
+ </tr>
|
|
|
+ </table>
|
|
|
</div>
|
|
|
- </el-col>
|
|
|
- <el-col :span="12">
|
|
|
- <div class="part-box">
|
|
|
- <h3 class="invigilation-part-title">
|
|
|
- <span>预警类型分布</span>
|
|
|
- <el-popover
|
|
|
- placement="top-start"
|
|
|
- popper-class="warning-popover"
|
|
|
- width="200"
|
|
|
- trigger="hover"
|
|
|
- content="当前考试累计预警的类型分析。"
|
|
|
- >
|
|
|
- <i class="el-icon-question" slot="reference"></i>
|
|
|
- </el-popover>
|
|
|
- </h3>
|
|
|
- <echart-render
|
|
|
- :chart-data="typeWarningData"
|
|
|
- chart-type="pieAnnulus"
|
|
|
- ></echart-render>
|
|
|
+ <div class="invi-types-chart invi-chart">
|
|
|
+ <div v-if="inviTypesChartOption" class="invi-chart-title">
|
|
|
+ 预警类型占比
|
|
|
+ </div>
|
|
|
+ <vue-charts
|
|
|
+ v-if="inviTypesChartOption"
|
|
|
+ :options="inviTypesChartOption"
|
|
|
+ autoresize
|
|
|
+ ></vue-charts>
|
|
|
</div>
|
|
|
- </el-col>
|
|
|
- </el-row>
|
|
|
- </div>
|
|
|
- <div class="invigilation-trend part-box">
|
|
|
- <h3 class="invigilation-part-title">
|
|
|
- <span>预警时间趋势</span>
|
|
|
- <el-popover
|
|
|
- placement="top-start"
|
|
|
- popper-class="warning-popover"
|
|
|
- width="200"
|
|
|
- trigger="hover"
|
|
|
- content="按时间维度呈现预警数量的升跌走势图。"
|
|
|
- >
|
|
|
- <i class="el-icon-question" slot="reference"></i>
|
|
|
- </el-popover>
|
|
|
- </h3>
|
|
|
- <echart-render
|
|
|
- :chart-data="warningTrendData"
|
|
|
- chart-type="line"
|
|
|
- ></echart-render>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="invi-analysis-item">
|
|
|
+ <div class="invi-analysis-box invi-area">
|
|
|
+ <h2 class="invi-analysis-title">预警地区排行</h2>
|
|
|
+ <div class="invi-area-table">
|
|
|
+ <table class="invi-table">
|
|
|
+ <colgroup>
|
|
|
+ <col width="40" />
|
|
|
+ <col width="150" />
|
|
|
+ <col width="30" />
|
|
|
+ </colgroup>
|
|
|
+ <tr v-for="item in inviAreaList" :key="item.id">
|
|
|
+ <td>{{ item.province }}</td>
|
|
|
+ <td>
|
|
|
+ <el-progress
|
|
|
+ :stroke-width="6"
|
|
|
+ :show-text="false"
|
|
|
+ :percentage="item.percentage"
|
|
|
+ ></el-progress>
|
|
|
+ </td>
|
|
|
+ <td>{{ item.warnCount }}</td>
|
|
|
+ </tr>
|
|
|
+ </table>
|
|
|
+ </div>
|
|
|
+ <div class="invi-area-chart invi-chart">
|
|
|
+ <div v-if="inviAreaChartOption" class="invi-chart-title">
|
|
|
+ 考生分布
|
|
|
+ </div>
|
|
|
+ <vue-charts
|
|
|
+ v-if="inviAreaChartOption"
|
|
|
+ :options="inviAreaChartOption"
|
|
|
+ autoresize
|
|
|
+ ></vue-charts>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
</div>
|
|
|
- <div class="invigilation-message part-box">
|
|
|
- <h3 class="invigilation-part-title">
|
|
|
- <span>预警消息</span>
|
|
|
- <el-popover
|
|
|
- placement="top-start"
|
|
|
- popper-class="warning-popover"
|
|
|
- width="200"
|
|
|
- trigger="hover"
|
|
|
- content="系统实时预警提示滚屏。"
|
|
|
- >
|
|
|
- <i class="el-icon-question" slot="reference"></i>
|
|
|
- </el-popover>
|
|
|
- </h3>
|
|
|
- <div class="message-list">
|
|
|
- <div
|
|
|
- class="message-item"
|
|
|
- v-for="(item, index) in messages"
|
|
|
- :key="index"
|
|
|
- >
|
|
|
- <span><i class="el-icon-warning"></i></span>
|
|
|
- <span>{{ item.time | datetimeFilter }}</span>
|
|
|
- <span>{{ item.content }}</span>
|
|
|
+ <div class="invi-analysis">
|
|
|
+ <div class="invi-analysis-item">
|
|
|
+ <div class="invi-analysis-box invi-student">
|
|
|
+ <h2 class="invi-analysis-title">考试动态预警</h2>
|
|
|
+ <div v-if="inviStudentWainList.length" class="invi-student-table">
|
|
|
+ <table class="invi-table">
|
|
|
+ <colgroup>
|
|
|
+ <col width="60" />
|
|
|
+ <col width="60" />
|
|
|
+ <col width="140" />
|
|
|
+ <col width="100" />
|
|
|
+ <col width="70" />
|
|
|
+ </colgroup>
|
|
|
+ <tbody>
|
|
|
+ <tr>
|
|
|
+ <th>时间</th>
|
|
|
+ <th>姓名</th>
|
|
|
+ <th>证件号</th>
|
|
|
+ <th>预警类型</th>
|
|
|
+ <th>处理状态</th>
|
|
|
+ </tr>
|
|
|
+ <tr v-for="item in inviStudentWainList" :key="item.id">
|
|
|
+ <td>{{ item.createTime | timeFilter }}</td>
|
|
|
+ <td>
|
|
|
+ <div class="td-cont" style="width: 60px;">
|
|
|
+ {{ item.name }}
|
|
|
+ </div>
|
|
|
+ </td>
|
|
|
+ <td>{{ item.identity }}</td>
|
|
|
+ <td>
|
|
|
+ <div
|
|
|
+ class="td-cont"
|
|
|
+ style="width: 140px;"
|
|
|
+ :title="item.info"
|
|
|
+ >
|
|
|
+ {{ item.info }}
|
|
|
+ </div>
|
|
|
+ </td>
|
|
|
+ <td>{{ item.approveStatus }}</td>
|
|
|
+ </tr>
|
|
|
+ </tbody>
|
|
|
+ </table>
|
|
|
+ </div>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
- <div class="invigilation-list">
|
|
|
- <h3>实时监控台</h3>
|
|
|
- <invigilation-student
|
|
|
- ref="InvigilationStudent"
|
|
|
- v-for="item in students"
|
|
|
+ <div class="invi-monitor">
|
|
|
+ <h3 class="invi-monitor-title">实时监控台</h3>
|
|
|
+ <div
|
|
|
+ v-for="item in studentVideoList"
|
|
|
:key="item.examStudentId"
|
|
|
- :data="item"
|
|
|
- show-type="patrol"
|
|
|
- :max-retry-count="1"
|
|
|
- @muted-change="videoAllMuted"
|
|
|
- ></invigilation-student>
|
|
|
+ class="invi-monitor-item"
|
|
|
+ >
|
|
|
+ <invigilation-student
|
|
|
+ ref="InvigilationStudent"
|
|
|
+ :data="item"
|
|
|
+ show-type="patrol"
|
|
|
+ :max-retry-count="1"
|
|
|
+ detail-name="详情"
|
|
|
+ @muted-change="videoAllMuted"
|
|
|
+ ></invigilation-student>
|
|
|
+ </div>
|
|
|
</div>
|
|
|
</div>
|
|
|
</template>
|
|
|
|
|
|
<script>
|
|
|
-import EchartRender from "../common/EchartRender";
|
|
|
import InvigilationStudent from "../common/InvigilationStudent";
|
|
|
-import {
|
|
|
- examInvigilationCount,
|
|
|
- examInvigilationWarnDistribution,
|
|
|
- examInvigilationWarnTrend,
|
|
|
- examInvigilationVideoRandomList,
|
|
|
- examInvigilationWarnMessage,
|
|
|
-} from "@/api/invigilation";
|
|
|
-import { mapState } from "vuex";
|
|
|
-import timeMixin from "@/mixins/timeMixin";
|
|
|
+import VueCharts from "@/plugins/VueCharts";
|
|
|
+import AnimateNumber from "@/components/AnimateNumber";
|
|
|
+import examInviMixins from "./examInviMixins";
|
|
|
|
|
|
export default {
|
|
|
name: "exam-invigilation",
|
|
|
- components: { EchartRender, InvigilationStudent },
|
|
|
- mixins: [timeMixin],
|
|
|
+ components: { InvigilationStudent, VueCharts, AnimateNumber },
|
|
|
+ mixins: [examInviMixins],
|
|
|
data() {
|
|
|
return {
|
|
|
- monitorCount: {
|
|
|
- onlineCount: 0,
|
|
|
- waitingCount: 0,
|
|
|
- examingCount: 0,
|
|
|
- exceptionCount: 0,
|
|
|
- warnCount: 0,
|
|
|
- exceptionCountChange: false,
|
|
|
- warnCountChange: false,
|
|
|
- },
|
|
|
- onlineData: {
|
|
|
- dataList: [],
|
|
|
- type: "light", // light or dark
|
|
|
- },
|
|
|
- orgWarningData: {
|
|
|
- dataList: [],
|
|
|
- type: "light",
|
|
|
- },
|
|
|
- typeWarningData: {
|
|
|
- dataList: [],
|
|
|
- type: "light",
|
|
|
- },
|
|
|
- warningTrendData: {
|
|
|
- dataList: [],
|
|
|
- type: "light",
|
|
|
- },
|
|
|
- loopRunning: false,
|
|
|
- students: [],
|
|
|
- messages: [],
|
|
|
+ colorType: "white",
|
|
|
};
|
|
|
},
|
|
|
- computed: {
|
|
|
- ...mapState("invigilation", ["liveDomains"]),
|
|
|
- isFullScreen() {
|
|
|
- return this.$store.state.isFullScreen;
|
|
|
- },
|
|
|
- },
|
|
|
watch: {
|
|
|
- isFullScreen(val) {
|
|
|
- this.fullScreenChange(val);
|
|
|
+ isFullScreen: {
|
|
|
+ immediate: true,
|
|
|
+ handler(val, oldVal) {
|
|
|
+ if (val !== oldVal && val) {
|
|
|
+ this.$router.replace({ name: "ExamInvigilationFull" });
|
|
|
+ }
|
|
|
+ },
|
|
|
},
|
|
|
},
|
|
|
- mounted() {
|
|
|
- this.loopRunning = true;
|
|
|
- this.initData();
|
|
|
- },
|
|
|
methods: {
|
|
|
- async initData() {
|
|
|
- if (!this.loopRunning) return;
|
|
|
- this.clearSetTs();
|
|
|
-
|
|
|
- const fetchAll = [
|
|
|
- this.getCount(),
|
|
|
- this.getWarnDistribution(),
|
|
|
- this.getWarnTrend(),
|
|
|
- ];
|
|
|
- await Promise.all(fetchAll).catch(() => {});
|
|
|
-
|
|
|
- this.fullScreenChange(this.checkDocIsFullscreen());
|
|
|
-
|
|
|
- await this.getVideoList();
|
|
|
- await this.getMessageList();
|
|
|
-
|
|
|
- this.addSetTime(() => {
|
|
|
- this.initData();
|
|
|
- }, 10 * 1000);
|
|
|
- },
|
|
|
- async getCount() {
|
|
|
- const res = await examInvigilationCount();
|
|
|
- const data = res.data.data;
|
|
|
- this.monitorCount = {
|
|
|
- onlineCount: data.onlineCount,
|
|
|
- waitingCount: data.waitingCount,
|
|
|
- examingCount: data.examingCount,
|
|
|
- exceptionCount: data.exceptionCount,
|
|
|
- warnCount: data.warnCount,
|
|
|
- exceptionCountChange:
|
|
|
- data.exceptionCount - this.monitorCount.exceptionCount,
|
|
|
- warnCountChange: data.warnCount - this.monitorCount.warnCount,
|
|
|
- };
|
|
|
- this.onlineData.dataList = data.orgExamingCount.map((item) => {
|
|
|
- return {
|
|
|
- name: item.orgName,
|
|
|
- count: item.count * 1,
|
|
|
- };
|
|
|
- });
|
|
|
- },
|
|
|
- async getWarnDistribution() {
|
|
|
- const res = await examInvigilationWarnDistribution();
|
|
|
- const data = res.data.data;
|
|
|
- this.orgWarningData.dataList = data.orgDistribution.map((item) => {
|
|
|
- return {
|
|
|
- name: item.orgName,
|
|
|
- count: item.count,
|
|
|
- };
|
|
|
- });
|
|
|
- this.typeWarningData.dataList = data.typeDistribution.map((item) => {
|
|
|
- return {
|
|
|
- name: item.type,
|
|
|
- count: item.count * 1,
|
|
|
- };
|
|
|
- });
|
|
|
- },
|
|
|
- async getWarnTrend() {
|
|
|
- const res = await examInvigilationWarnTrend();
|
|
|
- this.warningTrendData.dataList = res.data.data.map((item) => {
|
|
|
- return {
|
|
|
- name: item.hour,
|
|
|
- count: item.count * 1,
|
|
|
- };
|
|
|
- });
|
|
|
- },
|
|
|
- async getVideoList() {
|
|
|
- const res = await examInvigilationVideoRandomList({ randomNum: 4 });
|
|
|
- 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`
|
|
|
- : "";
|
|
|
- item.progress = item.progress ? Math.round(item.progress * 100) : 0;
|
|
|
- return item;
|
|
|
- });
|
|
|
+ initData() {
|
|
|
+ this.intervalSummary();
|
|
|
+ this.intervalCommonData();
|
|
|
+ this.intervalStudentWain();
|
|
|
+ this.intervalTimeTrend();
|
|
|
},
|
|
|
- async getMessageList() {
|
|
|
- const res = await examInvigilationWarnMessage();
|
|
|
- this.messages = res.data.data;
|
|
|
- },
|
|
|
- // fullscreen
|
|
|
- exitFullscreen() {
|
|
|
- const exitFullscreen =
|
|
|
- document.exitFullscreen ||
|
|
|
- document.mozCancelFullScreen ||
|
|
|
- document.webkitCancelFullScreen;
|
|
|
-
|
|
|
- exitFullscreen.call(document);
|
|
|
- },
|
|
|
- checkDocIsFullscreen() {
|
|
|
- return (
|
|
|
- document.fullscreenElement ||
|
|
|
- document.msFullscreenElement ||
|
|
|
- document.mozFullscreenElement ||
|
|
|
- document.webkitFullscreenElement
|
|
|
- );
|
|
|
- },
|
|
|
- fullScreenChange(isFullScreen) {
|
|
|
- const colorType = isFullScreen ? "dark" : "light";
|
|
|
- this.onlineData.type = colorType;
|
|
|
- this.orgWarningData.type = colorType;
|
|
|
- this.typeWarningData.type = colorType;
|
|
|
- this.warningTrendData.type = colorType;
|
|
|
- },
|
|
|
- videoAllMuted() {
|
|
|
- this.$refs.InvigilationStudent.forEach((refInst) => {
|
|
|
- refInst.mutedPlayer(true);
|
|
|
- });
|
|
|
- },
|
|
|
- },
|
|
|
- beforeDestroy() {
|
|
|
- this.loopRunning = false;
|
|
|
- this.clearSetTs();
|
|
|
},
|
|
|
};
|
|
|
</script>
|
|
|
-
|
|
|
-<style lang="scss" scoped>
|
|
|
-.exam-invigilation {
|
|
|
- position: relative;
|
|
|
- padding-right: 310px;
|
|
|
- min-width: 1250px;
|
|
|
- .part-box-head-right {
|
|
|
- display: none;
|
|
|
- }
|
|
|
- .part-box {
|
|
|
- position: relative;
|
|
|
- }
|
|
|
- .invigilation-part-title {
|
|
|
- position: absolute;
|
|
|
- top: 20px;
|
|
|
- left: 20px;
|
|
|
- font-size: 16px;
|
|
|
- font-weight: 500;
|
|
|
- z-index: 9;
|
|
|
- }
|
|
|
- .el-icon-question {
|
|
|
- margin-left: 5px;
|
|
|
- color: #bdc8da;
|
|
|
- }
|
|
|
-}
|
|
|
-.invigilation-list {
|
|
|
- position: absolute;
|
|
|
- top: 0;
|
|
|
- right: 0;
|
|
|
- width: 280px;
|
|
|
- height: 100%;
|
|
|
- border-radius: 6px;
|
|
|
- z-index: 9;
|
|
|
- overflow-y: auto;
|
|
|
- overflow-x: hidden;
|
|
|
-
|
|
|
- > h3 {
|
|
|
- font-size: 18px;
|
|
|
- font-weight: 600;
|
|
|
- line-height: 25px;
|
|
|
- margin-bottom: 20px;
|
|
|
- }
|
|
|
- .invigilation-student {
|
|
|
- background-color: #fff;
|
|
|
- }
|
|
|
-}
|
|
|
-.invigilation-analysis {
|
|
|
- min-width: 940px;
|
|
|
- .part-box-head-left h1 {
|
|
|
- line-height: 25px;
|
|
|
- }
|
|
|
-}
|
|
|
-.invigilation-summary {
|
|
|
- margin: 0 -10px;
|
|
|
- font-size: 0;
|
|
|
-
|
|
|
- &-item {
|
|
|
- display: inline-block;
|
|
|
- vertical-align: top;
|
|
|
- width: 20%;
|
|
|
- padding: 0 10px;
|
|
|
- font-size: 14px;
|
|
|
- color: #202b4b;
|
|
|
-
|
|
|
- h5 {
|
|
|
- font-size: 14px;
|
|
|
- height: 20px;
|
|
|
- color: #626a82;
|
|
|
- margin: 0;
|
|
|
- }
|
|
|
- p {
|
|
|
- font-size: 32px;
|
|
|
- line-height: 51px;
|
|
|
- font-weight: 600;
|
|
|
- margin: 0;
|
|
|
- }
|
|
|
- .icon {
|
|
|
- margin-top: -4px;
|
|
|
- }
|
|
|
-
|
|
|
- &:first-child {
|
|
|
- .part-box {
|
|
|
- background-color: #3a93fb;
|
|
|
- }
|
|
|
- h5 {
|
|
|
- color: #fff;
|
|
|
- }
|
|
|
- p {
|
|
|
- color: #fff;
|
|
|
- font-weight: 900;
|
|
|
- font-size: 36px;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-}
|
|
|
-.invigilation-online {
|
|
|
- height: 360px;
|
|
|
-}
|
|
|
-.invigilation-warning {
|
|
|
- .part-box {
|
|
|
- height: 282px;
|
|
|
- padding-top: 50px;
|
|
|
- padding-bottom: 10px;
|
|
|
- }
|
|
|
-}
|
|
|
-.invigilation-trend {
|
|
|
- height: 327px;
|
|
|
-}
|
|
|
-.invigilation-message {
|
|
|
- min-height: 160px;
|
|
|
- padding-top: 70px;
|
|
|
- .message-item {
|
|
|
- margin-bottom: 15px;
|
|
|
-
|
|
|
- span {
|
|
|
- line-height: 20px;
|
|
|
-
|
|
|
- &:first-child {
|
|
|
- color: #fe5863;
|
|
|
- }
|
|
|
-
|
|
|
- &:nth-of-type(2) {
|
|
|
- margin: 0 20px 0 12px;
|
|
|
- color: #8c94ac;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-}
|
|
|
-</style>
|
|
|
-<style lang="scss">
|
|
|
-// fullscreen style
|
|
|
-.app-fullscreen {
|
|
|
- .part-box {
|
|
|
- background: #2d325a;
|
|
|
- }
|
|
|
-
|
|
|
- .exam-invigilation {
|
|
|
- margin: -30px;
|
|
|
- padding-right: 280px;
|
|
|
- color: #fff;
|
|
|
- .part-box-head-right {
|
|
|
- display: block;
|
|
|
- cursor: pointer;
|
|
|
- color: #737aae;
|
|
|
- > i {
|
|
|
- margin-right: 8px;
|
|
|
- margin-top: -2px;
|
|
|
- }
|
|
|
- }
|
|
|
- .part-box-head-left > h1 {
|
|
|
- color: #fff;
|
|
|
- }
|
|
|
- .el-icon-question {
|
|
|
- color: #737aae;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- .invigilation-analysis {
|
|
|
- padding: 30px;
|
|
|
- background: #25294a;
|
|
|
- }
|
|
|
- .invigilation-list {
|
|
|
- background: #25294a;
|
|
|
- border-radius: 0;
|
|
|
- padding-top: 30px;
|
|
|
- padding-right: 20px;
|
|
|
-
|
|
|
- .invigilation-student {
|
|
|
- background: #2d325a;
|
|
|
- border: 1px solid #2d325a;
|
|
|
- }
|
|
|
- .student-info {
|
|
|
- &-time {
|
|
|
- background: #353c70;
|
|
|
- }
|
|
|
- > p {
|
|
|
- color: #737aae;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- .invigilation-summary {
|
|
|
- &-item {
|
|
|
- h5 {
|
|
|
- color: #737aae;
|
|
|
- }
|
|
|
- p {
|
|
|
- color: #fff;
|
|
|
- }
|
|
|
-
|
|
|
- &:first-child {
|
|
|
- .el-icon-question {
|
|
|
- color: #fff;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-}
|
|
|
-</style>
|