# 开发审批应用

接下来以开发【合同管理】为例,介绍整个过程。

# 创建实体

创建合同实体(Contract),包含以下的字段:

查看代码 (Contract.json)
{
  "name": "Contract",
  "packageName": "",
  "title": "合同",
  "tableName": "contract",
  "fields": {
    "id": {
      "name": "id",
      "packageName": "",
      "title": "唯一ID",
      "primaryKey": true,
      "autoIncrement": false,
      "type": "VARCHAR",
      "length": 36,
      "nullable": false,
      "columnName": "id",
      "insertable": true,
      "updatable": true,
      "order": 1
    },
    "name": {
      "name": "name",
      "packageName": "",
      "title": "合同名称",
      "autoIncrement": false,
      "type": "VARCHAR",
      "length": 150,
      "nullable": true,
      "columnName": "name",
      "insertable": true,
      "updatable": true,
      "sortable": true,
      "filterable": true,
      "searchable": true,
      "order": 2
    },
    "code": {
      "name": "code",
      "packageName": "",
      "title": "合同编码",
      "autoIncrement": false,
      "type": "VARCHAR",
      "length": 50,
      "nullable": true,
      "columnName": "code",
      "insertable": true,
      "updatable": true,
      "sortable": true,
      "filterable": true,
      "searchable": true,
      "order": 3
    },
    "salesId": {
      "name": "salesId",
      "packageName": "",
      "title": "销售经理 ID",
      "autoIncrement": false,
      "type": "VARCHAR",
      "length": 36,
      "nullable": true,
      "columnName": "sales_id",
      "insertable": true,
      "updatable": true,
      "sortable": true,
      "filterable": true,
      "order": 4
    },
    "deptId": {
      "name": "deptId",
      "packageName": "",
      "title": "所属部门 ID",
      "autoIncrement": false,
      "type": "VARCHAR",
      "length": 36,
      "nullable": true,
      "columnName": "dept_id",
      "sortable": true,
      "filterable": true,
      "order": 5
    },
    "description": {
      "name": "description",
      "packageName": "",
      "title": "合同描述",
      "autoIncrement": false,
      "type": "VARCHAR",
      "length": 2000,
      "nullable": true,
      "columnName": "description",
      "sortable": true,
      "filterable": true,
      "order": 6
    },
    "signDate": {
      "name": "signDate",
      "packageName": "",
      "title": "签约日期",
      "autoIncrement": false,
      "type": "TIMESTAMP",
      "length": 19,
      "nullable": true,
      "columnName": "sign_date",
      "sortable": true,
      "filterable": true,
      "order": 7
    },
    "status": {
      "name": "status",
      "packageName": "",
      "title": "合同状态",
      "autoIncrement": false,
      "type": "VARCHAR",
      "length": 15,
      "nullable": true,
      "columnName": "status",
      "sortable": true,
      "filterable": true,
      "order": 8
    },
    "tenantId": {
      "name": "tenantId",
      "packageName": "",
      "title": "租户号",
      "autoIncrement": false,
      "type": "VARCHAR",
      "length": 60,
      "nullable": true,
      "columnName": "tenant_id",
      "sortable": true,
      "filterable": true,
      "defaultValue": "#vars.tenant_id",
      "order": 9
    },
    "isDeleted": {
      "name": "isDeleted",
      "packageName": "",
      "title": "是否删除",
      "autoIncrement": false,
      "type": "BIT",
      "length": 1,
      "nullable": true,
      "columnName": "is_deleted",
      "sortable": true,
      "filterable": true,
      "columnDefault": "0",
      "order": 10
    },
    "createdBy": {
      "name": "createdBy",
      "packageName": "",
      "title": "创建人",
      "autoIncrement": false,
      "type": "VARCHAR",
      "length": 36,
      "nullable": true,
      "columnName": "created_by",
      "sortable": true,
      "filterable": true,
      "defaultValue": "#vars.user.id",
      "order": 11
    },
    "createdByName": {
      "name": "createdByName",
      "packageName": "",
      "title": "创建人姓名",
      "autoIncrement": false,
      "type": "VARCHAR",
      "length": 150,
      "nullable": true,
      "columnName": "created_by_name",
      "sortable": true,
      "filterable": true,
      "defaultValue": "#vars.user.name",
      "order": 12
    },
    "createdAt": {
      "name": "createdAt",
      "packageName": "",
      "title": "创建时间",
      "autoIncrement": false,
      "type": "TIMESTAMP",
      "length": 19,
      "nullable": false,
      "columnName": "created_at",
      "sortable": true,
      "filterable": true,
      "columnDefault": "now(3)",
      "defaultValue": "#vars.now",
      "order": 13
    },
    "updatedBy": {
      "name": "updatedBy",
      "packageName": "",
      "title": "更新人",
      "autoIncrement": false,
      "type": "VARCHAR",
      "length": 36,
      "nullable": true,
      "columnName": "updated_by",
      "sortable": true,
      "filterable": true,
      "defaultValue": "#vars.user.id",
      "updateValue": "#vars.user.id",
      "order": 14
    },
    "updatedByName": {
      "name": "updatedByName",
      "packageName": "",
      "title": "更新人姓名",
      "autoIncrement": false,
      "type": "VARCHAR",
      "length": 150,
      "nullable": true,
      "columnName": "updated_by_name",
      "sortable": true,
      "filterable": true,
      "defaultValue": "#vars.user.name",
      "updateValue": "#vars.user.name",
      "order": 15
    },
    "updatedAt": {
      "name": "updatedAt",
      "packageName": "",
      "title": "更新时间",
      "autoIncrement": false,
      "type": "TIMESTAMP",
      "length": 19,
      "nullable": false,
      "columnName": "updated_at",
      "sortable": true,
      "filterable": true,
      "columnDefault": "now(3)",
      "defaultValue": "#vars.now",
      "updateValue": "#vars.now",
      "order": 16
    }
  },
  "relations": {},
  "indexes": {},
  "onEvents": {}
}

# 生成接口

实体生成后,需要创建实体的CRUD接口。

# 开发页面

开发合同管理功能,主要包括,合同列表、新增合同和修改合同。 可以在此下载:合同管理页面 (opens new window) 放到 app/modules 目录下。

除此之外,里面的【流程表单】,该页面是需要在流程设计器中进行绑定,将会在【我的申请】【我的审批】中查看【审批信息】的时候呈现。

⚠️注意:在流程表单页面的外层使用流程表单容器组件,可以在审批页面自动生成操作按钮。

流程表单页面可以获得如下参数:

  • businessKey:业务数据ID(编排发起流程时传入的数据)
  • processInstanceId:流程实例ID

页面获取参数的方式为:request.params.businessKeyrequest.params.processInstanceId

# 设计流程

下面演示如何创建一个合同审批流程,包含三个步骤:拟稿、部门经理审批、财务审批。

# 1.全局配置

创建完一个新的流程后,在设计界面的右侧栏,可以修改流程名称和流程Key。

⚠️注意:当前版本需要保证流程Key的全局唯一性,不能与其他应用的流程Key重复,后续版本会增加应用租户支持。

# 2.流程表单

表单主要用于填报数据,并且带有数据的协作功能,如修改,删除,导入,导出。也就是说没有设置特定的表单权限的情况下,申请人和每一个环节的审批人都有权限对表单的字段进行修改操作。表单可以给不同的人不同的管理权限。

  • 流程级表单:流程中每个环节审批时都默认使用这个表单,也就是说流程级的表单贯穿整个流程的流转,如上图所示,点击空白区域,就可以在全局页面中设置流程级表单
  • 环节级表单:没配置表单的环节,默认使用流程级表单,环节配置了表单,在这个环节审批时,使用这个特定的表单

# 3.用户任务

用户任务是流程中需要用户来操作的任务。在这个任务中需要设置审批人,也称为候选人,用户任务只有通过审批人处理了才能进行流程的流转。本例中的部门经理审批、财务审批就是用户任务。

# 4.设置审批人

这里支持多种类型的人员,用户、部门、角色等。

如果涉及到审批人是根据业务动态计算的,请参考流程动态参与者

# 5.服务任务

服务任务用于在流程运行中自动执行一些业务逻辑,无需人工参与,常见场景包括调用外部接口、写回业务数据、发送通知等,以上业务功能在本平台中通过编排函数来实现。服务任务环节调用编排函数处理完成后返回结果,流程继续流转。

# 用法实践

此处用例子帮助大家了解服务任务的用法。场景如下:流程定义中增加一个服务任务环节,触发函数编排,在函数编排里调用远程接口获取SSO的版本信息,将结果写到流程变量,流程继续往下流转,在排他网关环节根据SSO的版本信息来决定流程的分支流向。

  • 创建编排:创建一个给服务任务调用的编排函数,调用远程接口:https://dfuse.bingosoft.net/workflow/api/web.json,从里面拿到SSO运行版本(auth2.serverVersion)。此处需要特别注意,编排的返回结果要放入流程变量,长度有限制,可以通过下图所示的方式,用输出结果过滤器只返回需要用于后续业务逻辑的内容。
  • 环节配置:选择刚刚创建的编排用于服务环节的触发动作,通过设置结果变量名,写回到流程变量,用于后续环节使用。
  • 结果使用:通过服务任务环节返回的结果进行条件判断,控制网关的分支流向。

# 发起流程

设想一个场景,在填写完合同申请表单后,需要发起一个【合同申请流程】的动作,这个动作的发起有两种做法,一是直接调用API接口发起流程、二是通过实体事件发起流程。推荐使用第二种做法。

# 基于实体事件发起流程

# 1.创建编排函数

在低代码的编排模块中提供了发起流程的组件,通过创建一个发起流程的编排函数,就可以便捷的实现流程的发起动作。

  • 通过实体事件的方式调用编排函数,会将实体数据通过上下文参数的方式传入进来,参数key为entity
  • 流程定义Key 选择前文设计的流程
  • 绑定流程实体信息,上图例子中把流程名称设置为实体的name字段${.entity.name},业务数据id设置的是实体的id字段${.entity.id}

# 2.添加实体监听事件

配置实体的【创建后执行】的事件,执行的方式是调用上文创建的编排函数。


至此,【合同管理】就可以实现合同申请过程的流转了。更多的开发指引,将会在后续的章节中呈现。

# 流程自动发布配置

通过配置以下参数,可以启用流程应用的自动发布功能,初次部署或后续更新,都无需在IDE的流程设计页面手动发布流程定义。

services:
  workflow:
    startupAutoPublish: true
顶部