学生姓名
@@ -162,6 +149,23 @@
+
+
+
+
+ 保存
+
+ {{ formatTeacherScore(row.teacherScore) }}
+
+
@@ -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");