@steedos/objectql 2.2.50 → 2.2.51-beta.4
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/lib/services/helpers/graphql/consts.d.ts +17 -0
- package/lib/services/helpers/graphql/consts.js +28 -0
- package/lib/services/helpers/graphql/consts.js.map +1 -0
- package/lib/services/helpers/graphql/getQueryFields.js +17 -2
- package/lib/services/helpers/graphql/getQueryFields.js.map +1 -1
- package/lib/services/helpers/graphql/index.d.ts +1 -1
- package/lib/services/helpers/graphql/index.js +31 -46
- package/lib/services/helpers/graphql/index.js.map +1 -1
- package/lib/util/index.js +7 -0
- package/lib/util/index.js.map +1 -1
- package/package.json +11 -12
- package/src/actions/field_updates.ts +0 -118
- package/src/actions/index.ts +0 -3
- package/src/actions/types/field_update_target.ts +0 -7
- package/src/actions/types/workflow_notification.ts +0 -9
- package/src/actions/types/workflow_rule.ts +0 -11
- package/src/actions/workflow_notifications.ts +0 -81
- package/src/actions/workflow_rule.ts +0 -136
- package/src/driver/driver.ts +0 -102
- package/src/driver/field-encrytion/index.ts +0 -8
- package/src/driver/field-encrytion/sharedconst.ts +0 -34
- package/src/driver/fieldDBType.ts +0 -14
- package/src/driver/format.ts +0 -36
- package/src/driver/index.ts +0 -20
- package/src/driver/metadata.ts +0 -226
- package/src/driver/meteorMongo.ts +0 -639
- package/src/driver/mongo.ts +0 -416
- package/src/driver/mysql.ts +0 -47
- package/src/driver/oracle.ts +0 -60
- package/src/driver/postgres.ts +0 -46
- package/src/driver/sqlite3.ts +0 -40
- package/src/driver/sqlserver.ts +0 -52
- package/src/dynamic-load/actions.ts +0 -146
- package/src/dynamic-load/approval_process.ts +0 -73
- package/src/dynamic-load/button.ts +0 -75
- package/src/dynamic-load/chart.ts +0 -22
- package/src/dynamic-load/client_script.ts +0 -65
- package/src/dynamic-load/field.ts +0 -77
- package/src/dynamic-load/flow_role.ts +0 -46
- package/src/dynamic-load/index.ts +0 -21
- package/src/dynamic-load/layout.ts +0 -53
- package/src/dynamic-load/listview.ts +0 -57
- package/src/dynamic-load/method.ts +0 -63
- package/src/dynamic-load/object_translations.ts +0 -61
- package/src/dynamic-load/originalObject.ts +0 -8
- package/src/dynamic-load/package.ts +0 -312
- package/src/dynamic-load/page.ts +0 -23
- package/src/dynamic-load/permission.ts +0 -71
- package/src/dynamic-load/permissionset.ts +0 -78
- package/src/dynamic-load/preload_data.ts +0 -104
- package/src/dynamic-load/profile.ts +0 -90
- package/src/dynamic-load/query.ts +0 -22
- package/src/dynamic-load/restrictionRules.ts +0 -23
- package/src/dynamic-load/role.ts +0 -46
- package/src/dynamic-load/shareRules.ts +0 -23
- package/src/dynamic-load/tab.ts +0 -17
- package/src/dynamic-load/tabs.ts +0 -13
- package/src/dynamic-load/translations.ts +0 -54
- package/src/dynamic-load/trigger.ts +0 -236
- package/src/dynamic-load/validation_rule.ts +0 -77
- package/src/dynamic-load/workflow.ts +0 -114
- package/src/errors/index.ts +0 -111
- package/src/formula/core.ts +0 -490
- package/src/formula/field_formula.ts +0 -107
- package/src/formula/index.ts +0 -81
- package/src/formula/params.ts +0 -197
- package/src/formula/recompute.ts +0 -65
- package/src/formula/simple_params.ts +0 -92
- package/src/formula/type.ts +0 -107
- package/src/formula/util.ts +0 -207
- package/src/index.ts +0 -24
- package/src/metadata-register/_base.ts +0 -85
- package/src/metadata-register/app.ts +0 -30
- package/src/metadata-register/chart.ts +0 -9
- package/src/metadata-register/index.ts +0 -123
- package/src/metadata-register/layout.ts +0 -38
- package/src/metadata-register/object.ts +0 -68
- package/src/metadata-register/page.ts +0 -9
- package/src/metadata-register/permissionFields.ts +0 -13
- package/src/metadata-register/permissionset.ts +0 -25
- package/src/metadata-register/process.ts +0 -16
- package/src/metadata-register/processTrigger.ts +0 -24
- package/src/metadata-register/profile.ts +0 -25
- package/src/metadata-register/query.ts +0 -9
- package/src/metadata-register/restrictionRules.ts +0 -12
- package/src/metadata-register/shareRules.ts +0 -13
- package/src/metadata-register/tab.ts +0 -9
- package/src/metadata-register/tabs.ts +0 -43
- package/src/services/datasourceServiceFactory.ts +0 -55
- package/src/services/helpers/graphql/getPrimaryFieldType.ts +0 -48
- package/src/services/helpers/graphql/getQueryFields.ts +0 -36
- package/src/services/helpers/graphql/index.ts +0 -681
- package/src/services/helpers/rest.ts +0 -57
- package/src/services/index.ts +0 -13
- package/src/services/objectService.ts +0 -846
- package/src/services/objectServiceDispatcher.ts +0 -209
- package/src/services/objectServiceFactory.ts +0 -29
- package/src/summary/core.ts +0 -263
- package/src/summary/field_summary.ts +0 -71
- package/src/summary/index.ts +0 -96
- package/src/summary/recompute.ts +0 -31
- package/src/summary/type.ts +0 -60
- package/src/ts-types/index.ts +0 -3
- package/src/ts-types/permissionset.ts +0 -8
- package/src/ts-types/profile.ts +0 -11
- package/src/ts-types/triggerActionParams.ts +0 -22
- package/src/typeorm/driver.ts +0 -379
- package/src/typeorm/index.ts +0 -3
- package/src/typeorm/util.ts +0 -147
- package/src/types/action.ts +0 -52
- package/src/types/app.ts +0 -280
- package/src/types/config.ts +0 -152
- package/src/types/connection.ts +0 -87
- package/src/types/dashboard.ts +0 -91
- package/src/types/datasource.ts +0 -570
- package/src/types/field.ts +0 -370
- package/src/types/field_permission.ts +0 -42
- package/src/types/field_types.ts +0 -1
- package/src/types/index.ts +0 -21
- package/src/types/list_view.ts +0 -56
- package/src/types/listeners.ts +0 -18
- package/src/types/object.ts +0 -2076
- package/src/types/object_dynamic_load.ts +0 -426
- package/src/types/object_events.ts +0 -43
- package/src/types/object_layouts.ts +0 -20
- package/src/types/object_permission.ts +0 -134
- package/src/types/query.ts +0 -28
- package/src/types/report.ts +0 -128
- package/src/types/restrictionRule.ts +0 -57
- package/src/types/schema.ts +0 -273
- package/src/types/shareRule.ts +0 -57
- package/src/types/trigger.ts +0 -88
- package/src/types/userSession.ts +0 -45
- package/src/types/validation_rules.ts +0 -29
- package/src/util/convert.ts +0 -131
- package/src/util/field.ts +0 -93
- package/src/util/function_expression.ts +0 -63
- package/src/util/index.ts +0 -1058
- package/src/util/locale.ts +0 -24
- package/src/util/permission_shares.ts +0 -25
- package/src/util/suffix.ts +0 -78
- package/src/util/transform.ts +0 -239
- package/src/validators/index.ts +0 -36
package/src/types/object.ts
DELETED
|
@@ -1,2076 +0,0 @@
|
|
|
1
|
-
import { Dictionary, JsonMap } from "@salesforce/ts-types";
|
|
2
|
-
import { SteedosTriggerType, SteedosFieldType, SteedosFieldTypeConfig, SteedosSchema, SteedosListenerConfig, SteedosObjectListViewTypeConfig, SteedosObjectListViewType, SteedosIDType, SteedosObjectPermissionTypeConfig, SteedosActionType, SteedosActionTypeConfig, SteedosUserSession, getSteedosSchema } from ".";
|
|
3
|
-
import { getUserObjectSharesFilters, isTemplateSpace, isCloudAdminSpace, generateActionParams, absoluteUrl } from '../util'
|
|
4
|
-
import _ = require("underscore");
|
|
5
|
-
import { SteedosTriggerTypeConfig, SteedosTriggerContextConfig } from "./trigger";
|
|
6
|
-
import { SteedosQueryOptions, SteedosQueryFilters } from "./query";
|
|
7
|
-
import { SteedosDataSourceType, SteedosDatabaseDriverType, getDataSource } from "./datasource";
|
|
8
|
-
import { SteedosFieldDBType } from '../driver/fieldDBType';
|
|
9
|
-
import { runCurrentObjectFieldFormulas, runQuotedByObjectFieldFormulas } from '../formula';
|
|
10
|
-
import { runQuotedByObjectFieldSummaries, runCurrentObjectFieldSummaries } from '../summary';
|
|
11
|
-
import { formatFiltersToODataQuery } from "@steedos/filters";
|
|
12
|
-
import { WorkflowRulesRunner } from '../actions';
|
|
13
|
-
import { runValidationRules } from './validation_rules';
|
|
14
|
-
import { brokeEmitEvents } from "./object_events";
|
|
15
|
-
import { translationObject } from "@steedos/i18n";
|
|
16
|
-
import { getObjectLayouts } from "./object_layouts";
|
|
17
|
-
import { sortBy, forEach } from 'lodash';
|
|
18
|
-
import { ShareRules } from './shareRule';
|
|
19
|
-
import { RestrictionRule } from './restrictionRule';
|
|
20
|
-
import { FieldPermission } from './field_permission';
|
|
21
|
-
import { getPatternListeners } from '../dynamic-load';
|
|
22
|
-
import { getCacher } from '@steedos/cachers';
|
|
23
|
-
|
|
24
|
-
const clone = require('clone')
|
|
25
|
-
|
|
26
|
-
// 主子表有层级限制,超过3层就报错,该函数判断当前对象作为主表对象往下的层级最多不越过3层,
|
|
27
|
-
// 其3层指的是A-B-C-D,它们都有父子关系,A作为最顶层,该对象上不可以再创建主表子表关系字段,但是B、C、D上可以;
|
|
28
|
-
// 或者如果当前对象上创建的主表子表关系字段指向的对象是D,那么也会超过3层的层级限制;
|
|
29
|
-
// 又或者中间加一层M先连接B再连接C,形成A-B-M-C-D,也会超过3层的层级限制;
|
|
30
|
-
export const MAX_MASTER_DETAIL_LEAVE = 3;
|
|
31
|
-
|
|
32
|
-
/**
|
|
33
|
-
* 判断传入的paths中每条path下是否有重复对象名称,返回第一个重复的对象名称
|
|
34
|
-
* 有可能传入的paths有多个链条,只要其中任何一个链条上有同名对象名说明异常,返回第一个异常的同名对象名即可
|
|
35
|
-
* 比如传入下面示例中的paths,表示当前对象b向下有4条主子关系链,将返回第三条链中的重复对象名b
|
|
36
|
-
* @param paths 对象上getDetailPaths或getMasterPaths函数返回的当前对象向下或向上取主表子表关联对象名称列表链条
|
|
37
|
-
* [
|
|
38
|
-
[ 'b', 't1', 't2' ],
|
|
39
|
-
[ 'b', 't1', 'm1', 'm2' ],
|
|
40
|
-
[ 'b', 't1', 'm2', 'b' ],
|
|
41
|
-
[ 'b', 'c', 'd' ]
|
|
42
|
-
* ]
|
|
43
|
-
*/
|
|
44
|
-
export const getRepeatObjectNameFromPaths = (paths: string[]) => {
|
|
45
|
-
let repeatItem: string;
|
|
46
|
-
for (let p of paths) {
|
|
47
|
-
if (repeatItem) {
|
|
48
|
-
break;
|
|
49
|
-
}
|
|
50
|
-
let g = _.groupBy(p);
|
|
51
|
-
for (let k in g) {
|
|
52
|
-
if (g[k].length > 1) {
|
|
53
|
-
repeatItem = k;
|
|
54
|
-
break;
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
return repeatItem;
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
abstract class SteedosObjectProperties {
|
|
62
|
-
_id?: string
|
|
63
|
-
abstract name?: string
|
|
64
|
-
extend?: string
|
|
65
|
-
abstract table_name?: string
|
|
66
|
-
label?: string
|
|
67
|
-
icon?: string
|
|
68
|
-
enable_search?: boolean
|
|
69
|
-
is_enable?: boolean
|
|
70
|
-
enable_files?: boolean
|
|
71
|
-
enable_tasks?: boolean
|
|
72
|
-
enable_notes?: boolean
|
|
73
|
-
enable_events?: boolean
|
|
74
|
-
enable_api?: boolean //TODO 未开放功能
|
|
75
|
-
abstract enable_share?: boolean
|
|
76
|
-
abstract enable_instances?: boolean
|
|
77
|
-
enable_chatter?: boolean
|
|
78
|
-
abstract enable_audit?: boolean
|
|
79
|
-
abstract enable_trash?: boolean
|
|
80
|
-
enable_space_global?: boolean
|
|
81
|
-
enable_tree?: boolean
|
|
82
|
-
parent_field?: string
|
|
83
|
-
children_field?: string
|
|
84
|
-
enable_enhanced_lookup?: boolean
|
|
85
|
-
enable_inline_edit?: boolean
|
|
86
|
-
enable_approvals?: boolean
|
|
87
|
-
enable_process?: boolean
|
|
88
|
-
is_view?: boolean
|
|
89
|
-
hidden?: boolean
|
|
90
|
-
description?: string
|
|
91
|
-
custom?: boolean
|
|
92
|
-
owner?: string
|
|
93
|
-
// triggers?: object
|
|
94
|
-
sidebar?: object //TODO
|
|
95
|
-
calendar?: object //TODO
|
|
96
|
-
abstract actions?: Dictionary<SteedosActionTypeConfig>
|
|
97
|
-
abstract fields?: Dictionary<SteedosFieldTypeConfig>
|
|
98
|
-
abstract listeners?: Dictionary<SteedosListenerConfig>
|
|
99
|
-
abstract list_views?: Dictionary<SteedosObjectListViewTypeConfig>
|
|
100
|
-
permissions?: Dictionary<SteedosObjectPermissionTypeConfig>
|
|
101
|
-
methods?: Dictionary<Function>
|
|
102
|
-
fields_serial_number?: number
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
export interface SteedosObjectTypeConfig extends SteedosObjectProperties {
|
|
108
|
-
__filename?: string
|
|
109
|
-
name?: string
|
|
110
|
-
isMain?: boolean
|
|
111
|
-
datasource?: string
|
|
112
|
-
fields?: Dictionary<SteedosFieldTypeConfig>
|
|
113
|
-
actions?: Dictionary<SteedosActionTypeConfig>
|
|
114
|
-
listeners?: Dictionary<SteedosListenerConfig>
|
|
115
|
-
permission_set?: Dictionary<SteedosObjectPermissionTypeConfig> //TODO remove ; 目前为了兼容现有object的定义保留
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
export const _TRIGGERKEYS = ['beforeFind', 'beforeInsert', 'beforeUpdate', 'beforeDelete', 'afterFind', 'afterCount', 'afterFindOne', 'afterInsert', 'afterUpdate', 'afterDelete', 'beforeAggregate', 'afterAggregate']
|
|
119
|
-
|
|
120
|
-
const properties = ['label', 'icon', 'enable_search', 'sidebar', 'is_enable', 'enable_files', 'enable_tasks', 'enable_notes', 'enable_events', 'enable_api', 'enable_share', 'enable_instances', 'enable_chatter', 'enable_audit', 'enable_web_forms', 'enable_inline_edit', 'enable_approvals', 'enable_trash', 'enable_space_global', 'enable_tree', 'parent_field', 'children_field', 'enable_enhanced_lookup', 'enable_workflow', 'is_view', 'hidden', 'description', 'custom', 'owner', 'methods', '_id', 'relatedList', 'fields_serial_number', "is_enable", "in_development", "version", "paging"]
|
|
121
|
-
|
|
122
|
-
export class SteedosObjectType extends SteedosObjectProperties {
|
|
123
|
-
|
|
124
|
-
private _schema: SteedosSchema;
|
|
125
|
-
private _datasource: SteedosDataSourceType;
|
|
126
|
-
public get datasource(): SteedosDataSourceType {
|
|
127
|
-
return this._datasource;
|
|
128
|
-
}
|
|
129
|
-
private _name: string;
|
|
130
|
-
private _fields: Dictionary<SteedosFieldType> = {};
|
|
131
|
-
private _actions: Dictionary<SteedosActionType> = {};
|
|
132
|
-
private _listeners: Dictionary<SteedosListenerConfig> = {};
|
|
133
|
-
private _triggers: Dictionary<SteedosTriggerType> = {};
|
|
134
|
-
private _list_views: Dictionary<SteedosObjectListViewType> = {};
|
|
135
|
-
private _table_name: string;
|
|
136
|
-
private _triggersQueue: Dictionary<Dictionary<SteedosTriggerType>> = {}
|
|
137
|
-
private _idFieldName: string;
|
|
138
|
-
private _idFieldNames: string[] = [];
|
|
139
|
-
private _NAME_FIELD_KEY: string;
|
|
140
|
-
private _masters: string[] = [];
|
|
141
|
-
private _details: string[] = [];
|
|
142
|
-
|
|
143
|
-
private _enable_audit: boolean;
|
|
144
|
-
public get enable_audit(): boolean {
|
|
145
|
-
return this._enable_audit;
|
|
146
|
-
}
|
|
147
|
-
public set enable_audit(value: boolean) {
|
|
148
|
-
if (value && !this._datasource.enable_space) {
|
|
149
|
-
throw new Error(`not support, please set ${this._name}.enable_audit to false or remove the enable_audit attribute`)
|
|
150
|
-
}
|
|
151
|
-
this._enable_audit = value;
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
private _enable_instances: boolean;
|
|
155
|
-
public get enable_instances(): boolean {
|
|
156
|
-
return this._enable_instances;
|
|
157
|
-
}
|
|
158
|
-
public set enable_instances(value: boolean) {
|
|
159
|
-
if (value && !this._datasource.enable_space) {
|
|
160
|
-
throw new Error(`not support, please set ${this._name}.enable_instances to false or remove the enable_instances attribute`)
|
|
161
|
-
}
|
|
162
|
-
this._enable_instances = value;
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
private _enable_trash: boolean;
|
|
166
|
-
public get enable_trash(): boolean {
|
|
167
|
-
return this._enable_trash;
|
|
168
|
-
}
|
|
169
|
-
public set enable_trash(value: boolean) {
|
|
170
|
-
if (value && !this._datasource.enable_space) {
|
|
171
|
-
throw new Error(`not support, please set ${this._name}.enable_trash to false or remove the enable_trash attribute`)
|
|
172
|
-
}
|
|
173
|
-
this._enable_trash = value;
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
private _enable_share;
|
|
177
|
-
public get enable_share(): boolean {
|
|
178
|
-
return this._enable_share;
|
|
179
|
-
}
|
|
180
|
-
public set enable_share(value: boolean) {
|
|
181
|
-
if (value && !this._datasource.enable_space) {
|
|
182
|
-
throw new Error(`not support, please set ${this._name}.enable_share to false or remove the enable_share attribute`)
|
|
183
|
-
}
|
|
184
|
-
this._enable_share = value;
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
public get NAME_FIELD_KEY(): string {
|
|
188
|
-
return this._NAME_FIELD_KEY;
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
getMethod(method_name: string) {
|
|
192
|
-
return this.methods[method_name]
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
public get idFieldName(): string {
|
|
196
|
-
return this._idFieldName;
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
public get idFieldNames(): string[] {
|
|
200
|
-
return this._idFieldNames;
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
public get masters(): string[] {
|
|
204
|
-
return this._masters;
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
public get details(): string[] {
|
|
208
|
-
return this._details;
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
private async callMetadataObjectServiceAction(action, params?){
|
|
212
|
-
const actionFullName = `objects.${action}`
|
|
213
|
-
const result = await this.schema.metadataBroker.call(actionFullName, params);
|
|
214
|
-
return result;
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
private checkField() {
|
|
218
|
-
let driverSupportedColumnTypes = this._datasource.adapter.getSupportedColumnTypes()
|
|
219
|
-
_.each(this.fields, (field: SteedosFieldType, key: string) => {
|
|
220
|
-
if (SteedosFieldDBType[field.fieldDBType] && !driverSupportedColumnTypes.includes(field.fieldDBType)) {
|
|
221
|
-
throw new Error(`driver ${this._datasource.driver} can not support field ${key} config`)
|
|
222
|
-
}
|
|
223
|
-
})
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
constructor(object_name: string, datasource: SteedosDataSourceType, config: SteedosObjectTypeConfig) {
|
|
227
|
-
super();
|
|
228
|
-
this._name = object_name
|
|
229
|
-
this._datasource = datasource
|
|
230
|
-
this._schema = datasource.schema
|
|
231
|
-
if (this._datasource.driver != SteedosDatabaseDriverType.MeteorMongo)
|
|
232
|
-
this._enable_share = false
|
|
233
|
-
|
|
234
|
-
if (/^[_a-zA-Z][_a-zA-Z0-9]*$/.test(object_name) != true) {
|
|
235
|
-
throw new Error('invalid character, object_name can only be start with _ or a-zA-Z and contain only _ or _a-zA-Z0-9. you can set table_name');
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
if (config.table_name) {
|
|
239
|
-
this._table_name = config.table_name
|
|
240
|
-
} else {
|
|
241
|
-
this._table_name = this._name
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
_.each(properties, (property) => {
|
|
245
|
-
if (_.has(config, property)) {
|
|
246
|
-
this[property] = config[property]
|
|
247
|
-
}
|
|
248
|
-
})
|
|
249
|
-
|
|
250
|
-
_.each(config.fields, (field, field_name) => {
|
|
251
|
-
this.setField(field_name, field)
|
|
252
|
-
})
|
|
253
|
-
|
|
254
|
-
this.checkField()
|
|
255
|
-
|
|
256
|
-
_.each(config.actions, (action, action_name) => {
|
|
257
|
-
this.setAction(action_name, action)
|
|
258
|
-
})
|
|
259
|
-
|
|
260
|
-
_.each(config.listeners, (listener, listener_name) => {
|
|
261
|
-
this.setListener(listener_name, listener)
|
|
262
|
-
})
|
|
263
|
-
|
|
264
|
-
_.each(config.list_views, (list_view, name) => {
|
|
265
|
-
this.setListView(name, list_view)
|
|
266
|
-
})
|
|
267
|
-
|
|
268
|
-
_.each(config.permissions, (permission, name) => {
|
|
269
|
-
permission.name = name
|
|
270
|
-
this.setPermission(permission)
|
|
271
|
-
})
|
|
272
|
-
|
|
273
|
-
//TODO remove ; 目前为了兼容现有object的定义保留
|
|
274
|
-
_.each(config.permission_set, (permission, name) => {
|
|
275
|
-
permission.name = name
|
|
276
|
-
this.setPermission(permission)
|
|
277
|
-
})
|
|
278
|
-
|
|
279
|
-
if (this._datasource.driver == SteedosDatabaseDriverType.Mongo || this._datasource.driver == SteedosDatabaseDriverType.MeteorMongo) {
|
|
280
|
-
this._idFieldName = '_id'
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
this.schema.setObjectMap(this.name, { datasourceName: this.datasource.name, _id: config._id })
|
|
284
|
-
}
|
|
285
|
-
|
|
286
|
-
getConfig(){
|
|
287
|
-
return this.datasource.getObjectConfig(this.name);
|
|
288
|
-
}
|
|
289
|
-
|
|
290
|
-
setPermission(config: SteedosObjectPermissionTypeConfig) {
|
|
291
|
-
this._datasource.setObjectPermission(this._name, config)
|
|
292
|
-
}
|
|
293
|
-
|
|
294
|
-
setListener(listener_name: string, config: SteedosListenerConfig) {
|
|
295
|
-
this.listeners[listener_name] = config
|
|
296
|
-
_TRIGGERKEYS.forEach((key) => {
|
|
297
|
-
let event = config[key];
|
|
298
|
-
if (_.isFunction(event)) {
|
|
299
|
-
this.setTrigger(`${listener_name}_${event.name}`, key, event);
|
|
300
|
-
}
|
|
301
|
-
})
|
|
302
|
-
}
|
|
303
|
-
|
|
304
|
-
removeListener(listener_name: string, config: SteedosListenerConfig) {
|
|
305
|
-
this.listeners[listener_name] = config
|
|
306
|
-
_TRIGGERKEYS.forEach((key) => {
|
|
307
|
-
try {
|
|
308
|
-
let event = config[key];
|
|
309
|
-
delete this._triggersQueue[key][`${listener_name}_${event.name}`]
|
|
310
|
-
} catch (error) {
|
|
311
|
-
|
|
312
|
-
}
|
|
313
|
-
})
|
|
314
|
-
}
|
|
315
|
-
|
|
316
|
-
private setTrigger(name: string, when: string, todo: Function, on = 'server') {
|
|
317
|
-
let triggerConfig: SteedosTriggerTypeConfig = {
|
|
318
|
-
name: name,
|
|
319
|
-
on: on,
|
|
320
|
-
when: when,
|
|
321
|
-
todo: todo,
|
|
322
|
-
}
|
|
323
|
-
let trigger = new SteedosTriggerType(triggerConfig)
|
|
324
|
-
this.triggers[name] = trigger
|
|
325
|
-
this.registerTrigger(trigger)
|
|
326
|
-
}
|
|
327
|
-
|
|
328
|
-
registerTrigger(trigger: SteedosTriggerType) {
|
|
329
|
-
//如果是meteor mongo 则不做任何处理
|
|
330
|
-
if (!_.isString(this._datasource.driver) || this._datasource.driver != SteedosDatabaseDriverType.MeteorMongo || trigger.when === 'beforeFind' || trigger.when === 'afterFind' || trigger.when === 'afterFindOne' || trigger.when === 'afterCount' || trigger.when === 'beforeAggregate' || trigger.when === 'afterAggregate') {
|
|
331
|
-
if (!trigger.todo) {
|
|
332
|
-
return;
|
|
333
|
-
}
|
|
334
|
-
if (!this._triggersQueue[trigger.when]) {
|
|
335
|
-
this._triggersQueue[trigger.when] = {}
|
|
336
|
-
}
|
|
337
|
-
this._triggersQueue[trigger.when][trigger.name] = trigger
|
|
338
|
-
}
|
|
339
|
-
}
|
|
340
|
-
|
|
341
|
-
unregisterTrigger(trigger: SteedosTriggerType) {
|
|
342
|
-
delete this._triggersQueue[trigger.when][trigger.name]
|
|
343
|
-
}
|
|
344
|
-
|
|
345
|
-
private async runTirgger(trigger: SteedosTriggerType, context: SteedosTriggerContextConfig) {
|
|
346
|
-
let object_name = this.name
|
|
347
|
-
let event = trigger.todo
|
|
348
|
-
let todoWrapper = async function (...args) {
|
|
349
|
-
// Object.setPrototypeOf(thisArg, Object.getPrototypeOf(trigger))
|
|
350
|
-
return await event.apply(thisArg, args)
|
|
351
|
-
}
|
|
352
|
-
let thisArg = {
|
|
353
|
-
...context,
|
|
354
|
-
object_name: object_name,
|
|
355
|
-
datasource_name: this._datasource.name,
|
|
356
|
-
getObject: (object_name: string) => {
|
|
357
|
-
return this._schema.getObject(object_name)
|
|
358
|
-
}
|
|
359
|
-
}
|
|
360
|
-
|
|
361
|
-
return await todoWrapper.call(thisArg)
|
|
362
|
-
}
|
|
363
|
-
|
|
364
|
-
async runTriggers(when: string, context: SteedosTriggerContextConfig) {
|
|
365
|
-
let triggers = this._triggersQueue[when]
|
|
366
|
-
if (triggers) {
|
|
367
|
-
let triggerKeys = _.keys(triggers)
|
|
368
|
-
|
|
369
|
-
for (let index = 0; index < triggerKeys.length; index++) {
|
|
370
|
-
let trigger = triggers[triggerKeys[index]];
|
|
371
|
-
await this.runTirgger(trigger, context)
|
|
372
|
-
}
|
|
373
|
-
}
|
|
374
|
-
|
|
375
|
-
// 获取通配的trigger,如果有则生成SteedosTriggerType执行
|
|
376
|
-
let wildcardListeners = getPatternListeners(this.name);
|
|
377
|
-
if (wildcardListeners) {
|
|
378
|
-
for (const key in wildcardListeners) {
|
|
379
|
-
if (Object.prototype.hasOwnProperty.call(wildcardListeners, key)) {
|
|
380
|
-
const listener = wildcardListeners[key];
|
|
381
|
-
if (listener && listener[when]) {
|
|
382
|
-
let triggerConfig: SteedosTriggerTypeConfig = {
|
|
383
|
-
name: `${key}_${when}`,
|
|
384
|
-
on: 'server',
|
|
385
|
-
when: when,
|
|
386
|
-
todo: listener[when],
|
|
387
|
-
}
|
|
388
|
-
let trigger = new SteedosTriggerType(triggerConfig)
|
|
389
|
-
await this.runTirgger(trigger, context)
|
|
390
|
-
}
|
|
391
|
-
}
|
|
392
|
-
}
|
|
393
|
-
}
|
|
394
|
-
|
|
395
|
-
}
|
|
396
|
-
|
|
397
|
-
getTriggerActions(when: string){
|
|
398
|
-
|
|
399
|
-
const triggers = [];
|
|
400
|
-
|
|
401
|
-
const cache = getCacher('action-triggers');
|
|
402
|
-
const triggerActions = cache.get('triggerActions');
|
|
403
|
-
|
|
404
|
-
if(!_.isEmpty(triggerActions)){
|
|
405
|
-
_.map(triggerActions, (item)=>{
|
|
406
|
-
if(item && item.metadata){
|
|
407
|
-
const { metadata } = item
|
|
408
|
-
if(metadata.isPattern){
|
|
409
|
-
try {
|
|
410
|
-
if(metadata.listenTo === '*'){
|
|
411
|
-
triggers.push(item);
|
|
412
|
-
}else if(_.isArray(metadata.listenTo) && _.include(metadata.listenTo, this.name)){
|
|
413
|
-
triggers.push(item);
|
|
414
|
-
}else if(_.isRegExp(metadata.listenTo) && metadata.listenTo.test(this.name)){
|
|
415
|
-
triggers.push(item);
|
|
416
|
-
}else if(_.isString(metadata.listenTo) && metadata.listenTo.startsWith("/")){
|
|
417
|
-
try {
|
|
418
|
-
if(_.isRegExp(eval(metadata.listenTo)) && eval(metadata.listenTo).test(this.name)){
|
|
419
|
-
triggers.push(item);
|
|
420
|
-
}
|
|
421
|
-
} catch (error) {
|
|
422
|
-
}
|
|
423
|
-
}
|
|
424
|
-
} catch (error) {
|
|
425
|
-
console.log(`error`, error);
|
|
426
|
-
}
|
|
427
|
-
}else{
|
|
428
|
-
if(metadata.when === when && metadata.listenTo === this.name){
|
|
429
|
-
triggers.push(item);
|
|
430
|
-
}
|
|
431
|
-
}
|
|
432
|
-
|
|
433
|
-
}
|
|
434
|
-
})
|
|
435
|
-
}
|
|
436
|
-
|
|
437
|
-
return triggers;
|
|
438
|
-
}
|
|
439
|
-
|
|
440
|
-
async runTriggerActions(when: string, context: SteedosTriggerContextConfig) {
|
|
441
|
-
let triggers = this.getTriggerActions(when);
|
|
442
|
-
if (_.isEmpty(triggers)) {
|
|
443
|
-
return;
|
|
444
|
-
}
|
|
445
|
-
|
|
446
|
-
for (const trigger of triggers) {
|
|
447
|
-
let params = generateActionParams(when, context); //参考sf
|
|
448
|
-
await this._schema.metadataBroker.call(`${trigger.service.name}.${trigger.metadata.action}`, params).catch((error)=>{
|
|
449
|
-
//如果action trigger 下线,则只打印error
|
|
450
|
-
if(error && _.isObject(error) && error.type === 'SERVICE_NOT_AVAILABLE'){
|
|
451
|
-
console.error(`runTriggerActions error`, error)
|
|
452
|
-
}else{
|
|
453
|
-
throw error
|
|
454
|
-
}
|
|
455
|
-
})
|
|
456
|
-
}
|
|
457
|
-
|
|
458
|
-
}
|
|
459
|
-
|
|
460
|
-
toConfig() {
|
|
461
|
-
let config: JsonMap = {
|
|
462
|
-
name: this.name,
|
|
463
|
-
fields: {}
|
|
464
|
-
}
|
|
465
|
-
|
|
466
|
-
_.each(properties, (property) => {
|
|
467
|
-
if (this[property] != null && this[property] != undefined) {
|
|
468
|
-
config[property] = this[property]
|
|
469
|
-
}
|
|
470
|
-
})
|
|
471
|
-
|
|
472
|
-
if (this.fields) {
|
|
473
|
-
config.fields = {}
|
|
474
|
-
_.each(this.fields, (field: SteedosFieldType, key: string) => {
|
|
475
|
-
config.fields[key] = field.toConfig();
|
|
476
|
-
})
|
|
477
|
-
}
|
|
478
|
-
|
|
479
|
-
if (this.list_views) {
|
|
480
|
-
config.list_views = {}
|
|
481
|
-
_.each(this.list_views, (list_view: SteedosObjectListViewType, key: string) => {
|
|
482
|
-
config.list_views[key] = list_view.toConfig()
|
|
483
|
-
})
|
|
484
|
-
}
|
|
485
|
-
|
|
486
|
-
if (this.actions) {
|
|
487
|
-
config.actions = {}
|
|
488
|
-
_.each(this.actions, (action: SteedosActionType, key: string) => {
|
|
489
|
-
config.actions[key] = action.toConfig()
|
|
490
|
-
})
|
|
491
|
-
}
|
|
492
|
-
|
|
493
|
-
if (this.triggers) {
|
|
494
|
-
config.triggers = {}
|
|
495
|
-
_.each(this.triggers, (trigger: SteedosTriggerType, key: string) => {
|
|
496
|
-
config.triggers[key] = trigger.toConfig();
|
|
497
|
-
})
|
|
498
|
-
}
|
|
499
|
-
|
|
500
|
-
let rolePermission = this.getObjectRolesPermission()
|
|
501
|
-
if (rolePermission) {
|
|
502
|
-
config.permission_set = {}
|
|
503
|
-
_.each(rolePermission, (v, k) => {
|
|
504
|
-
config.permission_set[k] = v
|
|
505
|
-
})
|
|
506
|
-
}
|
|
507
|
-
|
|
508
|
-
config.datasource = this.datasource.name;
|
|
509
|
-
|
|
510
|
-
return config
|
|
511
|
-
}
|
|
512
|
-
|
|
513
|
-
setField(field_name: string, fieldConfig: SteedosFieldTypeConfig) {
|
|
514
|
-
let field = new SteedosFieldType(field_name, this, fieldConfig)
|
|
515
|
-
this.fields[field_name] = field
|
|
516
|
-
|
|
517
|
-
if (field.primary && this._datasource.driver != SteedosDatabaseDriverType.Mongo && this._datasource.driver != SteedosDatabaseDriverType.MeteorMongo) {
|
|
518
|
-
this._idFieldName = field.name
|
|
519
|
-
if (this._idFieldNames.indexOf(field.name) < 0) {
|
|
520
|
-
this._idFieldNames.push(field.name);
|
|
521
|
-
}
|
|
522
|
-
}
|
|
523
|
-
|
|
524
|
-
if (field.is_name) {
|
|
525
|
-
this._NAME_FIELD_KEY = field_name
|
|
526
|
-
} else if (field_name == 'name' && !this._NAME_FIELD_KEY) {
|
|
527
|
-
this._NAME_FIELD_KEY = field_name
|
|
528
|
-
}
|
|
529
|
-
}
|
|
530
|
-
|
|
531
|
-
getField(field_name: string) {
|
|
532
|
-
return this.fields[field_name]
|
|
533
|
-
}
|
|
534
|
-
|
|
535
|
-
getFields(){
|
|
536
|
-
return this.toConfig().fields
|
|
537
|
-
}
|
|
538
|
-
|
|
539
|
-
getNameFieldKey(){
|
|
540
|
-
return this.NAME_FIELD_KEY;
|
|
541
|
-
}
|
|
542
|
-
|
|
543
|
-
async getDetailPaths(){
|
|
544
|
-
return await this.callMetadataObjectServiceAction(`getDetailPaths`, {objectApiName: this.name});
|
|
545
|
-
}
|
|
546
|
-
|
|
547
|
-
async getMasterPaths(){
|
|
548
|
-
return await this.callMetadataObjectServiceAction(`getMasterPaths`, {objectApiName: this.name});
|
|
549
|
-
}
|
|
550
|
-
|
|
551
|
-
async getMaxDetailsLeave(paths?){
|
|
552
|
-
return await this.callMetadataObjectServiceAction(`getMaxDetailsLeave`, {objectApiName: this.name, paths});
|
|
553
|
-
}
|
|
554
|
-
|
|
555
|
-
async getMaxMastersLeave(paths?){
|
|
556
|
-
return await this.callMetadataObjectServiceAction(`getMaxMastersLeave`, {objectApiName: this.name, paths});
|
|
557
|
-
}
|
|
558
|
-
|
|
559
|
-
addMaster(object_name: string) {
|
|
560
|
-
let index = this._masters.indexOf(object_name);
|
|
561
|
-
if (index < 0) {
|
|
562
|
-
this._masters.push(object_name);
|
|
563
|
-
return true;
|
|
564
|
-
}
|
|
565
|
-
return false;
|
|
566
|
-
}
|
|
567
|
-
|
|
568
|
-
removeMaster(object_name: string) {
|
|
569
|
-
let index = this._masters.indexOf(object_name);
|
|
570
|
-
if (index >= 0) {
|
|
571
|
-
this._masters.splice(index, 1);
|
|
572
|
-
}
|
|
573
|
-
}
|
|
574
|
-
|
|
575
|
-
addDetail(object_name: string) {
|
|
576
|
-
let index = this._details.indexOf(object_name);
|
|
577
|
-
if (index < 0) {
|
|
578
|
-
this._details.push(object_name);
|
|
579
|
-
return true;
|
|
580
|
-
}
|
|
581
|
-
return false;
|
|
582
|
-
}
|
|
583
|
-
|
|
584
|
-
removeDetail(object_name: string) {
|
|
585
|
-
let index = this._details.indexOf(object_name);
|
|
586
|
-
if (index >= 0) {
|
|
587
|
-
this._details.splice(index, 1);
|
|
588
|
-
}
|
|
589
|
-
}
|
|
590
|
-
|
|
591
|
-
setListView(list_view_name: string, config: SteedosObjectListViewTypeConfig) {
|
|
592
|
-
this.list_views[list_view_name] = new SteedosObjectListViewType(list_view_name, this, config)
|
|
593
|
-
}
|
|
594
|
-
|
|
595
|
-
setAction(action_name: string, actionConfig: SteedosActionTypeConfig) {
|
|
596
|
-
this._actions[action_name] = new SteedosActionType(action_name, this, actionConfig)
|
|
597
|
-
}
|
|
598
|
-
|
|
599
|
-
getAction(action_name: string) {
|
|
600
|
-
return this._actions[action_name]
|
|
601
|
-
}
|
|
602
|
-
|
|
603
|
-
async refreshIndexes(){
|
|
604
|
-
if(this.datasource.driver === SteedosDatabaseDriverType.Mongo || this.datasource.driver === SteedosDatabaseDriverType.MeteorMongo){
|
|
605
|
-
const adapter = this.datasource.adapter;
|
|
606
|
-
await adapter.connect()
|
|
607
|
-
let collection = (adapter as any).collection(this.name);
|
|
608
|
-
if (this.datasource.driver === SteedosDatabaseDriverType.MeteorMongo) {
|
|
609
|
-
let defaultAdapter = getDataSource('default').adapter
|
|
610
|
-
await defaultAdapter.connect();
|
|
611
|
-
collection = (defaultAdapter as any).collection(this.name);
|
|
612
|
-
}
|
|
613
|
-
const indexesInfo = [];
|
|
614
|
-
const dropIndexNames = [];
|
|
615
|
-
for (const key in this.fields) {
|
|
616
|
-
const field = this.fields[key];
|
|
617
|
-
const info = field.getIndexInfo();
|
|
618
|
-
if(info){
|
|
619
|
-
indexesInfo.push(info);
|
|
620
|
-
}else{
|
|
621
|
-
dropIndexNames.push(field.getIndexName());
|
|
622
|
-
}
|
|
623
|
-
}
|
|
624
|
-
if(indexesInfo && indexesInfo.length > 0){
|
|
625
|
-
try {
|
|
626
|
-
for await (const indexInfo of indexesInfo) {
|
|
627
|
-
const key = indexInfo.key;
|
|
628
|
-
delete indexInfo.key;
|
|
629
|
-
try {
|
|
630
|
-
await collection.createIndex(key, indexInfo)
|
|
631
|
-
} catch (error) {
|
|
632
|
-
// DO NOTHING
|
|
633
|
-
}
|
|
634
|
-
}
|
|
635
|
-
// await collection.createIndexes(indexesInfo)
|
|
636
|
-
} catch (error) {
|
|
637
|
-
console.error(error)
|
|
638
|
-
}
|
|
639
|
-
}
|
|
640
|
-
// if(dropIndexNames && dropIndexNames.length > 0){
|
|
641
|
-
// try {
|
|
642
|
-
// for await (const indexName of dropIndexNames) {
|
|
643
|
-
// try {
|
|
644
|
-
// await collection.dropIndex(indexName)
|
|
645
|
-
// } catch (error) {
|
|
646
|
-
|
|
647
|
-
// }
|
|
648
|
-
// }
|
|
649
|
-
|
|
650
|
-
// } catch (error) {
|
|
651
|
-
// console.error(error)
|
|
652
|
-
// }
|
|
653
|
-
// }
|
|
654
|
-
}
|
|
655
|
-
}
|
|
656
|
-
|
|
657
|
-
//TODO 处理对象继承
|
|
658
|
-
extend_TODO(config: SteedosObjectTypeConfig) {
|
|
659
|
-
if (this.name != config.name)
|
|
660
|
-
throw new Error("You can not extend on different object");
|
|
661
|
-
|
|
662
|
-
// override each fields
|
|
663
|
-
_.each(config.fields, (field, field_name) => {
|
|
664
|
-
this.setField(field_name, field)
|
|
665
|
-
})
|
|
666
|
-
|
|
667
|
-
// override each actions
|
|
668
|
-
// if (config.actions) {
|
|
669
|
-
// _.each(config.actions, (action) => {
|
|
670
|
-
// this.actions[action.name] = action
|
|
671
|
-
// })
|
|
672
|
-
// }
|
|
673
|
-
|
|
674
|
-
// override each triggers
|
|
675
|
-
// if (config.triggers) {
|
|
676
|
-
// _.each(config.triggers, (trigger) => {
|
|
677
|
-
// this.triggers[trigger.name] = trigger
|
|
678
|
-
// })
|
|
679
|
-
// }
|
|
680
|
-
}
|
|
681
|
-
|
|
682
|
-
getObjectRolesPermission(spaceId?: string) {
|
|
683
|
-
let globalPermission = this._datasource.getObjectRolesPermission(this._name)
|
|
684
|
-
if (spaceId) {
|
|
685
|
-
let permission = this._datasource.getObjectSpaceRolesPermission(this._name, spaceId);
|
|
686
|
-
if (!_.isEmpty(permission)) {
|
|
687
|
-
return Object.assign({}, globalPermission || {}, permission);
|
|
688
|
-
}
|
|
689
|
-
}
|
|
690
|
-
return globalPermission
|
|
691
|
-
}
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
/**
|
|
695
|
-
* @description:
|
|
696
|
-
* @param {SteedosUserSession} userSession
|
|
697
|
-
* @param {any} rolesFieldsPermission: 如果为false, 则不计算字段集权限,提交计算效率.
|
|
698
|
-
* @return {*}
|
|
699
|
-
*/
|
|
700
|
-
async getUserObjectPermission(userSession: SteedosUserSession, rolesFieldsPermission?: any) {
|
|
701
|
-
|
|
702
|
-
if (!userSession) {
|
|
703
|
-
throw new Error('userSession is required')
|
|
704
|
-
}
|
|
705
|
-
|
|
706
|
-
let roles = userSession.roles
|
|
707
|
-
let objectRolesPermission = this.getObjectRolesPermission(userSession.spaceId)
|
|
708
|
-
|
|
709
|
-
let userObjectPermission = {
|
|
710
|
-
allowRead: false,
|
|
711
|
-
allowCreate: false,
|
|
712
|
-
allowEdit: false,
|
|
713
|
-
allowDelete: false,
|
|
714
|
-
viewAllRecords: false,
|
|
715
|
-
modifyAllRecords: false,
|
|
716
|
-
viewCompanyRecords: false,
|
|
717
|
-
modifyCompanyRecords: false,
|
|
718
|
-
allowReadFiles: null,
|
|
719
|
-
viewAllFiles: null,
|
|
720
|
-
allowCreateFiles: null,
|
|
721
|
-
allowEditFiles: null,
|
|
722
|
-
allowDeleteFiles: null,
|
|
723
|
-
modifyAllFiles: null,
|
|
724
|
-
disabled_list_views: null,
|
|
725
|
-
disabled_actions: null,
|
|
726
|
-
unreadable_fields: null,
|
|
727
|
-
uneditable_fields: null,
|
|
728
|
-
unrelated_objects: null,
|
|
729
|
-
field_permissions: null,
|
|
730
|
-
viewAssignCompanysRecords: [],
|
|
731
|
-
modifyAssignCompanysRecords: [],
|
|
732
|
-
// read_filters: [],
|
|
733
|
-
// edit_filters: []
|
|
734
|
-
}
|
|
735
|
-
|
|
736
|
-
if (_.isEmpty(roles)) {
|
|
737
|
-
throw new Error('not find user permission');
|
|
738
|
-
}
|
|
739
|
-
|
|
740
|
-
if(rolesFieldsPermission === false){
|
|
741
|
-
rolesFieldsPermission = {};
|
|
742
|
-
}else{
|
|
743
|
-
if (!rolesFieldsPermission) {
|
|
744
|
-
rolesFieldsPermission = await FieldPermission.getObjectFieldsPermissionGroupRole(this.name);
|
|
745
|
-
}
|
|
746
|
-
}
|
|
747
|
-
|
|
748
|
-
roles.forEach((role) => {
|
|
749
|
-
let rolePermission = objectRolesPermission[role];
|
|
750
|
-
if (rolePermission) {
|
|
751
|
-
let roleFieldsPermission = rolesFieldsPermission[role];
|
|
752
|
-
_.each(userObjectPermission, (v, k) => {
|
|
753
|
-
let _v = rolePermission[k];
|
|
754
|
-
if (k === 'field_permissions') {
|
|
755
|
-
_v = roleFieldsPermission
|
|
756
|
-
}
|
|
757
|
-
if (_.isBoolean(v)) {
|
|
758
|
-
if (v === false && _v === true) {
|
|
759
|
-
userObjectPermission[k] = _v
|
|
760
|
-
}
|
|
761
|
-
} else if (['allowReadFiles','viewAllFiles','allowCreateFiles','allowEditFiles','allowDeleteFiles','modifyAllFiles'].indexOf(k) > -1){
|
|
762
|
-
if(_.isBoolean(_v)){
|
|
763
|
-
userObjectPermission[k] = _v
|
|
764
|
-
}
|
|
765
|
-
} else if (['read_filters', 'edit_filters'].indexOf(k) > -1) {
|
|
766
|
-
if ('edit_filters' === k) {
|
|
767
|
-
if (!_.isEmpty(_v)) {
|
|
768
|
-
userObjectPermission['read_filters'].push(_v);
|
|
769
|
-
}
|
|
770
|
-
}
|
|
771
|
-
if (!_.isEmpty(_v)) {
|
|
772
|
-
userObjectPermission[k].push(_v);
|
|
773
|
-
}
|
|
774
|
-
} else if (['viewAssignCompanysRecords', 'modifyAssignCompanysRecords'].indexOf(k) > -1) {
|
|
775
|
-
if ('modifyAssignCompanysRecords' === k) {
|
|
776
|
-
if (!_.isEmpty(_v) && _.isArray(_v)) {
|
|
777
|
-
userObjectPermission['viewAssignCompanysRecords'].push(..._v);
|
|
778
|
-
}
|
|
779
|
-
}
|
|
780
|
-
if (!_.isEmpty(_v) && _.isArray(_v)) {
|
|
781
|
-
userObjectPermission[k].push(..._v);
|
|
782
|
-
}
|
|
783
|
-
}
|
|
784
|
-
else if ((_.isArray(v) || _.isNull(v))) {
|
|
785
|
-
if (!_.isArray(_v)) {
|
|
786
|
-
_v = []
|
|
787
|
-
}
|
|
788
|
-
if (_.isNull(v)) {
|
|
789
|
-
userObjectPermission[k] = _v
|
|
790
|
-
} else {
|
|
791
|
-
if (k === 'field_permissions') {
|
|
792
|
-
userObjectPermission[k] = _.union(v, _v)
|
|
793
|
-
} else {
|
|
794
|
-
userObjectPermission[k] = _.intersection(v, _v)
|
|
795
|
-
}
|
|
796
|
-
}
|
|
797
|
-
}
|
|
798
|
-
})
|
|
799
|
-
}
|
|
800
|
-
});
|
|
801
|
-
|
|
802
|
-
const field_permissions = {};
|
|
803
|
-
if (userObjectPermission.field_permissions) {
|
|
804
|
-
_.each(userObjectPermission.field_permissions, (field_permission) => {
|
|
805
|
-
const { field, read, edit } = field_permission;
|
|
806
|
-
if (field_permissions[field]) {
|
|
807
|
-
field_permissions[field].edit = field_permissions[field].edit || edit;
|
|
808
|
-
if (field_permissions[field].edit) {
|
|
809
|
-
field_permissions[field].read = true
|
|
810
|
-
} else {
|
|
811
|
-
field_permissions[field].read = field_permissions[field].read || read;
|
|
812
|
-
}
|
|
813
|
-
} else {
|
|
814
|
-
field_permissions[field] = {
|
|
815
|
-
field: field,
|
|
816
|
-
read: edit || read,
|
|
817
|
-
edit: edit
|
|
818
|
-
}
|
|
819
|
-
}
|
|
820
|
-
})
|
|
821
|
-
}
|
|
822
|
-
|
|
823
|
-
userObjectPermission.field_permissions = field_permissions;
|
|
824
|
-
|
|
825
|
-
userObjectPermission.disabled_list_views = userObjectPermission.disabled_list_views || []
|
|
826
|
-
userObjectPermission.disabled_actions = userObjectPermission.disabled_actions || []
|
|
827
|
-
userObjectPermission.unreadable_fields = userObjectPermission.unreadable_fields || []
|
|
828
|
-
userObjectPermission.uneditable_fields = userObjectPermission.uneditable_fields || []
|
|
829
|
-
userObjectPermission.unrelated_objects = userObjectPermission.unrelated_objects || []
|
|
830
|
-
|
|
831
|
-
let spaceId = userSession.spaceId
|
|
832
|
-
if (isTemplateSpace(spaceId)) {
|
|
833
|
-
return Object.assign({}, userObjectPermission, { allowRead: true, viewAllRecords: true, viewCompanyRecords: true })
|
|
834
|
-
}
|
|
835
|
-
|
|
836
|
-
return userObjectPermission;
|
|
837
|
-
}
|
|
838
|
-
|
|
839
|
-
async allowRead(userSession: SteedosUserSession) {
|
|
840
|
-
if (!userSession)
|
|
841
|
-
return true
|
|
842
|
-
let userObjectPermission = await this.getUserObjectPermission(userSession, false)
|
|
843
|
-
if (userObjectPermission.allowRead) {
|
|
844
|
-
return true
|
|
845
|
-
} else {
|
|
846
|
-
return false
|
|
847
|
-
}
|
|
848
|
-
}
|
|
849
|
-
|
|
850
|
-
async allowInsert(userSession: SteedosUserSession) {
|
|
851
|
-
if (!userSession)
|
|
852
|
-
return true
|
|
853
|
-
let userObjectPermission = await this.getUserObjectPermission(userSession, false)
|
|
854
|
-
if (userObjectPermission.allowCreate) {
|
|
855
|
-
return true
|
|
856
|
-
} else {
|
|
857
|
-
return false
|
|
858
|
-
}
|
|
859
|
-
}
|
|
860
|
-
|
|
861
|
-
async allowUpdate(userSession: SteedosUserSession) {
|
|
862
|
-
if (!userSession)
|
|
863
|
-
return true
|
|
864
|
-
let userObjectPermission = await this.getUserObjectPermission(userSession, false)
|
|
865
|
-
if (userObjectPermission.allowEdit) {
|
|
866
|
-
return true
|
|
867
|
-
} else {
|
|
868
|
-
return false
|
|
869
|
-
}
|
|
870
|
-
}
|
|
871
|
-
|
|
872
|
-
async allowDelete(userSession: SteedosUserSession) {
|
|
873
|
-
if (!userSession)
|
|
874
|
-
return true
|
|
875
|
-
let userObjectPermission = await this.getUserObjectPermission(userSession, false)
|
|
876
|
-
if (userObjectPermission.allowDelete) {
|
|
877
|
-
return true
|
|
878
|
-
} else {
|
|
879
|
-
return false
|
|
880
|
-
}
|
|
881
|
-
}
|
|
882
|
-
|
|
883
|
-
async find(query: SteedosQueryOptions, userSession?: SteedosUserSession) {
|
|
884
|
-
let clonedQuery = Object.assign({}, query);
|
|
885
|
-
if(userSession)
|
|
886
|
-
await this.processUnreadableField(userSession, clonedQuery);
|
|
887
|
-
return await this.callAdapter('find', this.table_name, clonedQuery, userSession)
|
|
888
|
-
}
|
|
889
|
-
|
|
890
|
-
// 此函数支持driver: MeteorMongo
|
|
891
|
-
async aggregate(query: SteedosQueryOptions, externalPipeline, userSession?: SteedosUserSession) {
|
|
892
|
-
let clonedQuery = Object.assign({}, query);
|
|
893
|
-
if(userSession)
|
|
894
|
-
await this.processUnreadableField(userSession, clonedQuery);
|
|
895
|
-
return await this.callAdapter('aggregate', this.table_name, clonedQuery, externalPipeline, userSession)
|
|
896
|
-
}
|
|
897
|
-
|
|
898
|
-
// 此函数支持driver: MeteorMongo
|
|
899
|
-
async directAggregate(query: SteedosQueryOptions, externalPipeline: any[], userSession?: SteedosUserSession) {
|
|
900
|
-
let clonedQuery = Object.assign({}, query);
|
|
901
|
-
if(userSession)
|
|
902
|
-
await this.processUnreadableField(userSession, clonedQuery);
|
|
903
|
-
return await this.callAdapter('directAggregate', this.table_name, clonedQuery, externalPipeline, userSession)
|
|
904
|
-
}
|
|
905
|
-
|
|
906
|
-
// 此函数支持driver: MeteorMongo,类似于aggregate,其参数externalPipeline放在最前面而已
|
|
907
|
-
async directAggregatePrefixalPipeline(query: SteedosQueryOptions, prefixalPipeline: any[], userSession?: SteedosUserSession) {
|
|
908
|
-
let clonedQuery = Object.assign({}, query);
|
|
909
|
-
if(userSession)
|
|
910
|
-
await this.processUnreadableField(userSession, clonedQuery);
|
|
911
|
-
return await this.callAdapter('directAggregatePrefixalPipeline', this.table_name, clonedQuery, prefixalPipeline, userSession)
|
|
912
|
-
}
|
|
913
|
-
|
|
914
|
-
async findOne(id: SteedosIDType, query: SteedosQueryOptions, userSession?: SteedosUserSession) {
|
|
915
|
-
let clonedQuery = Object.assign({}, query);
|
|
916
|
-
if(userSession)
|
|
917
|
-
await this.processUnreadableField(userSession, clonedQuery);
|
|
918
|
-
const result = await this.callAdapter('findOne', this.table_name, id, clonedQuery, userSession);
|
|
919
|
-
return result
|
|
920
|
-
}
|
|
921
|
-
|
|
922
|
-
async insert(doc: Dictionary<any>, userSession?: SteedosUserSession) {
|
|
923
|
-
doc = this.formatRecord(doc);
|
|
924
|
-
return await this.callAdapter('insert', this.table_name, doc, userSession)
|
|
925
|
-
}
|
|
926
|
-
|
|
927
|
-
async update(id: SteedosIDType, doc: Dictionary<any>, userSession?: SteedosUserSession) {
|
|
928
|
-
doc = this.formatRecord(doc);
|
|
929
|
-
// await this.processUneditableFields(userSession, doc)
|
|
930
|
-
let clonedId = id;
|
|
931
|
-
return await this.callAdapter('update', this.table_name, clonedId, doc, userSession)
|
|
932
|
-
}
|
|
933
|
-
|
|
934
|
-
async updateOne(id: SteedosIDType, doc: Dictionary<any>, userSession?: SteedosUserSession) {
|
|
935
|
-
doc = this.formatRecord(doc);
|
|
936
|
-
// await this.processUneditableFields(userSession, doc)
|
|
937
|
-
let clonedId = id;
|
|
938
|
-
return await this.callAdapter('updateOne', this.table_name, clonedId, doc, userSession)
|
|
939
|
-
}
|
|
940
|
-
// 此函数支持driver: MeteorMongo、Mongo
|
|
941
|
-
async updateMany(queryFilters: SteedosQueryFilters, doc: Dictionary<any>, userSession?: SteedosUserSession) {
|
|
942
|
-
doc = this.formatRecord(doc);
|
|
943
|
-
// await this.processUneditableFields(userSession, doc)
|
|
944
|
-
let clonedQueryFilters = queryFilters;
|
|
945
|
-
return await this.callAdapter('updateMany', this.table_name, clonedQueryFilters, doc, userSession)
|
|
946
|
-
}
|
|
947
|
-
|
|
948
|
-
async delete(id: SteedosIDType, userSession?: SteedosUserSession) {
|
|
949
|
-
let clonedId = id;
|
|
950
|
-
return await this.callAdapter('delete', this.table_name, clonedId, userSession)
|
|
951
|
-
}
|
|
952
|
-
|
|
953
|
-
async directFind(query: SteedosQueryOptions, userSession?: SteedosUserSession) {
|
|
954
|
-
let clonedQuery = Object.assign({}, query);
|
|
955
|
-
await this.processUnreadableField(userSession, clonedQuery);
|
|
956
|
-
return await this.callAdapter('directFind', this.table_name, clonedQuery, userSession)
|
|
957
|
-
}
|
|
958
|
-
|
|
959
|
-
async directInsert(doc: Dictionary<any>, userSession?: SteedosUserSession) {
|
|
960
|
-
doc = this.formatRecord(doc);
|
|
961
|
-
return await this.callAdapter('directInsert', this.table_name, doc, userSession)
|
|
962
|
-
}
|
|
963
|
-
|
|
964
|
-
async directUpdate(id: SteedosIDType, doc: Dictionary<any>, userSession?: SteedosUserSession) {
|
|
965
|
-
doc = this.formatRecord(doc);
|
|
966
|
-
// await this.processUneditableFields(userSession, doc)
|
|
967
|
-
let clonedId = id;
|
|
968
|
-
return await this.callAdapter('directUpdate', this.table_name, clonedId, doc, userSession)
|
|
969
|
-
}
|
|
970
|
-
|
|
971
|
-
async directDelete(id: SteedosIDType, userSession?: SteedosUserSession) {
|
|
972
|
-
let clonedId = id;
|
|
973
|
-
return await this.callAdapter('directDelete', this.table_name, clonedId, userSession)
|
|
974
|
-
}
|
|
975
|
-
|
|
976
|
-
async _makeNewID(){
|
|
977
|
-
return await this._datasource._makeNewID(this.table_name);
|
|
978
|
-
}
|
|
979
|
-
|
|
980
|
-
async getFirstListView(){
|
|
981
|
-
return this.list_views[0];
|
|
982
|
-
}
|
|
983
|
-
|
|
984
|
-
async getAbsoluteUrl(app_id, record_id?){
|
|
985
|
-
const object_name = this.name;
|
|
986
|
-
const list_view:any = await this.getFirstListView();
|
|
987
|
-
const list_view_id = list_view ? list_view._id || list_view.name : 'all'
|
|
988
|
-
if(record_id)
|
|
989
|
-
return absoluteUrl("/app/" + app_id + "/" + object_name + "/view/" + record_id)
|
|
990
|
-
else{
|
|
991
|
-
if(object_name === 'meeting'){
|
|
992
|
-
return absoluteUrl("/app/" + app_id + "/" + object_name + "/calendar/")
|
|
993
|
-
}else{
|
|
994
|
-
return absoluteUrl("/app/" + app_id + "/" + object_name + "/grid/" + list_view_id)
|
|
995
|
-
}
|
|
996
|
-
}
|
|
997
|
-
}
|
|
998
|
-
|
|
999
|
-
async getRecordAbsoluteUrl(app_id, record_id){
|
|
1000
|
-
return await this.getAbsoluteUrl(app_id, record_id)
|
|
1001
|
-
}
|
|
1002
|
-
|
|
1003
|
-
async getGridAbsoluteUrl(app_id){
|
|
1004
|
-
return await this.getAbsoluteUrl(app_id)
|
|
1005
|
-
}
|
|
1006
|
-
|
|
1007
|
-
async isEnableAudit(){
|
|
1008
|
-
return this.enable_audit;
|
|
1009
|
-
}
|
|
1010
|
-
|
|
1011
|
-
async getDetails(){
|
|
1012
|
-
return await this.callMetadataObjectServiceAction(`getDetails`, {objectApiName: this.name});
|
|
1013
|
-
}
|
|
1014
|
-
|
|
1015
|
-
async getMasters(){
|
|
1016
|
-
return await this.callMetadataObjectServiceAction(`getMasters`, {objectApiName: this.name});
|
|
1017
|
-
}
|
|
1018
|
-
|
|
1019
|
-
async getLookupDetails(){
|
|
1020
|
-
return await this.callMetadataObjectServiceAction(`getLookupDetails`, {objectApiName: this.name});
|
|
1021
|
-
}
|
|
1022
|
-
|
|
1023
|
-
async getDetailsInfo(){
|
|
1024
|
-
return await this.callMetadataObjectServiceAction(`getDetailsInfo`, {objectApiName: this.name});
|
|
1025
|
-
}
|
|
1026
|
-
|
|
1027
|
-
async getMastersInfo(){
|
|
1028
|
-
return await this.callMetadataObjectServiceAction(`getMastersInfo`, {objectApiName: this.name});
|
|
1029
|
-
}
|
|
1030
|
-
|
|
1031
|
-
async getLookupDetailsInfo(){
|
|
1032
|
-
return await this.callMetadataObjectServiceAction(`getLookupDetailsInfo`, {objectApiName: this.name});
|
|
1033
|
-
}
|
|
1034
|
-
|
|
1035
|
-
/**
|
|
1036
|
-
* 此函数返回getDetailsInfo、getMastersInfo、getLookupDetailsInfo 3个请求的结果,用于优化访问速度
|
|
1037
|
-
*/
|
|
1038
|
-
async getRelationsInfo() {
|
|
1039
|
-
return await this.callMetadataObjectServiceAction(`getRelationsInfo`, { objectApiName: this.name });
|
|
1040
|
-
}
|
|
1041
|
-
|
|
1042
|
-
async getRecordPermissions(record, userSession){
|
|
1043
|
-
const permissions = await this.getUserObjectPermission(userSession);
|
|
1044
|
-
const { userId, company_ids: user_company_ids } = userSession;
|
|
1045
|
-
if(record){
|
|
1046
|
-
if(record.record_permissions){
|
|
1047
|
-
return record.record_permissions
|
|
1048
|
-
}
|
|
1049
|
-
let recordOwnerId = record.owner;
|
|
1050
|
-
if(_.isObject(recordOwnerId)){
|
|
1051
|
-
recordOwnerId = recordOwnerId._id;
|
|
1052
|
-
}
|
|
1053
|
-
const isOwner = recordOwnerId == userId;
|
|
1054
|
-
let record_company_id = record.company_id;
|
|
1055
|
-
if(record_company_id && _.isObject(record_company_id) && record_company_id._id){
|
|
1056
|
-
record_company_id = record_company_id._id;
|
|
1057
|
-
}
|
|
1058
|
-
let record_company_ids = record.company_ids;
|
|
1059
|
-
if(record_company_ids && record_company_ids.length && _.isObject(record_company_ids[0])){
|
|
1060
|
-
record_company_ids = record_company_ids.map((n)=> n._id)
|
|
1061
|
-
}
|
|
1062
|
-
record_company_ids = _.union(record_company_ids, [record_company_id]);
|
|
1063
|
-
record_company_ids = _.compact(record_company_ids);
|
|
1064
|
-
if(!permissions.modifyAllRecords && !isOwner && !permissions.modifyCompanyRecords){
|
|
1065
|
-
permissions.allowEdit = false
|
|
1066
|
-
permissions.allowDelete = false
|
|
1067
|
-
}else if(!permissions.modifyAllRecords && permissions.modifyCompanyRecords){
|
|
1068
|
-
if(record_company_ids && record_company_ids.length){
|
|
1069
|
-
if(user_company_ids && user_company_ids.length){
|
|
1070
|
-
if(!_.intersection(user_company_ids, record_company_ids).length){
|
|
1071
|
-
permissions.allowEdit = false
|
|
1072
|
-
permissions.allowDelete = false
|
|
1073
|
-
}
|
|
1074
|
-
}else{
|
|
1075
|
-
permissions.allowEdit = false
|
|
1076
|
-
permissions.allowDelete = false
|
|
1077
|
-
}
|
|
1078
|
-
}
|
|
1079
|
-
}
|
|
1080
|
-
if(record.locked && !permissions.modifyAllRecords){
|
|
1081
|
-
permissions.allowEdit = false
|
|
1082
|
-
permissions.allowDelete = false
|
|
1083
|
-
}
|
|
1084
|
-
if(!permissions.viewAllRecords && !isOwner && !permissions.viewCompanyRecords){
|
|
1085
|
-
permissions.allowRead = false
|
|
1086
|
-
}else if(!permissions.viewAllRecords && permissions.viewCompanyRecords){
|
|
1087
|
-
if(record_company_ids && record_company_ids.length){
|
|
1088
|
-
if(user_company_ids && user_company_ids.length){
|
|
1089
|
-
if(!_.intersection(user_company_ids, record_company_ids).length){
|
|
1090
|
-
permissions.allowRead = false
|
|
1091
|
-
}
|
|
1092
|
-
}else{
|
|
1093
|
-
permissions.allowRead = false
|
|
1094
|
-
}
|
|
1095
|
-
}
|
|
1096
|
-
}
|
|
1097
|
-
}
|
|
1098
|
-
return permissions
|
|
1099
|
-
}
|
|
1100
|
-
|
|
1101
|
-
/**
|
|
1102
|
-
* 获取用户可访问字段
|
|
1103
|
-
* 字段权限设计: https://github.com/steedos/steedos-platform/issues/2943
|
|
1104
|
-
* 字段配置为必填字段:
|
|
1105
|
-
* 1 字段级权限不能设置为只读。
|
|
1106
|
-
* 2 页面布局中不能修改必填选项,始终必填。
|
|
1107
|
-
* 3 页面布局中不能设置为只读。
|
|
1108
|
-
* 4 字段如果不在页面布局中, 则显示在最后
|
|
1109
|
-
* @param objectFields
|
|
1110
|
-
* @param objectLayout
|
|
1111
|
-
* @param objectPermission
|
|
1112
|
-
*/
|
|
1113
|
-
getAccessFields(objectFields, objectLayout, objectPermission){
|
|
1114
|
-
const accessFields = {};
|
|
1115
|
-
const universallyRequiredFields = _.filter(objectFields, (objectFile)=>{
|
|
1116
|
-
return _.isBoolean(objectFile.required) && objectFile.required;
|
|
1117
|
-
});
|
|
1118
|
-
|
|
1119
|
-
const universallyRequiredFieldsName = _.pluck(universallyRequiredFields, 'name');
|
|
1120
|
-
|
|
1121
|
-
_.each(objectFields, (field)=>{
|
|
1122
|
-
if(field){
|
|
1123
|
-
const fieldPermission = objectPermission.field_permissions[field.name];
|
|
1124
|
-
|
|
1125
|
-
let fieldLayout = objectLayout && objectLayout.fields ? _.find(objectLayout.fields, (item)=>{return item.field_name == field.name}) : null;
|
|
1126
|
-
|
|
1127
|
-
const isUniversallyRequiredField = _.contains(universallyRequiredFieldsName, field.name);
|
|
1128
|
-
|
|
1129
|
-
if(isUniversallyRequiredField){
|
|
1130
|
-
fieldLayout = Object.assign({}, fieldLayout, {
|
|
1131
|
-
field_name: field.name,
|
|
1132
|
-
is_required: true,
|
|
1133
|
-
is_readonly: false,
|
|
1134
|
-
})
|
|
1135
|
-
}
|
|
1136
|
-
|
|
1137
|
-
// 如果配置了页面布局且没有授权字段时, 不显示此字段
|
|
1138
|
-
if(objectLayout && !fieldLayout){
|
|
1139
|
-
return ;
|
|
1140
|
-
}
|
|
1141
|
-
|
|
1142
|
-
let {read, edit} = fieldPermission || {read: !field.hidden, edit: !field.hidden && !field.readonly};
|
|
1143
|
-
|
|
1144
|
-
// 通用必填字段始终可见、可编辑
|
|
1145
|
-
if(isUniversallyRequiredField){
|
|
1146
|
-
read = true;
|
|
1147
|
-
edit = true;
|
|
1148
|
-
}
|
|
1149
|
-
|
|
1150
|
-
if(fieldLayout && fieldLayout.is_readonly){
|
|
1151
|
-
edit = false;
|
|
1152
|
-
}
|
|
1153
|
-
|
|
1154
|
-
//不可查看: 配置了字段权限且不可查看; 没有配置字段权限,字段的hidden为true
|
|
1155
|
-
if(read === false){
|
|
1156
|
-
return;
|
|
1157
|
-
}
|
|
1158
|
-
|
|
1159
|
-
//可查看不可编辑: 配置了字段权限可查看不可编辑; 没有配置字段权限 字段的hidden 为false 且字段的readonly为true
|
|
1160
|
-
if(read === true && edit === false){
|
|
1161
|
-
accessFields[field.name] = Object.assign({}, field, {
|
|
1162
|
-
hidden: false,
|
|
1163
|
-
required: false,
|
|
1164
|
-
readonly: true,
|
|
1165
|
-
disabled: true
|
|
1166
|
-
})
|
|
1167
|
-
return;
|
|
1168
|
-
}
|
|
1169
|
-
|
|
1170
|
-
//可查看可编辑: 配置了字段权限可查看可编辑; 没有配置字段权限 字段的hidden 为false 且字段的readonly为false
|
|
1171
|
-
if(read === true && edit === true){
|
|
1172
|
-
accessFields[field.name] = Object.assign({}, field, {
|
|
1173
|
-
hidden: false,
|
|
1174
|
-
readonly: false,
|
|
1175
|
-
disabled: false,
|
|
1176
|
-
required: _.isString(field.required) ? field.required : (fieldLayout ? fieldLayout.is_required : false),
|
|
1177
|
-
})
|
|
1178
|
-
return;
|
|
1179
|
-
}
|
|
1180
|
-
console.error('字段权限处理异常', field, read, edit);
|
|
1181
|
-
}
|
|
1182
|
-
});
|
|
1183
|
-
|
|
1184
|
-
if(objectLayout){
|
|
1185
|
-
let sort_no = 1;
|
|
1186
|
-
_.each(objectLayout.fields, function(_item){
|
|
1187
|
-
if(accessFields[_item.field_name]){
|
|
1188
|
-
if(_.has(_item, 'group')){
|
|
1189
|
-
accessFields[_item.field_name].group = _item.group
|
|
1190
|
-
}
|
|
1191
|
-
|
|
1192
|
-
if(_item.visible_on){
|
|
1193
|
-
accessFields[_item.field_name].visible_on = _item.visible_on
|
|
1194
|
-
}
|
|
1195
|
-
|
|
1196
|
-
accessFields[_item.field_name].sort_no = sort_no;
|
|
1197
|
-
sort_no++;
|
|
1198
|
-
}
|
|
1199
|
-
})
|
|
1200
|
-
|
|
1201
|
-
//处理通用必填字段默认显示顺序
|
|
1202
|
-
_.each(universallyRequiredFieldsName, function(fieldName){
|
|
1203
|
-
const fieldLayout = _.find(objectLayout.fields, (item)=>{return item.field_name == fieldName});
|
|
1204
|
-
if(!fieldLayout){
|
|
1205
|
-
accessFields[fieldName].sort_no = sort_no;
|
|
1206
|
-
sort_no++;
|
|
1207
|
-
}
|
|
1208
|
-
})
|
|
1209
|
-
}
|
|
1210
|
-
|
|
1211
|
-
return accessFields;
|
|
1212
|
-
}
|
|
1213
|
-
|
|
1214
|
-
async getRecordView(userSession, context: any = {}) {
|
|
1215
|
-
let { objectConfig, layouts, spaceProcessDefinition, dbListViews, rolesFieldsPermission, relationsInfo} = context;
|
|
1216
|
-
const lng = userSession.language;
|
|
1217
|
-
if (!objectConfig) {
|
|
1218
|
-
const objectMetadataConfig: any = await this.callMetadataObjectServiceAction('get', { objectApiName: this.name });
|
|
1219
|
-
objectConfig = objectMetadataConfig.metadata;
|
|
1220
|
-
}
|
|
1221
|
-
objectConfig.name = this.name
|
|
1222
|
-
objectConfig.datasource = this.datasource.name;
|
|
1223
|
-
objectConfig.permissions = await this.getUserObjectPermission(userSession, rolesFieldsPermission);
|
|
1224
|
-
if(!relationsInfo){
|
|
1225
|
-
relationsInfo = await this.getRelationsInfo();
|
|
1226
|
-
}
|
|
1227
|
-
objectConfig.details = relationsInfo.details;
|
|
1228
|
-
objectConfig.masters = relationsInfo.masters;
|
|
1229
|
-
objectConfig.lookup_details = relationsInfo.lookup_details;
|
|
1230
|
-
delete objectConfig.db
|
|
1231
|
-
translationObject(lng, objectConfig.name, objectConfig, true);
|
|
1232
|
-
if (!layouts) {
|
|
1233
|
-
layouts = await getObjectLayouts(userSession.profile, userSession.spaceId, this.name);
|
|
1234
|
-
}
|
|
1235
|
-
|
|
1236
|
-
let objectLayout = null
|
|
1237
|
-
if(layouts && layouts.length > 0){
|
|
1238
|
-
objectLayout = layouts[0];
|
|
1239
|
-
_.each(objectLayout.buttons, function(button){
|
|
1240
|
-
const action = objectConfig.actions[button.button_name];
|
|
1241
|
-
if(action){
|
|
1242
|
-
if(button.visible_on){
|
|
1243
|
-
action._visible = button.visible_on;
|
|
1244
|
-
}
|
|
1245
|
-
}
|
|
1246
|
-
})
|
|
1247
|
-
|
|
1248
|
-
const layoutButtonsName = _.pluck(objectLayout.buttons,'button_name');
|
|
1249
|
-
_.each(objectConfig.actions, function(action){
|
|
1250
|
-
if(!_.include(layoutButtonsName, action.name)){
|
|
1251
|
-
action.visible = false
|
|
1252
|
-
action._visible = function(){return false}.toString()
|
|
1253
|
-
}
|
|
1254
|
-
})
|
|
1255
|
-
objectConfig.related_lists = objectLayout.related_lists || []
|
|
1256
|
-
_.each(objectConfig.related_lists, (related_list)=>{
|
|
1257
|
-
if(related_list.sort_field_name && _.isArray(related_list.sort_field_name) && related_list.sort_field_name.length > 0){
|
|
1258
|
-
related_list.sort = [];
|
|
1259
|
-
_.each(related_list.sort_field_name, (fName)=>{
|
|
1260
|
-
related_list.sort.push({field_name: fName, order: related_list.sort_order || 'asc'})
|
|
1261
|
-
})
|
|
1262
|
-
}
|
|
1263
|
-
})
|
|
1264
|
-
}
|
|
1265
|
-
objectConfig.fields = this.getAccessFields(objectConfig.fields, objectLayout, objectConfig.permissions)
|
|
1266
|
-
// TODO object layout 是否需要控制审批记录显示?
|
|
1267
|
-
if (!spaceProcessDefinition) {
|
|
1268
|
-
spaceProcessDefinition = await getObject("process_definition").directFind({ filters: [['space', '=', userSession.spaceId], ['object_name', '=', this.name], ['active', '=', true]] })
|
|
1269
|
-
}
|
|
1270
|
-
if (spaceProcessDefinition.length > 0) {
|
|
1271
|
-
objectConfig.enable_process = true
|
|
1272
|
-
}
|
|
1273
|
-
//清理数据
|
|
1274
|
-
_.each(objectConfig.triggers, function(trigger, key){
|
|
1275
|
-
if(trigger?.on != 'client'){
|
|
1276
|
-
delete objectConfig.triggers[key];
|
|
1277
|
-
}
|
|
1278
|
-
})
|
|
1279
|
-
if (!dbListViews) {
|
|
1280
|
-
dbListViews = await getObject("object_listviews").directFind({ filters: [['space', '=', userSession.spaceId], ['object_name', '=', this.name], [['owner', '=', userSession.userId], 'or', ['shared', '=', true]]] })
|
|
1281
|
-
}
|
|
1282
|
-
objectConfig.list_views = Object.assign({}, objectConfig.list_views)
|
|
1283
|
-
_.each(dbListViews, function(dbListView){
|
|
1284
|
-
delete dbListView.created;
|
|
1285
|
-
delete dbListView.created_by;
|
|
1286
|
-
delete dbListView.modified;
|
|
1287
|
-
delete dbListView.modified_by;
|
|
1288
|
-
objectConfig.list_views[dbListView.name] = dbListView;
|
|
1289
|
-
})
|
|
1290
|
-
delete objectConfig.listeners
|
|
1291
|
-
delete objectConfig.__filename
|
|
1292
|
-
delete objectConfig.extend
|
|
1293
|
-
return objectConfig;
|
|
1294
|
-
}
|
|
1295
|
-
|
|
1296
|
-
async getDefaultRecordView(userSession){
|
|
1297
|
-
const object_name = this.name;
|
|
1298
|
-
const type = 'record';
|
|
1299
|
-
const buttons = [];
|
|
1300
|
-
const fields = [];
|
|
1301
|
-
const related_lists = [];
|
|
1302
|
-
|
|
1303
|
-
const objectConfig: any = await this.callMetadataObjectServiceAction('getOriginalObject', {objectApiName: this.name});
|
|
1304
|
-
let sortedFields = [];
|
|
1305
|
-
forEach(objectConfig.fields, (fieldItem, key)=>{
|
|
1306
|
-
sortedFields.push(Object.assign({}, {name: key}, fieldItem));
|
|
1307
|
-
});
|
|
1308
|
-
sortedFields = sortBy(sortedFields, function(o) { return o.sort_no; });
|
|
1309
|
-
_.each(sortedFields, function(field, key){
|
|
1310
|
-
const layoutField: any = {};
|
|
1311
|
-
layoutField.field_name = field.name;
|
|
1312
|
-
layoutField.is_readonly = field.readonly;
|
|
1313
|
-
layoutField.is_required = field.required;
|
|
1314
|
-
layoutField.group = field.group;
|
|
1315
|
-
// layoutField.visible_on = `${!field.hidden}`;
|
|
1316
|
-
fields.push(layoutField);
|
|
1317
|
-
});
|
|
1318
|
-
|
|
1319
|
-
let relatedLists = []
|
|
1320
|
-
if(this.enable_files){
|
|
1321
|
-
relatedLists.push("cms_files.parent")
|
|
1322
|
-
}
|
|
1323
|
-
|
|
1324
|
-
const details = await this.getDetailsInfo();
|
|
1325
|
-
const lookup_details = await this.getLookupDetailsInfo();
|
|
1326
|
-
relatedLists = relatedLists.concat(_.union(details, lookup_details));
|
|
1327
|
-
|
|
1328
|
-
if(this.enable_tasks){
|
|
1329
|
-
relatedLists.push("tasks.related_to")
|
|
1330
|
-
}
|
|
1331
|
-
if(this.enable_notes){
|
|
1332
|
-
relatedLists.push("notes.related_to")
|
|
1333
|
-
}
|
|
1334
|
-
if(this.enable_events){
|
|
1335
|
-
relatedLists.push("events.related_to")
|
|
1336
|
-
}
|
|
1337
|
-
if(this.enable_instances){
|
|
1338
|
-
relatedLists.push("instances.record_ids")
|
|
1339
|
-
}
|
|
1340
|
-
if(this.enable_approvals){
|
|
1341
|
-
relatedLists.push("approvals.related_to")
|
|
1342
|
-
}
|
|
1343
|
-
if(this.enable_process){
|
|
1344
|
-
relatedLists.push("process_instance_history.target_object")
|
|
1345
|
-
}
|
|
1346
|
-
for await (const related of relatedLists) {
|
|
1347
|
-
if(related){
|
|
1348
|
-
const relatedItem: any = {}
|
|
1349
|
-
relatedItem.related_field_fullname = related;
|
|
1350
|
-
let foo = (related as any).split('.');
|
|
1351
|
-
let rObjectName = foo[0];
|
|
1352
|
-
|
|
1353
|
-
const relatedObject = await getObject(rObjectName).toConfig();
|
|
1354
|
-
const relatedObjectAllListView = _.find(relatedObject.list_views, function(listview){
|
|
1355
|
-
return listview.name === 'all'
|
|
1356
|
-
})
|
|
1357
|
-
|
|
1358
|
-
if(relatedObjectAllListView && relatedObjectAllListView.columns){
|
|
1359
|
-
const fieldNames = [];
|
|
1360
|
-
_.each(relatedObjectAllListView.columns, (column)=>{
|
|
1361
|
-
if(_.isString(column)){
|
|
1362
|
-
fieldNames.push(column);
|
|
1363
|
-
}else if(_.isObject(column)){
|
|
1364
|
-
fieldNames.push(column.field);
|
|
1365
|
-
}
|
|
1366
|
-
})
|
|
1367
|
-
|
|
1368
|
-
relatedItem.field_names = fieldNames
|
|
1369
|
-
}
|
|
1370
|
-
related_lists.push(relatedItem)
|
|
1371
|
-
}
|
|
1372
|
-
}
|
|
1373
|
-
|
|
1374
|
-
buttons.push({
|
|
1375
|
-
button_name: 'standard_new'
|
|
1376
|
-
})
|
|
1377
|
-
|
|
1378
|
-
buttons.push({
|
|
1379
|
-
button_name: 'standard_edit'
|
|
1380
|
-
})
|
|
1381
|
-
|
|
1382
|
-
buttons.push({
|
|
1383
|
-
button_name: 'standard_delete'
|
|
1384
|
-
})
|
|
1385
|
-
|
|
1386
|
-
_.each(objectConfig.actions, function(action, key){
|
|
1387
|
-
if(action.is_enable){
|
|
1388
|
-
buttons.push({
|
|
1389
|
-
button_name: action.name
|
|
1390
|
-
})
|
|
1391
|
-
}
|
|
1392
|
-
});
|
|
1393
|
-
|
|
1394
|
-
return {
|
|
1395
|
-
object_name, type, buttons, fields, related_lists,
|
|
1396
|
-
space: userSession.spaceId
|
|
1397
|
-
}
|
|
1398
|
-
}
|
|
1399
|
-
|
|
1400
|
-
async createDefaultRecordView(userSession){
|
|
1401
|
-
const name = 'default';
|
|
1402
|
-
const label = 'Default';
|
|
1403
|
-
const profiles = ['user'];
|
|
1404
|
-
try {
|
|
1405
|
-
let defaultRecordView = await this.getDefaultRecordView(userSession);
|
|
1406
|
-
return await getObject('object_layouts').insert(Object.assign({},defaultRecordView, {name, label, profiles}), userSession)
|
|
1407
|
-
} catch (error) {
|
|
1408
|
-
return {error: error.message}
|
|
1409
|
-
}
|
|
1410
|
-
}
|
|
1411
|
-
|
|
1412
|
-
async getRelateds(){
|
|
1413
|
-
const related_objects = [];
|
|
1414
|
-
if(this.enable_files){
|
|
1415
|
-
related_objects.push({object_name:"cms_files", foreign_key: "parent"})
|
|
1416
|
-
}
|
|
1417
|
-
let detailsInfo = await this.getDetailsInfo();
|
|
1418
|
-
let lookupsInfo = await this.getLookupDetailsInfo();
|
|
1419
|
-
let relatedInfos = detailsInfo.concat(lookupsInfo);
|
|
1420
|
-
for (const info of relatedInfos) {
|
|
1421
|
-
if (!info.startsWith('__')) {
|
|
1422
|
-
let infos = info.split('.');
|
|
1423
|
-
let detailObjectApiName = infos[0];
|
|
1424
|
-
let detailFieldName = infos[1];
|
|
1425
|
-
let related_field = await getObject(detailObjectApiName).getField(detailFieldName);
|
|
1426
|
-
if(related_field){
|
|
1427
|
-
if((related_field.type == "master_detail" || (related_field.type == "lookup" && related_field.relatedList)) && related_field.reference_to && related_field.reference_to == this.name){
|
|
1428
|
-
if(detailObjectApiName == "object_fields"){
|
|
1429
|
-
related_objects.splice(0, 0, {object_name: detailObjectApiName, foreign_key: detailFieldName})
|
|
1430
|
-
}else{
|
|
1431
|
-
related_objects.push({object_name:detailObjectApiName, foreign_key: detailFieldName, write_requires_master_read: related_field.write_requires_master_read})
|
|
1432
|
-
}
|
|
1433
|
-
}
|
|
1434
|
-
}
|
|
1435
|
-
}
|
|
1436
|
-
}
|
|
1437
|
-
if(this.enable_tasks){
|
|
1438
|
-
related_objects.push({object_name:"tasks", foreign_key: "related_to"})
|
|
1439
|
-
}
|
|
1440
|
-
if(this.enable_notes){
|
|
1441
|
-
related_objects.push({object_name:"notes", foreign_key: "related_to"})
|
|
1442
|
-
}
|
|
1443
|
-
if(this.enable_events){
|
|
1444
|
-
related_objects.push({object_name:"events", foreign_key: "related_to"});
|
|
1445
|
-
}
|
|
1446
|
-
if(this.enable_instances){
|
|
1447
|
-
related_objects.push({object_name:"instances", foreign_key: "record_ids"})
|
|
1448
|
-
}
|
|
1449
|
-
|
|
1450
|
-
if(this.enable_approvals){
|
|
1451
|
-
related_objects.push({object_name:"approvals", foreign_key: "related_to"})
|
|
1452
|
-
}
|
|
1453
|
-
|
|
1454
|
-
if(this.enable_process){
|
|
1455
|
-
related_objects.push({object_name:"process_instance_history", foreign_key: "target_object"})
|
|
1456
|
-
}
|
|
1457
|
-
return related_objects;
|
|
1458
|
-
}
|
|
1459
|
-
|
|
1460
|
-
private isDirectCRUD(methodName: string) {
|
|
1461
|
-
return methodName.startsWith("direct");
|
|
1462
|
-
}
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
async count(query: SteedosQueryOptions, userSession?: SteedosUserSession) {
|
|
1466
|
-
let clonedQuery = Object.assign({}, query);
|
|
1467
|
-
return await this.callAdapter('count', this.table_name, clonedQuery, userSession)
|
|
1468
|
-
}
|
|
1469
|
-
|
|
1470
|
-
private async allow(method: string, userSession: SteedosUserSession) {
|
|
1471
|
-
if (_.isNull(userSession) || _.isUndefined(userSession)) {
|
|
1472
|
-
return true
|
|
1473
|
-
}
|
|
1474
|
-
if (method === 'find' || method === 'findOne' || method === 'count' || method === 'aggregate' || method === 'aggregatePrefixalPipeline') {
|
|
1475
|
-
return await this.allowRead(userSession)
|
|
1476
|
-
} else if (method === 'insert') {
|
|
1477
|
-
return await this.allowInsert(userSession)
|
|
1478
|
-
} else if (method === 'update' || method === 'updateOne' || method === 'updateMany') {
|
|
1479
|
-
return await this.allowUpdate(userSession)
|
|
1480
|
-
} else if (method === 'delete') {
|
|
1481
|
-
return await this.allowDelete(userSession)
|
|
1482
|
-
}
|
|
1483
|
-
}
|
|
1484
|
-
|
|
1485
|
-
private async runBeforeTriggers(method: string, context: SteedosTriggerContextConfig) {
|
|
1486
|
-
if (method === 'count' || method === "findOne") {
|
|
1487
|
-
method = 'find';
|
|
1488
|
-
}
|
|
1489
|
-
let meteorWhen = `before${method.charAt(0).toLocaleUpperCase()}${_.rest([...method]).join('')}`
|
|
1490
|
-
let when = `before.${method}`;
|
|
1491
|
-
await this.runTriggers(meteorWhen, context);
|
|
1492
|
-
return await this.runTriggerActions(when, context)
|
|
1493
|
-
}
|
|
1494
|
-
|
|
1495
|
-
private async runAfterTriggers(method: string, context: SteedosTriggerContextConfig) {
|
|
1496
|
-
let meteorWhen = `after${method.charAt(0).toLocaleUpperCase()}${_.rest([...method]).join('')}`
|
|
1497
|
-
let when = `after.${method}`;
|
|
1498
|
-
await this.runTriggers(meteorWhen, context);
|
|
1499
|
-
return await this.runTriggerActions(when, context)
|
|
1500
|
-
}
|
|
1501
|
-
|
|
1502
|
-
private async appendRecordPermission(records, userSession) {
|
|
1503
|
-
const _ids = _.pluck(records, '_id');
|
|
1504
|
-
const objPm = await this.getUserObjectPermission(userSession, false);
|
|
1505
|
-
const permissionFilters = this.getObjectEditPermissionFilters(objPm, userSession);
|
|
1506
|
-
if (_.isEmpty(permissionFilters)) {
|
|
1507
|
-
return;
|
|
1508
|
-
}
|
|
1509
|
-
const filters = formatFiltersToODataQuery(['_id', 'in', _ids])
|
|
1510
|
-
|
|
1511
|
-
const results = await this.directFind({
|
|
1512
|
-
fields: ['_id'],
|
|
1513
|
-
filters: `(${filters}) and (${permissionFilters.join(' or ')})`
|
|
1514
|
-
});
|
|
1515
|
-
const allowEditIds = _.pluck(results, '_id');
|
|
1516
|
-
_.each(records, (record) => {
|
|
1517
|
-
if (_.include(allowEditIds, record._id)) {
|
|
1518
|
-
record.record_permissions = {
|
|
1519
|
-
allowRead: true,
|
|
1520
|
-
allowEdit: true,
|
|
1521
|
-
allowDelete: true,
|
|
1522
|
-
}
|
|
1523
|
-
}
|
|
1524
|
-
})
|
|
1525
|
-
|
|
1526
|
-
}
|
|
1527
|
-
|
|
1528
|
-
private async getTriggerContext(when: string, method: string, args: any[], recordId?: string) {
|
|
1529
|
-
|
|
1530
|
-
let userSession = args[args.length - 1]
|
|
1531
|
-
|
|
1532
|
-
let context: SteedosTriggerContextConfig = { objectName: this.name, userId: userSession ? userSession.userId : undefined, spaceId: userSession ? userSession.spaceId : undefined }
|
|
1533
|
-
|
|
1534
|
-
if (method === 'find' || method === 'findOne' || method === 'count') {
|
|
1535
|
-
context.query = args[args.length - 2]
|
|
1536
|
-
}
|
|
1537
|
-
|
|
1538
|
-
if (method === 'aggregate' || method === 'aggregatePrefixalPipeline') {
|
|
1539
|
-
context.query = args[args.length - 3]
|
|
1540
|
-
}
|
|
1541
|
-
|
|
1542
|
-
if (method === 'findOne' || method === 'update' || method === 'delete') {
|
|
1543
|
-
context.id = args[1]
|
|
1544
|
-
}
|
|
1545
|
-
|
|
1546
|
-
if (method === 'insert' || method === 'update') {
|
|
1547
|
-
context.doc = args[args.length - 2]
|
|
1548
|
-
}
|
|
1549
|
-
|
|
1550
|
-
if (when === 'after' && (method === 'update' || method === 'delete')) {
|
|
1551
|
-
context.previousDoc = await this.findOne(recordId, {}, userSession)
|
|
1552
|
-
}
|
|
1553
|
-
|
|
1554
|
-
return context
|
|
1555
|
-
}
|
|
1556
|
-
|
|
1557
|
-
private async processUnreadableField(userSession: SteedosUserSession, query: SteedosQueryOptions) {
|
|
1558
|
-
if (!userSession) {
|
|
1559
|
-
return
|
|
1560
|
-
}
|
|
1561
|
-
let userObjectPermission = await this.getUserObjectPermission(userSession, false)
|
|
1562
|
-
let userObjectUnreadableFields = userObjectPermission.unreadable_fields
|
|
1563
|
-
if (userObjectUnreadableFields.length > 0) {
|
|
1564
|
-
let queryFields = [];
|
|
1565
|
-
|
|
1566
|
-
if (_.isArray(query.fields)) {
|
|
1567
|
-
queryFields = query.fields
|
|
1568
|
-
} else if (_.isString(query.fields)) {
|
|
1569
|
-
queryFields = query.fields.split(',')
|
|
1570
|
-
}
|
|
1571
|
-
|
|
1572
|
-
if (!(query.fields && query.fields.length)) {
|
|
1573
|
-
queryFields = _.keys(this.toConfig().fields)
|
|
1574
|
-
_.each(queryFields, function (fieldName, index) {
|
|
1575
|
-
if (fieldName && fieldName.indexOf("$") > -1) {
|
|
1576
|
-
delete queryFields[index];
|
|
1577
|
-
}
|
|
1578
|
-
})
|
|
1579
|
-
queryFields = _.compact(queryFields)
|
|
1580
|
-
}
|
|
1581
|
-
queryFields = _.difference(queryFields, userObjectUnreadableFields)
|
|
1582
|
-
|
|
1583
|
-
if (queryFields.length < 1) {
|
|
1584
|
-
queryFields.push()
|
|
1585
|
-
}
|
|
1586
|
-
|
|
1587
|
-
if (this.idFieldName) {
|
|
1588
|
-
queryFields.unshift(this.idFieldName)
|
|
1589
|
-
queryFields = _.compact(_.uniq(queryFields))
|
|
1590
|
-
}
|
|
1591
|
-
|
|
1592
|
-
query.fields = queryFields.join(',')
|
|
1593
|
-
}
|
|
1594
|
-
}
|
|
1595
|
-
|
|
1596
|
-
// private async processUneditableFields(userSession: SteedosUserSession, doc: JsonMap) {
|
|
1597
|
-
// 后台直接去掉uneditable_fields相关判断逻辑
|
|
1598
|
-
// [签约对象同时配置了company_ids必填及uneditable_fields造成部分用户新建签约对象时报错 #192](https://github.com/steedos/steedos-project-dzug/issues/192)
|
|
1599
|
-
// if (!userSession) {
|
|
1600
|
-
// return
|
|
1601
|
-
// }
|
|
1602
|
-
|
|
1603
|
-
// let userObjectPermission = await this.getUserObjectPermission(userSession)
|
|
1604
|
-
// let userObjectUneditableFields = userObjectPermission.uneditable_fields
|
|
1605
|
-
|
|
1606
|
-
// let intersection = _.intersection(userObjectUneditableFields, _.keys(doc))
|
|
1607
|
-
// if (intersection.length > 0) {
|
|
1608
|
-
// throw new Error(`no permissions to edit fields ${intersection.join(', ')}`)
|
|
1609
|
-
// }
|
|
1610
|
-
|
|
1611
|
-
// // _.each(userObjectUneditableFields, (name: string)=>{
|
|
1612
|
-
// // delete doc[name]
|
|
1613
|
-
// // })
|
|
1614
|
-
// }
|
|
1615
|
-
|
|
1616
|
-
private formatRecord(doc: JsonMap) {
|
|
1617
|
-
let adapterFormat = this._datasource["formatRecord"];
|
|
1618
|
-
if (typeof adapterFormat == 'function') {
|
|
1619
|
-
doc = adapterFormat.apply(this._datasource, [doc, this.toConfig()]);
|
|
1620
|
-
}
|
|
1621
|
-
return doc;
|
|
1622
|
-
}
|
|
1623
|
-
|
|
1624
|
-
private async callAdapter(method: string, ...args: any[]) {
|
|
1625
|
-
|
|
1626
|
-
const adapterMethod = this._datasource[method];
|
|
1627
|
-
if (typeof adapterMethod !== 'function') {
|
|
1628
|
-
throw new Error('Adapted does not support "' + method + '" method');
|
|
1629
|
-
}
|
|
1630
|
-
const userSession: SteedosUserSession = args[args.length - 1];
|
|
1631
|
-
if(!_.isEmpty(userSession)){
|
|
1632
|
-
let allow = await this.allow(method, userSession)
|
|
1633
|
-
if (!allow) {
|
|
1634
|
-
throw new Error('not find permission')
|
|
1635
|
-
}
|
|
1636
|
-
}
|
|
1637
|
-
|
|
1638
|
-
let objectName = args[0], recordId: string, doc: JsonMap;
|
|
1639
|
-
if (["insert", "update", "updateMany", "delete"].indexOf(method) > -1) {
|
|
1640
|
-
// 因下面的代码,比如函数dealWithMethodPermission可能改写args变量,所以需要提前从args取出对应变量值。
|
|
1641
|
-
if (method === "insert") {
|
|
1642
|
-
// 此处doc不带_id值,得执行完adapterMethod.apply后,doc中才有_id属性,所以这里的doc及recordId都不准确
|
|
1643
|
-
doc = args[1];
|
|
1644
|
-
recordId = <string>doc._id;
|
|
1645
|
-
}
|
|
1646
|
-
else {
|
|
1647
|
-
recordId = args[1];
|
|
1648
|
-
doc = args[2];
|
|
1649
|
-
}
|
|
1650
|
-
}
|
|
1651
|
-
|
|
1652
|
-
let paramRecordId; // 用于记录原始的id参数值
|
|
1653
|
-
if (method === 'findOne' || method === 'update' || method === 'delete') {
|
|
1654
|
-
paramRecordId = args[1];
|
|
1655
|
-
}
|
|
1656
|
-
|
|
1657
|
-
// 判断处理工作区权限,公司级权限,owner权限
|
|
1658
|
-
if (!_.isEmpty(userSession) && this._datasource.enable_space) {
|
|
1659
|
-
this.dealWithFilters(method, args);
|
|
1660
|
-
await this.dealWithMethodPermission(method, args);
|
|
1661
|
-
}
|
|
1662
|
-
let returnValue: any;
|
|
1663
|
-
if (this.isDirectCRUD(method)) {
|
|
1664
|
-
args.splice(args.length - 1, 1, userSession ? userSession.userId : undefined)
|
|
1665
|
-
returnValue = await adapterMethod.apply(this._datasource, args);
|
|
1666
|
-
} else {
|
|
1667
|
-
let beforeTriggerContext = await this.getTriggerContext('before', method, args)
|
|
1668
|
-
if (paramRecordId) {
|
|
1669
|
-
beforeTriggerContext = Object.assign({} , beforeTriggerContext, { id: paramRecordId });
|
|
1670
|
-
}
|
|
1671
|
-
await this.runBeforeTriggers(method, beforeTriggerContext)
|
|
1672
|
-
await runValidationRules(method, beforeTriggerContext, args[0], userSession)
|
|
1673
|
-
let afterTriggerContext = await this.getTriggerContext('after', method, args, paramRecordId)
|
|
1674
|
-
if (paramRecordId) {
|
|
1675
|
-
afterTriggerContext = Object.assign({}, afterTriggerContext, { id: paramRecordId });
|
|
1676
|
-
}
|
|
1677
|
-
let previousDoc = clone(afterTriggerContext.previousDoc);
|
|
1678
|
-
args.splice(args.length - 1, 1, userSession ? userSession.userId : undefined)
|
|
1679
|
-
|
|
1680
|
-
returnValue = await adapterMethod.apply(this._datasource, args);
|
|
1681
|
-
if (method === 'find' || method == 'findOne' || method == 'count' || method == 'aggregate' || method == 'aggregatePrefixalPipeline') {
|
|
1682
|
-
let values = returnValue || {}
|
|
1683
|
-
if (method === 'count') {
|
|
1684
|
-
values = returnValue || 0
|
|
1685
|
-
}
|
|
1686
|
-
else {
|
|
1687
|
-
if (userSession) {
|
|
1688
|
-
let _records = returnValue
|
|
1689
|
-
if (method == 'findOne' && returnValue) {
|
|
1690
|
-
_records = [_records]
|
|
1691
|
-
}
|
|
1692
|
-
await this.appendRecordPermission(_records, userSession);
|
|
1693
|
-
}
|
|
1694
|
-
}
|
|
1695
|
-
Object.assign(afterTriggerContext, { data: { values: values } })
|
|
1696
|
-
}
|
|
1697
|
-
// console.log("==returnValue==", returnValue);
|
|
1698
|
-
if(method == 'insert' && _.has(returnValue, '_id')){
|
|
1699
|
-
afterTriggerContext.doc = returnValue;
|
|
1700
|
-
afterTriggerContext = Object.assign({}, afterTriggerContext, { id: returnValue._id });
|
|
1701
|
-
}
|
|
1702
|
-
if (method == "update") {
|
|
1703
|
-
if (returnValue) {
|
|
1704
|
-
afterTriggerContext.doc = returnValue;
|
|
1705
|
-
await this.runAfterTriggers(method, afterTriggerContext)
|
|
1706
|
-
}
|
|
1707
|
-
}
|
|
1708
|
-
else {
|
|
1709
|
-
await this.runAfterTriggers(method, afterTriggerContext)
|
|
1710
|
-
}
|
|
1711
|
-
if (method === 'find' || method == 'findOne' || method == 'count' || method == 'aggregate' || method == 'aggregatePrefixalPipeline') {
|
|
1712
|
-
if (_.isEmpty(afterTriggerContext.data) || (_.isEmpty(afterTriggerContext.data.values) && !_.isNumber(afterTriggerContext.data.values))) {
|
|
1713
|
-
return returnValue
|
|
1714
|
-
} else {
|
|
1715
|
-
return afterTriggerContext.data.values
|
|
1716
|
-
}
|
|
1717
|
-
}
|
|
1718
|
-
await new WorkflowRulesRunner({
|
|
1719
|
-
object_name: this.name,
|
|
1720
|
-
event: method,
|
|
1721
|
-
record: returnValue,
|
|
1722
|
-
user_session: userSession,
|
|
1723
|
-
previous_record: afterTriggerContext.previousDoc
|
|
1724
|
-
}).run();
|
|
1725
|
-
if (returnValue) {
|
|
1726
|
-
if (method === "insert") {
|
|
1727
|
-
// 当为insert时,上面代码执行后的doc不带_id,只能从returnValue中取
|
|
1728
|
-
doc = returnValue;
|
|
1729
|
-
recordId = <string>doc._id;
|
|
1730
|
-
}
|
|
1731
|
-
// 一定要先运行公式再运行汇总,以下两个函数顺序不能反
|
|
1732
|
-
await this.runRecordFormula(method, objectName, recordId, doc, userSession);
|
|
1733
|
-
await this.runRecordSummaries(method, objectName, recordId, doc, previousDoc, userSession);
|
|
1734
|
-
}
|
|
1735
|
-
await brokeEmitEvents(objectName, method, afterTriggerContext);
|
|
1736
|
-
}
|
|
1737
|
-
return returnValue
|
|
1738
|
-
};
|
|
1739
|
-
|
|
1740
|
-
private async runRecordFormula(method: string, objectName: string, recordId: string, doc: any, userSession: any) {
|
|
1741
|
-
if (["insert", "update", "updateMany", "delete"].indexOf(method) > -1) {
|
|
1742
|
-
if (method === "updateMany") {
|
|
1743
|
-
// TODO:暂时不支持updateMany公式计算,因为拿不到修改了哪些数据
|
|
1744
|
-
// let filters: SteedosQueryFilters = args[1];
|
|
1745
|
-
// await runManyCurrentObjectFieldFormulas(objectName, filters, userSession);
|
|
1746
|
-
}
|
|
1747
|
-
else {
|
|
1748
|
-
let currentUserId = userSession ? userSession.userId : undefined;
|
|
1749
|
-
if(method !== "delete"){
|
|
1750
|
-
await runCurrentObjectFieldFormulas(objectName, recordId, doc, currentUserId, true);
|
|
1751
|
-
}
|
|
1752
|
-
// 新建记录时肯定不会有字段被其它对象引用,但是会有当前对象上的字段之间互相引用,所以也需要重算被引用的公式字段值
|
|
1753
|
-
// 见issue: a公式字段,其中应用了b公式字段,记录保存后a字段没计算,编辑后再保存字段计算 #2946
|
|
1754
|
-
const onlyForOwn = method === "insert";
|
|
1755
|
-
// 删除记录时需要考虑其他对象记录中的公式字段引用了被删除的记录,其公式需要重新计算,但是不可以再重新计算自身公式字段,因为记录被删除了会报错
|
|
1756
|
-
// 见issue:删除记录时并不会触发公式字段重新计算,需要评估考虑加上 #2375 删除包含公式字段的记录时报错 #3427
|
|
1757
|
-
const withoutCurrent = method === "delete";
|
|
1758
|
-
await runQuotedByObjectFieldFormulas(objectName, recordId, userSession, { onlyForOwn, withoutCurrent });
|
|
1759
|
-
}
|
|
1760
|
-
}
|
|
1761
|
-
}
|
|
1762
|
-
|
|
1763
|
-
private async runRecordSummaries(method: string, objectName: string, recordId: string, doc: any, previousDoc: any, userSession: any) {
|
|
1764
|
-
if (["insert", "update", "updateMany", "delete"].indexOf(method) > -1) {
|
|
1765
|
-
if (method === "updateMany") {
|
|
1766
|
-
// TODO:暂时不支持updateMany汇总计算,因为拿不到修改了哪些数据
|
|
1767
|
-
}
|
|
1768
|
-
else {
|
|
1769
|
-
if (method === "insert") {
|
|
1770
|
-
await runCurrentObjectFieldSummaries(objectName, recordId);
|
|
1771
|
-
}
|
|
1772
|
-
await runQuotedByObjectFieldSummaries(objectName, recordId, previousDoc, userSession);
|
|
1773
|
-
}
|
|
1774
|
-
}
|
|
1775
|
-
}
|
|
1776
|
-
|
|
1777
|
-
private getObjectEditPermissionFilters(objectPermission, userSession) {
|
|
1778
|
-
const objectPermissionFilters = [];
|
|
1779
|
-
if (!_.isEmpty(objectPermission.modifyAssignCompanysRecords)) {
|
|
1780
|
-
objectPermissionFilters.push(`(${formatFiltersToODataQuery([['company_id', 'in', objectPermission.modifyAssignCompanysRecords], 'or', ['company_ids', 'in', objectPermission.modifyAssignCompanysRecords]], userSession)})`)
|
|
1781
|
-
}
|
|
1782
|
-
return objectPermissionFilters;
|
|
1783
|
-
}
|
|
1784
|
-
|
|
1785
|
-
/**
|
|
1786
|
-
* 把query.filters用formatFiltersToODataQuery转为odata query
|
|
1787
|
-
* 主要是为了把userSession中的utcOffset逻辑传入formatFiltersToODataQuery函数处理
|
|
1788
|
-
*/
|
|
1789
|
-
private dealWithFilters(method: string, args: any[]) {
|
|
1790
|
-
let userSession = args[args.length - 1];
|
|
1791
|
-
if (userSession) {
|
|
1792
|
-
if (method === 'find' || method === 'count' || method === 'aggregate' || method === 'aggregatePrefixalPipeline') {
|
|
1793
|
-
let query = args[args.length - 2];
|
|
1794
|
-
if (method === 'aggregate' || method === 'aggregatePrefixalPipeline') {
|
|
1795
|
-
query = args[args.length - 3];
|
|
1796
|
-
}
|
|
1797
|
-
if (query.filters && !_.isString(query.filters)) {
|
|
1798
|
-
query.filters = formatFiltersToODataQuery(query.filters, userSession);
|
|
1799
|
-
}
|
|
1800
|
-
}
|
|
1801
|
-
}
|
|
1802
|
-
}
|
|
1803
|
-
|
|
1804
|
-
private async dealWithMethodPermission(method: string, args: any[]) {
|
|
1805
|
-
let userSession = args[args.length - 1];
|
|
1806
|
-
if (userSession) {
|
|
1807
|
-
let spaceId = userSession.spaceId;
|
|
1808
|
-
let userId = userSession.userId;
|
|
1809
|
-
let objPm = await this.getUserObjectPermission(userSession, false);
|
|
1810
|
-
if (method === 'find' || method === 'count' || method === 'findOne' || method === 'aggregate' || method === 'aggregatePrefixalPipeline') {
|
|
1811
|
-
let query = args[args.length - 2];
|
|
1812
|
-
if (method === 'aggregate' || method === 'aggregatePrefixalPipeline') {
|
|
1813
|
-
query = args[args.length - 3];
|
|
1814
|
-
}
|
|
1815
|
-
if (query.filters && !_.isString(query.filters)) {
|
|
1816
|
-
query.filters = formatFiltersToODataQuery(query.filters);
|
|
1817
|
-
}
|
|
1818
|
-
|
|
1819
|
-
if (this.table_name == 'cfs.files.filerecord' || this.table_name == 'cfs.instances.filerecord') {
|
|
1820
|
-
return;
|
|
1821
|
-
}
|
|
1822
|
-
|
|
1823
|
-
if (isCloudAdminSpace(spaceId)) {
|
|
1824
|
-
return
|
|
1825
|
-
}
|
|
1826
|
-
|
|
1827
|
-
let spaceFilter, companyFilter, ownerFilter, sharesFilter, shareRuleFilters, restrictionRuleFilters, clientFilter = query.filters, filters, permissionFilters = [], userFilters = [];
|
|
1828
|
-
|
|
1829
|
-
//space 权限
|
|
1830
|
-
if (spaceId) {
|
|
1831
|
-
spaceFilter = `(space eq '${spaceId}')`;
|
|
1832
|
-
}
|
|
1833
|
-
|
|
1834
|
-
// 本公司权限
|
|
1835
|
-
if (spaceId && !objPm.viewAllRecords && objPm.viewCompanyRecords) {
|
|
1836
|
-
if (_.isEmpty(userSession.companies)) {
|
|
1837
|
-
console.log('objPm', objPm);
|
|
1838
|
-
throw new Error("user not belong any company!");
|
|
1839
|
-
}
|
|
1840
|
-
companyFilter = _.map(userSession.companies, function (comp: any) {
|
|
1841
|
-
return `(company_id eq '${comp._id}') or (company_ids eq '${comp._id}')`
|
|
1842
|
-
});
|
|
1843
|
-
}
|
|
1844
|
-
|
|
1845
|
-
if (!objPm.viewAllRecords && !objPm.viewCompanyRecords && objPm.allowRead) { // owner
|
|
1846
|
-
ownerFilter = `(owner eq '${userId}')`;
|
|
1847
|
-
}
|
|
1848
|
-
|
|
1849
|
-
// 指定公司权限
|
|
1850
|
-
let viewAssignCompanysRecordsFilter = [];
|
|
1851
|
-
if (objPm.viewAssignCompanysRecords) {
|
|
1852
|
-
_.each(objPm.viewAssignCompanysRecords, (assignCompanyId) => {
|
|
1853
|
-
viewAssignCompanysRecordsFilter.push(`((company_id eq '${assignCompanyId}') or (company_ids eq '${assignCompanyId}'))`)
|
|
1854
|
-
})
|
|
1855
|
-
}
|
|
1856
|
-
if (!_.isEmpty(viewAssignCompanysRecordsFilter)) {
|
|
1857
|
-
permissionFilters.push(`(${viewAssignCompanysRecordsFilter.join(' or ')})`);
|
|
1858
|
-
}
|
|
1859
|
-
|
|
1860
|
-
//共享规则
|
|
1861
|
-
shareRuleFilters = await ShareRules.getUserObjectFilters(this.name, userSession);
|
|
1862
|
-
|
|
1863
|
-
if (!_.isEmpty(shareRuleFilters)) {
|
|
1864
|
-
permissionFilters.push(`(${shareRuleFilters.join(' or ')})`);
|
|
1865
|
-
}
|
|
1866
|
-
|
|
1867
|
-
// 限制规则
|
|
1868
|
-
restrictionRuleFilters = await RestrictionRule.getUserObjectFilters(this.name, userSession);
|
|
1869
|
-
|
|
1870
|
-
if (!_.isEmpty(restrictionRuleFilters)) {
|
|
1871
|
-
userFilters.push(`(${restrictionRuleFilters.join(' or ')})`);
|
|
1872
|
-
}
|
|
1873
|
-
// objectPermissionFilters = this.getObjectPermissionFilters(objPm, userSession, false);
|
|
1874
|
-
|
|
1875
|
-
// if (!_.isEmpty(objectPermissionFilters)) {
|
|
1876
|
-
// permissionFilters.push(`(${objectPermissionFilters.join(' or ')})`);
|
|
1877
|
-
// }
|
|
1878
|
-
|
|
1879
|
-
//共享规则(旧)
|
|
1880
|
-
sharesFilter = getUserObjectSharesFilters(this.name, userSession);
|
|
1881
|
-
|
|
1882
|
-
if (!_.isEmpty(companyFilter)) {
|
|
1883
|
-
permissionFilters.push(`(${companyFilter.join(' or ')})`);
|
|
1884
|
-
}
|
|
1885
|
-
|
|
1886
|
-
if (ownerFilter) {
|
|
1887
|
-
permissionFilters.push(ownerFilter);
|
|
1888
|
-
}
|
|
1889
|
-
|
|
1890
|
-
if (!_.isEmpty(sharesFilter)) {
|
|
1891
|
-
permissionFilters.push(`(${sharesFilter.join(' or ')})`);
|
|
1892
|
-
}
|
|
1893
|
-
|
|
1894
|
-
if (clientFilter) {
|
|
1895
|
-
userFilters.push(clientFilter);
|
|
1896
|
-
}
|
|
1897
|
-
|
|
1898
|
-
if (spaceFilter) {
|
|
1899
|
-
userFilters.push(spaceFilter);
|
|
1900
|
-
}
|
|
1901
|
-
|
|
1902
|
-
if (!userSession.is_space_admin && !_.isEmpty(permissionFilters)) {
|
|
1903
|
-
filters = permissionFilters.join(' or ');
|
|
1904
|
-
}
|
|
1905
|
-
|
|
1906
|
-
if (!_.isEmpty(userFilters)) {
|
|
1907
|
-
filters = filters ? `(${filters}) and (${userFilters.join(' and ')})` : userFilters.join(' and ')
|
|
1908
|
-
}
|
|
1909
|
-
|
|
1910
|
-
query.filters = filters;
|
|
1911
|
-
}
|
|
1912
|
-
else if (method === 'insert') {
|
|
1913
|
-
if (!objPm.allowCreate) {
|
|
1914
|
-
throw new Error(`no ${method} permission!`);
|
|
1915
|
-
}
|
|
1916
|
-
}
|
|
1917
|
-
else if (method === 'update' || method === 'updateOne') {
|
|
1918
|
-
const permissionFilters = this.getObjectEditPermissionFilters(objPm, userSession);
|
|
1919
|
-
if (!objPm.allowEdit && _.isEmpty(permissionFilters)) {
|
|
1920
|
-
throw new Error(`no ${method} permission!`);
|
|
1921
|
-
}
|
|
1922
|
-
let objectPermissionEditFilters = '';
|
|
1923
|
-
if (!_.isEmpty(permissionFilters)) {
|
|
1924
|
-
objectPermissionEditFilters = ` or (${permissionFilters.join(' or ')})`
|
|
1925
|
-
}
|
|
1926
|
-
let id = args[args.length - 3];
|
|
1927
|
-
if (!objPm.modifyAllRecords && objPm.modifyCompanyRecords) {
|
|
1928
|
-
let companyFilters = _.map(userSession.companies, function (comp: any) {
|
|
1929
|
-
return `(company_id eq '${comp._id}') or (company_ids eq '${comp._id}')`
|
|
1930
|
-
}).join(' or ')
|
|
1931
|
-
if (companyFilters) {
|
|
1932
|
-
if (_.isString(id)) {
|
|
1933
|
-
id = { filters: `(_id eq \'${id}\') and (${companyFilters}${objectPermissionEditFilters})` }
|
|
1934
|
-
}
|
|
1935
|
-
else if (_.isObject(id)) {
|
|
1936
|
-
if (id.filters && !_.isString(id.filters)) {
|
|
1937
|
-
id.filters = formatFiltersToODataQuery(id.filters);
|
|
1938
|
-
}
|
|
1939
|
-
id.filters = id.filters ? `(${id.filters}) and (${companyFilters}${objectPermissionEditFilters})` : `(${companyFilters}${objectPermissionEditFilters})`;
|
|
1940
|
-
}
|
|
1941
|
-
}
|
|
1942
|
-
}
|
|
1943
|
-
else if (!objPm.modifyAllRecords && !objPm.modifyCompanyRecords && objPm.allowEdit) {
|
|
1944
|
-
if (_.isString(id)) {
|
|
1945
|
-
id = { filters: `(_id eq \'${id}\') and (owner eq \'${userId}\' ${objectPermissionEditFilters})` }
|
|
1946
|
-
}
|
|
1947
|
-
else if (_.isObject(id)) {
|
|
1948
|
-
if (id.filters && !_.isString(id.filters)) {
|
|
1949
|
-
id.filters = formatFiltersToODataQuery(id.filters);
|
|
1950
|
-
}
|
|
1951
|
-
id.filters = id.filters ? `(${id.filters}) and (owner eq \'${userId}\' ${objectPermissionEditFilters})` : `(owner eq \'${userId}\' ${objectPermissionEditFilters})`;
|
|
1952
|
-
}
|
|
1953
|
-
} else if (objectPermissionEditFilters) {
|
|
1954
|
-
if (_.isString(id)) {
|
|
1955
|
-
id = { filters: `(_id eq \'${id}\') and (${objectPermissionEditFilters})` }
|
|
1956
|
-
}
|
|
1957
|
-
else if (_.isObject(id)) {
|
|
1958
|
-
if (id.filters && !_.isString(id.filters)) {
|
|
1959
|
-
id.filters = formatFiltersToODataQuery(id.filters);
|
|
1960
|
-
}
|
|
1961
|
-
id.filters = id.filters ? `(${id.filters}) and (${objectPermissionEditFilters})` : `(${objectPermissionEditFilters})`;
|
|
1962
|
-
}
|
|
1963
|
-
}
|
|
1964
|
-
args[args.length - 3] = id;
|
|
1965
|
-
}
|
|
1966
|
-
else if (method === 'updateMany') {
|
|
1967
|
-
if (!objPm.modifyAllRecords && !objPm.modifyCompanyRecords) {
|
|
1968
|
-
throw new Error(`no ${method} permission!`);
|
|
1969
|
-
}
|
|
1970
|
-
if (!objPm.modifyAllRecords && objPm.modifyCompanyRecords) {
|
|
1971
|
-
let queryFilters = args[args.length - 3];
|
|
1972
|
-
let companyFilters = _.map(userSession.companies, function (comp: any) {
|
|
1973
|
-
return `(company_id eq '${comp._id}') or (company_ids eq '${comp._id}')`
|
|
1974
|
-
}).join(' or ')
|
|
1975
|
-
if (companyFilters) {
|
|
1976
|
-
if (queryFilters && !_.isString(queryFilters)) {
|
|
1977
|
-
queryFilters = formatFiltersToODataQuery(queryFilters);
|
|
1978
|
-
}
|
|
1979
|
-
queryFilters = queryFilters ? `(${queryFilters}) and (${companyFilters})` : `(${companyFilters})`;
|
|
1980
|
-
args[args.length - 3] = queryFilters;
|
|
1981
|
-
}
|
|
1982
|
-
}
|
|
1983
|
-
}
|
|
1984
|
-
else if (method === 'delete') {
|
|
1985
|
-
const permissionFilters = this.getObjectEditPermissionFilters(objPm, userSession);
|
|
1986
|
-
if (!objPm.allowDelete && _.isEmpty(permissionFilters)) {
|
|
1987
|
-
throw new Error(`no ${method} permission!`);
|
|
1988
|
-
}
|
|
1989
|
-
|
|
1990
|
-
let objectPermissionEditFilters = '';
|
|
1991
|
-
if (!_.isEmpty(permissionFilters)) {
|
|
1992
|
-
objectPermissionEditFilters = ` or (${permissionFilters.join(' or ')})`
|
|
1993
|
-
}
|
|
1994
|
-
|
|
1995
|
-
let id = args[args.length - 2];
|
|
1996
|
-
if (!objPm.modifyAllRecords && objPm.modifyCompanyRecords) {
|
|
1997
|
-
let companyFilters = _.map(userSession.companies, function (comp: any) {
|
|
1998
|
-
return `(company_id eq '${comp._id}') or (company_ids eq '${comp._id}')`
|
|
1999
|
-
}).join(' or ')
|
|
2000
|
-
if (companyFilters) {
|
|
2001
|
-
id = { filters: `(_id eq \'${id}\') and (${companyFilters}${objectPermissionEditFilters})` };
|
|
2002
|
-
}
|
|
2003
|
-
}
|
|
2004
|
-
else if (!objPm.modifyAllRecords && !objPm.modifyCompanyRecords) {
|
|
2005
|
-
id = { filters: `(_id eq \'${id}\') and (owner eq \'${userId}\'${objectPermissionEditFilters})` };
|
|
2006
|
-
} else if (objectPermissionEditFilters) {
|
|
2007
|
-
if (_.isString(id)) {
|
|
2008
|
-
id = { filters: `(_id eq \'${id}\') and (${objectPermissionEditFilters})` }
|
|
2009
|
-
}
|
|
2010
|
-
else if (_.isObject(id)) {
|
|
2011
|
-
if (id.filters && !_.isString(id.filters)) {
|
|
2012
|
-
id.filters = formatFiltersToODataQuery(id.filters);
|
|
2013
|
-
}
|
|
2014
|
-
id.filters = id.filters ? `(${id.filters}) and (${objectPermissionEditFilters})` : `(${objectPermissionEditFilters})`;
|
|
2015
|
-
}
|
|
2016
|
-
}
|
|
2017
|
-
args[args.length - 2] = id;
|
|
2018
|
-
}
|
|
2019
|
-
|
|
2020
|
-
}
|
|
2021
|
-
|
|
2022
|
-
}
|
|
2023
|
-
|
|
2024
|
-
/***** get/set *****/
|
|
2025
|
-
public get schema(): SteedosSchema {
|
|
2026
|
-
return this._schema;
|
|
2027
|
-
}
|
|
2028
|
-
|
|
2029
|
-
public get name(): string {
|
|
2030
|
-
return this._name;
|
|
2031
|
-
}
|
|
2032
|
-
|
|
2033
|
-
public get fields(): Dictionary<SteedosFieldType> {
|
|
2034
|
-
return this._fields;
|
|
2035
|
-
}
|
|
2036
|
-
|
|
2037
|
-
public get actions(): Dictionary<SteedosActionType> {
|
|
2038
|
-
return this._actions;
|
|
2039
|
-
}
|
|
2040
|
-
|
|
2041
|
-
public get triggers(): Dictionary<SteedosTriggerType> {
|
|
2042
|
-
return this._triggers;
|
|
2043
|
-
}
|
|
2044
|
-
|
|
2045
|
-
public get listeners(): Dictionary<SteedosListenerConfig> {
|
|
2046
|
-
return this._listeners;
|
|
2047
|
-
}
|
|
2048
|
-
public set listeners(value: Dictionary<SteedosListenerConfig>) {
|
|
2049
|
-
this._listeners = value;
|
|
2050
|
-
}
|
|
2051
|
-
|
|
2052
|
-
public get list_views(): Dictionary<SteedosObjectListViewType> {
|
|
2053
|
-
return this._list_views;
|
|
2054
|
-
}
|
|
2055
|
-
|
|
2056
|
-
public get table_name(): string {
|
|
2057
|
-
return this._table_name;
|
|
2058
|
-
}
|
|
2059
|
-
|
|
2060
|
-
public get primaryField(): SteedosFieldType {
|
|
2061
|
-
return this._fields[this._idFieldName];
|
|
2062
|
-
}
|
|
2063
|
-
|
|
2064
|
-
public get primaryFields(): SteedosFieldType[] {
|
|
2065
|
-
return this._idFieldNames.map((fieldName) => {
|
|
2066
|
-
return this._fields[fieldName]
|
|
2067
|
-
});
|
|
2068
|
-
}
|
|
2069
|
-
}
|
|
2070
|
-
|
|
2071
|
-
export function getObject(objectName: string, schema?: SteedosSchema) {
|
|
2072
|
-
return (schema ? schema : getSteedosSchema()).getObject(objectName);
|
|
2073
|
-
}
|
|
2074
|
-
export function getLocalObject(objectName: string, schema?: SteedosSchema) {
|
|
2075
|
-
return (schema ? schema : getSteedosSchema()).getLocalObject(objectName);
|
|
2076
|
-
}
|