blob: dab0c0f7112697008e0c6e8127cddfc910ea46c9 [file] [log] [blame]
import React, { useCallback, useEffect,useState,useRef } from 'react';
import styles from './homepage.module.css';
import { useApi } from '@/hooks/request';
import { useAppSelector } from '@/hooks/store';
import { RootState } from '@/store';
import { useNavigate } from 'react-router';
import Logo from '&/assets/logo.png';
import { getUserMessage } from '@/api/homepage'
import { getUserDetail } from '@/api/homepage'
import request from '@/utils/request'
// import { hotPosts } from '@/api/post';
import { postUserLogin } from '@/api/auth';
import { debounce } from 'lodash';
import { Q } from 'react-router/dist/development/fog-of-war-CGNKxM4z';
import head from '&/assets/head.jpg'
import lv_one from '&/assets/pet/lv_one.png'
import lv_two from '&/assets/pet/lv_two.png'
import lv_three from '&/assets/pet/lv_three.png'
import lv_four from '&/assets/pet/lv_four.png'
import lv_five from '&/assets/pet/lv_five.png'
import PetGame from '@/components/pet'
interface WorkItem {
postId: number,
userId: number,
postTitle: string,
postContent: string,
createdAt: number,
postType: string,
isLocked: boolean,
lockedReason: string,
lockedAt: string,
lockedBy: number,
viewCount: number,
hotScore: number,
lastCalculated: number
}
interface UserStats {
username: string;
uploadAmount: number;
level: string;
likes: number;
following: number;
followers: number;
mutualFollows: number;
}
const Homepage: React.FC =() => {
const [userStats, setUserStats] = useState<UserStats | null>(null);
const [works, setWorks] = useState<WorkItem[]>([]);
const worksRef = useRef<WorkItem[]>([]);
const navigate = useNavigate();
const userInfo = useAppSelector((state: RootState) => state.user);
const userId = userInfo.userId; // 从Redux获取当前用户ID
const levelImages: { [key: string]: string } = {
'lv1': lv_one,
'lv2': lv_two,
'lv3': lv_three,
'lv4': lv_four,
'lv5': lv_five
};
const { data:userdata, loading:userloading, error:usererror, refresh: getUserDetailRefresh } = useApi(
() => request.get(getUserDetail, {params: {userId}}),
false
);
const { data: workdata, loading: workloading, error: workerror, refresh: getUserMessageRefresh } = useApi(
() => request.get(`${getUserMessage}/${userId}`), // 注意这里拼接了 userId
false
);
const getUserDetails = debounce(async () => {
try{
// const res = await getUserDetailRefresh({userId});
const res = await getUserDetailRefresh();
const data_1 = res?.userInfo;
const data_2 = res?.statistics;
console.log('data', data_1)
const formatted: UserStats = {
username: data_1.userName,
uploadAmount: data_1.uploadAmount,
level: data_1.userLevel,
likes: data_2.likes,
following: data_2.followingCount,
followers: data_2.followersCount,
mutualFollows: data_2.mutualFollows
};
setUserStats(formatted);
console.log('formatted:',formatted)
}catch(error){
console.error('获取用户信息错误', error);
}
},1000) as () => void;
const getUserPost = debounce(async () => {
try {
const url = `${getUserMessage}/${userId}`; // ✅ 正确的 URL 拼接方式
console.log("请求发送:", url);
// 不需要传 userId 参数了,因为 URL 已包含它
const res = await getUserMessageRefresh();
console.log("res", res);
worksRef.current = res;
setWorks(res);
} catch (error) {
console.error('获取帖子列表错误', error);
}
}, 1000) as () => void;
useEffect(() => {
if (!userId) {
navigate('/login');
}
else {
getUserDetails();
getUserPost();
}
}, [userId]);
if (!userId) return null;
return (
<div className={styles.container}>
{/* 用户信息主区域 */}
<div className={styles.mainContent}>
{/* 左侧用户信息区 */}
<div className={styles.userProfile}>
<div className={styles.userHeader}>
<img
src={head}
alt="用户头像"
className={styles.userAvatar}
/>
<div className={styles.userInfo}>
<h2 className={styles.username}>{userStats?.username}</h2>
<div className={styles.inviteCode}>邀请码:123456</div>
<button className={styles.editButton}>编辑主页</button>
</div>
</div>
<div className={styles.userStats}>
<div className={styles.statItem}>
<div className={styles.statNumber}>{userStats?.likes ?? '--'}</div>
<div className={styles.statLabel}>获赞</div>
</div>
<div className={styles.statItem}>
<div className={styles.statNumber}>{userStats?.following ?? '--'}</div>
<div className={styles.statLabel}>关注</div>
</div>
<div className={styles.statItem}>
<div className={styles.statNumber}>{userStats?.followers ?? '--'}</div>
<div className={styles.statLabel}>粉丝</div>
</div>
{/* <div className={styles.statItem}>
<div className={styles.statNumber}>{userStats?.mutualFollows ?? '--'}</div>
<div className={styles.statLabel}>互关</div>
</div> */}
</div>
<div className={styles.userData}>
<div className={styles.dataItem}>
<span>您的总上传量为:</span>
<strong>{userStats?.uploadAmount ?? '--'}</strong>
</div>
<div className={styles.dataItem}>
<span>您的用户等级为:</span>
<strong>{userStats?.level ?? '--'}</strong>
</div>
</div>
<div className={styles.worksSection}>
<h3 className={styles.sectionTitle}>我的作品</h3>
{workloading && <div className={styles.loading}>加载中...</div>}
{workerror && <div className={styles.error}>{workerror.message}</div>}
{works.map(work => (
<div key={work.postId} className={styles.workItem}>
<h4 className={styles.workTitle}>{work.postTitle}</h4>
<div className={styles.workMeta}>
<span>发布时间:{work.createdAt}</span>
<span>下载量:{work.viewCount} 做种数:{'待定'}</span>
</div>
</div>
)) }
</div>
</div>
{/* 右侧内容区 */}
<div className={styles.rightContent}>
<div className={styles.petSection}>
<h3 className={styles.sectionTitle}>宠物图</h3>
<div className={styles.petContainer}>
<img
src={levelImages[userStats?.level || 'lv5']} // 默认用 '1' 级
alt={`等级${userStats?.level}宠物`}
className={styles.petImage}
/>
</div>
<PetGame/>
</div>
</div>
</div>
</div>
);
};
export default Homepage;