This commit is contained in:
fengxiangdebaozi committed 2026-05-25 19:30:26 +08:00
1 parent 2f7f07467e
commit ca1d7e77ba
18 files changed
+53 -76

No files matched your search

@@ -1,7 +1,5 @@
import { FileText, PenLine } from 'lucide-react';
import { desensitize } from '@/lib/desensitize';
import { useCanvasGraphContext } from '../../contexts/CanvasGraphContext';
import { getCurrentArtifactContent, isCodeArtifact } from '../../utils/artifact';
import { TextArtifactRenderer } from '../artifact/TextArtifactRenderer';
@@ -47,7 +45,7 @@ export function AIWritingDraftPanel() {
<div className="h-10 border-b flex items-center gap-2 px-4 shrink-0 bg-muted/20">
<FileText className="w-3.5 h-3.5 text-muted-foreground shrink-0" />
<span className="text-sm font-medium truncate flex-1">
{content?.title ? desensitize(content.title) : '草稿预览'}
{content?.title ?? '草稿预览'}
</span>
</div>
@@ -1,7 +1,5 @@
import { CheckCircle2, ChevronRight, FileText, Search, PenLine, ClipboardEdit, Star } from 'lucide-react';
import { desensitize } from '@/lib/desensitize';
import type { AIWritingSessionSummary, CompletedInterventionRecord } from '../../api/ai-writing-sessions';
import { AIWritingTimeline } from './AIWritingTimeline';
@@ -81,10 +79,10 @@ export function AIWritingHistoryView({ session }: AIWritingHistoryViewProps) {
{/* 元信息 */}
<div className="px-4 pt-3">
<div className="rounded-lg border bg-muted/30 px-3 py-2.5 space-y-1">
<p className="text-xs font-semibold truncate">{desensitize(session.draft_title ?? session.title ?? "")}</p>
<p className="text-xs font-semibold truncate">{session.draft_title ?? session.title}</p>
{session.user_intent && (
<p className="text-[11px] text-muted-foreground leading-relaxed line-clamp-2">
{desensitize(session.user_intent)}
{session.user_intent}
</p>
)}
{createdAt && (
@@ -4,7 +4,6 @@ import { ChevronsDown, Play, Plus, RotateCcw, Settings2, Square, Trash2 } from '
import { toast } from 'sonner';
import { Button } from '@/components/ui/button';
import { desensitize } from '@/lib/desensitize';
import { cn } from '@/lib/utils';
import {
Dialog,
@@ -252,7 +251,7 @@ export function AIWritingPanel({
<div className="flex flex-col h-full overflow-hidden bg-background">
<div className="flex items-center justify-between px-4 py-2.5 border-b shrink-0">
<span className="text-sm font-semibold truncate flex-1 min-w-0 mr-2">
{desensitize(historySession.draft_title ?? historySession.title)}
{historySession.draft_title ?? historySession.title}
</span>
<div className="flex items-center gap-1.5 shrink-0">
<Button
@@ -502,7 +501,7 @@ export function AIWritingPanel({
<span className="inline-block size-1.5 rounded-full bg-blue-500 animate-pulse" />
)}
{state.status === 'researching' && state.researchProgress
? desensitize(state.researchProgress)
? state.researchProgress
: STATUS_LABEL[state.status] ?? state.status}
</>
)}
@@ -518,16 +517,16 @@ export function AIWritingPanel({
</DialogHeader>
<div className="space-y-3 py-1 text-sm">
<ReqRow label="写作意图">
<p className="text-muted-foreground whitespace-pre-wrap leading-relaxed">{desensitize(state.request.userIntent ?? "")}</p>
<p className="text-muted-foreground whitespace-pre-wrap leading-relaxed">{state.request.userIntent}</p>
</ReqRow>
<ReqRow label="文章类型">
<span className="text-muted-foreground">
{desensitize(articleTypes.find((t) => t.key === state.request!.articleType)?.label ?? state.request.articleType ?? "")}
{articleTypes.find((t) => t.key === state.request!.articleType)?.label ?? state.request.articleType}
</span>
</ReqRow>
{!hideAdvancedFields && (
<ReqRow label="目标读者">
<span className="text-muted-foreground">{desensitize(state.request.targetAudience ?? "")}</span>
<span className="text-muted-foreground">{state.request.targetAudience}</span>
</ReqRow>
)}
<ReqRow label="目标字数">
@@ -547,7 +546,7 @@ export function AIWritingPanel({
)}
{state.request.modelName && (
<ReqRow label="写作模型">
<span className="text-muted-foreground">{desensitize(state.request.modelName)}</span>
<span className="text-muted-foreground">{state.request.modelName}</span>
</ReqRow>
)}
</div>
@@ -4,7 +4,6 @@ import {
ExternalLink, ListTree, FileText,
} from 'lucide-react';
import { cn } from '@/lib/utils';
import { desensitize } from '@/lib/desensitize';
import { buildIntranetSourceUrl } from '@/core/config';
import type { AIMaterial, CompletedIntervention } from '../../types/ai-writing';
import { OutlineCard } from './OutlineCard';
@@ -105,7 +104,7 @@ function CompletedMaterialItem({ material }: { material: AIMaterial }) {
)}
>
<div className="flex items-start gap-1.5">
<span className="flex-1 font-medium leading-snug line-clamp-2">{desensitize(material.title ?? "")}</span>
<span className="flex-1 font-medium leading-snug line-clamp-2">{material.title}</span>
{hasDetail && (
<ChevronRight
className={cn(
@@ -116,8 +115,8 @@ function CompletedMaterialItem({ material }: { material: AIMaterial }) {
)}
</div>
<div className="flex items-center gap-2 text-muted-foreground">
<span className="truncate max-w-[100px]">{desensitize(material.source ?? "")}</span>
{material.publishedAt && <><span className="text-muted-foreground/40">·</span><span>{desensitize(material.publishedAt)}</span></>}
<span className="truncate max-w-[100px]">{material.source}</span>
{material.publishedAt && <><span className="text-muted-foreground/40">·</span><span>{material.publishedAt}</span></>}
<div className="flex flex-1 items-center gap-1 min-w-0">
<div className="flex-1 h-1 rounded-full bg-muted overflow-hidden min-w-[40px]">
<div className={cn('h-full rounded-full', barColor)} style={{ width: `${pct}%` }} />
@@ -132,7 +131,7 @@ function CompletedMaterialItem({ material }: { material: AIMaterial }) {
<div className="px-2.5 pb-2 pt-1.5 space-y-1.5 border-t border-border/40">
{material.content && (
<p className="text-muted-foreground leading-relaxed line-clamp-6">
{desensitize(material.content.slice(0, 300))}
{material.content.slice(0, 300)}
{material.content.length > 300 && '…'}
</p>
)}
@@ -170,7 +169,7 @@ function OutlineCompleted({ record, expanded, onToggle }: { record: CompletedInt
已确认大纲
{record.outline?.title && (
<span className="ml-1 text-muted-foreground font-normal">
《{desensitize(record.outline.title)}》
《{record.outline.title}》
</span>
)}
<span className="ml-1 text-muted-foreground font-normal">共 {sectionCount} 章节</span>
@@ -197,7 +196,7 @@ function OutlineCompleted({ record, expanded, onToggle }: { record: CompletedInt
// ── 草稿确认历史卡 ────────────────────────────────────────────────────────────
function DraftCompleted({ record, expanded, onToggle }: { record: CompletedIntervention; expanded: boolean; onToggle: () => void }) {
const title = record.draftTitle ? `《${desensitize(record.draftTitle)}》` : '草稿';
const title = record.draftTitle ? `《${record.draftTitle}》` : '草稿';
const wordCount = record.draftWordCount ?? 0;
const hasReview = !!record.reviewResult;
@@ -1,7 +1,6 @@
import { useEffect, useRef, useState } from 'react';
import { Brain, ChevronRight } from 'lucide-react';
import { cn } from '@/lib/utils';
import { desensitize } from '@/lib/desensitize';
import type { StreamingDraftSection } from '../../types/ai-writing';
import { CollapseTransition } from './CollapseTransition';
@@ -50,7 +49,7 @@ function SectionThinking({ thinkingText, isDone }: { thinkingText: string; isDon
ref={preRef}
className="text-[10px] font-mono leading-relaxed px-2.5 py-2 text-amber-700/70 dark:text-amber-300/60 whitespace-pre-wrap max-h-32 overflow-y-auto italic"
>
{desensitize(thinkingText)}
{thinkingText}
{!isDone && (
<span className="inline-block w-0.5 h-3 bg-amber-400 ml-0.5 align-text-bottom animate-[blink_1s_step-end_infinite]" />
)}
@@ -72,7 +71,7 @@ function SectionBody({ text, showCursor }: { text: string; showCursor: boolean }
if (heading) {
return (
<p key={i} className="text-xs font-semibold text-foreground mt-2 mb-1">
{desensitize(line.slice(heading[0].length))}
{line.slice(heading[0].length)}
</p>
);
}
@@ -82,7 +81,7 @@ function SectionBody({ text, showCursor }: { text: string; showCursor: boolean }
key={i}
className="text-xs leading-relaxed text-foreground/90 whitespace-pre-wrap m-0 mb-1"
>
{desensitize(line)}
{line}
</p>
);
})}
@@ -109,7 +108,7 @@ export function DraftStreamingView({ title, sections }: DraftStreamingViewProps)
<div className="px-4 pb-4">
<div className="rounded-xl border bg-card shadow-sm p-4 prose prose-sm dark:prose-invert max-w-none">
{title && (
<h1 className="text-base font-bold text-center mb-4 text-foreground">{desensitize(title)}</h1>
<h1 className="text-base font-bold text-center mb-4 text-foreground">{title}</h1>
)}
{sections.map((sec) => (
@@ -118,7 +117,7 @@ export function DraftStreamingView({ title, sections }: DraftStreamingViewProps)
'text-sm font-semibold mb-1.5',
sec.isDone ? 'text-foreground' : 'text-purple-500',
)}>
{desensitize(sec.sectionTitle ?? "")}
{sec.sectionTitle}
</h2>
{/* 该章节的思考过程(可折叠) */}
@@ -1,7 +1,5 @@
import { Sparkles } from 'lucide-react';
import { desensitize } from '@/lib/desensitize';
import type { ParsedIntent } from '../../types/ai-writing';
import type { ArticleType } from '../../api/ai-writing-article-types';
@@ -34,13 +32,13 @@ export function IntentResultCard({
</span>
</div>
<div className="px-3 py-2.5 space-y-1.5 text-xs">
<Row label="文章类型" value={desensitize(typeLabel ?? "")} />
<Row label="文章类型" value={typeLabel} />
{!hideTargetAudience && (
<Row label="目标读者" value={desensitize(intent.targetAudience ?? "")} />
<Row label="目标读者" value={intent.targetAudience} />
)}
<Row label="字数目标" value={`${intent.wordCountTarget} 字`} />
{intent.refinedIntent && (
<Row label="精炼意图" value={desensitize(intent.refinedIntent)} multiline />
<Row label="精炼意图" value={intent.refinedIntent} multiline />
)}
</div>
</div>
@@ -1,8 +1,6 @@
import { useEffect, useRef, useState } from 'react';
import { Sparkles, ChevronDown, ChevronRight, Brain } from 'lucide-react';
import { desensitize } from '@/lib/desensitize';
interface IntentStreamingViewProps {
text: string;
thinkingText?: string;
@@ -56,7 +54,7 @@ export function IntentStreamingView({ text, thinkingText }: IntentStreamingViewP
ref={thinkRef}
className="text-[11px] font-mono leading-relaxed p-3 text-amber-700/70 dark:text-amber-300/60 whitespace-pre-wrap max-h-40 overflow-y-auto italic"
>
{desensitize(thinkingText)}
{thinkingText}
{!text && (
<span className="inline-block w-0.5 h-3.5 bg-amber-400 ml-0.5 align-text-bottom animate-[blink_1s_step-end_infinite]" />
)}
@@ -86,7 +84,7 @@ export function IntentStreamingView({ text, thinkingText }: IntentStreamingViewP
ref={preRef}
className="text-[11px] font-mono leading-relaxed p-3 text-muted-foreground whitespace-pre-wrap max-h-52 overflow-y-auto"
>
{desensitize(text)}
{text}
<span className="inline-block w-0.5 h-3.5 bg-blue-400 ml-0.5 align-text-bottom animate-[blink_1s_step-end_infinite]" />
</pre>
</div>
@@ -6,7 +6,6 @@ import {
} from 'lucide-react';
import { Button } from '@/components/ui/button';
import { cn } from '@/lib/utils';
import { desensitize } from '@/lib/desensitize';
import type {
AIMaterial, AIOutline, ReviewResult, ReviewIssue,
ProgressEvent, UserInterventionPayload,
@@ -381,7 +380,7 @@ function DraftConfirmCard({ draftTitle, revisionCount, reviewResult, onSubmit, d
<div>
<p className="text-xs font-medium">草稿已完成,请确认后继续</p>
<p className="text-xs text-muted-foreground mt-0.5">
{draftTitle ? `《${desensitize(draftTitle)}》` : '草稿'}
{draftTitle ? `《${draftTitle}》` : '草稿'}
{revisionCount > 0 ? `(第 ${revisionCount} 次修改稿)` : '(初稿)'}
· 右侧可预览完整内容
</p>
@@ -617,8 +616,8 @@ function SectionHelpCard({ blockedSections, onSubmit, disabled }: SectionHelpCar
{blockedSections.map((b) => (
<div key={b.sectionTitle} className="rounded-md border bg-background p-2.5 space-y-2">
<div>
<p className="text-xs font-medium">{desensitize(b.sectionTitle ?? "")}</p>
<p className="text-[11px] text-muted-foreground mt-0.5">{desensitize(b.reason ?? "")}</p>
<p className="text-xs font-medium">{b.sectionTitle}</p>
<p className="text-[11px] text-muted-foreground mt-0.5">{b.reason}</p>
</div>
<div className="flex gap-1">
{DECISION_OPTIONS.map((opt) => {
@@ -1,5 +1,4 @@
import { cn } from '@/lib/utils';
import { desensitize } from '@/lib/desensitize';
import type { ReviewIssue } from '../../types/ai-writing';
interface IssueListProps {
@@ -94,14 +93,14 @@ function IssueGroup({ label, labelClass, items, selectable, selectedIndices, onT
<span className={cn('rounded px-1.5 py-0.5 text-[10px] font-medium', CATEGORY_COLOR[issue.category] ?? 'bg-muted text-muted-foreground')}>
{CATEGORY_LABEL[issue.category] ?? issue.category}
</span>
<span className="text-muted-foreground truncate">{desensitize(issue.location ?? "")}</span>
<span className="text-muted-foreground truncate">{issue.location}</span>
</div>
<p className={cn('text-foreground leading-snug', selectable ? 'pl-5' : '')}>
{desensitize(issue.issue ?? "")}
{issue.issue}
</p>
<p className={cn('text-muted-foreground leading-snug', selectable ? 'pl-5' : '')}>
<span className="text-primary mr-1">→</span>
{desensitize(issue.suggestion ?? "")}
{issue.suggestion}
</p>
</div>
);
@@ -1,7 +1,6 @@
import { useState } from 'react';
import { ChevronRight, ExternalLink } from 'lucide-react';
import { cn } from '@/lib/utils';
import { desensitize } from '@/lib/desensitize';
import { buildIntranetSourceUrl } from '@/core/config';
import type { AIMaterial } from '../../types/ai-writing';
import { CollapseTransition } from './CollapseTransition';
@@ -52,7 +51,7 @@ export function MaterialItem({ material, checked, onToggle }: MaterialItemProps)
className="flex flex-1 items-start gap-1.5 text-left"
>
<span className={cn('flex-1 font-medium leading-snug line-clamp-2', !checked && 'text-muted-foreground')}>
{desensitize(material.title ?? "")}
{material.title}
</span>
<ChevronRight
className={cn(
@@ -65,11 +64,11 @@ export function MaterialItem({ material, checked, onToggle }: MaterialItemProps)
{/* 元信息行 */}
<div className="flex items-center gap-2 px-2.5 pb-2 pl-8">
<span className="text-muted-foreground truncate max-w-[120px]">{desensitize(material.source ?? "")}</span>
<span className="text-muted-foreground truncate max-w-[120px]">{material.source}</span>
{material.publishedAt && (
<>
<span className="text-muted-foreground/40">·</span>
<span className="text-muted-foreground shrink-0">{desensitize(material.publishedAt)}</span>
<span className="text-muted-foreground shrink-0">{material.publishedAt}</span>
</>
)}
{/* 相关度色条 */}
@@ -91,7 +90,7 @@ export function MaterialItem({ material, checked, onToggle }: MaterialItemProps)
<CollapseTransition open={expanded}>
<div className="px-2.5 pb-2.5 pl-8 space-y-1.5 border-t">
<p className="text-muted-foreground leading-relaxed pt-2 line-clamp-6">
{desensitize(material.content.slice(0, 300))}
{material.content.slice(0, 300)}
{material.content.length > 300 && '…'}
</p>
{material.recUuid && (
@@ -1,7 +1,6 @@
import { useState } from 'react';
import { ListTree, Plus } from 'lucide-react';
import { Button } from '@/components/ui/button';
import { desensitize } from '@/lib/desensitize';
import type { AIOutline, OutlineSection as OutlineSectionType } from '../../types/ai-writing';
import { OutlineSection } from './OutlineSection';
import { CollapseTransition } from './CollapseTransition';
@@ -93,7 +92,7 @@ export function OutlineCard({ outline, onChange, readOnly = false }: OutlineCard
className={editable ? 'flex-1 font-semibold cursor-text hover:text-primary' : 'flex-1 font-semibold'}
onClick={() => editable && setEditingTitle(true)}
>
{outline.title ? desensitize(outline.title) : <span className="text-muted-foreground italic font-normal">(未设置标题)</span>}
{outline.title || <span className="text-muted-foreground italic font-normal">(未设置标题)</span>}
</span>
)}
</div>
@@ -1,6 +1,5 @@
import { useState } from 'react';
import { ChevronRight, Plus, X, GripVertical } from 'lucide-react';
import { desensitize } from '@/lib/desensitize';
import { cn } from '@/lib/utils';
import type { OutlineSection as OutlineSectionType } from '../../types/ai-writing';
import { CollapseTransition } from './CollapseTransition';
@@ -101,7 +100,7 @@ export function OutlineSection({
className={cn('flex-1 font-medium', !readOnly && 'cursor-text hover:text-primary')}
onClick={() => !readOnly && setEditingTitle(true)}
>
{section.sectionTitle ? desensitize(section.sectionTitle) : <span className="text-muted-foreground italic">(未命名)</span>}
{section.sectionTitle || <span className="text-muted-foreground italic">(未命名)</span>}
</span>
)}
@@ -120,7 +119,7 @@ export function OutlineSection({
<div key={i} className="flex items-center gap-1.5 pt-1.5">
<span className="text-muted-foreground/40 shrink-0">•</span>
{readOnly ? (
<span className="flex-1 text-muted-foreground">{desensitize(kp)}</span>
<span className="flex-1 text-muted-foreground">{kp}</span>
) : (
<input
value={kp}
@@ -1,8 +1,6 @@
import { useEffect, useRef, useState } from 'react';
import { FileText, ChevronDown, ChevronRight, Brain } from 'lucide-react';
import { desensitize } from '@/lib/desensitize';
interface OutlineStreamingViewProps {
text: string;
thinkingText?: string;
@@ -52,7 +50,7 @@ export function OutlineStreamingView({ text, thinkingText }: OutlineStreamingVie
ref={thinkRef}
className="text-[11px] font-mono leading-relaxed p-3 text-amber-700/70 dark:text-amber-300/60 whitespace-pre-wrap max-h-40 overflow-y-auto italic"
>
{desensitize(thinkingText)}
{thinkingText}
{/* 思考仍在进行时显示光标 */}
{!text && (
<span className="inline-block w-0.5 h-3.5 bg-amber-400 ml-0.5 align-text-bottom animate-[blink_1s_step-end_infinite]" />
@@ -84,7 +82,7 @@ export function OutlineStreamingView({ text, thinkingText }: OutlineStreamingVie
ref={preRef}
className="text-[11px] font-mono leading-relaxed p-3 text-muted-foreground whitespace-pre-wrap max-h-52 overflow-y-auto"
>
{desensitize(text)}
{text}
<span className="inline-block w-0.5 h-3.5 bg-purple-400 ml-0.5 align-text-bottom animate-[blink_1s_step-end_infinite]" />
</pre>
</div>
@@ -1,7 +1,6 @@
import { useEffect, useRef } from 'react';
import { CheckCircle2, Loader2 } from 'lucide-react';
import { cn } from '@/lib/utils';
import { desensitize } from '@/lib/desensitize';
import type { StreamingReviewItem, ReviewIssue } from '../../types/ai-writing';
const CATEGORY_META: Record<
@@ -42,9 +41,9 @@ function IssueRow({ issue }: { issue: ReviewIssue }) {
)}>
{issue.severity === 'major' ? '严重' : '轻微'}
</span>
<span className="text-muted-foreground">{desensitize(issue.issue ?? "")}</span>
<span className="text-muted-foreground">{issue.issue}</span>
{issue.suggestion && (
<span className="text-orange-600 dark:text-orange-400"> → {desensitize(issue.suggestion)}</span>
<span className="text-orange-600 dark:text-orange-400"> → {issue.suggestion}</span>
)}
</div>
);
@@ -74,10 +73,10 @@ function StreamingText({ item }: { item: StreamingReviewItem }) {
>
{item.thinkingText && (
<span className="italic text-amber-600/70 dark:text-amber-400/60">
{desensitize(item.thinkingText)}
{item.thinkingText}
</span>
)}
{desensitize(item.streamingText ?? "")}
{item.streamingText}
<span className="inline-block w-0.5 h-3 bg-orange-400 ml-0.5 align-text-bottom animate-[blink_1s_step-end_infinite]" />
</pre>
);
@@ -1,6 +1,5 @@
import { CheckCircle2, XCircle } from 'lucide-react';
import { cn } from '@/lib/utils';
import { desensitize } from '@/lib/desensitize';
import type { RevisionSummary } from '../../types/ai-writing';
interface RevisionSummaryCardProps {
@@ -50,7 +49,7 @@ export function RevisionSummaryCard({ summary }: RevisionSummaryCardProps) {
)}>
{CATEGORY_LABEL[iss.category] ?? iss.category}
</span>
<span>{desensitize(iss.issue ?? "")}</span>
<span>{iss.issue}</span>
</div>
))}
</div>
@@ -65,7 +64,7 @@ export function RevisionSummaryCard({ summary }: RevisionSummaryCardProps) {
</p>
{skippedIssues.map((iss, i) => (
<div key={i} className="flex items-start gap-1.5 pl-5 text-muted-foreground/60 leading-snug line-through">
<span>{desensitize(iss.issue ?? "")}</span>
<span>{iss.issue}</span>
</div>
))}
</div>
@@ -1,6 +1,5 @@
import { AlertCircle, AlertTriangle, CheckCircle2, Circle, Loader2, PauseCircle } from 'lucide-react';
import { cn } from '@/lib/utils';
import { desensitize } from '@/lib/desensitize';
import type { ProgressEvent } from '../../types/ai-writing';
type StepStatus = 'done' | 'running' | 'paused' | 'waiting' | 'error' | 'warning';
@@ -50,7 +49,7 @@ export function TimelineStep({ event, isLast, children }: TimelineStepProps) {
AGENT_COLOR[event.agentName] ?? 'text-muted-foreground',
)}
>
{desensitize(event.agentName)}
{event.agentName}
</span>
)}
@@ -71,11 +70,11 @@ export function TimelineStep({ event, isLast, children }: TimelineStepProps) {
: 'text-amber-600 dark:text-amber-500',
)}
>
{desensitize(event.title || event.message || (isError ? '出错了' : '提示'))}
{event.title || event.message || (isError ? '出错了' : '提示')}
</p>
{event.detail && (
<p className="mt-0.5 text-[11px] leading-relaxed text-muted-foreground break-words">
{desensitize(event.detail)}
{event.detail}
</p>
)}
{/* 接口解析失败时的原始错误响应体,默认折叠,点击展开 */}
@@ -85,13 +84,13 @@ export function TimelineStep({ event, isLast, children }: TimelineStepProps) {
错误返回结果(点击展开)
</summary>
<pre className="mt-1 max-h-60 overflow-auto whitespace-pre-wrap break-all rounded bg-muted/60 p-2 text-[10px] leading-relaxed text-muted-foreground">
{desensitize(event.raw)}
{event.raw}
</pre>
</details>
)}
</div>
) : (
<span className="ml-1.5 text-xs text-muted-foreground">{desensitize(event.message ?? "")}</span>
<span className="ml-1.5 text-xs text-muted-foreground">{event.message}</span>
)}
{children}
@@ -1,5 +1,4 @@
import { cn } from '@/lib/utils';
import { desensitize } from '@/lib/desensitize';
import type { WritingStatus } from '../../types/ai-writing';
interface WritingSkeletonCardProps {
@@ -38,7 +37,7 @@ function MaterialsSkeleton({ researchProgress }: { researchProgress?: string })
{/* 标题行:展示素材收集专家的实时进度 */}
<div className="flex items-center gap-2 text-xs text-blue-500 font-medium">
<ThinkingDots color="bg-blue-400" />
<span>{researchProgress ? desensitize(researchProgress) : '素材收集专家搜索中…'}</span>
<span>{researchProgress || '素材收集专家搜索中…'}</span>
</div>
{/* 关键词标签占位 */}
@@ -4,7 +4,6 @@ import ReactMarkdown from "react-markdown";
import remarkGfm from "remark-gfm";
import { Button } from "@/components/ui/button";
import { desensitize } from "@/lib/desensitize";
import type { CanvasArtifactText } from "../../types/artifact";
import { TiptapEditor } from "../../editor/TiptapEditor";
import { useWritingEditor } from "../../hooks/useWritingEditor";
@@ -248,7 +247,7 @@ export function TextArtifactRenderer({ content, isStreaming }: TextArtifactRende
},
}}
>
{desensitize(content.fullMarkdown)}
{content.fullMarkdown}
</ReactMarkdown>
<span className="inline-block w-0.5 h-4 bg-primary animate-pulse align-middle ml-0.5" />
</div>