video-detail.tsx 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346
  1. import CourseVideoItem from '@/business-components/course-video-item'
  2. import SectionDetail from '@/business-components/section-detail'
  3. import UserDetail from '@/business-components/user-detail'
  4. import UserList from '@/business-components/user-list'
  5. import { Button, Dialog, List, Popup, Sticky, Tab, Tabs, Toast } from 'vant'
  6. import { defineComponent } from 'vue'
  7. import styles from './video-detail.module.less'
  8. import request from '@/helpers/request'
  9. import ColResult from '@/components/col-result'
  10. import ColShare from '@/components/col-share'
  11. import ColSticky from '@/components/col-sticky'
  12. import LiveItem from '@/views/live-class/live-item'
  13. import { state } from '@/state'
  14. import { postMessage } from '@/helpers/native-message'
  15. import ColHeader from '@/components/col-header'
  16. export default defineComponent({
  17. name: 'VideoDetail',
  18. data() {
  19. const query = this.$route.query
  20. return {
  21. userInfo: {} as any,
  22. detailList: [],
  23. musicAlbumInfos: [], // 关联曲目或专辑"
  24. buyUserList: [], // 购买学生数
  25. dataShow: true, // 判断是否有数据
  26. loading: false,
  27. finished: false,
  28. share: query.share,
  29. params: {
  30. videoLessonGroupId: query.groupId,
  31. page: 1,
  32. rows: 20
  33. },
  34. shareStatus: false,
  35. shareUrl: '',
  36. shelvesFlag: 0,
  37. myself: false
  38. }
  39. },
  40. async mounted() {
  41. try {
  42. const res = await request.get(
  43. '/api-teacher/videoLessonGroup/selectVideoLesson',
  44. {
  45. params: {
  46. groupId: this.params.videoLessonGroupId
  47. }
  48. }
  49. )
  50. const result = res.data || {}
  51. if (state.platformType === 'TEACHER') {
  52. this.myself = !result.myself
  53. }
  54. this.userInfo = {
  55. id: result.lessonGroup.teacherId,
  56. username: result.lessonGroup.username,
  57. headUrl: result.lessonGroup.avatar,
  58. buyNum: result.lessonGroup.countStudent,
  59. lessonId: result.lessonGroup.id,
  60. lessonNum: result.lessonGroup.lessonCount,
  61. payType: result.lessonGroup.payType,
  62. lessonName: result.lessonGroup.lessonName,
  63. lessonDesc: result.lessonGroup.lessonDesc,
  64. lessonPrice: result.lessonGroup.lessonPrice,
  65. lessonCoverUrl: result.lessonGroup.lessonCoverUrl,
  66. relationType: result.lessonGroup.relationType,
  67. lessonSubjectName: result.lessonGroup.lessonSubjectName,
  68. auditVersion: result.lessonGroup.auditVersion,
  69. isDegree: result.degreeFlag ? true : false,
  70. isTeacher: result.teacherFlag ? true : false,
  71. alreadyBuy: result.alreadyBuy
  72. }
  73. this.shelvesFlag = result.lessonGroup.shelvesFlag
  74. this.detailList = result.detailList || []
  75. // shareVideo?recomUserId=56&groupId=124
  76. this.shareUrl = `${location.origin}/teacher/#/shareVideo?recomUserId=${state.user.data?.userId}&groupId=${this.params.videoLessonGroupId}&p=tenant`
  77. !this.myself && this.getList()
  78. } catch (e) {
  79. console.log(e)
  80. }
  81. },
  82. methods: {
  83. async getList() {
  84. try {
  85. const params = this.params
  86. const res = await request.post('/api-teacher/videoLesson/pageStudent', {
  87. data: {
  88. ...params
  89. }
  90. })
  91. this.loading = false
  92. const result = res.data || {}
  93. // 处理重复请求数据
  94. if (this.buyUserList.length > 0 && result.pageNo === 1) {
  95. return
  96. }
  97. this.buyUserList = this.buyUserList.concat(result.rows || [])
  98. this.finished = result.pageNo >= result.totalPage
  99. this.params.page = result.pageNo + 1
  100. this.dataShow = this.buyUserList.length > 0
  101. } catch {
  102. this.dataShow = false
  103. this.finished = true
  104. }
  105. },
  106. onPlay(detail: any) {
  107. this.$router.push({
  108. path: '/videoClassDetail',
  109. query: {
  110. groupId: this.params.videoLessonGroupId,
  111. classId: detail.id
  112. }
  113. })
  114. },
  115. async updateShelves() {
  116. Dialog.confirm({
  117. title: '提示',
  118. message: '确认下架该课程吗?',
  119. confirmButtonColor: 'var(--van-primary)'
  120. }).then(async () => {
  121. try {
  122. // 下架
  123. await request.post('/api-teacher/videoLessonGroup/updateShelves', {
  124. data: {
  125. id: this.userInfo.lessonId,
  126. shelvesFlag: 0
  127. }
  128. })
  129. Toast('下架成功')
  130. setTimeout(() => {
  131. postMessage({ api: 'back' })
  132. }, 800)
  133. } catch {
  134. //
  135. }
  136. })
  137. }
  138. },
  139. render() {
  140. return (
  141. <div class={[styles['video-detail'], 'mb12']}>
  142. <ColHeader />
  143. {this.userInfo.id && <UserDetail userInfo={this.userInfo} />}
  144. <SectionDetail border>
  145. <p class={styles.introduction}>{this.userInfo.lessonDesc}</p>
  146. </SectionDetail>
  147. {this.myself ? (
  148. <SectionDetail title="课程列表" icon="courseList" border={true}>
  149. {this.detailList.map((item: any) => {
  150. const musicAlbumInfos = item.musicAlbumInfos || []
  151. const temp = musicAlbumInfos.map((info: any) => {
  152. return {
  153. relationMusicAlbum: info.relationType,
  154. musicAlbumName: info.name,
  155. musicAlbumId: info.musicAlbumId,
  156. status: info.status,
  157. useRelationType: this.userInfo.relationType
  158. }
  159. })
  160. return (
  161. <CourseVideoItem
  162. musicAlbumInfos={temp}
  163. detail={{
  164. id: item.id,
  165. title: item.videoTitle,
  166. content: item.videoContent,
  167. imgUrl: item.coverUrl
  168. }}
  169. onPlay={this.onPlay}
  170. onMusicAlbumDetail={(item: any) => {
  171. if (!this.userInfo.alreadyBuy && !item.status) {
  172. Toast('数据正在更新,请稍后再试')
  173. return
  174. }
  175. if (item.relationMusicAlbum === 'MUSIC') {
  176. this.$router.push({
  177. path: '/music-detail',
  178. query: {
  179. id: item.musicAlbumId
  180. }
  181. })
  182. } else if (item.relationMusicAlbum === 'ALBUM') {
  183. this.$router.push({
  184. path: '/music-album-detail/' + item.musicAlbumId
  185. })
  186. }
  187. }}
  188. />
  189. )
  190. })}
  191. </SectionDetail>
  192. ) : (
  193. <SectionDetail
  194. title="课程列表"
  195. icon="courseList"
  196. titleShow={false}
  197. contentStyle={{ paddingTop: '0' }}
  198. >
  199. <Tabs color="var(--van-primary)" lineWidth={20} sticky>
  200. <Tab title="课程" titleClass="van-hairline--bottom">
  201. {this.detailList.map((item: any) => {
  202. const musicAlbumInfos = item.musicAlbumInfos || []
  203. const temp = musicAlbumInfos.map((info: any) => {
  204. return {
  205. relationMusicAlbum: info.relationType,
  206. musicAlbumName: info.name,
  207. musicAlbumId: info.musicAlbumId,
  208. status: info.status,
  209. useRelationType: this.userInfo.relationType
  210. }
  211. })
  212. return (
  213. <CourseVideoItem
  214. musicAlbumInfos={temp}
  215. detail={{
  216. id: item.id,
  217. title: item.videoTitle,
  218. content: item.videoContent,
  219. imgUrl: item.coverUrl
  220. }}
  221. onPlay={this.onPlay}
  222. onMusicAlbumDetail={(item: any) => {
  223. if (!this.userInfo.alreadyBuy && !item.status) {
  224. Toast('数据正在更新,请稍后再试')
  225. return
  226. }
  227. if (item.relationMusicAlbum === 'MUSIC') {
  228. this.$router.push({
  229. path: '/music-detail',
  230. query: {
  231. id: item.musicAlbumId
  232. }
  233. })
  234. } else if (item.relationMusicAlbum === 'ALBUM') {
  235. this.$router.push({
  236. path: '/music-album-detail/' + item.musicAlbumId
  237. })
  238. }
  239. }}
  240. />
  241. )
  242. })}
  243. </Tab>
  244. <Tab title="学员列表" titleClass="van-hairline--bottom">
  245. {this.dataShow ? (
  246. <List
  247. v-model:loading={this.loading}
  248. finished={this.finished}
  249. finishedText="没有更多了"
  250. onLoad={this.getList}
  251. >
  252. {this.buyUserList.map((item: any) => (
  253. <UserList
  254. class="mb12"
  255. users={{
  256. avatar: item.avatar,
  257. studentId: item.userId,
  258. studentName: item.username,
  259. createTime: item.createTime
  260. }}
  261. />
  262. ))}
  263. </List>
  264. ) : (
  265. <ColResult
  266. btnStatus={false}
  267. classImgSize="SMALL"
  268. tips="暂无学生购买"
  269. />
  270. )}
  271. </Tab>
  272. </Tabs>
  273. </SectionDetail>
  274. )}
  275. {this.shelvesFlag === 1 && (
  276. <>
  277. {this.share == '1' && this.detailList.length > 0 && (
  278. <ColSticky position="bottom" background="white">
  279. <div class={['btnGroup']} style={{ paddingTop: '12px' }}>
  280. <Button
  281. block
  282. round
  283. type="primary"
  284. onClick={() => {
  285. this.shareStatus = true
  286. }}
  287. >
  288. 分享课程
  289. </Button>
  290. </div>
  291. </ColSticky>
  292. )}
  293. {this.share != '1' && this.detailList.length > 0 && (
  294. <ColSticky position="bottom" background="white">
  295. <div class={['btnGroup']} style={{ paddingTop: '12px' }}>
  296. <Button
  297. block
  298. round
  299. type="primary"
  300. onClick={this.updateShelves}
  301. >
  302. 下架
  303. </Button>
  304. </div>
  305. </ColSticky>
  306. )}
  307. </>
  308. )}
  309. <Popup
  310. v-model:show={this.shareStatus}
  311. style={{ background: 'transparent' }}
  312. >
  313. <ColShare
  314. teacherId={this.userInfo.id}
  315. shareUrl={this.shareUrl}
  316. shareType="video"
  317. >
  318. <LiveItem
  319. class={styles.shareCourse}
  320. coverClass={styles.coverClass}
  321. liveInfo={{
  322. backgroundPic: this.userInfo.lessonCoverUrl,
  323. courseGroupId: this.userInfo.lessonId,
  324. courseGroupName: this.userInfo.lessonName,
  325. courseNum: this.userInfo.lessonNum,
  326. coursePrice: this.userInfo.lessonPrice,
  327. teacherName: this.userInfo.username,
  328. teacherId: this.userInfo.id,
  329. avatar: this.userInfo.headUrl,
  330. studentCount: this.userInfo.buyNum,
  331. existBuy: 0,
  332. subjectName: this.userInfo.lessonSubjectName
  333. }}
  334. />
  335. </ColShare>
  336. </Popup>
  337. </div>
  338. )
  339. }
  340. })