Files
baiyue-firstleg/deploy/sql/2026-08-03-一期头程下单前置增量迁移.sql
T
2026-08-03 17:26:59 +08:00

203 lines
12 KiB
SQL

-- 一期头程下单前置增量迁移。
-- 适用:旧版测试库已存在基础表,但缺少客户档案、往来单位或订单一期字段。
-- 特性:仅新增缺失字段/表,可重复执行;不删除数据,不写入订单业务数据。
SET NAMES utf8mb4;
-- 1. IAM:下单资格校验会查询以下租户档案字段。
USE baiyue_iam;
SET @ddl = IF(
EXISTS(SELECT 1 FROM information_schema.columns WHERE table_schema = DATABASE() AND table_name = 'iam_tenant' AND column_name = 'service_package'),
'SELECT 1', 'ALTER TABLE iam_tenant ADD COLUMN service_package VARCHAR(64) NOT NULL DEFAULT ''基础版'' COMMENT ''客户服务套餐'' AFTER contact_email');
PREPARE stmt FROM @ddl; EXECUTE stmt; DEALLOCATE PREPARE stmt;
SET @ddl = IF(
EXISTS(SELECT 1 FROM information_schema.columns WHERE table_schema = DATABASE() AND table_name = 'iam_tenant' AND column_name = 'contact_wechat'),
'SELECT 1', 'ALTER TABLE iam_tenant ADD COLUMN contact_wechat VARCHAR(64) NULL COMMENT ''联系微信'' AFTER contact_email');
PREPARE stmt FROM @ddl; EXECUTE stmt; DEALLOCATE PREPARE stmt;
SET @ddl = IF(
EXISTS(SELECT 1 FROM information_schema.columns WHERE table_schema = DATABASE() AND table_name = 'iam_tenant' AND column_name = 'sales_owner_name'),
'SELECT 1', 'ALTER TABLE iam_tenant ADD COLUMN sales_owner_name VARCHAR(64) NULL COMMENT ''销售负责人姓名'' AFTER contact_wechat');
PREPARE stmt FROM @ddl; EXECUTE stmt; DEALLOCATE PREPARE stmt;
SET @ddl = IF(
EXISTS(SELECT 1 FROM information_schema.columns WHERE table_schema = DATABASE() AND table_name = 'iam_tenant' AND column_name = 'payment_term_days'),
'SELECT 1', 'ALTER TABLE iam_tenant ADD COLUMN payment_term_days SMALLINT UNSIGNED NULL COMMENT ''账期天数'' AFTER sales_owner_name');
PREPARE stmt FROM @ddl; EXECUTE stmt; DEALLOCATE PREPARE stmt;
SET @ddl = IF(
EXISTS(SELECT 1 FROM information_schema.columns WHERE table_schema = DATABASE() AND table_name = 'iam_tenant' AND column_name = 'enterprise_type'),
'SELECT 1', 'ALTER TABLE iam_tenant ADD COLUMN enterprise_type VARCHAR(64) NULL COMMENT ''企业类型'' AFTER payment_term_days');
PREPARE stmt FROM @ddl; EXECUTE stmt; DEALLOCATE PREPARE stmt;
SET @ddl = IF(
EXISTS(SELECT 1 FROM information_schema.columns WHERE table_schema = DATABASE() AND table_name = 'iam_tenant' AND column_name = 'established_date'),
'SELECT 1', 'ALTER TABLE iam_tenant ADD COLUMN established_date DATE NULL COMMENT ''成立日期'' AFTER enterprise_type');
PREPARE stmt FROM @ddl; EXECUTE stmt; DEALLOCATE PREPARE stmt;
SET @ddl = IF(
EXISTS(SELECT 1 FROM information_schema.columns WHERE table_schema = DATABASE() AND table_name = 'iam_tenant' AND column_name = 'registered_capital'),
'SELECT 1', 'ALTER TABLE iam_tenant ADD COLUMN registered_capital DECIMAL(18,2) NULL COMMENT ''注册资本'' AFTER established_date');
PREPARE stmt FROM @ddl; EXECUTE stmt; DEALLOCATE PREPARE stmt;
SET @ddl = IF(
EXISTS(SELECT 1 FROM information_schema.columns WHERE table_schema = DATABASE() AND table_name = 'iam_tenant' AND column_name = 'registered_capital_currency'),
'SELECT 1', 'ALTER TABLE iam_tenant ADD COLUMN registered_capital_currency CHAR(3) NULL COMMENT ''注册资本币种'' AFTER registered_capital');
PREPARE stmt FROM @ddl; EXECUTE stmt; DEALLOCATE PREPARE stmt;
SET @ddl = IF(
EXISTS(SELECT 1 FROM information_schema.columns WHERE table_schema = DATABASE() AND table_name = 'iam_tenant' AND column_name = 'registered_address'),
'SELECT 1', 'ALTER TABLE iam_tenant ADD COLUMN registered_address VARCHAR(500) NULL COMMENT ''注册地址'' AFTER registered_capital_currency');
PREPARE stmt FROM @ddl; EXECUTE stmt; DEALLOCATE PREPARE stmt;
SET @ddl = IF(
EXISTS(SELECT 1 FROM information_schema.columns WHERE table_schema = DATABASE() AND table_name = 'iam_tenant' AND column_name = 'internal_remark'),
'SELECT 1', 'ALTER TABLE iam_tenant ADD COLUMN internal_remark VARCHAR(1000) NULL COMMENT ''平台内部备注'' AFTER registered_address');
PREPARE stmt FROM @ddl; EXECUTE stmt; DEALLOCATE PREPARE stmt;
-- 2. Warehouse:订单主数据校验依赖往来单位及其 SHIPPER 类型。
USE baiyue_warehouse;
DROP PROCEDURE IF EXISTS order_prerequisite_add_partner_column;
DELIMITER $$
CREATE PROCEDURE order_prerequisite_add_partner_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 = 'wh_partner' AND column_name = p_column
) THEN
SET @sql = CONCAT('ALTER TABLE wh_partner ADD COLUMN `', p_column, '` ', p_definition);
PREPARE add_column_stmt FROM @sql;
EXECUTE add_column_stmt;
DEALLOCATE PREPARE add_column_stmt;
END IF;
END$$
DELIMITER ;
CALL order_prerequisite_add_partner_column('tenant_id', 'BIGINT UNSIGNED NOT NULL DEFAULT 0');
CALL order_prerequisite_add_partner_column('data_scope_id', 'BIGINT UNSIGNED NOT NULL DEFAULT 0');
CALL order_prerequisite_add_partner_column('partner_code', 'VARCHAR(50) NOT NULL DEFAULT ''''');
CALL order_prerequisite_add_partner_column('partner_name', 'VARCHAR(128) NOT NULL DEFAULT ''''');
CALL order_prerequisite_add_partner_column('partner_type', 'VARCHAR(20) NOT NULL DEFAULT ''CUSTOMER''');
CALL order_prerequisite_add_partner_column('contact_name', 'VARCHAR(64) NOT NULL DEFAULT ''''');
CALL order_prerequisite_add_partner_column('contact_phone', 'VARCHAR(32) NOT NULL DEFAULT ''''');
CALL order_prerequisite_add_partner_column('contact_email', 'VARCHAR(128) NULL');
CALL order_prerequisite_add_partner_column('country_code', 'CHAR(2) NOT NULL DEFAULT ''CN''');
CALL order_prerequisite_add_partner_column('province', 'VARCHAR(64) NULL');
CALL order_prerequisite_add_partner_column('city', 'VARCHAR(64) NOT NULL DEFAULT ''''');
CALL order_prerequisite_add_partner_column('district', 'VARCHAR(64) NULL');
CALL order_prerequisite_add_partner_column('address_line', 'VARCHAR(255) NOT NULL DEFAULT ''''');
CALL order_prerequisite_add_partner_column('postal_code', 'VARCHAR(20) NULL');
CALL order_prerequisite_add_partner_column('status', 'VARCHAR(20) NOT NULL DEFAULT ''ACTIVE''');
CALL order_prerequisite_add_partner_column('remark', 'VARCHAR(500) NULL');
CALL order_prerequisite_add_partner_column('created_by', 'BIGINT UNSIGNED NULL');
CALL order_prerequisite_add_partner_column('created_at', 'DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3)');
CALL order_prerequisite_add_partner_column('updated_by', 'BIGINT UNSIGNED NULL');
CALL order_prerequisite_add_partner_column('updated_at', 'DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3)');
CALL order_prerequisite_add_partner_column('deleted', 'TINYINT(1) NOT NULL DEFAULT 0');
CALL order_prerequisite_add_partner_column('version', 'INT NOT NULL DEFAULT 0');
DROP PROCEDURE IF EXISTS order_prerequisite_add_partner_column;
UPDATE wh_partner SET data_scope_id = tenant_id WHERE data_scope_id = 0;
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='往来单位业务类型';
-- 将既有有效往来单位的兼容单值类型回填到类型关联表。
INSERT IGNORE INTO wh_partner_type(partner_id, tenant_id, data_scope_id, partner_type)
SELECT id, tenant_id, data_scope_id, partner_type
FROM wh_partner
WHERE deleted = 0 AND partner_type <> 'BOTH';
INSERT IGNORE INTO wh_partner_type(partner_id, tenant_id, data_scope_id, partner_type)
SELECT id, tenant_id, data_scope_id, 'CUSTOMER'
FROM wh_partner
WHERE deleted = 0 AND partner_type = 'BOTH';
INSERT IGNORE INTO wh_partner_type(partner_id, tenant_id, data_scope_id, partner_type)
SELECT id, tenant_id, data_scope_id, 'SUPPLIER'
FROM wh_partner
WHERE deleted = 0 AND partner_type = 'BOTH';
-- 一期演示商户的既有客户同时作为发货单位,供头程订单 customerId=191000000000000001 使用。
INSERT IGNORE INTO wh_partner_type(partner_id, tenant_id, data_scope_id, partner_type)
SELECT id, tenant_id, data_scope_id, 'SHIPPER'
FROM wh_partner
WHERE id = 191000000000000001 AND tenant_id = 10001 AND status = 'ACTIVE' AND deleted = 0;
-- 3. Order:草稿创建、货物快照和 Idempotency-Key 持久化。
USE baiyue_order;
DROP PROCEDURE IF EXISTS order_prerequisite_add_order_column;
DELIMITER $$
CREATE PROCEDURE order_prerequisite_add_order_column(
IN p_table VARCHAR(64),
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 = p_table AND column_name = p_column
) THEN
SET @sql = CONCAT('ALTER TABLE `', p_table, '` ADD COLUMN `', p_column, '` ', p_definition);
PREPARE add_column_stmt FROM @sql;
EXECUTE add_column_stmt;
DEALLOCATE PREPARE add_column_stmt;
END IF;
END$$
DELIMITER ;
CALL order_prerequisite_add_order_column('ord_order', 'pickup_method', 'VARCHAR(24) NULL');
CALL order_prerequisite_add_order_column('ord_order', 'receiving_warehouse_id', 'BIGINT UNSIGNED NULL');
CALL order_prerequisite_add_order_column('ord_order', 'receiving_warehouse_name', 'VARCHAR(128) NULL');
CALL order_prerequisite_add_order_column('ord_order', 'receiving_warehouse_address', 'VARCHAR(600) NULL');
CALL order_prerequisite_add_order_column('ord_order', 'receiving_time', 'VARCHAR(128) NULL');
CALL order_prerequisite_add_order_column('ord_order', 'channel_code', 'VARCHAR(64) NULL');
CALL order_prerequisite_add_order_column('ord_order', 'channel_name', 'VARCHAR(128) NULL');
CALL order_prerequisite_add_order_column('ord_order', 'tax_mode', 'VARCHAR(24) NULL');
CALL order_prerequisite_add_order_column('ord_order', 'container_mode', 'VARCHAR(24) NULL');
CALL order_prerequisite_add_order_column('ord_order', 'customs_inspection', 'TINYINT(1) NULL');
CALL order_prerequisite_add_order_column('ord_order', 'destination_type', 'VARCHAR(24) NULL');
CALL order_prerequisite_add_order_column('ord_order', 'amazon_warehouse_code', 'VARCHAR(32) NULL');
CALL order_prerequisite_add_order_column('ord_order', 'shipment_id', 'VARCHAR(64) NULL');
CALL order_prerequisite_add_order_column('ord_order', 'reference_id', 'VARCHAR(64) NULL');
CALL order_prerequisite_add_order_column('ord_order', 'express_company', 'VARCHAR(64) NULL');
CALL order_prerequisite_add_order_column('ord_order', 'express_tracking_no', 'VARCHAR(128) NULL');
CALL order_prerequisite_add_order_column('ord_order_cargo', 'sku_no', 'VARCHAR(64) NULL');
CALL order_prerequisite_add_order_column('ord_order_cargo', 'upc_no', 'VARCHAR(64) NULL');
CALL order_prerequisite_add_order_column('ord_order_cargo', 'cargo_name_en', 'VARCHAR(128) NULL');
CALL order_prerequisite_add_order_column('ord_order_cargo', 'customs_hs_code', 'VARCHAR(20) NULL');
CALL order_prerequisite_add_order_column('ord_order_cargo', 'units_per_package', 'INT UNSIGNED NULL');
CALL order_prerequisite_add_order_column('ord_order_cargo', 'total_quantity', 'INT UNSIGNED NULL');
CALL order_prerequisite_add_order_column('ord_order_cargo', 'net_weight_kg', 'DECIMAL(18,3) NULL');
CALL order_prerequisite_add_order_column('ord_order_cargo', 'unit_declared_value', 'DECIMAL(18,2) NULL');
CALL order_prerequisite_add_order_column('ord_order_cargo', 'material', 'VARCHAR(128) NULL');
CALL order_prerequisite_add_order_column('ord_order_cargo', 'product_usage', 'VARCHAR(128) NULL');
CALL order_prerequisite_add_order_column('ord_order_cargo', 'model', 'VARCHAR(64) NULL');
CALL order_prerequisite_add_order_column('ord_order_cargo', 'brand', 'VARCHAR(64) NULL');
DROP PROCEDURE IF EXISTS order_prerequisite_add_order_column;
CREATE TABLE IF NOT EXISTS ord_idempotency_record (
id BIGINT UNSIGNED NOT NULL,
tenant_id BIGINT UNSIGNED NOT NULL,
operator_id BIGINT UNSIGNED NOT NULL,
operation VARCHAR(32) NOT NULL,
resource_id BIGINT UNSIGNED NOT NULL DEFAULT 0,
idempotency_key VARCHAR(128) NOT NULL,
request_hash CHAR(64) NOT NULL,
status VARCHAR(16) NOT NULL,
result_order_id BIGINT UNSIGNED NULL,
completed_at DATETIME(3) NULL,
created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
updated_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3),
PRIMARY KEY (id),
UNIQUE KEY uk_order_idempotency_scope (tenant_id, operator_id, operation, idempotency_key),
KEY idx_order_idempotency_created (created_at)
) ENGINE=InnoDB COMMENT='订单幂等记录';