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