@steedos/service-core-objects 3.0.0-beta.8 → 3.0.0-beta.81
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/main/default/client/{topic.client.js → css.client.js} +2 -1
- package/main/default/client/socket.client.js +118 -0
- package/main/default/objectTranslations/base.en/base.en.objectTranslation.yml +2 -0
- package/main/default/objectTranslations/base.zh-CN/base.zh-CN.objectTranslation.yml +2 -0
- package/main/default/objectTranslations/datasources.zh-CN/datasources.zh-CN.objectTranslation.yml +1 -1
- package/main/default/objectTranslations/object_actions.zh-CN/object_actions.zh-CN.objectTranslation.yml +1 -1
- package/main/default/objectTranslations/object_fields.en/object_fields.en.objectTranslation.yml +1 -5
- package/main/default/objectTranslations/object_fields.zh-CN/object_fields.zh-CN.objectTranslation.yml +3 -3
- package/main/default/objectTranslations/object_functions.zh-CN/object_functions.zh-CN.objectTranslation.yml +1 -1
- package/main/default/objectTranslations/object_layouts.zh-CN/object_layouts.zh-CN.objectTranslation.yml +1 -1
- package/main/default/objectTranslations/object_listviews.en/object_listviews.en.objectTranslation.yml +0 -1
- package/main/default/objectTranslations/object_listviews.zh-CN/object_listviews.zh-CN.objectTranslation.yml +2 -3
- package/main/default/objectTranslations/objects.en/objects.en.objectTranslation.yml +23 -18
- package/main/default/objectTranslations/objects.zh-CN/objects.zh-CN.objectTranslation.yml +39 -25
- package/main/default/objects/_base/base.client.js +11 -10
- package/main/default/objects/_base/base.object.js +279 -105
- package/main/default/objects/_base/base.object.yml +8 -0
- package/main/default/objects/announcements.object.yml +68 -0
- package/main/default/objects/apps/apps.object.yml +25 -69
- package/main/default/objects/apps/buttons/disable.button.js +3 -1
- package/main/default/objects/apps/buttons/enable.button.js +3 -1
- package/main/default/objects/audit_records.object.yml +1 -1
- package/main/default/objects/cms_files/cms_files.object.yml +2 -1
- package/main/default/objects/favorites.object.yml +65 -0
- package/main/default/objects/keyvalue/keyvalue.object.yml +1 -0
- package/main/default/objects/logs/logs.object.yml +1 -0
- package/main/default/objects/object_fields/buttons/recomputeFormulaValues.button.js +6 -2
- package/main/default/objects/object_fields/buttons/recomputeSummaryValues.button.js +6 -2
- package/main/default/objects/object_fields/buttons/standard_new.button.js +1 -1
- package/main/default/objects/object_fields/fields/_name.field.yml +1 -0
- package/main/default/objects/object_fields/fields/auto_fill_mapping.$.to.field.yml +28 -13
- package/main/default/objects/object_fields/fields/name.field.yml +1 -0
- package/main/default/objects/object_fields/fields/options.field.yml +1 -0
- package/main/default/objects/object_fields/fields/summary_filters.$.field.field.yml +16 -9
- package/main/default/objects/object_fields/fields/summary_filters.$.operation.field.yml +26 -29
- package/main/default/objects/object_fields/listviews/all.listview.yml +3 -1
- package/main/default/objects/object_fields/listviews/customize.listview.yml +3 -1
- package/main/default/objects/object_functions/fields/script.field.yml +1 -1
- package/main/default/objects/object_listviews/buttons/customize.button.js +36 -30
- package/main/default/objects/object_listviews/buttons/showDesign.button.js +6 -6
- package/main/default/objects/object_listviews/fields/adaptor.field.yml +2 -2
- package/main/default/objects/object_listviews/fields/crudDataFilter.field.yml +10 -0
- package/main/default/objects/object_listviews/fields/enable_amis_schema.field.yml +1 -0
- package/main/default/objects/object_listviews/fields/requestAdaptor.field.yml +2 -2
- package/main/default/objects/object_triggers/fields/handler.field.yml +1 -1
- package/main/default/objects/objects/buttons/custom.button.js +6 -35
- package/main/default/objects/objects/buttons/custom.button.yml +85 -1
- package/main/default/objects/objects/buttons/delete_object.button.yml +5 -4
- package/main/default/objects/objects/buttons/design_fields_layout.button.yml +1 -1
- package/main/default/objects/objects/buttons/reset.button.yml +6 -5
- package/main/default/objects/objects/buttons/show_object.button.js +2 -29
- package/main/default/objects/objects/fields/compactLayouts.field.yml +2 -2
- package/main/default/objects/objects/fields/enable_audit.field.yml +5 -0
- package/main/default/objects/objects/fields/enable_chatter.field.yml +5 -4
- package/main/default/objects/objects/fields/enable_dataloader.field.yml +0 -1
- package/main/default/objects/objects/fields/enable_enhanced_lookup.field.yml +0 -4
- package/main/default/objects/objects/fields/enable_events.field.yml +2 -2
- package/main/default/objects/objects/fields/enable_files.field.yml +1 -1
- package/main/default/objects/objects/fields/enable_form_tabs.field.yml +1 -2
- package/main/default/objects/objects/fields/enable_inline_edit.field.yml +1 -1
- package/main/default/objects/objects/fields/enable_instances.field.yml +2 -2
- package/main/default/objects/objects/fields/enable_lock_detail.field.yml +0 -1
- package/main/default/objects/objects/fields/enable_notes.field.yml +2 -2
- package/main/default/objects/objects/fields/enable_tasks.field.yml +1 -1
- package/main/default/objects/objects/fields/enable_tree.field.yml +0 -1
- package/main/default/objects/objects/fields/field_groups.field.yml +1 -1
- package/main/default/objects/objects/fields/in_development.field.yml +0 -1
- package/main/default/objects/objects/fields/is_deleted.field.yml +1 -0
- package/main/default/objects/objects/fields/name.field.yml +1 -4
- package/main/default/objects/objects/fields/table_name.field.yml +0 -1
- package/main/default/objects/objects/listviews/all.listview.yml +4 -1
- package/main/default/objects/objects/listviews/customize.listview.yml +3 -1
- package/main/default/objects/objects/listviews/deleted.listview.yml +3 -1
- package/main/default/objects/objects/listviews/metadata.listview.yml +3 -1
- package/main/default/objects/objects/listviews/system.listview.yml +3 -1
- package/main/default/objects/objects/objects.object.yml +1 -1
- package/main/default/objects/permission_set.object.yml +0 -4
- package/main/default/objects/queue_import.object.yml +15 -1
- package/main/default/objects/roles.object.yml +1 -5
- package/main/default/objects/space_users/buttons/standard_edit.button.js +0 -1
- package/main/default/objects/space_users/fields/locale.field.yml +2 -1
- package/main/default/pages/cms_files_preview.page.amis.json +20 -1
- package/main/default/pages/object_detail.page.amis.json +17 -11
- package/main/default/pages/object_fields_form.page.amis.json +0 -11
- package/main/default/pages/object_validation_rules_form.page.amis.json +38 -0
- package/main/default/pages/object_validation_rules_form.page.yml +13 -0
- package/main/default/pages/object_webhooks_form.page.amis.json +1 -1
- package/main/default/pages/space_users_list.page.amis.json +2 -2
- package/main/default/routes/importRecords.router.js +87 -0
- package/main/default/routes/notifications.router.js +113 -0
- package/main/default/routes/object_fields_design.ejs +0 -7
- package/main/default/services/app-design.service.js +2 -1
- package/main/default/services/notifications.service.js +190 -0
- package/main/default/services/users.service.js +1 -1
- package/main/default/triggers/objects_set_default_object_properties_trigger.trigger.yml +9 -6
- package/main/default/triggers/queue_import.trigger.js +16 -0
- package/package.json +4 -3
- package/package.service.js +3 -2
- package/public/platform.css +62 -0
- package/public/topic.css +17 -37
- package/main/default/objectTranslations/flow_positions.en/flow_positions.en.objectTranslation.yml +0 -19
- package/main/default/objectTranslations/flow_positions.zh-CN/flow_positions.zh-CN.objectTranslation.yml +0 -19
- package/main/default/objectTranslations/flow_roles.en/flow_roles.en.objectTranslation.yml +0 -11
- package/main/default/objectTranslations/flow_roles.zh-CN/flow_roles.zh-CN.objectTranslation.yml +0 -14
- package/main/default/objectTranslations/flows.en/flows.en.objectTranslation.yml +0 -317
- package/main/default/objectTranslations/flows.zh-CN/flows.zh-CN.objectTranslation.yml +0 -314
- package/main/default/objects/apps/buttons/amis_edit.button.yml +0 -39
- package/main/default/objects/apps/buttons/amis_new.button.yml +0 -43
- package/main/default/objects/flows/flows.object.yml +0 -1089
- package/main/default/objects/object_actions/buttons/customize.button.js +0 -33
- package/main/default/objects/object_actions/buttons/customize.button.yml +0 -3
- package/main/default/objects/object_listviews/buttons/copy.button.js +0 -58
- package/main/default/objects/object_listviews/buttons/copy.button.yml +0 -3
- package/main/default/objects/object_listviews/buttons/customize.button.yml +0 -3
- package/main/default/objects/objects/buttons/design_field_layout.button.js +0 -28
- package/main/default/objects/objects/buttons/design_field_layout.button.yml +0 -5
- package/main/default/objects/process_definition.object.yml +0 -323
- package/main/default/objects/space_users/fields/zoom.field.yml +0 -16
- package/main/default/tabs/admin_process_delegation_rules.tab.yml +0 -24
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
{
|
|
2
|
+
"type": "service",
|
|
3
|
+
"body": [
|
|
4
|
+
{
|
|
5
|
+
"type": "steedos-object-form",
|
|
6
|
+
"label": "对象表单",
|
|
7
|
+
"objectApiName": "object_validation_rules",
|
|
8
|
+
"recordId": "${recordId}",
|
|
9
|
+
"className": "",
|
|
10
|
+
"id": "u:b3d626885b90",
|
|
11
|
+
"enableTabs": false,
|
|
12
|
+
"mode": "edit",
|
|
13
|
+
"layout": "normal",
|
|
14
|
+
"tabsMode": "",
|
|
15
|
+
"fieldsExtend": {
|
|
16
|
+
"error_condition_formula": {
|
|
17
|
+
"amis": {
|
|
18
|
+
"type": "service",
|
|
19
|
+
"schemaApi": {
|
|
20
|
+
"method": "get",
|
|
21
|
+
"url": "${context.rootUrl}/service/api/amis-metadata-objects/objects/${object_name}/fields/options",
|
|
22
|
+
"cache": 30000,
|
|
23
|
+
"adaptor": "const field = context.uiSchema.fields.error_condition_formula; const variables = SteedosUI.getFormulaVariables(payload.data.options); \n var fieldSchema={label: field.label, type:'input-formula', name: 'error_condition_formula', 'evalMode': false, variableMode: 'tabs', variables: variables, labelRemark: field.inlineHelpText, description: field.description } \n return {...payload, data:fieldSchema};",
|
|
24
|
+
"trackExpression": "${object_name}",
|
|
25
|
+
"sendOn": "${object_name}"
|
|
26
|
+
},
|
|
27
|
+
"dsType": "api",
|
|
28
|
+
"id": "u:508198dbfac7"
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
],
|
|
34
|
+
"data": {},
|
|
35
|
+
"name": "page_object_validation_rules_form",
|
|
36
|
+
"id": "u:5f4f07272db7",
|
|
37
|
+
"dsType": "api"
|
|
38
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
name: object_validation_rules_form
|
|
2
|
+
is_active: true
|
|
3
|
+
label: 对象验证规则表单
|
|
4
|
+
locked: false
|
|
5
|
+
object_name: object_validation_rules
|
|
6
|
+
pageAssignments:
|
|
7
|
+
- type: orgDefault
|
|
8
|
+
page: object_validation_rules_form
|
|
9
|
+
desktop: true
|
|
10
|
+
mobile: true
|
|
11
|
+
render_engine: amis
|
|
12
|
+
type: form
|
|
13
|
+
widgets: []
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
"method": "get",
|
|
17
17
|
"url": "/service/api/amis-metadata-objects/objects/${object_name}/fields/options",
|
|
18
18
|
"cache": 30000,
|
|
19
|
-
"adaptor": "const field = context.uiSchema.fields.condition; const
|
|
19
|
+
"adaptor": "const field = context.uiSchema.fields.condition; const variables = SteedosUI.getFormulaVariables(payload.data.options);\n var fieldSchema={label: field.label, type:'input-formula', name: 'condition', 'evalMode': false, variableMode: 'tabs', variables: variables, labelRemark: field.inlineHelpText, description: field.description } \n return {...payload, data:fieldSchema};",
|
|
20
20
|
"trackExpression": "${object_name}",
|
|
21
21
|
"sendOn": "${object_name}"
|
|
22
22
|
}
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
{
|
|
20
20
|
"type": "input-tree",
|
|
21
21
|
"id": "u:7fd77b7915b0",
|
|
22
|
-
"className": "",
|
|
22
|
+
"className": "bg-none",
|
|
23
23
|
"source": {
|
|
24
24
|
"method": "post",
|
|
25
25
|
"url": "${context.rootUrl}/graphql",
|
|
@@ -88,7 +88,7 @@
|
|
|
88
88
|
{
|
|
89
89
|
"type": "wrapper",
|
|
90
90
|
"size": "none",
|
|
91
|
-
"className": "flex-1
|
|
91
|
+
"className": "flex-1 focus:outline-none lg:order-last w-96",
|
|
92
92
|
"body": [
|
|
93
93
|
{
|
|
94
94
|
"type": "steedos-object-listview",
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
|
|
2
|
+
const { requireAuthentication } = require('@steedos/auth');
|
|
3
|
+
const { importWithCmsFile } = require('@steedos/data-import/lib/index')
|
|
4
|
+
const express = require('express');
|
|
5
|
+
const router = express.Router();
|
|
6
|
+
|
|
7
|
+
const json2xls = require('json2xls');
|
|
8
|
+
const { getObject } = require('@steedos/objectql');
|
|
9
|
+
const _ = require('lodash');
|
|
10
|
+
|
|
11
|
+
const initiateImport = async function (req, res) {
|
|
12
|
+
try {
|
|
13
|
+
const userSession = req.user;
|
|
14
|
+
// const spaceId = userSession.spaceId;
|
|
15
|
+
let { importObjId, importObjectHistoryId } = req.body;
|
|
16
|
+
let fileId = null;
|
|
17
|
+
const isSpaceAdmin = req.user.is_space_admin;
|
|
18
|
+
//传入了importObjId参数,必须是工作区管理员权限
|
|
19
|
+
if (importObjId && !isSpaceAdmin) {
|
|
20
|
+
return res
|
|
21
|
+
.status(401)
|
|
22
|
+
.send({ status: "error", message: "Permission denied" });
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
if (importObjectHistoryId) {
|
|
26
|
+
const record = await getObject('queue_import_history').findOne(importObjectHistoryId);
|
|
27
|
+
if (!record) {
|
|
28
|
+
throw new Error(
|
|
29
|
+
`can not find queue_import_history record with given id "${importObjectHistoryId}"`
|
|
30
|
+
);
|
|
31
|
+
}
|
|
32
|
+
if (!record.file) {
|
|
33
|
+
throw new Error(`Upload excel file, please.`);
|
|
34
|
+
}
|
|
35
|
+
fileId = record.file
|
|
36
|
+
importObjId = record.queue_import
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// if (!Steedos.hasFeature('metadata_api', spaceId)) {
|
|
40
|
+
// return res.status(403).send({ status: 'error', message: 'Please upgrade the platform license to Enterprise Edition' });
|
|
41
|
+
// }
|
|
42
|
+
|
|
43
|
+
try {
|
|
44
|
+
let result = await importWithCmsFile(importObjId, userSession, importObjectHistoryId, fileId);
|
|
45
|
+
return res.status(200).send({ status: "success", result });
|
|
46
|
+
} catch (error) {
|
|
47
|
+
console.log(error)
|
|
48
|
+
return res
|
|
49
|
+
.status(500)
|
|
50
|
+
.send({ status: "failed", message: error.message });
|
|
51
|
+
}
|
|
52
|
+
} catch (error) {
|
|
53
|
+
console.log(error)
|
|
54
|
+
return res.status(500).send({ status: "failed", error: error.message });
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
router.post('/api/data/initiateImport', requireAuthentication, initiateImport);
|
|
59
|
+
|
|
60
|
+
router.get('/api/data/download/template/:record_id', requireAuthentication, async function (req, res) {
|
|
61
|
+
try {
|
|
62
|
+
const { record_id } = req.params;
|
|
63
|
+
let queueImportDoc = await getObject("queue_import").findOne(record_id);
|
|
64
|
+
let fieldMaps = queueImportDoc.field_mappings;
|
|
65
|
+
if (_.isEmpty(fieldMaps)) {
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
let json = {};
|
|
69
|
+
for (const fMap of fieldMaps) {
|
|
70
|
+
json[fMap.header] = null;
|
|
71
|
+
}
|
|
72
|
+
let xls = json2xls([json]);
|
|
73
|
+
res.writeHead(200, {
|
|
74
|
+
'Content-Type': 'application/octet-stream',
|
|
75
|
+
'Content-Disposition': 'attachment;filename=' + encodeURI(queueImportDoc.description + '.xlsx'),
|
|
76
|
+
'Access-Control-Expose-Headers': 'Content-Disposition'
|
|
77
|
+
});
|
|
78
|
+
res.end(xls, 'binary');
|
|
79
|
+
} catch (error) {
|
|
80
|
+
console.error(error);
|
|
81
|
+
res.status(500).send({ error: error.message });
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
exports.default = router;
|
|
87
|
+
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* @Author: 殷亮辉 yinlianghui@hotoa.com
|
|
3
|
+
* @Date: 2025-05-27 14:51:49
|
|
4
|
+
* @LastEditors: 殷亮辉 yinlianghui@hotoa.com
|
|
5
|
+
* @LastEditTime: 2025-05-27 15:48:42
|
|
6
|
+
*/
|
|
7
|
+
const { requireAuthentication } = require("@steedos/auth");
|
|
8
|
+
const { getSteedosSchema, getObject } = require("@steedos/objectql");
|
|
9
|
+
const express = require("express");
|
|
10
|
+
const router = express.Router();
|
|
11
|
+
const _ = require("lodash");
|
|
12
|
+
|
|
13
|
+
const util = {
|
|
14
|
+
/**
|
|
15
|
+
* Returns the object record Relative url
|
|
16
|
+
*/
|
|
17
|
+
getObjectRecordRelativeUrl: (objectName, recordId, spaceId = null, options = {}) => {
|
|
18
|
+
let appId = '-';
|
|
19
|
+
if (options.appId) {
|
|
20
|
+
appId = options.appId;
|
|
21
|
+
}
|
|
22
|
+
let url = `/app/${appId}/${objectName}/view/${recordId}`;
|
|
23
|
+
if (objectName === "instances") {
|
|
24
|
+
url = `/api/workflow/instances/redirect/${recordId}`
|
|
25
|
+
}
|
|
26
|
+
return url;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
router.get(
|
|
31
|
+
"/api/v4/notifications/:_id/read",
|
|
32
|
+
requireAuthentication,
|
|
33
|
+
async function (req, res) {
|
|
34
|
+
let { _id: record_id } = req.params;
|
|
35
|
+
let { rootUrl, appId } = req.query;
|
|
36
|
+
const userSession = req.user;
|
|
37
|
+
let req_async = _.has(req.query, 'async');
|
|
38
|
+
if (userSession.userId) {
|
|
39
|
+
let record = await getSteedosSchema().getObject("notifications").findOne(record_id, { fields: ['owner', 'is_read', 'related_to', 'space', 'url'] });
|
|
40
|
+
if (!record) {
|
|
41
|
+
// 跳转到通知记录界面会显示为404效果
|
|
42
|
+
let redirectUrl = util.getObjectRecordRelativeUrl("notifications", record_id);
|
|
43
|
+
if (req.get("X-Requested-With") === 'XMLHttpRequest') {
|
|
44
|
+
return res.status(200).send({
|
|
45
|
+
"status": 404,
|
|
46
|
+
"redirect": redirectUrl
|
|
47
|
+
});
|
|
48
|
+
} else {
|
|
49
|
+
return res.redirect(redirectUrl);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
if (!record.related_to && !record.url) {
|
|
53
|
+
return res.status(401).send({
|
|
54
|
+
"error": "Validate Request -- Missing related_to or url",
|
|
55
|
+
"success": false
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
if (!record.is_read && record.owner === userSession.userId) {
|
|
59
|
+
// 没有权限时,只是不修改is_read值,但是允许跳转到相关记录查看
|
|
60
|
+
await getSteedosSchema().getObject('notifications').update(record_id, { 'is_read': true, modified: new Date() })
|
|
61
|
+
}
|
|
62
|
+
let redirectUrl = record.url ? record.url : util.getObjectRecordRelativeUrl(record.related_to.o, record.related_to.ids[0], record.space, {
|
|
63
|
+
rootUrl, appId
|
|
64
|
+
});
|
|
65
|
+
if (req_async) { // || req.get("X-Requested-With") === 'XMLHttpRequest'
|
|
66
|
+
return res.status(200).send({
|
|
67
|
+
"status": 200,
|
|
68
|
+
"redirect": redirectUrl
|
|
69
|
+
});
|
|
70
|
+
} else {
|
|
71
|
+
return res.redirect(redirectUrl);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
return res.status(401).send({
|
|
75
|
+
"error": "Validate Request -- Missing X-Auth-Token",
|
|
76
|
+
"success": false
|
|
77
|
+
})
|
|
78
|
+
}
|
|
79
|
+
);
|
|
80
|
+
|
|
81
|
+
router.post(
|
|
82
|
+
"/api/v4/notifications/all/markReadAll",
|
|
83
|
+
requireAuthentication,
|
|
84
|
+
async function (req, res) {
|
|
85
|
+
let userSession = req.user;
|
|
86
|
+
let error;
|
|
87
|
+
let updatedCount = await getObject("notifications").directUpdateMany([
|
|
88
|
+
["space", "=", userSession.spaceId],
|
|
89
|
+
["owner", "=", userSession.userId],
|
|
90
|
+
[["is_read", "=", null], 'or', ["is_read", "=", false]]
|
|
91
|
+
], {
|
|
92
|
+
is_read: true
|
|
93
|
+
}).catch((ex) => {
|
|
94
|
+
console.error(ex);
|
|
95
|
+
error = ex;
|
|
96
|
+
return 0;
|
|
97
|
+
});
|
|
98
|
+
if (error) {
|
|
99
|
+
res.status(500).send({
|
|
100
|
+
"error": error,
|
|
101
|
+
"success": false
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
else {
|
|
105
|
+
return res.send({
|
|
106
|
+
markedCount: updatedCount,
|
|
107
|
+
"success": true
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
);
|
|
112
|
+
|
|
113
|
+
exports.default = router;
|
|
@@ -1,10 +1,3 @@
|
|
|
1
|
-
<!--
|
|
2
|
-
* @Author: baozhoutao@steedos.com
|
|
3
|
-
* @Date: 2022-06-02 17:45:15
|
|
4
|
-
* @LastEditors: baozhoutao@steedos.com
|
|
5
|
-
* @LastEditTime: 2024-10-17 12:02:21
|
|
6
|
-
* @Description:
|
|
7
|
-
-->
|
|
8
1
|
<html>
|
|
9
2
|
<head>
|
|
10
3
|
<script src="/unpkg.com/@steedos-builder/fiddle@0.0.5/dist/builder-fiddle.umd.js"></script>
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
2
|
+
const _ = require("lodash");
|
|
3
|
+
const objectql = require('@steedos/objectql');
|
|
4
|
+
|
|
5
|
+
module.exports = {
|
|
6
|
+
name: 'notifications',
|
|
7
|
+
namespace: "steedos",
|
|
8
|
+
mixins: [],
|
|
9
|
+
/**
|
|
10
|
+
* Settings
|
|
11
|
+
*/
|
|
12
|
+
settings: {
|
|
13
|
+
|
|
14
|
+
},
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Dependencies
|
|
18
|
+
*/
|
|
19
|
+
dependencies: [],
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Actions
|
|
23
|
+
*/
|
|
24
|
+
actions: {
|
|
25
|
+
/**
|
|
26
|
+
* @api {post} add 发送通知
|
|
27
|
+
* @apiName add
|
|
28
|
+
* @apiGroup notifications.service.js
|
|
29
|
+
* @apiParam {Object} message 消息主体
|
|
30
|
+
* @apiParam {String} message[name] 消息标题
|
|
31
|
+
* @apiParam {String} message[body] 消息内容
|
|
32
|
+
* @apiParam {String} message[related_to] 关联记录
|
|
33
|
+
* @apiParam {String} message[related_name] 关联名称
|
|
34
|
+
* @apiParam {String} message[from] 发送者ID,选填
|
|
35
|
+
* @apiParam {String} message[space] 工作区ID
|
|
36
|
+
* @apiParam {String} from 发送者ID
|
|
37
|
+
* @apiParam {String[]} to 接受者ID
|
|
38
|
+
*/
|
|
39
|
+
add: {
|
|
40
|
+
params: {
|
|
41
|
+
message: {
|
|
42
|
+
type: "object",
|
|
43
|
+
props: {
|
|
44
|
+
name: { type: "string" },
|
|
45
|
+
body: { type: "string" },
|
|
46
|
+
related_to: {
|
|
47
|
+
type: "object",
|
|
48
|
+
props: {
|
|
49
|
+
o: { type: "string" },
|
|
50
|
+
ids: { type: "array", items: "string" },
|
|
51
|
+
}
|
|
52
|
+
},
|
|
53
|
+
related_name: { type: "string", optional: true },
|
|
54
|
+
from: { type: "string", optional: true },
|
|
55
|
+
space: { type: "string" },
|
|
56
|
+
}
|
|
57
|
+
},
|
|
58
|
+
from: { type: "string" },
|
|
59
|
+
to: {
|
|
60
|
+
type: "multi",
|
|
61
|
+
rules: [
|
|
62
|
+
{ type: "string" },
|
|
63
|
+
{ type: "array", items: "string" }
|
|
64
|
+
]
|
|
65
|
+
},
|
|
66
|
+
},
|
|
67
|
+
async handler(ctx) {
|
|
68
|
+
let { from, to, message } = ctx.params;
|
|
69
|
+
this.broker.emit('notifications.add', {from, to, message})
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
let notifications_ids = [];
|
|
73
|
+
if(!_.isArray(to) && _.isString(to)){
|
|
74
|
+
to = [to]
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
if (_.isEmpty(to)) {
|
|
78
|
+
return
|
|
79
|
+
}
|
|
80
|
+
let now = new Date();
|
|
81
|
+
const datasource = objectql.getDataSource('default');
|
|
82
|
+
const adapter = datasource.adapter
|
|
83
|
+
await adapter.connect()
|
|
84
|
+
const collection = adapter.collection('notifications');
|
|
85
|
+
let bulk = collection.initializeUnorderedBulkOp();
|
|
86
|
+
|
|
87
|
+
let doc = Object.assign({
|
|
88
|
+
created: now,
|
|
89
|
+
modified: now,
|
|
90
|
+
created_by: from,
|
|
91
|
+
modified_by: from
|
|
92
|
+
}, message)
|
|
93
|
+
|
|
94
|
+
for (const userId of to) {
|
|
95
|
+
let notifications_id = await objectql.getObject('notifications')._makeNewID();
|
|
96
|
+
bulk.insert(Object.assign({}, doc, {_id: notifications_id, owner: userId}));
|
|
97
|
+
notifications_ids.push(notifications_id)
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
bulk.execute().catch(function (error) {
|
|
101
|
+
console.error("通知数据插入失败,错误信息:", error);
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
try {
|
|
105
|
+
this.broker.emit(`notifications.hasBeenSent`, {
|
|
106
|
+
ids: notifications_ids
|
|
107
|
+
});
|
|
108
|
+
await ctx.broker.call('b6-microservice.broadcast', {name: '$notification.users', data: {tenantId: message.space, users: to, message: {name: message.name, body: message.body}}})
|
|
109
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
110
|
+
} catch (e) { console.log(e) }
|
|
111
|
+
}
|
|
112
|
+
},
|
|
113
|
+
/**
|
|
114
|
+
* @api {post} remove 删除通知
|
|
115
|
+
* @apiName remove
|
|
116
|
+
* @apiGroup notifications.service.js
|
|
117
|
+
* @apiParam {Object} doc 消息主体
|
|
118
|
+
* @apiParam {String} doc[_id] 消息ID
|
|
119
|
+
* @apiParam {String[]} assignees 接受者ID
|
|
120
|
+
* @apiParam {String} objectName 关联对象名称
|
|
121
|
+
*/
|
|
122
|
+
remove: {
|
|
123
|
+
params: {
|
|
124
|
+
doc: {
|
|
125
|
+
type: "object",
|
|
126
|
+
props: {
|
|
127
|
+
_id: { type: "string" },
|
|
128
|
+
}
|
|
129
|
+
},
|
|
130
|
+
assignees: {
|
|
131
|
+
type: "array", items: "string"
|
|
132
|
+
},
|
|
133
|
+
objectName: { type: "string" },
|
|
134
|
+
},
|
|
135
|
+
async handler(ctx) {
|
|
136
|
+
const { doc, assignees, objectName } = ctx.params;
|
|
137
|
+
const datasource = objectql.getDataSource('default');
|
|
138
|
+
const adapter = datasource.adapter
|
|
139
|
+
await adapter.connect()
|
|
140
|
+
const collection = adapter.collection('notifications');
|
|
141
|
+
let bulk = collection.initializeUnorderedBulkOp();
|
|
142
|
+
assignees.forEach(function (assignee) {
|
|
143
|
+
bulk.find({
|
|
144
|
+
"related_to.o": objectName,
|
|
145
|
+
"related_to.ids": doc._id,
|
|
146
|
+
owner: assignee
|
|
147
|
+
}).remove();
|
|
148
|
+
});
|
|
149
|
+
return bulk.execute().catch(function (error) {
|
|
150
|
+
console.error("通知数据删除失败,错误信息:", error);
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
},
|
|
154
|
+
},
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* Events
|
|
158
|
+
*/
|
|
159
|
+
events: {
|
|
160
|
+
|
|
161
|
+
},
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* Methods
|
|
165
|
+
*/
|
|
166
|
+
methods: {
|
|
167
|
+
|
|
168
|
+
},
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* Service created lifecycle event handler
|
|
172
|
+
*/
|
|
173
|
+
created() {
|
|
174
|
+
|
|
175
|
+
},
|
|
176
|
+
|
|
177
|
+
/**
|
|
178
|
+
* Service started lifecycle event handler
|
|
179
|
+
*/
|
|
180
|
+
async started() {
|
|
181
|
+
this.broker.logger.info('[service][notifications]===>', 'started')
|
|
182
|
+
},
|
|
183
|
+
|
|
184
|
+
/**
|
|
185
|
+
* Service stopped lifecycle event handler
|
|
186
|
+
*/
|
|
187
|
+
async stopped() {
|
|
188
|
+
|
|
189
|
+
}
|
|
190
|
+
};
|
|
@@ -156,7 +156,7 @@ module.exports = {
|
|
|
156
156
|
}
|
|
157
157
|
const steedosConfig = getSteedosConfig();
|
|
158
158
|
const accountsConfig = steedosConfig.public.accounts || {};
|
|
159
|
-
const usernameMinLength = accountsConfig.username_min_length ? Number(accountsConfig.username_min_length) :
|
|
159
|
+
const usernameMinLength = accountsConfig.username_min_length ? Number(accountsConfig.username_min_length) : 2
|
|
160
160
|
if (username.length < usernameMinLength) {
|
|
161
161
|
throw new Error(`用户名最小长度不能小于 ${usernameMinLength} 位字符`);
|
|
162
162
|
}
|
|
@@ -5,7 +5,9 @@ when:
|
|
|
5
5
|
isEnabled: true
|
|
6
6
|
handler: |
|
|
7
7
|
try{
|
|
8
|
-
const { doc, userId } = ctx.params;
|
|
8
|
+
const { doc, userId, spaceId} = ctx.params;
|
|
9
|
+
const user = await ctx.getUser(userId, spaceId);
|
|
10
|
+
|
|
9
11
|
// 插入默认字段
|
|
10
12
|
await objects.object_fields.insert({
|
|
11
13
|
object: doc.name,
|
|
@@ -20,7 +22,7 @@ handler: |
|
|
|
20
22
|
index: true,
|
|
21
23
|
searchable: true,
|
|
22
24
|
filterable: true
|
|
23
|
-
});
|
|
25
|
+
}, user);
|
|
24
26
|
|
|
25
27
|
// 插入默认列表视图 "所有"
|
|
26
28
|
await objects.object_listviews.insert({
|
|
@@ -34,13 +36,14 @@ handler: |
|
|
|
34
36
|
crud_mode: 'table',
|
|
35
37
|
type: 'grid',
|
|
36
38
|
columns: [{ field: 'name' }],
|
|
39
|
+
is_enable: true,
|
|
37
40
|
sort: [
|
|
38
41
|
{
|
|
39
42
|
field_name: "created",
|
|
40
43
|
order: "desc"
|
|
41
44
|
}
|
|
42
45
|
]
|
|
43
|
-
});
|
|
46
|
+
}, user);
|
|
44
47
|
|
|
45
48
|
// 插入默认列表视图 "最近查看"
|
|
46
49
|
await objects.object_listviews.insert({
|
|
@@ -54,7 +57,7 @@ handler: |
|
|
|
54
57
|
filter_scope: "space",
|
|
55
58
|
crud_mode: 'table',
|
|
56
59
|
columns: [{ field: 'name' }]
|
|
57
|
-
});
|
|
60
|
+
}, user);
|
|
58
61
|
|
|
59
62
|
|
|
60
63
|
const psUserId = "user"; // 用户权限集 ID
|
|
@@ -86,7 +89,7 @@ handler: |
|
|
|
86
89
|
permission_set_id: psUserId,
|
|
87
90
|
object_name: doc.name,
|
|
88
91
|
space: doc.space
|
|
89
|
-
});
|
|
92
|
+
}, user);
|
|
90
93
|
|
|
91
94
|
// 插入管理员权限对象
|
|
92
95
|
await objects.permission_objects.insert({
|
|
@@ -95,7 +98,7 @@ handler: |
|
|
|
95
98
|
permission_set_id: psAdminId,
|
|
96
99
|
object_name: doc.name,
|
|
97
100
|
space: doc.space
|
|
98
|
-
});
|
|
101
|
+
}, user);
|
|
99
102
|
}catch(error){
|
|
100
103
|
console.log(error)
|
|
101
104
|
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
|
|
2
|
+
const objectql = require('@steedos/objectql');
|
|
3
|
+
|
|
4
|
+
module.exports = {
|
|
5
|
+
listenTo: 'queue_import',
|
|
6
|
+
|
|
7
|
+
afterFind: async function () {
|
|
8
|
+
if (this.data.values) {
|
|
9
|
+
for (const value of this.data.values) {
|
|
10
|
+
if (value) {
|
|
11
|
+
value.template_url = objectql.absoluteUrl(`/api/data/download/template/${value._id}`)
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@steedos/service-core-objects",
|
|
3
|
-
"version": "3.0.0-beta.
|
|
3
|
+
"version": "3.0.0-beta.81",
|
|
4
4
|
"main": "package.service.js",
|
|
5
5
|
"private": false,
|
|
6
6
|
"publishConfig": {
|
|
@@ -10,11 +10,12 @@
|
|
|
10
10
|
"steedos"
|
|
11
11
|
],
|
|
12
12
|
"dependencies": {
|
|
13
|
-
"@steedos/service-package-loader": "3.0.0-beta.
|
|
13
|
+
"@steedos/service-package-loader": "3.0.0-beta.81",
|
|
14
|
+
"json2xls": "^0.1.2",
|
|
14
15
|
"lodash": "^4.17.21"
|
|
15
16
|
},
|
|
16
17
|
"description": "steedos package",
|
|
17
18
|
"repository": {},
|
|
18
19
|
"license": "MIT",
|
|
19
|
-
"gitHead": "
|
|
20
|
+
"gitHead": "15126b1b1de6e4cb0592f0bc55e1458cac2a1894"
|
|
20
21
|
}
|
package/package.service.js
CHANGED
|
@@ -31,7 +31,7 @@ module.exports = {
|
|
|
31
31
|
$package: {
|
|
32
32
|
path: __dirname,
|
|
33
33
|
name: packageName,
|
|
34
|
-
isPackage:
|
|
34
|
+
isPackage: false
|
|
35
35
|
}
|
|
36
36
|
},
|
|
37
37
|
/**
|
|
@@ -212,9 +212,10 @@ module.exports = {
|
|
|
212
212
|
this.broker.createService({
|
|
213
213
|
name: 'steedos-server',
|
|
214
214
|
mixins: [],
|
|
215
|
+
dependencies: ['metadata-cachers-service'],
|
|
215
216
|
actions: {
|
|
216
217
|
setSettings(ctx) {
|
|
217
|
-
|
|
218
|
+
global.Steedos.settings = _.defaultsDeep({}, ctx.params, global.Steedos.settings);
|
|
218
219
|
}
|
|
219
220
|
},
|
|
220
221
|
started: function() {
|