类似钉钉的回调通知机制,主要通过两个监听实现:
1.实现TaskEventListener接口,监听任务变化
/**
* 全局任务时间监听
*
* @author LTX
*/
@Slf4j
@Service
public class MyTaskEventListener implements TaskEventListener {
@Autowired
private IActService actService;
@Override
public void onEvent(RuntimeEvent runtimeEvent) {
//任务
TaskImpl task = (TaskImpl) runtimeEvent.getEntity();
log.info("processInstanceId: {}, ProcessDefinitionId: {}, taskId: {}", task.getProcessInstanceId(), task.getProcessDefinitionId(), task.getId());
if (runtimeEvent instanceof TaskActivatedEvent) {
log.info("任务激活, processInstanceId: {}, taskId: {}", task.getProcessInstanceId(), task.getId());
} else if (runtimeEvent instanceof TaskAssignedEvent) {
log.info("任务被指派, processInstanceId: {}, taskId: {}", task.getProcessInstanceId(), task.getId());
//TODO 你的代码
} else if (runtimeEvent instanceof TaskCancelledEvent) {
//任务取消:
//CANCELED表示任务被取消,比如一个或签节点,同时有多个任务,其中一个审批人完成审批后,剩余的审批任务可以置为CANCELED状态。
log.info("任务取消(会签任务-取消), processInstanceId: {}, taskId: {}", task.getProcessInstanceId(), task.getId());
//TODO 你的代码
} else if (runtimeEvent instanceof TaskCompletedEvent) {
//任务完成,执行这里
log.info("任务完成, processInstanceId: {}, taskId: {}", task.getProcessInstanceId(), task.getId());
//TODO 你的代码
} else if (runtimeEvent instanceof TaskCreatedEvent) {
log.info("任务创建, processInstanceId: {}, taskId: {}", task.getProcessInstanceId(), task.getId());
} else if (runtimeEvent instanceof TaskSuspendedEvent) {
log.info("任务暂停, processInstanceId: {}, taskId: {}", task.getProcessInstanceId(), task.getId());
} else {
log.info("MyTaskEventListener_未知事件, processInstanceId: {}, taskId: {}", task.getProcessInstanceId(), task.getId());
}
}
}
2.实现ProcessEventListener接口,监听流程变化
/**
* 全局流程事件监听
*
* @author LTX
*/
@Slf4j
@Service
public class MyProcessEventListener implements ProcessEventListener {
@Autowired
private IActService actService;
@Override
public void onEvent(RuntimeEvent runtimeEvent) {
String processInstanceId = "";
if (runtimeEvent.getEntity() instanceof ProcessInstanceImpl) {
ProcessInstanceImpl pi = (ProcessInstanceImpl) runtimeEvent.getEntity();
processInstanceId = pi.getId();
}
if (runtimeEvent instanceof ProcessStartedEvent) {
log.info("流程启动, {}", processInstanceId);
} else if (runtimeEvent instanceof ProcessCompletedEvent) {
//TODO 回调业务,流程正常结束
log.info("流程结束, {}", processInstanceId);
//TODO 你的代码
} else if (runtimeEvent instanceof ProcessCancelledEvent) {
//TODO 回调业务,流程拒绝/流程撤销
log.info("流程取消, {}", processInstanceId);
} else if (runtimeEvent instanceof ProcessSuspendedEvent) {
log.info("流程挂起, {}", processInstanceId);
} else if (runtimeEvent instanceof ProcessResumedEvent) {
log.info("流程恢复, {}", processInstanceId);
} else if (runtimeEvent instanceof ProcessCreatedEvent) {
log.info("流程创建, {}", processInstanceId);
} else if (runtimeEvent instanceof SequenceFlowEvent) {
log.info("连线事件, {}", processInstanceId);
} else if (runtimeEvent instanceof VariableCreatedEvent) {
log.info("创建参数, {}", processInstanceId);
} else {
log.info("MyProcessEventListener_未知事件, {}", processInstanceId);
}
}
}
可通过post回调外部系统接口,把流程数据信息传给外部系统,主要的信息:
实例id、流程状态
整个交互过程:
1.外部系统api发起流程,接口成功之后,把返回的流程实例id存起来;
2.审批流回调外部系统接口,外部系统根据第1步的实例id做相应处理,这里注意接口的幂等;
最大努力通知机制(和钉钉一样的方案):
避免流程回调外部系统接口时候,外部系统接口失败,外部系统断网、停机、卡死...等情况,审批流还提供了一个查询流程状态的接口给外部系统查询调用;外部系统可定时用审批状态是“审批中”的实例id去流程平台取状态,然后做处理;
所以:外部系统对接流程平台,需要编写3个操作:
1.向流程平台发起流程
2.给流程平台回调的post接口
3.用实例id从流程平台查询流程状态