research.md 4.1 KB

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.specPricePosOrder.food 快照 otherPrice)读取 food_sku JSON;直接废弃会破坏存量链路。双写保证渐进兼容。
  • Alternatives: 仅结构化关联、废弃 JSON——拒绝:需同步改前端 + 订单读取,范围过大。

决策 4:命名统一

  • Decision: 消除源项目命名不一致(其 foodSku JSON 内规格值明细叫 objectsfoodSpecs 内叫 foodSpecsItems)。foodie 移植版统一:结构化规格 FoodSpecs.foodSpecsItemsfoodSpecsItemsfood_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"逻辑供 setposfoodadd/edit 复用。
  • Rationale: spec FR-011 要求;否则后台编辑商品会丢规格,造成数据不一致。
  • Alternatives: 仅改商家端 setposfood——拒绝:留隐患。

决策 7:查询性能 — 批量注入避免 N+1

  • Decision: 商品列表注入规格采用"一次查该批商品所有关联 → 一次查相关规格组 → 一次查相关规格值 → 内存分组",不逐商品查库(沿用源项目模式)。
  • Rationale: 列表接口商品数多,逐条查会 N+1。
  • Alternatives: 逐商品查——拒绝:性能差。

依赖与集成

  • 技术栈均为 foodie 既有,无需引入新依赖。
  • 唯一需对齐的集成点:订单快照 otherPrice、促销 specPrice 的取值来源(决策 5 已统一为"所选规格值加价之和")。