一、前言
前面已经给大家介绍了我的工作流引擎的总体设计及的API设计,这篇是实战篇说说怎么实际应用了,这就得涉及到UI界面了。首先我们常用的工作流个人办公应用系统至少要包括发起流程、待办事项、已办事项等。我们设计了一个尽量简单的系统,能够满足个人办公的基本需求,只实现以下功能:
1、发起流程
2、待办事项
3、已办事项
4、我的流程
5、我的消息
6、我的委办
这些功能基本就是流程能正常的运行流转基础,其实只应用了我们引擎的一小部分功能,其它功能如果有需要可以在这基本上再添加。
二、页面设计及实现
1、发起流程,很简单的一个页面,左边显示已发布流程列表,右边放置一个iframe用于显示对应的启动表单
左边流程列表数据:
select * from bpm_definition_process where state = 'Deploy'
左边根据流程定义的分类显示为树形结构,点击选择左边流程时,右边iframe打开对应流程的启动表单页面即可。
点击发起流程按钮时,调用ajax处理,把表单数据传到后台,后台处理逻辑如下:
//1 保存表单返回表单数据id var id = ...; //2 启动流程 var process = bpm.NewProcessIntance(processId, id); var task = process.Start(); //3 发送到下一步审批 task.SetRecord(id); task.Signal();
列表的数据查询:
select * from bpm_instance_task where state = 'Run' and actor_id = @user_id
双单或点击办理时,打开表单展示页面:
表单审批页签,在这里可以查看表单录入的数据,查看历史审批情况,或进行审批操作,可设置签章
当然每个审批节点都可以有自己的表单也可以通过参数,来控制以下各元素的是否需要显示:审批选项、审批意见、添加附件、指定下一步审批人
按钮逻辑
保存即只保存表单数据怎么保存可以自己定义
转交下一步逻辑:
//加载任务实例 var task = bpm.LoadTaskInstance(taskInstanceId); //如果有新表单,保存表单数据返回ID, var id = ...; task.SetRecord(id) //如果有附件,保存附件,返回附件ID列表 var attachments = ...; task.SetAttach(attachments); //如果需要设置下一步审批人 task.SetReceiver(receiver); //如果需要设置自由跳转的目标工作项 task.SetFreeRedirect(redirect); //设置审批意见 task.SetOpinion(choice, comment); //设置审批签章 task.SetSignature(signature); //转交下一步 task.Signal();
流程图是我通过raphaeljs实现的,接收工作项及路由(连接线)的数据展现图形,根据数据自动计算每个工作任务的位置和连线,目前只实现了图形展示功能,还没有去实现拖拉设计的功能。
关于我的表单的设计和流程图的展示,后续有时间我会跟大家详细介绍。不过这和工作流引擎没什么关系了,这两块每个人的设计可能都会不尽相同,但并不会影响工作流引擎的使用。
这个页面还有一个委办的功能
后台逻辑:
bpm.NewDeputeService(user.Id, tarActorId) //委托人、受托人 .ForTaskInstance(taskInstanceId) //工作项ID .SetDateRange(effectDate,expireDate) //生效时间、失效时间 .SetMemo(memo) //委托备注 .Depute();
数据列表中的查询:
select * from bpm_instance_task where state = 'Complete' and actor_id = @user_id
仅仅一个查询页面,非常简单,双击时也打开表单展示页面,但是当前节点不是运行状态时是只能查看不能编辑的。
4、我的流程,这些页面都是一个数据查询页,没有什么逻辑,所以都很简单
催办逻辑:
//工作催办 var taskInstanceId = '当前运行节点实例id'; var task = bpm.LoadTaskInstance(taskInstanceId); task.Urge("很急,请经理尽快处理,在线等!");
数据列表查询:
select * from bpm_application_notify where reciever_id = @user_id and push_type = 'System'
数据列表查询:
select * from bpm_application_depute where src_actor_id = @user_id and effect_date <= @now and expire_date >= @now
三、流程定义及表单设计
这块的东西做到在页面上很方便的拖拉定义而且还要好用的话,是有一定难度的,其实我们有做一些页面尝试设计定义,但是都不好用而且很费时间折腾。其实这一块是开发人员使用的比较多,并不会影响客户使用,所以优先级靠后点,以后有精力再来开发。
我们现在的解决方案是,在项目目录下建了一个Definitions的目录:
每个流程新建一个目录,比如合同审批目录下存放,“流程定义.xml”及“合同审批表.cshtml”
对这个流程定义的修改,直接修改这两个文件即可,两个文件内容如下:
1、流程定义.xml
<?xml version="1.0" encoding="UTF-8"?> <process name="合同审批流程" category="项目流程"> <start name="合同审批开始" app-form="合同审批表.cshtml" app-enable-attach="true"> <transition to="项目负责人或材料负责人"></transition> </start> <task name="项目负责人或材料负责人" > <transition to="分管副总"></transition> <action script="log.Debug('项目负责人或材料负责人签字');"></action> <assignment owner="pan"></assignment> </task> <task name="分管副总" > <transition to="工程经营部"></transition> <action script="log.Debug('分管副总签字');"></action> <assignment owner="lhs"></assignment> </task> <task name="工程经营部" > <transition to="财务部"></transition> <action script="log.Debug('工程经营部签字');"></action> <assignment owner="pan"></assignment> </task> <task name="财务部" > <transition to="法务部"></transition> <action script="log.Debug('财务部签字');"></action> <assignment owner="yrh"></assignment> </task> <task name="法务部" > <transition to="常务副总"></transition> <action script="log.Debug('法务部签字');"></action> <assignment owner="czm"></assignment> </task> <task name="常务副总" > <transition to="总经理"></transition> <action script="log.Debug('常务副总签字');"></action> <assignment owner="zfg"></assignment> </task> <task name="总经理" > <transition to="合同审批结束"></transition> <action script="log.Debug('总经理签字');"></action> <assignment owner="lhs"></assignment> </task> <end name="合同审批结束"> </end> </process>
2、合同审批表.cshtml
<table class="form-body"> <colgroup> <col style="15%" /> <col style="35%" /> <col style="15%" /> <col style="35%" /> </colgroup> <tr> <td class="title" >所属项目</td> <td class="input">@Controls.Render("input","project_name")</td> <td class="title" >合同编号</td> <td class="input">@Controls.Render("input","contract_id")</td> </tr> <tr> <td class="title" >合同名称</td> <td class="input">@Controls.Render("input","contract_name")</td> <td class="title" >报批时间</td> <td class="input">@Controls.Render("datebox","audit_date")</td> </tr> <tr> <td class="title" >合同己方</td> <td class="input">@Controls.Render("input","contract_own")</td> <td class="title" >合同对方</td> <td class="input">@Controls.Render("input","contract_other")</td> </tr> <tr> <td class="title" >合同金额</td> <td class="input">@Controls.Render("input","amount_contract")</td> <td class="title" >预算金额</td> <td class="input">@Controls.Render("input","amount_budget")</td> </tr> <tr> <td class="title" >合作方式</td> <td class="input">@Controls.Render("input","procurement_method")</td> <td class="title" >合同份数</td> <td class="input">@Controls.Render("input","copies_contract")</td> </tr> </table>
修改完这两个文件后,运行“流程定义工具.bat”实现上是调用一个我写的控制台应用程序,输入“deploy 流程名称”即可完成发布
这样使用对于开发人员来说还是很方便的,但是对于不懂开发的人来说就有一定难度了
1、把xml编辑变成图形拖拉
2、把cshtml文件编辑变成控件拖拉
这两点我们以后再想办法实现,无论怎样,现在这样是可以使用了,除了自定义流程,其它都没有任何问题。
四、总结说明
这个示例程序是拿我们以前的项目UI来实现的,用什么界面都没问题,主要是给大家介绍下这款工作流引擎的实际应用。关于流程设计器及表单设计器这个我以后有时间间精力会慢慢开发。如果大家有什么意见或建议欢迎给我留言。