|
@@ -49,6 +49,7 @@
|
|
data-type="trouble"
|
|
data-type="trouble"
|
|
:exam-id="filter.examId"
|
|
:exam-id="filter.examId"
|
|
v-if="filter.examId"
|
|
v-if="filter.examId"
|
|
|
|
+ ref="SummaryLine"
|
|
></summary-line>
|
|
></summary-line>
|
|
<div class="part-filter-info-sub" v-if="!this.IS_INSPECTION">
|
|
<div class="part-filter-info-sub" v-if="!this.IS_INSPECTION">
|
|
<el-badge
|
|
<el-badge
|
|
@@ -218,10 +219,13 @@
|
|
</span>
|
|
</span>
|
|
</template>
|
|
</template>
|
|
</el-table-column>
|
|
</el-table-column>
|
|
- <el-table-column label="操作" width="100">
|
|
|
|
|
|
+ <el-table-column label="操作" width="125">
|
|
<template slot-scope="scope">
|
|
<template slot-scope="scope">
|
|
<el-button
|
|
<el-button
|
|
- class="btn-table-icon"
|
|
|
|
|
|
+ :class="[
|
|
|
|
+ 'btn-table-icon',
|
|
|
|
+ { 'warn-new-tips': scope.row.warningNew },
|
|
|
|
+ ]"
|
|
type="primary"
|
|
type="primary"
|
|
icon="icon icon-view"
|
|
icon="icon icon-view"
|
|
@click="toDetail(scope.row)"
|
|
@click="toDetail(scope.row)"
|
|
@@ -233,7 +237,7 @@
|
|
<div class="invigilation-student-list" v-else>
|
|
<div class="invigilation-student-list" v-else>
|
|
<div
|
|
<div
|
|
class="invigilation-student-item"
|
|
class="invigilation-student-item"
|
|
- v-for="item in videoList"
|
|
|
|
|
|
+ v-for="item in dataList"
|
|
:key="item.examStudentId"
|
|
:key="item.examStudentId"
|
|
>
|
|
>
|
|
<invigilation-student :data="item"></invigilation-student>
|
|
<invigilation-student :data="item"></invigilation-student>
|
|
@@ -288,7 +292,7 @@ import {
|
|
CLIENT_WEBSOCKET_STATUS,
|
|
CLIENT_WEBSOCKET_STATUS,
|
|
MONITOR_STATUS_SOURCE,
|
|
MONITOR_STATUS_SOURCE,
|
|
} from "@/constant/constants";
|
|
} from "@/constant/constants";
|
|
-import { mapActions } from "vuex";
|
|
|
|
|
|
+import { mapMutations, mapActions } from "vuex";
|
|
|
|
|
|
export default {
|
|
export default {
|
|
name: "realtime-monitoring",
|
|
name: "realtime-monitoring",
|
|
@@ -319,14 +323,15 @@ export default {
|
|
MONITOR_STATUS_SOURCE,
|
|
MONITOR_STATUS_SOURCE,
|
|
IS_INSPECTION: false,
|
|
IS_INSPECTION: false,
|
|
hasNewWarning: false,
|
|
hasNewWarning: false,
|
|
|
|
+ loopRunning: false,
|
|
|
|
+ loopSetTs: [],
|
|
communicationCount: 0,
|
|
communicationCount: 0,
|
|
curExamBatch: {},
|
|
curExamBatch: {},
|
|
curViewingAngle: {},
|
|
curViewingAngle: {},
|
|
noticeCaches: {},
|
|
noticeCaches: {},
|
|
- setT: null,
|
|
|
|
current: 1,
|
|
current: 1,
|
|
total: 0,
|
|
total: 0,
|
|
- size: 100,
|
|
|
|
|
|
+ size: 24,
|
|
multipleSelection: [],
|
|
multipleSelection: [],
|
|
batchId: "",
|
|
batchId: "",
|
|
batchs: [],
|
|
batchs: [],
|
|
@@ -334,7 +339,6 @@ export default {
|
|
subjects: [],
|
|
subjects: [],
|
|
pageType: "0",
|
|
pageType: "0",
|
|
dataList: [],
|
|
dataList: [],
|
|
- videoList: [],
|
|
|
|
viewingAngles: [
|
|
viewingAngles: [
|
|
{
|
|
{
|
|
code: "1",
|
|
code: "1",
|
|
@@ -363,7 +367,49 @@ export default {
|
|
};
|
|
};
|
|
},
|
|
},
|
|
methods: {
|
|
methods: {
|
|
- ...mapActions("invigilation", ["setDetailIds"]),
|
|
|
|
|
|
+ ...mapActions("invigilation", ["updateDetailIds"]),
|
|
|
|
+ ...mapMutations("invigilation", ["setDetailIds"]),
|
|
|
|
+ clearLoopSetTs() {
|
|
|
|
+ if (!this.loopSetTs.length) return;
|
|
|
|
+ this.loopSetTs.forEach((sett) => {
|
|
|
|
+ clearTimeout(sett);
|
|
|
|
+ });
|
|
|
|
+ this.loopSetTs = [];
|
|
|
|
+ },
|
|
|
|
+ async timerUpdatePage() {
|
|
|
|
+ this.clearLoopSetTs();
|
|
|
|
+ if (!this.loopRunning) return;
|
|
|
|
+
|
|
|
|
+ await this.getList().catch(() => {});
|
|
|
|
+ await this.$refs.SummaryLine.initData().catch(() => {});
|
|
|
|
+ if (!this.IS_INSPECTION) {
|
|
|
|
+ await this.getMonitorCallCount().catch(() => {});
|
|
|
|
+ await this.fetchWarningNotice().catch(() => {});
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ this.loopSetTs.push(
|
|
|
|
+ setTimeout(() => {
|
|
|
|
+ this.timerUpdatePage();
|
|
|
|
+ }, 10 * 1000)
|
|
|
|
+ );
|
|
|
|
+ },
|
|
|
|
+ examChange(examBatch) {
|
|
|
|
+ if (!examBatch) return;
|
|
|
|
+ this.filter.examId = examBatch.id;
|
|
|
|
+ this.curExamBatch = examBatch;
|
|
|
|
+ this.toSearch();
|
|
|
|
+
|
|
|
|
+ this.timerUpdatePage();
|
|
|
|
+ },
|
|
|
|
+ pageTypeChange(pageType) {
|
|
|
|
+ this.pageType = pageType;
|
|
|
|
+ this.toPage(1);
|
|
|
|
+ this.multipleSelection = [];
|
|
|
|
+ },
|
|
|
|
+ viewingAngleChange(data) {
|
|
|
|
+ this.curViewingAngle = data;
|
|
|
|
+ // TODO:视角切换
|
|
|
|
+ },
|
|
async getList() {
|
|
async getList() {
|
|
const datas = {
|
|
const datas = {
|
|
...this.filter,
|
|
...this.filter,
|
|
@@ -380,51 +426,65 @@ export default {
|
|
});
|
|
});
|
|
} else {
|
|
} else {
|
|
res = await invigilateVideoList(datas);
|
|
res = await invigilateVideoList(datas);
|
|
- this.videoList = res.data.data.records.map((item) => {
|
|
|
|
|
|
+ this.dataList = res.data.data.records.map((item) => {
|
|
item.liveUrl = `http://live.qmth.com.cn/live/${item.monitorLiveUrl.toLowerCase()}.flv`;
|
|
item.liveUrl = `http://live.qmth.com.cn/live/${item.monitorLiveUrl.toLowerCase()}.flv`;
|
|
return item;
|
|
return item;
|
|
});
|
|
});
|
|
}
|
|
}
|
|
- const ids = res.data.data.records.map((item) => item.examRecordId);
|
|
|
|
- this.setDetailIds([...new Set(ids)]);
|
|
|
|
-
|
|
|
|
this.total = res.data.data.total;
|
|
this.total = res.data.data.total;
|
|
},
|
|
},
|
|
toPage(page) {
|
|
toPage(page) {
|
|
this.current = page;
|
|
this.current = page;
|
|
this.getList();
|
|
this.getList();
|
|
},
|
|
},
|
|
- toSearch() {
|
|
|
|
- this.toPage(1);
|
|
|
|
|
|
+ async toSearch() {
|
|
|
|
+ this.current = 1;
|
|
|
|
+ await this.getList();
|
|
|
|
+
|
|
|
|
+ if (this.total > this.size) {
|
|
|
|
+ this.updateDetailIds({
|
|
|
|
+ filterData: this.filter,
|
|
|
|
+ fetchFunc: invigilateList,
|
|
|
|
+ });
|
|
|
|
+ } else {
|
|
|
|
+ const ids = this.dataList.map((item) => item.examRecordId);
|
|
|
|
+ this.setDetailIds([...new Set(ids)]);
|
|
|
|
+ }
|
|
},
|
|
},
|
|
async getMonitorCallCount() {
|
|
async getMonitorCallCount() {
|
|
if (!this.filter.examId) return;
|
|
if (!this.filter.examId) return;
|
|
const res = await monitorCallCount(this.filter.examId);
|
|
const res = await monitorCallCount(this.filter.examId);
|
|
this.communicationCount = res.data.data.count || 0;
|
|
this.communicationCount = res.data.data.count || 0;
|
|
},
|
|
},
|
|
- examChange(examBatch) {
|
|
|
|
- if (!examBatch) return;
|
|
|
|
- this.filter.examId = examBatch.id;
|
|
|
|
- this.curExamBatch = examBatch;
|
|
|
|
- this.toSearch();
|
|
|
|
- if (this.IS_INSPECTION) return;
|
|
|
|
|
|
+ async fetchWarningNotice() {
|
|
|
|
+ if (!this.filter.examId) return;
|
|
|
|
|
|
- this.getMonitorCallCount();
|
|
|
|
- this.fetchWarningNotice();
|
|
|
|
- },
|
|
|
|
- pageTypeChange(pageType) {
|
|
|
|
- this.pageType = pageType;
|
|
|
|
- this.toPage(1);
|
|
|
|
- this.multipleSelection = [];
|
|
|
|
|
|
+ const res = await invigilationWarningMessage(this.filter.examId);
|
|
|
|
+ res.data.data.forEach((item) => {
|
|
|
|
+ const stdKey = item.examRecordId;
|
|
|
|
+ if (!this.noticeCaches[stdKey]) {
|
|
|
|
+ this.noticeCaches[stdKey] = item;
|
|
|
|
+ this.$notify({
|
|
|
|
+ duration: 5 * 1000,
|
|
|
|
+ dangerouslyUseHTMLString: true,
|
|
|
|
+ customClass: "msg-monitor-magbox",
|
|
|
|
+ position: "bottom-right",
|
|
|
|
+ offset: 50,
|
|
|
|
+ message: `
|
|
|
|
+ <div class="msg-monitor">
|
|
|
|
+ <span class="msg-monitor-icon"><i class="icon icon-warning"></i></span>
|
|
|
|
+ <span>注意:<b>${item.name}</b>发现违纪,</span>
|
|
|
|
+ <span class="msg-monitor-action" onclick="window.inviligateWarning('${item.examRecordId}')">立即处理</span>
|
|
|
|
+ </div>
|
|
|
|
+ `,
|
|
|
|
+ });
|
|
|
|
+ }
|
|
|
|
+ });
|
|
},
|
|
},
|
|
handleSelectionChange(val) {
|
|
handleSelectionChange(val) {
|
|
console.log(val);
|
|
console.log(val);
|
|
this.multipleSelection = val;
|
|
this.multipleSelection = val;
|
|
},
|
|
},
|
|
- viewingAngleChange(data) {
|
|
|
|
- this.curViewingAngle = data;
|
|
|
|
- // TODO:视角切换
|
|
|
|
- },
|
|
|
|
async finishInvigilation() {
|
|
async finishInvigilation() {
|
|
if (!this.multipleSelection.length) {
|
|
if (!this.multipleSelection.length) {
|
|
this.$message.error("请先选择数据!");
|
|
this.$message.error("请先选择数据!");
|
|
@@ -465,36 +525,6 @@ export default {
|
|
},
|
|
},
|
|
});
|
|
});
|
|
},
|
|
},
|
|
- async fetchWarningNotice() {
|
|
|
|
- if (this.setT) clearTimeout(this.setT);
|
|
|
|
- if (!this.filter.examId) return;
|
|
|
|
-
|
|
|
|
- const res = await invigilationWarningMessage(this.filter.examId);
|
|
|
|
- res.data.data.forEach((item) => {
|
|
|
|
- const stdKey = item.examRecordId;
|
|
|
|
- if (!this.noticeCaches[stdKey]) {
|
|
|
|
- this.noticeCaches[stdKey] = item;
|
|
|
|
- this.$notify({
|
|
|
|
- duration: 5 * 1000,
|
|
|
|
- dangerouslyUseHTMLString: true,
|
|
|
|
- customClass: "msg-monitor-magbox",
|
|
|
|
- position: "bottom-right",
|
|
|
|
- offset: 50,
|
|
|
|
- message: `
|
|
|
|
- <div class="msg-monitor">
|
|
|
|
- <span class="msg-monitor-icon"><i class="icon icon-warning"></i></span>
|
|
|
|
- <span>注意:<b>${item.name}</b>发现违纪,</span>
|
|
|
|
- <span class="msg-monitor-action" onclick="window.inviligateWarning(${item.examRecordId})">立即处理</span>
|
|
|
|
- </div>
|
|
|
|
- `,
|
|
|
|
- });
|
|
|
|
- }
|
|
|
|
- });
|
|
|
|
-
|
|
|
|
- this.setT = setTimeout(() => {
|
|
|
|
- this.fetchWarningNotice();
|
|
|
|
- }, 10 * 1000);
|
|
|
|
- },
|
|
|
|
toDetail(row) {
|
|
toDetail(row) {
|
|
const routerName = this.IS_INSPECTION
|
|
const routerName = this.IS_INSPECTION
|
|
? "PatrolWarningDetail"
|
|
? "PatrolWarningDetail"
|
|
@@ -506,7 +536,8 @@ export default {
|
|
},
|
|
},
|
|
},
|
|
},
|
|
beforeDestroy() {
|
|
beforeDestroy() {
|
|
- if (this.setT) clearTimeout(this.setT);
|
|
|
|
|
|
+ this.loopRunning = false;
|
|
|
|
+ this.clearLoopSetTs();
|
|
delete window.inviligateWarning;
|
|
delete window.inviligateWarning;
|
|
},
|
|
},
|
|
};
|
|
};
|
|
@@ -627,4 +658,19 @@ export default {
|
|
width: 25%;
|
|
width: 25%;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
+.warn-new-tips {
|
|
|
|
+ position: relative;
|
|
|
|
+
|
|
|
|
+ &::after {
|
|
|
|
+ content: "";
|
|
|
|
+ display: block;
|
|
|
|
+ position: absolute;
|
|
|
|
+ width: 32px;
|
|
|
|
+ height: 16px;
|
|
|
|
+ right: -32px;
|
|
|
|
+ top: 0;
|
|
|
|
+ background-image: url(../../../assets/icon-new-tips.png);
|
|
|
|
+ background-size: 100% 100%;
|
|
|
|
+ }
|
|
|
|
+}
|
|
</style>
|
|
</style>
|