diff --git a/src/views/teacherEnd/score/TaskReviewPanel.vue b/src/views/teacherEnd/score/TaskReviewPanel.vue index a79b9e7..2793d3c 100644 --- a/src/views/teacherEnd/score/TaskReviewPanel.vue +++ b/src/views/teacherEnd/score/TaskReviewPanel.vue @@ -26,7 +26,7 @@ 批量打分 - + @@ -41,6 +41,7 @@ + 仅班级创建教师可评分 @@ -168,15 +169,7 @@ - + @@ -186,12 +179,7 @@ 已选择 {{ selectedStudents.length }} 名学生 - + @@ -227,14 +215,8 @@ - - - {{ batchAiScoreProgress.current }} / {{ batchAiScoreProgress.total }} - + + {{ batchAiScoreProgress.current }} / {{ batchAiScoreProgress.total }} @@ -245,52 +227,23 @@ 批量AI评分已完成! - - AI评分过程中出现错误,请重试 - + AI评分过程中出现错误,请重试 - + @@ -312,13 +265,7 @@ - + @@ -333,14 +280,14 @@ - + 综合评分 - {{ aiScoreDetailData.totalScore ?? '--' }} + {{ aiScoreDetailData.totalScore ?? "--" }} /{{ aiScoreDetailData.totalFullScore }} @@ -349,15 +296,11 @@ - + {{ dimension.name }} - {{ dimension.score ?? '--' }} + {{ dimension.score ?? "--" }} /{{ dimension.fullScore }} @@ -424,7 +367,7 @@ const aiScoreDetailData = ref({ totalFullScore: 100, comment: "", dimensions: [], - improvements: [] + improvements: [], }); const batchAiScoreDialogVisible = ref(false); const batchAiScoring = ref(false); @@ -433,10 +376,14 @@ const batchAiScoreProgress = ref({ current: 0, successCount: 0, failCount: 0, - status: 'idle' // 'idle' | 'running' | 'completed' | 'failed' + status: "idle", // 'idle' | 'running' | 'completed' | 'failed' }); const aiAssistEvalDialogVisible = ref(false); const aiAssistEvaluating = ref(false); +const pagination = ref({ + currentPage: 1, + pageSize: 10, +}); const canManageClass = computed(() => { const currentClass = teachingClasses.value.find((item) => item.schoolClassId === filters.value.classId); @@ -444,6 +391,12 @@ const canManageClass = computed(() => { }); const selectedStudent = computed(() => review.value.students.find((row) => row.studentUserId === selectedStudentId.value) || review.value.students[0] || null); const canBatchScore = computed(() => canManageClass.value && selectedStudents.value.length > 0 && Boolean(filters.value.taskId)); +const paginatedStudents = computed(() => { + const students = review.value.students; + const start = (pagination.value.currentPage - 1) * pagination.value.pageSize; + const end = start + pagination.value.pageSize; + return students.slice(start, end); +}); watch( teachingClasses, @@ -505,6 +458,8 @@ function normalizeReview(data) { if (!students.some((row) => row.studentUserId === selectedStudentId.value)) selectedStudentId.value = students[0]?.studentUserId || ""; selectedStudents.value = []; studentTableRef.value?.clearSelection(); + // 重置分页到第一页 + pagination.value.currentPage = 1; } async function loadReview() { if (!filters.value.classId) return; @@ -565,6 +520,13 @@ function canSelectStudent(row) { function selectStudent(row) { selectedStudentId.value = row.studentUserId; } +function onPageChange(page) { + pagination.value.currentPage = page; +} +function onPageSizeChange(pageSize) { + pagination.value.pageSize = pageSize; + pagination.value.currentPage = 1; +} function studentRowClass({ row }) { return row.studentUserId === selectedStudentId.value ? "task-review__selected-row" : ""; } @@ -655,13 +617,13 @@ function onBatchAiScore() { current: 0, successCount: 0, failCount: 0, - status: 'idle' + status: "idle", }; } async function startBatchAiScore() { batchAiScoring.value = true; - batchAiScoreProgress.value.status = 'running'; + batchAiScoreProgress.value.status = "running"; batchAiScoreProgress.value.current = 0; batchAiScoreProgress.value.successCount = 0; batchAiScoreProgress.value.failCount = 0; @@ -670,8 +632,8 @@ async function startBatchAiScore() { for (const student of selectedStudents.value) { try { // 模拟 AI 评分过程,后续替换为真实 API - await new Promise(resolve => setTimeout(resolve, 800 + Math.random() * 400)); - + await new Promise((resolve) => setTimeout(resolve, 800 + Math.random() * 400)); + // 调用真实 API: await teacherApi.aiScoreStudent({ ... }); batchAiScoreProgress.value.successCount++; } catch (error) { @@ -679,28 +641,26 @@ async function startBatchAiScore() { } batchAiScoreProgress.value.current++; } - - batchAiScoreProgress.value.status = 'completed'; - ElMessage.success( - `AI评分完成!成功${batchAiScoreProgress.value.successCount}名学生,失败${batchAiScoreProgress.value.failCount}名` - ); - + + batchAiScoreProgress.value.status = "completed"; + ElMessage.success(`AI评分完成!成功${batchAiScoreProgress.value.successCount}名学生,失败${batchAiScoreProgress.value.failCount}名`); + // 延迟关闭对话框 setTimeout(() => { batchAiScoreDialogVisible.value = false; loadReview(); }, 2000); } catch (error) { - batchAiScoreProgress.value.status = 'failed'; - ElMessage.error('批量AI评分发生错误'); + batchAiScoreProgress.value.status = "failed"; + ElMessage.error("批量AI评分发生错误"); } finally { batchAiScoring.value = false; } } function closeBatchAiScoreDialog() { - if (batchAiScoreProgress.value.status === 'running') { - ElMessage.warning('正在进行中,请等待...'); + if (batchAiScoreProgress.value.status === "running") { + ElMessage.warning("正在进行中,请等待..."); return; } batchAiScoreDialogVisible.value = false; @@ -708,16 +668,16 @@ function closeBatchAiScoreDialog() { async function onAiAssistEvaluation() { if (!selectedStudent.value) return; - + aiAssistEvalDialogVisible.value = true; aiAssistEvaluating.value = true; try { // 模拟 AI 助评过程,后续替换为真实 API - await new Promise(resolve => setTimeout(resolve, 2000)); - + await new Promise((resolve) => setTimeout(resolve, 2000)); + // 调用真实 API: const response = await teacherApi.aiAssistEvaluation({ ... }); - + // 模拟生成 AI 评分详情 aiScoreDetailData.value = { totalScore: Math.floor(75 + Math.random() * 25), @@ -728,38 +688,34 @@ async function onAiAssistEvaluation() { name: "用户角度分析", score: 25, fullScore: 25, - analysis: "学生全面分析了产品的用户痛点、需求洞察和用户体验优化方向,能够从用户视角出发提出有价值的改进建议,符合用户为中心的产品设计思维。" + analysis: "学生全面分析了产品的用户痛点、需求洞察和用户体验优化方向,能够从用户视角出发提出有价值的改进建议,符合用户为中心的产品设计思维。", }, { name: "技术与合规角度分析", score: 23, fullScore: 25, - analysis: "对产品的技术可行性和合规性进行了基本分析,识别了主要技术风险点,但在法律法规适配性方面的论述深度不够,建议补充更详细的合规性评估。" + analysis: "对产品的技术可行性和合规性进行了基本分析,识别了主要技术风险点,但在法律法规适配性方面的论述深度不够,建议补充更详细的合规性评估。", }, { name: "商业化及市场反馈角度分析", score: 25, fullScore: 25, - analysis: "学生准确把握了市场定位和商业模式,对竞争环境有清晰认知,提出的市场推广策略具有可操作性,商业价值分析完整。" + analysis: "学生准确把握了市场定位和商业模式,对竞争环境有清晰认知,提出的市场推广策略具有可操作性,商业价值分析完整。", }, { name: "结论总结分析", score: 19, fullScore: 25, - analysis: "总结部分提炼了主要观点,但逻辑性和结构性有待加强,建议按照问题-分析-结论的框架重新组织,增加可操作性建议。" - } + analysis: "总结部分提炼了主要观点,但逻辑性和结构性有待加强,建议按照问题-分析-结论的框架重新组织,增加可操作性建议。", + }, ], - improvements: [ - "补充技术合规性评估的详细内容,包括数据安全、隐私保护等方面的法规适配性分析", - "优化结论总结的逻辑结构,建议采用MECE原则(相互独立、完全穷尽)进行归纳", - "在商业化分析中增加财务可行性评估,包括成本收益分析和ROI预测" - ] + improvements: ["补充技术合规性评估的详细内容,包括数据安全、隐私保护等方面的法规适配性分析", "优化结论总结的逻辑结构,建议采用MECE原则(相互独立、完全穷尽)进行归纳", "在商业化分析中增加财务可行性评估,包括成本收益分析和ROI预测"], }; - + aiAssistEvalDialogVisible.value = false; aiScoreDetailDialogVisible.value = true; } catch (error) { - ElMessage.error('AI助评失败,请重试'); + ElMessage.error("AI助评失败,请重试"); } finally { aiAssistEvaluating.value = false; } @@ -767,7 +723,7 @@ async function onAiAssistEvaluation() { async function showAiScoreDetail() { if (!selectedStudent.value) return; - + // 模拟数据 - 后续替换为真实API aiScoreDetailData.value = { totalScore: selectedStudent.value.aiAssessmentScore, @@ -778,36 +734,32 @@ async function showAiScoreDetail() { name: "用户角度分析", score: 25, fullScore: 25, - analysis: "学生全面分析了产品的用户痛点、需求洞察和用户体验优化方向,能够从用户视角出发提出有价值的改进建议,符合用户为中心的产品设计思维。" + analysis: "学生全面分析了产品的用户痛点、需求洞察和用户体验优化方向,能够从用户视角出发提出有价值的改进建议,符合用户为中心的产品设计思维。", }, { name: "技术与合规角度分析", score: 23, fullScore: 25, - analysis: "对产品的技术可行性和合规性进行了基本分析,识别了主要技术风险点,但在法律法规适配性方面的论述深度不够,建议补充更详细的合规性评估。" + analysis: "对产品的技术可行性和合规性进行了基本分析,识别了主要技术风险点,但在法律法规适配性方面的论述深度不够,建议补充更详细的合规性评估。", }, { name: "商业化及市场反馈角度分析", score: 25, fullScore: 25, - analysis: "学生准确把握了市场定位和商业模式,对竞争环境有清晰认知,提出的市场推广策略具有可操作性,商业价值分析完整。" + analysis: "学生准确把握了市场定位和商业模式,对竞争环境有清晰认知,提出的市场推广策略具有可操作性,商业价值分析完整。", }, { name: "结论总结分析", score: 19, fullScore: 25, - analysis: "总结部分提炼了主要观点,但逻辑性和结构性有待加强,建议按照问题-分析-结论的框架重新组织,增加可操作性建议。" - } + analysis: "总结部分提炼了主要观点,但逻辑性和结构性有待加强,建议按照问题-分析-结论的框架重新组织,增加可操作性建议。", + }, ], - improvements: [ - "补充技术合规性评估的详细内容,包括数据安全、隐私保护等方面的法规适配性分析", - "优化结论总结的逻辑结构,建议采用MECE原则(相互独立、完全穷尽)进行归纳", - "在商业化分析中增加财务可行性评估,包括成本收益分析和ROI预测" - ] + improvements: ["补充技术合规性评估的详细内容,包括数据安全、隐私保护等方面的法规适配性分析", "优化结论总结的逻辑结构,建议采用MECE原则(相互独立、完全穷尽)进行归纳", "在商业化分析中增加财务可行性评估,包括成本收益分析和ROI预测"], }; - + aiScoreDetailDialogVisible.value = true; - + // TODO: 后续替换为真实API调用 // try { // const response = await teacherApi.getAiScoreDetail({ @@ -923,6 +875,16 @@ async function showAiScoreDetail() { font-size: var(--fs-body); } + .task-review__pagination { + margin: 12px 0 0; + display: flex; + justify-content: flex-end; + + :deep(.el-pagination) { + font-size: var(--fs-body); + } + } + /* ===== 右侧预览区 ===== */ .task-review__content { min-width: 0;
仅班级创建教师可评分
- {{ batchAiScoreProgress.current }} / {{ batchAiScoreProgress.total }} -
{{ batchAiScoreProgress.current }} / {{ batchAiScoreProgress.total }}
@@ -245,52 +227,23 @@ 批量AI评分已完成!
- AI评分过程中出现错误,请重试 -
AI评分过程中出现错误,请重试