zhwl-miniapp/pages/hotel/paySuccess.vue
2025-06-26 12:38:35 +08:00

204 lines
7.6 KiB
Vue

<template>
<view class="waper">
<u-navbar @leftClick="leftClick" bgColor="#FFFFFF">
<view slot='center' style="font-size: 36rpx; font-weight: bold;">
支付成功
</view>
</u-navbar>
<mescroll-body @init="mescrollInit" @down="downCallback" @up="upCallback" :down="downOption" :up="upOption" :top="paddingTop + 'px'">
<view class="content">
<image class="img" src="../../static/image/hotel/paySuccess.png" mode=""></image>
<view class="tips">支付成功</view>
<view class="btn_box">
<view class="btn1" @click="refund">申请退款</view>
<view class="btn2" @click="reserve">再次预定</view>
</view>
<view class="tabs_box">
<view :class="['tab-item', isTab == index ? 'activeTab' : '']" v-for="(item, index) in tabList" :key="index" @click="changeTab(index)">
<view class="label">{{item}}</view>
<view class="line" v-if="isTab == index"></view>
</view>
</view>
<view class="list">
<view v-if="isTab == 0" class="list_item" v-for="(item, index) in list" :key="index" @click="toDetail('/pages/hotel/detail?id=' + item.id)">
<view class="image">
<image :src="item.coverImage ? $utils.setImgUrl(item.coverImage.split(',')[0]) : ''" mode=""></image>
</view>
<view class="name">{{ item.name }}</view>
<view class="distance">
距离酒店{{getDistance(item)}}km
</view>
<view class="footer">
<view class="price">
<text class="unit">¥</text>{{ item.price }}
</view>
<view class="sold" v-if="item.orderQuantity">已售{{item.orderQuantity}}+</view>
</view>
</view>
</view>
</view>
</mescroll-body>
</view>
</template>
<script>
import MescrollMixin from "@/uni_modules/mescroll-uni/components/mescroll-uni/mescroll-mixins.js";
export default {
mixins: [MescrollMixin],
data () {
return {
id: '',
hotelId: '',
paddingTop: 0,
downOption: { auto: false },
tabList: ['附近酒店'],
isTab: 0,
list: [],
lola: null,
latitude: null,
longitude: null,
source: ''
}
},
onLoad (options) {
this.id = options.id;
this.hotelId = options.hotelId;
this.source = options.source;
this.paddingTop = this.$paddingTop;
uni.getLocation({
type: 'gcj02',
isHighAccuracy: true,
success: (res) => {
this.latitude = res.latitude;
this.longitude = res.longitude;
}
})
},
methods: {
toDetail (url) {
uni.navigateTo({ url: url })
},
async upCallback(page) {
if (!this.lola) {
let res=await this.$http.homestayId(this.hotelId);
this.lola = {
lo: res.data.longitude,
la: res.data.latitude
};
}
let info = null;
let obj = { pageNum: page.num, pageSize: page.size, 'params[longitude]': this.lola.lo, 'params[latitude]': this.lola.la };
info = await this.$http.hotelNearHomestay(obj);
if(page.num == 1) this.list = [];
this.list = this.list.concat(info.rows);
this.mescroll.endBySize(info.rows.length, info.total);
},
getDistance(e) {
const R = 6371; // 地球半径,单位为千米
const dLat = (e.latitude - this.latitude) * Math.PI / 180;
const dLon = (e.longitude - this.longitude) * Math.PI / 180;
const a =
Math.sin(dLat / 2) * Math.sin(dLat / 2) +
Math.cos(this.latitude * Math.PI / 180) * Math.cos(e.latitude * Math.PI / 180) *
Math.sin(dLon / 2) * Math.sin(dLon / 2);
const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
const distance = R * c;
const range = distance.toFixed(2); // 保留两位小数
return range;
},
refund() {
uni.navigateTo({ url: `/pages/hotelOrder/detail?id=${this.id}` });
},
reserve() {
uni.navigateTo({ url: `/pages/hotel/detail?id=${this.hotelId}` });
},
changeTab(i) {
this.isTab = i;
this.list = [];
this.mescroll.resetUpScroll();
},
leftClick() {
if (this.source == 'order') {
uni.navigateBack()
} else {
this.navigateBackToPage('pages/hotel/list');
}
},
navigateBackToPage(pagePath) {
let pages = getCurrentPages();
let targetIndex = pages.findIndex(page => page.route === pagePath);
if (targetIndex >= 0) {
let delta = pages.length - targetIndex - 1;
uni.navigateBack({
delta: delta
});
}
}
}
}
</script>
<style lang="scss">
.waper { min-height: 100vh; background-color: #F6F6F6; }
.content{
width: 100%; box-sizing: border-box; padding: 79rpx 24rpx 0; text-align: center;
.img { width: 240rpx; height: 215rpx; }
.tips { margin-top: 24rpx; font-weight: 500; font-size: 36rpx; color: rgba(0,0,0,0.85); }
.btn_box {
margin-top: 48rpx; display: flex; align-items: center; justify-content: space-between;
.btn1 { width: 341rpx; height: 80rpx; background: #F6F6F6; border-radius: 4rpx; border: 2rpx solid #03AE80; line-height: 80rpx; text-align: center; font-size: 28rpx; color: #03AE80; }
.btn2 { width: 341rpx; height: 80rpx; background: #03AE80; border-radius: 4rpx; border: 2rpx solid #03AE80; line-height: 80rpx; text-align: center; font-size: 28rpx; color: #FFFFFF; }
}
.tabs_box {
margin-top: 32rpx; display: flex; align-items: center; height: 74rpx;
.tab-item {
margin-right: 77rpx;
&:last-child { margin-right: 0; }
.label { font-size: 30rpx; color: rgba(0,0,0,0.65); line-height: 42rpx; }
}
.activeTab {
position: relative;
.label { font-weight: 500; font-size: 36rpx; color: #03AE80; }
.line { position: absolute; left: 50%; bottom: -12rpx; transform: translateX(-50%); width: 74rpx; height: 4rpx; background: #03AE80; border-radius: 3rpx; }
}
}
.list {
margin-top: 20rpx; display: flex; align-items: center; flex-wrap: wrap;
.list_item {
width: 340rpx; background: #FFFFFF; border-radius: 10rpx; padding: 20rpx 20rpx 24rpx; box-sizing: border-box; margin: 0 20rpx 22rpx 0; text-align: left;
&:nth-child(2n) { margin-right: 0; }
.image{
width: 100%; height: 300rpx; position: relative;
image { border-radius: 8rpx; }
.image_text{
width: 100%; height: 84rpx; background: linear-gradient( 180deg, rgba(0,0,0,0) 0%, rgba(0,0,0,0.7) 100%); border-radius: 0 0 8rpx 8rpx; box-sizing: border-box; padding: 36rpx 12rpx 0; position: absolute; left: 0; bottom: 0;
.image_text_waper{
width: 100%; height: 36rpx; box-sizing: border-box; padding-left: 32rpx; position: relative;
.img{ width: 28rpx; height: 28rpx; position: absolute; left: 0; top: 50%; transform: translateY(-50%); }
.text{ line-height: 36rpx; color: #fff; font-size: 24rpx; width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
}
}
}
.name { font-weight: 500; font-size: 30rpx; color: rgba(0,0,0,0.85); margin-top: 20rpx; }
.distance { font-size: 24rpx; color: rgba(0,0,0,0.65); margin-top: 7rpx; }
.tag {
margin-top: 8rpx; height: 36rpx; display: flex; align-items: center;
view{
line-height: 36rpx; color: #03AE80; font-size: 24rpx; padding: 0 14rpx; background: rgba(71, 175, 195, 0.1); margin-right: 16rpx;
&:nth-child(2){ margin-right: 0; background: rgba(255,180,87,0.1); color: #FFB457; }
}
}
.footer {
display: flex; align-items: center; justify-content: space-between; margin-top: 20rpx;
.price {
font-weight: bold; font-size: 40rpx; color: #EE595A;
.unit { font-weight: 400; font-size: 24rpx; }
.text { font-size: 24rpx; color: rgba(0,0,0,0.25); }
}
.sold { font-size: 24rpx; color: rgba(0,0,0,0.25); }
}
}
}
}
</style>