注:(1)环境搭建:activiti自定义流程之Spring整合activiti-modeler5.16实例(一):环境搭建
(2)创建流程模型:activiti自定义流程之Spring整合activiti-modeler5.16实例(二):创建流程模型
(3)流程模型列表展示:activiti自定义流程之Spring整合activiti-modeler5.16实例(三):流程模型列表展示
(4)部署流程定义:activiti自定义流程之Spring整合activiti-modeler5.16实例(四):部署流程定义
(1)自定义的申请单实体类(为的目的只为了跑通整个流程,因此只定义了一个实体类,按公司标准开发来说,应该是和前台交互一个command类(其实也还是实体类,叫法不一样而已),和数据库交互还有一个实体类),在这里定义了一个申请单的基本信息:
(2)业务逻辑:
A,这个方法获取流程部署时xml文件里的各个节点相关信息,用来辨别当前是哪个节点,下一节点又是什么,共下边的B方法调用。因为操作部署时的文件,因此使用repositoryService:
B.这里调用上一个方法,一起完成流程的启动及相关信息的设置:
3.angular js前台代码,:
(1)app.js中配置路由:
(2)逻辑相关代码:
4.对应的填写相关信息的页面:
5.成功启动一个流程实例后,会看到act_ru_execution、act_ru_identitylink、act_ru_task、act_ru_variable以及act_hi_actinst、act_hi_detail、act_hi_indentitylink、act_hi_procinst、act_hi_taskinst、act_hi_varinst表中都有了数据。除开variable和varinst中的数据条数是根据对应的流程变量多少来定的,其他都是增加了一条数据。
(2)创建流程模型:activiti自定义流程之Spring整合activiti-modeler5.16实例(二):创建流程模型
(3)流程模型列表展示:activiti自定义流程之Spring整合activiti-modeler5.16实例(三):流程模型列表展示
(4)部署流程定义:activiti自定义流程之Spring整合activiti-modeler5.16实例(四):部署流程定义
(5)流程定义列表:activiti自定义流程之Spring整合activiti-modeler5.16实例(五):流程定义列表
1.启动流程并分配任务是单个流程的正式开始,因此要使用到runtimeService接口,以及相关的启动流程的方法。我习惯于用流程定义的key启动,因为有多个版本的流程定义时,用key启动默认会使用最新版本。同时,因为启动中查询了流程部署时xml文件中流程节点的信息,也用到了repositoryService及相关方法。
(1)自定义的申请单实体类(为的目的只为了跑通整个流程,因此只定义了一个实体类,按公司标准开发来说,应该是和前台交互一个command类(其实也还是实体类,叫法不一样而已),和数据库交互还有一个实体类),在这里定义了一个申请单的基本信息:
package model; public class applyModel { /** * 流程定义id */ private String proDefId; /** * 流程定义的key */ private String key; private String name; /** * 申请人 */ private String appPerson; /** * 原因 */ private String cause; /** * 内容 */ private String content; /** * 处理人,即下一个任务节点的受理人 */ private String proPerson; public String getKey() { return key; } public void setKey(String key) { this.key = key; } public String getAppPerson() { return appPerson; } public void setAppPerson(String appPerson) { this.appPerson = appPerson; } 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 getProPerson() { return proPerson; } public void setProPerson(String proPerson) { this.proPerson = proPerson; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getProDefId() { return proDefId; } public void setProDefId(String proDefId) { this.proDefId = proDefId; } @Override public String toString() { return "applyModel [proDefId=" + proDefId + ", key=" + key + ", name=" + name + ", appPerson=" + appPerson + ", cause=" + cause + ", content=" + content + ", proPerson=" + proPerson + "]"; } }
(2)业务逻辑:
A,这个方法获取流程部署时xml文件里的各个节点相关信息,用来辨别当前是哪个节点,下一节点又是什么,共下边的B方法调用。因为操作部署时的文件,因此使用repositoryService:
/** * @throws XMLStreamException * 查询流程节点 * * @author:tuzongxun * @Title: findFlow * @param @return * @return Iterator<FlowElement> * @date Mar 21, 2016 9:31:42 AM * @throws */ public Iterator<FlowElement> findFlow(String processDefId) throws XMLStreamException { List<ProcessDefinition> lists = repositoryService .createProcessDefinitionQuery() .processDefinitionId(processDefId) .orderByProcessDefinitionVersion().desc().list(); ProcessDefinition processDefinition = lists.get(0); processDefinition.getCategory(); String resourceName = processDefinition.getResourceName(); InputStream inputStream = repositoryService.getResourceAsStream( processDefinition.getDeploymentId(), resourceName); BpmnXMLConverter converter = new BpmnXMLConverter(); XMLInputFactory factory = XMLInputFactory.newInstance(); XMLStreamReader reader = factory.createXMLStreamReader(inputStream); BpmnModel bpmnModel = converter.convertToBpmnModel(reader); Process process = bpmnModel.getMainProcess(); Collection<FlowElement> elements = process.getFlowElements(); Iterator<FlowElement> iterator = elements.iterator(); return iterator; }
B.这里调用上一个方法,一起完成流程的启动及相关信息的设置:
/** * @throws XMLStreamException * 启动流程 * * @author:tuzongxun * @Title: startProcess * @param @return * @return Object * @date Mar 17, 2016 2:06:34 PM * @throws */ @RequestMapping(value = "/startProcess.do", method = RequestMethod.POST, produces = "application/json;charset=utf-8") @ResponseBody public Object startProcess(@RequestBody applyModel applyModel, HttpServletRequest req) throws XMLStreamException { Map<String, String> map = new HashMap<String, String>(); boolean isLogin = this.isLogin(req); if (isLogin) { if (applyModel != null) { String processKey = applyModel.getKey(); String processDefId = applyModel.getProDefId(); // ////////////////////////// Iterator<FlowElement> iterator = this.findFlow(processDefId); Map<String, Object> varables = new HashMap<String, Object>(); int i = 1; while (iterator.hasNext()) { FlowElement flowElement = iterator.next(); // 申请人 if (flowElement.getClass().getSimpleName() .equals("UserTask") && i == 1) { UserTask userTask = (UserTask) flowElement; String assignee = userTask.getAssignee(); int index1 = assignee.indexOf("{"); int index2 = assignee.indexOf("}"); varables.put(assignee.substring(index1 + 1, index2), applyModel.getAppPerson()); varables.put("cause", applyModel.getCause()); varables.put("content", applyModel.getContent()); varables.put("taskType", applyModel.getName()); i++; // 下一个处理人 } else if (flowElement.getClass().getSimpleName() .equals("UserTask") && i == 2) { UserTask userTask = (UserTask) flowElement; String assignee = userTask.getAssignee(); int index1 = assignee.indexOf("{"); int index2 = assignee.indexOf("}"); varables.put(assignee.substring(index1 + 1, index2), applyModel.getProPerson()); break; } } // /////////////////////////// runtimeService.startProcessInstanceByKey(processKey, varables); map.put("userName", (String) req.getSession().getAttribute("userName")); map.put("isLogin", "yes"); map.put("result", "success"); } else { map.put("result", "fail"); } } else { map.put("isLogin", "no"); } return map; }
3.angular js前台代码,:
(1)app.js中配置路由:
$stateProvider .state('startProcess', { url: "/startProcess", views: { 'view': { templateUrl: 'activi_views/startProcess.html', controller: 'startProcessCtr' } } });
(2)逻辑相关代码:
angular.module('activitiApp') .controller('startProcessCtr', ['$rootScope','$scope','$http','$location', function($rootScope,$scope,$http,$location){ $http.post("createFlush.do").success(function(result){ if(result.isLogin==="yes"){ $rootScope.userName=result.userName; $scope.process1={"proDefId":"","key":"","appPerson":"","cause":"","content":"","proPerson":"","name":""}; if($rootScope.process==null||$rootScope.process.key==null){ $location.path("/processList"); }else{ $scope.process1.proDefId=$rootScope.process.id; $scope.process1.key=$rootScope.process.key; $scope.process1.name=$rootScope.process.name; } }else{ $location.path("/login"); } }); $scope.startProcess=function(process){ console.log(process); $http.post("./startProcess.do",process).success(function(deployResult){ $location.path("/taskList"); }); } }])
4.对应的填写相关信息的页面:
<center> <div style="margin-top:20px;margin-left:200px;background-color:#9cc;height:500px;width:50%;font-size:22px;position:relative;float:left;"> <p style="font-size:28px">新建申请</p> 流程定义id:<input type="text" ng-model="process1.proDefId" readonly="readonly" style="background-color:#9dc"/> </br> </br> 流程定义key:<input type="text" ng-model="process1.key" readonly="readonly" style="background-color:#9dc"/> </br> </br> 申请类型:<input type="text" ng-model="process1.name" readonly="readonly" style="background-color:#9dc"/> </br> </br> 申请人:<input type="text" ng-model="process1.appPerson" /> </br> </br> 申请原因:<input type="text" ng-model="process1.cause"/> </br> </br> 申请内容:<input type="text" ng-model="process1.content"/> </br> </br> 受理人:<input type="text" ng-model="process1.proPerson"/> </br> </br> <input style="font-size:24px;cursor:pointer" type="button" value="提交申请" ng-click="startProcess(process1);"> <input style="font-size:24px;cursor:pointer" type="button" value="返回"> </div> </center>
5.成功启动一个流程实例后,会看到act_ru_execution、act_ru_identitylink、act_ru_task、act_ru_variable以及act_hi_actinst、act_hi_detail、act_hi_indentitylink、act_hi_procinst、act_hi_taskinst、act_hi_varinst表中都有了数据。除开variable和varinst中的数据条数是根据对应的流程变量多少来定的,其他都是增加了一条数据。