jxTMS--简易流程

41 篇文章 0 订阅

简易流程

jxTMS目前主要针对两种业务场景:功能性作业以及各种审批流程。这两者的关系是:业务流程当然是围绕组织价值链来逐步渗透展开的,而功能性作业是用来为业务流程的展开进行数据准备的。

所以我们着重讲解jxTMS中的流程。起初,笔者按标准流程实现了完整流程的文本化定义、分发等等工作,但后来发现一个比较严重的问题:标准流程是全功能的,所以其支持各节点的与入与出、或入或出,而如果开发者对流程设计不够熟悉的话,如果无法准确掌握标准流程:与入并与出或入并或出的原则,很容易把流程锁死,而笔者还考虑的比较复杂,设计了自动化条件执行等短路处理,那对经验不太够的开发者来说,就是灾难了。因为其连排查都无法排查。

考虑到这个关键问题,同时笔者还观察到jxTMS初始目标的中小微企业的主要作业模式没这么复杂,就是单主线的逐环节串行作业,根本也不需要标准流程的并行作业等功能,这些功能对于目标用户来说,反而是复杂化了。因此,笔者对流程进行了两个简化:

  • 去掉了标准流程的与或节点的概念,每个节点就是或入或出,这样一来,开发者也不需要过多学习流程应该如何设计、如何排查了

  • 去掉了节点间的自由流转,即将标准流程可并行的多业务线缩减为只有一条逐个节点依次推进的业务线,该业务线就是从第一个业务节点一直执行到最后一个节点,如果某节点被拒绝则返回到前面的节点重新执行

这就是简易流程。如此一来,开发者设计简易流程就简单多了:

  • 按照现有流程画出各业务作业点,包括打回到哪个节点

  • 给每个节点设计操作界面【当然高层的就简单多了,就是审批意见、同意、拒绝按钮,如果需要增加一个打回到哪个节点】

  • 给每个节点指定一个执行角色,为了避免影响其它业务,如果可能就指定专用的角色,然后将这个角色映射到相应的人员

  • 检查各业务点是否必须执行,如果是根据业务实际情况可选的,就为其确定判断条件,如果有必要,就为其设立一个专门的业务状态,如demo所演示的needCEO【需总经理审批】

  • 是否需要创建业务规则,如果有必要则和用户讨论相应的业务规则

好了,有了这些考虑,我们两个小时后就可以将这个简易流程上线了【别忘了,我们对每个组织是创建一个正式的ORG,一个用于测试的TestORG,别直接上到生产环境上啦】,然后让用户来试用,改进迭代好了。

流程定义

demo所演示的销售订单审批流程:

@myModule.simpleFlow('sfApproveSalesOrder')
def sfApproveSalesOrder():
    '''
    web sfApproveSalesOrder;
    node saleApprove 销售填写 web asoSaleApprove ;
    node managerConfirm 业务主管审核 web asoManagerConfirm needRole 销售部经理 ;
    node ceoConfirm 总经理审批 web asoCeoConfirm needRole 总经理 ;
    '''
    pass

这是demo中用于演示的销售订单审批流程。其中,@myModule.simpleFlow(‘sfApproveSalesOrder’)是定义简易流程的标准做法,指示在本模块中增加名为sfApproveSalesOrder的简易流程,然后在本模块被整体加载到ORG中时,该流程也自动被加载了。

具体的流程定义,在用simpleFlow修饰的函数的doc说明中定义的,该函数的名字无所谓,其函数体也就是一个pass语句,但建议最好和流程同名。需要说明的是,流程定义文本,必须以英文的分号【;】结束,连续的分号没有任何影响,但如果两行定义之间,缺少分号,则会编译错误。

注1:如果编写错误,没什么好担心的,修改后重刷一下也就好了
注2:导入自定义模块,在开始的时候,笔者是作为一个微服务实现的,这就导致如果加载错误,下达重新加载命令的用户是不知道的。后来由于微服务需要再启动一个java程序,额外增加了不必要的系统开销,所以在验证可行后,笔者最终取消了微服务的设计而将其移入app中实现,但这个问题却遗留了下来,即前端是无法感知加载错误的,所以目前需要开发者是重新加载前,在后台查看系统日志,如果有加载错误的报错就进行修改。这个问题,由于优先级不高,所以需要等待一段时间后再行修复。同时,笔者也强烈建议开发者应熟悉如何查看、分析系统日志来更好的掌握jxTMS的运行

#指出本流程各操作环节所共享的web界面,建议还是最好和流程同名
    web sfApproveSalesOrder;

一个简易流程的web界面是一个div的组容器,然后其是由各个节点的div组容器所组成的。在流程流转过程中,这些节点都会被遮挡,只有当你有任务执行时,才会将相应的节点遮罩打开,如果没有任务执行,那即便是查看自己执行过的流程,相应节点的遮罩也不会打开。

下面接着定义了三个业务节点,其定义格式为:

node 节点名 该环节显示名 web 该节点所定义的组容器名 (needRole 执行该节点的角色名)? notJump?

其中的英文都是关键字,括号扩起来的是一个定义的整体,?代表该定义可选。建议开发者应熟悉正则表达式的编写,为了降低开发者的学习曲线,jxTMS中各文本定义的语法规则,如+、*等的含义都和其相似。

定义说明:

  • 节点名,是该业务节点的名字,系统发射、打回、分发等都是根据该名字进行调度的。由于该名字,会在多个环境下使用,所以同样建议最好不要使用中文

  • 该环节显示名,是用来在任务分发后,显示给用户看,他需要执行哪个流程的哪步操作的提示性文字,所以必须是中文,而且要能简短说明任务内容

  • 该节点所定义的组容器名,即上面所说的,整个简易流程的界面是一个div组容器,其就是由各个节点的组容器所组成的。系统在需要用其来确定如何处理遮罩,即当被分发来执行该环节操作时,jxTMS需要利用该名来决定取消哪个组容器的遮罩

  • 执行该节点的角色名,jxTMS在需要执行该节点时,是动态决定由谁来执行的,最优先的,自然是用户明确指定了由谁来执行,这主要是考虑,在某个环节,总经理等出于业务考虑,将某环节直接指定某人来执行【目前暂不开放本功能】;其次就是该节点上次是谁执行的,这主要是当某节点被打回时,就直接指派给上次的执行者,这主要是考虑其熟悉情况,可以提高作业效率;然后就是根据这里所定义的角色进行动态的映射

需要说明的是,除了第一个节点,其它后继节点都必须指定角色,否则系统会报错。而第一个节点不指定,主要是由于流程的第一步一般都是申请人填写,自然是谁申请谁执行,而其有无权力来启动该流程则是通过启动该流程的入口来进行控制的。

下面讲解一下角色的动态映射:

  • 如果该角色是真实角色,即可直接映射用户的角色,则从其所映射的角色中选择一个进行分发。所以强烈建议,角色要单一专用,否则可能导致业务运行混乱

  • 如果是虚拟角色,即供其它真实角色进行映射的角色。如,报销审批,第二步一定是各部门的经理进行审核,那总不能每个部门单独设计一个报销流程吧?所以这里一定是一个虚拟的经理角色,然后由申请者所在部门和经理这两个信息共同确定应该分发给哪个部门经理,然后再根据这个真实的部门经理的角色找到映射的用户,将任务分发给他

  • 如果该虚拟角色的层级非常高,比如是总监,则会按照组织的架构,从最基层的部门一路向上直到找到管辖申请者的那个真正的总监,然后将任务分发给他

  • 如果找到的那个待执行者就是自己怎么办?!那要看这个节点是否定义了notJump【是否不可被跳过】,如果定义了notJump,则该发就发,也就说这个业务环节属于业务处理环节,必须执行;而如果没有定义notJump,那就是说,该节点在业务上属于核验性质的环节,那自然就不存在自己信不过自己,还要检查自己所申请的是否真实的问题了

  • 如果这个待执行者请假了怎么办呢?!jxTMS有一个代理机制,每个用户都可以指定其代理人,如果有代理人则使用代理人。不过呢,目前该功能暂不开放。反正有手机有平板,跑哪都得干活啦:( 实在顶不住,请假前将其映射的角色映射给他人吧

注:强调一点,找不到执行者会自动以accept提交该节点,如果设计不当,这可能会导致流程自动以审批通过结束

当系统确定了待执行人之后,会向其发送一个系统消息,该消息包含了执行该任务所有必须的信息,该信息由info.mgr进行管理,其会在左侧快捷功能树中的【消息】项目下占有【我在做的任务】和【我完成的任务】两项,用户在每次登录后都应点击一下【我在做的任务】,检查是否有新的任务分发给自己。

注:如果用户处于登录状态,新任务出现后,会在【我在做的任务】后用红色数字来提示有几个新任务分发给用户了

流程流转

和其它的操作按钮不同,简易流程的操作按钮是固定的:

with sfApproveSalesOrderD1t3 row 2 col c0 web n type button width=80,text='确认',motion=cmd,
     demand=simpleFlowDual,params={'flowName':'sfApproveSalesOrder','nodeName':'saleApprove','active':'accept','signBy':'salesBy','signDate':'salesDate'};

其操作按钮,必须为cmd类型的simpleFlowDual事件,其参数必须指定flowName【必须指定为本流程名】、nodeName【操作的节点名】、active【本操作所希望执行的动作】,以及签名人控件和签名时间控件所绑定的数据名。

简易流程目前支持三种动作:

  • accept:同意,意为放行当前节点,使得简易流程按节点定义的顺序自动流转到下一个节点

  • reject:否决,意为打回到前面的节点重新执行,如果指定了exportAdditional,则退回到exportAdditional所指定的节点重新执行,否则返回到第一步重新开始执行

  • replenish:存疑需做进一步说明,和reject相同的都是退回到exportAdditional所指定的节点或第一步,但不同的是退回到的那个节点不需要用户执行,而是会给其显示一个补充说明的工具条,该用户点击后会弹出一个对话框,让其填写相关说明或解释,解释之后,就不需要重新一步步执行了,而是直接返回到发出replenish的环节,由其根据这个说明选择是放行、拒绝还是继续要求补充说明

节点操作

每一个节点,都有三个可自定义的事件函数,这三个节点事件是:

1、本节点的处理,当该节点被提交【用户点击accept或reject按钮,或系统自动accept该节点】时,jxTMS会检查开发者是否定义了该节点的dual函数,如定义了则调用该函数:

@myModule.event('简易流程名', '节点名', 'dual')
def saleApprove_dual(self, db, ctx,ca,active):
    if active=='accept':
    	#用户同意了,那么
    	#参数中的ca就是当前在处理的数据对象
    elif active=='reject':
    	#用户否决了,那么

无论定义还是不定义该节点的dual,jxTMS都会把现场数据,包括用户意见,以及用户的签名、时间这两个信息保存到数据库中。

2、本节点是否需要人来执行:

@myModule.event('简易流程名', '节点名', 'check')
def ceoConfirm_check(self, db, ctx,ca,json):
	#json函数就是要发给用户的a串,开发者基本上不需关心
    needCEO=ca.getInfo('needCEO')
    need= (not needCEO is None) and needCEO
    return need

在某节点被accept后,jxTMS会检查下一个节点是否需要发给用户执行,会调用下一个节点的check函数,如果返回True,就查找下一个节点的应执行人,如果找到则分发任务给该执行人。如果check函数返回False,则默认下一个节点以accept放行。

注1:check函数返回False,并不意味着该节点不需要被执行了,而只是说不需要被人来执行,该节点是默认以accept放行的,则其dual函数就会收到一个active=accept的事件

注2:check函数的优先级是高于notJump的,因为只有确定某节点需要执行,才会在查找该节点的执行人时根据notJump与否来决定找到的人如果是自己那要不要还发任务

3、发任务时,如果需要附加特定的参数,则还可定义visitor事件,但还是那句话,本功能目前暂不开放

简易流程的结束

当简易流程执行到最后一个节点,而该节点也以accept放行的时候,该流程将执行一个虚拟的end节点,该节点将执行如下两类动作:

  • 虽然是虚拟节点,但也是节点,所以其会触发@myModule.event(‘简易流程名’, ‘end’, ‘dual’)所修饰的函数,来执行用户的流程结束代码

demo中的销售订单审批流程的结束代码是:

#订单审批简易流程-结束-处理
@myModule.event('sfApproveSalesOrder', 'end', 'dual')
def sprjend_dual(self, db, ctx,ca,active):
    #用jxTMS平台提供的orm.set(db,filed,value)可实现赋值之后自动设置自动变动
    #同时如果设置了标记或约束,还会自动进行检查
    self.currentAffair.set(db,'State','交付中'.decode('utf-8'))
    #根据订单id查找销售
    sales=Relation.getObj(db.getDBConn(),self.currentAffair.ID,'relSales2Order','people')
    #对订单进行统计,由于订单统计需要查询订单和销售的信息,所以必须将这两者同时提供
    self.statistics(db,ctx,'订单统计'.decode('utf-8'),self.currentAffair,sales)
    return True

其一共做了两件事,修改订单状态、对本订单进行统计

  • 执行标准的简易流程结束处理,最关键就是触发一次兴趣广播。即广播本流程结束了,有兴趣的可以捕获了进行自己的处理。相关说明详见关于兴趣点的介绍

注:end节点的check函数没有意义,end本来就是一个虚拟节点【开发者不需要定义但依然存在】,本来就不需要人来执行的

自动签名

由于每个用户都需要进行签名包括记录签名时的时间,而这些控件又是需要一个数据名才能被感知到并保存的,所以对签名和签名时间的处理就成了一个简单到极点但却每个节点都要做的重复性劳动,所以jxTMS引入了一个自动签名的机制,即开发者在定义accept、reject等简易流程操作按钮时,明确指出本环节的签名控件数据名和签名时间控件数据名,则jxTMS即自动用调用者名和当前时间来为这两个控件赋值,开发者也就不再需要在每个节点的dual函数中写入这两个信息了:

params={'flowName':'sfApproveSalesOrder','nodeName':'managerConfirm','active':'reject','signBy':'suggestionBy','signDate':'suggestionDate'};

这两个参数就是上面示例中的:

signBy:本节点签名控件的数据名
signDate:本节点签名时间控件的数据名

注:这两个控件的值是按钮被点击后的当前值,即如果有重复执行,签名时间就是其最新一次点击时的时间

现场数据

流程性的capa和功能性的capa不同之处在于:流程涉及到多人协作,所以其不如功能性的任务,责任很明确的就是那一个人的,而流程非常容易出现扯皮、责任不清。所以流程引擎设计的核心,不在于什么流转、什么分发这些说起来觉得高大上的东东,而在于如何非常明确的确定问题点、落实责任、出现问题时快速追溯、固定证据。

也就是说,流程有没有用,完全取决于责任有没有划分清楚、能不能明确、能不能事后非常容易的确定责任。

而这些东东包括两部分,一是设计流程时要经过良好的设计,但这一点基本都会有用户的参与,开发者只要提供技术方面的配合就好了;二就是系统提供了什么样的有力工具。

jxTMS在设计工具之前,首先要解决一个问题:如果要追溯,就需要收集数据,这些数据保存到哪?!如果全部直接保存到数据库中的数据表中,那么是否要限定一个固定的流程数据表?!如果要限定,那么流程的弹性如何解决?!如果流程可以适用于任何开发者自定义的数据对象【数据表】,那系统如何保存数据呢?!连数据都无法统一保存,还谈什么统筹管理控制呢?!

所以呢,第一步,jxTMS实现了一个称之为现场数据的保存机制,很简单,凡要支持流程的数据对象,只要在自己的数据定义中同时声明如下两项即可:

class 开发者自己定义的数据类/数据表名:
	...其它field
	field Extant json
	field FlowExec json
	;

其中:

  • Extant,json格式。用来保存本流程的现场数据

  • FlowExec,json格式。用来保存各节点都是谁执行的

那么,什么是现场数据呢?!当前所有执行过的用户输入的最新数据所组成的数据集合,就是现场数据。

注:现场数据的采集非常容易:拦截所有的用户输入并将其合并到Extant中即可

现场数据在每个节点,被当前用户修改后,就会出现一个新版本的现场数据,所有版本的现场数据,就组成了整个流程流转的历史记录,而这一个个不同版本的现场数据,就叫做快照,就相当于每次有用户对现场数据做出了修改之后,用照相机拍下来,然后保存到数据库中。

有了这一个个快照所组成的流程的历史数据集合,那么从第一个快照开始播放,就实现了流程的追溯;把用户所负责的控件组所对应的数据集在不同快照中的差,就是其输入。

至此,我们就有了一个强大的基础设施:基于现场数据的快照所组成的历史数据集合。我们利用这个快照集,就很容易实现追溯、问题分析、固定证据了。

流程附属功能

基于现场数据机制和其它配合机制,jxTMS提供了三个通用的流程附属功能:

  • 日志与快照:所有的流程在流转时,jxTMS自动记录流程的流转信息,并抓取快照,供用户随时查看

  • 数据变动记录:快照很好很强大,但一般来说,流程所需处理的数据项都非常多,逐一查看比对是非常低效的,所以jxTMS还提供了一个记录数据变动的功能,即对每个节点,都会收集用户修改了哪些数据:将这些数据从什么修改为了什么

开发者只要给需要记录数据变动的输入控件添加一个属性,则该控件在发生变化时jxTMS就会将变动自动提取出来,这样用户在那个环节改了什么就一目了然了:

#是输入控件的一个属性
logChangedDisp='记录后给人看的数据名'

输入控件都会绑一个数据名,但前面说了,由于涉及到复杂的跨编程环境转换,所以我们建议数据名最好不要用中文,但这个数据记录的变动就是要给人看的,所以这里就是给出这个给人看的数据提示。

  • 补充说明:既然会发出补充说明的要求,自然这一来一往对业务就非常重要,所以就需要在回顾、回溯、追溯时能统一查看所有的补充说明。同时还需为发布补充说明的要求、答复补充说明等提供操作支持

注:这三个功能都是开箱即用的,开发者只要简单的将这三个功能的入口链接到自己的流程查看页面即可使用。具体的请参考demo中sales.order下op.py中的说明。

目前,jxTMS已经打包为云服务器镜像,开发者开箱即用:
jxTMS-腾讯云市场​

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值