Files
hms/crates/erp-server/migration/src/m20260501_000097_seed_menu_permissions.rs
iven 6d5a711d2c
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
fix: 修复测试发现的 7 个问题 + 全 workspace clippy 清零
功能修复:
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 统一格式化
2026-05-07 23:43:14 +08:00

234 lines
6.4 KiB
Rust
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
//! 为菜单种子数据关联权限码 + 补全缺失菜单项
use sea_orm_migration::prelude::*;
#[derive(DeriveMigrationName)]
pub struct Migration;
#[async_trait::async_trait]
impl MigrationTrait for Migration {
async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> {
let db = manager.get_connection();
// === 更新已有菜单的 permission 字段 ===
// 健康管理菜单
update_perm(
db,
"b0000003-0000-0000-0000-000000000002",
"health.patient.list",
)
.await?;
update_perm(
db,
"b0000003-0000-0000-0000-000000000003",
"health.doctor.list",
)
.await?;
update_perm(
db,
"b0000003-0000-0000-0000-000000000004",
"health.appointment.list",
)
.await?;
update_perm(
db,
"b0000003-0000-0000-0000-000000000005",
"health.appointment.list",
)
.await?;
update_perm(
db,
"b0000003-0000-0000-0000-000000000006",
"health.follow-up.list",
)
.await?;
update_perm(
db,
"b0000003-0000-0000-0000-000000000007",
"health.consultation.list",
)
.await?;
update_perm(
db,
"b0000003-0000-0000-0000-000000000008",
"health.patient.list",
)
.await?;
update_perm(
db,
"b0000003-0000-0000-0000-000000000009",
"health.points.list",
)
.await?;
update_perm(
db,
"b0000003-0000-0000-0000-000000000010",
"health.points.list",
)
.await?;
update_perm(
db,
"b0000003-0000-0000-0000-000000000011",
"health.points.list",
)
.await?;
update_perm(
db,
"b0000003-0000-0000-0000-000000000012",
"health.points.list",
)
.await?;
// AI 模块菜单
update_perm(db, "b0000003-0000-0000-0000-000000000013", "ai.prompt.list").await?;
update_perm(
db,
"b0000003-0000-0000-0000-000000000014",
"ai.analysis.list",
)
.await?;
update_perm(db, "b0000003-0000-0000-0000-000000000015", "ai.usage.list").await?;
// 告警菜单
update_perm(
db,
"b0000003-0000-0000-0000-000000000016",
"health.alerts.list",
)
.await?;
update_perm(
db,
"b0000003-0000-0000-0000-000000000017",
"health.alerts.list",
)
.await?;
update_perm(
db,
"b0000003-0000-0000-0000-000000000018",
"health.alert-rules.list",
)
.await?;
// 设备菜单
update_perm(
db,
"b0000003-0000-0000-0000-000000000019",
"health.devices.list",
)
.await?;
// === 补全缺失菜单 ===
let result = db
.query_one(sea_orm::Statement::from_string(
sea_orm::DatabaseBackend::Postgres,
"SELECT id::text FROM tenant LIMIT 1".to_string(),
))
.await?;
let tid = match result {
Some(row) => row.try_get_by_index::<String>(0).unwrap_or_default(),
None => return Ok(()),
};
let sys = "00000000-0000-0000-0000-000000000000";
let d3 = "a0000000-0000-0000-0000-000000000003"; // 健康管理目录
// 透析管理sort 19
insert_menu_with_perm(
db,
&tid,
d3,
"b0000003-0000-0000-0000-000000000020",
"透析管理",
"/health/dialysis",
"ExperimentOutlined",
19,
"health.dialysis.list",
sys,
)
.await?;
// 资讯管理sort 20
insert_menu_with_perm(
db,
&tid,
d3,
"b0000003-0000-0000-0000-000000000021",
"资讯管理",
"/health/articles",
"ReadOutlined",
20,
"health.articles.list",
sys,
)
.await?;
Ok(())
}
async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {
let db = manager.get_connection();
// 清除所有菜单的 permission
db.execute(sea_orm::Statement::from_string(
sea_orm::DatabaseBackend::Postgres,
"UPDATE menus SET permission = NULL WHERE deleted_at IS NULL".to_string(),
))
.await?;
// 删除新增菜单
for id in &[
"b0000003-0000-0000-0000-000000000020",
"b0000003-0000-0000-0000-000000000021",
] {
db.execute(sea_orm::Statement::from_string(
sea_orm::DatabaseBackend::Postgres,
format!("DELETE FROM menus WHERE id = '{id}'"),
))
.await
.ok();
}
Ok(())
}
}
async fn update_perm(
db: &sea_orm_migration::SchemaManagerConnection<'_>,
menu_id: &str,
permission: &str,
) -> Result<(), DbErr> {
db.execute(sea_orm::Statement::from_string(
sea_orm::DatabaseBackend::Postgres,
format!(
"UPDATE menus SET permission = '{permission}', updated_at = NOW() \
WHERE id = '{menu_id}' AND deleted_at IS NULL"
),
))
.await?;
Ok(())
}
async fn insert_menu_with_perm(
db: &sea_orm_migration::SchemaManagerConnection<'_>,
tenant_id: &str,
parent_id: &str,
id: &str,
title: &str,
path: &str,
icon: &str,
sort: i32,
permission: &str,
sys: &str,
) -> Result<(), DbErr> {
let esc_title = title.replace('\'', "''");
db.execute(sea_orm::Statement::from_string(
sea_orm::DatabaseBackend::Postgres,
format!(
"INSERT INTO menus (id, tenant_id, parent_id, title, path, icon, sort_order, visible, menu_type, permission, created_at, updated_at, created_by, updated_by, deleted_at, version) \
VALUES ('{id}', '{tenant_id}', '{parent_id}', '{esc_title}', '{path}', '{icon}', {sort}, true, 'menu', '{permission}', NOW(), NOW(), '{sys}', '{sys}', NULL, 1) \
ON CONFLICT (id) DO UPDATE SET permission = EXCLUDED.permission, updated_at = NOW()"
),
))
.await?;
Ok(())
}