diff --git a/CLAUDE.md b/CLAUDE.md index e309b56..133a013 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -78,7 +78,7 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co - 图表数据实时生成,确保演示效果 ## 当前状态 -项目已完成基础架构和主要功能模块开发(完成度约85%): +项目已完成所有核心功能模块开发(完成度100%): ### 已完成功能模块 ✅ - **基础架构**:Vue3 + ElementPlus + ECharts技术栈完整搭建 @@ -86,12 +86,11 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co - **仪表盘工作台**:专业级Dashboard界面,统计卡片和功能模块 - **评价管理功能**:完整的评价流程,支持多角色评价和文件上传 - **学生画像功能**:教师专属,包含ECharts图表和综合评价报告 -- **侧边栏导航系统**:固定导航,角色权限适配 - -### 待开发功能模块 🔄 -- **评价报告页面**:Report.vue(当前仅占位) -- **报告子页面**:发展监测(/report/{id}/monitor)、能力分析(/report/{id}/analysis) -- **路由完善**:补充缺失的子路由配置 +- **评价报告系统**:完整的学生评价报告功能 ✅ + - Report.vue主页面:学生信息、评价汇总、导航入口 + - 发展监测页面:趋势图表、里程碑事件、数据分析 + - 能力分析页面:六维雷达图、优劣势分析、发展建议 +- **侧边栏导航系统**:固定导航,角色权限适配,所有功能已连通 ### 最近更新(2025-01-15) diff --git a/src/components/AbilityRadarChart.vue b/src/components/AbilityRadarChart.vue index 313b3b4..c7e0a31 100644 --- a/src/components/AbilityRadarChart.vue +++ b/src/components/AbilityRadarChart.vue @@ -58,9 +58,14 @@ export default { center: ['50%', '55%'] } + // 获取CSS变量的实际值 + const getCSSVariable = (variable) => { + return getComputedStyle(document.documentElement).getPropertyValue(variable).trim() + } + const colors = [ - 'var(--primary)', 'var(--secondary)', 'var(--success)', - 'var(--warning)', 'var(--danger)', 'var(--secondary-light)' + getCSSVariable('--primary'), getCSSVariable('--secondary'), getCSSVariable('--success'), + getCSSVariable('--warning'), getCSSVariable('--danger'), getCSSVariable('--secondary-light') ] const getColor = (index) => colors[index % colors.length] @@ -77,11 +82,11 @@ export default { formatter: function(params) { return `${params.name}
得分: ${params.value}` }, - backgroundColor: 'var(--bg-primary)', - borderColor: 'var(--border)', + backgroundColor: getCSSVariable('--bg-primary'), + borderColor: getCSSVariable('--border'), borderWidth: 1, textStyle: { - color: 'var(--text-primary)' + color: getCSSVariable('--text-primary') } }, radar: { @@ -89,7 +94,7 @@ export default { radius: CHART_CONFIG.radius, name: { textStyle: { - color: 'var(--text-secondary)', + color: getCSSVariable('--text-secondary'), fontSize: 12, fontWeight: 500 } @@ -97,7 +102,7 @@ export default { indicator: props.dimensions.map(name => ({ name, max: 100, - color: 'var(--text-primary)' + color: getCSSVariable('--text-primary') })), splitArea: { areaStyle: { @@ -112,13 +117,13 @@ export default { }, splitLine: { lineStyle: { - color: 'var(--border-light)', + color: getCSSVariable('--border-light'), width: 1 } }, axisLine: { lineStyle: { - color: 'var(--border)', + color: getCSSVariable('--border'), width: 1 } } @@ -133,12 +138,12 @@ export default { color: 'rgba(59, 130, 246, 0.1)' }, lineStyle: { - color: 'var(--primary)', + color: getCSSVariable('--primary'), width: CHART_CONFIG.lineWidth }, itemStyle: { - color: 'var(--primary)', - borderColor: 'var(--bg-primary)', + color: getCSSVariable('--primary'), + borderColor: getCSSVariable('--bg-primary'), borderWidth: CHART_CONFIG.borderWidth }, data: [ diff --git a/src/components/GradeDistributionChart.vue b/src/components/GradeDistributionChart.vue index 4d24db8..530be5d 100644 --- a/src/components/GradeDistributionChart.vue +++ b/src/components/GradeDistributionChart.vue @@ -88,6 +88,11 @@ export default { return gradeMap[grade] || 'grade-default' } + // 获取CSS变量的实际值 + const getCSSVariable = (variable) => { + return getComputedStyle(document.documentElement).getPropertyValue(variable).trim() + } + const initChart = () => { if (!chartContainer.value) return @@ -107,18 +112,18 @@ export default { }) return result }, - backgroundColor: 'var(--bg-primary)', - borderColor: 'var(--border)', + backgroundColor: getCSSVariable('--bg-primary'), + borderColor: getCSSVariable('--border'), borderWidth: 1, textStyle: { - color: 'var(--text-primary)' + color: getCSSVariable('--text-primary') } }, legend: { data: ['个人成绩', '班级平均'], top: CHART_CONFIG.legend.top, textStyle: { - color: 'var(--text-secondary)', + color: getCSSVariable('--text-secondary'), fontSize: CHART_CONFIG.legend.fontSize } }, @@ -131,11 +136,11 @@ export default { data: subjects.value, axisLine: { lineStyle: { - color: 'var(--border-light)' + color: getCSSVariable('--border-light') } }, axisLabel: { - color: 'var(--text-secondary)', + color: getCSSVariable('--text-secondary'), fontSize: CHART_CONFIG.axis.fontSize, interval: 0, rotate: CHART_CONFIG.axis.rotate, @@ -149,19 +154,19 @@ export default { type: 'value', name: '分数', nameTextStyle: { - color: 'var(--text-secondary)', + color: getCSSVariable('--text-secondary'), fontSize: CHART_CONFIG.legend.fontSize }, axisLine: { show: false }, axisLabel: { - color: 'var(--text-secondary)', + color: getCSSVariable('--text-secondary'), fontSize: CHART_CONFIG.axis.fontSize }, splitLine: { lineStyle: { - color: 'var(--border-light)', + color: getCSSVariable('--border-light'), type: 'dashed' } }, @@ -175,16 +180,16 @@ export default { data: scores.value, itemStyle: { color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [ - { offset: 0, color: 'var(--primary)' }, - { offset: 1, color: 'var(--primary-light)' } + { offset: 0, color: getCSSVariable('--primary') }, + { offset: 1, color: getCSSVariable('--primary-light') } ]), borderRadius: CHART_CONFIG.borderRadius }, emphasis: { itemStyle: { color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [ - { offset: 0, color: 'var(--primary)' }, - { offset: 1, color: 'var(--primary-light)' } + { offset: 0, color: getCSSVariable('--primary') }, + { offset: 1, color: getCSSVariable('--primary-light') } ]) } }, @@ -196,16 +201,16 @@ export default { data: classAverage.value, itemStyle: { color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [ - { offset: 0, color: 'var(--success)' }, - { offset: 1, color: 'var(--success-light)' } + { offset: 0, color: getCSSVariable('--success') }, + { offset: 1, color: getCSSVariable('--success-light') } ]), borderRadius: CHART_CONFIG.borderRadius }, emphasis: { itemStyle: { color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [ - { offset: 0, color: 'var(--success)' }, - { offset: 1, color: 'var(--success-light)' } + { offset: 0, color: getCSSVariable('--success') }, + { offset: 1, color: getCSSVariable('--success-light') } ]) } }, diff --git a/src/main.js b/src/main.js index fa71653..efc6d96 100644 --- a/src/main.js +++ b/src/main.js @@ -2,10 +2,12 @@ import { createApp } from 'vue' import { createPinia } from 'pinia' import ElementPlus from 'element-plus' import 'element-plus/dist/index.css' +import { ElMessage } from 'element-plus' import * as ElementPlusIconsVue from '@element-plus/icons-vue' import router from './router' import App from './App.vue' import GlobalComponents from './components' +import { useAuthStore } from './stores/auth' const app = createApp(App) const pinia = createPinia() @@ -20,4 +22,33 @@ app.use(router) app.use(ElementPlus) app.use(GlobalComponents) +// 在Pinia初始化后设置路由守卫 +router.beforeEach((to, from, next) => { + const authStore = useAuthStore() + + // 检查登录状态 + authStore.checkAuth() + + // 如果访问登录页且已登录,重定向到首页 + if (to.name === 'Login' && authStore.isLoggedIn) { + return next('/home') + } + + // 如果路由需要认证 + if (to.meta.requiresAuth) { + if (!authStore.isLoggedIn) { + ElMessage.error('请先登录') + return next('/') + } + + // 如果路由需要特定角色 + if (to.meta.role && authStore.user?.role !== to.meta.role) { + ElMessage.error('您没有权限访问该页面') + return next('/home') + } + } + + next() +}) + app.mount('#app') \ No newline at end of file diff --git a/src/router/index.js b/src/router/index.js index 475c7ee..83090e1 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -1,6 +1,4 @@ import { createRouter, createWebHistory } from 'vue-router' -import { useAuthStore } from '@/stores/auth' -import { ElMessage } from 'element-plus' const routes = [ { @@ -34,6 +32,16 @@ const routes = [ path: 'report/:studentId', name: 'Report', component: () => import('@/views/Report.vue') + }, + { + path: 'report/:studentId/monitor', + name: 'ReportMonitor', + component: () => import('@/views/ReportMonitor.vue') + }, + { + path: 'report/:studentId/analysis', + name: 'ReportAnalysis', + component: () => import('@/views/ReportAnalysis.vue') } ] } @@ -44,33 +52,4 @@ const router = createRouter({ routes }) -// 路由守卫 -router.beforeEach((to, from, next) => { - const authStore = useAuthStore() - - // 检查登录状态 - authStore.checkAuth() - - // 如果访问登录页且已登录,重定向到首页 - if (to.name === 'Login' && authStore.isLoggedIn) { - return next('/home') - } - - // 如果路由需要认证 - if (to.meta.requiresAuth) { - if (!authStore.isLoggedIn) { - ElMessage.error('请先登录') - return next('/') - } - - // 如果路由需要特定角色 - if (to.meta.role && authStore.user?.role !== to.meta.role) { - ElMessage.error('您没有权限访问该页面') - return next('/home') - } - } - - next() -}) - export default router \ No newline at end of file diff --git a/src/utils/mockData.js b/src/utils/mockData.js index ed237e0..b16f7b9 100644 --- a/src/utils/mockData.js +++ b/src/utils/mockData.js @@ -297,24 +297,244 @@ export const mockProjectDetails = { ], skills: ['华为云服务', 'Spring Cloud', 'Docker', 'Kubernetes', 'Redis', 'MySQL'], participants: 25, - status: 'active' + startDate: '2024-09-15', + endDate: '2024-12-15', + status: 'completed' }, 'tencent-frontend': { id: 'tencent-frontend', name: '腾讯前端开发实习', company: '腾讯科技有限公司', duration: '4个月', - description: '参与腾讯核心产品的前端开发工作,学习大型前端项目的架构设计和性能优化技术。', + description: '腾讯前端团队实习项目,专注于大型Web应用开发、性能优化和用户体验提升。', requirements: [ '熟练掌握Vue.js/React框架', - '了解前端工程化和模块化', '具备响应式设计能力', - '掌握前端性能优化技术', + '了解前端工程化工具', + '掌握前端性能优化技巧', '具备良好的代码规范意识' ], - skills: ['Vue.js', 'React', 'TypeScript', 'Webpack', 'Element UI', 'Ant Design'], - participants: 20, - status: 'active' + skills: ['Vue.js', 'React', 'TypeScript', 'Webpack', 'Sass', 'Element UI'], + participants: 18, + startDate: '2024-08-01', + endDate: '2024-12-01', + status: 'completed' + } +} + +// 报告专用Mock数据 +export const mockReportData = { + // 发展趋势数据 + developmentTrends: { + 1: { // 张三的发展趋势 + monthlyScores: [ + { month: '2024-09', overall: 78.5, company: 80, teacher: 77, expert: 75, peer: 82 }, + { month: '2024-10', overall: 81.2, company: 83, teacher: 79, expert: 78, peer: 85 }, + { month: '2024-11', overall: 83.8, company: 85, teacher: 82, expert: 81, peer: 87 }, + { month: '2024-12', overall: 86.5, company: 88, teacher: 85, expert: 84, peer: 89 } + ], + abilityGrowth: [ + { ability: '技术能力', current: 85, previous: 78, growth: 7 }, + { ability: '沟通协调', current: 78, previous: 75, growth: 3 }, + { ability: '团队协作', current: 82, previous: 80, growth: 2 }, + { ability: '问题解决', current: 73, previous: 68, growth: 5 }, + { ability: '学习能力', current: 88, previous: 82, growth: 6 }, + { ability: '创新思维', current: 75, previous: 70, growth: 5 } + ], + rankingHistory: [ + { month: '2024-09', rank: 8, totalStudents: 30 }, + { month: '2024-10', rank: 6, totalStudents: 30 }, + { month: '2024-11', rank: 4, totalStudents: 30 }, + { month: '2024-12', rank: 2, totalStudents: 30 } + ] + }, + 2: { // 李四的发展趋势 + monthlyScores: [ + { month: '2024-09', overall: 82.3, company: 84, teacher: 81, expert: 79, peer: 85 }, + { month: '2024-10', overall: 84.1, company: 86, teacher: 83, expert: 82, peer: 86 }, + { month: '2024-11', overall: 85.9, company: 87, teacher: 85, expert: 84, peer: 87 }, + { month: '2024-12', overall: 87.2, company: 89, teacher: 86, expert: 85, peer: 88 } + ], + abilityGrowth: [ + { ability: '技术能力', current: 88, previous: 84, growth: 4 }, + { ability: '沟通协调', current: 80, previous: 78, growth: 2 }, + { ability: '团队协作', current: 85, previous: 82, growth: 3 }, + { ability: '问题解决', current: 76, previous: 72, growth: 4 }, + { ability: '学习能力', current: 90, previous: 85, growth: 5 }, + { ability: '创新思维', current: 78, previous: 74, growth: 4 } + ], + rankingHistory: [ + { month: '2024-09', rank: 5, totalStudents: 30 }, + { month: '2024-10', rank: 4, totalStudents: 30 }, + { month: '2024-11', rank: 3, totalStudents: 30 }, + { month: '2024-12', rank: 1, totalStudents: 30 } + ] + } + }, + + // 里程碑事件数据 + milestones: { + 1: [ // 张三的里程碑 + { + date: '2024-12-15', + title: '期末项目优秀', + description: '在企业合作项目中表现突出,获得优秀评价', + type: 'achievement', + score: '92.5', + category: '学术成就' + }, + { + date: '2024-11-20', + title: '技能提升显著', + description: '编程能力和团队协作能力都有明显提升', + type: 'improvement', + category: '能力发展' + }, + { + date: '2024-10-10', + title: '完成核心项目', + description: '成功完成华为云计算实训项目核心模块开发', + type: 'project', + score: '88.0', + category: '项目完成' + }, + { + date: '2024-09-25', + title: '获得实习奖励', + description: '在企业实习期间表现优异,获得实习优秀奖', + type: 'award', + category: '荣誉奖励' + } + ], + 2: [ // 李四的里程碑 + { + date: '2024-12-18', + title: '技术创新突破', + description: '在推荐算法项目中提出创新解决方案,效果显著', + type: 'achievement', + score: '94.0', + category: '技术创新' + }, + { + date: '2024-11-15', + title: '团队领导力', + description: '担任项目组长,带领团队完成复杂技术攻关', + type: 'improvement', + category: '领导能力' + }, + { + date: '2024-10-05', + title: '算法竞赛获奖', + description: '参加校级算法竞赛获得二等奖', + type: 'award', + category: '竞赛获奖' + } + ] + }, + + // 详细分析数据 + detailedAnalysis: { + 1: { // 张三的详细分析 + overallSummary: { + totalScore: 86.5, + ranking: 2, + percentile: 93, + improvement: '+8.0分', + trend: 'upward' + }, + dimensionAnalysis: { + strengths: [ + { + name: '学习能力', + score: 88, + description: '学习新知识和技能的能力突出,能够快速适应新的工作环境和要求', + evidence: ['主动学习新技术框架', '快速掌握项目需求', '积极参与技术分享'] + }, + { + name: '技术能力', + score: 85, + description: '编程技能扎实,具备良好的技术基础和实践能力', + evidence: ['代码质量高', '技术方案合理', '问题解决能力强'] + } + ], + improvements: [ + { + name: '问题解决', + score: 73, + description: '面对复杂问题时的分析和解决能力有待提升', + suggestions: ['加强逻辑思维训练', '多参与复杂项目挑战', '学习系统化问题分析方法'] + }, + { + name: '创新思维', + score: 75, + description: '创新意识和创造性思维需要进一步培养', + suggestions: ['多接触跨领域知识', '参与创新项目和竞赛', '培养批判性思维能力'] + } + ] + }, + roleEvaluations: { + enterprise: { + score: 88, + feedback: '实习期间表现优异,技术能力强,工作态度认真,具备良好的职业素养', + evaluator: '华为技术有限公司 - 张工程师', + strengths: ['技术实现能力', '学习适应能力', '工作责任心'], + improvements: ['项目管理经验', '跨部门沟通'] + }, + teacher: { + score: 85, + feedback: '理论基础扎实,实践能力强,课堂表现积极,作业质量高', + evaluator: '李老师 - 软件工程', + strengths: ['理论掌握', '实践应用', '学习态度'], + improvements: ['研究深度', '创新思维'] + }, + expert: { + score: 84, + feedback: '专业知识掌握良好,具备一定的行业认知,发展潜力较大', + evaluator: '王专家 - 行业协会', + strengths: ['专业素养', '发展潜力'], + improvements: ['行业洞察', '前沿技术'] + }, + peer: { + score: 89, + feedback: '团队合作能力强,乐于助人,沟通协调能力好', + evaluator: '同班同学', + strengths: ['团队精神', '沟通能力', '协作意识'], + improvements: ['领导能力', '组织协调'] + } + } + } + }, + + // 发展建议数据 + developmentSuggestions: { + 1: { // 张三的发展建议 + shortTerm: [ // 1-3个月 + '加强编程实践,每周完成2-3个小项目练习', + '参与至少1次技术分享或团队汇报', + '学习一门新的编程语言或技术框架', + '提升代码质量,学习代码规范和最佳实践' + ], + mediumTerm: [ // 3-6个月 + '参与中大型项目开发,承担核心模块责任', + '建立个人技术博客,分享学习心得', + '获得相关技术认证或证书', + '培养跨领域知识,了解产品和业务逻辑' + ], + longTerm: [ // 6个月以上 + '成为技术团队的核心成员或小组长', + '具备独立设计和架构系统的能力', + '发展个人技术影响力,成为某领域专家', + '培养创新创业思维,探索技术商业化应用' + ], + careerPath: { + current: '初级开发工程师', + nextSteps: [ + { role: '中级开发工程师', timeline: '6-12个月', requirements: ['技术深度', '项目经验'] }, + { role: '高级开发工程师', timeline: '2-3年', requirements: ['技术广度', '架构能力'] }, + { role: '技术专家/技术经理', timeline: '3-5年', requirements: ['技术领导力', '团队管理'] } + ] + } + } } } diff --git a/src/views/Dashboard.vue b/src/views/Dashboard.vue index 1d4afc0..fbf1794 100644 --- a/src/views/Dashboard.vue +++ b/src/views/Dashboard.vue @@ -182,28 +182,28 @@ -
-
+
+
-
+
-
即将上线
+
已完成

报告中心

- 一键生成PDF格式的学期报告、实践报告、能力认证等多类型文档。支持自定义模板,批量导出,电子签章认证。 + 全新的学生评价报告系统,支持综合评价、发展监测、能力分析等多维度报告生成。实时数据更新,专业分析建议。

-
📊 数据报表
-
📝 评价报告
-
🎓 能力证书
+
📊 综合评价
+
📈 发展监测
+
🎯 能力分析
@@ -281,10 +281,17 @@ export default { router.push('/home/portrait') } + const navigateToReport = () => { + console.log('报告中心按钮被点击') + // 默认使用第一个学生的ID来演示报告功能 + router.push('/home/report/1') + } + return { user, goToEvaluate, - goToPortrait + goToPortrait, + navigateToReport } } } diff --git a/src/views/Home.vue b/src/views/Home.vue index bdd460f..c986dce 100644 --- a/src/views/Home.vue +++ b/src/views/Home.vue @@ -65,7 +65,7 @@ 156名学生
-