@steedos-labs/plugin-workflow 3.0.65 → 3.0.67
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-CuWu3LJm.js +990 -0
- package/designer/dist/assets/index-D2CMqwIn.css +1 -0
- package/designer/dist/index.html +2 -2
- package/main/default/client/navigation_guard.client.js +2 -0
- package/main/default/client/socket.client.js +43 -13
- package/main/default/manager/uuflow_manager.js +37 -2
- package/main/default/methods/trace_approve_cc.js +16 -2
- package/main/default/objectTranslations/instances.en/instances.en.objectTranslation.yml +10 -0
- package/main/default/objectTranslations/instances.zh-CN/instances.zh-CN.objectTranslation.yml +10 -0
- package/main/default/objects/flows/flows.object.yml +4 -9
- package/main/default/objects/instance_tasks/buttons/instance_new.button.yml +18 -4
- package/main/default/objects/instances/buttons/instance_hide.button.yml +65 -2
- package/main/default/objects/instances/buttons/instance_reopen.button.yml +65 -3
- package/main/default/objects/instances/buttons/instance_save.button.yml +2 -2
- package/main/default/objects/instances/fields/is_hidden.field.yml +5 -0
- package/main/default/pages/flow_selector.page.amis.json +2 -2
- package/main/default/pages/flow_selector_mobile.page.amis.json +2 -2
- package/main/default/pages/page_instance_print.page.amis.json +103 -34
- package/main/default/routes/api_workflow_ai_form_design.router.js +7 -416
- package/main/default/routes/api_workflow_ai_form_design_stream.router.js +7 -435
- package/main/default/routes/api_workflow_approve_save.router.js +28 -5
- package/main/default/routes/api_workflow_forward.router.js +4 -4
- package/main/default/routes/api_workflow_forward_refill.router.js +1 -1
- package/main/default/routes/api_workflow_instance_forward.router.js +4 -4
- package/main/default/routes/api_workflow_instance_hide.router.js +93 -0
- package/main/default/routes/api_workflow_next_step_users.router.js +17 -2
- package/main/default/routes/buildFormDesignSystemPrompt.js +522 -0
- package/main/default/routes/flow_form_design.ejs +1 -1
- package/main/default/services/instance.service.js +5 -0
- package/main/default/test/test_socket_reconnect.js +105 -0
- package/main/default/utils/designerManager.js +14 -1
- package/main/default/utils/formula-compat.js +10 -1
- 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 +326 -207
- package/src/schema/steedos_form_schema.amis.js +1 -1
- package/designer/dist/assets/index-CFR_MNwA.css +0 -1
- package/designer/dist/assets/index-CdtiiXeP.js +0 -994
|
@@ -203,7 +203,7 @@ router.post("/api/workflow/v2/instance/forward", requireAuthentication, async fu
|
|
|
203
203
|
|
|
204
204
|
// Process select to input fields
|
|
205
205
|
for (const field of select_to_input_fields) {
|
|
206
|
-
if (old_values[field.code]) {
|
|
206
|
+
if (old_values[field.code] != null) {
|
|
207
207
|
new_values[field.code] = old_values[field.code];
|
|
208
208
|
}
|
|
209
209
|
}
|
|
@@ -218,7 +218,7 @@ router.post("/api/workflow/v2/instance/forward", requireAuthentication, async fu
|
|
|
218
218
|
}
|
|
219
219
|
const key = f.code;
|
|
220
220
|
let old_v = old_values[key];
|
|
221
|
-
if (old_v) {
|
|
221
|
+
if (old_v != null) {
|
|
222
222
|
const fieldOptions = _.isArray(f.options) ? f.options : f.options?.split("\n").map(n => {
|
|
223
223
|
const itemSplits = n.split(":");
|
|
224
224
|
return {
|
|
@@ -258,7 +258,7 @@ router.post("/api/workflow/v2/instance/forward", requireAuthentication, async fu
|
|
|
258
258
|
}
|
|
259
259
|
const key = f.code;
|
|
260
260
|
let old_v = old_table_row_values[key];
|
|
261
|
-
if (old_v) {
|
|
261
|
+
if (old_v != null) {
|
|
262
262
|
const fieldOptions = f.options?.split("\n").map(n => {
|
|
263
263
|
const itemSplits = n.split(":");
|
|
264
264
|
return {
|
|
@@ -301,7 +301,7 @@ router.post("/api/workflow/v2/instance/forward", requireAuthentication, async fu
|
|
|
301
301
|
}
|
|
302
302
|
const key = field.code;
|
|
303
303
|
let old_v = old_values[key];
|
|
304
|
-
if (old_v) {
|
|
304
|
+
if (old_v != null) {
|
|
305
305
|
const fieldOptions = _.isArray(field.options) ? field.options : field.options?.split("\n").map(n => {
|
|
306
306
|
const itemSplits = n.split(":");
|
|
307
307
|
return {
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* @Description: 隐藏/显示审批单
|
|
3
|
+
*/
|
|
4
|
+
'use strict';
|
|
5
|
+
const express = require('express');
|
|
6
|
+
const router = express.Router();
|
|
7
|
+
const { requireAuthentication } = require("@steedos/auth");
|
|
8
|
+
const PermissionManager = require('../manager/permission_manager');
|
|
9
|
+
const { getCollection } = require('../utils/collection');
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* 隐藏或显示审批单
|
|
13
|
+
* body {
|
|
14
|
+
* instance_id: string,
|
|
15
|
+
* is_hidden: boolean
|
|
16
|
+
* }
|
|
17
|
+
*/
|
|
18
|
+
router.post('/api/workflow/instance/hide', requireAuthentication, async function (req, res) {
|
|
19
|
+
try {
|
|
20
|
+
const userSession = req.user;
|
|
21
|
+
const userId = userSession.userId;
|
|
22
|
+
const spaceId = userSession.spaceId;
|
|
23
|
+
const { instance_id, is_hidden } = req.body;
|
|
24
|
+
|
|
25
|
+
if (!instance_id) {
|
|
26
|
+
throw new Error("instance_id is required");
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const instancesColl = await getCollection('instances');
|
|
30
|
+
const instance = await instancesColl.findOne(
|
|
31
|
+
{ _id: instance_id },
|
|
32
|
+
{ projection: { state: 1, space: 1, flow: 1, is_hidden: 1 } }
|
|
33
|
+
);
|
|
34
|
+
|
|
35
|
+
if (!instance) {
|
|
36
|
+
throw new Error("未找到申请单");
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
if (instance.state !== 'completed') {
|
|
40
|
+
throw new Error("只能对已完成的申请单执行此操作");
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// 检查权限:space admin 或 flow admin
|
|
44
|
+
const spacesColl = await getCollection('spaces');
|
|
45
|
+
const space = await spacesColl.findOne(
|
|
46
|
+
{ _id: instance.space },
|
|
47
|
+
{ projection: { admins: 1 } }
|
|
48
|
+
);
|
|
49
|
+
|
|
50
|
+
const isSpaceAdmin = space && space.admins && space.admins.includes(userId);
|
|
51
|
+
|
|
52
|
+
let hasFlowAdmin = false;
|
|
53
|
+
if (!isSpaceAdmin) {
|
|
54
|
+
const permissions = await PermissionManager.getFlowPermissions(instance.flow, userId);
|
|
55
|
+
hasFlowAdmin = permissions.includes('admin');
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
if (!isSpaceAdmin && !hasFlowAdmin) {
|
|
59
|
+
throw new Error("无权执行此操作");
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
const now = new Date();
|
|
63
|
+
const setObj = {
|
|
64
|
+
is_hidden: !!is_hidden,
|
|
65
|
+
modified: now,
|
|
66
|
+
modified_by: userId
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
await instancesColl.updateOne(
|
|
70
|
+
{ _id: instance_id },
|
|
71
|
+
{ $set: setObj }
|
|
72
|
+
);
|
|
73
|
+
|
|
74
|
+
// 同步更新 instance_tasks 的 is_hidden
|
|
75
|
+
const instanceTasksColl = await getCollection('instance_tasks');
|
|
76
|
+
await instanceTasksColl.updateMany(
|
|
77
|
+
{ instance: instance_id },
|
|
78
|
+
{ $set: { is_hidden: !!is_hidden, modified: now, modified_by: userId } }
|
|
79
|
+
);
|
|
80
|
+
|
|
81
|
+
res.status(200).json({
|
|
82
|
+
success: true,
|
|
83
|
+
message: is_hidden ? "隐藏审批单成功" : "显示审批单成功"
|
|
84
|
+
});
|
|
85
|
+
} catch (e) {
|
|
86
|
+
console.error('api_workflow_instance_hide error:', e);
|
|
87
|
+
res.status(200).json({
|
|
88
|
+
errors: [{ errorMessage: e.message }]
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
exports.default = router;
|
|
@@ -300,9 +300,24 @@ router.post('/api/workflow/v2/nextStepUsersValue', requireAuthentication, async
|
|
|
300
300
|
newNextUsers = step_approve[nextStepId] || [];
|
|
301
301
|
}
|
|
302
302
|
|
|
303
|
+
// 校验 newNextUsers 中的用户是否存在于 space_users 中
|
|
304
|
+
let uniqueNextUsers = _.isArray(newNextUsers) ? _.uniq(newNextUsers) : [newNextUsers];
|
|
305
|
+
if (uniqueNextUsers.length > 0) {
|
|
306
|
+
const existingUsers = await objectql.getObject('space_users').find({
|
|
307
|
+
filters: [['space', '=', spaceId], ['user', 'in', uniqueNextUsers]],
|
|
308
|
+
fields: ['user']
|
|
309
|
+
});
|
|
310
|
+
const existingUserIds = _.map(existingUsers, 'user');
|
|
311
|
+
const missingUserIds = _.difference(uniqueNextUsers, existingUserIds);
|
|
312
|
+
if (missingUserIds.length > 0) {
|
|
313
|
+
error = `下一步处理人不存在或已离职: ${missingUserIds.join(', ')}`;
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
|
|
303
317
|
res.status(200).send({
|
|
304
|
-
'value':
|
|
305
|
-
'
|
|
318
|
+
'value': uniqueNextUsers,
|
|
319
|
+
'_error': error,
|
|
320
|
+
status: 0
|
|
306
321
|
});
|
|
307
322
|
} catch (error) {
|
|
308
323
|
console.error(error);
|