chenlei 1 rok temu
rodzic
commit
84fd22882f
98 zmienionych plików z 1395 dodań i 153 usunięć
  1. 1 0
      components.d.ts
  2. 1 0
      src/assets/svgs/more.svg
  3. 6 0
      src/components/Breadcrumb/constants.ts
  4. 2 5
      src/components/Breadcrumb/index.vue
  5. 4 4
      src/components/Layout/data.ts
  6. 35 8
      src/components/Layout/index.vue
  7. 90 0
      src/components/PageNav/index.vue
  8. 7 0
      src/components/PageNav/types.ts
  9. 46 0
      src/router/index.ts
  10. 56 0
      src/views/About/components/Connections.vue
  11. 51 0
      src/views/About/components/Contact.vue
  12. 65 0
      src/views/About/components/Director.vue
  13. 106 0
      src/views/About/components/History.vue
  14. BIN
      src/views/About/images/a6.jpg
  15. BIN
      src/views/About/images/au2.jpg
  16. BIN
      src/views/About/images/au3.png
  17. BIN
      src/views/About/images/au6.gif
  18. BIN
      src/views/About/images/banner.jpg
  19. BIN
      src/views/About/images/his/1.png
  20. BIN
      src/views/About/images/his/2.png
  21. BIN
      src/views/About/images/his/3.png
  22. BIN
      src/views/About/images/his/4.png
  23. BIN
      src/views/About/images/his/back.png
  24. BIN
      src/views/About/images/link/1.jpg
  25. BIN
      src/views/About/images/link/10.jpg
  26. BIN
      src/views/About/images/link/11.jpg
  27. BIN
      src/views/About/images/link/12.jpg
  28. BIN
      src/views/About/images/link/13.jpg
  29. BIN
      src/views/About/images/link/14.jpg
  30. BIN
      src/views/About/images/link/15.jpg
  31. BIN
      src/views/About/images/link/16.jpg
  32. BIN
      src/views/About/images/link/17.jpg
  33. BIN
      src/views/About/images/link/18.jpg
  34. BIN
      src/views/About/images/link/19.jpg
  35. BIN
      src/views/About/images/link/2.jpg
  36. BIN
      src/views/About/images/link/20.jpg
  37. BIN
      src/views/About/images/link/3.jpg
  38. BIN
      src/views/About/images/link/4.jpg
  39. BIN
      src/views/About/images/link/5.jpg
  40. BIN
      src/views/About/images/link/6.jpg
  41. BIN
      src/views/About/images/link/7.jpg
  42. BIN
      src/views/About/images/link/8.jpg
  43. BIN
      src/views/About/images/link/9.jpg
  44. BIN
      src/views/About/images/youxiang.jpg
  45. 9 0
      src/views/About/index.scss
  46. 34 0
      src/views/About/index.vue
  47. 8 0
      src/views/Collections/components/DetailDialog/index.scss
  48. 46 7
      src/views/Collections/components/DetailDialog/index.vue
  49. BIN
      src/views/Collections/images/mark.png
  50. 6 5
      src/views/Exhibitions/constants.ts
  51. 0 34
      src/views/Exhibitions/index.scss
  52. 2 29
      src/views/Exhibitions/index.vue
  53. 67 0
      src/views/JoinSupport/Give/detail.vue
  54. 70 0
      src/views/JoinSupport/Give/index.scss
  55. 52 0
      src/views/JoinSupport/Give/index.vue
  56. 20 0
      src/views/JoinSupport/Volunteer/detail.vue
  57. 99 0
      src/views/JoinSupport/Volunteer/index.scss
  58. 29 0
      src/views/JoinSupport/Volunteer/index.vue
  59. 32 0
      src/views/JoinSupport/constants.ts
  60. BIN
      src/views/JoinSupport/images/banner.jpg
  61. BIN
      src/views/JoinSupport/images/bg3.gif
  62. BIN
      src/views/JoinSupport/images/bg4.gif
  63. BIN
      src/views/JoinSupport/images/dianhua.png
  64. BIN
      src/views/JoinSupport/images/n1.png
  65. BIN
      src/views/JoinSupport/images/n2.png
  66. BIN
      src/views/JoinSupport/images/v1.jpg
  67. BIN
      src/views/JoinSupport/images/v2.jpg
  68. BIN
      src/views/JoinSupport/images/v3.jpg
  69. BIN
      src/views/JoinSupport/images/v4.jpg
  70. BIN
      src/views/JoinSupport/images/wg1.gif
  71. BIN
      src/views/JoinSupport/images/wg1.jpg
  72. BIN
      src/views/JoinSupport/images/wg2.gif
  73. BIN
      src/views/JoinSupport/images/wg2.jpg
  74. BIN
      src/views/JoinSupport/images/y1.png
  75. BIN
      src/views/JoinSupport/images/y1Ac.png
  76. BIN
      src/views/JoinSupport/images/y2.png
  77. BIN
      src/views/JoinSupport/images/y2Ac.png
  78. BIN
      src/views/JoinSupport/images/y3.png
  79. BIN
      src/views/JoinSupport/images/y3Ac.png
  80. BIN
      src/views/JoinSupport/images/y4.png
  81. BIN
      src/views/JoinSupport/images/y4Ac.png
  82. 19 0
      src/views/JoinSupport/index.scss
  83. 72 0
      src/views/JoinSupport/index.vue
  84. 62 0
      src/views/Publications/Catalogues/index.scss
  85. 25 1
      src/views/Publications/Catalogues/index.vue
  86. 8 0
      src/views/Publications/Detail/index.scss
  87. 2 0
      src/views/Publications/Detail/index.vue
  88. 2 1
      src/views/Publications/constants.ts
  89. BIN
      src/views/Publications/images/heng.png
  90. BIN
      src/views/Publications/images/href.png
  91. BIN
      src/views/Publications/images/infoCon.png
  92. 0 34
      src/views/Publications/index.scss
  93. 2 25
      src/views/Publications/index.vue
  94. 129 0
      src/views/Search/index.scss
  95. 102 0
      src/views/Search/index.vue
  96. BIN
      src/views/Site/images/1.jpg
  97. BIN
      src/views/Site/images/home.jpg
  98. 28 0
      src/views/Site/index.vue

+ 1 - 0
components.d.ts

@@ -19,6 +19,7 @@ declare module 'vue' {
     ElPagination: typeof import('element-plus/es')['ElPagination']
     FloatDirectory: typeof import('./src/components/FloatDirectory/index.vue')['default']
     Layout: typeof import('./src/components/Layout/index.vue')['default']
+    PageNav: typeof import('./src/components/PageNav/index.vue')['default']
     PageTitle: typeof import('./src/components/PageTitle/index.vue')['default']
     Pagination: typeof import('./src/components/Pagination/index.vue')['default']
     RouterLink: typeof import('vue-router')['RouterLink']

Plik diff jest za duży
+ 1 - 0
src/assets/svgs/more.svg


+ 6 - 0
src/components/Breadcrumb/constants.ts

@@ -0,0 +1,6 @@
+import type { RouteLocationNamedRaw } from "vue-router";
+
+export interface BreadcrumbParent {
+  label: string;
+  routeParams: RouteLocationNamedRaw;
+}

+ 2 - 5
src/components/Breadcrumb/index.vue

@@ -36,13 +36,10 @@
 </template>
 
 <script lang="ts" setup>
-import type { RouteLocationRaw } from "vue-router";
+import type { BreadcrumbParent } from "./constants";
 
 defineProps<{
-  parents: {
-    label: string;
-    routeParams: RouteLocationRaw;
-  }[];
+  parents: BreadcrumbParent[];
 
   curRoute?: {
     name: string;

+ 4 - 4
src/components/Layout/data.ts

@@ -114,10 +114,10 @@ export const topData = [
     url: "About",
     about: true,
     children: [
-      { url: 338, id: 8.1, name: "From the Director" },
-      { url: 805, id: 8.2, name: "History" },
-      { url: 1307, id: 8.3, name: "Partners & Connections" },
-      { url: 1515, id: 8.4, name: "Contact" },
+      { url: 352, id: 8.1, name: "From the Director" },
+      { url: 816, id: 8.2, name: "History" },
+      { url: 1319, id: 8.3, name: "Partners & Connections" },
+      { url: 1525, id: 8.4, name: "Contact" },
     ],
   },
 ];

+ 35 - 8
src/components/Layout/index.vue

@@ -90,8 +90,18 @@
               data-aria-interaction-area
               aria-description="You've reached the search field, please use the tab key to browse the content."
             >
-              <input placeholder="search..." />
-              <svg-icon name="search" color="var(--van-primary-color)" />
+              <template v-if="$route.name !== 'Search'">
+                <input
+                  v-model="searchTxt"
+                  placeholder="search..."
+                  @keyup.enter="handleSearch(searchTxt)"
+                />
+                <svg-icon
+                  name="search"
+                  color="var(--van-primary-color)"
+                  @click="handleSearch(searchTxt)"
+                />
+              </template>
             </div>
           </div>
         </div>
@@ -112,15 +122,16 @@
             aria-description="You've reached the search field, please use the tab key to browse the content."
           >
             <div class="searchHover">
-              <div class="ll" @click="handleSearch">
+              <div class="ll" @click="handleSearch(searchTxt2)">
                 <img src="@/assets/images/LayoutSearch2.jpg" alt="" />
               </div>
-              <div class="rr" @keyup.enter="handleSearch">
+              <div class="rr">
                 <input
                   type="text"
                   placeholder="search"
-                  v-model="searchTxt"
-                  :aria-description="searchTxt || 'search'"
+                  v-model="searchTxt2"
+                  :aria-description="searchTxt2 || 'search'"
+                  @keyup.enter="handleSearch(searchTxt2)"
                 />
               </div>
             </div>
@@ -234,12 +245,13 @@ const skipTow = (url: string | number, about?: boolean) => {
   } else router.push(url as string);
 };
 
-const handleSearch = () => {
+const handleSearch = (txt: string) => {
   router.push({
     name: "Search",
-    params: { txt: searchTxt2.value },
+    query: { txt: txt },
   });
   searchTxt2.value = "";
+  searchTxt.value = "";
 };
 </script>
 
@@ -250,6 +262,7 @@ const handleSearch = () => {
   --primary-hover-bg: rgba(204, 0, 3, 0.8);
   --black-text-color: black;
   --gray-text-color: #666;
+  --gray2-text-color: #a6a6a6;
   --white-bg: white;
   --white-text-color: white;
 
@@ -259,6 +272,7 @@ const handleSearch = () => {
     --primary-hover-bg: white;
     --black-text-color: black;
     --gray-text-color: #666;
+    --gray2-text-color: #a6a6a6;
     --white-bg: white;
     --white-text-color: black;
   }
@@ -268,6 +282,7 @@ const handleSearch = () => {
     --primary-hover-bg: #00f;
     --black-text-color: #ff0;
     --gray-text-color: #ff0;
+    --gray2-text-color: #ff0;
     --white-bg: #00f;
     --white-text-color: #ff0;
   }
@@ -277,6 +292,7 @@ const handleSearch = () => {
     --primary-hover-bg: #ff0;
     --black-text-color: black;
     --gray-text-color: black;
+    --gray2-text-color: black;
     --white-bg: #ff0;
     --white-text-color: black;
   }
@@ -286,11 +302,18 @@ const handleSearch = () => {
     --primary-hover-bg: black;
     --black-text-color: #ff0;
     --gray-text-color: #ff0;
+    --gray2-text-color: #ff0;
     --white-bg: black;
     --white-text-color: #ff0;
   }
 }
 
+.aria-control-target {
+  position: relative;
+  min-height: 100vh;
+  padding-bottom: 45px;
+}
+
 .topnav {
   position: absolute;
   top: 0;
@@ -440,6 +463,10 @@ const handleSearch = () => {
 }
 
 .footer {
+  position: absolute;
+  left: 0;
+  right: 0;
+  bottom: 0;
   display: flex;
   justify-content: space-between;
   padding: 0 100px;

+ 90 - 0
src/components/PageNav/index.vue

@@ -0,0 +1,90 @@
+<template>
+  <div
+    class="page-nav"
+    data-aria-viewport-area
+    aria-description="You've reached the secondary menu under the Exhibition section. This menu contains four options. To browse the content,  please use the tab key."
+  >
+    <ul>
+      <li
+        v-for="(item, index) in list"
+        :key="index"
+        :class="{
+          active: isActive(index, item.name),
+        }"
+        @click="$router.push(item.routeParams)"
+        @keydown.enter.passive="$router.push(item.routeParams)"
+        tabindex="0"
+        aria-label="Link"
+        :aria-description="item.name"
+      >
+        <img :src="item.img" alt="" />
+        <p>
+          {{ item.name }}
+        </p>
+      </li>
+    </ul>
+  </div>
+</template>
+
+<script lang="ts" setup>
+import { isNumber } from "lodash-unified";
+import type { PageNavListItemType } from "./types";
+
+const props = defineProps<{
+  /**
+   * 导航列表
+   */
+  list: PageNavListItemType[];
+  /**
+   * 当前所在路由名称
+   */
+  curRouteName?: string;
+  /**
+   * 当前所在导航索引,默认通过路由名称判断
+   */
+  activeIndex?: number;
+}>();
+
+const isActive = (idx: number, name: string) => {
+  if (isNumber(props.activeIndex)) {
+    return props.activeIndex === idx;
+  }
+
+  return props.curRouteName === name;
+};
+</script>
+
+<style lang="scss" scoped>
+.page-nav {
+  width: 100%;
+  padding-bottom: 8px;
+  background: url("@/assets/images/Visit/bg_3.png") left bottom repeat-x #f1f1f1;
+  overflow: hidden;
+
+  ul {
+    margin: 0 auto;
+    display: flex;
+    width: 1180px;
+
+    li {
+      display: flex;
+      flex-direction: column;
+      align-items: center;
+      justify-content: center;
+      width: 168px;
+      height: 108px;
+      cursor: pointer;
+
+      &.active {
+        background: url("@/assets/images/Visit/bg_1.jpg") center top no-repeat
+          #f1f1f1;
+      }
+      p {
+        margin-top: 5px;
+        font-size: 14px;
+        line-height: 18px;
+      }
+    }
+  }
+}
+</style>

+ 7 - 0
src/components/PageNav/types.ts

@@ -0,0 +1,7 @@
+import type { RouteLocationNamedRaw } from "vue-router";
+
+export interface PageNavListItemType {
+  name: string;
+  img: string;
+  routeParams: RouteLocationNamedRaw;
+}

+ 46 - 0
src/router/index.ts

@@ -121,6 +121,52 @@ const router = createRouter({
             },
           ],
         },
+        {
+          path: "/Layout/JoinSupport",
+          name: "JoinSupport",
+          redirect: "/Layout/JoinSupport/Volunteer",
+          component: () => import("../views/JoinSupport/index.vue"),
+          children: [
+            {
+              path: "/Layout/JoinSupport/Volunteer",
+              name: "Volunteer",
+              component: () =>
+                import("../views/JoinSupport/Volunteer/index.vue"),
+            },
+            {
+              path: "/Layout/JoinSupport/VolunteerInfo",
+              name: "VolunteerDetail",
+              component: () =>
+                import("../views/JoinSupport/Volunteer/detail.vue"),
+            },
+
+            {
+              path: "/Layout/JoinSupport/Give",
+              name: "Give",
+              component: () => import("../views/JoinSupport/Give/index.vue"),
+            },
+            {
+              path: "/Layout/JoinSupport/GiveInfo",
+              name: "GiveDetail",
+              component: () => import("../views/JoinSupport/Give/detail.vue"),
+            },
+          ],
+        },
+        {
+          path: "/Layout/About",
+          name: "About",
+          component: () => import("../views/About/index.vue"),
+        },
+        {
+          path: "/Layout/Search",
+          name: "Search",
+          component: () => import("../views/Search/index.vue"),
+        },
+        {
+          path: "/Layout/Index",
+          name: "SiteIndex",
+          component: () => import("../views/Site/index.vue"),
+        },
       ],
     },
   ],

+ 56 - 0
src/views/About/components/Connections.vue

@@ -0,0 +1,56 @@
+<template>
+  <div class="about-connections">
+    <div class="container">
+      <ul>
+        <li class="about-connections-item">
+          <a
+            href=""
+            target="_blank"
+            aria-label="Image link"
+            aria-description="Edo-Tokyo Museum"
+          >
+            <img src="../images/link/8.jpg" />
+          </a>
+        </li>
+      </ul>
+
+      <div class="about-connections__more">See More</div>
+    </div>
+  </div>
+</template>
+
+<style lang="scss" scoped>
+.about-connections {
+  position: relative;
+  padding-top: 115px;
+  height: 559px;
+  background: url("../images/a6.jpg") center top no-repeat;
+
+  ul {
+    display: flex;
+    flex-wrap: wrap;
+    margin: -10px -5px;
+  }
+  &-item {
+    margin: 10px 5px;
+    width: calc(33.3333% - 10px);
+    height: 143px;
+    filter: grayscale(100%);
+
+    &:hover {
+      filter: grayscale(0);
+    }
+  }
+  &__more {
+    margin: 20px auto 0;
+    width: 148px;
+    height: 48px;
+    text-align: center;
+    line-height: 48px;
+    color: white;
+    font-size: 24px;
+    background: var(--van-primary-color);
+    cursor: pointer;
+  }
+}
+</style>

+ 51 - 0
src/views/About/components/Contact.vue

@@ -0,0 +1,51 @@
+<template>
+  <div class="about-contact">
+    <p tabindex="0">
+      Official website of Capital Museum:
+      <a href="https://en.capitalmuseum.org.cn/" tabindex="0"
+        >https://en.capitalmuseum.org.cn/</a
+      >
+    </p>
+    <p tabindex="0">
+      Telephone reservation (individual visitors):
+      <span tabindex="0">+86 (10) 63393339</span>
+    </p>
+    <p tabindex="0">
+      Telephone reservation (group visitors):
+      <span tabindex="0">+86 (10) 63370458</span>
+    </p>
+    <p tabindex="0">
+      Inquiry Hotline: <span tabindex="0">+86 (10) 63370491</span>
+    </p>
+    <p>
+      <a
+        href="mailto:ICD@capitalmuseum.org.cn"
+        tabindex="0"
+        aria-description="Email Us"
+      >
+        <img src="../images/youxiang.jpg" />
+      </a>
+    </p>
+  </div>
+</template>
+
+<style lang="scss" scoped>
+.about-contact {
+  margin: 0px auto 100px;
+  padding: 143px 35px 35px;
+  width: 930px;
+  font-size: 24px;
+  line-height: 30px;
+  background: url("../images/au6.gif") var(--white-bg) no-repeat center top;
+
+  p {
+    padding: 10px 0px;
+    font-size: 14px;
+
+    a,
+    span {
+      color: var(--van-primary-color);
+    }
+  }
+}
+</style>

+ 65 - 0
src/views/About/components/Director.vue

@@ -0,0 +1,65 @@
+<template>
+  <div
+    class="about-director"
+    tabindex="0"
+    data-aria-viewport-area
+    aria-description="You've reached the From the Director section, please use the tab key to navigate through the content."
+  >
+    <div class="about-director__container">
+      <p tabindex="0">Welcome to the website of the Capital Museum of China.</p>
+      <p tabindex="0">
+        We are looking forward to your visit. The Capital Museum is a palace of
+        Beijing culture. Its collections relate to the long development of the
+        capital city, showcasing its magnificent living history of 500,000
+        years, urban history of 3,000 years and history as the Chinese capital
+        for 800 years. The museum also presents cultural and artistic
+        exhibitions from different regions and displays the achievements of
+        various ethnic groups at home and abroad. You can feel the breadth of
+        both Chinese and world civilizations.
+      </p>
+      <p tabindex="0">
+        Historical culture is the soul of a city and in the case of Beijing it
+        is a great witness to the long history of Chinese civilization. We are
+        looking forward to welcoming you to share with us the full
+        interpretation of this glorious civilization while immersing yourself in
+        the great wisdom of Beijing.<br />
+      </p>
+      <div class="about-director__more" tabindex="0" aria-label="Link">
+        Read More
+      </div>
+    </div>
+  </div>
+</template>
+
+<style lang="scss" scoped>
+.about-director {
+  padding: 135px 0 20px;
+  height: 466px;
+  color: white;
+  font-size: 16px;
+  line-height: 20px;
+  background: url("../images/au2.jpg") rgb(203, 7, 7) no-repeat center top;
+
+  &__container {
+    width: 750px;
+    margin: 0px auto;
+    padding-left: 50px;
+
+    p {
+      text-align: justify;
+      padding-bottom: 13px;
+    }
+  }
+  &__more {
+    margin: 20px auto;
+    width: 110px;
+    font-size: 12px;
+    color: white;
+    line-height: 30px;
+    text-align: center;
+    border: 1px solid rgb(255, 255, 255);
+    font-weight: bold;
+    cursor: pointer;
+  }
+}
+</style>

+ 106 - 0
src/views/About/components/History.vue

@@ -0,0 +1,106 @@
+<template>
+  <div class="about-history">
+    <div class="container">
+      <p class="about-history__title">History</p>
+
+      <ul>
+        <li
+          v-for="(item, idx) in LIST"
+          :key="idx"
+          class="about-history-item"
+          :style="{ backgroundImage: `url(${item.bg})` }"
+        >
+          <div class="about-history-item-hover">
+            <p>{{ item.label }}</p>
+
+            <div class="about-history-item-hover__btn">Enter</div>
+          </div>
+        </li>
+      </ul>
+    </div>
+  </div>
+</template>
+
+<script lang="ts" setup>
+import Bg1Img from "../images/his/1.png";
+
+const LIST = [
+  {
+    bg: Bg1Img,
+    label: "The Capital Museum",
+  },
+];
+</script>
+
+<style lang="scss" scoped>
+.about-history {
+  position: relative;
+  padding-top: 40px;
+  height: 501px;
+  background: url("../images/au3.png") 100% 100%;
+
+  &__title {
+    margin-bottom: 30px;
+    font-size: 30px;
+    font-weight: bold;
+    text-align: center;
+  }
+  ul {
+    display: flex;
+    justify-content: space-between;
+  }
+  &-item {
+    position: relative;
+    width: 280px;
+    height: 360px;
+    overflow: hidden;
+    transition: all 0.1s ease 0s;
+    background-position: center top;
+    background-size: cover;
+    border-radius: 8px;
+    cursor: pointer;
+    transition: all 0.1s ease 0s;
+
+    &:hover {
+      transform: scale(1.1);
+
+      .about-history-item-hover {
+        opacity: 1;
+      }
+    }
+    &-hover {
+      position: absolute;
+      top: 0;
+      left: 0;
+      right: 0;
+      bottom: 0;
+      padding: 10px 10px 70px;
+      display: flex;
+      align-items: center;
+      justify-content: center;
+      background: var(--van-primary-color);
+      opacity: 0;
+
+      p {
+        color: white;
+        font-size: 18px;
+        line-height: 26px;
+      }
+      &__btn {
+        display: flex;
+        justify-content: center;
+        align-items: center;
+        position: absolute;
+        left: 50%;
+        bottom: 40px;
+        width: 130px;
+        height: 42px;
+        color: white;
+        font-size: 20px;
+        border: 1px solid white;
+        transform: translateX(-50%);
+      }
+    }
+  }
+}
+</style>

BIN
src/views/About/images/a6.jpg


BIN
src/views/About/images/au2.jpg


BIN
src/views/About/images/au3.png


BIN
src/views/About/images/au6.gif


BIN
src/views/About/images/banner.jpg


BIN
src/views/About/images/his/1.png


BIN
src/views/About/images/his/2.png


BIN
src/views/About/images/his/3.png


BIN
src/views/About/images/his/4.png


BIN
src/views/About/images/his/back.png


BIN
src/views/About/images/link/1.jpg


BIN
src/views/About/images/link/10.jpg


BIN
src/views/About/images/link/11.jpg


BIN
src/views/About/images/link/12.jpg


BIN
src/views/About/images/link/13.jpg


BIN
src/views/About/images/link/14.jpg


BIN
src/views/About/images/link/15.jpg


BIN
src/views/About/images/link/16.jpg


BIN
src/views/About/images/link/17.jpg


BIN
src/views/About/images/link/18.jpg


BIN
src/views/About/images/link/19.jpg


BIN
src/views/About/images/link/2.jpg


BIN
src/views/About/images/link/20.jpg


BIN
src/views/About/images/link/3.jpg


BIN
src/views/About/images/link/4.jpg


BIN
src/views/About/images/link/5.jpg


BIN
src/views/About/images/link/6.jpg


BIN
src/views/About/images/link/7.jpg


BIN
src/views/About/images/link/8.jpg


BIN
src/views/About/images/link/9.jpg


BIN
src/views/About/images/youxiang.jpg


+ 9 - 0
src/views/About/index.scss

@@ -0,0 +1,9 @@
+.about {
+  &-banner {
+    margin-top: -60px;
+    display: block;
+    width: 100%;
+    height: 300px;
+    object-fit: cover;
+  }
+}

+ 34 - 0
src/views/About/index.vue

@@ -0,0 +1,34 @@
+<template>
+  <div class="about">
+    <img
+      class="about-banner"
+      aria-label="Image"
+      aria-description="You've reached the banner area of the About page; this page has one image; please use the tab key to go through the content."
+      src="./images/banner.jpg"
+    />
+
+    <div class="container">
+      <Breadcrumb :parents="[]" :cur-route="{ name: 'About' }" />
+    </div>
+
+    <Director />
+
+    <History />
+
+    <Connections />
+
+    <Contact />
+  </div>
+</template>
+
+<script lang="ts" setup>
+import Breadcrumb from "@/components/Breadcrumb/index.vue";
+import Director from "./components/Director.vue";
+import History from "./components/History.vue";
+import Connections from "./components/Connections.vue";
+import Contact from "./components/Contact.vue";
+</script>
+
+<style lang="scss" scoped>
+@import "./index.scss";
+</style>

+ 8 - 0
src/views/Collections/components/DetailDialog/index.scss

@@ -62,4 +62,12 @@
     flex: 1;
     width: 440px;
   }
+  &__mask {
+    position: absolute;
+    top: 0;
+    left: 0;
+    width: 64px;
+    height: 133px;
+    background: url("../../images/mark.png") no-repeat center / contain;
+  }
 }

+ 46 - 7
src/views/Collections/components/DetailDialog/index.vue

@@ -5,12 +5,16 @@
         Gold-inlaid Incense Burner with Cord-shaped Ears and Persian Inscription
       </h3>
 
-      <ElImage
-        tabindex="0"
-        aria-label="Image"
-        aria-description=""
-        src="http://localhost:8080/data/Collections/Bronzes/big25.png"
-      />
+      <div ref="maskRef" style="position: relative">
+        <ElImage
+          tabindex="0"
+          aria-label="Image"
+          aria-description=""
+          src="http://localhost:8080/data/Collections/Bronzes/big25.png"
+        />
+
+        <span class="collection-detail__mask" :style="maskStyle" />
+      </div>
 
       <div
         class="collection-detail-preview__btn"
@@ -26,12 +30,17 @@
 </template>
 
 <script lang="ts" setup>
-import { computed } from "vue";
+import { ref, watch, reactive, computed, nextTick, onBeforeMount } from "vue";
 
 const props = defineProps<{
   visible: boolean;
 }>();
 const emits = defineEmits(["update:visible"]);
+const maskStyle = reactive({
+  opacity: 1,
+  top: 0,
+  left: 0,
+});
 
 const show = computed({
   get() {
@@ -41,6 +50,36 @@ const show = computed({
     emits("update:visible", v);
   },
 });
+
+let timer: number;
+const maskRef = ref();
+
+watch(show, (v) => {
+  if (v) {
+    nextTick(() => {
+      const maxLeft = maskRef.value.offsetWidth - 64;
+      const maxTop = maskRef.value.offsetHeight - 133;
+
+      timer = setInterval(() => {
+        maskStyle.opacity = 0;
+
+        setTimeout(() => {
+          Object.assign(maskStyle, {
+            opacity: 1,
+            top: Math.ceil(Math.random() * maxTop) + "px",
+            left: Math.ceil(Math.random() * maxLeft) + "px",
+          });
+        }, 500);
+      }, 3000);
+    });
+  } else {
+    clearInterval(timer);
+  }
+});
+
+onBeforeMount(() => {
+  clearInterval(timer);
+});
 </script>
 
 <style lang="scss">

BIN
src/views/Collections/images/mark.png


+ 6 - 5
src/views/Exhibitions/constants.ts

@@ -2,26 +2,27 @@ import CurrentIcon from "@/assets/images/Exhibitions/t_1.png";
 import PermanentIcon from "@/assets/images/Exhibitions/t_2.png";
 import Pastcon from "@/assets/images/Exhibitions/t_3.png";
 import OverseasIcon from "@/assets/images/Exhibitions/t_4.png";
+import type { PageNavListItemType } from "@/components/PageNav/types";
 
-export const NAV_LIST = [
+export const NAV_LIST: PageNavListItemType[] = [
   {
     name: "Current Exhibitions",
     img: CurrentIcon,
-    pathName: "Exhibitions",
+    routeParams: { name: "Exhibitions", params: { type: 1 } },
   },
   {
     name: "Permanent Exhibitions",
     img: PermanentIcon,
-    pathName: "Exhibitions",
+    routeParams: { name: "Exhibitions", params: { type: 2 } },
   },
   {
     name: "Past Exhibitions",
     img: Pastcon,
-    pathName: "Exhibitions",
+    routeParams: { name: "Exhibitions", params: { type: 3 } },
   },
   {
     name: "Overseas Exhibitions",
     img: OverseasIcon,
-    pathName: "Exhibitions",
+    routeParams: { name: "Exhibitions", params: { type: 4 } },
   },
 ];

+ 0 - 34
src/views/Exhibitions/index.scss

@@ -1,38 +1,4 @@
 .exhibitions {
-  &-nav {
-    width: 100%;
-    padding-bottom: 8px;
-    background: url("@/assets/images/Visit/bg_3.png") left bottom repeat-x
-      #f1f1f1;
-    overflow: hidden;
-
-    ul {
-      margin: 0 auto;
-      display: flex;
-      width: 1180px;
-
-      li {
-        display: flex;
-        flex-direction: column;
-        align-items: center;
-        justify-content: center;
-        width: 168px;
-        height: 108px;
-        cursor: pointer;
-
-        &.active {
-          background: url("@/assets/images/Visit/bg_1.jpg") center top no-repeat
-            #f1f1f1;
-        }
-        p {
-          margin-top: 5px;
-          font-size: 14px;
-          line-height: 18px;
-        }
-      }
-    }
-  }
-
   .container {
     width: 1180px;
   }

+ 2 - 29
src/views/Exhibitions/index.vue

@@ -6,35 +6,7 @@
       src="@/assets/images/Exhibitions/banner_1.jpg"
     />
 
-    <div
-      class="exhibitions-nav"
-      data-aria-viewport-area
-      aria-description="You've reached the secondary menu under the Exhibition section. This menu contains four options. To browse the content,  please use the tab key."
-    >
-      <ul>
-        <li
-          v-for="(item, index) in NAV_LIST"
-          :key="index"
-          :class="{
-            active: curRoute?.name === item.name,
-          }"
-          @click="
-            $router.push({ name: item.pathName, params: { type: index + 1 } })
-          "
-          @keydown.enter.passive="
-            $router.push({ name: item.pathName, params: { type: index + 1 } })
-          "
-          tabindex="0"
-          aria-label="Link"
-          :aria-description="item.name"
-        >
-          <img :src="item.img" alt="" />
-          <p>
-            {{ item.name }}
-          </p>
-        </li>
-      </ul>
-    </div>
+    <PageNav :list="NAV_LIST" :cur-route-name="curRoute.name" />
 
     <div class="container">
       <Breadcrumb
@@ -127,6 +99,7 @@
 <script lang="ts" setup>
 import { useRoute } from "vue-router";
 import { computed, ref } from "vue";
+import PageNav from "@/components/PageNav/index.vue";
 import PageTitle from "@/components/PageTitle/index.vue";
 import ListModeIcon from "@/assets/images/Exhibitions/cut1.png";
 import ActListModeIcon from "@/assets/images/Exhibitions/cut1Ac.png";

+ 67 - 0
src/views/JoinSupport/Give/detail.vue

@@ -0,0 +1,67 @@
+<template>
+  <div class="give-detail">
+    <div class="give-detail__main">
+      <h1 tabindex="0">Corporations & Institutions</h1>
+
+      <div class="give-detail-contact">
+        <p tabindex="1">86 (10) 63370488</p>
+        <p tabindex="1">86 (10) 63363388 to extension 6223</p>
+      </div>
+    </div>
+  </div>
+</template>
+
+<style lang="scss" scoped>
+.give-detail {
+  position: relative;
+  padding-bottom: 100px;
+
+  &__main {
+    position: relative;
+    padding: 30px 30px 100px;
+    background-color: rgb(31, 29, 29);
+    z-index: 2;
+
+    > h1 {
+      position: relative;
+      padding: 0 0 20px 20px;
+      font-size: 24px;
+      line-height: 26px;
+      color: white;
+
+      &::before {
+        content: "";
+        position: absolute;
+        top: 12px;
+        left: 0;
+        width: 11px;
+        height: 11px;
+        background: var(--van-primary-color);
+      }
+    }
+  }
+  &-contact {
+    position: absolute;
+    left: 23px;
+    bottom: -60px;
+    padding: 76px 0px 0px 112px;
+    width: 529px;
+    height: 181px;
+    color: white;
+    font-size: 24px;
+    line-height: 36px;
+    font-weight: bold;
+    background: url("../images/dianhua.png") no-repeat center / contain;
+  }
+  &::after {
+    content: "";
+    position: absolute;
+    top: 0;
+    left: 50%;
+    bottom: 0;
+    width: 100vw;
+    background: url("../images/bg4.gif") no-repeat center bottom / 100% auto;
+    transform: translateX(-50%);
+  }
+}
+</style>

+ 70 - 0
src/views/JoinSupport/Give/index.scss

@@ -0,0 +1,70 @@
+.give {
+  margin-bottom: 40px;
+
+  &-row {
+    display: flex;
+    height: 300px;
+
+    &:hover {
+      .give-row__img p {
+        opacity: 1;
+      }
+    }
+    > div {
+      flex: 1;
+      height: inherit;
+    }
+    &.individuals {
+      .give-row__banner {
+        background: url("../images/wg1.gif") center / 100%;
+      }
+      .give-row__img {
+        background: url("../images/wg1.jpg") center / cover;
+      }
+    }
+    &.institutions {
+      .give-row__banner {
+        background: url("../images/wg2.gif") center / 100%;
+      }
+      .give-row__img {
+        background: url("../images/wg2.jpg") center / cover;
+      }
+    }
+    &__banner {
+      display: flex;
+      align-items: center;
+      justify-content: center;
+
+      div {
+        font-size: 20px;
+        width: 218px;
+        height: 78px;
+        line-height: 76px;
+        color: var(--white-bg);
+        border: 1px solid var(--white-bg);
+        font-weight: 700;
+        text-align: center;
+        cursor: pointer;
+      }
+    }
+    &__img {
+      position: relative;
+      cursor: pointer;
+
+      p {
+        position: absolute;
+        top: 0;
+        left: 0;
+        right: 0;
+        bottom: 0;
+        padding: 90px 45px 0;
+        font-size: 14px;
+        line-height: 24px;
+        color: var(--white-text-color);
+        background: var(--topnav-bg-color);
+        transition: opacity 0.3s;
+        opacity: 0;
+      }
+    }
+  }
+}

+ 52 - 0
src/views/JoinSupport/Give/index.vue

@@ -0,0 +1,52 @@
+<template>
+  <div
+    class="give"
+    tabindex="0"
+    data-aria-viewport-area
+    aria-description="You've reached the content area of the Ways to Give page, please use the tab key to go through the content."
+  >
+    <div class="give-row individuals">
+      <div class="give-row__banner">
+        <div
+          tabindex="0"
+          aria-label="Link"
+          @click="$router.push({ name: 'GiveDetail' })"
+        >
+          Individuals
+        </div>
+      </div>
+
+      <div class="give-row__img">
+        <p>
+          Since the establishment of Capital Museum, we have got sufficient
+          supports from people from all walks of life. Due to the limited space,
+          here we only give a few examples, and we show our respect to all units
+          and individuals who have supported the development of Chinese museums
+          and have given help and supports to Capital Museum.
+        </p>
+      </div>
+    </div>
+
+    <div class="give-row institutions">
+      <div class="give-row__img">
+        <p>
+          The century-old Beijing Match Factory donated to Capital Museum a
+          large number of files and real objects which record the development of
+          Beijing's light industry in modern history, including 518 sets of high
+          standard real samples of matches, 40 volumes data, and 3 volumes of
+          text materials of sparks, etc.
+        </p>
+      </div>
+
+      <div class="give-row__banner">
+        <div tabindex="0" aria-label="Link" style="width: 370px">
+          Corporations & Institutions
+        </div>
+      </div>
+    </div>
+  </div>
+</template>
+
+<style lang="scss" scoped>
+@import "./index.scss";
+</style>

+ 20 - 0
src/views/JoinSupport/Volunteer/detail.vue

@@ -0,0 +1,20 @@
+<template>
+  <div class="volunteer-detail">
+    <h1 aria-label="Volunteer Team Introduction">
+      Volunteer Team Introduction
+    </h1>
+  </div>
+</template>
+
+<style lang="scss" scoped>
+.volunteer-detail {
+  padding-bottom: 100px;
+
+  h1 {
+    padding: 20px 0;
+    text-align: center;
+    font-size: 30px;
+    font-weight: bold;
+  }
+}
+</style>

+ 99 - 0
src/views/JoinSupport/Volunteer/index.scss

@@ -0,0 +1,99 @@
+.volunteer {
+  margin: 20px auto 30px;
+  padding-top: 4px;
+  display: flex;
+  width: 900px;
+  background: url("../images/bg3.gif") black no-repeat 0 0 / auto 4px;
+
+  &-item {
+    position: relative;
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+    justify-content: center;
+    flex: 1;
+    height: 627px;
+    color: white;
+    font-size: 24px;
+    font-weight: bold;
+    overflow: hidden;
+    cursor: pointer;
+
+    &:hover {
+      &::before,
+      .volunteer-item__bg {
+        opacity: 1;
+      }
+    }
+    &::after {
+      content: "";
+      position: absolute;
+      top: 50%;
+      left: 50%;
+      width: 74px;
+      height: 74px;
+      transform: translate(-50%, -50%);
+      z-index: 2;
+    }
+    &::before {
+      content: "";
+      position: absolute;
+      top: 50%;
+      left: 50%;
+      width: 228px;
+      height: 228px;
+      transform: translate(-50%, -50%);
+      opacity: 0;
+      transition: opacity 0.5s;
+      z-index: 3;
+    }
+    &:nth-child(1) {
+      .volunteer-item__bg {
+        background: url("../images/v1.jpg") no-repeat center / cover;
+      }
+      &::after {
+        background: url("../images/y1.png") no-repeat center / contain;
+      }
+      &::before {
+        background: url("../images/y1Ac.png") no-repeat center / contain;
+      }
+    }
+    &:nth-child(2) {
+      .volunteer-item__bg {
+        background: url("../images/v2.jpg") no-repeat center / cover;
+      }
+      &::after {
+        background: url("../images/y2.png") no-repeat center / contain;
+      }
+      &::before {
+        background: url("../images/y2Ac.png") no-repeat center / contain;
+      }
+    }
+    &:nth-child(3) {
+      .volunteer-item__bg {
+        background: url("../images/v3.jpg") no-repeat center / cover;
+      }
+      &::after {
+        background: url("../images/y3.png") no-repeat center / contain;
+      }
+      &::before {
+        background: url("../images/y3Ac.png") no-repeat center / contain;
+      }
+    }
+    &__bg {
+      position: absolute;
+      top: 0;
+      left: 0;
+      right: 0;
+      bottom: 0;
+      opacity: 0.5;
+      transition: opacity 0.5s;
+      z-index: 1;
+    }
+    h1 {
+      position: relative;
+      text-align: center;
+      z-index: 4;
+    }
+  }
+}

+ 29 - 0
src/views/JoinSupport/Volunteer/index.vue

@@ -0,0 +1,29 @@
+<template>
+  <div
+    class="volunteer"
+    tabindex="0"
+    data-aria-viewport-area
+    aria-description="You've reached the content area of the Ways to Volunteer page, please use the tab key to go through the content."
+  >
+    <div
+      v-for="(item, idx) in VOLUNTEER_DETAIL_NAV"
+      :key="item.label"
+      class="volunteer-item"
+      tabindex="0"
+      aria-label="Image link"
+      :aria-description="item.label"
+      @click="$router.push({ name: 'VolunteerDetail', query: { id: idx + 1 } })"
+    >
+      <div class="volunteer-item__bg" />
+      <h1>{{ item.label }}</h1>
+    </div>
+  </div>
+</template>
+
+<script lang="ts" setup>
+import { VOLUNTEER_DETAIL_NAV } from "../constants";
+</script>
+
+<style lang="scss" scoped>
+@import "./index.scss";
+</style>

+ 32 - 0
src/views/JoinSupport/constants.ts

@@ -0,0 +1,32 @@
+import type { PageNavListItemType } from "@/components/PageNav/types";
+import VolunteerIcon from "./images/n1.png";
+import GiveIcon from "./images/n2.png";
+
+export const VOLUNTEER_DETAIL_NAV = [
+  {
+    label: "Volunteer Team Introduction",
+  },
+  {
+    label: "Volunteer Apply",
+  },
+  {
+    label: "Volunteer Program",
+  },
+];
+
+export const NAV_LIST: PageNavListItemType[] = [
+  {
+    name: "Ways to Volunteer",
+    img: VolunteerIcon,
+    routeParams: {
+      name: "Volunteer",
+    },
+  },
+  {
+    name: "Ways to Give",
+    img: GiveIcon,
+    routeParams: {
+      name: "Give",
+    },
+  },
+];

BIN
src/views/JoinSupport/images/banner.jpg


BIN
src/views/JoinSupport/images/bg3.gif


BIN
src/views/JoinSupport/images/bg4.gif


BIN
src/views/JoinSupport/images/dianhua.png


BIN
src/views/JoinSupport/images/n1.png


BIN
src/views/JoinSupport/images/n2.png


BIN
src/views/JoinSupport/images/v1.jpg


BIN
src/views/JoinSupport/images/v2.jpg


BIN
src/views/JoinSupport/images/v3.jpg


BIN
src/views/JoinSupport/images/v4.jpg


BIN
src/views/JoinSupport/images/wg1.gif


BIN
src/views/JoinSupport/images/wg1.jpg


BIN
src/views/JoinSupport/images/wg2.gif


BIN
src/views/JoinSupport/images/wg2.jpg


BIN
src/views/JoinSupport/images/y1.png


BIN
src/views/JoinSupport/images/y1Ac.png


BIN
src/views/JoinSupport/images/y2.png


BIN
src/views/JoinSupport/images/y2Ac.png


BIN
src/views/JoinSupport/images/y3.png


BIN
src/views/JoinSupport/images/y3Ac.png


BIN
src/views/JoinSupport/images/y4.png


BIN
src/views/JoinSupport/images/y4Ac.png


+ 19 - 0
src/views/JoinSupport/index.scss

@@ -0,0 +1,19 @@
+.join-support {
+  background: white;
+
+  .page-nav {
+    background-color: white;
+  }
+
+  &-banner {
+    margin-top: -60px;
+    display: block;
+    width: 100%;
+    height: 300px;
+    object-fit: cover;
+  }
+
+  .breadcrumb {
+    margin-top: 0;
+  }
+}

+ 72 - 0
src/views/JoinSupport/index.vue

@@ -0,0 +1,72 @@
+<template>
+  <div class="join-support">
+    <img
+      :aria-description="`You've reached the banner area of the ${curRoute?.name} page; this area has one image; please use the tab key to navigate through the content.`"
+      class="join-support-banner"
+      src="./images/banner.jpg"
+    />
+
+    <PageNav
+      :active-index="activeNavIndex"
+      :list="NAV_LIST"
+      :cur-route-name="curRoute?.name"
+    />
+
+    <div class="container">
+      <Breadcrumb :parents="parentRoutes" :cur-route="curRoute" />
+
+      <RouterView />
+    </div>
+  </div>
+</template>
+
+<script lang="ts" setup>
+import { useRoute } from "vue-router";
+import { computed } from "vue";
+import PageNav from "@/components/PageNav/index.vue";
+import Breadcrumb from "@/components/Breadcrumb/index.vue";
+import type { BreadcrumbParent } from "@/components/Breadcrumb/constants";
+import { NAV_LIST, VOLUNTEER_DETAIL_NAV } from "./constants";
+
+const route = useRoute();
+const activeNavIndex = computed(() => {
+  if (route.name === "VolunteerDetail") return 0;
+  if (route.name === "GiveDetail") return 1;
+
+  return undefined;
+});
+const parentRoutes = computed(() => {
+  const stack: BreadcrumbParent[] = [
+    {
+      label: "Join & Support",
+      routeParams: {
+        name: "JoinSupport",
+      },
+    },
+  ];
+
+  if (["VolunteerDetail", "GiveDetail"].includes(route.name as string)) {
+    const item = NAV_LIST[route.name === "VolunteerDetail" ? 0 : 1];
+
+    stack.push({
+      label: item.name,
+      routeParams: item.routeParams,
+    });
+  }
+
+  return stack;
+});
+const curRoute = computed(() => {
+  if (route.name === "VolunteerDetail") {
+    return {
+      name: VOLUNTEER_DETAIL_NAV[Number(route.query.id || 1) - 1].label,
+    };
+  }
+
+  return NAV_LIST.find((item) => item.routeParams.name === route.name);
+});
+</script>
+
+<style lang="scss" scoped>
+@import "./index.scss";
+</style>

+ 62 - 0
src/views/Publications/Catalogues/index.scss

@@ -0,0 +1,62 @@
+.catalogues {
+  overflow: hidden;
+  margin-bottom: 30px;
+
+  &__border {
+    display: block;
+    margin-top: 20px;
+    width: 100%;
+  }
+  &__list {
+    display: flex;
+    flex-wrap: wrap;
+    margin: -7.5px;
+  }
+  &-item {
+    position: relative;
+    margin: 7.5px;
+    width: calc(25% - 15px);
+    height: 375px;
+
+    &:hover {
+      .catalogues-item__ft {
+        height: 50%;
+        opacity: 1;
+      }
+    }
+    img {
+      width: inherit;
+      height: inherit;
+      object-fit: cover;
+      object-position: center;
+    }
+    &__ft {
+      position: absolute;
+      left: 0;
+      right: 0;
+      bottom: 0;
+      display: flex;
+      flex-direction: column;
+      align-items: center;
+      justify-content: center;
+      gap: 20px;
+      height: 0;
+      color: var(--white-text-color);
+      background: var(--topnav-bg-color);
+      cursor: pointer;
+      font-weight: 700;
+      font-size: 20px;
+      opacity: 0;
+      transition: all 0.6s ease 0s;
+      z-index: 1;
+
+      img {
+        width: 36px;
+        height: 30px;
+      }
+      span {
+        width: 175px;
+      }
+    }
+  }
+}

+ 25 - 1
src/views/Publications/Catalogues/index.vue

@@ -1,3 +1,27 @@
 <template>
-  <div class="magazines"></div>
+  <div class="catalogues">
+    <img class="catalogues__border" :src="HengImg" />
+
+    <ul class="catalogues__list">
+      <li v-for="key in 8" :key="key" class="catalogues-item">
+        <ElImage
+          src="https://en.capitalmuseum.org.cn/data/Publications/Exhibition/1.jpg"
+        />
+
+        <a href="" target="_blank" class="catalogues-item__ft">
+          <img :src="HrefImg" />
+          <span>Click here to open the catalogue</span>
+        </a>
+      </li>
+    </ul>
+  </div>
 </template>
+
+<script setup lang="ts">
+import HengImg from "../images/heng.png";
+import HrefImg from "../images/href.png";
+</script>
+
+<style lang="scss" scoped>
+@import "./index.scss";
+</style>

+ 8 - 0
src/views/Publications/Detail/index.scss

@@ -38,4 +38,12 @@
       }
     }
   }
+
+  &__title {
+    margin-bottom: 15px;
+    font-size: 24px;
+    line-height: 64px;
+    text-indent: 30px;
+    background: url("../images/infoCon.png") no-repeat center / contain;
+  }
 }

+ 2 - 0
src/views/Publications/Detail/index.vue

@@ -11,6 +11,8 @@
         </div>
       </div>
     </div>
+
+    <div class="publications-detail__title">Contents</div>
   </div>
 </template>
 

+ 2 - 1
src/views/Publications/constants.ts

@@ -1,10 +1,11 @@
+import type { PageNavListItemType } from "@/components/PageNav/types";
 import MagazinesIcon from "./images/1.png";
 import CataloguesIcon from "./images/2.png";
 import P1Icon from "./images/p1.png";
 import P2Icon from "./images/p2.png";
 import P3Icon from "./images/p3.png";
 
-export const NAV_LIST = [
+export const NAV_LIST: PageNavListItemType[] = [
   {
     name: "Magazines",
     img: MagazinesIcon,

BIN
src/views/Publications/images/heng.png


BIN
src/views/Publications/images/href.png


BIN
src/views/Publications/images/infoCon.png


+ 0 - 34
src/views/Publications/index.scss

@@ -1,38 +1,4 @@
 .publications {
-  &-nav {
-    width: 100%;
-    padding-bottom: 8px;
-    background: url("@/assets/images/Visit/bg_3.png") left bottom repeat-x
-      #f1f1f1;
-    overflow: hidden;
-
-    ul {
-      margin: 0 auto;
-      display: flex;
-      width: 1180px;
-
-      li {
-        display: flex;
-        flex-direction: column;
-        align-items: center;
-        justify-content: center;
-        width: 168px;
-        height: 108px;
-        cursor: pointer;
-
-        &.active {
-          background: url("@/assets/images/Visit/bg_1.jpg") center top no-repeat
-            #f1f1f1;
-        }
-        p {
-          margin-top: 5px;
-          font-size: 14px;
-          line-height: 18px;
-        }
-      }
-    }
-  }
-
   .container {
     width: 1180px;
   }

+ 2 - 25
src/views/Publications/index.vue

@@ -6,31 +6,7 @@
       src="./images/banner.jpg"
     />
 
-    <div
-      class="publications-nav"
-      data-aria-viewport-area
-      aria-description="You've reached the secondary menu under the Exhibition section. This menu contains four options. To browse the content,  please use the tab key."
-    >
-      <ul>
-        <li
-          v-for="(item, index) in NAV_LIST"
-          :key="index"
-          :class="{
-            active: curRoute?.name === item.name,
-          }"
-          @click="$router.push(item.routeParams)"
-          @keydown.enter.passive="$router.push(item.routeParams)"
-          tabindex="0"
-          aria-label="Link"
-          :aria-description="item.name"
-        >
-          <img :src="item.img" alt="" />
-          <p>
-            {{ item.name }}
-          </p>
-        </li>
-      </ul>
-    </div>
+    <PageNav :list="NAV_LIST" :cur-route-name="curRoute?.name" />
 
     <div class="container">
       <Breadcrumb
@@ -55,6 +31,7 @@
 <script lang="ts" setup>
 import { useRoute } from "vue-router";
 import { computed } from "vue";
+import PageNav from "@/components/PageNav/index.vue";
 import PageTitle from "@/components/PageTitle/index.vue";
 import Breadcrumb from "@/components/Breadcrumb/index.vue";
 import { NAV_LIST } from "./constants";

+ 129 - 0
src/views/Search/index.scss

@@ -0,0 +1,129 @@
+.search-page {
+  &-title {
+    font-size: 18px;
+    line-height: 30px;
+    text-indent: 10px;
+    border-left: 2px solid var(--van-primary-color);
+
+    span {
+      margin-left: 10px;
+      color: var(--van-primary-color);
+    }
+  }
+  &-search {
+    display: flex;
+    align-items: center;
+    margin: 20px auto;
+    padding: 20px;
+    height: 80px;
+    overflow: hidden;
+    background-color: var(--white-bg);
+    border: 1px solid #c8c8c8;
+
+    input {
+      flex: 1;
+      padding: 0 10px;
+      height: 100%;
+      font-size: 16px;
+      border: 1px solid #c8c8c8;
+      box-sizing: border-box;
+    }
+    &__btn {
+      flex-shrink: 0;
+      display: flex;
+      align-items: center;
+      justify-content: center;
+      width: 20%;
+      height: 100%;
+      font-size: 16px;
+      color: #fff;
+      background-color: #855b31;
+      border: 1px solid #855b31;
+      cursor: pointer;
+    }
+  }
+  &-tabbar {
+    display: flex;
+    align-items: center;
+    overflow: hidden;
+    padding: 0 20px;
+    height: 78px;
+    background-color: var(--white-bg);
+    border: 1px solid #c8c8c8;
+
+    &__more {
+      p:first-child {
+        display: flex;
+        align-items: center;
+        gap: 2px;
+      }
+    }
+    li {
+      position: relative;
+      text-align: center;
+      padding: 0 10px;
+      height: 34px;
+      white-space: nowrap;
+      color: var(--gray2-text-color);
+
+      &:last-child::after {
+        display: none;
+      }
+      &::after {
+        content: "";
+        position: absolute;
+        top: 0;
+        right: 0;
+        width: 1px;
+        height: 14px;
+        background: var(--gray-text-color);
+      }
+      &.active {
+        color: var(--black-text-color);
+
+        &::after {
+          color: var(--black-text-color);
+        }
+      }
+      p:first-child {
+        cursor: pointer;
+        font-weight: 700;
+        font-size: 14px;
+      }
+      p:last-child {
+        margin-top: 8px;
+        font-size: 12px;
+      }
+    }
+  }
+  &__pagination {
+    display: flex;
+    justify-content: center;
+    padding: 30px 0;
+  }
+  &-item {
+    display: flex;
+    gap: 20px;
+    margin-top: 20px;
+    padding: 20px;
+    background-color: var(--white-bg);
+    border: 1px solid #c8c8c8;
+    cursor: pointer;
+
+    .el-image {
+      flex-shrink: 0;
+      width: 150px;
+      height: 150px;
+    }
+    h3 {
+      font-weight: 700;
+      font-size: 14px;
+      line-height: 30px;
+    }
+    p {
+      font-size: 14px;
+      color: var(--gray2-text-color);
+      line-height: 24px;
+    }
+  }
+}

+ 102 - 0
src/views/Search/index.vue

@@ -0,0 +1,102 @@
+<template>
+  <div class="search-page container">
+    <Breadcrumb :parents="[]" :cur-route="{ name: 'Search' }" />
+
+    <div class="search-page-title">Search<span>378 results</span></div>
+
+    <div
+      class="search-page-search"
+      data-aria-interaction-area
+      tabindex="0"
+      aria-description="You've reached the Search interactive section, please use the tab key to go through the content."
+    >
+      <input />
+      <div class="search-page-search__btn">Search</div>
+    </div>
+
+    <ul
+      class="search-page-tabbar"
+      data-aria-viewport-area
+      tabindex="0"
+      aria-description="You've reached the content area of the Search results page, please use the tab key to navigate through the content."
+    >
+      <li
+        v-for="(item, idx) in TABBAR.slice(0, showMore ? 7 : TABBAR.length)"
+        :key="item.id"
+        tabindex="0"
+        aria-label="Link"
+        :aria-description="item.name"
+        :class="{ active: idx === activeTabbar }"
+      >
+        <p>{{ item.name }}</p>
+        <p>(33)</p>
+      </li>
+
+      <li
+        v-if="showMore"
+        class="search-page-tabbar__more"
+        tabindex="0"
+        aria-label="Button"
+        aria-description="More"
+      >
+        <p @click="showMore = false">
+          More<SvgIcon
+            name="more"
+            color="var(--gray2-text-color)"
+            style="width: 10px; height: 10px"
+          />
+        </p>
+        <p />
+      </li>
+    </ul>
+
+    <ul class="search-page-list">
+      <li class="search-page-item">
+        <ElImage
+          src="https://en.capitalmuseum.org.cn/data/Exhibitions/Current/2.jpg"
+        />
+        <div class="search-page-item__inner">
+          <h3>Splendid Central Axis of Beijing</h3>
+          <p>
+            Starting from the planning and construction of the Central Axis of
+            the Capital Dadu of the Yuan Dynasty and with the ongoing
+            inheritance and carrying forward of past achievements over the later
+            dynasties, the Central Axis of Beijing has finally been made such a
+            magnificent presence as it stands now, with originality and
+            creativeness to be found everywhere along the Axis.
+          </p>
+        </div>
+      </li>
+    </ul>
+
+    <div class="search-page__pagination">
+      <Pagination :total="100" />
+    </div>
+  </div>
+</template>
+
+<script lang="ts" setup>
+import Breadcrumb from "@/components/Breadcrumb/index.vue";
+import Pagination from "@/components/Pagination/index.vue";
+import { ref } from "vue";
+
+const TABBAR = [
+  { id: 1, name: "All Results", cut: "All" },
+  { id: 2, name: "Visit", cut: "Visit" },
+  { id: 3, name: "Exhibitions", cut: "Exhibitions" },
+  { id: 4, name: "Collections", cut: "Collections" },
+  { id: 5, name: "Learn & Engage", cut: "Learn" },
+  { id: 6, name: "Research & Publications", cut: "Research" },
+  { id: 7, name: "Join & Support", cut: "Join" },
+  { id: 8, name: "About", cut: "About" },
+  { id: 9, name: "Events", cut: "Events" },
+  { id: 10, name: "Terms of Use", cut: "Terms" },
+  { id: 11, name: "Employment", cut: "Employment" },
+];
+const showMore = ref(true);
+const activeTabbar = ref(0);
+</script>
+
+<style lang="scss" scoped>
+@import "./index.scss";
+</style>

BIN
src/views/Site/images/1.jpg


BIN
src/views/Site/images/home.jpg


+ 28 - 0
src/views/Site/index.vue

@@ -0,0 +1,28 @@
+<template>
+  <div
+    class="site-index container"
+    tabindex="0"
+    data-aria-viewport-area
+    aria-description="You've reached the content area of the Site Index, please use the tab key to navigate through the content."
+  >
+    <img
+      src="./images/1.jpg"
+      alt=""
+      tabindex="0"
+      aria-label=""
+      aria-description="Site Index"
+    />
+
+    <div class="site-index__home">
+      <img
+        src="./images/home.jpg"
+        alt=""
+        tabindex="0"
+        aria-label="Link"
+        aria-description="Home"
+        @click="$router.push({ name: 'Home' })"
+        @keydown.enter.passive="$router.push({ name: 'Home' })"
+      />
+    </div>
+  </div>
+</template>