fix(出题页): 改了挑战点保存,提示「保存好了」其实一条都没存上
出题页发请求时漏了 challenges 这个字段,后端又把「不带」当成「不动原来的」, 所以改动被静默丢掉。现在出题页带上它,接口也改成必须带(null 是清空), 以后再漏传会直接报错,不会再悄悄丢。 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
195069450f
commit
6b5ca745bb
3 files changed
+8
-7
No files matched your search
@@ -260,9 +260,7 @@ type ProblemInput = ReturnType<typeof createProblemRequestSchema.parse>
|
||||
async function validateProblem(data: ProblemInput, previousChallenges: ProblemChallenges | null = null): Promise<{ error: string } | Validated> {
|
||||
const checked = commonChecks(data)
|
||||
if ('error' in checked) return checked
|
||||
// 不带挑战(旧版出题页)就原样留着,见契约 createProblemRequestSchema.challenges
|
||||
const normalized =
|
||||
data.challenges === undefined ? { challenges: previousChallenges } : normalizeChallenges(data.challenges, previousChallenges, data.languages)
|
||||
const normalized = normalizeChallenges(data.challenges, previousChallenges, data.languages)
|
||||
if ('error' in normalized) return normalized
|
||||
const { challenges } = normalized
|
||||
if (!checked.sql) return { sql: false, sqlDisplay: null, challenges }
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { toAdminType, toProblemPermission } from '@oj2/contract'
|
||||
import type {
|
||||
AddContestProblemRequest,
|
||||
ChallengeInput,
|
||||
ChallengeSuggestionsResponse,
|
||||
AddProblemsToSetRequest,
|
||||
BatchProblemTagRequest,
|
||||
@@ -358,8 +359,9 @@ export function generateTestInputs(data: GenerateTestInputsRequest) {
|
||||
|
||||
/** 出站补默认值。字段名两边已经一致,不再做键名转换 */
|
||||
function toProblemBody(problem: AdminProblem | BlankProblem) {
|
||||
const p = problem as Partial<Omit<AdminProblem, 'flowchartData'>> & {
|
||||
const p = problem as Partial<Omit<AdminProblem, 'flowchartData' | 'challenges'>> & {
|
||||
flowchartData?: Record<string, unknown> | null
|
||||
challenges?: Record<string, ChallengeInput[]> | null
|
||||
}
|
||||
return {
|
||||
_id: p._id,
|
||||
@@ -387,6 +389,7 @@ function toProblemBody(problem: AdminProblem | BlankProblem) {
|
||||
flowchartData: p.flowchartData ?? null,
|
||||
flowchartHint: p.flowchartHint ?? null,
|
||||
astRules: p.astRules ?? null,
|
||||
challenges: p.challenges ?? null,
|
||||
sqlConfig: p.sqlConfig ?? null,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1004,10 +1004,10 @@ export const createProblemRequestSchema = z.object({
|
||||
flowchartHint: z.string().nullable().default(null),
|
||||
astRules: astRulesSchema.nullable().default(null),
|
||||
/**
|
||||
* 不带这个键 = 不动原来的挑战。上线那一刻浏览器里还开着旧版出题页,它保存时不带挑战,
|
||||
* 给个默认 null 的话一保存就把挑战清了;null 才是「清空」
|
||||
* 必须带:null 是「清空」。不给默认值是故意的 —— 前端漏传这个键的话,给默认 null
|
||||
* 会一保存就把挑战清了,而「不带 = 不动」又会让出题页改的挑战静默存不上
|
||||
*/
|
||||
challenges: challengeInputsSchema.nullable().optional(),
|
||||
challenges: challengeInputsSchema.nullable(),
|
||||
// order_sensitive 缺省补 false —— 与旧后端 SQLConfigSerializer 的
|
||||
// `BooleanField(default=False)` 一致
|
||||
sqlConfig: sqlConfigSchema
|
||||
|
||||
Reference in new issue
Block a user