自动化
parent
b4cd127ff2
commit
8a6ef40cda
5
App.vue
5
App.vue
|
|
@ -257,9 +257,6 @@ export default {
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
// 加上图鸟会全变白
|
// 加上图鸟会全变白
|
||||||
//@import './tuniao-ui/index.scss';
|
@import './tuniao-ui/iconfont.css';
|
||||||
//@import './tuniao-ui/iconfont.css';
|
|
||||||
@import '@/static/scss/index.scss';
|
@import '@/static/scss/index.scss';
|
||||||
//@import "colorui/main.css";
|
|
||||||
//@import "colorui/icon.css";
|
|
||||||
</style>
|
</style>
|
||||||
|
|
|
||||||
13
pages.json
13
pages.json
|
|
@ -67,6 +67,19 @@
|
||||||
"navigationBarTitleText": "控制中心"
|
"navigationBarTitleText": "控制中心"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// ,
|
||||||
|
// {
|
||||||
|
// "path": "control/automatic",
|
||||||
|
// "style": {
|
||||||
|
// "navigationBarTitleText": "自动控制"
|
||||||
|
// }
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// "path": "control/manual",
|
||||||
|
// "style": {
|
||||||
|
// "navigationBarTitleText": "手动控制"
|
||||||
|
// }
|
||||||
|
// }
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
/* {
|
/* {
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -8,191 +8,83 @@
|
||||||
</template>
|
</template>
|
||||||
<view class="card shadow shadow-lg bg-white ">
|
<view class="card shadow shadow-lg bg-white ">
|
||||||
<uni-section :title="`当前大棚:【${selectedText}】`" :subTitle="imei" titleFontSize="20px" type="line" >
|
<uni-section :title="`当前大棚:【${selectedText}】`" :subTitle="imei" titleFontSize="20px" type="line" >
|
||||||
<!-- <view class="uni-px-5 uni-pb-5">-->
|
<template v-slot:right>
|
||||||
<!-- <uni-data-select v-model="value" :localdata="range" @change="change"></uni-data-select>-->
|
<view class="switch-row">
|
||||||
<!-- </view>-->
|
<text class="modal-text">手动</text>
|
||||||
</uni-section>
|
<tn-switch
|
||||||
|
v-model="currentMode"
|
||||||
<uni-divider margin="10rpx 0"></uni-divider>
|
:size="60"
|
||||||
<uni-section title="实时温湿度" titleFontSize="16px" type="line" v-if="value!== 1">
|
|
||||||
<template v-slot:right >
|
|
||||||
{{ temp }}
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<view>
|
|
||||||
<!-- 优化:温度卡片循环渲染 -->
|
|
||||||
<view class="uni-flex_control uni-row" >
|
|
||||||
<view
|
|
||||||
class="text uni-flex_control_one uni-view"
|
|
||||||
v-for="item in sensorCards.temp"
|
|
||||||
:key="item.key"
|
|
||||||
@click="openDataModal(item)"
|
|
||||||
>
|
|
||||||
<text class="data" :style="fontStyle">
|
|
||||||
{{ liveData[item.key] }}
|
|
||||||
<text v-if="isEffectiveValue(liveData[item.key])" class="tempStyle">℃</text>
|
|
||||||
</text>
|
|
||||||
<text class="data" v-if="dtu_remark[item.key]">{{ dtu_remark[item.key] }}</text>
|
|
||||||
<text class="data" v-else>{{ item.label }}</text>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
|
|
||||||
<!-- 优化:湿度卡片循环渲染 -->
|
|
||||||
<view class="uni-flex_control uni-row" >
|
|
||||||
<view
|
|
||||||
class="text uni-flex_control_two uni-view"
|
|
||||||
v-for="item in sensorCards.humi"
|
|
||||||
:key="item.key"
|
|
||||||
@click="openDataModal(item)"
|
|
||||||
>
|
|
||||||
<text class="data" :style="fontStyle">
|
|
||||||
{{ liveData[item.key] }}
|
|
||||||
<text v-if="isEffectiveValue(liveData[item.key])" class="humiStyle"> %RH</text>
|
|
||||||
</text>
|
|
||||||
<text class="data" v-if="dtu_remark[item.key]">{{ dtu_remark[item.key] }}</text>
|
|
||||||
<text class="data" v-else>{{ item.label }}</text>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</uni-section>
|
|
||||||
|
|
||||||
<uni-section title="设备控制" titleFontSize="16px" type="line" v-if="value!== 1 && !['862538065276939','A','B','C'].includes(imei)">
|
|
||||||
<template v-slot:right >
|
|
||||||
{{ control }}
|
|
||||||
</template>
|
|
||||||
<!-- 优化:设备卡片循环渲染 -->
|
|
||||||
<view class="card-grid">
|
|
||||||
<view
|
|
||||||
class="control-card"
|
|
||||||
v-for="card in deviceCards"
|
|
||||||
:key="card.type"
|
|
||||||
@click="openTimeModal(card)"
|
|
||||||
>
|
|
||||||
<view class="card-text">
|
|
||||||
<text class="card-main" v-if="dtu_remark[card.type]">{{ dtu_remark[card.type] }}</text>
|
|
||||||
<text class="card-main" v-else>{{ card.name }}</text>
|
|
||||||
<view class="card-sub-wrapper">
|
|
||||||
<text class="card-sub" v-if="showStatusText">{{ show[card.type] || '未知' }}</text>
|
|
||||||
<text class="limit-time">
|
|
||||||
运行时间:{{ limitTimes[`${card.type}Limit`] && limitTimes[`${card.type}Limit`]!=='0' ? `${limitTimes[`${card.type}Limit`]} s` : '- -' }}
|
|
||||||
</text>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
<view v-if="showFlag" class="card-icon" :class="{ active: status[card.type] === 1 }" @click.stop="handleCardClick(1 - status[card.type], card.type)">
|
|
||||||
<!-- 加@click.stop防止冒泡触发卡片点击的弹窗事件 -->
|
|
||||||
<uni-icons
|
|
||||||
:type="status[card.type] === 1 ? 'circle' : 'circle-filled'"
|
|
||||||
size="24"
|
|
||||||
color="#fff"
|
|
||||||
/>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</uni-section>
|
|
||||||
</view>
|
|
||||||
|
|
||||||
<uni-popup ref="inputNamelog" mode="center" >
|
|
||||||
<!-- 新增:修改运行时间的弹窗 -->
|
|
||||||
<view class="modal-container">
|
|
||||||
<view class="modal-title">{{ `【${selectedText} - 实时温湿度】别名设置` }}</view>
|
|
||||||
<view class="modal-input-wrap" >
|
|
||||||
<text class="modal-label">别名设置:</text>
|
|
||||||
<uni-easyinput style="width: 100px" v-model="remark" placeholder="不填展示默认备注" />
|
|
||||||
</view>
|
|
||||||
<view class="modal-btn-wrap">
|
|
||||||
<button class="modal-btn cancel" @click="closeModalDataName">取消</button>
|
|
||||||
<button class="modal-btn confirm" @click="confirmModifyName">确定</button>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</uni-popup>
|
|
||||||
|
|
||||||
<uni-popup ref="inputDialog" mode="center" >
|
|
||||||
<!-- 新增:修改运行时间的弹窗 -->
|
|
||||||
<view class="modal-container">
|
|
||||||
<view class="modal-title">{{ `【${selectedText} - ${currentCard.name}】设置` }}</view>
|
|
||||||
<view class="modal-input-wrap">
|
|
||||||
<text class="modal-label">当前时间:</text>
|
|
||||||
<text class="modal-current">{{ currentCardTime>0 ? `${currentCardTime} 秒` : '未设置' }}</text>
|
|
||||||
</view>
|
|
||||||
<view class="modal-input-wrap" >
|
|
||||||
<text class="modal-label">修改后时间:</text>
|
|
||||||
<input
|
|
||||||
class="modal-input"
|
|
||||||
type="number"
|
|
||||||
v-model.number="newLimitTime"
|
|
||||||
/>
|
/>
|
||||||
<!-- <uni-number-box v-model="newLimitTime" />-->
|
<text class="modal-text">自动</text>
|
||||||
<text class="modal-unit">秒</text>
|
|
||||||
</view>
|
</view>
|
||||||
|
</template>
|
||||||
|
</uni-section>
|
||||||
|
<uni-divider margin="10rpx 0"></uni-divider>
|
||||||
|
|
||||||
<view class="modal-input-wrap" >
|
<!-- 把解析好的完整数据传给子组件 -->
|
||||||
<text class="modal-label">别名设置:</text>
|
<auto-page
|
||||||
<uni-easyinput style="width: 100px" v-model="remark" placeholder="不填展示默认备注" />
|
v-if="currentMode === true"
|
||||||
</view>
|
value="0"
|
||||||
<view class="modal-btn-wrap">
|
/>
|
||||||
<button class="modal-btn cancel" @click="close">取消</button>
|
<manual-page
|
||||||
<button class="modal-btn confirm" @click="confirmModifyTime">确定</button>
|
ref="manualPage"
|
||||||
</view>
|
v-else-if="currentMode === false"
|
||||||
</view>
|
:liveData="liveData"
|
||||||
</uni-popup>
|
:show="show"
|
||||||
|
:status="status"
|
||||||
|
:dtu_remark="dtu_remark"
|
||||||
|
:selectedText="selectedText"
|
||||||
|
:value="value"
|
||||||
|
:agriId="agriId"
|
||||||
|
@publicMsg="publishMessage"
|
||||||
|
@getRemark="getRemarkByImei"
|
||||||
|
/>
|
||||||
|
</view>
|
||||||
</z-paging>
|
</z-paging>
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
// 优化:抽离魔法值常量
|
// 优化:抽离魔法值常量
|
||||||
import UniPopupDialog from "../../../uni_modules/uni-popup/components/uni-popup-dialog/uni-popup-dialog.vue";
|
import ManualPage from "./manual.vue"
|
||||||
|
import AutoPage from "./automatic.vue"
|
||||||
const SENSOR_MAP = {
|
const SENSOR_MAP = {
|
||||||
temp1: "201", temp2: "202", temp3: "203", temp4: "204",
|
temp1: "201", temp2: "202", temp3: "203", temp4: "204",
|
||||||
humi1: "101", humi2: "102", humi3: "103", humi4: "104"
|
humi1: "101", humi2: "102", humi3: "103", humi4: "104"
|
||||||
};
|
};
|
||||||
const MQTT_TOPIC_SUFFIX = { UP: "/+", DOWN: "/control" };
|
const MQTT_TOPIC_SUFFIX = { UP: "/+", DOWN: "/control" };
|
||||||
|
|
||||||
import UniDatetimePicker from "../../../uni_modules/uni-datetime-picker/components/uni-datetime-picker/uni-datetime-picker.vue";
|
|
||||||
import UniPopup from "../../../uni_modules/uni-popup/components/uni-popup/uni-popup.vue"; // 引入弹窗组件
|
|
||||||
import { findDtuDataByInfo } from "@/api/system/data";
|
|
||||||
import mqttUtil from '@/utils/mqtt';
|
import mqttUtil from '@/utils/mqtt';
|
||||||
import UniNumberBox from "../../../uni_modules/uni-number-box/components/uni-number-box/uni-number-box.vue";
|
|
||||||
import {addLimit, getAgriByImei, updateLimit} from "../../../api/system/assets/limit";
|
|
||||||
import {listAgri} from "../../../api/system/assets/agri";
|
import {listAgri} from "../../../api/system/assets/agri";
|
||||||
import {getNewSpecialData} from "../../../api/data/specialData";
|
import {getNewSpecialData} from "../../../api/data/specialData";
|
||||||
import store from "../../../store";
|
import store from "../../../store";
|
||||||
import {addRemark, getRemarkByImei, updateRemark} from "../../../api/system/assets/remark";
|
import {getRemarkByImei} from "../../../api/system/assets/remark";
|
||||||
import CustomRefresher from "../../../components/custom-refresher/custom-refresher.vue";
|
import CustomRefresher from "../../../components/custom-refresher/custom-refresher.vue";
|
||||||
import ZPaging from "../../../uni_modules/z-paging/components/z-paging/z-paging.vue";
|
import ZPaging from "../../../uni_modules/z-paging/components/z-paging/z-paging.vue";
|
||||||
|
import {findDtuDataByInfo} from "../../../api/system/data";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
dicts: ['sys_data_map'],
|
dicts: ['sys_data_map'],
|
||||||
components: {
|
components: {
|
||||||
ZPaging,
|
ZPaging,
|
||||||
UniNumberBox,
|
|
||||||
UniPopupDialog,
|
|
||||||
UniDatetimePicker,
|
|
||||||
CustomRefresher,
|
CustomRefresher,
|
||||||
UniPopup // 注册弹窗组件
|
ManualPage,
|
||||||
|
AutoPage,
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
showFlag:true,
|
currentMode:false,
|
||||||
temp: "",
|
|
||||||
mqttConfig: {
|
mqttConfig: {
|
||||||
subscribeTopic:'/listener',
|
subscribeTopic:'/listener',
|
||||||
},
|
},
|
||||||
value: 1,
|
value: 1,
|
||||||
selectedText: '',
|
selectedText: '',
|
||||||
// 优化:语义化变量名(替换原 hide: false)
|
|
||||||
showStatusText: false,
|
|
||||||
control: '正在加载中...',
|
|
||||||
// range: [],
|
// range: [],
|
||||||
agriId:'',
|
agriId:'',
|
||||||
imei:'',
|
imei:'',
|
||||||
publishTopic: '/control',
|
publishTopic: '/control',
|
||||||
title:'',
|
|
||||||
message: {},
|
|
||||||
// 优化:声明响应式变量 connected
|
// 优化:声明响应式变量 connected
|
||||||
connected: false,
|
connected: false,
|
||||||
remark:'',
|
|
||||||
dtu_remark:{},
|
dtu_remark:{},
|
||||||
liveData: {
|
liveData: {
|
||||||
temp1: '数据加载中...',
|
temp1: '数据加载中...',
|
||||||
|
|
@ -202,37 +94,9 @@ export default {
|
||||||
humi1: '数据加载中...',
|
humi1: '数据加载中...',
|
||||||
humi2: '数据加载中...',
|
humi2: '数据加载中...',
|
||||||
humi3: '数据加载中...',
|
humi3: '数据加载中...',
|
||||||
humi4: '数据加载中...'
|
humi4: '数据加载中...',
|
||||||
|
temp: "正在加载中..."
|
||||||
},
|
},
|
||||||
// 优化:温湿度卡片配置(固定顺序:温度1→2→3→4,湿度1→2→3→4)
|
|
||||||
sensorCards: {
|
|
||||||
temp: [
|
|
||||||
{ label: '温度1', key: 'temp1' },
|
|
||||||
{ label: '温度2', key: 'temp2' },
|
|
||||||
{ label: '温度3', key: 'temp3' },
|
|
||||||
{ label: '温度4', key: 'temp4' }
|
|
||||||
],
|
|
||||||
humi: [
|
|
||||||
{ label: '湿度1', key: 'humi1' },
|
|
||||||
{ label: '湿度2', key: 'humi2' },
|
|
||||||
{ label: '湿度3', key: 'humi3' },
|
|
||||||
{ label: '湿度4', key: 'humi4' }
|
|
||||||
]
|
|
||||||
},
|
|
||||||
sensorCard:{},
|
|
||||||
// 优化:设备卡片配置(固定顺序)
|
|
||||||
deviceCards: [
|
|
||||||
{ type: 'jbk', name: '卷被开' },
|
|
||||||
{ type: 'jbg', name: '卷被关' },
|
|
||||||
{ type: 'jm1k', name: '卷膜1开' },
|
|
||||||
{ type: 'jm1g', name: '卷膜1关' },
|
|
||||||
{ type: 'jm2k', name: '卷膜2开' },
|
|
||||||
{ type: 'jm2g', name: '卷膜2关' },
|
|
||||||
{ type: 'jm3k', name: '卷膜3开' },
|
|
||||||
{ type: 'jm3g', name: '卷膜3关' },
|
|
||||||
{ type: 'jlk', name: '卷帘开' },
|
|
||||||
{ type: 'jlg', name: '卷帘关' },
|
|
||||||
],
|
|
||||||
// 卡片状态
|
// 卡片状态
|
||||||
show: {
|
show: {
|
||||||
jbk: "暂停",
|
jbk: "暂停",
|
||||||
|
|
@ -246,19 +110,6 @@ export default {
|
||||||
jm3k: "暂停",
|
jm3k: "暂停",
|
||||||
jm3g: "暂停"
|
jm3g: "暂停"
|
||||||
},
|
},
|
||||||
// 新增:限位时间配置
|
|
||||||
limitTimes: {
|
|
||||||
jbkLimit: 0,
|
|
||||||
jbgLimit: 0,
|
|
||||||
jlkLimit: 0,
|
|
||||||
jlgLimit: 0,
|
|
||||||
jm1kLimit: 0,
|
|
||||||
jm1gLimit: 0,
|
|
||||||
jm2kLimit: 0,
|
|
||||||
jm2gLimit: 0,
|
|
||||||
jm3kLimit: 0,
|
|
||||||
jm3gLimit: 0
|
|
||||||
},
|
|
||||||
status: {
|
status: {
|
||||||
jbk: 0,
|
jbk: 0,
|
||||||
jbg: 0,
|
jbg: 0,
|
||||||
|
|
@ -269,14 +120,10 @@ export default {
|
||||||
jm2k: 0,
|
jm2k: 0,
|
||||||
jm2g: 0,
|
jm2g: 0,
|
||||||
jm3k: 0,
|
jm3k: 0,
|
||||||
jm3g: 0
|
jm3g: 0,
|
||||||
|
deviceTime:"正在加载中..."
|
||||||
},
|
},
|
||||||
testMsg:'由于线上为真实数据。任何操作均可影响线上功能,故仅作演示',
|
testMsg:'由于线上为真实数据。任何操作均可影响线上功能,故仅作演示',
|
||||||
fontStyle: '',
|
|
||||||
// 新增:弹窗相关变量
|
|
||||||
currentCard: {}, // 当前点击的卡片信息
|
|
||||||
currentCardTime: '', // 当前卡片的运行时间
|
|
||||||
newLimitTime: 0, // 新的运行时间
|
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
onLoad(option) {
|
onLoad(option) {
|
||||||
|
|
@ -288,8 +135,6 @@ export default {
|
||||||
this.agriId = agriInfo.agriId;
|
this.agriId = agriInfo.agriId;
|
||||||
this.change(this.value)
|
this.change(this.value)
|
||||||
}
|
}
|
||||||
|
|
||||||
this.title="";
|
|
||||||
// 定义所有互斥的键对:[k键, g键]
|
// 定义所有互斥的键对:[k键, g键]
|
||||||
const mutexPairs = [
|
const mutexPairs = [
|
||||||
['jbk', 'jbg'],
|
['jbk', 'jbg'],
|
||||||
|
|
@ -311,7 +156,6 @@ export default {
|
||||||
mqttUtil.setOnMessageCallback(this.ackMessage);
|
mqttUtil.setOnMessageCallback(this.ackMessage);
|
||||||
// 更新连接状态
|
// 更新连接状态
|
||||||
this.connected = mqttUtil.getMqttState().isConnected;
|
this.connected = mqttUtil.getMqttState().isConnected;
|
||||||
this.showFlag = !((store.getters && store.getters.name !== 'admin') && this.$auth.hasRole("test"))
|
|
||||||
},
|
},
|
||||||
onUnload() {
|
onUnload() {
|
||||||
// 移除MQTT消息回调(避免内存泄漏)
|
// 移除MQTT消息回调(避免内存泄漏)
|
||||||
|
|
@ -323,12 +167,13 @@ export default {
|
||||||
this.change(this.imei)
|
this.change(this.imei)
|
||||||
mqttUtil.setOnMessageCallback(this.ackMessage);
|
mqttUtil.setOnMessageCallback(this.ackMessage);
|
||||||
this.$refs.paging.complete();
|
this.$refs.paging.complete();
|
||||||
|
this.$refs.manualPage.refresh();
|
||||||
},
|
},
|
||||||
getNewSpecialData() {
|
getNewSpecialData() {
|
||||||
getNewSpecialData().then(response => {
|
getNewSpecialData().then(response => {
|
||||||
if (response.code === 200 && response.data) {
|
if (response.code === 200 && response.data) {
|
||||||
this.makeSpecialData(response.data,false);
|
this.makeSpecialData(response.data,false);
|
||||||
this.temp = "最后更新时间:"+response.data.time;
|
this.liveData.temp = "最后更新时间:"+response.data.time;
|
||||||
this.fontStyle = 'font-size:16px;'
|
this.fontStyle = 'font-size:16px;'
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
@ -338,15 +183,11 @@ export default {
|
||||||
var clientId = mqttUtil.getMqttState().clientId;
|
var clientId = mqttUtil.getMqttState().clientId;
|
||||||
this.connected = mqttUtil.getMqttState().isConnected;
|
this.connected = mqttUtil.getMqttState().isConnected;
|
||||||
if ((e === 'A' || e==='B' || e==='C')
|
if ((e === 'A' || e==='B' || e==='C')
|
||||||
&& store.getters && store.getters.name === 'admin' ) {
|
&& store.getters && store.getters.name === 'admin'
|
||||||
|
&& this.currentMode===false) {
|
||||||
this.getNewSpecialData(e);
|
this.getNewSpecialData(e);
|
||||||
this.mqttConfig.subscribeTopic = `frontend/${clientId}/dtu/862538065276061`;
|
this.mqttConfig.subscribeTopic = `frontend/${clientId}/dtu/862538065276061`;
|
||||||
}
|
}
|
||||||
// const selectedItem = this.range.find(item => item.value === e);
|
|
||||||
// if (selectedItem) {
|
|
||||||
// this.selectedText = selectedItem.text; // 获取展示文本
|
|
||||||
// this.agriId = selectedItem.agriId;
|
|
||||||
// this.title= this.selectedText;
|
|
||||||
if (e !== 'A' && e!=='B' && e!=='C') {
|
if (e !== 'A' && e!=='B' && e!=='C') {
|
||||||
// 优化:使用常量拼接MQTT主题
|
// 优化:使用常量拼接MQTT主题
|
||||||
this.publishTopic = `frontend/${clientId}${MQTT_TOPIC_SUFFIX.DOWN}/${this.imei}`;
|
this.publishTopic = `frontend/${clientId}${MQTT_TOPIC_SUFFIX.DOWN}/${this.imei}`;
|
||||||
|
|
@ -359,24 +200,17 @@ export default {
|
||||||
Object.keys(response.data).forEach(key => {
|
Object.keys(response.data).forEach(key => {
|
||||||
this.liveData[key] = response.data[key] || '已离线..';
|
this.liveData[key] = response.data[key] || '已离线..';
|
||||||
});
|
});
|
||||||
this.temp = "最后更新时间:"+response.data.time;
|
this.liveData.temp = "最后更新时间:"+response.data.time;
|
||||||
this.fontStyle = 'font-size:16px;'
|
this.fontStyle = 'font-size:16px;'
|
||||||
})
|
})
|
||||||
// 限位
|
|
||||||
this.getAgriByImei();
|
|
||||||
// 备注
|
// 备注
|
||||||
this.getRemarkByImei();
|
this.getRemarkByImei();
|
||||||
if (e!=="862538065276939"){
|
if (e!=="862538065276939"){
|
||||||
this.message=JSON.stringify({jbk: 0,read:true})
|
const message = JSON.stringify({jbk: 0,read:true})
|
||||||
this.publishMessage()
|
this.publishMessage(message)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// } else {
|
|
||||||
// this.selectedText = ''; // 无匹配项时清空
|
|
||||||
// this.title='';
|
|
||||||
// this.value=1;
|
|
||||||
// this.agriId = '';
|
|
||||||
// }
|
|
||||||
this.reset();
|
this.reset();
|
||||||
this.style="";
|
this.style="";
|
||||||
},
|
},
|
||||||
|
|
@ -387,16 +221,7 @@ export default {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
getAgriByImei() {
|
|
||||||
getAgriByImei(this.imei).then(response => {
|
|
||||||
if (response.code === 200) {
|
|
||||||
if (!response.data) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.limitTimes = response.data;
|
|
||||||
}
|
|
||||||
})
|
|
||||||
},
|
|
||||||
getAgriList() {
|
getAgriList() {
|
||||||
listAgri().then(response => {
|
listAgri().then(response => {
|
||||||
if (response.code === 200) {
|
if (response.code === 200) {
|
||||||
|
|
@ -469,106 +294,44 @@ export default {
|
||||||
|| "已离线..."
|
|| "已离线..."
|
||||||
])
|
])
|
||||||
);
|
);
|
||||||
|
this.liveData.temp = "最后更新时间:" + this.getCurrentTime();
|
||||||
},
|
},
|
||||||
reset() {
|
reset() {
|
||||||
Object.keys(this.show).forEach(key => {
|
Object.keys(this.show).forEach(key => {
|
||||||
this.show[key] = "暂停";
|
this.show[key] = "暂停";
|
||||||
});
|
});
|
||||||
Object.keys(this.status).forEach(key => {
|
Object.keys(this.status).forEach(key => {
|
||||||
|
if (key === "deviceTime") {
|
||||||
|
this.status[key] = '正在加载中...';
|
||||||
|
return;
|
||||||
|
}
|
||||||
this.status[key] = 0;
|
this.status[key] = 0;
|
||||||
});
|
});
|
||||||
Object.keys(this.liveData).forEach(key => {
|
Object.keys(this.liveData).forEach(key => {
|
||||||
|
if (key==="temp") {
|
||||||
|
this.liveData[key] = '正在加载中...';
|
||||||
|
return;
|
||||||
|
}
|
||||||
this.liveData[key] = '数据加载中...';
|
this.liveData[key] = '数据加载中...';
|
||||||
});
|
});
|
||||||
Object.keys(this.limitTimes).forEach(key => {
|
|
||||||
this.limitTimes[key] = 0;
|
|
||||||
});
|
|
||||||
this.control = '正在加载中...';
|
|
||||||
this.message = {};
|
|
||||||
this.temp = '';
|
|
||||||
},
|
},
|
||||||
// 卡片点击事件(实际项目中调用接口修改状态) 功能标识
|
|
||||||
handleCardClick(status, type) {
|
|
||||||
const funcMsg = "该功能用来开启或暂停设备,按钮亮为开启,按钮暗为暂停设备"
|
|
||||||
if ((store.getters && store.getters.name !== 'admin')
|
|
||||||
&& this.$auth.hasRole("test")) {
|
|
||||||
// this.testFunction(`${this.testMsg}\n${funcMsg}`)
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// 校验
|
|
||||||
// 定义类型与提示文案的映射关系,减少重复代码
|
|
||||||
const tipMap = {
|
|
||||||
'jbk': {opposite: 'jbg', name: '卷被关', op: '卷被开'},
|
|
||||||
'jbg': {opposite: 'jbk', name: '卷被开', op: '卷被关'},
|
|
||||||
'jlk': {opposite: 'jlg', name: '卷帘关', op: '卷帘开'},
|
|
||||||
'jlg': {opposite: 'jlk', name: '卷帘开', op: '卷帘关'},
|
|
||||||
'jm1k': {opposite: 'jm1g', name: '卷膜1关', op: '卷膜1开'},
|
|
||||||
'jm1g': {opposite: 'jm1k', name: '卷膜1开', op: '卷膜1关'},
|
|
||||||
'jm2k': {opposite: 'jm2g', name: '卷膜2关', op: '卷膜2开'},
|
|
||||||
'jm2g': {opposite: 'jm2k', name: '卷膜2开', op: '卷膜2关'},
|
|
||||||
'jm3k': {opposite: 'jm3g', name: '卷膜3关', op: '卷膜3开'},
|
|
||||||
'jm3g': {opposite: 'jm3k', name: '卷膜3开', op: '卷膜3关'}
|
|
||||||
};
|
|
||||||
|
|
||||||
// 先判断类型是否在映射表中,避免无效case
|
|
||||||
if (!tipMap[type]) return;
|
|
||||||
|
|
||||||
const {opposite, name, op} = tipMap[type];
|
|
||||||
// 核心校验逻辑(只写一次,无需重复)
|
|
||||||
if (status === 1 && this.status[opposite] === 1) {
|
|
||||||
this.$modal.msgError(`【${this.selectedText}】${name}在运行状态,不能运行${op}操作!`);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ========== 修改:从全局工具类获取连接状态 ==========
|
|
||||||
this.connected = mqttUtil.getMqttState().isConnected;
|
|
||||||
if (!this.connected) {
|
|
||||||
this.$modal.msgError("设备连接异常");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (this.value === 1) {
|
|
||||||
this.$modal.msgError("设备控制失败!");
|
|
||||||
console.info("大棚选取失败!")
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
uni.showModal({
|
|
||||||
title: '操作提示:',
|
|
||||||
content: '确定' + (status === 1 ? "运行" : "暂停") + '【' + this.selectedText + '】设备?',
|
|
||||||
cancelText: '取消',
|
|
||||||
confirmText: '确定',
|
|
||||||
success: (res) => {
|
|
||||||
if (res.confirm) {
|
|
||||||
// 组装消息
|
|
||||||
this.message = JSON.stringify({[`${type}1`]: status})
|
|
||||||
// 控制设备
|
|
||||||
this.publishMessage();
|
|
||||||
//todo
|
|
||||||
// this.testAuto(type);
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
},
|
|
||||||
|
|
||||||
// 测试专用
|
// 测试专用
|
||||||
testAuto(type) {
|
testAuto(type) {
|
||||||
this.$set(this.status, type, this.status[type] === 0 ? 1 : 0);
|
this.$set(this.status, type, this.status[type] === 0 ? 1 : 0);
|
||||||
this.$set(this.show, type, this.status[type] === 0 ? "暂停" : "运行");
|
this.$set(this.show, type, this.status[type] === 0 ? "暂停" : "运行");
|
||||||
},
|
},
|
||||||
publishMessage() {
|
publishMessage(message) {
|
||||||
if (!this.connected || !this.publishTopic || !this.message) {
|
if (!this.connected || !this.publishTopic || !message) {
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// 调用全局MQTT工具类发布消息
|
// 调用全局MQTT工具类发布消息
|
||||||
const publishSuccess = mqttUtil.publishMqtt(this.publishTopic, this.message);
|
const publishSuccess = mqttUtil.publishMqtt(this.publishTopic, message);
|
||||||
if (publishSuccess) {
|
if (publishSuccess) {
|
||||||
this.addMessage(`【指令已发送】imei: ${this.publishTopic},指令: ${this.message}`);
|
this.addMessage(`【指令已发送】imei: ${this.publishTopic},指令: ${message}`);
|
||||||
} else {
|
} else {
|
||||||
this.addMessage(`发布失败:设备:[${this.publishTopic}]`)
|
this.addMessage(`发布失败:设备:[${this.publishTopic}]`)
|
||||||
}
|
}
|
||||||
this.message = {};
|
|
||||||
},
|
},
|
||||||
|
|
||||||
// 消息回调逻辑完全保留(仅依赖全局工具类转发消息)
|
// 消息回调逻辑完全保留(仅依赖全局工具类转发消息)
|
||||||
|
|
@ -641,13 +404,12 @@ export default {
|
||||||
const value = msgData[key];
|
const value = msgData[key];
|
||||||
this.show[key] = value === 0 ? '暂停' : '运行';
|
this.show[key] = value === 0 ? '暂停' : '运行';
|
||||||
});
|
});
|
||||||
this.control = '最后更新时间:' + this.getCurrentTime();
|
this.status.deviceTime = '最后更新时间:' + this.getCurrentTime();
|
||||||
}
|
}
|
||||||
|
if (this.currentMode) return;
|
||||||
const allKeysNumeric2 = Object.keys(msgData).every(key => /^\d+$/.test(key));
|
const allKeysNumeric2 = Object.keys(msgData).every(key => /^\d+$/.test(key));
|
||||||
if (Object.keys(msgData).length > 0 && allKeysNumeric2) {
|
if (Object.keys(msgData).length > 0 && allKeysNumeric2) {
|
||||||
this.temp = "最后更新时间:" + this.getCurrentTime();
|
|
||||||
this.fontStyle = 'font-size:16px;'
|
this.fontStyle = 'font-size:16px;'
|
||||||
|
|
||||||
this.makeSpecialData(msgData, true);
|
this.makeSpecialData(msgData, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -674,220 +436,6 @@ export default {
|
||||||
return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
|
return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
|
||||||
},
|
},
|
||||||
|
|
||||||
testNumber(data) {
|
|
||||||
const reg = /^-?\d+(\.\d+)?$/;
|
|
||||||
return reg.test(String(data).trim());
|
|
||||||
},
|
|
||||||
|
|
||||||
// 优化:封装温湿度单位判断函数
|
|
||||||
isEffectiveValue(value) {
|
|
||||||
return this.testNumber(value);
|
|
||||||
},
|
|
||||||
|
|
||||||
// 新增:打开修改运行时间的弹窗
|
|
||||||
openTimeModal(card) {
|
|
||||||
if ((store.getters && store.getters.name !== 'admin')
|
|
||||||
&& this.$auth.hasRole("test")) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.currentCard = card; // 记录当前卡片信息
|
|
||||||
this.currentCardTime = this.limitTimes[`${card.type}Limit`]; // 记录当前时间
|
|
||||||
this.newLimitTime = this.currentCardTime; // 默认填充当前时间
|
|
||||||
this.remark = this.dtu_remark[card.type] || card.name;
|
|
||||||
this.$refs.inputDialog.open()
|
|
||||||
},
|
|
||||||
openDataModal(sensorCard) {
|
|
||||||
if ((store.getters && store.getters.name !== 'admin')
|
|
||||||
&& this.$auth.hasRole("test")) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.sensorCard = sensorCard;
|
|
||||||
this.remark=this.dtu_remark[sensorCard.key] || sensorCard.label;
|
|
||||||
this.$refs.inputNamelog.open()
|
|
||||||
},
|
|
||||||
confirmModifyName() {
|
|
||||||
const funcMsg = "该功能用来设置温湿度卡片别名,如若不填则展示默认备注"
|
|
||||||
if ((store.getters && store.getters.name !== 'admin')
|
|
||||||
&& this.$auth.hasRole("test")) {
|
|
||||||
// this.testFunction(`${this.testMsg}\n${funcMsg}`)
|
|
||||||
this.$refs?.inputNamelog?.close();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// 1. 解构赋值优化:直接拆分sensorCard的key/label,减少冗余
|
|
||||||
let {
|
|
||||||
selectedText,
|
|
||||||
dtu_remark,
|
|
||||||
imei,
|
|
||||||
sensorCard: { key: sensorKey, label: sensorLabel },
|
|
||||||
remark
|
|
||||||
} = this;
|
|
||||||
|
|
||||||
remark = remark || sensorLabel;
|
|
||||||
// 2. 语义化判定:别名是否修改
|
|
||||||
const isRemarkModified = remark !== (dtu_remark[sensorKey] || sensorLabel);
|
|
||||||
if (!isRemarkModified) {
|
|
||||||
// 统一关闭弹窗方式
|
|
||||||
this.$refs?.inputNamelog?.close();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 3. 确认弹窗(async/await处理异步请求)
|
|
||||||
uni.showModal({
|
|
||||||
title: '温馨提示:',
|
|
||||||
content: `确定将${selectedText}-${sensorLabel}别名设置为:${remark}?`, // 修复文案冗余冒号,补全remark变量
|
|
||||||
cancelText: '取消',
|
|
||||||
confirmText: '确定',
|
|
||||||
success: async (res) => {
|
|
||||||
// 关闭弹窗(无论确认/取消都关闭)
|
|
||||||
this.$refs?.inputNamelog?.close();
|
|
||||||
|
|
||||||
if (!res.confirm) return; // 取消操作直接返回
|
|
||||||
|
|
||||||
try {
|
|
||||||
// 4. 设置loading(可选,防止重复点击)
|
|
||||||
// uni.showLoading({ title: '处理中...' });
|
|
||||||
|
|
||||||
// 5. 更新响应式数据
|
|
||||||
this.$set(dtu_remark, sensorKey, remark); // sensorKey本身是字符串,无需拼接
|
|
||||||
// 补全imei字段(确保非空)
|
|
||||||
if (!dtu_remark.imei) {
|
|
||||||
this.$set(dtu_remark, 'imei', imei);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 6. 异步请求:await等待结果(核心修复)
|
|
||||||
const remarkRes = dtu_remark.id ? await updateRemark(dtu_remark) : await addRemark(dtu_remark);
|
|
||||||
|
|
||||||
// 7. 根据接口响应提示
|
|
||||||
const isSuccess = remarkRes.code === 200;
|
|
||||||
this.$modal[isSuccess ? 'msgSuccess' : 'msgError'](
|
|
||||||
isSuccess ? '修改成功' : '修改失败'
|
|
||||||
);
|
|
||||||
|
|
||||||
// 8. 仅成功时刷新数据(失败时不刷新,避免覆盖现有数据)
|
|
||||||
if (isSuccess) {
|
|
||||||
this.getRemarkByImei();
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
// 捕获网络异常/接口报错
|
|
||||||
console.error('别名修改失败:', error);
|
|
||||||
this.$modal.msgError('修改失败,请重试');
|
|
||||||
} finally {
|
|
||||||
// 无论成功/失败,关闭loading
|
|
||||||
// uni.hideLoading();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
closeModalDataName() {
|
|
||||||
this.$refs.inputNamelog.close()
|
|
||||||
},
|
|
||||||
close() {
|
|
||||||
this.$refs.inputDialog.close()
|
|
||||||
},
|
|
||||||
// 新增:确认修改运行时间
|
|
||||||
// 确认修改运行时间
|
|
||||||
confirmModifyTime() {
|
|
||||||
const funcMsg = "该功能用来设置设备运行时间及设备别名,设备运行时间即开启设备后到达运行时间自行暂停设备;设备别名不填则展示默认设备名称"
|
|
||||||
if ((store.getters && store.getters.name !== 'admin')
|
|
||||||
&& this.$auth.hasRole("test")) {
|
|
||||||
// this.testFunction(`${this.testMsg}\n${funcMsg}`)
|
|
||||||
this.$refs?.inputDialog?.close();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// 1. 解构赋值:简化频繁的this.xxx调用,提升可读性
|
|
||||||
let {
|
|
||||||
newLimitTime, currentCardTime, selectedText, currentCard,
|
|
||||||
limitTimes, dtu_remark, imei, agriId, remark
|
|
||||||
} = this;
|
|
||||||
|
|
||||||
// 2. 恢复并优化数字校验(如需启用,取消注释即可)
|
|
||||||
/*if (!newLimitTime || newLimitTime < 1 || newLimitTime > 60) {
|
|
||||||
uni.showToast({ title: '请输入1-60的有效数字', icon: 'none' });
|
|
||||||
return;
|
|
||||||
}*/
|
|
||||||
|
|
||||||
// 3. 定义核心判定变量(语义化命名)
|
|
||||||
const isLimitTimeModified = newLimitTime !== currentCardTime; // 运行时间是否修改
|
|
||||||
remark = remark || currentCard.name;
|
|
||||||
const isRemarkModified = (remark !== (dtu_remark[currentCard.type] || currentCard.name)); // 别名是否修改
|
|
||||||
|
|
||||||
// 4. 无修改则直接返回,避免无效弹窗
|
|
||||||
if (!isLimitTimeModified && !isRemarkModified) {
|
|
||||||
// 关闭弹窗(无论确认/取消都关闭)
|
|
||||||
this.$refs?.inputDialog?.close();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 5. 简化提示文案拼接(减少嵌套判断)
|
|
||||||
let confirmContent = `确定修改${selectedText}-${currentCard.name}:`;
|
|
||||||
const tips = [];
|
|
||||||
if (isLimitTimeModified) tips.push(`运行时间为:${newLimitTime} 秒`);
|
|
||||||
if (isRemarkModified) {
|
|
||||||
tips.push(`别名设置为:${remark}`)
|
|
||||||
}
|
|
||||||
confirmContent += `\n${tips.map((tip, idx) => `${idx + 1}. ${tip}?`).join('\n')}`;
|
|
||||||
|
|
||||||
// 6. 确认弹窗(async/await处理异步请求)
|
|
||||||
uni.showModal({
|
|
||||||
title: '温馨提示:',
|
|
||||||
content: confirmContent,
|
|
||||||
cancelText: '取消',
|
|
||||||
confirmText: '确定',
|
|
||||||
success: async (res) => {
|
|
||||||
// 关闭弹窗(无论确认/取消都关闭)
|
|
||||||
this.$refs?.inputDialog?.close();
|
|
||||||
|
|
||||||
if (!res.confirm) return; // 取消操作则直接返回
|
|
||||||
|
|
||||||
let isAllSuccess = true; // 统一判定所有请求是否成功
|
|
||||||
|
|
||||||
try {
|
|
||||||
// 7. 处理运行时间修改
|
|
||||||
if (isLimitTimeModified) {
|
|
||||||
this.$set(limitTimes, `${currentCard.type}Limit`, newLimitTime || 0);
|
|
||||||
// 补全必要字段(合并重复逻辑)
|
|
||||||
if (!limitTimes.imei) {
|
|
||||||
this.$set(limitTimes, 'imei', imei);
|
|
||||||
this.$set(limitTimes, 'agriName', selectedText);
|
|
||||||
this.$set(limitTimes, 'agriId', agriId);
|
|
||||||
}
|
|
||||||
// 发起请求并等待结果(async/await确保顺序执行)
|
|
||||||
const limitRes = limitTimes.id
|
|
||||||
? await updateLimit(limitTimes)
|
|
||||||
: await addLimit(limitTimes);
|
|
||||||
if (limitRes.code !== 200) isAllSuccess = false;
|
|
||||||
// 新增后刷新数据
|
|
||||||
if (!limitTimes.imei) this.getAgriByImei();
|
|
||||||
}
|
|
||||||
|
|
||||||
// 8. 处理别名修改
|
|
||||||
if (isRemarkModified) {
|
|
||||||
this.$set(dtu_remark, currentCard.type, remark);
|
|
||||||
// 补全imei字段
|
|
||||||
if (!dtu_remark.imei) {
|
|
||||||
this.$set(dtu_remark, 'imei', imei);
|
|
||||||
}
|
|
||||||
// 发起请求并等待结果
|
|
||||||
const remarkRes = dtu_remark.id
|
|
||||||
? await updateRemark(dtu_remark)
|
|
||||||
: await addRemark(dtu_remark);
|
|
||||||
if (remarkRes.code !== 200) isAllSuccess = false;
|
|
||||||
// 新增后刷新数据
|
|
||||||
if (!dtu_remark.imei) this.getRemarkByImei();
|
|
||||||
}
|
|
||||||
|
|
||||||
// 9. 正确的提示逻辑(修复原本文案反写的问题)
|
|
||||||
this.$modal[isAllSuccess ? 'msgSuccess' : 'msgError'](
|
|
||||||
isAllSuccess ? '修改成功' : '修改失败'
|
|
||||||
);
|
|
||||||
} catch (error) {
|
|
||||||
// 捕获网络异常/接口报错,避免页面卡死
|
|
||||||
console.error('修改失败:', error);
|
|
||||||
this.$modal.msgError('修改失败,请重试');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
onHide() {
|
onHide() {
|
||||||
mqttUtil.removeOnMessageCallback();
|
mqttUtil.removeOnMessageCallback();
|
||||||
|
|
@ -897,13 +445,10 @@ export default {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
<style>
|
|
||||||
@import "@/colorui/main.css";
|
|
||||||
// #ifdef mp-weixin
|
|
||||||
@import "/colorui/main.css";
|
|
||||||
// #endif
|
|
||||||
</style>
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
@import '@/tuniao-ui/index.scss';
|
||||||
|
@import "@/colorui/main.css";
|
||||||
|
@import "@/colorui/icon.css";
|
||||||
|
|
||||||
/deep/ .z-paging-content-fixed {
|
/deep/ .z-paging-content-fixed {
|
||||||
padding: 20rpx !important;
|
padding: 20rpx !important;
|
||||||
|
|
@ -1117,5 +662,14 @@ export default {
|
||||||
border-radius: 20rpx;
|
border-radius: 20rpx;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
.switch-row {
|
||||||
|
display: flex;
|
||||||
|
align-items: center; /* 垂直居中 */
|
||||||
|
gap: 8px; /* 元素之间的间距,可根据需要调整 */
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-text {
|
||||||
|
/* 确保文字和开关在视觉上对齐 */
|
||||||
|
line-height: 1;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,778 @@
|
||||||
|
<template>
|
||||||
|
<view>
|
||||||
|
|
||||||
|
<uni-section title="实时温湿度" titleFontSize="16px" type="line" v-if="value!== '1'">
|
||||||
|
<template v-slot:right>
|
||||||
|
{{ liveData.temp }}
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<view>
|
||||||
|
<!-- 优化:温度卡片循环渲染 -->
|
||||||
|
<view class="uni-flex_control uni-row">
|
||||||
|
<view
|
||||||
|
class="text uni-flex_control_one uni-view"
|
||||||
|
v-for="item in sensorCards.temp"
|
||||||
|
:key="item.key"
|
||||||
|
@click="openDataModal(item)"
|
||||||
|
>
|
||||||
|
<text class="data" :style="fontStyle">
|
||||||
|
{{ liveData[item.key] }}
|
||||||
|
<text v-if=" (liveData[item.key])" class="tempStyle">℃</text>
|
||||||
|
</text>
|
||||||
|
<text class="data" v-if="dtu_remark[item.key]">{{ dtu_remark[item.key] }}</text>
|
||||||
|
<text class="data" v-else>{{ item.label }}</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 优化:湿度卡片循环渲染 -->
|
||||||
|
<view class="uni-flex_control uni-row">
|
||||||
|
<view
|
||||||
|
class="text uni-flex_control_two uni-view"
|
||||||
|
v-for="item in sensorCards.humi"
|
||||||
|
:key="item.key"
|
||||||
|
@click="openDataModal(item)"
|
||||||
|
>
|
||||||
|
<text class="data" :style="fontStyle">
|
||||||
|
{{ liveData[item.key] }}
|
||||||
|
<text v-if="isEffectiveValue(liveData[item.key])" class="humiStyle"> %RH</text>
|
||||||
|
</text>
|
||||||
|
<text class="data" v-if="dtu_remark[item.key]">{{ dtu_remark[item.key] }}</text>
|
||||||
|
<text class="data" v-else>{{ item.label }}</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</uni-section>
|
||||||
|
|
||||||
|
<uni-section title="设备控制" titleFontSize="16px" type="line"
|
||||||
|
v-if="value!== 1 && !['862538065276939','A','B','C'].includes(value)">
|
||||||
|
<template v-slot:right>
|
||||||
|
{{ status.deviceTime }}
|
||||||
|
</template>
|
||||||
|
<!-- 优化:设备卡片循环渲染 -->
|
||||||
|
<view class="card-grid">
|
||||||
|
<view
|
||||||
|
class="control-card"
|
||||||
|
v-for="card in deviceCards"
|
||||||
|
:key="card.type"
|
||||||
|
@click="openTimeModal(card)"
|
||||||
|
>
|
||||||
|
<view class="card-text">
|
||||||
|
<text class="card-main" v-if="dtu_remark[card.type]">{{ dtu_remark[card.type] }}</text>
|
||||||
|
<text class="card-main" v-else>{{ card.name }}</text>
|
||||||
|
<view class="card-sub-wrapper">
|
||||||
|
<text class="card-sub" v-if="showStatusText">{{ show[card.type] || '未知' }}</text>
|
||||||
|
<text class="limit-time">
|
||||||
|
运行时间:{{
|
||||||
|
limitTimes[`${card.type}Limit`] && limitTimes[`${card.type}Limit`] !== '0' ? `${limitTimes[`${card.type}Limit`]} s` : '- -'
|
||||||
|
}}
|
||||||
|
</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view v-if="showFlag" class="card-icon" :class="{ active: status[card.type] === 1 }"
|
||||||
|
@click.stop="handleCardClick(1 - status[card.type], card.type)">
|
||||||
|
<!-- 加@click.stop防止冒泡触发卡片点击的弹窗事件 -->
|
||||||
|
<uni-icons
|
||||||
|
:type="status[card.type] === 1 ? 'circle' : 'circle-filled'"
|
||||||
|
size="24"
|
||||||
|
color="#fff"
|
||||||
|
/>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</uni-section>
|
||||||
|
|
||||||
|
<uni-popup ref="inputNamelog" mode="center">
|
||||||
|
<!-- 新增:修改运行时间的弹窗 -->
|
||||||
|
<view class="modal-container">
|
||||||
|
<view class="modal-title">{{ `【${selectedText} - 实时温湿度】别名设置` }}</view>
|
||||||
|
<view class="modal-input-wrap">
|
||||||
|
<text class="modal-label">别名设置:</text>
|
||||||
|
<uni-easyinput style="width: 100px" v-model="remark" placeholder="不填展示默认备注"/>
|
||||||
|
</view>
|
||||||
|
<view class="modal-btn-wrap">
|
||||||
|
<button class="modal-btn cancel" @click="closeModalDataName">取消</button>
|
||||||
|
<button class="modal-btn confirm" @click="confirmModifyName">确定</button>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</uni-popup>
|
||||||
|
|
||||||
|
<uni-popup ref="inputDialog" mode="center">
|
||||||
|
<!-- 新增:修改运行时间的弹窗 -->
|
||||||
|
<view class="modal-container">
|
||||||
|
<view class="modal-title">{{ `【${selectedText} - ${currentCard.name}】设置` }}</view>
|
||||||
|
<view class="modal-input-wrap">
|
||||||
|
<text class="modal-label">当前时间:</text>
|
||||||
|
<text class="modal-current">{{ currentCardTime > 0 ? `${currentCardTime} 秒` : '未设置' }}</text>
|
||||||
|
</view>
|
||||||
|
<view class="modal-input-wrap">
|
||||||
|
<text class="modal-label">修改后时间:</text>
|
||||||
|
<input
|
||||||
|
class="modal-input"
|
||||||
|
type="number"
|
||||||
|
v-model.number="newLimitTime"
|
||||||
|
/>
|
||||||
|
<!-- <uni-number-box v-model="newLimitTime" />-->
|
||||||
|
<text class="modal-unit">秒</text>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="modal-input-wrap">
|
||||||
|
<text class="modal-label">别名设置:</text>
|
||||||
|
<uni-easyinput style="width: 100px" v-model="remark" placeholder="不填展示默认备注"/>
|
||||||
|
</view>
|
||||||
|
<view class="modal-btn-wrap">
|
||||||
|
<button class="modal-btn cancel" @click="close">取消</button>
|
||||||
|
<button class="modal-btn confirm" @click="confirmModifyTime">确定</button>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</uni-popup>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
// 优化:抽离魔法值常量
|
||||||
|
import UniPopup from "../../../uni_modules/uni-popup/components/uni-popup/uni-popup.vue"; // 引入弹窗组件
|
||||||
|
import mqttUtil from '@/utils/mqtt';
|
||||||
|
import {addLimit, getAgriByImei, updateLimit} from "../../../api/system/assets/limit";
|
||||||
|
import store from "../../../store";
|
||||||
|
import {addRemark, updateRemark} from "../../../api/system/assets/remark";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
dicts: ['sys_data_map'],
|
||||||
|
name: "manual",
|
||||||
|
props: {
|
||||||
|
// 尺寸
|
||||||
|
value: {
|
||||||
|
type: String,
|
||||||
|
default: "1"
|
||||||
|
},
|
||||||
|
// 打开时的背景颜色
|
||||||
|
activeColor: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
dtu_remark: {
|
||||||
|
type: Object,
|
||||||
|
default() {
|
||||||
|
return {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
status: {
|
||||||
|
type: Object,
|
||||||
|
default() {
|
||||||
|
return {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
liveData: {
|
||||||
|
type: Object,
|
||||||
|
default() {
|
||||||
|
return {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
show: {
|
||||||
|
type: Object,
|
||||||
|
default() {
|
||||||
|
return {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
selectedText: {
|
||||||
|
type: String,
|
||||||
|
default: ""
|
||||||
|
},
|
||||||
|
agriId: {
|
||||||
|
type: String,
|
||||||
|
default: null
|
||||||
|
},
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
value: {
|
||||||
|
deep: true, // 监听对象内部属性变化(防止数据是对象时监听不到)
|
||||||
|
immediate: true, // 关键:进入组件就执行,不用等数据变化
|
||||||
|
handler(newVal) {
|
||||||
|
// 确保数据有值后执行方法
|
||||||
|
if (newVal) {
|
||||||
|
this.imei = this.value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
components: {
|
||||||
|
ZPaging,
|
||||||
|
UniNumberBox,
|
||||||
|
UniPopupDialog,
|
||||||
|
CustomRefresher,
|
||||||
|
UniPopup // 注册弹窗组件
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.refresh()
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
fontStyle: '',
|
||||||
|
sensorCards: {
|
||||||
|
temp: [
|
||||||
|
{label: '温度1', key: 'temp1'},
|
||||||
|
{label: '温度2', key: 'temp2'},
|
||||||
|
{label: '温度3', key: 'temp3'},
|
||||||
|
{label: '温度4', key: 'temp4'}
|
||||||
|
],
|
||||||
|
humi: [
|
||||||
|
{label: '湿度1', key: 'humi1'},
|
||||||
|
{label: '湿度2', key: 'humi2'},
|
||||||
|
{label: '湿度3', key: 'humi3'},
|
||||||
|
{label: '湿度4', key: 'humi4'}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
deviceCards: [
|
||||||
|
{type: 'jbk', name: '卷被开'},
|
||||||
|
{type: 'jbg', name: '卷被关'},
|
||||||
|
{type: 'jm1k', name: '卷膜1开'},
|
||||||
|
{type: 'jm1g', name: '卷膜1关'},
|
||||||
|
{type: 'jm2k', name: '卷膜2开'},
|
||||||
|
{type: 'jm2g', name: '卷膜2关'},
|
||||||
|
{type: 'jm3k', name: '卷膜3开'},
|
||||||
|
{type: 'jm3g', name: '卷膜3关'},
|
||||||
|
{type: 'jlk', name: '卷帘开'},
|
||||||
|
{type: 'jlg', name: '卷帘关'},
|
||||||
|
],
|
||||||
|
// 优化:语义化变量名(替换原 hide: false)
|
||||||
|
showStatusText: false,
|
||||||
|
showFlag: true,
|
||||||
|
remark: '',
|
||||||
|
// 新增:弹窗相关变量
|
||||||
|
currentCard: {}, // 当前点击的卡片信息
|
||||||
|
currentCardTime: '', // 当前卡片的运行时间
|
||||||
|
newLimitTime: 0, // 新的运行时间
|
||||||
|
message: {},
|
||||||
|
// 优化:声明响应式变量 connected
|
||||||
|
connected: false,
|
||||||
|
imei: '',
|
||||||
|
// 新增:限位时间配置
|
||||||
|
limitTimes: {
|
||||||
|
jbkLimit: 0,
|
||||||
|
jbgLimit: 0,
|
||||||
|
jlkLimit: 0,
|
||||||
|
jlgLimit: 0,
|
||||||
|
jm1kLimit: 0,
|
||||||
|
jm1gLimit: 0,
|
||||||
|
jm2kLimit: 0,
|
||||||
|
jm2gLimit: 0,
|
||||||
|
jm3kLimit: 0,
|
||||||
|
jm3gLimit: 0
|
||||||
|
},
|
||||||
|
// 优化:温湿度卡片配置(固定顺序:温度1→2→3→4,湿度1→2→3→4)
|
||||||
|
sensorCard:{},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
refresh() {
|
||||||
|
this.showFlag = !((store.getters && store.getters.name !== 'admin') && this.$auth.hasRole("test"))
|
||||||
|
this.getAgriByImei();
|
||||||
|
},
|
||||||
|
openDataModal(sensorCard) {
|
||||||
|
if ((store.getters && store.getters.name !== 'admin')
|
||||||
|
&& this.$auth.hasRole("test")) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.sensorCard = sensorCard;
|
||||||
|
this.remark = this.dtu_remark[sensorCard.key] || sensorCard.label;
|
||||||
|
this.$refs.inputNamelog.open()
|
||||||
|
},
|
||||||
|
|
||||||
|
// 优化:封装温湿度单位判断函数
|
||||||
|
isEffectiveValue(value) {
|
||||||
|
return this.testNumber(value);
|
||||||
|
},
|
||||||
|
testNumber(data) {
|
||||||
|
const reg = /^-?\d+(\.\d+)?$/;
|
||||||
|
return reg.test(String(data).trim());
|
||||||
|
},
|
||||||
|
// 新增:打开修改运行时间的弹窗
|
||||||
|
openTimeModal(card) {
|
||||||
|
if ((store.getters && store.getters.name !== 'admin')
|
||||||
|
&& this.$auth.hasRole("test")) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.currentCard = card; // 记录当前卡片信息
|
||||||
|
this.currentCardTime = this.limitTimes[`${card.type}Limit`]; // 记录当前时间
|
||||||
|
this.newLimitTime = this.currentCardTime; // 默认填充当前时间
|
||||||
|
this.remark = this.dtu_remark[card.type] || card.name;
|
||||||
|
this.$refs.inputDialog.open()
|
||||||
|
},
|
||||||
|
// 卡片点击事件(实际项目中调用接口修改状态) 功能标识
|
||||||
|
handleCardClick(status, type) {
|
||||||
|
const funcMsg = "该功能用来开启或暂停设备,按钮亮为开启,按钮暗为暂停设备"
|
||||||
|
if ((store.getters && store.getters.name !== 'admin')
|
||||||
|
&& this.$auth.hasRole("test")) {
|
||||||
|
// this.testFunction(`${this.testMsg}\n${funcMsg}`)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// 校验
|
||||||
|
// 定义类型与提示文案的映射关系,减少重复代码
|
||||||
|
const tipMap = {
|
||||||
|
'jbk': {opposite: 'jbg', name: '卷被关', op: '卷被开'},
|
||||||
|
'jbg': {opposite: 'jbk', name: '卷被开', op: '卷被关'},
|
||||||
|
'jlk': {opposite: 'jlg', name: '卷帘关', op: '卷帘开'},
|
||||||
|
'jlg': {opposite: 'jlk', name: '卷帘开', op: '卷帘关'},
|
||||||
|
'jm1k': {opposite: 'jm1g', name: '卷膜1关', op: '卷膜1开'},
|
||||||
|
'jm1g': {opposite: 'jm1k', name: '卷膜1开', op: '卷膜1关'},
|
||||||
|
'jm2k': {opposite: 'jm2g', name: '卷膜2关', op: '卷膜2开'},
|
||||||
|
'jm2g': {opposite: 'jm2k', name: '卷膜2开', op: '卷膜2关'},
|
||||||
|
'jm3k': {opposite: 'jm3g', name: '卷膜3关', op: '卷膜3开'},
|
||||||
|
'jm3g': {opposite: 'jm3k', name: '卷膜3开', op: '卷膜3关'}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 先判断类型是否在映射表中,避免无效case
|
||||||
|
if (!tipMap[type]) return;
|
||||||
|
|
||||||
|
const {opposite, name, op} = tipMap[type];
|
||||||
|
// 核心校验逻辑(只写一次,无需重复)
|
||||||
|
if (status === 1 && this.status[opposite] === 1) {
|
||||||
|
this.$modal.msgError(`【${this.selectedText}】${name}在运行状态,不能运行${op}操作!`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ========== 修改:从全局工具类获取连接状态 ==========
|
||||||
|
this.connected = mqttUtil.getMqttState().isConnected;
|
||||||
|
if (!this.connected) {
|
||||||
|
this.$modal.msgError("设备连接异常");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (this.value === 1) {
|
||||||
|
this.$modal.msgError("设备控制失败!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
uni.showModal({
|
||||||
|
title: '操作提示:',
|
||||||
|
content: '确定' + (status === 1 ? "运行" : "暂停") + '【' + this.selectedText + '】设备?',
|
||||||
|
cancelText: '取消',
|
||||||
|
confirmText: '确定',
|
||||||
|
success: (res) => {
|
||||||
|
if (res.confirm) {
|
||||||
|
// 组装消息
|
||||||
|
this.message = JSON.stringify({[`${type}1`]: status})
|
||||||
|
// 控制设备
|
||||||
|
this.$emit("publicMsg", this.message)
|
||||||
|
//todo
|
||||||
|
// this.testAuto(type);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
closeModalDataName() {
|
||||||
|
this.$refs.inputNamelog.close()
|
||||||
|
},
|
||||||
|
close() {
|
||||||
|
this.$refs.inputDialog.close()
|
||||||
|
},
|
||||||
|
// 新增:确认修改运行时间
|
||||||
|
// 确认修改运行时间
|
||||||
|
confirmModifyTime: function () {
|
||||||
|
const funcMsg = "该功能用来设置设备运行时间及设备别名,设备运行时间即开启设备后到达运行时间自行暂停设备;设备别名不填则展示默认设备名称"
|
||||||
|
if ((store.getters && store.getters.name !== 'admin')
|
||||||
|
&& this.$auth.hasRole("test")) {
|
||||||
|
// this.testFunction(`${this.testMsg}\n${funcMsg}`)
|
||||||
|
this.$refs?.inputDialog?.close();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// 1. 解构赋值:简化频繁的this.xxx调用,提升可读性
|
||||||
|
let {
|
||||||
|
newLimitTime, currentCardTime, selectedText, currentCard,
|
||||||
|
limitTimes, dtu_remark, imei, agriId, remark
|
||||||
|
} = this;
|
||||||
|
|
||||||
|
// 2. 恢复并优化数字校验(如需启用,取消注释即可)
|
||||||
|
/*if (!newLimitTime || newLimitTime < 1 || newLimitTime > 60) {
|
||||||
|
uni.showToast({ title: '请输入1-60的有效数字', icon: 'none' });
|
||||||
|
return;
|
||||||
|
}*/
|
||||||
|
|
||||||
|
// 3. 定义核心判定变量(语义化命名)
|
||||||
|
const isLimitTimeModified = newLimitTime !== currentCardTime; // 运行时间是否修改
|
||||||
|
remark = remark || currentCard.name;
|
||||||
|
const isRemarkModified = (remark !== (dtu_remark[currentCard.type] || currentCard.name)); // 别名是否修改
|
||||||
|
|
||||||
|
// 4. 无修改则直接返回,避免无效弹窗
|
||||||
|
if (!isLimitTimeModified && !isRemarkModified) {
|
||||||
|
// 关闭弹窗(无论确认/取消都关闭)
|
||||||
|
this.$refs?.inputDialog?.close();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 5. 简化提示文案拼接(减少嵌套判断)
|
||||||
|
let confirmContent = `确定修改${selectedText}-${currentCard.name}:`;
|
||||||
|
const tips = [];
|
||||||
|
if (isLimitTimeModified) tips.push(`运行时间为:${newLimitTime} 秒`);
|
||||||
|
if (isRemarkModified) {
|
||||||
|
tips.push(`别名设置为:${remark}`)
|
||||||
|
}
|
||||||
|
confirmContent += `\n${tips.map((tip, idx) => `${idx + 1}. ${tip}?`).join('\n')}`;
|
||||||
|
|
||||||
|
// 6. 确认弹窗(async/await处理异步请求)
|
||||||
|
uni.showModal({
|
||||||
|
title: '温馨提示:',
|
||||||
|
content: confirmContent,
|
||||||
|
cancelText: '取消',
|
||||||
|
confirmText: '确定',
|
||||||
|
success: async (res) => {
|
||||||
|
// 关闭弹窗(无论确认/取消都关闭)
|
||||||
|
this.$refs?.inputDialog?.close();
|
||||||
|
|
||||||
|
if (!res.confirm) return; // 取消操作则直接返回
|
||||||
|
|
||||||
|
let isAllSuccess = false; // 统一判定所有请求是否成功
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 7. 处理运行时间修改
|
||||||
|
if (isLimitTimeModified) {
|
||||||
|
this.$set(limitTimes, `${currentCard.type}Limit`, newLimitTime || 0);
|
||||||
|
// 补全必要字段(合并重复逻辑)
|
||||||
|
if (!limitTimes.imei) {
|
||||||
|
this.$set(limitTimes, 'imei', imei);
|
||||||
|
this.$set(limitTimes, 'agriName', selectedText);
|
||||||
|
this.$set(limitTimes, 'agriId', agriId);
|
||||||
|
}
|
||||||
|
// 发起请求并等待结果(async/await确保顺序执行)
|
||||||
|
const limitRes = limitTimes.id
|
||||||
|
? await updateLimit(limitTimes)
|
||||||
|
: await addLimit(limitTimes);
|
||||||
|
if (limitRes.code === 200) {
|
||||||
|
isAllSuccess = true;
|
||||||
|
this.getAgriByImei();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 8. 处理别名修改
|
||||||
|
if (isRemarkModified) {
|
||||||
|
this.$set(dtu_remark, currentCard.type, remark);
|
||||||
|
// 补全imei字段
|
||||||
|
if (!dtu_remark.imei) {
|
||||||
|
this.$set(dtu_remark, 'imei', imei);
|
||||||
|
}
|
||||||
|
// 发起请求并等待结果
|
||||||
|
const remarkRes = dtu_remark.id
|
||||||
|
? await updateRemark(dtu_remark)
|
||||||
|
: await addRemark(dtu_remark);
|
||||||
|
if (remarkRes.code === 200) {
|
||||||
|
this.$emit("getRemark")
|
||||||
|
isAllSuccess = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 9. 正确的提示逻辑(修复原本文案反写的问题)
|
||||||
|
this.$modal[isAllSuccess ? 'msgSuccess' : 'msgError'](
|
||||||
|
isAllSuccess ? '修改成功' : '修改失败'
|
||||||
|
);
|
||||||
|
} catch (error) {
|
||||||
|
// 捕获网络异常/接口报错,避免页面卡死
|
||||||
|
console.error('修改失败:', error);
|
||||||
|
this.$modal.msgError('修改失败,请重试');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
confirmModifyName() {
|
||||||
|
const funcMsg = "该功能用来设置温湿度卡片别名,如若不填则展示默认备注"
|
||||||
|
if ((store.getters && store.getters.name !== 'admin')
|
||||||
|
&& this.$auth.hasRole("test")) {
|
||||||
|
// this.testFunction(`${this.testMsg}\n${funcMsg}`)
|
||||||
|
this.$refs?.inputNamelog?.close();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// 1. 解构赋值优化:直接拆分sensorCard的key/label,减少冗余
|
||||||
|
let {
|
||||||
|
selectedText,
|
||||||
|
dtu_remark,
|
||||||
|
imei,
|
||||||
|
sensorCard: {key: sensorKey, label: sensorLabel},
|
||||||
|
remark
|
||||||
|
} = this;
|
||||||
|
|
||||||
|
remark = remark || sensorLabel;
|
||||||
|
// 2. 语义化判定:别名是否修改
|
||||||
|
const isRemarkModified = remark !== (dtu_remark[sensorKey] || sensorLabel);
|
||||||
|
if (!isRemarkModified) {
|
||||||
|
// 统一关闭弹窗方式
|
||||||
|
this.$refs?.inputNamelog?.close();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. 确认弹窗(async/await处理异步请求)
|
||||||
|
uni.showModal({
|
||||||
|
title: '温馨提示:',
|
||||||
|
content: `确定将${selectedText}-${sensorLabel}别名设置为:${remark}?`, // 修复文案冗余冒号,补全remark变量
|
||||||
|
cancelText: '取消',
|
||||||
|
confirmText: '确定',
|
||||||
|
success: async (res) => {
|
||||||
|
// 关闭弹窗(无论确认/取消都关闭)
|
||||||
|
this.$refs?.inputNamelog?.close();
|
||||||
|
|
||||||
|
if (!res.confirm) return; // 取消操作直接返回
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 4. 设置loading(可选,防止重复点击)
|
||||||
|
// uni.showLoading({ title: '处理中...' });
|
||||||
|
|
||||||
|
// 5. 更新响应式数据
|
||||||
|
this.$set(dtu_remark, sensorKey, remark); // sensorKey本身是字符串,无需拼接
|
||||||
|
// 补全imei字段(确保非空)
|
||||||
|
if (!dtu_remark.imei) {
|
||||||
|
this.$set(dtu_remark, 'imei', imei);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 6. 异步请求:await等待结果(核心修复)
|
||||||
|
const remarkRes = dtu_remark.id ? await updateRemark(dtu_remark) : await addRemark(dtu_remark);
|
||||||
|
|
||||||
|
// 7. 根据接口响应提示
|
||||||
|
const isSuccess = remarkRes.code === 200;
|
||||||
|
this.$modal[isSuccess ? 'msgSuccess' : 'msgError'](
|
||||||
|
isSuccess ? '修改成功' : '修改失败'
|
||||||
|
);
|
||||||
|
|
||||||
|
// 8. 仅成功时刷新数据(失败时不刷新,避免覆盖现有数据)
|
||||||
|
if (isSuccess) {
|
||||||
|
this.$emit("getRemark")
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
// 捕获网络异常/接口报错
|
||||||
|
console.error('别名修改失败:', error);
|
||||||
|
this.$modal.msgError('修改失败,请重试');
|
||||||
|
} finally {
|
||||||
|
// 无论成功/失败,关闭loading
|
||||||
|
// uni.hideLoading();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
getAgriByImei() {
|
||||||
|
getAgriByImei(this.imei).then(response => {
|
||||||
|
if (response.code === 200) {
|
||||||
|
if (!response.data) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.limitTimes = response.data;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
|
||||||
|
|
||||||
|
/* 2列栅格布局 */
|
||||||
|
.card-grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 1fr 1fr;
|
||||||
|
gap: 20rpx;
|
||||||
|
padding: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 卡片样式 */
|
||||||
|
.control-card {
|
||||||
|
background-color: #fff;
|
||||||
|
border-radius: 16rpx;
|
||||||
|
padding: 30rpx 20rpx;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
box-shadow: 0 2rpx 8rpx #bfbec1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 卡片文字区域 */
|
||||||
|
.card-text {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 8rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-main {
|
||||||
|
font-size: 30rpx;
|
||||||
|
color: #333;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-sub {
|
||||||
|
font-size: 24rpx;
|
||||||
|
color: #999;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 保留原有样式,仅修改/新增以下部分 */
|
||||||
|
.card-sub-wrapper {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
width: 100%;
|
||||||
|
gap: 10rpx;
|
||||||
|
/* 新增:给容器加最小宽度,确保所有卡片一致 */
|
||||||
|
min-width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.limit-time {
|
||||||
|
font-size: 24rpx;
|
||||||
|
color: #999;
|
||||||
|
/* 可选:加固定左边距,确保和暂停的间距统一 */
|
||||||
|
margin-left: 0rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 卡片图标容器 */
|
||||||
|
.card-icon {
|
||||||
|
width: 48rpx;
|
||||||
|
height: 48rpx;
|
||||||
|
border-radius: 50%;
|
||||||
|
background-color: #e5e5e5;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 激活状态(运行) */
|
||||||
|
.card-icon.active {
|
||||||
|
background-color: #007aff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-px-5 {
|
||||||
|
padding-left: 20rpx;
|
||||||
|
padding-right: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-pb-5 {
|
||||||
|
padding-bottom: 15rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text {
|
||||||
|
width: 50rpx;
|
||||||
|
margin: 10rpx 10rpx 8rpx 0;
|
||||||
|
padding: 0;
|
||||||
|
height: 70rpx;
|
||||||
|
line-height: 70rpx;
|
||||||
|
text-align: center;
|
||||||
|
font-size: 26rpx;
|
||||||
|
box-shadow: 0 2rpx 8rpx #bfbec1
|
||||||
|
}
|
||||||
|
|
||||||
|
.tempStyle, .humiStyle {
|
||||||
|
display: inline-block;
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text:first-child {
|
||||||
|
margin-left: 10rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-view {
|
||||||
|
-webkit-flex: 1;
|
||||||
|
flex: 1;
|
||||||
|
height: 150rpx;
|
||||||
|
-webkit-justify-content: center;
|
||||||
|
justify-content: center;
|
||||||
|
-webkit-align-items: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.data {
|
||||||
|
font-size: 13px;
|
||||||
|
display: inline-block;
|
||||||
|
line-height: 23px;
|
||||||
|
color: #3a3a3a;
|
||||||
|
}
|
||||||
|
|
||||||
|
.data:nth-child(even) {
|
||||||
|
font-size: 12px;
|
||||||
|
margin-top: 3px;
|
||||||
|
color: #9c9c9c;
|
||||||
|
}
|
||||||
|
|
||||||
|
/deep/ .uni-section-header__slot-right {
|
||||||
|
color: green;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 新增:弹窗样式 */
|
||||||
|
.modal-container {
|
||||||
|
width: 600rpx;
|
||||||
|
background: #fff;
|
||||||
|
border-radius: 16rpx;
|
||||||
|
padding: 30rpx 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-title {
|
||||||
|
font-size: 30rpx;
|
||||||
|
font-weight: 500;
|
||||||
|
text-align: center;
|
||||||
|
margin-bottom: 40rpx;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-input-wrap {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 35rpx;
|
||||||
|
font-size: 26rpx;
|
||||||
|
margin-left: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-label {
|
||||||
|
width: 160rpx;
|
||||||
|
color: #666;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-current {
|
||||||
|
margin-left: 14rpx;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-input {
|
||||||
|
height: 60rpx;
|
||||||
|
border: 1px solid #eee;
|
||||||
|
border-radius: 8rpx;
|
||||||
|
padding: 0 15rpx;
|
||||||
|
font-size: 26rpx;
|
||||||
|
width: 80rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-unit {
|
||||||
|
margin-left: 10rpx;
|
||||||
|
color: #666;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-btn-wrap {
|
||||||
|
display: flex;
|
||||||
|
gap: 20rpx;
|
||||||
|
margin-top: 40rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-btn {
|
||||||
|
flex: 1;
|
||||||
|
height: 70rpx;
|
||||||
|
border-radius: 8rpx;
|
||||||
|
font-size: 26rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-btn.cancel {
|
||||||
|
background: #f5f5f5;
|
||||||
|
color: #666;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-btn.confirm {
|
||||||
|
background: #007aff;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon {
|
||||||
|
margin-left: 15rpx
|
||||||
|
}
|
||||||
|
|
||||||
|
/deep/ .is-input-border {
|
||||||
|
width: 340rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card {
|
||||||
|
border-radius: 20rpx;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
|
|
@ -314,7 +314,7 @@ export default {
|
||||||
{
|
{
|
||||||
imei:item.imei,
|
imei:item.imei,
|
||||||
agriName:item.agriName,
|
agriName:item.agriName,
|
||||||
agriId:item.agriId
|
agriId:item.id
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
this.$tab.navigateTo('/pages/home/control/index?agriInfo='+encodeURIComponent(agri))
|
this.$tab.navigateTo('/pages/home/control/index?agriInfo='+encodeURIComponent(agri))
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue