This commit is contained in:
2026-10-19 17:56:36 +08:00
parent bb917c954c
commit dcfba1053c
232 changed files with 15655 additions and 6005 deletions
@@ -31,7 +31,6 @@ VALUES
(5107011,0,'PLATFORM','BUTTON',5107010,'platform:overseas-warehouse:inbound-order:create','创建海外入仓计划',NULL,'POST',711,'ACTIVE',1,0),
(5107012,0,'PLATFORM','BUTTON',5107010,'platform:overseas-warehouse:inbound-order:edit','编辑海外入仓计划',NULL,'POST',712,'ACTIVE',1,0),
(5107013,0,'PLATFORM','BUTTON',5107010,'platform:overseas-warehouse:inbound-order:fba-appointment','FBA预约',NULL,'POST',713,'ACTIVE',1,0),
(5107014,0,'PLATFORM','BUTTON',5107010,'platform:overseas-warehouse:inbound-order:smart-dispatch','智能排车',NULL,'POST',714,'ACTIVE',1,0),
(5107015,0,'PLATFORM','BUTTON',5107010,'lastleg:pda:operate','海外仓PDA入仓作业',NULL,'POST',715,'ACTIVE',1,0),
(5107020,0,'PLATFORM','MENU',0,'platform:overseas-warehouse:relabel-order:list','海外换标单','/overseas-warehouse/relabel-orders','GET',720,'ACTIVE',1,0),
(5107021,0,'PLATFORM','BUTTON',5107020,'platform:overseas-warehouse:relabel-order:create','创建海外换标单',NULL,'POST',721,'ACTIVE',1,0),
@@ -283,8 +282,7 @@ SELECT 0, role.id, permission.id, NOW(3)
FROM iam_role role
JOIN iam_permission permission ON permission.tenant_id=0 AND permission.app_code='PLATFORM'
AND permission.permission_code IN (
'platform:overseas-warehouse:inbound-order:fba-appointment',
'platform:overseas-warehouse:inbound-order:smart-dispatch'
'platform:overseas-warehouse:inbound-order:fba-appointment'
)
WHERE role.tenant_id=0 AND role.app_code='PLATFORM'
AND UPPER(role.role_code)='PLATFORM_CUSTOM_ADMIN'
@@ -9,6 +9,9 @@ BEGIN
IF EXISTS (
SELECT 1 FROM iam_permission
WHERE (id = 5107064 AND permission_code <> 'platform:overseas-warehouse:dispatch:list')
OR (id = 5107065 AND permission_code <> 'platform:overseas-warehouse:dispatch:create')
OR (id = 5107066 AND permission_code <> 'platform:overseas-warehouse:dispatch:loading-complete')
OR (id = 5107067 AND permission_code <> 'platform:overseas-warehouse:dispatch:depart')
OR (id = 5107016 AND permission_code <> 'platform:overseas-warehouse:dispatch:edit')
OR (id = 5107017 AND permission_code <> 'platform:overseas-warehouse:dispatch:cancel')
OR (id = 5107018 AND permission_code <> 'platform:overseas-warehouse:dispatch:transfer-delivery')
@@ -25,10 +28,12 @@ BEGIN
OR (id = 5107081 AND permission_code <> 'platform:overseas-warehouse:customer-visit:edit')
OR (id = 5107082 AND permission_code <> 'platform:overseas-warehouse:delivery:status')
OR (id = 5306000 AND permission_code <> 'merchant:warehouse:delivery:list')
OR (id = 5306001 AND permission_code <> 'merchant:warehouse:delivery:create')
) OR EXISTS (
SELECT 1 FROM iam_permission
WHERE (permission_code = 'platform:overseas-warehouse:dispatch:list' AND id <> 5107064)
OR (permission_code = 'platform:overseas-warehouse:dispatch:create' AND id <> 5107065)
OR (permission_code = 'platform:overseas-warehouse:dispatch:loading-complete' AND id <> 5107066)
OR (permission_code = 'platform:overseas-warehouse:dispatch:depart' AND id <> 5107067)
OR (permission_code = 'platform:overseas-warehouse:dispatch:edit' AND id <> 5107016)
OR (permission_code = 'platform:overseas-warehouse:dispatch:cancel' AND id <> 5107017)
OR (permission_code = 'platform:overseas-warehouse:dispatch:transfer-delivery' AND id <> 5107018)
@@ -45,7 +50,6 @@ BEGIN
OR (permission_code = 'platform:overseas-warehouse:customer-visit:edit' AND id <> 5107081)
OR (permission_code = 'platform:overseas-warehouse:delivery:status' AND id <> 5107082)
OR (permission_code = 'merchant:warehouse:delivery:list' AND id <> 5306000)
OR (permission_code = 'merchant:warehouse:delivery:create' AND id <> 5306001)
) THEN
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT='五期海外派送权限初始化失败:权限ID或编码冲突';
END IF;
@@ -59,8 +63,11 @@ INSERT INTO iam_permission
permission_name, route_path, http_method, sort_no, status, built_in, deleted)
VALUES
(5107064,0,'PLATFORM','MENU',0,'platform:overseas-warehouse:dispatch:list','海外排车单','/overseas-warehouse/dispatches','GET',764,'ACTIVE',1,0),
(5107065,0,'PLATFORM','BUTTON',5107064,'platform:overseas-warehouse:dispatch:create','新增排车单',NULL,'POST',765,'ACTIVE',1,0),
(5107066,0,'PLATFORM','BUTTON',5107064,'platform:overseas-warehouse:dispatch:loading-complete','确认装车完成',NULL,'POST',766,'ACTIVE',1,0),
(5107067,0,'PLATFORM','BUTTON',5107064,'platform:overseas-warehouse:dispatch:depart','确认实际发车',NULL,'POST',767,'ACTIVE',1,0),
(5107016,0,'PLATFORM','BUTTON',5107064,'platform:overseas-warehouse:dispatch:edit','编辑海外排车',NULL,'PUT',716,'ACTIVE',1,0),
(5107017,0,'PLATFORM','BUTTON',5107064,'platform:overseas-warehouse:dispatch:cancel','取消海外排车',NULL,'DELETE',717,'ACTIVE',1,0),
(5107017,0,'PLATFORM','BUTTON',5107064,'platform:overseas-warehouse:dispatch:cancel','取消海外排车',NULL,'POST',717,'ACTIVE',1,0),
(5107018,0,'PLATFORM','BUTTON',5107064,'platform:overseas-warehouse:dispatch:transfer-delivery','排车转派送',NULL,'POST',718,'ACTIVE',1,0),
(5107070,0,'PLATFORM','MENU',0,'platform:overseas-warehouse:exception-order:list','海外异常订单','/overseas-warehouse/exception-orders','GET',770,'ACTIVE',1,0),
(5107071,0,'PLATFORM','BUTTON',5107070,'platform:overseas-warehouse:exception-order:create','新增海外异常订单',NULL,'POST',771,'ACTIVE',1,0),
@@ -74,8 +81,7 @@ VALUES
(5107092,0,'PLATFORM','MENU',0,'platform:overseas-warehouse:delivery:list','海外派送单','/overseas-warehouse/delivery-orders','GET',767,'ACTIVE',1,0),
(5107094,0,'PLATFORM','BUTTON',5107092,'platform:overseas-warehouse:delivery:documents','管理派送资料',NULL,'POST',769,'ACTIVE',1,0),
(5107093,0,'PLATFORM','BUTTON',5107090,'platform:overseas-warehouse:outbound:cancel','取消海外出库单',NULL,'POST',768,'ACTIVE',1,0),
(5306000,0,'MERCHANT','MENU',0,'merchant:warehouse:delivery:list','海外仓派送单','/orders/delivery','GET',60,'ACTIVE',1,0),
(5306001,0,'MERCHANT','BUTTON',5306000,'merchant:warehouse:delivery:create','创建海外仓派送单',NULL,'POST',10,'ACTIVE',1,0)
(5306000,0,'MERCHANT','MENU',0,'merchant:warehouse:delivery:list','海外仓派送单','/orders/delivery','GET',60,'ACTIVE',1,0)
ON DUPLICATE KEY UPDATE
permission_type=VALUES(permission_type), parent_id=VALUES(parent_id),
permission_name=VALUES(permission_name), route_path=VALUES(route_path),
@@ -92,6 +98,9 @@ SELECT 0, role.id, permission.id, CURRENT_TIMESTAMP(3)
AND role.status='ACTIVE' AND role.deleted=0
AND permission.permission_code IN (
'platform:overseas-warehouse:dispatch:list',
'platform:overseas-warehouse:dispatch:create',
'platform:overseas-warehouse:dispatch:loading-complete',
'platform:overseas-warehouse:dispatch:depart',
'platform:overseas-warehouse:dispatch:edit',
'platform:overseas-warehouse:dispatch:cancel',
'platform:overseas-warehouse:dispatch:transfer-delivery',
@@ -117,8 +126,7 @@ SELECT role.tenant_id, role.id, permission.id, CURRENT_TIMESTAMP(3)
WHERE role.tenant_id>0 AND role.app_code='MERCHANT' AND role.role_code='MERCHANT_OWNER'
AND role.status='ACTIVE' AND role.deleted=0
AND permission.permission_code IN (
'merchant:warehouse:delivery:list',
'merchant:warehouse:delivery:create')
'merchant:warehouse:delivery:list')
AND permission.status='ACTIVE' AND permission.deleted=0;
-- 仓库后台岗位按最小职责授权;PDA 岗位不得获得后台排车、出库或派送权限。
@@ -130,6 +138,9 @@ CREATE TEMPORARY TABLE tmp_phase5_delivery_role_permission (
) ENGINE=MEMORY;
INSERT INTO tmp_phase5_delivery_role_permission (role_code, permission_code) VALUES
('WAREHOUSE_OPERATOR','platform:overseas-warehouse:dispatch:list'),
('WAREHOUSE_OPERATOR','platform:overseas-warehouse:dispatch:create'),
('WAREHOUSE_OPERATOR','platform:overseas-warehouse:dispatch:loading-complete'),
('WAREHOUSE_OPERATOR','platform:overseas-warehouse:dispatch:depart'),
('WAREHOUSE_OPERATOR','platform:overseas-warehouse:dispatch:edit'),
('WAREHOUSE_OPERATOR','platform:overseas-warehouse:dispatch:cancel'),
('WAREHOUSE_OPERATOR','platform:overseas-warehouse:dispatch:transfer-delivery'),
@@ -160,6 +171,9 @@ WHERE role.tenant_id=0 AND role.app_code='PLATFORM'
AND role.role_code IN ('WAREHOUSE_OPERATOR','WAREHOUSE_TALLY','OVERSEAS_WAREHOUSE_PDA_OPERATOR','CN_FIRSTLEG_PDA_OPERATOR')
AND permission.permission_code IN (
'platform:overseas-warehouse:dispatch:list',
'platform:overseas-warehouse:dispatch:create',
'platform:overseas-warehouse:dispatch:loading-complete',
'platform:overseas-warehouse:dispatch:depart',
'platform:overseas-warehouse:dispatch:edit',
'platform:overseas-warehouse:dispatch:cancel',
'platform:overseas-warehouse:dispatch:transfer-delivery',
@@ -186,7 +200,7 @@ SELECT 0, role.id, permission.id, CURRENT_TIMESTAMP(3)
AND permission.permission_code=expected.permission_code
AND permission.status='ACTIVE' AND permission.deleted=0;
-- 客户默认管理员获得派送列表/详情只读及独立创建;其他客户角色不自动扩权。
-- 客户默认管理员只获得派送列表和详情读取;整车派送由平台统一安排。
INSERT IGNORE INTO iam_role_permission (tenant_id, role_id, permission_id, created_at)
SELECT 0, role.id, permission.id, CURRENT_TIMESTAMP(3)
FROM iam_role role
@@ -194,8 +208,7 @@ SELECT 0, role.id, permission.id, CURRENT_TIMESTAMP(3)
WHERE role.tenant_id=0 AND role.app_code='MERCHANT' AND role.role_code='MERCHANT_OWNER'
AND role.status='ACTIVE' AND role.deleted=0
AND permission.permission_code IN (
'merchant:warehouse:delivery:list',
'merchant:warehouse:delivery:create')
'merchant:warehouse:delivery:list')
AND permission.status='ACTIVE' AND permission.deleted=0;
DROP PROCEDURE IF EXISTS assert_phase5_delivery_permissions;
@@ -209,6 +222,9 @@ BEGIN
WHERE tenant_id=0 AND status='ACTIVE' AND deleted=0
AND permission_code IN (
'platform:overseas-warehouse:dispatch:list',
'platform:overseas-warehouse:dispatch:create',
'platform:overseas-warehouse:dispatch:loading-complete',
'platform:overseas-warehouse:dispatch:depart',
'platform:overseas-warehouse:dispatch:edit',
'platform:overseas-warehouse:dispatch:cancel',
'platform:overseas-warehouse:dispatch:transfer-delivery',
@@ -224,8 +240,7 @@ BEGIN
'platform:overseas-warehouse:delivery:documents',
'platform:overseas-warehouse:customer-visit:list',
'platform:overseas-warehouse:customer-visit:edit',
'merchant:warehouse:delivery:list',
'merchant:warehouse:delivery:create')) <> 18 THEN
'merchant:warehouse:delivery:list')) <> 20 THEN
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT='五期海外派送权限初始化失败:权限目录不完整';
END IF;
IF (SELECT COUNT(*) FROM iam_role_permission grant_row
@@ -234,6 +249,9 @@ BEGIN
WHERE role.role_code='PLATFORM_ADMIN'
AND permission.permission_code IN (
'platform:overseas-warehouse:dispatch:list',
'platform:overseas-warehouse:dispatch:create',
'platform:overseas-warehouse:dispatch:loading-complete',
'platform:overseas-warehouse:dispatch:depart',
'platform:overseas-warehouse:dispatch:edit',
'platform:overseas-warehouse:dispatch:cancel',
'platform:overseas-warehouse:dispatch:transfer-delivery',
@@ -248,7 +266,7 @@ BEGIN
'platform:overseas-warehouse:delivery:status',
'platform:overseas-warehouse:delivery:documents',
'platform:overseas-warehouse:customer-visit:list',
'platform:overseas-warehouse:customer-visit:edit')) <> 16 THEN
'platform:overseas-warehouse:customer-visit:edit')) <> 19 THEN
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT='五期海外派送权限初始化失败:平台管理员授权不完整';
END IF;
IF EXISTS (SELECT 1 FROM iam_role role
@@ -260,6 +278,9 @@ BEGIN
WHERE grant_row.role_id=role.id AND grant_row.tenant_id=role.tenant_id
AND permission.permission_code IN (
'platform:overseas-warehouse:dispatch:list',
'platform:overseas-warehouse:dispatch:create',
'platform:overseas-warehouse:dispatch:loading-complete',
'platform:overseas-warehouse:dispatch:depart',
'platform:overseas-warehouse:dispatch:edit',
'platform:overseas-warehouse:dispatch:cancel',
'platform:overseas-warehouse:dispatch:transfer-delivery',
@@ -274,14 +295,14 @@ BEGIN
'platform:overseas-warehouse:delivery:status',
'platform:overseas-warehouse:delivery:documents',
'platform:overseas-warehouse:customer-visit:list',
'platform:overseas-warehouse:customer-visit:edit')) <> 16) THEN
'platform:overseas-warehouse:customer-visit:edit')) <> 19) THEN
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT='五期海外派送权限初始化失败:平台自定义管理员授权不完整';
END IF;
SELECT COALESCE(SUM(role_code='WAREHOUSE_OPERATOR'),0),
COALESCE(SUM(role_code='WAREHOUSE_TALLY'),0)
INTO v_warehouse_operator_permission_count, v_warehouse_tally_permission_count
FROM tmp_phase5_delivery_role_permission;
IF v_warehouse_operator_permission_count <> 16
IF v_warehouse_operator_permission_count <> 19
OR v_warehouse_tally_permission_count <> 5 THEN
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT='五期海外派送权限初始化失败:仓库岗位最小权限矩阵异常';
END IF;
@@ -291,6 +312,9 @@ BEGIN
WHERE role.role_code IN ('OVERSEAS_WAREHOUSE_PDA_OPERATOR','CN_FIRSTLEG_PDA_OPERATOR')
AND permission.permission_code IN (
'platform:overseas-warehouse:dispatch:list',
'platform:overseas-warehouse:dispatch:create',
'platform:overseas-warehouse:dispatch:loading-complete',
'platform:overseas-warehouse:dispatch:depart',
'platform:overseas-warehouse:dispatch:edit',
'platform:overseas-warehouse:dispatch:cancel',
'platform:overseas-warehouse:dispatch:transfer-delivery',
@@ -313,11 +337,10 @@ BEGIN
ON grant_row.role_id=role.id AND grant_row.tenant_id=role.tenant_id
LEFT JOIN iam_permission permission ON permission.id=grant_row.permission_id
AND permission.permission_code IN (
'merchant:warehouse:delivery:list',
'merchant:warehouse:delivery:create')
'merchant:warehouse:delivery:list')
WHERE role.role_code='MERCHANT_OWNER' AND role.app_code='MERCHANT'
AND role.status='ACTIVE' AND role.deleted=0
GROUP BY role.id HAVING COUNT(DISTINCT permission.permission_code) <> 2) THEN
GROUP BY role.id HAVING COUNT(DISTINCT permission.permission_code) <> 1) THEN
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT='五期海外派送权限初始化失败:客户默认管理员授权不完整';
END IF;
END$$
+2 -2
View File
@@ -146,7 +146,7 @@ paths:
get:
tags: [IAM Resources / IAM 资源]
summary: 查询当前用户有效权限
description: 返回当前有效平台成员权限编码;只要求有效 PLATFORM JWT,不依赖 `platform:role:list`。入库单扣货与解除扣货返回独立写权限 `platform:firstleg:inbound:hold`,不会由 `platform:firstleg:inbound:list` 查看权限自动获得。资金账户充值审核与手工调账分别返回 `platform:finance:recharge:review`、`platform:finance:customer-account:adjust`,并与 `platform:finance:customer-account:list` 只读权限分离。海外仓返回 `platform:overseas-warehouse:dispatch:list`、`platform:overseas-warehouse:dispatch:edit`、`platform:overseas-warehouse:dispatch:cancel`、`platform:overseas-warehouse:dispatch:transfer-delivery`、`platform:overseas-warehouse:outbound:list`、`platform:overseas-warehouse:outbound:create`、`platform:overseas-warehouse:outbound:cancel`、`platform:overseas-warehouse:delivery:list`、`platform:overseas-warehouse:delivery:return`、`platform:overseas-warehouse:delivery:status`、`platform:overseas-warehouse:delivery:documents`、`platform:overseas-warehouse:exception-order:list`、`platform:overseas-warehouse:exception-order:create`、`platform:overseas-warehouse:exception-order:process`、`platform:overseas-warehouse:customer-visit:list`、`platform:overseas-warehouse:customer-visit:edit`;海外 PDA 盘点、移库、换标和现场查询统一返回 `lastleg:pda:operate`,且仅限 `OVERSEAS_WAREHOUSE_PDA_OPERATOR`。货柜双工作台以 `platform:firstleg:container:list/create/edit` 维护国内送柜报关,国外清关提柜独立返回 `platform:firstleg:terminal-drayage:list`、`platform:firstleg:terminal-drayage:document:edit`、`platform:firstleg:terminal-drayage:fleet:edit`、`platform:firstleg:terminal-drayage:pickup-appointment:edit`、`platform:firstleg:terminal-drayage:empty-return:confirm`,不以 `container:list/edit` 兼容放行国外操作。派送三类资料管理使用独立写权限 `platform:overseas-warehouse:delivery:documents`;读取和下载仍使用 `platform:overseas-warehouse:delivery:list`。列表权限包含详情和只读辅助接口,写操作独立授权。
description: 返回当前有效平台成员权限编码;只要求有效 PLATFORM JWT,不依赖 `platform:role:list`。入库单扣货与解除扣货返回独立写权限 `platform:firstleg:inbound:hold`,不会由 `platform:firstleg:inbound:list` 查看权限自动获得。资金账户充值审核与手工调账分别返回 `platform:finance:recharge:review`、`platform:finance:customer-account:adjust`,并与 `platform:finance:customer-account:list` 只读权限分离。海外仓返回 `platform:overseas-warehouse:dispatch:list`、`platform:overseas-warehouse:dispatch:create`、`platform:overseas-warehouse:dispatch:loading-complete`、`platform:overseas-warehouse:dispatch:depart`、`platform:overseas-warehouse:dispatch:edit`、`platform:overseas-warehouse:dispatch:cancel`、`platform:overseas-warehouse:dispatch:transfer-delivery`、`platform:overseas-warehouse:outbound:list`、`platform:overseas-warehouse:outbound:create`、`platform:overseas-warehouse:outbound:cancel`、`platform:overseas-warehouse:delivery:list`、`platform:overseas-warehouse:delivery:return`、`platform:overseas-warehouse:delivery:status`、`platform:overseas-warehouse:delivery:documents`、`platform:overseas-warehouse:exception-order:list`、`platform:overseas-warehouse:exception-order:create`、`platform:overseas-warehouse:exception-order:process`、`platform:overseas-warehouse:customer-visit:list`、`platform:overseas-warehouse:customer-visit:edit`;海外 PDA 盘点、移库、换标和现场查询统一返回 `lastleg:pda:operate`,且仅限 `OVERSEAS_WAREHOUSE_PDA_OPERATOR`。货柜双工作台以 `platform:firstleg:container:list/create/edit` 维护国内送柜报关,国外清关提柜独立返回 `platform:firstleg:terminal-drayage:list`、`platform:firstleg:terminal-drayage:document:edit`、`platform:firstleg:terminal-drayage:fleet:edit`、`platform:firstleg:terminal-drayage:pickup-appointment:edit`、`platform:firstleg:terminal-drayage:empty-return:confirm`,不以 `container:list/edit` 兼容放行国外操作。派送三类资料管理使用独立写权限 `platform:overseas-warehouse:delivery:documents`;读取和下载仍使用 `platform:overseas-warehouse:delivery:list`。列表权限包含详情和只读辅助接口,写操作独立授权。
responses:
'200':
description: 当前平台成员权限查询成功
@@ -364,7 +364,7 @@ paths:
get:
tags: [IAM Resources / IAM 资源]
summary: 查询当前用户有效权限
description: 返回当前有效客户成员权限编码。资金账户和流水只读返回 `merchant:finance:account:view`,提交充值申请返回 `merchant:finance:recharge:create`,两者独立授权。海外采购、本土卡、本土散板的列表入口分别返回 `merchant:cross-border:procurement:list`、`merchant:cross-border:domestic-trucking:list`、`merchant:cross-border:pallet-shipping:list`,创建和编辑另行授权;海外仓入库返回 `merchant:warehouse:inbound:list`,尾程订单、换标、转运、废弃、退货预报和退货库存均返回各自 `merchant:overseas-warehouse:*` 权限。客户派送返回 `merchant:warehouse:delivery:list` 和 `merchant:warehouse:delivery:create`。列表权限包含详情只读,创建、文件、确认、取消和转换操作独立授权。
description: 返回当前有效客户成员权限编码。资金账户和流水只读返回 `merchant:finance:account:view`,提交充值申请返回 `merchant:finance:recharge:create`,两者独立授权。海外采购、本土卡、本土散板的列表入口分别返回 `merchant:cross-border:procurement:list`、`merchant:cross-border:domestic-trucking:list`、`merchant:cross-border:pallet-shipping:list`,创建和编辑另行授权;海外仓入库返回 `merchant:warehouse:inbound:list`,尾程订单、换标、转运、废弃、退货预报和退货库存均返回各自 `merchant:overseas-warehouse:*` 权限。客户派送仅返回 `merchant:warehouse:delivery:list`,整车派送由平台统一安排。列表权限包含详情只读,创建、文件、确认、取消和转换操作独立授权。
responses:
'200':
description: 当前商户成员权限查询成功
@@ -10,6 +10,7 @@ import java.util.Map;
import static org.assertj.core.api.Assertions.assertThat;
class IamOpenApiContractTest {
/** 核对当前授权接口公开说明,整车写权限独立且客户派送只读。 */
@Test
void shouldHandleCase01() throws IOException {
String document;
@@ -21,6 +22,9 @@ class IamOpenApiContractTest {
assertThat(document).contains("/api/platform/v1/iam/authorization/permissions:")
.contains("/api/merchant/v1/iam/authorization/permissions:")
.contains("platform:overseas-warehouse:dispatch:list")
.contains("platform:overseas-warehouse:dispatch:create")
.contains("platform:overseas-warehouse:dispatch:loading-complete")
.contains("platform:overseas-warehouse:dispatch:depart")
.contains("platform:overseas-warehouse:dispatch:edit")
.contains("platform:overseas-warehouse:dispatch:cancel")
.contains("platform:overseas-warehouse:dispatch:transfer-delivery")
@@ -45,7 +49,7 @@ class IamOpenApiContractTest {
.contains("platform:firstleg:terminal-drayage:empty-return:confirm")
.contains("不以 `container:list/edit` 兼容放行国外操作")
.contains("merchant:warehouse:delivery:list")
.contains("merchant:warehouse:delivery:create")
.doesNotContain("merchant:warehouse:delivery:create")
.contains("merchant:cross-border:procurement:list")
.contains("merchant:cross-border:domestic-trucking:list")
.contains("merchant:cross-border:pallet-shipping:list")
@@ -39,8 +39,7 @@ class OverseasPhase4PermissionSqlContractTest {
private static final Pattern CANONICAL = Pattern.compile("platform:overseas-[a-z0-9:-]+");
private static final Set<String> CUSTOM_ADMIN_PERMISSIONS = Set.of(
"platform:overseas-warehouse:inbound-order:fba-appointment",
"platform:overseas-warehouse:inbound-order:smart-dispatch");
"platform:overseas-warehouse:inbound-order:fba-appointment");
private static final List<String> REQUIRED = List.of(
"platform:overseas-warehouse:last-mile-order:list",
"platform:overseas-warehouse:discard:list",
@@ -48,7 +47,6 @@ class OverseasPhase4PermissionSqlContractTest {
"platform:overseas-warehouse:warehouse-transfer:approve",
"platform:overseas-warehouse:inbound-order:list",
"platform:overseas-warehouse:inbound-order:fba-appointment",
"platform:overseas-warehouse:inbound-order:smart-dispatch",
"platform:overseas-warehouse:relabel-order:status",
"platform:overseas-warehouse:pallet:list",
"platform:overseas-warehouse:inventory:adjust",
@@ -77,7 +75,7 @@ class OverseasPhase4PermissionSqlContractTest {
assertThat(sql).contains(REQUIRED.toArray(String[]::new));
assertThat(sql).contains("'lastleg:pda:operate'");
assertPdaPickerGrant(sql);
assertThat(catalog).hasSize(71).noneMatch(code -> code.endsWith(":view"));
assertThat(catalog).hasSize(70).noneMatch(code -> code.endsWith(":view"));
assertThat(sql).contains(
"(5107003,0,'PLATFORM','BUTTON',5107000,'platform:overseas-warehouse:warehouse-transfer:approve'");
assertThat(sql).contains("CALL assert_warehouse_transfer_approval_permission()",
@@ -85,7 +83,8 @@ class OverseasPhase4PermissionSqlContractTest {
assertThat(sql).doesNotContain(
"'platform:overseas-warehouse:warehouse-transfer:list','仓储转运审核'");
assertThat(sql).contains("permission_code LIKE 'platform:lastleg:%'", "status='INACTIVE'", "deleted=1");
assertThat(sql).doesNotContain(":carton:", ":product:");
assertThat(sql).doesNotContain(":carton:", ":product:",
"platform:overseas-warehouse:inbound-order:smart-dispatch");
assertThat(catalog).contains("platform:overseas-warehouse:delivery:list");
assertCustomAdminGrant(sql);
assertCustomAdminNavigationGrant(sql);
@@ -16,6 +16,9 @@ class Phase5DeliveryPermissionSqlContractTest {
private static final Pattern CODE = Pattern.compile("(?:platform:overseas-warehouse|merchant:warehouse):[a-z0-9:-]+");
private static final Set<String> REQUIRED = Set.of(
"platform:overseas-warehouse:dispatch:list",
"platform:overseas-warehouse:dispatch:create",
"platform:overseas-warehouse:dispatch:loading-complete",
"platform:overseas-warehouse:dispatch:depart",
"platform:overseas-warehouse:dispatch:edit",
"platform:overseas-warehouse:dispatch:cancel",
"platform:overseas-warehouse:dispatch:transfer-delivery",
@@ -31,15 +34,16 @@ class Phase5DeliveryPermissionSqlContractTest {
"platform:overseas-warehouse:delivery:documents",
"platform:overseas-warehouse:customer-visit:list",
"platform:overseas-warehouse:customer-visit:edit",
"merchant:warehouse:delivery:list",
"merchant:warehouse:delivery:create");
"merchant:warehouse:delivery:list");
/** 核对整车权限目录只包含当前正式编码。 */
@Test
void definesOnlyTheFrozenPhase5DeliveryCatalogWithoutAliases() throws Exception {
String sql = sql();
assertThat(codes(sql)).containsExactlyInAnyOrderElementsOf(REQUIRED);
assertThat(codes(sql)).noneMatch(code -> code.endsWith(":view"));
assertThat(sql).doesNotContain("merchant:warehouse:delivery:create");
assertThat(sql).contains(
"guard_phase5_delivery_permission_ids",
"权限ID或编码冲突",
@@ -47,27 +51,32 @@ class Phase5DeliveryPermissionSqlContractTest {
"列表权限同时覆盖列表和详情只读");
}
/** 核对菜单、动作方法及独立装车发车权限。 */
@Test
void keepsMenuRoutesAndHttpMethodsAlignedWithTheFrozenAdminAndClientContracts() throws Exception {
String sql = sql();
assertThat(sql).contains(
"'platform:overseas-warehouse:dispatch:list','海外排车单','/overseas-warehouse/dispatches','GET'",
"'platform:overseas-warehouse:dispatch:cancel','取消海外排车',NULL,'DELETE'",
"'platform:overseas-warehouse:dispatch:cancel','取消海外排车',NULL,'POST'",
"'platform:overseas-warehouse:exception-order:list','海外异常订单','/overseas-warehouse/exception-orders','GET'",
"'platform:overseas-warehouse:exception-order:create','新增海外异常订单',NULL,'POST'",
"'platform:overseas-warehouse:exception-order:process','处理海外异常订单',NULL,'POST'",
"'platform:overseas-warehouse:delivery:return','派送单标记退货',NULL,'POST'",
"'platform:overseas-warehouse:delivery:status','编辑派送单状态',NULL,'PUT'",
"(5107065,0,'PLATFORM','BUTTON',5107064,'platform:overseas-warehouse:dispatch:create'",
"(5107066,0,'PLATFORM','BUTTON',5107064,'platform:overseas-warehouse:dispatch:loading-complete'",
"(5107067,0,'PLATFORM','BUTTON',5107064,'platform:overseas-warehouse:dispatch:depart'",
"(5107094,0,'PLATFORM','BUTTON',5107092,'platform:overseas-warehouse:delivery:documents','管理派送资料',NULL,'POST'",
"'platform:overseas-warehouse:customer-visit:list','客户回访','/overseas-warehouse/customer-visits','GET'",
"'platform:overseas-warehouse:customer-visit:edit','保存客户回访',NULL,'PUT'",
"'merchant:warehouse:delivery:list','海外仓派送单','/orders/delivery','GET'");
assertThat(sql).doesNotContain(
"'platform:overseas-warehouse:dispatch:cancel','取消海外排车',NULL,'POST'",
"'platform:overseas-warehouse:dispatch:cancel','取消海外排车',NULL,'DELETE'",
"'merchant:warehouse:delivery:list','海外仓派送单','/overseas-warehouse/delivery-orders'");
}
/** 核对后台操作岗位、理货只读岗位与PDA之间的最小授权边界。 */
@Test
void grantsAdministratorsAndWarehouseRolesByTheFrozenMinimumMatrix() throws Exception {
String sql = sql();
@@ -76,6 +85,9 @@ class Phase5DeliveryPermissionSqlContractTest {
"UPPER(role.role_code) IN ('PLATFORM_ADMIN','PLATFORM_CUSTOM_ADMIN')",
"tmp_phase5_delivery_role_permission",
"('WAREHOUSE_OPERATOR','platform:overseas-warehouse:dispatch:list')",
"('WAREHOUSE_OPERATOR','platform:overseas-warehouse:dispatch:create')",
"('WAREHOUSE_OPERATOR','platform:overseas-warehouse:dispatch:loading-complete')",
"('WAREHOUSE_OPERATOR','platform:overseas-warehouse:dispatch:depart')",
"('WAREHOUSE_OPERATOR','platform:overseas-warehouse:dispatch:edit')",
"('WAREHOUSE_OPERATOR','platform:overseas-warehouse:outbound:create')",
"('WAREHOUSE_OPERATOR','platform:overseas-warehouse:exception-order:create')",
@@ -92,6 +104,9 @@ class Phase5DeliveryPermissionSqlContractTest {
"role.role_code IN ('OVERSEAS_WAREHOUSE_PDA_OPERATOR','CN_FIRSTLEG_PDA_OPERATOR')",
"PDA岗位错误获得后台权限");
assertThat(sql).doesNotContain(
"('WAREHOUSE_TALLY','platform:overseas-warehouse:dispatch:create')",
"('WAREHOUSE_TALLY','platform:overseas-warehouse:dispatch:loading-complete')",
"('WAREHOUSE_TALLY','platform:overseas-warehouse:dispatch:depart')",
"('WAREHOUSE_TALLY','platform:overseas-warehouse:dispatch:edit')",
"('WAREHOUSE_TALLY','platform:overseas-warehouse:outbound:create')",
"('WAREHOUSE_TALLY','platform:overseas-warehouse:exception-order:create')",
@@ -104,6 +119,7 @@ class Phase5DeliveryPermissionSqlContractTest {
"('CN_FIRSTLEG_PDA_OPERATOR','platform:overseas-warehouse:");
}
/** 核对临时角色矩阵一次读取及完整性判断。 */
@Test
void validatesTheWarehouseRoleMatrixWithOneTemporaryTableReadPerStatement() throws Exception {
String sql = sql();
@@ -114,7 +130,7 @@ class Phase5DeliveryPermissionSqlContractTest {
"SELECT COALESCE(SUM(role_code='WAREHOUSE_OPERATOR'),0)",
"COALESCE(SUM(role_code='WAREHOUSE_TALLY'),0)",
"INTO v_warehouse_operator_permission_count, v_warehouse_tally_permission_count",
"IF v_warehouse_operator_permission_count <> 16",
"IF v_warehouse_operator_permission_count <> 19",
"OR v_warehouse_tally_permission_count <> 5 THEN",
"IF EXISTS (SELECT 1 FROM iam_role role",
"AND UPPER(role.role_code)='PLATFORM_CUSTOM_ADMIN'",
@@ -126,10 +142,11 @@ class Phase5DeliveryPermissionSqlContractTest {
"OR (SELECT COUNT(*) FROM tmp_phase5_delivery_role_permission");
}
/** 客户默认管理员只获得本客户派送读取权限。 */
@Test
void grantsOnlyTheDefaultCustomerAdministratorAutomatically() throws Exception {
String sql = sql();
int marker = sql.indexOf("-- 客户默认管理员获得派送列表/详情只读及独立创建");
int marker = sql.indexOf("-- 客户默认管理员只获得派送列表和详情读取");
int assertion = sql.indexOf("DROP PROCEDURE IF EXISTS assert_phase5_delivery_permissions", marker);
assertThat(marker).isGreaterThanOrEqualTo(0);
assertThat(assertion).isGreaterThan(marker);
@@ -137,11 +154,11 @@ class Phase5DeliveryPermissionSqlContractTest {
String grant = sql.substring(marker, assertion);
assertThat(grant).contains(
"role.role_code='MERCHANT_OWNER'",
"merchant:warehouse:delivery:list",
"merchant:warehouse:delivery:create");
assertThat(grant).doesNotContain("MERCHANT_OPERATOR", "ORDER_VIEWER", "role.role_code IN");
"merchant:warehouse:delivery:list");
assertThat(grant).doesNotContain("MERCHANT_OPERATOR", "ORDER_VIEWER", "role.role_code IN", "merchant:warehouse:delivery:create");
}
/** 国内空库基线必须同步当前权限与默认角色关联。 */
@Test
void domesticCleanInitializationContainsTheCompletePermissionCatalog() throws Exception {
String unifiedSql = repositoryFile("deploy/sql/头程数据库统一增量-MySQL8.sql");
@@ -151,7 +168,10 @@ class Phase5DeliveryPermissionSqlContractTest {
.contains("(4000004,5107064,0,CURRENT_TIMESTAMP(3))")
.contains("(4000004,5107094,0,CURRENT_TIMESTAMP(3))")
.contains("(4000100,5306000,0,CURRENT_TIMESTAMP(3))")
.contains("(4000100,5306001,0,CURRENT_TIMESTAMP(3))")
.contains("(4000004,5107065,0,CURRENT_TIMESTAMP(3))")
.contains("(4000004,5107066,0,CURRENT_TIMESTAMP(3))")
.contains("(4000004,5107067,0,CURRENT_TIMESTAMP(3))")
.doesNotContain("merchant:warehouse:delivery:create", "(4000100,5306001,0,CURRENT_TIMESTAMP(3))")
.doesNotContain("guard_phase5_delivery_permission_ids", "tmp_phase5_delivery_role_permission");
}
@@ -20,6 +20,7 @@ class Phase5DeliveryPermissionSqlExecutionTest {
private static final Pattern PLATFORM_CODE =
Pattern.compile("platform:overseas-warehouse:[a-z0-9:-]+");
/** 没有自定义管理员时不产生虚假的缺权错误。 */
@Test
void noCustomAdministratorDoesNotCreateAnAssertionViolation() throws Exception {
try (Connection connection = database()) {
@@ -29,6 +30,7 @@ class Phase5DeliveryPermissionSqlExecutionTest {
}
}
/** 按当前完整目录补齐管理员授权,重复执行不增加关联。 */
@Test
void onePartiallyGrantedCustomAdministratorIsCompletedIdempotently() throws Exception {
try (Connection connection = database()) {
@@ -37,50 +39,53 @@ class Phase5DeliveryPermissionSqlExecutionTest {
assertThat(customAdministratorViolations(connection)).isEqualTo(1);
executeGrant(connection);
assertThat(grantCount(connection, 11L)).isEqualTo(16);
assertThat(grantCount(connection, 11L)).isEqualTo(19);
assertThat(customAdministratorViolations(connection)).isZero();
executeGrant(connection);
assertThat(grantCount(connection, 11L)).isEqualTo(16);
assertThat(totalGrantCount(connection)).isEqualTo(16);
assertThat(grantCount(connection, 11L)).isEqualTo(19);
assertThat(totalGrantCount(connection)).isEqualTo(19);
}
}
/** 分别核对每个管理员,缺少任一权限不能被其他角色抵消。 */
@Test
void multipleCustomAdministratorsExposeTheSingleIncompleteRole() throws Exception {
try (Connection connection = database()) {
insertRole(connection, 21L, "PLATFORM_CUSTOM_ADMIN");
insertRole(connection, 22L, "Platform_Custom_Admin");
grantFirstPermissions(connection, 21L, 16);
grantFirstPermissions(connection, 22L, 15);
grantFirstPermissions(connection, 21L, 19);
grantFirstPermissions(connection, 22L, 18);
assertThat(customAdministratorViolations(connection)).isEqualTo(1);
executeGrant(connection);
assertThat(grantCount(connection, 21L)).isEqualTo(16);
assertThat(grantCount(connection, 22L)).isEqualTo(16);
assertThat(grantCount(connection, 21L)).isEqualTo(19);
assertThat(grantCount(connection, 22L)).isEqualTo(19);
assertThat(customAdministratorViolations(connection)).isZero();
}
}
/** 完整管理员重复授权保持各自权限集合稳定。 */
@Test
void multipleCompleteCustomAdministratorsRemainCompleteAfterReplay() throws Exception {
try (Connection connection = database()) {
insertRole(connection, 31L, "PLATFORM_CUSTOM_ADMIN");
insertRole(connection, 32L, "platform_custom_admin");
grantFirstPermissions(connection, 31L, 16);
grantFirstPermissions(connection, 32L, 16);
grantFirstPermissions(connection, 31L, 19);
grantFirstPermissions(connection, 32L, 19);
assertThat(customAdministratorViolations(connection)).isZero();
executeGrant(connection);
executeGrant(connection);
assertThat(grantCount(connection, 31L)).isEqualTo(16);
assertThat(grantCount(connection, 32L)).isEqualTo(16);
assertThat(totalGrantCount(connection)).isEqualTo(32);
assertThat(grantCount(connection, 31L)).isEqualTo(19);
assertThat(grantCount(connection, 32L)).isEqualTo(19);
assertThat(totalGrantCount(connection)).isEqualTo(38);
}
}
/** 管理员授权不得扩散到理货只读岗位或停用账号。 */
@Test
void administratorGrantDoesNotEscalateAReadOnlyRoleOrDisabledAdministrator() throws Exception {
try (Connection connection = database()) {
@@ -99,7 +104,7 @@ class Phase5DeliveryPermissionSqlExecutionTest {
executeGrant(connection);
executeGrant(connection);
assertThat(grantCount(connection, 41L)).isEqualTo(16);
assertThat(grantCount(connection, 41L)).isEqualTo(19);
assertThat(grantCount(connection, 42L)).isEqualTo(1);
assertThat(grantCount(connection, 43L)).isZero();
try (Statement statement = connection.createStatement();
@@ -206,6 +211,7 @@ class Phase5DeliveryPermissionSqlExecutionTest {
}
}
/** 逐角色核对当前后台权限全集,避免跨角色合并计数。 */
private static int customAdministratorViolations(Connection connection) throws Exception {
String placeholders = String.join(",", platformPermissions().stream().map(code -> "?").toList());
String sql = """
@@ -216,7 +222,7 @@ class Phase5DeliveryPermissionSqlExecutionTest {
AND (SELECT COUNT(*) FROM iam_role_permission grant_row
JOIN iam_permission permission ON permission.id=grant_row.permission_id
WHERE grant_row.role_id=role.id AND grant_row.tenant_id=role.tenant_id
AND permission.permission_code IN (%s)) <> 16
AND permission.permission_code IN (%s)) <> 19
""".formatted(placeholders);
try (PreparedStatement query = connection.prepareStatement(sql)) {
int index = 1;
@@ -239,11 +245,12 @@ class Phase5DeliveryPermissionSqlExecutionTest {
return sql.substring(start, end);
}
/** 从实际管理员授予语句提取当前后台权限全集。 */
private static Set<String> platformPermissions() throws Exception {
LinkedHashSet<String> codes = new LinkedHashSet<>();
String grant = administratorGrantSql();
PLATFORM_CODE.matcher(grant).results().map(result -> result.group()).forEach(codes::add);
assertThat(codes).hasSize(16);
assertThat(codes).hasSize(19);
return codes;
}
@@ -64,18 +64,16 @@ class AuthorizationSnapshotServiceTest {
verify(mapper).findSnapshot(42L, 0L, 9L, "PLATFORM");
}
/** 按当前有效角色返回客户派送读取权限。 */
@Test
void exposesPhase5DeliveryPermissionsFromCurrentRoleAssignments() {
void exposesCustomerDeliveryReadPermissionFromCurrentRoleAssignments() {
when(mapper.findSnapshot(42L, 7L, 9L, "MERCHANT")).thenReturn(rows(List.of("MERCHANT_OWNER"), List.of(
"merchant:warehouse:delivery:list",
"merchant:warehouse:delivery:create")));
"merchant:warehouse:delivery:list")));
var result = service.currentPermissions(new AuthenticatedUser(42L, 7L, 7L, 9L,
"owner", "MERCHANT", "MERCHANT", java.util.Set.of()), "MERCHANT");
assertThat(result).containsExactlyInAnyOrder(
"merchant:warehouse:delivery:create",
"merchant:warehouse:delivery:list");
assertThat(result).containsExactly("merchant:warehouse:delivery:list");
}
@Test