@mldong/jeeflow 1.8.21 → 1.8.23

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.
Files changed (2) hide show
  1. package/dist/engine.js +48 -11
  2. package/package.json +1 -1
package/dist/engine.js CHANGED
@@ -155,6 +155,8 @@ export class EngineImpl {
155
155
  [`operatorList_${curNode.id}`]: actors,
156
156
  };
157
157
  await this.repo.saveTask(nt);
158
+ // TASK_CREATE:顺序会签推进新任务落库后 fire(对齐 Java CreateTaskHandler / Rust)
159
+ await this.fireEvent({ type: EventType.TaskCreate, instanceId: inst.id, taskId: nt.id, nodeId: curNode.id, operator });
158
160
  return (await this.repo.findInstanceById(inst.id));
159
161
  }
160
162
  }
@@ -253,7 +255,10 @@ export class EngineImpl {
253
255
  const def = await this.repo.findDefineById(inst.defineId);
254
256
  const flow = JSON.parse(typeof def.content === 'string' ? def.content : new TextDecoder().decode(def.content));
255
257
  args = filterFieldByPerm(args, findNode(flow, task.taskName));
256
- const vars = { ...inst.variables, ...task.variables, ...args };
258
+ // issues/97:捕获原始实例变量(start 注入的发起人 u_*)——操作人 u_* 只进执行上下文
259
+ // 与任务行,不得整体写回实例(对齐 Java completeTask=putAll(args),args 不含 u_*)。
260
+ const baseVars = inst.variables;
261
+ const vars = { ...baseVars, ...task.variables, ...args };
257
262
  await this.addUserInfo(operator, vars);
258
263
  const now = new Date();
259
264
  // 聚合根:完成任务(子实体状态转换 + 实例变量合并)
@@ -263,7 +268,8 @@ export class EngineImpl {
263
268
  // completeTask 改的是外部任务对象,需同步回聚合根
264
269
  syncTaskToAggregate(inst, task);
265
270
  await this.fireEvent({ type: EventType.TaskComplete, instanceId: inst.id, taskId: task.id, nodeId: task.taskName, operator });
266
- inst.variables = vars;
271
+ // issues/97:实例变量写回排除操作人 u_*,保留 start 注入的发起人 u_*(u_realName 恒为发起人)
272
+ inst.variables = mergeExecIntoInstance(baseVars, vars);
267
273
  await this.repo.updateInstance(inst);
268
274
  return { task, inst, flow, vars };
269
275
  }
@@ -336,8 +342,11 @@ export class EngineImpl {
336
342
  switch (ct) {
337
343
  case 'PARALLEL':
338
344
  case '':
339
- for (const actor of actors)
340
- await this.repo.saveTask(inst.createTask(this.nextId(), node.id, node.text.value, actor, operator, form, now, 1));
345
+ for (const actor of actors) {
346
+ const nt = inst.createTask(this.nextId(), node.id, node.text.value, actor, operator, form, now, 1);
347
+ await this.repo.saveTask(nt);
348
+ await this.fireEvent({ type: EventType.TaskCreate, instanceId: inst.id, taskId: nt.id, nodeId: node.id, operator });
349
+ }
341
350
  return;
342
351
  case 'SEQUENTIAL': {
343
352
  const nt = inst.createTask(this.nextId(), node.id, node.text.value, actors[0], operator, form, now, 1);
@@ -347,11 +356,15 @@ export class EngineImpl {
347
356
  [`operatorList_${node.id}`]: actors,
348
357
  };
349
358
  await this.repo.saveTask(nt);
359
+ await this.fireEvent({ type: EventType.TaskCreate, instanceId: inst.id, taskId: nt.id, nodeId: node.id, operator });
350
360
  return;
351
361
  }
352
362
  default:
353
- for (const actor of actors)
354
- await this.repo.saveTask(inst.createTask(this.nextId(), node.id, node.text.value, actor, operator, form, now, 1));
363
+ for (const actor of actors) {
364
+ const nt = inst.createTask(this.nextId(), node.id, node.text.value, actor, operator, form, now, 1);
365
+ await this.repo.saveTask(nt);
366
+ await this.fireEvent({ type: EventType.TaskCreate, instanceId: inst.id, taskId: nt.id, nodeId: node.id, operator });
367
+ }
355
368
  return;
356
369
  }
357
370
  }
@@ -359,6 +372,7 @@ export class EngineImpl {
359
372
  if (actors.length > 1)
360
373
  nt.actorIds = actors;
361
374
  await this.repo.saveTask(nt);
375
+ await this.fireEvent({ type: EventType.TaskCreate, instanceId: inst.id, taskId: nt.id, nodeId: node.id, operator });
362
376
  }
363
377
  // ─── Helpers ───────────────────────────────────────────────────────────────
364
378
  async loadAndCheck(taskId, operator) {
@@ -407,7 +421,8 @@ export class EngineImpl {
407
421
  else {
408
422
  inst.finish(new Date());
409
423
  }
410
- inst.variables = vars;
424
+ // issues/97:结束节点写回同样排除操作人 u_*(保留发起人 u_*,与 prepareExecuteTask 一致)
425
+ inst.variables = mergeExecIntoInstance(inst.variables, vars);
411
426
  await this.repo.updateInstance(inst);
412
427
  await this.fireEvent({ type: EventType.ProcessFinish, instanceId: inst.id, operator });
413
428
  return;
@@ -484,8 +499,12 @@ export class EngineImpl {
484
499
  if (isCountersign(node.properties?.performType) && ct) {
485
500
  switch (ct) {
486
501
  case 'PARALLEL':
487
- for (const actor of actors)
488
- await this.repo.saveTask(inst.createTask(this.nextId(), node.id, node.text.value, actor, operator, form, now, 1));
502
+ for (const actor of actors) {
503
+ const nt = inst.createTask(this.nextId(), node.id, node.text.value, actor, operator, form, now, 1);
504
+ await this.repo.saveTask(nt);
505
+ // TASK_CREATE:任务落库后逐个 fire(会签多任务逐个,对齐 Java CreateTaskHandler)
506
+ await this.fireEvent({ type: EventType.TaskCreate, instanceId: inst.id, taskId: nt.id, nodeId: node.id, operator });
507
+ }
489
508
  return;
490
509
  case 'SEQUENTIAL': {
491
510
  // 顺序会签任务也是会签任务(issues/57 E29 修正:仅普通分支默认 0)
@@ -496,11 +515,15 @@ export class EngineImpl {
496
515
  [`operatorList_${node.id}`]: actors,
497
516
  };
498
517
  await this.repo.saveTask(nt);
518
+ await this.fireEvent({ type: EventType.TaskCreate, instanceId: inst.id, taskId: nt.id, nodeId: node.id, operator });
499
519
  return;
500
520
  }
501
521
  default:
502
- for (const actor of actors)
503
- await this.repo.saveTask(inst.createTask(this.nextId(), node.id, node.text.value, actor, operator, form, now, 1));
522
+ for (const actor of actors) {
523
+ const nt = inst.createTask(this.nextId(), node.id, node.text.value, actor, operator, form, now, 1);
524
+ await this.repo.saveTask(nt);
525
+ await this.fireEvent({ type: EventType.TaskCreate, instanceId: inst.id, taskId: nt.id, nodeId: node.id, operator });
526
+ }
504
527
  return;
505
528
  }
506
529
  }
@@ -509,6 +532,7 @@ export class EngineImpl {
509
532
  if (actors.length > 1)
510
533
  nt.actorIds = actors;
511
534
  await this.repo.saveTask(nt);
535
+ await this.fireEvent({ type: EventType.TaskCreate, instanceId: inst.id, taskId: nt.id, nodeId: node.id, operator });
512
536
  }
513
537
  async resolveActors(node, inst, operator, vars) {
514
538
  // 1a. Registry 按名称解析(推荐)
@@ -638,6 +662,19 @@ function syncTaskToAggregate(inst, task) {
638
662
  }
639
663
  }
640
664
  }
665
+ /** 实例变量写回合并(issues/97 对齐 Java):以 base(start 注入的发起人 u_*)为底,
666
+ * 并入执行上下文中**非 u_*** 键(f_ 表单字段 / submitType 等流转数据)。
667
+ * addUserInfo 生成的操作人 u_* 只属于当次执行上下文与任务行 ext,不整体写回实例——
668
+ * 实例 u_realName 语义是「发起人」(与 autoGenTitle 一致),不随审批节点漂移。 */
669
+ function mergeExecIntoInstance(base, execVars) {
670
+ const out = { ...base };
671
+ for (const [k, v] of Object.entries(execVars)) {
672
+ if (k.startsWith('u_'))
673
+ continue;
674
+ out[k] = v;
675
+ }
676
+ return out;
677
+ }
641
678
  function isTruthy(v) {
642
679
  if (typeof v === 'boolean')
643
680
  return v;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mldong/jeeflow",
3
- "version": "1.8.21",
3
+ "version": "1.8.23",
4
4
  "description": "jeeflow workflow engine — Node.js / TypeScript implementation",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",