@steedos/standard-object-database 2.7.7 → 2.7.8-beta.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/main/default/objects/objects/buttons/design_fields_layout.button.js +35 -0
- package/main/default/objects/objects/buttons/design_fields_layout.button.yml +5 -0
- package/main/default/routes/object_fields_design.ejs +411 -0
- package/main/default/routes/object_fields_design.router.js +76 -0
- package/main/default/services/object_fields.service.js +218 -3
- package/package.json +5 -5
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* @Author: baozhoutao@steedos.com
|
|
3
|
+
* @Date: 2024-08-29 09:36:15
|
|
4
|
+
* @LastEditors: baozhoutao@steedos.com
|
|
5
|
+
* @LastEditTime: 2024-09-05 16:26:51
|
|
6
|
+
* @Description:
|
|
7
|
+
*/
|
|
8
|
+
module.exports = {
|
|
9
|
+
|
|
10
|
+
design_fields_layout: function(object_name, record_id, item_element) {
|
|
11
|
+
var record = this.record || Creator.getObjectById(record_id);
|
|
12
|
+
if (record && record.record) {
|
|
13
|
+
record = record.record;
|
|
14
|
+
}
|
|
15
|
+
if (!record) {
|
|
16
|
+
return toastr.error("未找到记录");
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
window.open(Creator.getRelativeUrl("/api/amisObjectFieldsDesign?oid=" + record_id+`&assetUrls=${Builder.settings.assetUrls}`));
|
|
20
|
+
},
|
|
21
|
+
design_fields_layoutVisible: function(object_name, record_id, record_permissions, data) {
|
|
22
|
+
var record = data && data.record;
|
|
23
|
+
if (!Creator.isSpaceAdmin()) {
|
|
24
|
+
return false
|
|
25
|
+
}
|
|
26
|
+
if (!record) {
|
|
27
|
+
record = Creator.odata.get("objects", record_id, "is_deleted");
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
if (record && !record.is_deleted && record.name != 'users' && record.created) {
|
|
31
|
+
return true;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
}
|
|
@@ -0,0 +1,411 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
* @Author: baozhoutao@steedos.com
|
|
3
|
+
* @Date: 2022-06-02 17:45:15
|
|
4
|
+
* @LastEditors: baozhoutao@steedos.com
|
|
5
|
+
* @LastEditTime: 2024-09-04 18:09:08
|
|
6
|
+
* @Description:
|
|
7
|
+
-->
|
|
8
|
+
<html>
|
|
9
|
+
<head>
|
|
10
|
+
<script src="/unpkg.com/@steedos-builder/fiddle@0.0.5/dist/builder-fiddle.umd.js"></script>
|
|
11
|
+
<script src="/unpkg.com/axios@0.26.1/dist/axios.min.js"></script>
|
|
12
|
+
<script src="https://unpkg.steedos.cn/flowbite@2.3.0/dist/flowbite.min.js"></script>
|
|
13
|
+
<script src="https://cdn.tailwindcss.com"></script>
|
|
14
|
+
</head>
|
|
15
|
+
|
|
16
|
+
<body>
|
|
17
|
+
<!-- Main modal -->
|
|
18
|
+
<div id="fieldLayoutModal" tabindex="-1" aria-hidden="true" class="hidden overflow-y-auto overflow-x-hidden fixed top-0 right-0 left-0 z-50 justify-center items-center w-full md:inset-0 h-[calc(100%-1rem)] max-h-full">
|
|
19
|
+
<div class="relative p-4 w-full max-w-2xl max-h-full">
|
|
20
|
+
<!-- Modal content -->
|
|
21
|
+
<div class="relative bg-white rounded-lg shadow dark:bg-gray-700">
|
|
22
|
+
<!-- Modal header -->
|
|
23
|
+
<div class="flex items-center justify-between p-4 md:p-5 border-b rounded-t dark:border-gray-600">
|
|
24
|
+
<h3 class="text-xl font-semibold text-gray-900 dark:text-white">
|
|
25
|
+
字段保存结果
|
|
26
|
+
</h3>
|
|
27
|
+
<button type="button" class="text-gray-400 bg-transparent hover:bg-gray-200 hover:text-gray-900 rounded-lg text-sm w-8 h-8 ms-auto inline-flex justify-center items-center dark:hover:bg-gray-600 dark:hover:text-white" data-modal-hide="fieldLayoutModal">
|
|
28
|
+
<svg class="w-3 h-3" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 14 14">
|
|
29
|
+
<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="m1 1 6 6m0 0 6 6M7 7l6-6M7 7l-6 6"/>
|
|
30
|
+
</svg>
|
|
31
|
+
<span class="sr-only">Close modal</span>
|
|
32
|
+
</button>
|
|
33
|
+
</div>
|
|
34
|
+
<!-- Modal body -->
|
|
35
|
+
<div class="p-4 md:p-5 space-y-4">
|
|
36
|
+
<ul class="space-y-4 text-gray-500 list-disc list-inside dark:text-gray-400" id="fieldLayoutList">
|
|
37
|
+
</ul>
|
|
38
|
+
</div>
|
|
39
|
+
</div>
|
|
40
|
+
</div>
|
|
41
|
+
</div>
|
|
42
|
+
<builder-fiddle host="<%=builderHost%>"></builder-fiddle>
|
|
43
|
+
<script>
|
|
44
|
+
const useOpenAPI= <%=(useOpenAPI === "true" || useOpenAPI === true)%>;
|
|
45
|
+
const settings = {
|
|
46
|
+
assetUrls: "<%=assetUrls%>",
|
|
47
|
+
rootUrl: "<%=rootUrl%>",
|
|
48
|
+
userId: "<%=userId%>",
|
|
49
|
+
tenantId: "<%=tenantId%>",
|
|
50
|
+
authToken: "<%=authToken%>",
|
|
51
|
+
messageOnly: true,
|
|
52
|
+
useOpenAPI: useOpenAPI,
|
|
53
|
+
oid: "<%=id%>",
|
|
54
|
+
pageId: "<%=id%>",
|
|
55
|
+
hiddenDeploy: true
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
let comp = document.querySelector("builder-fiddle");
|
|
59
|
+
|
|
60
|
+
// set the modal menu element
|
|
61
|
+
const $targetEl = document.getElementById('fieldLayoutModal');
|
|
62
|
+
// options with default values
|
|
63
|
+
const options = {
|
|
64
|
+
placement: 'top-center',
|
|
65
|
+
backdrop: 'dynamic',
|
|
66
|
+
backdropClasses:
|
|
67
|
+
'bg-gray-900/50 dark:bg-gray-900/80 fixed inset-0 z-40',
|
|
68
|
+
closable: true,
|
|
69
|
+
onHide: () => {
|
|
70
|
+
console.log('modal is hidden');
|
|
71
|
+
},
|
|
72
|
+
onShow: () => {
|
|
73
|
+
console.log('modal is shown');
|
|
74
|
+
},
|
|
75
|
+
onToggle: () => {
|
|
76
|
+
console.log('modal has been toggled');
|
|
77
|
+
},
|
|
78
|
+
};
|
|
79
|
+
// instance options object
|
|
80
|
+
const instanceOptions = {
|
|
81
|
+
id: 'fieldLayoutModal',
|
|
82
|
+
override: true
|
|
83
|
+
};
|
|
84
|
+
const modal = new Flowbite.default.Modal($targetEl, options, instanceOptions);
|
|
85
|
+
|
|
86
|
+
const loadPage = async () => {
|
|
87
|
+
const { assetUrls, rootUrl, userId, tenantId, authToken, oid } = settings;
|
|
88
|
+
|
|
89
|
+
// 如果传入 steedos rooturl
|
|
90
|
+
if (rootUrl && !authToken) return;
|
|
91
|
+
|
|
92
|
+
const initialContent = {
|
|
93
|
+
type: "page",
|
|
94
|
+
title: "Welcome to Steedos",
|
|
95
|
+
body: [],
|
|
96
|
+
regions: ["body"],
|
|
97
|
+
data: {
|
|
98
|
+
objectName: "space_users",
|
|
99
|
+
recordId: "",
|
|
100
|
+
initialValues: {},
|
|
101
|
+
appId: "builder",
|
|
102
|
+
title: "",
|
|
103
|
+
context: {
|
|
104
|
+
rootUrl,
|
|
105
|
+
userId,
|
|
106
|
+
tenantId,
|
|
107
|
+
authToken,
|
|
108
|
+
},
|
|
109
|
+
},
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
if (oid) {
|
|
113
|
+
const result = await axios.get(
|
|
114
|
+
`${rootUrl}/service/api/object_fields/amis/design/schema?oid=${oid}`,
|
|
115
|
+
{
|
|
116
|
+
withCredentials: true,
|
|
117
|
+
headers: { Authorization: `Bearer ${tenantId},${authToken}` },
|
|
118
|
+
}
|
|
119
|
+
);
|
|
120
|
+
if (result?.data) {
|
|
121
|
+
let schema = result.data.schema || initialContent;
|
|
122
|
+
|
|
123
|
+
// let objectName = result.data.object_name;
|
|
124
|
+
// let pageType = result.data.type;
|
|
125
|
+
if (typeof schema === "string") {
|
|
126
|
+
schema = JSON.parse(schema);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
if (!schema.data) {
|
|
130
|
+
schema.data = {};
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
if (!schema.data.context) {
|
|
134
|
+
schema.data.context = {};
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
// schema.data.objectName = objectName;
|
|
138
|
+
|
|
139
|
+
schema.data.context.rootUrl = rootUrl;
|
|
140
|
+
schema.data.context.tenantId = tenantId;
|
|
141
|
+
schema.data.context.userId = userId;
|
|
142
|
+
schema.data.context.authToken = authToken;
|
|
143
|
+
schema.data.context.user = <%- JSON.stringify(userSession) %>;
|
|
144
|
+
|
|
145
|
+
// if (objectName && pageType === "record") {
|
|
146
|
+
// const record = await axios.get(
|
|
147
|
+
// `${rootUrl}/api/v4/${objectName}?$orderby=modified&$top=1`,
|
|
148
|
+
// {
|
|
149
|
+
// withCredentials: true,
|
|
150
|
+
// headers: { Authorization: `Bearer ${tenantId},${authToken}` },
|
|
151
|
+
// }
|
|
152
|
+
// );
|
|
153
|
+
// const value = record?.data?.value;
|
|
154
|
+
// if (value?.length > 0) {
|
|
155
|
+
// schema.data.recordId = value[0]._id;
|
|
156
|
+
// }
|
|
157
|
+
// }
|
|
158
|
+
|
|
159
|
+
return schema || initialContent
|
|
160
|
+
}
|
|
161
|
+
} else {
|
|
162
|
+
return initialContent
|
|
163
|
+
}
|
|
164
|
+
};
|
|
165
|
+
|
|
166
|
+
const savePage = async (data) => {
|
|
167
|
+
const { rootUrl, userId, tenantId, authToken, oid } = settings;
|
|
168
|
+
|
|
169
|
+
if (!oid) {
|
|
170
|
+
return;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
// 保存schema时,清理context下的认证信息
|
|
174
|
+
const schema = JSON.parse(
|
|
175
|
+
JSON.stringify(data.data.AmisSchema, null, 4)
|
|
176
|
+
);
|
|
177
|
+
if (schema.data && typeof schema.data.context === 'object' ) {
|
|
178
|
+
delete schema.data.context
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
try {
|
|
182
|
+
delete schema.data.recordId;
|
|
183
|
+
delete schema.data.objectName;
|
|
184
|
+
} catch (error) {
|
|
185
|
+
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
return await axios.post(
|
|
189
|
+
`${rootUrl}/service/api/object_fields/amis/design/schema?oid=${oid}`,
|
|
190
|
+
{
|
|
191
|
+
withCredentials: true,
|
|
192
|
+
schema: schema,
|
|
193
|
+
},
|
|
194
|
+
{
|
|
195
|
+
headers: { Authorization: `Bearer ${tenantId},${authToken}` },
|
|
196
|
+
}
|
|
197
|
+
)
|
|
198
|
+
.catch(function (error) {
|
|
199
|
+
// handle error
|
|
200
|
+
console.log(error);
|
|
201
|
+
});
|
|
202
|
+
};
|
|
203
|
+
window.addEventListener('message', function (event) {
|
|
204
|
+
const { data } = event;
|
|
205
|
+
if (data) {
|
|
206
|
+
if(data.type === 'builder.loaded'){
|
|
207
|
+
comp.messageFrame('builder.EditorPropsChanged', { editorProps : JSON.stringify({
|
|
208
|
+
onDndAccept: function(event){
|
|
209
|
+
console.log(`onDndAccept===>`, event);
|
|
210
|
+
return true;
|
|
211
|
+
},
|
|
212
|
+
onInit: function(){
|
|
213
|
+
// 创建一个新的 style 元素
|
|
214
|
+
var style = document.createElement('style');
|
|
215
|
+
style.type="text/css";
|
|
216
|
+
style.media="screen";
|
|
217
|
+
// 将 CSS 样式写入 style 元素
|
|
218
|
+
style.innerHTML = `
|
|
219
|
+
.ae-RendererList-groupWrap .ae-RendererList-group:nth-child(n+3) {
|
|
220
|
+
display: none;
|
|
221
|
+
}
|
|
222
|
+
.ae-RendererList-groupWrap .ae-RendererList-head:nth-child(n+2) {
|
|
223
|
+
display: none !important;
|
|
224
|
+
}
|
|
225
|
+
.ae-RendererList-tabs-header .antd-Tabs-link:nth-child(n+2) {
|
|
226
|
+
display: none !important;
|
|
227
|
+
}
|
|
228
|
+
`;
|
|
229
|
+
|
|
230
|
+
// 将 style 元素插入到 head 中
|
|
231
|
+
document.head.appendChild(style);
|
|
232
|
+
},
|
|
233
|
+
disableBultinPlugin: false,
|
|
234
|
+
disablePluginList2: function(id, plugin){
|
|
235
|
+
if(lodash.includes([
|
|
236
|
+
"FlexPlugin",
|
|
237
|
+
"GridPlugin",
|
|
238
|
+
"ContainerPlugin",
|
|
239
|
+
"Layout_free_container",
|
|
240
|
+
"Layout_fixed_top",
|
|
241
|
+
"Layout_fixed",
|
|
242
|
+
"CollapseGroupPlugin",
|
|
243
|
+
"PanelPlugin",
|
|
244
|
+
"TabsPlugin",
|
|
245
|
+
"SwitchContainerPlugin",
|
|
246
|
+
"CRUDPlugin",
|
|
247
|
+
"Table2Plugin",
|
|
248
|
+
"TableCRUDPlugin",
|
|
249
|
+
"FormPlugin",
|
|
250
|
+
"ServicePlugin",
|
|
251
|
+
// "TextControlPlugin",
|
|
252
|
+
// "TextareaControlPlugin",
|
|
253
|
+
// "NumberControlPlugin",
|
|
254
|
+
// "SelectControlPlugin",
|
|
255
|
+
// "NestedSelectControlPlugin",
|
|
256
|
+
// "ChainedSelectControlPlugin",
|
|
257
|
+
// "DropDownButtonPlugin",
|
|
258
|
+
// "CheckboxesControlPlugin",
|
|
259
|
+
// "RadiosControlPlugin",
|
|
260
|
+
// "CheckboxControlPlugin",
|
|
261
|
+
// "DateControlPlugin",
|
|
262
|
+
// "DateRangeControlPlugin",
|
|
263
|
+
// "FileControlPlugin",
|
|
264
|
+
// "ImageControlPlugin",
|
|
265
|
+
// "ExcelControlPlugin",
|
|
266
|
+
// "TreeControlPlugin",
|
|
267
|
+
// "TagControlPlugin",
|
|
268
|
+
// "ListControlPlugin",
|
|
269
|
+
// "ButtonGroupControlPlugin",
|
|
270
|
+
// "ButtonToolbarControlPlugin",
|
|
271
|
+
// "PickerControlPlugin",
|
|
272
|
+
// "SwitchControlPlugin",
|
|
273
|
+
// "RangeControlPlugin",
|
|
274
|
+
// "RateControlPlugin",
|
|
275
|
+
// "CityControlPlugin",
|
|
276
|
+
// "TransferPlugin",
|
|
277
|
+
// "TabsTransferPlugin",
|
|
278
|
+
// "ColorControlPlugin",
|
|
279
|
+
// "ConditionBilderPlugin",
|
|
280
|
+
// "FieldSetControlPlugin",
|
|
281
|
+
// "ComboControlPlugin",
|
|
282
|
+
// "InputGroupControlPlugin",
|
|
283
|
+
// "TableControlPlugin",
|
|
284
|
+
// "MatrixControlPlugin",
|
|
285
|
+
// "RichTextControlPlugin",
|
|
286
|
+
// "DiffEditorControlPlugin",
|
|
287
|
+
// "CodeEditorControlPlugin",
|
|
288
|
+
// "SearchBoxPlugin",
|
|
289
|
+
// "KVControlPlugin",
|
|
290
|
+
// "RepeatControlPlugin",
|
|
291
|
+
// "UUIDControlPlugin",
|
|
292
|
+
// "LocationControlPlugin",
|
|
293
|
+
// "SubFormControlPlugin",
|
|
294
|
+
// "HiddenControlPlugin",
|
|
295
|
+
// "SignaturePlugin",
|
|
296
|
+
// "StaticControlPlugin",
|
|
297
|
+
"ButtonPlugin",
|
|
298
|
+
"ButtonGroupPlugin",
|
|
299
|
+
"NavPlugin",
|
|
300
|
+
"AnchorNavPlugin",
|
|
301
|
+
"TooltipWrapperPlugin",
|
|
302
|
+
"AlertPlugin",
|
|
303
|
+
"WizardPlugin",
|
|
304
|
+
"TableViewPlugin",
|
|
305
|
+
"WebComponentPlugin",
|
|
306
|
+
"AudioPlugin",
|
|
307
|
+
"VideoPlugin",
|
|
308
|
+
"CustomPlugin",
|
|
309
|
+
"TasksPlugin",
|
|
310
|
+
"EachPlugin",
|
|
311
|
+
"PropertyPlugin",
|
|
312
|
+
"IFramePlugin",
|
|
313
|
+
"QRCodePlugin",
|
|
314
|
+
"TplPlugin",
|
|
315
|
+
"IconPlugin",
|
|
316
|
+
"LinkPlugin",
|
|
317
|
+
"ListPlugin",
|
|
318
|
+
"List2Plugin",
|
|
319
|
+
"MappingPlugin",
|
|
320
|
+
"AvatarPlugin",
|
|
321
|
+
"CardPlugin",
|
|
322
|
+
"Card2Plugin",
|
|
323
|
+
"CardsPlugin",
|
|
324
|
+
"TablePlugin",
|
|
325
|
+
"TableCell2Plugin",
|
|
326
|
+
"ChartPlugin",
|
|
327
|
+
"SparklinePlugin",
|
|
328
|
+
"CarouselPlugin",
|
|
329
|
+
"ImagePlugin",
|
|
330
|
+
"ImagesPlugin",
|
|
331
|
+
"DatePlugin",
|
|
332
|
+
"TimePlugin",
|
|
333
|
+
"DatetimePlugin",
|
|
334
|
+
"CalendarPlugin",
|
|
335
|
+
"TagPlugin",
|
|
336
|
+
"JsonPlugin",
|
|
337
|
+
"ProgressPlugin",
|
|
338
|
+
"StatusPlugin",
|
|
339
|
+
"StepsPlugin",
|
|
340
|
+
"TimelinePlugin",
|
|
341
|
+
// "DividerPlugin",
|
|
342
|
+
// "CodeViewPlugin",
|
|
343
|
+
// "MarkdownPlugin",
|
|
344
|
+
// "CollapsePlugin",
|
|
345
|
+
"OfficeViewerPlugin",
|
|
346
|
+
"PdfViewerPlugin",
|
|
347
|
+
"LogPlugin",
|
|
348
|
+
"ActionPlugin",
|
|
349
|
+
"TableCellPlugin",
|
|
350
|
+
"ArrayControlPlugin",
|
|
351
|
+
"ControlPlugin",
|
|
352
|
+
"DateTimeControlPlugin",
|
|
353
|
+
"DateTimeRangeControlPlugin",
|
|
354
|
+
"EmailControlPlugin",
|
|
355
|
+
"FormulaControlPlugin",
|
|
356
|
+
"GroupControlPlugin",
|
|
357
|
+
"ItemPlugin",
|
|
358
|
+
"MonthControlPlugin",
|
|
359
|
+
"MonthRangeControlPlugin",
|
|
360
|
+
"PasswordControlPlugin",
|
|
361
|
+
"InputQuarterPlugin",
|
|
362
|
+
"QuarterRangePlugin",
|
|
363
|
+
"TimeControlPlugin",
|
|
364
|
+
"TimeRangeControlPlugin",
|
|
365
|
+
"TreeSelectControlPlugin",
|
|
366
|
+
"URLControlPlugin",
|
|
367
|
+
"YearControlPlugin",
|
|
368
|
+
"YearRangeControlPlugin",
|
|
369
|
+
"BreadcrumbPlugin",
|
|
370
|
+
"CustomRegionPlugin",
|
|
371
|
+
"DialogPlugin",
|
|
372
|
+
"DrawerPlugin",
|
|
373
|
+
"HBoxPlugin",
|
|
374
|
+
"ListItemPlugin",
|
|
375
|
+
"OperationPlugin",
|
|
376
|
+
// "PagePlugin",
|
|
377
|
+
"PaginationPlugin",
|
|
378
|
+
"PlainPlugin",
|
|
379
|
+
"ResetPlugin",
|
|
380
|
+
"SubmitPlugin",
|
|
381
|
+
"WrapperPlugin",
|
|
382
|
+
"ColumnToggler"
|
|
383
|
+
]
|
|
384
|
+
,id)){
|
|
385
|
+
return true;
|
|
386
|
+
}
|
|
387
|
+
return false
|
|
388
|
+
}
|
|
389
|
+
}, (key, value) => {
|
|
390
|
+
if (typeof value === 'function') {
|
|
391
|
+
return value.toString();
|
|
392
|
+
}
|
|
393
|
+
return value;
|
|
394
|
+
})} )
|
|
395
|
+
}
|
|
396
|
+
if (data.type === 'builder.loadContent') {
|
|
397
|
+
loadPage().then((content)=>{
|
|
398
|
+
comp.messageFrame('builder.contentChanged', { AmisSchema : content } )
|
|
399
|
+
})
|
|
400
|
+
}
|
|
401
|
+
if (data.type === 'builder.saveContent') {
|
|
402
|
+
savePage(data.data).then(()=>{
|
|
403
|
+
comp.messageFrame('builder.contentSaved')
|
|
404
|
+
})
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
})
|
|
408
|
+
comp.settings = settings;
|
|
409
|
+
</script>
|
|
410
|
+
</body>
|
|
411
|
+
</html>
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* @Author: baozhoutao@steedos.com
|
|
3
|
+
* @Date: 2022-04-04 16:34:28
|
|
4
|
+
* @Description:
|
|
5
|
+
*/
|
|
6
|
+
const express = require('express');
|
|
7
|
+
const router = express.Router();
|
|
8
|
+
const core = require('@steedos/core');
|
|
9
|
+
const ejs = require('ejs');
|
|
10
|
+
const fs = require('fs');
|
|
11
|
+
const _ = require('lodash');
|
|
12
|
+
const path = require('path');
|
|
13
|
+
const objectql = require('@steedos/objectql');
|
|
14
|
+
|
|
15
|
+
const getPublicAssetUrls = function(assetUrls){
|
|
16
|
+
const values = _.map(_.split(assetUrls), (item)=>{
|
|
17
|
+
if(_.startsWith(item, '/')){
|
|
18
|
+
return Meteor.absoluteUrl(item) ;
|
|
19
|
+
}else{
|
|
20
|
+
return item;
|
|
21
|
+
}
|
|
22
|
+
})
|
|
23
|
+
return _.join(values, ',')
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
router.get('/api/amisObjectFieldsDesign', core.requireAuthentication, async function (req, res) {
|
|
27
|
+
try {
|
|
28
|
+
res.set('Content-Type', 'text/html');
|
|
29
|
+
const userSession = req.user;
|
|
30
|
+
let assetUrls = getPublicAssetUrls(req.query.assetUrls);
|
|
31
|
+
const assetUrl = `assetUrl=${assetUrls.split(',').join("&assetUrl=")}&`;
|
|
32
|
+
|
|
33
|
+
// const dataContext = {
|
|
34
|
+
// rootUrl: __meteor_runtime_config__.ROOT_URL,
|
|
35
|
+
// tenantId: userSession.spaceId,
|
|
36
|
+
// userId: userSession.userId,
|
|
37
|
+
// authToken: userSession.authToken
|
|
38
|
+
// }
|
|
39
|
+
let locale = "zh-CN";
|
|
40
|
+
if (req.query.locale == "en-us") {
|
|
41
|
+
locale = "en-US";
|
|
42
|
+
} else if (req.query.locale == "zh-cn") {
|
|
43
|
+
locale = "zh-CN";
|
|
44
|
+
}
|
|
45
|
+
const retUrl = __meteor_runtime_config__.ROOT_URL + '/app/admin/objects/view/' + req.query.oid
|
|
46
|
+
const steedosBuilderUrl = process.env.STEEDOS_BUILDER_URL || 'https://builder.steedos.cn';
|
|
47
|
+
const builderHost = `${steedosBuilderUrl}/object?${assetUrl}retUrl=${retUrl}&locale=${locale}&isObjectDesign=1&pType=objectDesign`;
|
|
48
|
+
|
|
49
|
+
const filename = __dirname+'/object_fields_design.ejs'
|
|
50
|
+
const data = {
|
|
51
|
+
builderHost,
|
|
52
|
+
assetUrls,
|
|
53
|
+
rootUrl: __meteor_runtime_config__.ROOT_URL,
|
|
54
|
+
tenantId: userSession.spaceId,
|
|
55
|
+
userId: userSession.userId,
|
|
56
|
+
authToken: userSession.authToken,
|
|
57
|
+
userSession: userSession,
|
|
58
|
+
id: req.query.oid,
|
|
59
|
+
useOpenAPI: process.env.STEEDOS_PUBLIC_USE_OPEN_API
|
|
60
|
+
}
|
|
61
|
+
const options = {}
|
|
62
|
+
ejs.renderFile(filename, data, options, function(err, str){
|
|
63
|
+
if(err){
|
|
64
|
+
console.log(`err`, err)
|
|
65
|
+
}
|
|
66
|
+
// str => Rendered HTML string
|
|
67
|
+
res.send(str);
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
} catch (error) {
|
|
71
|
+
console.log(error)
|
|
72
|
+
res.status(500).send({ message: error.message });
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
});
|
|
76
|
+
exports.default = router;
|
|
@@ -6,12 +6,11 @@ const register = require("@steedos/metadata-registrar");
|
|
|
6
6
|
const steedosI18n = require("@steedos/i18n");
|
|
7
7
|
const _ = require("lodash");
|
|
8
8
|
const clone = require("clone");
|
|
9
|
-
|
|
9
|
+
const serviceObjectMixin = require('@steedos/service-object-mixin');
|
|
10
10
|
// 默认值字段代码:services/standard-object-database/main/default/services/object_fields.service.js
|
|
11
|
-
|
|
12
11
|
module.exports = {
|
|
13
12
|
name: "object_fields",
|
|
14
|
-
mixins: [],
|
|
13
|
+
mixins: [serviceObjectMixin],
|
|
15
14
|
/**
|
|
16
15
|
* Settings
|
|
17
16
|
*/
|
|
@@ -38,6 +37,27 @@ module.exports = {
|
|
|
38
37
|
const data = await this.getDefaultValueSchema(ctx);
|
|
39
38
|
return { status: 0, msg: "", data: data }
|
|
40
39
|
}
|
|
40
|
+
},
|
|
41
|
+
getAmisDesignSchema: {
|
|
42
|
+
// 需要传 objectName, targetObject(非必填), field_name 参数进来。
|
|
43
|
+
rest: {
|
|
44
|
+
method: "GET",
|
|
45
|
+
path: "/amis/design/schema"
|
|
46
|
+
},
|
|
47
|
+
async handler(ctx) {
|
|
48
|
+
const schema = await this.getAmisDesignSchema(ctx);
|
|
49
|
+
return { status: 0, msg: "", schema: schema }
|
|
50
|
+
}
|
|
51
|
+
},
|
|
52
|
+
saveAmisDesignSchema: {
|
|
53
|
+
rest: {
|
|
54
|
+
method: "POST",
|
|
55
|
+
path: "/amis/design/schema"
|
|
56
|
+
},
|
|
57
|
+
async handler(ctx) {
|
|
58
|
+
const data = await this.saveAmisDesignSchema(ctx);
|
|
59
|
+
return { status: 0, msg: "", data: data}
|
|
60
|
+
}
|
|
41
61
|
}
|
|
42
62
|
},
|
|
43
63
|
|
|
@@ -243,6 +263,201 @@ module.exports = {
|
|
|
243
263
|
body
|
|
244
264
|
}
|
|
245
265
|
}
|
|
266
|
+
},
|
|
267
|
+
getAmisDesignSchema: {
|
|
268
|
+
async handler(ctx) {
|
|
269
|
+
// console.log('ctx==>', ctx);
|
|
270
|
+
const userSession = ctx.meta.user;
|
|
271
|
+
const lng = userSession.language || 'zh-CN';
|
|
272
|
+
const oid = ctx.params.oid || 'text';
|
|
273
|
+
|
|
274
|
+
const object = await this.getObject("objects").findOne(oid);
|
|
275
|
+
|
|
276
|
+
if(object){
|
|
277
|
+
|
|
278
|
+
const groups = object.field_groups;
|
|
279
|
+
|
|
280
|
+
const getGroup = (groupName)=>{
|
|
281
|
+
if(groupName == 'undefined' || groupName == 'null'){
|
|
282
|
+
groupName = '';
|
|
283
|
+
}
|
|
284
|
+
return _.find(groups, (group)=>{
|
|
285
|
+
return group.group_name === groupName;
|
|
286
|
+
}) || {group_name: groupName}
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
const objectName = object.name;
|
|
290
|
+
let objectFields = await this.getObject('object_fields').find({filters: [['object', '=', objectName]]});
|
|
291
|
+
|
|
292
|
+
_.map(objectFields, (objectField)=>{
|
|
293
|
+
if(!objectField.group){
|
|
294
|
+
objectField.group = '基本信息'
|
|
295
|
+
}
|
|
296
|
+
})
|
|
297
|
+
|
|
298
|
+
return {
|
|
299
|
+
type: 'steedos-object',
|
|
300
|
+
name: objectName,
|
|
301
|
+
label: object.label,
|
|
302
|
+
description: object.description,
|
|
303
|
+
data: {
|
|
304
|
+
objectName
|
|
305
|
+
},
|
|
306
|
+
className: "steedos-amis-form steedos-field-layout-page m-4",
|
|
307
|
+
body: _.map(_.groupBy(_.orderBy(objectFields, function(o) { return o.sort_no || 100 }), 'group'), (items, groupName)=>{
|
|
308
|
+
const group = getGroup(groupName)
|
|
309
|
+
return {
|
|
310
|
+
type: 'steedos-field-group',
|
|
311
|
+
title: group.group_name,
|
|
312
|
+
collapsed: group.collapsed,
|
|
313
|
+
visible_on: group.visible_on,
|
|
314
|
+
body: _.map(items, (field)=>{
|
|
315
|
+
return {
|
|
316
|
+
type: `sfield-${field.type}`,
|
|
317
|
+
config: Object.assign({amis: {name: field.name}}, field)
|
|
318
|
+
}
|
|
319
|
+
})
|
|
320
|
+
}
|
|
321
|
+
})
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
}
|
|
326
|
+
},
|
|
327
|
+
saveAmisDesignSchema: {
|
|
328
|
+
async handler(ctx) {
|
|
329
|
+
// console.log('ctx==>', ctx);
|
|
330
|
+
const userSession = ctx.meta.user;
|
|
331
|
+
|
|
332
|
+
if(!userSession.is_space_admin){
|
|
333
|
+
return {
|
|
334
|
+
message: '无权限'
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
|
|
339
|
+
const lng = userSession.language || 'zh-CN';
|
|
340
|
+
// TODO 必须是管理员
|
|
341
|
+
|
|
342
|
+
const oid = ctx.params.oid || 'text';
|
|
343
|
+
const schema = ctx.params.schema;
|
|
344
|
+
const object = await this.getObject("objects").findOne(oid);
|
|
345
|
+
const fields = [];
|
|
346
|
+
const groups = [];
|
|
347
|
+
const objectSet = {
|
|
348
|
+
name: schema.name,
|
|
349
|
+
label: schema.label,
|
|
350
|
+
description: schema.description
|
|
351
|
+
};
|
|
352
|
+
if(!object){
|
|
353
|
+
return {}
|
|
354
|
+
}
|
|
355
|
+
let sort_no = 50;
|
|
356
|
+
_.each(schema.body, (group)=>{
|
|
357
|
+
if(group.type === 'steedos-field-group'){
|
|
358
|
+
const groupName = group.title;
|
|
359
|
+
_.each(group.body, (field)=>{
|
|
360
|
+
if(_.startsWith(field.type, 'sfield-')){
|
|
361
|
+
fields.push(Object.assign({}, field.config, {group: groupName, sort_no}));
|
|
362
|
+
sort_no += 50;
|
|
363
|
+
}
|
|
364
|
+
})
|
|
365
|
+
groups.push({
|
|
366
|
+
group_name: group.title,
|
|
367
|
+
collapsed: group.collapsed,
|
|
368
|
+
visible_on: group.visible_on
|
|
369
|
+
})
|
|
370
|
+
}else if(_.startsWith(field.type, 'sfield-')){
|
|
371
|
+
fields.push(Object.assign({}, field.config, {sort_no}));
|
|
372
|
+
sort_no += 50;
|
|
373
|
+
}
|
|
374
|
+
})
|
|
375
|
+
|
|
376
|
+
objectSet.field_groups = groups;
|
|
377
|
+
|
|
378
|
+
const object_fields = await this.getObject('object_fields');
|
|
379
|
+
const dbFields = await object_fields.directFind({filters: ['object','=', object.name]});
|
|
380
|
+
|
|
381
|
+
let insertFields = _.differenceBy(fields, dbFields, 'name').map(field => field.name);
|
|
382
|
+
let updateFields = _.intersectionBy(fields, dbFields, 'name').map(field => field.name);
|
|
383
|
+
let deleteFields = _.differenceBy(dbFields, fields, 'name').map(field => field.name);
|
|
384
|
+
|
|
385
|
+
// 用于记录成功和失败的字段
|
|
386
|
+
const log = {
|
|
387
|
+
insert: {
|
|
388
|
+
success: [],
|
|
389
|
+
error: []
|
|
390
|
+
},
|
|
391
|
+
update: {
|
|
392
|
+
success: [],
|
|
393
|
+
error: []
|
|
394
|
+
},
|
|
395
|
+
delete: {
|
|
396
|
+
success: [],
|
|
397
|
+
error: []
|
|
398
|
+
}
|
|
399
|
+
};
|
|
400
|
+
|
|
401
|
+
// 循环需要增加的字段
|
|
402
|
+
for (const fieldName of insertFields) {
|
|
403
|
+
try {
|
|
404
|
+
const newId = await object_fields._makeNewID();
|
|
405
|
+
const now = new Date();
|
|
406
|
+
const field = _.find(fields, { name: fieldName });
|
|
407
|
+
await object_fields.directInsert(Object.assign({}, field, {
|
|
408
|
+
_id: newId,
|
|
409
|
+
owner: userSession.userId,
|
|
410
|
+
space: userSession.spaceId,
|
|
411
|
+
object: object.name,
|
|
412
|
+
created: now,
|
|
413
|
+
modified: now,
|
|
414
|
+
created_by: userSession.userId,
|
|
415
|
+
modified_by: userSession.userId,
|
|
416
|
+
company_id: userSession.company_id,
|
|
417
|
+
company_ids: userSession.company_ids
|
|
418
|
+
}));
|
|
419
|
+
log.insert.success.push(fieldName);
|
|
420
|
+
} catch (e) {
|
|
421
|
+
log.insert.error.push(fieldName);
|
|
422
|
+
console.error(`新增字段 ${fieldName} 时出错:`, e);
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
// 循环需要修改的字段
|
|
427
|
+
const now = new Date();
|
|
428
|
+
for (const fieldName of updateFields) {
|
|
429
|
+
try {
|
|
430
|
+
const field = _.find(fields, { name: fieldName });
|
|
431
|
+
const id = _.find(dbFields, { name: fieldName })._id;
|
|
432
|
+
const submitField = _.omit(field, ['name', '_name']);
|
|
433
|
+
await object_fields.directUpdate(id, Object.assign({}, submitField, {
|
|
434
|
+
modified: now,
|
|
435
|
+
modified_by: userSession.userId
|
|
436
|
+
}));
|
|
437
|
+
log.update.success.push(fieldName);
|
|
438
|
+
} catch (e) {
|
|
439
|
+
log.update.error.push(fieldName);
|
|
440
|
+
console.log(`dbFields`, fieldName, dbFields)
|
|
441
|
+
console.error(`更新字段 ${fieldName} 时出错:`, e);
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
// 循环需要删除的字段
|
|
445
|
+
for (const fieldName of deleteFields) {
|
|
446
|
+
try {
|
|
447
|
+
const id = _.find(dbFields, { name: fieldName })._id;
|
|
448
|
+
await object_fields.directDelete(id);
|
|
449
|
+
log.delete.success.push(fieldName);
|
|
450
|
+
} catch (e) {
|
|
451
|
+
log.delete.error.push(fieldName);
|
|
452
|
+
console.error(`删除字段 ${fieldName} 时出错:`, e);
|
|
453
|
+
}
|
|
454
|
+
}
|
|
455
|
+
//label和修改时间未实时生效
|
|
456
|
+
const objectConn = await this.getObject('objects');
|
|
457
|
+
const current_object = await objectConn.findOne({filters:[["name","=",object.name]]});
|
|
458
|
+
await objectConn.update(current_object._id, Object.assign({}, objectSet, {reload_time: new Date()}))
|
|
459
|
+
return log;
|
|
460
|
+
}
|
|
246
461
|
}
|
|
247
462
|
}
|
|
248
463
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@steedos/standard-object-database",
|
|
3
|
-
"version": "2.7.
|
|
3
|
+
"version": "2.7.8-beta.2",
|
|
4
4
|
"main": "package.service.js",
|
|
5
5
|
"private": false,
|
|
6
6
|
"publishConfig": {
|
|
@@ -12,14 +12,14 @@
|
|
|
12
12
|
"description": "steedos package",
|
|
13
13
|
"dependencies": {
|
|
14
14
|
"@steedos-widgets/amis-lib": "^1.0.22",
|
|
15
|
-
"@steedos/metadata-core": "2.7.
|
|
16
|
-
"@steedos/service-object-mixin": "2.7.
|
|
17
|
-
"@steedos/standard-objects": "2.7.
|
|
15
|
+
"@steedos/metadata-core": "2.7.8-beta.2",
|
|
16
|
+
"@steedos/service-object-mixin": "2.7.8-beta.2",
|
|
17
|
+
"@steedos/standard-objects": "2.7.8-beta.2",
|
|
18
18
|
"amis-formula": "~6.3.0",
|
|
19
19
|
"clone": "^2.1.2",
|
|
20
20
|
"moleculer-bullmq": "3.0.0"
|
|
21
21
|
},
|
|
22
22
|
"repository": {},
|
|
23
23
|
"license": "MIT",
|
|
24
|
-
"gitHead": "
|
|
24
|
+
"gitHead": "d915768c87aaa7bc026623a4953d6f39c5ddace1"
|
|
25
25
|
}
|