Sprinkler-app/pages/gateway/xq.vue
2026-03-26 17:48:21 +08:00

819 lines
18 KiB
Vue
Raw Permalink 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="page">
<u-navbar :title="$t('gateway.detailTitle')" :border-bottom="false" :background="bgc" title-color='#262B37' title-size='38'
height='40'></u-navbar>
<!-- 左上角信号和版本信息 -->
<view class="top-info">
<view class="info-item" style="display: flex;align-items: center;font-size: 26rpx;color: #737070;margin-top: 20rpx;margin-left: 20rpx;">
<view class="info-icon-wrapper signal-icon">
<text class="iconfont icon-xinhao">{{ $t('gateway.signal') }}</text>
</view>
<text class="info-value" v-if="wgxq.iotData.CSQ">{{ wgxq.iotData.CSQ.value }}</text>
<text class="info-value" v-else>--</text>
</view>
<view class="info-item" style="display: flex;align-items: center;font-size: 26rpx;color: #737070;margin-top: 10rpx;margin-left: 20rpx;">
<view class="info-icon-wrapper version-icon">
<text class="iconfont icon-banben">{{ $t('gateway.versionLabel') }}</text>
</view>
<text class="info-value">{{ getVersion() || '--' }}</text>
</view>
</view>
<view class="wangguan">
<!-- 网关设备信息 -->
<view class="wgshebei">
<image :src="wgxq.picture || wgxq.modelPicture || ''" mode="aspectFill"></image>
<view class="wgname">
<text>{{ gatewayName || $t('gateway.gatewayDefault') }}</text>
<image class="edit-icon" src="https://api.ccttiot.com/smartmeter/img/static/uL6FHnMGWFrdptmDokDI" mode="aspectFit" @click="showEditNameDialog"></image>
<view class="status-badge" :class="wgxq.onlineStatus == 1 ? 'status-online' : 'status-offline'">
{{ wgxq.onlineStatus == 1 ? $t('gateway.online') : $t('gateway.offline') }}
</view>
</view>
</view>
<!-- SN和MAC -->
<view class="wgsnmac">
<view class="ltsn">
SN{{ wgxq.sn || '--' }}
</view>
<view class="rtmac">
MAC{{ wgxq.mac || '--' }}
</view>
</view>
<!-- 操作区域 -->
<!-- <view class="wgcaozuo">
<view class="wggx">
<view class="lt">
<view class="">
版本信息
</view>
<view class="">
{{ wgxq.version || '--' }} <image src="https://api.ccttiot.com/smartmeter/img/static/ugdatiDv4sy9w6SLYMgU" mode=""></image>
</view>
</view>
</view>
</view> -->
<!-- 时间信息 -->
<view class="wgtime" v-if="wgxq.updateTime || wgxq.activationTime">
<view class="time-item" v-if="wgxq.activationTime">
<text class="time-label">{{ $t('gateway.activated') }}</text>
<text class="time-value">{{ wgxq.activationTime }}</text>
</view>
</view>
<!-- 设备列表 -->
<view class="wglist">
<view class="wgtit">
{{ $t('gateway.deviceList') }} ({{ wglist.length }})
</view>
<view class="wgitem" v-for="(item,index) in wglist" :key="index">
<image :src="item.picture || item.modelPicture || ''" mode="aspectFill"></image>
<view class="cen">
<text>{{ item.deviceName || $t('gateway.unnamed') }}</text>
<text style="color: #808080;font-size: 24rpx;">{{ item.modelName || '--' }}</text>
</view>
<view class="signal-container">
<!-- 在线显示信号强度格数 -->
<view v-if="item.onlineStatus == 1" class="signal-bars">
<view class="signal-bar" v-for="(bar, barIndex) in 4" :key="barIndex"
:class="barIndex < getSignalLevel(item) ? 'bar-active' : 'bar-inactive'">
</view>
</view>
<!-- 离线显示灰色圆点 -->
<view v-else class="item-status status-offline-dot"></view>
</view>
</view>
<view class="empty-device" v-if="wglist.length === 0">
<text>{{ $t('gateway.noDeviceShort') }}</text>
</view>
</view>
</view>
<view class="saoma" @click="btnjb">
{{ $t('gateway.unbind') }}
</view>
<!-- 修改网关名称弹窗 -->
<view class="edit-name-modal" v-if="showEditName" @click.stop>
<view class="modal-mask" @click="closeEditNameDialog"></view>
<view class="modal-content">
<view class="modal-title">{{ $t('gateway.editGwName') }}</view>
<input class="modal-input" v-model="editNameValue" :placeholder="$t('gateway.gwNamePh')" maxlength="20" />
<view class="modal-buttons">
<view class="modal-btn cancel-btn" @click="closeEditNameDialog">{{ $t('common.cancel') }}</view>
<view class="modal-btn confirm-btn" @click="confirmEditName">{{ $t('common.confirm') }}</view>
</view>
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
bgc: {
backgroundColor: "#fff",
},
id:'',
wgxq:{},
wglist:[],
gatewayName: '',
showEditName: false,
editNameValue: '',
}
},
onLoad(e) {
this.id = e.id
this.getxq()
},
methods: {
// 点击进行解绑
btnjb(){
let that = this
uni.showModal({
title: that.$t('common.tip'),
content: that.$t('gateway.unbindConfirm'),
success: function(res) {
if (res.confirm) {
that.$u.delete(`/app/device/unbind/${that.wgxq.deviceId}`).then(res => {
if (res.code == 200) {
uni.showToast({
title: that.$t('gateway.unbindOk'),
icon: 'success',
duration: 2000
})
setTimeout(() => {
uni.reLaunch({
url:'/pages/index/index'
})
}, 1000)
} else {
uni.showToast({
title: res.msg,
icon: 'none',
duration: 2000
})
}
})
} else if (res.cancel) {
}
}
})
},
getxq(){
this.$u.get(`/app/device/getDetail?deviceId=${this.id}`).then((res) => {
if (res.code == 200) {
this.wgxq = res.data
// 设置网关名称,如果设备名称为空或未命名,使用默认值"网关"
this.gatewayName = res.data.deviceName && res.data.deviceName !== '未命名设备' ? res.data.deviceName : ''
console.log(11);
this.getlist()
}
})
},
// 获取RSSI信号值
getRSSIValue() {
if (this.wgxq.iotData && this.wgxq.iotData.RSSI && this.wgxq.iotData.RSSI.value !== undefined) {
return this.wgxq.iotData.RSSI.value
}
return null
},
// 获取版本信息
getVersion() {
if (this.wgxq.version) {
return this.wgxq.version
}
if (this.wgxq.iotData && this.wgxq.iotData.version) {
return this.wgxq.iotData.version
}
return null
},
// 计算信号强度格数基于RSSI
getSignalLevel(item) {
// 获取设备的信号强度RSSI
let rssiValue = null
if (item.rssi) {
rssiValue = parseFloat(item.rssi)
} else if (item.rssi !== undefined) {
rssiValue = parseFloat(item.rssi)
}
if (rssiValue === null || isNaN(rssiValue)) {
return 0
}
// 根据RSSI信号强度返回格数
// -60到0为4格
if (rssiValue >= -60 && rssiValue <= 0) {
return 4
}
// -60到-80为3格不包括-60不包括-80
if (rssiValue > -80 && rssiValue < -60) {
return 3
}
// -80到-100为2格包括-80包括-100
if (rssiValue >= -100 && rssiValue <= -80) {
return 2
}
// -100以下为1格
if (rssiValue < -100) {
return 1
}
return 0
},
// 显示修改名称弹窗
showEditNameDialog() {
this.editNameValue = this.gatewayName
this.showEditName = true
},
// 关闭修改名称弹窗
closeEditNameDialog() {
this.showEditName = false
this.editNameValue = ''
},
// 确认修改名称
confirmEditName() {
if (!this.editNameValue.trim()) {
uni.showToast({
title: this.$t('gateway.enterGwName'),
icon: 'none',
duration: 2000
})
return
}
this.$u.put(`/app/editDeviceName?deviceId=${this.id}&deviceName=${this.editNameValue.trim()}`).then(res => {
if (res.code == 200) {
this.gatewayName = this.editNameValue.trim()
this.wgxq.deviceName = this.editNameValue.trim()
this.closeEditNameDialog()
uni.showToast({
title: this.$t('gateway.editOk'),
icon: 'success',
duration: 2000
})
} else {
uni.showToast({
title: res.msg || this.$t('gateway.editFail'),
icon: 'none',
duration: 2000
})
}
}).catch(err => {
uni.showToast({
title: this.$t('gateway.editFail'),
icon: 'none',
duration: 2000
})
})
},
// 查询网关下的设备
getlist(){
console.log(111);
// let data = {
// mac:
// }
this.$u.get(`/app/device/gateway/gateWaySubDeviceList?gatewayMac=${this.wgxq.mac}&pageNum=1&pageSize=99`).then((res) => {
if (res.code == 200) {
this.wglist = res.rows
}
})
},
}
}
</script>
<style lang="scss">
// 修改名称弹窗
.edit-name-modal{
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: 1000;
display: flex;
align-items: center;
justify-content: center;
.modal-mask{
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(0, 0, 0, 0.6);
backdrop-filter: blur(4rpx);
}
.modal-content{
position: relative;
width: 640rpx;
background: #FFFFFF;
border-radius: 32rpx;
padding: 50rpx 40rpx 40rpx;
box-sizing: border-box;
box-shadow: 0 10rpx 40rpx rgba(0, 0, 0, 0.15);
animation: slideUp 0.3s ease;
@keyframes slideUp {
from {
transform: translateY(50rpx);
opacity: 0;
}
to {
transform: translateY(0);
opacity: 1;
}
}
.modal-title{
font-size: 36rpx;
font-weight: 600;
color: #262B37;
margin-bottom: 40rpx;
text-align: center;
letter-spacing: 1rpx;
}
.modal-input{
width: 100%;
height: 88rpx;
border: 2rpx solid #E8E8E8;
border-radius: 16rpx;
padding: 0 24rpx;
box-sizing: border-box;
font-size: 30rpx;
color: #262B37;
margin-bottom: 40rpx;
background: #F8F8F8;
transition: all 0.3s;
&:focus{
border-color: #48893B;
background: #FFFFFF;
}
}
.modal-buttons{
display: flex;
justify-content: space-between;
gap: 20rpx;
.modal-btn{
flex: 1;
height: 88rpx;
line-height: 88rpx;
text-align: center;
border-radius: 16rpx;
font-size: 30rpx;
font-weight: 500;
transition: all 0.3s;
&.cancel-btn{
background: #F5F5F5;
color: #666666;
&:active{
background: #E8E8E8;
transform: scale(0.98);
}
}
&.confirm-btn{
background: linear-gradient(135deg, #48893B 0%, #5BA849 100%);
color: #FFFFFF;
box-shadow: 0 4rpx 12rpx rgba(72, 137, 59, 0.3);
&:active{
transform: scale(0.98);
box-shadow: 0 2rpx 8rpx rgba(72, 137, 59, 0.3);
}
}
}
}
}
}
.saoma{
width: 680rpx;
height: 96rpx;
background: linear-gradient(135deg, #48893B 0%, #5BA849 100%);
color: #FFFFFF;
font-size: 32rpx;
font-weight: 600;
text-align: center;
line-height: 96rpx;
border-radius: 48rpx;
position: fixed;
left: 50%;
transform: translateX(-50%);
bottom: 40rpx;
box-shadow: 0 8rpx 24rpx rgba(72, 137, 59, 0.35);
transition: all 0.3s;
&:active{
transform: translateX(-50%) scale(0.98);
box-shadow: 0 4rpx 16rpx rgba(72, 137, 59, 0.3);
}
}
.wangguan{
padding: 0 30rpx;
box-sizing: border-box;
.wglist{
width: 100%;
min-height: 200rpx;
max-height: 670rpx;
overflow: scroll;
background: #FFFFFF;
box-shadow: 0rpx 4rpx 24rpx 0rpx rgba(0, 0, 0, 0.08);
margin: auto;
margin-top: 20rpx;
border-radius: 24rpx;
padding: 32rpx 40rpx;
box-sizing: border-box;
.wgtit{
font-size: 32rpx;
color: #3D3D3D;
font-weight: 600;
margin-bottom: 20rpx;
}
.wgitem{
margin-top: 30rpx;
max-height: 730rpx;
overflow: scroll;
display: flex;
justify-content: space-between;
align-items: center;
padding: 24rpx;
padding-bottom: 30rpx;
border-bottom: 1rpx solid #F0F0F0;
border-radius: 16rpx;
transition: all 0.3s;
&:hover{
background: #FAFAFA;
}
&:last-child{
border-bottom: none;
}
image{
width: 88rpx;
height: 88rpx;
border-radius: 16rpx;
background: #F5F5F5;
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.06);
}
.cen{
flex: 1;
margin-left: 24rpx;
text{
display: block;
font-weight: 600;
font-size: 30rpx;
color: #262B37;
line-height: 1.4;
&:last-child{
margin-top: 10rpx;
font-weight: 400;
font-size: 24rpx;
color: #808080;
}
}
}
.item-status{
width: 16rpx;
height: 16rpx;
border-radius: 50%;
&.status-online-dot{
background: #15C55D;
box-shadow: 0 0 8rpx rgba(21, 197, 93, 0.4);
}
&.status-offline-dot{
background: #999999;
}
}
.signal-container{
display: flex;
align-items: center;
justify-content: flex-end;
min-width: 60rpx;
.item-status{
width: 18rpx;
height: 18rpx;
border-radius: 50%;
background: #CCCCCC;
box-shadow: 0 2rpx 4rpx rgba(0, 0, 0, 0.1);
}
}
}
.empty-device{
text-align: center;
padding: 60rpx 0;
color: #999;
font-size: 28rpx;
}
}
.wgtime{
width: 100%;
background: #FFFFFF;
box-shadow: 0rpx 4rpx 24rpx 0rpx rgba(0, 0, 0, 0.08);
margin-top: 20rpx;
border-radius: 24rpx;
padding: 32rpx 40rpx;
box-sizing: border-box;
.time-item{
margin-bottom: 20rpx;
&:last-child{
margin-bottom: 0;
}
.time-label{
font-size: 28rpx;
color: #808080;
font-weight: 500;
}
.time-value{
font-size: 28rpx;
color: #262B37;
margin-left: 10rpx;
font-weight: 500;
}
}
}
.wgcaozuo{
width: 100%;
background: #FFFFFF;
box-shadow: 0rpx 0rpx 38rpx 0rpx rgba(128,128,128,0.15);
margin-top: 20rpx;
border-radius: 24rpx;
padding: 0 40rpx;
box-sizing: border-box;
.wgkg{
height: 110rpx;
line-height: 110rpx;
border-bottom: 1px solid #D8D8D8;
.lt{
width: 100%;
display: flex;
justify-content: space-between;
align-items: center;
.status-switch{
.status-text{
font-size: 26rpx;
padding: 6rpx 16rpx;
border-radius: 20rpx;
&.status-online-text{
background: rgba(21, 197, 93, 0.1);
color: #15C55D;
}
&.status-offline-text{
background: rgba(153, 153, 153, 0.1);
color: #999999;
}
}
}
}
}
.wggx{
height: 110rpx;
line-height: 110rpx;
.lt{
width: 100%;
display: flex;
justify-content: space-between;
align-items: center;
image{
width: 32rpx;
height: 32rpx;
margin-left: 10rpx;
}
view{
display: flex;
align-items: center;
}
}
}
}
.wgsnmac{
width: 100%;
height: 100rpx;
background: #FFFFFF;
box-shadow: 0rpx 4rpx 24rpx 0rpx rgba(0, 0, 0, 0.08);
border-radius: 24rpx;
display: flex;
justify-content: space-between;
box-sizing: border-box;
padding: 20rpx 0;
.ltsn{
border-right: 1px solid #E8E8E8;
}
view{
height: 60rpx;
width: 50%;
text-align: center;
line-height: 60rpx;
font-size: 28rpx;
color: #666666;
font-weight: 500;
}
}
.wgshebei{
width: 100%;
text-align: center;
margin-top: 40rpx;
margin-bottom: 30rpx;
image{
width: 168rpx;
height: 168rpx;
border-radius: 20rpx;
background: #F5F5F5;
}
.wgname{
font-weight: 600;
font-size: 36rpx;
color: #3D3D3D;
display: flex;
align-items: center;
justify-content: center;
margin-top: 30rpx;
flex-wrap: wrap;
gap: 12rpx;
text{
margin-right: 0;
}
.edit-icon{
width: 36rpx;
height: 36rpx;
padding: 8rpx;
border-radius: 8rpx;
transition: all 0.3s;
&:active{
background: rgba(0, 0, 0, 0.05);
transform: scale(0.95);
}
}
.status-badge{
display: inline-block;
padding: 8rpx 24rpx;
border-radius: 24rpx;
font-size: 24rpx;
font-weight: 500;
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.08);
&.status-online{
background: linear-gradient(135deg, rgba(21, 197, 93, 0.15) 0%, rgba(21, 197, 93, 0.1) 100%);
color: #15C55D;
border: 1rpx solid rgba(21, 197, 93, 0.2);
}
&.status-offline{
background: rgba(153, 153, 153, 0.1);
color: #999999;
border: 1rpx solid rgba(153, 153, 153, 0.2);
}
}
}
}
// 左上角信息
.top-info{
position: fixed;
top: 20rpx;
left: 30rpx;
z-index: 999;
display: flex;
flex-direction: column;
gap: 16rpx;
padding: 20rpx 24rpx;
background: rgba(255, 255, 255, 0.95);
backdrop-filter: blur(10rpx);
border-radius: 16rpx;
box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.08);
.info-item{
display: flex;
align-items: center;
gap: 12rpx;
.info-icon-wrapper{
width: 44rpx;
height: 44rpx;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
font-size: 28rpx;
&.signal-icon{
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
box-shadow: 0 2rpx 8rpx rgba(102, 126, 234, 0.3);
}
&.version-icon{
background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);
box-shadow: 0 2rpx 8rpx rgba(245, 87, 108, 0.3);
}
.iconfont{
font-size: 28rpx;
line-height: 1;
}
}
.info-value{
color: #262B37;
font-weight: 600;
font-size: 26rpx;
letter-spacing: 0.5rpx;
}
}
}
// 信号强度显示
.signal-container{
.signal-bars{
display: flex;
align-items: flex-end;
gap: 5rpx;
height: 36rpx;
padding: 4rpx 0;
.signal-bar{
width: 6rpx;
border-radius: 5rpx 5rpx 2rpx 2rpx;
transition: all 0.3s ease;
&:nth-child(1){
height: 10rpx;
}
&:nth-child(2){
height: 16rpx;
}
&:nth-child(3){
height: 20rpx;
}
&:nth-child(4){
height: 24rpx;
}
&.bar-active{
background: linear-gradient(180deg, #15C55D 0%, #0FA855 100%);
box-shadow: 0 2rpx 6rpx rgba(21, 197, 93, 0.4);
}
&.bar-inactive{
background: linear-gradient(180deg, #E8E8E8 0%, #D0D0D0 100%);
}
}
}
}
}
</style>