refactor(契约): 展示题号统一叫 problemDisplayId,题单 id 统一叫 problemSetId
Deploy / deploy (push) Canceled after 0s
Deploy / deploy (push) Canceled after 0s
前后端同时改,部署前开着的旧页面要刷新一次(题号列会是空的、提交筛选会失效)。 - 挂在非题目对象上的展示题号,原来叫 problem(字符串)或 displayId,统一成 problemDisplayId:提交列表、流程图列表、统计的 lastFailure / items / 今日最热题、站内信里的提交、后台题单的题目列表。别处的 problem 都是对象 或数字 id,这几处是字符串,最容易看错 - 列表筛选的 query 参数 ?problemId= 实际传的是展示题号,改成 ?problemDisplayId=(提交列表、流程图列表、三个统计接口) - 契约里 problemsetId / problemSetId、problemset / problemSet 两种拼法并存, 统一成 problemSetId / problemSet,和 ProblemSet* 类型名、problem-sets 路径、前端路由参数一致。drizzle 的列键跟表名走,没动 - aiDetail.user(用户名字符串,而契约里别的 user 都是对象)→ username。 ai_analysis.data 里存的历史快照仍是 user,没有代码读回它 - 后台题单题目表的列是按字符串键 'displayId' 取的,类型检查抓不到,一并改 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
5ae830a7f9
commit
9412ba3cf6
24 files changed
+80
-82
No files matched your search
@@ -293,9 +293,9 @@ adminProblemSetRoutes.get(
|
||||
({ item, problem }) =>
|
||||
({
|
||||
id: item.id,
|
||||
problemsetId: item.problemsetId,
|
||||
problemSetId: item.problemsetId,
|
||||
problemId: item.problemId,
|
||||
displayId: problem.displayId,
|
||||
problemDisplayId: problem.displayId,
|
||||
title: problem.title,
|
||||
difficulty: problem.difficulty,
|
||||
order: item.order,
|
||||
@@ -456,7 +456,7 @@ async function badgesWithCount(badges: BadgeRow[]) {
|
||||
(badge) =>
|
||||
({
|
||||
id: badge.id,
|
||||
problemsetId: badge.problemsetId,
|
||||
problemSetId: badge.problemsetId,
|
||||
name: badge.name,
|
||||
description: badge.description,
|
||||
icon: badge.icon,
|
||||
|
||||
@@ -169,7 +169,7 @@ contentRoutes.get("/messages", requireAuth, async (c) => {
|
||||
language: submission.language,
|
||||
statisticInfo: asRecord(submission.statisticInfo),
|
||||
// 展示用题号而非数字主键,站内信页面拿它拼 /problem/<题号>
|
||||
problem: displayId,
|
||||
problemDisplayId: displayId,
|
||||
showLink: true,
|
||||
} satisfies EmbeddedSubmission,
|
||||
}) satisfies Message,
|
||||
|
||||
@@ -244,7 +244,7 @@ flowchartRoutes.get("/flowcharts", requireAuth, async (c) => {
|
||||
const user = c.get("user")!
|
||||
const limit = queryInteger(c.req.query("limit"), 10, { min: 1, max: 250 })
|
||||
const offset = queryInteger(c.req.query("offset"), 0, { min: 0 })
|
||||
const displayId = c.req.query("problemId")?.trim()
|
||||
const displayId = c.req.query("problemDisplayId")?.trim()
|
||||
const username = c.req.query("username")?.trim()
|
||||
const grade = c.req.query("grade")
|
||||
// 与代码提交列表同一套口径(submission.ts 的 GET /submissions):关掉
|
||||
@@ -298,7 +298,7 @@ flowchartRoutes.get("/flowcharts", requireAuth, async (c) => {
|
||||
({
|
||||
id: flowchart.id,
|
||||
username,
|
||||
problem: problem.displayId,
|
||||
problemDisplayId: problem.displayId,
|
||||
problemTitle: problem.title,
|
||||
status: flowchart.status,
|
||||
createTime: flowchart.createTime,
|
||||
@@ -349,7 +349,7 @@ flowchartRoutes.get("/flowcharts/statistics", requireTeacher, async (c) => {
|
||||
if (start)
|
||||
filters.push(sql`${schema.flowchartSubmission.createTime} >= ${start}`)
|
||||
|
||||
const displayId = c.req.query("problemId")?.trim()
|
||||
const displayId = c.req.query("problemDisplayId")?.trim()
|
||||
if (displayId) {
|
||||
const [problem] = await db
|
||||
.select({ id: schema.problem.id })
|
||||
|
||||
@@ -81,7 +81,7 @@ function badgeData(
|
||||
) {
|
||||
return {
|
||||
id: badge.id,
|
||||
problemsetId: badge.problemsetId,
|
||||
problemSetId: badge.problemsetId,
|
||||
name: badge.name,
|
||||
description: badge.description,
|
||||
icon: badge.icon,
|
||||
@@ -306,7 +306,7 @@ problemsetRoutes.get("/problem-sets/:id/problems", optionalAuth, async (c) => {
|
||||
({ link, problemId, displayId, title, difficulty }) =>
|
||||
({
|
||||
id: link.id,
|
||||
problemsetId: link.problemsetId,
|
||||
problemSetId: link.problemsetId,
|
||||
problem: { id: problemId, _id: displayId, title, difficulty },
|
||||
order: link.order,
|
||||
isRequired: link.isRequired,
|
||||
@@ -435,7 +435,7 @@ problemsetRoutes.get("/users/:username/badges", optionalAuth, async (c) => {
|
||||
userId: userBadge.userId,
|
||||
badge: badgeData(badge),
|
||||
earnedTime: userBadge.earnedTime,
|
||||
problemset: { id: problemSet.id, title: problemSet.title },
|
||||
problemSet: { id: problemSet.id, title: problemSet.title },
|
||||
}) satisfies UserBadge,
|
||||
),
|
||||
)
|
||||
@@ -572,7 +572,7 @@ problemsetRoutes.get(
|
||||
({ progress, user: progressUser, realName }) =>
|
||||
({
|
||||
id: progress.id,
|
||||
problemsetId: progress.problemsetId,
|
||||
problemSetId: progress.problemsetId,
|
||||
user: sampleUser(progressUser, realName),
|
||||
joinTime: progress.joinTime,
|
||||
completeTime: progress.completeTime,
|
||||
|
||||
@@ -151,7 +151,7 @@ submissionStatisticsRoutes.get(
|
||||
count: row.value,
|
||||
})),
|
||||
problems: problemRows.map((row) => ({
|
||||
problem: row.displayId,
|
||||
problemDisplayId: row.displayId,
|
||||
problemTitle: row.title,
|
||||
count: row.value,
|
||||
acceptedCount: row.accepted,
|
||||
@@ -240,7 +240,7 @@ async function lastFailureByUser(where: SQL | undefined, userIds: number[]) {
|
||||
number,
|
||||
{
|
||||
id: string
|
||||
problem: string
|
||||
problemDisplayId: string
|
||||
result: JudgeStatusValue
|
||||
error: string | null
|
||||
}
|
||||
@@ -276,7 +276,7 @@ async function lastFailureByUser(where: SQL | undefined, userIds: number[]) {
|
||||
for (const row of rows) {
|
||||
byUser.set(row.user_id, {
|
||||
id: row.id,
|
||||
problem: row.problem,
|
||||
problemDisplayId: row.problem,
|
||||
result: row.result,
|
||||
error: row.error,
|
||||
})
|
||||
@@ -412,7 +412,7 @@ async function statisticsScope(c: {
|
||||
if (range.start)
|
||||
filters.push(sql`${schema.submission.createTime} >= ${range.start}`)
|
||||
|
||||
const displayIds = parseDisplayIds(c.req.query("problemId") ?? "")
|
||||
const displayIds = parseDisplayIds(c.req.query("problemDisplayId") ?? "")
|
||||
if (displayIds.length > STATISTICS_MAX_PROBLEMS) {
|
||||
return {
|
||||
ok: false,
|
||||
@@ -682,7 +682,7 @@ submissionStatisticsRoutes.get(
|
||||
id: schema.submission.id,
|
||||
result: schema.submission.result,
|
||||
createTime: schema.submission.createTime,
|
||||
problem: schema.problem.displayId,
|
||||
problemDisplayId: schema.problem.displayId,
|
||||
problemTitle: schema.problem.title,
|
||||
})
|
||||
.from(schema.submission)
|
||||
|
||||
@@ -627,7 +627,7 @@ submissionRoutes.get("/submissions", optionalAuth, async (c) => {
|
||||
) {
|
||||
return success(c, { results: [], total: 0 } satisfies SubmissionList)
|
||||
}
|
||||
const displayId = c.req.query("problemId")?.trim()
|
||||
const displayId = c.req.query("problemDisplayId")?.trim()
|
||||
const myself = c.req.query("myself") === "1" ? user : null
|
||||
// 「只看自己」盖过用户名
|
||||
const username = myself ? undefined : c.req.query("username")?.trim()
|
||||
@@ -673,7 +673,7 @@ submissionRoutes.get("/submissions", optionalAuth, async (c) => {
|
||||
({ submission, problem }) =>
|
||||
({
|
||||
id: submission.id,
|
||||
problem: problem.displayId,
|
||||
problemDisplayId: problem.displayId,
|
||||
problemTitle: problem.title,
|
||||
showLink: user
|
||||
? canViewSubmission(user, submission, problem, null, joinTimes)
|
||||
@@ -708,7 +708,7 @@ submissionRoutes.get(
|
||||
const limit = queryInteger(c.req.query("limit"), 10, { min: 1, max: 250 })
|
||||
const offset = queryInteger(c.req.query("offset"), 0, { min: 0 })
|
||||
const user = c.get("user")
|
||||
const displayId = c.req.query("problemId")?.trim()
|
||||
const displayId = c.req.query("problemDisplayId")?.trim()
|
||||
const myself = c.req.query("myself") === "1" ? user : null
|
||||
const username = myself ? undefined : c.req.query("username")?.trim()
|
||||
const result = c.req.query("result")
|
||||
@@ -757,7 +757,7 @@ submissionRoutes.get(
|
||||
({ submission, problem }) =>
|
||||
({
|
||||
id: submission.id,
|
||||
problem: problem.displayId,
|
||||
problemDisplayId: problem.displayId,
|
||||
problemTitle: problem.title,
|
||||
showLink: user
|
||||
? canViewSubmission(user, submission, problem, contest)
|
||||
|
||||
Reference in new issue
Block a user