detail.vue 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176
  1. <template>
  2. <view>
  3. <view style="position: fixed;width: 100%;z-index: 999;background: #FFFFFF;" id="top">
  4. <view class="video_box">
  5. <image
  6. v-if="!startStatus"
  7. :src="infoData.firstImage === null ? 'https://cdn.uviewui.com/uview/swiper/3.jpg' : infoData.firstImage"
  8. style="width: 100%;height: 460rpx;"
  9. ></image>
  10. <image v-if="!startStatus" class="video_play" src="/static/play.png" @click="startVideo"></image>
  11. <polyv-player
  12. v-else
  13. id="playerVideo"
  14. playerId="playerVideo"
  15. height="460rpx"
  16. :vid="vid"
  17. :showSettingBtn="true"
  18. isAllowSeek="ifViewed"
  19. :showPlaybackRateBtn="false"
  20. :enablePlayGesture="true"
  21. :playbackRate="playbackRate"
  22. @statechange="onStateChange"
  23. ></polyv-player>
  24. </view>
  25. <view>
  26. <u-row>
  27. <u-col span="8" offset="1">
  28. <view class="video_t1">{{ infoData.name || pageData.courseName }}</view>
  29. </u-col>
  30. <u-col span="3">
  31. <view class="video_t1">共{{ chapterList.length }}章节</view>
  32. </u-col>
  33. </u-row>
  34. </view>
  35. <view><u-tabs :list="list" font-size="24" bar-width="90" :current="current" @change="change" active-color="#32467B"></u-tabs></view>
  36. <u-line color="#D6D6DB" />
  37. </view>
  38. <view class="box" @touchmove="touchMove">
  39. <view id="modules1">
  40. <!-- 课程目录-->
  41. <view style="padding-top: 15rpx;">
  42. <u-row>
  43. <u-col span="9">
  44. <view class="video_t2" style="display: flex;align-items: center;">
  45. <view class="top_line"></view>
  46. 课程目录
  47. </view>
  48. </u-col>
  49. <u-col span="3" text-align="right">
  50. <view class="video_t2" @click="swipStatus">
  51. 共{{ chapterList.length }}章节
  52. <u-icon name="arrow-right" size="28" style="transition: all 0.2s;margin-left:10rpx" :class="activeStatus ? 'rotoct' : ''"></u-icon>
  53. </view>
  54. </u-col>
  55. </u-row>
  56. <!-- <view class="scroll_box">
  57. <scroll-view class="r_sliper" scroll-x="true">
  58. <view v-for="(item, index) in chapterList" :key="index" style="margin-right: 20rpx;display:inline-block"><view class="r_t2">{{item.name}}</view></view>
  59. </scroll-view>
  60. </view> -->
  61. <view class="catalogBox" :class="activeStatus ? 'changeCatalogBox' : ''">
  62. <view
  63. class="catalogA"
  64. v-for="(item, index) in chapterList"
  65. :key="index"
  66. :class="activeStatusCata === item.chapterId ? 'activesq' : ''"
  67. @click="activeList(item, index)"
  68. >
  69. {{ item.name }}
  70. </view>
  71. </view>
  72. </view>
  73. <u-line color="#D6D6DB" />
  74. </view>
  75. <view id="modules2">
  76. <!-- 课程介绍-->
  77. <view style="padding-top: 15rpx;">
  78. <u-row>
  79. <u-col span="8">
  80. <view class="video_t2" style="display: flex;align-items: center;">
  81. <view class="top_line"></view>
  82. 课程介绍
  83. </view>
  84. </u-col>
  85. </u-row>
  86. </view>
  87. <view class="t2" v-html="pageData.introduction"></view>
  88. <u-line color="#D6D6DB" />
  89. </view>
  90. <!-- 出题名师-->
  91. <view id="modules3">
  92. <view style="padding: 15rpx 0;">
  93. <u-row>
  94. <u-col span="8">
  95. <view class="video_t2" style="display: flex;align-items: center;">
  96. <view class="top_line"></view>
  97. 出题名师
  98. </view>
  99. </u-col>
  100. </u-row>
  101. <u-row>
  102. <view style="margin: 25rpx;display: flex;">
  103. <view><image :src="$method.splitImgHost(teacherInfo.avatar)" class="teacher_img"></image></view>
  104. <view class="teacher_t">
  105. <view>{{ teacherInfo.teacherName }}</view>
  106. <view>{{ teacherInfo.introduce }}</view>
  107. </view>
  108. </view>
  109. </u-row>
  110. </view>
  111. <u-line color="#D6D6DB" />
  112. </view>
  113. <!-- 相关推荐-->
  114. <view style="padding-top: 15rpx;" id="modules4" :style="'padding-bottom:' + modules4Bottom + 'px'">
  115. <u-row>
  116. <u-col span="8">
  117. <view class="video_t2" style="display: flex;align-items: center;">
  118. <view class="top_line"></view>
  119. 相关推荐
  120. </view>
  121. </u-col>
  122. </u-row>
  123. <view style="margin: 10rpx;">
  124. <view class="tj_box" v-for="(item, index) in commendList" :key="index" @click="getNavTo(item)">
  125. <image :src="$method.splitImgHost(item.coverUrl)" style="width: 320rpx;height: 160rpx;"></image>
  126. <view style="font-size: 24rpx;color: #666666;text-align: left;">{{ item.courseName }}</view>
  127. <view>
  128. <u-row>
  129. <u-col span="6">
  130. <view style="margin-left: 20rpx;">
  131. <image src="/static/people.png" style="width: 20rpx;height: 20rpx;"></image>
  132. <text style="color: #999999;font-size: 20rpx;margin-left: 10rpx;">2023</text>
  133. </view>
  134. </u-col>
  135. <u-col span="6" text-align="right">
  136. <text style="color: #E91313;font-size: 16rpx;margin-left: 8rpx;">活动价</text>
  137. <text style="color: #E91313;font-size: 24rpx;font-weight: bold;">¥{{ item.price }}</text>
  138. </u-col>
  139. </u-row>
  140. </view>
  141. </view>
  142. </view>
  143. </view>
  144. </view>
  145. <view class="footer_tab" id="foot">
  146. <u-line color="#D6D6DB" />
  147. <view style="height: 100%;display: flex;align-items: center;position: relative;">
  148. <view style="text-align: center;margin-left: 30rpx;" @click="favorites">
  149. <image :src="collecStatus ? '/static/star.png' : '/static/sc.png'" class="sc"></image>
  150. <view class="sc_t">收藏</view>
  151. </view>
  152. <view style="text-align: center;margin-left: 30rpx;">
  153. <view class="price_t1">¥{{ pageData.price }}</view>
  154. <view class="price_t2">¥699</view>
  155. </view>
  156. <view class="buy" @click="jumpBuy" v-if="payStatus === 0">立即购买</view>
  157. <view class="buy" v-if="payStatus === 1" @click="startVideo">立即观看</view>
  158. </view>
  159. </view>
  160. <u-popup v-model="showBox" mode="bottom" border-radius="14">
  161. <view class="content">
  162. <scroll-view scroll-y="true" style="height: 300rpx;">
  163. <view v-if="boxList.length > 0">
  164. <view
  165. v-for="(item, index) in boxList"
  166. :key="index"
  167. style="line-height: 60rpx;border-bottom: 1rpx solid #eee;display: flex;align-items: center;justify-content: space-between;padding: 15rpx 0;"
  168. :style="infoData.sectionId === item.sectionId ? 'color:#1677ff;' : ''"
  169. @click="getsec(item)"
  170. >
  171. <view>{{ item.name }}</view>
  172. <u-icon v-if="infoData.sectionId === item.sectionId" name="checkbox-mark"></u-icon>
  173. </view>
  174. </view>
  175. <view v-else>暂无内容</view>
  176. </scroll-view>
  177. <view class="confrim-btn" style="margin-top: 10rpx;"><u-button @click="showBox = false">取消</u-button></view>
  178. </view>
  179. </u-popup>
  180. <u-popup v-model="showPricePop" mode="bottom" border-radius="14">
  181. <view class="topBox">
  182. <view class="firstTopL">
  183. <view class="imageBs"><image :src="$method.splitImgHost(pageData.coverUrl)" mode=""></image></view>
  184. <view class="textBs">{{ pageData.courseName }}</view>
  185. </view>
  186. <view class="boldFonstType">
  187. 类型:
  188. <span style="font-weight: bold;">{{ pageData.categoryName }}</span>
  189. </view>
  190. <view class="priceBxs">
  191. <view class="pricleft">
  192. 活动价
  193. <span style="font-weight: bold;">¥{{ pageData.price }}</span>
  194. </view>
  195. <view class="pricright" style="text-decoration: line-through;color: #666;">¥{{ pageData.price }}</view>
  196. </view>
  197. </view>
  198. <view class="yh">
  199. <view class="yhtitle">
  200. <span>优惠</span>
  201. <u-icon
  202. style="transition: all 0.2s;"
  203. name="arrow-right"
  204. color="#999"
  205. size="28"
  206. @click="getConfiguration"
  207. :style="pricestatus ? 'transform: rotate(90deg);' : ''"
  208. ></u-icon>
  209. </view>
  210. <view class="ts">
  211. <u-icon name="error-circle" color="#999" size="24"></u-icon>
  212. 平台所有优惠均不可同时使用
  213. </view>
  214. <radio-group @change="activeCoupon" v-show="pricestatus">
  215. <view class="yhj" v-if="configList.length !== 0">
  216. <view class="yhjtit">优惠券</view>
  217. <view class="yhjList" v-for="(item, index) in configList" :key="index">
  218. <view class="yhjLefts">
  219. <view class="yhl">
  220. {{ item.couponType === 0 ? '现金券' : item.couponType === 1 ? '折扣券' : '未知' }}:{{ item.price
  221. }}{{ item.couponType === 0 ? '元' : item.couponType === 1 ? '折' : '未知' }}
  222. </view>
  223. <view class="yhbq" v-if="item.endTime - newDate <= 3 * 24 * 3600">即将到期</view>
  224. </view>
  225. <radio :value="JSON.stringify([1, item.couponId])" />
  226. </view>
  227. </view>
  228. <view class="hdyhj" v-if="activityList.length !== 0">
  229. <view class="yhjtit">活动优惠</view>
  230. <view class="yhjList" v-for="(item, index) in activityList" :key="index">
  231. <view class="yhjLefts">
  232. <view class="yhl">{{ item.activityName }}:{{ item.description }}</view>
  233. <view class="yhbq" v-if="item.endTime - newDate <= 3 * 24 * 3600">即将到期</view>
  234. </view>
  235. <radio :value="JSON.stringify([2, item.id])" />
  236. </view>
  237. </view>
  238. </radio-group>
  239. </view>
  240. <view class="btnspric">
  241. <view class="lefprL">
  242. 实付:
  243. <span style="color: #E91313;">¥{{ prices }}</span>
  244. </view>
  245. <view class="lefprR" @click="getorder">提交订单</view>
  246. </view>
  247. </u-popup>
  248. </view>
  249. </template>
  250. <script>
  251. import { mapGetters } from 'vuex';
  252. export default {
  253. data() {
  254. return {
  255. playbackRate: [0.5, 0.8, 1.0, 1.25, 1.5],
  256. list: [
  257. {
  258. name: '课程目录'
  259. },
  260. {
  261. name: '课程介绍'
  262. },
  263. {
  264. name: '出题名师'
  265. },
  266. {
  267. name: '相关推荐'
  268. }
  269. ],
  270. activeStatus: false, //课程目录下拉样式变化是否开启
  271. activeStatusCata: 0, //当前选中章节
  272. current: 0,
  273. h1: 0,
  274. h2: 0,
  275. h3: 0,
  276. h4: 0,
  277. hh1: 0,
  278. hh2: 0,
  279. hh3: 0,
  280. hh4: 0,
  281. foot_h: 0,
  282. top_h: 0,
  283. windowHeight: 0,
  284. modules4Bottom: 0,
  285. isClick: false,
  286. // vid: 'd5f6d309fe0b016d3844b194a8b32249_d', // 视频ID
  287. vid: '', // 视频ID
  288. sign: '',
  289. ts: '',
  290. startStatus: false,
  291. queryData: {}, //页面跳转内容
  292. pageData: {},
  293. infoData: {},
  294. chapterList: [], //章列表
  295. teacherInfo: {},
  296. faceGetState: false, //模拟今天是否人脸识别
  297. showBox: false,
  298. boxList: [], //章节弹窗列表
  299. payStatus: 0, //是否购买该课程
  300. commendList: [], //推荐课程列表
  301. collecStatus: false, //收藏状态
  302. initH4: 0,
  303. id: 0,
  304. PlayDuration: 0,
  305. firstPlay: true,
  306. showPricePop: false, //购买详情弹窗
  307. configList: [], //优惠卷列表
  308. activityList: [], //活动优惠列表
  309. activeCouponId: [], //当前优惠卷ID [0] : 1 优惠卷 2 活动优惠
  310. pricestatus: false, //当前优惠卷展开状态
  311. newDate: 0, //现在时间戳
  312. prices: 0 //实付
  313. };
  314. },
  315. onUnload() {
  316. var polyvPlayerContext = this.selectComponent('#playerVideo');
  317. if (polyvPlayerContext != null) {
  318. //存储播放记录
  319. let PlayCurrentTime = polyvPlayerContext.getCurrentTime();
  320. if (PlayCurrentTime) {
  321. let key = this.vid;
  322. uni.setStorageSync(key, PlayCurrentTime);
  323. this.addStudyRecord(PlayCurrentTime);
  324. }
  325. }
  326. },
  327. computed: { ...mapGetters(['userInfo']) },
  328. onLoad(option) {
  329. const Verify = require('@/wxcomponents/verify_mpsdk/main.js');
  330. Verify.init();
  331. this.id = option.id;
  332. this.$api.courseInfo(option.id).then(res => {
  333. this.pageData = res.data.data;
  334. this.prices = res.data.data.price.toFixed(2);
  335. this.getTeacher(res.data.data.teacherIds);
  336. });
  337. this.getChapter(this.id);
  338. this.getcommendList(this.id);
  339. this.getHaveThis();
  340. let time = uni.getStorageSync('face');
  341. if (time) {
  342. let nowTime = new Date().getTime() / 1000;
  343. if (nowTime - time < 24 * 3600) {
  344. this.faceGetState = true;
  345. }
  346. }
  347. },
  348. onShow() {
  349. if (!uni.getStorageSync('union_id') && this.$store.state.token === '') {
  350. } else {
  351. this.favoritesStatus();
  352. }
  353. let that = this;
  354. this.windowHeight = uni.getSystemInfoSync().windowHeight;
  355. setTimeout(function() {
  356. that.getHeight();
  357. }, 1800);
  358. },
  359. onPageScroll: function(e) {
  360. //防止触发两次跳动
  361. if (this.isClick) {
  362. return;
  363. }
  364. if (e.scrollTop <= this.hh1) {
  365. this.current = 0;
  366. }
  367. if (e.scrollTop <= this.hh2 && e.scrollTop > this.hh1) {
  368. this.current = 1;
  369. }
  370. if (e.scrollTop <= this.hh3 && e.scrollTop > this.hh2) {
  371. this.current = 2;
  372. }
  373. if (e.scrollTop > this.hh3) {
  374. this.current = 3;
  375. }
  376. },
  377. methods: {
  378. //检测是否已购买该课程
  379. getHaveThis() {
  380. var self = this;
  381. var data = {
  382. possessId: this.id,
  383. typeId: 1
  384. };
  385. if (this.$method.isLogin()) {
  386. this.$api.systemuserowner(data).then(res => {
  387. if (res.data.code === 200) {
  388. self.payStatus = res.data.data.payStatus;
  389. }
  390. });
  391. }
  392. },
  393. //提交订单
  394. getorder() {
  395. var self = this;
  396. var data = {
  397. goodsList: [
  398. {
  399. goodsId: self.pageData.courseId,
  400. num: 1,
  401. goodsType: 1
  402. }
  403. ]
  404. };
  405. if (self.activeCouponId.length !== 0) {
  406. if (self.activeCouponId[0] === 1) {
  407. data.couponId = self.activeCouponId[1];
  408. }
  409. if (self.activeCouponId[0] === 2) {
  410. data.activityId = self.activeCouponId[1];
  411. }
  412. }
  413. self.$api.order(data).then(res => {
  414. if (res.data.code === 200) {
  415. let objarr = res.data.data;
  416. wx.requestPayment({
  417. timeStamp: objarr.timeStamp,
  418. nonceStr: objarr.nonceStr,
  419. package: objarr.package,
  420. signType: objarr.signType,
  421. paySign: objarr.sign,
  422. success(result) {
  423. uni.showModal({
  424. title: '提示',
  425. content: '支付成功',
  426. showCancel: false,
  427. success: function(resst) {
  428. if (resst.confirm) {
  429. self.showPricePop = false;
  430. self.getHaveThis();
  431. }
  432. }
  433. });
  434. },
  435. fail(err) {
  436. uni.showModal({
  437. title: '提示',
  438. content: '支付失败',
  439. showCancel: false,
  440. success: function(resst) {
  441. self.showPricePop = false;
  442. self.getHaveThis();
  443. }
  444. });
  445. }
  446. });
  447. } else {
  448. uni.showToast({
  449. title: res.data.msg,
  450. icon: 'none',
  451. duration: 2000
  452. });
  453. }
  454. });
  455. },
  456. //选择卷触发
  457. activeCoupon(e) {
  458. var self = this;
  459. self.activeCouponId = JSON.parse(e.detail.value);
  460. self.computedPrice(JSON.parse(e.detail.value));
  461. },
  462. //计算价格
  463. async computedPrice(arrs) {
  464. var self = this;
  465. const aites = await this.$api.courseInfo(this.id);
  466. self.prices = aites.data.data.price.toFixed(2);
  467. if (arrs[0] === 1) {
  468. self.configList.forEach((item, index) => {
  469. if (item.couponId === arrs[1]) {
  470. if (item.couponType === 0) {
  471. self.prices = (self.prices - item.price).toFixed(2);
  472. }
  473. if (item.couponType === 1) {
  474. self.prices = (self.prices * (item.price * 0.1)).toFixed(2);
  475. }
  476. }
  477. });
  478. }
  479. if (arrs[0] === 2) {
  480. self.activityList.forEach((item, index) => {
  481. if (item.id === arrs[1]) {
  482. if (item.activityType === '0') {
  483. self.prices = (self.prices - item.price).toFixed(2);
  484. }
  485. if (item.activityType === '1') {
  486. self.prices = (self.prices * (item.price * 0.1)).toFixed(2);
  487. }
  488. if (item.activityType === '2') {
  489. }
  490. if (item.activityType === '3') {
  491. self.prices = item.price.toFixed(2);
  492. }
  493. if (item.activityType === '4') {
  494. self.prices = (self.prices - item.price).toFixed(2);
  495. }
  496. if (item.activityType === '5') {
  497. self.prices = (self.prices * (item.price * 0.1)).toFixed(2);
  498. }
  499. }
  500. });
  501. }
  502. console.log(self.prices);
  503. },
  504. //优惠卷
  505. getConfiguration() {
  506. var self = this;
  507. self.newDate = self.$method.timest();
  508. if (this.pricestatus) {
  509. self.pricestatus = false;
  510. return;
  511. }
  512. self.pricestatus = true;
  513. },
  514. addStudyRecord(study_duration) {
  515. let data = {
  516. courseId: this.id,
  517. sectionId: this.infoData.sectionId,
  518. studyDuration: study_duration
  519. };
  520. this.$api.studyRecord(data).then(result => {});
  521. },
  522. onStateChange(newstate, oldstate) {
  523. if (newstate.detail.newstate == 'playing') {
  524. if (this.firstPlay) {
  525. var polyvPlayerContext = this.selectComponent('#playerVideo');
  526. if (polyvPlayerContext != null) {
  527. //获取播放记录
  528. let key = this.vid;
  529. let PlayDuration = uni.getStorageSync(key);
  530. if (PlayDuration) {
  531. polyvPlayerContext.seek(parseInt(PlayDuration));
  532. this.firstPlay = false;
  533. }
  534. }
  535. }
  536. }
  537. },
  538. swipStatus() {
  539. this.activeStatus = !this.activeStatus;
  540. let self = this;
  541. self.$nextTick(function() {
  542. self.getHeight();
  543. });
  544. },
  545. getHeight() {
  546. let that = this;
  547. const query = uni.createSelectorQuery().in(this);
  548. query
  549. .select('#modules1')
  550. .boundingClientRect(data => {
  551. that.h1 = data.height;
  552. that.countHeight(that);
  553. })
  554. .exec();
  555. query
  556. .select('#modules2')
  557. .boundingClientRect(data => {
  558. that.h2 = data.height;
  559. that.countHeight(that);
  560. })
  561. .exec();
  562. query
  563. .select('#modules3')
  564. .boundingClientRect(data => {
  565. that.h3 = data.height;
  566. that.countHeight(that);
  567. })
  568. .exec();
  569. query
  570. .select('#modules4')
  571. .boundingClientRect(data => {
  572. if (that.h4 == 0) {
  573. that.h4 = data.height;
  574. }
  575. that.countHeight(that);
  576. })
  577. .exec();
  578. query
  579. .select('#foot')
  580. .boundingClientRect(data => {
  581. that.foot_h = data.height;
  582. that.countModelusPadding();
  583. })
  584. .exec();
  585. query
  586. .select('#top')
  587. .boundingClientRect(data => {
  588. that.top_h = data.height;
  589. that.countModelusPadding();
  590. })
  591. .exec();
  592. },
  593. favoritesStatus() {
  594. this.$api.coursecollectPD(this.id).then(result => {
  595. if (result.data.data === undefined) {
  596. this.collecStatus = false;
  597. } else {
  598. this.collecStatus = true;
  599. }
  600. });
  601. },
  602. favorites() {
  603. var self = this;
  604. if (!uni.getStorageSync('union_id') && this.$store.state.token === '') {
  605. uni.navigateTo({
  606. url: '/pages/login/login'
  607. });
  608. } else {
  609. if (this.collecStatus) {
  610. this.$api.coursecollectPD(self.id).then(results => {
  611. self.$api.deletecoursecollect(results.data.data.collectCourseId).then(resz => {
  612. self.favoritesStatus();
  613. });
  614. });
  615. } else {
  616. var data = {
  617. userId: this.$store.state.userInfo.userId,
  618. courseId: self.id
  619. };
  620. this.$api.coursecollect(data).then(res => {
  621. self.favoritesStatus();
  622. });
  623. }
  624. }
  625. },
  626. getcommendList(v) {
  627. let self = this;
  628. var data = {
  629. courseId: v
  630. };
  631. this.$api.courseInforecommendList(data).then(res => {
  632. self.commendList = res.data.data;
  633. self.$nextTick(function() {
  634. self.getHeight();
  635. });
  636. });
  637. },
  638. activeList(item, index) {
  639. var self = this;
  640. var dataset = {
  641. chapterId: item.chapterId
  642. };
  643. this.$api.coursesectionlist(dataset).then(result => {
  644. self.boxList = result.data.rows;
  645. });
  646. this.showBox = true;
  647. },
  648. getsec(item) {
  649. this.startStatus = false;
  650. this.infoData = item;
  651. this.vid = this.infoData.vid;
  652. this.activeStatusCata = item.chapterId;
  653. this.showBox = false;
  654. this.firstPlay = true;
  655. },
  656. getChapter(v) {
  657. var self = this;
  658. var data = {
  659. courseId: v
  660. };
  661. this.$api.coursechapterlist(data).then(res => {
  662. var chaList = res.data.rows;
  663. if (chaList.length === 0) {
  664. uni.showToast({
  665. title: '暂无相关章节内容',
  666. icon: 'none',
  667. duration: 2000
  668. });
  669. return;
  670. }
  671. var dataset = {
  672. chapterId: res.data.rows[0].chapterId
  673. };
  674. self.$api.coursesectionlist(dataset).then(result => {
  675. self.getsec(result.data.rows[0]);
  676. });
  677. this.chapterList = chaList;
  678. });
  679. },
  680. getTeacher(v) {
  681. let self = this;
  682. var data = {
  683. teacherIds: v
  684. };
  685. this.$api.teacherList(data).then(res => {
  686. self.teacherInfo = res.data.rows[0];
  687. });
  688. },
  689. startVideo() {
  690. if (!uni.getStorageSync('union_id')) {
  691. uni.navigateTo({
  692. url: '/pages/login/login'
  693. });
  694. } else {
  695. if (this.payStatus === 0) {
  696. uni.showToast({
  697. title: '暂未购买该课程',
  698. icon: 'none',
  699. duration: 2000
  700. });
  701. return;
  702. }
  703. if (this.userInfo.certified != 1) {
  704. uni.showModal({
  705. title: '提示',
  706. content: '请先实名认证',
  707. success: function(res) {
  708. if (res.confirm) {
  709. uni.navigateTo({
  710. url: '/pages2/wd/info'
  711. });
  712. } else if (res.cancel) {
  713. }
  714. }
  715. });
  716. return;
  717. }
  718. //模拟今天是否人脸识别
  719. if (!this.faceGetState) {
  720. this.certification();
  721. return;
  722. }
  723. if (this.vid === null) {
  724. uni.showToast({
  725. title: '视频加载失败',
  726. icon: 'none',
  727. duration: 2000
  728. });
  729. return;
  730. }
  731. this.$api
  732. .polyvVideoSign(this.vid)
  733. .then(res => {
  734. this.startStatus = true;
  735. })
  736. .catch(err => {
  737. console.log('报错');
  738. });
  739. }
  740. },
  741. async certification() {
  742. var self = this;
  743. const faceBiz = await self.$api.facecertificationPicBizToken();
  744. self.BizToken = faceBiz.data.data.bizToken;
  745. let time = new Date().getTime() / 1000;
  746. uni.setStorageSync('face', time);
  747. wx.startVerify({
  748. data: {
  749. token: self.BizToken
  750. },
  751. success: result => {
  752. setTimeout(() => {
  753. self.faceGetState = true;
  754. self.$api.facecertificationPicDetectInfo(self.BizToken).then(faceRec => {
  755. if (faceRec.data.data === 0) {
  756. uni.showToast({
  757. title: '识别成功',
  758. icon: 'none',
  759. duration: 2000
  760. });
  761. } else {
  762. uni.showToast({
  763. title: '识别失败',
  764. icon: 'none',
  765. duration: 2000
  766. });
  767. console.log('识别失败');
  768. }
  769. });
  770. }, 500);
  771. },
  772. fail: err => {
  773. setTimeout(() => {
  774. console.log('识别功能失败');
  775. uni.showModal({
  776. title: '提示',
  777. content: err,
  778. showCancel: false
  779. });
  780. }, 500);
  781. }
  782. });
  783. },
  784. touchMove(e) {
  785. this.isClick = false;
  786. },
  787. countModelusPadding() {
  788. let offsetHeight = this.windowHeight - this.foot_h - this.top_h;
  789. this.modules4Bottom = offsetHeight > this.h4 ? offsetHeight - this.h4 : 7;
  790. },
  791. countHeight(that) {
  792. this.hh1 = this.h1;
  793. this.hh2 = this.h1 + this.h2;
  794. this.hh3 = this.h1 + this.h2 + this.h3;
  795. this.hh4 = this.h1 + this.h2 + this.h3 + this.h4;
  796. },
  797. getNavTo(item) {
  798. this.$navTo.togo('/pages2/course/detail', {
  799. id: item.courseId
  800. });
  801. },
  802. change(index) {
  803. this.current = index;
  804. let that = this;
  805. this.isClick = true;
  806. if (index == 0) {
  807. uni.pageScrollTo({
  808. scrollTop: 0
  809. });
  810. }
  811. if (index == 1) {
  812. uni.pageScrollTo({
  813. scrollTop: that.h1 + 4
  814. });
  815. }
  816. if (index == 2) {
  817. uni.pageScrollTo({
  818. scrollTop: that.h1 + that.h2 + 4
  819. });
  820. }
  821. if (index == 3) {
  822. uni.pageScrollTo({
  823. scrollTop: that.h1 + that.h2 + that.h3 + 4
  824. });
  825. }
  826. },
  827. jumpBuy() {
  828. var self = this;
  829. uni.getStorage({
  830. key: 'union_id',
  831. success: function(res) {
  832. // 继续操作
  833. self.$api
  834. .configurationlistCoupon({
  835. courseId: self.id
  836. })
  837. .then(configL => {
  838. self.configList = configL.data.rows;
  839. });
  840. self.$api
  841. .configurationlistConfig({
  842. courseId: self.id
  843. })
  844. .then(activityL => {
  845. self.activityList = activityL.data.rows;
  846. });
  847. self.showPricePop = true;
  848. },
  849. fail: function(err) {
  850. //重新登入
  851. self.$navTo.togo('/pages/login/login', {});
  852. }
  853. });
  854. }
  855. }
  856. };
  857. </script>
  858. <style>
  859. ::-webkit-scrollbar {
  860. width: 0;
  861. height: 0;
  862. color: transparent;
  863. }
  864. </style>
  865. <style scope>
  866. .btnspric {
  867. border-top: 1rpx solid #eee;
  868. display: flex;
  869. align-items: center;
  870. justify-content: space-between;
  871. height: 108rpx;
  872. padding-left: 43rpx;
  873. padding-right: 32rpx;
  874. }
  875. .btnspric > .lefprL {
  876. font-size: 36rpx;
  877. color: #0c141f;
  878. font-weight: bold;
  879. }
  880. .btnspric > .lefprR {
  881. padding: 0rpx 24rpx;
  882. height: 60rpx;
  883. line-height: 60rpx;
  884. text-align: center;
  885. color: #fff;
  886. background: #32467b;
  887. border-radius: 24rpx;
  888. box-shadow: 0rpx 0rpx 16rpx 4rpx rgba(145, 156, 178, 0.1);
  889. }
  890. .yhj,
  891. .hdyhj {
  892. padding: 24rpx 29rpx 24rpx 34rpx;
  893. }
  894. .yhj {
  895. border-bottom: 16rpx solid #f9f9f9;
  896. }
  897. .yhjtit {
  898. font-size: 30rpx;
  899. color: #0c141f;
  900. font-weight: 500;
  901. margin-bottom: 14rpx;
  902. }
  903. .yhjList {
  904. display: flex;
  905. align-items: center;
  906. justify-content: space-between;
  907. margin-bottom: 14rpx;
  908. }
  909. .yhjList > .yhjLefts {
  910. display: flex;
  911. align-items: center;
  912. }
  913. .yhjLefts > .yhl {
  914. color: #32467b;
  915. font-size: 30rpx;
  916. margin-right: 31rpx;
  917. }
  918. .yhjLefts > .yhbq {
  919. font-size: 24rpx;
  920. color: #ff9500;
  921. border-radius: 18rpx;
  922. background-color: rgba(255, 149, 0, 0.2);
  923. border: 2rpx solid #ff9500;
  924. height: 38rpx;
  925. line-height: 38rpx;
  926. padding: 0rpx 16rpx;
  927. }
  928. .ts {
  929. font-size: 24rpx;
  930. color: #999;
  931. margin: 14rpx 0rpx;
  932. padding-right: 29rpx;
  933. padding-left: 34rpx;
  934. }
  935. .yh {
  936. padding-top: 20rpx;
  937. }
  938. .yh > .yhtitle {
  939. display: flex;
  940. align-items: center;
  941. justify-content: space-between;
  942. padding-right: 29rpx;
  943. padding-left: 34rpx;
  944. }
  945. .priceBxs {
  946. display: flex;
  947. align-items: center;
  948. }
  949. .priceBxs > .pricleft {
  950. border-radius: 24rpx;
  951. border: 1rpx solid #e91313;
  952. background-color: rgba(233, 19, 19, 0.1);
  953. padding: 0rpx 18rpx;
  954. height: 49rpx;
  955. line-height: 49rpx;
  956. text-align: center;
  957. font-size: 30rpx;
  958. font-weight: 500;
  959. color: #e91313;
  960. margin-right: 13rpx;
  961. }
  962. .topBox {
  963. padding: 32rpx 32rpx 24rpx;
  964. border-bottom: 1rpx solid #eeeeee;
  965. }
  966. .topBox > .boldFonstType {
  967. font-weight: 500;
  968. font-size: 30rpx;
  969. margin: 16rpx 0rpx 23rpx;
  970. }
  971. .topBox > .firstTopL {
  972. display: flex;
  973. align-items: center;
  974. }
  975. .topBox > .firstTopL > .imageBs {
  976. width: 331rpx;
  977. height: 160rpx;
  978. border-radius: 6rpx;
  979. overflow: hidden;
  980. margin-right: 8rpx;
  981. box-shadow: 0rpx 6rpx 6rpx 0rpx rgba(47, 67, 121, 0.08);
  982. }
  983. .topBox > .firstTopL > .imageBs > image {
  984. width: 100%;
  985. height: 100%;
  986. }
  987. .topBox > .firstTopL > .textBs {
  988. font-size: 30rpx;
  989. font-weight: bold;
  990. color: #0c141f;
  991. }
  992. .content {
  993. padding: 24rpx;
  994. text-align: left;
  995. }
  996. .catalogBox {
  997. display: flex;
  998. align-items: center;
  999. flex-wrap: nowrap;
  1000. overflow-x: auto;
  1001. padding-left: 38rpx;
  1002. max-height: 305rpx;
  1003. overflow-y: auto;
  1004. transition: all 0.4s;
  1005. }
  1006. .catalogBox > .catalogA {
  1007. min-width: 200rpx;
  1008. height: 48rpx;
  1009. line-height: 48rpx;
  1010. // text-align: center;
  1011. border: 2rpx solid transparent;
  1012. white-space: nowrap;
  1013. text-overflow: ellipsis;
  1014. overflow: hidden;
  1015. word-break: break-all;
  1016. border-radius: 10rpx;
  1017. background: rgba(22, 119, 255, 0.05);
  1018. padding-left: 19rpx;
  1019. box-sizing: border-box;
  1020. padding-right: 15rpx;
  1021. margin-right: 16rpx;
  1022. margin-bottom: 20rpx;
  1023. margin-top: 15rpx;
  1024. font-size: 24rpx;
  1025. color: #666;
  1026. }
  1027. .catalogBox > .activesq {
  1028. border-color: #1677ff;
  1029. }
  1030. .changeCatalogBox {
  1031. display: block;
  1032. }
  1033. .catalogBox::-webkit-scrollbar {
  1034. display: none; /* Chrome Safari */
  1035. }
  1036. .box {
  1037. position: relative;
  1038. top: 600rpx;
  1039. padding-bottom: 88rpx;
  1040. }
  1041. .price_t2 {
  1042. font-size: 18rpx;
  1043. font-family: PingFang SC;
  1044. font-weight: 500;
  1045. text-decoration: line-through;
  1046. color: #999999;
  1047. }
  1048. .price_t1 {
  1049. font-size: 33rpx;
  1050. font-family: PingFang SC;
  1051. font-weight: bold;
  1052. color: #e91313;
  1053. }
  1054. .sc_t {
  1055. font-size: 22rpx;
  1056. color: #000000;
  1057. }
  1058. .sc {
  1059. width: 29rpx;
  1060. height: 29rpx;
  1061. }
  1062. .buy {
  1063. width: 138rpx;
  1064. height: 48rpx;
  1065. line-height: 48rpx;
  1066. background: #32467b;
  1067. border-radius: 10rpx;
  1068. color: #ffffff;
  1069. font-size: 28rpx;
  1070. text-align: center;
  1071. vertical-align: middle;
  1072. position: absolute;
  1073. right: 30rpx;
  1074. }
  1075. .video_body {
  1076. padding-bottom: 96rpx;
  1077. }
  1078. .footer_tab {
  1079. position: fixed;
  1080. bottom: 0;
  1081. height: 96rpx;
  1082. width: 100%;
  1083. background-color: #ffffff;
  1084. }
  1085. .tj_box {
  1086. width: 50%;
  1087. display: inline-block;
  1088. text-align: center;
  1089. margin: 10rpx 0;
  1090. }
  1091. .teacher_t {
  1092. font-size: 24rpx;
  1093. font-family: PingFang SC;
  1094. font-weight: 400;
  1095. color: #666666;
  1096. line-height: 36rpx;
  1097. margin-left: 15rpx;
  1098. }
  1099. .teacher_img {
  1100. width: 87rpx;
  1101. height: 129rpx;
  1102. }
  1103. .t2 {
  1104. font-size: 24rpx;
  1105. font-family: PingFang SC;
  1106. color: #666666;
  1107. line-height: 36rpx;
  1108. margin: 15rpx;
  1109. }
  1110. .r_t2 {
  1111. width: 201rpx;
  1112. height: 49rpx;
  1113. background: rgba(22, 119, 255, 0.05);
  1114. border: 1rpx solid #32467b;
  1115. border-radius: 16rpx;
  1116. color: #666666;
  1117. font-size: 23rpx;
  1118. text-align: center;
  1119. display: flex;
  1120. align-items: center;
  1121. padding: 5rpx;
  1122. }
  1123. .scroll_box {
  1124. width: 100%;
  1125. height: 60rpx;
  1126. background: #ffffff;
  1127. box-shadow: 0rpx 0rpx 16rpx 4rpx rgba(145, 156, 178, 0.1);
  1128. white-space: nowrap;
  1129. overflow: hidden;
  1130. margin: 15rpx 0;
  1131. }
  1132. .r_sliper {
  1133. padding: 0 20rpx;
  1134. }
  1135. .top_line {
  1136. width: 6rpx;
  1137. height: 22rpx;
  1138. background: #32467b;
  1139. margin-right: 10rpx;
  1140. }
  1141. .video_t2 {
  1142. font-size: 24rpx;
  1143. font-family: PingFang SC;
  1144. font-weight: 500;
  1145. color: #666666;
  1146. }
  1147. .video_t1 {
  1148. font-size: 28rpx;
  1149. font-family: PingFang SC;
  1150. font-weight: bold;
  1151. color: #333333;
  1152. }
  1153. .video_play {
  1154. position: absolute;
  1155. width: 95rpx;
  1156. height: 95rpx;
  1157. top: 0;
  1158. left: 0;
  1159. right: 0;
  1160. bottom: 0;
  1161. margin: auto;
  1162. }
  1163. .video_box {
  1164. position: relative;
  1165. }
  1166. .rotoct {
  1167. transform: rotate(90deg);
  1168. }
  1169. page {
  1170. background: #ffffff;
  1171. }
  1172. </style>