activiti工作流引擎组件

学习目的

  • 为了解决项目中某些特殊的业务场景,流程审批业务(请假审批,出差审批,申请单审批,报销单审批,公文的流转)。

设计思想

  • 比如开发请假流程(员工请假申请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);
    }
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值