课程内容

  • 本次为作业 自己完成
  • 由于微信支付业务无法实现 派送和完成订单无法完成
  • 暂不考虑检测配送范围功能

用户端历史订单模块

  • 查询历史订单
  • 查询订单详细
  • 再来一单
  • 取消订单

商家端订单管理模块

  • 订单搜索
  • 各个状态的订单数量统计
  • 查询订单详情
  • 接单
  • 拒单
  • 取消订单
  • 派送订单
  • 完成订单

用户端历史订单模块

业务功能

  • 查询订单数据
  • 分页展示订单数据
  • 展示订单详细数据

查询订单

设计VO

  • 在pojo模块中 OrderVO一定义
@Data  
@NoArgsConstructor  
@AllArgsConstructor  
public class OrderVO extends Orders implements Serializable {  
  
    //订单菜品信息  
    private String orderDishes;  
  
    //订单详情  
    private List<OrderDetail> orderDetailList;  
  
}

Controller

  • 在user/OrderController层添加查询订单方法
@GetMapping("/historyOrders")  
@ApiOperation("查询订单")  
public Result <PageResult> pageQueryOrders(int page , int pageSize , Integer status) {  
    PageResult pageResult = orderService.pageQueryOrders(page, pageSize,status);  
    return Result.success(pageResult);  
}

Service层

  • 在user/OrderService中声明查询订单方法
/**  
 * 分页查询订单  
 * @param page  
 * @param pageSize  
 * @param status  
 * @return  
 */  
PageResult pageQueryOrders(int page, int pageSize , Integer status);
  • 在对应实现类实现
@Override  
public PageResult pageQueryOrders(int pageNum, int pageSize ,Integer status) {  
  
    //设置分页  
    PageHelper.startPage(pageNum, pageSize);  
    OrdersPageQueryDTO ordersPageQueryDTO = new OrdersPageQueryDTO();  
    ordersPageQueryDTO.setUserId(BaseContext.getCurrentId());  
    ordersPageQueryDTO.setStatus(status);  
  
    //分页条件查询  
    Page<Orders> page = orderMapper.pageQuery(ordersPageQueryDTO);  
    List<OrderVO> list = new ArrayList<>();  
  
    //查询订单明细  
  
    if(page != null && page.getTotal() > 0){  
        for (Orders order : page){  
            Long orderId = order.getId();  
  
            //查询订单明细  
            List<OrderDetail> orderDetails = orderDetailMapper.getByOrderId(orderId);  
            //封装到OrderVo类  
            OrderVO orderVO = new OrderVO();  
            BeanUtils.copyProperties(order,orderVO);  
            orderVO.setOrderDetailList(orderDetails);  
            list.add(orderVO);  
  
        }  
    }  
    return new PageResult(page.getTotal(),list);  
}

Mapper层

  • 在OrderMapper层中添加分页查询订单方法
//分页查询订单  
Page<Orders> pageQuery(OrdersPageQueryDTO ordersPageQueryDTO);
  • 在对应的xml文件中添加具体逻辑
<select id="pageQuery" resultType="Orders">  
    select * from orders  
    <where>  
        <if test="number != null and number!=''">  
            and number like concat('%',#{number},'%')  
        </if>  
        <if test="phone != null and phone!=''">  
            and phone like concat('%',#{phone},'%')  
        </if>  
        <if test="userId != null">  
            and user_id = #{userId}  
        </if>  
        <if test="status != null">  
            and status = #{status}  
        </if>  
        <if test="beginTime != null">  
            and order_time &gt;= #{beginTime}  
        </if>  
        <if test="endTime != null">  
            and order_time &lt;= #{endTime}  
        </if>  
    </where>  
    order by order_time desc  
</select>
  • 在OrderDetailMapper中添加批量查询订单明细方法
  • 简单语句不使用xml文件
//批量查询订单明细
@Select("select * from order_detail where order_id = #{orderId}")  
List<OrderDetail> getByOrderId(Long orderId);

查询订单详细

Controller层

  • 在OrderController中添加查询订单明细方法
//查询订单详细  
@GetMapping("/orderDatail/{id}")  
@ApiOperation("查询订单详细")  
public Result<OrderVO> detail(@PathVariable("id") Long id) {  
    OrderVO orderVO = orderService.detail(id);  
    return Result.success(orderVO);  
}

Service层

  • 在OrderService中声音查询订单明细方法
/**  
 * 查询订单详情  
 * @param id  
 * @return  
 */  
OrderVO details(Long id);
  • 对应实现类实现
@Override  
public OrderVO details(Long id) {  
    // 根据id查询订单  
    Orders orders = orderMapper.getById(id);  
  
    // 查询该订单对应的菜品/套餐明细  
    List<OrderDetail> orderDetailList = orderDetailMapper.getByOrderId(orders.getId());  
  
    // 将该订单及其详情封装到OrderVO并返回  
    OrderVO orderVO = new OrderVO();  
    BeanUtils.copyProperties(orders, orderVO);  
    orderVO.setOrderDetailList(orderDetailList);  
  
    return orderVO;  
}

Mapper层

  • 在OrderMapper层中添加缺失的getByid方法
//根据id查询订单  
@Select("select  # from orders where id = #{id}")  
Orders getById(Long id);

取消订单

  • 待支付和待阶段状态下 用户可以直接取消订单
  • 商家已接单状态下 取消订单需要商家同意
  • 若取消成功 订单状态将修改为已取消 并且为用户退款

Controller层

  • 在OrderContorller层中添加取消订单方法
//取消订单  
@GetMapping("/cancel/{id}")  
@ApiOperation("取消订单")  
public Result cancel(@PathVariable("id") Long id) {  
    orderService.userCancel(id);  
    return Result.success();  
}

Service层

  • 在OrderService中声明取消订单方法
//取消订单  
void userCancel(Long id);
  • 在对应实现类中实现
@Override  
public void userCancel(Long id) throws Exception {  
    //根据id查询订单  
    Orders orders = orderMapper.getById(id);  
    //判断订单状态  
    if (orders == null) {  
        throw new OrderBusinessException("MessageConstant.ORDER_NOT_EXIST");  
    }else if (orders.getStatus() > 2){  
        //订单状态 1待付款 2待接单 3已接单 4派送中 5已完成 6已取消  
        throw new OrderBusinessException(MessageConstant.PASSWORD_ERROR);  
    }  
    Orders order= new Orders();  
    order.setId(orders.getId());  
  
    //订单处于可取消状态下 调用微信支付接口退款  
    if(orders.getStatus().equals(Orders.TO_BE_CONFIRMED)){  
        weChatPayUtil.refund(  
                orders.getNumber(), //商户订单号  
                orders.getNumber(), //商户退款单号  
                new BigDecimal(0.01),//退款金额,单位 元  
                new BigDecimal(0.01));//原订单金额  
        //修改订单状态  
        order.setStatus(Orders.REFUND);  
    }  
    //更新订单状态  
    orders.setStatus(Orders.CONFIRMED);  
    orders.setCancelReason("用户取消订单");  
    orders.setCancelTime(LocalDateTime.now());  
    orderMapper.update(orders);  
}

再来一单

  • 根据订单查询商品 然后将之前商品全部加入到购物车中

Controller层

  • 在OrderController中添加再来一单方法
//再来一单  
@PostMapping("/repetition/{id}")  
@ApiOperation("再来一单")  
public Result recetition(@PathVariable("id") Long id){  
    orderService.repetition(id);  
    return Result.success();  
}

Service层

  • 在OrderService层中声明再来一单方法
//再来一单  
void repetition(Long id);
  • 对应实现类实现
@Override  
public void repetition(Long id) {  
    //查询当前用户id  
    Long userId = BaseContext.getCurrentId();  
  
    //根据订单id查询订单详细  
    List<OrderDetail> orderDetailList = orderDetailMapper.getByOrderId(id);  
  
    //将订单详细数据转换为购物车数据  
    if(!CollectionUtils.isEmpty(orderDetailList)){  
        List<ShoppingCart> shoppingCartList = orderDetailList.stream().map(x -> {  
            ShoppingCart shoppingCart = new ShoppingCart();  
            //将原订详细里面的菜品复制到购物车对象中  
            BeanUtils.copyProperties(x,shoppingCart,"id");  
            shoppingCart.setId(userId);  
            shoppingCart.setCreateTime(LocalDateTime.now());  
            return shoppingCart;  
        }).collect(Collectors.toList());  
        //将购物车对象批量添加到数据库  
        shoppingCartMapper.insertBatch(shoppingCartList);  
  
    }  
  
}

Mapper层

  • 在shoppingCartMapper层中声明批量插入方法
//批量插入购物车数据  
void insertBatch(List<ShoppingCart> shoppingCartList);
  • 对应的xml
<insert id="insertBatch" parameterType="list">

        insert into shopping_cart

        (name, image, user_id, dish_id, setmeal_id, dish_flavor, number, amount, create_time)

        values

        <foreach collection="shoppingCartList" item="sc" separator=",">

            (#{sc.name},#{sc.image},#{sc.userId},#{sc.dishId},#{sc.setmealId},#{sc.dishFlavor},#{sc.number},#{sc.amount},#{sc.createTime})

        </foreach>

</insert>

商家端订单管理模块

  • 订单搜索
  • 各个状态的订单数量统计
  • 查询订单详情
  • 接单
  • 拒单
  • 取消订单
  • 派送订单
  • 完成订单

订单搜索功能

  • 根据订单号/手机号查询订单 支持模糊搜索
  • 根据订单状态进行筛选
  • 根据下单时间进行时间筛选
  • 搜索内容为空 提示未找到相关订单
  • 分页展示搜索到的订单数据

Controller层

  • 在controller.admin下创建orderController类
  • 新增订单搜索方法
@RestController("adminOrderController")  
@RequestMapping("/admin/order")  
@Slf4j  
@Api(tags = "订单管理模块")  
public class OrderController {  
    @Autowired  
    private OrderService orderService;  
  
    //订单搜索  
    @GetMapping("/conditionSearch")  
    @ApiOperation("订单搜索")  
    public Result<PageResult> conditionSearch(OrdersPageQueryDTO ordersPageQueryDTO) {  
        PageResult pageResult = orderService.conditionSearch(ordersPageQueryDTO);  
        return Result.success(pageResult);  
    }  
  
}
  • 增加统计订单数量方法
//不同状态订单统计  
@GetMapping("/statistics")  
@ApiOperation("不同状态订单统计")  
public Result<OrderStatisticsVO> statistics(){  
    OrderStatisticsVO orderStatisticsVO = orderService.statistics();  
    return Result.success(orderStatisticsVO);  
}
  • 新增剩余其他方法
  • 比较简单基础就全写一块了
//接单  
@PutMapping("/confirm")  
@ApiOperation("接单")  
public Result confirm(@RequestBody OrdersConfirmDTO ordersConfirmDTO){  
    orderService.confirm(ordersConfirmDTO);  
    return Result.success();  
}  
  
//拒单  
@PutMapping("/rejection")  
@ApiOperation("拒单")  
public Result rejection(@RequestBody OrdersConfirmDTO ordersConfirmDTO){  
    orderService.rejection(ordersConfirmDTO);  
    return Result.success();  
}  
  
//取消订单  
@PutMapping("/cancel")  
@ApiOperation("取消订单")  
public Result cancel(@RequestBody OrdersConfirmDTO ordersConfirmDTO){  
    orderService.cancel(ordersConfirmDTO);  
    return Result.success();  
}  
  
//派送订单  
@PutMapping("/delivery/{id}")  
@ApiOperation("派送订单")  
public Result delivery(@PathVariable("id") Long id) {  
    orderService.delivery(id);  
    return Result.success();  
}  
  
//完成订单  
@PutMapping("/complete/{id}")  
@ApiOperation("完成订单")  
public Result complete(@PathVariable("id") Long id){  
    orderService.complete(id);  
    return Result.success();  
}

Service层

  • 在OrderService中先声明所有方法
//后台查询订单  
PageResult conditionSearch(OrdersPageQueryDTO ordersPageQueryDTO);  
  
//不同状态订单统计  
OrderStatisticsVO statistics();  
  
//接单  
void confirm(OrdersConfirmDTO ordersConfirmDTO);  
  
//拒单  
void rejection(OrdersConfirmDTO ordersConfirmDTO);  
  
//取消订单  
void cancel(OrdersConfirmDTO ordersConfirmDTO);  
  
//派送订单  
void delivery(Long id);  
  
//完成订单 void complete(Long id);
  • 在实现类分开完成实现
  • 后天查询部分代码
  • 将部分代码抽取单独封装为其他补充方法
@Override  
//后台查询订单  
public PageResult conditionSearch(OrdersPageQueryDTO ordersPageQueryDTO) {  
    PageHelper.startPage(ordersPageQueryDTO.getPage(), ordersPageQueryDTO.getPageSize());  
    Page<Orders> page orderMapper.pageQuery(ordersPageQueryDTO);  
    //部分订单状态  
    //需要将Orders转化为OrderVo  
    List<OrderVO> orderVOList = getOrderVOList(page);  
    return new PageResult(page.getTotal(),orderVOList);  
}  
  
//补充方法  
//将Orders转化为OrderVo  
private List<OrderVO> getOrderVOList(Page<Orders> page){  
    //需要返回订单菜品信息  
    List<OrderVO> orderVOList = new ArrayList<>();  
    List<Orders> ordersList = page.getResult();  
    if(!CollectionUtils.isEmpty(ordersList)){  
        for (Orders orders : ordersList) {  
            OrderVO orderVO = new OrderVO();  
            BeanUtils.copyProperties(orders,orderVO);  
            //补充方法  
            String orderDishes = getOrderDish(orders);  
            //将财评订单信息封装到orderVo中  
            orderVO.setOrderDishes(orderDishes);  
            //将orderVo添加到集合中  
            orderVOList.add(orderVO);  
        }  
    }  
    return orderVOList;  
}  
  
//补充方法  
//获取订单菜品信息  
private String getOrderDish(Orders orders){  
    List<OrderDetail> orderDetails = orderDetailMapper.getByOrderId(orders.getId());  
    //将每一条订单菜品信息拼接问字符串  
    List<String> orderDishList = orderDetails.stream().map(x -> {  
        String orderDish = x.getName() + "*" + x.getNumber() + ";";  
        return orderDish;  
    }).collect(Collectors.toList());  
  
    // 将该订单对应的所有菜品信息拼接在一起  
    return String.join("", orderDishList);  
  
}
  • 不同订单数量统计方法实现
@Override  
//不同状态订单统计  
public OrderStatisticsVO statistics() {  
    //根据状态 查询出不同状态的订单数量  
    Integer toBeConfirmed = orderMapper.countByStatus(Orders.TO_BE_CONFIRMED);  
    Integer confirmed = orderMapper.countByStatus(Orders.CONFIRMED);  
    Integer delivering = orderMapper.countByStatus(Orders.DELIVERING_IN_PROGRESS);  
      
    //将查询到的数据封装到ordersStatisticsVO中响应  
    OrderStatisticsVO orderStatisticsVO = new OrderStatisticsVO();  
    orderStatisticsVO.setConfirmed(confirmed);  
    orderStatisticsVO.setToBeConfirmed(toBeConfirmed);  
    orderStatisticsVO.setDeliveryInProgress(delivering);  
    return orderStatisticsVO;  
}
  • 接单方法实现
@Override  
//接单  
public void confirm(OrdersConfirmDTO ordersConfirmDTO) {  
    Orders orders = Orders.builder()  
            .id(ordersConfirmDTO.getId())  
            .status(ordersConfirmDTO.getStatus())  
            .build();  
    orderMapper.update(orders);  
}
  • 拒单方法实现
@Override  
//拒单  
public void rejection(OrdersRejectionDTO ordersRejectionDTO) throws Exception {  
    //先查询订单状态 只有状态为待接单的订单才能拒单  
    Orders ordersd = orderMapper.getById(ordersRejectionDTO.getId());  
    if(ordersd == null || !ordersd.getStatus().equals(Orders.TO_BE_CONFIRMED)) {  
        throw new OrderBusinessException("MessageConstant.ORDER_STATSU_ERROR");  
    }  
    //判断支付状态  
    Integer payStatus = ordersd.getPayStatus();  
    if (payStatus == ordersd.PAID){  
        //已支付 需要退款  
        String refund = weChatPayUtil.refund(  
                ordersd.getNumber(),  
                ordersd.getNumber(),  
                new BigDecimal(0.01),  
                new BigDecimal(0.01));  
        log.info("退款结果:{}",refund);  
    }  
  
    //更新订单状态  
    Orders orders = new Orders();  
    orders.setId(ordersd.getId());  
    orders.setStatus(Orders.CANCELLED);  
    orders.setRejectionReason(ordersRejectionDTO.getRejectionReason());  
}
  • 取消订单方法实现
@Override  
//取消订单  
public void cancel(OrdersCancelDTO ordersCancelDTO) throws Exception {  
    //根据id查询订单  
    Orders ordersd = orderMapper.getById(ordersCancelDTO.getId());  
    //判断支付状态  
    Integer payStatus = ordersd.getPayStatus();  
    if (payStatus == ordersd.PAID){  
        //已支付 需要退款  
        String refund = weChatPayUtil.refund(  
                ordersd.getNumber(),  
                ordersd.getNumber(),  
                new BigDecimal(0.01),  
                new BigDecimal(0.01));  
        log.info("退款结果:{}",refund);  
  
    }  
    //更新订单状态  
    Orders orders = new Orders();  
    orders.setId(ordersd.getId());  
    orders.setStatus(Orders.CANCELLED);  
    orders.setCancelReason(ordersCancelDTO.getCancelReason());  
    orders.setCancelTime(LocalDateTime.now());  
    orderMapper.update(orders);  
  
}
  • 派送订单方法实现
@Override  
//派送订单  
public void delivery(Long id) {  
    //根据id查询订单  
    Orders ordersd = orderMapper.getById(id);  
    //判断订单状态  
    if(ordersd == null || !ordersd.getStatus().equals(Orders.CONFIRMED)){  
        throw new OrderBusinessException("MessageConstant.ORDER_STATSU_ERROR");  
    }  
    Orders orders = new Orders();  
    orders.setId(ordersd.getId());  
    //更新订单状态为派送中  
    orderMapper.update(orders);  
}
  • 完成订单方法实现
@Override  
//完成订单  
public void complete(Long id) {  
    //根据id查询订单  
    Orders orderd = orderMapper.getById(id);  
    //判断订单状态  
    if (orderd == null || !orderd.getStatus().equals(Orders.TO_BE_CONFIRMED)) {  
        throw new OrderBusinessException("MessageConstant.ORDER_STATSU_ERROR");  
    }  
    Orders orders = new Orders();  
    orders.setId(orderd.getId());  
    orders.setStatus(Orders.COMPLETED);  
    orders.setDeliveryTime(LocalDateTime.now());  
    //更新订单状态为已完成  
    orderMapper.update(orders);  
}

Mapper层

  • 只需补全统计订单数量方法
//统计不同状态订单数量  
@Select("select count(id) from orders where status = #{status}")  
Integer countStatus(Integer status);

优化

想温柔的对待这个世界