Solon v3.0.9

链的构建方式(编排)

</> markdown

链的结构就是“流程图(画图)”的代码化。

画图元素:

  • 链、节点(可带任务)、连接(可带条件)

画图规则(或定义):

  • 一个链(Chain),会有多个节点(Node)组成。
  • 一个节点(Node),会有多个连接(Link,也叫“流出连接”)连向别的节点。连接向其它节点,称为:流出连接。被其它节点连接,称为:流入连接。
  • 一个链从一个 start 类型的节点开始,顺着连接(Link)流出

通俗些,就是通过 “点”(节点) + “线”(连接)来描述一个流程图结构。

1、使用配置构建(支持 json 或 yml)

  • 示例1 demo1.chain.yml(简单示例)。
id: "d1"
nodes:
  - { id: "n1", type: "start", link: "n2"}
  - { id: "n2", type: "execute", link: "n3", task: "System.out.println(\"hello world!\");"}
  - { id: "n3", type: "end"}
  • 示例2 demo2.chain.yml(审批风格)。示例中,使用了元信息和空任务(用于触发驱动器的任务处理)。
id: "d2"
title: "请假审批"
nodes:
- { id: "s", type: "start", title: "发起人", meta: {role: "employee", form: "form1"}, link: "n1"}
- { id: "n1", type: "execute", title: "主管批", meta: {role: "tl"}, link: "g1"}
- { id: "g1", type: "exclusive", link:[
    {nextId: "e"},
    {nextId: "n2", title: "3天以上", condition: "day>=3"}]}
- { id: "n2", type: "execute", title: "部门经理批", meta: {role: "dm"}, link: "g2"}
- { id: "g2", type: "exclusive", link:[
    {nextId: "e"},
    {nextId: "n3", title: "7天以上", condition: "day>=7"}]}
- { id: "n3", type: "execute", title: "副总批", meta: {role: "vp"}, link: "e"}
- { id: "e", type: "end"}


# tl: team leader; dm: department manager; vp: vice-president

示意图:

  • 示例3 demo3.chain.yml(计算风格)。示例中,使用了"@"组件型任务
id: "d3"
title: "风控计算"
nodes:
  - { id: "s", type: "start", link: "n1"}
  - { id: "n1", type: "execute", title: "基本信息评分", link: "g1", task: "@base_score"}
  - { id: "g1", type: "exclusive", title: "分流", link: [
      {nextId: "e", title: "优质用户(评分90以上)", condition: "score > 90"},
      {nextId: "n2", title: "普通用户"}]}
  - { id: "n2", type: "execute", title: "电商消费评分", link: "n3", task: "@ec_score"}
  - { id: "n3", type: "execute", title: "黑名单检测", link: "e", task: "@bl_score"}
  - { id: "e", type: "end"}

示意图:

2、链配置的简化模式

属性简化:

  • 当没有 id 属性时,会按顺序自动生成(格式示例:"n-1")
  • 当没有 link 属性时,会按顺序自动链接后一个节点(适合简单的链,复杂的需手动指定)
  • 当没有 type 属性时,缺省为 execute 节点类型

节点简化:

  • 当没有 type=start 节点时,按顺序第一个节点为开始节点
  • 当没有 type=end 节点时,不影响执行

以上面的 “简单示例” 为例,可以简化为:

id: "d1"
nodes:
  - { type: "start"}
  - { task: "System.out.println(\"hello world!\");"}
  - { type: "end"}

或者(更简)

id: "d1"
nodes:
  - { task: "System.out.println(\"hello world!\");"}

3、使用代码构建

代码构建提供了更开放的机制,意味着可以自定义配置格式(自己解析),或者分解存放到持久层。

  • 示例2(审批风格)。对就上面的配置
@Configuration
public class Demo {
    @Bean
    public void case1(FlowEngine flowEngine){
        Chain chain = new Chain("d2", "请假审批");
        
        chain.addNode(new NodeDecl("s", NodeType.start).title("发起人").metaPut("role", "employee").metaPut("form", "form1").linkAdd("n1"));
        chain.addNode(new NodeDecl("n1", NodeType.execute).title("主管批").metaPut("role", "tl").linkAdd("g1"));
        chain.addNode(new NodeDecl("g1", NodeType.exclusive)
                .linkAdd("g2", l -> l.title("3天以下"))
                .linkAdd("n2", l -> l.title("3天以上").condition("day>=3"))
        );
        chain.addNode(new NodeDecl("n2", NodeType.execute).title("部门经理批").metaPut("role", "dm").linkAdd("g2"));
        chain.addNode(new NodeDecl("g2", NodeType.exclusive)
                .linkAdd("e", l -> l.title("7天以下"))
                .linkAdd("n3", l -> l.title("7天以上").condition("day>=7"))
        );
        chain.addNode(new NodeDecl("n3", NodeType.execute).title("副总批").metaPut("role", "vp").linkAdd("e"));
        chain.addNode(new NodeDecl("e", NodeType.end));
        
        
        //配置好后,装载到引擎
        flowEngine.load(chain);
        
        //执行
        flowEngine.eval("d2", ...);
    }
}
  • 示例3(计算风格)。对就上面的配置
@Configuration
public class Demo {
    @Bean
    public void case2(FlowEngine flowEngine){
        Chain chain = new Chain("d3", "风控计算");
        
        chain.addNode(new NodeDecl("s", NodeType.start).linkAdd("n2"));
        chain.addNode(new NodeDecl("n1", NodeType.execute).title("基本信息评分").linkAdd("g1").task("@base_score"));
        chain.addNode(new NodeDecl("g1", NodeType.exclusive).title("分流")
                .linkAdd("e", l->l.title("优质用户(评分90以上)").condition("score > 90"))
                .linkAdd("n2", l->l.title("普通用户")) //没条件时,做为默认
        );
        chain.addNode(new NodeDecl("n2", NodeType.execute).title("电商消费评分").linkAdd("n3").task("@ec_score"));
        chain.addNode(new NodeDecl("n3", NodeType.execute).title("黑名单检测").linkAdd("e").task("@bl_score"));
        chain.addNode(new NodeDecl("e", NodeType.end).task("."));


        //配置好后,装载到引擎
        flowEngine.load(chain);
        
        //执行
        flowEngine.eval("d3", ...);
    }
}