注:(1)环境搭建:activiti自定义流程之Spring整合activiti-modeler5.16实例(一):环境搭建
(2)创建流程模型:activiti自定义流程之Spring整合activiti-modeler5.16实例(二):创建流程模型
(3)流程模型列表展示:activiti自定义流程之Spring整合activiti-modeler5.16实例(三):流程模型列表展示
(4)部署流程定义:activiti自定义流程之Spring整合activiti-modeler5.16实例(四):部署流程定义
(5)流程定义列表:activiti自定义流程之Spring整合activiti-modeler5.16实例(五):流程定义列表
(6)启动流程:activiti自定义流程之Spring整合activiti-modeler5.16实例(六):启动流程
1.通过上一节的操作,可以知道流程启动以后会同时生成一个流程实例和用户任务,这个用户任务保存在act_ru_task和act_hi_task表中,从表明可以看出ru是runtime,hi是history。但是需要注意的是,和操作流程使用的service不同,操作正在发生任务不是使用runtimeService,而是专门的taskService。
2.后台业务代码,
(1)自定义的任务实体类
package model; import java.util.Date; public class TaskModel { private String id; private String name; private String processInstanceId; private String assignee; private Date createTime; private String nextPerson; private String cause; private String content; private String taskType; private String processKey; private String processDefId; public String getTaskType() { return taskType; } public void setTaskType(String taskType) { this.taskType = taskType; } public String getId() { return id; } public void setId(String id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getProcessInstanceId() { return processInstanceId; } public void setProcessInstanceId(String processInstanceId) { this.processInstanceId = processInstanceId; } public String getAssignee() { return assignee; } public void setAssignee(String assignee) { this.assignee = assignee; } public Date getCreateTime() { return createTime; } public void setCreateTime(Date createTime) { this.createTime = createTime; } public String getNextPerson() { return nextPerson; } public void setNextPerson(String nextPerson) { this.nextPerson = nextPerson; } public String getCause() { return cause; } public void setCause(String cause) { this.cause = cause; } public String getContent() { return content; } public void setContent(String content) { this.content = content; } public String getProcessKey() { return processKey; } public void setProcessKey(String processKey) { this.processKey = processKey; } public String getProcessDefId() { return processDefId; } public void setProcessDefId(String processDefId) { this.processDefId = processDefId; } @Override public String toString() { return "TaskModel [id=" + id + ", name=" + name + ", processInstanceId=" + processInstanceId + ", assignee=" + assignee + ", createTime=" + createTime + ", nextPerson=" + nextPerson + ", cause=" + cause + ", content=" + content + ", taskType=" + taskType + ", processKey=" + processKey + ", processDefId=" + processDefId + "]"; } }
(2)业务逻辑:查询任务使用taskService调用相关的方法来完成,可以根据特定的条件,也可以不加条件查询所有。可以返回task为元素的list,也可以返回单独的task对象,但是需要注意的是,如果要返回单独的task对象,则必须确定返回值是唯一的对象,否则就会抛出异常。下边的例子中,我是根据当前登陆的用户名来查询出对应的所有task:
/** * @throws XMLStreamException * 查询个人任务 * * @author:tuzongxun * @Title: findTask * @param @return * @return Object * @date Mar 17, 2016 2:44:11 PM * @throws */ @RequestMapping(value = "/findTask.do", method = RequestMethod.POST, produces = "application/json;charset=utf-8") @ResponseBody public Object findTask(HttpServletRequest req) throws XMLStreamException { Map<String, Object> map = new HashMap<String, Object>(); boolean isLogin = this.isLogin(req); if (isLogin) { List<TaskModel> taskList = new ArrayList<TaskModel>(); HttpSession session = req.getSession(); String assginee = (String) session.getAttribute("userName"); List<Task> taskList1 = taskService.createTaskQuery() .taskAssignee(assginee).list(); if (taskList1 != null && taskList1.size() > 0) { for (Task task : taskList1) { TaskModel taskModel = new TaskModel(); taskModel.setAssignee(task.getAssignee()); taskModel.setCreateTime(task.getCreateTime()); taskModel.setId(task.getId()); taskModel.setName(task.getName()); taskModel.setProcessInstanceId(task.getProcessInstanceId()); taskModel.setProcessDefId(task.getProcessDefinitionId()); // 获取流程变量 Map<String, Object> variables = runtimeService .getVariables(task.getProcessInstanceId()); Set<String> keysSet = variables.keySet(); Iterator<String> keySet = keysSet.iterator(); while (keySet.hasNext()) { String key = keySet.next(); if (key.endsWith("cause")) { taskModel.setCause((String) variables.get("cause")); } else if (key.endsWith("content")) { taskModel.setContent((String) variables .get("content")); } else if (key.endsWith("taskType")) { taskModel.setTaskType((String) variables .get("taskType")); } else if (!assginee.equals(variables.get(key))) { // 想办法查询是否还有下一个任务节点 Iterator<FlowElement> iterator = this.findFlow(task .getProcessDefinitionId()); while (iterator.hasNext()) { FlowElement flowElement = iterator.next(); String classNames = flowElement.getClass() .getSimpleName(); if (classNames.equals("UserTask")) { UserTask userTask = (UserTask) flowElement; String assginee11 = userTask.getAssignee(); String assginee12 = assginee11.substring( assginee11.indexOf("{") + 1, assginee11.indexOf("}")); String assignee13 = (String) variables .get(assginee12); if (assginee.equals(assignee13)) { // 看下下一个节点是什么 iterator.next(); FlowElement flowElement2 = iterator .next(); String classNames1 = flowElement2 .getClass().getSimpleName(); // 设置下一个任务人 if (!(classNames1.equals("EndEvent"))) { UserTask userTask2 = (UserTask) flowElement2; String assginee21 = userTask2 .getAssignee(); String assginee22 = assginee21 .substring( assginee21 .indexOf("{") + 1, assginee21 .indexOf("}")); String assignee23 = (String) variables .get(assginee22); taskModel.setNextPerson(ToolUtils .isEmpty(assignee23)); } } } } // ////////// } } taskList.add(taskModel); } } map.put("isLogin", "yes"); map.put("userName", (String) req.getSession().getAttribute("userName")); map.put("result", "success"); map.put("data", taskList); } else { map.put("isLogin", "no"); } return map; }
3.angular js前台代码(前台只是做简单的展示,不多讲):
(1)app.js中配置路由:
$stateProvider .state('taskList', { url: "/taskList", views: { 'view': { templateUrl: 'activi_views/taskList.html', controller: 'taskCtr' } } });
(2)逻辑相关代码:
angular.module('activitiApp') .controller('taskCtr', ['$rootScope','$scope','$http','$location','$state', function($rootScope,$scope,$http,$location,$state){ $scope.init=function(){ $http.post("./findTask.do").success(function(result) { if(result.isLogin==="yes"){ console.log(result.data); $rootScope.userName=result.userName; $scope.taskList=result.data; }else{ $location.path("/login"); } }); } $scope.completeTaskTo=function(task){ console.log(task); $rootScope.task=task; //$location.path("/completeTaskTo"); $location.path("/completeTaskTo1"); } }])
4.对应的填写相关信息的页面:
<div id="logdiv1" ng-init="init();"> <p style="font-size:22px;margin-top:10px">当前任务列表</p> <center> <table border="1px" style="width:87%;font-size:14px;text-align:center;margin-top:1px;margin-left:2px;position:relative;float:left;" cellSpacing="0px" cellPadding="0px"> <tr style="background-color:#ccc"> <td>类型</td> <td>ID</td> <td>NAME</td> <td>ProcessIntanceId</td> <td>ProcessDefId</td> <td>创建时间</td> <td>申请人</td> <td>受理人</td> <td>申请原因</td> <td>申请内容</td> <td>操 作</td> </tr> <tr ng-repeat="task in taskList | orderBy:'id'" > <td>{{task.taskType}}</td> <td>{{task.id}}</td> <td>{{task.name}}</td> <td>{{task.processInstanceId}}</td> <td>{{task.processDefId}}</td> <td>{{task.createTime | date:"yyyy-MM-dd HH:mm:ss"}}</td> <td>{{task.assignee}}</td> <td>{{task.nextPerson}}</td> <td>{{task.cause}}</td> <td>{{task.content}}</td> <td><a href="script:;" ng-click="completeTaskTo(task)">完成任务</a> </td> </tr> </table> </center> </div>