WorkflowExecutor 是在 Solon Flow 的基础上，通过驱动定制和封装实现的轻量级工作流执行器


状态服务相关的主要接口包括：


|  主要接口                          | 描述                                                         | 
| --------------------- | ---------------------------------- |
| WorkflowExecutor         | 工作流执行器     | 
| | |
| Task                           | 工作任务   |
| TaskAction                   | 任务动作   |
| TaskState                     | 任务状态   |
| | |
| StateController               | 状态控制器接口。提供状态控制（是否可操作，是否自动前进）     | 
| StateRepository              | 状态仓库接口。提供状态保存与获取     | 




StateController 框架内提供有（也可按需定制）：


| 实现                          | 描述 |
| ----------------- | -------- | 
| BlockStateController     | 阻塞状态控制器（所有节点有权操作，类似超级管理员）     | 
| NotBlockStateController     | 不阻塞状态控制器（像无状态一样执行，除非中断，中断处可恢复执行）。v3.5.0 后支持     | 
| ActorStateController     | 参与者状态控制器（节点元数据匹配参与者后有权操作，没有配置的会自动前进）     | 


StateRepository 框架内提供有（也可按需定制）：


| 实现                          | 描述 |
| ----------------- | -------- | 
| InMemoryStateRepository     | 内存状态仓库（基于 Map 封装）     | 
| RedisStateRepository     | Redis 状态仓库（基于 Redis 封装）     | 




### 2、Task 属性



| 操作                                 | 描述                  |
| --------------------- | --------------------------------- |
| `run(context)`                     | 运行当前节点任务（如果有可执行代码？）                    |
| | |
| `getRootGraph():Graph`       | 获取根图（跨多图执行时，会有根图概念）                    |
| `getNode():Node`                | 获取当前节点（进则获取节点的元数据）                    |
| `getNodeId():String`             | 获取当前节点Id（v3.8.0 后支持）                    |
| `getState():StateType`          | 获取当前节点“状态类型”（等待、完成、等...）                    |


获取示例：

```java
//查询任务：查找下一个待处理节点，或者完结的节点
Task task = workflow.findTask("c1", FlowContext.of("i-1"));

//认领任务：权限匹配 + 状态激活（自动前进的会跳过）
//Task task = workflow.claimTask("c1", FlowContext.of("i-1"));
```


### 3、WorkflowExecutor 构建


```java
@Configuration
public class DemoCom {
    @Bean
    public WorkflowExecutor workflowOf(FlowEngine flowEngine) {
        return WorkflowExecutor.of(engine,
                new ActorStateController(), 
                new InMemoryStateRepository()); 

    }
}
```


WorkflowExecutor 一组偏“审批”场景的接口（中间需要参与者介入。一般配合 ActorStateController）：

| 接口                                                       | 描述          | 
| --------------------------------- | -------- | 
| `claimTask(...)->Task`                      | 认领任务：权限匹配 + 状态激活（自动前进的会跳过）   |
| | |
| `findTask(...)->Task`                      | 查询任务：查找下一个待处理节点，或者完结的节点   |
| | |
| `findNextTasks(...)->Collection<Task>`   | 查询下一步任务列表      |
| | |
| `submitTask(...)`                                         | 提交任务（会产生“前进”或“后退”的效果）     | 
| `submitTaskIfWaiting(...)`                             | 提交任务（会检测是否在等待参与者操作）     | 
| | |
| `getState(...)`                                              | 获取流程节点状态 |




### 4、 WorkflowExecutor 接口参考



```java
public interface WorkflowExecutor {
    static WorkflowExecutor of(FlowEngine engine, StateController stateController, StateRepository stateRepository) {
        return new WorkflowExecutorDefault(engine, stateController, stateRepository);
    }

    /**
     * 流程引擎
     */
    FlowEngine engine();

    /**
     * 状态控制器
     */
    StateController stateController();

    /**
     * 状态仓库
     */
    StateRepository stateRepository();


    /// ////////////////////////////////


    /**
     * 认领当前活动任务（权限匹配，并锁定状态为等待）
     *
     * @param graphId 图id
     * @param context 流上下文（要有人员配置）
     */
    @Nullable
    default Task claimTask(String graphId, FlowContext context) {
        return claimTask(engine().getGraphOrThrow(graphId), context);
    }

    /**
     * 认领当前活动任务（权限匹配，并锁定状态为等待）
     *
     * @param graph   图
     * @param context 流上下文（要有人员配置）
     */
    @Nullable
    Task claimTask(Graph graph, FlowContext context);

    /**
     * 寻找当前确定的任务（逻辑探测）
     *
     * @param graphId 图id
     * @param context 流上下文（要有人员配置）
     */
    @Nullable
    default Task findTask(String graphId, FlowContext context) {
        return findTask(engine().getGraphOrThrow(graphId), context);
    }

    /**
     * 寻找当前确定的任务（逻辑探测）
     *
     * @param graph   图
     * @param context 流上下文（要有人员配置）
     */
    @Nullable
    Task findTask(Graph graph, FlowContext context);

    /**
     * 寻找下一步可能的任务列表（逻辑探测）
     *
     * @param graphId 图id
     * @param context 流上下文（不需要有人员配置）
     */
    default Collection<Task> findNextTasks(String graphId, FlowContext context) {
        return findNextTasks(engine().getGraphOrThrow(graphId), context);
    }

    /**
     * 寻找下一步可能的任务列表（寻找所有可能性）
     *
     * @param graph   图
     * @param context 流上下文（逻辑探测）
     */
    Collection<Task> findNextTasks(Graph graph, FlowContext context);


    /// ////////////////////////////////

    /**
     * 获取状态
     */
    TaskState getState(Node node, FlowContext context);

    /// ////////////////////////////////

    /**
     * 提交任务（如果当前任务为等待介入）
     *
     * @param task    任务
     * @param action  动作
     * @param context 流上下文
     */
    boolean submitTaskIfWaiting(Task task, TaskAction action, FlowContext context);

    /**
     * 提交任务
     *
     * @param task    任务
     * @param action  动作
     * @param context 流上下文
     */
    default void submitTask(Task task, TaskAction action, FlowContext context) {
        submitTask(task.getRootGraph(), task.getNode(), action, context);
    }

    /**
     * 提交任务
     *
     * @param graphId 图id
     * @param nodeId  节点id
     * @param action  动作
     * @param context 流上下文
     */
    default void submitTask(String graphId, String nodeId, TaskAction action, FlowContext context) {
        submitTask(engine().getGraphOrThrow(graphId), nodeId, action, context);
    }

    /**
     * 提交任务
     *
     * @param graph   图
     * @param nodeId  节点id
     * @param action  动作
     * @param context 流上下文
     */
    default void submitTask(Graph graph, String nodeId, TaskAction action, FlowContext context) {
        submitTask(graph, graph.getNodeOrThrow(nodeId), action, context);
    }

    /**
     * 提交任务
     *
     * @param graph   图
     * @param node    节点
     * @param action  动作
     * @param context 流上下文
     */
    void submitTask(Graph graph, Node node, TaskAction action, FlowContext context);
}
```






