index copy.vue 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194
  1. <template>
  2. <div class="school">
  3. <div class="top">
  4. <div class="search">
  5. <image src="@/static/images/search.png" mode="" class="search_icon"></image>
  6. <div class="s_input"><u-input v-model="value" type="text" :border="false" /></div>
  7. <div class="searh_btn">查询</div>
  8. </div>
  9. </div>
  10. <view class="CoursePage">
  11. <scroll-view :scroll-y="!detail.vis" class="CourseScrollBody">
  12. <!-- 悬浮窗 -->
  13. <view v-if="!detail.vis && showfu&&img" class="showfu" @click.stop="appectData($event)">
  14. <view class="imgBox">
  15. <image :src="img" mode="widthFix" style="width: 88rpx;height: 88rpx;"></image>
  16. </view>
  17. <image src="@/static/images/school/start.png" mode="widthFix" style="width: 40rpx;"></image>
  18. <image src="@/static/images/school/xx.png" mode="widthFix" style="width: 40rpx;margin-right: 28rpx;"
  19. @click.stop="clearSave"></image>
  20. </view>
  21. <div class="tabs">
  22. <u-tabs ref="tabs" :list="tabList" active-color="#F5222D" :show-bar="false"></u-tabs>
  23. </div>
  24. <view class="CourseBody">
  25. <view class="CourseList">
  26. <template>
  27. <view class="CourseList-item" v-for="(item, i) in courseList" :key="item.id">
  28. <view class="ItemInfo">
  29. <image :src="item.cover" mode="aspectFill" class="ItemInfo-teamcher">
  30. <view class="Info-right">
  31. <view class="Right-title">{{item.name}}</view>
  32. <view class="Right-teacher">{{item.day}} 首席导师·{{item.author}}</view>
  33. <view class="Right-play no_open">
  34. <image v-if="play.ing && play.index === i"
  35. src="@/static/images/school/pause2.png" class="Play-icon"
  36. @click.stop="playSelf($event,item, i)" />
  37. <image v-else src="@/static/images/school/play2.png" class="Play-icon"
  38. @click.stop="playSelf($event,item, i)" />
  39. <view class="Play-Sound">
  40. <view class="SoundWave">
  41. <view v-for="ni in 20" :key="i + '_' + ni" class="Wave-line"
  42. :class="play.ing && play.index === i ? 'active' : ''" />
  43. </view>
  44. </view>
  45. <view class="Play-time">{{ item.seconds | mediaTimeFormatter }}
  46. </view>
  47. </view>
  48. </view>
  49. </view>
  50. </view>
  51. <!-- <view class="CourseList-item">
  52. <view class="ItemInfo">
  53. <image src="@/static/images/school/teacher.png" mode="aspectFill"
  54. class="ItemInfo-teamcher">
  55. <view class="Info-right">
  56. <view class="Right-title">不得不听的学位争霸赛赛前课</view>
  57. <view class="Right-teacher">2024-10-20 首席导师·李老师</view>
  58. <view class="Right-play">
  59. <template>
  60. <image src="@/static/images/school/play2.png" class="Play-icon" />
  61. </template>
  62. <view class="Play-Sound">
  63. <view class="SoundWave">
  64. <view v-for="ni in 20" :key="i + '_' + ni" class="Wave-line"
  65. :class="play.ing && play.index === i ? 'active' : ''" />
  66. </view>
  67. </view>
  68. <view class="Play-time">120分钟
  69. </view>
  70. </view>
  71. </view>
  72. </view>
  73. </view> -->
  74. </template>
  75. <!-- <template v-if="courseList.length > 0">
  76. <view v-for="(item, i) in courseList" :key="item.id" class="CourseList-item"
  77. @click="toInfo(item, i)">
  78. <view class="ItemInfo">
  79. <image :src="item.cover" mode="aspectFill" class="ItemInfo-teamcher">
  80. <view class="Info-right">
  81. <view class="Right-title">{{ item.name }}</view>
  82. <view class="Right-teacher">{{ item.teacher_name }}</view>
  83. <view class="Right-play" :class="item.status ? '' : 'no_open'">
  84. <template v-if="item.status">
  85. <image v-if="play.ing && play.index === i"
  86. src="@/static/images/school/pause2.png" class="Play-icon"
  87. @click.stop="playSelf($event,item, i)" />
  88. <image v-else src="@/static/images/school/play2.png"
  89. class="Play-icon" @click.stop="playSelf($event,item, i)" />
  90. </template>
  91. <template v-else>
  92. <image src="@/static/images/school/play1.png" class="Play-icon" />
  93. </template>
  94. <view class="Play-Sound">
  95. <view class="SoundWave">
  96. <view v-for="ni in 20" :key="i + '_' + ni" class="Wave-line"
  97. :class="play.ing && play.index === i ? 'active' : ''" />
  98. </view>
  99. </view>
  100. <view class="Play-time">{{ item.seconds | mediaTimeFormatter }}
  101. </view>
  102. </view>
  103. </view>
  104. </view>
  105. </view>
  106. </template>
  107. <template v-else>
  108. <view class="noTip">暂无相关课程</view>
  109. </template> -->
  110. </view>
  111. </view>
  112. </scroll-view>
  113. <view v-if="detail.vis" class="CourseAudioDetail">
  114. <view class="CoursePlay">
  115. <view class="PlayTitle">{{ detail.info.title }}</view>
  116. <view class="PlayTeacher">{{ detail.info.teacher_name }}</view>
  117. <view class="PlayCover">
  118. <image class="CoverImg" mode="aspectFill" :src="detail.info.teacher_img"
  119. :class="play.ing ? 'start' : 'start paused'" />
  120. </view>
  121. <view class="AudioProgress">
  122. <view class="Progress-left">
  123. <audio-slide class="Audio-slide" :allTime="Number(detail.info.course_length)"
  124. :playTime.sync="play.time" @update:progress="moveAudioPlay" @touchStart="audioTouch" />
  125. </view>
  126. <image v-show="params.season > 33" src="@/static/images/school/xia.png" mode="widthFix"
  127. style="width: 60rpx;margin-left: 26rpx;"
  128. @click="goXia(detail.info.title,detail.info.down_link)"></image>
  129. <!-- <view class="Progress-right">倍数</view> -->
  130. </view>
  131. <view class="AudioControl">
  132. <image src="@/static/images/school/prev_15.png" mode="widthFix" @click="prevTime"></image>
  133. <image src="@/static/images/school/prev.png" mode="widthFix" @click="toPrev"></image>
  134. <image v-if="!play.ing" src="@/static/images/school/play.png" mode="widthFix"
  135. @click="detailPlay" />
  136. <image v-else src="@/static/images/school/pause.png" mode="widthFix" @click="detailPlay" />
  137. <image src="@/static/images/school/next.png" mode="widthFix" @click="toNext"></image>
  138. <image src="@/static/images/school/next_15.png" mode="widthFix" @click="nextTime"></image>
  139. </view>
  140. </view>
  141. </view>
  142. </view>
  143. </div>
  144. </template>
  145. <script>
  146. import {
  147. AudioSlide
  148. } from "@/components/audio-slide.vue"
  149. // import {
  150. // GetSeason
  151. // } from '../../api.js'
  152. import {
  153. mapState
  154. } from "vuex"
  155. export default {
  156. components: {
  157. AudioSlide
  158. },
  159. data() {
  160. return {
  161. typd: 0,
  162. saveData: {},
  163. showfu: false,
  164. title_list: [],
  165. title: '赛季点击此处选择',
  166. params: {
  167. page: 1,
  168. page_size: 15,
  169. week: 1,
  170. season: ''
  171. },
  172. courseList: [],
  173. tabList: [{
  174. name: '全部'
  175. }, {
  176. name: '认知课程'
  177. }, {
  178. name: '卖货课程',
  179. }, {
  180. name: '团队管理',
  181. }],
  182. img: '',
  183. play: {
  184. self: null,
  185. index: -1,
  186. all: false,
  187. ing: false,
  188. time: 0,
  189. img: ''
  190. },
  191. detail: {
  192. vis: false,
  193. info: {}
  194. }
  195. }
  196. },
  197. computed: {
  198. ...mapState(['userServerInfo'])
  199. },
  200. watch: {
  201. 'params.week'(a) {
  202. if (this.tyed != 1) {
  203. this.toPause()
  204. this.play.ing = false
  205. this.play.index = -1
  206. this.params.page = 1
  207. this.getCourseList()
  208. console.log(0)
  209. } else {
  210. console.log(1)
  211. this.getCourseList()
  212. this.tyed = 0
  213. }
  214. },
  215. "play.all"(a) {
  216. if (a) {
  217. this.play.self.onEnded(() => {
  218. let len = this.courseList.length - 1
  219. if (this.play.index >= len) {
  220. this.play.index = 0
  221. this.play.all = false
  222. this.play.ing = false
  223. return false
  224. }
  225. let _i = this.play.index + 1
  226. if (!this.courseList[_i].status) {
  227. return false
  228. }
  229. this.toPlay(this.courseList[_i].course_link, this.courseList[_i].title, this.courseList[_i]
  230. .cover_url, () => {
  231. this.play.index = _i
  232. })
  233. if (this.detail.vis) {
  234. this.detail.info = this.courseList[_i]
  235. }
  236. })
  237. } else {
  238. this.play.self ? this.play.self.offEnded() : null
  239. }
  240. },
  241. "play.ing"(a) {
  242. if (a) {
  243. this.play.self.onTimeUpdate(() => {
  244. this.play.time = this.play.self.currentTime
  245. })
  246. this.play.self.onEnded(() => {
  247. if (!this.play.all) {
  248. this.toPause()
  249. this.play.time = 0
  250. }
  251. })
  252. } else {
  253. // this.play.self.offTimeUpdate()
  254. }
  255. },
  256. "detail.info": {
  257. handler(a) {
  258. if (a.course_link) {
  259. this.play.self.onTimeUpdate(() => {
  260. this.play.time = this.play.self.currentTime
  261. })
  262. }
  263. },
  264. deep: true,
  265. immediate: true
  266. }
  267. },
  268. filters: {
  269. dateFormatter: (timestamp, fmt) => {
  270. fmt = fmt || "yyyy-MM-dd";
  271. if (typeof timestamp === 'string') {
  272. timestamp = timestamp.replace(/-/g, '/')
  273. }
  274. const $this = new Date(timestamp);
  275. const o = {
  276. "M+": $this.getMonth() + 1,
  277. "d+": $this.getDate(),
  278. "h+": $this.getHours(),
  279. "m+": $this.getMinutes(),
  280. "s+": $this.getSeconds(),
  281. "q+": Math.floor(($this.getMonth() + 3) / 3),
  282. S: $this.getMilliseconds()
  283. };
  284. if (/(y+)/.test(fmt)) {
  285. fmt = fmt.replace(
  286. RegExp.$1,
  287. ($this.getFullYear() + "").substr(4 - RegExp.$1.length)
  288. );
  289. }
  290. for (var k in o) {
  291. if (new RegExp("(" + k + ")").test(fmt)) {
  292. fmt = fmt.replace(
  293. RegExp.$1,
  294. RegExp.$1.length === 1 ?
  295. o[k] :
  296. ("00" + o[k]).substr(("" + o[k]).length)
  297. );
  298. }
  299. }
  300. return fmt;
  301. },
  302. dateWeek(time) {
  303. if (typeof time === 'string') {
  304. time = time.replace(/-/g, '/')
  305. }
  306. let _d = new Date(time).getDay()
  307. let _a = ['日', '一', '二', '三', '四', '五', '六']
  308. return _a[_d]
  309. },
  310. mediaTimeFormatter: num => {
  311. if (!num) return "00:00";
  312. num = Math.floor(num);
  313. let hour = Math.floor(num / 3600);
  314. let minutes = Math.floor((num - hour * 3600) / 60);
  315. let second = num - hour * 3600 - minutes * 60;
  316. if (hour > 0) {
  317. return `${hour > 9 ? hour : "0" + hour}:${
  318. minutes > 9 ? minutes : "0" + minutes
  319. }:${second > 9 ? second : "0" + second}`;
  320. } else {
  321. return `${minutes > 9 ? minutes : "0" + minutes}:${
  322. second > 9 ? second : "0" + second
  323. }`;
  324. }
  325. }
  326. },
  327. onBackPress() {
  328. return false
  329. },
  330. onShow() {
  331. // 从聊天页面回来
  332. if (this.play.self && this.play.ing) { // 正在播放
  333. this.play.self.seek(this.play.time)
  334. this.play.self.play()
  335. } else if (this.play.self && !this.play.ing) { // 暂停播放,显示悬浮窗
  336. if (uni.getStorageSync('saveData')) {
  337. console.log(121212121)
  338. this.getSave();
  339. // this.showfu = true
  340. // const obj = uni.getStorageSync('saveData')
  341. // this.img = obj.data.teacher_img
  342. }
  343. }
  344. },
  345. onHide() {
  346. // 离开小程序,去聊天
  347. if (this.play.self && !this.play.ing) { // 暂停播放,存储数据
  348. console.log(1121215)
  349. this.saveData.params = this.params
  350. this.saveData.play = this.play
  351. uni.setStorageSync('saveData', this.saveData)
  352. console.log(console.log('存储的saveData', uni.getStorageSync('saveData')))
  353. this.showfu = true
  354. }
  355. },
  356. destroyed() {
  357. // this.toPause()
  358. },
  359. onLoad(e) {
  360. // 从首页进入小程序
  361. // this.getSeasonList()
  362. console.log(uni.getStorageSync('saveData'), 'onload中的saveDate')
  363. this.getSave();
  364. if (e.week) {
  365. this.params.week = Number(e.week)
  366. }
  367. this.getCategoryLlist()
  368. this.getCourseList()
  369. },
  370. onUnload() {
  371. console.log('onunload')
  372. // 返回首页,存储数据
  373. if (this.play.index != -1) {
  374. this.saveData.params = this.params
  375. this.saveData.play = this.play
  376. uni.setStorageSync('saveData', this.saveData)
  377. console.log(console.log('跳转页面存储的saveData', uni.getStorageSync('saveData')))
  378. }
  379. },
  380. methods: {
  381. // 获取缓存的数据
  382. getSave() {
  383. if (uni.getStorageSync('saveData')) {
  384. this.showfu = true
  385. const obj = uni.getStorageSync('saveData')
  386. if (obj.play && obj.data) {
  387. const {
  388. index,
  389. ing,
  390. time
  391. } = obj.play
  392. this.play.index = index
  393. this.play.ing = ing
  394. const {
  395. course_link,
  396. cover_url,
  397. title,
  398. teacher_img
  399. } = obj.data
  400. this.play.self.src = course_link
  401. this.play.self.coverImgUrl = cover_url
  402. this.play.self.title = title
  403. this.img = obj.data.teacher_img
  404. }
  405. }
  406. },
  407. //下载音频文件
  408. goXia(title, url) {
  409. let that = this
  410. const filePath = wx.env.USER_DATA_PATH + '/' + title + '.mp4'
  411. const downloadTask = uni.downloadFile({
  412. url: url,
  413. filePath: filePath,
  414. success: (res) => {
  415. if (res.statusCode === 200) {
  416. wx.saveVideoToPhotosAlbum({
  417. filePath: filePath,
  418. success: function(red) {
  419. uni.showToast({
  420. title: '下载成功',
  421. icon: 'none'
  422. })
  423. },
  424. fail: function(err) {
  425. uni.showToast({
  426. title: '下载失败',
  427. icon: 'none'
  428. })
  429. }
  430. })
  431. } else {
  432. uni.showToast({
  433. title: '保存失败',
  434. icon: 'none'
  435. })
  436. }
  437. }
  438. })
  439. downloadTask.onProgressUpdate((res) => {
  440. // console.log('下载进度' + res.progress);
  441. uni.showToast({
  442. title: '下载进度' + res.progress + '%',
  443. icon: 'none'
  444. })
  445. // console.log('已经下载的数据长度' + res.totalBytesWritten);
  446. // console.log('预期需要下载的数据总长度' + res.totalBytesExpectedToWrite);
  447. })
  448. },
  449. clearSave() {
  450. uni.removeStorageSync('saveData')
  451. this.showfu = false
  452. },
  453. appectData(e) {
  454. const data = uni.getStorageSync('saveData')
  455. if (data.params.week === this.params.week) {
  456. this.tyed = 0
  457. } else {
  458. this.tyed = 1
  459. }
  460. this.params = data.params
  461. this.getSeason(this.params.season)
  462. console.log(this.title_list)
  463. this.play.index = data.play.index
  464. this.play.self.src = data.data.course_link
  465. this.play.time = data.play.time
  466. console.log('play.time', this.play.time)
  467. this.playSelfd(e, data.data, this.play.index) //列表播放
  468. uni.removeStorageSync('saveData')
  469. this.showfu = false
  470. this.toInfo(data.data, this.play.index)
  471. },
  472. // 列表里的暂停播放按钮
  473. playSelfd(e, data, i) {
  474. this.saveData.data = data
  475. uni.removeStorageSync('saveData')
  476. e.stopPropagation()
  477. this.toPlayd(data.course_link, data.title, data.cover_url, () => {
  478. console.log(1, this.play)
  479. this.play.index = i
  480. })
  481. },
  482. toPlayd(src, cb) {
  483. this.play.ing ? this.play.self.pause() : null
  484. this.play.self.src = src;
  485. this.play.self.seek(this.play.time)
  486. this.play.self.play()
  487. this.play.ing = true
  488. cb && cb()
  489. },
  490. getSeason(e) {
  491. // if (e === this.params.season) {
  492. // this.tyed = 0
  493. // } else {
  494. // this.tyed = 1
  495. // }
  496. let i = this.title_list.findIndex(item => item.season == e)
  497. this.title = this.title_list[i].name
  498. this.season = this.title_list[i].season
  499. this.getCourseList()
  500. },
  501. getSeasonList() {
  502. this.$ajax.get(`${GetSeason}`).then(([, {
  503. data: res
  504. }]) => {
  505. if (res.code === 200) {
  506. var arr = res.data
  507. arr.forEach((item, i) => {
  508. item.name = '第' + item.season + '届培训课程表'
  509. })
  510. this.title_list = arr
  511. this.title = this.title_list[0].name
  512. this.season = res.data[0].season
  513. uni.hideLoading()
  514. this.getCourseList()
  515. this.init()
  516. }
  517. })
  518. },
  519. titlePicker(e) {
  520. console.log(e.target.value)
  521. this.title = this.title_list[e.target.value].name
  522. this.season = this.title_list[e.target.value].season
  523. this.toPause()
  524. this.play.ing = false
  525. this.play.index = -1
  526. this.params.page = 1
  527. this.getCourseList()
  528. },
  529. audioTouch() {
  530. this.toPause()
  531. },
  532. mockend() {
  533. this.play.self.seek(212)
  534. },
  535. toBack() {
  536. if (this.detail.vis) {
  537. this.detail.time = 0
  538. this.detail.info = {}
  539. this.detail.vis = false
  540. if (!this.play.ing) { //暂停状态返回列表,显示悬浮窗
  541. this.saveData.params = this.params
  542. this.saveData.play = this.play
  543. uni.setStorageSync('saveData', this.saveData)
  544. this.img = this.saveData.data.teacher_img
  545. console.log(console.log('11存储的saveData1', uni.getStorageSync('saveData')))
  546. this.showfu = true
  547. }
  548. } else {
  549. // console.log(111,this.play.self)
  550. // uni.setStorageSync('floating', this.play)
  551. uni.navigateBack()
  552. }
  553. },
  554. init() {
  555. // this.play.self = uni.createInnerAudioContext()
  556. this.play.self = uni.getBackgroundAudioManager()
  557. },
  558. toPlay(src, title, cover_rul, cb) {
  559. this.play.ing ? this.play.self.pause() : null
  560. this.play.self = uni.getBackgroundAudioManager();
  561. this.play.self.title = title;
  562. this.play.self.coverImgUrl = cover_rul;
  563. this.play.self.src = encodeURI(src)
  564. this.play.ing = true
  565. wx.setInnerAudioOption({
  566. obeyMuteSwitch: false,
  567. success: function(e) {
  568. console.log('play success')
  569. },
  570. fail: function(e) {
  571. console.log(e)
  572. console.log('play fail')
  573. }
  574. })
  575. cb && cb()
  576. },
  577. toPause() {
  578. if (!this.play.ing) {
  579. return false
  580. }
  581. this.play.ing = false
  582. this.play.self.pause()
  583. },
  584. playAll() {
  585. if (this.courseList.length === 0) {
  586. uni.showModal({
  587. content: "没有可播放的课程",
  588. showCancel: false
  589. })
  590. return false
  591. }
  592. let _this = this
  593. if (this.play.ing) {
  594. if (this.play.all) {
  595. this.toPause()
  596. } else {
  597. if (this.play.index === -1) {
  598. this.toPause()
  599. } else {
  600. this.play.all = true
  601. }
  602. }
  603. return false
  604. }
  605. if (this.play.index === -1) {
  606. this.toPlay(this.courseList[0].course_link, this.courseList[0].title, this.courseList[0].cover_url,
  607. () => {
  608. this.play.all = true
  609. this.play.index = 0
  610. })
  611. } else {
  612. this.play.ing = true;
  613. this.play.self.play()
  614. }
  615. },
  616. // 列表里的暂停播放按钮
  617. playSelf(e, data, i) {
  618. this.saveData.data = data
  619. uni.removeStorageSync('saveData')
  620. this.showfu = false
  621. e.stopPropagation()
  622. if (this.play.ing && this.play.index === i) {
  623. this.toPause()
  624. return false
  625. }
  626. this.toPlay(data.course_link, data.title, data.cover_url, () => {
  627. console.log(1, this.play)
  628. this.play.index = i
  629. })
  630. },
  631. getCategoryLlist() {
  632. this.$u.get('/dwbs/business/category/select-options').then(res => {
  633. console.log(res)
  634. this.tabList = [{
  635. id: 0,
  636. name: '全部'
  637. }].concat(res.data)
  638. })
  639. },
  640. getCourseList() {
  641. this.$u.get('/dwbs/business/schools').then(res => {
  642. let data = res.data.data
  643. if (this.page > 1 && data.length == 0) {
  644. uni.showToast({
  645. title: '暂无更多',
  646. icon: 'none'
  647. })
  648. this.last = true
  649. } else {
  650. this.courseList = this.courseList.concat(data)
  651. }
  652. })
  653. },
  654. toPrev() {
  655. if (this.play.index === 0) {
  656. uni.showModal({
  657. content: "前面没有课程了",
  658. showCancel: false
  659. })
  660. return false
  661. }
  662. let _i = this.play.index - 1
  663. if (!this.courseList[_i].status) {
  664. uni.showModal({
  665. content: "上一个课程还未开始",
  666. showCancel: false
  667. })
  668. return false
  669. }
  670. this.play.time = 0
  671. this.toPlay(this.courseList[_i].course_link, this.courseList[_i].title, this.courseList[_i].cover_url,
  672. () => {
  673. this.play.index = _i
  674. })
  675. this.detail.info = Object.assign({}, this.courseList[_i])
  676. },
  677. toNext() {
  678. let max = this.courseList.length - 1
  679. if (this.play.index >= max) {
  680. uni.showModal({
  681. content: "后面没有课程了",
  682. showCancel: false
  683. })
  684. return false
  685. }
  686. let _i = this.play.index + 1
  687. if (!this.courseList[_i].status) {
  688. uni.showModal({
  689. content: "下一个课程还未开始",
  690. showCancel: false
  691. })
  692. return false
  693. }
  694. this.play.time = 0
  695. this.toPlay(this.courseList[_i].course_link, this.courseList[_i].title, this.courseList[_i].cover_url,
  696. () => {
  697. this.play.index = _i
  698. })
  699. this.detail.info = Object.assign({}, this.courseList[_i])
  700. },
  701. toInfo(data, i) {
  702. uni.removeStorageSync('saveData')
  703. console.log(uni.getStorageInfo('saveData'), '点击详情的save')
  704. console.log(data, 'data')
  705. this.saveData.data = data
  706. this.showfu = false
  707. if (!data.status) {
  708. uni.showModal({
  709. content: '课程还未开始',
  710. showCancel: false
  711. })
  712. return false
  713. }
  714. if (i !== this.play.index) {
  715. // this.play.self.src = data.course_link
  716. this.play.ing ? this.toPause() : null
  717. this.play.index = i
  718. this.play.time = 0
  719. this.play.self.seek(this.play.time)
  720. }
  721. this.detail.info = data
  722. this.detail.vis = true
  723. },
  724. moveAudioPlay({
  725. value
  726. }) {
  727. this.play.time = value
  728. this.play.self.seek(value)
  729. this.toPlay()
  730. },
  731. // 倒退15秒
  732. prevTime() {
  733. this.play.time = this.play.time > 15 ? this.play.time - 15 : 0
  734. this.play.self.seek(this.play.time)
  735. },
  736. // 快进15秒
  737. nextTime() {
  738. let max = Number(this.detail.info.course_length)
  739. this.play.time = this.play.time < max ? this.play.time + 15 : max
  740. this.play.self.seek(this.play.time)
  741. },
  742. // 播放详情里的 播放和暂停
  743. detailPlay() {
  744. if (this.play.ing) { // 暂停
  745. this.toPause()
  746. } else { // 播放
  747. const {
  748. title,
  749. cover_rul,
  750. course_link
  751. } = this.detail.info
  752. this.play.self = uni.getBackgroundAudioManager();
  753. this.play.self.title = title;
  754. this.play.self.coverImgUrl = cover_rul;
  755. this.play.self.src = course_link
  756. // this.play.self.play();
  757. this.play.ing = true;
  758. wx.setInnerAudioOption({
  759. obeyMuteSwitch: false,
  760. success: function(e) {
  761. console.log(e)
  762. console.log('play success')
  763. },
  764. fail: function(e) {
  765. console.log(e)
  766. console.log('play fail')
  767. }
  768. })
  769. }
  770. }
  771. }
  772. }
  773. </script>
  774. <style lang="scss" scoped>
  775. page {
  776. background-color: #f5f5f5;
  777. }
  778. .top {
  779. padding: 12px;
  780. background-color: #FFFFFF;
  781. }
  782. .search {
  783. background: #F9F9FB;
  784. height: 40px;
  785. line-height: 40px;
  786. border-radius: 20px;
  787. display: flex;
  788. align-items: center;
  789. padding: 0 12px;
  790. .search_icon {
  791. width: 24px;
  792. height: 24px;
  793. margin-right: 5px;
  794. }
  795. .s_input {
  796. flex: 1
  797. }
  798. .searh_btn {
  799. background: linear-gradient(91deg, #FF232C 0%, #FF571B 99%);
  800. border-radius: 20px;
  801. text-align: center;
  802. height: 32px;
  803. width: 66px;
  804. line-height: 32px;
  805. font-size: 14px;
  806. color: #FFFFFF;
  807. }
  808. }
  809. .showfu {
  810. width: 268rpx;
  811. height: 96rpx;
  812. background: #5B5B5B;
  813. box-shadow: 0px 6px 12px rgba(0, 0, 0, 0.16);
  814. border-radius: 50rpx;
  815. position: fixed;
  816. right: 44rpx;
  817. bottom: 80rpx;
  818. display: flex;
  819. justify-content: space-between;
  820. align-items: center;
  821. .imgBox {
  822. width: 96rpx;
  823. height: 96rpx;
  824. border: 6rpx solid #FFFFFF;
  825. border-radius: 50%;
  826. overflow: hidden;
  827. }
  828. }
  829. .select {
  830. margin-top: 20rpx;
  831. padding-left: 30rpx;
  832. font-size: 34rpx;
  833. }
  834. .noTip {
  835. padding: 20rpx;
  836. text-align: center;
  837. width: 100%;
  838. color: #999999;
  839. }
  840. $rotate: 0deg;
  841. .CoursePage {
  842. background-color: #FFFFFF;
  843. margin-top: 10px;
  844. border-radius: 10px 10px 0px 0px;
  845. @include page();
  846. display: flex;
  847. flex-direction: column;
  848. justify-content: space-between;
  849. .CourseAudioDetail {
  850. @include page();
  851. position: fixed;
  852. height: 100%;
  853. bottom: 0;
  854. left: 0;
  855. right: 0;
  856. background-color: #FFFFFF;
  857. overflow: hidden;
  858. .CoursePlay {
  859. padding: 30rpx;
  860. width: 100%;
  861. box-sizing: border-box;
  862. display: flex;
  863. align-items: center;
  864. justify-content: flex-start;
  865. flex-direction: column;
  866. .PlayTitle {
  867. width: 100%;
  868. color: #333333;
  869. font-size: 40rpx;
  870. line-height: 60rpx;
  871. text-align: center;
  872. margin-bottom: 40rpx;
  873. }
  874. .PlayTeacher {
  875. color: #999999;
  876. font-size: 32rpx;
  877. line-height: 60rpx;
  878. text-align: center;
  879. margin-bottom: 40rpx;
  880. }
  881. .PlayCover {
  882. width: 496rpx;
  883. height: 496rpx;
  884. border-radius: 50%;
  885. background-color: #333333;
  886. padding: 26rpx;
  887. box-sizing: border-box;
  888. .CoverImg {
  889. display: block;
  890. width: 100%;
  891. height: 100%;
  892. border-radius: 50%;
  893. &.start {
  894. animation: rotate 10s 0s infinite linear;
  895. }
  896. &.paused {
  897. animation-play-state: paused;
  898. }
  899. }
  900. margin-bottom: 150rpx;
  901. }
  902. .AudioProgress {
  903. width: 100%;
  904. display: flex;
  905. align-items: center;
  906. justify-content: space-between;
  907. margin-bottom: 50rpx;
  908. .Progress-right {
  909. color: #EA4A41;
  910. font-size: 24rpx;
  911. margin-left: 30px;
  912. }
  913. .Progress-left {
  914. flex: 1;
  915. min-width: 0;
  916. .Audio-slide {
  917. margin: 0;
  918. }
  919. }
  920. }
  921. .AudioControl {
  922. display: flex;
  923. align-items: center;
  924. justify-content: space-between;
  925. width: 100%;
  926. image {
  927. &:nth-of-type(1),
  928. &:nth-last-of-type(1) {
  929. width: 43rpx;
  930. height: 38rpx;
  931. }
  932. &:nth-of-type(2),
  933. &:nth-last-of-type(2) {
  934. width: 38rpx;
  935. height: 46rpx;
  936. }
  937. &:nth-of-type(3) {
  938. width: 124rpx;
  939. height: 124rpx;
  940. }
  941. }
  942. }
  943. }
  944. }
  945. .CourseScrollBody {
  946. width: 100%;
  947. flex: 1;
  948. overflow: hidden;
  949. position: relative;
  950. }
  951. }
  952. .CourseBody {
  953. width: 100%;
  954. padding: 0 30rpx 30rpx;
  955. box-sizing: border-box;
  956. .CourseWeek {
  957. width: 100%;
  958. display: flex;
  959. align-items: center;
  960. justify-content: space-between;
  961. margin-bottom: 60rpx;
  962. .week {
  963. // width: 192rpx;
  964. padding: 0 30rpx;
  965. height: 68rpx;
  966. border-radius: 68rpx;
  967. text-align: center;
  968. line-height: 68rpx;
  969. background: #F8F8F8;
  970. color: #999999;
  971. font-size: 28rpx;
  972. &.active {
  973. color: #FFFFFF !important;
  974. background: linear-gradient(to right, #F97C55, #F44545) !important;
  975. }
  976. }
  977. }
  978. .CourseList {
  979. &-item {
  980. margin-bottom: 40rpx;
  981. background: #F6F6F6;
  982. border-radius: 5px;
  983. &:nth-last-of-type(1) {
  984. margin-bottom: 0;
  985. }
  986. .ItemTitle {
  987. color: #333333;
  988. font-size: 32rpx;
  989. line-height: 44rpx;
  990. margin-bottom: 30rpx;
  991. display: flex;
  992. align-items: center;
  993. justify-content: space-between;
  994. &-status {
  995. height: 44rpx;
  996. line-height: 44rpx;
  997. width: 118rpx;
  998. border: 2rpx solid #999999;
  999. color: #999999;
  1000. text-align: center;
  1001. font-size: 28rpx;
  1002. box-sizing: border-box;
  1003. &.active {
  1004. border-color: #EA4A41 !important;
  1005. color: #EA4A41 !important;
  1006. }
  1007. }
  1008. }
  1009. .ItemInfo {
  1010. width: 100%;
  1011. display: flex;
  1012. align-items: stretch;
  1013. justify-content: space-between;
  1014. .ItemInfo-teamcher {
  1015. display: block;
  1016. width: 180rpx;
  1017. height: 234rpx;
  1018. }
  1019. .Info-right {
  1020. flex: 1;
  1021. overflow: hidden;
  1022. margin-left: 16rpx;
  1023. display: flex;
  1024. justify-content: space-between;
  1025. flex-direction: column;
  1026. align-items: flex-start;
  1027. padding-top: 4px;
  1028. .Right-title {
  1029. color: #333333;
  1030. font-size: 32rpx;
  1031. line-height: 44rpx;
  1032. }
  1033. .Right-teacher {
  1034. color: #999999;
  1035. font-size: 28rpx;
  1036. line-height: 40rpx;
  1037. }
  1038. .Right-play {
  1039. width: 422rpx;
  1040. height: 60rpx;
  1041. padding: 12rpx 14rpx;
  1042. box-sizing: border-box;
  1043. display: flex;
  1044. align-items: center;
  1045. background: linear-gradient(to right, #F97C55, #F44545);
  1046. border-radius: 60rpx;
  1047. margin-bottom: 22rpx;
  1048. display: flex;
  1049. align-items: center;
  1050. justify-content: space-between;
  1051. &.no_open {
  1052. background: #F8F8F8 !important;
  1053. .Play-time {
  1054. color: #999999 !important;
  1055. }
  1056. /deep/ .Wave-line {
  1057. background: #999999 !important;
  1058. }
  1059. }
  1060. .Play-icon {
  1061. display: block;
  1062. width: 36rpx;
  1063. height: 36rpx;
  1064. }
  1065. .Play-time {
  1066. color: #FFFFFF;
  1067. font-size: 28rpx;
  1068. }
  1069. .Play-Sound {
  1070. flex: 1;
  1071. height: 100%;
  1072. overflow: hidden;
  1073. margin: 0 20rpx;
  1074. }
  1075. }
  1076. }
  1077. }
  1078. }
  1079. }
  1080. }
  1081. .SoundWave {
  1082. width: 100%;
  1083. height: 100%;
  1084. display: flex;
  1085. align-items: center;
  1086. justify-content: space-between;
  1087. .Wave-line {
  1088. width: 4rpx;
  1089. background: #FFFFFF;
  1090. border-radius: 4rpx;
  1091. @for $i from 1 through 20 {
  1092. &:nth-of-type(#{$i}) {
  1093. height: #{random(40)}rpx;
  1094. }
  1095. }
  1096. &.active {
  1097. @for $i from 1 through 20 {
  1098. &:nth-of-type(#{$i}) {
  1099. animation: load 2.5s #{(random(10)*0.2)+ 1}s infinite linear;
  1100. }
  1101. }
  1102. }
  1103. }
  1104. }
  1105. @keyframes load {
  1106. 0% {
  1107. height: 100%;
  1108. }
  1109. 30% {
  1110. height: 20%;
  1111. }
  1112. 60% {
  1113. height: 60%;
  1114. }
  1115. 100% {
  1116. height: 10%;
  1117. }
  1118. }
  1119. @keyframes rotate {
  1120. 100% {
  1121. transform: rotate(360deg);
  1122. }
  1123. }
  1124. </style>