在springBoot项目中使用activiti


声明:本文转载自https://my.oschina.net/silenceyawen/blog/1609603,转载目的在于传递更多信息,仅供学习交流之用。如有侵权行为,请联系我,我会及时删除。

依赖:

新建springBoot项目时勾选activiti,或者在已建立的springBoot项目添加以下依赖:

<dependency> 	<groupId>org.activiti</groupId> 	<artifactId>activiti-spring-boot-starter-basic</artifactId> 	<version>6.0.0</version> </dependency>

配置:

数据源和activiti配置:

server:   port: 8081  spring:   datasource:     url: jdbc:mysql://localhost:3306/act5?useSSL=true     driver-class-name: com.mysql.jdbc.Driver     username: root     password: root    # activiti default configuration   activiti:     database-schema-update: true     check-process-definitions: true     process-definition-location-prefix: classpath:/processes/ #    process-definition-location-suffixes: #      - **.bpmn #      - **.bpmn20.xml     history-level: full

在activiti的默认配置中,process-definition-location-prefix 是指定activiti流程描述文件的前缀(即路径),启动时,activiti就会去寻找此路径下的流程描述文件,并且自动部署;suffix 是一个String数组,表示描述文件的默认后缀名,默认以上两种。

springMVC配置:

package com.yawn.config;  import org.springframework.context.annotation.Configuration; import org.springframework.format.FormatterRegistry; import org.springframework.http.HttpStatus; import org.springframework.web.servlet.config.annotation.*;  /**  * Created by yawn on 2017/8/5.  */ @EnableWebMvc @Configuration public class MvcConfig extends WebMvcConfigurerAdapter {      @Override     public void addResourceHandlers(ResourceHandlerRegistry registry) {         registry.addResourceHandler("/static/**").addResourceLocations("classpath:/static/");         registry.addResourceHandler("/templates/**").addResourceLocations("classpath:/templates/");         super.addResourceHandlers(registry);     }      @Override     public void addViewControllers(ViewControllerRegistry registry) {         registry.addViewController("/index");         registry.addViewController("/user");         registry.addRedirectViewController("/","/templates/login.html"); //        registry.addStatusController("/403", HttpStatus.FORBIDDEN);         super.addViewControllers(registry);     } } 

这里配置静态资源和直接访问的页面: 在本示例项目中,添加了thymeleaf依赖解析视图,主要采用异步方式获取数据,通过angularJS进行前端数据的处理和展示。

使用activiti:

配置了数据源和activiti后,启动项目,activiti 的各个服务组件就已经被加入到spring容器中了,所以就可以直接注入使用了。如果在未自动配置的spring环境中,可以使用通过指定bean的init-method来配置activiti的服务组件。

案例:

以以下请假流程为例:

1. 开始流程并“申请请假”(员工)

    private static final String PROCESS_DEFINE_KEY = "vacationProcess";       public Object startVac(String userName, Vacation vac) {          identityService.setAuthenticatedUserId(userName);         // 开始流程         ProcessInstance vacationInstance = runtimeService.startProcessInstanceByKey(PROCESS_DEFINE_KEY);         // 查询当前任务         Task currentTask = taskService.createTaskQuery().processInstanceId(vacationInstance.getId()).singleResult();         // 申明任务         taskService.claim(currentTask.getId(), userName);          Map<String, Object> vars = new HashMap<>(4);         vars.put("applyUser", userName);         vars.put("days", vac.getDays());         vars.put("reason", vac.getReason());         // 完成任务         taskService.complete(currentTask.getId(), vars);          return true;     }

在此方法中,Vaction 是申请时的具体信息,在完成“申请请假”任务时,可以将这些信息设置成参数。

2. 审批请假(老板)

(1)查询需要自己审批的请假

    public Object myAudit(String userName) {         List<Task> taskList = taskService.createTaskQuery().taskCandidateUser(userName)                 .orderByTaskCreateTime().desc().list(); //        / 多此一举 taskList中包含了以下内容(用户的任务中包含了所在用户组的任务) //        Group group = identityService.createGroupQuery().groupMember(userName).singleResult(); //        List<Task> list = taskService.createTaskQuery().taskCandidateGroup(group.getId()).list(); //        taskList.addAll(list);         List<VacTask> vacTaskList = new ArrayList<>();         for (Task task : taskList) {             VacTask vacTask = new VacTask();             vacTask.setId(task.getId());             vacTask.setName(task.getName());             vacTask.setCreateTime(task.getCreateTime());             String instanceId = task.getProcessInstanceId();             ProcessInstance instance = runtimeService.createProcessInstanceQuery().processInstanceId(instanceId).singleResult();             Vacation vac = getVac(instance);             vacTask.setVac(vac);             vacTaskList.add(vacTask);         }         return vacTaskList;     }      private Vacation getVac(ProcessInstance instance) {         Integer days = runtimeService.getVariable(instance.getId(), "days", Integer.class);         String reason = runtimeService.getVariable(instance.getId(), "reason", String.class);         Vacation vac = new Vacation();         vac.setApplyUser(instance.getStartUserId());         vac.setDays(days);         vac.setReason(reason);         Date startTime = instance.getStartTime(); // activiti 6 才有         vac.setApplyTime(startTime);         vac.setApplyStatus(instance.isEnded() ? "申请结束" : "等待审批");         return vac;     }
package com.yawn.entity;  import java.util.Date;  /**  * @author Created by yawn on 2018-01-09 14:31  */ public class VacTask {      private String id;     private String name;     private Vacation vac;     private Date createTime;      // getter setter ... } 

老板查询自己当前需要审批的任务,并且将任务和参数设置到一个VacTask对象,用于页面的展示。

(2)审批请假

    public Object passAudit(String userName, VacTask vacTask) {         String taskId = vacTask.getId();         String result = vacTask.getVac().getResult();         Map<String, Object> vars = new HashMap<>();         vars.put("result", result);         vars.put("auditor", userName);         vars.put("auditTime", new Date());         taskService.claim(taskId, userName);         taskService.complete(taskId, vars);         return true;     }

同理,result是审批的结果,也是在完成审批任务时需要传入的参数;taskId是刚才老板查询到的当前需要自己完成的审批任务ID。(如果流程在这里设置分支,可以通过判断result的值来跳转到不同的任务)

3. 查询记录

由于已完成的请假在数据库runtime表中查不到(runtime表只保存正在进行的流程示例信息),所以需要在history表中查询。

(1) 查询请假记录

    public Object myVacRecord(String userName) {         List<HistoricProcessInstance> hisProInstance = historyService.createHistoricProcessInstanceQuery()                 .processDefinitionKey(PROCESS_DEFINE_KEY).startedBy(userName).finished()                 .orderByProcessInstanceEndTime().desc().list();          List<Vacation> vacList = new ArrayList<>();         for (HistoricProcessInstance hisInstance : hisProInstance) {             Vacation vacation = new Vacation();             vacation.setApplyUser(hisInstance.getStartUserId());             vacation.setApplyTime(hisInstance.getStartTime());             vacation.setApplyStatus("申请结束");             List<HistoricVariableInstance> varInstanceList = historyService.createHistoricVariableInstanceQuery()                     .processInstanceId(hisInstance.getId()).list();             ActivitiUtil.setVars(vacation, varInstanceList);             vacList.add(vacation);         }         return vacList;     }

 请假记录即查出历史流程实例,再查出关联的历史参数,将历史流程实例和历史参数设置到Vcation对象(VO对象)中去,即可返回,用来展示。

package com.yawn.util;  import org.activiti.engine.history.HistoricVariableInstance;  import java.lang.reflect.Field; import java.util.List;  /**  * activiti中使用得到的工具方法  * @author Created by yawn on 2018-01-10 16:32  */ public class ActivitiUtil {      /**      * 将历史参数列表设置到实体中去      * @param entity 实体      * @param varInstanceList 历史参数列表      */     public static <T> void setVars(T entity, List<HistoricVariableInstance> varInstanceList) {         Class<?> tClass = entity.getClass();         try {             for (HistoricVariableInstance varInstance : varInstanceList) {                 Field field = tClass.getDeclaredField(varInstance.getVariableName());                 if (field == null) {                     continue;                 }                 field.setAccessible(true);                 field.set(entity, varInstance.getValue());             }         } catch (Exception e) {             e.printStackTrace();         }     } } 

此外,以上是查询历史流程实例和历史参数后,设置VO对象的通用方法:可以根据参数列表中的参数,将与VO对象属性同名的参数设置到VO对象中去。

4. 前端展示和操作

(1)审批列表和审批操作示例

    <div ng-controller="myAudit">         <h2 ng-init="myAudit()">待我审核的请假</h2>         <table border="0">             <tr>                 <td>任务名称</td>                 <td>任务时间</td>                 <td>申请人</td>                 <td>申请时间</td>                 <td>天数</td>                 <td>事由</td>                 <td>操作</td>             </tr>             <tr ng-repeat="vacTask in vacTaskList">                 <td>{{vacTask.name}}</td>                 <td>{{vacTask.createTime | date:'yyyy-MM-dd HH:mm:ss'}}</td>                 <td>{{vacTask.vac.applyUser}}</td>                 <td>{{vacTask.vac.applyTime | date:'yyyy-MM-dd HH:mm:ss'}}</td>                 <td>{{vacTask.vac.days}}</td>                 <td>{{vacTask.vac.reason}}</td>                 <td>                     <button type="button" ng-click="passAudit(vacTask.id, 1)">审核通过</button>                     <button type="button" ng-click="passAudit(vacTask.id, 0)">审核拒绝</button>                 </td>             </tr>         </table>     </div>
app.controller("myAudit", function ($scope, $http, $window) {     $scope.vacTaskList = [];      $scope.myAudit = function () {         $http.get(             "/myAudit"         ).then(function (response) {             $scope.vacTaskList = response.data;         })     };      $scope.passAudit = function (taskId, result) {         $http.post(             "/passAudit",             {                 "id": taskId,                 "vac": {                     "result": result >= 1 ? "审核通过" : "审核拒绝"                 }             }         ).then(function (response) {             if (response.data === true) {                 alert("操作成功!");                 $window.location.reload();             } else {                 alert("操作失败!");             }         })     } }); 

 

以上是一个springBoot 与 activiti 6.0 整合的示例项目的部分代码与说明,完整的项目代码在:

https://gitee.com/yawensilence/activiti-demo6-springboot 。

本文发表于2018年01月20日 12:32
(c)注:本文转载自https://my.oschina.net/silenceyawen/blog/1609603,转载目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责。如有侵权行为,请联系我们,我们会及时删除.

阅读 3195 讨论 0 喜欢 2

抢先体验

扫码体验
趣味小程序
文字表情生成器

闪念胶囊

你要过得好哇,这样我才能恨你啊,你要是过得不好,我都不知道该恨你还是拥抱你啊。

直抵黄龙府,与诸君痛饮尔。

那时陪伴我的人啊,你们如今在何方。

不出意外的话,我们再也不会见了,祝你前程似锦。

这世界真好,吃野东西也要留出这条命来看看

快捷链接
网站地图
提交友链
Copyright © 2016 - 2021 Cion.
All Rights Reserved.
京ICP备2021004668号-1