一个简单一个简单一个简单一个简单CCCC#工作流的实现#工作流的实现#工作流的实现#工作流的实现WorkFlow2010-04-2310:06:33阅读316评论0字号:大中小最近一直在做一个小项目,这个项目是高等学校岗位聘用审核系统,该系统涉及到多个部门审批,同时还要求管理员能对审核部门进行管理,编辑、添加和删除等。在了解到这些系统需要后,我首先想到利用微软sharepoint2007来开发,毕竟微软的工作流引擎已经非常成熟了,而且让人有种站在巨人肩膀的感觉(HoHo)。经过一段时间对sharepoint2007的学习,这套系统实在是太大了,而早几个月前这套系统在国内几乎没有一本成形的开发书籍,只有系统管理类书籍,常因为一个问题而耽误好几天,整个开发就这样停滞了,后来仔细想想其实我所开发的系统需要的工作流只是最简单工作流应用,因此也就有了自己设计一个小型工作流的想法,成就了本文,希望对大家有帮助。我设计的这个小型工作流只具有“运行先后”这个概念,没有其它判断条件,前一批工作流活动完成,后一批工作流活动开始。因为工作流类(Workflow)的结构非常简单:classWorkflow(){privateint_id;//工作流活动IDprivatestring_name;//工作流活动名称privatestring_url;//工作流活动相应的网页privateint_seq;//运行顺序privateint_statusBit;//状态位}工作流活动ID不用解释了,工作流活动名称可是任何字符,这样是为了更好区分工作流活动。url的设计是由INFOPATH联想到的,微软sharepoint2007可以通过为每个工作流活动指定相应的编辑表单,可以是网页也可以infopath设计的表单,这样的好处是让工作流的不同活动具有不同的用户界面,sharepoint2007可以在feature.xml里设置,而我这就使用url字段记录一个网页链接,不同工作流活动对应不同的网页。seq是每个工作流运行的顺序,从零开始,依次为0、1、2、3......,这个字段正是为了设置工作流的运行顺序,并行的工作流活动可以设置成相同的运行顺序。可能有人会问怎么标识工作流活动已经完成呢,这个标识正是由statusBit状态位来实现的,每个申请表中都含有一个status字段,这个字段默认为50个‘0’组成的字符串,status字段是为了记录当前申请表哪些工作流活动完成了,1为完成0为未完成,statusBit状态位正是将工作流活动与申请表中的状态联系起来,也许有些朋友会认为让系统自动分配好更好,第一个工作流活动联系第一位状态,第二个工作流活动联系第二位状态,等等。我这么做的好处是考虑到可能会有多个工作流活动只需完成其中一个活动就情况,就像逻辑判断中的“或”一样,在这种情况我们只需将多个工作流活动状态位设置成一样就可以达到目的了。光说而没有实例可能有些朋友不太明白,下面我以项目中工作流流程为例:本系统的流程是这样的(不好意思,linux下画的图效果没visio好):由流程图得出各工作流实例如下:IDNAMEURLSEQSTATUSBIT1申请人提交申请表user_main.aspx012各部门审查depart_check.aspx123科技处审查check_main.aspx234教务处审查check_main.aspx245研究生院审查check_main.aspx256人事科审查check_main.aspx267人事处审查recheck.aspx378专家评议expert_main.aspx489完成聘用null59想必由以上实例应该很容易看出流程图了,看到这应该明白了吧下面是我的工作流类的c#实现:usingSystem;usingSystem.Web;usingSystem.Web.Services;usingSystem.Web.Services.Protocols;usingSystem.ComponentModel;usingSystem.Data;usingSystem.Data.SqlClient;usingSystem.Collections.Generic;///summary///工作流类////summarypublicclassWorkflow{privateint_id;///summary///工作流编号////summarypublicintId{get{return_id;}set{_id=value;}}privatestring_name;///summary///工作流名字////summarypublicstringName{get{return_name;}set{_name=value;}}privatestring_url;///summary///工作流使用网页////summarypublicstringUrl{get{return_url;}set{_url=value;}}privateint_seq;///summary///工作流运行序号////summarypublicintSeq{get{return_seq;}set{_seq=value;}}privateint_statusBit;///summary///状态位////summarypublicintStatusBit{get{return_statusBit;}set{_statusBit=value;}}publicWorkflow(){}publicWorkflow(intid,stringname,stringurl,intseq,intstatusBit){this.Id=id;this.Name=name;this.Url=url;this.Seq=seq;this.StatusBit=statusBit;}publicWorkflow(SqlDataReaderdr){this.Id=Convert.ToInt32(dr[id]);this.Name=dr[name].ToString();this.Url=dr[url].ToString();this.Seq=Convert.ToInt32(dr[seq]);this.StatusBit=Convert.ToInt32(dr[statusBit]);}publicintAdd(){stringprocName=pr_AddWorkflow;SqlParameter[]prams={newSqlParameter(@name,SqlDbType.NVarChar,50),newSqlParameter(@url,SqlDbType.NVarChar,500),newSqlParameter(@seq,SqlDbType.Int),newSqlParameter(@statusbit,SqlDbType.Int)};prams[0].Value=Name;prams[1].Value=Url;prams[2].Value=Seq;prams[3].Value=StatusBit;returnDatabase.runExecute(procName,prams);}publicintDelete(){stringprocName=pr_DeleteWorkflow;SqlParameter[]prams={newSqlParameter(@id,SqlDbType.BigInt)};prams[0].Value=Id;returnDatabase.runExecute(procName,prams);}publicintUpdate(){stringprocName=pr_UpdateWorkflow;SqlParameter[]prams={newSqlParameter(@id,SqlDbType.BigInt),newSqlParameter(@name,SqlDbType.NVarChar,50),newSqlParameter(@url,SqlDbType.NVarChar,500),newSqlParameter(@seq,SqlDbType.Int),newSqlParameter(@statusbit,SqlDbType.Int)};prams[0].Value=Id;prams[1].Value=Name;prams[2].Value=Url;prams[3].Value=Seq;prams[4].Value=StatusBit;returnDatabase.runExecute(procName,prams);}///summary///根据工作流编号获得工作流信息////summary///paramname=id工作流编号/param///returns工作流信息/returnspublicstaticWorkflowGetWorkflowById(intid){Workflowwl=newWorkflow();stringprocName=pr_GetWorkflowById;SqlParameter[]prams={newSqlParameter(@Id,SqlDbType.BigInt)};prams[0].Value=id;SqlDataReaderdr=Database.runProcGetReader(procName,prams);while(dr.Read()){wl=newWorkflow(dr);}dr.Close();returnwl;}///summary///根据工作流编号获得工作流网页地址////summary///paramRealName=workflowId工作流编号/param///returns工作流网页地址/returnspublicstaticstringGetWorkflowUrlById(intworkflowId){stringprocName=pr_GetWorkflowUrlById;SqlParameter[]prams={newSqlParameter(@workflowId,SqlDbType.BigInt),newSqlParameter(@url,SqlDbType.NVarChar,500)};prams[0].Value=workflowId;prams[1].Direction=ParameterDirection.Output;Database.runExecute(procName,prams);returnprams[1].Value.ToString();}///summary///返回工作流个数////summary///returns工作流个数/returnspublicstaticintGetWorkflowNum(){stringprocName=pr_GetWorkflowNum;SqlParameter[]prams={newSqlParameter(@num,SqlDbType.Int)};prams[0].Direction=ParameterDirection.Output;Database.runExecute(procName,prams);returnConvert.ToInt32(prams[0].Value);}///summary///设置申请表的工作流完成状态////summary///paramname=reportId申请表编号/param///paramname=workflowId工作流编号/param///paramname=status完成状态/param///returns/returnspublicstaticintSetActivityStatus(intrepor