iot-ui-app/pages/iots/map/device-map.nvue

559 lines
13 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<view class="map-box">
<map
id="maps"
ref="maps"
:style="{'width': width,'height': height}"
:longitude="mapLocation.longitude"
:latitude="mapLocation.latitude"
show-location="false"
:include-points="includePoints"
:markers="mapMarkers"
:polyline="mapPolyline"
:polygons="mapPolygons"
:scale="scale"
:enable-scroll="true"
@markertap="pointClick"
@tap="mapClick"
@regionchange="getRegion"
>
</map>
<view class="search-box">
<view class="search-content">
<input class="search-content-input" type="text" placeholder="搜索设备名称/ID" v-model="searchVal" @input="getDeviceDataList(true)">
<button class="search-content-btn" @click="getDeviceDataList(true)"><text class="search-content-btn-txt">搜索</text></button>
</view>
<scroll-view class="search-list" scroll-y="true" v-if="isShowSearchList">
<view class="search-item" :class="activeId==item.id?'active':''" v-for="(item,index) in deviceList" :key="item.id" @click="selectDevice(item,index)">
<!-- <view class="item-img"> -->
<image class="item-img" :src="item.devImage ? imgPath + item.devImage : deviceDefaultPath"></image>
<!-- </view> -->
<view class="item-content">
<text class="item-title">
{{item.devName}}
</text>
<text class="item-info">
{{item.devId}}
</text>
</view>
</view>
<view class="empty-box" v-if="deviceList.length == 0 && showEmpy">
<image class="empty-box-img" :src="deviceDefaultPath"></image>
<text class="empty-box-txt">暂无设备</text>
</view>
</scroll-view>
</view>
<scroll-view class="info-box" v-if="isModel" scroll-y="true" :style="{height:deviceInfoList.length>7?'600rpx':'auto'}">
<view class="info-box-header">
<!-- <view class="iconfont icon-plus" @click="isModel=false"></view> -->
<text class="icon-close" @click="isModel=false">×</text>
</view>
<view class="info-box-content">
<!-- <view class="info-img"> -->
<image class="info-img" :src="deviceInfo.devImage ? imgPath + deviceInfo.devImage : deviceDefaultPath" mode=""></image>
<!-- </view> -->
<view class="info-list">
<view class="info-item">
<text class="item-label">
设备名:
</text>
<text class="item-value">
{{deviceInfo.devName}}
</text>
</view>
<view class="info-item">
<text class="item-label">
在线状态:
</text>
<text class="item-value" :style="{color:deviceInfo.devState==1?'#10CC70':deviceInfo.devState==2?'#FF2B38':'#999999'}">
{{deviceInfo.devState==1?'在线':deviceInfo.devState==2?'离线':'未激活'}}
</text>
</view>
<view class="info-item">
<text class="item-label">
设备ID
</text>
<text class="item-value">
{{deviceInfo.devId}}
</text>
</view>
<view class="info-item">
<text class="item-label">
上线时间:
</text>
<text class="item-value">
{{deviceInfo.lastOnlineTime}}
</text>
</view>
<view class="info-item">
<text class="item-label">
PK
</text>
<text class="item-value">
{{deviceInfo.pk}}
</text>
</view>
</view>
</view>
<button class="info-box-btn" @click="goDeviceDetail"><text class="info-box-btn-txt">查看设备详情</text></button>
</scroll-view>
</view>
</template>
<script>
import { numAdd,numSub } from '@/common/js/util/js-calculate.js'
import request from '@/network/request.js'
export default {
data() {
return {
mapCtx:null,
mapLocation:{
longitude:119.216327,
latitude:26.028788
},
scale:12,
includePoints:[],
height:'500px',
width:'100%',
mapMarkers:[],
mapPolyline:[],
mapPolygons:[],
isModel:false,
deviceInfoList:[
{
label:'设备id',
value:'00000000000001'
},
{
label:'设备名称',
value:'换电柜001'
},
{
label:'设备状态',
value:'在线'
},
{
label:'仓门数量',
value:'5'
},
{
label:'电池数量',
value:'4'
}
],
pointData:[],
isShowSearchList:false,
showEmpy:false,
searchVal:'',
imgPath:'',
activeIndex:-1,
activeId:0,
deviceList:[],
deviceInfo:{
devImage:null,
devName:null,
devState:0,
devId:null,
lastOnlineTime:null,
pk:null,
},
mapRange:{
latMax:0,
latMin:0,
lngMax:0,
lngMin:0,
},
deviceDefaultPath:'/static/app-plus/image/device/device-default.png'
};
},
onReady() {
if (!this.mapCtx) {
this.mapCtx = uni.createMapContext("maps",this); // map 组件绑定,操作对应的 map 组件
}
// this.deviceDefaultPath = this.$staticPath+'/image/device/device-default.png';
this.getRegion();
},
onLoad(option) {
this.getConfigPath();
this.getSystemInfo();
// this.getDeviceDataList();
},
methods:{
// 获取系统信息
getSystemInfo() {
uni.getSystemInfo({
success: (res) => {
console.log("获取到系统信息", res)
let height = (res.windowHeight ) + 'px'
this.$set(this, "height", height)
this.$set(this, "width", res.windowWidth)
}
})
},
selectDevice(data,index){
this.activeIndex = index;
this.activeId = data.id;
this.deviceInfo = data;
this.mapLocation.longitude = data.lng;
this.mapLocation.latitude = data.lat;
this.isShowSearchList = false;
this.isModel = true;
},
getConfigPath(){
let configList = uni.getStorageSync('configList');
let configIndex = uni.getStorageSync('configIndex');
this.imgPath = configList[configIndex].protocol + configList[configIndex].address;
},
getDeviceDataList(flag){
let params = {
"page": 1,
"pageSize": 99999,
"Wheres": {
"wheres": [
{"field": "locateState","operator": "=","value": 1},
{"field": "lng","operator": ">=","value": this.mapRange.lngMin},
{"field": "lng","operator": "<=","value": this.mapRange.lngMax},
{"field": "lat","operator": ">=","value": this.mapRange.latMin},
{"field": "lat","operator": "<=","value": this.mapRange.latMax},
// {"field": "prodType","operator": "=","value": this.deviceType},
// {"field":"devState","operator":"=","value":this.tabsList[this.tabIndex].value},
{"fields": ["devId","devName"],"operator": "keyword","value": this.searchVal}
]
},
}
request.TokenRequest({
url: '/iot/admin/device/list',
method: 'POST',
},params)
.then((res) =>{
console.log("获取设备列表",res)
// res.data.list = null;
if(res.code === 0){
this.deviceList = res.data.list ? res.data.list : [];
if(res.data.list){
this.getPointData()
}
if(flag){
this.isShowSearchList = true;
this.showEmpy = res.data.list ? false : true;
}
}else{
this.deviceList = [];
if(flag){
this.isShowSearchList = true;
this.showEmpy = true;
}
}
}).catch(err =>{
})
},
getRegion() {
this.mapCtx.getRegion({
success: res => {
let obj = {
"latMax": res.northeast.latitude.toString(),
"latMin": res.southwest.latitude.toString(),
"lngMax": res.northeast.longitude.toString(),
"lngMin": res.southwest.longitude.toString(),
}
this.mapRange = obj;
this.getDeviceDataList(false);
},
fail: (data, code) => {
console.log('fail' + JSON.stringify(data));
}
})
},
getPointData(){
let includePoints = [];
let points = this.deviceList.map((item,index)=>{
includePoints.push({
longitude:item.lng,
latitude:item.lat,
})
// this.pointData.push({
// index:index,
// id:item.id,
// infoData:item.infoData,
// longitude:item.lng,
// latitude:item.lat,
// })
let x = 0;
if(uni.getSystemInfoSync().platform=='android'){
x = - item.devName.length*5;
}else{
x = - item.devName.length*8;
}
return {
// id:item.id,
id:index,
longitude:item.lng,
latitude:item.lat,
title:item.devName,
label:{
content:item.devName,
textAlign:'center',
color:'#2e66e7',
anchorX:x,
textAlign:'left'
},
// iconPath: '/static/image/device/location-blue.png',
iconPath: item.devImage ? this.imgPath + item.devImage : this.deviceDefaultPath,
width:24,
height:24,
}
});
this.$nextTick(()=>{
this.$set(this,'mapMarkers',points);
this.$forceUpdate()//手动刷新页面数据
})
// this.includePoints = this.getPaddingPoints(includePoints);
// this.mapCtx.includePoints({
// padding: [20,20,20,20],
// points: this.getPaddingPoints(includePoints)
// })
},
// 经纬度向四周移动0.0001约为10米防止边缘点位被覆盖
getPaddingPoints(points){
points = JSON.parse(JSON.stringify(points))
let minLatIndex = 0;
let maxLatIndex = 0;
let minLngIndex = 0;
let maxLngIndex = 0;
points.forEach((item,index)=>{
if(index !== 0){
if(points[minLatIndex].latitude > item.latitude){
minLatIndex = index;
}
if(points[maxLatIndex].latitude < item.latitude){
maxLatIndex = index;
}
if(points[minLngIndex].longitude > item.longitude){
minLngIndex = index;
}
if(points[maxLngIndex].longitude < item.longitude){
maxLngIndex = index;
}
}
})
points[minLatIndex].latitude = numSub(points[minLatIndex].latitude,0.0050);
points[maxLatIndex].latitude = numAdd(points[maxLatIndex].latitude,0.0050);
points[minLngIndex].longitude = numSub(points[minLngIndex].longitude,0.0050);
points[maxLngIndex].longitude = numAdd(points[maxLngIndex].longitude,0.0050);
return points;
},
pointClick(e){
console.log("当前点击点",e)
this.activeIndex = e.detail.markerId;
this.deviceInfo = this.deviceList[e.detail.markerId];
this.activeId = this.deviceList[e.detail.markerId].id;
this.mapLocation.longitude = this.deviceList[e.detail.markerId].lng;
this.mapLocation.latitude = this.deviceList[e.detail.markerId].lat;
this.isModel = true;
},
mapClick(e){
console.log("当前点击地图",e)
this.isModel = false;
},
goDeviceDetail(){
uni.navigateTo({
url:'/pages/iots/device/device-detail?id=' + this.deviceInfo.id + '&devName=' + this.deviceInfo.devName
})
}
}
}
</script>
<style lang="scss" scoped>
// .map-box,#maps{
// width: 100%;
// height: 100%;
// }
.search-box {
position: fixed;
top: 20rpx;
left: 20rpx;
right: 20rpx;
z-index: 999;
}
.search-content {
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
background: #fff;
border-radius: 10rpx;
}
.search-content-input{
flex: 1;
padding-left: 20rpx;
height: 80rpx;
line-height: 80rpx;
}
.search-content-btn{
height: 80rpx;
line-height: 80rpx;
margin: 0;
background: #0960ff;
border: 1px solid #0960ff;
border-top-left-radius: 0;
border-bottom-left-radius: 0;
}
.search-content-btn-txt{
color: #fff;
}
.search-list {
margin-top: 10rpx;
// max-height: 450rpx;
height: 450rpx;
background: #fff;
border-radius: 10rpx;
overflow: hidden;
}
.search-item {
display: flex;
flex-direction: row;
align-items: center;
padding: 10rpx 20rpx;
border-bottom: 1px solid #f0f0f0;
}
.search-item:last-child {
border-bottom: 1px solid transparent;
}
.active {
background: #e2edff;
}
.item-img {
width: 80rpx;
height: 80rpx;
margin-right: 20rpx;
}
.item-title {
font-weight: bold;
}
.item-info {
margin-top: 5rpx;
font-size: 24rpx;
color: #666;
}
.empty-box {
padding: 50rpx 30rpx;
display: flex;
flex-direction: column;
align-items: center;
}
.empty-box-img {
width: 80rpx;
height: 80rpx;
}
.empty-box-txt {
margin-top: 10rpx;
color: #666;
}
.info-box {
position: fixed;
bottom: 20rpx;
left: 20rpx;
right: 20rpx;
z-index: 999;
background: #fff;
border-radius: 10rpx;
padding: 20rpx;
padding-top: 0;
box-shadow: 0px 0px 10px 0px rgba(192, 192, 192, 0.5);
// max-height: 750rpx;
height: 750rpx;
overflow: hidden;
}
.info-box-header {
position: relative;
height: 60rpx;
}
// .icon-plus {
// position: absolute;
// top: -10rpx;
// right: -10rpx;
// font-size: 40rpx;
// transform: rotate(45deg);
// font-weight: bold;
// }
.icon-close{
position: absolute;
top: 0rpx;
right: 0rpx;
font-size: 50rpx;
line-height: 60rpx;
// transform: rotate(45deg);
font-weight: bold;
}
.info-box-content {
display: flex;
flex-direction: row;
align-items: center;
}
.info-img {
width: 170rpx;
height: 170rpx;
margin-right: 20rpx;
}
.info-list {
flex: 1;
}
.info-item {
display: flex;
align-items: center;
flex-direction: row;
justify-content: space-between;
}
.item-label{
font-size: 28rpx;
}
.item-value {
font-size: 28rpx;
font-weight: bold;
}
.info-box-btn {
margin-top: 10rpx;
background: #0960ff;
border-radius: 8rpx;
height: 80rpx;
line-height: 80rpx;
}
.info-box-btn-txt{
color: #fff;
font-size: 36rpx;
}
</style>