From 12b749d7d86f1832404b6d2c1f57215733216b71 Mon Sep 17 00:00:00 2001 From: ouyangxq <775153912@qq.com> Date: Thu, 3 Sep 2026 10:12:08 +0800 Subject: [PATCH] fix(iam): grant domestic order export permission --- deploy/sql/头程数据库统一增量-MySQL8.sql | 32 +++++++++++---- .../main/resources/db/phase1-admin-rbac.sql | 13 +++--- .../db/platform-order-export-permission.sql | 9 ++++ ...eOrderExportPermissionSqlContractTest.java | 41 +++++++++++++++++++ 4 files changed, 82 insertions(+), 13 deletions(-) create mode 100644 order/src/test/java/com/baiyue/order/controller/DomesticWarehouseOrderExportPermissionSqlContractTest.java diff --git a/deploy/sql/头程数据库统一增量-MySQL8.sql b/deploy/sql/头程数据库统一增量-MySQL8.sql index cd224e64f..a526e13f1 100644 --- a/deploy/sql/头程数据库统一增量-MySQL8.sql +++ b/deploy/sql/头程数据库统一增量-MySQL8.sql @@ -1291,24 +1291,25 @@ ON DUPLICATE KEY UPDATE permission_name = VALUES(permission_name), route_path = VALUES(route_path), http_method = NULL, sort_no = VALUES(sort_no), status = 'ACTIVE', deleted = 0; --- 平台代客创建、编辑草稿权限;可重复执行并纳入已有平台管理员和订单运营角色授权。 +-- 平台订单写入与导出权限;可重复执行并纳入已有平台管理员和订单运营角色授权。 INSERT INTO iam_permission (id, tenant_id, app_code, permission_type, parent_id, permission_code, permission_name, route_path, http_method, sort_no, status, deleted) VALUES (5102019, 0, 'PLATFORM', 'BUTTON', 5102010, 'platform:order:create', '平台代客创建订单', NULL, NULL, 90, 'ACTIVE', 0), (5102024, 0, 'PLATFORM', 'BUTTON', 5102010, 'platform:order:edit', '平台编辑订单草稿', NULL, NULL, 100, 'ACTIVE', 0), - (5102025, 0, 'PLATFORM', 'BUTTON', 5102010, 'platform:order:submit', '平台代客提交订单', NULL, NULL, 110, 'ACTIVE', 0) + (5102025, 0, 'PLATFORM', 'BUTTON', 5102010, 'platform:order:submit', '平台代客提交订单', NULL, NULL, 110, 'ACTIVE', 0), + (5102026, 0, 'PLATFORM', 'BUTTON', 5102010, 'platform:order:export', '导出订单列表', NULL, NULL, 120, 'ACTIVE', 0) ON DUPLICATE KEY UPDATE permission_name = VALUES(permission_name), parent_id = VALUES(parent_id), status = 'ACTIVE', deleted = 0; INSERT INTO iam_role_permission (role_id, permission_id, tenant_id) SELECT 4000001, id, 0 FROM iam_permission -WHERE id IN (5102019, 5102024, 5102025) +WHERE id IN (5102019, 5102024, 5102025, 5102026) ON DUPLICATE KEY UPDATE tenant_id = VALUES(tenant_id); INSERT INTO iam_role_permission (role_id, permission_id, tenant_id) SELECT 4000003, id, 0 FROM iam_permission -WHERE id IN (5102019, 5102024, 5102025) +WHERE id IN (5102019, 5102024, 5102025, 5102026) ON DUPLICATE KEY UPDATE tenant_id = VALUES(tenant_id); INSERT INTO iam_membership_role (membership_id, role_id, tenant_id) VALUES @@ -1333,7 +1334,9 @@ ON DUPLICATE KEY UPDATE tenant_id = VALUES(tenant_id); INSERT INTO iam_role_permission (role_id, permission_id, tenant_id) SELECT 4000003, id, 0 FROM iam_permission -WHERE permission_code LIKE 'platform:order%' OR permission_code LIKE 'platform:firstleg%' +WHERE permission_code LIKE 'platform:order%' + OR permission_code LIKE 'platform:firstleg%' + OR permission_code = 'platform:download:list' ON DUPLICATE KEY UPDATE tenant_id = VALUES(tenant_id); INSERT INTO iam_data_scope (id, role_id, tenant_id, scope_type, scope_expression) VALUES @@ -14976,9 +14979,11 @@ BEGIN END IF; IF (SELECT COUNT(*) FROM baiyue_iam.iam_permission WHERE tenant_id = 0 AND app_code = 'PLATFORM' - AND ((id = 5103040 AND permission_code = 'platform:download:list' + AND ((id = 5102026 AND permission_code = 'platform:order:export' + AND permission_name = '导出订单列表' AND parent_id = 5102010) + OR (id = 5103040 AND permission_code = 'platform:download:list' AND permission_name = '下载中心' AND route_path = '/downloads') - OR (id = 5103041 AND permission_code = 'platform:download:all' AND parent_id = 5103040))) <> 2 + OR (id = 5103041 AND permission_code = 'platform:download:all' AND parent_id = 5103040))) <> 3 OR (SELECT COUNT(*) FROM baiyue_iam.iam_permission WHERE tenant_id = 0 AND app_code = 'PLATFORM' AND ((id = 5103060 AND permission_code = 'platform:location:list' AND parent_id = 5103000) @@ -14987,7 +14992,18 @@ BEGIN OR (id = 5103063 AND permission_code = 'platform:location:status' AND parent_id = 5103060) OR (id = 5103064 AND permission_code = 'platform:location:delete' AND parent_id = 5103060))) <> 5 THEN SIGNAL SQLSTATE '45000' - SET MESSAGE_TEXT = '统一迁移失败:下载中心或库位权限语义未修复'; + SET MESSAGE_TEXT = '统一迁移失败:订单导出、下载中心或库位权限语义未修复'; + END IF; + IF (SELECT COUNT(DISTINCT CONCAT(r.role_code, ':', p.permission_code)) + FROM baiyue_iam.iam_role_permission rp + JOIN baiyue_iam.iam_role r ON r.id = rp.role_id AND r.tenant_id = rp.tenant_id + JOIN baiyue_iam.iam_permission p ON p.id = rp.permission_id AND p.tenant_id = rp.tenant_id + WHERE r.tenant_id = 0 AND r.app_code = 'PLATFORM' + AND r.role_code IN ('PLATFORM_ADMIN', 'ORDER_OPERATOR') + AND p.permission_code IN ('platform:order:export', 'platform:download:list') + AND p.status = 'ACTIVE' AND p.deleted = 0) <> 4 THEN + SIGNAL SQLSTATE '45000' + SET MESSAGE_TEXT = '统一迁移失败:管理员或订单运营角色缺少订单导出与下载中心权限'; END IF; IF (SELECT COUNT(*) FROM baiyue_iam.iam_permission WHERE tenant_id = 0 AND app_code = 'PLATFORM' diff --git a/iam/src/main/resources/db/phase1-admin-rbac.sql b/iam/src/main/resources/db/phase1-admin-rbac.sql index 0f00deb81..a0be9fd0f 100644 --- a/iam/src/main/resources/db/phase1-admin-rbac.sql +++ b/iam/src/main/resources/db/phase1-admin-rbac.sql @@ -123,24 +123,25 @@ ON DUPLICATE KEY UPDATE permission_name = VALUES(permission_name), route_path = VALUES(route_path), http_method = NULL, sort_no = VALUES(sort_no), status = 'ACTIVE', deleted = 0; --- 平台代客创建、编辑草稿权限;可重复执行并纳入已有平台管理员和订单运营角色授权。 +-- 平台订单写入与导出权限;可重复执行并纳入已有平台管理员和订单运营角色授权。 INSERT INTO iam_permission (id, tenant_id, app_code, permission_type, parent_id, permission_code, permission_name, route_path, http_method, sort_no, status, deleted) VALUES (5102019, 0, 'PLATFORM', 'BUTTON', 5102010, 'platform:order:create', '平台代客创建订单', NULL, NULL, 90, 'ACTIVE', 0), (5102024, 0, 'PLATFORM', 'BUTTON', 5102010, 'platform:order:edit', '平台编辑订单草稿', NULL, NULL, 100, 'ACTIVE', 0), - (5102025, 0, 'PLATFORM', 'BUTTON', 5102010, 'platform:order:submit', '平台代客提交订单', NULL, NULL, 110, 'ACTIVE', 0) + (5102025, 0, 'PLATFORM', 'BUTTON', 5102010, 'platform:order:submit', '平台代客提交订单', NULL, NULL, 110, 'ACTIVE', 0), + (5102026, 0, 'PLATFORM', 'BUTTON', 5102010, 'platform:order:export', '导出订单列表', NULL, NULL, 120, 'ACTIVE', 0) ON DUPLICATE KEY UPDATE permission_name = VALUES(permission_name), parent_id = VALUES(parent_id), status = 'ACTIVE', deleted = 0; INSERT INTO iam_role_permission (role_id, permission_id, tenant_id) SELECT 4000001, id, 0 FROM iam_permission -WHERE id IN (5102019, 5102024, 5102025) +WHERE id IN (5102019, 5102024, 5102025, 5102026) ON DUPLICATE KEY UPDATE tenant_id = VALUES(tenant_id); INSERT INTO iam_role_permission (role_id, permission_id, tenant_id) SELECT 4000003, id, 0 FROM iam_permission -WHERE id IN (5102019, 5102024, 5102025) +WHERE id IN (5102019, 5102024, 5102025, 5102026) ON DUPLICATE KEY UPDATE tenant_id = VALUES(tenant_id); INSERT INTO iam_membership_role (membership_id, role_id, tenant_id) VALUES @@ -165,7 +166,9 @@ ON DUPLICATE KEY UPDATE tenant_id = VALUES(tenant_id); INSERT INTO iam_role_permission (role_id, permission_id, tenant_id) SELECT 4000003, id, 0 FROM iam_permission -WHERE permission_code LIKE 'platform:order%' OR permission_code LIKE 'platform:firstleg%' +WHERE permission_code LIKE 'platform:order%' + OR permission_code LIKE 'platform:firstleg%' + OR permission_code = 'platform:download:list' ON DUPLICATE KEY UPDATE tenant_id = VALUES(tenant_id); INSERT INTO iam_data_scope (id, role_id, tenant_id, scope_type, scope_expression) VALUES diff --git a/order/src/main/resources/db/platform-order-export-permission.sql b/order/src/main/resources/db/platform-order-export-permission.sql index b273a4af6..bb343b653 100644 --- a/order/src/main/resources/db/platform-order-export-permission.sql +++ b/order/src/main/resources/db/platform-order-export-permission.sql @@ -15,3 +15,12 @@ INSERT INTO iam_role_permission (role_id, permission_id, tenant_id) SELECT role_id, 5102026, 0 FROM (SELECT 4000001 AS role_id UNION ALL SELECT 4000003 AS role_id) roles ON DUPLICATE KEY UPDATE tenant_id = VALUES(tenant_id); + +-- 订单运营角色创建导出任务后必须能够进入下载中心获取结果文件。 +INSERT INTO iam_role_permission (role_id, permission_id, tenant_id) +SELECT 4000003, id, 0 +FROM iam_permission +WHERE tenant_id = 0 AND app_code = 'PLATFORM' + AND permission_code = 'platform:download:list' + AND status = 'ACTIVE' AND deleted = 0 +ON DUPLICATE KEY UPDATE tenant_id = VALUES(tenant_id); diff --git a/order/src/test/java/com/baiyue/order/controller/DomesticWarehouseOrderExportPermissionSqlContractTest.java b/order/src/test/java/com/baiyue/order/controller/DomesticWarehouseOrderExportPermissionSqlContractTest.java new file mode 100644 index 000000000..f406b3d9e --- /dev/null +++ b/order/src/test/java/com/baiyue/order/controller/DomesticWarehouseOrderExportPermissionSqlContractTest.java @@ -0,0 +1,41 @@ +package com.baiyue.order.controller; + +import org.junit.jupiter.api.Test; +import org.springframework.core.io.ClassPathResource; + +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; + +import static org.assertj.core.api.Assertions.assertThat; + +class DomesticWarehouseOrderExportPermissionSqlContractTest { + + @Test + void keepsOrderExportPermissionAndDownloadGrantInAllInitializationEntrypoints() throws Exception { + String moduleSql = new ClassPathResource("db/platform-order-export-permission.sql") + .getContentAsString(StandardCharsets.UTF_8); + String iamSeed = Files.readString(resolve("iam/src/main/resources/db/phase1-admin-rbac.sql"), + StandardCharsets.UTF_8); + String unified = Files.readString(resolve("deploy/sql/头程数据库统一增量-MySQL8.sql"), + StandardCharsets.UTF_8); + + for (String sql : new String[] {moduleSql, iamSeed, unified}) { + assertThat(sql) + .contains("5102026") + .contains("platform:order:export") + .contains("导出订单列表") + .contains("platform:download:list") + .contains("4000003"); + } + assertThat(iamSeed).contains("WHERE id IN (5102019, 5102024, 5102025, 5102026)"); + assertThat(unified) + .contains("WHERE id IN (5102019, 5102024, 5102025, 5102026)") + .contains("管理员或订单运营角色缺少订单导出与下载中心权限"); + } + + private static Path resolve(String relative) { + Path direct = Path.of(relative); + return Files.exists(direct) ? direct : Path.of("..").resolve(relative); + } +}