@steedos-labs/plugin-workflow 3.0.58 → 3.0.60

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 (33) hide show
  1. package/designer/dist/amis-renderer/amis-renderer.js +1 -1
  2. package/designer/dist/assets/{index-0cQynRDB.js → index-D5-hZ3Ut.js} +199 -159
  3. package/designer/dist/index.html +1 -1
  4. package/main/default/manager/instance_tasks_manager.js +36 -32
  5. package/main/default/manager/push_manager.js +63 -63
  6. package/main/default/manager/uuflowManagerForInitApproval.js +192 -98
  7. package/main/default/manager/uuflow_manager.js +31 -32
  8. package/main/default/objectTranslations/instances.en/instances.en.objectTranslation.yml +9 -0
  9. package/main/default/objectTranslations/instances.zh-CN/instances.zh-CN.objectTranslation.yml +9 -0
  10. package/main/default/objects/instance_tasks/buttons/instance_new.button.js +3 -0
  11. package/main/default/objects/instance_tasks/buttons/instance_new.button.yml +1 -1
  12. package/main/default/objects/instances/buttons/instance_cc.button.yml +1 -0
  13. package/main/default/objects/instances/buttons/instance_delete.button.yml +1 -1
  14. package/main/default/objects/instances/buttons/instance_distribute.button.yml +2 -1
  15. package/main/default/objects/instances/buttons/instance_export.button.js +1 -6
  16. package/main/default/objects/instances/buttons/instance_export.button.yml +12 -9
  17. package/main/default/objects/instances/buttons/instance_forward.button.yml +2 -1
  18. package/main/default/objects/instances/buttons/instance_new.button.js +3 -0
  19. package/main/default/objects/instances/buttons/instance_reassign.button.yml +2 -1
  20. package/main/default/objects/instances/buttons/instance_relocate.button.yml +3 -1
  21. package/main/default/objects/instances/buttons/instance_return.button.yml +1 -0
  22. package/main/default/objects/instances/buttons/instance_terminate.button.yml +1 -0
  23. package/main/default/objects/instances/listviews/monitor.listview.yml +13 -0
  24. package/main/default/objects/instances/listviews/outbox.listview.yml +36 -0
  25. package/main/default/routes/api_workflow_instance_terminate.router.js +26 -27
  26. package/main/default/routes/api_workflow_nav.router.js +65 -55
  27. package/main/default/routes/api_workflow_reassign.router.js +20 -17
  28. package/main/default/routes/api_workflow_redirect.router.js +11 -1
  29. package/main/default/routes/api_workflow_relocate.router.js +9 -4
  30. package/package.json +1 -1
  31. package/public/amis-renderer/amis-renderer.js +1 -1
  32. package/src/instance_record_queue.js +142 -12
  33. package/src/rests/badgeRecalcExecute.js +7 -11
@@ -5,7 +5,7 @@
5
5
  <link rel="shortcut icon" type="image/svg+xml" href="/images/logo.svg" />
6
6
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
7
  <title>designer</title>
8
- <script type="module" crossorigin src="/api/workflow/designer-v2/assets/index-0cQynRDB.js"></script>
8
+ <script type="module" crossorigin src="/api/workflow/designer-v2/assets/index-D5-hZ3Ut.js"></script>
9
9
  <link rel="stylesheet" crossorigin href="/api/workflow/designer-v2/assets/index-DEEcIiu0.css">
10
10
  </head>
11
11
  <body>
@@ -9,6 +9,7 @@
9
9
  // @ts-check
10
10
  const _ = require('lodash')
11
11
  const { getObject } = require('@steedos/objectql')
12
+ const { getCollection } = require('../utils/collection')
12
13
 
13
14
  const DISABLE_DIRECT = process.env.STEEDOS_INSTANCE_TASKS_DISABLE_DIRECT == true || process.env.STEEDOS_INSTANCE_TASKS_DISABLE_DIRECT == 'true';
14
15
 
@@ -36,8 +37,9 @@ async function _find(query) {
36
37
  return await getObject('instance_tasks').find(query);
37
38
  }
38
39
 
39
- async function _count(query) {
40
- return await getObject('instance_tasks').count(query);
40
+ async function _count(filter) {
41
+ const col = await getCollection('instance_tasks');
42
+ return await col.countDocuments(filter);
41
43
  }
42
44
 
43
45
  /**
@@ -117,30 +119,22 @@ async function insert_many_instance_tasks(insId, traceId, approveIds) {
117
119
  * @returns 更新后的instance_tasks
118
120
  */
119
121
  async function update_instance_tasks(insId, traceId, approveId, doc) {
120
- console.time(`update_instance_tasks ${approveId}`);
121
122
  let taskDoc = doc
122
123
  if (!taskDoc) {
123
- console.time(`update_instance_tasks_makeTaskDoc ${approveId}`);
124
124
  taskDoc = await _makeTaskDoc(insId, traceId, approveId)
125
125
  delete taskDoc._id
126
- console.timeEnd(`update_instance_tasks_makeTaskDoc ${approveId}`);
127
126
  }
128
- console.time(`update_instance_tasks_update ${approveId}`);
129
127
  const result = await _update(approveId, taskDoc)
130
- console.timeEnd(`update_instance_tasks_update ${approveId}`);
131
-
128
+
132
129
  // 如果任务已完成,更新相关通知为已读
133
130
  if (taskDoc.is_finished) {
134
- console.time(`update_instance_tasks_notifications ${approveId}`);
135
131
  const instance = taskDoc.instance || insId
136
132
  const handler = taskDoc.handler
137
133
  if (instance && handler) {
138
134
  await _updateNotificationsAsRead(instance, handler)
139
135
  }
140
- console.timeEnd(`update_instance_tasks_notifications ${approveId}`);
141
136
  }
142
-
143
- console.timeEnd(`update_instance_tasks ${approveId}`);
137
+
144
138
  return result
145
139
  }
146
140
 
@@ -180,23 +174,28 @@ async function update_many_instance_tasks(insId, traceId, approveIds, keys) {
180
174
 
181
175
  /**
182
176
  * 删除instance_tasks记录
183
- * @param {String} approveId
177
+ * @param {String} approveId
184
178
  * @returns 1
185
179
  */
186
180
  async function remove_instance_tasks(approveId) {
181
+ const col = await getCollection('instance_tasks')
182
+ const notificationsCol = await getCollection('notifications')
187
183
  // 删除前先获取任务信息用于更新通知
188
- const taskDoc = await getObject('instance_tasks').findOne(approveId)
189
- const result = await _remove(approveId)
190
-
184
+ const taskDoc = await col.findOne({ _id: approveId }, { projection: { instance: 1, handler: 1 } })
185
+ await col.deleteOne({ _id: approveId })
186
+
191
187
  // 删除任务后,更新相关通知为已删除
192
188
  if (taskDoc) {
193
189
  const { instance, handler } = taskDoc
194
190
  if (instance && handler) {
195
- await _updateNotificationsAsDeleted(instance, handler)
191
+ await notificationsCol.updateMany(
192
+ { owner: handler, 'related_to.o': 'instances', 'related_to.ids': instance },
193
+ { $set: { is_deleted: true } }
194
+ )
196
195
  }
197
196
  }
198
-
199
- return result
197
+
198
+ return 1
200
199
  }
201
200
 
202
201
  /**
@@ -205,21 +204,26 @@ async function remove_instance_tasks(approveId) {
205
204
  * @returns 1
206
205
  */
207
206
  async function remove_many_instance_tasks(approveIds) {
208
- const results = []
209
- for (const aId of approveIds) {
207
+ if (!approveIds || approveIds.length === 0) return []
208
+ const col = await getCollection('instance_tasks')
209
+ const notificationsCol = await getCollection('notifications')
210
+ const results = await Promise.all(approveIds.map(async (aId) => {
210
211
  // 删除前先获取任务信息用于更新通知
211
- const taskDoc = await getObject('instance_tasks').findOne(aId)
212
- const r = await _remove(aId)
213
- results.push(r)
214
-
212
+ const taskDoc = await col.findOne({ _id: aId }, { projection: { instance: 1, handler: 1 } })
213
+ await col.deleteOne({ _id: aId })
214
+
215
215
  // 删除任务后,更新相关通知为已删除
216
216
  if (taskDoc) {
217
217
  const { instance, handler } = taskDoc
218
218
  if (instance && handler) {
219
- await _updateNotificationsAsDeleted(instance, handler)
219
+ await notificationsCol.updateMany(
220
+ { owner: handler, 'related_to.o': 'instances', 'related_to.ids': instance },
221
+ { $set: { is_deleted: true } }
222
+ )
220
223
  }
221
224
  }
222
- }
225
+ return 1
226
+ }))
223
227
  return results
224
228
  }
225
229
 
@@ -269,14 +273,14 @@ async function direct_remove_many_instance_tasks(approveIds) {
269
273
 
270
274
  /**
271
275
  * 计数instance_tasks
272
- * @param {object} query
273
- * @returns 1
276
+ * @param {object} filter MongoDB原生查询条件
277
+ * @returns {number}
274
278
  */
275
- async function count_instance_tasks(query) {
279
+ async function count_instance_tasks(filter) {
276
280
  if(process.env.STEEDOS_WORKFLOW_DISABLE_BADGE === 'true'){
277
281
  return 0;
278
- }
279
- const result = await _count(query)
282
+ }
283
+ const result = await _count(filter)
280
284
  return result
281
285
  }
282
286
 
@@ -54,11 +54,12 @@ const uuflowManager = {
54
54
  const settings = require('@steedos/objectql').getSteedosConfig();
55
55
 
56
56
 
57
- async function count_instance_tasks(query) {
57
+ async function count_instance_tasks(filter) {
58
58
  if(process.env.STEEDOS_WORKFLOW_DISABLE_BADGE === 'true'){
59
59
  return 0;
60
- }
61
- return await getObject('instance_tasks').count(query)
60
+ }
61
+ const col = await getCollection('instance_tasks');
62
+ return await col.countDocuments(filter);
62
63
  }
63
64
 
64
65
  // 定义全局变量
@@ -385,29 +386,36 @@ pushManager.get_badge = async function (send_from, user_id) {
385
386
  if (!BADGE_SEND_FROM_WHITELIST.has(send_from) || !user_id) {
386
387
  return null;
387
388
  }
389
+ if (process.env.STEEDOS_WORKFLOW_DISABLE_BADGE === 'true') {
390
+ return 0;
391
+ }
388
392
 
389
- let badge = 0;
390
- const [spaceUsersCol, categoriesCol, keyvaluesCol] = await Promise.all([
393
+ const [spaceUsersCol, categoriesCol] = await Promise.all([
391
394
  getCollection('space_users'),
392
395
  getCollection('categories'),
393
- getCollection('steedos_keyvalues')
394
396
  ]);
395
-
396
- const badgeQuery = { user: user_id, key: 'badge' };
397
- const badgeFields = { fields: { _id: 1, value: 1 } };
397
+ const keyvaluesObj = getObject('steedos_keyvalues');
398
398
 
399
399
  const userSpaces = await spaceUsersCol.find(
400
400
  { user: user_id, user_accepted: true },
401
- { fields: { space: 1 } }
401
+ { projection: { space: 1 } }
402
402
  ).toArray();
403
403
 
404
- for (const userSpace of userSpaces) {
404
+ // space 之间并行处理,每个返回该 space 的 taskCount
405
+ const spaceBadges = await Promise.all(userSpaces.map(async (userSpace) => {
405
406
  const spaceId = userSpace.space;
406
407
 
408
+ // 查出该 space 的 keyvalue 记录(只查一次,app和workflow共用)
409
+ const spaceKeyValues = await keyvaluesObj.find({
410
+ filters: [['user', '=', user_id], ['key', '=', 'badge'], ['space', '=', spaceId]],
411
+ fields: ['_id', 'value']
412
+ });
413
+ let spaceKeyValue = spaceKeyValues.length > 0 ? spaceKeyValues[0] : null;
414
+
407
415
  // 按 app 分组的 category badge 更新
408
416
  const categories = await categoriesCol.find(
409
417
  { space: spaceId, app: { $ne: null } },
410
- { fields: { app: 1 } }
418
+ { projection: { app: 1 } }
411
419
  ).toArray();
412
420
 
413
421
  if (categories.length > 0) {
@@ -420,81 +428,70 @@ pushManager.get_badge = async function (send_from, user_id) {
420
428
  if (categoryIds.length === 0) continue;
421
429
 
422
430
  const categoryBadge = await count_instance_tasks({
423
- filters: [
424
- ['handler', '=', user_id],
425
- ['is_finished', '=', false],
426
- ['space', '=', spaceId],
427
- ['category', 'in', categoryIds],
428
- ]
431
+ handler: user_id,
432
+ is_finished: false,
433
+ space: spaceId,
434
+ category: { $in: categoryIds },
429
435
  });
430
436
 
431
- const appKeyValue = await keyvaluesCol.findOne(
432
- { ...badgeQuery, space: spaceId },
433
- badgeFields
434
- );
435
-
436
- if (appKeyValue) {
437
- if (appKeyValue.value?.[appName] !== categoryBadge) {
438
- await getObject('steedos_keyvalues').update(appKeyValue._id, {
439
- [`value.${appName}`]: categoryBadge
437
+ if (spaceKeyValue) {
438
+ if (spaceKeyValue.value?.[appName] !== categoryBadge) {
439
+ await keyvaluesObj.update(spaceKeyValue._id, {
440
+ value: { ...spaceKeyValue.value, [appName]: categoryBadge }
440
441
  });
442
+ spaceKeyValue.value = { ...spaceKeyValue.value, [appName]: categoryBadge };
441
443
  }
442
444
  } else {
443
- await getObject('steedos_keyvalues').insert({
445
+ const inserted = await keyvaluesObj.insert({
444
446
  user: user_id,
445
447
  space: spaceId,
446
448
  key: 'badge',
447
449
  value: { [appName]: categoryBadge }
448
450
  });
451
+ spaceKeyValue = inserted;
449
452
  }
450
453
  }
451
454
  }
452
455
 
453
456
  // workflow 记录所有待办数量
454
457
  const taskCount = await count_instance_tasks({
455
- filters: [
456
- ['handler', '=', user_id],
457
- ['is_finished', '=', false],
458
- ['space', '=', spaceId],
459
- ]
458
+ handler: user_id,
459
+ is_finished: false,
460
+ space: spaceId,
460
461
  });
461
- badge += taskCount;
462
-
463
- const sk = await keyvaluesCol.findOne(
464
- { ...badgeQuery, space: spaceId },
465
- badgeFields
466
- );
467
462
 
468
- if (sk) {
469
- if (sk.value?.workflow !== taskCount) {
470
- await getObject('steedos_keyvalues').update(sk._id, {
471
- 'value.workflow': taskCount
463
+ if (spaceKeyValue) {
464
+ if (spaceKeyValue.value?.workflow !== taskCount) {
465
+ await keyvaluesObj.update(spaceKeyValue._id, {
466
+ value: { ...spaceKeyValue.value, workflow: taskCount }
472
467
  });
473
- continue;
474
468
  }
475
469
  } else {
476
- await getObject('steedos_keyvalues').insert({
470
+ await keyvaluesObj.insert({
477
471
  user: user_id,
478
472
  space: spaceId,
479
473
  key: 'badge',
480
474
  value: { workflow: taskCount }
481
475
  });
482
- continue;
483
476
  }
484
- }
477
+
478
+ return taskCount;
479
+ }));
480
+
481
+ const badge = spaceBadges.reduce((sum, count) => sum + count, 0);
485
482
 
486
483
  // 更新跨 space 的全局 badge
487
- const skAll = await keyvaluesCol.findOne(
488
- { ...badgeQuery, space: null },
489
- { fields: { _id: 1 } }
490
- );
491
-
492
- if (skAll) {
493
- await getObject('steedos_keyvalues').update(skAll._id, {
494
- 'value.workflow': badge
484
+ const skAllArr = await keyvaluesObj.find({
485
+ filters: [['user', '=', user_id], ['key', '=', 'badge'], ['space', '=', null]],
486
+ fields: ['_id']
487
+ });
488
+
489
+ if (skAllArr.length > 0) {
490
+ await keyvaluesObj.update(skAllArr[0]._id, {
491
+ value: { workflow: badge }
495
492
  });
496
493
  } else {
497
- await getObject('steedos_keyvalues').insert({
494
+ await keyvaluesObj.insert({
498
495
  user: user_id,
499
496
  space: null,
500
497
  key: 'badge',
@@ -686,7 +683,9 @@ pushManager.send_instance_notification = async function (send_from, instance, de
686
683
  try {
687
684
  const space_id = instance.space;
688
685
  const instance_id = instance._id;
686
+
689
687
  const flow = flowDoc || await uuflowManager.getFlow(instance.flow);
688
+
690
689
  const to_users = await pushManager.get_to_users(send_from, instance, cc_user_ids, current_user_info);
691
690
 
692
691
  const href = `${process.env.ROOT_URL}workflow/space/${space_id}/inbox/${instance_id}`;
@@ -753,6 +752,7 @@ pushManager.send_instance_notification = async function (send_from, instance, de
753
752
 
754
753
  const body = await pushManager.get_body(parameters, lang);
755
754
  const title = await pushManager.get_title(parameters, lang);
755
+
756
756
  const badge = await pushManager.get_badge(send_from, to_user._id);
757
757
 
758
758
  const push_body = {
@@ -785,15 +785,14 @@ pushManager.send_instance_notification = async function (send_from, instance, de
785
785
 
786
786
 
787
787
  // 发送给当前用户
788
- pushManager.send_message_current_user = function (user_info) {
788
+ pushManager.send_message_current_user = async function (user_info) {
789
789
  if (process.env.STEEDOS_DEBUG_DISABLE_PUSHMANAGER) {
790
790
  return;
791
791
  }
792
792
 
793
793
  try {
794
- const badge = this.get_badge("current_user", user_info._id);
794
+ const badge = await this.get_badge("current_user", user_info._id);
795
795
  const push_body = { badge };
796
-
797
796
  return this.send_message([user_info.steedos_id], push_body, user_info);
798
797
  } catch (error) {
799
798
  console.error(error.stack);
@@ -805,21 +804,22 @@ pushManager.send_message_to_specifyUser = async function (send_from, to_user) {
805
804
  if (process.env.STEEDOS_DEBUG_DISABLE_PUSHMANAGER) {
806
805
  return
807
806
  }
808
- const db = {
809
- users: await getCollection("users")
810
- }
811
807
  var badge, e, push_body, user_info;
812
808
  try {
813
809
  badge = await pushManager.get_badge(send_from, to_user);
810
+
814
811
  push_body = new Object;
815
812
  push_body["badge"] = badge;
816
- user_info = await db.users.findOne({
813
+
814
+ const usersCol = await getCollection("users");
815
+ user_info = await usersCol.findOne({
817
816
  _id: to_user
818
817
  }, {
819
818
  fields: {
820
819
  steedos_id: 1
821
820
  }
822
821
  });
822
+
823
823
  if (user_info) {
824
824
  return await pushManager.send_message([user_info.steedos_id], push_body);
825
825
  }