fix:空调数据下发、参数页样式
This commit is contained in:
@ -9,29 +9,32 @@
|
||||
<view class="tabbar-content">
|
||||
<!-- 顶部参数卡片 -->
|
||||
<view class="parameter-cards">
|
||||
<view class="card-item">
|
||||
<!-- 温度卡片 -->
|
||||
<view class="card-item temperature-card">
|
||||
<view class="card-icon temperature-icon">🌡️</view>
|
||||
<view class="card-content">
|
||||
<text class="card-value">{{ temperature }}°C</text>
|
||||
<text class="card-label">温度</text>
|
||||
<text class="card-value">{{ temperature }}°C</text>
|
||||
</view>
|
||||
<view class="card-status" :class="temperature > 0 ? 'active' : 'inactive'"></view>
|
||||
</view>
|
||||
|
||||
<view class="card-item">
|
||||
<!-- 湿度卡片 -->
|
||||
<view class="card-item humidity-card">
|
||||
<view class="card-icon humidity-icon">💧</view>
|
||||
<view class="card-content">
|
||||
<text class="card-value">{{ humidity }}%</text>
|
||||
<text class="card-label">湿度</text>
|
||||
<text class="card-value">{{ humidity }}%</text>
|
||||
</view>
|
||||
<view class="card-status" :class="humidity > 0 ? 'active' : 'inactive'"></view>
|
||||
</view>
|
||||
|
||||
<view class="card-item">
|
||||
<!-- 洁净度卡片 -->
|
||||
<view class="card-item cleanliness-card">
|
||||
<view class="card-icon cleanliness-icon">✨</view>
|
||||
<view class="card-content">
|
||||
<text class="card-value">{{ cleanliness > 0 ? cleanliness + '%' : '-%' }}</text>
|
||||
<text class="card-label">洁净度</text>
|
||||
<text class="card-value">{{ cleanliness > 0 ? cleanliness + '%' : '-%' }}</text>
|
||||
</view>
|
||||
<view class="card-status" :class="cleanliness > 0 ? 'active' : 'inactive'"></view>
|
||||
</view>
|
||||
@ -39,89 +42,95 @@
|
||||
|
||||
<!-- 环境参数详情 -->
|
||||
<view class="parameter-details">
|
||||
<view class="parameter-item">
|
||||
<view class="parameter-header">
|
||||
<text class="parameter-label">温度</text>
|
||||
<text class="current-value">{{ temperature }}°C</text>
|
||||
<!-- 温度卡片 -->
|
||||
<view class="detail-card temperature-detail-card">
|
||||
<view class="detail-header">
|
||||
<text class="detail-label">温度</text>
|
||||
<text class="detail-value">{{ temperature }}°C</text>
|
||||
</view>
|
||||
<view class="progress-container">
|
||||
<view class="progress-bar">
|
||||
<view class="progress-fill temperature-progress" :style="{ width: temperatureProgress + '%' }"></view>
|
||||
</view>
|
||||
<view class="detail-progress-bar">
|
||||
<view class="detail-progress-fill temperature-progress" :style="{ width: temperatureProgress + '%' }"></view>
|
||||
</view>
|
||||
<view class="detail-range">
|
||||
<text class="detail-range-text">{{ temperatureRange.min }}°C - {{ temperatureRange.max }}°C</text>
|
||||
</view>
|
||||
<view class="progress-info">
|
||||
<text class="range-value">{{ temperatureRange.min }}°C - {{ temperatureRange.max }}°C</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="parameter-item">
|
||||
<view class="parameter-header">
|
||||
<text class="parameter-label">湿度</text>
|
||||
<text class="current-value">{{ humidity }}%</text>
|
||||
<!-- 湿度卡片 -->
|
||||
<view class="detail-card humidity-detail-card">
|
||||
<view class="detail-header">
|
||||
<text class="detail-label">湿度</text>
|
||||
<text class="detail-value">{{ humidity }}%</text>
|
||||
</view>
|
||||
<view class="progress-container">
|
||||
<view class="progress-bar">
|
||||
<view class="progress-fill humidity-progress" :style="{ width: humidityProgress + '%' }"></view>
|
||||
</view>
|
||||
<view class="detail-progress-bar">
|
||||
<view class="detail-progress-fill humidity-progress" :style="{ width: humidityProgress + '%' }"></view>
|
||||
</view>
|
||||
<view class="detail-range">
|
||||
<text class="detail-range-text">{{ humidityRange.min }}% - {{ humidityRange.max }}%</text>
|
||||
</view>
|
||||
<view class="progress-info">
|
||||
<text class="range-value">{{ humidityRange.min }}% - {{ humidityRange.max }}%</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="parameter-item">
|
||||
<view class="parameter-header">
|
||||
<text class="parameter-label">洁净度</text>
|
||||
<text class="current-value">{{ cleanliness > 0 ? cleanliness + '%' : '-%' }}</text>
|
||||
<!-- 洁净度卡片 -->
|
||||
<view class="detail-card cleanliness-detail-card">
|
||||
<view class="detail-header">
|
||||
<text class="detail-label">洁净度</text>
|
||||
<text class="detail-value">{{ cleanliness > 0 ? cleanliness + '%' : '-%' }}</text>
|
||||
</view>
|
||||
<view class="progress-container">
|
||||
<view class="progress-bar">
|
||||
<view class="progress-fill cleanliness-progress" :style="{ width: cleanlinessProgress + '%' }"></view>
|
||||
</view>
|
||||
<view class="detail-progress-bar">
|
||||
<view class="detail-progress-fill cleanliness-progress" :style="{ width: cleanlinessProgress + '%' }"></view>
|
||||
</view>
|
||||
<view class="detail-range">
|
||||
<text class="detail-range-text">暂无数据</text>
|
||||
</view>
|
||||
<view class="progress-info">
|
||||
<text class="range-value">暂无数据</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 空调目标参数设置 -->
|
||||
<view class="air-conditioner-settings">
|
||||
<view class="settings-header">
|
||||
<text class="settings-title">空调目标参数设置</text>
|
||||
<view class="ac-header">
|
||||
<text class="ac-title">空调目标参数设置</text>
|
||||
</view>
|
||||
<view class="temperature-control">
|
||||
<text class="control-label">目标温度</text>
|
||||
<view class="temperature-display">
|
||||
<button class="temp-btn decrease" @click="decreaseTemperature">-</button>
|
||||
<text class="temperature-value">{{ targetTemperature }}°C</text>
|
||||
<button class="temp-btn increase" @click="increaseTemperature">+</button>
|
||||
<view class="ac-control">
|
||||
<view class="ac-label">目标温度</view>
|
||||
<view class="ac-temp-control">
|
||||
<button class="ac-btn decrease" @click="decreaseTemperature">−</button>
|
||||
<view class="ac-temp-display">
|
||||
<text class="ac-temp-value">{{ targetTemperature }}</text>
|
||||
<text class="ac-temp-unit">°C</text>
|
||||
</view>
|
||||
<button class="ac-btn increase" @click="increaseTemperature">+</button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 环境控制区域 -->
|
||||
<view class="environment-control">
|
||||
<view class="control-header">
|
||||
<text class="control-title">环境控制</text>
|
||||
<view class="status-indicator">
|
||||
<view class="env-header">
|
||||
<text class="env-title">环境控制</text>
|
||||
<!-- <view class="env-status">
|
||||
<view class="status-dot"></view>
|
||||
<text class="status-text">异常</text>
|
||||
</view> -->
|
||||
</view>
|
||||
|
||||
<view class="env-info">
|
||||
<!-- <view class="info-item">
|
||||
<text class="info-label">最后更新</text>
|
||||
<text class="info-value">{{ lastUpdate }}</text>
|
||||
</view> -->
|
||||
|
||||
<view class="control-ranges">
|
||||
<view class="range-item">
|
||||
<text class="range-label">温度控制</text>
|
||||
<text class="range-value">{{ temperatureRange.min }}°C - {{ temperatureRange.max }}°C</text>
|
||||
</view>
|
||||
<view class="range-item">
|
||||
<text class="range-label">湿度控制</text>
|
||||
<text class="range-value">{{ humidityRange.min }}% - {{ humidityRange.max }}%</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="control-info">
|
||||
<text class="last-update">最后更新: {{ lastUpdate }}</text>
|
||||
<!-- <view class="connection-info">
|
||||
<text class="connection-status" :class="connectionStatus.isConnected ? 'connected' : 'disconnected'">
|
||||
{{ connectionStatus.isConnected ? 'MQTT已连接' : 'MQTT未连接' }}
|
||||
</text>
|
||||
<button v-if="!connectionStatus.isConnected" class="reconnect-btn" @click="manualReconnect">
|
||||
重连
|
||||
</button>
|
||||
</view> -->
|
||||
<text class="temperature-range">温度控制: {{ temperatureRange.min }}°C - {{ temperatureRange.max }}°C</text>
|
||||
<text class="humidity-range">湿度控制: {{ humidityRange.min }}% - {{ humidityRange.max }}%</text>
|
||||
</view>
|
||||
|
||||
<button class="settings-button" @click="openSettingsModal">
|
||||
<text class="settings-icon">⚙️</text>
|
||||
<text class="settings-text">参数设定</text>
|
||||
@ -192,7 +201,7 @@
|
||||
|
||||
<script>
|
||||
import mqttDataManager from '@/utils/mqttDataManager.js'
|
||||
import { manualReconnect } from '@/utils/sendMqtt.js'
|
||||
import { manualReconnect, sendMqttData } from '@/utils/sendMqtt.js'
|
||||
|
||||
export default {
|
||||
data() {
|
||||
@ -224,7 +233,7 @@ export default {
|
||||
isConnected: false,
|
||||
lastUpdate: null
|
||||
},
|
||||
targetTemperature: 40
|
||||
targetTemperature: 30
|
||||
}
|
||||
},
|
||||
onLoad() {
|
||||
@ -349,26 +358,49 @@ export default {
|
||||
|
||||
// 提高目标温度
|
||||
increaseTemperature() {
|
||||
if (this.targetTemperature < 30) {
|
||||
if (this.targetTemperature < 50) {
|
||||
this.targetTemperature++
|
||||
console.log('目标温度提高至:', this.targetTemperature + '°C')
|
||||
this.showTemperatureChangeToast()
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: '温度不能高于30°C',
|
||||
title: '温度不能高于50°C',
|
||||
icon: 'none'
|
||||
})
|
||||
}
|
||||
},
|
||||
|
||||
// 显示温度变化提示
|
||||
showTemperatureChangeToast() {
|
||||
uni.showToast({
|
||||
title: `目标温度: ${this.targetTemperature}°C`,
|
||||
icon: 'success',
|
||||
duration: 1500
|
||||
})
|
||||
},
|
||||
// 显示温度变化提示
|
||||
showTemperatureChangeToast() {
|
||||
uni.showToast({
|
||||
title: `目标温度: ${this.targetTemperature}°C`,
|
||||
icon: 'success',
|
||||
duration: 1500
|
||||
})
|
||||
|
||||
// 发送空调参数到MQTT
|
||||
this.sendAirConditionerParams()
|
||||
},
|
||||
|
||||
// 发送空调参数
|
||||
sendAirConditionerParams() {
|
||||
const airConditionerData = {
|
||||
"TagValue": this.targetTemperature,
|
||||
"TagName": "JS_COD",
|
||||
"method": "setValue"
|
||||
}
|
||||
|
||||
console.log('🌡️ 发送空调参数:', airConditionerData)
|
||||
|
||||
// 调用发送MQTT数据的方法
|
||||
const success = sendMqttData(airConditionerData)
|
||||
|
||||
if (success) {
|
||||
console.log('✅ 空调参数发送请求已提交')
|
||||
} else {
|
||||
console.log('❌ 空调参数发送失败')
|
||||
}
|
||||
},
|
||||
|
||||
// 手动重连MQTT
|
||||
manualReconnect() {
|
||||
@ -434,18 +466,52 @@ export default {
|
||||
flex: 1;
|
||||
background: white;
|
||||
border-radius: 12rpx;
|
||||
padding: 20rpx;
|
||||
padding: 25rpx 20rpx;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
position: relative;
|
||||
box-shadow: 0 2rpx 8rpx rgba(0,0,0,0.1);
|
||||
box-shadow: 0 4rpx 12rpx rgba(0,0,0,0.1);
|
||||
min-height: 120rpx;
|
||||
border: 2rpx solid transparent;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.card-item:hover {
|
||||
transform: translateY(-2rpx);
|
||||
box-shadow: 0 6rpx 16rpx rgba(0,0,0,0.15);
|
||||
}
|
||||
|
||||
/* 温度卡片 */
|
||||
.temperature-card {
|
||||
// border-left: 4rpx solid #ff4444;
|
||||
}
|
||||
|
||||
.temperature-card .card-icon {
|
||||
color: #ff4444;
|
||||
}
|
||||
|
||||
/* 湿度卡片 */
|
||||
.humidity-card {
|
||||
// border-left: 4rpx solid #4488ff;
|
||||
}
|
||||
|
||||
.humidity-card .card-icon {
|
||||
color: #4488ff;
|
||||
}
|
||||
|
||||
/* 洁净度卡片 */
|
||||
.cleanliness-card {
|
||||
// border-left: 4rpx solid #ffaa00;
|
||||
}
|
||||
|
||||
.cleanliness-card .card-icon {
|
||||
color: #ffaa00;
|
||||
}
|
||||
|
||||
.card-icon {
|
||||
font-size: 40rpx;
|
||||
margin-bottom: 10rpx;
|
||||
font-size: 36rpx;
|
||||
margin-bottom: 12rpx;
|
||||
}
|
||||
|
||||
.card-content {
|
||||
@ -456,40 +522,11 @@ export default {
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.card-value {
|
||||
font-size: 28rpx;
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
margin-bottom: 5rpx;
|
||||
}
|
||||
|
||||
.card-label {
|
||||
font-size: 24rpx;
|
||||
font-size: 26rpx;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.card-status {
|
||||
position: absolute;
|
||||
top: 15rpx;
|
||||
right: 15rpx;
|
||||
width: 16rpx;
|
||||
height: 16rpx;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.card-status.active {
|
||||
background-color: #4caf50;
|
||||
}
|
||||
|
||||
.card-status.inactive {
|
||||
background-color: #ccc;
|
||||
}
|
||||
|
||||
.card-label {
|
||||
display: block;
|
||||
font-size: 28rpx;
|
||||
color: #666;
|
||||
margin-bottom: 10rpx;
|
||||
margin-bottom: 8rpx;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.card-value {
|
||||
@ -498,77 +535,89 @@ export default {
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.card-indicator {
|
||||
.card-status {
|
||||
position: absolute;
|
||||
top: 20rpx;
|
||||
right: 20rpx;
|
||||
width: 20rpx;
|
||||
height: 20rpx;
|
||||
top: 15rpx;
|
||||
right: 15rpx;
|
||||
width: 14rpx;
|
||||
height: 14rpx;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.temperature-indicator {
|
||||
background-color: #ff4444;
|
||||
.card-status.active {
|
||||
background-color: #4caf50;
|
||||
box-shadow: 0 0 8rpx rgba(76, 175, 80, 0.5);
|
||||
}
|
||||
|
||||
.humidity-indicator {
|
||||
background-color: #4488ff;
|
||||
.card-status.inactive {
|
||||
background-color: #ccc;
|
||||
}
|
||||
|
||||
.cleanliness-indicator {
|
||||
background-color: #999;
|
||||
}
|
||||
|
||||
.parameter-details {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 20rpx;
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
|
||||
.detail-card {
|
||||
background: white;
|
||||
border-radius: 12rpx;
|
||||
padding: 25rpx;
|
||||
margin-bottom: 20rpx;
|
||||
box-shadow: 0 2rpx 8rpx rgba(0,0,0,0.05);
|
||||
box-shadow: 0 2rpx 8rpx rgba(0,0,0,0.08);
|
||||
border-left: 4rpx solid transparent;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.parameter-item {
|
||||
margin-bottom: 30rpx;
|
||||
.detail-card:hover {
|
||||
transform: translateY(-1rpx);
|
||||
box-shadow: 0 4rpx 12rpx rgba(0,0,0,0.12);
|
||||
}
|
||||
|
||||
.parameter-item:last-child {
|
||||
margin-bottom: 0;
|
||||
/* 温度详情卡片 */
|
||||
.temperature-detail-card {
|
||||
// border-left-color: #ff4444;
|
||||
}
|
||||
|
||||
.parameter-header {
|
||||
/* 湿度详情卡片 */
|
||||
.humidity-detail-card {
|
||||
// border-left-color: #4488ff;
|
||||
}
|
||||
|
||||
/* 洁净度详情卡片 */
|
||||
.cleanliness-detail-card {
|
||||
// border-left-color: #ffaa00;
|
||||
}
|
||||
|
||||
.detail-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 15rpx;
|
||||
}
|
||||
|
||||
.parameter-label {
|
||||
.detail-label {
|
||||
font-size: 28rpx;
|
||||
color: #333;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.current-value {
|
||||
.detail-value {
|
||||
font-size: 28rpx;
|
||||
color: #4488ff;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.progress-container {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 20rpx;
|
||||
}
|
||||
|
||||
.progress-bar {
|
||||
flex: 1;
|
||||
.detail-progress-bar {
|
||||
height: 16rpx;
|
||||
background-color: #f0f0f0;
|
||||
border-radius: 8rpx;
|
||||
overflow: hidden;
|
||||
margin-bottom: 10rpx;
|
||||
}
|
||||
|
||||
.progress-fill {
|
||||
.detail-progress-fill {
|
||||
height: 100%;
|
||||
border-radius: 8rpx;
|
||||
transition: width 0.3s ease;
|
||||
@ -586,21 +635,12 @@ export default {
|
||||
background: linear-gradient(90deg, #4488ff, #44ff88);
|
||||
}
|
||||
|
||||
.progress-info {
|
||||
.detail-range {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-end;
|
||||
min-width: 200rpx;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
.current-value {
|
||||
font-size: 28rpx;
|
||||
font-weight: bold;
|
||||
color: #4488ff;
|
||||
margin-bottom: 5rpx;
|
||||
}
|
||||
|
||||
.range-value {
|
||||
.detail-range-text {
|
||||
font-size: 24rpx;
|
||||
color: #666;
|
||||
}
|
||||
@ -608,168 +648,218 @@ export default {
|
||||
/* 空调目标参数设置样式 */
|
||||
.air-conditioner-settings {
|
||||
background: white;
|
||||
border-radius: 12rpx;
|
||||
padding: 25rpx;
|
||||
border-radius: 16rpx;
|
||||
padding: 30rpx;
|
||||
margin-bottom: 20rpx;
|
||||
box-shadow: 0 2rpx 8rpx rgba(0,0,0,0.05);
|
||||
box-shadow: 0 4rpx 16rpx rgba(0,0,0,0.08);
|
||||
border: 1rpx solid #f0f0f0;
|
||||
}
|
||||
|
||||
.settings-header {
|
||||
.ac-header {
|
||||
margin-bottom: 25rpx;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.settings-title {
|
||||
.ac-title {
|
||||
font-size: 32rpx;
|
||||
font-weight: bold;
|
||||
font-weight: 600;
|
||||
color: #333;
|
||||
letter-spacing: 1rpx;
|
||||
}
|
||||
|
||||
.temperature-control {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.control-label {
|
||||
font-size: 28rpx;
|
||||
color: #333;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.temperature-display {
|
||||
.ac-control {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 20rpx;
|
||||
}
|
||||
|
||||
.temp-btn {
|
||||
width: 60rpx;
|
||||
height: 60rpx;
|
||||
.ac-label {
|
||||
font-size: 28rpx;
|
||||
color: #666;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.ac-temp-control {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 30rpx;
|
||||
background: #f8f9fa;
|
||||
border-radius: 50rpx;
|
||||
padding: 15rpx 25rpx;
|
||||
border: 2rpx solid #e9ecef;
|
||||
}
|
||||
|
||||
.ac-btn {
|
||||
width: 80rpx;
|
||||
height: 80rpx;
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 36rpx;
|
||||
font-size: 40rpx;
|
||||
font-weight: bold;
|
||||
border: none;
|
||||
color: white;
|
||||
transition: all 0.3s ease;
|
||||
box-shadow: 0 2rpx 8rpx rgba(0,0,0,0.1);
|
||||
}
|
||||
|
||||
.temp-btn.decrease {
|
||||
background-color: #ff4444;
|
||||
.ac-btn.decrease {
|
||||
background: linear-gradient(135deg, #ff6b6b, #ee5a52);
|
||||
}
|
||||
|
||||
.temp-btn.increase {
|
||||
background-color: #4caf50;
|
||||
.ac-btn.increase {
|
||||
background: linear-gradient(135deg, #51cf66, #40c057);
|
||||
}
|
||||
|
||||
.temperature-value {
|
||||
font-size: 36rpx;
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
.ac-btn:active {
|
||||
transform: scale(0.95);
|
||||
box-shadow: 0 1rpx 4rpx rgba(0,0,0,0.2);
|
||||
}
|
||||
|
||||
.ac-temp-display {
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
gap: 8rpx;
|
||||
min-width: 120rpx;
|
||||
text-align: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.ac-temp-value {
|
||||
font-size: 48rpx;
|
||||
font-weight: 700;
|
||||
color: #333;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.ac-temp-unit {
|
||||
font-size: 28rpx;
|
||||
color: #666;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.environment-control {
|
||||
background: white;
|
||||
border-radius: 12rpx;
|
||||
padding: 25rpx;
|
||||
box-shadow: 0 2rpx 8rpx rgba(0,0,0,0.05);
|
||||
border-radius: 16rpx;
|
||||
padding: 30rpx;
|
||||
box-shadow: 0 4rpx 16rpx rgba(0,0,0,0.08);
|
||||
border: 1rpx solid #f0f0f0;
|
||||
}
|
||||
|
||||
.control-header {
|
||||
.env-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 25rpx;
|
||||
padding-bottom: 20rpx;
|
||||
border-bottom: 1rpx solid #f0f0f0;
|
||||
}
|
||||
|
||||
.env-title {
|
||||
font-size: 32rpx;
|
||||
font-weight: 600;
|
||||
color: #333;
|
||||
letter-spacing: 1rpx;
|
||||
}
|
||||
|
||||
.env-status {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10rpx;
|
||||
// background: #f0f8ff;
|
||||
padding: 8rpx 16rpx;
|
||||
border-radius: 20rpx;
|
||||
// border: 1rpx solid #e6f3ff;
|
||||
}
|
||||
|
||||
.status-dot {
|
||||
width: 12rpx;
|
||||
height: 12rpx;
|
||||
border-radius: 50%;
|
||||
background-color: #4a90e2;
|
||||
}
|
||||
|
||||
.status-text {
|
||||
font-size: 24rpx;
|
||||
color: #4a90e2;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.env-info {
|
||||
margin-bottom: 25rpx;
|
||||
}
|
||||
|
||||
.info-item {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 20rpx;
|
||||
padding: 15rpx 20rpx;
|
||||
background: #f8fbff;
|
||||
border-radius: 12rpx;
|
||||
border-left: 4rpx solid #4a90e2;
|
||||
}
|
||||
|
||||
.control-title {
|
||||
font-size: 32rpx;
|
||||
color: #333;
|
||||
font-weight: bold;
|
||||
.info-label {
|
||||
font-size: 26rpx;
|
||||
color: #666;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.status-indicator {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10rpx;
|
||||
.info-value {
|
||||
font-size: 24rpx;
|
||||
color: #4a90e2;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.status-dot {
|
||||
width: 20rpx;
|
||||
height: 20rpx;
|
||||
border-radius: 50%;
|
||||
background-color: #ffaa00;
|
||||
}
|
||||
|
||||
.status-text {
|
||||
font-size: 28rpx;
|
||||
color: #ffaa00;
|
||||
}
|
||||
|
||||
.control-info {
|
||||
.control-ranges {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 10rpx;
|
||||
margin-bottom: 30rpx;
|
||||
gap: 15rpx;
|
||||
}
|
||||
|
||||
.last-update {
|
||||
font-size: 28rpx;
|
||||
color: #4488ff;
|
||||
}
|
||||
|
||||
.connection-status {
|
||||
font-size: 28rpx;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.connection-status.connected {
|
||||
color: #4caf50;
|
||||
}
|
||||
|
||||
.connection-status.disconnected {
|
||||
color: #ff4444;
|
||||
}
|
||||
|
||||
.connection-info {
|
||||
.range-item {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
gap: 20rpx;
|
||||
padding: 15rpx 20rpx;
|
||||
// background: #f8fbff;
|
||||
border-radius: 12rpx;
|
||||
// border-left: 4rpx solid #4a90e2;
|
||||
}
|
||||
|
||||
.reconnect-btn {
|
||||
background-color: #ff4444;
|
||||
color: white;
|
||||
padding: 8rpx 16rpx;
|
||||
border-radius: 20rpx;
|
||||
font-size: 24rpx;
|
||||
border: none;
|
||||
.range-label {
|
||||
font-size: 26rpx;
|
||||
color: #666;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.temperature-range {
|
||||
font-size: 28rpx;
|
||||
color: #4488ff;
|
||||
}
|
||||
|
||||
.humidity-range {
|
||||
font-size: 28rpx;
|
||||
color: #4488ff;
|
||||
.range-value {
|
||||
font-size: 30rpx;
|
||||
color: #4a90e2;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.settings-button {
|
||||
background-color: #3f51b5;
|
||||
color: white;
|
||||
padding: 20rpx 40rpx;
|
||||
border-radius: 10rpx;
|
||||
padding: 18rpx 30rpx;
|
||||
border-radius: 12rpx;
|
||||
font-size: 28rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 10rpx;
|
||||
gap: 12rpx;
|
||||
width: 100%;
|
||||
border: none;
|
||||
box-shadow: 0 4rpx 12rpx rgba(74, 144, 226, 0.3);
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.settings-button:active {
|
||||
transform: translateY(1rpx);
|
||||
box-shadow: 0 2rpx 8rpx rgba(74, 144, 226, 0.4);
|
||||
}
|
||||
|
||||
.settings-icon {
|
||||
@ -778,15 +868,17 @@ export default {
|
||||
|
||||
.settings-text {
|
||||
font-size: 28rpx;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
/* 弹窗样式 */
|
||||
.settings-modal {
|
||||
background: white;
|
||||
border-radius: 20rpx;
|
||||
border-radius: 16rpx;
|
||||
width: 600rpx;
|
||||
max-width: 90vw;
|
||||
overflow: hidden;
|
||||
border: 1rpx solid #f0f0f0;
|
||||
}
|
||||
|
||||
.modal-header {
|
||||
@ -794,20 +886,34 @@ export default {
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 30rpx;
|
||||
background-color: #f8f8f8;
|
||||
border-bottom: 2rpx solid #e0e0e0;
|
||||
// background-color: #f8fbff;
|
||||
border-bottom: 1rpx solid #e6f3ff;
|
||||
}
|
||||
|
||||
.modal-title {
|
||||
font-size: 32rpx;
|
||||
font-weight: bold;
|
||||
font-weight: 600;
|
||||
color: #333;
|
||||
letter-spacing: 1rpx;
|
||||
}
|
||||
|
||||
.close-btn {
|
||||
font-size: 32rpx;
|
||||
color: #666;
|
||||
padding: 10rpx;
|
||||
font-size: 28rpx;
|
||||
color: #999;
|
||||
padding: 8rpx;
|
||||
border-radius: 50%;
|
||||
background-color: #f5f5f5;
|
||||
width: 60rpx;
|
||||
height: 60rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.close-btn:active {
|
||||
background-color: #e0e0e0;
|
||||
transform: scale(0.95);
|
||||
}
|
||||
|
||||
.modal-content {
|
||||
@ -815,7 +921,7 @@ export default {
|
||||
}
|
||||
|
||||
.setting-item {
|
||||
margin-bottom: 40rpx;
|
||||
margin-bottom: 30rpx;
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
@ -826,52 +932,69 @@ export default {
|
||||
display: block;
|
||||
font-size: 28rpx;
|
||||
color: #333;
|
||||
margin-bottom: 20rpx;
|
||||
font-weight: bold;
|
||||
margin-bottom: 15rpx;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.range-inputs {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 15rpx;
|
||||
gap: 20rpx;
|
||||
}
|
||||
|
||||
.range-input {
|
||||
flex: 1;
|
||||
padding: 20rpx;
|
||||
border: 2rpx solid #e0e0e0;
|
||||
border-radius: 10rpx;
|
||||
border: 2rpx solid #e6f3ff;
|
||||
border-radius: 12rpx;
|
||||
font-size: 28rpx;
|
||||
text-align: center;
|
||||
background-color: #f8f8f8;
|
||||
background-color: #f8fbff;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.range-input:focus {
|
||||
border-color: #4a90e2;
|
||||
background-color: white;
|
||||
box-shadow: 0 0 0 4rpx rgba(74, 144, 226, 0.1);
|
||||
}
|
||||
|
||||
.range-separator {
|
||||
font-size: 28rpx;
|
||||
color: #666;
|
||||
font-weight: bold;
|
||||
color: #4a90e2;
|
||||
font-weight: 600;
|
||||
min-width: 40rpx;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.unit {
|
||||
font-size: 24rpx;
|
||||
color: #666;
|
||||
color: #4a90e2;
|
||||
min-width: 60rpx;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.modal-actions {
|
||||
display: flex;
|
||||
gap: 20rpx;
|
||||
padding: 30rpx;
|
||||
background-color: #f8f8f8;
|
||||
background-color: #f8fbff;
|
||||
}
|
||||
|
||||
.cancel-btn {
|
||||
flex: 1;
|
||||
background-color: #666;
|
||||
color: white;
|
||||
background-color: #f5f5f5;
|
||||
color: #666;
|
||||
padding: 20rpx;
|
||||
border-radius: 10rpx;
|
||||
border-radius: 12rpx;
|
||||
font-size: 28rpx;
|
||||
border: 2rpx solid #e0e0e0;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.cancel-btn:active {
|
||||
background-color: #e0e0e0;
|
||||
transform: translateY(1rpx);
|
||||
}
|
||||
|
||||
.confirm-btn {
|
||||
@ -879,7 +1002,15 @@ export default {
|
||||
background-color: #3f51b5;
|
||||
color: white;
|
||||
padding: 20rpx;
|
||||
border-radius: 10rpx;
|
||||
border-radius: 12rpx;
|
||||
font-size: 28rpx;
|
||||
border: none;
|
||||
box-shadow: 0 4rpx 12rpx rgba(63, 81, 181, 0.3);
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.confirm-btn:active {
|
||||
transform: translateY(1rpx);
|
||||
box-shadow: 0 2rpx 8rpx rgba(63, 81, 181, 0.4);
|
||||
}
|
||||
</style>
|
||||
@ -42,7 +42,6 @@ const createMqtt = () => {
|
||||
clean: true,
|
||||
reconnectPeriod: 1000, // 恢复自动重连,1秒重连一次
|
||||
connectTimeout: 5000, // 5s超时时间
|
||||
// topic: "HDYDCJ_01_DOWN",
|
||||
topic: "HDYDCJ_01_UP",
|
||||
rejectUnauthorized: false,
|
||||
// #ifdef MP-ALIPAY
|
||||
@ -245,11 +244,70 @@ const manualReconnect = () => {
|
||||
}, 300);
|
||||
};
|
||||
|
||||
// 发送MQTT数据(单独订阅HDYDCJ_01_DOWN)
|
||||
const sendMqttData = (data) => {
|
||||
try {
|
||||
if (!client || !client.connected) {
|
||||
console.error('❌ MQTT客户端未连接,无法发送数据');
|
||||
uni.showToast({
|
||||
title: 'MQTT未连接',
|
||||
icon: 'error',
|
||||
duration: 2000
|
||||
});
|
||||
return false;
|
||||
}
|
||||
|
||||
const message = JSON.stringify(data);
|
||||
console.log('📤 发送MQTT数据:', data);
|
||||
console.log('📤 发送消息内容:', message);
|
||||
console.log('📤 发送到主题: HDYDCJ_01_DOWN');
|
||||
|
||||
// 先订阅HDYDCJ_01_DOWN主题(如果还没有订阅)
|
||||
client.subscribe("HDYDCJ_01_DOWN", (err) => {
|
||||
if (err) {
|
||||
console.error('❌ 订阅HDYDCJ_01_DOWN失败:', err);
|
||||
} else {
|
||||
console.log('✅ 订阅HDYDCJ_01_DOWN成功');
|
||||
}
|
||||
});
|
||||
|
||||
// 发送数据到HDYDCJ_01_DOWN主题
|
||||
client.publish("HDYDCJ_01_DOWN", message, (err) => {
|
||||
if (err) {
|
||||
console.error('❌ MQTT数据发送失败:', err);
|
||||
uni.showToast({
|
||||
title: '数据发送失败',
|
||||
icon: 'error',
|
||||
duration: 2000
|
||||
});
|
||||
} else {
|
||||
console.log('✅ MQTT数据发送成功');
|
||||
uni.showToast({
|
||||
title: '数据发送成功',
|
||||
icon: 'success',
|
||||
duration: 1500
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
return true;
|
||||
} catch (error) {
|
||||
console.error('❌ 发送MQTT数据异常:', error);
|
||||
uni.showToast({
|
||||
title: '发送数据异常',
|
||||
icon: 'error',
|
||||
duration: 2000
|
||||
});
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
export {
|
||||
createMqtt,
|
||||
closeMqtt,
|
||||
judgeBeat,
|
||||
getConnectionStatus,
|
||||
manualReconnect,
|
||||
sendMqttData,
|
||||
client,
|
||||
}
|
||||
Reference in New Issue
Block a user