blob: a994e7c292a9974c0abc99cdbadcb6935da96aac [file] [log] [blame]
LaoeGaoci388f7762025-05-29 22:24:35 +08001'use client';
LaoeGaocia82dfe92025-04-01 20:17:11 +08002
LaoeGaoci388f7762025-05-29 22:24:35 +08003import React, { useEffect, useState, useRef } from "react";
4import { Button } from 'primereact/button';
5import { Card } from 'primereact/card';
6import { Image } from 'primereact/image';
7import { Carousel } from 'primereact/carousel';
8// 页面跳转
9import { useRouter } from 'next/navigation';
10// 消息提醒
11import { Toast } from 'primereact/toast';
12// 评分图标
13import { Fire } from '@icon-park/react';
14// 接口传输
15import axios from 'axios';
16
17// 样式
18import './main.scss';
19// 模组列表数据
20interface Mod {
21 resourceId: number;
22 resourceName: string;
23 resourcePicture: string;
24 likes: number;
25}
26interface ModList {
27 records: Mod[];
28}
29// 地图列表数据
30interface Map {
31 resourceId: number;
32 resourceName: string;
33 resourcePicture: string;
34 likes: number;
35}
36interface MapList {
37 records: Mod[];
38}
39// 帖子列表数据
40interface Modpack {
41 resourceId: number;
42 resourceName: string;
43 resourcePicture: string;
44 likes: number;
45}
46interface ModpackList {
47 records: Modpack[];
48}
49// 帖子列表数据
50interface Texture {
51 resourceId: number;
52 resourceName: string;
53 resourcePicture: string;
54 likes: number;
55}
56interface TextureList {
57 records: Texture[];
58}
59// 热门资源幻灯片数据
60interface HotResource {
61 resourceId: number;
62 resourceName: string;
63 resourcePicture: string;
64 likes: number;
65 dowloads: number;
66 seeds: number;
67}
68interface HotResourceList {
69 records: HotResource[];
70}
71// 站点统计数据
72interface Stats {
73 threadCount: number;
74 downloadCount: number;
75 authorCount: number;
76 resourceCount: number;
77}
78// 悬赏列表
79interface Reward {
80 rewardId: number;
81 userId: number;
82 rewardPicture: string;
83 rewardName: string;
84 createdAt: string;
85 rewardDescription: string;
86 price: number;
87}
88interface RewardList {
89 total: number; // 总记录数
90 records: Reward[];
91}
92// 主页
LaoeGaocia82dfe92025-04-01 20:17:11 +080093export default function Home() {
LaoeGaoci388f7762025-05-29 22:24:35 +080094 // 模组列表
95 const [mods, setMods] = useState<Mod[]>([]);
96 // 悬赏列表
97 const [reward, setReweard] = useState<Reward[]>([]);
98 // 地图列表
99 const [maps, setMaps] = useState<Map[]>([]);
100 // 整合包列表
101 const [modpacks, setModpacks] = useState<Modpack[]>([]);
102 // 材质包列表
103 const [textures, setTextures] = useState<Texture[]>([]);
104 // 热门资源列表
105 const [hotResources, setHotResources] = useState<HotResource[]>([]);
106 // 站点统计信息
107 const [stats, setStats] = useState<Stats>({
108 threadCount: 0,
109 downloadCount: 0,
110 authorCount: 0,
111 resourceCount: 0
112 });
113 // 消息提醒
114 const toast = useRef<Toast>(null);
115 const router = useRouter();
LaoeGaocia82dfe92025-04-01 20:17:11 +0800116
LaoeGaoci388f7762025-05-29 22:24:35 +0800117
118 // 获取帖子列表
119 useEffect(() => {
120 fetchHotResources();
121 fetchRewards();
122 fetchstats();
123 fetchRecommendMods();
124 fetchRecommendMaps();
125 fetchRecommendModpacks();
126 fetchRecommendTextures();
127 }, []);
128
129 // 获取悬赏列表
130 const fetchRewards = async () => {
131 try {
132 const response = await axios.get<RewardList>(process.env.PUBLIC_URL +`/reward`, {
133 params: { pageNumber: 1, rows: 5, searchValue: '', option: '' }
134 });
135 console.log('获取悬赏列表:', response.data.records);
136 setReweard(response.data.records);
137 } catch (err) {
138 console.error('获取悬赏失败', err);
139 toast.current?.show({ severity: 'error', summary: 'error', detail: '获取悬赏失败' });
140 }
141 };
142
143 // 获取热门资源幻灯片
144 const fetchHotResources = async () => {
145 try {
146 const response = await axios.get<HotResourceList>(process.env.PUBLIC_URL +`/resource/hot`, {
147 params: { pageNumber: 1, rows: 3, searchValue: '', type: '' }
148 });
149 console.log('获取热门社区幻灯片:', response.data.records);
150 setHotResources(response.data.records);
151 } catch (err) {
152 console.error('获取Mod失败', err);
153 toast.current?.show({ severity: 'error', summary: 'error', detail: '获取Mod失败' });
154 }
155 };
156
157 // 获取全站数据
158 const fetchstats = async () => {
159 try {
160 const response = await axios.get<Stats>(process.env.PUBLIC_URL +`/total/info`);
161 console.log('获取全站数据:', response.data);
162 setStats(response.data);
163 } catch (err) {
164 console.error('获取数据失败', err);
165 toast.current?.show({ severity: 'error', summary: 'error', detail: '获取数据失败' });
166 }
167 };
168
169
170 // 获取推荐模组、地图、整合包、材质包
171 const fetchRecommendMods = async () => {
172 try {
173 const response = await axios.get<ModList>(process.env.PUBLIC_URL +`/resource/recommend`, {
174 params: { userId: 22301145, pageNumber: 1, rows: 3, type: '模组' }
175 });
176 console.log('获取模组列表:', response.data.records);
177 setMods(response.data.records);
178 } catch (err) {
179 console.error('获取Mod失败', err);
180 toast.current?.show({ severity: 'error', summary: 'error', detail: '获取Mod失败' });
181 }
182 };
183 const fetchRecommendMaps = async () => {
184 try {
185 const response = await axios.get<MapList>(process.env.PUBLIC_URL +`/resource/recommend`, {
186 params: { userId: 22301145, pageNumber: 1, rows: 3, type: '地图' }
187 });
188 console.log('获取模组列表:', response.data.records);
189 setMaps(response.data.records);
190 } catch (err) {
191 console.error('获取地图失败', err);
192 toast.current?.show({ severity: 'error', summary: 'error', detail: '获取地图失败' });
193 }
194 };
195 const fetchRecommendModpacks = async () => {
196 try {
197 const response = await axios.get<ModpackList>(process.env.PUBLIC_URL +`/resource/recommend`, {
198 params: { userId: 22301145, pageNumber: 1, rows: 3, type: '整合包' }
199 });
200 console.log('获取模组列表:', response.data.records);
201 setModpacks(response.data.records);
202 } catch (err) {
203 console.error('获取整合包失败', err);
204 toast.current?.show({ severity: 'error', summary: 'error', detail: '获取整合包失败' });
205 }
206 };
207 const fetchRecommendTextures = async () => {
208 try {
209 const response = await axios.get<TextureList>(process.env.PUBLIC_URL +`/resource/recommend`, {
210 params: { userId: 22301145, pageNumber: 1, rows: 3, type: '材质包' }
211 });
212 console.log('获取模组列表:', response.data.records);
213 setTextures(response.data.records);
214 } catch (err) {
215 console.error('获取材质包失败', err);
216 toast.current?.show({ severity: 'error', summary: 'error', detail: '获取材质包失败' });
217 }
218 };
219 return (
220 <div className="Home">
221 {/* 轮播图部分 */}
222 <div className="main-header">
223 <div className="carousel-wrapper">
224 <Carousel
225 value={hotResources}
226 numVisible={1}
227 numScroll={1}
228 showIndicators={false}
229 showNavigators={true}
230 className="custom-carousel"
231 itemTemplate={(hotResource) => (
232 <div className="carousel-item" onClick={() => router.push(`/resource/resource-detail/${hotResource.resourceId}`)}>
233 <Image alt="slide" src={process.env.NEXT_PUBLIC_NGINX_URL + hotResource.resourcePicture} className="carousel-avatar" width="700" height="350" />
234 </div>
235 )}
236 />
LaoeGaocia82dfe92025-04-01 20:17:11 +0800237 </div>
LaoeGaoci388f7762025-05-29 22:24:35 +0800238 <div className="rewards-panel">
239 <h2>悬赏排行</h2>
240 <div className="rewards-list">
241 {reward.map((item) => (
242 <div key={item.rewardId} className="reward-item" onClick={() => router.push(`/reward/reward-detail/${item.rewardId}`)}>
243 <span className="reward-title">{item.rewardName}</span>
244 <span className="reward-price">${item.price}</span>
245 </div>
246 ))}
247 </div>
248 <Button
249 label="查看全部悬赏"
250 className="view-all-button"
251 onClick={() => router.push('/reward')}
LaoeGaocia82dfe92025-04-01 20:17:11 +0800252 />
LaoeGaoci388f7762025-05-29 22:24:35 +0800253 </div>
254 </div>
255 {/* 站点统计信息 */}
256 <div className="site-stats">
257 <div className="stat-item">
258 <span className="stat-value">{stats.threadCount}</span>
259 <span className="stat-label">总帖子数</span>
260 </div>
261 <div className="stat-item">
262 <span className="stat-value">{stats.downloadCount}</span>
263 <span className="stat-label">下载总数</span>
264 </div>
265 <div className="stat-item">
266 <span className="stat-value">{stats.authorCount}</span>
267 <span className="stat-label">人数统计</span>
268 </div>
269 <div className="stat-item">
270 <span className="stat-value">{stats.resourceCount}</span>
271 <span className="stat-label">内容总数</span>
272 </div>
273 </div>
274 {/* 推荐模组列表 */}
275 <div className="recommended-mods">
276 <div className="section-header">
277 <h1>推荐模组资源</h1>
278 <Button
279 label="显示更多"
280 link
281 onClick={() => router.push('/resource/recommend/模组')}
LaoeGaocia82dfe92025-04-01 20:17:11 +0800282 />
LaoeGaoci388f7762025-05-29 22:24:35 +0800283 </div>
284 <div className="resource-grid">
285 {mods.map((mod) => (
286 <Card key={mod.resourceId} className="resource-card" onClick={() => router.push(`/resource/resource-detail/${mod.resourceId}`)}>
287 <Image
288 src={process.env.NEXT_PUBLIC_NGINX_URL + mod.resourcePicture}
289 alt={mod.resourceName}
290 width="368"
291 height="200"
292 />
293 <div className="card-content">
294 <h3>{mod.resourceName}</h3>
295 <div className="view-count">
296 <Fire theme="outline" size="16" fill="#FF8D1A" />
297 <span>{mod.likes}</span>
298 </div>
299 </div>
300 </Card>
301 ))}
302 </div>
303 </div>
304 {/* 推荐地图列表 */}
305 <div className="recommended-maps">
306 <div className="section-header">
307 <h1>推荐地图资源</h1>
308 <Button
309 label="显示更多"
310 link
311 onClick={() => router.push('/resource/recommend/地图')}
LaoeGaocia82dfe92025-04-01 20:17:11 +0800312 />
LaoeGaoci388f7762025-05-29 22:24:35 +0800313 </div>
314 <div className="resource-grid">
315 {maps.map((map) => (
316 <Card key={map.resourceId} className="resource-card" onClick={() => router.push(`/resource/resource-detail/${map.resourceId}`)}>
317 <Image
318 src={process.env.NEXT_PUBLIC_NGINX_URL + map.resourcePicture}
319 alt={map.resourceName}
320 width="368"
321 height="200"
322 />
323 <div className="card-content">
324 <h3>{map.resourceName}</h3>
325 <div className="view-count">
326 <Fire theme="outline" size="16" fill="#FF8D1A" />
327 <span>{map.likes}</span>
328 </div>
329 </div>
330 </Card>
331 ))}
332 </div>
333 </div>
334 {/* 推荐材质包列表 */}
335 <div className="recommended-textures">
336 <div className="section-header">
337 <h1>推荐材质包资源</h1>
338 <Button
339 label="显示更多"
340 link
341 onClick={() => router.push('/resource/recommend/材质包')}
342 />
343 </div>
344 <div className="resource-grid">
345 {textures.map((texture) => (
346 <Card key={texture.resourceId} className="resource-card" onClick={() => router.push(`/resource/resource-detail/${texture.resourceId}`)}>
347 <Image
348 src={process.env.NEXT_PUBLIC_NGINX_URL + texture.resourcePicture}
349 alt={texture.resourceName}
350 width="368"
351 height="200"
352 />
353 <div className="card-content">
354 <h3>{texture.resourceName}</h3>
355 <div className="view-count">
356 <Fire theme="outline" size="16" fill="#FF8D1A" />
357 <span>{texture.likes}</span>
358 </div>
359 </div>
360 </Card>
361 ))}
362 </div>
363 </div>
364 {/* 推荐整合包列表 */}
365 <div className="recommended-Modpacks">
366 <div className="section-header">
367 <h1>推荐整合包资源</h1>
368 <Button
369 label="显示更多"
370 link
371 onClick={() => router.push('/resource/recommend/整合包')}
372 />
373 </div>
374 <div className="resource-grid">
375 {modpacks.map((modpack) => (
376 <Card key={modpack.resourceId} className="resource-card" onClick={() => router.push(`/resource/${modpack.resourceId}`)}>
377 <Image
378 src={process.env.NEXT_PUBLIC_NGINX_URL + modpack.resourcePicture}
379 alt={modpack.resourceName}
380 width="368"
381 height="200"
382 />
383 <div className="card-content">
384 <h3>{modpack.resourceName}</h3>
385 <div className="view-count">
386 <Fire theme="outline" size="16" fill="#FF8D1A" />
387 <span>{modpack.likes}</span>
388 </div>
389 </div>
390 </Card>
391 ))}
392 </div>
393 </div>
LaoeGaocia82dfe92025-04-01 20:17:11 +0800394 </div>
395 );
396}