| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460 |
- package com.common.workflow.service.activiti;
- import java.awt.image.BufferedImage;
- import java.io.File;
- import java.io.FileOutputStream;
- import java.io.InputStream;
- import java.io.OutputStream;
- import java.text.SimpleDateFormat;
- import java.util.ArrayList;
- import java.util.Arrays;
- import java.util.HashMap;
- import java.util.List;
- import java.util.Map;
- import javax.annotation.Resource;
- import javax.imageio.ImageIO;
- import javax.servlet.http.HttpServletResponse;
- import com.common.workflow.service.dto.ActiHistoricTaskDTO;
- import org.activiti.bpmn.model.BpmnModel;
- import org.activiti.bpmn.model.FlowNode;
- import org.activiti.bpmn.model.SequenceFlow;
- import org.activiti.engine.*;
- import org.activiti.engine.delegate.DelegateExecution;
- import org.activiti.engine.history.*;
- import org.activiti.engine.impl.RepositoryServiceImpl;
- import org.activiti.engine.impl.cfg.ProcessEngineConfigurationImpl;
- import org.activiti.engine.impl.persistence.entity.ProcessDefinitionEntity;
- import org.activiti.engine.runtime.ProcessInstance;
- import org.activiti.engine.task.Task;
- import org.activiti.engine.task.TaskQuery;
- import org.activiti.image.ProcessDiagramGenerator;
- import org.apache.commons.lang3.StringUtils;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.stereotype.Service;
- @Service
- public class ActivitiService {
- @Autowired
- private RuntimeService runtimeService;
- @Autowired
- private TaskService taskService;
- @Autowired
- private HistoryService historyService;
- @Autowired
- private ProcessEngine processEngine;
- @Autowired
- private RepositoryService repositoryService;
- @Autowired
- private ProcessEngineConfigurationImpl processEngineConfiguration;
- /**
- * 启动流程
- * @param businessKey 业务id
- */
- public String startProcesses(String processKey, String businessKey, String userNames) {
- Map<String, Object> variables = new HashMap<String, Object>();
- variables.put("businessKey", businessKey);
- variables.put("recorder", userNames);
- ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(processKey, variables);
- System.out.println("流程启动成功,流程id:"+processInstance.getId());
- return processInstance.getProcessInstanceId();
- }
- /**
- *
- * <p>描述: 根据工作流Key, 用户id, 业务表Key 查询待办任务列表</p>
- */
- public void completeTask(String processKey, String businessKey, String userNames, String userId, String result, String remarks) {
- Task myTask = taskService.createTaskQuery()
- .processDefinitionKey(processKey)
- .taskCandidateOrAssigned(userId)
- //.taskAssignee(userId)
- .processVariableValueEquals("businessKey", businessKey)
- .singleResult();
- /*List<Task> testTasks = taskService.createTaskQuery()
- .processDefinitionKey(processKey)
- .taskCandidateOrAssigned(userId)
- //.taskAssignee(userId)
- .processVariableValueEquals("businessKey", businessKey)
- .list();*/
- //获取流程实例
- taskService.claim(myTask.getId(), userId);
- Map<String,Object> vars = new HashMap<String,Object>();
- vars.put("users", userNames);
- vars.put("result", Integer.parseInt(result));
- List<String> assigneeList = Arrays.asList(userNames.split(","));
- vars.put("assigneeList", assigneeList);
- //设置流程变量【基本类型】
- taskService.setVariableLocal(myTask.getId(), "businessKey", businessKey);
- taskService.setVariableLocal(myTask.getId(), "users", userNames);
- taskService.setVariableLocal(myTask.getId(), "result", Integer.parseInt(result));
- taskService.setVariableLocal(myTask.getId(), "remarks", remarks);
- taskService.complete(myTask.getId(), vars);
- //taskService.complete(myTask.getId(), vars, true);
- }
- /**
- *
- * <p>描述:任务审批 (通过/拒接) </p>
- * @author 范相如
- * @date 2018年2月25日
- * @param taskId 任务id
- * @param userId 用户id
- * @param result false OR true
- */
- /*public void completeTask(String taskId,String userId,String result, String comments) {
- //获取流程实例
- taskService.claim(taskId, userId);
- Map<String,Object> vars = new HashMap<String,Object>();
- vars.put("sign", "true");
- taskService.complete(taskId, vars);
- }*/
- /**
- *
- * <p>描述: 根据工作流Key 和 用户id查询待办任务列表</p>
- */
- public String findTasksByUserId(String processKey, String userId) {
- List<Task> resultTasks = taskService.createTaskQuery().processDefinitionKey(processKey).taskCandidateOrAssigned(userId).list();
- String businessKeys = "";
- int i = 0;
- for (Task myTask : resultTasks) {
- if(resultTasks.size()-1 == i) {
- businessKeys += taskService.getVariable(myTask.getId(), "businessKey").toString();
- } else {
- businessKeys += taskService.getVariable(myTask.getId(), "businessKey").toString()+ ",";
- }
- i++;
- }
- return businessKeys;
- }
- /**
- *
- * <p>描述: 根据工作流Key 和 用户id查询已办任务列表</p>
- */
- public String findTaskHistByUserId(String processKey, String userId) {
- List<HistoricTaskInstance> hisTaskList = historyService.createHistoricTaskInstanceQuery()
- .processDefinitionKey(processKey)
- .taskAssignee(userId)
- .orderByTaskId()
- .desc()
- .list();
- List<String> businessKeyList = new ArrayList<>();
- String businessKeys = "";
- for (HistoricTaskInstance myTask : hisTaskList) {
- List<HistoricVariableInstance> varList = historyService.createHistoricVariableInstanceQuery()
- .processInstanceId(myTask.getProcessInstanceId())
- .list();
- for(HistoricVariableInstance hisvar : varList) {
- if(hisvar.getVariableName().equals("businessKey") && !businessKeyList.contains(hisvar.getValue().toString())) {
- businessKeyList.add(hisvar.getValue().toString());
- break;
- }
- }
- }
- businessKeys = StringUtils.join(businessKeyList.toArray(), ",");
- return businessKeys;
- }
- /**
- * 查询当前用户的待办任务
- * @param processDefinitionKey 流程定义key(流程定义的标识)
- * @param assignee 任务负责人
- * @return
- */
- /*public List<Task> findTasks(String processDefinitionKey, String assignee) {
- //创建查询对象
- TaskQuery taskQuery = taskService.createTaskQuery();
- //设置查询条件
- taskQuery.taskAssignee(assignee);
- //指定流程定义key,只查询某个流程的任务
- taskQuery.processDefinitionKey(processDefinitionKey);
- //获取查询列表
- List<Task> list = taskQuery.list();
- return list;
- }*/
- public List<ActiHistoricTaskDTO> getHistoricTasks(String processDefinitionKey, String businessKey, String processInstanceId) {
- List<HistoricTaskInstance> list = historyService.createHistoricTaskInstanceQuery()
- .processInstanceId(processInstanceId)
- .list();
- List<HistoricVariableInstance> varList = historyService.createHistoricVariableInstanceQuery()
- .processInstanceId(processInstanceId)
- .list();
- List<ActiHistoricTaskDTO> historicTaskDTOS = new ArrayList<>();
- if (list != null && list.size() > 0) {
- for(HistoricTaskInstance histTask : list) {
- ActiHistoricTaskDTO historicTask = new ActiHistoricTaskDTO();
- for(HistoricVariableInstance hvi : varList){
- if(hvi.getTaskId() != null && hvi.getTaskId().equals(histTask.getId())) {
- if(hvi.getVariableName().equals("businessKey")) {
- historicTask.setBusinessKey(hvi.getValue().toString());
- } else if(hvi.getVariableName().equals("result")) {
- historicTask.setResult(hvi.getValue().toString());
- } else if(hvi.getVariableName().equals("remarks")) {
- historicTask.setRemarks(hvi.getValue().toString());
- } else if( hvi.getVariableName().equals("users")) {
- historicTask.setUsers(hvi.getValue().toString());
- }
- }
- }
- //当前未完成的步骤,取出当前操作人
- if ( histTask.getClaimTime() == null || histTask.getEndTime() == null ) {
- List<HistoricVariableInstance> varListTmp = historyService.createHistoricVariableInstanceQuery()
- .processInstanceId(processInstanceId)
- .executionId(histTask.getExecutionId())
- .list();
- for(HistoricVariableInstance hvi : varListTmp){
- if(hvi.getVariableName().equals("businessKey")) {
- historicTask.setBusinessKey(hvi.getValue().toString());
- } else if(hvi.getVariableName().equals("result")) {
- historicTask.setResult(hvi.getValue().toString());
- } else if(hvi.getVariableName().equals("remarks")) {
- historicTask.setRemarks(hvi.getValue().toString());
- } else if( hvi.getVariableName().equals("users")) {
- historicTask.setUsers(hvi.getValue().toString());
- }
- }
- }
- historicTask.setAssignee(histTask.getAssignee());
- historicTask.setTaskName(histTask.getName());
- if(histTask.getStartTime() != null) {
- historicTask.setStartTime(histTask.getStartTime().getTime());
- }
- if(histTask.getEndTime() != null) {
- historicTask.setEndTime(histTask.getEndTime().getTime());
- }
- historicTask.setProcessInstanceId(histTask.getProcessInstanceId());
- historicTaskDTOS.add(historicTask);
- }
- }
- return historicTaskDTOS;
- }
- /**
- * 更改业务流程状态#{ActivityDemoServiceImpl.updateBizStatus(execution,"tj")}
- * @param execution
- * @param status
- */
- /*public void updateBizStatus(DelegateExecution execution,String status) {
- String bizId = execution.getProcessBusinessKey();
- //根据业务id自行处理业务表
- System.out.println("业务表["+bizId+"]状态更改成功,状态更改为:"+status);
- }*/
- //流程节点权限用户列表${ActivityDemoServiceImpl.findUsers(execution,sign)}
- /*public List<String> findUsersForSL(DelegateExecution execution){
- return Arrays.asList("sly1","sly2");
- }*/
- //流程节点权限用户列表${ActivityDemoServiceImpl.findUsers(execution,sign)}
- /*public List<String> findUsersForSP(DelegateExecution execution){
- return Arrays.asList("spy1","uspy2");
- }*/
- /**
- *
- * <p>描述: 生成流程图
- * 首先启动流程,获取processInstanceId,替换即可生成</p>
- * @author 范相如
- * @date 2018年2月25日
- * @param processInstanceId
- * @throws Exception
- */
- /*public void queryProImg(String processInstanceId) throws Exception {
- //获取历史流程实例
- HistoricProcessInstance processInstance = historyService.createHistoricProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
- //根据流程定义获取输入流
- InputStream is = repositoryService.getProcessDiagram(processInstance.getProcessDefinitionId());
- BufferedImage bi = ImageIO.read(is);
- File file = new File("demo2.png");
- if(!file.exists()) file.createNewFile();
- FileOutputStream fos = new FileOutputStream(file);
- ImageIO.write(bi, "png", fos);
- fos.close();
- is.close();
- System.out.println("图片生成成功");
- List<Task> tasks = taskService.createTaskQuery().taskCandidateUser("userId").list();
- for(Task t : tasks) {
- System.out.println(t.getName());
- }
- }*/
- /**
- * 获取流程图像,已执行节点和流程线高亮显示
- */
- public void getActivitiProccessImage(String pProcessInstanceId, HttpServletResponse response)
- {
- //logger.info("[开始]-获取流程图图像");
- try {
- // 获取历史流程实例
- HistoricProcessInstance historicProcessInstance = historyService.createHistoricProcessInstanceQuery()
- .processInstanceId(pProcessInstanceId).singleResult();
- if (historicProcessInstance == null) {
- //throw new BusinessException("获取流程实例ID[" + pProcessInstanceId + "]对应的历史流程实例失败!");
- }
- else
- {
- // 获取流程定义
- ProcessDefinitionEntity processDefinition = (ProcessDefinitionEntity) ((RepositoryServiceImpl) repositoryService)
- .getDeployedProcessDefinition(historicProcessInstance.getProcessDefinitionId());
- // 获取流程历史中已执行节点,并按照节点在流程中执行先后顺序排序
- List<HistoricActivityInstance> historicActivityInstanceList = historyService.createHistoricActivityInstanceQuery()
- .processInstanceId(pProcessInstanceId).orderByHistoricActivityInstanceId().asc().list();
- // 已执行的节点ID集合
- List<String> executedActivityIdList = new ArrayList<String>();
- int index = 1;
- //logger.info("获取已经执行的节点ID");
- for (HistoricActivityInstance activityInstance : historicActivityInstanceList) {
- executedActivityIdList.add(activityInstance.getActivityId());
- //logger.info("第[" + index + "]个已执行节点=" + activityInstance.getActivityId() + " : " +activityInstance.getActivityName());
- index++;
- }
- BpmnModel bpmnModel = repositoryService.getBpmnModel(historicProcessInstance.getProcessDefinitionId());
- // 已执行的线集合
- List<String> flowIds = new ArrayList<String>();
- // 获取流程走过的线 (getHighLightedFlows是下面的方法)
- flowIds = getHighLightedFlows(bpmnModel,processDefinition, historicActivityInstanceList);
- // 获取流程图图像字符流
- ProcessEngine processEngine = processEngineConfiguration.buildProcessEngine();
- ProcessDiagramGenerator pec = processEngine.getProcessEngineConfiguration().getProcessDiagramGenerator();
- //配置字体
- InputStream imageStream = pec.generateDiagram(bpmnModel, "png", executedActivityIdList, flowIds,"宋体","微软雅黑","黑体",null,2.0);
- response.setContentType("image/png");
- OutputStream os = response.getOutputStream();
- int bytesRead = 0;
- byte[] buffer = new byte[8192];
- while ((bytesRead = imageStream.read(buffer, 0, 8192)) != -1) {
- os.write(buffer, 0, bytesRead);
- }
- os.close();
- imageStream.close();
- }
- //logger.info("[完成]-获取流程图图像");
- } catch (Exception e) {
- System.out.println(e.getMessage());
- //logger.error("【异常】-获取流程图失败!" + e.getMessage());
- //throw new BusinessException("获取流程图失败!" + e.getMessage());
- }
- }
- public List<String> getHighLightedFlows(BpmnModel bpmnModel,ProcessDefinitionEntity processDefinitionEntity,List<HistoricActivityInstance> historicActivityInstances)
- {
- SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); //24小时制
- List<String> highFlows = new ArrayList<String>();// 用以保存高亮的线flowId
- for (int i = 0; i < historicActivityInstances.size() - 1; i++)
- {
- // 对历史流程节点进行遍历
- // 得到节点定义的详细信息
- FlowNode activityImpl = (FlowNode)bpmnModel.getMainProcess().getFlowElement(historicActivityInstances.get(i).getActivityId());
- List<FlowNode> sameStartTimeNodes = new ArrayList<FlowNode>();// 用以保存后续开始时间相同的节点
- FlowNode sameActivityImpl1 = null;
- HistoricActivityInstance activityImpl_ = historicActivityInstances.get(i);// 第一个节点
- HistoricActivityInstance activityImp2_ ;
- for(int k = i + 1 ; k <= historicActivityInstances.size() - 1; k++)
- {
- activityImp2_ = historicActivityInstances.get(k);// 后续第1个节点
- if ( activityImpl_.getActivityType().equals("userTask") && activityImp2_.getActivityType().equals("userTask") &&
- df.format(activityImpl_.getStartTime()).equals(df.format(activityImp2_.getStartTime())) ) //都是usertask,且主节点与后续节点的开始时间相同,说明不是真实的后继节点
- {
- }
- else
- {
- sameActivityImpl1 = (FlowNode)bpmnModel.getMainProcess().getFlowElement(historicActivityInstances.get(k).getActivityId());//找到紧跟在后面的一个节点
- break;
- }
- }
- sameStartTimeNodes.add(sameActivityImpl1); // 将后面第一个节点放在时间相同节点的集合里
- for (int j = i + 1; j < historicActivityInstances.size() - 1; j++)
- {
- HistoricActivityInstance activityImpl1 = historicActivityInstances.get(j);// 后续第一个节点
- HistoricActivityInstance activityImpl2 = historicActivityInstances.get(j + 1);// 后续第二个节点
- if (df.format(activityImpl1.getStartTime()).equals(df.format(activityImpl2.getStartTime())) )
- {// 如果第一个节点和第二个节点开始时间相同保存
- FlowNode sameActivityImpl2 = (FlowNode)bpmnModel.getMainProcess().getFlowElement(activityImpl2.getActivityId());
- sameStartTimeNodes.add(sameActivityImpl2);
- }
- else
- {// 有不相同跳出循环
- break;
- }
- }
- List<SequenceFlow> pvmTransitions = activityImpl.getOutgoingFlows() ; // 取出节点的所有出去的线
- for (SequenceFlow pvmTransition : pvmTransitions)
- {// 对所有的线进行遍历
- FlowNode pvmActivityImpl = (FlowNode)bpmnModel.getMainProcess().getFlowElement( pvmTransition.getTargetRef());// 如果取出的线的目标节点存在时间相同的节点里,保存该线的id,进行高亮显示
- if (sameStartTimeNodes.contains(pvmActivityImpl)) {
- highFlows.add(pvmTransition.getId());
- }
- }
- }
- return highFlows;
- }
- }
|