目前的项目主要有两个审批流程,在审批过程中需要发送邮件给申请人告知目前进展,此处记录下我在项目中是如何使用flowable工作流与业务相结合的。
1. 添加工作流依赖
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.0</version>
</dependency>
<!-- spring aop -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-data-rest -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-rest</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.0.9</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- 邮件服务 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.security/spring-security-web -->
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.61</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-annotations -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/org.aspectj/aspectjrt -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
</dependency>
<!-- shiro -->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.4.1</version>
</dependency>
<!-- 日志 -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
</dependency>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.6</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.poi/poi -->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>3.14</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>3.14</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.jcraft/jsch -->
<dependency>
<groupId>com.jcraft</groupId>
<artifactId>jsch</artifactId>
<version>0.1.55</version>
</dependency>
<!-- https://mvnrepository.com/artifact/commons-net/commons-net -->
<dependency>
<groupId>commons-net</groupId>
<artifactId>commons-net</artifactId>
<version>3.6</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.flowable/flowable-spring-boot-starter-process -->
<dependency>
<groupId>org.flowable</groupId>
<artifactId>flowable-spring-boot-starter-process</artifactId>
<version>6.4.0</version>
</dependency>
</dependencies>
2. 在application.yml中增加配置项
flowable:
check-process-definitions: false #设置需要手动部署工作流
3. 画流程图
设置审批候选人为固定的某个色的所有人
实际应用中,除了需要将流程完整的结束,我们通常需要跟踪业务状态,通常每个处理节点都会对应一个业务状态,此处指定方法负责更新状态和发送邮件
4. 由于每个业务系统都会有自己的用户角色权限管理,因此需要与flowable的用户组关系保持同步,一种方法是利用监听器,当业务系统编辑用户信息时就同步至flowable用户表中,另一种就是删除flowable的用户组关系表,利用视图将业务系统的用户组关系同步至flowable的用户组关系表中,并且视图名称与原flowable用户组关系表名称相同
5. 代码
###部署工作流###
@Transactional(readOnly = false)
public Object deploy (final String processName) {
logger.info("---- FlowService deploy begin ----");
final Deployment deployment = processEngine.getRepositoryService()
.createDeployment()
.addClasspathResource("processes/" + processName + ".bpmn")
.addClasspathResource("processes/" + processName + ".png")
.name(processName)
.key(processName)
.deploy();
final Map<String, Object> map = new HashMap<>();
map.put("deploymentId", deployment.getId());
map.put("deploymentKey", deployment.getKey());
map.put("deploymentName", deployment.getName());
map.put("deploymentEngineVersion", deployment.getEngineVersion());
logger.info("---- FlowService deploy end ----");
return map;
}
###查看已部署的工作流###
public Object deployedProcessList() {
logger.info("---- FlowService deployedProcess begin ----");
final List<Deployment> deploymentList = processEngine.getRepositoryService()
.createDeploymentQuery()
.orderByDeploymenTime()
.asc()
.list();
final List<Map<String, Object>> list = new ArrayList<>();
for (Deployment deployment : deploymentList) {
final Map<String, Object> map = new HashMap<>();
map.put("deploymentId", deployment.getId());
map.put("deploymentKey", deployment.getKey());
map.put("deploymentName", deployment.getName());
map.put("deploymentEngineVersion", deployment.getEngineVersion());
list.add(map);
}
logger.info("---- FlowService deployedProcess end ----");
return list;
}
/**
* 查询流程定义
* @return
*/
public Object processDefinitionList () {
logger.info("---- FlowService getProcessDefinition begin ----");
final List<ProcessDefinition> definitionList = processEngine.getRepositoryService()
.createProcessDefinitionQuery()
.list();
final List<Map<String, Object>> list = new ArrayList<>();
for (ProcessDefinition processDefinition : definitionList) {
final Map<String, Object> map = new HashMap<>();
map.put("definitionId", processDefinition.getId());
map.put("definitionKey", processDefinition.getKey());
map.put("definitionName", processDefinition.getName());
map.put("definitionDeploymentId", processDefinition.getDeploymentId());
map.put("definitionResourceName", processDefinition.getResourceName());
map.put("definitionVersion", processDefinition.getVersion());
map.put("definitionEngineVersion", processDefinition.getEngineVersion());
list.add(map);
}
logger.info("---- FlowService getProcessDefinition end ----");
return list;
}
/**
* 启动一个工作流
*
* @param processName 工作流模板 (启动最新的版本)
* @param variables 参数表
* @param user 启动人
* @return
*/
@Transactional(readOnly=false)
public String startProcess(String processName, String key, Map<String, Object> variables) {
IdentityService identityService = processEngine.getIdentityService();
identityService.setAuthenticatedUserId(UserUtils.getCurrentUser().getUserName());
logger.info("设置启动人");
RuntimeService runtimeService = processEngine.getRuntimeService();
ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(processName, key, variables);
return processInstance.getId();
}
/**
* 获取当前角色待办任务列表
* @return
*/
public Object getRoleTaskList() {
logger.info("---- FlowService getRoleTaskList begin ----");
List<Task> taskList = processEngine.getTaskService()
.createTaskQuery()
.taskCandidateGroup(UserUtils.getCurrentUser().getRoleName())
.orderByTaskCreateTime()
.asc()
.list();
final List<Map<String, Object>> list = new ArrayList<>();
for (Task task : taskList) {
final Map<String, Object> map = new HashMap<>();
map.put("taskId", task.getId());
map.put("createTime", task.getCreateTime());
map.put("taskName", task.getName());
map.put("taskOwner", task.getOwner());
map.put("processDefinitionId", task.getProcessDefinitionId());
map.put("processInstanceId", task.getProcessInstanceId());
map.put("taskDefinitionId", task.getTaskDefinitionId());
map.put("taskDefinitiionKey", task.getTaskDefinitionKey());
list.add(map);
}
logger.info("---- FlowService getRoleTaskList end ----");
return list;
}
/**
* 获取当前用户待办任务列表
* @return
*/
public Object getPersonalTaskList() {
logger.info("---- FlowService getPersonalTaskList begin ----");
final List<Task> taskList = processEngine.getTaskService()
.createTaskQuery()
.taskAssignee(UserUtils.getCurrentUser().getUserName())
.orderByTaskCreateTime()
.asc()
.list();
final List<Map<String, Object>> list = new ArrayList<>();
for (Task task : taskList) {
final Map<String, Object> map = new HashMap<>();
map.put("taskId", task.getId());
map.put("createTime", task.getCreateTime());
map.put("taskName", task.getName());
map.put("taskOwner", task.getOwner());
map.put("processDefinitionId", task.getProcessDefinitionId());
map.put("processInstanceId", task.getProcessInstanceId());
map.put("taskDefinitionId", task.getTaskDefinitionId());
map.put("taskDefinitiionKey", task.getTaskDefinitionKey());
list.add(map);
}
logger.info("---- FlowService getPersonalTaskList end ----");
return list;
}
/**
* 判断所处理的任务是否是当前用户或当前用户角色的任务
* @param taskId
* @return
*/
public boolean isPersonalTask (final String taskId) {
final String currentUserName = UserUtils.getCurrentUser().getUserName();
final Task personalTask = processEngine.getTaskService()
.createTaskQuery()
.taskAssignee(currentUserName)
.taskId(taskId)
.singleResult();
logger.info("current user name: " + currentUserName);
logger.info("taskId: " + taskId);
if (personalTask == null) {
logger.info("personalTask is null");
} else {
logger.info("personal taskId: " + personalTask.getId() + "personal assignee: " + personalTask.getAssignee());
}
if (personalTask != null && taskId.equals(personalTask.getId())) {
return true;
}
final String currentRoleName = UserUtils.getCurrentUser().getRoleName();
final Task roleTask = processEngine.getTaskService()
.createTaskQuery()
.taskCandidateGroup(currentRoleName)
.taskId(taskId)
.singleResult();
logger.info("taskId: " + taskId);
if (roleTask == null) {
logger.info("roleTask is null");
} else {
logger.info("role taskId: " + roleTask.getId() + "role assignee: " + roleTask.getAssignee());
}
if (roleTask != null && taskId.equals(taskId)) {
return true;
}
return false;
}
/**
* 获取所有未处理的任务
* @return
*/
public Object getUnresolvedTaskList() {
List<Task> taskList = processEngine.getTaskService()
.createTaskQuery()
.orderByTaskCreateTime()
.asc()
.list();
final List<Map<String, Object>> list = new ArrayList<>();
for (Task task : taskList) {
final Map<String, Object> map = new HashMap<>();
map.put("taskId", task.getId());
map.put("createTime", task.getCreateTime());
map.put("taskName", task.getName());
map.put("taskOwner", task.getOwner());
map.put("processDefinitionId", task.getProcessDefinitionId());
map.put("processInstanceId", task.getProcessInstanceId());
map.put("taskDefinitionId", task.getTaskDefinitionId());
map.put("taskDefinitiionKey", task.getTaskDefinitionKey());
list.add(map);
}
return list;
}
/**
* 签收任务
* @param taskId
* @param username
*/
@Transactional(readOnly = false)
public void claim(String taskId, String username) {
logger.info("签收任务:"+ taskId + " 签收人:" + username + " begin");
processEngine.getTaskService().claim(taskId,username);
logger.info("签收任务:"+ taskId + " 签收人:" + username + " end");
}
/**
* 执行某个流程节点
* @param taskId
* @param variables
*/
@Transactional(readOnly=false)
public void completeTask(String taskId, Map<String, Object> variables) {
if (!isPersonalTask(taskId)) {
throw new BusinessException(ExceptionEnum.EXECUTE_BASE_CHECK_EXCPTION.setExceptionMsg("请任务处理人或处理角色操作"));
}
processEngine.getTaskService().complete(taskId, variables);
logger.info("完成任务:" + taskId);
}
/**
* 执行某个流程节点, 待审批意见和附件
* @param taskId
* @param variables
* @param comment
* @param fileMap <文件路径, 文件名称>
*/
@Transactional(readOnly=false)
public void completeTask(final String taskId, final Map<String, Object> variables, final String action, String opinion, final Map<String, Object> fileMap) {
logger.info("task id: " + taskId + " ; action = " + action);
if (!isPersonalTask(taskId)) {
throw new BusinessException(ExceptionEnum.EXECUTE_BASE_CHECK_EXCPTION.setExceptionMsg("请任务处理人或处理角色操作"));
}
//添加批注时候的审核人
Authentication.setAuthenticatedUserId(UserUtils.getCurrentUser().getUserName());
final TaskService taskService = processEngine.getTaskService();
final Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
if (StringUtils.isEmpty(opinion)) {
opinion = action;
} else {
opinion = action + ": " + opinion;
}
taskService.addComment(taskId, task.getProcessInstanceId(), opinion);
if (fileMap != null) {
final Iterator it = fileMap.keySet().iterator();
while(it.hasNext()) {
final String filePath = (String) it.next();
final String fileName = (String) fileMap.get(filePath);
String suffix = "";
if (fileName.contains(".") && !fileName.endsWith(".")) {
suffix = fileName.substring(fileName.lastIndexOf(".") + 1);
} else {
if (filePath.contains(".") && !filePath.endsWith(".")) {
suffix = filePath.substring(filePath.lastIndexOf(".") + 1);
}
}
taskService.createAttachment(suffix, taskId, task.getProcessInstanceId(), fileName, null, filePath);
}
}
try {
taskService.complete(taskId, variables);
} catch (Exception e) {
logger.error("处理任务失败", e);
throw new BusinessException(ExceptionEnum.EXECUTE_BASE_CHECK_EXCPTION.setExceptionMsg("任务处理失败"));
}
logger.info("完成任务:" + taskId);
}
/**
* 获取审批历史记录
* @param processInstanceId 流程实例ID
* @return
*/
public List<ApprovalHistory> getApprovalHistory (final String processInstanceId) {
final List<ApprovalHistory> approvalHistoryList = new ArrayList<>();
//通过流程实例查询所有的(用户任务)历史活动
List<HistoricActivityInstance> historicActivityInstanceList = processEngine.getHistoryService()
.createHistoricActivityInstanceQuery()
.processInstanceId(processInstanceId)
.activityType("userTask")
.orderByHistoricActivityInstanceStartTime()
.asc()
.list();
for (HistoricActivityInstance historicActivityInstance : historicActivityInstanceList) {
final String historyTaskId = historicActivityInstance.getTaskId();
//每个节点所产生的文档
final List<Attachment> attachments = processEngine.getTaskService().getTaskAttachments(historyTaskId);
final List<HistoryFile> historyFileList = new ArrayList<>();
for (Attachment attachment : attachments) {
final HistoryFile historyFile = new HistoryFile();
historyFile.setPath(attachment.getUrl());
historyFile.setName(attachment.getName());
historyFileList.add(historyFile);
}
//每个节点的评论
final List<Comment> comments = processEngine.getTaskService().getTaskComments(historyTaskId);
if (comments != null && comments.size() > 0) {
for (Comment comment : comments) {
final ApprovalHistory approvalHistory = new ApprovalHistory();
final User user = userDao.queryByUserName(comment.getUserId());
approvalHistory.setRoleName(user.getRoleName());
approvalHistory.setUserName(user.getName() + " (" + user.getUserName() + ")");
approvalHistory.setOperateTime(comment.getTime());
approvalHistory.setOpinion(comment.getFullMessage());
approvalHistory.setTaskId(historyTaskId);
approvalHistory.setProcessInstanceId(processInstanceId);
approvalHistory.setHistoryFileList(historyFileList);
approvalHistoryList.add(approvalHistory);
}
}
}
return approvalHistoryList;
}
public List<Comment> getProcessComments(String processInstanceId) {
final List<Comment> commentList = new ArrayList<>();
//通过流程实例查询所有的(用户任务)历史活动
List<HistoricActivityInstance> historicActivityInstanceList = processEngine.getHistoryService()
.createHistoricActivityInstanceQuery()
.processInstanceId(processInstanceId)
.activityType("userTask")
.orderByHistoricActivityInstanceStartTime()
.asc()
.list();
for (HistoricActivityInstance historicActivityInstance : historicActivityInstanceList) {
final String historyTaskId = historicActivityInstance.getTaskId();
List<Comment> comments = processEngine.getTaskService().getTaskComments(historyTaskId);
if (comments != null && comments.size() > 0) {
commentList.addAll(comments);
}
}
return commentList;
}
/**
* 生成流程进展图
* @param processKey
* @param request
* @return
*/
public void genProcessDiagram(final String processInstanceId, final HttpServletResponse response) {
logger.info("---- FlowService genProcessDiagram begin ----");
final HistoryService historyService = processEngine.getHistoryService();
final RuntimeService runtimeService = processEngine.getRuntimeService();
//获得当前活动的节点
String processDefinitionId = "";
if (isFinished(processInstanceId)) {
//如果流程已经结束,则得到结束节点
HistoricProcessInstance hpi = historyService.createHistoricProcessInstanceQuery()
.processInstanceId(processInstanceId)
.singleResult();
if (hpi == null) {
throw new BusinessException(ExceptionEnum.EXECUTE_BASE_CHECK_EXCPTION.setExceptionMsg("流程定义不存在"));
}
processDefinitionId = hpi.getProcessDefinitionId();
} else {
//如果流程没有结束,则取当前活动节点
//根据流程实例ID获得当前处于活动状态的activityId合集
final ProcessInstance instance = runtimeService.createProcessInstanceQuery()
.processInstanceId(processInstanceId)
.singleResult();
if (instance == null) {
throw new BusinessException(ExceptionEnum.EXECUTE_BASE_CHECK_EXCPTION.setExceptionMsg("流程实例不存在"));
}
processDefinitionId = instance.getProcessDefinitionId();
}
final List<String> highLightedActivitis = new ArrayList<String>();
//获得活动的节点
List<HistoricActivityInstance> highLightActivityList = historyService.createHistoricActivityInstanceQuery()
.processInstanceId(processInstanceId)
.orderByHistoricActivityInstanceStartTime()
.asc()
.list();
highLightActivityList = highLightActivityList.subList(highLightActivityList.size() - 1, highLightActivityList.size());
for (HistoricActivityInstance historicActivityInstance : highLightActivityList) {
final String activityId = historicActivityInstance.getActivityId();
//判断节点是否在当前节点之前
highLightedActivitis.add(activityId);
}
//需要高亮显示的线
final List<String> flows = new ArrayList<>();
final BpmnModel bpmnModel = processEngine.getRepositoryService().getBpmnModel(processDefinitionId);
final ProcessEngineConfiguration config = processEngine.getProcessEngineConfiguration();
final ProcessDiagramGenerator diagramGenerator = config.getProcessDiagramGenerator();
final InputStream inputStream = diagramGenerator.generateDiagram(bpmnModel, "bmp", highLightedActivitis, flows, config.getActivityFontName(),
config.getLabelFontName(), config.getAnnotationFontName(), config.getClassLoader(), 1.0, true);
OutputStream outputStream = null;
byte[] buf = new byte[1024];
int legth = 0;
try {
outputStream = response.getOutputStream();
while ((legth = inputStream.read(buf)) != -1) {
outputStream.write(buf, 0, legth);
}
outputStream.flush();
} catch (IOException e) {
logger.error("生成流程图片失败", e);
throw new BusinessException(ExceptionEnum.EXECUTE_RUNTIME_EXCEPTION.setExceptionMsg("生成流程图片失败"));
} finally {
if (outputStream != null) {
try {
outputStream.close();
} catch (IOException e) {
logger.error("输出流关闭失败", e);
}
}
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
logger.error("输入流关闭失败", e);
}
}
}
logger.info("---- FlowService genProcessDiagram end ----");
}
/**
* 判断节点是否结束
* @param processInstanceId
* @return
*/
public boolean isFinished(final String processInstanceId) {
return processEngine.getHistoryService().createHistoricProcessInstanceQuery().finished().processInstanceId(processInstanceId).count() > 0;
}
/**
* 查看流程定义图
* @param deploymentId
* @param response
*/
public void viewDefinitionDiagram(final String deploymentId, final HttpServletResponse response) {
final RepositoryService repositoryService = processEngine.getRepositoryService();
final ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().deploymentId(deploymentId).singleResult();
if (processDefinition == null) {
throw new BusinessException(ExceptionEnum.EXECUTE_BASE_CHECK_EXCPTION.setExceptionMsg("流程定义不存在"));
}
InputStream inputStream = processEngine.getRepositoryService().getResourceAsStream(deploymentId, processDefinition.getDiagramResourceName());
OutputStream outputStream = null;
byte[] buf = new byte[1024];
int legth = 0;
try {
outputStream = response.getOutputStream();
while ((legth = inputStream.read(buf)) != -1) {
outputStream.write(buf, 0, legth);
}
outputStream.flush();
} catch (IOException e) {
logger.error("获取流程定义图片失败", e);
throw new BusinessException(ExceptionEnum.EXECUTE_RUNTIME_EXCEPTION.setExceptionMsg("获取流程定义图片失败"));
} finally {
if (outputStream != null) {
try {
outputStream.close();
} catch (IOException e) {
logger.error("输出流关闭失败", e);
}
}
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
logger.error("输入流关闭失败", e);
}
}
}
}
/**
* 根据 processInstanceId 获取当前的任务
* @param processInstanceId
* @return
*/
public Task findTaskByProcessInstanceId(String processInstanceId) {
final Task task = processEngine.getTaskService()
.createTaskQuery()
.processInstanceId(processInstanceId)
.singleResult();
return task;
}
/**
* 撤回,返回 taskID
* @param processInstanceId
* @return
*/
public Object withdraw(String processInstanceId) {
// final ProcessInstance processInstance = processEngine.getRuntimeService()
// .createProcessInstanceQuery()
// .processInstanceId(processInstanceId)
// .singleResult();
final TaskService taskService = processEngine.getTaskService();
final HistoryService historyService = processEngine.getHistoryService();
final RepositoryService repositoryService = processEngine.getRepositoryService();
final RuntimeService runtimeService = processEngine.getRuntimeService();
final String currentUserName = UserUtils.getCurrentUser().getUserName();
final Task task = taskService.createTaskQuery()
.processInstanceId(processInstanceId)
.singleResult();
if (task == null) {
throw new BusinessException(ExceptionEnum.EXECUTE_BASE_CHECK_EXCPTION.setExceptionMsg("流程未启动或已执行完成,无法撤回"));
}
List<HistoricTaskInstance> htiList = historyService.createHistoricTaskInstanceQuery()
.processInstanceId(processInstanceId)
.orderByTaskCreateTime()
.asc()
.list();
HistoricTaskInstance myTask = null;
for (HistoricTaskInstance historicTaskInstance : htiList) {
if(currentUserName.equals(historicTaskInstance.getAssignee())) {
myTask = historicTaskInstance;
break;
}
}
if(myTask.getId() == null) {
throw new BusinessException(ExceptionEnum.EXECUTE_BASE_CHECK_EXCPTION.setExceptionMsg("该任务非当前用户提交,无法撤回"));
}
final String processDefinitionId = myTask.getProcessDefinitionId();
final ProcessDefinitionEntity processDefinitionEntity = (ProcessDefinitionEntity) processEngine.getRepositoryService()
.createProcessDefinitionQuery()
.processDefinitionId(processDefinitionId)
.singleResult();
final BpmnModel bpmnModel = repositoryService.getBpmnModel(processDefinitionId);
//变量
Map<String, VariableInstance> variables = runtimeService.getVariableInstances(task.getExecutionId());
String myActivityId = null;
final List<HistoricActivityInstance> haiList = historyService.createHistoricActivityInstanceQuery()
.executionId(myTask.getExecutionId()).finished().list();
for(HistoricActivityInstance hai : haiList) {
if(myTask.getId().equals(hai.getTaskId())) {
myActivityId = hai.getActivityId();
break;
}
}
FlowNode myFlowNode = (FlowNode) bpmnModel.getMainProcess().getFlowElement(myActivityId);
Execution execution = runtimeService.createExecutionQuery().executionId(task.getExecutionId()).singleResult();
String activityId = execution.getActivityId();
logger.warn("------->> activityId:" + activityId);
FlowNode flowNode = (FlowNode) bpmnModel.getMainProcess().getFlowElement(activityId);
//记录原活动方向
List<SequenceFlow> oriSequenceFlows = new ArrayList<SequenceFlow>();
oriSequenceFlows.addAll(flowNode.getOutgoingFlows());
//清理活动方向
flowNode.getOutgoingFlows().clear();
//建立新方向
List<SequenceFlow> newSequenceFlowList = new ArrayList<SequenceFlow>();
SequenceFlow newSequenceFlow = new SequenceFlow();
newSequenceFlow.setId("newSequenceFlowId");
newSequenceFlow.setSourceFlowElement(flowNode);
newSequenceFlow.setTargetFlowElement(myFlowNode);
newSequenceFlowList.add(newSequenceFlow);
flowNode.setOutgoingFlows(newSequenceFlowList);
Authentication.setAuthenticatedUserId(UserUtils.getCurrentUser().getUserName());
taskService.addComment(task.getId(), task.getProcessInstanceId(), "撤回");
Map<String,Object> currentVariables = new HashMap<String,Object>();
currentVariables.put("applier", currentUserName);
//完成任务
taskService.complete(task.getId(),currentVariables);
//恢复原方向
flowNode.setOutgoingFlows(oriSequenceFlows);
return task.getId();
}
###更新流程节点状态和发送邮件###
public void updateStatus (final DelegateExecution execution, final String status) {
String businessKey = execution.getProcessInstanceBusinessKey();
//根据业务id自行处理业务表
System.out.println("业务表["+businessKey+"]状态更改成功,状态更改为:" + status + ", 流程实例ID:" + execution.getProcessInstanceId());
if (businessKey.contains(":")) {
final Integer designId = Integer.valueOf(businessKey.split(":")[1]);
final Design design = (Design) designDao.queryById(designId);
design.setStatus(status);
designDao.update(design);
if (design.getCreateUserId().equals(UserUtils.getCurrentUser().getId())) {
return;
}
//根据流程关键字和状态查找邮件模板
MailTemplate mailTemplate = mailTemplateDao.findByProcessKeyAndStatus(Constant.PROCESS_KEY_DESIGN , status);
if (mailTemplate == null) {
mailTemplate = new MailTemplate();
mailTemplate.setContent("邮件通知");
mailTemplate.setSubject("邮件通知");
}
String content = mailTemplate.getContent();
if (!StringUtils.isEmpty(content)) {
content = content.replaceAll("\\$\\{name\\}", design.getName());
}
final User user = (User) userDao.queryById(design.getCreateUserId());
mailService.sendMail(user.getEmail(), mailTemplate.getSubject(), content, execution.getProcessInstanceId());
}
}