jsy-app/pages/index-map.vue
2025-01-16 17:25:51 +08:00

1931 lines
52 KiB
Vue
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>
<!-- 顶部导航栏 -->
<custom-nav-bar :left="false" leftText="" @leftClick="" :title="title || '田间'">
<template v-slot:left>
<view @click="$refs.landRef.open()">地块</view>
</template>
</custom-nav-bar>
<!-- 地图 -->
<view id="map" class="map" :data="mapObj.initData" :change:data="leaflet.initEmitHandler" :mapType="mapObj.mapType"
:change:mapType="leaflet.switchLayerEmitHandler" :centerPoint="mapObj.centerPoint"
:change:centerPoint="leaflet.centerPointEmitHandler" :landMap="mapObj.landMap"
:change:landMap="leaflet.drawEmitHandler" :davice="mapObj.davice" :change:davice="leaflet.markerEmitHandler"
:updateMarker="mapObj.updateMarker" :change:updateMarker="leaflet.updateMarkerEmitHandler"
:ranging="mapObj.ranging" :change:ranging="leaflet.rangingEmitHandler">
</view>
<!-- 工具 -->
<view class="below">
<view @click="mapObj.showMapType = true">
<i class="iconfont icon-tuceng">
<span></span>
</i>
</view>
<view @click="mapToCenterPoint">
<i class="iconfont icon-dingwei"></i>
</view>
<view @click="mapNavigation">
<i class="iconfont icon-luxian"></i>
</view>
<view @click="mapRanging" :style="mapObj.ranging ? 'background: deepskyblue;':''">
<i class="iconfont icon-ceju"></i>
</view>
</view>
<view class="tdt">
<image src="../static/images/map/logo.png"></image>GS20240568 - 甲测资字1100471
</view>
<!-- 图层弹出 -->
<u-popup type="center" :show="mapObj.showMapType" @close="mapObj.showMapType = false">
<view class="popup-content">
<view class="layer">
<view class="title" @click="mapObj.showMapType = false">
<span>图层</span>
<view>
<i class="iconfont icon-guanbi"></i>
</view>
</view>
<view class="card">
<view class="layer-item" :class="[mapObj.mapType == 'vec_w'? 'click':'']">
<view class="img" @click="mapSwitchLayer('vec_w')">
<image src="../static/images/map/dt.jpg"></image>
</view>
标准地图
</view>
<view class="layer-item" :class="[mapObj.mapType == 'ter_w'? 'click':'']">
<view class="img" @click="mapSwitchLayer('ter_w')">
<image src="../static/images/map/dx.jpg"></image>
</view>
地形图
</view>
<view class="layer-item" :class="[mapObj.mapType == 'img_w'? 'click':'']">
<view class="img" @click="mapSwitchLayer('img_w')">
<image src="../static/images/map/wx.jpg"></image>
</view>
卫星图
</view>
</view>
</view>
</view>
</u-popup>
<!-- 控制弹出 -->
<u-popup mode="bottom" :show="pop.show" @close="closePopup">
<view class="popup-content" v-if="pop.show">
<view class="card-grey">
<view class="gb" @click="closePopup">
<i class="iconfont icon-guanbi"></i>
</view>
<view class="card-title">
<u-row v-if="pop.item.type == 'jz'">
<u-col span="4">
<view @click="openDialog('adc', pop.item)">
<text class="font-green">●</text>{{pop.item.showName}}
</view>
</u-col>
<u-col span="4">
<view class="fixed">
<custom-signal :online="dc.dataObj[pop.item.dataKey]?.online"
:isp="dc.dataObj[pop.item.dataKey]?.isp"
:value="dc.dataObj[pop.item.dataKey]?.rssi" />
<custom-battery :online="dc.dataObj[pop.item.dataKey]?.online"
:charging="dc.dataObj[pop.item.dataKey]?.charging"
:value="dc.dataObj[pop.item.dataKey]?.b" />
</view>
</u-col>
<u-col span="4" style="align-items: flex-end;">
<view class="fixed">
<u-button type="success" size="mini" text="刷新" icon="reload"
:loading="dc.dataObj[pop.item.dataKey]?.refresh"
@click="dc.refreshDeviceItem(pop.item.dataKey, pop.item.device)" />
</view>
</u-col>
</u-row>
<u-row v-else>
<u-col span="2">
<view @click="openDialog('adc', pop.item)">
<text class="font-green">●</text>{{pop.item.showName}}
</view>
</u-col>
<u-col span="5">
<view class="fixed">
<custom-signal :online="dc.dataObj[pop.item.dataKey]?.online"
:value="dc.dataObj[pop.item.dataKey]?.comm.rssi"
v-if="dc.dataObj[pop.item.dataKey]?.comm.type == '4g'" />
<custom-battery :online="dc.dataObj[pop.item.dataKey]?.online"
:charging="dc.dataObj[pop.item.dataKey]?.adc.charging"
:value="dc.dataObj[pop.item.dataKey]?.adc.b" />
<view>
<view class="iconfont icon-wendu icon" style="float: left;margin-left: 5px;" />
{{ dc.dataObj[pop.item.dataKey]?.adc.t}}
</view>
</view>
</u-col>
<u-col span="5" style="align-items: flex-end;">
<view class="fixed">
<u-button type="success" size="mini" text="刷新" icon="reload"
:loading="dc.dataObj[pop.item.dataKey]?.refresh"
@click="dc.refreshDeviceItem(pop.item.dataKey, pop.item.device)" />
</view>
</u-col>
</u-row>
</view>
<view class="control" v-if="dc.dataObj[pop.item.dataKey]">
<u-row v-if="pop.item.device.deviceTypeKey == 'station'">
<image :src="valveImg.jz" mode="widthFix" />
</u-row>
<u-row v-else-if="pop.item.device.deviceTypeKey == 'valve'">
<u-col span="3">
<u-button :disabled="pop.item.device.disable?.open1"
:type="dc.getBtnType(pop.item.dataKey, 'open1')"
:plain="dc.dataObj[pop.item.dataKey].btnObj.open1.work"
@click="dc.deviceControlHandle(pop.item, 1)"> ①
<span v-if="dc.dataObj[pop.item.dataKey].btnObj.open1.work">
<span v-if="dc.countdownObj[pop.item.dataKey]">
({{ dc.countdownObj[pop.item.dataKey] }})
</span>
<span v-else class="timeout">
{{ dc.timeoutObj[pop.item.dataKey] }}
</span>
</span>
<span class="name"
v-if="pop.item.device.disable.show && !pop.item.device.disable.open1">
{{user.userName}}
</span>
</u-button>
<u-line-progress height="8" :showText="false"
:percentage="dc.dataObj[pop.item.dataKey].btnObj.open1.openAngle" activeColor="#74ffd4"
inactiveColor="#c7c7c7" />
</u-col>
<u-col span="6">
<view class="valve">
<view>
<u-button :disabled="pop.item.device.disable?.open"
:type="dc.getBtnType(pop.item.dataKey, 'open')"
:plain="dc.dataObj[pop.item.dataKey].btnObj.open.work"
@click="dc.deviceControlHandle(pop.item, 3)"> 全开
<span v-if="dc.dataObj[pop.item.dataKey].btnObj.open.work">
<span v-if="dc.countdownObj[pop.item.dataKey]">
({{ dc.countdownObj[pop.item.dataKey] }})
</span>
<span v-else class="timeout">
{{ dc.timeoutObj[pop.item.dataKey] }}
</span>
</span>
<span class="name"
v-if="pop.item.device.disable.show && !pop.item.device.disable.open">
{{user.userName}}
</span>
</u-button>
</view>
<view class="btn-img">
<view class="text">
<view class="left">
{{ dc.dataObj[pop.item.dataKey].adc.p[0] }}
</view>
<view class="top"></view>
<view class="middle" v-show="!dc.dataObj[pop.item.dataKey].online">
离线
</view>
<view class="right">
{{ dc.dataObj[pop.item.dataKey].adc.p[1] }}
</view>
<view class="bottom"></view>
</view>
<image :src="valveImg[dc.dataObj[pop.item.dataKey].valveImg]" mode="widthFix" />
</view>
<view>
<u-button :disabled="pop.item.device.disable?.close"
:type="dc.getBtnType(pop.item.dataKey, 'close')"
:plain="dc.dataObj[pop.item.dataKey].btnObj.close.work"
@click="dc.deviceControlHandle(pop.item, 4)"> 全关
<span v-if="dc.dataObj[pop.item.dataKey].btnObj.close.work">
<span v-if="dc.countdownObj[pop.item.dataKey]">
({{ dc.countdownObj[pop.item.dataKey] }})
</span>
<span v-else class="timeout">
{{ dc.timeoutObj[pop.item.dataKey] }}
</span>
</span>
<span class="name"
v-if="pop.item.device.disable.show && !pop.item.device.disable.close">
{{user.userName}}
</span>
</u-button>
</view>
</view>
</u-col>
<u-col span="3">
<u-button :disabled="pop.item.device.disable?.open2"
:type="dc.getBtnType(pop.item.dataKey, 'open2')"
:plain="dc.dataObj[pop.item.dataKey].btnObj.open2.work"
@click="dc.deviceControlHandle(pop.item, 2)"> ②
<span v-if="dc.dataObj[pop.item.dataKey].btnObj.open2.work">
<span v-if="dc.countdownObj[pop.item.dataKey]">
({{ dc.countdownObj[pop.item.dataKey] }})
</span>
<span v-else class="timeout">
{{ dc.timeoutObj[pop.item.dataKey] }}
</span>
</span>
<span class="name"
v-if="pop.item.device.disable.show && !pop.item.device.disable.open2">
{{user.userName}}
</span>
</u-button>
<u-line-progress height="8" :showText="false"
:percentage="dc.dataObj[pop.item.dataKey].btnObj.open2.openAngle" activeColor="#74ffd4"
inactiveColor="#c7c7c7" />
</u-col>
</u-row>
<u-row v-else-if="pop.item.device.deviceTypeKey == 'fiveValve'">
<u-col span="3">
<u-button :disabled="pop.item.device.disable?.open1"
:type="dc.getBtnType(pop.item.dataKey, 'open1')"
:plain="dc.dataObj[pop.item.dataKey].btnObj.open1.work"
@click="dc.deviceControlHandle(pop.item, 1)"> ①
<span v-if="dc.dataObj[pop.item.dataKey].btnObj.open1.work">
<span v-if="dc.countdownObj[`${pop.item.dataKey}_open1`]">
({{ dc.countdownObj[`${pop.item.dataKey}_open1`] }})
</span>
<span v-else class="timeout">
{{ dc.timeoutObj[`${pop.item.dataKey}_open1`] }}
</span>
</span>
<span class="name"
v-if="pop.item.device.disable.show && !pop.item.device.disable.open1">
{{user.userName}}
</span>
</u-button>
<u-line-progress height="8" :showText="false"
:percentage="dc.dataObj[pop.item.dataKey].btnObj.open1.openAngle" activeColor="#74ffd4"
inactiveColor="#c7c7c7" />
</u-col>
<u-col span="6">
<view class="valve">
<view>
<u-button :disabled="pop.item.device.disable?.open2"
:type="dc.getBtnType(pop.item.dataKey, 'open2')"
:plain="dc.dataObj[pop.item.dataKey].btnObj.open2.work"
@click="dc.deviceControlHandle(pop.item, 2)"> ②
<span v-if="dc.dataObj[pop.item.dataKey].btnObj.open2.work">
<span v-if="dc.countdownObj[`${pop.item.dataKey}_open2`]">
({{ dc.countdownObj[`${pop.item.dataKey}_open2`] }})
</span>
<span v-else class="timeout">
{{ dc.timeoutObj[`${pop.item.dataKey}_open2`] }}
</span>
</span>
<span class="name"
v-if="pop.item.device.disable.show && !pop.item.device.disable.open2">
{{user.userName}}
</span>
</u-button>
<u-line-progress height="8" :showText="false"
:percentage="dc.dataObj[pop.item.dataKey].btnObj.open2.openAngle"
activeColor="#74ffd4" inactiveColor="#c7c7c7" />
</view>
<view class="btn-img">
<view class="text5">
<view class="left">
{{ dc.dataObj[pop.item.dataKey].adc.p[0] }}
</view>
<view class="top">
{{ dc.dataObj[pop.item.dataKey].adc.p[1] }}
</view>
<view class="middle" v-show="!dc.dataObj[pop.item.dataKey].online">
离线
</view>
<view class="right">
{{ dc.dataObj[pop.item.dataKey].adc.p[2] }}
</view>
<view class="bottom">
{{ dc.dataObj[pop.item.dataKey].adc.p[3] }}
</view>
</view>
<image :src="valveImg[dc.dataObj[pop.item.dataKey].valveImg]" mode="widthFix" />
</view>
<view>
<u-button :disabled="pop.item.device.disable?.open4"
:type="dc.getBtnType(pop.item.dataKey, 'open4')"
:plain="dc.dataObj[pop.item.dataKey].btnObj.open4.work"
@click="dc.deviceControlHandle(pop.item, 4)"> ④
<span v-if="dc.dataObj[pop.item.dataKey].btnObj.open4.work">
<span v-if="dc.countdownObj[`${pop.item.dataKey}_open4`]">
({{ dc.countdownObj[`${pop.item.dataKey}_open4`] }})
</span>
<span v-else class="timeout">
{{ dc.timeoutObj[`${pop.item.dataKey}_open4`] }}
</span>
</span>
<span class="name"
v-if="pop.item.device.disable.show && !pop.item.device.disable.open4">
{{user.userName}}
</span>
</u-button>
<u-line-progress height="8" :showText="false"
:percentage="dc.dataObj[pop.item.dataKey].btnObj.open4.openAngle"
activeColor="#74ffd4" inactiveColor="#c7c7c7" />
</view>
</view>
</u-col>
<u-col span="3">
<u-button :disabled="pop.item.device.disable?.open3"
:type="dc.getBtnType(pop.item.dataKey, 'open3')"
:plain="dc.dataObj[pop.item.dataKey].btnObj.open3.work"
@click="dc.deviceControlHandle(pop.item, 3)"> ③
<span v-if="dc.dataObj[pop.item.dataKey].btnObj.open3.work">
<span v-if="dc.countdownObj[`${pop.item.dataKey}_open3`]">
({{ dc.countdownObj[`${pop.item.dataKey}_open3`] }})
</span>
<span v-else class="timeout">
{{ dc.timeoutObj[`${pop.item.dataKey}_open3`] }}
</span>
</span>
<span class="name"
v-if="pop.item.device.disable.show && !pop.item.device.disable.open3">
{{user.userName}}
</span>
</u-button>
<u-line-progress height="8" :showText="false"
:percentage="dc.dataObj[pop.item.dataKey].btnObj.open3.openAngle" activeColor="#74ffd4"
inactiveColor="#c7c7c7" />
</u-col>
</u-row>
<u-row v-else>
未知的设备
</u-row>
<view class="tips font-red"
v-if="dc.dataObj[pop.item.dataKey].warning && dc.dataObj[pop.item.dataKey].warning.length">
<view class="iconfont icon-guzhang icon">
{{ dc.dataObj[pop.item.dataKey].warning.toString() }}
</view>
</view>
</view>
<!-- 无数据上报 -->
<view class="control" v-else>
<u-row
v-if="pop.item.device.deviceTypeKey == 'valve' || pop.item.device.deviceTypeKey == 'fiveValve'">
<u-col span="3"></u-col>
<u-col span="6">
<view class="valve">
<view class="btn-img">
<view class="text">
<view class="middle" style="width: 100%;">
无数据上报
</view>
</view>
<image mode="widthFix" v-if="pop.item.device.deviceTypeKey == 'valve'"
:src="valveImg['valve3_close']" />
<image mode="widthFix" v-if="pop.item.device.deviceTypeKey == 'fiveValve'"
:src="valveImg['valve5_0000']" />
</view>
</view>
</u-col>
<u-col span="3"></u-col>
</u-row>
<u-row v-else>
未知的设备
</u-row>
</view>
<view v-if="pop.item.type != 'jz'">
<view class="expand5" @click="pop.showbox = !pop.showbox">
<view class="icon">
<view class="iconfont icon-jt-b"></view>
</view>
</view>
<view class="box" :class="[pop.showbox ? 'show':'hide']">
<view class="card">
<view class="title fixed">
<view class="text" style="min-width: 25px;">
水压趋势kPa
</view>
<view>更多<span class="iconfont icon-you"></span></view>
</view>
<view class="tip">设备仅采集已打开的出水口水压</view>
<view class="pressure">
<view>①口</view>
<view>
<view>放图表</view>
<span>近2小时暂无水压变化</span>
</view>
</view>
<view class="pressure">
<view>①口</view>
<view>
<view>放图表</view>
</view>
</view>
</view>
<view class="card" style="overflow: hidden;">
<view class="title fixed">
<view class="text" style="min-width: 25px;">
最近操作
</view>
<view @click="operationLog(pop.item)">
更多<span class="iconfont icon-you"></span>
</view>
</view>
<view class="text-list" v-if="dc.dataObj[pop.item.dataKey]"
v-for="item in dc.dataObj[pop.item.dataKey].latestOperation">
<view>
<view>
{{`${item.valveOutletNo}口,${item.operContent}`}}
</view>
<view class="font-green">
{{item.operResult ? '【成功】' : '【失败】'}}
</view>
</view>
<view>
<view>操作人:{{item.userName}}</view>
<view>{{formatData(item.time)}}</view>
</view>
</view>
</view>
</view>
</view>
</view>
</view>
</u-popup>
<!-- 地块选择 -->
<custom-select-land ref="landRef" :data="ijs.companys" :defaultSelect="ijs.land" @getLand="getLand" @select="" />
<!-- 角度 -->
<custom-angle-slider ref="refAngleSlider" mode="bottom" @close="openPopup" @confirm="swiperConfirm" />
<!-- ADC -->
<custom-index-adc ref="adcRef" @close="openPopup" />
<!-- 墒情 -->
<custom-index-mp ref="mpRef" />
</template>
<script>
import config from '@/config.js'
const appInfo = config.appInfo;
import store from "@/store"
import {
timestampFormat
} from '@/utils/common.js'
import * as imageAssets from '@/utils/indexUtil/imageAssets.js'
import {
getHeadDevice
} from "@/api/controlHeadInterface.js"
import {
getOtherDevice
} from "@/api/system/controlOtherInterface"
export default {
data() {
return {
user: store.state.user.user,
title: null,
ijs: getApp().ijs, // 首页公共js
dc: getApp().dc, // 设备控制公共代码
valveImg: imageAssets, //阀门图片
mqttshow: false, // h5端手动链接mqtt按钮显示
mqttConnected: false, // mqtt链接状态
mapObj: {
initData: null, // 地图初始化参数
landMap: null, //地图边界信息
davice: null, //设备 初始化一次后一般不动,因为会刷新整个地图
updateMarker: null, //更新设备 随外面的device一起更新
showMapType: false, //图层选择弹框
mapType: "img_w", //默认图层
centerPoint: 0, //用于中心点点击
ranging: false, //测距
},
pop: {
show: false,
showbox: false,
item: {}
},
}
},
onLoad() {
const that = this;
getApp().on("mqtt", "mqtt_map", function(e) {
if (e.type == "state") {
that.mqttConnected = e.connected;
} else if (e.type == "msg") {
that.mapUpdateMarker(e.data);
}
});
getApp().on("land", "land_map", function(e) {
that.title = that.ijs?.land?.landName || null;
that.mapOnload();
});
},
onShow() {
this.title = this.ijs?.land?.landName || "田间";
// 监听控制角度弹窗通知
uni.$off("open-angle-slider");
uni.$on("open-angle-slider", (e) => {
this.$refs.refAngleSlider.show(e.title, e.extra, e.value, e.other);
this.closePopup();
});
},
onHide() {
uni.$off("index-showLoading");
uni.$off("open-angle-slider");
},
mounted() {
//初始化基础数据
this.mapObj.initData = {
key: import.meta.env.VITE_APP_TIAN_DI_TU_KEY,
centerPoint: [87.624947, 43.791789], //默认乌鲁木齐
mapType: this.mapObj.mapType,
imgs: imageAssets,
};
},
methods: {
// 获取地块信息
getLand(e) {
this.ijs.getLand(e.node).then(res => {
this.$refs.landRef.addLand(e, res.data);
});
},
//初始化完成回调
mapOnload(e) {
if (!this.ijs.wo) {
return;
}
const that = this;
//地块边界
that.mapObj.landMap = that.ijs.wo.landMap;
let device = {};
//地块基站
if (that.dc.stations.length) {
that.dc.stations.forEach(item => {
if (item.latitude && item.longitude) {
item["deviceTypeKey"] = "station";
let obj = {
showName: item.deviceCode,
latlng: [item.latitude, item.longitude],
type: "jz",
dataKey: item.deviceCode,
device: item,
online: false,
warning: false,
logParams: {
operSubject: item.deviceCode
}
}
if (that.dc.dataObj[item.deviceCode]) {
obj.online = that.dc.dataObj[item.deviceCode].online;
}
device[item.deviceCode] = obj;
}
});
}
//其他设备
// for (let key in that.dc.others) {}
//地块阀门
if (that.dc.wo.length) {
that.dc.wo.forEach((item) => {
if (item.longitude && item.latitude) {
let obj = {
showName: item.showName,
latlng: [item.latitude, item.longitude],
type: item?.device?.deviceTypeKey,
dataKey: item.dataKey,
device: item.device,
online: false,
warning: false,
logParams: {
landId: item.landId,
wogId: item.id,
woId: -1,
}
}
if (that.dc.dataObj[item.dataKey]) {
obj.online = that.dc.dataObj[item.dataKey].online;
obj.warning = that.dc.dataObj[item.dataKey].warning.length > 0;
}
device[item.dataKey || item.showName] = obj;
}
if (item.children && item.children.length) {
item.children.forEach((child) => {
if (child.longitude && child.latitude) {
let obj = {
showName: child.showName,
latlng: [child.latitude, child.longitude],
type: child?.device?.deviceTypeKey,
dataKey: child.dataKey,
device: child.device,
online: false,
warning: false,
logParams: {
landId: child.landId,
wogId: child.landGroupId,
woId: child.id,
}
}
if (that.dc.dataObj[child.dataKey]) {
obj.online = that.dc.dataObj[child.dataKey].online;
obj.warning = that.dc.dataObj[child.dataKey].warning.length > 0;
}
device[child.dataKey || child.showName] = obj;
}
})
}
})
}
// 其他设备
for (var key in that.dc.others) {
if (that.dc.others[key].data && that.dc.others[key].data.length) {
that.dc.others[key].data.forEach(item => {
if (item.latitude && item.longitude) {
let showName = item.showName || item.deviceCode;
let deviceTypeKey = key,
dataKey = null;
if (key == "deviceMp") {
deviceTypeKey = "sq";
} else {
switch (item.deviceTypeId) {
case 4: // 4 施肥机
deviceTypeKey = "sfj"
break;
case 5: // 5 首部控制器
deviceTypeKey = "sb"
break;
case 6: // 6 气象站
deviceTypeKey = "qxz"
break;
case 7: // 7 病虫
deviceTypeKey = "bc"
break;
case 8: // 8 孢子
deviceTypeKey = "bz"
break;
case 9: // 9 摄像头
deviceTypeKey = "sxt"
break;
case 10: // 10 杀虫灯
deviceTypeKey = "scd"
break;
}
}
let obj = {
showName: showName,
latlng: [item.latitude, item.longitude],
type: deviceTypeKey,
dataKey: dataKey,
device: item,
online: false,
warning: false,
logParams: {},
}
device[showName] = obj;
}
});
}
}
that.mapObj.davice = device;
that.davice = device;
},
//选择图层
mapSwitchLayer(key) {
this.mapObj.showMapType = false;
this.mapObj.mapType = key;
},
//去中心点
mapToCenterPoint() {
this.mapObj.centerPoint++;
},
//导航
mapNavigation() {
this.$showConfirm(`导航至"${this.title}"`).then(res => {
if (res.confirm) {
const centerPoint = JSON.parse(this.mapObj.landMap.centerPoint);
const lat = centerPoint[1]
const lng = centerPoint[0]
let url = '';
const appName = appInfo.name; // 替换为你的应用名
const name = this.title; // 名称
// 高德地图
if (uni.getSystemInfoSync().platform === 'android') { // Android 平台
url =
`androidamap://route/plan/?sourceApplication=${appName}&sid=BGVIS1&did=BGVIS2&dlat=${lat}&dlon=${lng}&dname=${encodeURIComponent(name)}&mode=driving`;
} else if (uni.getSystemInfoSync().platform === 'ios') { // iOS 平台
url = `iosamap://path?sourceApplication=${appName}&mldl=${lat},${lng}`;
}
// // 百度地图 modedriving驾车模式。walking步行模式。transit公交模式。
// url = `baidumap://map/direction?destination=latlng:${lat},${lng}|name:${encodeURIComponent(name)}&mode=driving`;
// 尝试打开地图
plus.runtime.openURL(url, function(err) {
uni.showToast({
title: '未安装应用',
icon: 'none'
});
});
}
});
},
// 测距
mapRanging() {
if (this.mapObj.ranging) {
this.mapObj.ranging = false;
this.$toast("测距已关闭")
return;
}
this.$showConfirm(`开启测距,开启后再次点击关闭。`).then(res => {
if (res.confirm) {
this.mapObj.ranging = true;
}
});
},
//设备状态更新
mapUpdateMarker(e) {
if (!this.davice[e.deviceCode]) {
return;
}
const obj = {
key: e.deviceCode,
online: e.online,
warning: e.warning.length > 0,
};
const item = this.davice[e.deviceCode];
//如果这两个影响显示的值不一样,则更新它
if (item.online != obj.online || item.warning != obj.warning) {
this.mapObj.updateMarker = obj;
this.davice.online = obj.onlin;
this.davice.warning = obj.warning;
}
},
//设备点击
mapMarkerClickHandler(e) {
switch (e.type) {
case 'butterflyValve':
case 'valve':
case 'fiveValve':
case 'jz':
if (e.device) {
this.pop.showbox = false;
this.pop.item = e;
console.error("this.pop.item:", this.pop.item);
this.openPopup();
} else {
this.$toast("未绑定设备!");
}
break;
case 'sfj':
case 'sb':
this.$showConfirm("确定打开首部设备?").then(res => {
if (res.confirm) {
uni.showLoading()
getHeadDevice(e.device.deviceId).then((res) => {
uni.hideLoading()
if (res.data.deviceTypeId === 4) {
if (res.data.controlMode == 1) {
uni.navigateTo({
url: `/pages/head/fertilizerapplicator/detail?item=${JSON.stringify(res.data)}`,
});
} else if (item.controlMode == 2) {
uni.navigateTo({
url: `/pages/head/fertilizerapplicator/detailkl?item=${JSON.stringify(res.data)}`,
});
} else {}
} else if (res.data.deviceTypeId === 5) {
uni.navigateTo({
url: `/pages/head/headdevice/detail?item=${JSON.stringify(res.data)}`,
});
}
});
}
})
break;
case 'qxz':
case 'bc':
case 'bz':
case 'sxt':
case 'scd':
this.$showConfirm("确定打开农情设备?").then(res => {
if (res.confirm) {
uni.showLoading()
getOtherDevice(e.device.deviceId).then((res) => {
uni.hideLoading()
let url = null;
if (res.data.deviceTypeId === 6) {
url =
`/pages/fourmonitor/weatherstation?item=${encodeURIComponent(JSON.stringify(res.data))}`;
} else if (res.data.deviceTypeId === 7) {
url =
`/pages/fourmonitor/pest?item=${encodeURIComponent(JSON.stringify(res.data))}`;
} else if (res.data.deviceTypeId === 8) {
url =
`/pages/fourmonitor/spore?item=${encodeURIComponent(JSON.stringify(res.data))}`;
} else if (res.data.deviceTypeId === 9) {
if (!res.data.ezopenUrl1 || !res.data.ezopenUrl2) {
this.$toast("获取播放地址失败!")
return;
}
url =
`/pages/fourmonitor/camera?item=${encodeURIComponent(JSON.stringify(res.data))}`;
} else if (res.data.deviceTypeId === 10) {}
if (url) {
uni.navigateTo({
url: url,
});
}
});
}
});
break;
case 'sq':
this.$refs.mpRef.show(this.ijs.land, e.device.id);
break;
}
},
openPopup() {
this.pop.show = true;
},
closePopup() {
this.pop.show = false;
},
// 角度控制回调
swiperConfirm(e) {
this.dc.buildCommand(e.item, e.index, e.value, e.other);
this.openPopup();
},
// 打开弹窗
async openDialog(key, row = null) {
switch (key) {
// case "chart": //曲线
// this.$refs.adcChartRef.show(row);
// break;
// case "wo":
// this.$refs.woRemarkRef.show(row);
// break;
// case "wh": //浇灌履历
// this.$refs.wateringHistoryRef.show(this.land, row);
// break;
// case "log": //日志
// this.$refs.deviceLogRef.show(this.land, row);
// break;
case "mp": //墒情
this.$refs.mpRef.show(this.land);
break;
case "adc": //设备adc
this.$refs.adcRef.show(2, row, this.dc.dataObj[row.dataKey]);
break;
}
this.closePopup();
},
// 格式化日期
formatData(time) {
return timestampFormat(time);
},
operationLog(item) {
uni.navigateTo({
url: `/pages/work/operation-log/index?queryParams=${JSON.stringify(item.logParams)}`,
});
}
}
}
</script>
<script module="leaflet" lang="renderjs">
// #ifdef H5
import "leaflet/dist/leaflet.css"
// #endif
import L from "leaflet"
export default {
data() {
return {
map: null,
key: null,
centerPoint: null, //默认乌鲁木齐
mapType: null,
_selectMapType: null,
_imgs: null,
_device: null,
_markers: {},
drawing: {
ranging: null,
}
};
},
mounted() {},
methods: {
//初始化
initEmitHandler(e) {
if (!e) {
return;
}
this.key = e.key;
this.centerPoint = {
lat: e.centerPoint[0],
lng: e.centerPoint[1],
};
this._selectMapType = e.mapType;
this._imgs = e.imgs;
this.initMap();
},
//切换图层
switchLayerEmitHandler(e) {
if (!e) {
return;
}
this.switchLayer(e);
},
//去中心点
centerPointEmitHandler(e) {
if (!e) {
return;
}
this.toCenterPoint();
},
//地块边界绘制
drawEmitHandler(e) {
if (!e) {
return;
}
this.drawMap(e);
},
//设备
markerEmitHandler(e) {
if (!e) {
return;
}
this.setDeviceMarker(e);
},
// 更新设备
updateMarkerEmitHandler(e) {
if (!e) {
return;
}
this.updateMarkerColor(e);
},
//测距
rangingEmitHandler(e) {
if (e == true || e == false) {
if (e) {
this.ranging(1);
} else {
this.ranging(0);
}
}
},
//初始化地图
initMap() {
if (this.map) {
return;
}
const that = this;
that.mapType = {
vec_w: new L.tileLayer(
`http://t0.tianditu.com/DataServer?T=vec_w&x={x}&y={y}&l={z}&tk=${that.key}`, {
attribution: '矢量地图'
}),
img_w: new L.tileLayer(
`http://t0.tianditu.com/DataServer?T=img_w&x={x}&y={y}&l={z}&tk=${that.key}`, {
attribution: '影像地图'
}),
ter_w: new L.tileLayer(
`http://t0.tianditu.com/DataServer?T=ter_w&x={x}&y={y}&l={z}&tk=${that.key}`, {
attribution: '地形图'
}),
labelLayer: new L.tileLayer(
`http://t0.tianditu.gov.cn/cva_w/wmts?service=wmts&request=GetTile&version=1.0.0&LAYER=cva&tileMatrixSet=w&TileMatrix={z}&TileRow={y}&TileCol={x}&style=default&format=tiles&tk=${that.key}`, {
attribution: '矢量地名标注'
}),
};
var normal = L.layerGroup([that.mapType[that._selectMapType], that.mapType.labelLayer])
const map = L.map('map', {
// crs: L.CRS.EPSG3857,
// center: [34.07148, 108.84076], //中心点
center: [that.centerPoint.lng, that.centerPoint.lat], //中心点
layers: normal,
zoom: 5, //默认层级
minZoom: 2, //最小层级
maxZoom: 18, //最大层级
zoomControl: false, //是否将 zoom 缩放控件添加到地图中。
doubleClickZoom: false, //图是否可以通过双击来放大
dragging: true, //地图是否可以通过 mouse/touch 进行拖动。
attributionControl: false, //是否将 attribution 版权控件添加到地图中。
tap: true, // 确保此选项为 true 或者不指定,因为默认值是 true
});
// // 创建一个新的归因控件实例
// var attribution = L.control.attribution({
// position: 'bottomright', // 设置位置,可选值有 'topleft', 'topright', 'bottomleft', 'bottomright'
// });
// // 添加多个归因文本
// attribution.addAttribution('天地图');
// // attribution.addAttribution('GS20240568号 - 甲测资字1100471');
// // 将归因控件添加到地图
// attribution.addTo(map);
// 如果需要监听缩放过程中的变化,可以使用 'zoom' 事件
map.on('zoom', function() {
// that.onZoomend();
});
that.map = map;
that.$ownerInstance.callMethod('mapOnload', "map初始化回调");
},
//清理图层
clearMap() {
const that = this;
var layers = that.map._layers;
var markersToRemove = [];
// 遍历所有图层并移除
for (var id in layers) {
if (!(layers[id] instanceof L.TileLayer)) { // 假设底图是由TileLayer提供的
markersToRemove.push(layers[id]);
}
// if (layers[id] instanceof L.Marker) { // 确保我们处理的是一个Leaflet图层
// markersToRemove.push(layers[id]);
// }
}
// 移除所有的 Marker
markersToRemove.forEach(function(marker) {
that.map.removeLayer(marker);
});
},
//切换地图
switchLayer(key) {
if (!this.map) {
return;
}
const that = this;
// 移除当前所有图层
that.map.eachLayer(function(layer) {
if (layer instanceof L.TileLayer) {
that.map.removeLayer(layer);
}
});
// 添加新的图层
that.mapType[key].addTo(that.map);
that.mapType["labelLayer"].addTo(that.map);
that._selectMapType = key;
},
//中心点
toCenterPoint() {
var currentZoomLevel = this.map.getZoom();
const lng = this.centerPoint.lng;
const lat = this.centerPoint.lat;
if (currentZoomLevel > 10) {
this.map.setView([lng, lat], currentZoomLevel);
// this.map.panTo([lng, lat]);
// this.map.setZoom(18);
// this.map.flyTo([lng, lat], currentZoomLevel);
} else {
this.map.setZoomAround([lng, lat], 18);
this.map.flyTo([lng, lat], 18);
}
},
// 绘制地图
drawMap(landMap) {
if (!landMap) {
return
}
const {
centerPoint, //中心点
boundary, //边界(支持多个)
mainLine, //主干管
secondaryLine //支干管
} = landMap;
// 重新设置中心点
const cp = JSON.parse(centerPoint)
// this.map.setZoomAround([cp[1], cp[0]], 16)
// this.map.flyTo([cp[1], cp[0]], 16)
this.map.setView([cp[1], cp[0]], 18)
this.setCenterPoint(centerPoint)
this.setBoundary(boundary)
this.setMainLine(mainLine)
this.setSecondaryLine(secondaryLine)
},
// 设置中心点
setCenterPoint(centerPoint) {
if (!centerPoint) {
return
}
// 重新设置中心点
centerPoint = JSON.parse(centerPoint)
// 重新设置中心点
this.centerPoint = {
lat: centerPoint[0],
lng: centerPoint[1],
};
},
// 设置边界
setBoundary(boundary) {
if (!boundary) {
return
}
// 重新设置中心点
boundary = JSON.parse(boundary)
if (boundary.length) {
boundary.forEach((items) => {
let points = []
items.forEach(item => {
points.push([item[1], item[0]])
});
//创建面对象
var polygon = L.polygon(points, {
color: "blue"
});
this.map.addLayer(polygon);
})
}
},
// 设置主干管
setMainLine(mainLine) {
if (!mainLine) {
return
}
// 重新设置中心点
mainLine = JSON.parse(mainLine)
if (mainLine.length) {
mainLine.forEach((item1) => {
let points = []
item1.forEach((item2) => {
points.push([item2[1], item2[0]])
})
//创建线对象
var line = L.polyline(points, {
color: '#ff0000',
});
//向地图上添加线
this.map.addLayer(line)
})
}
},
// 设置主干管
setSecondaryLine(secondaryLine) {
if (!secondaryLine) {
return
}
// 重新设置中心点
secondaryLine = JSON.parse(secondaryLine)
if (secondaryLine.length) {
secondaryLine.forEach((item1) => {
let points = []
item1.forEach((item2) => {
points.push([item2[1], item2[0]])
})
//创建线对象
var line = L.polyline(points, {
color: '#00ff00',
});
//向地图上添加线
this.map.addLayer(line)
})
}
},
//设置设备
setDeviceMarker(device) {
const that = this;
let markers = {};
for (let key in device) {
let item = device[key];
// 创建标注
let marker = L.marker(item.latlng, {
icon: that.creatMapIcon(item.type)
})
marker.on('click', function(e) {
that.markerClick(e);
});
that.map.addLayer(marker) // 将标注添加到地图中
item["markerId"] = marker._leaflet_id;
// 创建文字
let label = L.marker(item.latlng, {
icon: that.creatLabel(item.showName, item.online, item.warning)
});
that.map.addLayer(label) // 将标注添加到地图中
item["labelId"] = label._leaflet_id;
//缓存起来
markers[marker._leaflet_id] = {
item: item,
select: false,
marker: marker,
label: label,
};
}
that._device = device;
that._markers = markers;
},
// 生成阀门图标
creatMapIcon(type, select = false) {
// 获取当前地图的缩放级别
// const zoom = this.map.getZoom();
var icon = null;
switch (type) {
case 'valve':
icon = L.icon({
iconUrl: `.${select ? this._imgs.valve3_select : this._imgs.valve3}`,
iconSize: [20, 34], //图标图像的尺寸,单位是像素。
});
break;
case 'fiveValve':
icon = L.icon({
iconUrl: `.${select ? this._imgs.valve5_select : this._imgs.valve5}`,
iconSize: [20, 34], //图标图像的尺寸,单位是像素。
});
break;
case 'butterflyValve':
icon = L.icon({
iconUrl: `.${select ? this._imgs.df_select : this._imgs.df}`,
iconSize: [20, 34], //图标图像的尺寸,单位是像素。
});
break;
case 'jz':
icon = L.icon({
iconUrl: `.${this._imgs.jz}`,
iconSize: [20, 34], //图标图像的尺寸,单位是像素。
});
break;
case 'sfj':
icon = L.icon({
iconUrl: `.${this._imgs.sfj}`,
iconSize: [20, 34], //图标图像的尺寸,单位是像素。
});
break;
case 'sb':
icon = L.icon({
iconUrl: `.${this._imgs.sb}`,
iconSize: [20, 34], //图标图像的尺寸,单位是像素。
});
break;
case 'qxz':
icon = L.icon({
iconUrl: `.${this._imgs.qxz}`,
iconSize: [20, 34], //图标图像的尺寸,单位是像素。
});
break;
case 'bc':
icon = L.icon({
iconUrl: `.${this._imgs.bc}`,
iconSize: [20, 34], //图标图像的尺寸,单位是像素。
});
break;
case 'bz':
icon = L.icon({
iconUrl: `.${this._imgs.bz}`,
iconSize: [20, 34], //图标图像的尺寸,单位是像素。
});
break;
case 'sxt':
icon = L.icon({
iconUrl: `.${this._imgs.sxt}`,
iconSize: [20, 34], //图标图像的尺寸,单位是像素。
});
break;
case 'scd':
icon = L.icon({
iconUrl: `.${this._imgs.scd}`,
iconSize: [20, 34], //图标图像的尺寸,单位是像素。
});
break;
case 'sq':
icon = L.icon({
iconUrl: `.${this._imgs.sq}`,
iconSize: [20, 34], //图标图像的尺寸,单位是像素。
});
break;
default:
icon = L.icon({
iconUrl: `.${this._imgs.csk}`,
iconSize: [20, 30], //图标图像的尺寸,单位是像素。
// //图标 "tip" 的坐标相对于其左上角。图标将被对齐使该点位于标记的地理位置。如果指定了尺寸默认为居中也可以在CSS中设置负的边距。
// iconAnchor: [7, 9],
// //弹出窗口popup的坐标相对于图标锚点而言将从该点打开。
// popupAnchor: [-3, -3],
});
break;
}
return icon;
},
// 生成阀门文字
creatLabel(name = "", online, warning) {
let divIcon = L.divIcon({
html: `<span>${name}</span>`,
className: `my-device-icon ${this.getLableColor(online, warning)}`,
iconAnchor: [15, -10],
});
if (name.length <= 3) {
divIcon.options.iconAnchor = [15, -10]
} else if (name.length == 4 || name.length == 5) {
divIcon.options.iconAnchor = [20, -10]
} else {
divIcon.options.iconAnchor = [25, -10]
}
return divIcon;
},
// 获取文字的颜色
getLableColor(online, warning) {
let color = 'device-white'; //"#fff";
if (online) {
if (warning) {
color = 'device-orange'; //"#fbc902"; //橙黄(警告)
} else {
color = 'device-green'; //"#0bff3a"; //绿色(在线)
}
} else {
color = 'device-white'; //"#fff"; //白色(默认/离线)
}
return color;
},
// 点击事件
markerClick(e) {
const that = this;
let key = e.sourceTarget._leaflet_id;
const clickItem = that._markers[key];
that.$ownerInstance.callMethod('mapMarkerClickHandler', clickItem.item);
// if (!["butterflyValve", "valve", "fiveValve"].includes(clickItem.item.type)) {
// key = null;
// }
if (clickItem.item.device) {
for (var rkey in that._markers) {
if (that._markers[rkey].select) {
const clickedIcon = that.creatMapIcon(that._markers[rkey].item.type, false);
that._markers[rkey].marker.setIcon(clickedIcon);
that._markers[rkey].select = false;
}
if (key == rkey) {
const clickedIcon = that.creatMapIcon(that._markers[rkey].item.type, true);
that._markers[rkey].marker.setIcon(clickedIcon);
that._markers[rkey].select = true;
}
}
}
},
// 更新设备的状态
updateMarkerColor(e) {
if (this._device[e.key]) {
const markerId = this._device[e.key]["markerId"]; //标签的id
const marker = this._markers[markerId];
if (marker) {
const dIcon = that.creatLabel(marker.item.showName, e.online, e.warning);
this._markers[markerId].label.setIcon(dIcon);
}
}
},
// 测距
ranging(type) {
const that = this;
if (type == 1) { //开始
that.drawing.ranging = {
latlngs: [],
gap: [],
pop: [],
item: null,
}
that.map.off('click');
that.map.on('click', (e) => {
//记录坐标
that.drawing.ranging.latlngs.push(e.latlng);
if (that.drawing.ranging.latlngs.length > 1) {
if (that.drawing.ranging.item) {
that.drawing.ranging.item.setLatLngs(that.drawing.ranging.latlngs);
} else {
that.drawing.ranging.item = L.polyline(that.drawing.ranging.latlngs, {
color: "red"
});
that.map.addLayer(that.drawing.ranging.item);
}
//计算距离
const prev = that.drawing.ranging.latlngs[that.drawing.ranging.latlngs.length - 2];
const gap = L.latLng(prev).distanceTo(e.latlng);
that.drawing.ranging.gap.push(gap);
let sumgap = that.drawing.ranging.gap.reduce((acc, curr) => acc + curr, 0);
if (sumgap > 1000) {
sumgap = (sumgap / 1000).toFixed(2);
let marker = L.marker(e.latlng, {
icon: L.divIcon({
html: `<span>${sumgap}公里</span>`,
className: 'my-div-icon'
})
}).addTo(that.map);
that.drawing.ranging.pop.push(marker);
} else {
let marker = L.marker(e.latlng, {
icon: L.divIcon({
html: `<span>${Math.round(sumgap)}m</span>`,
className: 'my-div-icon'
})
}).addTo(that.map);
that.drawing.ranging.pop.push(marker);
}
} else {
//创建marker
let marker = L.marker(e.latlng, {
icon: L.divIcon({
html: '<span>起点</span>',
className: 'my-div-icon'
})
}).addTo(that.map);
that.drawing.ranging.pop.push(marker);
}
});
} else if (type == 2) { //删除
if (that.drawing.ranging.latlngs.length) {
that.drawing.ranging.latlngs.pop();
}
if (that.drawing.ranging.pop.length) {
let pop = that.drawing.ranging.pop.pop();
that.map.removeLayer(pop);
}
if (that.drawing.ranging.item) {
that.drawing.ranging.item.setLatLngs(that.drawing.ranging.latlngs);
// if (that.drawing.ranging.latlngs.length > 1) {
// //计算距离
// let start = that.drawing.ranging.latlngs[0];
// let end = that.drawing.ranging.latlngs[that.drawing.ranging.latlngs.length - 1];
// const gap = L.latLng(start).distanceTo(end);
// }
}
} else { //结束
if (!that.drawing.ranging) {
return;
}
that.drawing.ranging.latlngs = null;
if (that.drawing.ranging.pop && that.drawing.ranging.pop.length) {
that.drawing.ranging.pop.forEach(x => {
that.map.removeLayer(x);
});
}
that.drawing.ranging.pop = null;
if (that.drawing.ranging.item) {
that.map.removeLayer(that.drawing.ranging.item);
}
that.drawing.ranging.item = null;
that.map.off('click');
}
},
}
}
</script>
<style lang="scss">
/* #ifdef APP-PLUS */
@import url("leaflet/dist/leaflet.css");
/* #endif */
.map {
width: 100%;
top: 0;
bottom: 0;
position: absolute;
z-index: 0;
/* 地图放大缩小 */
// ::v-deep .leaflet-control-container {
// position: absolute !important;
// right: 55px !important;
// top: 20% !important;
// }
::v-deep .leaflet-control-attribution {
a {}
}
/* 文字 */
:deep() {
.my-device-icon {
background-color: transparent;
}
.my-device-icon span {
font-size: 14px;
white-space: nowrap;
display: block;
border-radius: 4px;
background-color: transparent;
width: fit-content;
padding: 2px 5px;
}
.device-white span {
color: #fff;
}
.device-green span {
color: #0bff3a;
}
.device-orange span {
color: #fbc902;
}
/* 测距 */
.my-div-icon {
background-color: transparent;
}
.my-div-icon span {
white-space: nowrap;
display: block;
border-radius: 4px;
background-color: #fff;
width: fit-content;
padding: 2px 5px;
}
}
}
</style>
<style lang="scss" scoped>
// 顶部nav
::v-deep.uni-navbar__header-container {
align-items: center;
justify-content: center;
&>view {
font-size: 36rpx;
}
}
::v-deep.uni-navbar__header-btns-left {
font-size: 27rpx;
}
::v-deep.uni-navbar__header-btns-right .icon {
font-size: 44rpx;
margin-left: 10px;
}
// .icon {
// width: 16px;
// height: 16px;
// fill: currentColor;
// overflow: hidden;
// }
.tdt {
font-size: 12px;
position: absolute;
z-index: 1100;
bottom: 10px;
left: 10px;
uni-image {
width: 53px;
height: 22px;
vertical-align: middle;
margin-right: 5px;
}
}
.below {
position: absolute;
z-index: 1100;
bottom: 20%;
right: 10px;
&>view {
margin-bottom: 5px;
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
width: 35px;
height: 35px;
background-color: #fff;
border-radius: 10px;
span {
font-size: 9px;
}
}
}
/* 图层弹出 */
.layer {
padding: 10px;
background-color: #eff0f5;
width: 100%;
border-radius: 10px 10px 0 0;
.card {
background-color: #fff;
border-radius: 5px;
display: flex;
justify-content: space-around;
&>view {
width: 74px;
height: auto;
margin: 15px 0;
text-align: center;
.img {
width: 74px;
height: 50px;
overflow: hidden;
margin-bottom: 5px;
border-radius: 5px;
image {
width: 100%;
height: 100%;
}
}
}
.click {
color: #1a8def;
.img {
border: 1px solid #1a8def;
}
}
}
.title {
font-size: 16px;
display: flex;
justify-content: space-between;
view {
width: 30px;
}
i {
font-size: 14px;
}
}
}
// 控制弹出框
.uni-popup {
z-index: 1000;
}
.popup-content {
height: auto;
overflow: hidden;
max-height: calc(100vh - 290px);
}
// 水阀列表title
.card-grey {
height: auto;
overflow: hidden;
border-radius: 10px 10px 0 0;
margin-bottom: 0;
.gb {
text-align: right;
padding: 5px 5px 0 0;
font-size: 14px;
}
}
.card {
margin: 10px;
height: auto;
position: relative;
.title {
justify-content: space-between;
padding: 10px;
.text {
font-size: 16px;
}
}
.title>view:nth-child(2) {
color: #999;
span {
font-size: 0.875rem;
margin-left: 5px;
}
}
}
.sf-title {
font-size: 24rpx;
color: #999999;
padding: 10px 0;
.text {
font-size: 32rpx;
color: #333;
}
.icon {
vertical-align: top;
margin-right: 5px;
font-size: 44rpx;
color: #39ac4f;
}
}
.font-green {
color: #39ac4f !important;
}
.font-red {
color: #e60012 !important;
}
// 提示
.tip {
color: #999;
padding: 0 10px;
}
.box {
transition: height 0.5s ease-out;
}
.box.show {
height: 260px;
overflow-y: scroll;
}
.box.hide {
height: 0px;
}
.expand,
.expand5 {
.icon {
text-align: center;
width: 100%;
height: 26px;
}
.iconfont {
font-size: 24px;
animation: iconleft 0.5s infinite ease-in-out alternate;
color: #3399ff;
}
}
.expand5 {
.icon {
height: 46px;
}
}
@keyframes iconleft {
from {
transform: translateY(0px);
}
to {
transform: translateY(2px);
}
}
// 水压图表
.pressure {
padding: 10px;
&>view:first-child {
margin: 10px 0;
}
span {
text-align: center;
color: #999;
display: block;
}
}
// 操作记录
.text-list {
padding: 5px 10px;
margin: 0 10px 10px;
background-color: #f3f3f3;
border-radius: 5px;
&>view {
line-height: 24px;
display: flex;
justify-content: space-between;
}
&>view:nth-child(2) {
color: #666;
font-size: 0.775rem;
}
}
/* 首页阀门列表 */
.control {
padding: 20px 10px;
&>.icon {
color: #3399ff;
position: absolute;
right: 10px;
}
.u-button {
width: 100% !important;
min-width: 77px;
.name {
position: absolute;
color: rgb(0, 0, 0, 0.1);
}
}
.u-line-progress {
min-width: 77px;
margin-top: 5px;
}
}
.tips {
font-size: 12rpx;
margin: 10px;
width: 100%;
height: 25px;
}
.valve {
display: flex;
align-items: center;
flex-direction: column;
.timeout {
color: red !important;
font-size: 10px;
}
.btn-img {
width: 160px;
margin: 15px;
position: relative;
img {
width: 100%;
}
.text,
.text5 {
&>view {
position: absolute;
z-index: 2;
font-weight: bold;
font-size: 16px;
color: #333;
}
.left {
left: 0;
top: calc(50% - 17px);
transform: translateY(-50%);
}
.top {
top: 0;
left: 50%;
transform: translateX(-50%);
}
.middle {
font-size: 24px;
top: calc(50% - 18px);
left: 50%;
transform: translate(-50%, -50%);
color: #e60012;
text-align: center;
}
.right {
right: 0;
top: calc(50% - 17px);
transform: translateY(-50%);
}
.bottom {
bottom: 0;
right: 50%;
transform: translateX(50%);
}
}
.text5 {
.left {
left: 0;
top: calc(50% - 4px);
transform: translateY(-50%);
}
.middle {
top: calc(50% - 5px);
}
.right {
right: 0;
top: calc(50% - 4px);
transform: translateY(-50%);
}
}
}
}
</style>