@steedos-labs/plugin-workflow 3.0.0-beta.28 → 3.0.0-beta.30

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.
@@ -0,0 +1,212 @@
1
+ name: instances
2
+ label: Request
3
+ description:
4
+ fields:
5
+ name:
6
+ label: Name
7
+ help:
8
+ description:
9
+ flow:
10
+ label: Workflow
11
+ help:
12
+ description:
13
+ flow_version:
14
+ label: Workflow Version
15
+ help:
16
+ description:
17
+ form:
18
+ label: Form
19
+ help:
20
+ description:
21
+ form_version:
22
+ label: Form Version
23
+ help:
24
+ description:
25
+ submitter:
26
+ label: Submitter
27
+ help:
28
+ description:
29
+ submitter_name:
30
+ label: Submitter's Name
31
+ help:
32
+ description:
33
+ submit_date:
34
+ label: Submit Date
35
+ help:
36
+ description:
37
+ applicant:
38
+ label: Applicant
39
+ help:
40
+ description:
41
+ applicant_name:
42
+ label: Applicant's Name
43
+ help:
44
+ description:
45
+ applicant_organization:
46
+ label: Applicant Department
47
+ help:
48
+ description:
49
+ applicant_organization_name:
50
+ label: Applicant Department's Name
51
+ help:
52
+ description:
53
+ applicant_organization_fullname:
54
+ label: Applicant Department's Fullname
55
+ help:
56
+ description:
57
+ code:
58
+ label: Code
59
+ help:
60
+ description:
61
+ values:
62
+ label: Field Values
63
+ help:
64
+ description:
65
+ inbox_users:
66
+ label: Inbox Users
67
+ help:
68
+ description:
69
+ outbox_users:
70
+ label: Outbox Users
71
+ help:
72
+ description:
73
+ traces:
74
+ label: Processing Traces
75
+ help:
76
+ description:
77
+ attachments:
78
+ label: Attachments
79
+ help:
80
+ description:
81
+ flow_name:
82
+ label: Workflow Name
83
+ help:
84
+ description:
85
+ category_name:
86
+ label: Category Name
87
+ help:
88
+ description:
89
+ category:
90
+ label: Category
91
+ help:
92
+ description:
93
+ state:
94
+ label: Processing State
95
+ help:
96
+ options:
97
+ - label: Draft
98
+ value: draft
99
+ - label: Pending
100
+ value: pending
101
+ - label: Completed
102
+ value: completed
103
+ description:
104
+ is_archived:
105
+ label: Archived
106
+ help:
107
+ description:
108
+ is_deleted:
109
+ label: Deleted
110
+ help:
111
+ description:
112
+ related_instances:
113
+ label: Related Instances
114
+ help:
115
+ description:
116
+ record_ids:
117
+ label: Record IDs
118
+ help:
119
+ description:
120
+ record_ids.$.o:
121
+ label:
122
+ help:
123
+ description:
124
+ record_ids.$.ids:
125
+ label:
126
+ help:
127
+ description:
128
+ current_step_auto_submit:
129
+ label: Auto Submit if Time Out
130
+ help:
131
+ description:
132
+ current_step_name:
133
+ label: Current Step Name
134
+ help:
135
+ description:
136
+ applicant_company:
137
+ label: Applicant's Division
138
+ help:
139
+ description:
140
+ cc_count:
141
+ label: CC Count
142
+ help:
143
+ description:
144
+ listviews:
145
+ all:
146
+ label: All
147
+ inbox:
148
+ label: Inbox
149
+ outbox:
150
+ label: Outbox
151
+ draft:
152
+ label: Draft
153
+ pending:
154
+ label: In Progress
155
+ completed:
156
+ label: Finished
157
+ monitor:
158
+ label: Monitor
159
+ actions:
160
+ view_instance:
161
+ label: View Instance
162
+ instance_terminate:
163
+ label: Cancel Request
164
+ instance_save:
165
+ label: Save
166
+ instance_related:
167
+ label: Linked requests
168
+ instance_distribute:
169
+ label: Distribute
170
+ instance_submit:
171
+ label: Submit
172
+ instance_forward:
173
+ label: Request Forward
174
+ instance_cc:
175
+ label: Carbon Copy
176
+ instance_relocate:
177
+ label: Relocate
178
+ instance_new:
179
+ label: New Request
180
+ instance_delete:
181
+ label: Delete
182
+ instance_delete_many:
183
+ label: Delete
184
+ CustomLabels:
185
+ instance_action_new_dialog_title: Please select the process
186
+ instance_action_new_dialog_msg_success: Created successfully!
187
+ instance_action_new_dialog_msg_failed: Created failed!
188
+ instance_action_delete_many_msg_not_select: Please select at least one record
189
+ instance_action_instance_save_msg_success: Temporary storage successful
190
+ instance_action_instance_save_msg_failed: Temporary storage failed
191
+ instance_action_instance_distribute_dialog_sub_title: Distribute the currently selected file to the new process and continue to execute the approval operation
192
+ instance_action_instance_distribute_dialog_field_process: Process name
193
+ instance_action_instance_distribute_dialog_field_users: Distribute to
194
+ instance_action_instance_distribute_dialog_field_description: Description
195
+ instance_action_instance_distribute_dialog_field_to_self: Distribute it to yourself too
196
+ instance_action_instance_distribute_dialog_field_to_attachment: Save the original form as an attachment
197
+ instance_action_instance_distribute_dialog_field_related: Automatically create associated files
198
+ instance_action_instance_cc_dialog_title_prefix: "Current Step:"
199
+ instance_action_instance_cc_dialog_field_users: Carbon Copy To
200
+ instance_action_instance_cc_dialog_field_description: Carbon Copy Description
201
+ instance_action_instance_cc_dialog_sub_title: Forward the currently selected file to the new process and continue to execute the approval operation.
202
+ instance_action_terminate_dialog_title: Cancel Request
203
+ instance_action_terminate_dialog_content: Please fill in the reasons for canceling the application
204
+ instance_action_terminate_dialog_msg_success: The cancellation application has been successful!
205
+ instance_action_terminate_dialog_msg_failed: The cancellation application failed.
206
+ instance_action_instance_relocate_dialog_title: Relocate
207
+ instance_action_instance_relocate_dialog_title_prefix: "Current Step:"
208
+ instance_action_instance_relocate_dialog_field_reason: Please fill in the reasons for the Relocating
209
+ instance_action_relocate_dialog_msg_success: Relocated successful
210
+ instance_action_relocate_dialog_msg_failed: Relocated failed
211
+ instance_action_instance_save_msg_upgraded: The workflow has been upgraded. The page will refresh automatically.
212
+
@@ -0,0 +1,209 @@
1
+ name: instances
2
+ label: 审批单
3
+ description:
4
+ fields:
5
+ name:
6
+ label: 文件标题
7
+ help:
8
+ description:
9
+ flow:
10
+ label: 流程
11
+ help:
12
+ description:
13
+ flow_version:
14
+ label: 流程版本号
15
+ help:
16
+ description:
17
+ form:
18
+ label: 表单
19
+ help:
20
+ description:
21
+ form_version:
22
+ label: 表单版本号
23
+ help:
24
+ description:
25
+ submitter:
26
+ label: 提交人
27
+ help:
28
+ description:
29
+ submitter_name:
30
+ label: 提交人姓名
31
+ help:
32
+ description:
33
+ submit_date:
34
+ label: 提交日期
35
+ help:
36
+ description:
37
+ applicant:
38
+ label: 申请人
39
+ help:
40
+ description:
41
+ applicant_name:
42
+ label: 申请人姓名
43
+ help:
44
+ description:
45
+ applicant_organization:
46
+ label: 申请人部门
47
+ help:
48
+ description:
49
+ applicant_organization_name:
50
+ label: 申请人部门名称
51
+ help:
52
+ description:
53
+ applicant_organization_fullname:
54
+ label: 申请人部门全称
55
+ help:
56
+ description:
57
+ code:
58
+ label: 公式
59
+ help:
60
+ description:
61
+ values:
62
+ label: 审批单字段
63
+ help:
64
+ description:
65
+ inbox_users:
66
+ label: 待办处理人
67
+ help:
68
+ description:
69
+ outbox_users:
70
+ label: 已办处理人
71
+ help:
72
+ description:
73
+ traces:
74
+ label: 步骤审批
75
+ help:
76
+ description:
77
+ attachments:
78
+ label: 附件
79
+ help:
80
+ description:
81
+ flow_name:
82
+ label: 流程名
83
+ help:
84
+ description:
85
+ category_name:
86
+ label: 流程分类
87
+ help:
88
+ description:
89
+ category:
90
+ label: 流程分类
91
+ help:
92
+ description:
93
+ state:
94
+ label: 审批单状态
95
+ help:
96
+ options:
97
+ - label: 草稿
98
+ value: draft
99
+ - label: 进行中
100
+ value: pending
101
+ - label: 已完成
102
+ value: completed
103
+ description:
104
+ is_archived:
105
+ label: 已归档
106
+ help:
107
+ description:
108
+ is_deleted:
109
+ label: 已删除
110
+ help:
111
+ description:
112
+ related_instances:
113
+ label: 相关审批单
114
+ help:
115
+ description:
116
+ record_ids:
117
+ label: 记录ID
118
+ help:
119
+ description:
120
+ record_ids.$.o:
121
+ label:
122
+ help:
123
+ description:
124
+ record_ids.$.ids:
125
+ label:
126
+ help:
127
+ description:
128
+ current_step_auto_submit:
129
+ label: 当前步骤超时自动流转
130
+ help:
131
+ description:
132
+ current_step_name:
133
+ label: 当前步骤
134
+ help:
135
+ description:
136
+ applicant_company:
137
+ label: 申请人所属分部
138
+ help:
139
+ description:
140
+ cc_count:
141
+ label: 传阅数
142
+ help:
143
+ description:
144
+ listviews:
145
+ all:
146
+ label: 所有
147
+ inbox:
148
+ label: 待办文件
149
+ outbox:
150
+ label: 已办文件
151
+ draft:
152
+ label: 草稿
153
+ pending:
154
+ label: 进行中
155
+ completed:
156
+ label: 已完成
157
+ monitor:
158
+ label: 监控箱
159
+ actions:
160
+ view_instance:
161
+ label: 查看审批单
162
+ instance_terminate:
163
+ label: 取消申请
164
+ instance_save:
165
+ label: 保存
166
+ instance_related:
167
+ label: 关联文件
168
+ instance_distribute:
169
+ label: 分发
170
+ instance_submit:
171
+ label: 发送
172
+ instance_forward:
173
+ label: 转发
174
+ instance_cc:
175
+ label: 传阅
176
+ instance_relocate:
177
+ label: 重定位
178
+ instance_new:
179
+ label: 新建
180
+ instance_delete_many:
181
+ label: 删除
182
+ CustomLabels:
183
+ instance_action_new_dialog_title: 请选择流程
184
+ instance_action_new_dialog_msg_success: 创建成功!
185
+ instance_action_new_dialog_msg_failed: 创建失败!
186
+ instance_action_delete_many_msg_not_select: 请至少选择一条记录
187
+ instance_action_instance_save_msg_success: 暂存成功
188
+ instance_action_instance_save_msg_failed: 暂存失败
189
+ instance_action_instance_distribute_dialog_sub_title: 将当前选中的文件分发到新的流程,继续执行审批操作
190
+ instance_action_instance_distribute_dialog_field_process: 流程名称
191
+ instance_action_instance_distribute_dialog_field_users: 分发对象
192
+ instance_action_instance_distribute_dialog_field_description: 备注
193
+ instance_action_instance_distribute_dialog_field_to_self: 同时分发给自己
194
+ instance_action_instance_distribute_dialog_field_to_attachment: 将原表单存储为附件
195
+ instance_action_instance_distribute_dialog_field_related: 自动创建关联文件
196
+ instance_action_instance_cc_dialog_title_prefix: 当前步骤:
197
+ instance_action_instance_cc_dialog_field_users: 传阅对象
198
+ instance_action_instance_cc_dialog_field_description: 传阅说明
199
+ instance_action_instance_cc_dialog_sub_title: 将当前选中的文件转发到新的流程,继续执行审批操作
200
+ instance_action_terminate_dialog_title: 取消申请
201
+ instance_action_terminate_dialog_content: 请填写取消申请的理由
202
+ instance_action_terminate_dialog_msg_success: 取消申请成功!
203
+ instance_action_terminate_dialog_msg_failed: 取消申请失败
204
+ instance_action_instance_relocate_dialog_title: 重定位
205
+ instance_action_instance_relocate_dialog_title_prefix: 当前步骤:
206
+ instance_action_instance_relocate_dialog_field_reason: 请填写重定位的理由
207
+ instance_action_relocate_dialog_msg_success: 重定位成功
208
+ instance_action_relocate_dialog_msg_failed: 重定位失败
209
+ instance_action_instance_save_msg_upgraded: 流程已升级,页面将自动刷新。
@@ -63,7 +63,8 @@ amis_schema: |-
63
63
  "messages": {},
64
64
  "requestAdaptor": "api.url += api.body.global.spaceId\n\nif (api.body.company_id) {\n api.url += \"&company_id=\" + api.body.company_id\n}\n\nreturn api;",
65
65
  "dataType": "json"
66
- }
66
+ },
67
+ "reload": "listview_flows"
67
68
  }
68
69
  ],
69
70
  "showCloseButton": true,
@@ -18,7 +18,7 @@ amis_schema: |-
18
18
  "title": {
19
19
  "type": "tpl",
20
20
  "id": "u:0bce3c33b6e5",
21
- "tpl": "<p>${'CustomAction.instances.instance_cc' | t}<a href=\"https://www.steedos.cn/docs/user/workflow#%E5%A6%82%E4%BD%95%E4%BC%A0%E9%98%85\" target=\"_blank\" rel=\"noopener\"> ?&nbsp;</a></p>"
21
+ "tpl": "<p>${'CustomAction.instances.instance_cc' | t}</p>"
22
22
  },
23
23
  "body": [
24
24
  {
@@ -18,7 +18,7 @@ amis_schema: |-
18
18
  "method": "post",
19
19
  "sendOn": "",
20
20
  "requestAdaptor": "var _SteedosUI$getRef$get, _approveValues$next_s;\nconst formValues = context._scoped.getComponentById(\"instance_form\").getValues();\nconst approveValues = (_SteedosUI$getRef$get = context._scoped.getComponentById(\"instance_approval\")) === null || _SteedosUI$getRef$get === void 0 ? void 0 : _SteedosUI$getRef$get.getValues();\nlet nextUsers = approveValues === null || approveValues === void 0 ? void 0 : approveValues.next_users;\nif (_.isString(nextUsers)) {\n nextUsers = [approveValues.next_users];\n}\nconst instance = context.record;\nconst body = {\n instance: {\n _id: instance._id,\n applicant: formValues.applicant,\n submitter: formValues.submitter,\n traces: [{\n _id: instance.trace._id,\n step: instance.step._id,\n approves: [{\n _id: instance.approve._id,\n next_steps: [{\n step: approveValues === null || approveValues === void 0 || (_approveValues$next_s = approveValues.next_step) === null || _approveValues$next_s === void 0 ? void 0 : _approveValues$next_s._id,\n users: nextUsers\n }],\n description: approveValues === null || approveValues === void 0 ? void 0 : approveValues.suggestion,\n values: formValues\n }]\n }]\n }\n};\napi.data = body;\nreturn api;",
21
- "adaptor": "return payload.instance === true ? {...payload, status: 0, msg: t('instance_action_instance_save_msg_success')} : {...payload, status: 1, msg: t('instance_action_instance_save_msg_failed')};",
21
+ "adaptor": "if (payload.instance == \"upgraded\") { window.setTimeout(function(){ window.location.reload(); }, 2000); return {...payload, status: 1, msg: t('instance_action_instance_save_msg_upgraded')}; } \n return payload.instance === true ? {...payload, status: 0, msg: t('instance_action_instance_save_msg_success')} : {...payload, status: 1, msg: t('instance_action_instance_save_msg_failed')};",
22
22
  "headers": {
23
23
  "Authorization": "Bearer ${context.tenantId},${context.authToken}"
24
24
  },
@@ -9,7 +9,6 @@ columns:
9
9
  - flow_name
10
10
  - current_step_name
11
11
  - modified
12
- - is_archived
13
12
  mobile_columns:
14
13
  - name
15
14
  - flow_name
@@ -1,15 +1,15 @@
1
1
  /*
2
2
  * @Author: baozhoutao@steedos.com
3
3
  * @Date: 2022-09-15 13:09:51
4
- * @LastEditors: baozhoutao@steedos.com
5
- * @LastEditTime: 2023-02-07 18:12:15
4
+ * @LastEditors: 孙浩林 sunhaolin@steedos.com
5
+ * @LastEditTime: 2025-10-03 15:11:56
6
6
  * @Description:
7
7
  */
8
8
  const express = require("express");
9
9
  const router = express.Router();
10
10
  const { requireAuthentication } = require("@steedos/auth");
11
11
  const objectql = require('@steedos/objectql')
12
- const _ = require('lodash');
12
+ const { cc_do } = require('../methods/trace_approve_cc');
13
13
 
14
14
  router.post('/api/workflow/v2/cc_do', requireAuthentication, async function (req, res) {
15
15
  try {
@@ -17,15 +17,8 @@ router.post('/api/workflow/v2/cc_do', requireAuthentication, async function (req
17
17
  const { instanceId, traceId, approveId, usersId, description } = req.body;
18
18
  const approve = await objectql.getSteedosSchema().broker.call('instance.getApprove', {instanceId, traceId, approveId})
19
19
  try {
20
- Meteor.call('cc_do', approve, usersId, description, {userId: userSession.userId}, (error, result)=>{
21
- if(error){
22
- res.status(200).send({
23
- error: error.message
24
- });
25
- }else{
26
- res.status(200).send(result);
27
- }
28
- })
20
+ const result = await cc_do(approve, usersId, description, {userId: userSession.userId})
21
+ res.status(200).send(result);
29
22
  } catch (error) {
30
23
  console.error(error);
31
24
  res.status(200).send({
@@ -8,34 +8,91 @@
8
8
  const express = require("express");
9
9
  const router = express.Router();
10
10
  const { requireAuthentication } = require("@steedos/auth");
11
- const objectql = require('@steedos/objectql')
11
+ const { getCollection } = require('../utils/collection');
12
12
  const _ = require('lodash');
13
- const Fiber = function(fun){console.log('TODO Fiber...')}
14
13
 
15
- router.get('/api/workflow/v2/get_object_workflows', requireAuthentication, async function (req, res) {
16
- try {
17
- let userSession = req.user;
18
- const { spaceId, userId } = userSession;
19
- Fiber(async function () {
20
- try {
21
- Meteor.call('object_workflows.get', spaceId, userId, (error, result)=>{
22
- if(error){
23
- res.status(200).send({
24
- error: error.message
14
+ async function getObjectWorkflows(spaceId, userId) {
15
+ // 参数检查
16
+ if (typeof spaceId !== 'string') {
17
+ throw new Error('spaceId must be a string');
18
+ }
19
+ if (typeof userId !== 'string') {
20
+ throw new Error('userId must be a string');
21
+ }
22
+
23
+ // 获取space_users集合
24
+ const spaceUsersCollection = await getCollection('space_users');
25
+ const curSpaceUser = await spaceUsersCollection.findOne(
26
+ { space: spaceId, user: userId },
27
+ { projection: { organizations: 1 } }
28
+ );
29
+
30
+ if (!curSpaceUser) {
31
+ throw new Error('not-authorized');
32
+ }
33
+
34
+ // 获取organizations集合
35
+ const organizationsCollection = await getCollection('organizations');
36
+ const organizations = await organizationsCollection.find({
37
+ _id: {
38
+ $in: curSpaceUser.organizations
39
+ }
40
+ }, { projection: { parents: 1 } }).toArray();
41
+
42
+ // 获取object_workflows集合
43
+ const objectWorkflowsCollection = await getCollection('object_workflows');
44
+ let ows = await objectWorkflowsCollection.find(
45
+ { space: spaceId },
46
+ { projection: { object_name: 1, flow_id: 1, space: 1, sync_direction: 1 } }
47
+ ).toArray();
48
+
49
+ // 获取flows集合
50
+ const flowsCollection = await getCollection('flows');
51
+
52
+ // 使用Promise.all并行处理每个工作流
53
+ ows = await Promise.all(ows.map(async (o) => {
54
+ const fl = await flowsCollection.findOne(
55
+ { _id: o.flow_id, state: 'enabled' },
56
+ { projection: { name: 1, perms: 1, forbid_initiate_instance: 1 } }
57
+ );
58
+
59
+ if (fl) {
60
+ o.flow_name = fl.name;
61
+ o.can_add = false;
62
+ o.forbid_initiate_instance = fl.forbid_initiate_instance;
63
+
64
+ const perms = fl.perms;
65
+ if (perms) {
66
+ if (perms.users_can_add && perms.users_can_add.includes(userId)) {
67
+ o.can_add = true;
68
+ } else if (perms.orgs_can_add && perms.orgs_can_add.length > 0) {
69
+ if (curSpaceUser && curSpaceUser.organizations &&
70
+ _.intersection(curSpaceUser.organizations, perms.orgs_can_add).length > 0) {
71
+ o.can_add = true;
72
+ } else if (organizations) {
73
+ o.can_add = _.some(organizations, (org) => {
74
+ return org.parents && _.intersection(org.parents, perms.orgs_can_add).length > 0;
25
75
  });
26
- }else{
27
- res.status(200).send(result);
28
76
  }
29
- })
30
- } catch (error) {
31
- console.error(error);
32
- res.status(200).send({
33
- error: error.message
34
- });
77
+ }
35
78
  }
79
+ }
80
+ return o;
81
+ }));
36
82
 
37
- }).run()
38
-
83
+ // 过滤掉没有flow_name的工作流
84
+ ows = ows.filter(n => n.flow_name);
85
+
86
+ return ows;
87
+ }
88
+
89
+
90
+ router.get('/api/workflow/v2/get_object_workflows', requireAuthentication, async function (req, res) {
91
+ try {
92
+ let userSession = req.user;
93
+ const { spaceId, userId } = userSession;
94
+ const result = await getObjectWorkflows(spaceId, userId);
95
+ return res.status(200).send(result);
39
96
  } catch (error) {
40
97
  console.error(error);
41
98
  res.status(200).send({
@@ -9,34 +9,33 @@ const express = require("express");
9
9
  const router = express.Router();
10
10
  const { requireAuthentication } = require("@steedos/auth");
11
11
  const _ = require('lodash');
12
- const Fiber = function(fun){console.log('TODO Fiber...')}
13
-
12
+ const uuflowManagerForInitApproval = require('../manager/uuflowManagerForInitApproval');
13
+ const { getCollection } = require('../utils/collection');
14
14
  router.post('/api/object/workflow/drafts', requireAuthentication, async function (req, res) {
15
15
  try {
16
16
  let userSession = req.user;
17
17
  const { Instances } = req.body;
18
18
  const userId = userSession.userId;
19
19
  const inserted_instances = [];
20
- Fiber(function () {
21
- try {
22
- _.each(Instances, (instance_from_client)=>{
23
- const new_ins_id = uuflowManagerForInitApproval.create_instance(instance_from_client, Object.assign({}, userSession, {_id: userSession.userId}))
20
+ const coll = await getCollection('instances');
21
+ try {
22
+ for (const instance_from_client of Instances) {
23
+ const new_ins_id = await uuflowManagerForInitApproval.create_instance(instance_from_client, Object.assign({}, userSession, {_id: userSession.userId}))
24
24
 
25
- new_ins = Creator.Collections.instances.findOne({ _id: new_ins_id }, { fields: { space: 1, flow: 1, flow_version: 1, form: 1, form_version: 1 } })
25
+ new_ins = await coll.findOne({ _id: new_ins_id }, { fields: { space: 1, flow: 1, flow_version: 1, form: 1, form_version: 1 } })
26
26
 
27
- inserted_instances.push(new_ins)
28
- })
29
- res.status(200).send({
30
- inserts: inserted_instances
31
- });
32
- } catch (error) {
33
- console.error(error);
34
- res.status(200).send({
35
- error: error.message
36
- });
27
+ inserted_instances.push(new_ins)
37
28
  }
38
-
39
- }).run()
29
+
30
+ res.status(200).send({
31
+ inserts: inserted_instances
32
+ });
33
+ } catch (error) {
34
+ console.error(error);
35
+ res.status(200).send({
36
+ error: error.message
37
+ });
38
+ }
40
39
 
41
40
  } catch (error) {
42
41
  console.error(error);