-- 二期托盘、库位、预占与占用表结构。 -- 本脚本只新增表、字段、索引和约束,不包含业务数据及流程实现。 -- 可在 warehouse.sql 和一期增量脚本之后执行;所有建表均可重复执行。 SET NAMES utf8mb4; CREATE DATABASE IF NOT EXISTS baiyue_warehouse DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci; USE baiyue_warehouse; CREATE TABLE IF NOT EXISTS wh_pallet ( id BIGINT UNSIGNED NOT NULL COMMENT '托盘ID(雪花ID)', tenant_id BIGINT UNSIGNED NOT NULL COMMENT '平台公共托盘固定使用 tenant_id=0', warehouse_id BIGINT UNSIGNED NOT NULL COMMENT '所属仓库ID', pallet_code VARCHAR(50) NOT NULL COMMENT '平台仓库内唯一托盘编码', pallet_type VARCHAR(32) NOT NULL COMMENT '托盘类型', pallet_name VARCHAR(100) NULL COMMENT '托盘名称', capacity_cbm DECIMAL(18,6) NOT NULL COMMENT '托盘可用容积CBM', weight_kg DECIMAL(18,3) NOT NULL DEFAULT 0 COMMENT '托盘重量kg', color VARCHAR(32) NOT NULL DEFAULT '' COMMENT '托盘颜色', status VARCHAR(20) NOT NULL DEFAULT 'AVAILABLE' COMMENT '内部状态:AVAILABLE、RESERVED或OCCUPIED', remark VARCHAR(500) NULL COMMENT '备注', created_by BIGINT UNSIGNED NOT NULL COMMENT '创建人ID', created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '创建时间', updated_by BIGINT UNSIGNED NOT NULL COMMENT '最后修改人ID', updated_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3) COMMENT '更新时间', deleted TINYINT(1) NOT NULL DEFAULT 0 COMMENT '逻辑删除标记', version INT NOT NULL DEFAULT 0 COMMENT '乐观锁版本号', PRIMARY KEY (id), UNIQUE KEY uk_pallet_tenant_code (tenant_id, pallet_code), KEY idx_pallet_available (tenant_id, warehouse_id, status, deleted), KEY idx_pallet_type (tenant_id, warehouse_id, pallet_type, status, deleted), CONSTRAINT fk_pallet_warehouse FOREIGN KEY (warehouse_id) REFERENCES wh_warehouse (id), CONSTRAINT ck_pallet_capacity CHECK (capacity_cbm > 0) ) ENGINE=InnoDB COMMENT='二期托盘基础资料和物理托盘实例'; CREATE TABLE IF NOT EXISTS wh_location ( id BIGINT UNSIGNED NOT NULL COMMENT '库位ID(雪花ID)', tenant_id BIGINT UNSIGNED NOT NULL COMMENT '平台公共库位固定使用 tenant_id=0', warehouse_id BIGINT UNSIGNED NOT NULL COMMENT '所属仓库ID', zone_code VARCHAR(50) NULL COMMENT '库区编码', zone_name VARCHAR(100) NULL COMMENT '库区名称', location_code VARCHAR(50) NOT NULL COMMENT '平台仓库内唯一库位编码', location_name VARCHAR(100) NULL COMMENT '库位名称', location_type VARCHAR(32) NOT NULL DEFAULT 'PALLET' COMMENT '库位类型,二期为PALLET', max_weight_kg DECIMAL(18,3) NULL COMMENT '最大承重展示值,二期不作容量拦截', shared_overflow TINYINT(1) NOT NULL DEFAULT 0 COMMENT '是否为系统共享溢出位A0', status VARCHAR(20) NOT NULL DEFAULT 'AVAILABLE' COMMENT 'AVAILABLE、RESERVED、OCCUPIED或DISABLED', remark VARCHAR(500) NULL COMMENT '备注', created_by BIGINT UNSIGNED NOT NULL COMMENT '创建人ID', created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '创建时间', updated_by BIGINT UNSIGNED NOT NULL COMMENT '最后修改人ID', updated_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3) COMMENT '更新时间', deleted TINYINT(1) NOT NULL DEFAULT 0 COMMENT '逻辑删除标记', version INT NOT NULL DEFAULT 0 COMMENT '乐观锁版本号', PRIMARY KEY (id), UNIQUE KEY uk_location_tenant_warehouse_code (tenant_id, warehouse_id, location_code), KEY idx_location_available (tenant_id, warehouse_id, status, deleted), KEY idx_location_zone (tenant_id, warehouse_id, zone_code, status, deleted), CONSTRAINT fk_location_warehouse FOREIGN KEY (warehouse_id) REFERENCES wh_warehouse (id), CONSTRAINT ck_location_max_weight CHECK (max_weight_kg IS NULL OR max_weight_kg > 0) ) ENGINE=InnoDB COMMENT='二期库位基础资料,默认一托盘对应一个库位且不作容量校验'; CREATE TABLE IF NOT EXISTS wh_location_reservation ( id BIGINT UNSIGNED NOT NULL COMMENT '库位预占ID', tenant_id BIGINT UNSIGNED NOT NULL COMMENT '平台公共库位预占固定使用 tenant_id=0', reservation_no VARCHAR(40) NOT NULL COMMENT '平台内唯一预占业务号', idempotency_key VARCHAR(128) NOT NULL COMMENT '调用方幂等键', source_service VARCHAR(40) NOT NULL DEFAULT 'FIRSTLEG' COMMENT '来源服务', business_id BIGINT UNSIGNED NOT NULL COMMENT '来源服务入库单ID', inbound_code VARCHAR(40) NOT NULL COMMENT '入仓码快照', warehouse_id BIGINT UNSIGNED NOT NULL COMMENT '仓库ID', pallet_id BIGINT UNSIGNED NOT NULL COMMENT '托盘ID', pallet_code VARCHAR(50) NOT NULL COMMENT '托盘编码快照', location_id BIGINT UNSIGNED NOT NULL COMMENT '库位ID', location_code VARCHAR(50) NOT NULL COMMENT '库位编码快照', shared_overflow TINYINT(1) NOT NULL DEFAULT 0 COMMENT '是否使用共享溢出位A0', reservation_status VARCHAR(20) NOT NULL DEFAULT 'RESERVED' COMMENT 'RESERVED、CONFIRMED、RELEASED或EXPIRED', expires_at DATETIME(3) NOT NULL COMMENT '预占过期时间', confirmed_at DATETIME(3) NULL COMMENT '确认占用时间', released_at DATETIME(3) NULL COMMENT '释放时间', release_reason VARCHAR(500) NULL COMMENT '释放或过期原因', created_by BIGINT UNSIGNED NOT 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 '更新时间', version INT NOT NULL DEFAULT 0 COMMENT '乐观锁版本号', active_reservation TINYINT GENERATED ALWAYS AS (CASE WHEN reservation_status = 'RESERVED' AND shared_overflow = 0 THEN 1 ELSE NULL END) STORED COMMENT '普通库位活动预占唯一标记', active_pallet_reservation TINYINT GENERATED ALWAYS AS (CASE WHEN reservation_status = 'RESERVED' THEN 1 ELSE NULL END) STORED COMMENT '托盘活动预占唯一标记(包含A0)', PRIMARY KEY (id), UNIQUE KEY uk_location_reservation_no (tenant_id, reservation_no), UNIQUE KEY uk_location_reservation_idempotency (tenant_id, source_service, idempotency_key), UNIQUE KEY uk_location_active_reservation (tenant_id, location_id, active_reservation), UNIQUE KEY uk_pallet_active_reservation (tenant_id, pallet_id, active_pallet_reservation), KEY idx_location_reservation_business (tenant_id, source_service, business_id, reservation_status), KEY idx_location_reservation_expire (reservation_status, expires_at), KEY idx_location_reservation_target (tenant_id, warehouse_id, location_id, reservation_status), CONSTRAINT fk_reservation_warehouse FOREIGN KEY (warehouse_id) REFERENCES wh_warehouse (id), CONSTRAINT fk_reservation_pallet FOREIGN KEY (pallet_id) REFERENCES wh_pallet (id), CONSTRAINT fk_reservation_location FOREIGN KEY (location_id) REFERENCES wh_location (id) ) ENGINE=InnoDB COMMENT='跨服务入库Saga的托盘和库位临时预占'; CREATE TABLE IF NOT EXISTS wh_location_occupancy ( id BIGINT UNSIGNED NOT NULL COMMENT '库位占用ID', tenant_id BIGINT UNSIGNED NOT NULL COMMENT '平台公共库位占用固定使用 tenant_id=0', occupancy_no VARCHAR(40) NOT NULL COMMENT '平台内唯一占用业务号', reservation_id BIGINT UNSIGNED NOT NULL COMMENT '来源预占ID', source_service VARCHAR(40) NOT NULL DEFAULT 'FIRSTLEG' COMMENT '来源服务', business_id BIGINT UNSIGNED NOT NULL COMMENT '来源服务入库单ID', inbound_code VARCHAR(40) NOT NULL COMMENT '入仓码快照', warehouse_id BIGINT UNSIGNED NOT NULL COMMENT '仓库ID', pallet_id BIGINT UNSIGNED NOT NULL COMMENT '托盘ID', pallet_code VARCHAR(50) NOT NULL COMMENT '托盘编码快照', location_id BIGINT UNSIGNED NOT NULL COMMENT '库位ID', location_code VARCHAR(50) NOT NULL COMMENT '库位编码快照', shared_overflow TINYINT(1) NOT NULL DEFAULT 0 COMMENT '是否使用共享溢出位A0', allocated_volume_cbm DECIMAL(18,6) NOT NULL COMMENT '本托盘分配体积CBM', allocated_package_count INT UNSIGNED NULL COMMENT '本托盘分配箱数', occupancy_status VARCHAR(20) NOT NULL DEFAULT 'OCCUPIED' COMMENT 'OCCUPIED或RELEASED', occupied_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '占用开始时间', released_at DATETIME(3) NULL COMMENT '释放时间', release_reason VARCHAR(500) NULL COMMENT '释放原因', created_by BIGINT UNSIGNED NOT 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 '更新时间', version INT NOT NULL DEFAULT 0 COMMENT '乐观锁版本号', active_location_occupancy TINYINT GENERATED ALWAYS AS (CASE WHEN occupancy_status = 'OCCUPIED' AND shared_overflow = 0 THEN 1 ELSE NULL END) STORED COMMENT '普通库位活动占用唯一标记', active_pallet_occupancy TINYINT GENERATED ALWAYS AS (CASE WHEN occupancy_status = 'OCCUPIED' THEN 1 ELSE NULL END) STORED COMMENT '托盘活动占用唯一标记(包含A0)', PRIMARY KEY (id), UNIQUE KEY uk_location_occupancy_no (tenant_id, occupancy_no), UNIQUE KEY uk_occupancy_reservation (tenant_id, reservation_id), UNIQUE KEY uk_location_active_occupancy (tenant_id, location_id, active_location_occupancy), UNIQUE KEY uk_pallet_active_occupancy (tenant_id, pallet_id, active_pallet_occupancy), KEY idx_occupancy_business (tenant_id, source_service, business_id, occupancy_status), KEY idx_occupancy_warehouse (tenant_id, warehouse_id, occupancy_status, occupied_at), CONSTRAINT fk_occupancy_reservation FOREIGN KEY (reservation_id) REFERENCES wh_location_reservation (id), CONSTRAINT fk_occupancy_warehouse FOREIGN KEY (warehouse_id) REFERENCES wh_warehouse (id), CONSTRAINT fk_occupancy_pallet FOREIGN KEY (pallet_id) REFERENCES wh_pallet (id), CONSTRAINT fk_occupancy_location FOREIGN KEY (location_id) REFERENCES wh_location (id), CONSTRAINT ck_occupancy_volume CHECK (allocated_volume_cbm > 0) ) ENGINE=InnoDB COMMENT='已确认的一托一库位占用事实记录'; -- 头程入库单属于其他数据库,不建立跨库外键。