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.

706 lines
23 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<template>
<view>
<view class="page-body">
<view class="page-section page-section-gap">
<!-- H5环境嵌入iframe地图 -->
<view v-if="isH5" class="h5-map-container">
<iframe
:src="getMapUrl()"
width="100%"
height="100vh"
frameborder="0"
class="h5-map-iframe">
</iframe>
<!-- H5环境覆盖在地图上的UI内容 -->
<view class="book-box">
<view class="activityBox-content flex-col">
<view class="activityBox-row" style="margin-bottom: 56rpx;">
<text class="activityBox-title">{{info.name||""}}</text>
</view>
<view class="activityBox-row">
<text class="icon-shijian iconfont"></text>
<text>可入场时间段:{{info.start_time||""}}-{{info.end_time||""}}</text>
</view>
<view class="activityBox-row">
<text class="icon-huodong iconfont"></text>
<text>地址:{{info.address||""}}</text>
</view>
<view class="activityBox-row flex-row align-center" style="margin-bottom: 0rpx;"
@click="openlocation">
<text class="icon-ditu-dibiao iconfont"></text>
<text>距离:{{distance||"0"}}km</text>
<view class="tomap">
<text class="icon-daohang1 iconfont" style="margin-right: 0;"></text>
</view>
</view>
<view class="parkbox">
<view class="parkbox-title">可预约车位</view>
<view class="parkbox-content flex-row justify-around">
<view class="parkbox-item flex-row align-center"
style="margin-right: 10rpx;padding: 28rpx 20rpx;" @click="handleSelectPark(2)"
:class="(currentPark==2?'parkbox-item-on':'')" v-if="remain_big_park>0">
<view class="parkbox-item-status" v-if="currentPark==2">
<u-icon name="checkmark" color="#fff" size="20rpx"></u-icon>
</view>
<text class="iconfont icon-tingchechang1" style="font-size: 28rpx;"></text>
<view>
<text>大中(09:00-12:00){{remain_big_park}}</text>
</view>
</view>
<view class="parkbox-item flex-col align-center"
:class="(currentPark==1?'parkbox-item-on':'')" @click="handleSelectPark(1)"
style="margin-right: 10rpx;" v-if="remain_small_park>0">
<view class="parkbox-item-status" v-if="currentPark==1">
<u-icon name="checkmark" color="#fff" size="20rpx"></u-icon>
</view>
<view class="flex-row align-center">
<text class="iconfont icon-tingchechang1"
style="font-size: 28rpx;"></text><text>小车:{{remain_small_park}}</text>
</view>
<text style="font-size: 24rpx;color: #828282;">可预约车位:{{remain_small_park}}</text>
</view>
<view class="parkbox-item flex-row align-center"
style="margin-right: 10rpx;padding: 28rpx 20rpx;" @click="handleSelectPark(4)"
:class="(currentPark==4?'parkbox-item-on':'')" v-if="remain_big_park2>0">
<view class="parkbox-item-status" v-if="currentPark==4">
<u-icon name="checkmark" color="#fff" size="20rpx"></u-icon>
</view>
<text class="iconfont icon-tingchechang1" style="font-size: 28rpx;"></text>
<view>
<text>大中(13:00-16:00){{remain_big_park2}}</text>
</view>
</view>
<view class="parkbox-item flex-row align-center" style=""
@click="handleSelectPark(3)" :class="(currentPark==3?'parkbox-item-on':'')"
v-if="remain_special_park>0">
<view class="parkbox-item-status" v-if="currentPark==3">
<u-icon name="checkmark" color="#fff" size="20rpx"></u-icon>
</view>
<text class="iconfont icon-tingchechang1" style="font-size: 28rpx;"></text>
<view>
<text>残疾人车位:{{remain_special_park}}</text>
</view>
</view>
<view class="parkbox-item flex-row align-center" style=""
v-if="remain_special_park<=0&&remain_big_park<=0&&remain_small_park<=0">
<text class="iconfont icon-tingchechang1" style="font-size: 28rpx;"></text>
<view>
<text>暂无可选停车位</text>
</view>
</view>
</view>
</view>
<view class="activityBox-row" style="margin-top: 20rpx;color: #cf995a;"
@click="openselectorder">
<text>选择信息:{{selectInfo.info||"暂未选择"}}</text>
</view>
</view>
</view>
<view class="footer">
<u-button type="primary" :disabled="btnDisabled" @click="tobook">预约</u-button>
</view>
</view>
<!-- 小程序环境使用uni-app地图组件 -->
<map v-else id='map' ref='map' style="width: 100%; height: 100vh;position: relative;" :latitude="latitude"
:longitude="longitude" :markers="covers">
<!-- <cover-view slot='callout' style='position: relative;'>
<cover-view style='height:200px'>
<cover-image style="position: absolute;width:70px;height:70px" :src='covers[0].iconPath' :animation='animationData'>
</cover-image>
</cover-view>
</cover-view> -->
<view class="book-box">
<view class="activityBox-content flex-col">
<view class="activityBox-row" style="margin-bottom: 56rpx;">
<text class="activityBox-title">{{info.name||""}}</text>
</view>
<view class="activityBox-row">
<text class="icon-shijian iconfont"></text>
<text>可入场时间段:{{info.start_time||""}}-{{info.end_time||""}}</text>
</view>
<view class="activityBox-row">
<text class="icon-huodong iconfont"></text>
<text>地址:{{info.address||""}}</text>
</view>
<view class="activityBox-row flex-row align-center" style="margin-bottom: 0rpx;"
@click="openlocation">
<text class="icon-ditu-dibiao iconfont"></text>
<text>距离:{{distance||"0"}}km</text>
<view class="tomap">
<text class="icon-daohang1 iconfont" style="margin-right: 0;"></text>
</view>
</view>
<view class="parkbox">
<view class="parkbox-title">可预约车位</view>
<view class="parkbox-content flex-row justify-around">
<view class="parkbox-item flex-row align-center"
style="margin-right: 10rpx;padding: 28rpx 20rpx;" @click="handleSelectPark(2)"
:class="(currentPark==2?'parkbox-item-on':'')" v-if="remain_big_park>0">
<view class="parkbox-item-status" v-if="currentPark==2">
<u-icon name="checkmark" color="#fff" size="20rpx"></u-icon>
</view>
<text class="iconfont icon-tingchechang1" style="font-size: 28rpx;"></text>
<view>
<text>大中(09:00-12:00){{remain_big_park}}</text>
</view>
</view>
<view class="parkbox-item flex-col align-center"
:class="(currentPark==1?'parkbox-item-on':'')" @click="handleSelectPark(1)"
style="margin-right: 10rpx;" v-if="remain_small_park>0">
<view class="parkbox-item-status" v-if="currentPark==1">
<u-icon name="checkmark" color="#fff" size="20rpx"></u-icon>
</view>
<view class="flex-row align-center">
<text class="iconfont icon-tingchechang1"
style="font-size: 28rpx;"></text><text>小车:{{remain_small_park}}</text>
</view>
<text style="font-size: 24rpx;color: #828282;">可预约车位:{{remain_small_park}}</text>
</view>
<view class="parkbox-item flex-row align-center"
style="margin-right: 10rpx;padding: 28rpx 20rpx;" @click="handleSelectPark(4)"
:class="(currentPark==4?'parkbox-item-on':'')" v-if="remain_big_park2>0">
<view class="parkbox-item-status" v-if="currentPark==4">
<u-icon name="checkmark" color="#fff" size="20rpx"></u-icon>
</view>
<text class="iconfont icon-tingchechang1" style="font-size: 28rpx;"></text>
<view>
<text>大中(13:00-16:00){{remain_big_park2}}</text>
</view>
</view>
<view class="parkbox-item flex-row align-center" style=""
@click="handleSelectPark(3)" :class="(currentPark==3?'parkbox-item-on':'')"
v-if="remain_special_park>0">
<view class="parkbox-item-status" v-if="currentPark==3">
<u-icon name="checkmark" color="#fff" size="20rpx"></u-icon>
</view>
<text class="iconfont icon-tingchechang1" style="font-size: 28rpx;"></text>
<view>
<text>残疾人车位:{{remain_special_park}}</text>
</view>
</view>
<view class="parkbox-item flex-row align-center" style=""
v-if="remain_special_park<=0&&remain_big_park<=0&&remain_small_park<=0">
<text class="iconfont icon-tingchechang1" style="font-size: 28rpx;"></text>
<view>
<text>暂无可选停车位</text>
</view>
</view>
</view>
</view>
<view class="activityBox-row" style="margin-top: 20rpx;color: #cf995a;"
@click="openselectorder">
<text>选择信息:{{selectInfo.info||"暂未选择"}}</text>
</view>
</view>
</view>
<view class="footer">
<u-button type="primary" :disabled="btnDisabled" @click="tobook">预约</u-button>
</view>
</map>
</view>
</view>
<u-popup :show="showSelectorder" mode="bottom" :closeOnClickOverlay="false" @close="closeorder" :round="10">
<view class="mpopup">
<view class="mpopup-title">
选择预约的活动或者预约的参观
</view>
<view class="mpopup-content" style="padding: 40rpx 20rpx;">
<view v-if="listOrder.length!=0">
<view class="mpopup-title" style="text-align: left;padding: 20rpx 0;font-size: 14px;">
预约的参观
</view>
<block v-for="(item,index) in listOrder" :key="index">
<view class="box-tip flex-row align-center" @click="handleSelectOrder(index,1)"
style="margin-bottom: 30rpx;">
<u-icon size="24" :name="(item.checked?'checkmark-circle-fill':'checkmark-circle')"
:color="(item.checked?'#cf995a':'#828282')">
</u-icon>
<view class="box-tiptxt" style="margin-left: 10rpx;">
{{$u.timeFormat(new Date(item.date), 'mm月dd日')}}
{{item.time||""}}丨{{item.total}} 位观众</text>
</view>
</view>
</block>
</view>
<view v-if="listActivtyOrder.length!=0">
<view class="mpopup-title" style="text-align: left;padding: 20rpx 0;font-size: 14px;">
预约的活动
</view>
<block v-for="(item,index) in listActivtyOrder" :key="index">
<view class="box-tip flex-row align-center" @click="handleSelectOrder(index,2)"
style="margin-bottom: 30rpx;">
<u-icon size="24" :name="(item.checked?'checkmark-circle-fill':'checkmark-circle')"
:color="(item.checked?'#cf995a':'#828282')">
</u-icon>
<view class="box-tiptxt" style="margin-left: 10rpx;">
活动时间{{item.active_start_time||""}}
报名数量{{item.total}}</text>
</view>
</view>
</block>
</view>
<u-button type="primary" @click="handleConfirmOrder"></u-button>
</view>
</view>
</u-popup>
</view>
</template>
<script>
export default {
data() {
return {
latitude: 31.297241,
longitude: 120.580792,
userlatitude: 31.299893,
userlongitude: 120.626022,
distance: 0,
info: {},
covers: [{
latitude: 31.297241,
longitude: 120.580792,
width: 30,
height: 30,
iconPath: '/static/img/location.png',
id: 1
}],
currentPark: 0,
btnDisabled: true,
showSelectorder: false,
listOrder: [],
listActivtyOrder: [],
selectInfo: {
info: "",
orderType: 1,
orderid: 0,
userlatitude: 31.299893,
userlongitude: 120.626022
},
remain_big_park: 0,
remain_small_park: 0,
remain_special_park: 0,
remain_big_park2: 0,
animationData: null,
isH5: false
}
},
onshow(){
var animation = uni.createAnimation({
duration:200,
timingFunction:'linear'
})
var next = true
setInterval(()=>{
if(next){
animation.translateY(-2).step()
}else{
animation.translateY(0).step()
}
next = !next
this.animationData = animation.export()
},800)
},
onShareAppMessage() {
return this.util.shareInfo
},
onShareTimeline(){
return this.util.shareInfo
},
onLoad() {
var that = this;
// 检测运行环境
this.isH5 = typeof window !== 'undefined' && window.location
// 根据环境选择定位方式
if (this.isH5) {
// H5环境使用浏览器定位API
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(
function(position) {
that.userlatitude = position.coords.latitude;
that.userlongitude = position.coords.longitude;
console.log('H5定位成功:', that.userlatitude, that.userlongitude);
that.loadOrder(function(res) {
that.loadactivityOrder(function(r) {
if (res.length + r.length == 0) {
that.btnDisabled = true;
} else {
that.btnDisabled = true;
that.showSelectorder = false;
}
})
});
},
function(error) {
console.log('H5定位失败:', error);
// 定位失败时使用默认位置继续加载
that.loadOrder(function(res) {
that.loadactivityOrder(function(r) {
if (res.length + r.length == 0) {
that.btnDisabled = true;
} else {
that.btnDisabled = true;
that.showSelectorder = false;
}
})
});
},
{
enableHighAccuracy: true,
timeout: 15000,
maximumAge: 300000
}
);
} else {
console.log('浏览器不支持定位');
// 浏览器不支持定位时使用默认位置
that.loadOrder(function(res) {
that.loadactivityOrder(function(r) {
if (res.length + r.length == 0) {
that.btnDisabled = true;
} else {
that.btnDisabled = true;
that.showSelectorder = false;
}
})
});
}
} else {
// 小程序环境使用wx.getLocation
wx.getLocation({
success(res) {
that.userlatitude = res.latitude;
that.userlongitude = res.longitude;
console.log('小程序定位成功:', that.userlatitude, that.userlongitude);
that.loadOrder(function(res) {
that.loadactivityOrder(function(r) {
if (res.length + r.length == 0) {
that.btnDisabled = true;
} else {
that.btnDisabled = true;
that.showSelectorder = false;
}
})
});
},
fail(err) {
console.log('小程序定位失败:', err);
// 定位失败时使用默认位置继续加载
that.loadOrder(function(res) {
that.loadactivityOrder(function(r) {
if (res.length + r.length == 0) {
that.btnDisabled = true;
} else {
that.btnDisabled = true;
that.showSelectorder = false;
}
})
});
}
})
}
},
methods: {
// H5环境生成地图URL
getMapUrl() {
console.log('getMapUrl - info:', this.info);
console.log('getMapUrl - latitude:', this.info.latitude);
console.log('getMapUrl - longitude:', this.info.longitude);
if (this.info.latitude && this.info.longitude) {
// 使用真实的停车场坐标
const url = `https://apis.map.qq.com/uri/v1/marker?marker=coord:${this.info.latitude},${this.info.longitude};title:${encodeURIComponent(this.info.name || '停车场')};addr:${encodeURIComponent(this.info.address || '')}&referer=myapp`;
console.log('使用真实坐标:', url);
return url;
}
// 如果没有坐标数据,使用默认坐标
console.log('使用默认坐标');
return 'https://apis.map.qq.com/uri/v1/marker?marker=coord:31.297241,120.580792;title:苏州革命博物馆停车场;addr:苏州市姑苏区&referer=myapp';
},
handleConfirmOrder() {
if (this.selectInfo.orderid === 0) {
this.util.toast("请选择预约的活动或者预约的参观");
return false;
}
this.showSelectorder = false;
},
handleSelectOrder(index, type) {
for (var m of this.listActivtyOrder) {
m.checked = false;
}
for (var m of this.listOrder) {
m.checked = false;
}
if (type == 1) {
this.listOrder[index].checked = true;
this.selectInfo.info = this.$moment(this.listOrder[index].date).format("MM月DD日") + " " + this
.listOrder[index].time
this.selectInfo.time = this.$moment(this.listOrder[index].date + " " + this.listOrder[
index].time.split("-")[1]).format("YYYY-MM-DD HH:mm:ss");
this.selectInfo.orderid = this.orderid = this.listOrder[index].id;
} else {
this.listActivtyOrder[index].checked = true
this.selectInfo.info = this.$moment(this.listActivtyOrder[index].active_end_time).format(
"MM月DD日 HH:mm")
this.selectInfo.time = this.$moment(this.listActivtyOrder[index].active_end_time).format(
"YYYY-MM-DD HH:mm:ss");
this.selectInfo.orderid = this.orderid = this.listActivtyOrder[index].id;
}
this.orderType = type;
this.selectInfo.orderType = type;
this.loadInfo();
},
openselectorder() {
this.showSelectorder = true;
},
closeorder() {
this.showSelectorder = false;
},
loadOrder(cb) {
var that = this;
this.util.request({
api: '/api/mobile/user/my-visit-order',
data: {
status: 1,
not_expire: 1
},
utilSuccess: function(res) {
for (var mod of res) {
mod.checked = false;
}
that.listOrder = res;
cb(res)
},
utilFail: function(res) {
this.util.toast(res)
}
})
},
loadactivityOrder(cb) {
var that = this;
this.util.request({
api: '/api/mobile/user/my-activity-order',
data: {
status: 1,
not_expire: 0
},
utilSuccess: function(res) {
for (var mod of res) {
mod.checked = false;
mod.active_start_time = mod.number[0]['start_time']
mod.active_end_time = mod.number[0]['end_time']
}
that.listActivtyOrder = res;
cb(res);
},
utilFail: function(res) {
this.util.toast(res)
}
})
},
handleSelectPark(type) {
this.currentPark = type;
},
openlocation() {
if (this.isH5) {
// H5环境使用微信JS-SDK或浏览器打开地图
if (typeof wx !== 'undefined' && wx.openLocation) {
// 微信JS-SDK
wx.openLocation({
latitude: this.info.latitude,
longitude: this.info.longitude,
name: this.info.name,
address: this.info.address,
scale: 14
});
} else {
// 降级方案:使用腾讯地图
const mapUrl = `https://apis.map.qq.com/uri/v1/marker?marker=coord:${this.info.latitude},${this.info.longitude};title:${encodeURIComponent(this.info.name)};addr:${encodeURIComponent(this.info.address)}&referer=myapp`;
window.open(mapUrl, '_blank');
}
} else {
// 小程序环境使用uni.openLocation
uni.openLocation({
latitude: this.info.latitude,
longitude: this.info.longitude,
name: this.info.name,
address: this.info.address
});
}
},
loadInfo() {
var that = this;
this.util.request({
api: '/api/mobile/carpark/show',
data: {
date: that.selectInfo.time,
latitude: that.userlatitude,
longitude: that.userlongitude
},
utilSuccess: function(res) {
that.info = res.detail;
that.distance = res.distance;
that.info.latitude = parseFloat(res.detail.latitude);
that.info.longitude = parseFloat(res.detail.longitude);
that.remain_big_park = res.remain_big_park;
that.remain_small_park = res.remain_small_park;
that.remain_special_park = res.remain_special_park;
that.remain_big_park2 = res.remain_big_park2;
var mod = {
latitude: that.info.latitude,
longitude: that.info.longitude,
width: 30,
height: 30,
iconPath: '/static/img/location.png',
id: 1
}
that.covers = []
that.covers.push(mod);
let map = uni.createMapContext('map');
map.setCenterOffset({
offset: [0.5, 0.25]
})
},
utilFail: function(res) {
}
})
},
handleBook() {
uni.$u.throttle(this.tobook, 500)
},
tobook() {
if (this.selectInfo.orderid === 0) {
this.util.toast("请选择预约的活动或者预约的参观");
return false;
} else if (this.currentPark === 0) {
this.util.toast("请选择停车位");
return false;
} else {
var json = escape(JSON.stringify(this.selectInfo));
uni.navigateTo({
url: "book?bookinfo=" + json + "&id=" + this.info.id + "&currentPark=" + this.currentPark
})
}
}
}
}
</script>
<style>
@import url("@/static/css/activitybox.css");
.parkbox-item-status {
position: absolute;
right: 0;
top: 0;
background: #cf995a;
border-top-right-radius: 5rpx;
border-bottom-left-radius: 5rpx;
font-size: 20rpx;
color: #828282;
padding: 7rpx;
}
.
.parkbox-title {
margin-bottom: 40rpx;
margin-top: 40rpx;
font-size: 26rpx;
color: #4E4E4E;
}
.parkbox-item-on {
background: #FCF6E3 !important;
border: 2rpx solid #cf995a !important;
}
.parkbox-content {
flex-wrap: wrap;
}
.parkbox-item {
border: 2rpx solid #F7F6F4;
background: #F7F6F4;
border-radius: 5rpx;
position: relative;
padding: 10rpx 20rpx;
margin-bottom: 20rpx;
display: flex;
justify-content: center;
font-size: 26rpx;
color: #cf995a;
box-sizing: border-box;
}
.book-box {
height: 60%;
position: absolute;
bottom: 108rpx;
left: 0;
background: #FFFFFF;
border-top-left-radius: 16rpx;
border-top-right-radius: 16rpx;
margin: 0rpx 2%;
width: 96%;
}
.box-tiptxt {
font-size: 30rpx;
}
.footer {
position: fixed;
bottom: 0;
left: 0;
width: 100%;
height: 108rpx;
box-sizing: border-box;
background: #FFFFFF;
box-shadow: 2rpx 3rpx 10rpx 0rpx rgba(107, 94, 77, 0.3);
padding: 21rpx 25rpx;
}
/* H5地图iframe容器样式 */
.h5-map-container {
width: 100%;
height: 100vh;
position: relative;
background: #f5f5f5;
}
.h5-map-iframe {
width: 100%;
height: 100%;
border: none;
display: block;
}
.map-loading {
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
background: #f5f5f5;
color: #666;
font-size: 28rpx;
}
</style>