完善订单预约

This commit is contained in:
wangxiaowei
2025-12-06 19:39:25 +08:00
parent a5a81f869e
commit becadb1d0c
3 changed files with 441 additions and 91 deletions

View File

@ -10,9 +10,9 @@
<!-- 费用明细弹窗 -->
<Popup :show="billPopup" :width='750' :padding="0" type="bottom" backgroundColor="#FBFBFB" radius="32rpx 32rpx 0 0">
<view class="ww100 box-s-b pop-improt typeof pr time-popup">
<image style="width: 64rpx;height: 64rpx;position: absolute; top: 26rpx;right: 30rpx;" src="@/static/icon/close2.png" mode="" @click="closeBillPopup"></image>
<image style="width: 64rpx;height: 64rpx;position: absolute; top: 24rpx;right: 30rpx;" src="@/static/icon/close2.png" mode="" @click="closeBillPopup"></image>
<view class="d-c-c pt42" style="margin-top: 38rpx;">
<view class="d-c-c pt42" style="padding-top: 38rpx;">
<text class="f34 fb">费用明细</text>
</view>
@ -128,7 +128,7 @@
<view class="split-line"></view>
<!-- 网球场——场馆信息 -->
<view class="info-block mx-30rpx" v-if="typeId == 1">
<view class="info-block mx-30rpx" v-if="typeId == 1" style="padding-bottom: 180rpx;">
<view class="tag-block">
<view class="tag-title">立即预定</view>
<view class="tag">
@ -141,61 +141,41 @@
<view class="date-block">
<view class="">
<view class="date1-block">
<view class="date1-block-item bg-f7f7f7">
<view class="">周三</view>
<view class="">12/03</view>
</view>
<view class="date1-block-item bg-365A9A text-fff">
<view class="">周三</view>
<view class="">12/03</view>
</view>
<view class="date1-block-item bg-f7f7f7">
<view class="">周三</view>
<view class="">12/03</view>
</view>
<view class="date1-block-item bg-f7f7f7">
<view class="">周三</view>
<view class="">12/03</view>
<view class="date1-block-item bg-f7f7f7" :class="currentWeek == index ? 'bg-365A9A text-fff' : ''" v-for="(item, index) in weekList" :key="index" @click="selectWeek(item, index, item)">
<view>{{ item.value[0] }}</view>
<view>{{ item.value[1] }}</view>
</view>
</view>
</view>
</view>
<!-- <view class="d-f">
<view class="tab" v-for="(item, index) in tab" :key="index"
:style="currentTab === item.type ? 'background-color: #F0F5FF; color: #365A9A;' : ''"
@tap="handleChangeTab(item)" >
{{ item.name }}
</view>
</view>
<view class="">
<view class="" v-for="(item, index) in venueRoomLists" :key="index">
<view class="d-b-c">
<view class="">
<image style="width: 200rpx;height: 200rpx;border-radius: 10rpx; margin-right: 32rpx;" :src="item.img" mode=""></image>
<view class="">
<!-- 场馆时间 -->
<view class="d-f">
<view class="cg-time-block">
<view class="cg-time" v-for="(item, index1) in timeList" :key="index1">
{{ item.t }}
</view>
</view>
<view class="flex-1">
<view class="cg-name">{{ item.title }}</view>
<view class="d-b-c">
<view class="">
<price-format color="#FF5951" :subscript-size="26" :first-size="38" :second-size="26" :price="item.price"></price-format>
</view>
<view class="reserve-btn" @tap="heandleToReserve(item.id)">
预定
<view class="d-f cg-info" style="width: 800rpx; overflow-x: auto;">
<view style="width: 120rpx;margin-right: 10rpx;" v-for="(item2, index2) in cdList" :key="index2">
<view class="" style="margin-bottom: 6rpx; text-align: center;">{{ item2.title }}</view>
<view
v-for="(item3, index3) in item2.time" :key="index3"
@click="handleSelectTime(item2.title, item3.t, item3.status, item2.room_id)"
class="cg-info-time" :class="[
item3.status == 1
? 'cg-info-time-none'
: selectedTime[item2.title] && selectedTime[item2.title].includes(item3.t)
? 'cg-info-time-select'
: 'cg-info-time-normal'
]" >
{{ item3.price }}
</view>
</view>
</view>
</view>
<view class="d-f a-i-c" style="margin-top: 16rpx;">
<view class="time-block" v-for="(item, index) in 17" :key="index">
<view class="time-block-text font-400 text-20rpx leading-28rpx" :style="index === 1 ? 'color:#C9C9C9;' : ''">{{ item + 5 }}</view>
<view class="time-block-box h-12rpx rounded-6rpx mt-4rpx" :style="index === 1 ? 'color:#C9C9C9;' : ''"></view>
</view>
</view>
<view class="line"></view>
</view>
</view> -->
</view>
</view>
<!-- 篮球场场馆信息 -->
@ -223,7 +203,7 @@
</view>
</view>
<view class="price" v-if="showPrice && typeId == 2">
<view class="price">
<view class="line"></view>
<view class="d-b-c price-block">
<view class="d-f d-c j-c-b">
@ -292,12 +272,21 @@ export default {
total: 0 // 总价
},
billPopup: false,
weekList: [],
cdList: [],
timeList: [],
currentWeek: 0,
selectedTime: [],
selectedWeekDay: '',
selectedReserveTime: [],
countSelectedTime: 0,
submitting: false // 防止重复提交
};
},
onLoad(args) {
this.id = args.id || 0
this.typeId = args.typeId || 1
this.typeId = args.typeId || 1 // 网球场馆1 篮球场馆2
this.getData()
this.handleGetVenueRoom()
@ -329,6 +318,9 @@ export default {
}
}
)
// 获取预定时间
self.getReserveTime()
},
// 获取场馆包间列表
@ -346,7 +338,6 @@ export default {
function (res) {
if (res.code) {
self.venueRoomLists = res.data.lists
console.log("🚀 ~ self.venueRoomLists:", self.venueRoomLists)
self.loadding = false;
}
}
@ -392,19 +383,23 @@ export default {
// 确认选择时间
confirmSelectTime(e) {
this.date = e.value
let self = this
// 计算费用明细
uni.showLoading({
title: '加载中'
});
// 计算费用明细
},
// 计算费用明细
totalPrice() {
let self = this
self._post(
'ground.ground/countPrice',
{
app_id: self.getAppId(),
room_id: self.id,
nums: 4,
nums: this.countSelectedTime,
type_id: self.venue.type_id,
},
function(res) {
@ -426,7 +421,6 @@ export default {
self.loadding = false;
}
)
},
// 显示费用明细
@ -442,19 +436,208 @@ export default {
// 篮球场-立即预约
toReserve() {
if (!this.date) {
let self = this
if (self.submitting) {
uni.showToast({
title: '请选择预约时间',
title: '正在提交,请勿重复操作',
icon: 'none'
});
return;
}
// 一进来就锁定,彻底防止高频点击
self.submitting = true;
if (self.typeId == 1) {
if (self.selectedReserveTime.length === 0) {
uni.showToast({
title: '请选择预约时间',
icon: 'none'
});
self.submitting = false;
return;
}
uni.showLoading({
title: '提交中',
mask: true,
});
try {
// 订单提交
self._post(
'order.groundOrder/submitStoreOrder',
{
app_id: self.getAppId(),
ground_id: self.id,
room_list: JSON.stringify(self.selectedReserveTime),
},
function(res) {
self.loadding = false;
self.submitting = false;
if(res.code) {
uni.navigateTo({
url: `/bundle/reserve/confirm?venueId=${self.venue.id}&roomId=${self.id}&typeId=${self.typeId}&orderId=${res.data.lists.id}`
});
}
}
)
} catch (error) {
self.submitting = false;
console.error('订单提交失败:', error);
uni.showToast({
title: '订单提交失败,请重试',
icon: 'none'
});
self.loadding = false;
}
} else {
if (!self.date) {
uni.showToast({
title: '请选择预约时间',
icon: 'none'
});
self.submitting = false;
return;
}
uni.navigateTo({
url: `/bundle/reserve/confirm?venueId=${self.venue.id}&roomId=${self.id}&typeId=${self.typeId}`
});
self.submitting = false;
}
uni.navigateTo({
url: `/bundle/reserve/confirm?venueId=${this.venue.id}&roomId=${this.venueRoomLists[this.selectedRoomIndex].id}&date=${this.date}&typeId=${this.venue.type_id}`
});
},
handleSelectTime(title, time, status) {
// if (status == 1) {
// return;
// }
// // 多选逻辑selectedTime为对象按title区分
// if (!this.selectedTime[title]) {
// this.$set(this.selectedTime, title, []);
// }
// const idx = this.selectedTime[title].indexOf(time);
// if (idx > -1) {
// // 已选中则取消
// this.selectedTime[title].splice(idx, 1);
// } else {
// // 未选中则添加
// this.selectedTime[title].push(time);
// }
// this.countSelectedTime = Object.values(this.selectedTime).reduce((acc, times) => acc + times.length, 0);
// this.totalPrice()
// // 生成 room_list 数组格式weekList[this.currentWeek]?.value?.join('') || '';
// const day_title = this.weekList[this.currentWeek]?.day || '';
// // 遍历所有已选时间,生成 room_list
// const room_list = [];
// Object.keys(this.selectedTime).forEach(roomTitle => {
// const rid = this.cdList.find(cd => cd.title === roomTitle)?.id || 1;
// this.selectedTime[roomTitle].forEach(t => {
// // t 可能是 '09:00-10:00' 或 '09:00', 需拆分
// let start_time = t, end_time = '';
// if (t.includes('-')) {
// [start_time, end_time] = t.split('-');
// } else {
// start_time = t;
// // 假设每个时间段为1小时自动+1小时
// const [h, m] = t.split(':');
// const nextH = (parseInt(h, 10) + 1).toString().padStart(2, '0');
// end_time = `${nextH}:${m}`;
// }
// room_list.push({
// room_id: rid,
// // day_time,
// // day_title,
// start_time,
// end_time,
// hours: '1'
// });
// });
// });
// this.selectedReserveTime = room_list;
if (status == 1) {
return;
}
// 多选逻辑selectedTime为对象按title区分
if (!this.selectedTime[title]) {
this.$set(this.selectedTime, title, []);
}
const idx = this.selectedTime[title].indexOf(time);
if (idx > -1) {
// 已选中则取消
this.selectedTime[title].splice(idx, 1);
} else {
// 未选中则添加
this.selectedTime[title].push(time);
}
this.countSelectedTime = Object.values(this.selectedTime).reduce((acc, times) => acc + times.length, 0);
this.totalPrice()
// 遍历所有已选时间,生成 room_list
const room_list = [];
Object.keys(this.selectedTime).forEach(roomTitle => {
const roomId = this.cdList.find(cd => cd.title === roomTitle)?.room_id;
this.selectedTime[roomTitle].forEach(t => {
// t 可能是 '09:00-10:00' 或 '09:00', 需拆分
let start_time = t, end_time = '';
if (t.includes('-')) {
[start_time, end_time] = t.split('-');
} else {
start_time = t;
// 假设每个时间段为1小时自动+1小时
const [h, m] = t.split(':');
const nextH = (parseInt(h, 10) + 1).toString().padStart(2, '0');
end_time = `${nextH}:${m}`;
}
room_list.push({
room_id: roomId,
day_time: this.selectedWeekDay,
day_title: this.selectedWeekTimes,
start_time,
end_time,
});
});
});
console.log("🚀 ~ room_list:", room_list)
this.selectedReserveTime = room_list;
console.log('🚀 ~ room_list:', this.selectedReserveTime);
},
selectWeek(item, index) {
let self = this
self.currentWeek = index
self.selectedWeekDay = item.value[1] + '' + item.value[0]
self.selectedWeekTimes = item.times
self.selectedTime = []
self.getReserveTime()
},
getReserveTime() {
let self = this;
self._post(
'ground.ground/getSchedule',
{
app_id: self.getAppId(),
ground_id: self.id,
today: self.selectedWeekTimes
},
function (res) {
if (res.code) {
self.cdList = res.data.lists1
self.weekList = res.data.lists2
self.timeList = res.data.lists3
// 初始化选择的时间
self.selectedWeekDay = res.data.lists2[0].value[1] + '' + res.data.lists2[0].value[0]
self.selectedWeekTimes = res.data.lists2[0].times
self.loadding = false
}
}
)
}
}
};
</script>
@ -471,6 +654,8 @@ page {
}
.info-block {
margin-top: 30rpx;
.info-title {
font-weight: bold;
font-size: 34rpx;
@ -850,4 +1035,56 @@ page {
}
}
.split-line {
height: 20rpx;
background-color: #F6F7F9;
margin-top: 30rpx;
margin-bottom: 28rpx;
}
.cg-time-block {
margin-top: 76rpx;
.cg-time {
font-size: 26rpx;
color: #303133;
height: 60rpx;
line-height: 60rpx;
border: 2rpx solid transparent;
margin: 4rpx;
}
}
.cg-info {
margin-left: 54rpx;
margin-top: 38rpx;
.cg-info-time {
margin: 4rpx;
width: 120rpx;
height: 60rpx;
text-align: center;
line-height: 60rpx;
border-radius: 8rpx;
font-size: 26rpx;
}
.cg-info-time-none {
background: #D4DAE6;
border: 2rpx solid #D4DAE6;
}
.cg-info-time-normal {
background: #F7F7F7;
border: 2rpx solid #E9ECF4;
color: #303133;
}
.cg-info-time-select {
background: #365A9A;
border: 2rpx solid #365A9A;
color: #fff;
}
}
</style>