zoukankan      html  css  js  c++  java
  • 企业级工作流解决方案(十六)--工作流--工作流实体模型

      DDD思想强调先有领域实体模型定义,再有数据库设计,数据库只是做为领域模型的一种持久化介质,但是在工作中,还是习惯性的先做数据库设计,再翻译成领域实体模型。所有我还是以数据库设计为起点,讲解工作流整体设计思路。

      数据库设计的重要性就不用强调了,设计库设计最能反映应用程序的功能和设计思想。

      工作流数据库设计图:

    数据库设计详细说明:

    多租户

       所有的表都有租户Id,即TenantId,托管于Abp租户管理。

    业务表单(WF_FlowForm)

      业务表单是流程引擎与业务之前的桥梁,有两个核心的字段,RoutePrefix和RpcServicePrefix。我这里设计的流程引擎,表单信息定义在一个Xml文件里面,流程定义的时候会读取Xml文件对应的表单模版,运行时也会读取表单模版,并把运行时的值赋值给表单模版里面的字段。RoutePrefix即表单的标识,根据此标识读取Xml实体内容,发起流程的时候,也是根据此标识找到流程定义,发起对应的流程实例。RpcServicePrefix为表单微服务前缀,流程引擎定义业务表单需要实现的接口,流程运行时,由流程引擎在特定的过程中,拼接调用表单微服务的方法,比如在用户提交审批时,流程引擎拼接保存表单微服务方法“RpcServicePrefix.Send”,方法参数和返回值与接口定义的相同,则可以动态的调用到表单的Send服务方法。Xml定义举例如下:

    <FrameworkTemplates>
      <FrameworkTemplate Name="OA_Vacation" Type="DomainEntity" DataTableName="OA_Vacation" Inherit="BusinessFullAuditedEntity&lt;int&gt;, IMayHaveTenant, IBusinessEntity">
        <TemplateItem>
          <Field>Id</Field>
          <CnName>主键</CnName>
          <Type>int</Type>
          <IsRequred>false</IsRequred>
        </TemplateItem>
        <TemplateItem>
          <Field>Reason</Field>
          <CnName>请假原因</CnName>
          <Type>string</Type>
          <IsRequred>true</IsRequred>
          <MaxLength>500</MaxLength>
        </TemplateItem>
        <TemplateItem>
          <Field>StartTime</Field>
          <CnName>请假开始时间</CnName>
          <Type>datetime</Type>
          <IsRequred>true</IsRequred>
        </TemplateItem>
        <TemplateItem>
          <Field>EndTime</Field>
          <CnName>请假结束时间</CnName>
          <Type>datetime</Type>
          <IsRequred>true</IsRequred>
        </TemplateItem>
        <TemplateItem>
          <Field>VacationDay</Field>
          <CnName>请假时长</CnName>
          <Type>float</Type>
          <IsRequred>true</IsRequred>
        </TemplateItem>
        <TemplateItem>
          <Field>Remark</Field>
          <CnName>备注</CnName>
          <Type>string</Type>
          <IsRequred>false</IsRequred>
          <MaxLength>4000</MaxLength>
        </TemplateItem>
      </FrameworkTemplate>
    </FrameworkTemplates>

     流程类型(WF_FlowType)

      流程定义的分类,树形结构,方便分类管理。

    流程定义(WF_FlowDefine)

      流程定义表,先有流程定义,才能根据流程定义发起对应的流程实例。

      WorkflowFormId定义表单外键,RoutePrefix和RpcServicePrefix为表单定义带过来的数据,所用见流程表单描述;FlowDefineStatus为流程定义状态,可以为草稿、已发布、取消发布三种状态,草稿状态只能有一条数据,已发布的状态也只能有一条数据,已发布状态的工作流可以取消发布,发起流程实例时,只找到此流程定义发布状态的记录发起流程实例,修改了流程状态对已发起的流程实例不影响;FlowDefineId为流程定义的Id,区别于主键Id,一个流程定义可能有多个版本,可能有多种状态,数据库可能对应多条记录,但是他们的流程定义Id都是相同的。

      FlowDefine为整个工作流的WWF内容Xml格式存储,WWF工作流定义是以Xml格式的形式存储的,包括了设计器定义的活动信息和连线信息,设计时根据此字段还原之前的设计状态,还会存储工作流变量信息,活动自定义的数据信息,比如审批活动定义的任务分配规则、任务路由选择规则、活动表单权限控制规则等,发起流程实例时,也是读取此字段内容来发起工作流实例,运行时流程定义图也是根据这里面的内容画出来的。

    流程实例表(WF_FlowInstance)

      流程实例表即为发起的流程实例,一个流程定义对应多个流程实例,FormId存储的是运行时表单的Id,根据此字段与业务运行时表单数据进行关联,InstanceState为实例状态,可以为运行中、已完成、已暂停、已恢复。其他字段看名字应该知道意思。

    流程审批项(WF_FlowItem)

      解析运行时活动对应的处理人信息,一个流程实例对应多条流程审批项信息,流程引擎运行时,解析活动规则,审批活动给每一个审批人增加一条审批项信息,活动审批结束,流程引擎自动回收其他未处理的审批信息。TaskId字段为Guid类型,每一个活动的TaskId相同,TaskId定义为WWF里面的书签,审批的过程中,根据TaskId书签还原工作流运行时;TaskType为任务类型,可以为审批人、任务转发、传阅、自动审批、任务委托;TaskState为审批项状态,可以为未处理、处理完成、自动完成、已过期、已阅、自动回收;PartId和PartName为审批人Id和名称;

    WWF流程跟踪(WF_FlowWFTrack)

      WWF流程运行时可以记录他里面的活动运行时信息,这张表的作用是运行时根据他动态的展示流程跟踪图,他会记录活动执行的先后顺序,并根据ActivityId与流程定义的ActivityId关联起来,在流程定义图上动太的画出流程执行过程。前端页面根据JS代码,动态的画出流程跟踪。

     

    流程跟踪(WF_FlowTrack)

      活动审批信息存储在此表中,包括用户选择的路由规则或者表单执行的路由规则,活动审批时,先要试运行工作流,找到下一步骤审批人的信息,试运行工作流时,是从活动第一步骤开始的,那么可以根据这张表的数据,还原工作流实例运行过程,并计算出下一审批活动信息。

    流程文档(WF_UploadFiles)

      每一个流程实例可以挂一些流程相关的文档,统一保存在这里。

    这里只描述了比较核心的部分,具体的功能在后面的文章继续分解。

  • 相关阅读:
    二分查找
    Linux下查找目录中所有文件中含有某个字符串,并且只打印出文件名
    编码规范
    Cookie和Session的选择,以及如何解决分布式系统下各个服务器之间Session不统一的问题
    Mac VMware Fusion 11.5 虚拟机带密钥
    快速排序
    python装饰器
    商品详情页
    hadoop跑wordcount报expected org.apache.hadoop.io.Text, received org.apache.hadoop.io.LongWritable
    CentOS7设置共享文件夹不显示问题
  • 原文地址:https://www.cnblogs.com/spritekuang/p/10845841.html
Copyright © 2011-2022 走看看