diff --git a/src/api/teacher.js b/src/api/teacher.js index c2ceff6..3060c6c 100644 --- a/src/api/teacher.js +++ b/src/api/teacher.js @@ -693,6 +693,14 @@ export function getScoreDetail(params) { params, }); } +// 保存老师对学生的人工评分 +export function saveTeacherScore(params) { + return request({ + url: "/api/weight/saveTeacherScore", + method: "POST", + params, + }); +} // 更新成绩 export function doRankOne(params) { return request({ diff --git a/src/views/teacherEnd/score/index.vue b/src/views/teacherEnd/score/index.vue index 7a61c00..59621f1 100644 --- a/src/views/teacherEnd/score/index.vue +++ b/src/views/teacherEnd/score/index.vue @@ -46,6 +46,27 @@ + + + + + 保存 + + + {{ formatTrainingProgress(row) }} @@ -101,6 +122,20 @@ + + + 学生姓名 + {{ scoreDetailStudent.name || "--" }} + + + AI评测总分 + {{ formatScore(scoreDetailStudent.aiTotalScore) }} + + + 老师评分 + {{ formatTeacherScore(scoreDetailStudent.teacherScore) }} + + { if (row.trainingProgress === null || row.trainingProgress === undefined) return ""; return `已完成 ${row.completedTaskCount || 0}/${row.totalTaskCount || 0} 项`; }; +const formatScore = (score) => { + if (score === null || score === undefined || score === "") return "--"; + const value = Number(score); + return Number.isFinite(value) ? value.toFixed(2).replace(/\.00$/, "") : "--"; +}; +const formatTeacherScore = (score) => score === null || score === undefined || score === "" + ? "未评分" + : formatScore(score); const weightFields = ["foundationWeight", "marketInsightWeight", "planningDesignWeight", "developmentValidationWeight", "launchOperationWeight", "comprehensiveTrainingWeight"]; const rules = Object.fromEntries(weightFields.map((field) => [field, [ { required: true, message: "请输入权重", trigger: "blur" }, @@ -167,7 +216,12 @@ const buildScoreQuery = () => { const getList = () => { loading.value = true; indexApi.getScoreList(buildScoreQuery()).then((res) => { - workingCapitalList.value = res.data.list; + workingCapitalList.value = (res.data.list || []).map((row) => ({ + ...row, + teacherScoreDraft: row.teacherScore === null || row.teacherScore === undefined + ? null + : Number(row.teacherScore), + })); workingCapitalTotal.value = res.data.total; loading.value = false; }); @@ -231,11 +285,36 @@ const getClassScoreDetail = (row) => { proxy.$modal.msgWarning("请选择自己的教学班后再查看成绩详情"); return; } + scoreDetailStudent.value = { + name: row.name, + aiTotalScore: row.score, + teacherScore: row.teacherScore, + }; indexApi.getScoreDetail({ userId: row.userId, classId: scoreParams.value.classId }).then((res) => { tableData.value = res.data; scoreDetailsStart.value = true; }); }; +const saveTeacherScore = (row) => { + if (row.teacherScoreDraft === null || row.teacherScoreDraft === undefined || row.teacherScoreDraft === "") { + proxy.$message.error("请输入老师评分"); + return; + } + const score = Number(row.teacherScoreDraft); + if (!Number.isFinite(score) || score < 0 || score > 100) { + proxy.$message.error("老师评分必须为0至100之间的数值"); + return; + } + savingScoreUserId.value = row.userId; + indexApi.saveTeacherScore({ + classId: scoreParams.value.classId, + studentUserId: row.userId, + teacherScore: score, + }).then(() => { + row.teacherScore = score; + proxy.$message.success("老师评分保存成功"); + }).finally(() => (savingScoreUserId.value = "")); +}; // 更新成绩 const updateScore = () => { if (!scoreParams.value.classId) { @@ -265,4 +344,40 @@ onMounted(() => { background: #ffffff; height: calc(100vh - 70px); } +.teacher-score-editor { + display: flex; + align-items: center; + justify-content: center; + gap: 8px; + + :deep(.el-input-number) { + width: 104px; + } +} +.score-detail-summary { + display: grid; + grid-template-columns: repeat(3, minmax(0, 1fr)); + gap: 12px; + margin-bottom: 16px; +} +.score-detail-summary__item { + display: flex; + flex-direction: column; + gap: 8px; + padding: 14px 18px; + background: rgba(2, 167, 240, 0.08); + border: 1px solid rgba(2, 167, 240, 0.3); + border-radius: 6px; + + span { + color: #7f9cab; + font-size: 13px; + } + + strong { + color: #02a7f0; + font-size: 20px; + font-variant-numeric: tabular-nums; + } +} diff --git a/tests/score-detail-summary.static.test.cjs b/tests/score-detail-summary.static.test.cjs new file mode 100644 index 0000000..bc40040 --- /dev/null +++ b/tests/score-detail-summary.static.test.cjs @@ -0,0 +1,16 @@ +const assert = require("assert"); +const fs = require("fs"); + +const page = fs.readFileSync("src/views/teacherEnd/score/index.vue", "utf8"); +const api = fs.readFileSync("src/api/teacher.js", "utf8"); + +assert(page.includes("学生姓名")); +assert(page.includes("AI评测总分")); +assert(page.includes("老师评分")); +assert(page.includes("scoreDetailStudent.name")); +assert(page.includes("scoreDetailStudent.aiTotalScore")); +assert(page.includes("scoreDetailStudent.teacherScore")); +assert(page.includes("row.teacherScore = score")); +assert(api.includes("/api/weight/saveTeacherScore")); + +console.log("score detail summary static checks passed");