112 lines
2.8 KiB
TypeScript
112 lines
2.8 KiB
TypeScript
|
|
/**
|
|||
|
|
* 清理卡在30%的课程数据
|
|||
|
|
* 使用方法:ts-node backend/scripts/cleanup-stuck-courses.ts
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
import prisma from '../src/utils/prisma';
|
|||
|
|
import * as dotenv from 'dotenv';
|
|||
|
|
import path from 'path';
|
|||
|
|
|
|||
|
|
// 加载环境变量
|
|||
|
|
dotenv.config({ path: path.join(__dirname, '../.env') });
|
|||
|
|
|
|||
|
|
async function cleanupStuckCourses() {
|
|||
|
|
try {
|
|||
|
|
console.log('🔍 查找卡在30%的课程...\n');
|
|||
|
|
|
|||
|
|
// 查找状态为generating且progress为0.3的课程
|
|||
|
|
const stuckCourses = await prisma.course.findMany({
|
|||
|
|
where: {
|
|||
|
|
generationStatus: 'generating',
|
|||
|
|
generationProgress: 0.3,
|
|||
|
|
},
|
|||
|
|
include: {
|
|||
|
|
aiContentTask: {
|
|||
|
|
select: {
|
|||
|
|
id: true,
|
|||
|
|
status: true,
|
|||
|
|
suggestedTitle: true,
|
|||
|
|
},
|
|||
|
|
},
|
|||
|
|
},
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
console.log(`找到 ${stuckCourses.length} 个卡住的课程:\n`);
|
|||
|
|
|
|||
|
|
if (stuckCourses.length === 0) {
|
|||
|
|
console.log('✅ 没有需要清理的课程');
|
|||
|
|
await prisma.$disconnect();
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 显示课程信息
|
|||
|
|
stuckCourses.forEach((course, index) => {
|
|||
|
|
console.log(`${index + 1}. ${course.title}`);
|
|||
|
|
console.log(` Course ID: ${course.id}`);
|
|||
|
|
console.log(` Task ID: ${course.aiContentTask?.id || 'N/A'}`);
|
|||
|
|
console.log(` 创建时间: ${course.createdAt}`);
|
|||
|
|
console.log('');
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
// 确认删除
|
|||
|
|
console.log('⚠️ 准备删除以上课程及其关联数据...\n');
|
|||
|
|
|
|||
|
|
let deletedCount = 0;
|
|||
|
|
let errorCount = 0;
|
|||
|
|
|
|||
|
|
for (const course of stuckCourses) {
|
|||
|
|
try {
|
|||
|
|
// 1. 删除 UserCourse 关联
|
|||
|
|
await prisma.userCourse.deleteMany({
|
|||
|
|
where: {
|
|||
|
|
courseId: course.id,
|
|||
|
|
},
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
// 2. 删除 Course 记录
|
|||
|
|
await prisma.course.delete({
|
|||
|
|
where: {
|
|||
|
|
id: course.id,
|
|||
|
|
},
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
// 3. 删除 AIContentTask(如果存在)
|
|||
|
|
if (course.aiContentTaskId) {
|
|||
|
|
await prisma.aIPromptLog.deleteMany({
|
|||
|
|
where: {
|
|||
|
|
taskId: course.aiContentTaskId,
|
|||
|
|
},
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
await prisma.aIContentTask.delete({
|
|||
|
|
where: {
|
|||
|
|
id: course.aiContentTaskId,
|
|||
|
|
},
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
deletedCount++;
|
|||
|
|
console.log(`✅ 已删除: ${course.title} (${course.id})`);
|
|||
|
|
} catch (error: any) {
|
|||
|
|
errorCount++;
|
|||
|
|
console.error(`❌ 删除失败: ${course.title} (${course.id}) - ${error.message}`);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
console.log('\n📊 清理结果:');
|
|||
|
|
console.log(` ✅ 成功删除: ${deletedCount} 个课程`);
|
|||
|
|
if (errorCount > 0) {
|
|||
|
|
console.log(` ❌ 删除失败: ${errorCount} 个课程`);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
await prisma.$disconnect();
|
|||
|
|
} catch (error: any) {
|
|||
|
|
console.error('❌ 清理过程出错:', error);
|
|||
|
|
await prisma.$disconnect();
|
|||
|
|
process.exit(1);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 运行清理
|
|||
|
|
cleanupStuckCourses();
|