live-detail.tsx 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248
  1. import CoursePlanStep from '@/business-components/course-plan-step'
  2. import SectionDetail from '@/business-components/section-detail'
  3. import UserDetail from '@/business-components/user-detail'
  4. import request from '@/helpers/request'
  5. import dayjs from 'dayjs'
  6. import { Icon, Sticky, Button, Dialog } from 'vant'
  7. import { defineComponent } from 'vue'
  8. import styles from './live-detail.module.less'
  9. import iconTips from '@common/images/icon_tips.png'
  10. import { orderStatus } from '@/views/order-detail/orderStatus'
  11. import ColHeader from '@/components/col-header'
  12. import { postMessage } from '@/helpers/native-message'
  13. interface IProps {
  14. courseTime: string
  15. coursePlan: string
  16. videoPosterUrl?: string
  17. id?: number | string
  18. }
  19. export default defineComponent({
  20. name: 'LiveDetail',
  21. data() {
  22. const query = this.$route.query
  23. return {
  24. joinRoom: query.joinRoom, // 原生传递过来的参数,判断是否进入直播间
  25. groupId: query.groupId,
  26. courseId: query.classId,
  27. live: {} as any
  28. }
  29. },
  30. computed: {
  31. userInfo() {
  32. const live = this.live as any
  33. const planList = live.planList || []
  34. const startTime = planList[0]?.startTime || new Date()
  35. const endTime = planList[0]?.endTime || new Date()
  36. return {
  37. headUrl: live.avatar,
  38. username: live.userName || `游客${live.teacherId || ''}`,
  39. startTime:
  40. `${dayjs(startTime).format('YYYY-MM-DD')} ${dayjs(startTime).format(
  41. 'HH:mm'
  42. )}~${dayjs(endTime).format('HH:mm')}` || '',
  43. buyNum: live.studentCount,
  44. lessonPrice: live.coursePrice,
  45. lessonNum: live.courseNum,
  46. lessonDesc: live.courseIntroduce,
  47. lessonCoverUrl: live.backgroundPic || live.backgroundPicTemplate,
  48. lessonName: live.courseGroupName
  49. }
  50. },
  51. courseInfo() {
  52. let tempArr = [] as IProps[]
  53. const coursePlanList = this.live.planList || []
  54. coursePlanList.forEach((item: any) => {
  55. const startTime = item.startTime || new Date()
  56. const endTime = item.endTime || new Date()
  57. tempArr.push({
  58. courseTime: `${dayjs(startTime).format('YYYY-MM-DD')} ${dayjs(
  59. startTime
  60. ).format('HH:mm')}~${dayjs(endTime).format('HH:mm')}`,
  61. coursePlan: item.plan,
  62. id: item.courseId
  63. })
  64. })
  65. return tempArr || []
  66. },
  67. salesEndDate() {
  68. const live = this.live as any
  69. return dayjs(live.salesEndDate || new Date()).format('YYYY-MM-DD')
  70. },
  71. liveStatus() {
  72. const coursePlanList = this.live.planList || []
  73. const tempObj = {
  74. status: false,
  75. roomUid: ''
  76. }
  77. coursePlanList.forEach((item: any) => {
  78. if (item.courseId === Number(this.courseId)) {
  79. tempObj.status = true
  80. tempObj.roomUid = item.roomUid
  81. }
  82. })
  83. return tempObj
  84. }
  85. },
  86. async mounted() {
  87. try {
  88. const res = await request.get(
  89. '/api-student/courseGroup/queryLiveCourseInfo',
  90. {
  91. params: {
  92. groupId: this.groupId
  93. }
  94. }
  95. )
  96. this.live = res.data || {}
  97. } catch {}
  98. },
  99. methods: {
  100. async onBuy() {
  101. try {
  102. const res = await request.post(
  103. '/api-student/userOrder/getPendingOrder',
  104. {
  105. data: {
  106. goodType: 'LIVE',
  107. bizId: this.groupId
  108. }
  109. }
  110. )
  111. console.log(res, res.data)
  112. const live = this.live
  113. orderStatus.orderObject.orderType = 'LIVE'
  114. orderStatus.orderObject.orderName = '直播课购买'
  115. orderStatus.orderObject.orderDesc = '直播课购买'
  116. orderStatus.orderObject.actualPrice = live.coursePrice
  117. orderStatus.orderObject.orderNo = ''
  118. orderStatus.orderObject.orderList = [
  119. {
  120. orderType: 'LIVE',
  121. goodsName: '直播课购买',
  122. courseGroupId: live.courseGroupId,
  123. courseGroupName: live.courseGroupName,
  124. coursePrice: live.coursePrice,
  125. teacherName: live.teacherName || `游客${live.teacherId || ''}`,
  126. teacherId: live.teacherId,
  127. avatar: live.avatar,
  128. courseInfo: this.courseInfo
  129. }
  130. ]
  131. const result = res.data
  132. if (result) {
  133. Dialog.confirm({
  134. title: '提示',
  135. message: '您有一个未支付的订单,是否继续支付?',
  136. confirmButtonColor: '#269a93',
  137. cancelButtonText: '取消订单',
  138. confirmButtonText: '继续支付'
  139. })
  140. .then(async () => {
  141. orderStatus.orderObject.orderNo = result.orderNo
  142. orderStatus.orderObject.actualPrice = result.actualPrice
  143. this.routerTo()
  144. })
  145. .catch(() => {
  146. Dialog.close()
  147. // 只用取消订单,不用做其它处理
  148. this.cancelPayment(result.orderNo)
  149. })
  150. } else {
  151. this.routerTo()
  152. }
  153. } catch {}
  154. },
  155. routerTo() {
  156. const live = this.live
  157. this.$router.push({
  158. path: '/orderDetail',
  159. query: {
  160. orderType: 'LIVE',
  161. courseGroupId: live.courseGroupId
  162. }
  163. })
  164. },
  165. async cancelPayment(orderNo: string) {
  166. try {
  167. await request.post('/api-student/userOrder/orderCancel', {
  168. data: {
  169. orderNo
  170. }
  171. })
  172. // this.routerTo()
  173. } catch {}
  174. }
  175. },
  176. render() {
  177. return (
  178. <div class={[styles['live-detail'], 'mb12']}>
  179. <ColHeader />
  180. <UserDetail userInfo={this.userInfo} showBuy={false} />
  181. <SectionDetail>
  182. <p class={styles.introduction}>{this.userInfo.lessonDesc}</p>
  183. </SectionDetail>
  184. <SectionDetail
  185. title="课程列表"
  186. icon="courseList"
  187. contentStyle={{ paddingTop: '0' }}
  188. >
  189. {this.courseInfo.length > 0 && (
  190. <CoursePlanStep
  191. courseInfo={this.courseInfo}
  192. courseId={Number(this.courseId) || 0}
  193. />
  194. )}
  195. </SectionDetail>
  196. <div class={styles.tips}>
  197. <h3>
  198. <Icon name={iconTips} size={15} />
  199. 温馨提示
  200. </h3>
  201. <p>
  202. 1、该直播课程销售截止后,报名人数若少于
  203. {this.live.mixStudentNum || 0}
  204. 人将取消开课,已购买学员付费金额将自动返还,请您放心购买;
  205. <br />
  206. 2、直播课教学计划中的上课时间为老师预计时间,实际上课时间以老师开启直播时间为准;
  207. <br />
  208. 3、若您错过老师直播,可通过视频回放观看完整课程。
  209. </p>
  210. </div>
  211. {this.courseInfo.length > 0 && this.live.existBuy !== 1 && (
  212. <Sticky offsetBottom={0} position="bottom">
  213. <div class={['btnGroup', styles.btnMore]}>
  214. <Button block round type="primary" onClick={this.onBuy}>
  215. 立即购买
  216. </Button>
  217. </div>
  218. </Sticky>
  219. )}
  220. {this.joinRoom == '1' && (
  221. <Sticky offsetBottom={0} position="bottom">
  222. <div class={['btnGroup']} style={{ paddingTop: '12px' }}>
  223. <Button
  224. block
  225. round
  226. type="primary"
  227. onClick={() => {
  228. postMessage({
  229. api: 'joinLiveRoom',
  230. content: {
  231. roomId: this.liveStatus.roomUid,
  232. teacherId: this.live.teacherId
  233. }
  234. })
  235. }}
  236. >
  237. 进入直播间
  238. </Button>
  239. </div>
  240. </Sticky>
  241. )}
  242. </div>
  243. )
  244. }
  245. })