跳到主要内容

审批节点

审批节点(ApproveNode)是审批流中的人工审批环节,需要指定审批人进行审批操作。

概念说明

本文档是 平台接口 组件说明的一部分。会签规则、审批人动态角色与引擎行为的详细说明请参考 审批节点。

概述​

审批节点是审批流中的人工审批环节。一个审批节点需要指定审批人与会签方式,并可选配置通知模板、执行接口、审批表单、驳回 / 撤回 / 时间限制等高级能力。当节点有多个审批人时,会签方式决定该节点何时判定通过或拒绝。

配置项​

配置项必填说明
节点名称是显示在流程图上的名称,缺省为「审批节点」
副标题否节点名称下方的补充说明文本
会签方式是多个审批人的通过 / 拒绝规则,缺省为「所有人同意」
设置比例或人数条件必填会签方式为「超过x比例」「超过x人数」时出现,取值 0~100 的整数
审批人是通过高级选择器指定,可多选、可混合多种类型
审批人审批通知模板否审批人待办通知模板,留空使用系统默认模板
审批人点击同意后通知发起人模板否留空不发送
审批人点击不同意后通知发起人模板否留空不发送
节点同意后通知发起人模板否本节点判定通过时通知发起人,留空不发送
节点不同意后通知发起人模板否本节点判定拒绝时通知发起人,留空不发送
自定义执行前触发的接口否审批人操作前调用
自定义同意后触发的接口否本节点判定通过时调用
自定义不同意后触发的接口否本节点判定拒绝时调用
审批表单否审批人处理时使用的表单,仅可选择本对象下的表单
允许审批人驳回否开关,缺省关闭
驳回时的通知消息模板否开启驳回后出现
允许选择驳回目标节点否开关,缺省关闭;开启后可驳回至中间节点
允许发起人撤回否开关,缺省关闭
启用审批时间限制否开关,缺省关闭
审批开始时间 / 审批结束时间条件必填开启时间限制后出现
自定义错误信息否超出时间范围时的提示,留空使用系统默认文案

会签方式取值​

界面名称值(PassCondition)说明
所有人同意(任意一人不同意则拒绝)0全部审批人同意才通过,缺省值
任意一人同意(所有人不同意则拒绝)1任意一人同意即通过
任意一人同意或拒绝2任意一人表态即判定
超过x比例人员同意3同意人数占比达到设定比例即通过
超过x人数人员同意4同意人数超过设定人数即通过

选择「超过x比例人员同意」或「超过x人数人员同意」时出现「设置比例或人数」输入框。

审批人配置​

审批人通过高级选择器配置,可跨类型混合选择,支持人员、组织、档案、角色、组织负责人、审批用户选择、动态用户选择、接口用户选择等类型。会签方式与审批人的详细规则见 审批节点。

审批人必须可解析

审批人配置后,发起审批时会自动解析出每个节点的具体审批人。若任一节点解析不到具体审批人,流程发起会失败。

驳回与撤回​

配置项说明
允许审批人驳回开启后审批人可驳回;关闭则隐藏驳回按钮
驳回时的通知消息模板驳回后通知相关人员的模板
允许选择驳回目标节点开启后驳回可选择目标中间节点,否则默认驳回到发起人
允许发起人撤回开启后发起人可在流程进行中撤回

审批时间限制​

开启「启用审批时间限制」后,需设置审批开始时间与结束时间。审批人只能在时间窗口内处理该节点,超出范围会被拒绝提交并提示错误信息;未填自定义错误信息时使用系统默认文案。

下一步​

属性明细​

以下内容面向技术实现与 AI 检索,说明审批节点的节点元数据。所有值均为字符串。

节点元数据​

审批节点由 FlowCmpType.ApproveNode 标识:

属性名类型含义取值/存储值
typestring组件类型固定为 "ApproveNode"
Titlestring节点名称必填,缺省 "审批节点"
SubTitlestring副标题可为空
PassConditionstring会签方式"0"~"4",缺省 "0"
PercentOrPersonsstring比例或人数阈值数字字符串,如 "50";仅 PassCondition 为 "3"/"4" 时有效
Approverstring(JSON)审批人配置AdvancedSelectItem[] 的 JSON 字符串,必填
AssignApproversNotificationTemplateIdstring审批人审批通知模板 ID模板 ID,可为空
AgreeToLaunchUserNotificationTemplateIdForApproverOperationstring审批人点击同意后通知发起人模板 ID模板 ID,可为空
DisagreeToLaunchUserNotificationTemplateIdForApproverOperationstring审批人点击不同意后通知发起人模板 ID模板 ID,可为空
AgreeToLaunchUserNotificationTemplateIdForNodeFinishstring节点同意后通知发起人模板 ID模板 ID,可为空
DisagreeToLaunchUserNotificationTemplateIdForNodeFinishstring节点不同意后通知发起人模板 ID模板 ID,可为空
BeforeInterfaceIdstring自定义执行前触发的接口 ID标签为「功能」的接口 ID,可为空
AgreeInterfaceIdstring自定义同意后触发的接口 ID接口 ID,可为空
UnAgreeInterfaceIdstring自定义不同意后触发的接口 ID接口 ID,可为空
MetaFormIdstring审批表单 ID本对象下的表单 ID,可为空
DisplayReturnButtonstring(bool)允许审批人驳回"true" / "false"
ReturnMessageTemplateIdstring驳回时的通知消息模板 ID模板 ID,可为空
AllowSelectReturnTargetNodestring(bool)允许选择驳回目标节点"true" / "false"
AllowRevokestring(bool)允许发起人撤回"true" / "false"
EnableTimeLimitstring(bool)启用审批时间限制"true" / "false"
ApproveStartTimestring审批开始时间本地时间字符串
ApproveEndTimestring审批结束时间本地时间字符串
CustomTimeLimitErrorMessagestring超时自定义错误信息可为空
orderstring同级排序例:"4"

元数据存储示例​

{
"ID": "approve-node1",
"type": "ApproveNode",
"Title": "部门审批",
"SubTitle": "由部门负责人审批",
"PassCondition": "0",
"PercentOrPersons": "0",
"Approver": "[{\"type\":\"Role\",\"label\":\"部门负责人\",\"value\":\"role-dept\"}]",
"DisplayReturnButton": "false",
"AllowSelectReturnTargetNode": "false",
"AllowRevoke": "false",
"EnableTimeLimit": "false",
"order": "4"
}

数据源​

接口下拉通过 POST /api/DataSource/GetMetaInterfaceDataSource(extend.tags = "Function")获取,表单下拉通过 POST /api/DataSource/GetMetaFormDataSource 获取,通知模板下拉通过 POST /api/DataSource/GetMetaMessageTemplateDataSource 获取。

服务端执行逻辑​

审批节点由 ApproveNodeComponentManager 实现,继承 WorkflowComponentManagerBase,组件类型为 FlowComponentTypeEnum.ApproveNode。审批人在创建实例与进入节点两个时点各解析一次;会签判定在每次审批动作后按 PassCondition 重算。

元数据均为字符串

节点 meta 以 Dictionary<string, string> 存储,PassCondition、PercentOrPersons、Approver 等全部为字符串;Approver 是 AdvancedSelectItem[] 的 JSON 字符串,服务端读取后反序列化。

执行时机与场景​

时机入口说明
保存 / 发布校验_VerifyAsync校验 Title、Approver 并计入 FinalResultCount
发起审批(构建节点列表)_BuildAsync解析审批人并写入 NodeItems
流转到本节点_NotifyAsync置节点进行中,重新解析审批人并发送待办通知
审批人操作_ExecuteAsync处理同意 / 不同意 / 驳回 / 撤回,按会签规则判定节点完成
审批人配置变更重分配_ReAssignAsync发布新版本时刷新进行中实例的审批人

输入参数(meta 键)​

meta 键使用阶段含义
Title校验 / 构建节点名称,必填
SubTitle构建副标题
Approver校验 / 构建 / 通知 / 重分配审批人配置 JSON(AdvancedSelectItem[]),必填
PassCondition构建 / 判定会签方式,"0"~"4"
PercentOrPersons判定比例 / 人数阈值,PassCondition 为 "3"/"4" 时使用
AssignApproversNotificationTemplateId通知 / 重分配审批人待办通知模板
BeforeInterfaceId执行审批人操作前调用的接口
AgreeInterfaceId节点完成节点通过后调用的接口
UnAgreeInterfaceId节点完成节点拒绝后调用的接口
AgreeToLaunchUserNotificationTemplateIdForApproverOperation执行审批人同意后通知发起人
DisagreeToLaunchUserNotificationTemplateIdForApproverOperation执行审批人不同意后通知发起人
AgreeToLaunchUserNotificationTemplateIdForNodeFinish节点完成节点通过后通知发起人
DisagreeToLaunchUserNotificationTemplateIdForNodeFinish节点完成节点拒绝后通知发起人
ReturnMessageTemplateId驳回驳回时通知模板
EnableTimeLimit / ApproveStartTime / ApproveEndTime / CustomTimeLimitErrorMessage执行时间限制开关、起止时间与超时提示

审批请求 WorkflowOperationRequest 关键字段:Action(Agree / Disagree / Return / Revoke)、ApprovalOpinion、MetaFormId(审批表单)、ReturnTargetNodeId(驳回目标节点)、InstanceId。

审批人解析​

_BuildAsync 与 _NotifyAsync 都调用 IUserInformationService.GetAdvancedUserSelectorResultAsync,请求携带:

参数来源
Configmeta.SafeGet("Approver")
WorkflowLaunchUserIdflowData.LaunchUserId
BizDataIdsflowData.BizDataId
WorkflowId / MetaObjectCode / WorkflowDataIds实例字段
  • 解析结果按 UserId 写入该节点的 ApproverItems。
  • _BuildAsync 解析后仅入列表;_NotifyAsync 进入节点时重新解析最新审批人,若结果为空则置 flowData.IsNeedHandover = true(需要流程转交),否则按模板给审批人发送待办通知。
  • 进入节点后调用 RefreshPendingApproverUserIds 刷新实例的 PendingApproverUserIds(审批中心「待我审批」查询用)。

会签判定规则​

UpdateApproverItem 先把当前登录人(UserId)对应的 ApproverItems 项置为已处理(写 HandleTime、Opinion、Result);若该项已处理则抛 YouHaveAlreadyProcessedThisApproval,若找不到则抛 CurrentUserApprovalNodeNotFound。随后 AgreeNodeActionAsync / DisagreeNodeActionAsync 按 PassCondition 判定节点是否完成:

PassCondition同意后节点通过拒绝后节点拒绝
0 所有人同意全部 Agree存在任一 Disagree
1 任意一人同意存在任一 Agree全部 Disagree
2 任意一人同意或拒绝存在任一 Agree存在任一 Disagree
3 超过 x 比例同意ceil(同意数 / 总数 × 100) >= PercentOrPersonsceil(同意数 / 总数 × 100) > (100 - PercentOrPersons)
4 超过 x 人数同意同意数 > PercentOrPersons拒绝数 > (总数 - PercentOrPersons)

节点判定通过时:节点项 Status = Approved,移除未处理审批人,flowData.Status = Approved,进入 FinishNodeAsync;判定拒绝时节点项 Status = Rejected,flowData.Status = Rejected,同样进入 FinishNodeAsync。比例计算使用 Math.Ceiling 向上取整。

审批动作执行步骤(_ExecuteAsync)​

  1. 要求 context.Result 为 WorkflowData、context.Param 为 WorkflowOperationRequest。
  2. 读取 BeforeInterfaceId,非空则先调用该接口;request.MetaFormId 非空则调用 IDefaultMetaBizDataApp.DefaultEditAsync。
  3. 按 request.Action 分支:
Action处理
Agree校验时间限制 → UpdateApproverItem(Agree) → 校验 OpinionRequiredWhenAgree → AgreeNodeActionAsync → 按模板通知发起人
Disagree校验时间限制 → UpdateApproverItem(Disagree) → 校验 OpinionRequiredWhenDisagree → DisagreeNodeActionAsync → 按模板通知发起人
ReturnUpdateApproverItem(Disagree) → 校验 OpinionRequiredWhenReturn → 见「驳回」
Revoke删除本节点未审批待办、关闭剩余待办 → flowData.Status = Revoked → PendingApproverUserIds = [] → FinishAsync
其他抛 UnknownApprovalOperationType
  1. 动作处理完成后刷新 PendingApproverUserIds,关闭当前用户的待办数据。

驳回处理​

Return 动作分两种场景:

  • 驳回至指定中间节点:request.ReturnTargetNodeId 解析成功且目标节点类型为 ApproveNode 时,关闭当前用户待办、批量删除未处理待办、给目标节点审批人发通知;对「目标节点及其后所有节点」执行 Reset()(清空进入 / 完成时间、状态与审批人处理结果);把 context.CurrentNode 强行指到目标节点的上一个节点,调用 FinishAsync 后 NotifyNextAsync,从而把流程重新路由回目标节点并中断后续逻辑。
  • 驳回至发起人:节点项 Status = Returned,移除未处理审批人,flowData.Status = Returned,通知发起人后 FinishAsync。

目标节点不存在时抛 TargetNodeNotFound。

节点完成与流转(FinishNodeAsync)​

  1. 读取 AgreeInterfaceId / UnAgreeInterfaceId 与节点完成通知模板,置该节点项 FinishedTime 并加载流程定义。
  2. 批量删除该节点未处理的待办数据。
  3. 按节点结果选择接口(通过取 AgreeInterfaceId,否则取 UnAgreeInterfaceId)调用 CallMetaInterfaceAsync。
  4. 通过:按模板通知发起人,调用 NotifyNextAsync 流转到 NodeItems 中的下一个节点。
  5. 拒绝:移除所有节点中未处理的审批人,通知发起人,调用 FinishAsync 结束实例。

审批时间限制(ValidateTimeLimit)​

仅当 EnableTimeLimit == "true" 且起止时间均可解析时生效:取当前 UTC 时间,早于 ApproveStartTime 或晚于 ApproveEndTime 时抛异常,提示文案优先取 CustomTimeLimitErrorMessage,为空则用本地化默认文案 NotWithinAllowedTimePeriod。

上下文写入与实例状态​

目标写入值
节点项 StatusInProgress / Approved / Rejected / Returned
节点项 EntryTime / FinishedTime进入 / 完成时间(UTC)
节点项 ApproverItems审批人及各自的 Result(NotHandle / Agree / Disagree)、Opinion、HandleTime
flowData.StatusInProgress / Approved / Rejected / Returned / Revoked
flowData.CurrentNode当前节点 Id
flowData.PendingApproverUserIds当前节点未处理审批人
flowData.IsNeedHandover解析不到审批人时为 true

驳回至指定节点被重置的节点项通过 WorkflowDataNode.Reset() 与 WorkflowDataNodeApproverItem.Reset() 清空。

审批人重分配(_ReAssignAsync)​

发布新版本且审批人配置发生变化时触发:仅当 request.ReAssignNodeId == 当前节点 Id == flowData.CurrentNode、实例 Status == InProgress、节点项存在且 Status == InProgress 时处理。重新解析审批人后:

  1. 计算需新增 / 移除的审批人(仅移除仍为 NotHandle 者)。
  2. 无任何变更则直接返回;否则删除移除者的待办、为新增者发通知。
  3. 重新执行同意判定,若节点仍为 InProgress 再执行一次拒绝判定,避免节点卡死。
  4. 刷新 PendingApproverUserIds,并置 context.DicParam["HasReAssignApproverUserIds"] = "true" 标记有变更。

异常与校验​

场景异常 / 提示
节点 meta 为空ApprovalNodeMetaDataError
未设置节点名称ApprovalNodeNameNotSet
未设置审批人ApprovalNodeApproverNotSet
审批人 JSON 非法或为空ApprovalNodeApproverDataError
实例不存在ApprovalInstanceNotFound
审批参数缺失ApprovalRequestParamError
当前用户不在审批节点CurrentUserApprovalNodeNotFound
重复处理审批YouHaveAlreadyProcessedThisApproval
意见必填未填ApprovalOpinionRequired
超出审批时间范围自定义文案或 NotWithinAllowedTimePeriod
驳回目标节点不存在TargetNodeNotFound
未知审批操作UnknownApprovalOperationType

相关实现​

项位置
组件管理器ApproveNodeComponentManager(Components/Managers/WorkFlow/)
审批人解析IUserInformationService.GetAdvancedUserSelectorResultAsync
会签 / 驳回 / 完成AgreeNodeActionAsync、DisagreeNodeActionAsync、Return 分支、FinishNodeAsync