hrp-ui-base 1.3.7 → 1.4.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hrp-ui-base",
3
- "version": "1.3.7",
3
+ "version": "1.4.0",
4
4
  "description": "HRP 前端公共组件、工具方法和基础样式包",
5
5
  "type": "module",
6
6
  "sideEffects": [
@@ -11,7 +11,7 @@
11
11
  "devDependencies": {},
12
12
  "module": "index.ts",
13
13
  "peerDependencies": {
14
- "hrp-ui-base": "1.3.6",
14
+ "hrp-ui-base": "1.4.0",
15
15
  "vue": "^3.0.0"
16
16
  }
17
17
  }
@@ -79,8 +79,8 @@ import { ref, watch, inject } from "vue";
79
79
  import FlowInstanceController from "../../api/bms/flow/FlowInstanceController";
80
80
  import type AssociatedApprovalVO from "../../api/bms/flow/bo/AssociatedApprovalVO";
81
81
  import TableQueryCriteriaVO from "../../api/common/TableQueryCriteriaVO";
82
- import { useLayoutMenuStore } from "./stores/useLayoutMenuStore";
83
82
  import { LAYOUT_ROUTER_KEY } from "./plugin";
83
+ import { navigateByDomainRoute } from "./utils/redirect";
84
84
 
85
85
  // 默认头像 - 使用一个简单的 SVG data URI
86
86
  const defaultAvatar = "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'%3E%3Ccircle cx='16' cy='16' r='16' fill='%23e0e0e0'/%3E%3Ccircle cx='16' cy='12' r='5' fill='%23fff'/%3E%3Cpath d='M6 28c0-5.5 4.5-10 10-10s10 4.5 10 10' fill='%23fff'/%3E%3C/svg%3E";
@@ -94,7 +94,6 @@ const emit = defineEmits<{
94
94
  }>();
95
95
 
96
96
  const router = inject<any>(LAYOUT_ROUTER_KEY);
97
- const menuStore = useLayoutMenuStore();
98
97
 
99
98
  const drawerVisible = ref(false);
100
99
  const loading = ref(false);
@@ -152,11 +151,7 @@ const handlePageChange = () => {
152
151
  /** 跳转到审批详情页 */
153
152
  const gotoRelatedPage = async (item: AssociatedApprovalVO) => {
154
153
  if (!item.approveUrl) return;
155
- // 跨系统判断
156
- if (item.funSystem && item.funSystem !== localStorage.getItem("current-application-id")) {
157
- await menuStore.getDomainAndHomeMenu(item.approveUrl, router);
158
- }
159
- router?.push(item.approveUrl);
154
+ await navigateByDomainRoute(item.approveUrl, router);
160
155
  emit("update:visible", false);
161
156
  };
162
157
  </script>
@@ -110,6 +110,7 @@ import type { TabsOptions } from "./stores/useLayoutTabsStore";
110
110
  import type HomeMenu from "../../api/bms/home/bo/HomeMenu";
111
111
  import type NoticeVO from "../../api/notice/bo/NoticeVO";
112
112
  import { ElNotification, ElMessage } from "element-plus";
113
+ import { navigateByDomainRoute } from "./utils/redirect";
113
114
 
114
115
  defineOptions({ name: "LayoutContainer" });
115
116
 
@@ -287,10 +288,11 @@ const handleMessageNavigate = async (notice: NoticeVO) => {
287
288
  await noticeStore.readNoticeInfo(notice.noticeId);
288
289
  await noticeStore.getNoReadNoticeCount();
289
290
  updateNum.value += 1;
290
- if (notice.urlRoute.startsWith("/project/")) {
291
- options?.onCrossAppNavigate?.(notice.urlRoute);
291
+ if (!notice.urlRoute) return;
292
+ if (notice.urlRoute.startsWith("/project/") && options?.onCrossAppNavigate) {
293
+ options.onCrossAppNavigate(notice.urlRoute);
292
294
  } else {
293
- await router?.push(buildRouteLocation(notice.urlRoute));
295
+ await navigateByDomainRoute(notice.urlRoute, router);
294
296
  }
295
297
  };
296
298
 
@@ -298,7 +300,11 @@ const handleMessageDownload = async (notice: NoticeVO) => {
298
300
  await noticeStore.readNoticeInfo(notice.noticeId);
299
301
  await noticeStore.getNoReadNoticeCount();
300
302
  updateNum.value += 1;
301
- options?.onFileDownload?.(notice);
303
+ if (options?.onFileDownload) {
304
+ options.onFileDownload(notice);
305
+ } else {
306
+ await navigateByDomainRoute("/bms/base-manage/base-information/export-center", router);
307
+ }
302
308
  };
303
309
 
304
310
  const handleMessageUpdateCount = async () => {
@@ -410,11 +416,15 @@ const showNoticeNotification = async (notice: NoticeVO) => {
410
416
  await noticeStore.getNoReadNoticeCount();
411
417
  updateNum.value += 1;
412
418
  if (notice.noticeType === "file-notice") {
413
- options?.onFileDownload?.(notice);
414
- } else if (notice.urlRoute.startsWith("/project/")) {
415
- options?.onCrossAppNavigate?.(notice.urlRoute);
419
+ if (options?.onFileDownload) {
420
+ options.onFileDownload(notice);
421
+ } else {
422
+ await navigateByDomainRoute("/bms/base-manage/base-information/export-center", router);
423
+ }
424
+ } else if (notice.urlRoute?.startsWith("/project/") && options?.onCrossAppNavigate) {
425
+ options.onCrossAppNavigate(notice.urlRoute);
416
426
  } else {
417
- await router?.push(buildRouteLocation(notice.urlRoute));
427
+ await navigateByDomainRoute(notice.urlRoute, router);
418
428
  }
419
429
  closeNotification();
420
430
  };
@@ -455,18 +465,6 @@ const showNoticeNotification = async (notice: NoticeVO) => {
455
465
  updateNum.value += 1;
456
466
  };
457
467
 
458
- // ====== 辅助函数 ======
459
- const buildRouteLocation = (urlRoute: string) => {
460
- const [path, search] = urlRoute.split("?");
461
- const query: Record<string, string> = {};
462
- if (search) {
463
- new URLSearchParams(search).forEach((value, key) => {
464
- query[key] = value;
465
- });
466
- }
467
- return { path: path || "/", query };
468
- };
469
-
470
468
  // ====== 生命周期 ======
471
469
  onMounted(async () => {
472
470
  // 初始化用户配置
@@ -0,0 +1,120 @@
1
+ /**
2
+ * Layout cross-system route redirect helpers.
3
+ * Mirrors ui-hrp-entry/public/utils/redirect.js for runtime layout components.
4
+ */
5
+
6
+ const menuStateRelation: Record<string, string> = {
7
+ imd: "imd",
8
+ agoal: "agoal",
9
+ scm: "scm",
10
+ bms: "bms",
11
+ coc: "coc",
12
+ hws: "hws",
13
+ fms: "fms",
14
+ hrm: "hrm",
15
+ hrms: "hrms",
16
+ itr: "itrms",
17
+ personalization: "imd",
18
+ projectManagement: "projectManagement",
19
+ };
20
+
21
+ const loginPaths = ["/auth-login", "/oa-login", "/login"];
22
+
23
+ const normalizeBasePath = (path: string) => {
24
+ if (!path || path === "/") return "";
25
+ return path.endsWith("/") ? path.slice(0, -1) : path;
26
+ };
27
+
28
+ const getKnownDomainIds = () => {
29
+ return Array.from(new Set(Object.values(menuStateRelation)));
30
+ };
31
+
32
+ /**
33
+ * Get deploy base path before app segment.
34
+ *
35
+ * Examples:
36
+ * - /login -> ""
37
+ * - /hrp/login -> /hrp
38
+ * - /hws/ -> ""
39
+ * - /hrp/hws/ -> /hrp
40
+ */
41
+ export const getLayoutBasePath = () => {
42
+ const pathname = window.location.pathname || "/";
43
+
44
+ for (const loginPath of loginPaths) {
45
+ const idx = pathname.indexOf(loginPath);
46
+ if (idx !== -1) {
47
+ return normalizeBasePath(pathname.substring(0, idx));
48
+ }
49
+ }
50
+
51
+ const parts = pathname.split("/").filter(Boolean);
52
+ const knownDomainIds = getKnownDomainIds();
53
+ const lastPart = parts[parts.length - 1];
54
+ if (lastPart && knownDomainIds.includes(lastPart)) {
55
+ return normalizeBasePath(`/${parts.slice(0, -1).join("/")}`);
56
+ }
57
+
58
+ return normalizeBasePath(pathname.replace(/\/$/, ""));
59
+ };
60
+
61
+ export const normalizeRoutePath = (urlRoute: string) => {
62
+ if (!urlRoute) return "";
63
+ if (/^https?:\/\//i.test(urlRoute)) return urlRoute;
64
+
65
+ const [path = "", search = ""] = urlRoute.split("?");
66
+ const normalizedPath = path.startsWith("/") ? path : `/${path}`;
67
+ return search ? `${normalizedPath}?${search}` : normalizedPath;
68
+ };
69
+
70
+ export const buildRouteLocation = (urlRoute: string) => {
71
+ const routePath = normalizeRoutePath(urlRoute);
72
+ const [path, search] = routePath.split("?");
73
+ const query: Record<string, string> = {};
74
+ if (search) {
75
+ new URLSearchParams(search).forEach((value, key) => {
76
+ query[key] = value;
77
+ });
78
+ }
79
+ return { path: path || "/", query };
80
+ };
81
+
82
+ export const getDomainRedirectUrl = (urlRoute: string) => {
83
+ const routePath = normalizeRoutePath(urlRoute);
84
+ if (!routePath) return "";
85
+ if (/^https?:\/\//i.test(routePath)) return routePath;
86
+
87
+ const cleaned = routePath.replace(/^\/+/, "");
88
+ const firstValue = cleaned.split("/")[0] || "";
89
+ const basePath = getLayoutBasePath();
90
+ const domainId = menuStateRelation[firstValue];
91
+ const originBase = `${window.location.origin}${basePath}`;
92
+
93
+ if (domainId === "bms" || !domainId) {
94
+ return `${originBase}/#${routePath}`;
95
+ }
96
+ return `${originBase}/${domainId}/#${routePath}`;
97
+ };
98
+
99
+ const isSameAppUrl = (targetUrl: string) => {
100
+ const target = new URL(targetUrl, window.location.origin);
101
+ const currentPath = window.location.pathname.replace(/\/$/, "");
102
+ const targetPath = target.pathname.replace(/\/$/, "");
103
+ return target.origin === window.location.origin && targetPath === currentPath;
104
+ };
105
+
106
+ export const navigateByDomainRoute = async (urlRoute: string, router?: any) => {
107
+ const routePath = normalizeRoutePath(urlRoute);
108
+ if (!routePath) return;
109
+
110
+ const targetUrl = getDomainRedirectUrl(routePath);
111
+ if (!targetUrl) return;
112
+
113
+ if (router && isSameAppUrl(targetUrl)) {
114
+ await router.push(buildRouteLocation(routePath));
115
+ return;
116
+ }
117
+
118
+ window.location.href = targetUrl;
119
+ };
120
+