SpringBoot订单模块核心接口设计与实现

目录

一、 管理端接口实现 (后台管理系统)

一、订单搜索 (高权重 - 核心管理功能)

1.Controller (OrderController):

2.Service (OrderService): 

3.ServiceImpl (OrderServiceImpl):

        1.使用MyBatis分页插件PageHelper

        2.基础数据查询

         4.Mapper (OrderMapper): 

        5.Mapper XML (OrderMapper.xml):

        6.数据转换处理

        6.1getOrderVOList(ordersPage);查询订单详情数据  订单分为:订单基础信息+订单详情数据=完整订单信息 这两个信息是放在不同表内的,他们以逻辑外键 订单ID相连

       6.2 getOrderDishesStr(orders); 将订单信息拼接为字符串显示

        7.结果封装

二、各个状态的订单数量统计 (高权重 - 管理概览)

1.Controller (OrderController):

1.OrderStatisticsVO返回参数​编辑

2.Service (OrderService): 

3.ServiceImpl (AdminOrderServiceImpl): ​编辑​编辑

4.Mapper (OrderMapper): ​编辑

三、查询订单详情 (高权重 - 操作基础)

1.Controller (OrderController):

2.Service (OrderService): 

3.ServiceImpl (OrderServiceImpl):​编辑

3.1数据获取流程:

3.2对象转换:

4.Mapper (OrderMapper): 

5.getByOrderId()orderDetailMapper.getByOrderId(orders.getId());​编辑

四、接单 (核心操作)

1.Controller (OrderController):

2.Service (OrderService): 

3.ServiceImpl (OrderServiceImpl):

4.Mapper (OrderMapper): void update(Order order); (通用更新方法)

5.Mapper XML (OrderMapper.xml): 编写 UPDATE 语句更新状态、confirm_time、operator 等字段。​编辑

五、拒单 (核心操作)

1.Controller (OrderController):

OrdersRejectionDTO类:

2.Service (AdminOrderService): 

3.ServiceImpl (AdminOrderServiceImpl):

4.Mapper (OrderMapper): 同上(更新)。

5.Mapper XML (OrderMapper.xml): 同上(更新更多字段:状态、取消原因类型、取消原因、取消时间)。

六、派送订单 (核心操作)

1.Controller (AdminOrderController):

2.Service (AdminOrderService): 

3.ServiceImpl (AdminOrderServiceImpl):

4.Mapper (OrderMapper): 同上。

5.Mapper XML (OrderMapper.xml): 同上(更新状态、delivery_time)。

七、完成订单 (核心操作)

1.Controller (AdminOrderController):

2.Service (AdminOrderService): 

3.ServiceImpl (AdminOrderServiceImpl):

4.Mapper (OrderMapper): 同上。

5.Mapper XML (OrderMapper.xml): 同上(更新状态、completion_time)。

八、取消订单 (管理端)

1.Controller (AdminOrderController):

2.Service (AdminOrderService): 

3.ServiceImpl (AdminOrderServiceImpl):

4.Mapper (OrderMapper): 同上。

5.Mapper XML (OrderMapper.xml): 同上(更新状态、取消原因类型、取消原因、取消时间)。

二、 用户端接口实现 (小程序/APP)

一.用户下单 (最高权重 - 核心业务起点)

1.Controller (UserOrderController):

2.Service (UserOrderService): 

3.ServiceImpl (UserOrderServiceImpl):

4.Mapper 

5.Mapper XML (list(动态查询菜品或套餐信息), insert(插入订单数据), insert(插入订单详情)): 

二、订单支付 (最高权重 - 核心交易环节)

1.Controller (UserOrderController):

2.Service (UserOrderService): 

3.ServiceImpl (UserOrderServiceImpl):

4.Mapper (OrderMapper): 查询订单 (selectByNumberAndUserId), 更新订单状态/支付信息 (update)。

三、历史订单查询 (高权重 - 用户常用)

1.Controller (UserOrderController):

2.Service (UserOrderService): 

3.ServiceImpl (UserOrderServiceImpl):

4.Mapper (OrderMapper): 

5.Mapper XML (OrderMapper.xml): ​编辑

四、查询订单详情 (用户端)

1.Controller (UserOrderController):

2.Service (UserOrderService): 

3.ServiceImpl (UserOrderServiceImpl):

4.Mapper (OrderMapper): 

5.Mapper XML (OrderMapper.xml): 同管理端详情查询SQL,增加 user_id = #{userId} 条件。

五、取消订单 (用户端)

1.Controller (UserOrderController):

2.Service (UserOrderService): 

3.ServiceImpl (UserOrderServiceImpl):

4.Mapper (OrderMapper): 同上(更新)。

5.Mapper XML (OrderMapper.xml): 同上(更新状态、取消原因类型、取消时间)。

六、再来一单 (提升复购)

1.Controller (UserOrderController):

2.Service (UserOrderService): 

3.ServiceImpl (UserOrderServiceImpl):

4.Mapper (OrderMapper, OrderDetailMapper, ShoppingCartMapper): 

5.Mapper XML (OrderMapper.xml, OrderDetailMapper.xml, ShoppingCartMapper.xml): 

七、催单 (提升体验)

1.Controller (UserOrderController):

2.Service (UserOrderService): 

3.ServiceImpl (UserOrderServiceImpl):

4.Mapper (): 无

5.Mapper XML (): 无

三、 关键技术与注意事项

四、 总结


引言

  • 项目背景: 简述项目核心业务,突出订单模块的核心地位。

  • 技术栈: Spring Boot, Spring MVC, MyBatis (Mapper, XML), Lombok (可选), 数据库 (MySQL等)。

  • 分层架构简述: 快速回顾 Controller -> Service (Interface) -> ServiceImpl (Implementation) -> Mapper (Interface) -> Mapper.xml 的数据流和职责。

  • 本文目标: 聚焦订单模块接口设计,详细讲解管理端用户端核心接口的实现思路与关键代码,涵盖 Controller、Service、ServiceImpl、Mapper 及 XML 的协作。

一、 订单模块核心实体与状态流转

  • Order 实体核心字段: (简要列出,如 id, userId, amount, status, createTime, updateTime, address, items/snapshot 等)

  • 订单状态 (Status Enum): 定义关键状态(如:待支付待接单已接单/制作中派送中已完成已取消已拒绝),并配以状态流转图,清晰展示管理端和用户端操作如何触发状态变化。

一、 管理端接口实现 (后台管理系统)

按操作频率和业务重要性排序

通用返回参数:

Result

一、订单搜索 (高权重 - 核心管理功能)

代码核心逻辑:分页查询订单数据,将基础订单信息转换为包含详情的VO对象,并封装为分页结果返回。具体流程为:首先通过PageHelper设置分页参数并执行订单主表查询;随后调用getOrderVOList方法将查询到的订单数据转换为VO对象(此过程会补充查询订单详情数据);最后将总记录数和VO列表封装到PageResult对象中返回。

1.Controller (OrderController):
  •    GET /admin/order/conditionSearch 
  •         参数:OrdersPageQueryDTO
  •         返回:Result<PageResult>

OrdersPageQueryDTO参数

2.Service (OrderService): 
/*** 根据提供的数据 查询匹配的订单* @param ordersPageQueryDTO* @return*/PageResult QueryOrderAll(OrdersPageQueryDTO ordersPageQueryDTO);
3.ServiceImpl (OrderServiceImpl):

关键点详解分页初始化

        1.使用MyBatis分页插件PageHelper

设置当前页码(page)和每页记录数(pageSize

注意:这行代码必须紧挨在Mapper调用前,否则会导致分页失效java

PageHelper.startPage(ordersPageQueryDTO.getPage(), ordersPageQueryDTO.getPageSize());
        2.基础数据查询
Page<Orders> ordersPage = orderMapper.OrderPage(ordersPageQueryDTO);

执行Mapper层查询,返回Page<Orders>对象

ordersPage包含:

当前页的订单数据列表(List<Orders>

分页信息(总记录数、总页数等)

         4.Mapper (OrderMapper): 
Page<Orders> OrderPage(OrdersPageQueryDTO ordersPageQueryDTO);
        5.Mapper XML (OrderMapper.xml):

编写动态 SQL (<where><if>) 处理各种可选查询条件。

关联查询必要的关联信息(如用户信息、订单项快照等)。

实现高效分页 (limit)。

        6.数据转换处理

List<OrderVO> orderVOList = getOrderVOList(ordersPage);

        6.1getOrderVOList(ordersPage);查询订单详情数据  订单分为:订单基础信息+订单详情数据=完整订单信息 这两个信息是放在不同表内的,他们以逻辑外键 订单ID相连
/*** 根据order 查询order的详细信息* @param ordersPage* @return*/private List<OrderVO> getOrderVOList(Page<Orders> ordersPage){//创建封装类列表List<OrderVO> orderVOList=new ArrayList<>();//获取当前页的列表数据List<Orders> ordersList=ordersPage.getResult();//判断集合是否为空if(!CollectionUtils.isEmpty(ordersList)){//遍历每个数据for (Orders orders:ordersList){//创建封装类OrderVO orderVO=new OrderVO();//拷贝BeanUtils.copyProperties(orders,orderVO);//拼接描述信息(格式:宫保鸡丁*3;)String orderDishes=getOrderDishesStr(orders);//插入描述信息orderVO.setOrderDishes(orderDishes);orderVOList.add(orderVO);}}return orderVOList;}
       6.2 getOrderDishesStr(orders); 将订单信息拼接为字符串显示
/*** 拼接订单详细信息* @param orders* @return*/private String getOrderDishesStr(Orders orders){//查询订单详细信息List<OrderDetail> orderDetailList=orderDetailMapper.getByOrderId(orders.getId());// 将每一条订单菜品信息拼接为字符串(格式:宫保鸡丁*3;)List<String> orderDishes=orderDetailList.stream().map(x->{String orderDish=x.getName()+"*"+x.getNumber()+";";return orderDish;}).collect(Collectors.toList());// 将该订单对应的所有菜品信息拼接在一起return String.join("",orderDishes);}
        7.结果封装
return new PageResult(ordersPage.getTotal(), orderVOList);

构建包含以下内容的分页响应:

ordersPage.getTotal():总记录数(来自Page对象)

orderVOList:当前页的VO数据列表

  1. 二、各个状态的订单数量统计 (高权重 - 管理概览)

这段代码的核心逻辑是统计订单三种状态(退款、已确认、派送中)的数量并封装成VO对象返回。具体通过三次独立查询获取各状态订单数量:先查询退款状态订单数,再查询已确认状态订单数,最后查询派送中状态订单数,最终将这些统计值设置到OrderStatisticsVO对象的对应属性中返回。

1.Controller (OrderController):
  •    GET /admin/order/statistics 
  •         参数:无
  •         返回:自定义 OrderStatisticsVO,包含各状态订单数量。

1.OrderStatisticsVO返回参数
2.Service (OrderService): 
OrderStatisticsVO QueryOrderStatusNums();
3.ServiceImpl (AdminOrderServiceImpl): 
4.Mapper (OrderMapper): 

三、查询订单详情 (高权重 - 操作基础)

这段代码的核心逻辑是根据订单ID查询订单主信息及关联的订单详情列表,组装为VO对象返回。具体过程为:首先通过订单ID查询主订单数据(Orders对象),再根据该订单ID查询对应的订单详情列表(OrderDetail集合),最后将主订单属性拷贝到OrderVO对象并设置详情列表后返回。

1.Controller (OrderController):
  • GET: /admin/order/details/{id}
  • 参数: Long id (订单Id)
  • 返回:OrderVO,包含订单所有详细信息(主表信息、用户信息、地址、订单项详情等)。
  • OrderVO参数
2.Service (OrderService): 
OrderVO QueryOrderDeliver(Long id);
3.ServiceImpl (OrderServiceImpl):
  • 3.1数据获取流程
  • 先通过订单ID查询主表信息(Orders
  • 再通过订单ID查询关联的明细数据(OrderDetail
  • 3.2对象转换
  • 使用BeanUtils.copyProperties简化属性复制
  • 最后组装成前端需要的VO对象

4.Mapper (OrderMapper): 
orderMapper.SelectOrderID(id);
5.getByOrderId()
orderDetailMapper.getByOrderId(orders.getId());

四、接单 (核心操作)

这段代码的核心逻辑是:验证并执行订单接单操作。具体流程为:首先根据传入的ID查询订单数据,校验订单是否存在且处于待接单状态(状态码为REFUND);若校验失败则抛出业务异常;校验通过后创建新订单对象,设置ID并将状态更新为已确认(CONFIRMED),最后调用Mapper执行状态更新。

1.Controller (OrderController):
  • PUT /admin/order/confirm
  • 参数:OrdersConfirmDTO (包含 orderId,可能包含接单备注等)。
  • 返回:操作成功信息。

OrdersConfirmDTO参数:

2.Service (OrderService): 
void confirmOrder(OrdersConfirmDTO ordersConfirmDTO);
3.ServiceImpl (OrderServiceImpl):
  • 查询订单
  • 校验订单状态是否为 待接单
  • 更新订单状态为 已接单 (Order.Status.CONFIRMED),设置接单状态。
  • 调用 OrderMapper.update(Order order)

4.Mapper (OrderMapper): void update(Order order); (通用更新方法)
5.Mapper XML (OrderMapper.xml): 编写 UPDATE 语句更新状态、confirm_timeoperator 等字段。

五、拒单 (核心操作)

这段代码的核心逻辑是:执行订单拒单操作并更新订单状态。具体流程为:首先验证订单是否存在且处于待接单状态(状态码REFUND),校验失败则抛出异常;通过校验后创建新订单对象,设置订单状态为已取消(CANCELLED),同时记录拒单原因和取消时间(当前时间),最后调用Mapper执行更新。其中包含一段被注释的退款逻辑(支付状态下需调用微信退款接口),但当前未实际执行。

1.Controller (OrderController):
  • PUT /admin/order/rejection
  • 参数:OrdersRejectionDTO (包含 orderIdrejectionReason - 必填)。
  • 返回:操作成功信息。

OrdersRejectionDTO类:

2.Service (AdminOrderService): 
void rejectionOrder(OrdersRejectionDTO ordersRejectionDTO);
3.ServiceImpl (AdminOrderServiceImpl):
  • 校验订单状态是否为 待接单
  • 更新订单状态为 已取消,取消原因类型为 前端传输的拒绝原因、取消时间。
  • 调用 OrderMapper.update(Order order)
  • (重要) 如果原订单已支付,调用支付退款接口

4.Mapper (OrderMapper): 同上(更新)。
5.Mapper XML (OrderMapper.xml): 同上(更新更多字段:状态、取消原因类型、取消原因、取消时间)。

六、派送订单 (核心操作)

这段代码的核心逻辑是:执行订单派送操作,将订单状态从待派送更新为派送中。具体流程为:首先根据订单ID查询订单数据,校验订单是否存在且处于待派送状态(状态码CONFIRMED);若校验失败则抛出业务异常;通过校验后创建新订单对象,设置ID并将状态更新为派送中(DELIVERY_IN_PROGRESS),最后调用Mapper执行状态更新。

1.Controller (AdminOrderController):
  • PUT /admin/order/delivery/{id}
  • 参数:Long id(订单Id)
  • 返回:操作成功信息。

2.Service (AdminOrderService): 
void delivery(Long id);
3.ServiceImpl (AdminOrderServiceImpl):
  • 校验订单状态是否为 待派送
  • 更新订单状态为 派送中 (Order.Status.DELIVERY_IN_PROGRESS)。
  • 设置订单ID,订单状态
  • 调用 OrderMapper.update(...)

4.Mapper (OrderMapper): 同上。
5.Mapper XML (OrderMapper.xml): 同上(更新状态、delivery_time)。

七、完成订单 (核心操作)

这段代码的核心逻辑是:执行订单完成操作,将派送中的订单更新为已完成状态。具体流程为:首先根据订单ID查询订单数据,校验订单是否存在且处于派送中状态(状态码DELIVERY_IN_PROGRESS);校验失败则抛出业务异常;通过校验后创建新订单对象,设置ID、将状态更新为已完成(COMPLETED)并记录当前送达时间,最后调用Mapper执行状态更新。

1.Controller (AdminOrderController):
  • PUT /admin/order/complete/{id}
  • 参数:Long id(订单Id)
  • 返回:操作成功信息。

2.Service (AdminOrderService): 
void complete(Long id);
3.ServiceImpl (AdminOrderServiceImpl):
  • 校验订单状态是否为 派送中
  • 更新订单状态为 已完成 (Order.Status.COMPLETED)。
  • 设置订单ID,订单状态、完成时间
  • 调用 OrderMapper.update(...)

4.Mapper (OrderMapper): 同上。
5.Mapper XML (OrderMapper.xml): 同上(更新状态、completion_time)。

八、取消订单 (管理端)

这段代码的核心逻辑是:执行订单取消操作,将已接单订单更新为已取消状态。具体流程为:首先根据订单ID查询订单数据,校验订单是否存在且处于已接单状态(状态码CONFIRMED);校验失败则抛出业务异常;通过校验后创建新订单对象,设置ID、将状态更新为已取消(CANCELLED)并记录取消原因及当前取消时间,最后调用Mapper执行状态更新。其中包含一段被注释的退款逻辑(支付状态下需调用微信退款接口),但当前未实际执行。

1.Controller (AdminOrderController):
  • PUT /admin/order/cancel
  • 参数:OrdersCancelDTO (包含 orderIdcancelReason - 必填)。
  • 返回:操作成功信息。

OrdersCancelDTO参数:

2.Service (AdminOrderService): 
void cancel(OrdersCancelDTO ordersCancelDTO);
3.ServiceImpl (AdminOrderServiceImpl):
  • 校验订单状态(通常允许在已接单等状态取消,具体看业务)。
  • 更新订单状态为 已取消,记录取消原因、取消时间
  • 调用 OrderMapper.update(...)
  • (重要) 如果原订单已支付,调用支付退款接口

4.Mapper (OrderMapper): 同上。
5.Mapper XML (OrderMapper.xml): 同上(更新状态、取消原因类型、取消原因、取消时间)。

二、 用户端接口实现 (小程序/APP)

按用户操作流程和核心体验排序

一.用户下单 (最高权重 - 核心业务起点)

这段代码的核心逻辑是:执行用户下单全流程,包括地址与购物车校验、订单数据构建与插入、订单明细生成、购物车清理及结果返回。具体流程为:首先校验配送地址有效性及用户购物车非空;随后构建订单主数据(填充地址、用户信息、时间戳订单号等),设置初始状态为待付款并插入订单表;接着遍历购物车条目转换为订单明细对象并批量插入;完成后清空用户购物车;最终封装订单ID、下单时间、订单号和金额等基础信息返回VO对象。整个过程通过@Transactional保证事务一致性。

1.Controller (UserOrderController):
  • POST /user/order/submit
  • 参数:OrdersSubmitDTO (包含地址ID、支付方式、备注、购物车商品信息等)。
  • 返回:OrderSubmitVO (包含 orderIdorderNumberorderAmountorderTime 等)。

OrderSubmitVO参数

2.Service (UserOrderService): 
OrderSubmitVO submitOrder(OrdersSubmitDTO ordersSubmitDTO);
3.ServiceImpl (UserOrderServiceImpl):
  1. 数据校验

    • 验证配送地址有效性(地址簿ID存在性)

    • 验证用户购物车非空(通过用户ID查询购物车条目)

  2. 订单创建

    • 构建订单主数据(复制DTO属性,填充时间戳订单号、用户信息、地址信息等)

    • 设置初始状态:待付款(PENDING_PAYMENT)和未支付(UN_PAID

    • 执行订单主表插入

  3. 订单明细处理

    • 遍历购物车条目,转换为订单明细对象(关联新订单ID)

    • 批量插入订单明细表

  4. 清理购物车

    • 删除当前用户购物车所有条目

  5. 返回结果

    • 封装基础订单信息(ID、下单时间、订单号、金额)返回

4.Mapper 
/*** 根据id查询* @param id* @return*/
@Select("select * from address_book where id = #{id}")
AddressBook getById(Long id);
/*** 动态查询菜品或套餐信息* @param shoppingCart* @return*/
List<ShoppingCart> list(ShoppingCart shoppingCart);
/*** 根据id查询地址* @param addressId* @return*/
@Select("select * from address_book where id=#{addressId}")
AddressBook getByUserId(Long addressId);
/*** 插入订单数据* @param orders*/
void insert(Orders orders);
/*** 插入订单详情* @param orderDetailList*/
void inset(List<OrderDetail> orderDetailList);
/*** 清空购物车* @param userId*/
@Delete("delete from shopping_cart where user_id=#{userId}")
void DeleShoppingCart(Long userId);
5.Mapper XML (list(动态查询菜品或套餐信息)insert(插入订单数据)insert(插入订单详情): 
  • list(动态查询菜品或套餐信息)
  • insert(插入订单数据)
  • insert(插入订单详情

二、订单支付 (最高权重 - 核心交易环节)

这段代码的核心逻辑是模拟微信支付流程,生成预支付交易单并返回支付参数。具体流程为:首先获取当前用户信息(含openid),调用微信支付工具生成预支付单(传入订单号、象征性金额0.01元、固定描述和用户openid);若返回结果提示"ORDERPAID"(订单已支付)则抛出业务异常;最终将支付接口返回的JSON数据转换为VO对象,并特殊处理package字段(避免Java关键字冲突)后返回。注:实际支付场景因缺少商户资质无法真实调用,仅作演示用途。

1.Controller (UserOrderController):
  • PUT /user/order/payment
  • 参数:OrdersPaymentDTO (包含 orderNumberpayMethod - 可能微信支付码等)。
  • 返回:支付结果信息(根据支付平台返回封装)。

2.Service (UserOrderService): 
OrderPaymentVO payment(OrdersPaymentDTO ordersPaymentDTO) throws Exception;
3.ServiceImpl (UserOrderServiceImpl):

校验订单号有效性、订单状态为 待支付、订单用户归属。

调用第三方支付接口 (如微信支付):

  • 构造支付请求参数(订单号、金额、描述、用户openid等)。
  • 发起预支付请求,获取预支付交易标识 (prepay_id)。
  • 生成小程序/APP端调起支付所需参数(签名、时间戳等)。
  • (模拟支付场景): 直接修改订单状态为 待接单,记录支付时间。
  • 返回支付参数或成功标识。

4.Mapper (OrderMapper): 查询订单 (selectByNumberAndUserId), 更新订单状态/支付信息 (update)。

三、历史订单查询 (高权重 - 用户常用)

这段代码的核心逻辑是分页查询当前用户的历史订单(支持状态过滤),并将每个订单与其详情列表组合为VO对象返回。具体流程为:首先设置分页参数并构建查询条件(包含当前用户ID和订单状态);执行分页查询获取订单主数据;遍历每个订单,根据订单ID查询对应的订单详情列表;将主订单属性拷贝到VO对象并设置详情列表;最终封装分页结果(总记录数+VO列表)返回。

1.Controller (UserOrderController):
  • GET /user/order/historyOrders
  • 参数:页码、每页条数、订单状态(可选,可查询多个状态)。
  • 返回:分页对象 PageResult,包含订单概览信息列表。

2.Service (UserOrderService): 
PageResult PageOrder(int page, int pageSize, Integer status);
3.ServiceImpl (UserOrderServiceImpl):
  1. 分页初始化
    通过PageHelper.startPage()设置分页参数(页码+每页数量)

  2. 构建查询条件

    • 获取当前用户ID(BaseContext.getCurrentId()

    • 设置订单状态过滤条件(status参数)

    • 封装为DTO对象(OrdersPageQueryDTO

  3. 主订单查询
    调用orderMapper.OrderPage()执行分页查询,获取订单主表数据(Page<Orders>对象)

  4. 订单详情装配
    遍历每个订单:

    • 根据订单ID查询关联的订单详情(orderDetailMapper.getByOrderId()

    • 将主订单属性拷贝到VO对象(BeanUtils.copyProperties

    • 将详情列表注入VO对象(setOrderDetailList()

    • 组装为VO列表(orderVOS

  5. 返回分页结果
    封装总记录数(ordersPage.getTotal())和VO列表到PageResult对象返回

4.Mapper (OrderMapper): 
/*** 查询订单 根据封装类查询* @param ordersPageQueryDTO* @return*/
Page<Orders> OrderPage(OrdersPageQueryDTO ordersPageQueryDTO);
@Select("select * from order_detail where order_id=#{OrderID}")
List<OrderDetail> getByOrderId(Long OrderID);
5.Mapper XML (OrderMapper.xml): 

四、查询订单详情 (用户端)

这段代码的核心逻辑是根据订单ID查询订单主信息及关联的详情列表,组装成VO对象返回。具体执行流程为:首先校验订单ID非空(若为空则返回null);随后通过ID查询主订单数据,再根据订单ID查询对应的订单详情列表;最后创建VO对象,将主订单属性拷贝至VO并注入详情列表后返回。

1.Controller (UserOrderController):
  • GET /user/order/orderDetail/{id}
  • 参数:Long id(订单Id)
  • 返回:OrderVO (同管理端详情,但确保只返回当前用户的数据)。

2.Service (UserOrderService): 
OrderVO OrderByDetai(Long id);
3.ServiceImpl (UserOrderServiceImpl):
  1. 订单ID校验
    首先检查传入的订单ID是否为null,若为空直接返回null(避免无效查询)

  2. 主订单查询
    调用orderMapper.SelectOrderID(id)获取订单主表数据(Orders对象)
    注意:此处未处理ordersnull的情况(订单不存在时后续会抛NPE)

  3. 订单详情查询
    通过orderDetailMapper.getByOrderId()根据订单ID查询关联的菜品/商品明细(返回List<OrderDetail>

  4. VO对象组装

    • 创建OrderVO空对象

    • 使用BeanUtils.copyProperties将主订单属性拷贝到VO

    • 将详情列表注入VO的orderDetailList属性

  5. 返回完整数据
    返回包含主订单信息+详情列表的OrderVO对象

4.Mapper (OrderMapper): 
/*** 根据id查询订单* @param id* @return*/
@Select("select * from orders where id=#{id}")
Orders SelectOrderID(Long id);
/*** 查询订单详情信息* @param OrderID* @return*/
@Select("select * from order_detail where order_id=#{OrderID}")
List<OrderDetail> getByOrderId(Long OrderID);
5.Mapper XML (OrderMapper.xml): 同管理端详情查询SQL,增加 user_id = #{userId} 条件。

五、取消订单 (用户端)

这段代码的核心逻辑是:处理用户取消订单请求,仅允许取消待支付(状态1)和待接单(状态2)的订单,其他状态需联系商家协商。具体流程为:首先验证订单存在性,再校验订单状态是否≤2(非此范围则抛出异常);通过校验后创建新订单对象,设置状态为已取消(6),记录"用户主动取消"原因及当前取消时间,最后调用Mapper执行状态更新。原始设计中待接单状态需触发退款逻辑(调用微信退款接口),但因支付功能未实现而被注释。

1.Controller (UserOrderController):
  • PUT /user/order/cancel/{id}
  • 参数:Long id(订单Id)
  • 返回:操作成功信息。

2.Service (UserOrderService): 
void UpdateOrderStatus(Long id);
3.ServiceImpl (UserOrderServiceImpl):
  1. 校验订单有效性

    • 通过订单ID查询订单,若不存在则抛出异常

    • 仅允许取消待支付(1)和待接单(2)状态的订单(状态值≤2),其他状态抛出异常

  2. 退款处理(注释状态)

    • 原始设计:待接单状态需调用微信退款接口(因支付功能未实现,当前逻辑被注释)

    • 若执行退款需更新支付状态为REFUND

  3. 更新订单状态

    • 设置订单状态为已取消(CANCELLED

    • 记录取消原因为"用户主动取消"

    • 记录取消时间为当前时间

    • 调用Mapper执行状态更新

4.Mapper (OrderMapper): 同上(更新)。
5.Mapper XML (OrderMapper.xml): 同上(更新状态、取消原因类型、取消时间)。

六、再来一单 (提升复购)

这段代码的核心逻辑是将指定订单的菜品详情复制到当前用户的购物车中,实现"再来一单"功能。具体流程为:首先获取当前用户ID;再根据订单ID查询原订单的菜品详情列表;通过流式处理将每个菜品详情对象转换为购物车对象(复制除ID外的所有属性,并设置用户ID和当前创建时间);最终将转换后的购物车对象列表批量插入数据库。

1.Controller (UserOrderController):
  • POST /user/order/repetition/{id}
  • 参数:Long id(订单Id)
  • 返回:操作成功信息或新订单ID (可选)。

2.Service (UserOrderService): 
void repetitionOrder(Long id);
3.ServiceImpl (UserOrderServiceImpl):
  1. 获取当前用户身份
    BaseContext.getCurrentId() 获取当前登录用户的ID

  2. 查询历史订单详情
    通过 orderDetailMapper.getByOrderId(id) 根据订单ID获取原订单包含的所有菜品/商品明细(List<OrderDetail>

  3. 数据转换处理
    使用 Java Stream API 将订单明细转换为购物车对象:

    orderDetailList.stream().map(x->{...})
    • 对象拷贝:通过 BeanUtils.copyProperties 将菜品属性(名称、价格、数量等)从订单明细拷贝到新购物车对象

    • 排除ID:拷贝时忽略原ID("id"参数),确保插入时生成新ID

    • 绑定用户:设置购物车项的归属用户(setUserId(userid)

    • 设置时间:添加当前时间作为创建时间(setCreateTime(LocalDateTime.now())

  4. 批量写入数据库

    shoppingCartMapper.insertBatch(shoppingCartList)

    将转换后的购物车对象列表一次性批量插入购物车表

4.Mapper (OrderMapperOrderDetailMapperShoppingCartMapper): 
/*** 查询订单详情信息* @param OrderID* @return*/
@Select("select * from order_detail where order_id=#{OrderID}")
List<OrderDetail> getByOrderId(Long OrderID);
/*** 批量插入购物车对象* @param shoppingCartList*/
void insertBatch(List<ShoppingCart> shoppingCartList);
5.Mapper XML (OrderMapper.xmlOrderDetailMapper.xmlShoppingCartMapper.xml): 

七、催单 (提升体验)

这段代码的核心逻辑是处理用户催单请求,通过WebSocket向所有在线商家客户端广播催单通知。具体流程为:首先根据订单ID查询订单数据,若订单不存在则抛出异常;随后构建包含催单类型标识(type=2)、订单ID及订单号文本的消息内容;将消息转换为JSON格式后,调用WebSocket服务端方法sendToAllClient()实时推送给所有已连接的商家端客户端,触发商家端的语音/弹窗提醒。

1.Controller (UserOrderController):
  • GET /user/order/reminder/{id}
  • 参数:Long id(订单Id)
  • 返回:操作成功信息(“已提醒商家尽快处理”)。

2.Service (UserOrderService): 
void reminder(Long id);
3.ServiceImpl (UserOrderServiceImpl):
  1. 订单查询与校验

    • 根据订单ID查询订单数据(orderMapper.SelectOrderID(id)

    • 若订单不存在,抛出业务异常(OrderBusinessException

  2. 构建催单消息
    创建包含催单信息的Map对象:

    Map map = new HashMap();
    map.put("type", 2);         // 消息类型:2=催单(区别于1=来单提醒)
    map.put("orderId", id);      // 催单的订单ID
    map.put("content", "订单号: " + orders.getNumber()); // 拼接订单号文本
  3. 消息格式转换
    使用JSON.toJSONString()将Map对象转换为JSON字符串,准备网络传输

  4. 实时消息推送
    调用webSocketServer.sendToAllClient()将JSON格式的催单消息广播给所有已连接的商家端客户端

4.Mapper (): 无
5.Mapper XML (): 无

三、 关键技术与注意事项

  • 事务管理 (@Transactional): 强调在 下单、涉及多表更新的操作(如取消订单涉及状态更新+退款申请)上使用事务保证数据一致性。

  • 数据脱敏: 用户端返回的敏感信息(如电话号码、详细地址)适当脱敏。

  • 状态校验: 所有状态变更操作 (接单拒单取消完成支付) 必须严格校验当前状态是否符合业务规则。

  • 幂等性: 对于支付回调、重要的状态变更接口,考虑实现幂等(如通过唯一业务流水号)。

  • 日志记录: 关键操作(尤其是管理端操作和支付相关)记录详细操作日志。

  • 异常处理: 定义清晰的业务异常 (OrderBusinessExceptionAddressBookBusinessException 等),在Controller层统一捕获并返回友好错误信息。

  • 参数校验: 使用 Spring Validation (@Valid) 或手动校验DTO参数的有效性、非空等。

  • DTO / VO 的应用: 清晰区分数据传输对象 (DTO) 和视图对象 (VO),避免实体类直接暴露给前端。

四、 总结

  • 回顾订单模块的核心接口及其在管理端和用户端的分工。

  • 强调分层设计 (Controller/Service/Mapper) 和状态机管理的重要性。

  • 提示读者关注安全(权限、归属)、事务、幂等、日志等关键实践点。

  • 展望可能的优化点:分库分表(海量订单)、订单超时自动取消(定时任务)、更复杂的统计报表等。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/web/88214.shtml
繁体地址,请注明出处:http://hk.pswp.cn/web/88214.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

EXCEL链接模板无法自动链接到PowerBI?试试这个方法

在使用EXCEL链接模板连接PowerBI时&#xff0c;你有没有遇到如图所示的提示呢&#xff1a;下面我来分享一下&#xff0c;出现弹框的原因及解决方法&#xff1a;首先我们先看一下这个英文翻译&#xff0c;意思就是说&#xff0c;我们只能使一个PowerBI文件处于打开的状态&#x…

最新全开源礼品代发系统源码/电商快递代发/一件代发系统

简介&#xff1a;最新全开源礼品代发系统源码/电商快递代发/一件代发系统测试环境&#xff1a;Nginx PHP7.2 MySQL5.6图片&#xff1a;

Android 事件分发机制深度解析

一、事件分发机制核心概念1. 事件分发三要素要素作用关键方法事件(Event)用户触摸动作的封装MotionEvent分发者负责将事件传递给下级dispatchTouchEvent()拦截者决定是否截断事件传递&#xff08;仅ViewGroup&#xff09;onInterceptTouchEvent()消费者最终处理事件的组件onTou…

从威胁检测需求看两类安全监测平台差异

在网络安全领域&#xff0c;针对不同场景的威胁检测需求&#xff0c;衍生处了多种技术架构的安全监测平台。尽管它们的目标均为“识别异常行为、阻断潜在威胁”&#xff0c;但根据其核心引擎的配置的技术侧重点&#xff0c;可大致分为两类&#xff1a;聚焦基础入侵检测的平台与…

useContext:React 跨组件数据共享的优雅解决方案

关键点 useContext&#xff1a;React 提供的 Hook&#xff0c;用于在组件树中共享全局状态&#xff0c;简化跨组件数据传递。应用场景&#xff1a;主题切换、用户认证、语言设置和全局配置管理。实现方式&#xff1a;结合 createContext 和 useContext&#xff0c;实现灵活的状…

20250706-8-Docker快速入门(下)-Dockerfile介绍与基本使用_笔记

一、Dockerfile构建镜像1. Dockerfile概述&#xfeff;定义&#xff1a;Dockerfile是一个用于自动构建镜像的文本文件&#xff0c;由一条条指令组成工作原理&#xff1a;指令逐步执行&#xff0c;每个指令完成不同功能典型指令示例&#xff1a;FROM centos:latest&#xff1a;基…

Git系列--3.分支管理

目录 一、理解分支 1.1图示 1.2 打印仓库下有哪些分支 1.3创建分支 1.4HEAD与切换分支 1.5合并分支 1.6流程图理解 二、删除分支 ​ 三、合并分支冲突 3.1.问题导入 3.2.解决 3.3合并图示 四、合并模式 4.1合并​编辑 4.2变基 五、bug分支 5.1背景建立 5.2解决步骤 5.2.1…

Vue.js TDD开发深度指南:工具链配置与精细化测试策略

“TDD不是测试优先的开发&#xff0c;而是设计优先的开发。” —— Robert C. Martin 引言 在Vue.js项目中实施测试驱动开发&#xff08;TDD&#xff09;是构建健壮应用的关键路径。但许多开发者在实践中常遇到&#xff1a; 工具链配置复杂导致放弃不同类型组件测试策略混淆测…

基于物联网的智能家居控制系统设计与实现

标题:基于物联网的智能家居控制系统设计与实现内容:1.摘要 随着物联网技术的飞速发展&#xff0c;智能家居逐渐成为人们关注的焦点。本文旨在设计并实现一个基于物联网的智能家居控制系统&#xff0c;以提高家居的智能化水平和用户的生活便利性。通过采用先进的传感器技术、通信…

Vue 中使用 Cesium 实现可拖拽点标记及坐标实时显示功能

在 Cesium 地图开发中&#xff0c;实现点标记的拖拽交互并实时显示坐标信息是一个常见的需求。本文将详细介绍如何在 Vue 框架中使用 Cesium 的 Primitive 方式创建点标记&#xff0c;并实现拖拽功能及坐标提示框跟随效果。先看效果图功能实现概述我们将实现的功能包括&#xf…

HTML 插件:构建网页的强大工具

HTML 插件:构建网页的强大工具 引言 HTML 插件是网页设计中不可或缺的一部分,它们为网页增添了丰富的交互性和动态效果。本文将深入探讨 HTML 插件的概念、类型、应用及其在网页开发中的重要性。 什么是 HTML 插件? HTML 插件,也称为 HTML 组件或 HTML 控件,是指嵌入到…

NeRF、3DGS、2DGS下三维重建相关方法介绍及以及在实景三维领域的最新实践

一、引言 在计算机视觉与图形学领域&#xff0c;三维重建技术正经历从传统几何建模向智能化神经表征的范式转变。近年来&#xff0c;随着深度学习算法的迭代、传感器技术的进步及计算硬件的升级&#xff0c;以神经辐射场&#xff08;NeRF&#xff09;和高斯泼溅&#xff08;2D…

rt thread studio 和 KEIL对于使用rt thread 的中间件和组件,哪个更方便

下面我从中间件/组件集成和开发体验两个角度&#xff0c;详细对比 RT-Thread Studio 和 Keil MDK 的便利性&#xff1a;1. 中间件和组件集成 RT-Thread Studio 集成RT-Thread生态&#xff1a;内置RT-Thread的包管理器&#xff08;RT-Thread Package Manager&#xff09;&#x…

Spring Boot 项目开发实战:入门应用部分原理示例讲解

前言Spring Boot 作为当前 Java 开发领域最流行的框架之一&#xff0c;以其 "约定优于配置" 的理念极大简化了企业级应用的开发流程。本文将基于《Spring Boot 项目开发教程&#xff08;慕课版&#xff09;》中的资产管理系统项目&#xff0c;深入解析 Spring Boot 的…

ByteBrain x 清华 VLDB25|时序多模态大语言模型 ChatTS

资料来源&#xff1a;火山引擎-开发者社区 近年来&#xff0c;多模态大语言模型&#xff08;MLLM&#xff09;发展迅速&#xff0c;并在图像、视频、音频等领域取得了突破性成果。然而&#xff0c;相较于这些研究较为成熟的模态&#xff0c;时间序列这一类型的数据与大模型结合…

WPF学习笔记(25)MVVM框架与项目实例

MVVM框架与项目实例一、MVVM框架1. 概述2. 核心组件与优势一、MVVM项目1.普通项目2. MVVM架构3. MVVM项目实例1. 项目准备2. LoginViewModel与Login2. MainWindowViewModel4. MVVM项目优化1. BaseViewModel2. RealyCommand3. 效果展示总结一、MVVM框架 1. 概述 官方文档&…

MySQL实操

## 基于MySQL#先启动MySQL服务#第一次登录[rootlocalhost ~]# mysql -uroot -P3306#密码登录[rootlocalhost ~]# mysql -uroot -pEnter password: Welcome to the MySQL monitor. Commands end with ; or \g.Your MySQL connection id is 9Server version: 8.0.41 Source dist…

ez_rust_writeup

一道简单的[[rust逆向]] #rust逆向 #位运算 题目信息 文件名&#xff1a;ezrust.exe 题目附件&#xff1a;https://wwfj.lanzoul.com/iczMR30k5j4h 密码:bueq 题目分析 1. 初步分析 这是一道Rust编写的逆向题目。通过IDA分析可以看到&#xff0c;这是一个典型的flag验证程序。 …

【QT】-隐式转换 explicit用法

通俗易懂的解释:隐式转换 vs 显式转换 什么是隐式转换? 隐式转换就是编译器偷偷帮你做的类型转换,你甚至都没意识到它发生了。 例子: cpp 运行 double x = 5; // 隐式:int → double(5 变成 5.0) int y = x * 2.5; // 隐式:double → int(截断小数部分) 构造函数的隐…

Django核心知识点详解:JSON、AJAX、Cookie、Session与用户认证

1. JSON数据格式详解1.1 什么是JSON&#xff1f;JSON&#xff08;JavaScript Object Notation&#xff09;是一种轻量级的数据交换格式&#xff0c;具有以下特点&#xff1a;独立于语言&#xff0c;几乎所有编程语言都支持易于人阅读和编写易于机器解析和生成基于文本&#xff…