|
@@ -83,9 +83,20 @@ function computeBookGenStage(chapters: { genStage: string }[]): BookGenStage {
|
|
|
// 章节阶段顺序(索引越大越"后")
|
|
// 章节阶段顺序(索引越大越"后")
|
|
|
const stageOrder = ['idle', 'outline_completed', 'content_generating', 'content_completed', 'audio_generating', 'audio_completed', 'video_generating', 'video_completed', 'failed'];
|
|
const stageOrder = ['idle', 'outline_completed', 'content_generating', 'content_completed', 'audio_generating', 'audio_completed', 'video_generating', 'video_completed', 'failed'];
|
|
|
|
|
|
|
|
|
|
+ // 只看叶节点(没有子节点的节点)来判断整本书的阶段。
|
|
|
|
|
+ // 原因:L1 章(父节点)本身不生成内容/音频,永远停在 outline_completed,
|
|
|
|
|
+ // 若把它们算进去,会把整本书的阶段永远拉回 outline_completed,
|
|
|
|
|
+ // 导致书永远"完成不了"、前端永远显示"生成中"。
|
|
|
|
|
+ // 叶节点 = 不是任何其他节点的 parent。
|
|
|
|
|
+ const all = chapters as any[];
|
|
|
|
|
+ const parentIds = new Set(all.map(c => c.parentId).filter((v) => v != null));
|
|
|
|
|
+ let leaves = all.filter(c => !parentIds.has(c.id));
|
|
|
|
|
+ // 兜底:若无法判断父子关系(缺少 id/parentId 字段),退回用全部章节
|
|
|
|
|
+ if (leaves.length === 0) leaves = all;
|
|
|
|
|
+
|
|
|
// 找出最低阶段的索引
|
|
// 找出最低阶段的索引
|
|
|
let minIdx = stageOrder.length; // 默认最大
|
|
let minIdx = stageOrder.length; // 默认最大
|
|
|
- for (const ch of chapters) {
|
|
|
|
|
|
|
+ for (const ch of leaves) {
|
|
|
const idx = stageOrder.indexOf(ch.genStage);
|
|
const idx = stageOrder.indexOf(ch.genStage);
|
|
|
if (idx === -1) {
|
|
if (idx === -1) {
|
|
|
console.warn(`[BookStore] 未知章节阶段: chapterId=${(ch as any).id}, genStage="${ch.genStage}",跳过该章节`);
|
|
console.warn(`[BookStore] 未知章节阶段: chapterId=${(ch as any).id}, genStage="${ch.genStage}",跳过该章节`);
|