@ibiz-template/runtime 0.4.17-dev.1 → 0.5.0-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (97) hide show
  1. package/dist/index.esm.js +629 -816
  2. package/dist/index.system.min.js +2 -2
  3. package/out/controller/common/control/md-control.controller.d.ts +21 -1
  4. package/out/controller/common/control/md-control.controller.d.ts.map +1 -1
  5. package/out/controller/common/control/md-control.controller.js +38 -2
  6. package/out/controller/control/form/form-detail/form-detail/form-detail.controller.d.ts.map +1 -1
  7. package/out/controller/control/form/form-detail/form-detail/form-detail.controller.js +2 -6
  8. package/out/controller/control/gantt/gantt.controller.d.ts +6 -189
  9. package/out/controller/control/gantt/gantt.controller.d.ts.map +1 -1
  10. package/out/controller/control/gantt/gantt.controller.js +6 -412
  11. package/out/controller/control/gantt/gantt.service.d.ts +2 -2
  12. package/out/controller/control/gantt/gantt.service.d.ts.map +1 -1
  13. package/out/controller/control/gantt/gantt.service.js +5 -5
  14. package/out/controller/control/kanban/kanban.controller.d.ts +2 -2
  15. package/out/controller/control/kanban/kanban.controller.d.ts.map +1 -1
  16. package/out/controller/control/kanban/kanban.controller.js +1 -1
  17. package/out/controller/control/list/list.controller.d.ts +1 -30
  18. package/out/controller/control/list/list.controller.d.ts.map +1 -1
  19. package/out/controller/control/list/list.controller.js +0 -41
  20. package/out/controller/control/md-ctrl/md-ctrl.controller.js +1 -1
  21. package/out/controller/control/search-bar/index.d.ts +1 -0
  22. package/out/controller/control/search-bar/index.d.ts.map +1 -1
  23. package/out/controller/control/search-bar/index.js +1 -0
  24. package/out/controller/control/search-bar/search-bar.controller.d.ts.map +1 -1
  25. package/out/controller/control/search-bar/search-bar.controller.js +48 -4
  26. package/out/controller/control/search-bar/search-bar.service.d.ts +24 -0
  27. package/out/controller/control/search-bar/search-bar.service.d.ts.map +1 -1
  28. package/out/controller/control/search-bar/search-bar.service.js +62 -16
  29. package/out/interface/controller/event/control/i-gantt.event.d.ts +2 -44
  30. package/out/interface/controller/event/control/i-gantt.event.d.ts.map +1 -1
  31. package/out/interface/controller/state/control/i-gantt.state.d.ts +2 -41
  32. package/out/interface/controller/state/control/i-gantt.state.d.ts.map +1 -1
  33. package/out/interface/controller/state/control/i-search-bar.state.d.ts +8 -1
  34. package/out/interface/controller/state/control/i-search-bar.state.d.ts.map +1 -1
  35. package/out/interface/service/i-parent-config/i-parent-config.d.ts +67 -0
  36. package/out/interface/service/i-parent-config/i-parent-config.d.ts.map +1 -0
  37. package/out/interface/service/i-parent-config/i-parent-config.js +1 -0
  38. package/out/interface/service/index.d.ts +1 -0
  39. package/out/interface/service/index.d.ts.map +1 -1
  40. package/out/interface/service/service/i-app-de.service.d.ts +10 -0
  41. package/out/interface/service/service/i-app-de.service.d.ts.map +1 -1
  42. package/out/service/de-service-util.d.ts +3 -2
  43. package/out/service/de-service-util.d.ts.map +1 -1
  44. package/out/service/de-service-util.js +11 -10
  45. package/out/service/dto/method.dto.d.ts +22 -3
  46. package/out/service/dto/method.dto.d.ts.map +1 -1
  47. package/out/service/dto/method.dto.js +65 -4
  48. package/out/service/service/entity/de.service.d.ts +10 -0
  49. package/out/service/service/entity/de.service.d.ts.map +1 -1
  50. package/out/service/service/entity/de.service.js +22 -1
  51. package/out/service/service/entity/method/method.d.ts.map +1 -1
  52. package/out/service/service/entity/method/method.js +1 -12
  53. package/out/service/vo/gantt-node-data/gantt-data-set-node-data.d.ts +0 -1
  54. package/out/service/vo/gantt-node-data/gantt-data-set-node-data.d.ts.map +1 -1
  55. package/out/service/vo/gantt-node-data/gantt-data-set-node-data.js +1 -2
  56. package/out/service/vo/gantt-node-data/gantt-node-data-util.d.ts +0 -7
  57. package/out/service/vo/gantt-node-data/gantt-node-data-util.d.ts.map +1 -1
  58. package/out/service/vo/gantt-node-data/gantt-node-data-util.js +0 -18
  59. package/out/ui-action/provider/ui-action-provider-base.d.ts +10 -0
  60. package/out/ui-action/provider/ui-action-provider-base.d.ts.map +1 -1
  61. package/out/ui-action/provider/ui-action-provider-base.js +20 -9
  62. package/out/utils/index.d.ts +1 -1
  63. package/out/utils/index.d.ts.map +1 -1
  64. package/out/utils/index.js +1 -1
  65. package/out/utils/open-redirect-view/open-redirect-view.d.ts +25 -1
  66. package/out/utils/open-redirect-view/open-redirect-view.d.ts.map +1 -1
  67. package/out/utils/open-redirect-view/open-redirect-view.js +72 -31
  68. package/out/utils/ui-domain/ui-domain.d.ts +28 -0
  69. package/out/utils/ui-domain/ui-domain.d.ts.map +1 -1
  70. package/out/utils/ui-domain/ui-domain.js +40 -0
  71. package/package.json +6 -6
  72. package/src/controller/common/control/md-control.controller.ts +50 -2
  73. package/src/controller/control/form/form-detail/form-detail/form-detail.controller.ts +2 -6
  74. package/src/controller/control/gantt/gantt.controller.ts +7 -492
  75. package/src/controller/control/gantt/gantt.service.ts +5 -5
  76. package/src/controller/control/kanban/kanban.controller.ts +2 -2
  77. package/src/controller/control/list/list.controller.ts +0 -54
  78. package/src/controller/control/md-ctrl/md-ctrl.controller.ts +1 -1
  79. package/src/controller/control/search-bar/index.ts +1 -0
  80. package/src/controller/control/search-bar/search-bar.controller.ts +63 -10
  81. package/src/controller/control/search-bar/search-bar.service.ts +70 -16
  82. package/src/interface/controller/event/control/i-gantt.event.ts +2 -38
  83. package/src/interface/controller/state/control/i-gantt.state.ts +2 -47
  84. package/src/interface/controller/state/control/i-search-bar.state.ts +9 -1
  85. package/src/interface/service/i-parent-config/i-parent-config.ts +66 -0
  86. package/src/interface/service/index.ts +1 -0
  87. package/src/interface/service/service/i-app-de.service.ts +13 -0
  88. package/src/service/de-service-util.ts +6 -4
  89. package/src/service/dto/method.dto.ts +77 -5
  90. package/src/service/service/entity/de.service.ts +26 -1
  91. package/src/service/service/entity/method/method.ts +1 -13
  92. package/src/service/vo/gantt-node-data/gantt-data-set-node-data.ts +1 -4
  93. package/src/service/vo/gantt-node-data/gantt-node-data-util.ts +0 -21
  94. package/src/ui-action/provider/ui-action-provider-base.ts +34 -15
  95. package/src/utils/index.ts +1 -0
  96. package/src/utils/open-redirect-view/open-redirect-view.ts +93 -38
  97. package/src/utils/ui-domain/ui-domain.ts +44 -0
@@ -65,7 +65,7 @@ export class SearchBarController
65
65
  * @author: zhujiamin
66
66
  * @Date: 2023-12-21 10:17:43
67
67
  */
68
- isBackendSearchGroup = true;
68
+ isBackendSearchGroup = this.model.searchBarStyle === 'SEARCHBAR2';
69
69
 
70
70
  /**
71
71
  * 表格控制器
@@ -103,6 +103,7 @@ export class SearchBarController
103
103
 
104
104
  protected async onCreated(): Promise<void> {
105
105
  await super.onCreated();
106
+
106
107
  const appDataEntity = await ibiz.hub.getAppDataEntity(
107
108
  this.model.appDataEntityId!,
108
109
  this.context.srfappid,
@@ -318,12 +319,46 @@ export class SearchBarController
318
319
  this.state.searchBarGroups = [];
319
320
  if (this.isBackendSearchGroup) {
320
321
  if (this.model.searchBarGroups && this.model.searchBarGroups.length > 0) {
321
- this.state.searchBarGroups = this.model.searchBarGroups.map(item => ({
322
- ...item,
323
- show: true,
324
- saved: false,
325
- searchGroupData: {},
326
- }));
322
+ this.state.searchBarGroups = this.model.searchBarGroups.map(
323
+ (item, index) => {
324
+ const tempGroup = {
325
+ ...item,
326
+ saved: false,
327
+ show: true,
328
+ searchGroupData: {} as IData,
329
+ order: (index + 1) * 100,
330
+ };
331
+ if (item.data) {
332
+ try {
333
+ // 解析data属性到对应位置
334
+ const tempData = JSON.parse(item.data);
335
+ if (tempData.theme_model) {
336
+ if (tempData.theme_model.sort) {
337
+ tempGroup.searchGroupData.sort = tempData.theme_model.sort;
338
+ }
339
+ if (tempData.theme_model.columnstates) {
340
+ tempGroup.searchGroupData.columnstates =
341
+ tempData.theme_model.columnstates;
342
+ }
343
+ if (tempData.theme_model.filternodes) {
344
+ tempGroup.searchGroupData.filternodes =
345
+ tempData.theme_model.filternodes;
346
+ }
347
+ if (tempData.theme_model.searchconds) {
348
+ tempGroup.searchGroupData.searchconds =
349
+ tempData.theme_model.searchconds;
350
+ }
351
+ }
352
+ if (tempData.valid_flag) {
353
+ tempGroup.show = tempData.valid_flag === '1';
354
+ }
355
+ } catch (error) {
356
+ ibiz.log.error(error);
357
+ }
358
+ }
359
+ return tempGroup;
360
+ },
361
+ );
327
362
  }
328
363
  // 请求并合并searchBarGroups ,这里只能拿到清单
329
364
  const res = await this.service.fetch();
@@ -337,16 +372,32 @@ export class SearchBarController
337
372
  mergeInLeft(existGroup, group);
338
373
  existGroup.saved = true;
339
374
  } else {
375
+ // 找出最大的order项的下标index,然后+2新增
376
+ const tempMaxOrderIndex = this.state.searchBarGroups.reduce(
377
+ (maxIndex, item, currentIndex) =>
378
+ item.order > this.state.searchBarGroups[maxIndex].order
379
+ ? currentIndex
380
+ : maxIndex,
381
+ 0,
382
+ );
340
383
  this.state.searchBarGroups.push({
341
- ...group,
342
384
  appId: this.context.srfappid,
343
- show: true,
344
385
  saved: true,
386
+ show: true,
345
387
  searchGroupData: {},
388
+ order: (tempMaxOrderIndex + 2) * 100,
389
+ // 以后台给的为准
390
+ ...group,
346
391
  } as IBackendSearchBarGroup);
347
392
  }
348
393
  });
349
394
  }
395
+ // 按照 order 属性从小到大排序
396
+ this.state.searchBarGroups.sort((a, b) => a.order - b.order);
397
+ // 更新 order 属性的值
398
+ this.state.searchBarGroups.forEach((item, index) => {
399
+ item.order = (index + 1) * 100;
400
+ });
350
401
  }
351
402
  }
352
403
 
@@ -369,8 +420,9 @@ export class SearchBarController
369
420
  // 根据是否保存过决定是更新还是新建
370
421
  if (this.state.selectedSearchGroupItem.saved) {
371
422
  await this.service.update(this.state.selectedSearchGroupItem.id!, {
372
- theme_model: saveParams,
423
+ searchGroupData: saveParams,
373
424
  show: this.state.selectedSearchGroupItem.show,
425
+ order: this.state.selectedSearchGroupItem.order,
374
426
  });
375
427
  ibiz.message.success('保存成功');
376
428
  } else {
@@ -404,6 +456,7 @@ export class SearchBarController
404
456
  const res = await this.service.get(groupItem.id!);
405
457
  if (res.ok) {
406
458
  mergeInLeft(groupItem, res.data);
459
+ groupItem.show = true;
407
460
  }
408
461
  }
409
462
  if (groupItem.searchGroupData && groupItem.searchGroupData.filternodes) {
@@ -114,31 +114,46 @@ export class SearchBarService {
114
114
  return res;
115
115
  }
116
116
 
117
+ /**
118
+ * 批量新建
119
+ * @param {IData} data
120
+ * @return {*}
121
+ * @author: zhujiamin
122
+ * @Date: 2023-12-26 15:49:00
123
+ */
124
+ async createBatch(data: IData[]): Promise<IHttpResponse> {
125
+ const createParams = this.convertFrontDataToBack(data);
126
+ const res = await this.app.net.post(`${this.themeUrl}`, createParams);
127
+ return res;
128
+ }
129
+
117
130
  /**
118
131
  * 更新数据
119
132
  *
120
133
  */
121
134
  async update(id: string, data: IData): Promise<IHttpResponse> {
122
- const updateParams = { app_view_tag: this.viewTag };
123
- if (data.theme_model) {
124
- Object.assign(updateParams, {
125
- theme_model: JSON.stringify(data.theme_model),
126
- });
127
- }
128
- if (data.caption) {
129
- Object.assign(updateParams, {
130
- name: data.caption,
131
- });
132
- }
133
- if (typeof data.show === 'boolean') {
134
- Object.assign(updateParams, {
135
- show: data.show,
136
- });
137
- }
135
+ const [updateParams] = this.convertFrontDataToBack([data]);
138
136
  const res = await this.app.net.put(`${this.themeUrl}/${id}`, updateParams);
139
137
  return res;
140
138
  }
141
139
 
140
+ /**
141
+ * 批量更新数据
142
+ * @param {IData} data
143
+ * @return {*}
144
+ * @author: zhujiamin
145
+ * @Date: 2023-12-26 11:11:34
146
+ */
147
+ async updateBatch(data: IData[]): Promise<IHttpResponse> {
148
+ const updateParams = this.convertFrontDataToBack(data);
149
+ const idUrl = updateParams.map(item => item.id).join(';');
150
+ const res = await this.app.net.put(
151
+ `${this.themeUrl}/${idUrl}`,
152
+ updateParams,
153
+ );
154
+ return res;
155
+ }
156
+
142
157
  /**
143
158
  * 转换后台数据成前端需要的格式
144
159
  * @param {IData} data
@@ -155,6 +170,45 @@ export class SearchBarService {
155
170
  if (item.theme_model) {
156
171
  tempItem.searchGroupData = JSON.parse(item.theme_model);
157
172
  }
173
+ if (typeof item.valid_flag === 'number') {
174
+ tempItem.show = item.valid_flag === 1;
175
+ }
176
+ if (item.order_value) {
177
+ tempItem.order = item.order_value;
178
+ }
179
+ return tempItem;
180
+ });
181
+ }
182
+
183
+ /**
184
+ * 转换前端数据成后台需要的格式
185
+ * @param {IData} data
186
+ * @return {*}
187
+ * @author: zhujiamin
188
+ * @Date: 2023-12-22 11:19:50
189
+ */
190
+ convertFrontDataToBack(data: IData[]): IData[] {
191
+ return data.map(item => {
192
+ const tempItem: IData = {
193
+ appId: item.appId,
194
+ app_view_tag: this.viewTag,
195
+ id: item.id,
196
+ };
197
+ if (item.caption) {
198
+ tempItem.name = item.caption;
199
+ }
200
+ if (
201
+ item.searchGroupData &&
202
+ Object.keys(item.searchGroupData).length > 0
203
+ ) {
204
+ tempItem.theme_model = JSON.stringify(item.searchGroupData);
205
+ }
206
+ if (typeof item.show === 'boolean') {
207
+ tempItem.valid_flag = item.show ? 1 : 0;
208
+ }
209
+ if (item.order) {
210
+ tempItem.order_value = item.order;
211
+ }
158
212
  return tempItem;
159
213
  });
160
214
  }
@@ -1,6 +1,4 @@
1
- import { IGanttNodeData } from '../../state';
2
- import { EventBase } from '../argument';
3
- import { IMDControlEvent } from './i-md-control.event';
1
+ import { ITreeGridExEvent } from './i-tree-grid-ex.event';
4
2
 
5
3
  /**
6
4
  * 甘特图事件
@@ -11,38 +9,4 @@ import { IMDControlEvent } from './i-md-control.event';
11
9
  * @interface IGanttEvent
12
10
  * @extends {IMDControlEvent}
13
11
  */
14
- export interface IGanttEvent extends IMDControlEvent {
15
- /**
16
- * 数据激活事件
17
- *
18
- * @type {({
19
- * event: EventBase & { nodeData: IGanttNodeData };
20
- * emitArgs: { data: IData[]; nodeData: IGanttNodeData };
21
- * })}
22
- * @memberof IGanttEvent
23
- */
24
- onActive: {
25
- event: EventBase & { nodeData: IGanttNodeData };
26
- emitArgs: { data: IData[]; nodeData: IGanttNodeData };
27
- };
28
-
29
- /**
30
- * 父节点刷新结束之后事件
31
- *
32
- * @type {({
33
- * event: EventBase & {
34
- * parentNode: IGanttNodeData;
35
- * children: IGanttNodeData[];
36
- * };
37
- * emitArgs: { parentNode: IGanttNodeData; children: IGanttNodeData[] };
38
- * })}
39
- * @memberof IGanttEvent
40
- */
41
- onAfterRefreshParent: {
42
- event: EventBase & {
43
- parentNode: IGanttNodeData;
44
- children: IGanttNodeData[];
45
- };
46
- emitArgs: { parentNode: IGanttNodeData; children: IGanttNodeData[] };
47
- };
48
- }
12
+ export interface IGanttEvent extends ITreeGridExEvent {}
@@ -1,5 +1,4 @@
1
- import { IColumnState } from './i-grid.state';
2
- import { IMDControlState } from './i-md-control.state';
1
+ import { ITreeGridExState } from './i-tree-grid-ex.state';
3
2
  import { ITreeNodeData } from './i-tree.state';
4
3
 
5
4
  /**
@@ -11,43 +10,7 @@ import { ITreeNodeData } from './i-tree.state';
11
10
  * @interface IGanttState
12
11
  * @extends {ITreeState}
13
12
  */
14
- export interface IGanttState extends IMDControlState {
15
- items: IGanttNodeData[];
16
-
17
- /**
18
- * 表格列状态数组
19
- *
20
- * @type {IColumnState[]}
21
- * @memberof IGanttState
22
- */
23
- columnStates: IColumnState[];
24
-
25
- /**
26
- * 树的根节点
27
- *
28
- * @type {IGanttNodeData}
29
- * @memberof IGanttState
30
- */
31
- rootNodes: IGanttNodeData[];
32
-
33
- /**
34
- * 查询条件
35
- *
36
- * @author tony001
37
- * @date 2023-12-11 18:12:20
38
- * @type {string}
39
- */
40
- query: string;
41
-
42
- /**
43
- * 快速搜索占位符
44
- *
45
- * @author tony001
46
- * @date 2023-12-11 18:12:29
47
- * @type {string}
48
- */
49
- placeHolder: string;
50
-
13
+ export interface IGanttState extends ITreeGridExState {
51
14
  /**
52
15
  * 甘特图样式
53
16
  *
@@ -154,12 +117,4 @@ export interface IGanttNodeData extends ITreeNodeData {
154
117
  * @memberof IGanttNodeData
155
118
  */
156
119
  parent?: IGanttNodeData;
157
-
158
- /**
159
- * 节点数据项
160
- *
161
- * @type {IData}
162
- * @memberof IGanttNodeData
163
- */
164
- nodeDataItem?: IData;
165
120
  }
@@ -151,7 +151,7 @@ export interface ISearchGroupData {
151
151
  searchconds?: IData;
152
152
 
153
153
  /**
154
- * 表格排序
154
+ * 表格排序查询条件
155
155
  */
156
156
  sort?: string;
157
157
  }
@@ -177,6 +177,14 @@ export interface IBackendSearchBarGroup extends ISearchBarGroup {
177
177
  */
178
178
  show: boolean;
179
179
 
180
+ /**
181
+ * 分组排序值
182
+ * @return {*}
183
+ * @author: zhujiamin
184
+ * @Date: 2023-12-26 11:21:02
185
+ */
186
+ order: number;
187
+
180
188
  /**
181
189
  * 搜索分组数据
182
190
  * @return {*}
@@ -0,0 +1,66 @@
1
+ /**
2
+ * 父数据关系配置,用在数据域当中计算实体的父数据关系
3
+ *
4
+ * @author chitanda
5
+ * @date 2023-12-26 15:12:59
6
+ * @export
7
+ * @interface IParentConfig
8
+ */
9
+ export interface IParentConfig {
10
+ /**
11
+ * 主实体代码标识
12
+ *
13
+ * @author chitanda
14
+ * @date 2023-12-26 15:12:08
15
+ * @type {string}
16
+ */
17
+ majorDECodeName: string;
18
+ /**
19
+ * 主实体代码标识2
20
+ *
21
+ * @author chitanda
22
+ * @date 2023-12-26 15:12:03
23
+ * @type {string}
24
+ */
25
+ majorDECodeName2: string;
26
+ /**
27
+ * 主实体名称
28
+ *
29
+ * @author chitanda
30
+ * @date 2023-12-26 15:12:57
31
+ * @type {string}
32
+ */
33
+ majorDEName: string;
34
+ /**
35
+ * 从实体代码标识
36
+ *
37
+ * @author chitanda
38
+ * @date 2023-12-26 15:12:52
39
+ * @type {string}
40
+ */
41
+ minorDECodeName: string;
42
+ /**
43
+ * 从实体代码标识2
44
+ *
45
+ * @author chitanda
46
+ * @date 2023-12-26 15:12:46
47
+ * @type {string}
48
+ */
49
+ minorDECodeName2: string;
50
+ /**
51
+ * 从实体名称
52
+ *
53
+ * @author chitanda
54
+ * @date 2023-12-26 15:12:41
55
+ * @type {string}
56
+ */
57
+ minorDEName: string;
58
+ /**
59
+ * 关系属性名称
60
+ *
61
+ * @author chitanda
62
+ * @date 2023-12-26 15:12:29
63
+ * @type {string}
64
+ */
65
+ pickupDEFName: string;
66
+ }
@@ -1,3 +1,4 @@
1
1
  export type { CodeListItem } from './code-list-item/code-list-item';
2
2
  export type { IDataEntity } from './i-data-entity/i-data-entity';
3
+ export type { IParentConfig } from './i-parent-config/i-parent-config';
3
4
  export type * from './service';
@@ -3,6 +3,7 @@ import { DECache } from '../../../service/utils';
3
3
  import { IFileService } from './i-file.service';
4
4
  import { IWorkFlowService } from './i-wf.service';
5
5
  import { IConfigService } from './i-config.service';
6
+ import { IDataEntity } from '../i-data-entity/i-data-entity';
6
7
 
7
8
  /**
8
9
  * 实体服务
@@ -321,6 +322,18 @@ export interface IAppDEService {
321
322
  data?: IData,
322
323
  ): Promise<IHttpResponse>;
323
324
 
325
+ /**
326
+ * 创建当前数据对象实例
327
+ *
328
+ * @author chitanda
329
+ * @date 2023-12-23 19:12:01
330
+ * @param {(IData[] | IDataEntity[] | IData | IDataEntity)} data
331
+ * @return {*} {(IDataEntity | IDataEntity[])}
332
+ */
333
+ createEntity(
334
+ data: IData[] | IDataEntity[] | IData | IDataEntity,
335
+ ): IDataEntity | IDataEntity[];
336
+
324
337
  /**
325
338
  * 当前实体服务销毁时调用
326
339
  *
@@ -32,11 +32,13 @@ export class DEServiceUtil {
32
32
 
33
33
  /**
34
34
  * 实体服务构造方法缓存
35
+ *
35
36
  * @author lxm
36
37
  * @date 2023-05-15 08:37:13
37
38
  * @protected
38
39
  */
39
- protected constructorCache: Map<string, DEServiceConstructor> = new Map();
40
+ protected static constructorCache: Map<string, DEServiceConstructor> =
41
+ new Map();
40
42
 
41
43
  /**
42
44
  * Creates an instance of DEServiceUtil.
@@ -55,8 +57,8 @@ export class DEServiceUtil {
55
57
  * @param {string} id 实体标识
56
58
  * @param {DEServiceConstructor} constructor
57
59
  */
58
- register(id: string, constructor: DEServiceConstructor): void {
59
- this.constructorCache.set(id, constructor);
60
+ static register(id: string, constructor: DEServiceConstructor): void {
61
+ this.constructorCache.set(id.toUpperCase(), constructor);
60
62
  }
61
63
 
62
64
  /**
@@ -82,7 +84,7 @@ export class DEServiceUtil {
82
84
  if (!entityModel) {
83
85
  throw new RuntimeError(`未找到应用实体[${id}]`);
84
86
  }
85
- const constructor = this.constructorCache.get(id);
87
+ const constructor = DEServiceUtil.constructorCache.get(id.toUpperCase());
86
88
  let service: IAppDEService;
87
89
  if (constructor) {
88
90
  service = await constructor(sandboxId, entityModel);
@@ -5,7 +5,6 @@ import {
5
5
  IAppDEMethodDTOField,
6
6
  } from '@ibiz/model-core';
7
7
  import { ModelError } from '@ibiz-template/core';
8
- import { AppDataEntity } from '../app-data-entity/app-data-entity';
9
8
  import { findModelChild } from '../../model';
10
9
  import { IAppDEService, IAppService, IDataEntity } from '../../interface';
11
10
 
@@ -28,6 +27,16 @@ export class MethodDto {
28
27
 
29
28
  protected dtoMap: Map<string, MethodDto> = new Map();
30
29
 
30
+ /**
31
+ * 当前 DTO 是否已经计算过关系相关逻辑
32
+ *
33
+ * @link this.calcRs
34
+ * @author chitanda
35
+ * @date 2023-12-26 16:12:18
36
+ * @protected
37
+ */
38
+ protected isCalcRs = false;
39
+
31
40
  constructor(
32
41
  protected service: IAppDEService,
33
42
  protected entity: IAppDataEntity,
@@ -95,6 +104,7 @@ export class MethodDto {
95
104
  */
96
105
  async get(context: IContext, data: IData): Promise<IData> {
97
106
  const params: IData = {};
107
+ const uiDomain = ibiz.uiDomainManager.get(context.srfsessionid);
98
108
  // 拷贝数据
99
109
  for (let i = 0; i < this.fields.length; i++) {
100
110
  const field = this.fields[i];
@@ -121,12 +131,27 @@ export class MethodDto {
121
131
  if (!field.refAppDataEntityId) {
122
132
  break;
123
133
  }
134
+
135
+ // 获取当前需要打包子数据的关系配置
136
+ let configs = uiDomain.getDERConfig(field.refAppDataEntityId!);
137
+ // 找到当前层级所在下标
138
+ const index = configs.findIndex(
139
+ config => config.majorDECodeName === this.entity.codeName,
140
+ );
141
+ // 过滤出当前层级之后的关系配置
142
+ configs = configs.slice(index + 1);
143
+
124
144
  const dto = await this.getFieldDto(context, field);
125
145
  // 子数据过滤参数
126
146
  const filterParams: IParams = {};
127
147
  if (field.refPickupAppDEFieldId) {
128
148
  filterParams[field.refPickupAppDEFieldId!] = data.srfkey;
129
149
  }
150
+ // 子层级数据过滤参数对象必须为空
151
+ configs.forEach(config => {
152
+ filterParams[config.pickupDEFName.toLowerCase()] = null;
153
+ });
154
+
130
155
  const items = await dto.select(context, filterParams);
131
156
  if (items) {
132
157
  const arr = [];
@@ -156,12 +181,13 @@ export class MethodDto {
156
181
  * @date 2022-10-10 23:10:50
157
182
  * @param {IContext} context
158
183
  * @param {IData[]} data
159
- * @return {*} {Promise<AppDataEntity[]>}
184
+ * @return {*} {Promise<IDataEntity[]>}
160
185
  */
161
- async sets(context: IContext, data: IData[]): Promise<AppDataEntity[]> {
186
+ async sets(context: IContext, data: IData[]): Promise<IDataEntity[]> {
162
187
  if (this.isLocalMode) {
163
188
  this.service.local.clear();
164
189
  }
190
+ await this.calcRs(context);
165
191
  return Promise.all(
166
192
  data.map(async datum => {
167
193
  const all = this.fields
@@ -181,10 +207,11 @@ export class MethodDto {
181
207
  const pKey = datum[this.entity.keyAppDEFieldId!];
182
208
  // 特殊处理,在子包内设置父对象标识
183
209
  items.forEach(item => {
184
- item.srfpkey = pKey;
185
210
  item[field.refPickupAppDEFieldId!] = pKey;
186
211
  });
187
212
  await dto.sets(context, items);
213
+ // 删除下边一行代码,DTO 的属性也不能直接删除。界面上表单类似重复器的地方会用到,保存时也需要由界面提供
214
+ // delete datum[key];
188
215
  } else {
189
216
  await dto.sets(context, []);
190
217
  }
@@ -193,7 +220,7 @@ export class MethodDto {
193
220
  for (let i = 0; i < all.length; i++) {
194
221
  await all[i];
195
222
  }
196
- const entityData = new AppDataEntity(this.entity, datum);
223
+ const entityData = this.service.createEntity(datum) as IDataEntity;
197
224
  if (this.isLocalMode) {
198
225
  await this.service.local.add(context, entityData);
199
226
  }
@@ -202,6 +229,51 @@ export class MethodDto {
202
229
  );
203
230
  }
204
231
 
232
+ /**
233
+ * 递归计算当前 DTO 相关实体的父关系配置
234
+ *
235
+ * @author chitanda
236
+ * @date 2023-12-26 16:12:13
237
+ * @protected
238
+ * @param {IContext} context
239
+ * @param {number} [depth=0] 递归层级,避免进入死循环。最大递归层级为 10
240
+ * @return {*} {Promise<void>}
241
+ */
242
+ protected async calcRs(context: IContext, depth: number = 0): Promise<void> {
243
+ if (this.isCalcRs || depth > 10) {
244
+ return;
245
+ }
246
+ this.isCalcRs = true;
247
+ depth += 1;
248
+
249
+ const uiDomain = ibiz.uiDomainManager.get(context.srfsessionid);
250
+ const dtoFields = this.fields.filter(field => field.type === 'DTOS');
251
+
252
+ for (let i = 0; i < dtoFields.length; i++) {
253
+ const field = dtoFields[i];
254
+ if (!field.refAppDataEntityId) {
255
+ continue;
256
+ }
257
+ const configs = uiDomain.getDERConfig(field.refAppDataEntityId!);
258
+ const index = configs.findIndex(
259
+ config => config.pickupDEFName === field.refPickupAppDEFieldId!,
260
+ );
261
+ if (index === -1) {
262
+ const dto = await this.getFieldDto(context, field);
263
+ uiDomain.setDERConfig(field.refAppDataEntityId!, {
264
+ majorDEName: this.entity.name!,
265
+ majorDECodeName: this.entity.codeName!,
266
+ majorDECodeName2: this.entity.codeName2!,
267
+ minorDEName: dto.entity.name!,
268
+ minorDECodeName: dto.entity.codeName!,
269
+ minorDECodeName2: dto.entity.codeName2!,
270
+ pickupDEFName: field.refPickupAppDEFieldId!,
271
+ });
272
+ await dto.calcRs(context, depth);
273
+ }
274
+ }
275
+ }
276
+
205
277
  /**
206
278
  * 获取子属性 DTO
207
279
  *
@@ -12,7 +12,8 @@ import { FileService } from '../file/file.service';
12
12
  import { findModelChild } from '../../../model';
13
13
  import { IAppDEService, IDataEntity } from '../../../interface';
14
14
  import { ConfigService } from '../config/config.service';
15
- import { getDEMethodProvider } from '../../../register/helper/de-method-register';
15
+ import { getDEMethodProvider } from '../../../register';
16
+ import { AppDataEntity } from '../../app-data-entity/app-data-entity';
16
17
 
17
18
  /**
18
19
  * 实体服务
@@ -378,6 +379,30 @@ export class DEService implements IAppDEService {
378
379
  return resPath + curPath;
379
380
  }
380
381
 
382
+ protected newEntity(data: IData | IDataEntity): IDataEntity {
383
+ if (data instanceof AppDataEntity) {
384
+ return data.clone();
385
+ }
386
+ return new AppDataEntity(this.model, data);
387
+ }
388
+
389
+ /**
390
+ * 创建数据对象实例
391
+ *
392
+ * @author chitanda
393
+ * @date 2023-12-23 19:12:57
394
+ * @param {(IData[] | IDataEntity[] | IData | IDataEntity)} data
395
+ * @return {*} {(IDataEntity | IDataEntity[])}
396
+ */
397
+ createEntity(
398
+ data: IData[] | IDataEntity[] | IData | IDataEntity,
399
+ ): IDataEntity | IDataEntity[] {
400
+ if (Array.isArray(data)) {
401
+ return data.map(item => this.newEntity(item));
402
+ }
403
+ return this.newEntity(data);
404
+ }
405
+
381
406
  /**
382
407
  * 服务实例销毁
383
408
  *