activiti超時自動審批


有時候業務需求,我們得定時或者是多久以後處理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--------------------------");
	}

}



發佈了44 篇原創文章 · 獲贊 34 · 訪問量 13萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章