VideoInteractionPreview.vue 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. <!-- eslint-disable vue/no-v-html -->
  2. <template>
  3. <div class="imageText-preview" :style="getAreaStyle()">
  4. <SerialNumberPosition v-if="isEnable(data.property.sn_display_mode)" :property="data.property" />
  5. <div class="interaction-box" v-if="data.video_list.length > 0">
  6. <video
  7. id="interaction-preview-video"
  8. :src="data.video_list[0].file_url"
  9. width="100%"
  10. height="400"
  11. controls
  12. @timeupdate="handleTimeUpdate"
  13. controlsList="nodownload"
  14. ></video>
  15. </div>
  16. <!-- v-if="Object.keys(this.userAnswer).length === data.file_info_list.length" -->
  17. <el-button
  18. type="primary"
  19. @click="lookReport"
  20. :style="{
  21. background:
  22. data.unified_attrib && data.unified_attrib.topic_color ? data.unified_attrib.topic_color : '#165dff',
  23. borderColor:
  24. data.unified_attrib && data.unified_attrib.topic_color ? data.unified_attrib.topic_color : '#165dff',
  25. }"
  26. >查看答题报告</el-button
  27. >
  28. <el-dialog
  29. v-if="visible"
  30. :visible.sync="visible"
  31. :show-close="false"
  32. :close-on-click-modal="true"
  33. :modal-append-to-body="true"
  34. :append-to-body="true"
  35. :lock-scroll="true"
  36. width="80%"
  37. >
  38. <ExercisePreview :exercise_id="exercise_id" @handleCancle="handleClose" @submitAdd="submitAdd"></ExercisePreview>
  39. <!-- <iframe v-if="visible" :src="newpath" width="100%" :height="iframeHeight" frameborder="0"></iframe> -->
  40. </el-dialog>
  41. <el-dialog
  42. v-if="reportFlag"
  43. :visible.sync="reportFlag"
  44. :show-close="true"
  45. :close-on-click-modal="true"
  46. :modal-append-to-body="true"
  47. :append-to-body="true"
  48. :lock-scroll="true"
  49. width="80%"
  50. @close="handleClose"
  51. >
  52. <Report
  53. :reportResult="reportResult"
  54. :exerciseList="exerciseList"
  55. :userAnswer="userAnswer"
  56. :fileList="data.file_info_list"
  57. @handleCancle="handleClose"
  58. ></Report>
  59. </el-dialog>
  60. </div>
  61. </template>
  62. <script>
  63. import ExercisePreview from './ExercisePreview.vue';
  64. import Report from './Report.vue';
  65. import PreviewMixin from '../common/PreviewMixin';
  66. import { getVideoInteractionData } from '@/views/book/courseware/data/videoInteraction';
  67. import { getConfig } from '@/utils/auth';
  68. export default {
  69. name: 'VideoInteractionPreview',
  70. components: { ExercisePreview, Report },
  71. mixins: [PreviewMixin],
  72. data() {
  73. return {
  74. data: getVideoInteractionData(),
  75. video_info: null,
  76. file_preview_url: getConfig() ? getConfig().doc_preview_service_address : '',
  77. visible: false,
  78. newpath: '',
  79. iframeHeight: `${window.innerHeight - 100}px`,
  80. first: '',
  81. exercise_id: '',
  82. userAnswer: {}, // 用户答题答案
  83. exerciseList: {}, // 题目列表
  84. reportFlag: false,
  85. reportResult: {
  86. total: 0,
  87. right: 0,
  88. error: 0,
  89. rightRate: 0,
  90. },
  91. };
  92. },
  93. watch: {},
  94. created() {
  95. this.initData();
  96. },
  97. mounted() {},
  98. methods: {
  99. initData() {
  100. this.data.file_info_list = this.data.file_info_list.sort((a, b) => Number(a.currentTime) - Number(b.currentTime));
  101. },
  102. handleTimeUpdate(event) {
  103. let currentTime = event.target.currentTime;
  104. this.data.file_info_list.forEach((item) => {
  105. if (
  106. Number(item.currentTime) > Math.floor(currentTime) &&
  107. Number(item.currentTime) < Math.floor(currentTime) + 1 &&
  108. item.id !== this.first
  109. ) {
  110. this.first = item.id;
  111. document.getElementById('interaction-preview-video').pause();
  112. this.exercise_id = item.id;
  113. this.visible = true;
  114. // GetFileURLMap({ file_id_list: [item.file_id] }).then(({ url_map }) => {
  115. // this.newpath = `${this.file_preview_url}onlinePreview?url=${Base64.encode(url_map[item.file_id])}`;
  116. // this.visible = true;
  117. // });
  118. }
  119. });
  120. },
  121. handleClose() {
  122. this.reportFlag = false;
  123. document.getElementById('interaction-preview-video').play();
  124. // setTimeout(() => {
  125. // this.first = '';
  126. // }, 1000);
  127. },
  128. submitAdd(id, answer, content) {
  129. this.visible = false;
  130. document.getElementById('interaction-preview-video').play();
  131. setTimeout(() => {
  132. this.first = '';
  133. }, 1000);
  134. this.$set(this.userAnswer, id, answer);
  135. this.$set(this.exerciseList, id, content);
  136. },
  137. lookReport() {
  138. document.getElementById('interaction-preview-video').pause();
  139. let num = 0;
  140. let total = this.data.file_info_list.length;
  141. Object.keys(this.userAnswer).forEach((key) => {
  142. if (this.userAnswer[key].is_right) {
  143. num++;
  144. }
  145. });
  146. this.reportResult = {
  147. total: total,
  148. right: num,
  149. error: total - num,
  150. rightRate: ((num / total) * 100).toFixed(0) + '%',
  151. };
  152. this.reportFlag = true;
  153. },
  154. },
  155. };
  156. </script>
  157. <style lang="scss" scoped>
  158. @use '@/styles/mixin.scss' as *;
  159. video:full-screen {
  160. :fullscreen::-webkit-media-controls-fullscreen-button {
  161. display: none;
  162. }
  163. }
  164. video::-webkit-media-controls-fullscreen-button {
  165. display: none;
  166. }
  167. </style>