You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

704 lines
18 KiB

<template>
<view class="course-detail-index">
<view v-if="$store.getters.token || userInfo.uid" class="content">
<view class="swiper-box">
<swiper :indicator-dots="true" :autoplay="true" :interval="3000" :duration="1000">
<swiper-item v-for="(item,index) in detail.imageArr" :key="index">
<view class="swiper-item"><image :src="item" mode=""></image></view>
</swiper-item>
</swiper>
</view>
<view class="course-info-box">
<view class="course-title">{{detail.courseName}}</view>
<view class="tips-box">
<view class="tip-item blue">{{detail.categoryName}}</view>
<!-- <view class="tip-item orange">国学院</view> -->
</view>
</view>
<view class="tab-box acea-row row-around" :class="isFixedTop?'fixed':''">
<view class="tab-item" :class="active == '0' ? 'tab-item-active' : ''" @click="handelScroll('content1','0')">简介</view>
<view class="tab-item" :class="active == '1' ? 'tab-item-active' : ''" @click="handelScroll('content2','1')">课程安排</view>
<view class="tab-item" :class="active == '2' ? 'tab-item-active' : ''" @click="handelScroll('content3','2')">相关推荐</view>
</view>
<view class="content-box" bindscroll="scroll">
<scroll-view scroll-y="true" scroll-with-animation="true" style="height:100%;" :scroll-into-view="toView" >
<view class="teacher-info-box content" id="content1">
<view class="title-box acea-row row-middle">
<view class="left-line"></view>
<span>主讲人介绍</span>
</view>
<scroll-view class="scroll-view_H" scroll-x="true">
<view class="info-box" v-for="(item,index) in detail.masterDtos" :key="index">
<image :src="item.photoPath"></image>
<view class="name">{{item.name}}</view>
<view class="tip">禪易能量高级讲师</view>
<view class="desc">{{item.introduction}}</view>
</view>
</scroll-view>
</view>
<view class="course-desc-box">
<view class="title-box acea-row row-middle">
<view class="left-line"></view>
<span>课程简介</span>
</view>
<text class="desc">{{item.courseIntroduce}}</text>
</view>
<view class="course-desc-box content" id="content2">
<view class="title-box acea-row row-middle">
<view class="left-line"></view>
<span>课程表</span>
</view>
<view class="course-card-list">
<view class="course-card-item acea-row row-middle">
<image src="../../static/course-icon1.png"></image>
<view class="label">课程时间</view>
<view class="info">{{detail.courseStartTime}}</view>
</view>
<view class="course-card-item acea-row row-middle">
<image src="../../static/course-icon2.png"></image>
<view class="label">课程地点</view>
<view class="info">{{detail.coursePlace}}</view>
</view>
<view class="course-card-item acea-row row-middle">
<image src="../../static/course-icon3.png"></image>
<view class="label">签到时间</view>
<view class="info">{{detail.enterStartTime}}</view>
</view>
<view class="course-card-item acea-row row-middle">
<image src="../../static/course-icon4.png"></image>
<view class="label">报名截止</view>
<view class="info">{{detail.signEndTime}}</view>
</view>
</view>
</view>
<view class="course-desc-box" >
<view class="title-box acea-row row-middle">
<view class="left-line"></view>
<span>课程安排</span>
</view>
<view class="plan-box acea-row-nowrap" v-for="(item,index) in detail.courseScheduleList" :key="index">
<text class="plan-time">{{item.courseDate.split(' ')[0]}}</text>
<text>{{item.courseContent}}</text>
</view>
</view>
<view class="recommend-box content" id="content3">
<view class="title-box acea-row row-middle row-center">
<view class="row-line"></view>
<view class="title">相关推荐</view>
<view class="row-line"></view>
</view>
<view class="knowledge-list">
<view class="knowledge-item acea-row" v-for="(item,index) in detail.similarCourseList" :key="index" @click="toDetail(item.id)">
<view class="img-box">
<image src="../../static/img1.png" mode=""></image>
</view>
<view class="knowledge-info-box">
<view class="title line1">{{item.courseName}}</view>
<view class="time">{{setDate(item.courseStartTime)}}-{{setDate(item.courseEndTime)}}</view>
<view class="address">{{item.coursePlace}}</view>
<view class="type-box acea-row row-between row-middle">
<view class="price">¥{{item.courseCharge}}</view>
<view class="signin-btn red">去报名</view>
</view>
</view>
</view>
</view>
</view>
</scroll-view>
</view>
<view class="footer-box acea-row row-between-wrapper">
<view class="footer-left">
<view class="price"><span class="fz24">¥</span>{{detail.courseCharge}}</view>
</view>
<view class="footer-right">
<view class="btn-box acea-row row-between-wrapper" v-if="detail.haveSeller && !detail.enterState">
<view class="count-down">
<view>距离截止时间还剩</view>
<uni-countdown color="#EB5744" :day="day" :hour="hour" :minute="minute" :second="second" />
</view>
<view class="signin-btn" @click="signInClick">立即报名</view>
</view>
<view class="signin-btn call-btn" v-if="detail.enterState" >已报名</view>
<view class="signin-btn call-btn" @click="signInClick" v-if="userInfo.phone && !detail.haveSeller">联系服务老师</view>
<!-- #ifdef MP-WEIXIN -->
<button open-type="getPhoneNumber" @getphonenumber="getPhoneNumber" v-if="userInfo.phone == '' && detail.haveSeller == 0" class="binding signin-btn call-btn" v-else>
<text>联系服务老师2</text>
</button>
<!-- #endif -->
<!-- #ifndef MP-WEIXIN -->
<button class="binding" @click="goBindPhone()" v-if="userInfo.phone == '' && detail.haveSeller == 0">
<text>联系服务老师</text>
</button>
<!-- #endif -->
</view>
</view>
<view class="mask-box" v-if="maskDialog">
<view class="dialog-box">
<view class="close" @click="closeDialog()">×</view>
<view class="dialog-top acea-row-nowrap row-center-wrapper">
<image src="../../static/error-icon.png"></image>
<view class="word">{{teacher.msg}}</view>
</view>
<view class="dialog-btm">
<view class="l-box acea-row row-between-wrapper">
<view class="acea-row row-middle">
<image :src="teacher.imgPath"></image>
<view>
<view>{{teacher.name}}</view>
<view>{{teacher.phone}}</view>
</view>
</view>
<view class="call-btn" @click="call">拨打电话</view>
</view>
</view>
</view>
</view>
</view>
<Authorization v-else />
</view>
</template>
<script>
// import WucTab from '@/components/wuc-tab/wuc-tab.vue';
import { mapState, mapGetters, mapMutations, mapActions } from 'vuex'
import { getCourseDetail ,enterCourse } from '@/api/knowledge';
import Authorization from '@/pages/authorization/index'
export default {
components: {
Authorization,
},
data() {
return {
id: '',
detail:{courseScheduleList:[]},
active: '0',
toView: '',
heightArr:[],
tabInitTop:'',
isFixedTop: false,
maskDialog:false,
day:'',
hour:'',
minute:'',
second:'',
teacher:{}
}
},
computed: mapGetters(['userInfo']),
onLoad() {
console.log(this.userInfo,'11')
//获取节点距离顶部的距离
uni.createSelectorQuery().select('.tab-box').boundingClientRect((res) => {
if (res && res.top > 0) {
var tabInitTop= res.top;
this.tabInitTop= tabInitTop
}
}).exec();
this.courseId = this.$yroute.query.id;
this.getDetail()
},
mounted() {
this.getHeightArr()
},
methods: {
getPhoneNumber: function(e) {
let thit = this
console.log(e)
// 判断一下这里是不是小程序 如果是小程序,走获取微信手机号进行绑定
if (e.mp.detail.errMsg == 'getPhoneNumber:ok') {
uni.showLoading({
title: '绑定中',
})
wxappBindingPhone({
encryptedData: e.mp.detail.encryptedData,
iv: e.mp.detail.iv,
})
.then(res => {
// this.User();
thit.$store.dispatch('userInfo', true)
uni.hideLoading()
uni.showToast({
title: res.msg,
icon: 'success',
duration: 2000,
})
})
.catch(error => {
uni.hideLoading()
thit.$store.dispatch('userInfo', true)
uni.showToast({
title: error.msg || error.response.data.msg || error.response.data.message,
icon: 'none',
duration: 2000,
})
})
} else {
uni.showToast({
title: '已拒绝授权',
icon: 'none',
duration: 2000,
})
}
},
setDate(t){
let str = t.split(" ")[0].split("-")[1] + "." + t.split(" ")[0].split("-")[2]
return str
},
toDetail(id){
this.$yrouter.push({
path: '/pages/course/detail',
query: {
id:id,
},
})
},
getDetail(){
let nowTime = Date.parse(new Date())/1000;
getCourseDetail({"id":this.courseId,"uid":this.userInfo.uid}).then((res)=>{
this.detail = res.data
let endTime = Date.parse(new Date(res.data.signEndTime))/1000
this.times = endTime - nowTime;
this.day = Math.floor(this.times / (60 * 60 * 24));
this.hour = Math.floor(this.times / (60 * 60)) - (this.day * 24);
this.minute = Math.floor(this.times / 60) - (this.day * 24 * 60) - (this.hour * 60);
this.second = Math.floor(this.times) - (this.day * 24 * 60 * 60) - (this.hour * 60 * 60) - (this.minute * 60);
})
},
signInClick(){
enterCourse({courseId:this.courseId}).then((res)=>{
if(res.data.state == 0){
this.maskDialog = true
this.teacher = res.data
} else if(res.data.state == 1){
uni.showToast({
title: res.data.msg,
duration: 2000,
type: "success"
});
this.getDetail()
}
})
},
call(){
uni.makePhoneCall({
phoneNumber: this.teacher.phone
});
},
closeDialog(){
this.maskDialog = false
},
handelScroll(id,idx){
uni.createSelectorQuery().select('#'+id).boundingClientRect(function(res){
uni.pageScrollTo({
scrollTop:res.top,
duration: 300
});
}).exec()
this.active = idx;
this.toView = id
},
getHeightArr(){
let h=0;
let heightArr = [];
//selectAll会选择所要含有该类名的盒子
uni.createSelectorQuery().selectAll('.content').boundingClientRect((rect) => {
}).exec((res) => {
// console.log(res)
res[0].forEach((item)=>{
h+=item.height;
heightArr.push(h);
})
this.heightArr = heightArr;
})
},
onPageScroll(res) {
let scrollTop = res.scrollTop;
let scrollArr = this.heightArr;
for  (let  i = 0; i < scrollArr.length; i++) {
if  (scrollTop >= 0  && scrollTop < scrollArr[0]) {
this.active = 0;
} else if (scrollTop >= (scrollArr[i - 1]) && scrollTop < scrollArr[i]) {
this.active= i;
}
}
var isSatisfy = scrollTop >= this.tabInitTop? true : false;
//只有处于吸顶的临界值才会不相等
if (this.isFixedTop === isSatisfy) {
return false;
}
this.isFixedTop = isSatisfy
},
onHide() {
clearInterval(this.timer);
},
}
}
</script>
<style scoped lang="less">
.course-detail-index{
width: 100%;
box-sizing: border-box;
.mask-box{
width: 100%;
height: 100%;
background: rgba(0,0,0,.6);
position: fixed;
top: 0;
.dialog-box{
width: 600rpx;
border-radius: 12rpx;
overflow: hidden;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%,-50%);
.close{
width: 38rpx;
height: 38rpx;
position: absolute;
right: 12rpx;
top: 12rpx;
font-size: 36rpx;
}
.dialog-top{
width: 100%;
height: 212rpx;
box-sizing: border-box;
padding: 30rpx 38rpx 0;
background: linear-gradient(180deg, #FFE8E8 0%, #FFFFF8 100%);
image{
width: 154rpx;
height: 162rpx;
margin-right: 12rpx;
}
.word{
width: calc(100% - 164rpx);
height: 108rpx;
font-size: 28rpx;
color: #666;
}
}
.dialog-btm{
background-color: #fff;
padding: 30rpx 32rpx;
color: #666;
font-size: 28rpx;
image{
width: 100rpx;
height: 100rpx;
border-radius: 25px;
margin-right: 20rpx;
}
.call-btn{
width: 192rpx;
height: 60rpx;
background: #ECEFFD;
border-radius: 12rpx;
text-align: center;
line-height: 60rpx;
color: #6E85EB;
}
}
}
}
.swiper-box{
width: 100%;
height: 340rpx;
swiper{
height: 100%;
.swiper-item{
width: 100%;
height: 100%;
image{
width: 100%;
height: 100%;
}
}
}
}
.course-info-box{
box-sizing: border-box;
padding: 30rpx 30rpx 50rpx;
background: #fff;
.course-title{
font-size: 40rpx;
font-weight: 500;
color: #333333;
line-height: 56rpx;
margin: 0rpx 0 20rpx;
}
.tips-box{
display: flex;
.tip-item{
min-width: 60rpx;
height: 34rpx;
text-align: center;
line-height: 34rpx;
font-size: 24rpx;
margin-left: 20rpx;
padding: 0 5rpx;
}
.blue{
color: #6E85EB;
border: 1px solid #6E85EB;
background: #EDEFF8;
}
.orange{
color: #EF644E;
border: 1px solid #EF644E;
background: #FFF4F2;
}
}
}
.tab-box{
white-space: nowrap;
width: 100%;
background: #fff;
padding: 18rpx 34rpx 0;
.tab-item{
width: 33%;
text-align: center;
display: inline-block;
padding-bottom: 18rpx;
font-size: 32rpx;
color: #222;
}
.tab-item-active{
font-size: 40rpx;
font-weight: bold;
border-bottom: 4rpx solid #EB5744;
}
}
.fixed{
position: -webkit-sticky;
position: sticky;
top: 0;
z-index: 99;
}
.content-box{
width: 100%;
box-sizing: border-box;
background: #F5F6F7;
padding: 24rpx 22rpx;
.teacher-info-box,.course-desc-box{
width: 100%;
background:#fff;
border-radius: 8rpx;
padding: 18rpx 24rpx 30rpx;
margin-bottom: 20rpx;
}
.desc{
text-indent: 2em;
font-size: 28rpx;
color: #666666;
line-height: 24px;
}
.scroll-view_H{
white-space: nowrap;
width: 100%;
}
.info-box{
width: 100%;
display: inline-block;
text-align: center;
image{
width: 100rpx;
height: 100rpx;
border-radius: 25px;
}
.name{
width: 100%;
font-size: 32rpx;
color: #3C464F;
line-height: 44rpx;
}
.tip{
width: 100%;
font-size: 24rpx;
color: #999999;
line-height: 34px;
}
.desc{
width: 100%;
white-space: pre-wrap;
}
}
.title-box{
font-size: 36rpx;
font-weight: bold;
color: #3C464F;
line-height: 50rpx;
margin-bottom: 20rpx;
.left-line{
width: 6rpx;
height: 32rpx;
background-color: #EB5744;
margin-right: 16rpx;
}
}
.plan-box{
font-size: 28rpx;
color: #666;
line-height: 32rpx;
margin-bottom: 12rpx;
.plan-time{
width: 170rpx;
margin-right: 22rpx;
}
}
.course-card-item{
font-size: 32rpx;
image{
width: 30rpx;
height: 30rpx;
}
.label{
color: #999999;
line-height: 34rpx;
margin: 0 32rpx 0 18rpx;
}
.info{
color: #666666;
line-height: 34px;
}
}
.recommend-box{
.title-box{
font-size: 32rpx;
color: #EB5744;
.title{
margin: 0 10rpx;
}
.row-line{
width: 36rpx;
height: 2rpx;
border: 2rpx solid #EB5744;
}
}
.knowledge-list {
width: 100%;
.knowledge-item {
background: #fff;
padding: 32rpx;
.img-box {
width: 204rpx;
height: 200rpx;
margin-right: 30rpx;
image {
width: 100%;
height: 100%;
}
}
.knowledge-info-box {
width: calc(100% - 234rpx);
.title {
font-size: 28rpx;
color: #333;
font-size: 500;
line-height: 40rpx;
}
.time,.address{
color: #999;
font-size: 24rpx;
margin-top: 5rpx;
line-height: 34rpx;
}
.intro {
font-size: 28rpx;
color: #999999;
line-height: 40rpx;
margin: 8rpx 0 36rpx;
}
.type-box {
font-size: 24rpx;
color: #999;
margin-top: 28rpx;
.price{
font-size: 36rpx;
color: #EA533E;
font-weight: 600;
}
.signin-btn{
width: 156rpx;
height: 60rpx;
text-align: center;
line-height: 60rpx;
background: #FFEAE7;
border-radius: 12rpx;
font-size: 32rpx;
}
.red{
background: #FFEAE7;
color: #EE7060;
}
.blue {
color: #6E85EB;
background: #ECEFFD;
}
.yellow {
color: #F99C10;
background: #FFEDCC;
}
}
}
}
}
}
}
.footer-box{
width: 100%;
padding: 24rpx 26rpx 66rpx 44rpx;
background: #fff;
.price{
font-size: 44rpx;
color: #EA533E;
}
.fz24{
font-size: 24rpx;
}
.footer-right{
.btn-box{
text-align: center;
width: 410rpx;
height: 80rpx;
border-radius: 44px;
border: 2rpx solid #EB5744;
box-sizing: border-box;
overflow: hidden;
.count-down{
width: calc(100% - 178rpx);
text-align: center;
font-size: 24rpx;
color: #999;
}
.colR{
color: #EB5744;
}
.signin-btn{
width: 178rpx;
height: 100%;
line-height: 84rpx;
font-size: 32rpx;
color: #fff;
background: #EB5744;
}
}
.call-btn{
width: 268rpx;
height: 80rpx;
background: #F99C10;
border-radius: 44rpx;
text-align: center;
line-height: 80rpx;
color: #fff;
font-size: 30rpx;
}
}
}
}
</style>