工作流里的转办、委托和工作移交的业务语义与技术实现

在 OA 审批和企业工作流里,转办、委托和工作移交都可能让"另一个人接手任务",但三者不是同一个按钮的不同叫法。转办是当前任务的责任永久转移;委托是原责任人保留责任、由受托人临时代办;工作移交是人员请假、调岗或离职时,对一批存量工作和未来工作的组织级安排。

技术实现也应分层:单条转办可以重新设置任务办理人;标准委托应使用 owner、assignee 和 delegationState 表达责任与执行的分离;工作移交必须由平台的人员代理规则、批量任务命令、审计和失败补偿共同完成。把三者都实现成 setAssignee,短期看起来简单,长期一定会在责任追溯、待办查询和权限审计上出问题。

本文以截至 2026 年 8 月最新正式版 Flowable 8.0.0 为源码基线,说明这三类操作的业务边界、引擎 API、数据模型和企业级实现方式。

一、核心结论与问题边界

先给答案:先判断责任是否转移,再决定怎样改任务

选择实现方式前,先问三个问题:原办理人是否仍承担最终责任、目标人处理后任务是否返回原办理人、操作只影响当前任务还是还要覆盖其他工作。

操作 一句话定义 原办理人责任 作用范围 推荐技术语义
转办 把当前任务永久交给另一人 通常退出当前责任链 一条正在运行的任务 重新分配 assignee + 转办审计
委托 原责任人请另一人临时代办 通常仍为 owner 一条任务或一段代理期 owner/assignee + 委托状态
工作移交 因请假、调岗、离职批量安排工作 由制度决定 存量任务 + 未来任务 + 非流程工作 移交单、路由规则、批处理与对账

不要只看"待办现在显示给谁"。真正的区别在于责任、返回路径、影响范围和审计语义。

图 1:转办改变当前责任人,委托分离责任人与执行人,工作移交覆盖一组工作和一个时间范围。

转办是什么:当前任务的责任永久转移

转办通常发生在当前办理人发现任务不属于自己、需要更合适的人处理,或者组织要求重新指定责任人的场景。操作完成后,新办理人获得当前任务的完整办理权限,原办理人从待办中退出,但转办记录必须保留。

一个完整的转办至少要满足四个条件:

  • 只改变当前任务的办理责任,不自动修改后续节点的人员规则;
  • 原办理人不能继续提交同一任务;
  • 新办理人接手原任务的表单、附件、意见上下文和 SLA;
  • 审计中能够回答"谁在何时、因为什么把哪一条任务转给了谁"。

转办不是加签。加签会增加一个参与者或一个审批环节,原办理链路通常仍存在;转办不增加审批票数,也不应凭空创建新 BPMN 节点,它只是让同一条任务换了当前责任人。

转办也不等于把业务单据的负责人全部改掉。流程任务 assignee、业务单据 owner、客户经理、项目负责人可能是四个不同字段,是否联动必须由业务规则明确规定。

二、关键概念与能力差异

委托是什么:责任保留,执行临时交给受托人

委托的核心是"代办",而不是"让责"。原办理人通常仍是责任所有者,受托人只在授权范围内处理任务。Flowable 的标准委托模型正是这种语义:owner 表示原责任人,assignee 表示当前执行人,delegationState 表示委托是否待处理。

企业产品中常见两种委托模式:

1. 协助委托:受托人处理后返回原办理人

受托人填写意见、补充材料或给出建议,然后执行 resolve。任务回到 owner,由原办理人复核并最终完成。这与 Flowable 原生 delegateTask、resolveTask 的语义最一致。

2. 全权委托:受托人可以直接完成任务

这是一种业务扩展。它适合明确授权代理人代表原责任人作出审批结论的场景,但不能直接套用 PENDING 委托后调用普通 complete,因为 Flowable 会拒绝完成仍处于 PENDING 的委托任务。平台应把"协助委托"和"全权代理"设计成两个清晰的策略,分别保存授权来源、实际完成人和最终责任人。

委托链还必须限制深度。允许 A 委托 B、B 再委托 C,容易形成循环代理、越权扩散和责任模糊。常见做法是默认禁止再次委托,或最多允许一层且必须重新校验授权范围。

工作移交是什么:它不是一个任务动作,而是一项组织事件

工作移交通常由请假、出差、调岗、离职或组织调整触发。它的对象不只是"当前一条待办",还可能包括:

  • 已经分配给移交人的活动任务;
  • 仍在候选组中、尚未签收的任务;
  • 移交期间新生成的流程任务;
  • 草稿、传阅、抄送、催办、日程和非流程业务工作;
  • 到期提醒、代理期限结束后的恢复与对账。

因此,工作移交应先生成一张可审批、可撤销、可追踪的移交单,再根据任务类型决定每条工作采用转办、委托、保留或排除。直接执行一条"把 userA 的所有任务改成 userB"的 SQL,不但绕过引擎事件和历史,还可能把保密审批、本人确认、财务授权和已经结束的任务错误移走。

三、模型架构与运行机制

Flowable 8 的标准委托在源码里怎样运行

Flowable 8.0.0 的 TaskServiceImpl.delegateTask 提交 DelegateTaskCmd。命令的关键逻辑非常直接:先将 delegationState 设为 PENDING;如果 task.owner 为空,就把当前 assignee 保存为 owner;最后通过 TaskHelper.changeTaskAssignee 把 assignee 改为受托人。

java 复制代码
taskService.delegateTask(taskId, delegateeUserId);

// 受托人处理后,不是 complete,而是 resolve
taskService.resolveTask(taskId, variables);

ResolveTaskCmd 会把 delegationState 改为 RESOLVED,再把 assignee 改回 owner。源码中的 TaskHelper.completeTask 还会显式检查:如果任务仍为 PENDING,就抛出异常,要求先 resolve,而不能直接 complete。

这条限制非常重要。它说明 Flowable 原生委托不是"换个人后直接审批完成",而是"受托人代办后把任务交还责任人"。如果产品需要全权代理,就必须在业务层明确扩展语义,不能悄悄把原生委托解释成转办。

图 2:delegateTask 进入 PENDING,resolveTask 返回 owner;PENDING 状态不能按普通任务直接完成。

在 Flowable 里怎样实现转办

Flowable 没有一个名为"transferTask"的专用业务 API。通常使用 TaskService.setAssignee(taskId, targetUserId) 重新分配当前任务。Flowable 8.0.0 的 TaskServiceImpl 会提交 AddIdentityLinkCmd,当 identityLinkType 为 ASSIGNEE 时,命令调用 TaskHelper.changeTaskAssignee,进而更新任务办理人并触发分配相关事件。

java 复制代码
@Transactional
public void transfer(String taskId, String operatorId,
        String targetUserId, String reason) {
    Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
    policy.checkTransfer(task, operatorId, targetUserId);
    taskService.setAssignee(taskId, targetUserId);
    taskService.addComment(taskId, task.getProcessInstanceId(),
        "TRANSFER", reason);
    actionRepository.save(TaskAction.transfer(task, operatorId,
        targetUserId, reason));
}

引擎 API 只完成受理人变化,不会替平台检查目标用户是否存在、是否在职、是否属于同一租户、是否具备金额授权,也不会自动生成满足企业审计需要的完整转办单。Flowable 官方 API 文档也明确说明,运行时不会替应用验证用户是否真实存在。因此,校验和审计必须由领域服务承担。

四、核心场景与处理策略

为什么工作移交不能只是批量调用 setAssignee

批量 setAssignee 只能处理查询时已经存在并且直接分配给某个人的任务。它处理不了未来才创建的任务,也不能自然覆盖候选组任务、非流程工作、委托中的任务和需要本人亲自处理的例外事项。

企业级工作移交至少应拆成四层:

  1. 移交计划:记录移交人、接收人、原因、生效时间、结束时间和审批状态;
  2. 范围规则:按流程、节点、业务类型、组织、金额或密级决定转办、委托、保留、排除;
  3. 执行批次:冻结任务清单,逐条执行,支持幂等、失败重试和部分回滚;
  4. 未来路由:在新任务分配时查询有效代理规则,而不是每天扫描数据库补改。

移交期间新生成的任务应在人员解析阶段完成路由。例如,节点原本解析到 userA,分配服务发现 userA 存在有效的休假代理规则,于是根据策略把任务直接分配给 userB,或先以 userA 为 owner 再委托给 userB。这样才能从源头保证一致性。

图 3:移交计划同时驱动存量任务批处理和未来任务分配,二者通过同一策略与审计模型保持一致。

存量任务和未来任务应该怎样分别处理

存量任务应先形成快照,再执行迁移。快照至少包含 taskId、processInstanceId、taskDefinitionKey、当前 assignee、owner、delegationState、版本号和命中规则。任务在快照后可能被其他人完成,因此执行时必须再次读取并校验,不能相信旧清单。

未来任务则不应该提前生成。推荐在人员解析服务、任务创建监听器或统一分配网关中应用代理规则。选择哪一层取决于平台架构:

介入点 优点 风险与适用边界
人员解析阶段 创建时即得到正确责任关系 所有建模入口必须统一调用解析服务
Task Listener 容易接入现有 Flowable 流程 需防止监听器重复执行和事务副作用
任务创建后事件 与引擎解耦、便于扩展 存在短暂错误待办,需保证最终一致

对于候选组任务,通常不应把整个候选池移交给一个人。应判断用户是否已经 claim;未签收任务继续由候选组竞争,除非业务规则明确要求替换候选用户或候选组。

五、数据、规则与状态设计

三类操作的数据模型和审计应该怎样设计

Flowable 运行时任务能够提供 assignee、owner 和 delegationState,历史任务可以保留 assignee、owner、completedBy 等最终信息。但"最终字段"不能完整解释多次转办、委托、解除委托和批量移交的全过程。平台需要独立的操作流水。

建议至少保存以下数据:

字段组 关键字段
操作身份 actionId、actionType、operatorId、sourceChannel
责任变化 fromAssignee、toAssignee、ownerBefore、ownerAfter
业务范围 taskId、processInstanceId、handoverPlanId、batchId
决策依据 reason、policyId、authorizationId、effectiveTime
并发结果 expectedRevision、status、errorCode、retryCount

任务评论适合给用户展示原因,不能替代结构化审计表。结构化流水应与业务单据日志、引擎历史和安全审计通过 actionId 关联,才能支持查询、对账和合规取证。

图 4:运行时任务保存当前状态,领域流水保存责任变化,移交计划保存批量范围,三者不能互相替代。

权限和数据可见范围为什么必须重新计算

任务转给另一个人,并不意味着目标人自动获得查看全部业务数据的权限。企业平台必须同时校验任务操作权、表单字段权、附件密级、组织数据范围和业务授权额度。

尤其要关注以下约束:

  • 发起人与审批人、经办人与复核人之间的职责分离;
  • 财务、合同、人事等流程的金额与密级授权;
  • 目标用户是否在职、是否处于停用或同一代理期;
  • 是否允许转给本人、流程发起人或下属;
  • 受托人能否再次转办、委托、加签或撤回;
  • 代理到期后,未完成任务继续由谁负责。

Flowable 不会替应用完成这些组织校验。引擎负责可靠执行任务状态,平台负责业务资格、权限边界和人员主数据一致性。

六、工程实现与系统集成

并发、多实例和委托中的任务怎样处理

普通串行用户任务可以直接按 taskId 操作,但多实例、并行分支和已有委托状态需要专门策略。

多实例会签中的每个实例通常有独立 taskId。转办其中一人的任务只改变该实例的办理人,不应修改集合变量或其他成员。若是"某岗位全部实例"移交,应先明确是替换未创建的未来实例,还是仅迁移当前活动实例。

并行分支可能同时存在多个待办。工作移交按任务逐条执行,但批次结果必须区分全部成功、部分成功和已跳过,不能因为一条任务已完成就回滚所有已成功的迁移。

对于 delegationState=PENDING 的任务,不能再次按普通转办逻辑覆盖 assignee。平台应决定先解除原委托、拒绝操作,还是把原委托关系纳入新的工作移交。默认拒绝并要求人工处理,通常最容易解释。

并发控制至少需要任务版本校验、请求幂等键和批次行级状态。操作前查到的 task 不代表提交时仍然活动,最终结果必须以引擎事务提交和执行后复查为准。

怎样封装统一的任务责任变更服务

前端不要直接调用 setAssignee、delegateTask 或批量 SQL。建议由一个任务责任变更服务统一接收 ResponsibilityChangeCommand,命令至少包含 requestId、taskId、changeType、operatorId、targetUserId、reason 和 expectedRevision。

服务按固定顺序执行:鉴权与幂等校验、读取活动任务、校验组织和业务规则、选择 Flowable API、写入操作流水、同步任务中心索引,最后重新查询任务确认 assignee、owner 和 delegationState。

工作移交则复用同一单任务服务,由批次协调器逐条提交命令。这样单条操作和批量操作共享规则,却不会把一个大批次锁在超长数据库事务中。

七、安全、性能与治理要求

设计器和任务中心应该怎样呈现

设计器负责定义"这个节点允许哪些责任变更"和"目标人员范围",运行时任务中心负责展示当前责任关系与操作后果。

一个清晰的操作弹窗至少应显示:

  • 转办:提示"原办理人将退出当前任务";
  • 协助委托:提示"受托人处理后返回原责任人";
  • 全权代理:提示"受托人可代表原责任人作出最终结论";
  • 工作移交:展示命中任务数、排除任务数、未来路由规则和有效期。

任务详情不应只显示当前 assignee,还要显示 owner、受托状态、代理来源和责任变更时间线。否则用户看到"任务在 B 手里",却无法判断 B 是最终责任人还是临时代办人。

低代码工作流平台怎样把三种能力产品化

成熟平台不应在每个业务应用中重复编写转办和委托代码,而应提供统一的人员选择器、组织规则、审批动作策略、任务责任服务、移交计划和审计查询。

云程低代码开发平台可以在 Flowable 之上把节点权限、数据权限、操作按钮、人员代理和任务中心统一起来:模型只声明允许的业务动作,运行时由策略服务决定能否执行、目标范围和审计方式。这样既保留开源引擎的稳定任务状态,也补齐中国式 OA 所需要的组织语义。

八、案例实践与迁移路线

上线前至少覆盖哪些测试

  1. 转办后原办理人立即失去办理权限,新办理人可以正常提交;
  2. 委托后 owner、assignee、PENDING 状态正确,普通 complete 被拒绝;
  3. resolve 后任务回到 owner,受托意见和变量仍可追溯;
  4. 全权代理与协助委托使用不同策略和审计类型;
  5. 工作移交快照后任务已完成时能够安全跳过;
  6. 移交期间创建的新任务命中未来路由规则;
  7. 候选组任务、多实例任务和并行任务不会被错误合并;
  8. 重复 requestId 不会再次迁移同一任务;
  9. 部分失败批次可以重试,已成功任务不会重复操作;
  10. 代理到期、提前撤销和员工复岗后路由能够恢复;
  11. 跨租户、越权目标、职责冲突和循环委托会被拒绝;
  12. 操作流水、Flowable 历史、任务中心索引和业务日志可以对账。

测试断言不能只看"目标人出现待办",还要验证 owner、assignee、delegationState、历史办理人、业务权限、SLA 和批次明细。

九、平台落地、测试与选型

标准答案:转办、委托和工作移交应该怎样实现

转办是单条活动任务的永久责任转移,通常用 setAssignee 更新当前办理人,但必须补充权限校验、转办原因和结构化审计。它不增加流程节点,也不自动改变后续节点人员。

委托是责任与执行的分离。Flowable 8.0.0 的标准实现通过 delegateTask 保存 owner、切换 assignee 并进入 PENDING;受托人完成代办后调用 resolveTask,任务返回 owner。需要受托人直接作最终决定时,应定义独立的全权代理策略。

工作移交是一项组织级治理能力,不是引擎的单任务动作。它需要移交计划、任务范围快照、存量批处理、未来任务路由、幂等重试、到期恢复和统一审计。

如果只记住三句话:

  • 转办改变最终责任人;
  • 委托改变当前执行人,但通常保留原 owner;
  • 工作移交同时治理一批存量工作和一个时期内的未来工作。
相关推荐
愚农搬码11 天前
Flowable 工作流中如何接入大模型 LLM 节点
llm·ai编程·工作流引擎
愚农搬码18 天前
Flowable工作流引擎如何适配国产数据库?以达梦数据库举例说明
工作流引擎
songgeb18 天前
mspec体验:基于SDD的轻量AI工作流
ai编程·工作流引擎
大龄码农有梦想18 天前
企业工作流系统如何设计用户、部门、角色、岗位、动态关系五类流程办理人?
工作流引擎·flowable·流程引擎·oa·工作流系统·选人规则·bpm平台
大龄码农有梦想21 天前
工作流中的子流程节点能否驳回到父流程?
工作流引擎·流程引擎·oa·bpm·子流程·驳回·退回
愚农搬码21 天前
工作流中的子流程节点能否驳回到父流程?
工作流引擎
愚农搬码21 天前
流程图上的回退线与运行时动态回退,应该选择哪一种?
工作流引擎
大龄码农有梦想22 天前
开源流程引擎 Camunda 如何实现任意节点跳转?
工作流引擎·流程引擎·camunda·oa·bpn·流程跳转·会签
愚农搬码25 天前
在开源流程引擎 Flowable 里如何实现任意节点跳转?
工作流引擎