知会的需求很简单:流程走到某个位置时,通知另一个人;接收人可以查看进展,但是否阅读,不影响主流程继续运行。因此,知会应当和“必须完成后才能往下走的审批任务”分开。

两种常见的承载方式

一种是只在业务系统中保存通知记录,通过站内消息或待阅列表展示。另一种是创建不关联流程执行的独立任务,借用任务列表显示提醒,再用业务表保存它与流程的关系。

选择第二种方式时,必须理解独立任务的含义。Activiti 7.1.0.M6 引擎层的 TaskService.newTask() 创建的是不关联流程实例的任务,随后需要显式保存。因此它没有自动获得某个流程实例的业务关联,不应该期待创建后自然带上 businessKey。TaskService 接口说明

下面是创建提醒的局部示例,不是 BPMN 中新增审批节点:

org.activiti.engine.task.Task notice = taskService.newTask();
notice.setName("采购申请知会");
notice.setAssignee(recipientId);
notice = taskService.saveTask(notice);

String noticeTaskId = notice.getId();
// 在同一业务事务或可靠的一致性流程中保存通知关联记录。

recipientId 应来自经过授权的接收人选择,不能直接信任客户端传入的任意账号。

用明确字段保存关联

不要把 businessKey 塞进 taskName。任务名用于展示,可能重复,也可能被修改;用它兼任主键,会让查询依赖一个隐蔽约定。

业务知会记录至少需要分清这些职责:

字段用途
通知 ID唯一识别一次知会
流程实例 ID指向具体的一轮流程
业务标识关联申请单等业务对象
接收人、租户确认归属和访问范围
来源任务或事件标识识别为什么发出这次通知
阅读状态、阅读时间控制待阅列表
独立任务 ID(如使用)关联引擎提醒任务

是否能仅通过业务标识定位流程,还要考虑多次发起的问题,见 businessKey 与实例关联。

一次知会怎样流转

  1. 业务动作或流程事件触发知会,先确认当前操作者有通知该接收人的权限。
  2. 按“事件+接收人”等业务幂等键创建通知,防止事务重试或重复回调生成多条提醒。
  3. 接收人登录后,只查询属于自己和当前租户的未读记录。
  4. 打开详情时,服务端根据记录校验访问权限,再读取业务资料和流程信息。
  5. 阅读后更新已读状态;使用独立任务时,按选定生命周期完成或清理该任务,但不完成主流程的审批任务。

如果业务记录和引擎任务不在同一事务中,需要通过可靠事件、重试及对账避免“有提醒没有关联”或“有关联没有提醒”。

已读不等于撤销权限

不再显示红点,只说明提醒已处理,不能自动代表接收人失去了查看权。反过来,收到提醒也不意味着可以查看所有业务字段。

服务端需要独立处理通知状态和数据权限,包括转岗、离职、撤销知会,以及流程结束后的访问规则。知道链接或猜到 businessKey 不能成为授权依据;前端隐藏按钮也不能代替接口检查。