detail.vue 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821
  1. <template>
  2. <view>
  3. <nav-bar title="课程详情"></nav-bar>
  4. <view class="videoBox" >
  5. <!-- <view > -->
  6. <view class="video_box" v-if="!startStatus">
  7. <image :src="$method.splitImgHost(detail.coverUrl)" style="width: 100%;height: 450rpx;"></image>
  8. <image v-if="false" class="video_play" src="/static/play.png" @click="startVideo"></image>
  9. </view>
  10. <view v-else class="video_box" style="width: 100%;height: 450rpx;">
  11. <polyv-player
  12. id="playerVideo"
  13. playerId="playerVideo"
  14. height="450rpx"
  15. :vid="vid"
  16. :showSettingBtn="true"
  17. :enablePlayGesture="true"
  18. :playbackRate="playbackRate"
  19. :isAllowSeek="isAllowSeek"
  20. :autoplay="autoplay"
  21. :startTime="startTime"
  22. @statechange="onStateChange"
  23. ></polyv-player>
  24. </view>
  25. <view class="cou_title">
  26. <view class="title_name">
  27. <!-- <view class="yearTag" v-if="detail.year">{{detail.year}}</view> -->
  28. <view class="titleTag">{{detail.goodsName}}</view>
  29. </view>
  30. <view style="display: flex;justify-content: space-between;margin-top: 13rpx;">
  31. <view class="prices">
  32. <!-- <text class="price_sym">¥</text> -->
  33. <!-- <text class="price_word">¥ {{ detail.standPrice }}</text> -->
  34. <text v-if="detail.standPrice" class="price_word">¥ {{ detail.standPrice }}</text>
  35. <text v-else class="price_word free">免费</text>
  36. <text v-if="detail.linePrice" class="sale"> ¥ </text>
  37. <text v-if="detail.linePrice" class="price_line"> {{detail.linePrice }}</text>
  38. </view>
  39. <view class="noteTag">
  40. <!-- <image src="/static/icon/wk_icon1.png" class="wk_icon"></image> -->
  41. 共 <text class="blackFont">{{courseList.length}} 课程 {{detail.classHours || '-'}}</text> 学时
  42. </view>
  43. </view>
  44. </view>
  45. <!-- </view> -->
  46. </view>
  47. <view class="contents">
  48. <!-- <u-line color="#D6D6DB" /> -->
  49. <!-- <view style="height: 80rpx;">
  50. <view><u-tabs :list="list" :item-width="itemWidth()" font-size="30" bar-width="24" :current="current" @change="change" active-color="#007AFF"></u-tabs></view>
  51. </view> -->
  52. <view class="tabs">
  53. <view v-for="(item, index) in list" :key="index" class="tab_item"
  54. :class="[list.length == 2 ? 'twoBtn' : list.length == 3 ? 'threeBtn' : '',{nactive: current == index}]" @click="change(index)">{{ item.name }}</view>
  55. </view>
  56. <view style="padding: 20rpx;padding-bottom: 100rpx;position: relative;" v-show="current==0">
  57. <view class="content">
  58. <view v-html="detail.mobileDetailHtml" style="width: 100%;overflow: hidden;"></view>
  59. </view>
  60. </view>
  61. <view style="padding: 20rpx;padding-bottom: 100rpx;position: relative;" v-show="current==1">
  62. <view v-for="(item,index) in courseList" :key="index" >
  63. <view class="courseItemBox" >
  64. <view class="courseItem" @click="openCourse(item)">
  65. <view class="courseName">{{item.courseName}}</view>
  66. <view>
  67. <image src="/static/icon/up.png" class="icon_up" v-if="item.down"></image>
  68. <image src="/static/icon/down.png" class="icon_up" v-if="!item.down"></image>
  69. </view>
  70. </view>
  71. <view v-show="!item.down">
  72. <view v-for="(itemM,indexM) in item.menuList" :key="indexM">
  73. <courseModule :courseId="itemM.courseId" :needOpen="(isFirstEnter && menuIndex[0] === index && menuIndex[1] === indexM) ? true : false" v-if="itemM.type==1" :menuItem="itemM"></courseModule>
  74. <courseChapter :courseId="itemM.courseId" :needOpen="(isFirstEnter && menuIndex[0] === index && menuIndex[1] === indexM) ? true : false" v-if="itemM.type==2" :isBuy="false" :menuItem="itemM"></courseChapter>
  75. <courseSection :courseId="itemM.courseId" v-if="itemM.type==3" :isBuy="false" :menuItem="itemM"></courseSection>
  76. <u-line></u-line>
  77. </view>
  78. </view>
  79. </view>
  80. </view>
  81. </view>
  82. <view style="padding: 20rpx;padding-bottom: 100rpx;position: relative;" v-show="current==2">
  83. <!-- <view > -->
  84. <view v-for="(item,index) in freeMenuList" :key="index" >
  85. <view class="courseItemBox" >
  86. <view class="courseItem">
  87. <view class="courseName">{{item.freeExamName}}</view>
  88. </view>
  89. </view>
  90. </view>
  91. <!-- </view> -->
  92. </view>
  93. </view>
  94. <view class="bottomBox" v-if="!hideBuyState">
  95. <!-- <view class="priceTag">¥ {{toFixed(detail.standPrice)}}</view> -->
  96. <!-- <view class="priceTag">分享</view> -->
  97. <view class="icons">
  98. <view class="icon_item ones">
  99. <image src="/static/index/share.png" class="share"></image>
  100. <button type="default" open-type="share" class="bt_share"></button>
  101. <view class="share_w">分享</view>
  102. </view>
  103. <view class="icon_item">
  104. <image src="/static/index/shopcar.png" class="shopcar" @click="toShopcar()"></image>
  105. <view class="share_w">购物车</view>
  106. </view>
  107. </view>
  108. <view style="display: flex;color: #FFFFFF;align-items: center;">
  109. <view class="btn1" @click="addCart">加购物车</view>
  110. <view class="btn2" @click="buy">立即购买 </view>
  111. </view>
  112. </view>
  113. <!-- 已购买过课程的弹窗 -->
  114. <u-popup v-model="bugCourseModel" mode="center" border-radius="40">
  115. <view class="had_bugCourse">
  116. <image src="/pages3/static/imgs/hadBug.png" class="share"></image>
  117. <view class="tips">
  118. <view class="warns">温馨提示</view>
  119. <view class="words">您<text>已购买过</text>该商品课程</view>
  120. <view class="words">可立即前往学习</view>
  121. </view>
  122. <view class="tip_botton">
  123. <view class="cancel_btn" @click="changeKown()">知道了</view>
  124. <view class="confirm_btn" @click="toStudy()">去学习</view>
  125. </view>
  126. </view>
  127. </u-popup>
  128. </view>
  129. </template>
  130. <script>
  131. import courseModule from '@/components/course/courseModule.vue';
  132. import courseChapter from '@/components/course/courseChapter.vue';
  133. import courseSection from '@/components/course/courseSection.vue';
  134. import { mapGetters,mapMutations } from 'vuex';
  135. export default {
  136. components: {
  137. courseModule,
  138. courseChapter,
  139. courseSection
  140. },
  141. data() {
  142. return {
  143. id:0,
  144. list: [],
  145. menuIndex:[],
  146. current:0,
  147. detail:{},
  148. courseList:[],
  149. menuList:[],
  150. freeMenuList:[],
  151. startStatus:false,
  152. playbackRate: [1.0],
  153. isAllowSeek:'no',
  154. vid:'',
  155. autoplay:true,
  156. listenConfigList:[],
  157. listenSecond:0,
  158. isFirstEnter:true, //是否首次进入
  159. timer:null,
  160. businessData:{},
  161. startTime:0,
  162. bugCourseModel: false, // 弹窗
  163. hadBuyCourse: {}, // 已购买课程信息
  164. };
  165. },
  166. computed: { ...mapGetters(['userInfo','goodsAuditionConfigIdList','playSectionId','hideBuyState']) },
  167. onLoad(option) {
  168. this.id = option.id;
  169. this.getDetail()
  170. this.goodsCourseList()
  171. this.appCommonGoodsCourseModuleFreeExamList();
  172. this.getIsBuy() // 判断是否已经购买过该课程
  173. wx.showShareMenu({
  174. withShareTicket: true,
  175. menus: ["shareAppMessage", "shareTimeline"]
  176. })
  177. },
  178. onUnload(option) {
  179. this.$store.commit('setPlaySectionId', {playSectionId :0});
  180. //移除所有的事件监听器
  181. uni.$off();
  182. },
  183. // 分享到朋友圈
  184. onShareTimeline() {
  185. return {
  186. title: this.detail.goodsName,
  187. query: 'id=' + this.id,
  188. imageUrl: this.$method.splitImgHost(this.detail.coverUrl)
  189. }
  190. },
  191. // 分享给朋友
  192. onShareAppMessage() {
  193. return {
  194. title: this.detail.goodsName,
  195. path: `/pages3/course/detail?id=` + this.id,
  196. imageUrl: this.$method.splitImgHost(this.detail.coverUrl)
  197. }
  198. },
  199. mounted() {
  200. let self = this
  201. uni.$on('getSection', item => {
  202. //播放试听
  203. self.listenSecond = 0
  204. for (var itemChild of self.listenConfigList) {
  205. if(self.playSectionId == (itemChild.sectionId || itemChild.menuId) && item.courseId == itemChild.courseId){
  206. if(itemChild.auditionMinute>0){
  207. // self.listenSecond = itemChild.auditionMinute *60 //试听秒数
  208. self.listenSecond = itemChild.auditionMinute //试听秒数 auditionMinute调整为秒单位
  209. }
  210. }
  211. }
  212. if(self.listenSecond>0){
  213. if(self.timer){
  214. clearInterval(self.timer);
  215. }
  216. if(self.vid){
  217. //切换视频
  218. var polyvPlayerContext = self.selectComponent('#playerVideo');
  219. polyvPlayerContext.changeVid(item.recordingUrl)
  220. }else{
  221. self.vid = item.recordingUrl
  222. }
  223. self.startStatus = true
  224. self.startTime = 0
  225. }else{
  226. self.$u.toast('试听配置错误');
  227. }
  228. })
  229. this.updateChapterOpen(true)
  230. },
  231. methods: {
  232. ...mapMutations(['updateChapterOpen']),
  233. itemWidth() {
  234. return (100/this.list.length)+'%'
  235. },
  236. appCommonGoodsCourseModuleFreeExamList() {
  237. // url: '/app/common/goods/course/moduleFreeExamList/'+data,
  238. this.$api.appCommonGoodsCourseModuleFreeExamList(this.id).then(res => {
  239. if(res.data.data.length) {
  240. this.freeMenuList = res.data.data;
  241. this.list = [
  242. {
  243. name: '课程介绍'
  244. },
  245. {
  246. name: '课程目录'
  247. },
  248. {
  249. name: '赠送'
  250. }
  251. ]
  252. } else {
  253. this.list = [
  254. {
  255. name: '课程介绍'
  256. },
  257. {
  258. name: '课程目录'
  259. }
  260. ]
  261. }
  262. console.log(this.list)
  263. })
  264. },
  265. courseBusiness(){
  266. // url: '/app/common/course/business/'+data,
  267. this.$api.courseBusiness(this.detail.businessId).then(res => {
  268. this.businessData = res.data.data;
  269. })
  270. },
  271. toFixed(number) {
  272. if(number > 0) {
  273. return number.toFixed(2)
  274. } else {
  275. return '0.00'
  276. }
  277. },
  278. onStateChange(newstate, oldstate) {
  279. if (newstate.detail.newstate == 'playing') {
  280. //开始播放
  281. if(this.timer){
  282. clearInterval(this.timer);
  283. }
  284. this.timer = setInterval(this.timeEvent, 1500);//定时器
  285. }
  286. },
  287. closePlay(){
  288. this.$store.commit('setPlaySectionId', {playSectionId :0});
  289. this.vid = ""
  290. this.startStatus = false
  291. },
  292. timeEvent() {
  293. let self = this
  294. var polyvPlayerContext = this.selectComponent('#playerVideo');
  295. if (polyvPlayerContext != null) {
  296. let PlayCurrentTime = polyvPlayerContext.getCurrentTime();
  297. if(PlayCurrentTime>=this.listenSecond){
  298. polyvPlayerContext.stop();
  299. polyvPlayerContext.exitFullScreen();
  300. clearInterval(this.timer);
  301. this.timer = null
  302. uni.showModal({
  303. title: '提示',
  304. content: '试听结束,购买课程可学习全部',
  305. showCancel:false,
  306. success: function(resst) {
  307. self.closePlay()
  308. }
  309. });
  310. }
  311. }
  312. },
  313. openCourse(item){
  314. item.down = !item.down
  315. if(!item.down&&item.menuList.length==0){
  316. this.getMenuList(item)
  317. }
  318. },
  319. addShopCart() {
  320. let self = this
  321. this.$api.addCart({goodsId:this.id}).then(res => {
  322. if(res.data.code==200){
  323. uni.setStorageSync('updateCart',1) //提醒刷新购物车
  324. uni.showToast({
  325. title: '添加成功'
  326. });
  327. }else{
  328. this.$u.toast(res.data.msg);
  329. }
  330. });
  331. },
  332. goodsCourseList() {
  333. // url: '/app/common/goods/course/list/'+ data,
  334. this.$api.goodsCourseList(this.id).then(res => {
  335. if(res.data.code==200){
  336. for(let i=0;i<res.data.rows.length;i++){
  337. let item = res.data.rows[i]
  338. item.down = true
  339. item.menuList = []
  340. }
  341. this.courseList = res.data.rows;
  342. this.getFirstCourse();
  343. }
  344. });
  345. },
  346. /**
  347. * 获取第一个有模块或者章的课程
  348. */
  349. async getFirstCourse() {
  350. for(let i = 0; i < this.courseList.length; i++) {
  351. let menuIndexOrFalse = await this.getCourseMenus(this.courseList[i]);
  352. if(menuIndexOrFalse !== false) {
  353. this.menuIndex = [i,menuIndexOrFalse]
  354. this.openCourse(this.courseList[i])
  355. break
  356. }
  357. }
  358. },
  359. getCourseMenus(item) {
  360. return new Promise(resolve => {
  361. // url: '/app/common/course/menuList',
  362. this.$api.menuList({courseId:item.courseId}).then(res => {
  363. if(res.data.code==200){
  364. for(let i=0;i<res.data.rows.length;i++){
  365. if(res.data.rows[i].type == 1 || res.data.rows[i].type == 2) {
  366. resolve(i)
  367. break;
  368. }
  369. }
  370. }
  371. });
  372. })
  373. },
  374. getMenuList(item) {
  375. let self = this
  376. this.$api.menuList({courseId:item.courseId}).then(res => {
  377. if(res.data.code==200){
  378. for(let i=0;i<res.data.rows.length;i++){
  379. let item = res.data.rows[i]
  380. item.down = true
  381. item.id = item.menuId
  382. item.name = item.menuName
  383. if(item.type==3){
  384. //判断是否试听
  385. item.tryListen = false
  386. if(self.goodsAuditionConfigIdList.indexOf(item.id)!==-1){
  387. item.tryListen = true
  388. }
  389. }
  390. }
  391. item.menuList = res.data.rows
  392. }
  393. });
  394. },
  395. // 获取课程详情
  396. getDetail() {
  397. let self = this
  398. let sectionIdList = []
  399. // /app/common/goods/+data
  400. this.$api.commonGoodsDetail(this.id).then(res => {
  401. if(res.data.code==200){
  402. if(res.data.data.mobileDetailHtml){
  403. res.data.data.mobileDetailHtml = res.data.data.mobileDetailHtml.replace(/<img/gi,'<img style="max-width:100%;"')
  404. }
  405. self.detail = res.data.data
  406. this.courseBusiness();
  407. if(self.detail.goodsAuditionConfig){
  408. self.listenConfigList = JSON.parse(self.detail.goodsAuditionConfig)
  409. for (var itemChild of self.listenConfigList) {
  410. sectionIdList.push(itemChild.sectionId)//存储试听节ID
  411. }
  412. self.$store.commit('setGoodsAuditionConfigIdList', {goodsAuditionConfigIdList:sectionIdList});
  413. }
  414. }
  415. });
  416. },
  417. buy(){
  418. if(this.$method.isGoLogin()){
  419. return
  420. }
  421. this.$navTo.togo('/pages2/order/confirm_list?id='+this.id);
  422. },
  423. addCart(){
  424. if(this.$method.isGoLogin()){
  425. return
  426. }
  427. this.addShopCart()
  428. },
  429. open(item){
  430. item.showChildren = !item.showChildren
  431. },
  432. change(index){
  433. this.current = index;
  434. },
  435. toShopcar() {
  436. uni.switchTab({
  437. url: '/pages/shopping/shoppingCart'
  438. })
  439. },
  440. getIsBuy() {
  441. this.$http({
  442. url: '/order/buyGoodsNotExpired',
  443. method: 'get',
  444. data: { goodsId: this.id }
  445. }).then((res) => {
  446. if (res.data.code == 200) {
  447. if (res.data.data) { // 有data返回是已经购买过的课程
  448. this.hadBuyCourse = res.data.data
  449. this.bugCourseModel = true
  450. }
  451. }
  452. })
  453. },
  454. changeKown() {
  455. this.bugCourseModel = false
  456. },
  457. async toStudy() {
  458. let item = this.hadBuyCourse
  459. if (item.goodsType == 6) { // 进入直播课
  460. this.toLive(item)
  461. return
  462. }
  463. // /course/goodsRebuildStatus查询用户商品重修状态
  464. let rebuildStatus = await this.courseGoodsRebuildStatus(item.goodsId, item.gradeId)
  465. if (rebuildStatus == 0) {
  466. this.$navTo.togo('/pages2/learn/details', {
  467. gradeId: item.gradeId,
  468. goodsId: item.goodsId,
  469. orderGoodsId: item.orderGoodsId,
  470. });
  471. return;
  472. }
  473. // /lock/lockStatus
  474. this.$api.lockLockStatus({
  475. action: 'jxjy',
  476. uuid:this.$method.getUuid()
  477. }).then(res => {
  478. if (res.data.code == 200) { //有其他端在操作,不能学习
  479. uni.showToast({
  480. icon: 'none',
  481. title: res.data.msg,
  482. mask: true,
  483. duration: 3000
  484. })
  485. } else if (res.data.code == 500) { //可以学习
  486. this.$http({
  487. url: '/course/courseList',
  488. method: 'get',
  489. data: {
  490. pageNum: 1,
  491. pageSize: 1,
  492. goodsId: item.goodsId,
  493. gradeId: item.gradeId,
  494. orderGoodsId: item.orderGoodsId,
  495. },
  496. })
  497. .then(res => {
  498. if (res.data.code == 200) {
  499. if(res.data.total > 1) {
  500. // this.$navTo.togo(`/pages2/wd/course?id=${item.goodsId}&gid=${item.gradeId}&orderGoodsId=${item.orderGoodsId}`);
  501. uni.navigateTo({
  502. url: `/pages3/polyv/detail?id=''&goodsId=${item.goodsId}&orderGoodsId=${item.orderGoodsId}&gradeId=${item.gradeId}`
  503. })
  504. } else if(res.data.total == 1) {
  505. uni.navigateTo({
  506. url: `/pages3/polyv/detail?id=${res.data.rows[0].courseId}&goodsId=${item.goodsId}&orderGoodsId=${item.orderGoodsId}&gradeId=${item.gradeId}`
  507. })
  508. } else {
  509. uni.showToast({
  510. icon:'none',
  511. title:'暂无可观看的视频课程'
  512. })
  513. }
  514. }
  515. })
  516. }
  517. })
  518. },
  519. toLive(item) {
  520. this.$api.courseCourseList({
  521. pageNum: 1,
  522. pageSize: 1,
  523. goodsId: item.goodsId,
  524. gradeId: 0,
  525. orderGoodsId: item.orderGoodsId,
  526. }).then(res => {
  527. if (res.data.code == 200) {
  528. if(res.data.total > 1) {
  529. // uni.navigateTo({
  530. // url:'/pages5/liveDetail/course?orderGoodsId='+item.orderGoodsId+'&goodsId='+item.goodsId+'&gradeId=0'
  531. // })
  532. uni.navigateTo({
  533. url:'/pages3/live/detail?orderGoodsId='+item.orderGoodsId+'&goodsId='+item.goodsId+'&gradeId=0&courseId=""'
  534. })
  535. } else if(res.data.total == 1) {
  536. uni.navigateTo({
  537. url:'/pages3/live/detail?orderGoodsId='+item.orderGoodsId+'&goodsId='+item.goodsId+'&gradeId=0&courseId='+ res.data.rows[0].courseId
  538. })
  539. } else {
  540. uni.showToast({
  541. icon:'none',
  542. title:'暂无可观看的直播课程'
  543. })
  544. }
  545. }
  546. })
  547. },
  548. /**
  549. * @param {Object} goodsId 商品id
  550. * 查询商品重修状态
  551. */
  552. courseGoodsRebuildStatus(goodsId, gradeId) {
  553. return new Promise(resolve => {
  554. this.$http({
  555. url: '/course/goodsRebuildStatus',
  556. method: 'get',
  557. data: {
  558. goodsId: goodsId,
  559. gradeId: gradeId
  560. },
  561. // noLoading: true,
  562. // compleLoading: true, // 请求成功是否还要继续显示加载中
  563. })
  564. .then(res => {
  565. resolve(res.data.data)
  566. })
  567. })
  568. },
  569. }
  570. };
  571. </script>
  572. <style >
  573. page{
  574. background-color: #F2F2F2;
  575. }
  576. </style>
  577. <style lang="scss" scope>
  578. @import './index.scss';
  579. .video_t2 {
  580. font-size: 24rpx;
  581. font-family: PingFang SC;
  582. font-weight: 500;
  583. color: #666666;
  584. }
  585. .video_t1 {
  586. height: 80rpx;
  587. color: #333333;
  588. line-height: 80rpx;
  589. font-size: 30rpx;
  590. font-family: PingFang SC;
  591. font-weight: bold;
  592. color: #333333;
  593. overflow: hidden;
  594. text-overflow:ellipsis;
  595. white-space: nowrap;
  596. }
  597. .video_t1_t {
  598. display: flex;
  599. flex-direction: column;
  600. height: 80rpx;
  601. color: #333333;
  602. text-align: center;
  603. align-items: center;
  604. border-left: solid 1px #d6d6db;
  605. }
  606. .video_play {
  607. position: absolute;
  608. width: 95rpx;
  609. height: 95rpx;
  610. top: 0;
  611. left: 0;
  612. right: 0;
  613. bottom: 0;
  614. margin: auto;
  615. }
  616. .video_box {
  617. position: relative;
  618. }
  619. .contents {
  620. width: 100%;
  621. height: 100%;
  622. background-color: #ffffff;
  623. margin-top: 16rpx;
  624. overflow: hidden;
  625. }
  626. .cou_title {
  627. padding: 24rpx 32rpx 40rpx 32rpx;
  628. display: flex;
  629. flex-direction: column;
  630. justify-content: space-around;
  631. }
  632. .prices {
  633. .price_word {
  634. font-size: 40rpx;
  635. font-weight: 800;
  636. color: #FC3F3F;
  637. }
  638. .sale {
  639. color: #999999;
  640. font-size: 28rpx;
  641. margin-left: 8rpx;
  642. }
  643. .price_line {
  644. color: #999999;
  645. font-size: 28rpx;
  646. text-decoration:line-through;
  647. font-weight: 400;
  648. }
  649. .free {
  650. font-size: 32rpx;
  651. }
  652. }
  653. // tab
  654. .tabs {
  655. // width: 100%;
  656. height: 78rpx;
  657. display: flex;
  658. align-items: center;
  659. justify-content: space-between;
  660. background-color: #F2F7FF;
  661. border-radius: 38rpx;
  662. margin: 24rpx;
  663. padding: 0rpx 5rpx;
  664. .tab_item {
  665. width: 345rpx;
  666. height: 65rpx;
  667. line-height: 65rpx;
  668. font-size: 28rpx;
  669. font-weight: bold;
  670. border-radius: 32rpx;
  671. text-align: center;
  672. color: #333;
  673. &.nactive {
  674. color: #fff;
  675. background-color: #3577E8;
  676. }
  677. &.twoBtn {
  678. width: 50%;
  679. }
  680. &.threeBtn {
  681. width: 33%;
  682. }
  683. }
  684. // /deep/ .u-tabs {
  685. // background:none!important;
  686. // }
  687. }
  688. .courseName{
  689. white-space:nowrap;
  690. overflow:hidden;
  691. text-overflow:ellipsis;
  692. }
  693. .videoBox{
  694. background-color: #FFFFFF;
  695. width: 100%;
  696. /* height: 680rpx; */
  697. z-index: 999;
  698. }
  699. .icon_up{
  700. width: 32rpx;
  701. height: 32rpx;
  702. }
  703. .courseItemBox{
  704. background: #FFFFFF;
  705. border-radius: 16rpx;
  706. padding: 0 10rpx;
  707. margin-bottom: 20rpx;
  708. }
  709. .courseItem{
  710. height: 80rpx;
  711. color: #333333;
  712. font-size: 32rpx;
  713. line-height: 80rpx;
  714. font-weight: bold;
  715. display: flex;
  716. justify-content: space-between;
  717. }
  718. .content{
  719. background-color: #FFFFFF;
  720. width: 100%;
  721. }
  722. .btn2 {
  723. width: 187rpx;
  724. height: 79rpx;
  725. line-height: 79rpx;
  726. background: #FC3F3F;
  727. border-radius: 40rpx;
  728. text-align: center;
  729. font-size: 24rpx;
  730. }
  731. .btn1 {
  732. width: 187rpx;
  733. height: 79rpx;
  734. line-height: 79rpx;
  735. background: #FFB102;
  736. border-radius: 40rpx;
  737. text-align: center;
  738. margin-right: 11rpx;
  739. font-size: 24rpx;
  740. }
  741. .blackFont{
  742. margin: 0 4rpx;
  743. }
  744. .wk_icon{
  745. width: 24rpx;
  746. height: 24rpx;
  747. margin-right: 12rpx;
  748. }
  749. .noteTag, .blackFont {
  750. font-size: 30rpx;
  751. font-family: PingFang SC;
  752. font-weight: 400;
  753. color: #A7B0B8;
  754. align-items: center;
  755. }
  756. .priceTag{
  757. /* font-size: 30rpx;
  758. font-family: PingFang SC;
  759. font-weight: bold;
  760. color: #FF2D55; */
  761. width: 60rpx;
  762. height: 40rpx;
  763. line-height: 40rpx;
  764. text-align: center;
  765. border: 1rpx solid #333;
  766. }
  767. .titleTag{
  768. font-size: 32rpx;
  769. font-weight: bold;
  770. color: #333333;
  771. // margin-left: 8rpx;
  772. }
  773. .yearTag{
  774. width: 80rpx;
  775. height: 32rpx;
  776. background: #EBF5FF;
  777. border: 2rpx solid #007AFF;
  778. border-radius: 16rpx;
  779. font-size: 24rpx;
  780. color: #007AFF;
  781. text-align: center;
  782. line-height: 32rpx;
  783. }
  784. .itemBox{
  785. background: #FFFFFF;
  786. box-shadow: 0rpx 10rpx 9rpx 1rpx rgba(165, 196, 239, 0.1);
  787. border-radius: 24rpx;
  788. width: 100%;
  789. padding: 20rpx;
  790. margin-bottom: 20rpx;
  791. }
  792. </style>