订单状态机
前言
在电商平台中,订单的状态是十分复杂的,并且订单状态的流转也是极其复杂并且十分严格的。
因此,我们需要定义订单状态的流转模型,并定义订单状态机模型。
我们只需对订单进行相应的状态设置即可,订单状态机内部去触发订单状态流转事件,从而进行相关的状态设置。
如果订单状态不符合(例:待付款->已发货),那么订单状态机内部判断订单前置状态不符合,不能触发相关的流转事件,从而抛出异常,设置订单状态失败。
下边是一个订单状态机的模型,此订单状态稍微有点复杂,不过也涵盖了所有的问题情况。
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;
public enum OrderStatusEnum {
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;
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;
@Configuration
@EnableStateMachine(name = "orderStatusMachine")
public class OrderStatusMachineConfig extends StateMachineConfigurerAdapter<OrderStatusEnum, OrderStatusChangeEvent> {
public void configure(StateMachineStateConfigurer<OrderStatusEnum, OrderStatusChangeEvent> orderStatusMachineConfig) throws Exception {
orderStatusMachineConfig.withStates()
.initial(OrderStatusEnum.PAY_WAIT)
.states(EnumSet.allOf(OrderStatusEnum.class));
}
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()