Flowable 7.0 审核状态详解:通过、转办、委派、认领、取消认领、退回、驳回、撤销

Flowable工作流之加签(委派)、转签(转办) 顾名思义就是增加一道审批签名,这道审批往往是临时增加的,标准流程没有规定要走的在现实工作流程中,加签功能使用率颇高;有时,审批人对内容不太确定,不太敢做主,就会找更高层的领导进行加签;这样就可以规避个人风险;出问题大家一起担。有时为了表示对领导尊重,或者让领导知道这回事,也需要使用加签功能任务在 这里, 这个时候需要 核对一下,等 核对之后又回到 这里,这时 才能继续自己的任务任务在 这里, 这个时候需要 处理这个事情,处理完毕之后就不用管了,继续后面的审批环节完成后的流程图如下 文件内容 阅读详情

一、前言

在使用 Flowable 7.0 开发工作流审批系统时,常见的审核操作不仅仅是“同意”和“拒绝”,还包括转办、委派、认领、取消认领、退回、驳回、撤销等操作。

这些操作看起来相似,但在业务含义、流程是否继续流转、任务办理人是否变化、流程实例是否结束、历史记录如何保存等方面都有明显区别。

本文结合 Flowable 7.0 的实际开发场景,对常见审核状态进行详细说明,方便在 OA、审批流、用章申请、报销申请、合同审批、请假审批等系统中使用。


二、Flowable 审核状态总览

常见审核操作可以分为以下几类:

操作是否完成当前任务是否改变办理人是否继续流程是否结束流程常用 API
通过是否是否taskService.complete
驳回是否一般否/或走驳回线可结束/可退回complete + 流程变量
退回是否回到指定节点否changeState / 自定义跳转
转办否是否否taskService.setAssignee
委派否是否否taskService.delegateTask
完成委派否/部分完成是,交还原负责人否否taskService.resolveTask
认领否是否否taskService.claim
取消认领否是,清空办理人否否taskService.unclaim
撤销视业务而定否否通常结束runtimeService.deleteProcessInstance
取消视业务而定否否通常结束deleteProcessInstance / 自定义状态

三、通过

1. 业务含义

“通过”是最常见的审批操作,表示当前审批人同意当前节点的申请内容,当前任务完成,流程继续向下一个节点流转。

例如:

  • 科室负责人审核通过

  • 分管领导审核通过

  • 财务审核通过

  • 老板最终审批通过

2. 流程表现

当前任务会被完成,Flowable 会根据 BPMN 流程图中的连线条件,自动流转到下一个节点。

如果当前节点是最后一个审批节点,流程实例结束。

3. 常用 API

taskService.complete(taskId, variables);

4. 示例代码

Map<String, Object> variables = new HashMap<>();
variables.put("approved", true);
variables.put("approvalStatus", "PASS");
variables.put("approvalOpinion", "同意");

taskService.complete(taskId, variables);

5. 数据变化

通过后,通常会产生以下变化:

  • 当前任务从运行时任务表中删除

  • 当前任务进入历史任务表

  • 流程继续流转到下一个节点

  • 审批意见保存到流程变量或业务审批记录表

  • 如果没有下一个节点,流程结束

常见相关表:

ACT_RU_TASK          当前运行任务表
ACT_HI_TASKINST      历史任务表
ACT_HI_ACTINST       历史节点表
ACT_HI_VARINST       历史变量表
ACT_RU_VARIABLE      运行时变量表

6. 适用场景

通过适合正常审批场景,例如:

  • 申请内容无问题

  • 当前节点审批人确认通过

  • 流程继续进入下一审批环节


四、驳回

1. 业务含义

“驳回”表示当前审批人不同意申请内容,流程不再按照正常审批路径继续向后流转。

驳回通常有两种业务设计:

第一种:驳回后流程直接结束。

第二种:驳回后流程退回申请人修改,修改后可以重新提交。

2. 驳回和退回的区别

很多系统中,“驳回”和“退回”容易混用。

建议区分如下:

类型含义流程结果
驳回审批不同意,申请失败流程结束或进入驳回结束节点
退回审批人要求修改材料回到申请人或上一个节点

也就是说,驳回更偏向“否决”,退回更偏向“修改后再提交”。

3. 常用实现方式

方式一:通过流程变量走驳回线

在 BPMN 流程图中配置排他网关,根据变量判断走通过线还是驳回线。

Map<String, Object> variables = new HashMap<>();
variables.put("approved", false);
variables.put("approvalStatus", "REJECT");
variables.put("approvalOpinion", "材料不完整,驳回申请");

taskService.complete(taskId, variables);

BPMN 条件示例:

${approved == true}   -> 通过
${approved == false}  -> 驳回

方式二:直接终止流程实例

如果业务要求驳回后流程直接结束,也可以删除流程实例。

runtimeService.deleteProcessInstance(processInstanceId, "审批驳回,流程结束");

4. 建议状态值

REJECT
驳回

5. 适用场景

驳回适合以下场景:

  • 申请内容明显不符合要求

  • 审批人不同意该事项

  • 不允许申请人继续修改提交

  • 流程需要终止


五、退回

1. 业务含义

“退回”表示当前审批人认为申请内容需要修改,但不是彻底否决。

退回一般会把流程退回到:

  • 发起人节点

  • 上一个审批节点

  • 指定审批节点

  • 重新填写节点

例如:

  • 材料缺失,退回申请人补充

  • 金额填写错误,退回发起人修改

  • 科室负责人填写意见不完整,退回科室负责人重新处理

2. 退回和驳回的区别

对比项退回驳回
业务含义要求修改不同意
流程是否结束通常不结束通常结束
是否允许再次提交允许不一定
常见目标节点发起人/上一节点结束节点/驳回节点
用户感知修改后重新提交申请失败

3. Flowable 实现思路

Flowable 原生没有一个简单的 rollback 方法专门表示退回,实际项目中通常使用以下方式:

方式一:流程图中提前设计退回线

在 BPMN 中通过排他网关配置“通过”和“退回”两条线。

Map<String, Object> variables = new HashMap<>();
variables.put("approvalStatus", "RETURN");
variables.put("approvalOpinion", "请补充附件后重新提交");

taskService.complete(taskId, variables);

然后 BPMN 中配置条件:

${approvalStatus == 'PASS'}    -> 下一审批节点
${approvalStatus == 'RETURN'}  -> 申请人修改节点

这种方式最稳定,也最容易维护。

方式二:动态跳转到指定节点

在复杂场景中,可以使用动态改变流程状态的方式,将当前任务跳转到指定节点。

伪代码示例:

runtimeService.createChangeActivityStateBuilder()
        .processInstanceId(processInstanceId)
        .moveActivityIdTo(currentActivityId, targetActivityId)
        .changeState();

这种方式适合自由退回、退回任意节点等复杂审批场景。

4. 建议状态值

RETURN
退回

5. 注意事项

退回操作建议记录以下信息:

当前节点ID
当前节点名称
当前审批人
退回目标节点ID
退回目标节点名称
退回原因
退回时间
流程实例ID
业务ID

否则后续查看流程轨迹时,很难知道是谁退回、退回到哪里、为什么退回。


六、转办

1. 业务含义

“转办”表示当前任务由当前办理人转交给另一个人办理。

转办后,原办理人不再处理该任务,新办理人成为当前任务的实际办理人。

例如:

  • 张三当前有一个审批任务

  • 张三因为请假,把任务转给李四

  • 转办后,李四负责审批该任务

  • 张三不再拥有这个待办任务

2. 流程表现

转办不会完成当前任务,也不会推动流程向下流转。

它只改变当前任务的办理人。

3. 常用 API

taskService.setAssignee(taskId, newUserId);

4. 示例代码

String taskId = "任务ID";
String newAssignee = "lisi";

taskService.setAssignee(taskId, newAssignee);

5. 数据变化

转办后,当前任务仍然存在,只是 ASSIGNEE_ 字段发生变化。

相关表:

ACT_RU_TASK.ASSIGNEE_
ACT_HI_TASKINST.ASSIGNEE_

6. 转办特点

不完成任务
不进入下一节点
不改变流程路线
只改变当前任务办理人
原办理人失去待办权限
新办理人获得待办任务

7. 适用场景

转办适合以下场景:

  • 当前审批人无权限处理

  • 当前审批人请假

  • 当前审批人认为应该由别人审批

  • 任务分配错误,需要改派

8. 转办建议记录业务日志

Flowable 自身只会修改任务办理人,业务系统最好额外记录转办日志。

建议记录字段:

taskId
processInstanceId
businessKey
oldAssignee
newAssignee
transferReason
transferTime
operator

9. 转办和委派的区别

对比项转办委派
原办理人是否还负责不负责仍然负责
新办理人处理后是否回到原办理人不会会
是否改变 assignee是是
是否设置 owner一般不设置通常设置原办理人为 owner
适合场景彻底交给别人请别人协助处理

七、委派

1. 业务含义

“委派”表示当前办理人临时把任务交给别人处理,但任务最终责任人仍然是原办理人。

被委派人处理完成后,任务会回到原办理人,由原办理人继续最终审批。

例如:

  • 张三是当前审批人

  • 张三不确定某个问题,让李四协助确认

  • 张三将任务委派给李四

  • 李四处理后,任务回到张三

  • 张三再最终审批通过或驳回

2. 流程表现

委派不会完成当前任务,也不会推动流程流转。

它只是把当前任务临时交给被委派人。

3. 常用 API

taskService.delegateTask(taskId, delegateUserId);

4. 示例代码

String taskId = "任务ID";
String delegateUserId = "lisi";

taskService.delegateTask(taskId, delegateUserId);

5. 委派后的任务状态

委派后,任务通常会出现以下变化:

owner      = 原办理人
assignee   = 被委派人
delegationState = PENDING

含义如下:

字段含义
owner原始负责人
assignee当前被委派处理人
delegationState委派状态

6. 被委派人处理完成

被委派人不能直接使用普通的 complete 结束任务,而应该使用:

taskService.resolveTask(taskId, variables);

示例:

Map<String, Object> variables = new HashMap<>();
variables.put("delegateOpinion", "已核实,建议通过");

taskService.resolveTask(taskId, variables);

执行后,任务会回到原办理人。

7. 原办理人最终审批

任务回到原办理人后,原办理人再执行:

taskService.complete(taskId, variables);

8. 委派适用场景

委派适合以下场景:

  • 需要其他人协助确认

  • 需要专业人员补充意见

  • 领导让下属先处理,但最终仍由领导审批

  • 审批人保留最终决定权

9. 委派和转办的核心区别

转办:我不管了,彻底交给你。
委派:你先帮我看看,最后还要回到我这里。

八、认领

1. 业务含义

“认领”通常用于候选人或候选组任务。

当一个任务没有明确办理人,而是分配给多个候选人或一个候选组时,需要某个人主动认领该任务。

认领后,该任务就归认领人处理。

例如:

  • 一个任务分配给“财务组”

  • 财务组有 A、B、C 三个人

  • A 点击认领

  • 任务办理人变成 A

  • B、C 不再看到该任务为可办理状态

2. 流程表现

认领不会完成任务,也不会推动流程流转。

认领只是把“候选任务”变成“个人待办任务”。

3. 常用 API

taskService.claim(taskId, userId);

4. 示例代码

String taskId = "任务ID";
String userId = "zhangsan";

taskService.claim(taskId, userId);

5. 认领前后变化

认领前:

assignee = null
candidateUsers / candidateGroups = 有候选人或候选组

认领后:

assignee = zhangsan

6. 适用场景

认领适合以下场景:

  • 多人共享一个任务池

  • 谁先处理谁认领

  • 客服工单

  • 财务审核池

  • 运维任务池

  • 行政审批任务池

7. 注意事项

认领前最好判断任务是否已经被别人认领。

伪代码:

Task task = taskService.createTaskQuery()
        .taskId(taskId)
        .singleResult();

if (task.getAssignee() != null) {
    throw new RuntimeException("任务已被其他人认领");
}

taskService.claim(taskId, userId);

九、取消认领

1. 业务含义

“取消认领”表示认领人放弃当前任务,任务重新回到候选任务池。

取消认领后,其他候选人可以重新认领该任务。

2. 常用 API

taskService.unclaim(taskId);

或者:

taskService.claim(taskId, null);

3. 示例代码

taskService.unclaim(taskId);

4. 流程表现

取消认领不会完成任务,不会推动流程流转。

它只是把任务办理人清空。

取消认领后:

assignee = null

如果任务仍然保留候选组或候选人,则其他人可以继续认领。

5. 适用场景

取消认领适合以下场景:

  • 认领人发现自己无法处理

  • 认领错误

  • 工作量过大,需要释放任务

  • 管理员要求重新分配

6. 注意事项

取消认领时要校验当前用户是否为任务认领人,避免别人取消别人的任务。

伪代码:

Task task = taskService.createTaskQuery()
        .taskId(taskId)
        .singleResult();

if (!currentUserId.equals(task.getAssignee())) {
    throw new RuntimeException("只能取消自己认领的任务");
}

taskService.unclaim(taskId);

十、撤销

1. 业务含义

“撤销”一般是由流程发起人主动取消自己发起的流程。

例如:

  • 发起人提交了用章申请

  • 发现信息填写错误

  • 在审批人未处理前,发起人主动撤销

  • 流程结束或回到草稿状态

2. 撤销和驳回的区别

对比项撤销驳回
操作人通常是发起人通常是审批人
业务含义发起人主动取消审批人不同意
流程结果通常结束结束或退回
是否代表审批失败不一定是

3. 常用实现方式

方式一:直接删除流程实例

runtimeService.deleteProcessInstance(processInstanceId, "发起人撤销申请");

这种方式会终止正在运行的流程实例。

方式二:走撤销流程线

如果希望流程图上能看到撤销节点,可以在 BPMN 中设计“撤销”路径。

例如:

申请人提交 -> 审批中 -> 发起人撤销 -> 撤销结束

然后通过变量控制流程走向。

4. 建议状态值

CANCEL
撤销

或者:

REVOKE
撤销

5. 撤销权限建议

一般建议只有以下人员可以撤销:

流程发起人
系统管理员
特殊授权人员

并且需要限制撤销条件:

审批人未处理前可以撤销
流程未结束前可以撤销
已归档流程不允许撤销
已完成流程不允许撤销

十一、取消

1. 业务含义

“取消”通常表示系统或管理员主动取消流程。

取消和撤销类似,但操作主体不同。

撤销:一般是发起人主动操作
取消:一般是管理员或系统操作

例如:

  • 管理员发现流程发起错误,取消流程

  • 业务数据被删除,自动取消流程

  • 重复发起的流程被系统取消

  • 流程长时间异常,管理员手动取消

2. 常用 API

runtimeService.deleteProcessInstance(processInstanceId, "管理员取消流程");

3. 建议状态值

CANCELLED
已取消

4. 注意事项

取消流程时,建议同步更新业务表状态。

例如业务表:

update biz_apply
set process_status = 'CANCELLED',
    update_time = now()
where process_instance_id = #{processInstanceId};

否则 Flowable 流程实例已经结束,但业务表仍然显示“审批中”,会造成数据不一致。


十二、加签

1. 业务含义

“加签”表示在当前审批流程中临时增加一个或多个审批人。

加签一般分为:

前加签
后加签
并行加签

2. 前加签

前加签表示当前审批人审批之前,先让其他人审批。

示例:

当前审批人 A
A 前加签 B
B 审批完成后,再回到 A

3. 后加签

后加签表示当前审批人审批之后,再增加一个审批人。

示例:

当前审批人 A
A 审批完成后,流转到临时审批人 B
B 审批完成后,再继续原流程

4. 并行加签

并行加签表示同时增加多个人共同审批。

示例:

当前节点需要 A 审批
临时增加 B、C 同时审批
A、B、C 都审批完成后,流程继续

5. Flowable 实现建议

加签属于复杂动态流程调整,建议根据业务复杂度选择:

方式说明
BPMN 预留加签节点稳定、清晰
动态多实例任务适合多人会签
changeState 动态跳转灵活,但维护复杂
自定义业务任务表最灵活,适合复杂 OA

十三、会签

1. 业务含义

会签表示多个审批人共同审批同一个节点。

常见会签规则:

全部通过才通过
任意一人通过即通过
超过半数通过即通过
一人驳回即驳回

2. Flowable 实现方式

Flowable 中通常使用多实例用户任务实现会签。

多实例类型包括:

并行多实例
串行多实例

3. 并行会签

所有审批人同时收到任务。

例如:

A、B、C 同时审批
三人全部完成后进入下一节点

4. 串行会签

审批人按顺序依次审批。

例如:

A 审批完成 -> B 审批 -> C 审批

5. 常用变量

nrOfInstances          总实例数
nrOfCompletedInstances 已完成实例数
nrOfActiveInstances    当前活动实例数
loopCounter            当前循环下标

十四、常见状态字段设计

在实际业务系统中,不建议只依赖 Flowable 自身表判断业务状态,建议在业务表中维护流程状态字段。

1. 业务表状态字段

process_status varchar(50) comment '流程状态'

2. 推荐状态枚举

public enum ProcessStatusEnum {

    DRAFT("DRAFT", "草稿"),

    RUNNING("RUNNING", "审批中"),

    PASS("PASS", "审批通过"),

    REJECT("REJECT", "驳回"),

    RETURN("RETURN", "退回"),

    REVOKE("REVOKE", "撤销"),

    CANCELLED("CANCELLED", "已取消"),

    TERMINATED("TERMINATED", "已终止");

    private final String code;
    private final String name;

    ProcessStatusEnum(String code, String name) {
        this.code = code;
        this.name = name;
    }
}

3. 任务操作状态枚举

public enum TaskOperateTypeEnum {

    COMPLETE("COMPLETE", "通过"),

    REJECT("REJECT", "驳回"),

    RETURN("RETURN", "退回"),

    TRANSFER("TRANSFER", "转办"),

    DELEGATE("DELEGATE", "委派"),

    RESOLVE("RESOLVE", "完成委派"),

    CLAIM("CLAIM", "认领"),

    UNCLAIM("UNCLAIM", "取消认领"),

    REVOKE("REVOKE", "撤销"),

    CANCEL("CANCEL", "取消");

    private final String code;
    private final String name;

    TaskOperateTypeEnum(String code, String name) {
        this.code = code;
        this.name = name;
    }
}

十五、审批操作日志表设计

为了方便展示审批记录,建议单独设计审批日志表,不要完全依赖 Flowable 历史表。

1. 审批日志表字段建议

CREATE TABLE wf_task_approve_record (
    id BIGINT PRIMARY KEY AUTO_INCREMENT COMMENT '主键ID',
    process_instance_id VARCHAR(64) NOT NULL COMMENT '流程实例ID',
    task_id VARCHAR(64) DEFAULT NULL COMMENT '任务ID',
    task_name VARCHAR(255) DEFAULT NULL COMMENT '任务名称',
    business_key VARCHAR(100) DEFAULT NULL COMMENT '业务Key',

    operate_type VARCHAR(50) NOT NULL COMMENT '操作类型:通过、驳回、退回、转办、委派等',
    operate_user_id VARCHAR(64) NOT NULL COMMENT '操作人ID',
    operate_user_name VARCHAR(100) DEFAULT NULL COMMENT '操作人名称',

    old_assignee VARCHAR(64) DEFAULT NULL COMMENT '原办理人',
    new_assignee VARCHAR(64) DEFAULT NULL COMMENT '新办理人',

    target_activity_id VARCHAR(100) DEFAULT NULL COMMENT '目标节点ID',
    target_activity_name VARCHAR(255) DEFAULT NULL COMMENT '目标节点名称',

    comment VARCHAR(1000) DEFAULT NULL COMMENT '审批意见',
    operate_time DATETIME NOT NULL COMMENT '操作时间',

    create_time DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间'
) COMMENT='流程审批操作记录表';

2. 为什么要设计审批日志表

原因如下:

Flowable 历史表更偏引擎层,不完全适合业务展示
审批意见、转办原因、退回原因需要单独保存
前端审批轨迹需要统一展示
方便后期统计审批效率
方便排查流程问题
方便做待办、已办、我的申请展示

十六、常见操作代码汇总

1. 审批通过

public void pass(String taskId, String opinion) {
    Map<String, Object> variables = new HashMap<>();
    variables.put("approvalStatus", "PASS");
    variables.put("approved", true);
    variables.put("approvalOpinion", opinion);

    taskService.complete(taskId, variables);
}

2. 驳回

public void reject(String taskId, String opinion) {
    Map<String, Object> variables = new HashMap<>();
    variables.put("approvalStatus", "REJECT");
    variables.put("approved", false);
    variables.put("approvalOpinion", opinion);

    taskService.complete(taskId, variables);
}

3. 转办

public void transfer(String taskId, String newAssignee, String reason) {
    Task task = taskService.createTaskQuery()
            .taskId(taskId)
            .singleResult();

    if (task == null) {
        throw new RuntimeException("任务不存在");
    }

    String oldAssignee = task.getAssignee();

    taskService.setAssignee(taskId, newAssignee);

    // 保存转办日志
    // oldAssignee -> newAssignee
}

4. 委派

public void delegate(String taskId, String delegateUserId, String reason) {
    Task task = taskService.createTaskQuery()
            .taskId(taskId)
            .singleResult();

    if (task == null) {
        throw new RuntimeException("任务不存在");
    }

    taskService.delegateTask(taskId, delegateUserId);

    // 保存委派日志
}

5. 完成委派

public void resolveDelegateTask(String taskId, String opinion) {
    Map<String, Object> variables = new HashMap<>();
    variables.put("delegateOpinion", opinion);

    taskService.resolveTask(taskId, variables);
}

6. 认领

public void claim(String taskId, String userId) {
    Task task = taskService.createTaskQuery()
            .taskId(taskId)
            .singleResult();

    if (task == null) {
        throw new RuntimeException("任务不存在");
    }

    if (task.getAssignee() != null) {
        throw new RuntimeException("任务已被认领");
    }

    taskService.claim(taskId, userId);
}

7. 取消认领

public void unclaim(String taskId, String currentUserId) {
    Task task = taskService.createTaskQuery()
            .taskId(taskId)
            .singleResult();

    if (task == null) {
        throw new RuntimeException("任务不存在");
    }

    if (!currentUserId.equals(task.getAssignee())) {
        throw new RuntimeException("只能取消自己认领的任务");
    }

    taskService.unclaim(taskId);
}

8. 撤销流程

public void revoke(String processInstanceId, String reason) {
    runtimeService.deleteProcessInstance(processInstanceId, reason);

    // 同步更新业务表状态为 REVOKE
}

十七、前端按钮显示建议

审批系统中,不同状态下应该显示不同按钮。

1. 我的待办

通过
驳回
退回
转办
委派

2. 候选任务

认领

3. 已认领任务

取消认领
通过
驳回
退回

4. 我的申请

撤销
查看进度

5. 管理员

取消流程
强制转办
查看流程变量
查看流程图

十八、推荐业务状态流转

1. 正常通过

草稿 -> 审批中 -> 审批通过

2. 驳回结束

草稿 -> 审批中 -> 驳回

3. 退回修改

草稿 -> 审批中 -> 退回修改 -> 重新提交 -> 审批中 -> 审批通过

4. 发起人撤销

草稿 -> 审批中 -> 已撤销

5. 转办

审批中 -> 转办给其他人 -> 审批中

6. 委派

审批中 -> 委派给其他人 -> 完成委派 -> 回到原审批人 -> 审批中

十九、开发注意事项

1. 不要把转办当成通过

转办只是换人处理,不会推动流程。

错误理解:

转办 = 当前人处理完了

正确理解:

转办 = 当前任务换一个办理人

2. 不要把委派当成转办

委派后任务最终还要回到原负责人。

委派 = 临时交给别人处理
转办 = 彻底交给别人处理

3. 退回最好在流程图中明确设计

如果业务比较固定,建议在 BPMN 中画出退回线。

优点:

流程清晰
历史轨迹清晰
方便维护
不容易出错

4. 自由退回要谨慎使用

动态跳转虽然灵活,但容易导致流程图轨迹复杂,后期维护成本较高。

5. 审批意见建议单独保存

不要只依赖流程变量保存审批意见。

建议同时保存到业务审批记录表,方便前端展示和后期统计。

6. 业务表状态必须同步更新

Flowable 只管理流程,业务系统仍然需要维护自己的业务状态。

例如:

审批中
审批通过
驳回
退回
撤销
取消

否则会出现流程已结束,但业务表仍然显示审批中的问题。


二十、总结

Flowable 7.0 中常见审核操作可以简单理解为:

通过:当前任务完成,流程继续向后走。

驳回:审批不同意,流程失败或进入驳回路径。

退回:要求修改,流程回到申请人或指定节点。

转办:当前任务换人处理,原办理人不再负责。

委派:临时交给别人处理,处理完还要回到原办理人。

认领:候选任务被某个人领取,变成个人待办。

取消认领:放弃已认领任务,任务回到候选池。

撤销:发起人主动取消流程。

取消:管理员或系统取消流程。

在实际项目中,建议做到以下几点:

1. Flowable 负责流程流转。
2. 业务表负责业务状态。
3. 审批记录表负责展示审批轨迹。
4. 流程变量负责控制流程走向。
5. 转办、委派、退回、驳回必须区分清楚。

只有把这些状态区分清楚,工作流系统的待办、已办、我的申请、审批记录、流程图追踪才能稳定、清晰、易维护。

Flowable 全局监听 监听流程的启动和流程的结束 下表列出引擎中的所有事件类型。每种类型对应org.flowable.engine.common.api.delegate.event.FlowableEventType中的一个枚举值。 阅读详情

相关推荐

Flowable26任务管理全解析:待签、待办、转办与委派的实战应用

本文深入解析了Flowable26工作流引擎中的核心任务管理操作,包括待签、待办、转办与委派。通过生动的业务场景类比和详实的代码示例,阐述了每种操作的概念差异、适用场景及API使用方法,并提供了混合场景下的实战指南与性能优化建议,帮助开发者构建灵活稳健的流程应用。

c6d7e8f9g的博客 1088

JeeSite4 Flowable入门教程

购课须知:由于部分视频教程因为转码原因可能未上传成功,购课学员请留言咨询,补发未成功的视频教程!

flowable常见操作

描述:A将任务转办给B,B审核完成就到下一个节点,不会再到A。描述:名词介绍:A将任务转办给B,B审核完成就再回到A。描述:业务数据的审核需要区别不同用户和委派任务的审核。

youxiaxiaomage的博客 896

【Flowable | 第五篇】flowable工作流审批动作:提交/委托/转办/退回/终止

flowable工作流审批动作:提交/委托/转办/退回/终止

踢桃的成长之路 5582

Flowable 7.0.0 release

Flowable 7.0.0 release

宁波阿成的博客 1527

flowable-7.0.0.M

flowable-7.0.0.Mflowable-7.0.0.M

Flowable 7.0 版本新特性:更高效、更灵活的业务流程管理

作为一个业务流程管理(BPM)工具,Flowable 一直以高效、灵活、易用等特点受到广大用户的青睐。而最近发布的 Flowable 7.0 版本,则进一步优化了其功能和性能,为用户带来更加出色的使用体验。本文将介绍 Flowable 7.0 版本的几个新特性。

爱媳妇儿爱编程 9571

ARM芯片内部的高速公路:手把手教你用AMBA Designer配置NIC-400互连控制器

本文详细介绍了如何使用AMBA Designer工具配置ARM芯片中的NIC-400互连控制器,涵盖从基础拓扑构建到高级QoS设置的完整流程。通过实际案例演示,帮助开发者掌握AXI协议下的高效片上网络设计,提升SoC性能与能效比。

weixin_26750481的博客 310

FLOWABLE全面升级之任务交接、转办、转派

FLOWABLE全面升级之任务交接、转办、转派

weixin_48278764的博客 1105

UVM实战 卷I学习笔记1——简单的UVM验证平台:只有driver

目录验证平台的组成最简单的验证平台——只有driverUVM如何搭建driver:加入factory机制加入objection机制加入virtual interface 个人《UVM实战卷I》学习随手笔记,此书作者:张强 验证平台的组成 一个验证平台要实现的基本功能: 模拟DUT的各种真实使用情况——给DUT施加各种激励→driver实现激励功能; 根据DUT的输出判断DUT行为是否与预期符合→scoreboard(也称为checker)——需注意判断的东西和判断的标准是什么; 收集DUT的输出并传递

weixin_41979380的博客 3889

【机器学习】Anaconda安装后打不开jupyter notebook(网页不自动跳出)

anaconda安装成功以后,jupyter notebook可以出现打开的路径,能够手动复制粘贴地址路径打开,却不能自动跳转到网页。解决的办法是在配置文件中加入指定的浏览器配置信息。

weixin_43416960的博客 4万+

Flowable 7.0.0.M2 版本功能

Flowable 7.0.0.M2 版本功能

分享牛 3460

linux redis7 完整的集群搭建过程

一。安装: 1.1 说明: Redis官方只提供了源码,并没有提供经过编译之后的安装包。 因此,安装Redis,要先编译、后安装。(即源码安装方式) 注意:需要联网安装 1.2 安装编译的工具: yum install gcc gcc-c++ -y 1.3 下载tar包,上传到linux服务器,解压配置环境变量 1.4 cd +解压的目录下:编译 make 注意:如果编译失败,请重新进行解压编译,...

m0_38028438的博客 719

Flowable 7.0.0 发布说明

Flowable 7.0.0是Flowable引擎的第一个稳定版本,专注于Spring Boot 3、Spring 6和Java 17的升级。REST应用程序要求使用支持Jakarta 9的servlet容器/应用服务器。此版本重点关注BPMN、CMMN、DMN和事件注册引擎的主Flowable引擎和REST API。这意味着没有UI应用程序、内容和表单引擎,以及Mule和其他一些模块被移除。

weixin_43841461的博客 3097

Python爬虫实战:巧用HEAD请求和Cookie令牌绕过沃尔玛反爬(附完整代码)

本文详细介绍了如何利用Python爬虫技术,通过HEAD请求和Cookie令牌绕过沃尔玛的反爬机制。文章深入解析了人机验证系统的运作原理,并提供了完整的工程化实现代码,包括令牌池设计、高并发架构和异常处理策略,帮助开发者高效采集电商数据。

weixin_29046035的博客 1007

Google Earth Engine 红树林制图方法的代码(三个模块)

谷歌地球引擎红树林制图方法(GEM)提供了一种直观、易用且可复制的工具,适用于广泛的非专业沿海管理者和决策者。该工具全面回顾并整合了相关的红树林遥感文献,并利用云计算的力量,包括简化的基于图像的潮汐校准方法。GEM 可免费用于非营利用途,并在 GEE 中运行,包含全面且详细注释的代码。GEM 专门设计用于绘制全球范围内多日期红树林分布并量化其动态变化。目前可用的工具和方法未能充分利用沿海管理者通常持有的丰富地方专业知识——GEM 致力于填补这一空白,帮助结合地方专业知识与 GEE 的云计算能力。

此星光明博客 559

工作流实战_18_flowable 流程任务的转办

项目地址:https://gitee.com/lwj/flowable.git 分支flowable-base 视频讲解地址 https://www.bilibili.com/video/av78184848/ 1、演示2、代码分享 public ReturnVo<String> turnTask(TurnTaskVo turnTaskVo) { ReturnVo&lt...

Gblfy_Blog 3165

用 SAML 2.0 Bearer Assertion 配置 ABAP OAuth 2.0 令牌交换

摘要: SAP系统集成中,身份跨系统传递是关键挑战。OAuth 2.0的SAML 2.0 Bearer Assertion grant机制通过SAML断言换取访问令牌,实现安全身份传递。配置核心在ABAP的SOAUTH2事务码,需绑定可信SAML身份提供商(IdP)并指定访问范围。实际应用中,需确保SSL加密传输,正确配置SAML IdP信任关系,并为OAuth客户端分配专用系统用户。常见问题包括证书不匹配、权限配置不当等,需分层控制权限边界以保障安全。

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 835

Flowable工作流简单入门

flowable我认为是傻瓜式审批流程或者说专业术语叫工作流,我之前写审批流代码的时候,通过改变字段的值,来区分各个阶段的状态,开发起来比较简单粗暴+无脑。flowable可以编程可视图画创建审批流程,例如:审批节点,驳回,委派,转办,拒绝等功能。在实际开发中功能更加全面。个人认为可以参考钉钉上面的审批流。

QPiker的博客 1495

Python二级考试题目及答案解析(含刷题软件)

答案:A 解析:print()函数可以在屏幕上输出指定的字符串或变量,input()函数用于从键盘获取用户输入,int()函数可以将指定的字符串或浮点数转换为整数,float()函数可以将指定的字符串或整数转换为浮点数。答案:A 解析:int()函数可以将字符串转换为整数,float()函数可以将字符串转换为浮点数,str()函数可以将任意类型的变量转换为字符串,bool()函数可以将任意类型的变量转换为布尔值。

YOLO 1万+

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

Flowable 工作流(待签、待办、转办、委派)相关功能

1.候选人的任务签收/候选组的任务签收/完成任务 2.转办任务 3.委派任务与代办任务 二、主要接口有: 1.候选人待签收任务列表:List tasks = taskService.createTaskQuery().taskCandidateUser(userId).list(); 候选组待签收任务列表: List tasks = taskService.createTaskQuery().taskCandidateGroup(userGroup).list(); 签收动作:taskService.cla

qq_44293888的博客 1万+

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

activiti画流程图、部署、启动、审批、驳回

工作流activiti 业务过程的部分或整体在计算机应用环境下自动化,使多个参与者按照某种预定义的规则进行。 activiti版本5.13 一、画流程图 1、创建web项目,安装activiti插件 2、引入activiti相关jar包 3、新建流程图—单实例流程 3-1、节点只需要设置Assignee 3-2、对线的设置 如果是提交,outcome==′提交′如果是批准,{outcome=='提交'} 如果是批准,outcome==′提交′如果是批准,{outcome==‘批准’} 如果是驳回,${o

weixin_41632551的博客 5219

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

18.flowable 流程任务的转办

项目地址:https://gitee.com/lwj/flowable.git 分支flowable-demo 视频讲解地址 https://space.bilibili.com/485524575/channel/detail?cid=94579 1、演示 2、代码分享 public ReturnVo<String> turnTask(TurnTaskVo turnTaskVo)...

liuwenjun05101的博客 5678

【flowable】十一、flowable加签和转签

flowable加签和转签同时让多人处理任务,但是不同于网关操作。1、向前加签 任务在A这里,A这个时候需要BCD核对一下,等BCD核对之后又回到A这里 2、向后加签 任务在A这里,A这个时候需要BCD处理这个事情,处理完毕之后就不用管了,继续后面的审批环节创建一个新的流程:就一个简单的流程,员工请假申请,总经理审批 部署流程并启动: 员工完成任务: 正常流程,员工完成任务后到总经理审批但,实际中会出现特殊情况,还需要董事长审批,但在流程设计中并没有董事长这个流程节点。所以需要用到加签的功能。加签功能 任

return 5983

flowable工作流-连续委派丢失原委托人问题

基于开源项目KonBAI / RuoYi-Flowable-Plus使用的部分功能调整。原代码存在连续委派时,任务无法回到最初委派人的情况。

qq_36782325的博客 1213
上一篇: vue3 使用element-ui实现el-table懒加载
漂落人间
博客等级 码龄13年 1粉丝 7原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值