diff --git a/apps/api/src/routes/admin/problem.ts b/apps/api/src/routes/admin/problem.ts index 1f84a25..e035091 100644 --- a/apps/api/src/routes/admin/problem.ts +++ b/apps/api/src/routes/admin/problem.ts @@ -6,6 +6,7 @@ import { createProblemRequestSchema, makeProblemPublicRequestSchema, updateProblemRequestSchema, + sqlTestCaseScriptSchema, uploadTestCaseResponseSchema, } from "@oj2/contract" 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 { failure, success } from "../../http" 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" export const adminProblemRoutes = new Hono() @@ -569,3 +570,27 @@ adminProblemRoutes.get("/problems/:id/test-cases", requireProblemPermission, asy 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", "测试点脚本读取失败") + } +}) diff --git a/apps/web/src/admin/api.ts b/apps/web/src/admin/api.ts index 9cecab5..716060c 100644 --- a/apps/web/src/admin/api.ts +++ b/apps/web/src/admin/api.ts @@ -228,9 +228,8 @@ export function previewSQLTestcase(data: { // 回显已上传的 SQL 测试点脚本内容(按 1.sql, 2.sql... 排序) export function getSQLTestcaseScripts(problemId: number) { - return http.get<{ name: string; content: string }[]>( - "admin/sql_test_case_scripts", - { params: { problem_id: problemId } }, + return legacyResponse<{ name: string; content: string }[]>( + api2.get(`admin/problems/${problemId}/sql-scripts`), ) } diff --git a/packages/contract/src/admin.ts b/packages/contract/src/admin.ts index ad5c6a1..3205a40 100644 --- a/packages/contract/src/admin.ts +++ b/packages/contract/src/admin.ts @@ -603,3 +603,8 @@ export const uploadTestCaseResponseSchema = z.object({ id: z.string(), info: z.array(testCaseEntrySchema), }) + +export const sqlTestCaseScriptSchema = z.object({ + name: z.string(), + content: z.string(), +})