增加停车场预约功能

master
linyongLynn 5 days ago
parent 8862b359e3
commit 54c0c5e3b2

@ -1,8 +1,16 @@
<template>
<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">
<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="activityBox-top">
<image :src='item.cover_upload.url' style="width: 100%;height: 333rpx;"></image>
@ -34,16 +42,16 @@
<view style="display: inline-block;">
<text class="icon-shijian iconfont"></text>活动场次
</view>
<view style="display: flex;flex-direction: column;">
<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;">
<text style="margin-right:12rpx">
{{timeFormat(k.start_time,"MM月DD日")}}
</text>
<text>
{{getHm(k.start_time)}}-{{getHm(k.end_time)}}
</text>
</view>
<view style="display: flex;flex-direction: column;">
<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;">
<text style="margin-right:12rpx">
{{timeFormat(k.start_time,"MM月DD日")}}
</text>
<text>
{{getHm(k.start_time)}}-{{getHm(k.end_time)}}
</text>
</view>
</block>
</view>
@ -82,28 +90,120 @@
list: [],
latitude: "",
longitude: "",
isloading: true
isloading: true,
locationError: false //
}
},
onLoad() {
var that = this;
wx.getLocation({
success(res) {
console.log(res)
that.latitude = res.latitude;
that.longitude = res.longitude;
//
const isH5 = typeof window !== 'undefined' && window.location
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()
}
})
} 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() {
return this.util.shareInfo
},
onShareTimeline(){
return this.util.shareInfo
onShareAppMessage() {
return this.util.shareInfo
},
onShareTimeline(){
return this.util.shareInfo
},
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) {
uni.openLocation({
latitude: parseFloat(item.latitude),
@ -119,17 +219,25 @@
})
},
loadActivity() {
console.log("aaa")
console.log("加载活动列表")
var that = this;
var nt = new Date();
that.isloading = true;
//
var requestData = {
page_size: 100
};
//
if (that.latitude && that.longitude) {
requestData.latitude = that.latitude;
requestData.longitude = that.longitude;
}
this.util.request({
api: '/api/mobile/activity/index',
data: {
latitude: that.latitude,
longitude: that.longitude,
page_size: 100
},
data: requestData,
utilSuccess: function(res) {
for (var mod of res.data) {
mod.isCanBook = that.$moment(nt).isBefore(mod.end_plan);
@ -138,7 +246,7 @@
that.isloading = false;
},
utilFail: function(res) {
that.isloading = false;
}
})
},
@ -166,32 +274,32 @@
page {
background-color: #f7f6f4;
}
.activityBox{
position: relative;
}
.activityBox-title {
font-size: 32rpx;
}
.activityBox-row{
font-size: 28rpx;
}
.activityBox-top{
font-size: 0;
}
.gray100{
width:100%;
height:333rpx;
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{
position: relative;
}
.activityBox-title {
font-size: 32rpx;
}
.activityBox-row{
font-size: 28rpx;
}
.activityBox-top{
font-size: 0;
}
.gray100{
width:100%;
height:333rpx;
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 {
/* height: 70rpx; */
@ -201,16 +309,46 @@
background: #FCF6E3;
border: 2rpx solid #cf995a;
border-radius: 20rpx;
color: #4E4E4E;
color: #4E4E4E;
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 class="page-body">
<view class="page-section page-section-gap">
<map 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>
<!-- 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">
@ -95,7 +196,7 @@
</view>
<view class="activityBox-row" style="margin-top: 20rpx;color: #cf995a;"
@click="showSelectorder=false">
@click="openselectorder">
<text>选择信息{{selectInfo.info||"暂未选择"}}</text>
</view>
</view>
@ -167,7 +268,7 @@
distance: 0,
info: {},
covers: [{
latitude: 31.297241,
latitude: 31.297241,
longitude: 120.580792,
width: 30,
height: 30,
@ -189,48 +290,86 @@
remain_big_park: 0,
remain_small_park: 0,
remain_special_park: 0,
remain_big_park2: 0,
animationData:null
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
},
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;
let map = uni.createMapContext('map');
map.setCenterOffset({
offset: [0.5, 0.25]
})
wx.getLocation({
success(res) {
that.userlatitude = res.latitude;
that.userlongitude = res.longitude;
//
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.util.toast("");
that.btnDisabled = true;
} else {
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: {
// 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() {
if (this.selectInfo.orderid === 0) {
this.util.toast("请选择预约的活动或者预约的参观");
@ -313,8 +501,8 @@
},
utilSuccess: function(res) {
for (var mod of res) {
mod.checked = false;
mod.active_start_time = mod.number[0]['start_time']
mod.checked = false;
mod.active_start_time = mod.number[0]['start_time']
mod.active_end_time = mod.number[0]['end_time']
}
that.listActivtyOrder = res;
@ -330,12 +518,31 @@
this.currentPark = type;
},
openlocation() {
uni.openLocation({
latitude: this.info.latitude,
longitude: this.info.longitude,
name: this.info.name,
address: this.info.address
});
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;
@ -363,7 +570,7 @@
height: 30,
iconPath: '/static/img/location.png',
id: 1
}
}
that.covers = []
that.covers.push(mod);
let map = uni.createMapContext('map');
@ -441,7 +648,7 @@
font-size: 26rpx;
color: #cf995a;
box-sizing: border-box;
}
}
.book-box {
height: 60%;
@ -470,4 +677,30 @@
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>
Loading…
Cancel
Save