feat: add teacher task scoring and detail paging

bugfix/ai-assessment-evidence-rescore
陈沅 1 month ago
parent d14afa667e
commit 9588ec8c57

@ -156,7 +156,8 @@
v-model="row.teacherScoreDraft"
:min="0"
:max="100"
:precision="2"
:precision="0"
:step="1"
:controls="false"
placeholder="0-100"
:aria-label="`给${row.taskName}评分`"
@ -167,6 +168,13 @@
</template>
</el-table-column>
</el-table>
<pagination
v-show="taskDetailTotal > 0"
:total="taskDetailTotal"
v-model:page="taskDetailPagination.index"
v-model:limit="taskDetailPagination.size"
@pagination="getClassScoreDetail"
/>
</el-dialog>
</div>
</template>
@ -189,6 +197,9 @@ const scoreParams = ref({
});
const scoreDetailsStart = ref(false);
const tableData = ref([]);
const taskDetailRows = ref([]);
const taskDetailTotal = ref(0);
const taskDetailPagination = ref({ index: 1, size: 10 });
const scoreDetailStudent = ref({
name: "",
aiTotalScore: null,
@ -227,6 +238,12 @@ const formatScore = (score) => {
const formatTeacherScore = (score) => score === null || score === undefined || score === ""
? "待评阅"
: formatScore(score);
const normalizeTaskScoreRow = (row) => ({
...row,
teacherScoreDraft: row.teacherScore === null || row.teacherScore === undefined
? null
: Number(row.teacherScore),
});
const weightFields = ["foundationWeight", "marketInsightWeight", "planningDesignWeight", "developmentValidationWeight", "launchOperationWeight", "comprehensiveTrainingWeight"];
const rules = Object.fromEntries(weightFields.map((field) => [field, [
{ required: true, message: "请输入权重", trigger: "blur" },
@ -320,26 +337,42 @@ const exportExcel = () => {
URL.revokeObjectURL(url);
});
};
const getClassScoreDetail = (row) => {
if (!scoreParams.value.classId) {
proxy.$modal.msgWarning("请选择教学班后再查看成绩详情");
const refreshScoreDetail = () => {
if (!scoreDetailStudent.value.userId || !scoreParams.value.classId) {
return Promise.resolve();
}
return indexApi.getScoreDetail({
userId: scoreDetailStudent.value.userId,
classId: scoreParams.value.classId,
...taskDetailPagination.value,
}).then((res) => {
const responseData = res.data || [];
if (Array.isArray(responseData)) {
taskDetailRows.value = responseData.map(normalizeTaskScoreRow);
taskDetailTotal.value = taskDetailRows.value.length;
const start = (taskDetailPagination.value.index - 1) * taskDetailPagination.value.size;
tableData.value = taskDetailRows.value.slice(start, start + taskDetailPagination.value.size);
return;
}
tableData.value = (responseData.list || []).map(normalizeTaskScoreRow);
taskDetailTotal.value = Number(responseData.total) || tableData.value.length;
});
};
const getClassScoreDetail = (row) => {
if (row?.userId) {
taskDetailPagination.value.index = 1;
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 || []).map((item) => ({
...item,
teacherScoreDraft: item.teacherScore === null || item.teacherScore === undefined
? null
: Number(item.teacherScore),
}));
scoreDetailsStart.value = true;
});
}
if (!scoreParams.value.classId || !scoreDetailStudent.value.userId) {
proxy.$modal.msgWarning("请选择教学班后再查看成绩详情");
return;
}
refreshScoreDetail().then(() => (scoreDetailsStart.value = true));
};
const canScoreTask = (row) => Boolean(row.submitted) || row.progressStatus === "COMPLETED";
const saveTaskTeacherScore = (row) => {
@ -348,8 +381,8 @@ const saveTaskTeacherScore = (row) => {
return;
}
const score = Number(row.teacherScoreDraft);
if (!Number.isFinite(score) || score < 0 || score > 100) {
proxy.$message.error("教师评分必须为0至100之间的数值");
if (!Number.isInteger(score) || score < 0 || score > 100) {
proxy.$message.error("教师评分必须为0至100之间的整数");
return;
}
savingTaskId.value = row.taskId;
@ -360,8 +393,9 @@ const saveTaskTeacherScore = (row) => {
teacherScore: score,
}).then(() => {
row.teacherScore = score;
row.teacherScoreDraft = score;
proxy.$message.success("任务评分保存成功");
return getList();
return Promise.all([refreshScoreDetail(), getList()]);
}).then(() => {
const latest = workingCapitalList.value.find((item) => item.userId === scoreDetailStudent.value.userId);
if (latest) {

@ -0,0 +1,21 @@
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, /label="教师评分"/);
assert.match(page, /v-model="row\.teacherScoreDraft"/);
assert.match(page, /:precision="0"/);
assert.match(page, /saveTaskTeacherScore\(row\)/);
assert.match(page, /教师评分必须为0至100之间的整数/);
assert.match(page, /taskDetailPagination/);
assert.match(page, /taskDetailTotal/);
assert.match(page, /@pagination="getClassScoreDetail"/);
assert.match(page, /refreshScoreDetail/);
assert.match(api, /export function saveTaskTeacherScore/);
assert.match(api, /url: "\/api\/weight\/saveTaskTeacherScore"/);
console.log("teacher task score detail static checks passed");
Loading…
Cancel
Save