• 我的微型工作流引擎-办公应用实战


    一、前言

        前面已经给大家介绍了我的工作流引擎的总体设计及的API设计,这篇是实战篇说说怎么实际应用了,这就得涉及到UI界面了。首先我们常用的工作流个人办公应用系统至少要包括发起流程、待办事项、已办事项等。我们设计了一个尽量简单的系统,能够满足个人办公的基本需求,只实现以下功能:
        1、发起流程
        2、待办事项
        3、已办事项
        4、我的流程
        5、我的消息
        6、我的委办

    这些功能基本就是流程能正常的运行流转基础,其实只应用了我们引擎的一小部分功能,其它功能如果有需要可以在这基本上再添加。

    二、页面设计及实现

        1、发起流程,很简单的一个页面,左边显示已发布流程列表,右边放置一个iframe用于显示对应的启动表单image

    左边流程列表数据:

    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();

    2、待办事项,也就是我的任务工作的列表image

    列表的数据查询:

    select * 
      from bpm_instance_task
     where state = 'Run'
       and actor_id = @user_id

    双单或点击办理时,打开表单展示页面:
    表单审批页签,在这里可以查看表单录入的数据,查看历史审批情况,或进行审批操作,可设置签章
    image

    当然每个审批节点都可以有自己的表单也可以通过参数,来控制以下各元素的是否需要显示:审批选项、审批意见、添加附件、指定下一步审批人
    image
    按钮逻辑
    保存即只保存表单数据怎么保存可以自己定义
    转交下一步逻辑:

    //加载任务实例
    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();

    基本信息页签:
    image

    流程图页签:
    image

    流程图是我通过raphaeljs实现的,接收工作项及路由(连接线)的数据展现图形,根据数据自动计算每个工作任务的位置和连线,目前只实现了图形展示功能,还没有去实现拖拉设计的功能。
    image

    关于我的表单的设计和流程图的展示,后续有时间我会跟大家详细介绍。不过这和工作流引擎没什么关系了,这两块每个人的设计可能都会不尽相同,但并不会影响工作流引擎的使用。
    这个页面还有一个委办的功能
    image

    后台逻辑:

    bpm.NewDeputeService(user.Id, tarActorId)    //委托人、受托人
       .ForTaskInstance(taskInstanceId)          //工作项ID
       .SetDateRange(effectDate,expireDate)      //生效时间、失效时间
       .SetMemo(memo)                            //委托备注
       .Depute();

    3、已办事项,即我的已完成的工作列表
    image

    数据列表中的查询:

    select * 
      from bpm_instance_task
     where state = 'Complete'
       and actor_id = @user_id

    仅仅一个查询页面,非常简单,双击时也打开表单展示页面,但是当前节点不是运行状态时是只能查看不能编辑的。

    4、我的流程,这些页面都是一个数据查询页,没有什么逻辑,所以都很简单
    image
    催办逻辑:

    //工作催办
    var taskInstanceId = '当前运行节点实例id';
    var task = bpm.LoadTaskInstance(taskInstanceId);
    task.Urge("很急,请经理尽快处理,在线等!");

    5、我的消息
    image

    数据列表查询:

    select * 
      from bpm_application_notify
     where reciever_id = @user_id
       and push_type = 'System'

    6、我的委托
    image

    数据列表查询:

    select * 
      from bpm_application_depute
     where src_actor_id = @user_id
       and effect_date <= @now
       and expire_date >= @now

    三、流程定义及表单设计

        这块的东西做到在页面上很方便的拖拉定义而且还要好用的话,是有一定难度的,其实我们有做一些页面尝试设计定义,但是都不好用而且很费时间折腾。其实这一块是开发人员使用的比较多,并不会影响客户使用,所以优先级靠后点,以后有精力再来开发。
        我们现在的解决方案是,在项目目录下建了一个Definitions的目录:
    image
    每个流程新建一个目录,比如合同审批目录下存放,“流程定义.xml”及“合同审批表.cshtml”
    image
    对这个流程定义的修改,直接修改这两个文件即可,两个文件内容如下:
    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 流程名称”即可完成发布
    image

    这样使用对于开发人员来说还是很方便的,但是对于不懂开发的人来说就有一定难度了
    1、把xml编辑变成图形拖拉
    2、把cshtml文件编辑变成控件拖拉
    这两点我们以后再想办法实现,无论怎样,现在这样是可以使用了,除了自定义流程,其它都没有任何问题。

    四、总结说明

        这个示例程序是拿我们以前的项目UI来实现的,用什么界面都没问题,主要是给大家介绍下这款工作流引擎的实际应用。关于流程设计器及表单设计器这个我以后有时间间精力会慢慢开发。如果大家有什么意见或建议欢迎给我留言。

  • 相关阅读:
    【转】全国各地做生意十年的心得,忍不住上来感慨一下,诚信才是根基!
    pbootcms常用标签
    wordpress常用标签
    表格
    dedecms忘记后台密码
    新手建站基础步骤
    zblog常用插件及操作步骤
    织梦建站如何添加视频文件
    #Centos7.4#Shell中判断语句if中-z至-d的意思
    #Centos7.4#Linux虚拟机KVM配置网卡【Requested operation is not valid: network 'br0' is not active】
  • 原文地址:https://www.cnblogs.com/xqin/p/4845605.html
Copyright © 2020-2023  润新知