Activiti7初探

activiti 7.0.0.SR1+springboot 2.0.4.RELEASE

1、 idea中安装activiti的插件

在这里插入图片描述

2、引入依赖

<parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.4.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <properties>
        <activiti.version>7.0.0.SR1</activiti.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatisplus-spring-boot-starter</artifactId>
            <version>1.0.5</version>
        </dependency>

        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus</artifactId>
            <version>3.1.0</version>
        </dependency>

        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.16</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.35</version>
        </dependency>

        <dependency>
            <groupId>org.activiti</groupId>
            <artifactId>activiti-spring-boot-starter</artifactId>
            <version>${activiti.version}</version>
            <exclusions>
                <exclusion>
                    <groupId>org.activiti.core.common</groupId>
                    <artifactId>activiti-spring-identity</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
    </dependencies>

application.properties中增加配置

#表示启动时检查数据库表,不存在则创建
spring.activiti.database-schema-update=true
#表示哪种情况下使用历史表,这里配置为full表示全部记录历史,方便绘制流程图
spring.activiti.history-level=full
#true表示使用历史表,如果不配置,则工程启动后可以检查数据库,只建立了17张表
spring.activiti.db-history-used=true

3、画流程的bpmn图,其实就是设计中的活动图

在这里插入图片描述

4、25张表

在这里插入图片描述

5、核心service

RuntimeService
TaskService
HistoryService
RepositoryService

6、启动流程并自动完成第一步

public String startProcess(ProcessDealDto processDealDto) {

        ProcessInstance instance = runtimeService.startProcessInstanceByKey(WorkFlowConstant.PROCESS_WORKTICKET_ID);
        //验证是否启动成功
        //通过查询正在运行的流程实例来判断
        ProcessInstanceQuery processInstanceQuery = runtimeService.createProcessInstanceQuery();
        //根据流程实例ID来查询
        List<ProcessInstance> runningList = processInstanceQuery.processInstanceId(instance.getProcessInstanceId()).list();
        logger.debug(LogFormatter.toMsg("start process", "instance"), runningList);

        String instanceId = instance.getId();

        //设置处理人
        Task task = taskService.createTaskQuery().processInstanceId(instanceId).singleResult();
        if (task != null) {
            //自动完成第一步

            Map<String, Object> map = new HashMap<String, Object>(2);
            map.put("check", 1);
            map.put("personId", processDealDto.getPersonId());
            taskService.setAssignee(task.getId(), processDealDto.getCurrentPersonId());
            taskService.complete(task.getId(), map);

            task = taskService.createTaskQuery().processInstanceId(instanceId).singleResult();
            taskService.setAssignee(task.getId(), processDealDto.getPersonId());
        } else {
            throw new BusinessException(WorkTaskErrorCode.WORK_TASK_START_PROCESS_ERROR);
        }

        // 返回流程ID
        return instanceId;
    }

7、节点处理

public void auditProcess(ProcessDealDto processDealDto) {
        Task task = null;
        if (ObjectUtils.isNotEmpty(processDealDto.getInstanceId())) {
            task = taskService.createTaskQuery().processInstanceId(processDealDto.getInstanceId()).singleResult();
        } else if (ObjectUtils.isNotEmpty(processDealDto.getTaskId())) {
            task = taskService.createTaskQuery().taskId(processDealDto.getTaskId()).singleResult();
        }

        if (task == null) {
            throw new BusinessException(WorkTaskErrorCode.WORK_TASK_BACK_PROCESS_EMPTY_ERROR);
        }
        if (WorkFlowConstant.AUDIT_PASS.equals(processDealDto.getCheck())) {
            dealProcess(task, processDealDto);
        } else {
            backProcess(task, processDealDto);
        }
    }

/**
     * 退回到上一节点
     *
     * @param task
     * @param processDealDto
     */
    private void backProcess(Task task, ProcessDealDto processDealDto) {

        List<HistoricTaskInstance> htiList = historyService.createHistoricTaskInstanceQuery()
                .processInstanceId(processDealDto.getInstanceId())
                .orderByTaskCreateTime()
                .desc()
                .list();

        if (ObjectUtils.isEmpty(htiList) || htiList.size() < 2) {
            return;
        }

        HistoricTaskInstance myTask = htiList.get(1);
        String myTaskId = myTask.getId();

        if (null == myTaskId) {
            throw new BusinessException(WorkTaskErrorCode.WORK_TASK_BACK_PROCESS_USER_ERROR);
        }

        String processDefinitionId = myTask.getProcessDefinitionId();
        ProcessDefinitionEntity processDefinitionEntity = (ProcessDefinitionEntity) repositoryService.createProcessDefinitionQuery().processDefinitionId(processDefinitionId).singleResult();
        BpmnModel bpmnModel = repositoryService.getBpmnModel(processDefinitionId);

        //变量
//		Map<String, VariableInstance> variables = runtimeService.getVariableInstances(currentTask.getExecutionId());
        String myActivityId = null;
        List<HistoricActivityInstance> haiList = historyService.createHistoricActivityInstanceQuery()
                .executionId(myTask.getExecutionId()).finished().list();
        for (HistoricActivityInstance hai : haiList) {
            if (myTaskId.equals(hai.getTaskId())) {
                myActivityId = hai.getActivityId();
                break;
            }
        }
        FlowNode myFlowNode = (FlowNode) bpmnModel.getMainProcess().getFlowElement(myActivityId);


        Execution execution = runtimeService.createExecutionQuery().executionId(task.getExecutionId()).singleResult();
        String activityId = execution.getActivityId();
//        logger.warn("------->> activityId:" + activityId);
        FlowNode flowNode = (FlowNode) bpmnModel.getMainProcess().getFlowElement(activityId);

        //记录原活动方向
        List<SequenceFlow> oriSequenceFlows = new ArrayList<SequenceFlow>();
        oriSequenceFlows.addAll(flowNode.getOutgoingFlows());

        //清理活动方向
        flowNode.getOutgoingFlows().clear();
        //建立新方向
        List<SequenceFlow> newSequenceFlowList = new ArrayList<SequenceFlow>();
        SequenceFlow newSequenceFlow = new SequenceFlow();
        newSequenceFlow.setId("newSequenceFlowId");
        newSequenceFlow.setSourceFlowElement(flowNode);
        newSequenceFlow.setTargetFlowElement(myFlowNode);
        newSequenceFlowList.add(newSequenceFlow);
        flowNode.setOutgoingFlows(newSequenceFlowList);

        Map<String, Object> currentVariables = new HashMap<String, Object>();
        currentVariables.put("check", 0);
        currentVariables.put("dealMsg", processDealDto.getDealMsg());
        currentVariables.put("personId", processDealDto.getPersonId());
        taskService.createAttachment("", task.getId(), processDealDto.getInstanceId(), "dealMsg", processDealDto.getDealMsg(), "");
        //完成任务
        taskService.complete(task.getId(), currentVariables);
        //恢复原方向
        flowNode.setOutgoingFlows(oriSequenceFlows);

        Task nextTask = taskService.createTaskQuery().processInstanceId(processDealDto.getInstanceId()).singleResult();
        if(nextTask!=null) {
            taskService.setAssignee(nextTask.getId(), myTask.getAssignee());
        }
    }

    /**
     * 正向流程
     *
     * @param task
     * @param processDealDto
     */
    private void dealProcess(Task task, ProcessDealDto processDealDto) {

        Map<String, Object> map = new HashMap<String, Object>(2);
        map.put("check", processDealDto.getCheck());
        map.put("personId", processDealDto.getPersonId());
        map.put("dealMsg", processDealDto.getDealMsg());

        task.setDescription(WorkFlowStatus.getDescriptionByIndex(processDealDto.getNodeType()));

        String taskId = task.getId();
        taskService.createAttachment("", taskId, processDealDto.getInstanceId(), "dealMsg", processDealDto.getDealMsg(), "");
        taskService.complete(taskId, map);

        //设置处理人,将流程流转到下一个人
        Task nextTask = taskService.createTaskQuery().processInstanceId(processDealDto.getInstanceId()).singleResult();

        if(nextTask!=null) {
            taskService.setAssignee(nextTask.getId(), processDealDto.getPersonId());
        }
    }

8、历史查询

不显示起始节点和排他网关

public List<ProcessHistoryDto> getHistoryByInstance(String instanceId) {

        HistoricActivityInstanceQuery historyInstanceQuery = historyService.createHistoricActivityInstanceQuery().processInstanceId(instanceId);
        // 查询历史节点
        List<HistoricActivityInstance> historicActivityInstanceList = historyInstanceQuery.orderByHistoricActivityInstanceStartTime().asc().list();
        if (ObjectUtils.isNotEmpty(historicActivityInstanceList)) {
            List<ProcessHistoryDto> historyDtos = new ArrayList<>();

            Integer lastNodeId = null;

            ProcessHistoryDto lastHistoryNode = null;

            for (HistoricActivityInstance activityInstance : historicActivityInstanceList) {
                if(activityInstance.getActivityName().equals("StartEvent") || activityInstance.getActivityName().equals("ExclusiveGateway")){
                    continue;
                }

                ProcessHistoryDto historyDto = new ProcessHistoryDto();
                historyDto.setActivitId(activityInstance.getActivityId());
                historyDto.setDealPersonID(activityInstance.getAssignee());
                historyDto.setDealTime(activityInstance.getEndTime());

                Integer nowNodeId = WorkFlowNodeEnum.getIndexByName(activityInstance.getActivityId());
                historyDto.setNodeId(nowNodeId);
                historyDto.setCheck(true);
                //判断是否为驳回
                if(lastNodeId != null && nowNodeId < lastNodeId){
                    lastHistoryNode.setCheck(false);
                }else if(lastNodeId != null && WorkFlowNodeEnum.WORK_PERMITER_CHECK.getIndex().equals(lastNodeId)
                        && WorkFlowNodeEnum.FINISH.getIndex().equals(nowNodeId)){
                    //从许可人直接驳回
                    lastHistoryNode.setCheck(false);
                }

                if(!"EndEvent".equals(activityInstance.getActivityName())) {
                    List<Attachment> attachmentList = taskService.getTaskAttachments(activityInstance.getTaskId());
                    if (ObjectUtils.isNotEmpty(attachmentList)) {
                        historyDto.setAttachment(attachmentList.get(0).getDescription());
                    }

                    historyDto.setDealPersonName(getPersonNameAndNoById(activityInstance.getAssignee()));
                }

                lastNodeId = nowNodeId;
                lastHistoryNode = historyDto;

                //没有结束时间,表示当前正处于该节点,历史中不展示,但是要用这个节点来判断是否是驳回
                if(ObjectUtils.isEmpty(activityInstance.getEndTime())){
                    continue;
                }

                historyDtos.add(historyDto);
            }
            return historyDtos;
        }
        return null;
    }

9、代办

public List<PersonToDoDto> getToDoList(String personId) {

        List<Task> list = taskService.createTaskQuery().taskCandidateOrAssigned(personId).list();
        if(ObjectUtils.isNotEmpty(list)){
            List<PersonToDoDto> personToDoDtos = new ArrayList<>();
            for(Task task : list){
                PersonToDoDto personToDoDto = new PersonToDoDto();
                personToDoDto.setInstanceId(task.getProcessInstanceId());
                personToDoDto.setTaskId(task.getId());
                personToDoDtos.add(personToDoDto);
            }
            return personToDoDtos;
        }
        return null;
    }

10、重写用户权限

@Service
public class CustomUserGroupManagerImpl implements UserGroupManager{

    public static List<String> roles = new ArrayList<>();
    public static List<String> groups = new ArrayList<>();
    public static List<String> users = new ArrayList<>();
    public static Map<String,String> userRoleMap = new HashMap<>();
    static {
        roles.add("workCreate");
        roles.add("workPermit");
        roles.add("workLeader");

        groups.add("workGroupA");

        users.add("admin");
        users.add("laowang");
        users.add("xiaofang");

        userRoleMap.put("admin", "workCreate");
        userRoleMap.put("laowang", "workPermit");
        userRoleMap.put("xiaofang", "workLeader");
    }

    @Override
    public List<String> getUserGroups(String s) {

        return groups;
    }

    @Override
    public List<String> getUserRoles(String s) {
        String role = userRoleMap.get(s);
        List<String> list = new ArrayList<>();
        list.add(role);
        return list;
    }

    @Override
    public List<String> getGroups() {
        return groups;
    }

    @Override
    public List<String> getUsers() {
        return users;
    }
}

11、关闭activiti默认的安全校验

启动类上添加注解

@EnableAutoConfiguration(exclude = {org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration.class})
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests().anyRequest().permitAll().and().logout().permitAll();
    }
}

12、配置activiti的数据源和线程池

@Configuration
public class WorkFlowConfiguration{

@Autowired
private UserGroupManager userGroupManager;

    @Autowired
    private DataSource dataSource;

    private int corePoolSize = 10;
    private int maxPoolSize = 30;
    private int keepAliveSeconds = 300;
    private int queueCapacity = 300;

    @Bean
    public SpringProcessEngineConfiguration springProcessEngineConfiguration(
            PlatformTransactionManager transactionManager) throws IOException {

        SpringProcessEngineConfiguration configuration = new SpringProcessEngineConfiguration();
        configuration.setDataSource(dataSource);
        configuration.setTransactionManager(transactionManager);
        SpringAsyncExecutor asyncExecutor = new SpringAsyncExecutor();
        asyncExecutor.setTaskExecutor(workFlowAsync());
        configuration.setAsyncExecutor(asyncExecutor);

        configuration.setDatabaseSchemaUpdate("true");
        configuration.setUserGroupManager(userGroupManager);
        configuration.setHistoryLevel(HistoryLevel.FULL);
        configuration.setDbHistoryUsed(true);
        return configuration;
    }

    @Primary
    @Bean("workFlowTaskExecutor")
    public ThreadPoolTaskExecutor workFlowAsync() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(corePoolSize);
        executor.setMaxPoolSize(maxPoolSize);
        executor.setKeepAliveSeconds(keepAliveSeconds);
        executor.setQueueCapacity(queueCapacity);
        executor.setThreadNamePrefix("workFlowTaskExecutor-");
        executor.initialize();
        return executor;
    }


}

13、其他问题

有时候发现application.properties中的配置不起作用

@Configuration
public class InitConfigTest implements CommandLineRunner {

    @Autowired
    private ProcessEngine processEngine;

    @Override
    public void run(String... args) throws Exception {
        Deployment deployment = processEngine.getRepositoryService()
                .createDeployment()
                .name("workTask")
                .addClasspathResource("processes/workTask.bpmn")
//                .addClasspathResource("repository/TestProcess.png")
                .deploy();
    }
}
  • 15
    点赞
  • 90
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
### 回答1: Activiti是一个开源的工作流引擎,它提供了丰富的API来帮助开发人员设计和管理工作流程。Activiti 7是Activiti的最新版本,它提供了许多新的功能和改进,包括更好的性能和易用性。Activiti API可以用来管理工作流程定义、部署和执行,包括启动、查询和终止流程实例。此外,Activiti API还提供了对流程变量、任务和历史数据的管理功能。 ### 回答2: activiti7是一个开源的工作流引擎,它是activiti的升级版本。activiti7提供了一套强大的API,使得开发者可以方便地与工作流引擎进行交互。 activiti7的API可以用于各种工作流相关的操作,包括流程定义、流程实例、任务管理等。通过activiti7的API,开发者可以创建、部署和管理各种流程定义,定义流程的图形模型、表单等。同时,API还支持启动、暂停和终止流程实例,查询和处理任务,得到流程实例运行状态等。 使用activiti7的API还可以对流程进行管理,包括监听流程启动、流程完成等事件,触发相应的业务逻辑。此外,API还支持获取和设置流程变量,进行用户组和角色的管理,以及集成和扩展其他业务系统等。 activiti7的API遵循了RESTful架构,提供了一套统一的HTTP接口,使得开发者可以轻松地集成activiti7到自己的应用程序中。同时,activiti7还提供了一些Java类库和工具类,方便开发者进行各种操作。 总之,activiti7提供了一套简洁易用的API,使得开发者可以方便地使用工作流引擎,实现各种复杂的工作流业务。无论是开发者还是企业用户,都可以通过activiti7的API来提升工作效率和业务管理能力。 ### 回答3: Activiti7是一个开源的企业级工作流管理和自动化平台,它提供了一套强大的API,用于流程定义、任务管理、流程实例管理等操作。 首先,使用Activiti7的API可以定义流程,包括流程节点、流程变量和流程规则等。可以使用API中的类和方法创建和配置流程,将各个节点按照需要连接起来,并定义流程中的变量和规则。通过API的调用,可以实现灵活的流程定义,满足业务需求。 其次,Activiti7的API还提供了任务管理功能。通过API可以创建、分配和处理任务,可以将任务分配给特定的用户或组,并设置任务的截止日期和优先级等属性。API还提供了查询任务的方法,可以根据不同的条件查询任务列表,并对任务进行处理,如完成、取消或重新指派任务等。 另外,API还包括流程实例管理的功能。通过API可以启动流程实例,跟踪流程实例的状态,并对流程实例进行操作,如暂停、恢复或终止。API还提供了查询流程实例的方法,可以根据条件查询流程实例列表,并对流程实例进行管理和监控。 总结来说,Activiti7提供了一套功能丰富的API,可以方便地进行流程定义、任务管理和流程实例管理。通过使用这些API,可以实现灵活、高效的工作流管理和自动化,提升企业的业务流程效率。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值