背景(业务方推翻上一轮约束)
----
上一轮按「一张单同时只能有一个持有人」实现了**整单转交**,并把「单内出现多个
持有人」当作 bug 去修。业务方验收后明确纠正:
物理现场经常只转交部分工具(借了 2 件、只把 1 件转给别人),
单内多持有人才是符合现实的正常状态。
故转交粒度从 borrow_no 下沉回 trans_borrow.id(明细行)。
改动
----
· transfer_borrow:只操作传入的那**一行**明细,不再按单号整批覆盖。
转出方 = 该行当前持有人;数量 = 该行待还量。
· accept_transfer:只转移 transfer.borrow_id 指向的那一行 ——
整批改写会把别人手上的东西一并抢过来(部分转交下同单明细分属不同人)。
· 唯一性约束从「单号至多一条 PENDING」下沉为「明细行至多一条」:
同单的其他明细可以同时各自挂着待接收,互不阻塞 —— 这正是部分转交的语义。
· get_records 的 pending_transfer 改按 borrow_id 关联(原按 borrow_no),
否则同单多项待接收会互相覆盖。
· 删除已无用的 _load_slip_for_update。
★ 数量粒度:一行只支持**整行转交**。一行只能有一个 current_holder_id,
「同一行只转一部分」需要把这行拆成两行 —— 经业务确认,现场场景中
「借 2 件转 1 件」的两件本就是两条明细行,故该限制不影响实际使用;
接口对传入的非整行数量会明确提示「应另立一条明细行」。
数据层
----
无需改表结构:borrow_id 本就是流水的关联列,borrow_no 退化为单据归属与
分组展示用。仅补 (borrow_id, status) 复合索引支撑新的查询路径。
存量撕裂数据(BOR-20260917-0001 的「测试 / 杜邢宸」)按业务方选择**保留不动**
—— 它现在不再是 bug,而是部分转交的正常形态。
验证(合成 2 明细单,21 项断言全通过)
----
· 只转工具A:工具B 完全不受影响
· 同一张单可同时挂两条待接收,互不阻塞;同一明细重复发起被拒
· accept 工具A 后:A→测试,B 仍是杜邢宸(单内两个持有人)
· 两个持有人、以及待接收人,三方各自都能在列表中看到该单
· pending_transfer 挂在正确的明细行上,is_mine 判定正确
· reject 后主表持有人不变;非整行数量被拒并提示拆行
· 全程 available_quantity 无变化,库存精确还原、零残留数据
75 lines
3.8 KiB
PL/PgSQL
75 lines
3.8 KiB
PL/PgSQL
-- =============================================================================
|
||
-- 借库转交 · 粒度下沉到明细行(部分转交)
|
||
--
|
||
-- 背景(业务方推翻上一轮约束)
|
||
-- 上一轮按「一张单同时只能有一个持有人」实现了**整单转交**,并把「单内出现
|
||
-- 多个持有人」当作 bug 去修。业务方验收后明确纠正:
|
||
-- 物理现场经常只转交部分工具(借了 2 件,只把 1 件转给别人),
|
||
-- **单内多持有人才是符合现实的正常状态**。
|
||
-- 故转交粒度从 borrow_no 下沉回 trans_borrow.id(明细行)。
|
||
--
|
||
-- ---------------------------------------------------------------------------
|
||
-- 本次改动的实质
|
||
-- 代码层:transfer_borrow / accept_transfer 只操作**一行**明细,
|
||
-- 唯一性约束从「单号最多一条 PENDING」改为「明细行最多一条 PENDING」。
|
||
-- 数据层:**无需改动任何表结构** —— borrow_id(明细行)本就是流水的主键
|
||
-- 关联列,borrow_no 继续保留作单据归属与展示分组用。
|
||
-- 仅补一个复合索引,支撑「按明细行查待接收流水」这一新查询路径。
|
||
--
|
||
-- ★ 为什么不需要新的列
|
||
-- 转交粒度既然回到明细行,覆盖范围就是 borrow_id 指向的那一行本身 ——
|
||
-- 不需要额外的「覆盖清单」来表达范围,borrow_no 退化为分组/展示用途。
|
||
--
|
||
-- ★ 存量数据不动(业务方选择)
|
||
-- BOR-20260917-0001 的「测试 / 杜邢宸」双持有人状态予以保留:
|
||
-- 它现在不再是 bug,而是「部分转交」的正常业务形态。
|
||
--
|
||
-- 幂等:带 IF NOT EXISTS,可重复执行。
|
||
-- 执行:docker exec -i inventory_db psql -U test -d inventory_system < 本文件
|
||
-- =============================================================================
|
||
|
||
BEGIN;
|
||
|
||
-- 支撑「该明细行是否已有待接收流水」的唯一性检查,以及按明细行批量取待接收
|
||
CREATE INDEX IF NOT EXISTS ix_trans_borrow_transfer_borrow_status
|
||
ON trans_borrow_transfer (borrow_id, status);
|
||
|
||
COMMENT ON COLUMN trans_borrow_transfer.borrow_no IS
|
||
'借用单号。仅用于单据归属与列表分组展示;转交的**覆盖范围**是 borrow_id 指向的单个明细行';
|
||
COMMENT ON COLUMN trans_borrow_transfer.borrow_id IS
|
||
'转交目标明细行ID(trans_borrow.id)。转交粒度 = 明细行,一行最多一条待接收流水';
|
||
|
||
COMMIT;
|
||
|
||
|
||
-- =============================================================================
|
||
-- 执行后核对
|
||
-- =============================================================================
|
||
\echo '--- 1) 复合索引已就位 ---'
|
||
SELECT indexname FROM pg_indexes
|
||
WHERE tablename = 'trans_borrow_transfer'
|
||
AND indexname = 'ix_trans_borrow_transfer_borrow_status';
|
||
|
||
\echo '--- 2) 存量流水(borrow_id / borrow_no / status)---'
|
||
SELECT id, borrow_id, borrow_no, status, from_user_name, to_user_name
|
||
FROM trans_borrow_transfer ORDER BY id;
|
||
|
||
\echo '--- 3) 各明细行的待接收流水数(应全部 <= 1)---'
|
||
SELECT borrow_id, count(*) AS 待接收数
|
||
FROM trans_borrow_transfer WHERE status = 'PENDING'
|
||
GROUP BY borrow_id HAVING count(*) > 1;
|
||
|
||
\echo '--- 4) 单内多持有人的单号(现在属正常业务形态,不再视为异常)---'
|
||
SELECT borrow_no, count(DISTINCT current_holder_id) AS 持有人数,
|
||
string_agg(DISTINCT coalesce(current_holder_name,'NULL'), ', ') AS 持有人
|
||
FROM trans_borrow WHERE is_returned = FALSE
|
||
GROUP BY borrow_no HAVING count(DISTINCT current_holder_id) > 1;
|
||
|
||
|
||
-- =============================================================================
|
||
-- 回滚段
|
||
-- =============================================================================
|
||
-- BEGIN;
|
||
-- DROP INDEX IF EXISTS ix_trans_borrow_transfer_borrow_status;
|
||
-- COMMIT;
|