美文网首页
activiti 工作流 的 一些学习整理

activiti 工作流 的 一些学习整理

作者: 那个唐僧 | 来源:发表于2022-01-28 14:43 被阅读0次

    acitivi 的表的文档说明链接:https://www.devdoc.cn/activiti-table-act_ru_identitylink.html

    1. activiti的表说明

      1. 使用25张表
        1. ACT_RE 流程定义和流程资源
        2. ACT_RU 运行时,流程实例、任务、变量
        3. ACT_HI 历史表
        4. ACT_GE 通用表
    2. Activiti的架构、类关系图

      1. 获取流程引擎的工具类
      2. ProcessEngines.使用默认方式获取配置文件,构造流程引擎。配置文件名字activiti.cfg.xml 放在class path下
      3. ProcessEngineConfiguration.可以自定义配置文件名
      4. 使用上面两个工具类都可以获得流程引擎
      5. ProcessEngine:流程引擎,获取各种服务的接口
      6. 服务接口:用于流程的部署、执行、管理,使用这些接口就是在操作对应的数据表
        1. RepositoryService 资源管理类
        2. RuntimeService 运行时管理类
        3. TaskService 任务管理类
        4. HistoryService 历史数据管理类
        5. ManagementService 流程引擎
    3. BPMN插件

      1. idea安装actiBPM
    4. 流程符号、画流程图

      1. 流程符号:事件Event、活动Activity,网关 geteway,流向
      2. 使用流程设计器画出流程图
      3. bpmn文件本质上是xml文件,因为安装actibpm插件
      4. 创建bpmn文件,在流程设计器使用流程符号来表达流程,指定流程的key,指定任务负责人
      5. 生成png文件,把bpmn文件后缀改为xml,在这个文件上右键选择diagrams-》show BPMN2.0 Designer,打开窗口,点击导出文件
    5. 部署流程

      1. 使用activiti提供的API把流程图的内容写入数据库中

      2. 属于资源类操作,使用repositoryService

      3. 单文件部署:把BPMN文件和png文件一个一个来处理

      4. 压缩包部署:把BPMN文件和png打压缩包来处理

      5. //1、创建processEngine
              ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
              //2、获取repositoryService
              RepositoryService service = processEngine.getRepositoryService();
              //3、使用service进行流程的部署,定义一个流程的名字,把bpmn和png部署到数据中
              Deployment deploy = service.createDeployment()
                      .name("出差申请流程")
                      .addClasspathResource("bpmn/evection.bpmn")
                      .addClasspathResource("bpmn/evection.png")
                      .deploy();
              //4、输出部署信息
              System.out.println("流程部署id=" + deploy.getId());
              System.out.println("流程部署名称=" + deploy.getName());
        
      6. 部署操作表:

        1. act_re_deployment 部署表
        2. act_re_procdef 流程定义表
        3. act_ge_bytearray 资源表
    6. 启动流程实例

      1. 使用runtimeService 根据流程定义的key

      2.     //1、创建processEngine
            ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
            //2、获取runtimeService
            RuntimeService service = processEngine.getRuntimeService();
            //3、根据流程定义的ID启动流程
            ProcessInstance instance = service.startProcessInstanceByKey("myEvection");
            //4、输出内容
            System.out.println("流程定义ID:" + instance.getProcessDefinitionId());
            System.out.println("流程实例ID:" + instance.getId());
            System.out.println("当前活动的ID:" + instance.getActivityId());
        
      3. 操作表:

        1. act_hi_actinst 流程实例执行历史信息
        2. act_hi_identitylink 流程参与用户的历史信息
        3. act_hi_procinst 流程实例的历史信息
        4. act_hi_taskinst 流程任务的历史信息
        5. act_ru_execution 流程执行信息
        6. act_ru_identitylink 流程正在参与用户信息
        7. act_ru_task 流程当前任务信息
    7. 任务查询

      1. 使用Task Service,根据流程定义的key,任务的负责人来进行查询

      2.     //1、获取流程引擎
            ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
            //2、获取taskService
            TaskService taskService = processEngine.getTaskService();
            //3、根据流程key和任务的负责人查询任务
            List<Task> taskList = taskService.createTaskQuery()
                    .processDefinitionKey("myEvection")
                    .taskAssignee("zhangsan")
                    .list();
            for (Task task : taskList) {
                System.out.println("流程实例ID:" + task.getProcessDefinitionId());
                System.out.println("任务ID:" + task.getId());
                System.out.println("任务负责人:" + task.getAssignee());
                System.out.println("任务名称:" + task.getName());
            }
        
    8. 任务完成

      1. 使用TaskService用任务的ID来完成任务

      2.     TaskService taskService = ProcessEngines.getDefaultProcessEngine().getTaskService();
            taskService.complete("30005");
        

    • 删除流程

      •     /**
             * 删除流程部署信息
             * act_ge_bytearray
             * act_re_deployment
             * act_re_procdef
             * 删除流程不会删除流程历史信息
             * 删除注意事项:如果当前的流程并没有完成,想要删除流程的话,需要进行级联删除
             */
            @Test
            public void deleteDeployment() {
                RepositoryService service = ProcessEngines.getDefaultProcessEngine().getRepositoryService();
                String deploymentID = "27501";
                service.deleteDeployment(deploymentID);
                //删除注意事项:如果当前的流程并没有完成,想要删除流程的话,需要进行级联删除,true代表级联删除
                service.deleteDeployment(deploymentID,true);
            }
        
    • 添加业务key到Activiti表

      •     /**
             * 添加业务key到activiti表
             */
            @Test
            public void addBusinessKey() {
                RuntimeService service = ProcessEngines.getDefaultProcessEngine().getRuntimeService();
                ProcessInstance instance = service.startProcessInstanceByKey("myEvection", "1001");
                System.out.println(instance.getBusinessKey());
            }
        
    • 全部流程实例的挂起和激活

      •     /**
             * 全部流程实例的挂起和激活
             */
            @Test
            public void suspendAllPrecessInstance() {
                RepositoryService service = ProcessEngines.getDefaultProcessEngine().getRepositoryService();
                //查询流程定义,获取流程定义的查询对象
                ProcessDefinition evection = service.createProcessDefinitionQuery()
                        .processDefinitionKey("myEvection")
                        .singleResult();
                //获取当前流程定义的实例是否都是挂起状态
                boolean suspended = evection.isSuspended();
                //获取流程定义的ID
                String id = evection.getId();
                //如果是挂起状态,改为激活状态
                if (suspended) {
                    //如果是挂起,执行激活
                    //args1  流程定义id         args2 是否激活          args3 激活时间
                    service.activateProcessDefinitionById(id, true, null);
                    System.out.println("流程定义id:" + id + ",已激活");
                } else {
                    //如果是激活状态,改为挂起状态
                    //args1  流程定义id         args2 是否挂起          args3 挂起时间
                    service.suspendProcessDefinitionById(id, true, null);
                    System.out.println("流程定义id:" + id + ",已挂起");
                }
        
            }
        
    • 挂起激活单个流程实例

      •     /**
             * 挂起激活单个流程实例
             */
            @Test
            public void suspendSingleProcessInstance() {
                RuntimeService runtimeService = ProcessEngines.getDefaultProcessEngine().getRuntimeService();
                ProcessInstance instance = runtimeService.createProcessInstanceQuery()
                        .processInstanceId("")
                        .singleResult();
                boolean suspended = instance.isSuspended();  // true 已暂停   false 激活
                String instanceId = instance.getId();
                if (suspended) {
                    runtimeService.activateProcessInstanceById(instanceId);
                    System.out.println("流程实例ID:" + instanceId + ",已激活");
                } else {
                    runtimeService.suspendProcessInstanceById(instanceId);
                    System.out.println("流程实例ID:" + instanceId + ",已挂起");
                }
            }
        

    处理工作流回退MySQL存储过程

    CREATE DEFINER=`admin`@`` PROCEDURE `activiti_back`(IN proc_inst_id VARCHAR(64))
    BEGIN
    DECLARE v_id_ VARCHAR(64);
        DECLARE v_proc_def_id_ VARCHAR(64);
        DECLARE v_task_def_key_ VARCHAR(255);
        DECLARE v_name_ VARCHAR(255);
        DECLARE v_assignee_ VARCHAR(255);
        DECLARE cur_act_hi_taskinst CURSOR FOR SELECT ID_,PROC_DEF_ID_,TASK_DEF_KEY_,NAME_,ASSIGNEE_ 
        FROM act_hi_taskinst
        where PROC_INST_ID_ = proc_inst_id and TASK_DEF_KEY_ is not null
        order by START_TIME_ desc  ;
    
    OPEN cur_act_hi_taskinst;
            set @i = 0;
            label: LOOP
            SET @i = @i + 1;
            FETCH cur_act_hi_taskinst INTO v_id_, v_proc_def_id_, v_task_def_key_, v_name_, v_assignee_;
            IF @i = 1 THEN
            -- 1、处理历史任务 将当前任务设置为完成状态
            UPDATE ACT_HI_TASKINST SET END_TIME_ = now(),duration_ = 1 ,DELETE_REASON_ = 'completed' where id_ = v_id_;
            ELSEIF @i = 2 THEN
            -- 2、处理历史任务 添加当前新任务
            INSERT INTO ACT_HI_TASKINST (id_    ,proc_def_id_   ,task_def_key_,proc_inst_id_,execution_id_
            ,name_,assignee_,start_time_,priority_) 
            values  (uuid(),v_proc_def_id_,v_task_def_key_,proc_inst_id,proc_inst_id
            ,v_name_,v_assignee_,now(),50);
            LEAVE label;
            ELSE
            LEAVE label;
            END IF;
            END LOOP label;
    CLOSE cur_act_hi_taskinst;
    -- 3、修改当前执行信息
    UPDATE act_ru_execution SET rev_ = rev_ + 1 , ACT_ID_ = v_task_def_key_   where  PROC_INST_ID_ = proc_inst_id;
    -- 4、修改当前任务信息   
    UPDATE act_ru_task SET name_ = v_name_,TASK_DEF_KEY_ = v_task_def_key_,ASSIGNEE_ = v_assignee_ where PROC_INST_ID_ = proc_inst_id;
    END
    



    一、创建Spring boot项目
    1. pom文件依赖
            <!--新增activiti7依赖-->
            <dependency>
                <groupId>org.activiti</groupId>
                <artifactId>activiti-spring-boot-starter</artifactId>
                <version>7.1.0.M4</version>
            </dependency>
            <dependency>
                <groupId>org.activiti.dependencies</groupId>
                <artifactId>activiti-dependencies</artifactId>
                <version>7.1.0.M4</version>
                <type>pom</type>
            </dependency>
            <!--新增activiti7依赖-->
                
            <!--其它依赖-->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-jdbc</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-security</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
            <dependency>
                <groupId>org.mybatis.spring.boot</groupId>
                <artifactId>mybatis-spring-boot-starter</artifactId>
                <version>2.2.1</version>
            </dependency>
    
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-devtools</artifactId>
                <scope>runtime</scope>
                <optional>true</optional>
            </dependency>
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <scope>runtime</scope>
            </dependency>
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <optional>true</optional>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-test</artifactId>
                <scope>test</scope>
            </dependency>
            <dependency>
                <groupId>org.springframework.security</groupId>
                <artifactId>spring-security-test</artifactId>
                <scope>test</scope>
            </dependency>
    
    1. File | Settings | Editor | File Encodings 编码改为 UTF-8

    2. application.yml依赖

      server:
        port: 8089
        servlet:
          context-path: /
      
      spring:
        datasource:
          url: jdbc:mysql://xxx.xxx.xxx.xxx:3306/activiti?characterEncoding=UTF8&autoReconnect=true&serverTimezone=Asia/Shanghai&allowMultiQueries=true
          username: xxxx
          password: xxxxxx
          driver-class-name: com.mysql.cj.jdbc.Driver
        activiti:
          #activiti创建历史记录表
          db-history-used: true
          #历史记录为所有记录
          history-level: full
          #不自动部署流程
          check-process-definitions: false
      
    3. resources目录下创建bpmn文件夹,将流程文件放入(bpmn文件和png文件)

    4. activiti剔除security

      1. 新建SpringSecurityConfig

        import org.springframework.context.annotation.Configuration;
        import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
        
        @Configuration
        public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {}
        
      2. 新建SelfUserDetailsServiceImpl

        import lombok.extern.slf4j.Slf4j;
        import org.springframework.security.core.userdetails.UserDetails;
        import org.springframework.security.core.userdetails.UserDetailsService;
        import org.springframework.security.core.userdetails.UsernameNotFoundException;
        import org.springframework.stereotype.Component;
        
        @Slf4j
        @Component
        public class SelfUserDetailsServiceImpl implements UserDetailsService {
        
            private final UserService userService;
        
            public SelfUserDetailsServiceImpl(UserService userService) {
                this.userService = userService;
            }
        
            @Override
            public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
                return userService.findOneUserByName(username);
            }
        }
        
      3. 新建UserService

        import org.slf4j.Logger;
        import org.slf4j.LoggerFactory;
        import org.springframework.security.core.GrantedAuthority;
        import org.springframework.security.core.authority.AuthorityUtils;
        import org.springframework.security.core.userdetails.User;
        import org.springframework.stereotype.Service;
        
        import java.util.List;
        
        @Service
        public class UserService {
            private final Logger logger = LoggerFactory.getLogger(UserService.class);
            public User findOneUserByName(String username) {
                logger.info("username:");
                logger.info(username);
                List<GrantedAuthority> authorities= AuthorityUtils.commaSeparatedStringToAuthorityList("admin");
                // 密码置空
                return new User(username,"",authorities);
            }
        
        
      4. 需要在启动类上面加

        @SpringBootApplication(exclude = {org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration.class})
        
    5. activiti 7 的M4版本中有字段缺失bug需要手动更新

      -- ----------------------------
      -- 修复Activiti7的M4版本缺失字段Bug
      -- ----------------------------
      alter table ACT_RE_DEPLOYMENT add column PROJECT_RELEASE_VERSION_ varchar(255) DEFAULT NULL;
      alter table ACT_RE_DEPLOYMENT add column VERSION_ varchar(255) DEFAULT NULL;
      
    6. 至此activiti7配置完毕

    二、部署流程、流程相关
    1. 流程部署

      @SpringBootTest
      class ActivityDemoApplicationTests {
      
          @Autowired
          private RepositoryService repositoryService;
      
          @Autowired
          private RuntimeService runtimeService;
      
          @Autowired
          private TaskService taskService;
      
          /**
           * 装柜通知单流程部署
           * act_re_deployment  流程部署信息表
           *      ID_           流程部署ID
           *      NAME_         流程部署名称
           *      DEPLOY_TIME_  流程部署时间
           */
          @Test
          public void initPackDeployment() {
              Deployment deploy = repositoryService
                      .createDeployment()
                      .name("装柜通知流程")
                      .addClasspathResource("bpmn/Container.bpmn")
                      .addClasspathResource("bpmn/Container.png")
                      .deploy();
              System.out.println("流程部署成功:id==》" + deploy.getId());
              System.out.println("流程部署成功:name==》" + deploy.getName());
          }
      
           /**
           * 开启一个装柜通知单流程实例
           * act_ru_task              运行时任务节点表
           *      PROC_INST_ID_       流程实例ID  开启一个新的流程的实例ID
           *      PROC_DEF_ID_        流程部署时的ID
           *      NAME_               节点定义名称
           *      ASSIGNEE_           任务执行人
           */
          @Test
          public void startProcessInstance() {
              ProcessInstance instance = runtimeService.startProcessInstanceByKey("Container", "1");
              System.out.println("流程实例ID:" + instance.getProcessInstanceId());
              //9ab732ff-8002-11ec-8ac6-8cc6819ca54f
          }
      
      
          /**
           * 单证查询个人代办的任务
           */
          @Test
          public void getTaskByAssignee() {
              List<Task> list = taskService.createTaskQuery().taskCandidateUser("rxy").list();
              for (Task task : list) {
                  System.out.println("单证任务ID:" + task.getId());
                  //任务TaskID  9abab573-8002-11ec-8ac6-8cc6819ca54f
                  System.out.println("单证任务名称:" + task.getName());
              }
          }
      
      
          /**
           * 单证执行任务  (转发货代,此处需依据货代标识对应转发相应货代)
           */
          @Test
          public void completeTask() {
              taskService.complete("9abab573-8002-11ec-8ac6-8cc6819ca54f");
              System.out.println("执行任务成功");
          }
      
          /**
           * 货代查询个人代办的任务
           */
          @Test
          public void getTaskByAssigneeForHd() {
              List<Task> list = taskService.createTaskQuery().taskCandidateUser("dn").list();
              for (Task task : list) {
                  System.out.println("货代任务ID:" + task.getId());
                  System.out.println("货代任务名称:" + task.getName());
              }
          }
      
      
          /**
           * 货代拾取任务
           */
          @Test
          public void claimTaskByHd() {
              taskService.claim("af675955-7fd5-11ec-a892-8cc6819ca54f", "dn");
              System.out.println("货代拾取任务成功");//货代拾取任务成功
          }
      
          /**
           * 货代执行任务(修改)
           */
          @Test
          public void hdCompleteTask() {
              //todo 此处根据装柜通知单ID修改表单
      
              //货代执行任务(修改)
              taskService.complete("af675955-7fd5-11ec-a892-8cc6819ca54f");
              System.out.println("货代填写完信息,交给单证");
          }
      
      
          /**
           * 单证再次查询个人代办的任务
           */
          @Test
          public void getTaskByAssigneeByDz() {
              List<Task> list = taskService.createTaskQuery().taskCandidateUser("rxy").list();
              for (Task task : list) {
                  System.out.println("单证任务ID:" + task.getId());//2dbfbfcd-7fd7-11ec-abf5-8cc6819ca54f
                  System.out.println("单证任务名称:" + task.getName());//单证审核货代
              }
          }
      
      
          /**
           * 单证再次拾取任务
           */
          @Test
          public void claimTaskAgain() {
              taskService.claim("2dbfbfcd-7fd7-11ec-abf5-8cc6819ca54f", "rxy");
              System.out.println("再次拾取任务成功");
          }
      
          /**
           * 单证执行任务  (转发自提)
           */
          @Test
          public void completeTaskForZiTi() {
              taskService.complete("2dbfbfcd-7fd7-11ec-abf5-8cc6819ca54f");
              System.out.println("执行任务成功");
          }
          /**
           * 自提查询个人代办的任务
           */
          @Test
          public void getTaskByAssigneeByZT() {
              List<Task> list = taskService.createTaskQuery().taskCandidateUser("hmf").list();
              for (Task task : list) {
                  System.out.println("自提任务ID:" + task.getId());//9b05d6f0-7fd7-11ec-b78d-8cc6819ca54f
                  System.out.println("自提任务名称:" + task.getName());//单证审核货代
              }
          }
      
      
          /**
           * 自提拾取任务
           */
          @Test
          public void claimTaskAgainByZT() {
              taskService.claim("9b05d6f0-7fd7-11ec-b78d-8cc6819ca54f", "hmf");
              System.out.println("再次拾取任务成功");
          }
      
          /**
           * 自提执行任务  (转发单证)
           */
          @Test
          public void completeTaskForZiTiByDanZheng() {
              taskService.complete("9b05d6f0-7fd7-11ec-b78d-8cc6819ca54f");
              System.out.println("执行任务成功");
          }
      
          /**
           * 单证再次查询个人代办的任务 (审核自提)
           */
          @Test
          public void getTaskByAssigneeByDzZT() {
              List<Task> list = taskService.createTaskQuery().taskCandidateUser("rxy").list();
              for (Task task : list) {
                  System.out.println("单证任务ID:" + task.getId());//11749858-7fd8-11ec-aa53-8cc6819ca54f
                  System.out.println("单证任务名称:" + task.getName());//单证审核货代
              }
          }
      
      
          /**
           * 单证再次拾取任务 (审核自提)
           */
          @Test
          public void claimTaskAgainzz() {
              taskService.claim("11749858-7fd8-11ec-aa53-8cc6819ca54f", "rxy");
              System.out.println("再次拾取任务成功");
          }
      
          /**
           * 单证执行任务  ((审核自提)并且最终转发货代)
           */
          @Test
          public void completeTaskForZiTizz() {
              taskService.complete("11749858-7fd8-11ec-aa53-8cc6819ca54f");
              System.out.println("执行任务成功");
          }
      
          /**
           * 货代查询个人代办的任务
           */
          @Test
          public void getTaskByAssigneeForHdhh() {
              List<Task> list = taskService.createTaskQuery().taskCandidateUser("dn").list();
              for (Task task : list) {
                  System.out.println("货代任务ID:" + task.getId());//67b7926d-7fd8-11ec-98b3-8cc6819ca54f
                  System.out.println("货代任务名称:" + task.getName());//货代确认
              }
          }
      
      
          /**
           * 货代拾取任务
           */
          @Test
          public void claimTaskByHdhh() {
              taskService.claim("67b7926d-7fd8-11ec-98b3-8cc6819ca54f", "dn");
              System.out.println("货代拾取任务成功");//货代拾取任务成功
          }
      
          /**
           * 货代执行任务(最终)
           */
          @Test
          public void hdCompleteTaskhh() {
              //货代执行任务(最终)
              taskService.complete("67b7926d-7fd8-11ec-98b3-8cc6819ca54f");
              System.out.println("货代填写完信息,各自走自己的装鞋柜流程");
          }
          
      }
      

    说明:

    流程回退,存储过程中传入的流程实例ID也就是 act_ru_task 表中的 PROC_INST_ID_ ,其余流程进行中的拾取任务、执行任务等取得都是 act_ru_task 表中的 ID_

    重要说明

    Bpmn文件 idea 2020 之后不能使用act BPMN插件 需要使用扩展程序camunda-modeler

    下载地址:https://github.com/camunda/camunda-modeler

    img

    之后

    img

    之后 创建的BPMN文件会出现bug assignee为null

    解决方案 :camunda-modeler画完图以后, 得到的xml中的标签是camunda:assignee, 需要换成activiti:assignee

    修改后标签会报错, 需要改命名空间

    <pre mdtype="fences" cid="n805" lang="xml" class="md-fences md-end-block ty-contain-cm modeLoaded" spellcheck="false" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-thickness: initial; text-decoration-style: initial; text-decoration-color: initial;"><bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI"
     xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:di="http://www.omg.org/spec/DD/20100524/DI"
     xmlns:camunda="http://camunda.org/schema/1.0/bpmn" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xmlns:activiti="http://activiti.org/bpmn" xmlns:modeler="http://camunda.org/schema/modeler/1.0" id="Definitions_03io3g1"
     targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Modeler" exporterVersion="4.9.0"
     modeler:executionPlatform="Camunda Platform" modeler:executionPlatformVersion="7.15.0"></pre>
    

    相关文章

      网友评论

          本文标题:activiti 工作流 的 一些学习整理

          本文链接:https://www.haomeiwen.com/subject/tyctkrtx.html