AnCao/web/src/pages/Profile.tsx
yanlongqi 6446508954 实现完整的错题本功能模块
后端实现:
- 创建错题数据模型和数据库表结构
- 实现错题记录、查询、统计、标记和清空API
- 答题错误时自动记录到错题本
- 支持重复错误累计次数和更新时间

前端实现:
- 创建错题本页面,支持查看、筛选和管理错题
- 实现错题统计展示(总数、已掌握、待掌握)
- 支持标记已掌握、清空错题本和重做题目
- 在首页和个人中心添加错题本入口
- 完整的响应式设计适配移动端和PC端

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-04 13:44:51 +08:00

149 lines
3.8 KiB
TypeScript

import React, { useState, useEffect } from 'react'
import { useNavigate } from 'react-router-dom'
import {
Card,
Avatar,
List,
Button,
Modal,
message,
Typography,
Space,
} from 'antd'
import {
RightOutlined,
SettingOutlined,
FileTextOutlined,
UserOutlined,
BookOutlined,
} from '@ant-design/icons'
import styles from './Profile.module.less'
const { Title, Text } = Typography
interface UserInfo {
username: string
nickname: string
avatar: string
}
const Profile: React.FC = () => {
const navigate = useNavigate()
const [userInfo, setUserInfo] = useState<UserInfo | null>(null)
useEffect(() => {
// 从 localStorage 获取用户信息
const token = localStorage.getItem('token')
const savedUserInfo = localStorage.getItem('user')
if (token && savedUserInfo) {
try {
setUserInfo(JSON.parse(savedUserInfo))
} catch (e) {
console.error('解析用户信息失败', e)
}
}
}, [])
const handleLogout = () => {
Modal.confirm({
title: '确定要退出登录吗?',
onOk: () => {
localStorage.removeItem('token')
localStorage.removeItem('user')
setUserInfo(null)
message.success('已退出登录')
navigate('/login')
},
})
}
const handleLogin = () => {
navigate('/login')
}
return (
<div className={styles.container}>
<div className={styles.content}>
{/* 用户信息卡片 */}
<Card className={styles.userCard}>
{userInfo ? (
<div className={styles.userInfo}>
<Avatar
src={userInfo.avatar || undefined}
size={80}
icon={<UserOutlined />}
/>
<div className={styles.userDetails}>
<Title level={4} className={styles.userNickname}>{userInfo.nickname}</Title>
<Text type="secondary" className={styles.userUsername}>@{userInfo.username}</Text>
</div>
</div>
) : (
<div className={styles.userInfo}>
<Avatar size={80} icon={<UserOutlined />} />
<div className={styles.userDetails}>
<Title level={4} className={styles.userNickname}></Title>
<Button type="primary" onClick={handleLogin} style={{ marginTop: 8 }}>
</Button>
</div>
</div>
)}
</Card>
{/* 功能列表 */}
<Card title="功能" className={styles.menuCard}>
<List>
<List.Item
onClick={() => navigate('/wrong-questions')}
style={{ cursor: 'pointer' }}
>
<Space>
<BookOutlined />
<span></span>
</Space>
<RightOutlined />
</List.Item>
<List.Item
onClick={() => message.info('功能开发中')}
style={{ cursor: 'pointer' }}
>
<Space>
<FileTextOutlined />
<span></span>
</Space>
<RightOutlined />
</List.Item>
<List.Item
onClick={() => message.info('功能开发中')}
style={{ cursor: 'pointer' }}
>
<Space>
<SettingOutlined />
<span></span>
</Space>
<RightOutlined />
</List.Item>
</List>
</Card>
{/* 退出登录按钮 */}
{userInfo && (
<Button
danger
block
size="large"
onClick={handleLogout}
className={styles.logoutButton}
>
退
</Button>
)}
</div>
</div>
)
}
export default Profile