VideoInteractionPreview.vue 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  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. <PreviewOperation @showAnswerAnalysis="showAnswerAnalysis" />
  29. <AnswerAnalysis
  30. :visible.sync="visibleAnswerAnalysis"
  31. :answer-list="data.answer_list"
  32. :analysis-list="data.analysis_list"
  33. @closeAnswerAnalysis="closeAnswerAnalysis"
  34. />
  35. <el-dialog
  36. v-if="visible"
  37. :visible.sync="visible"
  38. :show-close="false"
  39. :close-on-click-modal="true"
  40. :modal-append-to-body="true"
  41. :append-to-body="true"
  42. :lock-scroll="true"
  43. width="80%"
  44. >
  45. <ExercisePreview :exercise_id="exercise_id" @handleCancle="handleClose" @submitAdd="submitAdd" />
  46. <!-- <iframe v-if="visible" :src="newpath" width="100%" :height="iframeHeight" frameborder="0"></iframe> -->
  47. </el-dialog>
  48. <el-dialog
  49. v-if="reportFlag"
  50. :visible.sync="reportFlag"
  51. :show-close="true"
  52. :close-on-click-modal="true"
  53. :modal-append-to-body="true"
  54. :append-to-body="true"
  55. :lock-scroll="true"
  56. :width="isMobile ? '100%' : '80%'"
  57. @close="handleClose"
  58. >
  59. <Report
  60. :report-result="reportResult"
  61. :exercise-list="exerciseList"
  62. :user-answer="userAnswer"
  63. :file-list="data.file_info_list"
  64. @handleCancle="handleClose"
  65. />
  66. </el-dialog>
  67. </div>
  68. </template>
  69. <script>
  70. import ExercisePreview from './ExercisePreview.vue';
  71. import Report from './Report.vue';
  72. import PreviewMixin from '../common/PreviewMixin';
  73. import { getVideoInteractionData } from '@/views/book/courseware/data/videoInteraction';
  74. import { getConfig } from '@/utils/auth';
  75. export default {
  76. name: 'VideoInteractionPreview',
  77. components: { ExercisePreview, Report },
  78. mixins: [PreviewMixin],
  79. props: {
  80. isMobile: {
  81. type: Boolean,
  82. default: false,
  83. },
  84. },
  85. data() {
  86. return {
  87. data: getVideoInteractionData(),
  88. video_info: null,
  89. file_preview_url: getConfig() ? getConfig().doc_preview_service_address : '',
  90. visible: false,
  91. newpath: '',
  92. iframeHeight: `${window.innerHeight - 100}px`,
  93. first: '',
  94. exercise_id: '',
  95. userAnswer: {}, // 用户答题答案
  96. exerciseList: {}, // 题目列表
  97. reportFlag: false,
  98. reportResult: {
  99. total: 0,
  100. right: 0,
  101. error: 0,
  102. rightRate: 0,
  103. },
  104. };
  105. },
  106. watch: {
  107. isJudgingRightWrong(val) {
  108. if (!val) return;
  109. this.userAnswer = this.answer.answer_list[0];
  110. },
  111. },
  112. created() {
  113. this.initData();
  114. },
  115. mounted() {},
  116. methods: {
  117. initData() {
  118. this.data.file_info_list = this.data.file_info_list.sort((a, b) => Number(a.currentTime) - Number(b.currentTime));
  119. if (!this.isJudgingRightWrong) {
  120. this.answer.answer_list[0] = this.userAnswer;
  121. }
  122. },
  123. handleTimeUpdate(event) {
  124. let currentTime = event.target.currentTime;
  125. this.data.file_info_list.forEach((item) => {
  126. if (
  127. Number(item.currentTime) > Math.floor(currentTime) &&
  128. Number(item.currentTime) < Math.floor(currentTime) + 1 &&
  129. item.id !== this.first
  130. ) {
  131. this.first = item.id;
  132. document.getElementById('interaction-preview-video').pause();
  133. this.exercise_id = item.id;
  134. this.visible = true;
  135. // GetFileURLMap({ file_id_list: [item.file_id] }).then(({ url_map }) => {
  136. // this.newpath = `${this.file_preview_url}onlinePreview?url=${Base64.encode(url_map[item.file_id])}`;
  137. // this.visible = true;
  138. // });
  139. }
  140. });
  141. },
  142. handleClose() {
  143. this.reportFlag = false;
  144. document.getElementById('interaction-preview-video').play();
  145. // setTimeout(() => {
  146. // this.first = '';
  147. // }, 1000);
  148. },
  149. submitAdd(id, answer, content) {
  150. this.visible = false;
  151. document.getElementById('interaction-preview-video').play();
  152. setTimeout(() => {
  153. this.first = '';
  154. }, 1000);
  155. this.$set(this.userAnswer, id, answer);
  156. this.$set(this.exerciseList, id, content);
  157. },
  158. lookReport() {
  159. document.getElementById('interaction-preview-video').pause();
  160. let num = 0;
  161. let total = this.data.file_info_list.length;
  162. Object.keys(this.userAnswer).forEach((key) => {
  163. if (this.userAnswer[key].is_right) {
  164. num++;
  165. }
  166. });
  167. this.reportResult = {
  168. total,
  169. right: num,
  170. error: total - num,
  171. rightRate: `${((num / total) * 100).toFixed(0)}%`,
  172. };
  173. this.reportFlag = true;
  174. },
  175. },
  176. };
  177. </script>
  178. <style lang="scss" scoped>
  179. @use '@/styles/mixin.scss' as *;
  180. video:full-screen {
  181. :fullscreen::-webkit-media-controls-fullscreen-button {
  182. display: none;
  183. }
  184. }
  185. video::-webkit-media-controls-fullscreen-button {
  186. display: none;
  187. }
  188. </style>