This commit is contained in:
2026-08-05 16:26:10 +08:00
parent 06f7f9d2f2
commit 5ba9716e12
155 changed files with 2883 additions and 551 deletions
@@ -119,6 +119,54 @@ CALL add_column_if_missing('wh_express_company', 'updated_at', 'DATETIME(3) NOT
CALL add_column_if_missing('wh_express_company', 'deleted', 'TINYINT(1) NOT NULL DEFAULT 0');
CALL add_column_if_missing('wh_express_company', 'version', 'INT NOT NULL DEFAULT 0');
-- 平台公共仓储主数据和平台往来单位统一归平台作用域 0;订单自身仍按客户 tenant_id 隔离。
UPDATE wh_warehouse SET tenant_id = 0 WHERE tenant_id <> 0;
UPDATE wh_warehouse_address a
JOIN wh_warehouse w ON w.id = a.warehouse_id
SET a.tenant_id = w.tenant_id
WHERE a.tenant_id <> w.tenant_id;
UPDATE wh_service_capability c
JOIN wh_warehouse w ON w.id = c.warehouse_id
SET c.tenant_id = w.tenant_id
WHERE c.tenant_id <> w.tenant_id;
UPDATE wh_warehouse_address SET tenant_id = 0 WHERE tenant_id <> 0;
UPDATE wh_service_capability SET tenant_id = 0 WHERE tenant_id <> 0;
UPDATE wh_express_company SET tenant_id = 0 WHERE tenant_id <> 0;
UPDATE wh_partner SET tenant_id = 0, data_scope_id = 0
WHERE tenant_id <> 0 OR data_scope_id <> 0;
UPDATE wh_partner_type SET tenant_id = 0, data_scope_id = 0
WHERE tenant_id <> 0 OR data_scope_id <> 0;
DROP PROCEDURE IF EXISTS assert_platform_public_resource_scope;
DELIMITER $$
CREATE PROCEDURE assert_platform_public_resource_scope()
BEGIN
IF (SELECT COUNT(*) FROM wh_warehouse WHERE tenant_id <> 0) > 0
OR (SELECT COUNT(*) FROM wh_warehouse_address WHERE tenant_id <> 0) > 0
OR (SELECT COUNT(*) FROM wh_service_capability WHERE tenant_id <> 0) > 0
OR (SELECT COUNT(*) FROM wh_express_company WHERE tenant_id <> 0) > 0
OR (SELECT COUNT(*) FROM wh_partner WHERE tenant_id <> 0 OR data_scope_id <> 0) > 0
OR (SELECT COUNT(*) FROM wh_partner_type WHERE tenant_id <> 0 OR data_scope_id <> 0) > 0 THEN
SIGNAL SQLSTATE '45000'
SET MESSAGE_TEXT = 'Warehouse 迁移失败:平台公共仓储或往来单位仍有非0作用域';
END IF;
IF EXISTS (
SELECT 1 FROM wh_warehouse_address a
JOIN wh_warehouse w ON w.id = a.warehouse_id
WHERE a.tenant_id <> w.tenant_id
) OR EXISTS (
SELECT 1 FROM wh_service_capability c
JOIN wh_warehouse w ON w.id = c.warehouse_id
WHERE c.tenant_id <> w.tenant_id
) THEN
SIGNAL SQLSTATE '45000'
SET MESSAGE_TEXT = 'Warehouse 迁移失败:仓库子表与父仓库平台归属不一致';
END IF;
END$$
DELIMITER ;
CALL assert_platform_public_resource_scope();
DROP PROCEDURE IF EXISTS assert_platform_public_resource_scope;
DROP PROCEDURE IF EXISTS add_column_if_missing;
-- MySQL 8 的 ALTER ADD INDEX 不在所有小版本都支持 IF NOT EXISTS,使用元数据判断以保证重复执行安全。
@@ -35,6 +35,12 @@ PREPARE statement FROM @sql;
EXECUTE statement;
DEALLOCATE PREPARE statement;
-- 托盘、库位、预占和占用均为平台公共仓储资源,存量测试数据统一迁移到平台作用域 0。
UPDATE wh_pallet SET tenant_id = 0 WHERE tenant_id <> 0;
UPDATE wh_location SET tenant_id = 0 WHERE tenant_id <> 0;
UPDATE wh_location_reservation SET tenant_id = 0 WHERE tenant_id <> 0;
UPDATE wh_location_occupancy SET tenant_id = 0 WHERE tenant_id <> 0;
SET @sql = IF((SELECT COUNT(*) FROM information_schema.statistics
WHERE table_schema = @schema_name
AND table_name = 'wh_location_reservation'
@@ -44,3 +50,43 @@ SET @sql = IF((SELECT COUNT(*) FROM information_schema.statistics
PREPARE statement FROM @sql;
EXECUTE statement;
DEALLOCATE PREPARE statement;
DROP PROCEDURE IF EXISTS assert_phase2_public_resource_scope;
DELIMITER $$
CREATE PROCEDURE assert_phase2_public_resource_scope()
BEGIN
IF (SELECT COUNT(*) FROM wh_pallet WHERE tenant_id <> 0) > 0
OR (SELECT COUNT(*) FROM wh_location WHERE tenant_id <> 0) > 0
OR (SELECT COUNT(*) FROM wh_location_reservation WHERE tenant_id <> 0) > 0
OR (SELECT COUNT(*) FROM wh_location_occupancy WHERE tenant_id <> 0) > 0 THEN
SIGNAL SQLSTATE '45000'
SET MESSAGE_TEXT = 'Warehouse 二期迁移失败:托盘、库位、预占或占用仍有 tenant_id<>0';
END IF;
IF EXISTS (
SELECT 1 FROM wh_pallet p JOIN wh_warehouse w ON w.id = p.warehouse_id
WHERE p.tenant_id <> w.tenant_id
) OR EXISTS (
SELECT 1 FROM wh_location l JOIN wh_warehouse w ON w.id = l.warehouse_id
WHERE l.tenant_id <> w.tenant_id
) OR EXISTS (
SELECT 1 FROM wh_location_reservation r
JOIN wh_warehouse w ON w.id = r.warehouse_id
JOIN wh_pallet p ON p.id = r.pallet_id
JOIN wh_location l ON l.id = r.location_id
WHERE r.tenant_id <> w.tenant_id OR r.tenant_id <> p.tenant_id OR r.tenant_id <> l.tenant_id
) OR EXISTS (
SELECT 1 FROM wh_location_occupancy o
JOIN wh_warehouse w ON w.id = o.warehouse_id
JOIN wh_pallet p ON p.id = o.pallet_id
JOIN wh_location l ON l.id = o.location_id
JOIN wh_location_reservation r ON r.id = o.reservation_id
WHERE o.tenant_id <> w.tenant_id OR o.tenant_id <> p.tenant_id
OR o.tenant_id <> l.tenant_id OR o.tenant_id <> r.tenant_id
) THEN
SIGNAL SQLSTATE '45000'
SET MESSAGE_TEXT = 'Warehouse 二期迁移失败:公共仓储资源父子归属不一致';
END IF;
END$$
DELIMITER ;
CALL assert_phase2_public_resource_scope();
DROP PROCEDURE IF EXISTS assert_phase2_public_resource_scope;
@@ -9,9 +9,9 @@ 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 '数据所属租户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_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',
@@ -33,11 +33,11 @@ CREATE TABLE IF NOT EXISTS wh_pallet (
CREATE TABLE IF NOT EXISTS wh_location (
id BIGINT UNSIGNED NOT NULL COMMENT '库位ID(雪花ID)',
tenant_id BIGINT UNSIGNED NOT NULL COMMENT '数据所属租户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_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 '最大承重展示值,二期不作容量拦截',
@@ -60,8 +60,8 @@ CREATE TABLE IF NOT EXISTS wh_location (
CREATE TABLE IF NOT EXISTS wh_location_reservation (
id BIGINT UNSIGNED NOT NULL COMMENT '库位预占ID',
tenant_id BIGINT UNSIGNED NOT NULL COMMENT '数据所属租户ID',
reservation_no VARCHAR(40) NOT NULL COMMENT '租户内唯一预占业务号',
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',
@@ -98,8 +98,8 @@ CREATE TABLE IF NOT EXISTS wh_location_reservation (
CREATE TABLE IF NOT EXISTS wh_location_occupancy (
id BIGINT UNSIGNED NOT NULL COMMENT '库位占用ID',
tenant_id BIGINT UNSIGNED NOT NULL COMMENT '数据所属租户ID',
occupancy_no VARCHAR(40) NOT NULL COMMENT '租户内唯一占用业务号',
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',
@@ -3,8 +3,8 @@ USE baiyue_warehouse;
CREATE TABLE IF NOT EXISTS wh_express_company (
id BIGINT UNSIGNED NOT NULL COMMENT '快递公司记录ID',
tenant_id BIGINT UNSIGNED NOT NULL COMMENT '所属租户ID',
company_code VARCHAR(50) NOT NULL COMMENT '租户内唯一快递公司编码',
tenant_id BIGINT UNSIGNED NOT NULL COMMENT '平台公共快递公司固定使用 tenant_id=0',
company_code VARCHAR(50) NOT NULL COMMENT '平台内唯一快递公司编码',
company_name VARCHAR(128) NOT NULL COMMENT '快递公司名称',
service_phone VARCHAR(32) DEFAULT NULL COMMENT '客服电话',
website VARCHAR(255) DEFAULT NULL COMMENT '官方网站',
@@ -21,4 +21,4 @@ CREATE TABLE IF NOT EXISTS wh_express_company (
UNIQUE KEY uk_wh_express_tenant_code (tenant_id, company_code, deleted),
UNIQUE KEY uk_wh_express_tenant_name (tenant_id, company_name, deleted),
KEY idx_wh_express_tenant_status (tenant_id, status, deleted)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='租户维度快递公司主数据';
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='平台公共快递公司主数据,固定归属 tenant_id=0';
@@ -16,18 +16,18 @@ CREATE TABLE IF NOT EXISTS wh_partner (
deleted TINYINT(1) NOT NULL DEFAULT 0, version INT NOT NULL DEFAULT 0,
PRIMARY KEY(id), UNIQUE KEY uk_wh_partner_tenant_code(tenant_id,partner_code,deleted),
KEY idx_wh_partner_tenant_status(tenant_id,status,deleted)
) ENGINE=InnoDB COMMENT='仓储域内的租户往来单位配置';
) ENGINE=InnoDB COMMENT='平台统一维护、供全部客户共享的往来单位主数据';
CREATE TABLE IF NOT EXISTS wh_partner_type (
partner_id BIGINT UNSIGNED NOT NULL, tenant_id BIGINT UNSIGNED NOT NULL,
data_scope_id BIGINT UNSIGNED NOT NULL, partner_type VARCHAR(32) NOT NULL,
PRIMARY KEY(partner_id,partner_type),
KEY idx_wh_partner_type_scope(tenant_id,data_scope_id,partner_type,partner_id)
) ENGINE=InnoDB COMMENT='往来单位稳定业务类型';
) ENGINE=InnoDB COMMENT='平台共享往来单位稳定业务类型';
INSERT INTO wh_partner(id,tenant_id,data_scope_id,partner_code,partner_name,partner_type,contact_name,contact_phone,contact_email,country_code,province,city,district,address_line,postal_code,status)
VALUES(191000000000000001,10001,10001,'CUS-001','深圳示例贸易有限公司','CUSTOMER','张三','13800138000','contact@example.com','CN','广东省','深圳市','宝安区','航城街道示例路1号','518000','ACTIVE')
ON DUPLICATE KEY UPDATE partner_name=VALUES(partner_name),status='ACTIVE';
VALUES(191000000000000001,0,0,'CUS-001','深圳示例贸易有限公司','CUSTOMER','张三','13800138000','contact@example.com','CN','广东省','深圳市','宝安区','航城街道示例路1号','518000','ACTIVE')
ON DUPLICATE KEY UPDATE tenant_id=VALUES(tenant_id),data_scope_id=VALUES(data_scope_id),partner_name=VALUES(partner_name),status='ACTIVE';
INSERT INTO wh_partner_type(partner_id,tenant_id,data_scope_id,partner_type)
VALUES
(191000000000000001,10001,10001,'CUSTOMER'),
(191000000000000001,10001,10001,'SHIPPER')
(191000000000000001,0,0,'CUSTOMER'),
(191000000000000001,0,0,'SHIPPER')
ON DUPLICATE KEY UPDATE tenant_id=VALUES(tenant_id),data_scope_id=VALUES(data_scope_id);
@@ -2,16 +2,16 @@ SET NAMES utf8mb4;
USE baiyue_warehouse;
-- 一期联调初始化仓库,重复执行不会产生重复数据。
INSERT INTO wh_warehouse(id,tenant_id,warehouse_code,warehouse_name,warehouse_type,country_code,timezone,contact_name,contact_phone,status,remark)
VALUES(190000000000000001,10001,'CN-SZX-01','深圳头程收货仓','DOMESTIC','CN','Asia/Shanghai','仓库收货组','0755-88886666','ACTIVE','工作日预约收货')
ON DUPLICATE KEY UPDATE warehouse_name=VALUES(warehouse_name),status='ACTIVE';
VALUES(190000000000000001,0,'CN-SZX-01','深圳头程收货仓','DOMESTIC','CN','Asia/Shanghai','仓库收货组','0755-88886666','ACTIVE','工作日预约收货')
ON DUPLICATE KEY UPDATE tenant_id=0,warehouse_name=VALUES(warehouse_name),status='ACTIVE';
INSERT INTO wh_warehouse_address(id,tenant_id,warehouse_id,address_type,country_code,state_province,city,district,postal_code,address_line1)
VALUES(190000000000000011,10001,190000000000000001,'OPERATING','CN','广东省','深圳市','宝安区','518000','航城街道示例物流园1号仓')
ON DUPLICATE KEY UPDATE address_line1=VALUES(address_line1);
VALUES(190000000000000011,0,190000000000000001,'OPERATING','CN','广东省','深圳市','宝安区','518000','航城街道示例物流园1号仓')
ON DUPLICATE KEY UPDATE tenant_id=0,address_line1=VALUES(address_line1);
INSERT INTO wh_service_capability(id,tenant_id,warehouse_id,capability_code,capability_name,enabled,cutoff_time,description)
VALUES(190000000000000021,10001,190000000000000001,'RECEIVING','头程收货',1,'16:00:00','工作日16点前预约可当日收货')
ON DUPLICATE KEY UPDATE enabled=1,cutoff_time=VALUES(cutoff_time);
VALUES(190000000000000021,0,190000000000000001,'RECEIVING','头程收货',1,'16:00:00','工作日16点前预约可当日收货')
ON DUPLICATE KEY UPDATE tenant_id=0,enabled=1,cutoff_time=VALUES(cutoff_time);
-- 一期联调快递公司主数据,供平台维护和订单履约回显验证。
INSERT INTO wh_express_company(id,tenant_id,company_code,company_name,service_phone,website,tracking_url_template,status,remark)
VALUES(192000000000000001,10001,'SF','顺丰速运','95338','https://www.sf-express.com','https://www.sf-express.com/chn/sc/dynamic_function/waybill/#search/bill-number/{trackingNo}','ACTIVE','一期联调样本,可按租户回收')
ON DUPLICATE KEY UPDATE company_name=VALUES(company_name),status='ACTIVE';
VALUES(192000000000000001,0,'SF','顺丰速运','95338','https://www.sf-express.com','https://www.sf-express.com/chn/sc/dynamic_function/waybill/#search/bill-number/{trackingNo}','ACTIVE','平台公共快递公司样本')
ON DUPLICATE KEY UPDATE tenant_id=0,company_name=VALUES(company_name),status='ACTIVE';
@@ -5,8 +5,8 @@ USE baiyue_warehouse;
CREATE TABLE IF NOT EXISTS wh_warehouse (
id BIGINT UNSIGNED NOT NULL COMMENT '仓库ID(雪花ID)',
tenant_id BIGINT UNSIGNED NOT NULL COMMENT '仓库所属租户ID',
warehouse_code VARCHAR(50) NOT NULL COMMENT '租户内唯一仓库编码',
tenant_id BIGINT UNSIGNED NOT NULL COMMENT '平台公共仓库固定使用 tenant_id=0',
warehouse_code VARCHAR(50) NOT NULL COMMENT '平台内唯一仓库编码',
warehouse_name VARCHAR(120) NOT NULL COMMENT '仓库名称',
warehouse_type VARCHAR(32) NOT NULL DEFAULT 'DOMESTIC' COMMENT '公共仓库类型:DOMESTIC、FBA、OVERSEAS',
country_code CHAR(2) NOT NULL COMMENT '所在国家二字码',
@@ -27,11 +27,11 @@ CREATE TABLE IF NOT EXISTS wh_warehouse (
KEY idx_wh_tenant_status (tenant_id, status, deleted),
KEY idx_wh_tenant_type_status (tenant_id, warehouse_type, status, deleted),
KEY idx_wh_country (tenant_id, country_code, deleted)
) ENGINE=InnoDB COMMENT='仓库主数据表:以租户为边界维护仓库编码、名称、国家、时区和启停状态';
) ENGINE=InnoDB COMMENT='平台公共仓库主数据表:统一归属平台作用域 tenant_id=0';
CREATE TABLE IF NOT EXISTS wh_warehouse_address (
id BIGINT UNSIGNED NOT NULL COMMENT '仓库地址ID',
tenant_id BIGINT UNSIGNED NOT NULL COMMENT '数据所属租户ID',
tenant_id BIGINT UNSIGNED NOT NULL COMMENT '平台公共仓库地址固定使用 tenant_id=0',
warehouse_id BIGINT UNSIGNED NOT NULL COMMENT '所属仓库ID',
address_type VARCHAR(20) NOT NULL DEFAULT 'OPERATING' COMMENT '地址类型,例如OPERATING或RETURN',
country_code CHAR(2) NOT NULL COMMENT '国家二字码',
@@ -56,7 +56,7 @@ CREATE TABLE IF NOT EXISTS wh_warehouse_address (
CREATE TABLE IF NOT EXISTS wh_service_capability (
id BIGINT UNSIGNED NOT NULL COMMENT '服务能力ID',
tenant_id BIGINT UNSIGNED NOT NULL COMMENT '数据所属租户ID',
tenant_id BIGINT UNSIGNED NOT NULL COMMENT '平台公共仓库服务能力固定使用 tenant_id=0',
warehouse_id BIGINT UNSIGNED NOT NULL COMMENT '所属仓库ID',
capability_code VARCHAR(50) NOT NULL COMMENT '能力编码:RECEIVING、STORAGE、PICK_PACK、RETURN等',
capability_name VARCHAR(100) NOT NULL COMMENT '能力名称',