文章目录
学习目的设计思想使用流程变量流程部署及执行测试类LeaveServiceLeaveServiceImpl
学习目的
为了解决项目中某些特殊的业务场景,流程审批业务(请假审批,出差审批,申请单审批,报销单审批,公文的流转)。
设计思想
比如开发请假流程(员工请假申请apply–>部门经理审批–>if(请假天数>3天)–>总经理审批–>结束
-->if(请假天数<=3天)–>结束)。
第一步:提供了ide插件,可视化流程定义,以bpmn流程定义描述性语言(xml描述)。
第二步:提供api服务接口,进行部署流程定义(解析xml, 把xml流程数据保存到数据库)。
第三步:开发请假申请业务(增删改查),调用组件api服务去驱动流程向下一步步的执行。
使用
搭建activiti数据库环境(各种组件内的表)
运行三个sql脚本创建数据库表
act_ge_*:元数据表(存储引擎版本信息,流程定义xml文件数据)act_id_*:用户与角色表(存储系统用户与用户组信息)act_re_*:流程部署表(存储流程部署信息,流程定义文件信息)act_ru_*:正在执行当中的流程数据表(存储流程实例与任务信息)act_hi_*:执行完结的流程数据历史表(存储历史流程实例与历史任务信息) 搭建代码环境 (依赖jar包)与spring集成使用,依赖mybatis
引入依赖jar创建activiti的xml配置文件,注入spring容器相关的bean对象(ProcessEngineConfiguration,ProcessEngine,5个核心服务bean)
pom
<dependency>
<groupId>org.activiti
</groupId>
<artifactId>activiti-spring
</artifactId>
<version>5.22.0
</version>
</dependency>
activiti.cfg.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="processEngineConfiguration" class="org.activiti.spring.SpringProcessEngineConfiguration">
<property name="dataSource" ref="dataSource"/>
<property name="transactionManager" ref="transactionManager"/>
<property name="databaseSchemaUpdate" value="false"/>
<property name="jobExecutorActivate" value="false"/>
</bean>
<bean id="processEngine" class="org.activiti.spring.ProcessEngineFactoryBean">
<property name="processEngineConfiguration" ref="processEngineConfiguration"/>
</bean>
<bean id="repositoryService" factory-bean="processEngine" factory-method="getRepositoryService"/>
<bean id="runtimeService" factory-bean="processEngine" factory-method="getRuntimeService"/>
<bean id="identityService" factory-bean="processEngine" factory-method="getIdentityService"/>
<bean id="taskService" factory-bean="processEngine" factory-method="getTaskService"/>
<bean id="historyService" factory-bean="processEngine" factory-method="getHistoryService"/>
</beans>
设计流程定义文件并进行部署
安装插件:actiBpm
流程定义的节点(id,name,assignee|candidate users|candidate groups(节点的执行人))
生成png图片
进行流程部署
自己建立的任务表,一定要有对应的任务id字段(processid)
流程变量
流程定义中的表达式,称为流程变量
${loginUser}
groups: deptMgr
users:mgr1,mgr2
${days<=3}
${approveResult}:审批通过与否
流程部署及执行
测试类
@RunWith(SpringJUnit4ClassRunner
.class)
@ContextConfiguration("classpath:spring.xml")
public class activitiTest {
@Resource
private LeaveService leaveService
;
@Resource
private RepositoryService rs
;
@Resource
private IdentityService is
;
@Test
public void deployTest() {
DeploymentBuilder deployment
= rs
.createDeployment();
deployment
.name("请假申请");
deployment
.addClasspathResource("bpmn/LeaveApply.bpmn");
deployment
.addClasspathResource("bpmn/LeaveApply.png");
Deployment deploy
= deployment
.deploy();
String id
= deploy
.getId();
System
.out
.println(id
);
}
@Test
public void deployQueryTest() {
DeploymentQuery deploymentQuery
= rs
.createDeploymentQuery();
List
<Deployment> list
= deploymentQuery
.list();
System
.out
.println(list
);
}
@Test
public void addUser() {
User wj
= is
.newUser("wj");
User deptMgr1
= is
.newUser("deptMgr1");
User deptMgr2
= is
.newUser("deptMgr2");
User mgr1
= is
.newUser("mgr1");
User mgr2
= is
.newUser("mgr2");
is
.saveUser(wj
);
is
.saveUser(deptMgr1
);
is
.saveUser(deptMgr2
);
is
.saveUser(mgr1
);
is
.saveUser(mgr2
);
}
@Test
public void addGroup() {
Group employee
= is
.newGroup("employee");
Group deptMgr
= is
.newGroup("deptMgr");
Group mgr
= is
.newGroup("mgr");
is
.saveGroup(employee
);
is
.saveGroup(deptMgr
);
is
.saveGroup(mgr
);
}
@Test
public void addMemberShip() {
is
.createMembership("wj", "employee");
is
.createMembership("deptMgr1", "deptMgr");
is
.createMembership("deptMgr2", "deptMgr");
is
.createMembership("mgr1", "mgr");
is
.createMembership("mgr2", "mgr");
}
@Test
public void addLeaveApplyTest() {
LeaveApply apply
= new LeaveApply();
apply
.setLapplyuser("张三");
apply
.setLreason("探亲");
apply
.setLdays("10");
leaveService
.addLeaveApply(apply
);
}
@Test
public void addLeaveApplyAndStartProcessTest() {
String loginUser
= "wj";
LeaveApply apply
= new LeaveApply();
apply
.setLapplyuser("wj");
apply
.setLreason("探亲");
apply
.setLdays("10");
leaveService
.startProcess(apply
, loginUser
);
}
@Test
public void getTodoTask(){
String loginUser
="deptMgr2";
List
<Task> todoTask
= leaveService
.getTodoTask(loginUser
);
System
.out
.println(todoTask
);
}
@Test
public void claimTask(){
String loginUser
="mgr2";
String taskid
= "17505";
ls
.claimTask(loginUser
,taskid
);
}
@Test
public void approve(){
String loginUser
="mgr2";
String taskid
= "17505";
boolean approveResult
= true;
ls
.approveTask(loginUser
,taskid
,"回家吧",approveResult
);
}
}
LeaveService
public interface ILeaveService {
public void addLeaveApply(LeaveApply apply
);
void startProcess(LeaveApply la
,String loginUser
);
List
<ProcessTask> getTodoTask(String loginUser
);
void claimTask(String loginUser
, String taskid
);
void approveTask(String loginUser
, String taskid
,String comment
,boolean approveResult
);
}
LeaveServiceImpl
@Service
public class LeaveServiceImpl implements ILeaveService {
@Resource
private LeaveApplyMapper lm
;
@Resource
private RuntimeService rs
;
@Resource
private TaskService ts
;
@Override
public void addLeaveApply(LeaveApply apply
) {
lm
.insertSelective(apply
);
}
@Transactional
@Override
public void startProcess(LeaveApply la
,String loginUser
) {
addLeaveApply(la
);
Map
<String,Object> valiables
= new HashMap<>();
valiables
.put("loginUser",loginUser
);
valiables
.put("days",la
.getLdays());
ProcessInstance processInstance
= rs
.startProcessInstanceByKey("LEAVE_APPLY",valiables
);
String processInstanceId
= processInstance
.getId();
String taskid
= querySingTaskByAssigneeAndPid(processInstanceId
,loginUser
).getId();
ts
.complete(taskid
);
la
.setProcessid(processInstanceId
);
updateProcessId(la
);
}
@Override
public List
<ProcessTask> getTodoTask(String loginUser
) {
List
<ProcessTask> result
= new ArrayList<>();
TaskQuery taskQuery
= ts
.createTaskQuery();
taskQuery
.taskCandidateOrAssigned(loginUser
);
taskQuery
.processDefinitionKey("LEAVE_APPLY");
List
<Task> list
= taskQuery
.list();
for (Task t
:list
){
String processInstanceId
= t
.getProcessInstanceId();
LeaveApply leaveApply
= queryLeaveApplyByProcessId(processInstanceId
);
ProcessTask pt
= new ProcessTask();
pt
.setOrder(leaveApply
);
pt
.setTask(t
);
result
.add(pt
);
}
return result
;
}
@Override
public void claimTask(String loginUser
, String taskid
) {
ts
.claim(taskid
,loginUser
);
}
public LeaveApply
queryLeaveApplyByProcessId(String processid
){
LeaveApply la
= lm
.selectByProcessId(processid
);
return la
;
}
public void updateProcessId(LeaveApply la
){
lm
.updateByPrimaryKeySelective(la
);
}
public Task
querySingTaskByAssigneeAndPid(String processInstanceId
,String assignee
){
TaskQuery taskQuery
= ts
.createTaskQuery();
taskQuery
.processInstanceId(processInstanceId
);
taskQuery
.taskAssignee(assignee
);
Task task
= taskQuery
.singleResult();
return task
;
}
@Override
public void approveTask(String loginUser
,String taskid
,String comment
, boolean approveResult
) {
TaskQuery taskQuery
= ts
.createTaskQuery();
taskQuery
.taskId(taskid
);
String processInstanceId
= taskQuery
.singleResult().getProcessInstanceId();
Map
<String,Object> valiables
= new HashMap<>();
valiables
.put("approveResult",approveResult
);
ts
.addComment(taskid
,processInstanceId
,"通过",comment
);
ts
.complete(taskid
,valiables
);
}
}