examDetail.vue 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662
  1. <template>
  2. <el-container>
  3. <el-main class="el-main-padding">
  4. <commonFormVue :form="form" :getExamCondition="getExamCondition">
  5. <el-row v-show="showAllCondition">
  6. <el-col :span="6">
  7. <el-form-item label="采集人">
  8. <el-input
  9. class="form_search_width"
  10. size="small"
  11. v-model="form.infoCollector"
  12. placeholder="采集人"
  13. ></el-input>
  14. </el-form-item>
  15. </el-col>
  16. <el-col :span="12">
  17. <el-form-item label="开考时间">
  18. <el-date-picker
  19. class="input"
  20. v-model="startExamDatetimeRange"
  21. type="datetimerange"
  22. start-placeholder="开始日期"
  23. range-separator="至"
  24. end-placeholder="结束日期"
  25. value-format="yyyy/MM/dd HH:mm:ss"
  26. :clearable="false"
  27. size="small"
  28. @change="changeStartExamDatetimeRange"
  29. ></el-date-picker>
  30. </el-form-item>
  31. </el-col>
  32. </el-row>
  33. </commonFormVue>
  34. <el-col :span="24">
  35. <el-button
  36. @click="search('clickSelectBtn')"
  37. size="small"
  38. type="primary"
  39. icon="el-icon-search"
  40. >查询</el-button
  41. >
  42. <el-button
  43. size="small"
  44. type="primary"
  45. icon="el-icon-more"
  46. v-if="!showAllCondition"
  47. @click="showMoreCondition"
  48. >高级查询</el-button
  49. >
  50. <el-button
  51. size="small"
  52. type="primary"
  53. v-if="showAllCondition"
  54. @click="showSimpleCondition"
  55. >简单查询</el-button
  56. >
  57. <el-button
  58. size="small"
  59. icon="el-icon-refresh"
  60. @click="resetForm"
  61. class="margin-bottom-10"
  62. >重置</el-button
  63. >
  64. </el-col>
  65. <el-row>
  66. <el-col v-show="currentPagePrivileges.EXAM_DETAIL_EXPORT">
  67. <div class="block-seperator"></div>
  68. <span>操作:</span>
  69. <commonExportVue
  70. :form="form"
  71. :exportUrl="exportUrl"
  72. :exportFileName="exportFileName"
  73. ></commonExportVue>
  74. </el-col>
  75. </el-row>
  76. <el-row class="margin-top-10">
  77. <el-col :span="24">
  78. <el-table
  79. v-loading="tableLoading"
  80. element-loading-text="数据加载中"
  81. ref="multipleTable"
  82. @selection-change="handleSelectionChange"
  83. :data="tableData"
  84. border
  85. >
  86. <el-table-column label="考试ID" width="120">
  87. <template slot-scope="scope">
  88. <el-button
  89. v-show="
  90. scope.row.examType == 'ONLINE' &&
  91. currentPagePrivileges.SNAPSHOT_DETAILS
  92. "
  93. @click="gotoCaptureDetail(scope.row.dataId)"
  94. type="text"
  95. >{{ scope.row.dataId }}</el-button
  96. >
  97. <span
  98. v-show="
  99. scope.row.examType != 'ONLINE' ||
  100. !currentPagePrivileges.SNAPSHOT_DETAILS
  101. "
  102. >{{ scope.row.dataId }}</span
  103. >
  104. </template>
  105. </el-table-column>
  106. <el-table-column
  107. sortable
  108. label="学习中心"
  109. prop="orgName"
  110. width="120"
  111. ></el-table-column>
  112. <el-table-column
  113. sortable
  114. label="姓名"
  115. prop="studentName"
  116. width="120"
  117. ></el-table-column>
  118. <el-table-column
  119. sortable
  120. label="身份证号"
  121. prop="identityNumber"
  122. width="120"
  123. ></el-table-column>
  124. <el-table-column
  125. sortable
  126. label="学号"
  127. prop="studentCode"
  128. width="120"
  129. ></el-table-column>
  130. <el-table-column
  131. sortable
  132. label="课程"
  133. prop="courseNameAndCode"
  134. width="120"
  135. ></el-table-column>
  136. <el-table-column
  137. sortable
  138. label="课程层次"
  139. prop="courseLevel"
  140. width="120"
  141. ></el-table-column>
  142. <el-table-column
  143. sortable
  144. label="年级"
  145. prop="grade"
  146. width="120"
  147. ></el-table-column>
  148. <el-table-column
  149. sortable
  150. label="学生电话"
  151. prop="phone"
  152. width="120"
  153. ></el-table-column>
  154. <el-table-column
  155. sortable
  156. label="采集人"
  157. prop="infoCollector"
  158. width="120"
  159. ></el-table-column>
  160. <el-table-column
  161. sortable
  162. label="考试次数"
  163. prop="examOrder"
  164. width="120"
  165. ></el-table-column>
  166. <el-table-column
  167. sortable
  168. label="开考时间"
  169. prop="paperStartTime"
  170. width="120"
  171. ></el-table-column>
  172. <el-table-column
  173. sortable
  174. label="交卷时间"
  175. prop="paperSubmitTime"
  176. width="120"
  177. ></el-table-column>
  178. <el-table-column
  179. sortable
  180. :sort-method="sortByExamTime"
  181. label="持续时间"
  182. prop="examTime"
  183. width="120"
  184. ></el-table-column>
  185. <el-table-column
  186. sortable
  187. label="校验成功率(%)"
  188. prop="faceSuccessPercent"
  189. width="150"
  190. ></el-table-column>
  191. <el-table-column
  192. sortable
  193. label="续考次数"
  194. prop="continuedCount"
  195. width="120"
  196. ></el-table-column>
  197. <el-table-column
  198. sortable
  199. :sort-method="sortByPaperTotalScore"
  200. label="卷面总分"
  201. prop="paperTotalScore"
  202. width="120"
  203. ></el-table-column>
  204. <el-table-column
  205. sortable
  206. label="是否违纪"
  207. prop="isIllegality"
  208. width="120"
  209. ></el-table-column>
  210. <el-table-column
  211. sortable
  212. label="是否提交"
  213. prop="isSubmit"
  214. width="120"
  215. ></el-table-column>
  216. <el-table-column fixed="right" label="详情" width="100">
  217. <template slot-scope="scope">
  218. <el-row
  219. class="operateRow"
  220. v-if="
  221. scope.row.examType == 'ONLINE' &&
  222. currentPagePrivileges.EXAM_QUERY_GETPAPER
  223. "
  224. >
  225. <el-col :span="24">
  226. <el-button
  227. size="mini"
  228. type="primary"
  229. icon="el-icon-view"
  230. plain
  231. @click="
  232. examPaperDetail(scope.row.courseId, scope.row.dataId)
  233. "
  234. >调&nbsp;卷</el-button
  235. >
  236. </el-col>
  237. </el-row>
  238. <el-row
  239. class="operateRow"
  240. v-if="
  241. scope.row.examType == 'ONLINE' &&
  242. currentPagePrivileges.REDO_AUDIT
  243. "
  244. >
  245. <el-col :span="24">
  246. <el-dropdown>
  247. <el-button
  248. size="mini"
  249. icon="el-icon-arrow-down"
  250. type="primary"
  251. plain
  252. >重审</el-button
  253. >
  254. <el-dropdown-menu slot="dropdown">
  255. <el-dropdown-item>
  256. <el-button
  257. size="mini"
  258. type="success"
  259. @click="redoAudit(scope.row.dataId, 'pass')"
  260. icon="el-icon-success"
  261. >通&nbsp;&nbsp;过</el-button
  262. >
  263. </el-dropdown-item>
  264. <el-dropdown-item>
  265. <el-button
  266. size="mini"
  267. type="danger"
  268. @click="redoAudit(scope.row.dataId, 'nopass')"
  269. icon="el-icon-error"
  270. >不通过</el-button
  271. >
  272. </el-dropdown-item>
  273. </el-dropdown-menu>
  274. </el-dropdown>
  275. </el-col>
  276. </el-row>
  277. <el-row
  278. class="operateRow"
  279. v-if="
  280. scope.row.examType == 'OFFLINE' &&
  281. scope.row.offlineFileUrl &&
  282. currentPagePrivileges.EXAM_QUERY_GETPAPER
  283. "
  284. >
  285. <el-col :span="24">
  286. <el-button
  287. size="mini"
  288. type="primary"
  289. icon="el-icon-view"
  290. plain
  291. @click="downloadOfflineFile(scope.row.offlineFileUrl)"
  292. >调卷</el-button
  293. >
  294. </el-col>
  295. </el-row>
  296. </template>
  297. </el-table-column>
  298. </el-table>
  299. <div class="block pull-right">
  300. <el-pagination
  301. @size-change="handleSizeChange"
  302. @current-change="handleCurrentChange"
  303. :current-page.sync="form.pageNo"
  304. :page-sizes="[10, 20, 50, 100]"
  305. :page-size="form.pageSize"
  306. layout="total, sizes, prev, pager, next, jumper"
  307. :total="total"
  308. ></el-pagination>
  309. </div>
  310. </el-col>
  311. </el-row>
  312. <el-dialog
  313. title="审核"
  314. :visible.sync="dialogAuditFormVisible"
  315. @closed="auditDialogClosed"
  316. >
  317. <el-form :model="auditForm" ref="redoAuditForm">
  318. <el-form-item
  319. label="违纪类型"
  320. prop="disciplineType"
  321. :rules="[
  322. { required: true, message: '请选择违纪类型', trigger: 'change' }
  323. ]"
  324. >
  325. <el-select v-model="auditForm.disciplineType" placeholder="请选择">
  326. <el-option
  327. v-for="item in disciplineTypeList"
  328. :key="item.name"
  329. :label="item.desc"
  330. :value="item.name"
  331. ></el-option>
  332. </el-select>
  333. </el-form-item>
  334. <el-form-item label="详情描述" style="margin-top:15px;">
  335. <el-input
  336. v-model="auditForm.disciplineDetail"
  337. type="textarea"
  338. :autosize="{ minRows: 6, maxRows: 10 }"
  339. placeholder="请输入内容"
  340. ></el-input>
  341. </el-form-item>
  342. <div class="dialog-footer margin-top-10 text-center">
  343. <el-button type="primary" @click="doRedoAuditNoPass"
  344. >确 定</el-button
  345. >
  346. <el-button @click="dialogAuditFormVisible = false">取 消</el-button>
  347. </div>
  348. </el-form>
  349. </el-dialog>
  350. </el-main>
  351. </el-container>
  352. </template>
  353. <script>
  354. import { mapState } from "vuex";
  355. import commonFormVue from "../component/commonForm.vue";
  356. import commonExportVue from "../component/commonExport.vue";
  357. import { DISCIPLINE_TYPE_LIST } from "../constants/constants";
  358. import pagePrivilege from "../mixin/pagePrivilege.js";
  359. import _ from "lodash";
  360. export default {
  361. components: { commonFormVue, commonExportVue },
  362. mixins: [pagePrivilege],
  363. data() {
  364. return {
  365. disciplineTypeList: DISCIPLINE_TYPE_LIST,
  366. total: 0,
  367. tableLoading: false,
  368. showAllCondition: false,
  369. startExamDatetimeRange: [],
  370. form: {
  371. examRecordDataId: null,
  372. hasStranger: null,
  373. courseId: null,
  374. courseLevel: null,
  375. examId: null,
  376. examRecordId: null,
  377. faceSuccessPercentLower: null,
  378. faceSuccessPercentUpper: null,
  379. identityNumber: null,
  380. orgId: null,
  381. studentCode: null,
  382. studentName: null,
  383. isWarn: null,
  384. pageNo: 1,
  385. pageSize: 10,
  386. rootOrgId: null,
  387. startTime: null,
  388. endTime: null,
  389. infoCollector: null
  390. },
  391. getExamCondition: {
  392. params: {
  393. name: "",
  394. examTypes: "ONLINE#OFFLINE"
  395. },
  396. filterCondition: ""
  397. },
  398. tableData: [],
  399. exportUrl: "/api/ecs_oe_admin/exam/record/detail/list/export",
  400. exportFileName: "考试明细",
  401. currentPagePrivileges: {
  402. EXAM_DETAIL_EXPORT: false, //导出
  403. SNAPSHOT_DETAILS: false, //详情查看
  404. EXAM_QUERY_GETPAPER: false, //调卷
  405. REDO_AUDIT: false //重新审核
  406. },
  407. dialogAuditFormVisible: false,
  408. auditForm: {
  409. examRecordDataId: null,
  410. disciplineType: "",
  411. disciplineDetail: "",
  412. isPass: null
  413. }
  414. };
  415. },
  416. computed: {
  417. ...mapState({ user: state => state.user })
  418. },
  419. methods: {
  420. resetForm() {
  421. this.form = {
  422. examRecordDataId: null,
  423. hasStranger: null,
  424. courseId: null,
  425. courseLevel: null,
  426. examId: null,
  427. examRecordId: null,
  428. faceSuccessPercentLower: null,
  429. faceSuccessPercentUpper: null,
  430. identityNumber: null,
  431. orgId: null,
  432. studentCode: null,
  433. studentName: null,
  434. isWarn: null,
  435. pageNo: 1,
  436. pageSize: 10,
  437. rootOrgId: null,
  438. startTime: null,
  439. endTime: null,
  440. infoCollector: null
  441. };
  442. this.startExamDatetimeRange = [];
  443. },
  444. showMoreCondition() {
  445. this.showAllCondition = true;
  446. },
  447. showSimpleCondition() {
  448. this.$notify({
  449. title: "提示",
  450. message: "高级查询条件值已重置",
  451. type: "info",
  452. duration: 2000
  453. });
  454. this.resetForm();
  455. this.showAllCondition = false;
  456. },
  457. changeStartExamDatetimeRange(e) {
  458. if (e && e.length > 0) {
  459. this.form.startTime = e[0];
  460. this.form.endTime = e[1];
  461. } else {
  462. this.form.startTime = "";
  463. this.form.endTime = "";
  464. }
  465. },
  466. search(type) {
  467. if (!this.form.examId) {
  468. this.$notify({
  469. title: "警告",
  470. message: "请选择考试批次",
  471. type: "warning",
  472. duration: 2000
  473. });
  474. return false;
  475. }
  476. if (type && type == "clickSelectBtn") {
  477. this.form.pageNo = 1;
  478. }
  479. this.tableLoading = true;
  480. var params = JSON.parse(JSON.stringify(this.form));
  481. this.$http
  482. .post("/api/ecs_oe_admin/exam/record/detail/list", params)
  483. .then(response => {
  484. if (response.data) {
  485. this.tableData = response.data.content;
  486. this.total = response.data.totalElements;
  487. this.form.pageNo = response.data.number + 1;
  488. } else {
  489. this.tableData = [];
  490. }
  491. this.tableLoading = false;
  492. this.$router.push({
  493. path: "/oe/examDetail?" + new URLSearchParams(params)
  494. });
  495. });
  496. },
  497. handleSelectionChange(val) {
  498. this.multipleSelection = val;
  499. },
  500. /**
  501. * pagesize改变时触发
  502. */
  503. handleSizeChange(val) {
  504. this.form.pageSize = val;
  505. this.search();
  506. },
  507. /**
  508. * 当前页改变时触发
  509. */
  510. handleCurrentChange() {
  511. this.search();
  512. },
  513. examPaperDetail(courseId, examRecordDataId) {
  514. window.open(
  515. "/admin/oe/examPaperDetail/" + courseId + "/" + examRecordDataId
  516. );
  517. },
  518. gotoCaptureDetail(examRecordDataId) {
  519. this.$router.push({
  520. path: "/oe/captureDetail/" + examRecordDataId + "/examDetail"
  521. });
  522. },
  523. downloadOfflineFile(url) {
  524. window.open(url);
  525. },
  526. redoAudit(examRecordDataId, isPass) {
  527. if (isPass != "pass") {
  528. this.dialogAuditFormVisible = true;
  529. this.auditForm.examRecordDataId = examRecordDataId;
  530. } else {
  531. //审核通过
  532. var redoAuditInfo = {
  533. examRecordDataIds: [examRecordDataId],
  534. isPass: true,
  535. disciplineType: "",
  536. disciplineDetail: ""
  537. };
  538. this.$http
  539. .post("/api/ecs_oe_admin/exam/audit/redoAudit", redoAuditInfo)
  540. .then(() => {
  541. this.$notify({
  542. title: "成功",
  543. message: "操作成功",
  544. type: "success"
  545. });
  546. this.search();
  547. })
  548. .catch(res => {
  549. var errorMsg = "操作失败";
  550. if (res.response && res.response.data) {
  551. errorMsg = res.response.data.desc;
  552. }
  553. this.$notify({
  554. title: "提示",
  555. message: errorMsg,
  556. type: "error"
  557. });
  558. });
  559. }
  560. },
  561. doRedoAuditNoPass() {
  562. this.$refs["redoAuditForm"].validate(valid => {
  563. if (valid) {
  564. var redoAuditInfo = {
  565. examRecordDataIds: [this.auditForm.examRecordDataId],
  566. isPass: false,
  567. disciplineType: this.auditForm.disciplineType,
  568. disciplineDetail: this.auditForm.disciplineDetail
  569. };
  570. this.$http
  571. .post("/api/ecs_oe_admin/exam/audit/redoAudit", redoAuditInfo)
  572. .then(() => {
  573. this.$notify({
  574. title: "成功",
  575. message: "操作成功",
  576. type: "success"
  577. });
  578. this.doRedoAuditNoPassPostProcess();
  579. this.search();
  580. })
  581. .catch(res => {
  582. var errorMsg = "操作失败";
  583. if (res.response && res.response.data) {
  584. errorMsg = res.response.data.desc;
  585. }
  586. this.doRedoAuditNoPassPostProcess();
  587. this.$notify({
  588. title: "提示",
  589. message: errorMsg,
  590. type: "error"
  591. });
  592. });
  593. } else {
  594. return false;
  595. }
  596. });
  597. },
  598. doRedoAuditNoPassPostProcess() {
  599. this.auditForm = {
  600. examRecordDataId: null,
  601. disciplineType: "",
  602. disciplineDetail: "",
  603. isPass: null
  604. };
  605. this.$refs["redoAuditForm"].resetFields();
  606. this.dialogAuditFormVisible = false;
  607. },
  608. auditDialogClosed() {
  609. this.$refs["redoAuditForm"].resetFields();
  610. },
  611. backFill() {
  612. var formData = this.$route.query;
  613. if (formData && formData.examId) {
  614. for (var attr in formData) {
  615. var value = formData[attr];
  616. if (value && value != "null") {
  617. //是数字 且 长度小于15
  618. if (!isNaN(value) && value.toString().length < 15) {
  619. value = _.toNumber(value);
  620. }
  621. this.form[attr] = value;
  622. }
  623. }
  624. this.search();
  625. }
  626. },
  627. sortByPaperTotalScore(obj1, obj2) {
  628. let p1 = Number(obj1.paperTotalScore);
  629. let p2 = Number(obj2.paperTotalScore);
  630. return p1 - p2;
  631. },
  632. sortByExamTime(obj1, obj2) {
  633. debugger;
  634. let startTime1 = new Date(obj1.paperStartTime);
  635. let endTime1 = new Date(obj1.paperSubmitTime);
  636. let startTime2 = new Date(obj2.paperStartTime);
  637. let endTime2 = new Date(obj2.paperSubmitTime);
  638. let p1 = Number(endTime1 - startTime1);
  639. let p2 = Number(endTime2 - startTime2);
  640. if (isNaN(p1)) {
  641. p1 = 0;
  642. }
  643. if (isNaN(p2)) {
  644. p2 = 0;
  645. }
  646. return p1 - p2;
  647. }
  648. },
  649. created() {
  650. this.form.rootOrgId = this.user.rootOrgId;
  651. this.backFill();
  652. }
  653. };
  654. </script>
  655. <style scope>
  656. .el-date-editor.el-input,
  657. .el-date-editor.el-input__inner {
  658. width: auto !important;
  659. }
  660. </style>
  661. <style scoped src="../style/common.css"></style>