statefulflow - 两组接口应用演示
下面是一个行政审批的流程配置:
# classpath:flow/f1.chain.yml
id: f1
layout:
- {id: step1, title: "发起审批", meta: {actor: "刘涛", form: "form1"}}
- {id: step2, title: "抄送", meta: {cc: "吕方"}, task: "@OaMetaProcessCom"}
- {id: step3, title: "审批", meta: {actor: "陈鑫", cc: "吕方"}, task: "@OaMetaProcessCom"}
- {id: step4, title: "审批", type: "parallel", link: [step4_1, step4_2]}
- {id: step4_1, meta: {actor: "陈宇"}, link: step4_end}
- {id: step4_2, meta: {actor: "吕方"}, link: step4_end}
- {id: step4_end, type: "parallel"}
- {id: step5, title: "抄送", meta: {cc: "吕方"}, task: "@OaMetaProcessCom"}
- {id: step6, title: "结束", type: "end"}
OaMetaProcessCom 可以帮我们实现邮件抄送之类的活
@Component("OaMetaProcessCom")
public class OaMetaProcessCom implements TaskComponent {
@Override
public void run(FlowContext context, Node node) throws Throwable {
String cc = node.getMeta("cc");
if (Utils.isNotEmpty(cc)) {
//发送邮件...
}
}
}
1、断点操控场景(就是手动前进、或后退)
每个活动节点,都会被断点操控。一般使用 BlockStateController 比较合适(也可使用 ActorStateController,要注意不同状态控制器的特点)。比如开发 ai-flow 时:用户输入后,有些节点是自动前进,有些节点要停下来再等用户输出。
@Configuration
public class DemoCom {
@Bean
public StatefulFlowEngine flowEngine() {
return StatefulFlowEngine.newInstance(StatefulSimpleFlowDriver.builder()
.stateController(new BlockStateController() { //改进一下,节点可配置自动前进
@Override
public boolean isAutoForward(FlowContext context, Node node) {
return super.isAutoForward(context, node) ||
node.getMetaOrDefault("autoForward", false);
}
})
.stateRepository(new InMemoryStateRepository())
.build());
}
@Bean
public void test(StatefulFlowEngine flowEngine) {
//单步前进(上下文需要配置,实例id)
StatefulNode statefulNode = flowEngine.stepForward("c1", new FlowContext("instance-1")); //使用实例id
assert "step1".equals(statefulNode.getNode().getId());
statefulNode = flowEngine.stepForward("c1", new FlowContext("instance-1")); //使用实例id
assert "step2".equals(statefulNode.getNode().getId());
}
}
2、等待介入场景
这个场景就是把前进或后退分为3个步骤:
- 先获取节点状态
- 参与者介入
- 再根据介入情况提交状态
这个场景,有参与者配置的,才会被要求介入(没有人员配置时,会自动前进)。一般使用 ActorStateController 比较合适。
@Configuration
public class DemoCom {
@Bean
public StatefulFlowEngine flowEngine() {
return StatefulFlowEngine.newInstance(StatefulSimpleFlowDriver.builder()
.stateController(new ActorStateController("actor")) //参与者配置,可多个。比如:userId, roleId...
.stateRepository(new InMemoryStateRepository())
.build());
}
@Bean
public void test(StatefulFlowEngine flowEngine) {
FlowContext context;
StatefulNode statefulNode;
context = new FlowContext("instance-1").put("actor", "刘涛"); //使用实例id
statefulNode = flowEngine.getActivityNode("c1", context);
assert "step1".equals(statefulNode.getNode().getId());
assert StateType.WAITING == statefulNode.getState();
//等待当前用户处理
flowEngine.postActivityState(context, statefulNode.getNode(), StateType.COMPLETED);
//-----------
context = new FlowContext("instance-1").put("actor", "陈鑫"); //使用实例id
statefulNode = flowEngine.getActivityNode("c1", context);
assert "step3".equals(statefulNode.getNode().getId());
assert StateType.WAITING == statefulNode.getState();
//等待当前用户处理
flowEngine.postActivityState(context, statefulNode.getNode(), StateType.COMPLETED);
}
}
3、实现自动流转与阻断结合
重写 StateController 的 isAutoForward 方法,比如实现:有 "autoForward: true" 的元信息配置,则自动前进。
@Configuration
public class DemoCom {
@Bean
public StatefulFlowEngine flowEngine() {
return StatefulFlowEngine.newInstance(StatefulSimpleFlowDriver.builder()
.stateController(new BlockStateController() {
@Override
public boolean isAutoForward(FlowContext context, Node node) {
return super.isAutoForward(context, node) ||
node.getMetaOrDefault("autoForward", false);
}
})
.stateRepository(new InMemoryStateRepository())
.build());
}
}
配置效果(注意 autoForward)
# classpath:flow/f1.chain.yml
id: f1
layout:
- {id: step1, title: "发起审批", meta: {actor: "刘涛", form: "form1"}}
- {id: step2, title: "抄送", meta: {cc: "吕方", autoForward: true}, task: "@OaMetaProcessCom"}
- {id: step3, title: "审批", meta: {actor: "陈鑫", cc: "吕方"}, task: "@OaMetaProcessCom"}
- {id: step4, title: "审批", type: "parallel", link: [step4_1, step4_2]}
- {id: step4_1, meta: {actor: "陈宇"}, link: step4_end}
- {id: step4_2, meta: {actor: "吕方"}, link: step4_end}
- {id: step4_end, type: "parallel"}
- {id: step5, title: "抄送", meta: {cc: "吕方"}, task: "@OaMetaProcessCom"}
- {id: step6, title: "结束", type: "end"}