Java搭建订单状态机模型

本文介绍了如何使用Spring State Machine构建一个订单状态机,详细展示了从订单创建到完成的各个状态流转,包括状态枚举、事件定义、状态机配置、持久化处理、业务类和服务类的实现。状态机监听器处理状态转换逻辑,确保订单状态按照预设路径正确流转。此外,还提供了测试用例来验证状态机的功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

订单状态机

前言

在电商平台中,订单的状态是十分复杂的,并且订单状态的流转也是极其复杂并且十分严格的。
因此,我们需要定义订单状态的流转模型,并定义订单状态机模型。
我们只需对订单进行相应的状态设置即可,订单状态机内部去触发订单状态流转事件,从而进行相关的状态设置。
如果订单状态不符合(例:待付款->已发货),那么订单状态机内部判断订单前置状态不符合,不能触发相关的流转事件,从而抛出异常,设置订单状态失败。
下边是一个订单状态机的模型,此订单状态稍微有点复杂,不过也涵盖了所有的问题情况。

1 订单状态流程的构建

在这里插入图片描述

2 订单状态机源码

2.1 引入相关依赖

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-messaging</artifactId>
    <version>5.3.3</version>
</dependency>
<dependency>
    <groupId>org.springframework.statemachine</groupId>
    <artifactId>spring-statemachine-core</artifactId>
    <version>2.0.1.RELEASE</version>
</dependency>=

2.2 定义状态机枚举类

package com.wazk.statusmachine.constant;

/**
 * @class: OrderStatusEnum
 * @description: TODO
 * @author: wazk
 * @version: 1.0
 * @date: 2022/4/5 5:03 下午
 */
public enum OrderStatusEnum {
    // 待支付	pay_wait 0
    // 部分支付	pay_part 5
    // 已支付	pay_over 10
    // 待发货待授权	send_wait 15
    // 部分发货		send_part 20
    // 已发货全部发货	send_over 25
    // 已完成(全部收到货)finished 30 25
    // 已发起售后申请 aftermarket_apply 35
    // 部分退款	refund_part 40 15
    // 已关闭	closed 100

    PAY_WAIT(0, "PAY_WAIT"),
    PAY_PART(5, "PAY_PART"),
    PAY_OVER(10, "PAY_OVER"),
    SEND_WAIT(15, "SEND_WAIT"),
    SEND_PART(20, "SEND_PART"),
    SEND_OVER(25, "SEND_OVER"),
    FINISHED(30, "FINISHED"),
    AFTERMARKET_APPLY(35, "AFTERMARKET_APPLY"),
    REFUND_PART(40, "REFUND_PART"),
    CLOSED(100, "CLOSED"),
    ;


    private Integer code;
    private String type;

    public Integer getCode(){
        return this.code;
    }
    public String getType(){
        return this.type;
    }

    OrderStatusEnum(Integer code, String type) {
        this.code = code;
        this.type = type;
    }

    public static OrderStatusEnum getByCode(Integer code){
        for (OrderStatusEnum saleOrderStatusEnum : values()) {
            if (saleOrderStatusEnum.getCode().equals(code)) {
                return saleOrderStatusEnum;
            }
        }
        return null;
    }

}

2.3 定义状态机流转事件

package com.wazk.statusmachine.machine;

/**
 * @class: OrderStatusChangeEvent
 * @description: TODO
 * @author: wazk
 * @version: 1.0
 * @date: 2022/4/5 5:07 下午
 */
public enum OrderStatusChangeEvent {

//    待付款 -> 部分支付 部分支付事件
    PAY_WAIT_TO_PAY_PART_EVENT,
//    待付款 -> 已支付(待成团) 全部支付,待成团
    PAY_WAIT_TO_PAY_OVER_EVENT,
//    待付款 -> 待发货(待授权) 实体全部付款待发货,虚拟全部付款待授权
    PAY_WAIT_TO_SEND_WAIT_EVENT,
//    待付款 -> 已完成(全部收货) 不需要发货
    PAY_WAIT_TO_FINISHED_EVENT,
//    待付款 -> 已关闭 订单取消
    PAY_WAIT_TO_CLOSED_EVENT,

//    部分支付 -> 已支付(待成团) 拼团订单支付剩下的一部分
    PAY_PART_TO_PAY_OVER_EVENT,
//    部分支付 -> 待发货(待授权) 订单支付剩下的一部分
    PAY_PART_TO_SEND_WAIT_EVENT,
//    部分支付 -> 已完成(全部收货) 不需要发货订单支付剩下的一部分
    PAY_PART_TO_FINISHED_EVENT,

//    已支付(待成团) -> 待发货(待授权) 拼团订单拼团成功
    PAY_OVER_TO_SEND_WAIT_EVENT,
//    已支付(待成团) -> 已完成(全部收货) 不需要发货的订单拼团成功
    PAY_OVER_TO_FINISHED_EVENT,
//    已支付(待成团) -> 发起售后申请 拼团订单未拼成功发起售后申请
    PAY_OVER_TO_AFTERMARKET_APPLY_EVENT,

//    待发货(待授权) -> 部分发货
    SEND_WAIT_TO_SEND_PART_EVENT,
//    待发货(待授权) -> 已发货(全部发货)
    SEND_WAIT_TO_SEND_OVER_EVENT,
//    待发货(待授权) -> 发起售后申请
    SEND_WAIT_TO_AFTERMARKET_APPLY_EVENT,

//    部分发货 -> 已发货(全部发货)
    SEND_PART_TO_SEND_OVER_EVENT,
//    部分发货 -> 发起售后申请
    SEND_PART_TO_AFTERMARKET_APPLY_EVENT,

//    已发货(全部发货) -> 已完成(全部收货)
    SEND_OVER_TO_FINISHED_EVENT,
//    已发货(全部发货) -> 发起售后申请
    SEND_OVER_TO_AFTERMARKET_APPLY_EVENT,

//    已完成(全部收货) -> 发起售后申请
    FINISHED_TO_AFTERMARKET_APPLY_EVENT,

//    发起售后申请 -> 部分退款
    AFTERMARKET_APPLY_TO_REFUND_PART_EVENT,
//    发起售后申请 -> 已关闭
    AFTERMARKET_APPLY_TO_CLOSED_EVENT,

//    部分退款 -> 已关闭
    REFUND_PART_TO_CLOSED_EVENT,
//    部分退款 -> 发起售后申请 再次发起售后申请
    REFUND_PART_TO_AFTERMARKET_APPLY_EVENT,

    ;

}

2.4 定义状态机配置类

package com.wazk.statusmachine.machine;

import com.wazk.statusmachine.constant.OrderStatusEnum;
import org.springframework.context.annotation.Configuration;
import org.springframework.statemachine.config.EnableStateMachine;
import org.springframework.statemachine.config.StateMachineConfigurerAdapter;
import org.springframework.statemachine.config.builders.StateMachineStateConfigurer;
import org.springframework.statemachine.config.builders.StateMachineTransitionConfigurer;

import java.util.EnumSet;

/**
 * @class: OrderStatusMachineConfig
 * @description: TODO
 * @author: wazk
 * @version: 1.0
 * @date: 2022/4/5 5:09 下午
 */
@Configuration
@EnableStateMachine(name = "orderStatusMachine")
public class OrderStatusMachineConfig extends StateMachineConfigurerAdapter<OrderStatusEnum, OrderStatusChangeEvent> {

    /**
     * 配置状态
     * @param orderStatusMachineConfig:
     * @throws Exception:
     */
    public void configure(StateMachineStateConfigurer<OrderStatusEnum, OrderStatusChangeEvent> orderStatusMachineConfig) throws Exception {
        orderStatusMachineConfig.withStates()
                .initial(OrderStatusEnum.PAY_WAIT)
                .states(EnumSet.allOf(OrderStatusEnum.class));
    }


    /**
     * 配置状态转换事件关系
     * @param orderStatusMachineConfig:
     * @throws Exception:
     */
    public void configure(StateMachineTransitionConfigurer<OrderStatusEnum, OrderStatusChangeEvent> orderStatusMachineConfig) throws Exception {
        orderStatusMachineConfig
//            待付款 -> 部分支付 部分支付事件
                .withExternal().source(OrderStatusEnum.PAY_WAIT).target(OrderStatusEnum.PAY_PART).event(OrderStatusChangeEvent.PAY_WAIT_TO_PAY_PART_EVENT)
                .and()
//            待付款 -> 已支付(待成团) 全部支付,待成团
                .withExternal().source(OrderStatusEnum.PAY_WAIT).target(OrderStatusEnum.PAY_OVER).event(OrderStatusChangeEvent.PAY_WAIT_TO_PAY_OVER_EVENT)
                .and()
//            待付款 -> 待发货(待授权) 实体全部付款待发货,虚拟全部付款待授权
                .withExternal().source(OrderStatusEnum.PAY_WAIT).target(OrderStatusEnum.SEND_WAIT).event(OrderStatusChangeEvent.PAY_WAIT_TO_SEND_WAIT_EVENT)
                .and()
//            待付款 -> 已完成(全部收货) 不需要发货
                .withExternal().source(OrderStatusEnum.PAY_WAIT).target(OrderStatusEnum.FINISHED).event(OrderStatusChangeEvent.PAY_WAIT_TO_FINISHED_EVENT)
                .and()
//            待付款 -> 已关闭 订单取消
                .withExternal().source(OrderStatusEnum.PAY_WAIT).target(OrderStatusEnum.CLOSED).event(OrderStatusChangeEvent.PAY_WAIT_TO_CLOSED_EVENT)
                .and()

//            部分支付 -> 已支付(待成团) 拼团订单支付剩下的一部分
                .withExternal().source(OrderStatusEnum.PAY_PART).target(OrderStatusEnum.PAY_OVER).event(OrderStatusChangeEvent.PAY_PART_TO_PAY_OVER_EVENT)
                .and()
//            部分支付 -> 待发货(待授权) 订单支付剩下的一部分
                .withExternal().source(OrderStatusEnum.PAY_PART).target(OrderStatusEnum.SEND_WAIT).event(OrderStatusChangeEvent.PAY_PART_TO_SEND_WAIT_EVENT)
                .and()
//            部分支付 -> 已完成(全部收货) 不需要发货订单支付剩下的一部分
                .withExternal().source(OrderStatusEnum.PAY_PART).target(OrderStatusEnum.FINISHED).event(OrderStatusChangeEvent.PAY_PART_TO_FINISHED_EVENT)
                .and()

//            已支付(待成团) -> 待发货(待授权) 拼团订单拼团成功
                .withExternal().source(OrderStatusEnum.PAY_OVER).target(OrderStatusEnum.SEND_WAIT).event(OrderStatusChangeEvent.PAY_OVER_TO_SEND_WAIT_EVENT)
                .and()
//            已支付(待成团) -> 已完成(全部收货) 不需要发货的订单拼团成功
                .withExternal().source(OrderStatusEnum.PAY_OVER).target(OrderStatusEnum.FINISHED).event(OrderStatusChangeEvent.PAY_OVER_TO_FINISHED_EVENT)
                .and()
//            已支付(待成团) -> 发起售后申请 拼团订单未拼成功发起售后申请
                .withExternal().source(OrderStatusEnum.PAY_OVER).target(OrderStatusEnum.AFTERMARKET_APPLY).event(OrderStatusChangeEvent.PAY_OVER_TO_AFTERMARKET_APPLY_EVENT)
                .and()

//            待发货(待授权) -> 部分发货
                .withExternal().source(OrderStatusEnum.SEND_WAIT).target(OrderStatusEnum.SEND_PART).event(OrderStatusChangeEvent.SEND_WAIT_TO_SEND_PART_EVENT)
                .and()
//            待发货(待授权) -> 已发货(全部发货)
                .withExternal().source(OrderStatusEnum.SEND_WAIT).target(OrderStatusEnum.SEND_OVER).event(OrderStatusChangeEvent.SEND_WAIT_TO_SEND_OVER_EVENT)
                .and()
//            待发货(待授权) -> 发起售后申请
                .withExternal().source(OrderStatusEnum.SEND_WAIT).target(OrderStatusEnum.AFTERMARKET_APPLY).event(OrderStatusChangeEvent.SEND_WAIT_TO_AFTERMARKET_APPLY_EVENT)
                .and()

//            部分发货 -> 已发货(全部发货)
                .withExternal().source(OrderStatusEnum.SEND_PART).target(OrderStatusEnum.SEND_OVER).event(OrderStatusChangeEvent.SEND_PART_TO_SEND_OVER_EVENT)
                .and()
//            部分发货 -> 发起售后申请
                .withExternal().source(OrderStatusEnum.SEND_PART).target(OrderStatusEnum.AFTERMARKET_APPLY).event(OrderStatusChangeEvent.SEND_PART_TO_AFTERMARKET_APPLY_EVENT)
                .and()

//            已发货(全部发货) -> 已完成(全部收货)
                .withExternal().source(OrderStatusEnum.SEND_OVER).target(OrderStatusEnum.FINISHED).event(OrderStatusChangeEvent.SEND_OVER_TO_FINISHED_EVENT)
                .and()
//            已发货(全部发货) -> 发起售后申请
                .withExternal().source(OrderStatusEnum.SEND_OVER).target(OrderStatusEnum.AFTERMARKET_APPLY).event(OrderStatusChangeEvent.SEND_OVER_TO_AFTERMARKET_APPLY_EVENT)
                .and()

//            已完成(全部收货) -> 发起售后申请
                .withExternal().source(OrderStatusEnum.FINISHED).target(OrderStatusEnum.AFTERMARKET_APPLY).event(OrderStatusChangeEvent.FINISHED_TO_AFTERMARKET_APPLY_EVENT)
                .and()

//            发起售后申请 -> 部分退款
                .withExternal().source(OrderStatusEnum.AFTERMARKET_APPLY).target(OrderStatusEnum.REFUND_PART).event(OrderStatusChangeEvent.AFTERMARKET_APPLY_TO_REFUND_PART_EVENT)
                .and()
//            发起售后申请 -> 已关闭
                .withExternal().source(OrderStatusEnum.AFTERMARKET_APPLY).target(OrderStatusEnum.CLOSED).event(OrderStatusChangeEvent.AFTERMARKET_APPLY_TO_CLOSED_EVENT)
                .and()

//            部分退款 -> 已关闭
                .withExternal().source(OrderStatusEnum.REFUND_PART).target(OrderStatusEnum.CLOSED).event(OrderStatusChangeEvent.REFUND_PART_TO_CLOSED_EVENT)
                .and()
//            部分退款 -> 发起售后申请 再次发起售后申请
                .withExternal().source(OrderStatusEnum.REFUND_PART).target(OrderStatusEnum.AFTERMARKET_APPLY).event(OrderStatusChangeEvent.REFUND_PART_TO_AFTERMARKET_APPLY_EVENT)
        ;
    }
    
}

2.5 定义状态机持久化工作类

package com.wazk.statusmachine.machine;

import com.wazk.statusmachine.constant.OrderStatusEnum;
import com.wazk.statusmachine.entity.Order;
import org.springframework.statemachine.StateMachineContext;
import org.springframework.statemachine.StateMachinePersist;
import org.springframework.statemachine.support.DefaultStateMachineContext;
import org.springframework.stereotype.Component;

/**
 * @class: OrderStatusMachinePersist
 * @description: TODO
 * @author: wazk
 * @version: 1.0
 * @date: 2022/4/5 5:15 下午
 */
@Component
public class OrderStatusMachinePersist implements StateMachinePersist<OrderStatusEnum, OrderStatusChangeEvent, Order> {

    @Override
    public void write(StateMachineContext<OrderStatusEnum, OrderStatusChangeEvent> context, Order contextObj) {
        // 这里不做任何持久化工作
    }

    @Override
    public StateMachineContext<OrderStatusEnum, OrderStatusChangeEvent> read(Order contextObj) {
        return new DefaultStateMachineContext<>(OrderStatusEnum.getByCode(contextObj.getStatus()), null, null, null, null, "orderStatusMachine");
    }

}

2.6 定义状态机持久化工作配置类

package com.wazk.statusmachine.machine;

import com.wazk.statusmachine.constant.OrderStatusEnum;
import com.wazk.statusmachine.entity.Order;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.statemachine.persist.DefaultStateMachinePersister;
import org.springframework.statemachine.persist.StateMachinePersister;

/**
 * @class: OrderStatusMachinePersistConfig
 * @description: TODO
 * @author: wazk
 * @version: 1.0
 * @date: 2022/4/5 5:20 下午
 */
@Configuration
public class OrderStatusMachinePersistConfig {

    @Autowired
    private OrderStatusMachinePersist orderStatusMachinePersist;

    @Bean(name="orderStatusMachinePersister")
    public StateMachinePersister<OrderStatusEnum, OrderStatusChangeEvent, Order> orderPersist() {
        return new DefaultStateMachinePersister<>(orderStatusMachinePersist);
    }

}

2.7 定义状态机业务类

package com.wazk.statusmachine.machine;

import com.wazk.statusmachine.constant.OrderStatusEnum;
import com.wazk.statusmachine.entity.Order;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.Message;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.statemachine.StateMachine;
import org.springframework.statemachine.persist.StateMachinePersister;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Objects;

/**
 * @class: OrderStatusMachineService
 * @description: TODO
 * @author: wazk
 * @version: 1.0
 * @date: 2022/4/5 5:28 下午
 */
@Service
public class OrderStatusMachineService {

    private static final String ERROR_MSG = "订单前置状态错误";

    @Autowired
    private StateMachine<OrderStatusEnum, OrderStatusChangeEvent> orderStatusMachine;

    @Resource(name = "orderStatusMachinePersister")
    private StateMachinePersister<OrderStatusEnum, OrderStatusChangeEvent, Order> persister;

    // 待付款
    // -> 部分支付 部分支付事件
    public synchronized boolean setPayPart(Order order) {
        return handleEvent(OrderStatusChangeEvent.PAY_WAIT_TO_PAY_PART_EVENT, order);
    }


    // 待付款 -> 已支付(待成团) 全部支付,待成团
    // 部分支付 -> 已支付(待成团) 拼团订单支付剩下的一部分
    public synchronized boolean setPayOver(Order order) {
        OrderStatusEnum orderStatusEnum = getPrefixStatus(order);
        switch (orderStatusEnum) {
            case PAY_WAIT:
                return handleEvent(OrderStatusChangeEvent.PAY_WAIT_TO_PAY_OVER_EVENT, order);
            case PAY_PART:
                return handleEvent(OrderStatusChangeEvent.PAY_PART_TO_PAY_OVER_EVENT, order);
            default:
                throw new RuntimeException(ERROR_MSG);
        }
    }


    // 待付款 -> 待发货(待授权) 实体全部付款待发货,虚拟全部付款待授权
    // 部分支付 -> 待发货(待授权) 订单支付剩下的一部分
    // 已支付(待成团) -> 待发货(待授权) 拼团订单拼团成功
    public synchronized boolean setSendWait(Order order) {
        OrderStatusEnum orderStatusEnum = getPrefixStatus(order);
        switch (orderStatusEnum) {
            case PAY_WAIT:
                return handleEvent(OrderStatusChangeEvent.PAY_WAIT_TO_SEND_WAIT_EVENT, order);
            case PAY_PART:
                return handleEvent(OrderStatusChangeEvent.PAY_PART_TO_SEND_WAIT_EVENT, order);
            case PAY_OVER:
                return handleEvent(OrderStatusChangeEvent.PAY_OVER_TO_SEND_WAIT_EVENT, order);
            default:
                throw new RuntimeException(ERROR_MSG);
        }
    }


    // 待发货(待授权) -> 部分发货
    public synchronized boolean setSendPart(Order order) {
        return handleEvent(OrderStatusChangeEvent.SEND_WAIT_TO_SEND_PART_EVENT, order);
    }


    // 待发货(待授权) -> 已发货(全部发货)
    // 部分发货 -> 已发货(全部发货)
    public synchronized boolean setSendOver(Order order) {
        OrderStatusEnum orderStatusEnum = getPrefixStatus(order);
        switch (orderStatusEnum) {
            case SEND_WAIT:
                return handleEvent(OrderStatusChangeEvent.SEND_WAIT_TO_SEND_OVER_EVENT, order);
            case SEND_PART:
                return handleEvent(OrderStatusChangeEvent.SEND_PART_TO_SEND_OVER_EVENT, order);
            default:
                throw new RuntimeException(ERROR_MSG);
        }
    }


    //    待付款 -> 已完成(全部发货) 不需要发货
    //    部分支付 -> 已完成(全部收货) 不需要发货订单支付剩下的一部分
    //    已支付(待成团) -> 已完成(全部收货) 不需要发货的订单拼团成功
    //    已发货(全部发货) -> 已完成(全部收货)
    public synchronized boolean setFinished(Order order) {
        OrderStatusEnum orderStatusEnum = getPrefixStatus(order);
        switch (orderStatusEnum) {
            case PAY_WAIT:
                return handleEvent(OrderStatusChangeEvent.PAY_WAIT_TO_FINISHED_EVENT, order);
            case PAY_PART:
                return handleEvent(OrderStatusChangeEvent.PAY_PART_TO_FINISHED_EVENT, order);
            case PAY_OVER:
                return handleEvent(OrderStatusChangeEvent.PAY_OVER_TO_FINISHED_EVENT, order);
            case SEND_OVER:
                return handleEvent(OrderStatusChangeEvent.SEND_OVER_TO_FINISHED_EVENT, order);
            default:
                throw new RuntimeException(ERROR_MSG);
        }
    }


    // 已支付(待成团) -> 发起售后申请 拼团订单未拼成功发起售后申请
    // 待发货(待授权) -> 发起售后申请
    // 部分发货 -> 发起售后申请
    // 已发货(全部发货) -> 发起售后申请
    // 已完成(全部收货) -> 发起售后申请
    // 部分退款 -> 发起售后申请 再次发起售后申请
    public synchronized boolean setAftermarketApply(Order order) {
        OrderStatusEnum orderStatusEnum = getPrefixStatus(order);
        switch (orderStatusEnum) {
            case PAY_OVER:
                return handleEvent(OrderStatusChangeEvent.PAY_OVER_TO_AFTERMARKET_APPLY_EVENT, order);
            case SEND_WAIT:
                return handleEvent(OrderStatusChangeEvent.SEND_WAIT_TO_AFTERMARKET_APPLY_EVENT, order);
            case SEND_PART:
                return handleEvent(OrderStatusChangeEvent.SEND_PART_TO_AFTERMARKET_APPLY_EVENT, order);
            case SEND_OVER:
                return handleEvent(OrderStatusChangeEvent.SEND_OVER_TO_AFTERMARKET_APPLY_EVENT, order);
            case FINISHED:
                return handleEvent(OrderStatusChangeEvent.FINISHED_TO_AFTERMARKET_APPLY_EVENT, order);
            case REFUND_PART:
                return handleEvent(OrderStatusChangeEvent.REFUND_PART_TO_AFTERMARKET_APPLY_EVENT, order);
            default:
                throw new RuntimeException(ERROR_MSG);
        }
    }


    // 发起售后申请 -> 部分退款
    public synchronized boolean setRefundPart(Order order) {
        return handleEvent(OrderStatusChangeEvent.AFTERMARKET_APPLY_TO_REFUND_PART_EVENT, order);
    }


    // 待付款 -> 已关闭 订单取消
    // 发起售后申请 -> 已关闭
    // 部分退款 -> 已关闭
    public synchronized boolean setClosed(Order order) {
        OrderStatusEnum orderStatusEnum = getPrefixStatus(order);
        switch (orderStatusEnum) {
            case PAY_WAIT:
                return handleEvent(OrderStatusChangeEvent.PAY_WAIT_TO_CLOSED_EVENT, order);
            case AFTERMARKET_APPLY:
                return handleEvent(OrderStatusChangeEvent.AFTERMARKET_APPLY_TO_CLOSED_EVENT, order);
            case REFUND_PART:
                return handleEvent(OrderStatusChangeEvent.REFUND_PART_TO_CLOSED_EVENT, order);
            default:
                throw new RuntimeException(ERROR_MSG);
        }
    }


    /**
     * @Description: 发送订单状态转换事件
     * @Author: wazk
     * @Date: 2022/4/1 4:47 下午
     * @param event:
     * @param order:
     * @return: boolean
     **/
    private synchronized boolean sendEvent(OrderStatusChangeEvent event, Order order) {
        boolean result = false;
        try {
            Message<OrderStatusChangeEvent> message = MessageBuilder.withPayload(event).setHeader("order", order).build();
            orderStatusMachine.start();
            // 尝试恢复状态机状态
            persister.restore(orderStatusMachine, order);
            result = orderStatusMachine.sendEvent(message);
            // 持久化状态机状态
            persister.persist(orderStatusMachine, order);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            orderStatusMachine.stop();
        }
        return result;
    }


    private boolean handleEvent (OrderStatusChangeEvent event, Order order) {
        if (!sendEvent(event, order)) {
            throw new RuntimeException("订单状态流转事件失败");
        }
        return true;
    }

    // 获取订单的前置状态
    private OrderStatusEnum getPrefixStatus (Order order) {
        OrderStatusEnum orderStatusEnum = OrderStatusEnum.getByCode(order.getStatus());
        if (Objects.isNull(orderStatusEnum)) {
            throw new RuntimeException("获取订单前置状态失败");
        }
        return orderStatusEnum;
    }

}

2.8 定义状态机的监听器

package com.wazk.statusmachine.machine;

import com.wazk.statusmachine.constant.OrderStatusEnum;
import com.wazk.statusmachine.entity.Order;
import org.springframework.messaging.Message;
import org.springframework.statemachine.annotation.OnTransition;
import org.springframework.statemachine.annotation.WithStateMachine;
import org.springframework.stereotype.Service;

import java.util.Objects;

/**
 * @class: OrderStatusListener
 * @description: TODO
 * @author: wazk
 * @version: 1.0
 * @date: 2022/4/5 5:24 下午
 */
@Service
@WithStateMachine(name = "orderStatusMachine")
public class OrderStatusListener {

    private static final String STR_ORDER = "order";

    // 待付款 -> 部分支付 部分支付事件
    @OnTransition(source = "PAY_WAIT", target = "PAY_PART")
    public boolean payWaitToPayPartEvent(Message<OrderStatusChangeEvent> message){
        Order order = (Order) message.getHeaders().get(STR_ORDER);
        if (!Objects.isNull(order)) {
            order.setStatus(OrderStatusEnum.PAY_PART.getCode());
            return true;
        }
        return false;
    }
    // 待付款 -> 已支付(待成团) 全部支付,待成团
    @OnTransition(source = "PAY_WAIT", target = "PAY_OVER")
    public boolean payWaitToPayOverEvent(Message<OrderStatusChangeEvent> message){
        Order order = (Order) message.getHeaders().get(STR_ORDER);
        if (!Objects.isNull(order)) {
            order.setStatus(OrderStatusEnum.PAY_OVER.getCode());
            return true;
        }
        return false;
    }
    // 待付款 -> 待发货(待授权) 实体全部付款待发货,虚拟全部付款待授权
    @OnTransition(source = "PAY_WAIT", target = "SEND_WAIT")
    public boolean payWaitToSendWaitEvent(Message<OrderStatusChangeEvent> message){
        Order order = (Order) message.getHeaders().get(STR_ORDER);
        if (!Objects.isNull(order)) {
            order.setStatus(OrderStatusEnum.SEND_WAIT.getCode());
            return true;
        }
        return false;
    }
    // 待付款 -> 已完成(全部收货) 不需要发货
    @OnTransition(source = "PAY_WAIT", target = "FINISHED")
    public boolean payWaitToFinishedEvent(Message<OrderStatusChangeEvent> message){
        Order order = (Order) message.getHeaders().get(STR_ORDER);
        if (!Objects.isNull(order)) {
            order.setStatus(OrderStatusEnum.FINISHED.getCode());
            return true;
        }
        return false;
    }
    // 待付款 -> 已关闭 订单取消
    @OnTransition(source = "PAY_WAIT", target = "CLOSED")
    public boolean payWaitToClosedEvent(Message<OrderStatusChangeEvent> message){
        Order order = (Order) message.getHeaders().get(STR_ORDER);
        if (!Objects.isNull(order)) {
            order.setStatus(OrderStatusEnum.CLOSED.getCode());
            return true;
        }
        return false;
    }


    // 部分支付 -> 已支付(待成团) 拼团订单支付剩下的一部分
    @OnTransition(source = "PAY_PART", target = "PAY_OVER")
    public boolean payPartToPayOverEvent(Message<OrderStatusChangeEvent> message){
        Order order = (Order) message.getHeaders().get(STR_ORDER);
        if (!Objects.isNull(order)) {
            order.setStatus(OrderStatusEnum.PAY_OVER.getCode());
            return true;
        }
        return false;
    }
    // 部分支付 -> 待发货(待授权) 订单支付剩下的一部分
    @OnTransition(source = "PAY_PART", target = "SEND_WAIT")
    public boolean payPartToSendWaitEvent(Message<OrderStatusChangeEvent> message){
        Order order = (Order) message.getHeaders().get(STR_ORDER);
        if (!Objects.isNull(order)) {
            order.setStatus(OrderStatusEnum.SEND_WAIT.getCode());
            return true;
        }
        return false;
    }
    // 部分支付 -> 已完成(全部收货) 不需要发货订单支付剩下的一部分
    @OnTransition(source = "PAY_PART", target = "FINISHED")
    public boolean payPartToFinishedEvent(Message<OrderStatusChangeEvent> message){
        Order order = (Order) message.getHeaders().get(STR_ORDER);
        if (!Objects.isNull(order)) {
            order.setStatus(OrderStatusEnum.FINISHED.getCode());
            return true;
        }
        return false;
    }


    // 已支付(待成团) -> 待发货(待授权) 拼团订单拼团成功
    @OnTransition(source = "PAY_OVER", target = "SEND_WAIT")
    public boolean payOverToSendWaitEvent(Message<OrderStatusChangeEvent> message){
        Order order = (Order) message.getHeaders().get(STR_ORDER);
        if (!Objects.isNull(order)) {
            order.setStatus(OrderStatusEnum.SEND_WAIT.getCode());
            return true;
        }
        return false;
    }
    // 已支付(待成团) -> 已完成(全部收货) 不需要发货的订单拼团成功
    @OnTransition(source = "PAY_OVER", target = "FINISHED")
    public boolean payOverToFinishedEvent(Message<OrderStatusChangeEvent> message){
        Order order = (Order) message.getHeaders().get(STR_ORDER);
        if (!Objects.isNull(order)) {
            order.setStatus(OrderStatusEnum.FINISHED.getCode());
            return true;
        }
        return false;
    }
    // 已支付(待成团) -> 发起售后申请 拼团订单未拼成功发起售后申请
    @OnTransition(source = "PAY_OVER", target = "AFTERMARKET_APPLY")
    public boolean payOverToAftermarketApplyEvent(Message<OrderStatusChangeEvent> message){
        Order order = (Order) message.getHeaders().get(STR_ORDER);
        if (!Objects.isNull(order)) {
            order.setStatus(OrderStatusEnum.AFTERMARKET_APPLY.getCode());
            return true;
        }
        return false;
    }


    // 待发货(待授权) -> 部分发货
    @OnTransition(source = "SEND_WAIT", target = "SEND_PART")
    public boolean sendWaitToSendPartEvent(Message<OrderStatusChangeEvent> message){
        Order order = (Order) message.getHeaders().get(STR_ORDER);
        if (!Objects.isNull(order)) {
            order.setStatus(OrderStatusEnum.SEND_PART.getCode());
            return true;
        }
        return false;
    }
    // 待发货(待授权) -> 已发货(全部发货)
    @OnTransition(source = "SEND_WAIT", target = "SEND_OVER")
    public boolean sendWaitToSendOverEvent(Message<OrderStatusChangeEvent> message){
        Order order = (Order) message.getHeaders().get(STR_ORDER);
        if (!Objects.isNull(order)) {
            order.setStatus(OrderStatusEnum.SEND_OVER.getCode());
            return true;
        }
        return false;
    }
    // 待发货(待授权) -> 发起售后申请
    @OnTransition(source = "SEND_WAIT", target = "AFTERMARKET_APPLY")
    public boolean sendWaitToAftermarketApplyEvent(Message<OrderStatusChangeEvent> message){
        Order order = (Order) message.getHeaders().get(STR_ORDER);
        if (!Objects.isNull(order)) {
            order.setStatus(OrderStatusEnum.AFTERMARKET_APPLY.getCode());
            return true;
        }
        return false;
    }


    // 部分发货 -> 已发货(全部发货)
    @OnTransition(source = "SEND_PART", target = "SEND_OVER")
    public boolean sendPartToSendOverEvent(Message<OrderStatusChangeEvent> message){
        Order order = (Order) message.getHeaders().get(STR_ORDER);
        if (!Objects.isNull(order)) {
            order.setStatus(OrderStatusEnum.SEND_OVER.getCode());
            return true;
        }
        return false;
    }
    // 部分发货 -> 发起售后申请
    @OnTransition(source = "SEND_PART", target = "AFTERMARKET_APPLY")
    public boolean sendPartToAftermarketApplyEvent(Message<OrderStatusChangeEvent> message){
        Order order = (Order) message.getHeaders().get(STR_ORDER);
        if (!Objects.isNull(order)) {
            order.setStatus(OrderStatusEnum.AFTERMARKET_APPLY.getCode());
            return true;
        }
        return false;
    }


    // 已发货(全部发货) -> 已完成(全部收货)
    @OnTransition(source = "SEND_OVER", target = "FINISHED")
    public boolean sendOverToFinishedEvent(Message<OrderStatusChangeEvent> message){
        Order order = (Order) message.getHeaders().get(STR_ORDER);
        if (!Objects.isNull(order)) {
            order.setStatus(OrderStatusEnum.FINISHED.getCode());
            return true;
        }
        return false;
    }
    // 已发货(全部发货) -> 发起售后申请
    @OnTransition(source = "SEND_OVER", target = "AFTERMARKET_APPLY")
    public boolean sendOverToAftermarketApplyEvent(Message<OrderStatusChangeEvent> message){
        Order order = (Order) message.getHeaders().get(STR_ORDER);
        if (!Objects.isNull(order)) {
            order.setStatus(OrderStatusEnum.AFTERMARKET_APPLY.getCode());
            return true;
        }
        return false;
    }


    // 已完成(全部收货) -> 发起售后申请
    @OnTransition(source = "FINISHED", target = "AFTERMARKET_APPLY")
    public boolean finishedToAftermarketApplyEvent(Message<OrderStatusChangeEvent> message){
        Order order = (Order) message.getHeaders().get(STR_ORDER);
        if (!Objects.isNull(order)) {
            order.setStatus(OrderStatusEnum.AFTERMARKET_APPLY.getCode());
            return true;
        }
        return false;
    }


    // 发起售后申请 -> 部分退款
    @OnTransition(source = "AFTERMARKET_APPLY", target = "REFUND_PART")
    public boolean aftermarketApplyToRefundPartEvent(Message<OrderStatusChangeEvent> message){
        Order order = (Order) message.getHeaders().get(STR_ORDER);
        if (!Objects.isNull(order)) {
            order.setStatus(OrderStatusEnum.REFUND_PART.getCode());
            return true;
        }
        return false;
    }
    // 发起售后申请 -> 已关闭
    @OnTransition(source = "AFTERMARKET_APPLY", target = "CLOSED")
    public boolean aftermarketApplyToClosedEvent(Message<OrderStatusChangeEvent> message){
        Order order = (Order) message.getHeaders().get(STR_ORDER);
        if (!Objects.isNull(order)) {
            order.setStatus(OrderStatusEnum.CLOSED.getCode());
            return true;
        }
        return false;
    }


    // 部分退款 -> 已关闭
    @OnTransition(source = "REFUND_PART", target = "CLOSED")
    public boolean refundPartToClosedEvent(Message<OrderStatusChangeEvent> message){
        Order order = (Order) message.getHeaders().get(STR_ORDER);
        if (!Objects.isNull(order)) {
            order.setStatus(OrderStatusEnum.CLOSED.getCode());
            return true;
        }
        return false;
    }
    // 部分退款 -> 发起售后申请 再次发起售后申请
    @OnTransition(source = "REFUND_PART", target = "AFTERMARKET_APPLY")
    public boolean refundPartToAftermarketApplyEvent(Message<OrderStatusChangeEvent> message){
        Order order = (Order) message.getHeaders().get(STR_ORDER);
        if (!Objects.isNull(order)) {
            order.setStatus(OrderStatusEnum.AFTERMARKET_APPLY.getCode());
            return true;
        }
        return false;
    }

}

3 测试状态机

package com.wazk.statusmachine;

import com.wazk.statusmachine.constant.OrderStatusEnum;
import com.wazk.statusmachine.entity.Order;
import com.wazk.statusmachine.machine.OrderStatusMachineService;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
class StatusMachineApplicationTests {

    @Autowired
    private OrderStatusMachineService orderStatusMachineService;

    @Test
    void contextLoads() {
        Order order = new Order();
        System.out.println("1: " + order.getStatus());

        order.setStatus(OrderStatusEnum.PAY_WAIT.getCode());
        System.out.println("2: " + order.getStatus());

//        正常支付,设置状态机为支付完成状态
//        orderStatusMachineService.setPayOver(order);

//        测试错误,设置状态机为全部发货状态 => 测试结果抛异常[订单前置状态错误]
        orderStatusMachineService.setSendOver(order);
        System.out.println("3: " + order.getStatus());

    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

难过的风景

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值