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.
 
 
 
 
 

1811 lines
48 KiB

<template>
<view class="bg">
<view class="top-box1" >
<view class="top-left">
<view class="title text-overflow">{{ pInfo.title }}</view>
<view>
<view style="padding: 20rpx 0 10rpx;" v-if="allSeldDate.length > 0">{{showDate.date}} {{ShowDateDay(new Date(showDate.date).getDay())}}</view>
<view v-if="showDate.startTime">{{ showDate.startTime }}-{{ showDate.endTime }} 入园</view>
</view>
</view>
<view class="top-edit" @click="changeSku">修改 <uni-icons style="height: 20rpx;" color="#999999" type="right" size="12"></uni-icons></view>
</view>
<view class="tickets-box">
<view class="w-full" v-for="(skuItem,skuIndex) in pInfo.specifications" :key="skuIndex">
<view class="num-box" v-if="showMore||skuIndex==0">
<view class="flex-between num-left">
<view class="left-title text-overflow">{{skuItem.title}}</view>
<view class="left-price">{{skuItem.price / 100}}</view>
<view class="num-right" v-if="skuItem.store>0">
<view :class="['btn-num',skuItem.buyNum<=0||(skuItem.id==sInfo.id&&skuItem.buyNum<=1)?'disabled':'']"
v-if="!skuItem.originate_order_id && !skuItem.gp_id" @click="delNumber(skuItem)" >-</view>
<view class="num-span">{{ skuItem.buyNum }}</view>
<view class="btn-num" v-if="!skuItem.originate_order_id && !skuItem.gp_id" @click="addNumber(skuItem)" >+</view>
</view>
<view class="num-right" style="width: 160rpx;" v-else>
<view>无库存</view>
</view>
</view>
<view style="padding: 30rpx 0 20rpx;" class="num-subtitle text-overflow" @click="showpopRule(true, skuItem)">
<view class="flex" v-if="skuItem.specifications_new_tag">
<view v-for="(tag,tagIndex) in skuItem.specifications_new_tag.split(',').slice(0, 2)"
:key="tagIndex">{{ tag }}<text style="padding: 0 5rpx;">|</text></view>
</view>
<view>预订须知 ></view>
</view>
<!-- <view style="color: #C3282E;" class="num-subtitle text-overflow">购票限制没有绑定字段</view> -->
</view>
</view>
<view class="buyMore" @click="showMore=!showMore">
<template v-if="!showMore">
<view>一起订</view>
<view class="buyMore-btn">展开购买</view>
</template>
<template v-else>
<view></view>
<view class="buyMore-btn">收起</view>
<view></view>
</template>
</view>
</view>
<view class="people-box" >
<view class="people-box-title">
<view v-if="!skuBuyMultiple">仅需填写{{pInfo.specifications[0].buyNum}}位出行人</view>
<view v-else>出行人信息</view>
</view>
<view style="padding: 42rpx 0 10rpx;">
<view v-for="(skuItem,skuIndex) in pInfo.specifications" :key="skuIndex">
<view class="people-box-sku" v-if="skuItem.buyNum>=1">
<view class="flex relative" style="max-width: 100%;width: fit-content;"
v-if="!skuBuyMultiple&&skuItem.is_card">
<view class="person-scroll no-scrollbar" style="overflow-y: auto;">
<view :class="['person-item-container',(skuItem.is_real_name&&skuItem.selPeople.some(v=>v.id==item.id))||(!skuItem.is_real_name&&skuItem.selPerson.id==item.id)?'active':'']"
v-for="(item,addI) in addressList" :key="addI"
@click.stop="personClick(item,skuItem)">
<view class="person-item">
<view>{{item.name}}</view>
<view v-if="!judegeAgeLimit(skuItem, item)" class="disabled">信息不符</view>
</view>
<view class="selected" v-if="(skuItem.is_real_name&&skuItem.selPeople.some(v=>v.id==item.id))||(!skuItem.is_real_name&&skuItem.selPerson.id==item.id)">
<uni-icons color="#fff" type="checkmarkempty" size="10" ></uni-icons>
</view>
</view>
</view>
<view class="h-1rpx flex-shrink-0" style="width: 110rpx;"></view>
<view class="person-item-more" @click.stop="showAddressPopUp({},[],true)" v-if="addressList.length>0">
<view>更多></view>
</view>
</view>
<view class="sku-title" v-if="skuBuyMultiple">{{skuItem.title}}</view>
<!-- 一票一证 -->
<view class="w-full" v-if="skuItem.is_card&&skuItem.is_real_name">
<view v-for="(person,personIndex) in skuItem.selPeople" :key="personIndex" @click.stop="showAddressPopUp(person,skuItem.selPeople)">
<view class="person-info flex" v-if="person.id">
<view @click.stop="removePerson(person)">
<uni-icons color="#F84A56" type="minus" size="30" ></uni-icons>
</view>
<text style="padding:0 30rpx 0 20rpx;">出行人{{personIndex+1}}</text>
<view class="person-info-detail">
<view style="font-size: 31rpx;color: #000000;" class="flex flex-items-center">
<text style="padding-right: 30rpx;">{{person.name}}</text>
<img @click.stop="changeAddressAddPopup('open',person)" v-if="skuBuyMultiple" style="width: 32rpx;height: 32rpx;" :src="showImg('/uploads/20241023/337cf610ce5924c2a65b7a28b6a4891e.png')" alt="" />
</view>
<view v-if="judegeAgeLimit(skuItem,person)">
<view style="padding: 20rpx 0 14rpx;">手机号 {{person.tel}}</view>
<view>身份证 {{person.id_number}}</view>
</view>
<view v-else style="color: #C3282E;padding: 20rpx 0 14rpx;">不符合适用人群年龄限制</view>
</view>
<img @click.stop="changeAddressAddPopup('open',person)" v-if="!skuBuyMultiple" style="width: 32rpx;height: 32rpx;"
:src="showImg('/uploads/20241023/337cf610ce5924c2a65b7a28b6a4891e.png')" alt="" />
<uni-icons v-else type="right" size="16"></uni-icons>
</view>
<view class="w-full" style="padding-bottom: 33rpx;" v-else>
<view class="person-need" >
<view class="flex flex-items-center">
<uni-icons color="#515150" type="plus" size="30"></uni-icons>
<text style="padding:0 30rpx;">出行人{{personIndex+1}}</text>
<text >点击填写1位出行人信息</text>
</view>
<uni-icons color="#515150" type="right" size="16"></uni-icons>
</view>
</view>
</view>
</view>
<!-- 多票一证 -->
<view class="w-full" v-if="skuItem.is_card&&(!skuItem.is_real_name)">
<view @click.stop="showAddressPopUp(skuItem.selPerson,[])">
<view class="person-info flex" v-if="skuItem.selPerson.id">
<view @click.stop="removePerson(skuItem.selPerson)">
<uni-icons color="#F84A56" type="minus" size="30" ></uni-icons>
</view>
<text style="padding:0 30rpx 0 20rpx;">出行人1</text>
<view class="person-info-detail">
<view style="font-size: 31rpx;color: #000000;" class="flex flex-items-center">
<text style="padding-right: 30rpx;">{{skuItem.selPerson.name}}</text>
<img @click.stop="changeAddressAddPopup('open',skuItem.selPerson)" v-if="skuBuyMultiple" style="width: 32rpx;height: 32rpx;" :src="showImg('/uploads/20241023/337cf610ce5924c2a65b7a28b6a4891e.png')" alt="" />
</view>
<view v-if="judegeAgeLimit(skuItem,skuItem.selPerson)">
<view style="padding: 20rpx 0 14rpx;">手机号 {{skuItem.selPerson.tel}}</view>
<view>身份证 {{skuItem.selPerson.id_number}}</view>
</view>
<view v-else style="color: #C3282E;padding: 20rpx 0 14rpx;">不符合适用人群年龄限制</view>
</view>
<img @click.stop="changeAddressAddPopup('open',skuItem.selPerson)" v-if="!skuBuyMultiple" style="width: 32rpx;height: 32rpx;"
:src="showImg('/uploads/20241023/337cf610ce5924c2a65b7a28b6a4891e.png')" alt="" />
<uni-icons v-else type="right" size="16"></uni-icons>
</view>
<view class="w-full" style="padding-bottom: 33rpx;" v-else>
<view class="person-need" >
<view class="flex flex-items-center">
<uni-icons color="#515150" type="plus" size="30"></uni-icons>
<text style="padding:0 30rpx;">出行人1</text>
<text >点击填写1位出行人信息</text>
</view>
<uni-icons color="#515150" type="right" size="16"></uni-icons>
</view>
</view>
</view>
</view>
<!-- 不实名 -->
<view class="w-full flex flex-items-center" v-if="!skuItem.is_card" style="padding-bottom: 33rpx;font-size: 29rpx;">
<view style="width: 170rpx;" class="flex-shrink-0">联系电话</view>
<view class="flex flex-between flex-1 w-1rpx" >
<input class="input" type="text" placeholder="请输入手机号" v-model="skuItem.selPerson.tel" />
<uni-icons v-if="skuItem.selPerson.tel&&skuItem.selPerson.tel.length>0"
type="closeempty" size="14" @click="clearTel(skuItem.selPerson)"></uni-icons>
</view>
</view>
</view>
</view>
</view>
</view>
<!-- 优惠券 -->
<view @click="goOrderCoupon" class="tickets-container flex-between top-line">
<view class="order-title">优惠券</view>
<view class="coupon-btn" v-if="coupon==''">
<view class="select">选择优惠券</view>
<uni-icons style="height: 42rpx;" color="#999999" type="right" size="18"></uni-icons>
</view>
<div class="coupon-price" v-else>
<span v-if="coupon.percent == 0">-¥{{coupon.discounts/100}}</span>
<span v-else>-{{coupon.percent}}%</span>
<span style="margin:0 31rpx 0 8rpx;color: #6C7A94;">></span>
</div>
</view>
<view class="btn-list">
<view class="price-box">
<view class="text">合计:</view>
<view class="price">{{ total() }}</view>
<!-- <view class="post-text" v-if="sendType==1&&post">含邮费:¥{{ post / 100 }}</view> -->
</view>
<view class="btn" @click="order()">去支付</view>
</view>
<!-- 选择出行人 -->
<uni-popup ref="addressPopup" type="bottom" backgroundColor="#F4F4F4" >
<view class="people-popup">
<view class="top flex-between" style="padding-bottom: 14rpx;">
<text class="text-overflow" @click="changeAddressPopup('close')">取消</text>
<text style="color: #515150;" class="confirm" @click="changeAddressPopup('close',true)">确定</text>
</view>
<view class="button" @click="changeAddressAddPopup('open',{})">添加出行人</view>
<view class="popup-list" v-if="addressList.length > 0">
<view :class="['popup-item',addressSelect.id==item.id?'active':'',currentPerson.id!=item.id&&currentPersonIds.includes(item.id)?'disabled':'']"
v-for="(item, index) in addressList" :key="index" @click="seldThisAddress(item)">
<view class="item-top flex flex-items-center">
<img @click.stop="changeAddressAddPopup('open',item)" class="flex-shrink-0" :src="showImg('/uploads/20241023/337cf610ce5924c2a65b7a28b6a4891e.png')" alt="" />
<view class="name flex-shrink-0" style="padding-left: 32rpx;width: 180rpx;">{{item.name}}</view>
<view class="flex-1 w-1rpx" style="padding-left: 20rpx;">
<view class="name">
<text>手机号 {{ item.tel }}</text>
<text class="tag" v-if="item.is_default == 1">默认</text>
</view>
<view class="subtitle text-overflowRows">身份证 {{ item.id_number}}</view>
</view>
</view>
</view>
</view>
</view>
</uni-popup>
<!-- 新增编辑出行人弹窗 -->
<uni-popup ref="addressAddPopup" type="bottom" backgroundColor="#F4F4F4" style="border-radius: 13rpx 13rpx 0 0;">
<view class="people-popup">
<view class="top-box">
<view class="top flex-between" style="height: fit-content;">
<text class="text-overflow" @click="changeAddressAddPopup('close')">取消</text>
<text style="font-size: 35rpx;font-weight: 600;">{{addressTitle}}</text>
<text style="color: #515150;" class="confirm" @click="saveAddress">保存</text>
</view>
</view>
<view class="add-edit-content">
<contactAddVue ref="addressAddVueRef"></contactAddVue>
</view>
</view>
</uni-popup>
<!-- 预订须知的弹窗 -->
<uni-popup ref="popupRule" type="bottom" :safe-area="false">
<view class="popup-content-date flex-column flex" >
<view class="popup-content-title flex">
<view class="flex-1 w-1rpx text-overflow">
{{skuInfo.title}}
</view>
<img src="https://static.ticket.sz-trip.com/taizhou/images/cha.png" @click="showpopRule(null)"
style="width: 20rpx;height: 20rpx;" class="flex-shrink-0">
</view>
<view class="content flex-1 h-1rpx no-scrollbar">
<view class="detail-content" v-html="formateRichText(skuInfo.reserve_content)"></view>
</view>
</view>
</uni-popup>
<!-- 预定弹窗 -->
<uni-popup ref="popup" type="bottom" :safe-area="false">
<view class="popup-content-date calendar-edit" >
<view class="popup-content-title flex">
<view class="flex-1 w-1rpx text-overflow">
{{sInfo.title}}
</view>
<img src="https://static.ticket.sz-trip.com/taizhou/images/cha.png" @click="closePopup"
style="width: 31rpx;height: 31rpx;" class="flex-shrink-0">
</view>
<view class="order-popup-detail">
<view class="relative">
<view class="sku-title">使用日期</view>
<view class="date-content">
<view :class="['item', item.store>0?'':'disabled',seldDateIndex===index?'active':'']"
v-for="(item,index) in allSeldDate" :key="index"
@click="clickTab(item,index)">
<view>{{ShowDateDay(new Date(item.date).getDay())}}</view>
<view>{{item.date.slice(-5)}}</view>
<view class="price" v-if="item.store > 0">¥{{item.money/100}}</view>
<view v-else>不可定</view>
</view>
</view>
<view class="dateMore" @click="openCalendar">
<view style="width: 55rpx;">更多日期</view>
</view>
</view>
<view v-if="timesArr.length > 0 && sInfo.is_time_stock">
<view class="sku-title">选择场次</view>
<view class="time-box">
<view v-for="(item,index) in timesArr" :key="index"
:class="['time-item',{'time-disable': item.stock_number < 1, 'time-active': item.stock_number > 0 && index == seldTimeIndex}]"
@click="changeTime(item,index)">
{{ item.start_time }}-{{ item.end_time }}
{{item.stock_number < 10 ? (item.stock_number === -1 ? '不可定' : item.stock_number === 0 ? '无票' : '(余票' + item.stock_number + ')') : '有票'}}
</view>
</view>
</view>
</view>
<view class="sku-bottom">
<view class="flex" style="align-items: baseline;">
合计:<view class="bottom-price">{{allSeldDate[seldDateIndex].money / 100 || 0}}</view>
</view>
<view class="bottom-btn" @click="addBuyCard">
确定
</view>
</view>
</view>
</uni-popup>
<uni-calendar ref="calendar" class="uni-calendar--hook" :clear-date="true"
:date="allSeldDate[seldDateIndex].date" :insert="false" :startDate="calendarParam.startDate"
:endDate="calendarParam.endDate" @confirm="confirmCalendar" :selected="calendarParam.selected"/>
</view>
</template>
<script>
import contactAddVue from '../../compoents/contactAdd.vue';
export default {
components: {contactAddVue},
data() {
return {
pInfo: {specifications: []}, // 当前商品
sInfo: {sku_model: {}}, // 当前门票
showDate: {
date: '',
startTime: '',
endTime: ''
},
minSeldDate: new Date().Format('yyyy-MM-dd'),
maxSeldDate: new Date((new Date()).getFullYear(), (new Date()).getMonth() + 3, 0).Format('yyyy-MM-dd'),
calendarParam: {
stratDate:'',endDate: '', selected: []
},
allSeldDate: [],
seldDateIndex: 0,
timesArr: [],
seldTimeIndex: 0,
buyNum: 0,
addressList: [], // 出行人列表
currentPerson: {}, // 列表当前要设置的出行人 用地址引用直接修改
currentPersonIds: [], // 当前门票的所有出行人
addressSelect: {}, // 出行人弹窗选择的人
showMore: false,
skuBuyMultiple: false,
coupon:'',
skuInfo: {}, // 当前点击的sku
addressTitle: '添加出行人',
setDefault: false
}
},
onLoad(options) {
// this.getList();
this.$store.commit("choseCoupon", "");
this.initPageData()
},
onShow() {
this.coupon = this.$store.state.user.coupon
},
onUnload () {
},
methods: {
goOrderCoupon () {
let allPrice = 0
let skuIds= []
this.pInfo.specifications.forEach(v=>{
allPrice+= v.price*v.buyNum
if (v.buyNum>0) {
skuIds.push(v.id)
}
})
uni.navigateTo({
url: `/subPackages/order/orderCoupon?allprice=${allPrice}&sku_ids=${skuIds.join(',')}`
})
},
// 获取最大优惠券
async getMaxCouponData () {
let allPrice = 0
this.pInfo.specifications.forEach(v=>{
allPrice+= v.price*v.buyNum
})
let param = {money:allPrice,sku_ids:this.sInfo.id}
let res = await this.getMaxCoupon(param)
if (res.id) {
this.coupon = res
}
},
// 获取sku价格日历money
async initPriceCal(skuId) {
let res = await this.Post({
specifications_id: skuId,
date: this.showDate.date,
start_time:this.showDate.startTime||'',
end_time:this.showDate.endTime||''
}, '/api/goods/getSpecificationsPriceCalendarAndTime')
if (res.code == 1) {
return {code:1,...res.data}
}
return {code:2}
},
async initPageData () {
this.setDefault = false
this.showMore = false
this.skuBuyMultiple = false
let data = uni.getStorageSync('ticketOrder');
try{
data = JSON.parse(data)
// selPeople 一证多票 selPerson 一证一票
data.pInfo.specifications.forEach(v=>{
let age_limit = null
try {
age_limit = JSON.parse(v.age_restriction)
} catch (e) {
age_limit = null
}
v.age_limit = age_limit
v.buyNum = 0;v.selPeople = [];v.selPerson = {}
v.is_card = Number(v.is_card);
v.is_real_name = Number(v.is_real_name)
})
let orderSkuIndex = data.pInfo.specifications.findIndex(v=>v.id == data.sInfo.id)
let item = data.pInfo.specifications.splice(orderSkuIndex, 1)[0]; // 将购买的数据放在第一位
item.buyNum = 1
item.selPeople = [
{
id:null,id_number:null,name:null,
tel:null,user_id:null,age:null,
},
]
item.selPerson = {
id:null,id_number:null,name:null,tel:null,user_id:null,age:null,
}
data.pInfo.specifications.unshift(item);
// 过滤出时间格式一致的sku
let is_time_stock = data.sInfo.is_time_stock
let is_price_calendar = data.sInfo.is_price_calendar
data.pInfo.specifications = data.pInfo.specifications.filter(v=>v.is_time_stock==is_time_stock && v.is_price_calendar==is_price_calendar)
this.minSeldDate=data.minSeldDate
this.maxSeldDate = data.maxSeldDate
this.calendarParam = data.calendarParam
this.allSeldDate = data.allSeldDate || []
this.seldDateIndex = data.seldDateIndex
this.timesArr = data.timesArr || []
this.seldTimeIndex = data.seldTimeIndex
this.showDate = {
date: ((this.allSeldDate[this.seldDateIndex])||{}).date,
startTime: (this.timesArr[this.seldTimeIndex]||{}).start_time,
endTime: (this.timesArr[this.seldTimeIndex]||{}).end_time
}
for(let sku of data.pInfo.specifications) {
let res = await this.initPriceCal(sku.id)
if (res.code === 1) {
sku.price = res.money
sku.store = res.store
}
}
this.pInfo = data.pInfo
this.sInfo = data.sInfo
} catch(e){
console.log(e)
}
this.getAddressList()
this.getMaxCouponData()
},
/*---------------出行人------------------------------*/
// 判断出行人年龄限制
judegeAgeLimit (ticket, person) {
console.log(ticket,person)
let age_limit = ticket.age_limit
let personAge = person.age
let result = true
if (!age_limit) {
return true
} else {
if (age_limit.start&& result) {
result = personAge>=age_limit.start
}
if (age_limit.end&&result) {
result = personAge<=age_limit.end
}
}
return result
},
// 选择出行人
showAddressPopUp (person,personList, isMore) {
if (isMore) {
let currentSku = this.pInfo.specifications[0]
if (currentSku.is_real_name) {
let personIndex = currentSku.selPeople.findIndex(v=>!v.id)
if (personIndex<0) {personIndex = 0}
person = currentSku.selPeople[personIndex]
personList = currentSku.selPeople
} else {
person = currentSku.selPerson
personList = [currentSku.selPerson]
}
}
this.currentPerson = person
this.currentPersonIds = []
personList.forEach(v=>{
if (v.id) {
this.currentPersonIds.push(v.id)
}
})
if (person.id) {
this.addressSelect = person
} else {
this.addressSelect = {}
}
// 如果没有出行人 打开新增弹窗
if (this.addressList.length<=0) {
this.changeAddressAddPopup('open',{})
return
}
this.changeAddressPopup('open')
},
// 获取出行人信息
getAddressList () {
this.Post({},'/api/user/contactList').then((res)=> {
this.addressList = res.data || []
// 对比所有出行人信息进行变更
this.pInfo.specifications.forEach(s=>{
s.selPeople.forEach(person=>{
let currentPerson = this.addressList.find(v=>v.id == person.id)
if (currentPerson) {
person.id = currentPerson.id
person.id_number = currentPerson.id_number
person.name = currentPerson.name
person.user_id = currentPerson.user_id
person.tel = currentPerson.tel
person.age = currentPerson.age
}
})
let currentPerson = this.addressList.find(v=>v.id == s.selPerson.id)
if (currentPerson) {
s.selPerson.id = currentPerson.id
s.selPerson.id_number = currentPerson.id_number
s.selPerson.name = currentPerson.name
s.selPerson.user_id = currentPerson.user_id
s.selPerson.tel = currentPerson.tel
s.selPerson.age = currentPerson.age
}
})
// 如果只有一张票给默认值
if (!this.setDefault ) {
// 找符合条件的
let currentData = this.pInfo.specifications[0]
let person0 = currentData.selPeople[0]
let person = currentData.selPerson
let currentPerson = {}
if (!currentData.is_card) {
person.tel = JSON.parse(uni.getStorageSync('userInfo')).mobile
} else if(this.addressList.length>0) {
if (this.addressList.some(v=>v.is_default=='1')) {
currentPerson = this.addressList.find(v=>v.is_default=='1')
} else {
currentPerson = this.addressList[0]
}
person.id = currentPerson.id
person.id_number = currentPerson.id_number
person.name = currentPerson.name
person.user_id = currentPerson.user_id
person.tel = currentPerson.tel
person.age = currentPerson.age
person0.id = currentPerson.id
person0.id_number = currentPerson.id_number
person0.name = currentPerson.name
person0.user_id = currentPerson.user_id
person0.tel = currentPerson.tel
person0.age = currentPerson.age
}
this.setDefault = true
}
})
},
// 出行人弹窗
changeAddressPopup(type, confirm) {
if (confirm) {
// 赋值
this.currentPerson.id = this.addressSelect.id
this.currentPerson.name = this.addressSelect.name
this.currentPerson.id_number = this.addressSelect.id_number
this.currentPerson.tel = this.addressSelect.tel
this.currentPerson.user_id = this.addressSelect.user_id
this.currentPerson.age = this.addressSelect.age
}
if (type == 'open') this.$refs.addressPopup.open('bottom');
else this.$refs.addressPopup.close();
this.$forceUpdate();
},
// 选中出行人
seldThisAddress(item){
if (this.addressSelect.id == item.id) {
this.addressSelect = {}
} else {
if (this.currentPersonIds.includes(item.id)&&item.id!=this.currentPerson.id) {
return
} else {
this.addressSelect = item
}
}
},
// 表单上选择点击出行人
personClick (person, sku) {
// 一证一票
if (sku.is_real_name) {
let personHave = sku.selPeople.find(v=>v.id == person.id)
if (personHave) {
for(let key in personHave) {
personHave[key] = null
}
} else {
for(let p of sku.selPeople) {
if (!p.id) {
p.id = person.id
p.id_number = person.id_number
p.name = person.name
p.user_id = person.user_id
p.tel = person.tel
p.age = person.age
break
}
}
}
} else {
if(sku.selPerson.id == person.id) {
sku.selPerson.id = null
sku.selPerson.id_number = null
sku.selPerson.name = null
sku.selPerson.user_id = null
sku.selPerson.tel = null
sku.selPerson.age = null
} else {
sku.selPerson.id = person.id
sku.selPerson.id_number = person.id_number
sku.selPerson.name = person.name
sku.selPerson.user_id = person.user_id
sku.selPerson.tel = person.tel
sku.selPerson.age = person.age
}
}
},
removePerson (person) {
for(let key in person) {
person[key] = null
}
},
clearTel (data) {data.tel = ''},
// 出行人新增弹窗
changeAddressAddPopup(type, item) {
if (type == 'open') {
this.addressTitle = '添加出行人'
if (item.id) { this.addressTitle = '编辑出行人' }
this.$refs.addressAddPopup.open('bottom');
this.$nextTick(()=>{
this.$refs.addressAddVueRef.init(item)
})
}
else {this.$refs.addressAddPopup.close();}
this.$forceUpdate();
},
// 保存地址
async saveAddress () {
let res = await this.$refs.addressAddVueRef.submit()
if (res && res.code == 1) {
this.getAddressList();
this.changeAddressAddPopup('close')
}
},
/*---------------------------出行人结束-----------------------------------*/
// 减少数量
delNumber(skuItem) {
if (skuItem.buyNum <= 0) {
return
}
if (skuItem.id == this.sInfo.id && skuItem.buyNum<=1) {
return
}
skuItem.buyNum -= 1
skuItem.selPeople.pop()
this.$store.commit("choseCoupon","");
this.coupon = ''
if (skuItem.buyNum == 0) {
skuItem.selPerson.id = null
skuItem.selPerson.id_number=null
skuItem.selPerson.name=null
skuItem.selPerson.tel=null
skuItem.selPerson.user_id=null
skuItem.selPerson.age=null
}
this.calBuyMultiple()
},
// 增加数量
addNumber(skuItem) {
skuItem.buyNum += 1
// if(this.max_num && this.buyNum > this.max_num){
// this.buyNum = this.max_num
// this.$toast("本产品单笔限购"+this.max_num+"份")
// }
if (Array.isArray(skuItem.selPeople)) {
skuItem.selPeople.push({
id:null,id_number:null,name:null,
tel:null,user_id:null,age:null,
})
} else {
skuItem.selPeople = [{
id:null,id_number:null,name:null,
tel:null,user_id:null,age:null,
}]
}
this.$store.commit("choseCoupon","");
this.coupon = ''
this.calBuyMultiple()
},
// 计算总价
total() {
let price = 0
let allPrice = 0
this.pInfo.specifications.forEach(v=>{
allPrice+= v.price*v.buyNum
})
this.allprice = allPrice
if (this.coupon) {
if (this.coupon.percent == 0) {
if (this.coupon.discounts>allPrice) {
price =0
}else{
price = allPrice - (this.coupon.discounts)
}
} else{
price = allPrice - allPrice * (this.coupon.percent/100)
}
} else {
price = allPrice
}
return price < 0 ? 0 : (price/100).toFixed(2)
},
// 判断是否买多个sku
calBuyMultiple () {
this.skuBuyMultiple = this.pInfo.specifications.slice(1).some(v=>v.buyNum>0)
},
// 预定须知
showpopRule(flag, item) {
if (item) {
this.skuInfo = item
}
if (flag) {
this.$refs.popupRule.open('bottom');
} else {
this.$refs.popupRule.close();
}
},
/*---------------------------价格日历-----------------------------------*/
// 选择列表规格
changeSku() {
// this.getPriceCal(this.sInfo.id,this.pInfo.id)
this.openPop()
},
openCalendar () {
this.calendarParam = {
startDate: (this.allSeldDate.find(v=>v.store>0) || {}).date,
endDate: (this.allSeldDate[this.allSeldDate.findLastIndex(v=>v.store>0)]||{}).date,
selected: this.allSeldDate.filter(v=>v.store>0).map(v=>{
return {
date: v.date,
info: '¥'+v.money/100,
notNeedDot:true,
}
})
}
this.$refs.calendar.open();
},
// 获取价格日历列表
getPriceCal(skuId, goodsId) {
this.Post({
specifications_id: skuId,
goods_id: goodsId,
limit: 60
}, '/api/goods/getPriceCalendarListBySpecifications').then(res => {
this.allSeldDate = res.data || []
this.seldDateIndex = this.allSeldDate.findIndex(item => item.store != 0)
this.getTimeStock(this.allSeldDate[this.seldDateIndex].date)
this.openPop()
})
},
// 获取规格分时库存
getTimeStock(date) {
this.Post({
specifications_id: this.sInfo.id,
date: date,
}, '/api/goods/getTimeStock').then(res => {
if (Array.isArray(res.data)) {
this.timesArr = res.data || []
this.seldTimeIndex = -1
}
if (res.data.length > 0) {
this.seldTimeIndex = this.timesArr.findIndex(item => item.stock_number > 0)
}
// if (res.data.length > 0) {
// this.timesArr = res.data || []
// this.seldTimeIndex = this.timesArr.findIndex(item => item.stock_number > 0)
// }
})
},
// 选择日期
clickTab(item, index) {
if (item.store>0) {
this.seldDateIndex = index
this.getTimeStock(item.date)
}
},
// 选择时段
changeTime(item, index) {
if(item.stock_number > 0) {
this.seldTimeIndex = index
}
},
confirmCalendar (val) {
let index = this.allSeldDate.findIndex(v=>v.date == val.fulldate)
if (index>=0) {
this.clickTab(this.allSeldDate[index],index)
}
},
closePopup() {
this.$refs.popup.close()
},
openPop(){
this.$refs.popup.open()
},
addBuyCard () {
// 如果是分时,未选择分时
if(this.sInfo.is_time_stock && this.seldTimeIndex < 0) {
uni.showToast({title:'请选择分时',icon:'none'})
return;
}
this.showDate = {
date: ((this.allSeldDate[this.seldDateIndex])||{}).date,
startTime: (this.timesArr[this.seldTimeIndex]||{}).start_time,
endTime: (this.timesArr[this.seldTimeIndex]||{}).end_time
}
this.closePopup()
//todo 请求接口重新获取 将页面数据全部重置
this.pInfo.specifications.forEach(v=>{
v.buyNum = 0;v.selPeople = [];v.selPerson = {}
v.is_card = Number(v.is_card);
v.is_real_name = Number(v.is_real_name)
})
this.pInfo.specifications[0].buyNum = 1
let date = this.allSeldDate[this.seldDateIndex].date
for(let sku of this.pInfo.specifications) {
sku.selPeople = [
{
id:null,id_number:null,name:null,
tel:null,user_id:null,age:null,
},
]
sku.selPerson = {
id:null,id_number:null,name:null,tel:null,user_id:null,age:null,
}
let res = this.initPriceCal(sku.id)
if (res.code === 1) {
sku.price = res.money
sku.store = res.store
}
}
},
/*---------------------------价格日历-----------------------------------*/
order() {
let use_date = this.allSeldDate[this.seldDateIndex].date
let start_time =(this.timesArr[this.seldTimeIndex]||{}).start_time
let end_time = (this.timesArr[this.seldTimeIndex]||{}).end_time
let goods = []
// 设置参数
let canSubmit = true
this.pInfo.specifications.filter(v=>v.buyNum>0).forEach(sku=>{
if (!sku.is_card) {
if (!this.IsTel(sku.selPerson.tel)) {
uni.showToast({
title:'请输入正确的手机号',
icon:'none'
})
canSubmit = false
}
let param = {
specifications_id: sku.id,
num: sku.buyNum,
// contact_id: sku.selPeople.filter(v=>v.id).map(v=>v.id),
date: use_date,
start_time: start_time||'',
end_time: end_time||'',
reserve_mobile: sku.selPerson.tel,
}
goods.push(param)
} else {
if (sku.is_real_name) {
if (sku.selPeople.some(v=>!v.id)) {
uni.showToast({
title:'请选择出行人',
icon:'none'
})
canSubmit = false
}
for(let v of sku.selPeople) {
let judegRes = this.judegeAgeLimit(sku, v)
if (!judegRes) {
uni.showToast({
title:'出行人年龄信息不符合使用限制',
icon:'none'
})
canSubmit = false
break;
}
}
let param = {
specifications_id: sku.id,
num: sku.buyNum,
contact_id: sku.selPeople.filter(v=>v.id).map(v=>v.id),
date: use_date,
start_time: start_time,
end_time: end_time,
}
goods.push(param)
} else {
if (!sku.selPerson.id) {
uni.showToast({
title:'请选择出行人',
icon:'none'
})
canSubmit = false
}
let judegRes = this.judegeAgeLimit(sku, sku.selPerson)
if (!judegRes) {
uni.showToast({
title:'出行人年龄信息不符合使用限制',
icon:'none'
})
canSubmit = false
}
let param = {
specifications_id: sku.id,
num: sku.buyNum,
contact_id: [sku.selPerson.id],
date: use_date,
start_time: start_time,
end_time: end_time,
}
goods.push(param)
}
}
})
console.log(goods)
if (!canSubmit) {
return
}
let data = {
goods: goods,
coupon: this.coupon ? this.coupon.id : "",
// reserve_name: this.reserve_name,
// reserve_phone: this.reserve_phone
// remark: this.remark
}
console.log('data数据',data);
this.Post({
method: 'POST',
data: JSON.stringify(data)
}, '/api/order/place').then(res => {
if (res.code == 1) {
uni.removeStorageSync('ticketOrder')
console.log(res.data.order_id);
let order_id = res.data.order_id
this.$store.commit("choseCoupon", "");
this.Post({
order_id: order_id,
type: "miniprogram",
platform: 'miniprogram'
}, '/api/pay/unify').then(res => {
if (res.data) {
uni.requestPayment({
nonceStr: res.data.nonceStr,
package: res.data.package,
paySign: res.data.paySign,
signType: res.data.signType,
timeStamp: res.data.timeStamp,
complete() {
uni.navigateTo({
url: '/subPackages/order/trades'
})
}
})
}
})
}
})
}
}
}
</script>
<style scoped lang="scss">
*{
box-sizing: border-box;
}
.bg{
min-height: 100vh;
padding: 20rpx;
padding-bottom: 200rpx;
background-color: rgb(247, 247, 247);
}
.top-box1 {
width: 100%;
background: #FFFFFF;
border-radius: 13rpx;
padding: 32rpx 20rpx;
display: flex;
justify-content: space-between;
align-items: center;
font-weight: 500;
font-size: 25rpx;
color: #999999;
.top-left {
display: flex;
flex-direction: column;
justify-content: space-between;
flex: 1;
width: 1rpx;
.title{
font-weight: bold;
font-size: 36rpx;
color: #000000;
}
}
.top-edit{
font-family: PingFang SC;
font-weight: bold;
font-size: 27rpx;
color: #999999;
}
}
.tickets-box{
background: #FFFFFF;
border-radius: 13rpx;
width: 100%;
margin: 20rpx 0;
.num-box {
display: flex;
justify-content: space-between;
flex-direction: column;
padding: 40rpx 20rpx;
border-bottom: 1px solid #CCCCCC;
.num-left {
width: 100%;
box-sizing: border-box;
display: flex;
justify-content: space-between;
.left-title {
font-family: PingFang SC;
font-weight: bold;
font-size: 31rpx;
color: #000000;
width: 450rpx;
}
.left-price {
font-weight: bold;
font-size: 36rpx;
color: #C3282E;
padding-right: 27rpx;
}
.left-price::before {
font-size: 24rpx;
content: '';
}
}
.num-subtitle {
display: flex;
align-items: center;
width: 100%;
font-family: PingFang SC;
font-weight: 500;
font-size: 23rpx;
color: #666666;
}
.num-right {
display: flex;
align-items: center;
font-weight: bold;
font-size: 29rpx;
color: #000000;
text-align: center;
.num-span {
width: 67rpx;
line-height: 63rpx;
}
.btn-num {
width: 46rpx;
height: 46rpx;
line-height: 40rpx;
background: #515150;
border-radius: 50%;
font-weight: 500;
font-size: 45rpx;
font-size: 34rpx;
color: #FFFFFF;
}
.btn-num.disabled{
color: #999999;
background: #E8E8E8;
}
}
}
.buyMore{
height: 118rpx;
font-family: PingFang SC;
font-weight: bold;
font-size: 31rpx;
color: #000000;
display: flex;
align-items: center;
justify-content: space-between;
padding:0 20rpx;
.buyMore-btn{
height: 47rpx;
width: 148rpx;
text-align: center;
border-radius: 23rpx;
border: 1px solid #515150;
font-family: PingFang SC;
font-weight: bold;
font-size: 25rpx;
color: #515150;
line-height: 45rpx;
}
}
}
.people-box{
width: 100%;
background: #FFFFFF;
border-radius: 13rpx;
.people-box-title{
font-family: PingFangSC;
font-weight: 600;
font-size: 31rpx;
color: #000000;
padding: 42rpx 18rpx;
border-bottom: 1px solid #CCCCCC;
}
.person-scroll{
display: flex;
flex-wrap: nowrap;
position: relative;
padding-bottom: 50rpx;
overflow-y: auto;
.person-item-container{
width: 167rpx;
height: 73rpx;
background: #F1F1F1;
border-radius: 11rpx;
font-family: PingFangSC;
font-weight: 400;
font-size: 27rpx;
color: #000000;
padding: 2rpx;
margin-right: 14rpx;
position: relative;
&.active{
background: #515150
}
.disabled{
font-weight: 400;
font-size: 23rpx;
color: #999999;
}
.selected{
width: 28rpx;
height: 28rpx;
background: #515150;
border-radius: 10rpx 0rpx 10rpx 0rpx;
position: absolute;
bottom: 0;
right: 0;
display: flex;
justify-content: center;
line-height: 28rpx;
}
}
.person-item{
width: 163rpx;
height: 69rpx;
border-radius: 11rpx;
background: #F1F1F1;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
}
.people-box-sku{
width: 100%;
background: #FFFFFF;
border-radius: 18rpx;
padding: 0rpx 20rpx;
.sku-title{
font-weight: 400;
font-size: 29rpx;
color: #060001;
padding-bottom: 25rpx;
}
.person-info{
display: flex;
align-items: center;
justify-content: space-between;
font-weight: 400;
font-size: 27rpx;
color: #000000;
margin-bottom: 33rpx;
.person-info-detail{
font-weight: 400;
font-size: 24rpx;
color: #666666;
width: 400rpx;
}
}
.person-need{
width: 100%;
height: 80rpx;
background: #F2F2F2;
border-radius: 13rpx;
display: flex;
align-items: center;
justify-content: space-between;
font-family: PingFang SC;
font-weight: 500;
font-size: 27rpx;
color: #515150;
padding: 0 20rpx;
}
.person-item-more{
width: 110rpx;
height: 73rpx;
background: #F2F2F2;
border-radius: 11rpx;
text-align: center;
font-family: PingFang SC;
font-weight: 500;
font-size: 29rpx;
color: #515150;
line-height: 73rpx;
position: absolute;
right: 0;
top: 0;
}
}
}
.people-popup {
padding: 26rpx;
min-height: 800rpx;
.top-box {
height: 80rpx;
.top {
position: fixed;
left: 0;
right: 0;
color: #000;
height: 80rpx;
font-size: 0;
overflow: hidden;
padding: 0 26rpx;
text {
text-align: left;
font-size: 35rpx;
font-weight: 400;
color: #000000;
}
.confirm {
font-weight: 400;
color: #000000;
}
}
}
.popup-list {
height: 666rpx;
overflow: scroll;
.popup-item {
border-radius: 12rpx;
padding: 2rpx;
margin-top: 24rpx;
font-size: 24rpx;
color: #333333;
font-weight: 400;
background-color: #ffffff;
.item-top {
border-radius: 12rpx;
padding: 30rpx 40rpx;
background-color: #ffffff;
img {
color: #666666;
width: 40rpx;
height: 40rpx;
}
.name {
overflow: hidden;
font-family: PingFang SC;
font-weight: 400;
font-size: 32rpx;
text {
color: #666;
font-size: 25rpx;
}
.tag {
padding: 0 8rpx;
height: 32rpx;
border-radius: 7rpx;
line-height: 30rpx;
text-align: center;
font-size: 23rpx;
font-family: PingFang SC;
font-weight: 500;
color: #ffffff;
background: #515150;
margin-left: 10rpx;
}
}
.com-flex-start {
margin: 0 0 30rpx;
}
.subtitle {
font-weight: 400;
flex: 1;
text-align: left;
margin-top: 33rpx;
color: #666666;
font-size: 25rpx;
.mobile {
margin-bottom: 36rpx;
}
}
.status {
width: 40rpx;
height: 40rpx;
line-height: 40rpx;
border-radius: 50%;
text-align: center;
box-sizing: border-box;
img {
width: 27rpx;
height: 21rpx;
}
}
.statuss {
background: linear-gradient(90deg, #fa2b66, #ff9834);
border: none;
}
.noSelect {
border: 1rpx solid #999999;
}
}
.item-site {
color: #666666;
display: flex;
align-items: center;
padding: 36rpx 0;
view {
width: 23rpx;
height: 23rpx;
margin-right: 10rpx;
border: 1rpx solid #999999;
border-radius: 50%;
view {
width: 8rpx;
height: 8rpx;
background: #000000;
border-radius: 50%;
margin: auto;
}
}
}
}
.popup-item.active{
background: #515150
}
.popup-item.disabled{
.item-top {
background-color: #CCC;
}
}
}
.button {
text-align: center;
width: 100%;
height: 80rpx;
line-height: 80rpx;
background-color: #ffffff;
border-radius: 40rpx;
font-family: PingFang SC;
font-weight: 400;
font-size: 33rpx;
color: #000000;
}
.add-edit-content{
background: #FFFFFF;
border-radius: 13rpx;
min-height: 800rpx;
}
}
.tickets-container {
width: 100%;
background: #fff;
height: 120rpx;
margin-top: 22rpx;
.order-title {
margin: 31rpx 0 31rpx 30rpx;
font-size: 31rpx;
font-family: PingFang SC;
font-weight: bold;
color: #000000;
}
.coupon-price {
color:#DD0000;
font-size: 30rpx;
font-weight: bold;
}
}
.btn-list {
width: 100%;
height: 166rpx;
background: #ffffff;
box-shadow: 0rpx -3rpx 9rpx 1rpx rgba(227, 229, 232, 0.5);
display: flex;
position: fixed;
bottom: 0;
left: 0;
right:0;
padding: 20rpx 50rpx;
align-items: center;
justify-content: space-between;
.btn {
width: 250rpx;
height: 80rpx;
background: #C3282E;
border-radius: 43rpx;
text-align: center;
line-height: 80rpx;
font-size: 32rpx;
font-family: PingFang SC;
font-weight: bold;
color: #FFFFFF;
}
.price-box {
display: flex;
align-items: baseline;
.text {
font-size: 28rpx;
font-family: PingFangSC-Regular, PingFang SC;
font-weight: 400;
color: #393b3e;
}
.price {
margin-left: 15rpx;
font-size: 48rpx;
font-weight: bold;
color: #C3282E;
&:before {
content: '';
display: inline-block;
color: #C3282E;
font-size: 24rpx;
}
}
.post-text {
margin-left: 15rpx;
color: #C3282E;
font-size: 24rpx;
}
}
}
.popup-content-date {
background-color: white;
padding: 0rpx 28rpx 166rpx;
height: 70vh;
border-radius: 20rpx 20rpx 0 0 ;
.popup-content-title{
font-family: PingFang SC;
font-weight: bold;
font-size: 37rpx;
color: #000000;
padding: 39rpx 0;
display: flex;
align-items: center;
border-bottom: 1px solid #CCCCCC;
}
// 预定须知
.content{
padding-top: 48rpx;
overflow-y: auto;
}
.order-popup-detail{
.sku-title{
padding: 48rpx 0 26rpx;
font-family: PingFangSC;
font-weight: 500;
font-size: 31rpx;
color: #000000;
}
}
.dateMore{
width: 120rpx;
height: 133rpx;
background: white;
border-radius: 10rpx;
border: 1px solid #000000;
font-family: PingFang SC;
font-weight: 500;
font-size: 27rpx;
color: #000000;
display: flex;
flex-direction: column;
align-items: center;
justify-content: space-around;
flex-shrink: 0;
padding: 6rpx 0;
position: absolute;
bottom: 0;
right: 0;
}
.date-content{
width: 100%;
display: flex;
overflow-y: auto;
position: relative;
padding-right: 140rpx;
.item{
width: 120rpx;
height: 133rpx;
border-radius: 10rpx;
border: 1px solid #000000;
margin-right: 24rpx;
font-family: PingFang SC;
font-weight: 500;
font-size: 27rpx;
color: #000000;
display: flex;
flex-direction: column;
align-items: center;
justify-content: space-around;
flex-shrink: 0;
padding: 6rpx 0;
}
.item.active{
background: #515150;
color: white;
border: none;
.price{color: white;}
}
.item.disabled{
color: #666;
border-color: #CCC;
}
.price{
color: #C3282E;
}
}
.date-content::-webkit-scrollbar{
display: none;
}
}
.calendar-edit{
.time-box {
display: flex;
justify-content: space-between;
flex-wrap: wrap;
max-height: 340rpx;
overflow-y: auto;
.time-item {
width: 48%;
height: 60rpx;
border-radius: 10rpx;
text-align: center;
font-size: 34rpx;
margin-bottom: 23rpx;
font-family: PingFangSC;
font-weight: 400;
font-size: 25rpx;
border: 1px solid #333333;
line-height: 58rpx;
color: #000;
}
.time-active {
background: #515150;
color: white;
border: none;
}
.time-disable {
color: #666666;
border-color: #CCC;
}
}
.sku-bottom {
width: 100%;
height: 166rpx;
background: #FFFFFF;
box-shadow: 0rpx -3rpx 8rpx 0rpx rgba(71,71,71,0.1);
display: flex;
justify-content: space-between;
align-items: center;
box-sizing: border-box;
padding: 50rpx 50rpx 85rpx;
font-family: PingFang SC;
font-weight: 500;
font-size: 28rpx;
color: #393B3E;
position: absolute;
bottom: 0;
left: 0;
right: 0;
.bottom-price {
font-size: 48rpx;
font-weight: bold;
color: #C3282E;
}
.bottom-price::before {
font-size: 24rpx;
content: '';
}
.bottom-btn {
width: 250rpx;
height: 80rpx;
background: #C3282E;
border-radius: 40rpx;
font-size: 32rpx;
text-align: center;
font-weight: bold;
color: #FFFFFF;
line-height: 78rpx;
}
}
}
.coupon-btn {
color: #999999;;
display: flex;
align-items: center;
.select {
display: block;
width: 153rpx;
height: 40rpx;
background: #C3282E;
border-radius: 9rpx;
font-weight: 500;
font-size: 24rpx;
color: #FFFFFF;
text-align: center;
line-height: 40rpx;
font-family: PingFang SC;
margin-right: 20rpx;
}
}
/deep/ .uni-calendar-item--extra{
color: #333 !important;
}
/deep/ .uni-calendar-item--isDay{
background: #12293C !important;
border-radius: 50%;
.uni-calendar-item--extra{
color: white !important;
}
}
/deep/ .uni-calendar-item--checked{
background: #12293C !important;
border-radius: 50%;
.uni-calendar-item--extra{
color: white !important;
}
}
</style>