Files
mqtt_power/docs/系统开发日志/LogBook4.md
2025-05-25 13:16:34 +08:00

305 lines
23 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

## 2024-08-09 (全局样式优化 - 内容区域背景)
- **目标**: 为所有认证后页面的主要内容区域设置统一的淡灰色背景和内边距,以提升视觉一致性。
- **问题**: 之前 `bg-gray-100` 和特定内边距仅应用于部分页面如管理员控制台其他页面如MQTT日志页面未使用此背景。
- **解决方案**:
- 修改 `charging_web_app/src/app/(authenticated)/layout.tsx` 文件。
-`<main>` 元素的类名从 `"flex-grow container mx-auto p-4 sm:p-6 lg:p-8"` 修改为 `"flex-grow container mx-auto bg-gray-100 py-8 px-4 md:px-6 lg:px-8"`
- 这使得所有通过 `AuthenticatedLayout` 渲染的子页面 (`{children}`) 的主内容区域都将继承 `bg-gray-100` 背景色和 `py-8 px-4 md:px-6 lg:px-8` 的内边距。
- **状态**: 全局内容区域背景和内边距已统一。所有认证后的页面现在应具有一致的淡灰色背景和内边距。
- **下一步**: 用户验证所有相关页面的视觉效果。
## 2024-08-09 (MQTT通信日志页面 - 对接真实API与UI增强)
- **目标**: 将 `charging_web_app/src/app/(authenticated)/admin/mqtt-logs/page.tsx` 从使用模拟数据改为对接真实的后端API并使用Ant Design组件增强UI和功能。
- **实施**:
- **移除模拟数据**: 删除了页面中用于生成和显示模拟日志的逻辑。
- **引入Ant Design**: 页面全面改用Ant Design组件包括 `Table`, `Form`, `Input`, `Select`, `Button`, `DatePicker`, `Tag`, `Tooltip`, `Card`, `Row`, `Col`, `Space`
- **API对接**:
- 导入了 `fetchMqttLogs` 服务 (来自 `logService.ts`) 和相关的类型定义 (`MqttCommunicationLog`, `MqttLogQueryRequest`, `PageResponse`, `BaseResponse` 来自 `log.types.ts`)。
- `fetchData` 函数现在调用 `fetchMqttLogs`,并正确处理后端返回的数据结构,包括分页信息和错误处理。
- 使用 `dayjs` 格式化时间戳。
- **查询表单功能**:
- 创建了一个包含多个筛选条件的表单 (客户端ID, 主题, 方向, Payload内容, 时间范围, 关联会话ID, 关联任务ID)。
- 实现了查询和重置功能,查询时会重新获取数据并重置到第一页。
- 时间范围选择器使用 AntD `RangePicker`
- **表格功能增强**:
- 实现了服务器端分页和排序。
- 表格列根据后端返回的数据模型 (`MqttCommunicationLog`) 进行定义,并对关键字段 (时间戳, 方向, Payload, Retained标记等) 进行了格式化和本地化显示。
- Payload 列使用 `Tooltip` 展示完整内容,并通过 `pre` 标签保持格式。
- 为表格启用了水平滚动条和边框。
- **权限与加载状态**: 保留并优化了用户权限检查逻辑和加载状态的显示。
- **状态**: MQTT通信日志页面现在能够从后端API获取、显示和筛选真实的日志数据并拥有了基于Ant Design的完善的用户界面。与全局布局和导航保持一致。
- **下一步**:
- 用户进行全面测试,包括查询、分页、排序、错误处理等。
- 根据反馈进行可能的微调。
## 2024-08-09 (MQTT通信日志页面 - 修复路径冲突)
- **问题**: Next.js 报错 "You cannot have two parallel pages that resolve to the same path",指向 `/src/app/admin`
- **原因**:
- 先前在 `charging_web_app/src/app/admin/mqtt-logs/page.tsx` 创建了MQTT日志页面。
- 之后为了应用认证布局,在 `charging_web_app/src/app/(authenticated)/admin/mqtt-logs/page.tsx` 又创建了同路径页面。
- Next.js 的路由组 `(authenticated)` 不影响 URL 路径,导致两个文件都解析到 `/admin/mqtt-logs`,引发冲突。
- **解决方案**:
- 删除了位于 `charging_web_app/src/app/admin/mqtt-logs/` 目录下的旧 `page.tsx` 文件及其父目录(如果为空)。
- 保留了 `charging_web_app/src/app/(authenticated)/admin/mqtt-logs/page.tsx`,因为它能正确应用期望的布局。
- **状态**: 路径冲突已解决。MQTT日志页面现在由 `(authenticated)` 路由组内的文件唯一定义。
## 2024-08-09 (MQTT通信日志页面 - 布局优化)
- **目标**: 确保 `charging_web_app` 中新创建的MQTT通信日志页面 (`/admin/mqtt-logs`) 与应用的全局布局(特别是顶部导航栏)保持一致。
- **分析**:
- 全局的根布局 `charging_web_app/src/app/layout.tsx` 比较基础,主要提供全局样式和 `AuthProvider`
- 经过认证的用户界面布局(包括顶部导航栏、主内容区和页脚)定义在 `charging_web_app/src/app/(authenticated)/layout.tsx` 中。
- `AuthenticatedLayout.tsx` 使用 Tailwind CSS并包含了一个指向 `/admin/mqtt-logs` 的链接(仅管理员可见)。
- **实施**:
-`charging_web_app/src/app/(authenticated)/admin/mqtt-logs/` 目录下创建了 `page.tsx` 文件。
- `page.tsx` 中实现了一个基本的MQTT日志展示组件包括模拟数据加载、分页、权限检查和基本的Tailwind CSS样式使其内容区域风格与整体应用一致。
- 由于页面嵌套在 `(authenticated)/admin/` 路径下,它自动继承了 `(authenticated)/layout.tsx` 的布局,因此顶部导航栏和整体页面结构符合预期。
- **状态**: MQTT通信日志页面已创建并成功融入了现有的全局布局和导航结构中。管理员用户可以通过导航栏的链接访问此页面。
- **下一步**:
-`page.tsx` 中的模拟数据获取逻辑替换为真实的API调用连接到先前开发的后端 `MqttCommunicationLogController`)。
- 完善页面的筛选、排序和错误处理功能。
## 2024-08-08 (MQTT通信日志功能 - 开发完成)
- **概述**: MQTT通信日志功能模块开发完成。该模块旨在记录系统与MQTT代理之间的所有通信消息并提供前端界面供管理员查询和审计。
- **后端**:
- 实现了独立的MQTT客户端用于监听所有相关主题的上行消息。
- 通过AOP切面记录了业务系统主动发送的下行消息。
- 消息数据异步存入 `mqtt_communication_log` 表,确保不阻塞主业务线程。
- 提供了分页查询API (`/api/admin/mqtt-log/list/page`),支持多种条件筛选和排序。
- 关键配置项如日志开关、订阅主题、客户端ID前缀、异步线程池参数均可通过 `application.yml` 进行配置。
- 修复了开发过程中的Bean注入冲突和API路径错误。
- **前端 (`charging_web_app`)**:
- 创建了MQTT日志查看页面 (`/admin/mqtt-logs`)。
- 实现了基于Ant Design的查询表单和数据表格支持分页、条件查询和排序。
- 表格中的关键字段如方向、Payload格式、是否保留已进行本地化中文显示。
- 解决了API调用404错误和数据无法在表格中正确显示的问题。
- 在管理员导航栏中添加了页面入口。
- **核心功能确认**: `payload` 字段记录的是MQTT消息队列中的原始发送/接收内容。
- **当前状态**: 功能已可基本使用。后端日志记录和API服务正常前端页面可展示和查询日志数据。
- **后续待办**:
- 处理前端控制台中剩余的Ant Design Modal `destroyOnClose` 废弃警告 (位于 `DashboardPage`)。
- 调研并处理Ant Design v5与React 19的兼容性警告。
- 进行更全面的功能测试,包括各种边界条件和长时间运行的稳定性。
- (可选) 进一步优化Payload的展示例如对JSON格式的Payload进行美化或提供折叠/展开功能。
- (可选) 根据实际需求,考虑日志数据的定期归档或清理策略的实现。
## 2024-07-29 (用户激活码功能 - 后端主体)
- **核心业务逻辑实现 (Service & Impl)**:
- 创建 `ActivationCodeService.java` 接口,定义了激活码生成 (`generateCodes`)、兑换 (`redeemCode`) 和查询条件构建 (`getQueryWrapper`) 的方法。
- 创建 `ActivationCodeServiceImpl.java` 实现类:
- `generateCodes`: 实现批量生成激活码的逻辑,使用 UUID 生成唯一码,支持自定义数量、面值、过期时间和批次号,并进行批量保存。
- `redeemCode`: 实现用户兑换激活码的逻辑,包含参数校验、激活码状态(是否存在、已用、过期)校验,调用 `UserService.increaseBalance()` 增加用户余额,并更新激活码状态。整个过程使用 `@Transactional` 保证事务原子性。
- `getQueryWrapper`: 根据 `ActivationCodeQueryRequest` 中的各种条件如激活码、使用状态、批次号、用户ID、面值范围、过期时间范围、创建时间范围构建 MyBatis Plus 查询条件,并处理排序(默认按创建时间降序)。
- **数据传输对象 (DTO) & 视图对象 (VO)**:
-`com.yupi.project.model.dto.activationcode` 包下创建了以下 DTO
- `RedeemCodeRequest.java`: 用户兑换激活码请求 (包含 `code`)。
- `GenerateCodesRequest.java`: 管理员生成激活码请求 (包含 `count`, `value`, `expireTime`, `batchId`)。
- `ActivationCodeQueryRequest.java`: 管理员查询激活码请求,继承自 `PageRequest`,包含多种筛选条件。
-`com.yupi.project.model.vo` 包下创建了 `ActivationCodeVO.java`:
- 包含激活码详细信息,并为已使用的激活码增加了 `userName` 字段(用于显示使用者用户名),日期时间字段使用 `@JsonFormat` 格式化。
- **API 控制器 (Controller)**:
- 创建 `ActivationCodeController.java`,定义了以下 RESTful API 接口:
- `POST /api/activation-code/redeem`: 用户兑换激活码接口。需要用户登录。调用 `activationCodeService.redeemCode`
- `POST /api/activation-code/admin/generate`: 管理员批量生成激活码接口。使用 `@AuthCheck(mustRole = UserConstant.ADMIN_ROLE)` 进行权限控制。调用 `activationCodeService.generateCodes`
- `POST /api/activation-code/admin/list/page`: 管理员分页查询激活码接口。使用 `@AuthCheck(mustRole = UserConstant.ADMIN_ROLE)` 进行权限控制。调用 `activationCodeService.page``getQueryWrapper`,并实现 `Page<ActivationCode>``Page<ActivationCodeVO>` 的转换逻辑,包括填充 `userName`
- **依赖注入与注解**:
- 正确使用了 `@Service`, `@Resource`, `@RestController`, `@RequestMapping`, `@PostMapping`, `@RequestBody`, `@AuthCheck`, `@Transactional`, `@Slf4j` 等注解。
- **项目结构**: 相关类已放置在规范的包路径下。
- **待办与后续**:
- 编写 API 文档 (Swagger/OpenAPI)。
- 编写单元测试和集成测试。
- 前端页面对接和开发。
- 根据实际测试反馈进一步完善错误处理和日志。
## 2024-08-05 (MQTT通信日志系统 - 开发方案)
- **开发方案文档创建**:
-`springboot-init-main/doc/` 目录下创建了 `mqtt_communication_log_plan.md` 文件详细描述了MQTT通信日志系统的设计与实现方案。
- 该系统旨在完整记录单片机与服务器之间的所有MQTT消息通信用于通信可视化、故障诊断、性能分析和安全审计。
- **系统定位与设计原则**:
- 纯日志记录系统,不干扰正常业务流程,不消费消息队列中的数据
- 采用"监听者模式"通过独立的MQTT客户端进行旁路监听
- 异步记录消息,确保不影响主业务性能
- **核心架构设计**:
- 利用已有的 `mqtt_communication_log` 数据表存储日志数据
- 设计了 `MqttCommunicationLogger``MqttLogService``MqttLogController` 三个核心组件
- 使用AOP技术拦截发送消息记录下行消息内容
- 通过独立MQTT客户端订阅同样的主题记录上行消息内容
- **技术实现细节**:
- 设计了消息监听、记录、解析和关联的具体实现方法
- 提供了完整的配置项和部署说明
- 包含数据库维护策略,避免日志数据膨胀
- **风险评估与解决方案**:
- 识别了性能影响、存储膨胀、消息完整性等技术风险
- 提出了敏感信息处理和数据一致性等业务风险的解决方案
- **项目计划**:
- 制定了包括设计、开发、测试、部署在内的完整计划
- 总体开发周期预计为11个工作日
- **下一步**:
- 开始实施开发方案,首先进行后端核心功能实现
- 准备测试数据和测试用例
- 开发管理员日志查询界面
## 2024-08-06 (MQTT通信日志系统 - 后端核心功能实现)
- **配置与属性类**:
-`application.yml` 中添加了 `mqtt.logger` 相关配置包括启用开关、客户端ID前缀、订阅主题、异步线程池参数和日志保留策略。
- 创建了 `MqttLoggerProperties.java` 用于映射这些配置。
- **数据模型与Mapper**:
- 创建了 `MqttCommunicationLog.java` 实体类,对应数据库表 `mqtt_communication_log`
- 创建了 `MqttCommunicationLogMapper.java` MyBatis Plus接口。
- **核心服务层**:
- 创建了 `MqttCommunicationLogService.java` 接口,定义了异步记录上行和下行消息的方法。
- 创建了 `MqttCommunicationLogServiceImpl.java` 实现类,包含:
- `asyncLogMessage`: 异步记录完整的MQTT消息包括方向、客户端ID、主题、Payload、QoS等并进行初步的Payload格式判断TEXT/JSON
- `asyncLogDownstreamMessage`: 异步记录出站消息的简化版本。
- 使用 `@Async("mqttLoggerThreadPoolTaskExecutor")` 指定自定义线程池执行异步任务。
- **异步配置**:
- 创建了 `MqttLoggerAsyncConfigurer.java`,配置了名为 `mqttLoggerThreadPoolTaskExecutor` 的专用线程池,用于异步写入日志,避免阻塞主线程。
- **MQTT日志专用客户端**:
- 创建了 `MqttLoggerClientConfig.java`用于配置和创建专用于日志记录的MQTT客户端 (`mqttLoggerClient`)。此客户端懒加载并使用与主业务不同的客户端ID。
- 创建了 `MqttLoggerCallbackHandler.java`,作为日志客户端的回调处理器:
-`connectComplete` 中,根据配置订阅 `mqtt.logger.topics` 中指定的主题,用于监听上行消息。
-`messageArrived` 中,调用 `logService.asyncLogMessage` 记录接收到的上行消息。
- 创建了 `MqttLoggerConnectionManager.java`,负责在应用启动时连接日志客户端,并在应用关闭时断开和关闭客户端。
- **出站消息记录 (AOP)**:
- 创建了 `MqttPublishLogAspect.java` 切面,通过 `@Around` 注解拦截 `MqttServiceImpl.sendCommand` 方法。
- 在目标方法执行后,调用 `logService.asyncLogDownstreamMessage` 记录出站DOWNSTREAM消息的详情。
- 为了能关联到具体的业务任务,在 `RobotTaskService` 接口及其实现类 `RobotTaskServiceImpl` 中添加了 `findLatestTaskByRobotIdAndSessionId` 方法以便AOP切面可以根据 `robotId``sessionId` 查询关联的 `taskId`
- **管理API接口**:
- 创建了 `MqttCommunicationLogController.java`,提供了 `/api/admin/mqtt-log/list/page` 接口允许管理员分页查询MQTT通信日志。
- 创建了 `MqttLogQueryRequest.java` DTO用于封装查询条件包括消息ID、方向、客户端ID、主题、Payload内容、QoS、时间范围、关联会话ID和任务ID等。
- 控制器方法使用 `@AuthCheck(mustRole = UserConstant.ADMIN_ROLE)` 进行了权限控制。
- **问题修复**:
- 修复了 `MqttLoggerConnectionManager.java``disconnectFromMqtt` 方法内误用 `mqttLoggerClient.isOpen()`(此方法不存在)导致的编译错误。修改为直接调用 `mqttLoggerClient.close()`
- 解决了 `MqttPublishLogAspect` 中因存在两个 `MqttClient` 类型的Bean (`mqttClientBean``mqttLoggerClient`) 而导致的 `NoUniqueBeanDefinitionException` 启动错误。通过在 `MqttPublishLogAspect` 的构造函数中为 `MqttClient` 参数添加 `@Qualifier("mqttClientBean")` 注解明确指定注入主业务MQTT客户端。
- 解决了 `MqttConnectionManager` 中类似的 `NoUniqueBeanDefinitionException` 启动错误。通过在其构造函数中为 `MqttClient` 参数添加 `@Qualifier("mqttClientBean")` 注解明确指定注入主业务MQTT客户端。
- **状态**: 后端核心功能已开发完成具备了独立的MQTT客户端监听上行消息和通过AOP记录下行消息的能力并将日志异步存入数据库。同时提供了管理员查询日志的API接口。相关启动错误已修复。
- **下一步**:
- 前端日志查看与管理界面的开发。
- 对日志记录的准确性和完整性进行全面测试。
- 根据测试结果进行优化和调整。
## 2024-08-07 (MQTT通信日志系统 - 前端页面与导航)
- **页面创建与组件**:
-`charging_web_app/src/app/admin/mqtt-logs/` 目录下创建了 `page.tsx`作为MQTT通信日志的查看页面。
- 使用 Ant Design 组件 (`Card`, `Form`, `Input`, `Select`, `DatePicker`, `Button`, `Table`, `Tag`, `Tooltip`, `message`) 构建了页面结构。
- 包含一个查询表单,其字段对应后端的 `MqttLogQueryRequest`
- 包含一个数据表格,列定义对应后端的 `MqttCommunicationLog` 实体并对部分字段如日期、方向、Payload进行了格式化显示。
- 实现了基本的查询、重置、分页和客户端排序逻辑的骨架。
- **类型定义**:
- 创建了 `charging_web_app/src/types/log.types.ts` 文件,定义了前端所需的 `MqttCommunicationLog``MqttLogQueryRequest` 和通用分页响应 `PageResponse<T>` 接口。
- **API服务**:
- 创建了 `charging_web_app/src/services/axiosInstance.ts`,提供了一个基础的全局 Axios 实例配置。
- 创建了 `charging_web_app/src/services/logService.ts`,其中包含 `fetchMqttLogs`异步函数,用于调用后端 `/api/admin/mqtt-log/list/page` 接口获取日志数据。
- 解决了 `logService.ts` 中因 `axiosInstance` 相对路径导入问题导致的TypeScript编译错误改为使用 `@/services/axiosInstance` 别名路径。
- **页面逻辑集成**:
- `mqtt-logs/page.tsx` 导入了类型定义和API服务函数。
- 实现了 `useEffect` Hook 在页面加载时获取初始日志数据。
- 完善了表单提交 (`handleSearch`)、表单重置 (`handleReset`) 和表格变化 (`handleTableChange`) 的处理函数使其能够正确调用API获取和展示数据。
- 使用 Ant Design `message` 组件在API请求失败时给出用户提示。
- **导航链接添加**:
-`charging_web_app/src/app/(authenticated)/layout.tsx` 文件中,为管理员角色的用户在头部导航栏添加了一个"MQTT日志"链接,指向 `/admin/mqtt-logs` 页面。
- 使用了 Next.js 的 `Link` 组件以优化导航体验。
- **状态**: MQTT通信日志查看页面的前端基本框架已完成包括UI界面、API对接和导航入口。可以进行初步的功能测试。
- **下一步**:
- 全面测试前端页面的查询、分页、排序、重置等功能。
- 确保与后端API的交互无误数据能正确展示和更新。
- 根据测试反馈和视觉需求,进一步优化页面样式和用户交互体验。
- 考虑在Payload列增加更完善的JSON格式化显示或代码高亮功能如果需要
- 检查并确保所有代码符合项目规范和最佳实践。
## 2024-08-08 (MQTT通信日志系统 - 前端表格列本地化)
- **需求**: 将MQTT日志表格中的 `direction`, `payloadFormat`, `isRetained` 等字段值转换为中文显示,提升可读性。
- **解决方案**:
- 修改 `charging_web_app/src/app/admin/mqtt-logs/page.tsx` 文件中 `columns` 的定义。
-`direction` 列的 `render` 函数增加逻辑:`UPSTREAM` -> `上行` (蓝色标签), `DOWNSTREAM` -> `下行` (绿色标签)。
-`payloadFormat` 列的 `render` 函数增加逻辑:`TEXT` -> `文本`, `JSON` -> `JSON`
- `isRetained` 列的 `render` 函数已能正确处理布尔值到 `是`/`否` 的转换。
- **状态**: 表格相关列的显示已本地化。
- **下一步**:
- 用户验证本地化显示效果。
- 处理Ant Design Modal `destroyOnClose` 废弃警告和 React 19 兼容性警告。
## 2024-08-08 (MQTT通信日志系统 - 前端数据显示修复)
- **问题定位**:
- 前端API调用成功并获取到数据但Ant Design Table显示"No data"。
- 原因在于前端从API响应中提取数据的方式与实际的 `BaseResponse<PageResponse<T>>` 嵌套结构不匹配。
- `fetchMqttLogs` 函数返回的类型与其实际获取的数据结构存在偏差,导致在页面组件中访问 `response.data` 时类型不匹配,进而无法正确提取 `records``total`
- **解决方案**:
1. **修改 `charging_web_app/src/services/logService.ts`**:
- 添加了 `BaseResponse<T>` 接口定义以匹配后端通用响应结构。
- 更新了 `fetchMqttLogs` 函数的返回类型为 `Promise<BaseResponse<PageResponse<MqttCommunicationLog>>>`
- 更新了 `axiosInstance.post` 的泛型参数为 `BaseResponse<PageResponse<MqttCommunicationLog>>`
- 确保 `fetchMqttLogs` 返回的是从Axios响应中获取的 `response.data`,这个 `data` 实际上是后端的 `BaseResponse` 对象。
2. **修改 `charging_web_app/src/app/admin/mqtt-logs/page.tsx`**:
-`loadLogs` 函数中,当接收到 `fetchMqttLogs` 的结果 (`response`) 时,数据提取逻辑调整为从 `response.data` (即 `PageResponse` 对象) 中获取 `records``total` 等分页信息。
- 例如: `const pageData = response.data; setLogs(pageData.records);`
- **状态**: 已调整前端服务层和页面组件的数据处理逻辑,以正确解析后端返回的嵌套响应结构。预计数据能够正确显示在表格中。
- **下一步**:
- 用户验证数据是否已在前端表格中正确显示。
- 检查分页、查询、排序等功能是否均正常工作。
- 继续处理前端控制台剩余的警告。
## 2024-08-08 (MQTT通信日志系统 - 404错误修复)
- **问题定位**:
- 前端请求MQTT日志列表API (`/api/admin/mqtt-log/list/page`) 时出现 404 错误。
- 后端 `application.yml` 中配置了 `server.servlet.context-path: /api`
- 后端 `MqttCommunicationLogController``@RequestMapping` 错写为 `"/api/admin/mqtt-log"`
- 导致实际的API路径变为 `/api` (context-path) + `/api/admin/mqtt-log` (controller mapping) = `/api/api/admin/mqtt-log/list/page`
- 而前端请求路径为 `/api/admin/mqtt-log/list/page`,因此不匹配。
- **解决方案**:
- 修改 `springboot-init-main/src/main/java/com/yupi/project/controller/MqttCommunicationLogController.java`
-`@RequestMapping("/api/admin/mqtt-log")` 修改为 `@RequestMapping("/admin/mqtt-log")`
- 这样,结合 `context-path`正确的API路径为 `/api/admin/mqtt-log/list/page`,与前端请求一致。
- **状态**: 已修改后端Controller的路径预计能解决404问题。等待用户重启后端服务并验证。
- **下一步**:
- 用户验证404错误是否已解决。
- 继续处理前端控制台的其他警告(`Link` `legacyBehavior` 已处理Ant Design Modal `destroyOnClose` 和 React 19 兼容性问题)。
- 检查并确保所有代码符合项目规范和最佳实践。