import { useEffect, useMemo, useState } from 'react'; import Taro from '@tarojs/taro'; import { Button, Text, View } from '@tarojs/components'; import { getTenantContext } from '@/services/api'; import { loadStudentDashboard, type DashboardSnapshot } from '@/services/catalog'; import { requireSignedIn } from '@/services/routeGuard'; import './index.css'; export default function StudentHomePage() { const tenant = getTenantContext(); const [snapshot, setSnapshot] = useState(null); const [userName, setUserName] = useState(''); useEffect(() => { requireSignedIn('/pages/student/home/index').then(payload => { if (payload) setUserName(payload.user?.name || payload.item?.name || ''); }).catch(() => undefined); loadStudentDashboard().then(setSnapshot).catch(() => setSnapshot({ entries: [], banners: [], announcements: [], profile: null })); }, []); const entryNames = useMemo(() => (snapshot?.entries || []).slice(0, 6), [snapshot]); const brandName = tenant?.branding.brandName || tenant?.branding.shortName || '工学题库'; const profile = snapshot?.profile && typeof snapshot.profile === 'object' ? snapshot.profile as Record : {}; const stats = profile.stats && typeof profile.stats === 'object' ? profile.stats as Record : {}; const answerStats = stats.answers && typeof stats.answers === 'object' ? stats.answers as Record : {}; const totalAnswered = Number(answerStats.totalAnswered || 0); const accuracy = Math.round(Number(answerStats.accuracy || 0) * 100); const wrongCount = Number((stats.wrongBook as Record | undefined)?.unresolvedWrong || 0); const quickActions = [ { name: '文化课', path: '/pages/student/catalog/index?entryType=subjects', meta: '必刷好题', tone: 'red' }, { name: '专业课', path: '/pages/student/catalog/index?entryType=exam_bank', meta: '专项练习', tone: 'blue' }, { name: '升本单词', path: '/pages/student/vocabulary/index', meta: '今日待背', tone: 'orange' }, { name: '知识手册', path: '/pages/student/handbook/index', meta: '考前速查', tone: 'green' }, { name: '错题本', path: '/pages/student/review/index?type=wrong', meta: '查漏补缺', tone: 'violet' }, { name: '收藏夹', path: '/pages/student/review/index?type=favorite', meta: '重点复习', tone: 'pink' }, { name: '练习报告', path: '/pages/student/reports/index', meta: '模考 / 历史', tone: 'slate' }, { name: '分数线', path: '/pages/student/scoreline/index', meta: '院校趋势', tone: 'blue' }, { name: 'AI择校', path: '/pages/student/ai-school/index', meta: 'SVIP报告', tone: 'violet' }, { name: '备考资料', path: '/pages/student/assets/index', meta: 'PDF 预览', tone: 'green' }, { name: '消息通知', path: '/pages/student/notifications/index', meta: '通知 / 待办', tone: 'orange' }, { name: '个人中心', path: '/pages/student/profile/index', meta: '会员 / 订单', tone: 'slate' }, ]; return ( {(userName || brandName || 'U').slice(0, 1).toUpperCase()} Hi, {userName || '同学'} {brandName} · 今天也要加油刷题哦 今天也是元气满满的一天 继续你的备考之旅 已经连续学习的每一天,都会让你离目标院校更近一步。 {String(totalAnswered)} 累计刷题 {accuracy ? `${accuracy}%` : '--'} 正确率 Taro.navigateTo({ url: '/pages/student/review/index?type=wrong' })}> {String(wrongCount)} 错题本 学习入口 {entryNames.length ? entryNames.map(item => ( Taro.navigateTo({ url: `/pages/student/catalog/index?entryId=${item.id}` })}> 已配置入口 {item.name} {item.entryType || 'content'} )) : quickActions.map(item => ( Taro.navigateTo({ url: item.path })}> {item.meta} {item.name} 点击进入 ))} 全部功能 {quickActions.map(item => ( Taro.navigateTo({ url: item.path })}> {item.name} {item.meta} ))} ); }