video-detail.tsx 12 KB

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