Research: 商品规格移植
Feature: 013-food-spec | Date: 2026-07-15
本研究基于对源项目 cte_server 规格功能与目标项目 foodie_server 商品体系的代码勘察,记录关键技术决策。无 NEEDS CLARIFICATION(移植任务,源代码即参考答案)。
决策 1:数据模型 — 规格加价模型(非笛卡尔积 SKU)
- Decision: 采用"规格组 + 规格值 + 商品-规格关联"三表模型;规格值带"加价",顾客选规格后加价累加到商品基础价。
- Rationale: 源项目 cte_server 即此模型,需求是"移植";满足餐饮/夜市"甜度/加料/辣度"场景;实现简单,无需笛卡尔积组合管理。
- Alternatives: 电商式 SKU(每规格组合独立价格/库存/编码)——拒绝:当前无独立库存/编码需求,且与现有 specPrice/otherPrice 加价口径冲突,复杂度不划算。
决策 2:规格归属 — 门店级共享
- Decision: 规格组按门店(
md_id) + 语言(language)维度管理,本门店多商品复用。
- Rationale: 与源项目一致;餐饮场景同一门店的"甜度"规格被多杯饮品复用,避免每商品重复录入。
- Alternatives: 商品级独立规格——拒绝:录入成本高、无复用价值。
决策 3:food_sku JSON 与结构化关联双写
- Decision: 保留
pos_food.food_sku JSON 字段,与 food_spec_relation 结构化关联双写;查询时以结构化关联为权威,food_sku 作兼容冗余。
- Rationale: foodie 现有前端与订单链路(
PromotionCalc.specPrice、PosOrder.food 快照 otherPrice)读取 food_sku JSON;直接废弃会破坏存量链路。双写保证渐进兼容。
- Alternatives: 仅结构化关联、废弃 JSON——拒绝:需同步改前端 + 订单读取,范围过大。
决策 4:命名统一
- Decision: 消除源项目命名不一致(其
foodSku JSON 内规格值明细叫 objects,foodSpecs 内叫 foodSpecsItems)。foodie 移植版统一:结构化规格 FoodSpecs.foodSpecsItems 用 foodSpecsItems;food_sku JSON 内明细若 foodie 前端已有约定则从之,否则统一为 foodSpecsItems。最终命名在 contracts/api.md 明确,前后端对齐。
- Rationale: 源项目命名不一致是已知坑,移植时必须消除,否则前后端字段对不上。
- Alternatives: 照搬两套命名——拒绝:维护负担大。
决策 5:价格类型与口径统一
- Decision: 规格值加价
price 与商品 price 同口径。foodie PosFood.price 为 BigDecimal(DB decimal),故规格加价列也用 decimal/BigDecimal,不照搬源项目的 Long(分)。下单实付单价 = 商品基础价 + 所选规格值加价之和;该和即写入订单快照 otherPrice 与促销 specPrice。
- Rationale: 保持与 foodie 现有价格体系一致,避免单位换算 bug;统一 otherPrice/specPrice/规格加价三国口径。
- Alternatives: 用整数分——拒绝:与商品价类型不一致,引入换算风险。
决策 6:后台通道统一收口(FR-011)
- Decision: 一并修复后台
add/edit(PosFoodController 后台段)不写规格的问题,使两条保存通道行为一致;抽取公共的"保存规格关联 + 写 food_sku"逻辑供 setposfood 与 add/edit 复用。
- Rationale: spec FR-011 要求;否则后台编辑商品会丢规格,造成数据不一致。
- Alternatives: 仅改商家端 setposfood——拒绝:留隐患。
决策 7:查询性能 — 批量注入避免 N+1
- Decision: 商品列表注入规格采用"一次查该批商品所有关联 → 一次查相关规格组 → 一次查相关规格值 → 内存分组",不逐商品查库(沿用源项目模式)。
- Rationale: 列表接口商品数多,逐条查会 N+1。
- Alternatives: 逐商品查——拒绝:性能差。
依赖与集成
- 技术栈均为 foodie 既有,无需引入新依赖。
- 唯一需对齐的集成点:订单快照
otherPrice、促销 specPrice 的取值来源(决策 5 已统一为"所选规格值加价之和")。