@litianxiang/portal-core 0.2.4 → 0.2.6
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/README.md +30 -3
- package/dist/index.d.ts +49 -9
- package/dist/index.js +75 -4
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -71,18 +71,31 @@ export const { http, logoutToAuth } = createAuthHttpClient({
|
|
|
71
71
|
})
|
|
72
72
|
```
|
|
73
73
|
|
|
74
|
+
如果业务项目只需要一个标准站点 http 模块,也可以直接使用更薄的封装:
|
|
75
|
+
|
|
76
|
+
```ts
|
|
77
|
+
import { createSiteHttpModule } from '@litianxiang/portal-core'
|
|
78
|
+
|
|
79
|
+
export const { http, logoutToAuth } = createSiteHttpModule({
|
|
80
|
+
getUserStore: () => useUserStore(),
|
|
81
|
+
getLoadingStore: () => useLoadingStore(),
|
|
82
|
+
onShowError: (msg) => console.error(msg)
|
|
83
|
+
})
|
|
84
|
+
```
|
|
85
|
+
|
|
74
86
|
## 导出方法说明(逐方法)
|
|
75
87
|
|
|
76
88
|
### app
|
|
77
89
|
|
|
78
|
-
- `
|
|
90
|
+
- `setupApp(options)`:统一执行应用启动编排(插件注册、图标注册、beforeMount、mount)。
|
|
91
|
+
- `setupRuntime(options)`:统一执行挂载前的运行时初始化(i18n、登录态同步、菜单状态、portal-ui http 绑定)。
|
|
79
92
|
|
|
80
93
|
最小示例:
|
|
81
94
|
|
|
82
95
|
```ts
|
|
83
|
-
import {
|
|
96
|
+
import { setupApp } from '@litianxiang/portal-core'
|
|
84
97
|
|
|
85
|
-
|
|
98
|
+
setupApp({
|
|
86
99
|
app,
|
|
87
100
|
plugins: [router, pinia],
|
|
88
101
|
elementIcons: ElementPlusIconsVue,
|
|
@@ -108,6 +121,20 @@ const router = createAppRouter({
|
|
|
108
121
|
})
|
|
109
122
|
```
|
|
110
123
|
|
|
124
|
+
- `createStaticAppRouter(options)`:创建静态站点路由,可选统一登录守卫,适用于 portal.web、portal.auth.web 这类无动态菜单站点。
|
|
125
|
+
|
|
126
|
+
最小示例:
|
|
127
|
+
|
|
128
|
+
```ts
|
|
129
|
+
import { createStaticAppRouter } from '@litianxiang/portal-core'
|
|
130
|
+
|
|
131
|
+
const router = createStaticAppRouter({
|
|
132
|
+
staticRoutes,
|
|
133
|
+
getUserStore: () => useUserStore(),
|
|
134
|
+
requireAuth: true
|
|
135
|
+
})
|
|
136
|
+
```
|
|
137
|
+
|
|
111
138
|
### auth
|
|
112
139
|
|
|
113
140
|
- `createLogoutToAuth(options)`:生成统一退出函数,负责清理用户态并跳转到认证站。
|
package/dist/index.d.ts
CHANGED
|
@@ -1,22 +1,32 @@
|
|
|
1
1
|
import * as vue_router from 'vue-router';
|
|
2
|
-
import { RouteRecordRaw } from 'vue-router';
|
|
3
2
|
import { Dayjs } from 'dayjs';
|
|
4
|
-
import { App, Plugin } from 'vue';
|
|
5
3
|
import * as vue_i18n from 'vue-i18n';
|
|
6
4
|
|
|
7
5
|
interface AppRouterOptions {
|
|
8
|
-
staticRoutes:
|
|
6
|
+
staticRoutes: any[];
|
|
9
7
|
getUserStore: () => any;
|
|
10
8
|
getFirstPage?: (allMenu: any[]) => string | null | undefined;
|
|
11
9
|
authLoginUrl?: string;
|
|
12
10
|
/** 是否开启从 URL 参数恢复 token,默认关闭 */
|
|
13
11
|
enableUrlTokenRecovery?: boolean;
|
|
14
12
|
}
|
|
13
|
+
interface StaticAppRouterOptions {
|
|
14
|
+
staticRoutes: any[];
|
|
15
|
+
getUserStore?: () => any;
|
|
16
|
+
authLoginUrl?: string;
|
|
17
|
+
requireAuth?: boolean;
|
|
18
|
+
}
|
|
15
19
|
/**
|
|
16
20
|
* 创建带统一登录、动态菜单和 Tab 管理的 Router
|
|
17
21
|
* 各站点只需注入各自的 userStore / tabStore / getFirstPage 即可复用
|
|
18
22
|
*/
|
|
19
23
|
declare function createAppRouter(options: AppRouterOptions): vue_router.Router;
|
|
24
|
+
/**
|
|
25
|
+
* 创建静态站点路由:
|
|
26
|
+
* - 可选统一登录守卫
|
|
27
|
+
* - 适用于 portal.web / portal.auth.web 这类无动态菜单站点
|
|
28
|
+
*/
|
|
29
|
+
declare function createStaticAppRouter(options: StaticAppRouterOptions): vue_router.Router;
|
|
20
30
|
|
|
21
31
|
interface LogoutToAuthOptions {
|
|
22
32
|
getUserStore: () => {
|
|
@@ -69,10 +79,16 @@ interface CreateAuthHttpClientOptions {
|
|
|
69
79
|
inactiveBufferMs?: number;
|
|
70
80
|
onShowError?: (msg: string) => void;
|
|
71
81
|
}
|
|
82
|
+
interface CreateSiteHttpModuleOptions extends CreateAuthHttpClientOptions {
|
|
83
|
+
}
|
|
72
84
|
declare function createAuthHttpClient(options: CreateAuthHttpClientOptions): {
|
|
73
85
|
http: any;
|
|
74
86
|
logoutToAuth: () => void;
|
|
75
87
|
};
|
|
88
|
+
declare function createSiteHttpModule(options: CreateSiteHttpModuleOptions): {
|
|
89
|
+
http: any;
|
|
90
|
+
logoutToAuth: () => void;
|
|
91
|
+
};
|
|
76
92
|
|
|
77
93
|
interface PermissionHelperOptions {
|
|
78
94
|
/** 返回用户 Store 实例,需至少提供 getUserALLMenu 或 getUserPageMenu */
|
|
@@ -146,6 +162,7 @@ interface CoreMenuItem {
|
|
|
146
162
|
icon?: string;
|
|
147
163
|
order_num?: number;
|
|
148
164
|
site?: string;
|
|
165
|
+
is_blank_page?: boolean;
|
|
149
166
|
children?: CoreMenuItem[];
|
|
150
167
|
}
|
|
151
168
|
interface TransformMenuOptions {
|
|
@@ -503,15 +520,38 @@ interface AuthConfig {
|
|
|
503
520
|
}
|
|
504
521
|
declare const AUTH_CONFIG: AuthConfig;
|
|
505
522
|
|
|
506
|
-
type
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
523
|
+
type AppLike = {
|
|
524
|
+
use: (plugin: any, ...args: any[]) => unknown;
|
|
525
|
+
component: (name: string, component: any) => unknown;
|
|
526
|
+
mount: (rootContainer: string | Element, ...args: any[]) => unknown;
|
|
527
|
+
};
|
|
528
|
+
type PluginTuple = [any, ...unknown[]];
|
|
529
|
+
type UsePluginItem = any | PluginTuple;
|
|
530
|
+
interface PortalBootstrapUserStoreLike {
|
|
531
|
+
syncFromAuthStore?: () => unknown;
|
|
532
|
+
setLoadUserMenulist?: () => unknown;
|
|
533
|
+
}
|
|
534
|
+
interface SetupAppOptions {
|
|
535
|
+
app: AppLike;
|
|
510
536
|
plugins?: UsePluginItem[];
|
|
511
537
|
elementIcons?: Record<string, unknown>;
|
|
512
538
|
beforeMount?: () => void;
|
|
513
539
|
mountSelector?: string;
|
|
514
540
|
}
|
|
541
|
+
interface SetupRuntimeOptions {
|
|
542
|
+
initI18n?: () => void;
|
|
543
|
+
getUserStore?: () => PortalBootstrapUserStoreLike | null | undefined;
|
|
544
|
+
bindPortalUiHttp?: () => void;
|
|
545
|
+
beforeReady?: () => void;
|
|
546
|
+
}
|
|
547
|
+
/**
|
|
548
|
+
* 统一处理业务前端在挂载前的常见初始化:
|
|
549
|
+
* 1. 绑定 i18n 工具
|
|
550
|
+
* 2. 恢复统一登录缓存
|
|
551
|
+
* 3. 重置菜单加载状态
|
|
552
|
+
* 4. 注入 portal-ui http 实例
|
|
553
|
+
*/
|
|
554
|
+
declare function setupRuntime(options: SetupRuntimeOptions): void;
|
|
515
555
|
/**
|
|
516
556
|
* 按 Portal 约定完成应用启动编排:
|
|
517
557
|
* 1. 注册插件
|
|
@@ -519,7 +559,7 @@ interface SetupPortalAppOptions {
|
|
|
519
559
|
* 3. 执行挂载前回调
|
|
520
560
|
* 4. 挂载应用
|
|
521
561
|
*/
|
|
522
|
-
declare function
|
|
562
|
+
declare function setupApp(options: SetupAppOptions): void;
|
|
523
563
|
|
|
524
564
|
interface CreateI18nOptions {
|
|
525
565
|
/** 翻译消息,key 为 locale(如 'zh-CN'),value 为翻译对象 */
|
|
@@ -537,4 +577,4 @@ interface CreateI18nOptions {
|
|
|
537
577
|
*/
|
|
538
578
|
declare function createPortalI18n(options: CreateI18nOptions): vue_i18n.I18n<Record<string, any>, {}, {}, string, false>;
|
|
539
579
|
|
|
540
|
-
export { AUTH_CONFIG, type AppRouterOptions, type AuthConfig, type BaseUserStoreLike, type BreadcrumbItem, type CoreMenuItem, type CoreMenuUserState, type CoreUserStoreLike, type CreateAuthHttpClientOptions, type CreateBaseUserActionsOptions, type CreateI18nOptions, type CreateMenuUserActionsOptions, DEFAULT_AUTH_LOGIN_ENV_KEY, DEFAULT_AUTH_LOGIN_PATH, DEFAULT_HOME_PATH, DEFAULT_SSO_STORAGE_KEY, type FetchUserMenuForStoreOptions, type FontSize, type InactivityConfig, type InactivityResult, type LoadingState, type LogoutToAuthOptions, type MenuHelper, type MenuHelperOptions, type PermissionHelper, type PermissionHelperOptions, type PresetRangeKey, type
|
|
580
|
+
export { AUTH_CONFIG, type AppRouterOptions, type AuthConfig, type BaseUserStoreLike, type BreadcrumbItem, type CoreMenuItem, type CoreMenuUserState, type CoreUserStoreLike, type CreateAuthHttpClientOptions, type CreateBaseUserActionsOptions, type CreateI18nOptions, type CreateMenuUserActionsOptions, type CreateSiteHttpModuleOptions, DEFAULT_AUTH_LOGIN_ENV_KEY, DEFAULT_AUTH_LOGIN_PATH, DEFAULT_HOME_PATH, DEFAULT_SSO_STORAGE_KEY, type FetchUserMenuForStoreOptions, type FontSize, type InactivityConfig, type InactivityResult, type LoadingState, type LogoutToAuthOptions, type MenuHelper, type MenuHelperOptions, type PermissionHelper, type PermissionHelperOptions, type PortalBootstrapUserStoreLike, type PresetRangeKey, type SetupAppOptions, type SetupRuntimeOptions, type SidebarMenuFilterOptions, type StaticAppRouterOptions, type SyncFromAuthStoreOptions, type TabItem, type ThemeConfig, type ThemeMode, type TimeInput, type TimeRange, type TransformMenuOptions, addTab, applyTheme, buildAllMenuTree, buildPageMenuList, calcInactivityAction, closeAll, closeLeft, closeOthers, closeRight, createAppRouter, createAuthHttpClient, createBaseUserActions, createBaseUserGetters, createBaseUserState, createLoadingStoreOptions, createLogoutToAuth, createMenuHelper, createMenuUserActions, createMenuUserGetters, createMenuUserState, createPermissionHelper, createPortalI18n, createRange, createSiteHttpModule, createStaticAppRouter, createTabStoreOptions, fetchUserMenuForStore, filterSidebarMenu, findFirstPagePath, formatRange, formatTime, formatToMonthDay, formatToWanShou, formatToYi, formatWanYuanToYi, getDefaultAuthLoginUrl, getPresetRange, humanizeTime, initTheme, isInRange, removeTab, setupApp, setupRuntime, syncFromAuthStoreToStore, timeDiff, transformMenuTree, useThemeWatcher, useTime };
|
package/dist/index.js
CHANGED
|
@@ -101,6 +101,7 @@ function transformMenuTree(menuList, options) {
|
|
|
101
101
|
icon: item?.icon,
|
|
102
102
|
order_num: item?.order_num,
|
|
103
103
|
site: item?.site ?? defaultSite,
|
|
104
|
+
is_blank_page: item?.is_blank_page,
|
|
104
105
|
children
|
|
105
106
|
};
|
|
106
107
|
});
|
|
@@ -117,6 +118,7 @@ function buildAllMenuTree(menuList) {
|
|
|
117
118
|
icon: item.icon,
|
|
118
119
|
order_num: item.order_num,
|
|
119
120
|
site: item.site,
|
|
121
|
+
is_blank_page: item.is_blank_page,
|
|
120
122
|
children: item.children && item.children.length > 0 ? buildAllMenuTree(item.children) : []
|
|
121
123
|
});
|
|
122
124
|
}
|
|
@@ -135,6 +137,7 @@ function buildPageMenuList(menuList) {
|
|
|
135
137
|
icon: item.icon,
|
|
136
138
|
order_num: item.order_num,
|
|
137
139
|
site: item.site,
|
|
140
|
+
is_blank_page: item.is_blank_page,
|
|
138
141
|
children: item.children ? buildPageMenuList(item.children) : []
|
|
139
142
|
});
|
|
140
143
|
} else if (item.children && item.children.length > 0) {
|
|
@@ -150,6 +153,7 @@ function buildPageMenuList(menuList) {
|
|
|
150
153
|
icon: child.icon,
|
|
151
154
|
order_num: child.order_num,
|
|
152
155
|
site: child.site,
|
|
156
|
+
is_blank_page: child.is_blank_page,
|
|
153
157
|
children: child.children
|
|
154
158
|
});
|
|
155
159
|
}
|
|
@@ -172,6 +176,9 @@ function findFirstPagePath(menuList) {
|
|
|
172
176
|
}
|
|
173
177
|
|
|
174
178
|
// src/router/router.ts
|
|
179
|
+
function resolveAuthLoginUrl(authLoginUrl) {
|
|
180
|
+
return authLoginUrl || `${window.location.origin}/auth/#/login`;
|
|
181
|
+
}
|
|
175
182
|
function createAppRouter(options) {
|
|
176
183
|
const {
|
|
177
184
|
staticRoutes,
|
|
@@ -207,7 +214,7 @@ function createAppRouter(options) {
|
|
|
207
214
|
history: createWebHashHistory(),
|
|
208
215
|
routes: staticRoutes
|
|
209
216
|
});
|
|
210
|
-
const AUTH_LOGIN_URL = authLoginUrl
|
|
217
|
+
const AUTH_LOGIN_URL = resolveAuthLoginUrl(authLoginUrl);
|
|
211
218
|
const modules = import.meta.glob("@/views/**/*.vue");
|
|
212
219
|
const registeredPaths = /* @__PURE__ */ new Set();
|
|
213
220
|
const resolveRouteAndView = (item) => {
|
|
@@ -369,6 +376,43 @@ function createAppRouter(options) {
|
|
|
369
376
|
});
|
|
370
377
|
return router;
|
|
371
378
|
}
|
|
379
|
+
function createStaticAppRouter(options) {
|
|
380
|
+
const {
|
|
381
|
+
staticRoutes,
|
|
382
|
+
getUserStore,
|
|
383
|
+
authLoginUrl,
|
|
384
|
+
requireAuth = false
|
|
385
|
+
} = options;
|
|
386
|
+
const router = createRouter({
|
|
387
|
+
history: createWebHashHistory(),
|
|
388
|
+
routes: staticRoutes
|
|
389
|
+
});
|
|
390
|
+
if (!requireAuth || !getUserStore) {
|
|
391
|
+
return router;
|
|
392
|
+
}
|
|
393
|
+
const AUTH_LOGIN_URL = resolveAuthLoginUrl(authLoginUrl);
|
|
394
|
+
router.beforeEach((_to, _from, next) => {
|
|
395
|
+
const userStore = getUserStore();
|
|
396
|
+
let accessToken = userStore.getUserAccessToken;
|
|
397
|
+
if (accessToken && !userStore.getUserName) {
|
|
398
|
+
userStore.syncFromAuthStore?.();
|
|
399
|
+
accessToken = userStore.getUserAccessToken;
|
|
400
|
+
}
|
|
401
|
+
if (!accessToken) {
|
|
402
|
+
const restored = userStore.syncFromAuthStore?.();
|
|
403
|
+
if (restored) {
|
|
404
|
+
accessToken = userStore.getUserAccessToken;
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
if (!accessToken) {
|
|
408
|
+
const currentUrl = encodeURIComponent(window.location.href);
|
|
409
|
+
window.location.href = `${AUTH_LOGIN_URL}?redirect=${currentUrl}`;
|
|
410
|
+
return;
|
|
411
|
+
}
|
|
412
|
+
next();
|
|
413
|
+
});
|
|
414
|
+
return router;
|
|
415
|
+
}
|
|
372
416
|
|
|
373
417
|
// src/config/auth-config.ts
|
|
374
418
|
var DEFAULT_SSO_STORAGE_KEY = "auth-user-store";
|
|
@@ -612,6 +656,13 @@ function createAuthHttpClient(options) {
|
|
|
612
656
|
);
|
|
613
657
|
return { http, logoutToAuth };
|
|
614
658
|
}
|
|
659
|
+
function createSiteHttpModule(options) {
|
|
660
|
+
const { http, logoutToAuth } = createAuthHttpClient(options);
|
|
661
|
+
return {
|
|
662
|
+
http,
|
|
663
|
+
logoutToAuth
|
|
664
|
+
};
|
|
665
|
+
}
|
|
615
666
|
|
|
616
667
|
// src/permission/permission.ts
|
|
617
668
|
function normalizePath2(raw) {
|
|
@@ -1006,9 +1057,12 @@ function createMenuUserGetters() {
|
|
|
1006
1057
|
isMenuLoaded: (state) => state.menuLoaded
|
|
1007
1058
|
};
|
|
1008
1059
|
}
|
|
1060
|
+
function isBlankPageMenu(item) {
|
|
1061
|
+
return item?.is_blank_page === true || item?.is_blank_page === "true" || item?.is_blank_page === 1;
|
|
1062
|
+
}
|
|
1009
1063
|
function filterSidebarMenu(menus, options) {
|
|
1010
1064
|
const exclude = options?.excludeCategories ?? ["button", "flow-module", "flow-page"];
|
|
1011
|
-
return (menus || []).filter((item) => !exclude.includes(item?.category)).map((item) => ({
|
|
1065
|
+
return (menus || []).filter((item) => !exclude.includes(item?.category) && !isBlankPageMenu(item)).map((item) => ({
|
|
1012
1066
|
...item,
|
|
1013
1067
|
children: item.children && item.children.length > 0 ? filterSidebarMenu(item.children, options) : []
|
|
1014
1068
|
}));
|
|
@@ -1173,7 +1227,21 @@ function usePlugin(app, plugin) {
|
|
|
1173
1227
|
}
|
|
1174
1228
|
app.use(plugin);
|
|
1175
1229
|
}
|
|
1176
|
-
function
|
|
1230
|
+
function setupRuntime(options) {
|
|
1231
|
+
const {
|
|
1232
|
+
initI18n,
|
|
1233
|
+
getUserStore,
|
|
1234
|
+
bindPortalUiHttp,
|
|
1235
|
+
beforeReady
|
|
1236
|
+
} = options;
|
|
1237
|
+
initI18n?.();
|
|
1238
|
+
const userStore = getUserStore?.();
|
|
1239
|
+
userStore?.syncFromAuthStore?.();
|
|
1240
|
+
userStore?.setLoadUserMenulist?.();
|
|
1241
|
+
bindPortalUiHttp?.();
|
|
1242
|
+
beforeReady?.();
|
|
1243
|
+
}
|
|
1244
|
+
function setupApp(options) {
|
|
1177
1245
|
const {
|
|
1178
1246
|
app,
|
|
1179
1247
|
plugins = [],
|
|
@@ -1242,6 +1310,8 @@ export {
|
|
|
1242
1310
|
createPermissionHelper,
|
|
1243
1311
|
createPortalI18n,
|
|
1244
1312
|
createRange,
|
|
1313
|
+
createSiteHttpModule,
|
|
1314
|
+
createStaticAppRouter,
|
|
1245
1315
|
createTabStoreOptions,
|
|
1246
1316
|
fetchUserMenuForStore,
|
|
1247
1317
|
filterSidebarMenu,
|
|
@@ -1258,7 +1328,8 @@ export {
|
|
|
1258
1328
|
initTheme,
|
|
1259
1329
|
isInRange,
|
|
1260
1330
|
removeTab,
|
|
1261
|
-
|
|
1331
|
+
setupApp,
|
|
1332
|
+
setupRuntime,
|
|
1262
1333
|
syncFromAuthStoreToStore,
|
|
1263
1334
|
timeDiff,
|
|
1264
1335
|
transformMenuTree,
|