检索结果过程添加

This commit is contained in:
董宏凯 committed 2026-05-17 22:01:29 +08:00
1 parent 20786e690d
commit 166016a741
6 files changed
+65 -11

No files matched your search

@@ -29,7 +29,7 @@ export async function startWritingSession(req: AIWritingRequest): Promise<string
}
const SSE_EVENT_TYPES: ProgressEventType[] = [
'connected', 'step_start', 'step_done',
'connected', 'step_start', 'step_done', 'research_progress',
'materials_ready', 'outline_chunk', 'outline_ready',
'draft_chunk', 'draft_ready',
'review_chunk', 'review_item_done', 'review_ready',
@@ -327,7 +327,7 @@ export function AIWritingPanel() {
!(state.status === 'writing_outline' && (state.outlineStreamingText || state.outlineThinkingText)) &&
!(state.status === 'reviewing' && state.streamingReviewItems.length > 0) && (
<div className="px-4 pb-4">
<WritingSkeletonCard status={state.status} />
<WritingSkeletonCard status={state.status} researchProgress={state.researchProgress} />
</div>
)}
@@ -376,7 +376,9 @@ export function AIWritingPanel() {
{isRunning && (
<span className="inline-block size-1.5 rounded-full bg-blue-500 animate-pulse" />
)}
{STATUS_LABEL[state.status] ?? state.status}
{state.status === 'researching' && state.researchProgress
? state.researchProgress
: STATUS_LABEL[state.status] ?? state.status}
</>
)}
</div>
@@ -3,6 +3,8 @@ import type { WritingStatus } from '../../types/ai-writing';
interface WritingSkeletonCardProps {
status: WritingStatus;
/** 素材收集阶段的实时进度文案(仅 researching 阶段使用) */
researchProgress?: string;
}
// ── 基础骨架元素 ──────────────────────────────────────────────────────────────
@@ -29,13 +31,13 @@ function ThinkingDots({ color = 'bg-blue-400' }: { color?: string }) {
// ── 素材收集骨架屏 ────────────────────────────────────────────────────────────
function MaterialsSkeleton() {
function MaterialsSkeleton({ researchProgress }: { researchProgress?: string }) {
return (
<div className="space-y-3 p-4">
{/* 标题行 */}
{/* 标题行:展示素材收集专家的实时进度 */}
<div className="flex items-center gap-2 text-xs text-blue-500 font-medium">
<ThinkingDots color="bg-blue-400" />
<span>素材收集专家搜索中…</span>
<span>{researchProgress || '素材收集专家搜索中…'}</span>
</div>
{/* 关键词标签占位 */}
@@ -198,21 +200,28 @@ function RevisingSkeleton() {
// ── 状态映射 ──────────────────────────────────────────────────────────────────
// researching / awaiting_material_confirm 由 WritingSkeletonCard 单独处理(需透传进度文案)
const SKELETON_MAP: Partial<Record<WritingStatus, React.FC>> = {
// 实际运行状态
researching: MaterialsSkeleton,
writing_outline: OutlineSkeleton,
writing_draft: DraftSkeleton,
reviewing: ReviewSkeleton,
revising: RevisingSkeleton,
// 过渡等待状态(用户提交后、后端事件到达前的空白期)
awaiting_material_confirm: MaterialsSkeleton, // 重新搜索 / 过渡到大纲
awaiting_outline_confirm: OutlineSkeleton, // 过渡到写作
awaiting_draft_confirm: DraftSkeleton, // 提交修改意见或编辑审核后
awaiting_review_confirm: RevisingSkeleton, // 采纳编辑意见后
};
export function WritingSkeletonCard({ status }: WritingSkeletonCardProps) {
export function WritingSkeletonCard({ status, researchProgress }: WritingSkeletonCardProps) {
// 素材收集阶段单独渲染,以便透传实时进度文案
if (status === 'researching' || status === 'awaiting_material_confirm') {
return (
<div className="rounded-xl border bg-card shadow-sm overflow-hidden">
<MaterialsSkeleton researchProgress={researchProgress} />
</div>
);
}
const Skeleton = SKELETON_MAP[status];
if (!Skeleton) return null;
return (
@@ -34,6 +34,7 @@ const INITIAL_STATE: AIWritingState = {
streamingDraftSections: [],
outlineStreamingText: '',
outlineThinkingText: '',
researchProgress: '',
streamingReviewItems: [],
revisionSummary: null,
pendingRevisionContext: null,
@@ -64,14 +65,19 @@ export function useAIWriting() {
case 'step_done':
return base;
case 'research_progress':
// 素材收集专家实时进度:仅更新最新提示文案
return { ...base, researchProgress: event.message ?? '' };
case 'resumed':
return { ...base, currentPause: null };
case 'materials_ready':
// 仅缓存素材数据,不弹干预卡(等 await_user 事件再弹)
// 仅缓存素材数据,不弹干预卡(等 await_user 事件再弹);进度文案已完成可清空
return {
...base,
materials: (event.materials ?? []) as AIMaterial[],
researchProgress: '',
};
case 'outline_chunk': {
@@ -345,6 +351,7 @@ export function useAIWriting() {
currentPause: null,
status: nextStatus,
// Clear stale streaming state so new-cycle detection in chunk handlers works correctly
...(nextStatus === 'researching' ? { researchProgress: '' } : {}),
...(nextStatus === 'writing_outline' ? { outlineStreamingText: '', outlineThinkingText: '' } : {}),
...(nextStatus === 'writing_draft' ? { streamingDraftSections: [], streamingDraftTitle: '' } : {}),
...(nextStatus === 'reviewing' ? { streamingReviewItems: [] } : {}),
@@ -67,6 +67,7 @@ export type ProgressEventType =
| 'connected'
| 'step_start'
| 'step_done'
| 'research_progress'
| 'materials_ready'
| 'outline_chunk'
| 'outline_ready'
@@ -201,6 +202,8 @@ export interface AIWritingState {
// 流式大纲(正文 / 思考分开)
outlineStreamingText: string;
outlineThinkingText: string;
// 素材收集实时进度(最新一条提示文案)
researchProgress: string;
// 流式审核(逐条到达)
streamingReviewItems: StreamingReviewItem[];
// 修改摘要