fix(前端): 一批表格列静默空白,题单进度点「移除」还会抛
没有 render 的列,naive-ui 直接按 key 取 row[key]。上一批把响应字段改成 camelCase 之后,这些列的 key 还留着 snake_case,取不到值就渲染成空白 —— 排行榜、题单进度、AI 报告、后台首页共 13 处。 这类问题类型检查够不着(列 key 是字符串),是扫「没有 render 的列 key 里 还带下划线」的组合才找出来的。 同一张表还有两处更严重的: - 「用户」列 key 写的是 user.username,但后台 /admin/problem-sets/:id/progress 下发的是扁平的 username,没有嵌套 user。 - 点「移除」emit 的是 row.user.id —— row.user 是 undefined,直接抛, 学生根本移不掉。 test_case 那两处保留:读的是判题机 info.data 的原始键。 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -2,10 +2,10 @@
|
|||||||
import { h } from "vue"
|
import { h } from "vue"
|
||||||
import { NDataTable, NButton, NFlex } from "naive-ui"
|
import { NDataTable, NButton, NFlex } from "naive-ui"
|
||||||
import { parseTime } from "utils/functions"
|
import { parseTime } from "utils/functions"
|
||||||
import type { ProblemSetProgress } from "utils/types"
|
import type { AdminProblemSetProgress } from "utils/types"
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
progress: ProblemSetProgress[]
|
progress: AdminProblemSetProgress[]
|
||||||
}
|
}
|
||||||
|
|
||||||
interface Emits {
|
interface Emits {
|
||||||
@@ -17,41 +17,41 @@ const emit = defineEmits<Emits>()
|
|||||||
|
|
||||||
// 定义表格列
|
// 定义表格列
|
||||||
const progressColumns = [
|
const progressColumns = [
|
||||||
{ title: "用户", key: "user.username", width: 120 },
|
{ title: "用户", key: "username", width: 120 },
|
||||||
{
|
{
|
||||||
title: "加入时间",
|
title: "加入时间",
|
||||||
key: "join_time",
|
key: "joinTime",
|
||||||
width: 180,
|
width: 180,
|
||||||
render: (row: ProblemSetProgress) =>
|
render: (row: AdminProblemSetProgress) =>
|
||||||
parseTime(row.joinTime, "YYYY-MM-DD HH:mm:ss"),
|
parseTime(row.joinTime, "YYYY-MM-DD HH:mm:ss"),
|
||||||
},
|
},
|
||||||
{ title: "已完成", key: "completed_problems_count", width: 100 },
|
{ title: "已完成", key: "completedProblemsCount", width: 100 },
|
||||||
{ title: "总题目", key: "total_problems_count", width: 100 },
|
{ title: "总题目", key: "totalProblemsCount", width: 100 },
|
||||||
{
|
{
|
||||||
title: "进度",
|
title: "进度",
|
||||||
key: "progress_percentage",
|
key: "progressPercentage",
|
||||||
width: 100,
|
width: 100,
|
||||||
render: (row: ProblemSetProgress) =>
|
render: (row: AdminProblemSetProgress) =>
|
||||||
`${row.progressPercentage.toFixed(0)}%`,
|
`${row.progressPercentage.toFixed(0)}%`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "是否完成",
|
title: "是否完成",
|
||||||
key: "is_completed",
|
key: "isCompleted",
|
||||||
width: 100,
|
width: 100,
|
||||||
render: (row: ProblemSetProgress) => (row.isCompleted ? "是" : "否"),
|
render: (row: AdminProblemSetProgress) => (row.isCompleted ? "是" : "否"),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "操作",
|
title: "操作",
|
||||||
key: "actions",
|
key: "actions",
|
||||||
width: 120,
|
width: 120,
|
||||||
render: (row: ProblemSetProgress) =>
|
render: (row: AdminProblemSetProgress) =>
|
||||||
h(
|
h(
|
||||||
NButton,
|
NButton,
|
||||||
{
|
{
|
||||||
size: "small",
|
size: "small",
|
||||||
type: "error",
|
type: "error",
|
||||||
secondary: true,
|
secondary: true,
|
||||||
onClick: () => emit("remove-user", row.user.id),
|
onClick: () => emit("remove-user", row.userId),
|
||||||
},
|
},
|
||||||
{ default: () => "移除" },
|
{ default: () => "移除" },
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -53,8 +53,8 @@ const columns: DataTableColumn<Rank>[] = [
|
|||||||
),
|
),
|
||||||
},
|
},
|
||||||
{ title: "个性签名", key: "mood" },
|
{ title: "个性签名", key: "mood" },
|
||||||
{ title: "已解决", key: "accepted_number", width: 100 },
|
{ title: "已解决", key: "acceptedNumber", width: 100 },
|
||||||
{ title: "提交数", key: "submission_number", width: 100 },
|
{ title: "提交数", key: "submissionNumber", width: 100 },
|
||||||
{
|
{
|
||||||
title: "正确率",
|
title: "正确率",
|
||||||
key: "rate",
|
key: "rate",
|
||||||
|
|||||||
@@ -134,7 +134,7 @@ const flowchartsColumns: DataTableColumn<FlowchartSummary>[] = [
|
|||||||
() => `${row.problemId} ${row.problemTitle}`,
|
() => `${row.problemId} ${row.problemTitle}`,
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
{ title: "提交次数", key: "submission_count", width: 100, align: "center" },
|
{ title: "提交次数", key: "submissionCount", width: 100, align: "center" },
|
||||||
{
|
{
|
||||||
title: "最高分",
|
title: "最高分",
|
||||||
key: "best",
|
key: "best",
|
||||||
@@ -149,6 +149,6 @@ const flowchartsColumns: DataTableColumn<FlowchartSummary>[] = [
|
|||||||
align: "center",
|
align: "center",
|
||||||
render: (row) => parseTime(row.latestSubmissionTime),
|
render: (row) => parseTime(row.latestSubmissionTime),
|
||||||
},
|
},
|
||||||
{ title: "平均分", key: "avg_score", width: 100, align: "center" },
|
{ title: "平均分", key: "avgScore", width: 100, align: "center" },
|
||||||
]
|
]
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -111,7 +111,7 @@ const progressColumns = [
|
|||||||
title: "排名",
|
title: "排名",
|
||||||
key: "rank",
|
key: "rank",
|
||||||
width: 80,
|
width: 80,
|
||||||
render: (row: ProblemSetProgress, index: number) => {
|
render: (_row: ProblemSetProgress, index: number) => {
|
||||||
// 计算全局排名:当前页偏移 + 当前行索引 + 1
|
// 计算全局排名:当前页偏移 + 当前行索引 + 1
|
||||||
const globalRank = (query.page - 1) * query.limit + index + 1
|
const globalRank = (query.page - 1) * query.limit + index + 1
|
||||||
return globalRank
|
return globalRank
|
||||||
@@ -132,7 +132,7 @@ const progressColumns = [
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "已完成数量",
|
title: "已完成数量",
|
||||||
key: "completed_problems_count",
|
key: "completedProblemsCount",
|
||||||
width: 100,
|
width: 100,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -295,28 +295,28 @@ const classColumns: DataTableColumn<ClassRank>[] = [
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "人数",
|
title: "人数",
|
||||||
key: "user_count",
|
key: "userCount",
|
||||||
width: 80,
|
width: 80,
|
||||||
titleAlign: "center",
|
titleAlign: "center",
|
||||||
align: "center",
|
align: "center",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "总AC数",
|
title: "总AC数",
|
||||||
key: "total_ac",
|
key: "totalAc",
|
||||||
width: 90,
|
width: 90,
|
||||||
titleAlign: "center",
|
titleAlign: "center",
|
||||||
align: "center",
|
align: "center",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "提交数",
|
title: "提交数",
|
||||||
key: "total_submission",
|
key: "totalSubmission",
|
||||||
width: 90,
|
width: 90,
|
||||||
titleAlign: "center",
|
titleAlign: "center",
|
||||||
align: "center",
|
align: "center",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "平均AC数",
|
title: "平均AC数",
|
||||||
key: "avg_ac",
|
key: "avgAc",
|
||||||
width: 100,
|
width: 100,
|
||||||
titleAlign: "center",
|
titleAlign: "center",
|
||||||
align: "center",
|
align: "center",
|
||||||
@@ -399,13 +399,13 @@ const myClassColumns: DataTableColumn<ClassUserRank["ranks"][number]>[] = [
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "已解决",
|
title: "已解决",
|
||||||
key: "accepted_number",
|
key: "acceptedNumber",
|
||||||
width: 120,
|
width: 120,
|
||||||
align: "center",
|
align: "center",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "提交数",
|
title: "提交数",
|
||||||
key: "submission_number",
|
key: "submissionNumber",
|
||||||
width: 120,
|
width: 120,
|
||||||
align: "center",
|
align: "center",
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user