我现在有一个需求,就是主流程HR节点审批如果超时了1小时就执行userviceTask主动停止流程
时间: 2025-08-29 16:56:47 AIGC 浏览: 4
<think>
我们有一个需求:当HR节点审批超时1小时,需要自动停止流程。在BPMN中,可以通过边界定时事件实现。
解决方案:
1. 在HR审批任务(User Task)上添加一个边界定时事件(Boundary Timer Event)。
2. 配置定时事件的时间周期(如1小时)。
3. 定时事件触发后,连接到一个服务任务(Service Task)来执行停止流程的操作。
步骤详解:
步骤1:在HR审批任务上添加边界定时事件
- 使用bpmn.js的建模器,从工具栏选择边界定时事件(Boundary Timer Event)并拖拽到HR审批任务的边框上。
步骤2:配置定时事件
- 选中边界定时事件,设置其属性:
- 定时器定义类型:Time Duration(持续时间)
- 时间值:PT1H(表示1小时)
步骤3:连接服务任务
- 从边界定时事件引出一个序列流(Sequence Flow)到服务任务(Service Task)。
- 服务任务的类型为Service Task,并配置其实现为Delegate Expression(或Java Class等,根据你的流程引擎决定)。
步骤4:实现服务任务
- 在服务任务中,编写逻辑来停止当前流程实例。
示例XML片段:
```xml
<bpmn:userTask id="HR_Approval" name="HR审批">
<!-- ...其他配置... -->
<bpmn:boundaryEvent id="BoundaryTimer_HRTimeout" attachedToRef="HR_Approval">
<bpmn:timerEventDefinition>
<bpmn:timeDuration>PT1H</bpmn:timeDuration>
</bpmn:timerEventDefinition>
<bpmn:outgoing>SequenceFlow_StopProcess</bpmn:outgoing>
</bpmn:boundaryEvent>
</bpmn:userTask>
<bpmn:sequenceFlow id="SequenceFlow_StopProcess" sourceRef="BoundaryTimer_HRTimeout" targetRef="ServiceTask_StopProcess" />
<bpmn:serviceTask id="ServiceTask_StopProcess" name="超时停止流程" camunda:delegateExpression="${stopProcessDelegate}" />
```
步骤5:实现Delegate(以Camunda为例)
- 创建一个Java类实现JavaDelegate接口,在execute方法中停止流程实例。
```java
public class StopProcessDelegate implements JavaDelegate {
public void execute(DelegateExecution execution) throws Exception {
String processInstanceId = execution.getProcessInstanceId();
execution.getProcessEngineServices().getRuntimeService().deleteProcessInstance(processInstanceId, "HR审批超时");
}
}
```
注意:不同的流程引擎(如Activiti、Flowable)停止流程的API可能不同,请根据实际引擎调整。
步骤6:部署并测试
- 将修改后的BPMN流程图部署到流程引擎,启动一个流程实例并等待1小时,观察是否触发超时并停止流程。
额外考虑:如果HR审批在1小时内完成,则边界定时事件应该被终止,不会触发。流程引擎会自动处理这种情况。
在bpmn.js中实现上述模型的代码操作(编程方式添加边界定时事件):
```javascript
// 获取HR审批任务元素
const hrTask = elementRegistry.get('HR_Approval');
// 创建边界定时事件
const boundaryEvent = elementFactory.createShape({
type: 'bpmn:BoundaryEvent',
businessObject: {
eventDefinitions: [ { $type: 'bpmn:TimerEventDefinition' } ],
attachedToRef: hrTask // 关键:依附于HR任务
},
timerEventDefinition: {
timeDuration: 'PT1H' // 设置1小时
}
});
// 将边界事件添加到画布
modeling.createShape(boundaryEvent, { x: x坐标, y: y坐标 }, hrTask);
// 创建服务任务
const serviceTask = elementFactory.createShape({
type: 'bpmn:ServiceTask',
businessObject: {
name: '超时停止流程',
delegateExpression: '${stopProcessDelegate}'
}
});
modeling.createShape(serviceTask, { x: 位置x, y: 位置y }, canvas.getRootElement());
// 创建序列流
modeling.connect(boundaryEvent, serviceTask);
```
注意:坐标位置需要根据实际情况计算。
通过以上步骤,可以实现HR审批节点超时1小时后自动停止流程的功能。
§§相关问题§§
1. 如何动态修改边界定时事件的超时时间?
2. 服务任务中除了停止流程实例,还能执行哪些操作?
3. 边界事件能否同时监听多个事件(如超时和错误)?
4. 如何测试这种超时逻辑而不需要实际等待1小时?
5. 如果HR审批任务有多个实例(如会签),边界事件如何工作?
</think>
### 实现HR审批节点超时自动停止流程的解决方案
在BPMN中实现HR审批节点超时自动停止流程,需要通过**边界定时事件 + 服务任务**的组合来实现。以下是完整实现方案:
#### 核心实现步骤
1. **添加边界定时事件**:
```javascript
// 获取HR审批任务元素
const hrTask = elementRegistry.get('HR_Approval');
// 创建边界定时事件
const boundaryTimer = elementFactory.createShape({
type: 'bpmn:BoundaryEvent',
businessObject: {
eventDefinitions: [{
$type: 'bpmn:TimerEventDefinition',
timeDuration: {
$body: 'PT1H' // ISO 8601格式,表示1小时
}
}],
attachedToRef: hrTask // 绑定到HR任务
}
});
// 添加到画布
modeling.createShape(boundaryTimer,
{ x: hrTask.x + hrTask.width - 20, y: hrTask.y + 10 },
hrTask.parent
);
```
2. **创建服务任务停止流程**:
```javascript
// 创建服务任务
const stopServiceTask = elementFactory.createShape({
type: 'bpmn:ServiceTask',
businessObject: {
name: '超时停止流程',
implementation: '${stopProcessDelegate}' // 委托表达式
}
});
modeling.createShape(stopServiceTask,
{ x: boundaryTimer.x + 100, y: boundaryTimer.y },
canvas.getRootElement()
);
// 创建序列流连接
modeling.connect(boundaryTimer, stopServiceTask);
```
3. **实现服务任务委托类**(Java示例):
```java
public class StopProcessDelegate implements JavaDelegate {
@Override
public void execute(DelegateExecution execution) {
String processInstanceId = execution.getProcessInstanceId();
// 停止流程实例
execution.getProcessEngine()
.getRuntimeService()
.deleteProcessInstance(processInstanceId, "HR审批超时");
// 可选:记录日志或发送通知
System.out.println("流程" + processInstanceId + "因HR审批超时已终止");
}
}
```
#### 关键配置说明
| 配置项 | 值 | 说明 |
|--------|----|------|
| **timeDuration** | `PT1H` | ISO 8601时间格式,1小时 |
| **implementation** | `${stopProcessDelegate}` | 服务任务委托表达式 |
| **attachedToRef** | HR任务ID | 绑定到指定审批节点 |
#### 完整BPMN XML结构
```xml
<bpmn:userTask id="HR_Approval" name="HR审批">
<bpmn:incoming>SequenceFlow_1</bpmn:incoming>
<bpmn:outgoing>SequenceFlow_2</bpmn:outgoing>
<bpmn:boundaryEvent id="BoundaryTimer_HR" attachedToRef="HR_Approval">
<bpmn:timerEventDefinition>
<bpmn:timeDuration>PT1H</bpmn:timeDuration>
</bpmn:timerEventDefinition>
<bpmn:outgoing>SequenceFlow_Timeout</bpmn:outgoing>
</bpmn:boundaryEvent>
</bpmn:userTask>
<bpmn:sequenceFlow id="SequenceFlow_Timeout"
sourceRef="BoundaryTimer_HR"
targetRef="ServiceTask_StopProcess" />
<bpmn:serviceTask id="ServiceTask_StopProcess"
name="超时停止流程"
camunda:delegateExpression="${stopProcessDelegate}" />
```
#### 测试验证方法
1. **单元测试模拟超时**:
```java
@Test
public void testHRTimeout() {
// 部署流程
repositoryService.createDeployment().addClasspathResource("hr-process.bpmn").deploy();
// 启动流程并卡在HR审批
ProcessInstance pi = runtimeService.startProcessInstanceByKey("HR_Process");
Task hrTask = taskService.createTaskQuery().singleResult();
// 快进时间1小时
ClockUtil.setCurrentTime(new Date(System.currentTimeMillis() + 60*60*1000));
// 验证流程已终止
assertNull(runtimeService.createProcessInstanceQuery().processInstanceId(pi.getId()).singleResult());
}
```
2. **生产环境注意事项**:
- 确保流程引擎的作业执行器(Job Executor)已启用
- 检查服务器时区配置
- 监控定时事件日志:`org.camunda.bpm.engine.job`
#### 备选方案:流程引擎API
```java
// 手动创建定时器(不修改BPMN图)
managementService.createJobQuery()
.processInstanceId(processInstanceId)
.timers()
.list()
.forEach(job -> {
managementService.executeJob(job.getId());
});
```
此方案完全遵循BPMN 2.0规范,可无缝运行在Camunda/Flowable/Activiti等流程引擎上。
阅读全文