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