FormService和IdentityService在Activiti7.0中删除了;这块activiti可能考虑表单和身份验证是具体的业务方面的事情,与工作流本身就没有多大的关系,更何况这两个服务根本无法满足所有的人;
activiti7虽然删除了这两个服务,但是有些情况,我们还是要用的,因此给我们预留了相关功能点,只需要接入整合就可以了;
本次我只研究了类似IdentityService相关实现在activiti7应用;表单的可以执行研究,我这边暂时用不到;进入正题。
我们知道在化BPMN流程时有三个字段确定负责人情况,分别是assignee、candidateUsers、candidateGrous,这三个都是支持UEL的,扩展性比较强,我分别解释下这三个;
assignee:受托人,也就是任务具体的执行人,可以通过UEL在创建流程实例时进行设置;适用简单流程,没有多用户情况
candidateUsers:候选者,也就是支持多个用户,可以通过UEL在创建流程实例时进行设置;这个适用于流程节点多个负责人,还有不容易变化的负责人,例如初级审核就张三、李四他俩审核,后期变动不大,这样的是可以适用的
candidateGrous:候选组,这个流程绑定到组,组里有多少负责人,activiti不关心,也就是说,组里的候选人用户,可以动态添加,不受工作流程影响,这个事大部分公司比较适用的,包括我所在公司的业务
花了半天时间研究了这三种,发现最后还是candidateGrous比较适合我目前业务场景;关键activiti在设置节点负责人,可以在创建流程实例、任务办理时、当前流程实例可以设置这些负责人,,与其说是负责人,不如说是流程里的全局变量比较适合
再结合监听器、网关等功能,再复杂的流程基本上都能满足。
继续说下candidateGrous,这里在bpmn里设置UEL表达式即可,例如:
<userTask activiti:candidateGroups="${assigneeGroupBean.bmjlspGroupCode}" activiti:exclusive="true" id="_4" name="部门经理审批"/>
assigneeGroupBean.bmjlspGroupCode 是组名code,我把我测试的说下,我这边用的是group_code,,
其实有些需求,没必要新创建组,因为基本上每个系统都是RBAC设计模型,里面有角色,把角色code或者id当作组名code也是可以的;我测试的demo,为了好测试,就没放到role里,单独拿出来了;还有我设计的不是最合理的,,最好组和用户要用关系表进行关联,我是为了省事,直接在组表里关联用户id;
设计好后以后,我们还需要实现一个接口,这样activiti7在走流程时就会帮我们去找有哪些用户
package com.zsy.common.config;
import cn.hutool.core.collection.ListUtil;
import com.zsy.dao.entity.TGroup;
import com.zsy.dao.entity.TRole;
import com.zsy.dao.entity.TUser;
import com.zsy.dao.service.TGroupService;
import com.zsy.dao.service.TRoleService;
import com.zsy.dao.service.TUserService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.activiti.api.runtime.shared.identity.UserGroupManager;
import java.util.List;
import java.util.stream.Collectors;
/**
* <p>
* 组管理
* </p>
*
* @author zsy
* @since 2021/6/4
*/
@Slf4j
@AllArgsConstructor
public class ActivitiGroupManagerImpl implements UserGroupManager {
private TUserService tUserService;
private TRoleService tRoleService;
private TGroupService tGroupService;
//这里就是activiti通过用户名或者id去找有哪些用户组;目前发现这个方法每次会调用好几次,,这可能是activiti内部问题,后期版本可能会解决
@Override
public List<String> getUserGroups(String username) {
TUser one = tUserService.lambdaQuery().eq(TUser::getUsername, username).one();
List<String> collect = tGroupService.lambdaQuery().eq(TGroup::getUserId, one.getId()).list().stream().map(g -> g.getGroupCode()).collect(Collectors.toList());
log.info("当前用户【{}】所在组:{}",username,collect.toString());
return collect;
}
//这里是限制用户权限访问activiti的,,可以不用管它,,直接返回空也行,我目前在研究这块,我就写上了;后面有时间也介绍下这块如何使用
@Override
public List<String> getUserRoles(String username) {
TUser one = tUserService.lambdaQuery().eq(TUser::getUsername, username).one();
List<String> collect = tRoleService.lambdaQuery().eq(TRole::getUserId, one.getId()).list().stream().map(g -> g.getRoleCode()).collect(Collectors.toList());
log.info("当前用户【{}】所在角色:{}",username,collect.toString());
return collect;
}
@Override
public List<String> getGroups() {
return null;
}
@Override
public List<String> getUsers() {
return null;
}
}
还要在这里把实现类设置上:
springProcessEngineConfiguration.setUserGroupManager(new ActivitiGroupManagerImpl(tUserService,tRoleService,tGroupService));
到这里就没问题了,,我把其他代码也发下:
其他的代码,就是都很类似了,,进行操作即可;
demo正在研究中,,,后面上传;先这样