courseDetail.vue 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267
  1. <template>
  2. <view class="details">
  3. <!-- 视频 -->
  4. <video-box ref="videoBox" v-if="isPlay" :videoUrl="videoInfo.videoUrl" @recordDuration="recordDuration"></video-box>
  5. <!-- 介绍 -->
  6. <view class="details-content">
  7. <view class="details-content-title">{{ videoInfo.chapterName }}</view>
  8. <view class="details-content-progress">本课程 共{{ info.amount }}课,已学完{{ info.finishCount }}课,共进度{{ info.finishPercent || 0 }}%</view>
  9. <view class="details-content-teacher">主讲老师:{{ info.presenter }}</view>
  10. <view class="details-content-info">{{ videoInfo.chapterInfo }}</view>
  11. </view>
  12. <!-- 课程章节 -->
  13. <view class="details-classes">
  14. <view class="details-classes-header">
  15. <view>精选课程</view>
  16. <view
  17. >更多
  18. <u-icon name="arrow-right" size="22" color="#A3A3A3" />
  19. </view>
  20. </view>
  21. <view class="details-classes-list">
  22. <view
  23. class="details-classes-list-item"
  24. v-for="(item, index) in info.chapterList"
  25. :key="index"
  26. :class="{ active: index === videoIndex }"
  27. @click="classesClick(index)"
  28. >
  29. <view>{{ index + 1 }}</view>
  30. <view>{{ item.flag === 2 ? '已学' : item.finishPercent + '%' }}</view>
  31. </view>
  32. </view>
  33. </view>
  34. <view class="details-line">
  35. <view></view>
  36. </view>
  37. <!-- 评论 -->
  38. <view class="details-comment">
  39. <view class="details-comment-header">
  40. <view>课程评论</view>
  41. <view>共{{ total }}条评论</view>
  42. </view>
  43. <view class="details-comment-list">
  44. <view class="details-comment-list-item" v-for="(item, index) in commentList" :key="index">
  45. <view class="left">
  46. <u-avatar :src="item.createByAvatar" size="96" mode="square"></u-avatar>
  47. </view>
  48. <view class="right">
  49. <view>{{ item.createBy }}</view>
  50. <view>
  51. <u-rate :count="5" size="24" disabled="" active-color="#C4C4C4" v-model="item.starLevel"> </u-rate>
  52. <text>{{ item.createTime }}</text>
  53. </view>
  54. <view>{{ item.content }}</view>
  55. </view>
  56. </view>
  57. </view>
  58. <view class="details-comment-page" v-if="total">
  59. <wyb-pagination :padding="0" :totalItems="total" :current="query.pageNum" @change="pageChange" />
  60. </view>
  61. <view class="details-comment-mine">
  62. <text>我的评论</text>
  63. </view>
  64. <view class="details-comment-conent">
  65. <view class="details-comment-conent-star">
  66. <u-rate :count="5" size="40" active-color="#FFBC00" v-model="form.starLevel"></u-rate>
  67. </view>
  68. <view class="details-comment-content-textarea">
  69. <u-input
  70. v-model="form.content"
  71. placeholder="请输入您的评价"
  72. type="textarea"
  73. :custom-style="{ backgroundColor: '#F5F5F5', padding: '30rpx', borderRadius: '10rpx', minHeight: '280rpx' }"
  74. >
  75. </u-input>
  76. </view>
  77. <view class="details-comment-conent-button" @click="submitCommet">提交</view>
  78. </view>
  79. </view>
  80. <u-toast ref="uToast" />
  81. </view>
  82. </template>
  83. <script>
  84. export default {
  85. data() {
  86. return {
  87. info: {},
  88. videoInfo: {},
  89. videoIndex: 0,
  90. classesId: '',
  91. isPlay: true,
  92. query: {
  93. pageNum: 1,
  94. pageSize: 5,
  95. tabId: ''
  96. },
  97. total: 0,
  98. commentList: [],
  99. form: {
  100. tabId: '',
  101. starLevel: 0,
  102. content: ''
  103. }
  104. };
  105. },
  106. onLoad(page) {
  107. if (page.id) {
  108. this.getClassesDetails(page.id);
  109. this.classesId = page.id;
  110. this.query.tabId = this.classesId;
  111. this.form.tabId = this.classesId;
  112. }
  113. },
  114. beforeDestroy() {
  115. this.$refs['videoBox'].recordDuration(this.videoIndex, false);
  116. },
  117. methods: {
  118. /**
  119. * 获取课程详情
  120. * @param {Object} id
  121. */
  122. getClassesDetails(id) {
  123. this.videoLoading = true;
  124. this.$u.api.school
  125. .getPackageCourseDetail({
  126. id
  127. })
  128. .then((res) => {
  129. if (res.code === 200) {
  130. this.info = res.data;
  131. this.videoInfo = res.data.chapterList[this.videoIndex];
  132. this.query.pageNum = 1;
  133. this.isPlay = true;
  134. this.$nextTick(() => {
  135. this.$refs['videoBox'].loadVideo(this.videoInfo);
  136. });
  137. this.getCommentList();
  138. }
  139. });
  140. },
  141. /**
  142. * 课程章节点击
  143. * @param {Object} index
  144. */
  145. classesClick(index) {
  146. this.$refs['videoBox'].recordDuration(index, true);
  147. this.videoIndex = index;
  148. this.isPlay = false;
  149. },
  150. /**
  151. * 描述
  152. * @date 2022-10-19
  153. * @param {any} obj
  154. * @param {any} index
  155. * @returns {any}
  156. */
  157. recordDuration(obj, index, refresh = true) {
  158. this.submitTimeLong(
  159. { tabId: this.videoInfo.id, playDuration: obj.playDuration, currentDuration: obj.currentDuration, duration: obj.duration },
  160. index || this.videoIndex,
  161. refresh
  162. );
  163. },
  164. /**
  165. * 提交课程时长
  166. */
  167. submitTimeLong({ tabId, playDuration, duration, currentDuration }, index, refresh) {
  168. if (tabId) {
  169. this.$u.api.training
  170. .videoTimeLongApi({
  171. tabId,
  172. playDuration,
  173. duration,
  174. currentDuration
  175. })
  176. .then((res) => {
  177. if (res.code === 200) {
  178. this.videoInfo = this.info.chapterList[index];
  179. if (refresh) {
  180. this.$refs.uToast.show({
  181. title: '已记录章节时长!',
  182. type: 'success'
  183. });
  184. this.getClassesDetails(this.classesId);
  185. }
  186. } else {
  187. this.$refs.uToast.show({
  188. title: res.msg,
  189. type: 'error'
  190. });
  191. }
  192. });
  193. }
  194. },
  195. /**
  196. * 获取评论列表
  197. */
  198. getCommentList() {
  199. if (this.query.tabId) {
  200. this.$u.api.training.getClassesCommentApi(this.query).then((res) => {
  201. if (res.code === 200) {
  202. this.total = Number(res.total);
  203. this.commentList = res.rows;
  204. }
  205. });
  206. }
  207. },
  208. /**
  209. * @param {Object} e 分页触发
  210. */
  211. pageChange(e) {
  212. this.query.pageNum = e.current;
  213. this.getCommentList();
  214. },
  215. /**
  216. * 提交评论
  217. */
  218. submitCommet() {
  219. if (this.form.tabId) {
  220. if (this.form.starLevel && this.form.content) {
  221. this.$u.api.training.addClassesCommentApi(this.form).then((res) => {
  222. if (res.code === 200) {
  223. this.$refs.uToast.show({
  224. title: '评论成功!',
  225. type: 'success'
  226. });
  227. this.form.content = '';
  228. this.form.starLevel = 0;
  229. this.getCommentList();
  230. } else {
  231. this.$refs.uToast.show({
  232. title: res.msg,
  233. type: 'error'
  234. });
  235. }
  236. });
  237. }
  238. if (!this.form.starLevel) {
  239. this.$refs.uToast.show({
  240. title: '请选择星级',
  241. type: 'warning'
  242. });
  243. }
  244. if (!this.form.content) {
  245. this.$refs.uToast.show({
  246. title: '请输入评论内容',
  247. type: 'warning'
  248. });
  249. }
  250. } else {
  251. this.$refs.uToast.show({
  252. title: '未找到课程章节,无法提交评论!',
  253. type: 'warning'
  254. });
  255. }
  256. }
  257. }
  258. };
  259. </script>
  260. <style lang="scss" scoped>
  261. @import './courseDetail.scss';
  262. </style>