feat: 支持评分字段的导入
This commit is contained in:
@@ -44,6 +44,9 @@ interface ParsedItem {
|
||||
hint1: string
|
||||
hint2: string
|
||||
hint3: string
|
||||
// 评分(1-5,可空)
|
||||
difficultyScore: number | null
|
||||
funScore: number | null
|
||||
// 解析警告/错误信息
|
||||
parseError?: string
|
||||
// 上传/创建过程状态
|
||||
@@ -76,6 +79,18 @@ interface RiddleConfigItem {
|
||||
anchor_text?: string
|
||||
reference_image?: string
|
||||
riddle_image?: string
|
||||
// JSON 里通常是字符串,容忍数字
|
||||
difficulty_score?: string | number
|
||||
fun_score?: string | number
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析评分字段,失败/缺失静默置 null,导入流程不因此阻塞。
|
||||
*/
|
||||
function parseScoreField(raw: string | number | undefined): number | null {
|
||||
if (raw === undefined || raw === null || raw === '') return null
|
||||
const n = typeof raw === 'number' ? raw : Number(raw)
|
||||
return Number.isInteger(n) && n >= 1 && n <= 5 ? n : null
|
||||
}
|
||||
|
||||
function truncate(s: string | undefined, max: number): string {
|
||||
@@ -181,6 +196,8 @@ async function parseConfigJson(
|
||||
hint1: (hints[0] || '').trim(),
|
||||
hint2: (hints[1] || '').trim(),
|
||||
hint3: (hints[2] || '').trim(),
|
||||
difficultyScore: parseScoreField(config.difficulty_score),
|
||||
funScore: parseScoreField(config.fun_score),
|
||||
status: 'pending',
|
||||
}
|
||||
|
||||
@@ -250,6 +267,8 @@ async function parseFolders(files: FileList): Promise<ParsedItem[]> {
|
||||
hint1: '',
|
||||
hint2: '',
|
||||
hint3: '',
|
||||
difficultyScore: null,
|
||||
funScore: null,
|
||||
status: 'pending',
|
||||
}
|
||||
|
||||
@@ -412,6 +431,11 @@ export function BatchImportDialog({
|
||||
hint1: it.hint1 || '',
|
||||
hint2: it.hint2 || '',
|
||||
hint3: it.hint3 || '',
|
||||
difficultyScore: it.difficultyScore,
|
||||
funScore: it.funScore,
|
||||
// 故意不传 position / sortKey。
|
||||
// 命中存量关卡时,POST /api/levels 的 riddleId-update 分支会忽略
|
||||
// 这两个字段以保护用户手动维护的关卡顺序。
|
||||
}
|
||||
|
||||
const res = await apiFetch('/api/levels', {
|
||||
@@ -695,6 +719,45 @@ function ItemCard({ index, item, disabled, onChange, onRemove }: ItemCardProps)
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="col-span-2 grid grid-cols-2 gap-2">
|
||||
<div className="space-y-1">
|
||||
<Label className="text-xs">难度评分 (1-5)</Label>
|
||||
<Input
|
||||
type="number"
|
||||
min={1}
|
||||
max={5}
|
||||
step={1}
|
||||
value={item.difficultyScore ?? ''}
|
||||
onChange={(e) =>
|
||||
onChange({
|
||||
difficultyScore:
|
||||
e.target.value === '' ? null : Number(e.target.value),
|
||||
})
|
||||
}
|
||||
disabled={disabled}
|
||||
placeholder="可选"
|
||||
/>
|
||||
</div>
|
||||
<div className="space-y-1">
|
||||
<Label className="text-xs">有趣度 (1-5)</Label>
|
||||
<Input
|
||||
type="number"
|
||||
min={1}
|
||||
max={5}
|
||||
step={1}
|
||||
value={item.funScore ?? ''}
|
||||
onChange={(e) =>
|
||||
onChange({
|
||||
funScore:
|
||||
e.target.value === '' ? null : Number(e.target.value),
|
||||
})
|
||||
}
|
||||
disabled={disabled}
|
||||
placeholder="可选"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user