1003 lines
49 KiB
Vue
1003 lines
49 KiB
Vue
<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> |