This commit is contained in:
2026-08-08 12:01:45 +08:00
parent 1a2f598c9a
commit a35cd868b9
56 changed files with 7178 additions and 735 deletions
+2 -1
View File
@@ -55,7 +55,8 @@
- 三期平台权限直接维护在统一初始化与发布入口中,避免额外增加独立权限脚本。
- 测试和生产环境仍只执行固定入口 `头程数据库统一增量-MySQL8.sql`,不得再串行执行上述模块脚本。
- 必须先执行统一增量并取得 `PASS`,再启动或重启 Firstleg Service;否则统一订单摘要查询会因缺少三期操作表而失败。
- 统一脚本会创建 `fl_preload_plan`、`fl_split_operation`、`fl_loading_evidence`、`fl_loading_operation`、`fl_loading_pick_task`,并补齐 9 项平台操作权限。新增权限默认只授予平台系统管理员,其他角色由平台权限管理按职责配置。
- 统一脚本会创建智能装柜任务 `fl_loading_pick_task`,并把历史入库汇总任务按字段签名无损迁移到 `fl_inbound_loading_pick_task`;未知混合结构会直接终止。`WAIT_SPLIT` 是二期有效终点,脚本不会改写主表或状态历史。
- 下载中心固定使用 `5103040-5103041`,库位权限迁移到 `5103060-5103064`;入库装柜权限迁移到 `5102121-5102129`,迁移会按 `permission_code` 保留角色授权,目标 ID 被其他语义占用时直接终止。
部署前可只读盘点:
+272 -151
View File
@@ -2510,6 +2510,30 @@ CREATE TABLE IF NOT EXISTS fl_inbound_measurement_item (
CONSTRAINT fk_measure_item_batch FOREIGN KEY (measurement_id) REFERENCES fl_inbound_measurement (id)
) ENGINE=InnoDB COMMENT='入库长宽高和箱数测量明细';
CREATE TABLE IF NOT EXISTS fl_mojia_measurement_receipt (
id BIGINT UNSIGNED NOT NULL COMMENT '墨家联调收件记录ID',
tenant_id BIGINT UNSIGNED NOT NULL COMMENT '客户隔离ID',
subject_id BIGINT UNSIGNED NOT NULL COMMENT '设备应用操作主体ID',
box_code VARCHAR(128) NOT NULL COMMENT '设备扫描的原始箱码',
length_cm DECIMAL(12,3) NOT NULL COMMENT '设备实测长度cm',
width_cm DECIMAL(12,3) NOT NULL COMMENT '设备实测宽度cm',
height_cm DECIMAL(12,3) NOT NULL COMMENT '设备实测高度cm',
weight_kg DECIMAL(18,3) NULL COMMENT '设备实测重量kg',
machine_no VARCHAR(64) NOT NULL COMMENT '设备编号',
measured_at DATETIME(3) NOT NULL COMMENT '设备测量时间或服务接收时间',
image_file_id BIGINT UNSIGNED NOT NULL COMMENT 'File服务中的墨家联调图片ID',
status VARCHAR(24) NOT NULL DEFAULT 'UNMATCHED' COMMENT '收件状态',
match_failure_code VARCHAR(16) NOT NULL COMMENT '正式业务匹配失败码',
match_failure_reason VARCHAR(500) NOT NULL COMMENT '脱敏后的匹配失败原因',
request_id VARCHAR(128) NULL COMMENT '请求链路ID',
trace_id VARCHAR(128) NULL COMMENT '调用链ID',
created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '创建时间',
updated_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3) COMMENT '更新时间',
PRIMARY KEY (id),
KEY idx_mojia_receipt_status_time (tenant_id, status, created_at),
KEY idx_mojia_receipt_box_time (tenant_id, box_code, created_at)
) ENGINE=InnoDB COMMENT='墨家模拟或未匹配入库单的原始测量收件箱';
CREATE TABLE IF NOT EXISTS fl_inbound_carton_label (
id BIGINT UNSIGNED NOT NULL COMMENT '实际箱唛头映射ID(雪花ID)',
tenant_id BIGINT UNSIGNED NOT NULL COMMENT '当前客户隔离ID',
@@ -3429,6 +3453,66 @@ ON DUPLICATE KEY UPDATE tenant_id = VALUES(tenant_id);
USE baiyue_iam;
SET NAMES utf8mb4;
DROP PROCEDURE IF EXISTS repair_location_permission_ids;
DELIMITER $$
CREATE PROCEDURE repair_location_permission_ids()
BEGIN
IF EXISTS (
SELECT 1 FROM iam_permission
WHERE id IN (5103060, 5103061, 5103062, 5103063, 5103064)
AND permission_code <> CASE id
WHEN 5103060 THEN 'platform:location:list'
WHEN 5103061 THEN 'platform:location:create'
WHEN 5103062 THEN 'platform:location:edit'
WHEN 5103063 THEN 'platform:location:status'
WHEN 5103064 THEN 'platform:location:delete'
END
) THEN
SIGNAL SQLSTATE '45000'
SET MESSAGE_TEXT = '库位权限迁移失败:5103060-5103064 已被其他权限占用';
END IF;
IF EXISTS (
SELECT 1 FROM iam_permission
WHERE (id = 5103040 AND permission_code <> 'platform:download:list')
OR (id = 5103041 AND permission_code <> 'platform:download:all')
OR (permission_code = 'platform:download:list' AND id <> 5103040)
OR (permission_code = 'platform:download:all' AND id <> 5103041)
) THEN
SIGNAL SQLSTATE '45000'
SET MESSAGE_TEXT = '库位权限迁移失败:下载中心稳定 ID 被未知权限占用';
END IF;
DROP TEMPORARY TABLE IF EXISTS tmp_location_role_grant;
CREATE TEMPORARY TABLE tmp_location_role_grant (
role_id BIGINT UNSIGNED NOT NULL, tenant_id BIGINT UNSIGNED NOT NULL,
permission_code VARCHAR(128) NOT NULL,
PRIMARY KEY (role_id, tenant_id, permission_code)
) ENGINE=MEMORY;
INSERT IGNORE INTO tmp_location_role_grant (role_id, tenant_id, permission_code)
SELECT rp.role_id, rp.tenant_id, permission.permission_code
FROM iam_role_permission rp JOIN iam_permission permission ON permission.id = rp.permission_id
WHERE permission.permission_code IN ('platform:location:list', 'platform:location:create',
'platform:location:edit', 'platform:location:status', 'platform:location:delete');
DELETE rp FROM iam_role_permission rp
JOIN iam_permission permission ON permission.id = rp.permission_id
WHERE permission.permission_code IN ('platform:location:list', 'platform:location:create',
'platform:location:edit', 'platform:location:status', 'platform:location:delete');
DELETE FROM iam_permission WHERE permission_code IN ('platform:location:create',
'platform:location:edit', 'platform:location:status', 'platform:location:delete');
DELETE FROM iam_permission WHERE permission_code = 'platform:location:list';
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
(5103040, 0, 'PLATFORM', 'MENU', 5103000, 'platform:download:list', '下载中心', '/downloads', NULL, 40, 'ACTIVE', 1, 0),
(5103041, 0, 'PLATFORM', 'BUTTON', 5103040, 'platform:download:all', '查看全部下载任务', NULL, NULL, 10, '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;
END$$
DELIMITER ;
CALL repair_location_permission_ids();
DROP PROCEDURE repair_location_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, deleted)
@@ -3560,21 +3644,27 @@ 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
(5103040, 0, 'PLATFORM', 'MENU', 5103000, 'platform:location:list', '库位管理',
(5103060, 0, 'PLATFORM', 'MENU', 5103000, 'platform:location:list', '库位管理',
'/master-data/locations', NULL, 40, 'ACTIVE', 1, 0),
(5103041, 0, 'PLATFORM', 'BUTTON', 5103040, 'platform:location:create', '新增库位',
(5103061, 0, 'PLATFORM', 'BUTTON', 5103060, 'platform:location:create', '新增库位',
NULL, NULL, 10, 'ACTIVE', 1, 0),
(5103042, 0, 'PLATFORM', 'BUTTON', 5103040, 'platform:location:edit', '编辑库位',
(5103062, 0, 'PLATFORM', 'BUTTON', 5103060, 'platform:location:edit', '编辑库位',
NULL, NULL, 20, 'ACTIVE', 1, 0),
(5103043, 0, 'PLATFORM', 'BUTTON', 5103040, 'platform:location:status', '启停库位',
(5103063, 0, 'PLATFORM', 'BUTTON', 5103060, 'platform:location:status', '启停库位',
NULL, NULL, 30, 'ACTIVE', 1, 0),
(5103044, 0, 'PLATFORM', 'BUTTON', 5103040, 'platform:location:delete', '删除库位',
(5103064, 0, 'PLATFORM', 'BUTTON', 5103060, 'platform:location:delete', '删除库位',
NULL, NULL, 40, '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),
sort_no = VALUES(sort_no), status = 'ACTIVE', built_in = 1, deleted = 0;
INSERT IGNORE INTO iam_role_permission (role_id, permission_id, tenant_id)
SELECT saved.role_id, permission.id, saved.tenant_id
FROM tmp_location_role_grant saved
JOIN iam_permission permission ON permission.permission_code = saved.permission_code
AND permission.tenant_id = 0 AND permission.app_code = 'PLATFORM';
-- 二期新增库位权限默认只授予平台系统管理员。
INSERT INTO iam_role_permission (role_id, permission_id, tenant_id)
SELECT 4000001, id, 0
@@ -3586,6 +3676,8 @@ WHERE tenant_id = 0 AND app_code = 'PLATFORM'
)
ON DUPLICATE KEY UPDATE tenant_id = VALUES(tenant_id);
DROP TEMPORARY TABLE IF EXISTS tmp_location_role_grant;
-- ============================================================================
-- 来源:iam\src\main\resources\db\phase2-pallet-permissions.sql
-- ============================================================================
@@ -5026,120 +5118,9 @@ BEGIN
IF (SELECT COUNT(*) FROM information_schema.check_constraints
WHERE constraint_schema = 'baiyue_firstleg'
AND constraint_name = 'chk_loading_plan_status'
AND check_clause LIKE '%''EDITING''%'
AND check_clause LIKE '%''LOADING''%'
AND check_clause LIKE '%''COMPLETED''%') <> 1 THEN
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = '智能装柜迁移失败:装柜状态约束不是最终三状态';
END IF;
IF (SELECT COUNT(*) FROM information_schema.columns
WHERE table_schema = 'baiyue_firstleg' AND table_name = 'fl_container_booking'
AND column_name IN ('booking_no', 'cabinet_no', 'warehouse_id', 'bill_of_lading_no',
'vessel_name', 'voyage_no', 'container_type', 'capacity_cbm',
'max_weight_kg', 'terminal_trucking_company')) <> 10 THEN
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = '智能装柜迁移失败:货柜原型字段缺失';
END IF;
IF (SELECT COUNT(*) FROM information_schema.columns
WHERE table_schema = 'baiyue_firstleg' AND table_name = 'fl_loading_plan_item'
AND column_name IN ('account_id', 'customer_name', 'active_inbound_detail_id', 'frozen_at',
'destination_warehouse_name', 'product_name_zh', 'product_name_en',
'product_image_file_id', 'pallet_count', 'net_weight_kg',
'dimensional_weight_kg', 'product_quantity', 'units_per_carton',
'fba_tracking_no', 'shipment_no', 'shipping_mark', 'version')) <> 17 THEN
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = '智能装柜迁移失败:明细归属、清单快照或冻结字段缺失';
END IF;
IF (SELECT COUNT(*) FROM information_schema.statistics
WHERE table_schema = 'baiyue_firstleg' AND table_name = 'fl_loading_plan_item'
AND index_name = 'uk_loading_item_plan_detail' AND non_unique = 0) <> 2 THEN
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = '智能装柜迁移失败:计划内唯一活动明细锁缺失';
END IF;
IF (SELECT COUNT(*) FROM information_schema.columns
WHERE table_schema = 'baiyue_firstleg'
AND table_name = 'fl_loading_pick_item'
AND column_name IN ('pick_task_id', 'loading_plan_item_id', 'inbound_id',
'inbound_detail_id', 'planned_package_count',
'picked_package_count', 'item_status', 'version')) <> 8 THEN
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = '智能装柜迁移失败:PDA拣货明细字段缺失';
END IF;
IF (SELECT COUNT(*) FROM information_schema.statistics
WHERE table_schema = 'baiyue_firstleg' AND non_unique = 0
AND index_name IN ('uk_loading_pick_task_plan',
'uk_loading_pick_item_plan_item',
'uk_loading_pick_history_operation')) <> 3 THEN
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = '智能装柜迁移失败:PDA唯一索引缺失';
END IF;
IF (SELECT COUNT(*) FROM information_schema.triggers
WHERE trigger_schema = 'baiyue_firstleg'
AND trigger_name IN ('trg_container_booking_before_update',
'trg_loading_plan_before_update', 'trg_loading_plan_after_update',
'trg_loading_item_before_insert', 'trg_loading_item_before_update',
'trg_loading_item_before_delete', 'trg_container_document_before_insert',
'trg_container_document_before_update', 'trg_container_document_before_delete',
'trg_loading_history_before_update', 'trg_loading_history_before_delete',
'trg_loading_pick_task_before_update',
'trg_loading_pick_item_before_update',
'trg_loading_pick_item_before_delete',
'trg_loading_pick_history_before_update',
'trg_loading_pick_history_before_delete')) <> 16 THEN
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = '智能装柜迁移失败:不可逆状态或冻结触发器缺失';
END IF;
IF (SELECT COUNT(DISTINCT permission_code) FROM baiyue_iam.iam_permission
WHERE tenant_id = 0 AND app_code = 'PLATFORM' AND status = 'ACTIVE' AND deleted = 0
AND permission_code IN (
'platform:firstleg:container:list', 'platform:firstleg:container:view',
'platform:firstleg:container:create', 'platform:firstleg:container:edit',
'platform:firstleg:smart-loading:list', 'platform:firstleg:smart-loading:create',
'platform:firstleg:smart-loading:assign', 'platform:firstleg:smart-loading:delete',
'platform:firstleg:smart-loading:push', 'platform:firstleg:preload:list',
'platform:firstleg:preload:view', 'platform:firstleg:preload:edit',
'platform:firstleg:preload:complete', 'platform:firstleg:preload:confirm',
'platform:firstleg:loading-list:list', 'platform:firstleg:loading-list:view')) <> 16 THEN
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = '智能装柜迁移失败:平台权限资源未完整创建';
END IF;
IF (SELECT COUNT(DISTINCT CONCAT(role.role_code, ':', permission.permission_code))
FROM baiyue_iam.iam_role role
JOIN baiyue_iam.iam_role_permission grant_row ON grant_row.role_id = role.id
JOIN baiyue_iam.iam_permission permission ON permission.id = grant_row.permission_id
WHERE role.tenant_id = 0 AND role.role_code IN ('PLATFORM_ADMIN', 'ORDER_OPERATOR')
AND permission.tenant_id = 0
AND permission.permission_code IN (
'platform:firstleg:container:list', 'platform:firstleg:container:view',
'platform:firstleg:container:create',
'platform:firstleg:container:edit', 'platform:firstleg:smart-loading:list',
'platform:firstleg:smart-loading:create', 'platform:firstleg:smart-loading:assign',
'platform:firstleg:smart-loading:delete', 'platform:firstleg:smart-loading:push',
'platform:firstleg:preload:list', 'platform:firstleg:preload:view',
'platform:firstleg:preload:edit', 'platform:firstleg:preload:complete',
'platform:firstleg:preload:confirm', 'platform:firstleg:loading-list:list',
'platform:firstleg:loading-list:view')) <> 32 THEN
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = '智能装柜迁移失败:平台角色授权未完整写入';
END IF;
END$$
DELIMITER ;
CALL assert_phase3_smart_loading_schema();
DROP PROCEDURE IF EXISTS assert_phase3_smart_loading_schema;
DELIMITER $$
CREATE PROCEDURE assert_phase3_smart_loading_schema()
BEGIN
IF (SELECT COUNT(*) FROM information_schema.tables
WHERE table_schema = 'baiyue_firstleg'
AND table_name IN ('fl_container_booking', 'fl_loading_plan', 'fl_loading_plan_item',
'fl_container_document', 'fl_loading_plan_history',
'fl_loading_pick_task', 'fl_loading_pick_item',
'fl_loading_pick_history')) <> 8 THEN
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = '智能装柜迁移失败:核心表未完整创建';
END IF;
IF EXISTS (SELECT 1 FROM fl_loading_plan
WHERE plan_status NOT IN ('EDITING', 'LOADING', 'COMPLETED')) THEN
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = '智能装柜迁移失败:存在旧装柜状态';
END IF;
IF (SELECT COUNT(*) FROM information_schema.check_constraints
WHERE constraint_schema = 'baiyue_firstleg'
AND constraint_name = 'chk_loading_plan_status'
AND check_clause LIKE '%''EDITING''%'
AND check_clause LIKE '%''LOADING''%'
AND check_clause LIKE '%''COMPLETED''%') <> 1 THEN
AND UPPER(check_clause) LIKE '%EDITING%'
AND UPPER(check_clause) LIKE '%LOADING%'
AND UPPER(check_clause) LIKE '%COMPLETED%') <> 1 THEN
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = '智能装柜迁移失败:装柜状态约束不是最终三状态';
END IF;
IF (SELECT COUNT(*) FROM information_schema.columns
@@ -6118,28 +6099,106 @@ CREATE TABLE IF NOT EXISTS fl_inbound_loading_pick_task (
USE baiyue_iam;
DROP PROCEDURE IF EXISTS unified_relocate_inbound_loading_permissions;
DELIMITER $$
CREATE PROCEDURE unified_relocate_inbound_loading_permissions()
BEGIN
IF EXISTS (
SELECT 1 FROM iam_permission
WHERE id BETWEEN 5102121 AND 5102129
AND permission_code <> CASE id
WHEN 5102121 THEN 'firstleg:inbound:split'
WHEN 5102122 THEN 'firstleg:inbound:preload'
WHEN 5102123 THEN 'firstleg:inbound:preload-view'
WHEN 5102124 THEN 'platform:firstleg:inbound:loading:edit'
WHEN 5102125 THEN 'platform:firstleg:inbound:loading:view'
WHEN 5102126 THEN 'platform:firstleg:inbound:loading:complete'
WHEN 5102127 THEN 'platform:firstleg:inbound:delivery:complete'
WHEN 5102128 THEN 'platform:firstleg:inbound:picking:edit'
WHEN 5102129 THEN 'platform:firstleg:inbound:picking:view'
END
) THEN
SIGNAL SQLSTATE '45000'
SET MESSAGE_TEXT = '三期权限迁移失败:5102121-5102129 已被其他权限占用';
END IF;
DROP TEMPORARY TABLE IF EXISTS tmp_phase3_inbound_role_grant;
CREATE TEMPORARY TABLE tmp_phase3_inbound_role_grant (
role_id BIGINT UNSIGNED NOT NULL,
tenant_id BIGINT UNSIGNED NOT NULL,
permission_code VARCHAR(128) NOT NULL,
PRIMARY KEY (role_id, tenant_id, permission_code)
) ENGINE=MEMORY;
INSERT IGNORE INTO tmp_phase3_inbound_role_grant (role_id, tenant_id, permission_code)
SELECT role_permission.role_id, role_permission.tenant_id, permission.permission_code
FROM iam_role_permission role_permission
JOIN iam_permission permission ON permission.id = role_permission.permission_id
WHERE permission.permission_code IN (
'firstleg:inbound:split', 'firstleg:inbound:preload', 'firstleg:inbound:preload-view',
'platform:firstleg:inbound:loading:edit', 'platform:firstleg:inbound:loading:view',
'platform:firstleg:inbound:loading:complete', 'platform:firstleg:inbound:delivery:complete',
'platform:firstleg:inbound:picking:edit', 'platform:firstleg:inbound:picking:view'
);
DELETE role_permission FROM iam_role_permission role_permission
JOIN iam_permission permission ON permission.id = role_permission.permission_id
WHERE permission.permission_code IN (
'firstleg:inbound:split', 'firstleg:inbound:preload', 'firstleg:inbound:preload-view',
'platform:firstleg:inbound:loading:edit', 'platform:firstleg:inbound:loading:view',
'platform:firstleg:inbound:loading:complete', 'platform:firstleg:inbound:delivery:complete',
'platform:firstleg:inbound:picking:edit', 'platform:firstleg:inbound:picking:view'
);
DELETE FROM iam_permission WHERE permission_code IN (
'firstleg:inbound:split', 'firstleg:inbound:preload', 'firstleg:inbound:preload-view',
'platform:firstleg:inbound:loading:edit', 'platform:firstleg:inbound:loading:view',
'platform:firstleg:inbound:loading:complete', 'platform:firstleg:inbound:delivery:complete',
'platform:firstleg:inbound:picking:edit', 'platform:firstleg:inbound:picking:view'
);
END$$
DELIMITER ;
CALL unified_relocate_inbound_loading_permissions();
DROP PROCEDURE unified_relocate_inbound_loading_permissions;
-- 如果旧入库权限占用了 5102091-5102099,上面的语义迁移已释放这些 ID;
-- 此处重新写入智能装柜权限,修复此前 ON DUPLICATE 只改元数据、不改 code 的污染。
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
(5102091, 0, 'PLATFORM', 'BUTTON', 5102090, 'platform:firstleg:container:view', '查看货柜', NULL, 'GET', 10, 'ACTIVE', 1, 0),
(5102092, 0, 'PLATFORM', 'BUTTON', 5102090, 'platform:firstleg:container:create', '建立货柜', NULL, 'POST', 20, 'ACTIVE', 1, 0),
(5102093, 0, 'PLATFORM', 'BUTTON', 5102090, 'platform:firstleg:container:edit', '编辑货柜', NULL, 'PUT', 30, 'ACTIVE', 1, 0),
(5102094, 0, 'PLATFORM', 'MENU', 5102000, 'platform:firstleg:smart-loading:list', '智能装柜', '/first-leg/smart-loading', 'GET', 50, 'ACTIVE', 1, 0),
(5102096, 0, 'PLATFORM', 'BUTTON', 5102094, 'platform:firstleg:smart-loading:create', '创建智能装柜计划', NULL, 'POST', 20, 'ACTIVE', 1, 0),
(5102097, 0, 'PLATFORM', 'BUTTON', 5102094, 'platform:firstleg:smart-loading:assign', '分配装柜明细', NULL, 'POST', 30, 'ACTIVE', 1, 0),
(5102098, 0, 'PLATFORM', 'BUTTON', 5102094, 'platform:firstleg:smart-loading:delete', '删除装柜明细', NULL, 'DELETE', 40, 'ACTIVE', 1, 0),
(5102099, 0, 'PLATFORM', 'BUTTON', 5102094, 'platform:firstleg:smart-loading:push', '推送预装', NULL, 'POST', 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;
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
(5102091, 0, 'PLATFORM', 'BUTTON', 5102030,
(5102121, 0, 'PLATFORM', 'BUTTON', 5102030,
'firstleg:inbound:split', '智能分柜', NULL, NULL, 140, 'ACTIVE', 1, 0),
(5102092, 0, 'PLATFORM', 'BUTTON', 5102030,
(5102122, 0, 'PLATFORM', 'BUTTON', 5102030,
'firstleg:inbound:preload', '编辑并确认预装清单', NULL, NULL, 150, 'ACTIVE', 1, 0),
(5102093, 0, 'PLATFORM', 'BUTTON', 5102030,
(5102123, 0, 'PLATFORM', 'BUTTON', 5102030,
'firstleg:inbound:preload-view', '查看预装清单', NULL, NULL, 160, 'ACTIVE', 1, 0),
(5102094, 0, 'PLATFORM', 'BUTTON', 5102030,
(5102124, 0, 'PLATFORM', 'BUTTON', 5102030,
'platform:firstleg:inbound:loading:edit', '维护装柜证据', NULL, NULL, 170, 'ACTIVE', 1, 0),
(5102095, 0, 'PLATFORM', 'BUTTON', 5102030,
(5102125, 0, 'PLATFORM', 'BUTTON', 5102030,
'platform:firstleg:inbound:loading:view', '查看装柜证据', NULL, NULL, 180, 'ACTIVE', 1, 0),
(5102096, 0, 'PLATFORM', 'BUTTON', 5102030,
(5102126, 0, 'PLATFORM', 'BUTTON', 5102030,
'platform:firstleg:inbound:loading:complete', '完成装柜', NULL, NULL, 190, 'ACTIVE', 1, 0),
(5102097, 0, 'PLATFORM', 'BUTTON', 5102030,
(5102127, 0, 'PLATFORM', 'BUTTON', 5102030,
'platform:firstleg:inbound:delivery:complete', '完成派送', NULL, NULL, 200, 'ACTIVE', 1, 0),
(5102098, 0, 'PLATFORM', 'BUTTON', 5102030,
(5102128, 0, 'PLATFORM', 'BUTTON', 5102030,
'platform:firstleg:inbound:picking:edit', '执行拣货', NULL, NULL, 210, 'ACTIVE', 1, 0),
(5102099, 0, 'PLATFORM', 'BUTTON', 5102030,
(5102129, 0, 'PLATFORM', 'BUTTON', 5102030,
'platform:firstleg:inbound:picking:view', '查看拣货任务', NULL, NULL, 220, 'ACTIVE', 1, 0)
ON DUPLICATE KEY UPDATE
permission_type = VALUES(permission_type), parent_id = VALUES(parent_id),
@@ -6164,6 +6223,25 @@ WHERE tenant_id = 0 AND app_code = 'PLATFORM'
)
ON DUPLICATE KEY UPDATE tenant_id = VALUES(tenant_id);
INSERT IGNORE INTO iam_role_permission (role_id, permission_id, tenant_id)
SELECT grant_row.role_id, permission.id, grant_row.tenant_id
FROM tmp_phase3_inbound_role_grant grant_row
JOIN iam_permission permission ON permission.permission_code = grant_row.permission_code
AND permission.tenant_id = 0 AND permission.app_code = 'PLATFORM';
DROP TEMPORARY TABLE IF EXISTS tmp_phase3_inbound_role_grant;
INSERT IGNORE INTO iam_role_permission (role_id, permission_id, tenant_id)
SELECT role.id, permission.id, role.tenant_id
FROM iam_role role
JOIN iam_permission permission ON permission.tenant_id = 0
AND permission.permission_code IN (
'platform:firstleg:container:view', 'platform:firstleg:container:create',
'platform:firstleg:container:edit', 'platform:firstleg:smart-loading:list',
'platform:firstleg:smart-loading:create', 'platform:firstleg:smart-loading:assign',
'platform:firstleg:smart-loading:delete', 'platform:firstleg:smart-loading:push'
)
WHERE role.tenant_id = 0 AND role.role_code IN ('PLATFORM_ADMIN', 'ORDER_OPERATOR');
-- 兼容已经执行过旧单行配置模型的开发/测试库。仅精确识别旧结构时丢弃旧值并重建;
-- 已是四箱规结构时不做 DDL,避免破坏 Admin 已编辑的数据。
DROP PROCEDURE IF EXISTS unified_upgrade_legacy_customer_dimension_config;
@@ -6254,7 +6332,8 @@ SELECT UUID_SHORT(), tenant.tenant_id, defaults.box_type,
SELECT 'LARGE', 50.000, 40.000, 40.000, '标准大箱'
UNION ALL
SELECT 'EXTRA_LARGE', 60.000, 50.000, 50.000, '特大箱'
) defaults
) defaults
WHERE TRUE
ON DUPLICATE KEY UPDATE id = id;
-- ============================================================================
@@ -6808,9 +6887,9 @@ BEGIN
END IF;
IF (SELECT COUNT(DISTINCT index_name) FROM information_schema.statistics
WHERE table_schema = DATABASE()
AND index_name IN ('uk_inbound_master_order', 'uk_inbound_parent_sequence',
AND index_name IN ('uk_inbound_master_order', 'uk_inbound_one_child',
'uk_inbound_split_operation', 'uk_inbound_split_idempotency',
'uk_inbound_split_child', 'uk_inbound_split_history_operation')) <> 6 THEN
'uk_inbound_split_history_operation')) <> 5 THEN
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = '主子入仓单唯一约束未完整创建';
END IF;
IF (SELECT COUNT(*) FROM information_schema.table_constraints
@@ -6865,6 +6944,23 @@ BEGIN
SIGNAL SQLSTATE '45000'
SET MESSAGE_TEXT = '统一迁移失败:稳定箱号或单箱测量唯一约束未完整创建';
END IF;
IF (SELECT COUNT(*) FROM information_schema.columns
WHERE table_schema = 'baiyue_firstleg'
AND table_name = 'fl_mojia_measurement_receipt'
AND column_name IN ('id', 'tenant_id', 'subject_id', 'box_code', 'length_cm', 'width_cm',
'height_cm', 'weight_kg', 'machine_no', 'measured_at', 'image_file_id',
'status', 'match_failure_code', 'match_failure_reason', 'request_id',
'trace_id', 'created_at', 'updated_at')) <> 18 THEN
SIGNAL SQLSTATE '45000'
SET MESSAGE_TEXT = '统一迁移失败:墨家未匹配测量收件箱字段未完整创建';
END IF;
IF (SELECT character_maximum_length FROM information_schema.columns
WHERE table_schema = 'baiyue_firstleg'
AND table_name = 'fl_inbound_measurement_item'
AND column_name = 'calculation_rule_version') <> 64 THEN
SIGNAL SQLSTATE '45000'
SET MESSAGE_TEXT = '统一迁移失败:测量计算规则版本字段长度不是64';
END IF;
IF (SELECT COUNT(*) FROM information_schema.tables
WHERE table_schema = 'baiyue_firstleg'
AND table_name = 'fl_customer_dimension_config') <> 1 THEN
@@ -6969,30 +7065,55 @@ BEGIN
SIGNAL SQLSTATE '45000'
SET MESSAGE_TEXT = '统一迁移失败:订单运营角色的客户尺寸计算配置权限不是只读';
END IF;
IF (SELECT COUNT(*) FROM information_schema.columns
WHERE table_schema = 'baiyue_firstleg' AND table_name = 'fl_loading_pick_task'
AND column_name IN ('loading_plan_id', 'container_no', 'task_status')) <> 3
OR (SELECT COUNT(*) FROM information_schema.columns
WHERE table_schema = 'baiyue_firstleg' AND table_name = 'fl_loading_pick_task'
AND column_name IN ('tenant_id', 'inbound_id', 'status', 'expected_count', 'picked_count')) <> 0 THEN
SIGNAL SQLSTATE '45000'
SET MESSAGE_TEXT = '统一迁移失败:智能装柜拣货任务表型不正确';
END IF;
IF (SELECT COUNT(*) FROM information_schema.columns
WHERE table_schema = 'baiyue_firstleg' AND table_name = 'fl_inbound_loading_pick_task'
AND column_name IN ('tenant_id', 'inbound_id', 'status', 'expected_count', 'picked_count')) <> 5
OR (SELECT COUNT(*) FROM information_schema.columns
WHERE table_schema = 'baiyue_firstleg' AND table_name = 'fl_inbound_loading_pick_task'
AND column_name IN ('loading_plan_id', 'container_no', 'task_status')) <> 0 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'
AND ((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 (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)
OR (id = 5103061 AND permission_code = 'platform:location:create' AND parent_id = 5103060)
OR (id = 5103062 AND permission_code = 'platform:location:edit' AND parent_id = 5103060)
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 = '统一迁移失败:下载中心或库位权限语义未修复';
END IF;
IF (SELECT COUNT(*) FROM baiyue_iam.iam_permission
WHERE tenant_id = 0 AND app_code = 'PLATFORM'
AND id BETWEEN 5102121 AND 5102129
AND permission_code IN ('firstleg:inbound:split', 'firstleg:inbound:preload',
'firstleg:inbound:preload-view', 'platform:firstleg:inbound:loading:edit',
'platform:firstleg:inbound:loading:view', 'platform:firstleg:inbound:loading:complete',
'platform:firstleg:inbound:delivery:complete', 'platform:firstleg:inbound:picking:edit',
'platform:firstleg:inbound:picking:view')) <> 9 THEN
SIGNAL SQLSTATE '45000'
SET MESSAGE_TEXT = '统一迁移失败:三期入库装柜权限 ID 未完成迁移';
END IF;
END$$
DELIMITER ;
CALL phase3_assert_inbound_parent_child_schema();
DROP PROCEDURE IF EXISTS phase3_assert_inbound_parent_child_schema;
-- ============================================================================
-- 来源:firstleg/src/main/resources/db/phase3-inbounded-status-unification.sql
-- ============================================================================
-- 将已废弃的 WAIT_SPLIT 统一为 INBOUNDED。
-- 执行前请确认所有服务已升级至本次状态契约;脚本可重复执行。
USE baiyue_firstleg;
UPDATE fl_inbound_order
SET process_status = 'INBOUNDED',
updated_at = CURRENT_TIMESTAMP(3),
version = version + 1
WHERE process_status = 'WAIT_SPLIT';
UPDATE fl_inbound_status_history
SET from_status = 'INBOUNDED'
WHERE from_status = 'WAIT_SPLIT';
UPDATE fl_inbound_status_history
SET to_status = 'INBOUNDED'
WHERE to_status = 'WAIT_SPLIT';
-- WAIT_SPLIT 是二期当前有效终点;统一迁移不得改写主表或历史状态。
SELECT 'PASS' AS migration_status,
'统一增量全部执行完成;箱号映射、单箱测量、三期出仓、费用、公共资源及可靠审计结构校验通过' AS message;