activiti 动态自定义流程(包含会签流程)

 

后台加入工作流步骤(这个不重要,自己实现)

 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 }

 部署完流程图

(当前选择两个步骤的流程图)

 

posted @ 2017-11-27 14:54  suruozhong  阅读(25908)  评论(4编辑  收藏  举报