================将流程的一些使用技巧写下来,以备后续复用====================
1、人工处理节点的超时自动流传功能:
某个项目中,客户提出了这么一个要求:当某个处理环节的责任人逾期不处理的话,流程将自动流转到下一环节(如果有多个路由的话,可以设定特定的路由)。
这个功能使用joinwork的特定节点是很难实现的,我们采用了一种灵活的基于“消息”的处理方法!
1、首先创建一个新的流程,其启动节点是基于消息启动的。
2、在需要进行逾期自动处理的人工处理节点上,先设置任务时限,并设置第一次(或第二次)任务消息的发生时间,并在消息发生时所对应的事件处理中,发送一个消息,将当前流程实例,流程节点、计划路由的路线、以参数的形式封装在消息中,代码如下:
Map msgDataMap = new java.util.HashMap(); Map myCustom = new java.util.HashMap(); Map myDataMap = new java.util.HashMap(); myDataMap.put("affirmIdea", "ok"); myDataMap.put("currentUserIdea", "**** 用户超时,系统自动处理工作任务! ****"); msgDataMap.put("text", "deadline_auto_doing"); msgDataMap.put("custom", myCustom); myCustom.put("myProcessId", _process.processId); myCustom.put("myCaseId", _process.caseId); myCustom.put("myNodeId", _node.id); myCustom.put("myLinkId", "Link_11"); myCustom.put("dataMap", myDataMap); Message.sendMessage("message1", 1, 60, msgDataMap); |
3、在新创建流程的消息启动节点中的“消息设置”中加入如下代码:
//消息匹配 text.equals("deadline_auto_doing") |
Map myCustom = (Map) custom; System.out.println(" 未处理工作任务 ProcessId=" + myCustom.get("myProcessId")); System.out.println(" 未处理工作任务 caseId=" + myCustom.get("myCaseId")); System.out.println(" 未处理工作任务 nodeId=" + myCustom.get("myNodeId")); Map myDataMap = (Map) (myCustom.get("dataMap")); String queryStr = "from WorkitemRun dao where (dao.state=7 or dao.state=4) and dao.caseid='" + myCustom.get("myCaseId") + "' and dao.activityid='" + myCustom.get("myNodeId") + "' "; System.out.println(" 查询语句是: " + queryStr); DataSet dataset = DataBase.createQueryByHql(queryStr, "WorkitemRun"); List list2 = dataset.list(); ProcessEngine engine = WAPIFactory.getProcessEngine(_domain); WorkItemManager workManager = WAPIFactory.getWorkItemManager(engine.getTaskManager()); for (int i = 0; i < list2.size(); i++) { WorkitemRun wr = (WorkitemRun) list2.get(i); if ((wr.getPerformer() != null) || (wr.getOwner() != null)) { Object sessionData = null; workManager.finishWorkItem(((wr.getPerformer() == null) ? wr.getOwner() : wr.getPerformer()), wr.getId().intValue(), (String) myCustom.get("myNodeId"), (String) myCustom.get("myLinkId"), myDataMap, sessionData); } } |
注意:为了使用的方便,我们针对WORKITEM_RUN表又创建了一个数据组件 ,在实际应用中,这个可以根据项目需要来决定,另外,要注意导入相应的jar包:
import net.joinwork.bpm.data.dataobject.WorkitemRun; import net.joinwork.bpm.engine.wapi.CaseInfo; import net.joinwork.bpm.engine.wapi.Constant; import net.joinwork.bpm.engine.wapi.FormData; import net.joinwork.bpm.engine.wapi.FormDatas; import net.joinwork.bpm.engine.wapi.ProcessDefManager; import net.joinwork.bpm.engine.wapi.ProcessEngine; import net.joinwork.bpm.engine.wapi.ProcessObject; import net.joinwork.bpm.engine.wapi.WAPIFactory; import net.joinwork.bpm.engine.wapi.WorkItem; import net.joinwork.bpm.engine.wapi.WorkItemManager; |
以上方法不仅可以用于超时任务的自动处理,稍加改动,也可以用于超时任务的邮件报警等等功能实现!
2、针对Joinwork的代理人设置的扩展:
joinwork中设置代理人,是以节点为基础的,虽然能满足功能,但同时也比较繁琐,在实际使用中,会存在诸多不便,主要如下几点:
a、在变更频繁的流程中,如果节点Id被改或者重新添加新的环节的话,用户可能需要再重新设置各个环节的代理人。
b、在我们设计流程的时候,一般都不会去设置特定某个环节权限用户的列表,尤其在频繁变更的环境下,会极大增加维护的工作量,加大出错的概率。因此,在这种情况下,用户在设置代理人的时候,看到的环节列表时整个流程的所有可以设置代理的环节列表,容易给用户长生歧义。
因此,根据实际业务场景,可以在其基础上,对代理人功能进行如下扩展,增加:
a:流程(业务)代理人,在流程范围内的工作任务进行代理。
b:域代理人,在全域范围对工作任务进行代理。
执行顺序如下:如果针对环节设置代理人了,优先采用环节代理人,如果没有,则使用流程(业务)代理人,都没有的话,最后才采用域代理人。
要做到这一点,要对joinwork的jar包和workdesk的代码做多处修改:
a、修改workdesk的WorkItemAction类,在查找代理人列表及保存代理人列表的地方进行修改,以保证能够获得流程代理人及域代理人。
b、针对delegater.jsp文件进行扩展,增加对流程(业务)代理人、域代理人的支持。
c、修改jar包中的,WorkitemMangeImpl.java中的getDelegater方法,增加如下代码:
<textarea cols="50" rows="15" name="code" class="java">//-----------没有环节代理人,则找这个用户设置了流程代理人了没有,如果有,则返回流程代理人------------- if (delegaterList == null || delegaterList.size() == 0) { delegaterList = Delegater.getDelegater(database, userId, engineDomain, processId, null); } //-----------没有流程代理人,则找这个用户设置了全局代理人了没有,如果有,则返回全局代理人------------- if (delegaterList == null || delegaterList.size() == 0) { delegaterList = Delegater.getDelegater(database, userId, engineDomain, null, null); }</textarea>
d、修改jar包中的Delegater.java文件中的getDelegater方法,修改为可以动态识别参数是否为空!
这样的话,最简单的使用方式就是:用户只要设置一个全局(域)代理人,流程就会在可代理环节中将工作任务指派给这个全局代理人了!