优化
This commit is contained in:
@@ -69,7 +69,7 @@ public class PlatformTenantController {
|
||||
}
|
||||
|
||||
@GetMapping("/tenants/{tenantId:\\d+}")
|
||||
@PreAuthorize("hasAuthority('platform:customer:view')")
|
||||
@PreAuthorize("hasAnyAuthority('platform:customer:list','platform:customer:view')")
|
||||
@Operation(summary = "查询企业客户档案", description = "返回企业基础资料、销售负责人、账期、注册地址以及入驻和审批时间。")
|
||||
public ApiResponse<TenantResponse> tenant(@PathVariable long tenantId,
|
||||
@AuthenticationPrincipal AuthenticatedUser user) {
|
||||
@@ -89,7 +89,7 @@ public class PlatformTenantController {
|
||||
}
|
||||
|
||||
@GetMapping("/tenants/{tenantId:\\d+}/members")
|
||||
@PreAuthorize("hasAuthority('platform:customer:view')")
|
||||
@PreAuthorize("hasAnyAuthority('platform:customer:list','platform:customer:view')")
|
||||
@Operation(summary = "查询企业客户成员及账号", description = "平台只读查询指定企业的全部成员,包含 OWNER 企业管理员,并返回登录账号。")
|
||||
public ApiResponse<List<PlatformCustomerMemberDtos.MemberResponse>> members(
|
||||
@PathVariable long tenantId, @AuthenticationPrincipal AuthenticatedUser user) {
|
||||
|
||||
@@ -115,7 +115,7 @@ public class ProfileResourceController {
|
||||
}
|
||||
|
||||
@GetMapping("/api/platform/v1/iam/tenants/{tenantId}/qualifications")
|
||||
@PreAuthorize("hasAuthority('platform:customer:view')")
|
||||
@PreAuthorize("hasAnyAuthority('platform:customer:list','platform:customer:view')")
|
||||
@Operation(summary = "查询企业客户资质", description = "只读查询企业客户资质元数据,不授予审核能力。")
|
||||
public ApiResponse<List<IamTenantQualification>> platformQualifications(
|
||||
@PathVariable long tenantId, @AuthenticationPrincipal AuthenticatedUser user) {
|
||||
@@ -124,7 +124,7 @@ public class ProfileResourceController {
|
||||
}
|
||||
|
||||
@GetMapping("/api/platform/v1/iam/tenants/{tenantId}/addresses")
|
||||
@PreAuthorize("hasAuthority('platform:customer:view')")
|
||||
@PreAuthorize("hasAnyAuthority('platform:customer:list','platform:customer:view')")
|
||||
@Operation(summary = "查询企业客户地址", description = "只读查询企业客户地址,不开放平台端写入。")
|
||||
public ApiResponse<List<IamTenantAddress>> platformAddresses(
|
||||
@PathVariable long tenantId, @AuthenticationPrincipal AuthenticatedUser user) {
|
||||
|
||||
+2
-2
@@ -31,9 +31,9 @@ public class NotificationInboxController {
|
||||
public ApiResponse<UnreadCountResponse> unread(@PathVariable String app,@AuthenticationPrincipal AuthenticatedUser user){String code=guard(app,user);return ApiResponse.success(service.unread(user.tenantId(),user.membershipId(),code));}
|
||||
@GetMapping("/{id:\\d+}") @PreAuthorize("hasAuthority(#app + ':notification:view')")
|
||||
public ApiResponse<NotificationDetail> detail(@PathVariable String app,@PathVariable Long id,@AuthenticationPrincipal AuthenticatedUser user){String code=guard(app,user);return ApiResponse.success(service.detail(user.tenantId(),user.membershipId(),code,id));}
|
||||
@PutMapping("/{id:\\d+}/read") @PreAuthorize("hasAuthority(#app + ':notification:view')")
|
||||
@PutMapping("/{id:\\d+}/read") @PreAuthorize("hasAuthority(#app + ':notification:read')")
|
||||
public ApiResponse<NotificationDetail> read(@PathVariable String app,@PathVariable Long id,@AuthenticationPrincipal AuthenticatedUser user){String code=guard(app,user);return ApiResponse.success(service.read(user.tenantId(),user.membershipId(),code,id));}
|
||||
@PutMapping("/read-all") @PreAuthorize("hasAuthority(#app + ':notification:view')")
|
||||
@PutMapping("/read-all") @PreAuthorize("hasAuthority(#app + ':notification:read-all')")
|
||||
public ApiResponse<ReadAllResponse> readAll(@PathVariable String app,@AuthenticationPrincipal AuthenticatedUser user){String code=guard(app,user);return ApiResponse.success(service.readAll(user.tenantId(),user.membershipId(),code));}
|
||||
private String guard(String app,AuthenticatedUser user){String code=switch(app){case"platform"->"PLATFORM";case"merchant"->"MERCHANT";default->throw new BizException(ResultCode.BAD_REQUEST,"不支持的应用端");};TenantGuard.tenant(user,code);return code;}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
-- Admin prototype-aligned page menus and page permissions.
|
||||
-- Permission codes remain stable; this migration only adds page-level MENU resources,
|
||||
-- reparents existing finance action resources, and retires unsupported fee create/delete actions.
|
||||
USE baiyue_iam;
|
||||
SET NAMES utf8mb4;
|
||||
|
||||
INSERT INTO iam_permission
|
||||
(id, tenant_id, app_code, permission_type, parent_id, permission_code,
|
||||
permission_name, route_path, http_method, sort_no, status, built_in, deleted)
|
||||
VALUES
|
||||
(5102041,0,'PLATFORM','MENU',5102000,'platform:firstleg:inbound:measure:view','订单测量','/inbounds/measurements','GET',30,'ACTIVE',1,0),
|
||||
(5102051,0,'PLATFORM','MENU',5102000,'firstleg:inbound:measurement-review','测量数据审核','/inbounds/measurement-reviews','GET',40,'ACTIVE',1,0),
|
||||
(5103070,0,'PLATFORM','API',5103010,'platform:domestic-container:list','整柜业务','/api/platform/v1/domestic-containers','GET',70,'ACTIVE',1,0),
|
||||
(5103071,0,'PLATFORM','BUTTON',5103070,'platform:domestic-container:inbound:create','新建整柜入库单',NULL,'POST',10,'ACTIVE',1,0),
|
||||
(5103072,0,'PLATFORM','BUTTON',5103070,'platform:domestic-container:outbound:create','新建整柜出库单',NULL,'POST',20,'ACTIVE',1,0),
|
||||
(5103080,0,'PLATFORM','MENU',5103000,'platform:supplier:list','供应商列表','/suppliers','GET',80,'ACTIVE',1,0),
|
||||
(5103081,0,'PLATFORM','BUTTON',5103080,'platform:supplier:create','新增供应商',NULL,'POST',10,'ACTIVE',1,0),
|
||||
(5103082,0,'PLATFORM','BUTTON',5103080,'platform:supplier:edit','编辑供应商',NULL,'PUT',20,'ACTIVE',1,0),
|
||||
(5103083,0,'PLATFORM','BUTTON',5103080,'platform:supplier:status','启停供应商',NULL,'PATCH',30,'ACTIVE',1,0),
|
||||
(5105040,0,'PLATFORM','MENU',5105000,'platform:finance:customer-account:list','客户账户','/finance/customer-accounts','GET',10,'ACTIVE',1,0),
|
||||
(5105041,0,'PLATFORM','MENU',5105000,'platform:finance:customer-arap:list','客户应收应付','/finance/customer-arap','GET',20,'ACTIVE',1,0),
|
||||
(5105042,0,'PLATFORM','MENU',5105000,'platform:finance:customer-statement:list','客户对账单','/finance/customer-statements','GET',30,'ACTIVE',1,0),
|
||||
(5105043,0,'PLATFORM','MENU',5105000,'platform:finance:settlement-ar:list','结算单应收','/finance/settlement-receivables','GET',40,'ACTIVE',1,0),
|
||||
(5105044,0,'PLATFORM','MENU',5105000,'platform:finance:settlement-ap:list','结算单应付','/finance/settlement-payables','GET',50,'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),
|
||||
http_method=VALUES(http_method), sort_no=VALUES(sort_no), status='ACTIVE',
|
||||
built_in=1, deleted=0;
|
||||
|
||||
UPDATE iam_permission
|
||||
SET status='INACTIVE', deleted=1
|
||||
WHERE tenant_id=0 AND app_code='PLATFORM'
|
||||
AND permission_code IN ('platform:overseas-storage-fee:create','platform:overseas-storage-fee:delete');
|
||||
|
||||
INSERT IGNORE INTO iam_role_permission (tenant_id, role_id, permission_id, created_at)
|
||||
SELECT 0, r.id, p.id, CURRENT_TIMESTAMP(3)
|
||||
FROM iam_role r
|
||||
JOIN iam_permission p ON p.tenant_id=0 AND p.app_code='PLATFORM'
|
||||
WHERE r.tenant_id=0 AND r.app_code='PLATFORM' AND r.role_code='PLATFORM_ADMIN'
|
||||
AND p.permission_code IN (
|
||||
'platform:finance:customer-account:list','platform:finance:customer-arap:list',
|
||||
'platform:finance:customer-statement:list','platform:finance:settlement-ar:list',
|
||||
'platform:finance:settlement-ap:list','platform:firstleg:inbound:measure:view',
|
||||
'firstleg:inbound:measurement-review','platform:supplier:list',
|
||||
'platform:supplier:create','platform:supplier:edit','platform:supplier:status',
|
||||
'platform:domestic-container:list','platform:domestic-container:inbound:create',
|
||||
'platform:domestic-container:outbound:create');
|
||||
|
||||
UPDATE iam_permission p
|
||||
JOIN (SELECT 'platform:firstleg:inbound:measure:edit' code, 5102041 parent_id UNION ALL
|
||||
SELECT 'platform:firstleg:inbound:measure:submit', 5102041 UNION ALL
|
||||
SELECT 'platform:firstleg:inbound:measure:manual-entry', 5102041 UNION ALL
|
||||
SELECT 'platform:firstleg:inbound:weight:edit', 5102041 UNION ALL
|
||||
SELECT 'platform:firstleg:inbound:weight:confirm', 5102041 UNION ALL
|
||||
SELECT 'firstleg:inbound:measurement-review-history', 5102051 UNION ALL
|
||||
SELECT 'firstleg:inbound:exception-release', 5102051) mapping
|
||||
ON mapping.code=p.permission_code
|
||||
SET p.parent_id=mapping.parent_id
|
||||
WHERE p.tenant_id=0 AND p.app_code='PLATFORM';
|
||||
|
||||
UPDATE iam_permission p
|
||||
JOIN (SELECT 'platform:finance:account:view' code, 5105040 parent_id UNION ALL
|
||||
SELECT 'platform:finance:fee-source:view', 5105041 UNION ALL
|
||||
SELECT 'platform:finance:fee-source:review', 5105041 UNION ALL
|
||||
SELECT 'platform:finance:fee-source:settlement', 5105041 UNION ALL
|
||||
SELECT 'platform:finance:reconciliation:create', 5105042 UNION ALL
|
||||
SELECT 'platform:finance:reconciliation:review', 5105042 UNION ALL
|
||||
SELECT 'platform:finance:reconciliation:issue', 5105042 UNION ALL
|
||||
SELECT 'platform:finance:reconciliation:adjust', 5105042 UNION ALL
|
||||
SELECT 'platform:finance:reconciliation:void', 5105042 UNION ALL
|
||||
SELECT 'platform:finance:settlement-ar:create', 5105043 UNION ALL
|
||||
SELECT 'platform:finance:settlement-ar:view', 5105043 UNION ALL
|
||||
SELECT 'platform:finance:settlement-ap:create', 5105044 UNION ALL
|
||||
SELECT 'platform:finance:settlement-ap:view', 5105044 UNION ALL
|
||||
SELECT 'platform:finance:payment:create', 5105044) mapping
|
||||
ON mapping.code=p.permission_code
|
||||
SET p.parent_id=mapping.parent_id
|
||||
WHERE p.tenant_id=0 AND p.app_code='PLATFORM' AND p.permission_type='BUTTON';
|
||||
@@ -0,0 +1,61 @@
|
||||
USE baiyue_iam;
|
||||
SET NAMES utf8mb4;
|
||||
|
||||
DROP PROCEDURE IF EXISTS migrate_domestic_container_permissions;
|
||||
DELIMITER $$
|
||||
CREATE PROCEDURE migrate_domestic_container_permissions()
|
||||
BEGIN
|
||||
IF EXISTS (
|
||||
SELECT 1 FROM iam_permission
|
||||
WHERE (id = 5103070 AND permission_code <> 'platform:domestic-container:list')
|
||||
OR (id = 5103071 AND permission_code <> 'platform:domestic-container:inbound:create')
|
||||
OR (id = 5103072 AND permission_code <> 'platform:domestic-container:outbound:create')
|
||||
OR (permission_code = 'platform:domestic-container:list' AND id <> 5103070)
|
||||
OR (permission_code = 'platform:domestic-container:inbound:create' AND id <> 5103071)
|
||||
OR (permission_code = 'platform:domestic-container:outbound:create' AND id <> 5103072)
|
||||
) THEN
|
||||
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'domestic container permission id/code conflict';
|
||||
END IF;
|
||||
|
||||
INSERT INTO iam_permission
|
||||
(id, tenant_id, app_code, permission_type, parent_id, permission_code,
|
||||
permission_name, route_path, http_method, sort_no, status, built_in, deleted)
|
||||
VALUES
|
||||
(5103070,0,'PLATFORM','API',5103010,'platform:domestic-container:list',
|
||||
'查看国内整柜业务','/api/platform/v1/domestic-containers','GET',40,'ACTIVE',1,0),
|
||||
(5103071,0,'PLATFORM','BUTTON',5103070,'platform:domestic-container:inbound:create',
|
||||
'新建整柜入库单','/api/platform/v1/domestic-containers/inbounds','POST',10,'ACTIVE',1,0),
|
||||
(5103072,0,'PLATFORM','BUTTON',5103070,'platform:domestic-container:outbound:create',
|
||||
'新建整柜出库单','/api/platform/v1/domestic-containers/outbounds','POST',20,'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),
|
||||
http_method=VALUES(http_method), sort_no=VALUES(sort_no), status='ACTIVE', built_in=1, deleted=0;
|
||||
|
||||
INSERT IGNORE INTO iam_role_permission (tenant_id, role_id, permission_id, created_at)
|
||||
SELECT 0, r.id, p.id, CURRENT_TIMESTAMP(3)
|
||||
FROM iam_role r
|
||||
JOIN iam_permission p ON p.tenant_id=0 AND p.app_code='PLATFORM'
|
||||
WHERE r.tenant_id=0 AND r.app_code='PLATFORM' AND r.role_code='PLATFORM_ADMIN'
|
||||
AND r.status='ACTIVE' AND r.deleted=0
|
||||
AND p.permission_code IN ('platform:domestic-container:list',
|
||||
'platform:domestic-container:inbound:create','platform:domestic-container:outbound:create');
|
||||
|
||||
IF (SELECT COUNT(*) FROM iam_permission WHERE tenant_id=0 AND app_code='PLATFORM'
|
||||
AND status='ACTIVE' AND built_in=1 AND deleted=0
|
||||
AND permission_code IN ('platform:domestic-container:list',
|
||||
'platform:domestic-container:inbound:create','platform:domestic-container:outbound:create')) <> 3 THEN
|
||||
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'domestic container permission catalog is incomplete';
|
||||
END IF;
|
||||
IF (SELECT COUNT(*) FROM iam_role_permission rp
|
||||
JOIN iam_role r ON r.id=rp.role_id AND r.tenant_id=rp.tenant_id
|
||||
JOIN 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='PLATFORM_ADMIN'
|
||||
AND p.permission_code IN ('platform:domestic-container:list',
|
||||
'platform:domestic-container:inbound:create','platform:domestic-container:outbound:create')) <> 3 THEN
|
||||
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'PLATFORM_ADMIN domestic container grant is incomplete';
|
||||
END IF;
|
||||
END$$
|
||||
DELIMITER ;
|
||||
CALL migrate_domestic_container_permissions();
|
||||
DROP PROCEDURE IF EXISTS migrate_domestic_container_permissions;
|
||||
@@ -58,24 +58,28 @@ VALUES
|
||||
(5106000,0,'PLATFORM','MENU',0,'platform:notification','消息中心','/notifications',NULL,600,'ACTIVE',0),
|
||||
(5106001,0,'PLATFORM','API',5106000,'platform:notification:view','查看消息','/api/platform/v1/notifications','GET',601,'ACTIVE',0),
|
||||
(5106002,0,'PLATFORM','BUTTON',5106000,'platform:notification:create','发送消息','/api/platform/v1/notifications','POST',602,'ACTIVE',0),
|
||||
(5106003,0,'PLATFORM','API',5106000,'platform:notification:template:list','查看消息模板','/api/platform/v1/notification-templates','GET',603,'ACTIVE',0),
|
||||
(5106003,0,'PLATFORM','MENU',5106000,'platform:notification:template:list','模板管理','/notifications/templates','GET',603,'ACTIVE',0),
|
||||
(5106004,0,'PLATFORM','BUTTON',5106000,'platform:notification:template:create','新增消息模板','/api/platform/v1/notification-templates','POST',604,'ACTIVE',0),
|
||||
(5106005,0,'PLATFORM','BUTTON',5106000,'platform:notification:template:edit','编辑消息模板','/api/platform/v1/notification-templates/{id}','PUT',605,'ACTIVE',0),
|
||||
(5106006,0,'PLATFORM','BUTTON',5106000,'platform:notification:template:status','变更模板状态','/api/platform/v1/notification-templates/{id}/status','PUT',606,'ACTIVE',0),
|
||||
(5106007,0,'PLATFORM','API',5106000,'platform:notification:task:list','查看消息任务','/api/platform/v1/notification-tasks','GET',607,'ACTIVE',0),
|
||||
(5106007,0,'PLATFORM','MENU',5106000,'platform:notification:task:list','消息管理','/notifications/messages','GET',607,'ACTIVE',0),
|
||||
(5106008,0,'PLATFORM','BUTTON',5106000,'platform:notification:task:cancel','取消消息任务','/api/platform/v1/notification-tasks/{id}/cancel','PUT',608,'ACTIVE',0),
|
||||
(5106009,0,'PLATFORM','BUTTON',5106000,'platform:notification:task:retry','重试消息任务','/api/platform/v1/notification-tasks/{id}/retry','PUT',609,'ACTIVE',0)
|
||||
(5106009,0,'PLATFORM','BUTTON',5106000,'platform:notification:task:retry','重试消息任务','/api/platform/v1/notification-tasks/{id}/retry','PUT',609,'ACTIVE',0),
|
||||
(5106011,0,'PLATFORM','BUTTON',5106001,'platform:notification:read','标记消息已读','/api/platform/v1/notifications/{id}/read','PUT',610,'ACTIVE',0),
|
||||
(5106012,0,'PLATFORM','BUTTON',5106001,'platform:notification:read-all','全部标记已读','/api/platform/v1/notifications/read-all','PUT',611,'ACTIVE',0)
|
||||
ON DUPLICATE KEY UPDATE permission_name=VALUES(permission_name), route_path=VALUES(route_path), http_method=VALUES(http_method), 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 (5106010, 0, 'MERCHANT', 'API', 0, 'merchant:notification:view', '查看我的消息',
|
||||
'/api/merchant/v1/notifications', 'GET', 900, 'ACTIVE', 0)
|
||||
VALUES
|
||||
(5106010,0,'MERCHANT','API',0,'merchant:notification:view','查看我的消息','/api/merchant/v1/notifications','GET',900,'ACTIVE',0),
|
||||
(5106013,0,'MERCHANT','BUTTON',5106010,'merchant:notification:read','标记消息已读','/api/merchant/v1/notifications/{id}/read','PUT',901,'ACTIVE',0),
|
||||
(5106014,0,'MERCHANT','BUTTON',5106010,'merchant:notification:read-all','全部标记已读','/api/merchant/v1/notifications/read-all','PUT',902,'ACTIVE',0)
|
||||
ON DUPLICATE KEY UPDATE permission_name=VALUES(permission_name), route_path=VALUES(route_path), status='ACTIVE', deleted=0;
|
||||
|
||||
INSERT IGNORE INTO iam_role_permission (tenant_id, role_id, permission_id, created_at)
|
||||
SELECT 0, r.id, p.id, CURRENT_TIMESTAMP(3)
|
||||
FROM iam_permission p JOIN iam_role r ON r.tenant_id=0 AND r.app_code='MERCHANT' AND r.status='ACTIVE'
|
||||
WHERE p.tenant_id=0 AND p.permission_code='merchant:notification:view' AND r.role_code='MERCHANT_OWNER';
|
||||
WHERE p.tenant_id=0 AND p.permission_code IN ('merchant:notification:view','merchant:notification:read','merchant:notification:read-all') AND r.role_code='MERCHANT_OWNER';
|
||||
|
||||
INSERT IGNORE INTO iam_role_permission (tenant_id, role_id, permission_id, created_at)
|
||||
SELECT 0, r.id, p.id, CURRENT_TIMESTAMP(3)
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
-- 平台供应商权限资源及 PLATFORM_ADMIN 默认授权;可重复执行。
|
||||
USE baiyue_iam;
|
||||
SET NAMES utf8mb4;
|
||||
|
||||
DROP PROCEDURE IF EXISTS guard_platform_supplier_permission_ids;
|
||||
DELIMITER $$
|
||||
CREATE PROCEDURE guard_platform_supplier_permission_ids()
|
||||
BEGIN
|
||||
IF EXISTS (SELECT 1 FROM iam_permission WHERE id BETWEEN 5103080 AND 5103083 AND permission_code <> CASE id WHEN 5103080 THEN 'platform:supplier:list' WHEN 5103081 THEN 'platform:supplier:create' WHEN 5103082 THEN 'platform:supplier:edit' WHEN 5103083 THEN 'platform:supplier:status' END)
|
||||
OR EXISTS (SELECT 1 FROM iam_permission WHERE permission_code IN ('platform:supplier:list','platform:supplier:create','platform:supplier:edit','platform:supplier:status') AND id NOT BETWEEN 5103080 AND 5103083) THEN
|
||||
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT='供应商权限固定ID或权限码已被其他语义占用';
|
||||
END IF;
|
||||
END$$
|
||||
DELIMITER ;
|
||||
CALL guard_platform_supplier_permission_ids();
|
||||
DROP PROCEDURE guard_platform_supplier_permission_ids;
|
||||
|
||||
INSERT INTO iam_permission
|
||||
(id,tenant_id,app_code,permission_type,parent_id,permission_code,permission_name,route_path,http_method,sort_no,status,built_in,deleted)
|
||||
VALUES
|
||||
(5103080,0,'PLATFORM','MENU',5103000,'platform:supplier:list','供应商列表','/suppliers','GET',80,'ACTIVE',1,0),
|
||||
(5103081,0,'PLATFORM','BUTTON',5103080,'platform:supplier:create','新增供应商',NULL,'POST',10,'ACTIVE',1,0),
|
||||
(5103082,0,'PLATFORM','BUTTON',5103080,'platform:supplier:edit','编辑供应商',NULL,'PUT',20,'ACTIVE',1,0),
|
||||
(5103083,0,'PLATFORM','BUTTON',5103080,'platform:supplier:status','启停供应商',NULL,'PATCH',30,'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),http_method=VALUES(http_method),sort_no=VALUES(sort_no),status='ACTIVE',built_in=1,deleted=0;
|
||||
|
||||
INSERT IGNORE INTO iam_role_permission (tenant_id,role_id,permission_id,created_at)
|
||||
SELECT 0,r.id,p.id,CURRENT_TIMESTAMP(3)
|
||||
FROM iam_role r JOIN iam_permission p ON p.tenant_id=0 AND p.app_code='PLATFORM'
|
||||
WHERE r.tenant_id=0 AND r.app_code='PLATFORM' AND r.role_code='PLATFORM_ADMIN' AND r.status='ACTIVE' AND r.deleted=0
|
||||
AND p.permission_code IN ('platform:supplier:list','platform:supplier:create','platform:supplier:edit','platform:supplier:status');
|
||||
|
||||
DROP PROCEDURE IF EXISTS assert_platform_supplier_permissions;
|
||||
DELIMITER $$
|
||||
CREATE PROCEDURE assert_platform_supplier_permissions()
|
||||
BEGIN
|
||||
IF (SELECT COUNT(*) FROM iam_permission WHERE tenant_id=0 AND app_code='PLATFORM' AND status='ACTIVE' AND deleted=0 AND permission_code IN ('platform:supplier:list','platform:supplier:create','platform:supplier:edit','platform:supplier:status')) <> 4 THEN
|
||||
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT='供应商权限资源初始化不完整';
|
||||
END IF;
|
||||
IF (SELECT COUNT(*) FROM iam_role_permission rp JOIN iam_role r ON r.id=rp.role_id AND r.tenant_id=rp.tenant_id JOIN iam_permission p ON p.id=rp.permission_id AND p.tenant_id=rp.tenant_id WHERE r.role_code='PLATFORM_ADMIN' AND p.permission_code IN ('platform:supplier:list','platform:supplier:create','platform:supplier:edit','platform:supplier:status')) <> 4 THEN
|
||||
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT='PLATFORM_ADMIN供应商权限授权不完整';
|
||||
END IF;
|
||||
END$$
|
||||
DELIMITER ;
|
||||
CALL assert_platform_supplier_permissions();
|
||||
DROP PROCEDURE assert_platform_supplier_permissions;
|
||||
@@ -35,12 +35,14 @@ paths:
|
||||
put:
|
||||
tags: [Notification inbox]
|
||||
summary: Mark one message as read (idempotent)
|
||||
description: Requires {app}:notification:read.
|
||||
parameters: [{$ref: '#/components/parameters/AppPath'}, {$ref: '#/components/parameters/IdPath'}]
|
||||
responses: {'200': {$ref: '#/components/responses/InboxDetail'}}
|
||||
/{app}/v1/notifications/read-all:
|
||||
put:
|
||||
tags: [Notification inbox]
|
||||
summary: Mark all current-user messages as read (idempotent)
|
||||
description: Requires {app}:notification:read-all.
|
||||
parameters: [{$ref: '#/components/parameters/AppPath'}]
|
||||
responses: {'200': {$ref: '#/components/responses/ReadAll'}}
|
||||
/platform/v1/notifications:
|
||||
|
||||
+69
@@ -0,0 +1,69 @@
|
||||
package com.baiyue.iam.repository;
|
||||
|
||||
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 AdminPrototypeMenuPermissionSqlContractTest {
|
||||
private static final String[] FINANCE_MENUS = {
|
||||
"platform:finance:customer-account:list", "platform:finance:customer-arap:list",
|
||||
"platform:finance:customer-statement:list", "platform:finance:settlement-ar:list",
|
||||
"platform:finance:settlement-ap:list"
|
||||
};
|
||||
|
||||
@Test
|
||||
void declaresFinancePageMenusAndReparentsActions() throws Exception {
|
||||
String sql = new ClassPathResource("db/admin-prototype-menu-permissions.sql")
|
||||
.getContentAsString(StandardCharsets.UTF_8);
|
||||
|
||||
for (int index = 0; index < FINANCE_MENUS.length; index++) {
|
||||
assertThat(sql).contains("(" + (5105040 + index) + ",0,'PLATFORM','MENU',5105000,'" + FINANCE_MENUS[index] + "'");
|
||||
}
|
||||
assertThat(sql)
|
||||
.contains("'platform:finance:account:view' code, 5105040 parent_id")
|
||||
.contains("'platform:finance:fee-source:view', 5105041")
|
||||
.contains("'platform:finance:reconciliation:create', 5105042")
|
||||
.contains("'platform:finance:settlement-ar:create', 5105043")
|
||||
.contains("'platform:finance:settlement-ap:create', 5105044")
|
||||
.contains("'platform:finance:payment:create', 5105044)")
|
||||
.contains("role_code='PLATFORM_ADMIN'");
|
||||
}
|
||||
|
||||
@Test
|
||||
void retiresUnsupportedOverseasFeeCreateAndDelete() throws Exception {
|
||||
String sql = new ClassPathResource("db/admin-prototype-menu-permissions.sql")
|
||||
.getContentAsString(StandardCharsets.UTF_8);
|
||||
|
||||
assertThat(sql).contains("status='INACTIVE', deleted=1")
|
||||
.contains("'platform:overseas-storage-fee:create','platform:overseas-storage-fee:delete'");
|
||||
|
||||
String unified = Files.readString(resolveUnifiedSql(), StandardCharsets.UTF_8);
|
||||
assertThat(unified).contains("<> 2")
|
||||
.contains("platform:overseas-storage-fee:list', 'platform:overseas-storage-fee:create'");
|
||||
}
|
||||
|
||||
@Test
|
||||
void keepsDomesticContainerAndSupplierPermissionIdsDisjoint() throws Exception {
|
||||
String sql = new ClassPathResource("db/admin-prototype-menu-permissions.sql")
|
||||
.getContentAsString(StandardCharsets.UTF_8);
|
||||
assertThat(sql)
|
||||
.contains("(5103070,0,'PLATFORM','API',5103010,'platform:domestic-container:list'")
|
||||
.contains("(5103071,0,'PLATFORM','BUTTON',5103070,'platform:domestic-container:inbound:create'")
|
||||
.contains("(5103072,0,'PLATFORM','BUTTON',5103070,'platform:domestic-container:outbound:create'")
|
||||
.contains("(5103080,0,'PLATFORM','MENU',5103000,'platform:supplier:list'")
|
||||
.contains("(5103081,0,'PLATFORM','BUTTON',5103080,'platform:supplier:create'")
|
||||
.contains("(5103082,0,'PLATFORM','BUTTON',5103080,'platform:supplier:edit'")
|
||||
.contains("(5103083,0,'PLATFORM','BUTTON',5103080,'platform:supplier:status'")
|
||||
.doesNotContain("platform:supplier:view");
|
||||
}
|
||||
|
||||
private static Path resolveUnifiedSql() {
|
||||
Path direct = Path.of("deploy", "sql", "头程数据库统一增量-MySQL8.sql");
|
||||
return Files.exists(direct) ? direct : Path.of("..", "deploy", "sql", "头程数据库统一增量-MySQL8.sql");
|
||||
}
|
||||
}
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
package com.baiyue.iam.repository;
|
||||
|
||||
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 DomesticContainerPermissionSqlContractTest {
|
||||
@Test
|
||||
void registersAndGrantsDedicatedPermissionsIdempotently() throws Exception {
|
||||
String sql = new ClassPathResource("db/domestic-container-permissions.sql")
|
||||
.getContentAsString(StandardCharsets.UTF_8);
|
||||
assertThat(sql).contains("5103070", "5103071", "5103072",
|
||||
"platform:domestic-container:list", "platform:domestic-container:inbound:create",
|
||||
"platform:domestic-container:outbound:create", "ON DUPLICATE KEY UPDATE",
|
||||
"INSERT IGNORE INTO iam_role_permission", "role_code='PLATFORM_ADMIN'", "<> 3");
|
||||
assertThat(sql).contains("permission id/code conflict", "permission catalog is incomplete",
|
||||
"PLATFORM_ADMIN domestic container grant is incomplete");
|
||||
}
|
||||
|
||||
@Test
|
||||
void reservesFinalIdsAndRejectsSupplierReuse() throws Exception {
|
||||
String sql = new ClassPathResource("db/domestic-container-permissions.sql")
|
||||
.getContentAsString(StandardCharsets.UTF_8);
|
||||
assertThat(sql).contains("(5103070,0,'PLATFORM','API'", "(5103071,0,'PLATFORM','BUTTON',5103070",
|
||||
"(5103072,0,'PLATFORM','BUTTON',5103070");
|
||||
Path supplier = Path.of("src/main/resources/db/platform-supplier-permissions.sql");
|
||||
if (!Files.exists(supplier)) supplier = Path.of("iam/src/main/resources/db/platform-supplier-permissions.sql");
|
||||
if (Files.exists(supplier)) {
|
||||
String supplierSql = Files.readString(supplier, StandardCharsets.UTF_8);
|
||||
assertThat(supplierSql).doesNotContain("5103070", "5103071", "5103072");
|
||||
}
|
||||
}
|
||||
}
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
package com.baiyue.iam.repository;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
class PlatformSupplierPermissionSqlContractTest {
|
||||
@Test void registersFourSupplierPermissionsAndGrantsPlatformAdmin() throws Exception {
|
||||
String sql = new ClassPathResource("db/platform-supplier-permissions.sql").getContentAsString(StandardCharsets.UTF_8);
|
||||
assertThat(sql).contains("5103080", "5103081", "5103082", "5103083",
|
||||
"platform:supplier:list", "platform:supplier:create",
|
||||
"platform:supplier:edit", "platform:supplier:status", "role_code='PLATFORM_ADMIN'",
|
||||
"ON DUPLICATE KEY UPDATE", "INSERT IGNORE INTO iam_role_permission",
|
||||
"guard_platform_supplier_permission_ids", "SIGNAL SQLSTATE '45000'",
|
||||
"assert_platform_supplier_permissions");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user