blob: ec74187455a3914dd79d71600f59c84a9206a260 [file] [log] [blame]
阳菜,放晴!77743f42025-06-06 23:04:08 +08001import React, { useCallback, useEffect,useState,useRef } from 'react';
阳菜,放晴!7e1e3a52025-06-05 23:00:51 +08002import styles from './homepage.module.css';
3import { useApi } from '@/hooks/request';
4import { useSelector } from 'react-redux';
5import { RootState } from '@/store';
6import { useNavigate } from 'react-router';
7import logo from '&/assets/logo.png';
阳菜,放晴!77743f42025-06-06 23:04:08 +08008import { getUserMessage } from '@/api/homepage'
9import { getUserDetail } from '@/api/homepage'
阳菜,放晴!7e1e3a52025-06-05 23:00:51 +080010import request from '@/utils/request'
阳菜,放晴!77743f42025-06-06 23:04:08 +080011// import { hotPosts } from '@/api/post';
阳菜,放晴!7e1e3a52025-06-05 23:00:51 +080012import { postUserLogin } from '@/api/auth';
阳菜,放晴!77743f42025-06-06 23:04:08 +080013import { debounce } from 'lodash';
14import { Q } from 'react-router/dist/development/fog-of-war-CGNKxM4z';
阳菜,放晴!7e1e3a52025-06-05 23:00:51 +080015
16interface WorkItem {
17 postId: number,
18 userId: number,
19 postTitle: string,
20 postContent: string,
21 createdAt: number,
22 postType: string,
阳菜,放晴!77743f42025-06-06 23:04:08 +080023 isLocked: boolean,
24 lockedReason: string,
25 lockedAt: string,
26 lockedBy: number,
阳菜,放晴!7e1e3a52025-06-05 23:00:51 +080027 viewCount: number,
28 hotScore: number,
29 lastCalculated: number
阳菜,放晴!7e1e3a52025-06-05 23:00:51 +080030}
31
32interface UserStats {
阳菜,放晴!77743f42025-06-06 23:04:08 +080033 username: string;
34 uploadAmount: number;
35 level: string;
阳菜,放晴!7e1e3a52025-06-05 23:00:51 +080036 likes: number;
37 following: number;
38 followers: number;
39 mutualFollows: number;
40}
41
阳菜,放晴!7e1e3a52025-06-05 23:00:51 +080042
43const Homepage: React.FC =() => {
阳菜,放晴!77743f42025-06-06 23:04:08 +080044 const [userStats, setUserStats] = useState<UserStats | null>(null);
45
46 const [works, setWorks] = useState<WorkItem[]>([]);
47 const worksRef = useRef<WorkItem[]>([]);
48
49
阳菜,放晴!7e1e3a52025-06-05 23:00:51 +080050 const navigate = useNavigate();
51 const userInfo = useSelector((state: RootState) => state.user);
阳菜,放晴!77743f42025-06-06 23:04:08 +080052 const userId = userInfo.userId; // 从Redux获取当前用户ID
53
54 const { data:userdata, loading:userloading, error:usererror, refresh: getUserDetailRefresh } = useApi(
55 () => request.get(getUserDetail, {params: {userId}}).then(res => res.data.data),
56 );
57
58 const { data:workdata, loading:workloading, error:workerror, refresh: getUserMessageRefresh } = useApi(
59 () => request.get(getUserMessage, { params: { userId } }).then(res => res.data.data),
60 false
61 );
62
63 const getUserDetails = debounce(async () => {
64 try{
65 const res = await getUserDetailRefresh({userId});
66 console.log("res", res);
67 setUserStats(res);
68 }catch(error){
69 console.error('获取用户信息错误', error);
70 }
71 },1000) as () => void;
72
73
74 const getUserPost = debounce(async () => {
75 try{
76 const res = await getUserMessageRefresh({userId});
77 console.log("res", res);
78 worksRef.current = res;
79 setWorks(res);
80 }catch(error) {
81 console.error('获取帖子列表错误', error);
82 }
83 },1000) as () => void;
84
阳菜,放晴!7e1e3a52025-06-05 23:00:51 +080085 useEffect(() => {
阳菜,放晴!77743f42025-06-06 23:04:08 +080086 if (!userId) {
87 navigate('/login');
88 }
89 else {
90 getUserDetails();
91 getUserPost();
92 }
93 }, [userId]);
94
95 if (!userId) return null;
96
阳菜,放晴!7e1e3a52025-06-05 23:00:51 +080097
98 return (
99 <div className={styles.container}>
100
101
102 {/* 用户信息主区域 */}
103 <div className={styles.mainContent}>
104 {/* 左侧用户信息区 */}
105 <div className={styles.userProfile}>
106 <div className={styles.userHeader}>
107 <img
108 src={userInfo.avatar || '/default-avatar.png'}
109 alt="用户头像"
110 className={styles.userAvatar}
111 />
112 <div className={styles.userInfo}>
113 <h2 className={styles.username}>阳菜,放睛!</h2>
114 <div className={styles.inviteCode}>邀请码:1314520</div>
115 <button className={styles.editButton}>编辑主页</button>
阳菜,放晴!7e1e3a52025-06-05 23:00:51 +0800116 </div>
117 </div>
118
119 <div className={styles.userStats}>
120 <div className={styles.statItem}>
阳菜,放晴!77743f42025-06-06 23:04:08 +0800121 <div className={styles.statNumber}>{userStats?.likes ?? '--'}</div>
阳菜,放晴!7e1e3a52025-06-05 23:00:51 +0800122 <div className={styles.statLabel}>获赞</div>
123 </div>
124 <div className={styles.statItem}>
阳菜,放晴!77743f42025-06-06 23:04:08 +0800125 <div className={styles.statNumber}>{userStats?.following ?? '--'}</div>
阳菜,放晴!7e1e3a52025-06-05 23:00:51 +0800126 <div className={styles.statLabel}>关注</div>
127 </div>
128 <div className={styles.statItem}>
阳菜,放晴!77743f42025-06-06 23:04:08 +0800129 <div className={styles.statNumber}>{userStats?.followers ?? '--'}</div>
阳菜,放晴!7e1e3a52025-06-05 23:00:51 +0800130 <div className={styles.statLabel}>粉丝</div>
131 </div>
132 <div className={styles.statItem}>
阳菜,放晴!77743f42025-06-06 23:04:08 +0800133 <div className={styles.statNumber}>{userStats?.mutualFollows ?? '--'}</div>
阳菜,放晴!7e1e3a52025-06-05 23:00:51 +0800134 <div className={styles.statLabel}>互关</div>
135 </div>
136 </div>
137
138 <div className={styles.userData}>
139 <div className={styles.dataItem}>
140 <span>您的总上传量为:</span>
阳菜,放晴!77743f42025-06-06 23:04:08 +0800141 <strong>{userStats?.uploadAmount ?? '--'}</strong>
阳菜,放晴!7e1e3a52025-06-05 23:00:51 +0800142 </div>
143 <div className={styles.dataItem}>
144 <span>您的用户等级为:</span>
阳菜,放晴!77743f42025-06-06 23:04:08 +0800145 <strong>{userStats?.level ?? '--'}</strong>
阳菜,放晴!7e1e3a52025-06-05 23:00:51 +0800146 </div>
147 </div>
148
149 <div className={styles.worksSection}>
150 <h3 className={styles.sectionTitle}>我的作品</h3>
阳菜,放晴!77743f42025-06-06 23:04:08 +0800151 {workloading && <div className={styles.loading}>加载中...</div>}
152 {workerror && <div className={styles.error}>{workerror.message}</div>}
阳菜,放晴!7e1e3a52025-06-05 23:00:51 +0800153
阳菜,放晴!77743f42025-06-06 23:04:08 +0800154 {works.map(work => (
阳菜,放晴!7e1e3a52025-06-05 23:00:51 +0800155 <div key={work.postId} className={styles.workItem}>
156 <h4 className={styles.workTitle}>{work.postTitle}</h4>
157 <div className={styles.workMeta}>
158 <span>发布时间:{work.createdAt}</span>
159 <span>下载量:{work.viewCount} 做种数:{'待定'}</span>
160 </div>
161 </div>
162 )) }
163 </div>
164 </div>
165
166 {/* 右侧内容区 */}
167 <div className={styles.rightContent}>
168 <div className={styles.petSection}>
169 <h3 className={styles.sectionTitle}>宠物图</h3>
170 <div className={styles.petContainer}>
171 <img
172 src="/assets/pet-blue-star.png"
173 alt="蓝色星星宠物"
174 className={styles.petImage}
175 />
176 </div>
177 </div>
178
179 </div>
180 </div>
181 </div>
182 );
183};
184
185export default Homepage;