Skip to content

工作流

工作流用于把业务流程显式建模,例如请假审批、报销审批、合同审批、订单流转。相比把流程写死在代码里,工作流引擎可以更清晰地表达节点、审批人、条件分支和流程状态。

为什么需要工作流

如果所有流程都写在 Java if/else 里,刚开始会很快,但流程一变复杂就会出现维护问题:审批节点散落在代码里,谁审批过不清楚,流程改动需要发版,历史轨迹需要自己补表,测试也很难覆盖所有分支。

工作流解决的是“流程可建模、可运行、可追踪、可调整”的问题。

没有工作流时使用工作流后
流程藏在业务代码里流程定义用 BPMN 显式表达
审批记录要自己设计引擎保存任务、实例和历史
改节点要改代码发版流程定义可以独立版本化
分支条件难以可视化网关条件和流向在图中可见
待办、已办、催办都要自己造引擎提供任务 API 和查询能力

工作流不是为了替代业务系统。业务数据仍然应该保存在业务表中,工作流引擎负责“谁下一步处理、流程走到哪里、历史轨迹是什么”。

本目录内容

基本概念

概念说明
流程定义设计好的流程模板
流程实例一次真实运行的流程
任务等待某个人或系统处理的节点
网关条件分支、并行分支
流程变量流程运行中的数据

核心原理

mermaid
flowchart TD
    A["流程定义<br/>BPMN 模板"] --> B["部署到工作流引擎"]
    B --> C["发起流程实例"]
    C --> D["生成当前任务"]
    D --> E["用户处理任务"]
    E --> F["引擎根据变量和网关计算下一步"]
    F --> G{"流程是否结束"}
    G -- "否" --> D
    G -- "是" --> H["写入历史轨迹"]

理解工作流时一定要分清“定义”和“实例”:流程定义是模板,流程实例是某一次真实业务流转。就像 Java 类和对象的关系,类定义结构,对象承载一次具体数据。

审批流程示例

mermaid
flowchart TD
    A[提交请假申请] --> B[直属领导审批]
    B --> C{是否超过 3 天?}
    C -->|否| D[审批通过]
    C -->|是| E[部门负责人审批]
    E --> F{是否同意?}
    F -->|同意| D
    F -->|拒绝| G[流程结束: 驳回]

什么时候适合使用工作流

  • 流程节点多,且经常调整。
  • 审批人、条件、分支比较复杂。
  • 需要记录完整流程轨迹。
  • 需要可视化流程图。
  • 需要催办、转办、撤回、驳回等能力。

如果流程非常简单,例如只有一个状态字段从 0 改为 1,直接使用状态机可能更轻量。

代码 Demo:不用工作流时的状态机

简单流程可以先用状态机表达,避免过早引入工作流引擎。

java
public enum LeaveStatus {
    DRAFT,
    WAIT_LEADER_APPROVE,
    WAIT_MANAGER_APPROVE,
    APPROVED,
    REJECTED
}
java
@Service
public class LeaveService {
    @Transactional
    public void approve(Long leaveId, Long approverId) {
        LeaveApply apply = leaveRepository.findById(leaveId)
            .orElseThrow(() -> new BizException("申请不存在"));

        if (apply.getStatus() == LeaveStatus.WAIT_LEADER_APPROVE && apply.getDays() <= 3) {
            apply.setStatus(LeaveStatus.APPROVED);
            return;
        }

        if (apply.getStatus() == LeaveStatus.WAIT_LEADER_APPROVE && apply.getDays() > 3) {
            apply.setStatus(LeaveStatus.WAIT_MANAGER_APPROVE);
            return;
        }

        if (apply.getStatus() == LeaveStatus.WAIT_MANAGER_APPROVE) {
            apply.setStatus(LeaveStatus.APPROVED);
            return;
        }

        throw new BizException("当前状态不能审批");
    }
}

当审批节点、审批人、条件分支经常变化时,再考虑 Activiti、Flowable 这类工作流引擎。