增加停车场预约功能

master
linyongLynn 5 days ago
parent 8862b359e3
commit 54c0c5e3b2

@ -1,8 +1,16 @@
<template> <template>
<view> <view>
<!-- 定位失败提示 -->
<view v-if="locationError" class="location-error">
<view class="location-error-content">
<text class="location-error-text">无法获取位置信息活动距离可能不准确</text>
<u-button size="mini" type="primary" @click="retryLocation" class="location-error-btn">重新定位</u-button>
</view>
</view>
<view class="listActivity"> <view class="listActivity">
<u-empty mode="list" text="暂无活动" marginTop="50" v-if="list.length==0&&!isloading"></u-empty> <u-empty mode="list" text="暂无活动" marginTop="50" v-if="list.length==0&&!isloading"></u-empty>
<view class="activityBox" v-for="(item,index) in list" :key="index" @click="openInfo(item)"> <view class="activityBox" v-for="(item,index) in list" :key="index" @click="openInfo(item)">
<view :class="!item.isCanBook?'gray100':''"></view> <view :class="!item.isCanBook?'gray100':''"></view>
<view class="activityBox-top"> <view class="activityBox-top">
<image :src='item.cover_upload.url' style="width: 100%;height: 333rpx;"></image> <image :src='item.cover_upload.url' style="width: 100%;height: 333rpx;"></image>
@ -34,16 +42,16 @@
<view style="display: inline-block;"> <view style="display: inline-block;">
<text class="icon-shijian iconfont"></text>活动场次 <text class="icon-shijian iconfont"></text>活动场次
</view> </view>
<view style="display: flex;flex-direction: column;"> <view style="display: flex;flex-direction: column;">
<block v-for="(k,index) in item.numbers"> <block v-for="(k,index) in item.numbers">
<view v-if="index<2" class="tag tag_green activityBox_btn activityBox_time" style="margin-top: -5px;margin-bottom: 10px;"> <view v-if="index<2" class="tag tag_green activityBox_btn activityBox_time" style="margin-top: -5px;margin-bottom: 10px;">
<text style="margin-right:12rpx"> <text style="margin-right:12rpx">
{{timeFormat(k.start_time,"MM月DD日")}} {{timeFormat(k.start_time,"MM月DD日")}}
</text> </text>
<text> <text>
{{getHm(k.start_time)}}-{{getHm(k.end_time)}} {{getHm(k.start_time)}}-{{getHm(k.end_time)}}
</text> </text>
</view> </view>
</block> </block>
</view> </view>
@ -82,28 +90,120 @@
list: [], list: [],
latitude: "", latitude: "",
longitude: "", longitude: "",
isloading: true isloading: true,
locationError: false //
} }
}, },
onLoad() { onLoad() {
var that = this; var that = this;
wx.getLocation({
success(res) { //
console.log(res) const isH5 = typeof window !== 'undefined' && window.location
that.latitude = res.latitude;
that.longitude = res.longitude; if (isH5) {
// H5使API
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(
function(position) {
that.latitude = position.coords.latitude;
that.longitude = position.coords.longitude;
console.log('定位成功:', that.latitude, that.longitude);
that.loadActivity()
},
function(error) {
console.log('定位失败:', error);
that.locationError = true;
//
switch(error.code) {
case error.PERMISSION_DENIED:
console.log('用户拒绝了定位权限');
break;
case error.POSITION_UNAVAILABLE:
console.log('位置信息不可用');
break;
case error.TIMEOUT:
console.log('定位超时');
break;
default:
console.log('定位失败,未知错误');
break;
}
//
that.loadActivity()
},
{
enableHighAccuracy: true,
timeout: 15000, // 15
maximumAge: 300000 // 5
}
);
} else {
console.log('浏览器不支持定位');
uni.showToast({
title: '浏览器不支持定位功能',
icon: 'none'
});
that.loadActivity() that.loadActivity()
} }
}) } else {
// 使wx.getLocation
wx.getLocation({
success(res) {
console.log(res)
that.latitude = res.latitude;
that.longitude = res.longitude;
that.loadActivity()
},
fail(err) {
console.log('定位失败:', err);
that.loadActivity()
}
})
}
}, },
onShareAppMessage() { onShareAppMessage() {
return this.util.shareInfo return this.util.shareInfo
}, },
onShareTimeline(){ onShareTimeline(){
return this.util.shareInfo return this.util.shareInfo
}, },
methods: { methods: {
//
retryLocation() {
this.locationError = false;
this.latitude = "";
this.longitude = "";
const isH5 = typeof window !== 'undefined' && window.location;
var that = this;
if (isH5 && navigator.geolocation) {
navigator.geolocation.getCurrentPosition(
function(position) {
that.latitude = position.coords.latitude;
that.longitude = position.coords.longitude;
console.log('重新定位成功:', that.latitude, that.longitude);
that.loadActivity();
},
function(error) {
console.log('重新定位失败:', error);
that.locationError = true;
uni.showToast({
title: '定位失败,请检查浏览器定位权限',
icon: 'none',
duration: 3000
});
},
{
enableHighAccuracy: true,
timeout: 15000,
maximumAge: 0 // 使
}
);
}
},
tothere(item) { tothere(item) {
uni.openLocation({ uni.openLocation({
latitude: parseFloat(item.latitude), latitude: parseFloat(item.latitude),
@ -119,17 +219,25 @@
}) })
}, },
loadActivity() { loadActivity() {
console.log("aaa") console.log("加载活动列表")
var that = this; var that = this;
var nt = new Date(); var nt = new Date();
that.isloading = true; that.isloading = true;
//
var requestData = {
page_size: 100
};
//
if (that.latitude && that.longitude) {
requestData.latitude = that.latitude;
requestData.longitude = that.longitude;
}
this.util.request({ this.util.request({
api: '/api/mobile/activity/index', api: '/api/mobile/activity/index',
data: { data: requestData,
latitude: that.latitude,
longitude: that.longitude,
page_size: 100
},
utilSuccess: function(res) { utilSuccess: function(res) {
for (var mod of res.data) { for (var mod of res.data) {
mod.isCanBook = that.$moment(nt).isBefore(mod.end_plan); mod.isCanBook = that.$moment(nt).isBefore(mod.end_plan);
@ -138,7 +246,7 @@
that.isloading = false; that.isloading = false;
}, },
utilFail: function(res) { utilFail: function(res) {
that.isloading = false;
} }
}) })
}, },
@ -166,32 +274,32 @@
page { page {
background-color: #f7f6f4; background-color: #f7f6f4;
}
.activityBox{
position: relative;
}
.activityBox-title {
font-size: 32rpx;
}
.activityBox-row{
font-size: 28rpx;
} }
.activityBox-top{ .activityBox{
font-size: 0; position: relative;
} }
.gray100{ .activityBox-title {
width:100%; font-size: 32rpx;
height:333rpx; }
position: absolute; .activityBox-row{
top:0; font-size: 28rpx;
left:0; }
background-color: rgba(0,0,0,0.5); .activityBox-top{
z-index:999; font-size: 0;
/* opacity: 50%; }
filter: grayscale(100%); .gray100{
opacity: 50%; width:100%;
-webkit-filter: blackscale(100%); height:333rpx;
filter: brightness(0.2); */ position: absolute;
top:0;
left:0;
background-color: rgba(0,0,0,0.5);
z-index:999;
/* opacity: 50%;
filter: grayscale(100%);
opacity: 50%;
-webkit-filter: blackscale(100%);
filter: brightness(0.2); */
} }
.activityBox_time { .activityBox_time {
/* height: 70rpx; */ /* height: 70rpx; */
@ -201,16 +309,46 @@
background: #FCF6E3; background: #FCF6E3;
border: 2rpx solid #cf995a; border: 2rpx solid #cf995a;
border-radius: 20rpx; border-radius: 20rpx;
color: #4E4E4E; color: #4E4E4E;
margin-right: 10rpx; margin-right: 10rpx;
}
.activityMore{
font-size: 26rpx;
font-family: PingFang SC;
font-weight: 400;
display: flex;
color: #cf995a;
flex-direction: column-reverse;
margin-left:10rpx
} }
</style> .activityMore{
font-size: 26rpx;
font-family: PingFang SC;
font-weight: 400;
display: flex;
color: #cf995a;
flex-direction: column-reverse;
margin-left:10rpx
}
.location-error {
background-color: #fff3cd;
border: 1px solid #ffeaa7;
border-radius: 8rpx;
margin: 20rpx;
padding: 20rpx;
}
.location-error-content {
display: flex;
justify-content: space-between;
align-items: center;
font-size: 28rpx;
color: #856404;
flex-wrap: wrap;
gap: 20rpx;
}
.location-error-text {
flex: 1;
min-width: 0;
word-wrap: break-word;
line-height: 1.4;
}
.location-error-btn {
flex-shrink: 0;
white-space: nowrap;
}
</style>

@ -2,14 +2,115 @@
<view> <view>
<view class="page-body"> <view class="page-body">
<view class="page-section page-section-gap"> <view class="page-section page-section-gap">
<map id='map' ref='map' style="width: 100%; height: 100vh;position: relative;" :latitude="latitude" <!-- H5环境嵌入iframe地图 -->
:longitude="longitude" :markers="covers"> <view v-if="isH5" class="h5-map-container">
<!-- <cover-view slot='callout' style='position: relative;'> <iframe
<cover-view style='height:200px'> :src="getMapUrl()"
<cover-image style="position: absolute;width:70px;height:70px" :src='covers[0].iconPath' :animation='animationData'> width="100%"
</cover-image> height="100vh"
</cover-view> 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> --> </cover-view> -->
<view class="book-box"> <view class="book-box">
<view class="activityBox-content flex-col"> <view class="activityBox-content flex-col">
@ -95,7 +196,7 @@
</view> </view>
<view class="activityBox-row" style="margin-top: 20rpx;color: #cf995a;" <view class="activityBox-row" style="margin-top: 20rpx;color: #cf995a;"
@click="showSelectorder=false"> @click="openselectorder">
<text>选择信息{{selectInfo.info||"暂未选择"}}</text> <text>选择信息{{selectInfo.info||"暂未选择"}}</text>
</view> </view>
</view> </view>
@ -167,7 +268,7 @@
distance: 0, distance: 0,
info: {}, info: {},
covers: [{ covers: [{
latitude: 31.297241, latitude: 31.297241,
longitude: 120.580792, longitude: 120.580792,
width: 30, width: 30,
height: 30, height: 30,
@ -189,48 +290,86 @@
remain_big_park: 0, remain_big_park: 0,
remain_small_park: 0, remain_small_park: 0,
remain_special_park: 0, remain_special_park: 0,
remain_big_park2: 0, remain_big_park2: 0,
animationData:null animationData: null,
isH5: false
} }
}, },
onshow(){ onshow(){
var animation = uni.createAnimation({ var animation = uni.createAnimation({
duration:200, duration:200,
timingFunction:'linear' timingFunction:'linear'
}) })
var next = true var next = true
setInterval(()=>{ setInterval(()=>{
if(next){ if(next){
animation.translateY(-2).step() animation.translateY(-2).step()
}else{ }else{
animation.translateY(0).step() animation.translateY(0).step()
} }
next = !next next = !next
this.animationData = animation.export() this.animationData = animation.export()
},800) },800)
}, },
onShareAppMessage() { onShareAppMessage() {
return this.util.shareInfo return this.util.shareInfo
}, },
onShareTimeline(){ onShareTimeline(){
return this.util.shareInfo return this.util.shareInfo
}, },
onLoad() { onLoad() {
var that = this; var that = this;
let map = uni.createMapContext('map'); //
map.setCenterOffset({ this.isH5 = typeof window !== 'undefined' && window.location
offset: [0.5, 0.25]
}) //
wx.getLocation({ if (this.isH5) {
success(res) { // H5使API
that.userlatitude = res.latitude; if (navigator.geolocation) {
that.userlongitude = res.longitude; 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.loadOrder(function(res) {
that.loadactivityOrder(function(r) { that.loadactivityOrder(function(r) {
if (res.length + r.length == 0) { if (res.length + r.length == 0) {
// that.util.toast("");
that.btnDisabled = true; that.btnDisabled = true;
} else { } else {
that.btnDisabled = true; that.btnDisabled = true;
@ -239,10 +378,59 @@
}) })
}); });
} }
}) } 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: { methods: {
// H5URL
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() { handleConfirmOrder() {
if (this.selectInfo.orderid === 0) { if (this.selectInfo.orderid === 0) {
this.util.toast("请选择预约的活动或者预约的参观"); this.util.toast("请选择预约的活动或者预约的参观");
@ -313,8 +501,8 @@
}, },
utilSuccess: function(res) { utilSuccess: function(res) {
for (var mod of res) { for (var mod of res) {
mod.checked = false; mod.checked = false;
mod.active_start_time = mod.number[0]['start_time'] mod.active_start_time = mod.number[0]['start_time']
mod.active_end_time = mod.number[0]['end_time'] mod.active_end_time = mod.number[0]['end_time']
} }
that.listActivtyOrder = res; that.listActivtyOrder = res;
@ -330,12 +518,31 @@
this.currentPark = type; this.currentPark = type;
}, },
openlocation() { openlocation() {
uni.openLocation({ if (this.isH5) {
latitude: this.info.latitude, // H5使JS-SDK
longitude: this.info.longitude, if (typeof wx !== 'undefined' && wx.openLocation) {
name: this.info.name, // JS-SDK
address: this.info.address 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() { loadInfo() {
var that = this; var that = this;
@ -363,7 +570,7 @@
height: 30, height: 30,
iconPath: '/static/img/location.png', iconPath: '/static/img/location.png',
id: 1 id: 1
} }
that.covers = [] that.covers = []
that.covers.push(mod); that.covers.push(mod);
let map = uni.createMapContext('map'); let map = uni.createMapContext('map');
@ -441,7 +648,7 @@
font-size: 26rpx; font-size: 26rpx;
color: #cf995a; color: #cf995a;
box-sizing: border-box; box-sizing: border-box;
} }
.book-box { .book-box {
height: 60%; height: 60%;
@ -470,4 +677,30 @@
box-shadow: 2rpx 3rpx 10rpx 0rpx rgba(107, 94, 77, 0.3); box-shadow: 2rpx 3rpx 10rpx 0rpx rgba(107, 94, 77, 0.3);
padding: 21rpx 25rpx; 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> </style>
Loading…
Cancel
Save