萤石云对接、温湿度卡片合并、接口更新

This commit is contained in:
吉浩茹
2025-10-06 15:06:48 +08:00
parent 5f20cc7cd3
commit 4b65bea0bb
21 changed files with 5445 additions and 1027 deletions

View File

@ -7,17 +7,22 @@
<!-- 内容区域 -->
<view class="tabbar-content">
<!-- 日期选择 -->
<!-- 日期导航 -->
<view class="date-selector">
<picker mode="date" :value="selectedDate" @change="onDateChange">
<view class="date-picker">
<view class="date-navigation">
<button class="nav-button prev-button" @click="goToPreviousDay">
<!-- <text class="nav-icon"></text> -->
<text class="nav-text">上一天</text>
</button>
<view class="current-date">
<text class="date-text">{{ selectedDate }}</text>
<text class="picker-arrow"></text>
<!-- <text class="date-weekday">{{ getWeekday(selectedDate) }}</text> -->
</view>
</picker>
<!-- <view class="data-status" :class="dataStatus.dataSource">
<text class="status-text">{{ dataStatus.dataSource === 'api' ? '实时数据' : '示例数据' }}</text>
</view> -->
<button class="nav-button next-button" @click="goToNextDay">
<text class="nav-text">下一天</text>
<!-- <text class="nav-icon"></text> -->
</button>
</view>
</view>
<!-- 温度趋势图表 -->
@ -101,10 +106,12 @@ export default {
},
// 页面初始化状态
hasInitialized: false,
// 查询模式:'default' 表示过去24小时'date' 表示按日期查询
queryMode: 'default',
// ECharts配置选项
temperatureOption: {
title: {
text: '温度趋势',
text: '',
left: 'center',
textStyle: {
fontSize: 16,
@ -115,7 +122,7 @@ export default {
trigger: 'axis',
formatter: function(params) {
const data = params[0];
return `时间: ${data.axisValue}<br/>温度: ${data.value}°C`;
return `时间: ${data.axisValue} 温度: ${data.value}°C`;
}
},
grid: {
@ -126,7 +133,7 @@ export default {
},
xAxis: {
type: 'category',
data: Array.from({length: 24}, (_, i) => `${i.toString().padStart(2, '0')}:00`),
data: this.generateXAxisLabels(),
axisLabel: {
interval: 3, // 每4个小时显示一个标签
fontSize: 10
@ -172,7 +179,7 @@ export default {
},
humidityOption: {
title: {
text: '湿度趋势',
text: '',
left: 'center',
textStyle: {
fontSize: 16,
@ -183,7 +190,7 @@ export default {
trigger: 'axis',
formatter: function(params) {
const data = params[0];
return `时间: ${data.axisValue}<br/>湿度: ${data.value}%`;
return `时间: ${data.axisValue} 湿度: ${data.value}%`;
}
},
grid: {
@ -194,7 +201,7 @@ export default {
},
xAxis: {
type: 'category',
data: Array.from({length: 24}, (_, i) => `${i.toString().padStart(2, '0')}:00`),
data: this.generateXAxisLabels(),
axisLabel: {
interval: 3,
fontSize: 10
@ -240,7 +247,7 @@ export default {
},
pm25Option: {
title: {
text: 'PM2.5趋势',
text: '',
left: 'center',
textStyle: {
fontSize: 16,
@ -251,7 +258,7 @@ export default {
trigger: 'axis',
formatter: function(params) {
const data = params[0];
return `时间: ${data.axisValue}<br/>PM2.5: ${data.value}μg/m³`;
return `时间: ${data.axisValue} PM2.5: ${data.value}μg/m³`;
}
},
grid: {
@ -262,7 +269,7 @@ export default {
},
xAxis: {
type: 'category',
data: Array.from({length: 24}, (_, i) => `${i.toString().padStart(2, '0')}:00`),
data: this.generateXAxisLabels(),
axisLabel: {
interval: 3,
fontSize: 10
@ -334,19 +341,90 @@ export default {
}
},
methods: {
// 生成x轴标签
generateXAxisLabels() {
if (this.queryMode === 'date') {
// 按日期查询时显示0-23小时
return Array.from({length: 24}, (_, i) => `${i.toString().padStart(2, '0')}:00`)
} else {
// 默认查询时显示当前时间之前24小时整点时间
const now = new Date()
const currentHour = now.getHours()
const labels = []
for (let i = 23; i >= 0; i--) {
// 计算目标小时
let targetHour = currentHour - i
if (targetHour < 0) {
targetHour += 24 // 跨天处理
}
labels.push(`${String(targetHour).padStart(2, '0')}:00`)
}
return labels
}
},
// 获取今天的日期(本地时区)
getTodayDate() {
const today = new Date()
const year = today.getFullYear()
const month = String(today.getMonth() + 1).padStart(2, '0')
const day = String(today.getDate()).padStart(2, '0')
console.log('📅 获取今天日期:', {
'原始Date对象': today,
'ISO字符串': today.toISOString(),
'本地字符串': today.toLocaleString(),
'本地日期字符串': today.toLocaleDateString(),
'本地时间字符串': today.toLocaleTimeString(),
'时区偏移': today.getTimezoneOffset(),
'格式化结果': `${year}-${month}-${day}`
})
return `${year}-${month}-${day}`
},
// 格式化日期为 YYYY-MM-DD 格式
formatDate(date) {
const year = date.getFullYear()
const month = String(date.getMonth() + 1).padStart(2, '0')
const day = String(date.getDate()).padStart(2, '0')
return `${year}-${month}-${day}`
},
// 获取星期几
getWeekday(dateString) {
const date = new Date(dateString)
const weekdays = ['周日', '周一', '周二', '周三', '周四', '周五', '周六']
return weekdays[date.getDay()]
},
// 获取时间范围显示文本
getTimeRangeText() {
if (this.queryMode === 'date') {
return `查询日期: ${this.selectedDate}`
} else {
const now = new Date()
const past24Hours = new Date(now.getTime() - 24 * 60 * 60 * 1000)
const startTime = this.formatTimeDisplay(past24Hours)
const endTime = this.formatTimeDisplay(now)
return `过去24小时: ${startTime} ~ ${endTime}`
}
},
// 格式化时间显示(用于界面显示)
formatTimeDisplay(date) {
const month = String(date.getMonth() + 1).padStart(2, '0')
const day = String(date.getDate()).padStart(2, '0')
const hours = String(date.getHours()).padStart(2, '0')
const minutes = String(date.getMinutes()).padStart(2, '0')
return `${month}-${day} ${hours}:${minutes}`
},
// 初始化MQTT监听
initMqttListener() {
// 监听数据更新
this.dataUpdateHandler = (data) => {
console.log('参数记录页面收到MQTT数据:', data)
// this.updateChartData(data)
}
mqttDataManager.addListener('dataUpdate', this.dataUpdateHandler)
@ -354,7 +432,6 @@ export default {
// 监听连接状态
this.statusUpdateHandler = (status) => {
this.connectionStatus = status
console.log('参数记录页面连接状态更新:', status)
}
mqttDataManager.addListener('connectionStatus', this.statusUpdateHandler)
@ -364,25 +441,33 @@ export default {
// 更新图表数据
updateChartData(data) {
console.log('📊 参数记录页面更新数据:', data)
// 只处理WSD设备的数据
if (data.deviceType === 'WSD') {
const now = new Date()
const currentHour = now.getHours()
const currentMinute = now.getMinutes()
const currentTimeInHours = currentHour + currentMinute / 60
// 更新对应小时的数据
// 计算数据在数组中的索引位置
let dataIndex
if (this.queryMode === 'date') {
// 按日期查询时,直接使用当前小时
dataIndex = currentHour
} else {
// 默认查询时当前时间对应索引0最新数据
dataIndex = 0
}
// 更新对应位置的数据
if (data.temperature !== undefined) {
Math.round(data.temperature) && (this.temperatureData[currentHour] = Math.round(data.temperature))
console.log(`✅ 温度数据已更新 - 小时${currentHour}:`, this.temperatureData[currentHour])
Math.round(data.temperature) && (this.temperatureData[dataIndex] = Math.round(data.temperature))
}
if (data.humidity !== undefined) {
Math.round(data.humidity) && (this.humidityData[currentHour] = Math.round(data.humidity))
console.log(`✅ 湿度数据已更新 - 小时${currentHour}:`, this.humidityData[currentHour])
Math.round(data.humidity) && (this.humidityData[dataIndex] = Math.round(data.humidity))
}
if (data.pm !== undefined) {
Math.round(data.pm) && (this.pm25Data[currentHour] = Math.round(data.pm))
console.log(`✅ PM2.5数据已更新 - 小时${currentHour}:`, this.pm25Data[currentHour])
Math.round(data.pm) && (this.pm25Data[dataIndex] = Math.round(data.pm))
}
// 重新绘制图表
@ -391,9 +476,9 @@ export default {
})
console.log('✅ 图表数据更新完成:', {
temperature: this.temperatureData[currentHour],
humidity: this.humidityData[currentHour],
hour: currentHour
temperature: this.temperatureData[dataIndex],
humidity: this.humidityData[dataIndex],
dataIndex: dataIndex
})
} else {
console.log('⚠️ 非WSD设备数据跳过图表更新:', data.deviceType)
@ -402,26 +487,29 @@ export default {
// 图表初始化方法
initTemperatureChart() {
console.log('初始化温度图表')
this.temperatureOption.xAxis.data = this.generateXAxisLabels()
this.temperatureOption.series[0].data = this.temperatureData
this.$refs.temperatureChartRef.init(this.temperatureOption)
},
initHumidityChart() {
console.log('初始化湿度图表')
this.humidityOption.xAxis.data = this.generateXAxisLabels()
this.humidityOption.series[0].data = this.humidityData
this.$refs.humidityChartRef.init(this.humidityOption)
},
initPM25Chart() {
console.log('初始化PM2.5图表')
this.pm25Option.xAxis.data = this.generateXAxisLabels()
this.pm25Option.series[0].data = this.pm25Data
this.$refs.pm25ChartRef.init(this.pm25Option)
},
onDateChange(e) {
this.selectedDate = e.detail.value
console.log('📅 日期已更改为:', this.selectedDate)
// 上一天
goToPreviousDay() {
const currentDate = new Date(this.selectedDate)
currentDate.setDate(currentDate.getDate() - 1)
this.selectedDate = this.formatDate(currentDate)
this.queryMode = 'date' // 切换到按日期查询模式
// 显示加载状态
uni.showLoading({
@ -429,29 +517,64 @@ export default {
})
// 重新获取历史数据
this.getHistoryData().finally(() => {
this.getHistoryDataByDate().finally(() => {
uni.hideLoading()
})
},
// 下一天
goToNextDay() {
const currentDate = new Date(this.selectedDate)
const today = new Date()
// 检查是否已经是今天,如果是则不允许继续往后
if (this.selectedDate >= this.formatDate(today)) {
uni.showToast({
title: '不能查看未来日期',
icon: 'none',
duration: 2000
})
return
}
currentDate.setDate(currentDate.getDate() + 1)
this.selectedDate = this.formatDate(currentDate)
this.queryMode = 'date' // 切换到按日期查询模式
// 显示加载状态
uni.showLoading({
title: '加载数据中...'
})
// 重新获取历史数据
this.getHistoryDataByDate().finally(() => {
uni.hideLoading()
})
},
// 更新图表数据
updateCharts() {
const xAxisLabels = this.generateXAxisLabels()
if (this.$refs.temperatureChartRef) {
this.temperatureOption.xAxis.data = xAxisLabels
this.temperatureOption.series[0].data = this.temperatureData
this.$refs.temperatureChartRef.setOption(this.temperatureOption)
}
if (this.$refs.humidityChartRef) {
this.humidityOption.xAxis.data = xAxisLabels
this.humidityOption.series[0].data = this.humidityData
this.$refs.humidityChartRef.setOption(this.humidityOption)
}
if (this.$refs.pm25ChartRef) {
this.pm25Option.xAxis.data = xAxisLabels
this.pm25Option.series[0].data = this.pm25Data
this.$refs.pm25ChartRef.setOption(this.pm25Option)
}
},
// 获取历史数据
async getHistoryData() {
// 根据选择的日期获取历史数据
async getHistoryDataByDate() {
try {
// 根据选择的日期构建时间范围
const startTime = `${this.selectedDate} 00:00:00`
@ -462,7 +585,83 @@ export default {
endTime: endTime
}
console.log('📊 请求历史数据:', params)
const response = await dataHistoryApi.getHistory(params)
// 处理历史数据
if (response && Array.isArray(response) && response.length > 0) {
this.historyData = response
this.processHistoryData(response)
// 更新数据状态
this.dataStatus = {
isRealData: true,
lastUpdateTime: new Date().toLocaleString(),
dataSource: 'api'
}
// 保存查询事件
await this.createQueryEvent('success', response.length)
} else {
console.log('📊 没有历史数据,显示空状态')
// 没有数据时显示空状态
this.showEmptyState()
// 更新数据状态
this.dataStatus = {
isRealData: false,
lastUpdateTime: new Date().toLocaleString(),
dataSource: 'empty'
}
// 保存查询事件(无数据)
await this.createQueryEvent('empty', 0)
}
return response
} catch (error) {
console.error('❌ 历史数据获取失败:', error)
// 出错时显示空状态
this.showEmptyState()
// 更新数据状态
this.dataStatus = {
isRealData: false,
lastUpdateTime: new Date().toLocaleString(),
dataSource: 'error'
}
// 保存查询事件(错误)
await this.createQueryEvent('error', 0)
// 显示错误提示
uni.showToast({
title: '数据加载失败',
icon: 'none',
duration: 2000
})
throw error
}
},
// 获取历史数据默认过去24小时
async getHistoryData() {
try {
// 构建时间范围从当前时间开始过去24小时
const now = new Date()
const past24Hours = new Date(now.getTime() - 24 * 60 * 60 * 1000) // 24小时前
// 格式化时间字符串
const startTime = this.formatDateTimeString(past24Hours)
const endTime = this.formatDateTimeString(now)
const params = {
startTime: startTime,
endTime: endTime
}
console.log('📊 请求历史数据过去24小时:', params)
const response = await dataHistoryApi.getHistory(params)
@ -586,11 +785,37 @@ export default {
const hour = time.getHours()
const minute = time.getMinutes()
// 计算在24小时数组中的索引位置
let dataIndex
if (this.queryMode === 'date') {
// 按日期查询时,直接使用小时作为索引
dataIndex = hour
} else {
// 默认查询时,需要计算相对于当前时间的位置(按小时计算)
const now = new Date()
const currentHour = now.getHours()
// 计算时间差(小时)
let timeDiff = currentHour - hour
if (timeDiff < 0) {
timeDiff += 24 // 跨天的情况
}
// 转换为数组索引23表示24小时前0表示当前时间
dataIndex = 23 - timeDiff
if (dataIndex < 0 || dataIndex >= 24) {
console.log(`⚠️ 数据超出范围,跳过 - 索引:${dataIndex}`)
return // 超出范围的数据跳过
}
}
// 处理温度数据 (wd是温度)
const temperature = item.wd || item.temperature || item.temp || item.T
if (temperature !== undefined && temperature !== null && temperature >= 0) {
this.chartData.temperature.push({
time: hour + minute / 60,
time: dataIndex,
value: Number(temperature),
timestamp: item.createTime || item.timestamp || item.time
})
@ -600,7 +825,7 @@ export default {
const humidity = item.sd || item.humidity || item.hum || item.H
if (humidity !== undefined && humidity !== null && humidity >= 0) {
this.chartData.humidity.push({
time: hour + minute / 60,
time: dataIndex,
value: Number(humidity),
timestamp: item.createTime || item.timestamp || item.time
})
@ -610,7 +835,7 @@ export default {
const pm = item.pm || item.pm25 || item.pm2_5 || item.PM
if (pm !== undefined && pm !== null && pm >= 0) {
this.chartData.pm.push({
time: hour + minute / 60,
time: dataIndex,
value: Number(pm),
timestamp: item.createTime || item.timestamp || item.time
})
@ -633,17 +858,20 @@ export default {
updateChartsWithHistoryData() {
console.log('🎨 使用历史数据更新图表')
const xAxisLabels = this.generateXAxisLabels()
// 处理温度数据
if (this.chartData.temperature.length > 0) {
const temperatureData = new Array(24).fill(0)
this.chartData.temperature.forEach(item => {
const hour = Math.floor(item.time)
if (hour >= 0 && hour < 24) {
temperatureData[hour] = item.value || 0
const dataIndex = Math.floor(item.time)
if (dataIndex >= 0 && dataIndex < 24) {
temperatureData[dataIndex] = item.value || 0
}
})
this.temperatureData = temperatureData
if (this.$refs.temperatureChartRef) {
this.temperatureOption.xAxis.data = xAxisLabels
this.temperatureOption.series[0].data = temperatureData
this.$refs.temperatureChartRef.setOption(this.temperatureOption)
}
@ -651,6 +879,7 @@ export default {
// 没有温度数据时使用0填充
this.temperatureData = new Array(24).fill(0)
if (this.$refs.temperatureChartRef) {
this.temperatureOption.xAxis.data = xAxisLabels
this.temperatureOption.series[0].data = this.temperatureData
this.$refs.temperatureChartRef.setOption(this.temperatureOption)
}
@ -660,13 +889,14 @@ export default {
if (this.chartData.humidity.length > 0) {
const humidityData = new Array(24).fill(0)
this.chartData.humidity.forEach(item => {
const hour = Math.floor(item.time)
if (hour >= 0 && hour < 24) {
humidityData[hour] = item.value || 0
const dataIndex = Math.floor(item.time)
if (dataIndex >= 0 && dataIndex < 24) {
humidityData[dataIndex] = item.value || 0
}
})
this.humidityData = humidityData
if (this.$refs.humidityChartRef) {
this.humidityOption.xAxis.data = xAxisLabels
this.humidityOption.series[0].data = humidityData
this.$refs.humidityChartRef.setOption(this.humidityOption)
}
@ -674,6 +904,7 @@ export default {
// 没有湿度数据时使用0填充
this.humidityData = new Array(24).fill(0)
if (this.$refs.humidityChartRef) {
this.humidityOption.xAxis.data = xAxisLabels
this.humidityOption.series[0].data = this.humidityData
this.$refs.humidityChartRef.setOption(this.humidityOption)
}
@ -683,13 +914,14 @@ export default {
if (this.chartData.pm.length > 0) {
const pmData = new Array(24).fill(0)
this.chartData.pm.forEach(item => {
const hour = Math.floor(item.time)
if (hour >= 0 && hour < 24) {
pmData[hour] = item.value || 0
const dataIndex = Math.floor(item.time)
if (dataIndex >= 0 && dataIndex < 24) {
pmData[dataIndex] = item.value || 0
}
})
this.pm25Data = pmData
if (this.$refs.pm25ChartRef) {
this.pm25Option.xAxis.data = xAxisLabels
this.pm25Option.series[0].data = pmData
this.$refs.pm25ChartRef.setOption(this.pm25Option)
}
@ -697,6 +929,7 @@ export default {
// 没有PM数据时使用0填充
this.pm25Data = new Array(24).fill(0)
if (this.$refs.pm25ChartRef) {
this.pm25Option.xAxis.data = xAxisLabels
this.pm25Option.series[0].data = this.pm25Data
this.$refs.pm25ChartRef.setOption(this.pm25Option)
}
@ -752,6 +985,19 @@ export default {
const hours = String(date.getHours()).padStart(2, '0')
const minutes = String(date.getMinutes()).padStart(2, '0')
const seconds = String(date.getSeconds()).padStart(2, '0')
const result = `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`
return result
},
// 格式化时间字符串用于API请求
formatDateTimeString(date) {
const year = date.getFullYear()
const month = String(date.getMonth() + 1).padStart(2, '0')
const day = String(date.getDate()).padStart(2, '0')
const hours = String(date.getHours()).padStart(2, '0')
const minutes = String(date.getMinutes()).padStart(2, '0')
const seconds = String(date.getSeconds()).padStart(2, '0')
return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`
}
}
@ -768,12 +1014,20 @@ export default {
.date-selector {
background: white;
border-radius: 8rpx;
padding: 15rpx;
margin-bottom: 15rpx;
display: flex;
justify-content: space-between;
align-items: center;
border-radius: 12rpx;
padding: 20rpx;
margin-bottom: 20rpx;
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.1);
}
.time-range-info {
flex: 1;
}
.time-range-text {
font-size: 26rpx;
color: #333;
font-weight: 500;
}
.connection-status {
@ -809,23 +1063,70 @@ export default {
font-size: 24rpx;
}
.date-picker {
.date-navigation {
display: flex;
align-items: center;
gap: 8rpx;
padding: 15rpx 20rpx;
background-color: #f8f8f8;
border-radius: 6rpx;
gap: 15rpx;
justify-content: space-between;
}
.nav-button {
// padding: 12rpx 20rpx;
// background: #007aff;
// color: white;
margin: 0;
border: none;
border-radius: 8rpx;
font-size: 24rpx;
// min-width: 120rpx;
display: flex;
align-items: center;
justify-content: center;
gap: 6rpx;
transition: all 0.2s ease;
}
.nav-button:active {
// background: #0056b3;
transform: scale(0.95);
}
.nav-button::after {
border: none;
}
.nav-icon {
font-size: 24rpx;
color: white;
}
.nav-text {
// color: white;
font-size: 24rpx;
font-weight: 500;
}
.current-date {
padding: 16rpx 24rpx;
background: #f8f9fa;
border-radius: 8rpx;
min-width: 180rpx;
text-align: center;
border: 1rpx solid #e9ecef;
}
.date-text {
font-size: 28rpx;
color: #333;
font-weight: 600;
display: block;
margin-bottom: 4rpx;
}
.picker-arrow {
color: #999;
font-size: 20rpx;
.date-weekday {
font-size: 22rpx;
color: #666;
font-weight: 400;
}
.chart-card {
@ -839,7 +1140,7 @@ export default {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 30rpx;
// margin-bottom: 30rpx;
}
.chart-title {