diff --git a/deploy/postgres/README.md b/deploy/postgres/README.md index 4ebe378..74347b6 100644 --- a/deploy/postgres/README.md +++ b/deploy/postgres/README.md @@ -13,6 +13,7 @@ - `seed_tenant_customer_permissions.sql`:补齐租户端客户管理权限码、菜单权限与角色授权映射(可重复执行)。 - `seed_tenant_member_permissions.sql`:补齐租户端会员管理权限码、菜单权限与角色授权映射(可重复执行)。 - `seed_tenant_member_stored_card_permissions.sql`:补齐租户端会员储值卡权限码、菜单权限与角色授权映射(可重复执行)。 +- `seed_tenant_member_points_mall_permissions.sql`:补齐租户端积分商城权限码、菜单权限与角色授权映射(可重复执行)。 ## 前置条件 @@ -143,6 +144,20 @@ psql -h -p -U identity_user -d takeout_identity_db -f .\seed_tenan 2. 更新会员储值卡菜单 (`/member/stored-card/index`) 的 `RequiredPermissions`、`MetaPermissions` 与 `AuthListJson`。 3. 按订单列表权限映射补齐会员储值卡权限的角色模板与租户角色授权。 +## 积分商城权限补齐 + +在 `takeout_identity_db` 执行: + +```powershell +psql -h -p -U identity_user -d takeout_identity_db -f .\seed_tenant_member_points_mall_permissions.sql +``` + +脚本会完成: + +1. 新增/修正 `tenant:member:points-mall:*` 权限码(view/manage)。 +2. 更新积分商城菜单 (`/member/points-mall/index`) 的 `RequiredPermissions`、`MetaPermissions` 与 `AuthListJson`。 +3. 按会员模块权限映射补齐积分商城权限的角色模板与租户角色授权。 + ## 常见问题 | 问题 | 处理方式 | diff --git a/deploy/postgres/seed_tenant_member_message_reach_permissions.sql b/deploy/postgres/seed_tenant_member_message_reach_permissions.sql new file mode 100644 index 0000000..913b694 --- /dev/null +++ b/deploy/postgres/seed_tenant_member_message_reach_permissions.sql @@ -0,0 +1,287 @@ +-- 文件职责:补齐 Tenant 端会员消息触达权限与菜单绑定(可重复执行)。 +-- 执行范围:takeout_identity 数据库(Portal=1,Tenant 端)。 + +BEGIN; + +-- 1) 新增/修正会员消息触达权限码 +WITH message_reach_permissions(code, name, sort_order) AS ( + VALUES + ('tenant:member:message-reach:view', '查看会员消息触达', 48), + ('tenant:member:message-reach:manage', '管理会员消息触达', 49) +), +missing AS ( + SELECT + source.code, + source.name, + source.sort_order, + ROW_NUMBER() OVER (ORDER BY source.sort_order, source.code) AS rn + FROM message_reach_permissions source + LEFT JOIN public.permissions existing + ON existing."Code" = source.code + WHERE existing."Id" IS NULL +), +base AS ( + SELECT COALESCE(MAX("Id"), 820000000000000000) AS max_id + FROM public.permissions +), +parent AS ( + SELECT COALESCE( + ( + SELECT "Id" + FROM public.permissions + WHERE "Code" = 'tenant:member:view' + LIMIT 1 + ), + ( + SELECT "ParentId" + FROM public.permissions + WHERE "Code" = 'tenant:order:list:view' + LIMIT 1 + ), + 820000000000000004 + ) AS parent_id +) +INSERT INTO public.permissions +( + "Id", "Name", "Code", "Description", "CreatedAt", "UpdatedAt", "DeletedAt", + "CreatedBy", "UpdatedBy", "DeletedBy", "ParentId", "SortOrder", "Type", "Portal" +) +SELECT + base.max_id + missing.rn, + missing.name, + missing.code, + NULL, + NOW(), + NULL, + NULL, + NULL, + NULL, + NULL, + parent.parent_id, + missing.sort_order, + 'leaf', + 1 +FROM missing +CROSS JOIN base +CROSS JOIN parent; + +WITH message_reach_permissions(code, name, sort_order) AS ( + VALUES + ('tenant:member:message-reach:view', '查看会员消息触达', 48), + ('tenant:member:message-reach:manage', '管理会员消息触达', 49) +), +parent AS ( + SELECT COALESCE( + ( + SELECT "Id" + FROM public.permissions + WHERE "Code" = 'tenant:member:view' + LIMIT 1 + ), + ( + SELECT "ParentId" + FROM public.permissions + WHERE "Code" = 'tenant:order:list:view' + LIMIT 1 + ), + 820000000000000004 + ) AS parent_id +) +UPDATE public.permissions target +SET + "Name" = source.name, + "ParentId" = parent.parent_id, + "SortOrder" = source.sort_order, + "Type" = 'leaf', + "Portal" = 1, + "DeletedAt" = NULL, + "DeletedBy" = NULL, + "UpdatedAt" = NOW() +FROM message_reach_permissions source +CROSS JOIN parent +WHERE target."Code" = source.code; + +-- 2) 绑定会员消息触达菜单权限 +UPDATE public.menu_definitions +SET + "RequiredPermissions" = 'tenant:member:message-reach:view', + "MetaPermissions" = 'tenant:member:message-reach:view,tenant:member:message-reach:manage', + "AuthListJson" = '[{"title":"编辑","authMark":"tenant:member:message-reach:manage"}]', + "UpdatedAt" = NOW() +WHERE + "Portal" = 1 + AND ( + "Name" = 'MessageReach' + OR "Path" = 'message-reach' + OR "Component" = '/member/message-reach/index' + ); + +-- 3) 给角色模板补齐会员消息触达权限(按会员模块权限映射) +WITH code_mapping(source_code, target_code) AS ( + VALUES + ('tenant:member:view', 'tenant:member:message-reach:view'), + ('tenant:member:manage', 'tenant:member:message-reach:manage') +), +candidates AS ( + SELECT DISTINCT + source."RoleTemplateId", + mapping.target_code + FROM public.role_template_permissions source + INNER JOIN code_mapping mapping + ON mapping.source_code = source."PermissionCode" + WHERE source."DeletedAt" IS NULL +), +missing AS ( + SELECT + candidate."RoleTemplateId", + candidate.target_code, + ROW_NUMBER() OVER ( + ORDER BY candidate."RoleTemplateId", candidate.target_code + ) AS rn + FROM candidates candidate + LEFT JOIN public.role_template_permissions existing + ON existing."RoleTemplateId" = candidate."RoleTemplateId" + AND existing."PermissionCode" = candidate.target_code + WHERE existing."Id" IS NULL +), +base AS ( + SELECT COALESCE(MAX("Id"), 820000000000000000) AS max_id + FROM public.role_template_permissions +) +INSERT INTO public.role_template_permissions +( + "Id", "RoleTemplateId", "PermissionCode", "CreatedAt", "UpdatedAt", "DeletedAt", + "CreatedBy", "UpdatedBy", "DeletedBy" +) +SELECT + base.max_id + missing.rn, + missing."RoleTemplateId", + missing.target_code, + NOW(), + NULL, + NULL, + NULL, + NULL, + NULL +FROM missing +CROSS JOIN base; + +WITH code_mapping(source_code, target_code) AS ( + VALUES + ('tenant:member:view', 'tenant:member:message-reach:view'), + ('tenant:member:manage', 'tenant:member:message-reach:manage') +) +UPDATE public.role_template_permissions target +SET + "DeletedAt" = NULL, + "DeletedBy" = NULL, + "UpdatedAt" = NOW() +FROM public.role_template_permissions source +INNER JOIN code_mapping mapping + ON mapping.source_code = source."PermissionCode" +WHERE + source."RoleTemplateId" = target."RoleTemplateId" + AND target."PermissionCode" = mapping.target_code; + +-- 4) 给租户角色补齐会员消息触达权限(按会员模块权限映射) +WITH code_mapping(source_code, target_code) AS ( + VALUES + ('tenant:member:view', 'tenant:member:message-reach:view'), + ('tenant:member:manage', 'tenant:member:message-reach:manage') +), +source_rows AS ( + SELECT DISTINCT + source."RoleId", + source."TenantId", + source."Portal", + mapping.target_code + FROM public.role_permissions source + INNER JOIN public.permissions source_permission + ON source_permission."Id" = source."PermissionId" + INNER JOIN code_mapping mapping + ON mapping.source_code = source_permission."Code" + WHERE source."DeletedAt" IS NULL + AND source."Portal" = 1 +), +candidates AS ( + SELECT DISTINCT + source_row."RoleId", + source_row."TenantId", + source_row."Portal", + target_permission."Id" AS target_permission_id + FROM source_rows source_row + INNER JOIN public.permissions target_permission + ON target_permission."Code" = source_row.target_code +), +missing AS ( + SELECT + candidate."RoleId", + candidate."TenantId", + candidate."Portal", + candidate.target_permission_id, + ROW_NUMBER() OVER ( + ORDER BY candidate."TenantId", candidate."RoleId", candidate.target_permission_id + ) AS rn + FROM candidates candidate + LEFT JOIN public.role_permissions existing + ON existing."RoleId" = candidate."RoleId" + AND existing."PermissionId" = candidate.target_permission_id + AND existing."Portal" = candidate."Portal" + AND ( + (existing."TenantId" IS NULL AND candidate."TenantId" IS NULL) + OR existing."TenantId" = candidate."TenantId" + ) + WHERE existing."Id" IS NULL +), +base AS ( + SELECT COALESCE(MAX("Id"), 830000000000000000) AS max_id + FROM public.role_permissions +) +INSERT INTO public.role_permissions +( + "Id", "RoleId", "PermissionId", "CreatedAt", "UpdatedAt", "DeletedAt", + "CreatedBy", "UpdatedBy", "DeletedBy", "TenantId", "Portal" +) +SELECT + base.max_id + missing.rn, + missing."RoleId", + missing.target_permission_id, + NOW(), + NULL, + NULL, + NULL, + NULL, + NULL, + missing."TenantId", + missing."Portal" +FROM missing +CROSS JOIN base; + +WITH code_mapping(source_code, target_code) AS ( + VALUES + ('tenant:member:view', 'tenant:member:message-reach:view'), + ('tenant:member:manage', 'tenant:member:message-reach:manage') +) +UPDATE public.role_permissions target +SET + "DeletedAt" = NULL, + "DeletedBy" = NULL, + "UpdatedAt" = NOW() +FROM public.role_permissions source +INNER JOIN public.permissions source_permission + ON source_permission."Id" = source."PermissionId" +INNER JOIN code_mapping mapping + ON mapping.source_code = source_permission."Code" +INNER JOIN public.permissions target_permission + ON target_permission."Code" = mapping.target_code +WHERE + source."Portal" = 1 + AND target."Portal" = source."Portal" + AND target."RoleId" = source."RoleId" + AND target."PermissionId" = target_permission."Id" + AND ( + (target."TenantId" IS NULL AND source."TenantId" IS NULL) + OR target."TenantId" = source."TenantId" + ); + +COMMIT; diff --git a/deploy/postgres/seed_tenant_member_points_mall_permissions.sql b/deploy/postgres/seed_tenant_member_points_mall_permissions.sql new file mode 100644 index 0000000..eda1cde --- /dev/null +++ b/deploy/postgres/seed_tenant_member_points_mall_permissions.sql @@ -0,0 +1,287 @@ +-- 文件职责:补齐 Tenant 端积分商城权限与菜单绑定(可重复执行)。 +-- 执行范围:takeout_identity 数据库(Portal=1,Tenant 端)。 + +BEGIN; + +-- 1) 新增/修正积分商城权限码 +WITH points_mall_permissions(code, name, sort_order) AS ( + VALUES + ('tenant:member:points-mall:view', '查看积分商城', 50), + ('tenant:member:points-mall:manage', '管理积分商城', 51) +), +missing AS ( + SELECT + source.code, + source.name, + source.sort_order, + ROW_NUMBER() OVER (ORDER BY source.sort_order, source.code) AS rn + FROM points_mall_permissions source + LEFT JOIN public.permissions existing + ON existing."Code" = source.code + WHERE existing."Id" IS NULL +), +base AS ( + SELECT COALESCE(MAX("Id"), 820000000000000000) AS max_id + FROM public.permissions +), +parent AS ( + SELECT COALESCE( + ( + SELECT "Id" + FROM public.permissions + WHERE "Code" = 'tenant:member:view' + LIMIT 1 + ), + ( + SELECT "ParentId" + FROM public.permissions + WHERE "Code" = 'tenant:order:list:view' + LIMIT 1 + ), + 820000000000000004 + ) AS parent_id +) +INSERT INTO public.permissions +( + "Id", "Name", "Code", "Description", "CreatedAt", "UpdatedAt", "DeletedAt", + "CreatedBy", "UpdatedBy", "DeletedBy", "ParentId", "SortOrder", "Type", "Portal" +) +SELECT + base.max_id + missing.rn, + missing.name, + missing.code, + NULL, + NOW(), + NULL, + NULL, + NULL, + NULL, + NULL, + parent.parent_id, + missing.sort_order, + 'leaf', + 1 +FROM missing +CROSS JOIN base +CROSS JOIN parent; + +WITH points_mall_permissions(code, name, sort_order) AS ( + VALUES + ('tenant:member:points-mall:view', '查看积分商城', 50), + ('tenant:member:points-mall:manage', '管理积分商城', 51) +), +parent AS ( + SELECT COALESCE( + ( + SELECT "Id" + FROM public.permissions + WHERE "Code" = 'tenant:member:view' + LIMIT 1 + ), + ( + SELECT "ParentId" + FROM public.permissions + WHERE "Code" = 'tenant:order:list:view' + LIMIT 1 + ), + 820000000000000004 + ) AS parent_id +) +UPDATE public.permissions target +SET + "Name" = source.name, + "ParentId" = parent.parent_id, + "SortOrder" = source.sort_order, + "Type" = 'leaf', + "Portal" = 1, + "DeletedAt" = NULL, + "DeletedBy" = NULL, + "UpdatedAt" = NOW() +FROM points_mall_permissions source +CROSS JOIN parent +WHERE target."Code" = source.code; + +-- 2) 绑定积分商城菜单权限 +UPDATE public.menu_definitions +SET + "RequiredPermissions" = 'tenant:member:points-mall:view', + "MetaPermissions" = 'tenant:member:points-mall:view,tenant:member:points-mall:manage', + "AuthListJson" = '[{"title":"编辑","authMark":"tenant:member:points-mall:manage"}]', + "UpdatedAt" = NOW() +WHERE + "Portal" = 1 + AND ( + "Name" = 'PointsMall' + OR "Path" = 'points-mall' + OR "Component" = '/member/points-mall/index' + ); + +-- 3) 给角色模板补齐积分商城权限(按会员模块权限映射) +WITH code_mapping(source_code, target_code) AS ( + VALUES + ('tenant:member:view', 'tenant:member:points-mall:view'), + ('tenant:member:manage', 'tenant:member:points-mall:manage') +), +candidates AS ( + SELECT DISTINCT + source."RoleTemplateId", + mapping.target_code + FROM public.role_template_permissions source + INNER JOIN code_mapping mapping + ON mapping.source_code = source."PermissionCode" + WHERE source."DeletedAt" IS NULL +), +missing AS ( + SELECT + candidate."RoleTemplateId", + candidate.target_code, + ROW_NUMBER() OVER ( + ORDER BY candidate."RoleTemplateId", candidate.target_code + ) AS rn + FROM candidates candidate + LEFT JOIN public.role_template_permissions existing + ON existing."RoleTemplateId" = candidate."RoleTemplateId" + AND existing."PermissionCode" = candidate.target_code + WHERE existing."Id" IS NULL +), +base AS ( + SELECT COALESCE(MAX("Id"), 820000000000000000) AS max_id + FROM public.role_template_permissions +) +INSERT INTO public.role_template_permissions +( + "Id", "RoleTemplateId", "PermissionCode", "CreatedAt", "UpdatedAt", "DeletedAt", + "CreatedBy", "UpdatedBy", "DeletedBy" +) +SELECT + base.max_id + missing.rn, + missing."RoleTemplateId", + missing.target_code, + NOW(), + NULL, + NULL, + NULL, + NULL, + NULL +FROM missing +CROSS JOIN base; + +WITH code_mapping(source_code, target_code) AS ( + VALUES + ('tenant:member:view', 'tenant:member:points-mall:view'), + ('tenant:member:manage', 'tenant:member:points-mall:manage') +) +UPDATE public.role_template_permissions target +SET + "DeletedAt" = NULL, + "DeletedBy" = NULL, + "UpdatedAt" = NOW() +FROM public.role_template_permissions source +INNER JOIN code_mapping mapping + ON mapping.source_code = source."PermissionCode" +WHERE + source."RoleTemplateId" = target."RoleTemplateId" + AND target."PermissionCode" = mapping.target_code; + +-- 4) 给租户角色补齐积分商城权限(按会员模块权限映射) +WITH code_mapping(source_code, target_code) AS ( + VALUES + ('tenant:member:view', 'tenant:member:points-mall:view'), + ('tenant:member:manage', 'tenant:member:points-mall:manage') +), +source_rows AS ( + SELECT DISTINCT + source."RoleId", + source."TenantId", + source."Portal", + mapping.target_code + FROM public.role_permissions source + INNER JOIN public.permissions source_permission + ON source_permission."Id" = source."PermissionId" + INNER JOIN code_mapping mapping + ON mapping.source_code = source_permission."Code" + WHERE source."DeletedAt" IS NULL + AND source."Portal" = 1 +), +candidates AS ( + SELECT DISTINCT + source_row."RoleId", + source_row."TenantId", + source_row."Portal", + target_permission."Id" AS target_permission_id + FROM source_rows source_row + INNER JOIN public.permissions target_permission + ON target_permission."Code" = source_row.target_code +), +missing AS ( + SELECT + candidate."RoleId", + candidate."TenantId", + candidate."Portal", + candidate.target_permission_id, + ROW_NUMBER() OVER ( + ORDER BY candidate."TenantId", candidate."RoleId", candidate.target_permission_id + ) AS rn + FROM candidates candidate + LEFT JOIN public.role_permissions existing + ON existing."RoleId" = candidate."RoleId" + AND existing."PermissionId" = candidate.target_permission_id + AND existing."Portal" = candidate."Portal" + AND ( + (existing."TenantId" IS NULL AND candidate."TenantId" IS NULL) + OR existing."TenantId" = candidate."TenantId" + ) + WHERE existing."Id" IS NULL +), +base AS ( + SELECT COALESCE(MAX("Id"), 830000000000000000) AS max_id + FROM public.role_permissions +) +INSERT INTO public.role_permissions +( + "Id", "RoleId", "PermissionId", "CreatedAt", "UpdatedAt", "DeletedAt", + "CreatedBy", "UpdatedBy", "DeletedBy", "TenantId", "Portal" +) +SELECT + base.max_id + missing.rn, + missing."RoleId", + missing.target_permission_id, + NOW(), + NULL, + NULL, + NULL, + NULL, + NULL, + missing."TenantId", + missing."Portal" +FROM missing +CROSS JOIN base; + +WITH code_mapping(source_code, target_code) AS ( + VALUES + ('tenant:member:view', 'tenant:member:points-mall:view'), + ('tenant:member:manage', 'tenant:member:points-mall:manage') +) +UPDATE public.role_permissions target +SET + "DeletedAt" = NULL, + "DeletedBy" = NULL, + "UpdatedAt" = NOW() +FROM public.role_permissions source +INNER JOIN public.permissions source_permission + ON source_permission."Id" = source."PermissionId" +INNER JOIN code_mapping mapping + ON mapping.source_code = source_permission."Code" +INNER JOIN public.permissions target_permission + ON target_permission."Code" = mapping.target_code +WHERE + source."Portal" = 1 + AND target."Portal" = source."Portal" + AND target."RoleId" = source."RoleId" + AND target."PermissionId" = target_permission."Id" + AND ( + (target."TenantId" IS NULL AND source."TenantId" IS NULL) + OR target."TenantId" = source."TenantId" + ); + +COMMIT;