001project_wildgrowth/backend/scripts/backfill-notebooks-cover.ts

125 lines
3.8 KiB
TypeScript
Raw Normal View History

2026-02-11 15:26:03 +08:00
import { PrismaClient } from '@prisma/client';
import { logger } from '../src/utils/logger';
const prisma = new PrismaClient();
/**
*
*/
async function backfillNotebooksCover() {
try {
console.log('=== 开始清洗笔记本封面数据 ===\n');
// 获取所有没有封面的笔记本
const notebooks = await prisma.notebook.findMany({
where: {
OR: [
{ coverImage: null },
{ coverImage: '' },
],
},
});
console.log(`找到 ${notebooks.length} 个需要补封面的笔记本\n`);
let successCount = 0;
let failCount = 0;
for (const notebook of notebooks) {
let coverImage: string | null = null;
try {
// 方法1从关联笔记的课程中获取
const firstNote = await prisma.note.findFirst({
where: {
notebookId: notebook.id,
courseId: { not: null },
},
orderBy: { createdAt: 'asc' },
include: {
course: {
select: {
coverImage: true,
},
},
},
});
if (firstNote?.course?.coverImage) {
coverImage = firstNote.course.coverImage;
console.log(`✅ [${notebook.id}] 从关联笔记的课程获取封面: ${coverImage}`);
} else if (firstNote?.courseId) {
// 备用方案:单独查询课程
const course = await prisma.course.findUnique({
where: { id: firstNote.courseId },
select: { coverImage: true },
});
if (course?.coverImage) {
coverImage = course.coverImage;
console.log(`✅ [${notebook.id}] 从课程 ${firstNote.courseId} 获取封面(备用方案): ${coverImage}`);
}
}
// 方法2如果方法1失败通过课程名称匹配
if (!coverImage) {
const courseName = notebook.title
.replace(/《/g, '')
.replace(/》/g, '')
.trim();
if (courseName) {
// 先尝试精确匹配
let matchingCourse = await prisma.course.findFirst({
where: { title: courseName },
select: { id: true, title: true, coverImage: true },
});
// 如果精确匹配失败,尝试包含匹配
if (!matchingCourse) {
matchingCourse = await prisma.course.findFirst({
where: {
title: {
contains: courseName,
},
},
select: { id: true, title: true, coverImage: true },
});
}
if (matchingCourse?.coverImage) {
coverImage = matchingCourse.coverImage;
console.log(`✅ [${notebook.id}] 通过课程名称匹配获取封面: ${matchingCourse.title} -> ${coverImage}`);
}
}
}
// 更新笔记本封面
if (coverImage) {
await prisma.notebook.update({
where: { id: notebook.id },
data: { coverImage },
});
successCount++;
} else {
console.log(`⚠️ [${notebook.id}] "${notebook.title}" 无法找到匹配的课程封面`);
failCount++;
}
} catch (error) {
console.error(`❌ [${notebook.id}] 处理失败:`, error);
failCount++;
}
}
console.log(`\n=== 清洗完成 ===`);
console.log(`成功: ${successCount}`);
console.log(`失败: ${failCount}`);
} catch (error) {
console.error('脚本执行失败:', error);
} finally {
await prisma.$disconnect();
}
}
backfillNotebooksCover();