|
@@ -0,0 +1,738 @@
|
|
|
|
|
+<template>
|
|
|
|
|
+ <view class="facilitystate-page">
|
|
|
|
|
+ <custom-card>
|
|
|
|
|
+ <block slot="backText">
|
|
|
|
|
+ <view class="facilitystate-top__title">
|
|
|
|
|
+ <text :class="devStatus == '1' ? 'online' : 'offline'">{{
|
|
|
|
|
+ devStatus == '1' ? '在线' : '离线'
|
|
|
|
|
+ }}</text>
|
|
|
|
|
+ {{ devName }}
|
|
|
|
|
+ </view>
|
|
|
|
|
+ </block>
|
|
|
|
|
+ </custom-card>
|
|
|
|
|
+ <view class="facilitystate-top">
|
|
|
|
|
+ <view
|
|
|
|
|
+ class="facilitystate-top__item"
|
|
|
|
|
+ v-for="(item, index) in deviceList"
|
|
|
|
|
+ :key="index"
|
|
|
|
|
+ @click="nativeTo(item)"
|
|
|
|
|
+ >
|
|
|
|
|
+ <view class="item-icon-container" :class="item.className">
|
|
|
|
|
+ <image class="item-icon" :src="item.icon" />
|
|
|
|
|
+ </view>
|
|
|
|
|
+ <view class="facilitystate-top__item-text">{{ item.title }}</view>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ <view class="irrMode">
|
|
|
|
|
+ <view class="irrMode__header">
|
|
|
|
|
+ <view @click="changeMode('1')" :class="workStatus == '1' ? 'active' : ''">施肥模式</view>
|
|
|
|
|
+ <view @click="changeMode('0')" :class="workStatus == '0' ? 'active' : ''">灌溉模式</view>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ <view class="irrMode__content">
|
|
|
|
|
+ <view class="irrMode__content-header">
|
|
|
|
|
+ <view class="irrMode__content-header-list">
|
|
|
|
|
+ <view class="irrMode__content-header-title">
|
|
|
|
|
+ <view class="irrMode__content-header-container">
|
|
|
|
|
+ <image class="header-item-icon" :src="rain" />
|
|
|
|
|
+ <text style="color:#333;font-size: 24rpx;margin-left: 10rpx">当前灌溉区域:</text>{{ runTitle }}
|
|
|
|
|
+ </view>
|
|
|
|
|
+ <view class="timer-text">{{ timer }}分</view>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ <view class="irrMode__content-item">
|
|
|
|
|
+ <view class="irrMode__content-item-raduis" :class="runStatus == '1' ? 'active-radius' : ''" @click="changeActive('1')">
|
|
|
|
|
+ <image class="item-icon" :src="runStatus=='1'?mediaPlayFill:mediaPlay" />
|
|
|
|
|
+ <view class="item-text">启动</view>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ <view class="irrMode__content-item-raduis" :class="runStatus == '2' ? 'active-radius' : ''" @click="changeActive('2')">
|
|
|
|
|
+ <image class="item-icon" :src="runStatus=='2'?mediaPauseFill:mediaPause" />
|
|
|
|
|
+ <view class="item-text">暂停</view>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ <view class="irrMode__content-item-raduis" :class="runStatus == '0' ? 'active-radius' : ''" @click="changeActive('0')" style="margin-right:0">
|
|
|
|
|
+ <image class="item-icon" :src="runStatus=='0'?stopFill:stop" />
|
|
|
|
|
+ <view class="item-text">停止</view>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ <view class="irr-run-list">
|
|
|
|
|
+ <text v-for="(item, index) in selectAreaList" :key="index">
|
|
|
|
|
+ {{ item.group_name }}
|
|
|
|
|
+ <text v-if="index != selectAreaList.length - 1">、</text>
|
|
|
|
|
+ </text>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ <Base :dataList="dataList" />
|
|
|
|
|
+ <facilitystate
|
|
|
|
|
+ :devBid="devBid"
|
|
|
|
|
+ :ggbCurrent="ggbCurrent"
|
|
|
|
|
+ :sfbCurrent="sfbCurrent"
|
|
|
|
|
+ :irrigatedAreaList="irrigatedAreaList"
|
|
|
|
|
+ :webSockedData="webSockedData"
|
|
|
|
|
+ :alreadyfertilizerBucketList="alreadyfertilizerBucketList"
|
|
|
|
|
+ />
|
|
|
|
|
+ </view>
|
|
|
|
|
+ </view>
|
|
|
|
|
+</template>
|
|
|
|
|
+
|
|
|
|
|
+<script>
|
|
|
|
|
+import manualControl from './assets/manualControl.png';
|
|
|
|
|
+import mediaPause from './assets/media-pause.png';
|
|
|
|
|
+import mediaPauseFill from './assets/media-pause-fill.png';
|
|
|
|
|
+import mediaPlay from './assets/media-play.png';
|
|
|
|
|
+import mediaPlayFill from './assets/media-play-fill.png';
|
|
|
|
|
+import rain from './assets/rain.png';
|
|
|
|
|
+import stop from './assets/stop.png';
|
|
|
|
|
+import stopFill from './assets/stop-fill.png';
|
|
|
|
|
+import wheelIrrigation from './assets/wheelIrrigation.png';
|
|
|
|
|
+import time from './assets/timing.png';
|
|
|
|
|
+import formulaSetting from './assets/formulaSetting.png';
|
|
|
|
|
+import operatingRecord from './assets/operatingRecord.png';
|
|
|
|
|
+import Base from './components/base.vue';
|
|
|
|
|
+import facilitystate from './components/facilitystate.vue';
|
|
|
|
|
+export default {
|
|
|
|
|
+ data() {
|
|
|
|
|
+ return {
|
|
|
|
|
+ ws: null,
|
|
|
|
|
+ currentMode: '1',
|
|
|
|
|
+ title: '水肥一体机',
|
|
|
|
|
+ manualControl,
|
|
|
|
|
+ devBid: '',
|
|
|
|
|
+ devName: '',
|
|
|
|
|
+ devStatus: '1',
|
|
|
|
|
+ dataList: [],
|
|
|
|
|
+ irrigatedAreaList: [],
|
|
|
|
|
+ alreadyfertilizerBucketList: [],
|
|
|
|
|
+ mediaPause,
|
|
|
|
|
+ mediaPauseFill,
|
|
|
|
|
+ mediaPlay,
|
|
|
|
|
+ mediaPlayFill,
|
|
|
|
|
+ rain,
|
|
|
|
|
+ stop,
|
|
|
|
|
+ stopFill,
|
|
|
|
|
+ deviceList: [
|
|
|
|
|
+ {
|
|
|
|
|
+ icon: manualControl,
|
|
|
|
|
+ title: '手动控制',
|
|
|
|
|
+ className: 'manualControl',
|
|
|
|
|
+ url: '/pages/cb/shuifeizsFirst/control',
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ icon: wheelIrrigation,
|
|
|
|
|
+ title: '自动控制',
|
|
|
|
|
+ className: 'wheelIrrigation',
|
|
|
|
|
+ url: '/pages/cb/shuifeizsFirst/autoSetting?devBid=' + this.devBid,
|
|
|
|
|
+ }, {
|
|
|
|
|
+ icon: time,
|
|
|
|
|
+ title: '定时设置',
|
|
|
|
|
+ className: 'timedSetting',
|
|
|
|
|
+ url: '/pages/cb/shuifeizsFirst/timingSetting?devBid=' + this.devBid,
|
|
|
|
|
+ },{
|
|
|
|
|
+ icon: formulaSetting,
|
|
|
|
|
+ title: '配方设置',
|
|
|
|
|
+ className: 'formulaSetting',
|
|
|
|
|
+ url: '/pages/cb/shuifeizsFirst/formulaSetting?devBid=' + this.devBid,
|
|
|
|
|
+ }, {
|
|
|
|
|
+ icon: operatingRecord,
|
|
|
|
|
+ title: '操作记录',
|
|
|
|
|
+ className: 'operatingRecord',
|
|
|
|
|
+ url: '/pages/cb/shuifeizsFirst/history?devBid=' + this.devBid,
|
|
|
|
|
+ },
|
|
|
|
|
+ ],
|
|
|
|
|
+ ggbCurrent: {},
|
|
|
|
|
+ sfbCurrent: {},
|
|
|
|
|
+ sfToken: '',
|
|
|
|
|
+ entityId: '',
|
|
|
|
|
+ heartbeatTimer: null,
|
|
|
|
|
+ info: {},
|
|
|
|
|
+ dataArray:[],
|
|
|
|
|
+ webSockedData: {},
|
|
|
|
|
+ reconnectCount: 0,
|
|
|
|
|
+ isActive: '0',
|
|
|
|
|
+ runStatus: -1,
|
|
|
|
|
+ workStatus: -1,
|
|
|
|
|
+ clearIrr: {},
|
|
|
|
|
+ selectAreaList: [],
|
|
|
|
|
+ runTitle: '--',
|
|
|
|
|
+ timer:'--'
|
|
|
|
|
+ };
|
|
|
|
|
+ },
|
|
|
|
|
+ components: {
|
|
|
|
|
+ Base,
|
|
|
|
|
+ facilitystate,
|
|
|
|
|
+ },
|
|
|
|
|
+ onLoad(options) {
|
|
|
|
|
+ /*
|
|
|
|
|
+ 0 水源 泵类 负责水源进入管道的总泵或者阀
|
|
|
|
|
+ 1 肥料 泵类 负责肥料进入管道的总阀或者泵
|
|
|
|
|
+ 2 吸肥 泵类 控制肥料桶出肥的阀或者泵,每个肥料桶一个
|
|
|
|
|
+ 3 搅拌 泵类 肥料桶的搅拌电机或者泵 每个肥料桶一个
|
|
|
|
|
+ 4 肥料桶 泵类 肥料桶,每个施肥机有多个或者没有,不一定真实存在,只是逻辑上的概念
|
|
|
|
|
+ 5 电磁阀 无 管道最末端每个田地里控制出水的阀门
|
|
|
|
|
+ 6 传感器 无 水肥机上的 温度,压力,流速,PH EC等监测类要素
|
|
|
|
|
+ 7 灌区 无 逻辑区域,电磁阀的分组
|
|
|
|
|
+ */
|
|
|
|
|
+ const { devBid, devName, devStatus } = options;
|
|
|
|
|
+ this.devBid = devBid;
|
|
|
|
|
+ this.devName = devName;
|
|
|
|
|
+ this.devStatus = devStatus;
|
|
|
|
|
+ this.deviceList[0].url = `/pages/cb/shuifeizsFirst/control?devBid=${options.devBid}`;
|
|
|
|
|
+ this.deviceList[1].url = `/pages/cb/shuifeizsFirst/autoSetting?devBid=${options.devBid}`;
|
|
|
|
|
+ this.deviceList[2].url = `/pages/cb/shuifeizsFirst/timingSetting?devBid=${options.devBid}`;
|
|
|
|
|
+ this.deviceList[3].url = `/pages/cb/shuifeizsFirst/formulaSetting?devBid=${options.devBid}`;
|
|
|
|
|
+ this.deviceList[
|
|
|
|
|
+ this.deviceList.length - 1
|
|
|
|
|
+ ].url = `/pages/cb/shuifeizsFirst/history?devBid=${options.devBid}`;
|
|
|
|
|
+ if (devBid) {
|
|
|
|
|
+ this.init();
|
|
|
|
|
+ }
|
|
|
|
|
+ },
|
|
|
|
|
+ onUnload() {
|
|
|
|
|
+ this.ws.close();
|
|
|
|
|
+ },
|
|
|
|
|
+ onShow(){
|
|
|
|
|
+ if (this.devBid) {
|
|
|
|
|
+ this.init();
|
|
|
|
|
+ }
|
|
|
|
|
+ },
|
|
|
|
|
+ methods: {
|
|
|
|
|
+ isHaveTime(childrenList) {
|
|
|
|
|
+ let time = 0;
|
|
|
|
|
+ let currentKey = '';
|
|
|
|
|
+ let currentItem = {};
|
|
|
|
|
+ for (let i = 0; i < this.selectAreaList.length; i++) {
|
|
|
|
|
+ for (let key in this.selectAreaList[i]) {
|
|
|
|
|
+ if (key.includes(':Status')) {
|
|
|
|
|
+ currentKey = key;
|
|
|
|
|
+ currentItem = this.selectAreaList[i];
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ for (let i = 0; i < childrenList.length; i++) {
|
|
|
|
|
+ const item = childrenList[i];
|
|
|
|
|
+ if (item.sfCode === currentKey) {
|
|
|
|
|
+ for (let key in currentItem) {
|
|
|
|
|
+ if (key.includes(':PartTim')) {
|
|
|
|
|
+ time = currentItem[key];
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ return time;
|
|
|
|
|
+ },
|
|
|
|
|
+ isAutoRun(childrenList) {
|
|
|
|
|
+ for (let i = 0; i < childrenList.length; i++) {
|
|
|
|
|
+ const item = childrenList[i];
|
|
|
|
|
+ if (item.value == 1) {
|
|
|
|
|
+ return true
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ return false
|
|
|
|
|
+ },
|
|
|
|
|
+ async initsfyunshangAutoConfigInfo() {
|
|
|
|
|
+ const selectAreaList = [];
|
|
|
|
|
+ const res = await this.$myRequest({
|
|
|
|
|
+ url:'/api/v2/iot/device/sf/yunshang/auto/config/info/',
|
|
|
|
|
+ method:'post',
|
|
|
|
|
+ data: {
|
|
|
|
|
+ devBid: String(this.devBid),
|
|
|
|
|
+ },
|
|
|
|
|
+ })
|
|
|
|
|
+ const list = res;
|
|
|
|
|
+ const group_list = list.group_list || [];
|
|
|
|
|
+ group_list.forEach((item) => {
|
|
|
|
|
+ if (item.group_value == 1) {
|
|
|
|
|
+ selectAreaList.push(item);
|
|
|
|
|
+ }
|
|
|
|
|
+ });
|
|
|
|
|
+ this.selectAreaList = selectAreaList;
|
|
|
|
|
+ },
|
|
|
|
|
+ async devctlContorl(data){
|
|
|
|
|
+ const params = {
|
|
|
|
|
+ devBid: Number(this.devBid),
|
|
|
|
|
+ data,
|
|
|
|
|
+ };
|
|
|
|
|
+ const res = await this.$myRequest({
|
|
|
|
|
+ url: '/api/v2/iot/mobile/device/sf/devctl/',
|
|
|
|
|
+ method: 'post',
|
|
|
|
|
+ data:params,
|
|
|
|
|
+ header: {
|
|
|
|
|
+ 'Content-Type': 'application/json',
|
|
|
|
|
+ },
|
|
|
|
|
+ });
|
|
|
|
|
+ uni.showToast({
|
|
|
|
|
+ title: res.msg,
|
|
|
|
|
+ icon: 'none',
|
|
|
|
|
+ });
|
|
|
|
|
+ },
|
|
|
|
|
+ changeActive(active) {
|
|
|
|
|
+ this.runStatus = active;
|
|
|
|
|
+ const params = {
|
|
|
|
|
+ IrrStatus:active
|
|
|
|
|
+ }
|
|
|
|
|
+ this.devctlContorl(params);
|
|
|
|
|
+ },
|
|
|
|
|
+ changeMode(mode) {
|
|
|
|
|
+ if(this.runStatus == '1' || this.runStatus == '2'){
|
|
|
|
|
+ uni.showToast({
|
|
|
|
|
+ title: '请先停止运行',
|
|
|
|
|
+ icon: 'none',
|
|
|
|
|
+ });
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+ this.currentMode = mode;
|
|
|
|
|
+ const params = {
|
|
|
|
|
+ IrrMode:mode
|
|
|
|
|
+ }
|
|
|
|
|
+ this.devctlContorl(params);
|
|
|
|
|
+ },
|
|
|
|
|
+ initWebSocket() {
|
|
|
|
|
+ const url = 'wss://things.ysiot.net:18080/api/ws';
|
|
|
|
|
+ this.ws = uni.connectSocket({
|
|
|
|
|
+ url: url,
|
|
|
|
|
+ success: () => {
|
|
|
|
|
+ console.log('WebSocket 连接初始化成功');
|
|
|
|
|
+ }
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ uni.onSocketOpen(() => {
|
|
|
|
|
+ console.log('WebSocket 已连接');
|
|
|
|
|
+ // 发送测试参数
|
|
|
|
|
+ const testParams = {
|
|
|
|
|
+ cmds: [
|
|
|
|
|
+ {
|
|
|
|
|
+ type: 'TIMESERIES',
|
|
|
|
|
+ entityType: 'DEVICE',
|
|
|
|
|
+ entityId: this.entityId,
|
|
|
|
|
+ scope: 'LATEST_TELEMETRY',
|
|
|
|
|
+ cmdId: 1
|
|
|
|
|
+ }
|
|
|
|
|
+ ],
|
|
|
|
|
+ authCmd: {
|
|
|
|
|
+ cmdId: 0,
|
|
|
|
|
+ token: this.sfToken,
|
|
|
|
|
+ }
|
|
|
|
|
+ };
|
|
|
|
|
+ console.log('发送测试参数:', testParams);
|
|
|
|
|
+ uni.sendSocketMessage({
|
|
|
|
|
+ data: JSON.stringify(testParams)
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ // 心跳:每 30 秒 ping 一次
|
|
|
|
|
+ this.heartbeatTimer = setInterval(() => {
|
|
|
|
|
+ uni.sendSocketMessage({
|
|
|
|
|
+ data: JSON.stringify({ type: 'ping' })
|
|
|
|
|
+ });
|
|
|
|
|
+ }, 30 * 1000);
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ uni.onSocketMessage((evt) => {
|
|
|
|
|
+ try {
|
|
|
|
|
+ const data = JSON.parse(evt.data);
|
|
|
|
|
+ this.webSockedData = data;
|
|
|
|
|
+ // 收到实时数据后刷新右侧组件
|
|
|
|
|
+ if(this.dataArray.length){
|
|
|
|
|
+ this.mergeTwoObject(this.dataArray,this.webSockedData?.data);
|
|
|
|
|
+ this.initData(this.dataArray);
|
|
|
|
|
+ }
|
|
|
|
|
+ } catch (e) {
|
|
|
|
|
+ console.error('WebSocket 消息解析失败', e);
|
|
|
|
|
+ }
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ uni.onSocketError((e) => {
|
|
|
|
|
+ console.error('WebSocket 错误', e);
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ uni.onSocketClose(() => {
|
|
|
|
|
+ console.warn('WebSocket 已断开,3 秒后尝试重连');
|
|
|
|
|
+ clearInterval(this.heartbeatTimer);
|
|
|
|
|
+ this.reconnectCount = (this.reconnectCount || 0) + 1;
|
|
|
|
|
+ if (this.reconnectCount <= 10) {
|
|
|
|
|
+ setTimeout(() => this.initWebSocket(), 3000);
|
|
|
|
|
+ } else {
|
|
|
|
|
+ console.warn('WebSocket 重连次数已达上限,停止重连');
|
|
|
|
|
+ }
|
|
|
|
|
+ });
|
|
|
|
|
+ },
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+ mergeTwoObject(firstObject, secondObject) {
|
|
|
|
|
+ // 构建 sfCode 到对象的映射,实现 O(1) 查找
|
|
|
|
|
+ const sfCodeMap = new Map();
|
|
|
|
|
+
|
|
|
|
|
+ // 递归构建映射
|
|
|
|
|
+ const buildMap = (items) => {
|
|
|
|
|
+ for (const item of items) {
|
|
|
|
|
+ if (item.sfCode) {
|
|
|
|
|
+ sfCodeMap.set(item.sfCode, item);
|
|
|
|
|
+ }
|
|
|
|
|
+ if (item.childrenList && item.childrenList.length) {
|
|
|
|
|
+ buildMap(item.childrenList);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ buildMap(firstObject);
|
|
|
|
|
+
|
|
|
|
|
+ // 遍历 secondObject 并更新值
|
|
|
|
|
+ for (const key in secondObject) {
|
|
|
|
|
+ let newKey = '';
|
|
|
|
|
+ if(key.includes('GHChannelDev:ChannelParamSet')){
|
|
|
|
|
+ newKey = key + ':Status';
|
|
|
|
|
+ const item = sfCodeMap.get(newKey);
|
|
|
|
|
+ if (item) {
|
|
|
|
|
+ const params = JSON.parse(secondObject[key][0][1]);
|
|
|
|
|
+ this.$set(item,'value',params.Status)
|
|
|
|
|
+ }
|
|
|
|
|
+ }else{
|
|
|
|
|
+ const item = sfCodeMap.get(key);
|
|
|
|
|
+ if (item) {
|
|
|
|
|
+ this.$set(item,'value',secondObject[key][0][1])
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ },
|
|
|
|
|
+ // 关闭 WebSocket
|
|
|
|
|
+ closeWebSocket() {
|
|
|
|
|
+ clearInterval(this.heartbeatTimer);
|
|
|
|
|
+ if (this.ws) {
|
|
|
|
|
+ uni.closeSocket();
|
|
|
|
|
+ this.ws = null;
|
|
|
|
|
+ }
|
|
|
|
|
+ },
|
|
|
|
|
+ async getsfrhinfo() {
|
|
|
|
|
+ const res = await this.$myRequest({
|
|
|
|
|
+ url: '/api/v2/iot/device/sf/info/',
|
|
|
|
|
+ method: 'post',
|
|
|
|
|
+ data: {
|
|
|
|
|
+ devBid: String(this.devBid),
|
|
|
|
|
+ },
|
|
|
|
|
+ });
|
|
|
|
|
+ this.info = res;
|
|
|
|
|
+ this.sfToken = this.info?.sfToken;
|
|
|
|
|
+ this.entityId = this.info?.sfUuid;
|
|
|
|
|
+ this.closeWebSocket();
|
|
|
|
|
+ this.initWebSocket();
|
|
|
|
|
+ },
|
|
|
|
|
+ async init() {
|
|
|
|
|
+ this.getdeviceSfStatus();
|
|
|
|
|
+ await this.getpeifangRefresh();
|
|
|
|
|
+ this.getsfrhinfo();
|
|
|
|
|
+ this.initsfyunshangAutoConfigInfo();
|
|
|
|
|
+ await this.getRunStatus();
|
|
|
|
|
+ },
|
|
|
|
|
+ async getpeifangRefresh() {
|
|
|
|
|
+ await this.$myRequest({
|
|
|
|
|
+ url: '/api/v2/iot/mobile/device/sf/peifang/refresh/',
|
|
|
|
|
+ method: 'post',
|
|
|
|
|
+ data: {
|
|
|
|
|
+ devBid: this.devBid,
|
|
|
|
|
+ },
|
|
|
|
|
+ });
|
|
|
|
|
+ },
|
|
|
|
|
+ async getRunStatus() {
|
|
|
|
|
+ const res = await this.$myRequest({
|
|
|
|
|
+ url: '/api/v2/iot/mobile/device/sf/zsrf/task/run/status/',
|
|
|
|
|
+ method: 'post',
|
|
|
|
|
+ data: {
|
|
|
|
|
+ devBid: this.devBid,
|
|
|
|
|
+ },
|
|
|
|
|
+ });
|
|
|
|
|
+ const data = JSON.stringify(res || {});
|
|
|
|
|
+
|
|
|
|
|
+ if (data == '{}') {
|
|
|
|
|
+ this.isRun = true;
|
|
|
|
|
+ } else {
|
|
|
|
|
+ this.isRun = false;
|
|
|
|
|
+ }
|
|
|
|
|
+ },
|
|
|
|
|
+ initData(res){
|
|
|
|
|
+ this.dataList = [];
|
|
|
|
|
+ this.irrigatedAreaList = [];
|
|
|
|
|
+ this.alreadyfertilizerBucketList = [];
|
|
|
|
|
+ res?.forEach((item) => {
|
|
|
|
|
+ if (item.sfType === '0') {
|
|
|
|
|
+ this.ggbCurrent = item;
|
|
|
|
|
+ } else if (item.sfType === '1') {
|
|
|
|
|
+ this.sfbCurrent = item;
|
|
|
|
|
+ } else if (item.sfType === '4') {
|
|
|
|
|
+ this.alreadyfertilizerBucketList.push(item);
|
|
|
|
|
+ } else if (item.sfType === '6') {
|
|
|
|
|
+ this.dataList.push(item);
|
|
|
|
|
+ } else if (item.sfType === '7') {
|
|
|
|
|
+ this.irrigatedAreaList.push(item);
|
|
|
|
|
+ } else if (item.sfType === '9') {
|
|
|
|
|
+ if (item.sfCode === 'IrrStatus') {
|
|
|
|
|
+ this.runStatus = item.value;
|
|
|
|
|
+ } else if (item.sfCode === 'IrrMode') {
|
|
|
|
|
+ this.workStatus = item.value;
|
|
|
|
|
+ } else if (item.sfCode === 'WaterFlowSum:Value') {
|
|
|
|
|
+ this.clearIrr = item;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ });
|
|
|
|
|
+ this.runTitle = '--';
|
|
|
|
|
+ this.timer = '--';
|
|
|
|
|
+ if(this.runStatus == '1'){
|
|
|
|
|
+ this.irrigatedAreaList.forEach((item) => {
|
|
|
|
|
+ if (this.isAutoRun(item.childrenList)) {
|
|
|
|
|
+ this.runTitle = item.sfDisplayname || item.sfName;
|
|
|
|
|
+ this.timer = this.isHaveTime(item.childrenList);
|
|
|
|
|
+ }
|
|
|
|
|
+ });
|
|
|
|
|
+ }else{
|
|
|
|
|
+ this.runTitle = '--';
|
|
|
|
|
+ this.timer = '--';
|
|
|
|
|
+ }
|
|
|
|
|
+ },
|
|
|
|
|
+ async getdeviceSfStatus() {
|
|
|
|
|
+ const res = await this.$myRequest({
|
|
|
|
|
+ url: '/api/v2/iot/mobile/device/sf/status/',
|
|
|
|
|
+ method: 'post',
|
|
|
|
|
+ data: {
|
|
|
|
|
+ devBid: this.devBid,
|
|
|
|
|
+ },
|
|
|
|
|
+ });
|
|
|
|
|
+ this.dataArray = res || [];
|
|
|
|
|
+ this.initData(this.dataArray);
|
|
|
|
|
+ },
|
|
|
|
|
+ nativeTo(item) {
|
|
|
|
|
+ if(item.className == 'manualControl'){
|
|
|
|
|
+ if(this.runStatus == '1' || this.runStatus == '2'){
|
|
|
|
|
+ uni.showToast({
|
|
|
|
|
+ title: '请先停止运行',
|
|
|
|
|
+ icon: 'none',
|
|
|
|
|
+ });
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ uni.navigateTo({
|
|
|
|
|
+ url: item.url,
|
|
|
|
|
+ });
|
|
|
|
|
+ },
|
|
|
|
|
+ },
|
|
|
|
|
+};
|
|
|
|
|
+</script>
|
|
|
|
|
+<style scoped lang="scss">
|
|
|
|
|
+uni-page-body {
|
|
|
|
|
+ position: relative;
|
|
|
|
|
+ height: 100%;
|
|
|
|
|
+}
|
|
|
|
|
+.irrMode{
|
|
|
|
|
+ margin-top: 30rpx;
|
|
|
|
|
+ border-radius: 32rpx 32rpx 0 0;
|
|
|
|
|
+ margin-bottom: 30rpx;
|
|
|
|
|
+ padding: 32rpx;
|
|
|
|
|
+ border: 3rpx solid #FFF;
|
|
|
|
|
+ background: linear-gradient(180deg, #D3F3F2 0%, #FFF 41.06%);
|
|
|
|
|
+ .irrMode__header{
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ width:320rpx;
|
|
|
|
|
+ padding:0 10rpx;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ background: #ffffff;
|
|
|
|
|
+ border-radius: 12rpx;
|
|
|
|
|
+ margin-bottom: 24rpx;
|
|
|
|
|
+ font-family: "Source Han Sans CN VF";
|
|
|
|
|
+ font-size: 28rpx;
|
|
|
|
|
+ font-style: normal;
|
|
|
|
|
+ font-weight: 400;
|
|
|
|
|
+ line-height: normal;
|
|
|
|
|
+ color:#999999;
|
|
|
|
|
+ height: 68rpx;
|
|
|
|
|
+ line-height: 68rpx;
|
|
|
|
|
+ view{
|
|
|
|
|
+ width: 160rpx;
|
|
|
|
|
+ text-align: center;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ .active{
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ justify-content: center;
|
|
|
|
|
+ border-radius: 8rpx;
|
|
|
|
|
+ color: #ffffff;
|
|
|
|
|
+ background: #0BBC58;
|
|
|
|
|
+ height: 56rpx;
|
|
|
|
|
+ }
|
|
|
|
|
+ .irrMode__content{
|
|
|
|
|
+ margin-top: 24rpx;
|
|
|
|
|
+ border-radius: 16rpx;
|
|
|
|
|
+ padding: 2rpx;
|
|
|
|
|
+ background: linear-gradient(180deg, #FFF 0%, #F5F6FA 100%);
|
|
|
|
|
+ .irrMode__content-header{
|
|
|
|
|
+ width: calc(100% - 32rpx);
|
|
|
|
|
+ padding: 16rpx 16rpx 16rpx 16rpx;
|
|
|
|
|
+ border-radius: 12rpx;
|
|
|
|
|
+ background: linear-gradient(180deg, #BBF1EA 0%, #E6F4F9 100%);
|
|
|
|
|
+ .irrMode__content-header-list{
|
|
|
|
|
+ display:flex;
|
|
|
|
|
+ justify-content: space-between;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ margin-bottom: 12rpx;
|
|
|
|
|
+ }
|
|
|
|
|
+ .irrMode__content-header-title{
|
|
|
|
|
+ color: #020305;
|
|
|
|
|
+ text-align: right;
|
|
|
|
|
+ font-family: "Source Han Sans CN VF";
|
|
|
|
|
+ font-size: 30rpx;
|
|
|
|
|
+ font-weight: 500;
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ justify-content: space-between;
|
|
|
|
|
+ width: 100%;
|
|
|
|
|
+ .irrMode__content-header-container{
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ }
|
|
|
|
|
+ .header-item-icon{
|
|
|
|
|
+ width: 48rpx;
|
|
|
|
|
+ height: 48rpx;
|
|
|
|
|
+ }
|
|
|
|
|
+ .timer-text{
|
|
|
|
|
+ color: #0bbc58;
|
|
|
|
|
+ text-align: right;
|
|
|
|
|
+ font-family: "Source Han Sans CN VF";
|
|
|
|
|
+ font-size: 28rpx;
|
|
|
|
|
+ font-weight: 400;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ .irrMode__content-header-desc{
|
|
|
|
|
+ color: #999999;
|
|
|
|
|
+ text-align: right;
|
|
|
|
|
+ font-family: "Source Han Sans CN VF";
|
|
|
|
|
+ font-size: 28rpx;
|
|
|
|
|
+ font-weight: 400;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ .irrMode__content-item{
|
|
|
|
|
+ display:flex;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ justify-content: center;
|
|
|
|
|
+ padding: 16rpx 0;
|
|
|
|
|
+ border-radius: 12rpx;
|
|
|
|
|
+ .irrMode__content-item-raduis{
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ height: 88rpx;
|
|
|
|
|
+ padding: 0rpx 32rpx;
|
|
|
|
|
+ flex-direction: column;
|
|
|
|
|
+ justify-content: center;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ flex: 1 0 0;
|
|
|
|
|
+ border-radius: 16rpx;
|
|
|
|
|
+ margin-right: 16rpx;
|
|
|
|
|
+ border: 2rpx solid #0BBC58;
|
|
|
|
|
+ color: #0bbc58;
|
|
|
|
|
+ text-align: right;
|
|
|
|
|
+ font-family: "Source Han Sans CN VF";
|
|
|
|
|
+ font-size: 20rpx;
|
|
|
|
|
+ image{
|
|
|
|
|
+ width: 48rpx;
|
|
|
|
|
+ height: 48rpx;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ .active-radius{
|
|
|
|
|
+ background: #0BBC58;
|
|
|
|
|
+ color:#ffffff;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ .irr-run-list{
|
|
|
|
|
+ padding: 16rpx;
|
|
|
|
|
+ font-family: "Source Han Sans CN VF";
|
|
|
|
|
+ color: #999999;
|
|
|
|
|
+ font-family: "Source Han Sans CN VF";
|
|
|
|
|
+ font-size: 24rpx;
|
|
|
|
|
+ font-weight: 400;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+.online {
|
|
|
|
|
+ height: 32rpx;
|
|
|
|
|
+ line-height: 32rpx;
|
|
|
|
|
+ padding: 0 8rpx;
|
|
|
|
|
+ border-radius: 4rpx;
|
|
|
|
|
+ background: #14a478;
|
|
|
|
|
+ color: #ffffff;
|
|
|
|
|
+ font-family: 'Source Han Sans CN';
|
|
|
|
|
+ font-size: 20rpx;
|
|
|
|
|
+ font-weight: 500;
|
|
|
|
|
+ margin-right: 8rpx;
|
|
|
|
|
+ top: -4rpx;
|
|
|
|
|
+ display:inline-block;
|
|
|
|
|
+ position: relative;
|
|
|
|
|
+}
|
|
|
|
|
+.manualControl{
|
|
|
|
|
+ background: linear-gradient(326deg, #FFAB3D 6.86%, #FED55A 93.52%);
|
|
|
|
|
+}
|
|
|
|
|
+.wheelIrrigation{
|
|
|
|
|
+ background: linear-gradient(152deg, #83D2FF 14.82%, #02A2FC 92.92%);
|
|
|
|
|
+}
|
|
|
|
|
+.timedSetting{
|
|
|
|
|
+ background: linear-gradient(335deg, #0BBC58 6.91%, #60D799 89.95%);
|
|
|
|
|
+}
|
|
|
|
|
+.formulaSetting{
|
|
|
|
|
+ background: linear-gradient(147deg, #FE9797 12.77%, #FF6060 92.63%);
|
|
|
|
|
+}
|
|
|
|
|
+.operatingRecord{
|
|
|
|
|
+ background: linear-gradient(152deg, #B9B9F6 11.22%, #8080F8 94.92%);
|
|
|
|
|
+}
|
|
|
|
|
+.facilitystate-top__title{
|
|
|
|
|
+ overflow: hidden;
|
|
|
|
|
+ white-space: nowrap;
|
|
|
|
|
+ text-overflow: ellipsis;
|
|
|
|
|
+}
|
|
|
|
|
+.offline {
|
|
|
|
|
+ height: 32rpx;
|
|
|
|
|
+ line-height: 32rpx;
|
|
|
|
|
+ padding: 0 8rpx;
|
|
|
|
|
+ border-radius: 4rpx;
|
|
|
|
|
+ background: #ff4d4f;
|
|
|
|
|
+ color: #ffffff;
|
|
|
|
|
+ font-family: 'Source Han Sans CN';
|
|
|
|
|
+ font-size: 20rpx;
|
|
|
|
|
+ font-weight: 500;
|
|
|
|
|
+ margin-right: 8rpx;
|
|
|
|
|
+ top: -4rpx;
|
|
|
|
|
+ display:inline-block;
|
|
|
|
|
+ position: relative;
|
|
|
|
|
+}
|
|
|
|
|
+.facilitystate-page {
|
|
|
|
|
+ background: linear-gradient(180deg, #f5f6fa00 0%, #F5F6FA 23.46%, #FFF 25.24%, #FFF 100%), linear-gradient(102deg, #BFEADD 6.77%, #B8F1E7 40.15%, #B9EEF5 84.02%);
|
|
|
|
|
+ height: 100%;
|
|
|
|
|
+ width: 100%;
|
|
|
|
|
+ overflow-x: hidden;
|
|
|
|
|
+ overflow-y: scroll;
|
|
|
|
|
+ .facilitystate-top {
|
|
|
|
|
+ display: grid;
|
|
|
|
|
+ grid-template-columns: repeat(5, 1fr);
|
|
|
|
|
+ text-align: center;
|
|
|
|
|
+ margin-top: 18rpx;
|
|
|
|
|
+ &__item {
|
|
|
|
|
+ margin-bottom: 32rpx;
|
|
|
|
|
+ .item-icon-container{
|
|
|
|
|
+ width: 96rpx;
|
|
|
|
|
+ height: 96rpx;
|
|
|
|
|
+ border-radius: 26rpx;
|
|
|
|
|
+ overflow: hidden;
|
|
|
|
|
+ margin: 0 auto;
|
|
|
|
|
+ display:flex;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ justify-content: center;
|
|
|
|
|
+ }
|
|
|
|
|
+ .item-icon {
|
|
|
|
|
+ width: 64rpx;
|
|
|
|
|
+ height: 64rpx;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ &__item-text {
|
|
|
|
|
+ color: #042118;
|
|
|
|
|
+ font-family: 'Source Han Sans CN VF';
|
|
|
|
|
+ font-size: 28rpx;
|
|
|
|
|
+ font-weight: 400;
|
|
|
|
|
+ margin-top: 16rpx;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+</style>
|