activiti超时自动审批

  • Post author:
  • Post category:其他




有时候业务需求,我们得定时或者是多久以后处理task,最近项目就有个这种场景,当流程到某个节点以后,过多久未处理自动流转到下一个节点、activiti自身



是支持这种业务场景的。




这里给个简单的示例



流程图:








xml文件:


<?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="testTimer" name="Test timer" isExecutable="true">
    <startEvent id="startevent1" name="Start"></startEvent>
    <userTask id="usertask1" name="节点1" activiti:assignee="1"></userTask>
    <userTask id="usertask2" name="节点2" activiti:assignee="${userId}"></userTask>
    <boundaryEvent id="boundarytimer1" name="Timer" attachedToRef="usertask1" cancelActivity="true">
      <timerEventDefinition>
        <timeDuration>${duTime}</timeDuration>
      </timerEventDefinition>
    </boundaryEvent>
    <sequenceFlow id="flow1" name="超时" sourceRef="boundarytimer1" targetRef="usertask2">
      <extensionElements>
        <activiti:executionListener event="take" class="FlowTakeListener"></activiti:executionListener>
      </extensionElements>
    </sequenceFlow>
    <sequenceFlow id="flow2" sourceRef="startevent1" targetRef="usertask1"></sequenceFlow>
    <endEvent id="endevent1" name="End"></endEvent>
    <sequenceFlow id="flow3" sourceRef="usertask1" targetRef="endevent1"></sequenceFlow>
    <sequenceFlow id="flow4" sourceRef="usertask2" targetRef="endevent1"></sequenceFlow>
  </process>
  <bpmndi:BPMNDiagram id="BPMNDiagram_testTimer">
    <bpmndi:BPMNPlane bpmnElement="testTimer" id="BPMNPlane_testTimer">
      <bpmndi:BPMNShape bpmnElement="startevent1" id="BPMNShape_startevent1">
        <omgdc:Bounds height="35.0" width="35.0" x="240.0" y="210.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="usertask1" id="BPMNShape_usertask1">
        <omgdc:Bounds height="55.0" width="105.0" x="340.0" y="200.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="boundarytimer1" id="BPMNShape_boundarytimer1">
        <omgdc:Bounds height="30.0" width="30.0" x="390.0" y="240.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="usertask2" id="BPMNShape_usertask2">
        <omgdc:Bounds height="55.0" width="105.0" x="352.0" y="380.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="endevent1" id="BPMNShape_endevent1">
        <omgdc:Bounds height="35.0" width="35.0" x="560.0" y="210.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNEdge bpmnElement="flow1" id="BPMNEdge_flow1">
        <omgdi:waypoint x="405.0" y="270.0"></omgdi:waypoint>
        <omgdi:waypoint x="404.0" y="380.0"></omgdi:waypoint>
        <bpmndi:BPMNLabel>
          <omgdc:Bounds height="14.0" width="24.0" x="415.0" y="270.0"></omgdc:Bounds>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="flow2" id="BPMNEdge_flow2">
        <omgdi:waypoint x="275.0" y="227.0"></omgdi:waypoint>
        <omgdi:waypoint x="340.0" y="227.0"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="flow3" id="BPMNEdge_flow3">
        <omgdi:waypoint x="445.0" y="227.0"></omgdi:waypoint>
        <omgdi:waypoint x="560.0" y="227.0"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="flow4" id="BPMNEdge_flow4">
        <omgdi:waypoint x="404.0" y="380.0"></omgdi:waypoint>
        <omgdi:waypoint x="577.0" y="245.0"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
    </bpmndi:BPMNPlane>
  </bpmndi:BPMNDiagram>
</definitions>



其中关键位置


<boundaryEvent id="boundarytimer1" name="Timer" attachedToRef="usertask1" cancelActivity="true">
      <timerEventDefinition>
        <timeDuration>${duTime}</timeDuration>
      </timerEventDefinition>
    </boundaryEvent>
    <sequenceFlow id="flow1" name="超时" sourceRef="boundarytimer1" targetRef="usertask2">
      <extensionElements>
        <activiti:executionListener event="take" class="FlowTakeListener"></activiti:executionListener>
      </extensionElements>
    </sequenceFlow>



boundaryEvent :定时事件    连线  flow1



timeDuration 延迟时间  即过多久触发




连线作用: 事件类型  take 即经过的时候触发对应监听



监听类的配置有多种方式 :直接指定class,代理表达式等等



而一般我们习惯在监听类中处理相关业务逻辑 比如指定下一步审批人之类的业务,通常需要用到spring管理下的bean,这样最好将监听类交由spring管理,所以这里



选择代理表达式的方式,如图:





EL表达式中的值,对应bean id



FlowTakeListener代码类似于:

@Component
public class FlowTakeListener implements ExecutionListener {

	
	/** @Fields serialVersionUID: */
	
	private static final Logger log = LoggerFactory.getLogger(FlowTakeListener.class);
	  	
	private static final long serialVersionUID = 1L;

	@Resource
	private TaskService taskService;
	
	@Resource
	private HistoryService historyService;
	
	@Resource(name="applyFormInfoService")
	private ApplyFormInfoService applyFormInfoService;
	
	@Override
	public void notify(DelegateExecution delegateExecution) throws Exception {
		// TODO Auto-generated method stub
		List<MyActivitiTask> myTasks = Lists.newArrayList();
		log.debug("-------------------------------------over time start--------------------------");
		//获取超时业务ID
		//获取超时的流程实例ID
		//String processInstanceId = delegateExecution.getProcessInstanceId();
		//获取流程历史数据
		//HistoricProcessInstance hisProcessInstance = historyService.createHistoricProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
		//获取业务主键ID
		String businessKey = delegateExecution.getProcessBusinessKey();
		log.debug("--------------------业务ID------------" + businessKey);
		//获取需要执行的任务
		List<Task> tasks = taskService.createTaskQuery().processInstanceBusinessKey(businessKey).list();
		
		for(Task task:tasks){
			MyActivitiTask myTask = new MyActivitiTask();
			myTask.setBussinessId(Long.parseLong(businessKey));
			myTask.setCreateDate(task.getCreateTime());
			myTask.setUserId(Integer.parseInt(task.getAssignee()));
			myTasks.add(myTask);
		}
		
		this.applyFormInfoService.insertApproveOvertimeRecord(myTasks);
		
		Integer approverId = this.applyFormInfoService.selectGradeAdvisorByBusId(Integer.parseInt(businessKey));
		//设置审批人
		log.debug("--------------年级主任--------" + approverId);
		delegateExecution.setVariable("userId", approverId);
		
		
		log.debug("-------------------------------------over time end--------------------------");
	}

}







版权声明:本文为jin5203344原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。