feat(db): 添加 student/teacher/parent 角色种子 — 日记权限分配
This commit is contained in:
@@ -70,6 +70,7 @@ mod m20260531_000181_create_teacher_profiles;
|
||||
mod m20260531_000182_create_user_settings;
|
||||
mod m20260531_000183_diary_indexes_and_fts;
|
||||
mod m20260531_000184_diary_seed_data;
|
||||
mod m20260601_000300_diary_role_seed;
|
||||
|
||||
pub struct Migrator;
|
||||
|
||||
@@ -146,6 +147,7 @@ impl MigratorTrait for Migrator {
|
||||
Box::new(m20260531_000182_create_user_settings::Migration),
|
||||
Box::new(m20260531_000183_diary_indexes_and_fts::Migration),
|
||||
Box::new(m20260531_000184_diary_seed_data::Migration),
|
||||
Box::new(m20260601_000300_diary_role_seed::Migration),
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,100 @@
|
||||
// 暖记角色种子 — student/teacher/parent 角色 + 权限分配
|
||||
|
||||
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 conn = manager.get_connection();
|
||||
let tid = "'00000000-0000-0000-0000-000000000000'::uuid";
|
||||
|
||||
// 插入 student/teacher/parent 角色
|
||||
let roles = [
|
||||
("student", "学生", "学生 — 创建和管理自己的日记", false),
|
||||
("teacher", "老师", "老师 — 创建班级、布置主题、点评日记", false),
|
||||
("parent", "家长", "家长 — 查看和管理孩子的日记数据", false),
|
||||
];
|
||||
|
||||
for (code, name, desc, is_system) in &roles {
|
||||
let sys_flag = if *is_system { "true" } else { "false" };
|
||||
let sql = format!(
|
||||
r#"INSERT INTO roles (id, tenant_id, name, code, description, is_system, created_at, updated_at, created_by, updated_by, version)
|
||||
VALUES (gen_random_uuid(), {tid}, '{name}', '{code}', '{desc}', {sys_flag}, now(), now(), {tid}, {tid}, 1)
|
||||
ON CONFLICT (tenant_id, code) WHERE deleted_at IS NULL DO NOTHING"#,
|
||||
);
|
||||
conn.execute(sea_orm::Statement::from_string(
|
||||
sea_orm::DatabaseBackend::Postgres,
|
||||
sql,
|
||||
))
|
||||
.await
|
||||
.map_err(|e| DbErr::Custom(e.to_string()))?;
|
||||
}
|
||||
|
||||
// student 权限: diary.journal.create, diary.journal.read
|
||||
// teacher 权限: diary.journal.create, diary.journal.read, diary.class.manage, diary.topic.assign, diary.comment.write
|
||||
// parent 权限: diary.journal.read, diary.parent.bind
|
||||
let role_permissions = [
|
||||
("student", "diary.journal.create"),
|
||||
("student", "diary.journal.read"),
|
||||
("teacher", "diary.journal.create"),
|
||||
("teacher", "diary.journal.read"),
|
||||
("teacher", "diary.class.manage"),
|
||||
("teacher", "diary.topic.assign"),
|
||||
("teacher", "diary.comment.write"),
|
||||
("parent", "diary.journal.read"),
|
||||
("parent", "diary.parent.bind"),
|
||||
];
|
||||
|
||||
for (role_code, perm_code) in &role_permissions {
|
||||
let sql = format!(
|
||||
r#"INSERT INTO role_permissions (id, role_id, permission_id, tenant_id, created_at, updated_at, created_by, updated_by, version)
|
||||
SELECT gen_random_uuid(), r.id, p.id, r.tenant_id, now(), now(), {tid}, {tid}, 1
|
||||
FROM roles r
|
||||
JOIN permissions p ON p.tenant_id = r.tenant_id
|
||||
WHERE r.code = '{role_code}' AND r.tenant_id = {tid} AND r.deleted_at IS NULL
|
||||
AND p.code = '{perm_code}' AND p.deleted_at IS NULL
|
||||
ON CONFLICT DO NOTHING"#,
|
||||
);
|
||||
conn.execute(sea_orm::Statement::from_string(
|
||||
sea_orm::DatabaseBackend::Postgres,
|
||||
sql,
|
||||
))
|
||||
.await
|
||||
.map_err(|e| DbErr::Custom(e.to_string()))?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {
|
||||
let conn = manager.get_connection();
|
||||
let tid_str = "WHERE tenant_id = '00000000-0000-0000-0000-000000000000'";
|
||||
|
||||
// 先删除 role_permissions 引用
|
||||
for role_code in &["student", "teacher", "parent"] {
|
||||
conn.execute(sea_orm::Statement::from_string(
|
||||
sea_orm::DatabaseBackend::Postgres,
|
||||
format!(
|
||||
"DELETE FROM role_permissions WHERE role_id IN (SELECT id FROM roles WHERE code = '{role_code}' {tid_str})"
|
||||
),
|
||||
))
|
||||
.await
|
||||
.map_err(|e| DbErr::Custom(e.to_string()))?;
|
||||
}
|
||||
|
||||
// 再删除角色
|
||||
for role_code in &["student", "teacher", "parent"] {
|
||||
conn.execute(sea_orm::Statement::from_string(
|
||||
sea_orm::DatabaseBackend::Postgres,
|
||||
format!("DELETE FROM roles WHERE code = '{role_code}' {tid_str}"),
|
||||
))
|
||||
.await
|
||||
.map_err(|e| DbErr::Custom(e.to_string()))?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user