@mldong/jeeflow 1.8.6 → 1.8.8

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/dist/engine.d.ts CHANGED
@@ -53,5 +53,11 @@ export declare class EngineImpl implements Engine {
53
53
  private resolveActors;
54
54
  private isAllowed;
55
55
  private addUserInfo;
56
+ /** 用户提供者访问(issue 41 补强:nodeProgress 姓名解析用) */
57
+ getUserProvider(): UserProvider | undefined;
56
58
  private nextId;
57
59
  }
60
+ /** 会签判定(issue 42,对齐 Java ProcessTaskPerformTypeEnum.codeOf):
61
+ * '1' / 'ALL' / 'COUNTERSIGN'(大小写不敏感)→ 会签。
62
+ * 设计器属性面板保存 'ALL' 字符串符合 Java 契约,引擎必须兼容 */
63
+ export declare function isCountersign(v: any): boolean;
package/dist/engine.js CHANGED
@@ -356,11 +356,10 @@ export class EngineImpl {
356
356
  const actors = await this.resolveActors(node, inst, operator, vars);
357
357
  if (!actors.length)
358
358
  return;
359
- const performType = parseInt(String(node.properties?.performType ?? '0'));
360
359
  const ct = node.properties?.countersignType;
361
360
  const now = new Date();
362
361
  const form = node.properties?.form ?? '';
363
- if (performType === 1 && ct) {
362
+ if (isCountersign(node.properties?.performType) && ct) {
364
363
  switch (ct) {
365
364
  case 'PARALLEL':
366
365
  for (const actor of actors)
@@ -470,6 +469,10 @@ export class EngineImpl {
470
469
  if (u.postName)
471
470
  vars[KeyPostName] = u.postName;
472
471
  }
472
+ /** 用户提供者访问(issue 41 补强:nodeProgress 姓名解析用) */
473
+ getUserProvider() {
474
+ return this.userProv;
475
+ }
473
476
  nextId() {
474
477
  if (this.idGen)
475
478
  return this.idGen.nextId();
@@ -513,6 +516,13 @@ function isTruthy(v) {
513
516
  return v !== 0;
514
517
  return v != null;
515
518
  }
519
+ /** 会签判定(issue 42,对齐 Java ProcessTaskPerformTypeEnum.codeOf):
520
+ * '1' / 'ALL' / 'COUNTERSIGN'(大小写不敏感)→ 会签。
521
+ * 设计器属性面板保存 'ALL' 字符串符合 Java 契约,引擎必须兼容 */
522
+ export function isCountersign(v) {
523
+ const s = String(v ?? '').trim().toUpperCase();
524
+ return s === '1' || s === 'ALL' || s === 'COUNTERSIGN';
525
+ }
516
526
  /** 办理提交的 f_ 字段按任务节点 field 权限过滤(issues/26)——
517
527
  * 任务节点 properties.field 声明 PERMISSION_f_{全名}(前端约定,优先)或
518
528
  * PERMISSION_{去前缀名}(兼容)的字段,值非 EDIT(2)(只读 1/隐藏 3 等)→ 剔除不入变量。
package/dist/facade.d.ts CHANGED
@@ -48,8 +48,11 @@ export declare class JeeflowFacade {
48
48
  private highLight;
49
49
  /** 节点成员进度(issue 41,对齐 boot3 highLight):按任务状态 + 会签变量组装
50
50
  * nodeProgress——会签节点带 type(PARALLEL/SEQUENTIAL),成员 done/active 标记;
51
- * 动态参与人节点(无静态 actorIds)不返回;name 缺省(引擎不持有宿主用户体系,前端降级显示 id) */
51
+ * 动态参与人节点(无静态 actorIds)不返回;name 走引擎 UserProvider SPI 解析
52
+ * realName(未注入/查不到时缺省空串,前端降级显示 id) */
52
53
  private buildNodeProgress;
54
+ /** 成员姓名解析(issue 43/E15):UserProvider SPI 并行批量解析 realName,查不到缺省空串 */
55
+ private resolveMemberNames;
53
56
  private collectPath;
54
57
  /** 决策输出边表达式求值(args = 实例变量 + 决策节点前置任务变量) */
55
58
  private evalDecisionExpr;
package/dist/facade.js CHANGED
@@ -4,7 +4,7 @@
4
4
  // action(boot2/boot3 端点短名)路由。返回统一结构 {code, msg, data}
5
5
  // (code=0 成功 / 99999999 失败)。操作人约定:args.operator 显式传入。
6
6
  import { TaskState, } from './model.js';
7
- import { KeyNextNodeOperator, KeyProcessStartNextNodeOperator } from './engine.js';
7
+ import { KeyNextNodeOperator, KeyProcessStartNextNodeOperator, isCountersign } from './engine.js';
8
8
  // submitType 枚举(对齐 boot3)
9
9
  const SUBMIT_APPLY = 0;
10
10
  const SUBMIT_AGREE = 1;
@@ -607,7 +607,7 @@ export class JeeflowFacade {
607
607
  if (def) {
608
608
  try {
609
609
  const flow = JSON.parse(toStr(def.content));
610
- nodeProgress = this.buildNodeProgress(flow, his);
610
+ nodeProgress = await this.buildNodeProgress(flow, his);
611
611
  await this.collectPath(flow, 'start', '', active, history, edges, new Set(), inst.variables ?? {}, his);
612
612
  }
613
613
  catch { /* ignore */ }
@@ -616,8 +616,9 @@ export class JeeflowFacade {
616
616
  }
617
617
  /** 节点成员进度(issue 41,对齐 boot3 highLight):按任务状态 + 会签变量组装
618
618
  * nodeProgress——会签节点带 type(PARALLEL/SEQUENTIAL),成员 done/active 标记;
619
- * 动态参与人节点(无静态 actorIds)不返回;name 缺省(引擎不持有宿主用户体系,前端降级显示 id) */
620
- buildNodeProgress(flow, his) {
619
+ * 动态参与人节点(无静态 actorIds)不返回;name 走引擎 UserProvider SPI 解析
620
+ * realName(未注入/查不到时缺省空串,前端降级显示 id) */
621
+ async buildNodeProgress(flow, his) {
621
622
  const progress = {};
622
623
  const names = [...new Set(his.map(t => t.taskName))];
623
624
  for (const name of names) {
@@ -640,24 +641,43 @@ export class JeeflowFacade {
640
641
  const node = (flow.nodes ?? []).find((n) => n.id === name);
641
642
  // 会签判定:定义节点属性(引擎创建任务时 performType 未落任务表,取模型为准)
642
643
  const nodeProps = node?.properties ?? {};
643
- const isCountersign = nodeProps.performType === 1 || nodeProps.countersignType != null;
644
- const item = {
645
- members: members.map((id) => {
646
- const m = { id, name: '' };
647
- if (doneSet.has(id))
648
- m.done = true;
649
- else if (id === activeActor)
650
- m.active = true;
651
- return m;
652
- }),
653
- };
654
- if (isCountersign && nodeProps.countersignType) {
644
+ const isCs = isCountersign(nodeProps.performType) || nodeProps.countersignType != null;
645
+ // 姓名走 UserProvider SPI 解析(未注入/查不到缺省空串),done/active 按任务状态标记
646
+ const memberList = await this.resolveMemberNames(members);
647
+ for (const m of memberList) {
648
+ if (doneSet.has(m.id))
649
+ m.done = true;
650
+ else if (m.id === activeActor)
651
+ m.active = true;
652
+ }
653
+ const item = { members: memberList };
654
+ if (isCs && nodeProps.countersignType) {
655
655
  item.type = nodeProps.countersignType;
656
656
  }
657
657
  progress[name] = item;
658
658
  }
659
659
  return progress;
660
660
  }
661
+ /** 成员姓名解析(issue 43/E15):UserProvider SPI 并行批量解析 realName,查不到缺省空串 */
662
+ async resolveMemberNames(ids) {
663
+ const userProv = this.engine.getUserProvider();
664
+ const nameMap = {};
665
+ if (userProv) {
666
+ const results = await Promise.all(ids.map(async (id) => {
667
+ try {
668
+ const u = await userProv.getUser(id);
669
+ return [id, u?.realName ?? ''];
670
+ }
671
+ catch {
672
+ return [id, '']; // 单用户失败不影响其余
673
+ }
674
+ }));
675
+ for (const [id, name] of results)
676
+ if (name)
677
+ nameMap[id] = name;
678
+ }
679
+ return ids.map(id => ({ id, name: nameMap[id] ?? '' }));
680
+ }
661
681
  async collectPath(flow, nodeId, edgeName, active, history, edges, visited, vars, historyTasks) {
662
682
  if (visited.has(nodeId))
663
683
  return;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mldong/jeeflow",
3
- "version": "1.8.6",
3
+ "version": "1.8.8",
4
4
  "description": "jeeflow workflow engine — Node.js / TypeScript implementation",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",