后台加入工作流步骤(这个不重要,自己实现)
1 package com.blk.integrated.pojo; 2 3 import java.io.Serializable; 4 import java.util.Date; 5 6 import javax.persistence.Column; 7 import javax.persistence.Entity; 8 import javax.persistence.GeneratedValue; 9 import javax.persistence.GenerationType; 10 import javax.persistence.Id; 11 import javax.persistence.Table; 12 13 import org.codehaus.jackson.map.annotate.JsonSerialize; 14 import org.springframework.format.annotation.DateTimeFormat; 15 16 import lib.core.utils3.system.CustomDateSerializerHM; 17 18 @Entity 19 @Table(name="sys_workflow") 20 public class SysWorkflow implements Serializable { 21 22 private static final long serialVersionUID = 1L; 23 24 @Id 25 @GeneratedValue(strategy = GenerationType.IDENTITY) 26 @Column(name="id") 27 private Long id; 28 29 @JsonSerialize(using = CustomDateSerializerHM.class) 30 @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm") 31 @Column(name="create_time") 32 private Date createTime; 33 //工作流名称 34 @Column(name="name") 35 private String name; 36 //工作流描述 37 @Column(name="content") 38 private String content; 39 40 @Column(name="skip_level") 41 private Integer skipLevel; 42 43 public Long getId() { 44 return id; 45 } 46 47 public void setId(Long id) { 48 this.id = id; 49 } 50 51 public Date getCreateTime() { 52 return createTime; 53 } 54 55 public void setCreateTime(Date createTime) { 56 this.createTime = createTime; 57 } 58 59 public String getName() { 60 return name; 61 } 62 63 public void setName(String name) { 64 this.name = name; 65 } 66 67 public String getContent() { 68 return content; 69 } 70 71 public void setContent(String content) { 72 this.content = content; 73 } 74 75 public Integer getSkipLevel() { 76 return skipLevel; 77 } 78 79 public void setSkipLevel(Integer skipLevel) { 80 this.skipLevel = skipLevel; 81 } 82 83 84 }
1 package com.blk.integrated.pojo; 2 3 import java.io.Serializable; 4 import java.util.Date; 5 6 import javax.persistence.Column; 7 import javax.persistence.Entity; 8 import javax.persistence.GeneratedValue; 9 import javax.persistence.GenerationType; 10 import javax.persistence.Id; 11 import javax.persistence.Table; 12 13 import org.codehaus.jackson.map.annotate.JsonSerialize; 14 import org.springframework.format.annotation.DateTimeFormat; 15 16 import lib.core.utils3.system.CustomDateSerializerHM; 17 18 @Entity 19 @Table(name="sys_workflow_step") 20 public class SysWorkflowStep implements Serializable { 21 private static final long serialVersionUID = 1L; 22 23 @Id 24 @GeneratedValue(strategy = GenerationType.IDENTITY) 25 @Column(name="id") 26 private Long id; 27 28 @JsonSerialize(using = CustomDateSerializerHM.class) 29 @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm") 30 @Column(name="create_time") 31 private Date createTime; 32 33 @Column(name="workflow_id") 34 private Long workflowId; 35 //该步骤审核的角色 36 @Column(name="role_pkno") 37 private String rolePkno; 38 /** 39 * type==1 会签 40 * type==2 普通流转 41 */ 42 @Column(name="type") 43 private Integer type; 44 45 public Long getId() { 46 return id; 47 } 48 49 public void setId(Long id) { 50 this.id = id; 51 } 52 53 public Date getCreateTime() { 54 return createTime; 55 } 56 57 public void setCreateTime(Date createTime) { 58 this.createTime = createTime; 59 } 60 61 public Long getWorkflowId() { 62 return workflowId; 63 } 64 65 public void setWorkflowId(Long workflowId) { 66 this.workflowId = workflowId; 67 } 68 69 public String getRolePkno() { 70 return rolePkno; 71 } 72 73 public void setRolePkno(String rolePkno) { 74 this.rolePkno = rolePkno; 75 } 76 77 public Integer getType() { 78 return type; 79 } 80 81 public void setType(Integer type) { 82 this.type = type; 83 } 84 85 86 }
//创建模型并部署工作流
1 package com.blk.back.service.impl; 2 3 import java.io.File; 4 import java.io.InputStream; 5 import java.util.*; 6 7 import javax.transaction.Transactional; 8 9 import com.blk.integrated.pojo.SysUserRoleMappingPo; 10 import lib.core.utils3.StringUtils; 11 import lib.hibernate.dao.SimpleDao; 12 import org.activiti.bpmn.BpmnAutoLayout; 13 import org.activiti.bpmn.model.*; 14 import org.activiti.bpmn.model.Process; 15 import org.activiti.engine.ActivitiException; 16 import org.activiti.engine.ProcessEngine; 17 import org.activiti.engine.ProcessEngines; 18 import org.activiti.engine.repository.Deployment; 19 import org.activiti.engine.runtime.ProcessInstance; 20 import org.activiti.engine.task.Task; 21 import org.apache.commons.io.FileUtils; 22 import org.springframework.beans.factory.annotation.Autowired; 23 import org.springframework.stereotype.Service; 24 25 import com.alibaba.fastjson.JSONArray; 26 import com.alibaba.fastjson.JSONObject; 27 import com.blk.back.service.SysWorkflowService; 28 import com.blk.core.util.RetKit; 29 /** 30 * 31 * @project cb-console-service 32 * @author suruozhong 33 * @description (工作流管理) 34 * @date 2017年10月19日 35 */ 36 import com.blk.integrated.dao.SysRoleDao; 37 import com.blk.integrated.dao.SysWorkflowDao; 38 import com.blk.integrated.dao.SysWorkflowStepDao; 39 import com.blk.integrated.pojo.SysRolePo; 40 import com.blk.integrated.pojo.SysWorkflow; 41 import com.blk.integrated.pojo.SysWorkflowStep; 42 @Service 43 @Transactional 44 public class SysWorkflowServiceImpl implements SysWorkflowService { 45 46 @Autowired 47 private SysRoleDao sysRoleDao; 48 @Autowired 49 private SysWorkflowDao sysWorkflowDao; 50 @Autowired 51 private SysWorkflowStepDao sysWorkflowStepDao; 52 @Autowired 53 private SimpleDao simpleDao; 54 //获取角色下所有用户 55 private List<String> getUserRole(String rolePkno){ 56 List<String> list = simpleDao.getDelegate().createSQLQuery("select user_pkno from sys_user_role_mapping where role_pkno=:rolePkno").setParameter("rolePkno",rolePkno).list(); 57 return list; 58 } 59 60 @Override 61 public RetKit save(SysWorkflow model,String stepArr) { 62 63 model.setCreateTime(new Date()); 64 sysWorkflowDao.getDelegate().save(model); 65 JSONArray arr = JSONObject.parseArray(stepArr); 66 List<SysWorkflowStep> stepList = new ArrayList<SysWorkflowStep>(); 67 for(int i=0; i<arr.size();i++) { 68 SysWorkflowStep step = new SysWorkflowStep(); 69 JSONObject obj = JSONObject.parseObject(arr.get(i).toString()); 70 step.setId(obj.getLong("id")); 71 step.setCreateTime(new Date()); 72 step.setWorkflowId(model.getId()); 73 step.setRolePkno(obj.getString("rolePkno")); 74 step.setType(obj.getIntValue("type")); 75 sysWorkflowStepDao.merge(step); 76 stepList.add(step); 77 } 78 //部署工作流 79 addFlowDeployment(model,stepList); 80 return RetKit.ok(); 81 } 82 83 /** 84 *@Date:2017/11/24 85 *@Description:创建流程并部署 86 * 87 */ 88 protected void addFlowDeployment(SysWorkflow workflow,List<SysWorkflowStep> stepList){ 89 System.out.println(".........start..."); 90 ProcessEngine processEngine= ProcessEngines.getDefaultProcessEngine(); 91 92 // 1. 建立模型 93 BpmnModel model = new BpmnModel(); 94 Process process=new Process(); 95 model.addProcess(process); 96 process.setId("news"); 97 process.setName(workflow.getName()); 98 process.setDocumentation(workflow.getContent()); 99 //添加流程 100 //开始节点 101 process.addFlowElement(createStartEvent()); 102 for(int i=0; i<stepList.size(); i++){ 103 SysWorkflowStep step = stepList.get(i); 104 //判断是否会签 105 if(step.getType()==1){ 106 //会签 107 //加入并行网关-分支 108 process.addFlowElement(createParallelGateway("parallelGateway-fork"+i,"并行网关-分支"+i)); 109 //获取角色下所有用户 110 List<String> userList = getUserRole(step.getRolePkno()); 111 for(int u=0; u<userList.size();u++){ 112 //并行网关分支的审核节点 113 process.addFlowElement(createUserTask("userTask"+i+u,"并行网关分支用户审核节点"+i+u,userList.get(u))); 114 } 115 //并行网关-汇聚 116 process.addFlowElement(createParallelGateway("parallelGateway-join"+i,"并行网关到-汇聚"+i)); 117 118 }else{ 119 //普通流转 120 //审核节点 121 process.addFlowElement(createGroupTask("task"+i,"组审核节点"+i,step.getRolePkno())); 122 //回退节点 123 process.addFlowElement(createUserTask("repulse"+i,"回退节点"+i,"${startUserId}")); 124 } 125 } 126 //结束节点 127 process.addFlowElement(createEndEvent()); 128 129 //连线 130 for(int y=0; y<stepList.size(); y++){ 131 SysWorkflowStep step = stepList.get(y); 132 //是否会签 133 if(step.getType()==1){ 134 //会签 135 //判断是否第一个节点 136 if(y==0){ 137 //开始节点和并行网关-分支连线 138 process.addFlowElement(createSequenceFlow("startEvent", "parallelGateway-fork"+y, "开始节点到并行网关-分支"+y, "")); 139 }else{ 140 //审核节点或者并行网关-汇聚到并行网关-分支 141 //判断上一个节点是否是会签 142 if(stepList.get(y-1).getType()==1){ 143 process.addFlowElement(createSequenceFlow("parallelGateway-join"+(y-1),"parallelGateway-fork"+y,"并行网关-汇聚到并行网关-分支"+y,"")); 144 }else{ 145 process.addFlowElement(createSequenceFlow("task"+(y-1),"parallelGateway-fork"+y,"上一个审核节点到并行网关-分支"+y,"")); 146 } 147 } 148 //并行网关-分支和会签用户连线,会签用户和并行网关-汇聚连线 149 List<String> userList = getUserRole(step.getRolePkno()); 150 for(int u=0; u<userList.size(); u++){ 151 process.addFlowElement(createSequenceFlow("parallelGateway-fork"+y,"userTask"+y+u,"并行网关-分支到会签用户"+y+u,"")); 152 process.addFlowElement(createSequenceFlow("userTask"+y+u,"parallelGateway-join"+y,"会签用户到并行网关-汇聚","")); 153 } 154 //最后一个节点 并行网关-汇聚到结束节点 155 if(y==(stepList.size()-1)){ 156 process.addFlowElement(createSequenceFlow("parallelGateway-join"+y,"endEvent","并行网关-汇聚到结束节点","")); 157 } 158 }else{ 159 //普通流转 160 //第一个节点 161 if(y==0){ 162 //开始节点和审核节点1 163 process.addFlowElement(createSequenceFlow("startEvent", "task"+y, "开始节点到审核节点"+y, "")); 164 }else{ 165 //判断上一个节点是否会签 166 if(stepList.get(y-1).getType()==1){ 167 //会签 168 //并行网关-汇聚到审核节点 169 process.addFlowElement(createSequenceFlow("parallelGateway-join"+(y-1),"task"+y,"并行网关-汇聚到审核节点"+y,"")); 170 }else{ 171 //普通 172 process.addFlowElement(createSequenceFlow("task"+(y-1),"task"+y,"审核节点"+(y-1)+"到审核节点"+y,"${flag=='true'}")); 173 } 174 } 175 //是否最后一个节点 176 if(y==(stepList.size()-1)){ 177 //审核节点到结束节点 178 process.addFlowElement(createSequenceFlow("task"+y,"endEvent","审核节点"+y+"到结束节点","${flag=='true'}")); 179 } 180 //审核节点到回退节点 181 process.addFlowElement(createSequenceFlow("task"+y,"repulse"+y,"审核不通过-打回"+y,"${flag=='false'}")); 182 process.addFlowElement(createSequenceFlow("repulse"+y,"task"+y,"回退节点到审核节点"+y,"")); 183 } 184 } 185 186 // 2. 生成的图形信息 187 new BpmnAutoLayout(model).execute(); 188 189 // 3. 部署流程 190 Deployment deployment = processEngine.getRepositoryService().createDeployment().addBpmnModel(process.getId()+".bpmn", model).name(process.getId()+"_deployment").deploy(); 191 192 // // 4. 启动一个流程实例 193 // ProcessInstance processInstance = processEngine.getRuntimeService().startProcessInstanceByKey(process.getId()); 194 // 195 // // 5. 获取流程任务 196 // List<Task> tasks = processEngine.getTaskService().createTaskQuery().processInstanceId(processInstance.getId()).list(); 197 // try{ 198 // // 6. 将流程图保存到本地文件 199 // InputStream processDiagram = processEngine.getRepositoryService().getProcessDiagram(processInstance.getProcessDefinitionId()); 200 // FileUtils.copyInputStreamToFile(processDiagram, new File("/deployments/"+process.getId()+".png")); 201 // 202 // // 7. 保存BPMN.xml到本地文件 203 // InputStream processBpmn = processEngine.getRepositoryService().getResourceAsStream(deployment.getId(), process.getId()+".bpmn"); 204 // FileUtils.copyInputStreamToFile(processBpmn,new File("/deployments/"+process.getId()+".bpmn")); 205 // }catch (Exception e){ 206 // e.printStackTrace(); 207 // } 208 209 System.out.println(".........end..."); 210 } 211 212 213 //任务节点-组 214 protected UserTask createGroupTask(String id, String name, String candidateGroup) { 215 List<String> candidateGroups=new ArrayList<String>(); 216 candidateGroups.add(candidateGroup); 217 UserTask userTask = new UserTask(); 218 userTask.setName(name); 219 userTask.setId(id); 220 userTask.setCandidateGroups(candidateGroups); 221 return userTask; 222 } 223 224 //任务节点-用户 225 protected UserTask createUserTask(String id, String name, String userPkno) { 226 List<String> candidateUsers=new ArrayList<String>(); 227 candidateUsers.add(userPkno); 228 UserTask userTask = new UserTask(); 229 userTask.setName(name); 230 userTask.setId(id); 231 userTask.setCandidateUsers(candidateUsers); 232 return userTask; 233 } 234 235 //任务节点-锁定者 236 protected UserTask createAssigneeTask(String id, String name, String assignee) { 237 UserTask userTask = new UserTask(); 238 userTask.setName(name); 239 userTask.setId(id); 240 userTask.setAssignee(assignee); 241 return userTask; 242 } 243 244 /*连线*/ 245 protected SequenceFlow createSequenceFlow(String from, String to,String name,String conditionExpression) { 246 SequenceFlow flow = new SequenceFlow(); 247 flow.setSourceRef(from); 248 flow.setTargetRef(to); 249 flow.setName(name); 250 if(StringUtils.isNotEmpty(conditionExpression)){ 251 flow.setConditionExpression(conditionExpression); 252 } 253 return flow; 254 } 255 256 //排他网关 257 protected ExclusiveGateway createExclusiveGateway(String id,String name) { 258 ExclusiveGateway exclusiveGateway = new ExclusiveGateway(); 259 exclusiveGateway.setId(id); 260 exclusiveGateway.setName(name); 261 return exclusiveGateway; 262 } 263 264 //并行网关 265 protected ParallelGateway createParallelGateway(String id,String name){ 266 ParallelGateway gateway = new ParallelGateway(); 267 gateway.setId(id); 268 gateway.setName(name); 269 return gateway; 270 } 271 272 //开始节点 273 protected StartEvent createStartEvent() { 274 StartEvent startEvent = new StartEvent(); 275 startEvent.setId("startEvent"); 276 return startEvent; 277 } 278 279 /*结束节点*/ 280 protected EndEvent createEndEvent() { 281 EndEvent endEvent = new EndEvent(); 282 endEvent.setId("endEvent"); 283 return endEvent; 284 } 285 286 }
部署完流程图
(当前选择两个步骤的流程图)