一、前言 前面已经给大家介绍了我的工作流引擎的总体设计及的API设计,这篇是实战篇说说怎么实际应用了,这就得涉及到UI界面了。首先我们常用的工作流个人办公应用系统至少要包括发起流程、待办事项、已办事项等。我们设计了一个尽量简单的系统,能够满足个人办公的基本需求,只实现以下功能: 1、发起流程 2、待办事项 3、已办事项 4、我的流程 5、我的消息 6、我的委办 这些功能基本就是流程能正常的运行流转基础,其实只应用了我们引擎的一小部分功能,其它功能如果有需要可以在这基本上再添加。
一、前言
前面已经给大家介绍了我的工作流引擎的总体设计及的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="width:15%" />
<col style="width:35%" />
<col style="width:15%" />
<col style="width: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来实现的,用什么界面都没问题,主要是给大家介绍下这款工作流引擎的实际应用。关于流程设计器及表单设计器这个我以后有时间间精力会慢慢开发。如果大家有什么意见或建议欢迎给我留言。