feat(order-service): 重构分类资料收集与订单状态链路
This commit is contained in:
@@ -0,0 +1,74 @@
|
||||
-- 128_order_service_profiles.sql
|
||||
--
|
||||
-- 分类级订单服务配置:资料收集字段、引导图、截图规则与自动发布策略。
|
||||
-- 工单创建时固化配置快照,后续修改配置不影响已创建工单。
|
||||
|
||||
ALTER TABLE work_categories
|
||||
ADD COLUMN IF NOT EXISTS default_work_rule_id BIGINT REFERENCES work_product_rules(id) ON DELETE SET NULL;
|
||||
|
||||
COMMENT ON COLUMN work_categories.default_work_rule_id IS
|
||||
'分类默认接单模板;商品级映射可覆盖,未命中时整个分类使用该模板';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS order_service_profiles (
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
category_id BIGINT NOT NULL REFERENCES work_categories(id) ON DELETE CASCADE,
|
||||
name TEXT NOT NULL,
|
||||
title TEXT NOT NULL DEFAULT '',
|
||||
description TEXT NOT NULL DEFAULT '',
|
||||
guide_image_json JSONB NOT NULL DEFAULT '{}'::jsonb,
|
||||
fields_json JSONB NOT NULL DEFAULT '[]'::jsonb,
|
||||
screenshots_json JSONB NOT NULL DEFAULT '{}'::jsonb,
|
||||
auto_publish_json JSONB NOT NULL DEFAULT '{"enabled":false}'::jsonb,
|
||||
submit_text TEXT NOT NULL DEFAULT '提交资料',
|
||||
success_text TEXT NOT NULL DEFAULT '资料已提交,请等待处理',
|
||||
status TEXT NOT NULL DEFAULT 'draft',
|
||||
current_version_id BIGINT,
|
||||
created_by_admin_user_id BIGINT REFERENCES admin_users(id) ON DELETE SET NULL,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
CONSTRAINT order_service_profiles_status_check
|
||||
CHECK (status IN ('draft', 'published', 'archived'))
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS uq_order_service_profiles_category
|
||||
ON order_service_profiles (category_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_order_service_profiles_status
|
||||
ON order_service_profiles (status);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS order_service_profile_versions (
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
profile_id BIGINT NOT NULL REFERENCES order_service_profiles(id) ON DELETE CASCADE,
|
||||
version_no INTEGER NOT NULL,
|
||||
config_json JSONB NOT NULL DEFAULT '{}'::jsonb,
|
||||
published_by_admin_user_id BIGINT REFERENCES admin_users(id) ON DELETE SET NULL,
|
||||
published_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
CONSTRAINT uq_order_service_profile_versions_no
|
||||
UNIQUE (profile_id, version_no)
|
||||
);
|
||||
|
||||
DO $$
|
||||
BEGIN
|
||||
IF NOT EXISTS (
|
||||
SELECT 1 FROM pg_constraint WHERE conname = 'fk_order_service_profiles_current_version'
|
||||
) THEN
|
||||
ALTER TABLE order_service_profiles
|
||||
ADD CONSTRAINT fk_order_service_profiles_current_version
|
||||
FOREIGN KEY (current_version_id)
|
||||
REFERENCES order_service_profile_versions(id) ON DELETE SET NULL;
|
||||
END IF;
|
||||
END $$;
|
||||
|
||||
ALTER TABLE work_orders
|
||||
ADD COLUMN IF NOT EXISTS service_profile_id BIGINT REFERENCES order_service_profiles(id) ON DELETE SET NULL,
|
||||
ADD COLUMN IF NOT EXISTS service_profile_version_id BIGINT REFERENCES order_service_profile_versions(id) ON DELETE SET NULL,
|
||||
ADD COLUMN IF NOT EXISTS service_profile_snapshot_json JSONB;
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_work_orders_service_profile
|
||||
ON work_orders (service_profile_id, service_profile_version_id)
|
||||
WHERE service_profile_id IS NOT NULL;
|
||||
|
||||
COMMENT ON TABLE order_service_profiles IS
|
||||
'分类级订单服务配置:资料字段、引导图、截图规则与自动发布策略';
|
||||
COMMENT ON COLUMN work_orders.service_profile_snapshot_json IS
|
||||
'工单创建时固化的订单服务配置快照;配置后续变更不影响该工单';
|
||||
@@ -0,0 +1,29 @@
|
||||
-- 129_order_service_auto_publish_jobs.sql
|
||||
--
|
||||
-- 资料提交后自动发布工单。任务先落库,外部电子凭证核销失败时可以重试。
|
||||
|
||||
CREATE TABLE IF NOT EXISTS order_service_auto_publish_jobs (
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
work_order_id BIGINT NOT NULL REFERENCES work_orders(id) ON DELETE CASCADE,
|
||||
status TEXT NOT NULL DEFAULT 'pending',
|
||||
attempt_count INTEGER NOT NULL DEFAULT 0,
|
||||
max_attempts INTEGER NOT NULL DEFAULT 3,
|
||||
next_run_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
last_error TEXT NOT NULL DEFAULT '',
|
||||
result_json JSONB NOT NULL DEFAULT '{}'::jsonb,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
CONSTRAINT order_service_auto_publish_jobs_status_check
|
||||
CHECK (status IN ('pending', 'succeeded', 'failed', 'skipped'))
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS uq_order_service_auto_publish_pending
|
||||
ON order_service_auto_publish_jobs (work_order_id)
|
||||
WHERE status = 'pending';
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_order_service_auto_publish_due
|
||||
ON order_service_auto_publish_jobs (next_run_at)
|
||||
WHERE status = 'pending';
|
||||
|
||||
COMMENT ON TABLE order_service_auto_publish_jobs IS
|
||||
'客户资料提交后的自动发布任务;核销失败可按配置重试';
|
||||
@@ -0,0 +1,35 @@
|
||||
-- 130_customer_notifications.sql
|
||||
--
|
||||
-- 客户订单通知事件模型。首版只落事件,不发送短信;
|
||||
-- 后续接入 SMS Provider 时消费 pending 任务即可。
|
||||
|
||||
CREATE TABLE IF NOT EXISTS customer_order_notifications (
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
order_id BIGINT REFERENCES orders(id) ON DELETE CASCADE,
|
||||
order_item_id BIGINT REFERENCES order_items(id) ON DELETE SET NULL,
|
||||
work_order_id BIGINT REFERENCES work_orders(id) ON DELETE CASCADE,
|
||||
event_type TEXT NOT NULL,
|
||||
channel TEXT NOT NULL DEFAULT 'sms',
|
||||
status TEXT NOT NULL DEFAULT 'skipped',
|
||||
phone TEXT NOT NULL DEFAULT '',
|
||||
template_key TEXT NOT NULL DEFAULT '',
|
||||
payload_json JSONB NOT NULL DEFAULT '{}'::jsonb,
|
||||
dedupe_key TEXT NOT NULL,
|
||||
attempt_count INTEGER NOT NULL DEFAULT 0,
|
||||
last_error TEXT NOT NULL DEFAULT '',
|
||||
sent_at TIMESTAMPTZ,
|
||||
next_run_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
CONSTRAINT customer_order_notifications_channel_check
|
||||
CHECK (channel IN ('web', 'sms')),
|
||||
CONSTRAINT customer_order_notifications_status_check
|
||||
CHECK (status IN ('pending', 'sent', 'failed', 'skipped'))
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS uq_customer_order_notifications_dedupe
|
||||
ON customer_order_notifications (dedupe_key);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_customer_order_notifications_pending
|
||||
ON customer_order_notifications (next_run_at)
|
||||
WHERE status = 'pending';
|
||||
@@ -0,0 +1,34 @@
|
||||
-- 131_order_service_hardening.sql
|
||||
--
|
||||
-- 订单服务配置以“分类 -> 当前发布版本”为线上唯一读取源。
|
||||
-- 分类与接单模板的绑定沿用 work_product_rules.category_id,不再维护反向默认模板。
|
||||
|
||||
ALTER TABLE work_categories
|
||||
DROP COLUMN IF EXISTS default_work_rule_id;
|
||||
|
||||
ALTER TABLE order_service_auto_publish_jobs
|
||||
ADD COLUMN IF NOT EXISTS locked_until TIMESTAMPTZ,
|
||||
ADD COLUMN IF NOT EXISTS locked_by TEXT NOT NULL DEFAULT '',
|
||||
ADD COLUMN IF NOT EXISTS finished_at TIMESTAMPTZ;
|
||||
|
||||
ALTER TABLE order_service_auto_publish_jobs
|
||||
DROP CONSTRAINT IF EXISTS order_service_auto_publish_jobs_status_check;
|
||||
|
||||
ALTER TABLE order_service_auto_publish_jobs
|
||||
ADD CONSTRAINT order_service_auto_publish_jobs_status_check
|
||||
CHECK (status IN ('pending', 'processing', 'succeeded', 'failed', 'skipped'));
|
||||
|
||||
DROP INDEX IF EXISTS uq_order_service_auto_publish_pending;
|
||||
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS uq_order_service_auto_publish_active
|
||||
ON order_service_auto_publish_jobs (work_order_id)
|
||||
WHERE status IN ('pending', 'processing');
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_order_service_auto_publish_lease
|
||||
ON order_service_auto_publish_jobs (locked_until)
|
||||
WHERE status = 'processing';
|
||||
|
||||
COMMENT ON COLUMN order_service_auto_publish_jobs.locked_until IS
|
||||
'任务处理租约到期时间;进程中断后可被其它 worker 重新领取';
|
||||
COMMENT ON COLUMN order_service_auto_publish_jobs.locked_by IS
|
||||
'领取任务的进程或实例标识';
|
||||
Reference in New Issue
Block a user