first commit
Some checks failed
Some checks failed
This commit is contained in:
156
app/lib/testcase-backend/process.ts
Normal file
156
app/lib/testcase-backend/process.ts
Normal file
@@ -0,0 +1,156 @@
|
||||
import path from "path";
|
||||
import { getTask, setTask } from "./store";
|
||||
import { validateStandardCode } from "./runner";
|
||||
import { generateFallbackTestCases, runAIGeneratedCases, getOutputBase } from "./generator";
|
||||
import { generateTestCases, isQwenAvailable } from "./qwen-service";
|
||||
|
||||
function formatErrorMessage(err: unknown): string {
|
||||
const message = err instanceof Error ? err.message : String(err);
|
||||
if ((err as Error & { code?: string }).code === "COMPILATION_ERROR") {
|
||||
return `C++程序编译失败: ${message}`;
|
||||
}
|
||||
if ((err as Error & { code?: string }).code === "EXECUTION_ERROR") {
|
||||
return `程序执行错误: ${message}`;
|
||||
}
|
||||
return message;
|
||||
}
|
||||
|
||||
function updateTaskProgress(
|
||||
taskId: string,
|
||||
status: "pending" | "running" | "completed" | "failed",
|
||||
progress: number,
|
||||
message: string,
|
||||
generatedCount?: number
|
||||
): void {
|
||||
const task = getTask(taskId);
|
||||
if (!task) return;
|
||||
task.status = status;
|
||||
task.progress = Math.min(100, Math.max(0, progress));
|
||||
task.updatedAt = new Date();
|
||||
task.currentMessage = message;
|
||||
if (generatedCount !== undefined) task.generatedCases = generatedCount;
|
||||
setTask(taskId, task);
|
||||
}
|
||||
|
||||
export async function processTask(taskId: string): Promise<void> {
|
||||
const task = getTask(taskId);
|
||||
if (!task) {
|
||||
console.error(`任务不存在: ${taskId}`);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
updateTaskProgress(taskId, "running", 10, "正在初始化生成环境...");
|
||||
|
||||
await validateStandardCode(task.standardCode);
|
||||
updateTaskProgress(taskId, "running", 20, "标准程序验证通过,开始生成测试数据...");
|
||||
|
||||
let result: { testCases: { input: string; output: string }[]; outputDirName: string; zipFileName: string };
|
||||
|
||||
if (isQwenAvailable()) {
|
||||
try {
|
||||
updateTaskProgress(taskId, "running", 22, "正在调用阿里云大模型生成测试用例...", 0);
|
||||
const aiCases = await generateTestCases({
|
||||
title: task.title,
|
||||
englishName: task.englishName,
|
||||
description: task.description,
|
||||
standardCode: task.standardCode,
|
||||
testCaseCount: task.testCaseCount,
|
||||
serviceLevel: task.serviceLevel,
|
||||
});
|
||||
if (aiCases.length > 0) {
|
||||
updateTaskProgress(taskId, "running", 25, "AI 生成完成,正在用标程计算输出...", 0);
|
||||
result = await runAIGeneratedCases(
|
||||
{
|
||||
englishName: task.englishName,
|
||||
description: task.description,
|
||||
standardCode: task.standardCode,
|
||||
testCaseCount: task.testCaseCount,
|
||||
},
|
||||
aiCases,
|
||||
(progress, message, generatedCount) => {
|
||||
updateTaskProgress(
|
||||
taskId,
|
||||
"running",
|
||||
25 + Math.floor(progress * 65),
|
||||
message,
|
||||
generatedCount
|
||||
);
|
||||
}
|
||||
);
|
||||
} else {
|
||||
throw new Error("AI 未返回有效用例");
|
||||
}
|
||||
} catch (aiErr) {
|
||||
console.warn("AI 生成失败,使用备用算法:", aiErr);
|
||||
updateTaskProgress(taskId, "running", 20, "使用智能算法生成测试用例...", 0);
|
||||
result = await generateFallbackTestCases(
|
||||
{
|
||||
englishName: task.englishName,
|
||||
description: task.description,
|
||||
standardCode: task.standardCode,
|
||||
testCaseCount: task.testCaseCount,
|
||||
},
|
||||
(progress, message, generatedCount) => {
|
||||
updateTaskProgress(
|
||||
taskId,
|
||||
"running",
|
||||
20 + Math.floor(progress * 70),
|
||||
message,
|
||||
generatedCount
|
||||
);
|
||||
}
|
||||
);
|
||||
}
|
||||
} else {
|
||||
result = await generateFallbackTestCases(
|
||||
{
|
||||
englishName: task.englishName,
|
||||
description: task.description,
|
||||
standardCode: task.standardCode,
|
||||
testCaseCount: task.testCaseCount,
|
||||
},
|
||||
(progress, message, generatedCount) => {
|
||||
updateTaskProgress(
|
||||
taskId,
|
||||
"running",
|
||||
20 + Math.floor(progress * 70),
|
||||
message,
|
||||
generatedCount
|
||||
);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
updateTaskProgress(taskId, "running", 95, "正在打包文件...", result.testCases.length);
|
||||
|
||||
const finalTask = getTask(taskId);
|
||||
if (finalTask) {
|
||||
finalTask.status = "completed";
|
||||
finalTask.progress = 100;
|
||||
finalTask.updatedAt = new Date();
|
||||
finalTask.completedAt = new Date();
|
||||
finalTask.generatedCases = result.testCases.length;
|
||||
finalTask.zipFileName = result.zipFileName;
|
||||
finalTask.outputDirName = result.outputDirName;
|
||||
setTask(taskId, finalTask);
|
||||
}
|
||||
} catch (err) {
|
||||
console.error(`任务失败: ${taskId}`, err);
|
||||
const finalTask = getTask(taskId);
|
||||
if (finalTask) {
|
||||
finalTask.status = "failed";
|
||||
finalTask.progress = 0;
|
||||
finalTask.errorMessage = formatErrorMessage(err);
|
||||
finalTask.updatedAt = new Date();
|
||||
finalTask.failedAt = new Date();
|
||||
setTask(taskId, finalTask);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function getZipPathForTask(taskId: string): string | null {
|
||||
const task = getTask(taskId);
|
||||
if (!task?.zipFileName) return null;
|
||||
return path.join(getOutputBase(), task.zipFileName);
|
||||
}
|
||||
Reference in New Issue
Block a user