工作流认识

 

工作流,从业务角度看,就是审核流程,其表现就是控制不同的角色看到不同的数据,不同的操作使得数据的流向不同,一般情况下会有申请,审核,批准,核准等步骤;从技术实现的角度看,就是通过控制一个表的一个字段的不同状态,同时配合角色控制来实现。

II.我们的工作

我们的主要工作是配置一个工作流,添加一个后台页面,然后流程中的所有步骤都调用这个页面,然后控制具体的每一个步骤中页面需要显示的和不需要显示的数据,控件。

III.配置工作流

A.配置工作流绑定的表

一般来说,我们的每一个工作流都会对应一个表,表中的每一条数据对应一个申请单;这个表中会记录申请单的状态和显示状态(状态是用于查询显示数据,显示状态是用于页面的实现的),同时还有申请单号,申请人,申请时间,目的,备注的信息,根据不同的流程添加不同的字段;特别说明一下申请单号,一般会设这个字段为主键,同时这个字段也会做相应的编码处理,比如会添加申请时的日期时间等;以下开始以食品所标本使用申请为例,做一个大致的介绍:

1.工作流主表

在系统主界面左边系统设置------工作流设置中,配置工作流如上图所示;先在上方的datagrid中添加工作流代码,此代码是唯一的,这是一个重要的参数,后面会将这个参数传入到页面中去;工作流名称字段是相关业务的名称,比如库存领用申请等,工作流描述字段是对此工作流的描述,引用窗体,是我们画好的页面所在的Application,数据表字段就是创建的表INVENTORY_APPLY,状态字段和状态显示字段就是我们创建的表中的STATUS和DISPSTATUS,这个字段不一定非要用STATUS和DISPSTATUS,不过习惯上都用STATUS字段,退回字段是一个标志字段,他是为了满足这么一种需求:如果单子在整个流程中有被退回过,就更改此标记,这样就可以修改被退回单子显示的颜色;

2.工作流步骤

左下方的工作流步骤就是工作流程中所有的步骤,每一步有一个状态,当添加过上方的审核工作流以后,会有默认的许多工作流步骤加进去,这只是为了方便大家,不用再一步步的添加,也可以将这些全部删除,然后再一步步的添加;

⑴排序:就是为了看的更清楚而排序用的,我们都会从负到正,从小到大走流程;

⑵步骤代码:当前步骤的代码,唯一标识此步骤,一般我们会和状态字段取值相同

⑶状态:这个是要存到INVENTORY_APPLY表STATUS字段的值,我们的流程就是控制这个字段的不同取值,显示不同的流程

(4)显示状态,这个是要存到INVENTORY_APPLY表DISPSTATUS字段的值,是和STATUS字段对应的,用来显示中文的

(5)窗体标题:窗体的名字

(6)角色:通过角色可以过滤数据

(7)工作描述:就是职位,通过职位可以过滤数据

(8)用户:通过用户可以过滤数据

(9)签名类型:此字段用来控制签名框是否需要用户名密码

(10)备注标题:备注label的名字

(11)电子签名代码:可以另外增加的客户端代码

3.动作信息

上面的就是步骤的信息,下面介绍每一个步骤对已的不同TAB页的信息:

上图为标本领用申请审核对应的动作,用来控制流程的去向

(1)动作代码:唯一标识动作

(2)动作名称:动作的名字,一般就是审核通过和审核拒绝两种

(3)下一步:这个字段很重要,这一步提交之后,如果通过,INVENTORY_APPLY中当前申请单表的STATUS字段就会变为Approve2,如果拒绝,则变为Draft

(4)执行脚本:通过或者拒绝的时候同时执行脚本,这个脚本可以取两个参数,一个是当前单子的ORIGREC,另一个是填写的原因;

(5)退回:是否能够退回,申请的时候只有通过,没有拒绝

(6)显示:是否显示电子签名

(7)动作分类:

(8)原因必填:电子签名的备注是否必填

(9)是否汇签:是否需要多人同时签名

4.客户端执行脚本

上图为标本领用申请审核对应的客户端执行脚本,用来控制页面的初始化和控件调用不同的代码

(1)名称,此字段是当前客户端执行脚本唯一标识符,后台代码中根据这个名称加载后面的具体代码

(2)描述,当前脚本的描述

(3)控件类型,页面中的控件类型

(4)控件ID,控件的名字

(5)动作类型:控制不同情况下显示的动作不同,为空就是都显示

(6)替换,当前脚本是体检执行,还是推迟,还是覆盖后台中的同名代码

5.控制台脚本

上图为标本领用申请审核对应的控制台脚本,用来控制在主页面的左右两边的菜单中显示的;⑴控制台选择,Main Menu为系统主页面左面菜单,Life Cycle Options为系           统主页面右面菜单

⑵组名称:为主页面左右菜单下面得二级菜单代码

⑶项目名称:当前要显示的菜单的代码,这个是全局唯一的,即所有流程中所有步骤对应的项目名称都是不同的,最好是当前的流程代码+步骤代码,这样能保证唯一性;先填好项目名称再创建,如果你点击创建后发现下面无故出现了很多东西,那一定是出现重名的了;

⑷英文:英文显示名称

⑸中文:中文显示名称,菜单的名字

⑹序号:在二级菜单下所在的位置,默认会排到菜单最下面

⑺计数器:显示当前菜单中的单子个数,计算INVENTORY_APPLY中STATUS等于当前步骤的数据个数,为0,不显示;为正整数,显示

⑻图片:菜单的图标

⑼类型:菜单类型,一般为Application(会自动默认)

⑽窗口:显示这个窗口的位置,默认为Application Tab,即以TAB页打开新页面(会自动默认)

⑾窗体:调用的页面,和上面datagrid中的窗体一样(会自动默认)

⑿设定命令参数:这个是传给页面的参数,会有三个参数传进去,第一个是当前的工作流代码,第二个是当前的步骤代码,第三个是where条件,用于查询当前步骤对应申请单的条件

⒀右面的多选框:是角色控制,特定对象的人能看到当前的菜单;

5.汇签

 

上图为标本领用申请审核对应的汇签页面,用来控制汇签时有哪些人要一起审核,此流程不需要汇签,所以没有编辑用户。

IV.需要注意的问题及补充

A. FormInit

ExecuteFormInit();这句话写在Form1_OnInit事件中,这样就可以调用工作流步骤中的客户端执行脚本的FormInit事件,同时取得传递给页面的参数并写入到form.Variables["WorkFlowCode"],form.Variables["StepCode"],

form.Variables["strWhere"],form.Variables["strParams"]中,客户端执行脚本中不能用return;不能注释代码,如果要设标志条件,只能使用全局变量;所有步骤中都要使用的东西,比如附件,审核流程,动态链接报表,这些都写在Form1_OnInit事件中

B. Form1_OnLoad

   Form1_OnLoad事件中,需要设置申请单Datagrid的数据源,同时设置标志,此处设置标志的作用是因为数据加载的时候会调用申请单Datagrid的OnRowChange事件,如果加载所有的数据会很慢,所以设置标志,只刷新当前的TAB页的数据,用户更换TAB页时再刷对应的TAB页数据,提高速度;设置标志组的个数,需要看对应的TAB页的的关联个数;在样本申请流程中有两个上下级的TAB页,所以设置两组标志

C. Commit_OnClick

ExecuteWFAction( form.Variables["WorkFlowCode"],form.Variables["StepCode"], "BeforeSubmit" );

这句话写在提交,这样就可以调用工作流步骤中的客户端执行脚本的BeforeSubmit事件

D. Refresh

   刷新数据的时候,考虑两种情况,第一种是添加删除申请单时对应的子数据要更新;第二种是完全删除申请单Datagrid数据时要清空所有子数据

至此,工作流的配置大致完成,下面的工作就是写调用FORM的后台代码和不同步骤的初始化和提交事件;尽量把提交数据,控件的控制写在我们刚刚讲解的工作流配置页面中,这样在后期的维护与修改中,会非常的方便并且逻辑很清楚。


V.工作流原理

在上面的配置介绍中,我们知道了如何配置一个工作流,使他正常的运作起来,而工作流具体是怎么实现的,以下会有一个逐步渐进的介绍。

A.电子签名Form

⒈电子签名Form图片

这个就是我们一直使用的数字签名所调用的form,同时也是控制数据流向的接口,界面很简单,不用过多介绍,再没有汇签的情况下,汇签人员以及后面的控件是不显示的,如过有汇签,就会显示相应的控件。

2.Commit_OnClick提交函数

在Commit_OnClick提交函数中,会调用Var returnValues = form.ShowModalDialog(lims.GetFormSource("GeneralWorkFlowActions.Audit"),[form.Variables["WorkFlowCode"], Status, Origrec, form.Variables["StepDetType"]]);

这个函数呢就是召唤出数字签名Form,并且传入必要的参数;

form.Variables["WorkFlowCode"]工作流代码,此工作流的唯一标示符;

Status当前申请单的状态,就是工作流绑定表中STATUS字段的值,注意:这个和工作流的步骤代码是一样的;

Origrec:当前申请单的唯一标识字段

⑷form.Variables["StepDetType"]:动作分类代码

 

3.Form初始化

function frmMain_OnLoad( sender, eventArgs )

{

    用户名.Text = 当前用户用户名;

    如果( 传入参数不为空 )

    {

      

全局变量["WFCode"] = 工作流代码;

       全局变量["StepCode"] =步骤代码;

       全局变量["SID"] = 申请单唯一标示符;

      

        通过工作流代码和步骤代码参数在GENERAL_WORKFLOW_STEPS表中查询出签名类型ESign和备注名字CommentName;

      

       如果(签名类型ESign 不等于 'Esig')

       {

           用户名密码.可见性 = 不可见;

       }

      

       如果(备注名字CommentName != "")

       {

           备注.名字 = CommentName;

       }

      

       定义 StepDetCat = null;

       如果(传入参数长度大于3)

       {

           StepDetCat = 第四个参数

       }

      

       通过工作流代码和步骤代码和StepDetCat在GENERAL_WORKFLOWSTEPDET查找出当前步骤的动作代码;

             

 

 

             

       如果 (动作代码不为空)

       {

           第一个动作被选中;确定按钮可以用;

       }

    }

    否则

    {

       全局变量["WFCode"] = "";

       全局变量["SID"] = "";

       全局变量["Esign"] = "Silent";

      

    }

   

    lblDate.Text = 当前日期;

    lblTime.Text = 当前时间;

}

 

通过对电子签名页面初始化得分析,我们知道初始化得时候,会确定是否需要用户签名,动作,备注名字这三个配置;

4.是否汇签

页面初始化给动作下拉框绑定数据后,会触发OnSelectionChanged事件,这时会判断是否需要汇签

function cboOperation_OnSelectionChanged( sender, eventArgs )

{

    通过工作流代码和步骤代码和当前动作下拉框的值在GENERAL_WORKFLOWSTEPDET表中查询出当前工作流的步骤对应的动作备注是否必填,是否汇签,下一步代码,汇签人是否必填;

    通过工作流代码和步骤代码在GENERAL_WORKFLOW_AUDIT表中查询出汇签人用户名和全名;

    如果(要求汇签)

    {

       汇签人员控件.可见性 = 可见;

    }

    否则

    {

       汇签人员控件.可见性 = 不可见;

    }

    将查询出的汇签用户名和全名赋值给combox和text显示;

}

5.确定按钮动作

function btnOK_OnClick( sender, eventArgs )

{

   通过工作流代码和步骤代码和当前动作下拉框的值在GENERAL_WORKFLOWSTEPDET表中查询出当前工作流的步骤对应的动作备注是否必填;

    如果(备注必填 == 真 && 备注为空)

    {

       提示用户,光标锁定备注,结束函数;

    }

   

    如果(签名类型ESign == "Esig")

    {

       获取当前的用户名和用书输入的密码,如果验证不通过,提示用户,结束函数;

    }

   

    如果(需要汇签 并且 汇签人不能为空)

    {

       提示用户,光标锁定汇签框,结束函数;

    }

    最后调用工作流主SSL函数:

    lims.CallServer("GeneralWorkFlowActions.Audit",

       [工作流代码,步骤代码,动作代码,申请单唯一标示符,备注,汇签人用户名]);

    页面返回备注,操作代码,操作名称;关闭Form;

}

6.工作流主SSL函数

lims.CallServer("GeneralWorkFlowActions.Audit",

[form.Variables["WFCode"],form.Variables["StepCode"],OperationCode,form.Variables["SID"],Reason,AuditUsrNam]);

 

  1. 通过工作流代码在GENERAL_WORKFLOWS表中查询出工作流绑定表,状态字段,状态显示字段,是否退回字段;
  2. 通过工作流代码和步骤代码在GENERAL_WORKFLOW_STEPS表中查询出步骤名称,用于写入GENERAL_WORKFLOW_HISTORY表记录时使用
  3. 通过工作流代码和步骤代码和动作代码在GENERAL_WORKFLOWSTEPDET表中查询出下一步代码,动作名称,执行脚本名字,是否退回;
  4. 通过工作流代码和已经查询出的下一步代码在GENERAL_WORKFLOW_STEPS表中查询出下一步的状态和显示状态;
  5. 通过执行脚本名字在CALCS_ACTIONS表中查询出具体要执行的脚步,传入的参数为ORIGREC和COMMENTS,这个脚本是最后才会执行的,这点要清楚;
  6. 通过工作流代码和步骤代码和当前用户名在GENERAL_WORKFLOW_RECORD表中查询ORIGREC;

7.根据传入的申请单ORIGREC的个数循环下面的操作:

如果(ORIGREC个数大于0)

{

    (1)更新GENERAL_WORKFLOW_RECORD表中当前工作流,当前步骤,当前用户,当前申请单ORIGREC,当前绑定表,当前状态的数据为下一步状态;

   (2)通过查询GENERAL_WORKFLOW_RECORD表中当前工作流,当前步骤,当前绑定表,当前申请单ORIGREC,当前状态的数据个数,来判断是否更新申请单的状态;如果个数大于0,则表示汇签人员还有没有签核完的,如果等于0,表示都签核完了,就可以更新申请单的状态了;

}

否则

{

    (1)根据申请单ORIGREC更新申请单状态到下一状态;

    (2)如果退回字段不为空且退回标志为“Y”,则根据申请单ORIGREC更新退回标志为“Y”;

    如果(会签人员不为空)

{

(1)从GENERAL_WORKFLOW_RECORD表中删除当前工作流,下一步骤,当前绑定表,当前申请单号的数据,保证会签的正确性;

(2)向GENERAL_WORKFLOW_RECORD表写入数据,有几个汇签人就写几笔数据,数据为当前工作流,下一步骤,绑定表,申请单ID,下一步状态,下一步显示状态;

(3)向GENERAL_WORKFLOW_HISTORY写工作流操作记录;

 

 

(4)如果(当前步骤执行脚本不为空)

{

    执行脚本(传入参数为当前申请单ORIGREC和备注)

}

}

}

原文地址:https://www.cnblogs.com/csschn/p/4726857.html