feat(后台): SQL 题有了自己的出题页——左边写,右边就是学生看到的样子,改答案、改数据马上重跑
- 「新建题目」先选编程题还是 SQL 题,选了就不能改;编辑时按题目本身进对应的页 - SQL 出题页(设计稿「SQL 出题页」方案 B):测试数据一组一行,改完自动重跑, 跑不通的用中文说原因;保存时才打包上传测试点,不用再手动「预览」「上传」 - 新建时存草稿,误关页面不丢 - 编程题出题页去掉 SQL 那一堆分支(以前勾上 SQL 会静默清掉语法要求和流程图) - 题目列表能按题型筛,SQL 题标题后面挂标签 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
25d3296410
commit
2cb39fd96b
13 files changed
+1414
-185
No files matched your search
@@ -1,5 +1,6 @@
|
||||
import {
|
||||
addContestProblemRequestSchema,
|
||||
isSqlProblem,
|
||||
createProblemRequestSchema,
|
||||
generateSqlTestCaseRequestSchema,
|
||||
makeProblemPublicRequestSchema,
|
||||
@@ -15,7 +16,7 @@ import {
|
||||
type SqlTestCaseScript,
|
||||
type UploadTestCaseResponse,
|
||||
} 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, not, or, sql } from "drizzle-orm"
|
||||
import { Hono } from "hono"
|
||||
|
||||
import { requireProblemPermission, type AppEnv } from "../../auth/middleware"
|
||||
@@ -216,7 +217,7 @@ function commonChecks(data: {
|
||||
}): { error: string } | { sql: boolean } {
|
||||
const astError = astRulesError(pickAstRules(data.astRules, data.languages))
|
||||
if (astError) return { error: astError }
|
||||
if (data.languages.includes("SQL")) {
|
||||
if (isSqlProblem(data)) {
|
||||
if (data.languages.length !== 1)
|
||||
return { error: "SQL problem cannot be mixed with other languages" }
|
||||
if (!data.sqlConfig) return { error: "SQL problem requires sql_config" }
|
||||
@@ -397,6 +398,11 @@ adminProblemRoutes.get("/problems", requireProblemPermission, async (c) => {
|
||||
const author = c.req.query("author")?.trim()
|
||||
const keyword = c.req.query("keyword")?.trim()
|
||||
const tagId = c.req.query("tagId")?.trim()
|
||||
// 题型:sql = SQL 题,code = 编程题(C / C++ / Python)
|
||||
const kind = c.req.query("kind")
|
||||
const sqlOnly = sql`${schema.problem.languages} @> '["SQL"]'::jsonb`
|
||||
if (kind === "sql") filters.push(sqlOnly)
|
||||
else if (kind === "code") filters.push(not(sqlOnly))
|
||||
if (author) filters.push(eq(schema.user.username, author))
|
||||
if (keyword) {
|
||||
filters.push(
|
||||
@@ -456,6 +462,7 @@ adminProblemRoutes.get("/problems", requireProblemPermission, async (c) => {
|
||||
createTime: problem.createTime,
|
||||
difficulty: problem.difficulty,
|
||||
tags: tags.get(problem.id) ?? [],
|
||||
isSql: isSqlProblem(problem),
|
||||
hasAstRules: problem.astRules !== null,
|
||||
allowFlowchart: problem.allowFlowchart,
|
||||
showFlowchart: problem.showFlowchart,
|
||||
@@ -637,6 +644,7 @@ adminProblemRoutes.get("/contests/:contestId/problems", requireProblemPermission
|
||||
createTime: problem.createTime,
|
||||
difficulty: problem.difficulty,
|
||||
tags: tags.get(problem.id) ?? [],
|
||||
isSql: isSqlProblem(problem),
|
||||
hasAstRules: problem.astRules !== null,
|
||||
allowFlowchart: problem.allowFlowchart,
|
||||
showFlowchart: problem.showFlowchart,
|
||||
|
||||
Reference in new issue
Block a user