add:新增同一个工单同一人可以多次拼单

This commit is contained in:
2026-10-23 15:14:07 +08:00
parent bfd2325ac5
commit 1d5615f1ae
18 changed files with 2996 additions and 128 deletions
@@ -0,0 +1,9 @@
-- 后台「接单工单 → 店铺」筛选:按订单归属店铺精确匹配(可多选)。
-- 过滤器写法是 BTRIM(o.shop_name) = ANY($n::text[]),普通 btree 无法命中表达式,
-- 所以补一个与查询同口径的表达式索引;部分索引省掉空店铺的无效条目。
CREATE INDEX IF NOT EXISTS idx_orders_shop_name_trimmed
ON orders (BTRIM(shop_name))
WHERE BTRIM(shop_name) <> '';
COMMENT ON INDEX idx_orders_shop_name_trimmed IS
'支持后台接单工单按订单店铺(orders.shop_name)精确多选筛选';
@@ -0,0 +1,64 @@
-- 104_work_order_share_multi_participation.sql
-- 目标:同一打手可对同一拼单工单多次参与,每次参与一条 work_order_shares;
-- 每份在参与时固化截止时间与超时策略;超时/验收/撤单按份额独立。
--
-- 说明:
-- 1. 只加列 + 回填 + 删「一人一条」唯一键 + 建索引,不拆分历史行、不改历史资金。
-- 2. 历史合并份额(quantity > 1)保持原样,结算公式 quantity × unit_reward 完全兼容。
-- 3. request_id 为客户端幂等键,唯一索引只约束非空值。
ALTER TABLE work_order_shares
ADD COLUMN IF NOT EXISTS deadline_at TIMESTAMPTZ,
ADD COLUMN IF NOT EXISTS timeout_minutes INTEGER NOT NULL DEFAULT 0,
ADD COLUMN IF NOT EXISTS timeout_policy TEXT NOT NULL DEFAULT '',
ADD COLUMN IF NOT EXISTS cancelled_reason TEXT NOT NULL DEFAULT '',
ADD COLUMN IF NOT EXISTS request_id TEXT NOT NULL DEFAULT '';
COMMENT ON COLUMN work_order_shares.deadline_at IS '本份额截止时间:参与时 = created_at + 母单当时 timeout_minutes;0 分钟为 NULL';
COMMENT ON COLUMN work_order_shares.timeout_minutes IS '参与时固化的时限(分钟),母单后续改配置不影响';
COMMENT ON COLUMN work_order_shares.timeout_policy IS '参与时固化的超时策略 reopen/cancel_release/cancel_deduct';
COMMENT ON COLUMN work_order_shares.cancelled_reason IS '取消来源:timeout/worker_request/admin/problem/settlement';
COMMENT ON COLUMN work_order_shares.request_id IS '客户端幂等键(一次点击一个),重复请求返回原份额';
-- 回填历史份额:按当时母单配置一次性固化
UPDATE work_order_shares s
SET timeout_minutes = COALESCE(w.timeout_minutes, 0),
timeout_policy = COALESCE(NULLIF(w.timeout_policy, ''), 'reopen'),
deadline_at = CASE
WHEN COALESCE(w.timeout_minutes, 0) > 0
THEN s.created_at + (w.timeout_minutes || ' minutes')::interval
ELSE NULL
END
FROM work_orders w
WHERE w.id = s.work_order_id
AND s.timeout_minutes = 0;
-- 删除「同一工单同一打手只能一条」约束(否则第二次参与报 23505)
DO $$
BEGIN
IF EXISTS (
SELECT 1 FROM pg_constraint
WHERE conname = 'work_order_shares_work_order_id_worker_id_key'
) THEN
ALTER TABLE work_order_shares
DROP CONSTRAINT work_order_shares_work_order_id_worker_id_key;
END IF;
END $$;
-- 到期扫描:只覆盖 joined 份额,走部分索引
CREATE INDEX IF NOT EXISTS idx_work_order_shares_due
ON work_order_shares (deadline_at)
WHERE status = 'joined';
-- 打手在某工单的份额列表(我的订单展开、押金累计求和)
CREATE INDEX IF NOT EXISTS idx_work_order_shares_worker_order
ON work_order_shares (worker_id, work_order_id, created_at DESC);
-- 母单份额集合推导(recompute 母单状态、剩余份数)
CREATE INDEX IF NOT EXISTS idx_work_order_shares_order_status
ON work_order_shares (work_order_id, status, created_at ASC);
-- 幂等键:同一打手同一个 request_id 只能产生一条份额
CREATE UNIQUE INDEX IF NOT EXISTS uq_work_order_shares_worker_request
ON work_order_shares (worker_id, request_id)
WHERE request_id <> '';