001project_wildgrowth/backend/scripts/inspect-paragraphs-server.js

125 lines
4.4 KiB
JavaScript
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.

#!/usr/bin/env node
/**
* 排查「段落间距」:对比 调用记录里 outline.suggestedContent 与 node_slides.content.paragraphs
* 在服务器上执行(需能连到数据库):
* cd /var/www/wildgrowth-backend/backend && node scripts/inspect-paragraphs-server.js
* 本地(有 .env
* cd backend && node scripts/inspect-paragraphs-server.js
*/
const { PrismaClient } = require('@prisma/client');
const prisma = new PrismaClient();
async function main() {
const argId = process.argv[2] ? process.argv[2].trim() : null;
let task;
if (argId) {
// 先按 taskId 查,再按 courseId 查
task = await prisma.courseGenerationTask.findFirst({
where: { id: argId },
include: { course: { select: { id: true, title: true } } },
});
if (!task) {
task = await prisma.courseGenerationTask.findFirst({
where: { courseId: argId },
orderBy: { createdAt: 'desc' },
include: { course: { select: { id: true, title: true } } },
});
}
if (!task) {
console.log('未找到 taskId 或 courseId 为', argId, '的任务');
return;
}
} else {
// 取最新一条已完成任务
task = await prisma.courseGenerationTask.findFirst({
where: { status: 'completed' },
orderBy: { createdAt: 'desc' },
include: { course: { select: { id: true, title: true } } },
});
if (!task) {
console.log('没有已完成的生成任务');
return;
}
}
console.log('=== 任务信息 ===');
console.log('taskId:', task.id);
console.log('courseId:', task.courseId);
console.log('courseTitle:', task.course?.title ?? '');
console.log('');
const outline = task.outline;
if (!outline || !outline.chapters || !Array.isArray(outline.chapters)) {
console.log('任务无 outline 或 chapters');
return;
}
// 取第一个小节对应的 suggestedContent调用记录里显示的那类内容
let firstSuggestedContent = null;
let firstNodeTitle = '';
for (const ch of outline.chapters) {
if (ch.nodes && Array.isArray(ch.nodes)) {
for (const node of ch.nodes) {
if (node.suggestedContent) {
firstSuggestedContent = node.suggestedContent;
firstNodeTitle = node.title || '';
break;
}
}
if (firstSuggestedContent) break;
}
}
if (!firstSuggestedContent) {
console.log('outline 中未找到 suggestedContent');
} else {
console.log('=== outline 中第一个小节的 suggestedContent调用记录里看到的内容===');
console.log('小节标题:', firstNodeTitle);
console.log('长度:', firstSuggestedContent.length);
const idx = firstSuggestedContent.indexOf('\n');
console.log('第一个 \\n 位置:', idx === -1 ? '无' : idx);
const doubleNewlineCount = (firstSuggestedContent.match(/\n\s*\n/g) || []).length;
console.log('双换行 \\n\\n 出现次数:', doubleNewlineCount);
const splitByDouble = firstSuggestedContent.split(/\n\s*\n/).map((p) => p.trim()).filter((p) => p.length > 0);
console.log('按 /\\n\\s*\\n/ 拆分后段落数:', splitByDouble.length);
console.log('前 350 字符repr:', JSON.stringify(firstSuggestedContent.slice(0, 350)));
console.log('');
}
// 该课程下第一个节点的 node_slides 的 content.paragraphs
const firstNode = await prisma.courseNode.findFirst({
where: { courseId: task.courseId },
orderBy: { orderIndex: 'asc' },
include: { slides: { orderBy: { orderIndex: 'asc' }, take: 1 } },
});
if (!firstNode || !firstNode.slides || firstNode.slides.length === 0) {
console.log('该课程下没有节点或没有 node_slides');
return;
}
const slide = firstNode.slides[0];
const content = slide.content;
console.log('=== 该课程第一个节点的 node_slides.content实际落库===');
console.log('节点标题:', firstNode.title);
console.log('slide id:', slide.id);
if (content && typeof content === 'object' && Array.isArray(content.paragraphs)) {
console.log('paragraphs 数量:', content.paragraphs.length);
content.paragraphs.forEach((p, i) => {
console.log(` [${i}] 长度: ${p.length}, 前80字: ${JSON.stringify(p.slice(0, 80))}`);
});
} else {
console.log('content 或 content.paragraphs 不存在:', content ? Object.keys(content) : 'null');
}
}
main()
.then(() => process.exit(0))
.catch((e) => {
console.error(e);
process.exit(1);
})
.finally(() => prisma.$disconnect());