Przeglądaj źródła

📦 按要求修改

快乐的梦鱼 2 tygodni temu
rodzic
commit
6b7559cf11

BIN
src/assets/images/juzhen.jpg


+ 62 - 3
src/assets/scss/main.scss

@@ -75,9 +75,9 @@ header {
   .inner {
     display: flex;
     flex-direction: row;
-    justify-content: space-between;
+    justify-content: center;
     align-items: center;
-    max-width: var(--container-width);
+    //max-width: var(--container-width);
     margin: 0 auto;
   }
   .logo {
@@ -115,11 +115,36 @@ header {
       margin-right: 10px;
     }
   }
+  .action-buttons {
+    position: relative;
+    display: flex;
+    flex-direction: row;
+    align-items: center;
+    justify-content: center;
+    padding-left: 10px;
+  }
+
   .mobile-menu-toggle {
     display: none;
     width: 60px;
     height: 60px;
   }
+  .extra-menu-toggle {
+    width: 60px;
+    height: 60px;
+    display: flex;
+    background-color: transparent;
+    border: none;
+    padding: 0;
+    margin: 0;
+    cursor: pointer;
+    .iconify {
+      color: var(--color-text);
+    }
+    &:hover {
+      background-color: var(--color-box);
+    }
+  }
 }
 
 button {
@@ -190,6 +215,7 @@ nav.main-nav {
     display: flex;
     justify-content: center;
     align-items: center;
+    flex-wrap: wrap;
     margin-bottom: 0;
   }
   .nav-item {
@@ -214,6 +240,39 @@ nav.main-nav {
   }
 }
 
+.extra-nav-list {
+  position: absolute;
+  display: flex;
+  flex-direction: column;
+  margin-bottom: 0;
+  top: 100%;
+  left: -50px;
+  background-color: var(--color-box);
+  box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
+  padding: 10px;
+  z-index: 100;
+
+  .nav-item {
+    position: relative;
+
+    &.active a {
+      font-weight: bold;
+      color: var(--color-primary);
+    }
+  }
+  a {
+    display: block;
+    color: var(--color-text);
+    padding: 12px 10px;
+    font-weight: 500;
+    white-space: nowrap;
+    transition: background-color 0.3s;
+
+    &:hover, &:active {
+      color: var(--color-primary);
+    }
+  }
+}
 
 .search-bar {
   position: relative;
@@ -660,7 +719,7 @@ footer {
 
   select {
     color: #666;
-    padding: 8px 45px 8px 15px;
+    padding: 8px 15px 8px 15px;
     border: 1px solid rgba(221, 221, 221, 0.6);
     border-radius: 6px;
     background-color: rgba(255, 255, 255, 0.25);

+ 70 - 32
src/components/Footer.vue

@@ -2,37 +2,55 @@
   <!-- 底部 -->
   <footer>
     <div class="container">
-      <div class="footer-select">
-        <select name="related-links" id="related-links" @change="handleLinkChange">
-          <option value="">相关网站链接</option>
-          <option value="http://www.ncha.gov.cn/index.html">国家文物局</option>
-          <option value="https://wlt.fujian.gov.cn/">福建省文化和旅游厅</option>
-          <option value="https://www.xm.gov.cn/">厦门市人民政府</option>
-          <option value="https://www.ihchina.cn/">中国非物质文化遗产网</option>
-        </select>
-      </div>
-      
-      <div class="footer-links">
-        <template v-for="link in footerInfo.links" :key="link.url">
-          <template v-if="link.url.startsWith('http')">
-            <a :href="link.url" class="footer-link">
-              {{ link.name }}
-            </a>
-          </template>
-          <template v-else>
-            <router-link :to="link.url" class="footer-link">
-              {{ link.name }}
-            </router-link>
-          </template>
-        </template>
-      </div>
-      
-      <div class="footer-info">
-        <p>闽公网安备35020302036685号 | <a href="https://beian.miit.gov.cn/">闽ICP备2025115303号-1</a> | 
-          <span id="_ideConac"><a href="https://bszs.conac.cn/sitename?method=show&amp;id=43C18E2A812B1ABAE06310291AACF961" target="_blank"><img id="imgConac" vspace="0" hspace="0" border="0" src="https://dcs.conac.cn/image/blue_error.png" data-bd-imgshare-binded="1"></a></span>
-        </p>
-        <p>联系地址: {{ footerInfo.address }}</p>
-        <p>联系电话: {{ footerInfo.contactPhone }} | 工作电话: {{ footerInfo.workPhone }}</p>
+      <div class="row d-flex flex-row justify-content-between">
+        <div class="col d-none d-lg-block col-lg-4">
+        </div>
+        <div class="col col-sm-12 col-md-6 col-lg-4">
+          <div class="footer-select">
+            <select name="related-links-superior" id="related-links-superior" @change="handleLinkChange">
+              <option value="">上级主管部门</option>
+              <option value="http://www.ncha.gov.cn/index.html">国家文物局</option>
+              <option value="https://wlt.fujian.gov.cn/">福建省文化和旅游厅</option>
+            </select>
+            <select name="related-links-municipal" id="related-links-municipal" @change="handleLinkChange">
+              <option value="">市政府部门网站</option>
+              <option value="https://www.xm.gov.cn/">厦门市人民政府</option>
+            </select>
+            <select name="related-links-units" id="related-links-units" @change="handleLinkChange">
+              <option value="">局属单位</option>
+              <option value="https://www.ihchina.cn/">中国非物质文化遗产网</option>
+              <option value="https://www.xmlib.net/">厦门市图书馆</option>
+              <option value="https://www.xmwhg.com.cn/">厦门市文化馆</option>
+              <option value="http://xmmuseum.com/">厦门市博物馆</option>
+            </select>
+          </div>
+          
+          <div class="footer-links">
+            <template v-for="link in footerInfo.links" :key="link.url">
+              <template v-if="link.url.startsWith('http')">
+                <a :href="link.url" class="footer-link">
+                  {{ link.name }}
+                </a>
+              </template>
+              <template v-else>
+                <router-link :to="link.url" class="footer-link">
+                  {{ link.name }}
+                </router-link>
+              </template>
+            </template>
+          </div>
+          
+          <div class="footer-info">
+            <p>闽公网安备35020302036685号 | <a href="https://beian.miit.gov.cn/">闽ICP备2025115303号-1</a> | 
+              <span id="_ideConac"><a href="https://bszs.conac.cn/sitename?method=show&amp;id=43C18E2A812B1ABAE06310291AACF961" target="_blank"><img id="imgConac" vspace="0" hspace="0" border="0" src="https://dcs.conac.cn/image/blue_error.png" data-bd-imgshare-binded="1"></a></span>
+            </p>
+            <p>联系地址: {{ footerInfo.address }}</p>
+            <p>联系电话: {{ footerInfo.contactPhone }} | 工作电话: {{ footerInfo.workPhone }}</p>
+          </div>
+        </div>
+        <div class="col col-sm-12 col-md-6 col-lg-4 position-relative d-flex justify-content-end">
+          <img src="@/assets/images/juzhen.jpg" alt="新媒体矩阵" class="media-matrix">
+        </div>
       </div>
     </div>
   </footer>
@@ -63,4 +81,24 @@ function handleLinkChange(event: Event) {
   }
 }
 
-</script>
+</script>
+
+<style scoped lang="scss">  
+.footer-select {
+  display: flex;
+  flex-direction: row;
+  align-items: center;
+  justify-content: space-between;
+  gap: 10px;
+
+  select {
+    width: 33%;;
+  }
+}
+.media-matrix {
+  width: 100%;
+  height: 100%;
+  max-width: 250px;
+  object-fit: cover;
+}
+</style>

+ 50 - 9
src/components/NavBar.vue

@@ -11,16 +11,35 @@
       </div>
       <!-- 导航 -->
       <nav class="main-nav" :class="{ show: isMenuOpen }">
-        <div class="container">
-          <ul class="nav-list">
-            <li v-for="item in navItems.content.value" :key="item.url" class="nav-item" :class="{ active: isActive(item.url) }">
-              <ChannelLink :item="item" />
-            </li>
-          </ul>
-        </div>
+        <ul class="nav-list">
+          <li v-for="item in navItemsFinal" :key="item.url" class="nav-item" :class="{ active: isActive(item.url) }">
+            <ChannelLink :item="item" />
+          </li>
+        </ul>
       </nav>
-      <div class="d-flex flex-row align-items-center">
-        <button class="mobile-menu-toggle" @click="toggleMenu"><Icon name="material-symbols:menu" /></button>
+      <div class="action-buttons">
+        <button 
+          v-if="navItemsOverflow"
+          class="extra-menu-toggle" 
+          @click="toggleExtraMenu">
+          <Icon name="material-symbols-light:more-horiz" size="34" />
+        </button>
+        <ul class="extra-nav-list" v-if="isExtraMenuOpen">
+          <li 
+            v-for="item in navItemsExtra" :key="item.url"
+            class="nav-item" 
+            :class="{ active: isActive(item.url) }"
+            @click="toggleExtraMenu"
+          >
+            <ChannelLink :item="item" />
+          </li>
+        </ul>
+
+        <button
+          class="mobile-menu-toggle" 
+          @click="toggleMenu">
+          <Icon name="material-symbols:menu" size="34" />
+        </button>
         <div class="search-bar">
           <button @click="toggleSearch"><Icon name="material-symbols:search-rounded" /></button>
           <input type="text" placeholder="搜索..." v-model="keyword" @blur="hideSearch" @keydown.enter="goSearch" :class="{ show: isSearchOpen }">
@@ -36,6 +55,7 @@ import { useRoute } from 'vue-router';
 import { solveChannelData } from '~/composeable/InternalData';
 import { useSSrSimpleDataLoader } from '~/composeable/SimpleDataLoader';
 import ChannelLink from './link/ChannelLink.vue';
+import { useWindowSizeListener } from '~/composeable/WindowSizeListener';
 
 const route = useRoute();
 
@@ -44,7 +64,25 @@ const navItems = await useSSrSimpleDataLoader('navItems', async () => {
   const items = solveChannelData(data);
   return items;
 });
+const navItemsFinal = computed(() => {
+  if (navItemsOverflow.value)
+    return navItems.content.value?.slice(0, 7);
+  return navItems.content.value;
+});
+const navItemsExtra = computed(() => {
+  if (navItemsOverflow.value)
+    return navItems.content.value?.slice(7);
+  return [];
+});
+const { windowWidth } = useWindowSizeListener();
+const navItemsOverflow = computed(() => 
+  import.meta.client && (windowWidth.value > 992 && windowWidth.value < 1400) 
+  && (navItems.content.value?.length || 0) > 8
+);
+
+
 const isMenuOpen = ref(false);
+const isExtraMenuOpen = ref(false);
 const isSearchOpen = ref(false);
 const keyword = ref('');
 
@@ -59,6 +97,9 @@ function toggleMenu() {
 function toggleSearch() {
   isSearchOpen.value = !isSearchOpen.value;
 }
+function toggleExtraMenu() {
+  isExtraMenuOpen.value = !isExtraMenuOpen.value;
+}
 function hideSearch() {
   isSearchOpen.value = false;
 }

+ 22 - 0
src/composeable/WindowSizeListener.ts

@@ -0,0 +1,22 @@
+export function useWindowSizeListener() {
+  const windowWidth = ref(import.meta.client ? window.innerWidth : 0);
+  const windowHeight = ref(import.meta.client ? window.innerHeight : 0);
+
+  function updateWindowSize() {
+    windowWidth.value = window.innerWidth;
+    windowHeight.value = window.innerHeight;
+  }
+
+  onMounted(() => {
+    window.addEventListener('resize', updateWindowSize);
+  });
+  onUnmounted(() => {
+    window.removeEventListener('resize', updateWindowSize);
+  });
+
+
+  return {
+    windowWidth,
+    windowHeight,
+  }
+}

+ 1 - 1
src/pages/about.vue

@@ -26,7 +26,7 @@
                 电话: 0592-2085737
               </li>
               <li class="info-item">
-                <Icon name="material-symbols:email" />
+                <Icon name="material-symbols:attach-email" />
                 邮箱: hlspt@xm.gov.cn
               </li>
               <li class="info-item">

+ 47 - 37
src/pages/index.vue

@@ -35,7 +35,30 @@
         <!-- 通知公告和热点新闻 -->
         <div class="row">
 
-          <div class="col col-sm-12 col-md-6 col-lg-6 notices-list">
+          <div class="col col-sm-12 col-md-6 col-lg-6">
+            <Carousel v-bind="carouselConfig">
+              <Slide 
+                v-for="(item, key) in recommendArticles.content.value"
+                :key="key"
+                class="featured-image bg-secondary"
+                :style="{ 'background-image': `url(${item.image})`, 'background-size': 'cover' }"
+              >
+                <router-link :to="'/page/' + item.id">
+                  <img :src="item.image" :alt="item.desc || item.title" style="width: 100%; height: 100%; object-fit: contain;">
+                  <div class="caption">
+                    <h3>{{ item.title }}</h3>
+                    <p>{{ item.desc || '' }}</p>
+                  </div>
+                </router-link>
+              </Slide>
+              <template #addons>
+                <Navigation />
+                <Pagination />
+              </template>
+            </Carousel>
+          </div>
+
+          <div class="d-flex flex-column col col-sm-12 col-md-6 col-lg-6 notices-list">
             <div class="section-title">
               <div class="d-flex flex-row align-items-center">
                 <h2 id="notices-button" @click="currentTab = 'notices'" :class="{'active': currentTab === 'notices'}" class="button icon">通知公告</h2>
@@ -49,7 +72,7 @@
               </router-link>
             </div>
 
-            <div v-if="currentTab === 'notices'" id="notices-list" class="notices-content">
+            <div v-if="currentTab === 'notices'" id="notices-list" class="notices-content flex-one flex-grow-1">
               <SimplePageContentLoader :loader="notices" :showEmpty="!notices.content.value?.items?.length">
                 <div v-for="notice in notices.content.value?.items" :key="notice.id" class="notice-item">
                   <div>
@@ -60,7 +83,7 @@
                 </div>
               </SimplePageContentLoader>
             </div>
-            <div v-if="currentTab === 'hot'" id="hot-news-list" class="news-content">
+            <div v-if="currentTab === 'hot'" id="hot-news-list" class="news-content flex-one flex-grow-1">
               <SimplePageContentLoader :loader="hot" :showEmpty="!hot.content.value?.items?.length">
                 <div v-for="item in hot.content.value?.items" :key="item.id" class="news-item">
                   <router-link :to="'/page/' + item.id" class="title">{{ item.title }}</router-link>
@@ -69,29 +92,7 @@
               </SimplePageContentLoader>
             </div>
 
-          </div>
-
-          <div class="col col-sm-12 col-md-6 col-lg-6">
-            <Carousel v-bind="carouselConfig">
-              <Slide 
-                v-for="(item, key) in recommendArticles.content.value"
-                :key="key"
-                class="featured-image bg-secondary"
-                :style="{ 'background-image': `url(${item.image})`, 'background-size': 'cover' }"
-              >
-                <router-link :to="'/page/' + item.id">
-                  <img :src="item.image" :alt="item.desc || item.title" style="width: 100%; height: 100%; object-fit: contain;">
-                  <div class="caption">
-                    <h3>{{ item.title }}</h3>
-                    <p>{{ item.desc || '' }}</p>
-                  </div>
-                </router-link>
-              </Slide>
-              <template #addons>
-                <Navigation />
-                <Pagination />
-              </template>
-            </Carousel>
+            <!-- 学习强国 -->
             <div class="d-flex flex-row justify-content-between">
               <a href="http://cpc.people.com.cn/GB/67481/448544/index.html" class="w-50">
                 <img src="https://wlj.xm.gov.cn/ztzl/202211/W020221213510920336898.jpg" class="mt-3" style="width: 100%; height:130px;object-fit:cover;" /> 
@@ -195,13 +196,13 @@
           <img class="title" src="@/assets/images/box-service.png" alt="公共服务">
           <div class="services-grid">
 
-            <div class="service-card" @click="handleServiceClick('volunteer')">
+            <a class="service-card" href="https://mp.weixin.qq.com/s/r6Tgsp068VNo4tVIA2sEHA" target="_blank">
               <img class="icon" src="@/assets/images/icon-explore.png">
               <h3>志愿者招募</h3>
-              <a href="#" class="service-link">
+              <div class="service-link">
                 <Icon name="material-symbols-light:chevron-right" />
-              </a>
-            </div>
+              </div>
+            </a>
 
             <div class="service-card" @click="handleServiceClick('activity')">
               <img class="icon" src="@/assets/images/icon-join.png">
@@ -211,12 +212,12 @@
               </a>
             </div>
 
-            <div class="service-card" @click="handleServiceClick('contact')">
+            <div class="service-card" @click="router.push('/about/')">
               <img class="icon" src="@/assets/images/icon-contract.png">
               <h3>联系咨询通道</h3>
-              <a href="#" class="service-link">
+              <RouterLink to="/about/" class="service-link">
                 <Icon name="material-symbols-light:chevron-right" />
-              </a>
+              </RouterLink>
             </div>
           </div>
         </div>
@@ -237,7 +238,9 @@ import CarouselItem3 from '@/assets/images/board1/3.jpg';
 import CarouselItem4 from '@/assets/images/board1/4.jpg';
 import CarouselItem5 from '@/assets/images/board1/5.jpg';
 import type { ICarousel } from '~~/server/api/ecms/carousel';
+import { useRouter } from 'vue-router';
 
+const router = useRouter();
 const carouselConfig = {
   itemsToShow: 1,
   wrapAround: true,
@@ -303,10 +306,17 @@ function handleImageClick(image: ICarousel) {
   window.open(image.url || image.image, '_blank');
 }
 function handleServiceClick(service: string) {
-  Modal.info({
-    title: '提示',
-    content: '网站正在进行内部测试,暂未对外开放功能,敬请期待。',
-  });
+  if (service === 'activity') {
+    Modal.info({
+      title: '提示',
+      content: '暂无最新活动',
+    });
+  } else {
+    Modal.info({
+      title: '提示',
+      content: '网站正在进行内部测试,暂未对外开放功能,敬请期待。',
+    });
+  }
 }