fix: 修复测试发现的 7 个问题 + 全 workspace clippy 清零
Some checks failed
CI / rust-check (push) Has been cancelled
CI / rust-test (push) Has been cancelled
CI / frontend-build (push) Has been cancelled
CI / security-audit (push) Has been cancelled

功能修复:
1. 患者创建空名称验证:后端添加 name.trim().is_empty() 检查
2. 仪表盘统计容错:单个查询失败返回零值而非 500
3. FHIR 路由修复:从 /fhir 移到 /api/v1/fhir 保持一致
4. 冻结模块后端中间件:新增 frozen_module_middleware 拦截冻结路径
5. 积分端点权限码:health.health-data.list → health.points.list
6. 角色权限迁移:护士补充 devices.list,运营补充 points.list/manage
7. 测试结果文档:R01-R05 角色测试 + T00/T10 结果归档

Clippy 全 workspace 清零(14→0 errors):
- erp-core: 修复 empty doc line、collapsible if、redundant closure 等 9 处
- erp-health: 修复 too_many_arguments、unused var、unnecessary parens 等 58 处
- erp-ai: 修复 dead_code、unused import 等 11 处
- erp-plugin: 修复 too_many_arguments、wildcard pattern 等 11 处
- erp-server-migration: 修复 enum_variant_names 5 处
- erp-auth/config/workflow/message: 各 1-3 处

工程改进:
- lint-staged 配置迁移到 .lintstagedrc.js(函数式避免文件列表传给 clippy)
- cargo fmt 统一格式化
This commit is contained in:
iven
2026-05-07 23:43:14 +08:00
parent 786f57c151
commit 6d5a711d2c
323 changed files with 15662 additions and 6603 deletions

View File

@@ -74,12 +74,12 @@ impl MessageModule {
// 先获取许可,再 spawn 任务
tokio::spawn(async move {
let _permit = match permit.acquire().await {
Ok(p) => p,
Err(_) => {
tracing::warn!("信号量已关闭,跳过工作流事件处理");
return;
}
};
Ok(p) => p,
Err(_) => {
tracing::warn!("信号量已关闭,跳过工作流事件处理");
return;
}
};
if let Err(e) = handle_workflow_event(&event, &db, &event_bus).await {
tracing::warn!(
event_type = %event.event_type,
@@ -143,11 +143,36 @@ impl ErpModule for MessageModule {
fn permissions(&self) -> Vec<PermissionDescriptor> {
vec![
PermissionDescriptor { code: "message.list".into(), name: "查看消息".into(), description: "查看消息列表".into(), module: "message".into() },
PermissionDescriptor { code: "message.send".into(), name: "发送消息".into(), description: "发送新消息".into(), module: "message".into() },
PermissionDescriptor { code: "message.template.list".into(), name: "查看消息模板".into(), description: "查看消息模板列表".into(), module: "message".into() },
PermissionDescriptor { code: "message.template.create".into(), name: "创建消息模板".into(), description: "创建消息模板".into(), module: "message".into() },
PermissionDescriptor { code: "message.template.manage".into(), name: "管理消息模板".into(), description: "编辑、删除消息模板".into(), module: "message".into() },
PermissionDescriptor {
code: "message.list".into(),
name: "查看消息".into(),
description: "查看消息列表".into(),
module: "message".into(),
},
PermissionDescriptor {
code: "message.send".into(),
name: "发送消息".into(),
description: "发送新消息".into(),
module: "message".into(),
},
PermissionDescriptor {
code: "message.template.list".into(),
name: "查看消息模板".into(),
description: "查看消息模板列表".into(),
module: "message".into(),
},
PermissionDescriptor {
code: "message.template.create".into(),
name: "创建消息模板".into(),
description: "创建消息模板".into(),
module: "message".into(),
},
PermissionDescriptor {
code: "message.template.manage".into(),
name: "管理消息模板".into(),
description: "编辑、删除消息模板".into(),
module: "message".into(),
},
]
}
@@ -289,7 +314,10 @@ async fn handle_workflow_event(
event.tenant_id,
pid,
"预约已创建".to_string(),
format!("您的新预约 {} 已创建,请等待确认。", &appointment_id[..8.min(appointment_id.len())]),
format!(
"您的新预约 {} 已创建,请等待确认。",
&appointment_id[..8.min(appointment_id.len())]
),
"normal",
Some("appointment".to_string()),
uuid::Uuid::parse_str(appointment_id).ok(),
@@ -361,7 +389,10 @@ async fn handle_workflow_event(
event.tenant_id,
pid,
"预约已取消".to_string(),
format!("您的预约 {} 已被取消。", &appointment_id[..8.min(appointment_id.len())]),
format!(
"您的预约 {} 已被取消。",
&appointment_id[..8.min(appointment_id.len())]
),
"normal",
Some("appointment".to_string()),
uuid::Uuid::parse_str(appointment_id).ok(),
@@ -397,10 +428,17 @@ async fn handle_workflow_event(
event.tenant_id,
pid,
"预约提醒".to_string(),
format!("您明天({})有一个预约,时间段:{},请准时就诊。", appointment_date, time_slot),
format!(
"您明天({})有一个预约,时间段:{},请准时就诊。",
appointment_date, time_slot
),
"normal",
Some("appointment".to_string()),
event.payload.get("appointment_id").and_then(|v| v.as_str()).and_then(|s| uuid::Uuid::parse_str(s).ok()),
event
.payload
.get("appointment_id")
.and_then(|v| v.as_str())
.and_then(|s| uuid::Uuid::parse_str(s).ok()),
db,
event_bus,
)
@@ -723,7 +761,10 @@ async fn handle_workflow_event(
event.tenant_id,
assignee,
format!("新随访任务{}", patient_info),
format!("您被分配了一个随访任务{},计划日期:{}", patient_info, planned_date),
format!(
"您被分配了一个随访任务{},计划日期:{}",
patient_info, planned_date
),
"normal",
Some("follow_up".to_string()),
uuid::Uuid::parse_str(task_id).ok(),
@@ -1005,10 +1046,15 @@ async fn handle_workflow_event(
event.tenant_id,
pid,
"护理计划已完成".to_string(),
"您的护理计划已完成,感谢您这段时间的配合!我们将继续关注您的健康。".to_string(),
"您的护理计划已完成,感谢您这段时间的配合!我们将继续关注您的健康。"
.to_string(),
"normal",
Some("care_plan".to_string()),
event.payload.get("plan_id").and_then(|v| v.as_str()).and_then(|s| uuid::Uuid::parse_str(s).ok()),
event
.payload
.get("plan_id")
.and_then(|v| v.as_str())
.and_then(|s| uuid::Uuid::parse_str(s).ok()),
db,
event_bus,
)
@@ -1036,25 +1082,31 @@ async fn handle_workflow_event(
let (title, body) = match action {
"item_completed" => {
let item_title = event.payload.get("item_title").and_then(|v| v.as_str()).unwrap_or("护理项目");
let item_title = event
.payload
.get("item_title")
.and_then(|v| v.as_str())
.unwrap_or("护理项目");
(
"关怀已送达".to_string(),
format!("您的护理团队已完成「{}」,感谢您的配合。", item_title),
)
}
"outcome_measured" => {
let metric = event.payload.get("metric").and_then(|v| v.as_str()).unwrap_or("健康指标");
let metric = event
.payload
.get("metric")
.and_then(|v| v.as_str())
.unwrap_or("健康指标");
(
"健康数据已更新".to_string(),
format!("您的{}数据已记录,护理团队正在持续关注。", metric),
)
}
_ => {
(
"关怀已送达".to_string(),
"您的护理团队正在关注您的健康状况。".to_string(),
)
}
_ => (
"关怀已送达".to_string(),
"您的护理团队正在关注您的健康状况。".to_string(),
),
};
let _ = crate::service::message_service::MessageService::send_system(
@@ -1064,7 +1116,11 @@ async fn handle_workflow_event(
body,
"low",
Some("care_action".to_string()),
event.payload.get("plan_id").and_then(|v| v.as_str()).and_then(|s| uuid::Uuid::parse_str(s).ok()),
event
.payload
.get("plan_id")
.and_then(|v| v.as_str())
.and_then(|s| uuid::Uuid::parse_str(s).ok()),
db,
event_bus,
)