BPMN2.0,flowable工作流,多实例子流程的实现、动态设置多实例子流程处理人
本文介绍了基于Flowable工作流引擎的多实例子流程实现方案。针对多部门协同处理场景,通过配置子流程的multiInstanceLoopCharacteristics特性实现并行任务分配。方案包含三个关键部分:1)子流程XML配置,通过collection属性指定处理人集合;2)Java代码实现处理人分配逻辑;3)任务监听器动态调整各实例处理人。该方案支持顺序/并行执行模式,并能根据业务需求灵活
目录
前言
子流程的功能与优势
子流程通过将复杂流程拆分为多个独立阶段,帮助用户更清晰地管理和控制整体流程。这种模块化设计提升了流程的可维护性和可操作性。
多实例的应用场景
在实际业务中,多实例需求不仅限于单个活动,更常见的是对一组活动进行多实例化。例如多部门联合处置流程中,领导分派任务后需多个部门并行处置,所有部门完成处理后才能进入下一环节。这种场景下,多实例子流程能高效实现并行协作的需求。
实际案例
1、环境
前端:BPMN2.0.js
后端:flowable:6.8.0
2、流程信息
流程图(7、流程文件在文章最后):

各节点信息:
| 节点名称 | 节点类型 | 节点id |
|---|---|---|
| 开始 | 开始事件(StartEvent) | ks |
| 登记 | 用户任务(UserTask) | dj |
| 主管领导 | 用户任务(UserTask) | zgld |
| 部门内部流程 | 子流程(SubProcess) | ldsp |
| 部门开始 | 开始事件(StartEvent) | bmks |
|
部门处理员 |
用户任务(UserTask) | bmcly |
| 部门领导 | 用户任务(UserTask) | bmld |
| 部门结束 | 结束事件(EndEvent) | bmjs |
| 结束 | 结束事件(EndEvent) | js |
3、需求
【主管领导】分派任务给多个【部门内部流程】子流程后,所有【部门内部流程】处理完后才会进入到【结束】节点。
4、实现
1.【部门内部流程】子流程配置
【部门内部流程】子流程xml配置
<bpmn2:subProcess id="bmnblc" name="部门内部流程">
<bpmn2:extensionElements />
<bpmn2:incoming>ld</bpmn2:incoming>
<bpmn2:outgoing>bmjs</bpmn2:outgoing>
<bpmn2:multiInstanceLoopCharacteristics flowable:collection="${deptInsideMultiInstanceHandler.getUserNames(execution)}" flowable:elementVariable="assignee">
<bpmn2:completionCondition xsi:type="bpmn2:tFormalExpression">${nrOfCompletedInstances >= nrOfInstances}</bpmn2:completionCondition>
</bpmn2:multiInstanceLoopCharacteristics isSequential="false">
<bpmn2:startEvent id="bmks" name="部门开始">
<bpmn2:outgoing>Flow_1ely17h</bpmn2:outgoing>
</bpmn2:startEvent>
<bpmn2:userTask id="bmcly" name="部门处理员" flowable:dataType="SUBPROCESSFIRST" flowable:assignee="${assignee}" flowable:text="实际处理人">
<bpmn2:incoming>Flow_1ely17h</bpmn2:incoming>
<bpmn2:outgoing>Flow_00zbmka</bpmn2:outgoing>
</bpmn2:userTask>
<bpmn2:sequenceFlow id="Flow_1ely17h" sourceRef="bmks" targetRef="bmcly" />
<bpmn2:userTask id="bmld" name="部门领导">
<bpmn2:incoming>Flow_00zbmka</bpmn2:incoming>
<bpmn2:outgoing>Flow_151ru34</bpmn2:outgoing>
</bpmn2:userTask>
<bpmn2:sequenceFlow id="Flow_00zbmka" name="提交" sourceRef="bmcly" targetRef="bmld" />
<bpmn2:endEvent id="Event_1thya8l" name="部门结束">
<bpmn2:incoming>Flow_151ru34</bpmn2:incoming>
</bpmn2:endEvent>
<bpmn2:sequenceFlow id="Flow_151ru34" name="提交" sourceRef="bmld" targetRef="Event_1thya8l" />
</bpmn2:subProcess>
说明:
- flowable:assignee="${assignee}":子流程中除了【开始】节点后的第一个节点需要配置,表示实际处理人指定的变量名为assignee,跟flowable:elementVariable="assignee"搭配使用。【flowable:assignee】也可以修改为【flowable:candidateGroups】,表示候选组。
- flowable:elementVariable="assignee":assignee要跟flowable:assignee占位符里面的值一致。
- isSequential="false":true表示顺序执行,false表示并行执行。
- ${nrOfCompletedInstances >= nrOfInstances}:表示完成条件为全部实例完成。
- flowable:collection="${deptInsideMultiInstanceHandler.getUserNames(execution)}":表示处理人的集合,这里调用了java代码(deptInsideMultiInstanceHandler.getUserNames方法)返回具体的处理人。下面会贴上代码。在上面的配置基础上,再加上【执行监听器】,配置如下
2.代码实现
multiInstanceHandler.getUserNames代码:
@Component("deptInsideMultiInstanceHandler")
public class DeptInsideMultiInstanceHandler {
public Set<String> getUserNames(DelegateExecution execution) {
Set<String> candidateUserNames = new LinkedHashSet<>();
// 设置三个实例,三个实例的实际处理人分别为"技术部处理员001", "产品部处理员001", "售前处理员001"
candidateUserNames.addAll(Arrays.asList("技术部处理员001", "产品部处理员001", "售前处理员001"));
//如果流程xml配置文件【flowable:assignee】修改为【flowable:candidateGroups】,则使用以下设置候选组
// 设置三个实例,三个实例的候选组分别为"ROLE123456", "ROLE456789", "DEPT456123"
//candidateUserNames.addAll(Arrays.asList("ROLE123456", "ROLE456789", "DEPT456123"));
return candidateUserNames;
}
}
以上代码设置了三个账号,表示三个实例的【部门处理员】节点处理人分别为这三个账号
3.流程文件
flowable.xml:
<?xml version="1.0" encoding="UTF-8"?>
<bpmn2:definitions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:bpmn2="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" xmlns:flowable="http://flowable.org/bpmn" id="diagram_Process_1761616908502" targetNamespace="http://flowable.org/bpmn" xsi:schemaLocation="http://www.omg.org/spec/BPMN/20100524/MODEL BPMN20.xsd">
<bpmn2:process id="Process_1761616908502" name="分派流程" isExecutable="true">
<bpmn2:startEvent id="ks" name="开始">
<bpmn2:outgoing>Flow_0zttbj2</bpmn2:outgoing>
</bpmn2:startEvent>
<bpmn2:userTask id="zgld" name="主管领导" flowable:dataType="INITIATOR" flowable:assignee="${initiator}" flowable:text="流程发起人">
<bpmn2:incoming>fq</bpmn2:incoming>
<bpmn2:outgoing>ld</bpmn2:outgoing>
</bpmn2:userTask>
<bpmn2:endEvent id="js" name="结束">
<bpmn2:incoming>bmjs</bpmn2:incoming>
</bpmn2:endEvent>
<bpmn2:sequenceFlow id="bmjs" name="提交" sourceRef="bmnblc" targetRef="js" />
<bpmn2:sequenceFlow id="fq" name="发起" sourceRef="dj" targetRef="zgld" />
<bpmn2:sequenceFlow id="ld" name="分派" sourceRef="zgld" targetRef="bmnblc" />
<bpmn2:userTask id="dj" name="登记" flowable:dataType="INITIATOR" flowable:assignee="${initiator}" flowable:text="流程发起人">
<bpmn2:incoming>Flow_0zttbj2</bpmn2:incoming>
<bpmn2:outgoing>fq</bpmn2:outgoing>
</bpmn2:userTask>
<bpmn2:sequenceFlow id="Flow_0zttbj2" sourceRef="ks" targetRef="dj" />
<bpmn2:subProcess id="bmnblc" name="部门内部流程">
<bpmn2:extensionElements />
<bpmn2:incoming>ld</bpmn2:incoming>
<bpmn2:outgoing>bmjs</bpmn2:outgoing>
<bpmn2:multiInstanceLoopCharacteristics flowable:collection="${deptInsideMultiInstanceHandler.getUserNames(execution)}" flowable:elementVariable="assignee">
<bpmn2:completionCondition xsi:type="bpmn2:tFormalExpression">${nrOfCompletedInstances >= nrOfInstances}</bpmn2:completionCondition>
</bpmn2:multiInstanceLoopCharacteristics>
<bpmn2:startEvent id="bmks" name="部门开始">
<bpmn2:outgoing>Flow_1ely17h</bpmn2:outgoing>
</bpmn2:startEvent>
<bpmn2:userTask id="bmcly" name="部门处理员" flowable:dataType="SUBPROCESSFIRST" flowable:assignee="${assignee}" flowable:text="实际处理人">
<bpmn2:incoming>Flow_1ely17h</bpmn2:incoming>
<bpmn2:outgoing>Flow_00zbmka</bpmn2:outgoing>
</bpmn2:userTask>
<bpmn2:sequenceFlow id="Flow_1ely17h" sourceRef="bmks" targetRef="bmcly" />
<bpmn2:userTask id="bmld" name="部门领导">
<bpmn2:incoming>Flow_00zbmka</bpmn2:incoming>
<bpmn2:outgoing>Flow_151ru34</bpmn2:outgoing>
</bpmn2:userTask>
<bpmn2:sequenceFlow id="Flow_00zbmka" name="提交" sourceRef="bmcly" targetRef="bmld" />
<bpmn2:endEvent id="Event_1thya8l" name="部门结束">
<bpmn2:incoming>Flow_151ru34</bpmn2:incoming>
</bpmn2:endEvent>
<bpmn2:sequenceFlow id="Flow_151ru34" name="提交" sourceRef="bmld" targetRef="Event_1thya8l" />
</bpmn2:subProcess>
</bpmn2:process>
<bpmndi:BPMNDiagram id="BPMNDiagram_1">
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Process_1761616908502">
<bpmndi:BPMNEdge id="Flow_0zttbj2_di" bpmnElement="Flow_0zttbj2">
<di:waypoint x="-32" y="239" />
<di:waypoint x="60" y="239" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="ld_di" bpmnElement="ld">
<di:waypoint x="260" y="279" />
<di:waypoint x="260" y="385" />
<di:waypoint x="360" y="385" />
<bpmndi:BPMNLabel>
<dc:Bounds x="269" y="325" width="22" height="14" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="fq_di" bpmnElement="fq">
<di:waypoint x="160" y="239" />
<di:waypoint x="210" y="239" />
<bpmndi:BPMNLabel>
<dc:Bounds x="169" y="213" width="22" height="14" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="bmjs_di" bpmnElement="bmjs">
<di:waypoint x="930" y="385" />
<di:waypoint x="1000" y="385" />
<di:waypoint x="1000" y="257" />
<bpmndi:BPMNLabel>
<dc:Bounds x="959" y="364" width="22" height="14" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
<bpmndi:BPMNShape id="ks_di" bpmnElement="ks">
<dc:Bounds x="-68" y="221" width="36" height="36" />
<bpmndi:BPMNLabel>
<dc:Bounds x="-60" y="264" width="22" height="14" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="zgld_di" bpmnElement="zgld">
<dc:Bounds x="210" y="199" width="100" height="80" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="js_di" bpmnElement="js">
<dc:Bounds x="982" y="221" width="36" height="36" />
<bpmndi:BPMNLabel>
<dc:Bounds x="989" y="197" width="22" height="14" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="dj_di" bpmnElement="dj">
<dc:Bounds x="60" y="199" width="100" height="80" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="bmnblc_di" bpmnElement="bmnblc" isExpanded="true">
<dc:Bounds x="360" y="310" width="570" height="150" />
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge id="Flow_151ru34_di" bpmnElement="Flow_151ru34">
<di:waypoint x="760" y="390" />
<di:waypoint x="822" y="390" />
<bpmndi:BPMNLabel>
<dc:Bounds x="780" y="372" width="22" height="14" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="Flow_00zbmka_di" bpmnElement="Flow_00zbmka">
<di:waypoint x="600" y="390" />
<di:waypoint x="660" y="390" />
<bpmndi:BPMNLabel>
<dc:Bounds x="619" y="372" width="22" height="14" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="Flow_1ely17h_di" bpmnElement="Flow_1ely17h">
<di:waypoint x="448" y="390" />
<di:waypoint x="500" y="390" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNShape id="bmks_di" bpmnElement="bmks">
<dc:Bounds x="411.66666666666674" y="372" width="36" height="36" />
<bpmndi:BPMNLabel>
<dc:Bounds x="408" y="415" width="44" height="14" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="bmcly_di" bpmnElement="bmcly">
<dc:Bounds x="500" y="350" width="100" height="80" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="bmld_di" bpmnElement="bmld">
<dc:Bounds x="660" y="350" width="100" height="80" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Event_1thya8l_di" bpmnElement="Event_1thya8l">
<dc:Bounds x="822" y="372" width="36" height="36" />
<bpmndi:BPMNLabel>
<dc:Bounds x="818" y="415" width="44" height="14" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
</bpmndi:BPMNPlane>
</bpmndi:BPMNDiagram>
</bpmn2:definitions>
5、动态设置每个子流程实例的处理人
如果每个实例中第一个节点还有比较复杂的判断,可以在flowable:collection配置的接口中简单地返回每个实例特定的人员,然后在子流程第一个节点中配置【任务监听器】来设置每个实例的处理人员。
实际需求:
-
如果实际处理人是【技术部处理员001】,则设置当前实例的【部门处理员】节点的实际处理人为【技术部处理员002】
-
如果实际处理人是【产品部处理员001】,则设置当前实例的【部门处理员】节点的候选组为角色【ROLE123456】
-
如果实际处理人是【售前处理员001】,则设置当前实例的【部门处理员】节点的候选人为角色【售前处理员001】和【售前处理员002】
1.【部门处理员】节点配置
其他配置跟上面的一样,【部门处理员】节点只需要添加一个【任务监听器】即可。

2.代码实现
UserTaskDeptHandlerListener代码:
public class UserTaskDeptHandlerListener implements TaskListener {
private static final long serialVersionUID = 1L;
private TaskService taskService = SpringUtil.getBean(TaskService.class);
@Override
public void notify(DelegateTask delegateTask) {
System.out.println("执行部门内部流程-部门处理员任务监听器...start");
//获取任务ID
String taskId = delegateTask.getId();
//获取变量
Map<String, Object> variables = delegateTask.getVariables();
String assignee = delegateTask.getAssignee();//实际处理人
Set<IdentityLink> candidates = delegateTask.getCandidates();//候选组/候选人
//以下可以根据处理人判断,也可以根据候选组/候选人做判断
if(assignee != null){
switch (assignee){
case "技术部处理员001":
//如果实际处理人是【技术部处理员001】,则设置当前实例的【部门处理员】节点的实际处理人为【技术部处理员002】
taskService.setAssignee(taskId, "技术部处理员002");//设置下一个节点的处理人
break;
case "产品部处理员001":
//如果实际处理人是【产品部处理员001】,则设置当前实例的【部门处理员】节点的候选组为角色【ROLE123456】
taskService.addGroupIdentityLink(taskId, "ROLE123456", IdentityLinkType.CANDIDATE);//设置下一个节点的候选人为【ROLE123456】角色
break;
case "售前处理员001":
//如果实际处理人是【售前处理员001】,则设置当前实例的【部门处理员】节点的候选人为角色【售前处理员001】和【售前处理员002】
taskService.deleteUserIdentityLink(taskId,"售前处理员001", IdentityLinkType.ASSIGNEE);//先删除当前节点的处理人
//设置下一个节点的候选人为【售前处理员001】和【售前处理员002】
taskService.addUserIdentityLink(taskId,"售前处理员001",IdentityLinkType.CANDIDATE);
taskService.addUserIdentityLink(taskId,"售前处理员002",IdentityLinkType.CANDIDATE);
break;
}
}
System.out.println("执行部门内部流程-部门处理员任务监听器...end");
}
}
3.流程文件
flowable.xml:
<?xml version="1.0" encoding="UTF-8"?>
<bpmn2:definitions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:bpmn2="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" xmlns:flowable="http://flowable.org/bpmn" id="diagram_Process_1761616908502" targetNamespace="http://flowable.org/bpmn" xsi:schemaLocation="http://www.omg.org/spec/BPMN/20100524/MODEL BPMN20.xsd">
<bpmn2:process id="Process_1761616908502" name="分派流程" isExecutable="true">
<bpmn2:startEvent id="ks" name="开始">
<bpmn2:outgoing>Flow_0zttbj2</bpmn2:outgoing>
</bpmn2:startEvent>
<bpmn2:userTask id="zgld" name="主管领导" flowable:dataType="INITIATOR" flowable:assignee="${initiator}" flowable:text="流程发起人">
<bpmn2:incoming>fq</bpmn2:incoming>
<bpmn2:outgoing>ld</bpmn2:outgoing>
</bpmn2:userTask>
<bpmn2:endEvent id="js" name="结束">
<bpmn2:incoming>bmjs</bpmn2:incoming>
</bpmn2:endEvent>
<bpmn2:sequenceFlow id="bmjs" name="提交" sourceRef="bmnblc" targetRef="js" />
<bpmn2:sequenceFlow id="fq" name="发起" sourceRef="dj" targetRef="zgld" />
<bpmn2:sequenceFlow id="ld" name="分派" sourceRef="zgld" targetRef="bmnblc" />
<bpmn2:userTask id="dj" name="登记" flowable:dataType="INITIATOR" flowable:assignee="${initiator}" flowable:text="流程发起人">
<bpmn2:incoming>Flow_0zttbj2</bpmn2:incoming>
<bpmn2:outgoing>fq</bpmn2:outgoing>
</bpmn2:userTask>
<bpmn2:sequenceFlow id="Flow_0zttbj2" sourceRef="ks" targetRef="dj" />
<bpmn2:subProcess id="bmnblc" name="部门内部流程">
<bpmn2:extensionElements />
<bpmn2:incoming>ld</bpmn2:incoming>
<bpmn2:outgoing>bmjs</bpmn2:outgoing>
<bpmn2:multiInstanceLoopCharacteristics flowable:collection="${deptInsideMultiInstanceHandler.getUserNames(execution)}" flowable:elementVariable="assignee">
<bpmn2:completionCondition xsi:type="bpmn2:tFormalExpression">${nrOfCompletedInstances >= nrOfInstances}</bpmn2:completionCondition>
</bpmn2:multiInstanceLoopCharacteristics>
<bpmn2:startEvent id="bmks" name="部门开始">
<bpmn2:outgoing>Flow_1ely17h</bpmn2:outgoing>
</bpmn2:startEvent>
<bpmn2:userTask id="bmcly" name="部门处理员" flowable:dataType="SUBPROCESSFIRST" flowable:assignee="${assignee}" flowable:text="实际处理人">
<bpmn2:extensionElements>
<flowable:taskListener class="com.cn.workflow.flowable.listener.UserTaskDeptHandlerListener" event="create" />
</bpmn2:extensionElements>
<bpmn2:incoming>Flow_1ely17h</bpmn2:incoming>
<bpmn2:outgoing>Flow_00zbmka</bpmn2:outgoing>
</bpmn2:userTask>
<bpmn2:sequenceFlow id="Flow_1ely17h" sourceRef="bmks" targetRef="bmcly" />
<bpmn2:userTask id="bmld" name="部门领导">
<bpmn2:incoming>Flow_00zbmka</bpmn2:incoming>
<bpmn2:outgoing>Flow_151ru34</bpmn2:outgoing>
</bpmn2:userTask>
<bpmn2:sequenceFlow id="Flow_00zbmka" name="提交" sourceRef="bmcly" targetRef="bmld" />
<bpmn2:endEvent id="Event_1thya8l" name="部门结束">
<bpmn2:incoming>Flow_151ru34</bpmn2:incoming>
</bpmn2:endEvent>
<bpmn2:sequenceFlow id="Flow_151ru34" name="提交" sourceRef="bmld" targetRef="Event_1thya8l" />
</bpmn2:subProcess>
</bpmn2:process>
<bpmndi:BPMNDiagram id="BPMNDiagram_1">
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Process_1761616908502">
<bpmndi:BPMNEdge id="Flow_0zttbj2_di" bpmnElement="Flow_0zttbj2">
<di:waypoint x="-32" y="239" />
<di:waypoint x="60" y="239" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="ld_di" bpmnElement="ld">
<di:waypoint x="260" y="279" />
<di:waypoint x="260" y="385" />
<di:waypoint x="360" y="385" />
<bpmndi:BPMNLabel>
<dc:Bounds x="269" y="325" width="22" height="14" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="fq_di" bpmnElement="fq">
<di:waypoint x="160" y="239" />
<di:waypoint x="210" y="239" />
<bpmndi:BPMNLabel>
<dc:Bounds x="169" y="213" width="22" height="14" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="bmjs_di" bpmnElement="bmjs">
<di:waypoint x="930" y="385" />
<di:waypoint x="1000" y="385" />
<di:waypoint x="1000" y="257" />
<bpmndi:BPMNLabel>
<dc:Bounds x="959" y="364" width="22" height="14" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
<bpmndi:BPMNShape id="ks_di" bpmnElement="ks">
<dc:Bounds x="-68" y="221" width="36" height="36" />
<bpmndi:BPMNLabel>
<dc:Bounds x="-60" y="264" width="22" height="14" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="zgld_di" bpmnElement="zgld">
<dc:Bounds x="210" y="199" width="100" height="80" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="js_di" bpmnElement="js">
<dc:Bounds x="982" y="221" width="36" height="36" />
<bpmndi:BPMNLabel>
<dc:Bounds x="989" y="197" width="22" height="14" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="dj_di" bpmnElement="dj">
<dc:Bounds x="60" y="199" width="100" height="80" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="bmnblc_di" bpmnElement="bmnblc" isExpanded="true">
<dc:Bounds x="360" y="310" width="570" height="150" />
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge id="Flow_151ru34_di" bpmnElement="Flow_151ru34">
<di:waypoint x="760" y="390" />
<di:waypoint x="822" y="390" />
<bpmndi:BPMNLabel>
<dc:Bounds x="780" y="372" width="22" height="14" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="Flow_00zbmka_di" bpmnElement="Flow_00zbmka">
<di:waypoint x="600" y="390" />
<di:waypoint x="660" y="390" />
<bpmndi:BPMNLabel>
<dc:Bounds x="619" y="372" width="22" height="14" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="Flow_1ely17h_di" bpmnElement="Flow_1ely17h">
<di:waypoint x="448" y="390" />
<di:waypoint x="500" y="390" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNShape id="bmks_di" bpmnElement="bmks">
<dc:Bounds x="411.66666666666674" y="372" width="36" height="36" />
<bpmndi:BPMNLabel>
<dc:Bounds x="408" y="415" width="44" height="14" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="bmcly_di" bpmnElement="bmcly">
<dc:Bounds x="500" y="350" width="100" height="80" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="bmld_di" bpmnElement="bmld">
<dc:Bounds x="660" y="350" width="100" height="80" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Event_1thya8l_di" bpmnElement="Event_1thya8l">
<dc:Bounds x="822" y="372" width="36" height="36" />
<bpmndi:BPMNLabel>
<dc:Bounds x="818" y="415" width="44" height="14" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
</bpmndi:BPMNPlane>
</bpmndi:BPMNDiagram>
</bpmn2:definitions>
火山引擎开发者社区是火山引擎打造的AI技术生态平台,聚焦Agent与大模型开发,提供豆包系列模型(图像/视频/视觉)、智能分析与会话工具,并配套评测集、动手实验室及行业案例库。社区通过技术沙龙、挑战赛等活动促进开发者成长,新用户可领50万Tokens权益,助力构建智能应用。
更多推荐
所有评论(0)