Explorar o código

📦 调整细节

快乐的梦鱼 hai 1 mes
pai
achega
0214f53bf6

+ 37 - 0
server/api/ecms/channel/sitemap.ts

@@ -0,0 +1,37 @@
+import { defineEventHandler, EventHandlerRequest } from 'h3';
+import { DB } from '~~/server/db/DB';
+import { createErrorResponse, createSuccessResponse, IResponse } from '~~/server/utils/response';
+import { IChannel } from './[id]';
+
+/**
+ * 获取网站地图
+ */
+export default defineEventHandler<EventHandlerRequest, Promise<IResponse<(IChannel & {
+  childs: IChannel[];
+})[]>>>(async (event) => {
+  try {
+    const result : (IChannel & {
+      childs: IChannel[];
+    })[] = [];
+    const navs = await DB.table('pr_cms_channel')
+      .where('status', 'normal')
+      .where('isnav', 1)
+      .select('*')
+      .get()
+
+    for (const nav of navs) {
+      const childs = await DB.table('pr_cms_channel')
+        .where('status', 'normal')
+        .where('parent_id', nav.id)
+        .select('*')
+        .get();
+      result.push({
+        ...nav,
+        childs,
+      });
+    }
+    return createSuccessResponse(result);
+  } catch (error) {
+    return createErrorResponse(error);
+  }
+});

+ 16 - 7
src/components/Footer.vue

@@ -12,7 +12,18 @@
       </div>
       
       <div class="footer-links">
-        <a v-for="link in footerInfo.links" :key="link.url" :href="link.url" class="footer-link">{{ link.name }}</a>
+        <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">
@@ -35,12 +46,10 @@ const footerInfo = ref({
   workPhone: "0592-5045291",
   address: "厦门市思明区体育路95号 邮编:361012",
   links: [
-    { name: "关于我们", url: "#" },
-    { name: "联系我们", url: "#" },
-    { name: "网站声明", url: "#" },
-    { name: "隐私声明", url: "#" },
-    { name: "使用帮助", url: "#" },
-    { name: "网站地图", url: "#" }
+    { name: "关于我们", url: "/about/" },
+    { name: "联系我们", url: "/about/" },
+    { name: "使用帮助", url: "/channel/57/" },
+    { name: "网站地图", url: "/sitemap" }
   ]
 });
 

+ 2 - 2
src/components/NavBar.vue

@@ -14,8 +14,7 @@
         <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) }">
-              <a v-if="item.type === 'link'" :href="item.outlink" target="_blank">{{ item.name }}</a>
-              <router-link v-else :to="item.url">{{ item.name }}</router-link>
+              <ChannelLink :item="item" />
             </li>
           </ul>
         </div>
@@ -36,6 +35,7 @@ import { ref } from 'vue';
 import { useRoute } from 'vue-router';
 import { solveChannelData } from '~/composeable/InternalData';
 import { useSSrSimpleDataLoader } from '~/composeable/SimpleDataLoader';
+import ChannelLink from './link/ChannelLink.vue';
 
 const route = useRoute();
 

+ 15 - 0
src/components/link/ChannelLink.vue

@@ -0,0 +1,15 @@
+<template>
+  <a v-if="item.type === 'link'" :href="item.outlink" target="_blank">{{ item.name }}</a>
+  <router-link v-else :to="item.url">{{ item.name }}</router-link>
+</template>
+
+<script setup lang="ts">
+import type { IChannel } from '~~/server/api/ecms/channel/[id]';
+
+const props = defineProps({
+  item: {
+    type: Object as PropType<IChannel>,
+    required: true,
+  },
+});
+</script>

+ 1 - 1
src/composeable/InternalData.ts

@@ -10,7 +10,7 @@ export function getNeedJumpToInternalPage(data: IChannel[]) {
   return undefined;
 }
 //处理系统内部使用的分类数据
-export function solveChannelData(data: IChannel[]) : (IChannel & {
+export function solveChannelData<T extends IChannel>(data: T[]) : (T & {
   url: string;
 })[] {
   const specialPages = [] as any[];

+ 78 - 0
src/pages/sitemap.vue

@@ -0,0 +1,78 @@
+<template>
+  <!-- 网站地图 -->
+  <PageContainer title="网站地图">
+    <template #breadcrumb>
+      <a-breadcrumb>
+        <a-breadcrumb-item><router-link to="/">首页</router-link></a-breadcrumb-item>
+        <a-breadcrumb-item>网站地图</a-breadcrumb-item>
+      </a-breadcrumb>
+    </template>
+    <template #sidebar>
+      <Sidebar title="网站地图" />
+    </template>
+    <template #content>
+      <div class="sitemap-content">
+        <div class="sitemap-item" v-for="item in channelData.content.value" :key="item.id">
+          <ChannelLink class="sitemap-header" :item="item" />
+          <div class="sitemap-child-list">
+            <ChannelLink :item="item" />
+            <div v-for="child in item.childs" :key="child.id">
+              <ChannelLink :item="child" />
+            </div>
+          </div>
+        </div>
+      </div>
+    </template>
+  </PageContainer>
+</template>
+
+<script setup lang="ts">
+import { useSSrSimpleDataLoader } from '@/composeable/SimpleDataLoader';
+import { solveChannelData } from '~/composeable/InternalData';
+import ChannelLink from '~/components/link/ChannelLink.vue';
+
+const channelData = await useSSrSimpleDataLoader('channelMap', async () => {
+  const res = await $fetch('/api/ecms/channel/sitemap');
+  if (!res.status)
+    throw new Error(res.message);
+  if (res.data)
+  for (const item of res.data)
+    item.childs = solveChannelData(item.childs || []);
+  return solveChannelData(res.data || []);
+});
+
+</script>
+
+<style lang="scss">
+@use "sass:list";
+@use "sass:math";
+
+.sitemap-content {
+  display: flex;
+  flex-direction: column;
+  gap: 10px;
+
+  .sitemap-header {
+    font-size: 16px;
+    font-weight: bold;
+    color: var(--color-secondary);
+    margin-top: 20px;
+    margin-bottom: 10px;
+    padding-bottom: 10px;
+    border-bottom: 1px dashed var(--color-border);
+  }
+  .sitemap-child-list {
+    display: flex;
+    flex-direction: row;
+    flex-wrap: wrap;
+    gap: 10px;
+  }
+  .sitemap-item {
+    display: flex;
+    flex-direction: column;
+    gap: 10px;
+  }
+}
+</style>
+
+