-- ============================================================================= -- 借库转交 · 双向握手 + 整单覆盖 -- -- 本次解决两个已发生的问题: -- 1) **单内撕裂**:原 /transfer 收的是**明细行 ID**,只更新那一行。 -- 一张单有 2 条明细时,转交后 108 归属接收人、109 仍是原借用人 —— -- 前端按 borrow_no 聚合,两个名字同时出现(实测 BOR-20260917-0001)。 -- 修复方向:转交必须按 **borrow_no** 覆盖该单全部未还明细。 -- 2) **单向强塞**:原实现发起即生效,接收人「被通知式」地背上资产责任。 -- 改为双向握手:发起只落 PENDING,接收人 accept 后才真正转移责任。 -- -- --------------------------------------------------------------------------- -- 1) 为什么新增 borrow_no 而不是复用 borrow_id -- borrow_id 是**明细行**主键,一条转交要覆盖该单多行,用单行 ID 无法表达 -- 「本次转交覆盖了哪些行」。borrow_no 是单据身份,accept 时据此批量更新。 -- borrow_id 保留为「发起时的代表明细」,供追溯与旧前端兼容。 -- -- 2) 为什么存量行标记为 ACCEPTED -- 旧语义是「发起即生效」—— 写流水的同时就改了主表 current_holder。 -- 本表现有 1 行(BOR-20260917-0001)已是生效状态,标为 ACCEPTED 才符合 -- 事实;若标 PENDING,接收人会收到一条早已生效的待办。 -- -- 3) 状态机 -- PENDING ──accept──> ACCEPTED (主表 current_holder 正式转移) -- └────reject──> REJECTED (主表不动,责任仍在原持有人) -- 同一单号同一时刻只允许一条 PENDING(应用层强制),避免两个接收人 -- 争抢同一批实物。 -- -- 幂等:带 IF NOT EXISTS,可重复执行。 -- 执行:docker exec -i inventory_db psql -U test -d inventory_system < 本文件 -- ============================================================================= BEGIN; ALTER TABLE trans_borrow_transfer ADD COLUMN IF NOT EXISTS borrow_no varchar(100), ADD COLUMN IF NOT EXISTS status varchar(20) NOT NULL DEFAULT 'PENDING'; COMMENT ON COLUMN trans_borrow_transfer.borrow_no IS '借用单号(单据身份)。一次转交覆盖该单号下全部未还明细,accept 时据此批量更新'; COMMENT ON COLUMN trans_borrow_transfer.status IS 'PENDING 待接收 / ACCEPTED 已接收(主表已转移)/ REJECTED 已拒绝(主表未动)'; COMMENT ON COLUMN trans_borrow_transfer.borrow_id IS '发起转交时的代表明细ID(trans_borrow.id),仅供追溯;覆盖范围以 borrow_no 为准'; -- 存量行:按旧语义(发起即生效)回填单号并标记为已接收 UPDATE trans_borrow_transfer t SET borrow_no = tb.borrow_no, status = 'ACCEPTED' FROM trans_borrow tb WHERE t.borrow_id = tb.id AND t.status = 'PENDING'; CREATE INDEX IF NOT EXISTS ix_trans_borrow_transfer_no ON trans_borrow_transfer (borrow_no); CREATE INDEX IF NOT EXISTS ix_trans_borrow_transfer_status ON trans_borrow_transfer (status); -- 支撑「待我接收」的可见性与列表查询 CREATE INDEX IF NOT EXISTS ix_trans_borrow_transfer_to_user ON trans_borrow_transfer (to_user_id, status); COMMIT; -- ============================================================================= -- 执行后核对 -- ============================================================================= \echo '--- 1) 新列已就位 ---' SELECT column_name, data_type, column_default FROM information_schema.columns WHERE table_name = 'trans_borrow_transfer' AND column_name IN ('borrow_no', 'status') ORDER BY column_name; \echo '--- 2) 存量行状态(应为 ACCEPTED 且 borrow_no 已回填)---' SELECT id, borrow_id, borrow_no, status, from_user_name, to_user_name FROM trans_borrow_transfer ORDER BY id; \echo '--- 3) 不应存在无单号的流水(应为 0)---' SELECT count(*) AS 缺单号 FROM trans_borrow_transfer WHERE borrow_no IS NULL; -- ============================================================================= -- 回滚段 -- ============================================================================= -- BEGIN; -- DROP INDEX IF EXISTS ix_trans_borrow_transfer_no; -- DROP INDEX IF EXISTS ix_trans_borrow_transfer_status; -- DROP INDEX IF EXISTS ix_trans_borrow_transfer_to_user; -- ALTER TABLE trans_borrow_transfer -- DROP COLUMN IF EXISTS borrow_no, -- DROP COLUMN IF EXISTS status; -- COMMIT;