@steedos-labs/plugin-workflow 3.0.0-beta.8 → 3.0.0

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 (72) hide show
  1. package/main/default/client/instance.client.js +6 -6
  2. package/main/default/client/object_workflows.client.js +8 -7
  3. package/main/default/manager/import.js +17 -1
  4. package/main/default/manager/push_manager.js +20 -12
  5. package/main/default/manager/uuflowManagerForInitApproval.js +794 -0
  6. package/main/default/manager/uuflow_manager.js +53 -4
  7. package/main/default/manager/workflow_manager.js +1 -1
  8. package/main/default/methods/trace_approve_cc.js +568 -0
  9. package/main/default/objectTranslations/flows.en/flows.en.objectTranslation.yml +19 -0
  10. package/main/default/objectTranslations/flows.zh-CN/flows.zh-CN.objectTranslation.yml +19 -0
  11. package/main/default/objectTranslations/instance_tasks.en/instance_tasks.en.objectTranslation.yml +211 -0
  12. package/main/default/objectTranslations/instance_tasks.zh-CN/instance_tasks.zh-CN.objectTranslation.yml +211 -0
  13. package/main/default/objectTranslations/instances.en/instances.en.objectTranslation.yml +212 -0
  14. package/main/default/objectTranslations/instances.zh-CN/instances.zh-CN.objectTranslation.yml +209 -0
  15. package/main/default/objects/categories.object.yml +1 -0
  16. package/main/default/objects/flows/buttons/del.button.yml +7 -10
  17. package/main/default/objects/flows/buttons/design_form_layout.button.js +5 -2
  18. package/main/default/objects/flows/buttons/distributeAdmin.button.yml +5 -5
  19. package/main/default/objects/flows/buttons/newexport.button.yml +1 -1
  20. package/main/default/objects/flows/buttons/newimport.button.yml +2 -1
  21. package/main/default/objects/flows/flows.object.yml +12 -4
  22. package/main/default/objects/forms/forms.object.yml +39 -0
  23. package/main/default/objects/instance_tasks/buttons/instance_new.button.yml +3 -5
  24. package/main/default/objects/instances/buttons/instance_cc.button.yml +7 -7
  25. package/main/default/objects/instances/buttons/instance_delete.button.yml +2 -2
  26. package/main/default/objects/instances/buttons/instance_delete_many.button.yml +6 -6
  27. package/main/default/objects/instances/buttons/instance_distribute.button.yml +14 -13
  28. package/main/default/objects/instances/buttons/instance_flow_chart.button.yml +1 -1
  29. package/main/default/objects/instances/buttons/instance_forward.button.yml +8 -8
  30. package/main/default/objects/instances/buttons/instance_new.button.yml +3 -5
  31. package/main/default/objects/instances/buttons/instance_reassign.button.yml +1 -16
  32. package/main/default/objects/instances/buttons/instance_related.button.yml +4 -4
  33. package/main/default/objects/instances/buttons/instance_relocate.button.yml +9 -12
  34. package/main/default/objects/instances/buttons/instance_retrieve.button.yml +106 -2
  35. package/main/default/objects/instances/buttons/instance_save.button.yml +3 -9
  36. package/main/default/objects/instances/buttons/instance_submit.button.yml +1 -1
  37. package/main/default/objects/instances/buttons/instance_terminate.button.yml +7 -10
  38. package/main/default/objects/instances/listviews/monitor.listview.yml +0 -1
  39. package/main/default/pages/flowdetail.page.amis.json +9 -9
  40. package/main/default/pages/instance_detail.page.amis.json +3 -3
  41. package/main/default/pages/instance_tasks_detail.page.amis.json +3 -3
  42. package/main/default/pages/instance_tasks_list.page.amis.json +147 -110
  43. package/main/default/pages/instances_list.page.amis.json +146 -110
  44. package/main/default/routes/am.router.js +49 -2
  45. package/main/default/routes/api_cc.router.js +5 -12
  46. package/main/default/routes/api_flow_permission.router.js +7 -2
  47. package/main/default/routes/api_get_object_workflows.router.js +79 -22
  48. package/main/default/routes/api_object_workflow_drafts.router.js +18 -19
  49. package/main/default/routes/api_workflow_chart.router.js +682 -0
  50. package/main/default/routes/api_workflow_engine.router.js +1 -1
  51. package/main/default/routes/api_workflow_instance_return.router.js +164 -167
  52. package/main/default/routes/api_workflow_next_step_users.router.js +13 -8
  53. package/main/default/routes/api_workflow_reassign.router.js +200 -196
  54. package/main/default/routes/api_workflow_relocate.router.js +2 -2
  55. package/main/default/routes/api_workflow_retrieve.router.js +246 -237
  56. package/main/default/routes/export.router.js +5 -4
  57. package/main/default/routes/flow_form_design.ejs +33 -8
  58. package/main/default/routes/flow_form_design.router.js +4 -3
  59. package/main/default/routes/import.router.js +6 -7
  60. package/main/default/services/flows.service.js +1 -1
  61. package/main/default/translations/en.translation.yml +5 -0
  62. package/main/default/translations/zh-CN.translation.yml +2 -1
  63. package/main/default/triggers/amis_form_design.trigger.js +27 -5
  64. package/main/default/triggers/instances.trigger.js +9 -7
  65. package/main/default/utils/designerManager.js +12 -5
  66. package/package.json +4 -4
  67. package/package.service.js +21 -7
  68. package/public/workflow/index.css +4 -0
  69. package/src/instance_record_queue.js +1 -3
  70. package/src/rests/api_workflow_instance_batch_remove.js +4 -3
  71. package/src/webhook_queue.js +283 -0
  72. package/main/default/manager/index.js +0 -23
@@ -16,6 +16,7 @@ const pushManager = require('./push_manager');
16
16
  const { t } = require('@steedos/i18n')
17
17
  const moment = require('moment')
18
18
  const { getObject } = require('@steedos/objectql');
19
+ const { evaluate } = require('amis-formula');
19
20
 
20
21
  const UUFlowManager = {};
21
22
 
@@ -556,6 +557,47 @@ UUFlowManager.isFlowSpaceMatched = function (flow, space_id) {
556
557
  }
557
558
  };
558
559
 
560
+ const isAmisFormula = (formula) => {
561
+ // 有${}包裹的表达式就识别为amis公式
562
+ return /\$\{.+\}/.test(formula);
563
+ };
564
+
565
+ const runAmisFormula = function (formula, data) {
566
+ try {
567
+ const amisFormulaValue = evaluate(
568
+ formula,
569
+ Object.assign({}, data),
570
+ {},
571
+ );
572
+ if (formula === amisFormulaValue) {
573
+ throw new Error(
574
+ `Workflow Condition Step Amis formula "${formula}" evaluate failed "Function is not defined".`,
575
+ );
576
+ } else {
577
+ return amisFormulaValue;
578
+ }
579
+ } catch (e) {
580
+ throw new Error(
581
+ `Catch an error "${e.message}" while evaluate condition step amis formula "${formula}".`,
582
+ );
583
+ }
584
+ }
585
+
586
+ /**
587
+ * Calculate condition for conditional step
588
+ * @param {Object} values - Form values
589
+ * @param {String} condition_str - Condition string
590
+ * @returns {Boolean} Condition result
591
+ */
592
+ UUFlowManager.calculateConditionWithAmis = function (values, condition_str) {
593
+ try {
594
+ return runAmisFormula(condition_str, values);
595
+ } catch (error) {
596
+ console.error(error.stack);
597
+ return false;
598
+ }
599
+ };
600
+
559
601
  /**
560
602
  * Calculate condition for conditional step
561
603
  * @param {Object} values - Form values
@@ -829,10 +871,17 @@ UUFlowManager.getNextSteps = async function (instance, flow, step, judge, values
829
871
 
830
872
  for (const step_line of step.lines) {
831
873
  if (step_line.state === "submitted") {
832
- const step_line_condition = step_line.condition.replace(reg, (vowel) => {
833
- return prefix + vowel.replace(/\{\s*/, "[\"").replace(/\s*\}/, "\"]").replace(/\s*\.\s*/g, "\"][\"");
834
- });
835
- const allow = UUFlowManager.calculateCondition(__values, step_line_condition);
874
+ let step_line_condition = step_line.condition;
875
+ let allow = false;
876
+ if (isAmisFormula(step_line_condition)) {
877
+ allow = UUFlowManager.calculateConditionWithAmis(__values, step_line_condition);
878
+ }
879
+ else {
880
+ step_line_condition = step_line.condition.replace(reg, (vowel) => {
881
+ return prefix + vowel.replace(/\{\s*/, "[\"").replace(/\s*\}/, "\"]").replace(/\s*\.\s*/g, "\"][\"");
882
+ });
883
+ allow = UUFlowManager.calculateCondition(__values, step_line_condition);
884
+ }
836
885
  if (allow) {
837
886
  nextSteps.push(step_line.to_step);
838
887
  }
@@ -246,7 +246,7 @@ WorkflowManager.getUser = async function (spaceId, userId, notNeedDetails) {
246
246
  }
247
247
 
248
248
  if (typeof userId !== 'string') {
249
- return WorkflowManager.getUsers(spaceId, userId, notNeedDetails);
249
+ return await WorkflowManager.getUsers(spaceId, userId, notNeedDetails);
250
250
  }
251
251
 
252
252
  const spaceUsersCollection = await getCollection('space_users');
@@ -0,0 +1,568 @@
1
+
2
+ const { getCollection, _makeNewID } = require('../utils/collection');
3
+ const UUFlowManager = require('../manager/uuflow_manager.js');
4
+ const pushManager = require('../manager/push_manager.js');
5
+ const {
6
+ update_instance_tasks,
7
+ insert_instance_tasks,
8
+ remove_instance_tasks,
9
+ direct_remove_many_instance_tasks
10
+ } = require('../manager/instance_tasks_manager')
11
+
12
+ module.exports = {
13
+ cc_do: async function (approve, cc_user_ids, description, ctx = {}) {
14
+ var setObj = {};
15
+ var ins_id = approve.instance;
16
+ var trace_id = approve.trace;
17
+ var approve_id = approve._id;
18
+
19
+ const instancesCollection = await getCollection('instances');
20
+ const usersCollection = await getCollection('users');
21
+ const spaceUsersCollection = await getCollection('space_users');
22
+ const organizationsCollection = await getCollection('organizations');
23
+
24
+ const instance = await instancesCollection.findOne({ _id: ins_id }, {
25
+ projection: {
26
+ space: 1,
27
+ traces: 1,
28
+ cc_users: 1,
29
+ values: 1
30
+ }
31
+ });
32
+ var current_user_id = ctx.userId || this.userId;
33
+ var space_id = instance.space;
34
+ var new_approves = [];
35
+
36
+ const from_user = await usersCollection.findOne({ _id: current_user_id })
37
+ const from_user_name = from_user.name;
38
+
39
+ for (const [idx, userId] of cc_user_ids.entries()) {
40
+
41
+ const user = await usersCollection.findOne({ _id: userId }, {
42
+ projection: {
43
+ name: 1
44
+ }
45
+ })
46
+
47
+ const space_user = await spaceUsersCollection.findOne({ user: userId, space: space_id }, {
48
+ projection: {
49
+ organization: 1
50
+ }
51
+ })
52
+
53
+ var org_id = space_user.organization;
54
+
55
+ const organization = await organizationsCollection.findOne({ _id: org_id }, {
56
+ projection: {
57
+ name: 1,
58
+ fullname: 1
59
+ }
60
+ })
61
+
62
+ var agent = await UUFlowManager.getAgent(space_id, userId);
63
+ var handler_id = userId;
64
+ var handler_info = user;
65
+ var handler_space_user = space_user;
66
+ var handler_org_info = organization;
67
+ if (agent) {
68
+ handler_id = agent;
69
+ handler_info = await usersCollection.findOne({ _id: agent }, {
70
+ projection: {
71
+ name: 1
72
+ }
73
+ })
74
+
75
+ handler_space_user = await UUFlowManager.getSpaceUser(space_id, agent);
76
+ handler_org_info = await UUFlowManager.getSpaceUserOrgInfo(handler_space_user);
77
+ cc_user_ids[idx] = agent;
78
+ }
79
+ var appr = {
80
+ '_id': _makeNewID(),
81
+ 'instance': ins_id,
82
+ 'trace': trace_id,
83
+ 'is_finished': false,
84
+ 'user': userId,
85
+ 'user_name': user.name,
86
+ 'handler': handler_id,
87
+ 'handler_name': handler_info.name,
88
+ 'handler_organization': handler_space_user.organization,
89
+ 'handler_organization_name': handler_org_info.name,
90
+ 'handler_organization_fullname': handler_org_info.fullname,
91
+ 'type': 'cc',
92
+ 'start_date': new Date(),
93
+ 'is_read': false,
94
+ 'from_user': current_user_id,
95
+ 'from_user_name': from_user_name,
96
+ 'opinion_fields_code': approve.opinion_fields_code,
97
+ 'sign_field_code': (approve.opinion_fields_code && approve.opinion_fields_code.length == 1) ? approve.opinion_fields_code[0] : "",
98
+ 'from_approve_id': approve_id,
99
+ 'cc_description': description
100
+ };
101
+ if (agent) {
102
+ appr.agent = agent;
103
+ }
104
+ await UUFlowManager.setRemindInfo(instance.values, appr)
105
+ new_approves.push(appr);
106
+ }
107
+
108
+ setObj.modified = new Date();
109
+ setObj.modified_by = this.userId;
110
+
111
+ await instancesCollection.updateOne({
112
+ _id: ins_id,
113
+ 'traces._id': trace_id
114
+ }, {
115
+ $set: setObj,
116
+ $push: {
117
+ 'traces.$.approves': {
118
+ $each: new_approves
119
+ },
120
+ cc_users: {
121
+ $each: cc_user_ids
122
+ }
123
+ },
124
+ $inc: {
125
+ cc_count: cc_user_ids.length
126
+ }
127
+ });
128
+ // 新增记录
129
+ for (const a of new_approves) {
130
+ await insert_instance_tasks(ins_id, trace_id, a._id)
131
+ }
132
+
133
+ const updatedInstance = await instancesCollection.findOne({ _id: ins_id });
134
+
135
+ await pushManager.send_instance_notification("trace_approve_cc", updatedInstance, "", from_user, cc_user_ids);
136
+
137
+ flow_id = instance.flow;
138
+ approve.cc_user_ids = cc_user_ids; // 记录下本次传阅的人员ID作为hook接口中的参数
139
+ // 如果已经配置webhook并已激活则触发
140
+ await pushManager.triggerWebhook(flow_id, instance, approve, 'cc_do', current_user_id, cc_user_ids)
141
+ return true;
142
+ },
143
+
144
+ /**
145
+ cc_read: function (approve) {
146
+ var setObj = {};
147
+ var ins_id = approve.instance;
148
+ var trace_id = approve.trace;
149
+ var approve_id = approve._id;
150
+ var instance = db.instances.findOne(ins_id, {
151
+ fields: {
152
+ traces: 1
153
+ }
154
+ });
155
+ var current_user_id = this.userId;
156
+ var current_trace = _.find(instance.traces, function (t) {
157
+ return t._id == trace_id;
158
+ })
159
+
160
+ var index = 0;
161
+
162
+ current_trace.approves.forEach(function (a, idx) {
163
+ if (approve_id == a._id && a.type == 'cc' && a.handler == current_user_id && !a.is_read) {
164
+ index = idx;
165
+ }
166
+ });
167
+
168
+ // setObj['traces.$.approves.' + index + '.is_read'] = true;
169
+ // setObj['traces.$.approves.' + index + '.read_date'] = new Date();
170
+ const key_str = 'traces.$.approves.' + index + '.';
171
+ const approveDoc = {
172
+ is_read: true,
173
+ read_date: new Date()
174
+ }
175
+ for (const key in approveDoc) {
176
+ if (Object.hasOwnProperty.call(approveDoc, key)) {
177
+ setObj[key_str + key] = approveDoc[key]
178
+ }
179
+ }
180
+
181
+
182
+ db.instances.update({
183
+ _id: ins_id,
184
+ 'traces._id': trace_id
185
+ }, {
186
+ $set: setObj
187
+ });
188
+ update_instance_tasks(ins_id, trace_id, current_trace.approves[index]._id, approveDoc)
189
+ return true;
190
+ },
191
+
192
+ cc_submit: function (ins_id, description, myApprove, ccHasEditPermission) {
193
+ var setObj = {};
194
+
195
+ var instance = db.instances.findOne(ins_id);
196
+ var traces = instance.traces;
197
+ var current_user_id = this.userId;
198
+
199
+ var flow = uuflowManager.getFlow(instance.flow);
200
+ var values = myApprove.values || {};
201
+
202
+ var approve_id = myApprove._id;
203
+
204
+ var myTrace;
205
+
206
+ var is_finished; // 传阅正真结束的标记
207
+
208
+ for (let tidx = 0; tidx < traces.length; tidx++) {
209
+ const t = traces[tidx];
210
+ if (t.approves) {
211
+ for (let aidx = 0; aidx < t.approves.length; aidx++) {
212
+ const a = t.approves[aidx];
213
+ if (approve_id == a._id && a.type == 'cc' && a.handler == current_user_id && a.is_finished == false) {
214
+ var upobj = {};
215
+ var key_str = 'traces.$.approves.' + aidx + '.';
216
+ const approveDoc = {
217
+ 'is_finished': true,
218
+ 'is_read': true,
219
+ 'finish_date': new Date(),
220
+ 'judge': "submitted",
221
+ 'cost_time': new Date() - a.start_date,
222
+ }
223
+ // upobj[key_str + 'is_finished'] = true;
224
+ // upobj[key_str + 'is_read'] = true;
225
+ // upobj[key_str + 'finish_date'] = new Date();
226
+ // upobj[key_str + 'judge'] = "submitted";
227
+ // upobj[key_str + 'cost_time'] = new Date() - a.start_date;
228
+ if (approve_id == a._id && !t.is_finished && ccHasEditPermission) {
229
+ myTrace = t;
230
+ var step = uuflowManager.getStep(instance, flow, t.step);
231
+ // upobj[key_str + "values"] = uuflowManager.getApproveValues(values, step["permissions"], instance.form, instance.form_version)
232
+ approveDoc['values'] = uuflowManager.getApproveValues(values, step["permissions"], instance.form, instance.form_version)
233
+ }
234
+ //设置意见,意见只添加到最后一条approve中
235
+ if (approve_id == a._id) {
236
+ // upobj[key_str + 'description'] = description;
237
+ approveDoc['description'] = description
238
+ }
239
+ for (const key in approveDoc) {
240
+ if (Object.hasOwnProperty.call(approveDoc, key)) {
241
+ upobj[key_str + key] = approveDoc[key]
242
+ }
243
+ }
244
+ db.instances.update({
245
+ _id: ins_id,
246
+ 'traces._id': t._id
247
+ }, {
248
+ $set: upobj
249
+ })
250
+ // 更新
251
+ update_instance_tasks(ins_id, a.trace, a._id, approveDoc)
252
+ is_finished = true;
253
+ }
254
+ }
255
+ }
256
+
257
+ }
258
+
259
+ if (myApprove && is_finished) {
260
+
261
+ setObj.modified = new Date();
262
+ setObj.modified_by = this.userId;
263
+
264
+ if (ccHasEditPermission && myApprove && !myTrace.is_finished) {
265
+ var ins = uuflowManager.getInstance(ins_id);
266
+ var updated_values = uuflowManager.getUpdatedValues(ins, approve_id);
267
+ setObj.values = updated_values;
268
+ setObj.name = uuflowManager.getInstanceName(instance);
269
+ // 计算extras
270
+ var form = db.forms.findOne(instance.form);
271
+ setObj.extras = uuflowManager.caculateExtras(setObj.values, form, instance.form_version);
272
+ }
273
+
274
+ db.instances.update({
275
+ _id: ins_id,
276
+ cc_users: current_user_id
277
+ }, {
278
+ $set: setObj,
279
+ $unset: {
280
+ 'cc_users.$': true
281
+ },
282
+ $addToSet: {
283
+ outbox_users: {
284
+ $each: [current_user_id, myApprove.user]
285
+ }
286
+ }
287
+ });
288
+
289
+ db.instances.update({
290
+ _id: ins_id,
291
+ }, {
292
+ $pull: {
293
+ cc_users: null
294
+ }
295
+ });
296
+
297
+ uuflowManager.updateCCcount(ins_id)
298
+
299
+ instance = db.instances.findOne(ins_id);
300
+
301
+ current_user_info = db.users.findOne(current_user_id);
302
+ //传阅提交不通知传阅者
303
+ if (false && description && myApprove && myApprove.from_user) {
304
+ pushManager.send_instance_notification("trace_approve_cc_submit", instance, "", current_user_info, [myApprove.from_user]);
305
+ }
306
+
307
+ pushManager.send_message_to_specifyUser("current_user", current_user_id);
308
+
309
+ flow_id = instance.flow;
310
+ // 如果已经配置webhook并已激活则触发
311
+ pushManager.triggerWebhook(flow_id, instance, myApprove, 'cc_submit', current_user_id, []);
312
+ }
313
+
314
+ return true;
315
+ },
316
+
317
+ cc_remove: function (instanceId, approveId) {
318
+ var setObj = {};
319
+
320
+ var instance = db.instances.findOne(instanceId, {
321
+ fields: {
322
+ traces: 1,
323
+ cc_users: 1
324
+ }
325
+ });
326
+ var traces = instance.traces;
327
+ var trace_id, remove_user_id, multi = false;
328
+
329
+ traces.forEach(function (t) {
330
+ if (t.approves) {
331
+ t.approves.forEach(function (a, idx) {
332
+ if (a._id == approveId) {
333
+ trace_id = a.trace;
334
+ remove_user_id = a.handler;
335
+ setObj['traces.$.approves.' + idx + '.judge'] = 'terminated';
336
+ setObj['traces.$.approves.' + idx + '.is_finished'] = true;
337
+ setObj['traces.$.approves.' + idx + '.finish_date'] = new Date();
338
+ setObj['traces.$.approves.' + idx + '.is_read'] = true;
339
+ setObj['traces.$.approves.' + idx + '.read_date'] = new Date();
340
+ }
341
+ });
342
+ }
343
+ })
344
+
345
+ if (!trace_id || !remove_user_id)
346
+ return;
347
+
348
+ var multi = 0;
349
+ traces.forEach(function (t) {
350
+ if (t.approves) {
351
+ t.approves.forEach(function (a) {
352
+ if (a.handler == remove_user_id && a.type == 'cc' && a.is_finished == false) {
353
+ multi++;
354
+ }
355
+ });
356
+ }
357
+ })
358
+
359
+ setObj.modified = new Date();
360
+ setObj.modified_by = this.userId;
361
+
362
+ if (multi > 1) {
363
+ db.instances.update({
364
+ _id: instanceId,
365
+ 'traces._id': trace_id
366
+ }, {
367
+ $set: setObj
368
+ });
369
+ } else {
370
+ db.instances.update({
371
+ _id: instanceId,
372
+ 'traces._id': trace_id
373
+ }, {
374
+ $set: setObj,
375
+ $pull: {
376
+ cc_users: remove_user_id
377
+ }
378
+ });
379
+ }
380
+
381
+ uuflowManager.updateCCcount(instanceId)
382
+
383
+ remove_instance_tasks(approveId)
384
+
385
+
386
+ pushManager.send_message_to_specifyUser("current_user", remove_user_id);
387
+ return true;
388
+ },
389
+
390
+ batch_cancel_cc: function (instance_id, approve_ids) {
391
+ check(instance_id, String)
392
+ check(approve_ids, Array)
393
+
394
+ var setObj = {};
395
+
396
+ var instance = db.instances.findOne(instance_id, {
397
+ fields: {
398
+ traces: 1,
399
+ cc_users: 1
400
+ }
401
+ });
402
+ var traces = instance.traces;
403
+ var remove_user_ids = [];
404
+ var removeApproveIds = []
405
+
406
+ traces.forEach(function (t, tIdx) {
407
+ if (t.approves) {
408
+ t.approves.forEach(function (a, idx) {
409
+ if (approve_ids.includes(a._id)) {
410
+ removeApproveIds.push(a._id)
411
+ remove_user_ids.push(a.user);
412
+ setObj['traces.' + tIdx + '.approves.' + idx + '.judge'] = 'terminated';
413
+ setObj['traces.' + tIdx + '.approves.' + idx + '.is_finished'] = true;
414
+ setObj['traces.' + tIdx + '.approves.' + idx + '.finish_date'] = new Date();
415
+ setObj['traces.' + tIdx + '.approves.' + idx + '.is_read'] = true;
416
+ setObj['traces.' + tIdx + '.approves.' + idx + '.read_date'] = new Date();
417
+ }
418
+ });
419
+ }
420
+ })
421
+
422
+ if (_.isEmpty(remove_user_ids))
423
+ return;
424
+
425
+ setObj.modified = new Date();
426
+ setObj.modified_by = this.userId;
427
+
428
+ db.instances.update({
429
+ _id: instance_id
430
+ }, {
431
+ $set: setObj,
432
+ });
433
+ for (const ruId of remove_user_ids) {
434
+ db.instances.update({
435
+ _id: instance_id,
436
+ cc_users: ruId
437
+ }, {
438
+ $unset: {
439
+ 'cc_users.$': true
440
+ }
441
+ });
442
+ }
443
+ db.instances.update({
444
+ _id: instance_id,
445
+ }, {
446
+ $pull: {
447
+ cc_users: null
448
+ }
449
+ });
450
+
451
+ uuflowManager.updateCCcount(instance_id)
452
+
453
+ direct_remove_many_instance_tasks(removeApproveIds)
454
+
455
+ remove_user_ids.forEach(function (u_id) {
456
+ pushManager.send_message_to_specifyUser("current_user", u_id);
457
+ })
458
+ return true;
459
+ },
460
+
461
+ cc_save: function (ins_id, description, myApprove, ccHasEditPermission) {
462
+ var setObj = {};
463
+ const approveDoc = {}
464
+
465
+ var instance = db.instances.findOne(ins_id);
466
+ var traces = instance.traces;
467
+ var current_user_id = this.userId;
468
+
469
+ var trace_id = myApprove.trace;
470
+ var approve_id = myApprove._id;
471
+
472
+ var current_trace = _.find(traces, function (t) {
473
+ return t._id == trace_id;
474
+ });
475
+ var current_approve = _.find(current_trace.approves, function (a) {
476
+ return a._id == approve_id;
477
+ });
478
+
479
+ var myTrace;
480
+
481
+ traces.forEach(function (t) {
482
+ if (t.approves) {
483
+ t.approves.forEach(function (a, idx) {
484
+ if (a.handler == current_user_id && a.type == 'cc' && a.is_finished == false) {
485
+ var upobj = {};
486
+ upobj['traces.$.approves.' + idx + '.judge'] = "submitted";
487
+ upobj['traces.$.approves.' + idx + '.read_date'] = new Date();
488
+ db.instances.update({
489
+ _id: ins_id,
490
+ 'traces._id': t._id
491
+ }, {
492
+ $set: upobj
493
+ })
494
+
495
+ }
496
+ });
497
+ }
498
+ })
499
+
500
+ var index = 0;
501
+ var currentStepId;
502
+
503
+ //设置意见,意见只添加到最后一条approve中
504
+ traces.forEach(function (t) {
505
+ if (myApprove && t._id === myApprove.trace) {
506
+ currentStepId = t.step;
507
+ myTrace = t;
508
+ if (t.approves) {
509
+ t.approves.forEach(function (a, idx) {
510
+ if (a._id === myApprove._id) {
511
+ index = idx;
512
+ }
513
+ });
514
+ }
515
+ }
516
+ });
517
+
518
+ setObj['traces.$.approves.' + index + '.description'] = description;
519
+ approveDoc['description'] = description
520
+
521
+ var updateObj = {};
522
+
523
+ if (ccHasEditPermission && myApprove && !myTrace.is_finished) {
524
+
525
+ var key_str = 'traces.$.approves.' + index + '.';
526
+
527
+ var flow = uuflowManager.getFlow(instance.flow);
528
+
529
+ var step = uuflowManager.getStep(instance, flow, currentStepId);
530
+
531
+ var permissions_values = uuflowManager.getApproveValues(myApprove.values, step.permissions, instance.form, instance.form_version);
532
+
533
+ var change_values = approveManager.getChangeValues(instance.values, permissions_values);
534
+
535
+ setObj.values = _.extend((instance.values || {}), permissions_values);
536
+ // 计算extras
537
+ var form = db.forms.findOne(instance.form);
538
+ setObj.extras = uuflowManager.caculateExtras(setObj.values, form, instance.form_version);
539
+ approveDoc['extras'] = setObj.extras
540
+
541
+ if (!_.isEmpty(change_values)) {
542
+ var pushObj = {};
543
+ pushObj[key_str + 'values_history'] = {
544
+ values: change_values,
545
+ create: new Date()
546
+ }
547
+ updateObj.$push = pushObj;
548
+
549
+ const values_history = current_approve.values_history || []
550
+ values_history.push(pushObj[key_str + 'values_history'])
551
+ approveDoc['values_history'] = values_history
552
+ }
553
+
554
+ setObj.name = uuflowManager.getInstanceName(instance)
555
+ approveDoc['instance_name'] = setObj.name
556
+ }
557
+
558
+ updateObj.$set = setObj;
559
+
560
+ db.instances.update({
561
+ _id: ins_id,
562
+ 'traces._id': myApprove.trace
563
+ }, updateObj);
564
+ update_instance_tasks(ins_id, myApprove.trace, myApprove._id, approveDoc)
565
+ return true;
566
+ }
567
+ */
568
+ }
@@ -288,6 +288,8 @@ actions:
288
288
  label: Flow Designer
289
289
  designForm:
290
290
  label: Form Designer
291
+ design_form_layout:
292
+ label: Form Designer(New)
291
293
  enableFlow:
292
294
  label: Enable Flow
293
295
  disableFlow:
@@ -310,8 +312,25 @@ actions:
310
312
  label: Delete
311
313
  addFormFields:
312
314
  label: Add Fields
315
+ del:
316
+ label: Delete
313
317
  CustomLabels:
314
318
  import_flows_error_title: Import Error
315
319
  import_flows_error_not_find_object: 'Not find object [ %s ]'
316
320
  import_flows_error_not_allow_enable_workflow: 'object [ %s ] not enable workflow'
317
321
  import_flows_error_not_find_fields: 'Missing field [ %s ]'
322
+ flows_action_del_dialog_title: Delete Flow
323
+ flows_action_del_dialog_field_flowName: For security reasons, please enter the name of the flow you want to delete (the relevant application form will also be deleted at the same time).
324
+ flows_action_del_dialog_error_not_same: Please confirm that the entered name is inconsistent with the flow name
325
+ flows_action_del_dialog_message_success: Operation successful
326
+ flows_action_del_dialog_message_failed: Operation failed
327
+ flows_action_distributeAdmin_dialog_error_not_find_step: Please first set the steps that allow distribution in the flow designer's steps
328
+ flows_action_distributeAdmin_dialog_field_distribute_optional_users_id: The selection range of distribution objects when the flow is distributed
329
+ flows_action_distributeAdmin_dialog_field_distribute_to_self: When distributing, you can give it to yourself
330
+ flows_action_distributeAdmin_dialog_field_distribute_end_notification: Remind the initiator after the distribution is completed
331
+ flows_action_distributeAdmin_dialog_field_upload_after_being_distributed: Is it allowed to upload attachments after being distributed
332
+ flows_page_record_field_form_name: Form Name
333
+ flows_page_record_field_form_description: Form Description
334
+ flows_page_record_field_form_name_forumla: Title Formula
335
+ flows_page_record_field_form_script: Form Script
336
+ flows_page_record_action_edit_dialog_title: Edit Form