@steedos-labs/plugin-workflow 3.0.59 → 3.0.61
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/designer/dist/amis-renderer/amis-renderer.css +1 -1
- package/designer/dist/amis-renderer/amis-renderer.js +1 -1
- package/designer/dist/assets/{index-0cQynRDB.js → index-CugibT25.js} +220 -180
- package/designer/dist/assets/index-DIAKZCeb.css +1 -0
- package/designer/dist/index.html +2 -2
- package/main/default/manager/instance_tasks_manager.js +36 -32
- package/main/default/manager/push_manager.js +63 -63
- package/main/default/manager/uuflowManagerForInitApproval.js +192 -98
- package/main/default/manager/uuflow_manager.js +35 -32
- package/main/default/objectTranslations/instances.en/instances.en.objectTranslation.yml +9 -0
- package/main/default/objectTranslations/instances.zh-CN/instances.zh-CN.objectTranslation.yml +9 -0
- package/main/default/objects/instance_tasks/buttons/instance_new.button.yml +1 -1
- package/main/default/objects/instances/buttons/instance_export.button.js +1 -6
- package/main/default/objects/instances/buttons/instance_export.button.yml +12 -9
- package/main/default/objects/instances/buttons/instance_relocate.button.yml +1 -0
- package/main/default/objects/instances/listviews/monitor.listview.yml +13 -0
- package/main/default/objects/instances/listviews/outbox.listview.yml +36 -0
- package/main/default/routes/api_workflow_instance_terminate.router.js +26 -27
- package/main/default/routes/api_workflow_nav.router.js +13 -12
- package/main/default/routes/api_workflow_reassign.router.js +20 -17
- package/main/default/routes/api_workflow_redirect.router.js +11 -1
- package/main/default/routes/api_workflow_relocate.router.js +9 -4
- package/package.json +1 -1
- package/public/amis-renderer/amis-renderer.css +1 -1
- package/public/amis-renderer/amis-renderer.js +1 -1
- package/src/instance_record_queue.js +231 -27
- package/src/rests/badgeRecalcExecute.js +7 -11
- package/designer/dist/assets/index-DEEcIiu0.css +0 -1
|
@@ -23,6 +23,19 @@ filters: !!js/function |
|
|
|
23
23
|
});
|
|
24
24
|
return result.filter;
|
|
25
25
|
}
|
|
26
|
+
requestAdaptor: |-
|
|
27
|
+
var searchFlow = selfData.__searchable__flow;
|
|
28
|
+
var flowIds = [];
|
|
29
|
+
if (searchFlow) {
|
|
30
|
+
flowIds = Array.isArray(searchFlow) ? searchFlow.slice() : [searchFlow];
|
|
31
|
+
}
|
|
32
|
+
flowIds = flowIds.filter(function(id) { return !!id; });
|
|
33
|
+
try {
|
|
34
|
+
window.postMessage({
|
|
35
|
+
type: 'page.dataProvider.setData',
|
|
36
|
+
data: { monitorExportFlowIds: flowIds.length > 0 ? flowIds : '' }
|
|
37
|
+
}, '*');
|
|
38
|
+
} catch(e) {}
|
|
26
39
|
sort: [['submit_date','desc']]
|
|
27
40
|
searchable_fields:
|
|
28
41
|
- field: flow
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
name: outbox
|
|
2
|
+
label: 已审批
|
|
3
|
+
columns:
|
|
4
|
+
- field: name
|
|
5
|
+
wrap: true
|
|
6
|
+
width: 300
|
|
7
|
+
- submitter_name
|
|
8
|
+
- submit_date
|
|
9
|
+
- flow_name
|
|
10
|
+
- current_step_name
|
|
11
|
+
- modified
|
|
12
|
+
mobile_columns:
|
|
13
|
+
- name
|
|
14
|
+
- flow_name
|
|
15
|
+
- current_step_name
|
|
16
|
+
- submitter_name
|
|
17
|
+
- modified
|
|
18
|
+
filter_scope: space
|
|
19
|
+
filters: !!js/function |
|
|
20
|
+
function(filters, data){
|
|
21
|
+
var result = Steedos.authRequest(`/api/workflow/v2/\${data.listName}/filter?app=\${data.appId}&additionalFilters=\${data.additionalFilters || ""}`, {
|
|
22
|
+
type: 'get', async: false
|
|
23
|
+
});
|
|
24
|
+
return result.filter;
|
|
25
|
+
}
|
|
26
|
+
sort: [['modified','desc']]
|
|
27
|
+
searchable_fields:
|
|
28
|
+
- field: flow
|
|
29
|
+
- field: name
|
|
30
|
+
- field: submitter_name
|
|
31
|
+
- field: applicant_organization_name
|
|
32
|
+
- field: submit_date
|
|
33
|
+
- field: instance_state
|
|
34
|
+
extra_columns:
|
|
35
|
+
- extras
|
|
36
|
+
disableSwitch: true
|
|
@@ -24,7 +24,7 @@ router.post("/api/workflow/v2/instance/terminate", requireAuthentication, async
|
|
|
24
24
|
try {
|
|
25
25
|
const userSession = req.user;
|
|
26
26
|
const { terminate_reason, instance_id } = req.body;
|
|
27
|
-
|
|
27
|
+
|
|
28
28
|
if (!terminate_reason) {
|
|
29
29
|
throw new Error("还未填写强制结束申请单的理由,操作失败");
|
|
30
30
|
}
|
|
@@ -67,9 +67,9 @@ router.post("/api/workflow/v2/instance/terminate", requireAuthentication, async
|
|
|
67
67
|
|
|
68
68
|
// Check permissions
|
|
69
69
|
const permissions = await PermissionManager.getFlowPermissions(flow_id, current_user);
|
|
70
|
-
const hasPermission = permissions.includes("admin") ||
|
|
71
|
-
space.admins.includes(current_user) ||
|
|
72
|
-
instance.submitter === current_user ||
|
|
70
|
+
const hasPermission = permissions.includes("admin") ||
|
|
71
|
+
space.admins.includes(current_user) ||
|
|
72
|
+
instance.submitter === current_user ||
|
|
73
73
|
instance.applicant === current_user;
|
|
74
74
|
if (!hasPermission) {
|
|
75
75
|
throw new Error("无权终止此申请单");
|
|
@@ -147,7 +147,7 @@ router.post("/api/workflow/v2/instance/terminate", requireAuthentication, async
|
|
|
147
147
|
const old_inbox_users = instance.inbox_users || [];
|
|
148
148
|
const old_cc_users = instance.cc_users || [];
|
|
149
149
|
const old_outbox_users = instance.outbox_users || [];
|
|
150
|
-
|
|
150
|
+
|
|
151
151
|
const tempUsers = [];
|
|
152
152
|
instance_trace.approves.forEach(approve => {
|
|
153
153
|
tempUsers.push(approve.user);
|
|
@@ -167,6 +167,7 @@ router.post("/api/workflow/v2/instance/terminate", requireAuthentication, async
|
|
|
167
167
|
|
|
168
168
|
// Update instance
|
|
169
169
|
const instancesCollection = await getCollection('instances');
|
|
170
|
+
|
|
170
171
|
const result = await instancesCollection.updateOne(
|
|
171
172
|
{ _id: instance_id },
|
|
172
173
|
{ $set: setObj }
|
|
@@ -178,30 +179,28 @@ router.post("/api/workflow/v2/instance/terminate", requireAuthentication, async
|
|
|
178
179
|
|
|
179
180
|
// Send notifications
|
|
180
181
|
const updatedInstance = await UUFlowManager.getInstance(instance_id);
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
updatedInstance,
|
|
184
|
-
terminate_reason,
|
|
185
|
-
current_user_info
|
|
186
|
-
);
|
|
187
|
-
|
|
188
|
-
// Notify all involved users
|
|
182
|
+
|
|
183
|
+
// Send notifications + webhook (并行)
|
|
189
184
|
const usersToNotify = _.uniq([...old_inbox_users, ...old_cc_users]);
|
|
190
|
-
await Promise.all(
|
|
191
|
-
|
|
185
|
+
await Promise.all([
|
|
186
|
+
pushManager.send_instance_notification(
|
|
187
|
+
"submit_terminate_applicant",
|
|
188
|
+
updatedInstance,
|
|
189
|
+
terminate_reason,
|
|
190
|
+
current_user_info
|
|
191
|
+
),
|
|
192
|
+
...usersToNotify.map(user_id =>
|
|
192
193
|
pushManager.send_message_to_specifyUser("terminate_approval", user_id)
|
|
194
|
+
),
|
|
195
|
+
pushManager.triggerWebhook(
|
|
196
|
+
updatedInstance.flow,
|
|
197
|
+
updatedInstance,
|
|
198
|
+
{},
|
|
199
|
+
"terminate",
|
|
200
|
+
current_user,
|
|
201
|
+
[]
|
|
193
202
|
)
|
|
194
|
-
);
|
|
195
|
-
|
|
196
|
-
// Trigger webhook
|
|
197
|
-
await pushManager.triggerWebhook(
|
|
198
|
-
updatedInstance.flow,
|
|
199
|
-
updatedInstance,
|
|
200
|
-
{},
|
|
201
|
-
"terminate",
|
|
202
|
-
current_user,
|
|
203
|
-
[]
|
|
204
|
-
);
|
|
203
|
+
]);
|
|
205
204
|
}
|
|
206
205
|
|
|
207
206
|
res.status(200).send({});
|
|
@@ -213,4 +212,4 @@ router.post("/api/workflow/v2/instance/terminate", requireAuthentication, async
|
|
|
213
212
|
}
|
|
214
213
|
});
|
|
215
214
|
|
|
216
|
-
exports.default = router;
|
|
215
|
+
exports.default = router;
|
|
@@ -329,18 +329,19 @@ router.get('/api/:appId/workflow/nav', requireAuthentication, async function (re
|
|
|
329
329
|
"icon": "fa fa-check"
|
|
330
330
|
});
|
|
331
331
|
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
"
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
332
|
+
if (monitorResult.hasFlowsPer) {
|
|
333
|
+
options.push({
|
|
334
|
+
"label": t('monitor', {}, userSession.language),
|
|
335
|
+
"icon": "fa fa-eye",
|
|
336
|
+
"options":{
|
|
337
|
+
"level":1,
|
|
338
|
+
"to": `/app/${appId}/instances/view/none?side_object=instances&side_listview_id=monitor&additionalFilters=`,
|
|
339
|
+
},
|
|
340
|
+
"value": `/app/${appId}/instances/view/none?side_object=instances&side_listview_id=monitor&additionalFilters=`,
|
|
341
|
+
"children": monitorResult.schema,
|
|
342
|
+
"unfolded": monitorResult.monitorIsUnfolded
|
|
343
|
+
});
|
|
344
|
+
}
|
|
344
345
|
|
|
345
346
|
const myfileChildren = [];
|
|
346
347
|
if (!isWorkflowReadonly) {
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* @Date: 2022-12-24 14:38:27
|
|
4
4
|
* @LastEditors: 孙浩林 sunhaolin@steedos.com
|
|
5
5
|
* @LastEditTime: 2025-10-08 14:50:07
|
|
6
|
-
* @Description:
|
|
6
|
+
* @Description:
|
|
7
7
|
*/
|
|
8
8
|
'use strict';
|
|
9
9
|
// @ts-check
|
|
@@ -49,10 +49,12 @@ router.post('/api/workflow/reassign', requireAuthentication, async function (req
|
|
|
49
49
|
const spaceUsersCollection = await getCollection('space_users');
|
|
50
50
|
const organizationsCollection = await getCollection('organizations');
|
|
51
51
|
|
|
52
|
-
for (const instance_from_client of hashData['Instances']) {
|
|
52
|
+
for (const instance_from_client of hashData['Instances']) {
|
|
53
53
|
var _users, approve_users_handlers, assignee_appr, current_space_user, current_user_organization, i, inbox_users, inbox_users_from_client, ins, instance, instance_id, last_trace, last_trace_from_client, new_inbox_users, not_in_inbox_users, now, permissions, r, reassign_reason, setObj, space, space_id;
|
|
54
54
|
instance_id = instance_from_client['_id'];
|
|
55
|
+
|
|
55
56
|
instance = await UUFlowManager.getInstance(instance_id);
|
|
57
|
+
|
|
56
58
|
space_id = instance.space;
|
|
57
59
|
// 验证instance为审核中状态
|
|
58
60
|
await UUFlowManager.isInstancePending(instance);
|
|
@@ -66,7 +68,7 @@ router.post('/api/workflow/reassign', requireAuthentication, async function (req
|
|
|
66
68
|
}
|
|
67
69
|
// 验证login user_id对该流程有管理申请单的权限
|
|
68
70
|
permissions = await PermissionManager.getFlowPermissions(instance.flow, current_user);
|
|
69
|
-
|
|
71
|
+
|
|
70
72
|
if ((!permissions.includes("admin")) && !is_space_admin) {
|
|
71
73
|
throw new Error("用户没有对当前流程的管理权限");
|
|
72
74
|
}
|
|
@@ -191,6 +193,7 @@ router.post('/api/workflow/reassign', requireAuthentication, async function (req
|
|
|
191
193
|
last_trace.approves.push(new_appr);
|
|
192
194
|
newApproveIds.push(new_appr._id)
|
|
193
195
|
};
|
|
196
|
+
|
|
194
197
|
instance.outbox_users.push(current_user);
|
|
195
198
|
instance.outbox_users = instance.outbox_users.concat(approve_users_handlers);
|
|
196
199
|
setObj.outbox_users = _.uniq(instance.outbox_users);
|
|
@@ -213,25 +216,25 @@ router.post('/api/workflow/reassign', requireAuthentication, async function (req
|
|
|
213
216
|
|
|
214
217
|
if (r) {
|
|
215
218
|
ins = await UUFlowManager.getInstance(instance_id);
|
|
216
|
-
|
|
217
|
-
await pushManager.send_message_current_user(current_user_info);
|
|
218
|
-
for (const user_id of not_in_inbox_users) {
|
|
219
|
-
if (user_id !== current_user) {
|
|
220
|
-
await pushManager.send_message_to_specifyUser("current_user", user_id);
|
|
221
|
-
}
|
|
222
|
-
};
|
|
219
|
+
|
|
223
220
|
// 提取instances.outbox_users数组和填单人、申请人
|
|
224
221
|
_users = new Array;
|
|
225
222
|
_users.push(ins.applicant);
|
|
226
223
|
_users.push(ins.submitter);
|
|
227
224
|
_users = _.uniq(_users.concat(ins.outbox_users));
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
225
|
+
|
|
226
|
+
// 所有通知+webhook 并行
|
|
227
|
+
await Promise.all([
|
|
228
|
+
pushManager.send_message_current_user(current_user_info),
|
|
229
|
+
...not_in_inbox_users
|
|
230
|
+
.filter(user_id => user_id !== current_user)
|
|
231
|
+
.map(user_id => pushManager.send_message_to_specifyUser("current_user", user_id)),
|
|
232
|
+
..._users.map(user_id =>
|
|
233
|
+
pushManager.send_message_to_specifyUser("current_user", user_id)
|
|
234
|
+
),
|
|
235
|
+
pushManager.send_instance_notification("reassign_new_inbox_users", ins, reassign_reason, current_user_info),
|
|
236
|
+
pushManager.triggerWebhook(ins.flow, ins, {}, 'reassign', current_user, ins.inbox_users)
|
|
237
|
+
]);
|
|
235
238
|
}
|
|
236
239
|
};
|
|
237
240
|
|
|
@@ -30,7 +30,17 @@ router.get('/api/workflow/instances/redirect/:insId', requireAuthentication, asy
|
|
|
30
30
|
if(ins.submitter === userId){
|
|
31
31
|
redirectUrl = `/app/approve_workflow/instances/view/${insId}?side_object=instance_tasks&side_listview_id=${ins.state === 'completed' ? 'completed' : 'pending'}`
|
|
32
32
|
}else{
|
|
33
|
-
|
|
33
|
+
const tasks2 = await db.instance_tasks.find({
|
|
34
|
+
instance: insId,
|
|
35
|
+
is_finished: true,
|
|
36
|
+
handler: userId,
|
|
37
|
+
space: spaceId
|
|
38
|
+
}, {_id: 1}).toArray();
|
|
39
|
+
if(tasks2.length > 0){
|
|
40
|
+
redirectUrl = `/app/approve_workflow/instance_tasks/view/${tasks2[0]._id}?side_object=instance_tasks&side_listview_id=outbox`
|
|
41
|
+
}else{
|
|
42
|
+
redirectUrl = `/app/approve_workflow/instances/view/${insId}?side_object=instance_tasks&side_listview_id=outbox`
|
|
43
|
+
}
|
|
34
44
|
}
|
|
35
45
|
}
|
|
36
46
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/*
|
|
2
|
-
* @Author: sunhaolin@hotoa.com
|
|
3
|
-
* @Date: 2022-03-26 10:49:51
|
|
2
|
+
* @Author: sunhaolin@hotoa.com
|
|
3
|
+
* @Date: 2022-03-26 10:49:51
|
|
4
4
|
* @Last Modified by: sunhaolin@hotoa.com
|
|
5
5
|
* @Last Modified time: 2022-03-26 10:53:33
|
|
6
6
|
*/
|
|
@@ -18,7 +18,7 @@ const afterHook = require('./afterHook');
|
|
|
18
18
|
* body {
|
|
19
19
|
* Instances: [
|
|
20
20
|
* {
|
|
21
|
-
*
|
|
21
|
+
*
|
|
22
22
|
* }
|
|
23
23
|
* ]
|
|
24
24
|
* }
|
|
@@ -35,9 +35,12 @@ router.post('/api/workflow/relocate', requireAuthentication, afterHook, async fu
|
|
|
35
35
|
const instance_from_client = hashData['Instances'][0];
|
|
36
36
|
// beforeEnd
|
|
37
37
|
const insId = instance_from_client._id;
|
|
38
|
+
|
|
38
39
|
const instanceDoc = (await objectql.getObject('instances').find({ filters: [['_id', '=', insId]], fields: ['flow', 'flow_version'] }))[0];
|
|
40
|
+
|
|
39
41
|
const flowId = instanceDoc.flow;
|
|
40
42
|
const flowDoc = await objectql.getObject('flows').findOne(flowId);
|
|
43
|
+
|
|
41
44
|
const next_step_id = instance_from_client["relocate_next_step"];
|
|
42
45
|
const next_step = getStep(instanceDoc, flowDoc, next_step_id);
|
|
43
46
|
const next_step_type = next_step["step_type"];
|
|
@@ -46,10 +49,12 @@ router.post('/api/workflow/relocate', requireAuthentication, afterHook, async fu
|
|
|
46
49
|
}
|
|
47
50
|
|
|
48
51
|
await UUFlowManager.relocate(instance_from_client, userSession)
|
|
52
|
+
|
|
49
53
|
// afterEnd
|
|
50
54
|
if (next_step_type === 'end') {
|
|
51
55
|
await excuteTriggers({ when: 'afterEnd', userId, flowId, insId });
|
|
52
56
|
}
|
|
57
|
+
|
|
53
58
|
res.status(200).send({});
|
|
54
59
|
|
|
55
60
|
} catch (e) {
|
|
@@ -58,4 +63,4 @@ router.post('/api/workflow/relocate', requireAuthentication, afterHook, async fu
|
|
|
58
63
|
});
|
|
59
64
|
}
|
|
60
65
|
});
|
|
61
|
-
exports.default = router;
|
|
66
|
+
exports.default = router;
|