先说结论
Odoo POS 的商品配置弹窗不是“前端选几个属性,然后把结果塞进订单行”这么简单。
从 product_configurator_popup.js 到 pos_order_line.js,这条链至少包含:
- 属性行如何初始化;
- 单选、多选、自定义值如何进入状态树;
- extra price 怎么即时展示;
- 当前选择最终落到哪个产品或变体;
- 订单行如何把这些配置持久化,保证后续还能编辑、打印、同步。
所以它的本质不是一个弹窗,而是:
把“顾客的个性化点单选择”翻译成一条可持久化、可重放的 POS 订单行。
一、为什么弹窗一开始维护的是属性状态,而不是订单行
ProductConfiguratorPopup 在 setup() 里先建立一个 attributes 状态对象。
这个状态的结构不是围绕订单行,而是围绕每条 attribute line:
- 当前选中的值;
- 当前的
custom_value。
这说明弹窗在第一阶段处理的不是“最终结果”,而是:
- 配置过程本身。
因为用户在这个阶段还可能:
- 来回切换属性;
- 增删多选值;
- 输入自定义文字;
- 强制指定某个 variant value。
如果一开始就把状态直接绑死在订单行结构上,交互会非常别扭。
二、为什么单选、多选、自定义值被拆成不同交互组件
源码里有:
RadioProductAttributePillsProductAttributeSelectProductAttributeColorProductAttributeImageProductAttributeMultiProductAttribute
这说明 Odoo 不是把属性都当成同一种输入框。
因为不同属性的业务语义本来就不同:
- 颜色更像视觉选择;
- 图片值更像商品外观确认;
- 多选值意味着组合扩展;
- 自定义值则意味着要把用户输入带进订单语义。
看起来是前端组件分层,实质上是在承认:
- 不同属性类型会影响后续订单行的表达方式。
三、extra price 为什么要在弹窗里就显示
getFormatPriceExtra() 会把属性值上的额外价格格式化成:
+ 金额- 或
- 金额
这不是简单美化,而是在点单当下就把价格后果可视化。
因为对 POS 来说,商品配置不是纯描述问题,而是:
- 顾客一边选,一边就会影响成交价。
如果 extra price 不在选择时展示,而是最后进订单行才体现:
- 收银员会更难解释;
- 顾客更容易在支付前才发现价格变化;
- 争议也会更大。
所以它必须前置到配置交互里。
四、为什么“当前 product 是谁”并不总是固定的
弹窗里的 get product() 并不是死拿 template 或固定 product。
它会根据:
- 是否存在 variant;
- 当前 attribute 选择;
- 是否强制某个 value;
- 是否在编辑既有订单行。
去确定当前应落到哪个产品对象。
这说明 Odoo POS 的商品配置,不是“同一 product 上记几个备注”而已。
很多时候,顾客的配置结果会直接决定:
- 最终卖的是哪个具体 variant;
- 订单行要记什么属性组合;
- 后续打印和同步要怎样还原这次选择。
五、为什么订单行必须持久化 selected attributes 与 custom values
如果这些选择只存在于弹窗关闭前的前端状态里,后面就会立刻出问题:
- 编辑订单行时无法回放原配置;
- 小票上看不出顾客具体选了什么;
- 同步到别的终端后信息丢失;
- 厨房或后场无法准确知道个性化要求。
所以 pos_order_line 必须把:
- 选中的 attribute values;
- custom values;
- 价格变化结果;
- 可能对应的 variant 归位信息;
一起保存下来。
这正是“商品配置链路”真正落地的地方。
六、为什么这套设计很适合餐饮和定制零售
POS 的配置弹窗最常见于两类场景:
- 餐饮:辣度、配菜、备注、自定义口味;
- 零售:颜色、尺寸、定制选项、附加项。
它们共同的难点是:
- 选项既要影响价格;
- 又要影响后续执行;
- 还要能在订单生命周期里被重复读取。
Odoo 把“配置”做成弹窗只是界面表象,真正的核心是:
- 把可变选择收敛成稳定订单语义。
七、最容易误解的几个点
误解 1:商品配置只是前端交互
不对。它最后要变成稳定订单行数据。
误解 2:extra price 只是展示效果
不对。它是在点单现场提前暴露价格后果。
误解 3:属性选择不会影响具体 product
不对。很多情况下它会重新决定最终 variant。
误解 4:自定义值只要打印出来就够了
不对。它还关系到编辑、同步和后场执行。
八、做配置定制时最该保留什么
如果你要扩展 POS 商品配置,最值得保留的是:
- 属性状态和订单行状态分层;
- extra price 在交互阶段即展示;
- 最终把 selected values / custom values 稳定写入订单行。
不要把它偷懒做成“前端备注框 + 最终价格手改”,那样很快就会丢失可追溯性。
最后一句
理解 Odoo POS 的商品配置,重点不是弹窗长什么样,而是看懂这条主链:
attribute 状态收集 → variant / product 归位 → extra price 即时提示 → 订单行持久化配置结果。
看懂以后你就会知道,这不是一个弹窗组件,而是一套把顾客偏好写进订单语义的机制。
DISCUSSION
评论区