六、业务流程与业务数据
业务流程的本质就是待办任务在不同的人之间传来传去,待办任务其实是“桥梁”起到通知提醒的作用,而实际在人之间传来出去的实体应该是业务表单。所以,业务流程能否和业务数据紧密结合就是业务流程是否可用的另一大衡量标准。
业务流程中可以通过三种方式访问业务数据,一是通过内置函数(业务函数)直接访问主数据;二是通过服务的方式返回业务数据;三是通过业务流程变量获取业务数据。
在业务流程中使用业务数据有三种方式,它们分别是在事件的JAVA代码中直接访问业务数据库,业务流程变量和业务表达式。三种方式分别有不同的用途,在JAVA代码中一般直接访问业务数据库更新业务数据。业务流程变量中一般记录一些从业务数据上取来的值参与业务流程各种表达式计算。业务表达式则是业务模型底提供的公共机制,里面有一些函数可以访问业务数据中的值。
1 sData
当待办任务在不同的人之间传来传去时,首先要解决的一个问题就是如果让双方的业务表单保持一致。例如人员A通过待办任务把一个单号为001的申请单发给人员B审批,则人员B打开待办任务处理的时候看到的业务单据就应该是单号为001的申请单。
在待办任务中业务数据的传递是通过sData来实现的。sData只是一个泛指,在待办任务的库表SA_Task中它其实是靠4个字段来描述的,它们分别是sData1,sData2,sData3和sData4。当业务流程启动时,在调用流程启动动作(startProcessAction)的地方要求必须传入一个值为sData1的初始值。这个值被记录在sData1中在待办任务中一直传着走,在上例中从人员A的待办任务传入人员B的待办任务。当人员B打开待办任务处理时,从sData1中把值取出来参与业务表单的过滤。
一般情况下,赋值给sData的都是当前业务单据的单号,也就是业务主表的主键。业务主表只有一个主键时,自然sData1就够用了。如果业务主表是多主键则就需要把每个主键字段的值分别填写入sData1,sData2,sData3和sData4。也就是说,目前只支持4个字段的联合主键。
当启动一个业务流程需要同时处理多条业务主表的数据时,一般推荐的方案是为这多条业务数据生成一个批号,再把批号赋值给sData。同样也可以把多个单据的单号分别都赋值给sData。也就是说一个待办任务可以有多套sData。每套sData里都包含sData1,sData2,sData3和sData4。
在业务表达式中常常会这样用“:sData1”,这其实是业表达式中变量的用法,也就是说在业务表达式中使用“:sData1”来引用sData1的值,同样的可以“:sData2”, “:sData3”和“:sData4”。
2 业务流程变量
业务流程变量把从业务数据中取到的或者从系统代码中取到的一些值存入业务流程的实例中,参与业务数据的过滤或者业务流程表达式的计算。其实业务流程表达式的计算不一定需要依赖到变量而可以直接调用函数来算,但是依赖变量的好处是只有在为变量赋值的地方业务流程需要和业务模块产生联系,而直接调用函数就是每个调用点都有依赖业务模块了。
sData1, sData2, sData3, sData4也是业务流程变量的一种,只是它们是特殊的,主体用来参与业务过滤的系统级的业务流程变量。
业务表达式中通过表达式的方式获取变量
*全局变量
定义于业务过程上的变量,当业务流程启动时根据定义把每个变量的值算出来,然后和变量名一起存入到业务流程实例中。这种变量可以在业务流程中任何一个地方直接引用。
*局部变量
定义于活动环节上的变量,当其他活动环节做流转动作流入当前活动环节时根据定义把每个变量的值计算出来,然后和变量名一起存入当前活动环节的待办任务中。这种变量只能在当前活动环节中使用。
3 业务表达式
在业务流程中使用的表达式分为两大类,它们分别用来执行者的组织机构表达式,和一般的业务表达式。两种表达式可以互相使用。
业务表达式其实是业务模型底层公共的表达式,业务表达式中的函数同样不是写死的,任何的函数基本都可以当作业务表达式的函数来用。
在业务流程中可以使用任意的业务表达式函数,在这里就不一一列举,而只列出来一些业务流程中最常用的函数以供参考。
*业务流程的业务表达式函数
在表达式中,获取业务数据的值基本都使用fieldValue函数,这种函数本质上就是根据传入参数构造一个SQL去数据库里把对应表和字段的值查出来。在多条关联时,这些函数是完全可以互相嵌套使用的,如果一个表达式里有多个这种函数,也就是说这个表达式计算时将发多个SQL到数据库里取值。这些取值的函数是业务模型底层提供的公共的获取业务数据值的函数,不仅仅在只在业务流程里使用。
函数名 |
描述 |
fieldValue |
获取表单字段值 |
guid |
32位的唯一标识 |
startsWith |
判断某个字符串是否以指定的字符串开始 |
endsWith |
判断某个字符串是否以指定的字符串结束 |