Files
2025-12-06 19:39:25 +08:00

716 lines
24 KiB
Vue
Raw 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 style="padding-bottom: 200rpx;">
<!-- 费用明细弹窗 -->
<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>
<view class="d-c-c pt42">
<text class="f34 fb">费用明细</text>
</view>
<view class="bg-white bill-info">
<!-- 网球场 -->
<view v-if="typeId == 1">
<view class="title1 d-b-c">
<view>场地费</view>
<view>
<price-format color="#303133" :subscript-size="30" :first-size="30" :second-size="30" :price="bill.cdf.total"></price-format>
</view>
</view>
<view class="title2 d-b-c">
<view>场地费(¥{{ bill.cdf.price }}元/小时)</view>
<view>x{{ bill.cdf.nums }}</view>
</view>
</view>
<!-- 篮球场 -->
<view v-if="typeId == 2">
<view class="title1 d-b-c">
<view>使用费</view>
<view>
<price-format color="#303133" :subscript-size="30" :first-size="30" :second-size="30" :price="bill.cdf.total"></price-format>
</view>
</view>
<view class="title2 d-b-c">
<view>¥{{ bill.cdf.price }}元/人</view>
<view>x1</view>
</view>
</view>
<view style="margin-top: 52rpx;" v-if="typeId == 1">
<view class="title1 d-b-c">
<view>灯光费</view>
<view>
<price-format color="#303133" :subscript-size="30" :first-size="30" :second-size="30" :price="bill.dgf.total"></price-format>
</view>
</view>
<view class="title2 d-b-c">
<view>灯光费(¥{{ bill.dgf.price }}元/小时)</view>
<view>x{{ bill.dgf.nums }}</view>
</view>
</view>
<!-- 使用余额支付优惠的折扣 -->
<view style="margin-top: 52rpx;" v-if="bill.dis">
<view class="title1 d-b-c">
<view style="color: #4C9F44;">优惠</view>
<view>
<text style="margin-right: 6rpx;"> - </text>
<price-format color="#303133" :subscript-size="30" :first-size="30" :second-size="30" :price="bill.dis"></price-format>
</view>
</view>
</view>
<view class="line"></view>
<view class="title3 d-b-c">
<view>实付金额</view>
<view>
<price-format color="#303133" :subscript-size="30" :first-size="30" :second-size="30" :price="bill.total"></price-format>
</view>
</view>
</view>
<view class="price2 bg-white" style="margin: 0; padding: 56rpx 22rpx 42rpx;">
<view class="d-b-c price-block" style="margin: 0;">
<view class="d-f d-c j-c-b">
<view class="">
合计: <price-format color="#FF5951" :subscript-size="26" :first-size="40" :second-size="40" :price="bill.total"></price-format>
</view>
<view class="d-f j-c-c a-i-c" style="margin-top: 10rpx;" @click="closeBillPopup">
<view class="price-detail">费用明细</view>
<image style="width: 14rpx;height: 8rpx;margin-left: 10rpx;" src="@/static/icon/up.png" mode=""></image>
</view>
</view>
<view class="price-btn" @tap="toConfirm">立即支付<text class="" v-if="countSelectedTime > 0">{{countSelectedTime}}小时)</text></view>
</view>
</view>
</view>
</Popup>
<navbar title="确认订单"></navbar>
<!-- 预约信息 -->
<view class="bg-white box pr">
<view class="current"></view>
<view class="title">预约信息</view>
<template v-if="typeId == 1">
<view class="desc">场馆信息:{{ order.ground_name }}</view>
<view class="desc">活动日期:{{ order.day_time }}</view>
<view class="desc">预约时长:{{ order.hours }}小时</view>
<view class="desc">场地信息:</view>
<view class="desc" v-for="(item, index) in order.trade" :key="index">
<view class="fb">{{ index }}</view>
<view class="date-grid">
<view class="date-time-btn" v-for="(item2, index2) in item" :key="index2">
{{ item2.start_time }}-{{ item2.end_time }}
</view>
</view>
</view>
<!-- <view class="desc">
预约时间
{{ date && date.hour ? date.hour : '' }}:{{ date && date.minute ? date.minute : '' }}
</view> -->
</template>
<template v-if="typeId == 2">
<view class="desc">预约场地{{ room.title }}</view>
<view class="desc">
预约时间{{ basketballDate }}
</view>
<view class="desc">预约人数1</view>
</template>
</view>
<!-- 其他须知 -->
<view class="bg-white box pr mt20">
<view class="current"></view>
<view class="title">
其他须知
</view>
<template v-if="typeId == 1">
<view class="desc2">
<view class="dot"></view>
<view class="">17点前预约100元/小时</view>
</view>
<view class="desc2">
<view class="dot"></view>
<view class="">17点后需要加收灯光费120/小时</view>
</view>
</template>
<template v-if="typeId == 2">
<view class="desc2">
<view class="dot"></view>
<view class="">默认选择4小时注意闭馆时间</view>
</view>
</template>
</view>
<!-- 退订规则 -->
<view class="bg-white box pr mt20">
<view class="current"></view>
<view class="title">
退订规则
</view>
<view class="desc">
①开场前24小时退订可全款退款
</view>
<view class="desc">
②4小时开场前24小时退订收取50%手续费
</view>
<view class="desc">
③开场前4小时退订不予退款
</view>
</view>
<!-- 支付方式 -->
<view class="buy-checkout p-0-30">
<view>
<view :class="payType == 'wxpay' ? 'item active' : 'item'" @tap="payTypeFunc('wxpay')" style="padding-bottom: 10rpx;">
<view class="d-s-c">
<view class="icon-box d-c-c mr10"><span class="icon iconfont icon-weixin"></span></view>
<text class="key">微信支付</text>
</view>
<view class="icon-box d-c-c"><span class="icon iconfont icon-xuanze"></span></view>
</view>
<view :class="payType == 'balance' ? 'item active' : 'item'" @tap="payTypeFunc('balance')">
<view class="d-s-c">
<view class="icon-box d-c-c mr10"><span class="icon iconfont icon-yue"></span></view>
<text class="key">余额支付(剩余{{balance}})</text>
</view>
<view class="icon-box d-c-c"><span class="icon iconfont icon-xuanze"></span></view>
</view>
</view>
</view>
<!-- 立即预定 -->
<view class="price" v-if="showPrice">
<view class="line"></view>
<view class="d-b-c price-block">
<view class="d-f d-c j-c-b">
<view class="">
合计 <price-format color="#FF5951" :subscript-size="26" :first-size="40" :second-size="40" :price="bill.total"></price-format>
</view>
<view class="d-f j-c-c a-i-c" style="margin-top: 10rpx;" @tap="handleShowBill">
<view class="price-detail">费用明细</view>
<image style="width: 14rpx;height: 8rpx;margin-left: 10rpx;" src="@/static/icon/down.png" mode=""></image>
</view>
</view>
<view class="price-btn" @tap="toConfirm">立即支付<text class="" v-if="countSelectedTime > 0">{{countSelectedTime}}小时</text></view>
</view>
</view>
</view>
</template>
<script>
import navbar from '@/components/navbar.vue';
import Popup from '@/components/uni-popup.vue';
export default {
components: {
navbar,
Popup
},
data() {
return {
orderId: 0,
venueId: 0,
roomId: 0,
typeId: 1, // 网球场1 篮球场2
billPopup: false,
showPrice: true,
adding: true,
basketballDate: null,
venue: {},
room: {},
countSelectedTime: 0,
bill: {
cdf: {
nums: 0, // 场地费小时数
price: 0, // 场地费单价
total: 0 // 场地费总价
},
dgf: {
nums: 0, // 灯光数量
price: 0, // 灯光单价
total: 0 // 灯光总价
},
dis: 0, // 折扣优惠
total: 0 // 总价
},
payType: 'wxpay', // 支付方式 wxpay\balance
balance: 0,
order: {},
};
},
onLoad(args) {
this.orderId = args.orderId || 0;
this.venueId = args.venueId || 0;
this.roomId = args.roomId || 0;
this.typeId = args.typeId || 1;
this.basketballDate = args.date || null;
console.log("🚀 ~ this.date:", this.date)
this.getData();
},
methods: {
getData() {
let self = this;
uni.showLoading({
title: '加载中'
});
const reserveDate = uni.getStorageSync('reserveDate') || null
self.date = reserveDate
self.countSelectedTime = reserveDate && reserveDate.duration ? reserveDate.duration : 0
if (self.typeId == 2) {
self.countSelectedTime = 4
}
// 获取余额
self._post(
'user.user/userMoney',
{
app_id: self.getAppId(),
},
function (res) {
if (res.code) {
self.balance = res.data.balance
}
}
)
// 获取场馆详情
self._post(
'ground.ground/groundDetails',
{
app_id: self.getAppId(),
id: self.venueId,
latitude: uni.getStorageSync('latitude') || '',
longitude: uni.getStorageSync('longitude') || '',
},
function (res) {
if (res.code) {
self.loadding = false;
self.venue = res.data.lists
}
}
)
// 获取场馆包间详情
self._post(
'ground.ground/groundRoomDetails',
{
app_id: self.getAppId(),
id: self.roomId, // 场馆包间ID
},
function(res) {
console.log("🚀 ~ res:", res)
if (res.code) {
self.room = res.data.lists;
}
self.loadding = false;
}
)
// 获取订单详情
self._post(
'order.groundOrder/orderGroundDetails',
{
app_id: self.getAppId(),
order_id: self.orderId, // 场馆包间ID
},
function(res) {
console.log("🚀 ~ res:", res)
if (res.code) {
self.order = res.data.lists;
self.countSelectedTime = self.order.hours
self.countPrice()
}
self.loadding = false;
}
)
},
countPrice() {
let self = this;
uni.showLoading({
title: '加载中'
});
// 计算费用明细
if (self.countSelectedTime > 0) {
self._post(
'ground.ground/countPrice',
{
app_id: self.getAppId(),
room_id: self.roomId,
nums: self.countSelectedTime,
type_id: self.typeId,
pay_type: self.payType
},
function(res) {
const result = res.data.lists
self.bill = {
total: result.order_amount,
dis: result.dis,
cdf: {
nums: result.nums,
price: result.room_price,
total: result.room_all_price
},
dgf: {
nums: result.nums,
price: result.light_price,
total: result.light_all_price
}
}
console.log("🚀 ~ self.bill:", self.bill)
self.loadding = false;
}
)
} else {
self.loadding = false;
}
},
// 显示费用明细
handleShowBill() {
this.showPrice = false;
this.billPopup = true;
},
closeBillPopup() {
this.billPopup = false;
this.showPrice = true;
},
// 选择支付方式
payTypeFunc(n) {
this.payType = n;
this.countPrice()
},
// 去支付
toConfirm() {
if (this.countSelectedTime === 0) {
uni.showToast({title: '请选择时间后再预定', icon: 'none'});
return;
}
let self = this;
uni.showLoading({
title: '加载中'
});
self._post(
'order.groundOrder/submitStoreOrder',
{
app_id: self.getAppId(),
ground_id: self.venueId,
room_id: self.roomId,
hours: 1,
day_time: self.date ? self.date.date : '',
start_time: self.date ? self.date.startTime : '',
end_time: self.date ? self.date.endTime : '',
},
function(res) {
console.log("🚀 ~ order res:", res)
self._post(
'user.groundOrder/pay',
{
app_id: self.getAppId(),
order_id: res.data.lists.id
},
function(res) {
const data = res.data
console.log("🚀 ~ pay data:", data)
uni.requestPayment({
provider: 'wxpay',
timeStamp: data.payment.timeStamp,
nonceStr: data.payment.nonceStr,
package: 'prepay_id=' + data.payment.prepay_id,
signType: 'MD5',
paySign: data.payment.paySign,
success: res => {
console.log("🚀 ~ pay success res:", res)
},
fail: res => {
console.log("🚀 ~ pay fail res:", res)
uni.reLaunch({
url: '/pages/order/cg-my-order',
});
},
});
}
)
self.loadding = false;
}
)
}
}
};
</script>
<style lang="scss">
.box {
border-radius: 16rpx;
padding: 32rpx 30rpx;
margin: 0 30rpx;
}
.title {
font-size: 32rpx;
color: #303133;
line-height: 44rpx;
margin-bottom: 28rpx;
}
.desc {
font-weight: 500;
font-size: 26rpx;
color: #303133;
line-height: 48rpx;
margin-bottom: 16rpx;
}
.desc:last-child {
margin-bottom: 0;
}
.current {
position: absolute;
left: 0;
top: 38rpx;
width: 8rpx;
height: 32rpx;
background-color: #365A9A;
border-radius: 4rpx;
}
.dot {
width: 8rpx;
height: 8rpx;
background: #6A6363;
margin-right: 12rpx;
}
.mt20 {
margin-top: 20rpx;
}
.desc2 {
display: flex;
align-items: center;
margin-bottom: 16rpx;
}
.desc2:last-child {
margin-bottom: 0;
}
.price {
position: fixed;
bottom: 0;
left: 0;
right: 0;
background-color: #fff;
.line {
height: 2rpx;
background: #E5E5E5;
width: 100%;
}
.price-block {
margin: 42rpx 22rpx;
}
.price-detail {
color: #365A9A;
font-size: 24rpx;
line-height: 34rpx;
}
.price-btn {
width: 368rpx;
height: 90rpx;
line-height: 90rpx;
text-align: center;
background: #365A9A;
border-radius: 8rpx;
font-size: 32rpx;
color: #FFF;
}
}
.time-popup {
position: relative;
.title {
font-size: 36rpx;
color: #121212;
line-height: 50rpx;
}
.pt42 {
padding-top: 42rpx;
}
.notice {
margin-top: 30rpx;
width: 100%;
height: 56rpx;
background: #FFFBE5;
padding: 10rpx 30rpx;
font-weight: 500;
font-size: 26rpx;
color: #E2950F;
line-height: 48rpx;
text-align: left;
}
.time-item {
margin-right: 32rpx;
font-weight: 400;
font-size: 32rpx;
color: #303133;
line-height: 44rpx;
height: 62rpx;
}
.time-item-line {
width: 60rpx;
height: 10px;
background-color: #365A9A;
border-radius: 6rpx;
}
.active {
color: #365A9A;
font-size: 32rpx;
line-height: 44rpx;
}
.active:after {
content: '';
display: block;
width: 60rpx;
height: 10rpx;
background-color: #365A9A;
border-radius: 6rpx;
margin: 8rpx auto 0 auto;
}
/* 可选:选中样式 */
.date-item.active {
border-color: #365A9A;
color: #365A9A;
box-shadow: 0 4rpx 10rpx rgba(54,90,154,0.08);
}
.price2 {
margin-top: 100rpx;
.line {
height: 2rpx;
background: #E5E5E5;
width: 100%;
}
.price-block {
margin: 42rpx 22rpx;
}
.price-detail {
color: #365A9A;
font-size: 24rpx;
line-height: 34rpx;
}
.price-btn {
width: 368rpx;
height: 90rpx;
line-height: 90rpx;
text-align: center;
background: #365A9A;
border-radius: 8rpx;
font-size: 32rpx;
color: #FFF;
}
}
}
.bill-info {
border-radius: 16rpx;
margin: 32rpx 30rpx 22rpx;
padding: 48rpx 30rpx 30rpx;
.title1 {
font-size: 30rpx;
color: #303133;
line-height: 42rpx;
}
.title2 {
margin-top: 12rpx;
font-weight: 400;
font-size: 24rpx;
color: #909399;
line-height: 34rpx;
}
.line {
border: 2rpx solid #F6F7F9;
margin: 34rpx 0 30rpx;
}
.title3 {
font-size: 30rpx;
color: #303133;
line-height: 42rpx;
}
}
.buy-checkout-top {
padding: 100rpx 0;
}
.buy-checkout {
border-radius: 16rpx;
background-color: #FFFFFF;
margin: 28rpx 30rpx 0;
.item {
border-bottom: none;
border-radius: 2rpx;
padding: 30rpx 0;
}
}
.buy-checkout .item.active .iconfont.icon-xuanze {
color: #365A9A;
}
/* 日期网格:一行三个,间距 20rpx */
.date-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-gap: 20rpx 20rpx; /* 行间距和列间距均为 20rpx */
}
.date-time-btn {
width: 100%;
height: 60rpx;
line-height: 60rpx;
background: #365A9A;
color: #fff;
font-size: 26rpx;
border-radius: 10rpx;
text-align: center;
}
</style>