diff --git a/apps/api/src/routes/submission.ts b/apps/api/src/routes/submission.ts index 0aad5fc..9f2a294 100644 --- a/apps/api/src/routes/submission.ts +++ b/apps/api/src/routes/submission.ts @@ -413,6 +413,8 @@ async function submissionDetail(id: string, user: AuthUser) { // 首轮修复只处理了 info 与 ip,这里补齐。 contestId: full ? row.submission.contestId : null, problemId: row.submission.problemId, + // problem 表本来就 join 了,不额外查库 + problemDisplayId: row.problem.displayId, showLink: true, canUnshare: canViewSubmission(user, row.submission, row.problem, row.contest, false), }) diff --git a/apps/web/src/oj/submission/detail.vue b/apps/web/src/oj/submission/detail.vue index 6d32baa..14677e0 100644 --- a/apps/web/src/oj/submission/detail.vue +++ b/apps/web/src/oj/submission/detail.vue @@ -78,10 +78,13 @@ function copyToCat() { function copyToProblem() { const { code, language, contestId } = submission.value! - // 编辑器的 storageKey 用 display id(problem._id),等于 props.problemID, - // 而非 submission.problem(内部数字 id) + // 编辑器的 storageKey 用 display id(problem._id),不是 submission.problemId + // (内部数字 id)。**不能只靠 props.problemID** —— 独立的 /submission/:id 路由 + // 只喂 submissionID,那个 prop 是 undefined,原来会一路带进 router.push 抛 + // `Missing required param "problemID"`。响应里的 problemDisplayId 就是干这个的。 + const problemID = props.problemID ?? submission.value!.problemDisplayId const contestIDForKey = contestId || null - const storageKey = `problem_${props.problemID}_contest_${contestIDForKey}_lang_${language}` + const storageKey = `problem_${problemID}_contest_${contestIDForKey}_lang_${language}` storage.set(storageKey, code) // 设置语言 + 代码:localStorage 覆盖全新挂载的编辑器, // setCode 覆盖已挂载(同页 modal)的编辑器 @@ -92,17 +95,17 @@ function copyToProblem() { if (contestId) { router.push({ name: "contest problem", - params: { contestID: String(contestId), problemID: props.problemID }, + params: { contestID: String(contestId), problemID }, }) } else if (problemSetId) { router.push({ name: "problemset problem", - params: { problemSetId, problemID: props.problemID }, + params: { problemSetId, problemID }, }) } else { router.push({ name: "problem", - params: { problemID: props.problemID }, + params: { problemID }, }) } diff --git a/packages/contract/src/submission.ts b/packages/contract/src/submission.ts index bc257a5..8d06ab6 100644 --- a/packages/contract/src/submission.ts +++ b/packages/contract/src/submission.ts @@ -42,6 +42,13 @@ export const submissionDetailSchema = z.object({ ip: z.string().nullable(), contestId: z.number().int().nullable(), problemId: z.number().int(), + /** + * 题目的展示编号(problem._id)。**独立的 /submission/:id 页面要靠它** —— + * 那条路由只喂 submissionID,组件拿不到 display id,而「复制回到题目」要用它 + * 拼路由。原来只给内部数字 id,于是那个按钮在这条路由上一点就抛 + * `Missing required param "problemID"`。 + */ + problemDisplayId: z.string(), showLink: z.boolean(), canUnshare: z.boolean(), })