activiti工作流引擎组件

    科技2025-05-06  58

    文章目录

    学习目的设计思想使用流程变量流程部署及执行测试类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> <!-- 这个是activiti的核心类,这个类依赖另一个类processEngineConfiguration --> <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(); // 执行数据库的insert操作 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"); // 部门经理1 User deptMgr2 = is.newUser("deptMgr2"); // 部门经理2 User mgr1 = is.newUser("mgr1"); // 总经理1 User mgr2 = is.newUser("mgr2"); // 总经理2 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); } //获取代办任务列表,deptMgr1与deptMgr2登录系统后都能看到部门经理审批的任务 @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); //开始流程(流程定义的key,流程依赖的变量) 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(); //把请假申请task继续向下执行 String taskid = querySingTaskByAssigneeAndPid(processInstanceId,loginUser).getId(); ts.complete(taskid);//完成某个task //把processInstanceId作为外键关联到请假申请单 la.setProcessid(processInstanceId); updateProcessId(la); } //获取所有的代办任务列表(包含申请单信息以及Task对象信息) @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(); //根据流程实例id,去查询申请单详情。 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); } //根据流程实例id与执行人查询task对象 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); } }
    Processed: 0.010, SQL: 8