feat(阶段4): SQL 测试点脚本回显
GET admin/problems/:id/sql-scripts 只读磁盘上的 N.sql,不需要 SQL 引擎 —— 同组的 sql-preview / sql-ai-gen 要跑 SQLite 生成展示数据,新后端还没有那条链路,那两个仍指向旧后端。 实测:SQL 题回显两个脚本内容正确;测试点不是 SQL 类型返回 409 并说明;题目不存在 404。 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -6,6 +6,7 @@ import {
|
|||||||
createProblemRequestSchema,
|
createProblemRequestSchema,
|
||||||
makeProblemPublicRequestSchema,
|
makeProblemPublicRequestSchema,
|
||||||
updateProblemRequestSchema,
|
updateProblemRequestSchema,
|
||||||
|
sqlTestCaseScriptSchema,
|
||||||
uploadTestCaseResponseSchema,
|
uploadTestCaseResponseSchema,
|
||||||
} from "@oj2/contract"
|
} from "@oj2/contract"
|
||||||
import { and, count, desc, eq, ilike, inArray, isNull, ne, or, sql } from "drizzle-orm"
|
import { and, count, desc, eq, ilike, inArray, isNull, ne, or, sql } from "drizzle-orm"
|
||||||
@@ -16,7 +17,7 @@ import type { AuthUser } from "../../auth/session"
|
|||||||
import { db, schema } from "../../db"
|
import { db, schema } from "../../db"
|
||||||
import { failure, success } from "../../http"
|
import { failure, success } from "../../http"
|
||||||
import { contestStatus } from "../../services/contest"
|
import { contestStatus } from "../../services/contest"
|
||||||
import { packTestCaseZip, processTestCaseZip, TestCaseError } from "../../services/test-case"
|
import { packTestCaseZip, processTestCaseZip, readInfo, readSqlScripts, TestCaseError } from "../../services/test-case"
|
||||||
import { objectValue, queryInteger, sampleUser, stringArray } from "../helpers"
|
import { objectValue, queryInteger, sampleUser, stringArray } from "../helpers"
|
||||||
|
|
||||||
export const adminProblemRoutes = new Hono<AppEnv>()
|
export const adminProblemRoutes = new Hono<AppEnv>()
|
||||||
@@ -569,3 +570,27 @@ adminProblemRoutes.get("/problems/:id/test-cases", requireProblemPermission, asy
|
|||||||
throw error
|
throw error
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 回显 SQL 题已上传的测试点脚本内容。只读磁盘上的 N.sql,不需要 SQL 引擎 ——
|
||||||
|
* 同组的 sql-preview / sql-ai-gen 要跑 SQLite 生成展示数据,新后端还没有那条链路,
|
||||||
|
* 那两个仍在旧后端上。
|
||||||
|
*/
|
||||||
|
adminProblemRoutes.get("/problems/:id/sql-scripts", requireProblemPermission, async (c) => {
|
||||||
|
const [problem] = await db.select().from(schema.problem)
|
||||||
|
.where(eq(schema.problem.id, queryInteger(c.req.param("id"), 0, { min: 1 }))).limit(1)
|
||||||
|
if (!problem) return failure(c, 404, "problem-not-found", "Problem does not exists")
|
||||||
|
if (!(await canEdit(c.get("user")!, problem))) {
|
||||||
|
return failure(c, 404, "problem-not-found", "Problem does not exists")
|
||||||
|
}
|
||||||
|
const info = await readInfo(problem.testCaseId)
|
||||||
|
if (!info) return failure(c, 404, "test-case-info-unreadable", "测试点信息读取失败")
|
||||||
|
if (!info.sql) return failure(c, 409, "not-sql-test-case", "该题的测试点不是 SQL 类型")
|
||||||
|
try {
|
||||||
|
const scripts = await readSqlScripts(problem.testCaseId)
|
||||||
|
return success(c, scripts.map((script) => sqlTestCaseScriptSchema.parse(script)))
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Failed to read SQL test case scripts", error)
|
||||||
|
return failure(c, 500, "test-case-error", "测试点脚本读取失败")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|||||||
@@ -228,9 +228,8 @@ export function previewSQLTestcase(data: {
|
|||||||
|
|
||||||
// 回显已上传的 SQL 测试点脚本内容(按 1.sql, 2.sql... 排序)
|
// 回显已上传的 SQL 测试点脚本内容(按 1.sql, 2.sql... 排序)
|
||||||
export function getSQLTestcaseScripts(problemId: number) {
|
export function getSQLTestcaseScripts(problemId: number) {
|
||||||
return http.get<{ name: string; content: string }[]>(
|
return legacyResponse<{ name: string; content: string }[]>(
|
||||||
"admin/sql_test_case_scripts",
|
api2.get(`admin/problems/${problemId}/sql-scripts`),
|
||||||
{ params: { problem_id: problemId } },
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -603,3 +603,8 @@ export const uploadTestCaseResponseSchema = z.object({
|
|||||||
id: z.string(),
|
id: z.string(),
|
||||||
info: z.array(testCaseEntrySchema),
|
info: z.array(testCaseEntrySchema),
|
||||||
})
|
})
|
||||||
|
|
||||||
|
export const sqlTestCaseScriptSchema = z.object({
|
||||||
|
name: z.string(),
|
||||||
|
content: z.string(),
|
||||||
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user