| 'use client'; |
| |
| import React, { useEffect, useState, useRef } from "react"; |
| import { Button } from 'primereact/button'; |
| import { Card } from 'primereact/card'; |
| import { Image } from 'primereact/image'; |
| import { Carousel } from 'primereact/carousel'; |
| // 页面跳转 |
| import { useRouter } from 'next/navigation'; |
| // 消息提醒 |
| import { Toast } from 'primereact/toast'; |
| // 评分图标 |
| import { Fire } from '@icon-park/react'; |
| // 接口传输 |
| import axios from 'axios'; |
| import { useLocalStorage } from './hook/useLocalStorage'; |
| // 样式 |
| import './main.scss'; |
| |
| interface User { |
| Id: number; |
| } |
| |
| // 模组列表数据 |
| interface Mod { |
| resourceId: number; |
| resourceName: string; |
| resourcePicture: string; |
| likes: number; |
| } |
| interface ModList { |
| records: Mod[]; |
| } |
| // 地图列表数据 |
| interface Map { |
| resourceId: number; |
| resourceName: string; |
| resourcePicture: string; |
| likes: number; |
| } |
| interface MapList { |
| records: Mod[]; |
| } |
| // 帖子列表数据 |
| interface Modpack { |
| resourceId: number; |
| resourceName: string; |
| resourcePicture: string; |
| likes: number; |
| } |
| interface ModpackList { |
| records: Modpack[]; |
| } |
| // 帖子列表数据 |
| interface Texture { |
| resourceId: number; |
| resourceName: string; |
| resourcePicture: string; |
| likes: number; |
| } |
| interface TextureList { |
| records: Texture[]; |
| } |
| // 热门资源幻灯片数据 |
| interface HotResource { |
| resourceId: number; |
| resourceName: string; |
| resourcePicture: string; |
| } |
| interface HotResourceList { |
| records: HotResource[]; |
| } |
| // 站点统计数据 |
| interface Stats { |
| threadCount: number; |
| downloadCount: number; |
| authorCount: number; |
| resourceCount: number; |
| } |
| // 悬赏列表 |
| interface Reward { |
| rewardId: number; |
| userId: number; |
| rewardPicture: string; |
| rewardName: string; |
| createdAt: string; |
| rewardDescription: string; |
| price: number; |
| } |
| interface RewardList { |
| total: number; // 总记录数 |
| records: Reward[]; |
| } |
| // 主页 |
| export default function Home() { |
| const user = useLocalStorage<User>('user'); |
| const userId: number = user?.Id ?? -1; |
| |
| // 模组列表 |
| const [mods, setMods] = useState<Mod[]>([]); |
| // 悬赏列表 |
| const [reward, setReweard] = useState<Reward[]>([]); |
| // 地图列表 |
| const [maps, setMaps] = useState<Map[]>([]); |
| // 整合包列表 |
| const [modpacks, setModpacks] = useState<Modpack[]>([]); |
| // 材质包列表 |
| const [textures, setTextures] = useState<Texture[]>([]); |
| // 热门资源列表 |
| const [hotResources, setHotResources] = useState<HotResource[]>([]); |
| // 站点统计信息 |
| const [stats, setStats] = useState<Stats>({ |
| threadCount: 0, |
| downloadCount: 0, |
| authorCount: 0, |
| resourceCount: 0 |
| }); |
| // 消息提醒 |
| const toast = useRef<Toast>(null); |
| const router = useRouter(); |
| |
| |
| // 获取帖子列表 |
| useEffect(() => { |
| fetchHotResources(); |
| fetchRewards(); |
| fetchstats(); |
| fetchRecommendMods(); |
| fetchRecommendMaps(); |
| fetchRecommendModpacks(); |
| fetchRecommendTextures(); |
| }, []); |
| |
| // 获取悬赏列表 |
| const fetchRewards = async () => { |
| try { |
| const response = await axios.get<RewardList>(process.env.PUBLIC_URL + `/reward`, { |
| params: { pageNumber: 1, rows: 5, searchValue: '', option: '' } |
| }); |
| console.log('获取悬赏列表:', response.data.records); |
| setReweard(response.data.records); |
| } catch (err) { |
| console.error('获取悬赏失败', err); |
| toast.current?.show({ severity: 'error', summary: 'error', detail: '获取悬赏失败' }); |
| } |
| }; |
| |
| // 获取热门资源幻灯片 |
| const fetchHotResources = async () => { |
| try { |
| const response = await axios.get<HotResourceList>(process.env.PUBLIC_URL + `/resource/hot/slide`); |
| console.log('获取热门社区幻灯片:', response.data.records); |
| setHotResources(response.data.records); |
| } catch (err) { |
| console.error('获取Mod失败', err); |
| toast.current?.show({ severity: 'error', summary: 'error', detail: '获取Mod失败' }); |
| } |
| }; |
| |
| // 获取全站数据 |
| const fetchstats = async () => { |
| try { |
| const response = await axios.get<Stats>(process.env.PUBLIC_URL + `/total/info`); |
| console.log('获取全站数据:', response.data); |
| setStats(response.data); |
| } catch (err) { |
| console.error('获取数据失败', err); |
| toast.current?.show({ severity: 'error', summary: 'error', detail: '获取数据失败' }); |
| } |
| }; |
| |
| |
| // 获取推荐模组、地图、整合包、材质包 |
| const fetchRecommendMods = async () => { |
| try { |
| const response = await axios.get<ModList>(process.env.PUBLIC_URL + `/resource/recommend`, { |
| params: { userId, pageNumber: 1, rows: 3, type: '模组' } |
| }); |
| console.log('获取模组列表:', response.data.records); |
| setMods(response.data.records); |
| } catch (err) { |
| console.error('获取Mod失败', err); |
| toast.current?.show({ severity: 'error', summary: 'error', detail: '获取Mod失败' }); |
| } |
| }; |
| const fetchRecommendMaps = async () => { |
| try { |
| const response = await axios.get<MapList>(process.env.PUBLIC_URL + `/resource/recommend`, { |
| params: { userId, pageNumber: 1, rows: 3, type: '地图' } |
| }); |
| console.log('获取模组列表:', response.data.records); |
| setMaps(response.data.records); |
| } catch (err) { |
| console.error('获取地图失败', err); |
| toast.current?.show({ severity: 'error', summary: 'error', detail: '获取地图失败' }); |
| } |
| }; |
| const fetchRecommendModpacks = async () => { |
| try { |
| const response = await axios.get<ModpackList>(process.env.PUBLIC_URL + `/resource/recommend`, { |
| params: { userId, pageNumber: 1, rows: 3, type: '整合包' } |
| }); |
| console.log('获取模组列表:', response.data.records); |
| setModpacks(response.data.records); |
| } catch (err) { |
| console.error('获取整合包失败', err); |
| toast.current?.show({ severity: 'error', summary: 'error', detail: '获取整合包失败' }); |
| } |
| }; |
| const fetchRecommendTextures = async () => { |
| try { |
| const response = await axios.get<TextureList>(process.env.PUBLIC_URL + `/resource/recommend`, { |
| params: { userId, pageNumber: 1, rows: 3, type: '材质包' } |
| }); |
| console.log('获取模组列表:', response.data.records); |
| setTextures(response.data.records); |
| } catch (err) { |
| console.error('获取材质包失败', err); |
| toast.current?.show({ severity: 'error', summary: 'error', detail: '获取材质包失败' }); |
| } |
| }; |
| return ( |
| <div className="Home"> |
| {/* 轮播图部分 */} |
| <div className="main-header"> |
| <div className="carousel-wrapper"> |
| <Carousel |
| value={hotResources} |
| numVisible={1} |
| numScroll={1} |
| showIndicators={false} |
| showNavigators={true} |
| className="custom-carousel" |
| itemTemplate={(hotResource) => ( |
| <div className="carousel-item" onClick={() => router.push(`/resource/resource-detail/${hotResource.resourceId}`)}> |
| <Image alt="slide" src={process.env.NEXT_PUBLIC_NGINX_URL + hotResource.resourcePicture} className="carousel-avatar" width="700" height="350" /> |
| </div> |
| )} |
| /> |
| </div> |
| <div className="rewards-panel"> |
| <h2>悬赏排行</h2> |
| <div className="rewards-list"> |
| {reward.map((item) => ( |
| <div key={item.rewardId} className="reward-item" onClick={() => router.push(`/reward/reward-detail/${item.rewardId}`)}> |
| <span className="reward-title">{item.rewardName}</span> |
| <span className="reward-price">${item.price}</span> |
| </div> |
| ))} |
| </div> |
| <Button |
| label="查看全部悬赏" |
| className="view-all-button" |
| onClick={() => router.push('/reward')} |
| /> |
| </div> |
| </div> |
| {/* 站点统计信息 */} |
| <div className="site-stats"> |
| <div className="stat-item"> |
| <span className="stat-value">{stats.threadCount}</span> |
| <span className="stat-label">总帖子数</span> |
| </div> |
| <div className="stat-item"> |
| <span className="stat-value">{stats.downloadCount}</span> |
| <span className="stat-label">下载总数</span> |
| </div> |
| <div className="stat-item"> |
| <span className="stat-value">{stats.authorCount}</span> |
| <span className="stat-label">人数统计</span> |
| </div> |
| <div className="stat-item"> |
| <span className="stat-value">{stats.resourceCount}</span> |
| <span className="stat-label">内容总数</span> |
| </div> |
| </div> |
| {/* 推荐模组列表 */} |
| <div className="recommended-mods"> |
| <div className="section-header"> |
| <h1>推荐模组资源</h1> |
| <Button |
| label="显示更多" |
| link |
| onClick={() => router.push('/resource/recommend/模组')} |
| /> |
| </div> |
| <div className="resource-grid"> |
| {mods.map((mod) => ( |
| <Card key={mod.resourceId} className="resource-card" onClick={() => router.push(`/resource/resource-detail/${mod.resourceId}`)}> |
| <Image |
| src={process.env.NEXT_PUBLIC_NGINX_URL + mod.resourcePicture} |
| alt={mod.resourceName} |
| width="368" |
| height="200" |
| /> |
| <div className="card-content"> |
| <h3>{mod.resourceName}</h3> |
| <div className="view-count"> |
| <Fire theme="outline" size="16" fill="#FF8D1A" /> |
| <span>{mod.likes}</span> |
| </div> |
| </div> |
| </Card> |
| ))} |
| </div> |
| </div> |
| {/* 推荐地图列表 */} |
| <div className="recommended-maps"> |
| <div className="section-header"> |
| <h1>推荐地图资源</h1> |
| <Button |
| label="显示更多" |
| link |
| onClick={() => router.push('/resource/recommend/地图')} |
| /> |
| </div> |
| <div className="resource-grid"> |
| {maps.map((map) => ( |
| <Card key={map.resourceId} className="resource-card" onClick={() => router.push(`/resource/resource-detail/${map.resourceId}`)}> |
| <Image |
| src={process.env.NEXT_PUBLIC_NGINX_URL + map.resourcePicture} |
| alt={map.resourceName} |
| width="368" |
| height="200" |
| /> |
| <div className="card-content"> |
| <h3>{map.resourceName}</h3> |
| <div className="view-count"> |
| <Fire theme="outline" size="16" fill="#FF8D1A" /> |
| <span>{map.likes}</span> |
| </div> |
| </div> |
| </Card> |
| ))} |
| </div> |
| </div> |
| {/* 推荐材质包列表 */} |
| <div className="recommended-textures"> |
| <div className="section-header"> |
| <h1>推荐材质包资源</h1> |
| <Button |
| label="显示更多" |
| link |
| onClick={() => router.push('/resource/recommend/材质包')} |
| /> |
| </div> |
| <div className="resource-grid"> |
| {textures.map((texture) => ( |
| <Card key={texture.resourceId} className="resource-card" onClick={() => router.push(`/resource/resource-detail/${texture.resourceId}`)}> |
| <Image |
| src={process.env.NEXT_PUBLIC_NGINX_URL + texture.resourcePicture} |
| alt={texture.resourceName} |
| width="368" |
| height="200" |
| /> |
| <div className="card-content"> |
| <h3>{texture.resourceName}</h3> |
| <div className="view-count"> |
| <Fire theme="outline" size="16" fill="#FF8D1A" /> |
| <span>{texture.likes}</span> |
| </div> |
| </div> |
| </Card> |
| ))} |
| </div> |
| </div> |
| {/* 推荐整合包列表 */} |
| <div className="recommended-Modpacks"> |
| <div className="section-header"> |
| <h1>推荐整合包资源</h1> |
| <Button |
| label="显示更多" |
| link |
| onClick={() => router.push('/resource/recommend/整合包')} |
| /> |
| </div> |
| <div className="resource-grid"> |
| {modpacks.map((modpack) => ( |
| <Card key={modpack.resourceId} className="resource-card" onClick={() => router.push(`/resource/${modpack.resourceId}`)}> |
| <Image |
| src={process.env.NEXT_PUBLIC_NGINX_URL + modpack.resourcePicture} |
| alt={modpack.resourceName} |
| width="368" |
| height="200" |
| /> |
| <div className="card-content"> |
| <h3>{modpack.resourceName}</h3> |
| <div className="view-count"> |
| <Fire theme="outline" size="16" fill="#FF8D1A" /> |
| <span>{modpack.likes}</span> |
| </div> |
| </div> |
| </Card> |
| ))} |
| </div> |
| </div> |
| </div> |
| ); |
| } |