bike-ali/pages/index/index.vue

1884 lines
45 KiB
Vue
Raw Normal View History

2024-05-08 23:18:30 +08:00
<template>
<view class="page">
<u-navbar :is-back="false" title="共享电动车" :border-bottom="false" :background="bgc" title-color='#2E4975'
title-size='36' height='36'></u-navbar>
<map class="map" id="map" ref="map" :scale="zoomSize" :latitude="latitude" :longitude="longitude"
:show-location="true" :markers="markers" :polygons="polyline" @markertap="onMarkerTap">
</map>
<view class="botmbox2" v-if="showdevice">
<view class="close" @click="close()">
<image src="https://lxnapi.ccttiot.com/bike/img/static/uBeBBKwQu2K2ZBdT7iN7" mode=""></image>
</view>
<view class="page1" v-if="deviceIndex==0">
<view class="top">
<view class="left">
<image src="https://lxnapi.ccttiot.com/bike/img/static/uD9pXetaMb5dmw8aSvoM" mode=""></image>
</view>
<view class="top_center">
<view class="cent_top">
车辆编号{{deviceInfos.sn}}
</view>
<view class="cent_bot">
骑行前请检查车辆状态
</view>
</view>
<view class="top_right" @click="findBike()">
响铃寻车
</view>
</view>
<view class="center">
<view class="center_left">
<view class="center_left_top">
剩余骑行
</view>
<view class="center_left_bot">
{{deviceInfos.remainingMileage}}公里
</view>
</view>
<view class="center_right">
<view class="center_right_top">
预约费10分钟
</view>
<view class="center_right_bot">
{{appointmentServiceFee}} <span></span>
</view>
</view>
</view>
<view class="bot">
<view class="left_btn" @click="qrCode()">
扫码用车
</view>
<view class="right_btn" @click="Reserve()">
预约用车
</view>
</view>
<view class="tips" @click="topage(7)">
发现坏车 >
</view>
</view>
<view class="page2" v-if="deviceIndex==1">
<view class="top">
<!-- <view class="left">
<view class="text">
可行驶53公里
</view>
<view class="ele">
<image src="https://api.ccttiot.com/smartmeter/img/static/upbpFLv4dkl88Syk2VKW" mode=""></image>
电量充足
</view>
</view> -->
<view class="right">
<view class="text">
剩余骑行
</view>
<view class="txt">
{{deviceInfos.remainingMileage}}<span style="font-size: 40rpx;">公里</span>
</view>
</view>
<view class="right">
<view class="text">
起步价{{startingHowManyMinutes}}分钟内
</view>
<view class="txt">
{{startingPrice}}<span style="font-size: 40rpx;"></span>
</view>
</view>
</view>
<view class="center">
<view class="card" :class="freeListIndex==0?'act1':''" @click="freeListIndex=0">
<image src="https://api.ccttiot.com/smartmeter/img/static/uYg1WNJJH1VK7RdldKE1" mode=""
v-if="freeListIndex==0"></image>
<view class="tit">
计时收费
</view>
<view class="nmtxt">
<view class="left">
起步价
</view>
<view class="right">
{{startingPrice}}{{startingHowManyMinutes}}分钟
</view>
</view>
<view class="nmtxt">
<view class="left">
时长费
</view>
<view class="right">
{{timeFee}}/{{ timeMinutes}}分钟
</view>
</view>
<view class="tip">
超出起步价包含时长后收取
</view>
</view>
<view class="card" v-for="(item,index ) in freList" :key="index" @click="changefree(item,index+1)"
:class="freeListIndex==index+1?'act1':''" v-if="isMeal==1">
<image src="https://api.ccttiot.com/smartmeter/img/static/uYg1WNJJH1VK7RdldKE1" mode=""
v-if="freeListIndex==index+1"></image>
<view class="tit">
{{item.name}}
</view>
<view class="nmtxt">
<view class="left">
可骑行{{item.time}}小时
</view>
<view class="right red">
{{item.fee}}<span style="font-size: 24rpx;"> </span>
</view>
</view>
<view class="nmtxt">
<view class="left">
</view>
<view class="right">
原价 <span style=" text-decoration: line-through;">{{item.originalFee}}</span>
</view>
</view>
<view class="tip">
超出起步价包含时长后收取
</view>
</view>
</view>
<view class="bot" style="margin-top: 20rpx;">
<view class="btn" @click="sub1()" v-if="type==1&&freeListIndex==0">
确认开锁
</view>
<view class="btn" @click="sub2()" v-if="type==1&&freeListIndex!=0">
确认套餐
</view>
<view class="btn" @click="sub3()" v-if="type==2&&freeListIndex==0">
确认预约
</view>
<view class="btn" @click="sub4()" v-if="type==2&&freeListIndex!=0">
确认支付
</view>
</view>
</view>
<view class="page3" v-if="deviceIndex==2">
<view class="bot_btn">
<view class="info">
<view class="left">
预估金额{{money}}<span></span>
</view>
<view class="right">
{{timeString}}
</view>
</view>
<view class="card">
<view class="tit">
电单车
</view>
<view class="cont">
<view class="left">
<view class="text">
可继续行驶53公里
</view>
<view class="speed">
<view class="speeds">
</view>
</view>
<view class="mac">
NO.74001387
</view>
</view>
<view class="right">
<image src="https://api.ccttiot.com/smartmeter/img/static/uHTCZOVUbmBkKW4G0wuF" mode=""></image>
</view>
</view>
</view>
<view class="bot" style="margin-top: 20rpx;">
<view class="btn" style=" margin-right: 16rpx;">
解锁骑行
</view>
<view class="btn1" @click="cancel()" >
取消预约
</view>
</view>
<!-- <view class="bot" style="margin-top: 20rpx;">
<view class="btn1" >
临时锁车
</view>
<view class="btn" >
还车
</view>
</view> -->
</view>
</view>
<view class="page4" v-if="deviceIndex==3">
<view class="bot_btn" >
<view class="time">
骑行时间30分钟9秒
</view>
<view class="price">
4.00<span></span>
</view>
<view class="toinfo">
查看骑行费明细 >
</view>
<view class="btn">
去支付
</view>
</view>
</view>
</view>
<view class="botmbox" v-if="showindex==0">
<view class="top_btn" >
<image src="https://api.ccttiot.com/smartmeter/img/static/un6Wi8CefEjy04qzvn67" mode=""
@click="topage(0)"></image>
扫码开锁
</view>
<view class="bot_btn">
<view class="cont" @click="topage(1)">
<image src="https://api.ccttiot.com/smartmeter/img/static/uGDkCwxDNH9oFORX2XNU" mode=""></image>
<view class="text">
押金充值
</view>
</view>
<view class="cont" @click="topage(2)">
<image src="https://api.ccttiot.com/smartmeter/img/static/uFHC2R6R3pgUOTShLxoQ" mode=""
style="width: 28rpx;height: 28rpx;"></image>
<view class="text">
计费规则
</view>
</view>
<view class="cont" @click="topage(3)">
<image src="https://api.ccttiot.com/smartmeter/img/static/utP4rdOzXLlQPx6Ug8cO" mode=""
style="width: 32rpx;height: 32rpx;"></image>
<view class="text">
用车指南
</view>
</view>
<view class="cont" @click="topage(4)">
<image src="https://api.ccttiot.com/smartmeter/img/static/uFaJV6NJGhmmodpEuWMy" mode=""
style="width: 32rpx;height: 32rpx;"></image>
<view class="text">
编号开锁
</view>
</view>
<view class="cont" @click="showindex=1">
<image src="https://api.ccttiot.com/smartmeter/img/static/udQjw62ubIRDIUQqlsTT" mode=""
style="width: 32rpx;height: 32rpx;"></image>
<view class="text">
更多
</view>
</view>
</view>
</view>
<u-mask :show="show" @click="show = false" :z-index='100' />
<view class="pops" v-if="show">
<view class="tit">
安全骑行 禁止超载
</view>
<view class="text">
<view class="yuan">
</view>
<span>临时锁车相当于拔钥匙还在租借中</span>
</view>
<view class="text">
<view class="yuan">
</view>
<span>结束订单在还车点结束订单押金可在个人中心-押金申请押金退还</span>
</view>
<view class="text">
<view class="yuan">
</view>
<span>严禁超载一辆车最多坐两个人</span>
</view>
<view class="text">
<view class="yuan">
</view>
<span>请爱护车辆且注意查看车辆剩余电量</span>
</view>
<view class="btn">
我已阅读同意
</view>
</view>
<view class="bottom_more" v-if="showindex==1">
<view class="close" @click="showindex=0">
<image src="https://api.ccttiot.com/smartmeter/img/static/uM76uO46a5cZOkFlffnX" mode=""></image>
</view>
<div class="tit">
更多用车服务
</div>
<div class="contbox">
<view class="cont_li" @click="topage(1)">
<image src="https://api.ccttiot.com/smartmeter/img/static/uGDkCwxDNH9oFORX2XNU" mode=""></image>
<view class="txt">
押金充值
</view>
</view>
<view class="cont_li" @click="topage(2)">
<image src="https://api.ccttiot.com/smartmeter/img/static/uFHC2R6R3pgUOTShLxoQ" mode=""></image>
<view class="txt">
计费规则
</view>
</view>
<view class="cont_li" @click="topage(3)">
<image src="https://api.ccttiot.com/smartmeter/img/static/utP4rdOzXLlQPx6Ug8cO" mode=""></image>
<view class="txt">
用车指南
</view>
</view>
<view class="cont_li" @click="topage(4)">
<image src="https://api.ccttiot.com/smartmeter/img/static/uFaJV6NJGhmmodpEuWMy" mode=""></image>
<view class="txt">
编号开锁
</view>
</view>
<!-- <view class="cont_li">
<image src="https://api.ccttiot.com/smartmeter/img/static/ulQHy1cQ28kiMLI0T0Uh" mode=""></image>
<view class="txt">
查看停车点
</view>
</view> -->
<view class="cont_li" @click="topage(5)">
<image src="https://api.ccttiot.com/smartmeter/img/static/uucc9g8b2MM6G9vp8HWa" mode=""></image>
<view class="txt">
故障上报
</view>
</view>
<view class="cont_li" @click="topage(6)">
<image src="https://lxnapi.ccttiot.com/bike/img/static/uW1XRPQfJTD6sLimkln5" mode=""></image>
<view class="txt">
个人中心
</view>
</view>
</div>
</view>
</view>
</template>
<script>
export default {
data() {
return {
bgc: {
backgroundColor: "#F7FAFE",
},
showindex: 0,
show: false,
latitude: '26.940805',
longitude: '120.356157',
isMap: false,
zoomSize: 16,
markers: [],
polyline: [],
areas: [],
gps: {},
deviceInfos: {},
showdevice: false,
deviceIndex: 0,
type: 0,
freList: [],
freeListIndex: 0,
freeInfo: {},
socket: null,
sn:'',
eventKey:0,
orderinfo:{},
timer :null,
timeString:'',
money:0
// userId:this.$store.getters.userId,
}
},
watch: {
userId(newValue, oldValue) {
// 处理userId变化的逻辑
console.log('userId 发生变化', newValue, oldValue);
this.getisInOrder()
}
},
onLoad(e) {
if(e.sn){
this.sn=e.sn
this.deviceInfo()
this.showdevice=true
this.deviceIndex = 1
this.type=1
}
},
onShow() {
if (uni.getStorageSync('token')) {
this.$store.dispatch('userInfo', this.$u).then(() => {
// 执行其他操作...
});
}
if(uni.getStorageSync('role')){
let abb = uni.getStorageSync('role')
if(abb==2){
uni.navigateTo({
url:'/page_fix/fix_index'
})
}
}
// this.eventKey = Math.floor(Math.random() * 100000);
console.log(this.userId);
this.getArea()
this.getlist()
setTimeout(() => {
this.getParking()
}, 2000)
// this.role()
this.$store.dispatch('fetchFeeRules', this.$u).then(() => {
// 执行其他操作...
});
// this.fetchFeeRules()
let that = this
uni.getLocation({
type: 'wgs84',
success: function(lb) {
that.gps.latitude = lb.latitude;
that.gps.longitude = lb.longitude;
that.gps.latitude = '26.940805',
that.gps.longitude = '120.356157';
that.getmarks()
},
fail: function(error) {
// 在这里处理获取位置信息失败的情况
}
})
},
computed: {
appointmentServiceFee() {
return this.$store.getters.appointmentServiceFee;
},
dispatchFee() {
return this.$store.getters.dispatchFee;
},
vehicleManagementFee() {
return this.$store.getters.vehicleManagementFee;
},
startingPrice() {
return this.$store.getters.startingPrice;
},
timeFee() {
return this.$store.getters.timeFee;
},
timeMinutes() {
return this.$store.getters.timeMinutes;
},
startingHowManyMinutes() {
return this.$store.getters.startingHowManyMinutes;
},
userId() {
return this.$store.getters.userId;
},
isMeal() {
return this.$store.getters.isMeal;
},
},
methods: {
cancel(){
this.$u.post('/appVerify/device/cancelAppointment?userId=' + this.userId+'&orderNo='+this.orderinfo.orderNo ).then((res) => {
if (res.code === 200) {
this.getisInOrder()
} else {
uni.showToast({
title: res.msg,
icon: 'none',
duration: 2000
});
}
})
},
starTime() {
if(this.orderinfo.status==0&&this.orderinfo.ruleId==null){
this.showdevice = true
this.deviceIndex=2
const createTimeTimestamp = new Date(this.orderinfo.createTime).getTime();
// 定义定时器
this.timer = setInterval(() => {
const currentTime = Date.now();
const timePassed = currentTime - createTimeTimestamp;
const secondsPassed = Math.floor(timePassed / 1000);
// 转换为时分秒格式
const hours = Math.floor(secondsPassed / 3600);
const minutes = Math.floor((secondsPassed % 3600) / 60);
const seconds = secondsPassed % 60;
const timeString = `${hours < 10 ? '0' : ''}${hours}:${minutes < 10 ? '0' : ''}${minutes}:${seconds < 10 ? '0' : ''}${seconds}`;
const tenMinuteIntervals = Math.floor((hours * 60 + minutes) / 10)+1 ; // 加1是因为不满十分钟也算一个十分钟
let money =0
// 增加费用逻辑假设每次增加10元
this.money = this.appointmentServiceFee* tenMinuteIntervals;
// console.log("已经过去了:" + timeString);
// console.log("增加了" +money+ "元费用");
// 每隔十分钟增加费用
if (minutes % 10 === 0 && seconds === 0) {
}
this.timeString=timeString
// console.log("已经过去了:" + timeString);
}, 1000);
}else if(this.orderinfo.status==1&&this.orderinfo.ruleId==null){
// this.topay()
const createTimeTimestamp = new Date(this.orderinfo.createTime).getTime();
// 定义定时器
const currentTime = Date.now();
const timePassed = currentTime - createTimeTimestamp;
const secondsPassed = Math.floor(timePassed / 1000);
// 转换为时分秒格式
const hours = Math.floor(secondsPassed / 3600);
const minutes = Math.floor((secondsPassed % 3600) / 60);
const seconds = secondsPassed % 60;
const timeString = `${hours < 10 ? '0' : ''}${hours}:${minutes < 10 ? '0' : ''}${minutes}:${seconds < 10 ? '0' : ''}${seconds}`;
const tenMinuteIntervals = Math.floor((hours * 60 + minutes) / 10)+1 ; // 加1是因为不满十分钟也算一个十分钟
this.timeString=timeString
// console.log("已经过去了:" + timeString);
this.showdevice = true
this.deviceIndex=3
}
// 将 createTime 转换为时间戳
},
topay(){
let data = {
userId: this.userId,
sn: this.sn,
ruleId: this.freeInfo.ruleId,
isAppointment:true,
// money: this.freeInfo.fee,
mark: "预约购买套餐",
type: '3'
}
console.log('点击了');
this.$u.post('/appVerify/pre/order', data).then((res) => {
if (res.code === 200) {
// this.freList=res.rows
uni.requestPayment({
provider: 'wxpay',
timeStamp: res.data.timeStamp,
nonceStr: res.data.nonceStr,
package: res.data.packageVal,
signType: res.data.signType,
paySign: res.data.paySign,
success(res) {
// 支付成功逻辑
},
fail(err) {
// 支付失败逻辑
uni.showToast({
title: '支付失败',
icon: 'none',
duration: 2000
});
}
});
} else {
uni.showToast({
title: res.msg,
icon: 'none',
duration: 2000
});
}
})
},
topage(num){
if(num==0){
// uni.navigateTo({
// url:''
// })
}else if(num==1){
uni.navigateTo({
url:'/page_user/yj'
})
}else if(num==2){
uni.navigateTo({
url:'/page_user/jfgz'
})
}else if(num==3){
uni.navigateTo({
url:'/page_user/yczn'
})
}else if(num==4){
uni.navigateTo({
url:'/page_user/bhks'
})
}else if(num==5){
uni.navigateTo({
url:'/page_user/gzsb'
})
}else if(num==6){
uni.navigateTo({
url:'/pages/my'
})
}else if(num==7){
uni.navigateTo({
url:'/page_user/gzsb?sn='+this.sn
})
}
},
createWebSocket() {
// 创建 WebSocket 实例,传入 token
let token =uni.getStorageSync('token')
let that =this
this.socket = uni.connectSocket({
url: `ws://192.168.2.8:8080/appVerify/ws/${this.eventKey}`, // WebSocket 服务器地址
header: {
'Authorization': token // 设置 Authorization 请求头
},
success(res) {
console.log('WebSocket 连接成功', res);
},
fail(err) {
console.error('WebSocket 连接失败', err);
}
});
// 监听 WebSocket 接收到消息事件
this.socket.onMessage(res => {
console.log('收到消息:', res.data);
});
// 监听 WebSocket 错误事件
this.socket.onError(err => {
console.error('WebSocket 错误:', err);
});
// 监听 WebSocket 连接关闭事件
this.socket.onClose(() => {
console.log('WebSocket 连接已关闭');
});
},
sendMessage() {
// console.log('发送了消息');
// 发送消息给服务器
this.socket.send({
data: 'Hello, server!'
});
},
closeConnection() {
// 关闭 WebSocket 连接
this.socket.close({
code: 1000, // 关闭连接的代码
reason: 'Closing connection' // 关闭连接的原因
});
},
// 确认开锁
sub1() {
let data = {
userId: this.userId,
sn: this.sn,
// ruleId: this.freeInfo.ruleId,
// money: this.freeInfo.fee,
mark: "确认开锁",
type: '1'
}
this.$u.post('/appVerify/device/snSwitch', data).then((res) => {
if (res.code === 200) {
// this.freList=res.rows
// uni.requestPayment({
// provider: 'wxpay',
// timeStamp: res.data.timeStamp,
// nonceStr: res.data.nonceStr,
// package: res.data.packageVal,
// signType: res.data.signType,
// paySign: res.data.paySign,
// success(res) {
// // 支付成功逻辑
// this.showdevice = false
// this.deviceIndex = 0
// this.mac = ''
// this.type = 0
// this.freeInfo = {}
// this.freeListIndex = 0
// },
// fail(err) {
// // 支付失败逻辑
// uni.showToast({
// title: '支付失败',
// icon: 'none',
// duration: 2000
// });
// }
// });
} else {
}
})
},
// 开锁购买套餐
sub2() {
let data = {
userId: this.userId,
sn: this.sn,
ruleId: this.freeInfo.ruleId,
// money: this.freeInfo.fee,
isAppointment:false,
mark: "套餐开锁",
type: '3'
}
this.$u.post('/appVerify/device/snSwitch', data).then((res) => {
if (res.code === 200) {
// this.freList=res.rows
uni.requestPayment({
provider: 'wxpay',
timeStamp: res.data.timeStamp,
nonceStr: res.data.nonceStr,
package: res.data.packageVal,
signType: res.data.signType,
paySign: res.data.paySign,
success(res) {
// 支付成功逻辑
this.showdevice = false
this.deviceIndex = 0
this.mac = ''
this.type = 0
this.freeInfo = {}
this.freeListIndex = 0
},
fail(err) {
// 支付失败逻辑
uni.showToast({
title: '支付失败',
icon: 'none',
duration: 2000
});
}
});
} else {
uni.showToast({
title: res.msg,
icon: 'none',
duration: 2000
});
}
})
},
// 确认预约
sub3() {
this.$u.post('/appVerify/device/appointment?userId=' + this.userId+'&sn='+this.sn ).then((res) => {
if (res.code === 200) {
uni.showLoading({
title:'预约中...'
})
setTimeout(()=>{
this.getisInOrder()
uni.hideLoading()
},1000)
// this.freList=res.rows
} else {
uni.showToast({
title: res.msg,
icon: 'none',
duration: 2000
});
}
})
},
// 预约购买套餐
sub4() {
let data = {
userId: this.userId,
sn: this.sn,
ruleId: this.freeInfo.ruleId,
isAppointment:true,
// money: this.freeInfo.fee,
mark: "预约购买套餐",
type: '3'
}
console.log('点击了');
this.$u.post('/appVerify/pre/order', data).then((res) => {
if (res.code === 200) {
// this.freList=res.rows
uni.requestPayment({
provider: 'wxpay',
timeStamp: res.data.timeStamp,
nonceStr: res.data.nonceStr,
package: res.data.packageVal,
signType: res.data.signType,
paySign: res.data.paySign,
success(res) {
// 支付成功逻辑
this.showdevice = false
this.deviceIndex = 0
this.mac = ''
this.type = 0
this.freeInfo = {}
this.freeListIndex = 0
},
fail(err) {
// 支付失败逻辑
uni.showToast({
title: '支付失败',
icon: 'none',
duration: 2000
});
}
});
} else {
uni.showToast({
title: res.msg,
icon: 'none',
duration: 2000
});
}
})
},
getisInOrder() {
this.$u.post('/app/user/isInOrder?userId=' + this.userId, ).then((res) => {
if (res.code === 200) {
// this.freList=res.rows
if(res.data!=''){
this.orderinfo=res.data[0]
this.starTime()
}
} else {
}
})
},
changefree(item, index) {
this.freeInfo = item
this.freeListIndex = index
},
getlist() {
this.$u.get('/app/fee/list').then((res) => {
if (res.code === 200) {
this.freList = res.rows
} else {
uni.showToast({
title: '未登录,请登录后尝试',
icon: 'none',
duration: 1000
});
}
})
},
// 发现坏车
// 预约车辆
Reserve() {
if (this.$store.getters.userId == undefined) {
// this.$u.get("/getAppInfo").then((res) => {
// console.log('进入跳转');
// if(res.code==200){
// this.$store.commit('SET_USERID', res.user.userId);
// }
// });
this.$store.dispatch('userInfo', this.$u).then(() => {
this.deviceIndex = 1
this.type = 2
console.log(this.$store.getters.userId,
'this.$store.getters.userIdthis.$store.getters.userId');
// 执行其他操作...
});
} else {
this.deviceIndex = 1
this.type = 2
}
},
// 扫码用车
qrCode() {
if (this.$store.getters.userId == null) {
this.$u.get("/getAppInfo").then((res) => {
console.log('进入跳转');
if (res.code == 200) {
this.$store.commit('SET_USERID', res.user.userId);
this.scanQRCode()
} else {
uni.showToast({
title: '未登录,请登录后尝试',
icon: 'none',
duration: 2000
});
}
});
}
},
// 关闭弹出
close() {
this.showdevice = false
this.deviceIndex = 0
this.sn = ''
this.type = 0
this.freeInfo = {}
this.freeListIndex = 0
},
// 扫码的方法
scanQRCode() {
uni.scanCode({
onlyFromCamera: true,
scanType: ['qrCode'],
success: res => {
console.log('扫描结果:', res);
this.sn = res.sn
this.type = 1
},
fail: err => {
console.error('扫描失败:', err);
uni.showToast({
title: '扫描失败',
icon: 'none'
});
}
});
},
findBike() {
this.$u.post('/app/device/ring?sn=' + this.sn).then((res) => {
if (res.code === 200) {
this.deviceInfos = res.data
}
})
},
onMarkerTap(e) {
if (e.type === 'markertap') {
console.log('点击了标记:', e.markerId);
// 这里可以根据需要处理点击标记的逻辑
// 阻止事件冒泡
this.showindex=0
this.showdevice = true
this.sn = e.markerId
this.deviceInfo()
}
},
deviceInfo() {
this.$u.get('/app/device/info?sn=' + this.sn).then((res) => {
if (res.code === 200) {
this.deviceInfos = res.data
}
})
},
// onMapTap(e) {
// console.log('点击了地图非标记区域:', e);
// // 这里可以根据需要处理点击地图非标记区域的逻辑
// },
getmarks() {
this.$u.get(`/app/vehicleLocalization`, this.gps).then((res) => {
if (res.code === 200) {
this.listData = res.data;
// const markers = data.map(item => {
// return {
// id: item.deviceId,
// latitude: parseFloat(item.latitude),
// longitude: parseFloat(item.longitude),
// title: item.deviceName,
// width : 25,
// height : 30,
// iconPath: 'https://api.ccttiot.com/smartmeter/img/static/uF9qLejuAZErNTrRuHq7',
// };
// });
this.listData.forEach(item => {
this.markers.push({
id: parseFloat(item.sn),
latitude: parseFloat(item.latitude),
longitude: parseFloat(item.longitude),
// title: item.deviceName,
width: 40,
height: 40,
iconPath: 'https://api.ccttiot.com/smartmeter/img/static/uF9qLejuAZErNTrRuHq7',
})
})
// this.markers = markers;
console.log(this.markers, ' this.markers this.markers');
} else {
// 处理接口返回错误的情况
}
}).catch(error => {
// 处理接口请求失败的情况
});
},
getArea() {
// 发送请求获取数据
this.$u.get('/app/area/list').then((res) => {
if (res.code === 200) {
// 处理接口返回的数据,将边界数据转换为地图组件需要的折线结构
const polylines = res.rows
.filter(area => area.boundaryStr) // 过滤掉boundary为空的数据
.map(area => this.convertBoundaryToPolyline(area.boundaryStr));
// 更新折线数据
this.polyline = polylines;
// console.log(this.polyline);
}
}).catch(error => {
console.error("Error fetching area data:", error);
});
},
convertBoundaryToPolylines(boundaries) {
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;
}
const points = coords.map(coord => ({
latitude: coord[1],
longitude: coord[0]
}));
return {
points: points,
fillColor: "#55888840", //填充颜色
strokeColor: "#558888", //描边颜色
strokeWidth: 2, //描边宽度
zIndex: 1, //层级
};
}).filter(polyline => polyline !== null); // 过滤掉无效的折线数据
},
getParking() {
// 发送请求获取数据
this.$u.get('/app/parking/list').then((res) => {
if (res.code === 200) {
// 处理接口返回的数据
const validBoundaries = res.rows.map(row => row.boundaryStr).filter(boundary =>
typeof boundary === 'string' && boundary.trim() !== '');
const polylines = this.convertBoundaryToPolylines(validBoundaries);
// 将处理后的数据添加到 this.polyline 中
this.polyline = this.polyline.concat(polylines);
console.log(this.polyline);
}
}).catch(error => {
console.error("Error fetching parking data:", error);
});
},
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: 2, //描边宽度
zIndex: 1, //层级
};
return polyline;
},
// convertBoundaryToPolylines(boundaries) {
// // 确保 boundaries 是一个有效的数组
// if (!Array.isArray(boundaries)) {
// console.error("Boundaries is not an array:", boundaries);
// return [];
// }
// 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;
// }
// const points = coords.map(coord => ({
// latitude: coord[1],
// longitude: coord[0]
// }));
// return {
// points: points,
// fillColor: "#55888840", //填充颜色
// strokeColor: "#22FF00", //描边颜色
// strokeWidth: 2, //描边宽度
// zIndex: 1, //层级
// };
// }).filter(polyline => polyline !== null); // 过滤掉无效的折线数据
// },
}
}
</script>
<style lang="scss">
page {
// background-color: ;
}
.page {
width: 750rpx;
.map {
width: 750rpx;
height: 80vh;
}
.botmbox2 {
position: fixed;
bottom: 0;
padding: 40rpx 32rpx;
width: 750rpx;
// height: 272rpx;
background: #fff;
border-radius: 50rpx 50rpx 0 0;
z-index: 100;
.close {
position: absolute;
top: 20rpx;
right: 20rpx;
width: 30rpx;
height: 30rpx;
}
.page1 {
.top {
margin-top: 20rpx;
display: flex;
flex-wrap: nowrap;
align-items: center;
padding-bottom: 28rpx;
border-bottom: 2rpx solid #D8D8D8;
.left {
width: 56rpx;
height: 56rpx;
image {
width: 56rpx;
height: 56rpx;
}
}
.top_center {
width: 50%;
display: flex;
flex-wrap: wrap;
margin-left: 28rpx;
.cent_top {
width: 100%;
font-weight: 500;
font-size: 28rpx;
color: #3D3D3D;
}
.cent_bot {
font-weight: 500;
font-size: 20rpx;
color: #808080;
}
}
.top_right {
display: flex;
align-items: center;
justify-content: center;
margin-left: auto;
width: 160rpx;
height: 60rpx;
border-radius: 0rpx 0rpx 0rpx 0rpx;
border: 2rpx solid #4C97E7;
font-weight: 500;
font-size: 28rpx;
color: #4C97E7;
}
}
.center {
margin-top: 42rpx;
display: flex;
flex-wrap: nowrap;
// justify-content: space-around;
padding-bottom: 28rpx;
border-bottom: 2rpx solid #D8D8D8;
.center_left {
width: 50%;
display: flex;
flex-wrap: wrap;
justify-content: center;
.center_left_top {
width: 100%;
text-align: center;
font-weight: 400;
font-size: 24rpx;
color: #808080;
}
.center_left_bot {
margin-top: 32rpx;
width: 100%;
text-align: center;
font-weight: 500;
font-size: 60rpx;
color: #3D3D3D;
}
}
.center_right {
width: 50%;
display: flex;
flex-wrap: wrap;
justify-content: center;
.center_right_top {
width: 100%;
text-align: center;
font-weight: 400;
font-size: 24rpx;
color: #808080;
}
.center_right_bot {
margin-top: 32rpx;
width: 100%;
text-align: center;
font-weight: 500;
font-size: 60rpx;
color: #3D3D3D;
}
}
}
.bot {
margin-top: 42rpx;
display: flex;
flex-wrap: nowrap;
justify-content: space-between;
.left_btn {
display: flex;
align-items: center;
justify-content: center;
width: 338rpx;
height: 90rpx;
border-radius: 45rpx 45rpx 45rpx 45rpx;
border: 2rpx solid #808080;
font-weight: 500;
font-size: 40rpx;
color: #808080;
}
.right_btn {
display: flex;
align-items: center;
justify-content: center;
width: 338rpx;
height: 90rpx;
background: #4C97E7;
border-radius: 45rpx 45rpx 45rpx 45rpx;
font-weight: 500;
font-size: 40rpx;
color: #FFFFFF;
}
}
.tips {
margin-top: 42rpx;
width: 100%;
text-align: center;
font-weight: 400;
font-size: 28rpx;
color: #3D3D3D;
}
}
.page2 {
.top {
display: flex;
flex-wrap: nowrap;
width: 100%;
height: 284rpx;
.left {
display: flex;
flex-wrap: wrap;
justify-content: center;
width: 50%;
padding-top: 68rpx;
.text {
font-weight: 400;
font-size: 24rpx;
color: #808080;
}
.ele {
width: 100%;
display: flex;
flex-wrap: nowrap;
// align-items: center;
justify-content: center;
font-weight: 400;
font-size: 40rpx;
color: #4C97E7;
image {
margin-right: 18rpx;
width: 22rpx;
height: 48rpx;
}
}
}
.right {
width: 50%;
padding-top: 68rpx;
display: flex;
flex-wrap: wrap;
justify-content: center;
.text {
font-weight: 400;
font-size: 24rpx;
color: #808080;
}
.txt {
width: 100%;
display: flex;
flex-wrap: nowrap;
// align-items: center;
// align-items: center;
justify-content: center;
font-weight: 500;
font-size: 72rpx;
color: #3D3D3D;
span {
font-weight: 700;
margin-top: 30rpx;
}
}
}
}
.center::-webkit-scrollbar {
display: none;
}
.center {
width: 750rpx;
display: flex;
// flex-wrap: nowrap;
padding: 0 32rpx;
height: 228rpx;
overflow-x: auto;
/* 添加水平滚动条 */
margin-bottom: 200rpx;
.card {
margin-right: 20rpx;
position: relative;
padding: 16rpx 24rpx;
// width: 368rpx;
height: 228rpx;
background: #FFFFFF;
box-shadow: 0rpx 10rpx 64rpx 0rpx rgba(0, 0, 0, 0.08);
border-radius: 16rpx 16rpx 16rpx 16rpx;
border: 2rpx solid #fff;
image {
position: absolute;
top: 0;
right: 0;
width: 82rpx;
height: 50rpx;
}
.tit {
width: 320rpx;
font-weight: 500;
font-size: 32rpx;
color: #3D3D3D;
}
.nmtxt {
margin-top: 22rpx;
display: flex;
flex-wrap: nowrap;
align-items: center;
justify-content: space-between;
.left {
font-weight: 400;
font-size: 24rpx;
color: #3D3D3D;
}
.right {
font-weight: 400;
font-size: 24rpx;
color: #3D3D3D;
}
.red {
font-weight: 400;
font-size: 36rpx;
color: #FF4444;
}
}
.tip {
margin-top: 14rpx;
font-weight: 400;
font-size: 20rpx;
color: #808080;
}
}
.act1 {
border: 2rpx solid #4C97E7;
}
}
.bot {
display: flex;
align-items: center;
justify-content: center;
position: absolute;
bottom: 0;
left: 0;
width: 750rpx;
height: 184rpx;
background: #FFFFFF;
box-shadow: 0rpx 10rpx 64rpx 0rpx rgba(0, 0, 0, 0.08), 0rpx 10rpx 64rpx 0rpx rgba(0, 0, 0, 0.08);
border-radius: 0rpx 0rpx 0rpx 0rpx;
.btn {
display: flex;
justify-content: center;
align-items: center;
width: 680rpx;
height: 90rpx;
background: #4C97E7;
border-radius: 54rpx 54rpx 54rpx 54rpx;
font-weight: 500;
font-size: 40rpx;
color: #FFFFFF;
}
}
}
.page3{
.bot_btn{
width: 750rpx;
height: 648rpx;
background: #F7F7F7;
box-shadow: 0rpx 10rpx 64rpx 0rpx rgba(0,0,0,0.08);
border-radius: 50rpx 50rpx 0 0 ;
.info{
padding: 0 60rpx;
display: flex;
flex-wrap: nowrap;
align-items: center;
justify-content: space-between;
width: 708rpx;
height: 100rpx;
background: #FFFFFF;
border-radius: 20rpx 20rpx 20rpx 20rpx;
}
.card{
margin-top: 12rpx;
padding: 20rpx 30rpx;
width: 708rpx;
height: 288rpx;
background: #FFFFFF;
border-radius: 20rpx 20rpx 20rpx 20rpx;
.tit{
font-weight: 500;
font-size: 36rpx;
color: #3D3D3D;
}
.cont{
display: flex;
flex-wrap: nowrap;
align-items: center;
justify-content: space-between;
.left{
.text{
font-weight: 400;
font-size: 28rpx;
color: #3D3D3D;
}
.speed{
margin-top: 18rpx;
width: 226rpx;
height: 22rpx;
background: #EFEFEF;
border-radius: 16rpx 16rpx 16rpx 16rpx;
.speeds{
width: 90%;
height: 100%;
background:#77B8FD ;
border-radius: 16rpx 0rpx 0rpx 16rpx;
}
}
.mac{
margin-top: 18rpx;
}
}
.right{
image{
width: 244rpx;
height: 196rpx;
font-weight: 400;
font-size: 24rpx;
color: #3D3D3D;
}
}
}
}
.bot{
display: flex;
align-items: center;
justify-content: center;
position: absolute;
bottom: 0;
left: 0;
width: 750rpx;
height: 184rpx;
background: #FFFFFF;
box-shadow: 0rpx 10rpx 64rpx 0rpx rgba(0,0,0,0.08), 0rpx 10rpx 64rpx 0rpx rgba(0,0,0,0.08);
border-radius: 0rpx 0rpx 0rpx 0rpx;
.btn{
display: flex;
justify-content: center;
align-items: center;
width: 338rpx;
height: 90rpx;
background: #4C97E7;
border-radius: 54rpx 54rpx 54rpx 54rpx;
font-weight: 500;
font-size: 40rpx;
color: #FFFFFF;
}
.btn1{
display: flex;
justify-content: center;
align-items: center;
width: 338rpx;
height: 90rpx;
border-radius: 45rpx 45rpx 45rpx 45rpx;
border: 2rpx solid #808080;
font-weight: 500;
font-size: 40rpx;
color: #808080;
}
}
}
}
.page4{
.bot_btn{
// padding: 26rpx 34rpx 48rpx 34rpx;
// position: fixed;
// display: flex;
// flex-wrap: wrap;
// justify-content: center;
// bottom: 0;
width: 750rpx;
height: 420rpx;
background: #FFFFFF;
box-shadow: 0rpx 10rpx 64rpx 0rpx rgba(0,0,0,0.08);
border-radius: 30rpx;
.time{
// height: 88rpx;
width: 100%;
text-align: center;
padding-bottom: 24rpx;
font-weight: 400;
font-size: 28rpx;
color: #3D3D3D;
border-bottom: 2rpx solid #EFEFEF;
}
.price{
margin-top: 22rpx;
width: 100%;
text-align: center;
font-weight: 500;
font-size: 72rpx;
color: #3D3D3D;
span{
font-size: 28rpx;
font-weight: 500;
}
}
.toinfo{
// margin-top: 12rpx;
width: 100%;
text-align: center;
font-weight: 400;
font-size: 24rpx;
color: #3D3D3D;
}
.btn{
margin-top: 34rpx;
display: flex;
align-items: center;
justify-content: center;
width: 680rpx;
height: 90rpx;
background: #4C97E7;
border-radius: 54rpx 54rpx 54rpx 54rpx;
font-weight: 500;
font-size: 40rpx;
color: #FFFFFF;
}
}
}
}
.botmbox {
position: fixed;
bottom: 0;
padding: 40rpx 32rpx;
width: 750rpx;
height: 272rpx;
background: #fff;
border-radius: 50rpx 50rpx 0 0;
.top_btn {
display: flex;
flex-wrap: nowrap;
align-items: center;
justify-content: center;
width: 686rpx;
height: 90rpx;
background: #4C97E7;
border-radius: 54rpx 54rpx 54rpx 54rpx;
font-weight: 500;
font-size: 40rpx;
color: #FFFFFF;
image {
width: 56rpx;
height: 56rpx;
margin-right: 4rpx;
}
}
.bot_btn {
margin-top: 34rpx;
display: flex;
flex-wrap: nowrap;
align-items: center;
justify-content: space-between;
.cont {
display: flex;
flex-wrap: wrap;
justify-content: center;
width: 80rpx;
image {
width: 29.33rpx;
height: 31.97rpx;
}
.text {
margin-top: 12rpx;
width: 80px;
text-align: center;
font-weight: 400;
font-size: 20rpx;
color: #3D3D3D;
}
}
}
}
.pops {
padding: 46rpx 36rpx;
position: fixed;
top: 400rpx;
left: 74rpx;
width: 604rpx;
height: 606rpx;
background: #fff;
border-radius: 20rpx 20rpx 20rpx 20rpx;
z-index: 110;
.tit {
// width: 604rpx;
text-align: center;
font-weight: 500;
font-size: 36rpx;
color: #3D3D3D;
margin-bottom: 54rpx;
}
.text {
margin-top: 36rpx;
display: flex;
flex-wrap: wrap;
// align-items: center;
.yuan {
margin-top: 10rpx;
margin-right: 12rpx;
width: 20rpx;
height: 20rpx;
background: #000;
border-radius: 50%;
}
span {
width: 90%;
font-weight: 400;
font-size: 28rpx;
color: #3D3D3D;
}
}
.btn {
margin-left: 40rpx;
margin-top: 50rpx;
display: flex;
align-items: center;
justify-content: center;
width: 470rpx;
height: 90rpx;
background: #4C97E7;
border-radius: 54rpx 54rpx 54rpx 54rpx;
font-weight: 500;
font-size: 40rpx;
color: #FFFFFF;
}
}
.bottom_more {
position: fixed;
bottom: 0;
width: 750rpx;
height: 530rpx;
background: linear-gradient(180deg, #EEF5FD 20%, rgba(255, 255, 255, 0)30%), #FFFFFF;
border-radius: 30rpx;
padding: 48rpx 36rpx;
.close {
position: absolute;
right: 32rpx;
top: 32rpx;
width: 32rpx;
height: 32rpx;
image {
width: 32rpx;
height: 32rpx;
}
}
.tit {
font-weight: 500;
font-size: 44rpx;
color: #3D3D3D;
}
.contbox {
margin-top: 44rpx;
width: 100%;
display: flex;
flex-wrap: wrap;
.cont_li {
margin-top: 22rpx;
display: flex;
flex-wrap: wrap;
// align-items: center;
justify-content: center;
width: 158rpx;
height: 124rpx;
background: #FFFFFF;
box-shadow: 0rpx 10rpx 64rpx 0rpx rgba(0, 0, 0, 0.08);
border-radius: 16rpx 16rpx 16rpx 16rpx;
margin-right: 12rpx;
image {
margin-top: 18rpx;
width: 46rpx;
height: 46rpx;
}
.txt {
width: 100%;
margin-top: 10rpx;
text-align: center;
font-weight: 400;
font-size: 24rpx;
color: #3D3D3D;
}
}
}
}
}
</style>