status: applied created: 2026-07-07 complexity: 🟡中等
当前操作日志只记录基础接口请求信息,缺少页面维度、操作人真实姓名、操作内容摘要、前后数据快照/差异展示和导出配置。需要在复用现有 sys_operation_log 与 @OperationLog 的基础上增强页面审计能力,并把 /system/operation-log 页面改造成更适合审计筛选和详情核查的视觉体验。
完成后可验证结果:
/system/operation-log 支持按账号、操作人、页面、类型、状态、IP、URL、内容、时间筛选,支持导出。forge-admin-ui/src/utils/http/interceptors.js:reqResolve 是前端统一请求拦截器,当前已写入 traceId、Authorization、防重放头,但未写入当前页面路径/标题。forge-server/forge-framework/forge-starter-parent/forge-starter-log/src/main/java/com/mdframe/forge/starter/log/aspect/OperationLogAspect.java:around 拦截 Controller 请求,构造 OperationLogInfo 并异步保存。forge-server/forge-framework/forge-plugin-parent/forge-plugin-system/src/main/java/com/mdframe/forge/plugin/system/service/impl/SystemLogServiceImpl.java:saveOperationLog 将 OperationLogInfo 转为 SysOperationLog 入库。forge-admin-ui/src/views/system/operation-log.vue 是现有操作日志页面,使用 AiCrudPage 和自定义详情弹窗。sys_operation_log 已有字段:tenant_id, user_id, username, operation_module, operation_type, operation_desc, request_method, request_url, request_params, response_result, error_msg, operation_status, operation_ip, operation_location, user_agent, execute_time, operation_time。SysOperationLogController.page 当前直接使用 LambdaQueryWrapper 写查询条件,不符合 AGENTS.md 第 5.1 条“查询 SQL 必须写 XML”。GenericExportController + DynamicExportEngine 提供,导出配置来自 sys_excel_export_config 和 sys_excel_column_config。AiCrudPage 已支持 showExport 和 apiConfig.export,可复用 POST /api/excel/export/{configKey}。@OperationLog,当前切面会根据 API 配置兜底。页面维度应在切面统一补齐,不要求逐个 Controller 改造。sys_operation_type 历史字典可能存在 INSERT 而非 ADD,本次迁移补齐 ADD,避免新增操作标签不显示。spec.md、tasks.md、test-spec.md、execution-log.md。sys_operation_log 增加页面、操作人、操作内容、前后快照和差异字段。X-Page-Path、X-Page-Title。OperationLogAspect 读取页面头,填充审计字段,并提供默认操作内容/快照兜底。SysOperationLogService、Query DTO 和 Mapper XML 查询,支持导出列表。/system/operation-log 列表字段、筛选项、详情弹窗和导出入口。INSERT 与现行 ADD 新增类型,避免页面“操作类型”下拉展示两个“新增”。username,操作人使用 operator_name,从 sys_user.real_name 补齐;为空时回退用户名。operation_page 和页面标题 operation_page_title。@OperationLog.desc,无注解时使用 API 配置名称;再拼接请求方法和 URL 形成可读摘要。ADD、UPDATE、DELETE、IMPORT、EXPORT、OTHER,以及未显式标注但 HTTP 方法为 POST、PUT、PATCH、DELETE 的接口。OperationType.QUERY、API 配置识别为 QUERY、未显式标注且 HTTP 方法为 GET、HEAD、OPTIONS 的接口直接放行;/page、/list、/tree、/detail、/getById、/options、/profile、/query 等 POST 查询兼容接口也按查询放行。before_data、after_data、diff_data 支持审计上下文主动写入;未主动写入时:
[DECRYPTED_REQUEST_BODY_OMITTED] 时,不允许把该占位符写入 after_data;需要精确快照的业务接口通过 OperationAuditContext 主动写入脱敏后的前后数据。OperationType.ADD 的 ADD 作为新增操作标准值;历史 INSERT 日志和字典值迁移归一到 ADD。页面展示时将 INSERT 兼容映射为 ADD,筛选 ADD 时兼容查询迁移前的 INSERT 数据。| 操作 | 表名 | 字段/索引 | 说明 |
|---|---|---|---|
| 修改 | sys_operation_log |
operator_name |
操作人真实姓名 |
| 修改 | sys_operation_log |
operation_page, operation_page_title |
页面路径和页面标题 |
| 修改 | sys_operation_log |
operation_content |
操作内容摘要 |
| 修改 | sys_operation_log |
before_data, after_data, diff_data |
前后快照与差异 |
| 修改 | sys_operation_log |
idx_operation_page_time, idx_operator_name |
查询优化 |
| 新增/补齐 | sys_dict_data |
sys_operation_type=ADD |
兼容 OperationType.ADD |
| 修改 | sys_operation_log, sys_dict_data |
INSERT → ADD |
统一新增操作类型,避免 INSERT/ADD 同时显示为两个“新增” |
| 新增 | sys_excel_export_config, sys_excel_column_config |
sys_operation_log_export |
操作日志导出配置 |
| 修改 | sys_resource |
操作日志菜单名称/权限 | 菜单展示为页面操作审计日志并补导出权限 |
| 操作 | 接口 | 方法 | 变更内容 |
|---|---|---|---|
| 修改 | /system/operationLog/page |
GET | 增加页面、操作人、操作内容筛选,后端改为 XML 查询 |
| 修改 | /system/operationLog/{id} |
GET | 返回新增审计字段 |
| 复用 | /api/excel/export/sys_operation_log_export |
POST | 导出筛选后的操作日志 |
forge-starter-log、forge-plugin-system、Flyway 迁移脚本。/system/operation-log 页面。sys_operation_log 增加字段;历史数据字段为空,不影响既有查询。@ApiDecrypt 请求体省略逻辑;本次继续沿用截断和脱敏边界,避免扩大敏感数据暴露面。sys_operation_log,不新建 page_audit_log 表,避免日志链路分叉。SysOperationLogMapper.xml,修正当前 Controller 内查询问题。traceId,不异步保存日志。| Task | 状态 | 实际改动文件 | 备注 |
|---|---|---|---|
| SDD 文档 | 已完成 | spec.md, tasks.md, test-spec.md, execution-log.md |
本轮创建 |
| Task 1 | 已完成 | V1.0.14__enhance_operation_log_page_audit.sql |
新增审计字段、索引、字典、导出配置和资源权限 |
| Task 2 | 已完成 | OperationAuditContext.java, OperationLogInfo.java, OperationLogAspect.java |
统一采集页面头、操作内容和审计快照 |
| Task 3 | 已完成 | SysOperationLogQuery.java, ISysOperationLogService.java, SysOperationLogServiceImpl.java, SysOperationLogMapper.java, SysOperationLogMapper.xml, SysOperationLogController.java |
查询迁移到 XML SQL 并支持导出 |
| Task 4 | 已完成 | interceptors.js |
所有请求自动携带页面路径和页面标题 |
| Task 5 | 已完成 | operation-log.vue |
审计列表、筛选、导出和详情弹窗视觉优化 |
| Task 6 | 已完成 | test-spec.md, execution-log.md |
后端编译、前端构建和静态校验通过 |
| 增量修正 | 已完成 | OperationLogAspect.java, spec.md, tasks.md, test-spec.md, execution-log.md |
查询类操作不再落库,只记录变更类操作 |
| 增量修正 | 已完成 | interceptors.js, OperationLogAspect.java, SysUserController.java, spec.md, tasks.md, test-spec.md, execution-log.md |
修正页面标题/模块兜底和用户管理快照,避免加密体占位符进入数据快照 |
| 增量修正 | 已完成 | operation-log.vue, SysOperationLogMapper.xml, V1.0.15__normalize_operation_type_add_dict.sql, spec.md, tasks.md, test-spec.md, execution-log.md |
修复操作类型两个“新增”,统一 INSERT 与 ADD |
已完成实现与验证。git diff --check 通过;Flyway 占位符扫描无 ${...};SysOperationLogMapper.xml 通过 xmllint --noout;forge-admin-server 依赖编译通过;pnpm --dir forge-admin-ui build 通过。前端构建中存在既有动态导入、CSS // 注释和 chunk size 类 warning,未阻断本次变更。未启动后端和真实数据库做页面联调,原因是本轮以代码实现、迁移脚本和构建验证为主,未引入本地服务启动。
2026-07-08 增量修正:按用户确认调整为只记录变更类操作。OperationType.QUERY 和只读 HTTP 方法默认不落库;ADD/UPDATE/DELETE/IMPORT/EXPORT/OTHER 继续记录。git diff --check 和 mvn -q -pl forge-admin-server -am compile -DskipTests 已通过。
2026-07-08 Flyway 修复:sys_dict_data 补齐 ADD 字典的派生表漏写 dict_label 别名,导致 Unknown column 'seed.dict_label' in 'field list'。已补为 '新增' dict_label,并通过 git diff --check 与静态别名检查。
2026-07-08 页面审计展示修复:请求头页面标题改为优先从菜单/页签解析,避免只写入基础系统名;后端模块为空时使用有效页面标题兜底;加密请求体占位符不再作为 after_data;用户管理主操作补充脱敏前后快照与 diff。git diff --check、mvn -q -pl forge-admin-server -am compile -DskipTests、pnpm --dir forge-admin-ui build 已通过。
2026-07-08 操作类型去重修复:旧基线字典存在 INSERT=新增,本变更补齐 ADD=新增 后页面会出现两个“新增”。已在前端将 INSERT 归一展示为 ADD,在 Mapper XML 中让 operationType=ADD 兼容历史 INSERT,并新增 V1.0.15__normalize_operation_type_add_dict.sql 迁移历史日志和字典。迁移脚本避开 sys_dict_data 的 (tenant_id, dict_type, dict_value) 唯一键冲突:有 ADD 时禁用 INSERT,无 ADD 时才将 INSERT 改为 ADD。git diff --check、Flyway 占位符扫描、xmllint --noout、mvn -q -pl forge-admin-server -am compile -DskipTests、pnpm --dir forge-admin-ui build 已通过;未启动 MySQL 实跑 Flyway。