5.1 KiB
ADDED Requirements
Requirement: API 请求全量采集
系统 SHALL 通过 ApiRequestLogMiddleware 记录经 FastAPI 处理的 API 请求,并写入 sys_api_request_log。每条记录 SHALL 包含 HTTP 方法、路径(接口地址)、Query 字符串、请求体、响应体、HTTP 状态码、耗时、IP、User-Agent、请求时间(create_at)、用户 ID、用户账号(user_no)及用户姓名(nick_name → create_name)。
Scenario: 记录业务 API 入参与出参
- WHEN 已认证用户调用 JSON 业务接口(如
POST /api/web/crm/customer/update) - THEN 系统持久化
path、query_string、request_body、response_body - AND
create_at为请求完成时刻 - AND
create_name为 JWT 中的real_name
Scenario: 敏感字段脱敏
- WHEN 请求或响应 JSON 包含
password、token、authorization等敏感键 - THEN 落库值 SHALL 为
***而非明文
Scenario: 跳过高噪与健康检查路径
- WHEN 请求为
OPTIONS或路径为/health、/docs、/openapi.json - THEN 系统 SHALL 不写入
sys_api_request_log
Scenario: 文件上传不记录文件体
- WHEN 请求 Content-Type 为
multipart/form-data - THEN
request_bodySHALL 标记为省略说明而非文件二进制内容
Requirement: 业务语义字段落库
系统 SHALL 在 sys_api_request_log 存储业务语义列:tenant_no、business_title、business_type、business_id、oper_summary。写操作接口 SHOULD 通过 @oper_log 声明上述字段;未声明时系统 SHALL 使用路径与方法推断规则填充 business_title 与 business_type(business_id 与 oper_summary 可为空)。
Scenario: 装饰器声明修改客户
- WHEN 带
@oper_log(title="CRM客户管理", business_type=2, business_id_param="id", summary="修改客户【{name}】")的更新接口被调用且 ContextVar 已设置 - THEN 落库
business_title=CRM客户管理、business_type=2 - AND
business_id为请求中的客户 id - AND
oper_summary为可读摘要文本
Scenario: 只读列表无装饰器
- WHEN 用户调用客户列表 GET 接口且路由无
@oper_log - THEN 系统仍记录 path 与入参出参
- AND
business_title由路径推断(如CRM客户管理) - AND
business_type为0(其他)
Scenario: business_type 枚举
- WHEN 系统写入
business_type - THEN 值 SHALL 属于:0其他、1新增、2修改、3删除、5导出、6导入(与
sys_oper_type字典一致)
Requirement: 租户隔离
操作日志查询 SHALL 按当前用户 tenant_no 过滤 sys_api_request_log.tenant_no。中间件落库时 SHALL 从 JWT 写入 tenant_no。
Scenario: 租户数据不可见
- WHEN 租户 A 的管理员查询操作日志
- THEN 结果 SHALL 不包含租户 B 的记录
Requirement: 操作日志查询 API
系统 SHALL 提供 POST /api/web/monitor/operlog/list 与 POST /api/web/monitor/operlog/detail,将日志适配为 RuoYi OperLogVO 结构:operUrl(path)、operParam(request_body)、jsonResult(response_body)、operName(create_name 优先)、operTime、title(business_title)、businessType。
Scenario: 列表筛选业务实体
- WHEN 请求体包含
businessId与可选businessTitle - THEN 返回匹配
business_id的日志分页列表
Scenario: 详情含完整入参出参
- WHEN 管理员请求某条日志详情
- THEN 响应 SHALL 包含完整
operParam与jsonResult(受库内截断上限约束)
Scenario: 数据权限
- WHEN 非 super_admin 用户查询列表
- THEN 结果 SHALL 受数据权限约束(按操作人
user_id范围)
Scenario: 访问控制
- WHEN 非 admin/super_admin 用户调用 operlog API
- THEN 系统 SHALL 拒绝访问
Requirement: 操作日志管理页
web-admin SHALL 提供操作日志标准列表页(界面模式 P01),支持按模块、操作类型、操作人、状态、时间范围筛选;详情展示接口地址、入参、出参与摘要。按钮与表格 SHALL 符合 Fresh Mint 与 web-admin-crud-dialog 规范。
Scenario: 管理员查看日志列表
- WHEN 已授权的 admin 用户打开操作日志页
- THEN 展示分页列表,列含模块、类型、操作人、时间、摘要、状态
- AND 可打开详情查看
operParam与jsonResult
Requirement: CRM 业务详情操作日志 Tab
CRM 客户详情与合同详情中的操作日志 Tab SHALL 按 business_id 调用 operlog 列表,不再拉取全量日志后前端过滤。
Scenario: 客户详情日志
- WHEN 用户在某客户详情打开「操作日志」Tab
- THEN 仅展示
business_id等于该客户 id 的日志
Requirement: 配置与生产开关
API_REQUEST_LOG_ENABLED 在生产环境 SHALL 为 true。body 截断上限 SHALL 保持可配置(API_REQUEST_LOG_MAX_BODY、API_REQUEST_LOG_MAX_BODY_BYTES)。
Scenario: 关闭采集
- WHEN
API_REQUEST_LOG_ENABLED=false - THEN 中间件 SHALL 不写入数据库