取消订单业务

文章目录

概要

取消订单是电子商务、外卖平台、在线零售等多个行业中常见的业务需求之一。这项功能允许消费者或商家取消已下的订单,通常是因为各种原因(如商品缺货、配送问题、支付问题等)。

需求分析以及接口设计

技术细节

1.Controller层:

@ApiOperation("取消订单")
    @PutMapping("/cancel")
    public Result rejection(@RequestBody OrdersCancelDTO ordersCancelDTO){
        log.info("取消订单,{}",ordersCancelDTO);
        orderService.cancel(ordersCancelDTO);
        return Result.success();
    }

2.Service层:

public void cancel(OrdersCancelDTO ordersCancelDTO) {
        Orders order = orderMapper.getById(ordersCancelDTO.getId());

        //获取到支付状态
        Integer payStatus = order.getPayStatus();
        if (payStatus == Orders.PAID) {
            //用户已支付,需要退款(略)

        }
        Orders orders = new Orders();
        orders.setId(orders.getId());
        orders.setCancelReason(ordersCancelDTO.getCancelReason());
        orders.setCancelTime(LocalDateTime.now());
        orderMapper.update(orders);
    }

3.Mapper层:

<update id="update" parameterType="com.sky.entity.Orders">
        update orders
        <set>
            <if test="cancelReason != null and cancelReason!='' ">
                cancel_reason=#{cancelReason},
            </if>
            <if test="rejectionReason != null and rejectionReason!='' ">
                rejection_reason=#{rejectionReason},
            </if>
            <if test="cancelTime != null">
                cancel_time=#{cancelTime},
            </if>
            <if test="payStatus != null">
                pay_status=#{payStatus},
            </if>
            <if test="payMethod != null">
                pay_method=#{payMethod},
            </if>
            <if test="checkoutTime != null">
                checkout_time=#{checkoutTime},
            </if>
            <if test="status != null">
                status = #{status},
            </if>
            <if test="deliveryTime != null">
                delivery_time = #{deliveryTime}
            </if>
        </set>
        where id = #{id}
    </update>

效果展示

在黑马MQ高级功能中,取消订单的实现方法通常涉及消息队列(MQ)的可靠性消息处理机制以及订单状态的最终一致性保障。以下是取消订单功能的相关实现方法和问题解决方案: ### 取消订单功能的实现方法 1. **基于延迟消息的超时订单取消** 黑马MQ中可以通过延迟交换机(Delay Exchange)实现超时订单的自动取消。当用户下单后未在指定时间内完成支付,系统会通过延迟消息触发取消订单的操作。 在订单服务中,可以通过声明延迟交换机和队列,绑定超时订单的路由键,确保在延迟时间到达后将消息投递给订单服务进行处理。例如,订单创建时发送一条延迟消息,在30分钟后触发检查订单支付状态的操作,如果订单仍未支付,则执行取消订单逻辑[^1]。 2. **消息确认机制保障可靠性** 在订单服务中,消费者通过监听消息队列获取订单取消指令。为了避免消息在处理过程中因异常丢失,可以采用手动确认(ack)机制。只有在业务逻辑执行成功后,才手动确认消息,确保消息不会在处理失败时被丢失。 例如,在RabbitMQ中,可以通过设置`autoAck`为`false`,并在处理完成后调用`basicAck`确认消息[^4]。 3. **订单状态一致性保障** 在交易服务中,如果支付成功消息未能正确投递,可以通过定时任务定期检查订单支付状态,确保订单状态的最终一致性。例如,定时任务可以每天执行一次,查询所有未支付的订单,并根据支付中心的状态更新订单状态,防止因消息丢失或处理失败导致数据不一致的问题[^1]。 ### 问题解决方案 1. **消息丢失问题** 如果订单取消消息未能正确投递,可以通过手动确认机制和消息持久化来解决。确保队列和交换机都设置为持久化,并在消费者端启用手动确认,避免消息在处理过程中丢失。 2. **订单状态不一致问题** 为了避免订单状态与支付中心状态不一致,可以设置定时任务周期性地查询订单支付状态。例如,每小时执行一次,检查所有未支付的订单,并根据支付中心的实际状态更新订单状态,确保最终一致性[^1]。 3. **重复消费问题** 如果订单取消消息被重复消费,可以通过幂等性设计来解决。例如,在订单服务中,可以使用唯一业务标识(如订单ID)作为幂等键,记录已处理的消息,避免重复执行取消订单操作。 ### 示例代码 以下是一个订单取消逻辑的代码示例,结合了消息监听和订单状态更新: ```java @RabbitListener(queues = "order.cancel.queue") public class OrderCancelConsumer { @Autowired private OrderService orderService; @RabbitHandler public void process(Long orderId, Channel channel, @Header(AmqpHeaders.DELIVERY_TAG) long tag) throws IOException { try { // 查询订单状态 Order order = orderService.getById(orderId); if (order == null || order.getStatus() == OrderStatus.CANCELED.getValue()) { // 订单取消,无需处理 channel.basicAck(tag, false); return; } // 执行取消订单逻辑 orderService.cancelOrder(orderId); System.out.println(orderId + "订单已被取消"); // 手动确认消息 channel.basicAck(tag, false); } catch (Exception e) { // 处理异常,拒绝消息并重新入队 channel.basicNack(tag, false, true); } } } ``` ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值