mirror of
https://github.com/massbug/judge4c.git
synced 2025-07-03 15:20:50 +00:00
fix(testcase): fix testcase add data failure due to index did not refresh index after save testcase
- 为测试用例添加唯一的临时 ID,避免重复 - 新增测试用例时检查输入和输出不能为空 - 保存测试用例时显示具体的成功和失败信息 - 保存完成后刷新最新测试用例数据 - 优化代码结构,提高可读性和可维护性
This commit is contained in:
parent
5bfa5fd642
commit
2a3769b95c
@ -24,7 +24,7 @@ export default function EditTestcasePanel({ problemId }: { problemId: string })
|
||||
const [testcases, setTestcases] = useState<Testcase[]>([]);
|
||||
const [isGenerating, setIsGenerating] = useState(false);
|
||||
|
||||
// 1) Load existing testcases
|
||||
// 加载测试用例
|
||||
useEffect(() => {
|
||||
async function fetch() {
|
||||
try {
|
||||
@ -38,21 +38,21 @@ export default function EditTestcasePanel({ problemId }: { problemId: string })
|
||||
fetch();
|
||||
}, [problemId]);
|
||||
|
||||
// 2) Local add
|
||||
// 本地添加测试用例
|
||||
const handleAddTestcase = () =>
|
||||
setTestcases((prev) => [
|
||||
...prev,
|
||||
{ id: `new-${Date.now()}`, expectedOutput: "", inputs: [{ name: "input1", value: "" }] },
|
||||
{ id: `new-${Date.now()}-${Math.random()}`, expectedOutput: "", inputs: [{ name: "input1", value: "" }] },
|
||||
]);
|
||||
|
||||
// 3) AI generation
|
||||
// AI 生成测试用例
|
||||
const handleAITestcase = async () => {
|
||||
setIsGenerating(true);
|
||||
try {
|
||||
const ai = await generateAITestcase({ problemId });
|
||||
setTestcases((prev) => [
|
||||
...prev,
|
||||
{ id: `new-${Date.now()}`, expectedOutput: ai.expectedOutput, inputs: ai.inputs },
|
||||
{ id: `new-${Date.now()}-${Math.random()}`, expectedOutput: ai.expectedOutput, inputs: ai.inputs },
|
||||
]);
|
||||
window.scrollTo({ top: document.body.scrollHeight, behavior: "smooth" });
|
||||
} catch (err) {
|
||||
@ -63,7 +63,7 @@ export default function EditTestcasePanel({ problemId }: { problemId: string })
|
||||
}
|
||||
};
|
||||
|
||||
// 4) Remove (local + remote if existing)
|
||||
// 删除测试用例(本地 + 服务器)
|
||||
const handleRemoveTestcase = async (idx: number) => {
|
||||
const tc = testcases[idx];
|
||||
if (!tc.id.startsWith("new-")) {
|
||||
@ -79,14 +79,15 @@ export default function EditTestcasePanel({ problemId }: { problemId: string })
|
||||
setTestcases((prev) => prev.filter((_, i) => i !== idx));
|
||||
};
|
||||
|
||||
// 5) Field updates
|
||||
// 修改预期输出
|
||||
const handleExpectedOutputChange = (idx: number, val: string) =>
|
||||
setTestcases((prev) => {
|
||||
const c = [...prev];
|
||||
c[idx].expectedOutput = val;
|
||||
c[idx] = { ...c[idx], expectedOutput: val };
|
||||
return c;
|
||||
});
|
||||
|
||||
// 修改输入参数
|
||||
const handleInputChange = (
|
||||
tIdx: number,
|
||||
iIdx: number,
|
||||
@ -95,43 +96,58 @@ export default function EditTestcasePanel({ problemId }: { problemId: string })
|
||||
) =>
|
||||
setTestcases((prev) => {
|
||||
const c = [...prev];
|
||||
c[tIdx].inputs[iIdx][field] = val;
|
||||
const newInputs = [...c[tIdx].inputs];
|
||||
newInputs[iIdx] = { ...newInputs[iIdx], [field]: val };
|
||||
c[tIdx] = { ...c[tIdx], inputs: newInputs };
|
||||
return c;
|
||||
});
|
||||
|
||||
// 添加输入参数
|
||||
const handleAddInput = (tIdx: number) =>
|
||||
setTestcases((prev) => {
|
||||
const c = [...prev];
|
||||
c[tIdx].inputs.push({ name: `input${c[tIdx].inputs.length + 1}`, value: "" });
|
||||
const inputs = [...c[tIdx].inputs, { name: `input${c[tIdx].inputs.length + 1}`, value: "" }];
|
||||
c[tIdx] = { ...c[tIdx], inputs };
|
||||
return c;
|
||||
});
|
||||
|
||||
// 删除输入参数
|
||||
const handleRemoveInput = (tIdx: number, iIdx: number) =>
|
||||
setTestcases((prev) => {
|
||||
const c = [...prev];
|
||||
c[tIdx].inputs.splice(iIdx, 1);
|
||||
const inputs = c[tIdx].inputs.filter((_, i) => i !== iIdx);
|
||||
c[tIdx] = { ...c[tIdx], inputs };
|
||||
return c;
|
||||
});
|
||||
|
||||
// 6) Persist all changes
|
||||
// 保存所有测试用例,并刷新最新数据
|
||||
const handleSaveAll = async () => {
|
||||
try {
|
||||
for (const tc of testcases) {
|
||||
for (let i = 0; i < testcases.length; i++) {
|
||||
const tc = testcases[i];
|
||||
if (tc.expectedOutput.trim() === "" || tc.inputs.some(inp => !inp.name.trim() || !inp.value.trim())) {
|
||||
toast.error(`第 ${i + 1} 个测试用例存在空的输入或输出,保存失败`);
|
||||
return;
|
||||
}
|
||||
|
||||
if (tc.id.startsWith("new-")) {
|
||||
const res = await addProblemTestcase(problemId, tc.expectedOutput, tc.inputs);
|
||||
if (res.success) toast.success("新增测试用例成功");
|
||||
else toast.error("新增测试用例失败");
|
||||
if (res.success) {
|
||||
toast.success(`新增测试用例 ${i + 1} 成功`);
|
||||
} else {
|
||||
const res = await updateProblemTestcase(
|
||||
problemId,
|
||||
tc.id,
|
||||
tc.expectedOutput,
|
||||
tc.inputs
|
||||
);
|
||||
if (res.success) toast.success("更新测试用例成功");
|
||||
else toast.error("更新测试用例失败");
|
||||
toast.error(`新增测试用例 ${i + 1} 失败`);
|
||||
}
|
||||
} else {
|
||||
const res = await updateProblemTestcase(problemId, tc.id, tc.expectedOutput, tc.inputs);
|
||||
if (res.success) toast.success(`更新测试用例 ${i + 1} 成功`);
|
||||
else toast.error(`更新测试用例 ${i + 1} 失败`);
|
||||
}
|
||||
}
|
||||
|
||||
// 保存完成后刷新最新测试用例
|
||||
const data = await getProblemData(problemId);
|
||||
setTestcases(data.testcases || []);
|
||||
toast.success("测试用例保存并刷新成功");
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
toast.error("保存测试用例异常");
|
||||
|
Loading…
Reference in New Issue
Block a user