Explorar o código

feat(web-admin): skip desktop chrome and login page inside mp webview routes.

Co-authored-by: Cursor <cursoragent@cursor.com>
wuzilong hai 1 mes
pai
achega
c0721786ff

+ 13 - 2
web-admin/src/router/guards/beforeEach.ts

@@ -55,6 +55,7 @@ import { ApiStatus } from '@/utils/http/status'
 import { isHttpError } from '@/utils/http/error'
 import { RouteRegistry, MenuProcessor, IframeRouteManager, RoutePermissionValidator } from '../core'
 import { refreshMenuBadges } from '@/utils/menu-badge-registry'
+import { isMpWebviewPath } from '@/utils/mp-webview'
 
 // 路由注册器实例
 let routeRegistry: RouteRegistry | null = null
@@ -176,6 +177,11 @@ async function handleRouteGuard(
 
   // 3. 处理动态路由注册
   if (!routeRegistry?.isRegistered() && userStore.isLogin) {
+    if (isMpWebviewPath(to.path)) {
+      setPageTitle(to)
+      next()
+      return
+    }
     // 防止并发请求(快速连续导航场景)
     if (routeInitInProgress) {
       // 正在初始化中,等待完成后重新导航
@@ -218,8 +224,13 @@ function handleLoginStatus(
     return false
   }
 
-  // 已登录或访问登录页或静态路由,直接放行
-  if (userStore.isLogin || to.path === RoutesAlias.Login || isStaticRoute(to.path)) {
+  // 已登录或访问登录页、静态路由、小程序 WebView 路由,直接放行
+  if (
+    userStore.isLogin ||
+    to.path === RoutesAlias.Login ||
+    isStaticRoute(to.path) ||
+    isMpWebviewPath(to.path)
+  ) {
     return true
   }
 

+ 6 - 1
web-admin/src/store/modules/user.ts

@@ -28,6 +28,7 @@ import { StorageConfig } from '@/utils/storage/storage-config'
 import { fetchLogout } from '@/api/auth'
 import { RoutesAlias } from '@/router/routesAlias'
 import { resolveSafeRedirectTarget } from '@/utils/router'
+import { isMpWebviewPath, redirectToMiniLogin } from '@/utils/mp-webview'
 
 /**
  * 用户状态管理
@@ -160,8 +161,12 @@ export const useUserStore = defineStore(
       clearPortalHomeActiveModule()
       // 重置路由状态
       resetRouterState(500)
-      // 跳转到登录页,携带当前路由作为 redirect 参数
       const currentRoute = router.currentRoute.value
+      if (isMpWebviewPath(currentRoute.path)) {
+        redirectToMiniLogin()
+        return
+      }
+      // 跳转到登录页,携带当前路由作为 redirect 参数
       const redirect =
         currentRoute.path !== RoutesAlias.Login
           ? resolveSafeRedirectTarget(currentRoute.fullPath, '')

+ 35 - 0
web-admin/src/utils/mp-webview.ts

@@ -0,0 +1,35 @@
+export const MP_WEBVIEW_PATH_PREFIX = '/m/'
+
+export function isMpWebviewPath(path: string): boolean {
+  return (path || '').startsWith(MP_WEBVIEW_PATH_PREFIX)
+}
+
+export function getWxMiniProgram(): {
+  reLaunch?: (opt: { url: string }) => void
+  navigateBack?: (opt?: { delta?: number }) => void
+} | null {
+  if (typeof window === 'undefined') return null
+  const wxObj = (window as unknown as { wx?: { miniProgram?: unknown } }).wx
+  const mini = wxObj?.miniProgram as
+    | { reLaunch?: (opt: { url: string }) => void; navigateBack?: (opt?: { delta?: number }) => void }
+    | undefined
+  return mini || null
+}
+
+export function redirectToMiniLogin(): void {
+  const mini = getWxMiniProgram()
+  if (mini?.reLaunch) {
+    mini.reLaunch({ url: '/pages/login/login' })
+    return
+  }
+  // 非小程序:只展示空态,禁止跳管理端登录
+}
+
+export function stripMpTicketFromUrl(
+  path: string,
+  query: Record<string, unknown>
+): Record<string, unknown> {
+  const next = { ...query }
+  delete next.mpTicket
+  return next
+}