feat(web): 随访模板管理页面 — CRUD + 路由 + 菜单迁移
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

- 新增 FollowUpTemplateList.tsx 页面(列表/新建/编辑/详情弹窗)
- 新增 followUpTemplates.ts API 客户端(list/get/create/update/delete)
- 注册路由 /health/follow-up-templates + 菜单标题 fallback
- 新增迁移 seed_follow_up_template_menu 注册菜单和权限
This commit is contained in:
iven
2026-05-03 09:31:43 +08:00
parent 2e4d98c479
commit 32df9c0655
6 changed files with 511 additions and 0 deletions

View File

@@ -102,6 +102,7 @@ mod m20260501_000099_create_ai_risk_threshold;
mod m20260501_000100_seed_action_inbox_menu;
mod m20260502_000101_seed_health_dictionaries;
mod m20260502_000102_seed_warning_thresholds;
mod m20260502_000103_seed_follow_up_template_menu;
pub struct Migrator;
@@ -211,6 +212,7 @@ impl MigratorTrait for Migrator {
Box::new(m20260501_000100_seed_action_inbox_menu::Migration),
Box::new(m20260502_000101_seed_health_dictionaries::Migration),
Box::new(m20260502_000102_seed_warning_thresholds::Migration),
Box::new(m20260502_000103_seed_follow_up_template_menu::Migration),
]
}
}

View File

@@ -0,0 +1,65 @@
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();
// 添加随访模板管理菜单排在行动收件箱后面sort_order=37
db.execute_unprepared(
r#"
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, version)
SELECT
'b0000003-0000-7000-8000-000000000021'::uuid,
t.id,
(SELECT id FROM menus WHERE path = '/health' AND tenant_id = t.id LIMIT 1),
'随访模板管理',
'/health/follow-up-templates',
'FormOutlined',
37,
true, 'page', 'health.follow-up-templates.list',
NOW(), NOW(),
(SELECT id FROM users WHERE tenant_id = t.id LIMIT 1),
(SELECT id FROM users WHERE tenant_id = t.id LIMIT 1),
1
FROM tenant t
WHERE NOT EXISTS (
SELECT 1 FROM menus
WHERE path = '/health/follow-up-templates' AND tenant_id = t.id
)
"#,
)
.await?;
// 给 admin 角色绑定 list + manage 权限
db.execute_unprepared(
r#"
INSERT INTO role_permissions (role_id, permission_id, tenant_id, created_by, updated_by, version)
SELECT r.id, p.id, t.id, r.id, r.id, 1
FROM tenant t
JOIN roles r ON r.tenant_id = t.id AND r.code = 'admin'
JOIN permissions p ON p.tenant_id = t.id AND p.code IN ('health.follow-up-templates.list', 'health.follow-up-templates.manage')
WHERE NOT EXISTS (
SELECT 1 FROM role_permissions rp
WHERE rp.permission_id = p.id AND rp.role_id = r.id
)
"#,
)
.await?;
Ok(())
}
async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {
let db = manager.get_connection();
db.execute_unprepared(
"DELETE FROM menus WHERE path = '/health/follow-up-templates'",
)
.await?;
Ok(())
}
}