4644 lines
130 KiB
Vue
4644 lines
130 KiB
Vue
<template>
|
||
<view class="page">
|
||
<u-navbar title=" " :border-bottom="false" back-icon-color="000" :background="bgc" title-color='#000'
|
||
title-size='36' height='44' id="navbar" :custom-back="btnfh">
|
||
</u-navbar>
|
||
<view class="gonggao" @click="btntopgg" v-if="ordernum > 1">
|
||
<image style="position: absolute;left: 20rpx;width: 20rpx;height: 34rpx;" src="https://api.ccttiot.com/smartmeter/img/static/uezO7WsDc6GIeLfAkAWb" mode=""></image>
|
||
<view class="container">
|
||
<view class="scroll-text">
|
||
<view class="scroll-item">
|
||
查看更多<text style="color: #4297F3;">骑行订单</text>,查看详情后可 <text style="color: #4297F3;">点击切换</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
<u-icon name="arrow-right" color="#4297F3" style="position: absolute;right: 10rpx;" size="32"></u-icon>
|
||
</view>
|
||
<!-- 地图 -->
|
||
<view class="">
|
||
<image class="picimg" v-if="iconflag"
|
||
src="https://api.ccttiot.com/smartmeter/img/static/uU4DEpKYqBND0oXDiqod" mode=""></image>
|
||
</view>
|
||
<map class='map' id="map" :latitude="latitude" :longitude="longitude" :markers="covers"
|
||
@markertap="handleMarkerClick" @regionchange="regionchange" :circles="circles" :polygons="polyline"
|
||
:show-location="true">
|
||
</map>
|
||
<view class="lticon">
|
||
<image style="width: 80rpx;height: 80rpx;"
|
||
src="https://api.ccttiot.com/smartmeter/img/static/ucMoHgzqfBeC1lh2vo4Q" @click="btnbz" mode=""></image>
|
||
</view>
|
||
<image style="width: 80rpx;height: 80rpx;position: fixed;right: 22rpx;bottom: 840rpx;"
|
||
@click="toggleIconAndCallout" src="https://api.ccttiot.com/smartmeter/img/static/u6r5tQVe2VO6bvxTLeFT"
|
||
mode=""></image>
|
||
<image style="width: 80rpx;height: 80rpx;position: fixed;right: 22rpx;bottom: 740rpx;"
|
||
src="https://api.ccttiot.com/smartmeter/img/static/ug1ExhYsZmdWWjVvjjuk" @click="btnhuiz" mode=""></image>
|
||
<!-- 车辆弹窗 -->
|
||
<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 v-if="cheobj.remainingPower >= 0 && cheobj.remainingPower < 20 "
|
||
src="https://api.ccttiot.com/smartmeter/img/static/u8M9KmIfHXpmeifTwCzj" mode="">
|
||
</image>
|
||
<image v-if="cheobj.remainingPower >= 20 && cheobj.remainingPower < 50 "
|
||
src="https://api.ccttiot.com/smartmeter/img/static/u2gp2pE9kPGwaJ4MKUxE" mode="">
|
||
</image>
|
||
<image v-if="cheobj.remainingPower >= 50 && cheobj.remainingPower < 80 "
|
||
src="https://api.ccttiot.com/smartmeter/img/static/umm5Ruc5vhNSjeacslwX" mode="">
|
||
</image>
|
||
<image v-if="cheobj.remainingPower >= 80 && cheobj.remainingPower <= 100 "
|
||
src="https://api.ccttiot.com/smartmeter/img/static/uo75cOfYZiQoxZQAI3FH" 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="aspectFill"
|
||
@click="kefuflag = false"></image>
|
||
<view class="box" >
|
||
<view class="" style="max-height: 268rpx;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">
|
||
温馨提示
|
||
</view> -->
|
||
<view class="wzs">
|
||
客服电话高峰期可能遇忙,请耐心等待
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
<view class="mask" style="z-index: 98;background-color: rgba(0, 0, 0, .6);" v-if="kefuflag"></view>
|
||
|
||
<!-- 有订单弹窗 -->
|
||
<view class="conts_box" v-if="orderflag">
|
||
<view class="orderzt">
|
||
<view class="" style="display: flex;align-items: center;">
|
||
<image src="https://api.ccttiot.com/smartmeter/img/static/uc5JSRyb7S6TUCbOiWb3"
|
||
v-if="huiyuanlist.length > 0" class="qixing" mode="" @click="btnhuiyuan"></image>
|
||
<view class="NO">
|
||
<image v-if="orderobj.deviceRemainingPower >= 0 && orderobj.deviceRemainingPower < 20 "
|
||
src="https://api.ccttiot.com/smartmeter/img/static/uPEOcK5sThcn6u2CtbGG" mode=""></image>
|
||
<image v-if="orderobj.deviceRemainingPower >= 20 && orderobj.deviceRemainingPower < 50 "
|
||
src="https://api.ccttiot.com/smartmeter/img/static/ukirjWKpLd9l0HXc1RA5" mode=""></image>
|
||
<image v-if="orderobj.deviceRemainingPower >= 50 && orderobj.deviceRemainingPower < 80 "
|
||
src="https://api.ccttiot.com/smartmeter/img/static/uI9cNuw1Qxl3hS1cKB9V" mode=""></image>
|
||
<image v-if="orderobj.deviceRemainingPower >= 80 && orderobj.deviceRemainingPower <= 100 "
|
||
src="https://api.ccttiot.com/smartmeter/img/static/ulCbP0LzpIp38u6P2fLF" mode=""></image>
|
||
<text v-if="orderobj.deviceRemainingPower >= 80 && orderobj.deviceRemainingPower <= 100 "
|
||
style="color: #16BC32;">{{orderobj.deviceRemainingPower == null ? '--' : orderobj.deviceRemainingPower}}%</text>
|
||
<text v-if="orderobj.deviceRemainingPower >= 50 && orderobj.deviceRemainingPower < 80 "
|
||
style="color: #16BC32;">{{orderobj.deviceRemainingPower == null ? '--' : orderobj.deviceRemainingPower}}%</text>
|
||
<text v-if="orderobj.deviceRemainingPower >= 20 && orderobj.deviceRemainingPower < 50"
|
||
style="color: #e87f25;">{{orderobj.deviceRemainingPower == null ? '--' : orderobj.deviceRemainingPower}}%</text>
|
||
<text v-if="orderobj.deviceRemainingPower >= 0 && orderobj.deviceRemainingPower < 20 "
|
||
style="color: #e81e1e;">{{orderobj.deviceRemainingPower == null ? '--' : orderobj.deviceRemainingPower}}%</text>
|
||
</view>
|
||
<view class="" style="margin-left: 20rpx;font-weight: 600;font-size: 28rpx;color: #3D3D3D;">
|
||
可骑行约{{orderobj.deviceRemainEndurance == null ? '--' : orderobj.deviceRemainEndurance}}km
|
||
</view>
|
||
</view>
|
||
<view class="" style="font-size: 28rpx;color: #4297F3;display: flex;align-items: center;"
|
||
@click="btnkefu">
|
||
<image style="width: 40rpx;height: 40rpx;margin-right: 10rpx;"
|
||
src="https://api.ccttiot.com/smartmeter/img/static/utZyZyusfqjD0TO0iOgZ" mode=""></image> 联系客服
|
||
</view>
|
||
</view>
|
||
<view class="cont_li">
|
||
<view class="one">
|
||
<view class="oneone">
|
||
{{orderobj.rideFee == null ? '0.00' : orderobj.rideFee}} <text>元</text>
|
||
</view>
|
||
<view class="twotwo" style="display: flex;align-items: center;">
|
||
骑行费用
|
||
</view>
|
||
</view>
|
||
<view class="one">
|
||
<view class="oneone">
|
||
{{ rideDurationText }}
|
||
</view>
|
||
<view class="twotwo">
|
||
骑行时长
|
||
</view>
|
||
</view>
|
||
<view class="one">
|
||
<view class="oneone">
|
||
{{orderobj.orderDistance == null ? '0.0' : (orderobj.orderDistance / 1000).toFixed(1)}}
|
||
<text>km</text>
|
||
</view>
|
||
<view class="twotwo">
|
||
骑行距离
|
||
</view>
|
||
</view>
|
||
</view>
|
||
<view class="imgpic">
|
||
<!-- <image @click="btnguzhang" class="gzimg" src="https://api.ccttiot.com/smartmeter/img/static/uNuvhrYF4COxUixSCg1q" mode=""></image>
|
||
<image @click="btnghbike" class="hcimg" src="https://api.ccttiot.com/smartmeter/img/static/uX8eCy3tMz4hMZc6A35P" mode=""></image>
|
||
<image v-if="orderobj.deviceModelEnableSeat == true" @click="btnkzds" src="https://api.ccttiot.com/smartmeter/img/static/u5yuBRYiIeychUXprgzI" mode=""></image> -->
|
||
</view>
|
||
<view class="botbtn">
|
||
<view class="suocheanniu">
|
||
<view class="jsdd" style="width: 290rpx;" @click.stop="btnqd">
|
||
{{orderobj.deviceLockStatus == 1 ? '临时锁车' : '开锁'}}
|
||
</view>
|
||
<view class="lssc" style="width: 380rpx;" @click.stop="btnjsdd">
|
||
我要还车
|
||
</view>
|
||
</view>
|
||
</view>
|
||
<view class="suocheanniu" style="margin-top: 40rpx;padding: 0 80rpx;">
|
||
<image src="https://api.ccttiot.com/smartmeter/img/static/u2N3Owincw5NIqOKmRDQ" @click="btnxl" mode="">
|
||
</image>
|
||
<image src="https://api.ccttiot.com/smartmeter/img/static/uNqmroyWtaYIW9yLn8lw" @click="btnxunche"
|
||
mode=""></image>
|
||
<image v-if="enableChange" src="https://api.ccttiot.com/smartmeter/img/static/ubg3Go1JkwJmzHxUqBdT" @click="btnghbike"
|
||
mode=""></image>
|
||
<image v-if="orderobj.deviceModelEnableSeat == true"
|
||
src="https://api.ccttiot.com/smartmeter/img/static/uqAFkcZMSlfUl7b7mY7m" @click="btnkzds" mode="">
|
||
</image> <!-- 坐垫锁 -->
|
||
<image src="https://api.ccttiot.com/smartmeter/img/static/u5GXMpFXAfVPtX3Vauco" @click="btnguzhang"
|
||
mode=""></image> <!-- 故障 -->
|
||
</view>
|
||
<view class=""
|
||
style="color: #7C7C7C;font-size: 24rpx;margin-top: 30rpx;width: 100%;text-align: center;display: flex;justify-content: center;padding: 0 50rpx;">
|
||
<view class="">
|
||
车牌:{{orderobj.deviceVehicleNum == null ? '--' : orderobj.deviceVehicleNum}} <text
|
||
style="margin-left: 40rpx;">SN:{{orderobj.deviceSn == null ? '--' : orderobj.deviceSn}}</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<view class="daohang" v-if="daohangflag">
|
||
<view class="name">
|
||
{{chexq.name == null ? '--' : chexq.name}}
|
||
<text v-if="chexq.type == 1">停车区</text>
|
||
<text v-if="chexq.type == 2">禁停区</text>
|
||
<text v-if="chexq.type == 3">禁行区</text>
|
||
<text v-if="chexq.type == 4">景区</text>
|
||
</view>
|
||
<view class="shuom">
|
||
{{chexq.remark == null ? '暂无说明' : chexq.remark}}
|
||
</view>
|
||
<image :src="chexq.picture" mode="aspectFill"></image>
|
||
<view class="anniu" @click="btndh">
|
||
导航前往
|
||
</view>
|
||
<view class="cha" @click="daohangflag = false">
|
||
×
|
||
</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" v-if="fajinobj.dispatchFee > 0">查看最近停车点</text> <text
|
||
v-if="fajinobj.manageFee > 0">请规范还车</text>
|
||
</view>
|
||
<image v-if="fajinobj.manageFee > 0"
|
||
src="https://api.ccttiot.com/smartmeter/img/static/u1JsP3mFqiYgfxrlfvA3" class="tcimg"
|
||
mode="aspectFill"></image>
|
||
<image v-if="fajinobj.dispatchFee > 0"
|
||
src="https://api.ccttiot.com/smartmeter/img/static/uVZ6KuaUpYHJgOeSpbv4" class="tcimg"
|
||
mode="aspectFill"></image>
|
||
<view class="btnan">
|
||
<view class="fj" @click="btnfajin">
|
||
缴纳罚金还车
|
||
</view>
|
||
<view class="qx" @click="btnjjqx">
|
||
继续骑行
|
||
</view>
|
||
</view>
|
||
</view>
|
||
<view class="mask" style="z-index: 10;" v-if="fjflag"></view>
|
||
|
||
<!-- 统一动画 -->
|
||
<view class="tongyi" v-if="wenbentxtflag">
|
||
<view class="top">
|
||
<image src="https://api.ccttiot.com/smartmeter/img/static/uft9oJbJIjOd6whGG3cM" mode=""></image>
|
||
{{wenbentxt}} <text class="percentage-text"
|
||
@click="restartPercentageAnimation">{{Math.floor(percentage)}}%</text>
|
||
</view>
|
||
<view class="" style="width: 100%;text-align: center;margin-top: 20rpx;font-size: 26rpx;color: #3D3D3D;">
|
||
{{caozuotext}}
|
||
</view>
|
||
<image class="ddc" v-if="caozuotext == '骑行前请检查车轿刹车是否灵敏,安全骑行'"
|
||
src="https://api.ccttiot.com/%E5%88%B9%E8%BD%A6-1756546350335.gif" mode=""></image>
|
||
<image class="ddc" v-else src="https://api.ccttiot.com/smartmeter/img/static/uKOCB6yMx4VMyBgblz3H" mode="">
|
||
</image>
|
||
</view>
|
||
<view class="mask" v-if="wenbentxtflag"></view>
|
||
|
||
<!-- 统一蓝牙连接失败 -->
|
||
<view class="tongyi" style="height: 1100rpx;padding: 0 20rpx;box-sizing: border-box;" v-if="ljsbflag">
|
||
<view class="" style="font-size: 60rpx;font-weight: 600;position: absolute;top: 0;right: 20rpx;"
|
||
@click="ljsbflag = false">
|
||
×
|
||
</view>
|
||
<view class="bluetooth-error-container">
|
||
<view class="error-header">
|
||
<image class="error-icon"
|
||
src="https://api.ccttiot.com/smartmeter/img/static/uDfEXjApmdS6ByM88pv3" mode=""></image>
|
||
<text class="error-title">蓝牙连接失败</text>
|
||
</view>
|
||
<view class="error-steps">
|
||
<view class="step-item">
|
||
<view class="step-number">1</view>
|
||
<text class="step-text">请检查手机蓝牙是否打开</text>
|
||
</view>
|
||
<view class="step-item">
|
||
<view class="step-number">2</view>
|
||
<text class="step-text">小程序蓝牙权限是否授权</text>
|
||
</view>
|
||
<view class="step-item">
|
||
<view class="step-number">3</view>
|
||
<text class="step-text">如有不解请点击查看教程</text>
|
||
</view>
|
||
</view>
|
||
<view class="tutorial-link" @click="btnjc">
|
||
<text class="tutorial-text">查看教程</text>
|
||
<view class="tutorial-arrow">→</view>
|
||
</view>
|
||
</view>
|
||
<image style="margin-top: 0;" class="ddc" v-if="caozuotext == '骑行前请检查车轿刹车是否灵敏,安全骑行'"
|
||
src="https://api.ccttiot.com/%E5%88%B9%E8%BD%A6-1756546350335.gif" mode=""></image>
|
||
<image style="margin-top: 0;" class="ddc" v-else src="https://api.ccttiot.com/smartmeter/img/static/uKOCB6yMx4VMyBgblz3H" mode=""></image>
|
||
<view class="anniu">
|
||
<view class="lx" @click="btnkefu">
|
||
联系客服
|
||
</view>
|
||
<view class="zx" @click="btnchongshi">
|
||
点击重试
|
||
</view>
|
||
</view>
|
||
</view>
|
||
<view class="mask" v-if="ljsbflag"></view>
|
||
</view>
|
||
</template>
|
||
|
||
<script>
|
||
var xBlufi = require("@/components/blufi/xBlufi.js")
|
||
export default {
|
||
data() {
|
||
return {
|
||
iconobj: this.$store.state.iconobj,
|
||
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,
|
||
showIconAndCallout: false,
|
||
orderflag: false,
|
||
hei: {
|
||
height: '64vh'
|
||
},
|
||
sockedata: {},
|
||
socketTask: null,
|
||
messages: [],
|
||
reconnectAttempts: 0,
|
||
maxReconnectAttempts: 5,
|
||
reconnectInterval: 3000,
|
||
isPageActive: true,
|
||
deviceMac: '',
|
||
newMarkers: '',
|
||
count: 0,
|
||
timer: null,
|
||
user: {},
|
||
xllat: '',
|
||
xllng: '',
|
||
circles: [],
|
||
nearbyMarkers: [],
|
||
listData: [],
|
||
yyid: '',
|
||
cachedPolyline: [], // 缓存多边形数据
|
||
cachedParkingData: {}, // 缓存停车区域数据
|
||
isFirstLoad: true, // 是否是首次加载
|
||
parkingList: [],
|
||
shibainum: 0,
|
||
jiance: false,
|
||
ver_dataflag: 1,
|
||
mac: '',
|
||
deviceid: '',
|
||
devicename: '',
|
||
name: '',
|
||
devicesarr: [],
|
||
findDeviceTimer: null,
|
||
uploadTimer: null, // 定时器ID
|
||
lastUploadTime: 0, // 上次上传时间戳
|
||
isUploading: false, // 上传状态锁
|
||
isRefreshing: false,
|
||
bluetoothData: {},
|
||
lslat: '',
|
||
lslon: '',
|
||
orderDeviceTimer: null, // 订单设备定时器
|
||
wenbentxt: '',
|
||
wenbentxtflag: false,
|
||
percentage: 0, // 百分比数值
|
||
percentageTimer: null, // 百分比动画定时器
|
||
ljsbflag: false,
|
||
chongshinum: '',
|
||
jieshuflag: true,
|
||
rideDurationText: '00:00',
|
||
rideTimer: null,
|
||
huiyuanlist: [],
|
||
daohangflag: false,
|
||
distance: 0,
|
||
chexq: {},
|
||
caozuotext: '',
|
||
enableChange:false,
|
||
scdevlist:[],
|
||
ordernum:0,
|
||
bltRemark:''
|
||
}
|
||
},
|
||
onLoad(e) {
|
||
console.log(e);
|
||
},
|
||
onShow() {
|
||
uni.openBluetoothAdapter({
|
||
success: function (res) {
|
||
this.bltRemark = '蓝牙权限均已打开'
|
||
},
|
||
fail: function (err) {
|
||
console.error('蓝牙适配器初始化失败', err)
|
||
// 蓝牙未打开或初始化失败
|
||
if(err.errMsg == 'openBluetoothAdapter:fail auth deny'){
|
||
this.bltRemark = '微信蓝牙权限没有授权'
|
||
}else if(err.errMsg == 'openBluetoothAdapter:fail open fail'){
|
||
this.bltRemark = '手机蓝牙没有打开'
|
||
}else if(err.errMsg == 'openBluetoothAdapter:fail:not available'){
|
||
this.bltRemark = '手机蓝牙是否打开'
|
||
}
|
||
console.log(this.bltRemark);
|
||
}
|
||
})
|
||
this.getnum()
|
||
this.getorderdevice()
|
||
xBlufi.initXBlufi(1)
|
||
xBlufi.notifyStartDiscoverBle({
|
||
'isStart': true
|
||
})
|
||
xBlufi.listenDeviceMsgEvent(true, this.funListenDeviceMsgEvent)
|
||
uni.getLocation({
|
||
type: 'gcj02',
|
||
success: (res) => {
|
||
this.xllat = res.latitude
|
||
this.xllng = res.longitude
|
||
},
|
||
fail: (err) => {
|
||
console.error('获取位置失败:', err)
|
||
}
|
||
})
|
||
this.getAone()
|
||
this.covers = []
|
||
this.sockedata = ''
|
||
setTimeout(() => {
|
||
this.setMapScale()
|
||
}, 500)
|
||
this.polyline = []
|
||
this.isFirstLoad = true // 重置首次加载标志
|
||
setTimeout(() => {
|
||
this.toggleIconAndCallout()
|
||
}, 3000)
|
||
},
|
||
onUnload() {
|
||
this.clearTimer()
|
||
this.stopOrderDeviceTimer() // 停止订单设备定时器
|
||
this.stopRideTimer()
|
||
this.stopPercentageAnimation() // 停止百分比动画
|
||
this.isPageActive = false
|
||
this.closeWebSocket()
|
||
if (this.findDeviceTimer) {
|
||
clearTimeout(this.findDeviceTimer)
|
||
this.findDeviceTimer = null
|
||
}
|
||
},
|
||
onHide() {
|
||
if (this.findDeviceTimer) {
|
||
clearTimeout(this.findDeviceTimer)
|
||
this.findDeviceTimer = null
|
||
}
|
||
this.clearTimer()
|
||
this.stopOrderDeviceTimer() // 停止订单设备定时器
|
||
this.stopRideTimer()
|
||
this.stopPercentageAnimation() // 停止百分比动画
|
||
// 页面隐藏时关闭连接
|
||
this.isPageActive = false
|
||
this.closeWebSocket()
|
||
},
|
||
// 组件销毁时清除定时器
|
||
beforeDestroy() {
|
||
clearTimeout(this.uploadTimer)
|
||
this.stopOrderDeviceTimer() // 停止订单设备定时器
|
||
this.stopPercentageAnimation() // 停止百分比动画
|
||
},
|
||
watch: {
|
||
wenbentxtflag(newVal) {
|
||
if (newVal) {
|
||
// 当wenbentxtflag变为true时,启动百分比动画
|
||
setTimeout(() => {
|
||
this.startPercentageAnimation()
|
||
}, 500)
|
||
} else {
|
||
// 当wenbentxtflag变为false时,停止百分比动画
|
||
this.stopPercentageAnimation()
|
||
this.percentage = 0
|
||
}
|
||
}
|
||
},
|
||
methods: {
|
||
// 查询订单数量
|
||
getnum(){
|
||
this.$u.get(`/app/orderDevice/mineUsingCount`).then(res => {
|
||
if (res.code == 200) {
|
||
this.ordernum = res.data
|
||
}
|
||
})
|
||
},
|
||
|
||
// 点击跳转进行中订单列表页
|
||
btntopgg(){
|
||
uni.navigateTo({
|
||
url:'/page_shanghu/yunwei/xzshebei'
|
||
})
|
||
},
|
||
|
||
// 启动百分比动画
|
||
startPercentageAnimation() {
|
||
this.percentage = 0
|
||
this.percentageTimer = setInterval(() => {
|
||
if (this.percentage < 98) {
|
||
// 使用缓动函数,让动画更自然
|
||
const remaining = 98 - this.percentage
|
||
const increment = Math.max(1, remaining * 0.1) // 越接近98%增长越慢,最小增长1
|
||
this.percentage += increment
|
||
if (this.percentage > 98) {
|
||
this.percentage = 98
|
||
}
|
||
} else {
|
||
clearInterval(this.percentageTimer)
|
||
this.percentageTimer = null
|
||
}
|
||
}, 80) // 每80ms更新一次,让动画更流畅
|
||
},
|
||
// 停止百分比动画
|
||
stopPercentageAnimation() {
|
||
if (this.percentageTimer) {
|
||
clearInterval(this.percentageTimer)
|
||
this.percentageTimer = null
|
||
}
|
||
},
|
||
// 重新开始百分比动画
|
||
restartPercentageAnimation() {
|
||
this.stopPercentageAnimation()
|
||
setTimeout(() => {
|
||
this.startPercentageAnimation()
|
||
}, 100)
|
||
},
|
||
// 规划路线
|
||
handleMarkerClick(e) {
|
||
console.log(e);
|
||
this.getcha(e.markerId)
|
||
this.daohangflag = true
|
||
},
|
||
// 查询运营区信息
|
||
getcha(id) {
|
||
this.$u.get(`/app/areaSub/detail?id=${id}`).then(res => {
|
||
if (res.code == 200) {
|
||
this.chexq = res.data
|
||
}
|
||
})
|
||
},
|
||
// 点击跳转导航
|
||
btndh() {
|
||
uni.openLocation({
|
||
latitude: this.chexq.latitude, //纬度-目的地/坐标点
|
||
longitude: this.chexq.longitude, //经度-目的地/坐标点
|
||
name: this.chexq.name, //地点名称
|
||
address: this.chexq.name //详细地点名称
|
||
})
|
||
},
|
||
|
||
// 计算骑行时长显示(按时和分,不到一分钟显示一分钟)
|
||
computeRideDurationText() {
|
||
if (!this.orderobj || !this.orderobj.orderStartTime) {
|
||
this.rideDurationText = '00:00'
|
||
return
|
||
}
|
||
let startMs = null
|
||
const os = this.orderobj.orderStartTime
|
||
if (typeof os === 'number') {
|
||
startMs = os
|
||
} else if (typeof os === 'string') {
|
||
const parsed = Date.parse(os.replace(/-/g, '/'))
|
||
startMs = isNaN(parsed) ? null : parsed
|
||
} else if (os instanceof Date) {
|
||
startMs = os.getTime()
|
||
}
|
||
if (!startMs) {
|
||
this.rideDurationText = '00:00'
|
||
return
|
||
}
|
||
const now = Date.now()
|
||
let diffMs = Math.max(0, now - startMs)
|
||
let totalMinutes = Math.floor(diffMs / 60000)
|
||
if (totalMinutes < 1) totalMinutes = 1
|
||
const hours = Math.floor(totalMinutes / 60)
|
||
const minutes = totalMinutes % 60
|
||
const hh = hours.toString().padStart(2, '0')
|
||
const mm = minutes.toString().padStart(2, '0')
|
||
this.rideDurationText = `${hh}:${mm}`
|
||
},
|
||
// 启动骑行时长定时器
|
||
startRideTimer() {
|
||
this.stopRideTimer()
|
||
this.computeRideDurationText()
|
||
this.rideTimer = setInterval(() => {
|
||
this.computeRideDurationText()
|
||
}, 1000)
|
||
},
|
||
// 停止骑行时长定时器
|
||
stopRideTimer() {
|
||
if (this.rideTimer) {
|
||
clearInterval(this.rideTimer)
|
||
this.rideTimer = null
|
||
}
|
||
},
|
||
// 点击查看蓝牙连接教程
|
||
btnjc() {
|
||
uni.navigateTo({
|
||
url: '/page_user/yongche/index?type=2'
|
||
})
|
||
},
|
||
// 点击进行操作重试
|
||
btnchongshi() {
|
||
this.ljsbflag = false
|
||
if (this.chongshinum == '解锁' || this.chongshinum == '锁车') {
|
||
this.btnqd()
|
||
} else if (this.chongshinum == '还车') {
|
||
this.btnjsdd()
|
||
} else if (this.chongshinum == '换车') {
|
||
this.btnghbike()
|
||
} else if (this.chongshinum == '响铃') {
|
||
this.btnxl()
|
||
}
|
||
},
|
||
// 点击请求客服列表进行咨询
|
||
btnkefu() {
|
||
this.$u.get(`/app/customerService/list?pageNum=1&pageSize=999&areaId=${this.orderobj.orderAreaId}`).then(
|
||
res => {
|
||
if (res.code == 200) {
|
||
if (res.rows.length > 0) {
|
||
this.kefulist = res.rows
|
||
this.kefuflag = true
|
||
} else {
|
||
uni.showToast({
|
||
title: '当前运营区暂无客服',
|
||
icon: 'none',
|
||
duration: 2000
|
||
})
|
||
}
|
||
} else {
|
||
uni.showToast({
|
||
title: res.msg,
|
||
icon: 'none',
|
||
duration: 2000
|
||
})
|
||
}
|
||
})
|
||
},
|
||
// 点击跳转导航寻车
|
||
btnxunche() {
|
||
this.$u.get(`/app/device/detailByOrderId?orderId=${this.orderobj.orderId}&supportLocation=true`).then((
|
||
res) => {
|
||
if (res.code == 200) {
|
||
uni.openLocation({
|
||
latitude: res.data.latitude, //纬度-目的地/坐标点
|
||
longitude: res.data.longitude, //经度-目的地/坐标点
|
||
// name: res.data.deviceVehicleNum, //地点名称
|
||
})
|
||
} else {
|
||
uni.showToast({
|
||
title: res.msg,
|
||
icon: 'none',
|
||
duration: 2000
|
||
})
|
||
}
|
||
})
|
||
},
|
||
// 点击车辆响铃
|
||
btnxl() {
|
||
this.scdevlist = this.devicesarr.map(item => {
|
||
const name = item.name || ''
|
||
return name.slice(-12)
|
||
})
|
||
if (this.jiance == true) {
|
||
xBlufi.initXBlufi(1)
|
||
xBlufi.notifyStartDiscoverBle({
|
||
'isStart': true
|
||
})
|
||
xBlufi.listenDeviceMsgEvent(true, this.funListenDeviceMsgEvent)
|
||
}
|
||
this.wenbentxt = '车辆响铃中...'
|
||
this.wenbentxtflag = true
|
||
uni.getLocation({
|
||
type: 'gcj02',
|
||
success: (res) => {
|
||
console.log(res);
|
||
this.xllat = res.latitude
|
||
this.xllng = res.longitude
|
||
},
|
||
fail: (err) => {
|
||
console.error('获取位置失败:', err)
|
||
}
|
||
})
|
||
let data = {
|
||
id:this.orderobj.deviceId,
|
||
lat:this.xllat,
|
||
lon:this.xllng,
|
||
macList:this.scdevlist
|
||
}
|
||
this.$u.put(`/app/device/iot/ring`,data).then((res) => {
|
||
if (res.code == 200) {
|
||
this.wenbentxt = ''
|
||
this.wenbentxtflag = false
|
||
uni.showToast({
|
||
title: '操作成功',
|
||
icon: 'success',
|
||
duration: 2000
|
||
})
|
||
} else if (res.code == 20001) {
|
||
this.wenbentxt = '蓝牙响铃中...'
|
||
let that = this
|
||
const findDevice = () => {
|
||
that.ver_dataflag = 2
|
||
const matchedDevice = that.devicesarr.find(device => {
|
||
return device.name.slice(-12) == that.mac.slice(-12)
|
||
})
|
||
if (matchedDevice) {
|
||
xBlufi.notifyStartDiscoverBle({
|
||
'isStart': false
|
||
})
|
||
xBlufi.notifyConnectBle({
|
||
isStart: true,
|
||
deviceId: matchedDevice.deviceId,
|
||
name: matchedDevice.name
|
||
})
|
||
that.deviceid = matchedDevice.deviceId
|
||
that.devicename = matchedDevice.name
|
||
setTimeout(() => {
|
||
if (that.ver_dataflag == 3) {
|
||
that.wenbentxt = ''
|
||
that.wenbentxtflag = false
|
||
xBlufi.notifySendCustomData({
|
||
customData: "11play1@"
|
||
})
|
||
} else {
|
||
that.chongshinum = '响铃'
|
||
that.ver_dataflag = 1
|
||
that.shibainum = 0
|
||
that.wenbentxt = ''
|
||
that.wenbentxtflag = false
|
||
that.ljsbflag = true
|
||
uni.openBluetoothAdapter({
|
||
success: function (res) {
|
||
|
||
},
|
||
fail: function (err) {
|
||
console.error('蓝牙适配器初始化失败', err)
|
||
// 蓝牙未打开或初始化失败
|
||
if(err.errMsg == 'openBluetoothAdapter:fail auth deny'){
|
||
uni.showToast({
|
||
title: '请检查微信蓝牙权限是否授权',
|
||
icon: 'none',
|
||
duration:5000
|
||
})
|
||
}else if(err.errMsg == 'openBluetoothAdapter:fail open fail'){
|
||
uni.showToast({
|
||
title: '请检查手机蓝牙是否打开',
|
||
icon: 'none',
|
||
duration:5000
|
||
})
|
||
}else if(err.errMsg == 'openBluetoothAdapter:fail:not available'){
|
||
uni.showToast({
|
||
title: '请检查手机蓝牙是否打开',
|
||
icon: 'none',
|
||
duration:5000
|
||
})
|
||
}
|
||
}
|
||
})
|
||
}
|
||
}, 4000)
|
||
} else {
|
||
if (that.shibainum < 3) {
|
||
that.shibainum++
|
||
that.findDeviceTimer = setTimeout(findDevice.bind(that),1000) // 使用 bind 保持 this 上下文
|
||
} else {
|
||
that.chongshinum = '响铃'
|
||
that.ver_dataflag = 1
|
||
that.shibainum = 0
|
||
that.wenbentxt = ''
|
||
that.wenbentxtflag = false
|
||
that.ljsbflag = true
|
||
let lanya = ''
|
||
if (that.jiance == true) {
|
||
lanya = '蓝牙未开启'
|
||
} else {
|
||
lanya = '蓝牙已开启'
|
||
}
|
||
let data = {
|
||
mac: that.mac,
|
||
orderId: that.orderobj.orderId,
|
||
reason: '用户蓝牙响铃失败' + lanya,
|
||
command: '11play1@',
|
||
lat: that.lat,
|
||
lon: that.lon,
|
||
result: '失败'
|
||
}
|
||
that.$u.post(`/app/commandLog/bluetooth`, data).then(res => {})
|
||
uni.openBluetoothAdapter({
|
||
success: function (res) {
|
||
|
||
},
|
||
fail: function (err) {
|
||
console.error('蓝牙适配器初始化失败', err)
|
||
// 蓝牙未打开或初始化失败
|
||
if(err.errMsg == 'openBluetoothAdapter:fail auth deny'){
|
||
uni.showToast({
|
||
title: '请检查微信蓝牙权限是否授权',
|
||
icon: 'none',
|
||
duration:5000
|
||
})
|
||
}else if(err.errMsg == 'openBluetoothAdapter:fail open fail'){
|
||
uni.showToast({
|
||
title: '请检查手机蓝牙是否打开',
|
||
icon: 'none',
|
||
duration:5000
|
||
})
|
||
}else if(err.errMsg == 'openBluetoothAdapter:fail:not available'){
|
||
uni.showToast({
|
||
title: '请检查手机蓝牙是否打开',
|
||
icon: 'none',
|
||
duration:5000
|
||
})
|
||
}
|
||
}
|
||
})
|
||
}
|
||
}
|
||
}
|
||
findDevice()
|
||
} else {
|
||
this.wenbentxt = ''
|
||
this.wenbentxtflag = false
|
||
uni.showToast({
|
||
title: res.msg,
|
||
icon: 'none',
|
||
duration: 3000
|
||
})
|
||
}
|
||
})
|
||
},
|
||
// 获取附近蓝牙设备列表
|
||
funListenDeviceMsgEvent: function(options) {
|
||
switch (options.type) {
|
||
case xBlufi.XBLUFI_TYPE.TYPE_STATUS_CONNECTED: //监听蓝牙是否断开
|
||
if (!options.result) {
|
||
this.ver_dataflag = 1
|
||
console.log(this.ver_dataflag, '断开断开');
|
||
clearTimeout(this.uploadTimer) //清除每十秒传一次的定时
|
||
this.jiance = true
|
||
}
|
||
break;
|
||
case xBlufi.XBLUFI_TYPE.TYPE_GET_DEVICE_LISTS: //获取附近蓝牙设备列表
|
||
if (options.result) {
|
||
this.devicesarr = options.data
|
||
}
|
||
break;
|
||
case xBlufi.XBLUFI_TYPE.TYPE_CONNECTED: //连接回调是否连接上蓝牙
|
||
console.log("连接回调:" + JSON.stringify(options))
|
||
if (options.result == true) {
|
||
setTimeout(() => {
|
||
this.ver_dataflag = 3
|
||
}, 2000)
|
||
xBlufi.notifyInitBleEsp32({
|
||
deviceId: this.deviceid
|
||
})
|
||
this.deviceid = options.data.deviceId
|
||
this.name = this.name
|
||
} else {
|
||
this.ver_dataflag = 1
|
||
}
|
||
break;
|
||
case xBlufi.XBLUFI_TYPE.TYPE_RECIEVE_CUSTON_DATA: //接收蓝牙传输数据
|
||
console.log("1收到设备发来的自定义数据结果:", options.data)
|
||
this.getlysj(options.data)
|
||
break;
|
||
case xBlufi.XBLUFI_TYPE.TYPE_GET_DEVICE_LISTS_START: //判断蓝牙是否初始化成功兼是否开启蓝牙
|
||
if (!options.result) {
|
||
console.log('蓝牙未开启')
|
||
this.jiance = true
|
||
return
|
||
}
|
||
break;
|
||
}
|
||
},
|
||
// 解析接收的蓝牙数据
|
||
getlysj(data) {
|
||
if (!data) return;
|
||
// 1. 更健壮的数据解析
|
||
const dataStr = data.toString();
|
||
// console.log('原始数据:', dataStr);
|
||
const dataObj = {};
|
||
// 判断数据格式:检查是否包含@或,分隔符
|
||
let separator = ',';
|
||
if (dataStr.includes('@')) {
|
||
separator = '@';
|
||
}
|
||
dataStr.split(separator).forEach(part => {
|
||
if (!part) return; // 忽略空字符串
|
||
let key, value;
|
||
// 如果使用@分隔符,数据格式为 key-value 对,例如: status0@csq0@bat125@...
|
||
if (separator === '@') {
|
||
// 使用正则表达式分离键(字母)和值(数字)
|
||
const match = part.match(/^([a-zA-Z]+)(.*)$/);
|
||
if (!match) return;
|
||
key = match[1];
|
||
value = match[2];
|
||
} else {
|
||
// 如果使用,分隔符,数据格式为 key:value 对,例如: status:0,csq:0,bat:125,...
|
||
const [keyPart, valuePart] = part.split(':').map(item => item.trim());
|
||
if (!keyPart || valuePart === undefined) return;
|
||
key = keyPart;
|
||
value = valuePart;
|
||
}
|
||
if (key && value !== undefined) {
|
||
switch (key) {
|
||
case 'status':
|
||
dataObj.status = value;
|
||
break;
|
||
case 'bat':
|
||
dataObj.bat = parseFloat(value);
|
||
break;
|
||
case 'csq':
|
||
dataObj.csq = parseInt(value, 10);
|
||
break;
|
||
case 'lat':
|
||
dataObj.lat = parseFloat(value);
|
||
break;
|
||
case 'lon':
|
||
dataObj.lon = parseFloat(value);
|
||
break;
|
||
case 'q':
|
||
dataObj.q = parseInt(value, 10);
|
||
break;
|
||
case 's':
|
||
dataObj.s = parseInt(value, 10);
|
||
break;
|
||
}
|
||
}
|
||
})
|
||
// 2. 获取定位
|
||
uni.getLocation({
|
||
type: 'gcj02',
|
||
isHighAccuracy: true,
|
||
success: (res) => {
|
||
this.submitData({
|
||
...dataObj,
|
||
lon: res.longitude,
|
||
lat: res.latitude
|
||
})
|
||
},
|
||
fail: () => {
|
||
this.submitData({
|
||
...dataObj,
|
||
lon: dataObj.lon || 0,
|
||
lat: dataObj.lat || 0
|
||
})
|
||
}
|
||
})
|
||
},
|
||
// 3. 单独封装数据提交
|
||
submitData(data) {
|
||
const payload = {
|
||
mac: this.mac,
|
||
sys: {
|
||
bat: data.bat !== undefined && data.bat !== null ? Number(data.bat) : 0,
|
||
csq: data.csq !== undefined && data.csq !== null ? Number(data.csq) : 0,
|
||
s: data.s !== undefined && data.s !== null ? Number(data.s) : null,
|
||
q: data.q !== undefined && data.q !== null ? Number(data.q) : null,
|
||
status: String(data.status || '0'),
|
||
lon: data.lon !== undefined && data.lon !== null ? Number(data.lon) : 0,
|
||
lat: data.lat !== undefined && data.lat !== null ? Number(data.lat) : 0
|
||
}
|
||
}
|
||
this.bluetoothData = payload
|
||
this.throttledUpload()
|
||
},
|
||
// 节流上传控制
|
||
throttledUpload() {
|
||
const now = Date.now()
|
||
const throttleInterval = 10000 // 10秒
|
||
clearTimeout(this.uploadTimer)
|
||
// 如果距离上次上传超过10秒且没有正在上传的请求
|
||
if (now - this.lastUploadTime >= throttleInterval && !this.isUploading) {
|
||
this.doUpload()
|
||
} else {
|
||
const remainingTime = throttleInterval - (now - this.lastUploadTime)
|
||
this.uploadTimer = setTimeout(() => {
|
||
this.doUpload()
|
||
}, remainingTime)
|
||
}
|
||
},
|
||
// 实际执行上传
|
||
doUpload() {
|
||
if (!this.bluetoothData || this.isUploading) return
|
||
this.isUploading = true
|
||
this.lastUploadTime = Date.now()
|
||
this.$u.put(`/app/device/iot/bltUpload`, this.bluetoothData).then(res => {
|
||
if (res.code == 200) {
|
||
console.log('上传蓝牙数据成功', this.bluetoothData, new Date().toLocaleTimeString())
|
||
} else {
|
||
console.log('上传蓝牙数据失败', res.msg)
|
||
}
|
||
}).catch(err => {
|
||
console.error('上传异常:', err)
|
||
}).finally(() => {
|
||
this.isUploading = false
|
||
})
|
||
},
|
||
// 开坐垫锁
|
||
btnkzds(){
|
||
this.scdevlist = this.devicesarr.map(item => {
|
||
const name = item.name || ''
|
||
return name.slice(-12)
|
||
})
|
||
let that = this
|
||
uni.openBluetoothAdapter({
|
||
success: function (res) {
|
||
that.bltRemark = '蓝牙权限均已打开'
|
||
that.btnkzs()
|
||
},
|
||
fail: function (err) {
|
||
console.error('蓝牙适配器初始化失败', err)
|
||
// 蓝牙未打开或初始化失败
|
||
if(err.errMsg == 'openBluetoothAdapter:fail auth deny'){
|
||
that.bltRemark = '微信蓝牙权限没有授权'
|
||
that.btnkzs()
|
||
}else if(err.errMsg == 'openBluetoothAdapter:fail open fail'){
|
||
that.bltRemark = '手机蓝牙没有打开'
|
||
that.btnkzs()
|
||
}else if(err.errMsg == 'openBluetoothAdapter:fail:not available'){
|
||
that.bltRemark = '手机蓝牙是否打开'
|
||
that.btnkzs()
|
||
}else{
|
||
that.bltRemark = `其他错误 + ${err.errMsg}`
|
||
that.btnkzs()
|
||
}
|
||
}
|
||
})
|
||
},
|
||
btnkzs() {
|
||
uni.getLocation({
|
||
type: 'gcj02', // 国内地图更兼容
|
||
isHighAccuracy: true,
|
||
accuracy: 'best',
|
||
success: (res) => {
|
||
// console.log('精确坐标:', res)
|
||
this.lslat = res.latitude
|
||
this.lslon = res.longitude
|
||
},
|
||
fail: (err) => {
|
||
console.error('获取位置失败:', err)
|
||
this.lslat = null
|
||
this.lslat = null
|
||
}
|
||
})
|
||
let that = this
|
||
uni.showModal({
|
||
title: '提示',
|
||
content: '您是否要开启坐垫锁?',
|
||
showCancel: true,
|
||
success: function(res) {
|
||
if (res.confirm) {
|
||
uni.showLoading({
|
||
title: '加载中...',
|
||
mask: true
|
||
})
|
||
let data = {
|
||
orderId: that.orderobj.orderId,
|
||
lon: that.lslon,
|
||
lat: that.lslat,
|
||
requiredIot: true,
|
||
bltRemark:that.bltRemark
|
||
}
|
||
that.$u.put("/app/order/seat", data).then((res) => {
|
||
if (res.code == 200) {
|
||
uni.showToast({
|
||
title: '打开成功',
|
||
icon: 'success',
|
||
duration: 2000
|
||
})
|
||
} else if (res.code == 20001) {
|
||
uni.hideLoading()
|
||
if (that.ver_dataflag != 3) {
|
||
uni.showLoading({
|
||
title: '坐垫锁开启中...',
|
||
mask: true
|
||
})
|
||
this.ver_dataflag = 2
|
||
const matchedDevice = this.devicesarr.find(device => {
|
||
return device.name.slice(-12) == this.mac.slice(-12)
|
||
})
|
||
if (matchedDevice) {
|
||
xBlufi.notifyStartDiscoverBle({
|
||
'isStart': false
|
||
})
|
||
xBlufi.notifyConnectBle({
|
||
isStart: true,
|
||
deviceId: matchedDevice.deviceId,
|
||
name: matchedDevice.name
|
||
})
|
||
this.deviceid = matchedDevice.deviceId
|
||
this.devicename = matchedDevice.name
|
||
setTimeout(() => {
|
||
uni.hideLoading()
|
||
xBlufi.notifySendCustomData({
|
||
customData: "11hpen@"
|
||
})
|
||
}, 4000)
|
||
} else {
|
||
if (this.shibainum < 3) {
|
||
this.shibainum++
|
||
this.findDeviceTimer = setTimeout(this.findDevice.bind(this), 1000) // 使用 bind 保持 this 上下文
|
||
} else {
|
||
this.ver_dataflag = 1
|
||
this.shibainum = 0
|
||
uni.showModal({
|
||
title: '提示',
|
||
content: '开启坐垫锁失败,请重试',
|
||
showCancel: false,
|
||
success: function(res) {
|
||
if (res.confirm) {
|
||
|
||
} else if (res.cancel) {
|
||
|
||
}
|
||
}
|
||
})
|
||
}
|
||
}
|
||
}
|
||
} else {
|
||
uni.hideLoading()
|
||
uni.showToast({
|
||
title: res.msg,
|
||
icon: 'none',
|
||
duration: 2000
|
||
})
|
||
}
|
||
})
|
||
}
|
||
}
|
||
})
|
||
},
|
||
// 点击自定义返回页面
|
||
btnfh() {
|
||
uni.reLaunch({
|
||
url: '/pages/nearbystores/index?qbtype=1'
|
||
})
|
||
},
|
||
// 拖动查询中心点的数据
|
||
regionchange(e) {},
|
||
// 解析判断赋值车辆状态
|
||
status(item) {
|
||
if (item.status == 0) {
|
||
return '仓库中'
|
||
} else if (item.status == 1) {
|
||
return '待租'
|
||
} else if (item.status == 2) {
|
||
return '预约中'
|
||
} else if (item.status == 3) {
|
||
return '骑行中'
|
||
} else if (item.status == 4) {
|
||
return '临时锁车中'
|
||
} else if (item.status == 6) {
|
||
return '调度中'
|
||
} else if (item.status == 7) {
|
||
return '未绑定'
|
||
} else if (item.status == 8) {
|
||
return '禁用中'
|
||
}
|
||
},
|
||
// startTimer() {
|
||
// this.timer = setInterval(() => {
|
||
// this.count++ //每次加一
|
||
// // 这里替换为你的实际逻辑
|
||
// this.setMapScale()
|
||
// }, 5000)
|
||
// },
|
||
// 清除定时器
|
||
clearTimer() {
|
||
if (this.timer) {
|
||
clearInterval(this.timer)
|
||
this.timer = null
|
||
console.log("定时器已清除")
|
||
}
|
||
},
|
||
// 点击继续骑行
|
||
btnjjqx() {
|
||
this.orderflag = true
|
||
this.fjflag = false
|
||
},
|
||
//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}`,
|
||
// url: `wss://ysd.chuantewulian.cn/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.covers = []
|
||
const newMarkers = []
|
||
this.parkingList.forEach(item => {
|
||
newMarkers.push({
|
||
id: parseFloat(item.id),
|
||
latitude: parseFloat(item.latitude),
|
||
longitude: parseFloat(item.longitude),
|
||
width: 18,
|
||
height: 26,
|
||
iconPath: item.type == 1 ? 'https://lxnapi.ccttiot.com/bike/img/static/up2xXqAgwCX5iER600k3' : item.type == 2 ? 'https://lxnapi.ccttiot.com/bike/img/static/uDNY5Q4zOiZTCBTA2Jdq' : item.type == 3 ? 'https://lxnapi.ccttiot.com/bike/img/static/u53BAQcFIX3vxsCzEZ7t' : 'https://api.ccttiot.com/%E5%BE%AE%E4%BF%A1%E5%9B%BE%E7%89%87_20250829161752_210_17-1756455764351.png',
|
||
callout: {
|
||
content: item.name,
|
||
color: '#ffffff',
|
||
fontSize: 12,
|
||
borderRadius: 8,
|
||
bgColor: item.type == 1 ? '#3A7EDB' : item.type == 2 ?'#FF473E' : item.type == 3 ? '#FFC107' : '#3bbd55',
|
||
padding: 4,
|
||
display: 'ALWAYS'
|
||
},
|
||
isCalloutVisible: true // 添加标记
|
||
})
|
||
})
|
||
this.newMarkers = newMarkers
|
||
this.$set(this, 'covers', [...this.covers, ...newMarkers])
|
||
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',
|
||
})
|
||
}
|
||
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(){
|
||
this.scdevlist = this.devicesarr.map(item => {
|
||
const name = item.name || ''
|
||
return name.slice(-12)
|
||
})
|
||
let that = this
|
||
uni.openBluetoothAdapter({
|
||
success: function (res) {
|
||
that.bltRemark = '蓝牙权限均已打开'
|
||
that.btnjsds()
|
||
},
|
||
fail: function (err) {
|
||
console.error('蓝牙适配器初始化失败', err)
|
||
// 蓝牙未打开或初始化失败
|
||
if(err.errMsg == 'openBluetoothAdapter:fail auth deny'){
|
||
that.bltRemark = '微信蓝牙权限没有授权'
|
||
that.btnjsds()
|
||
}else if(err.errMsg == 'openBluetoothAdapter:fail open fail'){
|
||
that.bltRemark = '手机蓝牙没有打开'
|
||
that.btnjsds()
|
||
}else if(err.errMsg == 'openBluetoothAdapter:fail:not available'){
|
||
that.bltRemark = '手机蓝牙是否打开'
|
||
that.btnjsds()
|
||
}else{
|
||
that.bltRemark = `其他错误 + ${err.errMsg}`
|
||
that.btnjsds()
|
||
}
|
||
}
|
||
})
|
||
},
|
||
btnjsds() {
|
||
if (this.jiance == true) {
|
||
xBlufi.initXBlufi(1)
|
||
xBlufi.notifyStartDiscoverBle({
|
||
'isStart': true
|
||
})
|
||
xBlufi.listenDeviceMsgEvent(true, this.funListenDeviceMsgEvent)
|
||
}
|
||
this.caozuotext = '还车前请将车辆停放于运营区和停车区内'
|
||
if (this.jieshuflag == true) {
|
||
this.jieshuflag = false
|
||
this.$u.get("/app/order/mineProcessing").then((res) => {
|
||
if (res.code == 200) {
|
||
if (res.data) {
|
||
if (this.orderAreaReturnVerify == true) {
|
||
if (this.orderobj.deviceOnlineStatus == 0) {
|
||
this.jieshuflag = true
|
||
this.wenbentxtflag = true
|
||
this.wenbentxt = '蓝牙连接中...'
|
||
let that = this
|
||
const findDevice = () => {
|
||
that.ver_dataflag = 2
|
||
const matchedDevice = that.devicesarr.find(device => {
|
||
return device.name.slice(-12) == that.mac.slice(-12)
|
||
})
|
||
if (matchedDevice) {
|
||
xBlufi.notifyStartDiscoverBle({
|
||
'isStart': false
|
||
})
|
||
xBlufi.notifyConnectBle({
|
||
isStart: true,
|
||
deviceId: matchedDevice.deviceId,
|
||
name: matchedDevice.name
|
||
})
|
||
that.deviceid = matchedDevice.deviceId
|
||
that.devicename = matchedDevice.name
|
||
setTimeout(() => {
|
||
if (that.ver_dataflag == 3) {
|
||
that.wenbentxt = ''
|
||
that.wenbentxtflag = false
|
||
let flag = false
|
||
uni.navigateTo({
|
||
url: '/page_user/hcshenhe?sn=' +that.orderobj.deviceSn +'&orderid=' + that.orderobj.orderId + '&orderAreaId=' +that.orderobj.orderAreaId +'&flag=' + flag + '&mac=' + that.mac + '&macList=' + that.scdevlist
|
||
})
|
||
} else {
|
||
that.ver_dataflag = 1
|
||
that.shibainum = 0
|
||
that.wenbentxt = ''
|
||
that.wenbentxtflag = false
|
||
that.ljsbflag = true
|
||
that.chongshinum = '还车'
|
||
uni.openBluetoothAdapter({
|
||
success: function (res) {
|
||
|
||
},
|
||
fail: function (err) {
|
||
console.error('蓝牙适配器初始化失败', err)
|
||
// 蓝牙未打开或初始化失败
|
||
if(err.errMsg == 'openBluetoothAdapter:fail auth deny'){
|
||
uni.showToast({
|
||
title: '请检查微信蓝牙权限是否授权',
|
||
icon: 'none',
|
||
duration:5000
|
||
})
|
||
}else if(err.errMsg == 'openBluetoothAdapter:fail open fail'){
|
||
uni.showToast({
|
||
title: '请检查手机蓝牙是否打开',
|
||
icon: 'none',
|
||
duration:5000
|
||
})
|
||
}else if(err.errMsg == 'openBluetoothAdapter:fail:not available'){
|
||
uni.showToast({
|
||
title: '请检查手机蓝牙是否打开',
|
||
icon: 'none',
|
||
duration:5000
|
||
})
|
||
}
|
||
}
|
||
})
|
||
}
|
||
}, 4000)
|
||
} else {
|
||
if (that.shibainum < 3) {
|
||
that.shibainum++
|
||
that.findDeviceTimer = setTimeout(findDevice.bind(that),1000) // 使用 bind 保持 this 上下文
|
||
} else {
|
||
that.ver_dataflag = 1
|
||
that.shibainum = 0
|
||
that.wenbentxt = ''
|
||
that.wenbentxtflag = false
|
||
that.ljsbflag = true
|
||
that.chongshinum = '还车'
|
||
uni.openBluetoothAdapter({
|
||
success: function (res) {
|
||
|
||
},
|
||
fail: function (err) {
|
||
console.error('蓝牙适配器初始化失败', err)
|
||
// 蓝牙未打开或初始化失败
|
||
if(err.errMsg == 'openBluetoothAdapter:fail auth deny'){
|
||
uni.showToast({
|
||
title: '请检查微信蓝牙权限是否授权',
|
||
icon: 'none',
|
||
duration:5000
|
||
})
|
||
}else if(err.errMsg == 'openBluetoothAdapter:fail open fail'){
|
||
uni.showToast({
|
||
title: '请检查手机蓝牙是否打开',
|
||
icon: 'none',
|
||
duration:5000
|
||
})
|
||
}else if(err.errMsg == 'openBluetoothAdapter:fail:not available'){
|
||
uni.showToast({
|
||
title: '请检查手机蓝牙是否打开',
|
||
icon: 'none',
|
||
duration:5000
|
||
})
|
||
}
|
||
}
|
||
})
|
||
}
|
||
}
|
||
}
|
||
findDevice()
|
||
} else {
|
||
this.jieshuflag = true
|
||
uni.navigateTo({
|
||
url: '/page_user/hcshenhe?sn=' + this.orderobj.deviceSn +'&orderid=' + this.orderobj.orderId + '&orderAreaId=' +this.orderobj.orderAreaId + '&flag=' + true + '&macList=' + this.scdevlist
|
||
})
|
||
}
|
||
} else {
|
||
this.wenbentxt = '车辆还车中...'
|
||
this.wenbentxtflag = true
|
||
console.log(this.devicesarr, '附近设备');
|
||
let that = this
|
||
const findDevice = () => {
|
||
that.ver_dataflag = 2
|
||
const matchedDevice = that.devicesarr.find(device => {
|
||
return device.name.slice(-12) == that.mac.slice(-12)
|
||
})
|
||
if (matchedDevice) {
|
||
console.log('在旁边');
|
||
that.wenbentxt = ''
|
||
that.wenbentxtflag = false
|
||
uni.getLocation({
|
||
type: 'gcj02', // 国内地图更兼容
|
||
isHighAccuracy: true,
|
||
accuracy: 'best',
|
||
success: (res) => {
|
||
console.log('精确坐标:', res)
|
||
that.lat = res.latitude
|
||
that.lon = res.longitude
|
||
that.lngsc = res.longitude
|
||
that.latsc = res.latitude
|
||
that.getfeiyong()
|
||
},
|
||
fail: (err) => {
|
||
console.error('获取位置失败:', err)
|
||
that.lat = null
|
||
that.lon = null
|
||
that.lngsc = null
|
||
that.latsc = null
|
||
that.getfeiyong() // 降级处理
|
||
}
|
||
})
|
||
} else {
|
||
if (that.shibainum < 3) {
|
||
that.shibainum++
|
||
that.findDeviceTimer = setTimeout(findDevice.bind(that),
|
||
1000) // 使用 bind 保持 this 上下文
|
||
} else {
|
||
console.log('不在旁边2');
|
||
uni.getLocation({
|
||
type: 'gcj02', // 国内地图更兼容
|
||
isHighAccuracy: true,
|
||
accuracy: 'best',
|
||
success: (res) => {
|
||
console.log('精确坐标:', res)
|
||
that.lat = res.latitude
|
||
that.lon = res.longitude
|
||
that.lngsc = res.longitude
|
||
that.latsc = res.latitude
|
||
that.ver_dataflag = 1
|
||
that.shibainum = 0
|
||
that.wenbentxt = ''
|
||
that.wenbentxtflag = false
|
||
that.chongshinum = '还车'
|
||
that.getfeiyong()
|
||
},
|
||
fail: (err) => {
|
||
console.error('获取位置失败:', err)
|
||
that.lat = null
|
||
that.lon = null
|
||
that.lngsc = null
|
||
that.latsc = null
|
||
that.ver_dataflag = 1
|
||
that.shibainum = 0
|
||
that.wenbentxt = ''
|
||
that.wenbentxtflag = false
|
||
that.chongshinum = '还车'
|
||
that.getfeiyong()
|
||
}
|
||
})
|
||
|
||
}
|
||
}
|
||
}
|
||
findDevice()
|
||
}
|
||
} else {
|
||
this.jieshuflag = true
|
||
uni.navigateTo({
|
||
url: '/page_user/yongche/orderxq?id=' + this.orderobj.orderId
|
||
})
|
||
}
|
||
} else {
|
||
this.jieshuflag = true
|
||
uni.showToast({
|
||
title: res.msg,
|
||
icon: 'none',
|
||
duration: 5000
|
||
})
|
||
}
|
||
})
|
||
}
|
||
},
|
||
// 点击还车判断是否需要另外缴费
|
||
// getfeiyong(){
|
||
// this.scdevlist = this.devicesarr.map(item => {
|
||
// const name = item.name || ''
|
||
// return name.slice(-12)
|
||
// })
|
||
// let that = this
|
||
// uni.openBluetoothAdapter({
|
||
// success: function (res) {
|
||
// that.bltRemark = '蓝牙权限均已打开'
|
||
// that.getfeiyons()
|
||
// },
|
||
// fail: function (err) {
|
||
// console.error('蓝牙适配器初始化失败', err)
|
||
// // 蓝牙未打开或初始化失败
|
||
// if(err.errMsg == 'openBluetoothAdapter:fail auth deny'){
|
||
// that.bltRemark = '微信蓝牙权限没有授权'
|
||
// that.getfeiyons()
|
||
// }else if(err.errMsg == 'openBluetoothAdapter:fail open fail'){
|
||
// that.bltRemark = '手机蓝牙没有打开'
|
||
// that.getfeiyons()
|
||
// }else if(err.errMsg == 'openBluetoothAdapter:fail:not available'){
|
||
// that.bltRemark = '手机蓝牙是否打开'
|
||
// that.getfeiyons()
|
||
// }else{
|
||
// that.bltRemark = `其他错误 + ${err.errMsg}`
|
||
// that.getfeiyons()
|
||
// }
|
||
// }
|
||
// })
|
||
// },
|
||
getfeiyong() {
|
||
let data = {
|
||
orderId: this.orderobj.orderId,
|
||
lon: this.lngsc,
|
||
lat: this.latsc,
|
||
checkLocation: true,
|
||
macList:this.scdevlist,
|
||
bltRemark:this.bltRemark
|
||
}
|
||
this.$u.post(`/app/order/calcFee`, data).then(res => {
|
||
if (res.code == 200) {
|
||
this.jieshuflag = true
|
||
this.fajinobj = res.data
|
||
if (res.data.manageFee > 0 || res.data.dispatchFee > 0) {
|
||
this.wenbentxt = ''
|
||
this.wenbentxtflag = false
|
||
this.fjflag = true
|
||
this.orderflag = false
|
||
} else {
|
||
this.gethuan()
|
||
}
|
||
} else {
|
||
setTimeout(() => {
|
||
this.jieshuflag = true
|
||
}, 3000)
|
||
uni.showModal({
|
||
title: '提示',
|
||
content: res.msg,
|
||
showCancel: false,
|
||
confirmText: '知道了'
|
||
})
|
||
}
|
||
})
|
||
},
|
||
// 点击缴纳罚金继续还车
|
||
btnfajin() {
|
||
this.gethuan()
|
||
},
|
||
// 还车统一调用
|
||
gethuan() {
|
||
let that = this
|
||
uni.showModal({
|
||
title: '提示',
|
||
content: '您确定要还车吗?',
|
||
showCancel: true,
|
||
success: function(res) {
|
||
if (res.confirm) {
|
||
that.fjflag = false
|
||
that.wenbentxt = '车辆还车中...'
|
||
that.wenbentxtflag = true
|
||
let data = {
|
||
orderId: that.orderobj.orderId,
|
||
picture: that.imgs,
|
||
lon: that.lngsc,
|
||
lat: that.latsc,
|
||
requiredIot: true,
|
||
macList:that.scdevlist,
|
||
bltRemark:that.bltRemark
|
||
}
|
||
that.$u.put(`/app/order/end`, data).then(res => {
|
||
if (res.code == 200) {
|
||
that.cheflag = true
|
||
that.fjflag = false
|
||
that.wenbentxt = ''
|
||
that.wenbentxtflag = false
|
||
uni.showToast({
|
||
title: '还车成功',
|
||
icon: 'success',
|
||
duration: 2000
|
||
})
|
||
setTimeout(() => {
|
||
uni.navigateTo({
|
||
url: '/page_user/yongche/orderxq?id=' +that.orderobj.orderId
|
||
})
|
||
}, 1000)
|
||
} else if (res.code == 20001) {
|
||
if (that.ver_dataflag == 3) {
|
||
that.wenbentxt = '蓝牙还车中...'
|
||
xBlufi.notifySendCustomData({
|
||
customData: "11llosesub300@"
|
||
})
|
||
setTimeout(() => {
|
||
xBlufi.notifySendCustomData({
|
||
customData: "11reboot@"
|
||
})
|
||
}, 2000)
|
||
that.fjflag = false
|
||
let data = {
|
||
orderId: that.orderobj.orderId,
|
||
picture: that.imgs,
|
||
lon: that.lon,
|
||
lat: that.lat,
|
||
requiredIot: false,
|
||
macList:that.scdevlist,
|
||
bltRemark:that.bltRemark
|
||
}
|
||
that.$u.put(`/app/order/end`, data).then(res => {
|
||
if (res.code == 200) {
|
||
setTimeout(() => {
|
||
that.wenbentxt = ''
|
||
that.wenbentxtflag = false
|
||
setTimeout(() => {
|
||
uni.navigateTo({
|
||
url: '/page_user/yongche/orderxq?id=' +that.orderobj.orderId
|
||
})
|
||
}, 1000)
|
||
}, 2000)
|
||
} else if (res.msg == null) {
|
||
that.wenbentxt = ''
|
||
that.wenbentxtflag = false
|
||
uni.showToast({
|
||
title: '未知错误',
|
||
icon: 'none',
|
||
duration: 2000
|
||
})
|
||
} else {
|
||
that.wenbentxt = ''
|
||
that.wenbentxtflag = false
|
||
uni.showModal({
|
||
title: '提示',
|
||
content: res.msg,
|
||
showCancel: false,
|
||
success: function(res) {
|
||
if (res.confirm) {
|
||
|
||
} else if (res.cancel) {
|
||
|
||
}
|
||
}
|
||
})
|
||
}
|
||
})
|
||
} else {
|
||
that.wenbentxt = '蓝牙还车中...'
|
||
const findDevice = () => {
|
||
that.ver_dataflag = 2
|
||
const matchedDevice = that.devicesarr.find(device => {
|
||
return device.name.slice(-12) == that.mac.slice(-12)
|
||
})
|
||
if (matchedDevice) {
|
||
xBlufi.notifyStartDiscoverBle({
|
||
'isStart': false
|
||
})
|
||
xBlufi.notifyConnectBle({
|
||
isStart: true,
|
||
deviceId: matchedDevice.deviceId,
|
||
name: matchedDevice.name
|
||
})
|
||
that.deviceid = matchedDevice.deviceId
|
||
that.devicename = matchedDevice.name
|
||
setTimeout(() => {
|
||
if (that.ver_dataflag == 3) {
|
||
that.fjflag = false
|
||
let data = {
|
||
orderId: that.orderobj.orderId,
|
||
picture: that.imgs,
|
||
lon: that.lon,
|
||
lat: that.lat,
|
||
requiredIot: false,
|
||
macList:that.scdevlist,
|
||
bltRemark:that.bltRemark
|
||
}
|
||
that.$u.put(`/app/order/end`, data).then(res => {
|
||
if (res.code == 200) {
|
||
xBlufi.notifySendCustomData({
|
||
customData: "11close@"
|
||
})
|
||
setTimeout(() => {
|
||
xBlufi.notifySendCustomData({
|
||
customData: "11reboot@"
|
||
})
|
||
that.wenbentxt =''
|
||
that.wenbentxtflag =false
|
||
setTimeout(() => {
|
||
uni.navigateTo({
|
||
url: '/page_user/yongche/orderxq?id=' +that.orderobj.orderId
|
||
})
|
||
},1000)
|
||
}, 2000)
|
||
} else if (res.msg == null) {
|
||
that.wenbentxt = ''
|
||
that.wenbentxtflag =false
|
||
that.orderflag =true
|
||
uni.showToast({
|
||
title: '未知错误',
|
||
icon: 'none',
|
||
duration: 2000
|
||
})
|
||
} else {
|
||
that.wenbentxt = ''
|
||
that.wenbentxtflag =false
|
||
that.orderflag =true
|
||
uni.showModal({
|
||
title: '提示',
|
||
content: res.msg,
|
||
showCancel: false,
|
||
success: function(res) {
|
||
if (res.confirm) {
|
||
|
||
} else if (res.cancel) {
|
||
|
||
}
|
||
}
|
||
})
|
||
}
|
||
})
|
||
} else {
|
||
that.ver_dataflag = 1
|
||
that.shibainum = 0
|
||
that.wenbentxt = ''
|
||
that.wenbentxtflag = false
|
||
that.orderflag = true
|
||
that.ljsbflag = true
|
||
that.chongshinum = '还车'
|
||
uni.openBluetoothAdapter({
|
||
success: function (res) {
|
||
|
||
},
|
||
fail: function (err) {
|
||
console.error('蓝牙适配器初始化失败', err)
|
||
// 蓝牙未打开或初始化失败
|
||
if(err.errMsg == 'openBluetoothAdapter:fail auth deny'){
|
||
uni.showToast({
|
||
title: '请检查微信蓝牙权限是否授权',
|
||
icon: 'none',
|
||
duration:5000
|
||
})
|
||
}else if(err.errMsg == 'openBluetoothAdapter:fail open fail'){
|
||
uni.showToast({
|
||
title: '请检查手机蓝牙是否打开',
|
||
icon: 'none',
|
||
duration:5000
|
||
})
|
||
}else if(err.errMsg == 'openBluetoothAdapter:fail:not available'){
|
||
uni.showToast({
|
||
title: '请检查手机蓝牙是否打开',
|
||
icon: 'none',
|
||
duration:5000
|
||
})
|
||
}
|
||
}
|
||
})
|
||
}
|
||
}, 4000)
|
||
} else {
|
||
if (that.shibainum < 3) {
|
||
that.shibainum++
|
||
that.findDeviceTimer = setTimeout(findDevice.bind(that), 1000) // 使用 bind 保持 this 上下文
|
||
} else {
|
||
that.ver_dataflag = 1
|
||
that.shibainum = 0
|
||
that.wenbentxt = ''
|
||
that.wenbentxtflag = false
|
||
that.orderflag = true
|
||
that.ljsbflag = true
|
||
that.chongshinum = '还车'
|
||
let lanya = ''
|
||
if (that.jiance == true) {
|
||
lanya = '蓝牙未开启'
|
||
} else {
|
||
lanya = '蓝牙已开启'
|
||
}
|
||
let data = {
|
||
mac: that.mac,
|
||
orderId: that.orderobj.orderId,
|
||
reason: '用户蓝牙还车失败' + lanya,
|
||
command: '11close@',
|
||
lat: that.lat,
|
||
lon: that.lon,
|
||
result: '失败'
|
||
}
|
||
that.$u.post(`/app/commandLog/bluetooth`, data).then(res => {})
|
||
uni.openBluetoothAdapter({
|
||
success: function (res) {
|
||
|
||
},
|
||
fail: function (err) {
|
||
console.error('蓝牙适配器初始化失败', err)
|
||
// 蓝牙未打开或初始化失败
|
||
if(err.errMsg == 'openBluetoothAdapter:fail auth deny'){
|
||
uni.showToast({
|
||
title: '请检查微信蓝牙权限是否授权',
|
||
icon: 'none',
|
||
duration:5000
|
||
})
|
||
}else if(err.errMsg == 'openBluetoothAdapter:fail open fail'){
|
||
uni.showToast({
|
||
title: '请检查手机蓝牙是否打开',
|
||
icon: 'none',
|
||
duration:5000
|
||
})
|
||
}else if(err.errMsg == 'openBluetoothAdapter:fail:not available'){
|
||
uni.showToast({
|
||
title: '请检查手机蓝牙是否打开',
|
||
icon: 'none',
|
||
duration:5000
|
||
})
|
||
}
|
||
}
|
||
})
|
||
}
|
||
}
|
||
}
|
||
findDevice()
|
||
}
|
||
} else if (res.msg == null) {
|
||
that.wenbentxt = ''
|
||
that.wenbentxtflag = false
|
||
that.orderflag = true
|
||
uni.showToast({
|
||
title: '未知错误',
|
||
icon: 'none',
|
||
duration: 2000
|
||
})
|
||
} else {
|
||
that.wenbentxt = ''
|
||
that.wenbentxtflag = false
|
||
that.orderflag = true
|
||
uni.showModal({
|
||
title: '提示',
|
||
content: res.msg,
|
||
showCancel: false,
|
||
success: function(res) {
|
||
if (res.confirm) {
|
||
|
||
} else if (res.cancel) {
|
||
|
||
}
|
||
}
|
||
})
|
||
}
|
||
})
|
||
} else if (res.cancel) {
|
||
that.wenbentxtflag = false
|
||
that.wenbentxt = ''
|
||
}
|
||
}
|
||
})
|
||
},
|
||
// 点击跳转到最近停车点
|
||
btntcd() {
|
||
uni.navigateTo({
|
||
url: '/pages/myorder/returned/tingche?areaId=' + this.orderobj.orderAreaId
|
||
})
|
||
},
|
||
// 点击故障上报
|
||
btnguzhang() {
|
||
uni.navigateTo({
|
||
url: '/page_user/guzhang/index?sn=' + this.orderobj.deviceSn
|
||
})
|
||
},
|
||
// 点击去进行换车
|
||
btnghbike(){
|
||
this.scdevlist = this.devicesarr.map(item => {
|
||
const name = item.name || ''
|
||
return name.slice(-12)
|
||
})
|
||
let that = this
|
||
uni.openBluetoothAdapter({
|
||
success: function (res) {
|
||
that.bltRemark = '蓝牙权限均已打开'
|
||
that.btnghbiks()
|
||
},
|
||
fail: function (err) {
|
||
console.error('蓝牙适配器初始化失败', err)
|
||
// 蓝牙未打开或初始化失败
|
||
if(err.errMsg == 'openBluetoothAdapter:fail auth deny'){
|
||
that.bltRemark = '微信蓝牙权限没有授权'
|
||
that.btnghbiks()
|
||
}else if(err.errMsg == 'openBluetoothAdapter:fail open fail'){
|
||
that.bltRemark = '手机蓝牙没有打开'
|
||
that.btnghbiks()
|
||
}else if(err.errMsg == 'openBluetoothAdapter:fail:not available'){
|
||
that.bltRemark = '手机蓝牙是否打开'
|
||
that.btnghbiks()
|
||
}else{
|
||
that.bltRemark = `其他错误 + ${err.errMsg}`
|
||
that.btnghbiks()
|
||
}
|
||
}
|
||
})
|
||
},
|
||
btnghbiks() {
|
||
this.caozuotext = '换车前请将车辆停放于运营区和停车区内'
|
||
if (this.jiance == true) {
|
||
xBlufi.initXBlufi(1)
|
||
xBlufi.notifyStartDiscoverBle({
|
||
'isStart': true
|
||
})
|
||
xBlufi.listenDeviceMsgEvent(true, this.funListenDeviceMsgEvent)
|
||
}
|
||
const findDevice = () => {
|
||
this.ver_dataflag = 2
|
||
const matchedDevice = this.devicesarr.find(device => {
|
||
return device.name.slice(-12) == this.mac.slice(-12)
|
||
})
|
||
if (matchedDevice) {
|
||
xBlufi.notifyStartDiscoverBle({
|
||
'isStart': false
|
||
})
|
||
uni.getLocation({
|
||
type: 'gcj02', // 国内地图更兼容
|
||
isHighAccuracy: true,
|
||
accuracy: 'best',
|
||
success: (res) => {
|
||
console.log('精确坐标:', res)
|
||
this.lslat = res.latitude
|
||
this.lslon = res.longitude
|
||
},
|
||
fail: (err) => {
|
||
console.error('获取位置失败:', err)
|
||
this.lslat = null
|
||
this.lslon = null
|
||
}
|
||
})
|
||
} else {
|
||
if (this.shibainum < 3) {
|
||
this.shibainum++
|
||
this.findDeviceTimer = setTimeout(findDevice.bind(this), 1000) // 使用 bind 保持 this 上下文
|
||
} else {
|
||
this.lslat = null
|
||
this.lslon = null
|
||
}
|
||
}
|
||
}
|
||
findDevice()
|
||
|
||
let that = this
|
||
that.wenbentxt = '车辆锁车中...'
|
||
that.wenbentxtflag = true
|
||
let data = {
|
||
orderId: that.orderobj.orderId,
|
||
lat: that.lslat,
|
||
lon: that.lslon,
|
||
requiredIot: true,
|
||
macList:that.scdevlist,
|
||
bltRemark:that.bltRemark
|
||
}
|
||
that.$u.put(`/app/order/closeDevice`,data).then((res) => {
|
||
if (res.code == 200) {
|
||
that.wenbentxt = ''
|
||
that.wenbentxtflag = false
|
||
uni.showToast({
|
||
title: '锁车成功',
|
||
icon: 'success',
|
||
duration: 2000
|
||
})
|
||
that.orderobj.deviceLockStatus = 0
|
||
setTimeout(() => {
|
||
uni.navigateTo({
|
||
url: '/page_user/huanbike?sn=' + that.orderobj.deviceSn +'&orderid=' + that.orderobj.orderId + '&deviceid=' + that.deviceid + '&devicename=' + that.devicename + '&macList=' + this.scdevlist
|
||
})
|
||
}, 1000)
|
||
} else if (res.code == 20001) {
|
||
if (that.ver_dataflag == 3) {
|
||
uni.getLocation({
|
||
type: 'gcj02', // 国内地图更兼容
|
||
isHighAccuracy: true,
|
||
accuracy: 'best',
|
||
success: (res) => {
|
||
console.log('精确坐标:', res)
|
||
that.lslat = res.latitude
|
||
that.lslon = res.longitude
|
||
},
|
||
fail: (err) => {
|
||
console.error('获取位置失败:', err)
|
||
that.lslat = null
|
||
that.lslon = null
|
||
}
|
||
})
|
||
that.orderobj.deviceLockStatus = 0
|
||
xBlufi.notifySendCustomData({
|
||
customData: "11llosesub300@",
|
||
})
|
||
setTimeout(() => {
|
||
that.wenbentxt = ''
|
||
that.wenbentxtflag = false
|
||
}, 2000)
|
||
let lanya = ''
|
||
if (that.jiance == true) {
|
||
lanya = '蓝牙未开启'
|
||
} else {
|
||
lanya = '蓝牙已开启'
|
||
}
|
||
let data = {
|
||
mac: that.mac,
|
||
reason: '临时锁车' + lanya,
|
||
command: '11llosesub300@',
|
||
longitude: that.lslon,
|
||
latitude: that.lslat,
|
||
result: '失败'
|
||
}
|
||
that.$u.post(`/app/commandLog/bluetooth`, data).then(res => {
|
||
console.log(res, '蓝牙')
|
||
})
|
||
let datas = {
|
||
orderId: that.orderobj.orderId,
|
||
lat: that.lslat,
|
||
lon: that.lslon,
|
||
requiredIot: true,
|
||
macList:that.scdevlist,
|
||
bltRemark:that.bltRemark
|
||
}
|
||
that.$u.put(`/app/order/closeDevice`,datas).then((res) => {})
|
||
uni.navigateTo({
|
||
url: '/page_user/huanbike?sn=' + that.orderobj.deviceSn + '&orderid=' +that.orderobj.orderId + '&deviceid=' + that.deviceid + '&devicename=' +that.devicename + '&macList=' + that.scdevlist
|
||
})
|
||
} else {
|
||
that.wenbentxt = '车辆锁车中...'
|
||
const findDevice = () => {
|
||
that.ver_dataflag = 2
|
||
const matchedDevice = that.devicesarr.find(device => {
|
||
return device.name.slice(-12) == that.mac.slice(-12)
|
||
})
|
||
if (matchedDevice) {
|
||
xBlufi.notifyStartDiscoverBle({
|
||
'isStart': false
|
||
})
|
||
xBlufi.notifyConnectBle({
|
||
isStart: true,
|
||
deviceId: matchedDevice.deviceId,
|
||
name: matchedDevice.name
|
||
})
|
||
that.deviceid = matchedDevice.deviceId
|
||
that.devicename = matchedDevice.name
|
||
setTimeout(() => {
|
||
if (that.ver_dataflag == 3) {
|
||
uni.getLocation({
|
||
type: 'gcj02', // 国内地图更兼容
|
||
isHighAccuracy: true,
|
||
accuracy: 'best',
|
||
success: (res) => {
|
||
console.log('精确坐标:', res)
|
||
that.lslat = res.latitude
|
||
that.lslon = res.longitude
|
||
},
|
||
fail: (err) => {
|
||
console.error('获取位置失败:', err)
|
||
that.lslat = null
|
||
that.lslon = null
|
||
}
|
||
})
|
||
that.orderobj.deviceLockStatus = 0
|
||
xBlufi.notifySendCustomData({
|
||
customData: "11llosesub300@",
|
||
})
|
||
setTimeout(() => {
|
||
xBlufi.notifySendCustomData({
|
||
customData: "11reboot@"
|
||
})
|
||
that.wenbentxt = ''
|
||
that.wenbentxtflag = false
|
||
}, 2000)
|
||
let lanya = ''
|
||
if (that.jiance == true) {
|
||
lanya = '蓝牙未开启'
|
||
} else {
|
||
lanya = '蓝牙已开启'
|
||
}
|
||
let data = {
|
||
mac: that.mac,
|
||
reason: '临时锁车' + lanya,
|
||
command: '11llosesub300@',
|
||
longitude: that.lslon,
|
||
latitude: that.lslat,
|
||
result: '成功'
|
||
}
|
||
that.$u.post(`/app/commandLog/bluetooth`, data).then(res => {
|
||
console.log(res, '蓝牙')
|
||
})
|
||
let datas = {
|
||
orderId: that.orderobj.orderId,
|
||
lat: that.lslat,
|
||
lon: that.lslon,
|
||
requiredIot: true,
|
||
macList:that.scdevlist,
|
||
bltRemark:that.bltRemark
|
||
}
|
||
that.$u.put(`/app/order/closeDevice`,datas).then((res) => {})
|
||
uni.navigateTo({
|
||
url: '/page_user/huanbike?sn=' + that.orderobj.deviceSn + '&orderid=' + that.orderobj.orderId + '&deviceid=' + that.deviceid +'&devicename=' + that.devicename + '&macList=' + this.scdevlist
|
||
})
|
||
} else {
|
||
that.ver_dataflag = 1
|
||
that.shibainum = 0
|
||
that.wenbentxt = ''
|
||
that.wenbentxtflag = false
|
||
that.ljsbflag = true
|
||
that.chongshinum = '换车'
|
||
uni.openBluetoothAdapter({
|
||
success: function (res) {
|
||
|
||
},
|
||
fail: function (err) {
|
||
console.error('蓝牙适配器初始化失败', err)
|
||
// 蓝牙未打开或初始化失败
|
||
if(err.errMsg == 'openBluetoothAdapter:fail auth deny'){
|
||
uni.showToast({
|
||
title: '请检查微信蓝牙权限是否授权',
|
||
icon: 'none',
|
||
duration:5000
|
||
})
|
||
}else if(err.errMsg == 'openBluetoothAdapter:fail open fail'){
|
||
uni.showToast({
|
||
title: '请检查手机蓝牙是否打开',
|
||
icon: 'none',
|
||
duration:5000
|
||
})
|
||
}else if(err.errMsg == 'openBluetoothAdapter:fail:not available'){
|
||
uni.showToast({
|
||
title: '请检查手机蓝牙是否打开',
|
||
icon: 'none',
|
||
duration:5000
|
||
})
|
||
}
|
||
}
|
||
})
|
||
}
|
||
}, 4000)
|
||
} else {
|
||
if (that.shibainum < 3) {
|
||
that.shibainum++
|
||
that.findDeviceTimer = setTimeout(findDevice.bind(that),1000) // 使用 bind 保持 this 上下文
|
||
} else {
|
||
uni.getLocation({
|
||
type: 'gcj02', // 国内地图更兼容
|
||
isHighAccuracy: true,
|
||
accuracy: 'best',
|
||
success: (res) => {
|
||
console.log('精确坐标:', res)
|
||
that.lslat = res.latitude
|
||
that.lslon = res.longitude
|
||
},
|
||
fail: (err) => {
|
||
console.error('获取位置失败:', err)
|
||
that.lslat = null
|
||
that.lslon = null
|
||
}
|
||
})
|
||
that.ver_dataflag = 1
|
||
that.shibainum = 0
|
||
that.wenbentxt = ''
|
||
that.wenbentxtflag = false
|
||
that.ljsbflag = true
|
||
that.chongshinum = '换车'
|
||
let lanya = ''
|
||
if (that.jiance == true) {
|
||
lanya = '蓝牙未开启'
|
||
} else {
|
||
lanya = '蓝牙已开启'
|
||
}
|
||
let data = {
|
||
mac: that.mac,
|
||
orderId: that.orderobj.orderId,
|
||
reason: '用户蓝牙临时锁车失败' + lanya,
|
||
command: '11llosesub300@',
|
||
lat: that.lslat,
|
||
lon: that.lslon,
|
||
result: '失败'
|
||
}
|
||
that.$u.post(`/app/commandLog/bluetooth`, data).then(res => {})
|
||
uni.openBluetoothAdapter({
|
||
success: function (res) {
|
||
|
||
},
|
||
fail: function (err) {
|
||
console.error('蓝牙适配器初始化失败', err)
|
||
// 蓝牙未打开或初始化失败
|
||
if(err.errMsg == 'openBluetoothAdapter:fail auth deny'){
|
||
uni.showToast({
|
||
title: '请检查微信蓝牙权限是否授权',
|
||
icon: 'none',
|
||
duration:5000
|
||
})
|
||
}else if(err.errMsg == 'openBluetoothAdapter:fail open fail'){
|
||
uni.showToast({
|
||
title: '请检查手机蓝牙是否打开',
|
||
icon: 'none',
|
||
duration:5000
|
||
})
|
||
}else if(err.errMsg == 'openBluetoothAdapter:fail:not available'){
|
||
uni.showToast({
|
||
title: '请检查手机蓝牙是否打开',
|
||
icon: 'none',
|
||
duration:5000
|
||
})
|
||
}
|
||
}
|
||
})
|
||
}
|
||
}
|
||
}
|
||
findDevice()
|
||
}
|
||
} else {
|
||
that.wenbentxt = ''
|
||
that.wenbentxtflag = false
|
||
uni.showToast({
|
||
title: res.msg,
|
||
icon: 'none',
|
||
duration: 2000
|
||
})
|
||
}
|
||
})
|
||
},
|
||
// 点击跳转导航
|
||
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(){
|
||
this.scdevlist = this.devicesarr.map(item => {
|
||
const name = item.name || ''
|
||
return name.slice(-12)
|
||
})
|
||
let that = this
|
||
uni.openBluetoothAdapter({
|
||
success: function (res) {
|
||
that.bltRemark = '蓝牙权限均已打开'
|
||
that.btnqs()
|
||
},
|
||
fail: function (err) {
|
||
console.error('蓝牙适配器初始化失败', err)
|
||
// 蓝牙未打开或初始化失败
|
||
if(err.errMsg == 'openBluetoothAdapter:fail auth deny'){
|
||
that.bltRemark = '微信蓝牙权限没有授权'
|
||
that.btnqs()
|
||
}else if(err.errMsg == 'openBluetoothAdapter:fail open fail'){
|
||
that.bltRemark = '手机蓝牙没有打开'
|
||
that.btnqs()
|
||
}else if(err.errMsg == 'openBluetoothAdapter:fail:not available'){
|
||
that.bltRemark = '手机蓝牙是否打开'
|
||
that.btnqs()
|
||
}else{
|
||
that.bltRemark = `其他错误 + ${err.errMsg}`
|
||
that.btnqs()
|
||
}
|
||
}
|
||
})
|
||
},
|
||
btnqs() {
|
||
this.caozuotext = '骑行前请检查车轿刹车是否灵敏,安全骑行'
|
||
if (this.jiance == true) {
|
||
xBlufi.initXBlufi(1)
|
||
xBlufi.notifyStartDiscoverBle({
|
||
'isStart': true
|
||
})
|
||
xBlufi.listenDeviceMsgEvent(true, this.funListenDeviceMsgEvent)
|
||
}
|
||
this.$u.get("/app/orderDevice/mineUsing").then((res) => {
|
||
if (res.code == 200) {
|
||
if (res.data) {
|
||
if (res.data.deviceStatus == 9) {
|
||
uni.showModal({
|
||
title: '提示',
|
||
content: '超出运营区车辆已被强制锁车,请返回运营区或联系客服',
|
||
showCancel: false,
|
||
success: function(res) {
|
||
if (res.confirm) {
|
||
|
||
}
|
||
}
|
||
})
|
||
} else {
|
||
if (res.data.deviceLockStatus == 0) {
|
||
uni.getLocation({ //获取手机定位
|
||
type: 'gcj02', // 国内地图更兼容
|
||
isHighAccuracy: true,
|
||
accuracy: 'best',
|
||
success: (res) => {
|
||
console.log('精确坐标:', res)
|
||
this.lslat = res.latitude
|
||
this.lslon = res.longitude
|
||
},
|
||
fail: (err) => {
|
||
console.error('获取位置失败:', err)
|
||
this.lslat = null
|
||
this.lslon = null
|
||
}
|
||
})
|
||
let that = this
|
||
uni.showModal({
|
||
title: '提示',
|
||
content: '您是否要解锁车辆?',
|
||
showCancel: true,
|
||
success: function(res) {
|
||
if (res.confirm) {
|
||
that.wenbentxt = '车辆解锁中...'
|
||
that.wenbentxtflag = true
|
||
let dataks = {
|
||
orderId: that.orderobj.orderId,
|
||
lat: that.lslat,
|
||
lon: that.lslon,
|
||
requiredIot: true,
|
||
bltRemark:that.bltRemark
|
||
}
|
||
that.$u.put('/app/order/openDevice',dataks).then((res) => {
|
||
if (res.code == 200) {
|
||
that.wenbentxt = ''
|
||
that.wenbentxtflag = false
|
||
uni.showToast({
|
||
title: '解锁成功',
|
||
icon: 'success',
|
||
duration: 2000
|
||
})
|
||
that.orderobj.deviceLockStatus = 1
|
||
} else if (res.code == 20001) {
|
||
that.wenbentxt = '蓝牙解锁中...'
|
||
const findDevice = () => {
|
||
that.ver_dataflag = 2
|
||
const matchedDevice = that.devicesarr.find(device => {
|
||
return device.name.slice(-12) ==that.mac.slice(-12)
|
||
})
|
||
if (matchedDevice) {
|
||
xBlufi.notifyStartDiscoverBle({
|
||
'isStart': false
|
||
})
|
||
xBlufi.notifyConnectBle({
|
||
isStart: true,
|
||
deviceId: matchedDevice.deviceId,
|
||
name: matchedDevice.name
|
||
})
|
||
that.deviceid =matchedDevice.deviceId
|
||
that.devicename =matchedDevice.name
|
||
setTimeout(() => {
|
||
if (that.ver_dataflag ==3) {
|
||
xBlufi.notifySendCustomData({
|
||
customData: "11opensub5@"
|
||
})
|
||
that.wenbentxt =''
|
||
that.wenbentxtflag =false
|
||
that.orderobj.deviceLockStatus =1
|
||
let datakss = {
|
||
orderId: that.orderobj.orderId,
|
||
lat: that.lslat,
|
||
lon: that.lslon,
|
||
requiredIot: false,
|
||
bltRemark:that.bltRemark
|
||
}
|
||
that.$u.put('/app/order/openDevice',datakss).then((res) => {})
|
||
} else {
|
||
that.ver_dataflag =1
|
||
that.shibainum =0
|
||
that.wenbentxt =''
|
||
that.wenbentxtflag =false
|
||
uni.hideLoading()
|
||
that.ljsbflag =true
|
||
that.chongshinum ='解锁'
|
||
}
|
||
}, 4000)
|
||
} else {
|
||
if (that.shibainum < 3) {
|
||
that.shibainum++
|
||
that.findDeviceTimer = setTimeout(findDevice.bind(that),1000) // 使用 bind 保持 this 上下文
|
||
} else {
|
||
that.ver_dataflag = 1
|
||
that.shibainum = 0
|
||
that.wenbentxt = ''
|
||
that.wenbentxtflag =false
|
||
uni.hideLoading()
|
||
that.ljsbflag = true
|
||
that.chongshinum = '解锁'
|
||
let lanya = ''
|
||
if (that.jiance ==true) {
|
||
lanya = '蓝牙未开启'
|
||
} else {
|
||
lanya = '蓝牙已开启'
|
||
}
|
||
let data = {
|
||
mac: that.mac,
|
||
orderId: that.orderobj.orderId,
|
||
reason: '用户蓝牙解锁失败' +lanya,
|
||
command: '11opensub5@',
|
||
lat: that.lslat,
|
||
lon: that.lslon,
|
||
result: '失败',
|
||
}
|
||
that.$u.post(`/app/commandLog/bluetooth`,data).then(res => {})
|
||
uni.openBluetoothAdapter({
|
||
success: function (res) {
|
||
|
||
},
|
||
fail: function (err) {
|
||
console.error('蓝牙适配器初始化失败', err)
|
||
// 蓝牙未打开或初始化失败
|
||
if(err.errMsg == 'openBluetoothAdapter:fail auth deny'){
|
||
uni.showToast({
|
||
title: '请检查微信蓝牙权限是否授权',
|
||
icon: 'none',
|
||
duration:5000
|
||
})
|
||
}else if(err.errMsg == 'openBluetoothAdapter:fail open fail'){
|
||
uni.showToast({
|
||
title: '请检查手机蓝牙是否打开',
|
||
icon: 'none',
|
||
duration:5000
|
||
})
|
||
}else if(err.errMsg == 'openBluetoothAdapter:fail:not available'){
|
||
uni.showToast({
|
||
title: '请检查手机蓝牙是否打开',
|
||
icon: 'none',
|
||
duration:5000
|
||
})
|
||
}
|
||
}
|
||
})
|
||
}
|
||
}
|
||
}
|
||
findDevice()
|
||
} else {
|
||
uni.hideLoading()
|
||
uni.showToast({
|
||
title: res.msg,
|
||
icon: 'none',
|
||
duration: 2000
|
||
})
|
||
}
|
||
})
|
||
}
|
||
}
|
||
})
|
||
} else if (res.data.deviceLockStatus == 1) {
|
||
uni.getLocation({
|
||
type: 'gcj02', // 国内地图更兼容
|
||
isHighAccuracy: true,
|
||
accuracy: 'best',
|
||
success: (res) => {
|
||
console.log('精确坐标:', res)
|
||
this.lslat = res.latitude
|
||
this.lslon = res.longitude
|
||
},
|
||
fail: (err) => {
|
||
console.error('获取位置失败:', err)
|
||
this.lslat = null
|
||
this.lslon = null
|
||
}
|
||
})
|
||
let that = this
|
||
uni.showModal({
|
||
title: '提示',
|
||
content: '您是否要临时锁车?',
|
||
showCancel: true,
|
||
success: function(res) {
|
||
if (res.confirm) {
|
||
that.wenbentxt = '车辆临时锁车中...'
|
||
that.wenbentxtflag = true
|
||
let data = {
|
||
orderId: that.orderobj.orderId,
|
||
lat: that.lslat,
|
||
lon: that.lslon,
|
||
requiredIot: true,
|
||
macList:that.scdevlist,
|
||
bltRemark:that.bltRemark
|
||
}
|
||
that.$u.put(`/app/order/closeDevice`,data).then((res) => {
|
||
if (res.code == 200) {
|
||
that.wenbentxt = ''
|
||
that.wenbentxtflag = false
|
||
uni.showToast({
|
||
title: '临时锁车成功',
|
||
icon: 'success',
|
||
duration: 2000
|
||
})
|
||
that.orderobj.deviceLockStatus = 0
|
||
} else if (res.code == 20001) {
|
||
that.wenbentxt = '蓝牙临时锁车中...'
|
||
const findDevice = () => {
|
||
that.ver_dataflag = 2
|
||
const matchedDevice = that.devicesarr.find(device => {
|
||
return device.name.slice(-12) ==that.mac.slice(-12)
|
||
})
|
||
if (matchedDevice) {
|
||
xBlufi.notifyStartDiscoverBle({
|
||
'isStart': false
|
||
})
|
||
xBlufi.notifyConnectBle({
|
||
isStart: true,
|
||
deviceId: matchedDevice.deviceId,
|
||
name: matchedDevice.name
|
||
})
|
||
that.deviceid =matchedDevice.deviceId
|
||
that.devicename =matchedDevice.name
|
||
setTimeout(() => {
|
||
if (that.ver_dataflag ==3) {
|
||
that.orderobj.deviceLockStatus =0
|
||
xBlufi.notifySendCustomData({
|
||
customData: "11llosesub300@",
|
||
})
|
||
setTimeout(() => {
|
||
xBlufi.notifySendCustomData({
|
||
customData: "11reboot@"
|
||
})
|
||
that.wenbentxt =''
|
||
that.wenbentxtflag =false
|
||
},2000)
|
||
let lanya =''
|
||
if (that.jiance ==true) {
|
||
lanya ='蓝牙未开启'
|
||
} else {
|
||
lanya ='蓝牙已开启'
|
||
}
|
||
let data = {
|
||
mac: that.mac,
|
||
reason: '临时锁车' +lanya,
|
||
command: '11llosesub300@',
|
||
longitude: that.lslon,
|
||
latitude: that.lslat,
|
||
result: '失败'
|
||
}
|
||
that.$u.post(`/app/commandLog/bluetooth`,data).then(res =>{console.log(res,'蓝牙')})
|
||
let datas = {
|
||
orderId: that.orderobj.orderId,
|
||
lat: that.lslat,
|
||
lon: that.lslon,
|
||
requiredIot: false,
|
||
macList:that.scdevlist,
|
||
bltRemark:that.bltRemark
|
||
}
|
||
that.$u.put(`/app/order/closeDevice`,datas).then((res) => {})
|
||
} else {
|
||
that.ver_dataflag = 1
|
||
that.shibainum = 0
|
||
that.wenbentxt = ''
|
||
that.wenbentxtflag = false
|
||
that.ljsbflag = true
|
||
that.chongshinum = '锁车'
|
||
uni.openBluetoothAdapter({
|
||
success: function (res) {
|
||
|
||
},
|
||
fail: function (err) {
|
||
console.error('蓝牙适配器初始化失败', err)
|
||
// 蓝牙未打开或初始化失败
|
||
if(err.errMsg == 'openBluetoothAdapter:fail auth deny'){
|
||
uni.showToast({
|
||
title: '请检查微信蓝牙权限是否授权',
|
||
icon: 'none',
|
||
duration:5000
|
||
})
|
||
}else if(err.errMsg == 'openBluetoothAdapter:fail open fail'){
|
||
uni.showToast({
|
||
title: '请检查手机蓝牙是否打开',
|
||
icon: 'none',
|
||
duration:5000
|
||
})
|
||
}else if(err.errMsg == 'openBluetoothAdapter:fail:not available'){
|
||
uni.showToast({
|
||
title: '请检查手机蓝牙是否打开',
|
||
icon: 'none',
|
||
duration:5000
|
||
})
|
||
}
|
||
}
|
||
})
|
||
}
|
||
}, 4000)
|
||
} else {
|
||
if (that.shibainum < 3) {
|
||
that.shibainum++
|
||
that.findDeviceTimer = setTimeout(findDevice.bind(that),1000) // 使用 bind 保持 this 上下文
|
||
} else {
|
||
that.ver_dataflag = 1
|
||
that.shibainum = 0
|
||
that.wenbentxt = ''
|
||
that.wenbentxtflag = false
|
||
that.ljsbflag = true
|
||
that.chongshinum = '锁车'
|
||
let lanya = ''
|
||
if (that.jiance == true) {
|
||
lanya = '蓝牙未开启'
|
||
} else {
|
||
lanya = '蓝牙已开启'
|
||
}
|
||
let data = {
|
||
mac: that.mac,
|
||
orderId: that.orderobj.orderId,
|
||
reason: '用户蓝牙临时锁车失败' +lanya,
|
||
command: '11llosesub300@',
|
||
lat: that.lslat,
|
||
lon: that.lslon,
|
||
result: '失败'
|
||
}
|
||
that.$u.post(`/app/commandLog/bluetooth`,data).then(res => {})
|
||
uni.openBluetoothAdapter({
|
||
success: function (res) {
|
||
|
||
},
|
||
fail: function (err) {
|
||
console.error('蓝牙适配器初始化失败', err)
|
||
// 蓝牙未打开或初始化失败
|
||
if(err.errMsg == 'openBluetoothAdapter:fail auth deny'){
|
||
uni.showToast({
|
||
title: '请检查微信蓝牙权限是否授权',
|
||
icon: 'none',
|
||
duration:5000
|
||
})
|
||
}else if(err.errMsg == 'openBluetoothAdapter:fail open fail'){
|
||
uni.showToast({
|
||
title: '请检查手机蓝牙是否打开',
|
||
icon: 'none',
|
||
duration:5000
|
||
})
|
||
}else if(err.errMsg == 'openBluetoothAdapter:fail:not available'){
|
||
uni.showToast({
|
||
title: '请检查手机蓝牙是否打开',
|
||
icon: 'none',
|
||
duration:5000
|
||
})
|
||
}
|
||
}
|
||
})
|
||
}
|
||
}
|
||
}
|
||
findDevice()
|
||
} else {
|
||
that.wenbentxt = ''
|
||
that.wenbentxtflag = false
|
||
uni.showToast({
|
||
title: res.msg,
|
||
icon: 'none',
|
||
duration: 2000
|
||
})
|
||
}
|
||
})
|
||
} else if (res.cancel) {
|
||
console.log('取消') // 用户点击取消
|
||
}
|
||
}
|
||
})
|
||
}
|
||
}
|
||
} else {
|
||
uni.navigateTo({
|
||
url: '/page_user/yongche/orderxq?id=' + this.orderobj.orderId
|
||
})
|
||
}
|
||
} else if (res.code == 40001) {
|
||
uni.navigateTo({
|
||
url: '/page_user/yongche/orderxq?id=' + this.orderobj.orderId
|
||
})
|
||
}
|
||
})
|
||
},
|
||
// 获取本人正在使用的订单设备
|
||
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.mac = res.data.deviceMac
|
||
this.orderflag = true
|
||
this.isPageActive = true
|
||
this.gethuiyuan()
|
||
this.getMyLocation()
|
||
this.initWebSocket() //WebSocket接受数据
|
||
this.$u.get(`/app/area/detail?id=${this.orderAreaId}`).then((res) => {
|
||
if (res.code == 200) {
|
||
this.enableChange = res.data.enableChange
|
||
const polylines = this.convertBoundaryToPolyline(res.data.boundaryStr)
|
||
this.polyline.push(polylines)
|
||
this.getParking()
|
||
}
|
||
})
|
||
this.startRideTimer()
|
||
// 如果有数据,启动定时器每分钟执行一次
|
||
this.startOrderDeviceTimer()
|
||
} else {
|
||
uni.reLaunch({
|
||
url: '/pages/nearbystores/index'
|
||
})
|
||
this.orderAreaId = ''
|
||
this.orderflag = false
|
||
this.newMarkers = ''
|
||
console.log(this.covers)
|
||
this.stopRideTimer()
|
||
this.rideDurationText = '00:00'
|
||
// 如果没有数据,停止定时器
|
||
this.stopOrderDeviceTimer()
|
||
}
|
||
}
|
||
})
|
||
},
|
||
// 请求会员卡列表
|
||
gethuiyuan() {
|
||
this.$u.get(`/app/vip/listByArea?areaId=${this.areaId}`).then(res => {
|
||
if (res.code == 200) {
|
||
this.huiyuanlist = res.data
|
||
}
|
||
})
|
||
},
|
||
// 点击跳转到购买会员列表
|
||
btnhuiyuan() {
|
||
uni.navigateTo({
|
||
url: '/page_fenbao/huiyuan/index?areaId=' + this.areaId
|
||
})
|
||
},
|
||
// 启动订单设备定时器
|
||
startOrderDeviceTimer() {
|
||
// 先清除可能存在的定时器
|
||
this.stopOrderDeviceTimer()
|
||
// 创建新的定时器,每分钟执行一次
|
||
this.orderDeviceTimer = setInterval(() => {
|
||
// 检查页面是否活跃
|
||
if (!this.isPageActive) {
|
||
this.stopOrderDeviceTimer()
|
||
return
|
||
}
|
||
// 执行获取订单设备的请求
|
||
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.mac = res.data.deviceMac
|
||
this.orderflag = true
|
||
this.isPageActive = true
|
||
this.computeRideDurationText()
|
||
if (!this.rideTimer) this.startRideTimer()
|
||
// 如果WebSocket连接断开,重新连接
|
||
if (!this.socketTask || this.socketTask.readyState !== 1) {
|
||
this.initWebSocket()
|
||
}
|
||
} else {
|
||
// 如果没有数据,停止定时器
|
||
this.orderAreaId = ''
|
||
this.orderflag = false
|
||
this.newMarkers = ''
|
||
this.stopRideTimer()
|
||
this.rideDurationText = '00:00'
|
||
this.stopOrderDeviceTimer()
|
||
}
|
||
}
|
||
}).catch(err => {
|
||
console.error('定时获取订单设备失败:', err)
|
||
// 发生错误时也停止定时器
|
||
this.stopOrderDeviceTimer()
|
||
})
|
||
}, 60000) // 60000毫秒 = 1分钟
|
||
},
|
||
// 停止订单设备定时器
|
||
stopOrderDeviceTimer() {
|
||
if (this.orderDeviceTimer) {
|
||
clearInterval(this.orderDeviceTimer)
|
||
this.orderDeviceTimer = null
|
||
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.setStorageSync('user', res.user)
|
||
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() {
|
||
let data = {
|
||
id:this.orderobj.deviceId,
|
||
lat:this.xllat,
|
||
lon:this.xllng,
|
||
macList:this.scdevlist
|
||
}
|
||
this.$u.put(`/app/device/iot/ring`,data).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.newMarkers = ''
|
||
},
|
||
|
||
// 点击选择骑行套餐
|
||
btntcxz(index) {
|
||
this.tcindex = index
|
||
},
|
||
// 点击跳转到帮助中心
|
||
btnbz() {
|
||
uni.navigateTo({
|
||
url: '/page_user/bangzhu'
|
||
})
|
||
},
|
||
// 点击拨打平台客服电话
|
||
btnptkf(tel) {
|
||
uni.makePhoneCall({
|
||
phoneNumber: tel,
|
||
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) {
|
||
console.log(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 = this.iconobj.mappic
|
||
this.$u.get(`/app/device/listNearBy?radius=10000¢er=${this.jingweidu}&areaId=${this.orderobj.orderAreaId == undefined ? null : this.orderobj.orderAreaId}`).then((res) => {
|
||
if (res.code == 200) {
|
||
this.covers = []
|
||
this.listData = []
|
||
this.$set(this, 'covers', [...this.covers, ...this.newMarkers])
|
||
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',
|
||
})
|
||
}
|
||
this.listData = res.data
|
||
res.data.forEach(item => {
|
||
const shopCover = {
|
||
// 门店后面拼接1,车辆拼接2,3是导览
|
||
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: item.modelIcon == null ? this.iconPath : item.modelIcon,
|
||
callout: {
|
||
content: item.vehicleNum == null ? item.sn : '' + 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: 'gcj02',
|
||
success: (res) => {
|
||
this.latitude = Number(res.latitude) - 0.005
|
||
this.longitude = Number(res.longitude) + 0.005
|
||
this.jingweidu = this.longitude + ',' + this.latitude
|
||
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: "#55888820",
|
||
strokeColor: "#22FF00",
|
||
strokeWidth: 1,
|
||
zIndex: 1,
|
||
isOperationArea: true
|
||
}
|
||
return polyline
|
||
},
|
||
convertBoundaryToPolylines(boundaries, num) {
|
||
if (!Array.isArray(boundaries)) {
|
||
console.error('边界数据不是数组:', boundaries)
|
||
return []
|
||
}
|
||
|
||
const polylines = boundaries.map(boundary => {
|
||
if (!boundary) {
|
||
console.warn('边界数据为空')
|
||
return null
|
||
}
|
||
|
||
let coords
|
||
try {
|
||
coords = JSON.parse(boundary)
|
||
} catch (error) {
|
||
console.error('解析边界JSON失败:', error)
|
||
return null
|
||
}
|
||
|
||
if (!Array.isArray(coords)) {
|
||
console.error('解析后的边界数据不是数组:', coords)
|
||
return null
|
||
}
|
||
|
||
const points = coords.map(coord => {
|
||
if (!Array.isArray(coord) || coord.length < 2) {
|
||
console.warn('坐标数据格式错误:', coord)
|
||
return null
|
||
}
|
||
return {
|
||
latitude: parseFloat(coord[1]),
|
||
longitude: parseFloat(coord[0])
|
||
}
|
||
}).filter(point => point !== null)
|
||
|
||
if (points.length < 3) {
|
||
console.warn('有效坐标点不足3个,无法构成多边形')
|
||
return null
|
||
}
|
||
|
||
// 根据类型设置不同的样式
|
||
let style = {}
|
||
if (num == 1) { // 停车区
|
||
style = {
|
||
fillColor: "#88888850",
|
||
strokeColor: "#88888850",
|
||
strokeWidth: 1,
|
||
zIndex: 1,
|
||
isOperationArea: false
|
||
}
|
||
} else if (num == 2) { // 禁停区
|
||
style = {
|
||
fillColor: "#FFF5D640",
|
||
strokeColor: "#FF473E",
|
||
strokeWidth: 2,
|
||
zIndex: 1,
|
||
isOperationArea: false
|
||
}
|
||
} else if (num == 3) { // 禁行区
|
||
style = {
|
||
fillColor: "#FFD1CF40",
|
||
strokeColor: "#FFC107",
|
||
strokeWidth: 2,
|
||
zIndex: 1,
|
||
isOperationArea: false
|
||
}
|
||
} else if (num == 4) { // 景区
|
||
style = {
|
||
fillColor: "#4abd2040",
|
||
strokeColor: "#4abd20",
|
||
strokeWidth: 2,
|
||
zIndex: 1,
|
||
isOperationArea: false
|
||
}
|
||
}
|
||
|
||
return {
|
||
points: points,
|
||
...style
|
||
}
|
||
}).filter(polyline => polyline !== null)
|
||
|
||
return polylines
|
||
},
|
||
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: 18,
|
||
height: 26,
|
||
iconPath: item.type == 1 ?
|
||
'https://lxnapi.ccttiot.com/bike/img/static/up2xXqAgwCX5iER600k3' :
|
||
item.type == 2 ?
|
||
'https://lxnapi.ccttiot.com/bike/img/static/uDNY5Q4zOiZTCBTA2Jdq' :
|
||
item.type == 3 ?
|
||
'https://lxnapi.ccttiot.com/bike/img/static/u53BAQcFIX3vxsCzEZ7t' :
|
||
'https://api.ccttiot.com/%E5%BE%AE%E4%BF%A1%E5%9B%BE%E7%89%87_20250829161752_210_17-1756455764351.png',
|
||
callout: {
|
||
content: item.name,
|
||
color: '#ffffff',
|
||
fontSize: 12,
|
||
borderRadius: 8,
|
||
bgColor: item.type == 1 ? '#3A7EDB' : item.type == 2 ? '#FF473E' : item
|
||
.type == 3 ? '#FFC107' : '#3bbd55',
|
||
padding: 4,
|
||
display: 'ALWAYS'
|
||
},
|
||
isCalloutVisible: true // 添加标记
|
||
})
|
||
})
|
||
this.newMarkers = newMarkers
|
||
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 && Array.isArray(res.data)) {
|
||
// 缓存数据
|
||
const filteredData = res.data.filter(item => item.status != 1);
|
||
this.cachedParkingData[this.areaId] = filteredData
|
||
const type1Data = []
|
||
const type2Data = []
|
||
const type3Data = []
|
||
const type4Data = []
|
||
filteredData.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)
|
||
else if (row.type == 4) type4Data.push(row)
|
||
})
|
||
const processBoundaries = (data, type) => {
|
||
const validBoundaries = data.map(row => row.boundaryStr).filter(boundary => boundary && typeof boundary === 'string' && boundary.trim() !== '')
|
||
if (validBoundaries.length > 0) {
|
||
const polylines = this.convertBoundaryToPolylines(validBoundaries, type)
|
||
if (polylines && polylines.length > 0) {
|
||
return polylines
|
||
}
|
||
}
|
||
return []
|
||
}
|
||
// 先处理所有边界数据
|
||
const type1Polylines = processBoundaries(type1Data, 1)
|
||
const type2Polylines = processBoundaries(type2Data, 2)
|
||
const type3Polylines = processBoundaries(type3Data, 3)
|
||
const type4Polylines = processBoundaries(type4Data, 4)
|
||
// 保留现有的运营区边界
|
||
const operationAreaPolylines = this.polyline.filter(p => p.isOperationArea)
|
||
// 合并所有边界数据
|
||
const allPolylines = [
|
||
...operationAreaPolylines,
|
||
...type1Polylines,
|
||
...type2Polylines,
|
||
...type3Polylines,
|
||
...type4Polylines
|
||
]
|
||
// 缓存多边形数据
|
||
this.cachedPolyline = allPolylines
|
||
// 更新显示
|
||
this.polyline = allPolylines
|
||
this.parkingList = filteredData
|
||
this.isFirstLoad = false
|
||
}
|
||
})
|
||
},
|
||
updatePolylineFromCache() {
|
||
// 保留现有的运营区边界
|
||
const operationAreaPolylines = this.polyline.filter(p => p.isOperationArea)
|
||
// 从缓存中获取其他边界数据
|
||
const otherPolylines = this.cachedPolyline.filter(p => !p.isOperationArea)
|
||
// 合并数据
|
||
const allPolylines = [...operationAreaPolylines, ...otherPolylines]
|
||
// 更新显示
|
||
this.polyline = allPolylines
|
||
},
|
||
// 请求运营区停车点,禁行区,
|
||
getArea() {
|
||
this.polyline = []
|
||
this.$u.get(`/app/area/detail?id=${this.areaId}`).then((res) => {
|
||
this.enableChange = res.data.enableChange
|
||
if (res.code == 200) {
|
||
const polylines = this.convertBoundaryToPolyline(res.data.boundaryStr)
|
||
this.polyline.push(polylines)
|
||
this.getParking()
|
||
}
|
||
})
|
||
},
|
||
// 第一次请求运营区停车点,禁行区,
|
||
getAone() {
|
||
this.$u.get(`/getInfo`).then(res => {
|
||
if (res.code == 200) {
|
||
this.user = res.user
|
||
this.$u.get(`/app/area/nearby?id=${res.user.areaId == null ? '' : res.user.areaId}&radius=1000¢er=${this.jingweidu}&appId=${this.$store.state.appid}`).then((resp) => {
|
||
if (resp.code == 200) {
|
||
if (resp.data) {
|
||
this.yyid = resp.data.id
|
||
}
|
||
if (resp.data && resp.data.boundaryStr) {
|
||
const polylines = this.convertBoundaryToPolyline(resp.data.boundaryStr)
|
||
if (polylines) {
|
||
this.polyline = [polylines]
|
||
this.getParking()
|
||
if (resp.data && resp.data.id) {
|
||
this.loadNearbyDevices(resp.data.id)
|
||
}
|
||
}
|
||
}
|
||
}
|
||
})
|
||
}
|
||
})
|
||
},
|
||
|
||
loadNearbyDevices(areaId) {
|
||
if (this.rtindex == 2) {
|
||
this.$u.get(`/app/device/listNearBy?radius=10000¢er=${this.jingweidu}&areaId=${areaId}`).then((res) => {
|
||
if (res.code == 200) {
|
||
this.listData = res.data
|
||
this.updateMarkers()
|
||
}
|
||
})
|
||
}
|
||
},
|
||
|
||
updateMarkers() {
|
||
const newMarkers = []
|
||
this.listData.forEach(item => {
|
||
if (item.latitude && item.longitude) {
|
||
const marker = {
|
||
id: this.rtindex == 1 ? parseInt(item.id + "1") : this.rtindex == 2 ? parseInt(item.id + "2") : parseInt(item.id + "3"),
|
||
latitude: parseFloat(item.latitude),
|
||
longitude: parseFloat(item.longitude),
|
||
width: 35,
|
||
height: 40,
|
||
iconPath: item.modelIcon == null ? this.getIconPath() : item.modelIcon,
|
||
callout: {
|
||
content: item.vehicleNum || item.sn || '',
|
||
color: '#0D75E5',
|
||
fontSize: 10,
|
||
borderRadius: 10,
|
||
bgColor: '#fff',
|
||
padding: 3,
|
||
display: 'ALWAYS'
|
||
}
|
||
}
|
||
newMarkers.push(marker)
|
||
}
|
||
})
|
||
this.tempCovers = newMarkers
|
||
this.covers = this.tempCovers
|
||
},
|
||
getIconPath() {
|
||
if (this.rtindex == 1) {
|
||
return 'https://api.ccttiot.com/smartmeter/img/static/upX2lLilhrRi4tttdHlo'
|
||
} else if (this.rtindex == 2) {
|
||
return this.iconobj.mappic
|
||
} else if (this.rtindex == 3) {
|
||
return 'https://api.ccttiot.com/smartmeter/img/static/un7ecyEN8vsJhlEnXfD4'
|
||
}
|
||
return null
|
||
},
|
||
updatePolyline(newPolylines) {
|
||
// 使用Vue的响应式更新
|
||
this.tempPolyline = [...newPolylines]
|
||
this.polyline = this.tempPolyline
|
||
},
|
||
updateCovers(newCovers) {
|
||
// 使用Vue的响应式更新
|
||
this.tempCovers = [...newCovers]
|
||
this.covers = this.tempCovers
|
||
},
|
||
|
||
}
|
||
}
|
||
</script>
|
||
|
||
<style lang="scss">
|
||
.gonggao{
|
||
width: 682rpx;
|
||
height: 72rpx;
|
||
overflow: hidden;
|
||
background: #FFFFFF;
|
||
box-shadow: 0rpx 4rpx 10rpx 0rpx rgba(0,0,0,0.3);
|
||
border-radius: 53rpx 53rpx 53rpx 53rpx;
|
||
position: fixed;
|
||
left: 50%;
|
||
transform: translateX(-50%);
|
||
z-index: 99;
|
||
display: flex;
|
||
align-items: center;
|
||
margin-bottom: 10rpx;
|
||
margin: auto;
|
||
padding-left: 70rpx;
|
||
.container{
|
||
width: 560rpx;
|
||
overflow: hidden;
|
||
height: 72rpx;
|
||
line-height: 72rpx;
|
||
}
|
||
}
|
||
page {
|
||
background: #fff;
|
||
border-radius: 0rpx 0rpx 0rpx 0rpx;
|
||
}
|
||
|
||
@keyframes gifLoop {
|
||
0% {
|
||
opacity: 1;
|
||
}
|
||
|
||
100% {
|
||
opacity: 1;
|
||
}
|
||
}
|
||
|
||
.active {
|
||
image {
|
||
z-index: 99 !important;
|
||
}
|
||
|
||
.bike_item {
|
||
border: 1px solid #4297F3 !important;
|
||
}
|
||
}
|
||
|
||
.daohang {
|
||
width: 750rpx;
|
||
height: 652rpx;
|
||
background: #FFFFFF;
|
||
box-shadow: 0rpx 10rpx 64rpx 0rpx rgba(0, 0, 0, 0.08);
|
||
position: fixed;
|
||
left: 0;
|
||
bottom: 0;
|
||
border-radius: 30rpx 30rpx 0 0;
|
||
padding: 44rpx 38rpx;
|
||
box-sizing: border-box;
|
||
|
||
.cha {
|
||
font-size: 60rpx;
|
||
font-weight: 600;
|
||
position: absolute;
|
||
top: 30rpx;
|
||
right: 34rpx;
|
||
}
|
||
|
||
.name {
|
||
font-weight: 600;
|
||
font-size: 44rpx;
|
||
color: #3D3D3D;
|
||
display: flex;
|
||
align-items: center;
|
||
|
||
text {
|
||
padding: 6rpx 10rpx;
|
||
background-color: #0D75E5;
|
||
color: #fff;
|
||
margin-left: 10rpx;
|
||
border-radius: 6rpx;
|
||
font-size: 26rpx;
|
||
}
|
||
}
|
||
|
||
.shuom {
|
||
font-weight: 600;
|
||
font-size: 32rpx;
|
||
color: #808080;
|
||
margin-top: 22rpx;
|
||
}
|
||
|
||
image {
|
||
width: 680rpx;
|
||
height: 234rpx;
|
||
margin-top: 30rpx;
|
||
}
|
||
|
||
.anniu {
|
||
width: 682rpx;
|
||
height: 90rpx;
|
||
background: #4C97E7;
|
||
border-radius: 54rpx 54rpx 54rpx 54rpx;
|
||
font-weight: 600;
|
||
font-size: 40rpx;
|
||
color: #FFFFFF;
|
||
text-align: center;
|
||
line-height: 90rpx;
|
||
margin-top: 62rpx;
|
||
}
|
||
}
|
||
|
||
@keyframes fadeIn {
|
||
from {
|
||
opacity: 0;
|
||
}
|
||
|
||
to {
|
||
opacity: 1;
|
||
}
|
||
}
|
||
|
||
@keyframes rotate360 {
|
||
0% {
|
||
transform: rotate(0deg);
|
||
}
|
||
|
||
100% {
|
||
transform: rotate(360deg);
|
||
}
|
||
}
|
||
|
||
@keyframes pulse {
|
||
|
||
0%,
|
||
100% {
|
||
transform: scale(1);
|
||
opacity: 1;
|
||
}
|
||
|
||
50% {
|
||
transform: scale(1.1);
|
||
opacity: 0.8;
|
||
}
|
||
}
|
||
|
||
.tongyi {
|
||
width: 100%;
|
||
height: 580rpx;
|
||
background: #FFFFFF;
|
||
border-radius: 3rpx 3rpx 0rpx 0rpx;
|
||
position: fixed;
|
||
bottom: 0;
|
||
left: 50%;
|
||
transform: translateX(-50%);
|
||
z-index: 97;
|
||
border-radius: 30rpx 30rpx 0 0;
|
||
text-align: center;
|
||
|
||
.anniu {
|
||
width: 100%;
|
||
display: flex;
|
||
justify-content: space-between;
|
||
margin-top: 30rpx;
|
||
|
||
.lx {
|
||
width: 338rpx;
|
||
height: 90rpx;
|
||
border-radius: 10rpx;
|
||
border: 2rpx solid #808080;
|
||
text-align: center;
|
||
line-height: 90rpx;
|
||
font-size: 40rpx;
|
||
color: #808080;
|
||
}
|
||
|
||
.zx {
|
||
width: 338rpx;
|
||
height: 90rpx;
|
||
background: #4C97E7;
|
||
border-radius: 10rpx;
|
||
text-align: center;
|
||
line-height: 90rpx;
|
||
font-size: 40rpx;
|
||
color: #FFFFFF;
|
||
}
|
||
}
|
||
|
||
.top {
|
||
display: flex;
|
||
justify-content: center;
|
||
align-items: center;
|
||
margin-top: 30rpx;
|
||
|
||
image {
|
||
width: 50rpx;
|
||
height: 50rpx;
|
||
margin-right: 8rpx;
|
||
animation: rotate360 1.2s linear infinite;
|
||
}
|
||
|
||
font-weight: 600;
|
||
font-size: 32rpx;
|
||
color: #3D3D3D;
|
||
|
||
.percentage-text {
|
||
margin-left: 10rpx;
|
||
font-size: 36rpx; // 增大字体,与前方文字保持一致
|
||
color: #3D3D3D; // 使用与前方文字相同的颜色
|
||
font-weight: 600; // 与前方文字保持一致的字体粗细
|
||
animation: pulse 1.5s ease-in-out infinite;
|
||
cursor: pointer;
|
||
transition: all 0.3s ease;
|
||
|
||
&:hover {
|
||
color: #000; // 悬停时变为黑色
|
||
transform: scale(1.05);
|
||
}
|
||
}
|
||
}
|
||
|
||
.tops {
|
||
margin-top: 30rpx;
|
||
|
||
image {
|
||
width: 50rpx;
|
||
height: 50rpx;
|
||
margin-right: 8rpx;
|
||
}
|
||
}
|
||
|
||
// 蓝牙连接失败样式
|
||
.bluetooth-error-container {
|
||
padding: 40rpx 30rpx;
|
||
text-align: left;
|
||
|
||
.error-header {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
margin-bottom: 40rpx;
|
||
|
||
.error-icon {
|
||
width: 40rpx;
|
||
height: 40rpx;
|
||
margin-right: 16rpx;
|
||
}
|
||
|
||
.error-title {
|
||
font-weight: 600;
|
||
font-size: 36rpx;
|
||
color: #333;
|
||
}
|
||
}
|
||
|
||
.error-steps {
|
||
margin-bottom: 40rpx;
|
||
|
||
.step-item {
|
||
display: flex;
|
||
align-items: center;
|
||
margin-bottom: 24rpx;
|
||
padding: 20rpx;
|
||
background: linear-gradient(135deg, #f8f9fa 0%, #e9ecef 100%);
|
||
border-radius: 16rpx;
|
||
border-left: 6rpx solid #4C97E7;
|
||
box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.05);
|
||
transition: all 0.3s ease;
|
||
|
||
&:hover {
|
||
transform: translateX(8rpx);
|
||
box-shadow: 0 8rpx 20rpx rgba(76, 151, 231, 0.15);
|
||
}
|
||
|
||
.step-number {
|
||
width: 48rpx;
|
||
height: 48rpx;
|
||
background: linear-gradient(135deg, #4C97E7 0%, #6BB6FF 100%);
|
||
color: #fff;
|
||
border-radius: 50%;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
font-weight: 600;
|
||
font-size: 28rpx;
|
||
margin-right: 20rpx;
|
||
box-shadow: 0 4rpx 12rpx rgba(76, 151, 231, 0.3);
|
||
}
|
||
|
||
.step-text {
|
||
flex: 1;
|
||
font-size: 30rpx;
|
||
color: #333;
|
||
line-height: 1.5;
|
||
font-weight: 500;
|
||
}
|
||
}
|
||
}
|
||
|
||
.tutorial-link {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
padding: 24rpx 32rpx;
|
||
background: linear-gradient(135deg, #4C97E7 0%, #6BB6FF 100%);
|
||
border-radius: 50rpx;
|
||
box-shadow: 0 8rpx 24rpx rgba(76, 151, 231, 0.3);
|
||
transition: all 0.3s ease;
|
||
cursor: pointer;
|
||
|
||
&:hover {
|
||
transform: translateY(-4rpx);
|
||
box-shadow: 0 12rpx 32rpx rgba(76, 151, 231, 0.4);
|
||
}
|
||
|
||
&:active {
|
||
transform: translateY(-2rpx);
|
||
}
|
||
|
||
.tutorial-text {
|
||
color: #fff;
|
||
font-size: 32rpx;
|
||
font-weight: 600;
|
||
margin-right: 12rpx;
|
||
}
|
||
|
||
.tutorial-arrow {
|
||
color: #fff;
|
||
font-size: 32rpx;
|
||
font-weight: 600;
|
||
transition: transform 0.3s ease;
|
||
}
|
||
|
||
&:hover .tutorial-arrow {
|
||
transform: translateX(8rpx);
|
||
}
|
||
}
|
||
}
|
||
|
||
.ddc {
|
||
width: 610rpx;
|
||
height: 314rpx;
|
||
margin-top: 40rpx;
|
||
animation: gifLoop 1s infinite;
|
||
}
|
||
}
|
||
|
||
.fixdivce {
|
||
padding: 12rpx 22rpx 12rpx 22rpx;
|
||
position: fixed;
|
||
left: 0;
|
||
top: 34vh;
|
||
width: 280rpx;
|
||
height: 40vh;
|
||
background: #FFFFFF10;
|
||
border-radius: 0 40rpx 40rpx 0;
|
||
box-shadow: 0rpx 4rpx 10rpx 0rpx rgba(0, 0, 0, 0.3);
|
||
|
||
.scrollable-content::-webkit-scrollbar {
|
||
display: none;
|
||
}
|
||
|
||
.scrollable-content {
|
||
height: 100%;
|
||
overflow-y: auto;
|
||
|
||
.divce_li:last-child {
|
||
border-bottom: 1rpx solid #fff;
|
||
}
|
||
|
||
.divce_li {
|
||
padding: 10rpx 0;
|
||
display: flex;
|
||
flex-wrap: nowrap;
|
||
align-items: center;
|
||
border-bottom: 1rpx solid #D8D8D8;
|
||
|
||
.left_img {
|
||
image {
|
||
width: 44rpx;
|
||
height: 70rpx;
|
||
}
|
||
}
|
||
|
||
.right_cont {
|
||
margin-left: 20rpx;
|
||
display: flex;
|
||
flex-wrap: wrap;
|
||
font-weight: 400;
|
||
font-size: 24rpx;
|
||
color: #3D3D3D;
|
||
|
||
.right_top {
|
||
width: 100%;
|
||
display: flex;
|
||
flex-wrap: nowrap;
|
||
align-items: center;
|
||
|
||
.right_top_left {
|
||
margin-left: auto;
|
||
display: flex;
|
||
flex-wrap: nowrap;
|
||
align-items: center;
|
||
|
||
image {
|
||
margin-right: 6rpx;
|
||
width: 12rpx;
|
||
height: 26rpx;
|
||
}
|
||
}
|
||
|
||
.right_top_right {}
|
||
}
|
||
|
||
.right_bot {
|
||
width: 100%;
|
||
display: flex;
|
||
flex-wrap: nowrap;
|
||
justify-content: space-between;
|
||
margin-top: 8rpx;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
.mask {
|
||
width: 100%;
|
||
height: 100vh;
|
||
position: fixed;
|
||
top: 0;
|
||
left: 0;
|
||
background-color: rgba(0, 0, 0, .3);
|
||
z-index: 9;
|
||
}
|
||
|
||
.tingchetc {
|
||
width: 100%;
|
||
height: 700rpx;
|
||
background: #FFFFFF;
|
||
border-radius: 20rpx 20rpx 20rpx 20rpx;
|
||
position: fixed;
|
||
left: 50%;
|
||
transform: translateX(-50%);
|
||
bottom: 0;
|
||
z-index: 99;
|
||
padding: 28rpx 36rpx;
|
||
box-sizing: border-box;
|
||
|
||
.btnan {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
margin-top: 40rpx;
|
||
|
||
.fj {
|
||
width: 320rpx;
|
||
height: 90rpx;
|
||
border-radius: 10rpx;
|
||
border: 2rpx solid #808080;
|
||
font-weight: 600;
|
||
font-size: 32rpx;
|
||
color: #808080;
|
||
text-align: center;
|
||
line-height: 90rpx;
|
||
}
|
||
|
||
.qx {
|
||
width: 330rpx;
|
||
height: 90rpx;
|
||
background: #4C97E7;
|
||
border-radius: 10rpx;
|
||
text-align: center;
|
||
line-height: 90rpx;
|
||
box-sizing: border-box;
|
||
font-weight: 600;
|
||
font-size: 32rpx;
|
||
color: #FFFFFF;
|
||
}
|
||
}
|
||
|
||
.tcimg {
|
||
width: 668rpx;
|
||
height: 360rpx;
|
||
margin-top: 28rpx;
|
||
animation: gifLoop 1s infinite;
|
||
}
|
||
|
||
.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: 100%;
|
||
height: 600rpx;
|
||
margin: 0 auto;
|
||
margin-top: 38rpx;
|
||
background: #FFFFFF;
|
||
box-shadow: 0rpx 10rpx 64rpx 0rpx rgba(0, 0, 0, 0.08);
|
||
border-radius: 30rpx 30rpx 20rpx 20rpx;
|
||
padding-bottom: 20rpx;
|
||
position: fixed;
|
||
left: 50%;
|
||
-webkit-transform: translateX(-50%);
|
||
transform: translateX(-50%);
|
||
bottom: 0;
|
||
padding-bottom: 30rpx;
|
||
box-sizing: border-box;
|
||
|
||
.orderzt {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
width: 100%;
|
||
border-bottom: 1px solid #F4F4F4;
|
||
padding: 0 54rpx;
|
||
position: relative;
|
||
background-color: #fff;
|
||
|
||
.qixing {
|
||
width: 100%;
|
||
height: 130rpx;
|
||
position: absolute;
|
||
top: -80rpx;
|
||
left: 0;
|
||
z-index: -1;
|
||
}
|
||
|
||
.NO {
|
||
font-weight: 600;
|
||
font-size: 32rpx;
|
||
color: #3D3D3D;
|
||
display: flex;
|
||
align-items: center;
|
||
|
||
image {
|
||
width: 58rpx;
|
||
height: 70rpx;
|
||
margin-right: 8rpx;
|
||
}
|
||
}
|
||
|
||
.huanche {
|
||
width: 150rpx;
|
||
height: 60rpx;
|
||
background-color: #0D75E5;
|
||
color: #fff;
|
||
text-align: center;
|
||
line-height: 60rpx;
|
||
font-size: 32rpx;
|
||
border-radius: 30rpx;
|
||
}
|
||
|
||
.icon {
|
||
display: flex;
|
||
align-items: center;
|
||
|
||
image {
|
||
width: 30rpx;
|
||
height: 36rpx;
|
||
}
|
||
}
|
||
}
|
||
|
||
.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 {
|
||
width: 100%;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
|
||
image {
|
||
width: 90rpx;
|
||
height: 88rpx;
|
||
}
|
||
|
||
.jsdd {
|
||
width: 190rpx;
|
||
height: 88rpx;
|
||
background: rgba(76, 151, 231, 0);
|
||
border-radius: 20rpx 20rpx 20rpx 20rpx;
|
||
border: 2rpx solid #A8A8A8;
|
||
text-align: center;
|
||
line-height: 88rpx;
|
||
font-weight: 600;
|
||
font-size: 36rpx;
|
||
color: #3D3D3D;
|
||
}
|
||
|
||
.lssc {
|
||
font-weight: 600;
|
||
font-size: 36rpx;
|
||
color: #FFFFFF;
|
||
width: 240rpx;
|
||
height: 88rpx;
|
||
text-align: center;
|
||
line-height: 88rpx;
|
||
background: #4C97E7;
|
||
border-radius: 20rpx 20rpx 20rpx 20rpx;
|
||
}
|
||
}
|
||
|
||
.botbtn {
|
||
display: flex;
|
||
width: 100%;
|
||
justify-content: space-between;
|
||
margin-top: 30rpx;
|
||
padding: 0 30rpx;
|
||
}
|
||
|
||
.imgpic {
|
||
display: flex;
|
||
margin-top: 10rpx;
|
||
padding: 0 54rpx;
|
||
|
||
image {
|
||
width: 152rpx;
|
||
height: 38rpx;
|
||
margin-right: 16rpx;
|
||
}
|
||
|
||
.gzimg {
|
||
width: 152rpx;
|
||
height: 38rpx;
|
||
margin-right: 16rpx;
|
||
}
|
||
|
||
.hcimg {
|
||
width: 162rpx;
|
||
height: 38rpx;
|
||
}
|
||
}
|
||
|
||
.cont_li {
|
||
width: 100%;
|
||
display: flex;
|
||
flex-wrap: nowrap;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
margin-top: 20rpx;
|
||
padding: 0 54rpx;
|
||
background-color: #fff;
|
||
|
||
.one {
|
||
text-align: center;
|
||
|
||
.oneone {
|
||
font-weight: 600;
|
||
font-size: 52rpx;
|
||
color: #3D3D3D;
|
||
margin-top: 30rpx;
|
||
|
||
text {
|
||
font-size: 24rpx;
|
||
}
|
||
}
|
||
|
||
.twotwo {
|
||
font-weight: 600;
|
||
font-size: 24rpx;
|
||
color: #3D3D3D;
|
||
margin-top: 10rpx;
|
||
|
||
image {
|
||
width: 32rpx;
|
||
height: 32rpx;
|
||
margin-left: 10rpx;
|
||
}
|
||
}
|
||
}
|
||
|
||
.left {
|
||
font-weight: 600;
|
||
font-size: 36rpx;
|
||
color: #3D3D3D;
|
||
width: 70%;
|
||
|
||
.guzhang {
|
||
width: 240rpx;
|
||
text-align: center;
|
||
color: #fff !important;
|
||
padding: 8rpx 10rpx;
|
||
box-sizing: border-box;
|
||
border-radius: 50rpx;
|
||
background-color: #4C97E7;
|
||
font-weight: 400;
|
||
font-size: 28rpx;
|
||
margin-top: 10rpx;
|
||
}
|
||
|
||
.km {
|
||
font-weight: 400;
|
||
font-size: 28rpx;
|
||
color: #3D3D3D;
|
||
margin-top: 10rpx;
|
||
}
|
||
|
||
.speed {
|
||
margin-top: 10rpx;
|
||
width: 226rpx;
|
||
height: 22rpx;
|
||
background: #ccc;
|
||
border-radius: 16rpx 16rpx 16rpx 16rpx;
|
||
|
||
.speeds {
|
||
height: 100%;
|
||
background: #4297F3;
|
||
border-radius: 16rpx 16rpx 16rpx 16rpx;
|
||
}
|
||
}
|
||
|
||
|
||
}
|
||
|
||
.right {
|
||
padding-right: 20rpx;
|
||
font-size: 24rpx;
|
||
color: #333;
|
||
|
||
image {
|
||
width: 280rpx;
|
||
height: 224rpx;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
.picimg {
|
||
width: 46rpx;
|
||
height: 76rpx;
|
||
position: fixed;
|
||
left: 50%;
|
||
transform: translateX(-50%);
|
||
top: 30%;
|
||
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: 96;
|
||
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: 50rpx;
|
||
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: 200rpx;
|
||
|
||
image {
|
||
width: 78rpx;
|
||
height: 96rpx;
|
||
display: block;
|
||
margin-top: 32rpx;
|
||
}
|
||
}
|
||
|
||
.lticon {
|
||
position: fixed;
|
||
right: 20rpx;
|
||
bottom: 940rpx;
|
||
|
||
image {
|
||
width: 88rpx;
|
||
height: 88rpx;
|
||
display: block;
|
||
margin-top: 32rpx;
|
||
}
|
||
}
|
||
|
||
.map {
|
||
width: 100%;
|
||
height: 130vh;
|
||
position: absolute;
|
||
top: -30vh;
|
||
|
||
.center-marker {
|
||
position: absolute;
|
||
top: 50%;
|
||
left: 50%;
|
||
transform: translate(-50%, -80%);
|
||
/* 定位在中心点上方 */
|
||
pointer-events: none;
|
||
/* 使其不可点击 */
|
||
}
|
||
}
|
||
</style> |