feat: Iteration 1 — 审计日志IP记录、文件上传、医护端API、小程序角色切换
Iteration 1 六项任务全部完成: 1. 审计日志IP记录 — task_local RequestInfo 自动注入 IP/user_agent 2. 文件上传服务 — multipart 上传 + ServeDir 静态文件服务 3. 医护端后端API — 医生工作台仪表盘 + 患者标签CRUD + 会话已读 4. 小程序角色切换 — 登录后根据角色跳转医护台/患者首页 5. 小程序安全加固 — secure-storage 开发模式警告 6. 讨论记录归档 — docs/discussions/
This commit is contained in:
@@ -3,6 +3,8 @@ use axum::http::Request;
|
||||
use axum::middleware::Next;
|
||||
use axum::response::Response;
|
||||
use erp_core::error::AppError;
|
||||
use erp_core::request_info::REQUEST_INFO;
|
||||
use erp_core::request_info::RequestInfo;
|
||||
use erp_core::types::TenantContext;
|
||||
|
||||
use crate::service::token_service::TokenService;
|
||||
@@ -13,6 +15,9 @@ use crate::service::token_service::TokenService;
|
||||
/// using `TokenService::decode_token`, and injects a `TenantContext` into the
|
||||
/// request extensions so downstream handlers can access tenant/user identity.
|
||||
///
|
||||
/// 同时提取请求的 IP 地址和 User-Agent,通过 task_local 传递给审计服务,
|
||||
/// 使所有审计日志自动记录来源信息。
|
||||
///
|
||||
/// The `jwt_secret` parameter is passed explicitly by the server crate at
|
||||
/// middleware construction time, avoiding any circular dependency between
|
||||
/// erp-auth and erp-server.
|
||||
@@ -58,6 +63,9 @@ pub async fn jwt_auth_middleware_fn(
|
||||
None => vec![],
|
||||
};
|
||||
|
||||
// 提取请求来源信息(IP + User-Agent),用于审计日志
|
||||
let request_info = RequestInfo::from_headers(req.headers());
|
||||
|
||||
let ctx = TenantContext {
|
||||
tenant_id: claims.tid,
|
||||
user_id: claims.sub,
|
||||
@@ -72,7 +80,8 @@ pub async fn jwt_auth_middleware_fn(
|
||||
let mut req = Request::from_parts(parts, body);
|
||||
req.extensions_mut().insert(ctx);
|
||||
|
||||
Ok(next.run(req).await)
|
||||
// 在 task_local scope 中运行后续处理,审计服务可自动读取请求信息
|
||||
Ok(REQUEST_INFO.scope(request_info, next.run(req)).await)
|
||||
}
|
||||
|
||||
/// 查询用户所属的所有部门 ID(通过 user_departments 关联表)
|
||||
|
||||
Reference in New Issue
Block a user