Spring Boot集成Activity7实现简单的审批流

avatar
作者
筋斗云
阅读量:3

由于客户对于系统里的一些新增数据,例如照片墙、照片等,想实现上级逐级审批通过才可见的效果,于是引入了Acitivity7工作流技术来实现,本文是对实现过程的介绍讲解,由于我是中途交接前同事的这块需求,所以具体实现方式和代码编写我暂时先按前同事的思路简单介绍,不代表我个人看法。

参考文章:

springboot+Activiti7整合实践 (一)_vue2集成activit7-CSDN博客

org.springframework.security.core.userdetails.UsernameNotFoundException,三步解决Activiti7和Security冲突问题_cause: org.springframework.security.core.userdetai-CSDN博客

Activiti7笔记(二)Activiti7一共涉及到25张表,哪些操作会涉及哪些表,每张表的作用是什么_activiti7数据表详细解读-CSDN博客

Activiti7笔记(一)Activiti7是什么,入门流程操作的代码实现-腾讯云开发者社区-腾讯云 (tencent.com)

文章目录

一、引入依赖

        <!--activity7工作流-->         <dependency>             <groupId>org.activiti</groupId>             <artifactId>activiti-spring-boot-starter</artifactId>             <version>${activity.starter.version}</version>             <exclusions>                 <exclusion>                     <!-- 项目引入了mybatis-plus,则需要排除 -->                     <groupId>org.mybatis</groupId>                     <artifactId>mybatis</artifactId>                 </exclusion>             </exclusions>         </dependency>          <dependency>             <groupId>org.activiti.dependencies</groupId>             <artifactId>activiti-dependencies</artifactId>             <version>${activity.starter.version}</version>             <type>pom</type>         </dependency>          <!-- 生成流程图 -->         <dependency>             <groupId>org.activiti</groupId>             <artifactId>activiti-image-generator</artifactId>             <version>${activity.starter.version}</version>         </dependency> 

二、修改配置文件

  spring:       #activity工作流配置       activiti:         # 自动部署验证设置:true-开启(默认)、false-关闭         check-process-definitions: false         # 保存历史数据         history-level: full         # 检测历史表是否存在         db-history-used: true         # 关闭自动部署         deployment-mode: never-fail         # 对数据库中所有表进行更新操作,如果表不存在,则自动创建         # create_drop:启动时创建表,在关闭时删除表(必须手动关闭引擎,才能删除表)         # drop-create:启动时删除原来的旧表,然后在创建新表(不需要手动关闭引擎)         database-schema-update: true         # 解决频繁查询SQL问题         async-executor-activate: false 

db-history-userdhistory-level,建议按图中配置,方便查询工作流历史记录

三、解决Activity7和Security框架冲突

场景:由于Activity升级到7版本后,引入了Security来用于权限校验,但是本项目自身已经引入了Security框架,于是发生了冲突

【如果项目用的不是security框架,例如用的shiro,需要在启动项排除,参考:springboot+Activiti7整合实践 (一)_vue2集成activit7-CSDN博客

本项目
在这里插入图片描述
在这里插入图片描述

网上其他做法(用的activity原生的api):

从Activiti工作流中检索所有用户任务_在activiti 7中获取流程实例的所有任务_如何在Activiti工作流中的单独实例中强制顺序执行任务 - 腾讯云开发者社区 - 腾讯云 (tencent.com)
在这里插入图片描述

四、启动项目,生成activity的数据库表

引入依赖、配置好后,第一次启动会在数据库生成相关的表
在这里插入图片描述

具体介绍:Activiti7笔记(二)Activiti7一共涉及到25张表,哪些操作会涉及哪些表,每张表的作用是什么_activiti7数据表详细解读-CSDN博客

本项目主要用到的表:

  • 流程部署表 :[ACT_RE_PROCDEF]

    每对一个流程图部署后,会记录在该表里(部署过程下面会讲到)

    在这里插入图片描述

  • 历史流程实例表:[ACT_HI_PROCINST]

    流程一次从头到尾执行,对应一个流程实例,流程结束时会保留下来

  • 运行时流程执行对象表 :[ACT_RU_EXECUTION]

    流程实例与执行对象的关系:‌一个流程实例在执行过程中,‌如果流程包含分支或聚合,‌那么执行对象的数量可以多个【至少有2条数据,其中第1条是对应历史流程实例表】。‌这是因为流程实例在运行过程中可能会产生多个并行的执行路径,‌每个路径上的任务或活动都可以视为一个执行对象。‌例如,‌在一个具有多个分支的审批流程中,‌不同的审批人可能会同时处理不同的分支任务,‌这些分支任务就代表了多个执行对象

    Activiti工作流学习(二)流程实例、执行对象、任务 - 百度文库 (baidu.com)

    这个表里面主要记录的是当前已经执行到哪个节点了,把对应的节点对象记录到这个里面

    流程结束后,这张表对应的数据会清除

    在这里插入图片描述

在这里插入图片描述

  • 运行时节点人员数据信息表 :[ACT_RU_IDENTITYLINK]

    运行时用户关系信息,存储任务节点与参与者的相关信息
    也就是只要当前任务有参与者,就会将参与者的信息保存到这个表,多个人参与,保存多个信息

    在这里插入图片描述

  • **运行时任务节点表:[ACT_RU_TASK] **

    一个流程有多个节点,到某一个节点的时候,都会更新这个表,将当前节点的数据更新到这个表

    在这里插入图片描述

审批流过程

  1. 部署流程,到ACT_RE_PROCDEF表看有没有新增一条对应的数据
  2. 启动流程实例,执行流程对象(可能多个),到ACT_HI_PROCINSTACT_RU_EXECUTION表看有没有新增对应数据
  3. 完成整个流程,过程主要看ACT_RU_TASKACT_RU_IDENTITYLINK表的更新情况

五、画流程图

  • IDEA安装插件:

    在这里插入图片描述

  • 在resource下创建一个目录process存放流程图文件

    在这里插入图片描述

  • 右键,新建流程图文件

    在这里插入图片描述

  • 具体画图过程省略,这里介绍画完之后的流程图的重点信息

    2个审批节点的流程图为例(增加、减少节点都需要另外画图部署)

    1. 定义流程的id和名字(后续代码可以取到)

      在这里插入图片描述

    2. 开始节点

      在这里插入图片描述

    3. 审批节点

      第1个审批节点:

      在这里插入图片描述

      第2个审批节点,同上

      在这里插入图片描述

    4. 结束节点

      在这里插入图片描述

    5. 二级节点之后的网关

      这里二级审批完之后,会出现2种不同的可能走向(审批通过,继续到一级审批节点;审批不通过,直接结束),所以需要加上一个网关

      【由于时间较赶等原因,本项目不做回退的实现,所以审核不通过都是直接走向结束节点(一级审批节点通过或不通过都是走向结束节点)】

      在这里插入图片描述

    6. 节点之间或节点与网关之间的连接线

      在这里插入图片描述

      在这里插入图片描述

      在这里插入图片描述

      重点注意:网关后的线

      定义一个条件变量,当SecondJudge=true时(代码赋值),即审核通过,会走向 一级审核 节点,否则走向结束节点,如下图所示

      【当二级组织发起审核,但是选择最终审批组织也是二级的时候,审核通过会赋值SecondJudge=false,直接走结束节点】

      在这里插入图片描述

      在这里插入图片描述

六、部署流程

本项目采用的是通过接口,手动部署的方式【每新建或修改流程图都要调用一次接口来部署(后续打算优化成自动部署或者定时任务调用接口部署)】

    @ApiOperation("手动部署照片审核")     @GetMapping("/photo/process/{typeLevel}")     public String auditingPhotoProcessByTypeLevel(@PathVariable("typeLevel") Integer typeLevel, @RequestParam("force") Boolean force) {         return auditingPhotoService.auditingPhotoProcessByTypeLevel(typeLevel,force);     } 
    /**      * 手动部署      * @param typeLevel 组织等级      * @param force 是否强制部署(当修改了流程图的时候需要传true)      * @return 部署结果      */     public String auditingPhotoProcessByTypeLevel(Integer typeLevel, Boolean force); 
    @Override     public String auditingPhotoProcessByTypeLevel(Integer typeLevel, Boolean force) {         switch (typeLevel) {             case 6:                 auditingPhotoSixService.process(force);                 break;             case 5:                 auditingPhotoFiveService.process(force);                 break;             case 4:                 auditingPhotoFourService.process(force);                 break;             case 3:                 auditingPhotoThreeService.process(force);                 break;             case 2:                 auditingPhotoTwoService.process(force);                 break;             case 1:                 auditingPhotoOneService.process(force);                 break;             default:                 throw new ServicesException(ResultStatus.ARGS_VALID_ERROR);         }         return typeLevel + "级照片流程部署成功";     } 
    /**      * 部署流程      * @param force      * @return      */     public void process(Boolean force); 
    public void process(Boolean force) {         //判断流程是否已经部署,当force=0时,         if (force == null || force) {             //部署流程             DeploymentBuilder builder = repositoryService.createDeployment();             builder.addClasspathResource(AuditingConstant.BpmnXmlPhotoPathConstant.AUDITING_PHOTO_SIX_XML).disableSchemaValidation();             String id = builder.deploy().getId();             repositoryService.setDeploymentKey(id, AuditingConstant.BpmnIdConstant.AUDITING_PHOTO_SIX_ID);         } else {             //检测流程是否已经部署过             List<ProcessDefinition> definitions = repositoryService.createProcessDefinitionQuery()                     .processDefinitionKey(AuditingConstant.BpmnIdConstant.AUDITING_PHOTO_SIX_ID)                     .list();             if (!definitions.isEmpty()) {                 // 已经部署过流程定义                 throw new ServicesException(ResultStatus.AUDITING_PROCESS_DUPLICATE);             } else {                 //部署流程                 DeploymentBuilder builder = repositoryService.createDeployment();                 builder.addClasspathResource(AuditingConstant.BpmnXmlPhotoPathConstant.AUDITING_PHOTO_SIX_XML).disableSchemaValidation();                 String id = builder.deploy().getId();                 repositoryService.setDeploymentKey(id, AuditingConstant.BpmnIdConstant.AUDITING_PHOTO_SIX_ID);             }         }     } 

这里AuditingConstant.BpmnXmlPhotoPathConstant.AUDITING_PHOTO_SIX_XML是流程图的路径,如下图所示

在这里插入图片描述

部署好后,查看数据表 ACT_RE_PROCDEF 即可判断是否成功部署

在这里插入图片描述

七、发起流程

前提: 业务表(需要审批的)数据创建 ——> 点击提交审核

如下图的照片墙审核,创建一条新的数据,此时一开始没审核,状态是“草稿”,点击发布后,才会触发审批流程

在这里插入图片描述

1.示例

二级组织用户 新增一个照片墙,点击发布(选择审核等级为 上级(一级)组织,即需要经过两个审批节点才截止

【只要是二级发起的,都走的是2个审批节点的流程图,只不过根据结束节点会有不同的走向逻辑,如果这里选择本级(二级)结束,则不论二级通过不通过,都会直接走向结束节点】

在这里插入图片描述

点击发布后,会启动一个流程实例,并执行流程对象,见表ACT_HI_PROCINSTACT_RU_EXECUTION

ACT_HI_PROCINST(历史流程实例表)

在这里插入图片描述

ACT_RU_EXECUTION(运行时流程执行对象表):

在这里插入图片描述

如下图,当二级用户点击发步后,会发起审核,先走到 “二级审核2” 节点,对应上图的第1条数据

在这里插入图片描述

2.相关代码

    @ApiOperation("发起照片审核")     @ApiImplicitParams({             @ApiImplicitParam(type = "query", name = "taskName", value = "任务名称", required = true),             @ApiImplicitParam(type = "query", name = "priority", value = "优先级", required = true),             @ApiImplicitParam(type = "query", name = "desc", value = "描述", required = true),             @ApiImplicitParam(type = "query", name = "photoWallId", value = "照片墙id", required = true),             @ApiImplicitParam(type = "query", name = "auditingOrganizeId", value = "审核的组织id", required = true)})     @ApiResponses({@ApiResponse(response = ResponseResult.class, message = "1", code = 200),             @ApiResponse(response = ServiceException.class, message = "系统错误,请稍等!", code = 4000)})     @PostMapping("/startPhotoAuditProcess")     public ResponseResult<String> photoStartAuditing(@RequestBody Map<String, Object> map) {         return ResponseResult.success(auditingPhotoService.photoStartAuditing(map));     } 
    /**      * 启动流程      * @param map      * @return success      */     public String photoStartAuditing(Map<String,Object> map); 

下面代码解释:根据当前用户的组织级别,走不同的实现方法【代码比较臃肿,后续再优化,后面的代码同理】

    @Override     @Transactional(rollbackFor = Exception.class)     public String photoStartAuditing(Map<String, Object> map) {         //根据照片墙id查找照片墙,给照片墙设置审核的组织ID         PhotoWall photoWall = photoWallService.selectPhotoWallDetail(map.get("photoWallId") + "");         photoWall.setOrganizeAuditingId(Long.parseLong(map.get("auditingOrganizeId") + ""));         photoWall.setOpinion("");         OrganizeTreeVO userOrganize = iOrganizeService.getUserOrganize();         photoWallService.updatePhotoWallForAuditing(photoWall);         //当前组织的级别         Integer typeLevel = userOrganize.getTypeLevel();         Integer typeLevelSix = 6;         Integer typeLevelFive = 5;         Integer typeLevelFour = 4;         Integer typeLevelThree = 3;         Integer typeLevelTwo = 2;         Integer typeLevelOne = 1;         if (typeLevel.equals(typeLevelSix)) {             auditingPhotoSixService.startAuditProcess(map);         } else if (typeLevel.equals(typeLevelFive)) {             auditingPhotoFiveService.startAuditProcess(map);         } else if (typeLevel.equals(typeLevelFour)) {             auditingPhotoFourService.startAuditProcess(map);         } else if (typeLevel.equals(typeLevelThree)) {             auditingPhotoThreeService.startAuditProcess(map);         } else if (typeLevel.equals(typeLevelTwo)) {             auditingPhotoTwoService.startAuditProcess(map);         } else if (typeLevel.equals(typeLevelOne)) {             auditingPhotoOneService.startAuditProcess(map);         }         return "success";     } 
/**  * 启动流程  * @param map  */ public void startAuditProcess(Map<String,Object> map); 
public void startAuditProcess(Map<String, Object> map) {     String id = map.get("photoWallId") + "";     //修改照片墙的状态     PhotoWall photoWall = photoWallService.selectPhotoWallDetail(id);     photoWall.setAuditState(1);     photoWall.setOrganizeAuditingId(Long.parseLong(map.get("auditingOrganizeId") + ""));     Boolean code = photoWallService.updatePhotoWallForAuditing(photoWall);      if (code) {         // 获取当前登录用户的组织信息         OrganizeTreeVO userOrganize = iOrganizeService.getUserOrganize();         //当前组织的级别         Integer typeLevel = userOrganize.getTypeLevel();         //用来封装存储每一级组织的审核人,key是integer,表示不同级的组织,value是个list集合,每一级组织的审核人         HashMap<String, List<SysUser>> auditors = new HashMap<>(10);         //找出每一级审批流人员         activitiService.getAuditors(userOrganize,typeLevel,auditors);         // 设置流程变量         Map<String, Object> variables = new HashMap<>(10);         //获得每级审核的审核人         List<String> firstAuditor = getAuditorsId(auditors.get("1"));         List<String> secondAuditor = getAuditorsId(auditors.get("2"));         //审核人         variables.put("firstAuditor", firstAuditor);         variables.put("secondAuditor", secondAuditor);          String formKey = AuditingConstant.BpmnIdConstant.AUDITING_PHOTO_TWO_ID + ":";         String bussinessKey = formKey + id;         variables.put("bussinessKey", bussinessKey);         // 启动流程实例         runtimeService.startProcessInstanceByKey(AuditingConstant.BpmnIdConstant.AUDITING_PHOTO_TWO_ID, bussinessKey, variables);          //给接下来的每一个审核人都创建一个,在刚发起的时候,是同一级的审核人         List<SysUser> auditorsTypeLevel = auditors.get(typeLevel + "");         //获得和登录用户同一级的审核人的id         List<String> auditorsTypeLevelIds = getAuditorsId(auditorsTypeLevel);         for (int i = 0; i < auditorsTypeLevelIds.size(); i++) {             SysTask sysTask = new SysTask();             sysTask.setTaskName((String) map.get("taskName"));             sysTask.setPriority(Integer.valueOf(map.get("priority") + ""));             sysTask.setDescribe((String) map.get("desc"));             sysTask.setPhotoWallId((String) map.get("photoWallId"));             sysTask.setCreatorName(SecurityUtils.getLoginUser().getUsername());             sysTask.setCreatorId(SecurityUtils.getLoginUser().getUserId());             //审核人的名字  这里要怎么设置啊,审核人的名字和id,用的是候选用户啊             sysTask.setAuditingPeople(auditorsTypeLevel.get(i).getUserName());             //审核人的id             sysTask.setAuditingPeopleid(Long.parseLong(auditorsTypeLevelIds.get(i)));             sysTask.setState(1);             sysTask.setAuditingType(2);             //任务表添加             iSysTaskService.addTask(sysTask);             //审核人的消息             Message message = new Message();             SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日");             String date = sdf.format(new Date());             message.setContent("你在" + date + "有一个照片墙的审核");             message.setCreateTime(new Date());             message.setState(1);             message.setUserId(auditorsTypeLevelIds.get(i));             message.setType(1);             messageService.addMessage(message);         }          //登录用户的消息         Message message = new Message();         SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日");         String date = sdf.format(new Date());         message.setContent("你在" + date + "发起了一个照片墙审核");         message.setCreateTime(new Date());         message.setState(1);         message.setUserId(SecurityUtils.getLoginUser().getUserId() + "");         message.setType(2);         messageService.addMessage(message);     } } 

上方代码重点

  • 设置变量,启动流程实例

    这里把每一级审核人提前都设置好(后续不变)【这里根据业务需求应该也可以设计成后续动态添加】

    业务id bussinessKey 规则在此设定,调用最后一行的activity api时候需要传递,同时将其设置到流程变量 variables 中,后续方便读取

    在这里插入图片描述

  • 业务部分

    在这里插入图片描述

    在这里插入图片描述

    1. 修改 照片墙业务表 流程相关字段
    2. 新增 审核任务业务表
    3. 发送消息

八、审批过程

现在流程走到第一个审批节点,即 二级审核2

在这里插入图片描述

此时,运行时节点人员数据信息表 ACT_RU_IDENTITYLINK,存入二级审核2 节点的 是审核人角色 的 用户,尾号20用户和尾号52用户都是该节点的审批人【该项目里,只要其中一个审批通过,就算通过,反之,一个拒绝就算拒绝】,

且被分配到了任务(同个任务),见表ACT_RU_TASK,如下图

在这里插入图片描述

在这里插入图片描述

对应业务表 任务表里,也加了2条数据

在这里插入图片描述

他们之间通过 BUSINESS_KEY_ 来关联

1.审核通过

审批通过,在activity7框架中,只需要设置SecondJudge变量,然后将task任务完成即可

在这里插入图片描述

1.示例

二级组织人员 尾号52用户 创建了一个照片墙,点击发布后,生成本级人员(尾号52和尾号20)的任务,此时52用户进入“我的待办”里(业务表 任务表),找到对应任务,点击审批通过,如下图

在这里插入图片描述

2.相关代码

@ApiOperation("照片墙审批通过") @ApiImplicitParams({         @ApiImplicitParam(type = "query", name = "id", value = "任务id", required = true),         @ApiImplicitParam(type = "query", name = "opinion", value = "建议", required = false) }) @PostMapping("/auditing/photo/approve/{id}") public ResponseResult<String> auditingPhotoApprove(@PathVariable Integer id, @RequestParam(required = false) String opinion) {     return ResponseResult.success(auditingPhotoService.auditingPhotoApprove(id, opinion)); } 
/**  * 审核通过  * @param id  * @param opinion  * @return success  */ public String auditingPhotoApprove(Integer id,String opinion); 

下面代码解释:

通过照片墙的创建者的组织等级,走不同的审核通过实现类

@Override @Transactional(rollbackFor = Exception.class) public String auditingPhotoApprove(Integer id, String opinion) {     //id是任务的id,可以获得照片墙的id     //再去新建表中查询这个照片墙是哪级创建的,     //这个级数直接判断吗,然后去调用哪个类的approve方法?     SysTask sysTask = iSysTaskService.selectTaskById(id);     //通过任务的informatinid来获得照片墙id     String photoId = sysTask.getPhotoWallId();      //根据照片墙的id去查询审核创建者的级别     LambdaQueryWrapper<PhotoWall> lambdaQueryWrapper = new LambdaQueryWrapper<PhotoWall>();     lambdaQueryWrapper.eq(PhotoWall::getPhotoWallId, photoId);     PhotoWall photoWall = photoWallService.getOne(lambdaQueryWrapper);      //获得当前等级     Long organizeId = photoWall.getOrganizeId();     Integer userOrganizeLevel = iOrganizeService.searchOrganizeById(organizeId).getOrganizeLevel();     Integer userOrganizeLevelOne = 1;     Integer userOrganizeLevelTwo = 2;     Integer userOrganizeLevelThree = 3;     Integer userOrganizeLevelFour = 4;     Integer userOrganizeLevelFive = 5;     Integer userOrganizeLevelSix = 6;      //获得审核组织的级别     Long auditingOrganizeId = photoWall.getOrganizeAuditingId();     Integer auditingOrganizeLevel = iOrganizeService.searchOrganizeById(auditingOrganizeId).getOrganizeLevel();      if (userOrganizeLevel.equals(userOrganizeLevelOne)) {         auditingPhotoOneService.approve(id, opinion);     } else if (userOrganizeLevel.equals(userOrganizeLevelTwo)) {         auditingPhotoTwoService.approve(id, opinion, auditingOrganizeLevel);     } else if (userOrganizeLevel.equals(userOrganizeLevelThree)) {         auditingPhotoThreeService.approve(id, opinion, auditingOrganizeLevel);     } else if (userOrganizeLevel.equals(userOrganizeLevelFour)) {         auditingPhotoFourService.approve(id, opinion, auditingOrganizeLevel);     } else if (userOrganizeLevel.equals(userOrganizeLevelFive)) {         auditingPhotoFiveService.approve(id, opinion, auditingOrganizeLevel);     } else if (userOrganizeLevel.equals(userOrganizeLevelSix)) {         auditingPhotoSixService.approve(id, opinion, auditingOrganizeLevel);     }     return "success"; } 
/**  * 审核通过  * @param id  * @param opinion  * @param auditingOrganizeLevel  */ public void approve(Integer id, String opinion,Integer auditingOrganizeLevel); 
@Override public void approve(Integer id, String opinion, Integer auditingOrganizeLevel) {     //获取任务的候选人是登录用户的任务的方法     List<Task> taskList = activitiService.getTaskIdByCandidate(SecurityUtils.getLoginUser().getUserId().toString());     //当前登录用户的组织级别     Integer typeLevel = iOrganizeService.getUserOrganize().getTypeLevel();     //搜索出工作台选的任务id     SysTask sysTask = iSysTaskService.selectTaskById(id);     //通过任务的photoWallId来获得照片墙id     PhotoWall photoWall = photoWallService.selectPhotoWallDetail(sysTask.getPhotoWallId() + "");     String photoWallId = photoWall.getPhotoWallId();     auditingInformTwoApproveService(taskList, photoWallId, typeLevel, photoWall, auditingOrganizeLevel, opinion);     // 获取当前登录用户的组织信息     OrganizeTreeVO userOrganize = iOrganizeService.getUserOrganize();     //用来封装存储每一级组织的审核人,key是integer,表示不同级的组织,value是个list集合,每一级组织的审核人     HashMap<String, List<SysUser>> auditors = new HashMap<>(10);     //找出每一级审批流人员     activitiService.getAuditors(userOrganize,typeLevel,auditors);     List<String> auditorsList = new ArrayList<>();     if(typeLevel.equals(AuditingConstant.Number.TWO)){         auditorsList = getAuditorsId(auditors.get("2"));     }     if (typeLevel == 1) {         auditorsList = getAuditorsId(auditors.get("1"));     }      sysTask.setState(2);     sysTask.setOpinion(opinion);     sysTask.setCompletionTime(new Date());     iSysTaskService.updateTask(sysTask);     Long userId1 = SecurityUtils.getLoginUser().getUserId();     String photoWallId1 = sysTask.getPhotoWallId();     //删除其他用户中关联这个照片墙id的任务     //循环审核人列表     for (String s : auditorsList) {         //当审核人不等于登录用户时,即其他用户         if (!Objects.equals(s, userId1 + "")) {             //搜索出他的全部任务             List<SysTask> sysTaskList = iSysTaskService.selectTaskByAuditorId(Long.parseLong(s));             //循环任务             for (SysTask task : sysTaskList) {                 //找出任务中关联的照片墙id等于当前登录用户审核的任务的关联的照片墙id                 if (photoWallId1.equals(task.getPhotoWallId())) {                     //删除                     iSysTaskService.deleteTask(task.getTaskId().intValue());                 }             }         }     }      if (typeLevel == 1 || typeLevel.equals(auditingOrganizeLevel)) {         photoWall.setAuditState(2);         photoWallService.updatePhotoWallForAuditing(photoWall);         Message message = new Message();         Date date = new Date();         message.setContent("你的照片墙在" + typeLevel + "级审核通过");         message.setCreateTime(date);         message.setState(1);         String userId = sysTask.getCreatorId() + "";         message.setUserId(userId);         message.setType(2);         message.setTaskId(sysTask.getTaskId().intValue());         messageService.addMessage(message);         return;     }     if (typeLevel.equals(AuditingConstant.Number.TWO)) {         auditorsList = getAuditorsId(auditors.get("1"));     }     for (String s : auditorsList) {         SysTask sysTask1 = new SysTask();         sysTask1.setTaskName(sysTask.getTaskName());         sysTask1.setPriority(sysTask.getPriority());         sysTask1.setDescribe(sysTask.getDescribe());         sysTask1.setPhotoWallId(sysTask.getPhotoWallId());         sysTask1.setCreatorName(SecurityUtils.getLoginUser().getUsername());         sysTask1.setCreatorId(SecurityUtils.getLoginUser().getUserId());         sysTask1.setAuditingPeopleid(Long.parseLong(s));         SysUser sysUser = iSysUserService.selectUserById(Long.parseLong(s));         sysTask1.setAuditingPeople(sysUser.getUserName());         sysTask1.setState(1);         sysTask1.setAuditingType(2);         iSysTaskService.addTask(sysTask1);         sendMessage(s, sysTask);     }     sendMessage(typeLevel, sysTask); } 
private void auditingInformTwoApproveService(List<Task> taskList, String photoWallId, Integer typeLevel, PhotoWall photoWall, Integer auditingOrganizeLevel, String opinion) {     if (!ObjectUtils.isEmpty(taskList)) {         for (Task item : taskList) {             ProcessInstance processInstance = runtimeService                     .createProcessInstanceQuery()                     .processInstanceId(item.getProcessInstanceId())                     .singleResult();             //根据流程实例得到bussinesskey,格式是formkey:id             String a = processInstance.getBusinessKey();             if (StringUtils.isNotBlank(a)) {                 String[] b = a.split(":");                 String photoId = b[1];                 //判断bussinesskey,bussinesskey是任务表中的记录的id,在发起流程的时候会插入任务表,任务表的id也会变成流程变量                 if (photoId.equals(photoWallId)) {                     if (typeLevel == 2) {                         if (typeLevel.equals(auditingOrganizeLevel)) {                             taskService.setVariable(item.getId(), "SecondJudge", false);                         } else {                             taskService.setVariable(item.getId(), "SecondJudge", true);                         }                     } else if (typeLevel == 1) {                         //如果当前审核人是一级组织的,那审核就结束了                         photoWall.setAuditState(2);                         photoWall.setOpinion(opinion);                         photoWallService.updatePhotoWallForAuditing(photoWall);                     }                     taskService.addComment(item.getId(), item.getProcessInstanceId(), "审核通过");                     taskService.complete(item.getId());                     break;                 }             }         }     } } 

上面代码重点

  • 找到activity的任务表中,当前该用户的所有任务

    在这里插入图片描述

    @Override public List<Task> getTaskIdByCandidate(String userId) {     List<ActivitiTaskId> activitiTaskId = activitiMapper.getTaskIdByCandidate(userId);     List<String> activitiTaskIds = new ArrayList<>();     for (com.znak.platform.entity.ActivitiTaskId taskId : activitiTaskId) {         activitiTaskIds.add(taskId.getTaskId());     }     List<Task> taskList = new ArrayList<>();     for (String taskId : activitiTaskIds) {         Task task = taskService.createTaskQuery().taskId(taskId).singleResult();         taskList.add(task);     }     return taskList; } 
    <select id="getTaskIdByCandidate" resultType="com.znak.platform.entity.ActivitiTaskId">     select distinct TASK_ID_ from ACT_RU_IDENTITYLINK     where USER_ID_ = #{userId}  and TASK_ID_ != "" </select> 
  • 根据bussinesskey找到对应的任务,修改变量SecondJudge,并完成任务

    在这里插入图片描述

    这里注意,如果当前是走到一级审批节点了,则走下面的else if逻辑,直接将业务表修改审核通过(不用设置变量,因为没有网关了),如下图

    在这里插入图片描述

    在这里插入图片描述

  • 业务相关

    • 修改业务表的审批流相关字段,同时发送消息,同上

    • 然后删除同级别组织人员的 业务表 任务表,新建下一级的人员的业务表 任务表,见代码

2.审批不通过

过程和审批通过大致一样

在这里插入图片描述

1.相关代码

@ApiOperation("照片审核不通过") @ApiResponses({@ApiResponse(response = ResponseResult.class, message = "1", code = 200),         @ApiResponse(response = ServiceException.class, message = "系统错误,请稍等!", code = 4000)}) @ApiImplicitParams({         //发起资讯申请相关字段         @ApiImplicitParam(type = "query", name = "id", value = "任务id", required = true),         @ApiImplicitParam(type = "query", name = "opinion", value = "建议", required = false) }) @PostMapping("/auditing/photo/reject/{id}") public ResponseResult<String> auditingPhotoReject(@PathVariable Integer id, @RequestParam(required = false) String opinion) {     return ResponseResult.success(auditingPhotoService.auditingPhotoReject(id, opinion)); } 
/**  * 审核不通过  * @param id  * @param opinion  * @return success  */ public String auditingPhotoReject(Integer id,String opinion); 
@Override @Transactional(rollbackFor = Exception.class) public String auditingPhotoReject(Integer id, String opinion) {     //id是任务的id,可以获得资讯的id     //再去新建表中查询这个资讯是哪级创建的,     //这个级数直接判断吗,然后去调用哪个类的approve方法?     SysTask sysTask = iSysTaskService.selectTaskById(id);     //通过任务的informatinid来获得资讯id     String photoWallId = sysTask.getPhotoWallId();     //根据资讯的id去查询审核创建者的级别     LambdaQueryWrapper<PhotoWall> lambdaQueryWrapper = new LambdaQueryWrapper<PhotoWall>();     lambdaQueryWrapper.eq(PhotoWall::getPhotoWallId, photoWallId);     PhotoWall photoWall = photoWallService.getOne(lambdaQueryWrapper);      //获得当前等级     Long organizeId = photoWall.getOrganizeId();     Integer userOrganizeLevel = iOrganizeService.searchOrganizeById(organizeId).getOrganizeLevel();     Integer userOrganizeLevelOne = 1;     Integer userOrganizeLevelTwo = 2;     Integer userOrganizeLevelThree = 3;     Integer userOrganizeLevelFour = 4;     Integer userOrganizeLevelFive = 5;     Integer userOrganizeLevelSix = 6;     if (userOrganizeLevel.equals(userOrganizeLevelOne)) {         auditingPhotoOneService.rej(id, opinion);     } else if (userOrganizeLevel.equals(userOrganizeLevelTwo)) {         auditingPhotoTwoService.rej(id, opinion);     } else if (userOrganizeLevel.equals(userOrganizeLevelThree)) {         auditingPhotoThreeService.rej(id, opinion);     } else if (userOrganizeLevel.equals(userOrganizeLevelFour)) {         auditingPhotoFourService.rej(id, opinion);     } else if (userOrganizeLevel.equals(userOrganizeLevelFive)) {         auditingPhotoFiveService.rej(id, opinion);     } else if (userOrganizeLevel.equals(userOrganizeLevelSix)) {         auditingPhotoSixService.rej(id, opinion);     }     return "success"; } 
/**  * 审核不通过  * @param id  * @param opinion  */ public void rej(Integer id, String opinion); 
public void rej(Integer id, String opinion) {     //获取任务的候选人是登录用户的任务的方法     List<Task> taskList = activitiService.getTaskIdByCandidate(SecurityUtils.getLoginUser().getUserId().toString());     //当前登录用户的组织级别     Integer typeLevel = iOrganizeService.getUserOrganize().getTypeLevel();      //搜索出工作台选的任务id     SysTask sysTask = iSysTaskService.selectTaskById(id);      //通过任务的informatinid来获得资讯id     PhotoWall photoWall = photoWallService.selectPhotoWallDetail(sysTask.getPhotoWallId());     String photoWallId = photoWall.getPhotoWallId();     auditingInformTwoRejService(taskList, photoWallId, typeLevel, photoWall,opinion);      // 获取当前登录用户的组织信息     OrganizeTreeVO userOrganize = iOrganizeService.getUserOrganize();     //用来封装存储每一级组织的审核人,key是integer,表示不同级的组织,value是个list集合,每一级组织的审核人     HashMap<String, List<SysUser>> auditors = new HashMap<>(4);     //找出每一级审批流人员     activitiService.getAuditors(userOrganize,typeLevel,auditors);     //防止四级发起的审核,然后任务到达三级的时候调用此方法,会报错4级审核人找不到     List<String> auditorsList = new ArrayList<>();      Integer typeLevelTwo = 2;     if (typeLevel.equals(typeLevelTwo)) {         auditorsList = getAuditorsId(auditors.get("2"));      }     if (typeLevel == 1) {         auditorsList = getAuditorsId(auditors.get("1"));     }     //这一个等级的组织的审核任务处理,处理上一阶段的任务     //获得当前级别的审核人     sysTask.setState(3);     sysTask.setOpinion(opinion);     sysTask.setCompletionTime(new Date());     iSysTaskService.updateTask(sysTask);     Long userId1 = SecurityUtils.getLoginUser().getUserId();     String photoWallId1 = photoWall.getPhotoWallId();     //删除其他用户中关联这个咨询id的任务     //循环审核人列表     for (String s : auditorsList) {         //当审核人不等于登录用户时,即其他用户         if (!Objects.equals(s, userId1 + "")){             //搜索出他的全部任务             List<SysTask> sysTaskList = iSysTaskService.selectTaskByAuditorId(Long.parseLong(s));             //循环任务             for(SysTask task : sysTaskList){                 //找出任务中关联的照片墙id等于当前登录用户审核的任务的关联的照片墙id                 if(photoWallId1.equals(task.getPhotoWallId())){                     //删除                     iSysTaskService.deleteTask(task.getTaskId().intValue());                 }             }         }     }      Message message = new Message();     Date date = new Date();     message.setContent("你的照片墙在" + typeLevel + "级审核没有通过");     message.setCreateTime(date);     message.setState(1);     //这个审核的是谁的流程     String userId = sysTask.getCreatorId() + "";     message.setUserId(userId);     message.setType(2);     message.setTaskId(sysTask.getTaskId().intValue());     messageService.addMessage(message);  } 
private void auditingInformTwoRejService(List<Task> taskList, String photoWallId, Integer typeLevel, PhotoWall photoWall,String opinion) {     if (!ObjectUtils.isEmpty(taskList)) {         for (Task item : taskList) {             ProcessInstance processInstance = runtimeService                     .createProcessInstanceQuery()                     .processInstanceId(item.getProcessInstanceId())                     .singleResult();             //根据流程实例得到bussinesskey,格式是formkey:id             String a = processInstance.getBusinessKey();             if (StringUtils.isNotBlank(a)) {                 String[] b = a.split(":");                 String photoId = b[1];                 //判断bussinesskey,bussinesskey是任务表中的记录的id,在发起流程的时候会插入任务表,任务表的id也会变成流程变量                 if (photoId.equals(photoWallId)) {                     //根据当前登录用户的组织级别判断是第几级判断,设置相关的流程变量                     if (typeLevel == 2) {                         photoWall.setAuditState(4);                         photoWall.setOpinion(opinion);                         photoWallService.updatePhotoWallForAuditing(photoWall);                         taskService.setVariable(item.getId(), "SecondJudge", false);                     } else if (typeLevel == 1) {                         //如果当前审核人是一级组织的,那审核就结束了                         photoWall.setAuditState(4);                         photoWall.setOpinion(opinion);                         photoWallService.updatePhotoWallForAuditing(photoWall);                     }                     taskService.addComment(item.getId(), item.getProcessInstanceId(), "审核不通过");                     taskService.complete(item.getId());                     break;                 }             }         }     } } 

上面代码的重点:

  • 找到activity的任务表中,当前该用户的所有任务

    同上

  • 根据bussinesskey找到对应的任务,修改变量SecondJudge,并完成任务

    同上

  • 业务相关

    • 修改业务表的审批流相关字段,同时发送消息,同上

    • 然后删除同级别组织人员的 业务表 任务表,见代码

九、业务表相关字段

1.任务表

在这里插入图片描述

2.业务数据表

以 照片墙 为例

在这里插入图片描述

十、业务表数据权限变化

  • 审核前,即草稿状态的数据,只能看自己创建的
  • 审核通过,本级 到 最终审核组织 之间的用户都可见

广告一刻

为您即时展示最新活动产品广告消息,让您随时掌握产品活动新动态!