<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" :style="{ width: OrderdeviceInfos.remainingPower + '%' }"> </view> </view> <view class="mac"> NO.{{orderinfo.sn}} </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;" v-if="orderinfo.status==0"> <view class="btn" style=" margin-right: 16rpx;" @click="unlockdevice()"> 解锁骑行 </view> <view class="btn1" @click="cancel()" > 取消预约 </view> </view> <view class="bot" style="margin-top: 20rpx;" v-if="orderinfo.status==2"> <view class="btn" style=" margin-right: 16rpx;" v-if="OrderdeviceInfos.status==3" @click="loackdevice()"> 临时锁车 </view> <view class="btn" style=" margin-right: 16rpx;" v-if="OrderdeviceInfos.status==4" @click="unloackdevices()"> 解锁用车 </view> <view class="btn1" @click="backDevice()" > 还车 </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"> 使用时间:{{timeString}} </view> <view class="price"> {{orderinfo.totalFee}}<span>元</span> </view> <view class="toinfo"> 查看骑行费明细 > </view> <view class="btn" @click="topay()" v-if="orderinfo.status==1"> 去支付 </view> <view class="btn" @click="topay1()" v-if="orderinfo.status==3"> 去支付 </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: {}, OrderdeviceInfos:{}, 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') } // 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) { that.getmarks() // 在这里处理获取位置信息失败的情况 } }) }, 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 }); } }) }, backDevice(){ this.$u.post('/appVerify/device/return?returnType=1&orderNo=' +this.orderinfo.orderNo ).then((res) => { if (res.code === 200) { this.getisInOrder() } else { uni.showToast({ title: res.msg, icon: 'none', duration: 2000 }); } }) }, // 预约解锁骑行 unlockdevice(){ let data = { userId: this.userId, sn: this.orderinfo.sn, // ruleId: this.freeInfo.ruleId, // money: this.freeInfo.fee, mark: "预约开锁", // type: '1', orderNo:this.orderinfo.orderNo } this.$u.post('/appVerify/device/snSwitch', data).then((res) => { if (res.code === 200) { this.getisInOrder() } else { } }) }, unloackdevices(){ this.$u.post('/appVerify/device/unlock?sn='+this.OrderdeviceInfos.sn+'&orderNo='+this.orderinfo.orderNo).then((res) => { if (res.code === 200) { this.getisInOrder() } else { } }) }, // ;临时锁车 loackdevice(){ this.$u.post('/appVerify/device/lock?sn='+this.OrderdeviceInfos.sn+'&orderNo='+this.orderinfo.orderNo).then((res) => { if (res.code === 200) { this.getisInOrder() } else { } }) }, starTime() { clearInterval(this.timer) this.timer=null this.$u.get('/app/device/info?sn=' + this.orderinfo.sn).then((res) => { if (res.code === 200) { this.OrderdeviceInfos = res.data } }) // 预约中 if(this.orderinfo.status==0&&this.orderinfo.ruleId==null){ this.showdevice = true this.deviceIndex=2 const createTimeTimestamp = new Date(this.orderinfo.appointmentStartTime).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 )+this.startingPrice; // 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.appointmentStartTime).getTime(); // 定义定时器 const currentTime = new Date(this.orderinfo.appointmentEndTime).getTime();; 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 )+this.startingPrice; this.timeString=timeString // console.log("已经过去了:" + timeString); this.showdevice = true this.deviceIndex=3 }else if(this.orderinfo.status==2&&this.orderinfo.ruleId==null){ // 开始骑行 // this.topay() 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 )+this.startingPrice; // console.log("已经过去了:" + timeString); // console.log("增加了" +money+ "元费用"); // 每隔十分钟增加费用 if (minutes % 10 === 0 && seconds === 0) { } this.timeString=timeString // console.log("已经过去了:" + timeString); }, 1000); }else if(this.orderinfo.status==3&&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.orderinfo.sn, orderNo:this.orderinfo.orderNo, // money: this.freeInfo.fee, mark: "订单支付", type: '2' } console.log('点击了'); let that =this 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) { // 支付成功逻辑 that.getisInOrder() }, fail(err) { // 支付失败逻辑 uni.showToast({ title: '支付失败', icon: 'none', duration: 2000 }); } }); } else { uni.showToast({ title: res.msg, icon: 'none', duration: 2000 }); } }) }, // 骑行结束支付 topay1(){ let data = { userId: this.userId, sn: this.orderinfo.sn, orderNo:this.orderinfo.orderNo, // money: this.freeInfo.fee, mark: "订单支付", type: '1' } console.log('点击了'); let that =this 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) { // 支付成功逻辑 that.getisInOrder() }, 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.getisInOrder() } 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{ this.showdevice = false this.deviceIndex=0 } } 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>