chenlei před 1 rokem
rodič
revize
261c7ff813
74 změnil soubory, kde provedl 981 přidání a 12 odebrání
  1. 365 0
      public/birds/birdsData.json
  2. binární
      public/birds/niaolei/1(1).jpg
  3. binární
      public/birds/niaolei/1(2).jpg
  4. binární
      public/birds/niaolei/1(3).jpg
  5. binární
      public/birds/niaolei/1(4).jpg
  6. binární
      public/birds/niaolei/1(5).jpg
  7. binární
      public/birds/niaolei/1(6).jpg
  8. binární
      public/birds/niaolei/1(7).jpg
  9. binární
      public/birds/niaolei/1(8).jpg
  10. binární
      public/birds/niaolei/2(10).jpg
  11. binární
      public/birds/niaolei/2(11).jpg
  12. binární
      public/birds/niaolei/2(12).jpg
  13. binární
      public/birds/niaolei/2(13).jpg
  14. binární
      public/birds/niaolei/2(1).JPG
  15. binární
      public/birds/niaolei/2(2).jpg
  16. binární
      public/birds/niaolei/2(3).jpg
  17. binární
      public/birds/niaolei/2(4).jpg
  18. binární
      public/birds/niaolei/2(5).jpg
  19. binární
      public/birds/niaolei/2(6).jpg
  20. binární
      public/birds/niaolei/2(7).jpg
  21. binární
      public/birds/niaolei/2(8).jpg
  22. binární
      public/birds/niaolei/2(9).jpg
  23. binární
      public/birds/niaolei/3(1).jpg
  24. binární
      public/birds/niaolei/3(2).jpg
  25. binární
      public/birds/niaolei/3(3).jpg
  26. binární
      public/birds/niaolei/3(4).jpg
  27. binární
      public/birds/niaolei/3(5).jpg
  28. binární
      public/birds/niaolei/4(10).jpg
  29. binární
      public/birds/niaolei/4(1).jpg
  30. binární
      public/birds/niaolei/4(2).jpg
  31. binární
      public/birds/niaolei/4(3).jpg
  32. binární
      public/birds/niaolei/4(4).jpg
  33. binární
      public/birds/niaolei/4(5).jpg
  34. binární
      public/birds/niaolei/4(6).jpg
  35. binární
      public/birds/niaolei/4(7).jpg
  36. binární
      public/birds/niaolei/4(8).jpg
  37. binární
      public/birds/niaolei/4(9).jpg
  38. binární
      public/birds/niaolei/5(1).jpg
  39. binární
      public/birds/niaolei/5(2).jpg
  40. binární
      public/birds/niaolei/icon_luqin_bird@2x-min.png
  41. binární
      public/birds/niaolei/icon_mengqin_bird@2x-min.png
  42. binární
      public/birds/niaolei/icon_mingqin_bird@2x-min.png
  43. binární
      public/birds/niaolei/icon_sheqin_bird@2x-min.png
  44. binární
      public/birds/niaolei/icon_youqin_bird@2x-min.png
  45. 1 1
      public/tongyan/tongyanData.json
  46. binární
      src/assets/images/birds/bg_detail_bird@2x-min.png
  47. binární
      src/assets/images/birds/bg_luqin_bird2@2x-min.png
  48. binární
      src/assets/images/birds/bg_luqin_bird@2x-min.png
  49. binární
      src/assets/images/birds/bg_mengqin_bird2@2x-min.png
  50. binární
      src/assets/images/birds/bg_mengqin_bird@2x-min.png
  51. binární
      src/assets/images/birds/bg_mingqin_bird2@2x-min.png
  52. binární
      src/assets/images/birds/bg_mingqin_bird@2x-min.png
  53. binární
      src/assets/images/birds/bg_pre&end_bird2@2x-min.png
  54. binární
      src/assets/images/birds/bg_pre&end_bird@2x-min.png
  55. binární
      src/assets/images/birds/bg_sheqin_bird2@2x-min.png
  56. binární
      src/assets/images/birds/bg_sheqin_bird@2x-min.png
  57. binární
      src/assets/images/birds/bg_youqin_bird2@2x-min.png
  58. binární
      src/assets/images/birds/bg_youqin_bird@2x-min.png
  59. binární
      src/assets/images/birds/btn_select_bird@2x.png
  60. binární
      src/assets/images/birds/icon_back_bird@2x-min.png
  61. binární
      src/assets/images/birds/icon_end_bird@2x-min.png
  62. binární
      src/assets/images/birds/icon_pre_bird@2x-min.png
  63. binární
      src/assets/images/birds/img_bird@2x-min.png
  64. 5 1
      src/birds.vue
  65. 8 8
      src/router/birds.ts
  66. 15 0
      src/stores/birds.ts
  67. 248 0
      src/views/Birds/index.scss
  68. 98 0
      src/views/Birds/index.vue
  69. 84 0
      src/views/BirdsDetail/index.scss
  70. 81 0
      src/views/BirdsDetail/index.vue
  71. 32 0
      src/views/BirdsHome/index.scss
  72. 32 0
      src/views/BirdsHome/index.vue
  73. 10 1
      tsconfig.app.json
  74. 2 1
      vite.config.ts

Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 365 - 0
public/birds/birdsData.json


binární
public/birds/niaolei/1(1).jpg


binární
public/birds/niaolei/1(2).jpg


binární
public/birds/niaolei/1(3).jpg


binární
public/birds/niaolei/1(4).jpg


binární
public/birds/niaolei/1(5).jpg


binární
public/birds/niaolei/1(6).jpg


binární
public/birds/niaolei/1(7).jpg


binární
public/birds/niaolei/1(8).jpg


binární
public/birds/niaolei/2(10).jpg


binární
public/birds/niaolei/2(11).jpg


binární
public/birds/niaolei/2(12).jpg


binární
public/birds/niaolei/2(13).jpg


binární
public/birds/niaolei/2(1).JPG


binární
public/birds/niaolei/2(2).jpg


binární
public/birds/niaolei/2(3).jpg


binární
public/birds/niaolei/2(4).jpg


binární
public/birds/niaolei/2(5).jpg


binární
public/birds/niaolei/2(6).jpg


binární
public/birds/niaolei/2(7).jpg


binární
public/birds/niaolei/2(8).jpg


binární
public/birds/niaolei/2(9).jpg


binární
public/birds/niaolei/3(1).jpg


binární
public/birds/niaolei/3(2).jpg


binární
public/birds/niaolei/3(3).jpg


binární
public/birds/niaolei/3(4).jpg


binární
public/birds/niaolei/3(5).jpg


binární
public/birds/niaolei/4(10).jpg


binární
public/birds/niaolei/4(1).jpg


binární
public/birds/niaolei/4(2).jpg


binární
public/birds/niaolei/4(3).jpg


binární
public/birds/niaolei/4(4).jpg


binární
public/birds/niaolei/4(5).jpg


binární
public/birds/niaolei/4(6).jpg


binární
public/birds/niaolei/4(7).jpg


binární
public/birds/niaolei/4(8).jpg


binární
public/birds/niaolei/4(9).jpg


binární
public/birds/niaolei/5(1).jpg


binární
public/birds/niaolei/5(2).jpg


binární
public/birds/niaolei/icon_luqin_bird@2x-min.png


binární
public/birds/niaolei/icon_mengqin_bird@2x-min.png


binární
public/birds/niaolei/icon_mingqin_bird@2x-min.png


binární
public/birds/niaolei/icon_sheqin_bird@2x-min.png


binární
public/birds/niaolei/icon_youqin_bird@2x-min.png


Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 1 - 1
public/tongyan/tongyanData.json


binární
src/assets/images/birds/bg_detail_bird@2x-min.png


binární
src/assets/images/birds/bg_luqin_bird2@2x-min.png


binární
src/assets/images/birds/bg_luqin_bird@2x-min.png


binární
src/assets/images/birds/bg_mengqin_bird2@2x-min.png


binární
src/assets/images/birds/bg_mengqin_bird@2x-min.png


binární
src/assets/images/birds/bg_mingqin_bird2@2x-min.png


binární
src/assets/images/birds/bg_mingqin_bird@2x-min.png


binární
src/assets/images/birds/bg_pre&end_bird2@2x-min.png


binární
src/assets/images/birds/bg_pre&end_bird@2x-min.png


binární
src/assets/images/birds/bg_sheqin_bird2@2x-min.png


binární
src/assets/images/birds/bg_sheqin_bird@2x-min.png


binární
src/assets/images/birds/bg_youqin_bird2@2x-min.png


binární
src/assets/images/birds/bg_youqin_bird@2x-min.png


binární
src/assets/images/birds/btn_select_bird@2x.png


binární
src/assets/images/birds/icon_back_bird@2x-min.png


binární
src/assets/images/birds/icon_end_bird@2x-min.png


binární
src/assets/images/birds/icon_pre_bird@2x-min.png


binární
src/assets/images/birds/img_bird@2x-min.png


+ 5 - 1
src/birds.vue

@@ -33,7 +33,11 @@ const back = () => {
     magnetic="x"
     @click="back"
   >
-    <img draggable="false" class="back-icon" src="@/assets/images/tongyan/icon_back@2x-min.png" />
+    <img
+      draggable="false"
+      class="back-icon"
+      src="@/assets/images/birds/icon_back_bird@2x-min.png"
+    />
   </van-floating-bubble>
 </template>
 

+ 8 - 8
src/router/birds.ts

@@ -1,7 +1,7 @@
 import { createRouter, createWebHashHistory } from 'vue-router'
-import BookFair from '../views/BookFair/index.vue'
-import BookFairDetail from '../views/BookFairDetail/index.vue'
-import BookFairHome from '../views/BookFairHome/index.vue'
+import List from '../views/Birds/index.vue'
+import Detail from '../views/BirdsDetail/index.vue'
+import Home from '../views/BirdsHome/index.vue'
 
 const router = createRouter({
   history: createWebHashHistory(import.meta.env.BASE_URL),
@@ -9,17 +9,17 @@ const router = createRouter({
     {
       path: '/',
       name: 'home',
-      component: BookFairHome
+      component: Home
     },
     {
       path: '/list/:id/:secondId',
-      name: 'book-fair',
-      component: BookFair
+      name: 'birds',
+      component: List
     },
     {
       path: '/detail/:id/:sid/:detailId',
-      name: 'book-fair-detail',
-      component: BookFairDetail
+      name: 'birds-detail',
+      component: Detail
     }
   ]
 })

+ 15 - 0
src/stores/birds.ts

@@ -0,0 +1,15 @@
+import { ref } from 'vue'
+import { defineStore } from 'pinia'
+import type { IData } from './types'
+
+export const useBirdsStore = defineStore('birds', () => {
+  const data = ref<IData[]>([])
+
+  fetch('./birdsData.json')
+    .then((res) => res.json())
+    .then((res) => {
+      data.value = res
+    })
+
+  return { data }
+})

+ 248 - 0
src/views/Birds/index.scss

@@ -0,0 +1,248 @@
+.birds {
+  --van-tab-text-color: #000000;
+  --van-tab-active-text-color: #52c1ff;
+  --van-tab-font-size: 34px;
+  --van-tabs-line-height: 112px;
+  --van-padding-sm: 40px;
+  --van-padding-xs: 38px;
+  --van-tabs-nav-background: #fffdf5;
+
+  &__bg {
+    position: absolute;
+    top: 0;
+    left: 0;
+    right: 0;
+    bottom: 0;
+    z-index: -1;
+
+    &.b0 {
+      &::after {
+        content: '';
+        position: absolute;
+        top: 0;
+        right: 0;
+        width: 252px;
+        height: 494px;
+        background: url('@/assets/images/birds/bg_pre&end_bird@2x-min.png') no-repeat center /
+          contain;
+      }
+      &::before {
+        content: '';
+        position: absolute;
+        left: 0;
+        bottom: 0;
+        width: 186px;
+        height: 386px;
+        background: url('@/assets/images/birds/bg_pre&end_bird2@2x-min.png') no-repeat center /
+          contain;
+      }
+    }
+    &.b1 {
+      &::after {
+        content: '';
+        position: absolute;
+        top: 20px;
+        right: 0;
+        width: 154px;
+        height: 370px;
+        background: url('@/assets/images/birds/bg_youqin_bird@2x-min.png') no-repeat center /
+          contain;
+      }
+      &::before {
+        content: '';
+        position: absolute;
+        left: 0;
+        bottom: 200px;
+        width: 212px;
+        height: 430px;
+        background: url('@/assets/images/birds/bg_youqin_bird2@2x-min.png') no-repeat center /
+          contain;
+      }
+    }
+    &.b2 {
+      &::after {
+        content: '';
+        position: absolute;
+        top: 106px;
+        right: 0;
+        width: 172px;
+        height: 466px;
+        background: url('@/assets/images/birds/bg_sheqin_bird@2x-min.png') no-repeat center /
+          contain;
+      }
+      &::before {
+        content: '';
+        position: absolute;
+        left: 0;
+        bottom: 0;
+        width: 208px;
+        height: 454px;
+        background: url('@/assets/images/birds/bg_sheqin_bird2@2x-min.png') no-repeat center /
+          contain;
+      }
+    }
+    &.b3 {
+      &::after {
+        content: '';
+        position: absolute;
+        top: 60px;
+        right: 0;
+        width: 150px;
+        height: 414px;
+        background: url('@/assets/images/birds/bg_luqin_bird@2x-min.png') no-repeat center / contain;
+      }
+      &::before {
+        content: '';
+        position: absolute;
+        left: 0;
+        bottom: 38px;
+        width: 204px;
+        height: 422px;
+        background: url('@/assets/images/birds/bg_luqin_bird2@2x-min.png') no-repeat center /
+          contain;
+      }
+    }
+    &.b4 {
+      &::after {
+        content: '';
+        position: absolute;
+        top: 100px;
+        right: 0;
+        width: 112px;
+        height: 208px;
+        background: url('@/assets/images/birds/bg_mingqin_bird@2x-min.png') no-repeat center /
+          contain;
+      }
+      &::before {
+        content: '';
+        position: absolute;
+        left: 0;
+        bottom: 0;
+        width: 278px;
+        height: 562px;
+        background: url('@/assets/images/birds/bg_mingqin_bird2@2x-min.png') no-repeat center /
+          contain;
+      }
+    }
+    &.b5 {
+      &::after {
+        content: '';
+        position: absolute;
+        top: 90px;
+        right: 0;
+        width: 178px;
+        height: 318px;
+        background: url('@/assets/images/birds/bg_mengqin_bird@2x-min.png') no-repeat center /
+          contain;
+      }
+      &::before {
+        content: '';
+        position: absolute;
+        left: 0;
+        bottom: 180px;
+        width: 336px;
+        height: 382px;
+        background: url('@/assets/images/birds/bg_mengqin_bird2@2x-min.png') no-repeat center /
+          contain;
+      }
+    }
+  }
+  &__title {
+    display: block;
+    width: 176px;
+    margin: 0 auto;
+    padding: 60px 0 24px;
+  }
+  &__preface {
+    color: #576030;
+    text-indent: 2em;
+    padding: 0 60px 140px;
+    line-height: 50px;
+  }
+  &__info {
+    position: relative;
+    padding: 55px;
+    margin-bottom: 20px;
+    color: #434142;
+    line-height: 50px;
+    text-indent: 2em;
+  }
+  &-cards {
+    padding-bottom: 20px;
+  }
+  &-card {
+    position: relative;
+    display: flex;
+    flex-direction: column;
+    margin-bottom: 20px;
+    padding: 46px 46px 0;
+    width: 680px;
+    height: 560px;
+    box-sizing: border-box;
+    background: url('@/assets/images/birds/img_bird@2x-min.png') no-repeat center / 100% 100%;
+
+    &__title {
+      position: absolute;
+      bottom: 50px;
+      left: 50%;
+      transform: translateX(-50%);
+      font-size: 36px;
+    }
+    &__subtitle {
+      position: absolute;
+      bottom: 24px;
+      left: 50%;
+      transform: translateX(-50%);
+      font-size: 20px;
+      opacity: 0.5;
+    }
+    &__img {
+      width: 100%;
+      height: 400px;
+    }
+    &:last-child {
+      margin-bottom: 0;
+    }
+  }
+
+  &__bg {
+    position: absolute;
+    top: 0;
+    left: 0;
+    right: 0;
+    bottom: 0;
+    z-index: -1;
+  }
+
+  .van-tab {
+    z-index: 2;
+
+    &__panel {
+      position: relative;
+      padding: 0 30px;
+
+      &__last-child {
+        padding-bottom: 130px;
+      }
+    }
+  }
+  .van-tabs {
+    &__line {
+      bottom: 46px;
+      width: 114px;
+      height: 72px;
+      background: none;
+      border: none;
+
+      &::after {
+        content: '';
+        position: absolute;
+        top: 0;
+        left: 12px;
+        width: 100%;
+        height: 100%;
+        background: url('@/assets/images/birds/btn_select_bird@2x.png') no-repeat center / contain;
+      }
+    }
+  }
+}

+ 98 - 0
src/views/Birds/index.vue

@@ -0,0 +1,98 @@
+<template>
+  <van-tabs v-if="model" ref="tabsRef" v-model:active="active" scrollspy sticky class="birds">
+    <van-tab title="前言" :name="0">
+      <img class="birds__title" src="@/assets/images/birds/icon_pre_bird@2x-min.png" />
+      <div class="birds__preface">
+        <div v-html="model.preface" />
+      </div>
+
+      <div class="birds__bg b0" :style="{ background: '#FFFDF5' }" />
+    </van-tab>
+
+    <van-tab v-for="item in model.list" :title="item.label" :key="item.id" :name="item.id">
+      <img class="birds__title" :src="item.labelImg" />
+
+      <div v-if="item.info" class="birds__info">
+        <p :style="{ color: item.infoColor }" v-html="item.info" />
+      </div>
+
+      <div class="birds-cards">
+        <div
+          v-for="subItem in item.list"
+          :key="subItem.id"
+          class="birds-card"
+          @click="handleCard(item.id, subItem.id)"
+        >
+          <div class="birds-card__img">
+            <van-image lazy-load fit="cover" width="100%" height="100%" :src="subItem.imgs[0]" />
+          </div>
+          <p class="birds-card__title limit-line">{{ subItem.title }}</p>
+          <p class="birds-card__subtitle limit-line">{{ subItem.author }}</p>
+        </div>
+      </div>
+
+      <div
+        v-if="item.bgColor"
+        :class="['birds__bg', `b${item.id}`]"
+        :style="{ background: item.bgColor }"
+      />
+    </van-tab>
+
+    <van-tab title="结语">
+      <img class="birds__title" src="@/assets/images/birds/icon_end_bird@2x-min.png" />
+      <div class="birds__preface">
+        <div v-html="model.epilogue" :style="{ color: '#533D23' }" />
+      </div>
+
+      <div class="birds__bg b0" :style="{ background: '#FFFDF5' }" />
+    </van-tab>
+  </van-tabs>
+
+  <div v-if="loading" class="loading-page">
+    <van-loading color="#52c1ff" :size="48" />
+  </div>
+</template>
+
+<script lang="ts">
+export default {
+  name: 'birds'
+}
+</script>
+
+<script lang="ts" setup>
+import { ref, onMounted, computed } from 'vue'
+import { useRoute, useRouter } from 'vue-router'
+import type { TabsInstance } from 'vant'
+import { useBirdsStore } from '@/stores/birds'
+
+const route = useRoute()
+const router = useRouter()
+const active = ref(0)
+const loading = ref(true)
+const birds = useBirdsStore()
+const tabsRef = ref<TabsInstance>()
+const model = computed(() => birds.data.find((item) => item.id === Number(route.params.id)))
+
+onMounted(() => {
+  setTimeout(() => {
+    tabsRef.value?.scrollTo(Number(route.params.secondId))
+
+    loading.value = false
+  }, 500)
+})
+
+const handleCard = (pId: number, id: number) => {
+  router.push({
+    name: 'birds-detail',
+    params: {
+      id: route.params.id,
+      sid: pId,
+      detailId: id
+    }
+  })
+}
+</script>
+
+<style lang="scss">
+@import './index.scss';
+</style>

+ 84 - 0
src/views/BirdsDetail/index.scss

@@ -0,0 +1,84 @@
+@import url('/node_modules/vant/es/image-preview/index.css');
+
+.birds-detail {
+  display: flex;
+  flex-direction: column;
+  min-height: 100vh;
+
+  &__indicator {
+    position: absolute;
+    left: 0;
+    right: 0;
+    bottom: 44px;
+    text-align: center;
+    color: #fff;
+  }
+
+  &-swipe {
+    position: relative;
+
+    &__lf-icon,
+    &__rg-icon {
+      position: absolute;
+      top: 50%;
+      width: 66px;
+      transform: translateY(-50%);
+      cursor: pointer;
+    }
+    &__lf-icon {
+      left: 0;
+    }
+    &__rg-icon {
+      right: 0;
+    }
+  }
+
+  &-main {
+    position: relative;
+    flex: 1;
+    border-top-left-radius: 18px;
+    border-top-right-radius: 18px;
+    margin-top: -18px;
+    padding: 50px 50px 80px;
+    color: #294363;
+    background: #fffef9;
+    overflow: hidden;
+
+    &::after {
+      content: '';
+      position: absolute;
+      left: -50px;
+      bottom: -60px;
+      width: 186px;
+      height: 386px;
+      background: url('@/assets/images/birds/bg_detail_bird@2x-min.png') no-repeat center / contain;
+    }
+    &__title {
+      margin: 0 auto;
+      text-align: center;
+      max-width: 480px;
+      font-size: 40px;
+      line-height: 46px;
+      font-family: KaiTi-Regular, KaiTi;
+    }
+    &__subtitle {
+      margin-top: 12px;
+      font-size: 24px;
+      opacity: 0.5;
+      text-align: center;
+    }
+    &__author {
+      padding-bottom: 24px;
+      margin-bottom: 28px;
+      font-size: 24px;
+      opacity: 0.5;
+      text-align: center;
+      border-bottom: 1px dashed rgba(41, 67, 99, 0.5);
+    }
+    &__info {
+      opacity: 0.5;
+      line-height: 32px;
+      text-indent: 2em;
+    }
+  }
+}

+ 81 - 0
src/views/BirdsDetail/index.vue

@@ -0,0 +1,81 @@
+<template>
+  <div v-if="detail" class="birds-detail">
+    <div class="birds-detail-swipe">
+      <van-swipe ref="swipeRef" height="420">
+        <van-swipe-item v-for="(img, index) in detail.imgs" :key="img">
+          <van-image
+            lazy-load
+            fit="cover"
+            width="100%"
+            height="100%"
+            :src="img"
+            @click="handlePreview(index)"
+          />
+        </van-swipe-item>
+        <template #indicator="{ active, total }">
+          <div class="birds-detail__indicator">{{ active + 1 }}/{{ total }}</div>
+        </template>
+      </van-swipe>
+      <img
+        class="birds-detail-swipe__lf-icon"
+        src="@/assets/images/btn_left_beita@2x.png"
+        @click="handleSwipe('left')"
+      />
+      <img
+        class="birds-detail-swipe__rg-icon"
+        src="@/assets/images/btn_right_beita@2x.png"
+        @click="handleSwipe('right')"
+      />
+    </div>
+
+    <div class="birds-detail-main">
+      <p class="birds-detail-main__title">{{ detail.title }}</p>
+      <p class="birds-detail-main__subtitle">{{ detail.subtitle }}</p>
+      <p class="birds-detail-main__author">{{ detail.author }}</p>
+      <p class="birds-detail-main__info" v-html="detail.content" />
+    </div>
+  </div>
+
+  <van-image-preview
+    v-model:show="showPreview"
+    :images="detail?.imgs"
+    @change="(idx) => (previewIndex = idx)"
+  >
+    <template v-slot:index>第{{ previewIndex + 1 }}页</template>
+  </van-image-preview>
+</template>
+
+<script lang="ts" setup>
+import { ref, computed } from 'vue'
+import { useRoute } from 'vue-router'
+import { type SwipeInstance } from 'vant'
+import { useBirdsStore } from '@/stores/birds'
+
+const route = useRoute()
+const birds = useBirdsStore()
+const swipeRef = ref<SwipeInstance>()
+const showPreview = ref(false)
+const previewIndex = ref(0)
+const model = computed(() => birds.data.find((item) => item.id === Number(route.params.id)))
+const list = computed(() => model.value?.list.find((item) => item.id === Number(route.params.sid)))
+const detail = computed(
+  () => list.value?.list.find((item) => item.id === Number(route.params.detailId))
+)
+
+const handleSwipe = (type: 'left' | 'right') => {
+  if (type === 'left') {
+    swipeRef.value?.prev()
+  } else {
+    swipeRef.value?.next()
+  }
+}
+
+const handlePreview = (idx: number) => {
+  previewIndex.value = idx
+  showPreview.value = true
+}
+</script>
+
+<style lang="scss" scoped>
+@import url('./index.scss');
+</style>

+ 32 - 0
src/views/BirdsHome/index.scss

@@ -0,0 +1,32 @@
+.home {
+  width: 100vw;
+  height: 100vh;
+  overflow: hidden;
+  background: url('@/assets/images/birds/bg_bird@2x-min.jpg') no-repeat center bottom / cover;
+
+  &__start {
+    position: absolute;
+    right: 38px;
+    bottom: 78px;
+    width: 126px;
+    z-index: 1;
+  }
+  &__img1 {
+    position: absolute;
+    left: 50px;
+    bottom: 78px;
+    width: 404px;
+  }
+  &__img2 {
+    position: absolute;
+    right: 36px;
+    top: 40px;
+    width: 192px;
+  }
+  &__img3 {
+    position: absolute;
+    left: 50px;
+    top: 46px;
+    width: 130px;
+  }
+}

+ 32 - 0
src/views/BirdsHome/index.vue

@@ -0,0 +1,32 @@
+<template>
+  <div class="home">
+    <img draggable="false" class="home__img1" :src="Image1" />
+    <img draggable="false" class="home__img2" :src="Image2" />
+    <img draggable="false" class="home__img3" :src="Image3" />
+    <img draggable="false" class="home__start" :src="ButtonIcon" @click="handleStart" />
+  </div>
+</template>
+
+<script lang="ts" setup>
+import { useRouter } from 'vue-router'
+import ButtonIcon from '@/assets/images/birds/btn_start_bird@2x-min.png'
+import Image1 from '@/assets/images/birds/time@2x-min.png'
+import Image2 from '@/assets/images/birds/title_CN@2x-min.png'
+import Image3 from '@/assets/images/birds/title_EN@2x-min.png'
+
+const router = useRouter()
+
+const handleStart = () => {
+  router.push({
+    name: 'birds',
+    params: {
+      id: 1,
+      secondId: 0
+    }
+  })
+}
+</script>
+
+<style lang="scss" scoped>
+@import './index.scss';
+</style>

+ 10 - 1
tsconfig.app.json

@@ -1,6 +1,15 @@
 {
   "extends": "@vue/tsconfig/tsconfig.dom.json",
-  "include": ["env.d.ts", "src/**/*", "src/**/*.vue", "src/**/*.json", "monument/main.ts"],
+  "include": [
+    "env.d.ts",
+    "src/**/*",
+    "src/**/*.vue",
+    "src/**/*.json",
+    "monument/main.ts",
+    "tongyan/main.ts",
+    "bookFair/main.ts",
+    "birds/main.ts"
+  ],
   "exclude": ["src/**/__tests__/*"],
   "compilerOptions": {
     "composite": true,

+ 2 - 1
vite.config.ts

@@ -27,7 +27,8 @@ export default defineConfig({
       input: {
         monument: resolve(__dirname, 'monument/index.html'),
         bookFair: resolve(__dirname, 'book-fair/index.html'),
-        tongyan: resolve(__dirname, 'tongyan/index.html')
+        tongyan: resolve(__dirname, 'tongyan/index.html'),
+        birds: resolve(__dirname, 'birds/index.html')
       },
       output: {
         assetFileNames: (assetInfo) => {