feat(ai写作): 草稿局部修改只改命中章节,支持改章节标题,修改时右侧流式重写

用户在草稿确认填修改意见(user_revise)时,按章节定位只重写命中章节、
其余字节级保留;新增范围识别区分「改标题」与「改正文」,改标题同步回写
outline 使其持久生效(修复改章节标题不生效);整体性/结构性意见自动回退
整篇重写。前端新增 isRevising:修改时右侧先恢复初始占位(清空旧稿),
重写流到达后实时展示被改章节的流式重写。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
fengxiangdebaoziandClaude Opus 4.8 committed 2026-06-24 19:45:00 +08:00
1 parent 42f55251f2
commit c117e296cb
6 files changed
+125 -51

No files matched your search

@@ -41,10 +41,23 @@ export function AIWritingDraftPanel() {
const showCompletedDraftView = isDraftEditable || isHistoryMode;
const writingStatus = writing?.state.status;
const streamingSectionCount = writing?.state.streamingDraftSections.length ?? 0;
// 按用户意见修改中、且重写流还没开始(无任何流式章节):右侧先恢复初始空占位,
// 把旧稿清掉;一旦重写流式 chunk 到达(streamingDraftSections 非空)就走下面的
// 流式预览,实时展示重写过程;draft_ready 后 isRevising 置回 false 显示新成稿。
if (writing?.state.isRevising && streamingSectionCount === 0) {
return (
<div className="h-full bg-muted/10 border-l">
<DraftWaitingPlaceholder />
</div>
);
}
// 仅当章节仍在累积时走流式 Markdown;draft_ready 清空 sections 后即使 status 尚未切走也进画布
const isActivelyStreamingDraft =
(writingStatus === 'writing_draft' || writingStatus === 'revising') &&
(writing?.state.streamingDraftSections.length ?? 0) > 0;
streamingSectionCount > 0;
const streamingMarkdown = isActivelyStreamingDraft && writing
? assembleStreamingDraftMarkdown(
@@ -70,6 +70,7 @@ const INITIAL_STATE: AIWritingState = {
streamingReviewItems: [],
revisionSummary: null,
pendingRevisionContext: null,
isRevising: false,
};
export { INITIAL_STATE };
@@ -118,7 +119,8 @@ export function reducer(prev: AIWritingState, action: Action): AIWritingState {
...(ns === 'writing_outline' ? { outlineStreamingText: '', outlineThinkingText: '' } : {}),
...(ns === 'writing_draft' ? { streamingDraftSections: [], streamingDraftTitle: '' } : {}),
...(ns === 'reviewing' ? { streamingReviewItems: [] } : {}),
...(ns === 'revising' ? { streamingDraftSections: [], streamingDraftTitle: '' } : {}),
// 进入「修改」:右侧画布恢复初始空占位(isRevising),不再显示旧稿/流式重写
...(ns === 'revising' ? { streamingDraftSections: [], streamingDraftTitle: '', isRevising: true } : {}),
completedInterventions: [...prev.completedInterventions, action.record],
...(action.pendingRevisionContext ? { pendingRevisionContext: action.pendingRevisionContext } : {}),
};
@@ -357,6 +359,8 @@ function handleEvent(prev: AIWritingState, event: ProgressEvent): AIWritingState
streamingDraftTitle: '',
revisionSummary: summary,
pendingRevisionContext: null,
// 修改完成:解除右侧空占位,展示新成稿
isRevising: false,
};
}
@@ -389,4 +389,7 @@ export interface AIWritingState {
skippedIssues: ReviewIssue[];
oldWordCount: number;
} | null;
/** 是否正按用户意见修改中(revising 提交起 → draft_ready 止)。
* 为 true 时右侧画布恢复初始空占位,不展示旧稿 / 流式重写过程。 */
isRevising: boolean;
}