From f81908a7eaa6267c0d8f382de71a2e84b58f57b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Liu=20=E5=AE=87=E9=98=B3?= Date: Fri, 25 Oct 2024 16:10:29 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=8C=E6=88=90=E6=96=87=E7=AB=A0=E5=BD=92?= =?UTF-8?q?=E7=BA=B3=E5=9F=BA=E6=9C=AC=E5=B8=83=E5=B1=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/data/page.tsx | 146 +++++++++++++++++++++++++++++ src/assets/svg/other/archiving.svg | 1 + src/styles/index.scss | 15 +++ src/utils/request.ts | 45 ++++++++- 4 files changed, 204 insertions(+), 3 deletions(-) create mode 100644 src/app/data/page.tsx create mode 100644 src/assets/svg/other/archiving.svg diff --git a/src/app/data/page.tsx b/src/app/data/page.tsx new file mode 100644 index 0000000..70b4c1c --- /dev/null +++ b/src/app/data/page.tsx @@ -0,0 +1,146 @@ +"use client" + +import { useEffect, useState } from "react" +import { getArticleListAPI } from '@/api/article' +import { Article } from "@/types/app/article" +import Swiper from "@/components/Swiper"; +import Starry from "@/components/Starry"; +import { Accordion, AccordionItem } from "@nextui-org/react"; +import archiving from '@/assets/svg/other/archiving.svg' + +interface MonthData { + total: number; + list: Article[]; + wordCount: number; +} + +interface YearData { + year: number; + total: number; + month: Record; + wordCount: number; +} + +const Title = ({ data }: { data: YearData }) => { + return ( +
+
{data.year} 年
+
总共发布了:{data.total} 篇文章
+
总字数约:{(data.wordCount / 1000).toFixed(2)}K
+
+ ) +} + +export default () => { + const [list, setList] = useState([]) + const getArticleList = async () => { + const { data } = await getArticleListAPI() + const result = groupByYearAndMonth(data); + // 从早到晚排序 + result.sort((a, b) => b.year - a.year) + setList(result) + } + + // 将文章进行分组 + function groupByYearAndMonth(data: Article[]): YearData[] { + const groupedData: Record = {}; + + data.forEach(item => { + const date = new Date(+item.createTime!); + const year = date.getFullYear(); + const month = date.getMonth() + 1; + const wordCount = item.content ? item.content.length : 0; + + if (!groupedData[year]) { + groupedData[year] = { year, total: 0, month: {}, wordCount: 0 }; + } + + if (!groupedData[year].month[month]) { + groupedData[year].month[month] = { total: 0, list: [], wordCount: 0 }; + } + + groupedData[year].month[month].list.push(item); + groupedData[year].month[month].total++; + groupedData[year].total++; + groupedData[year].wordCount += wordCount; + }); + + return Object.values(groupedData); + } + + useEffect(() => { + getArticleList() + }, []) + + const defaultContent = + "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat."; + + + return ( + <> + 数据统计 + + + + {/* 星空背景组件 */} + + +
+
数据统计
+
+
+ +
+

归档 文章归纳

+ + + { + list.map((item, index) => ( + }> + {defaultContent} + + )) + } + +
+ + ) +} \ No newline at end of file diff --git a/src/assets/svg/other/archiving.svg b/src/assets/svg/other/archiving.svg new file mode 100644 index 0000000..810f92a --- /dev/null +++ b/src/assets/svg/other/archiving.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/styles/index.scss b/src/styles/index.scss index 4a925bc..eab6fa9 100644 --- a/src/styles/index.scss +++ b/src/styles/index.scss @@ -33,6 +33,21 @@ body { animation: 5s linear infinite miniShape; } +// 文本标记样式 +.textMarkSty { + position: relative; + + &::after { + content: ""; + position: absolute; + top: 50%; + left: 0; + width: 50%; + height: 10px; + background-color: #539dfd80; + } +} + @keyframes miniShape { 0%, diff --git a/src/utils/request.ts b/src/utils/request.ts index 7a531e2..ee69b03 100644 --- a/src/utils/request.ts +++ b/src/utils/request.ts @@ -1,5 +1,5 @@ -// const url = "http://localhost:9003/api" -const url = "https://api.liuyuyang.net/api" +const url = "http://localhost:9003/api" +// const url = "https://api.liuyuyang.net/api" export default async (method: string, api: string, data?: any, caching = true) => { const res = await fetch(`${url}${api}`, { @@ -16,4 +16,43 @@ export default async (method: string, api: string, data?: any, caching = true }) return res.json() as Promise>; -} \ No newline at end of file +} + +// [ +// { +// year: 2024, +// total: 3, // 结果是每个月份的total +// month: [ +// { +// 1: { +// total: 2, // 文章的数量 +// list: [文章数据1, 文章数据2] +// }, +// 2: { +// total: 1, +// list: [文章数据1] +// }, +// } +// ] +// }, +// { +// year: 2023, +// total: 2, // 结果是每个月份的total +// month: [ +// { +// 1: { +// total: 1, // 文章的数量 +// list: [文章数据1] +// }, +// 2: { +// total: 0, +// list: [] +// }, +// 3: { +// total: 1, +// list: [文章数据1] +// } +// } +// ] +// } +// ] \ No newline at end of file