Ccflow的SDK开发模式,主要是用于一些页面交互性较强而且现有的表单设计模式无法满足的情况下,或者二次开发时使用的模式。在新版本发布之后,前后端分离,将会取消很多服务器控件,使用js和css代替,所以,开发者需要对代码掌握度较高,而且拥有较多的ccflow使用经验才可以。
SDK流程的优点:
1. 流程表单页面交互性强。
2. 表单样式可以随意控制,自由性较高。
3. 更贴近(用户)表单需求(特定情况下)
4. 有助于优化用户体验
5. 给开发者最大的开发的发挥空间,包括数据源同步、多数据库数据交互等等。
SDK流程的缺点:
1. 代码开发量(工作量)较大。
2. 必须遵守ccflow的流程流转规则
3. Ccflow中的有些功能无法使用。主要与数据存储的空间有关。
4. 开发时考虑的因素较多,比如退回信息如何显示、明细表如何同步等等。
开发教程:
第一步:创建流程。如下图:
第二步:设置节点访问规则与节点处理人。本步骤可以省略,即不设置规则与处理人,在执行流程send的时候,调用相关的接口也可以发送出去。
相关的流程发送接口:
1. WorkNode firstwn=newWorkNode(long.Parse(this.WorkID)),int.Parse(this.FK_Node);
Msg= firstwn.NodeSend().ToMsgOfHtml();
2. BP.WF.Dev2Interface.Node_SendWork();
代码位于类库:BP.WF/ Dev2Interface.CS
第三步:开发流程页面。
页面开发中,表单内容与样式自己控制。但是顶部流程控制按钮需要调用或者自己编写代码。
除发送、保存按钮之外,其他的都存在可调用的页面,可直接调用。
可直接调用的按钮功能页面如下:(如何这些页面样式不符合,也可以自己重做)
公文按钮:
function OpenWord() {
varurl="../../WF/WorkOpt/WebOffice.aspx?FK_Node="+ FK_Node + "&FID=" + FID + "&WorkID=" + WorkID + "&FK_Flow=" + FK_Flow + "";
WinOpenNew(url,"正y文?");
}
轨迹按钮:
function OpenTrack(){
varurl="../../WF/WorkOpt/OneWork/ChartTrack.aspx?WorkID="+ this.WorkID + "&FK_Flow="+ this.FK_Flow + "&FID="+ this.FID + "&FK_Node="+ this.FK_Node + "";
WinOpenNew(url,"轨¨¬迹¡ê");
}
其他的请参考/WF/UC/MyFlow.ascx.cs中的InitToolbar()方法。此处不一一列举,只将demo中的使用到的贴出来。
第四步:创建实体类。
创建实例主要用于流程表单数据的存储。
本步骤也可以跳过,主要根据个人存储数据的位置而定。如果想将流程数据存储与NDXX系统自带的库中,则必须创建。例如:
扩展字段,就是SDK表单中存储数据的字段。具体实例创建方法,请参考我们提供的SDK开发demo中的实例创建方法。
如果不使用ccflow系统提供的NDXX表存储数据,也可以创建实例。此demo中就创建了一个与NDXX无关的表的实例,主要是因为实例封装、继承了一些方法,免去了许多增删改查操作。如果不创建实例,则需要自己通过sql语句进行操作。下面为此demo中的实例:
第五步:编写SDK表单数据存储代码
此处不讲解前后台数据交互,每个人的习惯、喜好不一样,我比较喜欢使用ajax与一般处理程序文件进行前后台数据交互。
数据存储部分:
GongWenGuiDang gwd = new GongWenGuiDang();
gwd.OID = int.Parse(this.WorkID);
//标题
gwd.Title = this.MyContext.Request.QueryString["Title"].ToString();
//文号
gwd.WenHao = this.MyContext.Request.QueryString["WenHao"].ToString();
//部门名称
gwd.DeptName = this.MyContext.Request.QueryString["DeptName"].ToString();
//公文类型¨
gwd.GWType = this.MyContext.Request.QueryString["GWType"].ToString();
//发布时间
gwd.FBRDT = this.MyContext.Request.QueryString["FBTime"].ToString();
//自定义类别
gwd.GWLieBie = this.MyContext.Request.QueryString["LeiBie"].ToString();
//摘要
gwd.ZhaiYao = this.MyContext.Request.QueryString["ZhaiYao"].ToString();
//关键字
gwd.GuanJianZi = this.MyContext.Request.QueryString["GuanJianZi"].ToString();
//是否归档
gwd.IsGuiDang = this.MyContext.Request.QueryString["GuiDang"].ToString();
if(gwd.IsExits == false)
gwd.InsertAsOID(int.Parse(this.WorkID));/*如果已经不存在.*/
else
gwd.Update();
其他部分:如果有其他与保存相关的事件,也可以写在这
//获取流程实例
FlowcurrFlow = new Flow(this.FK_Flow);
//获取节点实例
NodecurrND = new Node(this.FK_Node);
//如果是开始节点
if(currND.IsStartNode == true)
{
if(currFlow.DraftRole != DraftRole.None)
{
//设置流程标题
string title = this.MyContext.Request.QueryString["Title"].ToString();
BP.WF.Dev2Interface.Flow_SetFlowTitle(this.FK_Flow, long.Parse(this.WorkID), title);
//将草稿保存到待办
if (currFlow.DraftRole == DraftRole.SaveToTodolist)//如果是开始节点并且是保存事件
BP.WF.Dev2Interface.Node_SaveEmpWorks(this.FK_Flow, title, this.WorkID.ToString(),WebUser.No);
}
}
第六步:编写发送方法
在执行发送之前,必须执行一次保存操作。如果没有点击保存,表单数据将不会写入数据库。
由于此流程,我已经设置了规则与处理人,所以直接调用不需要参数的方法(WORKID,FK_FLOW,FK_NODE,FID是ccflow的四大必要参数,当然,与发送接口相关的参数还有 到达节点、处理人、接收人等等。)
流程所需要的基本参数,在流程页面打开时,就已经传递过去,自己可以获取。
FK_Flow=017&FK_Node=1701&WORKID=1793&CWorkID=0&NodeID=1701&FID=0&UserNo=zhangsan&SID=hgp5isirspihkk4hp03n5nyt
try
{
msg ="suess#"+firstwn.NodeSend().ToMsgOfHtml();
stringtitle = this.MyContext.Request.QueryString["Title"].ToString();
BP.WF.Dev2Interface.Flow_SetFlowTitle(this.FK_Flow, long.Parse(this.WorkID), title);
}
catch(Exception exSend)
{
if(exSend.Message.Contains("请选择下一步骤¨工作") == true)
{
msg = "url#../../WF/WorkOpt/ToNodes.aspx?FK_Flow="+ this.FK_Flow + "&FK_Node="+ this.FK_Node + "&WorkID="+ this.WorkID + "&FID="+ this.FID + "&AuthorEmp="+ this.MyContext.Request.QueryString["AuthorEmp"] + "";
returnmsg;
}
if(exSend.Message.Contains("用户没有选择发送到的节点") == true ||exSend.Message.Contains("设置方向条件") == true)
{
msg = "url#../../WF/WorkOpt/ToNodes.aspx?FK_Flow="+ this.FK_Flow + "&FK_Node="+ this.FK_Node + "&WorkID="+ this.WorkID + "&FID="+ this.FID + "&AuthorEmp="+ this.MyContext.Request.QueryString["AuthorEmp"] + "";
returnmsg;
}
msg = "err#"+exSend.Message.ToString();
}
发送时有发送前、发送后、发送成功时、发送失败时等等事件,都可以添加逻辑代码。
发送成功后,数据都保存到了数据库中,怎么在下一步骤中,将填写的内容显示出来,给表单控件赋值,或者控制有些值是否需要显示,就不要讲了吧。
第七步:将编写的表单页面配置到流程节点中。
如果每个节点都显示不一样的表单,可以通过代码控制某些控件是否显示、或者额外添加一个页面,配置在相关的节点中。
例如我的第二个节点与第一个节点就显示的不一样,配置的url也是不一样的。
运行示例:
发送与待办:
正文:
轨迹: