订单状态机

前言

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

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 100PAY_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> {@Overridepublic void write(StateMachineContext<OrderStatusEnum, OrderStatusChangeEvent> context, Order contextObj) {// 这里不做任何持久化工作}@Overridepublic 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 {@Autowiredprivate 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 = "订单前置状态错误";@Autowiredprivate 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 {@Autowiredprivate OrderStatusMachineService orderStatusMachineService;@Testvoid 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());}}

Java搭建订单状态机模型相关推荐

  1. 高德打车通用可编排订单状态机引擎设计

    一  背景 订单状态流转是交易系统的最为核心的工作,订单系统往往都会存在状态多.链路长.逻辑复杂的特点,还存在多场景.多类型.多业务维度等业务特性.在保证订单状态流转稳定性的前提下.可扩展性和可维护性 ...

  2. Python搭建Keras CNN模型破解网站验证码

    在本项目中,将会用Keras来搭建一个稍微复杂的CNN模型来破解以上的验证码.验证码如下: 利用Keras可以快速方便地搭建CNN模型,本项目搭建的CNN模型如下: 将数据集分为训练集和测试集,占比为 ...

  3. 使用C++实现一套简单的状态机模型——原理解析

    在上一文中,我们介绍了该状态机模型的使用方法.通过例子,我们发现可以使用该模型快速构建满足基本业务需求的状态机.本文我们将解析该模型的基础代码,以便大家可以根据自己状态机特点进行修改.(转载请指明出于 ...

  4. 使用C++实现一套简单的状态机模型——实例

    一般来说,"状态机"是一种表达状态转换变换逻辑的方法.曾经有人和我讨论过为什么不直接用ifelse,而要使用"状态机"去实现一些逻辑,认为使用"状态机 ...

  5. 【动态规划】状态机模型

    整理的算法模板合集: ACM模板 文章目录 A.抛砖引玉 - AcWing 1049. 大盗阿福 B.AcWing 1057. 股票买卖 IV C.AcWing 1058. 股票买卖 V D.AcWi ...

  6. Tensorflow object detection API 搭建物体识别模型

    ----------------------------------------------------先把别人博客教程跑通-------------------------------------- ...

  7. 买卖股票 状态机模型的理解

    经典讲解https://www.cnblogs.com/Bella2017/p/11277064.html 假设把某股票的价格按照时间先后顺序存储在数组中,请问买卖该股票一次可能获得的最大利润是多少? ...

  8. 状态模式的介绍及状态机模型的函数库javascript-state-machine的用法和源码解析

    文章大体就两部分: 状态模式 状态机模型的函数库javascript-state-machine的用法和源码解析 场景及问题背景: 我们平时开发时本质上就是对应用程序的各种状态进行切换并作出相应处理. ...

  9. PAT甲级1093 Count PAT‘s :[C++题解]DP、状态机模型dp

    文章目录 题目分析 题目链接 题目分析 来源:acwing 分析:统计子串"PAT"的数量. 状态机模型:本题需要的是PAT,需要选3个字母,对应三条边,需要4个状态. 下面以样例 ...

最新文章

  1. 卷积神经网络之卷积计算、作用与思想 深度学习
  2. pytorch 查看当前学习率_pytorch调整模型训练的学习率
  3. 算法工程师如何改进豆瓣电影
  4. 福玛特机器人评测_深度爆料扫地机器人地宝福玛特D820评测好不好?怎么样呢?内幕曝光测评...
  5. Java怎么重复使用套接字_在java中连续地通过套接字传输数据
  6. MySql中 delimiter 详解
  7. 2019诺贝尔化学奖: 二战老兵的传奇人生
  8. 为啥Underlay才是容器网络的最佳落地选择
  9. Vue第二部分(4): 嵌套路由和路由传参
  10. C++小白课本练习1
  11. 专业科目笔试计算机,2021年度中国证监会招考职位专业科目笔试考试大纲(计算机类)...
  12. 3分钟tips:什么是特征向量?什么是特征值?
  13. 大连理工大学计算机组织与结构实验,大连理工大学计算机系统结构实验-实验四.doc...
  14. 好看流光风格个人主页源码
  15. 信号处理--几种常见的窗函数
  16. 使用postman发送post请求,header设置问题
  17. MySQL--基于Xtrabackup+Shell+Crond实现的数据库(全量+增量)热备份方案
  18. must implement OnFragmentInteractionListener/ Fragment与Activity,Fragment与Fragment之间的信息传递
  19. Java:实现Prim算法(附完整源码)
  20. » 用HSCALE实现MySQL的数据分布式存储 江边潮未尽,枫红一季秋 -- NinGoo's blog

热门文章

  1. 服务办公软件金山偷换“核高基”重大软件专项课题名称,瞒天过海,欺骗大众...
  2. VUE超超超!入门介绍
  3. 根据离散点画直线,iOS离散点画曲线
  4. 王俊杰:苏宁AI在智慧零售上的应用
  5. 官方文档翻译《The Libra Blockchain》之执行交易(二)
  6. aux ps 和top_关于vmstat,top,ps aux查看的cpu占用率不一致的问题
  7. 全极化雷达遥感图像的迭代优化非局部均值去噪法
  8. 金融大数据分析-Jupyter-Python3-资产定价模型-CAPM
  9. 计算机控制系统的品质指标,过程控制系统的品质指标.PPT
  10. 胜不骄 败不馁 心胸似大海宽广