chuangte_bike_newxcx/pages/nearbystores/index.vue
2025-04-12 18:01:40 +08:00

1704 lines
41 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 class="page">
<!-- 地图 -->
<image class="picimg" v-if="iconflag" src="https://api.ccttiot.com/smartmeter/img/static/uEAmNMMt65U10qwijrsJ"
mode=""></image>
<map class='map' id="map" :latitude="latitude" :longitude="longitude" :markers="covers"
@markertap="handleMarkerClick" @regionchange="regionchange" :polygons="polyline" :show-location="true" />
<!-- 左侧图标 -->
<view class="lticon">
<image src="https://api.ccttiot.com/smartmeter/img/static/u8WwVFtQy59eGWWQ9cfy" @click="btnbz" mode="">
</image>
<!-- <image src="https://api.ccttiot.com/smartmeter/img/static/ulCxXq0nQDSfdDWg5Ttw" @click="kefuflag = true" mode=""></image> -->
<image src="https://api.ccttiot.com/smartmeter/img/static/uDnm3dpbwMh9jLBRMeZw" @click="btnhuiz" mode="">
</image>
</view>
<!-- 右侧图标 -->
<view class="rticon">
<image v-if="rtindex != 1" src="https://api.ccttiot.com/smartmeter/img/static/uyNPBYUMjYxybfRLHyu9"
@click="btntap(1)" mode=""></image>
<image v-if="rtindex == 1" src="https://api.ccttiot.com/smartmeter/img/static/u8zXd0xYhLKD0BvgZDVv"
@click="btntap(1)" mode=""></image>
<image v-if="rtindex != 2" src="https://api.ccttiot.com/smartmeter/img/static/unoWsjJjeFKVrivp7MMF"
@click="btntap(2)" mode=""></image>
<image v-if="rtindex == 2" src="https://api.ccttiot.com/smartmeter/img/static/ukCjlSRsRoqMNNNxcFJ9"
@click="btntap(2)" mode=""></image>
<image v-if="rtindex != 3" src="https://api.ccttiot.com/smartmeter/img/static/uwIWeuTVbjFLNmLTGPOh"
@click="btntap(3)" mode=""></image>
<image v-if="rtindex == 3" src="https://api.ccttiot.com/smartmeter/img/static/uEWVQFGBf10XJn8aTlaZ"
@click="btntap(3)" mode=""></image>
<image style="width: 80rpx;height: 80rpx;" @click="toggleIconAndCallout"
src="https://api.ccttiot.com/smartmeter/img/static/uZT6o9OqOdZeXHLYszIg" mode=""></image>
</view>
<!-- 点击地图门店弹窗 -->
<view class="shoptc" v-if="shoptcflag" @click="btnmendain">
<view class="top">
<view class="name">
云行租车(汇丰公寓)
</view>
<view class="zu">
1辆可租 <image src="https://api.ccttiot.com/smartmeter/img/static/uX3GfXzwzS4GY1J55raG" mode="">
</image>
</view>
</view>
<view class="juli">
<view class="mi">
727m
</view>
<view class="dizhi">
福建省宁德市霞浦县六一七路402号台铃...
</view>
</view>
<view class="cont">
<image src="https://api.ccttiot.com/smartmeter/img/static/uK5bAmrXLEHVxbH6FcFD" mode=""></image>
<view class="shuoming">
<view class="name">
全新车网红泡泡50KM...
</view>
<view class="price">
日租¥<text>108</text>
</view>
</view>
</view>
</view>
<!-- 车辆弹窗 -->
<view class="biketc" v-if="taocanflag">
<view class="topfor">
<view class="biketop">
<image src="https://api.ccttiot.com/smartmeter/img/static/u6u6mWzrgiVCHICU1IWg" mode=""></image>
<view class="bianh">
<view class="">
车牌号:{{cheobj.vehicleNum == null ? '--' : cheobj.vehicleNum}}
</view>
<view class="bh" style="color: #808080;">
车辆编号:{{cheobj.sn == null ? '--' : cheobj.sn}}
</view>
</view>
<view class="bikebeep" @click="btnxlxc">
响铃寻车
</view>
</view>
<view class="bikesy">
<view class="bikelt">
<view class="bikets">
剩余骑行
</view>
<view class="bikegongli">
<image src="https://api.ccttiot.com/smartmeter/img/static/uLybsyJqWL4siF7mXkXh" mode="">
</image> {{cheobj.remainEndurance == null ? '--' : cheobj.remainEndurance}}公里
</view>
</view>
<view class="bikert">
<view class="bikets">
剩余电量
</view>
<view class="bikegongli">
<image src="https://api.ccttiot.com/smartmeter/img/static/u9y1tZIJBWLsO0DRoweT" mode="">
</image> {{cheobj.remainingPower == null ? '--' : cheobj.remainingPower}}%
</view>
</view>
</view>
<view class="bikeyc" @click="btncheyc">
×
</view>
</view>
<view class="anniuks" @click="btndetaxq">
<text>去下单</text>
</view>
</view>
<view class="clmask" v-if="taocanflag"></view>
<!-- 平台客服弹窗 -->
<view class="kefutc" v-if="kefuflag">
<image src="https://api.ccttiot.com/smartmeter/img/static/umtjJg2CJLiOS6hfAEzo" mode=""
@click="kefuflag = false"></image>
<view class="box">
<view class="" style="max-height: 170rpx;overflow: scroll;">
<view class="top" v-for="(item,index) in kefulist" :key="index">
<view class="dianhua">
{{item.name == null ? '--' : item.name}}{{item.contact == null ? '--' : item.contact}}
</view>
<view class="boda" @click.stop="btnptkf(item.contact)">
<u-icon name="phone-fill" color="#4297F3" size="28"></u-icon>
<text>拨打</text>
</view>
</view>
</view>
<view class="bot">
<view class="wz">
平台客服工作时间
</view>
<view class="wz">
0800~2000
</view>
<view class="wzs">
客服电话高峰期可能遇忙请耐心等待
</view>
</view>
</view>
</view>
<view class="mask" v-if="kefuflag"></view>
<!-- 有订单弹窗 -->
<view class="conts_box" v-if="orderAreaId != ''" @click="btntz">
<view class="orderzt">
<view class="" style="font-size: 32rpx;font-weight: 600;">
订单状态
</view>
<view class="">
<view style="color: #333;">订单进行中<u-icon name="arrow-right" color="#333" size="28"></u-icon></view>
</view>
</view>
<view class="cont_li">
<view class="right">
<image src="https://lxnapi.ccttiot.com/bike/img/static/uqKmFMF9YHTX8lAQARSd" mode="aspectFill">
</image>
<view class="NO">
SN{{orderobj.deviceSn == null ? '--' : orderobj.deviceSn}}
</view>
</view>
<view class="left">
<view class="km">
可继续行驶{{orderobj.deviceRemainEndurance == null ? '--' : orderobj.deviceRemainEndurance}}公里
</view>
<view class="speed">
<view class="speeds" :style="{ width: orderobj.deviceRemainingPower + '%' }"></view>
</view>
<view class="NO">
电量{{orderobj.deviceRemainingPower == null ? '--' : orderobj.deviceRemainingPower}}%
</view>
</view>
</view>
<view class=""
style="display: flex;width: 100%;padding: 0 20rpx;box-sizing: border-box;justify-content: space-between;">
<view class="dh" @click.stop="danghang">
导航 <u-icon name="arrow-right" color="#333" size="28"></u-icon>
</view>
<view class="suocheanniu">
<view class="lssc" @click.stop="btnjsdd">
结束订单
</view>
<view class="lssc" @click.stop="btnqd">
{{orderobj.deviceLockStatus == 1 ? '临时锁车' : '开锁'}}
</view>
</view>
</view>
</view>
<!-- 扫码用车未在停车点内还车弹窗 -->
<view class="tingchetc" v-if="fjflag">
<view class="topname">
<image src="https://api.ccttiot.com/smartmeter/img/static/uDfEXjApmdS6ByM88pv3" mode=""></image>
{{fajinobj.manageFee > 0 ? '不在运营区' : fajinobj.dispatchFee > 0 ? '不在停车点' : ''}}
</view>
<view class="shuom">
需支付<text>{{fajinobj.manageFee > 0 ? fajinobj.manageFee : fajinobj.dispatchFee > 0 ? fajinobj.dispatchFee : ''}}元</text>,你可查看<text
@click="btntcd">最近停车点</text>
</view>
<image src="https://api.ccttiot.com/smartmeter/img/static/uzRrRFiToK3bb3IurIHU" class="tcimg" mode="">
</image>
<view class="btnan">
<view class="fj" @click="btnfajin">
缴纳罚金还车
</view>
<view class="qx" @click="fjflag = false">
继续骑行
</view>
</view>
</view>
<view class="mask" v-if="fjflag"></view>
<tab-bar :indexs='1'></tab-bar>
</view>
</template>
<script>
export default {
data() {
return {
bgc: {
backgroundColor: "",
},
latitude: '',
longitude: '',
lat: '',
lng: '',
latsc: '',
lngsc: '',
rtindex: 2,
covers: [],
shoptcflag: false,
iconPath: '',
tcindex: 0,
taocanflag: false,
kefuflag: false,
iconflag: false,
cheobj: {},
jingweidu: '',
taocaolist: [],
polyline: [],
kefulist: [],
orderAreaId: '',
areaId: '',
orderobj: {},
orderAreaReturnVerify: '',
fajinobj: {},
fjflag: false,
sockedata:{},
socketTask: null,
messages: [],
reconnectAttempts: 0,
maxReconnectAttempts: 5,
reconnectInterval: 3000, // 3秒重试一次
isPageActive: true,
deviceMac: '' // 从页面参数或其他地方获取
}
},
onLoad() {
},
onShow() {
this.getMyLocation()
this.getkefu()
this.getorderdevice()
this.polyline = []
},
onUnload() {
this.isPageActive = false;
this.closeWebSocket();
},
onHide() {
// 页面隐藏时关闭连接
this.isPageActive = false;
this.closeWebSocket();
},
methods: {
//WebSocket 自动重连实现
initWebSocket() {
if (!this.isPageActive || !this.deviceMac) return;
let token = uni.getStorageSync('token');
// 关闭已有连接
if (this.socketTask) {
this.socketTask.close();
this.socketTask = null;
}
// 创建新连接
this.socketTask = uni.connectSocket({
url: `wss://ele.ccttiot.com/prod-api/ws/device?token=${token}&mac=${this.deviceMac}`,
success: () => {
console.log('WebSocket连接建立中...');
},
fail: (err) => {
console.error('WebSocket连接失败:', err);
this.scheduleReconnect();
}
});
// 监听连接打开
this.socketTask.onOpen(() => {
console.log('WebSocket连接已打开');
this.reconnectAttempts = 0; // 重置重连计数器
// 发送订阅消息(如果需要)
this.socketTask.send({
data: JSON.stringify({
action: 'subscribe'
}),
success: () => console.log('订阅消息发送成功'),
fail: (err) => console.error('订阅消息发送失败:', err)
});
});
// 监听消息接收
this.socketTask.onMessage((res) => {
console.log('收到实时消息:', res.data);
this.messages.push(res.data); // 存储消息
try {
const data = JSON.parse(res.data);
console.log('解析后的JSON数据:', data);
// 这里可以处理具体的业务逻辑
this.sockedata = data
this.getqingqiu()
this.covers.push({
latitude: data.latitude,
longitude: data.longitude,
width: 8,
height: 8,
iconPath: 'https://api.ccttiot.com/smartmeter/img/static/uow9Zq3edTUYCVHI9H60',
})
} catch (e) {
console.log('原始消息内容:', res.data);
}
});
// 监听错误
this.socketTask.onError((err) => {
console.error('WebSocket错误:', err);
this.scheduleReconnect();
});
// 监听连接关闭
this.socketTask.onClose((res) => {
console.log('WebSocket连接已关闭', res);
if (this.isPageActive) {
this.scheduleReconnect();
}
});
},
// 关闭WebSocket连接
closeWebSocket() {
if (this.socketTask) {
this.socketTask.close({
success: () => {
console.log('WebSocket已主动关闭');
this.socketTask = null;
},
fail: (err) => {
console.error('WebSocket关闭失败:', err);
this.socketTask = null;
}
});
}
},
// 安排重连
scheduleReconnect() {
if (!this.isPageActive || this.reconnectAttempts >= this.maxReconnectAttempts) {
console.log('已达到最大重连次数或页面已关闭,停止重连');
return;
}
this.reconnectAttempts++;
console.log(`尝试第 ${this.reconnectAttempts} 次重连,等待 ${this.reconnectInterval/1000} 秒...`);
setTimeout(() => {
this.initWebSocket();
}, this.reconnectInterval);
// 指数退避策略,增加重连间隔
this.reconnectInterval = Math.min(this.reconnectInterval * 2, 30000); // 最大不超过30秒
},
// 点击结束订单
btnjsdd() {
if (this.orderAreaReturnVerify == true) {
uni.navigateTo({
url: '/page_user/hcshenhe?sn=' + this.orderobj.deviceSn + '&orderid=' + this.orderobj
.orderId + '&orderAreaId=' + this.orderobj.orderAreaId
})
} else {
uni.getLocation({
type: 'wgs84',
success: (res) => {
console.log(res);
this.latsc = res.latitude
this.lonsc = res.longitude
this.getfeiyong()
},
fail: (err) => {
console.error('获取位置失败:', err)
this.getfeiyong()
}
})
}
},
// 点击还车判断是否需要另外缴费
getfeiyong() {
let data = {
orderId: this.orderobj.orderId,
lon: this.latsc,
lat: this.lonsc
}
this.$u.post(`/app/order/calcFee`, data).then(res => {
if (res.code == 200) {
this.fajinobj = res.data
if (res.data.manageFee > 0 || res.data.dispatchFee > 0) {
this.fjflag = true
// this.gethuan()
} else {
// this.fjflag = true
this.gethuan()
}
}
})
},
// 点击缴纳罚金继续还车
btnfajin() {
this.gethuan()
},
// 还车统一调用
gethuan() {
let that = this
uni.showModal({
title: '提示',
content: '您确定要还车吗?',
showCancel: true,
success: function(res) {
if (res.confirm) {
let data = {
orderId: that.orderobj.orderId,
picture: that.imgs,
lon: that.lonsc,
lat: that.latsc
}
that.$u.put(`/app/order/end`, data).then(res => {
if (res.code == 200) {
uni.showToast({
title: '还车成功',
icon: 'success',
duration: 2000
})
that.getorderdevice()
that.fjflag = false
} else {
uni.showToast({
title: res.msg,
icon: 'none',
duration: 2000
})
}
})
} else if (res.cancel) {
}
}
})
},
// 点击跳转到最近停车点
btntcd() {
uni.navigateTo({
url: '/pages/myorder/returned/tingche?areaId=' + this.orderobj.orderAreaId
})
},
// 点击跳转到车辆
btntz() {
uni.switchTab({
url: '/pages/myorder/returned/index'
})
},
// 点击跳转导航
danghang() {
if (this.orderobj.deviceLatitude && this.orderobj.deviceLongitude) {
uni.openLocation({
latitude: this.orderobj.deviceLatitude, //纬度-目的地/坐标点
longitude: this.orderobj.deviceLongitude, //经度-目的地/坐标点
name: '', //地点名称
address: '' //详细地点名称
})
} else {
uni.showToast({
title: '车辆暂无法导航',
icon: 'none',
duration: 2000
})
}
},
// 点击启动and关闭
btnqd() {
if (this.orderobj.deviceLockStatus == 0) {
let that = this
uni.showModal({
title: '提示',
content: '您是否要解锁车辆?',
showCancel: true,
success: function(res) {
if (res.confirm) {
that.$u.put(`/app/order/openDevice?orderId=${that.orderobj.orderId}`).then((
res) => {
if (res.code == 200) {
uni.showToast({
title: '解锁成功',
icon: 'success',
duration: 2000
})
that.getorderdevice()
} else {
uni.showToast({
title: res.msg,
icon: 'none',
duration: 2000
})
}
})
} else if (res.cancel) {
console.log('取消'); // 用户点击取消
}
}
})
} else if (this.orderobj.deviceLockStatus == 1) {
uni.getLocation({
type: 'wgs84',
success: (res) => {
console.log(res);
this.latsc = res.latitude
this.lngsc = res.longitude
},
fail: (err) => {
console.error('获取位置失败:', err)
}
})
let that = this
uni.showModal({
title: '提示',
content: '您是否要临时解锁?',
showCancel: true,
success: function(res) {
if (res.confirm) {
that.$u.put(
`/app/order/closeDevice?orderId=${that.orderobj.orderId}&lat=${that.latsc}&lon=${that.lngsc}`
).then((res) => {
if (res.code == 200) {
uni.showToast({
title: '临时锁车成功',
icon: 'success',
duration: 2000
})
that.getorderdevice()
} else {
uni.showToast({
title: res.msg,
icon: 'none',
duration: 2000
})
}
})
} else if (res.cancel) {
console.log('取消'); // 用户点击取消
}
}
})
}
},
// 获取本人正在使用的订单设备
getorderdevice() {
this.$u.get("/app/orderDevice/mineUsing").then((res) => {
if (res.code == 200) {
if (res.data) {
this.orderobj = res.data
this.orderAreaReturnVerify = res.data.orderAreaReturnVerify
this.orderAreaId = res.data.orderAreaId
this.areaId = res.data.orderAreaId
this.deviceMac = res.data.deviceMac
this.isPageActive = true
this.initWebSocket() //WebSocket接受数据
this.$u.get(`/app/area/detail?id=${this.orderAreaId}`).then((res) => {
if (res.code == 200) {
const polylines = this.convertBoundaryToPolyline(res.data.boundaryStr)
this.polyline.push(polylines)
this.getParking()
}
})
} else {
this.orderAreaId = ''
}
}
})
},
// 点击地图中的店铺操作
handleMarkerClick(e) {
let id = String(e.detail.markerId)
if (id.slice(-1) == 1) {
console.log('店铺')
this.covers.filter(item => {
if (item.id == id) {
item.iconPath = 'https://api.ccttiot.com/smartmeter/img/static/u8ONjRuMpydcZ4WuA6vP'
this.shoptcflag = true
}
})
} else if (id.slice(-1) == 2) {
console.log('车辆')
if (this.orderAreaId == '') {
this.covers.filter(item => {
if (item.id == id) {
item.iconPath =
'https://api.ccttiot.com/smartmeter/img/static/uCBNaRAdk9kcgQgrom2G'
this.taocanflag = true
this.$u.get(`/app/device/availableDetail?id=${id.slice(0, -1)}`).then((res) => {
if (res.code == 200) {
this.cheobj = res.data
this.areaId = res.data.areaId
this.getArea()
}
})
}
})
} else {
console.log('进行中订单');
uni.showToast({
title: '当前已有订单',
icon: 'none',
duration: 2000
})
}
} else if (id.slice(-1) == 3) {
console.log('导览')
}
},
// 请求客服
getkefu() {
this.$u.get(`/app/customerService/list?pageNum=1&pageSize=999`).then(res => {
if (res.code == 200) {
this.kefulist = res.rows
}
})
},
// 点击去下单
btndetaxq() {
this.$u.get(`/getInfo`).then(res => {
if (res.code == 200) {
this.taocanflag = false
uni.navigateTo({
url: '/page_fenbao/storedlist/trueorder?modelId=' + this.cheobj.modelId +
'&sn=' + this.cheobj.sn
})
} else if (res.code == 401) {
uni.showModal({
title: '提示',
content: '您当前未登录,是否前去登录?',
showCancel: true,
success: function(res) {
if (res.confirm) {
uni.reLaunch({
url: '/pages/login/login'
})
} else if (res.cancel) {
}
}
})
}
})
},
// 点击响铃寻车
btnxlxc() {
this.$u.put(`/app/device/iot/ring?id=${this.cheobj.id}`).then((res) => {
if (res.code == 200) {
uni.showToast({
title: '操作成功',
icon: 'success',
duration: 2000
})
} else if (res.code == 401) {
uni.showModal({
title: '提示',
content: '您当前未登录,是否前去登录?',
showCancel: true,
success: function(res) {
if (res.confirm) {
uni.reLaunch({
url: '/pages/login/login'
})
} else if (res.cancel) {
}
}
})
} else {
uni.showToast({
title: res.msg,
icon: 'none',
duration: 2000
})
}
})
},
// 点击隐藏车辆弹窗
btncheyc() {
this.taocanflag = false
this.getqingqiu()
},
// 拖动查询中心点的数据
regionchange(e) {
this.iconflag = true
if (e.type == 'end') {
if (this.rtindex == 2) {
this.jingweidu = e.detail.centerLocation.longitude + ',' + e.detail.centerLocation.latitude
this.getqingqiu()
this.iconflag = false
}
}
},
// 点击选择骑行套餐
btntcxz(index) {
this.tcindex = index
},
// 点击跳转到帮助中心
btnbz() {
uni.navigateTo({
url: '/page_user/bangzhu'
})
},
// 点击拨打平台客服电话
btnptkf() {
uni.makePhoneCall({
phoneNumber: '18888888888',
success: function(res) {
console.log('拨打电话成功', res)
},
fail: function(err) {
console.error('拨打电话失败', err)
}
})
},
// 点击跳转到租车门店
btnmendain() {
uni.navigateTo({
url: '/page_fenbao/storedlist/index'
})
},
// 点击右侧图标
btntap(num) {
if (num == 3) {
uni.showToast({
title: '导览暂未开放',
icon: 'none',
duration: 2000
})
} else {
this.covers = []
this.rtindex = num
this.shoptcflag = false
this.getqingqiu()
}
},
// 点击调用回到地图中心点
btnhuiz() {
this.setMapScale()
},
// 回到地图中心点
async setMapScale(e, val) {
let mapContext = uni.createMapContext('map', this);
let setScale = () => {
return new Promise((resolve, reject) => {
mapContext.getScale({
success: r => {
resolve()
}
})
})
};
await setScale()
mapContext.moveToLocation({
success: (res) => {
const timer = setTimeout(() => {
clearTimeout(timer)
}, 500)
}
})
},
// 请求附近车辆and门店
getqingqiu() {
if (this.rtindex == 1) {
this.iconPath = 'https://api.ccttiot.com/smartmeter/img/static/upX2lLilhrRi4tttdHlo'
} else if (this.rtindex == 2) {
this.iconPath = 'https://api.ccttiot.com/smartmeter/img/static/uX0FBv86yDIR5tIqjoe2'
// this.iconPath = 'https://api.ccttiot.com/smartmeter/img/static/uX0FBv86yDIR5tIqjoe2'
this.$u.get(`/app/device/listNearBy?radius=10000&center=${this.jingweidu}`).then((res) => {
if (res.code == 200) {
this.covers = []
if(this.sockedata.latitude){
this.covers.push({
latitude: this.sockedata.latitude,
longitude: this.sockedata.longitude,
width: 8,
height: 8,
iconPath: 'https://api.ccttiot.com/smartmeter/img/static/uow9Zq3edTUYCVHI9H60',
})
}
res.data.forEach(item => {
const shopCover = {
// 门店后面拼接1车辆拼接23是导览
id: this.rtindex == 1 ? parseInt(item.id + "1") : this.rtindex ==
2 ? parseInt(item.id + "2") : parseInt(item.id + "3"),
latitude: item.latitude,
longitude: item.longitude,
width: 35,
height: 40,
iconPath: this.iconPath,
callout: {
content: '' + item.vehicleNum, // 修改为你想要显示的文字内容
color: '#0D75E5', // 修改为文字颜色
fontSize: 10, // 修改为文字大小
borderRadius: 10, // 修改为气泡圆角大小
bgColor: '#fff', // 修改为气泡背景颜色
padding: 3, // 修改为气泡内边距
display: 'ALWAYS', // 修改为气泡的显示策略
}
}
this.covers.push(shopCover)
})
}
})
} else if (this.rtindex == 3) {
this.iconPath = 'https://api.ccttiot.com/smartmeter/img/static/un7ecyEN8vsJhlEnXfD4'
} else {
this.iconPath = null
}
},
// 获取自身位置
getMyLocation() {
uni.getLocation({
type: 'wgs84',
success: (res) => {
this.latitude = Number(res.latitude) - 0.005
this.longitude = Number(res.longitude) + 0.005
this.jingweidu = this.longitude + ',' + this.latitude
this.setMapScale()
this.getqingqiu()
},
fail: (err) => {
console.error('获取位置失败:', err)
}
})
},
convertBoundaryToPolyline(boundary) {
if (!boundary) return null
const points = JSON.parse(boundary).map(coord => ({
latitude: coord[1],
longitude: coord[0]
}))
const polyline = {
points: points,
fillColor: "#55888840", //填充颜色
strokeColor: "#22FF00", //描边颜色
strokeWidth: 1, //描边宽度
zIndex: 1, //层级
}
return polyline
},
convertBoundaryToPolylines(boundaries, num) {
if (num == 1) {
console.log('判断')
return boundaries.map(boundary => {
if (!boundary) return null
let coords
try {
coords = JSON.parse(boundary)
} catch (error) {
console.error("Error parsing boundary JSON:", error)
return null
}
if (!Array.isArray(coords)) {
console.error("Parsed boundary is not an array:", coords)
return null
}
console.log(coords, '1111111');
const points = coords.map(coord => ({
latitude: coord[1],
longitude: coord[0]
}))
return {
points: points,
fillColor: "#3A7EDB40", //填充颜色
strokeColor: "#3A7EDB", //描边颜色
strokeWidth: 2, //描边宽度
zIndex: 1, //层级
}
}).filter(polyline => polyline !== null)
} else if (num == 2) {
return boundaries.map(boundary => {
if (!boundary) return null
let coords
try {
coords = JSON.parse(boundary)
} catch (error) {
console.error("Error parsing boundary JSON:", error)
return null
}
if (!Array.isArray(coords)) {
console.error("Parsed boundary is not an array:", coords)
return null
}
console.log(coords, '2222222222222')
const points = coords.map(coord => ({
latitude: coord[1],
longitude: coord[0]
}))
return {
points: points,
fillColor: "#FFF5D640", //填充颜色
strokeColor: "#FF473E", //描边颜色
strokeWidth: 2, //描边宽度
zIndex: 1, //层级
}
}).filter(polyline => polyline !== null)
} else if (num == 3) {
return boundaries.map(boundary => {
if (!boundary) return null
let coords
try {
coords = JSON.parse(boundary)
} catch (error) {
console.error("Error parsing boundary JSON:", error)
return null
}
if (!Array.isArray(coords)) {
console.error("Parsed boundary is not an array:", coords)
return null
}
console.log(coords, '333333333333');
const points = coords.map(coord => ({
latitude: coord[1],
longitude: coord[0]
}));
return {
points: points,
fillColor: "#FFD1CF40", //填充颜色
strokeColor: "#FFC107", //描边颜色
strokeWidth: 2, //描边宽度
zIndex: 1, //层级
};
}).filter(polyline => polyline !== null)
}
},
toggleIconAndCallout() {
if (this.cheobj == '') {
uni.showToast({
title: '请选选择车辆',
icon: 'none',
duration: 2000
})
} else {
this.showIconAndCallout = !this.showIconAndCallout
if (this.showIconAndCallout) {
const newMarkers = []
this.parkingList.forEach(item => {
newMarkers.push({
id: parseFloat(item.id),
latitude: parseFloat(item.latitude),
longitude: parseFloat(item.longitude),
width: 20,
height: 28.95,
iconPath: item.type == 1 ?
'https://lxnapi.ccttiot.com/bike/img/static/up2xXqAgwCX5iER600k3' :
item.type == 2 ?
'https://lxnapi.ccttiot.com/bike/img/static/uDNY5Q4zOiZTCBTA2Jdq' :
'https://lxnapi.ccttiot.com/bike/img/static/u53BAQcFIX3vxsCzEZ7t',
callout: {
content: item.name,
color: '#ffffff',
fontSize: 14,
borderRadius: 10,
bgColor: item.type == 1 ? '#3A7EDB' : item.type == 2 ? '#FF473E' :
'#FFC107',
padding: 6,
display: 'ALWAYS'
},
isCalloutVisible: true // 添加标记
})
})
this.$set(this, 'covers', [...this.covers, ...newMarkers])
} else {
// 过滤掉所有气泡显示的标记
this.$set(this, 'covers', this.covers.filter(marker => !marker.isCalloutVisible))
}
}
},
getParking() {
// 发送请求获取数据
this.$u.get(`/app/areaSub/listByArea?areaId=${this.areaId}`).then((res) => {
if (res.code === 200) {
// 处理接口返回的数据
const type1Data = []
const type2Data = []
const type3Data = []
res.data.forEach(row => {
if (row.type == 1) {
type1Data.push(row)
} else if (row.type == 2) {
type2Data.push(row)
} else if (row.type == 3) {
type3Data.push(row)
}
})
const validBoundaries = type1Data.map(row => row.boundaryStr).filter(boundary =>
typeof boundary === 'string' && boundary.trim() !== '')
const polylines = this.convertBoundaryToPolylines(validBoundaries, 1)
const validBoundaries1 = type2Data.map(row => row.boundaryStr).filter(boundary =>
typeof boundary === 'string' && boundary.trim() !== '')
const polylines1 = this.convertBoundaryToPolylines(validBoundaries1, 2)
const validBoundaries2 = type3Data.map(row => row.boundaryStr).filter(boundary =>
typeof boundary === 'string' && boundary.trim() !== '')
const polylines2 = this.convertBoundaryToPolylines(validBoundaries2, 3)
// 将处理后的数据添加到 this.polyline 中
this.polyline = this.polyline.concat(polylines2)
this.polyline = this.polyline.concat(polylines1)
this.polyline = this.polyline.concat(polylines)
this.parkingList = res.data
}
})
},
// 请求运营区停车点,禁行区,
getArea() {
this.polyline = []
this.$u.get(`/app/area/detail?id=${this.cheobj.areaId}`).then((res) => {
if (res.code == 200) {
const polylines = this.convertBoundaryToPolyline(res.data.boundaryStr)
this.polyline.push(polylines)
this.getParking()
}
})
},
}
}
</script>
<style lang="scss">
page {
background: #fff;
border-radius: 0rpx 0rpx 0rpx 0rpx;
}
.active {
image {
z-index: 99 !important;
}
.bike_item {
border: 1px solid #4297F3 !important;
}
}
@keyframes fadeIn {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
.mask {
width: 100%;
height: 100vh;
position: fixed;
top: 0;
left: 0;
background-color: rgba(0, 0, 0, .3);
z-index: 9;
}
.tingchetc {
width: 624rpx;
height: 610rpx;
background: #FFFFFF;
border-radius: 20rpx 20rpx 20rpx 20rpx;
position: fixed;
left: 50%;
transform: translateX(-50%);
top: 572rpx;
z-index: 99;
padding: 28rpx 36rpx;
box-sizing: border-box;
.btnan {
display: flex;
justify-content: space-between;
margin-top: 40rpx;
.fj {
width: 252rpx;
height: 72rpx;
border-radius: 45rpx 45rpx 45rpx 45rpx;
border: 2rpx solid #808080;
font-weight: 600;
font-size: 32rpx;
color: #808080;
text-align: center;
line-height: 72rpx;
}
.qx {
width: 252rpx;
height: 72rpx;
background: #4C97E7;
border-radius: 45rpx 45rpx 45rpx 45rpx;
text-align: center;
line-height: 72rpx;
box-sizing: border-box;
font-weight: 600;
font-size: 32rpx;
color: #FFFFFF;
}
}
.tcimg {
width: 552rpx;
height: 300rpx;
margin-top: 28rpx;
}
.shuom {
font-size: 26rpx;
color: #3D3D3D;
margin-top: 18rpx;
text {
color: #4C97E7;
}
}
.topname {
font-weight: 600;
font-size: 36rpx;
color: #3D3D3D;
display: flex;
align-items: center;
image {
width: 48rpx;
height: 48rpx;
margin-right: 14rpx;
}
}
}
.conts_box {
width: 680rpx;
height: 360rpx;
margin: 0 auto;
display: flex;
flex-wrap: wrap;
align-items: center;
justify-content: space-between;
margin-top: 38rpx;
background: #FFFFFF;
box-shadow: 0rpx 10rpx 64rpx 0rpx rgba(0, 0, 0, 0.08);
border-radius: 20rpx 20rpx 20rpx 20rpx;
padding-bottom: 20rpx;
position: fixed;
left: 50%;
transform: translateX(-50%);
bottom: 220rpx;
.orderzt {
display: flex;
justify-content: space-between;
padding: 0 20rpx;
margin-top: 20rpx;
box-sizing: border-box;
width: 100%;
}
.txtss {
margin-top: 18rpx;
padding-left: 20rpx;
width: 100%;
font-weight: 500;
font-size: 28rpx;
color: #808080;
}
.dh {
width: 160rpx;
height: 60rpx;
border-radius: 30rpx;
text-align: center;
border: 1px solid #333;
font-size: 28rpx;
padding-top: 10rpx;
box-sizing: border-box;
}
.suocheanniu {
display: flex;
align-items: center;
.lssc {
width: 160rpx;
height: 60rpx;
border-radius: 30rpx;
text-align: center;
background-color: #0D75E5;
color: #fff;
font-size: 28rpx;
padding-top: 10rpx;
box-sizing: border-box;
margin-left: 30rpx;
}
}
.cont_li {
width: 100%;
display: flex;
flex-wrap: nowrap;
align-items: center;
justify-content: space-between;
padding: 0 20rpx;
box-sizing: border-box;
.left {
display: flex;
flex-wrap: wrap;
font-weight: 600;
font-size: 36rpx;
color: #3D3D3D;
.km {
font-weight: 400;
font-size: 28rpx;
color: #3D3D3D;
}
.speed {
margin-top: 18rpx;
width: 226rpx;
height: 22rpx;
background: #ccc;
border-radius: 16rpx 16rpx 16rpx 16rpx;
.speeds {
height: 100%;
background: #4297F3;
border-radius: 16rpx 16rpx 16rpx 16rpx;
}
}
.NO {
width: 100%;
font-weight: 400;
font-size: 24rpx;
color: #3D3D3D;
margin-top: 18rpx;
}
}
.right {
width: 70%;
padding-right: 20rpx;
font-size: 24rpx;
color: #333;
image {
width: 160rpx;
height: 110rpx;
}
}
}
}
.picimg {
width: 120rpx;
height: 120rpx;
position: fixed;
left: 50%;
transform: translateX(-50%);
top: 50%;
z-index: 99;
}
.kefutc {
animation: fadeIn 0.5s ease-in-out forwards;
position: fixed;
top: 660rpx;
left: 50%;
transform: translateX(-50%);
z-index: 99;
.bot {
margin-top: 30rpx;
.wz {
margin-top: 10rpx;
font-weight: 600;
font-size: 28rpx;
color: #3D3D3D;
}
.wzs {
margin-top: 10rpx;
font-size: 24rpx;
color: #7C7C7C;
}
}
.top {
width: 538rpx;
height: 122rpx;
background: #FFFFFF;
box-shadow: 0rpx 0rpx 10rpx 0rpx rgba(0, 0, 0, 0.1);
border-radius: 14rpx 14rpx 14rpx 14rpx;
display: flex;
justify-content: space-between;
align-items: center;
padding-right: 14rpx;
box-sizing: border-box;
margin-top: 20rpx;
.dianhua {
font-weight: 600;
font-size: 28rpx;
color: #3D3D3D;
padding-left: 26rpx;
box-sizing: border-box;
}
.boda {
width: 94rpx;
height: 94rpx;
background: #DCEDFF;
border-radius: 8rpx 8rpx 8rpx 8rpx;
text-align: center;
padding-top: 8rpx;
box-sizing: border-box;
text {
display: block;
}
}
}
image {
position: absolute;
top: -280rpx;
z-index: -1;
left: 50%;
transform: translateX(-50%);
width: 614rpx;
height: 748rpx;
}
}
.mask {
width: 100%;
height: 100vh;
position: fixed;
z-index: 98;
background-color: rgba(0, 0, 0, 0.08);
top: 0;
left: 0;
}
.clmask {
width: 100%;
height: 100vh;
position: fixed;
z-index: 98;
background-color: rgba(0, 0, 0, 0.08);
top: 0;
left: 0;
}
.biketc {
position: fixed;
left: 50%;
transform: translateX(-50%);
bottom: 220rpx;
z-index: 99;
background-color: #fff;
border-radius: 30rpx;
width: 700rpx;
margin: auto;
padding-bottom: 30rpx;
box-sizing: border-box;
.topfor {
width: 100%;
margin: auto;
max-height: 664rpx;
background: #fff;
border-radius: 30rpx 30rpx 0 0;
padding: 44rpx 34rpx;
box-sizing: border-box;
position: relative;
.bikeyc {
position: absolute;
top: 20rpx;
right: 32rpx;
font-size: 70rpx;
font-weight: 600;
}
.biketaocan {
display: flex;
overflow: scroll;
.bikelist {
margin-right: 22rpx;
.bike_item {
border: 1px solid #fff;
margin-top: 36rpx;
padding-top: 16rpx;
padding-left: 24rpx;
padding-right: 24rpx;
box-sizing: border-box;
width: 368rpx;
height: 280rpx;
background: #FFFFFF;
box-shadow: 0rpx 10rpx 64rpx 0rpx rgba(0, 0, 0, 0.08);
border-radius: 26rpx 26rpx 26rpx 26rpx;
position: relative;
overflow: hidden;
image {
width: 82rpx;
height: 50rpx;
position: absolute;
top: 0;
right: 0;
z-index: -1;
}
.name {
font-weight: 600;
font-size: 32rpx;
color: #3D3D3D;
}
.qibu {
display: flex;
justify-content: space-between;
font-size: 24rpx;
color: #3D3D3D;
margin-top: 16rpx;
}
.ckxq {
width: 368rpx;
height: 58rpx;
background: #4297F3;
font-weight: 600;
font-size: 28rpx;
color: #FFFFFF;
position: absolute;
left: 0;
bottom: 0;
text-align: center;
line-height: 58rpx;
}
}
}
}
.bikesy {
width: 100%;
border-top: 1rpx solid #D8D8D8;
margin-top: 30rpx;
padding-top: 36rpx;
box-sizing: border-box;
display: flex;
.bikelt {
width: 50%;
text-align: center;
.bikegongli {
font-weight: 600;
font-size: 48rpx;
color: #3D3D3D;
}
.bikets {
font-size: 28rpx;
color: #808080;
margin-bottom: 28rpx;
}
image {
width: 48rpx;
height: 36rpx;
margin-right: 18rpx;
}
}
.bikert {
width: 50%;
text-align: center;
.bikegongli {
font-weight: 600;
font-size: 48rpx;
color: #3D3D3D;
}
.bikets {
font-size: 28rpx;
color: #808080;
margin-bottom: 28rpx;
}
image {
width: 22rpx;
height: 48rpx;
margin-right: 18rpx;
}
}
}
.biketop {
display: flex;
align-items: center;
.bikebeep {
width: 160rpx;
height: 60rpx;
border-radius: 10rpx 10rpx 10rpx 10rpx;
border: 2rpx solid #4C97E7;
font-weight: 600;
font-size: 28rpx;
color: #4C97E7;
text-align: center;
line-height: 60rpx;
margin-left: 80rpx;
}
.bianh {
view {
font-weight: 600;
font-size: 28rpx;
color: #3D3D3D;
}
}
image {
width: 56rpx;
height: 56rpx;
margin-right: 24rpx;
}
}
}
.anniuks {
width: 100%;
// height: 184rpx;
// background: #FFFFFF;
text-align: center;
// line-height: 184rpx;
text {
display: inline-block;
width: 680rpx;
height: 90rpx;
background: #4C97E7;
border-radius: 54rpx 54rpx 54rpx 54rpx;
font-weight: 600;
font-size: 40rpx;
color: #FFFFFF;
text-align: center;
line-height: 90rpx;
}
}
}
.shoptc {
position: fixed;
width: 696rpx;
max-height: 312rpx;
background: #FFFFFF;
border-radius: 20rpx 20rpx 20rpx 20rpx;
bottom: 200rpx;
left: 50%;
transform: translateX(-50%);
padding: 28rpx 34rpx;
box-sizing: border-box;
.cont {
margin-top: 40rpx;
display: flex;
.shuoming {
.name {
font-size: 28rpx;
color: #3D3D3D;
}
.price {
font-size: 24rpx;
color: #FF1C1C;
margin-top: 20rpx;
text {
font-size: 44rpx;
}
}
}
image {
width: 166rpx;
height: 128rpx;
margin-right: 26rpx;
}
}
.juli {
display: flex;
align-items: center;
margin-top: 12rpx;
.mi {
padding: 0 10rpx;
box-sizing: border-box;
height: 38rpx;
line-height: 38rpx;
background: #DCEDFF;
border-radius: 4rpx 4rpx 4rpx 4rpx;
font-size: 24rpx;
color: #0D75E5;
margin-right: 20rpx;
}
.dizhi {
font-size: 28rpx;
color: #808080;
}
}
.top {
display: flex;
justify-content: space-between;
.name {
font-size: 32rpx;
color: #3D3D3D;
font-weight: 600;
}
.zu {
font-size: 24rpx;
color: #3D3D3D;
display: flex;
align-items: center;
image {
width: 22rpx;
height: 22rpx;
}
}
}
}
.rticon {
position: fixed;
right: 28rpx;
top: 260rpx;
image {
width: 78rpx;
height: 96rpx;
display: block;
margin-top: 32rpx;
}
}
.lticon {
position: fixed;
left: 28rpx;
top: 300rpx;
image {
width: 88rpx;
height: 88rpx;
display: block;
margin-top: 32rpx;
}
}
.map {
width: 100%;
height: 100vh;
}
</style>