mirror of
https://github.com/LiuYuYang01/ThriveX-Blog.git
synced 2026-06-05 04:09:28 +08:00
refactor: 整理接口调用与类型定义,优化部分样式
1. 为Cate类型新增count字段定义 2. 移除冗余的next配置注释,调整输出模式配置 3. 统一文章分页接口参数,简化调用逻辑 4. 删除废弃的分类文章数量统计接口 5. 调整搜索组件与多处页面的API调用方式 6. 修正评论接口请求方法与参数处理 7. 调整归档页面圆点定位样式 8. 为标签统计新增Tooltip提示,优化背景样式
This commit is contained in:
@@ -1,10 +1,7 @@
|
||||
/** @type {import('next').NextConfig} */
|
||||
const nextConfig = {
|
||||
// 自定义构建输出目录
|
||||
// distDir: 'next',
|
||||
// 关闭严格模式
|
||||
reactStrictMode: false,
|
||||
// 启用 standalone 输出模式(用于 Docker 部署)
|
||||
output: 'standalone',
|
||||
// 配置图片来源
|
||||
images: {
|
||||
|
||||
@@ -6,15 +6,10 @@ export const getArticleDataAPI = async (id: number, password?: string) => {
|
||||
return await Request<Article>('GET', `/article${!password ? `/${id}` : `/${id}?password=${password}`}`);
|
||||
}
|
||||
|
||||
// 获取文章列表
|
||||
export const getArticleListAPI = async () => {
|
||||
return await Request<Paginate<Article[]>>('GET', `/article`,);
|
||||
}
|
||||
|
||||
// 分页获取文章数据
|
||||
export const getArticlePagingAPI = async (data: Page & { key?: string }) => {
|
||||
// 获取文章列表
|
||||
export const getArticlePagingAPI = async (params?: Page & { key?: string }) => {
|
||||
return await Request<Paginate<Article[]>>('GET', `/article`, {
|
||||
params: { pageNum: data.pageNum, pageSize: data.pageSize, key: data.key }
|
||||
params: params ?? {}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -10,9 +10,4 @@ export const getCateListAPI = async () => {
|
||||
// 获取指定分类中的所有文章
|
||||
export const getCateArticleListAPI = async (id: number, params: Page) => {
|
||||
return await Request<Paginate<Article[]>>('GET', `/article/cate/${id}`, { params })
|
||||
}
|
||||
|
||||
// 获取每个分类的文章数量
|
||||
export const getCateArticleCountAPI = async () => {
|
||||
return await Request<CateArticleCount[]>('GET', '/cate/article/count')
|
||||
}
|
||||
@@ -18,10 +18,10 @@ export const getCommentListAPI = async (paginate?: Page) => {
|
||||
|
||||
// 获取当前文章中所有评论
|
||||
export const getArticleCommentListAPI = async (articleId: number, paginate?: Page) => {
|
||||
return await Request<Paginate<Comment[]>>('POST', `/comment/article/${articleId}`, {
|
||||
return await Request<Paginate<Comment[]>>('GET', `/comment/article/${articleId}`, {
|
||||
params: paginate ? {
|
||||
pageNum: paginate.pageNum ?? 1,
|
||||
pageSize: paginate.pageSize ?? 5,
|
||||
pageNum: paginate.pageNum,
|
||||
pageSize: paginate.pageSize,
|
||||
} : {}
|
||||
});
|
||||
}
|
||||
@@ -2,4 +2,6 @@ import { Rss } from '@/types/app/rss';
|
||||
import { Request } from '@/utils';
|
||||
|
||||
// 获取订阅的内容
|
||||
export const getRssListAPI = (params?: Page) => Request<Paginate<Rss[]>>('GET', `/rss`, { params })
|
||||
export const getRssListAPI = (params?: Page) => Request<Paginate<Rss[]>>('GET', `/rss`, {
|
||||
params: params ?? {}
|
||||
})
|
||||
@@ -144,7 +144,7 @@ export default ({ list }: { list: Article[] }) => {
|
||||
{Object.keys(item.month).map((month, monthIdx) => (
|
||||
<div key={monthIdx} className="relative pl-6">
|
||||
<div className="absolute left-0 top-1.5 w-px h-[calc(100%-0.5rem)] bg-gradient-to-b from-primary/60 to-slate-200 dark:to-slate-600" />
|
||||
<div className="absolute left-0 top-1.5 w-2.5 h-2.5 rounded-full bg-primary shadow-sm ring-2 ring-white dark:ring-black-b" />
|
||||
<div className="absolute -left-1 top-1.5 w-2.5 h-2.5 rounded-full bg-primary shadow-sm ring-2 ring-white dark:ring-black-b" />
|
||||
<div className="rounded-xl bg-slate-50/80 dark:bg-slate-800/30 p-4 border border-slate-100 dark:border-slate-700/50">
|
||||
<div className="flex flex-wrap items-center gap-2 mb-3">
|
||||
<span className="text-lg font-semibold text-slate-700 dark:text-slate-200">
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import Image from 'next/image';
|
||||
import { useEffect, useRef, useState } from 'react';
|
||||
import { getCateArticleCountAPI } from '@/api/cate';
|
||||
import { getCateListAPI } from '@/api/cate';
|
||||
import cate from './svg/cate.svg';
|
||||
|
||||
import * as echarts from 'echarts/core';
|
||||
@@ -16,8 +16,8 @@ export default () => {
|
||||
const [list, setList] = useState<{ value: number; name: string }[]>([]);
|
||||
|
||||
const getCateArticleCount = async () => {
|
||||
const { data } = await getCateArticleCountAPI();
|
||||
setList(data?.map(({ count, name }) => ({ value: count, name })) ?? []);
|
||||
const { data } = await getCateListAPI();
|
||||
setList(data?.result?.map(({ count, name }) => ({ value: count, name })) ?? []);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
|
||||
@@ -3,6 +3,7 @@ import { useEffect, useState } from 'react';
|
||||
import { getTagListAPI } from '@/api/tag';
|
||||
import { Tag } from '@/types/app/tag';
|
||||
import { getRandom } from '@/utils';
|
||||
import { Tooltip } from '@heroui/react';
|
||||
import tag from './svg/tag.svg';
|
||||
|
||||
export default () => {
|
||||
@@ -38,12 +39,13 @@ export default () => {
|
||||
</div>
|
||||
<div className="overflow-auto max-h-[280px] pr-2 grid grid-cols-2 xs:grid-cols-3 sm:grid-cols-4 gap-2 hide_sliding">
|
||||
{list.map((item, index) => (
|
||||
<span
|
||||
key={index}
|
||||
className={`inline-flex justify-center items-center px-3 py-2 text-sm font-medium rounded-xl whitespace-nowrap transition-[transform,box-shadow] hover:scale-105 hover:shadow-md ${tagStyles[getRandom(0, tagStyles.length - 1)]}`}
|
||||
>
|
||||
{item.name}
|
||||
</span>
|
||||
<Tooltip key={index} content={item.name} showArrow={true}>
|
||||
<span
|
||||
className={`flex justify-center items-center min-w-0 px-3 py-2 text-sm font-medium rounded-xl transition-[transform,box-shadow] hover:scale-105 hover:shadow-md ${tagStyles[getRandom(0, tagStyles.length - 1)]} overflow-hidden text-ellipsis whitespace-nowrap`}
|
||||
>
|
||||
{item.name}
|
||||
</span>
|
||||
</Tooltip>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -2,10 +2,10 @@ import Slide from '@/components/Slide';
|
||||
import Starry from '@/components/Starry';
|
||||
import Statis from './components/Statis';
|
||||
import Archiving from './components/Archiving';
|
||||
import { getArticleListAPI } from '@/api/article';
|
||||
import { getArticlePagingAPI } from '@/api/article';
|
||||
|
||||
export default async () => {
|
||||
const { data } = await getArticleListAPI();
|
||||
const { data } = await getArticlePagingAPI();
|
||||
|
||||
return (
|
||||
<>
|
||||
|
||||
@@ -75,11 +75,11 @@ export default function FishpondPage() {
|
||||
<title>🐟 鱼塘 | Rss Feed</title>
|
||||
<meta name="description" content="汇聚好友与订阅的动态鱼塘" />
|
||||
|
||||
<div className="fixed inset-0 overflow-hidden pointer-events-none -z-10 bg-slate-50/50 dark:bg-[#0a0a0a]">
|
||||
<div className="fixed inset-0 overflow-hidden pointer-events-none">
|
||||
<div className="absolute inset-0 bg-[linear-gradient(rgba(148,163,184,0.06)_1px,transparent_1px),linear-gradient(90deg,rgba(148,163,184,0.06)_1px,transparent_1px)] bg-[size:64px_64px]" />
|
||||
<div className="absolute top-[-10%] left-[-10%] w-[40vw] h-[40vw] rounded-full bg-blue-400/10 dark:bg-blue-600/10 blur-[100px] mix-blend-multiply dark:mix-blend-screen" />
|
||||
<div className="absolute top-[20%] right-[-10%] w-[30vw] h-[30vw] rounded-full bg-violet-400/10 dark:bg-violet-600/10 blur-[120px] mix-blend-multiply dark:mix-blend-screen" />
|
||||
<div className="absolute bottom-[-10%] left-[20%] w-[35vw] h-[35vw] rounded-full bg-cyan-400/10 dark:bg-cyan-600/10 blur-[100px] mix-blend-multiply dark:mix-blend-screen" />
|
||||
<div className="absolute -top-1/2 left-1/2 -translate-x-1/2 w-[800px] h-[800px] rounded-full bg-primary/6 blur-[120px]" />
|
||||
<div className="absolute top-1/4 right-0 w-96 h-96 rounded-full bg-violet-400/8 blur-[80px]" />
|
||||
<div className="absolute bottom-1/4 left-0 w-80 h-80 rounded-full bg-cyan-400/8 blur-[80px]" />
|
||||
</div>
|
||||
|
||||
<div className="w-full min-h-screen pt-24 pb-12 px-4 sm:px-6 lg:px-8 max-w-[1920px] mx-auto">
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { MetadataRoute } from 'next';
|
||||
import { getArticleListAPI } from '@/api/article';
|
||||
import { getArticlePagingAPI } from '@/api/article';
|
||||
import { getWebConfigDataAPI } from '@/api/config';
|
||||
import { Web } from '@/types/app/config';
|
||||
|
||||
@@ -11,7 +11,7 @@ export default async function sitemap(): Promise<MetadataRoute.Sitemap> {
|
||||
const baseUrl = webConfig?.url ?? 'https://liuyuyang.net';
|
||||
|
||||
// 获取所有文章
|
||||
const res = await getArticleListAPI();
|
||||
const res = await getArticlePagingAPI();
|
||||
const articles = res?.data.result ?? [];
|
||||
|
||||
// 静态页面
|
||||
|
||||
@@ -27,8 +27,8 @@ export default ({ disclosure }: Props) => {
|
||||
|
||||
const { data } = await getArticlePagingAPI({
|
||||
key,
|
||||
page: 1,
|
||||
size: 10,
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
})
|
||||
|
||||
setData(data);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import Link from 'next/link';
|
||||
import Image from 'next/image';
|
||||
import { getWebConfigDataAPI } from '@/api/config';
|
||||
import { getArticleListAPI } from '@/api/article';
|
||||
import { getArticlePagingAPI } from '@/api/article';
|
||||
import { IoIosArrowForward } from 'react-icons/io';
|
||||
import FireSvg from '@/assets/svg/other/fire.svg';
|
||||
import { Theme } from '@/types/app/config';
|
||||
@@ -10,7 +10,7 @@ import { Article } from '@/types/app/article';
|
||||
const RandomArticle = async () => {
|
||||
const themeResponse = await getWebConfigDataAPI<{ value: Theme }>('theme');
|
||||
const theme = themeResponse?.data?.value as Theme;
|
||||
const { data: article } = await getArticleListAPI();
|
||||
const { data: article } = await getArticlePagingAPI();
|
||||
const ids = theme.reco_article.map((item) => Number(item)) ?? [];
|
||||
const list = article?.result.filter((item: Article) => ids.includes(item.id as number)) ?? [];
|
||||
|
||||
|
||||
1
src/types/app/cate.d.ts
vendored
1
src/types/app/cate.d.ts
vendored
@@ -6,6 +6,7 @@ export interface Cate {
|
||||
icon: string,
|
||||
level: number,
|
||||
type: 'cate' | 'nav',
|
||||
count: number,
|
||||
order: number,
|
||||
children: Cate[]
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user