Files
fishery-app/src/home/solar.vue
2026-04-02 22:57:19 +08:00

1564 lines
49 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>
<view>
<view class="wqm_home">
<scroll-view :scroll-y="isScroll" :style="{ height: 'calc(100% - 1px)' }">
<nut-config-provider :theme-vars="themeVars">
<view class="body">
<nut-row>
<!-- 设备信息区域 -->
<nut-col :span="24" v-if="!section || section === 'deviceInfo'">
<nut-cell class="wqm_body">
<nut-row>
<nut-col :span="24" class="title"> 设备信息 </nut-col>
<nut-col :span="24">
<nut-cell-group>
<nut-cell title="设备名称" is-link @click="setName">
<template #desc>
<text class="desc">{{
deviceInfoRes.deviceName
}}</text>
</template>
</nut-cell>
<nut-cell title="设备号">
<template #desc>
<text class="desc">{{
deviceInfoRes.serialNum
}}</text>
</template>
</nut-cell>
<nut-cell title="设备类型">
<template #desc>
<text class="desc">太阳能网控</text>
</template>
</nut-cell>
<nut-cell title="绑定时间">
<template #desc>
<text class="desc">{{
deviceInfoRes.bindTime
}}</text>
</template>
</nut-cell>
<nut-cell title="服务到期日">
<template #desc>
<text class="desc">{{
deviceInfoRes.deadTime
}}</text>
</template>
</nut-cell>
<nut-cell
title="关联塘口"
is-link
@click="showPond = true"
>
<template #desc>
<text class="desc">{{
deviceInfoRes.pondInfo
? deviceInfoRes.pondInfo.pondName
: "请绑定塘口"
}}</text>
</template>
</nut-cell>
</nut-cell-group>
</nut-col>
<!-- 盐度设置和设备校准 -->
<nut-col :span="24">
<nut-cell-group>
<nut-cell title="盐度设置" is-link @click="setSalFunc">
<template #desc>
<text class="desc"
>{{ deviceInfoRes.salinityCompensation }}</text
>
</template>
</nut-cell>
<nut-cell
title="设备校准"
is-link
@click="toCalibration"
/>
</nut-cell-group>
</nut-col>
<!-- 将解除绑定按钮移到设备信息区域内 -->
<nut-col :span="24" :style="{ marginTop: '20rpx' }">
<nut-button
block
shape="square"
size="large"
color="#E22323"
:style="{
fontWeight: 'bold',
fontSize: '14px !important',
borderRadius: '10px',
}"
@click="unbind"
:loading="b_isLoading"
v-if="isMainAccount"
>解除绑定</nut-button
>
</nut-col>
</nut-row>
</nut-cell>
</nut-col>
<!-- 溶解氧配置区域 -->
<nut-col :span="24" v-if="!section || section === 'alarmSettings'">
<nut-cell class="wqm_body">
<nut-row>
<nut-col :span="24" class="title"> 溶解氧配置 </nut-col>
<nut-col :span="24">
<nut-cell-group>
<nut-cell title="溶解氧电话告警开关">
<nut-row>
<nut-col
:span="24"
:style="{
display: 'flex',
alignItems: 'center',
justifyContent: 'space-between',
}"
>
<view>
<view class="c_title">溶解氧电话告警开关</view>
<view class="c_dis"
>溶解氧低于设定值会电话提醒</view
>
</view>
<view>
<nut-switch
v-model="deviceInfoRes.oxyWarnTelOpen"
active-color="#04D98A"
@change="changeO2"
/>
</view>
</nut-col>
<nut-col
:span="24"
:style="{
display: 'flex',
alignItems: 'center',
justifyContent: 'space-between',
}"
v-if="deviceInfoRes.oxyWarnTelOpen"
>
<view>
<view class="c_title">告警免打扰</view>
<view class="c_dis">
在08:00-14:0014:00-20:0020:00-08:00三个时段内只进行一次有效电话告警
</view>
</view>
<view>
<nut-switch
v-model="deviceInfoRes.oxyWarnTelNoDis"
active-color="#04D98A"
@change="changeOxyDis"
/>
</view>
</nut-col>
<nut-col
:span="24"
:style="{
display: 'flex',
alignItems: 'center',
justifyContent: 'space-between',
marginTop: '20rpx',
}"
>
<view class="d_title"
>下限 {{ deviceInfoRes.oxyWarnLower }}Mg/L
</view>
<view
class="d_dis"
:style="{
display: 'flex',
alignItems: 'center',
}"
@click="setOxy"
>
<view>设置</view>
<view
style="
width: var(--nut-icon-width);
color: #979797;
height: var(--nut-icon-height);
line-height: var(--nut-icon-line-height);
"
>
<RectRight />
</view>
</view>
</nut-col>
</nut-row>
</nut-cell>
<nut-cell>
<nut-row>
<nut-col
:span="24"
:style="{
display: 'flex',
alignItems: 'center',
justifyContent: 'space-between',
}"
>
<view>
<view class="c_title">温度电话告警开关</view>
<view class="c_dis"
>温度高于或低于设定值会电话提醒</view
>
</view>
<view>
<nut-switch
v-model="deviceInfoRes.tempWarnTelOpen"
active-color="#04D98A"
@change="changeTem"
/>
</view>
</nut-col>
<nut-col
:span="24"
:style="{
display: 'flex',
alignItems: 'center',
justifyContent: 'space-between',
}"
v-if="deviceInfoRes.tempWarnTelOpen"
>
<view>
<view class="c_title">告警免打扰</view>
<view class="c_dis">
在08:00-14:0014:00-20:0020:00-08:00三个时段内只进行一次有效电话告警
</view>
</view>
<view>
<nut-switch
v-model="deviceInfoRes.tempWarnTelNoDis"
active-color="#04D98A"
@change="changeTemDis"
/>
</view>
</nut-col>
<nut-col
:span="24"
:style="{
display: 'flex',
alignItems: 'center',
justifyContent: 'space-between',
marginTop: '20rpx',
}"
>
<view class="d_title"
>上限
{{
deviceInfoRes.tempWarnUpper
}}&nbsp;&nbsp;&nbsp;下限
{{ deviceInfoRes.tempWarnLower }}</view
>
<view
class="d_dis"
:style="{
display: 'flex',
alignItems: 'center',
}"
@click="setTemp"
>
<view>设置</view>
<view
style="
width: var(--nut-icon-width);
color: #979797;
height: var(--nut-icon-height);
line-height: var(--nut-icon-line-height);
"
>
<RectRight />
</view>
</view>
</nut-col>
</nut-row>
</nut-cell>
<!-- 联动控制已隐藏 -->
</nut-cell-group>
</nut-col>
</nut-row>
</nut-cell>
</nut-col>
<!-- 电量配置区域 -->
<nut-col :span="24" v-if="!section || section === 'batterySettings'">
<nut-cell class="wqm_body">
<nut-row>
<nut-col :span="24" class="title"> 电量配置 </nut-col>
<nut-col :span="24">
<nut-cell-group>
<nut-cell title="电量电话告警开关">
<nut-row>
<nut-col
:span="24"
:style="{
display: 'flex',
alignItems: 'center',
justifyContent: 'space-between',
}"
>
<view>
<view class="c_title">电量电话告警开关</view>
<view class="c_dis"
>电量低于设定值会电话提醒</view
>
</view>
<view>
<nut-switch
v-model="deviceInfoRes.batteryWarnCallOpen"
active-color="#04D98A"
@change="changeBattery"
/>
</view>
</nut-col>
<nut-col
:span="24"
:style="{
display: 'flex',
alignItems: 'center',
justifyContent: 'space-between',
}"
v-if="deviceInfoRes.batteryWarnCallOpen"
>
<view>
<view class="c_title">告警免打扰</view>
<view class="c_dis">
在08:00-14:0014:00-20:0020:00-08:00三个时段内只进行一次有效电话告警
</view>
</view>
<view>
<nut-switch
v-model="deviceInfoRes.batteryWarnCallNoDis"
active-color="#04D98A"
@change="changeBatteryDis"
/>
</view>
</nut-col>
<nut-col
:span="24"
:style="{
display: 'flex',
alignItems: 'center',
justifyContent: 'space-between',
marginTop: '20rpx',
}"
>
<view class="d_title"
>下限 {{ deviceInfoRes.batteryWarnLower }}
</view>
<view
class="d_dis"
:style="{
display: 'flex',
alignItems: 'center',
}"
@click="setBattery"
>
<view>设置</view>
<view
style="
width: var(--nut-icon-width);
color: #979797;
height: var(--nut-icon-height);
line-height: var(--nut-icon-line-height);
"
>
<RectRight />
</view>
</view>
</nut-col>
</nut-row>
</nut-cell>
</nut-cell-group>
</nut-col>
</nut-row>
</nut-cell>
</nut-col>
</nut-row>
</view>
</nut-config-provider>
</scroll-view>
<!-- 弹出层提示 -->
<nut-toast
:msg="state.msg"
v-model:visible="state.show"
:type="state.type"
/>
<!-- 选择塘口 -->
<nut-popup v-model:visible="showPond" position="bottom">
<nut-picker
v-model="pondId"
:columns="pondList"
title="请选择塘口"
@confirm="confirm"
:field-names="{ text: 'pondName', value: 'id' }"
@cancel="cancel"
/>
</nut-popup>
<nut-config-provider :theme-vars="themeVars2">
<!-- 溶解氧告警设置 -->
<nut-dialog v-model:visible="openSetOxy" text-align="left" no-footer>
<view :style="{ height: '100%' }">
<view class="d_body">
<nut-row>
<nut-col :span="24">
<view class="d_title">溶解氧告警值设置</view>
</nut-col>
<nut-col :span="24">
<nut-divider class="divider" />
</nut-col>
<nut-col :span="24" class="view_f">
<view :style="{ width: '40%' }" class="font_32 c_444"
>告警值</view
>
<view :style="{ width: '60%' }">
<nut-input
type="digit"
v-model="oxy"
@blur="oxyValue"
@focus="onfocus"
:border="false"
input-align="right"
clearable
max-length="5"
placeholder="范围1.5~20"
:cursor="String(oxy).length"
>
<template #right> Mg/L </template>
</nut-input>
</view>
</nut-col>
<nut-col :span="24">
<nut-divider class="divider" />
</nut-col>
</nut-row>
</view>
<view class="d_btn">
<nut-row>
<nut-col
:span="12"
:style="{ border: '1px solid #eee', color: '#222' }"
@click="openSetOxy = false"
>
取消
</nut-col>
<nut-col
:span="12"
:style="{ border: '1px solid #eee', color: '#15BBC5' }"
@click="setOxyEventD"
>
确定
</nut-col>
</nut-row>
</view>
</view>
</nut-dialog>
<!-- 温度告警设置 -->
<nut-dialog v-model:visible="openSetTemp" text-align="left" no-footer>
<view :style="{ height: '100%' }">
<view class="d_body">
<nut-row>
<nut-col :span="24">
<view class="d_title">温度告警设置</view>
</nut-col>
<nut-col :span="24">
<nut-divider class="divider" />
</nut-col>
<nut-col :span="24" class="view_f">
<view :style="{ width: '30%' }" class="font_32 c_444"
>温度上限</view
>
<view :style="{ width: '70%' }">
<nut-input
type="digit"
v-model="tempUp"
@blur="tUpValue"
@focus="onfocus"
placeholder="请输入温度告警上限"
:border="false"
input-align="right"
clearable
max-length="5"
:cursor="String(tempUp).length"
>
<template #right> </template>
</nut-input>
</view>
</nut-col>
<nut-col :span="24">
<nut-divider class="divider" />
</nut-col>
<nut-col :span="24" class="view_f">
<view :style="{ width: '30%' }" class="font_32 c_444"
>温度下限</view
>
<view :style="{ width: '70%' }">
<nut-input
type="digit"
v-model="tempLower"
@blur="tLoValue"
@focus="onfocus"
placeholder="请输入温度告警下限"
:border="false"
input-align="right"
clearable
max-length="5"
>
<template #right> </template>
</nut-input>
</view>
</nut-col>
</nut-row>
</view>
<view class="d_btn">
<nut-row>
<nut-col
:span="12"
:style="{ border: '1px solid #eee', color: '#222' }"
@click="openSetTemp = false"
>
取消
</nut-col>
<nut-col
:span="12"
:style="{ border: '1px solid #eee', color: '#15BBC5' }"
@click="setTempEventD"
>
确定
</nut-col>
</nut-row>
</view>
</view>
</nut-dialog>
<!-- 电量告警设置 -->
<nut-dialog v-model:visible="openSetBattery" text-align="left" no-footer>
<view :style="{ height: '100%' }">
<view class="d_body">
<nut-row>
<nut-col :span="24">
<view class="d_title">电量告警下限设置</view>
</nut-col>
<nut-col :span="24">
<nut-divider class="divider" />
</nut-col>
<nut-col :span="24" class="view_f">
<view :style="{ width: '40%' }" class="font_32 c_444"
>告警下限</view
>
<view :style="{ width: '60%' }">
<nut-input
type="digit"
v-model="battery"
@blur="batteryValue"
@focus="onfocus"
:border="false"
input-align="right"
clearable
max-length="5"
placeholder="范围1~7"
:cursor="String(battery).length"
>
<template #right> </template>
</nut-input>
</view>
</nut-col>
<nut-col :span="24">
<nut-divider class="divider" />
</nut-col>
</nut-row>
</view>
<view class="d_btn">
<nut-row>
<nut-col
:span="12"
:style="{ border: '1px solid #eee', color: '#222' }"
@click="openSetBattery = false"
>
取消
</nut-col>
<nut-col
:span="12"
:style="{ border: '1px solid #eee', color: '#15BBC5' }"
@click="setBatteryEventD"
>
确定
</nut-col>
</nut-row>
</view>
</view>
</nut-dialog>
<!-- 设备名称 -->
<nut-dialog v-model:visible="openSetName" text-align="left" no-footer>
<!-- <view :style="{ height: '100%' }"> -->
<view class="d_body">
<nut-row>
<nut-col :span="24">
<view class="d_title">设备名称设置</view>
</nut-col>
<nut-col :span="24">
<nut-divider class="divider" />
</nut-col>
<nut-col :span="24" class="view_f">
<view :style="{ width: '30%' }" class="font_32 c_444"
>名称</view
>
<view :style="{ width: '70%' }">
<nut-input
v-model="deviceName"
@focus="onfocus"
@blur="onblur"
placeholder="请输入设备名称"
:border="false"
input-align="right"
clearable
max-length="6"
:cursor="String(deviceName).length"
/>
</view>
</nut-col>
</nut-row>
</view>
<view class="d_btn">
<nut-row>
<nut-col
:span="12"
:style="{ border: '1px solid #eee', color: '#222' }"
@click="openSetName = false"
>
取消
</nut-col>
<nut-col
:span="12"
:style="{ border: '1px solid #eee', color: '#15BBC5' }"
@click="setNameEventD"
>
确定
</nut-col>
</nut-row>
</view>
<!-- </view> -->
</nut-dialog>
<!-- 盐度设置 -->
<nut-dialog v-model:visible="openSalinity" text-align="left" no-footer>
<view :style="{ height: '100%' }">
<view class="d_body">
<nut-row>
<nut-col :span="24">
<view class="d_title">盐度设置</view>
</nut-col>
<nut-col :span="24">
<nut-divider class="divider" />
</nut-col>
<nut-col :span="24" class="view_f">
<view :style="{ width: '30%' }" class="font_32 c_444"
>盐度</view
>
<view :style="{ width: '70%' }">
<nut-input
type="digit"
v-model="salinity"
@blur="salValue"
@focus="onfocus"
placeholder="请输入盐度"
:border="false"
input-align="right"
clearable
max-length="5"
:cursor="String(salinity).length"
>
<template #right> </template>
</nut-input>
</view>
</nut-col>
</nut-row>
</view>
<view class="d_btn">
<nut-row>
<nut-col
:span="12"
:style="{ border: '1px solid #eee', color: '#222' }"
@click="openSalinity = false"
>
取消
</nut-col>
<nut-col
:span="12"
:style="{ border: '1px solid #eee', color: '#15BBC5' }"
@click="setSalinityD"
>
确定
</nut-col>
</nut-row>
</view>
</view>
</nut-dialog>
<!-- 弹出层提示 -->
<nut-dialog v-model:visible="alertRes" text-align="center">
<template #default>
<view :style="{ height: '100%' }">
<nut-row>
<nut-col :span="24" class="font_36 c_222">
移除设备成功
</nut-col>
</nut-row>
</view>
</template>
<template #footer>
<view class="d_btn" :style="{ position: 'absolute' }">
<nut-row>
<nut-col
:span="24"
:style="{ border: '1px solid #eee', color: '#15BBC5' }"
>
<nut-button
type="primary"
shape="square"
block
@click="onGoBack"
>返回</nut-button
>
</nut-col>
</nut-row>
</view>
</template>
</nut-dialog>
</nut-config-provider>
</view>
</view>
</template>
<script setup lang="ts">
import { RectRight } from "@nutui/icons-vue-taro";
import {
deviceInfo,
deviceUnbind,
setWarnCall,
setOxyWarn,
setTempWarn,
deviceUpdateName,
deviceUpdatePond,
setSal,
deviceDel,
setBatteryWarn,
} from "@/api/device";
import { stateType } from "@/utils/types";
import { formatDate } from "@/utils/tools";
import { getPond2 } from "@/api/home";
import Taro from "@tarojs/taro";
import { debounce, throttle } from 'lodash';
const instance = Taro.getCurrentInstance();
const id = instance.router.params.id;
const name = instance.router.params.name;
const page = instance.router.params.page;
const section = instance.router.params.section; // 获取区域参数
// const name = undefined
Taro.setNavigationBarTitle({
title: "太阳能网控设置",
});
const store: any = inject("store");
// const id = instance.router.params.id
const themeVars = ref({
cellBorderRadius: "4px",
cellBoxShadow: "0px",
cellPadding: "26rpx 0px",
});
const themeVars2 = ref({
cellBoxShadow: "0px 0px 0px 0px",
cellPadding: "0",
cellColor: "#666666",
cellTitleFont: "32rpx",
cellTitleDescFont: "30rpx",
cellDescFont: "30rpx",
cellDescColor: "#222222",
popupBorderRadius: "10rpx",
});
const state: stateType = reactive({
msg: "",
type: "text",
center: true,
show: false,
});
const deviceInfoRes = ref({
id: undefined,
deviceName: undefined,
serialNum: undefined,
deviceType: 3,
bindTime: undefined,
deadTime: undefined,
pondInfo: {
id: undefined,
pondName: undefined,
},
isOxygenUsed: false,
oxyWarnTelOpen: false,
oxyWarnTelNoDis: false,
oxyWarnLower: undefined,
tempWarnTelOpen: false,
tempWarnUpper: undefined,
tempWarnLower: undefined,
salinityCompensation: undefined,
keepNightOpen: false,
inputVoltage: undefined,
listSwitch: undefined,
tempWarnTelNoDis: false,
listLinkedCtr: [],
// 太阳能网控特有属性
batteryWarnCallOpen: false,
batteryWarnCallNoDis: false,
batteryWarnLower: 2,
});
const showPond = ref<boolean>(false);
const openSetName = ref<boolean>(false);
const openSetOxy = ref<boolean>(false);
const openSetTemp = ref<boolean>(false);
const openSetBattery = ref<boolean>(false);
const openSalinity = ref<boolean>(false);
const alertRes = ref<boolean>(false);
const isScroll = ref<boolean>(true);
const salinity = ref<number>(30);
const pondList = ref<any[]>([]);
const pondId = ref();
const oxy = ref();
const tempLower = ref();
const tempUp = ref();
const battery = ref();
const deviceName = ref();
const r_isLoading = ref(false)
const b_isLoading = ref(false)
const Uid = Taro.getStorageSync("UserId")
const rootuserid = ref(store.getRootUserId);
// 判断是否为主账号:当前选中的是登录账号,且登录账号是主账号
const isMainAccount = computed(() => {
// 当前选中的必须是登录账号
if (Uid !== rootuserid.value) {
return false;
}
// 检查是否有父账号(如果有父账号,说明是子账号)
// 这里需要从 store 或 API 获取父账号列表,但为了简化,我们假设:
// 只有当前选中的是登录账号时才有解绑权限
return true;
});
/**--------------method start------------------- */
Taro.useDidShow(() => {
// 默认
getDevInfo();
getPondList();
});
// 查询塘口列表
function getPondList() {
getPond2().then((res: any) => {
if (res.code == 200) {
const arr = [{ id: 0, pondName: "无" }];
res.data.forEach(r => {
arr.push({ id: r.id, pondName: r.pondName })
})
pondList.value = arr;
}
});
}
// 设备详情
function getDevInfo() {
deviceInfo({ id }).then((res: any) => {
if (res.code == 200) {
res.data.bindTime = formatDate(new Date(res.data.bindTime));
res.data.deadTime = formatDate(new Date(res.data.deadTime));
// 将数字类型转为布尔类型
res.data.oxyWarnTelOpen = !!res.data.oxyWarnTelOpen;
res.data.oxyWarnTelNoDis = !!res.data.oxyWarnTelNoDis;
res.data.tempWarnTelOpen = !!res.data.tempWarnTelOpen;
res.data.tempWarnTelNoDis = !!res.data.tempWarnTelNoDis;
res.data.isOxygenUsed = !!res.data.isOxygenUsed;
// 太阳能网控特有属性
res.data.batteryWarnCallOpen = !!res.data.batteryWarnCallOpen;
res.data.batteryWarnCallNoDis = !!res.data.batteryWarnCallNoDis;
deviceInfoRes.value = res.data;
pondId.value = res.data.pondInfo ? [Number(res.data.pondInfo.id)] : [0];
}
});
}
// 格式化开关名称
function formatName(switchList: any) {
if (switchList && switchList.length > 0) {
const nameList = [];
switchList.forEach((res: any) => {
nameList.push(res.switchName);
});
return nameList.join(",");
}
return "/";
}
/** 解除绑定 */
function unbind() {
Taro.showModal({
title: "提示",
content:
"解除绑定后会将设备直接删除,并和塘口内的其他设备解除关联关系。再次绑定需重新扫码添加。确认解除绑定该设备?",
success: function (res) {
if (res.confirm) {
b_isLoading.value = true
deviceDel({ id }).then((res: any) => {
if (res.code == 200) {
state.show = true;
state.msg = "解绑成功";
setTimeout(() => {
if (page == "home") {
Taro.switchTab({
url: "/pages/main/home",
});
} else {
Taro.navigateBack({ delta: 1 });
}
}, 200);
// deviceInfoRes.value.pondInfo = {
// id: undefined,
// pondName: undefined,
// }
// pondId.value = 0
}
}).finally(() => {
b_isLoading.value = false
})
} else if (res.cancel) {
console.log("用户点击取消");
}
},
});
}
// 跳转到联动控制
function openLink() {
// 跳转到联动控制页面
Taro.navigateTo({
url: `/home/linkControl?id=${id}&pondId=${
pondId.value[0] ? pondId.value[0] : 0
}`,
});
}
// 确定选择塘口
function confirm({ selectedValue, selectedOptions }) {
console.log(selectedValue)
pondId.value = selectedValue;
deviceInfoRes.value.pondInfo = {
id: selectedValue,
pondName: selectedOptions[0].pondName,
};
const data = {
id,
pondId: selectedValue[0],
};
deviceUpdatePond(data)
.then((res: any) => {
if (res.code == 200) {
state.show = true;
state.msg = "设置成功";
} else {
state.show = true;
state.msg = res.msg || "设置失败";
}
})
.catch((error) => {
console.error('[绑定塘口] 失败:', error);
state.show = true;
state.msg = "网络错误,设置失败";
})
.finally(() => {
showPond.value = false;
});
}
// 取消选择塘口
function cancel() {
showPond.value = false;
}
// 设置溶解氧/水温告警
function changeO2(value, event) {
if (event) {
const data = {
deviceId: id,
type: 1,
isOpen: deviceInfoRes.value.oxyWarnTelOpen ? 1 : 0, // 布尔转数字
isNoDisturb: deviceInfoRes.value.oxyWarnTelOpen
? (deviceInfoRes.value.oxyWarnTelNoDis ? 1 : 0) // 布尔转数字
: 0,
};
setWarnCall(data).then((res) => {
if (res.code == 200) {
state.show = true;
state.msg = "设置成功";
} else {
state.show = true;
state.msg = res.msg || "设置失败";
}
}).catch((error) => {
console.error('[溶解氧告警开关] 失败:', error);
state.show = true;
state.msg = "网络错误,设置失败";
}).finally(() => {
getDevInfo();
});
}
}
function changeTem(value, event) {
if (event) {
const data = {
deviceId: id,
type: 2,
isOpen: deviceInfoRes.value.tempWarnTelOpen ? 1 : 0, // 布尔转数字
isNoDisturb: deviceInfoRes.value.tempWarnTelOpen
? (deviceInfoRes.value.tempWarnTelNoDis ? 1 : 0) // 布尔转数字
: 0,
};
setWarnCall(data).then((res) => {
if (res.code == 200) {
state.show = true;
state.msg = "设置成功";
} else {
state.show = true;
state.msg = res.msg || "设置失败";
}
}).catch((error) => {
console.error('[温度告警开关] 失败:', error);
state.show = true;
state.msg = "网络错误,设置失败";
}).finally(() => {
getDevInfo();
});
}
}
// 设置溶解氧/温度上下限
function setOxy() {
openSetOxy.value = true;
oxy.value = deviceInfoRes.value.oxyWarnLower;
}
// 设置设备名称
function setName() {
openSetName.value = true;
deviceName.value = deviceInfoRes.value.deviceName;
}
const setOxyEventD = debounce(setOxyEvent, 300);
function setOxyEvent() {
if (oxy.value) {
if (Number(oxy.value) < 1.5 || Number(oxy.value) > 20) {
state.show = true;
state.msg = "告警值范围为1.5-20";
return;
}
} else {
state.show = true;
state.msg = "请输入告警值";
return;
}
const data = {
deviceId: id,
oxyWarnLower: oxy.value,
};
setOxyWarn(data).then((res) => {
if (res.code == 200) {
state.show = true;
state.msg = "设置成功";
deviceInfoRes.value.oxyWarnLower = oxy.value;
openSetOxy.value = false;
} else {
state.show = true;
state.msg = res.msg || "设置失败";
}
}).catch((error) => {
console.error('[溶解氧阈值设置] 失败:', error);
state.show = true;
state.msg = "网络错误,设置失败";
});
}
const setNameEventD = debounce(setNameEvent, 300);
function setNameEvent() {
const data = {
id,
newName: deviceName.value,
};
deviceUpdateName(data).then((res) => {
if (res.code == 200) {
state.show = true;
state.msg = "设置成功";
openSetName.value = false;
// 重新加载设备信息
getDevInfo();
} else {
state.show = true;
state.msg = res.msg || "设置失败";
}
}).catch((error) => {
console.error('[设备名称设置] 失败:', error);
state.show = true;
state.msg = "网络错误,设置失败";
});
}
function setTemp() {
openSetTemp.value = true;
tempUp.value = deviceInfoRes.value.tempWarnUpper;
tempLower.value = deviceInfoRes.value.tempWarnLower;
}
const setTempEventD = debounce(setTempEvent, 300);
function setTempEvent() {
const up = tempUp.value;
const lo = tempLower.value;
if (Number(lo) >= Number(up)) {
state.show = true;
state.msg = "下限不能大于等于上限";
return;
}
if (!lo) {
state.show = true;
state.msg = "请输入下限值";
return;
}
if (!up) {
state.show = true;
state.msg = "请输入上限值";
return;
}
const data = {
deviceId: id,
tempWarnLower: tempLower.value,
tempWarnUpper: tempUp.value,
};
setTempWarn(data).then((res) => {
if (res.code == 200) {
state.show = true;
state.msg = "设置成功";
deviceInfoRes.value.tempWarnUpper = tempUp.value;
deviceInfoRes.value.tempWarnLower = tempLower.value;
openSetTemp.value = false;
} else {
state.show = true;
state.msg = res.msg || "设置失败";
}
}).catch((error) => {
console.error('[温度阈值设置] 失败:', error);
state.show = true;
state.msg = "网络错误,设置失败";
});
}
// 溶解氧告警
function oxyValue() {
onblur();
}
// 温度告警
function tUpValue() {
onblur();
}
function tLoValue() {
onblur();
}
// 盐度设置
function setSalFunc() {
openSalinity.value = true;
salinity.value = deviceInfoRes.value.salinityCompensation;
}
function salValue() {
const sal = salinity.value;
onblur();
if (Number(sal) > 40) {
salinity.value = 40;
}
}
const setSalinityD = debounce(setSalinity, 300);
function setSalinity() {
onblur();
const data = {
id,
salinityCompensation: salinity.value ? Number(salinity.value) : 0,
};
setSal(data).then((res) => {
if (res.code == 200) {
state.show = true;
state.msg = "设置成功";
deviceInfoRes.value.salinityCompensation = salinity.value;
openSalinity.value = false;
} else {
state.show = true;
state.msg = res.msg || "设置失败";
}
}).catch((error) => {
console.error('[盐度设置] 失败:', error);
state.show = true;
state.msg = "网络错误,设置失败";
});
}
//跳转校准页面
function toCalibration() {
Taro.navigateTo({ url: `/home/calibration?id=${id}&page=wqm` });
}
// 免打扰设置-溶解氧
function changeOxyDis(value, event) {
if (event) {
const data = {
deviceId: id,
type: 1,
isOpen: deviceInfoRes.value.oxyWarnTelOpen ? 1 : 0, // 布尔转数字
isNoDisturb: deviceInfoRes.value.oxyWarnTelOpen
? (deviceInfoRes.value.oxyWarnTelNoDis ? 1 : 0) // 布尔转数字
: 0,
};
setWarnCall(data).then((res) => {
if (res.code == 200) {
state.show = true;
state.msg = "设置成功";
} else {
state.show = true;
state.msg = res.msg || "设置失败";
}
}).catch((error) => {
console.error('[溶解氧免打扰] 失败:', error);
state.show = true;
state.msg = "网络错误,设置失败";
}).finally(() => {
getDevInfo();
});
}
}
// 免打扰设置-温度
function changeTemDis(value, event) {
if (event) {
const data = {
deviceId: id,
type: 2,
isOpen: deviceInfoRes.value.tempWarnTelOpen ? 1 : 0, // 布尔转数字
isNoDisturb: deviceInfoRes.value.tempWarnTelOpen
? (deviceInfoRes.value.tempWarnTelNoDis ? 1 : 0) // 布尔转数字
: 0,
};
setWarnCall(data).then((res) => {
if (res.code == 200) {
state.show = true;
state.msg = "设置成功";
} else {
state.show = true;
state.msg = res.msg || "设置失败";
}
}).catch((error) => {
console.error('[温度免打扰] 失败:', error);
state.show = true;
state.msg = "网络错误,设置失败";
}).finally(() => {
getDevInfo();
});
}
}
// 电量电话告警开关
function changeBattery(value, event) {
if (event) {
const data = {
deviceId: id,
type: 3,
isOpen: deviceInfoRes.value.batteryWarnCallOpen ? 1 : 0,
isNoDisturb: deviceInfoRes.value.batteryWarnCallOpen
? (deviceInfoRes.value.batteryWarnCallNoDis ? 1 : 0)
: 0,
};
setWarnCall(data).then((res) => {
if (res.code == 200) {
state.show = true;
state.msg = "设置成功";
} else {
state.show = true;
state.msg = res.msg || "设置失败";
}
}).catch((error) => {
console.error('[电量告警开关] 失败:', error);
state.show = true;
state.msg = "网络错误,设置失败";
}).finally(() => {
getDevInfo();
});
}
}
// 电量告警免打扰
function changeBatteryDis(value, event) {
if (event) {
const data = {
deviceId: id,
type: 3,
isOpen: deviceInfoRes.value.batteryWarnCallOpen ? 1 : 0,
isNoDisturb: deviceInfoRes.value.batteryWarnCallOpen
? (deviceInfoRes.value.batteryWarnCallNoDis ? 1 : 0)
: 0,
};
setWarnCall(data).then((res) => {
if (res.code == 200) {
state.show = true;
state.msg = "设置成功";
} else {
state.show = true;
state.msg = res.msg || "设置失败";
}
}).catch((error) => {
console.error('[电量免打扰] 失败:', error);
state.show = true;
state.msg = "网络错误,设置失败";
}).finally(() => {
getDevInfo();
});
}
}
// 设置电量告警下限
function setBattery() {
openSetBattery.value = true;
battery.value = deviceInfoRes.value.batteryWarnLower;
}
// 电量告警值验证
function batteryValue() {
onblur();
const val = battery.value;
if (Number(val) < 1 || Number(val) > 7) {
battery.value = 2;
}
}
const setBatteryEventD = debounce(setBatteryEvent, 300);
function setBatteryEvent() {
if (battery.value) {
if (Number(battery.value) < 1 || Number(battery.value) > 7) {
state.show = true;
state.msg = "电量告警下限范围为1-7";
return;
}
} else {
state.show = true;
state.msg = "请输入电量告警下限";
return;
}
const data = {
deviceId: id,
batteryWarnLower: battery.value,
};
setBatteryWarn(data).then((res) => {
if (res.code == 200) {
state.show = true;
state.msg = "设置成功";
deviceInfoRes.value.batteryWarnLower = battery.value;
openSetBattery.value = false;
} else {
state.show = true;
state.msg = res.msg || "设置失败";
}
}).catch((error) => {
console.error('[电量告警下限设置] 失败:', error);
state.show = true;
state.msg = "网络错误,设置失败";
});
}
// 返回上一页
function onGoBack() {
Taro.navigateBack({ delta: 1 });
}
function onfocus() {
isScroll.value = false;
}
function onblur() {
isScroll.value = true;
}
/**--------------method end--------------------- */
</script>
<style lang="scss">
.wqm_home {
width: 100%;
height: 100%;
background-image: url("https://www.yuceyun.cn/wechat/bg.jpg");
background-color: #e5ebed;
background-repeat: no-repeat;
background-size: 100% 100%;
position: fixed;
margin: 0;
font-size: 32px;
font-family: "PingFang SC";
font-weight: 400;
.nut-dialog {
padding: 0;
}
.nut-dialog__content {
margin: 0;
// max-height: 100%;
}
.nut-input {
padding: 20rpx 0;
}
.body {
padding: 20px;
.title {
font-size: 36px;
font-weight: bold;
color: #222;
}
.wqm_body {
padding: 20px;
.nut-cell__title {
font-size: 30px;
color: #666;
}
.desc {
font-size: 30px;
color: #222;
font-weight: bold;
}
.ils {
font-size: 30px;
color: #1589e9;
}
.c_title {
font-size: 30px;
color: #666;
}
.c_dis {
font-size: 26px;
color: #eb913e;
margin-top: 10rpx;
}
.d_title {
font-size: 30px;
color: #17b4b2;
}
.d_dis {
font-size: 30px;
color: #222222;
}
.nut-table {
display: flex;
flex-direction: column;
font-size: var(--nut-font-size-2, 14px);
width: 100%;
}
.nut-table__main {
border-collapse: collapse;
display: table;
overflow-x: hidden;
width: 100%;
}
.nut-table__main__body {
display: table-row-group;
}
.nut-table__main__body__tr,
.nut-table__main__head__tr {
display: table-row;
}
}
}
}
.tableTou {
font-size: 28px;
color: #222222 !important;
}
.tr {
width: 100%;
}
.tableTR {
border: 1rpx solid #e6e6e6;
width: 100%;
display: flex;
background-color: #fff;
height: 55rpx;
justify-content: center;
align-items: center;
color: #17b4b2;
font-size: 28px;
}
/* 联动控制表格优化样式 */
.linked-table {
width: 100%;
border-radius: 8px;
overflow: hidden;
background: #fff;
}
.table-row {
display: flex;
border-bottom: 1px solid #f0f0f0;
&:last-child {
border-bottom: none;
}
}
.table-header {
background: #f8f8f8;
font-weight: bold;
.table-cell {
color: #666;
font-size: 26rpx;
}
}
.table-cell {
flex: 1;
padding: 20rpx 10rpx;
text-align: center;
border-right: 1px solid #f0f0f0;
display: flex;
align-items: center;
justify-content: center;
min-height: 80rpx;
&:last-child {
border-right: none;
}
}
.table-label {
flex: 0 0 100rpx;
background: #fafafa;
font-size: 28rpx;
color: #333;
font-weight: 500;
}
.table-value {
color: #17b4b2;
font-size: 28rpx;
font-weight: 500;
}
.table-switch {
padding: 10rpx;
}
.switch-names {
display: flex;
flex-direction: column;
gap: 8rpx;
width: 100%;
}
.switch-name {
font-size: 24rpx;
color: #17b4b2;
padding: 6rpx 10rpx;
background: #f5f5f5;
border-radius: 4rpx;
line-height: 1.4;
word-break: break-all;
text-align: center;
}
</style>