最近接到一個用戶需求:
要求在流程部署完成後可通過手動配置各用戶任務的處理候選組,來控制流程走向。
解決此需求要解決以下問題:
1,流程部署完成後,尚未有流程實例,如何獲取所有用戶任務?
2,設置完各節點的處理候選組後,如何動態分配?
第二個問題好解決,通過設置任務監聽器,來獲取當前的用戶任務KEY,從配置表中獲取處理組進行設置。
下面來解決第一個問題,代碼如下:
@Override public List<ProcessTaskVO> findProcessUserTaskByPdId(String processDefinitionId){ List<ProcessTaskVO> processTasks = new ArrayList<ProcessTaskVO>(); if(StringUtils.isEmpty(processDefinitionId)){ return processTasks; } ProcessDefinition pd = repositoryService.createProcessDefinitionQuery().processDefinitionId(processDefinitionId).singleResult(); if(pd == null){ return processTasks; }else{ return findProcessUserTaskByPd(pd); } } private List<ProcessTaskVO> findProcessUserTaskByPd(ProcessDefinition pd){ List<ProcessTaskVO> processTasks = new ArrayList<ProcessTaskVO>(); ProcessTaskVO processTask = null; String resName = pd.getResourceName(); InputStream resouceStream =repositoryService.getResourceAsStream(pd.getDeploymentId(), resName); XMLInputFactory xif = XMLInputFactory.newInstance(); InputStreamReader in; XMLStreamReader xtr; try { in = new InputStreamReader(resouceStream, "UTF-8"); xtr = xif.createXMLStreamReader(in); BpmnModel model = new BpmnXMLConverter().convertToBpmnModel(xtr); Collection<FlowElement> flowElements = model.getMainProcess().getFlowElements(); for(FlowElement e : flowElements) { String clazz = e.getClass().toString(); if(clazz.endsWith("UserTask")){ processTask = new ProcessTaskVO(); processTask.setTaskKey(e.getId()); processTask.setTaskName(e.getName()); processTasks.add(processTask); } } } catch (XMLStreamException e) { e.printStackTrace(); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } return processTasks; }
由以上代碼可以獲取到所有的用戶任務,剩下的就是把這些信息存到數據庫中,然後寫一個配置頁面,配置用戶任務的處理組是什麼就OK了。
下面是ProcessTaskVO
public class ProcessTaskVO extends BaseVO { /** * */ private static final long serialVersionUID = 940722257892628250L; //流程實例ID private String processInsId; private String processDefinitionId; //任務名稱 private String taskName; //任務key private String taskKey; //任務ID private String taskId; private UserVO handleUser; //認領時間 private Date claimTime; private Date startTime; private Date endTime; private Map<String, Object> processVariables; public String getTaskName() { return taskName; } public void setTaskName(String taskName) { this.taskName = taskName; } public String getTaskKey() { return taskKey; } public void setTaskKey(String taskKey) { this.taskKey = taskKey; } public String getTaskId() { return taskId; } public void setTaskId(String taskId) { this.taskId = taskId; } public String getProcessInsId() { return processInsId; } public void setProcessInsId(String processInsId) { this.processInsId = processInsId; } public Date getClaimTime() { return claimTime; } public void setClaimTime(Date claimTime) { this.claimTime = claimTime; } public Date getStartTime() { return startTime; } public void setStartTime(Date startTime) { this.startTime = startTime; } public Date getEndTime() { return endTime; } public void setEndTime(Date endTime) { this.endTime = endTime; } public Map<String, Object> getProcessVariables() { return processVariables; } public void setProcessVariables(Map<String, Object> processVariables) { this.processVariables = processVariables; } public String getProcessDefinitionId() { return processDefinitionId; } public void setProcessDefinitionId(String processDefinitionId) { this.processDefinitionId = processDefinitionId; } public UserVO getHandleUser() { return handleUser; } public void setHandleUser(UserVO handleUser) { this.handleUser = handleUser; } }
下面是用戶任務與處理組的對應關係表:
CREATE TABLE `xxx_process_role` ( `id` int(11) NOT NULL AUTO_INCREMENT, `task_key` varchar(255) DEFAULT NULL COMMENT '用戶任務業務主鍵', `task_name` varchar(255) DEFAULT NULL COMMENT '用戶任務名稱', `timeout` int(11) DEFAULT NULL COMMENT '此任務的超時時間', `role_id` int(11) DEFAULT NULL COMMENT '此任務所分配的角色ID', `processdefinition_id` varchar(255) DEFAULT NULL COMMENT '流程定義ID', `create_date` date DEFAULT NULL COMMENT '創建時間', `create_user` varchar(50) DEFAULT NULL COMMENT '創建人', `update_date` date DEFAULT NULL COMMENT '更新時間', `update_user` varchar(50) DEFAULT NULL COMMENT '更新人', PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
編碼過程中的問題:
在使用任務監聽器過程中,發現監聽器中無法自動注入自己service,解決方法:
1,確保包掃描能夠掃描到任務監聽器
<!-- 掃描所有監聽 --> <context:component-scan base-package="com.xxxx.**.listener" />
2,配置任務監聽器
其中${applyTaskListener},爲任務監聽器的bean名稱
3,任務監聽器寫法:
@Service("applyTaskListener") public class ApplyTaskListener implements TaskListener{ /** * */ private static final long serialVersionUID = -7394227383264070902L; /** * 用戶查詢流程用戶任務的處理組的service */ @Autowired private IProcessTaskRoleService processTaskRoleService; @Override public void notify(DelegateTask delegateTask) { String taskKey = delegateTask.getTaskDefinitionKey(); String processDefinitionId = delegateTask.getProcessDefinitionId(); /** * 此變量含有流程發起人信息 */ Map<String,Object> variables = delegateTask.getVariables(); ProcessTaskRoleVO processTaskRole = processTaskRoleService.findByTaskKeyAndPdId(taskKey, processDefinitionId); //如未進行配置則處理人爲流程發起人 if(processTaskRole == null){ delegateTask.setAssignee(variables.get("流程發起人在變量MAP中的key").toString()); }else{ RoleVO role = processTaskRole.getRole(); if(role == null){ //如配置的角色不存在則處理人爲流程發起人 delegateTask.setAssignee(variables.get("流程發起人在變量MAP中的key").toString()); }else{ delegateTask.addCandidateGroup(role.getId().toString()); } } } }