VideoInteractionPreview.vue 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  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="isMobile ? '100%' : '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. props: {
  71. isMobile: {
  72. type: Boolean,
  73. default: false,
  74. },
  75. },
  76. components: { ExercisePreview, Report },
  77. mixins: [PreviewMixin],
  78. data() {
  79. return {
  80. data: getVideoInteractionData(),
  81. video_info: null,
  82. file_preview_url: getConfig() ? getConfig().doc_preview_service_address : '',
  83. visible: false,
  84. newpath: '',
  85. iframeHeight: `${window.innerHeight - 100}px`,
  86. first: '',
  87. exercise_id: '',
  88. userAnswer: {}, // 用户答题答案
  89. exerciseList: {}, // 题目列表
  90. reportFlag: false,
  91. reportResult: {
  92. total: 0,
  93. right: 0,
  94. error: 0,
  95. rightRate: 0,
  96. },
  97. };
  98. },
  99. watch: {},
  100. created() {
  101. this.initData();
  102. },
  103. mounted() {},
  104. methods: {
  105. initData() {
  106. this.data.file_info_list = this.data.file_info_list.sort((a, b) => Number(a.currentTime) - Number(b.currentTime));
  107. },
  108. handleTimeUpdate(event) {
  109. let currentTime = event.target.currentTime;
  110. this.data.file_info_list.forEach((item) => {
  111. if (
  112. Number(item.currentTime) > Math.floor(currentTime) &&
  113. Number(item.currentTime) < Math.floor(currentTime) + 1 &&
  114. item.id !== this.first
  115. ) {
  116. this.first = item.id;
  117. document.getElementById('interaction-preview-video').pause();
  118. this.exercise_id = item.id;
  119. this.visible = true;
  120. // GetFileURLMap({ file_id_list: [item.file_id] }).then(({ url_map }) => {
  121. // this.newpath = `${this.file_preview_url}onlinePreview?url=${Base64.encode(url_map[item.file_id])}`;
  122. // this.visible = true;
  123. // });
  124. }
  125. });
  126. },
  127. handleClose() {
  128. this.reportFlag = false;
  129. document.getElementById('interaction-preview-video').play();
  130. // setTimeout(() => {
  131. // this.first = '';
  132. // }, 1000);
  133. },
  134. submitAdd(id, answer, content) {
  135. this.visible = false;
  136. document.getElementById('interaction-preview-video').play();
  137. setTimeout(() => {
  138. this.first = '';
  139. }, 1000);
  140. this.$set(this.userAnswer, id, answer);
  141. this.$set(this.exerciseList, id, content);
  142. },
  143. lookReport() {
  144. document.getElementById('interaction-preview-video').pause();
  145. let num = 0;
  146. let total = this.data.file_info_list.length;
  147. Object.keys(this.userAnswer).forEach((key) => {
  148. if (this.userAnswer[key].is_right) {
  149. num++;
  150. }
  151. });
  152. this.reportResult = {
  153. total: total,
  154. right: num,
  155. error: total - num,
  156. rightRate: ((num / total) * 100).toFixed(0) + '%',
  157. };
  158. this.reportFlag = true;
  159. },
  160. },
  161. };
  162. </script>
  163. <style lang="scss" scoped>
  164. @use '@/styles/mixin.scss' as *;
  165. video:full-screen {
  166. :fullscreen::-webkit-media-controls-fullscreen-button {
  167. display: none;
  168. }
  169. }
  170. video::-webkit-media-controls-fullscreen-button {
  171. display: none;
  172. }
  173. </style>