若依框架SpringBoot+Activiti工作流的使用

若依框架SpringBoot+Activiti工作流的使用

使用简介:本技术点主要是针对类审批的业务流程的建模,可以有:任务发布(即流程开始)到一级一级的审批到最终结束(即流程结束)一整套完备的模型

1、idea下载activiti插件

  1. ider以前版本下载actiBPM,但是新版ider这个插件已经被淘汰,已经被下面这个替代

 

 

2、单独起一个activiti服务

3、添加依赖在activiti服务中:

<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-test</artifactId>
</dependency>
<dependency>
   <groupId>org.activiti</groupId>
   <artifactId>activiti-spring-boot-starter</artifactId>
   <version>7.0.0.Beta2</version>
</dependency>
<dependency>
   <groupId>org.mybatis.spring.boot</groupId>
   <artifactId>mybatis-spring-boot-starter</artifactId>
   <version>2.0.0</version>
</dependency>
<dependency>
   <groupId>mysql</groupId>
   <artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
   <groupId>org.projectlombok</groupId>
   <artifactId>lombok</artifactId>
</dependency>

4、添加配置

我这里的服务结构:

 

a、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"
      xmlns:context="http://www.springframework.org/schema/context"
      xmlns:tx="http://www.springframework.org/schema/tx"
      xsi:schemaLocation="http://www.springframework.org/schema/beans
                   http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/contex
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">
   <!-- 默认id对应的值 为processEngineConfiguration -->
   <!-- processEngine Activiti的流程引擎 -->
   <bean id="processEngineConfiguration"
         class="org.activiti.engine.impl.cfg.StandaloneProcessEngineConfiguration">
       <property name="jdbcDriver" value="***.mysql.cj.jdbc.Driver"/>
       <property name="jdbcUrl" value="jdbc:mysql://*****:3306/activiti"/>
       <property name="jdbcUsername" value="root"/>
       <property name="jdbcPassword" value="*****"/>
       <!-- activiti数据库表处理策略 不存在就创建表-->
       <property name="databaseSchemaUpdate" value="true"/>
   </bean>
</beans>

配置讲解:

 

b、添加log4j的配置(无需修改,直接粘):

# Set root category priority to INFO and its only appender to CONSOLE.
#log4j.rootCategory=INFO, CONSOLE debug info warn error fatal
log4j.rootCategory=debug, CONSOLE, LOGFILE
# Set the enterprise logger category to FATAL and its only appender to CONSOLE.
log4j.logger.org.apache.axis.enterprise=FATAL, CONSOLE
# CONSOLE is set to be a ConsoleAppender using a PatternLayout.
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern=%d{ISO8601} %-6r[%15.15t] %-5p %30.30c %x - %m\n
# LOGFILE is set to be a File appender using a PatternLayout.
log4j.appender.LOGFILE=org.apache.log4j.FileAppender
log4j.appender.LOGFILE.File=d:\XX\activiti.log
log4j.appender.LOGFILE.Append=true
log4j.appender.LOGFILE.layout=org.apache.log4j.PatternLayout
log4j.appender.LOGFILE.layout.ConversionPattern=%d{ISO8601} %-6r[%15.15t] %-5p %30.30c %x - %m\n

  1. 创建流程图文件:

 

在创建好的文件中任意位置右键,选择 View BPMN Diagram,打开可视化界面(流程定义的界面

任意右键选择定义流程:

 

 

 

 

解决图片乱码问题

1.打开 IDEA 安装路径,找到如下的安装目录

追加一条命令: -Dfile.encoding=UTF-8
如下所示

至此activiti的准备工作结束,一下是代码部分:

一、demo代码示例:
public class TestCreateTable {
   /**
    * 生成 activiti的数据库表
    */
   @Test
   public void testCreateDbTable() {
       //使用classpath下的activiti.cfg.xml中的配置创建processEngine
       //如果使用默认则需要上面activiti.cfg.xml配置
       ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
       System.out.println(processEngine);
   }

   //部署
   @Test
   public void test01() {
       //1、创建ProcessEngine
       ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
       //2、得到RepositoryService实例
       RepositoryService repositoryService = processEngine.getRepositoryService();
       //3、使用RepositoryService进行部署
       Deployment deploy = repositoryService.createDeployment().addClasspathResource("bpmn/chuchai.bpmn20.xml")
               .addClasspathResource("bpmn/diagram.png")
               .name("团购申请v1.0")
               .deploy();
       //4、输出部署信息
       System.out.println("部署id"+deploy.getId());
       System.out.println("部署的任务名称:"+deploy.getName());
   }

   //启动流程
   @Test
   public void testDeploy() {
       //1.创建ProcessEngine对象
       ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
       //创建TaskService
       TaskService taskService = processEngine.getTaskService();

       Map<String, Object> variables = new HashMap<>();
       //张三就是在bpmnAssignee配置的参数
       variables.put("张三", "aaa");
       //3.创建流程实例  流程定义的key需要知道 holiday
       ProcessInstance processInstance = ProcessEngines.getDefaultProcessEngine()
               .getRuntimeService()
               .startProcessInstanceByKey("chuchai", variables);
       Task tmp = taskService.createTaskQuery()
               .processInstanceId(processInstance.getProcessInstanceId()).singleResult();
       tmp.setAssignee("张三");
       //完成此节点。由下一节点审批。完成后act_ru_task会创建一条由下节点审批的数据
       taskService.***plete(tmp.getId(),variables);
       //4.输出实例的相关信息
       System.out.println( "流程部署ID" + processInstance.getDeploymentId() );
       System.out.println( "流程定义ID" + processInstance.getProcessDefinitionId());
       System.out.println( "流程实例ID" + processInstance.getId() );
       System.out.println( "活动ID" + processInstance.getActivityId() );
   }


   @Test
   //查询任务
   public void test(){
       ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
       //创建TaskService
       TaskService taskService = processEngine.getTaskService();
       //根据流程key 和 任务负责人 查询任务
       List<Task> list = taskService.createTaskQuery()
               .processDefinitionKey("chuchai") //流程Key
               .taskAssignee("张三")//只查询该任务负责人的任务
               .list();

       for (Task task : list) {
           System.out.println("流程实例id" + task.getProcessInstanceId());
           System.out.println("任务id" + task.getId());
           System.out.println("任务负责人:" + task.getAssignee());
           System.out.println("任务名称:" + task.getName());
       }

   }

   //审批流程
   @Test
   public void test1(){
       //1.创建ProcessEngine对象
       ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
       //创建TaskService
       TaskService taskService = processEngine.getTaskService();
       //根据角色信息获取自己的待办
       List<Task> T = taskService.createTaskQuery().taskAssignee("zs").list();
       if(!ObjectUtils.isEmpty(T)) {
           for (Task item : T) {
               Map<String, Object> variables = new HashMap<>();
               variables.put("张三", "zs");
               variables.put("isSu***ess", true);
               item.setAssignee("李四");
               //增加审批备注
               taskService.add***ment(item.getId(),item.getProcessInstanceId(),"部门经理同意");
               //完成此次审批。由下节点审批
               taskService.***plete(item.getId(), variables);
           }
       }
   }

   // 结束流程
   @Test
   public void test02() {
       //1.创建ProcessEngine对象
       ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
       //        创建TaskService
       TaskService taskService = processEngine.getTaskService();
       //act_re_execution id
       String taskId = "42503";
       //        任务负责人
       String assingee = "李四";
       Task task = taskService.createTaskQuery()
               .taskId(taskId)
               .taskAssignee(assingee)
               .singleResult();
       if (task != null) {
           HashMap<String, Object> map = new HashMap<>();
           map.put("agree", 1);
           taskService.***plete(taskId, map);

           System.out.println("完成任务");
       }

   }
}

二、项目代码示例:controller层代码(这里是运用到项目中的代码)


@RestController
@RequestMapping("/activiti")
@Slf4j
public class ActivitiController {

   @Autowired
   private IActivitiService iActivitiService;
   //生成25张表
   @GetMapping
   public Result getTables(){
       log.info("开始生成表................................................................");
       Result result = iActivitiService.getTable();
       return result;
   }

   //流程部署
   @GetMapping("/bushu")
   public Result bushu(){
       log.info("部署 ");
       return Result.su***ess("ok");

   }

   //查询个人待执行的任务
   @GetMapping("/list")
   public Result list(){
       log.info("查询个人待执行的任务");
       Result result = iActivitiService.list();
       return result;
   }

   //结束
   @GetMapping("/***plete")
   public Result ***plete(){
       log.info("结束");
       Result result = iActivitiService.***plete();
       return result;
   }
}

Service层代码:


@Service
@Repository
@Slf4j
public class ActivitiServiceImpl implements IActivitiService {

   @Autowired
   public IActivitiMapper iActivitiMapper;

   @Override
   public Result getTable() {
       //使用classpath下的activiti.cfg.xml中的配置创建processEngine
       //如果使用默认则需要上面activiti.cfg.xml配置
       ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
       return Result.su***ess("生成表成功");
   }

   @Override
   public Result bushu() {
       //1、创建ProcessEngine
       ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
       //2、得到RepositoryService实例
       RepositoryService repositoryService = processEngine.getRepositoryService();
       //3、使用RepositoryService进行部署
       Deployment deploy = repositoryService.createDeployment().addClasspathResource("activiti/groupactiviti.bpmn20.xml")
               .addClasspathResource("activiti/groupactiviti.png")
               .name("团购申请审批")
               .deploy();
       //4、输出部署信息
       log.info("部署id"+deploy.getId());
       log.info("部署的任务名称:"+deploy.getName());

       //5、启动流程定义       根据流程定义的id启动流程                           key:act_re_procdef中的KEY
       //创建TaskService
       TaskService taskService = processEngine.getTaskService();

       Map<String, Object> variables = new HashMap<>();
       String username = SecurityUtils.getLoginUser().getSysUser().getUserName();
//        String username = "admin";
       //user就是在bpmnAssignee配置的参数
       variables.put("admin", username);
       //3.创建流程实例  流程定义的key需要知道 holiday
       ProcessInstance processInstance = ProcessEngines.getDefaultProcessEngine()
               .getRuntimeService()
               .startProcessInstanceByKey("groupactiviti", variables);
       System.out.println(processInstance+"=============================================");
       Task tmp = taskService.createTaskQuery()
               .processInstanceId(processInstance.getProcessInstanceId()).singleResult();
       tmp.setAssignee("ry");
       //完成此节点。由下一节点审批。完成后act_ru_task会创建一条由下节点审批的数据
       taskService.***plete(tmp.getId(),variables);
       //4.输出实例的相关信息
       log.info("流程部署ID" + processInstance.getDeploymentId() );
       log.info("流程定义ID" + processInstance.getProcessDefinitionId());
       log.info("流程实例ID" + processInstance.getId());
       log.info("活动ID" + processInstance.getActivityId());
       return Result.su***ess(true,"申请已提交");
   }

   //个人待执行任务
   @Override
   public Result list() {
       ProcessEngine defaultProcessEngine = ProcessEngines.getDefaultProcessEngine();
       TaskService taskService = defaultProcessEngine.getTaskService();
       // 查询当前登录人的任务 进行完成
       String username= SecurityUtils.getLoginUser().getSysUser().getUserName();
       System.out.println("当前登录人"+username);

       if (username == null){
           throw new CheckedException("当前登录人为空");
       }
       List<Task> task = taskService.createTaskQuery()
               .processDefinitionKey("groupactiviti")
               .taskAssignee(username)
               .list();
       System.out.println("==================="+task);
       if(!ObjectUtils.isEmpty(task)) {
           for (Task item : task) {
               Map<String, Object> variables = new HashMap<>();
               if (username.equals("ry")){
                   variables.put("ry", username);
                   variables.put("isSu***ess", true);
                   item.setAssignee("aaa");
                   //增加审批备注
                   taskService.add***ment(item.getId(),item.getProcessInstanceId(),"部门经理已同意");
                   //完成此次审批。由下节点审批  act_hi_taskinst会修改时间
                   taskService.***plete(item.getId(), variables);
               }
               if (username.equals("aaa")){
                   variables.put("aaa", username);
                   variables.put("isSu***ess", true);
                   item.setAssignee("aaa");
                   //增加审批备注
                   taskService.add***ment(item.getId(),item.getProcessInstanceId(),"财务已同意");
                   //完成此次审批。由下节点审批  act_hi_taskinst会修改时间
                   taskService.***plete(item.getId(), variables);
               }
           }
       }
       return Result.su***ess(true,"审核成功");
   }

   // 结束
   @Override
   public Result ***plete() {
       //1.创建ProcessEngine对象
       ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
       //创建TaskService
       TaskService taskService = processEngine.getTaskService();
       // 获取当前登录人 判断是admin才结束任务
       String username = SecurityUtils.getLoginUser().getSysUser().getUserName();
//        String username = "aaa";
       if (username == null) {
           throw new CheckedException("当前登录人为空");
       }
       if (username.equals("aaa")) {
           //act_re_execution 任务id
           Task task = taskService.createTaskQuery()
                   .processDefinitionKey("groupactiviti")
                   .taskAssignee(username)
                   .singleResult();
           if (task != null) {
               HashMap<String, Object> map = new HashMap<>();
               map.put("agree", 1);
               taskService.***plete(task.getId(), map);
               System.out.println("完成任务");
           }
       }
       return Result.su***ess(true,"审核成功");
   }

}

定义远程调用remote供别的服务调用

结构:

  1. ActivitiRemoteFallback代码:



/**
* activiti服务降级处理
*
* @author 
*/
@***ponent
public class ActivitiRemoteFallback implements FallbackFactory<ActivitiRemoteService>
{
   private static final Logger log = LoggerFactory.getLogger(ActivitiRemoteFallback.class);

   @Override
   public ActivitiRemoteService create(Throwable cause) {
       log.error("工作流调用失败:{}", cause.getMessage());
       return new ActivitiRemoteService(){


           @Override
           public Result getTables() {
               return null;
           }

           @Override
           public Result bushu() {
               return Result.error("远程调用工作流部署失败");
           }

           @Override
           public Result list() {
               return Result.error("远程调用工作流审核失败");
           }

           @Override
           public Result ***plete() {
               return Result.error("远程调用工作流结束审核失败");
           }
       };
   }
}

  1. ActivitiRemoteService代码:



/**
* 用户服务
*
* @author bawei
*/
@FeignClient(contextId = "rctivitiRemoteService",
       value = ServiceNameConstants.****自己的文件名,
       fallbackFactory = ActivitiRemoteFallback.class,path = "/activiti")
public interface ActivitiRemoteService {
   //生成25张表
   @GetMapping
   public Result getTables();

   //流程部署
   @GetMapping("/bushu")
   public Result bushu();

   //查询个人待执行的任务
   @GetMapping("/list")
   public Result list();
   //结束
   @GetMapping("/***plete")
   public Result ***plete();
}

  1. org.springframework.boot.autoconfigure.AutoConfiguration.imports配置的代码

最后:在需要使用Activiti的地方直接注入该服务即可

转载请说明出处内容投诉
CSS教程_站长资源网 » 若依框架SpringBoot+Activiti工作流的使用

发表评论

欢迎 访客 发表评论

一个令你着迷的主题!

查看演示 官网购买