416 lines
20 KiB
Vue
416 lines
20 KiB
Vue
<template>
|
||
<view class="waper" :style="'padding-bottom: ' + windowBottom + 'px;'">
|
||
<u-navbar @leftClick="leftClick" :bgColor="scrollTop > 20 ? '#fff' : 'transparent'" :leftIconColor="scrollTop > 20 ? '#303133' : '#fff'">
|
||
<view slot='center' class="navbar_title">{{scrollTop > 20 ? '门票详情' : ''}}</view>
|
||
</u-navbar>
|
||
<view class="banner" v-if="detail">
|
||
<swiper :autoplay="true" :interval="5000" circular :duration="1000">
|
||
<swiper-item v-for="(i, index) in detail.image43 ? detail.image43.split(',') : []" :key="index">
|
||
<image :src="$utils.setImgUrl(i)" mode=""></image>
|
||
</swiper-item>
|
||
</swiper>
|
||
<view style="width: 100%; height: 100%; position: absolute; left: 0; top: 0; z-index: 2;" v-if="detail.image43 && detail.image43.split(',').length == 1"></view>
|
||
<button open-type="share" class="icon">
|
||
<u-icon size="44rpx" color="#fff" name="share-square"></u-icon>
|
||
</button>
|
||
</view>
|
||
<view class="waper_box" v-if="detail">
|
||
<view class="info">
|
||
<view class="title">{{detail.name}}</view>
|
||
<view class="number">
|
||
<view>库存:{{detail.inventory}}</view>
|
||
<view>已售:{{ detail.sales }}</view>
|
||
</view>
|
||
<view class="tel">
|
||
<view>电话:{{configData && configData.phone}}</view>
|
||
<view @click="callTel">
|
||
<image src="https://common/callTel.png" mode=""></image>
|
||
</view>
|
||
</view>
|
||
<view class="list">
|
||
|
||
</view>
|
||
</view>
|
||
<view class="content">
|
||
<view class="list_waper">
|
||
<view class="title">购买须知</view>
|
||
<view class="notic">
|
||
<view>{{detail.refundRule == '5' ? detail.refundRuleName.substr(0, 3) : detail.refundRuleName}}</view>
|
||
<view v-if="detail.refundRule == '0'">{{detail.refundRemark || ''}}</view>
|
||
<view v-if="detail.refundRule == '3'">门票有效期内可退</view>
|
||
<view v-if="detail.refundRule == '4'">订单生成后{{detail.refundDay}}天内可退</view>
|
||
<view v-if="detail.refundRule == '5'">未激活可退</view>
|
||
</view>
|
||
<view class="fee" v-if="detail.refundRule > 0">
|
||
<view>退款手续费</view>
|
||
<view>
|
||
<text v-if="detail.isFee == 0">无需手续费</text>
|
||
<text v-if="detail.isFee == 1 && detail.feeType == '1'">退款需扣除手续费{{(detail.deductionFees) + (detail.deductionFeesUnit == '1' ? '%' : '元')}}</text>
|
||
<text v-if="detail.isFee == 1 && detail.feeType == '2'" v-for="(i, index) in detail.refundRuleList" :key="index">游玩前{{i.day}}天内退票,需扣除手续费{{i.deductionFees}}{{i.deductionFeesUnit == '1' ? '%' : '元'}}</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
<view class="list_waper">
|
||
<view class="title">使用说明</view>
|
||
<view class="list">
|
||
<view>
|
||
<text>有效期</text>
|
||
<text v-if="detail.ticketValidityPeriod == '1'">游玩日期当天有效</text>
|
||
<text v-if="detail.ticketValidityPeriod == '2'">购买后{{detail.buyPeriodDay}}天有效</text>
|
||
<text v-if="detail.ticketValidityPeriod == '3'">{{detail.validityStartTime}}至{{detail.validityEndTime}}有效</text>
|
||
<text v-if="detail.ticketValidityPeriod == '4'">激活后{{detail.buyPeriodDay}}天有效</text>
|
||
</view>
|
||
<view v-if="detail.applicablePeriod && detail.classify == '4' && getDayMsg(detail.applicablePeriod)">
|
||
<text>适用时间段</text>
|
||
<text>{{getDayMsg(detail.applicablePeriod)}}不可用</text>
|
||
</view>
|
||
<view v-if="detail.applicablePeriod && detail.classify != '4'">
|
||
<text>适用时间段</text>
|
||
<text>{{getWeekMsg(detail.applicablePeriod)}}</text>
|
||
</view>
|
||
<view v-if="detail.admissionTime">
|
||
<text>入园时间</text>
|
||
<text>{{detail.admissionTime.split(',').join('-')}}</text>
|
||
</view>
|
||
<view>
|
||
<text>入园地址</text>
|
||
<text>{{detail.admissionAddress || ''}}</text>
|
||
</view>
|
||
<view v-if="detail.isUnavailableHoliday == '1'">
|
||
<text>不可用节日</text>
|
||
<text>{{detail.unavailableHolidayStr}}</text>
|
||
</view>
|
||
<view v-if="detail.isUnavailableTime == '1'">
|
||
<text>不可用时间</text>
|
||
<text>{{detail.unavailableTimeStr}}</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
<view class="list_waper">
|
||
<view class="title">费用说明</view>
|
||
<view class="list" v-if="detail.classify == 1 || detail.classify == 4">
|
||
<view>
|
||
<text>费用包含</text>
|
||
<text>{{detail.name}}-1张</text>
|
||
</view>
|
||
</view>
|
||
<view class="list" v-if="detail.classify == 2">
|
||
<view>
|
||
<text>费用包含</text>
|
||
<text v-for="(i, index) in detail.childList">{{i.childTicketName}}-1张</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
<view class="list_waper" v-if="detail.classify == 4">
|
||
<view class="title">年卡权益</view>
|
||
<view class="years_waper">
|
||
<view class="years_list" v-for="(i, index) in detail.childList">
|
||
<view>{{i.childTicketName}}</view>
|
||
<view>{{i.isUnlimited == '1' ? '不限次数' : ('限' + i.canVerificationNum + '次,每月最多' + i.monthVerificationNum + '次,每日最多' + i.dayVerificationNum + '次')}}</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
<view class="list_waper">
|
||
<view class="title">其他说明</view>
|
||
<view class="list">
|
||
<view>
|
||
<text>限购说明</text>
|
||
<text v-if="detail.isOrderQuantity">每单最多购买{{detail.orderQuantity}}张</text>
|
||
<text v-else>不限购</text>
|
||
</view>
|
||
<view v-if="detail.isOrder == '1'">
|
||
<text>预约说明</text>
|
||
<text>需提前{{detail.beforeDay}}天预约</text>
|
||
</view>
|
||
<view v-if="detail.authenticationType">
|
||
<text>是否实名</text>
|
||
<text>{{detail.authenticationTypeLabel}}</text>
|
||
</view>
|
||
<view v-if="detail.bookingNotice">
|
||
<text>预定须知</text>
|
||
<text>{{detail.bookingNotice}}</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
<!-- :style="'padding-bottom: ' + windowBottom + 'px;'" -->
|
||
<view class="bottom">
|
||
<view class="bottom_waper" v-if="detail">
|
||
<view class="left">
|
||
<view :class="detail.salesRice > 0 ? '' : 'free'">{{detail.salesRice > 0 ? detail.salesRice.toFixed('2') : '免费'}}</view>
|
||
<view>{{detail.salesRice > 0 ? '起' : ''}}</view>
|
||
<view :class="detail.salesRice > 0 ? '' : 'free'" v-if="detail.price && detail.price > 0">¥{{detail.price}}</view>
|
||
</view>
|
||
<view class="right" @click="submitOrder">立即购买</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</template>
|
||
|
||
<script>
|
||
export default {
|
||
data () {
|
||
return {
|
||
windowBottom: 0,
|
||
scrollTop: 0,
|
||
detail: null,
|
||
configData: null
|
||
}
|
||
},
|
||
onShareAppMessage (e) {
|
||
return {
|
||
title: '巴松措风景区',
|
||
path: '/pages/login/index'
|
||
}
|
||
},
|
||
async onLoad (options) {
|
||
let windowInfo = uni.getSystemInfoSync();
|
||
this.windowBottom = this.$safeAreaBottom;
|
||
this.configData = uni.getStorageSync('configData');
|
||
let info = await this.$http.ticketDetail(options.id);
|
||
let unavailableTimeStr = [];
|
||
info.data.unavailableTimeList.forEach((item) => {
|
||
unavailableTimeStr.push(item.beginTime + '至' + item.endTime)
|
||
})
|
||
let unavailableHolidayStr = [];
|
||
info.data.unavailableHolidayList.forEach((item) => {
|
||
unavailableHolidayStr.push(item.holidayName)
|
||
})
|
||
info.data.unavailableTimeStr = unavailableTimeStr.join(';');
|
||
info.data.unavailableHolidayStr = unavailableHolidayStr.join(';');
|
||
this.detail = info.data;
|
||
},
|
||
methods: {
|
||
leftClick () {
|
||
let pages = getCurrentPages();
|
||
let prevPage = pages[pages.length - 2];
|
||
if (prevPage) {
|
||
uni.navigateBack({ delta: 1 })
|
||
prevPage.onLoad(prevPage.options);
|
||
} else uni.reLaunch({ url: '/pages/tabbar/home' })
|
||
},
|
||
callTel () {
|
||
uni.makePhoneCall({ phoneNumber: this.configData.phone }).catch((e) => {});
|
||
},
|
||
async submitOrder () {
|
||
if (this.detail.mpOnlyShow) {
|
||
uni.showToast({ title: '小程序暂不支持购买此年卡', icon: 'none', mask: true })
|
||
return false;
|
||
}
|
||
if (this.detail.inventory <= 0) {
|
||
uni.showToast({ title: '当前门票已售罄', icon: 'none', mask: true })
|
||
return false;
|
||
}
|
||
let user = await this.$http.getUserInfo();
|
||
if (user.data.isBlack == 1) {
|
||
uni.showToast({ title: '您是黑名单用户,禁止购票', icon: 'none', mask: true })
|
||
return false;
|
||
}
|
||
if (!user.data.name || !user.data.mobile || !user.data.idCard) {
|
||
uni.showToast({ title: '请完善个人信息后操作', icon: 'none', mask: true })
|
||
setTimeout(() => {
|
||
uni.navigateTo({ url: '/pages/my/myProfile' })
|
||
}, 1500)
|
||
return false;
|
||
}
|
||
if (this.detail.ticketStatus == 0) {
|
||
uni.navigateTo({ url: '/pages/my/buyTicket?id=' + this.detail.id })
|
||
} else uni.showToast({ mask: true, title: '该门票已失效', icon: 'none' });
|
||
},
|
||
getWeekMsg (str) {
|
||
let time = str.split(',')
|
||
let weekLabel = '';
|
||
if (this.isContinuous(time)) {// 数组连续
|
||
weekLabel = this.getWeek(Number(time[0])) + '至' + this.getWeek(Number(time[time.length - 1]));
|
||
} else {
|
||
let arr = [];
|
||
time.forEach((item) => {
|
||
arr.push(this.getWeek(Number(item)))
|
||
})
|
||
weekLabel = arr.join(',');
|
||
}
|
||
return weekLabel;
|
||
},
|
||
isContinuous (nums) {
|
||
nums.sort((a, b) => a - b);
|
||
for (let i = 1; i < nums.length; i++) {
|
||
if (nums[i] !== nums[i - 1] + 1) {
|
||
return false;
|
||
}
|
||
}
|
||
return true;
|
||
},
|
||
getDayMsg (str) {
|
||
let time = str.split(',');
|
||
let dayLabel = '';
|
||
let arr = [];
|
||
time.forEach((item) => {
|
||
if (item > 0) arr.push(this.getDay(Number(item)))
|
||
})
|
||
dayLabel = arr.join(',');
|
||
return dayLabel;
|
||
},
|
||
getDay (key) {
|
||
let str = '';
|
||
switch (key) {
|
||
case 1:
|
||
str = '周末';
|
||
break;
|
||
case 2:
|
||
str = '元旦';
|
||
break;
|
||
case 3:
|
||
str = '春节';
|
||
break;
|
||
case 4:
|
||
str = '清明';
|
||
break;
|
||
case 5:
|
||
str = '劳动';
|
||
break;
|
||
case 6:
|
||
str = '端午';
|
||
break;
|
||
case 7:
|
||
str = '中秋';
|
||
break;
|
||
case 8:
|
||
str = '国庆';
|
||
break;
|
||
}
|
||
return str;
|
||
},
|
||
getWeek (key) {
|
||
let str = '';
|
||
switch (key) {
|
||
case 1:
|
||
str = '周一';
|
||
break;
|
||
case 2:
|
||
str = '周二';
|
||
break;
|
||
case 3:
|
||
str = '周三';
|
||
break;
|
||
case 4:
|
||
str = '周四';
|
||
break;
|
||
case 5:
|
||
str = '周五';
|
||
break;
|
||
case 6:
|
||
str = '周六';
|
||
break;
|
||
case 7:
|
||
str = '周日';
|
||
break;
|
||
}
|
||
return str;
|
||
}
|
||
},
|
||
onPageScroll (e) {
|
||
this.scrollTop = e.scrollTop;
|
||
}
|
||
}
|
||
</script>
|
||
|
||
<style lang="scss">
|
||
.banner{
|
||
width: 100%; height: 562rpx; position: relative;
|
||
swiper{ width: 100%; height: 100%; }
|
||
.icon{
|
||
width: 80rpx; height: 80rpx; background: rgba(0, 0, 0, 0.5); border-radius: 50%; display: flex; justify-content: center; align-items: center; border: none; padding: 0; position: absolute; bottom: 128rpx; right: 32rpx; z-index: 3;
|
||
&::after{ border: none; }
|
||
}
|
||
}
|
||
.waper_box{
|
||
width: 100%; margin-top: -80rpx; position: relative; z-index: 3; padding-bottom: 174rpx;
|
||
.info{
|
||
width: 100%; background: #fff; border-radius: 32rpx 32rpx 0 0; box-sizing: border-box; padding: 32rpx 32rpx 28rpx;
|
||
.title{ color: #333; line-height: 50rpx; font-size: 36rpx; font-weight: 500; }
|
||
.number{ margin-top: 20rpx; display: flex; justify-content: space-between; align-items: center; height: 40rpx; color: #999; font-size: 28rpx; }
|
||
.tel{
|
||
width: 100%; display: flex; justify-content: space-between; align-items: center; margin-top: 32rpx;
|
||
view{
|
||
&:nth-child(1){ color: #333; font-size: 28rpx; font-weight: 500; }
|
||
&:nth-child(2){ width: 50rpx; height: 50rpx; }
|
||
}
|
||
}
|
||
}
|
||
.content{
|
||
width: 100%; background: #fff; margin-top: 20rpx; box-sizing: border-box; padding: 32rpx 32rpx 0;
|
||
.list_waper{
|
||
width: 100%; border-bottom: 2rpx solid rgba(0, 0, 0, 0.05); margin-bottom: 32rpx; padding-bottom: 32rpx;
|
||
&:last-child{ border-bottom: 0; margin-bottom: 0; }
|
||
.title{ line-height: 46rpx; color: #333; font-size: 32rpx; font-weight: 500; }
|
||
.notic{
|
||
width: 100%; box-sizing: border-box; padding-left: 160rpx; position: relative; margin-top: 24rpx;
|
||
view{
|
||
&:nth-child(1){ height: 40rpx; background: rgba(3, 174, 128, 0.1); border-radius: 2rpx; color: #03AE80; line-height: 40rpx; width: 140rpx; text-align: center; position: absolute; left: 0; top: 0; font-size: 20rpx; }
|
||
&:nth-child(2){ line-height: 40rpx; color: #666; font-size: 28rpx; min-height: 40rpx; }
|
||
}
|
||
}
|
||
.fee{
|
||
width: 100%; box-sizing: border-box; padding-left: 160rpx; position: relative; margin-top: 28rpx;
|
||
view{
|
||
&:nth-child(1){ height: 40rpx; background: rgba(255, 88, 51, 0.1); border-radius: 2rpx; color: #FF5833; line-height: 40rpx; width: 140rpx; text-align: center; position: absolute; left: 0; top: 0; font-size: 20rpx; }
|
||
&:nth-child(2){
|
||
line-height: 40rpx; color: #666; font-size: 28rpx; min-height: 40rpx;
|
||
text{ display: block; }
|
||
}
|
||
}
|
||
}
|
||
.list{
|
||
margin-top: 24rpx;
|
||
view{
|
||
width: 100%; margin-bottom: 20rpx; padding-left: 160rpx; box-sizing: border-box; position: relative;
|
||
&:last-child{ margin-bottom: 0; }
|
||
text{
|
||
line-height: 40rpx; color: #666; font-size: 28rpx; min-height: 40rpx; display: block; margin-bottom: 20rpx;
|
||
&:nth-child(1){ line-height: 40rpx; color: #333; font-size: 28rpx; position: absolute; left: 0; top: 0; }
|
||
&:last-child{ margin-bottom: 0; }
|
||
}
|
||
}
|
||
}
|
||
.years_waper{
|
||
margin-top: 24rpx;
|
||
.years_list{
|
||
width: 100%; font-size: 0; margin-bottom: 20rpx; box-sizing: border-box; padding-left: 240rpx; position: relative; min-height: 40rpx;
|
||
&:last-child{ margin-bottom: 0; }
|
||
view{
|
||
line-height: 40rpx; font-size: 28rpx;
|
||
&:nth-child(1){ color: #333; position: absolute; left: 0; top: 0; width: 220rpx; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
||
&:nth-child(2){ color: #666; width: 100%; }
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
.bottom{
|
||
width: 100%; position: fixed; left: 0; bottom: 0; background: #fff; z-index: 10;
|
||
.bottom_waper{
|
||
width: 100%; height: 120rpx; box-sizing: border-box; padding: 0 32rpx; display: flex; justify-content: space-between; align-items: center;
|
||
.left{
|
||
display: flex; align-items: flex-end;
|
||
view{
|
||
&:nth-child(1){
|
||
color: #FF5833; font-size: 64rpx; font-weight: bold; line-height: 78rpx; padding-left: 36rpx; position: relative;
|
||
&::after{ content: "¥"; line-height: 50rpx; color: #FF5833; font-size: 36rpx; font-weight: 500; position: absolute; left: 0; bottom: 4rpx; }
|
||
&.free{
|
||
font-size: 32rpx;
|
||
&::after{ content: ""; font-size: 0; }
|
||
}
|
||
}
|
||
&:nth-child(2){ color: #C8C8C8; font-size: 28rpx; margin-left: 8rpx; line-height: 50rpx; }
|
||
&:nth-child(3){
|
||
margin-left: 20rpx; line-height: 50rpx; color: #C8C8C8; font-size: 28rpx; text-decoration: line-through;
|
||
&.free{ line-height: 66rpx; }
|
||
}
|
||
}
|
||
}
|
||
.right{ width: 228rpx; height: 80rpx; border-radius: 100rpx; background: linear-gradient( 141deg, #54C76E 0%, #03AE80 100%); text-align: center; line-height: 80rpx; color: #fff; font-size: 30rpx; font-weight: 500; }
|
||
}
|
||
}
|
||
</style> |