CurMaterial.vue 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236
  1. <template>
  2. <el-dialog
  3. :class="['cur-material', { 'align-left': !isAlignCenter }]"
  4. :visible="dialogVisibleMaterial"
  5. :modal="false"
  6. width="900px"
  7. @close="dialogMaterialClose"
  8. >
  9. <div slot="title" class="dialog-header">
  10. <span class="dialog-header-title">当前推送课件</span>
  11. <span @click="isAlignCenter = !isAlignCenter">
  12. <svg-icon :icon-class="isAlignCenter ? 'align-center' : 'align-left'" />
  13. </span>
  14. </div>
  15. <div class="material-name">{{ materialName }}</div>
  16. <template v-if="materialType === 'COURSEWARE'">
  17. <bookquestion
  18. ref="courseware"
  19. :context="context"
  20. @handleBookUserAnswer="handleBookUserAnswer"
  21. />
  22. </template>
  23. <template v-else>
  24. <template v-if="fileType === 'pdf'">
  25. <pdf v-for="i in numPages" :key="i" :src="pdfSrc" :page="i"></pdf>
  26. </template>
  27. <template v-else-if="isImage(fileType)">
  28. <el-image fit="contain" :src="file_url_https" />
  29. </template>
  30. <template v-if="fileType !== 'pdf'">
  31. <iframe
  32. :src="'https://view.officeapps.live.com/op/view.aspx?src=' + `${file_url_https}`"
  33. width="100%"
  34. height="490px"
  35. scrolling="no"
  36. >
  37. </iframe>
  38. </template>
  39. </template>
  40. <div slot="footer">
  41. <el-button type="primary" @click="finishMyMaterial">完成</el-button>
  42. </div>
  43. </el-dialog>
  44. </template>
  45. <script>
  46. import pdf from 'vue-pdf';
  47. import { GetCoursewareContent_View } from '@/api/course';
  48. import { GetFileStoreInfo } from '@/api/app';
  49. import { FinishMyMaterial } from '@/api/live';
  50. export default {
  51. components: {
  52. pdf
  53. },
  54. props: {
  55. dialogVisibleMaterial: {
  56. default: false,
  57. type: Boolean
  58. },
  59. taskId: {
  60. default: '',
  61. type: String
  62. },
  63. materialId: {
  64. default: '',
  65. type: String
  66. },
  67. materialName: {
  68. default: '',
  69. type: String
  70. },
  71. materialType: {
  72. default: '',
  73. type: String
  74. },
  75. materialPictureUrl: {
  76. default: '',
  77. type: String
  78. }
  79. },
  80. data() {
  81. return {
  82. context: null,
  83. exam_answer: '',
  84. file_relative_path: '',
  85. file_url_https: '',
  86. pdfSrc: '',
  87. numPages: 1,
  88. isAlignCenter: true
  89. };
  90. },
  91. computed: {
  92. fileType() {
  93. return this.file_url_https.slice(
  94. this.file_url_https.lastIndexOf('.') + 1,
  95. this.file_url_https.length
  96. );
  97. }
  98. },
  99. watch: {
  100. dialogVisibleMaterial(newVal) {
  101. if (!newVal) {
  102. this.context = null;
  103. this.exam_answer = '';
  104. this.file_relative_path = '';
  105. this.file_url_https = '';
  106. this.pdfSrc = '';
  107. this.numPages = 1;
  108. }
  109. },
  110. materialId() {
  111. if (this.materialType === 'COURSEWARE') {
  112. this.getCoursewareContent_View();
  113. } else {
  114. this.getFileStoreInfo();
  115. }
  116. }
  117. },
  118. methods: {
  119. dialogMaterialClose() {
  120. this.$emit('dialogMaterialClose');
  121. },
  122. getCoursewareContent_View() {
  123. GetCoursewareContent_View({ id: this.materialId }).then(({ content }) => {
  124. if (content) {
  125. this.context = {
  126. id: this.materialId,
  127. ui_type: JSON.parse(content).question.ui_type,
  128. content: JSON.parse(content)
  129. };
  130. this.$nextTick(() => {
  131. this.$refs.courseware.handleAnswerTimeStart();
  132. });
  133. } else {
  134. this.context = null;
  135. }
  136. });
  137. },
  138. getFileStoreInfo() {
  139. GetFileStoreInfo({ file_id: this.materialId }).then(
  140. ({ file_relative_path, file_url_https }) => {
  141. this.file_relative_path = file_relative_path;
  142. this.file_url_https = file_url_https;
  143. let fileType = file_url_https.slice(
  144. file_url_https.lastIndexOf('.') + 1,
  145. file_url_https.length
  146. );
  147. if (fileType === 'pdf') {
  148. this.getNumPages(file_url_https);
  149. }
  150. }
  151. );
  152. },
  153. getNumPages(url) {
  154. let loadingTask = pdf.createLoadingTask(url);
  155. loadingTask.promise
  156. .then(pdf => {
  157. this.pdfSrc = loadingTask;
  158. this.numPages = pdf.numPages;
  159. })
  160. .catch(err => {
  161. console.error('pdf加载失败', err);
  162. this.$message.error('pdf加载失败');
  163. });
  164. },
  165. handleBookUserAnswer(data) {
  166. this.exam_answer = data;
  167. },
  168. finishMyMaterial() {
  169. FinishMyMaterial({
  170. task_id: this.taskId,
  171. material_id: this.materialId,
  172. material_type: this.materialType,
  173. exam_answer: this.exam_answer
  174. }).then(() => {
  175. this.$message.success('完成推送资料成功');
  176. this.$emit('dialogMaterialClose');
  177. });
  178. },
  179. isImage(type) {
  180. return ['jpeg', 'gif', 'jpg', 'png', 'bmp', 'pic', 'svg'].includes(type);
  181. }
  182. }
  183. };
  184. </script>
  185. <style lang="scss">
  186. @import '~@/styles/mixin.scss';
  187. .cur-material {
  188. @include dialog;
  189. &.align-left {
  190. .el-dialog {
  191. margin-left: 20px;
  192. }
  193. }
  194. .el-dialog__header {
  195. .dialog-header {
  196. display: flex;
  197. justify-content: space-between;
  198. padding-right: 24px;
  199. &-title {
  200. font-weight: bold;
  201. font-size: 18px;
  202. line-height: 24px;
  203. }
  204. .svg-icon {
  205. cursor: pointer;
  206. }
  207. }
  208. }
  209. .material-name {
  210. font-size: 16px;
  211. font-weight: 700;
  212. color: #000;
  213. margin-bottom: 16px;
  214. }
  215. }
  216. </style>