2026-06-22 14:43:46 +08:00
|
|
|
import type { Metadata } from 'next';
|
|
|
|
|
import { publicApi } from '@/lib/services';
|
|
|
|
|
import { NewsCard } from '@/components/front/NewsCard';
|
2026-06-22 15:49:58 +08:00
|
|
|
import type { NewsCategory } from '@/lib/types';
|
2026-06-22 14:43:46 +08:00
|
|
|
|
|
|
|
|
export const metadata: Metadata = {
|
|
|
|
|
title: '新闻资讯',
|
|
|
|
|
description: '公司动态与行业新闻。',
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export const revalidate = 60;
|
|
|
|
|
|
|
|
|
|
interface PageProps {
|
|
|
|
|
searchParams: { categoryId?: string; keyword?: string; page?: string };
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export default async function NewsPage({ searchParams }: PageProps) {
|
|
|
|
|
const page = Number(searchParams.page ?? 1);
|
|
|
|
|
const categoryId = searchParams.categoryId ? Number(searchParams.categoryId) : undefined;
|
|
|
|
|
|
|
|
|
|
const [categories, newsRes] = await Promise.all([
|
2026-06-22 15:49:58 +08:00
|
|
|
publicApi.getNewsCategories().catch(() => [] as NewsCategory[]),
|
2026-06-22 14:43:46 +08:00
|
|
|
publicApi
|
|
|
|
|
.getNews({ page, pageSize: 10, categoryId, keyword: searchParams.keyword })
|
|
|
|
|
.catch(() => ({ list: [], total: 0, page, pageSize: 10 })),
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
<div className="container-page py-12">
|
|
|
|
|
<h1 className="text-3xl font-bold text-gray-900">新闻资讯</h1>
|
|
|
|
|
<p className="mt-2 text-sm text-gray-500">共 {newsRes.total} 条</p>
|
|
|
|
|
|
|
|
|
|
<div className="mt-6 flex flex-wrap gap-2">
|
|
|
|
|
<a
|
|
|
|
|
href="/news"
|
|
|
|
|
className={`rounded-full border px-3 py-1 text-sm ${
|
|
|
|
|
!categoryId
|
|
|
|
|
? 'border-brand-600 bg-brand-50 text-brand-700'
|
|
|
|
|
: 'border-gray-200 text-gray-600 hover:border-brand-300'
|
|
|
|
|
}`}
|
|
|
|
|
>
|
|
|
|
|
全部
|
|
|
|
|
</a>
|
|
|
|
|
{categories.map((c) => (
|
|
|
|
|
<a
|
|
|
|
|
key={c.id}
|
|
|
|
|
href={`/news?categoryId=${c.id}`}
|
|
|
|
|
className={`rounded-full border px-3 py-1 text-sm ${
|
|
|
|
|
categoryId === c.id
|
|
|
|
|
? 'border-brand-600 bg-brand-50 text-brand-700'
|
|
|
|
|
: 'border-gray-200 text-gray-600 hover:border-brand-300'
|
|
|
|
|
}`}
|
|
|
|
|
>
|
|
|
|
|
{c.name}
|
|
|
|
|
</a>
|
|
|
|
|
))}
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div className="mt-8 grid gap-4 md:grid-cols-2">
|
|
|
|
|
{newsRes.list.map((n) => (
|
|
|
|
|
<NewsCard key={n.id} news={n} />
|
|
|
|
|
))}
|
|
|
|
|
</div>
|
|
|
|
|
{newsRes.list.length === 0 && (
|
|
|
|
|
<div className="mt-8 flex h-32 items-center justify-center rounded-md border border-dashed text-sm text-gray-400">
|
|
|
|
|
暂无新闻
|
|
|
|
|
</div>
|
|
|
|
|
)}
|
|
|
|
|
|
|
|
|
|
{newsRes.total > 10 && (
|
|
|
|
|
<div className="mt-8 flex items-center justify-center gap-2">
|
|
|
|
|
<a
|
|
|
|
|
href={`/news?${new URLSearchParams({
|
|
|
|
|
...(searchParams as Record<string, string>),
|
|
|
|
|
page: String(Math.max(1, page - 1)),
|
|
|
|
|
}).toString()}`}
|
|
|
|
|
className={`rounded border px-3 py-1 text-sm ${
|
|
|
|
|
page <= 1 ? 'pointer-events-none opacity-50' : 'hover:bg-gray-50'
|
|
|
|
|
}`}
|
|
|
|
|
>
|
|
|
|
|
上一页
|
|
|
|
|
</a>
|
|
|
|
|
<span className="text-sm text-gray-600">
|
|
|
|
|
{page} / {Math.ceil(newsRes.total / 10)}
|
|
|
|
|
</span>
|
|
|
|
|
<a
|
|
|
|
|
href={`/news?${new URLSearchParams({
|
|
|
|
|
...(searchParams as Record<string, string>),
|
|
|
|
|
page: String(page + 1),
|
|
|
|
|
}).toString()}`}
|
|
|
|
|
className="rounded border px-3 py-1 text-sm hover:bg-gray-50"
|
|
|
|
|
>
|
|
|
|
|
下一页
|
|
|
|
|
</a>
|
|
|
|
|
</div>
|
|
|
|
|
)}
|
|
|
|
|
</div>
|
|
|
|
|
);
|
|
|
|
|
}
|