This commit is contained in:
2026-10-26 17:27:32 +08:00
parent 5b53be23e8
commit 2927fbee06
22 changed files with 512 additions and 38 deletions
@@ -11,7 +11,14 @@
两份文件虽然名称包含“增量”,仍只用于对应区域的空库初始化。新增列、索引和约束直接维护在最终 `CREATE TABLE` 中,菜单及授权使用初始化种子;不追加存量改造、权限版本回填或动态迁移段。目标 schema 必须为空,按文件原有初始化流程执行;不能向已有业务库重放。
本次不再提供这项功能的独立升级脚本。已有库升级必须按实际结构和明确授权另行准备、审阅受控增量,不能把删除重复文件理解为已有库已完成升级。
已有库只按实际缺项执行定向结构补齐,不能把删除重复文件理解为已有库已完成升级。指定 TEST 的最小执行集合如下;文件准备不代表获得执行授权或已部署。
| 顺序 | 文件 | 允许的变更与核对结果 |
|---|---|---|
| 1 | [表与审核人字段补齐](overseas-fees-storage-rent-structure-add.sql) | 只补 `ll_storage_rent_inbound`、`ll_finance_fee_source.reviewer_name`;已存在且匹配时跳过,同名异构则停止;成功回查表结构、字段并输出 `TABLE_COLUMN_READY` |
| 2 | [免费仓租定向修复](overseas-storage-rent-zero-fee-repair.sql) | 仅自动应收仓租允许原币/结算双零与空汇率;保留其他费用正额及有效汇率约束,保留已有汇率精度与数值默认值;最终核对 `SHOW CREATE TABLE` 中金额、汇率两项 CHECK 和汇率可空性 |
两步均固定 `baiyue_lastleg`,使用独立连接、支持 `DELIMITER` 的客户端,禁止遇错继续;不执行业务 DML、不补历史计租记录、不变更余额、汇率配置或权限。DDL 隐式提交,不能宣称整体可回滚;失败保留错误并只读复查,已完成项不删除重建。两步是已核缺项的补齐方案,不是任意版本升级工具;重新执行前仍需核对目标实例与结构。
## 海外表和字段
+2
View File
@@ -1,5 +1,7 @@
# 单测试环境数据库空库初始化
`overseas-fees-storage-rent-structure-add.sql` 为指定 TEST 海外费用/仓租的定向结构补齐,只增加缺失的 `ll_storage_rent_inbound` 和 `ll_finance_fee_source.reviewer_name`。全部前置检查在首个业务 DDL 前完成;已有结构匹配时跳过,不匹配则停止,不覆盖或回填。随后按单独授权执行已有 `overseas-storage-rent-zero-fee-repair.sql`,补齐自动免费仓租的金额与汇率约束。使用独立连接、遇错停止,不重放空库初始化;DDL 隐式提交,失败先回查,不删除已完成项。两步范围与发布清单见[海外费用数据库定义汇总](20261022-海外费用仓租数据库变更汇总.md)及[发布配套](../../lastleg-service/docs/overseas-fees-storage-rent-release.md#发布配套)。文件准备不代表已执行或部署。
放舱后预计到港窄维护需要配套更新 `trg_ocean_booking_before_update`:仅从冻结比较中移除 `estimated_arrival_at`,其余运输、预报、关系方及柜型冻结不变。定义已同步 `firstleg/src/main/resources/db/phase3-ocean-booking-schema.sql` 与国内统一基线;已有 TEST 需另行审阅并授权替换该触发器,不重放空库文件,不回填数据。本轮只准备定义,未执行 SQL 或部署。
货柜关联已放舱订舱时不再限制 ISO 柜号格式,Firstleg 模块基线与国内统一空库基线已移除 `chk_container_booking_iso6346`,保留同订舱柜号唯一键。既有 TEST 发布前需核对并单独授权移除该约束:`ALTER TABLE baiyue_firstleg.fl_container_booking DROP CHECK chk_container_booking_iso6346;`。配套发布 Firstleg 与 Admin;不重放空库初始化、不修改业务数据。本次仅准备源码与 SQL 定义,未执行环境 SQL 或部署。
@@ -0,0 +1,97 @@
-- 指定 TEST 的海外费用/仓租结构补齐;实例必须由执行者另行核对并获准。
-- 仅新增 ll_storage_rent_inbound 和 ll_finance_fee_source.reviewer_name。
-- 使用独立连接,支持 DELIMITER,遇错停止;禁止 mysql --force。
-- 不更新费用、库存、钱包或历史计租数据,不重放空库初始化。
-- DDL 隐式提交;失败先回查结构,禁止删除已建表/字段来重跑。
USE baiyue_lastleg;
-- 仅清理本脚本可能遗留的专用校验过程,不删除业务对象。
DROP PROCEDURE IF EXISTS overseas_fee_rent_structure_add_20261026;
DELIMITER $$
CREATE PROCEDURE overseas_fee_rent_structure_add_20261026()
BEGIN
DECLARE inbound_exists INT DEFAULT 0;
DECLARE reviewer_exists INT DEFAULT 0;
IF DATABASE()<>'baiyue_lastleg' THEN
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT='目标必须为 baiyue_lastleg';
END IF;
-- 在首个业务 DDL 前核对两张依赖表及新增字段的定位列。
IF (SELECT COUNT(*) FROM information_schema.TABLES
WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME IN ('ll_finance_fee_source','ll_storage_rent_lot')
AND TABLE_TYPE='BASE TABLE' AND ENGINE='InnoDB')<>2
OR (SELECT COUNT(*) FROM information_schema.COLUMNS
WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME='ll_finance_fee_source'
AND COLUMN_NAME='reviewer_id' AND DATA_TYPE='varchar' AND CHARACTER_MAXIMUM_LENGTH=128)<>1 THEN
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT='费用来源或计租批次基础结构不匹配,停止补齐';
END IF;
SELECT COUNT(*) INTO reviewer_exists FROM information_schema.COLUMNS
WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME='ll_finance_fee_source' AND COLUMN_NAME='reviewer_name';
IF reviewer_exists>0 AND (SELECT COUNT(*) FROM information_schema.COLUMNS
WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME='ll_finance_fee_source' AND COLUMN_NAME='reviewer_name'
AND DATA_TYPE='varchar' AND CHARACTER_MAXIMUM_LENGTH=255 AND IS_NULLABLE='YES'
AND COLUMN_DEFAULT IS NULL AND EXTRA='')<>1 THEN
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT='已存在的审核人名称字段与正式定义不同,停止且不覆盖';
END IF;
SELECT COUNT(*) INTO inbound_exists FROM information_schema.TABLES
WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME='ll_storage_rent_inbound';
-- 已存在的同名表必须完整匹配;不以 IF NOT EXISTS 掩盖半成品或异构表。
IF inbound_exists>0 THEN
IF (SELECT COUNT(*) FROM information_schema.TABLES
WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME='ll_storage_rent_inbound'
AND TABLE_TYPE='BASE TABLE' AND ENGINE='InnoDB' AND TABLE_COLLATION='utf8mb4_unicode_ci')<>1
OR (SELECT COUNT(*) FROM information_schema.COLUMNS
WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME='ll_storage_rent_inbound')<>4
OR (SELECT COUNT(*) FROM information_schema.COLUMNS
WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME='ll_storage_rent_inbound'
AND IS_NULLABLE='NO' AND COLUMN_DEFAULT IS NULL AND EXTRA=''
AND ((COLUMN_NAME IN ('receipt_id','lot_id') AND COLUMN_TYPE='bigint')
OR (COLUMN_NAME='quantity' AND COLUMN_TYPE='decimal(24,12)')
OR (COLUMN_NAME='created_at' AND COLUMN_TYPE='datetime(3)')))<>4 THEN
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT='已存在的计租实收表字段与正式定义不同,停止且不覆盖';
END IF;
IF (SELECT COUNT(*) FROM information_schema.STATISTICS
WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME='ll_storage_rent_inbound' AND INDEX_NAME='PRIMARY')<>1
OR (SELECT COUNT(*) FROM information_schema.STATISTICS
WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME='ll_storage_rent_inbound' AND INDEX_NAME='PRIMARY'
AND COLUMN_NAME='receipt_id' AND SEQ_IN_INDEX=1 AND NON_UNIQUE=0 AND SUB_PART IS NULL)<>1
OR (SELECT COUNT(*) FROM information_schema.STATISTICS
WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME='ll_storage_rent_inbound'
AND INDEX_NAME='idx_storage_rent_inbound_lot')<>1
OR (SELECT COUNT(*) FROM information_schema.STATISTICS
WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME='ll_storage_rent_inbound'
AND INDEX_NAME='idx_storage_rent_inbound_lot' AND COLUMN_NAME='lot_id'
AND SEQ_IN_INDEX=1 AND NON_UNIQUE=1 AND SUB_PART IS NULL)<>1 THEN
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT='计租实收表主键或批次索引不匹配,停止且不覆盖';
END IF;
END IF;
-- 全部前置检查通过后才补缺项;重跑时保持已存在的业务结构和数据。
IF reviewer_exists=0 THEN
ALTER TABLE ll_finance_fee_source
ADD COLUMN reviewer_name VARCHAR(255) NULL COMMENT '审核人名称快照' AFTER reviewer_id;
END IF;
IF inbound_exists=0 THEN
CREATE TABLE ll_storage_rent_inbound (
receipt_id bigint NOT NULL COMMENT '实际入库凭证主键,防止重复累计计租数量',
lot_id bigint NOT NULL COMMENT '头程同单同仓计租批次主键',
quantity decimal(24,12) NOT NULL COMMENT '本次实收追加计租箱数',
created_at datetime(3) NOT NULL COMMENT '计租登记时间,采用协调世界时',
PRIMARY KEY (receipt_id),
KEY idx_storage_rent_inbound_lot (lot_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='头程实收计租幂等登记';
END IF;
END$$
DELIMITER ;
CALL overseas_fee_rent_structure_add_20261026();
DROP PROCEDURE overseas_fee_rent_structure_add_20261026;
SHOW CREATE TABLE ll_storage_rent_inbound;
SELECT COLUMN_NAME,COLUMN_TYPE,IS_NULLABLE,COLUMN_DEFAULT
FROM information_schema.COLUMNS
WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME='ll_finance_fee_source' AND COLUMN_NAME='reviewer_name';
SELECT 'TABLE_COLUMN_READY' AS structure_status;
-- TABLE_COLUMN_READY 只表示上述表/字段补齐;免费仓租另执行已审阅的
-- overseas-storage-rent-zero-fee-repair.sql,不能据此宣称完整功能上线。
@@ -1,4 +1,4 @@
-- 固定目标本机 baiyue_lastleg,只修复自动免费仓租结构,不更新业务数据。
-- 固定目标经单独授权的 TEST 或本机开发 baiyue_lastleg,只修复自动免费仓租结构,不更新业务数据。
-- 使用独立连接、遇错停止;先核对既有表结构,不能重放空库初始化。
USE baiyue_lastleg;
SELECT COLUMN_NAME,COLUMN_TYPE,IS_NULLABLE FROM information_schema.COLUMNS