diff --git a/apps/backend/src/db/migrations/109_work_order_material_link.sql b/apps/backend/src/db/migrations/109_work_order_material_link.sql new file mode 100644 index 00000000..1b592839 --- /dev/null +++ b/apps/backend/src/db/migrations/109_work_order_material_link.sql @@ -0,0 +1,54 @@ +-- 109_work_order_material_link.sql +-- 接单工单「一次性补资料链接」。 +-- +-- 背景:客服在接单平台给待完善/未分配的工单生成一条客户可访问的链接, +-- 客户无需登录即可补充资料字段与买家主页截图;成功提交一次后链接立即失效, +-- 工单转为「未分配」,需要修改时必须由客服重新生成链接。 +-- +-- 独立于 claim_tokens:claim_tokens 强绑定 fulfillment_tasks, +-- 而这里绑定 work_orders,生命周期与补资料动作一致。 + +CREATE TABLE IF NOT EXISTS work_order_material_links ( + id BIGSERIAL PRIMARY KEY, + work_order_id BIGINT NOT NULL REFERENCES work_orders(id) ON DELETE CASCADE, + token TEXT NOT NULL UNIQUE, + status TEXT NOT NULL DEFAULT 'active', + expires_at TIMESTAMPTZ NOT NULL, + used_at TIMESTAMPTZ, + created_by TEXT NOT NULL DEFAULT '', + created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), + updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), + CONSTRAINT work_order_material_links_status_check + CHECK (status IN ('active', 'used', 'expired', 'revoked')) +); + +-- 兼容极端情况下先建表但约束未建成功的库(正常新库会走上面的内联约束)。 +DO $$ +BEGIN + IF NOT EXISTS ( + SELECT 1 + FROM pg_constraint + WHERE conname = 'work_order_material_links_status_check' + ) THEN + ALTER TABLE work_order_material_links + ADD CONSTRAINT work_order_material_links_status_check + CHECK (status IN ('active', 'used', 'expired', 'revoked')); + END IF; +END $$; + +CREATE INDEX IF NOT EXISTS idx_work_order_material_links_order + ON work_order_material_links (work_order_id, created_at DESC); + +-- 一个工单同时最多一条未使用链接;重新生成前先把旧 active 置为 revoked。 +CREATE UNIQUE INDEX IF NOT EXISTS idx_work_order_material_links_active + ON work_order_material_links (work_order_id) + WHERE status = 'active'; + +COMMENT ON TABLE work_order_material_links IS + '接单工单一次性补资料链接:客户凭 token 提交一次资料后失效'; +COMMENT ON COLUMN work_order_material_links.token IS + 'URL 安全随机 token;只在生成/复制链接时返回给后台'; +COMMENT ON COLUMN work_order_material_links.status IS + 'active 可用 / used 已提交 / expired 已过期 / revoked 已撤销'; +COMMENT ON COLUMN work_order_material_links.created_by IS + '生成链接的后台操作人展示名,用于审计'; diff --git a/apps/backend/src/db/migrations/109_after_sales_withdraw_deduction.sql b/apps/backend/src/db/migrations/112_after_sales_withdraw_deduction.sql similarity index 96% rename from apps/backend/src/db/migrations/109_after_sales_withdraw_deduction.sql rename to apps/backend/src/db/migrations/112_after_sales_withdraw_deduction.sql index 0f78100b..e3707ac9 100644 --- a/apps/backend/src/db/migrations/109_after_sales_withdraw_deduction.sql +++ b/apps/backend/src/db/migrations/112_after_sales_withdraw_deduction.sql @@ -1,4 +1,4 @@ --- 109_after_sales_withdraw_deduction.sql +-- 112_after_sales_withdraw_deduction.sql -- -- 售后追缴要能把「提现冻结中」的钱一并扣掉。 --