| 'use client'; |
| |
| import {useState, useEffect, useRef} from 'react'; |
| import {InputText} from 'primereact/inputtext'; |
| import {Card} from 'primereact/card'; |
| import {Image} from 'primereact/image'; |
| // 分页 |
| import {Paginator, type PaginatorPageChangeEvent} from 'primereact/paginator'; |
| // 页面跳转 |
| import {useParams} from 'next/navigation' |
| import {useRouter} from 'next/navigation'; |
| // 消息提醒 |
| import {Toast} from 'primereact/toast'; |
| // 接口传输 |
| import axios from 'axios'; |
| // 防抖函数 |
| import {debounce} from 'lodash'; |
| // 样式 |
| import './resource-recommend.scss'; |
| import { useLocalStorage } from '@/app/hook/useLocalStorage'; |
| |
| // 单元社区信息 |
| interface Resource { |
| resourceId: number; |
| resourceName: string; |
| resourcePicture: number; |
| resourceDetail: number; |
| lastUpdateTime: string; |
| } |
| |
| // 推荐资源列表 |
| interface ResourceList { |
| total: number; |
| records: Resource[]; |
| } |
| |
| interface User { |
| Id: number; |
| }; |
| |
| // 推荐资源界面 |
| export default function ResourceRecommendPage() { |
| const user = useLocalStorage<User>('user'); |
| const userId: number = user?.Id ?? -1; |
| // 获取URL参数 |
| const params = useParams<{ classification: string }>() |
| const classify = decodeURIComponent(params.classification); // 防止中文路径乱码 |
| const router = useRouter(); |
| const imgUrl = process.env.NEXT_PUBLIC_NGINX_URL || "http://localhost:65/"; |
| |
| // 社区列表数据 |
| const [resourceList, setResourceList] = useState<Resource[]>([]); |
| const [totalResources, setTotalResources] = useState<number>(0); |
| // 消息提醒 |
| const toast = useRef<Toast>(null); |
| //搜索框 |
| const [searchValue, setSearchValue] = useState(''); |
| const debouncedSearch = useRef( |
| debounce((value: string) => { |
| setSearchValue(value); |
| }, 600) |
| ).current; |
| |
| //分页 |
| const [first, setFirst] = useState(0); |
| const [rows, setRows] = useState(5); |
| const onPageChange = (event: PaginatorPageChangeEvent) => { |
| setFirst(event.first); |
| setRows(event.rows); |
| }; |
| |
| |
| // 获取社区列表 |
| useEffect(() => { |
| fetchResources(); |
| }, [classify, first, rows, searchValue]); |
| |
| const fetchResources = async () => { |
| try { |
| const pageNumber = first / rows + 1; |
| console.log("当前页" + pageNumber + "size" + rows + "classify" + classify + "searchValue" + searchValue); |
| const response = await axios.get<ResourceList>( |
| process.env.PUBLIC_URL + `/resource/recommend`, { |
| params: {userId, classify, pageNumber, rows, searchValue} |
| } |
| ); |
| console.log('获取推荐资源列表:', response.data.records); |
| setTotalResources(response.data.total); |
| setResourceList(response.data.records); |
| } catch (err) { |
| console.error('获取推荐资源失败', err); |
| toast.current?.show({severity: 'error', summary: 'error', detail: '获取推荐资源失败'}); |
| } |
| }; |
| |
| |
| return ( |
| <div className="resource-community-list-container"> |
| <Toast ref={toast}></Toast> |
| <div className="resource-communities-header"> |
| <h1 className="title"> |
| {classify === 'all' ? '全部资源' : `推荐${classify}资源`} |
| </h1> |
| </div> |
| |
| {/* 社区搜索栏 */} |
| <div className="searchBar"> |
| <i className="pi pi-search"/> |
| <InputText type="search" className="search-helper" placeholder="搜索你感兴趣的资源" onChange={(e) => { |
| const target = e.target as HTMLInputElement; |
| debouncedSearch(target.value); |
| }}/> |
| </div> |
| |
| |
| {/* 社区列表 */} |
| <div className="resource-communities-list"> |
| {resourceList.map((resource) => ( |
| <Card key={resource.resourceId} className="resource-communities-list-card" |
| onClick={() => router.push(`/resource/resource-detail/${resource.resourceId}`)}> |
| <Image alt="avatar" src={imgUrl + resource.resourcePicture} |
| className="community-avatar" width="250" height="140"/> |
| <div className="community-header"> |
| <div className="community-content"> |
| <h3>{resource.resourceName}</h3> |
| <p className="community-introduction">{resource.resourceDetail}</p> |
| </div> |
| <div className="community-states"> |
| <div className="state-item"> |
| <span>最近更新时间: {resource.lastUpdateTime}</span> |
| </div> |
| </div> |
| </div> |
| </Card> |
| ))} |
| {totalResources > 5 && |
| <Paginator className="Paginator" first={first} rows={rows} totalRecords={totalResources} |
| rowsPerPageOptions={[5, 10]} onPageChange={onPageChange}/>} |
| </div> |
| </div> |
| ); |
| } |