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.
 
 
 
 
 

451 lines
12 KiB

<template>
<view class="course-detail-index">
<view class="banner-box">
<image :src="detail.imgPath" mode="aspectFill"></image>
</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="course-desc-box content" id="content1">
<view class="title-box acea-row row-middle">
<view class="left-line"></view>
<span>榜单介绍</span>
</view>
<!-- <text class="desc">{{detail.content}}</text> -->
<rich-text class="desc" :nodes="detail.content"></rich-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">
<view class="label">打榜时间</view>
<view class="info">{{detail.listStartTime}} {{detail.listEndTime}}</view>
</view>
<view class="course-card-item acea-row row-middle">
<view class="label">报名时间</view>
<view class="info">{{detail.enterEndTime}}</view>
</view>
<view class="course-card-item acea-row row-middle">
<view class="label">打卡次数</view>
<view class="info">{{detail.clockTimes}}</view>
</view>
<view class="course-card-item acea-row row-middle">
<view class="label">打卡时间</view>
<view class="info">{{detail.signStartTime}}{{detail.signEndTime}}</view>
</view>
</view>
</view>
<view class="course-desc-box content" id="content3">
<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-nowrap row-middle">
<view class="label">积分奖惩</view>
<view class="info">{{detail.integral}}积分</view>
</view>
<view class="course-card-item acea-row-nowrap row-middle row-top">
<view class="label">积分用途</view>
<view class="info">可用于限定课程及商品活动参与名额的兑换</view>
</view>
<view class="course-card-item acea-row-nowrap row-middle row-top">
<view class="label">奖惩机制</view>
<view class="info">积极打卡满{{detail.clockTimes}}天可获得全部积分消极应对无积分奖励</view>
</view>
</view>
</view>
</scroll-view>
</view>
<view class="signin-btn-box">
<view class="signin-btn" @click="submitSignin" v-if="userInfo.phone != ''">{{detail.enterState ? '查看打榜记录' : '立即报名'}}</view>
<!-- #ifdef MP-WEIXIN -->
<button
open-type="getPhoneNumber"
@getphonenumber="getPhoneNumber"
v-if="userInfo.phone == ''"
class="signin-btn" v-else>
<text>点击绑定手机号</text>
</button>
<!-- #endif -->
<!-- #ifndef MP-WEIXIN -->
<button class="signin-btn" @click="goBindPhone()" v-if="userInfo.phone == ''">
<text>联系服务老师</text>
</button>
<!-- #endif -->
</view>
</view>
</template>
<script>
import { getStudyDetail , enterStudyList } from '@/api/knowledge';
import { mapState, mapGetters, mapMutations, mapActions } from 'vuex'
import { getUserInfo, bindingPhone, wxappBindingPhone } from '@/api/user'
export default {
computed: mapGetters(['userInfo']),
data() {
return {
studyId:'',
active: '0',
toView: '',
heightArr:[],
tabInitTop:'',
isFixedTop: false,
dialog:false,
detail:{}
}
},
onLoad() {
//获取节点距离顶部的距离
uni.createSelectorQuery().select('.tab-box').boundingClientRect((res) => {
if (res && res.top > 0) {
var tabInitTop= res.top;
this.tabInitTop= tabInitTop
}
}).exec();
this.studyId = this.$yroute.query.id;
this.getDetail()
},
mounted() {
this.getHeightArr()
},
methods: {
getPhoneNumber: function(e) {
let thit = this
// 判断一下这里是不是小程序 如果是小程序,走获取微信手机号进行绑定
if (e.mp.detail.errMsg == 'getPhoneNumber:ok') {
uni.showLoading({
title: '绑定中',
})
wxappBindingPhone({
encryptedData: e.mp.detail.encryptedData,
iv: e.mp.detail.iv,
})
.then(res => {
if(res.success){
thit.$store.dispatch('userInfo', true)
uni.hideLoading()
uni.showToast({
title: res.msg,
icon: 'success',
duration: 2000,
})
this.getDetail()
} else{
uni.hideLoading()
uni.showModal({
title:'提示!',
content:'授权已过期,请重新授权后绑定手机号',
success:function(res){
if(res.confirm){
thit.$store.commit('logout')
}
},
})
}
})
.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,
})
}
},
getDetail(){
getStudyDetail(this.studyId).then((res)=>{
this.detail = res.data
res.data.content = res.data.content.replace(/\<img/g, "<img style='width: 100%;'")
})
},
signInClick(){
this.dialog = true
},
submitSignin(){
if(this.userInfo.realName == null){
uni.showModal({
title: '提示!',
content: '请完善个人信息后报名!',
success(res) {
if (res.confirm) {
uni.navigateTo({
url:'/pages/user/PersonalData/index'
})
}
}
});
} else{
if(this.detail.enterState){
this.$yrouter.push({
path:'/pages/study/dabang',
query: {
id:this.studyId,
},
})
} else{
enterStudyList({listId:this.studyId}).then((res)=>{
if(res.status == 200){
uni.showToast({
title:'报名成功!',
icon:'success',
duration:1500
})
setTimeout(()=>{
this.$yrouter.push({
path:'/pages/study/dabang',
query: {
id:this.studyId,
},
})
},1500)
} else{
uni.showToast({
title:res.msg,
icon:'none',
duration:2000
})
}
})
}
}
},
handelScroll(id,idx){
uni.createSelectorQuery().select('#'+id).boundingClientRect(data=>{//目标位置的节点:类或者id
uni.createSelectorQuery().select(".course-detail-index").boundingClientRect(res=>{//最外层盒子的节点:类或者id
uni.pageScrollTo({
duration: 500,//过渡时间
scrollTop:data.top - res.top - 50 ,//返回顶部的top值
})
}).exec()
}).exec();
this.active = idx;
this.toView = id
},
getHeightArr(){
let h=0;
let heightArr = [];
//selectAll会选择所要含有该类名的盒子
uni.createSelectorQuery().selectAll('.content').boundingClientRect((rect) => {
}).exec((res) => {
res[0].forEach((item)=>{
h+=item.top;
heightArr.push(h);
})
this.heightArr = heightArr;
console.log(this.heightArr)
})
},
onPageScroll(res) {
this.scrollTop = res.scrollTop
let scrollTop = res.scrollTop;
let scrollArr = this.heightArr;
let timer = setTimeout(()=>{
if(this.scrollTop===scrollTop){
for  (let  i = 0; i < scrollArr.length; i++) {
if  (scrollTop < scrollArr[0]) {
this.active = 0;
} else if (scrollTop >= (scrollArr[i - 1]) && scrollTop < scrollArr[i]) {
this.active= i;
}
}
clearTimeout(timer)
}
},100)
var isSatisfy = scrollTop >= this.tabInitTop? true : false;
//只有处于吸顶的临界值才会不相等
if (this.isFixedTop === isSatisfy) {
return false;
}
this.isFixedTop = isSatisfy
},
}
}
</script>
<style scoped lang="less">
.course-detail-index{
width: 100%;
background: #fff;
padding-bottom: 190rpx;
box-sizing: border-box;
.banner-box{
width: 100%;
height: 286rpx;
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-weight: bold;
border-bottom: 4rpx solid #F99C10;
}
}
.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;
width: 100%;
font-size: 28rpx;
color: #666666;
line-height: 24px;
overflow: hidden;
image{
width: 100%;
}
}
.info-box{
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
image{
width: 100rpx;
height: 100rpx;
border-radius: 25px;
}
.name{
font-size: 32rpx;
color: #3C464F;
line-height: 44rpx;
}
.tip{
font-size: 24rpx;
color: #999999;
line-height: 34px;
}
}
.title-box{
font-size: 36rpx;
font-weight: bold;
color: #3C464F;
line-height: 50rpx;
margin-bottom: 20rpx;
.left-line{
width: 6rpx;
height: 32rpx;
background-color: #F99C10;
margin-right: 16rpx;
}
}
.course-card-item{
font-size: 26rpx;
color: #666666;
margin-bottom: 10rpx;
image{
width: 30rpx;
height: 30rpx;
}
.label{
// width: 160rpx;
// line-height: 34rpx;
}
.info{
width: calc(100% - 160rpx);
line-height: 46rpx;
}
}
}
.signin-btn-box{
width: 100%;
background: #fff;
padding: 30rpx 32rpx 60rpx;
position: fixed;
bottom: 0;
left: 0;
.signin-btn{
height: 88rpx;
background: linear-gradient(180deg, #F7D08E 0%, #E2B35D 100%);
border-radius: 44rpx;
text-align: center;
line-height: 88rpx;
color: #fff;
}
}
}
</style>