fix(health): 修复迁移外键表名引用 + 公开轮播图签名 URL 路径拼接
This commit is contained in:
@@ -307,10 +307,11 @@ pub async fn list_public_banners(
|
|||||||
|
|
||||||
let (token, expires) =
|
let (token, expires) =
|
||||||
generate_signed_url(&media.storage_path, &signing_secret(), 3600);
|
generate_signed_url(&media.storage_path, &signing_secret(), 3600);
|
||||||
|
let clean_path = media.storage_path.trim_start_matches("./");
|
||||||
let image_url = format!(
|
let image_url = format!(
|
||||||
"{}{}?expires={}&token={}",
|
"{}/{}?expires={}&token={}",
|
||||||
base_url.trim_end_matches('/'),
|
base_url.trim_end_matches('/'),
|
||||||
media.storage_path,
|
clean_path,
|
||||||
expires,
|
expires,
|
||||||
token
|
token
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -141,8 +141,9 @@ enum MediaItem {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// 外键引用 media_folder 表
|
/// 外键引用 media_folder 表
|
||||||
#[derive(DeriveIden)]
|
#[derive(Iden)]
|
||||||
enum MediaFolderRef {
|
enum MediaFolderRef {
|
||||||
|
#[iden = "media_folder"]
|
||||||
Table,
|
Table,
|
||||||
Id,
|
Id,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -129,8 +129,9 @@ enum Banner {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// 外键引用 media_item 表
|
/// 外键引用 media_item 表
|
||||||
#[derive(DeriveIden)]
|
#[derive(Iden)]
|
||||||
enum MediaItemRef {
|
enum MediaItemRef {
|
||||||
|
#[iden = "media_item"]
|
||||||
Table,
|
Table,
|
||||||
Id,
|
Id,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,192 @@
|
|||||||
|
//! 媒体库 + 轮播图管理菜单种子数据 + 首页推荐文章分类
|
||||||
|
//!
|
||||||
|
//! 1. 插入"媒体库"和"轮播图管理"菜单到健康业务目录(运营分组)
|
||||||
|
//! 2. 创建对应权限码 health.media.list / health.banners.list
|
||||||
|
//! 3. 将权限绑定 admin / operator 角色
|
||||||
|
//! 4. 插入"首页推荐"文章分类到 article_category 表
|
||||||
|
|
||||||
|
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();
|
||||||
|
let sys = "00000000-0000-0000-0000-000000000000";
|
||||||
|
|
||||||
|
// ================================================================
|
||||||
|
// Part 1: 插入"媒体库"和"轮播图管理"菜单
|
||||||
|
// ================================================================
|
||||||
|
// 运营分组: articles(40), points-rules(41), points-products(42),
|
||||||
|
// points-orders(43), offline-events(44)
|
||||||
|
// 媒体库 → 45, 轮播图管理 → 46
|
||||||
|
|
||||||
|
let menus: &[(&str, &str, &str, &str, i32)] = &[
|
||||||
|
(
|
||||||
|
"b0000003-0000-7000-8000-000000000033",
|
||||||
|
"媒体库",
|
||||||
|
"/health/media-library",
|
||||||
|
"PictureOutlined",
|
||||||
|
45,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"b0000003-0000-7000-8000-000000000034",
|
||||||
|
"轮播图管理",
|
||||||
|
"/health/banners",
|
||||||
|
"SwapOutlined",
|
||||||
|
46,
|
||||||
|
),
|
||||||
|
];
|
||||||
|
|
||||||
|
for &(id, title, path, icon, sort) in menus {
|
||||||
|
let sql = format!(
|
||||||
|
r#"
|
||||||
|
INSERT INTO menus (id, tenant_id, parent_id, title, path, icon, sort_order,
|
||||||
|
visible, menu_type, created_at, updated_at, created_by, updated_by, version)
|
||||||
|
SELECT
|
||||||
|
'{id}'::uuid,
|
||||||
|
t.id,
|
||||||
|
(SELECT m.id FROM menus m WHERE m.path = '/health' AND m.tenant_id = t.id LIMIT 1),
|
||||||
|
'{title}',
|
||||||
|
'{path}',
|
||||||
|
'{icon}',
|
||||||
|
{sort},
|
||||||
|
true, 'page',
|
||||||
|
NOW(), NOW(),
|
||||||
|
(SELECT u.id FROM users u WHERE u.tenant_id = t.id LIMIT 1),
|
||||||
|
(SELECT u.id FROM users u WHERE u.tenant_id = t.id LIMIT 1),
|
||||||
|
1
|
||||||
|
FROM tenant t
|
||||||
|
WHERE NOT EXISTS (
|
||||||
|
SELECT 1 FROM menus m WHERE m.path = '{path}' AND m.tenant_id = t.id
|
||||||
|
)
|
||||||
|
"#
|
||||||
|
);
|
||||||
|
db.execute_unprepared(&sql).await?;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ================================================================
|
||||||
|
// Part 2: 创建权限码
|
||||||
|
// ================================================================
|
||||||
|
let permissions: &[(&str, &str, &str, &str)] = &[
|
||||||
|
("health.media.list", "媒体库查看", "health", "media.list"),
|
||||||
|
(
|
||||||
|
"health.banners.list",
|
||||||
|
"轮播图查看",
|
||||||
|
"health",
|
||||||
|
"banners.list",
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"health.media.manage",
|
||||||
|
"媒体库管理",
|
||||||
|
"health",
|
||||||
|
"media.manage",
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"health.banners.manage",
|
||||||
|
"轮播图管理",
|
||||||
|
"health",
|
||||||
|
"banners.manage",
|
||||||
|
),
|
||||||
|
];
|
||||||
|
|
||||||
|
for &(code, name, resource, action) in permissions {
|
||||||
|
db.execute_unprepared(&format!(
|
||||||
|
r#"
|
||||||
|
INSERT INTO permissions (id, tenant_id, code, name, resource, action, description,
|
||||||
|
created_at, updated_at, created_by, updated_by, deleted_at, version)
|
||||||
|
SELECT gen_random_uuid(), t.id, '{code}', '{name}', '{resource}', '{action}', '{name}',
|
||||||
|
NOW(), NOW(), '{sys}', '{sys}', NULL, 1
|
||||||
|
FROM tenant t
|
||||||
|
WHERE NOT EXISTS (
|
||||||
|
SELECT 1 FROM permissions p
|
||||||
|
WHERE p.code = '{code}' AND p.tenant_id = t.id AND p.deleted_at IS NULL
|
||||||
|
)
|
||||||
|
"#
|
||||||
|
)).await?;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ================================================================
|
||||||
|
// Part 3: 绑定权限到 admin 和 operator 角色
|
||||||
|
// ================================================================
|
||||||
|
for role_code in &["admin", "operator"] {
|
||||||
|
db.execute_unprepared(&format!(
|
||||||
|
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 = '{role_code}' AND r.deleted_at IS NULL
|
||||||
|
JOIN permissions p ON p.tenant_id = t.id
|
||||||
|
AND p.code IN ('health.media.list', 'health.banners.list',
|
||||||
|
'health.media.manage', 'health.banners.manage')
|
||||||
|
AND p.deleted_at IS NULL
|
||||||
|
WHERE NOT EXISTS (
|
||||||
|
SELECT 1 FROM role_permissions rp
|
||||||
|
WHERE rp.permission_id = p.id AND rp.role_id = r.id
|
||||||
|
)
|
||||||
|
"#
|
||||||
|
)).await?;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ================================================================
|
||||||
|
// Part 4: 插入"首页推荐"文章分类
|
||||||
|
// ================================================================
|
||||||
|
db.execute_unprepared(&format!(
|
||||||
|
r#"
|
||||||
|
INSERT INTO article_category (id, tenant_id, name, slug, parent_id, description, sort_order,
|
||||||
|
created_at, updated_at, created_by, updated_by, deleted_at, version)
|
||||||
|
SELECT gen_random_uuid(), t.id, '首页推荐', 'home-featured', NULL,
|
||||||
|
'小程序访客首页展示的推荐文章', 0,
|
||||||
|
NOW(), NOW(), '{sys}', '{sys}', NULL, 1
|
||||||
|
FROM tenant t
|
||||||
|
WHERE NOT EXISTS (
|
||||||
|
SELECT 1 FROM article_category ac
|
||||||
|
WHERE ac.slug = 'home-featured' AND ac.tenant_id = t.id AND ac.deleted_at IS NULL
|
||||||
|
)
|
||||||
|
"#
|
||||||
|
)).await?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {
|
||||||
|
let db = manager.get_connection();
|
||||||
|
|
||||||
|
// 删除菜单
|
||||||
|
for path in &["/health/media-library", "/health/banners"] {
|
||||||
|
db.execute_unprepared(&format!("DELETE FROM menus WHERE path = '{path}'"))
|
||||||
|
.await
|
||||||
|
.ok();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 删除权限绑定
|
||||||
|
db.execute_unprepared(
|
||||||
|
"DELETE FROM role_permissions
|
||||||
|
WHERE permission_id IN (
|
||||||
|
SELECT id FROM permissions
|
||||||
|
WHERE code IN ('health.media.list', 'health.banners.list',
|
||||||
|
'health.media.manage', 'health.banners.manage')
|
||||||
|
)",
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
.ok();
|
||||||
|
|
||||||
|
// 删除权限
|
||||||
|
db.execute_unprepared(
|
||||||
|
"DELETE FROM permissions
|
||||||
|
WHERE code IN ('health.media.list', 'health.banners.list',
|
||||||
|
'health.media.manage', 'health.banners.manage')",
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
.ok();
|
||||||
|
|
||||||
|
// 删除文章分类
|
||||||
|
db.execute_unprepared("DELETE FROM article_category WHERE slug = 'home-featured'")
|
||||||
|
.await
|
||||||
|
.ok();
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user