ai-engineering-init 1.7.0 → 1.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/agents/bug-analyzer.md +103 -0
- package/.claude/agents/code-reviewer.md +115 -5
- package/.claude/agents/image-reader.md +154 -0
- package/.claude/agents/loki-runner.md +80 -0
- package/.claude/agents/mysql-runner.md +81 -0
- package/.claude/agents/requirements-analyzer.md +162 -0
- package/.claude/agents/task-fetcher.md +75 -0
- package/.claude/commands/dev.md +29 -0
- package/.claude/commands/next.md +31 -1
- package/.claude/commands/progress.md +23 -1
- package/.claude/hooks/skill-forced-eval.js +46 -62
- package/.claude/settings.json +10 -1
- package/.claude/skills/api-development/SKILL.md +179 -130
- package/.claude/skills/architecture-design/SKILL.md +102 -212
- package/.claude/skills/backend-annotations/SKILL.md +166 -220
- package/.claude/skills/bug-detective/SKILL.md +225 -186
- package/.claude/skills/code-patterns/SKILL.md +127 -244
- package/.claude/skills/collaborating-with-codex/SKILL.md +96 -113
- package/.claude/skills/crud-development/SKILL.md +226 -307
- package/.claude/skills/data-permission/SKILL.md +131 -202
- package/.claude/skills/database-ops/SKILL.md +158 -355
- package/.claude/skills/error-handler/SKILL.md +224 -285
- package/.claude/skills/file-oss-management/SKILL.md +174 -169
- package/.claude/skills/git-workflow/SKILL.md +123 -341
- package/.claude/skills/json-serialization/SKILL.md +121 -137
- package/.claude/skills/performance-doctor/SKILL.md +83 -89
- package/.claude/skills/redis-cache/SKILL.md +134 -185
- package/.claude/skills/scheduled-jobs/SKILL.md +187 -224
- package/.claude/skills/security-guard/SKILL.md +168 -276
- package/.claude/skills/sms-mail/SKILL.md +266 -228
- package/.claude/skills/social-login/SKILL.md +257 -195
- package/.claude/skills/tenant-management/SKILL.md +172 -188
- package/.claude/skills/utils-toolkit/SKILL.md +214 -222
- package/.claude/skills/websocket-sse/SKILL.md +251 -172
- package/.claude/skills/workflow-engine/SKILL.md +178 -250
- package/.codex/skills/api-development/SKILL.md +179 -130
- package/.codex/skills/architecture-design/SKILL.md +102 -212
- package/.codex/skills/backend-annotations/SKILL.md +166 -220
- package/.codex/skills/bug-detective/SKILL.md +225 -186
- package/.codex/skills/code-patterns/SKILL.md +127 -244
- package/.codex/skills/collaborating-with-codex/SKILL.md +96 -113
- package/.codex/skills/crud-development/SKILL.md +226 -307
- package/.codex/skills/data-permission/SKILL.md +131 -202
- package/.codex/skills/database-ops/SKILL.md +158 -355
- package/.codex/skills/dev/SKILL.md +476 -131
- package/.codex/skills/error-handler/SKILL.md +224 -285
- package/.codex/skills/file-oss-management/SKILL.md +174 -169
- package/.codex/skills/git-workflow/SKILL.md +123 -341
- package/.codex/skills/json-serialization/SKILL.md +121 -137
- package/.codex/skills/next/SKILL.md +186 -42
- package/.codex/skills/performance-doctor/SKILL.md +83 -89
- package/.codex/skills/progress/SKILL.md +147 -76
- package/.codex/skills/redis-cache/SKILL.md +134 -185
- package/.codex/skills/scheduled-jobs/SKILL.md +187 -224
- package/.codex/skills/security-guard/SKILL.md +168 -276
- package/.codex/skills/sms-mail/SKILL.md +266 -228
- package/.codex/skills/social-login/SKILL.md +257 -195
- package/.codex/skills/tenant-management/SKILL.md +172 -188
- package/.codex/skills/utils-toolkit/SKILL.md +214 -222
- package/.codex/skills/websocket-sse/SKILL.md +251 -172
- package/.codex/skills/workflow-engine/SKILL.md +178 -250
- package/.cursor/agents/bug-analyzer.md +102 -0
- package/.cursor/agents/code-reviewer.md +80 -97
- package/.cursor/agents/image-reader.md +154 -0
- package/.cursor/agents/loki-runner.md +80 -0
- package/.cursor/agents/mysql-runner.md +81 -0
- package/.cursor/agents/project-manager.md +1 -1
- package/.cursor/agents/requirements-analyzer.md +141 -0
- package/.cursor/agents/task-fetcher.md +75 -0
- package/.cursor/hooks/cursor-skill-eval.js +66 -6
- package/.cursor/skills/api-development/SKILL.md +179 -130
- package/.cursor/skills/architecture-design/SKILL.md +102 -212
- package/.cursor/skills/backend-annotations/SKILL.md +166 -220
- package/.cursor/skills/bug-detective/SKILL.md +225 -186
- package/.cursor/skills/code-patterns/SKILL.md +127 -244
- package/.cursor/skills/collaborating-with-codex/SKILL.md +96 -113
- package/.cursor/skills/crud-development/SKILL.md +226 -307
- package/.cursor/skills/data-permission/SKILL.md +131 -202
- package/.cursor/skills/database-ops/SKILL.md +158 -355
- package/.cursor/skills/error-handler/SKILL.md +224 -285
- package/.cursor/skills/file-oss-management/SKILL.md +174 -169
- package/.cursor/skills/git-workflow/SKILL.md +123 -341
- package/.cursor/skills/json-serialization/SKILL.md +121 -137
- package/.cursor/skills/performance-doctor/SKILL.md +83 -89
- package/.cursor/skills/redis-cache/SKILL.md +134 -185
- package/.cursor/skills/scheduled-jobs/SKILL.md +187 -224
- package/.cursor/skills/security-guard/SKILL.md +168 -276
- package/.cursor/skills/sms-mail/SKILL.md +266 -228
- package/.cursor/skills/social-login/SKILL.md +257 -195
- package/.cursor/skills/tenant-management/SKILL.md +172 -188
- package/.cursor/skills/utils-toolkit/SKILL.md +214 -222
- package/.cursor/skills/websocket-sse/SKILL.md +251 -172
- package/.cursor/skills/workflow-engine/SKILL.md +178 -250
- package/AGENTS.md +117 -540
- package/CLAUDE.md +105 -117
- package/README.md +37 -6
- package/bin/index.js +5 -1
- package/package.json +1 -1
- package/src/skills/api-development/SKILL.md +179 -130
- package/src/skills/architecture-design/SKILL.md +102 -212
- package/src/skills/backend-annotations/SKILL.md +166 -220
- package/src/skills/bug-detective/SKILL.md +225 -186
- package/src/skills/code-patterns/SKILL.md +127 -244
- package/src/skills/collaborating-with-codex/SKILL.md +96 -113
- package/src/skills/crud-development/SKILL.md +226 -307
- package/src/skills/data-permission/SKILL.md +131 -202
- package/src/skills/database-ops/SKILL.md +158 -355
- package/src/skills/error-handler/SKILL.md +224 -285
- package/src/skills/file-oss-management/SKILL.md +174 -169
- package/src/skills/git-workflow/SKILL.md +123 -341
- package/src/skills/json-serialization/SKILL.md +121 -137
- package/src/skills/performance-doctor/SKILL.md +83 -89
- package/src/skills/redis-cache/SKILL.md +134 -185
- package/src/skills/scheduled-jobs/SKILL.md +187 -224
- package/src/skills/security-guard/SKILL.md +168 -276
- package/src/skills/sms-mail/SKILL.md +266 -228
- package/src/skills/social-login/SKILL.md +257 -195
- package/src/skills/tenant-management/SKILL.md +172 -188
- package/src/skills/utils-toolkit/SKILL.md +214 -222
- package/src/skills/websocket-sse/SKILL.md +251 -172
- package/src/skills/workflow-engine/SKILL.md +178 -250
- package/.claude/skills/skill-creator/LICENSE.txt +0 -202
- package/.claude/skills/skill-creator/SKILL.md +0 -479
- package/.claude/skills/skill-creator/agents/analyzer.md +0 -274
- package/.claude/skills/skill-creator/agents/comparator.md +0 -202
- package/.claude/skills/skill-creator/agents/grader.md +0 -223
- package/.claude/skills/skill-creator/assets/eval_review.html +0 -146
- package/.claude/skills/skill-creator/eval-viewer/generate_review.py +0 -471
- package/.claude/skills/skill-creator/eval-viewer/viewer.html +0 -1325
- package/.claude/skills/skill-creator/references/schemas.md +0 -430
- package/.claude/skills/skill-creator/scripts/__init__.py +0 -0
- package/.claude/skills/skill-creator/scripts/aggregate_benchmark.py +0 -401
- package/.claude/skills/skill-creator/scripts/generate_report.py +0 -326
- package/.claude/skills/skill-creator/scripts/improve_description.py +0 -248
- package/.claude/skills/skill-creator/scripts/package_skill.py +0 -136
- package/.claude/skills/skill-creator/scripts/quick_validate.py +0 -103
- package/.claude/skills/skill-creator/scripts/run_eval.py +0 -310
- package/.claude/skills/skill-creator/scripts/run_loop.py +0 -332
- package/.claude/skills/skill-creator/scripts/utils.py +0 -47
|
@@ -1,321 +1,249 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: workflow-engine
|
|
3
3
|
description: |
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
通用工作流引擎开发指南。涵盖状态机模式、流程引擎选型(Flowable/Camunda/Activiti 对比)、业务集成模式。
|
|
6
5
|
触发场景:
|
|
7
|
-
-
|
|
8
|
-
-
|
|
9
|
-
-
|
|
10
|
-
-
|
|
11
|
-
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
触发词:工作流、流程、审批、WarmFlow、FlowEngine、任务、办理、驳回、转办、委派、加签、减签、抄送、流程实例、流程定义、办理人、GlobalListener、ProcessEvent
|
|
6
|
+
- 设计审批流程(请假、报销、订单审批)
|
|
7
|
+
- 选择工作流引擎
|
|
8
|
+
- 实现任务办理(审批、驳回、转办、委派)
|
|
9
|
+
- 业务模块集成工作流
|
|
10
|
+
- 监听流程状态变更
|
|
11
|
+
触发词:工作流、流程、审批、驳回、转办、委派、加签、抄送、流程引擎、Flowable、Camunda、Activiti、状态机、BPMN
|
|
12
|
+
注意:如果项目有专属技能,优先使用专属版本。
|
|
15
13
|
---
|
|
16
14
|
|
|
17
|
-
#
|
|
15
|
+
# 工作流引擎开发指南
|
|
18
16
|
|
|
19
|
-
>
|
|
17
|
+
> 通用模板。如果项目有专属技能,优先使用。
|
|
20
18
|
|
|
21
|
-
##
|
|
19
|
+
## 设计原则
|
|
22
20
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
FlowEngine.insService() // 实例服务
|
|
28
|
-
FlowEngine.defService() // 流程定义服务
|
|
29
|
-
FlowEngine.nodeService() // 节点服务
|
|
30
|
-
FlowEngine.hisTaskService() // 历史任务服务
|
|
31
|
-
FlowEngine.userService() // 用户服务
|
|
32
|
-
```
|
|
21
|
+
1. **流程与业务分离**:流程引擎负责流转控制,业务逻辑通过事件监听器/回调接入。
|
|
22
|
+
2. **状态可追溯**:每次流转记录操作人、操作时间、操作意见,形成完整审批链。
|
|
23
|
+
3. **灵活可配**:流程定义应支持可视化设计、动态修改,无需改代码。
|
|
24
|
+
4. **异常可恢复**:流程实例支持挂起、恢复、终止、撤销等操作。
|
|
33
25
|
|
|
34
|
-
|
|
26
|
+
---
|
|
35
27
|
|
|
36
|
-
|
|
28
|
+
## 流程引擎选型对比
|
|
37
29
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
public static boolean isPassOrBack(String status) { ... }
|
|
51
|
-
}
|
|
52
|
-
```
|
|
30
|
+
| 维度 | Flowable | Camunda | Activiti | 轻量方案(WarmFlow 等) |
|
|
31
|
+
|------|----------|---------|----------|----------------------|
|
|
32
|
+
| 成熟度 | 高 | 高 | 高(社区版停滞) | 中 |
|
|
33
|
+
| 学习曲线 | 中等 | 中等 | 中等 | 低 |
|
|
34
|
+
| BPMN 2.0 | 完整支持 | 完整支持 | 完整支持 | 部分支持 |
|
|
35
|
+
| DMN 决策表 | 支持 | 支持 | 有限 | 不支持 |
|
|
36
|
+
| CMMN 案例 | 支持 | 支持 | 不支持 | 不支持 |
|
|
37
|
+
| 流程设计器 | 内置 Web | 内置 Web + Desktop | 旧版 Eclipse | 简易 Web |
|
|
38
|
+
| 性能 | 优秀 | 优秀 | 良好 | 轻量高效 |
|
|
39
|
+
| Spring Boot | 原生支持 | 原生支持 | 原生支持 | 通常支持 |
|
|
40
|
+
| 商业版 | 有 | 有 | N/A | 通常免费 |
|
|
41
|
+
| 适用场景 | 企业级复杂流程 | 企业级复杂流程 | 已有项目维护 | 简单审批流 |
|
|
53
42
|
|
|
54
|
-
###
|
|
43
|
+
### 选型决策树
|
|
55
44
|
|
|
56
|
-
> **注意**:USER 和 SPEL 类型没有前缀!
|
|
57
|
-
|
|
58
|
-
```java
|
|
59
|
-
public enum TaskAssigneeEnum {
|
|
60
|
-
USER("用户", ""), // 无前缀
|
|
61
|
-
ROLE("角色", "role:"),
|
|
62
|
-
DEPT("部门", "dept:"),
|
|
63
|
-
POST("岗位", "post:"),
|
|
64
|
-
SPEL("SpEL表达式", ""); // 无前缀,通过 $ 或 # 开头判断
|
|
65
|
-
|
|
66
|
-
public static boolean isSpelExpression(String value) {
|
|
67
|
-
return StringUtils.startsWith(value, "$") || StringUtils.startsWith(value, "#");
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
45
|
```
|
|
71
|
-
|
|
72
|
-
|
|
46
|
+
流程复杂度?
|
|
47
|
+
├── 简单审批(3-5步线性流程)
|
|
48
|
+
│ └── 状态机模式 或 轻量流程引擎
|
|
49
|
+
├── 中等(分支、并行、会签)
|
|
50
|
+
│ └── Flowable / Camunda
|
|
51
|
+
└── 复杂(子流程、多实例、DMN、事件)
|
|
52
|
+
└── Flowable / Camunda
|
|
53
|
+
```
|
|
73
54
|
|
|
74
55
|
---
|
|
75
56
|
|
|
76
|
-
##
|
|
57
|
+
## 实现模式
|
|
77
58
|
|
|
78
|
-
###
|
|
59
|
+
### 模式一:状态机(简单场景)
|
|
79
60
|
|
|
80
|
-
|
|
81
|
-
@Autowired
|
|
82
|
-
private IFlwTaskService flwTaskService;
|
|
83
|
-
|
|
84
|
-
StartProcessBo bo = new StartProcessBo();
|
|
85
|
-
bo.setFlowCode("leave_apply");
|
|
86
|
-
bo.setBusinessId("order_123");
|
|
87
|
-
bo.setVariables(Map.of("amount", 1000));
|
|
88
|
-
StartProcessReturnDTO result = flwTaskService.startWorkFlow(bo);
|
|
89
|
-
```
|
|
61
|
+
适用于线性或简单分支的审批流程。
|
|
90
62
|
|
|
91
63
|
```java
|
|
92
|
-
//
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
```
|
|
101
|
-
|
|
102
|
-
### 3.2 办理任务
|
|
64
|
+
// 状态枚举
|
|
65
|
+
public enum OrderStatus {
|
|
66
|
+
DRAFT, // 草稿
|
|
67
|
+
PENDING, // 待审批
|
|
68
|
+
APPROVED, // 已通过
|
|
69
|
+
REJECTED, // 已驳回
|
|
70
|
+
CANCELLED; // 已撤销
|
|
71
|
+
}
|
|
103
72
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
bo.setTaskId(taskId);
|
|
107
|
-
bo.setMessage("同意");
|
|
108
|
-
bo.setVariables(Map.of("approved", true));
|
|
109
|
-
bo.setAssigneeMap(Map.of("pass:nodeCode", "user:1,user:2")); // 可选:指定下一节点办理人
|
|
110
|
-
flwTaskService.completeTask(bo);
|
|
111
|
-
```
|
|
73
|
+
// 状态流转规则
|
|
74
|
+
public class OrderStateMachine {
|
|
112
75
|
|
|
113
|
-
|
|
76
|
+
private static final Map<OrderStatus, Set<OrderStatus>> TRANSITIONS = Map.of(
|
|
77
|
+
OrderStatus.DRAFT, Set.of(OrderStatus.PENDING, OrderStatus.CANCELLED),
|
|
78
|
+
OrderStatus.PENDING, Set.of(OrderStatus.APPROVED, OrderStatus.REJECTED),
|
|
79
|
+
OrderStatus.REJECTED, Set.of(OrderStatus.PENDING, OrderStatus.CANCELLED)
|
|
80
|
+
);
|
|
114
81
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
82
|
+
public void transition(Order order, OrderStatus targetStatus, String operator, String comment) {
|
|
83
|
+
OrderStatus current = order.getStatus();
|
|
84
|
+
if (!TRANSITIONS.getOrDefault(current, Set.of()).contains(targetStatus)) {
|
|
85
|
+
throw new [你的异常类](
|
|
86
|
+
String.format("不允许从 %s 流转到 %s", current, targetStatus));
|
|
87
|
+
}
|
|
88
|
+
order.setStatus(targetStatus);
|
|
89
|
+
// 记录流转日志
|
|
90
|
+
saveFlowLog(order.getId(), current, targetStatus, operator, comment);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
121
93
|
```
|
|
122
94
|
|
|
123
|
-
###
|
|
95
|
+
### 模式二:流程引擎集成
|
|
124
96
|
|
|
125
|
-
|
|
126
|
-
TaskOperationBo bo = new TaskOperationBo();
|
|
127
|
-
bo.setTaskId(taskId);
|
|
128
|
-
bo.setUserId("targetUserId");
|
|
129
|
-
bo.setMessage("转交处理");
|
|
97
|
+
#### 核心概念
|
|
130
98
|
|
|
131
|
-
|
|
132
|
-
|
|
99
|
+
| 概念 | 说明 |
|
|
100
|
+
|------|------|
|
|
101
|
+
| 流程定义(Definition) | 流程模板(BPMN XML),可版本化管理 |
|
|
102
|
+
| 流程实例(Instance) | 基于定义创建的运行时实例 |
|
|
103
|
+
| 任务(Task) | 等待人工处理的节点 |
|
|
104
|
+
| 历史(History) | 已完成的流程/任务记录 |
|
|
105
|
+
| 变量(Variable) | 流程运行时数据,用于条件判断 |
|
|
133
106
|
|
|
134
|
-
|
|
135
|
-
flwTaskService.taskOperation(bo, FlowConstant.DELEGATE_TASK);
|
|
136
|
-
|
|
137
|
-
// 加签 / 减签
|
|
138
|
-
bo.setUserIds(List.of("user1", "user2"));
|
|
139
|
-
flwTaskService.taskOperation(bo, FlowConstant.ADD_SIGNATURE);
|
|
140
|
-
flwTaskService.taskOperation(bo, FlowConstant.REDUCTION_SIGNATURE);
|
|
141
|
-
```
|
|
142
|
-
|
|
143
|
-
### 3.5 查询任务
|
|
107
|
+
#### 启动流程
|
|
144
108
|
|
|
145
109
|
```java
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
flwTaskService.pageByAllTaskWait(bo, pageQuery); // 所有待办(管理员)
|
|
149
|
-
flwTaskService.pageByAllTaskFinish(bo, pageQuery); // 所有已办(管理员)
|
|
150
|
-
flwTaskService.pageByTaskCopy(bo, pageQuery); // 抄送任务
|
|
151
|
-
```
|
|
110
|
+
@Service
|
|
111
|
+
public class WorkflowService {
|
|
152
112
|
|
|
153
|
-
|
|
113
|
+
@Autowired
|
|
114
|
+
private [你的流程引擎] engine;
|
|
154
115
|
|
|
155
|
-
|
|
116
|
+
// 启动流程
|
|
117
|
+
public String startProcess(String processKey, String businessId, Map<String, Object> variables) {
|
|
118
|
+
variables.put("businessId", businessId);
|
|
119
|
+
variables.put("initiator", [你的安全工具类].getCurrentUserId());
|
|
156
120
|
|
|
157
|
-
|
|
121
|
+
// 启动流程实例
|
|
122
|
+
var instance = engine.startProcessByKey(processKey, businessId, variables);
|
|
123
|
+
return instance.getId();
|
|
124
|
+
}
|
|
158
125
|
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
126
|
+
// 办理任务(审批通过)
|
|
127
|
+
public void completeTask(String taskId, String comment, Map<String, Object> variables) {
|
|
128
|
+
// 记录审批意见
|
|
129
|
+
engine.addComment(taskId, comment);
|
|
130
|
+
// 完成任务
|
|
131
|
+
engine.completeTask(taskId, variables);
|
|
132
|
+
}
|
|
164
133
|
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
134
|
+
// 驳回
|
|
135
|
+
public void rejectTask(String taskId, String targetNodeId, String comment) {
|
|
136
|
+
engine.addComment(taskId, comment);
|
|
137
|
+
engine.rejectToNode(taskId, targetNodeId);
|
|
138
|
+
}
|
|
168
139
|
|
|
169
|
-
|
|
170
|
-
public void
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
orderService.updateStatus(businessId, "PENDING");
|
|
174
|
-
return;
|
|
175
|
-
}
|
|
176
|
-
switch (event.getStatus()) {
|
|
177
|
-
case "finish" -> orderService.updateStatus(businessId, "APPROVED");
|
|
178
|
-
case "back" -> orderService.updateStatus(businessId, "REJECTED");
|
|
179
|
-
case "cancel" -> orderService.updateStatus(businessId, "CANCELLED");
|
|
180
|
-
case "termination" -> orderService.updateStatus(businessId, "TERMINATED");
|
|
181
|
-
case "invalid" -> orderService.updateStatus(businessId, "INVALID");
|
|
182
|
-
}
|
|
140
|
+
// 转办
|
|
141
|
+
public void transferTask(String taskId, String targetUserId, String comment) {
|
|
142
|
+
engine.addComment(taskId, comment);
|
|
143
|
+
engine.setAssignee(taskId, targetUserId);
|
|
183
144
|
}
|
|
184
145
|
|
|
185
|
-
|
|
186
|
-
public void
|
|
187
|
-
|
|
146
|
+
// 撤销
|
|
147
|
+
public void cancelProcess(String instanceId, String comment) {
|
|
148
|
+
engine.deleteProcessInstance(instanceId, comment);
|
|
188
149
|
}
|
|
189
150
|
}
|
|
190
151
|
```
|
|
191
152
|
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
## 五、全局监听器 WorkflowGlobalListener
|
|
195
|
-
|
|
196
|
-
实现 `GlobalListener` 接口,在任务生命周期关键节点执行:
|
|
153
|
+
#### 业务集成 - 事件监听
|
|
197
154
|
|
|
198
155
|
```java
|
|
199
156
|
@Component
|
|
200
|
-
public class
|
|
201
|
-
@Override
|
|
202
|
-
public void create(ListenerVariable var) { /* 任务创建 */ }
|
|
203
|
-
|
|
204
|
-
@Override
|
|
205
|
-
public void start(ListenerVariable var) {
|
|
206
|
-
// 任务开始办理:处理抄送、自定义变量
|
|
207
|
-
String ext = var.getNode().getExt();
|
|
208
|
-
Map<String, Object> variable = var.getVariable();
|
|
209
|
-
}
|
|
157
|
+
public class OrderWorkflowListener {
|
|
210
158
|
|
|
211
|
-
@
|
|
212
|
-
|
|
213
|
-
// 分派:动态修改待办任务的办理人
|
|
214
|
-
List<Task> nextTasks = var.getNextTasks();
|
|
215
|
-
FlowParams flowParams = var.getFlowParams();
|
|
216
|
-
}
|
|
159
|
+
@Autowired
|
|
160
|
+
private OrderService orderService;
|
|
217
161
|
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
162
|
+
// 监听流程状态变更事件
|
|
163
|
+
@EventListener(condition = "#event.processKey == 'order_approve'")
|
|
164
|
+
public void onProcessEvent(ProcessStatusEvent event) {
|
|
165
|
+
String businessId = event.getBusinessId();
|
|
166
|
+
switch (event.getStatus()) {
|
|
167
|
+
case "submitted" -> orderService.updateStatus(businessId, "PENDING");
|
|
168
|
+
case "approved" -> orderService.updateStatus(businessId, "APPROVED");
|
|
169
|
+
case "rejected" -> orderService.updateStatus(businessId, "REJECTED");
|
|
170
|
+
case "cancelled" -> orderService.updateStatus(businessId, "CANCELLED");
|
|
171
|
+
}
|
|
223
172
|
}
|
|
224
|
-
}
|
|
225
|
-
```
|
|
226
173
|
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
String INITIATOR = "initiator"; // 发起人
|
|
236
|
-
String INITIATOR_DEPT_ID = "initiatorDeptId"; // 发起人部门
|
|
237
|
-
String BUSINESS_ID = "businessId";
|
|
238
|
-
String SUBMIT = "submit"; // 提交标识
|
|
239
|
-
|
|
240
|
-
String DELEGATE_TASK = "delegateTask"; // 委托
|
|
241
|
-
String TRANSFER_TASK = "transferTask"; // 转办
|
|
242
|
-
String ADD_SIGNATURE = "addSignature"; // 加签
|
|
243
|
-
String REDUCTION_SIGNATURE = "reductionSignature"; // 减签
|
|
244
|
-
|
|
245
|
-
String FLOW_COPY_LIST = "flowCopyList"; // 抄送人列表
|
|
246
|
-
String MESSAGE_TYPE = "messageType";
|
|
247
|
-
String MESSAGE_NOTICE = "messageNotice";
|
|
248
|
-
String AUTO_PASS = "autoPass"; // 自动通过
|
|
249
|
-
|
|
250
|
-
String VAR_IGNORE = "ignore"; // 忽略办理权限校验
|
|
251
|
-
String VAR_IGNORE_DEPUTE = "ignoreDepute";
|
|
252
|
-
String VAR_IGNORE_COOPERATE = "ignoreCooperate";
|
|
174
|
+
// 监听任务创建事件(发送通知)
|
|
175
|
+
@EventListener(condition = "#event.processKey == 'order_approve'")
|
|
176
|
+
public void onTaskCreated(TaskCreatedEvent event) {
|
|
177
|
+
notificationService.sendNotice(
|
|
178
|
+
event.getAssignee(),
|
|
179
|
+
"您有新的审批任务:" + event.getTaskName()
|
|
180
|
+
);
|
|
181
|
+
}
|
|
253
182
|
}
|
|
254
183
|
```
|
|
255
184
|
|
|
256
|
-
|
|
185
|
+
#### 办理人类型设计
|
|
257
186
|
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
187
|
+
| 类型 | 标识格式 | 示例 |
|
|
188
|
+
|------|---------|------|
|
|
189
|
+
| 指定用户 | 用户ID | `1001` |
|
|
190
|
+
| 角色 | `role:角色编码` | `role:finance_manager` |
|
|
191
|
+
| 部门 | `dept:部门ID` | `dept:100` |
|
|
192
|
+
| 岗位 | `post:岗位编码` | `post:cfo` |
|
|
193
|
+
| 表达式 | SpEL / UEL | `${order.amount > 10000 ? 'role:director' : 'role:manager'}` |
|
|
264
194
|
|
|
265
195
|
---
|
|
266
196
|
|
|
267
|
-
##
|
|
197
|
+
## API 接口设计参考
|
|
268
198
|
|
|
269
|
-
###
|
|
199
|
+
### 任务相关
|
|
270
200
|
|
|
271
201
|
| 接口 | 方法 | 说明 |
|
|
272
202
|
|------|------|------|
|
|
273
|
-
| `/
|
|
274
|
-
| `/
|
|
275
|
-
| `/
|
|
276
|
-
| `/
|
|
277
|
-
| `/
|
|
278
|
-
| `/
|
|
279
|
-
| `/
|
|
280
|
-
| `/
|
|
281
|
-
| `/{taskOperation}` | POST | 委派/转办/加签/减签 |
|
|
282
|
-
| `/urgeTask` | POST | 催办 |
|
|
283
|
-
|
|
284
|
-
### 实例 /workflow/instance
|
|
203
|
+
| `/workflow/start` | POST | 启动流程 |
|
|
204
|
+
| `/workflow/task/complete` | POST | 办理任务(审批通过) |
|
|
205
|
+
| `/workflow/task/reject` | POST | 驳回 |
|
|
206
|
+
| `/workflow/task/transfer` | POST | 转办 |
|
|
207
|
+
| `/workflow/task/delegate` | POST | 委派 |
|
|
208
|
+
| `/workflow/task/todo` | GET | 当前用户待办列表 |
|
|
209
|
+
| `/workflow/task/done` | GET | 当前用户已办列表 |
|
|
210
|
+
| `/workflow/task/copy` | GET | 抄送列表 |
|
|
285
211
|
|
|
286
|
-
|
|
287
|
-
|------|------|------|
|
|
288
|
-
| `/pageByRunning` | GET | 运行中实例 |
|
|
289
|
-
| `/pageByFinish` | GET | 已完成实例 |
|
|
290
|
-
| `/pageByCurrent` | GET | 当前用户发起 |
|
|
291
|
-
| `/cancelProcessApply` | PUT | 撤销申请 |
|
|
292
|
-
| `/invalid` | POST | 作废 |
|
|
293
|
-
| `/flowHisTaskList/{businessId}` | GET | 流程图+审批记录 |
|
|
294
|
-
|
|
295
|
-
### 定义 /workflow/definition
|
|
212
|
+
### 实例相关
|
|
296
213
|
|
|
297
214
|
| 接口 | 方法 | 说明 |
|
|
298
215
|
|------|------|------|
|
|
299
|
-
| `/
|
|
300
|
-
| `/
|
|
301
|
-
| `/
|
|
302
|
-
| `/
|
|
303
|
-
| `/importDef` | POST | 导入 |
|
|
304
|
-
| `/exportDef/{id}` | POST | 导出 |
|
|
216
|
+
| `/workflow/instance/running` | GET | 运行中实例 |
|
|
217
|
+
| `/workflow/instance/finished` | GET | 已完成实例 |
|
|
218
|
+
| `/workflow/instance/cancel` | PUT | 撤销申请 |
|
|
219
|
+
| `/workflow/instance/history/{businessId}` | GET | 审批记录 |
|
|
305
220
|
|
|
306
221
|
---
|
|
307
222
|
|
|
308
|
-
##
|
|
223
|
+
## 常见错误
|
|
309
224
|
|
|
310
|
-
```
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
225
|
+
```java
|
|
226
|
+
// 1. 流程与业务强耦合
|
|
227
|
+
// 在流程引擎的 ServiceTask 中直接操作数据库
|
|
228
|
+
// 应通过事件监听/消息解耦
|
|
229
|
+
|
|
230
|
+
// 2. 未处理并发审批
|
|
231
|
+
// 多人同时审批同一任务 -> 数据不一致
|
|
232
|
+
// 应在 completeTask 中加锁或使用乐观锁
|
|
233
|
+
|
|
234
|
+
// 3. 流程变量存放大对象
|
|
235
|
+
variables.put("orderDetail", hugeObject); // 序列化到数据库,性能差
|
|
236
|
+
// 应只存关键ID,通过 businessId 关联查询
|
|
237
|
+
|
|
238
|
+
// 4. 忽略流程版本管理
|
|
239
|
+
// 修改流程定义后,已运行的实例可能出错
|
|
240
|
+
// 应使用版本化部署,运行中实例按启动时版本执行
|
|
241
|
+
|
|
242
|
+
// 5. 审批意见未持久化
|
|
243
|
+
engine.completeTask(taskId, variables); // 忘记 addComment
|
|
244
|
+
// 应在 complete 前记录审批意见
|
|
245
|
+
|
|
246
|
+
// 6. 通知不及时
|
|
247
|
+
// 任务创建后没有通知办理人 -> 任务积压
|
|
248
|
+
// 应通过事件监听器自动发送通知
|
|
321
249
|
```
|