知会的需求很简单:流程走到某个位置时,通知另一个人;接收人可以查看进展,但是否阅读,不影响主流程继续运行。因此,知会应当和“必须完成后才能往下走的审批任务”分开。
两种常见的承载方式
一种是只在业务系统中保存通知记录,通过站内消息或待阅列表展示。另一种是创建不关联流程执行的独立任务,借用任务列表显示提醒,再用业务表保存它与流程的关系。
选择第二种方式时,必须理解独立任务的含义。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 与实例关联。
一次知会怎样流转
- 业务动作或流程事件触发知会,先确认当前操作者有通知该接收人的权限。
- 按“事件+接收人”等业务幂等键创建通知,防止事务重试或重复回调生成多条提醒。
- 接收人登录后,只查询属于自己和当前租户的未读记录。
- 打开详情时,服务端根据记录校验访问权限,再读取业务资料和流程信息。
- 阅读后更新已读状态;使用独立任务时,按选定生命周期完成或清理该任务,但不完成主流程的审批任务。
如果业务记录和引擎任务不在同一事务中,需要通过可靠事件、重试及对账避免“有提醒没有关联”或“有关联没有提醒”。
已读不等于撤销权限
不再显示红点,只说明提醒已处理,不能自动代表接收人失去了查看权。反过来,收到提醒也不意味着可以查看所有业务字段。
服务端需要独立处理通知状态和数据权限,包括转岗、离职、撤销知会,以及流程结束后的访问规则。知道链接或猜到 businessKey 不能成为授权依据;前端隐藏按钮也不能代替接口检查。