一、前言
上篇博文《浅谈Activiti工作流引擎用户管理》中已介绍了如何自定义自己的用户管理模块。然而困恼大多数新手的另一个问题:如何将任务分配给有层级关系的组织结构用户呢?例如,我只想把任务分配给我上级部门的领导审批,而上级部门的任务又只分配给指定的上级审批。而按Activiti的用户(user)、组(group)来平级关系来操作的话,则需要设计多个组、多个配置来实现,这显然不合适。
二、需求分析
一般公司的组织结构:
再看看我项目中的部分审批流程截图:
所以,我申请人的申请当然是给我上级部门领导审批,别的领导无权审批。而部门经理审批完后要相对应的上级中心领导来审批。就是这种层级关系。
三、配置文件
用过activiti的都知道,流程定义的配置文件为.bpmn,在eclipse中可以视图或xml格式打开。上面已经看了流程图,那下面则看看其xml中是如何配置的:
首先,我用的是动态表单配置,而每个节点允许签收任务的用户分配如上图红色框。
1、activiti:initiator属性:把启动流程实例的操作人以变量名称“applyUserId”保存到数据库中。
2、activiti:candidateUsers属性:此节点允许签收任务的用户。
例:<userTask id="theTask" name="my task" activiti:candidateUsers="kermit, gonzo" />
3、activiti:candidateGroups属性:此节点允许签收任务的组。
例:<userTask id="theTask" name="my task" activiti:candidateGroups="management, accountancy" />
4、activiti:assignee属性:此节点指定用户签收任务。
例:<userTask id="theTask" name="my task" activiti:assignee="kermit" />
大家应该注意到了,我的配置文件中,不是确定某个人或某个组而是个表达式。没错,关键点就在于此,应为用了spring,所以可以用service表达式来动态指定谁能签收此节点任务。若没用spring的话,解决办法还是有的,可以在此节点上设置监听器啊,监听此任务是谁申请的来判断受理人。
so,废话不多说。看看表达式中我所调用的方法吧:
/** * fms系统流程指定受理人目录业务接口 * @author linhy * */ public interface FmsLdapService { /** * 根据启动用户查询出其部门领导集合 * @param employee * @return */ public List<String> findDeptLeaders(String employee); /** * 根据启动用户查询运营操作者集合 * @param employee * @return */ public List<String> findOperators(String employee); /** * 根据启动用户查询总监领导集合 * @param employee * @return */ public List<String> findLeaders(String employee); /** * 根据启动用户查找财务集合 * @param employee * @return */ public List<String> findFinances(String employee); /** * 根据启动用户查找出纳集合 * @param employee * @return */ public List<String> findCashiers(String employee); }
看接口,大家应该知道什么意思吧,我根据启动实例流程的人,然后通过自己的用户管理系统去查找符合要求的受理任务者。要注意的是,这些方法查找出来的返回值必须是String或List<String>。
恩,这样就解决了如何去指定有层级组织结构的任务分配问题。无需去多配置,多分组。完全可用自己的用户管理系统组织架构去动态查找。这就是activiti的动态表单最大的特点,灵活。
四、结语
两篇文章,介绍了下自己对于Activiti工作流引擎,用户和任务分配模块的见解。并不是很深入,也不是很严谨,只是纯粹的分享与交流。接下去将还会陆续写些关于Activiti工作流引擎的使用心得,感谢阅读,本文若有不足之处,还望谅解指正。
分享是种快乐,坚持是种精神!