class="battery_line">连接蓝牙</text>
</view>
<view class="state_box">
<image :src="isMore48?imgOuttime:img2" class="battery_net"></image>
<text
class="['battery_state',isMore48?'danger':'']">{{ isMore48?已超过48小时
:已使用${batteryDetail.lastDriverTime}
}}</text>
</view>
</view>
</view>
<view class="tips_box" v-if="isMore48">
<text class="tips">请尽快换电,以免造成电池损坏!</text>
</view>
</view>
<!-- //地图 -->
<s-map :mapHeight="mapHeight" @changeScale="(value)=>scale=value" :isShowView="isNew" :scale="curScale"
polyline="polyline" ref="map" :markers="markers" :controls="controls" @initIndex="initIndex" @markerTap="markerTap" @regionchange='regionchange' @clickMap="clickMap"></s-map>
<view class="invite_wrap" @click="goInvite">
<image class="invite_img" :src="invite_img" mode="widthFix"></image>
</view>
<view class="operate_wrap">
<view class="icon-wrap" @click="refresh">
<image :src="icon_reload" mode="widthFix"></image>
</view>
<view class="icon-wrap" style="margin-top: 16rpx;" @click="onControltap('点击重新定位')">
<image :src="icon_curlocation" mode="widthFix"></image>
</view>
</view>
<!-- //选中电柜显示组件 -->
<s-electric :isShow="electricShow" @openMapApp="openMapApp" :info="currentBoxInfo"></s-electric>
<!-- 新人广告 -->
<s-adv :isShow="isNew" @close="isNew = false" :url="newUrl" @imgClick="handleImg"></s-adv>
<!-- 套餐信息 -->
<s-popup-tip :isShow="isPackageShow" @closePop="isPackageShow = false"
packageInfo="packageInfo"></s-popup-tip>
<!-- #ifdef MP-WEIXIN -->
<f-btn type="fixed" bottom="100" v-if="isShowLogin" noPlaceholder noBg :btnList="[{
text:'登录/注册'
}]" @click="gotoLogin"></f-btn>
<f-btn type="fixed" bottom="100" v-if="isNeedReal" noPlaceholder noBg :btnList="[{
text:'实名认证'
}]" @click="gotoReal"></f-btn>
<!-- #endif -->
<!-- #ifdef MP-ALIPAY -->
<f-btn type="fixed" :bottom="systemsInfo" v-if="isShowLogin" noPlaceholder noBg :btnList="[{
text:'登录/注册'
}]" @click="gotoLogin"></f-btn>
<f-btn type="fixed" :bottom="systemsInfo" v-if="isNeedReal" noPlaceholder noBg :btnList="[{
text:'实名认证'
}]" @click="gotoReal"></f-btn>
<!-- #endif -->
</view>
</f-container>
</template>
<script>
let app = getApp()
let AMapWx = require('@/utils/AMapWX.js')
import { debounce } from '@/utils/util.js';
import {
Blue
} from "@/utils/blue.js"
import locationutil from '@/utils/locationUtil.js';
import {
getAuthorization,
setAuthorization
} from '@/utils/auth.js'
let flag = false
import indexMixins from './index_mixins.js'
import box from '@/utils/box.js'
import {
DashboardBox
} from './index_canvas.js';
import login from "../../utils/login.js";
export default {
mixins: [indexMixins],
data() {
return {
mapHeight: 0, // 页面高
latitude: '',
longitude: '',
curLatitude: 0,
curLongitude: 0,
curScale: 12,
markers: [], // 电柜
isNew: false,
isPackageShow: false,
packageInfo: {},
markerId: '', // 被选中的柜子的ID
original: null, // 电柜原始数据
currentBoxInfo: {
distance: ""
}, // 选中的柜子详情信息
electricShow: false, //电柜选中
// 未读消息数量
unReadMsgNum: 0,
titleStyle: {},
// 是否绑定设备
isBindDevice: true,
img: this.$imgBaseUrl + "s_battery/icon_net.png",
imgOffnet: this.$imgBaseUrl + "s_battery/icon_offnet.png",
imgBluet: this.$imgBaseUrl + "s_battery/icon_bluet.png",
img2: this.$imgBaseUrl + "s_battery/icon_runtime.png",
imgOuttime: this.$imgBaseUrl + "s_battery/icon_outtime.png",
invite_img: this.$imgBaseUrl + "invite_img.png",
icon_reload: this.$imgBaseUrl + "icon_reload.png",
icon_curlocation: this.$imgBaseUrl + "icon_curlocation.png",
cbox2: null, //画布实例对象
percent: 60, //当前进度值 车辆电量
isScooterSocNull: false,
batteryDetail: {},
isBlueConnect: false,
newUrl: "",
h5URL: "",
mapCtx: null,
info: {},
polyline: [],
isShowLogin: false,
systemsInfo: 0,
}
},
onLoad(options) {
// console.log('999999999999',options);
if((options?.inviteId || options?.activityUuid) && options?.inviteType){
setAuthorization("inviteId", options?.inviteId);
setAuthorization("inviteType", options?.inviteType);
setAuthorization("activityUuid", options?.activityUuid);
}
let systemInfo = uni.getSystemInfoSync();
this.systemsInfo = systemInfo.platform === 'ios' ? 148 : 130
// #ifdef MP-ALIPAY
my.hideTabBar()
my.setBackButton({
color: '#1f1f1f'
});
my.setNavigationBar({
frontColor: '#000000',
backgroundColor: '#FFFFFF'
})
this.titleStyle = {
textAlign: 'left',
marginLeft: '-160rpx'
};
// #endif
// #ifdef MP-WEIXIN
this.titleStyle = {
textAlign: 'left',
marginLeft: '-208rpx'
};
// #endif
this.$nextTick(() => {
this.mapHeight = this.$util.pxToRpx(app.globalData.windowHeight - 44 - 50);
this.queryProfileInfo()
})
// #ifdef MP-ALIPAY
setTimeout(() => { //初始化的时候定位到我的位置
this.onControltap()
}, 1000)
// #endif
},
computed: {
isMore48() {
//最近一次电池绑定时间
if (!this.batteryDetail.bindTime) return false;
///当前时间戳-绑定时间戳
let useTime = Date.now() - this.batteryDetail.bindTime;
let hour48 = 48 60 60 * 1000;
return useTime >= hour48;
},
isNeedReal() {
//isRealName 实名认证状态 0 未实名 1 已实名
if (!app.globalData || this.info.isRealName === undefined) return false;
return app.globalData.isProfileInfo && this.info.isRealName !== 1;
},
},
onShow() {
this.getUnReadMsgNum();
this.queryDashboardInfo();
this.getHomeBottomData();
this.getCurLocation();
this.queryProfileInfo()
this.isShowLogin = !app.globalData.isProfileInfo;
},
methods: {
openMapApp(data) {
// #ifdef MP-WEIXIN
this.mapCtx.openMapApp({
longitude: data.longitude,
latitude: data.latitude,
destination: data.destination
})
// #endif
// #ifdef MP-ALIPAY
my.openLocation({
longitude: data.longitude,
latitude: data.latitude,
name: data.destination,
address: data.destination,
success: res => {
// console.log(res);
},
fail: res => {
// console.log(res);
},
});
// #endif
},
gotoBat() {
uni.navigateTo({
url: "/pages/dashboardModule/dashboard/dashboard"
})
},
gotoReal() {
uni.navigateTo({
url: '/pages/mineModule/realNameAuth/realNameAuth'
})
},
gotoLogin() {
// #ifdef MP-ALIPAY
uni.navigateTo({
url: "/pages/auth/aliAuth"
})
// #endif
// #ifdef MP-WEIXIN
uni.navigateTo({
url: "/pages/auth/auth"
})
// #endif
},
refresh() {
// console.log('---------------1',this.latitude, this.longitude);
this.updateMarkers(this.latitude, this.longitude);
},
operateBluet() {
let that = this;
let bid = this.batteryDetail.bid.slice(-20);
// let myBlue = new Blue(bid,this);
let myBlue = new Blue(bid, (value) => {
that.percent = parseInt(value, 16);
that.isBlueConnect = true;
app.globalData.isBlueConnect = true;
app.globalData.batPercent = parseInt(value, 16);
that.initDashboard();
});
myBlue.initBlue();
},
getCurLocation(str) {
let that = this
return new Promise(resolve => {
//获取定位授权
locationutil.updateLocation(str).then(res => {
//更新定位
that.curLongitude = res.longitude;
that.curLatitude = res.latitude;
resolve(res)
})
})
},
//定位
onControltap:debounce(function(str) {
let that = this;
this.getCurLocation(str).then(res => {
this.mapCtx.moveToLocation({
latitude: res.latitude,
longitude: res.longitude,
success: () => {
that.notLoggedIn(res.latitude, res.longitude)
that.updateMarkers(res.latitude, res.longitude);
}
});
})
},500),
homePopup(CurrentCityCode) {
// 是否游客
if (app.globalData.visitor) return
app.httpsPro({
url: '/activity/app/homePopup',
header: {
CurrentCityCode
}
}).then(res => {
if (res && res.cardImgUrl) {
this.isNew = true;
this.newUrl = res.cardImgUrl;
this.h5URL = res.cardImgH5Ur;
}
})
},
handleImg() {
if (!this.h5URL) {
this.goInvite();
return;
};
uni.navigateTo({
url:'/pagesA/pages/invite/inviteCode'
})
},
goInvite() {
// this.$util.showToast('暂无活动');
// return false
this.$permission.isVisitor().then(res => {
app.httpsPro({
url: '/activity/app/my/info',
}).then(res => {
if (res && res.h5url) {
uni.navigateTo({
url:'/pagesA/pages/invite/inviteCode'
})
}
})
});
},
//获取用户信息
queryProfileInfo() {
if (app.globalData.visitor) return
app.https({
url: '/cloud-user/user/queryProfileInfo',
}).then(res => {
this.info = res;
res.packageConsumeList.forEach(val => {
if (val.finishTime) {
val.finishTimeText = this.$util.time2YMD(val.finishTime)
}
})
this.packageList = res.packageConsumeList
this.isRealName = res.isRealName;//实名认证状态 1 == 已经实名认证
app.globalData.isProfileInfo = true;
app.globalData.profileInfo = res;
this.isShowLogin = !app.globalData.isProfileInfo;
this.homePopup(res.cityCode); //营销策略
})
},
// 获取首页底部卡片套餐信息
getHomeBottomData() {
if (app.globalData.visitor) return
app.https({
url: '/cloud-user/user/homeBottomData',
}).then(res => {
this.packageInfo = res;
let lastPackageShowDay = getAuthorization("lastPackageShowDay");
let today = this.$util.time2YMD(new Date().getTime());
//residueDay == 有效天数 havePackage == 是否有套餐 freeze == 是否有冻结套餐
if (res.havePackage && (res.freeze || res.residueDay <= 0)) {
if (today !== lastPackageShowDay) {
this.isPackageShow = true;
setAuthorization("lastPackageShowDay", today);
}
}
})
},
getImg() {
//connectNet == 电池网络是否正常;正常:true; 异常false ;当网络异常时 电量和经纬度可能返回为空
if (this.batteryDetail.connectNet) {
return this.img
} else if (this.isBlueConnect || app.globalData.isBlueConnect) {
return this.imgBluet
} else {
return this.imgOffnet
}
},
getStatus() {
if (this.batteryDetail.connectNet) {
return "网络正常"
} else if (this.isBlueConnect || app.globalData.isBlueConnect) {
return "蓝牙已连接"
} else {
return "电池离线"
}
},
initIndex(res) {
// console.log('----------------1',res.mapCtx,app.globalData.visitor);
this.mapCtx = res.mapCtx;
this.notLoggedIn(res.latitude, res.longitude)
this.$appData.judge('isBindDevice', this, () => {
this.isBindDevice = app.globalData.isBindDevice
})
if (app.globalData.visitor) return
// 判断是否购买押金
this.queryMyBenefit().then(res => {
//已经购买
}).catch(err => {
//没有购买
})
this.updateMarkers(res.latitude, res.longitude)
},
//获取仪表盘信息
queryDashboardInfo() {
if (app.globalData.visitor) return
app.https({
url: '/cloud-user/user/queryDashboardInfoV2',
}).then(res => {
this.batteryDetail = res;
app.globalData.bid = res.bid;
if (!res.batterySoc || !res.bid) { //batterySoc == 电池电量(单位 %) bid == 电池bid
this.isScooterSocNull = false;
this.percent = 100;
this.isBlueConnect = false;
} else {
this.isScooterSocNull = true;
if (res.bid && !res.connectNet && app.globalData.isBlueConnect) {
this.isBlueConnect = true;
this.percent = app.globalData.batPercent;
} else {
this.percent = res.batterySoc;
app.globalData.batPercent = 0;
app.globalData.isBlueConnect = false;
this.isBlueConnect = false;
}
}
this.initDashboard()
})
},
// 获取颜色
getColor(percent) {
const colorMap = {
high: "#2CCA7B",
middle: "#F99057",
low: "#F76168"
}
let percentStr = percent >= 50 ? "high" : percent >= 50 ? "middle" : "low"
return colorMap[percentStr];
},
// canvas
initDashboard() {
this.$nextTick(() => {
//实例对象
this.cbox2 = new DashboardBox(uni.createCanvasContext('battery_canvas'));
//开始绘制
this.cbox2.radius = uni.upx2px(148);
this.cbox2.lineWidth = uni.upx2px(8);
this.cbox2.padding = uni.upx2px(12);
this.cbox2.percent = this.percent;
this.cbox2.percentLineColor = this.getColor(this.percent);
this.cbox2.drawCircle();
})
},
//扫码换电
scanChange() {
box.scanQRCode().then(pid => {
box.scan(pid, 2).then((res) => {
const totalTime = 3 * 60 * 1000;
const interval = 1000;
box.runIntervalFunctionWithTimeout(totalTime, interval, res.pid, res.rentId, 2);
})
})
},
markerTap(options) {
let that = this;
this.$permission.isVisitor().then(() => {
//判断是否点击同一个柜子
if (this.markerId == options.detail.markerId) return
//点击的新柜子
this.markerId = options.detail.markerId
this.currentBoxInfo = this.original.find(val => {
return val.id == this.markerId
}) // 找到被点击柜子
const origin = `${that.curLongitude},${that.curLatitude}`;
const destination = `${that.currentBoxInfo.longitude},${that.currentBoxInfo.latitude}`;
AMapWx.getRidingPolyline(origin, destination, (points, distance) => {
let distanceExchange = distance < 1000 ? distance + "m" : (distance / 1000)
.toFixed(2) + "km";
that.$set(this.currentBoxInfo, "distance", distanceExchange)
that.curScale = 13;
if (distance <= 10000) {
that.polyline = [{
color: '#54576A',
width: 4,
arrowLine: true,
points
}]
}
})
//柜子ui变化
this.electricShow = true
this.fixUi()
})
},
clickMap(e) { // 点地图
if (this.currentBoxInfo != '') {
this.electricShow = false;
this.curScale = 12;
this.polyline = [];
this.markerId = ""
this.currentBoxInfo = ""
this.markers.forEach(val => {
val.iconPath = val.iconPathBase;
val.width = 40;
val.height = 40;
val.label.anchorY = -36;
val.label.content = val.label.content_before;
})
}
},
regionchange(res) { // 拖动地图,获取周边换电柜
this.latitude = res.latitude
this.longitude = res.longitude
this.updateMarkers(res.latitude, res.longitude);
},
updateMarkers(latitude, longitude) {
if (!latitude && !longitude) {
// this.$util.showConfirm("位置信息获取失败,请先开启定位权限")
return
}
AMapWx.getCity(latitude, longitude, (cityCode) => {
// 参数要求 真实cityCode的前4位后面加2个0
cityCode = cityCode.substring(0, 4) + '00'
cityCode = Number(cityCode)
setAuthorization("cityCode", cityCode);
this.getMarkers(latitude, longitude, cityCode)
})
},
//初始化未登录的时候调佣
notLoggedIn(latitude, longitude){
if (!latitude && !longitude) {
return
}
AMapWx.getCity(latitude, longitude, (cityCode) => {
// 参数要求 真实cityCode的前4位后面加2个0
cityCode = cityCode.substring(0, 4) + '00'
cityCode = Number(cityCode)
setAuthorization("cityCode", cityCode);
})
},
getMarkers(latitude, longitude, cityCode) {
// console.log('--------------------------',latitude,longitude,cityCode);
let token = getAuthorization('token') || ''
if (app.globalData.visitor || !token) return
app.https({
url: `/cloud-user/station/list?bizType=0&type=2&latitude=${latitude}&longitude=${longitude}&cityCode=${cityCode}`,
method: 'GET',
}).then(res => {
let list = res.powerStationList
let markers = []
if (list && list.length > 0) {
list.forEach(val => {
//添加唯一标识id
val.id = val.sn + val.pid + '';
})
// 组装为地图数据
markers = this.handleMarker(list)
// console.log(markers);
this.original = list
this.markers = markers
} else {
this.markers = markers
}
}).catch((err) => {
// this.$util.showWarning('网络未连接')
this.markers = []
})
},
}
}
</script>
<style lang="scss" scoped>
/deep/ .f-container {
height: 100vh;
overflow: hidden;
}
.danger {
color: #F5404E;
}
.index_container {
position: relative;
}
.notice_box {
position: fixed;
bottom: 168rpx;
height: 400rpx;
width: 100%;
z-index: 100;
background-color: orange;
}
.invite_wrap {
position: absolute;
right: 24rpx;
top: 740rpx;
.invite_img {
width: 100rpx;
height: 100rpx;
}
}
.operate_wrap {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
position: absolute;
top: 904rpx;
right: 32rpx;
background: transparent;
.icon-wrap {
width: 80rpx;
height: 80rpx;
background-color: #fff;
border-radius: 16rpx;
display: flex;
justify-content: center;
align-items: center;
image {
display: inline-block;
width: 40rpx;
height: 40rpx;
}
}
}
.s_battery_container {
position: relative;
min-width: 362rpx;
min-height: 148rpx;
background: rgba(255, 255, 255, 0.85);
;
border-radius: 16rpx;
box-shadow: 0rpx 2rpx 12rpx 0rpx rgba(0, 0, 0, 0.08);
position: fixed;
left: 14rpx;
top: 192rpx;
z-index: 200;
.tips_box {
padding: 0rpx 16rpx 16rpx 16rpx;
}
.tips {
font-size: 24rpx;
font-family: HarmonyOS_Sans_Regular;
font-weight: 400;
color: #F5404E;
}
}
.s-battery {
width: 100%;
height: 148rpx;
display: flex;
.s_canvas {
width: 148rpx;
height: 148rpx;
position: relative;
}
.battery_canvas {
width: 100%;
height: 100%;
}
.s-state-box {
display: flex;
flex-direction: column;
justify-content: space-around;
padding: 14rpx 16rpx 14rpx 0;
}
.battery_net {
width: 32rpx;
height: 32rpx;
margin-right: 10rpx;
}
.battery_line {
width: 112rpx;
height: 44rpx;
border: 1px solid $f-text-word-color;
text-align: center;
font-size: 20rpx;
font-weight: 400;
color: $f-text-word-color;
line-height: 38rpx;
border-radius: 36rpx;
margin-left: 12rpx;
}
.battery_tips {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
font-weight: 400;
color: #474747;
text-align: center;
line-height: 28rpx;
font-size: 20rpx;
}
.percent {
font-weight: 500;
line-height: 48rpx;
font-size: 32rpx;
}
.state_box {
height: 32rpx;
display: flex;
align-items: center;
}
.battery_state {
font-size: 24rpx;
font-family: HarmonyOS_Sans_Regular;
font-weight: 400;
}
}
</style>
<template> <view class="s-map" :style="{height:mapHeight+'rpx'}"> <!-- #ifdef MP-WEIXIN --> <map ref="map" class="eMap" id='eMap' :longitude='longitude' latitude='latitude' :scale='scale' :controls='controls' :markers='markers' :polyline="polyline" @click='clickMap' @controltap='controlTap' @markertap='markerTap' @labeltap="labeltap" @regionchange='regionchange'@updated='mapUpdated' :show-location='true'>
</map>
<!-- #endif -->
<!-- #ifdef MP-ALIPAY -->
<map ref="map" class="eMap" id='eMap' :longitude='longitude' latitude='latitude' :scale='mapScale' :controls='controls' :markers='markers' :polyline="polyline" @click='clickMap' @controltap='controlTap' @markertap='markerTap' @labeltap="labeltap" @regionchange='regionchange'
@updated='mapUpdated' :show-location='true'>
</map>
<!-- #endif -->
<cover-view class="cover-anno" :style="{'left':annoLeft,'top':annoTop}" v-if="!isShowView">
<cover-image class="anno-image" :src="map_location_anno"></cover-image>
</cover-view>
</view>
</template>
<script>
let app = getApp()
import locationutil from '@/utils/locationUtil.js'
export default {
name: "s-map",
props: {
markers: {
type: Array,
default: []
},
controls: {
type: Array,
default: []
},
scale: {
type: Number,
default: 12
},
polyline: {
type: Array,
default: [{
color: '#54576A',
width: 4,
arrowLine: true,
points: []
}], // 路径
},
isShowView:{
type: Boolean,
default: false
},
mapHeight:{
type: Number,
default: 0
}
},
computed: {
mapScale: {
get () {
return this.scale;
},
set (value) {
this.$emit('changeScale', value);
}
}
},
data() {
return {
longitude: '',
latitude: '',
annoTop:"",
annoLeft:"",
mapCtx: null,
markerTapFlag: false,
map_location_anno: this.$imgBaseUrl+"map_location_anno.png",
};
},
mounted() {
//默认地图页面铺满全屏 计算高度 兼容自定义头部和底部
this.mapCtx = uni.createMapContext('eMap', this) // 创建地图对象
this.init().then(res=>{
res.mapCtx = this.mapCtx;
this.$emit("initIndex",res)
})
this.$nextTick(() => {
this.annoTop = (this.$util.pxToRpx(app.globalData.windowHeight-44-50)/2)+"rpx";
this.annoLeft = (this.$util.pxToRpx(app.globalData.windowWidth/2))+"rpx";
})
},
methods: {
init() {
let that = this
return new Promise(resolve => {
//获取定位授权
locationutil.updateLocation().then(res => {
//更新定位
that.longitude = res.longitude;
that.latitude = res.latitude;
resolve(res)
})
})
},
clickMap(e) {
//延时是为了保证 marker点击事件在地图点击事件前面触发
setTimeout(() => {
if (!this.markerTapFlag) {
this.$emit('clickMap', e)
}
}, 0)
},
controlTap(e) {
this.$emit('controlTap', e)
},
labeltap(e) {
this.markerTapFlag = true
let timeOut = setTimeout(() => {
this.markerTapFlag = false
clearTimeout(timeOut)
}, 300)
this.$emit('markerTap', e)
},
markerTap(e) {
this.markerTapFlag = true
let timeOut = setTimeout(() => {
this.markerTapFlag = false
clearTimeout(timeOut)
}, 300)
this.$emit('markerTap', e)
},
regionchange(e) {
let judge = false;
// #ifdef MP-ALIPAY
judge = (e.type === 'end'&&e.causedBy==='drag');
if(e.causedBy==='scale') {
// console.log('111111111',e,e.scale);
this.mapScale = e.scale;
}
if (e.type === 'end'&&e.causedBy==='drag') {
this.longitude = e.longitude;
this.latitude = e.latitude;
}
// #endif
// #ifdef MP-WEIXIN
judge = (e.type === 'end'&&e.mp.causedBy==='drag');
// #endif
if (judge) {
this.mapCtx.getCenterLocation({
success: (res) => {
this.$emit('regionchange', res)
}
})
}
},
// #ifdef MP-ALIPAY
toJSON(){
return this
},
// #endif
mapUpdated(e) {
this.$emit('mapUpdated', e)
},
}
}
</script>
<style lang="scss" scoped>
.s-map {
// height: 100vh;
.eMap {
width: 100vw;
// height: calc(100vh - 264rpx );
height: 100%;
}
.cover-anno{
width:64rpx;
height: 64rpx;
position: absolute;
margin-left: -34rpx;
margin-top: -60rpx;
background: transparent;
}
.anno-image {
width: 64rpx;
height: 64rpx;
}
}
</style>
2***@qq.com (作者)
还有地图手指滑动/拖动会报错,然后回到最初缩放形状
2024-08-21 16:16