# 系统配置与审计通知中心实施计划 > **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task. **Goal:** 完成系统配置(字典管理、系统参数)、审计中心(登录日志、操作日志、异常追踪)、通知中心(系统公告、消息推送WebSocket)、文件管理(上传/下载/预览)的数据库持久化与功能完善 **Architecture:** 基于Spring R2DBC响应式架构,遵循现有分层模式(Handler->Service->Repository->Entity),使用H2/PostgreSQL + Caffeine缓存,消息推送采用WebSocket **Tech Stack:** Spring WebFlux, Spring Data R2DBC, H2/PostgreSQL, Caffeine, WebSocket, Lombok --- ## 第一阶段:数据层基础设施建设 ### Task 1: 创建数据库表SQL脚本 **Files:** - Modify: `docs/sql/init.sql` (创建以下表) **Step 1: 编写SQL脚本** ```sql -- 字典类型表 CREATE TABLE IF NOT EXISTS sys_dict_type ( id BIGINT PRIMARY KEY AUTO_INCREMENT, dict_name VARCHAR(100) NOT NULL COMMENT '字典名称', dict_type VARCHAR(100) NOT NULL UNIQUE COMMENT '字典类型', status VARCHAR(1) DEFAULT '0' COMMENT '状态(0正常 1停用)', remark VARCHAR(500) COMMENT '备注', created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, deleted_at TIMESTAMP ); -- 字典数据表 CREATE TABLE IF NOT EXISTS sys_dict_data ( id BIGINT PRIMARY KEY AUTO_INCREMENT, dict_sort INT DEFAULT 0 COMMENT '字典排序', dict_label VARCHAR(100) NOT NULL COMMENT '字典标签', dict_value VARCHAR(100) NOT NULL COMMENT '字典键值', dict_type VARCHAR(100) NOT NULL COMMENT '字典类型', css_class VARCHAR(100) COMMENT '样式属性', list_class VARCHAR(100) COMMENT '表格回显样式', is_default VARCHAR(1) DEFAULT 'N' COMMENT '是否默认(Y是 N否)', status VARCHAR(1) DEFAULT '0' COMMENT '状态(0正常 1停用)', created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, deleted_at TIMESTAMP ); -- 系统配置表 CREATE TABLE IF NOT EXISTS sys_config ( id BIGINT PRIMARY KEY AUTO_INCREMENT, config_name VARCHAR(100) NOT NULL COMMENT '配置名称', config_key VARCHAR(100) NOT NULL UNIQUE COMMENT '配置键名', config_value VARCHAR(500) NOT NULL COMMENT '配置值', config_type VARCHAR(1) DEFAULT 'N' COMMENT '系统内置(Y是 N否)', created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, deleted_at TIMESTAMP ); -- 登录日志表 CREATE TABLE IF NOT EXISTS sys_login_log ( id BIGINT PRIMARY KEY AUTO_INCREMENT, username VARCHAR(50) COMMENT '用户名', ip VARCHAR(50) COMMENT 'IP地址', location VARCHAR(255) COMMENT '登录位置', browser VARCHAR(50) COMMENT '浏览器类型', os VARCHAR(50) COMMENT '操作系统', status VARCHAR(1) COMMENT '登录状态(0成功 1失败)', message VARCHAR(255) COMMENT '提示消息', login_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); -- 异常日志表 CREATE TABLE IF NOT EXISTS sys_exception_log ( id BIGINT PRIMARY KEY AUTO_INCREMENT, username VARCHAR(50) COMMENT '用户名', title VARCHAR(100) COMMENT '异常标题', exception_name VARCHAR(100) COMMENT '异常名称', method_name VARCHAR(100) COMMENT '方法名称', method_params TEXT COMMENT '方法参数', exception_msg TEXT COMMENT '异常信息', exception_stack TEXT COMMENT '堆栈信息', ip VARCHAR(50) COMMENT 'IP地址', create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); -- 系统公告表 CREATE TABLE IF NOT EXISTS sys_notice ( id BIGINT PRIMARY KEY AUTO_INCREMENT, notice_title VARCHAR(100) NOT NULL COMMENT '公告标题', notice_type VARCHAR(1) DEFAULT '1' COMMENT '公告类型(1通知 2公告)', notice_content TEXT COMMENT '公告内容', status VARCHAR(1) DEFAULT '0' COMMENT '公告状态(0正常 1关闭)', created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, deleted_at TIMESTAMP ); -- 文件管理表 CREATE TABLE IF NOT EXISTS sys_file ( id BIGINT PRIMARY KEY AUTO_INCREMENT, file_name VARCHAR(255) NOT NULL COMMENT '文件名', file_path VARCHAR(500) NOT NULL COMMENT '文件路径', file_size VARCHAR(50) COMMENT '文件大小', file_type VARCHAR(50) COMMENT '文件类型', storage_type VARCHAR(20) DEFAULT 'local' COMMENT '存储类型(local/oss/s3)', create_by VARCHAR(50) COMMENT '创建者', created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, deleted_at TIMESTAMP ); -- 用户消息表(消息推送用) CREATE TABLE IF NOT EXISTS sys_user_message ( id BIGINT PRIMARY KEY AUTO_INCREMENT, user_id BIGINT NOT NULL COMMENT '接收用户ID', title VARCHAR(100) COMMENT '消息标题', content TEXT COMMENT '消息内容', message_type VARCHAR(1) DEFAULT '1' COMMENT '消息类型(1系统 2通知)', is_read VARCHAR(1) DEFAULT '0' COMMENT '是否已读(0未读 1已读)', create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); ``` **Step 2: 提交SQL脚本** ```bash git add docs/sql/init.sql git commit -m "feat: 添加系统配置和审计模块数据库表脚本" ``` --- ### Task 2: 创建字典类型Entity **Files:** - Create: `novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/entity/SysDictTypeEntity.java` - Modify: `novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/entity/BaseEntity.java` **Step 1: 在BaseEntity添加公共字段** 查看现有BaseEntity确保包含: - id, createdAt, updatedAt, deletedAt **Step 2: 创建SysDictTypeEntity** ```java package cn.novalon.manage.sys.infrastructure.db.entity; import org.springframework.data.annotation.Id; import org.springframework.data.relational.core.mapping.Column; import org.springframework.data.relational.core.mapping.Table; @Table("sys_dict_type") public class SysDictTypeEntity { @Id private Long id; @Column("dict_name") private String dictName; @Column("dict_type") private String dictType; @Column("status") private String status; @Column("remark") private String remark; @Column("created_at") private LocalDateTime createdAt; @Column("updated_at") private LocalDateTime updatedAt; @Column("deleted_at") private LocalDateTime deletedAt; // Getters and Setters } ``` **Step 3: 提交** ```bash git add entity/SysDictTypeEntity.java git commit -m "feat: 添加字典类型Entity" ``` --- ### Task 3: 创建其他Entity(字典数据、系统配置、登录日志、异常日志、公告、文件、消息) **Files:** - Create: `infrastructure/db/entity/SysDictDataEntity.java` - Create: `infrastructure/db/entity/SysConfigEntity.java` - Create: `infrastructure/db/entity/SysLoginLogEntity.java` - Create: `infrastructure/db/entity/SysExceptionLogEntity.java` - Create: `infrastructure/db/entity/SysNoticeEntity.java` - Create: `infrastructure/db/entity/SysFileEntity.java` - Create: `infrastructure/db/entity/SysUserMessageEntity.java` **每Entity结构:** 继承BaseEntity,添加对应字段的@Column注解和getter/setter **示例 - SysConfigEntity:** ```java @Table("sys_config") public class SysConfigEntity { @Id private Long id; @Column("config_name") private String configName; @Column("config_key") private String configKey; @Column("config_value") private String configValue; @Column("config_type") private String configType; @Column("created_at") private LocalDateTime createdAt; @Column("updated_at") private LocalDateTime updatedAt; @Column("deleted_at") private LocalDateTime deletedAt; // Getters and Setters } ``` --- ### Task 4: 创建Repository接口 **Files:** - Create: `infrastructure/db/repository/SysDictTypeRepository.java` - Create: `infrastructure/db/repository/SysDictDataRepository.java` - Create: `infrastructure/db/repository/SysConfigRepository.java` - Create: `infrastructure/db/repository/SysLoginLogRepository.java` - Create: `infrastructure/db/repository/SysExceptionLogRepository.java` - Create: `infrastructure/db/repository/SysNoticeRepository.java` - Create: `infrastructure/db/repository/SysFileRepository.java` - Create: `infrastructure/db/repository/SysUserMessageRepository.java` **每Repository:** 继承 ReactiveCrudRepository **示例:** ```java package cn.novalon.manage.sys.infrastructure.db.repository; import cn.novalon.manage.sys.infrastructure.db.entity.SysDictTypeEntity; import org.springframework.data.repository.reactive.ReactiveCrudRepository; import org.springframework.stereotype.Repository; @Repository public interface SysDictTypeRepository extends ReactiveCrudRepository { } ``` --- ## 第二阶段:领域层(Domain + Converter) ### Task 5: 更新Domain模型 **Files:** - Modify: `core/domain/SysDictType.java` - 添加dictDataList字段 - Modify: `core/domain/SysDictData.java` - 确保字段完整 - Modify: `core/domain/SysConfig.java` - 确保字段完整 - Modify: `core/domain/SysLoginLog.java` - 确保字段完整 - Create: `core/domain/SysExceptionLog.java` - Create: `core/domain/SysUserMessage.java` --- ### Task 6: 创建Converter转换器 **Files:** - Create: `infrastructure/db/converter/SysDictTypeConverter.java` - Create: `infrastructure/db/converter/SysDictDataConverter.java` - Create: `infrastructure/db/converter/SysConfigConverter.java` - Create: `infrastructure/db/converter/SysLoginLogConverter.java` - Create: `infrastructure/db/converter/SysExceptionLogConverter.java` - Create: `infrastructure/db/converter/SysNoticeConverter.java` - Create: `infrastructure/db/converter/SysFileConverter.java` --- ## 第三阶段:服务层(Service) ### Task 7: 创建Service接口和实现 **Files:** - Create: `core/service/ISysDictTypeService.java` + `impl/SysDictTypeServiceImpl.java` - Create: `core/service/ISysDictDataService.java` + `impl/SysDictDataServiceImpl.java` - Create: `core/service/ISysConfigService.java` + `impl/SysConfigServiceImpl.java` - Create: `core/service/ISysLoginLogService.java` + `impl/SysLoginLogServiceImpl.java` - Create: `core/service/ISysExceptionLogService.java` + `impl/SysExceptionLogServiceImpl.java` - Create: `core/service/ISysNoticeService.java` + `impl/SysNoticeServiceImpl.java` - Create: `core/service/ISysFileService.java` + `impl/SysFileServiceImpl.java` - Create: `core/service/ISysUserMessageService.java` + `impl/SysUserMessageServiceImpl.java` **核心方法:** - CRUD操作 - 字典: 根据类型查询数据列表 - 配置: 根据key查询value - 日志: 分页查询、按条件筛选 - 消息: 查询用户未读消息 --- ## 第四阶段:Handler层(API接口) ### Task 8: 重构Handler接入数据库 **Files:** - Modify: `handler/sys/SysDictHandler.java` - 注入Service替换内存Map - Modify: `handler/sys/SysConfigHandler.java` - 注入Service替换内存Map - Modify: `handler/sys/SysLogHandler.java` - 添加登录日志和异常日志查询 - Modify: `handler/sys/SysNoticeHandler.java` - 注入Service替换内存Map - Modify: `handler/sys/SysFileHandler.java` - 完善文件预览功能 --- ## 第五阶段:消息推送(WebSocket) ### Task 9: WebSocket配置 **Files:** - Create: `config/WebSocketConfig.java` - Create: `handler/websocket/WebSocketHandler.java` - Create: `service/impl/WebSocketService.java` ```java @Configuration @EnableWebSocket public class WebSocketConfig implements WebSocketConfigurer { @Override public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) { registry.addHandler(webSocketHandler(), "/ws") .setAllowedOrigins("*"); } @Bean public WebSocketHandler webSocketHandler() { return new WebSocketHandler(); } } ``` --- ### Task 10: 消息推送Service **Files:** - Create: `core/service/IWebSocketService.java` - Create: `core/service/impl/WebSocketServiceImpl.java` **功能:** - 发送消息给指定用户 - 发送消息给所有在线用户 - 用户上线/下线跟踪 --- ## 第六阶段:完善文件预览 ### Task 11: 文件预览支持 **Files:** - Modify: `handler/sys/SysFileHandler.java` - 添加预览接口 - 创建DTO: `dto/response/FilePreviewResponse.java` **预览支持:** - 图片: 返回Base64或直接流 - PDF: 返回PDF流 - 文本: 返回文本内容 --- ## 第七阶段:异常日志自动记录 ### Task 12: 全局异常处理器 **Files:** - Create: `handler/GlobalExceptionHandler.java` - Create: `config/GlobalExceptionHandlerConfig.java` **功能:** - 捕获所有Controller异常 - 自动记录到sys_exception_log表 - 返回统一格式的错误响应 --- ## 第八阶段:测试 ### Task 13: 单元测试 **Files:** - Create: `test/service/SysDictTypeServiceTest.java` - Create: `test/service/SysConfigServiceTest.java` - Create: `test/service/SysLoginLogServiceTest.java` - Create: `test/handler/SysDictHandlerTest.java` - Create: `test/handler/SysNoticeHandlerTest.java` **测试覆盖:** - Service层CRUD操作 - Handler层API响应 - 异常场景处理 --- ## 实施顺序 1. Task 1: SQL脚本 2. Task 2-4: Entity + Repository 3. Task 5-6: Domain + Converter 4. Task 7: Service层 5. Task 8: Handler层重构 6. Task 9-10: WebSocket消息推送 7. Task 11: 文件预览 8. Task 12: 异常日志 9. Task 13: 测试