|
@@ -11,7 +11,7 @@
|
|
<div class="invi-body">
|
|
<div class="invi-body">
|
|
<div class="invi-monitor">
|
|
<div class="invi-monitor">
|
|
<div
|
|
<div
|
|
- v-for="item in students"
|
|
|
|
|
|
+ v-for="item in studentVideoList"
|
|
:key="item.examStudentId"
|
|
:key="item.examStudentId"
|
|
class="invi-monitor-item"
|
|
class="invi-monitor-item"
|
|
>
|
|
>
|
|
@@ -48,7 +48,14 @@
|
|
<p>{{ summary.breachCount }}</p>
|
|
<p>{{ summary.breachCount }}</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
- <div class="invi-map"></div>
|
|
|
|
|
|
+ <div class="invi-map-chart">
|
|
|
|
+ <vue-charts
|
|
|
|
+ v-if="inviMapChartOption"
|
|
|
|
+ :options="inviMapChartOption"
|
|
|
|
+ autoresize
|
|
|
|
+ ></vue-charts>
|
|
|
|
+ <p class="chart-none" v-else>暂无数据</p>
|
|
|
|
+ </div>
|
|
</div>
|
|
</div>
|
|
<div class="invi-analysis">
|
|
<div class="invi-analysis">
|
|
<div class="invi-analysis-item">
|
|
<div class="invi-analysis-item">
|
|
@@ -75,7 +82,9 @@
|
|
</table>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
<div class="invi-types-chart invi-chart">
|
|
<div class="invi-types-chart invi-chart">
|
|
- <div class="invi-chart-title">预警类型占比</div>
|
|
|
|
|
|
+ <div v-if="inviTypesChartOption" class="invi-chart-title">
|
|
|
|
+ 预警类型占比
|
|
|
|
+ </div>
|
|
<vue-charts
|
|
<vue-charts
|
|
v-if="inviTypesChartOption"
|
|
v-if="inviTypesChartOption"
|
|
:options="inviTypesChartOption"
|
|
:options="inviTypesChartOption"
|
|
@@ -109,7 +118,9 @@
|
|
</table>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
<div class="invi-area-chart invi-chart">
|
|
<div class="invi-area-chart invi-chart">
|
|
- <div class="invi-chart-title">考生分布</div>
|
|
|
|
|
|
+ <div v-if="inviAreaChartOption" class="invi-chart-title">
|
|
|
|
+ 考生分布
|
|
|
|
+ </div>
|
|
<vue-charts
|
|
<vue-charts
|
|
v-if="inviAreaChartOption"
|
|
v-if="inviAreaChartOption"
|
|
:options="inviAreaChartOption"
|
|
:options="inviAreaChartOption"
|
|
@@ -152,8 +163,8 @@
|
|
<th>预警类型</th>
|
|
<th>预警类型</th>
|
|
<th>处理状态</th>
|
|
<th>处理状态</th>
|
|
</tr>
|
|
</tr>
|
|
- <tr v-for="item in inviStudentList" :key="item.id">
|
|
|
|
- <td>{{ item.createTime }}</td>
|
|
|
|
|
|
+ <tr v-for="item in inviStudentWainList" :key="item.id">
|
|
|
|
+ <td>{{ item.createTime | timeFilter }}</td>
|
|
<td>
|
|
<td>
|
|
<div class="td-cont" style="width: 60px;">
|
|
<div class="td-cont" style="width: 60px;">
|
|
{{ item.name }}
|
|
{{ item.name }}
|
|
@@ -161,7 +172,11 @@
|
|
</td>
|
|
</td>
|
|
<td>{{ item.identity }}</td>
|
|
<td>{{ item.identity }}</td>
|
|
<td>
|
|
<td>
|
|
- <div class="td-cont" style="width: 140px;">
|
|
|
|
|
|
+ <div
|
|
|
|
+ class="td-cont"
|
|
|
|
+ style="width: 140px;"
|
|
|
|
+ :title="item.info"
|
|
|
|
+ >
|
|
{{ item.info }}
|
|
{{ item.info }}
|
|
</div>
|
|
</div>
|
|
</td>
|
|
</td>
|
|
@@ -178,6 +193,7 @@
|
|
</template>
|
|
</template>
|
|
|
|
|
|
<script>
|
|
<script>
|
|
|
|
+import { mapState } from "vuex";
|
|
import TextClock from "../common/TextClock";
|
|
import TextClock from "../common/TextClock";
|
|
import InvigilationStudent from "../common/InvigilationStudent";
|
|
import InvigilationStudent from "../common/InvigilationStudent";
|
|
import VueCharts from "@/plugins/VueCharts";
|
|
import VueCharts from "@/plugins/VueCharts";
|
|
@@ -185,17 +201,27 @@ import {
|
|
getInviTypesOption,
|
|
getInviTypesOption,
|
|
getInviAreaOption,
|
|
getInviAreaOption,
|
|
getInviTimeOption,
|
|
getInviTimeOption,
|
|
|
|
+ getInviMapOption,
|
|
} from "./chartOpt";
|
|
} from "./chartOpt";
|
|
-
|
|
|
|
import {
|
|
import {
|
|
- students,
|
|
|
|
- summary,
|
|
|
|
- inviTypesList,
|
|
|
|
- inviTimeList,
|
|
|
|
- inviAreaList,
|
|
|
|
- inviMapList,
|
|
|
|
- inviStudentList,
|
|
|
|
-} from "./datas";
|
|
|
|
|
|
+ examInvigilationCount,
|
|
|
|
+ examInvigilationWarnDistribution,
|
|
|
|
+ examInvigilationWarnTrend,
|
|
|
|
+ examInvigilationVideoRandomList,
|
|
|
|
+ examInvigilationWarnMessage,
|
|
|
|
+ examinationMonitorMapList,
|
|
|
|
+ examinationMonitorAreaList,
|
|
|
|
+} from "@/api/invigilation";
|
|
|
|
+
|
|
|
|
+// import {
|
|
|
|
+// students,
|
|
|
|
+// summary,
|
|
|
|
+// inviTypesList,
|
|
|
|
+// inviTimeList,
|
|
|
|
+// inviAreaList,
|
|
|
|
+// inviMapList,
|
|
|
|
+// inviStudentList,
|
|
|
|
+// } from "./datas";
|
|
|
|
|
|
export default {
|
|
export default {
|
|
name: "exam-invigilation-full",
|
|
name: "exam-invigilation-full",
|
|
@@ -203,7 +229,6 @@ export default {
|
|
data() {
|
|
data() {
|
|
return {
|
|
return {
|
|
schoolName: "",
|
|
schoolName: "",
|
|
- students: [],
|
|
|
|
summary: {
|
|
summary: {
|
|
onlineCount: "",
|
|
onlineCount: "",
|
|
waitingCount: "",
|
|
waitingCount: "",
|
|
@@ -214,35 +239,168 @@ export default {
|
|
name: "",
|
|
name: "",
|
|
code: "",
|
|
code: "",
|
|
},
|
|
},
|
|
|
|
+ studentVideoList: [],
|
|
inviMapList: [],
|
|
inviMapList: [],
|
|
|
|
+ inviMapChartOption: null,
|
|
inviTypesList: [],
|
|
inviTypesList: [],
|
|
inviTypesChartOption: null,
|
|
inviTypesChartOption: null,
|
|
inviAreaList: [],
|
|
inviAreaList: [],
|
|
inviAreaChartOption: null,
|
|
inviAreaChartOption: null,
|
|
inviTimeList: [],
|
|
inviTimeList: [],
|
|
inviTimeChartOption: null,
|
|
inviTimeChartOption: null,
|
|
- inviStudentList: [],
|
|
|
|
|
|
+ inviStudentWainList: [],
|
|
|
|
+ curMapAreaInd: 0,
|
|
|
|
+ // setTs
|
|
|
|
+ setTsMap: {
|
|
|
|
+ summary: [],
|
|
|
|
+ common: [],
|
|
|
|
+ studengWain: [],
|
|
|
|
+ timeTrend: [],
|
|
|
|
+ areaMap: [],
|
|
|
|
+ areaMapDet: [],
|
|
|
|
+ },
|
|
};
|
|
};
|
|
},
|
|
},
|
|
|
|
+ computed: {
|
|
|
|
+ ...mapState("invigilation", ["liveDomains"]),
|
|
|
|
+ },
|
|
mounted() {
|
|
mounted() {
|
|
- this.students = students;
|
|
|
|
- this.summary = summary;
|
|
|
|
- this.inviMapList = inviMapList;
|
|
|
|
- this.parseInviTypesList(inviTypesList);
|
|
|
|
- this.parseInviAreaList(inviAreaList);
|
|
|
|
- this.parseInviTimeList(inviTimeList);
|
|
|
|
- this.inviStudentList = inviStudentList;
|
|
|
|
|
|
+ // this.studentVideoList = students;
|
|
|
|
+ // this.summary = summary;
|
|
|
|
+ // this.parseMapList(inviMapList);
|
|
|
|
+ // this.parseInviTypesList(inviTypesList);
|
|
|
|
+ // this.parseInviAreaList(inviAreaList);
|
|
|
|
+ // this.parseInviTimeList(inviTimeList);
|
|
|
|
+ // this.inviStudentWainList = inviStudentList;
|
|
|
|
+ this.initData();
|
|
|
|
+ },
|
|
|
|
+ beforeDestroy() {
|
|
|
|
+ this.clearSetTs();
|
|
},
|
|
},
|
|
methods: {
|
|
methods: {
|
|
|
|
+ initData() {
|
|
|
|
+ this.intervalSummary();
|
|
|
|
+ this.intervalCommonData();
|
|
|
|
+ this.intervalStudentWain();
|
|
|
|
+ this.intervalTimeTrend();
|
|
|
|
+ this.intervalMap();
|
|
|
|
+ },
|
|
|
|
+ addSetTime(typeName, action, time = 1 * 1000) {
|
|
|
|
+ this.setTsMap[typeName].push(setTimeout(action, time));
|
|
|
|
+ },
|
|
|
|
+ clearSetTs(typeName) {
|
|
|
|
+ if (typeName) {
|
|
|
|
+ if (!this.setTsMap[typeName] || !this.setTsMap[typeName].length) return;
|
|
|
|
+ this.setTsMap[typeName].forEach((t) => clearTimeout(t));
|
|
|
|
+ this.setTsMap[typeName] = [];
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+ Object.keys(this.setTsMap).forEach((k) => {
|
|
|
|
+ this.setTsMap[k].forEach((t) => clearTimeout(t));
|
|
|
|
+ this.setTsMap[k] = [];
|
|
|
|
+ });
|
|
|
|
+ },
|
|
videoAllMuted() {
|
|
videoAllMuted() {
|
|
this.$refs.InvigilationStudent.forEach((refInst) => {
|
|
this.$refs.InvigilationStudent.forEach((refInst) => {
|
|
refInst.mutedPlayer(true);
|
|
refInst.mutedPlayer(true);
|
|
});
|
|
});
|
|
},
|
|
},
|
|
|
|
+ // interval
|
|
|
|
+ async intervalSummary() {
|
|
|
|
+ const typeName = "summary";
|
|
|
|
+ this.clearSetTs(typeName);
|
|
|
|
+
|
|
|
|
+ await this.getSummary();
|
|
|
|
+ this.addSetTime(typeName, this.intervalSummary, 3 * 1000);
|
|
|
|
+ },
|
|
|
|
+ async intervalCommonData() {
|
|
|
|
+ const typeName = "common";
|
|
|
|
+ this.clearSetTs(typeName);
|
|
|
|
+
|
|
|
|
+ await this.getInviTypesList();
|
|
|
|
+ await this.getInviAreaList();
|
|
|
|
+ await this.getStudentVideoList();
|
|
|
|
+
|
|
|
|
+ this.addSetTime(typeName, this.intervalCommonData, 10 * 1000);
|
|
|
|
+ },
|
|
|
|
+ async intervalStudentWain() {
|
|
|
|
+ const typeName = "studengWain";
|
|
|
|
+ this.clearSetTs(typeName);
|
|
|
|
+
|
|
|
|
+ await this.getStudentWainList();
|
|
|
|
+ this.addSetTime(typeName, this.intervalStudentWain, 5 * 1000);
|
|
|
|
+ },
|
|
|
|
+ async intervalTimeTrend() {
|
|
|
|
+ const typeName = "timeTrend";
|
|
|
|
+ this.clearSetTs(typeName);
|
|
|
|
+
|
|
|
|
+ await this.getInviTimeList();
|
|
|
|
+ this.addSetTime(typeName, this.intervalTimeTrend, 60 * 1000);
|
|
|
|
+ },
|
|
|
|
+ async intervalMap() {
|
|
|
|
+ const typeName = "areaMap";
|
|
|
|
+ this.clearSetTs(typeName);
|
|
|
|
+
|
|
|
|
+ await this.getMapList();
|
|
|
|
+ this.intervalMapDet();
|
|
|
|
+ let inTime = this.inviMapList.length * 3 * 1000;
|
|
|
|
+ inTime = inTime || 3 * 1000;
|
|
|
|
+ this.addSetTime(typeName, this.intervalMap, inTime);
|
|
|
|
+ },
|
|
|
|
+ intervalMapDet() {
|
|
|
|
+ if (!this.inviMapList.length) return;
|
|
|
|
+ const typeName = "areaMapDet";
|
|
|
|
+ this.clearSetTs(typeName);
|
|
|
|
+
|
|
|
|
+ if (this.curMapAreaInd >= this.inviMapList.length - 1) {
|
|
|
|
+ this.curMapAreaInd = 0;
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+ this.inviMapList.forEach((item) => {
|
|
|
|
+ item.selected = false;
|
|
|
|
+ });
|
|
|
|
+ this.inviMapList[this.curMapAreaInd].selected = true;
|
|
|
|
+ this.inviMapChartOption = getInviMapOption(this.inviMapList);
|
|
|
|
+ this.curMapAreaInd++;
|
|
|
|
+ this.addSetTime(typeName, this.intervalMapDet, 3 * 1000);
|
|
|
|
+ },
|
|
|
|
+ // fetch action
|
|
getMaxNum(nums) {
|
|
getMaxNum(nums) {
|
|
return Math.max.apply(null, nums);
|
|
return Math.max.apply(null, nums);
|
|
},
|
|
},
|
|
- parseInviTypesList(dataList) {
|
|
|
|
|
|
+ async getSummary() {
|
|
|
|
+ // interval 3s
|
|
|
|
+ const res = await examInvigilationCount();
|
|
|
|
+ const data = res.data.data;
|
|
|
|
+ this.summary = Object.assign({}, this.summary, data);
|
|
|
|
+ },
|
|
|
|
+ async getStudentVideoList() {
|
|
|
|
+ // interval 10s
|
|
|
|
+ const res = await examInvigilationVideoRandomList({ randomNum: 4 });
|
|
|
|
+ const domainLen = this.liveDomains.length;
|
|
|
|
+ this.studentVideoList = 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;
|
|
|
|
+ });
|
|
|
|
+ },
|
|
|
|
+ async getMapList() {
|
|
|
|
+ // interval 60s
|
|
|
|
+ const res = await examinationMonitorMapList();
|
|
|
|
+ const dataList = res.data.data;
|
|
|
|
+ this.inviMapList = dataList.map((item) => {
|
|
|
|
+ item.selected = false;
|
|
|
|
+ return item;
|
|
|
|
+ });
|
|
|
|
+ // this.inviMapChartOption = getInviMapOption(dataList);
|
|
|
|
+ },
|
|
|
|
+ async getInviTypesList() {
|
|
|
|
+ // interval 10s
|
|
|
|
+ const res = await examInvigilationWarnDistribution();
|
|
|
|
+ const dataList = res.data.data;
|
|
const maxNum = this.getMaxNum(dataList.map((item) => item.warnCount));
|
|
const maxNum = this.getMaxNum(dataList.map((item) => item.warnCount));
|
|
this.inviTypesList = dataList.map((item) => {
|
|
this.inviTypesList = dataList.map((item) => {
|
|
return {
|
|
return {
|
|
@@ -252,7 +410,10 @@ export default {
|
|
});
|
|
});
|
|
this.inviTypesChartOption = getInviTypesOption(this.inviTypesList);
|
|
this.inviTypesChartOption = getInviTypesOption(this.inviTypesList);
|
|
},
|
|
},
|
|
- parseInviAreaList(dataList) {
|
|
|
|
|
|
+ async getInviAreaList() {
|
|
|
|
+ // interval 10s
|
|
|
|
+ const res = await examinationMonitorAreaList();
|
|
|
|
+ const dataList = res.data.data;
|
|
const maxNum = this.getMaxNum(dataList.map((item) => item.warnCount));
|
|
const maxNum = this.getMaxNum(dataList.map((item) => item.warnCount));
|
|
this.inviAreaList = dataList.map((item) => {
|
|
this.inviAreaList = dataList.map((item) => {
|
|
return {
|
|
return {
|
|
@@ -262,10 +423,19 @@ export default {
|
|
});
|
|
});
|
|
this.inviAreaChartOption = getInviAreaOption(this.inviAreaList);
|
|
this.inviAreaChartOption = getInviAreaOption(this.inviAreaList);
|
|
},
|
|
},
|
|
- parseInviTimeList(dataList) {
|
|
|
|
|
|
+ async getInviTimeList() {
|
|
|
|
+ // interval 60s
|
|
|
|
+ const res = await examInvigilationWarnTrend();
|
|
|
|
+ const dataList = res.data.data;
|
|
this.inviTimeList = dataList;
|
|
this.inviTimeList = dataList;
|
|
this.inviTimeChartOption = getInviTimeOption(dataList);
|
|
this.inviTimeChartOption = getInviTimeOption(dataList);
|
|
},
|
|
},
|
|
|
|
+ async getStudentWainList() {
|
|
|
|
+ // // interval 5s
|
|
|
|
+ const res = await examInvigilationWarnMessage();
|
|
|
|
+ const dataList = res.data.data;
|
|
|
|
+ this.inviStudentWainList = dataList;
|
|
|
|
+ },
|
|
},
|
|
},
|
|
};
|
|
};
|
|
</script>
|
|
</script>
|