日期:2026-10-06 | 起草:波波 | 状态:设计已定,字段已落库,C 端待接
一、需求(义父口述,四层)
商品是基础,其余全是属性:
第一层 选商品 59 款风物
第二层 选履约方式 直接买 / 到店取 / 供奉
第三层 选供奉途径 工作人员代为转达 / 工作人员带领游客亲自送
第四层 选拿回途径 工作人员代取后暂存到店拿 / 代取后邮寄 / 带领游客取
第五层 供奉时长 供奉完成 → 等待 N 天 → 才能拿回
关键结构:供奉与拿回在时间上分离。供奉完成不是终点,是进入等待期。
两条真实场景(验证模型成立)
| 场景 | 链路 |
| A. 下月才来 | 下月下单(含供奉)→ 公司提前安排 → 游客到阿里 → 作为活动一环带领取 |
| B. 游玩中下单 | 游玩中下单 → 工作人员带去供奉(途径 A 或 B)→ 时长到 → 邮寄给游客 |
| C. 线下到店扫码 | 游客在店面扫二维码 → 跳小程序 → 直接进入供奉线路选择 |
三条场景共用同一条链,只是触发时机与拿回途径不同。
二、枚举定义
第二层 履约方式 order_items.fulfillment_mode
| 值 | 含义 | 走哪条链路 |
direct | 直接买(线上销售) | 现有 goods + 线上支付 + 发货 |
pickup | 到店取 | 现有 redemption_codes 整单一码 + 商户扫 |
offering | 供奉 | 新增四层(本文档) |
第三层 供奉途径 order_items.offering_channel
| 值 | 含义 | 谁执行 |
staff_deliver | 工作人员代为转达 | 工作人员 |
staff_escort | 工作人员带领游客亲自送 | 工作人员 + 游客 |
第四层 拿回途径 order_items.retrieval_channel
| 值 | 含义 | 落点 |
staff_pickup_store | 工作人员代取后暂存,游客到店拿 | 门店/前台 |
mail | 工作人员代取后邮寄给游客 | 收货地址 |
staff_escort | 工作人员带领游客取 | 现场 |
第五层 供奉时长
offering_duration_days(天)+ offering_ready_at(可拿回时刻)= offering_done_at + duration
⚠️ 与既有 offering_deadline 语义不同,不可复用:
- offering_deadline:催单(必须在此前完成供奉,迁移 107)
- offering_duration_days:质保等待期(供奉完成后要等多久才能拿回)
order_items.fulfillment_status 状态机(供奉线)
┌─ staff_deliver / staff_escort
下单(选供奉) ────────→ awaiting_offering 待供奉
└─ 工作人员确认途径
↓
offered 供奉完成、时长计时开始
↓ ⏱ offering_duration_days
ready_for_pickup 时长到、可选拿回途径
↓ 游客/工作人员选
stored / shipped / escort_pickup
↓
delivered 已交付
direct / pickup 两条线完全不走这个状态机,fulfillment_status 留空。
三、字段清单(迁移 111)
商品层
ALTER TABLE goods ADD COLUMN IF NOT EXISTS offerable BOOLEAN NOT NULL DEFAULT FALSE;
COMMENT ON COLUMN goods.offerable IS
'是否可供奉(商品属性)。与 temple(历史归属寺名)解耦:offerable 只说"能供",
选哪座寺/怎么供/怎么拿回全部落到订单项上。';
订单项层
-- 第二层:履约方式
ALTER TABLE order_items ADD COLUMN IF NOT EXISTS fulfillment_mode TEXT
DEFAULT 'direct';
-- 第三层:供奉途径
ALTER TABLE order_items ADD COLUMN IF NOT EXISTS offering_channel TEXT;
-- 选寺
ALTER TABLE order_items ADD COLUMN IF NOT EXISTS offering_temple TEXT;
-- 第五层:供奉时长
ALTER TABLE order_items ADD COLUMN IF NOT EXISTS offering_duration_days INT;
ALTER TABLE order_items ADD COLUMN IF NOT EXISTS offering_done_at TIMESTAMPTZ;
ALTER TABLE order_items ADD COLUMN IF NOT EXISTS offering_ready_at TIMESTAMPTZ;
-- 第四层:拿回途径
ALTER TABLE order_items ADD COLUMN IF NOT EXISTS retrieval_channel TEXT;
ALTER TABLE order_items ADD COLUMN IF NOT EXISTS retrieved_at TIMESTAMPTZ;
-- 暂存与邮寄落点
ALTER TABLE order_items ADD COLUMN IF NOT EXISTS pickup_store_id BIGINT;
ALTER TABLE order_items ADD COLUMN IF NOT EXISTS ship_address JSONB;
-- 现场扫码入口(场景 C)
ALTER TABLE order_items ADD COLUMN IF NOT EXISTS entry_channel TEXT DEFAULT 'online';
订单层(场景 C 扫码入口)
ALTER TABLE orders ADD COLUMN IF NOT EXISTS entry_channel TEXT DEFAULT 'online';
ALTER TABLE orders ADD COLUMN IF NOT EXISTS entry_store_id BIGINT;
四、与现有系统的关系(零破坏)
| 既有资产 | 处置 |
goods.temple | 保留,仅作 A 端运营备注,不再作为分流依据 |
order_items.fulfillment_status | 保留,供奉线扩用;direct/pickup 留空 |
order_items.offering_deadline | 保留,催单用,与时长无关 |
redemption_codes | 不动,pickup 线直接复用 |
_create_goods_order 锁价 | 不动 |
全部为新增列,无一条 DROP / ALTER 现有列。
五、C 端改造清单(待接)
| 页 | 改动 |
pages/shop/shop | 加「可供供」筛选;商品卡标 offerable 徽标 |
pages/item-detail/item-detail | 履约方式三选一 → 供奉线再出(途径 2 选 1 + 选寺 + 时长说明) |
pages/order-detail/order-detail | 展示供奉进度 + 等待期倒计时 + 拿回途径选择 |
| 线下店二维码 | 小程序码带 scene,落地页读 scene 预填 entry_channel=store_qr + entry_store_id |
六、A 端改造清单(待接)
| 端 | 改动 |
| 商品管理 | 上架时勾「可供供」+ 配供奉时长 |
| 履约工作台 | 供奉单列表(按寺院/途径/状态筛),三键操作:确认供奉 / 确认取回 / 标记交付 |
| 暂存管理 | 途径 C 的暂存台账(哪单、存在哪、可拿时间) |
| 邮寄管理 | 途径 D 的待寄清单 + 运单号 |
七、待建的表(新概念,非加字段可解)
| 概念 | 说明 |
| 暂存台账 | 途径 C 落地:order_items.pickup_store_id + retrieved_at 只能表达"在哪、什么时候取",缺"暂存时长上限"与"超期处置" |
| 收货地址 | 途径 D 落地:ship_address JSONB 有位置,但缺地址簿(同一游客多单要复用) |
| 寺方对接 | 供奉涉及第三方(寺方),现有 merchants 体系不含寺;打通与结算方式待业务定 |
八、已执行
- [x] 设计定稿(本文档)
- [x] 迁移 111 落库(11 个新列,零破坏)
- [ ] 7 款现有寺供品回填
offerable=true - [ ] C 端四层选择器
- [ ] A 端履约工作台