Files
zhwl-miniapp/pages/my/buyTicket.vue
2025-06-26 12:38:35 +08:00

1003 lines
49 KiB
Vue
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<view class="waper" :style="'padding-bottom: ' + windowBottom + 'px'">
<u-navbar :autoBack="true" left-icon-color="#fff" :placeholder="true" bgColor="#03AE80">
<view slot='center' style="font-size: 36rpx; font-weight: 500; color: #fff;">提交订单</view>
</u-navbar>
<view class="banner"></view>
<view class="waper_box" v-if="detail">
<view class="waper_cont">
<view class="title">{{detail.name}}</view>
<view class="subsist" v-if="detail.classify == '2'">
<view>包含子票</view>
<view>
<text v-for="(i, index) in detail.childList">{{i.childTicketName}}-1张</text>
</view>
</view>
<view class="subsist" v-if="detail.isOrder == '1'">
<view>预约日期</view>
<view>当前门票需提前{{detail.beforeDay}}天预约</view>
</view>
<view class="subsist" v-if="detail.isPurchaseTime == '1'">
<view>可购时间</view>
<view>{{detail.purchStartTime}}{{detail.purchEndTime}}</view>
</view>
<view class="subsist">
<view>使用有效期</view>
<view v-if="detail.ticketValidityPeriod == '1'">游玩日期当天有效</view>
<view v-if="detail.ticketValidityPeriod == '2'">购买后{{detail.buyPeriodDay}}天有效</view>
<view v-if="detail.ticketValidityPeriod == '3'">{{detail.validityStartTime}}{{detail.validityEndTime}}有效</view>
<view v-if="detail.ticketValidityPeriod == '4'">激活后{{detail.buyPeriodDay}}天有效</view>
</view>
<view class="period" v-if="detail.applicablePeriod && detail.classify == '4' && getDayMsg(detail.applicablePeriod)">
({{getDayMsg(detail.applicablePeriod)}}不可用)
</view>
<view class="period" v-if="detail.applicablePeriod && detail.classify != '4'">
({{getWeekMsg(detail.applicablePeriod)}}可用)
</view>
<view class="date_waper" v-if="detail.isPurchaseDate == 1 || detail.isOrder == '1' || detail.ticketValidityPeriod == '1'">
<view class="date_title">游玩日期</view>
<view class="data_list">
<view v-for="(i, index) in dateList" :key="index" :class="dateActive == index ? 'list active' : 'list'" @click="tabDateActive(index)">
<view class="date_top">
<text>{{$utils.getDayOfWeek(i.date)}}</text>
<text>{{i.date.substr(5, i.date.length - 1).split('-').join('月')}}</text>
</view>
<view class="date_bottom">
<text>{{i.price > 0 ? '¥' : ''}}</text>
<text :style="i.price > 0 ? '' : 'font-size: 24rpx;'">{{i.price > 0 ? i.price.toFixed(2) : '免费'}}</text>
</view>
<image src="https://common/date_active.png" mode=""></image>
</view>
<view class="date_all" @click="showDate = true;">
<view class="left">
<view>更多</view>
<view>日期</view>
</view>
<view class="right">
<u-icon name="arrow-right" color="#999" size="32rpx"></u-icon>
</view>
</view>
</view>
</view>
<view class="time_waper" v-if="detail.isPurchaseDate == '1' && detail.isReservation == '1'">
<view class="time_title">场次</view>
<view class="time_list">
<view v-for="(i, index) in detail.periodList" :key="index" :class="{ active: dayActive == index }" @click="changeBuyNum(index)">{{i.timeQuantum}}
<image src="https://common/date_active.png" mode=""></image>
</view>
</view>
</view>
<view class="num">
<view class="left">购票数量</view>
<view class="right">
<u-number-box v-if="detail.isOrderQuantity" :min="1" :max="detail.orderQuantity" :step="1" v-model="buyNum"></u-number-box>
<u-number-box v-if="!detail.isOrderQuantity" :min="1" :max="dayActive == null ? detail.inventory : detail.periodList[dayActive].inventory" :step="1" v-model="buyNum"></u-number-box>
</view>
</view>
<view class="inventory">
<view class="left">
<view>剩余<text>{{dayActive == null ? detail.inventory : detail.periodList[dayActive].inventory}}</text></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="right" @click="showNotic = true;">
<text class="text">预定须知</text>
<u-icon name="arrow-right" color="#3F79FF" size="26rpx" top="2rpx"></u-icon>
</view>
</view>
<view class="msg" v-if="detail.isOrderQuantity">
<view class="icon">
<u-icon name="info-circle" color="#999" size="28rpx"></u-icon>
</view>
<view class="text">每单限购{{detail.orderQuantity}}</view>
</view>
<view class="tourist">
<view class="tourist_title" v-if="detail.classify == '4'">
<view>持卡人信息</view>
<view></view>
</view>
<view class="tourist_title" v-else>
<view>游客信息</view>
<view>需填
<text v-if="detail.authenticationType == '1' || detail.authenticationType == '2'">1</text>
<text v-if="detail.authenticationType == '3'">{{buyNum}}</text>
用于入园认证
</view>
</view>
<view class="menu_list" v-if="touristList.length > 0">
<view :class="'list' + (i.active ? ' active' : '')" v-for="(i, index) in touristList" :key="index" @click="selectTourist(index)">
<text>{{i.name}}</text>
<view class="close" v-if="i.active" @click.stop="removeTourist(index)">
<u-icon name="close-circle-fill" color="rgba(0, 0, 0, 0.4)" size="32rpx"></u-icon>
</view>
<image v-if="i.active" src="https://common/date_active.png" mode=""></image>
</view>
<view class="list add" @click="addTourist">
<text>新增游客</text>
<u-icon name="arrow-right" color="#fff" size="28rpx" top="2rpx"></u-icon>
</view>
</view>
<view class="add_menu" v-else @click="addTourist">
<u-icon name="plus" color="#03AE80" size="28rpx"></u-icon>
<view class="text">点击新增游客</view>
</view>
<view class="tourist_list">
<view class="list" v-for="(i, index) in touristList" :key="index" v-if="i.active">
<view class="row">
<view>
<text>出行人</text>
<text>{{i.name}}</text>
</view>
<view>
<text>手机号</text>
<text>{{i.mobile}}</text>
</view>
<view>
<text>身份证</text>
<text>{{i.idCard || '-'}}</text>
</view>
</view>
<u-icon name="edit-pen" color="#333" size="46rpx" @click="editTourist(i)"></u-icon>
</view>
</view>
</view>
</view>
<!-- <view class="iPass" v-if="cardInfo && (dayActive == null ? detail.salesRice > 0 : detail.periodList[dayActive].price > 0)">
<view class="iPass-left">
<view class="label">一卡通支付</view>
<view class="balance">余额¥{{cardInfo.balance}}</view>
</view>
<view class="iPass-right">
<u-checkbox-group v-model="cardSelect">
<u-checkbox shape="circle" activeColor="#03AE80" name="7"></u-checkbox>
</u-checkbox-group>
</view>
</view> -->
</view>
<view class="bottom">
<view class="bottom_waper" v-if="detail">
<view>
<text>总金额</text>
<text>{{(dayActive == null ? detail.salesRice > 0 : detail.periodList[dayActive].price > 0) ? '¥' : ''}}</text>
<text :class="(dayActive == null ? detail.salesRice > 0 : detail.periodList[dayActive].price > 0) > 0 ? '' : 'free'">{{(dayActive == null ? detail.salesRice : detail.periodList[dayActive].price) > 0 ? ((buyNum * (dayActive == null ? detail.salesRice : detail.periodList[dayActive].price)).toFixed(2)) : '免费'}}</text>
</view>
<view @click="submitOrder">提交订单</view>
</view>
</view>
<!-- 添加修改游客 -->
<view class="tourist_waper" v-if="showTourist">
<view class="tourist_box" :style="'padding-bottom: ' + keyboardHeight + 'px;'">
<view class="popup-tourist">
<view class="title">
{{popupTitle}}
<view class="close" @click="closeTourist">
<u-icon name="close" color="#000" size="30rpx"></u-icon>
</view>
</view>
<view class="form">
<view class="name-box">
<view class="list">
<view class="label">姓名</view>
<input type="text" :adjust-position="false" @keyboardheightchange="handleKeyboardChange" v-model="touristForm.name" placeholder="请输入联系人姓名" />
</view>
</view>
<view class="num-box">
<view class="list">
<view class="label">联系电话</view>
<input type="number" :adjust-position="false" @keyboardheightchange="handleKeyboardChange" v-model="touristForm.mobile" placeholder="请输入联系号码" @blur="keyboardHeight = 0;" />
</view>
<view class="list">
<view class="label">身份证号码</view>
<input type="idcard" :adjust-position="false" @keyboardheightchange="handleKeyboardChange" v-model="touristForm.idCard" placeholder="请输入证件号码" @blur="keyboardHeight = 0;" />
</view>
</view>
</view>
<view class="btn" @click="saveTourist">保存</view>
</view>
</view>
</view>
<!-- 预定须知 -->
<u-popup :show="showNotic" bgColor="transparent" mode="center">
<view class="notic_waper">
<view class="title">预定须知
<view class="icon" @click="showNotic = false;">
<u-icon name="close" color="#333" size="24rpx"></u-icon>
</view>
</view>
<view class="content">{{detail.bookingNotice}}</view>
</view>
</u-popup>
<!-- 日期选择 -->
<u-popup :show="showDate" bgColor="transparent" mode="bottom">
<view class="data_waper">
<view class="title">选择日期
<view class="icon" @click="showDate = false;">
<u-icon name="close" color="#333" size="24rpx"></u-icon>
</view>
</view>
<wn-calendar v-if="records.length && showDate && detail" ref="calendar" :data="records" :isBorder="false" :isLess="false" :colors="['#FF5833']" :isEn="false" :activeDate="dateList[dateActive].date" format="-" @choose="dateChoose" :isOrder="detail.isOrder" :beforeDay="detail.beforeDay"></wn-calendar>
</view>
</u-popup>
</view>
</template>
<script>
export default {
data () {
return {
detail: null,
touristList: [],
activeTourist: [],
showTourist: false,
keyboardHeight: 0,
popupTitle: '',
touristForm: { name: '', mobile: '', idCard: '' },
safeAreaBottom: 0,
windowBottom: 0,
buyNum: 1,
showNotic: false,
records: [],
dateActive: 0,
dateList: [],
showDate: false,
dayActive: null,
// cardInfo: null,
cardSelect: [],
configData: null
}
},
async onLoad (options) {
this.configData = uni.getStorageSync('configData');
uni.showLoading({ mask: true })
// let cardInfo = await this.$http.getPrepaidCard();
// this.cardInfo = cardInfo.data;
this.windowBottom = this.$safeAreaBottom + uni.upx2px(152);
this.safeAreaBottom = this.$safeAreaBottom;
let info = await this.$http.ticketDetail(options.id);
this.detail = info.data;
this.dateList = [];
this.$nextTick(async () => {
if (info.data.isPurchaseDate == '1') {// 开启可购日期 开启日历
// 判断当前日期是否在有效期
let dayNum = 0;// 提前预约天数
if (info.data.isOrder) dayNum = info.data.beforeDay;
if (this.$utils.isDateValid(info.data.purchStartDate, info.data.purchEndDate, this.$utils.formatDate('Y-M-D', this.$utils.getNumDay(dayNum)))) {
console.log('门票有效期:' + info.data.purchStartDate + '至' + info.data.purchEndDate);
let arr = this.$utils.getDateList(this.$utils.formatDate('Y-M-D', this.$utils.getNumDay(dayNum)));
arr.forEach((item) => {
this.dateList.push({ date: item, price: info.data.salesRice })
})
this.getRecords(info.data);
} else {
uni.showToast({ mask: true, title: '当前门票不在有效期', icon: 'none' })
setTimeout(() => {
uni.navigateBack({ delta: 1 })
}, 1500)
}
} else if (info.data.isOrder == '1' || info.data.ticketValidityPeriod == '1') {// 开日预约、门票有效期为游玩日期当天 开启日历
let dayNum = 0;// 提前预约天数
if (info.data.isOrder) dayNum = info.data.beforeDay;
let arr = this.$utils.getDateList(this.$utils.formatDate('Y-M-D', this.$utils.getNumDay(dayNum)));
arr.forEach((item) => {
this.dateList.push({ date: item, price: info.data.salesRice })
})
this.getAllRecords(info.data);
}
uni.hideLoading();
if (info.data.isReservation == '1') {
let time = await this.$http.queryTicketTimeInventory({ ticketId: this.detail.id, playTime: this.dateList[this.dateActive].date });
if (time.data.length > 0) {
let num = 0;
time.data.forEach((item) => {
num += item.inventory;
})
this.detail.periodList = time.data;
this.detail.inventory = num;
} else {
uni.showToast({ mask: true, title: '当前门票尚未设置场次', icon: 'none' });
setTimeout(() => {
uni.navigateBack({ delta: 1 });
}, 1500)
}
}
})
this.getTouristList('init');
},
methods: {
changeBuyNum (index) {
if (this.detail.periodList[index].inventory > 0) {
this.dayActive = index;
if (this.buyNum > this.detail.periodList[index].inventory) this.buyNum = this.detail.periodList[index].inventory;
} else {
uni.showToast({ mask: true, title: this.detail.periodList[index].timeQuantum + '已售罄', icon: 'none' });
}
},
async submitOrder () {
if (this.detail.isPurchaseDate == '1' && this.detail.isReservation == '1' && this.dayActive == null) {
uni.showToast({ mask: true, title: '请选择场次', icon: 'none' })
return false;
}
if (this.detail.isPurchaseTime == '1' && this.detail.purchStartTime && this.detail.purchEndTime) {
let nowDate = this.$utils.formatDate('h:m').split(':');
let start = this.detail.purchStartTime.split(':');
let end = this.detail.purchEndTime.split(':');
let nowTime = nowDate[0] * 60 + nowDate[1];
let startTime = start[0] * 60 + start[1];
let endTime = end[0] * 60 + end[1];
if (Number(nowTime) < Number(startTime) || Number(nowTime) > Number(endTime)) {
uni.showToast({ mask: true, title: '当前门票不在可购时间范围内', icon: 'none' })
return false;
}
}
const arr = this.touristList.filter((item) => {
return item.active;
});
if (this.detail.authenticationType == 3) {
if (arr.length != this.buyNum) {
uni.showToast({ mask: true, title: '购票数量和游客信息人数不匹配', icon: 'none' })
return false;
}
} else {
if (!arr.length) {
uni.showToast({ mask: true, title: '请选择游客信息', icon: 'none' })
return false;
}
}
// uni.showLoading({ mask: true });
let tourist = [];
// authenticationType 1不实名2需提供一位身份证信息3所有出行人需要提供身份信息
if (this.detail.authenticationType == '1' || this.detail.authenticationType == '2') {
for (var i = 0; i < this.buyNum; i ++) {
tourist.push({ id: arr[0].id, ticketId: this.detail.id, buyQuantity: 1 });
}
} else {
for (var i = 0; i < arr.length; i ++) {
tourist.push({ id: arr[i].id, ticketId: this.detail.id, buyQuantity: 1 });
}
}
let orderTime = '';
if (this.detail.isPurchaseDate == 1 || this.detail.isOrder == '1' || this.detail.ticketValidityPeriod == '1') {
orderTime = this.dateList[this.dateActive].date;
}
let data = [{
ticketName: this.detail.name,
ticketId: this.detail.id,
totalPrice: (this.buyNum * this.detail.salesRice).toFixed(2),
price: this.detail.salesRice,
buyQuantity: this.buyNum,
orderTime: orderTime,
userIdcardList: tourist,
qrcodeRule: this.detail.qrcodeRule
}]
if (this.detail.isPurchaseDate == '1' && this.detail.isReservation == '1') {
data[0].timeQuantum = this.detail.periodList[this.dayActive].timeQuantum;
data[0].totalPrice = (this.buyNum * this.detail.periodList[this.dayActive].price).toFixed(2);
data[0].price = this.detail.periodList[this.dayActive].price;
}
let paymentMethod = '';
if (this.cardSelect.length > 0) {
paymentMethod = this.cardSelect[0];
}
if (data[0].totalPrice <= 0) {
paymentMethod = '4';
}
let parmas = { orderItemList: data, orderSource: 4, totalPrice: (this.buyNum * data[0].price).toFixed(2), buyQuantity: this.buyNum };
uni.navigateTo({
url: `/pages/my/payment?parmas=${JSON.stringify(parmas)}`
})
// , paymentMethod: paymentMethod
// if (paymentMethod == '7') parmas.payCode = this.cardInfo.accountNo;
// let info = await this.$http.createTicketOrderPrepay(parmas)
// if (this.paymentMethod == '4' || this.paymentMethod == '7') {
// uni.redirectTo({
// url: `/pages/my/unpaid?id=` + info.data.id
// })
// return false;
// }
// if (info.code == 200) {
// if (info.data.errorMessage) {
// uni.showToast({ mask: true, title: info.data.errorMessage, icon: 'none' })
// setTimeout(() => {
// uni.redirectTo({
// url: `/pages/my/unpaid?id=` + info.data.id
// })
// }, 1500)
// return false;
// }
// if (info.data.tradeSession) {
// const prepayId = JSON.parse(info.data.tradeSession);
// uni.requestPayment({
// provider: 'wxpay',
// timeStamp: prepayId.timeStamp,
// nonceStr: prepayId.nonceStr,
// package: prepayId.packageValue,
// signType: prepayId.signType,
// paySign: prepayId.paySign,
// success: (res) => {
// uni.hideLoading();
// this.showSuccess = true;
// setTimeout(() => {
// uni.redirectTo({
// url: `/pages/my/unpaid?id=` + info.data.id
// })
// }, 3000)
// },
// fail: function (err) {
// uni.hideLoading();
// uni.showToast({ mask: true, title: '支付取消', icon: 'none' })
// setTimeout(() => {
// uni.redirectTo({
// url: `/pages/my/unpaid?id=` + info.data.id
// })
// }, 1500)
// }
// });
// } else {
// uni.hideLoading();
// setTimeout(() => {
// uni.redirectTo({
// url: `/pages/my/unpaid?id=` + info.data.id
// })
// }, 1500)
// }
// } else {
// uni.hideLoading();
// uni.showToast({ mask: true, title: info.msg, icon: 'none' });
// }
},
async tabDateActive (index) {
let date = this.$utils.formatDate('Y-M-D');
if (this.detail.isOrder == '1') {
date = this.$utils.formatDate('Y-M-D', this.$utils.getNumDay(this.detail.beforeDay))
}
if (this.$utils.isDateLessThanToday(this.dateList[index].date, date)) {// 判断是否大于今日
if (this.detail.isPurchaseDate == '1') {
if (this.$utils.isDateValid(this.detail.purchStartDate, this.detail.purchEndDate, this.dateList[index].date)) {
this.dateActive = index;
this.getPeriodList();
} else uni.showToast({ mask: true, title: this.dateList[index].date + '不在门票有效期', icon: 'none' });
} else {
this.dateActive = index;
this.getPeriodList();
}
} else {
if (this.detail.isOrder == '1') {
uni.showToast({ mask: true, title: this.dateList[index].date + '不可选择', icon: 'none' });
} else uni.showToast({ mask: true, title: '不可选择过去日期', icon: 'none' });
}
},
async getPeriodList () {
if (this.detail.isReservation == '1') {
this.dayActive = null;
let time = await this.$http.queryTicketTimeInventory({ ticketId: this.detail.id, playTime: this.dateList[this.dateActive].date });
if (time.data.length > 0) {
let num = 0;
time.data.forEach((item) => {
num += item.inventory;
})
this.detail.periodList = time.data;
this.detail.inventory = num;
} else {
uni.showToast({ mask: true, title: '当前门票尚未设置场次', icon: 'none' });
setTimeout(() => {
uni.navigateBack({ delta: 1 });
}, 1500)
}
}
},
dateChoose (e) {
let arr = this.$utils.getNewDate(this.$utils.formatDate('Y-M-D', e.date), this.detail.isPurchaseDate, this.detail.beforeDay);
this.dateList = [];
arr.forEach((item, index) => {
this.dateList.push({ date: item, price: this.detail.salesRice })
if (this.$utils.formatDate('Y-M-D', e.date) == item) this.dateActive = index;
})
this.showDate = false;
this.getPeriodList();
},
getRecords (data) {
this.records = [];
var currentDate = this.$moment(data.purchStartDate)
var stopDate = this.$moment(data.purchEndDate)
while(currentDate <= stopDate) {
this.records.push({
date: this.$moment(currentDate).format('YYYY/MM/DD').replace("/0","/").replace("/0","/"),
text: this.detail.salesRice > 0 ? this.detail.salesRice : '免费'
})
currentDate = this.$moment(currentDate).add(1, 'days')
}
},
getAllRecords (data) {
this.records = [];
let startData = this.$utils.formatDate('Y-M-D', this.$utils.getNumDay(data.beforeDay))
console.log('日历可选开始时间' + startData)
var currentDate = this.$moment(startData)
var stopDate = this.$moment('2099-12-31')
while(currentDate <= stopDate) {
this.records.push({
date: this.$moment(currentDate).format('YYYY/MM/DD').replace("/0","/").replace("/0","/"),
text: this.detail.salesRice > 0 ? this.detail.salesRice : '免费'
})
currentDate = this.$moment(currentDate).add(1, 'days')
}
},
editTourist (info) {
this.touristForm = { name: info.name, mobile: info.mobile, idCard: info.idCard, id: info.id };
this.popupTitle = '编辑游客'
this.showTourist = true;
let arr = [];
for (var i = 0; i < this.touristList.length; i ++) {
if (this.touristList[i].active) arr.push(this.touristList[i].id);
}
this.activeTourist = arr;
},
addTourist () {
let arr = [];
for (var i = 0; i < this.touristList.length; i ++) {
if (this.touristList[i].active) arr.push(this.touristList[i].id);
}
this.activeTourist = arr;
this.touristForm = { name: '', mobile: '', idCard: '' };
this.popupTitle = '新增游客'
this.showTourist = true;
},
async saveTourist () {
if (!this.touristForm.name) {
uni.showToast({ mask: true, title: '请输入姓名', icon: 'none' })
return false;
}
if (!this.$utils.checkStr(this.touristForm.idCard, 'card')) {
uni.showToast({ mask: true, title: '请输入正确的证件号', icon: 'none' })
return false;
}
if (!this.$utils.checkStr(this.touristForm.mobile, 'mobile')) {
uni.showToast({ mask: true, title: '请输入正确的手机号', icon: 'none' })
return false;
}
let info = null;
if (this.touristForm.id) {
info = await this.$http.updateTourist(this.touristForm);
} else {
info = await this.$http.addTourist(this.touristForm);
}
if (info.code == 200) {
uni.showToast({ mask: true, title: '操作成功', icon: 'success' });
this.closeTourist();
this.getTouristList('get');
}
},
handleKeyboardChange (e) {
this.$nextTick(() => {
this.keyboardHeight = e.detail.height
})
},
async getTouristList (type) {
let info = await this.$http.touristList();
if (type == 'init') {
let data = info.rows.find((item) => {
return item.status == '1'
})
if (data) this.activeTourist = [data.id];
}
for (var i = 0; i < info.rows.length; i ++) {
info.rows[i].active = false;
if (this.activeTourist.indexOf(info.rows[i].id) > -1) {
if (this.isUserOk(info.rows[i])) info.rows[i].active = true;
}
}
// this.detail.authenticationType 1不实名2需提一位为身份证3所有出行人需要提供身份信息
this.touristList = info.rows;
},
closeTourist () {
this.showTourist = false;
},
removeTourist (index) {
this.touristList[index].active = false;
},
selectTourist (index) {
const info = this.touristList[index];
if (info.active) return false;
if (!this.isUserOk(info)) return false;
if (this.buyNum == 1 || this.detail.authenticationType == 1 || this.detail.authenticationType == 2) {
for (var i = 0; i < this.touristList.length; i ++) {
this.touristList[i].active = false;
}
} else if (this.detail.authenticationType == 3) {
let num = this.touristList.filter((item) => {
return item.active
}).length;
if (num >= this.buyNum) {
uni.showToast({ mask: true, title: '游客人数不得大于购票数量', icon: 'none' });
return false;
}
}
this.touristList[index].active = true;
},
isUserOk (info) {
let bol = true;
if (this.detail.isSpecial == '1') {// 特殊票种
let age = this.getAge(info.idCard);
if (age == -1) {
uni.showToast({ mask: true, title: '身份证号不合法', icon: 'none' });
bol = false;
}
switch (this.detail.specialType) {
case '1':// 年龄
let start = this.detail.yearOldStart;
let end = this.detail.yearOldEnd;
if (age < start || age > end) {
uni.showToast({ mask: true, title: this.detail.name + '为特殊票种,仅限年龄为' + start + '岁至' + end + '岁的人员购买', icon: 'none' });
bol = false;
}
break;
case '2':// 性别身份证倒数第二位则是性别码,男性为奇数,女性为偶数
if (this.detail.sex != this.isEvenOrOdd(info.idCard[info.idCard.length - 2])) {
uni.showToast({ mask: true, title: this.detail.name + '为特殊票种,仅限性别为' + (this.detail.sex == '1' ? '男' : '女') + '的人员购买', icon: 'none' });
bol = false;
}
break;
case '3':// 特殊区域specialAreaTicket 1可购2不可购
let arr = [], area = [];
this.detail.specialAreaList.forEach((item) => {
arr.push(String(item.areaCode))
area.push(item.provinceName + item.cityName + item.areaName)
})
let str = info.idCard.substr(0, 6);
if (this.detail.specialAreaTicket == '1') {
if (arr.indexOf(str) == -1) {
uni.showToast({ mask: true, title: this.detail.name + '为特殊票种,仅在' + area.join(',') + '可购', icon: 'none' });
bol = false;
}
}
if (this.detail.specialAreaTicket == '2') {
if (arr.indexOf(str) > -1) {
uni.showToast({ mask: true, title: this.detail.name + '为特殊票种,在' + area.join(',') + '不可购', icon: 'none' });
bol = false;
}
}
break;
}
}
return bol;
},
isEvenOrOdd (num) {
if (num % 2 === 0) {
return '2';
} else {
return '1';
}
},
getAge (idCard) {
const birthday = idCard.match(/\d{6}(\d{4})(\d{2})(\d{2})/);
if (birthday) {
const year = parseInt(birthday[1]);
const month = parseInt(birthday[2]);
const day = parseInt(birthday[3]);
const today = new Date();
let age = today.getFullYear() - year;
if (today.getMonth() < month - 1 || (today.getMonth() == month - 1 && today.getDate() < day)) {
age--;
}
return age;
} else {
return -1; // 身份证号不合法
}
},
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;
},
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;
},
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;
},
}
}
</script>
<style lang="scss">
.waper{ position: relative; }
.banner{ width: 100%; height: 394rpx; background: #03AE80; position: absolute; left: 0; top: 0; }
.waper_box{
width: 100%; box-sizing: border-box; padding: 28rpx 32rpx; position: relative; z-index: 3; padding-bottom: 158rpx;
.waper_cont{
width: 100%; background: #fff; border-radius: 10rpx; box-sizing: border-box; padding: 42rpx 24rpx;
.title{ line-height: 56rpx; color: #333; font-size: 40rpx; font-weight: 500; padding-bottom: 24rpx; border-bottom: 2rpx solid #E8E8E8; }
.subsist{
width: 100%; margin-top: 32rpx;
view{
&:nth-child(1){ line-height: 46rpx; color: #333; font-size: 32rpx; font-weight: 500; }
&:nth-child(2){
margin-top: 20rpx; line-height: 40rpx; color: #999; font-size: 28rpx;
text{ display: block; }
}
}
}
.period{ margin-top: 4rpx; line-height: 34rpx; color: #666; font-size: 24rpx; }
.date_waper{
width: 100%; margin-top: 32rpx;
.date_title{ line-height: 46rpx; color: #333; font-size: 32rpx; font-weight: 500; }
.data_list{
width: 100%; margin-top: 20rpx; font-size: 0; height: 106rpx; position: relative; box-sizing: border-box; padding-right: 94rpx;
.list{
display: inline-block; vertical-align: top; width: 168rpx; height: 100%; box-sizing: border-box; border: 2rpx solid #E1E1E1; border-radius: 10rpx; padding: 16rpx 4rpx 0; margin-left: 20rpx; position: relative;
&:first-child{ margin-left: 0; }
.date_top{ width: 100%; height: 34rpx; display: flex; justify-content: space-between; align-items: center; color: #999; font-size: 24rpx; }
.date_bottom{
width: 100%; height: 40rpx; display: flex; align-items: flex-end; color: #FF5833; margin-top: 4rpx;
text{
&:first-child{ font-size: 24rpx; line-height: 36rpx; }
&:last-child{ font-size: 32rpx; font-weight: 500; line-height: 40rpx; }
}
}
image{ width: 40rpx; height: 40rpx; position: absolute; bottom: 0; right: 0; display: none; }
&.active{
border-color: #03AE80;
image{ display: block; }
}
}
.date_all{
display: flex; align-items: center; position: absolute; right: 0; top: 50%; transform: translateY(-50%);
.left{ line-height: 34rpx; font-size: 24rpx; color: #999; }
}
}
}
.time_waper{
width: 100%; margin-top: 32rpx;
.time_title{ line-height: 46rpx; color: #333; font-size: 32rpx; font-weight: 500; }
.time_list{
width: 100%; margin-top: 20rpx; font-size: 0;
view{
display: inline-block; width: 190rpx; height: 70rpx; box-sizing: border-box; border: 2rpx solid rgba(0, 0, 0, 0.2); border-radius: 10rpx; margin-right: 34rpx; margin-top: 14rpx; color: #666; font-size: 24rpx; text-align: center; line-height: 66rpx; position: relative;
&:nth-child(3n){ margin-right: 0; }
&:nth-child(1), &:nth-child(2), &:nth-child(3){ margin-top: 0; }
image{ position: absolute; right: 0; bottom: 0; width: 40rpx; height: 40rpx; display: none; }
&.active{
border-color: #03AE80;
image{ display: block; }
}
}
}
}
.num{
width: 100%; height: 64rpx; display: flex; justify-content: space-between; align-items: center; margin-top: 32rpx;
view{
&:first-child{ font-size: 32rpx; font-weight: 500; color: #333; }
&:last-child{
.u-number-box{
width: 198rpx; height: 100%; border-radius: 50rpx; box-sizing: border-box; border: 2rpx solid #E1E1E1;
.u-number-box__input{ width: 66rpx; margin: 0; background: transparent !important; border: 2rpx solid #E1E1E1; box-sizing: border-box; border-top: 0; border-bottom: 0; }
.u-number-box__minus, .u-number-box__plus{
background: transparent !important; width: 64rpx; height: 100% !important; padding: 0 !important;
.u-icon__icon{ font-size: 20rpx !important; color: #03AE80 !important; }
}
.u-number-box__minus--disabled .u-icon__icon{ color: #c8c9cc !important; }
}
}
}
}
.inventory{
width: 100%; margin-top: 24rpx; height: 34rpx; display: flex; justify-content: space-between; align-items: center;
.left{
font-size: 0;
view{
display: inline-block; vertical-align: top; color: #999; font-size: 24rpx; margin-right: 32rpx; position: relative;
&::after{ content: ""; width: 2rpx; height: 24rpx; background: #E8E8E8; position: absolute; left: -16rpx; top: 50%; transform: translateY(-50%); }
text{ color: #FF5833; }
&:last-child{ margin-right: 0; }
&:first-child{
&::after{ content: ""; width: 0; }
}
}
}
.right{
display: flex; align-items: center;
.text{ color: #3F79FF; font-size: 24rpx; margin-right: 4rpx; }
}
}
.msg{
width: 100%; background: #FBFBFB; border-radius: 10rpx; padding: 12rpx 20rpx; position: relative; padding-left: 56rpx; margin-top: 20rpx; box-sizing: border-box;
.icon{ position: absolute; left: 16rpx; top: 50%; transform: translateY(-50%); }
.text{ line-height: 34rpx; color: #999; font-size: 24rpx; }
}
.tourist{
width: 100%; margin-top: 40rpx;
.tourist_title{
width: 100%; display: flex; align-items: center; height: 46rpx;
view{
&:first-child{ font-size: 32rpx; color: #333; font-weight: 500; }
&:last-child{ margin-left: 8rpx; color: #999; font-size: 28rpx; }
}
}
.menu_list{
width: 100%; display: flex; flex-wrap: wrap;
.list{
width: 166rpx; height: 70rpx; display: flex; justify-content: center; align-items: center; color: #666; font-size: 24rpx; border-radius: 10rpx; margin-top: 24rpx; margin-right: 30rpx; border: 2rpx solid #999; box-sizing: border-box;
&.active{
position: relative; font-size: 28rpx; color: #03AE80; border: 1rpx solid #03AE80;
.close{ position: absolute; right: -14rpx; top: -14rpx; }
image{ width: 40rpx; height: 40rpx; position: absolute; bottom: 0; right: 0; }
}
&:last-child{ margin-right: 0; }
&.add{ background: #03AE80; border: 1rpx solid #03AE80; color: #FFFFFF; padding-left: 4rpx; }
}
}
.add_menu{
width: 100%; margin-top: 32rpx; height: 90rpx; display: flex; justify-content: center; align-items: center; background: rgba(3,174,128,0.1); border-radius: 10rpx;
.text{ margin-left: 8rpx; color: #03AE80; font-size: 28rpx; font-weight: 500; }
}
.tourist_list{
width: 100%;
.list{
width: 100%; margin-top: 38rpx; background: #FBFBFB; border-radius: 10rpx; box-sizing: border-box; padding: 28rpx 32rpx;
display: flex;
align-items: center;
flex-direction: row;
justify-content: space-between;
.row {
view{
width: 100%; display: flex; align-items: center; height: 40rpx; margin-bottom: 16rpx;
&:last-child{ margin-bottom: 0; }
text{
font-size: 28rpx;
&:first-child{ color: #999; }
&:last-child{ margin-left: 20rpx; color: #333; }
}
}
}
}
}
}
}
.iPass {
width: 100%; height: 135rpx; background: #FFFFFF; border-radius: 10rpx; margin-top: 20rpx; padding: 0 24rpx; box-sizing: border-box; display: flex; align-items: center; justify-content: space-between;
.iPass-left {
.label { font-weight: 500; font-size: 32rpx; color: rgba(0,0,0,0.85); line-height: 38rpx; }
.balance { font-size: 24rpx; color: #FF3333; line-height: 28rpx; margin-top: 4rpx; }
}
}
}
.bottom{
width: 100%; position: fixed; left: 0; bottom: 0; z-index: 5;
.bottom_waper{
width: 100%; height: 120rpx; box-sizing: border-box; padding: 20rpx 32rpx; background: #fff; display: flex; justify-content: space-between; align-items: center;
view{
height: 80rpx;
&:first-child{
display: flex; align-items: flex-end;
text{
&:nth-child(1){ line-height: 34rpx; color: #999; font-size: 24rpx; }
&:nth-child(2){ font-size: 36rpx; font-weight: bold; color: #FF5833; line-height: 44rpx; }
&:nth-child(3){
font-size: 64rpx; color: #FF5833; font-weight: bold; line-height: 64rpx;
&.free{ font-size: 34rpx; line-height: 48rpx; }
}
}
}
&:last-child{ width: 228rpx; text-align: center; line-height: 80rpx; background: linear-gradient( 141deg, #54C76E 0%, #03AE80 100%); color: #fff; border-radius: 66rpx; font-size: 30rpx; font-weight: 500; }
}
}
}
.tourist_waper{
width: 100%; height: 100%; background: rgba(0, 0, 0, 0.4); position: fixed; left: 0; bottom: 0; z-index: 100; display: flex; align-items: flex-end;
.tourist_box{
width: 100%;
.popup-tourist{ width: 100%; }
}
}
.notic_waper{
width: 638rpx; background: #fff; border-radius: 10rpx; box-sizing: border-box; padding: 32rpx;
.title{
height: 46rpx; text-align: center; line-height: 46rpx; position: relative; color: #333; font-size: 32rpx; font-weight: 500;
.icon{ position: absolute; right: 0; top: 50%; transform: translateY(-50%); }
}
.content{ margin-top: 28rpx; border-top: 2rpx solid rgba(0, 0, 0, 0.1); padding-top: 28rpx; max-height: 720rpx; font-size: 26rpx; color: #666; line-height: 42rpx; overflow: hidden; overflow-y: scroll; }
}
.data_waper{
width: 100%; background: #fff; border-radius: 10rpx 10rpx 0 0; box-sizing: border-box; padding: 32rpx;
.title{
height: 46rpx; text-align: center; line-height: 46rpx; position: relative; color: #333; font-size: 32rpx; font-weight: 500;
.icon{ position: absolute; right: 0; top: 50%; transform: translateY(-50%); }
}
}
</style>