B6/B7: failed终态前端可见 + SSE事件链核实
B6 错误态: - 后端已加 TaskStatus.FAILED + 异常区分重试中/耗尽(014迁移ALTER status ENUM) - 前端 TaskStatus 类型加 failed - RecentTasksBar/history STATUS_LABEL 补 failed 标签 - history 页 HISTORY_STATUSES 纳入 failed(否则失败任务前端找不到) - FatalErrorBanner + useSse error 不再静默丢弃 B7: 核实 SSE(ticket换JWT) + 事件消费链无缺口,标绿 tsc EXIT=0
This commit is contained in:
30
frontend/src/components/tasks/FatalErrorBanner.tsx
Normal file
30
frontend/src/components/tasks/FatalErrorBanner.tsx
Normal file
@@ -0,0 +1,30 @@
|
||||
'use client';
|
||||
// FatalErrorBanner — 任务级致命错误提示(B6)。生成彻底失败时给用户明确反馈,
|
||||
// 不再让页面无限转圈。从 generationStore.fatalError 读。
|
||||
import { useGenerationStore } from '@/stores/generationStore';
|
||||
|
||||
export function FatalErrorBanner() {
|
||||
const fatalError = useGenerationStore((s) => s.fatalError);
|
||||
if (!fatalError) return null;
|
||||
|
||||
return (
|
||||
<div
|
||||
className="mb-4 bg-red-50 border border-status-error rounded-xl px-4 py-3"
|
||||
role="alert"
|
||||
aria-live="assertive"
|
||||
>
|
||||
<div className="flex items-start gap-2">
|
||||
<span aria-hidden="true" className="text-status-error">⚠️</span>
|
||||
<div className="flex-1 min-w-0">
|
||||
<p className="text-sm font-medium text-status-error">生成失败</p>
|
||||
<p className="text-xs text-text-secondary mt-0.5 break-words">
|
||||
{fatalError.message || '生成过程出错,请重试或联系管理员'}
|
||||
</p>
|
||||
<p className="text-xs text-text-tertiary mt-1">
|
||||
可在任务列表对该任务重新生成;多次失败请检查 key 配置或网络。
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -19,6 +19,7 @@ const STATUS_LABELS: Record<TaskStatus, { label: string; color: string }> = {
|
||||
approved: { label: '已通过', color: 'text-status-success' },
|
||||
rejected: { label: '已打回', color: 'text-status-error' },
|
||||
archived: { label: '已归档', color: 'text-text-tertiary' },
|
||||
failed: { label: '生成失败', color: 'text-status-error' },
|
||||
};
|
||||
|
||||
export function RecentTasksBar() {
|
||||
|
||||
Reference in New Issue
Block a user