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