@ibiz-template/runtime 0.2.1 → 0.2.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.
Files changed (60) hide show
  1. package/dist/index.esm.js +301 -133
  2. package/dist/index.system.min.js +1 -1
  3. package/dist/index.system.min.js.map +1 -1
  4. package/out/controller/common/base.controller.js +4 -4
  5. package/out/controller/common/control/control.controller.d.ts.map +1 -1
  6. package/out/controller/common/control/control.controller.js +7 -0
  7. package/out/controller/common/view/view.controller.d.ts.map +1 -1
  8. package/out/controller/common/view/view.controller.js +3 -0
  9. package/out/controller/control/form/edit-form/edit-form.controller.d.ts.map +1 -1
  10. package/out/controller/control/form/edit-form/edit-form.controller.js +6 -2
  11. package/out/controller/control/form/form/form.controller.d.ts +9 -1
  12. package/out/controller/control/form/form/form.controller.d.ts.map +1 -1
  13. package/out/controller/control/form/form/form.controller.js +20 -1
  14. package/out/controller/control/form/form-detail/form-detail/form-detail.controller.d.ts +32 -3
  15. package/out/controller/control/form/form-detail/form-detail/form-detail.controller.d.ts.map +1 -1
  16. package/out/controller/control/form/form-detail/form-detail/form-detail.controller.js +84 -8
  17. package/out/controller/control/form/form-detail/form-group-panel/form-group-panel.controller.d.ts +1 -1
  18. package/out/controller/control/form/form-detail/form-group-panel/form-group-panel.controller.d.ts.map +1 -1
  19. package/out/controller/control/form/form-detail/form-group-panel/form-group-panel.controller.js +2 -2
  20. package/out/controller/control/form/form-detail/form-item/form-item.controller.d.ts +1 -1
  21. package/out/controller/control/form/form-detail/form-item/form-item.controller.d.ts.map +1 -1
  22. package/out/controller/control/form/form-detail/form-item/form-item.controller.js +2 -2
  23. package/out/interface/service/i-data-entity/i-data-entity.d.ts +19 -2
  24. package/out/interface/service/i-data-entity/i-data-entity.d.ts.map +1 -1
  25. package/out/interface/service/service/i-app-de.service.d.ts +11 -0
  26. package/out/interface/service/service/i-app-de.service.d.ts.map +1 -1
  27. package/out/logic-scheduler/scheduler/control-logic-scheduler.js +2 -2
  28. package/out/logic-scheduler/trigger/timer-trigger.d.ts.map +1 -1
  29. package/out/logic-scheduler/trigger/timer-trigger.js +4 -1
  30. package/out/model/view/view.d.ts.map +1 -1
  31. package/out/model/view/view.js +9 -1
  32. package/out/service/app-data-entity/app-data-entity.d.ts +3 -3
  33. package/out/service/app-data-entity/app-data-entity.d.ts.map +1 -1
  34. package/out/service/app-data-entity/app-data-entity.js +13 -12
  35. package/out/service/service/control/control.service.d.ts.map +1 -1
  36. package/out/service/service/control/control.service.js +1 -1
  37. package/out/service/service/entity/de.service.d.ts +15 -3
  38. package/out/service/service/entity/de.service.d.ts.map +1 -1
  39. package/out/service/service/entity/de.service.js +20 -4
  40. package/out/service/vo/control.vo.d.ts +12 -4
  41. package/out/service/vo/control.vo.d.ts.map +1 -1
  42. package/out/service/vo/control.vo.js +87 -50
  43. package/package.json +3 -3
  44. package/src/controller/common/base.controller.ts +4 -4
  45. package/src/controller/common/control/control.controller.ts +11 -0
  46. package/src/controller/common/view/view.controller.ts +2 -0
  47. package/src/controller/control/form/edit-form/edit-form.controller.ts +7 -2
  48. package/src/controller/control/form/form/form.controller.ts +26 -2
  49. package/src/controller/control/form/form-detail/form-detail/form-detail.controller.ts +102 -8
  50. package/src/controller/control/form/form-detail/form-group-panel/form-group-panel.controller.ts +2 -2
  51. package/src/controller/control/form/form-detail/form-item/form-item.controller.ts +2 -2
  52. package/src/interface/service/i-data-entity/i-data-entity.ts +22 -2
  53. package/src/interface/service/service/i-app-de.service.ts +16 -0
  54. package/src/logic-scheduler/scheduler/control-logic-scheduler.ts +2 -2
  55. package/src/logic-scheduler/trigger/timer-trigger.ts +4 -1
  56. package/src/model/view/view.ts +9 -1
  57. package/src/service/app-data-entity/app-data-entity.ts +21 -16
  58. package/src/service/service/control/control.service.ts +1 -2
  59. package/src/service/service/entity/de.service.ts +29 -5
  60. package/src/service/vo/control.vo.ts +101 -58
@@ -155,6 +155,11 @@ export class FormDetailController<T extends IDEFormDetail = IDEFormDetail>
155
155
  // 计算动态控制逻辑
156
156
  this.calcDynamicLogic(names);
157
157
 
158
+ // 计算显示,禁用,必填状态
159
+ this.calcDetailDisabled(this.data);
160
+ this.calcDetailVisible(this.data);
161
+ this.calcDetailRequired(this.data);
162
+
158
163
  // 计算动态样式表
159
164
  this.calcDynaClass(this.data);
160
165
  }
@@ -165,9 +170,14 @@ export class FormDetailController<T extends IDEFormDetail = IDEFormDetail>
165
170
  * @author lxm
166
171
  * @date 2022-09-20 18:09:07
167
172
  */
168
- async formStateNotify(state: FormNotifyState): Promise<void> {
173
+ async formStateNotify(_state: FormNotifyState): Promise<void> {
169
174
  // 计算动态控制逻辑
170
- this.calcDynamicLogic([], state);
175
+ this.calcDynamicLogic([], true);
176
+
177
+ // 计算显示,禁用,必填状态
178
+ this.calcDetailDisabled(this.data);
179
+ this.calcDetailVisible(this.data);
180
+ this.calcDetailRequired(this.data);
171
181
 
172
182
  // 计算动态样式表
173
183
  this.calcDynaClass(this.data);
@@ -180,10 +190,10 @@ export class FormDetailController<T extends IDEFormDetail = IDEFormDetail>
180
190
  * @date 2022-09-20 19:09:20
181
191
  * @protected
182
192
  * @param {string[]} names 变更的属性集合
183
- * @param {FormNotifyState} [state] 表单通知状态
193
+ * @param {boolean} [mustCalc=false] 是否强制计算一遍动态逻辑
184
194
  * @returns {*} {void}
185
195
  */
186
- protected calcDynamicLogic(names: string[], state?: FormNotifyState): void {
196
+ protected calcDynamicLogic(names: string[], mustCalc: boolean = false): void {
187
197
  // 逻辑优化,当父容器存在且为不显示时,不去计算自己的动态逻辑
188
198
  if (this.parent && !this.parent.state.visible) {
189
199
  return;
@@ -193,21 +203,21 @@ export class FormDetailController<T extends IDEFormDetail = IDEFormDetail>
193
203
  this.model.defdgroupLogics?.forEach(logic => {
194
204
  const relatedNames = logic.relatedDetailNames || [];
195
205
  // name是动态逻辑涉及到的时或state存在时
196
- if (state || isOverlap(relatedNames, names)) {
206
+ if (mustCalc || isOverlap(relatedNames, names)) {
197
207
  try {
198
208
  const ok = verifyFormGroupLogic(this.form.data, logic);
199
209
  switch (logic.logicCat) {
200
210
  // 动态空输入,不满足则必填
201
211
  case 'ITEMBLANK':
202
- this.state.required = !ok;
212
+ this.dynaLogicResult.required = !ok;
203
213
  break;
204
214
  // 动态启用,满足则启用
205
215
  case 'ITEMENABLE':
206
- this.state.disabled = !ok;
216
+ this.dynaLogicResult.disabled = !ok;
207
217
  break;
208
218
  // 动态显示,满足则显示
209
219
  case 'PANELVISIBLE':
210
- this.state.visible = ok;
220
+ this.dynaLogicResult.visible = ok;
211
221
  break;
212
222
  default:
213
223
  }
@@ -250,4 +260,88 @@ export class FormDetailController<T extends IDEFormDetail = IDEFormDetail>
250
260
  }
251
261
  }
252
262
  }
263
+
264
+ /**
265
+ * 计算项的禁用状态
266
+ *
267
+ * @param {IData} data
268
+ */
269
+ calcDetailDisabled(data: IData): void {
270
+ let enable = !this.dynaLogicResult.disabled;
271
+
272
+ // 上层计算为启用时计算预定义项启用逻辑
273
+ if (enable && this.form.scheduler) {
274
+ const itemEnable = this.form.scheduler.triggerItemEnable(this.model.id!, {
275
+ data: [data],
276
+ });
277
+ if (itemEnable !== undefined) {
278
+ enable = itemEnable;
279
+ }
280
+ }
281
+
282
+ // 修改state
283
+ this.state.disabled = !enable;
284
+ }
285
+
286
+ /**
287
+ * 计算项的显示状态
288
+ *
289
+ * @param {IData} data
290
+ */
291
+ calcDetailVisible(data: IData): void {
292
+ let { visible } = this.dynaLogicResult;
293
+
294
+ // 上层计算为显示时计算预定义项显示逻辑
295
+ if (visible && this.form.scheduler) {
296
+ const itemVIsible = this.form.scheduler.triggerItemVisible(
297
+ this.model.id!,
298
+ {
299
+ data: [data],
300
+ },
301
+ );
302
+ if (itemVIsible !== undefined) {
303
+ visible = itemVIsible;
304
+ }
305
+ }
306
+
307
+ // 修改state
308
+ this.state.visible = visible;
309
+ }
310
+
311
+ /**
312
+ * 计算项的必填状态
313
+ *
314
+ * @param {IData} data
315
+ */
316
+ calcDetailRequired(data: IData): void {
317
+ let allowEmpty = !this.dynaLogicResult.required;
318
+
319
+ // 上层计算为启用时计算预定义项空输入逻辑
320
+ if (allowEmpty && this.form.scheduler) {
321
+ const itemAllowEmpty = this.form.scheduler.triggerItemBlank(
322
+ this.model.id!,
323
+ {
324
+ data: [data],
325
+ },
326
+ );
327
+ if (itemAllowEmpty !== undefined) {
328
+ allowEmpty = itemAllowEmpty;
329
+ }
330
+ }
331
+
332
+ // 修改state
333
+ this.state.required = !allowEmpty;
334
+ }
335
+
336
+ /**
337
+ * 动态逻辑结果
338
+ * @author lxm
339
+ * @date 2023-09-21 03:36:37
340
+ * @protected
341
+ */
342
+ protected dynaLogicResult = {
343
+ visible: true,
344
+ disabled: false,
345
+ required: false,
346
+ };
253
347
  }
@@ -57,8 +57,8 @@ export class FormGroupPanelController<
57
57
  await this.initActionStates();
58
58
  }
59
59
 
60
- async formStateNotify(state: FormNotifyState): Promise<void> {
61
- super.calcDynamicLogic([], state);
60
+ async formStateNotify(_state: FormNotifyState): Promise<void> {
61
+ super.calcDynamicLogic([], true);
62
62
  // 只在加载后台数据之后,更新界面行为组状态
63
63
  if (this.state.actionGroupState) {
64
64
  this.state.actionGroupState.update(this.form.data.getOrigin());
@@ -292,10 +292,10 @@ export class FormItemController
292
292
  }
293
293
  }
294
294
 
295
- protected calcDynamicLogic(names: string[], state?: FormNotifyState): void {
295
+ protected calcDynamicLogic(names: string[], mustCalc: boolean = false): void {
296
296
  // 隐藏表单项不计算动态逻辑
297
297
  if (!this.model.hidden) {
298
- super.calcDynamicLogic(names, state);
298
+ super.calcDynamicLogic(names, mustCalc);
299
299
  }
300
300
  }
301
301
 
@@ -1,3 +1,5 @@
1
+ import { Srfuf } from '../../../service';
2
+
1
3
  /**
2
4
  * 应用数据实体接口
3
5
  *
@@ -35,7 +37,7 @@ export interface IDataEntity {
35
37
  * @date 2023-05-16 17:05:23
36
38
  * @type {string}
37
39
  */
38
- srfkeyfile: string;
40
+ srfkeyfield: string;
39
41
 
40
42
  /**
41
43
  * 实体主文本属性
@@ -44,7 +46,7 @@ export interface IDataEntity {
44
46
  * @date 2023-05-16 17:05:30
45
47
  * @type {string}
46
48
  */
47
- srfmajorfile: string;
49
+ srfmajorfield: string;
48
50
 
49
51
  /**
50
52
  * 实体主键值
@@ -55,6 +57,15 @@ export interface IDataEntity {
55
57
  */
56
58
  srfkey: string;
57
59
 
60
+ /**
61
+ * 临时实体主键值
62
+ *
63
+ * @author chitanda
64
+ * @date 2023-05-16 17:05:42
65
+ * @type {string}
66
+ */
67
+ tempsrfkey: string;
68
+
58
69
  /**
59
70
  * 实体主文本值
60
71
  *
@@ -64,6 +75,15 @@ export interface IDataEntity {
64
75
  */
65
76
  srfmajortext: string;
66
77
 
78
+ /**
79
+ * 是否是新建数据,0为新建
80
+ *
81
+ * @author lxm
82
+ * @date 2022-09-06 22:09:24
83
+ * @type {Srfuf}
84
+ */
85
+ srfuf: Srfuf;
86
+
67
87
  /**
68
88
  * 提供当前数据克隆操作,返回克隆后的当前实例
69
89
  *
@@ -102,4 +102,20 @@ export interface IAppDEService {
102
102
  params?: IParams,
103
103
  data?: IData,
104
104
  ): Promise<void>;
105
+
106
+ /**
107
+ * 获取 AI 聊天会话历史记录
108
+ *
109
+ * @author chitanda
110
+ * @date 2023-10-26 14:10:40
111
+ * @param {IParams} context
112
+ * @param {IParams} [params]
113
+ * @param {IData} [data]
114
+ * @return {*} {Promise<IHttpResponse>}
115
+ */
116
+ aiChatHistory(
117
+ context: IParams,
118
+ params?: IParams,
119
+ data?: IData,
120
+ ): Promise<IHttpResponse>;
105
121
  }
@@ -17,9 +17,9 @@ export class ControlLogicScheduler extends LogicScheduler {
17
17
  item => item.triggerType !== 'APPVIEWENGINE',
18
18
  );
19
19
  filterLogics.forEach(logic => {
20
- // 部件事件的部件名称在itemName上,统一写到ctrlName,与视图逻辑保持一致。
20
+ // 部件事件的部件名称在itemName上,当itemName没有时说明是部件自身触发此时名称在logicTag上,统一写到ctrlName,与视图逻辑保持一致。
21
21
  if (logic.triggerType === 'CTRLEVENT') {
22
- (logic as IData).ctrlName = logic.itemName;
22
+ (logic as IData).ctrlName = logic.itemName || logic.logicTag;
23
23
  }
24
24
  });
25
25
  super(filterLogics as ISchedulerLogic[]);
@@ -1,4 +1,4 @@
1
- import { RuntimeError } from '@ibiz-template/core';
1
+ import { RuntimeError, RuntimeModelError } from '@ibiz-template/core';
2
2
  import { LogicTrigger } from './logic-trigger';
3
3
 
4
4
  /**
@@ -15,6 +15,9 @@ export class TimerTrigger extends LogicTrigger {
15
15
  protected timer: number | null = null;
16
16
 
17
17
  start(): void {
18
+ if (!this.logic.timer) {
19
+ throw new RuntimeModelError(this.logic, '定时器缺少定时间隔');
20
+ }
18
21
  this.timer = setInterval(() => {
19
22
  if (!this.scheduler.defaultParamsCb) {
20
23
  throw new RuntimeError('定时器缺少默认参数回调');
@@ -53,5 +53,13 @@ export function getViewEngines(view: IAppView): IAppViewEngine[] {
53
53
  if (viewLayoutPanel) {
54
54
  appViewEngines.push(...(viewLayoutPanel.appViewEngines || []));
55
55
  }
56
- return appViewEngines;
56
+ return appViewEngines.filter(engine => {
57
+ switch (engine.engineCat) {
58
+ case 'CTRL':
59
+ ibiz.log.warn(`未支持的引擎分类:${engine.engineType}`);
60
+ return false;
61
+ default:
62
+ return true;
63
+ }
64
+ });
57
65
  }
@@ -4,6 +4,7 @@
4
4
  import { IAppDataEntity } from '@ibiz/model-core';
5
5
  import { clone, isNil } from 'ramda';
6
6
  import { DataTypes } from '@ibiz-template/core';
7
+ import { createUUID } from 'qx-util';
7
8
  import { Srfuf } from '../constant';
8
9
  import { findModelChild } from '../../model';
9
10
  import { IDataEntity } from '../../interface';
@@ -27,18 +28,18 @@ export class AppDataEntity implements IDataEntity {
27
28
 
28
29
  declare srfdecodename: string;
29
30
 
30
- declare srfkeyfile: string;
31
+ declare srfkeyfield: string;
31
32
 
32
- declare srfmajorfile: string;
33
+ declare srfmajorfield: string;
33
34
 
34
35
  declare srfkey: string;
35
36
 
36
- declare srfsourcekey: string;
37
-
38
37
  declare srfmajortext: string;
39
38
 
39
+ declare tempsrfkey: string;
40
+
40
41
  get srfuf(): Srfuf {
41
- return this.srfkey ? Srfuf.UPDATE : Srfuf.CREATE;
42
+ return this.srfkey === this.tempsrfkey ? Srfuf.UPDATE : Srfuf.CREATE;
42
43
  }
43
44
 
44
45
  /**
@@ -50,7 +51,6 @@ export class AppDataEntity implements IDataEntity {
50
51
  * @param {(IData | AppDataEntity)} data
51
52
  */
52
53
  constructor(entity: IAppDataEntity, data: IData | AppDataEntity) {
53
- let _srfkey: unknown;
54
54
  Object.defineProperty(this, '_entity', {
55
55
  enumerable: false,
56
56
  configurable: true,
@@ -71,26 +71,20 @@ export class AppDataEntity implements IDataEntity {
71
71
  return entity.codeName;
72
72
  },
73
73
  });
74
+
75
+ // 主键属性相关
74
76
  const keyAppField = findModelChild(
75
77
  entity.appDEFields || [],
76
78
  entity.keyAppDEFieldId!,
77
79
  );
78
80
  if (keyAppField) {
79
81
  const key = keyAppField.codeName!.toLowerCase();
80
- Object.defineProperty(this, 'srfkeyfile', {
82
+ Object.defineProperty(this, 'srfkeyfield', {
81
83
  get() {
82
84
  return key;
83
85
  },
84
86
  });
85
87
  Object.defineProperty(this, 'srfkey', {
86
- set(val: unknown) {
87
- _srfkey = val;
88
- },
89
- get() {
90
- return this._data[key] || _srfkey;
91
- },
92
- });
93
- Object.defineProperty(this, 'srfsourcekey', {
94
88
  set(val: unknown) {
95
89
  this._data[key] = val;
96
90
  },
@@ -105,9 +99,11 @@ export class AppDataEntity implements IDataEntity {
105
99
  entity.appDEFields || [],
106
100
  entity.majorAppDEFieldId!,
107
101
  );
102
+
103
+ // 主文本属性相关
108
104
  if (majorAppField) {
109
105
  const major = majorAppField.codeName!.toLowerCase();
110
- Object.defineProperty(this, 'srfmajorfile', {
106
+ Object.defineProperty(this, 'srfmajorfield', {
111
107
  get() {
112
108
  return major;
113
109
  },
@@ -123,6 +119,15 @@ export class AppDataEntity implements IDataEntity {
123
119
  } else {
124
120
  ibiz.log.warn(`实体[${entity.codeName}]未配置主文本字段`);
125
121
  }
122
+
123
+ // 设置临时主键
124
+ Object.defineProperty(this, 'tempsrfkey', {
125
+ enumerable: false,
126
+ configurable: true,
127
+ writable: true,
128
+ value: isNil(this.srfkey) ? createUUID() : this.srfkey,
129
+ });
130
+
126
131
  this.defineProperties();
127
132
  }
128
133
 
@@ -1,6 +1,5 @@
1
- import { IHttpResponse } from '@ibiz-template/core';
1
+ import { IHttpResponse, clone } from '@ibiz-template/core';
2
2
  import { IControl } from '@ibiz/model-core';
3
- import { clone } from 'ramda';
4
3
  import { ControlVO } from '../../vo/control.vo';
5
4
  import { UIMapField } from '../../vo/ui-map-field';
6
5
  import { Application } from '../../../application';
@@ -221,19 +221,43 @@ export class DEService implements IAppDEService {
221
221
  }
222
222
 
223
223
  /**
224
- * 计算请求路径
224
+ * 获取 AI 聊天会话历史记录
225
225
  *
226
226
  * @author chitanda
227
- * @date 2023-10-12 11:10:56
227
+ * @date 2023-10-26 14:10:58
228
+ * @param {IParams} context
229
+ * @param {IParams} [params={}]
230
+ * @param {IData} [data={}]
231
+ * @return {*} {Promise<IHttpResponse>}
232
+ */
233
+ aiChatHistory(
234
+ context: IParams,
235
+ params: IParams = {},
236
+ data: IData = {},
237
+ ): Promise<IHttpResponse> {
238
+ const app = ibiz.hub.getApp(this.model.appId);
239
+ const path = this.calcSsePath(context, true);
240
+ return app.net.post(path, data, { srfactag: 'AIChat', ...params });
241
+ }
242
+
243
+ /**
244
+ * 计算 AI 请求路径
245
+ *
246
+ * @author chitanda
247
+ * @date 2023-10-26 14:10:25
228
248
  * @protected
229
249
  * @param {IParams} context
250
+ * @param {boolean} [isHistories=false]
230
251
  * @return {*} {string}
231
252
  */
232
- protected calcSsePath(context: IParams): string {
253
+ protected calcSsePath(
254
+ context: IParams,
255
+ isHistories: boolean = false,
256
+ ): string {
233
257
  const srfkey = context[this.model.codeName!.toLowerCase()];
234
258
  const curPath = `/${this.model.codeName2!.toLowerCase()}/ssechatcompletion${
235
- srfkey ? `/${srfkey}` : ''
236
- }`;
259
+ isHistories ? '/histories' : ''
260
+ }${srfkey ? `/${srfkey}` : ''}`;
237
261
  const resPath = calcResPath(context, this.model);
238
262
  return resPath + curPath;
239
263
  }
@@ -1,7 +1,19 @@
1
+ import { createUUID } from 'qx-util';
1
2
  import { clone, isNil } from 'ramda';
2
3
  import { Srfuf } from '../constant';
3
4
  import { UIMapField } from './ui-map-field';
4
5
 
6
+ const BuildInKeys = [
7
+ 'srfkey',
8
+ 'srfmajortext',
9
+ 'srfmajorfield',
10
+ 'srfkeyfield',
11
+ 'tempsrfkey',
12
+ 'srfuf',
13
+ 'srfdeid',
14
+ 'srfdecodename',
15
+ ];
16
+
5
17
  /**
6
18
  * 部件UI显示层数据转换
7
19
  *
@@ -50,7 +62,16 @@ export class ControlVO {
50
62
  * @date 2022-09-07 19:09:42
51
63
  * @type {string}
52
64
  */
53
- declare srfkey: string;
65
+ declare srfkey?: string;
66
+
67
+ /**
68
+ * 临时主键
69
+ *
70
+ * @author lxm
71
+ * @date 2022-09-07 19:09:42
72
+ * @type {string}
73
+ */
74
+ declare tempsrfkey: string;
54
75
 
55
76
  /**
56
77
  * 主信息
@@ -59,7 +80,7 @@ export class ControlVO {
59
80
  * @date 2022-09-07 19:09:42
60
81
  * @type {string}
61
82
  */
62
- declare srfmajortext: string;
83
+ declare srfmajortext?: string;
63
84
 
64
85
  /**
65
86
  * 实体模型标识
@@ -86,7 +107,7 @@ export class ControlVO {
86
107
  * @date 2022-09-07 19:09:42
87
108
  * @type {string}
88
109
  */
89
- declare srfkeyfile: string;
110
+ declare srfkeyfield: string;
90
111
 
91
112
  /**
92
113
  * 实体主信息属性
@@ -95,7 +116,7 @@ export class ControlVO {
95
116
  * @date 2022-09-07 19:09:42
96
117
  * @type {string}
97
118
  */
98
- declare srfmajorfile: string;
119
+ declare srfmajorfield: string;
99
120
 
100
121
  /**
101
122
  * Creates an instance of ControlVO.
@@ -108,6 +129,7 @@ export class ControlVO {
108
129
  $origin: IData = {},
109
130
  $dataUIMap: Map<string, UIMapField> = new Map(),
110
131
  ) {
132
+ // 自身的属性
111
133
  Object.defineProperty(this, '$origin', {
112
134
  enumerable: false,
113
135
  configurable: true,
@@ -120,64 +142,88 @@ export class ControlVO {
120
142
  value: $dataUIMap || new Map(),
121
143
  });
122
144
 
123
- Object.defineProperty(this, 'srfuf', {
124
- get() {
125
- if (isNil(this.$origin.srfuf)) {
126
- return this.srfkey ? Srfuf.UPDATE : Srfuf.CREATE;
127
- }
128
- return this.$origin.srfuf;
129
- },
130
- enumerable: false,
131
- configurable: true,
132
- });
133
-
134
- Object.defineProperty(this, 'srfkey', {
135
- get() {
136
- return this.$origin.srfkey;
137
- },
138
- enumerable: false,
139
- configurable: true,
140
- });
141
-
142
- Object.defineProperty(this, 'srfmajortext', {
143
- get() {
144
- return this.$origin.srfmajortext;
145
- },
146
- enumerable: false,
147
- configurable: true,
148
- });
149
-
150
- Object.defineProperty(this, 'srfdeid', {
151
- get() {
152
- return this.$origin.srfdeid;
153
- },
154
- enumerable: false,
155
- configurable: true,
145
+ // 可读写的预置属性,主键属性和主文本属性
146
+ ['srfkey', 'srfmajortext'].forEach(key => {
147
+ if (Object.prototype.hasOwnProperty.call(this.$origin, key)) {
148
+ Object.defineProperty(this, key, {
149
+ get() {
150
+ return this.$origin.srfkey;
151
+ },
152
+ set(val: unknown) {
153
+ this.$origin.srfkey = val;
154
+ },
155
+ enumerable: false,
156
+ configurable: true,
157
+ });
158
+ } else if (this.$dataUIMap.has(key)) {
159
+ const { dataKey } = this.$dataUIMap.get(key)!;
160
+ Object.defineProperty(this, key, {
161
+ get() {
162
+ return this.$origin[dataKey];
163
+ },
164
+ set(val: unknown) {
165
+ this.$origin[dataKey] = val;
166
+ },
167
+ enumerable: false,
168
+ configurable: true,
169
+ });
170
+ } else {
171
+ Object.defineProperty(this, key, {
172
+ enumerable: false,
173
+ configurable: true,
174
+ writable: true,
175
+ value: null,
176
+ });
177
+ }
156
178
  });
157
179
 
158
- Object.defineProperty(this, 'srfdecodename', {
159
- get() {
160
- return this.$origin.srfdecodename;
161
- },
162
- enumerable: false,
163
- configurable: true,
164
- });
180
+ // tempsrfkey临时主键
181
+ if (Object.prototype.hasOwnProperty.call(this.$origin, 'tempsrfkey')) {
182
+ // $origin有的操作$origin的属性
183
+ Object.defineProperty(this, 'tempsrfkey', {
184
+ get() {
185
+ return this.$origin.tempsrfkey;
186
+ },
187
+ set(val: unknown) {
188
+ this.$origin.tempsrfkey = val;
189
+ },
190
+ enumerable: false,
191
+ configurable: true,
192
+ });
193
+ } else {
194
+ // $$origin没有的自己赋值
195
+ Object.defineProperty(this, 'tempsrfkey', {
196
+ enumerable: false,
197
+ configurable: true,
198
+ writable: true,
199
+ value: isNil(this.srfkey) ? createUUID() : this.srfkey,
200
+ });
201
+ }
165
202
 
166
- Object.defineProperty(this, 'srfkeyfile', {
203
+ // srfuf纯计算属性,不可修改
204
+ Object.defineProperty(this, 'srfuf', {
167
205
  get() {
168
- return this.$origin.srfkeyfile;
206
+ if (Object.prototype.hasOwnProperty.call(this.$origin, 'srfuf')) {
207
+ return this.$origin.srfuf;
208
+ }
209
+ return this.srfkey === this.tempsrfkey ? Srfuf.UPDATE : Srfuf.CREATE;
169
210
  },
170
211
  enumerable: false,
171
212
  configurable: true,
172
213
  });
173
214
 
174
- Object.defineProperty(this, 'srfmajorfile', {
175
- get() {
176
- return this.$origin.srfmajorfile;
215
+ // 只读的预置属性
216
+ ['srfdeid', 'srfdecodename', 'srfkeyfield', 'srfmajorfield'].forEach(
217
+ key => {
218
+ Object.defineProperty(this, key, {
219
+ get() {
220
+ return this.$origin[key];
221
+ },
222
+ enumerable: false,
223
+ configurable: true,
224
+ });
177
225
  },
178
- enumerable: false,
179
- configurable: true,
180
- });
226
+ );
181
227
 
182
228
  // 先转换映射的属性
183
229
  this.$dataUIMap.forEach((mapField, key) => {
@@ -213,8 +259,8 @@ export class ControlVO {
213
259
  mapField?: UIMapField,
214
260
  ): void {
215
261
  const isOriginField = mapField ? mapField.isOriginField : true;
216
- // srfuf和srfkey不做处理
217
- if (uiKey === 'srfuf') {
262
+ // 预置的属性不做处理
263
+ if (BuildInKeys.includes(uiKey)) {
218
264
  return;
219
265
  }
220
266
 
@@ -227,10 +273,7 @@ export class ControlVO {
227
273
  enumerable: true,
228
274
  configurable: true,
229
275
  get() {
230
- // srfkey 视图id优先,拿不到实体属性则拿界面属性(前端id)
231
- return uiKey === 'srfkey'
232
- ? this.$origin[dataKey] || this.$origin[uiKey]
233
- : this.$origin[dataKey];
276
+ return this.$origin[dataKey];
234
277
  },
235
278
  set(val) {
236
279
  // 有mapField的走它的转换