userTask,顾名思义,即用户操作的任务,任务的分配有三种方式:
◎直接指定办理人
◎使用流程变量
◎使用监听类
其中,任务分配又分为个人任务和组任务。这里我们先一起看一下个人任务的三种实现方式。
这种实现方式即在画流程图的时候在流程节点的properties属性为Assignee直接赋值。如上图所示,这里分配的
任务办理人为张三丰。对应生成的xml文件:
<process id="userTask" name="userTaskrocess" isExecutable="true"> <startEvent id="startevent1" name="Start"></startEvent> <userTask id="审批" name="审批" activiti:assignee="张三丰"></userTask> <sequenceFlow id="flow1" sourceRef="startevent1" targetRef="审批"></sequenceFlow> <endEvent id="endevent1" name="End"></endEvent> <sequenceFlow id="flow2" sourceRef="审批" targetRef="endevent1"></sequenceFlow> </process>
测试代码
public class UserTaskTest { /**获取默认流程引擎*/ ProcessEngine processEngine=ProcessEngines.getDefaultProcessEngine(); /**部署流程定义*/ @Test public void deploymentProcessDefiniton_inputStream(){ InputStream inputStreamBpmn=this.getClass().getResourceAsStream("userTask.bpmn"); InputStream inputStreamPng=this.getClass().getResourceAsStream("userTask.png"); Deployment deployment=processEngine.getRepositoryService()// .createDeployment()// .name("个人任务")// .addInputStream("userTask.bpmn", inputStreamBpmn)// .addInputStream("userTask.png", inputStreamPng)// .deploy(); System.out.println("部署ID:"+deployment.getId()); System.out.println("部署名称:"+deployment.getName()); } /**启动一个流程实例*/ @Test public void startProcessInstance(){ //通过流程定义的key启动,会启动最高版本的流程 String processDefinitionKey="userTask"; ProcessInstance processInstance= processEngine.getRuntimeService()// .startProcessInstanceByKey(processDefinitionKey); System.out.println("流程实例ID:"+processInstance.getId()); System.out.println("流程定义ID: "+processInstance.getProcessDefinitionId()); } /* * 查询我的个人任务列表 * */ @Test public void findMyTaskList(){ String userId = "张三丰"; List<Task> list = processEngine.getTaskService()// .createTaskQuery()// .taskAssignee(userId)//指定个人任务查询 .list(); for(Task task:list ){ System.out.println("id="+task.getId()); System.out.println("name="+task.getName()); System.out.println("assinee="+task.getAssignee()); System.out.println("createTime="+task.getCreateTime()); System.out.println("executionId="+task.getExecutionId()); } } /* * 完成任务 */ public void completeTask(){ String taskId=""; processEngine.getTaskService()// .complete(taskId); System.out.println("完成任务:"+taskId); } }
这样分配任务的办理人不够灵活,实际项目开发中任务办理人不直接在xml文件中配置。
这种实现方式在画流程图的时候在流程节点的properties属性为Assignee设置一个变量userID,具体办理人在程
序中动态传入。对应生成的xml文件
<process id="userTask" name="userTaskrocess" isExecutable="true"> <startEvent id="startevent1" name="Start"></startEvent> <userTask id="审批" name="审批" activiti:assignee="${userID}"></userTask> <sequenceFlow id="flow1" sourceRef="startevent1" targetRef="审批"></sequenceFlow> <endEvent id="endevent1" name="End"></endEvent> <sequenceFlow id="flow2" sourceRef="审批" targetRef="endevent1"></sequenceFlow> </process>
测试代码
/**启动一个流程实例并设置流程变量*/ @Test public void startProcessInstance(){ //用map动态设置任务办理人 Map<String, Object> variables=new HashMap<String, Object>(); variables.put("userID", "周芷若"); //通过流程定义的key启动,会启动最高版本的流程 String processDefinitionKey="userTask"; ProcessInstance processInstance= processEngine.getRuntimeService()// .startProcessInstanceByKey(processDefinitionKey,variables); System.out.println("流程实例ID:"+processInstance.getId()); System.out.println("流程定义ID: "+processInstance.getProcessDefinitionId()); }
可以在页面中指定下一个任务办理人,通过流程变量设置下一个任务的办理人。
这种的实现方式,即在流程节点上添加任务监听器,在任务监听器的实现类中动态指定任务办理人。如上图所
示。对应的XML文件:
<process id="userTask" name="userTaskProcess" isExecutable="true"> <startEvent id="startevent1" name="Start"></startEvent> <userTask id="审批" name="审批"> <extensionElements> <activiti:taskListener event="create" class="cn.tgb.i_userTask.TaskListenerImpl"></activiti:taskListener> </extensionElements> </userTask> <sequenceFlow id="flow1" sourceRef="startevent1" targetRef="审批"></sequenceFlow> <endEvent id="endevent1" name="End"></endEvent> <sequenceFlow id="flow2" sourceRef="审批" targetRef="endevent1"></sequenceFlow> </process>
测试代码:
<span style="font-family:SimSun;font-size:18px;">public class TaskListenerImpl implements TaskListener { /**指定个人任务和组任务的办理人*/ @Override public void notify(DelegateTask delegateTask) { /** 指定个人任务的办理人,也可以指定组任务的办理人 个人任务:通过类去查询数据库,将下一个任务的办理人查询获取 然后通过setAssignee的方法指定任务办理人 */ String assignee="张无忌"; //指定个人任务 delegateTask.setAssignee(assignee); } }</span>
<span style="font-family:SimSun;font-size:18px;">/**启动一个流程实例*/ @Test public void startProcessInstance(){ //通过流程定义的key启动,会启动最高版本的流程 String processDefinitionKey="userTask"; ProcessInstance processInstance= processEngine.getRuntimeService()// .startProcessInstanceByKey(processDefinitionKey); System.out.println("流程实例ID:"+processInstance.getId()); System.out.println("流程定义ID: "+processInstance.getProcessDefinitionId()); }</span>
在类中使用delegateTask.setAssignee(assignee);的方式分配个人任务办理人,张无忌即为下一个任务办理人。
扩展:
/** * 重新指定任务办理人 * 可以分配个人任务从一个人到另一个人 * 应用场景举例:张无忌出远门无法审批,可以把审批权交接给周芷若 */ @Test public void setAssigneeTask(){ String taskId=""; String userId="周芷若"; //getTaskService:Changes the assignee of the given task to the given userId. processEngine.getTaskService()// .setAssignee(taskId, userId); }
通过以上三中实现方式的递进,毫无疑问,灵活可配是我们最好的选择!