Activiti 工作流会签开发设计思路
http://man1900.iteye.com/blog/1607753
在流程业务管理中,任务是通常都是由一个人去处理的,而多个人同时处理一个任务,这种任务我们称之为会签任务。这种业务需求也很常见,如一个请款单,领导审批环节中,就需要多个部门领导签字。在流程业务中,我们可以把每个领导签字的环节都定义为任务,但若这样,这个流程业务有一点是固定的,就是签批人是固定的。而任务是由一个领导签完再到另一领导,当然也可以由多个领导同时签字。
传统的用流程业务来解决可以采用以下的做法:


前者在流程业务中,叫串行会签,也即是由一个领导签完再至另一领导签。后者我们称之为并行会签,表示几个领导同时进行签发,而不清楚最终是谁先签。
以上的解决方式有两大业务需求下是不能满足的,若会签的领导不是固定的,即可以由上一任务审批人提交前随意进行选择,另一种是对于会签业务中,要求若其中一部分领导审批通过,即直接往下走,不需要全部领导进行审批。另外,对于这种情况下,统计最终领导会签的结果也是比较困难的,即对审批单的意见是同意还是否决没有办法清楚。以上两种业务需求也是很常见的日常需求,但我们若采用了固定的流程节点,则不能实现。在这里,可以采用Activiti的节点多实例来处理,以上流程则可以简化为下:



- <userTask activiti:assignee="${assignee}" id="SignTask1" name="领导会签">
- <extensionElements>
- <activiti:taskListener class="com.hotent.platform.service.bpm.listener.TaskSignCreateListener" event="create"/>
- <activiti:taskListener class="com.hotent.platform.service.bpm.listener.TaskAssignListener" event="assignment"/>
- <activiti:taskListener class="com.hotent.platform.service.bpm.listener.TaskCompleteListener" event="complete"/>
- </extensionElements>
- <multiInstanceLoopCharacteristics activiti:elementVariable="assignee" isSequential="false" activiti:collection="${taskUserAssignService.getSignUser(execution)}">
- <completionCondition>${signComplete.isComplete(execution)}</completionCondition>
- </multiInstanceLoopCharacteristics>
- </userTask>


- @Override
- public boolean isComplete(ActivityExecution execution) {
- logger.debug("entert the SignComplete isComplete method...");
- String nodeId=execution.getActivity().getId();
- String actInstId=execution.getProcessInstanceId();
- ProcessDefinition processDefinition=bpmService.getProcessDefinitionByProcessInanceId(actInstId);
- //取得会签设置的规则
- BpmNodeSign bpmNodeSign=bpmNodeSignService.getByDefIdAndNodeId(processDefinition.getId(), nodeId);
- //完成会签的次数
- Integer completeCounter=(Integer)execution.getVariable("nrOfCompletedInstances");
- //总循环次数
- Integer instanceOfNumbers=(Integer)execution.getVariable("nrOfInstances");
- //计算投票结果。
- VoteResult voteResult=calcResult(bpmNodeSign, actInstId, nodeId, completeCounter,instanceOfNumbers);
- String signResult=voteResult.getSignResult();
- boolean isCompleted=voteResult.getIsComplete();
- /**
- * 会签完成做的动作。
- * 1.删除会签的流程变量。
- * 2.将会签数据更新为完成。
- * 3.设置会签结果变量。
- * 4.更新会签节点结果。
- * 5.清除会签用户。
- */
- if(isCompleted){
- //删除会签的变量。
- //删除 assignee,loopCounter变量。
- bpmService.delLoopAssigneeVars(execution.getId());
- logger.debug("set the sign result + " + signResult);
- //将会签数据更新为完成。
- taskSignDataService.batchUpdateCompleted(actInstId, nodeId);
- //设置会签的结果
- execution.setVariable("signResult_" + nodeId , signResult);
- //更新会签节点的状态。
- Short status=TaskOpinion.STATUS_PASSED;
- if(signResult.equals(SIGN_RESULT_REFUSE)){
- status=TaskOpinion.STATUS_NOT_PASSED;
- }
- //更新会签节点的状态。
- bpmProStatusDao.updStatus(actInstId, nodeId,status);
- //清除会签用户。
- taskUserAssignService.clearSignUser();
- }
- return isCompleted;
- }
- **
- * 根据会签规则计算投票结果。
- * <pre>
- .如果会签规则为空,那么需要所有的人同意通过会签,否则不通过。
- .否则按照规则计算投票结果。
- * </pre>
- * @param bpmNodeSign 会签规则
- * @param actInstId 流程实例ID
- * @param nodeId 节点id名称
- * @param completeCounter 循环次数
- * @param instanceOfNumbers 总的会签次数。
- * @return
- */
- private VoteResult calcResult(BpmNodeSign bpmNodeSign,String actInstId,String nodeId,Integer completeCounter,Integer instanceOfNumbers){
- VoteResult voteResult=new VoteResult();
- //没有会签实例
- ){
- return voteResult;
- }
- //投同意票数
- Integer agreeVotesCounts=taskSignDataService.getAgreeVoteCount(actInstId, nodeId);
- //没有设置会签规则
- //(那么得全部会签通过才通过,否则不通过)
- if(bpmNodeSign==null){
- //还没有完成可以退出。
- if(completeCounter<instanceOfNumbers){
- return voteResult;
- }
- else{
- //完成了 (全部同意才通过)
- if(agreeVotesCounts.equals(instanceOfNumbers)){
- return new VoteResult(SIGN_RESULT_PASS,true);
- }
- else{
- return new VoteResult(SIGN_RESULT_REFUSE,true);
- }
- }
- }
- //投反对票数
- Integer refuseVotesCounts=taskSignDataService.getRefuseVoteCount(actInstId, nodeId);
- //检查投票是否完成
- if(BpmNodeSign.VOTE_TYPE_PERCENT.equals(bpmNodeSign.getVoteType())){
- ;
- //按同意票数进行决定
- if(BpmNodeSign.DECIDE_TYPE_PASS.equals(bpmNodeSign.getDecideType())){
- percents=agreeVotesCounts/instanceOfNumbers;
- //投票同意票符合条件
- if(percents>=bpmNodeSign.getVoteAmount()){
- voteResult=new VoteResult(SIGN_RESULT_PASS, true);
- }
- //投票已经全部完成
- else if(completeCounter.equals(instanceOfNumbers)){
- voteResult=new VoteResult(SIGN_RESULT_REFUSE, true);
- }
- }
- //按反对票数进行决定
- else{
- percents=refuseVotesCounts/instanceOfNumbers;
- //投票
- if(percents>=bpmNodeSign.getVoteAmount()){
- voteResult=new VoteResult(SIGN_RESULT_REFUSE, true);
- }
- //投票已经全部完成
- else if(completeCounter.equals(instanceOfNumbers)){
- voteResult=new VoteResult(SIGN_RESULT_PASS, true);
- }
- }
- }
- //按绝对票数投票
- else{
- //按同意票数进行决定
- if(BpmNodeSign.DECIDE_TYPE_PASS.equals(bpmNodeSign.getDecideType())){
- //投票同意票符合条件
- if(agreeVotesCounts>=bpmNodeSign.getVoteAmount()){
- voteResult=new VoteResult(SIGN_RESULT_PASS, true);
- }
- //投票已经全部完成
- else if(completeCounter.equals(instanceOfNumbers)){
- voteResult=new VoteResult(SIGN_RESULT_REFUSE, true);
- }
- }
- //按反对票数进行决定
- else{
- //投票
- if(refuseVotesCounts>=bpmNodeSign.getVoteAmount()){
- voteResult=new VoteResult(SIGN_RESULT_REFUSE, true);
- }
- //投票已经全部完成
- else if(completeCounter.equals(instanceOfNumbers)){
- voteResult=new VoteResult(SIGN_RESULT_PASS, true);
- }
- }
- }
- return voteResult;
- }
Activiti 工作流会签开发设计思路的更多相关文章
- Activiti工作流引擎开发系列
Activiti工作流引擎开发系列-01 作者:Jesai 没有伞的孩子,只能光脚奔跑! 前言: 初次接触工作流这个概念是自从2014年11月份开始,当时是由于我的毕业设计需要,还记得当时我毕业设计的 ...
- IOS开发设计思路
我在做 iOS 开发的时候,发现自己在写程序的时候,常常处于两种状态的切换,我把这两种状态称为软件开发的上帝模式与农民模式.我先给大家介绍一下这两种模式的特点. 上帝模式 处于上帝模式时,我需要构思整 ...
- activiti工作流委托功能的设计和实现
最近公司开发一个项目,客户提出了一个需求,用户在出差的时候,可以将自己的工作进行委托.可以指定委托时间.委托工作内容.指定委托人等等内容. 然后我就上网查询资料,发现activiti工作流本身并不支持 ...
- Activiti工作流 安装myeclipse activiti设计插件并生成数据库表
从零开始学习Activiti工作流,记录下学习过程. 关于工作流的简介没什么好介绍了,只能说是个很有用的东西,数据库中23张表分别有什么用网上也有很详细的介绍,这里也不多加说明.activiti开发中 ...
- iOS开发:代码通用性以及其规范 第二篇(猜想iOS中实现TableView内部设计思路(附代码),以类似的思想实现一个通用的进度条)
在iOS开发中,经常是要用到UITableView的,我曾经思考过这样一个问题,为什么任何种类的model放到TableView和所需的cell里面,都可以正常显示?而我自己写的很多view却只是能放 ...
- java工作流快速开发之授权代办的设计
关键词:工作流快速开发平台 工作流流设计 业务流程管理 Java工作流引擎 asp.net 开源工作流 net开源工作流引擎 开源工作流系统 一.授权代办开发背景 应用需求:项目审批人出差无法及 ...
- IM开发基础知识补课(七):主流移动端账号登录方式的原理及设计思路
1.引言 在即时通讯网经常能看到各种高大上的高并发.分布式.高性能架构设计方面的文章,平时大家参加的众多开发者大会,主题也都是各种高大上的话题——什么5G啦.AI人工智能啦.什么阿里双11分分钟多少万 ...
- asp.net abp模块化开发之通用树2:设计思路及源码解析
一.前言 上一篇大概说了下abp通用树形模块如何使用,本篇主要分析下设计思路. 日常开发中会用到很多树状结构的数据,比如:产品的多级分类.省市区县,大多数系统也会用到类似“通用字典/数据字典”的功能, ...
- JSAAS的Activiti会签开发扩展处理
1.什么是会签? 在流程业务管理中,任务是通常都是由一个人去处理的,而多个人同时处理一个任务,这种任务我们称之为会签任务.这种业务需求很常见,如一个请款单,领导审批环节中,就需要多个部门领导签字.在流 ...
随机推荐
- HDU 3488--Tour(KM or 费用流)
因为每个点只能经过一次 所以考虑拆点 这题有坑,有重边.. KM算法 把一个点拆成入点和出点 入点在X部,出点在Y步. 如果u,v之间有路径,就在X部的u点连接Y部的v点 求完美匹配. 当完美匹配的时 ...
- poll()
# include < sys/ poll. h> int poll ( struct pollfd * fds, unsigned int nfds, int timeout) ; 和s ...
- hdu 5533 Dancing Stars on Me
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5533 Dancing Stars on Me Time Limit: 2000/1000 MS (Ja ...
- 转载ASP.NET MVC 中@Html.Partial,@Html.Action,@Html.RenderPartial,@Html.RenderAction区别
对这四个的区别做一个总结,清理一下思路,方便以后使用: 1.带有Render的方法返回值是void,在方法内部进行输出:不带的返回值类型为MvcHtmlString,所以只能这样使用: @Ht ...
- 关于UIImage类的对象两种初始化方法的区别
1.imageNamed: UIImage *image = [UIImage imageNamed:"]; UIImage的类方法 第一次读取图片的时候,先把这个图片放到缓存中,下次再使用 ...
- CSS构造模型
div 边距 边框 定位 浮动 21.1 div 部分(division)---<div>元素,经常以div形式引用---是XHTML元素,用于定义XHTML文件中的区域. 1.添加div ...
- 如何在64位系统上安装SQL Server 2000
如何在64位系统上安装SQL Server 2000? 现在用SQL Server 2000数据库的人少了吧?大都是SQL Server 2005/2008了.不过还是有需求的,今天一朋友就让我在他的 ...
- 剑指OFFER之顺时针打印矩阵(九度OJ1391)
题目描述: 输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,例如,如果输入如下矩阵: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 则依次打印出数字1,2 ...
- ABAP DEBUG
[Function] Command=/H Type=SystemCommand 将上面的文件推动到SAP 窗口 可以启动调试 ------------------------------------ ...
- cocos2d-x UserDefault
转自:http://blog.csdn.net/yanghuiliu/article/details/6912612 正在做项目中有很多游戏数据要保存,常见的玩家数据这些比较简单的可以用CCUserD ...