@ibiz-template/runtime 0.1.25 → 0.1.26
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/dist/index.esm.js +162 -36
- package/dist/index.system.min.js +1 -1
- package/dist/index.system.min.js.map +1 -1
- package/out/de-logic/de-logic-node/end-node/end-node.js +1 -1
- package/out/de-logic/utils/handle-src-val.js +1 -1
- package/out/global/global-util/global-util.d.ts +8 -1
- package/out/global/global-util/global-util.d.ts.map +1 -1
- package/out/global/global-util/global-util.js +8 -1
- package/out/logic-scheduler/executor/app-ui-logic-executor.d.ts +13 -1
- package/out/logic-scheduler/executor/app-ui-logic-executor.d.ts.map +1 -1
- package/out/logic-scheduler/executor/app-ui-logic-executor.js +106 -24
- package/out/service/service/control/control.service.d.ts.map +1 -1
- package/out/service/service/control/control.service.js +1 -1
- package/out/service/service/entity/de.service.d.ts.map +1 -1
- package/out/service/service/entity/de.service.js +1 -1
- package/out/service/service/entity/method/de-action.d.ts +1 -1
- package/out/service/service/entity/method/de-action.d.ts.map +1 -1
- package/out/service/service/entity/method/de-action.js +7 -7
- package/out/service/service/entity/method/method.d.ts +2 -2
- package/out/service/service/entity/method/method.d.ts.map +1 -1
- package/out/types.d.ts +11 -0
- package/out/types.d.ts.map +1 -1
- package/out/ui-logic/ui-logic-node/end-node/end-node.js +1 -1
- package/out/ui-logic/utils/handle-src-val.js +1 -1
- package/out/utils/index.d.ts +1 -0
- package/out/utils/index.d.ts.map +1 -1
- package/out/utils/index.js +1 -0
- package/out/utils/raw-value-util/raw-value-util.d.ts +23 -0
- package/out/utils/raw-value-util/raw-value-util.d.ts.map +1 -0
- package/out/utils/raw-value-util/raw-value-util.js +37 -0
- package/package.json +4 -4
- package/src/de-logic/de-logic-node/end-node/end-node.ts +1 -1
- package/src/de-logic/utils/handle-src-val.ts +1 -1
- package/src/global/global-util/global-util.ts +14 -1
- package/src/logic-scheduler/executor/app-ui-logic-executor.ts +129 -30
- package/src/service/service/control/control.service.ts +2 -2
- package/src/service/service/entity/de.service.ts +2 -2
- package/src/service/service/entity/method/de-action.ts +18 -12
- package/src/service/service/entity/method/method.ts +6 -6
- package/src/types.ts +12 -0
- package/src/ui-logic/ui-logic-node/end-node/end-node.ts +1 -1
- package/src/ui-logic/utils/handle-src-val.ts +1 -1
- package/src/utils/index.ts +1 -0
- package/src/utils/raw-value-util/raw-value-util.ts +37 -0
|
@@ -12,7 +12,7 @@ import {
|
|
|
12
12
|
import { notNilEmpty } from 'qx-util';
|
|
13
13
|
import { OpenAppViewCommand } from '../../command';
|
|
14
14
|
import { IModalData, IUILogicParams } from '../../interface';
|
|
15
|
-
import { getFormTypeFieldName } from '../../model';
|
|
15
|
+
import { calcDeCodeNameById, getFormTypeFieldName } from '../../model';
|
|
16
16
|
import { convertNavData } from '../../utils';
|
|
17
17
|
import { LogicExecutor } from './logic-executor';
|
|
18
18
|
|
|
@@ -113,6 +113,36 @@ export class AppUILogicExecutor extends LogicExecutor {
|
|
|
113
113
|
);
|
|
114
114
|
}
|
|
115
115
|
|
|
116
|
+
protected async calcOpenViewRef(
|
|
117
|
+
appUILogic: IAppUIOpenDataLogic,
|
|
118
|
+
parameters: IUILogicParams,
|
|
119
|
+
): Promise<IAppUILogicRefViewBase> {
|
|
120
|
+
const appDataEntityId = parameters.view.model.appDataEntityId!;
|
|
121
|
+
// 表单类型属性
|
|
122
|
+
const formTypeName = await getFormTypeFieldName(appDataEntityId);
|
|
123
|
+
if (!formTypeName) {
|
|
124
|
+
throw new RuntimeModelError(
|
|
125
|
+
appUILogic,
|
|
126
|
+
`${appDataEntityId}实体缺少表单类型应用实体属性`,
|
|
127
|
+
);
|
|
128
|
+
}
|
|
129
|
+
const { data } = parameters;
|
|
130
|
+
// 表单类型值
|
|
131
|
+
const formTypeValue = data[0][formTypeName];
|
|
132
|
+
if (!formTypeValue) {
|
|
133
|
+
throw new RuntimeModelError(appUILogic, '数据源无表单类型应用实体属性值');
|
|
134
|
+
}
|
|
135
|
+
const openViewRefs = appUILogic.openDataAppViews;
|
|
136
|
+
// 根据表单类型值找到实际打开的视图
|
|
137
|
+
const findView = openViewRefs?.find(item => item.refMode === formTypeValue);
|
|
138
|
+
if (!findView) {
|
|
139
|
+
throw new RuntimeError(
|
|
140
|
+
`没有找到与表单类型${formTypeValue}相关的实体的编辑视图`,
|
|
141
|
+
);
|
|
142
|
+
}
|
|
143
|
+
return findView;
|
|
144
|
+
}
|
|
145
|
+
|
|
116
146
|
/**
|
|
117
147
|
* 执行应用预置界面逻辑newdata
|
|
118
148
|
*
|
|
@@ -130,7 +160,7 @@ export class AppUILogicExecutor extends LogicExecutor {
|
|
|
130
160
|
parameters: IUILogicParams,
|
|
131
161
|
): Promise<IModalData> {
|
|
132
162
|
const { context, params, ...rest } = parameters;
|
|
133
|
-
const { data } = parameters;
|
|
163
|
+
const { data, view } = parameters;
|
|
134
164
|
const { enableWizardAdd, enableBatchAdd, batchAddOnly, newDataAppView } =
|
|
135
165
|
appUILogic;
|
|
136
166
|
|
|
@@ -142,8 +172,20 @@ export class AppUILogicExecutor extends LogicExecutor {
|
|
|
142
172
|
return { ok: false };
|
|
143
173
|
}
|
|
144
174
|
} else if (enableBatchAdd) {
|
|
145
|
-
//
|
|
146
|
-
|
|
175
|
+
// 查找批添加打开视图
|
|
176
|
+
const parentDeName = calcDeCodeNameById(
|
|
177
|
+
view.parentView!.model.appDataEntityId!,
|
|
178
|
+
);
|
|
179
|
+
const batchViews = appUILogic.batchAddAppViews;
|
|
180
|
+
newViewRef = batchViews?.find(viewRef => {
|
|
181
|
+
return viewRef.refMode!.toLowerCase() !== parentDeName;
|
|
182
|
+
});
|
|
183
|
+
if (!newViewRef) {
|
|
184
|
+
throw new RuntimeModelError(
|
|
185
|
+
appUILogic,
|
|
186
|
+
'没有找到批添加需要打开的选择视图',
|
|
187
|
+
);
|
|
188
|
+
}
|
|
147
189
|
} else if (batchAddOnly) {
|
|
148
190
|
// todo 只支持批添加
|
|
149
191
|
throw new ModelError(appUILogic, 'batchAddOnly暂未支持');
|
|
@@ -181,13 +223,20 @@ export class AppUILogicExecutor extends LogicExecutor {
|
|
|
181
223
|
}
|
|
182
224
|
|
|
183
225
|
// 打开视图
|
|
184
|
-
|
|
226
|
+
const result: IModalData = await ibiz.commands.execute(
|
|
185
227
|
OpenAppViewCommand.TAG,
|
|
186
228
|
newViewRef.refAppViewId,
|
|
187
229
|
tempContext,
|
|
188
230
|
tempParams,
|
|
189
231
|
rest,
|
|
190
232
|
);
|
|
233
|
+
|
|
234
|
+
// 执行批添加新建逻辑
|
|
235
|
+
if (enableBatchAdd && result.data) {
|
|
236
|
+
await this.doBatchAdd(appUILogic, result.data, context, newViewRef);
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
return result;
|
|
191
240
|
}
|
|
192
241
|
|
|
193
242
|
/**
|
|
@@ -239,33 +288,83 @@ export class AppUILogicExecutor extends LogicExecutor {
|
|
|
239
288
|
return findView;
|
|
240
289
|
}
|
|
241
290
|
|
|
242
|
-
|
|
291
|
+
/**
|
|
292
|
+
* 拿选中的数据做批添加新建
|
|
293
|
+
* @author lxm
|
|
294
|
+
* @date 2023-09-15 05:20:02
|
|
295
|
+
* @protected
|
|
296
|
+
* @param {IAppUIOpenDataLogic} appUILogic
|
|
297
|
+
* @param {IData[]} selections
|
|
298
|
+
* @param {IContext} context
|
|
299
|
+
* @param {IAppUILogicRefViewBase} newViewRef
|
|
300
|
+
* @return {*} {Promise<void>}
|
|
301
|
+
*/
|
|
302
|
+
protected async doBatchAdd(
|
|
243
303
|
appUILogic: IAppUIOpenDataLogic,
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
if (
|
|
250
|
-
|
|
251
|
-
appUILogic
|
|
252
|
-
|
|
253
|
-
);
|
|
254
|
-
}
|
|
255
|
-
const { data } = parameters;
|
|
256
|
-
// 表单类型值
|
|
257
|
-
const formTypeValue = data[0][formTypeName];
|
|
258
|
-
if (!formTypeValue) {
|
|
259
|
-
throw new RuntimeModelError(appUILogic, '数据源无表单类型应用实体属性值');
|
|
260
|
-
}
|
|
261
|
-
const openViewRefs = appUILogic.openDataAppViews;
|
|
262
|
-
// 根据表单类型值找到实际打开的视图
|
|
263
|
-
const findView = openViewRefs?.find(item => item.refMode === formTypeValue);
|
|
264
|
-
if (!findView) {
|
|
265
|
-
throw new RuntimeError(
|
|
266
|
-
`没有找到与表单类型${formTypeValue}相关的实体的编辑视图`,
|
|
304
|
+
selections: IData[],
|
|
305
|
+
context: IContext,
|
|
306
|
+
newViewRef: IAppUILogicRefViewBase,
|
|
307
|
+
): Promise<void> {
|
|
308
|
+
// 批添加新建选中数据后
|
|
309
|
+
if (selections?.length) {
|
|
310
|
+
const selfDe = await ibiz.hub.getAppDataEntity(
|
|
311
|
+
appUILogic.appDataEntityId!,
|
|
312
|
+
context.srfappid,
|
|
267
313
|
);
|
|
314
|
+
const minorDERs = selfDe.minorAppDERSs;
|
|
315
|
+
const pickParentDeName = newViewRef.refMode!.toLowerCase();
|
|
316
|
+
if (!minorDERs) {
|
|
317
|
+
throw new RuntimeModelError(selfDe, '实体没有从关系集合!');
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
// 获取选择视图对应父实体在当前实体里的外键属性名称。
|
|
321
|
+
let pickParentFieldName: string;
|
|
322
|
+
minorDERs?.forEach(item => {
|
|
323
|
+
const majorDeName = calcDeCodeNameById(item.majorAppDataEntityId!);
|
|
324
|
+
if (pickParentDeName === majorDeName) {
|
|
325
|
+
pickParentFieldName = item.parentAppDEFieldId!;
|
|
326
|
+
}
|
|
327
|
+
});
|
|
328
|
+
|
|
329
|
+
// 获取key为keymapping的特殊视图参数
|
|
330
|
+
const openViewKeyParam = newViewRef.navigateParams?.find(navParam => {
|
|
331
|
+
return navParam.key === 'keymapping';
|
|
332
|
+
});
|
|
333
|
+
let addData: IData[] = [];
|
|
334
|
+
if (openViewKeyParam) {
|
|
335
|
+
const keyValuePairs = openViewKeyParam.value!.split(';');
|
|
336
|
+
const keyMapping: IData = {};
|
|
337
|
+
// 遍历键值对数组并添加到 keyMapping 映射对象中
|
|
338
|
+
for (const pair of keyValuePairs) {
|
|
339
|
+
const [sourceKey, targetKey] = pair.split(':');
|
|
340
|
+
if (sourceKey && targetKey) {
|
|
341
|
+
keyMapping[sourceKey] = targetKey;
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
addData = selections.map(item => {
|
|
345
|
+
const tempData: IData = {
|
|
346
|
+
[pickParentFieldName]: item.srfkey,
|
|
347
|
+
};
|
|
348
|
+
// 遍历映射对象,将属性从 item 复制到 tempData
|
|
349
|
+
for (const key in keyMapping) {
|
|
350
|
+
if (Object.prototype.hasOwnProperty.call(keyMapping, key)) {
|
|
351
|
+
const targetKey = keyMapping[key];
|
|
352
|
+
if (Object.prototype.hasOwnProperty.call(item, key)) {
|
|
353
|
+
tempData[targetKey] = item[key];
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
return tempData;
|
|
358
|
+
});
|
|
359
|
+
} else {
|
|
360
|
+
addData = selections.map(item => ({
|
|
361
|
+
[pickParentFieldName]: item.srfkey,
|
|
362
|
+
}));
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
// 获取实体服务并调用创建接口
|
|
366
|
+
const service = ibiz.hub.getApp(context.srfappid).deService;
|
|
367
|
+
await service.exec(selfDe.id!, 'Create', context, addData);
|
|
268
368
|
}
|
|
269
|
-
return findView;
|
|
270
369
|
}
|
|
271
370
|
}
|
|
@@ -69,8 +69,8 @@ export class ControlService<T extends IControl = IControl> {
|
|
|
69
69
|
async exec(
|
|
70
70
|
methodName: string,
|
|
71
71
|
context: IParams,
|
|
72
|
-
data
|
|
73
|
-
params
|
|
72
|
+
data?: IData,
|
|
73
|
+
params?: IParams,
|
|
74
74
|
): Promise<IHttpResponse> {
|
|
75
75
|
const res = await this.app.deService.exec(
|
|
76
76
|
this.model.appDataEntityId!,
|
|
@@ -114,8 +114,8 @@ export class DEService implements IAppDEService {
|
|
|
114
114
|
exec(
|
|
115
115
|
id: string,
|
|
116
116
|
context: IParams,
|
|
117
|
-
params
|
|
118
|
-
params2
|
|
117
|
+
params?: IData,
|
|
118
|
+
params2?: IParams,
|
|
119
119
|
): Promise<IHttpResponse> {
|
|
120
120
|
const method = this.getMethod(id);
|
|
121
121
|
if (method) {
|
|
@@ -37,8 +37,8 @@ export class DEActionMethod extends Method {
|
|
|
37
37
|
|
|
38
38
|
async exec(
|
|
39
39
|
context: IParams,
|
|
40
|
-
data
|
|
41
|
-
params
|
|
40
|
+
data?: IData,
|
|
41
|
+
params?: IParams,
|
|
42
42
|
): Promise<HttpResponse<IData>> {
|
|
43
43
|
// 实体逻辑处理
|
|
44
44
|
|
|
@@ -47,22 +47,22 @@ export class DEActionMethod extends Method {
|
|
|
47
47
|
if (!deLogic) {
|
|
48
48
|
throw new RuntimeModelError(this.method, '缺少实体处理逻辑');
|
|
49
49
|
}
|
|
50
|
-
return execDELogicAction(deLogic, context, data, params);
|
|
50
|
+
return execDELogicAction(deLogic, context, data || {}, params || {});
|
|
51
51
|
}
|
|
52
52
|
|
|
53
|
-
if (!this.isLocalMode) {
|
|
53
|
+
if (data && !this.isLocalMode) {
|
|
54
54
|
data = await this.input.handle(context, data);
|
|
55
55
|
}
|
|
56
56
|
|
|
57
57
|
// 执行变更属性逻辑
|
|
58
|
-
if (!['READ', 'GETDRAFT'].includes(this.method.actionMode!)) {
|
|
59
|
-
await execFieldLogics(this.entity, 'change', context, data, params);
|
|
58
|
+
if (data && !['READ', 'GETDRAFT'].includes(this.method.actionMode!)) {
|
|
59
|
+
await execFieldLogics(this.entity, 'change', context, data, params || {});
|
|
60
60
|
}
|
|
61
61
|
|
|
62
62
|
let result: IHttpResponse<IData>;
|
|
63
63
|
switch (this.method.codeName) {
|
|
64
64
|
case 'Create':
|
|
65
|
-
result = await this.create(context, data
|
|
65
|
+
result = await this.create(context, data!, params || {});
|
|
66
66
|
break;
|
|
67
67
|
case 'Get':
|
|
68
68
|
result = await this.get(context, params);
|
|
@@ -74,10 +74,10 @@ export class DEActionMethod extends Method {
|
|
|
74
74
|
result = await this.remove(context, params);
|
|
75
75
|
break;
|
|
76
76
|
case 'Update':
|
|
77
|
-
result = await this.update(context, data
|
|
77
|
+
result = await this.update(context, data!, params);
|
|
78
78
|
break;
|
|
79
79
|
case 'CreateTemp':
|
|
80
|
-
result = await this.createTemp(context, data);
|
|
80
|
+
result = await this.createTemp(context, data!);
|
|
81
81
|
break;
|
|
82
82
|
case 'GetTemp':
|
|
83
83
|
result = await this.getTemp(context, data);
|
|
@@ -89,14 +89,14 @@ export class DEActionMethod extends Method {
|
|
|
89
89
|
result = await this.removeTemp(context, data);
|
|
90
90
|
break;
|
|
91
91
|
case 'UpdateTemp':
|
|
92
|
-
result = await this.updateTemp(context, data);
|
|
92
|
+
result = await this.updateTemp(context, data!);
|
|
93
93
|
break;
|
|
94
94
|
default: {
|
|
95
95
|
let path = this.calcPath(context);
|
|
96
96
|
if (this.method.needResourceKey) {
|
|
97
97
|
path = `${path}/${
|
|
98
98
|
context[this.entity.codeName!.toLowerCase()] ||
|
|
99
|
-
data[this.entity.keyAppDEFieldId!]
|
|
99
|
+
data?.[this.entity.keyAppDEFieldId!]
|
|
100
100
|
}`;
|
|
101
101
|
}
|
|
102
102
|
const res = await this.request(path, context, data, params);
|
|
@@ -106,7 +106,13 @@ export class DEActionMethod extends Method {
|
|
|
106
106
|
}
|
|
107
107
|
|
|
108
108
|
// 计算属性逻辑
|
|
109
|
-
await execFieldLogics(
|
|
109
|
+
await execFieldLogics(
|
|
110
|
+
this.entity,
|
|
111
|
+
'compute',
|
|
112
|
+
context,
|
|
113
|
+
result.data,
|
|
114
|
+
params || {},
|
|
115
|
+
);
|
|
110
116
|
|
|
111
117
|
return result;
|
|
112
118
|
}
|
|
@@ -80,8 +80,8 @@ export abstract class Method {
|
|
|
80
80
|
*/
|
|
81
81
|
abstract exec(
|
|
82
82
|
context: IParams,
|
|
83
|
-
params
|
|
84
|
-
params2
|
|
83
|
+
params?: IData,
|
|
84
|
+
params2?: IParams,
|
|
85
85
|
): Promise<HttpResponse>;
|
|
86
86
|
|
|
87
87
|
/**
|
|
@@ -99,8 +99,8 @@ export abstract class Method {
|
|
|
99
99
|
protected async request(
|
|
100
100
|
path: string,
|
|
101
101
|
context: IParams,
|
|
102
|
-
data
|
|
103
|
-
params
|
|
102
|
+
data?: IData,
|
|
103
|
+
params?: IParams,
|
|
104
104
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
105
105
|
): Promise<HttpResponse<any>> {
|
|
106
106
|
const { actionType, requestMethod } = this.method as IModel;
|
|
@@ -111,7 +111,7 @@ export abstract class Method {
|
|
|
111
111
|
case 'POST':
|
|
112
112
|
res = await this.app.net.post(
|
|
113
113
|
`${path}/${methodName}`,
|
|
114
|
-
notNilEmpty(data) ? data : params
|
|
114
|
+
notNilEmpty(data) ? data! : params!,
|
|
115
115
|
);
|
|
116
116
|
break;
|
|
117
117
|
case 'GET':
|
|
@@ -120,7 +120,7 @@ export abstract class Method {
|
|
|
120
120
|
case 'PUT': {
|
|
121
121
|
res = await this.app.net.put(
|
|
122
122
|
`${path}/${methodName}`,
|
|
123
|
-
notNilEmpty(data) ? data : params
|
|
123
|
+
notNilEmpty(data) ? data! : params!,
|
|
124
124
|
);
|
|
125
125
|
break;
|
|
126
126
|
}
|
package/src/types.ts
CHANGED
|
@@ -166,4 +166,16 @@ declare module '@ibiz-template/core' {
|
|
|
166
166
|
*/
|
|
167
167
|
scheduler: LogicSchedulerCenter;
|
|
168
168
|
}
|
|
169
|
+
|
|
170
|
+
interface IEnvironment {
|
|
171
|
+
/**
|
|
172
|
+
* 全局提供的功能性配置
|
|
173
|
+
*
|
|
174
|
+
* @description 默认无值使用默认配置,可以使用 environment.js 中的 globalConfig 覆盖默认配置
|
|
175
|
+
* @author chitanda
|
|
176
|
+
* @date 2023-09-15 14:09:14
|
|
177
|
+
* @type {IGlobalConfig}
|
|
178
|
+
*/
|
|
179
|
+
globalConfig?: IGlobalConfig;
|
|
180
|
+
}
|
|
169
181
|
}
|
|
@@ -26,7 +26,7 @@ export class EndNode extends UILogicNode {
|
|
|
26
26
|
ctx.result = null;
|
|
27
27
|
break;
|
|
28
28
|
case 'SRCVALUE': // 直接值
|
|
29
|
-
ctx.result = rawValue;
|
|
29
|
+
ctx.result = ibiz.util.rawValue.format(rawValue);
|
|
30
30
|
break;
|
|
31
31
|
case 'LOGICPARAM': // 逻辑参数对象
|
|
32
32
|
ctx.result = ctx.params[returnParamId!];
|
package/src/utils/index.ts
CHANGED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 直接值工具类
|
|
3
|
+
*
|
|
4
|
+
* @export
|
|
5
|
+
* @class RawValueUtil
|
|
6
|
+
*/
|
|
7
|
+
export class RawValueUtil {
|
|
8
|
+
/**
|
|
9
|
+
* 字符串是否完全由整数/浮点数组成
|
|
10
|
+
*
|
|
11
|
+
* @param {string} str
|
|
12
|
+
* @return {*}
|
|
13
|
+
*/
|
|
14
|
+
isNumber(str: string): boolean {
|
|
15
|
+
return /^-?\d+(\.\d+)?$/.test(str);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* 转换直接值
|
|
20
|
+
*
|
|
21
|
+
* @param {string} val
|
|
22
|
+
* @return {*}
|
|
23
|
+
*/
|
|
24
|
+
format(val: string | undefined): number | boolean | string | undefined {
|
|
25
|
+
let tempVal: number | boolean | string | undefined = val;
|
|
26
|
+
if (val !== undefined) {
|
|
27
|
+
if (val === 'true' || val === 'false') {
|
|
28
|
+
// 布尔值处理
|
|
29
|
+
tempVal = val === 'true';
|
|
30
|
+
} else if (this.isNumber(val)) {
|
|
31
|
+
// 数值处理
|
|
32
|
+
tempVal = parseFloat(val);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
return tempVal;
|
|
36
|
+
}
|
|
37
|
+
}
|