跳到主要内容

实例运行时

实例生命周期​

提交 → 运行中 → 同意/拒绝 → 已同意/已拒绝
→ 撤回 → 已撤回
→ 回退 → 已退回
→ 终止 → 已终止
已撤回/已退回 → 重新提交 → 运行中(再次)

运行时状态机只声明以下实例状态流转:

FromTo
runningapproved
runningrejected
runningwithdrawn
runningterminated
runningreturned
returnedrunning
returnedterminated
returnedwithdrawn
withdrawnrunning
withdrawnterminated

实例状态​

状态常量Wire value是否终态
运行中InstanceRunningrunning否
已同意InstanceApprovedapproved是
已拒绝InstanceRejectedrejected是
已撤回InstanceWithdrawnwithdrawn否
已退回InstanceReturnedreturned否
已终止InstanceTerminatedterminated是

枚举类型是 InstanceStatus。

任务状态​

状态常量Wire value是否终态
等待中TaskWaitingwaiting否
待处理TaskPendingpending否
已同意TaskApprovedapproved是
已拒绝TaskRejectedrejected是
已办理TaskHandledhandled是
已转交TaskTransferredtransferred是
已回退TaskRolledBackrolled_back是
已取消TaskCanceledcanceled是
已移除TaskRemovedremoved是
已跳过TaskSkippedskipped是

运行时状态机只声明以下任务状态流转:

FromTo
waitingpending
waitingcanceled
waitingskipped
waitingremoved
pendingapproved
pendinghandled
pendingrejected
pendingtransferred
pendingrolled_back
pendingcanceled
pendingwaiting
pendingremoved

操作类型​

操作常量Wire value说明
提交ActionSubmitsubmit发起新实例
同意ActionApproveapprove审批通过
办理ActionHandlehandle完成办理任务
拒绝ActionRejectreject审批拒绝
转交ActionTransfertransfer转交给其他用户
撤回ActionWithdrawwithdraw申请人撤回
取消ActionCancelcancel取消任务
回退ActionRollbackrollback退回到上一节点
加签ActionAddAssigneeadd_assignee动态添加审批人
减签ActionRemoveAssigneeremove_assignee移除审批人
加抄送ActionAddCCadd_cc动态添加抄送人
执行ActionExecuteexecute自动节点处理使用的内部执行动作
重新提交ActionResubmitresubmit重新提交已退回或已撤回的实例
改派ActionReassignreassign管理员改派任务
强制终止ActionTerminateterminate管理员强制终止

回退配置​

属性可选值
RollbackTypeRollbackNone(none)、RollbackPrevious(previous)、RollbackStart(start)、RollbackAny(any)、RollbackSpecified(specified)
RollbackDataStrategyRollbackDataClear(clear,重置表单)、RollbackDataKeep(keep,恢复目标节点进入时捕获的表单快照;节点多次进入时取最新一份)

同一申请人处理使用 SameApplicantAction,并且策略是按席位生效的:只要申请人在 节点解析出的审批人集合中占有一个席位就会触发,而不仅限于他是唯一审批人的情况。

常量Wire value行为
SameApplicantSelfApproveself_approve申请人像其他审批人一样审批自己的任务。
SameApplicantAutoPassauto_pass自动清掉申请人自己的那条任务——在节点进入时,或串行队列轮到他那个席位时。
SameApplicantTransferSuperiortransfer_superior只把申请人的席位交给他的上级,其他席位不受影响。
SameApplicantExcludeexclude避嫌:移除申请人的席位,由剩下的审批人决定,通过规则也只在剩余集合上计算。若排除后集合为空,则原样回落到 EmptyAssigneeAction。

此后由人显式创建的任务——加签插入、转办、改派、超时自动转交——一律豁免:既然有人 明确决定要把申请人卷进来,就应当压过节点策略。 连续审批人处理使用 ConsecutiveApproverAction,取值包括 ConsecutiveApproverNone(none)与 ConsecutiveApproverAutoPass (auto_pass)。

空审批人处理​

当节点找不到审批人时:

操作常量Wire value
自动通过EmptyAssigneeAutoPassauto_pass
转交管理员EmptyAssigneeTransferAdmintransfer_admin
转交上级EmptyAssigneeTransferSuperiortransfer_superior
转交申请人EmptyAssigneeTransferApplicanttransfer_applicant
转交指定人EmptyAssigneeTransferSpecifiedtransfer_specified

枚举类型是 EmptyAssigneeAction。

超时处理​

操作常量Wire value行为
无操作TimeoutActionNonenone仅标记超时
自动通过TimeoutActionAutoPassauto_pass自动审批通过
自动拒绝TimeoutActionAutoRejectauto_reject自动审批拒绝
发送通知TimeoutActionNotifynotify仅发送通知
转交管理员TimeoutActionTransferAdmintransfer_admin转交给节点管理员

枚举类型是 TimeoutAction。

表单数据存储​

模式常量Wire value存储位置
JSONStorageJSONjsonapv_instance.form_data(JSONB 列)
TableStorageTabletable每个已发布版本一张生成的物理表,同时继续写入 apv_instance.form_data 作为 canonical JSON snapshot

StorageMode.IsValid() 接受这两种导出模式。Table 模式通过 FormTable 和 FormTableColumn 记录生成的 DDL 元数据。

表存储元数据​

当已发布版本使用 StorageTable 时,框架公开两个元数据模型:

模型用途关键 JSON 字段
FormTable一张生成的物理表(主投影表或明细表格子表)flowId、versionId、physicalTableName、sourceFieldKey
FormTableColumn每个表单字段或内置列对应一个生成列formTableId、columnName、columnType、isNullable、sourceFieldKey、sortOrder

FormTable 是框架生成 DDL 的单一事实来源:发布路径会先查它,避免重复发布时 重复记录版本元数据(DDL 本身通过 CREATE TABLE IF NOT EXISTS 保证幂等); 操作员也可以通过它把版本映射到对应的投影表。FormTable.SourceFieldKey 对版本的主投影表是 "",对明细表格子投影是所属 table 字段的 key; (versionId, sourceFieldKey) 唯一。ColumnDataType 是表单定义使用的逻辑 字段到列类型词汇,storage 层再把它映射成具体数据库方言的 SQL 类型。

生成的物理表布局​

发布 table 模式的版本会创建一张主投影表,外加每个明细表格(table 类型) 字段一张子表:

表物理表名内置列字段列
主投影表apv_form_<code>_<versionId>(flow code 经净化处理并截断,使整个表名不超过 63 字符标识符上限;预算不足或 code 为空时退化为 apv_form_<versionId>)id(主键)、instance_id(UNIQUE)、created_at 排最后每个标量字段一列,按声明顺序
明细表格子表apv_form_<versionId>__<fieldKey 后缀>id(主键)、instance_id(有索引、非唯一)、row_index、created_at 排最后每个表格列一列,按声明顺序

每个物理表名和列名进入 DDL/DML 字符串前都要先通过安全 SQL 标识符校验, 字段 key 不能和内置列名冲突,所有表单值都以 ? 参数绑定——从不拼接。 CREATE TABLE IF NOT EXISTS 在发布事务之外执行(MySQL 的 DDL 会隐式提交 进行中的事务)且幂等;FormTable / FormTableColumn 元数据则在发布事务内 写入,随版本的发布状态一起提交或回滚。

写入时投影采用"替换而非追加"策略:主表每个实例恰好一行(由 instance_id UNIQUE 约束保证),子表按 row_index 排序、每条明细一行;每次投影(实例表单 数据发生变更时——启动、重新提交,以及任何修改表单数据的任务操作)都会先删除 该实例已有的行再插入新行——物理表始终反映当前表单数据,不积累历史。

实例进度投影​

管理端和用户端 instance detail 响应会在实例快照旁公开两个只读投影:

投影公开类型用途
timelineTimelineEntryKind、TimelineEntry、NodeVisitStatus、NodeParticipant、Activity、ActivityUrge、CCRecipient实例实际经过路径的时间线
flow graphNodeProgressStatus、InstanceFlowGraph、FlowGraphNode、FlowGraphNodeData、FlowGraphEdge带运行时进度标注、兼容 React Flow 的流程图

FlowGraphNode.ID 是 React Flow 设计期节点 id。FlowGraphNode.NodeID 是 action log 和 rollback target 使用的持久化 flow-node id。

进度和时间线枚举显式导出:

枚举常量
TimelineEntryKindTimelineEntryStart、TimelineEntryApproval、TimelineEntryHandle、TimelineEntryCC、TimelineEntryEnd、TimelineEntryWithdraw、TimelineEntryTerminate
NodeVisitStatusNodeVisitActive、NodeVisitPassed、NodeVisitRejected、NodeVisitReturned、NodeVisitCanceled
NodeProgressStatusNodeProgressPending、NodeProgressActive、NodeProgressPassed、NodeProgressRejected、NodeProgressReturned、NodeProgressCanceled

这些投影背后的持久化 visit 模型是 NodeVisit。

实例编号生成​

实现 InstanceNoGenerator 接口来自定义实例编号:

type InstanceNoGenerator interface {
Generate(ctx context.Context, flowCode string) (string, error)
}

下一步:事件与集成 了解如何在宿主代码中响应生命周期流转。