把订单拆成可解释的字段
提交面板将表单输入集中保存在共享状态中。内容加载完成后,界面初始化数量;用户调整时段、地点、选项和备注时,同步更新表单。请求构造步骤再将这些输入整理为一个明确的数据对象。
常见字段包括地点、备注、数量、单价、条目 ID、总额和附加选项。需要排期的提交还会包含日期和时段;部分计价模式会增加关联记录引用或额外成本。下面是通用字段示例:
final params = {
'location_id': location.id,
'note': note,
'quantity': quantity,
'unit_price': item?.unitPrice,
'item_id': item?.id,
'total': totalAmount,
'include_option': includeOption,
};
费用规则放在同一个计算入口
计价规则应集中在一个计算入口。常见模式是“单价乘数量”,必要时再加服务端返回的附加成本;其他模式可能只按条目单价计算。继续支付时,如果表单没有完整条目数据,则应使用已创建订单的权威金额。
enum PricingMode { withAdditionalCost, baseOnly }
double calculateTotal({
required PricingMode pricingMode,
required double unitPrice,
required int quantity,
double additionalCost = 0,
}) {
final subtotal = unitPrice * quantity;
return pricingMode == PricingMode.withAdditionalCost
? subtotal + additionalCost
: subtotal;
}
每当数量、内容、地点或附加成本变化时,都要确认计算结果重新同步到界面。把金额规则集中起来比在多个按钮回调里重复计算更容易校对。
订单创建前的校验要看两侧
提交函数先校验必填项,再调用服务端并根据返回结果展示下一步。对于可选时段、地点等字段,应同时核对界面按钮状态和服务端校验,避免只在某个入口遗漏检查。
金额和单项费用也不能只相信客户端参数。客户端总价用于即时展示,服务端需要根据有效条目、数量、附加成本规则和订单状态重新计算或核验。用户修改请求包不应改变最终应付金额。
一个适合写成测试的参数表
可以按以下场景直接断言参数对象:
- 需要关联记录的模式:包含关联记录引用、地点和附加成本。
- 普通目录条目:不发送不适用的对象字段。
- 预订单:包含计划日期和时间。
- 非预订单:不包含计划时段字段。
- 必填数据为空:界面阻止提交,服务端也返回明确错误。
- 附加选项:选项是否影响费用由明确的计价规则决定。
- 附加费用尚未返回:总价和提交按钮的行为明确。
经验总结
calculateTotal 这段我摘出来跑过,单价×数量+附加费的断言通过。订单计价我坚持一条铁律:客户端算的只是展示价,最终金额必须服务端重算——见过只信客户端数据的被刷单,再强调一遍不为过。另外”继续支付用已创建订单的权威金额”这个细节很关键:用户在下单页停留时服务端可能调过价,支付时拿旧 total 去调起,轻则失败重则资损。参数表那一节建议真的写成单元测试,字段一多,靠肉眼对”预订单带时段、非预订单不带”这种规则迟早漏。
小结
订单参数是页面选择、控制器状态和服务端规则的交汇处。拆清每个字段的来源、适用订单类型和金额责任,能降低“界面价格正确但提交数据不完整”的风险。
