文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

SpringBoot整合工作流引擎Activiti

2024-11-30 11:40

关注

环境说明:


  
    org.activiti.dependencies
    activiti-dependencies
    7.1.0.M6
    pom
  
  
    org.activiti
    activiti-spring-boot-starter
    7.1.0.M6
  
  
    org.springframework.boot
    spring-boot-starter-security
  
  
    org.springframework.boot
    spring-boot-starter-web
  
  
    org.mybatis.spring.boot
    mybatis-spring-boot-starter
    2.1.4
  
  
    mysql
    mysql-connector-java
    runtime
  
  
    org.springframework.boot
    spring-boot-starter-test
    test
    
      
        org.junit.vintage
        junit-vintage-engine
      
    
  

不知为何activit7中要吧这security强关联。。。

以上是pom.xml中所要引入的依赖。


所有的表:

图片

表结构说明:

ACT_RE_*: 'RE’表示repository。这个前缀的表包含了流程定义和流程 静态资源(图片、规则等等)

ACT_RU_*: 'RU’表示runtime。这些运行时的表,包含流程实例,认为,变量,异步任务等运行中的数据。Activiti只在流程实例执行过程中保持这些数据,在流程结束时就会删除这些记录。这样运行时表可以一直很小速度很快。

ACT_HI_*: 'HI’表示history。这些表包含历史数据,比如历史流程实例,遍历,任务等等。

ACT_GE_*: 'GE’表示general。通用数据,用于不同场景。

数据表分类

通用数据(act_ge_*)

图片

流程定义(act_re_*)

图片

运行实例(act_ru_*)

图片

历史流程(act_hi_*)

图片

其他

图片

来源网络


核心类

ProcessEngine

    流程引擎的抽象,可以通过此类获取需要的所有服务。

    通过ProcessEngine获取,Activiti将不同生命周期的服务封装在不同Service中,包括定义、部署、运行。通过服务类可获取相关生命周期中的服务信息。

TaskService

    流程运行过程中,每个任务节点的相关操作接口,如complete,delete,delegate等。
RepositoryService

    流程定义和部署相关的存储服务。
RuntimeService

    流程运行时相关的服务,如根据流程好启动流程实例startProcessInstanceByKey。
HistoryService

    历史记录相关服务接口。

关于eclipse中安装插件就不说了,我是把插件下载下来安装的,在线安装不上。

设计请假流程

在src/main/resources下新建processes文件夹,springboot下默认的流程文件定义路径前缀及文件后缀如下:

图片

这里可以在application.yml配置文件中更改。

设计一个请假的流程holiday.bpmn

图片



  
    
    
    
    
    
    
    
    
    
  
  
    
      
        
      
      
        
      
      
        
      
      
        
      
      
        
      
      
        
        
      
      
        
        
      
      
        
        
      
      
        
        
      
    
  

上面的每一个节点(任务)都动态的指派了用户执行。

填写审批单:${assignee};

部门经理审批: ${mgr};

总经理审批:${top};

每一个节点执行完成时都需要指明下一个节点的执行人。

配置文件

mybatis:
  mapper-locations: classpath:mapper
  public void createDeploy() {
    Deployment deployment = repositoryService.createDeployment()
        .addClasspathResource("processes/holiday.bpmn")
        .addClasspathResource("processes/holiday.png")
        .name("请假申请单流程")
        .key("holiday")
        .category("InnerP")
        .deploy();
    logger.info("流程部署id: {}", deployment.getId());
    logger.info("流程部署名称: {}", deployment.getName());
  }
  // 注意这里这个方法是当我们没有开启自动部署流程定义时,就需要手动部署。
  
  public List queryProcessDefinitionByKey(String processDefinition) {
    // 查询流程定义
    ProcessDefinitionQuery processDefinitionQuery = repositoryService.createProcessDefinitionQuery();
    List list = processDefinitionQuery.processDefinitionKey(processDefinition).list();
    list.forEach(pd -> {
      logger.info("------------------------------------------------");
      logger.info("流程部署id:{}", pd.getDeploymentId());
      logger.info("流程定义id:{}", pd.getId());
      logger.info("流程定义名称:{}", pd.getName());
      logger.info("流程定义key:{}", pd.getKey());
      logger.info("流程定义版本:{}", pd.getVersion());
      logger.info("------------------------------------------------");
    });
    return list ;
  }


  
  public void deleteDeployment(String deploymentId) {
    // 设置true 级联删除流程定义,即使该流程有流程实例启动也可以删除,设置为false非级别删除方式,如果流程
    repositoryService.deleteDeployment(deploymentId, true);
  }


  
  public void startProcessInstanceById(String processDefinitionId) {
    ProcessInstance processInstance = runtimeService.startProcessInstanceById(processDefinitionId) ;
    logger.info("流程定义ID: {}", processInstance.getProcessDefinitionId());
    logger.info("流程实例ID: {}", processInstance.getId());
  }
  
  
  public void startProcessInstanceToBussinessKey(String processDefinitionId, String bussinessKey) {
    ProcessInstance processInstance = runtimeService.startProcessInstanceById(processDefinitionId, bussinessKey);
    logger.info("流程定义ID: {}", processInstance.getProcessDefinitionId());
    logger.info("流程实例ID: {}", processInstance.getId());
    logger.info("BussinessKey: {}", processInstance.getBusinessKey()) ;
  }
  
  
  public void startProcessInstanceAssignVariables(String processDefinitionId, Map variables) {
    ProcessInstance processInstance = runtimeService.startProcessInstanceById(processDefinitionId, variables);
    logger.info("流程定义ID: {}", processInstance.getProcessDefinitionId());
    logger.info("流程实例ID: {}", processInstance.getId());
    logger.info("BussinessKey: {}", processInstance.getBusinessKey()) ;
  }
  
  
  public List queryTasks(String assignee) {
    TaskQuery query = taskService.createTaskQuery() ;
    return query.taskAssignee(assignee).orderByTaskCreateTime().asc().list() ;
  }
  
  public void executionTask(Map variables, String instanceId) {
    Task task = taskService.createTaskQuery().processInstanceId(instanceId).singleResult() ;
    if (task == null) {
      logger.error("任务【{}】不存在", instanceId) ;
      throw new RuntimeException("任务【" + instanceId + "】不存在") ;
    }
    taskService.complete(task.getId(), variables) ;
  }


}


@RestController
@RequestMapping("/holidays")
public class HolidayController {
  
  @Resource
  private HolidayService holidayService ;
  
  
  @GetMapping("")
  public R lists(String key) {
    return R.success(holidayService.queryProcessDefinitionByKey(key)) ;
  }
  
  
  @GetMapping("/_deploy")
  public R createDeploy() {
    holidayService.createDeploy();
    return R.success() ;
  }
  
  
  @GetMapping("/start")
  public R startProcess(String userId, String processDefinitionId) {
    Map variables = new HashMap<>() ;
    variables.put("assignee", userId) ;
    holidayService.startProcessInstanceAssignVariables(processDefinitionId, variables) ;
    return R.success() ;
  }
  
  
  @GetMapping("/tasks")
  public R myTasks(String userId) {
    List list = holidayService.queryTasks(userId) ;
    // 注意这里需要我们自己组装下数据,不然会报错。
    List> result = list.stream().map(task -> {
      Map res = new HashMap() ;
      res.put("id", task.getId()) ;
      res.put("assignee", task.getAssignee()) ;
      res.put("createTime", task.getCreateTime()) ;
      res.put("bussinessKey", task.getBusinessKey()) ;
      res.put("category", task.getCategory()) ;
      res.put("dueDate", task.getDueDate()) ; // 到期日期
      res.put("desc", task.getDescription()) ;
      res.put("name", task.getName()) ;
      res.put("owner", task.getOwner()) ;
      res.put("instanceId", task.getProcessInstanceId()) ;
      res.put("variables", task.getProcessVariables()) ;
      return res ;
    }).collect(Collectors.toList()) ;
    return R.success(result) ;
  }
  
  
  @GetMapping("/apply")
  public R fillApply(@RequestParam Map variables) {
    String instanceId = (String) variables.remove("instanceId") ;
    if (StringUtils.isEmpty(instanceId)) {
      return R.failure("未知任务") ;
    }
    holidayService.executionTask(variables, instanceId);
    return R.success() ; 
  }
  
}

测试:

启动服务

这里放在processes中的流程定义文件已经被自动部署上了。查看表act_re_procdef

  1. 查询制定key的流程审批
    接口:/holidays

图片

  1. 启动请假审批流程
    接口:/holidays/start

图片

参数:
processDefinitionId:流程定义中的ID。
userId:要处理用户的id。

查看表信息:

图片

这时候就为用户id为:10000的生成了一个要处理的任务,填写审批单。

  1. 查询指派给我需要处理的任务
    接口:/holidays/tasks

图片

  1. 填写审批单
    接口:/holidays/apply

图片

参数:
mgr:指定下一个节点处理人。
explain:请假原因。
days:请假天数。

这里根据自己的业务需要去设置。

再次调用查询接口userId=10002

图片

流程已经到了部门经理。

再次调用/holidays/apply接口。

图片

参数:
top:指明总经理节点需要处理的userId。

图片

再次调用/holidays/apply接口。(总经理处理)

图片

查询对应的任务表信息,已经没有数据了。

图片

查询表:act_hi_actinst

图片

到此一个流程就走完了。下篇 查看流程图。

完毕!!!

来源:实战案例锦集内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯