Browse Source

```
feat(breadcrumb): 支持将 query 参数添加到面包屑路径中

- 在 Breadcrumb 组件中新增对 route.query 的处理逻辑,
自动拼接查询参数至路径,确保导航准确性。
- 移除了未使用的样式 margin-bottom。

feat(i18n): 补充首页相关国际化翻译字段

- 在 en.js 和 zh-CN.js 中新增 route.home 对应的中英文翻译。
- 调整了部分结构以增强可读性。

feat(router): 新增搜索平台及工作流详情路由配置

- 添加 /search-platform 及其子路由 workflow-detail 页面。
- 修改首页路由结构,增加 redirect 至 /index 子路径。
- 为 my-learning 相关路由使用 Layout 布局组件并调整嵌套路由结构。
- 引入全局前置守卫,支持通过 metaTitle 动态修改页面标题。

feat(home): 更新主页结构与搜索功能交互逻辑

- 移除 container 类名,调整 banner 最小高度。
- 搜索按钮绑定 click 事件,跳转时携带 activePlatform 和 metaTitle 查询参数。
- 引入 vue-i18n 的 useI18n 实例,以便支持多语言切换。

style(app): 为主内容区添加 container 样式类

- 在 el-main 上添加 "container" 类,优化布局结构。

style(styles): 新增 container-height 工具类

- 提供 calc(100vh - 60px) 的高度工具类,便于统一视口适配。
```

zhangningning 1 tuần trước cách đây
mục cha
commit
84dff694fe

+ 1 - 1
src/App.vue

@@ -36,7 +36,7 @@
       </el-header>
       <!-- 固定头部占位 -->
       <div style="height: 60px;"></div>
-      <el-main >
+      <el-main class="container">
         <router-view />
       </el-main>
       

+ 6 - 2
src/components/Breadcrumb.vue

@@ -23,7 +23,7 @@ const route = useRoute()
 const breadcrumbItems = computed(() => {
   const items = []
   const processedPaths = new Set() // 用于跟踪已处理的路径
-  
+  console.log(2222, route)
   // 获取匹配的路由记录
   const matchedRoutes = route.matched.filter(item => item.meta && item.meta.title)
   
@@ -45,6 +45,11 @@ const breadcrumbItems = computed(() => {
         path = path.replace(`:${param}`, route.params[param])
       })
     }
+    //如果路径中有query参数,需要添加到路径中
+    if (route.query) {
+      const queryParams = new URLSearchParams(route.query)
+      path += '?' + queryParams.toString()
+    }
     
     // 避免重复添加相同路径的项目
     if (!processedPaths.has(path)) {
@@ -62,7 +67,6 @@ const breadcrumbItems = computed(() => {
 
 <style scoped>
 .app-breadcrumb {
-  margin-bottom: 20px;
   padding: 10px 0;
 }
 </style>

+ 12 - 0
src/components/Layout.vue

@@ -0,0 +1,12 @@
+<template>
+  <div>
+    <router-view />
+  </div>
+</template>
+
+<script setup>
+</script>
+
+<style scoped lang="scss">
+
+</style>

+ 3 - 0
src/locales/en.js

@@ -27,6 +27,9 @@ export default {
   },
   // 添加路由标题翻译
   route: {
+    home: 'Home',
+
+    
     courseDetail: 'Course Detail',
     myLearning: 'My Learning',
     myLearningCourseDetail: 'My Learning Course Detail'

+ 2 - 0
src/locales/zh-CN.js

@@ -27,6 +27,8 @@ export default {
   },
   // 添加路由标题翻译
   route: {
+    home: '首页',
+
 
 
     courseDetail: '课程详情',

+ 9 - 5
src/pages/Home.vue

@@ -1,5 +1,5 @@
 <template>
-  <div class="home-page container">
+  <div class="home-page">
     <div class="banner flex-center">
       <el-carousel :height="carouselHeight" style="width: 100%;">
         <el-carousel-item>
@@ -49,7 +49,7 @@
             :placeholder="$t('common.qingshuruyaosousuodegongzuoliu')"
             class="search-input"
           />
-          <button class="search-btn gradient">
+          <button class="search-btn gradient" @click.stop.prevent="goSearchPlatform">
             <img :src="searchIcon" alt="" class="icon-search">
             {{$t('common.shousuo')}}
           </button>
@@ -112,6 +112,8 @@ import detailIcon from '@/assets/imgs/detail.png'
 
 import { onMounted,ref } from 'vue'
 import { useRouter } from 'vue-router'
+import { useI18n } from 'vue-i18n' 
+const { t } = useI18n() // 获取t函数// 导入useI18n
 
 
 onMounted(() => {
@@ -135,12 +137,13 @@ const onImageLoad = (event) => {
 
 
 
-const goToCourseDetail = (id,title) => {
+const goSearchPlatform = () => {
   //增加参数名称
   router.push({
-    path: `/course/${id}`,
+    path: `/search-platform`,
     query: {
-      title: title
+      activePlatform: activePlatform.value,
+      metaTitle: activePlatform.value 
     }
   })
 };
@@ -152,6 +155,7 @@ const goToCourseDetail = (id,title) => {
 .banner {
   // margin-top: 140px;
   height: calc(100vh - 60px);
+  min-height: 600px;
   .carousel-image {
     width: 100%;
     height: auto;

+ 41 - 0
src/pages/SearchPlatform.vue

@@ -0,0 +1,41 @@
+<template>
+  <div class="search-platform container-height">
+    <div v-if="!isChildRoute">
+      {{currentPath}}
+      <Breadcrumb />
+      <h1 @click="goWorkflowDetail">{{activePlatform}}</h1>
+    </div>
+    <router-view />
+  </div>
+</template>
+
+<script setup>
+  import { useRouter, useRoute } from 'vue-router'
+  const router = useRouter()
+  const route = useRoute()
+  import { ref, computed } from 'vue'
+  //获取参数
+  const query = router.currentRoute.value.query
+  const activePlatform = ref(query.activePlatform || '')
+  //获取当前路由路径
+  // const currentPath = ref(router.currentRoute.value.path)
+  const isChildRoute = computed(() => {
+    return route.matched.length > 1
+  })
+  const goWorkflowDetail = () => {
+  //增加参数名称
+  router.push({
+    path: `/search-platform/workflow-detail`,
+    query: {
+      id:2,
+      metaTitle: 'WorkflowDetail'
+    }
+  })
+};
+</script>
+
+<style scoped lang="scss">
+.search-platform {
+  
+}
+</style>

+ 21 - 0
src/pages/WorkflowDetail.vue

@@ -0,0 +1,21 @@
+<template>
+  <div class="workflow-detail container-height">
+    <Breadcrumb />
+    <h1>{{id}}</h1>
+  </div>
+</template>
+
+<script setup>
+  import { useRouter } from 'vue-router'
+  const router = useRouter()
+  import { ref } from 'vue'
+  //获取参数
+  const query = router.currentRoute.value.query
+  const id = ref(query.id || '')
+</script>
+
+<style scoped lang="scss">
+.workflow-detail {
+  
+}
+</style>

+ 53 - 3
src/router/index.js

@@ -3,14 +3,50 @@ import Home from '../pages/Home.vue'
 import CourseDetail from '../pages/CourseDetail.vue'
 import MyLearning from '../pages/MyLearning.vue'
 import MyLearningHome from '../pages/MyLearningHome.vue'
+import Layout from '@/components/Layout.vue'
 
 const routes = [
   {
     path: '/',
     name: 'Home',
     component: Home,
-    meta: { title: '首页' }
+    redirect: '/index',
+    meta: { title: 'route.home' },
+    children: [
+      {
+        path: 'index',
+        name: 'Index',
+        component: Home,
+        meta: { title: 'route.home' }
+      }
+    ]
+  },
+  {
+    path: '/search-platform',
+    name: 'SearchPlatformHome',
+    component:() => import('@/pages/SearchPlatform.vue'),
+    meta: { title: 'SearchPlatformHome' },
+    children: [
+      // {
+      //   path: 'search-platform',
+      //   name: 'SearchPlatform',
+      //   component: () => import('@/pages/SearchPlatform.vue'),
+      //   meta: { title: '' }
+      // },
+      {
+        path: 'workflow-detail',
+        name: 'WorkflowDetail',
+        component: () => import('@/pages/WorkflowDetail.vue'),
+        meta: { title: '' }
+      }
+    ]
   },
+  // {
+  //   path: '/workflow-detail',
+  //   name: 'WorkflowDetail',
+  //   component: () => import('@/pages/WorkflowDetail.vue'),
+  //   meta: { title: '' }
+  // },
   {
     path: '/course/:id',
     name: 'CourseDetail',
@@ -20,7 +56,7 @@ const routes = [
   {
     path: '/my-learning',
     name: 'MyLearningHome',
-    component: MyLearningHome,
+    component: Layout,
     meta: { title: 'route.myLearning' },
     children: [
       {
@@ -30,7 +66,7 @@ const routes = [
         meta: { title: 'route.myLearning' }
       },
       {
-        path: '/my-learning/course/:id',
+        path: 'course/:id',
         name: 'MyLearningCourseDetail',
         component: CourseDetail,
         meta: { title: 'route.myLearningCourseDetail' }
@@ -43,5 +79,19 @@ const router = createRouter({
   history: createWebHistory(import.meta.env.BASE_URL),
   routes
 })
+// 全局路由守卫
+router.beforeEach((to, from, next) => {
+  console.log(33333333333, to)
+  // 设置页面标题
+  // document.title = to.meta.title || 'Boom Ai'
+ 
+  // 动态设置路由的meta.title
+  const lastRoute = to.matched?.[to.matched.length - 1]
+  if (lastRoute && to.query.metaTitle) {
+    to.meta.title =  to.query.metaTitle;
+    lastRoute.meta.title = to.query.metaTitle;
+  }
+  next()
+})
 
 export default router

+ 3 - 0
src/styles/index.scss

@@ -19,6 +19,9 @@ $danger-color: #e63946; // 危险色(价格、警告等)
 		background-color: #ffffff;
 	}
 }
+.container-height {
+  height: calc(100vh - 60px);
+}
 
 
 // 2. 全局重置样式(统一浏览器默认样式)