|
@@ -2,19 +2,27 @@
|
|
<div class="realtime-monitoring">
|
|
<div class="realtime-monitoring">
|
|
<div class="realtime-top clear-float">
|
|
<div class="realtime-top clear-float">
|
|
<p v-if="examName">考场名称:{{ examName }}</p>
|
|
<p v-if="examName">考场名称:{{ examName }}</p>
|
|
- <el-select
|
|
|
|
- v-model="filter.examId"
|
|
|
|
- placeholder="请选择批次"
|
|
|
|
- @change="examChange"
|
|
|
|
- clearable
|
|
|
|
|
|
+ <div
|
|
|
|
+ class="el-select el-select--small"
|
|
|
|
+ @click="$refs.ExamBatchDialog.open()"
|
|
>
|
|
>
|
|
- <el-option
|
|
|
|
- v-for="item in exams"
|
|
|
|
- :key="item.id"
|
|
|
|
- :value="item.id"
|
|
|
|
- :label="item.name"
|
|
|
|
- ></el-option>
|
|
|
|
- </el-select>
|
|
|
|
|
|
+ <div class="el-input el-input--small el-input--suffix">
|
|
|
|
+ <input
|
|
|
|
+ type="text"
|
|
|
|
+ readonly="readonly"
|
|
|
|
+ autocomplete="off"
|
|
|
|
+ placeholder="请选择批次"
|
|
|
|
+ v-model="curExamBatch.label"
|
|
|
|
+ class="el-input__inner"
|
|
|
|
+ />
|
|
|
|
+ <span class="el-input__suffix">
|
|
|
|
+ <span class="el-input__suffix-inner"
|
|
|
|
+ ><i
|
|
|
|
+ class="el-select__caret el-input__icon el-icon-arrow-up"
|
|
|
|
+ ></i></span
|
|
|
|
+ ></span>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
<p>现在是2020年6月2日 星期二 上午 09:30:12</p>
|
|
<p>现在是2020年6月2日 星期二 上午 09:30:12</p>
|
|
</div>
|
|
</div>
|
|
|
|
|
|
@@ -23,7 +31,11 @@
|
|
<h1>实时监控台</h1>
|
|
<h1>实时监控台</h1>
|
|
</div>
|
|
</div>
|
|
<div class="part-box-head-right">
|
|
<div class="part-box-head-right">
|
|
- <el-radio-group size="small" v-model="pageType">
|
|
|
|
|
|
+ <el-radio-group
|
|
|
|
+ size="small"
|
|
|
|
+ v-model="pageType"
|
|
|
|
+ @change="pageTypeChange"
|
|
|
|
+ >
|
|
<el-radio-button label="0">
|
|
<el-radio-button label="0">
|
|
<i class="el-icon-s-fold"></i>列表</el-radio-button
|
|
<i class="el-icon-s-fold"></i>列表</el-radio-button
|
|
>
|
|
>
|
|
@@ -38,20 +50,52 @@
|
|
<div class="part-filter-info">
|
|
<div class="part-filter-info">
|
|
<div class="part-filter-info-main summary-line">
|
|
<div class="part-filter-info-main summary-line">
|
|
<p class="summary-line-item">
|
|
<p class="summary-line-item">
|
|
- <i class="icon icon-users"></i
|
|
|
|
- ><span class="line-name">全部应考</span><span>50人</span>
|
|
|
|
|
|
+ <i class="icon icon-users"></i>
|
|
|
|
+ <el-popover
|
|
|
|
+ placement="top-start"
|
|
|
|
+ width="200"
|
|
|
|
+ trigger="hover"
|
|
|
|
+ content="全部应考:参加考试的全部考生。"
|
|
|
|
+ >
|
|
|
|
+ <span class="line-name" slot="reference">全部应考</span>
|
|
|
|
+ </el-popover>
|
|
|
|
+ <span>{{ examPropData.allCount }}人</span>
|
|
</p>
|
|
</p>
|
|
<p class="summary-line-item">
|
|
<p class="summary-line-item">
|
|
- <i class="line-point line-point-info"></i
|
|
|
|
- ><span class="line-name">已登录</span><span>5人</span>
|
|
|
|
|
|
+ <i class="line-point line-point-info"></i>
|
|
|
|
+ <el-popover
|
|
|
|
+ placement="top-start"
|
|
|
|
+ width="200"
|
|
|
|
+ trigger="hover"
|
|
|
|
+ content="已登录:已成功登录考生端的考生。"
|
|
|
|
+ >
|
|
|
|
+ <span class="line-name" slot="reference">已登录</span>
|
|
|
|
+ </el-popover>
|
|
|
|
+ <span>{{ examPropData.loginCount }}人</span>
|
|
</p>
|
|
</p>
|
|
<p class="summary-line-item">
|
|
<p class="summary-line-item">
|
|
- <i class="line-point line-point-success"></i
|
|
|
|
- ><span class="line-name">已待考</span><span>3人</span>
|
|
|
|
|
|
+ <i class="line-point line-point-success"></i>
|
|
|
|
+ <el-popover
|
|
|
|
+ placement="top-start"
|
|
|
|
+ width="200"
|
|
|
|
+ trigger="hover"
|
|
|
|
+ content="已待考:已进入待考界面等待开考的考生。"
|
|
|
|
+ >
|
|
|
|
+ <span class="line-name" slot="reference">已待考</span>
|
|
|
|
+ </el-popover>
|
|
|
|
+ <span>{{ examPropData.prepareCount }}人</span>
|
|
</p>
|
|
</p>
|
|
<p class="summary-line-item">
|
|
<p class="summary-line-item">
|
|
- <i class="line-point line-point-primary"></i
|
|
|
|
- ><span class="line-name">考试中</span><span>2人</span>
|
|
|
|
|
|
+ <i class="line-point line-point-primary"></i>
|
|
|
|
+ <el-popover
|
|
|
|
+ placement="top-start"
|
|
|
|
+ width="200"
|
|
|
|
+ trigger="hover"
|
|
|
|
+ content="考试中:正在答题的考生。"
|
|
|
|
+ >
|
|
|
|
+ <span class="line-name" slot="reference">考试中</span>
|
|
|
|
+ </el-popover>
|
|
|
|
+ <span>{{ examPropData.notComplete }}人</span>
|
|
</p>
|
|
</p>
|
|
<p class="summary-line-item">
|
|
<p class="summary-line-item">
|
|
<i class="line-point line-point-danger"></i>
|
|
<i class="line-point line-point-danger"></i>
|
|
@@ -59,7 +103,7 @@
|
|
placement="top-start"
|
|
placement="top-start"
|
|
width="200"
|
|
width="200"
|
|
trigger="hover"
|
|
trigger="hover"
|
|
- content="这是一段内容,这是一段内容,这是一段内容,这是一段内容。"
|
|
|
|
|
|
+ content="通讯故障:考生端出现断网、断电、软硬件故障等异常导致考生端与监考端无法正常连接的考生。"
|
|
>
|
|
>
|
|
<span class="line-name" slot="reference">通讯故障</span>
|
|
<span class="line-name" slot="reference">通讯故障</span>
|
|
</el-popover>
|
|
</el-popover>
|
|
@@ -144,17 +188,47 @@
|
|
</el-form>
|
|
</el-form>
|
|
|
|
|
|
<div class="part-filter-form-action">
|
|
<div class="part-filter-form-action">
|
|
- <el-button type="primary" icon="icon icon-handle" @click="cleanUnread"
|
|
|
|
|
|
+ <el-dropdown
|
|
|
|
+ @command="viewingAngleChange"
|
|
|
|
+ style="margin-right: 10px;"
|
|
|
|
+ v-if="pageType === '1'"
|
|
|
|
+ >
|
|
|
|
+ <el-button type="primary"
|
|
|
|
+ >{{ curViewingAngle.name || "切换视角"
|
|
|
|
+ }}<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
|
|
|
|
+ >
|
|
|
|
+ </el-dropdown-menu>
|
|
|
|
+ </el-dropdown>
|
|
|
|
+ <el-button
|
|
|
|
+ type="primary"
|
|
|
|
+ icon="icon icon-handle"
|
|
|
|
+ @click="finishInvigilation"
|
|
>手动收卷</el-button
|
|
>手动收卷</el-button
|
|
>
|
|
>
|
|
- <el-button type="danger" icon="icon icon-over" @click="batchAction"
|
|
|
|
|
|
+ <el-button
|
|
|
|
+ type="danger"
|
|
|
|
+ icon="icon icon-over"
|
|
|
|
+ @click="finishInvigilationExam"
|
|
>结束监考</el-button
|
|
>结束监考</el-button
|
|
>
|
|
>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
|
|
- <el-table ref="TableList" :data="dataList">
|
|
|
|
|
|
+ <el-table
|
|
|
|
+ ref="TableList"
|
|
|
|
+ :data="dataList"
|
|
|
|
+ @selection-change="handleSelectionChange"
|
|
|
|
+ v-if="pageType === '0'"
|
|
|
|
+ >
|
|
|
|
+ <el-table-column type="selection" width="55"> </el-table-column>
|
|
<el-table-column prop="identity" label="证件号"></el-table-column>
|
|
<el-table-column prop="identity" label="证件号"></el-table-column>
|
|
<el-table-column prop="name" label="姓名"></el-table-column>
|
|
<el-table-column prop="name" label="姓名"></el-table-column>
|
|
<el-table-column prop="courseName" label="科目名称"></el-table-column>
|
|
<el-table-column prop="courseName" label="科目名称"></el-table-column>
|
|
@@ -184,6 +258,16 @@
|
|
</template>
|
|
</template>
|
|
</el-table-column>
|
|
</el-table-column>
|
|
</el-table>
|
|
</el-table>
|
|
|
|
+ <div class="invigilation-student-list" v-else>
|
|
|
|
+ <div
|
|
|
|
+ class="invigilation-student-item"
|
|
|
|
+ v-for="item in dataList"
|
|
|
|
+ :key="item.examStudentId"
|
|
|
|
+ >
|
|
|
|
+ <invigilation-student :data="item"></invigilation-student>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+
|
|
<div class="part-page">
|
|
<div class="part-page">
|
|
<el-pagination
|
|
<el-pagination
|
|
background
|
|
background
|
|
@@ -195,14 +279,28 @@
|
|
>
|
|
>
|
|
</el-pagination>
|
|
</el-pagination>
|
|
</div>
|
|
</div>
|
|
|
|
+
|
|
|
|
+ <exam-batch-dialog
|
|
|
|
+ @confirm="examChange"
|
|
|
|
+ ref="ExamBatchDialog"
|
|
|
|
+ ></exam-batch-dialog>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
</template>
|
|
|
|
|
|
<script>
|
|
<script>
|
|
-import { invigilateList, examList } from "@/api/invigilation";
|
|
|
|
|
|
+import {
|
|
|
|
+ invigilateList,
|
|
|
|
+ invigilateVideoList,
|
|
|
|
+ invigilateFinish,
|
|
|
|
+ invigilateExamFinish,
|
|
|
|
+ examPropCount,
|
|
|
|
+} from "@/api/invigilation";
|
|
|
|
+import ExamBatchDialog from "./ExamBatchDialog";
|
|
|
|
+import InvigilationStudent from "../common/InvigilationStudent";
|
|
|
|
|
|
export default {
|
|
export default {
|
|
name: "realtime-monitoring",
|
|
name: "realtime-monitoring",
|
|
|
|
+ components: { ExamBatchDialog, InvigilationStudent },
|
|
data() {
|
|
data() {
|
|
return {
|
|
return {
|
|
filter: {
|
|
filter: {
|
|
@@ -215,34 +313,51 @@ export default {
|
|
minWarningCount: undefined,
|
|
minWarningCount: undefined,
|
|
},
|
|
},
|
|
examName: "",
|
|
examName: "",
|
|
|
|
+ curExamBatch: {},
|
|
|
|
+ curViewingAngle: {},
|
|
|
|
+ examPropData: {},
|
|
current: 1,
|
|
current: 1,
|
|
total: 0,
|
|
total: 0,
|
|
size: 10,
|
|
size: 10,
|
|
|
|
+ multipleSelection: [],
|
|
batchId: "",
|
|
batchId: "",
|
|
batchs: [],
|
|
batchs: [],
|
|
exams: [],
|
|
exams: [],
|
|
subjects: [],
|
|
subjects: [],
|
|
pageType: "0",
|
|
pageType: "0",
|
|
dataList: [],
|
|
dataList: [],
|
|
|
|
+ viewingAngles: [
|
|
|
|
+ {
|
|
|
|
+ code: "1",
|
|
|
|
+ name: "第一视角",
|
|
|
|
+ },
|
|
|
|
+ {
|
|
|
|
+ code: "2",
|
|
|
|
+ name: "第二视角",
|
|
|
|
+ },
|
|
|
|
+ {
|
|
|
|
+ code: "3",
|
|
|
|
+ name: "第三视角",
|
|
|
|
+ },
|
|
|
|
+ ],
|
|
};
|
|
};
|
|
},
|
|
},
|
|
- mounted() {
|
|
|
|
- this.initData();
|
|
|
|
- },
|
|
|
|
|
|
+ mounted() {},
|
|
methods: {
|
|
methods: {
|
|
- async initData() {
|
|
|
|
- await this.getExamList();
|
|
|
|
- this.filter.examId = this.exams[0] && this.exams[0].id;
|
|
|
|
- this.examChange();
|
|
|
|
- this.getList();
|
|
|
|
- },
|
|
|
|
async getList() {
|
|
async getList() {
|
|
const datas = {
|
|
const datas = {
|
|
...this.filter,
|
|
...this.filter,
|
|
pageNumber: this.current - 1,
|
|
pageNumber: this.current - 1,
|
|
pageSize: this.size,
|
|
pageSize: this.size,
|
|
};
|
|
};
|
|
- const res = await invigilateList(datas);
|
|
|
|
|
|
+
|
|
|
|
+ let res = null;
|
|
|
|
+ if (this.pageType === "0") {
|
|
|
|
+ res = await invigilateList(datas);
|
|
|
|
+ } else {
|
|
|
|
+ res = await invigilateVideoList(datas);
|
|
|
|
+ }
|
|
|
|
+
|
|
this.dataList = res.data.data.records;
|
|
this.dataList = res.data.data.records;
|
|
this.total = res.data.data.records.total;
|
|
this.total = res.data.data.records.total;
|
|
},
|
|
},
|
|
@@ -250,16 +365,57 @@ export default {
|
|
this.current = page;
|
|
this.current = page;
|
|
this.getList();
|
|
this.getList();
|
|
},
|
|
},
|
|
- examChange() {
|
|
|
|
- const exam = this.exams.find((item) => item.id === this.filter.examId);
|
|
|
|
- this.examName = exam.name;
|
|
|
|
|
|
+ async getExamPropCount() {
|
|
|
|
+ this.examPropData = await examPropCount(this.filter.examId);
|
|
|
|
+ },
|
|
|
|
+ examChange(examBatch) {
|
|
|
|
+ if (!examBatch) return;
|
|
|
|
+ this.filter.examId = examBatch.id;
|
|
|
|
+ this.curExamBatch = examBatch;
|
|
|
|
+ this.toPage(1);
|
|
},
|
|
},
|
|
- async getExamList() {
|
|
|
|
- const res = await examList({ pageNumber: 0, pageSize: 100 });
|
|
|
|
- this.exams = res.data.data.records;
|
|
|
|
|
|
+ pageTypeChange() {
|
|
|
|
+ this.toPage(1);
|
|
|
|
+ },
|
|
|
|
+ handleSelectionChange(val) {
|
|
|
|
+ console.log(val);
|
|
|
|
+ this.multipleSelection = val;
|
|
|
|
+ },
|
|
|
|
+ viewingAngleChange(data) {
|
|
|
|
+ this.curViewingAngle = data;
|
|
|
|
+ },
|
|
|
|
+ async finishInvigilation() {
|
|
|
|
+ const result = await this.$confirm("确定要手动收卷吗?", {
|
|
|
|
+ confirmButtonText: "确定",
|
|
|
|
+ cancelButtonText: "取消",
|
|
|
|
+ type: "confirm",
|
|
|
|
+ }).catch(() => {});
|
|
|
|
+
|
|
|
|
+ if (!result) return;
|
|
|
|
+
|
|
|
|
+ await invigilateFinish({ examRecordId: "", type: false });
|
|
|
|
+ this.toPage(1);
|
|
|
|
+ this.$message({
|
|
|
|
+ type: "success",
|
|
|
|
+ message: "操作成功!",
|
|
|
|
+ });
|
|
|
|
+ },
|
|
|
|
+ async finishInvigilationExam() {
|
|
|
|
+ const result = await this.$confirm("确定要结束监考吗?", {
|
|
|
|
+ confirmButtonText: "确定",
|
|
|
|
+ cancelButtonText: "取消",
|
|
|
|
+ type: "confirm",
|
|
|
|
+ }).catch(() => {});
|
|
|
|
+
|
|
|
|
+ if (!result) return;
|
|
|
|
+
|
|
|
|
+ await invigilateExamFinish();
|
|
|
|
+ this.toPage(1);
|
|
|
|
+ this.$message({
|
|
|
|
+ type: "success",
|
|
|
|
+ message: "操作成功!",
|
|
|
|
+ });
|
|
},
|
|
},
|
|
- cleanUnread() {},
|
|
|
|
- batchAction() {},
|
|
|
|
toCommunication() {
|
|
toCommunication() {
|
|
this.$router.push({ name: "VideoCommunication" });
|
|
this.$router.push({ name: "VideoCommunication" });
|
|
},
|
|
},
|
|
@@ -309,4 +465,18 @@ export default {
|
|
opacity: 0.8;
|
|
opacity: 0.8;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
+.invigilation-student-list {
|
|
|
|
+ background: #ffffff;
|
|
|
|
+ border-radius: 6px;
|
|
|
|
+ padding: 10px 10px;
|
|
|
|
+ font-size: 0;
|
|
|
|
+ min-height: 200px;
|
|
|
|
+ .invigilation-student-item {
|
|
|
|
+ font-size: 14px;
|
|
|
|
+ display: inline-block;
|
|
|
|
+ vertical-align: top;
|
|
|
|
+ padding: 10px;
|
|
|
|
+ width: 25%;
|
|
|
|
+ }
|
|
|
|
+}
|
|
</style>
|
|
</style>
|