feat:订阅Recall、日期查询

This commit is contained in:
吉浩茹
2025-10-11 10:03:58 +08:00
parent 4e66592cf8
commit 8b1a84f739
7 changed files with 777 additions and 349 deletions

View File

@ -15,6 +15,21 @@
</view>
</view> -->
<!-- 日期选择区域 -->
<view class="date-picker-container">
<picker
mode="date"
:value="selectedDate"
@change="onDateChange"
class="date-picker"
>
<view class="picker-input">
<text class="picker-text">{{ selectedDate || '请选择日期' }}</text>
<text class="picker-icon"></text>
</view>
</picker>
</view>
<!-- 报警表格 -->
<view class="page-content">
<view class="alarm-content">
@ -114,6 +129,11 @@ const isLoadingMore = ref(false);
const scrollTop = ref(0);
const isScrolling = ref(false);
// 日期选择相关
const selectedDate = ref('');
const startTime = ref('');
const endTime = ref('');
// 移除空行占位逻辑,没有数据时只显示"暂无数据"
// MQTT报警服务接口预留
@ -151,10 +171,36 @@ const mqttAlarmService = {
isLoadingMore.value = true;
}
// 如果没有选择日期,使用默认日期(当天)
let queryStartTime = startTime.value;
let queryEndTime = endTime.value;
if (!queryStartTime || !queryEndTime) {
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');
const todayStr = `${year}-${month}-${day}`;
queryStartTime = `${todayStr} 00:00:00`;
queryEndTime = `${todayStr} 23:59:59`;
// 更新选择的日期
if (!selectedDate.value) {
selectedDate.value = todayStr;
startTime.value = queryStartTime;
endTime.value = queryEndTime;
}
}
console.log('📅 查询时间范围:', queryStartTime, '至', queryEndTime);
// 调用分页获取告警接口
const response = await alertApi.getList({
const response = await alertApi.getListByCreateTime({
page: page,
size: size
size: size,
startTime: queryStartTime,
endTime: queryEndTime
});
// 处理响应数据
@ -408,6 +454,42 @@ const scrollToTop = () => {
scrollTop.value = scrollTop.value === 0 ? 1 : 0;
};
// 日期选择处理,选择后直接查询
const onDateChange = async (e) => {
selectedDate.value = e.detail.value;
console.log('选择的日期:', selectedDate.value);
// 自动构建开始和结束时间
if (selectedDate.value) {
startTime.value = `${selectedDate.value} 00:00:00`;
endTime.value = `${selectedDate.value} 23:59:59`;
console.log('开始时间:', startTime.value);
console.log('结束时间:', endTime.value);
// 选择日期后直接查询
console.log('🔍 开始查询报警记录');
console.log('查询时间范围:', startTime.value, '至', endTime.value);
try {
// 重置分页状态
currentPage.value = 0;
hasMoreData.value = true;
alarmList.value = [];
// 使用选择的日期范围查询
await mqttAlarmService.getHistoryAlarms(0, pageSize.value, false);
uni.showToast({
title: '查询成功',
icon: 'success',
duration: 1500
});
} catch (error) {
console.error('❌ 查询失败:', error);
}
}
};
// 滚动到底部
const scrollToBottom = () => {
// 使用nextTick确保DOM更新完成
@ -543,6 +625,49 @@ onUnmounted(() => {
height: 100%;
}
// 日期选择器容器样式
.date-picker-container {
display: flex;
align-items: center;
// justify-content: center;
padding: 20rpx 30rpx;
background: linear-gradient(135deg, #f8f9fa 0%, #ffffff 100%);
border-bottom: 2rpx solid #e8eaed;
}
.date-picker {
width: 100%;
// max-width: 500rpx;
}
.picker-input {
display: flex;
align-items: center;
justify-content: space-between;
padding: 16rpx 24rpx;
background: #ffffff;
border: 2rpx solid #dadce0;
border-radius: 8rpx;
transition: all 0.3s ease;
}
.picker-input:active {
border-color: #1a73e8;
background: #f1f5ff;
}
.picker-text {
font-size: 26rpx;
color: #3c4043;
flex: 1;
}
.picker-icon {
font-size: 20rpx;
color: #5f6368;
margin-left: 12rpx;
}
.alarm-content {
// 继承通用内容样式
flex: 1;
@ -863,6 +988,18 @@ onUnmounted(() => {
.empty-text {
font-size: 28rpx;
}
.date-picker-container {
padding: 24rpx 32rpx;
}
.date-picker {
max-width: 600rpx;
}
.picker-text {
font-size: 28rpx;
}
}
// 响应式设计 - 手机设备适配
@ -880,6 +1017,18 @@ onUnmounted(() => {
.empty-text {
font-size: 28rpx;
}
.date-picker-container {
padding: 16rpx 20rpx;
}
.date-picker {
max-width: 100%;
}
.picker-text {
font-size: 24rpx;
}
}
// 响应式设计 - 大屏设备适配

View File

@ -15,6 +15,21 @@
</view>
</view> -->
<!-- 日期选择区域 -->
<view class="date-picker-container">
<picker
mode="date"
:value="selectedDate"
@change="onDateChange"
class="date-picker"
>
<view class="picker-input">
<text class="picker-text">{{ selectedDate || '请选择日期' }}</text>
<text class="picker-icon"></text>
</view>
</picker>
</view>
<!-- 日志表格 -->
<view class="page-content">
<view class="log-content">
@ -91,6 +106,14 @@
import { ref, computed, onMounted, onUnmounted, nextTick } from 'vue';
import { eventApi } from '@/utils/api.js';
// 接收父组件传递的查询日期
const props = defineProps({
queryDate: {
type: String,
default: ''
}
});
// 日志数据
const logList = ref([]);
const isLoading = ref(false);
@ -107,6 +130,11 @@ const isLoadingMore = ref(false);
const scrollTop = ref(0);
const isScrolling = ref(false);
// 日期选择相关
const selectedDate = ref('');
const startTime = ref('');
const endTime = ref('');
// 移除空行占位逻辑,没有数据时只显示"暂无数据"
// 状态映射函数
@ -167,8 +195,8 @@ const mqttLogService = {
},
// 获取历史日志(分页)
getHistoryLogs: async (page = 0, size = 20, isLoadMore = false) => {
console.log(`📄 加载第${page}页数据,每页${size}`);
getHistoryLogs: async (page = 0, size = 20, isLoadMore = false, queryDate = '') => {
console.log(`📄 加载第${page}页数据,每页${size},查询日期:${queryDate}`);
try {
if (!isLoadMore) {
isLoading.value = true;
@ -177,8 +205,40 @@ const mqttLogService = {
}
hasInitialized.value = true;
// 如果没有选择日期,使用默认日期(当天)
let queryStartTime = startTime.value;
let queryEndTime = endTime.value;
if (!queryStartTime || !queryEndTime) {
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');
const todayStr = `${year}-${month}-${day}`;
queryStartTime = `${todayStr} 00:00:00`;
queryEndTime = `${todayStr} 23:59:59`;
// 更新选择的日期
if (!selectedDate.value) {
selectedDate.value = todayStr;
startTime.value = queryStartTime;
endTime.value = queryEndTime;
}
}
console.log('📅 查询时间范围:', queryStartTime, '至', queryEndTime);
// 构建查询参数
const params = {
page: page,
size: size,
startTime: queryStartTime,
endTime: queryEndTime
};
// 调用事件API获取分页数据
const response = await eventApi.getList({ page: page, size: size });
const response = await eventApi.getListByCreateTime(params);
// 将API数据转换为日志格式
const newLogs = response.data.map(item => ({
@ -264,7 +324,7 @@ const onScrollToLower = () => {
const nextPage = currentPage.value + 1;
console.log(`📄 开始加载第${nextPage}页数据`);
mqttLogService.getHistoryLogs(nextPage, pageSize.value, true);
mqttLogService.getHistoryLogs(nextPage, pageSize.value, true, props.queryDate);
};
// 滚动到顶部
@ -272,6 +332,42 @@ const scrollToTop = () => {
scrollTop.value = scrollTop.value === 0 ? 1 : 0;
};
// 日期选择处理,选择后直接查询
const onDateChange = async (e) => {
selectedDate.value = e.detail.value;
console.log('选择的日期:', selectedDate.value);
// 自动构建开始和结束时间
if (selectedDate.value) {
startTime.value = `${selectedDate.value} 00:00:00`;
endTime.value = `${selectedDate.value} 23:59:59`;
console.log('开始时间:', startTime.value);
console.log('结束时间:', endTime.value);
// 选择日期后直接查询
console.log('🔍 开始查询系统日志');
console.log('查询时间范围:', startTime.value, '至', endTime.value);
try {
// 重置分页状态
currentPage.value = 0;
hasMoreData.value = true;
logList.value = [];
// 使用选择的日期范围查询
await mqttLogService.getHistoryLogs(0, pageSize.value, false, selectedDate.value);
uni.showToast({
title: '查询成功',
icon: 'success',
duration: 1500
});
} catch (error) {
console.error('❌ 查询失败:', error);
}
}
};
// 组件生命周期
@ -280,7 +376,7 @@ onMounted(async () => {
// 连接MQTT并初始化
// await mqttLogService.connect();
// await mqttLogService.subscribeLogData();
await mqttLogService.getHistoryLogs(0, pageSize.value, false);
await mqttLogService.getHistoryLogs(0, pageSize.value, false, props.queryDate);
} catch (error) {
console.error('日志系统初始化失败:', error);
uni.showToast({
@ -300,15 +396,32 @@ const refreshData = async () => {
logList.value = [];
// 重新获取第一页数据
await mqttLogService.getHistoryLogs(0, pageSize.value, false);
await mqttLogService.getHistoryLogs(0, pageSize.value, false, props.queryDate);
} catch (error) {
console.error('❌ 刷新数据失败:', error);
}
};
// 按日期查询方法
const queryByDate = async (queryDate) => {
console.log('📅 按日期查询系统日志:', queryDate)
try {
// 重置分页状态
currentPage.value = 0;
hasMoreData.value = true;
logList.value = [];
// 按日期获取第一页数据
await mqttLogService.getHistoryLogs(0, pageSize.value, false, queryDate);
} catch (error) {
console.error('❌ 按日期查询失败:', error);
}
};
// 暴露方法给父组件
defineExpose({
refreshData
refreshData,
queryByDate
});
onUnmounted(() => {
@ -332,6 +445,49 @@ onUnmounted(() => {
height: 100%;
}
// 日期选择器容器样式
.date-picker-container {
display: flex;
align-items: center;
// justify-content: center;
padding: 20rpx 30rpx;
background: linear-gradient(135deg, #f8f9fa 0%, #ffffff 100%);
border-bottom: 2rpx solid #e8eaed;
}
.date-picker {
width: 100%;
// max-width: 500rpx;
}
.picker-input {
display: flex;
align-items: center;
justify-content: space-between;
padding: 16rpx 24rpx;
background: #ffffff;
border: 2rpx solid #dadce0;
border-radius: 8rpx;
transition: all 0.3s ease;
}
.picker-input:active {
border-color: #1a73e8;
background: #f1f5ff;
}
.picker-text {
font-size: 26rpx;
color: #3c4043;
flex: 1;
}
.picker-icon {
font-size: 20rpx;
color: #5f6368;
margin-left: 12rpx;
}
.log-content {
// 继承通用内容样式
flex: 1;
@ -547,74 +703,6 @@ onUnmounted(() => {
font-weight: 400;
}
.table-loading-spinner {
width: 60rpx;
height: 60rpx;
border: 4rpx solid #e9ecef;
border-top: 4rpx solid #6c757d;
border-radius: 50%;
animation: spin 1s linear infinite;
}
.table-loading-text {
font-size: 28rpx;
color: #6c757d;
font-weight: 500;
}
.table-empty-container {
display: flex;
justify-content: center;
align-items: center;
padding: 100rpx 20rpx;
background-color: #ffffff;
}
.table-empty-text {
font-size: 32rpx;
color: #999;
font-weight: 500;
}
.loading-container {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 60rpx;
gap: 20rpx;
}
.loading-spinner {
width: 60rpx;
height: 60rpx;
border: 4rpx solid rgba(255, 152, 0, 0.3);
border-top: 4rpx solid #ff9800;
border-radius: 50%;
animation: spin 1s linear infinite;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
.loading-text {
font-size: 28rpx;
color: #666;
}
.empty-container {
display: flex;
justify-content: center;
align-items: center;
padding: 100rpx;
}
.empty-text {
font-size: 32rpx;
color: #adb5bd;
}
// 响应式设计 - 平板设备适配
@media (min-width: 768px) and (max-width: 1024px) {
@ -631,6 +719,18 @@ onUnmounted(() => {
.empty-text {
font-size: 28rpx;
}
.date-picker-container {
padding: 24rpx 32rpx;
}
.date-picker {
max-width: 600rpx;
}
.picker-text {
font-size: 28rpx;
}
}
// 响应式设计 - 手机设备适配
@ -648,6 +748,18 @@ onUnmounted(() => {
.empty-text {
font-size: 24rpx;
}
.date-picker-container {
padding: 16rpx 20rpx;
}
.date-picker {
max-width: 100%;
}
.picker-text {
font-size: 24rpx;
}
}
// 响应式设计 - 大屏设备适配
@ -667,43 +779,43 @@ onUnmounted(() => {
}
}
/* 加载更多样式 */
// 加载更多样式
.load-more-container {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 30rpx;
gap: 20rpx;
padding: 30rpx 20rpx;
gap: 15rpx;
background-color: #ffffff;
}
.load-more-spinner {
width: 40rpx;
height: 40rpx;
border: 4rpx solid #f3f3f3;
border-top: 4rpx solid #3f51b5;
border: 3rpx solid #e8eaed;
border-top: 3rpx solid #5f6368;
border-radius: 50%;
animation: spin 1s linear infinite;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
.load-more-text {
font-size: 28rpx;
color: #666;
font-size: 24rpx;
color: #5f6368;
font-weight: 400;
}
.no-more-container {
display: flex;
align-items: center;
justify-content: center;
padding: 30rpx;
align-items: center;
padding: 30rpx 20rpx;
background-color: #ffffff;
}
.no-more-text {
font-size: 28rpx;
color: #999;
font-size: 24rpx;
color: #9aa0a6;
font-weight: 400;
}
</style>