web工作流管理系统开发3640Word下载.docx
- 文档编号:1005439
- 上传时间:2023-04-30
- 格式:DOCX
- 页数:27
- 大小:235.19KB
web工作流管理系统开发3640Word下载.docx
《web工作流管理系统开发3640Word下载.docx》由会员分享,可在线阅读,更多相关《web工作流管理系统开发3640Word下载.docx(27页珍藏版)》请在冰点文库上搜索。
步骤所有者可以是一个具体的人,也可以是一个变量(当流程实例运行到此步骤之前,给这个变量赋值,到达的时候,能获取到变量的值,否则,步骤所有者就会是空)。
步骤的所有者只能是一个人,不会是一个对人员的分类(例如角色,用户组等)。
历史步骤的执行人:
和步骤执行人一样,步骤执行完成后,均成为历史步骤,每个历史步骤都一定会有一个步骤的执行人。
常常用变量mostRecentCaller来表示,并辅助一个前置函数,将指定历史步骤的执行人,保存到mostRecentCaller变量中。
mostRecentCaller是临时变量,注意要在流程的一次流转中,前面环节赋值,后面的环节才能获取到值。
注:
历史步骤的执行人,可用于当流程再次返回到此步骤后,仍然交给原来的步骤执行人再次执行,例如,谁填写的报销单审核不通过,打回给原来的填写人重新填写。
或者后面的步骤执行人需要是以前步骤的执行人。
历史步骤的执行人和历史步骤的所有者均可作此运用。
历史步骤的所有者:
首先要此步骤在流程建模的时候,动作结果导向此步骤后,设置了此步骤的所有者。
当这个步骤成为历史步骤后,获取此步骤的的所有者,就是历史步骤的所有者。
常常用mostRecentOwner变量来表示,和mostRecentCaller一样,是临时变量,需要在流程的一次流转中,前面的环节利用前置函数给mostRecentOwner变量赋值,后面的环节才能获取到此值。
和mostRecentCaller的区别是,每个历史步骤,不一定会有历史步骤的所有者(需要设置了才会有),mostRecentCaller是一定会有的。
当前执行者:
就是执行流程的操作人。
在流程建模的时候,可以用caller变量来表示,caller变量也是临时变量,在流程的一次流转前面环节给caller变量赋值,后面的环节就可以获取caller变量的值来使用。
给caller变量赋值,用将当前执行者保存到变量caller
这个前置函数。
动作的执行人:
就是当前步骤的当前可执行动作的执行人。
动作是否可执行,有条件可以设置,当流程实例在运行时,当前执行者符合当前步骤的当前动作的条件,此动作就是当前可执行的动作。
动作的条件,可以是限制人,也可以是业务规则的限制。
动作的可执行人:
当流程建模时,动作的条件设置,是一个人,或者是一个角色等,那么这个人,或者是有这个角色的所有人都是此动作的可执行人。
任务的创建人:
当流程实例运转的时候,会根据节点的设置产生任务记录,谁执行的流程,产生的任务记录,任务的创建人就是谁。
任务的分配人:
在eworkflow工作流软件中,任务的分配人通常就是指任务的创建人。
任务的参与人:
顾名思义,就是可以看到此任务并参与执行任务的人。
在eworkflow工作流软件中,任务的参与人,不一定就是任务的最后完成人。
任务的签收人:
这是针对竞争型任务设置的,当产生竞争型任务时,谁先签收了此任务,谁就是任务的签收人,其它人就不能再执行此任务了。
任务工单的执行人:
在工作流软件中,一条任务信息,可能会产生多个任务工单。
任务工单的完成人:
谁完成的任务工单,谁就是任务工单的完成人。
一条任务工单,只会有一个完成人。
任务的完成人:
因为任务会产生多条派发的工单,所以任务工单的完成人,也就是任务的完成人(任务的完成人可能是多个)。
任务的抄送人
抄送给某些用户,任务的抄送人只能查看任务,不能执行任务。
....
随着工作流软件系统的不断升级,工作流软件的那些人,还会继续的添加......
三十七自由流的实现(续)
工作流系统的自由流实现了不按照流程预定义的轨迹流转,即需要在节点之间任意的跳转。
上一篇自由流的实现主要说明了跳转规律,如果是单节点间的跳转,只要有当前的节点,以及跳转到的节点,就ok了。
但是当当前节点和任意跳转到的节点之间有分支并发线路后,就不是简单的跳转了,当分支套分支,分支主干等之间的跳转就更复杂了。
如果是这种串行路由,就很简单了。
但是这样的多路分支,分支嵌套分支的,就很复杂了。
因此在实现的时候,必需找出,当前节点到跳转到的节点之间的轨迹线路。
又因为分支之间是可以嵌套的,所以必需用递归来遍历这之间的轨迹。
由当前节点开始,查找这个节点的动作结果节点是否为跳转到的节点,如果是,则找到之间的轨迹,返回。
如果不是,则将当前这个节点的动作结果节点作为当前节点,继续调用这个函数,查找,直到找到后退出。
因为流程定义的轨迹,可以是循环的轨迹,即一个节点的动作结果可以返回到前面的节点,如:
当返回到前面的节点时,用递归调用的话,就永远也退不出循环了。
因此,将处理过的节点放到traceNodeList中,每次调用递归函数前,均判断一下,此节点是否在traceNodeList中,如果在,就不用处理了。
不在的继续处理。
eworkflow自定义工作流系统有.net版和java版,两个版本的实现过程完全一样,只是一个是c#语言的一个是java语言的。
c#的递归函数:
privateArrayListgetJoinsAndSplitsBwteenStep(WorkflowDescriptorwd,IDictionaryorgNodeMap,ResultDescriptortheResult,ArrayListtraceNodeList)
{
ArrayListtagList=newArrayList();
stringnodeType=(System.String)orgNodeMap["
node_type"
];
AbstractDescriptornode=(AbstractDescriptor)orgNodeMap["
node"
ArrayListresults=newArrayList();
if(nodeType.Equals("
join"
))
JoinDescriptorjoin=(JoinDescriptor)node;
results.Add(join.Result);
}
split"
{
SplitDescriptorsplit=(SplitDescriptor)node;
results.AddRange(split.Results);
subflow"
SubflowDescriptorsubflow=(SubflowDescriptor)node;
results.Add(subflow.unconditionalResult);
results.AddRange(subflow.conditionalResults);
step"
StepDescriptorstep=(StepDescriptor)node;
ArrayListactions=step.actions;
for(IEnumeratoriter=actions.GetEnumerator();
iter.MoveNext();
)
ActionDescriptoraction=(ActionDescriptor)iter.Current;
ResultDescriptorresult=action.UnconditionalResult;
results.Add(result);
results.AddRange(action.ConditionalResults);
}
boolbFind=false;
for(IEnumeratorit=results.GetEnumerator();
it.MoveNext();
ResultDescriptorresult=(ResultDescriptor)it.Current;
if(result.Id==theResult.Id)
{//找到跳转到的节点,退出
bFind=true;
break;
if(bFind)returntagList;
//将当前处理节点存入traceNodeList中
traceNodeList.Add(node);
for(IEnumeratoriterator=results.GetEnumerator();
iterator.MoveNext();
ResultDescriptorresultDesc=(ResultDescriptor)iterator.Current;
intjoinid=resultDesc.join;
intsplitid=resultDesc.Split;
intstepid=resultDesc.Step;
intsubflowid=resultDesc.subflow;
inttraceid=0;
IDictionaryorgMap=newHashtable();
//记录节点信息
if(joinid>
0)
IDictionarym=newHashtable();
m["
]=joinid;
//newInteger(joinid);
tagList.Add(m);
JoinDescriptorjoin=wd.getJoin(joinid);
orgMap["
]="
;
]=join;
traceid=joinid;
if(splitid>
SplitDescriptorsplit=wd.getSplit(splitid);
]=split;
]=splitid;
//newInteger(splitid));
for(inti=0;
i<
split.Results.Count;
i++)
traceid=splitid;
if(stepid>
StepDescriptorstep=wd.getStep(stepid);
]=step;
traceid=stepid;
if(subflowid>
SubflowDescriptorsubflow=wd.getSubflow(subflowid);
]=subflow;
traceid=subflowid;
//判断关联到的节点是否处理过
boolinTrace=false;
for(IEnumeratoritrace=traceNodeList.GetEnumerator();
itrace.MoveNext();
AbstractDescriptortrace=(AbstractDescriptor)itrace.Current;
if(trace.Id==traceid)
{//已经处理过的了
inTrace=true;
if(!
inTrace)
tagList.AddRange(getJoinsAndSplitsBwteenStep(wd,orgMap,theResult,traceNodeList));
returntagList;
java的递归函数:
privateListgetJoinsAndSplitsBwteenStep(WorkflowDescriptorwd,MaporgNodeMap,ResultDescriptortheResult,ListtraceNodeList)throwsWorkflowException{
ListtagList=newArrayList();
StringnodeType=(String)orgNodeMap.get("
);
AbstractDescriptornode=(AbstractDescriptor)orgNodeMap.get("
Listresults=newArrayList();
if(nodeType.equals("
)){
results.add(join.getResult());
results.addAll(split.getResults());
results.add(subflow.getUnconditionalResult());
results.addAll(subflow.getConditionalResults());
Listactions=step.getActions();
for(Iteratoriter=actions.iterator();
iter.hasNext();
){
ActionDescriptoraction=(ActionDescriptor)iter.next();
ResultDescriptorresult=action.getUnconditionalResult();
results.add(result);
results.addAll(action.getConditionalResults());
booleanbFind=false;
for(Iteratorit=results.iterator();
it.hasNext();
ResultDescriptorresult=(ResultDescriptor)it.next();
if(result.getId()==theResult.getId()){//找到跳转到的节点,退出
//returntagList;
traceNodeList.add(node);
for(Iteratoriterator=results.iterator();
iterator.hasNext();
ResultDescriptorresultDesc=(ResultDescriptor)iterator.next();
intjoinid=resultDesc.getJoin();
intsplitid=resultDesc.getSplit();
intstepid=resultDesc.getStep();
intsubflowid=resultDesc.getSubflow();
MaporgMap=newHashMap();
0){
Mapm=newHashMap();
m.put("
newInteger(joinid));
tagList.add(m);
orgMap.put("
"
join);
split);
newInteger(splitid));
//tagList.add(m);
split.getResults().size();
i++){
step);
SubflowDescriptor
subflow=wd.getSubflow(subflowid);
subflow);
booleaninTrace=false;
for(Iteratoritrace=traceNodeList.iterator();
itrace.hasNext();
AbstractDescriptortrace=(AbstractDescriptor)itrace.next();
if(trace.getId()==traceid){//已经处理过的了
tagList.addAll(getJoinsAndSplitsBwteenStep(wd,orgMap,theResult,traceNodeList));
}
三十八工作流软件中的定时器处理
工作流软件中的定时器处理,一般分为两种:
应用服务启动就启动的定时器
这种类型和通常的web系统
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- web 工作流 管理 系统 开发 3640