java-activiti笔记

版本:activiti7

 <dependency>
            <groupId>org.activiti</groupId>
            <artifactId>activiti-json-converter</artifactId>
            <version>7.0.0.Beta2</version>
            <exclusions>
                <exclusion>
                    <groupId>org.mybatis</groupId>
                    <artifactId>mybatis</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <!--activiti与springboot整合包-->
        <dependency>
            <groupId>org.activiti</groupId>
            <artifactId>activiti-spring-boot-starter</artifactId>
            <version>7.0.0.Beta2</version>
            <exclusions>
                <exclusion>
                    <groupId>org.mybatis</groupId>
                    <artifactId>mybatis</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

发布

流程图

会签

这里是将流程图通过bpmn.io插件设计好流程图,存放到服务器端

  public AjaxResult publishBpm(BpmFormVo bpmFormVo) {
        FileInputStream bpmnfileInputStream = null;
        try{
            BpmForm byId = getById(bpmFormVo.getId());
            xml=BpmFormManager.xmlnsActivitiEmpty(xml);
            xml=BpmFormManager.gatewaySupply(xml);
            activitiFlowService.delFlowByDefKey(bpmFormVo.getCode());
            repositoryService.createDeployment().addString(code+ ProcessConstants.SUFFIX, xml)
                    .name(code).key(code).deploy();
            bpmFormVo.setPublishTime(new Date());
            bpmFormVo.setState(1);
            bpmFormMapper.publishBpm(bpmFormVo);
            if("1".equals(byId.getCountersignature())){
                bpmCountersignService.bpmPublishHandle(byId,xml);
            }
        }catch (Exception e){
            e.printStackTrace();
            return AjaxResult.error("部署失败");
        }finally {
            try {
                if(bpmnfileInputStream!=null){
                    bpmnfileInputStream.close();
                }
            }catch (Exception e){
                e.printStackTrace();
            }

        }

        return AjaxResult.success("部署成功");
    }

重新发布需要做如下处理

    @SneakyThrows
    public void delFlowByDefKey(String code) {
        List<String> deploymentIdByName = activitiFlowMapper.getDeploymentIdByName(code+ ProcessConstants.SUFFIX);
        if(CollUtil.isEmpty(deploymentIdByName)){
            return;
        }
        for(String did:deploymentIdByName){
            repositoryService.deleteDeployment(did);
        }
    }

启动

    @Override
    public ProcessInstance startProcess(String definitionKey, String bussinessId,String userId,String userName, String projectId) {
        String bpmCode=definitionKey;
        Authentication.setAuthenticatedUserId(userId);
        Map<String, Object> map=new HashMap<>();
        map.put("state",ProcessConstants.AUDIT_YES);
        map.put("assignee",userId);
        ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(definitionKey, bussinessId, map);

        Task task = taskService.createTaskQuery()
                .processDefinitionKey(definitionKey)
                .taskAssignee(userId) //设置任务的负责人
                .orderByTaskCreateTime().desc().list().get(0);
        if (task!=null){
            taskService.addComment(task.getId(), task.getProcessInstanceId(), "流程提交","流程提交成功!");
            startTaskComplete(bpmCode,projectId,task.getId(),null);
        }


        startLogProcessHandle(bpmCode,definitionKey,bussinessId,projectId,userId,userName,processInstance,task);
        return processInstance;
    }

将会签中的占位的数据赋值

    @Override
    public void startTaskComplete(String bpmCode,String projectId,String taskId, Map<String, Object> variables) {

        BpmForm bpmForm = bpmFormService.queryInfoByCode(bpmCode, projectId);
        if(variables==null){
            variables=new HashMap<>();
        }
        if(bpmForm!=null&&"1".equals(bpmForm.getCountersignature())){
            //会签模式
            Object xmlByKey = activitiFlowMapper.getXmlByKey(bpmForm.getResCode() + ".bpmn");
            Map<String, List<String>> stringListMap = bpmUtil.collectionUseMap(bpmForm, (byte[]) xmlByKey);
            variables.putAll(stringListMap);
        }
        if(CollUtil.isEmpty(variables)){
            taskService.complete(taskId);
        }else{
            taskService.complete(taskId,variables);
        }
    }

    @SneakyThrows
    public Map<String,List<String>> collectionUseMap(BpmForm bpmForm,byte[] resByte){
        Map<String,List<String>> result=new HashMap<>();
        if("0".equals(bpmForm.getCountersignature())){
            return result;
        }
        String resStr = new String(resByte);
        BpmnModel bpmnModel = ModelUtil.getBpmnModel(resStr);
        Collection<UserTask> allUserTaskEvent = ModelUtil.getAllUserTaskEvent(bpmnModel);
        if(CollUtil.isEmpty(allUserTaskEvent)){
            return result;
        }

        SysRoleVo sysRoleVo=new SysRoleVo();
        sysRoleVo.setProjectId(bpmForm.getProjectId());
        List<SysRoleVo> sysRoleVos = sysRoleService.queryList(sysRoleVo);

        SysDept sysDept=new SysDept();
        sysDept.setProjectId(bpmForm.getProjectId());
        List<SysDept> sysDepts = sysDeptService.queryList(sysDept);

        for(UserTask userTask:allUserTaskEvent){
            if(userTask.hasMultiInstanceLoopCharacteristics()){
                MultiInstanceLoopCharacteristics loopCharacteristics = userTask.getLoopCharacteristics();
                String inputDataItem = loopCharacteristics.getInputDataItem();
                String coll = inputDataItem.replace("${", "").replace("}", "");
                String[] groups = coll.split("_");
                if("ROLE".equals(groups[0])){
                    List<String> idListByRoleId = getIdListByRoleId(groups[1], sysRoleVos).getUserIdList();
                    if(CollUtil.isNotEmpty(idListByRoleId)){
                        result.put(coll,idListByRoleId);
                    }
                }else if("DEPT".equals(groups[0])){
                    List<String> idListByDeptId = getIdListByDeptId(groups[1], sysDepts).getUserIdList();
                    if(CollUtil.isNotEmpty(idListByDeptId)){
                        result.put(coll,idListByDeptId);
                    }
                }
            }
        }
        return result;
    }

流程审批

    @SneakyThrows
    public CompletResultVo orSignCompletHandle(String taskId, String result, String remark, String definitionKey, Map<String, Object> variables, String userName){
        Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
        taskService.addComment(taskId, task.getProcessInstanceId(), result,remark);
        if(variables==null){
            variables=new HashMap<>();
        }
        variables.put("state",result);
        taskService.complete(taskId,variables);
        CompletResultVo completResultVo=new CompletResultVo();
        boolean afterHandle = afterHandle(task, userName, remark, result);
        completResultVo.setAuditEndState(afterHandle);
        return completResultVo;
    }

    boolean afterHandle(Task task,String userName,String remark,String result){
        //存储审核日志信息
        QueryWrapper queryWrapper=new QueryWrapper<>();
        queryWrapper.eq("process_instance_id",task.getProcessInstanceId());
        BussTask bussTask = bussTaskMapper.selectOne(queryWrapper);
        //日志记录
completByTaskLogHandle(bussTask,task,task.getProcessInstanceId(),userName,remark, result);
        //更新结束记录
        return endHandle(task.getProcessInstanceId(),bussTask,userName);
    }

判断流程结束后相关操作

    boolean endHandle(String piid,BussTask bussTask,String userName){
        List<Task> task1 = taskService.createTaskQuery().processInstanceId(piid).list();
        bussTaskMapper.updateById(bussTask);
        if(CollUtil.isEmpty(task1)){
            bussTaskMapper.updateStatus(piid,ProcessConstants.AUDIT_NO);
            endLogHandle(bussTask);
            return true;
        }
        return false;
    }

会签审批

    @SneakyThrows
    public CompletResultVo countersignCompletHandle(String taskId, String result, String remark,String definitionKey,String projectId,
                                         String userName,Long userId,BpmForm bpmForm){
        Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
        String taskDefinitionKey = task.getTaskDefinitionKey();
        UserTask userTask = getUserTaskByNodeId(bpmForm.getResCode(), taskDefinitionKey);
        if(userTask==null){
            return orSignCompletHandle(taskId,result,remark,definitionKey,projectId,null,userName);
        }
        if(!userTask.hasMultiInstanceLoopCharacteristics()){
            return orSignCompletHandle(taskId,result,remark,definitionKey,projectId,null,userName);
        }

        MultiInstanceLoopCharacteristics loopCharacteristics = userTask.getLoopCharacteristics();
        String completionCondition = loopCharacteristics.getCompletionCondition();
        String codeByInfo = BpmCountersignTypeEnum.getCodeByInfo(completionCondition);

        Map<String,Object> variables=new HashMap<>();

        QueryWrapper queryWrapper=new QueryWrapper<>();
        queryWrapper.eq("process_instance_id",task.getProcessInstanceId());
        BussTask bussTask = bussTaskMapper.selectOne(queryWrapper);
        List<LogProcess> bussList = getLogs(bussTask.getBussId(), task.getProcessInstanceId());

        List<BpmCountersignRecord> bpmCountersignRecords=new ArrayList<>();
        if(CollUtil.isNotEmpty(bussList)){
            BpmCountersignRecord bpmCountersignRecord=new BpmCountersignRecord();
            bpmCountersignRecord.setExecutionId(bussList.get(0).getExecutionId());
            bpmCountersignRecords= bpmCountersignService.queryListByExeId(bpmCountersignRecord);
        }


        BpmCountersign bpmCountersignByTaskInfo = bpmCountersignService.getBpmCountersignByTaskInfo(task.getTaskDefinitionKey(), bussTask.getDefinitionKey());
        String[] user_split = bpmCountersignByTaskInfo.getUids().split(",");

        if("all".equals(codeByInfo)){
            if(ProcessConstants.AUDIT_NO.equals(result)){
                variables.put("pass",true);
                variables.put("state",ProcessConstants.AUDIT_NO);
                taskService.complete(taskId,variables);
                countersignRecordHandle(task,bpmForm,userName,userId,bpmCountersignByTaskInfo,result,remark,bussTask,false,true,bussList);
            }else{
                if(user_split.length<=(bpmCountersignRecords.size()+1)){
                    variables.put("pass",true);
                    variables.put("state",ProcessConstants.AUDIT_YES);
                    taskService.complete(taskId,variables);
                    countersignRecordHandle(task,bpmForm,userName,userId,bpmCountersignByTaskInfo,result,remark,bussTask,true,true,bussList);
                }else{
                    variables.put("pass",false);
                    taskService.complete(taskId,variables);
                    countersignRecordHandle(task,bpmForm,userName,userId,bpmCountersignByTaskInfo,result,remark,bussTask,false,false,bussList);
                }
            }
        }else if("half".equals(codeByInfo)){
            if(user_split.length<=(bpmCountersignRecords.size()+1)){
                int ok_users=0;
                for(BpmCountersignRecord bpm:bpmCountersignRecords){
                    if(ProcessConstants.AUDIT_YES.equals(bpm.getAuditResult())){
                        ok_users+=1;
                    }
                }
                if(ProcessConstants.AUDIT_YES.equals(result)){
                    ok_users+=1;
                }
                String state=null;
                BigDecimal divide = new BigDecimal(ok_users).divide(new BigDecimal(user_split.length), 2, BigDecimal.ROUND_HALF_UP)
                double doubleValue = divide.doubleValue();
                if(doubleValue>=0.5){
                    state=ProcessConstants.AUDIT_YES;
                }else{
                    state=ProcessConstants.AUDIT_NO;
                }
                variables.put("state",state);
                variables.put("pass",true);
                taskService.complete(taskId,variables);
                countersignRecordHandle(task,bpmForm,userName,userId,bpmCountersignByTaskInfo,result,remark,bussTask,state.equals(ProcessConstants.AUDIT_YES)?true:false,true,bussList);
            }else{
                variables.put("pass",false);
                taskService.complete(taskId,variables);
                countersignRecordHandle(task,bpmForm,userName,userId,bpmCountersignByTaskInfo,result,remark,bussTask,false,false,bussList);
            }
        }else if("single".equals(codeByInfo)){
            if(ProcessConstants.AUDIT_YES.equals(result)) {
                variables.put("pass",true);
                variables.put("state",ProcessConstants.AUDIT_YES);
                taskService.complete(taskId,variables);
                countersignRecordHandle(task,bpmForm,userName,userId,bpmCountersignByTaskInfo,result,remark,bussTask,true,true,bussList);
            }else{
                if(user_split.length<=(bpmCountersignRecords.size()+1)){
                    variables.put("pass",true);
                    variables.put("state",ProcessConstants.AUDIT_NO);
                    taskService.complete(taskId,variables);
                    countersignRecordHandle(task,bpmForm,userName,userId,bpmCountersignByTaskInfo,result,remark,bussTask,false,true,bussList);
                }else{
                    variables.put("pass",false);
                    taskService.complete(taskId,variables);
                    countersignRecordHandle(task,bpmForm,userName,userId,bpmCountersignByTaskInfo,result,remark,bussTask,false,false,bussList);
                }
            }
        }
        CompletResultVo completResultVo=new CompletResultVo();
        List<LogProcess> bussList2 = getLogs(bussTask.getBussId(), task.getProcessInstanceId());
        String aname="";
        if(CollUtil.isNotEmpty(bussList2)){
            aname=bussList2.get(0).getAssigneeName();
        }else{
            aname= bussList.get(0).getAssigneeName();
        }
        boolean endHandle = endHandle(task.getProcessInstanceId(), bussTask, aname);
        completResultVo.setAuditEndState(endHandle);
        return completResultVo;
    }

//日志及操作记录
 /**
     *
     * @param task
     * @param bpmForm
     * @param userName
     * @param userId
     * @param bpmCountersignByTaskInfo
     * @param result 当前人的审核状态
     * @param remark
     * @param auditState 最终审核状态(会签)
     * @param isEnd 当前节点是否全部完成
     */
    void countersignRecordHandle(Task task,BpmForm bpmForm,String userName,Long userId,BpmCountersign bpmCountersignByTaskInfo,
                           String result,String remark,BussTask bussTask,boolean auditState,boolean isEnd,List<LogProcess> bussList){
        LogProcess logRecord=null;
        if(CollUtil.isEmpty(bussList)){
            logRecord=new LogProcess();
            logRecord.setProjectId(bpmForm.getProjectId());
            String myExeId=UUID.randomUUID().toString();
            logRecord.setExecutionId(myExeId);
            logRecord.setBusinessId(bussTask.getBussId());
            logRecord.setTaskId(task.getId());
            logRecord.setAssigneeName(bpmCountersignByTaskInfo.getUnames());
            logRecord.setAssignee(bpmCountersignByTaskInfo.getUids());
            logRecord.setInstanceId(task.getProcessInstanceId());
            logRecord.setDefinitionKey(bpmForm.getResCode());
            if(isEnd){
                logRecord.setStepType(auditState?ActivitiStepType.approved.getCode():ActivitiStepType.reject.getCode());
            }else{
                logRecord.setStepType(ActivitiStepType.unapproved.getCode());
            }

            logProcessMapper.insert(logRecord);
        }else{
            if(isEnd){
                logRecord = bussList.get(0);
                logRecord.setStepType(auditState?ActivitiStepType.approved.getCode():ActivitiStepType.reject.getCode());
                logProcessMapper.updateById(logRecord);
            }
        }

        BpmCountersignRecord bcr=new BpmCountersignRecord();
        bcr.setNodeId(task.getTaskDefinitionKey());
        bcr.setBpmCode(bpmForm.getCode());
        bcr.setUserId(userId+"");
        bcr.setUserName(userName);
        if(logRecord!=null){
            bcr.setLogId(logRecord.getId());
        }else{
            bcr.setLogId(bussList.get(0).getId());
        }
        bcr.setBusinessId(bussTask.getBussId());
        bcr.setAuditRemark(remark);
        bcr.setAuditResult(result);
        bcr.setExecutionId(logRecord.getExecutionId());
        bcr.setProcessInstanceId(task.getProcessInstanceId());
        bpmCountersignRecordMapper.insert(bcr);
    }

会签流程表达式枚举,全部通过即通过,半数通过即通过,一人通过即通过:

public enum BpmCountersignTypeEnum {
    all("all", "${nrOfCompletedInstances==nrOfInstances||pass==true}"),
    half("half", "${nrOfCompletedInstances/nrOfInstances&gt;=0.5&&pass==true}"),
    single("single", "${nrOfCompletedInstances>=1&&pass==true}");

    private final String code;
    private final String info;

    BpmCountersignTypeEnum(String code, String info)
    {
        this.code = code;
        this.info = info;
    }

    public static String getCodeByInfo(String info){
        if(StringUtils.isBlank(info)){
            return null;
        }
        for(BpmCountersignTypeEnum bct:BpmCountersignTypeEnum.values()){
            String elEscape = EscapeUtil.elEscape(bct.info);
            if(info.equals(elEscape)){
                return bct.code;
            }
        }
        return null;
    }

    public String getCode()
    {
        return code;
    }

    public String getInfo()
    {
        return info;
    }
}

这里:

nrOfInstances:总实例数

nrOfCompletedInstances:已完成实例数

nrOfActiviteInstances:未完成的实例数

全部通过即通过和一人通过即通过直接处理即可,state是流线走向,按比例通过时,我这里用一张表记录了每次操作,即BpmCountersignRecord,将此次记录作为流程操作记录的子关联表,executionId作为关联键。

其他

每次流程启动表act_ge_bytearray中会出现如下图的数据,这就是会签流程里面的变量数据

当流程审批结束后,var-开头的数据就会消失,hist开头的是act_hi表中相关数据

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

暮雪...

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值