在苍穹外卖项目的 Day 08 学习中,“用户下单”是整个业务流程的核心,它完成了从购物车数据到正式订单记录的转换。
一、 需求分析与业务流程
用户下单是指用户在购物车选好商品后,通过“去结算”进入订单确认页,最终点击“去支付”生成订单的过程。
- 业务逻辑:下单时需要关联用户的地址簿信息、配送时间、打包费、总金额及备注等数据。
- 下单流程:购物车页面 订单提交页面 订单支付页面 下单成功页面。
二、 数据库与接口设计
1. 数据库表结构 (一对多关系)
下单操作涉及两张核心表:
orders(订单表) :存储订单基本信息,如订单号、状态(待付款、待接单等)、总金额、收货人及手机号等。order_detail(订单明细表) :存储该订单关联的具体菜品或套餐信息(如名称、份数、单价、口味),一个订单对应多个明细记录。
2. 接口定义
-
请求路径:
POST /user/order/submit。 -
数据模型:
- 入参 (DTO) :使用
OrdersSubmitDTO接收前端传递的地址 ID、配送状态、总金额、餐具数量等。 - 出参 (VO) :返回
OrderSubmitVO,包含订单 ID、订单号、订单金额及下单时间,用于后续支付环节。
- 入参 (DTO) :使用
三、 核心代码实现逻辑
下单业务集中在 OrderServiceImpl.submitOrder 方法中,其执行步骤如下:
-
异常情况校验:检查收货地址是否为空,以及当前用户的购物车是否有数据。
-
构造订单数据:创建
Orders对象,通过BaseContext.getCurrentId()获取用户 ID,设置订单号(通常使用系统时间戳)、订单状态(待付款)、下单时间等。 -
向订单表插入数据:调用
orderMapper.insert(order)向orders表插入 1 条记录。 -
构造并插入订单明细:
- 遍历当前用户的购物车数据,将每一项转换为
OrderDetail对象。 - 设置明细对应的订单 ID(由步骤 3 生成的主键)。
- 调用
orderDetailMapper.insertBatch(list)批量插入多条明细记录。
- 遍历当前用户的购物车数据,将每一项转换为
-
清理购物车:下单成功后,必须调用
shoppingCartMapper.deleteByUserId清空当前用户的购物车数据。 -
封装结果并返回。
四、 辅助学习建议
- 事务管理:下单涉及多表操作(订单表、明细表、购物车表),必须在 Service 方法上添加
@Transactional注解,保证操作的原子性。 - 冗余字段理解:观察
order_detail表,你会发现它存储了商品名称和图片等冗余字段。这是为了防止以后菜品信息被修改或删除后,历史订单中的商品信息依然能正确显示。 - 功能测试:在小程序端完成下单后,应立即去数据库检查
orders和order_detail是否产生了对应数据,并确认shopping_cart表中该用户的数据是否已清空。
概念类比: 用户下单的过程就像餐厅的“前台开单” : 服务员(后端服务)先确认你有没有坐下(校验地址和购物车),然后填一张总单据(orders 表)记录桌号和总价。接着,服务员会把具体的菜名和份数写在小纸条上(order_detail 表)贴在后厨墙上。最后,服务员会把你手里的选菜清单(购物车)撕掉,告诉你:“单已经开好了,请去收银台付钱”。