From 8ba04fc87d10327b70cb94160debfaf3631d27da Mon Sep 17 00:00:00 2001 From: ouyangxq <775153912@qq.com> Date: Thu, 13 Aug 2026 18:35:19 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- deploy/sql/头程数据库统一增量-MySQL8.sql | 67 +++++++++++++++++++ .../InboundCartonLabelSqlContractTest.java | 15 ++++- 2 files changed, 81 insertions(+), 1 deletion(-) diff --git a/deploy/sql/头程数据库统一增量-MySQL8.sql b/deploy/sql/头程数据库统一增量-MySQL8.sql index 109b7c8d9..acf8dced0 100644 --- a/deploy/sql/头程数据库统一增量-MySQL8.sql +++ b/deploy/sql/头程数据库统一增量-MySQL8.sql @@ -2674,6 +2674,58 @@ CREATE TABLE IF NOT EXISTS fl_inbound_carton_label ( CONSTRAINT fk_carton_label_inbound FOREIGN KEY (inbound_id) REFERENCES fl_inbound_order (id) ) ENGINE=InnoDB COMMENT='首次打印前冻结的实际箱号与订单货物明细映射'; +-- 存量环境可能已在箱唛版本化前建表;CREATE TABLE IF NOT EXISTS 不会补列。 +DROP PROCEDURE IF EXISTS unified_carton_label_add_column; +DELIMITER $$ +CREATE PROCEDURE unified_carton_label_add_column(IN p_column VARCHAR(64), IN p_definition TEXT) +BEGIN + IF NOT EXISTS (SELECT 1 FROM information_schema.columns + WHERE table_schema=DATABASE() + AND table_name='fl_inbound_carton_label' + AND column_name=p_column) THEN + SET @ddl = CONCAT('ALTER TABLE fl_inbound_carton_label ADD COLUMN `', p_column, '` ', p_definition); + PREPARE stmt FROM @ddl; EXECUTE stmt; DEALLOCATE PREPARE stmt; + END IF; +END$$ +DELIMITER ; +CALL unified_carton_label_add_column('label_version', 'INT UNSIGNED NOT NULL DEFAULT 1 COMMENT ''箱唛批次版本,从1递增'' AFTER carton_index'); +CALL unified_carton_label_add_column('batch_status', 'VARCHAR(16) NOT NULL DEFAULT ''ACTIVE'' COMMENT ''批次状态:ACTIVE有效、VOID已作废'' AFTER label_version'); +CALL unified_carton_label_add_column('cargo_fingerprint', 'CHAR(64) NULL COMMENT ''影响标签字段的SHA-256指纹'' AFTER batch_status'); +CALL unified_carton_label_add_column('voided_at', 'DATETIME(3) NULL COMMENT ''批次作废时间'' AFTER cargo_fingerprint'); +DROP PROCEDURE IF EXISTS unified_carton_label_add_column; + +UPDATE fl_inbound_carton_label + SET label_version=1, + batch_status='ACTIVE' + WHERE label_version IS NULL OR batch_status IS NULL; + +UPDATE fl_inbound_carton_label + SET box_code=CONCAT(inbound_code, '#V', label_version, '#', total_carton_count, '-', carton_index) + WHERE box_code NOT LIKE CONCAT(inbound_code, '#V%#%'); + +SET @ddl = IF( + EXISTS(SELECT 1 FROM information_schema.statistics + WHERE table_schema=DATABASE() AND table_name='fl_inbound_carton_label' + AND index_name='uk_carton_label_index'), + 'ALTER TABLE fl_inbound_carton_label DROP INDEX uk_carton_label_index', 'SELECT 1'); +PREPARE stmt FROM @ddl; EXECUTE stmt; DEALLOCATE PREPARE stmt; + +SET @ddl = IF( + NOT EXISTS(SELECT 1 FROM information_schema.statistics + WHERE table_schema=DATABASE() AND table_name='fl_inbound_carton_label' + AND index_name='uk_carton_label_index'), + 'ALTER TABLE fl_inbound_carton_label ADD UNIQUE KEY uk_carton_label_index (tenant_id,inbound_id,label_version,carton_index)', + 'SELECT 1'); +PREPARE stmt FROM @ddl; EXECUTE stmt; DEALLOCATE PREPARE stmt; + +SET @ddl = IF( + NOT EXISTS(SELECT 1 FROM information_schema.statistics + WHERE table_schema=DATABASE() AND table_name='fl_inbound_carton_label' + AND index_name='idx_carton_label_active'), + 'ALTER TABLE fl_inbound_carton_label ADD KEY idx_carton_label_active (tenant_id,inbound_id,batch_status,label_version)', + 'SELECT 1'); +PREPARE stmt FROM @ddl; EXECUTE stmt; DEALLOCATE PREPARE stmt; + CREATE TABLE IF NOT EXISTS fl_inbound_weight_result ( id BIGINT UNSIGNED NOT NULL COMMENT 'OCR重量结果ID', tenant_id BIGINT UNSIGNED NOT NULL COMMENT '客户ID和数据隔离键', @@ -13703,6 +13755,21 @@ 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_inbound_carton_label' + AND column_name IN ('label_version', 'batch_status', 'cargo_fingerprint', 'voided_at')) <> 4 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_inbound_carton_label' + AND index_name = 'idx_carton_label_active' + AND non_unique = 1) <> 4 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_measurement_item' diff --git a/firstleg/src/test/java/com/baiyue/firstleg/repository/InboundCartonLabelSqlContractTest.java b/firstleg/src/test/java/com/baiyue/firstleg/repository/InboundCartonLabelSqlContractTest.java index db3587568..7b5d1ec8e 100644 --- a/firstleg/src/test/java/com/baiyue/firstleg/repository/InboundCartonLabelSqlContractTest.java +++ b/firstleg/src/test/java/com/baiyue/firstleg/repository/InboundCartonLabelSqlContractTest.java @@ -14,6 +14,7 @@ class InboundCartonLabelSqlContractTest { void baseSchemaAndExistingDatabaseMigrationKeepStableCartonKeys() throws Exception { String schema = resource("db/phase2-inbound-schema.sql"); String migration = resource("db/phase2-inbound-carton-label.sql"); + String versioningMigration = resource("db/phase2-carton-label-versioning-migration.sql"); String unified = Files.readString(Path.of("..", "deploy", "sql", "头程数据库统一增量-MySQL8.sql")); assertThat(schema).contains("CREATE TABLE IF NOT EXISTS fl_inbound_carton_label") @@ -23,10 +24,22 @@ class InboundCartonLabelSqlContractTest { assertThat(migration).contains("CREATE TABLE IF NOT EXISTS fl_inbound_carton_label") .contains("固定二维码内容:入仓码#总箱数-箱下标") .contains("idx_carton_label_detail (tenant_id, inbound_id, inbound_detail_id)"); + assertThat(versioningMigration).contains("phase2_carton_label_add_column('label_version'") + .contains("phase2_carton_label_add_column('batch_status'") + .contains("idx_carton_label_active (tenant_id, inbound_id, batch_status, label_version)"); assertThat(unified).contains("CREATE TABLE IF NOT EXISTS fl_inbound_carton_label") + .contains("unified_carton_label_add_column('label_version'") + .contains("unified_carton_label_add_column('batch_status'") + .contains("unified_carton_label_add_column('cargo_fingerprint'") + .contains("unified_carton_label_add_column('voided_at'") + .contains("ALTER TABLE fl_inbound_carton_label DROP INDEX uk_carton_label_index") + .contains("ADD UNIQUE KEY uk_carton_label_index (tenant_id,inbound_id,label_version,carton_index)") + .contains("ADD KEY idx_carton_label_active (tenant_id,inbound_id,batch_status,label_version)") .contains("uk_carton_label_box_code") .contains("uk_carton_label_index") - .contains("稳定箱号映射表未创建"); + .contains("稳定箱号映射表未创建") + .contains("箱唛版本化字段未完整创建") + .contains("箱唛有效批次索引未完整创建"); } private String resource(String path) throws Exception {