IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 游戏开发 -> Java搭建订单状态机模型 -> 正文阅读

[游戏开发]Java搭建订单状态机模型

作者:token keyword

订单状态机

前言

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

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());

    }

}
  游戏开发 最新文章
6、英飞凌-AURIX-TC3XX: PWM实验之使用 GT
泛型自动装箱
CubeMax添加Rtthread操作系统 组件STM32F10
python多线程编程:如何优雅地关闭线程
数据类型隐式转换导致的阻塞
WebAPi实现多文件上传,并附带参数
from origin ‘null‘ has been blocked by
UE4 蓝图调用C++函数(附带项目工程)
Unity学习笔记(一)结构体的简单理解与应用
【Memory As a Programming Concept in C a
上一篇文章      下一篇文章      查看所有文章
加:2022-04-07 23:02:30  更:2022-04-07 23:04:15 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2025年1日历 -2025/1/16 21:02:10-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码