流程设计与节点配置
流程设计与节点配置
本文说明业务模块流程如何设计、发布,以及节点属性和回调怎么配置。
1. 创建业务模块流程
在前端流程设计页面创建流程时,关键配置是:
- 表单类型选择业务模块表单。
- 业务模块选择对应模块,例如
Leave。 - 保存并发布流程定义。
业务页面提交审批时,BusinessWorkflowStartDialog 只会加载当前业务模块下已启用、最新的流程定义。请假页面传入 business-module="Leave",所以弹窗只展示 Leave 的流程。
2. 发布后的关系
flowchart LR
A["WorkFlowFlow<br/>流程设计稿"] --> B["WorkFlowDefinition<br/>发布版本"]
B --> C["WorkFlowInstance<br/>运行实例"]
C --> D["WorkFlowStepInstance<br/>步骤实例"]
C --> E["WorkFlowTodo<br/>待办/抄送/通知"]
C --> F["WorkFlowFormRecord<br/>表单数据快照"]每次发布会生成或更新 WorkFlowDefinition。业务发起审批时使用 DefinitionId 或 WorkflowCode 启动实例。
3. 条件字段来源
流程条件字段有两个来源:
- 前端
workflowForm/{module}.ts的conditionFields,当前优先使用。 - 后端
/api/workflow/businessModule/{businessModule}/fields,读取实体上的WorkflowFieldAttribute。
请假示例前端字段:
conditionFields: [
{ name: 'leaveType', label: '请假类型', type: 'string' },
{ name: 'days', label: '请假天数', type: 'number' },
{ name: 'startTime', label: '开始时间', type: 'date' },
{ name: 'endTime', label: '结束时间', type: 'date' },
{ name: 'applicantName', label: '申请人', type: 'string' },
{ name: 'deptName', label: '部门', type: 'string' },
],请假实体后端字段:
[WorkflowField("请假天数", WorkflowFieldTypeEnum.Number)]
public decimal Days { get; set; }条件表达式最终基于启动流程时保存的 FormData 判断。字段没有进入 FormData,即使在设计器中能看到,也无法稳定参与运行时判断。
4. 条件表达式规则
常见表达式:
Days > 3
days <= 1
LeaveType == "年假"
DeptName == "研发部"运行时会对字段做大小写不敏感匹配,但建议统一使用一套字段名。请假示例后端 FormData 使用 Days、LeaveType,前端配置使用 days、leaveType,当前可以匹配,但新模块建议保持一致,减少排查成本。
条件表达式配置在 WorkFlow.json:
"ConditionExpression": {
"DefaultWhenEmpty": true,
"DefaultWhenFormDataEmpty": false,
"DefaultWhenFieldNotFound": false,
"DefaultWhenParseFailed": false,
"EnableDetailedLogging": true
}含义:
- 空表达式默认通过。
- 有表达式但表单数据为空时不通过。
- 字段不存在时不通过。
- 表达式解析失败时不通过。
5. 审批节点
审批节点通常配置:
- 审批模式,例如单人、会签、或签、依次审批。
- 审批人来源,例如指定用户、角色、部门。
- 抄送配置。
- 审批完成回调。
审批推进时,系统会创建 WorkFlowStepInstance 和 WorkFlowTodo。待办页面审批后,WorkflowApprovalService 根据节点配置推进到下一个节点或结束流程。
6. 节点 HTTP 回调
节点 HTTP 回调是“某个审批节点处理后触发”的接口调用,适合做中间动作,例如写业务备注、同步外部系统、调用内部服务。
节点属性支持:
| 属性 | 说明 |
|---|---|
callbackUrl | 回调 URL,支持相对路径和绝对 URL |
callbackHttpMethod | GET、POST、PUT、DELETE 等 |
callbackHeaders | 请求头,按行填写 Key: Value |
callbackBody | 请求体模板,GET 不使用 Body |
变量占位符:
| 变量 | 说明 |
|---|---|
{{instanceCode}} | 工作流实例编码 |
{{businessModule}} | 业务模块,例如 Leave |
{{businessId}} | 业务数据 ID |
{{stepInstance.stepCode}} | 当前步骤编码 |
{{stepInstance.stepName}} | 当前步骤名称 |
{{operatorId}} | 操作人 ID |
{{operatorName}} | 操作人姓名 |
{{comment}} | 审批意见 |
{{approvalStatus}} | 审批动作 |
{{action}} | 审批动作 |
{{formData}} | 完整表单数据 JSON |
{{formData.Days}} | 表单字段值 |
请假示例测试接口:
POST /api/demo/leave/updateRemark请求体模板示例:
{
"id": {{businessId}},
"remark": "节点 {{stepInstance.stepName}} 已处理,操作人 {{operatorName}},意见:{{comment}}"
}节点回调失败是否影响流程,由 WorkFlow:Callback:IgnoreFailure 控制。当前默认 true,即失败只记录日志,不阻断主流程。
7. 审批完成业务回调
审批完成业务回调是”整个流程结束或拒绝终止后触发”的业务状态回写,与节点 HTTP 回调不是同一个概念。
WorkflowApprovalService 按以下优先级通知业务模块:
- 依赖注入处理器(优先):从 DI 容器查找
IWorkflowCompletedHandler实现,匹配BusinessModule后调用HandleAsync。 - HTTP 回调(兜底):按
BusinessModuleCallbackRouteTemplate配置的地址发起 HTTP 请求。
依赖注入处理器方式
业务服务实现 IWorkflowCompletedHandler 接口,无需暴露 HTTP 接口:
public class LeaveService : IDynamicApiController, ITransient, IWorkflowCompletedHandler
{
public string BusinessModule => BusinessModuleConst.Leave;
public async Task HandleAsync(WorkflowCompletedContext context)
{
// 根据 context.Approved 更新业务状态
}
}HTTP 回调方式
默认配置:
"BusinessModuleCallbackRouteTemplate": "/api/demo/{businessModuleLower}/workflow/callback"回调数据:
{
"instanceCode": "INST_xxx",
"businessModule": "Leave",
"businessId": 123,
"approved": true,
"comment": null
}请假业务回调接口:POST /api/demo/leave/workflow/callback。
8. BaseUrl 和相对回调地址
如果回调地址是相对路径,后端会优先从当前 HTTP 请求解析应用地址,包括代理头:
X-Forwarded-ProtoX-Forwarded-HostX-Forwarded-PrefixX-Original-Prefix
如果没有当前请求上下文,则使用 WorkFlow:BaseUrl。部署到网关、虚拟目录或容器内时,请确认 BaseUrl 或转发头配置正确。