File tree Expand file tree Collapse file tree
flow-engine-framework/src
main/java/com/codingapi/flow
test/java/com/codingapi/flow Expand file tree Collapse file tree Original file line number Diff line number Diff line change @@ -64,7 +64,7 @@ REST 层通过请求参数 `mockKey` 分流到 Mock 实例(见 `FlowRecordCont
6464
6565### 事件(IFlowEvent + EventPusher)
6666
67- 7 种事件:开始 / 待办 / 已办 / 完成 / 催办 / 撤销(` FlowRecordRevokeEvent ` )/ 删除(` FlowRecordDeleteEvent ` )。操作完成后用 ` EventPusher.push(event) ` 推送;事件通常携带 ` FlowRecord ` + ` mock ` 标记。外部可用 Spring ` @EventListener ` 订阅。
67+ 8 种事件:开始 / 待办 / 已办 / 完成 / 催办 / 撤销(` FlowRecordRevokeEvent ` )/ 删除(` FlowRecordDeleteEvent ` )/ 子流程重置( ` FlowSubProcessResetEvent ` ) 。操作完成后用 ` EventPusher.push(event) ` 推送;记录类事件携带 ` FlowRecord ` + ` mock ` 标记,重置事件携带新旧聚合组快照 。外部可用 Spring ` @EventListener ` 订阅。
6868
6969### API 模块划分
7070
Original file line number Diff line number Diff line change 3232| [ 快速开始] ( ./quick-start.md ) | 最小集成步骤:引入依赖 → 提供 Bean → 编写流程 → 发起流程 |
3333| [ 流程用户体系] ( ./user-integration.md ) | ` FlowOperatorGateway ` / ` IFlowOperator ` / ` GatewayContext ` / 线程缓存 / 当前登录人 |
3434| [ 流程默认脚本] ( ./script-integration.md ) | 12 种脚本类型、` GroovyScriptRequest ` 完整 API、` $bind ` 、默认脚本替换、脚本生命周期 |
35- | [ 流程事件机制] ( ./event-integration.md ) | 7 种事件、` EventPusher ` 、` IHandler ` 订阅、异步分发管道、事务变体、推送时机 |
35+ | [ 流程事件机制] ( ./event-integration.md ) | 8 种事件、` EventPusher ` 、` IHandler ` 订阅、异步分发管道、事务变体、推送时机 |
3636| [ 仓储抽象与持久化] ( ./repository-integration.md ) | ` IRepositoryHolder ` 、12 个仓储接口(含 11 个 JPA 实现 + 需自行实现的 ` NodeViewJavaScriptRepository ` )、脚本仓储、锁机制 |
3737| [ Spring Boot 自动配置] ( ./auto-configuration.md ) | ` AutoConfiguration ` 8 个 Bean、4 个 Register、必选/可选 Bean 清单 |
3838| [ REST API] ( ./rest-api.md ) | 4 个 Controller、` mockKey ` /` operatorId ` 分流机制、请求/响应结构 |
Original file line number Diff line number Diff line change @@ -225,5 +225,5 @@ public class MyFlowRecordUrgeEventHandler implements IHandler<FlowRecordUrgeEven
225225
226226## 6. Mock 模式标记
227227
228- - 事件携带 ` mock ` 标记:有 session 的场景用 ` session.isMock() ` (等价于 ` repositoryHolder instanceof MockRepositoryHolder ` );无 session 的服务(` FlowDeleteService ` /` FlowUrgeService ` /` FlowRevokeService ` )直接用 ` repositoryHolder instanceof MockRepositoryHolder ` 。
228+ - 事件携带 ` mock ` 标记:有 session 的场景用 ` session.isMock() ` (等价于 ` repositoryHolder instanceof MockRepositoryHolder ` );无 session 的服务(` FlowDeleteService ` /` FlowUrgeService ` /` FlowRevokeService ` / ` FlowSubProcessResetService ` )直接用 ` repositoryHolder instanceof MockRepositoryHolder ` 。
229229- 订阅方可通过 ` event.isMock() ` 区分测试/演示流量与生产流量(例如不发送真实消息)。
Original file line number Diff line number Diff line change @@ -180,7 +180,7 @@ form(FlowForm 元数据) / fieldPermissions(字段权限)
180180todos(当前节点待办 Body 列表) / actions / actionList
181181mergeable / createOperator / currentOperator / flowState / recordState
182182histories(审批历史) / nodes(NodeOption 可操作节点) / revoke / urge
183- resetSubProcess(子流程重置能力标识:当前待办位于开启重置能力、已汇聚完成的子流程下游时为 true)
183+ resetSubProcess(子流程重置能力标识:当前待办位于开启重置能力、已汇聚完成的子流程的锁定合并节点上时为 true;更深层下游节点为 false )
184184```
185185
186186### ` FlowRecordContent ` (列表响应,字段摘要)
Original file line number Diff line number Diff line change 11---
22name : flow-engine-framework/sub-process
33module : flow-engine-framework
4- description : 子流程聚合执行能力,支持批量创建、主流程等待、脚本结果判定与异常跳转
4+ description : 子流程聚合执行能力,支持批量创建、主流程等待、脚本结果判定、异常跳转与数据重置(退回重走)
55status : 已实现
66scope : 后端
77source : 项目自有
@@ -115,7 +115,7 @@ def run(request){
115115
116116### 可见性(详情标识字段)
117117
118- 重置不是节点动作,不出现在动作列表中。流程详情 ` FlowContent ` 新增 ` resetSubProcess ` 布尔标识:当前待办位于「开启重置能力、已汇聚完成」的子流程下游时为 ` true ` 。前端解析到该标识即可自行提供重置交互(呈现方式由使用方决定,不限定于操作列);节点视图中新旧聚合组同时呈现,` ProcessNode.SubProcessBody.superseded ` 与 ` SubProcessInstanceBody.inherited/sourceProcessId ` 供前端区分。
118+ 重置不是节点动作,不出现在动作列表中。流程详情 ` FlowContent ` 新增 ` resetSubProcess ` 布尔标识:当前待办位于「开启重置能力、已汇聚完成」的子流程的 ** 锁定合并节点 ** 上时为 ` true ` (更深层下游节点为 ` false ` ) 。前端解析到该标识即可自行提供重置交互(呈现方式由使用方决定,不限定于操作列);节点视图中新旧聚合组同时呈现,` ProcessNode.SubProcessBody.superseded ` 与 ` SubProcessInstanceBody.inherited/sourceProcessId ` 供前端区分。
119119
120120### 数据结构兼容性
121121
Original file line number Diff line number Diff line change 1919| [ flow-engine-framework/operator-assignment] ( ./flow-engine-framework/operator-assignment.md ) | flow-engine-framework | 操作人分配能力,支持发起人/审批人设定的分配校验与落库 | 后端 | 项目自有 |
2020| [ flow-engine-framework/repository] ( ./flow-engine-framework/repository.md ) | flow-engine-framework | 仓储抽象层,定义流程引擎的持久化接口和仓储持有者上下文 | 后端 | 项目自有 |
2121| [ flow-engine-framework/script] ( ./flow-engine-framework/script.md ) | flow-engine-framework | Groovy 脚本运行时,包含脚本注册表、脚本类型封装和脚本执行上下文 | 后端 | 项目自有 |
22- | [ flow-engine-framework/sub-process] ( ./flow-engine-framework/sub-process.md ) | flow-engine-framework | 子流程聚合执行能力,支持批量创建、主流程等待、脚本结果判定与异常跳转 | 后端 | 项目自有 |
22+ | [ flow-engine-framework/sub-process] ( ./flow-engine-framework/sub-process.md ) | flow-engine-framework | 子流程聚合执行能力,支持批量创建、主流程等待、脚本结果判定、异常跳转与数据重置(退回重走) | 后端 | 项目自有 |
2323| [ flow-engine-framework/workflow-strategy] ( ./flow-engine-framework/workflow-strategy.md ) | flow-engine-framework | 工作流级别策略体系,包含策略接口、工厂和具体策略实现 | 后端 | 项目自有 |
2424| [ flow-engine-framework/workflow] ( ./flow-engine-framework/workflow.md ) | flow-engine-framework | 工作流引擎核心模型,包含流程定义、构建器、版本管理和运行时快照 | 后端 | 项目自有 |
2525| [ flow-engine-starter/auto-configuration] ( ./flow-engine-starter/auto-configuration.md ) | flow-engine-starter | Spring Boot 自动配置入口,注册流程引擎的核心组件和仓储上下文 | 后端 | 项目自有 |
Original file line number Diff line number Diff line change @@ -16,7 +16,7 @@ framework_version: "3.5.9"
1616- ** 依赖注入** :容器管理 Bean 之间的依赖关系。本项目不使用 ` @Autowired ` / ` @Inject ` 注解,统一通过 Lombok ` @AllArgsConstructor ` 构造器注入(如 ` WorkflowController ` 、` WorkflowService ` 、各 ` RepositoryImpl ` )
1717- ** Bean 生命周期管理** :容器统一管理 Bean 的创建、初始化和销毁
1818- ** AOP 支持** :框架提供 ` @Aspect ` 横切关注点能力(本项目未使用)
19- - ** 事件发布** :本项目不使用 Spring ` ApplicationEventPublisher ` ,事件系统为自研 ` IFlowEvent ` + ` EventPusher ` (` flow-engine-framework/event/ ` 下 7 种事件类,操作完成后通过 ` EventPusher.push(event) ` 推送)
19+ - ** 事件发布** :本项目不使用 Spring ` ApplicationEventPublisher ` ,事件系统为自研 ` IFlowEvent ` + ` EventPusher ` (` flow-engine-framework/event/ ` 下 8 种事件类,操作完成后通过 ` EventPusher.push(event) ` 推送)
2020- ** 自动配置** :通过 ` @Configuration ` + ` @Conditional ` 实现条件化 Bean 注册
2121
2222## 如何使用
Original file line number Diff line number Diff line change @@ -284,7 +284,7 @@ <h2 id="be-extends">5. 后端:扩展点</h2>
284284
285285< table >
286286 < tr > < th > 扩展点</ th > < th > 说明</ th > </ tr >
287- < tr > < td > 事件订阅</ td > < td > 实现 < code > IHandler<E></ code > 订阅 7 种事件:Start / Todo / Done / Finish / Urge / Revoke / Delete,自动被 Spring 扫描</ td > </ tr >
287+ < tr > < td > 事件订阅</ td > < td > 实现 < code > IHandler<E></ code > 订阅 8 种事件:Start / Todo / Done / Finish / Urge / Revoke / Delete / SubProcessReset ,自动被 Spring 扫描</ td > </ tr >
288288 < tr > < td > 节点策略</ td > < td > 15 种策略(OperatorLoad / RecordMerge / Revoke / Router / FormFieldPermission 等)由 < code > NodeStrategyManager</ code > 持有(工厂固定注册,不支持新增策略类型;业务方通过策略配置 + Groovy 脚本表达差异)</ td > </ tr >
289289 < tr > < td > 自定义动作</ td > < td > 8 种内置动作(PASS/REJECT/RETURN/TRANSFER/DELEGATE/ADD_AUDIT/SAVE/CUSTOM)由 < code > FlowActionFactory</ code > 固定注册(不支持新增动作类型);业务方通过 CUSTOM 动作 + Groovy 脚本表达自定义行为</ td > </ tr >
290290 < tr > < td > 自定义脚本注册</ td > < td > < code > ScriptRegistryContext.getInstance().setRegistry(new CustomScriptRegistry())</ code > 替换默认 Groovy 脚本</ td > </ tr >
Original file line number Diff line number Diff line change @@ -33,11 +33,13 @@ public List<FlowRecord> findTodoByOperator(long operatorId) {
3333 }
3434
3535 public List <FlowRecord > findDoneByOperator (long operatorId ) {
36- return cache .values ().stream ().filter (flowRecord -> flowRecord .getCurrentOperatorId () == operatorId && !flowRecord .isTodo ()).toList ();
36+ // 与 JPA 口径一致:已办列表过滤已作废与隐藏记录(撤销/重置产生的作废记录不进入已办)
37+ return cache .values ().stream ().filter (flowRecord -> flowRecord .getCurrentOperatorId () == operatorId && flowRecord .isDone ()).toList ();
3738 }
3839
3940 public List <FlowRecord > findNotifyByOperator (long operatorId ) {
40- return cache .values ().stream ().filter (flowRecord -> flowRecord .getCurrentOperatorId () == operatorId && flowRecord .isNotify ()).toList ();
41+ // 与 JPA 口径一致:抄送列表过滤已作废与隐藏记录
42+ return cache .values ().stream ().filter (flowRecord -> flowRecord .getCurrentOperatorId () == operatorId && flowRecord .isNotify () && !flowRecord .isRevoked () && !flowRecord .isHidden ()).toList ();
4143 }
4244
4345
Original file line number Diff line number Diff line change @@ -141,13 +141,12 @@ public void reset() {
141141 newInstances );
142142 subProcessRepository .save (newGroup );
143143
144- for (FlowActionRequest submitRequest : submitRequests ) {
145- flowService .action (submitRequest );
146- }
147-
148- // 作废触发锚点之后的记录链(复用撤销语义):重置后主流程退回子流程节点等待,
144+ // 作废触发锚点之后的旧记录链(复用撤销语义):重置后主流程退回子流程节点等待,
149145 // 锚点之后的旧记录不再代表有效路径,且其 fromId + 节点与恢复后新建记录相同,
150- // 不作废会被同节点记录查询误判为多人审批
146+ // 不作废会被同节点记录查询误判为多人审批。
147+ // 作废必须先于重建实例提交:纯自动子流程会在提交中同步跑完并触发结果判定
148+ // 恢复主流程(新记录 fromId == 锚点id),之后再作废会把刚恢复的新记录一并作废,
149+ // 导致主流程卡死
151150 List <FlowRecord > invalidatedRecords = new ArrayList <>();
152151 List <FlowRecord > afterRecords = repositoryHolder
153152 .findAfterRecords (currentRecord .getProcessId (), anchorRecord .getId ());
@@ -164,6 +163,10 @@ public void reset() {
164163 // 避免重走再次触发下游节点(如抄送)时被被动式环检测误判为循环
165164 LoopTriggerTraceContext .getInstance ().clearByProcess (currentRecord .getProcessId ());
166165
166+ for (FlowActionRequest submitRequest : submitRequests ) {
167+ flowService .action (submitRequest );
168+ }
169+
167170 boolean mock = repositoryHolder instanceof MockRepositoryHolder ;
168171 IFlowOperator resetOperator = repositoryHolder .getOperatorById (request .getOperatorId ());
169172 for (FlowRecord invalidatedRecord : invalidatedRecords ) {
You can’t perform that action at this time.
0 commit comments