Sprinkler-app/page_newyemian/wgkongzhi.vue

872 lines
21 KiB
Vue
Raw Normal View History

2026-01-17 17:37:00 +08:00
<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>