|
|
@@ -0,0 +1,63 @@
|
|
|
+import type { Router } from 'vue-router';
|
|
|
+import { useRouter } from 'vue-router';
|
|
|
+import { openWindow } from '/@/utils';
|
|
|
+import { PAGE_NOT_FOUND_NAME } from '/@/router/constant';
|
|
|
+
|
|
|
+/**
|
|
|
+ * 解析跳转地址,可以按站内路由跳转时返回路由地址,否则返回 null
|
|
|
+ * 1. 完整链接(如 http://当前域名:端口/ventilate/warn/home)且地址与当前地址一致:去掉地址部分,取 /ventilate/warn/home
|
|
|
+ * 2. 站内路由(如 /ventilate/warn/home):直接返回
|
|
|
+ * 3. 其他情况(外部链接、非同源链接、未注册的路由等):返回 null,由调用方按原有逻辑跳转
|
|
|
+ * @param to 配置的跳转地址
|
|
|
+ * @param router 路由实例
|
|
|
+ */
|
|
|
+export function resolveRoutePath(to: unknown, router: Router): string | null {
|
|
|
+ if (typeof to !== 'string') return null;
|
|
|
+ const value = to.trim();
|
|
|
+ if (!value) return null;
|
|
|
+
|
|
|
+ let path: string;
|
|
|
+ if (value.startsWith('/') && !value.startsWith('//')) {
|
|
|
+ // 站内路由
|
|
|
+ path = value;
|
|
|
+ } else {
|
|
|
+ // 完整链接或相对链接:解析后与当前地址同源,才认为可以在当前应用内跳转
|
|
|
+ let url: URL;
|
|
|
+ try {
|
|
|
+ url = new URL(value, window.location.href);
|
|
|
+ } catch {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ if (url.origin !== window.location.origin) return null;
|
|
|
+ path = `${url.pathname}${url.search}${url.hash}`;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 只对已注册的路由做路由跳转,避免把同源的非单页应用地址也带进来
|
|
|
+ try {
|
|
|
+ const resolved = router.resolve(path);
|
|
|
+ const isRoute = resolved.matched.length > 0 && resolved.matched.every((r) => r.name !== PAGE_NOT_FOUND_NAME);
|
|
|
+ return isRoute ? path : null;
|
|
|
+ } catch {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * 首页模块标题跳转:
|
|
|
+ * 站内路由使用 router.push 跳转,其余地址保持原有 openWindow 逻辑
|
|
|
+ */
|
|
|
+export function useRedirect() {
|
|
|
+ const router = useRouter();
|
|
|
+
|
|
|
+ return function redirect(to: unknown) {
|
|
|
+ if (typeof to !== 'string' || !to) return;
|
|
|
+ const path = resolveRoutePath(to, router);
|
|
|
+ if (path) {
|
|
|
+ console.log('debug push');
|
|
|
+ router.push(path);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ console.log('debug open');
|
|
|
+ openWindow(to, { target: '_self' });
|
|
|
+ };
|
|
|
+}
|