@bams-app/router 0.1.3 → 0.2.0-beta.1

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bams-app/router",
3
- "version": "0.1.3",
3
+ "version": "0.2.0-beta.1",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "main": "src/index.js",
@@ -14,10 +14,10 @@
14
14
  "vue-router": "^4.0.0"
15
15
  },
16
16
  "dependencies": {
17
- "@bams-app/api-model": "^0.1.3",
18
- "@bams-app/app-layout": "^0.1.3",
19
- "@bams-app/store": "^0.1.3",
20
- "@bams-app/utils": "^0.1.3",
17
+ "@bams-app/api-model": "^0.2.0-beta.1",
18
+ "@bams-app/app-layout": "^0.2.0-beta.1",
19
+ "@bams-app/store": "^0.2.0-beta.1",
20
+ "@bams-app/utils": "^0.2.0-beta.1",
21
21
  "axios": "^1.13.2"
22
22
  },
23
23
  "devDependencies": {
@@ -65,7 +65,7 @@
65
65
  };
66
66
 
67
67
  onMounted(async () => {
68
- const { sessionId, token, menuType, accountId, redirect, sysCode } = route.query;
68
+ const { sessionId, token, menuType, accountId, corpCode, redirect, sysCode } = route.query;
69
69
 
70
70
  // 1. 如果已经登录(登录组件已在本页建立会话),直接回跳,
71
71
  // 避免再次调用 getAccountData,同时避免二次请求失败时把已建立的会话清掉
@@ -108,6 +108,7 @@
108
108
  sessionId,
109
109
  menuType,
110
110
  accountId: userData.accountId || accountId,
111
+ corpCode: userData.corpCode || corpCode,
111
112
  role: "user",
112
113
  permissionMap: {},
113
114
  data: userData,
@@ -1,21 +1,32 @@
1
1
  <template>
2
2
  <div class="not-found-container">
3
- <a-result status="404" title="404" :sub-title="subTitle">
4
- <template #extra>
5
- <a-button @click="goBack">返回上一步</a-button>
6
- <a-button type="primary" @click="goHome">{{ backButtonText }}</a-button>
7
- </template>
8
- </a-result>
3
+ <!-- 顶层错误页不在 work 布局内,复用可配置 Header 组件提供退出登录等入口;
4
+ 系统被嵌入 iframe 时由外层系统承载头部,这里不再重复显示 -->
5
+ <HeaderComponent v-if="!isInIframe" :show-toggle-icon="false" />
6
+ <div class="not-found-body">
7
+ <a-result status="404" title="404" :sub-title="subTitle">
8
+ <template #extra>
9
+ <a-button @click="goBack">返回上一步</a-button>
10
+ <a-button type="primary" @click="goHome">{{ backButtonText }}</a-button>
11
+ </template>
12
+ </a-result>
13
+ </div>
9
14
  </div>
10
15
  </template>
11
16
 
12
17
  <script setup>
13
18
  import { computed } from "vue";
14
19
  import { useRoute, useRouter } from "vue-router";
20
+ import { env } from "@bams-app/utils";
21
+ // 编译阶段根据环境变量通过通用插槽别名选择组件
22
+ import HeaderComponent from "@configurable/header";
15
23
 
16
24
  const route = useRoute();
17
25
  const router = useRouter();
18
26
 
27
+ // 当前系统是否被宿主以 iframe 方式嵌入,被嵌入时头部由外层系统承载
28
+ const isInIframe = env.isInIframe();
29
+
19
30
  const fromPath = computed(() => (typeof route.query.from === "string" ? route.query.from : ""));
20
31
  const notFoundPath = computed(() => fromPath.value || route.fullPath);
21
32
  const subTitle = computed(() => `抱歉,您访问的页面不存在。访问地址:${notFoundPath.value}`);
@@ -46,8 +57,15 @@
46
57
  .not-found-container {
47
58
  height: 100%;
48
59
  display: flex;
60
+ flex-direction: column;
61
+ background-color: var(--bams-page-bg);
62
+ }
63
+
64
+ .not-found-body {
65
+ flex: 1;
66
+ min-height: 0;
67
+ display: flex;
49
68
  align-items: center;
50
69
  justify-content: center;
51
- background-color: var(--bams-page-bg);
52
70
  }
53
71
  </style>
@@ -1,21 +1,33 @@
1
1
  <template>
2
2
  <div class="system-error-container">
3
- <a-result status="error" title="系统错误" :sub-title="subTitle">
4
- <template #extra>
5
- <a-button @click="goBack">返回上一步</a-button>
6
- <a-button type="primary" @click="goHome">{{ backButtonText }}</a-button>
7
- </template>
8
- </a-result>
3
+ <!-- 顶层错误页不在 work 布局内,复用可配置 Header 组件提供退出登录等入口;
4
+ 系统被嵌入 iframe 时由外层系统承载头部,这里不再重复显示 -->
5
+ <HeaderComponent v-if="!isInIframe" :show-toggle-icon="false" />
6
+ <div class="system-error-body">
7
+ <a-result status="error" title="系统错误" :sub-title="subTitle">
8
+ <template #extra>
9
+ <a-button @click="goBack">返回上一步</a-button>
10
+ <a-button @click="retry">重试</a-button>
11
+ <a-button type="primary" @click="goHome">{{ backButtonText }}</a-button>
12
+ </template>
13
+ </a-result>
14
+ </div>
9
15
  </div>
10
16
  </template>
11
17
 
12
18
  <script setup>
13
19
  import { computed } from "vue";
14
20
  import { useRoute, useRouter } from "vue-router";
21
+ import { env } from "@bams-app/utils";
22
+ // 编译阶段根据环境变量通过通用插槽别名选择组件
23
+ import HeaderComponent from "@configurable/header";
15
24
 
16
25
  const route = useRoute();
17
26
  const router = useRouter();
18
27
 
28
+ // 当前系统是否被宿主以 iframe 方式嵌入,被嵌入时头部由外层系统承载
29
+ const isInIframe = env.isInIframe();
30
+
19
31
  const errorSource = computed(() => (typeof route.query.source === "string" ? route.query.source : ""));
20
32
  const errorMessage = computed(() => (typeof route.query.message === "string" ? route.query.message : ""));
21
33
  const fromPath = computed(() => (typeof route.query.from === "string" ? route.query.from : ""));
@@ -29,6 +41,11 @@
29
41
  const isFromWork = computed(() => fromPath.value.includes("/work/"));
30
42
  const backButtonText = computed(() => (isFromWork.value ? "回到系统首页" : "返回首页"));
31
43
 
44
+ // 重试:回到失败前的地址,由路由守卫重新拉取菜单并注册路由
45
+ const retry = () => {
46
+ window.location.replace(router.resolve(fromPath.value || "/").href);
47
+ };
48
+
32
49
  const goHome = () => {
33
50
  let targetPath = "/";
34
51
  if (isFromWork.value) {
@@ -53,8 +70,15 @@
53
70
  .system-error-container {
54
71
  height: 100%;
55
72
  display: flex;
73
+ flex-direction: column;
74
+ background-color: var(--bams-page-bg);
75
+ }
76
+
77
+ .system-error-body {
78
+ flex: 1;
79
+ min-height: 0;
80
+ display: flex;
56
81
  align-items: center;
57
82
  justify-content: center;
58
- background-color: var(--bams-page-bg);
59
83
  }
60
84
  </style>
@@ -84,12 +84,16 @@ export default function createRoutes(workLayout = undefined, routes = [], appCon
84
84
  {
85
85
  path: "/404",
86
86
  name: "404",
87
- component: NotFound
87
+ component: NotFound,
88
+ // 错误页不作为登录后的回跳目标(routerController 未登录分支据此回跳首页),
89
+ // 否则从错误页退出后重新登录会被再次带回错误页
90
+ meta: { isErrorPage: true }
88
91
  },
89
92
  {
90
93
  path: "/500",
91
94
  name: "500",
92
- component: SystemError
95
+ component: SystemError,
96
+ meta: { isErrorPage: true }
93
97
  },
94
98
  ...routes
95
99
  ];
@@ -1,6 +1,6 @@
1
1
  import { hasRoute, registerRoutes, registerRoutesByMenu, toNoPermissionOrNotFound, DEFAULT_HOME } from "./registerRoutes.js";
2
2
  import { useUserStore, useMenuStore } from "@bams-app/store";
3
- import { auth, url } from "@bams-app/utils";
3
+ import { auth } from "@bams-app/utils";
4
4
 
5
5
  const allowList = ["login", "register"];
6
6
  const loginRoutePath = "/login";
@@ -30,11 +30,23 @@ export default async function routerController(to, from, next) {
30
30
  // 2. 未登录时,仅允许访问匿名路由,其余统一跳转登录页
31
31
  const isAllowAnonymousRoute = allowList.includes(to.name) || to.meta?.allowAnonymous || to.path === loginRoutePath || pathWhiteList.some(path => to.path.includes(path));
32
32
  if (!userStore.checkLogin() && !isAllowAnonymousRoute) {
33
+ // 错误页(/404、/500)不作为登录后的回跳目标:从错误页退出后重新登录若回到错误页,
34
+ // 用户会再次看到错误页,故统一回跳应用首页(resolve 会自动带上 BASE_URL 前缀)
35
+ const callbackPath = to.meta?.isErrorPage ? router.resolve("/").href : to.href;
36
+ // 配置了第三方登录地址时整页跳转过去,由第三方登录成功后携带 token 回跳 callback_url,
37
+ // 再由 /auth/login 中间件消费 token 建立本地会话;未配置时保持原有本地登录页跳转
38
+ if (auth.isExternalLoginPage()) {
39
+ // callbackPath 是带 base 的路径(不含 origin),第三方登录页可能在其他域名,
40
+ // 必须补全为绝对地址,否则第三方会把它当相对路径拼到自己域名下,登录后跳错站点
41
+ const callbackUrl = new URL(callbackPath, window.location.origin).toString();
42
+ auth.redirectToLoginPage({ callbackPath: callbackUrl });
43
+ return;
44
+ }
33
45
  next({
34
46
  path: loginRoutePath,
35
47
  query: {
36
48
  sysCode: auth.getSysCode(),
37
- callback_url: to.href
49
+ callback_url: callbackPath
38
50
  }
39
51
  });
40
52
  return;