blob: fb42dacee1e52f599f50e3712f3cf4606470f95e [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;
LaoeGaoci388f7762025-05-29 22:24:35 +080064}
65interface HotResourceList {
66 records: HotResource[];
67}
68// 站点统计数据
69interface Stats {
70 threadCount: number;
71 downloadCount: number;
72 authorCount: number;
73 resourceCount: number;
74}
75// 悬赏列表
76interface Reward {
77 rewardId: number;
78 userId: number;
79 rewardPicture: string;
80 rewardName: string;
81 createdAt: string;
82 rewardDescription: string;
83 price: number;
84}
85interface RewardList {
86 total: number; // 总记录数
87 records: Reward[];
88}
89// 主页
LaoeGaocia82dfe92025-04-01 20:17:11 +080090export default function Home() {
LaoeGaoci388f7762025-05-29 22:24:35 +080091 // 模组列表
92 const [mods, setMods] = useState<Mod[]>([]);
93 // 悬赏列表
94 const [reward, setReweard] = useState<Reward[]>([]);
95 // 地图列表
96 const [maps, setMaps] = useState<Map[]>([]);
97 // 整合包列表
98 const [modpacks, setModpacks] = useState<Modpack[]>([]);
99 // 材质包列表
100 const [textures, setTextures] = useState<Texture[]>([]);
101 // 热门资源列表
102 const [hotResources, setHotResources] = useState<HotResource[]>([]);
103 // 站点统计信息
104 const [stats, setStats] = useState<Stats>({
105 threadCount: 0,
106 downloadCount: 0,
107 authorCount: 0,
108 resourceCount: 0
109 });
110 // 消息提醒
111 const toast = useRef<Toast>(null);
112 const router = useRouter();
LaoeGaocia82dfe92025-04-01 20:17:11 +0800113
LaoeGaoci388f7762025-05-29 22:24:35 +0800114
115 // 获取帖子列表
116 useEffect(() => {
117 fetchHotResources();
118 fetchRewards();
119 fetchstats();
120 fetchRecommendMods();
121 fetchRecommendMaps();
122 fetchRecommendModpacks();
123 fetchRecommendTextures();
124 }, []);
125
126 // 获取悬赏列表
127 const fetchRewards = async () => {
128 try {
129 const response = await axios.get<RewardList>(process.env.PUBLIC_URL +`/reward`, {
130 params: { pageNumber: 1, rows: 5, searchValue: '', option: '' }
131 });
132 console.log('获取悬赏列表:', response.data.records);
133 setReweard(response.data.records);
134 } catch (err) {
135 console.error('获取悬赏失败', err);
136 toast.current?.show({ severity: 'error', summary: 'error', detail: '获取悬赏失败' });
137 }
138 };
139
140 // 获取热门资源幻灯片
141 const fetchHotResources = async () => {
142 try {
LaoeGaoci8f6d0db2025-06-03 22:57:04 +0800143 const response = await axios.get<HotResourceList>(process.env.PUBLIC_URL +`/resource/hot/slide`);
LaoeGaoci388f7762025-05-29 22:24:35 +0800144 console.log('获取热门社区幻灯片:', response.data.records);
145 setHotResources(response.data.records);
146 } catch (err) {
147 console.error('获取Mod失败', err);
148 toast.current?.show({ severity: 'error', summary: 'error', detail: '获取Mod失败' });
149 }
150 };
151
152 // 获取全站数据
153 const fetchstats = async () => {
154 try {
155 const response = await axios.get<Stats>(process.env.PUBLIC_URL +`/total/info`);
156 console.log('获取全站数据:', response.data);
157 setStats(response.data);
158 } catch (err) {
159 console.error('获取数据失败', err);
160 toast.current?.show({ severity: 'error', summary: 'error', detail: '获取数据失败' });
161 }
162 };
163
164
165 // 获取推荐模组、地图、整合包、材质包
166 const fetchRecommendMods = async () => {
167 try {
168 const response = await axios.get<ModList>(process.env.PUBLIC_URL +`/resource/recommend`, {
169 params: { userId: 22301145, pageNumber: 1, rows: 3, type: '模组' }
170 });
171 console.log('获取模组列表:', response.data.records);
172 setMods(response.data.records);
173 } catch (err) {
174 console.error('获取Mod失败', err);
175 toast.current?.show({ severity: 'error', summary: 'error', detail: '获取Mod失败' });
176 }
177 };
178 const fetchRecommendMaps = async () => {
179 try {
180 const response = await axios.get<MapList>(process.env.PUBLIC_URL +`/resource/recommend`, {
181 params: { userId: 22301145, pageNumber: 1, rows: 3, type: '地图' }
182 });
183 console.log('获取模组列表:', response.data.records);
184 setMaps(response.data.records);
185 } catch (err) {
186 console.error('获取地图失败', err);
187 toast.current?.show({ severity: 'error', summary: 'error', detail: '获取地图失败' });
188 }
189 };
190 const fetchRecommendModpacks = async () => {
191 try {
192 const response = await axios.get<ModpackList>(process.env.PUBLIC_URL +`/resource/recommend`, {
193 params: { userId: 22301145, pageNumber: 1, rows: 3, type: '整合包' }
194 });
195 console.log('获取模组列表:', response.data.records);
196 setModpacks(response.data.records);
197 } catch (err) {
198 console.error('获取整合包失败', err);
199 toast.current?.show({ severity: 'error', summary: 'error', detail: '获取整合包失败' });
200 }
201 };
202 const fetchRecommendTextures = async () => {
203 try {
204 const response = await axios.get<TextureList>(process.env.PUBLIC_URL +`/resource/recommend`, {
205 params: { userId: 22301145, pageNumber: 1, rows: 3, type: '材质包' }
206 });
207 console.log('获取模组列表:', response.data.records);
208 setTextures(response.data.records);
209 } catch (err) {
210 console.error('获取材质包失败', err);
211 toast.current?.show({ severity: 'error', summary: 'error', detail: '获取材质包失败' });
212 }
213 };
214 return (
215 <div className="Home">
216 {/* 轮播图部分 */}
217 <div className="main-header">
218 <div className="carousel-wrapper">
219 <Carousel
220 value={hotResources}
221 numVisible={1}
222 numScroll={1}
223 showIndicators={false}
224 showNavigators={true}
225 className="custom-carousel"
226 itemTemplate={(hotResource) => (
227 <div className="carousel-item" onClick={() => router.push(`/resource/resource-detail/${hotResource.resourceId}`)}>
228 <Image alt="slide" src={process.env.NEXT_PUBLIC_NGINX_URL + hotResource.resourcePicture} className="carousel-avatar" width="700" height="350" />
229 </div>
230 )}
231 />
LaoeGaocia82dfe92025-04-01 20:17:11 +0800232 </div>
LaoeGaoci388f7762025-05-29 22:24:35 +0800233 <div className="rewards-panel">
234 <h2>悬赏排行</h2>
235 <div className="rewards-list">
236 {reward.map((item) => (
237 <div key={item.rewardId} className="reward-item" onClick={() => router.push(`/reward/reward-detail/${item.rewardId}`)}>
238 <span className="reward-title">{item.rewardName}</span>
239 <span className="reward-price">${item.price}</span>
240 </div>
241 ))}
242 </div>
243 <Button
244 label="查看全部悬赏"
245 className="view-all-button"
246 onClick={() => router.push('/reward')}
LaoeGaocia82dfe92025-04-01 20:17:11 +0800247 />
LaoeGaoci388f7762025-05-29 22:24:35 +0800248 </div>
249 </div>
250 {/* 站点统计信息 */}
251 <div className="site-stats">
252 <div className="stat-item">
253 <span className="stat-value">{stats.threadCount}</span>
254 <span className="stat-label">总帖子数</span>
255 </div>
256 <div className="stat-item">
257 <span className="stat-value">{stats.downloadCount}</span>
258 <span className="stat-label">下载总数</span>
259 </div>
260 <div className="stat-item">
261 <span className="stat-value">{stats.authorCount}</span>
262 <span className="stat-label">人数统计</span>
263 </div>
264 <div className="stat-item">
265 <span className="stat-value">{stats.resourceCount}</span>
266 <span className="stat-label">内容总数</span>
267 </div>
268 </div>
269 {/* 推荐模组列表 */}
270 <div className="recommended-mods">
271 <div className="section-header">
272 <h1>推荐模组资源</h1>
273 <Button
274 label="显示更多"
275 link
276 onClick={() => router.push('/resource/recommend/模组')}
LaoeGaocia82dfe92025-04-01 20:17:11 +0800277 />
LaoeGaoci388f7762025-05-29 22:24:35 +0800278 </div>
279 <div className="resource-grid">
280 {mods.map((mod) => (
281 <Card key={mod.resourceId} className="resource-card" onClick={() => router.push(`/resource/resource-detail/${mod.resourceId}`)}>
282 <Image
283 src={process.env.NEXT_PUBLIC_NGINX_URL + mod.resourcePicture}
284 alt={mod.resourceName}
285 width="368"
286 height="200"
287 />
288 <div className="card-content">
289 <h3>{mod.resourceName}</h3>
290 <div className="view-count">
291 <Fire theme="outline" size="16" fill="#FF8D1A" />
292 <span>{mod.likes}</span>
293 </div>
294 </div>
295 </Card>
296 ))}
297 </div>
298 </div>
299 {/* 推荐地图列表 */}
300 <div className="recommended-maps">
301 <div className="section-header">
302 <h1>推荐地图资源</h1>
303 <Button
304 label="显示更多"
305 link
306 onClick={() => router.push('/resource/recommend/地图')}
LaoeGaocia82dfe92025-04-01 20:17:11 +0800307 />
LaoeGaoci388f7762025-05-29 22:24:35 +0800308 </div>
309 <div className="resource-grid">
310 {maps.map((map) => (
311 <Card key={map.resourceId} className="resource-card" onClick={() => router.push(`/resource/resource-detail/${map.resourceId}`)}>
312 <Image
313 src={process.env.NEXT_PUBLIC_NGINX_URL + map.resourcePicture}
314 alt={map.resourceName}
315 width="368"
316 height="200"
317 />
318 <div className="card-content">
319 <h3>{map.resourceName}</h3>
320 <div className="view-count">
321 <Fire theme="outline" size="16" fill="#FF8D1A" />
322 <span>{map.likes}</span>
323 </div>
324 </div>
325 </Card>
326 ))}
327 </div>
328 </div>
329 {/* 推荐材质包列表 */}
330 <div className="recommended-textures">
331 <div className="section-header">
332 <h1>推荐材质包资源</h1>
333 <Button
334 label="显示更多"
335 link
336 onClick={() => router.push('/resource/recommend/材质包')}
337 />
338 </div>
339 <div className="resource-grid">
340 {textures.map((texture) => (
341 <Card key={texture.resourceId} className="resource-card" onClick={() => router.push(`/resource/resource-detail/${texture.resourceId}`)}>
342 <Image
343 src={process.env.NEXT_PUBLIC_NGINX_URL + texture.resourcePicture}
344 alt={texture.resourceName}
345 width="368"
346 height="200"
347 />
348 <div className="card-content">
349 <h3>{texture.resourceName}</h3>
350 <div className="view-count">
351 <Fire theme="outline" size="16" fill="#FF8D1A" />
352 <span>{texture.likes}</span>
353 </div>
354 </div>
355 </Card>
356 ))}
357 </div>
358 </div>
359 {/* 推荐整合包列表 */}
360 <div className="recommended-Modpacks">
361 <div className="section-header">
362 <h1>推荐整合包资源</h1>
363 <Button
364 label="显示更多"
365 link
366 onClick={() => router.push('/resource/recommend/整合包')}
367 />
368 </div>
369 <div className="resource-grid">
370 {modpacks.map((modpack) => (
371 <Card key={modpack.resourceId} className="resource-card" onClick={() => router.push(`/resource/${modpack.resourceId}`)}>
372 <Image
373 src={process.env.NEXT_PUBLIC_NGINX_URL + modpack.resourcePicture}
374 alt={modpack.resourceName}
375 width="368"
376 height="200"
377 />
378 <div className="card-content">
379 <h3>{modpack.resourceName}</h3>
380 <div className="view-count">
381 <Fire theme="outline" size="16" fill="#FF8D1A" />
382 <span>{modpack.likes}</span>
383 </div>
384 </div>
385 </Card>
386 ))}
387 </div>
388 </div>
LaoeGaocia82dfe92025-04-01 20:17:11 +0800389 </div>
390 );
391}