@ibiz-template/model-helper 0.6.0 → 0.6.1-alpha.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/src/model-util.ts DELETED
@@ -1,400 +0,0 @@
1
- import { calcUniqueTag } from '@ibiz/rt-model-api';
2
- import { IAppDERS } from '@ibiz/model-core';
3
- import { isEmpty } from 'ramda';
4
- import { formatPath, mergeModel, ServicePathUtil } from './utils';
5
- import { PSSysApp } from './model/PSSYSAPP';
6
-
7
- /**
8
- * 全动模型处理工具类,每个App一个实例
9
- *
10
- * @author chitanda
11
- * @date 2023-04-16 17:04:06
12
- * @export
13
- * @class ModelUtil
14
- */
15
- export class ModelUtil {
16
- /**
17
- * 模型缓存
18
- *
19
- * @author chitanda
20
- * @date 2023-04-16 17:04:40
21
- * @protected
22
- * @type {Map<string, IModel>}
23
- */
24
- protected modelCache: Map<string, IModel> = new Map();
25
-
26
- /**
27
- * 应用模型
28
- *
29
- * @author chitanda
30
- * @date 2023-04-16 17:04:17
31
- * @protected
32
- * @type {IModel}
33
- */
34
- protected appModel!: IModel;
35
-
36
- /**
37
- * 服务路径计算工具类
38
- *
39
- * @author chitanda
40
- * @date 2023-04-22 12:04:15
41
- * @type {ServicePathUtil}
42
- */
43
- servicePathUtil!: ServicePathUtil;
44
-
45
- /**
46
- * Creates an instance of GlobalModel.
47
- *
48
- * @author chitanda
49
- * @date 2023-04-13 21:04:21
50
- * @param {string}appId 应用标识
51
- * @param {string} modelTag
52
- * @param {(url: string, params?: IParams) => Promise<IModel>} get 模型加载方法
53
- * @param {boolean} hub 是否为 hub 应用基座
54
- */
55
- constructor(
56
- protected appId: string,
57
- protected modelTag: string,
58
- protected get: (url: string, params?: IParams) => Promise<IModel>,
59
- protected hub: boolean,
60
- protected permission: boolean = true,
61
- ) {}
62
-
63
- /**
64
- * 在使用前需要初始化,来进行异步加载
65
- *
66
- * @author chitanda
67
- * @date 2023-04-16 17:04:35
68
- * @return {*} {Promise<void>}
69
- */
70
- async init(): Promise<void> {
71
- await this.getAppModel();
72
- await this.specialHandling();
73
- // 填充缓存模型
74
- {
75
- const { cache } = this.appModel;
76
- if (cache) {
77
- const views = cache.getPSAppViews;
78
- if (views) {
79
- views.forEach((item: IModel) => {
80
- item.path = item.dynaModelFilePath;
81
- const appPath = this.calcAppPath(item.path);
82
- this.modelCache.set(appPath, item);
83
- });
84
- if (this.appModel.getAllPSAppViews == null) {
85
- this.appModel.getAllPSAppViews = views;
86
- } else {
87
- this.appModel.getAllPSAppViews.push(...views);
88
- }
89
- }
90
- }
91
- }
92
- const allDataEntities = (this.appModel.getAllPSAppDataEntities ||
93
- []) as IModel[];
94
- allDataEntities.forEach(item => {
95
- item.id = calcUniqueTag(item, false);
96
- });
97
- const allViews = (this.appModel.getAllPSAppViews || []) as IModel[];
98
- allViews.forEach(item => {
99
- item.id = calcUniqueTag(item, false);
100
- });
101
- const allAppDERSs = (this.appModel.getAllPSAppDERSs || []) as IModel[];
102
- allAppDERSs.forEach(item => {
103
- const major = item.getMajorPSAppDataEntity;
104
- const minor = item.getMinorPSAppDataEntity;
105
- item.majorAppDataEntityId = calcUniqueTag(major, false);
106
- item.minorAppDataEntityId = calcUniqueTag(minor, false);
107
- });
108
- this.servicePathUtil = new ServicePathUtil(
109
- allDataEntities,
110
- allAppDERSs as IAppDERS[],
111
- );
112
- if (
113
- this.appModel.getAllPSAppLans &&
114
- this.appModel.getAllPSAppLans.length > 0
115
- ) {
116
- ibiz.env.isEnableMultiLan = true;
117
- } else {
118
- ibiz.env.isEnableMultiLan = false;
119
- }
120
- }
121
-
122
- /**
123
- * 特殊处理应用模型
124
- *
125
- * @author chitanda
126
- * @date 2023-09-21 15:09:07
127
- * @protected
128
- * @return {*} {Promise<void>}
129
- */
130
- protected async specialHandling(): Promise<void> {
131
- // 特殊处理预置全局界面行为,附加一些特殊的模板预置模型
132
- if (this.appModel.getAllPSAppDEUIActions) {
133
- mergeModel(
134
- this.appModel.getAllPSAppDEUIActions,
135
- PSSysApp.getAllPSAppDEUIActions,
136
- 'codeName',
137
- );
138
- }
139
- }
140
-
141
- /**
142
- * 获取应用模型
143
- *
144
- * @author chitanda
145
- * @date 2023-04-16 17:04:21
146
- * @return {*} {Promise<IModel>}
147
- */
148
- async getAppModel(): Promise<IModel> {
149
- if (!this.appModel) {
150
- let appPath: string = '/PSSYSAPP.json';
151
- if (this.hub && ibiz.env.hub) {
152
- appPath = `/PSSYSAPP.hub.json`;
153
- }
154
- if (this.permission === false) {
155
- appPath = `/simple/PSSYSAPP.simple.json`;
156
- }
157
- this.appModel = await this.getModel(appPath);
158
- this.appModel.id = this.appId;
159
- }
160
- return this.appModel;
161
- }
162
-
163
- /**
164
- * 加载应用模型全局样式
165
- *
166
- * @author chitanda
167
- * @date 2023-09-06 10:09:11
168
- * @return {*} {(Promise<string | null>)}
169
- */
170
- async getAppStyle(): Promise<string | null> {
171
- let style: string = '';
172
- try {
173
- let stylePath: string = '/PSSYSAPP.json.css';
174
- if (this.hub && ibiz.env.hub) {
175
- stylePath = `/PSSYSAPP.hubsubapp.json.css`;
176
- }
177
- if (this.permission === false) {
178
- stylePath = `/simple/PSSYSAPP.simple.json.css`;
179
- }
180
- style = await this.getStyleModel(stylePath);
181
- if (style) {
182
- return style;
183
- }
184
- } catch (error) {
185
- // 忽略样式加载异常
186
- ibiz.log.error(error);
187
- }
188
- return null;
189
- }
190
-
191
- /**
192
- * 根据应用实体 codeName 或者 id 获取应用实体模型
193
- *
194
- * @author chitanda
195
- * @date 2023-04-16 18:04:45
196
- * @param {string} tag
197
- * @param {boolean} [isId=true]
198
- * @param {boolean} [ignoreCase=false]
199
- * @return {*} {Promise<IModel>}
200
- */
201
- async getAppDataEntityModel(
202
- tag: string,
203
- isId: boolean = true,
204
- ignoreCase: boolean = false,
205
- ): Promise<IModel> {
206
- const allDataEntities = this.appModel.getAllPSAppDataEntities as IModel[];
207
- if (allDataEntities && allDataEntities.length > 0) {
208
- const lowerTag = tag.toLowerCase();
209
- let dataEntity: IModel | undefined;
210
- if (isId) {
211
- dataEntity = allDataEntities.find(v => {
212
- if (ignoreCase) {
213
- return v.id.toLowerCase() === lowerTag;
214
- }
215
- return v.id === tag;
216
- });
217
- } else {
218
- dataEntity = allDataEntities.find(v => {
219
- if (ignoreCase) {
220
- return v.codeName.toLowerCase() === lowerTag;
221
- }
222
- return v.codeName === tag;
223
- });
224
- }
225
- if (dataEntity) {
226
- return this.getModel(dataEntity.path);
227
- }
228
- }
229
- throw new Error(`应用[${this.appId}]未找到数据实体[${tag}]`);
230
- }
231
-
232
- /**
233
- * 根据应用视图 id 获取应用视图模型,如果给了 params 则每次都会重新加载模型
234
- *
235
- * @author chitanda
236
- * @date 2024-01-15 12:01:36
237
- * @param {string} tag
238
- * @param {IParams} [params]
239
- * @param {boolean} [isDynamic]
240
- * @return {*} {Promise<IModel>}
241
- */
242
- async getAppViewModel(
243
- tag: string,
244
- params?: IParams,
245
- isDynamic?: boolean,
246
- ): Promise<IModel> {
247
- const allViews = this.appModel.getAllPSAppViews as IModel[];
248
- if (allViews && allViews.length > 0) {
249
- const lowerTag = tag.toLowerCase();
250
- const exTag = `.${lowerTag}`;
251
- const view = allViews.find(
252
- v => v.id.endsWith(exTag) || v.id === lowerTag,
253
- );
254
- if (view) {
255
- return this.getModel(view.path, params, isDynamic);
256
- }
257
- }
258
- throw new Error(`应用[${this.appId}]未找到视图[${tag}]`);
259
- }
260
-
261
- /**
262
- * 加载应用多语言模型
263
- *
264
- * @author chitanda
265
- * @date 2023-08-24 22:08:23
266
- * @param {string} language
267
- * @return {*} {Promise<IModel>}
268
- */
269
- async getPSAppLang(language: string): Promise<IModel> {
270
- const app = await this.getAppModel();
271
- if (app.getAllPSAppLans) {
272
- const langs = app.getAllPSAppLans as IModel[];
273
- const lang = langs.find(item => item.language === language);
274
- if (lang) {
275
- return this.getModel(lang.path);
276
- }
277
- ibiz.log.error(`[${language}]语言未支持`);
278
- }
279
- return {};
280
- }
281
-
282
- /**
283
- * 加载应用样式字符串
284
- *
285
- * @author chitanda
286
- * @date 2023-09-07 11:09:11
287
- * @param {string} modelPath
288
- * @return {*} {Promise<string>}
289
- */
290
- getStyleModel(modelPath: string): Promise<string> {
291
- let url: string;
292
- if (this.hub) {
293
- url = this.calcAppPath(modelPath);
294
- } else {
295
- url = this.calcSubAppPath(modelPath);
296
- }
297
- return this.get(url) as unknown as Promise<string>;
298
- }
299
-
300
- /**
301
- * 加载模型,如果给了 params 则不会缓存模型
302
- *
303
- * @author chitanda
304
- * @date 2024-01-15 12:01:57
305
- * @param {string} modelPath
306
- * @param {IParams} [params]
307
- * @param {boolean} [isDynamic]
308
- * @return {*} {Promise<IModel>}
309
- */
310
- async getModel(
311
- modelPath: string,
312
- params?: IParams,
313
- isDynamic?: boolean,
314
- ): Promise<IModel> {
315
- let url: string;
316
- if (this.hub) {
317
- url = this.calcAppPath(modelPath, isDynamic);
318
- } else {
319
- url = this.calcSubAppPath(modelPath, isDynamic);
320
- }
321
- const isParams = params && !isEmpty(params);
322
- if (this.modelCache.has(url) && !isParams) {
323
- return this.modelCache.get(url)!;
324
- }
325
- const model = await this.get(url, params);
326
- if (!isParams) {
327
- this.modelCache.set(url, model);
328
- }
329
- this.deepFillAppId(model);
330
- return model;
331
- }
332
-
333
- /**
334
- * 递归填充应用标识
335
- *
336
- * @author chitanda
337
- * @date 2023-08-21 10:08:41
338
- * @protected
339
- * @param {IModel} model
340
- */
341
- protected deepFillAppId(model: IModel): void {
342
- model.appId = this.appId;
343
- const keys = Object.keys(model);
344
- keys.forEach(key => {
345
- const value = model[key];
346
- if (value && typeof value === 'object') {
347
- if (Array.isArray(value)) {
348
- value.forEach(item => {
349
- if (item && typeof item === 'object') {
350
- this.deepFillAppId(item);
351
- }
352
- });
353
- } else {
354
- this.deepFillAppId(value);
355
- }
356
- }
357
- });
358
- }
359
-
360
- /**
361
- * 计算应用模型请求路径
362
- *
363
- * @author chitanda
364
- * @date 2024-01-15 12:01:45
365
- * @protected
366
- * @param {string} modelPath
367
- * @param {boolean} [isDynamic=false]
368
- * @return {*} {string}
369
- */
370
- protected calcAppPath(modelPath: string, isDynamic: boolean = false): string {
371
- if (isDynamic) {
372
- return formatPath(modelPath);
373
- }
374
- return `${formatPath(modelPath)}${
375
- this.modelTag ? `?dynamodeltag=${this.modelTag}` : ''
376
- }`;
377
- }
378
-
379
- /**
380
- * 计算子应用模型请求路径
381
- *
382
- * @author chitanda
383
- * @date 2024-01-15 12:01:39
384
- * @protected
385
- * @param {string} modelPath
386
- * @param {boolean} [isDynamic=false]
387
- * @return {*} {string}
388
- */
389
- protected calcSubAppPath(
390
- modelPath: string,
391
- isDynamic: boolean = false,
392
- ): string {
393
- if (isDynamic) {
394
- return `/subapps/${this.appId}${formatPath(modelPath)}`;
395
- }
396
- return `/subapps/${this.appId}${formatPath(modelPath)}?dynamodeltag=${
397
- this.modelTag
398
- }`;
399
- }
400
- }
@@ -1,9 +0,0 @@
1
- export function formatPath(path: string): string {
2
- // 合成路径,需要判断模型路径是否从 PSSYSAPPS 开始
3
- if (path?.indexOf('PSSYSAPPS/') === 0) {
4
- // 合成路径
5
- const pos = path.indexOf('/');
6
- return path.substring(path.indexOf('/', pos + 1));
7
- }
8
- return path;
9
- }
@@ -1,9 +0,0 @@
1
- export { formatPath } from './format-path/format-path';
2
- export { mergeModel } from './merge-model/merge-model';
3
- export { plural, pluralLower } from './plural/plural';
4
- export {
5
- ServicePathDeep,
6
- ServicePathItem,
7
- ServicePathUtil,
8
- } from './service-path-util/service-path-util';
9
- export { mergeAppMenu } from './merge-model/merge-app-menu';
@@ -1,84 +0,0 @@
1
- import { IAppMenuItem, IAppMenuModel, ISubAppRef } from '@ibiz/model-core';
2
-
3
- /**
4
- * 递归合并主菜单项和子菜单项
5
- * @author lxm
6
- * @date 2023-12-07 03:16:13
7
- * @param {IAppMenuItem} mainItem
8
- * @param {IAppMenuItem} subItem
9
- */
10
- function mergeMenuItem(mainItem: IAppMenuItem, subItem: IAppMenuItem): void {
11
- // 主菜单项没有子菜单项直接合并替换
12
- if (!mainItem.appMenuItems?.length) {
13
- if (subItem.appMenuItems?.length) {
14
- // 子菜单有下级菜单的时候只是添加下级菜单
15
- mainItem.appMenuItems = subItem.appMenuItems;
16
- } else {
17
- // 子菜单项也没有下级菜单的时候覆盖
18
- Object.assign(mainItem, subItem);
19
- }
20
- } else {
21
- const addItems: IAppMenuItem[] = [];
22
- subItem.appMenuItems?.forEach(item => {
23
- const sameMenu = mainItem.appMenuItems?.find(x => x.id === item.id);
24
- if (sameMenu) {
25
- mergeMenuItem(sameMenu, item);
26
- } else {
27
- addItems.push(item);
28
- }
29
- });
30
- mainItem.appMenuItems.push(...addItems);
31
- }
32
- }
33
-
34
- /**
35
- * 合并主菜单和子菜单
36
- * @author lxm
37
- * @date 2023-12-07 03:15:54
38
- * @param {IAppMenuModel} main
39
- * @param {IAppMenuModel} sub
40
- */
41
- function mergeMenu(main: IAppMenuModel, sub: IAppMenuModel): void {
42
- const addItems: IAppMenuItem[] = [];
43
- sub.appMenuItems?.forEach(item => {
44
- const sameMenu = main.appMenuItems?.find(x => x.id === item.id);
45
- if (sameMenu) {
46
- mergeMenuItem(sameMenu, item);
47
- } else {
48
- addItems.push(item);
49
- }
50
- });
51
-
52
- if (!main.appMenuItems) {
53
- main.appMenuItems = [];
54
- }
55
- main.appMenuItems.push(...addItems);
56
- }
57
-
58
- /**
59
- * 合并主应用首页菜单
60
- * @author lxm
61
- * @date 2023-12-07 02:26:57
62
- * @export
63
- * @param {IAppMenuModel} mainMenu
64
- * @param {ISubAppRef[]} subAppRefs
65
- */
66
- export function mergeAppMenu(
67
- mainMenu: IAppMenuModel,
68
- subAppRefs: ISubAppRef[],
69
- ): void {
70
- const subMenus: IAppMenuModel[] = [];
71
- subAppRefs.forEach(sub => {
72
- if (sub.appMenuModel?.appMenuItems?.length) {
73
- subMenus.push(sub.appMenuModel);
74
- }
75
- });
76
- if (subMenus.length === 0) {
77
- return;
78
- }
79
-
80
- // 依次合并主应用菜单和子应用菜单
81
- subMenus.forEach(subMenu => {
82
- mergeMenu(mainMenu, subMenu);
83
- });
84
- }
@@ -1,20 +0,0 @@
1
- import { mergeDeepLeft } from 'ramda';
2
-
3
- /**
4
- * 将预置的模型合并到当前模型中
5
- *
6
- * @author chitanda
7
- * @date 2023-09-22 10:09:10
8
- * @export
9
- * @param {IModel[]} models
10
- * @param {IModel} m
11
- * @param {string} tag
12
- */
13
- export function mergeModel(models: IModel[], m: IModel, tag: string): void {
14
- models.forEach(model => {
15
- const item = m[model[tag]];
16
- if (item) {
17
- Object.assign(model, mergeDeepLeft(model, item));
18
- }
19
- });
20
- }
@@ -1,30 +0,0 @@
1
- import pluralize from 'pluralize';
2
-
3
- // 补充特殊转换规则
4
- pluralize.addPluralRule(/(matr|vert|ind)ix|ex$/, '$1ices');
5
-
6
- /**
7
- * 英文转复数写法
8
- *
9
- * @author chitanda
10
- * @date 2022-08-25 18:08:41
11
- * @export
12
- * @param {string} key
13
- * @return {*} {string}
14
- */
15
- export function plural(key: string): string {
16
- return pluralize(key);
17
- }
18
-
19
- /**
20
- * 英文转复数写法并转全小写
21
- *
22
- * @author chitanda
23
- * @date 2022-08-25 18:08:23
24
- * @export
25
- * @param {string} key
26
- * @return {*} {string}
27
- */
28
- export function pluralLower(key: string): string {
29
- return plural(key).toLowerCase();
30
- }