样式修改

This commit is contained in:
fengxiangdebaozi committed 2026-05-29 20:16:41 +08:00
1 parent c890ae5a15
commit 27cfd53c06
12 files changed
+321 -56

No files matched your search

@@ -463,8 +463,9 @@ export function AIWritingPanel({
/>
)}
{/* 研究中 + 已有技能步骤:实时流式展示技能检索过程,避免 skeleton 卡片掩盖步骤 */}
{state.status === 'researching' && state.skillSearchSteps.length > 0 && (
{/* 技能检索 pending:用户点击瞬间到 awaiting 之间,始终显示 SkillStepsCard 占位
steps.length === 0 时 SkillStepsCard 内部会渲染骨架行,不让用户干等空白 */}
{state.skillSearchPending && (
<div className="px-4 pb-2">
<SkillStepsCard steps={state.skillSearchSteps} inProgress />
</div>
@@ -474,8 +475,8 @@ export function AIWritingPanel({
state.status !== 'writing_draft' &&
!(state.status === 'writing_outline' && (state.outlineStreamingText || state.outlineThinkingText)) &&
!(state.status === 'reviewing' && state.streamingReviewItems.length > 0) &&
/* 技能检索已经在流式展示步骤 / 选择打字机 / 等待 chunk 中,不再叠加 skeleton */
!(state.status === 'researching' && state.skillSearchSteps.length > 0) &&
/* 技能检索占位卡 / 选择打字机 已经在流式展示,不再叠加 skeleton */
!state.skillSearchPending &&
!(state.status === 'researching' && (state.skillSelectStreamingText || state.skillSelectThinkingText)) &&
/* 意图解析流式过程中(LLM 还在吐 JSON)不要显示 skeleton */
!state.intentStreamingText && !state.intentThinkingText && (
@@ -73,7 +73,7 @@ export function MaterialsToolbar({
value={userQuery}
onChange={handleInput}
onKeyDown={handleKeyDown}
placeholder={placeholder ?? '例如:想查看各大平台销量 / 2025 年财报 / 行业头部公司近期动态…'}
placeholder={placeholder ?? '输入文字后点击“重新搜索”或“技能检索”按钮…'}
disabled={disabled}
className="w-full resize-none rounded-md border border-input bg-background px-2.5 py-1.5 text-xs leading-5 placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:opacity-50 min-h-[28px] max-h-24"
/>
@@ -118,9 +118,28 @@ export function SkillStepsCard({ steps, inProgress }: SkillStepsCardProps) {
</li>
);
})}
{inProgress && (
{inProgress && steps.length === 0 && (
// 用户刚点击"技能检索",还没收到任何步骤事件:用骨架行 + spinner 占位,
// 避免用户在等待后端 emit 时干等空白
<>
<li className="flex items-center gap-2 text-[11px] text-violet-700/80 dark:text-violet-300/70 italic">
<Loader2 className="size-3 animate-spin shrink-0" />
正在准备技能检索…
</li>
{[0, 1, 2].map((i) => (
<li key={`skel-${i}`} className="flex items-start gap-2 animate-pulse" style={{ animationDelay: `${i * 120}ms` }}>
<span className="shrink-0 mt-0.5 size-4 rounded-full bg-violet-100 dark:bg-violet-900/60" />
<div className="flex-1 min-w-0 space-y-1">
<div className="h-2.5 w-24 rounded bg-violet-100 dark:bg-violet-900/60" />
<div className="h-2 w-40 rounded bg-violet-50 dark:bg-violet-900/30" />
</div>
</li>
))}
</>
)}
{inProgress && steps.length > 0 && (
<li className="flex items-center gap-2 text-[11px] text-muted-foreground italic">
<Loader2 className="size-3 animate-spin" />
<Loader2 className="size-3 animate-spin shrink-0" />
更多步骤生成中…
</li>
)}
@@ -75,6 +75,7 @@ const INITIAL_STATE: AIWritingState = {
skillSearchSteps: [],
skillSelectStreamingText: '',
skillSelectThinkingText: '',
skillSearchPending: false,
streamingReviewItems: [],
revisionSummary: null,
pendingRevisionContext: null,
@@ -105,10 +106,13 @@ function reducer(prev: AIWritingState, action: Action): AIWritingState {
case 'intervention_submitted': {
const ns = action.nextStatus;
// 点击瞬间标记技能检索 pending(动机 = 用户的 action 类型),让 SkillStepsCard 占位卡立即挂载
const enablingSkillSearch = action.record.action === 'enable_skill_search';
return {
...prev,
currentPause: null,
status: ns,
skillSearchPending: enablingSkillSearch ? true : prev.skillSearchPending,
...(ns === 'researching' ? { researchProgress: '', skillSearchSteps: [], skillSelectStreamingText: '', skillSelectThinkingText: '' } : {}),
...(ns === 'writing_outline' ? { outlineStreamingText: '', outlineThinkingText: '' } : {}),
...(ns === 'writing_draft' ? { streamingDraftSections: [], streamingDraftTitle: '' } : {}),
@@ -341,7 +345,9 @@ function handleEvent(prev: AIWritingState, event: ProgressEvent): AIWritingState
const extra: Partial<AIWritingState> = {};
if (pp === 'material_confirm' && event.materials?.length) extra.materials = event.materials;
if (pp === 'outline_confirm' && event.outline) extra.outline = event.outline;
return { ...base, ...extra, status: pauseStatus, currentPause: event };
// 进入素材确认(material_confirm)= 技能检索(如果在进行)已经完成,清掉 pending 占位
const clearPending = pp === 'material_confirm' ? { skillSearchPending: false } : {};
return { ...base, ...extra, ...clearPending, status: pauseStatus, currentPause: event };
}
case 'done':
@@ -321,6 +321,9 @@ export interface AIWritingState {
// 技能选择 LLM 流式打字内容(正文 / 思考分开),select_skills 完成后清空
skillSelectStreamingText: string;
skillSelectThinkingText: string;
/** 技能检索是否正在进行:用户点击"技能检索"瞬间 true,进入 awaiting 时清掉。
* 用于在 LangGraph 还没推任何 skill_search_step 事件时给前端展示占位卡。 */
skillSearchPending: boolean;
// 流式审核(逐条到达)
streamingReviewItems: StreamingReviewItem[];
// 修改摘要