@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.
Files changed (41) hide show
  1. package/designer/dist/amis-renderer/amis-renderer.css +1 -1
  2. package/designer/dist/amis-renderer/amis-renderer.js +1 -1
  3. package/designer/dist/assets/index-CuWu3LJm.js +990 -0
  4. package/designer/dist/assets/index-D2CMqwIn.css +1 -0
  5. package/designer/dist/index.html +2 -2
  6. package/main/default/client/navigation_guard.client.js +2 -0
  7. package/main/default/client/socket.client.js +43 -13
  8. package/main/default/manager/uuflow_manager.js +37 -2
  9. package/main/default/methods/trace_approve_cc.js +16 -2
  10. package/main/default/objectTranslations/instances.en/instances.en.objectTranslation.yml +10 -0
  11. package/main/default/objectTranslations/instances.zh-CN/instances.zh-CN.objectTranslation.yml +10 -0
  12. package/main/default/objects/flows/flows.object.yml +4 -9
  13. package/main/default/objects/instance_tasks/buttons/instance_new.button.yml +18 -4
  14. package/main/default/objects/instances/buttons/instance_hide.button.yml +65 -2
  15. package/main/default/objects/instances/buttons/instance_reopen.button.yml +65 -3
  16. package/main/default/objects/instances/buttons/instance_save.button.yml +2 -2
  17. package/main/default/objects/instances/fields/is_hidden.field.yml +5 -0
  18. package/main/default/pages/flow_selector.page.amis.json +2 -2
  19. package/main/default/pages/flow_selector_mobile.page.amis.json +2 -2
  20. package/main/default/pages/page_instance_print.page.amis.json +103 -34
  21. package/main/default/routes/api_workflow_ai_form_design.router.js +7 -416
  22. package/main/default/routes/api_workflow_ai_form_design_stream.router.js +7 -435
  23. package/main/default/routes/api_workflow_approve_save.router.js +28 -5
  24. package/main/default/routes/api_workflow_forward.router.js +4 -4
  25. package/main/default/routes/api_workflow_forward_refill.router.js +1 -1
  26. package/main/default/routes/api_workflow_instance_forward.router.js +4 -4
  27. package/main/default/routes/api_workflow_instance_hide.router.js +93 -0
  28. package/main/default/routes/api_workflow_next_step_users.router.js +17 -2
  29. package/main/default/routes/buildFormDesignSystemPrompt.js +522 -0
  30. package/main/default/routes/flow_form_design.ejs +1 -1
  31. package/main/default/services/instance.service.js +5 -0
  32. package/main/default/test/test_socket_reconnect.js +105 -0
  33. package/main/default/utils/designerManager.js +14 -1
  34. package/main/default/utils/formula-compat.js +10 -1
  35. package/package.json +1 -1
  36. package/public/amis-renderer/amis-renderer.css +1 -1
  37. package/public/amis-renderer/amis-renderer.js +1 -1
  38. package/src/instance_record_queue.js +326 -207
  39. package/src/schema/steedos_form_schema.amis.js +1 -1
  40. package/designer/dist/assets/index-CFR_MNwA.css +0 -1
  41. 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': _.isArray(newNextUsers) ? _.uniq(newNextUsers) : newNextUsers,
305
- 'error': error
318
+ 'value': uniqueNextUsers,
319
+ '_error': error,
320
+ status: 0
306
321
  });
307
322
  } catch (error) {
308
323
  console.error(error);