Explorar el Código

feat: 中间件跳转路由

reaper hace 23 horas
padre
commit
2d969ecd4f

+ 5 - 0
.gitignore

@@ -22,3 +22,8 @@ logs
 .env
 .env.*
 !.env.example
+
+.trae
+.github
+.agents
+.gitignore

+ 4 - 4
app/components/FooterH5.vue

@@ -1,6 +1,6 @@
 <template>
-  <footer class="h5-footer">
-    <div class="h5-footer-container">
+  <footer class="mobile-footer">
+    <div class="mobile-footer-container">
       <div class="footer-brand">
         <h2 class="brand-title">DDAC</h2>
       </div>
@@ -35,7 +35,7 @@
 </script>
 
 <style scoped lang="scss">
-.h5-footer {
+.mobile-footer {
   width: 100%;
   background-color: #030014;
   border-top: 1px solid rgba(255, 255, 255, 0.1);
@@ -43,7 +43,7 @@
   margin-top: auto;
 }
 
-.h5-footer-container {
+.mobile-footer-container {
   max-width: 768px;
   margin: 0 auto;
 }

+ 8 - 8
app/components/Header.vue

@@ -7,35 +7,35 @@
       </a>
     </div>
     <nav class="header-nav" role="navigation" aria-label="Main navigation">
-      <NuxtLink to="/pc" class="nav-item">首页</NuxtLink>
+      <NuxtLink to="/web" class="nav-item">首页</NuxtLink>
       <div class="nav-item-wrapper">
         <div class="nav-item">
           <span>产品</span>
           <Icon name="line-md:chevron-down" class="nav-item-icon" />
         </div>
         <div class="dropdown-menu">
-          <NuxtLink to="/pc/products/sdk" class="dropdown-item">
+          <NuxtLink to="/web/products/sdk" class="dropdown-item">
             <img class="item-img" src="~/assets/svg/header/icon1.svg" alt="SDK 安全加固">
             <div class="item-text">
               <p>SDK 安全加固</p>
               <span>三合一:抗 D、消 C、挡 W</span>
             </div>
           </NuxtLink>
-          <NuxtLink to="/pc/products/web" class="dropdown-item">
+          <NuxtLink to="/web/products/web" class="dropdown-item">
             <img class="item-img" src="~/assets/svg/header/icon2.svg" alt="Web 安全加速">
             <div class="item-text">
               <p>Web 安全加速</p>
               <span>部署 30 秒,省心 365 天</span>
             </div>
           </NuxtLink>
-          <NuxtLink to="/pc/products/dns" class="dropdown-item">
+          <NuxtLink to="/web/products/dns" class="dropdown-item">
             <img class="item-img" src="~/assets/svg/header/icon3.svg" alt="DNS 全球解析">
             <div class="item-text">
               <p>DNS 全球解析</p>
               <span>把地球缩成局域网——全球 280+ 节点实时同步</span>
             </div>
           </NuxtLink>
-          <NuxtLink to="/pc/products/boost" class="dropdown-item">
+          <NuxtLink to="/web/products/boost" class="dropdown-item">
             <img class="item-img" src="~/assets/svg/header/icon4.svg" alt="高防服务器">
             <div class="item-text">
               <p>高防服务器</p>
@@ -44,9 +44,9 @@
           </NuxtLink>
         </div>
       </div>
-      <NuxtLink to="/pc/solutions" class="nav-item">行业解决方案</NuxtLink>
-      <NuxtLink to="/pc/docs" class="nav-item">文档中心</NuxtLink>
-      <NuxtLink to="/pc/about" class="nav-item">了解我们</NuxtLink>
+      <NuxtLink to="/web/solutions" class="nav-item">行业解决方案</NuxtLink>
+      <NuxtLink to="/web/docs" class="nav-item">文档中心</NuxtLink>
+      <NuxtLink to="/web/about" class="nav-item">了解我们</NuxtLink>
     </nav>
     <div class="header-right">
       <div>登录</div>

+ 1 - 1
app/components/HeaderH5.vue

@@ -105,7 +105,7 @@ const toggleMenu = () => {
   }
 }
 
-.h5-nav {
+.mobile-nav {
   background: #030014;
   border-top: 1px solid rgba(255, 255, 255, 0.1);
   padding: 16px;

+ 4 - 4
app/layouts/h5.vue → app/layouts/mobile.vue

@@ -1,7 +1,7 @@
 <template>
-  <div class="h5-layout">
+  <div class="mobile-layout">
     <HeaderH5 />
-    <main class="h5-layout-main">
+    <main class="mobile-layout-main">
       <slot />
     </main>
     <FooterH5 />
@@ -13,7 +13,7 @@
 </script>
 
 <style scoped lang="scss">
-.h5-layout {
+.mobile-layout {
   width: 100%;
   min-height: 100vh;
   background-color: #030014;
@@ -21,7 +21,7 @@
   flex-direction: column;
 }
 
-.h5-layout-main {
+.mobile-layout-main {
   flex: 1;
   width: 100%;
   padding: 60px 16px 16px;

+ 4 - 4
app/layouts/pc.vue → app/layouts/web.vue

@@ -1,7 +1,7 @@
 <template>
-  <div class="pc-layout">
+  <div class="web-layout">
     <Header />
-    <main class="pc-layout-main">
+    <main class="web-layout-main">
       <slot />
     </main>
     <Footer />
@@ -13,7 +13,7 @@
 </script>
 
 <style scoped lang="scss">
-.pc-layout {
+.web-layout {
   width: 100%;
   min-height: 100vh;
   background-color: #030014;
@@ -21,7 +21,7 @@
   flex-direction: column;
 }
 
-.pc-layout-main {
+.web-layout-main {
   flex: 1;
   width: 100%;
   box-sizing: border-box;

+ 26 - 0
app/middleware/redirect.global.ts

@@ -0,0 +1,26 @@
+export default defineNuxtRouteMiddleware((to, from) => {
+  // 仅在根路径 '/' 进行判断,避免循环重定向或其他页面被误伤
+  if (to.path === '/') {
+    // 获取 User-Agent
+    // 注意:在 SSR 环境下,我们需要从请求头获取;在客户端导航时,使用 navigator
+    let userAgent = '';
+    
+    if (process.server) {
+      const headers = useRequestHeaders(['user-agent']);
+      userAgent = headers['user-agent'] || '';
+    } else {
+      userAgent = navigator.userAgent;
+    }
+
+    // 定义移动端正则匹配
+    const isMobile = /(phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|WebOS|Symbian|Windows Phone)/i.test(userAgent);
+
+    // 执行重定向
+    // 302: 临时重定向 (建议先用 302 测试,稳定后可改为 301)
+    if (isMobile) {
+      return navigateTo('/mobile', { redirectCode: 301 });
+    } else {
+      return navigateTo('/web', { redirectCode: 301 });
+    }
+  }
+});

+ 3 - 9
app/pages/index.vue

@@ -1,13 +1,7 @@
 <template>
+  <div>
+    <!-- 重定向由中间件处理 -->
+  </div>
 </template>
 <script setup>
-import { onMounted } from 'vue'
-onMounted(() => {
-  const isMobile = navigator.userAgent.match(/(phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|WebOS|Symbian|Windows Phone)/)
-  if (isMobile) {
-    window.location.href = '/h5'
-  } else {
-    window.location.href = '/pc'
-  }
-})
 </script>

+ 1 - 1
app/pages/h5/about.vue → app/pages/mobile/about.vue

@@ -6,7 +6,7 @@
 
 <script setup>
 definePageMeta({
-  layout: 'h5'
+  layout: 'mobile'
 })
 </script>
 

+ 2 - 2
app/pages/h5/index.vue → app/pages/mobile/index.vue

@@ -2,14 +2,14 @@
   <div class="h5-index">
     <h1>H5 首页</h1>
     <nav>
-      <NuxtLink to="/h5/about">关于(H5)</NuxtLink>
+      <NuxtLink to="/mobile/about">关于(H5)</NuxtLink>
     </nav>
   </div>
 </template>
 
 <script setup>
 definePageMeta({
-  layout: 'h5'
+  layout: 'mobile'
 })
 </script>
 

+ 1 - 1
app/pages/pc/about.vue → app/pages/web/about.vue

@@ -1,6 +1,6 @@
 <template></template>
 <script setup>
 definePageMeta({
-  layout: 'pc'
+  layout: 'web'
 })
 </script>

+ 1 - 1
app/pages/pc/docs.vue → app/pages/web/docs.vue

@@ -1,6 +1,6 @@
 <template></template>
 <script setup>
 definePageMeta({
-  layout: 'pc'
+  layout: 'web'
 })
 </script>

+ 1 - 4
app/pages/pc/index.vue → app/pages/web/index.vue

@@ -162,7 +162,7 @@
 
 <script setup>
 definePageMeta({
-  layout: 'pc'
+  layout: 'web'
 })
 
 import { ref } from 'vue'
@@ -195,9 +195,6 @@ useHead(() => ({
     { rel: 'icon', href: '/favicon.ico' },
     // { rel: 'preload', as: 'video', href: homeVideo }
   ],
-  htmlAttrs: {
-    lang: 'en'
-  }
 }))
 </script>
 

+ 1 - 1
app/pages/pc/products/boost.vue → app/pages/web/products/boost.vue

@@ -94,7 +94,7 @@
 </template>
 <script setup>
 definePageMeta({
-  layout: 'pc'
+  layout: 'web'  
 })
 useHead(() => ({
   title: '高防服务器',

+ 1 - 1
app/pages/pc/products/dns.vue → app/pages/web/products/dns.vue

@@ -3,7 +3,7 @@
 </template>
 <script setup>
 definePageMeta({
-  layout: 'pc'
+  layout: 'web'
 })
 </script>
 <style lang="scss" scoped></style>

+ 1 - 1
app/pages/pc/products/sdk.vue → app/pages/web/products/sdk.vue

@@ -33,7 +33,7 @@
 
 <script setup>
 definePageMeta({
-  layout: 'pc'
+  layout: 'web'
 })
 import { ref } from 'vue'
 import Introduction from '~/components/products/Introduction.vue'

+ 1 - 1
app/pages/pc/products/web.vue → app/pages/web/products/web.vue

@@ -63,7 +63,7 @@
 </template>
 <script setup>
 definePageMeta({
-  layout: 'pc'
+  layout: 'web'
 })
 useHead(() => ({
   title: 'WEB安全加速',

+ 1 - 1
app/pages/pc/solutions.vue → app/pages/web/solutions.vue

@@ -1,6 +1,6 @@
 <template></template>
 <script setup>
 definePageMeta({
-  layout: 'pc'
+  layout: 'web'
 })
 </script>