feat(oms,wms,system): OMS下单冻结库存(防超卖)——仓库级库存锁定模式

- 仓库新增stock_lock_mode开关(1-下单冻结 2-分配库存冻结默认),查询/独立切换接口+在途冻结单切换守卫
- WMS新增out_order_freeze_record冻结记录表:下单冻结/编辑原子重锁/取消解冻/分配承接/交接扣减/反审还原全状态机,条件更新防并发超卖
- OMS下单即冻结(失败阻断+落库失败补偿解冻)、已下发禁编辑、cancelIssueOrder补调WMS清理(修存量不同步)、cancelAuditState镜像还原修复
- 达梦SQL脚本3个(WAREHOUSE加列/冻结记录建表/主键列名修复),测试库已执行并全流程实测通过
This commit is contained in:
rcx
2026-09-14 15:41:32 +08:00
parent 888a293ebd
commit b1d92fdda8
31 changed files with 1587 additions and 47 deletions
@@ -0,0 +1,33 @@
-- ============================================================
-- 功能:仓库表新增"库存锁定模式"字段(OMS下单冻结库存/防超卖功能开关)
-- 数据库:达梦(DM8),兼容 Oracle 语法,表名/字段名统一大写
-- 模式:NGWL_TEST_SYSTEMmhd-system 服务对应业务库;生产环境按实际模式名替换)
-- 表名:WAREHOUSE
-- 日期:2026-09-12
-- 说明:
-- 1-下单冻结:OMS出库业务单「下单」即冻结WMS库存(可用-、冻结+,库存数量不变)
-- 2-分配库存冻结:现有模式,WMS「分配库存」时才冻结(默认值,存量仓库行为零变化)
-- 不变式:库存数量 = 可用数量 + 冻结数量(出库交接前全程成立)
-- NULL 视为 2(代码侧 isOrderFreezeWarehouse 仅 =1 才走下单冻结,兜底降级安全)
-- ============================================================
-- 0. 执行前检查(确认列是否已存在,已存在则跳过本脚本)
-- SELECT OWNER, TABLE_NAME, COLUMN_NAME, DATA_TYPE
-- FROM ALL_TAB_COLUMNS
-- WHERE OWNER = 'NGWL_TEST_SYSTEM'
-- AND TABLE_NAME = 'WAREHOUSE'
-- AND COLUMN_NAME = 'STOCK_LOCK_MODE';
-- 1. 添加字段(达梦 ADD COLUMN 不支持 AFTER,列追加在表尾;带 DEFAULT 时存量行自动填默认值)
ALTER TABLE NGWL_TEST_SYSTEM.WAREHOUSE ADD STOCK_LOCK_MODE TINYINT DEFAULT 2;
-- 2. 添加注释(达梦必须单独写)
COMMENT ON COLUMN NGWL_TEST_SYSTEM.WAREHOUSE.STOCK_LOCK_MODE IS '库存锁定模式: 1-下单冻结 2-分配库存冻结';
-- 3. 验证
-- SELECT WAREHOUSE_ID, WAREHOUSE_CODE, STOCK_LOCK_MODE FROM NGWL_TEST_SYSTEM.WAREHOUSE WHERE ROWNUM <= 10;
-- ----------------------------
-- 回滚脚本(按需,须确认无 status∈(1,2) 的在途冻结单后再执行)
-- ALTER TABLE NGWL_TEST_SYSTEM.WAREHOUSE DROP COLUMN STOCK_LOCK_MODE;
-- ----------------------------
@@ -0,0 +1,77 @@
-- ============================================================
-- 功能:WMS出库单库存冻结记录表(OMS下单冻结模式/防超卖)
-- 数据库:达梦(DM8),兼容 Oracle 语法,表名/字段名统一大写
-- 模式:NGWL_TEST_WMSmhd-wms 服务对应业务库,与 MATERIAL_INVENTORY 同库;
-- 生产环境按实际模式名替换)
-- 表名:OUT_ORDER_FREEZE_RECORD
-- 日期:2026-09-12
-- 说明:
-- 记录「业务单↔库存行↔冻结数量」占用关系与状态流转,是编辑重锁/取消解冻/
-- 分配承接/交接标记/反审还原的对账依据与单据级隔离判据。
-- 状态流转:1-业务单冻结(下单) → 2-执行单承接(WMS分配,数量不动)
-- → 3-已交接(出库交接扣减库存后终态);任一环节取消 → 4-已释放;
-- 反审(已出库) 3→1 重新激活。
-- ============================================================
-- 0. 执行前检查(确认表是否已存在,已存在则跳过本脚本)
-- SELECT OWNER, TABLE_NAME FROM ALL_TABLES
-- WHERE OWNER = 'NGWL_TEST_WMS' AND TABLE_NAME = 'OUT_ORDER_FREEZE_RECORD';
-- 1. 建表
CREATE TABLE OUT_ORDER_FREEZE_RECORD (
FREEZE_RECORD_ID BIGINT IDENTITY(1,1) NOT NULL,
BUSINESS_ORDER_NUMBER VARCHAR(50) DEFAULT NULL,
EXECUTION_ORDER_NUMBER VARCHAR(50) DEFAULT NULL,
MATERIAL_DETAIL_UNIQUE_ID VARCHAR(64) DEFAULT NULL,
MATERIAL_INVENTORY_ID BIGINT NOT NULL,
WAREHOUSE_ID BIGINT DEFAULT NULL,
MATERIAL_BASE_INFO_ID BIGINT DEFAULT NULL,
FREEZE_QUANTITY DECIMAL(24,6) NOT NULL,
FREEZE_STATUS INT DEFAULT 1 NOT NULL,
RELATE_NO VARCHAR(100) DEFAULT NULL,
REMARK VARCHAR(500) DEFAULT NULL,
CREATE_BY BIGINT DEFAULT NULL,
CREATE_BY_NAME VARCHAR(50) DEFAULT NULL,
CREATE_TIME DATETIME DEFAULT NULL,
UPDATE_BY BIGINT DEFAULT NULL,
UPDATE_BY_NAME VARCHAR(50) DEFAULT NULL,
UPDATE_TIME DATETIME DEFAULT NULL,
DEL_FLAG INT DEFAULT 1,
CONSTRAINT PK_OUT_ORDER_FREEZE_RECORD PRIMARY KEY (FREEZE_RECORD_ID)
);
-- 2. 表注释
COMMENT ON TABLE OUT_ORDER_FREEZE_RECORD IS 'WMS出库单库存冻结记录表(OMS下单冻结模式)';
-- 3. 列注释(达梦必须单独写)
COMMENT ON COLUMN OUT_ORDER_FREEZE_RECORD.FREEZE_RECORD_ID IS '编号';
COMMENT ON COLUMN OUT_ORDER_FREEZE_RECORD.BUSINESS_ORDER_NUMBER IS 'OMS出库业务单号';
COMMENT ON COLUMN OUT_ORDER_FREEZE_RECORD.EXECUTION_ORDER_NUMBER IS '执行出库单号(分配承接时回填,可空)';
COMMENT ON COLUMN OUT_ORDER_FREEZE_RECORD.MATERIAL_DETAIL_UNIQUE_ID IS '明细唯一标识(OMS明细uniqueId)';
COMMENT ON COLUMN OUT_ORDER_FREEZE_RECORD.MATERIAL_INVENTORY_ID IS '库存行ID(MATERIAL_INVENTORY.MATERIAL_INVENTORY_ID)';
COMMENT ON COLUMN OUT_ORDER_FREEZE_RECORD.WAREHOUSE_ID IS '仓库ID';
COMMENT ON COLUMN OUT_ORDER_FREEZE_RECORD.MATERIAL_BASE_INFO_ID IS '物料基础信息ID';
COMMENT ON COLUMN OUT_ORDER_FREEZE_RECORD.FREEZE_QUANTITY IS '冻结数量';
COMMENT ON COLUMN OUT_ORDER_FREEZE_RECORD.FREEZE_STATUS IS '冻结状态: 1-业务单冻结 2-执行单承接 3-已交接 4-已释放';
COMMENT ON COLUMN OUT_ORDER_FREEZE_RECORD.RELATE_NO IS '关联单号(业务单号#明细uniqueId,与库存调整记录RELATE_NO对应)';
COMMENT ON COLUMN OUT_ORDER_FREEZE_RECORD.REMARK IS '备注';
COMMENT ON COLUMN OUT_ORDER_FREEZE_RECORD.CREATE_BY IS '创建者';
COMMENT ON COLUMN OUT_ORDER_FREEZE_RECORD.CREATE_BY_NAME IS '创建者姓名';
COMMENT ON COLUMN OUT_ORDER_FREEZE_RECORD.CREATE_TIME IS '创建时间';
COMMENT ON COLUMN OUT_ORDER_FREEZE_RECORD.UPDATE_BY IS '更新者';
COMMENT ON COLUMN OUT_ORDER_FREEZE_RECORD.UPDATE_BY_NAME IS '更新人姓名';
COMMENT ON COLUMN OUT_ORDER_FREEZE_RECORD.UPDATE_TIME IS '更新时间';
COMMENT ON COLUMN OUT_ORDER_FREEZE_RECORD.DEL_FLAG IS '删除标记:0-无状态,1-正常,2-已删除';
-- 4. 索引(最热路径:按业务单号取记录[幂等/解冻/重锁/承接校验];按执行单号[解除承接/交接标记/重激活];按库存行[分配/取消分配判据])
CREATE INDEX IDX_OOFR_BIZ_ORDER ON OUT_ORDER_FREEZE_RECORD (BUSINESS_ORDER_NUMBER, DEL_FLAG);
CREATE INDEX IDX_OOFR_EXEC_ORDER ON OUT_ORDER_FREEZE_RECORD (EXECUTION_ORDER_NUMBER);
CREATE INDEX IDX_OOFR_INV_ID ON OUT_ORDER_FREEZE_RECORD (MATERIAL_INVENTORY_ID);
-- 5. 验证
-- SELECT FREEZE_STATUS, COUNT(*) FROM OUT_ORDER_FREEZE_RECORD GROUP BY FREEZE_STATUS;
-- ----------------------------
-- 回滚脚本(按需,须确认无在途冻结单[status∈(1,2)]后再执行)
-- DROP TABLE OUT_ORDER_FREEZE_RECORD;
-- ----------------------------
@@ -0,0 +1,24 @@
-- ============================================================
-- 功能:修复冻结记录表主键列名(实体字段 freezeRecordId → 列 FREEZE_RECORD_ID
-- 建表脚本误写为 ID,导致 MyBatis-Plus 查询报"无效的列名[FREEZE_RECORD_ID]"
-- 数据库:达梦(DM8)
-- 模式:NGWL_TEST_WMSmhd-wms 服务数据源;生产按实际模式名替换)
-- 表名:OUT_ORDER_FREEZE_RECORD
-- 日期:2026-09-12
-- ============================================================
-- 0. 执行前检查(确认当前列名)
-- SELECT COLUMN_NAME FROM ALL_TAB_COLUMNS
-- WHERE OWNER = 'NGWL_TEST_WMS' AND TABLE_NAME = 'OUT_ORDER_FREEZE_RECORD'
-- ORDER BY COLUMN_ID;
-- 1. 重命名主键列 ID → FREEZE_RECORD_ID(自增属性/主键约束随列保留)
ALTER TABLE NGWL_TEST_WMS.OUT_ORDER_FREEZE_RECORD RENAME COLUMN ID TO FREEZE_RECORD_ID;
-- 2. 验证(应能看到 FREEZE_RECORD_ID 且不再有 ID 列)
-- SELECT COLUMN_NAME FROM ALL_TAB_COLUMNS
-- WHERE OWNER = 'NGWL_TEST_WMS' AND TABLE_NAME = 'OUT_ORDER_FREEZE_RECORD'
-- ORDER BY COLUMN_ID;
-- SELECT FREEZE_RECORD_ID, BUSINESS_ORDER_NUMBER, FREEZE_STATUS FROM NGWL_TEST_WMS.OUT_ORDER_FREEZE_RECORD;
-- 回滚: ALTER TABLE NGWL_TEST_WMS.OUT_ORDER_FREEZE_RECORD RENAME COLUMN FREEZE_RECORD_ID TO ID;