功能修复: 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 统一格式化
234 lines
6.4 KiB
Rust
234 lines
6.4 KiB
Rust
//! 为菜单种子数据关联权限码 + 补全缺失菜单项
|
||
|
||
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(())
|
||
}
|