VideoInteractionPreview.vue 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. <!-- eslint-disable vue/no-v-html -->
  2. <template>
  3. <div class="imageText-preview" :style="[getAreaStyle(), getComponentStyle()]">
  4. <SerialNumberPosition v-if="isEnable(data.property.sn_display_mode)" :property="data.property" />
  5. <div v-if="data.video_list.length > 0" class="interaction-box">
  6. <video
  7. id="interaction-preview-video"
  8. :src="data.video_list[0].file_url"
  9. width="100%"
  10. height="400"
  11. controls
  12. controlsList="nodownload"
  13. @timeupdate="handleTimeUpdate"
  14. ></video>
  15. </div>
  16. <!-- v-if="Object.keys(this.userAnswer).length === data.file_info_list.length" -->
  17. <el-button
  18. type="primary"
  19. :style="{
  20. background:
  21. data.unified_attrib && data.unified_attrib.topic_color ? data.unified_attrib.topic_color : '#165dff',
  22. borderColor:
  23. data.unified_attrib && data.unified_attrib.topic_color ? data.unified_attrib.topic_color : '#165dff',
  24. }"
  25. @click="lookReport"
  26. >{{ convertText('查看答题报告') }}</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" />
  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. :report-result="reportResult"
  54. :exercise-list="exerciseList"
  55. :user-answer="userAnswer"
  56. :file-list="data.file_info_list"
  57. @handleCancle="handleClose"
  58. />
  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. props: {
  73. isMobile: {
  74. type: Boolean,
  75. default: false,
  76. },
  77. },
  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. isJudgingRightWrong(val) {
  101. if (!val) return;
  102. this.userAnswer = this.answer.answer_list[0];
  103. },
  104. },
  105. created() {
  106. this.initData();
  107. },
  108. mounted() {},
  109. methods: {
  110. initData() {
  111. this.data.file_info_list = this.data.file_info_list.sort((a, b) => Number(a.currentTime) - Number(b.currentTime));
  112. if (!this.isJudgingRightWrong) {
  113. this.answer.answer_list[0] = this.userAnswer;
  114. }
  115. },
  116. handleTimeUpdate(event) {
  117. let currentTime = event.target.currentTime;
  118. this.data.file_info_list.forEach((item) => {
  119. if (
  120. Number(item.currentTime) > Math.floor(currentTime) &&
  121. Number(item.currentTime) < Math.floor(currentTime) + 1 &&
  122. item.id !== this.first
  123. ) {
  124. this.first = item.id;
  125. document.getElementById('interaction-preview-video').pause();
  126. this.exercise_id = item.id;
  127. this.visible = true;
  128. // GetFileURLMap({ file_id_list: [item.file_id] }).then(({ url_map }) => {
  129. // this.newpath = `${this.file_preview_url}onlinePreview?url=${Base64.encode(url_map[item.file_id])}`;
  130. // this.visible = true;
  131. // });
  132. }
  133. });
  134. },
  135. handleClose() {
  136. this.reportFlag = false;
  137. document.getElementById('interaction-preview-video').play();
  138. // setTimeout(() => {
  139. // this.first = '';
  140. // }, 1000);
  141. },
  142. submitAdd(id, answer, content) {
  143. this.visible = false;
  144. document.getElementById('interaction-preview-video').play();
  145. setTimeout(() => {
  146. this.first = '';
  147. }, 1000);
  148. this.$set(this.userAnswer, id, answer);
  149. this.$set(this.exerciseList, id, content);
  150. },
  151. lookReport() {
  152. document.getElementById('interaction-preview-video').pause();
  153. let num = 0;
  154. let total = this.data.file_info_list.length;
  155. Object.keys(this.userAnswer).forEach((key) => {
  156. if (this.userAnswer[key].is_right) {
  157. num++;
  158. }
  159. });
  160. this.reportResult = {
  161. total,
  162. right: num,
  163. error: total - num,
  164. rightRate: `${((num / total) * 100).toFixed(0)}%`,
  165. };
  166. this.reportFlag = true;
  167. },
  168. },
  169. };
  170. </script>
  171. <style lang="scss" scoped>
  172. @use '@/styles/mixin.scss' as *;
  173. video:full-screen {
  174. :fullscreen::-webkit-media-controls-fullscreen-button {
  175. display: none;
  176. }
  177. }
  178. video::-webkit-media-controls-fullscreen-button {
  179. display: none;
  180. }
  181. </style>