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

@@ -83,10 +83,7 @@ impl WorkflowModule {
"/workflow/tasks/{id}/delegate",
post(task_handler::delegate_task),
)
.route(
"/workflow/tasks/{id}/claim",
put(task_handler::claim_task),
)
.route("/workflow/tasks/{id}/claim", put(task_handler::claim_task))
}
/// 启动超时检查后台任务。
@@ -103,7 +100,11 @@ impl WorkflowModule {
loop {
interval.tick().await;
match crate::engine::timeout::TimeoutChecker::find_all_overdue_tasks_with_details(&db).await {
match crate::engine::timeout::TimeoutChecker::find_all_overdue_tasks_with_details(
&db,
)
.await
{
Ok(overdue) => {
if !overdue.is_empty() {
tracing::warn!(
@@ -177,7 +178,9 @@ async fn handle_ai_action_start(
};
// 构造启动变量
let risk_level = event.payload.get("risk_level")
let risk_level = event
.payload
.get("risk_level")
.and_then(|v| v.as_str())
.unwrap_or("medium")
.to_string();
@@ -191,14 +194,18 @@ async fn handle_ai_action_start(
crate::dto::SetVariableReq {
name: "patient_id".into(),
var_type: Some("string".into()),
value: event.payload.get("patient_id")
value: event
.payload
.get("patient_id")
.cloned()
.unwrap_or(serde_json::Value::Null),
},
crate::dto::SetVariableReq {
name: "action_type".into(),
var_type: Some("string".into()),
value: event.payload.get("action_type")
value: event
.payload
.get("action_type")
.and_then(|v| v.as_str())
.map(|s| serde_json::Value::String(s.to_string()))
.unwrap_or(serde_json::Value::Null),
@@ -206,7 +213,9 @@ async fn handle_ai_action_start(
crate::dto::SetVariableReq {
name: "params".into(),
var_type: Some("string".into()),
value: event.payload.get("params")
value: event
.payload
.get("params")
.cloned()
.unwrap_or(serde_json::Value::Null),
},
@@ -214,18 +223,17 @@ async fn handle_ai_action_start(
let req = crate::dto::StartInstanceReq {
definition_id: def.id,
business_key: Some(format!("ai_action_{}", chrono::Utc::now().timestamp_millis())),
business_key: Some(format!(
"ai_action_{}",
chrono::Utc::now().timestamp_millis()
)),
variables: Some(variables),
};
let system_id = Uuid::parse_str("00000000-0000-0000-0000-000000000000").unwrap();
match crate::service::instance_service::InstanceService::start(
tenant_id,
system_id,
&req,
db,
event_bus,
tenant_id, system_id, &req, db, event_bus,
)
.await
{
@@ -310,8 +318,10 @@ impl ErpModule for WorkflowModule {
);
// 查找该用户有活跃任务的流程实例
use sea_orm::{ActiveModelTrait, ColumnTrait, EntityTrait, QueryFilter, Set};
use chrono::Utc;
use sea_orm::{
ActiveModelTrait, ColumnTrait, EntityTrait, QueryFilter, Set,
};
// 查找该用户作为 assignee 的 pending 任务
let active_tasks = crate::entity::task::Entity::find()
@@ -336,34 +346,36 @@ impl ErpModule for WorkflowModule {
for instance_id in &instance_ids {
// 将实例状态设置为 terminated
let instance = crate::entity::process_instance::Entity::find_by_id(*instance_id)
let instance =
crate::entity::process_instance::Entity::find_by_id(
*instance_id,
)
.one(&db)
.await;
if let Ok(Some(inst)) = instance {
if inst.tenant_id == event.tenant_id
&& inst.deleted_at.is_none()
&& inst.status == "running"
{
let ver = inst.version;
let mut active: crate::entity::process_instance::ActiveModel = inst.into();
active.status = Set("terminated".to_string());
active.updated_at = Set(Utc::now());
active.version = Set(ver + 1);
match active.update(&db).await {
Ok(_) => {
tracing::info!(
instance_id = %instance_id,
"流程实例已终止(用户被删除)"
);
}
Err(e) => {
tracing::warn!(
instance_id = %instance_id,
error = %e,
"终止流程实例失败"
);
}
if let Ok(Some(inst)) = instance
&& inst.tenant_id == event.tenant_id
&& inst.deleted_at.is_none()
&& inst.status == "running"
{
let ver = inst.version;
let mut active: crate::entity::process_instance::ActiveModel = inst.into();
active.status = Set("terminated".to_string());
active.updated_at = Set(Utc::now());
active.version = Set(ver + 1);
match active.update(&db).await {
Ok(_) => {
tracing::info!(
instance_id = %instance_id,
"流程实例已终止(用户被删除)"
);
}
Err(e) => {
tracing::warn!(
instance_id = %instance_id,
error = %e,
"终止流程实例失败"
);
}
}
}
@@ -399,7 +411,10 @@ impl ErpModule for WorkflowModule {
}
});
tracing::info!(module = "workflow", "Workflow 事件处理器已注册(监听 user.deleted");
tracing::info!(
module = "workflow",
"Workflow 事件处理器已注册(监听 user.deleted"
);
// 订阅 AI 行动工作流启动请求
let (mut ai_rx, _ai_handle) = bus.subscribe_filtered("workflow.ai_action.".to_string());
@@ -477,14 +492,54 @@ impl ErpModule for WorkflowModule {
fn permissions(&self) -> Vec<PermissionDescriptor> {
vec![
PermissionDescriptor { code: "workflow.create".into(), name: "创建流程".into(), description: "创建流程定义".into(), module: "workflow".into() },
PermissionDescriptor { code: "workflow.list".into(), name: "查看流程".into(), description: "查看流程列表".into(), module: "workflow".into() },
PermissionDescriptor { code: "workflow.read".into(), name: "查看流程详情".into(), description: "查看流程定义详情".into(), module: "workflow".into() },
PermissionDescriptor { code: "workflow.update".into(), name: "编辑流程".into(), description: "编辑流程定义".into(), module: "workflow".into() },
PermissionDescriptor { code: "workflow.publish".into(), name: "发布流程".into(), description: "发布流程定义".into(), module: "workflow".into() },
PermissionDescriptor { code: "workflow.start".into(), name: "发起流程".into(), description: "发起流程实例".into(), module: "workflow".into() },
PermissionDescriptor { code: "workflow.approve".into(), name: "审批任务".into(), description: "审批流程任务".into(), module: "workflow".into() },
PermissionDescriptor { code: "workflow.delegate".into(), name: "委派任务".into(), description: "委派流程任务".into(), module: "workflow".into() },
PermissionDescriptor {
code: "workflow.create".into(),
name: "创建流程".into(),
description: "创建流程定义".into(),
module: "workflow".into(),
},
PermissionDescriptor {
code: "workflow.list".into(),
name: "查看流程".into(),
description: "查看流程列表".into(),
module: "workflow".into(),
},
PermissionDescriptor {
code: "workflow.read".into(),
name: "查看流程详情".into(),
description: "查看流程定义详情".into(),
module: "workflow".into(),
},
PermissionDescriptor {
code: "workflow.update".into(),
name: "编辑流程".into(),
description: "编辑流程定义".into(),
module: "workflow".into(),
},
PermissionDescriptor {
code: "workflow.publish".into(),
name: "发布流程".into(),
description: "发布流程定义".into(),
module: "workflow".into(),
},
PermissionDescriptor {
code: "workflow.start".into(),
name: "发起流程".into(),
description: "发起流程实例".into(),
module: "workflow".into(),
},
PermissionDescriptor {
code: "workflow.approve".into(),
name: "审批任务".into(),
description: "审批流程任务".into(),
module: "workflow".into(),
},
PermissionDescriptor {
code: "workflow.delegate".into(),
name: "委派任务".into(),
description: "委派流程任务".into(),
module: "workflow".into(),
},
]
}