diff --git a/apps/api/src/routes/contest.ts b/apps/api/src/routes/contest.ts index d64462f..4d15a17 100644 --- a/apps/api/src/routes/contest.ts +++ b/apps/api/src/routes/contest.ts @@ -244,6 +244,7 @@ contestRoutes.get( allowFlowchart: problem.allowFlowchart, showFlowchart: problem.showFlowchart, hasAstRules: problem.astRules !== null, + isSql: problem.languages.includes("SQL"), myStatus: myStatusOf(statuses, problem.id), // 按人数是公开题库列表的列;比赛题表看的是榜单,不下发 solvedUsers: 0, diff --git a/apps/api/src/routes/problem.ts b/apps/api/src/routes/problem.ts index c362900..8f92857 100644 --- a/apps/api/src/routes/problem.ts +++ b/apps/api/src/routes/problem.ts @@ -110,6 +110,7 @@ function listItem( allowFlowchart: row.problem.allowFlowchart, showFlowchart: row.problem.showFlowchart, hasAstRules: row.problem.astRules !== null, + isSql: row.problem.languages.includes("SQL"), // 流程图评到 A / S 也打勾:problemStates 已经把它算进 solved myStatus: states?.solved.has(id) ? JudgeStatus.ACCEPTED @@ -157,6 +158,7 @@ problemRoutes.get("/problems", optionalAuth, async (c) => { if (type === "reference") filters.push(eq(schema.problem.showFlowchart, true)) if (type === "flowchart") filters.push(eq(schema.problem.allowFlowchart, true)) if (type === "ast") filters.push(sql`${schema.problem.astRules} is not null`) + if (type === "sql") filters.push(sql`${schema.problem.languages} @> '["SQL"]'::jsonb`) const states = user ? await problemStates(user.id) : null if (undone && states && states.solved.size > 0) diff --git a/apps/web/src/oj/problem/components/ProblemTypeTag.vue b/apps/web/src/oj/problem/components/ProblemTypeTag.vue index f042ccb..75964f0 100644 --- a/apps/web/src/oj/problem/components/ProblemTypeTag.vue +++ b/apps/web/src/oj/problem/components/ProblemTypeTag.vue @@ -5,7 +5,8 @@ import { useThemeVars } from "naive-ui" import { PROBLEM_TYPE_LABEL } from "../utils/problemType" /** - * 三类特殊题的小标签(设计稿「题目列表重设计 · 改版」)。轻重按对学生意味着什么分: + * 几类特殊题的小标签(设计稿「题目列表重设计 · 改版」)。轻重按对学生意味着什么分: + * - SQL:和画流程图一样重(实心底)—— 写的根本不是 C / Python,点进去之前就得知道 * - 画流程图:最醒目(浅紫底)—— 只有这类题能交流程图,要做的事和普通题不一样 * - 语法要求:蓝描边 —— 判题时会检查写法,要看得见 * - 有参考图:灰描边,最轻 —— 是帮助,不用提醒 @@ -16,6 +17,7 @@ const props = defineProps<{ kind: ProblemTypeFilter }>() const theme = useThemeVars() const ICON: Record = { + sql: "ph:database-bold", flowchart: "ph:pencil-simple-line-bold", ast: "ph:code-bold", reference: "ph:flow-arrow-bold", @@ -67,12 +69,38 @@ html.dark .type-tag.flowchart { background: rgba(160, 120, 240, 0.18); } +/* 青色:绿 / 橙 / 红是难度、紫是画流程图、蓝是语法要求,剩下它不和谁撞 */ +.type-tag.sql { + font-weight: 600; + color: #0b6470; + background: #dcf1f3; + border-color: transparent; +} + +html.dark .type-tag.sql { + color: #8fd8e0; + background: rgba(60, 180, 195, 0.18); +} + .type-tag.ast { color: var(--tag-info); border-color: #b9cdee; } -html.dark .type-tag.ast { +html.dark /* 青色:绿 / 橙 / 红是难度、紫是画流程图、蓝是语法要求,剩下它不和谁撞 */ +.type-tag.sql { + font-weight: 600; + color: #0b6470; + background: #dcf1f3; + border-color: transparent; +} + +html.dark .type-tag.sql { + color: #8fd8e0; + background: rgba(60, 180, 195, 0.18); +} + +.type-tag.ast { color: var(--tag-info-dark); border-color: rgba(112, 192, 232, 0.45); } diff --git a/apps/web/src/oj/problem/list.vue b/apps/web/src/oj/problem/list.vue index 560afbf..1875408 100644 --- a/apps/web/src/oj/problem/list.vue +++ b/apps/web/src/oj/problem/list.vue @@ -44,7 +44,7 @@ const DIFFICULTIES = [ { label: "困难", value: "High" }, ] -const TYPES: ProblemTypeFilter[] = ["reference", "flowchart", "ast"] +const TYPES: ProblemTypeFilter[] = ["sql", "reference", "flowchart", "ast"] /** 新生一道还没做对时,顶行引去的知识点 */ const START_TAG = "输出入门" diff --git a/apps/web/src/oj/problem/utils/problemType.ts b/apps/web/src/oj/problem/utils/problemType.ts index 9fc73f5..894f4a2 100644 --- a/apps/web/src/oj/problem/utils/problemType.ts +++ b/apps/web/src/oj/problem/utils/problemType.ts @@ -2,6 +2,7 @@ import type { ProblemTypeFilter } from "@oj2/contract" /** 名字和题目页一致:「语法要求」(题目页原来叫「代码要求」,一起改了) */ export const PROBLEM_TYPE_LABEL: Record = { + sql: "SQL", flowchart: "画流程图", ast: "语法要求", reference: "有参考图", @@ -9,18 +10,21 @@ export const PROBLEM_TYPE_LABEL: Record = { /** 「全部类型」下拉里每项下面那句话 */ export const PROBLEM_TYPE_HINT: Record = { + sql: "写 SQL 语句查数据库,不是写 C / Python 程序", reference: "题目里附了老师画好的流程图,照着写代码", flowchart: "除了写代码,也可以交流程图;评到 A 或 S 级算做对", ast: "要求用(或者不能用)某种写法,交了会检查", } -/** 一道题挂哪几个标签,从醒目到轻:画流程图 → 语法要求 → 有参考图 */ +/** 一道题挂哪几个标签,从醒目到轻:SQL → 画流程图 → 语法要求 → 有参考图 */ export function problemTypes(problem: { + isSql: boolean allowFlowchart: boolean hasAstRules: boolean showFlowchart: boolean }): ProblemTypeFilter[] { const kinds: ProblemTypeFilter[] = [] + if (problem.isSql) kinds.push("sql") if (problem.allowFlowchart) kinds.push("flowchart") if (problem.hasAstRules) kinds.push("ast") if (problem.showFlowchart) kinds.push("reference") diff --git a/apps/web/src/oj/transforms.ts b/apps/web/src/oj/transforms.ts index fc94c04..5140432 100644 --- a/apps/web/src/oj/transforms.ts +++ b/apps/web/src/oj/transforms.ts @@ -23,6 +23,7 @@ export function toProblemRow(result: ProblemListItem): ProblemRow { allowFlowchart: result.allowFlowchart, showFlowchart: result.showFlowchart, hasAstRules: result.hasAstRules, + isSql: result.isSql, solvedUsers: result.solvedUsers, triedUsers: result.triedUsers, } diff --git a/apps/web/src/utils/types.ts b/apps/web/src/utils/types.ts index f612404..cbd1b2d 100644 --- a/apps/web/src/utils/types.ts +++ b/apps/web/src/utils/types.ts @@ -167,6 +167,7 @@ export interface ProblemRow { allowFlowchart: boolean showFlowchart: boolean hasAstRules: boolean + isSql: boolean solvedUsers: number triedUsers: number } diff --git a/packages/contract/src/problem.ts b/packages/contract/src/problem.ts index e4fd85e..a3cc665 100644 --- a/packages/contract/src/problem.ts +++ b/packages/contract/src/problem.ts @@ -424,6 +424,8 @@ export const problemListItemSchema = z.object({ allowFlowchart: z.boolean(), showFlowchart: z.boolean(), hasAstRules: z.boolean(), + /** SQL 题(可选语言里有 SQL):写 SQL 语句查数据库,和写 C / Python 是两回事,列表里单独标出来 */ + isSql: z.boolean(), /** 0 = 做对了。画流程图的题,流程图评到 A / S 也给 0(和题单、课堂条一个口径) */ myStatus: z.number().int().nullable(), /** @@ -436,8 +438,8 @@ export const problemListItemSchema = z.object({ export const problemListSchema = paginatedSchema(problemListItemSchema) -/** 题目列表「全部类型」下拉:有参考图 / 画流程图 / 语法要求 */ -export const problemTypeFilterSchema = z.enum(["reference", "flowchart", "ast"]) +/** 题目列表「全部类型」下拉:SQL / 有参考图 / 画流程图 / 语法要求 */ +export const problemTypeFilterSchema = z.enum(["sql", "reference", "flowchart", "ast"]) /** * 题目列表的排序。值沿用原来的(旧链接照样能用):空串 = 最新创建、create_time = 最早创建,