courseDetail.vue 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446
  1. <template>
  2. <div class="pb_content">
  3. <div class="pb_head">
  4. <span>课程管理</span>
  5. </div>
  6. <div
  7. class="pb_content_body"
  8. style="width: 100%; height: 89%; overflow: hidden"
  9. >
  10. <div class="cd_head">
  11. <div class="cd_bread">
  12. <el-breadcrumb separator-class="el-icon-arrow-right">
  13. <el-breadcrumb-item :to="{ path: '/course' }"
  14. >课程管理</el-breadcrumb-item
  15. >
  16. <el-breadcrumb-item>{{ course.title }}</el-breadcrumb-item>
  17. </el-breadcrumb>
  18. </div>
  19. <div class="cd_picture">
  20. <div class="cd_image">
  21. <el-image
  22. style="width: 350px; height: 200px"
  23. :src="course.imgUrl"
  24. fit="cover"
  25. ></el-image>
  26. </div>
  27. <div class="cd_title">
  28. <div>
  29. <div class="cd_title_name">
  30. <span>{{ course.title }}</span>
  31. </div>
  32. <!-- <div class="cd_rate">
  33. <el-rate></el-rate>
  34. </div> -->
  35. <div class="course_view">
  36. <i></i><span>{{ course.learning }}人在学</span>
  37. </div>
  38. </div>
  39. <div>
  40. <el-button type="primary" @click="dialogVisible = true"
  41. >查看课程视频</el-button
  42. >
  43. </div>
  44. </div>
  45. </div>
  46. </div>
  47. <div class="cd_boder"></div>
  48. <div class="cd_content">
  49. <div class="cd_content_nav">
  50. <div :class="{ active: show }" @click="show = true">
  51. <span>课程简介</span>
  52. </div>
  53. <div :class="{ active: !show }" @click="show = false">
  54. <span>学员查看</span>
  55. </div>
  56. </div>
  57. <div class="cd_content_intro" v-if="show">
  58. <span v-html="course.brief" class="cont"></span>
  59. </div>
  60. <div class="cd_content_stutents_box" v-else>
  61. <div class="cd_content_stutents">
  62. <div v-if="students.length == 0">
  63. <span>暂无学生</span>
  64. </div>
  65. <div class="student_box" v-for="index in students" :key="index">
  66. <span>{{ index.name }}</span>
  67. </div>
  68. </div>
  69. </div>
  70. </div>
  71. </div>
  72. <el-dialog
  73. title="查看课程视频"
  74. :visible.sync="dialogVisible"
  75. :append-to-body="true"
  76. width="750px"
  77. :before-close="handleClose"
  78. class="dialog_diy"
  79. >
  80. <div>
  81. <div class="pb_head" style="width: 100%">
  82. <span>{{ course.title }}</span>
  83. </div>
  84. <div>
  85. <div class="workd_head">
  86. <div class="workd_media">
  87. <!-- <el-image
  88. style="width: 100%; height: 300px"
  89. :src="require('../../assets/tu4.png')"
  90. ></el-image> -->
  91. <video-player
  92. class="video-player vjs-custom-skin"
  93. ref="videoPlayer"
  94. :playsinline="true"
  95. :options="playerO"
  96. @play="onPlayerPlay($event)"
  97. style="width: 100%; height: 100%"
  98. ></video-player>
  99. </div>
  100. <div class="cd_content_steps">
  101. <div
  102. class="cd_steps_box"
  103. v-for="(media, index) in course.mediaList"
  104. :key="media"
  105. @click="switchVideo(media, index)"
  106. >
  107. <!-- <i :class="{ active: index < 1 }"></i> -->
  108. <i
  109. :class="{
  110. active: playerOptions.sources[0].src == media,
  111. }"
  112. ></i>
  113. <span>视频{{ index + 1 }}</span>
  114. </div>
  115. </div>
  116. </div>
  117. </div>
  118. </div>
  119. <span slot="footer" style="display: flex; justify-content: center">
  120. <el-button @click="cancelM">关 闭</el-button>
  121. </span>
  122. </el-dialog>
  123. </div>
  124. </template>
  125. <script>
  126. export default {
  127. data() {
  128. return {
  129. show: true,
  130. id: this.$route.query.id,
  131. course: {},
  132. students: [],
  133. dialogVisible: false,
  134. playerOptions: {
  135. playbackRates: [0.7, 1.0, 1.5, 2.0], //播放速度
  136. autoplay: false, //如果true,浏览器准备好时开始回放。
  137. muted: false, // 默认情况下将会消除任何音频。
  138. loop: false, // 导致视频一结束就重新开始。
  139. preload: "auto", // 建议浏览器在<video>加载元素后是否应该开始下载视频数据。auto浏览器选择最佳行为,立即开始加载视频(如果浏览器支持)
  140. language: "zh-CN",
  141. aspectRatio: "16:9", // 将播放器置于流畅模式,并在计算播放器的动态大小时使用该值。值应该代表一个比例 - 用冒号分隔的两个数字(例如"16:9"或"4:3")
  142. fluid: true, // 当true时,Video.js player将拥有流体大小。换句话说,它将按比例缩放以适应其容器。
  143. sources: [
  144. {
  145. type: "video/mp4", //这里的种类支持很多种:基本视频格式、直播、流媒体等,具体可以参看git网址项目 || "video/ogg"|| "video/webm"
  146. src: "", //url地址require("../../assets/media/aaa.mp4")
  147. },
  148. ],
  149. // poster: require("../../assets/tu31.png"), //你的封面地址
  150. // poster: dataRes.imgUrl, //你的封面地址
  151. notSupportedMessage: "此视频暂无法播放,请稍后再试", //允许覆盖Video.js无法播放媒体源时显示的默认信息。
  152. controlBar: {
  153. timeDivider: true, //当前时间和持续时间的分隔符
  154. durationDisplay: true, //显示持续时间
  155. remainingTimeDisplay: false, //是否显示剩余时间功能
  156. fullscreenToggle: true, //全屏按钮
  157. },
  158. },
  159. playerO: {},
  160. };
  161. },
  162. methods: {
  163. getDetail() {
  164. const loading = this.$loading.service({
  165. background: "rgba(255, 255, 255, 0.7)",
  166. target: document.querySelector(".student_table"),
  167. });
  168. let params = {
  169. cid: this.id,
  170. };
  171. this.ajax
  172. .get(this.$store.state.api + "getCourseDetail", params)
  173. .then((res) => {
  174. loading.close();
  175. res.data[0].filter((element) => {
  176. element.imgUrl = JSON.parse(element.chapters).poster;
  177. element.mediaList = JSON.parse(element.chapters).midia.split(",");
  178. });
  179. this.course = res.data[0][0];
  180. this.students = res.data[1];
  181. this.playerOptions.poster = this.course.imgUrl;
  182. this.playerOptions.sources[0].src = this.course.mediaList[0];
  183. this.playerO = this.playerOptions;
  184. console.log(res.data);
  185. })
  186. .catch((err) => {
  187. loading.close();
  188. console.error(err);
  189. });
  190. },
  191. switchVideo(media, index) {
  192. this.playerO = {};
  193. this.playerOptions.poster = "";
  194. this.playerOptions.sources[0].src = media;
  195. this.playerO = this.playerOptions;
  196. },
  197. cancelM() {
  198. this.dialogVisible = false;
  199. this.$refs.videoPlayer.player.pause();
  200. },
  201. onPlayerPlay() {},
  202. handleClose(done) {
  203. this.$refs.videoPlayer.player.pause();
  204. done();
  205. },
  206. },
  207. created() {
  208. this.getDetail();
  209. },
  210. };
  211. </script>
  212. <style scoped>
  213. .course_view {
  214. display: flex;
  215. align-items: center;
  216. margin: 5px 0 0 0;
  217. font-size: 14px;
  218. }
  219. .course_view i {
  220. background-image: url("../../assets/liulan.png");
  221. width: 25px;
  222. height: 25px;
  223. background-size: 100% 100%;
  224. /* margin-top: 1px; */
  225. line-height: 25px;
  226. vertical-align: text-top;
  227. background-repeat: no-repeat;
  228. }
  229. .cd_head {
  230. background: #fff;
  231. width: 94%;
  232. margin: 0 auto;
  233. }
  234. .cd_bread {
  235. margin: 20px auto;
  236. }
  237. .cd_picture {
  238. display: flex;
  239. }
  240. .cd_image {
  241. margin-right: 20px;
  242. }
  243. .cd_title {
  244. margin-top: 10px;
  245. display: flex;
  246. flex-direction: column;
  247. justify-content: space-between;
  248. }
  249. .cd_title_name {
  250. font-size: 22px;
  251. }
  252. .cd_rate {
  253. margin: 10px 0;
  254. }
  255. .cd_boder {
  256. border: 5px solid #eee;
  257. width: 100%;
  258. margin-top: 30px;
  259. }
  260. .cd_content {
  261. width: 94%;
  262. margin: 20px auto;
  263. height: 59%;
  264. overflow: hidden;
  265. }
  266. .cd_content_nav {
  267. height: 55px;
  268. margin: 20px 0 0 0;
  269. display: flex;
  270. align-items: center;
  271. }
  272. .cd_content_nav div {
  273. font-size: 18px;
  274. margin-right: 20px;
  275. color: rgb(180, 180, 180);
  276. padding-bottom: 5px;
  277. box-sizing: border-box;
  278. }
  279. .cd_content_nav .active {
  280. border-bottom: 5px solid rgb(90, 124, 194);
  281. color: #000;
  282. }
  283. .cd_content_intro {
  284. width: 80%;
  285. height: 79%;
  286. overflow: auto;
  287. min-height: 300px;
  288. }
  289. .cd_content_intro span {
  290. text-indent: 2em;
  291. display: block;
  292. line-height: 27px;
  293. }
  294. .cd_content_stutents_box {
  295. width: 80%;
  296. height: 79%;
  297. overflow: auto;
  298. min-height: 300px;
  299. }
  300. .cd_content_stutents {
  301. display: flex;
  302. flex-wrap: wrap;
  303. }
  304. .student_box {
  305. width: 120px;
  306. margin: 10px 10px 0 0;
  307. background: rgb(227, 117, 154);
  308. height: 40px;
  309. line-height: 40px;
  310. text-align: center;
  311. border-radius: 5px;
  312. color: #fff;
  313. }
  314. /* table 样式 */
  315. .cont >>> table {
  316. border-top: 1px solid #ccc;
  317. border-left: 1px solid #ccc;
  318. }
  319. .cont >>> table td,
  320. .cont >>> table th {
  321. border-bottom: 1px solid #ccc;
  322. border-right: 1px solid #ccc;
  323. padding: 3px 5px;
  324. }
  325. .cont >>> table th {
  326. border-bottom: 2px solid #ccc;
  327. text-align: center;
  328. }
  329. /* blockquote 样式 */
  330. .cont >>> blockquote {
  331. display: block;
  332. border-left: 8px solid #d0e5f2;
  333. padding: 5px 10px;
  334. margin: 10px 0;
  335. line-height: 1.4;
  336. font-size: 100%;
  337. background-color: #f1f1f1;
  338. }
  339. /* code 样式 */
  340. .cont >>> code {
  341. display: inline-block;
  342. *display: inline;
  343. *zoom: 1;
  344. background-color: #f1f1f1;
  345. border-radius: 3px;
  346. padding: 3px 5px;
  347. margin: 0 3px;
  348. }
  349. .cont >>> pre code {
  350. display: block;
  351. }
  352. /* ul ol 样式 */
  353. .cont >>> ul,
  354. ol {
  355. margin: 10px 0 10px 20px;
  356. }
  357. .workd_media {
  358. width: 100%;
  359. height: 400px;
  360. }
  361. .pb_head {
  362. font-size: 26px;
  363. /* font-weight: 600; */
  364. width: 95%;
  365. margin: 10px auto;
  366. padding: 10px 5px;
  367. border-bottom: 3px solid #eee;
  368. }
  369. .cd_content_steps {
  370. display: flex;
  371. width: 90%;
  372. margin: 15px auto 0;
  373. padding: 15px 0 0 0;
  374. justify-content: space-around;
  375. border-top: 1px solid #eeeeee;
  376. }
  377. .cd_steps_box {
  378. display: flex;
  379. justify-content: center;
  380. align-items: center;
  381. flex-direction: column;
  382. cursor: pointer;
  383. }
  384. .cd_steps_box i {
  385. background-image: url("../../assets/dui.png");
  386. width: 15px;
  387. height: 15px;
  388. background-size: 100% 100%;
  389. display: inline-block;
  390. line-height: 15px;
  391. vertical-align: text-top;
  392. background-repeat: no-repeat;
  393. }
  394. .cd_steps_box span {
  395. font-size: 15px;
  396. margin-top: 5px;
  397. }
  398. .cd_steps_box .active {
  399. background-image: url("../../assets/dui-active.png");
  400. }
  401. .dialog_diy >>> .el-dialog {
  402. background: #fafafa;
  403. }
  404. .dialog_diy >>> .el-dialog__header {
  405. background: #3d67bc !important;
  406. padding: 15px 20px;
  407. }
  408. .dialog_diy >>> .el-dialog__title {
  409. color: #fff;
  410. }
  411. .dialog_diy >>> .el-dialog__headerbtn {
  412. top: 19px;
  413. }
  414. .dialog_diy >>> .el-dialog__headerbtn .el-dialog__close {
  415. color: #fff;
  416. }
  417. .dialog_diy >>> .el-dialog__headerbtn .el-dialog__close:hover {
  418. color: #fff;
  419. }
  420. </style>