优化
This commit is contained in:
@@ -254,13 +254,18 @@ public class PlatformUserManagementService {
|
||||
}
|
||||
|
||||
private Long validateWarehouseBinding(List<Long> roleIds, Long overseasWarehouseId) {
|
||||
boolean picker = roleIds.stream().map(roleMapper::selectById).filter(Objects::nonNull)
|
||||
.anyMatch(role -> "WAREHOUSE_PICKER".equals(role.getRoleCode()));
|
||||
if (picker && (overseasWarehouseId == null || overseasWarehouseId <= 0)) {
|
||||
throw new BizException(ResultCode.BAD_REQUEST, "海外仓拣货员必须绑定一个有效海外仓");
|
||||
Set<String> roleCodes = roleIds.stream().map(roleMapper::selectById).filter(Objects::nonNull)
|
||||
.map(IamRole::getRoleCode).collect(Collectors.toSet());
|
||||
boolean overseasPda = roleCodes.contains("OVERSEAS_WAREHOUSE_PDA_OPERATOR");
|
||||
boolean domesticPda = roleCodes.contains("CN_FIRSTLEG_PDA_OPERATOR");
|
||||
if (overseasPda && domesticPda) {
|
||||
throw new BizException(ResultCode.BAD_REQUEST, "国内头程 PDA 与海外仓 PDA 角色不能同时分配");
|
||||
}
|
||||
if (!picker && overseasWarehouseId != null) {
|
||||
throw new BizException(ResultCode.BAD_REQUEST, "仅海外仓拣货员可绑定海外仓");
|
||||
if (overseasPda && (overseasWarehouseId == null || overseasWarehouseId <= 0)) {
|
||||
throw new BizException(ResultCode.BAD_REQUEST, "海外仓 PDA 作业员必须绑定一个有效海外仓");
|
||||
}
|
||||
if (!overseasPda && overseasWarehouseId != null) {
|
||||
throw new BizException(ResultCode.BAD_REQUEST, "仅海外仓 PDA 作业员可绑定海外仓");
|
||||
}
|
||||
return overseasWarehouseId;
|
||||
}
|
||||
|
||||
@@ -80,14 +80,14 @@ DELETE role_permission FROM iam_role_permission role_permission
|
||||
JOIN iam_role role ON role.id=role_permission.role_id AND role.tenant_id=role_permission.tenant_id
|
||||
JOIN iam_permission permission ON permission.id=role_permission.permission_id AND permission.tenant_id=role_permission.tenant_id
|
||||
WHERE permission.permission_code='lastleg:pda:operate'
|
||||
AND NOT (role.id=4000005 AND role.tenant_id=0 AND role.app_code='PLATFORM' AND role.role_code='WAREHOUSE_PICKER');
|
||||
AND NOT (role.id=4000005 AND role.tenant_id=0 AND role.app_code='PLATFORM' AND role.role_code='OVERSEAS_WAREHOUSE_PDA_OPERATOR');
|
||||
|
||||
INSERT IGNORE INTO iam_role_permission (tenant_id, role_id, permission_id, created_at)
|
||||
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='lastleg:pda:operate'
|
||||
WHERE role.id=4000005 AND role.tenant_id=0 AND role.app_code='PLATFORM' AND role.role_code='WAREHOUSE_PICKER'
|
||||
WHERE role.id=4000005 AND role.tenant_id=0 AND role.app_code='PLATFORM' AND role.role_code='OVERSEAS_WAREHOUSE_PDA_OPERATOR'
|
||||
AND role.status='ACTIVE' AND role.deleted=0 AND permission.status='ACTIVE' AND permission.deleted=0;
|
||||
|
||||
DROP PROCEDURE IF EXISTS assert_overseas_pda_picker_permission;
|
||||
@@ -98,15 +98,15 @@ BEGIN
|
||||
JOIN iam_role role ON role.id=grant_row.role_id AND role.tenant_id=grant_row.tenant_id
|
||||
JOIN iam_permission permission ON permission.id=grant_row.permission_id AND permission.tenant_id=grant_row.tenant_id
|
||||
WHERE permission.permission_code='lastleg:pda:operate'
|
||||
AND role.id=4000005 AND role.app_code='PLATFORM' AND role.role_code='WAREHOUSE_PICKER') <> 1 THEN
|
||||
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT='海外PDA权限初始化失败:WAREHOUSE_PICKER未精确授权';
|
||||
AND role.id=4000005 AND role.app_code='PLATFORM' AND role.role_code='OVERSEAS_WAREHOUSE_PDA_OPERATOR') <> 1 THEN
|
||||
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT='海外PDA权限初始化失败:海外仓 PDA 作业员未精确授权';
|
||||
END IF;
|
||||
IF EXISTS (SELECT 1 FROM iam_role_permission grant_row
|
||||
JOIN iam_role role ON role.id=grant_row.role_id AND role.tenant_id=grant_row.tenant_id
|
||||
JOIN iam_permission permission ON permission.id=grant_row.permission_id AND permission.tenant_id=grant_row.tenant_id
|
||||
WHERE permission.permission_code='lastleg:pda:operate'
|
||||
AND NOT (role.id=4000005 AND role.tenant_id=0 AND role.app_code='PLATFORM' AND role.role_code='WAREHOUSE_PICKER')) THEN
|
||||
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT='海外PDA权限初始化失败:存在非仓库拣货员授权';
|
||||
AND NOT (role.id=4000005 AND role.tenant_id=0 AND role.app_code='PLATFORM' AND role.role_code='OVERSEAS_WAREHOUSE_PDA_OPERATOR')) THEN
|
||||
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT='海外PDA权限初始化失败:存在非海外仓 PDA 作业员授权';
|
||||
END IF;
|
||||
END$$
|
||||
DELIMITER ;
|
||||
@@ -148,7 +148,7 @@ JOIN iam_permission permission ON permission.id=grant_row.permission_id AND perm
|
||||
LEFT JOIN tmp_phase4_warehouse_role_permission expected
|
||||
ON expected.role_code=role.role_code AND expected.permission_code=permission.permission_code
|
||||
WHERE role.tenant_id=0 AND role.app_code='PLATFORM'
|
||||
AND role.role_code IN ('WAREHOUSE_OPERATOR','WAREHOUSE_PICKER','WAREHOUSE_TALLY')
|
||||
AND role.role_code IN ('WAREHOUSE_OPERATOR','OVERSEAS_WAREHOUSE_PDA_OPERATOR','WAREHOUSE_TALLY','CN_FIRSTLEG_PDA_OPERATOR')
|
||||
AND permission.permission_code LIKE 'platform:overseas-%'
|
||||
AND expected.permission_code IS NULL;
|
||||
|
||||
|
||||
@@ -1,8 +1,15 @@
|
||||
-- 三期仓库常用系统角色:仓库操作员、仓库拣货员、仓库理货员。
|
||||
-- 三期仓库系统角色:国内仓后台、国内头程 PDA、海外仓 PDA、国内仓理货复核。
|
||||
-- 本脚本只组合已经存在的权限资源,需在三期 Firstleg/IAM 权限脚本之后执行,可重复部署。
|
||||
USE baiyue_iam;
|
||||
SET NAMES utf8mb4;
|
||||
|
||||
UPDATE iam_role
|
||||
SET role_code = 'OVERSEAS_WAREHOUSE_PDA_OPERATOR',
|
||||
role_name = '海外仓 PDA 作业员',
|
||||
description = '负责使用海外仓 PDA 执行接柜、入仓和库内作业,必须绑定一个海外仓'
|
||||
WHERE id = 4000005 AND tenant_id = 0 AND app_code = 'PLATFORM'
|
||||
AND role_code = 'WAREHOUSE_PICKER';
|
||||
|
||||
DROP PROCEDURE IF EXISTS assert_phase3_warehouse_role_ids_available;
|
||||
DELIMITER $$
|
||||
CREATE PROCEDURE assert_phase3_warehouse_role_ids_available()
|
||||
@@ -11,14 +18,16 @@ BEGIN
|
||||
SELECT 1
|
||||
FROM iam_role
|
||||
WHERE (id = 4000004 AND (tenant_id <> 0 OR app_code <> 'PLATFORM' OR role_code <> 'WAREHOUSE_OPERATOR'))
|
||||
OR (id = 4000005 AND (tenant_id <> 0 OR app_code <> 'PLATFORM' OR role_code <> 'WAREHOUSE_PICKER'))
|
||||
OR (id = 4000005 AND (tenant_id <> 0 OR app_code <> 'PLATFORM' OR role_code <> 'OVERSEAS_WAREHOUSE_PDA_OPERATOR'))
|
||||
OR (id = 4000006 AND (tenant_id <> 0 OR app_code <> 'PLATFORM' OR role_code <> 'WAREHOUSE_TALLY'))
|
||||
OR (id = 4000007 AND (tenant_id <> 0 OR app_code <> 'PLATFORM' OR role_code <> 'CN_FIRSTLEG_PDA_OPERATOR'))
|
||||
OR (tenant_id = 0 AND app_code = 'PLATFORM' AND role_code = 'WAREHOUSE_OPERATOR' AND id <> 4000004)
|
||||
OR (tenant_id = 0 AND app_code = 'PLATFORM' AND role_code = 'WAREHOUSE_PICKER' AND id <> 4000005)
|
||||
OR (tenant_id = 0 AND app_code = 'PLATFORM' AND role_code = 'OVERSEAS_WAREHOUSE_PDA_OPERATOR' AND id <> 4000005)
|
||||
OR (tenant_id = 0 AND app_code = 'PLATFORM' AND role_code = 'WAREHOUSE_TALLY' AND id <> 4000006)
|
||||
OR (tenant_id = 0 AND app_code = 'PLATFORM' AND role_code = 'CN_FIRSTLEG_PDA_OPERATOR' AND id <> 4000007)
|
||||
) THEN
|
||||
SIGNAL SQLSTATE '45000'
|
||||
SET MESSAGE_TEXT = '仓库角色初始化失败:4000004-4000006 或角色编码已被占用';
|
||||
SET MESSAGE_TEXT = '仓库角色初始化失败:4000004-4000007 或角色编码已被占用';
|
||||
END IF;
|
||||
IF EXISTS (
|
||||
SELECT 1
|
||||
@@ -26,12 +35,14 @@ BEGIN
|
||||
WHERE (id = 6000004 AND role_id <> 4000004)
|
||||
OR (id = 6000005 AND role_id <> 4000005)
|
||||
OR (id = 6000006 AND role_id <> 4000006)
|
||||
OR (id = 6000007 AND role_id <> 4000007)
|
||||
OR (role_id = 4000004 AND id <> 6000004)
|
||||
OR (role_id = 4000005 AND id <> 6000005)
|
||||
OR (role_id = 4000006 AND id <> 6000006)
|
||||
OR (role_id = 4000007 AND id <> 6000007)
|
||||
) THEN
|
||||
SIGNAL SQLSTATE '45000'
|
||||
SET MESSAGE_TEXT = '仓库角色初始化失败:6000004-6000006 数据范围ID已被占用';
|
||||
SET MESSAGE_TEXT = '仓库角色初始化失败:6000004-6000007 数据范围ID已被占用';
|
||||
END IF;
|
||||
END$$
|
||||
DELIMITER ;
|
||||
@@ -42,12 +53,14 @@ INSERT INTO iam_role (
|
||||
id, tenant_id, app_code, role_code, role_name, role_type, status,
|
||||
description, deleted, version
|
||||
) VALUES
|
||||
(4000004, 0, 'PLATFORM', 'WAREHOUSE_OPERATOR', '仓库操作员', 'SYSTEM', 'ACTIVE',
|
||||
(4000004, 0, 'PLATFORM', 'WAREHOUSE_OPERATOR', '国内仓后台操作员', 'SYSTEM', 'ACTIVE',
|
||||
'负责查看入仓业务并在后台维护装柜证据', 0, 0),
|
||||
(4000005, 0, 'PLATFORM', 'WAREHOUSE_PICKER', '仓库拣货员', 'SYSTEM', 'ACTIVE',
|
||||
'负责使用PDA执行柜次拣货和现场拍照', 0, 0),
|
||||
(4000006, 0, 'PLATFORM', 'WAREHOUSE_TALLY', '仓库理货员', 'SYSTEM', 'ACTIVE',
|
||||
'负责入库测量、PDA复核和装柜证据维护', 0, 0)
|
||||
(4000005, 0, 'PLATFORM', 'OVERSEAS_WAREHOUSE_PDA_OPERATOR', '海外仓 PDA 作业员', 'SYSTEM', 'ACTIVE',
|
||||
'负责使用海外仓 PDA 执行接柜、入仓和库内作业,必须绑定一个海外仓', 0, 0),
|
||||
(4000006, 0, 'PLATFORM', 'WAREHOUSE_TALLY', '国内仓理货复核员', 'SYSTEM', 'ACTIVE',
|
||||
'负责国内入库测量、PDA复核和装柜证据维护', 0, 0),
|
||||
(4000007, 0, 'PLATFORM', 'CN_FIRSTLEG_PDA_OPERATOR', '国内头程 PDA 作业员', 'SYSTEM', 'ACTIVE',
|
||||
'负责使用国内 PDA 执行柜次拣货、现场取证和装柜完成', 0, 0)
|
||||
ON DUPLICATE KEY UPDATE
|
||||
role_name = VALUES(role_name), role_type = 'SYSTEM', status = 'ACTIVE',
|
||||
description = VALUES(description), deleted = 0;
|
||||
@@ -67,10 +80,10 @@ INSERT INTO tmp_phase3_warehouse_role_permission (role_code, permission_code) VA
|
||||
('WAREHOUSE_OPERATOR', 'platform:firstleg:inbound:loading:view'),
|
||||
('WAREHOUSE_OPERATOR', 'platform:firstleg:inbound:loading:edit');
|
||||
|
||||
-- 拣货员:只允许PDA任务查询、作业和现场照片,不授予后台页面、任务分派或复核权限。
|
||||
-- 国内头程 PDA 作业员:只允许国内任务查询、作业和现场照片,不授予后台、海外、分派或复核权限。
|
||||
INSERT INTO tmp_phase3_warehouse_role_permission (role_code, permission_code) VALUES
|
||||
('WAREHOUSE_PICKER', 'platform:firstleg:pda:view'),
|
||||
('WAREHOUSE_PICKER', 'platform:firstleg:pda:work');
|
||||
('CN_FIRSTLEG_PDA_OPERATOR', 'platform:firstleg:pda:view'),
|
||||
('CN_FIRSTLEG_PDA_OPERATOR', 'platform:firstleg:pda:work');
|
||||
|
||||
-- 理货员:负责到仓测量、装柜证据维护和PDA复核,不允许完成装柜或确认出仓。
|
||||
INSERT INTO tmp_phase3_warehouse_role_permission (role_code, permission_code) VALUES
|
||||
@@ -92,15 +105,15 @@ DELIMITER $$
|
||||
CREATE PROCEDURE assert_phase3_warehouse_role_permissions_available()
|
||||
BEGIN
|
||||
DECLARE operator_permission_count INT DEFAULT 0;
|
||||
DECLARE picker_permission_count INT DEFAULT 0;
|
||||
DECLARE domestic_pda_permission_count INT DEFAULT 0;
|
||||
DECLARE tally_permission_count INT DEFAULT 0;
|
||||
SELECT COALESCE(SUM(role_code = 'WAREHOUSE_OPERATOR'), 0),
|
||||
COALESCE(SUM(role_code = 'WAREHOUSE_PICKER'), 0),
|
||||
COALESCE(SUM(role_code = 'CN_FIRSTLEG_PDA_OPERATOR'), 0),
|
||||
COALESCE(SUM(role_code = 'WAREHOUSE_TALLY'), 0)
|
||||
INTO operator_permission_count, picker_permission_count, tally_permission_count
|
||||
INTO operator_permission_count, domestic_pda_permission_count, tally_permission_count
|
||||
FROM tmp_phase3_warehouse_role_permission;
|
||||
IF operator_permission_count <> 5
|
||||
OR picker_permission_count <> 2
|
||||
OR domestic_pda_permission_count <> 2
|
||||
OR tally_permission_count <> 12 THEN
|
||||
SIGNAL SQLSTATE '45000'
|
||||
SET MESSAGE_TEXT = '仓库角色初始化失败:角色权限组合数量不符合预期';
|
||||
@@ -124,7 +137,7 @@ DELIMITER ;
|
||||
CALL assert_phase3_warehouse_role_permissions_available();
|
||||
DROP PROCEDURE assert_phase3_warehouse_role_permissions_available;
|
||||
|
||||
-- 三个系统角色的权限集合由迁移维护。重复执行时移除历史版本或人工误授的越权项,
|
||||
-- 四个系统角色的权限集合由初始化维护。重复执行时移除人工误授的越权项,
|
||||
-- 避免最小权限角色因脚本升级只增不减。
|
||||
DELETE role_permission
|
||||
FROM iam_role_permission role_permission
|
||||
@@ -139,8 +152,8 @@ DELETE role_permission
|
||||
AND expected.permission_code = permission.permission_code
|
||||
WHERE role.tenant_id = 0
|
||||
AND role.app_code = 'PLATFORM'
|
||||
AND role.role_code IN ('WAREHOUSE_OPERATOR', 'WAREHOUSE_PICKER', 'WAREHOUSE_TALLY')
|
||||
AND NOT (role.role_code = 'WAREHOUSE_PICKER' AND permission.permission_code = 'lastleg:pda:operate')
|
||||
AND role.role_code IN ('WAREHOUSE_OPERATOR', 'OVERSEAS_WAREHOUSE_PDA_OPERATOR', 'WAREHOUSE_TALLY', 'CN_FIRSTLEG_PDA_OPERATOR')
|
||||
AND NOT (role.role_code = 'OVERSEAS_WAREHOUSE_PDA_OPERATOR' AND permission.permission_code = 'lastleg:pda:operate')
|
||||
AND expected.permission_code IS NULL;
|
||||
|
||||
INSERT IGNORE INTO iam_role_permission (role_id, permission_id, tenant_id)
|
||||
@@ -162,7 +175,8 @@ SELECT role.id, permission.id, 0
|
||||
INSERT INTO iam_data_scope (id, role_id, tenant_id, scope_type, scope_expression) VALUES
|
||||
(6000004, 4000004, 0, 'TENANT', NULL),
|
||||
(6000005, 4000005, 0, 'TENANT', NULL),
|
||||
(6000006, 4000006, 0, 'TENANT', NULL)
|
||||
(6000006, 4000006, 0, 'TENANT', NULL),
|
||||
(6000007, 4000007, 0, 'TENANT', NULL)
|
||||
ON DUPLICATE KEY UPDATE
|
||||
tenant_id = 0, scope_type = 'TENANT', scope_expression = NULL;
|
||||
|
||||
@@ -177,7 +191,7 @@ BEGIN
|
||||
AND role_type = 'SYSTEM'
|
||||
AND status = 'ACTIVE'
|
||||
AND deleted = 0
|
||||
AND role_code IN ('WAREHOUSE_OPERATOR', 'WAREHOUSE_PICKER', 'WAREHOUSE_TALLY')) <> 3 THEN
|
||||
AND role_code IN ('WAREHOUSE_OPERATOR', 'OVERSEAS_WAREHOUSE_PDA_OPERATOR', 'WAREHOUSE_TALLY', 'CN_FIRSTLEG_PDA_OPERATOR')) <> 4 THEN
|
||||
SIGNAL SQLSTATE '45000'
|
||||
SET MESSAGE_TEXT = '仓库角色初始化失败:系统角色未完整启用';
|
||||
END IF;
|
||||
@@ -203,9 +217,9 @@ BEGIN
|
||||
JOIN iam_role role ON role.id = scope_row.role_id
|
||||
WHERE role.tenant_id = 0
|
||||
AND role.app_code = 'PLATFORM'
|
||||
AND role.role_code IN ('WAREHOUSE_OPERATOR', 'WAREHOUSE_PICKER', 'WAREHOUSE_TALLY')
|
||||
AND role.role_code IN ('WAREHOUSE_OPERATOR', 'OVERSEAS_WAREHOUSE_PDA_OPERATOR', 'WAREHOUSE_TALLY', 'CN_FIRSTLEG_PDA_OPERATOR')
|
||||
AND scope_row.tenant_id = 0
|
||||
AND scope_row.scope_type = 'TENANT') <> 3 THEN
|
||||
AND scope_row.scope_type = 'TENANT') <> 4 THEN
|
||||
SIGNAL SQLSTATE '45000'
|
||||
SET MESSAGE_TEXT = '仓库角色初始化失败:数据范围未完整写入';
|
||||
END IF;
|
||||
|
||||
@@ -645,7 +645,7 @@ paths:
|
||||
get:
|
||||
tags: [RBAC]
|
||||
summary: List roles / 查询角色
|
||||
description: List roles in the selected application and current customer or platform technical scope. The platform scope includes the built-in WAREHOUSE_OPERATOR, WAREHOUSE_PICKER and WAREHOUSE_TALLY roles after the phase-three role migration. / 查询指定应用及当前客户范围或平台技术作用域内的角色;三期角色迁移后,平台作用域包含仓库操作员、仓库拣货员和仓库理货员三个内置角色。
|
||||
description: List roles in the selected application and current customer or platform technical scope. Domestic first-leg PDA and overseas warehouse PDA operators are separate, mutually exclusive roles. / 查询指定应用及当前客户范围或平台技术作用域内的角色;国内头程 PDA 作业员与海外仓 PDA 作业员是两批独立人员,对应角色互斥且权限不交叉。
|
||||
responses:
|
||||
'200': {$ref: '#/components/responses/Success'}
|
||||
'403': {$ref: '#/components/responses/Forbidden'}
|
||||
@@ -1323,7 +1323,7 @@ components:
|
||||
email: {type: string, format: email, maxLength: 128}
|
||||
tenantId: {type: integer, format: int64, enum: [0], description: 保留的兼容字段,只允许平台技术作用域 0}
|
||||
roleIds: {type: array, minItems: 1, items: {type: integer, format: int64}}
|
||||
overseasWarehouseId: {type: integer, format: int64, nullable: true, description: 选择WAREHOUSE_PICKER角色时必填且只能绑定一个实际海外仓;其他角色必须为空}
|
||||
overseasWarehouseId: {type: integer, format: int64, nullable: true, description: 选择 OVERSEAS_WAREHOUSE_PDA_OPERATOR 时必填且只能绑定一个实际海外仓;CN_FIRSTLEG_PDA_OPERATOR 与其他角色必须为空;两个 PDA 角色不能同时分配}
|
||||
password: {type: string, format: password, minLength: 8, maxLength: 64, writeOnly: true}
|
||||
status: {type: string, enum: [ACTIVE, DISABLED]}
|
||||
UpdatePlatformManagedUserRequest:
|
||||
@@ -1335,7 +1335,7 @@ components:
|
||||
email: {type: string, format: email, maxLength: 128}
|
||||
tenantId: {type: integer, format: int64, enum: [0], description: 保留的兼容字段,只允许平台技术作用域 0}
|
||||
roleIds: {type: array, minItems: 1, items: {type: integer, format: int64}}
|
||||
overseasWarehouseId: {type: integer, format: int64, nullable: true, description: 选择WAREHOUSE_PICKER角色时必填且只能绑定一个实际海外仓;其他角色必须为空}
|
||||
overseasWarehouseId: {type: integer, format: int64, nullable: true, description: 选择 OVERSEAS_WAREHOUSE_PDA_OPERATOR 时必填且只能绑定一个实际海外仓;CN_FIRSTLEG_PDA_OPERATOR 与其他角色必须为空;两个 PDA 角色不能同时分配}
|
||||
CreateInternalUserRequest:
|
||||
type: object
|
||||
required: [displayName]
|
||||
|
||||
+5
-5
@@ -82,10 +82,10 @@ class OverseasPhase4PermissionSqlContractTest {
|
||||
"platform:overseas-business:purchase:list",
|
||||
"platform:overseas-business:truck:list",
|
||||
"platform:overseas-business:looseboard:list");
|
||||
assertThat(matrix).doesNotContain("WAREHOUSE_PICKER");
|
||||
assertThat(matrix).doesNotContain("OVERSEAS_WAREHOUSE_PDA_OPERATOR");
|
||||
assertThat(matrix).doesNotContain(":create'", ":edit'", ":status'", ":export'", ":adjust'");
|
||||
assertThat(sql).contains("assert_phase4_warehouse_role_minimum", "<> 20",
|
||||
"role.role_code IN ('WAREHOUSE_OPERATOR','WAREHOUSE_PICKER','WAREHOUSE_TALLY')");
|
||||
"role.role_code IN ('WAREHOUSE_OPERATOR','OVERSEAS_WAREHOUSE_PDA_OPERATOR','WAREHOUSE_TALLY','CN_FIRSTLEG_PDA_OPERATOR')");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -125,12 +125,12 @@ class OverseasPhase4PermissionSqlContractTest {
|
||||
"permission.permission_code<>'lastleg:pda:operate'",
|
||||
"role.id=4000005",
|
||||
"assert_overseas_pda_picker_permission",
|
||||
"存在非仓库拣货员授权",
|
||||
"role.role_code='WAREHOUSE_PICKER'",
|
||||
"存在非海外仓 PDA 作业员授权",
|
||||
"role.role_code='OVERSEAS_WAREHOUSE_PDA_OPERATOR'",
|
||||
"permission.permission_code='lastleg:pda:operate'",
|
||||
"role.role_code='PLATFORM_ADMIN'",
|
||||
"DELETE role_permission FROM");
|
||||
int picker = sql.indexOf("role.role_code='WAREHOUSE_PICKER'");
|
||||
int picker = sql.indexOf("role.role_code='OVERSEAS_WAREHOUSE_PDA_OPERATOR'");
|
||||
int grantStart = sql.lastIndexOf("INSERT IGNORE INTO", picker);
|
||||
int grantEnd = sql.indexOf(';', picker);
|
||||
assertThat(grantStart).isGreaterThanOrEqualTo(0);
|
||||
|
||||
@@ -30,33 +30,35 @@ class WarehouseRoleSqlContractTest {
|
||||
private static void assertWarehouseRoleContract(String sql) {
|
||||
|
||||
assertThat(sql)
|
||||
.contains("(4000004, 0, 'PLATFORM', 'WAREHOUSE_OPERATOR', '仓库操作员', 'SYSTEM'")
|
||||
.contains("(4000005, 0, 'PLATFORM', 'WAREHOUSE_PICKER', '仓库拣货员', 'SYSTEM'")
|
||||
.contains("(4000006, 0, 'PLATFORM', 'WAREHOUSE_TALLY', '仓库理货员', 'SYSTEM'")
|
||||
.contains("(4000004, 0, 'PLATFORM', 'WAREHOUSE_OPERATOR', '国内仓后台操作员', 'SYSTEM'")
|
||||
.contains("(4000005, 0, 'PLATFORM', 'OVERSEAS_WAREHOUSE_PDA_OPERATOR', '海外仓 PDA 作业员', 'SYSTEM'")
|
||||
.contains("(4000006, 0, 'PLATFORM', 'WAREHOUSE_TALLY', '国内仓理货复核员', 'SYSTEM'")
|
||||
.contains("(4000007, 0, 'PLATFORM', 'CN_FIRSTLEG_PDA_OPERATOR', '国内头程 PDA 作业员', 'SYSTEM'")
|
||||
.contains("ON DUPLICATE KEY UPDATE")
|
||||
.contains("INSERT IGNORE INTO iam_role_permission")
|
||||
.contains("'WAREHOUSE_PICKER', 'platform:firstleg:pda:work'")
|
||||
.contains("'CN_FIRSTLEG_PDA_OPERATOR', 'platform:firstleg:pda:work'")
|
||||
.contains("'WAREHOUSE_TALLY', 'platform:firstleg:pda:review'")
|
||||
.contains("'WAREHOUSE_TALLY', 'platform:firstleg:inbound:loading:edit'")
|
||||
.contains("'WAREHOUSE_OPERATOR', 'platform:firstleg:inbound:loading:edit'")
|
||||
.contains("operator_permission_count <> 5")
|
||||
.contains("picker_permission_count <> 2")
|
||||
.contains("domestic_pda_permission_count <> 2")
|
||||
.contains("tally_permission_count <> 12")
|
||||
.contains("依赖的三期平台权限尚未完整部署")
|
||||
.contains("DELETE role_permission")
|
||||
.contains("expected.permission_code IS NULL")
|
||||
.contains("role.role_code = 'WAREHOUSE_PICKER' AND permission.permission_code = 'lastleg:pda:operate'")
|
||||
.contains("role.role_code = 'OVERSEAS_WAREHOUSE_PDA_OPERATOR' AND permission.permission_code = 'lastleg:pda:operate'")
|
||||
.contains("最小权限授权未完整写入")
|
||||
.contains("grant_row.tenant_id = 0) <> 19")
|
||||
.contains("(6000004, 4000004, 0, 'TENANT', NULL)")
|
||||
.contains("(6000005, 4000005, 0, 'TENANT', NULL)")
|
||||
.contains("(6000006, 4000006, 0, 'TENANT', NULL)");
|
||||
.contains("(6000006, 4000006, 0, 'TENANT', NULL)")
|
||||
.contains("(6000007, 4000007, 0, 'TENANT', NULL)");
|
||||
|
||||
assertRoleGrant(sql, "WAREHOUSE_PICKER", "platform:firstleg:pda:work");
|
||||
assertRoleGrant(sql, "CN_FIRSTLEG_PDA_OPERATOR", "platform:firstleg:pda:work");
|
||||
assertRoleGrant(sql, "WAREHOUSE_TALLY", "platform:firstleg:pda:review");
|
||||
assertRoleGrant(sql, "WAREHOUSE_OPERATOR", "platform:firstleg:inbound:loading:edit");
|
||||
|
||||
assertThat(roleGrantBlock(sql, "WAREHOUSE_PICKER"))
|
||||
assertThat(roleGrantBlock(sql, "CN_FIRSTLEG_PDA_OPERATOR"))
|
||||
.doesNotContain("platform:order")
|
||||
.doesNotContain("platform:master-data")
|
||||
.doesNotContain("platform:warehouse:list")
|
||||
@@ -76,9 +78,9 @@ class WarehouseRoleSqlContractTest {
|
||||
.doesNotContain("'WAREHOUSE_OPERATOR', 'platform:firstleg:inbound:loading:complete'")
|
||||
.doesNotContain("'WAREHOUSE_OPERATOR', 'platform:firstleg:outbound-dispatch:confirm'")
|
||||
.doesNotContain("'WAREHOUSE_OPERATOR', 'platform:firstleg:outbound-dispatch:reverse'")
|
||||
.doesNotContain("'WAREHOUSE_PICKER', 'platform:firstleg:smart-loading:delete'")
|
||||
.doesNotContain("'CN_FIRSTLEG_PDA_OPERATOR', 'platform:firstleg:smart-loading:delete'")
|
||||
.doesNotContain("'WAREHOUSE_TALLY', 'firstleg:inbound:fee-detail:edit'")
|
||||
.doesNotContain("'WAREHOUSE_PICKER', 'merchant:")
|
||||
.doesNotContain("'CN_FIRSTLEG_PDA_OPERATOR', 'merchant:")
|
||||
.doesNotContain("'WAREHOUSE_OPERATOR', 'merchant:")
|
||||
.doesNotContain("'WAREHOUSE_TALLY', 'merchant:");
|
||||
}
|
||||
@@ -89,7 +91,7 @@ class WarehouseRoleSqlContractTest {
|
||||
|
||||
private static String roleGrantBlock(String sql, String roleCode) {
|
||||
String marker = "-- " + switch (roleCode) {
|
||||
case "WAREHOUSE_PICKER" -> "拣货员:";
|
||||
case "CN_FIRSTLEG_PDA_OPERATOR" -> "国内头程 PDA 作业员:";
|
||||
case "WAREHOUSE_TALLY" -> "理货员:";
|
||||
default -> throw new IllegalArgumentException("unsupported role " + roleCode);
|
||||
};
|
||||
|
||||
@@ -146,7 +146,7 @@ class PlatformUserManagementServiceTest {
|
||||
|
||||
@Test
|
||||
void warehousePickerRequiresAndPersistsSingleOverseasWarehouseBinding() {
|
||||
platformRole.setRoleCode("WAREHOUSE_PICKER");
|
||||
platformRole.setRoleCode("OVERSEAS_WAREHOUSE_PDA_OPERATOR");
|
||||
UpdateUserRequest missing = new UpdateUserRequest("张伟", "13800138000", null,
|
||||
0L, List.of(40001L), null);
|
||||
assertThrows(BizException.class,
|
||||
@@ -161,9 +161,31 @@ class PlatformUserManagementServiceTest {
|
||||
verify(auth).revokeSessions(eq("internal-token"), any());
|
||||
}
|
||||
|
||||
@Test
|
||||
void domesticAndOverseasPdaRolesAreMutuallyExclusive() {
|
||||
IamRole domestic = new IamRole();
|
||||
domestic.setId(40007L); domestic.setTenantId(0L); domestic.setAppCode("PLATFORM");
|
||||
domestic.setRoleCode("CN_FIRSTLEG_PDA_OPERATOR"); domestic.setRoleName("国内头程 PDA 作业员");
|
||||
domestic.setStatus("ACTIVE");
|
||||
IamRole overseas = new IamRole();
|
||||
overseas.setId(40005L); overseas.setTenantId(0L); overseas.setAppCode("PLATFORM");
|
||||
overseas.setRoleCode("OVERSEAS_WAREHOUSE_PDA_OPERATOR"); overseas.setRoleName("海外仓 PDA 作业员");
|
||||
overseas.setStatus("ACTIVE");
|
||||
when(roles.selectById(40007L)).thenReturn(domestic);
|
||||
when(roles.selectById(40005L)).thenReturn(overseas);
|
||||
|
||||
UpdateUserRequest request = new UpdateUserRequest("张伟", "13800138000", null,
|
||||
0L, List.of(40007L, 40005L), 900L);
|
||||
|
||||
BizException error = assertThrows(BizException.class,
|
||||
() -> service.update(30L, request, Set.of("platform:user:grant-role")));
|
||||
assertTrue(error.getMessage().contains("不能同时分配"));
|
||||
verify(auth, never()).scope(anyString(), anyLong(), any());
|
||||
}
|
||||
|
||||
@Test
|
||||
void changingWarehouseBindingRevokesAllAuthSessionsSoAccountVersionIsBumped() {
|
||||
platformRole.setRoleCode("WAREHOUSE_PICKER");
|
||||
platformRole.setRoleCode("OVERSEAS_WAREHOUSE_PDA_OPERATOR");
|
||||
membership.setOverseasWarehouseId(900L);
|
||||
UpdateUserRequest changed = new UpdateUserRequest("张伟", "13800138000", null,
|
||||
0L, List.of(40001L), 901L);
|
||||
|
||||
Reference in New Issue
Block a user