-- 仓储转运审核、PDA测量打托、换标、目的地绑定、智能排车与派送字段。 -- 目标数据库:baiyue_lastleg -- 可重复执行:字段和索引独立检查,补充缺失结构并修正必要的可空性;不更新业务数据。 USE `baiyue_lastleg`; DROP PROCEDURE IF EXISTS `ensure_transfer_column`; DROP PROCEDURE IF EXISTS `ensure_transfer_nullable_column`; DROP PROCEDURE IF EXISTS `ensure_transfer_index`; DROP PROCEDURE IF EXISTS `ensure_transfer_pallet_unique_index`; DELIMITER $$ CREATE PROCEDURE `ensure_transfer_column`( IN p_table_name VARCHAR(64), IN p_column_name VARCHAR(64), IN p_column_definition TEXT ) BEGIN IF NOT EXISTS ( SELECT 1 FROM information_schema.columns WHERE table_schema = DATABASE() AND table_name = p_table_name AND column_name = p_column_name ) THEN SET @ddl = CONCAT( 'ALTER TABLE `', REPLACE(p_table_name, '`', '``'), '` ADD COLUMN `', REPLACE(p_column_name, '`', '``'), '` ', p_column_definition ); PREPARE stmt FROM @ddl; EXECUTE stmt; DEALLOCATE PREPARE stmt; END IF; END$$ CREATE PROCEDURE `ensure_transfer_nullable_column`( IN p_table_name VARCHAR(64), IN p_column_name VARCHAR(64), IN p_column_definition TEXT ) BEGIN IF EXISTS ( SELECT 1 FROM information_schema.columns WHERE table_schema = DATABASE() AND table_name = p_table_name AND column_name = p_column_name AND is_nullable = 'NO' ) THEN SET @ddl = CONCAT( 'ALTER TABLE `', REPLACE(p_table_name, '`', '``'), '` MODIFY COLUMN `', REPLACE(p_column_name, '`', '``'), '` ', p_column_definition ); PREPARE stmt FROM @ddl; EXECUTE stmt; DEALLOCATE PREPARE stmt; END IF; END$$ CREATE PROCEDURE `ensure_transfer_index`( IN p_table_name VARCHAR(64), IN p_index_name VARCHAR(64), IN p_index_definition TEXT ) BEGIN IF NOT EXISTS ( SELECT 1 FROM information_schema.statistics WHERE table_schema = DATABASE() AND table_name = p_table_name AND index_name = p_index_name ) THEN SET @ddl = CONCAT( 'ALTER TABLE `', REPLACE(p_table_name, '`', '``'), '` ADD ', p_index_definition ); PREPARE stmt FROM @ddl; EXECUTE stmt; DEALLOCATE PREPARE stmt; END IF; END$$ CREATE PROCEDURE `ensure_transfer_pallet_unique_index`() BEGIN DECLARE v_duplicate_groups BIGINT DEFAULT 0; IF NOT EXISTS ( SELECT 1 FROM information_schema.statistics WHERE table_schema = DATABASE() AND table_name = 'll_inbound_plan_pallet' AND index_name = 'uk_ll_inbound_pallet_no' ) THEN SELECT COUNT(*) INTO v_duplicate_groups FROM ( SELECT 1 FROM `ll_inbound_plan_pallet` GROUP BY `customer_id`, `pallet_no` HAVING COUNT(*) > 1 ) duplicate_groups; IF v_duplicate_groups = 0 THEN ALTER TABLE `ll_inbound_plan_pallet` ADD UNIQUE KEY `uk_ll_inbound_pallet_no` (`customer_id`,`pallet_no`); END IF; END IF; END$$ DELIMITER ; -- 相关业务表统一补齐 SaaS 租户字段。默认值只用于兼容历史数据和单租户海外环境。 CALL ensure_transfer_column('ll_delivery_order', 'tenant_id', 'VARCHAR(128) NOT NULL DEFAULT ''BAIYUE'' COMMENT ''SaaS租户标识,当前海外租户固定为BAIYUE'''); CALL ensure_transfer_column('ll_dispatch_item', 'tenant_id', 'VARCHAR(128) NOT NULL DEFAULT ''BAIYUE'' COMMENT ''SaaS租户标识,当前海外租户固定为BAIYUE'''); CALL ensure_transfer_column('ll_inbound_plan_line', 'tenant_id', 'VARCHAR(128) NOT NULL DEFAULT ''BAIYUE'' COMMENT ''SaaS租户标识,当前海外租户固定为BAIYUE'''); CALL ensure_transfer_column('ll_inbound_plan_pallet', 'tenant_id', 'VARCHAR(128) NOT NULL DEFAULT ''BAIYUE'' COMMENT ''SaaS租户标识,当前海外租户固定为BAIYUE'''); CALL ensure_transfer_column('ll_order', 'tenant_id', 'VARCHAR(128) NOT NULL DEFAULT ''BAIYUE'' COMMENT ''SaaS租户标识,当前海外租户固定为BAIYUE'''); CALL ensure_transfer_column('ll_relabel_application', 'tenant_id', 'VARCHAR(128) NOT NULL DEFAULT ''BAIYUE'' COMMENT ''SaaS租户标识,当前海外租户固定为BAIYUE'''); CALL ensure_transfer_column('ll_relabel_item', 'tenant_id', 'VARCHAR(128) NOT NULL DEFAULT ''BAIYUE'' COMMENT ''SaaS租户标识,当前海外租户固定为BAIYUE'''); CALL ensure_transfer_column('ll_relabel_status_history', 'tenant_id', 'VARCHAR(128) NOT NULL DEFAULT ''BAIYUE'' COMMENT ''SaaS租户标识,当前海外租户固定为BAIYUE'''); CALL ensure_transfer_column('ll_warehouse_transfer_inventory_allocation', 'tenant_id', 'VARCHAR(128) NOT NULL DEFAULT ''BAIYUE'' COMMENT ''SaaS租户标识,当前海外租户固定为BAIYUE'''); CALL ensure_transfer_column('ll_warehouse_transfer_item', 'tenant_id', 'VARCHAR(128) NOT NULL DEFAULT ''BAIYUE'' COMMENT ''SaaS租户标识,当前海外租户固定为BAIYUE'''); CALL ensure_transfer_column('ll_warehouse_transfer_order', 'tenant_id', 'VARCHAR(128) NOT NULL DEFAULT ''BAIYUE'' COMMENT ''SaaS租户标识,当前海外租户固定为BAIYUE'''); CALL ensure_transfer_column('ll_warehouse_transfer_receipt', 'tenant_id', 'VARCHAR(128) NOT NULL DEFAULT ''BAIYUE'' COMMENT ''SaaS租户标识,当前海外租户固定为BAIYUE'''); CALL ensure_transfer_column('ll_warehouse_transfer_source_order', 'tenant_id', 'VARCHAR(128) NOT NULL DEFAULT ''BAIYUE'' COMMENT ''SaaS租户标识,当前海外租户固定为BAIYUE'''); -- 退货换标允许只更换箱唛,不强制生成新 SKU。 CALL ensure_transfer_nullable_column('ll_relabel_item', 'new_sku_code', 'VARCHAR(128) NULL COMMENT ''换标后SKU编码'''); -- 主单审核、提货、发货、换标和客户确认事实。 CALL ensure_transfer_column('ll_warehouse_transfer_order', 'pickup_contact_name', 'VARCHAR(128) NULL COMMENT ''提货联系人'''); CALL ensure_transfer_column('ll_warehouse_transfer_order', 'pickup_contact_phone', 'VARCHAR(64) NULL COMMENT ''提货联系电话'''); CALL ensure_transfer_column('ll_warehouse_transfer_order', 'estimated_ship_at', 'DATETIME(3) NULL COMMENT ''预计发货时间'''); CALL ensure_transfer_column('ll_warehouse_transfer_order', 'review_decision', 'VARCHAR(32) NULL COMMENT ''审核决定'''); CALL ensure_transfer_column('ll_warehouse_transfer_order', 'review_remark', 'VARCHAR(1000) NULL COMMENT ''审核备注或驳回原因'''); CALL ensure_transfer_column('ll_warehouse_transfer_order', 'reviewed_by', 'VARCHAR(128) NULL COMMENT ''审核人ID'''); CALL ensure_transfer_column('ll_warehouse_transfer_order', 'reviewed_at', 'DATETIME(3) NULL COMMENT ''审核时间'''); CALL ensure_transfer_column('ll_warehouse_transfer_order', 'label_deadline', 'DATETIME(3) NULL COMMENT ''换标截止时间'''); CALL ensure_transfer_column('ll_warehouse_transfer_order', 'relabel_contact_name', 'VARCHAR(128) NULL COMMENT ''换标联系人'''); CALL ensure_transfer_column('ll_warehouse_transfer_order', 'relabel_contact_phone', 'VARCHAR(64) NULL COMMENT ''换标联系电话'''); CALL ensure_transfer_column('ll_warehouse_transfer_order', 'relabel_charge_amount', 'DECIMAL(20,2) NULL COMMENT ''换标费用CNY'''); CALL ensure_transfer_column('ll_warehouse_transfer_order', 'relabel_delivery_method', 'VARCHAR(32) NULL COMMENT ''换标后派送方式'''); CALL ensure_transfer_column('ll_warehouse_transfer_order', 'relabel_completed_at', 'DATETIME(3) NULL COMMENT ''关联贴标完成时间'''); CALL ensure_transfer_column('ll_warehouse_transfer_order', 'palletize_idempotency_key', 'VARCHAR(255) NULL COMMENT ''PDA打托幂等键'''); CALL ensure_transfer_column('ll_warehouse_transfer_order', 'palletize_request_hash', 'CHAR(64) NULL COMMENT ''PDA打托请求哈希'''); CALL ensure_transfer_column('ll_warehouse_transfer_order', 'confirmation_idempotency_key', 'VARCHAR(255) NULL COMMENT ''客户测量确认幂等键'''); CALL ensure_transfer_column('ll_warehouse_transfer_order', 'confirmation_request_hash', 'CHAR(64) NULL COMMENT ''客户测量确认请求哈希'''); CALL ensure_transfer_column('ll_warehouse_transfer_order', 'customer_confirmed_at', 'DATETIME(3) NULL COMMENT ''客户确认测量时间'''); -- 仓储转运主单目的地。 CALL ensure_transfer_column('ll_warehouse_transfer_order', 'destination_type', 'VARCHAR(16) NULL COMMENT ''目的类型:FBA或PRIVATE'''); CALL ensure_transfer_column('ll_warehouse_transfer_order', 'destination_warehouse_id', 'VARCHAR(128) NULL COMMENT ''目的仓ID快照'''); CALL ensure_transfer_column('ll_warehouse_transfer_order', 'destination_warehouse_code', 'VARCHAR(128) NULL COMMENT ''目的仓编码快照'''); CALL ensure_transfer_column('ll_warehouse_transfer_order', 'destination_warehouse_name', 'VARCHAR(255) NULL COMMENT ''目的仓名称快照'''); CALL ensure_transfer_column('ll_warehouse_transfer_order', 'private_destination_address', 'VARCHAR(1000) NULL COMMENT ''私人仓完整地址'''); CALL ensure_transfer_column('ll_warehouse_transfer_order', 'private_destination_postal_code', 'VARCHAR(32) NULL COMMENT ''私人仓邮编'''); CALL ensure_transfer_column('ll_warehouse_transfer_order', 'private_destination_contact_name', 'VARCHAR(128) NULL COMMENT ''私人仓联系人'''); CALL ensure_transfer_column('ll_warehouse_transfer_order', 'private_destination_contact_phone', 'VARCHAR(64) NULL COMMENT ''私人仓联系电话'''); CALL ensure_transfer_column('ll_warehouse_transfer_order', 'destination_binding_idempotency_key', 'VARCHAR(255) NULL COMMENT ''目的地绑定幂等键'''); CALL ensure_transfer_column('ll_warehouse_transfer_order', 'destination_binding_request_hash', 'CHAR(64) NULL COMMENT ''目的地绑定请求哈希'''); -- 转仓尾程主单记录PDA实收箱数。 CALL ensure_transfer_column('ll_order', 'received_package_count', 'INT NULL COMMENT ''PDA实际入库箱数'''); -- PDA逐托草稿、生成、扫码绑定和整单完成事实。 CREATE TABLE IF NOT EXISTS `ll_warehouse_transfer_pallet` ( `id` BIGINT NOT NULL COMMENT '打托事实ID', `transfer_order_id` BIGINT NOT NULL COMMENT '转运单ID', `customer_id` VARCHAR(128) NOT NULL COMMENT '客户租户ID', `sequence_no` INT NOT NULL COMMENT '托序号', `warehouse_pallet_id` BIGINT NULL COMMENT '生成后的海外仓真实托盘ID', `pallet_no` VARCHAR(128) NULL COMMENT '生成后的真实托盘码', `warehouse_location_id` BIGINT NULL COMMENT '生成后的真实库位ID', `warehouse_location_code` VARCHAR(128) NULL COMMENT '真实库位码', `warehouse_resource_lock_id` BIGINT NULL COMMENT '生成后的仓储资源锁ID', `carton_count` INT NOT NULL COMMENT '本托实收箱数', `length_cm` DECIMAL(12,2) NOT NULL COMMENT '实测长cm', `width_cm` DECIMAL(12,2) NOT NULL COMMENT '实测宽cm', `height_cm` DECIMAL(12,2) NOT NULL COMMENT '实测高cm', `gross_weight_kg` DECIMAL(12,3) NOT NULL COMMENT '实测毛重kg', `volume_cbm` DECIMAL(18,6) NOT NULL COMMENT '实测体积CBM', `status` VARCHAR(32) NOT NULL COMMENT '逐托状态DRAFT/GENERATED/BOUND/COMPLETED', `draft_idempotency_key` VARCHAR(255) NULL COMMENT '草稿保存幂等键', `draft_request_hash` CHAR(64) NULL COMMENT '草稿请求摘要', `generate_idempotency_key` VARCHAR(255) NULL COMMENT '新托盘生成幂等键', `bind_idempotency_key` VARCHAR(255) NULL COMMENT '扫码绑定幂等键', `bound_at` DATETIME(3) NULL COMMENT '扫码确认绑定时间', `completed_at` DATETIME(3) NULL COMMENT '整单打托完成时间', `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`), UNIQUE KEY `uk_ll_transfer_pallet_seq` (`transfer_order_id`,`sequence_no`), UNIQUE KEY `uk_ll_transfer_pallet_physical` (`customer_id`,`warehouse_pallet_id`), KEY `idx_ll_transfer_pallet_order` (`customer_id`,`transfer_order_id`,`status`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='仓储转运PDA实测打托事实'; CREATE TABLE IF NOT EXISTS `ll_warehouse_transfer_pallet_item` ( `id` BIGINT NOT NULL COMMENT '主键ID', `transfer_order_id` BIGINT NOT NULL COMMENT '转运单ID', `transfer_pallet_id` BIGINT NOT NULL COMMENT '转运托盘事实ID', `transfer_item_id` BIGINT NOT NULL COMMENT '转运申报明细ID', `customer_id` VARCHAR(128) NOT NULL COMMENT '客户租户ID', `package_count` INT NOT NULL COMMENT '本托该SKU实收箱数', `created_at` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '创建时间', PRIMARY KEY (`id`), UNIQUE KEY `uk_ll_transfer_pallet_item` (`transfer_pallet_id`,`transfer_item_id`), KEY `idx_ll_transfer_pallet_item_order` (`customer_id`,`transfer_order_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='仓储转运每托SKU箱数回填'; CREATE TABLE IF NOT EXISTS `ll_warehouse_transfer_relabel_binding` ( `id` BIGINT NOT NULL COMMENT '主键ID', `transfer_order_id` BIGINT NOT NULL COMMENT '转运单ID', `customer_id` VARCHAR(128) NOT NULL COMMENT '客户租户ID', `operation_type` VARCHAR(32) NOT NULL COMMENT '换标类型', `customer_carton_mark` VARCHAR(255) NOT NULL COMMENT '客户原箱唛', `original_sku` VARCHAR(128) NOT NULL COMMENT '旧SKU', `new_sku` VARCHAR(128) NULL COMMENT '新SKU', `quantity` INT NOT NULL COMMENT '换标件数', `fba_carton_mark` VARCHAR(255) NULL COMMENT '新FBA箱唛', `destination_warehouse_code` VARCHAR(128) NULL COMMENT 'FBA目的仓', `remark` VARCHAR(1000) NULL COMMENT '备注', `created_at` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '创建时间', PRIMARY KEY (`id`), UNIQUE KEY `uk_ll_transfer_relabel_mark` (`transfer_order_id`,`customer_carton_mark`), KEY `idx_ll_transfer_relabel_order` (`customer_id`,`transfer_order_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='仓储转运换标预绑定明细'; CALL ensure_transfer_nullable_column('ll_warehouse_transfer_pallet', 'warehouse_pallet_id', 'BIGINT NULL COMMENT ''生成后的海外仓真实托盘ID'''); CALL ensure_transfer_nullable_column('ll_warehouse_transfer_pallet', 'pallet_no', 'VARCHAR(128) NULL COMMENT ''生成后的真实托盘码'''); CALL ensure_transfer_nullable_column('ll_warehouse_transfer_pallet', 'warehouse_location_id', 'BIGINT NULL COMMENT ''生成后的真实库位ID'''); CALL ensure_transfer_nullable_column('ll_warehouse_transfer_pallet', 'warehouse_resource_lock_id', 'BIGINT NULL COMMENT ''生成后的仓储资源锁ID'''); CALL ensure_transfer_nullable_column('ll_warehouse_transfer_pallet', 'completed_at', 'DATETIME(3) NULL COMMENT ''整单打托完成时间'''); CALL ensure_transfer_column('ll_warehouse_transfer_pallet', 'draft_idempotency_key', 'VARCHAR(255) NULL COMMENT ''草稿保存幂等键'''); CALL ensure_transfer_column('ll_warehouse_transfer_pallet', 'draft_request_hash', 'CHAR(64) NULL COMMENT ''草稿请求摘要'''); CALL ensure_transfer_column('ll_warehouse_transfer_pallet', 'generate_idempotency_key', 'VARCHAR(255) NULL COMMENT ''新托盘生成幂等键'''); CALL ensure_transfer_column('ll_warehouse_transfer_pallet', 'bind_idempotency_key', 'VARCHAR(255) NULL COMMENT ''扫码绑定幂等键'''); CALL ensure_transfer_column('ll_warehouse_transfer_pallet', 'bound_at', 'DATETIME(3) NULL COMMENT ''扫码确认绑定时间'''); CREATE TABLE IF NOT EXISTS `ll_warehouse_transfer_measurement_photo` ( `id` BIGINT NOT NULL COMMENT '测量照片引用ID', `transfer_order_id` BIGINT NOT NULL COMMENT '仓储转运单ID', `customer_id` VARCHAR(128) NOT NULL COMMENT '客户租户ID', `file_id` BIGINT NOT NULL COMMENT '文件服务文件ID', `file_name` VARCHAR(255) NULL COMMENT '文件名快照', `content_type` VARCHAR(128) NULL COMMENT '文件媒体类型快照', `size_bytes` BIGINT NOT NULL DEFAULT 0 COMMENT '文件字节数快照', `uploaded_by` VARCHAR(128) NULL COMMENT 'PDA上传操作人', `uploaded_at` DATETIME(3) NOT NULL COMMENT '上传时间', `submitted_at` DATETIME(3) NULL COMMENT '随测量打托提交时间', PRIMARY KEY (`id`), UNIQUE KEY `uk_ll_transfer_measurement_photo_file` (`customer_id`,`transfer_order_id`,`file_id`), KEY `idx_ll_transfer_measurement_photo_order` (`customer_id`,`transfer_order_id`,`uploaded_at`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='仓储转运PDA测量现场照片引用'; CALL ensure_transfer_column('ll_warehouse_transfer_measurement_photo', 'submitted_at', 'DATETIME(3) NULL COMMENT ''随测量打托提交时间'''); CALL ensure_transfer_index('ll_warehouse_transfer_measurement_photo', 'uk_ll_transfer_measurement_photo_file', 'UNIQUE KEY `uk_ll_transfer_measurement_photo_file` (`customer_id`,`transfer_order_id`,`file_id`)'); CALL ensure_transfer_index('ll_warehouse_transfer_measurement_photo', 'idx_ll_transfer_measurement_photo_order', 'KEY `idx_ll_transfer_measurement_photo_order` (`customer_id`,`transfer_order_id`,`uploaded_at`)'); -- 入库计划行和托盘保存私人仓目的地快照。 CALL ensure_transfer_column('ll_inbound_plan_line', 'delivery_address', 'VARCHAR(1000) NULL COMMENT ''私人仓目的地址快照'''); CALL ensure_transfer_column('ll_inbound_plan_line', 'postal_code', 'VARCHAR(32) NULL COMMENT ''私人仓邮编快照'''); CALL ensure_transfer_column('ll_inbound_plan_line', 'contact_name', 'VARCHAR(128) NULL COMMENT ''私人仓联系人快照'''); CALL ensure_transfer_column('ll_inbound_plan_line', 'contact_phone', 'VARCHAR(64) NULL COMMENT ''私人仓联系电话快照'''); CALL ensure_transfer_column('ll_inbound_plan_pallet', 'destination_type', 'VARCHAR(32) NULL COMMENT ''目的类型:FBA或PRIVATE'''); CALL ensure_transfer_column('ll_inbound_plan_pallet', 'delivery_address', 'VARCHAR(1000) NULL COMMENT ''私人仓目的地址快照'''); CALL ensure_transfer_column('ll_inbound_plan_pallet', 'postal_code', 'VARCHAR(32) NULL COMMENT ''私人仓邮编快照'''); CALL ensure_transfer_column('ll_inbound_plan_pallet', 'contact_name', 'VARCHAR(128) NULL COMMENT ''私人仓联系人快照'''); CALL ensure_transfer_column('ll_inbound_plan_pallet', 'contact_phone', 'VARCHAR(64) NULL COMMENT ''私人仓联系电话快照'''); CALL ensure_transfer_index('ll_inbound_plan_line', 'idx_ll_inbound_line_tenant_plan', 'KEY `idx_ll_inbound_line_tenant_plan` (`customer_id`,`plan_id`)'); CALL ensure_transfer_index('ll_inbound_plan_pallet', 'idx_ll_inbound_pallet_tenant_plan', 'KEY `idx_ll_inbound_pallet_tenant_plan` (`customer_id`,`plan_id`)'); CALL ensure_transfer_pallet_unique_index(); -- 智能排车候选和排车明细快照。 CALL ensure_transfer_column('ll_dispatch_item', 'destination_type', 'VARCHAR(32) NULL COMMENT ''目的类型:FBA或PRIVATE'''); CALL ensure_transfer_column('ll_dispatch_item', 'delivery_address', 'VARCHAR(1000) NULL COMMENT ''私人仓目的地址快照'''); CALL ensure_transfer_column('ll_dispatch_item', 'postal_code', 'VARCHAR(32) NULL COMMENT ''私人仓邮编快照'''); CALL ensure_transfer_column('ll_dispatch_item', 'contact_name', 'VARCHAR(128) NULL COMMENT ''私人仓联系人快照'''); CALL ensure_transfer_column('ll_dispatch_item', 'contact_phone', 'VARCHAR(64) NULL COMMENT ''私人仓联系电话快照'''); -- 派送单允许私人仓目的地,并保留地址、邮编及联系人快照。 CALL ensure_transfer_column('ll_delivery_order', 'destination_type', 'VARCHAR(16) NULL COMMENT ''目的地类型:FBA或PRIVATE'''); CALL ensure_transfer_column('ll_delivery_order', 'delivery_address', 'VARCHAR(1000) NULL COMMENT ''私人仓派送地址'''); CALL ensure_transfer_column('ll_delivery_order', 'postal_code', 'VARCHAR(32) NULL COMMENT ''私人仓邮编'''); CALL ensure_transfer_column('ll_delivery_order', 'contact_name', 'VARCHAR(128) NULL COMMENT ''私人仓联系人'''); CALL ensure_transfer_column('ll_delivery_order', 'contact_phone', 'VARCHAR(64) NULL COMMENT ''私人仓联系电话'''); -- 仓储转运直接出库历史兼容:这三列允许为空。 CALL ensure_transfer_nullable_column('ll_delivery_order', 'dispatch_order_id', 'BIGINT NULL COMMENT ''关联派车单ID,仓储转运直接出库时为空'''); CALL ensure_transfer_nullable_column('ll_delivery_order', 'dispatch_no', 'VARCHAR(64) NULL COMMENT ''关联派车单号,仓储转运直接出库时为空'''); CALL ensure_transfer_nullable_column('ll_delivery_order', 'destination_warehouse_code', 'VARCHAR(128) NULL COMMENT ''本派送单目的FBA仓编码快照,私人仓为空'''); DROP PROCEDURE IF EXISTS `ensure_transfer_column`; DROP PROCEDURE IF EXISTS `ensure_transfer_nullable_column`; DROP PROCEDURE IF EXISTS `ensure_transfer_index`; DROP PROCEDURE IF EXISTS `ensure_transfer_pallet_unique_index`; SELECT DATABASE() AS target_database, IF( EXISTS ( SELECT 1 FROM information_schema.statistics WHERE table_schema = DATABASE() AND table_name = 'll_inbound_plan_pallet' AND index_name = 'uk_ll_inbound_pallet_no' ), 'WAREHOUSE_TRANSFER_LATEST_SCHEMA_READY', 'WAREHOUSE_TRANSFER_SCHEMA_APPLIED_WITH_INDEX_BLOCKER' ) AS migration_result, IF( EXISTS ( SELECT 1 FROM information_schema.statistics WHERE table_schema = DATABASE() AND table_name = 'll_inbound_plan_pallet' AND index_name = 'uk_ll_inbound_pallet_no' ), 'READY', 'BLOCKED_BY_DUPLICATE_CUSTOMER_PALLET_NO' ) AS inbound_pallet_unique_index;