// 暖记种子数据 — 默认成就 + 基础贴纸包 + 暖记权限 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(); // 默认租户和系统用户 UUID(内嵌 SQL,避免类型转换问题) let tid = "'00000000-0000-0000-0000-000000000000'::uuid"; // 插入默认成就 let achievements = [ ("first_diary", "初出茅庐", "写下第一篇日记", "📝", "writing", r#"{"type":"diary_count","threshold":1}"#, 10), ("diary_10", "小有成就", "累计写 10 篇日记", "✏️", "writing", r#"{"type":"diary_count","threshold":10}"#, 20), ("diary_50", "笔下生花", "累计写 50 篇日记", "🌸", "writing", r#"{"type":"diary_count","threshold":50}"#, 30), ("diary_100", "日记达人", "累计写 100 篇日记", "🏆", "writing", r#"{"type":"diary_count","threshold":100}"#, 40), ("streak_3", "三日不间断", "连续 3 天写日记", "🔥", "writing", r#"{"type":"streak","threshold":3}"#, 50), ("streak_7", "一周坚持", "连续 7 天写日记", "⭐", "writing", r#"{"type":"streak","threshold":7}"#, 60), ("streak_30", "月度冠军", "连续 30 天写日记", "👑", "writing", r#"{"type":"streak","threshold":30}"#, 70), ("first_share", "分享快乐", "第一次分享日记到班级", "💝", "social", r#"{"type":"share_count","threshold":1}"#, 80), ("comment_received", "获得鼓励", "第一次收到老师点评", "💌", "social", r#"{"type":"comment_received","threshold":1}"#, 90), ("all_moods", "情绪彩虹", "使用过所有 5 种心情", "🌈", "collection", r#"{"type":"mood_variety","threshold":5}"#, 100), ]; for (code, name, desc, icon, category, condition, sort) in &achievements { let sql = format!( r#"INSERT INTO achievements (id, tenant_id, code, name, description, icon, category, condition, sort_order, created_at, updated_at, created_by, updated_by, version) VALUES (gen_random_uuid(), {tid}, '{code}', '{name}', '{desc}', '{icon}', '{category}', '{condition}'::jsonb, {sort}, now(), now(), {tid}, {tid}, 1)"#, ); conn.execute(sea_orm::Statement::from_string( sea_orm::DatabaseBackend::Postgres, sql, )).await.map_err(|e| DbErr::Custom(e.to_string()))?; } // 插入基础贴纸包 conn.execute(sea_orm::Statement::from_string( sea_orm::DatabaseBackend::Postgres, format!( r#"INSERT INTO sticker_packs (id, tenant_id, name, description, is_free, price, category, created_at, updated_at, created_by, updated_by, version) VALUES (gen_random_uuid(), {tid}, '基础贴纸', '暖记默认贴纸包,包含常用表情和装饰', true, 0, 'basic', now(), now(), {tid}, {tid}, 1)"#, ), )).await.map_err(|e| DbErr::Custom(e.to_string()))?; // 插入暖记权限到 permissions 表 (resource + action 模式) let diary_permissions = [ ("diary.journal.create", "创建日记", "journal", "create", "允许创建日记条目"), ("diary.journal.read", "查看日记", "journal", "read", "允许查看日记条目"), ("diary.journal.update", "编辑日记", "journal", "update", "允许编辑日记条目"), ("diary.journal.delete", "删除日记", "journal", "delete", "允许删除日记条目"), ("diary.class.manage", "管理班级", "class", "manage", "允许创建和管理班级"), ("diary.topic.assign", "布置主题", "topic", "assign", "允许老师布置日记主题"), ("diary.comment.write", "写评语", "comment", "write", "允许老师点评日记"), ("diary.parent.bind", "家长绑定", "parent", "bind", "允许家长绑定孩子账号"), ]; for (code, name, resource, action, desc) in &diary_permissions { let sql = format!( r#"INSERT INTO permissions (id, tenant_id, code, name, resource, action, description, created_at, updated_at, created_by, updated_by, version) VALUES (gen_random_uuid(), {tid}, '{code}', '{name}', '{resource}', '{action}', '{desc}', 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()))?; } 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'"; conn.execute(sea_orm::Statement::from_string( sea_orm::DatabaseBackend::Postgres, format!("DELETE FROM achievements {tid_str}"), )).await.map_err(|e| DbErr::Custom(e.to_string()))?; conn.execute(sea_orm::Statement::from_string( sea_orm::DatabaseBackend::Postgres, format!("DELETE FROM sticker_packs {tid_str}"), )).await.map_err(|e| DbErr::Custom(e.to_string()))?; conn.execute(sea_orm::Statement::from_string( sea_orm::DatabaseBackend::Postgres, format!("DELETE FROM permissions WHERE code LIKE 'diary.%' AND tenant_id = '00000000-0000-0000-0000-000000000000'"), )).await.map_err(|e| DbErr::Custom(e.to_string()))?; Ok(()) } }