@steedos/standard-object-database 2.7.1-beta.9 → 2.7.2-beta.1
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/objectTranslations/object_functions.en/object_functions.en.objectTranslation.yml +47 -0
- package/main/default/objectTranslations/object_functions.zh-CN/object_functions.zh-CN.objectTranslation.yml +44 -0
- package/main/default/objectTranslations/objects.en/objects.en.objectTranslation.yml +1 -1
- package/main/default/objectTranslations/objects.zh-CN/objects.zh-CN.objectTranslation.yml +2 -2
- package/main/default/objects/datasources/fields/driver.field.yml +1 -0
- package/main/default/objects/datasources/fields/is_enable.field.yml +1 -0
- package/main/default/objects/datasources/fields/label.field.yml +2 -0
- package/main/default/objects/datasources/fields/name.field.yml +1 -0
- package/main/default/objects/object_fields/fields/auto_fill_mapping.$.to.field.yml +2 -0
- package/main/default/objects/object_fields/fields/is_name.field.yml +1 -1
- package/main/default/objects/object_fields/fields/sortable.field.yml +1 -0
- package/main/default/objects/object_fields/fields/summary_filters.field.yml +1 -1
- package/main/default/objects/object_functions/buttons/standard_new.button.js +16 -0
- package/main/default/objects/object_functions/fields/_name.field.yml +7 -0
- package/main/default/objects/object_functions/fields/description.field.yml +5 -0
- package/main/default/objects/object_functions/fields/isEnabled.field.yml +5 -0
- package/main/default/objects/object_functions/fields/is_rest.field.yml +5 -0
- package/main/default/objects/object_functions/fields/is_system.field.yml +7 -0
- package/main/default/objects/object_functions/fields/name.field.yml +8 -0
- package/main/default/objects/object_functions/fields/objectApiName.field.yml +7 -0
- package/main/default/objects/object_functions/fields/record_permissions.field.yml +4 -0
- package/main/default/objects/object_functions/fields/script.field.yml +24 -0
- package/main/default/objects/object_functions/listviews/all.listview.yml +9 -0
- package/main/default/objects/object_functions/listviews/customize.listview.yml +13 -0
- package/main/default/objects/object_functions/object_functions.object.yml +8 -0
- package/main/default/objects/object_functions/permissions/admin.permission.yml +7 -0
- package/main/default/objects/object_functions/permissions/user.permission.yml +7 -0
- package/main/default/objects/object_listviews/buttons/customize.button.js +1 -1
- package/main/default/objects/object_triggers/fields/_name.field.yml +1 -0
- package/main/default/objects/object_triggers/fields/isEnabled.field.yml +1 -0
- package/main/default/objects/object_triggers/fields/listenTo.field.yml +1 -0
- package/main/default/objects/object_triggers/fields/name.field.yml +1 -0
- package/main/default/objects/object_triggers/fields/when.field.yml +1 -0
- package/main/default/objects/object_validation_rules/fields/active.field.yml +1 -0
- package/main/default/objects/object_validation_rules/fields/description.field.yml +1 -0
- package/main/default/objects/object_validation_rules/fields/name.field.yml +2 -0
- package/main/default/objects/object_validation_rules/fields/object_name.field.yml +1 -0
- package/main/default/objects/object_webhooks/fields/event.field.yml +2 -1
- package/main/default/objects/object_webhooks/fields/execute_when.field.yml +2 -1
- package/main/default/objects/object_webhooks/fields/name.field.yml +3 -1
- package/main/default/objects/object_webhooks/fields/object_name.field.yml +3 -1
- package/main/default/objects/object_webhooks/fields/payload_url.field.yml +3 -1
- package/main/default/objects/objects/fields/description.field.yml +1 -0
- package/main/default/objects/objects/fields/enable_form_tabs.field.yml +1 -0
- package/main/default/objects/objects/fields/in_development.field.yml +2 -0
- package/main/default/objects/objects/fields/is_customize.field.yml +1 -0
- package/main/default/objects/objects/fields/is_system.field.yml +1 -0
- package/main/default/objects/objects/listviews/customize.listview.yml +1 -1
- package/main/default/pages/design_field_layout.page.amis.json +3 -3
- package/main/default/pages/object_detail.page.amis.json +13 -0
- package/main/default/server/object_fields.object.js +1 -1
- package/main/default/server/objects.core.js +4 -0
- package/main/default/server/objects.object.js +2 -1
- package/main/default/services/suggestions.service.js +92 -0
- package/main/default/triggers/datasources.trigger.js +5 -0
- package/main/default/triggers/object_functions.trigger.js +104 -0
- package/main/default/triggers/object_triggers.trigger.js +2 -2
- package/main/default/triggers/objects.trigger.js +20 -3
- package/package.json +5 -5
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
name: object_functions
|
|
2
|
+
label: Object Functions
|
|
3
|
+
description:
|
|
4
|
+
fields:
|
|
5
|
+
_name:
|
|
6
|
+
label: API Name
|
|
7
|
+
help: >-
|
|
8
|
+
Can only contain lowercase letters and numbers, must start with a letter,
|
|
9
|
+
cannot end with an underscore character or contain two consecutive
|
|
10
|
+
underscore characters
|
|
11
|
+
description:
|
|
12
|
+
is_rest:
|
|
13
|
+
label: Enable API
|
|
14
|
+
help:
|
|
15
|
+
description: allow the use of api interface access:{POST/GET} /api/v1/:objectName/functions/:functionApiName
|
|
16
|
+
is_system:
|
|
17
|
+
label: System
|
|
18
|
+
help:
|
|
19
|
+
description:
|
|
20
|
+
isEnabled:
|
|
21
|
+
label: Enable
|
|
22
|
+
help:
|
|
23
|
+
description:
|
|
24
|
+
name:
|
|
25
|
+
label: Name
|
|
26
|
+
help:
|
|
27
|
+
description:
|
|
28
|
+
objectApiName:
|
|
29
|
+
label: Object
|
|
30
|
+
help:
|
|
31
|
+
description:
|
|
32
|
+
script:
|
|
33
|
+
label: Script
|
|
34
|
+
help:
|
|
35
|
+
description: |
|
|
36
|
+
async function run(ctx) {
|
|
37
|
+
// ...
|
|
38
|
+
}
|
|
39
|
+
description:
|
|
40
|
+
label: Description
|
|
41
|
+
help:
|
|
42
|
+
description:
|
|
43
|
+
listviews:
|
|
44
|
+
all:
|
|
45
|
+
label: All
|
|
46
|
+
customize:
|
|
47
|
+
label: Customize
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
name: object_functions
|
|
2
|
+
label: 对象函数
|
|
3
|
+
description:
|
|
4
|
+
fields:
|
|
5
|
+
_name:
|
|
6
|
+
label: API 名称
|
|
7
|
+
help: API 名称只能包含小写字母、数字,必须以字母开头,不能以下划线字符结尾或包含两个连续的下划线字符
|
|
8
|
+
description:
|
|
9
|
+
is_rest:
|
|
10
|
+
label: 启用API
|
|
11
|
+
help:
|
|
12
|
+
description: 允许使用API接口访问:{POST/GET} /api/v1/:objectName/functions/:functionApiName
|
|
13
|
+
is_system:
|
|
14
|
+
label: 系统
|
|
15
|
+
help:
|
|
16
|
+
description:
|
|
17
|
+
isEnabled:
|
|
18
|
+
label: 已启用
|
|
19
|
+
help:
|
|
20
|
+
description:
|
|
21
|
+
name:
|
|
22
|
+
label: 名称
|
|
23
|
+
help:
|
|
24
|
+
description:
|
|
25
|
+
objectApiName:
|
|
26
|
+
label: 所属对象
|
|
27
|
+
help:
|
|
28
|
+
description:
|
|
29
|
+
script:
|
|
30
|
+
label: 代码
|
|
31
|
+
help:
|
|
32
|
+
description: |
|
|
33
|
+
async function run(ctx) {
|
|
34
|
+
// ...
|
|
35
|
+
}
|
|
36
|
+
description:
|
|
37
|
+
label: 备注
|
|
38
|
+
help:
|
|
39
|
+
description:
|
|
40
|
+
listviews:
|
|
41
|
+
all:
|
|
42
|
+
label: 所有
|
|
43
|
+
customize:
|
|
44
|
+
label: 自定义
|
|
@@ -56,7 +56,7 @@ fields:
|
|
|
56
56
|
description:
|
|
57
57
|
enable_form_tabs:
|
|
58
58
|
label: Enable Form Tabs
|
|
59
|
-
help:
|
|
59
|
+
help: Displays groups in tabbed mode in the form, recognizing this property only when editing mode.
|
|
60
60
|
description:
|
|
61
61
|
enable_events:
|
|
62
62
|
label: Enable Events
|
|
@@ -6,4 +6,4 @@ hidden: false
|
|
|
6
6
|
label: Is Name
|
|
7
7
|
sort_no: 650
|
|
8
8
|
type: boolean
|
|
9
|
-
visible_on: ${ARRAYSOME(['text', 'textarea', 'autonumber', 'date', 'datetime', 'time', 'formula', 'lookup'], item => item === type) && !multiple}
|
|
9
|
+
visible_on: ${ARRAYSOME(['text', 'textarea', 'autonumber', 'date', 'datetime', 'time', 'formula', 'lookup', 'master_detail'], item => item === type) && !multiple}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* @Author: 孙浩林 sunhaolin@steedos.com
|
|
3
|
+
* @Date: 2024-05-14 17:04:31
|
|
4
|
+
* @LastEditors: 孙浩林 sunhaolin@steedos.com
|
|
5
|
+
* @LastEditTime: 2024-05-14 17:04:36
|
|
6
|
+
* @FilePath: /steedos-platform-2.3/services/standard-object-database/main/default/objects/object_functions/buttons/standard_new.button.js
|
|
7
|
+
* @Description:
|
|
8
|
+
*/
|
|
9
|
+
module.exports = {
|
|
10
|
+
standard_newVisible: function (object_name, record_id, record_permissions, data) {
|
|
11
|
+
if(Meteor.settings.public.enable_saas){
|
|
12
|
+
return false;
|
|
13
|
+
}
|
|
14
|
+
return Creator.baseObject.actions.standard_new.visible.apply(this, arguments);
|
|
15
|
+
},
|
|
16
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
name: script
|
|
2
|
+
label: Script
|
|
3
|
+
type: code
|
|
4
|
+
language: javascript
|
|
5
|
+
is_wide: true
|
|
6
|
+
required: true
|
|
7
|
+
defaultValue: |-
|
|
8
|
+
// global: {_:lodash, moment, validator, filters}
|
|
9
|
+
// objects
|
|
10
|
+
// ctx: {input, params, broker, getObject, getUser}
|
|
11
|
+
editorDidMount: >-
|
|
12
|
+
if(window._registerCompletionItemProviderFunction){
|
|
13
|
+
return ;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
window._registerCompletionItemProviderFunction = true;
|
|
17
|
+
|
|
18
|
+
const result = Steedos.authRequest("/service/api/suggestions/function.d.ts",
|
|
19
|
+
{async: false});
|
|
20
|
+
|
|
21
|
+
monaco.languages.typescript.javascriptDefaults.addExtraLib(
|
|
22
|
+
result
|
|
23
|
+
);
|
|
24
|
+
sort_no: 150
|
|
@@ -26,6 +26,6 @@ customize:function (object_name, record_id, fields) {
|
|
|
26
26
|
},
|
|
27
27
|
customizeVisible:function(object_name, record_id, record_permissions, data){
|
|
28
28
|
var record = data && data.record;
|
|
29
|
-
return Creator.baseObject.actions.standard_new.visible() && record.is_system;
|
|
29
|
+
return Creator.baseObject.actions.standard_new.visible(object_name) && record.is_system;
|
|
30
30
|
}
|
|
31
31
|
}
|
|
@@ -4,4 +4,6 @@ type: text
|
|
|
4
4
|
is_wide: true
|
|
5
5
|
# regEx: /^(?:(?:https?|ftp):\/\/)(?:\S+(?::\S*)?@)?(?:(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]+-?)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]+-?)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,})))(?::\d{2,5})?(?:\/[^\s]*)?$/i
|
|
6
6
|
required: true
|
|
7
|
-
sort_no: 70
|
|
7
|
+
sort_no: 70
|
|
8
|
+
filterable: true
|
|
9
|
+
searchable: true
|
|
@@ -162,7 +162,7 @@
|
|
|
162
162
|
"actions": [
|
|
163
163
|
{
|
|
164
164
|
"actionType": "custom",
|
|
165
|
-
"script": "///整理分组数据\nconst defaultGroupName = \"未分组\";\nconst hiddenGroupName = \"隐藏\";\nlet setting_groups = _.cloneDeep(event.data.groups);\nif (!_.find(setting_groups, { is_default: true })) {\n setting_groups.unshift({\n \"id\": \"default-group\",\n \"group_name\": defaultGroupName,\n \"visible_on\": \"\",\n \"is_default\": true\n })\n}\nif (!_.find(setting_groups, { is_hidden: true })) {\n setting_groups.push({\n id: \"hidden-group\",\n group_name: hiddenGroupName,\n visible_on: \"\",\n is_hidden: true\n });\n}\nsetting_groups.forEach(function (group) {\n if (!group.id) {\n group.id = window.
|
|
165
|
+
"script": "///整理分组数据\nconst defaultGroupName = \"未分组\";\nconst hiddenGroupName = \"隐藏\";\nlet setting_groups = _.cloneDeep(event.data.groups);\nif (!_.find(setting_groups, { is_default: true })) {\n setting_groups.unshift({\n \"id\": \"default-group\",\n \"group_name\": defaultGroupName,\n \"visible_on\": \"\",\n \"is_default\": true\n })\n}\nif (!_.find(setting_groups, { is_hidden: true })) {\n setting_groups.push({\n id: \"hidden-group\",\n group_name: hiddenGroupName,\n visible_on: \"\",\n is_hidden: true\n });\n}\nsetting_groups.forEach(function (group) {\n if (!group.id) {\n group.id = window.BuilderAmisObject.AmisLib.uuidv4();\n }\n if (/\\$\\{.+\\}/.test(group.visible_on)) {\n group.visible_on = group.visible_on.replaceAll('${', '\\\\${');\n }\n})\n\n//整理字段与分组关系的数据\nlet design_field = {};\nlet oldGroup = _.cloneDeep(event.data.design_field);\nsetting_groups.forEach(function (group) {\n if (_.has(oldGroup, group.id)) {\n design_field[group.id] = oldGroup[group.id];\n oldGroup = _.omit(oldGroup, group.id);\n } else {\n design_field[group.id] = [];\n }\n})\n//当有分组被删除时,会进入以下if,将该分组下所有字段放入未分组中\nif (oldGroup && !_.isEmpty(oldGroup)) {\n _.forEach(oldGroup, function (value, key) {\n design_field[\"default-group\"] = _.unionBy(design_field[\"default-group\"], value);\n });\n}\n\n//未分组 放在所有分组开头,隐藏 放在所有分组最后\nconst defaultGroup = design_field['default-group'];\nconst hiddenGroup = design_field['hidden-group'];\ndelete design_field['default-group'];\ndelete design_field['hidden-group'];\ndesign_field = _.merge({ 'default-group': defaultGroup }, design_field, { 'hidden-group': hiddenGroup });\n\n//根据design_field调整groups顺序,设置分组与保存时需要groups按照顺序\nconst keys = _.keys(design_field);\nsetting_groups = _.sortBy(setting_groups, function (group) { return _.findIndex(keys, function (key) { return key == group.id }) });\n\ndoAction({\n actionType: 'setValue',\n componentId: 'form_field_design',\n args: {\n value: {\n groups: setting_groups,\n design_field\n }\n }\n});"
|
|
166
166
|
},
|
|
167
167
|
{
|
|
168
168
|
"actionType": "closeDialog"
|
|
@@ -476,7 +476,7 @@
|
|
|
476
476
|
},
|
|
477
477
|
"messages": {},
|
|
478
478
|
"requestAdaptor": "",
|
|
479
|
-
"adaptor": "//筛选出可编辑的字段\nvar oldFields = _.filter(payload.data.fields, function (obj) { return obj.recordPermissions.allowEdit; });\n//将group为空的字段分为未分组的组中,将系统字段的_id改为对象名.字段名\noldFields = _.map(oldFields, function (obj) {\n obj.originId = obj._id;\n if (obj.hidden || obj.visible_on == \"{{false}}\") {\n obj.group = \"隐藏\";\n }else if (obj.group === null) {\n obj.group = \"未分组\";\n }\n if (obj.is_system) {\n obj._id = api.data.designObjectName + \".\" + obj._name;\n }\n return obj;\n});\n\n//整合出字段的属性集合\nconst fields = oldFields.map((field) => {\n return {\n \"id\": field._id,//用与steedos-board组件的关系分辨\n \"_name\": field._name,\n \"label\": field.label,\n \"_id\": field.originId,//用于打开steedos-object-form\n \"columnSpan\": field.is_wide ? 2 : 1,\n \"is_system\": field.is_system,\n \"type\": field.type,\n \"attr_visible_on\": field.visible_on\n }\n})\n\n//去重并去除隐藏和未分组\nlet newArray = _.reject(_.uniqBy(oldFields, \"group\"), function(obj) {\n return obj.group == \"隐藏\" || obj.group == \"未分组\";\n});\n//从字段的group属性中,整合出字段分组的属性集合\nlet field_groups = _.map(newArray, function (obj) {\n return {\n \"id\": window.
|
|
479
|
+
"adaptor": "//筛选出可编辑的字段\nvar oldFields = _.filter(payload.data.fields, function (obj) { return obj.recordPermissions.allowEdit; });\n//将group为空的字段分为未分组的组中,将系统字段的_id改为对象名.字段名\noldFields = _.map(oldFields, function (obj) {\n obj.originId = obj._id;\n if (obj.hidden || obj.visible_on == \"{{false}}\") {\n obj.group = \"隐藏\";\n }else if (obj.group === null) {\n obj.group = \"未分组\";\n }\n if (obj.is_system) {\n obj._id = api.data.designObjectName + \".\" + obj._name;\n }\n return obj;\n});\n\n//整合出字段的属性集合\nconst fields = oldFields.map((field) => {\n return {\n \"id\": field._id,//用与steedos-board组件的关系分辨\n \"_name\": field._name,\n \"label\": field.label,\n \"_id\": field.originId,//用于打开steedos-object-form\n \"columnSpan\": field.is_wide ? 2 : 1,\n \"is_system\": field.is_system,\n \"type\": field.type,\n \"attr_visible_on\": field.visible_on\n }\n})\n\n//去重并去除隐藏和未分组\nlet newArray = _.reject(_.uniqBy(oldFields, \"group\"), function(obj) {\n return obj.group == \"隐藏\" || obj.group == \"未分组\";\n});\n//从字段的group属性中,整合出字段分组的属性集合\nlet field_groups = _.map(newArray, function (obj) {\n return {\n \"id\": window.BuilderAmisObject.AmisLib.uuidv4(), \n \"group_name\": obj.group,\n \"visible_on\": \"\"\n };\n});\n\n//合并对象上的field_groups与字段上的group\nlet groups = _.unionBy(api.data.field_groups, field_groups, 'group_name');\n\n//判断是否第一次调用接口,不是的话(说明是触发了datachange事件),返回fields与fieldUpdateData;目前新增与删除都不支持\nif (api.data.dataInitialed) {\n const eventData = api.data.eventData;\n let fieldUpdateData = \"\";\n const fieldForGroup = api.data.fieldForGroup;\n let fieldForGroupLength = 0;\n _.forIn(fieldForGroup, function (value, key) {\n fieldForGroupLength += value.length;\n });\n if (fieldForGroupLength < fields.length) {\n fieldUpdateData = {\n type: \"insert\",\n id: eventData.result.data.recordId\n }\n } else if (fieldForGroupLength > fields.length) {\n fieldUpdateData = {\n type: \"delete\",\n id: eventData._id\n }\n }\n return payload = {\n data: {\n fields,\n fieldUpdateData\n }\n }\n}\n\n//整合字段与分组的关系\nconst oldFieldsInGroups = _.groupBy(oldFields, \"group\");\nlet fieldForGroup = _.mapValues(_.groupBy(groups, \"id\"), function (group,key) {\n if (oldFieldsInGroups[group[0].group_name]) {\n return _.map(oldFieldsInGroups[group[0].group_name], function (obj) {\n return obj._id;\n });\n } else {\n return [];\n }\n});\n\n//未分组 放在所有分组开头,隐藏 放在所有分组最后\nconst defaultGroupId = _.find(groups, { 'is_default': true }).id;\nconst hiddenGroupId = _.find(groups, { 'is_hidden': true }).id;\nconst defaultGroup = fieldForGroup[defaultGroupId];\nconst hiddenGroup = fieldForGroup[hiddenGroupId];\ndelete fieldForGroup[defaultGroupId];\ndelete fieldForGroup[hiddenGroupId];\nfieldForGroup = _.merge({ [defaultGroupId]: defaultGroup }, fieldForGroup, { [hiddenGroupId]: hiddenGroup });\n\n//根据fieldForGroup调整groups顺序,设置分组与保存时需要groups按照顺序\nconst keys = _.keys(fieldForGroup);\ngroups = _.sortBy(groups, function (group) { return _.findIndex(keys, function (key) { return key == group.id }) });\n\nreturn payload = {\n data: {\n fields,\n groups,\n fieldForGroup,\n dataInitialed: true\n }\n};",
|
|
480
480
|
"sendOn": "!!this.designObjectId"
|
|
481
481
|
},
|
|
482
482
|
"messages": {},
|
|
@@ -510,7 +510,7 @@
|
|
|
510
510
|
},
|
|
511
511
|
"messages": {},
|
|
512
512
|
"requestAdaptor": "",
|
|
513
|
-
"adaptor": "const field_groups = payload.data.objects[0] && _.map(payload.data.objects[0].field_groups, function (obj) {\n return {\n \"id\": window.
|
|
513
|
+
"adaptor": "const field_groups = payload.data.objects[0] && _.map(payload.data.objects[0].field_groups, function (obj) {\n return {\n \"id\": window.BuilderAmisObject.AmisLib.uuidv4(), //唯一性id\n \"group_name\": obj.group_name,\n \"visible_on\": obj.visible_on,\n \"collapsed\": obj.collapsed\n }\n});\nfield_groups.unshift({\n id: \"hidden-group\",\n group_name: \"隐藏\",\n visible_on: \"\",\n is_hidden: true\n});\nfield_groups.unshift({\n id: \"default-group\",\n group_name: \"未分组\",\n visible_on: \"\",\n is_default: true\n});\n\n\n\nconst designObjectId = payload.data.objects[0] && payload.data.objects[0]._id;\nreturn payload = {\n data: {\n field_groups,\n designObjectId,\n designObjectLabel: payload.data.objects[0] && payload.data.objects[0].label,\n _master: {\n recordId: designObjectId\n }\n }\n}"
|
|
514
514
|
},
|
|
515
515
|
"messages": {},
|
|
516
516
|
"onEvent": {
|
|
@@ -176,6 +176,19 @@
|
|
|
176
176
|
"perPage": 20
|
|
177
177
|
}
|
|
178
178
|
]
|
|
179
|
+
},
|
|
180
|
+
{
|
|
181
|
+
"title": "${'objects_amis_functions' | t}",
|
|
182
|
+
"body": [
|
|
183
|
+
{
|
|
184
|
+
"type": "steedos-object-related-listview",
|
|
185
|
+
"objectApiName": "objects",
|
|
186
|
+
"recordId": "${recordId}",
|
|
187
|
+
"relatedObjectApiName": "object_functions",
|
|
188
|
+
"relatedKey": "objectApiName",
|
|
189
|
+
"perPage": 20
|
|
190
|
+
}
|
|
191
|
+
]
|
|
179
192
|
}
|
|
180
193
|
],
|
|
181
194
|
"id": "u:6a3b45d7adcf",
|
|
@@ -299,7 +299,7 @@ function allowChangeObject(){
|
|
|
299
299
|
}
|
|
300
300
|
|
|
301
301
|
function checkNameField(nameField){
|
|
302
|
-
if(["text", "textarea", "autonumber", "date", "datetime", "time", "formula", "lookup"].indexOf(nameField.type) < 0){
|
|
302
|
+
if(["text", "textarea", "autonumber", "date", "datetime", "time", "formula", "lookup", "master_detail"].indexOf(nameField.type) < 0){
|
|
303
303
|
throw new Error("只有文本、长文本、自动编号、日期、日期时间、时间、公式、相关表这些类型的字段可以被设置为名称字段");
|
|
304
304
|
} else if(nameField.type == "lookup" && nameField.multiple) {
|
|
305
305
|
throw new Error("多选的相关表字段不可以被设置为名称字段");
|
|
@@ -349,6 +349,10 @@ function reloadObject(changeLog){
|
|
|
349
349
|
//获取到最新的对象
|
|
350
350
|
const object = register.getOriginalObjectConfig(objectName);
|
|
351
351
|
|
|
352
|
+
if (object.name) {
|
|
353
|
+
delete object.extend; // 因为objects.addConfig中会将extend赋值给name导致metadataApiName错误,故这里提前删除。
|
|
354
|
+
}
|
|
355
|
+
|
|
352
356
|
let _mf = _.max(_.values(object.fields), function (field) { return field.sort_no; });
|
|
353
357
|
if(_mf && object.name){
|
|
354
358
|
object.fields_serial_number = _mf.sort_no + 10;
|
|
@@ -129,6 +129,98 @@ module.exports = {
|
|
|
129
129
|
${servicesTypes}
|
|
130
130
|
`
|
|
131
131
|
}
|
|
132
|
+
},
|
|
133
|
+
functionTSExtraLib: {
|
|
134
|
+
rest: {
|
|
135
|
+
method: "GET",
|
|
136
|
+
path: "/function.d.ts",
|
|
137
|
+
},
|
|
138
|
+
async handler(ctx) {
|
|
139
|
+
let objectsTypes = 'declare const objects: {';
|
|
140
|
+
_.each(global.objects, (v, k)=>{
|
|
141
|
+
objectsTypes = `${objectsTypes} ${k}: SteedosObjectType;`
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
objectsTypes = objectsTypes + '}'
|
|
145
|
+
|
|
146
|
+
return `
|
|
147
|
+
|
|
148
|
+
declare var global = {_: any, moment: any, validator: any, filters: any};
|
|
149
|
+
|
|
150
|
+
declare type Params = {
|
|
151
|
+
userId: SteedosIDType;
|
|
152
|
+
spaceId?: SteedosIDType;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
declare type CTXType = {
|
|
156
|
+
input: any;
|
|
157
|
+
params: Params;
|
|
158
|
+
broker: {
|
|
159
|
+
meta: any;
|
|
160
|
+
call: any;
|
|
161
|
+
mcall: any;
|
|
162
|
+
emit: any;
|
|
163
|
+
broadcast: any;
|
|
164
|
+
broadcastLocal: any;
|
|
165
|
+
namespace: string;
|
|
166
|
+
nodeID: string;
|
|
167
|
+
instanceID: string;
|
|
168
|
+
logger: any;
|
|
169
|
+
metadata: any;
|
|
170
|
+
},
|
|
171
|
+
getObject(objectName: string): SteedosObjectType;
|
|
172
|
+
getUser(userId: string, spaceId: string): Promise<SteedosUserSession>;
|
|
173
|
+
};
|
|
174
|
+
|
|
175
|
+
declare var ctx: CTXType;
|
|
176
|
+
|
|
177
|
+
declare type SteedosQueryFilters = any;
|
|
178
|
+
declare type SteedosIDType = number | string;
|
|
179
|
+
declare type SteedosQueryOptions = {
|
|
180
|
+
fields?: Array<string> | string;
|
|
181
|
+
readonly filters?: SteedosQueryFilters;
|
|
182
|
+
readonly top?: number;
|
|
183
|
+
readonly skip?: number;
|
|
184
|
+
readonly sort?: string;
|
|
185
|
+
};
|
|
186
|
+
declare type SteedosUserSession = {
|
|
187
|
+
userId: SteedosIDType;
|
|
188
|
+
spaceId?: string;
|
|
189
|
+
name: string;
|
|
190
|
+
username?: string;
|
|
191
|
+
mobile?: string;
|
|
192
|
+
email?: string;
|
|
193
|
+
utcOffset?: number;
|
|
194
|
+
locale?: string;
|
|
195
|
+
roles?: string[];
|
|
196
|
+
space?: any;
|
|
197
|
+
spaces?: any;
|
|
198
|
+
company?: any;
|
|
199
|
+
companies?: any;
|
|
200
|
+
organization?: any;
|
|
201
|
+
organizations?: any;
|
|
202
|
+
permission_shares?: any;
|
|
203
|
+
company_id?: string;
|
|
204
|
+
company_ids?: string[];
|
|
205
|
+
is_space_admin?: boolean;
|
|
206
|
+
steedos_id?: string;
|
|
207
|
+
};
|
|
208
|
+
declare class SteedosObjectType {
|
|
209
|
+
find(query: SteedosQueryOptions, userSession?: SteedosUserSession): Promise<any>;
|
|
210
|
+
findOne(id: SteedosIDType, query: SteedosQueryOptions, userSession?: SteedosUserSession): Promise<any>;
|
|
211
|
+
insert(doc: Dictionary<any>, userSession?: SteedosUserSession): Promise<any>;
|
|
212
|
+
update(id: SteedosIDType, doc: Dictionary<any>, userSession?: SteedosUserSession): Promise<any>;
|
|
213
|
+
delete(id: SteedosIDType, userSession?: SteedosUserSession): Promise<any>;
|
|
214
|
+
directFind(query: SteedosQueryOptions, userSession?: SteedosUserSession): Promise<any>;
|
|
215
|
+
directInsert(doc: Dictionary<any>, userSession?: SteedosUserSession): Promise<any>;
|
|
216
|
+
directUpdate(id: SteedosIDType, doc: Dictionary<any>, userSession?: SteedosUserSession): Promise<any>;
|
|
217
|
+
directDelete(id: SteedosIDType, userSession?: SteedosUserSession): Promise<any>;
|
|
218
|
+
count(query: SteedosQueryOptions, userSession?: SteedosUserSession): Promise<any>;
|
|
219
|
+
_makeNewID(): Promise<any>;
|
|
220
|
+
}
|
|
221
|
+
${objectsTypes}
|
|
222
|
+
`
|
|
223
|
+
}
|
|
132
224
|
}
|
|
133
225
|
},
|
|
134
226
|
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* @Author: 孙浩林 sunhaolin@steedos.com
|
|
3
|
+
* @Date: 2024-05-13 14:20:37
|
|
4
|
+
* @LastEditors: 孙浩林 sunhaolin@steedos.com
|
|
5
|
+
* @LastEditTime: 2024-05-18 14:12:38
|
|
6
|
+
* @FilePath: /steedos-platform-2.3/services/standard-object-database/main/default/triggers/object_functions.trigger.js
|
|
7
|
+
* @Description:
|
|
8
|
+
*/
|
|
9
|
+
const _ = require('lodash');
|
|
10
|
+
const objectql = require('@steedos/objectql');
|
|
11
|
+
const auth = require('@steedos/auth');
|
|
12
|
+
const validator = require('validator');
|
|
13
|
+
const PERMISSIONS = {
|
|
14
|
+
allowEdit: false,
|
|
15
|
+
allowDelete: false,
|
|
16
|
+
allowRead: true,
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
const BASERECORD = {
|
|
20
|
+
is_system: true,
|
|
21
|
+
record_permissions: PERMISSIONS
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
const APINAMEM_MULTI_MSG = '函数Api Name不能重复';
|
|
25
|
+
const METADATA_CACHER_SERVICE_NAME = 'metadata-cachers-service'
|
|
26
|
+
|
|
27
|
+
const getSourceFunctions = async () => {
|
|
28
|
+
const fDocs = await broker.call(`${METADATA_CACHER_SERVICE_NAME}.find`, { metadataName: 'object_functions' });
|
|
29
|
+
const data = _.map(_.filter(fDocs, (item)=>{
|
|
30
|
+
return !item._id || item._id == item.name
|
|
31
|
+
}), (item) => {
|
|
32
|
+
return {
|
|
33
|
+
...item,
|
|
34
|
+
_id: item.name,
|
|
35
|
+
...BASERECORD
|
|
36
|
+
};
|
|
37
|
+
});
|
|
38
|
+
return data;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function checkVariableName(variableName) {
|
|
42
|
+
if (variableName.length > 50) {
|
|
43
|
+
throw new Error("名称长度不能大于50个字符");
|
|
44
|
+
}
|
|
45
|
+
var reg = /^[a-zA-Z_$][a-zA-Z0-9_$]*$/;
|
|
46
|
+
if (reg.test(variableName)) {
|
|
47
|
+
var keywords = ['break', 'case', 'catch', 'continue', 'debugger', 'default', 'delete', 'do', 'else', 'finally', 'for', 'function', 'if', 'in', 'instanceof', 'new', 'return', 'switch', 'this', 'throw', 'try', 'typeof', 'var', 'void', 'while', 'with', 'true', 'false', 'null', 'undefined', 'NaN', 'Infinity'];
|
|
48
|
+
if (keywords.indexOf(variableName) === -1) {
|
|
49
|
+
return true;
|
|
50
|
+
} else {
|
|
51
|
+
throw new Error("名称不能包含关键字");
|
|
52
|
+
}
|
|
53
|
+
} else {
|
|
54
|
+
throw new Error("名称只能包含字母、数字,必须以字母开头");
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
module.exports = {
|
|
59
|
+
beforeFind: async function () {
|
|
60
|
+
delete this.query.fields;
|
|
61
|
+
},
|
|
62
|
+
afterFind: async function () {
|
|
63
|
+
let spaceId = this.spaceId;
|
|
64
|
+
let sourceData = await getSourceFunctions();
|
|
65
|
+
this.data.values = this.data.values.concat(sourceData);
|
|
66
|
+
this.data.values = objectql.getSteedosSchema().metadataDriver.find(this.data.values, this.query, spaceId);
|
|
67
|
+
},
|
|
68
|
+
afterCount: async function () {
|
|
69
|
+
let spaceId = this.spaceId;
|
|
70
|
+
this.data.values = this.data.values + objectql.getSteedosSchema().metadataDriver.count(await getSourceFunctions(), this.query, spaceId);
|
|
71
|
+
},
|
|
72
|
+
afterFindOne: async function () {
|
|
73
|
+
let spaceId = this.spaceId;
|
|
74
|
+
if (_.isEmpty(this.data.values)) {
|
|
75
|
+
const records = objectql.getSteedosSchema().metadataDriver.find(await getSourceFunctions(), { filters: ['_id', '=', this.id] }, spaceId);
|
|
76
|
+
if (records.length > 0) {
|
|
77
|
+
this.data.values = records[0]
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
},
|
|
81
|
+
beforeInsert: async function () {
|
|
82
|
+
if (validator.toBoolean(process.env.STEEDOS_TENANT_ENABLE_SAAS || 'false', true) == true) {
|
|
83
|
+
throw new Error('No permission')
|
|
84
|
+
}
|
|
85
|
+
const doc = this.doc;
|
|
86
|
+
checkVariableName(doc._name)
|
|
87
|
+
const count = await objectql.getObject(this.object_name).count({ filters: [['_name', '=', doc._name], ['objectApiName', '=', doc.objectApiName]] })
|
|
88
|
+
if (count > 0) {
|
|
89
|
+
throw new Error(APINAMEM_MULTI_MSG)
|
|
90
|
+
}
|
|
91
|
+
doc.name = `${doc.objectApiName}_${doc._name}`
|
|
92
|
+
},
|
|
93
|
+
beforeUpdate: async function () {
|
|
94
|
+
const doc = this.doc;
|
|
95
|
+
if (doc._name) {
|
|
96
|
+
checkVariableName(doc._name)
|
|
97
|
+
}
|
|
98
|
+
const count = await objectql.getObject(this.object_name).count({ filters: [['_name', '=', doc._name], ['objectApiName', '=', doc.objectApiName], ['_id', '!=', this.id]] })
|
|
99
|
+
if (count > 0) {
|
|
100
|
+
throw new Error(APINAMEM_MULTI_MSG)
|
|
101
|
+
}
|
|
102
|
+
doc.name = `${doc.objectApiName}_${doc._name}`
|
|
103
|
+
}
|
|
104
|
+
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/*
|
|
2
2
|
* @Author: sunhaolin@hotoa.com
|
|
3
3
|
* @Date: 2021-06-03 15:11:52
|
|
4
|
-
* @LastEditors:
|
|
5
|
-
* @LastEditTime:
|
|
4
|
+
* @LastEditors: 孙浩林 sunhaolin@steedos.com
|
|
5
|
+
* @LastEditTime: 2024-05-18 14:06:18
|
|
6
6
|
* @Description:
|
|
7
7
|
*/
|
|
8
8
|
const Cache = require('@steedos/cachers');
|
|
@@ -2,7 +2,7 @@ const InternalData = require('@steedos/standard-objects').internalData;
|
|
|
2
2
|
const _ = require('underscore');
|
|
3
3
|
const objectql = require('@steedos/objectql');
|
|
4
4
|
const objectTree = require('../server/objects.tree.js');
|
|
5
|
-
|
|
5
|
+
const clone = require('clone');
|
|
6
6
|
const sleep = async (ms) => new Promise(resolve => setTimeout(resolve, ms));
|
|
7
7
|
|
|
8
8
|
module.exports = {
|
|
@@ -18,13 +18,25 @@ module.exports = {
|
|
|
18
18
|
let userId = this.userId
|
|
19
19
|
let spaceId = this.spaceId;
|
|
20
20
|
|
|
21
|
+
let filters = InternalData.parserFilters(this.query.filters);
|
|
22
|
+
|
|
21
23
|
_.each(this.data.values, (item)=>{
|
|
22
24
|
item.is_customize = true
|
|
23
25
|
})
|
|
24
26
|
|
|
25
|
-
|
|
27
|
+
let cloneValues = clone(this.data.values, false);
|
|
28
|
+
|
|
29
|
+
if(filters.is_customize){
|
|
30
|
+
const dbObjects = await objectql.getObject('objects').directFind({space: spaceId});
|
|
31
|
+
_.each(dbObjects, (item)=>{
|
|
32
|
+
item.is_customize = true
|
|
33
|
+
})
|
|
34
|
+
cloneValues = cloneValues.concat(dbObjects);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
cloneValues = cloneValues.concat(await InternalData.getObjects(userId));
|
|
26
38
|
|
|
27
|
-
this.data.values = objectql.getSteedosSchema().metadataDriver.find(
|
|
39
|
+
this.data.values = objectql.getSteedosSchema().metadataDriver.find(cloneValues, this.query, spaceId);
|
|
28
40
|
|
|
29
41
|
_.each(this.data.values, function(value){
|
|
30
42
|
if(value){
|
|
@@ -39,6 +51,11 @@ module.exports = {
|
|
|
39
51
|
afterCount: async function(){
|
|
40
52
|
let userId = this.userId
|
|
41
53
|
let spaceId = this.spaceId;
|
|
54
|
+
let filters = InternalData.parserFilters(this.query.filters);
|
|
55
|
+
if(filters.is_customize){
|
|
56
|
+
const dbObjects = await objectql.getObject('objects').directFind({space: spaceId});
|
|
57
|
+
return this.data.values = dbObjects.length;
|
|
58
|
+
}
|
|
42
59
|
this.data.values = this.data.values + objectql.getSteedosSchema().metadataDriver.count(await InternalData.getObjects(userId), this.query, spaceId);
|
|
43
60
|
},
|
|
44
61
|
afterFindOne: async function(){
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@steedos/standard-object-database",
|
|
3
|
-
"version": "2.7.
|
|
3
|
+
"version": "2.7.2-beta.1",
|
|
4
4
|
"main": "package.service.js",
|
|
5
5
|
"private": false,
|
|
6
6
|
"publishConfig": {
|
|
@@ -12,14 +12,14 @@
|
|
|
12
12
|
"description": "steedos package",
|
|
13
13
|
"dependencies": {
|
|
14
14
|
"@steedos-widgets/amis-lib": "^1.0.22",
|
|
15
|
-
"@steedos/metadata-core": "2.7.
|
|
16
|
-
"@steedos/service-object-mixin": "2.7.
|
|
17
|
-
"@steedos/standard-objects": "2.7.
|
|
15
|
+
"@steedos/metadata-core": "2.7.2-beta.1",
|
|
16
|
+
"@steedos/service-object-mixin": "2.7.2-beta.1",
|
|
17
|
+
"@steedos/standard-objects": "2.7.2-beta.1",
|
|
18
18
|
"amis-formula": "~6.3.0",
|
|
19
19
|
"clone": "^2.1.2",
|
|
20
20
|
"moleculer-bullmq": "3.0.0"
|
|
21
21
|
},
|
|
22
22
|
"repository": {},
|
|
23
23
|
"license": "MIT",
|
|
24
|
-
"gitHead": "
|
|
24
|
+
"gitHead": "666aa721be857f2a029c35cc03fbb94910367b24"
|
|
25
25
|
}
|