blob: 165ed67313f18f9c3fa5abb5127703b114730f6a [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';
阳菜,放晴!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
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);
阳菜,放晴!6f6d5c02025-06-07 22:27:25 +080067 const data = res?.userInfo;
68
69 const formatted: UserStats = {
70 username: data.username,
71 uploadAmount: data.uploadAmount,
72 level: data.level,
73 likes: data.likes,
74 following: data.following,
75 followers: data.followers,
76 mutualFollows: data.mutualFollows
77 };
78
79 setUserStats(formatted);
阳菜,放晴!77743f42025-06-06 23:04:08 +080080 }catch(error){
81 console.error('获取用户信息错误', error);
82 }
83 },1000) as () => void;
84
85
86 const getUserPost = debounce(async () => {
87 try{
阳菜,放晴!6f6d5c02025-06-07 22:27:25 +080088
89 const url = `${getUserMessage}?userId=${userId}`;
90 console.log("请求发送:", url);
91
阳菜,放晴!77743f42025-06-06 23:04:08 +080092 const res = await getUserMessageRefresh({userId});
93 console.log("res", res);
94 worksRef.current = res;
95 setWorks(res);
96 }catch(error) {
97 console.error('获取帖子列表错误', error);
98 }
99 },1000) as () => void;
100
阳菜,放晴!7e1e3a52025-06-05 23:00:51 +0800101 useEffect(() => {
阳菜,放晴!77743f42025-06-06 23:04:08 +0800102 if (!userId) {
103 navigate('/login');
104 }
105 else {
106 getUserDetails();
107 getUserPost();
108 }
109 }, [userId]);
110
111 if (!userId) return null;
112
阳菜,放晴!7e1e3a52025-06-05 23:00:51 +0800113
114 return (
115 <div className={styles.container}>
116
117
118 {/* 用户信息主区域 */}
119 <div className={styles.mainContent}>
120 {/* 左侧用户信息区 */}
121 <div className={styles.userProfile}>
122 <div className={styles.userHeader}>
123 <img
124 src={userInfo.avatar || '/default-avatar.png'}
125 alt="用户头像"
126 className={styles.userAvatar}
127 />
128 <div className={styles.userInfo}>
阳菜,放晴!6f6d5c02025-06-07 22:27:25 +0800129 <h2 className={styles.username}>{userStats?.username}</h2>
130 <div className={styles.inviteCode}>邀请码:123456</div>
阳菜,放晴!7e1e3a52025-06-05 23:00:51 +0800131 <button className={styles.editButton}>编辑主页</button>
阳菜,放晴!7e1e3a52025-06-05 23:00:51 +0800132 </div>
133 </div>
134
135 <div className={styles.userStats}>
136 <div className={styles.statItem}>
阳菜,放晴!77743f42025-06-06 23:04:08 +0800137 <div className={styles.statNumber}>{userStats?.likes ?? '--'}</div>
阳菜,放晴!7e1e3a52025-06-05 23:00:51 +0800138 <div className={styles.statLabel}>获赞</div>
139 </div>
140 <div className={styles.statItem}>
阳菜,放晴!77743f42025-06-06 23:04:08 +0800141 <div className={styles.statNumber}>{userStats?.following ?? '--'}</div>
阳菜,放晴!7e1e3a52025-06-05 23:00:51 +0800142 <div className={styles.statLabel}>关注</div>
143 </div>
144 <div className={styles.statItem}>
阳菜,放晴!77743f42025-06-06 23:04:08 +0800145 <div className={styles.statNumber}>{userStats?.followers ?? '--'}</div>
阳菜,放晴!7e1e3a52025-06-05 23:00:51 +0800146 <div className={styles.statLabel}>粉丝</div>
147 </div>
148 <div className={styles.statItem}>
阳菜,放晴!77743f42025-06-06 23:04:08 +0800149 <div className={styles.statNumber}>{userStats?.mutualFollows ?? '--'}</div>
阳菜,放晴!7e1e3a52025-06-05 23:00:51 +0800150 <div className={styles.statLabel}>互关</div>
151 </div>
152 </div>
153
154 <div className={styles.userData}>
155 <div className={styles.dataItem}>
156 <span>您的总上传量为:</span>
阳菜,放晴!77743f42025-06-06 23:04:08 +0800157 <strong>{userStats?.uploadAmount ?? '--'}</strong>
阳菜,放晴!7e1e3a52025-06-05 23:00:51 +0800158 </div>
159 <div className={styles.dataItem}>
160 <span>您的用户等级为:</span>
阳菜,放晴!77743f42025-06-06 23:04:08 +0800161 <strong>{userStats?.level ?? '--'}</strong>
阳菜,放晴!7e1e3a52025-06-05 23:00:51 +0800162 </div>
163 </div>
164
165 <div className={styles.worksSection}>
166 <h3 className={styles.sectionTitle}>我的作品</h3>
阳菜,放晴!77743f42025-06-06 23:04:08 +0800167 {workloading && <div className={styles.loading}>加载中...</div>}
168 {workerror && <div className={styles.error}>{workerror.message}</div>}
阳菜,放晴!7e1e3a52025-06-05 23:00:51 +0800169
阳菜,放晴!77743f42025-06-06 23:04:08 +0800170 {works.map(work => (
阳菜,放晴!7e1e3a52025-06-05 23:00:51 +0800171 <div key={work.postId} className={styles.workItem}>
172 <h4 className={styles.workTitle}>{work.postTitle}</h4>
173 <div className={styles.workMeta}>
174 <span>发布时间:{work.createdAt}</span>
175 <span>下载量:{work.viewCount} 做种数:{'待定'}</span>
176 </div>
177 </div>
178 )) }
179 </div>
180 </div>
181
182 {/* 右侧内容区 */}
183 <div className={styles.rightContent}>
184 <div className={styles.petSection}>
185 <h3 className={styles.sectionTitle}>宠物图</h3>
186 <div className={styles.petContainer}>
187 <img
阳菜,放晴!6f6d5c02025-06-07 22:27:25 +0800188 src={Logo}
阳菜,放晴!7e1e3a52025-06-05 23:00:51 +0800189 alt="蓝色星星宠物"
190 className={styles.petImage}
191 />
192 </div>
193 </div>
194
195 </div>
196 </div>
197 </div>
198 );
199};
200
201export default Homepage;