blob: 697ed8f868f7a9dae2c3a2002e16f268bc1e8c04 [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';
阳菜,放晴!54d564d2025-06-08 00:02:22 +08004import { useAppSelector } from '@/hooks/store';
阳菜,放晴!7e1e3a52025-06-05 23:00:51 +08005import { RootState } from '@/store';
6import { useNavigate } from 'react-router';
阳菜,放晴!6f6d5c02025-06-07 22:27:25 +08007import 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
阳菜,放晴!7e1e3a52025-06-05 23:00:51 +080049 const navigate = useNavigate();
阳菜,放晴!54d564d2025-06-08 00:02:22 +080050 const userInfo = useAppSelector((state: RootState) => state.user);
阳菜,放晴!77743f42025-06-06 23:04:08 +080051 const userId = userInfo.userId; // 从Redux获取当前用户ID
52
阳菜,放晴!54d564d2025-06-08 00:02:22 +080053
阳菜,放晴!77743f42025-06-06 23:04:08 +080054 const { data:userdata, loading:userloading, error:usererror, refresh: getUserDetailRefresh } = useApi(
阳菜,放晴!54d564d2025-06-08 00:02:22 +080055 () => request.get(getUserDetail, {params: {userId}}),
56 false
阳菜,放晴!77743f42025-06-06 23:04:08 +080057 );
58
阳菜,放晴!54d564d2025-06-08 00:02:22 +080059 const { data: workdata, loading: workloading, error: workerror, refresh: getUserMessageRefresh } = useApi(
60 () => request.get(`${getUserMessage}/${userId}`), // 注意这里拼接了 userId
阳菜,放晴!77743f42025-06-06 23:04:08 +080061 false
62 );
63
64 const getUserDetails = debounce(async () => {
65 try{
阳菜,放晴!54d564d2025-06-08 00:02:22 +080066 // const res = await getUserDetailRefresh({userId});
67 const res = await getUserDetailRefresh();
68 const data_1 = res?.userInfo;
69 const data_2 = res?.statistics;
70 console.log('data', data_1)
阳菜,放晴!6f6d5c02025-06-07 22:27:25 +080071 const formatted: UserStats = {
阳菜,放晴!54d564d2025-06-08 00:02:22 +080072 username: data_1.userName,
73 uploadAmount: data_1.uploadAmount,
74 level: data_1.userLevel,
75 likes: data_2.likes,
76 following: data_2.followingCount,
77 followers: data_2.followersCount,
78 mutualFollows: data_2.mutualFollows
阳菜,放晴!6f6d5c02025-06-07 22:27:25 +080079 };
80
81 setUserStats(formatted);
阳菜,放晴!54d564d2025-06-08 00:02:22 +080082 console.log('formatted:',formatted)
阳菜,放晴!77743f42025-06-06 23:04:08 +080083 }catch(error){
84 console.error('获取用户信息错误', error);
85 }
86 },1000) as () => void;
87
88
89 const getUserPost = debounce(async () => {
阳菜,放晴!54d564d2025-06-08 00:02:22 +080090 try {
91 const url = `${getUserMessage}/${userId}`; // ✅ 正确的 URL 拼接方式
阳菜,放晴!6f6d5c02025-06-07 22:27:25 +080092 console.log("请求发送:", url);
93
阳菜,放晴!54d564d2025-06-08 00:02:22 +080094 // 不需要传 userId 参数了,因为 URL 已包含它
95 const res = await getUserMessageRefresh();
阳菜,放晴!77743f42025-06-06 23:04:08 +080096 console.log("res", res);
阳菜,放晴!54d564d2025-06-08 00:02:22 +080097
阳菜,放晴!77743f42025-06-06 23:04:08 +080098 worksRef.current = res;
99 setWorks(res);
阳菜,放晴!54d564d2025-06-08 00:02:22 +0800100 } catch (error) {
阳菜,放晴!77743f42025-06-06 23:04:08 +0800101 console.error('获取帖子列表错误', error);
102 }
阳菜,放晴!54d564d2025-06-08 00:02:22 +0800103 }, 1000) as () => void;
104
阳菜,放晴!77743f42025-06-06 23:04:08 +0800105
阳菜,放晴!7e1e3a52025-06-05 23:00:51 +0800106 useEffect(() => {
阳菜,放晴!77743f42025-06-06 23:04:08 +0800107 if (!userId) {
108 navigate('/login');
109 }
110 else {
111 getUserDetails();
112 getUserPost();
113 }
114 }, [userId]);
115
116 if (!userId) return null;
117
阳菜,放晴!7e1e3a52025-06-05 23:00:51 +0800118
119 return (
120 <div className={styles.container}>
121
122
123 {/* 用户信息主区域 */}
124 <div className={styles.mainContent}>
125 {/* 左侧用户信息区 */}
126 <div className={styles.userProfile}>
127 <div className={styles.userHeader}>
128 <img
129 src={userInfo.avatar || '/default-avatar.png'}
130 alt="用户头像"
131 className={styles.userAvatar}
132 />
133 <div className={styles.userInfo}>
阳菜,放晴!6f6d5c02025-06-07 22:27:25 +0800134 <h2 className={styles.username}>{userStats?.username}</h2>
135 <div className={styles.inviteCode}>邀请码:123456</div>
阳菜,放晴!7e1e3a52025-06-05 23:00:51 +0800136 <button className={styles.editButton}>编辑主页</button>
阳菜,放晴!7e1e3a52025-06-05 23:00:51 +0800137 </div>
138 </div>
139
140 <div className={styles.userStats}>
141 <div className={styles.statItem}>
阳菜,放晴!77743f42025-06-06 23:04:08 +0800142 <div className={styles.statNumber}>{userStats?.likes ?? '--'}</div>
阳菜,放晴!7e1e3a52025-06-05 23:00:51 +0800143 <div className={styles.statLabel}>获赞</div>
144 </div>
145 <div className={styles.statItem}>
阳菜,放晴!77743f42025-06-06 23:04:08 +0800146 <div className={styles.statNumber}>{userStats?.following ?? '--'}</div>
阳菜,放晴!7e1e3a52025-06-05 23:00:51 +0800147 <div className={styles.statLabel}>关注</div>
148 </div>
149 <div className={styles.statItem}>
阳菜,放晴!77743f42025-06-06 23:04:08 +0800150 <div className={styles.statNumber}>{userStats?.followers ?? '--'}</div>
阳菜,放晴!7e1e3a52025-06-05 23:00:51 +0800151 <div className={styles.statLabel}>粉丝</div>
152 </div>
153 <div className={styles.statItem}>
阳菜,放晴!77743f42025-06-06 23:04:08 +0800154 <div className={styles.statNumber}>{userStats?.mutualFollows ?? '--'}</div>
阳菜,放晴!7e1e3a52025-06-05 23:00:51 +0800155 <div className={styles.statLabel}>互关</div>
156 </div>
157 </div>
158
159 <div className={styles.userData}>
160 <div className={styles.dataItem}>
161 <span>您的总上传量为:</span>
阳菜,放晴!77743f42025-06-06 23:04:08 +0800162 <strong>{userStats?.uploadAmount ?? '--'}</strong>
阳菜,放晴!7e1e3a52025-06-05 23:00:51 +0800163 </div>
164 <div className={styles.dataItem}>
165 <span>您的用户等级为:</span>
阳菜,放晴!77743f42025-06-06 23:04:08 +0800166 <strong>{userStats?.level ?? '--'}</strong>
阳菜,放晴!7e1e3a52025-06-05 23:00:51 +0800167 </div>
168 </div>
169
170 <div className={styles.worksSection}>
171 <h3 className={styles.sectionTitle}>我的作品</h3>
阳菜,放晴!77743f42025-06-06 23:04:08 +0800172 {workloading && <div className={styles.loading}>加载中...</div>}
173 {workerror && <div className={styles.error}>{workerror.message}</div>}
阳菜,放晴!7e1e3a52025-06-05 23:00:51 +0800174
阳菜,放晴!77743f42025-06-06 23:04:08 +0800175 {works.map(work => (
阳菜,放晴!7e1e3a52025-06-05 23:00:51 +0800176 <div key={work.postId} className={styles.workItem}>
177 <h4 className={styles.workTitle}>{work.postTitle}</h4>
178 <div className={styles.workMeta}>
179 <span>发布时间:{work.createdAt}</span>
180 <span>下载量:{work.viewCount} 做种数:{'待定'}</span>
181 </div>
182 </div>
183 )) }
184 </div>
185 </div>
186
187 {/* 右侧内容区 */}
188 <div className={styles.rightContent}>
189 <div className={styles.petSection}>
190 <h3 className={styles.sectionTitle}>宠物图</h3>
191 <div className={styles.petContainer}>
192 <img
阳菜,放晴!6f6d5c02025-06-07 22:27:25 +0800193 src={Logo}
阳菜,放晴!7e1e3a52025-06-05 23:00:51 +0800194 alt="蓝色星星宠物"
195 className={styles.petImage}
196 />
197 </div>
198 </div>
199
200 </div>
201 </div>
202 </div>
203 );
204};
205
206export default Homepage;