244 lines
11 KiB
C#
244 lines
11 KiB
C#
using Microsoft.EntityFrameworkCore.Infrastructure;
|
|
using Microsoft.EntityFrameworkCore.Migrations;
|
|
using TakeoutSaaS.Infrastructure.Identity.Persistence;
|
|
|
|
#nullable disable
|
|
|
|
namespace TakeoutSaaS.Infrastructure.Migrations.IdentityDb;
|
|
|
|
/// <summary>
|
|
/// 写入成本管理菜单与权限定义。
|
|
/// </summary>
|
|
[DbContext(typeof(IdentityDbContext))]
|
|
[Migration("20260305013000_SeedFinanceCostMenuAndPermissions")]
|
|
public sealed class SeedFinanceCostMenuAndPermissions : Migration
|
|
{
|
|
/// <inheritdoc />
|
|
protected override void Up(MigrationBuilder migrationBuilder)
|
|
{
|
|
migrationBuilder.Sql(
|
|
"""
|
|
DO $$
|
|
DECLARE
|
|
v_parent_permission_id bigint;
|
|
v_view_permission_id bigint;
|
|
v_manage_permission_id bigint;
|
|
v_parent_menu_id bigint;
|
|
v_cost_menu_id bigint;
|
|
v_permission_seed_base bigint := 840100000000000000;
|
|
v_menu_seed_base bigint := 850100000000000000;
|
|
BEGIN
|
|
-- 1. 确保财务权限分组存在。
|
|
SELECT "Id"
|
|
INTO v_parent_permission_id
|
|
FROM public.permissions
|
|
WHERE "Code" = 'group:tenant:finance'
|
|
ORDER BY "Id"
|
|
LIMIT 1;
|
|
|
|
IF v_parent_permission_id IS NULL THEN
|
|
v_parent_permission_id := v_permission_seed_base + 1;
|
|
INSERT INTO public.permissions (
|
|
"Id", "Name", "Code", "Description",
|
|
"CreatedAt", "UpdatedAt", "DeletedAt",
|
|
"CreatedBy", "UpdatedBy", "DeletedBy",
|
|
"ParentId", "SortOrder", "Type", "Portal")
|
|
VALUES (
|
|
v_parent_permission_id, '财务中心', 'group:tenant:finance', '财务中心权限分组',
|
|
NOW(), NULL, NULL,
|
|
NULL, NULL, NULL,
|
|
0, 5000, 'group', 1)
|
|
ON CONFLICT ("Code") DO NOTHING;
|
|
END IF;
|
|
|
|
-- 2. Upsert 成本管理查看权限。
|
|
INSERT INTO public.permissions (
|
|
"Id", "Name", "Code", "Description",
|
|
"CreatedAt", "UpdatedAt", "DeletedAt",
|
|
"CreatedBy", "UpdatedBy", "DeletedBy",
|
|
"ParentId", "SortOrder", "Type", "Portal")
|
|
VALUES (
|
|
v_permission_seed_base + 11, '成本管理查看', 'tenant:finance:cost:view', '查看成本录入与成本分析',
|
|
NOW(), NULL, NULL,
|
|
NULL, NULL, NULL,
|
|
v_parent_permission_id, 5110, 'leaf', 1)
|
|
ON CONFLICT ("Code") DO UPDATE
|
|
SET "Name" = EXCLUDED."Name",
|
|
"Description" = EXCLUDED."Description",
|
|
"ParentId" = EXCLUDED."ParentId",
|
|
"SortOrder" = EXCLUDED."SortOrder",
|
|
"Type" = EXCLUDED."Type",
|
|
"Portal" = EXCLUDED."Portal",
|
|
"DeletedAt" = NULL,
|
|
"DeletedBy" = NULL,
|
|
"UpdatedAt" = NOW();
|
|
|
|
-- 3. Upsert 成本管理维护权限。
|
|
INSERT INTO public.permissions (
|
|
"Id", "Name", "Code", "Description",
|
|
"CreatedAt", "UpdatedAt", "DeletedAt",
|
|
"CreatedBy", "UpdatedBy", "DeletedBy",
|
|
"ParentId", "SortOrder", "Type", "Portal")
|
|
VALUES (
|
|
v_permission_seed_base + 12, '成本管理维护', 'tenant:finance:cost:manage', '维护成本录入明细与保存数据',
|
|
NOW(), NULL, NULL,
|
|
NULL, NULL, NULL,
|
|
v_parent_permission_id, 5120, 'leaf', 1)
|
|
ON CONFLICT ("Code") DO UPDATE
|
|
SET "Name" = EXCLUDED."Name",
|
|
"Description" = EXCLUDED."Description",
|
|
"ParentId" = EXCLUDED."ParentId",
|
|
"SortOrder" = EXCLUDED."SortOrder",
|
|
"Type" = EXCLUDED."Type",
|
|
"Portal" = EXCLUDED."Portal",
|
|
"DeletedAt" = NULL,
|
|
"DeletedBy" = NULL,
|
|
"UpdatedAt" = NOW();
|
|
|
|
-- 4. 回填权限 ID。
|
|
SELECT "Id" INTO v_view_permission_id FROM public.permissions WHERE "Code" = 'tenant:finance:cost:view' LIMIT 1;
|
|
SELECT "Id" INTO v_manage_permission_id FROM public.permissions WHERE "Code" = 'tenant:finance:cost:manage' LIMIT 1;
|
|
|
|
-- 5. 确保租户端财务父菜单存在。
|
|
SELECT "Id"
|
|
INTO v_parent_menu_id
|
|
FROM public.menu_definitions
|
|
WHERE "Portal" = 1 AND "Path" = '/finance' AND "DeletedAt" IS NULL
|
|
ORDER BY "Id"
|
|
LIMIT 1;
|
|
|
|
IF v_parent_menu_id IS NULL THEN
|
|
v_parent_menu_id := v_menu_seed_base + 1;
|
|
INSERT INTO public.menu_definitions (
|
|
"Id", "ParentId", "Name", "Path", "Component", "Title", "Icon",
|
|
"IsIframe", "Link", "KeepAlive", "SortOrder",
|
|
"RequiredPermissions", "MetaPermissions", "MetaRoles", "AuthListJson",
|
|
"CreatedAt", "UpdatedAt", "DeletedAt", "CreatedBy", "UpdatedBy", "DeletedBy", "Portal")
|
|
VALUES (
|
|
v_parent_menu_id, 0, 'Finance', '/finance', 'BasicLayout', '财务中心', 'lucide:wallet',
|
|
FALSE, NULL, FALSE, 500,
|
|
'', '', '', NULL,
|
|
NOW(), NULL, NULL, NULL, NULL, NULL, 1)
|
|
ON CONFLICT ("Id") DO NOTHING;
|
|
END IF;
|
|
|
|
-- 6. Upsert 成本管理菜单。
|
|
SELECT "Id"
|
|
INTO v_cost_menu_id
|
|
FROM public.menu_definitions
|
|
WHERE "Portal" = 1
|
|
AND ("Path" = '/finance/cost' OR ("Path" = 'cost' AND "Component" = '/finance/cost/index'))
|
|
ORDER BY "DeletedAt" NULLS FIRST, "Id"
|
|
LIMIT 1;
|
|
|
|
IF v_cost_menu_id IS NULL THEN
|
|
v_cost_menu_id := v_menu_seed_base + 11;
|
|
INSERT INTO public.menu_definitions (
|
|
"Id", "ParentId", "Name", "Path", "Component", "Title", "Icon",
|
|
"IsIframe", "Link", "KeepAlive", "SortOrder",
|
|
"RequiredPermissions", "MetaPermissions", "MetaRoles", "AuthListJson",
|
|
"CreatedAt", "UpdatedAt", "DeletedAt", "CreatedBy", "UpdatedBy", "DeletedBy", "Portal")
|
|
VALUES (
|
|
v_cost_menu_id, v_parent_menu_id, 'CostManagement', '/finance/cost', '/finance/cost/index', '成本管理', 'lucide:circle-dollar-sign',
|
|
FALSE, NULL, TRUE, 520,
|
|
'tenant:finance:cost:view', 'tenant:finance:cost:view,tenant:finance:cost:manage', '', NULL,
|
|
NOW(), NULL, NULL, NULL, NULL, NULL, 1)
|
|
ON CONFLICT ("Id") DO NOTHING;
|
|
ELSE
|
|
UPDATE public.menu_definitions
|
|
SET "ParentId" = v_parent_menu_id,
|
|
"Name" = 'CostManagement',
|
|
"Path" = '/finance/cost',
|
|
"Component" = '/finance/cost/index',
|
|
"Title" = '成本管理',
|
|
"Icon" = 'lucide:circle-dollar-sign',
|
|
"IsIframe" = FALSE,
|
|
"Link" = NULL,
|
|
"KeepAlive" = TRUE,
|
|
"SortOrder" = 520,
|
|
"RequiredPermissions" = 'tenant:finance:cost:view',
|
|
"MetaPermissions" = 'tenant:finance:cost:view,tenant:finance:cost:manage',
|
|
"MetaRoles" = '',
|
|
"DeletedAt" = NULL,
|
|
"DeletedBy" = NULL,
|
|
"UpdatedAt" = NOW(),
|
|
"Portal" = 1
|
|
WHERE "Id" = v_cost_menu_id;
|
|
END IF;
|
|
|
|
-- 7. 为 tenant-admin 角色授予成本权限。
|
|
INSERT INTO public.role_permissions (
|
|
"Id", "RoleId", "PermissionId", "CreatedAt", "UpdatedAt", "DeletedAt",
|
|
"CreatedBy", "UpdatedBy", "DeletedBy", "TenantId", "Portal")
|
|
SELECT
|
|
ABS(HASHTEXTEXTENDED('tenant-admin:cost:' || role."Id"::text || ':' || permission_id::text, 0)),
|
|
role."Id",
|
|
permission_id,
|
|
NOW(), NULL, NULL,
|
|
NULL, NULL, NULL,
|
|
role."TenantId",
|
|
1
|
|
FROM public.roles role
|
|
CROSS JOIN LATERAL (
|
|
SELECT UNNEST(ARRAY[v_view_permission_id, v_manage_permission_id]) AS permission_id
|
|
) item
|
|
WHERE role."Code" = 'tenant-admin'
|
|
AND role."DeletedAt" IS NULL
|
|
AND item.permission_id IS NOT NULL
|
|
ON CONFLICT ("RoleId", "PermissionId") DO UPDATE
|
|
SET "DeletedAt" = NULL,
|
|
"DeletedBy" = NULL,
|
|
"UpdatedAt" = NOW(),
|
|
"Portal" = 1;
|
|
|
|
-- 8. 为 tenant-admin 角色模板授予成本权限。
|
|
INSERT INTO public.role_template_permissions (
|
|
"Id", "RoleTemplateId", "PermissionCode",
|
|
"CreatedAt", "UpdatedAt", "DeletedAt",
|
|
"CreatedBy", "UpdatedBy", "DeletedBy")
|
|
SELECT
|
|
ABS(HASHTEXTEXTENDED('template-cost:' || template."Id"::text || ':' || item.permission_code, 0)),
|
|
template."Id",
|
|
item.permission_code,
|
|
NOW(), NULL, NULL,
|
|
NULL, NULL, NULL
|
|
FROM public.role_templates template
|
|
CROSS JOIN LATERAL (
|
|
SELECT UNNEST(ARRAY['tenant:finance:cost:view', 'tenant:finance:cost:manage']) AS permission_code
|
|
) item
|
|
WHERE template."TemplateCode" = 'tenant-admin'
|
|
AND template."DeletedAt" IS NULL
|
|
ON CONFLICT ("RoleTemplateId", "PermissionCode") DO UPDATE
|
|
SET "DeletedAt" = NULL,
|
|
"DeletedBy" = NULL,
|
|
"UpdatedAt" = NOW();
|
|
END $$;
|
|
""");
|
|
}
|
|
|
|
/// <inheritdoc />
|
|
protected override void Down(MigrationBuilder migrationBuilder)
|
|
{
|
|
migrationBuilder.Sql(
|
|
"""
|
|
DO $$
|
|
BEGIN
|
|
DELETE FROM public.role_permissions
|
|
WHERE "PermissionId" IN (
|
|
SELECT "Id"
|
|
FROM public.permissions
|
|
WHERE "Code" IN ('tenant:finance:cost:view', 'tenant:finance:cost:manage'));
|
|
|
|
DELETE FROM public.role_template_permissions
|
|
WHERE "PermissionCode" IN ('tenant:finance:cost:view', 'tenant:finance:cost:manage');
|
|
|
|
DELETE FROM public.menu_definitions
|
|
WHERE "Portal" = 1 AND "Path" = '/finance/cost';
|
|
|
|
DELETE FROM public.permissions
|
|
WHERE "Code" IN ('tenant:finance:cost:view', 'tenant:finance:cost:manage');
|
|
END $$;
|
|
""");
|
|
}
|
|
}
|