@mldong/jeeflow 1.8.10 → 1.8.11

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.js CHANGED
@@ -148,7 +148,7 @@ export class EngineImpl {
148
148
  const [actors, lc] = getCsState(vars, curNode.id);
149
149
  if (actors && lc + 1 < actors.length) {
150
150
  // 聚合根:创建串行会签下一步任务
151
- const nt = inst.createTask(this.nextId(), curNode.id, curNode.text.value, actors[lc + 1], operator, curNode.properties?.form ?? '', now);
151
+ const nt = inst.createTask(this.nextId(), curNode.id, curNode.text.value, actors[lc + 1], operator, curNode.properties?.form ?? '', now, 1);
152
152
  nt.variables = {
153
153
  [`nrOfInstances_${curNode.id}`]: actors.length,
154
154
  [`loopCounter_${curNode.id}`]: lc + 1,
@@ -363,10 +363,11 @@ export class EngineImpl {
363
363
  switch (ct) {
364
364
  case 'PARALLEL':
365
365
  for (const actor of actors)
366
- await this.repo.saveTask(inst.createTask(this.nextId(), node.id, node.text.value, actor, operator, form, now));
366
+ await this.repo.saveTask(inst.createTask(this.nextId(), node.id, node.text.value, actor, operator, form, now, 1));
367
367
  return;
368
368
  case 'SEQUENTIAL': {
369
- const nt = inst.createTask(this.nextId(), node.id, node.text.value, actors[0], operator, form, now);
369
+ // 顺序会签任务也是会签任务(issues/57 E29 修正:仅普通分支默认 0
370
+ const nt = inst.createTask(this.nextId(), node.id, node.text.value, actors[0], operator, form, now, 1);
370
371
  nt.variables = {
371
372
  [`nrOfInstances_${node.id}`]: actors.length,
372
373
  [`loopCounter_${node.id}`]: 0,
@@ -377,7 +378,7 @@ export class EngineImpl {
377
378
  }
378
379
  default:
379
380
  for (const actor of actors)
380
- await this.repo.saveTask(inst.createTask(this.nextId(), node.id, node.text.value, actor, operator, form, now));
381
+ await this.repo.saveTask(inst.createTask(this.nextId(), node.id, node.text.value, actor, operator, form, now, 1));
381
382
  return;
382
383
  }
383
384
  }
package/dist/facade.js CHANGED
@@ -143,6 +143,13 @@ export class JeeflowFacade {
143
143
  flowArgs[k] = v;
144
144
  }
145
145
  const inst = await this.engine.startProcessInstanceById(defineId, operator, flowArgs);
146
+ // issues/56 E28:发起时抄送(f_ccActors)创建 cc 实例(对齐 Java enableCcActors 语义)
147
+ const ccList = Array.isArray(flowArgs.f_ccActors) ? flowArgs.f_ccActors
148
+ : typeof flowArgs.f_ccActors === 'string' && flowArgs.f_ccActors.trim()
149
+ ? flowArgs.f_ccActors.split(',').map((x) => x.trim()).filter(Boolean) : [];
150
+ if (ccList.length > 0) {
151
+ await this.repo.createCcInstance(inst.id, operator, ...ccList);
152
+ }
146
153
  // startAndExecute:自动完成申请节点(assignee="applicant" → 发起人)
147
154
  const doing = await this.repo.findDoingTasks(inst.id);
148
155
  for (const task of doing) {
@@ -229,9 +236,18 @@ export class JeeflowFacade {
229
236
  // 撤回:废弃全部 doing 任务 + 实例状态(v1.0.1:updateInstance 级联落库)
230
237
  const operator = String(args.operator ?? 'user1');
231
238
  const now = new Date();
232
- const abandoned = inst.abandonAllDoing(now);
233
- inst.reject(now);
239
+ // findInstanceById 不加载 tasks(空),必须按实例查 doing 任务废弃
240
+ const abandoned = [];
241
+ for (const t of await this.repo.findDoingTasks(instanceId)) {
242
+ t.abandon(now);
243
+ abandoned.push(t);
244
+ }
245
+ // issues/53 E25:撤回状态应为 Withdraw(30) 而非 Reject(45)(对齐 Java)
246
+ inst.withdraw(now);
234
247
  inst.updateUser = operator;
248
+ // 级联覆盖防护(issues/57 补正):废弃副本同步回聚合——updateInstance 级联会用
249
+ // 聚合内旧任务覆盖已废弃状态(memory 加载 tasks 时必现)
250
+ inst.tasks = abandoned;
235
251
  for (const t of abandoned)
236
252
  await this.repo.updateTask(t);
237
253
  await this.repo.updateInstance(inst);
@@ -532,13 +548,24 @@ export class JeeflowFacade {
532
548
  await ext.updateDesign(found);
533
549
  design = found;
534
550
  }
535
- // 内容快照(设计稿内容存历史表)
551
+ // 内容快照(设计稿内容存历史表)——issues/51 E23:无 content 也写默认快照
552
+ // (对齐 Java contentBytes 默认 JSON),保证「新建 → 部署」链路可用
536
553
  if (args.content != null) {
537
554
  await ext.saveDesignHis({
538
555
  id: '', processDesignId: design.id, content: String(args.content),
539
556
  createTime: new Date(), createUser: operator,
540
557
  });
541
558
  }
559
+ else {
560
+ await ext.saveDesignHis({
561
+ id: '', processDesignId: design.id,
562
+ content: JSON.stringify({
563
+ name: design.name, displayName: design.displayName, type: design.type,
564
+ nodes: [], edges: [],
565
+ }),
566
+ createTime: new Date(), createUser: operator,
567
+ });
568
+ }
542
569
  return { id: design.id };
543
570
  }
544
571
  // ── 委托代理(需扩展仓储) ───────────────────────────────────────────────
@@ -491,10 +491,12 @@ export class JdbcRepository {
491
491
  try {
492
492
  const countRow = await conn.fetchOne(this.sql('SELECT COUNT(DISTINCT t.id) ' + where), [filter, ...cond.params]);
493
493
  const total = Number(Object.values(countRow)[0] ?? 0);
494
+ // issues/45 E17:pd.display_name 与 t.display_name 列名冲突(DISTINCT 时后者覆盖)——
495
+ // 流程名加别名 pd_display_name,mapTaskRow 分别映射
494
496
  const cols = 'DISTINCT t.id, t.process_instance_id, t.task_name, t.display_name, t.task_type, t.perform_type,' +
495
497
  ' t.task_state, t.operator, t.finish_time, t.expire_time, t.form_key, t.task_parent_id, t.variable,' +
496
498
  ' t.create_time, t.create_user, t.update_time, t.update_user,' +
497
- ' pd.name, pd.display_name, pd.version AS process_define_version,' +
499
+ ' pd.name, pd.display_name AS pd_display_name, pd.version AS process_define_version,' +
498
500
  ' pi.variable AS instance_variable, pi.create_time AS instance_create_time';
499
501
  const rows = await conn.fetchAll(this.sql(`SELECT ${cols}${where} ORDER BY t.id DESC LIMIT ? OFFSET ?`), [filter, ...cond.params, pageSize, (pageNum - 1) * pageSize]);
500
502
  return { rows: rows.map(r => this.mapTaskRow(r)), total };
@@ -598,7 +600,7 @@ export class JdbcRepository {
598
600
  taskParentId: r.task_parent_id != null ? rowId(r.task_parent_id) : undefined,
599
601
  variables, createTime: r.create_time, createUser: rowId(r.create_user),
600
602
  updateTime: r.update_time, updateUser: rowId(r.update_user),
601
- processDefineName: r.name ?? '', processDefineDisplayName: r.display_name ?? '',
603
+ processDefineName: r.name ?? '', processDefineDisplayName: r.pd_display_name ?? '',
602
604
  defineVersion: Number(r.process_define_version ?? 0),
603
605
  instanceVariable: r.instance_variable ?? '', instanceCreateTime: r.instance_create_time,
604
606
  };
package/dist/model.d.ts CHANGED
@@ -155,6 +155,8 @@ export declare class ProcessInstance {
155
155
  finish(now: Date): void;
156
156
  /** 驳回流程 */
157
157
  reject(now: Date): void;
158
+ /** 撤回流程(issues/53 E25:withdraw 用 Withdraw(30),与 reject 区分) */
159
+ withdraw(now: Date): void;
158
160
  /** 追加变量 */
159
161
  addVariable(vars: Record<string, any>): void;
160
162
  /** 获取进行中任务 */
@@ -163,8 +165,8 @@ export declare class ProcessInstance {
163
165
  getDoneTasks(): ProcessTask[];
164
166
  /** 所有任务是否都已完成(join 合并判断) */
165
167
  isAllTasksFinished(): boolean;
166
- /** 创建任务(子实体工厂) */
167
- createTask(id: string, taskName: string, displayName: string, actor: string, operator: string, formKey: string, now: Date): ProcessTask;
168
+ /** 创建任务(子实体工厂)——performType:0 普通 / 1 会签(issues/52 E24 落库对齐 Java) */
169
+ createTask(id: string, taskName: string, displayName: string, actor: string, operator: string, formKey: string, now: Date, performType?: number): ProcessTask;
168
170
  }
169
171
  export declare class ProcessTask {
170
172
  id: string;
package/dist/model.js CHANGED
@@ -128,6 +128,11 @@ export class ProcessInstance {
128
128
  this.state = InstanceState.Reject;
129
129
  this.updateTime = now;
130
130
  }
131
+ /** 撤回流程(issues/53 E25:withdraw 用 Withdraw(30),与 reject 区分) */
132
+ withdraw(now) {
133
+ this.state = InstanceState.Withdraw;
134
+ this.updateTime = now;
135
+ }
131
136
  /** 追加变量 */
132
137
  addVariable(vars) {
133
138
  Object.assign(this.variables, vars);
@@ -144,13 +149,13 @@ export class ProcessInstance {
144
149
  isAllTasksFinished() {
145
150
  return !this.tasks.some(t => t.isDoing());
146
151
  }
147
- /** 创建任务(子实体工厂) */
148
- createTask(id, taskName, displayName, actor, operator, formKey, now) {
152
+ /** 创建任务(子实体工厂)——performType:0 普通 / 1 会签(issues/52 E24 落库对齐 Java) */
153
+ createTask(id, taskName, displayName, actor, operator, formKey, now, performType = 0) {
149
154
  const task = new ProcessTask({
150
155
  id, processInstanceId: this.id,
151
156
  taskName, displayName, taskState: TaskState.Doing,
152
157
  actorId: '', actorIds: [actor],
153
- taskType: 0, performType: 0, formKey,
158
+ taskType: 0, performType, formKey,
154
159
  variables: {},
155
160
  createTime: now, updateTime: now, createUser: operator, updateUser: operator,
156
161
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mldong/jeeflow",
3
- "version": "1.8.10",
3
+ "version": "1.8.11",
4
4
  "description": "jeeflow workflow engine — Node.js / TypeScript implementation",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",