UCML工作流系统与现有应用系统集成

更新时间:2024-04-18 00:13:01 阅读量: 综合文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

The best solution for

how to develop WEB application on .Net quickly and efficiently

UCML工作流系统与现有应用系统

集成实现方案说明

金富瑞(北京)科技有限公司

Goldframe Technologies Co., Ltd.

一 总体说明

UCML.Net工作流系统是国内领先的工作流平台,涵盖了从流程开发、发布、管理配置到运行、监控的整个过程。UCML工作流系统主要包括可视化的流程设计环境、独立的工作流引擎服务、WEB客户端管理、可视化的流程监控、流程套路生产线几个部分,是.Net领域用户最多,覆盖面最广的工作流平台。

一方面,UCML工作流系统与UCML平台其它部分(业务单元开发,Web报表)无缝集成,可以完成复杂的业务处理及流程流转;另一方面,UCML工作流系统与业务之间采用松耦合设计,不仅可以与UCML业务系统集成,还可以与其它现成的应用系统实现无缝集成。

UCML工作流在与其它应用系统集成时,一般有两种方式: 第一种:保留UCML现有的组织机构、用户及权限体系

第二种:完全屏蔽UCML提供的组织机构、用户及权限体系,完全采用客户原有的组织机构权限体系。

对于第一种方式,需要另外实现UCML系统与客户现有应用系统之间的数据同步,具体方法可采用程序同步方式,在这里就不详细介绍了。

下面主要介绍一下采用第二种方式时的处理方法。

二 UCML Workflow会话编程接口

UCML Workflow 提供了WorkFlow.WorkFlowSession会话类来访问工作流引擎, WorkFlow.WorkFlowSession以.Net Remoting服务形式形式存在于工作流引擎的独立进程中,客户端可以创建WorkFlow.WorkFlowSession的Client端来来调用服务端的接口。

? 创建工作流会话对象

WorkFlow.WorkFlowSession

FlowSession

=

(WorkFlow.WorkFlowSession)Activator.GetObject(typeof(WorkFlow.WorkFlowSession), \EnginePort+\

? 程序启动工作流程

public Guid CreateInstance(string FlowID,Object UserOID,Object PostnOID, Object DivisionOID,Object ORGOID, bool startNow)

通过调用CreateInstance函数,可以启动指定的工流程。

返回值:流程实例句柄。

参数名称 FlowID UserOID PostnOID DivisionOID ORGOID startNow

类型 string Object Object Object Object Bool

参数说明

要启动的流程编号

起动流程的用户OID,实际类型为GUID 起动流程的员工OID,实际类型为GUID

起动流程的员工所在部门的OID,实际类型为GUID 起动流程的员工所在组织的OID,实际类型为GUID ==true 流程是马上启动; ==false 流程暂不启动,要启动流程需调用StartInstance函数,这种情况一般用于在业务(如客户订单)提交成功后,先写入订单号到流程实例中,然后在启动流程。

? 向流程全局数据写入数据

public void WriteFlowData(string FlowID, Object InstanceID, string FieldName,Object

Value)

参数名称 FlowID InstanceID FieldName Value

类型 string Object string Object

参数说明

数据项所属的流程编号 流程的实例句柄,实际类型为GUID 数据的属性名称 数据的属性的值

? 从流程全局数据读出数据

public Object ReadFlowData(string FlowID, Guid InstanceID, string FieldName)

返回值:读取数据属性的值

参数名称 FlowID InstanceID FieldName

类型 string Object string

参数说明

数据项所属的流程编号 流程的实例句柄,实际类型为GUID 数据的属性名称

? 向流程局部数据写入数据

public void WriteActivityData(string FlowID, Guid InstanceID,string ActivityID, string FieldName,Object Value)

参数名称 FlowID InstanceID ActivityID FieldName Value

类型 string Object string string Object

参数说明

数据项所属的流程编号 流程的实例句柄,实际类型为GUID 活动节点的编号 数据的属性名称 数据的属性的值

? 从流程局部数据读出数据

public Object ReadActivityData(string FlowID, Guid InstanceID,string ActivityID, string FieldName)

返回值:读取数据属性的值 参数名称 FlowID InstanceID ActivityID FieldName

类型 string Object string string

参数说明

数据项所属的流程编号 流程的实例句柄,实际类型为GUID 活动节点的编号 数据的属性名称

? 完成已分配的任务

public string FinishTask(string strAssignTaskID) FinishTask代表设置已分配出去的任务已完成 返回值:提示信息

参数名称 strAssignTaskID

类型 string

参数说明

分配任务的唯一标志号

? 设置任务结果及状态

public void SetTaskResolution(Guid TaskID,TTaskResolution Resolution)

设置任务执行结果,代表任务执行完毕

参数名称 类型 参数说明

TaskID Resolution

Guid

任务的Key值

TtaskResolution 任务的状态{UNRESOLVED,SUCCESS,FAIL,EXCEPTION} 含

义分别为{未处理,成功,失败,异常}

? 编写节点分支条件

UCML Workflow用abstract public class Transition类来描述一个分支条件

类属性名称 类型 可见度 属性说明

TransResult

Boolean

protected

TransResult==true 则代表流程分支条成立

TransResult==false 则代表流程分支条不成成立

FromActivity

WorkFlowActivity

public

分支来源节点对象实例

ToActivity FlowModel

WorkFlowActivity WorkFlowModel的子类

public public

分支目标节点对象实例

其实是流程模型的实例对象,通过它可以访问流程所有属性(或状态)数据

方法名称

类型

可见度 public

方法说明

virtual public bool OutgoingCondition()

在UCML Workflow里,节点的一条流出分支是否成立完全取决于这个函数,编程人员员可以它的子类里编写它的具体实现代码,在编写代码时可以结合流程的状态数据。在这函数中一定要设置TransResult的值,也就是说如果TransResult==true 分支成,否则分支不成立,也就不走这条分支。

IncomingCondition

bool

public

virtual public bool IncomingCondition()

OutgoingCondition() bool

OutgoingCondition()这函数是在Transition的子类中已覆盖函数形式实现,在UCML环境里的流出条件编辑,就是实现此函数。如下图示:

? 9. 编程实现智能任务分配

wm_assign()-UCML Workflow提供回调函数,为开发者提供完成复杂分配的可能,详见回调函数接口

? 10. 终止流程

方法名称 Abort ()

类型 void

可见度 public

方法说明

public void Abort(string FlowID, Guid InstanceID) 终止某个流程实例

? 9. 挂起流程

方法名称 Pause ()

类型 void

可见度 public

方法说明

public virtual void Pause() 暂时挂起一个流程

? 10. 唤醒流程

方法名称 Resume ()

类型 void

可见度 public

方法说明

public void Resume(string FlowID, Guid InstanceID) 重新运转流程

? 11. 节点手动跳转

方法名称 GotoActivity ()

类型 void

可见度 public

方法说明

public void GotoActivity(string FlowID, Guid InstanceID,string FromActivityID,string

ToActivityID,string Performers) 作用 : 流程跳转 FlowID:流程ID

InstanceID:流程实例句柄 FromActivityID:来源活动名称 ToActivityID:目标活动名称 Performers:执行人的群组串.

? 回退任务

///

/// 回退任务 ///

/// public void Rollback(Guid TaskID)

? 回收任务

///

/// 收回任务 ///

///

? 获取某个活动节点执行人

///

/// 获取某个活动节点执行人 ///

/// ///

public string GetActivityPerformer( string ActivityID)

? 获取当前节点即将流向的目标节点,如果是并发输出将会多个流向。用于在当前节点完成时,马上选择下一节点执行人

///

/// 获取当前节点即将流向的目标节点,如果是并发输出将会多个流向 /// 用于在当前节点完成时,马上选择下一节点执行人 ///

/// /// /// /// 返回要输出的节点ID数组

public string[] GetOutgoingActivitys(string FlowID, Guid InstanceID, string ActivityID)

? 获取节点状态

///

/// 获取节点状态 ///

///

public int GetActivityStatus(string FlowID, Object InstanceID, string ActivityID)

? 修改节点状态

///

/// 修改节点状态 ///

///

public void ChangeActivityStatus(string FlowID, Object InstanceID, string ActivityID, int ActivityStatus)

? 不结束当前节点,而激活下一节点

///

/// 不结束当前节点,而激活下一节点 ///

///

///

/// ///

///

public void GotoActivityNotFinishTask(string FlowID, Guid InstanceID, string FromActivityID, string ToActivityID, string Performers)

? 完成已分配的任务,但不流转

///

/// 完成已分配的任务,但不流转 ///

/// ///

public string FinishTaskNotRun(WorkFlowActivity Activity)

? 加签或者转签

///

/// 加签或者转签 ///

/// ///

///

/// ///

///

/// ///

/// ///

public void AddSignPerformer(string FlowID, Guid InstanceID, Guid AssignTaskOID, Guid CurrentUserOID, string SignPerformers, bool fSignOneByeOne, bool InsertBefore, bool IsDeleteSigner,

int MessageType,string MessageContent)

? 协办或会签

///

/// 协办或会签 ///

/// ///

///

/// /// /// /// ///

public void AssignSignPerformer(string FlowID, Guid InstanceID, Guid AssignTaskOID, Guid CurrentUserOID, string SignPerformers,int MessageType, string MessageContent,int TaskKind)

? 手工正常分配任务

///

/// 手工正常分配任务 ///

///

///

public void MansualAssignTask(string TaskTicketOID,string Performer)

? 分配参阅任务

///

/// 分配参阅任务 ///

///

public void MansualAssignReadTask(string TaskTicketOID,string Performer)

? 悔签任务,对在任务分配表AssignTask中acceptFlag置为1的标记设为4悔签

悔签

///

/// 悔签任务,对在任务分配表AssignTask中acceptFlag置为1的标记设为4///

///

public void RepentSignforTask(string assignTaskID)

? 任务跳回到执行人

///

/// 任务跳回到执行人 ///

///

/// ///

public void TaskReturn(string FlowID, Guid InstanceID, string ActivityID)

? 获取某个已完成节点的执行人

///

/// 获取某个已完成节点的执行人 ///

///

/// /// /// 返回执行人OID数组

public Guid[] GetExecuteUser(string FlowID, Guid InstanceID, string ActivityID)

? 唤醒已完成的任务

///

/// 唤醒已完成的任务 ///

///

public void WakeFinishedAssignTask(string AssignTaskOID)

? 12. 任务超时处理及编程

UCML Workflow 的是否超时由下图的完成期限和延长时间两个属性决定:

?

当完成期限不填内容时,代表这个活动节点产生的任务没有时间限制 延长时间代表完成期限倒了之后,还可以再延长多少时间

? 即将超时处理

当完成期限到了之后,会回调wm_willtimeout函数,如果想在此时放个邮件通知或短信,就可在wm_willtimeout函数内调用。

? 超时处理

同样的当完成期限到了之后,如果有延长时间,而且延长时间也到了,会回调wm_deadline函数,如果想在此时放个邮件通知或者短信,就可在wm_deadline函数内调用。如下图示:

?

如果任务在截止期限和延长时间内都没有完成,此时任务做超时处理,流程是继续流转还是停止由截止期限到达时系统行为这个属性决定,如为SYNCHR(同步),则流程停在这里,如果为ASYNCHR(异步) 则流程继续流转。

三 UCML工作流开放性介绍

UCML 引擎底层框架的基类源码不开放,包括引擎调度代码和流程类、活动类和分支类基类代码。而根据定义可以直接生成引擎源码都是开放的,可以在这些源码的框架扩展时刻(回调函数)之内注入C#代码来进行,如下面活动节点代码的时刻函数

任务分配时刻函数

override public void wm_assign(Object taskTicketID,Object[] UserList,ref Object[] AssignUserList,ref int[] TaskKindList,Boolean reassignFlag) { }

任务分配后时刻函数

override public void wm_afterAssignTask(Object assignTaskID,Object UserOID) {

base.wm_afterAssignTask(assignTaskID,UserOID); }

任务分配前时刻函数

override public void wm_beforeAssignTask(SysDBModel.AssignTaskInfo AssignTaskInfo) { }

任务完成时刻函数

override public void wm_afterTaskFinish(Object taskTicketID,TTaskResolution TaskResolution) { }

任务超时时刻函数

override public void wm_deadline(Object taskTicketID) { }

任务完成规则函数

override public bool wm_finishTaskRule(SysDBModel.TaskTicketInfo taskTicketInfo) {

return false; }

任务创建函数

override public void wm_createTask(SysDBModel.TaskTicketInfo taskTicketInfo) { }

任务回滚前函数

override public void wm_beforerollback(Object taskTicketID) { }

任务回滚后函数

override public void wm_afterrollback(Object taskTicketID) { }

override public void wm_onactivate() { }

override public void wm_willtimeout(SysDBModel.TaskTicketInfo taskTicketInfo) { }

override public bool wm_activityInComeCondi() {

return false; }

} }

四 集成方案

在采用客户已有的人员权限体系时,主要用到UCML工作流系统的可视化流程设计环境、工作流引擎服务、工作流标准表结构、流程API、可视化的流程监控(可选)等。 在集成时可能需要修改客户已有的Web系统或表的结构,主要是修改以下地方: ? 修改人员信息表

? 引入流程接口(UCML工作流API) ? 客户登陆会话的改变

? 加入工作流引擎需要的初始化程序 ? 增加一个待办事宜模块

? 引入平台中的可视化的流程监控模块(如果需要可视化流程监控那么就需要引入) 在平台中主要有以下注意点: ? 在平台中设计工作流模型

? 添加流程状态数据

? 在任务分配函数-wm_assign()中设置任务的执行人 ? 修改人工节点上的业务标识符为为自己的页面

1、 ?修改人员信息表

需要在客户现有的用户表(存储登录帐号、密码表)中增加一个Guid类型的字段,这个字段的值唯一标记一个用户,不影响客户现有的应用体系,起到与UCML工作流衔接作用。

这个字段的字段名命名规范为:客户表名+OID,即“客户表名OID”,字段类型为GUID类型,在MSSQL Server中是Uniqueidentifier,Oracle中为VARCHAR类型。 在客户业务系统中客户的登录ID代表客户的身份,如果整合中客户表中有现存的数据需要手工给“客户表名OID”赋值;另外,在增加用户的程序中要同时给“客户表名OID”赋值。

2、 ?引入流程接口(UCML工作流API)

? 在客户现有系统的工程文件中引入UCML工作流API,并引用一个专门为第三方业

务开发包装的接口源程序WorkflowClient.cs。

? 相关工作流API:DBLayer.dll,SysDBModel.dll,UCMLBase.dll,WorkFlow.dll ? 把Workflow\\bin 目录下的UCMLConf.xml,DBLayer.xml文件拷贝到客户工程的bin

目录下,注意:如果不是在客户工程的本机运行工作流引擎,则需要把UCMLConf.xml文件中引用工作流引擎地址的IP改为运行工作流引擎主机的IP地址。

3、 ?客户登陆会话的改变

在用户登陆的程序中,在取得用户表中各项数据时,把用户表中新增的字段也读出来,并把该项也放入用户登陆会话中。

4、 ?加入工作流引擎需要的初始化程序

在使用客户的应用程序中与工作流引擎打交道之前的任意时刻加入如下程序: UCMLCommon.UCMLInitEnv.fInServer=true; UCMLCommon.UCMLInitEnv.LoadEnvVariable(); new DBLayer.LogicDBModel();

UCMLCommon.UCMLLogicDBModelApp x = new UCMLCommon.UCMLLogicDBModelApp(); x.PrepareModel();

5、 ?增加一个待办事宜模块

待办事宜也叫待办任务。

需要客户自己新增一个待办事宜模块,其数据来源是UCML提供的任务分配表AssignTask,开发者可根据记录(任务)的完成与否状态过滤数据到待办任务模块内。

6、 ?引入平台中的可视化的流程监控模块(如果需要可视化流程监控那么就需要引入)

可视化流程监控的页面在平台中的业务模块是:BPO_FlowTrace 可以将BPO_FlowTrace相关文件拷贝到项目下: BPO_FlowTrace.aspx BPO_FlowTrace.aspx.cs BPO_FlowTrace.asmx BPO_FlowTrace.asmx.cs BPO_FlowTrace.htc

7、 ?在平台中设计工作流模型

在平台中设计工作流模型,可以参考“工作流设计手册”。

8、 ?添加流程状态数据

UCML工作流引擎和业务之间是松耦合处理模式,工作流和业务之间是通过流程状态数据进行交互。

流程状态数据是指工作流在运转过程中流程流转所需要的保存在流程实例中的数据,一般有三类业务数据要保存在流程中,一是业务单据的关键字段,用它可以决定一个任务对应的业务单据号,在UCML里一般把表单主键存到流程里;二是决定流程分支走向的数据,有可能是领导意见,也有可能是单据金额,这些数据是为了工作流引擎内部调用的;三是流程执行人信息。

流程和业务之间的状态数据交互方法很简单,如下所示:

写入流程状态数据:即把业务的数据写入到流程中去,调用的方法是WriteFlowData;

读出流程状态数据:即把流程状态读出来赋给业务,调用的方法是ReadFlowData。 写入流程状态数据一般在数据提交时进行,读出流程状态数据一般在初始化时进行,读时可以把流程状态数据赋给业务中的某个属性,以方便业务中调用。

9、 在任务分配函数-wm_assign()中设置任务的执行人

在工作流中任务分配的方式有几种: 通过群组配置分配任务 回调函数分配任务 手工执行执行人

由于组织机构等均不采用平台自带的组织框架,所以无法采用“通过群组配置分配任务”的方式,只能采用“回调函数分配任务”或

10、 自己实现执行人群组解析接口,可以继续使用基于配置的任务分配

基于流程模型的执行人配置可以避免在wm_assign里写程序做任务分配,但必须必需特定某个组织机构,在这个组织机构基础之上可以定义群组,来描述人员、部门和岗位集合,也可以定义相对执行人如申请人的部门主管、申请人公司总经理等,只要实现自己的群组解析接口,就可以自己的群组串配置UCML的工作流执行人的字段里,就可以实现基于配置的任务分配实现步骤如下:

? 自定义类实现如下接口

public interface IGroupParser {

Object[] UserOIDList(string GroupStr, Object Starter, Object StartPostn, Object StartDivision, Object StartORG,

Object Performer, Object PerformerPostn, Object PerformerDivision, Object PerformerORG);

Object[] UserOIDList(string GroupStr); }

///

///

/// ///

/// 根据组定义获取用户列表

///

/// /// ///

/// /// ///

/// 返回GUID类型的用户ID

? 在UCMLCONF.XML文件里添加如下节点:

true

dll名称 类名称

11、 12、

修改人工节点上的业务标识符为为自己的页面 工作流计算工作日客户自定义接口

1. 自定义类实现如下接口

public interface IWorkDay {

///

/// 计算任务完成期限,用于扩展节假日等非工作日的完成时间的计算 ///

///

/// /// /// 返回任务最终完成时间

DateTime GetLimitDateTime(DateTime startTime, long delayTime, Guid UserOID); }

2. 在UCMLCONF.XML文件里添加如下节点:

< fCustomWorkDay>true

< WorkDayAssembly>dll名称 < WorkDayClass>类名称

13、

///

/// 流程切面时刻 ///

public interface IWorkFlowRuntime {

///

/// 流程创建时刻 ///

///

工作流时刻切面接口

1. 自定义类实现如下接口

///

void OnCreateInstance(WorkFlowModel FlowInstance, DateTime CreateTime); ///

/// 流程完成时刻 ///

///

void OnFinishInstance(WorkFlowModel FlowInstance, DateTime EndTime); ///

/// 流程终止时刻 ///

///

void OnAbortInstance(WorkFlowModel FlowInstance, DateTime AbortTime); }

///

/// 活动节点切面接口时刻 ///

public interface IActivityRunTime {

///

/// 任务创建时刻 ///

///

void OnCreateTask(WorkFlowModel FlowInstance, WorkFlowActivity Activity, DateTime CreateTime);

///

/// 完成任务分配时刻 ///

///

void OnFinishAssignTask(WorkFlowModel FlowInstance, WorkFlowActivity Activity, DateTime FinishTime); ///

/// 完成整个任务时刻 ///

///

void OnFinishTask(WorkFlowModel FlowInstance, WorkFlowActivity Activity, DateTime FinishTime);

}

本文来源:https://www.bwwdw.com/article/koip.html

Top