Browse Source

Merge branch 'master' of http://git.qmth.com.cn/themis/frontend-admin

zhangjie 4 years ago
parent
commit
fac9a9b08c

+ 25 - 0
src/api/examwork-markresult.js

@@ -27,3 +27,28 @@ export function searchMarkResult({
     "/api/admin/examStudent/mark/result?" + object2QueryString(data)
   );
 }
+
+export function exportMarkResult({
+  examId = "",
+  examActivityId = "",
+  courseCode = "",
+  name = "",
+  identity = "",
+  type = "",
+}) {
+  const data = pickBy(
+    {
+      examId,
+      examActivityId,
+      name,
+      courseCode,
+      identity,
+      type,
+    },
+    (v) => v !== "" && v !== null
+  );
+  return httpApp.post(
+    `/api/admin/examStudent/mark/result/${type}/export?` +
+      object2QueryString(data)
+  );
+}

+ 6 - 2
src/api/examwork-task.js

@@ -62,6 +62,10 @@ export function importInvigilator({ examId, fileName, file, md5 }) {
   });
 }
 
-export function exportInvigilate() {
-  return httpApp.post("/api/admin/invigilateUser/export");
+export function exportInvigilate({ examId, roomCode, userId }) {
+  const form = new FormData();
+  form.append("examId", examId);
+  form.append("roomCode", roomCode);
+  form.append("userId", userId);
+  return httpApp.post("/api/admin/invigilateUser/export", form);
 }

+ 1 - 1
src/components/VEditor/renderJSON.js

@@ -1,7 +1,7 @@
 // const _text_styles_ = ["bold", "underline", "italic", "sup", "sub"];
 
 export function renderRichText(body, container) {
-  let sections = body.sections || [];
+  let sections = body?.sections || [];
   let nodes = [];
   sections.forEach((section) => {
     nodes.push(renderSection(section));

+ 2 - 0
src/constant/constants.js

@@ -136,6 +136,8 @@ export const IMPORT_EXPORT_TASKS = [
   { code: "IMPORT_INVIGILATE_USER", name: "导入监考员" },
   { code: "EXPORT_INVIGILATE_USER", name: "导出监考员" },
   { code: "EXPORT_EXAM_STUDENT", name: "导出考生" },
+  { code: "EXPORT_MARK_RESULT_SIMPLE", name: "导出成绩简版" },
+  { code: "EXPORT_MARK_RESULT_STANDARD", name: "导出成绩标准版" },
 ];
 
 let domain;

+ 189 - 16
src/features/examwork/ExamManagement/ExamEdit.vue

@@ -1,5 +1,5 @@
 <template>
-  <div>
+  <div v-loading="!orgSetting">
     <el-tabs v-model="activeName" type="card">
       <el-tab-pane label="考试规则设置" name="first">
         <el-form
@@ -224,6 +224,8 @@
                 </el-radio>
                 <el-radio
                   v-model="form.entryAuthenticationPolicy"
+                  :disabled="orgSettingDisableLiveness"
+                  :title="orgSettingDisableLiveness && '原因:机构禁用活体'"
                   label="LIVENESS_VERIFY"
                 >
                   安全级别:<span style="color: red; font-size: 20px;">
@@ -239,12 +241,14 @@
             <el-form-item label="是否考中人脸识别">
               <el-radio
                 :disabled="!!form.cameraPhotoUpload"
+                :title="!!form.cameraPhotoUpload && '原因:拍照作答'"
                 v-model="form.inProcessFaceVerify"
                 :label="1"
                 >是
               </el-radio>
               <el-radio
                 :disabled="!!form.cameraPhotoUpload"
+                :title="!!form.cameraPhotoUpload && '原因:拍照作答'"
                 v-model="form.inProcessFaceVerify"
                 :label="0"
                 >否
@@ -255,12 +259,14 @@
             <el-form-item label="是否考中陌生人脸识别">
               <el-radio
                 :disabled="!!form.cameraPhotoUpload"
+                :title="!!form.cameraPhotoUpload && '原因:拍照作答'"
                 v-model="form.inProcessFaceStrangerIgnore"
                 :label="0"
                 >是
               </el-radio>
               <el-radio
                 :disabled="!!form.cameraPhotoUpload"
+                :title="!!form.cameraPhotoUpload && '原因:拍照作答'"
                 v-model="form.inProcessFaceStrangerIgnore"
                 :label="1"
                 >否
@@ -271,12 +277,14 @@
             <el-form-item label="是否考开启真实性检测">
               <el-radio
                 :disabled="!!form.cameraPhotoUpload"
+                :title="!!form.cameraPhotoUpload && '原因:拍照作答'"
                 v-model="form.inProcessRealnessVerify"
                 :label="1"
                 >是
               </el-radio>
               <el-radio
                 :disabled="!!form.cameraPhotoUpload"
+                :title="!!form.cameraPhotoUpload && '原因:拍照作答'"
                 v-model="form.inProcessRealnessVerify"
                 :label="0"
                 >否
@@ -286,13 +294,25 @@
           <el-row>
             <el-form-item label="是否考中活体检测">
               <el-radio
-                :disabled="!!form.cameraPhotoUpload"
+                :disabled="
+                  !!form.cameraPhotoUpload || orgSettingDisableLiveness
+                "
+                :title="
+                  (!!form.cameraPhotoUpload || orgSettingDisableLiveness) &&
+                  '原因:机构禁用活体或选择拍照作答'
+                "
                 v-model="form.inProcessLivenessVerify"
                 :label="1"
                 >是
               </el-radio>
               <el-radio
-                :disabled="!!form.cameraPhotoUpload"
+                :disabled="
+                  !!form.cameraPhotoUpload || orgSettingDisableLiveness
+                "
+                :title="
+                  (!!form.cameraPhotoUpload || orgSettingDisableLiveness) &&
+                  '原因:机构禁用活体或选择拍照作答'
+                "
                 v-model="form.inProcessLivenessVerify"
                 :label="0"
                 >否
@@ -339,39 +359,106 @@
             <el-form-item label="是否开启考生端监考直播">
               <el-radio
                 :disabled="!!form.cameraPhotoUpload"
+                :title="!!form.cameraPhotoUpload && '原因:拍照作答'"
                 v-model="form.monitorProxy"
                 :label="true"
                 >是
               </el-radio>
               <el-radio
                 :disabled="!!form.cameraPhotoUpload"
+                :title="!!form.cameraPhotoUpload && '原因:拍照作答'"
                 v-model="form.monitorProxy"
                 :label="false"
                 >否
               </el-radio>
             </el-form-item>
           </el-row>
-          <el-row>
+          <!-- <el-row>
             <el-form-item v-if="form.monitorProxy" label="是否需要视频回放">
               <el-radio v-model="form.monitorRecord" :label="1">是 </el-radio>
               <el-radio v-model="form.monitorRecord" :label="0">否 </el-radio>
             </el-form-item>
-          </el-row>
+          </el-row> -->
           <el-row>
             <el-form-item v-if="form.monitorProxy" label="电脑&手机监控方案">
               <el-checkbox-group v-model="form.monitorVideoSource">
-                <el-checkbox label="CLIENT_CAMERA"
-                  >电脑摄像头为主机位</el-checkbox
-                >
-                <el-checkbox label="CLIENT_SCREEN">电脑开启录屏</el-checkbox>
-                <el-checkbox label="MOBILE_FIRST">手机主机位</el-checkbox>
-                <el-checkbox
-                  :disabled="!form.monitorVideoSource.includes('MOBILE_FIRST')"
-                  label="MOBILE_SECOND"
-                  >手机辅机位</el-checkbox
-                >
+                <div class="d-flex">
+                  <div class="d-flex flex-column justify-content-between">
+                    <el-checkbox label="CLIENT_CAMERA"
+                      >电脑摄像头为主机位</el-checkbox
+                    >
+                    <el-checkbox label="CLIENT_SCREEN"
+                      >电脑开启录屏</el-checkbox
+                    >
+                    <el-checkbox label="MOBILE_FIRST">手机主机位</el-checkbox>
+                    <el-checkbox
+                      :disabled="
+                        !form.monitorVideoSource.includes('MOBILE_FIRST')
+                      "
+                      :title="
+                        !form.monitorVideoSource.includes('MOBILE_FIRST') &&
+                        '原因:先选择手机主机位'
+                      "
+                      label="MOBILE_SECOND"
+                      >手机辅机位</el-checkbox
+                    >
+                    <span style="color: red; font-size: 12px;"
+                      >*主机位设备负责收音及播放监考提示</span
+                    >
+                  </div>
+                  <div
+                    style="
+                      margin-left: 20px;
+                      padding: 10px;
+                      font-size: 10px;
+                      background: #f0f4f9;
+                    "
+                  >
+                    <div class="d-flex">
+                      <div
+                        class="d-flex flex-column justify-content-center align-items-center"
+                        style="width: 52px !important;"
+                      >
+                        <div :class="monitorImgSrc('MOBILE_SECOND')" />
+                        手机辅机位
+                      </div>
+                      <div
+                        class="d-flex flex-column justify-content-center align-items-center"
+                        style="width: 350px !important;"
+                      >
+                        <div :class="monitorImgSrc('CLIENT_CAMERA')" />
+                        电脑摄像头为主机位
+                      </div>
+                      <div style="width: 52px !important;"></div>
+                    </div>
+                    <div
+                      class="d-flex"
+                      style="margin-bottom: -60px; margin-top: -30px;"
+                    >
+                      <div style="width: 52px !important;"></div>
+                      <div
+                        class="d-flex flex-column justify-content-center align-items-center"
+                        style="width: 350px !important;"
+                      >
+                        <div :class="monitorImgSrc('CLIENT_SCREEN')" />
+                        电脑开启录屏
+                      </div>
+                      <div style="width: 52px !important;"></div>
+                    </div>
+                    <div class="d-flex">
+                      <div style="width: 52px !important;"></div>
+                      <div style="width: 350px !important;"></div>
+                      <div
+                        class="d-flex flex-column justify-content-center align-items-center"
+                        style="width: 52px !important;"
+                      >
+                        <div :class="monitorImgSrc('MOBILE_FIRST')" />
+                        手机主机位
+                      </div>
+                    </div>
+                  </div>
+                </div>
               </el-checkbox-group>
-              <span style="color: red;">*主机位设备负责收音及播放监考提示</span>
             </el-form-item>
           </el-row>
         </el-form>
@@ -433,6 +520,7 @@ import ExamTypeSelect from "@/components/ExamTypeSelect";
 import MinuteInput from "@/components/MinuteInput";
 import { saveExam, getExamDetail } from "@/api/examwork-exam";
 import { isNumber } from "lodash-es";
+import { searchOrg } from "@/api/system-org";
 
 export default {
   name: "ExamEdit",
@@ -473,6 +561,9 @@ export default {
         }
       },
     },
+    orgSettingDisableLiveness() {
+      return !this.orgSetting?.enableLiveness;
+    },
   },
   watch: {
     "form.mode": {
@@ -555,6 +646,21 @@ export default {
       this.form.preNoticeClone = this.form.preNotice;
       this.form.postNoticeClone = this.form.postNotice;
     }
+
+    // sleep
+    // await new Promise((res) =>
+    //   setTimeout(() => {
+    //     res();
+    //   }, 3000)
+    // );
+    const res = await searchOrg(this.$store.state.user.orgId);
+    this.orgSetting = res.data.data[0];
+    if (!this.orgSetting.enableLiveness) {
+      if (this.form.entryAuthenticationPolicy === "LIVENESS_VERIFY") {
+        this.form.entryAuthenticationPolicy = "FACE_VERIFY_FORCE";
+      }
+      this.form.inProcessLivenessVerify = 0;
+    }
   },
   data() {
     return {
@@ -628,10 +734,29 @@ export default {
           // message: "格式错误",
         },
       },
+      orgSetting: null,
       loading: false,
     };
   },
   methods: {
+    monitorImgSrc(monitorSource) {
+      const selected = this.form.monitorVideoSource.includes(monitorSource);
+      const selectedStr = selected ? "-selected" : "";
+      if (monitorSource === "MOBILE_FIRST") {
+        return `mobile-first-img${selectedStr}`;
+      } else if (monitorSource === "MOBILE_SECOND") {
+        return `mobile-second-img${selectedStr}`;
+        // return `./imgs/手机监考辅机位${selectedStr}.png`;
+      } else if (monitorSource === "CLIENT_CAMERA") {
+        // return `./imgs/手机监考辅机位${selectedStr}.png`;
+        return `client-camera-img${selectedStr}`;
+      } else if (monitorSource === "CLIENT_SCREEN") {
+        // return `./imgs/手机监考辅机位${selectedStr}.png`;
+        return `client-screen-img${selectedStr}`;
+      }
+
+      return "";
+    },
     async save() {
       try {
         await this.$refs.form1.validate();
@@ -699,4 +824,52 @@ export default {
     }
   }
 }
+
+.mobile-first-img {
+  background-image: url(./imgs/手机监考主机位.png);
+  background-repeat: no-repeat;
+  background-size: 52px 80px;
+  width: 52px;
+  height: 80px;
+  &-selected {
+    @extend .mobile-first-img;
+    background-image: url(./imgs/手机监考主机位-选中.png);
+  }
+}
+
+.mobile-second-img {
+  background-image: url(./imgs/手机监考辅机位.png);
+  background-repeat: no-repeat;
+  background-size: 52px 80px;
+  width: 52px;
+  height: 80px;
+  &-selected {
+    @extend .mobile-second-img;
+    background-image: url(./imgs/手机监考辅机位-选中.png);
+  }
+}
+
+.client-camera-img {
+  background-image: url(./imgs/电脑摄像头主机位.png);
+  background-repeat: no-repeat;
+  background-size: 33px 40px;
+  width: 33px;
+  height: 40px;
+  &-selected {
+    @extend .client-camera-img;
+    background-image: url(./imgs/电脑摄像头主机位-选中.png);
+  }
+}
+
+.client-screen-img {
+  background-image: url(./imgs/电脑操作录屏.png);
+  background-repeat: no-repeat;
+  background-size: 190px 110px;
+  width: 190px;
+  height: 110px;
+  &-selected {
+    @extend .client-screen-img;
+    background-image: url(./imgs/电脑操作录屏-选中.png);
+  }
+}
 </style>

BIN
src/features/examwork/ExamManagement/imgs/手机监考主机位-选中.png


BIN
src/features/examwork/ExamManagement/imgs/手机监考主机位.png


BIN
src/features/examwork/ExamManagement/imgs/手机监考辅机位-选中.png


BIN
src/features/examwork/ExamManagement/imgs/手机监考辅机位.png


BIN
src/features/examwork/ExamManagement/imgs/电脑摄像头主机位-选中.png


BIN
src/features/examwork/ExamManagement/imgs/电脑摄像头主机位.png


BIN
src/features/examwork/ExamManagement/imgs/电脑操作录屏-选中.png


BIN
src/features/examwork/ExamManagement/imgs/电脑操作录屏.png


+ 21 - 5
src/features/examwork/InvigilateManagement/InvigilateManagement.vue

@@ -129,11 +129,17 @@ export default {
       downloadUrl: INVIGILATOR_IMPORT_TEMPLATE_DOWNLOAD_URL,
     };
   },
-  async created() {
-    this.searchForm();
-  },
+  // async created() {
+  //   this.searchForm();
+  // },
   methods: {
     async searchForm() {
+      try {
+        await this.$refs.form.validate();
+      } catch (error) {
+        console.log(error);
+        return;
+      }
       const res = await searchInvigilators({
         examId: this.form.examId,
         userId: this.form.userId,
@@ -167,8 +173,18 @@ export default {
       }
       this.$refs.theDialog2.openDialog();
     },
-    exportInvigilate() {
-      exportInvigilate();
+    async exportInvigilate() {
+      try {
+        await this.$refs.form.validate();
+      } catch (error) {
+        console.log(error);
+        return;
+      }
+      exportInvigilate({
+        examId: this.form.examId,
+        userId: this.form.userId,
+        roomCode: this.form.roomCode,
+      });
       this.$notify({ title: "导入任务已成功启动", type: "success" });
     },
   },

+ 31 - 11
src/features/examwork/MarkResultManagement/MarkResultManagement.vue

@@ -28,6 +28,19 @@
             <el-button type="primary" @click="handleCurrentChange(0)"
               >查询</el-button
             >
+
+            <el-dropdown
+              class="mx-2"
+              split-button
+              type="primary"
+              @command="exportMarkResult"
+            >
+              导出
+              <el-dropdown-menu slot="dropdown">
+                <el-dropdown-item command="simple">简化版</el-dropdown-item>
+                <el-dropdown-item command="standard">标准版</el-dropdown-item>
+              </el-dropdown-menu>
+            </el-dropdown>
           </el-form-item>
         </el-form>
       </div>
@@ -97,7 +110,7 @@
 </template>
 
 <script>
-import { searchMarkResult } from "@/api/examwork-markresult";
+import { searchMarkResult, exportMarkResult } from "@/api/examwork-markresult";
 export default {
   name: "MarkResultManagement",
   data() {
@@ -116,9 +129,6 @@ export default {
       currentPage: 1,
       pageSize: 10,
       total: 10,
-      basePhotoDialogVisible: false,
-      selectedBasePhoto: null,
-      selectedStudent: {},
     };
   },
   async created() {},
@@ -152,13 +162,23 @@ export default {
       this.currentPage = 1;
       this.searchForm();
     },
-    openBasePhotoDialog(url) {
-      this.selectedBasePhoto = url;
-      this.basePhotoDialogVisible = true;
-    },
-    openExamRecord(user) {
-      this.selectedStudent = user;
-      this.$refs.theDialog.openDialog();
+    async exportMarkResult(type) {
+      try {
+        const valid = await this.$refs.form.validate();
+        if (!valid) return;
+      } catch (error) {
+        console.log(error);
+        return;
+      }
+      await exportMarkResult({
+        examId: this.form.examId,
+        examActivityId: this.form.examActivityId,
+        identity: this.form.identity,
+        courseCode: this.form.courseCode,
+        name: this.form.name,
+        type,
+      });
+      this.$notify({ title: "导入任务已成功启动", type: "success" });
     },
   },
 };

+ 1 - 1
src/features/system/OrgManagement/OrgManagementDialog.vue

@@ -63,7 +63,7 @@
         </el-form-item>
       </el-row>
       <el-row>
-        <el-form-item label="是否视频转录" prop="enableMonitorRecord">
+        <el-form-item label="是否视频回放" prop="enableMonitorRecord">
           <el-radio-group
             class="pull_right_sm"
             v-model="form.enableMonitorRecord"