blob: 453cf90ae1cd9943687b3a50e2f1ed26843ff87c [file] [log] [blame]
LaoeGaoci85307e62025-05-30 23:28:42 +08001'use client';
LaoeGaoci85307e62025-05-30 23:28:42 +08002
lfmylbhfe279c302025-06-09 23:28:21 +08003import {useState, useEffect, useRef} from 'react';
4import {InputText} from 'primereact/inputtext';
5import {Card} from 'primereact/card';
6import {Image} from 'primereact/image';
7// 分页
8import {Paginator, type PaginatorPageChangeEvent} from 'primereact/paginator';
9// 页面跳转
10import {useParams} from 'next/navigation'
11import {useRouter} from 'next/navigation';
12// 消息提醒
13import {Toast} from 'primereact/toast';
14// 接口传输
15import axios from 'axios';
16// 防抖函数
17import {debounce} from 'lodash';
18// 样式
19import './resource-recommend.scss';
20import { useLocalStorage } from '@/app/hook/useLocalStorage';
21
22// 单元社区信息
23interface Resource {
24 resourceId: number;
25 resourceName: string;
26 resourcePicture: number;
27 resourceDetail: number;
28 lastUpdateTime: string;
29}
30
31// 推荐资源列表
32interface ResourceList {
33 total: number;
34 records: Resource[];
35}
36
37interface User {
38 Id: number;
LaoeGaoci85307e62025-05-30 23:28:42 +080039};
40
lfmylbhfe279c302025-06-09 23:28:21 +080041// 推荐资源界面
42export default function ResourceRecommendPage() {
43 const user = useLocalStorage<User>('user');
44 const userId: number = user?.Id ?? -1;
45 // 获取URL参数
46 const params = useParams<{ classification: string }>()
47 const classify = decodeURIComponent(params.classification); // 防止中文路径乱码
48 const router = useRouter();
49 const imgUrl = process.env.NEXT_PUBLIC_NGINX_URL || "http://localhost:65/";
50
51 // 社区列表数据
52 const [resourceList, setResourceList] = useState<Resource[]>([]);
53 const [totalResources, setTotalResources] = useState<number>(0);
54 // 消息提醒
55 const toast = useRef<Toast>(null);
56 //搜索框
57 const [searchValue, setSearchValue] = useState('');
58 const debouncedSearch = useRef(
59 debounce((value: string) => {
60 setSearchValue(value);
61 }, 600)
62 ).current;
63
64 //分页
65 const [first, setFirst] = useState(0);
66 const [rows, setRows] = useState(5);
67 const onPageChange = (event: PaginatorPageChangeEvent) => {
68 setFirst(event.first);
69 setRows(event.rows);
70 };
71
72
73 // 获取社区列表
74 useEffect(() => {
75 fetchResources();
76 }, [classify, first, rows, searchValue]);
77
78 const fetchResources = async () => {
79 try {
80 const pageNumber = first / rows + 1;
81 console.log("当前页" + pageNumber + "size" + rows + "classify" + classify + "searchValue" + searchValue);
82 const response = await axios.get<ResourceList>(
83 process.env.PUBLIC_URL + `/resource/recommend`, {
84 params: {userId, classify, pageNumber, rows, searchValue}
85 }
86 );
87 console.log('获取推荐资源列表:', response.data.records);
88 setTotalResources(response.data.total);
89 setResourceList(response.data.records);
90 } catch (err) {
91 console.error('获取推荐资源失败', err);
92 toast.current?.show({severity: 'error', summary: 'error', detail: '获取推荐资源失败'});
93 }
94 };
95
96
97 return (
98 <div className="resource-community-list-container">
99 <Toast ref={toast}></Toast>
100 <div className="resource-communities-header">
101 <h1 className="title">
102 {classify === 'all' ? '全部资源' : `推荐${classify}资源`}
103 </h1>
104 </div>
105
106 {/* 社区搜索栏 */}
107 <div className="searchBar">
108 <i className="pi pi-search"/>
109 <InputText type="search" className="search-helper" placeholder="搜索你感兴趣的资源" onChange={(e) => {
110 const target = e.target as HTMLInputElement;
111 debouncedSearch(target.value);
112 }}/>
113 </div>
114
115
116 {/* 社区列表 */}
117 <div className="resource-communities-list">
118 {resourceList.map((resource) => (
119 <Card key={resource.resourceId} className="resource-communities-list-card"
120 onClick={() => router.push(`/resource/resource-detail/${resource.resourceId}`)}>
121 <Image alt="avatar" src={imgUrl + resource.resourcePicture}
122 className="community-avatar" width="250" height="140"/>
123 <div className="community-header">
124 <div className="community-content">
125 <h3>{resource.resourceName}</h3>
126 <p className="community-introduction">{resource.resourceDetail}</p>
127 </div>
128 <div className="community-states">
129 <div className="state-item">
130 <span>最近更新时间: {resource.lastUpdateTime}</span>
131 </div>
132 </div>
133 </div>
134 </Card>
135 ))}
136 {totalResources > 5 &&
137 <Paginator className="Paginator" first={first} rows={rows} totalRecords={totalResources}
138 rowsPerPageOptions={[5, 10]} onPageChange={onPageChange}/>}
139 </div>
140 </div>
141 );
142}