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:
@@ -11,7 +11,9 @@ pub struct AppConfig {
|
||||
pub cors: CorsConfig,
|
||||
pub wechat: WechatConfig,
|
||||
pub health: HealthConfig,
|
||||
pub crypto: CryptoConfig,
|
||||
pub ai: AiConfig,
|
||||
pub storage: StorageConfig,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Deserialize)]
|
||||
@@ -70,6 +72,13 @@ pub struct HealthConfig {
|
||||
pub hmac_key: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Deserialize)]
|
||||
pub struct CryptoConfig {
|
||||
/// Master KEK (64 字符 hex 编码,32 字节)。用于加密保护每租户 DEK。
|
||||
/// Phase A 阶段同时作为全局数据加密密钥使用。
|
||||
pub kek: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Deserialize)]
|
||||
pub struct AiConfig {
|
||||
pub default_provider: String,
|
||||
@@ -82,6 +91,30 @@ pub struct AiConfig {
|
||||
pub rate_limit_patient_daily: u32,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Deserialize)]
|
||||
pub struct StorageConfig {
|
||||
/// 文件上传目录(本地存储)
|
||||
pub upload_dir: String,
|
||||
/// 单文件最大大小(如 "10MB")
|
||||
pub max_file_size: String,
|
||||
}
|
||||
|
||||
impl StorageConfig {
|
||||
/// 解析 max_file_size 为字节数
|
||||
pub fn max_file_size_bytes(&self) -> u64 {
|
||||
let s = self.max_file_size.to_uppercase();
|
||||
if let Some(num) = s.strip_suffix("MB") {
|
||||
num.trim().parse::<u64>().unwrap_or(10) * 1024 * 1024
|
||||
} else if let Some(num) = s.strip_suffix("KB") {
|
||||
num.trim().parse::<u64>().unwrap_or(1024) * 1024
|
||||
} else if let Some(num) = s.strip_suffix("GB") {
|
||||
num.trim().parse::<u64>().unwrap_or(1) * 1024 * 1024 * 1024
|
||||
} else {
|
||||
s.parse::<u64>().unwrap_or(10 * 1024 * 1024)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl AppConfig {
|
||||
pub fn load() -> anyhow::Result<Self> {
|
||||
let config = config::Config::builder()
|
||||
|
||||
Reference in New Issue
Block a user