OA-审批流程控制数据库表的简单设计

OA-审批流程控制数据库表的简单设计

捡破烂的诗人 1,168 2023-02-06
  • 联系方式:1761430646@qq.com
  • 编写时间:2023年2月6日21:50:07
  • 博客地址:www.zeroeden.cn
  • 菜狗摸索,有误勿喷,烦请联系

前言

  • OA(office automation),简单来说就是做审批流程控制的
  • 写本文原由是实习期间做的是有关教务系统的东西,其核心也就是做审批流程控制,因此想写点东西出来小结小结(目前来说个人水平不咋地,写此文也是站在个人的角度上去写的,所以写的可能会很差,也会有错,勿喷
  • 此文重点在于数据库层面上的设计,实现逻辑上有牵扯到,但不多,目前不是很懂后端接口的实现逻辑(虽然能跑,但自己总想到其他乱七八糟的问题,后端接口怎么写好点还为想好),=后面有时间再研究再去补

1. 数据库设计

  • 主要是牵扯到三个表(业务表,审核主表,审核明细表)

1.1 业务表

  1. 实际上,对于某个系统来说,其审核的业务类型不仅仅只有一个

  2. 比如说有请假类型的,采购类型的等等

  3. 此业务表就是用来存储某种业务所拥有的信息的

  4. 也就是说你审批业务有多少种类,其业务表就对应有多个

  5. 本文我们会以请假类型的业务作为示例,所以此处的业务表就为请假表

  6. 就算是同一种类型的审批业务,对于不同的单位来说,所拥有的字段信息也是不同的,而本文重点又在于流程控制

  7. 所以此处为例的请假表我们知道有就行了(就不做字段设置了,实际生产环境需要用什么字段加上去即可),此表最重要的是其主键字段Id(为我们后面联表查询)

1.2 审核主表

  1. 审核主表主要是做一个总的流程控制管理的

  2. 该表设计如下

  • 讲讲为啥这样搞:

    • 主键id没啥好说的

    • 而审核类型audit_type和审批编号flow_no这是为了方便回找具体的业务记录信息的

      • 通常来说审核类型是具有多种的,为了减少其值在数据库中的占用,通常我们会采用映射方法表示其含义,如下图所示

        • 以至于通过审核类型audit_type的值,我们可以定位到具体的哪张业务表,然后在通过审批编号flow_no的值,作为对应业务表的主键id,寻找到对应记录,从而获取此业务相关信息。
    • 审核状态audit_status顾名思义表示总的审核状态,通常也是采用映射方法表示其含义,如下图所示

  • 实际上如果说系统只有一个请假的审核业务,业务表和审核主表是可以合在一起的(为啥?为了后续做各种功能实现时少写点SQL,多点时间摸鱼它不香么-.-

  • 注意:实际上应该还需增加几个字段,这里到后面引出问题时会自动补充(现在直接就给出来的话感觉不自然)

1.3 审核明细表

  • 审核明细表的记录实际上对应的是某个审核业务记录,每个审核节点的一些审核信息

  • 该表设计如下:

  • 讲讲为啥这样搞

    • 审核idaudit_id,是作为外键用来连接审核主表的id,表示当前记录从属于其对应的审核业务的起名困难症,这个不知道其啥名好,就瞎搞了个

    • 审核人idaudit_user_id,顾名思义,表明当前审核节点应该让谁来审核

    • 审核状态audit_status,表示当前审核节点的审核人审核结果,通常也是采用映射法来表示其含义

    • 其他字段也没啥好说的,如果实际需要,自己额外+字段即可

1.4 小结

  • 三个表之前的联系如下

    • 这样三个表之间的关系就串联起来了,通过某个审核业务记录id,可以查到对应审核状况,通过某条审核记录id,可以查看对应审核业务相关的信息

2. 所示

  • 在这里我们会通过一个员工请假审批的案例来描述数据库字段的变化(重点在于数据库的变化,后端接口逻辑处理这里不多说
  • 假设目前来说,此员工的请假审批节点为:小组长–>部门主任–>经理

2.1 员工发出申请

  1. 接口中获取前端传来的请假表单信息,在请假表中新增一条记录(对应字段信息填充上去即可)

  2. 在审核主表中同样新增一条记录表示有新的审核记录过来

    • id(主键):主键自增还是uuid,看个人

    • flow_no(审批编号):就是刚刚在请假表中新增记录的主键id

    • audit_type(审核类型):根据预先定义好的映射规则,凭借具体的审核类型做自动映射填充在实际开发中可能在controller层,一个接口对应一个审核类型业务,也可能一个接口对应多种审核类型业务,前者很好说,可以把映射规则定义成常量的形式–后面如果要改映射规则的话,直接改常量即可,方便后面维护,直接填充就好,而后者的话,实际上也可以让前端传来一个标志号,用来表示此审核业务的类型,后端拿到后再做具体分析填充)–不做映射,直接填充具体审核类型的名称也可以,看个人喜欢

    • audit_status(审核进度):现在是申请人发出申请,这里值毫无疑问是出于"待审",当然,按照个人习惯以及上述审核主表的设计,这里我也采用映射,也即此时值为"1"

  3. 最后则是轮到在审核明细表中新增记录了(这里有个【纠结点】,3个审核节点,一种是直接对应新增三条记录,还有就是一条记录一条记录增,这里为了方便描述,采用第一种方式,第二种方式会在后面说啥情况)

    • id(主键):主键自增还是uuid,看个人
    • audit_id(审核id):就是刚刚在审核主表中新增记录的主键id
    • audit_user_id(审核人id):分别把小组长部门主任经理的用户id查询出来填充到对应新增记录的字段值即可
    • audit_time(审核时间)、audit_opinion(审核意见)、audit_remark(审核备注):这些审核人都还没开始审呢,均为null
    • audit_status(审核状态):由于新增审核审批后,小组长作为第一个审核的节点,所以是"待我审核”,而部门主任经理需等待前审核节点的审核,所以均为"审核中",根据映射规则填充即可
  4. 注意:这是在同一事务中操作的

2.2 小组长审核同意

  1. 根据前端传来的具体业务记录的id,在审核主表中,审核明细表查的对应记录信息

  2. 审核明细表:

    • 根据前端传来的表单信息在小组长的记录中更改为对应字段值(如审核时间,审核意见等等,审核状态也即为"通过"映射的值3
    • 由于后续还有审核节点,因此此时需要再做多一步,将下一级审核结点(也就是将部门主任那条记录的审核状态改为"待我审核"映射的值2
  3. 审核主表(这里也有个小分类)

    • 后续还有审核节点:

      1. 也就是当前这种情况,后面还有部门主任经理这些审核节点
      2. 此时审核主表中的这条记录的audit_status审核进度字段就无需更改
    • 后续无审核节点:

      1. 当后面再无审核节点时
      2. 也就意味着,当前审核节点通过审核后,此审核业务记录总体上也是审核通过
      3. 此时需要把审核主表的这条记录的audit_status审核进度字段更改为"通过"映射的值3
  4. 注意:这里也是要在同一事务下

2.3 部门主任审核驳回

  1. 同理,根据前端传来的具体业务记录的id,在审核主表中,审核明细表查的对应记录信息

  2. 审核明细表:

    • 根据前端传来的表单信息,在部门主任的记录中更改为对应字段值(如审核时间,审核意见等等,此时的审核状态即为"驳回"映射的值4
  3. 审核主表:

    • 直接将对应记录的audit_status审核状态字段值改为“驳回”映射的值3即可
  4. 注意:这也需要再同一事务下

2.- 员工撤销申请

  • 模拟下员工撤销申请的操作

  • 在审核主表对应的记录中,将audit_status审核状态字段改为"撤销"映射的值4就好

  • 而审核明细表中对应的记录其实可以不用动(实际上每次对审核明细表对应记录做操作时,都需要把审核主表对应记录的audit_status字段值查出来,比较一下是否可操作,这是牵扯到后端接口的写法,还没有理清楚,这里重点在于描述数据库的字段值变化

2.- 谁审核的??

  1. 模拟下环境

  2. 假设员工发出请假申请后,隔了一段时间再登录系统查看审核情况

  3. 这也很好操作,直接把审核主表对应记录的audit_status审核状态显示出来即可

  4. 4个审核状态,通过撤销状态倒是很好理解

  5. 比如员工说想进一步了解,目前是待哪位领导审核,还是说想知道到底是哪位领导驳回了他的申请

  6. 此时就需要到审核明细表中查询所示了,审核明细表中的审核状态映射如下所示

  7. 想查待哪位领导审核,就可以通过审核主表对应记录的主键id以及"待我审核"映射的值2到审核明细表中查询,即可唯一确定一条记录,从而获取到用户id

  8. 想查哪位领导驳回了申请,同理查询即可

3. 存在问题

3.1 疑问点

  • 也即是在章节【2.1】中提到的,新发出申请在明细表中新增记录时,是直接新增三条还是一条一条新增
  • 新增三条意思很明显,一下子把所有审核结点的基础信息给添加上去
  • 这里特别解释下一条一条新增时啥含义:
    • 在审批流中,通常是只有存在一个流行结点(自己瞎定义的一个节点概念,不知道业界有没有这个专业术语)
    • 说人话就是只有待某个节点的那审核人审核后,才会进入下一节点的审核流程,在其审核的声明周期中,处于活跃状态的是只有一个结点
    • 也就代表前置审核节点未审核时,或者审核驳回时,后续节点的记录是没啥存在意义的
    • 而一条一条新增的含义,也就是待某个结点审核通过后,我才往明细表中添加下一节点的记录
  • 至于我在疑问啥?就是如果是直接采用发出申请时,新增三条记录这种形式的话
  • 那么如果第一结点审核驳回的话,后续两个结点的记录信息也就是多余的
  • 注意,这是我举例请假审核流程的三个节点出来的
  • 实际中,某种审核业务的审核节点可能有多个,也可能存在多种审核业务
  • 此时如果遭遇前置审核节点审核驳回的情况时,这时候审核明细表中这些记录的多余可能说就不能忽视了(虽然说实际上很可能是遇不到这种情况,或者说是不介意一点点硬盘的占用)
  • 而采用一条一条新增这种形式时,就不会采生如此诸多的多余记录,就是写后端接口时要稍微麻烦一丢丢,某个节点审核通过后,得主动找下一个审核节点
  • 在之前做一个HRM系统时,有接触到Actviti工作流引擎,了解到采用的就是这种一条一条新增的形式
  • 正如上述所说,直接新增三条这种形式造成多余的记录,虽然实际上影响是可以忽略不计的
  • 但是此时写出来,就是想提个醒,让自己知道,这种可能会造成的问题,要怎么优化(步是一点点进的)
  • 当然也可以骂我考虑复杂了

3.2 寻找下一节点

  • 特别注意,我们上述举的请假例子(只有3个审核节点)是很简化的,审核节点也是固定,不轻易更改的

  • 当某个审核结点通过后,我们即可知道下一个审核结点是谁,写其代码来也比较简单

  • 还是老实际,审核业务是有多种类型的,某种审核业务的审核结点也可能是比较长的

  • 如果还是这样做的话,在审核流程的代码中就得添加寻找下一节点业务代码,就有点乱了

  • 比如说一个具有十级审核节点的审核业务,当第五级节点审核通过后,就得去找第六级审核节点是谁,开发的时候分得清没啥问题,就是后面他人维护时就一脸懵逼了

  • 如何改呢?首先得往审核主表和审核明细表中新增几个字段,如下所示

    • totoal_point代表此审核业务总的审核结点数
    • now_point代表当前审核业务处于第几级审核结点处

    • now_point代表此记录处于第几级审核节点
  • 还是举请假的例子,当发出申请时(注意此时往审核明细表中添加记录时仍然采用一下子新增3条的形式)

    • 在审核主表中:
      • total_point值为3,代表共有3个审核节点
      • now_point值为1,代表目前审核流程处于第一个审核节点处
    • 在审核明细表中:
      • now_point:根据含义,小组长值为1,部门主任值为2,经理值为3
  • 小组长审核同意后,根据total_pointnow_point的联系,自然得知下一节点,改其中状态即可,代码中无需额外搞小动作

  • 同时根据经理审核同意后,又根据total_pointnow_point的联系,自然得知此时此审核业务记录已经总体通过

  • 这样一看,寻找下一节点问题似乎得到了解决

  • 看是一切挺好,但是还是有问题

  • 就是审核节点的确定,要知道就算是同一类型的审核业务,也可能会由于你所处的部门、职位不同,得到的审核节点是不一样的

  • 就比如经理请假的申请,可能需要总经理–>总裁的审核,而正常的员工请假申请,就需要比较多的审核节点

  • 当发出申请时,审核的总节点数以及每级的审核员到底如何确定呢?

    • 前端可视化选择
      • 也就是在系统上发出申请时,给个可视化界面列出领导信息,同时让申请人逐级往上选择各个审核领导
      • 后端接口收到请求时,就把所有审核节点信息给确定下来了
      • 这是比较好的解决方案,所处部门人员总会知道部门领导是谁,至于选到哪个职位的领导为最终节点,看实际情况
    • 在接口处逻辑处理
      • 这个有点相当于把问题转移了,把之前在具体的审核流程中寻找下一节点的问题转为在发出申请时就确定各个审核节点的问题

3.3 某节点审核是得具有某个职位的人员

  • 为啥有这个呢?这是在实习期间无意中碰到的一个点

  • 到现在这里,我们举的请假例子中,基本每个审核节点就是要特定的人员审核

  • 但是,并不是实际上都是这样的,就比如拿在实习期间碰到的例子为例,一个科研项目的申报,最初由所在院系辅导员审核,然后是学校科研部门管理员审核,最后是到所在院系院长

  • 问题就出在学校科研部门管理员身上,这个实际上是指具有这个职称/角色的人员,是不仅一个的

  • 也就是说具有学校科研部门管理员职称/角色的人,都可以审核

  • 按照我们之前的做法,是明显达到不了这个功能呢

  • 要做的话,其实也很简单,审核明细表中新增字段即可,如下图所示

  • 实际上这个字段应该也是玩映射的,举个例子如下所示

  • 这样的话根据此值来判断即可(主要是业务接口处的逻辑处理)

  • 至于如果值为2时,也就具有某个职称的人员均可审核时,这个职称的id号该存哪,再新增个字段来存也可以,也可以直接存在audit_user_id字段里,自己分的清楚就好,就是这么离谱

4. 小结

  • 不知道说啥
  • 这个用来做简单的OA应该没啥问题
  • 复杂一点的OA暂时没了解过
  • 之前了解到Activiti,是通过数据库中的数据来存储审核流程的
  • 好像也可以改成配置文件,诸如properties
  • 后面可以试一下能不能改-.-

参考

  1. 老炮说Java-老板要我开发一个OA多级审批流

# OA # 数据库设计 # 表设计