容错处理
This commit is contained in:
1 parent
0af8ca5f78
commit
836dd73446
6 files changed
+79
-17
No files matched your search
@@ -46,8 +46,14 @@ function MaterialCompleted({ record, expanded, onToggle }: { record: CompletedIn
|
||||
<CheckCircle2 className="size-3.5 text-green-500 shrink-0" />
|
||||
<FileText className="size-3.5 text-blue-500 shrink-0" />
|
||||
<span className="flex-1 font-medium">
|
||||
已确认{' '}
|
||||
<span className="text-muted-foreground font-normal">{count} 条素材</span>
|
||||
{count === 0 && record.action !== 're_search' ? (
|
||||
'已在无素材的情况下继续写作'
|
||||
) : (
|
||||
<>
|
||||
已确认{' '}
|
||||
<span className="text-muted-foreground font-normal">{count} 条素材</span>
|
||||
</>
|
||||
)}
|
||||
</span>
|
||||
{count > 0 && (
|
||||
expanded
|
||||
|
||||
@@ -118,6 +118,50 @@ function MaterialConfirmCard({ materials, onSubmit, disabled }: MaterialConfirmC
|
||||
|
||||
const hasExtra = extraKeywords.length > 0;
|
||||
|
||||
// 空数据态:未检索到任何素材,提示用户重新搜索或在无素材情况下继续
|
||||
if (materials.length === 0) {
|
||||
return (
|
||||
<div className="rounded-md border border-amber-200 bg-amber-50/50 dark:border-amber-900/40 dark:bg-amber-950/20 space-y-3 p-3">
|
||||
<div className="flex items-start gap-2">
|
||||
<ShieldAlert className="size-4 text-amber-500 shrink-0 mt-0.5" />
|
||||
<div>
|
||||
<p className="text-xs font-medium">未检索到任何素材</p>
|
||||
<p className="text-xs text-muted-foreground mt-0.5">
|
||||
素材收集专家本次没有检索到相关数据。你可以补充关键词重新搜索,或在无素材的情况下直接继续写作(文章将仅依据写作意图生成)。
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<MaterialsToolbar
|
||||
materials={materials}
|
||||
selectedIds={selectedIds}
|
||||
onSelectAll={() => setSelectedIds(new Set())}
|
||||
onDeselectAll={() => setSelectedIds(new Set())}
|
||||
extraKeywords={extraKeywords}
|
||||
onAddKeyword={(kw) => setExtraKeywords((prev) => [...prev, kw])}
|
||||
onRemoveKeyword={(kw) => setExtraKeywords((prev) => prev.filter((k) => k !== kw))}
|
||||
/>
|
||||
|
||||
<div className="flex gap-2 pt-1">
|
||||
<Button
|
||||
type="button" size="sm" className="flex-1 h-8 text-xs gap-1.5"
|
||||
onClick={handleReSearch} disabled={disabled || submitting}
|
||||
>
|
||||
{hasExtra
|
||||
? <><Search className="size-3.5" />追加搜索</>
|
||||
: <><RotateCcw className="size-3.5" />重新搜索</>}
|
||||
</Button>
|
||||
<Button
|
||||
type="button" variant="outline" size="sm" className="h-8 text-xs gap-1.5 shrink-0"
|
||||
onClick={handleConfirm} disabled={disabled || submitting}
|
||||
>
|
||||
<ArrowRight className="size-3.5" />无数据继续写作
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="rounded-md border bg-background space-y-3 p-3">
|
||||
<div className="flex items-start gap-2">
|
||||
|
||||
@@ -34,20 +34,22 @@ export function MaterialsToolbar({
|
||||
|
||||
return (
|
||||
<div className="space-y-2">
|
||||
{/* 全选/取消 */}
|
||||
<div className="flex items-center gap-2">
|
||||
<span className="text-xs text-muted-foreground">
|
||||
已选 {selectedIds.size} / {materials.length} 条素材
|
||||
</span>
|
||||
<div className="flex-1" />
|
||||
<button
|
||||
type="button"
|
||||
onClick={allSelected ? onDeselectAll : onSelectAll}
|
||||
className="text-xs text-primary hover:underline"
|
||||
>
|
||||
{allSelected ? '取消全选' : '全选'}
|
||||
</button>
|
||||
</div>
|
||||
{/* 全选/取消(无素材时隐藏) */}
|
||||
{materials.length > 0 && (
|
||||
<div className="flex items-center gap-2">
|
||||
<span className="text-xs text-muted-foreground">
|
||||
已选 {selectedIds.size} / {materials.length} 条素材
|
||||
</span>
|
||||
<div className="flex-1" />
|
||||
<button
|
||||
type="button"
|
||||
onClick={allSelected ? onDeselectAll : onSelectAll}
|
||||
className="text-xs text-primary hover:underline"
|
||||
>
|
||||
{allSelected ? '取消全选' : '全选'}
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* 补充关键词 */}
|
||||
<div className="space-y-1.5">
|
||||
|
||||
@@ -204,7 +204,7 @@ export function TextArtifactRenderer({ content, isStreaming }: TextArtifactRende
|
||||
</h3>
|
||||
),
|
||||
p: ({ children }) => (
|
||||
<p className="mb-4 leading-[1.8] text-[15px] text-foreground">
|
||||
<p className="mb-4 leading-[1.8] text-[15px] text-foreground indent-[2em]">
|
||||
{children}
|
||||
</p>
|
||||
),
|
||||
|
||||
@@ -579,6 +579,7 @@
|
||||
line-height: 1.8;
|
||||
font-size: 0.9375rem; /* 15px */
|
||||
color: var(--foreground);
|
||||
text-indent: 2em; /* 段落首行缩进 */
|
||||
}
|
||||
|
||||
.tiptap-writing-editor .ProseMirror h1 {
|
||||
@@ -658,6 +659,7 @@
|
||||
|
||||
.tiptap-writing-editor .ProseMirror li > p {
|
||||
margin-bottom: 0.25rem;
|
||||
text-indent: 0; /* 列表项内段落不缩进 */
|
||||
}
|
||||
|
||||
.tiptap-writing-editor .ProseMirror blockquote {
|
||||
@@ -716,6 +718,10 @@
|
||||
}
|
||||
|
||||
/* Placeholder */
|
||||
.tiptap-writing-editor .ProseMirror p.is-editor-empty:first-child {
|
||||
text-indent: 0; /* 占位文案不缩进 */
|
||||
}
|
||||
|
||||
.tiptap-writing-editor .ProseMirror p.is-editor-empty:first-child::before {
|
||||
content: attr(data-placeholder);
|
||||
color: var(--muted-foreground);
|
||||
|
||||
+4
@@ -140,6 +140,10 @@ async def researcher_node(state: AIWritingState, config: RunnableConfig) -> dict
|
||||
materials = sorted(raw_materials, key=lambda m: m.get("relevance_score", 0), reverse=True)[:_MAX_MATERIALS]
|
||||
summary = f"共搜索到{len(raw_materials)}条素材,精选{len(materials)}条"
|
||||
|
||||
# 空结果兜底:未检索到任何素材时给出明确文案,前端据此弹出「无数据继续」选项
|
||||
if not materials:
|
||||
summary = "未检索到相关素材,可重新搜索或在无素材的情况下继续写作"
|
||||
|
||||
pkg = MaterialPackage(keywords=keywords, materials=materials, summary=summary)
|
||||
|
||||
return {
|
||||
|
||||
Reference in new issue
Block a user