update
This commit is contained in:
@@ -1,7 +1,9 @@
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
const BASE = 'http://localhost:3030';
|
||||
const BASE = (process.env.BASE_URL || 'http://localhost:3031').replace(/\/$/, '');
|
||||
const ADMIN_USER = process.env.ADMIN_USER || 'admin';
|
||||
const ADMIN_PASS = process.env.ADMIN_PASS || 'admin123';
|
||||
const ARGS = process.argv.slice(2);
|
||||
const FILES = ARGS.length ? ARGS : ['set-dart-dev.json', 'set-flutter-dev.json'];
|
||||
|
||||
@@ -9,7 +11,7 @@ async function main() {
|
||||
const loginRes = await fetch(BASE + '/api/admin/login', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ username: 'admin', password: 'admin123' })
|
||||
body: JSON.stringify({ username: ADMIN_USER, password: ADMIN_PASS })
|
||||
});
|
||||
const login = await loginRes.json();
|
||||
if (!loginRes.ok) throw new Error('登录失败: ' + login.error);
|
||||
|
||||
@@ -1,18 +1,46 @@
|
||||
const d = require('../questions.json');
|
||||
let total = 0, bad = [];
|
||||
const setIds = new Set(), qIds = new Set(), setNames = new Set();
|
||||
let maxSetId = 0, maxQId = 0;
|
||||
if (!d || !Array.isArray(d.sets)) {
|
||||
console.error('questions.json 根节点必须包含 sets 数组');
|
||||
process.exit(1);
|
||||
}
|
||||
for (const set of d.sets) {
|
||||
if (!Number.isInteger(set.id) || set.id < 1 || setIds.has(set.id)) bad.push(`[套题] ID 非法或重复: ${set.id}`);
|
||||
else { setIds.add(set.id); maxSetId = Math.max(maxSetId, set.id); }
|
||||
const normalizedName = typeof set.name === 'string' ? set.name.trim().toLowerCase() : '';
|
||||
if (!normalizedName || setNames.has(normalizedName)) bad.push(`[套题 #${set.id}] 名称为空或重复`);
|
||||
else setNames.add(normalizedName);
|
||||
if (typeof set.name === 'string' && set.name.trim().length > 80) bad.push(`[套题 #${set.id}] 名称超过 80 个字符`);
|
||||
if (set.description !== undefined && (typeof set.description !== 'string' || set.description.trim().length > 240)) {
|
||||
bad.push(`[${set.name || set.id}] description 必须为不超过 240 字的字符串`);
|
||||
}
|
||||
if (set.published !== undefined && typeof set.published !== 'boolean') bad.push(`[${set.name || set.id}] published 必须为布尔值`);
|
||||
if (!Array.isArray(set.questions)) { bad.push(`[${set.name || set.id}] questions 不是数组`); continue; }
|
||||
if (set.lvNames != null && (!Array.isArray(set.lvNames) || set.lvNames.length !== 6 || set.lvNames.some(n => typeof n !== 'string' || !n.trim()))) {
|
||||
bad.push(`[${set.name}] lvNames 必须为 6 个非空名称`);
|
||||
}
|
||||
for (const q of set.questions) {
|
||||
total++;
|
||||
if (!q.q || !Array.isArray(q.opts) || q.opts.length < 2) { bad.push(`[${set.name} #${q.id}] 选项不足`); continue; }
|
||||
if (!Number.isInteger(q.id) || q.id < 1 || qIds.has(q.id)) { bad.push(`[${set.name}] 题目 ID 非法或重复: ${q.id}`); continue; }
|
||||
qIds.add(q.id); maxQId = Math.max(maxQId, q.id);
|
||||
if (typeof q.q !== 'string' || !q.q.trim()) { bad.push(`[${set.name} #${q.id}] 题干必须为非空字符串`); continue; }
|
||||
if (!Array.isArray(q.opts) || q.opts.length < 2 || q.opts.some(o => typeof o !== 'string' || !o.trim())) {
|
||||
bad.push(`[${set.name} #${q.id}] 至少需要 2 个非空字符串选项`); continue;
|
||||
}
|
||||
if (!Number.isInteger(q.ans) || q.ans < 0 || q.ans >= q.opts.length) { bad.push(`[${set.name} #${q.id}] ans 越界`); continue; }
|
||||
if (!q.exp) { bad.push(`[${set.name} #${q.id}] 缺解析`); continue; }
|
||||
if (typeof q.exp !== 'string' || !q.exp.trim()) { bad.push(`[${set.name} #${q.id}] 解析必须为非空字符串`); continue; }
|
||||
if (!Number.isInteger(q.lv) || q.lv < 1 || q.lv > 6) { bad.push(`[${set.name} #${q.id}] lv 非法`); continue; }
|
||||
const dup = q.opts.findIndex((o, i) => q.opts.indexOf(o) !== i);
|
||||
const normalizedOpts = q.opts.map(o => o.trim());
|
||||
const dup = normalizedOpts.findIndex((o, i) => normalizedOpts.indexOf(o) !== i);
|
||||
if (dup !== -1) { bad.push(`[${set.name} #${q.id}] 选项重复: "${q.opts[dup]}"`); }
|
||||
}
|
||||
}
|
||||
if (!Number.isInteger(d.nextSetId) || d.nextSetId <= maxSetId) bad.push(`nextSetId 应大于 ${maxSetId}`);
|
||||
if (!Number.isInteger(d.nextQId) || d.nextQId <= maxQId) bad.push(`nextQId 应大于 ${maxQId}`);
|
||||
console.log('总题数:', total);
|
||||
if (bad.length) { console.log('问题:'); bad.forEach(b => console.log(' -', b)); }
|
||||
if (bad.length) { console.log('问题:'); bad.forEach(b => console.log(' -', b)); process.exitCode = 1; }
|
||||
else console.log('结构校验全部通过');
|
||||
|
||||
// 抽查逻辑已移除,因为选项顺序已被随机打乱
|
||||
|
||||
Reference in New Issue
Block a user