video-detail.tsx 12 KB

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