瀏覽代碼

feat: save

gemercheung 6 月之前
父節點
當前提交
7e60b743d5

+ 1 - 1
packages/web/src/api/menu.ts

@@ -19,5 +19,5 @@ export type CategoryItem = {
   remark: string
 }
 export const getMenuList = (): Promise<ResultData<MenuItem[]>> => request.get('web/menu')
-export const getCategoryTree = (id: number): Promise<ResultData<CategoryItem[]>> =>
+export const getCategoryTree = (id: number): Promise<ResultData<CategoryItem | CategoryItem[]>> =>
   request.get('web/category/tree', { id })

+ 150 - 0
packages/web/src/pages/showcate/[id].vue

@@ -0,0 +1,150 @@
+<template>
+  <div class="max-w-screen-xl content my-0 mx-auto text-size-base overflow-hidden">
+
+    <div>
+      <div class="breadcrumb my-[30px] pb-[20px] bb-1px_#EBEBEB" role="navigation">
+        <n-breadcrumb separator=">" v-if="breadcrumb">
+          <template v-for="(bread, index) in breadcrumb" :key="index">
+            <n-breadcrumb-item :clickable="false"> {{ bread.title }}</n-breadcrumb-item>
+          </template>
+        </n-breadcrumb>
+      </div>
+
+      <div v-if="currentCate">
+        <n-h2 class="mb-10"> {{ currentCate.title }}</n-h2>
+      </div>
+
+      <div class="w-full flex flex-row flex-nowrap">
+
+        <div class="flex-basis-[240px] flex-grow-0 flex-shrink-0 br-1px_#EBEBEB">
+          <n-tree class="left-tree" v-if="mainCategories" block-line :data="mainCategories.children"
+            :default-expanded-keys="defaultExpandedKeys" :node-props="nodeProps" key-field="id" label-field="title"
+            children-field="children" selectable>
+            <template #empty></template>
+          </n-tree>
+        </div>
+
+        <div class="flex-1 w-[calc(100%-80px)] px-[40px] mb-[120px] overflow-hidden">
+          <template v-if="articleList.length > 0">
+            <ul class="cate-list">
+              <li v-for="article in articleList" :key="article.id">
+                <span @click="handleToArticle(article)">{{ article.title }}</span>
+              </li>
+            </ul>
+          </template>
+          <template v-else>
+            <div class="pt-20">
+              <n-empty />
+            </div>
+
+          </template>
+
+        </div>
+
+        <div class="flex-basis-[240px] flex-grow-0 flex-shrink-0">
+
+        </div>
+      </div>
+    </div>
+  </div>
+</template>
+
+<route>
+{
+name: "showcate",
+  meta: {
+  layout: "base"
+  }
+}
+</route>
+
+<script setup lang="ts">
+import {
+  type ArticleDetailType,
+  type CategoryItem,
+  getArticlesByCateId,
+  getCategoryTree
+} from '@/api'
+
+import { NH2, NBreadcrumb, NBreadcrumbItem, NTree, NEmpty } from 'naive-ui'
+import type { TreeOption } from 'naive-ui'
+
+const route = useRoute()
+const router = useRouter()
+
+const params = route.params as {
+  id?: number
+}
+const breadcrumb = ref<CategoryItem[]>([])
+const currentCate = ref<CategoryItem | undefined>()
+const mainCategories = ref<CategoryItem>()
+const articleList = ref<ArticleDetailType[]>([])
+const defaultExpandedKeys = ref<number[]>([])
+
+
+const nodeProps = ({ option }: { option: TreeOption }) => {
+  return {
+    async onClick() {
+      console.log('option', option.id)
+      router.replace(`/showcate/${option.id}`)
+      setTimeout(() => {
+        location.reload()
+      }, 500)
+    },
+  }
+}
+
+onMounted(async () => {
+
+  if (params.id) {
+    const res = await getArticlesByCateId(params.id);
+    if (res) {
+      articleList.value = res.data as ArticleDetailType[]
+    }
+    const res1 = await getCategoryTree(params.id)
+    if (res1) {
+      mainCategories.value = res1.data as CategoryItem
+    }
+  }
+})
+
+const handleToArticle = (article: ArticleDetailType) => {
+  console.log('article', article)
+  router.replace(`/showdoc/${article.id}`)
+}
+</script>
+
+<style lang="scss" scoped>
+:deep(.content-html img) {
+  width: 100% !important;
+  height: auto;
+}
+
+:deep(.left-tree) {
+  --n-node-content-height: 40px !important;
+  //--n-node-color-hover: rgba(6,97,201,0.06) !important;
+  //border-right: 1px solid #e5e7eb;
+
+  .n-tree-node-wrapper {
+    width: 240px;
+    font-size: 16px;
+  }
+}
+
+.articleNear {
+  &:hover {
+    cursor: pointer;
+    color: #5a5a5a;
+  }
+}
+
+.cate-list {
+  li {
+    &:hover {
+      text-decoration: underline;
+      cursor: pointer;
+      // display: block;
+    }
+  }
+}
+</style>

+ 7 - 17
packages/web/src/pages/showdoc/[id].vue

@@ -14,7 +14,7 @@
       </div>
       <div class="w-full flex flex-row flex-nowrap">
         <div class="flex-basis-[240px] flex-grow-0 flex-shrink-0 br-1px_#EBEBEB">
-          <n-tree class="left-tree" v-if="mainCategories.children" block-line :data="mainCategories.children"
+          <n-tree class="left-tree" v-if="mainCategories" block-line :data="mainCategories.children"
             :default-expanded-keys="defaultExpandedKeys" :node-props="nodeProps" key-field="id" label-field="title"
             children-field="children" selectable />
 
@@ -54,7 +54,6 @@
               </span>
             </div>
           </div>
-
         </div>
 
         <div class="flex-basis-[240px] flex-grow-0 flex-shrink-0">
@@ -89,7 +88,7 @@ import {
   getArticleDetail,
   getArticleCount,
   getCategoryTree,
-  getArticlesByCateId,
+  // getArticlesByCateId,
   getNearArticles,
 } from '@/api'
 import { htmlToTree, createAnchorNames, dayjs, findNodeById, findBreadcrumbPath } from '@/utils'
@@ -114,20 +113,11 @@ const articleNear = ref<ArticleDetailType[]>([])
 const nodeProps = ({ option }: { option: TreeOption }) => {
   return {
     async onClick() {
-      // window.$message.info(`[Click] ${option.title},[ID] ${option.id} `)
-      const res = await getArticlesByCateId(+(option.id as string))
-      // console.log(res.data)
-      if (res.data && res.data.length > 0) {
-        const articleId = res.data[0].id
-        console.log('articleId', articleId)
-        // location.reload()
-        router.replace(`/showdoc/${articleId}`)
-        setTimeout(() => {
-          location.reload()
-        }, 500)
-      } else {
-        window.$message.info(`当前类别没有相关联的文章!`)
-      }
+      console.log('option', option.id)
+      router.replace(`/showcate/${option.id}`)
+      setTimeout(() => {
+        location.reload()
+      }, 500)
     },
   }
 }

+ 1 - 0
packages/web/typed-router.d.ts

@@ -21,6 +21,7 @@ declare module 'vue-router/auto-routes' {
     'index': RouteRecordInfo<'index', '/', Record<never, never>, Record<never, never>>,
     '/about': RouteRecordInfo<'/about', '/about', Record<never, never>, Record<never, never>>,
     'search': RouteRecordInfo<'search', '/search', Record<never, never>, Record<never, never>>,
+    'showcate': RouteRecordInfo<'showcate', '/showcate/:id', { id: ParamValue<true> }, { id: ParamValue<false> }>,
     'showdoc': RouteRecordInfo<'showdoc', '/showdoc/:id', { id: ParamValue<true> }, { id: ParamValue<false> }>,
   }
 }