Sprinkler-app/page_newyemian/wgkongzhi.vue
2026-01-17 17:37:00 +08:00

872 lines
21 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 class="" style="padding-bottom: 50rpx;box-sizing: border-box;">
<u-navbar title="设备控制" :border-bottom="false" :background="bgc" title-color='#000' back-icon-color="#000" :custom-back="btnshang"
title-size='36' height='50'></u-navbar>
<view class="iptbox">
<view class="qrcode" @click="qrcode()">
<image src="https://api.ccttiot.com/smartmeter/img/static/uy7BNwAMIKwvstqFnRhs" mode=""></image>
</view>
<input type="text" class="ips" v-model="storeId" placeholder="请扫描设备上的二维码" style="margin-left: 32rpx;" placeholder-class="my-placeholder"/>
<view class="" style="width: 140rpx;height: 60rpx;background-color: #52c41a;text-align: center;line-height: 60rpx;border-radius: 8rpx;color: #fff;" @click="btnly" v-if="obj.mac">
蓝牙
</view>
</view>
<!-- <view class="machao">
网关MAC号{{obj.mac == undefined ? '--' : obj.mac}} <text v-if="onlineStatus == '离线'" style="color: red;margin-left: 50rpx;">离线</text> <text v-if="onlineStatus == '在线'" style="color: green;margin-left: 50rpx;">在线</text>
</view> -->
<!-- 网关信息卡片 -->
<view class="device-info-card" v-if="obj.dataPoints">
<!-- 设备头部信息 -->
<view class="device-header">
<view class="device-header-info" style="display: flex;justify-content: space-between;align-items: center;">
<view class="device-name" style="display: flex;justify-content: space-between;align-items: center;">
网关信息
<view class="device-status-row" style="margin-left: 20rpx;">
<view class="status-badge" :class="{'status-online': onlineStatus == '在线', 'status-offline': onlineStatus == '离线'}">
{{onlineStatus}}
</view>
</view>
</view>
<view class="info-item" style="font-size: 22rpx;font-weight: 400;color: #ccc;">
<text class="info-value">{{obj.mac || '--'}}</text>
</view>
</view>
</view>
<!-- 状态信息 -->
<view class="info-section" style="border-top: 1rpx solid #f0f0f0;padding-top: 20rpx;">
<view class="section-title">网关信息</view>
<view class="info-grid">
<view class="info-item">
<text class="info-label">VER</text>
<text class="info-value">{{obj.dataPoints && obj.dataPoints.VER ? obj.dataPoints.VER.value : '--'}}</text>
</view>
<view class="info-item" style="position: relative;">
<text class="info-label">CSQ</text>
<view style="display: flex;align-items: center;gap: 10rpx;">
<text class="info-value" style="flex: 1;">{{obj.dataPoints && obj.dataPoints.CSQ ? obj.dataPoints.CSQ.value : '--'}}</text>
<view class="update-btn" @click="updateCSQ">
<text class="update-icon">↻</text>
<text class="update-text">更新</text>
</view>
</view>
</view>
</view>
</view>
</view>
<view class="zisb" style="width: 658rpx;margin: auto;">
<view class="tit" style="margin-top: 30rpx;">
子设备信息
</view>
</view>
<!-- 设备详细信息卡片 -->
<view class="device-info-card" v-if="macobj.deviceId">
<!-- 设备头部信息 -->
<view class="device-header">
<image v-if="macobj.picture || macobj.modelPicture" :src="macobj.picture || macobj.modelPicture" class="device-image" mode="aspectFill"></image>
<view class="device-header-info">
<view class="device-name" style="display: flex;justify-content: space-between;align-items: center;">
{{macobj.deviceName || macobj.modelName || '--'}}
<view class="info-item" style="font-size: 22rpx;font-weight: 400;color: #ccc;">
<text class="info-value">{{macobj.mac || '--'}}</text>
</view></view>
<view class="device-status-row">
<view class="status-badge" :class="{'status-online': macobj.onlineStatus == '1', 'status-offline': macobj.onlineStatus == '0'}">
{{macobj.onlineStatus == '1' ? '在线' : '离线'}}
</view>
<text class="device-version" v-if="macobj.version">版本: {{macobj.dataPoints.ver.value == null ? '--' : macobj.dataPoints.ver.value}}</text>
<text class="device-version" v-if="macobj.dataPoints.RSSI">信号:{{macobj.dataPoints.RSSI.value == null ? '--' : macobj.dataPoints.RSSI.value}}</text>
<view class="signal-strength" v-if="macobj.bluetoothDbm !== null && macobj.bluetoothDbm !== undefined">
<view class="signal-bars">
<view class="signal-bar" :class="{'active': getSignalLevel(macobj.bluetoothDbm) >= 1}"></view>
<view class="signal-bar" :class="{'active': getSignalLevel(macobj.bluetoothDbm) >= 2}"></view>
<view class="signal-bar" :class="{'active': getSignalLevel(macobj.bluetoothDbm) >= 3}"></view>
<view class="signal-bar" :class="{'active': getSignalLevel(macobj.bluetoothDbm) >= 4}"></view>
</view>
<text class="signal-value">{{macobj.bluetoothDbm}}dBm</text>
</view>
</view>
</view>
</view>
<text class="device-version" style="margin-bottom: 20rpx;display: block;" v-if="macobj.dataPoints.RSSI">更新时间: {{macobj.dataPoints.RSSI.at == null ? '--' : macobj.dataPoints.RSSI.at}}</text>
<!-- 状态信息 -->
<view class="info-section" style="border-top: 1rpx solid #f0f0f0;padding-top: 20rpx;">
<view class="section-title">状态信息</view>
<view class="info-grid">
<view class="info-item">
<text class="info-label">在线状态</text>
<text class="info-value" :style="{color: macobj.onlineStatus == '1' ? '#52c41a' : '#ff4d4f'}">
{{macobj.onlineStatus == '1' ? '在线' : '离线'}}
</text>
</view>
<view class="info-item">
<text class="info-label">设备状态</text>
<text class="info-value" style="font-size: 36rpx;font-weight: 600;">{{getDeviceStatus()}}</text>
</view>
</view>
</view>
</view>
<view class="list">
<view class="anniulist">
<view class="anniu" @click="btngbkq">
开启
</view>
<view class="anniu" @click="btngb">
关闭
</view>
<view class="anniu" @click="getmacs">
刷新
</view>
</view>
<view class="fanhui" @click="btnfh">
返回
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
bgc: {
backgroundColor: "#FAFDFD",
},
storeId: '',
obj: {},
id: '',
onlineStatus: '--',
powerStatus: '--',
message: '定时器未启动',
intervalId: null, // 用于存储定时器的ID
wdxsn:'',
wdxsw:'',
xsN:'',
xsW:'',
valuedian:1000,
xshu:'1',
x:'',
macsb:'',
macobj:{}
}
},
onLoad(options) {
if (options.sn) {
this.storeId = options.sn
this.getsn()
}
},
onUnload() {
// 页面卸载时清除定时器
this.clearInterval()
},
onHide() {
// 页面隐藏时清除定时器(可选,根据需求决定是否添加)
this.clearInterval()
},
beforeDestroy() {
// 组件销毁前清除定时器(可选,根据需求决定是否添加)
this.clearInterval()
},
methods: {
btnly(){
uni.reLaunch({
url:'/page_newyemian/wgluru'
})
},
btnshang(){
uni.reLaunch({
url:'/page_newyemian/wgluru'
})
},
// 根据信号强度计算信号格数1-4格
getSignalLevel(dbm) {
if (dbm === null || dbm === undefined) {
return 0;
}
// 信号强度分级:-50到-60为满格-60到-70为3格-70到-80为2格-80到-90为1格
if (dbm >= -60) {
return 4; // 满格
} else if (dbm >= -70) {
return 3;
} else if (dbm >= -80) {
return 2;
} else if (dbm >= -90) {
return 1;
} else {
return 0; // 信号太弱,不显示
}
},
getver() {
if (!this.macobj || !this.macobj.dataPoints) {
return '--';
}
return this.macobj.dataPoints.ver
},
// 获取设备状态根据dataPoints.d判断
getDeviceStatus() {
if (!this.macobj || !this.macobj.dataPoints) {
return '--';
}
const d = this.macobj.dataPoints.water_sw.value;
if (d === 0 || d === '0') {
return '关闭';
} else if (d === 1 || d === '1') {
return '开启';
} else {
return '--';
}
},
startInterval() {
// 每五秒执行一次的方法
const timerCallback = () => {
if(this.storeId == '' || this.storeId == null || this.obj == null){
this.clearInterval()
}else{
this.$u.get(`/app/beehive/admin/sn/${this.storeId}?refresh=true`).then(res => {
if (res.code == 200) {
this.obj = res.data
this.xsW = res.data.xsW
this.xsN = res.data.xsN
this.id = res.data.deviceId
if (res.data.onlineStatus == 0) {
this.onlineStatus = '离线'
} else if (res.data.onlineStatus == 1) {
this.onlineStatus = '在线'
}
if (res.data.powerStatus == 0) {
this.powerStatus = '关闭'
} else if (res.data.powerStatus == 1) {
this.powerStatus = '开启'
}
}
})
}
}
// 启动定时器并将ID存储在intervalId中
this.intervalId = setInterval(timerCallback, 5000)
},
clearInterval() {
// 清除定时器
if (this.intervalId !== null) {
clearInterval(this.intervalId)
this.intervalId = null
}
},
// 进行扫描二维码获取设备sn
qrcode() {
uni.scanCode({
onlyFromCamera: true,
scanType: ['qrCode'],
success: res => {
function getQueryParam(url, paramName) {
let regex = new RegExp(`[?&]${paramName}=([^&]*)`)
let results = regex.exec(url);
return results ? decodeURIComponent(results[1].replace(/\+/g, ' ')) : null
}
let sceneValue = res.result
let decodedValue = decodeURIComponent(sceneValue)
let id = getQueryParam(decodedValue, 's')
this.storeId = id
this.getsn()
},
fail: err => {
console.error('扫描失败:', err)
uni.showToast({
title: '扫描失败',
icon: 'none'
})
}
})
},
// 根据设备sn获取设备详情
getsn() {
this.$u.get(`/device/device/getDetail?sn=${this.storeId}`).then(res => {
if (res.code == 200) {
if(res.data == null){
this.clearInterval()
}else{
this.obj = res.data
this.getmac()
if (res.data.onlineStatus == 0) {
this.onlineStatus = '离线'
} else if (res.data.onlineStatus == 1) {
this.onlineStatus = '在线'
}
}
} else {
uni.showToast({
title:'错误' + res.msg,
icon: 'none',
duration: 2000,
})
this.clearInterval()
}
})
},
// 更新CSQ
updateCSQ() {
uni.showLoading({
title: '更新中...',
mask: true,
icon: 'none'
})
let data = {
mac:this.obj.mac,
command:'CSQ'
}
this.$u.post(`/as/deviceGateway/sendCommandToGateway`,data).then(res => {
if (res.code == 200 && res.data.success == true) {
this.getsn()
setTimeout(()=>{
uni.hideLoading()
uni.showToast({
title: '更新成功',
icon: 'success',
duration: 2000
})
},1000)
} else {
uni.showToast({
title: res.data.msg,
icon: 'none',
duration: 2000
})
uni.hideLoading()
}
}).catch(err => {
uni.hideLoading()
uni.showToast({
title: '更新失败',
icon: 'none',
duration: 2000
})
})
},
// 返回录入
btnfh() {
uni.reLaunch({
url:'/page_newyemian/wgluru'
})
},
//点击刷新
getmacs(){
uni.showLoading({
title: '刷新中...',
mask: true,
icon: 'none'
})
setTimeout(()=>{
this.$u.get(`/system/config/configKey/device.gateway.test.mac`).then(res =>{
if(res.code == 200){
this.macsb = res.data
this.$u.get(`/device/device/getDetail?mac=${this.macsb}&gatewayMacList=${this.obj.mac}`).then(resp =>{
if(resp.code == 200){
this.getsn()
this.id = resp.data.deviceId
this.macobj = resp.data
uni.showToast({
title: '刷新成功',
icon: 'success',
duration: 2000
})
uni.hideLoading()
}else{
uni.showToast({
title: '错误' + resp.msg,
icon: 'none',
duration: 2000
})
uni.hideLoading()
}
})
}else{
uni.showToast({
title: '错误' + res.msg,
icon: 'none',
duration: 2000
})
uni.hideLoading()
}
})
},1000)
},
// 自动刷新
getmac(){
this.$u.get(`/system/config/configKey/device.gateway.test.mac`).then(res =>{
if(res.code == 200){
this.macsb = res.data
this.$u.get(`/device/device/getDetail?mac=${this.macsb}&gatewayMacList=${this.obj.mac}`).then(resp =>{
if(resp.code == 200){
this.id = resp.data.deviceId
this.macobj = resp.data
}else{
uni.showToast({
title: '错误' + resp.msg,
icon: 'none',
duration: 2000
})
}
})
}else{
uni.showToast({
title: '错误' + res.msg,
icon: 'none',
duration: 2000
})
}
})
},
// 关闭
btngb() {
uni.showLoading({
title: '关闭中...',
mask: true,
icon: 'none'
})
let data = {
deviceMac:this.macsb,
gatewayMac:this.obj.mac
}
this.$u.post(`/device/device/close/specGateway`,data).then((res) => {
if (res.code == 200) {
setTimeout(() => {
this.btnsx()
}, 1000)
uni.showToast({
title: res.msg,
icon: 'success',
duration: 2000
})
} else {
uni.hideLoading()
uni.showToast({
title: '错误' + res.msg,
icon: 'none',
duration: 2000
})
}
})
},
// 开启
btngbkq() {
uni.showLoading({
title: '开启中...',
mask: true,
icon: 'none'
})
let data = {
deviceMac:this.macsb,
second:180,
gatewayMac:this.obj.mac
}
this.$u.post(`/device/device/time/specGateway`,data).then((res) => {
if (res.code == 200) {
setTimeout(() => {
this.btnsx()
}, 1000)
uni.showToast({
title: res.msg,
icon: 'success',
duration: 2000
})
} else {
uni.hideLoading()
uni.showToast({
title: '错误' + res.msg,
icon: 'none',
duration: 2000
})
}
})
},
// 刷新
btnsx() {
this.$u.get(`/device/device/getDetail?mac=${this.macsb}&gatewayMacList=${this.obj.mac}`).then(resp =>{
if(resp.code == 200){
this.id = resp.data.deviceId
this.macobj = resp.data
uni.hideLoading()
}else{
uni.hideLoading()
uni.showToast({
title: '错误' + resp.msg,
icon: 'none',
duration: 2000
})
}
})
}
}
}
</script>
<style lang="less">
.jiaozhun{
display: flex;
padding:0 50rpx;
box-sizing: border-box;
width: 100%;
align-items: center;
justify-content: space-between;
button{
height: 80rpx;
line-height: 80rpx;
background-color: #52c41a;
color: #fff;
}
.input{
input{
height: 80rpx;
line-height: 80rpx;
}
border: 1px solid #ccc;
border-radius: 20rpx;
display: flex;
width: 260rpx;
height: 80rpx;
text-align: center;
}
.view{
width: 200rpx;
height: 80rpx;
border-radius: 20rpx;
background-color: #52c41a;
color: #fff;
text-align: center;
line-height: 80rpx;
font-size: 28rpx;
}
}
.list {
margin-top: 30rpx;
position: fixed;
left: 50%;
transform: translateX(-50%);
bottom: 50rpx;
.anniulist {
width: 658rpx;
margin: auto;
text-align: left;
font-size: 32rpx;
display: flex;
justify-content: space-between;
.anniu {
width: 30%;
height: 90rpx;
border-radius: 20rpx;
background-color: #52c41a;
color: #fff;
font-size: 32rpx;
text-align: center;
line-height: 90rpx;
margin: 0 10rpx;
}
}
.fanhui {
width: 658rpx;
height: 90rpx;
border-radius: 20rpx;
background-color: #52c41a;
color: #fff;
font-size: 32rpx;
text-align: center;
line-height: 90rpx;
margin: auto;
margin-top: 50rpx;
}
}
.machao {
width: 658rpx;
margin: auto;
margin-top: 20rpx;
text-align: left;
font-size: 32rpx;
display: flex;
align-items: center;
.one{
width: 320rpx;
}
input{
width: 100rpx;
height: 40rpx;
border: 1px solid #52c41a;
margin-left: 50rpx;
text-align: center;
border-radius: 10rpx;
}
view{
margin-left: 20rpx;
padding: 10rpx 20rpx;
box-sizing: border-box;
background-color: #52c41a;
color: #fff;
border-radius: 10rpx;
margin-right: 10rpx;
}
}
.title {
font-size: 70rpx;
font-weight: 600;
text-align: left;
width: 658rpx;
margin: auto;
margin-top: 30rpx;
}
.shuom {
width: 658rpx;
margin: auto;
margin-top: 30rpx;
text-align: left;
font-size: 32rpx;
}
.iptbox {
display: flex;
align-items: center;
flex-wrap: nowrap;
padding: 22rpx;
margin: 28rpx auto 0;
width: 658rpx;
height: 88rpx;
background: #FFFFFF;
box-shadow: 0rpx 0rpx 8rpx 0rpx rgba(0, 0, 0, 0.15);
border-radius: 20rpx 20rpx 20rpx 20rpx;
.qrcode {
padding-right: 20rpx;
border-right: 2rpx solid #D8D8D8;
image {
width: 54rpx;
height: 54rpx;
}
}
.ips {
width: 630rpx;
}
image {
width: 18rpx;
height: 32rpx;
}
.my-placeholder {
font-weight: 400;
font-size: 32rpx;
color: #808080;
}
}
.tit {
font-size: 36rpx;
font-weight: 600;
color: #333;
}
// 设备信息卡片
.device-info-card {
width: 658rpx;
margin: 30rpx auto;
background: #FFFFFF;
border-radius: 20rpx;
padding: 30rpx;
box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.08);
.device-header {
display: flex;
align-items: center;
padding-bottom: 30rpx;
.device-image {
width: 120rpx;
height: 120rpx;
border-radius: 16rpx;
margin-right: 24rpx;
background: #f5f5f5;
}
.device-header-info {
flex: 1;
.device-name {
font-size: 36rpx;
font-weight: 600;
color: #333;
margin-bottom: 16rpx;
}
.device-status-row {
display: flex;
align-items: center;
flex-wrap: wrap;
gap: 16rpx;
.status-badge {
padding: 8rpx 20rpx;
border-radius: 20rpx;
font-size: 24rpx;
&.status-online {
background: #e6f7e6;
color: #52c41a;
}
&.status-offline {
background: #fff1f0;
color: #ff4d4f;
}
}
.device-version {
font-size: 24rpx;
color: #999;
}
.signal-strength {
display: flex;
align-items: center;
gap: 8rpx;
.signal-bars {
display: flex;
align-items: flex-end;
gap: 3rpx;
height: 24rpx;
.signal-bar {
width: 6rpx;
background: #e0e0e0;
border-radius: 2rpx;
transition: all 0.3s;
&:nth-child(1) {
height: 8rpx;
}
&:nth-child(2) {
height: 12rpx;
}
&:nth-child(3) {
height: 16rpx;
}
&:nth-child(4) {
height: 20rpx;
}
&.active {
background: #52c41a;
}
}
}
.signal-value {
font-size: 22rpx;
color: #999;
}
}
}
}
}
.info-section {
margin-bottom: 30rpx;
&:last-child {
margin-bottom: 0;
}
.section-title {
font-size: 32rpx;
font-weight: 600;
color: #333;
margin-bottom: 20rpx;
padding-left: 16rpx;
border-left: 6rpx solid #52c41a;
}
.info-grid {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 20rpx;
.info-item {
background: #fafafa;
border-radius: 12rpx;
padding: 20rpx;
display: flex;
flex-direction: column;
.info-label {
font-size: 24rpx;
color: #999;
margin-bottom: 8rpx;
}
.info-value {
font-size: 28rpx;
color: #333;
font-weight: 500;
word-break: break-all;
width: 170rpx;
}
.info-value-group {
display: flex;
flex-direction: column;
.info-value {
margin-bottom: 4rpx;
}
.info-time {
font-size: 22rpx;
color: #999;
}
}
.update-btn {
padding: 8rpx 16rpx;
border: none;
border-radius: 8rpx;
background: linear-gradient(135deg, #52c41a 0%, #73d13d 100%);
cursor: pointer;
transition: all 0.3s;
flex-shrink: 0;
display: flex;
align-items: center;
justify-content: center;
gap: 4rpx;
box-shadow: 0 2rpx 8rpx rgba(82, 196, 26, 0.3);
.update-icon {
font-size: 22rpx;
color: #fff;
line-height: 1;
font-weight: bold;
display: inline-block;
transition: transform 0.3s;
}
.update-text {
font-size: 22rpx;
color: #fff;
line-height: 1;
font-weight: 500;
}
&:active {
background: linear-gradient(135deg, #389e0d 0%, #52c41a 100%);
box-shadow: 0 1rpx 4rpx rgba(82, 196, 26, 0.4);
transform: scale(0.95);
.update-icon {
transform: rotate(180deg);
}
}
}
}
}
}
}
</style>