@ebuilding/runtime 2.7.3 → 2.8.0

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 (69) hide show
  1. package/auth/auth-routing.module.d.ts +7 -0
  2. package/auth/auth.tokens.d.ts +7 -0
  3. package/auth/authmodule.d.ts +10 -0
  4. package/auth/index.d.ts +2 -0
  5. package/auth/login/login.component.d.ts +48 -0
  6. package/auth/login-cust/login.component.d.ts +47 -0
  7. package/core/app-feature-config.service.d.ts +26 -0
  8. package/core/app-feature.guard.d.ts +3 -0
  9. package/core/i18n/i18n.service.d.ts +25 -0
  10. package/core/index.d.ts +7 -0
  11. package/core/net/default.interceptor.d.ts +2 -0
  12. package/core/net/helper.d.ts +11 -0
  13. package/core/net/index.d.ts +2 -0
  14. package/core/net/refresh-token.d.ts +11 -0
  15. package/core/runtime-core.tokens.d.ts +18 -0
  16. package/core/start-default.guard.d.ts +2 -0
  17. package/core/startup/startup.service.d.ts +24 -0
  18. package/exception/index.d.ts +2 -0
  19. package/exception/index.module.d.ts +8 -0
  20. package/exception/main/index.d.ts +11 -0
  21. package/fesm2022/auth.mjs +500 -0
  22. package/fesm2022/auth.mjs.map +1 -0
  23. package/fesm2022/core.mjs +615 -0
  24. package/fesm2022/core.mjs.map +1 -0
  25. package/fesm2022/exception.mjs +52 -0
  26. package/fesm2022/exception.mjs.map +1 -0
  27. package/fesm2022/home.mjs +683 -0
  28. package/fesm2022/home.mjs.map +1 -0
  29. package/fesm2022/layout.mjs +2393 -0
  30. package/fesm2022/layout.mjs.map +1 -0
  31. package/home/box-bench/index.d.ts +23 -0
  32. package/home/box-custom/index.d.ts +18 -0
  33. package/home/box-item/index.d.ts +12 -0
  34. package/home/components/item.app/index.component.d.ts +14 -0
  35. package/home/components/item.calendar/index.component.d.ts +24 -0
  36. package/home/components/item.carousel/index.component.d.ts +21 -0
  37. package/home/components/item.chart/index.component.d.ts +20 -0
  38. package/home/components/item.notice/index.component.d.ts +17 -0
  39. package/home/components/item.report/index.component.d.ts +9 -0
  40. package/home/components/item.single/index.component.d.ts +9 -0
  41. package/home/components/item.workflow/index.component.d.ts +11 -0
  42. package/home/home-routing.module.d.ts +7 -0
  43. package/home/home.module.d.ts +8 -0
  44. package/home/home.service.d.ts +14 -0
  45. package/home/home.tokens.d.ts +11 -0
  46. package/home/index.d.ts +3 -0
  47. package/home/main/index.component.d.ts +25 -0
  48. package/layout/admin/index.component.d.ts +18 -0
  49. package/layout/auth/index.component.d.ts +19 -0
  50. package/layout/base.service.d.ts +48 -0
  51. package/layout/basic/basic.component.d.ts +13 -0
  52. package/layout/basic/widgets/clear-storage.component.d.ts +8 -0
  53. package/layout/basic/widgets/fullscreen.component.d.ts +8 -0
  54. package/layout/basic/widgets/i18n.component.d.ts +18 -0
  55. package/layout/basic/widgets/icon.component.d.ts +8 -0
  56. package/layout/basic/widgets/notify.component.d.ts +16 -0
  57. package/layout/basic/widgets/rtl.component.d.ts +8 -0
  58. package/layout/basic/widgets/search.component.d.ts +23 -0
  59. package/layout/basic/widgets/task.component.d.ts +8 -0
  60. package/layout/basic/widgets/user.component.d.ts +11 -0
  61. package/layout/blank/blank.component.d.ts +5 -0
  62. package/layout/components/nav-menu/index.d.ts +16 -0
  63. package/layout/components/nav-user/index.d.ts +54 -0
  64. package/layout/components/user/user.component.d.ts +57 -0
  65. package/layout/home/index.component.d.ts +20 -0
  66. package/layout/index.d.ts +7 -0
  67. package/layout/manage/index.component.d.ts +27 -0
  68. package/layout/manage/view.component.d.ts +21 -0
  69. package/package.json +50 -27
@@ -0,0 +1,615 @@
1
+ import { Platform } from '@angular/cdk/platform';
2
+ import { registerLocaleData } from '@angular/common';
3
+ import ngEn from '@angular/common/locales/en';
4
+ import ngZh from '@angular/common/locales/zh';
5
+ import ngZhTw from '@angular/common/locales/zh-Hant';
6
+ import * as i0 from '@angular/core';
7
+ import { inject, Injectable, InjectionToken, provideAppInitializer, Injector } from '@angular/core';
8
+ import * as i1$1 from '@delon/theme';
9
+ import { en_US, zh_TW, zh_CN, AlainI18nBaseService, _HttpClient, SettingsService, DelonLocaleService, ALAIN_I18N_TOKEN, IGNORE_BASE_URL, MenuService, TitleService } from '@delon/theme';
10
+ import { enUS, zhTW, zhCN } from 'date-fns/locale';
11
+ import { en_US as en_US$1, zh_TW as zh_TW$1, zh_CN as zh_CN$1, NzI18nService } from 'ng-zorro-antd/i18n';
12
+ import * as i1 from '@delon/util/config';
13
+ import { HttpClient, HttpErrorResponse, HttpResponse, HttpHeaders, HttpResponseBase } from '@angular/common/http';
14
+ import { DA_SERVICE_TOKEN } from '@delon/auth';
15
+ import { BehaviorSubject, throwError, filter, take, switchMap, catchError, of, mergeMap, zip, timeout, map } from 'rxjs';
16
+ import * as i2 from '@angular/router';
17
+ import { Router } from '@angular/router';
18
+ import { NzNotificationService } from 'ng-zorro-antd/notification';
19
+ import { AppSetId, AppCustomerId } from '@ebuilding/base/shared.var/shared.variable';
20
+ import { Gram_App_Type, Gram_App_Module, ModuleAPI, Gram_Platform } from '@ebuilding/base/shared.var/shared.constant';
21
+ import { NzMessageService } from 'ng-zorro-antd/message';
22
+ import { ACLService } from '@delon/acl';
23
+ import _ from 'lodash';
24
+ import { initData } from '@ebuilding/base/shared.util/comm.menu';
25
+ import { map as map$1, tap, catchError as catchError$1, shareReplay } from 'rxjs/operators';
26
+
27
+ const DEFAULT = 'zh-CN';
28
+ const LANGS = {
29
+ 'zh-CN': {
30
+ text: '简体中文',
31
+ ng: ngZh,
32
+ zorro: zh_CN$1,
33
+ date: zhCN,
34
+ delon: zh_CN,
35
+ abbr: '🇨🇳'
36
+ },
37
+ 'zh-TW': {
38
+ text: '繁体中文',
39
+ ng: ngZhTw,
40
+ zorro: zh_TW$1,
41
+ date: zhTW,
42
+ delon: zh_TW,
43
+ abbr: '🇭🇰'
44
+ },
45
+ 'en-US': {
46
+ text: 'English',
47
+ ng: ngEn,
48
+ zorro: en_US$1,
49
+ date: enUS,
50
+ delon: en_US,
51
+ abbr: '🇬🇧'
52
+ }
53
+ };
54
+ class I18NService extends AlainI18nBaseService {
55
+ http = inject(_HttpClient);
56
+ settings = inject(SettingsService);
57
+ nzI18nService = inject(NzI18nService);
58
+ delonLocaleService = inject(DelonLocaleService);
59
+ platform = inject(Platform);
60
+ _defaultLang = DEFAULT;
61
+ _langs = Object.keys(LANGS).map(code => {
62
+ const item = LANGS[code];
63
+ return { code, text: item.text, abbr: item.abbr };
64
+ });
65
+ constructor(cogSrv) {
66
+ super(cogSrv);
67
+ const defaultLang = this.getDefaultLang();
68
+ this._defaultLang = this._langs.findIndex(w => w.code === defaultLang) === -1 ? DEFAULT : defaultLang;
69
+ }
70
+ getDefaultLang() {
71
+ if (!this.platform.isBrowser) {
72
+ return DEFAULT;
73
+ }
74
+ if (this.settings.layout.lang) {
75
+ return this.settings.layout.lang;
76
+ }
77
+ let res = (navigator.languages ? navigator.languages[0] : null) || navigator.language;
78
+ const arr = res.split('-');
79
+ return arr.length <= 1 ? res : `${arr[0]}-${arr[1].toUpperCase()}`;
80
+ }
81
+ loadLangData(lang) {
82
+ return this.http.get(`./assets/tmp/i18n/${lang}.json`);
83
+ }
84
+ use(lang, data) {
85
+ if (this._currentLang === lang)
86
+ return;
87
+ this._data = this.flatData(data, []);
88
+ const item = LANGS[lang];
89
+ registerLocaleData(item.ng);
90
+ this.nzI18nService.setLocale(item.zorro);
91
+ this.nzI18nService.setDateLocale(item.date);
92
+ this.delonLocaleService.setLocale(item.delon);
93
+ this._currentLang = lang;
94
+ this._change$.next(lang);
95
+ }
96
+ getLangs() {
97
+ return this._langs;
98
+ }
99
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: I18NService, deps: [{ token: i1.AlainConfigService }], target: i0.ɵɵFactoryTarget.Injectable });
100
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: I18NService, providedIn: 'root' });
101
+ }
102
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: I18NService, decorators: [{
103
+ type: Injectable,
104
+ args: [{ providedIn: 'root' }]
105
+ }], ctorParameters: () => [{ type: i1.AlainConfigService }] });
106
+
107
+ const RUNTIME_CORE_ENVIRONMENT = new InjectionToken('RUNTIME_CORE_ENVIRONMENT', {
108
+ providedIn: 'root',
109
+ factory: () => ({
110
+ production: false,
111
+ useHash: false,
112
+ api: {
113
+ baseUrl: '',
114
+ licenseUrl: '',
115
+ flyUrl: '',
116
+ preRequest: '',
117
+ mockToken: '',
118
+ refreshTokenEnabled: true,
119
+ refreshTokenType: 'auth-refresh',
120
+ },
121
+ modules: [],
122
+ config: null,
123
+ configFile: 'development.json',
124
+ }),
125
+ });
126
+
127
+ const CODEMESSAGE = {
128
+ 200: '服务器成功返回请求的数据。',
129
+ 201: '新建或修改数据成功。',
130
+ 202: '一个请求已经进入后台排队(异步任务)。',
131
+ 204: '删除数据成功。',
132
+ 400: '发出的请求有错误,服务器没有进行新建或修改数据的操作。',
133
+ 401: '用户没有权限(令牌、用户名、密码错误)。',
134
+ 403: '用户得到授权,但是访问是被禁止的。',
135
+ 404: '发出的请求针对的是不存在的记录,服务器没有进行操作。',
136
+ 406: '请求的格式不可得。',
137
+ 410: '请求的资源被永久删除,且不会再得到的。',
138
+ 422: '当创建一个对象时,发生一个验证错误。',
139
+ 500: '服务器发生错误,请检查服务器。',
140
+ 502: '网关错误。',
141
+ 503: '服务不可用,服务器暂时过载或维护。',
142
+ 504: '网关超时。'
143
+ };
144
+ function goTo(injector, url) {
145
+ setTimeout(() => injector.get(Router).navigateByUrl(url));
146
+ }
147
+ function toLogin(injector) {
148
+ //injector.get(NzNotificationService).error(`未登录或登录已过期,请重新登录。`, ``);
149
+ goTo(injector, injector.get(DA_SERVICE_TOKEN).login_url);
150
+ }
151
+ function getAdditionalHeaders(req, injector) {
152
+ const res = {};
153
+ const environment = injector.get(RUNTIME_CORE_ENVIRONMENT);
154
+ const tokenSrv = injector.get(DA_SERVICE_TOKEN);
155
+ const token = tokenSrv.get()?.token;
156
+ const settingSrv = injector.get(SettingsService);
157
+ const lang = inject(ALAIN_I18N_TOKEN).currentLang;
158
+ if (!req?.headers?.has('Accept-Language') && lang) {
159
+ res['Accept-Language'] = lang;
160
+ }
161
+ const appType = settingSrv.getData(Gram_App_Type);
162
+ if (token) {
163
+ if (req.url.indexOf('airservice-') > 0) {
164
+ res['x-auth-token'] = environment.api.mockToken;
165
+ }
166
+ const eId = settingSrv.getData(AppSetId);
167
+ res['X-Access-Token'] = token;
168
+ res['e-id'] = eId ? eId : '';
169
+ res['customerId'] = settingSrv.getData(AppCustomerId);
170
+ }
171
+ if (req.url.indexOf('auth/login') > 0) {
172
+ if (appType == 'FLY') {
173
+ res['x-auth-token'] = '';
174
+ }
175
+ else {
176
+ res['X-Access-Token'] = '';
177
+ res['e-id'] = '';
178
+ }
179
+ }
180
+ if (req.url.indexOf('api/etalent/v1/upload') > 0) {
181
+ const res2 = {};
182
+ res2['Authorization'] = '';
183
+ res2['X-CSRF-Token'] = '';
184
+ res2['X-Max'] = '';
185
+ return res2;
186
+ }
187
+ return res;
188
+ }
189
+ function checkStatus(injector, ev) {
190
+ if ((ev.status >= 200 && ev.status < 300) || ev.status === 401) {
191
+ return;
192
+ }
193
+ const errortext = CODEMESSAGE[ev.status] || ev.statusText;
194
+ injector.get(NzNotificationService).error(`请求错误 ${ev.status}: ${ev.url}`, errortext);
195
+ }
196
+
197
+ let refreshToking = false;
198
+ let refreshToken$ = new BehaviorSubject(null);
199
+ /**
200
+ * 重新附加新 Token 信息
201
+ *
202
+ * > 由于已经发起的请求,不会再走一遍 `@delon/auth` 因此需要结合业务情况重新附加新的 Token
203
+ */
204
+ function reAttachToken(injector, req) {
205
+ const token = injector.get(DA_SERVICE_TOKEN).get()?.token;
206
+ return req.clone({
207
+ setHeaders: {
208
+ token: `Bearer ${token}`
209
+ }
210
+ });
211
+ }
212
+ function refreshTokenRequest(injector) {
213
+ const model = injector.get(DA_SERVICE_TOKEN).get();
214
+ return injector.get(HttpClient).post(`/api/auth/refresh`, { headers: { refresh_token: model?.['refresh_token'] || '' } });
215
+ }
216
+ /**
217
+ * 刷新Token方式一:使用 401 重新刷新 Token
218
+ */
219
+ function tryRefreshToken(injector, ev, req, next) {
220
+ // 1、若请求为刷新Token请求,表示来自刷新Token可以直接跳转登录页
221
+ if ([`/api/auth/refresh`].some(url => req.url.includes(url))) {
222
+ toLogin(injector);
223
+ return throwError(() => ev);
224
+ }
225
+ // 2、如果 `refreshToking` 为 `true` 表示已经在请求刷新 Token 中,后续所有请求转入等待状态,直至结果返回后再重新发起请求
226
+ if (refreshToking) {
227
+ return refreshToken$.pipe(filter(v => !!v), take(1), switchMap(() => next(reAttachToken(injector, req))));
228
+ }
229
+ // 3、尝试调用刷新 Token
230
+ refreshToking = true;
231
+ refreshToken$.next(null);
232
+ return refreshTokenRequest(injector).pipe(switchMap(res => {
233
+ // 通知后续请求继续执行
234
+ refreshToking = false;
235
+ refreshToken$.next(res);
236
+ // 重新保存新 token
237
+ injector.get(DA_SERVICE_TOKEN).set(res);
238
+ // 重新发起请求
239
+ return next(reAttachToken(injector, req));
240
+ }), catchError(err => {
241
+ refreshToking = false;
242
+ toLogin(injector);
243
+ return throwError(() => err);
244
+ }));
245
+ }
246
+ function buildAuthRefresh(injector) {
247
+ const tokenSrv = injector.get(DA_SERVICE_TOKEN);
248
+ tokenSrv.refresh
249
+ .pipe(filter(() => !refreshToking), switchMap(res => {
250
+ refreshToking = true;
251
+ return refreshTokenRequest(injector);
252
+ }))
253
+ .subscribe({
254
+ next: res => {
255
+ // TODO: Mock expired value
256
+ res.expired = +new Date() + 1000 * 60 * 5;
257
+ refreshToking = false;
258
+ tokenSrv.set(res);
259
+ },
260
+ error: () => toLogin(injector)
261
+ });
262
+ }
263
+ /**
264
+ * 刷新Token方式二:使用 `@delon/auth` 的 `refresh` 接口,需要在 `app.config.ts` 中注册 `provideBindAuthRefresh`
265
+ */
266
+ function provideBindAuthRefresh() {
267
+ return [
268
+ provideAppInitializer(() => {
269
+ const initializerFn = ((injector) => () => buildAuthRefresh(injector))(inject(Injector));
270
+ return initializerFn();
271
+ })
272
+ ];
273
+ }
274
+
275
+ function handleData(injector, ev, req, next) {
276
+ const msg = injector.get(NzMessageService);
277
+ checkStatus(injector, ev);
278
+ switch (ev.status) {
279
+ case 200:
280
+ if (ev instanceof HttpResponse) {
281
+ const body = ev.body;
282
+ if (body && body.type === 'application/vnd.ms-excel') {
283
+ // ❗建议你在此处引入并注入下载服务
284
+ // const downloadService = injector.get(YourDownloadService);
285
+ // downloadService.download(ev);
286
+ download(ev);
287
+ }
288
+ else {
289
+ if (body?.code === '1001') {
290
+ toLogin(injector);
291
+ throw new Error(body.message);
292
+ }
293
+ else if (body?.code === '99999') {
294
+ msg.error('上传的license文件不合规,请认证后再上传');
295
+ return of(new HttpResponse({ body }));
296
+ }
297
+ else {
298
+ if (body?.error) {
299
+ return throwError(() => ({ error: body.error }));
300
+ }
301
+ if (body?.code && Number(body.code) !== 200) {
302
+ msg.error(body.message);
303
+ }
304
+ if (body?.data !== undefined && Number(body.code) === 200) {
305
+ return of(new HttpResponse({ body }));
306
+ }
307
+ }
308
+ }
309
+ }
310
+ break;
311
+ case 401:
312
+ if (ev.url && ev.url.indexOf('/sys/module') < 0) {
313
+ const msgText = ev['error']?.['message'];
314
+ if (msgText && msgText !== 'token非法无效!' && msgText !== 'Token失效,请重新登录!') {
315
+ // const authService = injector.get(AuthService);
316
+ // authService.authErrorSubject.next(msgText);
317
+ toLogin(injector);
318
+ }
319
+ else {
320
+ toLogin(injector);
321
+ }
322
+ }
323
+ else {
324
+ toLogin(injector);
325
+ }
326
+ break;
327
+ case 403:
328
+ case 404:
329
+ case 500:
330
+ // 可跳转到异常页面,例如:
331
+ // goTo(injector, `/exception/${ev.status}?url=${req.urlWithParams}`);
332
+ break;
333
+ default:
334
+ if (ev instanceof HttpErrorResponse) {
335
+ console.warn('未可知错误,大部分是由于后端不支持跨域CORS或无效配置引起', ev);
336
+ }
337
+ break;
338
+ }
339
+ if (ev instanceof HttpErrorResponse) {
340
+ return throwError(() => ev);
341
+ }
342
+ else if (ev._throw === true) {
343
+ return throwError(() => ev.body);
344
+ }
345
+ else {
346
+ return of(ev);
347
+ }
348
+ }
349
+ const defaultInterceptor = (req, next) => {
350
+ const injector = inject(Injector);
351
+ const environment = inject(RUNTIME_CORE_ENVIRONMENT);
352
+ let url = req.url;
353
+ if (!req.context.get(IGNORE_BASE_URL) && !url.startsWith('https://') && !url.startsWith('http://') &&
354
+ url.indexOf('assets') < 0 &&
355
+ url.indexOf('api/etalent/v1/upload') < 0) {
356
+ const { baseUrl, flyUrl } = environment.api;
357
+ if (url.indexOf('flv/index') > 0) {
358
+ }
359
+ else if (url.indexOf('airservice-') > 0 || url.indexOf('airadapter-') > 0) {
360
+ url = flyUrl + (flyUrl.endsWith('/') && url.startsWith('/') ? url.substring(1) : url);
361
+ }
362
+ else {
363
+ url = baseUrl + (baseUrl.endsWith('/') && url.startsWith('/') ? url.substring(1) : url);
364
+ }
365
+ }
366
+ let headers = req.headers;
367
+ const shouldAddToken = !url.includes('flv/index/api/whep') && !url.includes('auth/login');
368
+ if (shouldAddToken) {
369
+ const additional = getAdditionalHeaders(req, injector);
370
+ for (const k of Object.keys(additional)) {
371
+ headers = headers.set(k, additional[k]);
372
+ }
373
+ }
374
+ else {
375
+ headers = new HttpHeaders();
376
+ }
377
+ const newReq = req.clone({
378
+ url,
379
+ headers,
380
+ responseType: url.indexOf('export') > 0 ? 'blob' : null
381
+ });
382
+ return next(newReq).pipe(mergeMap(ev => {
383
+ if (ev instanceof HttpResponseBase) {
384
+ return handleData(injector, ev, newReq, next);
385
+ }
386
+ return of(ev);
387
+ }), catchError((err) => handleData(injector, err, newReq, next)) // ✅ 必须保留
388
+ );
389
+ };
390
+ function download(ev) {
391
+ const data = ev.body;
392
+ const headers = ev.headers;
393
+ let fileName = 'download.xls';
394
+ const contentDisposition = headers.get('Content-Disposition') || headers.get('content-disposition');
395
+ if (contentDisposition) {
396
+ const matches = /filename=([^;]+)/.exec(contentDisposition);
397
+ if (matches?.[1]) {
398
+ fileName = decodeURIComponent(matches[1].replace(/['"]/g, ''));
399
+ }
400
+ }
401
+ executeDownload(data, fileName);
402
+ }
403
+ function executeDownload(data, fileName) {
404
+ if (!data)
405
+ return;
406
+ const url = window.URL.createObjectURL(new Blob([data]));
407
+ const link = document.createElement('a');
408
+ link.style.display = 'none';
409
+ link.href = url;
410
+ link.setAttribute('download', fileName);
411
+ document.body.appendChild(link);
412
+ link.click();
413
+ document.body.removeChild(link);
414
+ window.URL.revokeObjectURL(url);
415
+ }
416
+
417
+ /**
418
+ * Used for application startup
419
+ * Generally used to get the basic data of the application, like: Menu Data, User Data, etc.
420
+ */
421
+ function provideStartup() {
422
+ return [
423
+ StartupService,
424
+ provideAppInitializer(() => {
425
+ const initializerFn = ((startupService) => () => startupService.load())(inject(StartupService));
426
+ return initializerFn();
427
+ })
428
+ ];
429
+ }
430
+ class StartupService {
431
+ menuService = inject(MenuService);
432
+ settingService = inject(SettingsService);
433
+ aclService = inject(ACLService);
434
+ titleService = inject(TitleService);
435
+ httpClient = inject(HttpClient);
436
+ http = inject(_HttpClient);
437
+ router = inject(Router);
438
+ i18n = inject(ALAIN_I18N_TOKEN);
439
+ tokenSrv = inject(DA_SERVICE_TOKEN);
440
+ environment = inject(RUNTIME_CORE_ENVIRONMENT);
441
+ load() {
442
+ const configFile = this.environment.configFile || 'development.json';
443
+ return this.http.get(`assets/config/${configFile}?rd=${Math.random()}`).pipe(switchMap((configData) => {
444
+ this.environment.config = configData;
445
+ this.environment.useHash = configData.useHash;
446
+ this.environment.production = configData.production;
447
+ this.environment.api.baseUrl = configData.baseUrl;
448
+ this.environment.api.flyUrl = configData.flyUrl;
449
+ this.environment.api.licenseUrl = configData.licenseUrl;
450
+ this.environment.api.mockToken = configData.mockToken;
451
+ this.environment.api.preRequest = configData.preRequest;
452
+ const defaultLang = this.i18n.defaultLang;
453
+ return zip(this.getModule(), this.httpClient.get(`assets/tmp/i18n/${defaultLang}.json?rd=${Math.random()}`), this.httpClient.get(`assets/tmp/app-data.json?rd=${Math.random()}`)).pipe(timeout(10000), map(([appModule, langData, appData]) => {
454
+ this.i18n.use(defaultLang, langData);
455
+ const res = appData;
456
+ this.settingService.setApp(res.app);
457
+ this.aclService.setFull(false);
458
+ let listRole = [];
459
+ const token = this.tokenSrv.get();
460
+ if (token?.userInfo?.listRole) {
461
+ listRole = token.userInfo.listRole;
462
+ }
463
+ this.aclService.setRole(listRole);
464
+ let menuData = [];
465
+ if (appModule?.result?.length > 0) {
466
+ menuData = initData(appModule.result);
467
+ }
468
+ this.menuService.add(res.menu);
469
+ this.menuService.resume();
470
+ this.settingService.setData(Gram_App_Module, _.cloneDeep(menuData));
471
+ this.titleService.default = '';
472
+ this.titleService.suffix = res.app.name;
473
+ }), catchError(res => {
474
+ console.warn(`StartupService.load: Network request failed`, res);
475
+ // setTimeout(() => this.router.navigateByUrl(`/exception/500`));
476
+ return of(); // 返回空 Observable<void>
477
+ }));
478
+ }), catchError(res => {
479
+ console.warn(`StartupService.load: App initialization failed`, res);
480
+ return of(void 0);
481
+ }));
482
+ }
483
+ getModule() {
484
+ const token = this.tokenSrv.get()?.token;
485
+ if (token) {
486
+ return this.http.post(`${ModuleAPI.user}/user/sys/module`);
487
+ }
488
+ else {
489
+ return of(null);
490
+ }
491
+ }
492
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: StartupService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
493
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: StartupService });
494
+ }
495
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: StartupService, decorators: [{
496
+ type: Injectable
497
+ }] });
498
+
499
+ const startDefaultGuard = (_route, state) => {
500
+ const router = inject(Router);
501
+ const settingSrv = inject(SettingsService);
502
+ const tokenSrv = inject(DA_SERVICE_TOKEN);
503
+ const platform = settingSrv.getData(Gram_Platform);
504
+ const token = tokenSrv.get();
505
+ if (token && token?.token) {
506
+ }
507
+ else {
508
+ return router.parseUrl('/auth/login');
509
+ }
510
+ if ((token?.forceChangePwd === true || token?.userInfo?.forceChangePwd === true) && state.url !== '/admin/change-password') {
511
+ return router.parseUrl('/admin/change-password');
512
+ }
513
+ if (platform == "DEFAULT") {
514
+ return true;
515
+ }
516
+ return router.parseUrl('/exception');
517
+ };
518
+
519
+ const AppFeatureConfigKey = 'APP_FEATURE_CONFIG';
520
+ class AppFeatureConfigService {
521
+ http;
522
+ settings;
523
+ router;
524
+ loading$ = null;
525
+ constructor(http, settings, router) {
526
+ this.http = http;
527
+ this.settings = settings;
528
+ this.router = router;
529
+ }
530
+ load(force = false) {
531
+ if (!force) {
532
+ const cached = this.current();
533
+ if (cached) {
534
+ return of(cached);
535
+ }
536
+ if (this.loading$) {
537
+ return this.loading$;
538
+ }
539
+ }
540
+ this.loading$ = this.http.post(`${ModuleAPI.system}/sys/config/listData`, null).pipe(map$1((res) => this.fromResponse(res?.result || {})), tap(config => this.set(config)), catchError$1(() => {
541
+ const config = this.defaults();
542
+ this.set(config);
543
+ return of(config);
544
+ }), shareReplay(1));
545
+ return this.loading$;
546
+ }
547
+ save(config) {
548
+ const body = {
549
+ ENABLE_WORKFLOW: config.enableWorkflow ? '1' : '0',
550
+ ENABLE_MESSAGE_CENTER: config.enableMessageCenter ? '1' : '0'
551
+ };
552
+ return this.http.post(`${ModuleAPI.system}/sys/config/saveData`, body).pipe(map$1((res) => this.fromResponse(res?.result || body)), tap(value => this.set(value)));
553
+ }
554
+ current() {
555
+ return this.settings.getData(AppFeatureConfigKey) || null;
556
+ }
557
+ redirectHome() {
558
+ this.router.navigateByUrl('/home');
559
+ }
560
+ set(config) {
561
+ this.settings.setData(AppFeatureConfigKey, config);
562
+ }
563
+ fromResponse(data) {
564
+ return {
565
+ enableWorkflow: this.toBool(data?.ENABLE_WORKFLOW, true),
566
+ enableMessageCenter: this.toBool(data?.ENABLE_MESSAGE_CENTER, true)
567
+ };
568
+ }
569
+ defaults() {
570
+ return {
571
+ enableWorkflow: true,
572
+ enableMessageCenter: true
573
+ };
574
+ }
575
+ toBool(value, defaultValue) {
576
+ if (value === undefined || value === null || value === '') {
577
+ return defaultValue;
578
+ }
579
+ return value === true || value === 1 || value === '1' || `${value}`.toLowerCase() === 'true';
580
+ }
581
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: AppFeatureConfigService, deps: [{ token: i1$1._HttpClient }, { token: i1$1.SettingsService }, { token: i2.Router }], target: i0.ɵɵFactoryTarget.Injectable });
582
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: AppFeatureConfigService, providedIn: 'root' });
583
+ }
584
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: AppFeatureConfigService, decorators: [{
585
+ type: Injectable,
586
+ args: [{ providedIn: 'root' }]
587
+ }], ctorParameters: () => [{ type: i1$1._HttpClient }, { type: i1$1.SettingsService }, { type: i2.Router }] });
588
+
589
+ const workflowFeatureGuard = () => {
590
+ const service = inject(AppFeatureConfigService);
591
+ return service.load().pipe(map$1(config => {
592
+ if (!config.enableWorkflow) {
593
+ service.redirectHome();
594
+ return false;
595
+ }
596
+ return true;
597
+ }));
598
+ };
599
+ const messageFeatureGuard = () => {
600
+ const service = inject(AppFeatureConfigService);
601
+ return service.load().pipe(map$1(config => {
602
+ if (!config.enableMessageCenter) {
603
+ service.redirectHome();
604
+ return false;
605
+ }
606
+ return true;
607
+ }));
608
+ };
609
+
610
+ /**
611
+ * Generated bundle index. Do not edit.
612
+ */
613
+
614
+ export { AppFeatureConfigKey, AppFeatureConfigService, I18NService, RUNTIME_CORE_ENVIRONMENT, StartupService, defaultInterceptor, messageFeatureGuard, provideBindAuthRefresh, provideStartup, startDefaultGuard, workflowFeatureGuard };
615
+ //# sourceMappingURL=core.mjs.map