OnlineExamFaceCheckModal.vue 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. <template>
  2. <Modal v-model="faceCheckModalOpen" width="900" :mask-closable="false" :closable="false" @on-visible-change="updateCameraState">
  3. <div slot="header" style="display: flex; justify-content: space-between; align-items: center;">
  4. <div class="qm-title-text">人脸识别</div>
  5. <Icon type="ios-close" class="qm-icon-button" size="24" @click="closeModal" />
  6. </div>
  7. <div style="display: grid; grid-template-columns: 200px 400px 1fr; grid-gap: 5px;">
  8. <div class="avatar" :style="{ backgroundImage: `url('${userPhoto}')` }">
  9. <!-- <img :src="userPhoto" width="200px" height="300px" alt="底照" /> -->
  10. <div class="avatar-info" style="text-align: center; margin-top: 260px; color: white;">
  11. <!-- FIXME: 没有底照的逻辑 -->
  12. <span style="background-color: rgba(0, 0, 0, 0.5); display: inline-block;padding: 6px 16px; border-radius: 6px;">我的底照</span>
  13. </div>
  14. </div>
  15. <div class="camera">
  16. <FaceRecognition v-if="faceCheckModalOpen" width="400" height="300" :showRecognizeButton="true" :close-camera="closeCamera" @on-recognize-result="getFaceRecognitionResult">
  17. </FaceRecognition>
  18. </div>
  19. <div class="verify-desc qm-primary-text">
  20. <h4 class="qm-big-text" style="font-weight: bold">操作提示:</h4>
  21. <p>1.请先确保摄像头设备已连接并能正常工作;</p>
  22. <p>2.请保持光源充足,不要逆光操作;</p>
  23. <p>3.请保证脸部正面面向摄像头,并适当调整姿势保证整个脸部能够进入左侧识别画面;</p>
  24. <p>4.系统识别通过后,将自动跳转进入考试界面;</p>
  25. </div>
  26. </div>
  27. <div slot="footer">
  28. </div>
  29. </Modal>
  30. </template>
  31. <script>
  32. import FaceRecognition from "@/components/FaceRecognition/FaceRecognition.vue";
  33. import { createNamespacedHelpers } from "vuex";
  34. const { mapState, mapMutations } = createNamespacedHelpers("examHomeModule");
  35. export default {
  36. name: "OnlineExamFaceCheckModal",
  37. data() {
  38. return { userPhoto: null, closeCamera: false };
  39. },
  40. props: {
  41. open: Boolean,
  42. course: Object
  43. },
  44. async created() {
  45. const res = await this.$http.get(
  46. "/api/ecs_core/student/getStudentInfoBySession"
  47. );
  48. this.userPhoto = res.data.photoPath;
  49. if (!this.userPhoto) {
  50. this.$Message.error("没有底照");
  51. return;
  52. }
  53. // FIXME: 以后api返回的是绝对路径
  54. if (this.userPhoto.startsWith("http") === false) {
  55. this.userPhoto = this.userPhoto;
  56. }
  57. // const sysRes = await this.$http.get("/api/sys_param", {
  58. // params: {
  59. // orgId: this.$store.state.user.rootOrgId
  60. // }
  61. // });
  62. // // FIXME: 将faceEnable和faceCheck放到global的state中
  63. // this.faceEnable = sysRes.data.faceEnable; // 模拟练习?
  64. // this.faceCheck = sysRes.data.faceCheck; // 考试
  65. },
  66. computed: {
  67. ...mapState(["faceCheckModalOpen"])
  68. },
  69. methods: {
  70. ...mapMutations(["toggleFaceCheckModal"]),
  71. closeModal() {
  72. this.closeCamera = true;
  73. this.toggleFaceCheckModal(false);
  74. },
  75. updateCameraState(modalVisible) {
  76. this.closeCamera = !modalVisible;
  77. },
  78. getFaceRecognitionResult({ error, faceCount, pass }) {
  79. if (error) {
  80. console.log(error, faceCount, pass);
  81. this.$Message.error(error);
  82. return;
  83. }
  84. if (!pass && this.course.faceCheck) {
  85. this.$Modal.confirm({
  86. title: "郑重承诺",
  87. content:
  88. "我承诺由本人参加考试,并且同意接受考试监控系统信息审核,一经发现作弊,立即取消本门课程考试成绩。",
  89. onOk: () =>
  90. this.$router.push(
  91. `/online-exam/exam/${this.course.examId}/overview?stuExamInfoId=${
  92. this.course.examStudentId
  93. }`
  94. )
  95. });
  96. return;
  97. }
  98. this.$router.push(
  99. `/online-exam/exam/${this.course.examId}/overview?stuExamInfoId=${
  100. this.course.examStudentId
  101. }`
  102. );
  103. }
  104. },
  105. components: {
  106. FaceRecognition
  107. }
  108. };
  109. </script>
  110. <style scoped>
  111. .avatar {
  112. background: center no-repeat;
  113. background-size: cover;
  114. width: 200px;
  115. height: 300px;
  116. }
  117. .verify-desc {
  118. padding: 0 1em;
  119. line-height: 1.8em;
  120. }
  121. </style>