@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
|
@@ -100,45 +100,115 @@ const getFieldOdataValue = async (objName, id, referenceToFieldName) => {
|
|
|
100
100
|
return;
|
|
101
101
|
};
|
|
102
102
|
|
|
103
|
-
const getSelectUserValue = (userId, spaceId) => {
|
|
104
|
-
const
|
|
105
|
-
su
|
|
106
|
-
|
|
103
|
+
const getSelectUserValue = async (userId, spaceId) => {
|
|
104
|
+
const coll = await getCollection('space_users');
|
|
105
|
+
const su = await coll.findOne({ space: spaceId, user: userId });
|
|
106
|
+
if (su) {
|
|
107
|
+
su.id = userId;
|
|
108
|
+
return su;
|
|
109
|
+
}
|
|
110
|
+
return null;
|
|
107
111
|
};
|
|
108
112
|
|
|
109
|
-
const getSelectUserValues = (userIds, spaceId) => {
|
|
113
|
+
const getSelectUserValues = async (userIds, spaceId) => {
|
|
110
114
|
const sus = [];
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
115
|
+
|
|
116
|
+
// 处理多种输入格式
|
|
117
|
+
if (!userIds) {
|
|
118
|
+
return sus;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
let idArray = [];
|
|
122
|
+
if (typeof userIds === 'string') {
|
|
123
|
+
// 字符串:单个 ID 或逗号分隔的 ID 列表
|
|
124
|
+
idArray = userIds.includes(',')
|
|
125
|
+
? userIds.split(',').map(id => id.trim()).filter(id => id)
|
|
126
|
+
: [userIds];
|
|
127
|
+
} else if (Array.isArray(userIds)) {
|
|
128
|
+
// 数组:可能是字符串数组或对象数组
|
|
129
|
+
idArray = userIds.map(item => {
|
|
130
|
+
if (typeof item === 'string') {
|
|
131
|
+
return item.trim();
|
|
132
|
+
} else if (typeof item === 'object' && item !== null) {
|
|
133
|
+
// 对象格式:{id, ...} 或 {_id, ...} 或 {user, ...}
|
|
134
|
+
return item.id || item._id || item.user;
|
|
116
135
|
}
|
|
117
|
-
|
|
136
|
+
return null;
|
|
137
|
+
}).filter(id => id);
|
|
138
|
+
} else if (typeof userIds === 'object' && userIds !== null) {
|
|
139
|
+
// 单个对象:{id, ...}
|
|
140
|
+
const userId = userIds.id || userIds._id || userIds.user;
|
|
141
|
+
if (userId) {
|
|
142
|
+
idArray = [userId];
|
|
143
|
+
}
|
|
118
144
|
}
|
|
145
|
+
|
|
146
|
+
// 获取用户详细信息
|
|
147
|
+
for (const userId of idArray) {
|
|
148
|
+
const su = await getSelectUserValue(userId, spaceId);
|
|
149
|
+
if (su) {
|
|
150
|
+
sus.push(su);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
119
154
|
return sus;
|
|
120
155
|
};
|
|
121
156
|
|
|
122
|
-
const getSelectOrgValue = (orgId, spaceId) => {
|
|
123
|
-
const
|
|
124
|
-
org
|
|
125
|
-
|
|
157
|
+
const getSelectOrgValue = async (orgId, spaceId) => {
|
|
158
|
+
const coll = await getCollection('organizations');
|
|
159
|
+
const org = await coll.findOne(orgId, { fields: { _id: 1, name: 1, fullname: 1 } });
|
|
160
|
+
if (org) {
|
|
161
|
+
org.id = orgId;
|
|
162
|
+
return org;
|
|
163
|
+
}
|
|
164
|
+
return null;
|
|
126
165
|
};
|
|
127
166
|
|
|
128
|
-
const getSelectOrgValues = (orgIds, spaceId) => {
|
|
167
|
+
const getSelectOrgValues = async (orgIds, spaceId) => {
|
|
129
168
|
const orgs = [];
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
169
|
+
|
|
170
|
+
// 处理多种输入格式
|
|
171
|
+
if (!orgIds) {
|
|
172
|
+
return orgs;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
let idArray = [];
|
|
176
|
+
if (typeof orgIds === 'string') {
|
|
177
|
+
// 字符串:单个 ID 或逗号分隔的 ID 列表
|
|
178
|
+
idArray = orgIds.includes(',')
|
|
179
|
+
? orgIds.split(',').map(id => id.trim()).filter(id => id)
|
|
180
|
+
: [orgIds];
|
|
181
|
+
} else if (Array.isArray(orgIds)) {
|
|
182
|
+
// 数组:可能是字符串数组或对象数组
|
|
183
|
+
idArray = orgIds.map(item => {
|
|
184
|
+
if (typeof item === 'string') {
|
|
185
|
+
return item.trim();
|
|
186
|
+
} else if (typeof item === 'object' && item !== null) {
|
|
187
|
+
// 对象格式:{id, ...} 或 {_id, ...}
|
|
188
|
+
return item.id || item._id;
|
|
135
189
|
}
|
|
136
|
-
|
|
190
|
+
return null;
|
|
191
|
+
}).filter(id => id);
|
|
192
|
+
} else if (typeof orgIds === 'object' && orgIds !== null) {
|
|
193
|
+
// 单个对象:{id, ...}
|
|
194
|
+
const orgId = orgIds.id || orgIds._id;
|
|
195
|
+
if (orgId) {
|
|
196
|
+
idArray = [orgId];
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
// 获取组织详细信息
|
|
201
|
+
for (const orgId of idArray) {
|
|
202
|
+
const org = await getSelectOrgValue(orgId, spaceId);
|
|
203
|
+
if (org) {
|
|
204
|
+
orgs.push(org);
|
|
205
|
+
}
|
|
137
206
|
}
|
|
207
|
+
|
|
138
208
|
return orgs;
|
|
139
209
|
};
|
|
140
210
|
|
|
141
|
-
const getFileFieldValue = (recordFieldId, fType) => {
|
|
211
|
+
const getFileFieldValue = async (recordFieldId, fType) => {
|
|
142
212
|
if (_.isEmpty(recordFieldId)) {
|
|
143
213
|
return;
|
|
144
214
|
}
|
|
@@ -154,7 +224,8 @@ const getFileFieldValue = (recordFieldId, fType) => {
|
|
|
154
224
|
} else {
|
|
155
225
|
query = { _id: { $in: recordFieldId } };
|
|
156
226
|
}
|
|
157
|
-
const
|
|
227
|
+
const coll = await getCollection(`cfs.${collection}.filerecord`);
|
|
228
|
+
const files = await coll.find(query).toArray();
|
|
158
229
|
const value = [];
|
|
159
230
|
files.forEach((f) => {
|
|
160
231
|
const newFile = new FS.File();
|
|
@@ -200,27 +271,26 @@ const getInstanceFieldValue = (objField, formField, record, object_field, spaceI
|
|
|
200
271
|
odataFieldValue = getFieldOdataValue(referenceToObjectName, recordFieldValue, referenceToFieldName);
|
|
201
272
|
}
|
|
202
273
|
value = odataFieldValue;
|
|
203
|
-
}
|
|
274
|
+
}
|
|
275
|
+
// 对象的 lookup/master_detail 字段(users/space_users reference_to)→ 审批单的 member/memberMulti 字段
|
|
276
|
+
else if (formField && objField && (formField.type === 'user' || formField.code === 'member' || formField.code === 'memberMulti')
|
|
277
|
+
&& ['lookup', 'master_detail'].includes(objField.type)
|
|
278
|
+
&& ['users', 'space_users'].includes(objField.reference_to)) {
|
|
204
279
|
if (!_.isEmpty(recordFieldValue)) {
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
selectFieldValue = getSelectOrgValue(recordFieldValue, spaceId);
|
|
217
|
-
}
|
|
218
|
-
}
|
|
219
|
-
if (selectFieldValue) {
|
|
220
|
-
value = selectFieldValue;
|
|
221
|
-
}
|
|
280
|
+
// recordFieldValue 可能是字符串、字符数组、或 ID 数组,都统一处理
|
|
281
|
+
value = getSelectUserValues(recordFieldValue, spaceId);
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
// 对象的 lookup/master_detail 字段(organizations reference_to)→ 审批单的 org/orgMulti 字段
|
|
285
|
+
else if (formField && objField && (formField.type === 'group' || formField.code === 'org' || formField.code === 'orgMulti')
|
|
286
|
+
&& ['lookup', 'master_detail'].includes(objField.type)
|
|
287
|
+
&& objField.reference_to === 'organizations') {
|
|
288
|
+
if (!_.isEmpty(recordFieldValue)) {
|
|
289
|
+
// recordFieldValue 可能是字符串、字符数组、或 ID 数组,都统一处理
|
|
290
|
+
value = getSelectOrgValues(recordFieldValue, spaceId);
|
|
222
291
|
}
|
|
223
|
-
}
|
|
292
|
+
}
|
|
293
|
+
else if (formField && objField && formField.type == 'date' && recordFieldValue) {
|
|
224
294
|
value = uuflowManagerForInitApproval.formatDate(recordFieldValue);
|
|
225
295
|
} else if (formField && objField && formField.type == 'time' && recordFieldValue) {
|
|
226
296
|
value = uuflowManagerForInitApproval.formatTime(recordFieldValue);
|
|
@@ -256,7 +326,7 @@ const checkRequiredDetails = (requiredDetails, masterRecord) => {
|
|
|
256
326
|
|
|
257
327
|
const uuflowManagerForInitApproval = {};
|
|
258
328
|
|
|
259
|
-
uuflowManagerForInitApproval.check_authorization = (req) => {
|
|
329
|
+
uuflowManagerForInitApproval.check_authorization = async (req) => {
|
|
260
330
|
const query = req.query;
|
|
261
331
|
const userId = query["X-User-Id"];
|
|
262
332
|
const authToken = query["X-Auth-Token"];
|
|
@@ -265,17 +335,22 @@ uuflowManagerForInitApproval.check_authorization = (req) => {
|
|
|
265
335
|
throw new Error(401, 'Unauthorized');
|
|
266
336
|
}
|
|
267
337
|
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
338
|
+
// 使用 objectql 查询 users 对象
|
|
339
|
+
try {
|
|
340
|
+
const users = await objectql.getObject('users').find({
|
|
341
|
+
filters: [['_id', '=', userId]],
|
|
342
|
+
fields: ['_id', 'username']
|
|
343
|
+
});
|
|
344
|
+
|
|
345
|
+
if (!users || users.length === 0) {
|
|
346
|
+
throw new Error(401, 'Unauthorized');
|
|
347
|
+
}
|
|
273
348
|
|
|
274
|
-
|
|
349
|
+
const user = users[0];
|
|
350
|
+
return user;
|
|
351
|
+
} catch (error) {
|
|
275
352
|
throw new Error(401, 'Unauthorized');
|
|
276
353
|
}
|
|
277
|
-
|
|
278
|
-
return user;
|
|
279
354
|
};
|
|
280
355
|
|
|
281
356
|
uuflowManagerForInitApproval.getSpace = async (space_id) => {
|
|
@@ -710,38 +785,47 @@ uuflowManagerForInitApproval.evalFieldMapScript = (field_map_script, objectName,
|
|
|
710
785
|
return {};
|
|
711
786
|
};
|
|
712
787
|
|
|
713
|
-
uuflowManagerForInitApproval.initiateAttach = (recordIds, spaceId, insId, approveId) => {
|
|
714
|
-
|
|
788
|
+
uuflowManagerForInitApproval.initiateAttach = async (recordIds, spaceId, insId, approveId) => {
|
|
789
|
+
const cfsColl = await getCollection('cms_files');
|
|
790
|
+
const cfsFileRecordColl = await getCollection('cfs.files.filerecord');
|
|
791
|
+
|
|
792
|
+
const cmsFiles = await cfsColl.find({
|
|
715
793
|
space: spaceId,
|
|
716
794
|
parent: recordIds
|
|
717
|
-
}).
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
795
|
+
}).toArray();
|
|
796
|
+
|
|
797
|
+
for (const cf of cmsFiles) {
|
|
798
|
+
for (let idx = 0; idx < cf.versions.length; idx++) {
|
|
799
|
+
const versionId = cf.versions[idx];
|
|
800
|
+
const f = await cfsFileRecordColl.findOne(versionId);
|
|
801
|
+
|
|
802
|
+
if (f) {
|
|
803
|
+
const newFile = new FS.File();
|
|
804
|
+
newFile.attachData(f.createReadStream('files'), {
|
|
805
|
+
type: f.original.type
|
|
806
|
+
}, (err) => {
|
|
807
|
+
if (err) {
|
|
808
|
+
throw new Error(err.error, err.reason);
|
|
809
|
+
}
|
|
810
|
+
newFile.name(f.name());
|
|
811
|
+
newFile.size(f.size());
|
|
812
|
+
const metadata = {
|
|
813
|
+
owner: f.metadata.owner,
|
|
814
|
+
owner_name: f.metadata.owner_name,
|
|
815
|
+
space: spaceId,
|
|
816
|
+
instance: insId,
|
|
817
|
+
approve: approveId,
|
|
818
|
+
parent: cf._id
|
|
819
|
+
};
|
|
820
|
+
if (idx === 0) {
|
|
821
|
+
metadata.current = true;
|
|
822
|
+
}
|
|
823
|
+
newFile.metadata = metadata;
|
|
824
|
+
cfs.instances.insert(newFile);
|
|
825
|
+
});
|
|
826
|
+
}
|
|
827
|
+
}
|
|
828
|
+
}
|
|
745
829
|
return;
|
|
746
830
|
};
|
|
747
831
|
|
|
@@ -757,28 +841,38 @@ uuflowManagerForInitApproval.initiateRecordInstanceInfo = async (recordIds, insI
|
|
|
757
841
|
return;
|
|
758
842
|
};
|
|
759
843
|
|
|
760
|
-
uuflowManagerForInitApproval.initiateRelatedRecordInstanceInfo = (relatedTablesInfo, insId, spaceId) => {
|
|
761
|
-
|
|
762
|
-
const
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
844
|
+
uuflowManagerForInitApproval.initiateRelatedRecordInstanceInfo = async (relatedTablesInfo, insId, spaceId) => {
|
|
845
|
+
for (const [relatedObjectName, tableItems] of Object.entries(relatedTablesInfo)) {
|
|
846
|
+
const relatedColl = await getCollection(relatedObjectName);
|
|
847
|
+
for (const item of tableItems) {
|
|
848
|
+
await relatedColl.updateOne(
|
|
849
|
+
{ _id: item._table._id },
|
|
850
|
+
{
|
|
851
|
+
$set: {
|
|
852
|
+
instances: [{
|
|
853
|
+
_id: insId,
|
|
854
|
+
state: 'draft'
|
|
855
|
+
}],
|
|
856
|
+
_table: item._table
|
|
857
|
+
}
|
|
771
858
|
}
|
|
772
|
-
|
|
773
|
-
}
|
|
774
|
-
}
|
|
859
|
+
);
|
|
860
|
+
}
|
|
861
|
+
}
|
|
775
862
|
return;
|
|
776
863
|
};
|
|
777
864
|
|
|
778
865
|
uuflowManagerForInitApproval.checkIsInApproval = async (recordIds, spaceId) => {
|
|
779
866
|
const record = await objectFindOne(recordIds.o, { filters: [['_id', '=', recordIds.ids[0]]], fields: ['instances'] });
|
|
780
|
-
if (record && record.instances && record.instances[0].state !== 'completed'
|
|
781
|
-
|
|
867
|
+
if (record && record.instances && record.instances[0].state !== 'completed') {
|
|
868
|
+
// 使用 objectql 查询 instances 集合
|
|
869
|
+
const instances = await objectql.getObject('instances').find({
|
|
870
|
+
filters: [['_id', '=', record.instances[0]._id]],
|
|
871
|
+
fields: ['_id']
|
|
872
|
+
});
|
|
873
|
+
if (instances && instances.length > 0) {
|
|
874
|
+
throw new Error('error!', "此记录已发起流程正在审批中,待审批结束方可发起下一次审批!");
|
|
875
|
+
}
|
|
782
876
|
}
|
|
783
877
|
return;
|
|
784
878
|
};
|
|
@@ -147,6 +147,7 @@ UUFlowManager.getSpaceUser = async function (space_id, user_id, options = {}) {
|
|
|
147
147
|
}, options);
|
|
148
148
|
|
|
149
149
|
if (!space_user) {
|
|
150
|
+
console.log(`user_id: ${user_id} does not belong to space_id: ${space_id}`);
|
|
150
151
|
throw new Error("user_id对应的用户不属于当前space");
|
|
151
152
|
}
|
|
152
153
|
|
|
@@ -4454,6 +4455,9 @@ UUFlowManager.timeoutAutoSubmit = async function (ins_id) {
|
|
|
4454
4455
|
continue;
|
|
4455
4456
|
}
|
|
4456
4457
|
|
|
4458
|
+
console.log(`[timeout_auto_submit] Processing approve ${a._id} for instance ${instance_id}`);
|
|
4459
|
+
console.log(`[timeout_auto_submit] current_user_info: ${JSON.stringify(current_user_info)}`);
|
|
4460
|
+
|
|
4457
4461
|
const updatedInstance = await UUFlowManager.workflow_engine(
|
|
4458
4462
|
approve_from_client,
|
|
4459
4463
|
current_user_info,
|
|
@@ -4493,6 +4497,7 @@ UUFlowManager.relocate = async function (instance_from_client, current_user_info
|
|
|
4493
4497
|
|
|
4494
4498
|
// Verify permissions
|
|
4495
4499
|
const permissions = await PermissionManager.getFlowPermissions(instance.flow, current_user);
|
|
4500
|
+
|
|
4496
4501
|
const space = await db.spaces.findOne(
|
|
4497
4502
|
{ _id: instance.space },
|
|
4498
4503
|
{ projection: { admins: 1 } }
|
|
@@ -4560,9 +4565,9 @@ UUFlowManager.relocate = async function (instance_from_client, current_user_info
|
|
|
4560
4565
|
let signShowApproveId = null;
|
|
4561
4566
|
|
|
4562
4567
|
for (let l = sameTraces.length - 1; l >= 0; l--) {
|
|
4563
|
-
const found = sameTraces[l].approves.find(a =>
|
|
4564
|
-
a.user === traces[i].approves[h].user &&
|
|
4565
|
-
a.judge !== "terminated" &&
|
|
4568
|
+
const found = sameTraces[l].approves.find(a =>
|
|
4569
|
+
a.user === traces[i].approves[h].user &&
|
|
4570
|
+
a.judge !== "terminated" &&
|
|
4566
4571
|
a.description
|
|
4567
4572
|
);
|
|
4568
4573
|
if (found) {
|
|
@@ -4725,7 +4730,7 @@ UUFlowManager.relocate = async function (instance_from_client, current_user_info
|
|
|
4725
4730
|
setObj.traces = traces;
|
|
4726
4731
|
|
|
4727
4732
|
// Update instance
|
|
4728
|
-
const updateOperation = setObj.state === 'completed'
|
|
4733
|
+
const updateOperation = setObj.state === 'completed'
|
|
4729
4734
|
? { $set: setObj }
|
|
4730
4735
|
: { $set: setObj, $unset: { finish_date: 1 } };
|
|
4731
4736
|
|
|
@@ -4739,46 +4744,44 @@ UUFlowManager.relocate = async function (instance_from_client, current_user_info
|
|
|
4739
4744
|
await remove_many_instance_tasks(finishedApproveIds);
|
|
4740
4745
|
if (newTrace.approves?.length) {
|
|
4741
4746
|
await insert_many_instance_tasks(
|
|
4742
|
-
instance_id,
|
|
4743
|
-
newTrace._id,
|
|
4747
|
+
instance_id,
|
|
4748
|
+
newTrace._id,
|
|
4744
4749
|
newTrace.approves.map(a => a._id)
|
|
4745
4750
|
);
|
|
4746
4751
|
}
|
|
4747
4752
|
|
|
4748
4753
|
const updatedInstance = await UUFlowManager.getInstance(instance_id);
|
|
4749
4754
|
|
|
4750
|
-
// Send notifications
|
|
4751
|
-
await pushManager.send_message_current_user(current_user_info);
|
|
4752
|
-
await Promise.all(not_in_inbox_users
|
|
4753
|
-
.filter(user_id => user_id !== current_user)
|
|
4754
|
-
.map(user_id => pushManager.send_message_to_specifyUser("current_user", user_id))
|
|
4755
|
-
);
|
|
4756
|
-
|
|
4755
|
+
// Send notifications (并行)
|
|
4757
4756
|
const notifyUsers = [...new Set([
|
|
4758
4757
|
updatedInstance.applicant,
|
|
4759
4758
|
updatedInstance.submitter,
|
|
4760
4759
|
...(updatedInstance.outbox_users || [])
|
|
4761
4760
|
])];
|
|
4762
4761
|
|
|
4763
|
-
await Promise.all(
|
|
4764
|
-
pushManager.
|
|
4765
|
-
|
|
4766
|
-
|
|
4767
|
-
|
|
4768
|
-
|
|
4769
|
-
|
|
4770
|
-
|
|
4771
|
-
|
|
4772
|
-
|
|
4773
|
-
|
|
4774
|
-
|
|
4775
|
-
|
|
4776
|
-
|
|
4777
|
-
|
|
4778
|
-
|
|
4779
|
-
|
|
4780
|
-
|
|
4781
|
-
|
|
4762
|
+
await Promise.all([
|
|
4763
|
+
pushManager.send_message_current_user(current_user_info),
|
|
4764
|
+
...not_in_inbox_users
|
|
4765
|
+
.filter(user_id => user_id !== current_user)
|
|
4766
|
+
.map(user_id => pushManager.send_message_to_specifyUser("current_user", user_id)),
|
|
4767
|
+
...notifyUsers.map(user_id =>
|
|
4768
|
+
pushManager.send_message_to_specifyUser("current_user", user_id)
|
|
4769
|
+
),
|
|
4770
|
+
pushManager.send_instance_notification(
|
|
4771
|
+
"reassign_new_inbox_users",
|
|
4772
|
+
updatedInstance,
|
|
4773
|
+
relocate_comment,
|
|
4774
|
+
current_user_info
|
|
4775
|
+
),
|
|
4776
|
+
pushManager.triggerWebhook(
|
|
4777
|
+
updatedInstance.flow,
|
|
4778
|
+
updatedInstance,
|
|
4779
|
+
{},
|
|
4780
|
+
'relocate',
|
|
4781
|
+
current_user,
|
|
4782
|
+
updatedInstance.inbox_users
|
|
4783
|
+
)
|
|
4784
|
+
]);
|
|
4782
4785
|
}
|
|
4783
4786
|
|
|
4784
4787
|
return result;
|
|
@@ -181,6 +181,8 @@ actions:
|
|
|
181
181
|
label: Delete
|
|
182
182
|
instance_delete_many:
|
|
183
183
|
label: Delete
|
|
184
|
+
instance_export:
|
|
185
|
+
label: Export
|
|
184
186
|
CustomLabels:
|
|
185
187
|
instance_action_new_dialog_title: Please select the process
|
|
186
188
|
instance_action_new_dialog_msg_success: Created successfully!
|
|
@@ -209,4 +211,11 @@ CustomLabels:
|
|
|
209
211
|
instance_action_relocate_dialog_msg_success: Relocated successful
|
|
210
212
|
instance_action_relocate_dialog_msg_failed: Relocated failed
|
|
211
213
|
instance_action_instance_save_msg_upgraded: The workflow has been upgraded. The page will refresh automatically.
|
|
214
|
+
instance_export_tooltip: Export to Excel after selecting a workflow
|
|
215
|
+
instance_export_msg_no_flow: Please select a workflow to export
|
|
216
|
+
instance_export_msg_max_flow: Export up to 5 workflows at a time
|
|
217
|
+
instance_export_this_month: This Month
|
|
218
|
+
instance_export_last_month: Last Month
|
|
219
|
+
instance_export_this_year: This Year
|
|
220
|
+
instance_export_all: All
|
|
212
221
|
|
package/main/default/objectTranslations/instances.zh-CN/instances.zh-CN.objectTranslation.yml
CHANGED
|
@@ -179,6 +179,8 @@ actions:
|
|
|
179
179
|
label: 新建
|
|
180
180
|
instance_delete_many:
|
|
181
181
|
label: 删除
|
|
182
|
+
instance_export:
|
|
183
|
+
label: 导出
|
|
182
184
|
CustomLabels:
|
|
183
185
|
instance_action_new_dialog_title: 请选择流程
|
|
184
186
|
instance_action_new_dialog_msg_success: 创建成功!
|
|
@@ -207,3 +209,10 @@ CustomLabels:
|
|
|
207
209
|
instance_action_relocate_dialog_msg_success: 重定位成功
|
|
208
210
|
instance_action_relocate_dialog_msg_failed: 重定位失败
|
|
209
211
|
instance_action_instance_save_msg_upgraded: 流程已升级,页面将自动刷新。
|
|
212
|
+
instance_export_tooltip: 选择流程后可导出为Excel
|
|
213
|
+
instance_export_msg_no_flow: 请先选择要导出的流程
|
|
214
|
+
instance_export_msg_max_flow: 最多导出5个流程
|
|
215
|
+
instance_export_this_month: 本月
|
|
216
|
+
instance_export_last_month: 上月
|
|
217
|
+
instance_export_this_year: 本年度
|
|
218
|
+
instance_export_all: 所有
|
|
@@ -56,7 +56,7 @@ amis_schema: |-
|
|
|
56
56
|
},
|
|
57
57
|
{
|
|
58
58
|
"actionType": "custom",
|
|
59
|
-
"script": "\nconst {instance, appId, objectName} = event.data;\nconsole.log(`instance===`);doAction({\n actionType: 'link',\n args: {\n blank: false,\n
|
|
59
|
+
"script": "\nconst {instance, appId, objectName} = event.data;\nconsole.log(`instance===`);doAction({\n actionType: 'link',\n args: {\n blank: false,\n link: `/app/${appId}/instances/view/${instance._id}?side_object=instances&side_listview_id=draft&additionalFilters=&flowId=&categoryId=`\n }\n});\n"
|
|
60
60
|
},
|
|
61
61
|
{
|
|
62
62
|
"componentId": "",
|
|
@@ -1,10 +1,5 @@
|
|
|
1
1
|
module.exports = {
|
|
2
2
|
instance_exportVisible: function (object_name, record_id, record_permissions, data) {
|
|
3
|
-
|
|
4
|
-
var flowId = data.flowId;
|
|
5
|
-
if (box === "monitor" && flowId) {
|
|
6
|
-
return true;
|
|
7
|
-
}
|
|
8
|
-
return false;
|
|
3
|
+
return data.listName === "monitor";
|
|
9
4
|
}
|
|
10
5
|
}
|
|
@@ -5,20 +5,23 @@ amis_schema: |-
|
|
|
5
5
|
"body": [
|
|
6
6
|
{
|
|
7
7
|
"type": "dropdown-button",
|
|
8
|
-
"label": "
|
|
8
|
+
"label": "${'CustomAction.instances.instance_export' | t}",
|
|
9
9
|
"id": "u:instance_export",
|
|
10
10
|
"level": "default",
|
|
11
11
|
"icon": "fa fa-download",
|
|
12
|
+
"tooltip": "选择流程后可导出为Excel",
|
|
13
|
+
"tooltipPlacement": "top",
|
|
14
|
+
"align": "right",
|
|
12
15
|
"buttons": [
|
|
13
16
|
{
|
|
14
17
|
"type": "button",
|
|
15
|
-
"label": "
|
|
18
|
+
"label": "${'CustomLabels.instance_export_this_month' | t}",
|
|
16
19
|
"onEvent": {
|
|
17
20
|
"click": {
|
|
18
21
|
"actions": [
|
|
19
22
|
{
|
|
20
23
|
"actionType": "custom",
|
|
21
|
-
"script": "var spaceId = event.data.context.tenantId; var flowId = event.data.flowId; if(
|
|
24
|
+
"script": "var spaceId = event.data.context.tenantId; var flowIds = []; if (event.data.flowId && sessionStorage.getItem('flowId')) { flowIds = [event.data.flowId]; } else { var sf = event.data.monitorExportFlowIds; if (!sf) { sf = event.data.__searchable__flow; } if (sf) { flowIds = Array.isArray(sf) ? sf.slice() : [sf]; } } flowIds = flowIds.filter(function(id) { return !!id; }); if (flowIds.length === 0) { event.context.env.notify('warning', t('CustomLabels.instance_export_msg_no_flow')); } else if (flowIds.length > 5) { event.context.env.notify('warning', t('CustomLabels.instance_export_msg_max_flow')); } else { var tz = new Date().getTimezoneOffset(); flowIds.forEach(function(fid) { window.open(Steedos.absoluteUrl('/api/workflow/export/instances?space_id=' + spaceId + '&flow_id=' + fid + '&type=0&timezoneoffset=' + tz), '_blank'); }); }"
|
|
22
25
|
}
|
|
23
26
|
]
|
|
24
27
|
}
|
|
@@ -26,13 +29,13 @@ amis_schema: |-
|
|
|
26
29
|
},
|
|
27
30
|
{
|
|
28
31
|
"type": "button",
|
|
29
|
-
"label": "
|
|
32
|
+
"label": "${'CustomLabels.instance_export_last_month' | t}",
|
|
30
33
|
"onEvent": {
|
|
31
34
|
"click": {
|
|
32
35
|
"actions": [
|
|
33
36
|
{
|
|
34
37
|
"actionType": "custom",
|
|
35
|
-
"script": "var spaceId = event.data.context.tenantId; var flowId = event.data.flowId; if(
|
|
38
|
+
"script": "var spaceId = event.data.context.tenantId; var flowIds = []; if (event.data.flowId && sessionStorage.getItem('flowId')) { flowIds = [event.data.flowId]; } else { var sf = event.data.monitorExportFlowIds; if (!sf) { sf = event.data.__searchable__flow; } if (sf) { flowIds = Array.isArray(sf) ? sf.slice() : [sf]; } } flowIds = flowIds.filter(function(id) { return !!id; }); if (flowIds.length === 0) { event.context.env.notify('warning', t('CustomLabels.instance_export_msg_no_flow')); } else if (flowIds.length > 5) { event.context.env.notify('warning', t('CustomLabels.instance_export_msg_max_flow')); } else { var tz = new Date().getTimezoneOffset(); flowIds.forEach(function(fid) { window.open(Steedos.absoluteUrl('/api/workflow/export/instances?space_id=' + spaceId + '&flow_id=' + fid + '&type=1&timezoneoffset=' + tz), '_blank'); }); }"
|
|
36
39
|
}
|
|
37
40
|
]
|
|
38
41
|
}
|
|
@@ -40,13 +43,13 @@ amis_schema: |-
|
|
|
40
43
|
},
|
|
41
44
|
{
|
|
42
45
|
"type": "button",
|
|
43
|
-
"label": "
|
|
46
|
+
"label": "${'CustomLabels.instance_export_this_year' | t}",
|
|
44
47
|
"onEvent": {
|
|
45
48
|
"click": {
|
|
46
49
|
"actions": [
|
|
47
50
|
{
|
|
48
51
|
"actionType": "custom",
|
|
49
|
-
"script": "var spaceId = event.data.context.tenantId; var flowId = event.data.flowId; if(
|
|
52
|
+
"script": "var spaceId = event.data.context.tenantId; var flowIds = []; if (event.data.flowId && sessionStorage.getItem('flowId')) { flowIds = [event.data.flowId]; } else { var sf = event.data.monitorExportFlowIds; if (!sf) { sf = event.data.__searchable__flow; } if (sf) { flowIds = Array.isArray(sf) ? sf.slice() : [sf]; } } flowIds = flowIds.filter(function(id) { return !!id; }); if (flowIds.length === 0) { event.context.env.notify('warning', t('CustomLabels.instance_export_msg_no_flow')); } else if (flowIds.length > 5) { event.context.env.notify('warning', t('CustomLabels.instance_export_msg_max_flow')); } else { var tz = new Date().getTimezoneOffset(); flowIds.forEach(function(fid) { window.open(Steedos.absoluteUrl('/api/workflow/export/instances?space_id=' + spaceId + '&flow_id=' + fid + '&type=2&timezoneoffset=' + tz), '_blank'); }); }"
|
|
50
53
|
}
|
|
51
54
|
]
|
|
52
55
|
}
|
|
@@ -54,13 +57,13 @@ amis_schema: |-
|
|
|
54
57
|
},
|
|
55
58
|
{
|
|
56
59
|
"type": "button",
|
|
57
|
-
"label": "
|
|
60
|
+
"label": "${'CustomLabels.instance_export_all' | t}",
|
|
58
61
|
"onEvent": {
|
|
59
62
|
"click": {
|
|
60
63
|
"actions": [
|
|
61
64
|
{
|
|
62
65
|
"actionType": "custom",
|
|
63
|
-
"script": "var spaceId = event.data.context.tenantId; var flowId = event.data.flowId; if(
|
|
66
|
+
"script": "var spaceId = event.data.context.tenantId; var flowIds = []; if (event.data.flowId && sessionStorage.getItem('flowId')) { flowIds = [event.data.flowId]; } else { var sf = event.data.monitorExportFlowIds; if (!sf) { sf = event.data.__searchable__flow; } if (sf) { flowIds = Array.isArray(sf) ? sf.slice() : [sf]; } } flowIds = flowIds.filter(function(id) { return !!id; }); if (flowIds.length === 0) { event.context.env.notify('warning', t('CustomLabels.instance_export_msg_no_flow')); } else if (flowIds.length > 5) { event.context.env.notify('warning', t('CustomLabels.instance_export_msg_max_flow')); } else { var tz = new Date().getTimezoneOffset(); flowIds.forEach(function(fid) { window.open(Steedos.absoluteUrl('/api/workflow/export/instances?space_id=' + spaceId + '&flow_id=' + fid + '&type=3&timezoneoffset=' + tz), '_blank'); }); }"
|
|
64
67
|
}
|
|
65
68
|
]
|
|
66
69
|
}
|