/**
* Copyright (c) 2017 Avant-Port All Rights Reserved.
*/
package com.avp.mem.njpb.config;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.repository.Deployment;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import java.util.List;
/**
* 初始化Activiti配置
* * @author Amber
*/
@Component
public class ActivitiInitConfig {
protected static final Logger LOGGER = LoggerFactory.getLogger(ActivitiInitConfig.class);
@Autowired
protected RepositoryService repositoryService;
@PostConstruct
public void init() {
initProcessDefinitions();
initProcess();
}
/**
* 为了让Activiti引擎知道这个流程,我们必须先进行“发布”。
* 发布意味着引擎会把BPMN 2.0 xml解析成可以执行的东西, “发布包”中的所有流程定义都会添加到数据库中。
* 这样,当引擎重启时,它依然可以获得“已发布”的流程。
*/
protected void initProcessDefinitions() {
String deploymentName = "workorder processes";
List<Deployment> deploymentList = repositoryService.createDeploymentQuery().deploymentName(deploymentName).list();
if (deploymentList == null || deploymentList.isEmpty()) {
Deployment deployment = repositoryService.createDeployment()
.name(deploymentName)
.addClasspathResource("diagrams/workorder/workorder.bpmn")
.deploy();
LOGGER.debug("流程【{}】发布成功,流程ID为:{}", deploymentName, deployment.getId());
}
}
}
/**
* Copyright (c) 2017 Avant-Port All Rights Reserved.
*/
package com.avp.mem.njpb.config.handler;
import org.activiti.engine.IdentityService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.delegate.DelegateTask;
import org.activiti.engine.delegate.TaskListener;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
/**
* Created by Amber Wang on 2017-08-18 下午 06:04.
*/
@Component
public class CustomCreateEventHandler implements TaskListener {
private static final Logger LOGGER = LoggerFactory.getLogger(CustomCreateEventHandler.class);
@Autowired
private IdentityService identityService;
@Autowired
private RuntimeService runtimeService;
@PostConstruct
void init() {
LOGGER.debug("bean customCreateEventHandler is creating...");
}
/**
* 监听每个task的create事件
*
* @param delegateTask
*/
@Override
public void notify(DelegateTask delegateTask) {
String assignEmployee = (String) runtimeService.getVariable(delegateTask.getExecutionId(), "taskAssignEmployee");
String processInstanceId = delegateTask.getProcessInstanceId();
String taskDefinitionKey = delegateTask.getTaskDefinitionKey();
String currentActivityId = delegateTask.getExecution().getCurrentActivityId();
LOGGER.debug("流程id为:{},taskDefinitionKey:{},currentActivityId:{},assignEmployee:{}", processInstanceId, taskDefinitionKey, currentActivityId, assignEmployee);
delegateTask.setAssignee(assignEmployee);
}
}
/**
* Copyright (c) 2017 Avant-Port All Rights Reserved.
*/
package com.avp.mem.njpb.config.handler;
import com.avp.mem.njpb.entity.workorder.ObjWorkOrder;
import com.avp.mem.njpb.repository.workorder.ObjWorkOrderRepository;
import org.activiti.engine.IdentityService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.delegate.DelegateExecution;
import org.activiti.engine.delegate.ExecutionListener;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
/**
* Created by Amber Wang on 2017-08-18 下午 06:04.
*/
@Component
public class CustomTakeEventHandler implements ExecutionListener {
private static final Logger LOGGER = LoggerFactory.getLogger(CustomTakeEventHandler.class);
@Autowired
private IdentityService identityService;
@Autowired
private RuntimeService runtimeService;
@Autowired
private ObjWorkOrderRepository objWorkOrderRepository;
@PostConstruct
void init() {
LOGGER.debug("bean customTakeEventHandler is creating...");
}
@Override
public void notify(DelegateExecution delegateExecution) throws Exception {
String processInstanceId = delegateExecution.getProcessInstanceId();
LOGGER.debug("take事件触发,流程id为:{}", processInstanceId);
ObjWorkOrder objWorkOrder = objWorkOrderRepository.findByProcessInstanceId(processInstanceId);
Integer assignEmployee = objWorkOrder.getAssignEmployee();
LOGGER.debug("工单:{}的调度人为:{}", objWorkOrder.getId(), assignEmployee);
delegateExecution.setVariable("taskAssignEmployee", assignEmployee);
}
}
- service中启动流程、获取流程下一步操作、完成节点task
package com.avp.mem.njpb.service.activiti
import com.avp.mem.njpb.entity.stock.ObjStockWorkOrder
import com.avp.mem.njpb.entity.workorder.ObjWorkOrder
import com.avp.mem.njpb.util.Validator
import org.activiti.engine.FormService
import org.activiti.engine.RepositoryService
import org.activiti.engine.RuntimeService
import org.activiti.engine.TaskService
import org.activiti.engine.IdentityService
import org.activiti.engine.impl.RepositoryServiceImpl
import org.activiti.engine.impl.persistence.entity.ProcessDefinitionEntity
import org.activiti.engine.impl.pvm.PvmActivity
import org.activiti.engine.impl.pvm.PvmTransition
import org.activiti.engine.impl.pvm.process.ActivityImpl
import org.activiti.engine.runtime.ProcessInstance
import org.activiti.engine.task.Task
import org.slf4j.Logger
import org.slf4j.LoggerFactory
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.beans.factory.annotation.Value
import org.springframework.stereotype.Service
import org.springframework.transaction.annotation.Transactional
import java.util.ArrayList
import java.util.HashMap
import java.util.List
import java.util.Map
@Service
@Transactional
public class ActivitiService {
private static Logger LOGGER = LoggerFactory.getLogger(WorkOrderWorkflowService.class)
@Autowired
protected RepositoryService repositoryService
@Autowired
protected FormService formService
@Autowired
protected RuntimeService runtimeService
@Autowired
protected TaskService taskService
@Autowired
protected IdentityService identityService
@Value("${business.service.processKey}")
private String repairWoProcessKey
@Value("${business.service.processKeyOfStock}")
private String stockWoProcessKey
public String startRepairWorkflow(ObjWorkOrder entity) {
String businessKey = entity.getId().toString()
ProcessInstance processInstance = null
String processInstanceId = ""
try {
// 用来设置启动流程的人员ID,引擎会自动把用户ID保存到activiti:initiator中
identityService.setAuthenticatedUserId(entity.getCreateBy().toString())
Map<String, Object> params = new HashMap<>()
params.put("taskAssignEmployee", entity.getAssignEmployee().toString())
processInstance = runtimeService.startProcessInstanceByKey(repairWoProcessKey, businessKey, params)
processInstanceId = processInstance.getId()
LOGGER.debug("start process of key={}, businessKey={}, processInstanceId={}", entity.getId(), businessKey, processInstanceId)
} finally {
identityService.setAuthenticatedUserId(null)
}
return processInstanceId
}
public List<String> getTaskOperation(String processInstanceId) throws Exception {
List<String> nextOperation = new ArrayList<>()
Task task = taskService.createTaskQuery().processInstanceId(processInstanceId).singleResult()
if (Validator.isNull(task)) {
LOGGER.debug("该流程:{}已经完成", processInstanceId)
return nextOperation
}
String activityId = task.getTaskDefinitionKey()
ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId)
.singleResult()
ProcessDefinitionEntity processDefinition = (ProcessDefinitionEntity) ((RepositoryServiceImpl) repositoryService)
.getDeployedProcessDefinition(processInstance.getProcessDefinitionId())
// ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId)
// .singleResult()
// ProcessDefinitionEntity processDefinition = (ProcessDefinitionEntity) ((RepositoryServiceImpl) repositoryService)
// .getDeployedProcessDefinition(processInstance.getProcessDefinitionId())
ActivityImpl activityImpl = processDefinition.findActivity(activityId)
List<PvmTransition> outTransitions = activityImpl.getOutgoingTransitions()
for (PvmTransition tr : outTransitions) {
String type = (String) tr.getDestination().getProperty("type")
if ("exclusiveGateway".equals(type)) {
//说明是网关
PvmActivity ac = tr.getDestination()
System.out.println("下一步任务任务:" + ac.getProperty("name"))
List<PvmTransition> pvmTransitions = ac.getOutgoingTransitions()
pvmTransitions.forEach(pvmTransition -> {
LOGGER.debug("网关的操作为:{}", pvmTransition.getId())
nextOperation.add(pvmTransition.getId())
})
} else if ("userTask".equals(type) || "endEvent".equals(type)) {
//TODO 判断是task获取当前的flowid
LOGGER.debug("节点类型是userTask或者endEvent,flow ID是:{}", tr.getId())
nextOperation.add(tr.getId())
}
}
return nextOperation
}
public void completeTask(Map<String, Object> taskVariables, String processInstanceId) {
taskVariables.forEach((k, v) -> System.out.println("task参数----> key : " + k + " value : " + v))
// 设置当前任务信息
Task task = taskService.createTaskQuery().processInstanceId(processInstanceId).active().orderByTaskCreateTime().desc().singleResult()
LOGGER.debug("task:{},名称为:{}", task.getId(), task.getName())
taskService.complete(task.getId(), taskVariables)
LOGGER.debug("Task:{}完成,参数为:{}", task.getId(), taskVariables.toString())
}
}
- ActivitiController(使用不大,只用于重新部署流程)
package com.avp.mem.njpb.controller
import com.avp.mem.njpb.api.rest.ResponseBuilder
import com.avp.mem.njpb.api.rest.ResponseCode
import com.avp.mem.njpb.api.rest.RestBody
import com.avp.mem.njpb.config.ExtensionOperation
import com.avp.mem.njpb.entity.workorder.ObjWorkOrder
import com.avp.mem.njpb.service.activiti.ActivitiService
import com.avp.mem.njpb.util.Validator
import org.activiti.engine.FormService
import org.activiti.engine.RepositoryService
import org.activiti.engine.RuntimeService
import org.activiti.engine.TaskService
import org.activiti.engine.IdentityService
import org.activiti.engine.form.FormProperty
import org.activiti.engine.form.TaskFormData
import org.activiti.engine.impl.RepositoryServiceImpl
import org.activiti.engine.impl.persistence.entity.ProcessDefinitionEntity
import org.activiti.engine.impl.pvm.PvmActivity
import org.activiti.engine.impl.pvm.PvmTransition
import org.activiti.engine.impl.pvm.process.ActivityImpl
import org.activiti.engine.repository.Deployment
import org.activiti.engine.runtime.Execution
import org.activiti.engine.runtime.ProcessInstance
import org.activiti.engine.task.Task
import org.apache.commons.beanutils.PropertyUtils
import org.slf4j.Logger
import org.slf4j.LoggerFactory
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.http.ResponseEntity
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RequestMethod
import org.springframework.web.bind.annotation.RequestParam
import org.springframework.web.bind.annotation.RestController
import java.util.ArrayList
import java.util.HashMap
import java.util.List
import java.util.Map
@RestController
public class ActivitiController {
private static final Logger LOGGER = LoggerFactory.getLogger(ActivitiController.class)
@Autowired
protected RepositoryService repositoryService
@Autowired
protected FormService formService
@Autowired
protected RuntimeService runtimeService
@Autowired
protected TaskService taskService
@Autowired
protected IdentityService identityService
@Autowired
private ActivitiService activitiService
@RequestMapping(value = "workflows/redeploy")
public ResponseEntity<RestBody> redeployAll() {
ResponseBuilder build = ResponseBuilder.createBuilder()
try {
String deploymentName = "workorder processes"
Deployment deployment = repositoryService.createDeployment()
.name(deploymentName)
.addClasspathResource("diagrams/workorder/workorder.bpmn")
.deploy()
String deploymentId = deployment.getId()
LOGGER.debug("流程重新部署成功,流程ID:{}", deploymentId)
build.setResponseCode(ResponseCode.UPDATE_SUCCEED, "流程【" + deploymentId + "】重新部署成功")
} catch (Exception e) {
e.printStackTrace()
build.setResponseCode(ResponseCode.BAD_REQUEST, "流程重新部署失败")
}
return build.getResponseEntity()
}
@RequestMapping(value = "stockWorkflows/redeploy")
public ResponseEntity<RestBody> redeployStockAll() {
ResponseBuilder build = ResponseBuilder.createBuilder()
try {
String deploymentNameOfStock = "stockWorkOrder processes"
Deployment deployment = repositoryService.createDeployment()
.name(deploymentNameOfStock)
.addClasspathResource("diagrams/workorder/stockWorkOrder.bpmn")
.deploy()
String deploymentId = deployment.getId()
LOGGER.debug("流程重新部署成功,流程ID:{}", deploymentId)
build.setResponseCode(ResponseCode.UPDATE_SUCCEED, "流程【" + deploymentId + "】重新部署成功")
} catch (Exception e) {
e.printStackTrace()
build.setResponseCode(ResponseCode.BAD_REQUEST, "流程重新部署失败")
}
return build.getResponseEntity()
}
@RequestMapping(value = "workflows/getTaskByRole")
public ResponseEntity<RestBody> getTaskByRole(String role) {
ResponseBuilder build = ResponseBuilder.createBuilder()
try {
List<Task> tasks = taskService.createTaskQuery().taskCandidateGroup(role).list()
for (Task task : tasks) {
LOGGER.debug("Following task is available for sales group:{},group is :{}", task.getName(), role)
//为工单表中存放的id
String processInstanceId = task.getProcessInstanceId()
LOGGER.debug("工单中的流程id为:{}", processInstanceId)
}
} catch (Exception e) {
e.printStackTrace()
build.setResponseCode(ResponseCode.BAD_REQUEST, "流程重新部署失败")
}
return build.getResponseEntity()
}
//获取当前人的任务
@RequestMapping(value = "/tasks", method = RequestMethod.GET)
public List<Map<String, Object>> getTasks(@RequestParam String assignee) {
List<Task> tasks = taskService.createTaskQuery().taskAssignee(assignee).list()
List<Map<String, Object>> dtos = new ArrayList<>()
for (Task task : tasks) {
Map<String, Object> map = new HashMap<>()
map.put(task.getId(), task.getName())
dtos.add(map)
}
return dtos
}
}
<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:activiti="http://activiti.org/bpmn"
xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI"
xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC" xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI"
typeLanguage="http://www.w3.org/2001/XMLSchema" expressionLanguage="http://www.w3.org/1999/XPath"
targetNamespace="http://www.activiti.org/test">
<process id="process-workorder" name="工单流程" isExecutable="true">
<startEvent id="startevent" name="Start"></startEvent>
<userTask id="usertask_report_check" name="报修审核">
<extensionElements>
<activiti:taskListener event="create"
delegateExpression="${customCreateEventHandler}"></activiti:taskListener>
</extensionElements>
</userTask>
<userTask id="usertask_modify_report" name="调整报修内容">
<extensionElements>
<activiti:taskListener event="create"
delegateExpression="${customCreateEventHandler}"></activiti:taskListener>
</extensionElements>
</userTask>
<userTask id="usertask_repair_check" name="维修审核">
<extensionElements>
<activiti:taskListener event="create"
delegateExpression="${customCreateEventHandler}"></activiti:taskListener>
</extensionElements>
</userTask>
<userTask id="usertask_confirm_wo" name="工单确认">
<extensionElements>
<activiti:taskListener event="create"
delegateExpression="${customCreateEventHandler}"></activiti:taskListener>
</extensionElements>
</userTask>
<userTask id="usertask_reAssign" name="工单再次派发" activiti:assignee="${woAssignEmployee}">
</userTask>
<userTask id="usertask_repair" name="工单维修">
<extensionElements>
<activiti:taskListener event="create"
delegateExpression="${customCreateEventHandler}"></activiti:taskListener>
</extensionElements>
</userTask>
<userTask id="usertask_sign_in" name="工单签到">
<extensionElements>
<activiti:taskListener event="create"
delegateExpression="${customCreateEventHandler}"></activiti:taskListener>
</extensionElements>
</userTask>
<endEvent id="endevent" name="End"></endEvent>
<exclusiveGateway id="exclusivegateway_reportCheck" name="Exclusive Gateway1"></exclusiveGateway>
<exclusiveGateway id="exclusivegateway_reReport" name="Parallel Gateway"></exclusiveGateway>
<sequenceFlow id="flow_reportWo" name="报修" sourceRef="startevent"
targetRef="usertask_report_check"></sequenceFlow>
<sequenceFlow id="flow_report_agree" name="报修审核同意" sourceRef="exclusivegateway_reportCheck"
targetRef="usertask_confirm_wo">
<conditionExpression xsi:type="tFormalExpression"><![CDATA[${groupLeaderPassReport}]]></conditionExpression>
</sequenceFlow>
<sequenceFlow id="flow2" sourceRef="usertask_report_check"
targetRef="exclusivegateway_reportCheck"></sequenceFlow>
<sequenceFlow id="flow_report_reject" name="报修审核不同意" sourceRef="exclusivegateway_reportCheck"
targetRef="usertask_modify_report">
<conditionExpression xsi:type="tFormalExpression">
<![CDATA[${!groupLeaderPassReport}]]></conditionExpression>
</sequenceFlow>
<sequenceFlow id="flow_endReport" name="结束报修流程" sourceRef="exclusivegateway_reReport" targetRef="endevent">
<conditionExpression xsi:type="tFormalExpression"><![CDATA[${!repeatReport}]]></conditionExpression>
</sequenceFlow>
<sequenceFlow id="flow6" sourceRef="usertask_modify_report"
targetRef="exclusivegateway_reReport"></sequenceFlow>
<sequenceFlow id="flow_reReport" name="重新报修" sourceRef="exclusivegateway_reReport"
targetRef="usertask_report_check">
<conditionExpression xsi:type="tFormalExpression"><![CDATA[${repeatReport}]]></conditionExpression>
</sequenceFlow>
<sequenceFlow id="flow_reAssign" name="再次派发" sourceRef="usertask_reAssign"
targetRef="usertask_confirm_wo"></sequenceFlow>
<sequenceFlow id="flow_repair_check" name="工单完成" sourceRef="usertask_repair_check" targetRef="endevent"></sequenceFlow>
<sequenceFlow id="flow_repair_complete" name="维修完成或遗留" sourceRef="usertask_repair"
targetRef="usertask_repair_check"></sequenceFlow>
<sequenceFlow id="flow_confirm_wo" name="工单确认" sourceRef="usertask_confirm_wo"
targetRef="usertask_sign_in"></sequenceFlow>
<sequenceFlow id="flow_sign_in" name="签到" sourceRef="usertask_sign_in"
targetRef="usertask_repair"></sequenceFlow>
<boundaryEvent id="boundarytimer2" name="Timer" attachedToRef="usertask_confirm_wo" cancelActivity="true">
<timerEventDefinition>
<timeDuration>${responseTimeOut_time}</timeDuration>
</timerEventDefinition>
</boundaryEvent>
<sequenceFlow id="flow_response_timeout" name="响应超时" sourceRef="boundarytimer2" targetRef="usertask_reAssign">
</sequenceFlow>
</process>
<bpmndi:BPMNDiagram id="BPMNDiagram_process-workorder">
<bpmndi:BPMNPlane bpmnElement="process-workorder" id="BPMNPlane_process-workorder">
<bpmndi:BPMNShape bpmnElement="startevent" id="BPMNShape_startevent">
<omgdc:Bounds height="35.0" width="35.0" x="1.0" y="120.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="usertask_report_check" id="BPMNShape_usertask_report_check">
<omgdc:Bounds height="60.0" width="100.0" x="113.0" y="108.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="usertask_modify_report" id="BPMNShape_usertask_modify_report">
<omgdc:Bounds height="60.0" width="100.0" x="357.0" y="335.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="usertask_repair_check" id="BPMNShape_usertask_repair_check">
<omgdc:Bounds height="60.0" width="100.0" x="1050.0" y="478.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="usertask_confirm_wo" id="BPMNShape_usertask_confirm_wo">
<omgdc:Bounds height="60.0" width="100.0" x="640.0" y="106.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="boundarytimer2" id="BPMNShape_boundarytimer2">
<omgdc:Bounds height="30.0" width="30.0" x="712.0" y="132.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="usertask_reAssign" id="BPMNShape_usertask_reAssign">
<omgdc:Bounds height="60.0" width="100.0" x="677.0" y="310.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="usertask_repair" id="BPMNShape_usertask_repair">
<omgdc:Bounds height="60.0" width="100.0" x="1090.0" y="255.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="usertask_sign_in" id="BPMNShape_usertask_sign_in">
<omgdc:Bounds height="60.0" width="100.0" x="1240.0" y="108.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="endevent" id="BPMNShape_endevent">
<omgdc:Bounds height="35.0" width="35.0" x="649.0" y="490.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="exclusivegateway_reportCheck" id="BPMNShape_exclusivegateway_reportCheck">
<omgdc:Bounds height="40.0" width="40.0" x="392.0" y="115.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="exclusivegateway_reReport" id="BPMNShape_exclusivegateway_reReport">
<omgdc:Bounds height="40.0" width="40.0" x="142.0" y="487.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge bpmnElement="flow_reportWo" id="BPMNEdge_flow_reportWo">
<omgdi:waypoint x="36.0" y="137.0"></omgdi:waypoint>
<omgdi:waypoint x="113.0" y="138.0"></omgdi:waypoint>
<bpmndi:BPMNLabel>
<omgdc:Bounds height="14.0" width="24.0" x="59.0" y="115.0"></omgdc:Bounds>
</bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="flow_report_agree" id="BPMNEdge_flow_report_agree">
<omgdi:waypoint x="432.0" y="135.0"></omgdi:waypoint>
<omgdi:waypoint x="640.0" y="136.0"></omgdi:waypoint>
<bpmndi:BPMNLabel>
<omgdc:Bounds height="14.0" width="72.0" x="488.0" y="115.0"></omgdc:Bounds>
</bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="flow2" id="BPMNEdge_flow2">
<omgdi:waypoint x="213.0" y="138.0"></omgdi:waypoint>
<omgdi:waypoint x="392.0" y="135.0"></omgdi:waypoint>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="flow_report_reject" id="BPMNEdge_flow_report_reject">
<omgdi:waypoint x="412.0" y="155.0"></omgdi:waypoint>
<omgdi:waypoint x="407.0" y="335.0"></omgdi:waypoint>
<bpmndi:BPMNLabel>
<omgdc:Bounds height="14.0" width="84.0" x="363.0" y="241.0"></omgdc:Bounds>
</bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="flow_endReport" id="BPMNEdge_flow_endReport">
<omgdi:waypoint x="182.0" y="507.0"></omgdi:waypoint>
<omgdi:waypoint x="649.0" y="507.0"></omgdi:waypoint>
<bpmndi:BPMNLabel>
<omgdc:Bounds height="14.0" width="72.0" x="357.0" y="491.0"></omgdc:Bounds>
</bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="flow6" id="BPMNEdge_flow6">
<omgdi:waypoint x="407.0" y="395.0"></omgdi:waypoint>
<omgdi:waypoint x="162.0" y="487.0"></omgdi:waypoint>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="flow_reReport" id="BPMNEdge_flow_reReport">
<omgdi:waypoint x="162.0" y="487.0"></omgdi:waypoint>
<omgdi:waypoint x="163.0" y="168.0"></omgdi:waypoint>
<bpmndi:BPMNLabel>
<omgdc:Bounds height="14.0" width="48.0" x="110.0" y="395.0"></omgdc:Bounds>
</bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="flow_reAssign" id="BPMNEdge_flow_reAssign">
<omgdi:waypoint x="677.0" y="340.0"></omgdi:waypoint>
<omgdi:waypoint x="605.0" y="344.0"></omgdi:waypoint>
<omgdi:waypoint x="690.0" y="166.0"></omgdi:waypoint>
<bpmndi:BPMNLabel>
<omgdc:Bounds height="14.0" width="48.0" x="588.0" y="273.0"></omgdc:Bounds>
</bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="flow_repair_check" id="BPMNEdge_flow_repair_check">
<omgdi:waypoint x="1050.0" y="508.0"></omgdi:waypoint>
<omgdi:waypoint x="684.0" y="507.0"></omgdi:waypoint>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="flow_repair_complete" id="BPMNEdge_flow_repair_complete">
<omgdi:waypoint x="1140.0" y="315.0"></omgdi:waypoint>
<omgdi:waypoint x="1100.0" y="478.0"></omgdi:waypoint>
<bpmndi:BPMNLabel>
<omgdc:Bounds height="14.0" width="84.0" x="1116.0" y="395.0"></omgdc:Bounds>
</bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="flow_confirm_wo" id="BPMNEdge_flow_confirm_wo">
<omgdi:waypoint x="740.0" y="136.0"></omgdi:waypoint>
<omgdi:waypoint x="1240.0" y="138.0"></omgdi:waypoint>
<bpmndi:BPMNLabel>
<omgdc:Bounds height="14.0" width="48.0" x="950.0" y="115.0"></omgdc:Bounds>
</bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="flow_sign_in" id="BPMNEdge_flow_sign_in">
<omgdi:waypoint x="1290.0" y="168.0"></omgdi:waypoint>
<omgdi:waypoint x="1140.0" y="255.0"></omgdi:waypoint>
<bpmndi:BPMNLabel>
<omgdc:Bounds height="14.0" width="24.0" x="1241.0" y="202.0"></omgdc:Bounds>
</bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="flow_response_timeout" id="BPMNEdge_flow_response_timeout">
<omgdi:waypoint x="727.0" y="162.0"></omgdi:waypoint>
<omgdi:waypoint x="820.0" y="344.0"></omgdi:waypoint>
<omgdi:waypoint x="777.0" y="340.0"></omgdi:waypoint>
<bpmndi:BPMNLabel>
<omgdc:Bounds height="14.0" width="48.0" x="752.0" y="255.0"></omgdc:Bounds>
</bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
</bpmndi:BPMNPlane>
</bpmndi:BPMNDiagram>
</definitions>
- 附录工作流流程图
- activiti版本
<dependency>
<groupId>org.activiti</groupId>
<artifactId>spring-boot-starter-basic</artifactId>
<version>5.17.0</version>
</dependency>