diff --git a/src/api/teacher.js b/src/api/teacher.js index a897901..5e910cc 100644 --- a/src/api/teacher.js +++ b/src/api/teacher.js @@ -706,10 +706,10 @@ export function getScoreDetail(params) { params, }); } -// 保存班级创建教师对学生的人工评分 -export function saveTeacherScore(params) { +// 保存教师对单个实训任务的评分 +export function saveTaskTeacherScore(params) { return request({ - url: "/api/weight/saveTeacherScore", + url: "/api/weight/saveTaskTeacherScore", method: "POST", params, }); diff --git a/src/views/teacherEnd/score/index.vue b/src/views/teacherEnd/score/index.vue index 937f030..4a720d2 100644 --- a/src/views/teacherEnd/score/index.vue +++ b/src/views/teacherEnd/score/index.vue @@ -50,34 +50,21 @@ - + @@ -129,7 +116,7 @@ - +
学生姓名 @@ -162,6 +149,23 @@ + + +
@@ -174,7 +178,7 @@ const userStore = useUserStore(); const currentUserId = computed(() => String(userStore.userInfo.userId || "")); const workingCapitalList = ref([]); const loading = ref(false); -const savingScoreUserId = ref(""); +const savingTaskId = ref(""); const classList = ref([]); const teachingClassList = computed(() => classList.value.filter((item) => item.classType === "TEACHING")); const scoreParams = ref({ @@ -221,7 +225,7 @@ const formatScore = (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, [ @@ -239,16 +243,11 @@ const getList = () => { if (!scoreParams.value.classId) { workingCapitalList.value = []; workingCapitalTotal.value = 0; - return; + return Promise.resolve(); } loading.value = true; - indexApi.getScoreList(buildScoreQuery()).then((res) => { - workingCapitalList.value = (res.data.list || []).map((row) => ({ - ...row, - teacherScoreDraft: row.teacherScore === null || row.teacherScore === undefined - ? null - : Number(row.teacherScore), - })); + return indexApi.getScoreList(buildScoreQuery()).then((res) => { + workingCapitalList.value = res.data.list || []; workingCapitalTotal.value = res.data.total; }).finally(() => (loading.value = false)); }; @@ -327,34 +326,48 @@ const getClassScoreDetail = (row) => { return; } scoreDetailStudent.value = { + userId: row.userId, 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; - }); + tableData.value = (res.data || []).map((item) => ({ + ...item, + teacherScoreDraft: item.teacherScore === null || item.teacherScore === undefined + ? null + : Number(item.teacherScore), + })); + scoreDetailsStart.value = true; +}); }; -const saveTeacherScore = (row) => { +const canScoreTask = (row) => Boolean(row.submitted) || row.progressStatus === "COMPLETED"; +const saveTaskTeacherScore = (row) => { if (row.teacherScoreDraft === null || row.teacherScoreDraft === undefined || row.teacherScoreDraft === "") { - proxy.$message.error("请输入老师评分"); + proxy.$message.error("请输入教师评分"); return; } const score = Number(row.teacherScoreDraft); if (!Number.isFinite(score) || score < 0 || score > 100) { - proxy.$message.error("老师评分必须为0至100之间的数值"); + proxy.$message.error("教师评分必须为0至100之间的数值"); return; } - savingScoreUserId.value = row.userId; - indexApi.saveTeacherScore({ + savingTaskId.value = row.taskId; + indexApi.saveTaskTeacherScore({ classId: scoreParams.value.classId, - studentUserId: row.userId, + studentUserId: scoreDetailStudent.value.userId, + taskId: row.taskId, teacherScore: score, }).then(() => { row.teacherScore = score; - proxy.$message.success("老师评分保存成功"); - }).finally(() => (savingScoreUserId.value = "")); + proxy.$message.success("任务评分保存成功"); + return getList(); + }).then(() => { + const latest = workingCapitalList.value.find((item) => item.userId === scoreDetailStudent.value.userId); + if (latest) { + scoreDetailStudent.value.teacherScore = latest.teacherScore; + } + }).finally(() => (savingTaskId.value = "")); }; // 更新成绩 const updateScore = () => { @@ -384,7 +397,7 @@ onMounted(() => { background: #ffffff; height: calc(100vh - 70px); } -.teacher-score-editor { +.task-score-editor { display: flex; align-items: center; justify-content: center; diff --git a/tests/score-center-class-access-teacher-score.static.test.cjs b/tests/score-center-class-access-teacher-score.static.test.cjs index eb7c868..d385319 100644 --- a/tests/score-center-class-access-teacher-score.static.test.cjs +++ b/tests/score-center-class-access-teacher-score.static.test.cjs @@ -7,15 +7,15 @@ const page = fs.readFileSync(path.join(root, "src/views/teacherEnd/score/index.v const api = fs.readFileSync(path.join(root, "src/api/teacher.js"), "utf8"); assert.match(page, /label="老师评分"/); -assert.match(page, /teacherScoreDraft/); +assert.match(page, /自动汇总/); assert.match(page, /canManageSelectedClass/); assert.match(page, /createdBy/); -assert.match(page, /saveTeacherScore/); -assert.match(page, /老师评分必须为0至100之间的数值/); +assert.match(page, /saveTaskTeacherScore/); +assert.match(page, /教师评分必须为0至100之间的数值/); assert.match(page, /ownClass \|\| teachingClassList\.value\[0\]/); assert.match(page, /getAccessibleTeachingClasses/); assert.doesNotMatch(page, /onMounted\(\(\) => \{\s*getList\(\);\s*getClassList/); -assert.match(api, /url: "\/api\/weight\/saveTeacherScore"/); +assert.match(api, /url: "\/api\/weight\/saveTaskTeacherScore"/); assert.match(api, /url: "\/api\/weight\/accessibleTeachingClasses"/); console.log("score center class access and teacher score contract passed"); diff --git a/tests/score-detail-summary.static.test.cjs b/tests/score-detail-summary.static.test.cjs index bc40040..4266723 100644 --- a/tests/score-detail-summary.static.test.cjs +++ b/tests/score-detail-summary.static.test.cjs @@ -11,6 +11,6 @@ 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")); +assert(api.includes("/api/weight/saveTaskTeacherScore")); console.log("score detail summary static checks passed"); diff --git a/tests/teacher-score-sync.static.test.cjs b/tests/teacher-score-sync.static.test.cjs new file mode 100644 index 0000000..d7820e9 --- /dev/null +++ b/tests/teacher-score-sync.static.test.cjs @@ -0,0 +1,17 @@ +const assert = require("node:assert/strict"); +const fs = require("node:fs"); +const path = require("node:path"); + +const root = path.resolve(__dirname, ".."); +const page = fs.readFileSync(path.join(root, "src", "views", "teacherEnd", "score", "index.vue"), "utf8"); +const api = fs.readFileSync(path.join(root, "src", "api", "teacher.js"), "utf8"); + +assert.match(page, /已完成\s*\{\{\s*row\.completedTaskCount/); +assert.match(page, /teacherScoreDraft/); +assert.match(page, /saveTaskTeacherScore/); +assert.doesNotMatch(page, /saveTeacherScore\(row\)/); +assert.doesNotMatch(page, /teacher-score-editor/); +assert.match(api, /saveTaskTeacherScore/); +assert.doesNotMatch(api, /url: "\/api\/weight\/saveTeacherScore"/); + +console.log("teacher score sync UI contract passed");