苍穹外卖|项目日记(day08-day09)
前言: 今天是最煎熬的一天, 因为微信支付功能无法实现, 一直再改bug, 最后在一位大佬的文章中找到解决方法.
前言: 今天是最煎熬的一天, 因为微信支付功能无法实现, 一直再改bug, 最后在一位大佬的文章中找到解决方法.

点此处:大佬文章
今日收获:
1.跳过微信支付
2.理解订单接口开发的逻辑(与业务实际相结合)
遇到问题:
1.BeanUtils.copyProperties将Orders类中的属性赋值给OrderVO
起初我实在不理解为什么可以将Orders里那么多的属性赋值给OrderVO, 最后才知道, OrderVO继承了Orders, 这意味着两者天然存在同名属性的对应关系.
@Data
@NoArgsConstructor
@AllArgsConstructor
// OrderVo类
public class OrderVO extends Orders implements Serializable {
//订单菜品信息
private String orderDishes;
//订单详情
private List<OrderDetail> orderDetailList;
}
如图示:

一. 跳过微信支付
第一步:打开小程序端按照我提供的图片去修改注释代码

第二步:修改idea中OrderServiceImpl中的订单支付payment的业务代码
添加如下代码
完善这个orderMapper下这个updateStatus方法:
二.订单的相关开发代码
1.管理端
1.1订单搜索
这一接口的代码实现较复杂, 需要分页查询, 还需要自己设置菜品信息
/**
* 分页查询
* @param ordersPageQueryDTO
* @return
*/
@Override
public PageResult orderquery(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);
}
private List<OrderVO> getOrderVOList(Page<Orders> page) {
// 需要返回订单菜品信息,自定义OrderVO响应结果
List<OrderVO> orderVOList = new ArrayList<>();
List<Orders> ordersList = page.getResult();
if (!CollectionUtils.isEmpty(ordersList)) {
for (Orders orders : ordersList) {
// 将共同字段复制到OrderVO
OrderVO orderVO = new OrderVO();
BeanUtils.copyProperties(orders, orderVO);
String orderDishes = getOrderDishesStr(orders);
// 将订单菜品信息封装到orderVO中,并添加到orderVOList
orderVO.setOrderDishes(orderDishes);
orderVOList.add(orderVO);
}
}
return orderVOList;
}
/**
* 根据订单id获取菜品信息字符串
*
* @param orders
* @return
*/
private String getOrderDishesStr(Orders orders) {
// 查询订单菜品详情信息(订单中的菜品和数量)
List<OrderDetail> orderDetailList = orderDetailMapper.getByOrderId(orders.getId());
// 将每一条订单菜品信息拼接为字符串(格式:宫保鸡丁*3;)
List<String> orderDishList = orderDetailList.stream().map(x -> {
String orderDish = x.getName() + "*" + x.getNumber() + ";";
return orderDish;
}).collect(Collectors.toList());
// 将该订单对应的所有菜品信息拼接在一起
return String.join("", orderDishList);
}
1.2拒单
在最开始, 我是没有考虑到订单状态在2才可以拒单, 而是直接修改其状态并进行退款, 说到底还是业务实践不多. 下方代码把微信支付功能注释掉, 因为无法使用且会影响后续代码的学习.
核心代码:
/**
* 拒单
* @param ordersRejectionDTO
*/
@Override
public void reject(OrdersRejectionDTO ordersRejectionDTO) throws Exception{
// 根据id查询订单
Orders ordersDB = orderMapper.getById(ordersRejectionDTO.getId());
// 订单只有存在且状态为2(待接单)才可以拒单
if (ordersDB == null || !ordersDB.getStatus().equals(Orders.TO_BE_CONFIRMED)) {
throw new OrderBusinessException(MessageConstant.ORDER_STATUS_ERROR);
}
//支付状态
Integer payStatus = ordersDB.getPayStatus();
if (payStatus == Orders.PAID) {
//用户已支付,需要退款
// String refund = weChatPayUtil.refund(
// ordersDB.getNumber(),
// ordersDB.getNumber(),
// new BigDecimal(0.01),
// new BigDecimal(0.01));
// log.info("申请退款:{}", refund);
}
// 拒单需要退款,根据订单id更新订单状态、拒单原因、取消时间
Orders orders = new Orders();
orders.setId(ordersDB.getId());
orders.setStatus(Orders.CANCELLED);
orders.setRejectionReason(ordersRejectionDTO.getRejectionReason());
orders.setCancelTime(LocalDateTime.now());
orderMapper.update(orders);
}
1.3订单状态数量查询
我最开始的做法是直接是在mapper层中查询并封装三种状态的数量, 不过代码不简洁, 无法直接看到逻辑, 遂改为老师的做法, 对统计每个状态的数量, 进行逐个封装.
orderServiceImpl层
/**
* 订单状态数量查询
* @return
*/
@Override
public OrderStatisticsVO statistics() {
// 根据状态,分别查询出待接单、待派送、派送中的订单数量
Integer toBeConfirmed = orderMapper.countStatus(Orders.TO_BE_CONFIRMED);
Integer confirmed = orderMapper.countStatus(Orders.CONFIRMED);
Integer deliveryInProgress = orderMapper.countStatus(Orders.DELIVERY_IN_PROGRESS);
// 将查询出的数据封装到orderStatisticsVO中响应
OrderStatisticsVO orderStatisticsVO = new OrderStatisticsVO();
orderStatisticsVO.setToBeConfirmed(toBeConfirmed);
orderStatisticsVO.setConfirmed(confirmed);
orderStatisticsVO.setDeliveryInProgress(deliveryInProgress);
return orderStatisticsVO;
}
mapper层
/**
* 根据状态统计订单数量
* @param status
*/
@Select("select count(id) from orders where status = #{status}")
Integer countStatus(Integer status);
2.用户端
1.1 取消订单
该接口无疑是业务逻辑比较复杂的, 因为取消订单需要考虑订单的各种状态, 同理, 管理端的拒单也是一样, 需考虑订单的状态.
业务规则:
-
待支付和待接单状态下,用户可直接取消订单
-
商家已接单状态下,用户取消订单需电话沟通商家
-
派送中状态下,用户取消订单需电话沟通商家
-
如果在待接单状态下取消订单,需要给用户退款
-
取消订单后需要将订单状态修改为“已取消”
代码实现:
/**
* 用户取消订单
*
* @param id
*/
public void userCancelById(Long id) throws Exception {
// 根据id查询订单
Orders ordersDB = orderMapper.getById(id);
// 校验订单是否存在
if (ordersDB == null) {
throw new OrderBusinessException(MessageConstant.ORDER_NOT_FOUND);
}
//订单状态 1待付款 2待接单 3已接单 4派送中 5已完成 6已取消
if (ordersDB.getStatus() > 2) {
throw new OrderBusinessException(MessageConstant.ORDER_STATUS_ERROR);
}
Orders orders = new Orders();
orders.setId(ordersDB.getId());
// 订单处于待接单状态下取消,需要进行退款
if (ordersDB.getStatus().equals(Orders.TO_BE_CONFIRMED)) {
//调用微信支付退款接口
// weChatPayUtil.refund(
// ordersDB.getNumber(), //商户订单号
// ordersDB.getNumber(), //商户退款单号
// new BigDecimal(0.01),//退款金额,单位 元
// new BigDecimal(0.01));//原订单金额
//支付状态修改为 退款
orders.setPayStatus(Orders.REFUND);
}
// 更新订单状态、取消原因、取消时间
orders.setStatus(Orders.CANCELLED);
orders.setCancelReason("用户取消");
orders.setCancelTime(LocalDateTime.now());
orderMapper.update(orders);
}
1.2 查询历史订单
该接口的难度主要在于如何对返回的结果进行封装, 因为涉及封装OrdersPageQueryDTO
并分页查询, order与orderDetail表, 并将其封装进OrderVO.
最开始我很不理解为什么要创建实例化OrdersPageQueryDTO并利用它进行分页查询, 大概是因为职责分离, 实体类与表字段严格对应,用于持久化数据,. DTO可自由添加与查询相关的非持久化字段, 进行传参.
/**
* 用户端订单分页查询
*
* @param pageNum
* @param pageSize
* @param status
* @return
*/
public PageResult pageQuery4User(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();
// 查询出订单明细,并封装入OrderVO进行响应
if (page != null && page.getTotal() > 0) {
for (Orders orders : page) {
Long orderId = orders.getId();// 订单id
// 查询订单明细
List<OrderDetail> orderDetails = orderDetailMapper.getByOrderId(orderId);
OrderVO orderVO = new OrderVO();
BeanUtils.copyProperties(orders, orderVO);
orderVO.setOrderDetailList(orderDetails);
list.add(orderVO);
}
}
return new PageResult(page.getTotal(), list);
}
火山引擎开发者社区是火山引擎打造的AI技术生态平台,聚焦Agent与大模型开发,提供豆包系列模型(图像/视频/视觉)、智能分析与会话工具,并配套评测集、动手实验室及行业案例库。社区通过技术沙龙、挑战赛等活动促进开发者成长,新用户可领50万Tokens权益,助力构建智能应用。
更多推荐
所有评论(0)