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

125 lines
3.8 KiB
TypeScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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();