Forráskód Böngészése

考试记录修改

zhangjie 3 éve
szülő
commit
368bcf64b8

+ 1 - 0
package.json

@@ -26,6 +26,7 @@
     "echarts": "^4.8.0",
     "element-ui": "^2.13.2",
     "flv.js": "^1.5.0",
+    "hls.js": "^1.1.5",
     "js-cookie": "^2.2.1",
     "js-md5": "^0.7.3",
     "lodash-es": "^4.17.15",

+ 25 - 7
src/features/examwork/StudentManagement/HlsMedia.vue

@@ -1,6 +1,12 @@
 <template>
   <div class="hls-media">
-    <video ref="VideoMedia" muted></video>
+    <video
+      ref="VideoMedia"
+      muted
+      controls
+      controlslist="nodownload"
+      disablePictureInPicture
+    ></video>
   </div>
 </template>
 
@@ -28,24 +34,26 @@ export default {
       if (!this.url) return;
       if (!Hls.isSupported()) return;
 
-      this.hls = new Hls(this.$refs.VideoMedia);
+      this.hls = new Hls();
       this.hls.loadSource(this.url);
-      this.hls.attachMedia(this.$el);
+      this.hls.attachMedia(this.$refs.VideoMedia);
       this.player = this.$refs.VideoMedia;
       this.player.play();
 
       this.hls.on(Hls.Events.ERROR, (event, data) => {
-        if (data.fatal) {
+        if (!data.fatal) {
           switch (data.type) {
             case Hls.ErrorTypes.NETWORK_ERROR:
-              console.log("fatal network error encountered, try to recover");
+              console.log("网络问题,准备重试!");
               this.hls.startLoad();
               break;
             case Hls.ErrorTypes.MEDIA_ERROR:
-              console.log("fatal media error encountered, try to recover");
+              console.log("媒体问题,准备重试!");
               this.hls.recoverMediaError();
               break;
             default:
+              console.log("未知问题,无法播放!");
+              this.$emit("error");
               this.hls.destroy();
               break;
           }
@@ -61,7 +69,6 @@ export default {
     destroyPlayer() {
       if (!this.player) return;
       this.player.pause();
-      this.player.unload();
       this.player = null;
       this.hls.destroy();
       this.hls = null;
@@ -72,3 +79,14 @@ export default {
   },
 };
 </script>
+
+<style lang="scss" scoped>
+.hls-media {
+  height: 100%;
+  video {
+    display: block;
+    width: 100%;
+    height: 100%;
+  }
+}
+</style>

+ 8 - 1
src/features/examwork/StudentManagement/StudentManagementDialog.vue

@@ -3,7 +3,7 @@
     <el-dialog
       ref="dialog"
       title="考试记录"
-      width="600px"
+      width="760px"
       :visible.sync="visible"
       @close="closeDialog"
     >
@@ -82,6 +82,7 @@ export default {
       this.tableData = [];
       this.pageSize = 10;
       this.total = 0;
+      this.form.examId = "";
     },
   },
   data() {
@@ -138,6 +139,12 @@ export default {
     // monitor record
     openMonitorRecord(row) {
       console.log(row);
+      window.sessionStorage.setItem("record", JSON.stringify(row));
+      window.open(
+        this.$router.resolve({
+          name: "StudentMonitorRecord",
+        }).href
+      );
     },
   },
 };

+ 67 - 46
src/features/examwork/StudentManagement/StudentMonitorRecord.vue

@@ -4,21 +4,21 @@
       <div class="header-info">
         <span class="header-info-name">
           <i class="icon icon-user-act"></i>
-          {{ info.examStudentName }}
+          {{ info.name }}
         </span>
         <span class="header-info-item"> 证件号:{{ info.identity }} </span>
         <span class="header-info-item"> 课程:{{ info.courseName }} </span>
+        <span class="header-info-item"> 批次名称:{{ info.examName }} </span>
         <span class="header-info-item">
-          批次名称:{{ info.examBatchName }}
+          考试时间:{{ info.firstStartTime | datetimeFilter }}
         </span>
-        <span class="header-info-item"> 考试时间:{{ info.examTime }} </span>
       </div>
       <div>
         <el-button
-          v-for="source in videoSources"
-          :key="source.monitorKey"
+          v-for="source in info.monitorRecord"
+          :key="source.videoSource"
           :type="
-            curSource.monitorKey === source.monitorKey ? 'primary' : 'info'
+            curSource.videoSource === source.videoSource ? 'primary' : 'info'
           "
           @click="switchVideo(source)"
           >{{ videoSourceInfo[source.monitorKey] }}</el-button
@@ -27,14 +27,18 @@
     </div>
     <div class="record-body">
       <div class="record-video">
-        <video
-          :src="curSourceUrl"
-          controls
-          controlslist="nodownload"
-          disablePictureInPicture
+        <HlsMedia
+          v-if="curSource.videoUrl"
+          :url="curSource.videoUrl"
+          :key="curSource.videoUrl"
           @error="videoError"
-          @loadeddata="videoLoad($event)"
-        ></video>
+        />
+        <div v-else class="record-video-none">
+          <div>
+            <i class="el-icon-video-camera-solid"></i>
+            <p>暂无视频</p>
+          </div>
+        </div>
       </div>
     </div>
     <div class="record-footer">
@@ -52,8 +56,6 @@
       custom-class="record-code-dialog"
       :visible.sync="modalIsShow"
       width="280px"
-      :close-on-click-modal="false"
-      :close-on-press-escape="false"
       append-to-body
       destroy-on-close
     >
@@ -62,7 +64,7 @@
       </div>
       <div class="record-qrcode">
         <vue-qrcode
-          :value="curSourceUrl"
+          :value="curSource.videoUrl"
           :options="{ width: 200, margin: 0 }"
           tag="img"
         ></vue-qrcode>
@@ -74,54 +76,66 @@
 
 <script>
 import VueQrcode from "@chenfengyuan/vue-qrcode";
+import HlsMedia from "./HlsMedia";
 
 export default {
   name: "StudentMonitorRecord",
-  components: { VueQrcode },
+  components: { VueQrcode, HlsMedia },
   data() {
     return {
       info: {
-        examStudentName: "夏燕",
+        name: "",
+        identity: "",
+        examName: "",
+        courseName: "",
+        monitorRecord: [
+          {
+            videoSource: "",
+            videoUrl: "",
+          },
+        ],
       },
-      videoSources: [
-        {
-          monitorKey: "MOBILE_FIRST",
-          monitorKeyName: "",
-          urls: [],
-        },
-        {
-          monitorKey: "MOBILE_SECOND",
-          monitorKeyName: "",
-          urls: [],
-        },
-        {
-          monitorKey: "CLIENT_CAMERA",
-          monitorKeyName: "",
-          urls: [],
-        },
-        {
-          monitorKey: "CLIENT_SCREEN",
-          monitorKeyName: "",
-          urls: [],
-        },
-      ],
       videoSourceInfo: {
         CLIENT_CAMERA: "电脑摄像头",
         CLIENT_SCREEN: "电脑录屏",
         MOBILE_FIRST: "手机主机位",
         MOBILE_SECOND: "手机辅机位",
       },
-      curSource: {},
-      curSourceUrl: "http://localhost:8176/files/big_buck_bunny.mp4",
+      curSource: { videoSource: "", videoUrl: "" },
       modalIsShow: false,
     };
   },
+  created() {
+    const recordStr = window.sessionStorage.getItem("record");
+    if (!recordStr) {
+      this.$message.error("数据丢失,请关闭页面!");
+      return;
+    }
+    this.info = JSON.parse(recordStr);
+    this.info.monitorRecord = this.info.monitorRecord.map((item) => {
+      return {
+        ...item,
+        monitorKey: this.getVideoMonitorKey(item.videoSource),
+      };
+    });
+    this.switchVideo(this.info.monitorRecord[0]);
+  },
   methods: {
+    getVideoMonitorKey(videoSource) {
+      return Object.keys(this.videoSourceInfo).find((key) =>
+        videoSource.includes(key.toLowerCase())
+      );
+    },
     switchVideo(source) {
       this.curSource = source;
     },
     videoError() {
-      this.$message.error("视频解析错误,您可以尝试扫描二维码,通过手机观看。");
+      this.$message({
+        type: "error",
+        message: "视频解析错误,您可以尝试扫描二维码,通过手机观看。",
+        showClose: true,
+        duration: 10 * 1000,
+      });
     },
     videoLoad(event) {
       console.log(event);
@@ -197,10 +211,17 @@ export default {
   height: 100%;
   overflow: hidden;
 
-  > video {
-    display: block;
-    width: 100%;
+  &-none {
     height: 100%;
+    display: flex;
+    align-items: center;
+    justify-content: space-around;
+    text-align: center;
+    color: #333;
+
+    i {
+      font-size: 80px;
+    }
   }
 }
 .record-footer {

+ 1 - 1
src/router/index.js

@@ -179,7 +179,7 @@ const routes = [
     ],
   },
   {
-    path: "/exam/student-monitor-record/:recordId",
+    path: "/exam/student-monitor-record",
     name: "StudentMonitorRecord",
     component: () =>
       import(

+ 5 - 0
yarn.lock

@@ -5974,6 +5974,11 @@ highlight.js@^9.6.0:
   resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-9.15.7.tgz#0e54555beb031894c8f220b3c0eb4253c366406c"
   integrity sha512-6AgA4zXNQZbgvhuJQhL+8JEd+XiPyzRxHpoRnhU084/ZoLqvMRjFQ3eSXvcUlLpLByA++TDYiFr0r4CHRHRJBQ==
 
+hls.js@^1.1.5:
+  version "1.1.5"
+  resolved "https://registry.npmmirror.com/hls.js/-/hls.js-1.1.5.tgz#923a8a8cfdf09542578696d47c8ae435da981ffd"
+  integrity sha512-mQX5TSNtJEzGo5HPpvcQgCu+BWoKDQM6YYtg/KbgWkmVAcqOCvSTi0SuqG2ZJLXxIzdnFcKU2z7Mrw/YQWhPOA==
+
 hmac-drbg@^1.0.0:
   version "1.0.1"
   resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1"