基于 StoreOrderController 与 CartServiceImpl、StoreOrderServiceImpl 的代码梳理。
| 接口 | 方法 | 说明 |
|---|---|---|
/cart/add |
addCartItem |
添加菜品到购物车 |
/cart/update |
updateCartItem |
修改购物车中某菜品数量 |
/cart/remove |
removeCartItem |
从购物车删除某菜品 |
/cart/clear |
clearCart |
清空购物车(保留已下单商品和餐具) |
/create |
createOrder |
从购物车生成订单(下单) |
/create,把当前购物车内容落单。createOrder 会更新该订单(用当前购物车全量覆盖订单明细),从而实现加餐。没有单独的「加餐接口」,全程用「购物车 + 下单/更新订单」完成。createOrder 后由 lockCartItems 更新,只增不减,直到支付后清空购物车)。TABLEWARE_CUISINE_ID)store_info.tableware_fee(单位:元/人)。| 接口 | 方法 | 说明 |
|---|---|---|
POST /cart/set-diner-count |
setDinerCount(tableId, dinerCount) |
设置用餐人数,自动添加或更新餐具 |
PUT /cart/update-tableware |
updateTablewareQuantity(tableId, quantity) |
直接改餐具数量 |
setDinerCount(设置用餐人数)
tableId、dinerCount(必须 > 0)。tableware_fee 重算,小计 = 单价 × dinerCount。updateTablewareQuantity(更新餐具数量)
tableId、quantity(≥ 0)。removeItem 删除餐具项;若餐具已有 lockedQuantity > 0 会抛「商品已下单,不允许删除」。CartServiceImpl.getTablewareUnitPrice(storeId):
store_info 表,用 store_info.tableware_fee(Integer,单位一般为分或元,以当前代码使用方式看是按「元」参与计算)。addCartItem 或 updateCartItem 增加数量。addCartItem(会在原数量上叠加,再次下单时 lockCartItems 会更新 lockedQuantity)。updateCartItem 把数量改为比 lockedQuantity 小会报错:「商品数量不能少于已下单数量(x),该数量已下单」。lockedQuantity == 0 或 null 时才能 removeCartItem。清空购物车(clearCart):
setDinerCount 或 updateTablewareQuantity 修改人数/餐具数量;updateTablewareQuantity(0) 可删除餐具项。setDinerCount 或 updateTablewareQuantity 增加人数/餐具数量。setDinerCount(dinerCount) 或 updateTablewareQuantity(quantity) 导致餐具数量小于 lockedQuantity,会报错「餐具数量不能少于已下单数量(x)」。updateTablewareQuantity(0) 会调 removeItem,若餐具 lockedQuantity > 0 会报错「商品已下单,已下单数量为 x,不允许删除」。setDinerCount → 购物车出现或更新餐具项(数量 = 人数,单价 = 门店餐具费)。addCartItem / updateCartItem → 购物车有菜品与餐具。createOrder → 订单写入订单表+订单明细(含菜品和餐具),然后 lockCartItems:所有购物车项(含餐具)的 lockedQuantity 设为当前数量。updateTablewareQuantity 和 setDinerCount 已与菜品一致:下单后(lockedQuantity > 0)只能增不能减,数量不能小于已下单数量;updateTablewareQuantity(0) 删除餐具时,若已下单则走 removeItem 报错不允许删除。tablewareFee、totalAmount、payAmount 等完全采用前端传参,后端不校验;订单明细中的餐具行仍来自购物车(单价、数量、小计)。若前端与购物车不一致,会出现订单头与明细不一致,需前端保证与购物车一致或后端在需要时做一致性校验。创建订单金额 vs 支付时重算
totalAmount、tablewareFee、discountAmount、payAmount 完全采用前端传参,后端不校验。payOrder 会按订单的 totalAmount、tablewareFee 和优惠券重新计算 discountAmount、payAmount 并写回订单,即支付时以后端计算为准。更新订单优惠券时后端重算
updateOrderCoupon 会根据订单的 totalAmount、tablewareFee 和新的优惠券重新计算 discountAmount、payAmount 并更新订单,与支付逻辑一致。若希望「改券不改金额、由前端传」需单独约定并改逻辑。
门店餐具费单位
store_info.tableware_fee 为 Integer,当前代码按「数值直接作为元」参与计算(如 1 表示 1 元)。若实际配置为「分」,需在 getTablewareUnitPrice 中做单位换算(如 ÷100),并与配置约定一致。
【高】用户将菜品/餐具数量减至「已下单数量」后,再次点「下单」会报错,订单未同步(按产品策略不修复)
createOrder 要求「有新增商品或商品数量增加」才放行;若用户仅把某品数量减少后点下单,接口会报错,订单未同步。【中】清空购物车时餐具数量未恢复为已下单数量(已修复)
clearCart 对菜品会把「当前数量」恢复为 lockedQuantity,此前对餐具只做「保留」、不恢复数量。lockedQuantity > 0,将其数量与小计恢复为 lockedQuantity,与菜品逻辑一致。【低】Redis 过期后从 DB 加载购物车的时序
loadCartFromDatabase 可能读到旧数据。lockedQuantity 与当前订单不一致。lockCartItems 后同步写 DB 一次(或关键操作后同步落库),或缩短 Redis TTL + 监控异步写失败。【低】订单与购物车展示不一致的体验
文档基于当前代码逻辑整理,若后续接口或锁定策略有改动,需同步更新本文档。