Add analysis feature
This commit is contained in:
@@ -425,6 +425,35 @@ export function HistoryPage() {
|
||||
}
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (
|
||||
!dialogOpen ||
|
||||
!detail ||
|
||||
!["pending", "processing"].includes(detail.analysis.status)
|
||||
) {
|
||||
return;
|
||||
}
|
||||
let stopped = false;
|
||||
let loadingLatest = false;
|
||||
const timer = window.setInterval(() => {
|
||||
if (loadingLatest) return;
|
||||
loadingLatest = true;
|
||||
void conversationsApi
|
||||
.get(detail.id)
|
||||
.then((latest) => {
|
||||
if (!stopped) setDetail(latest);
|
||||
})
|
||||
.catch(() => undefined)
|
||||
.finally(() => {
|
||||
loadingLatest = false;
|
||||
});
|
||||
}, 2000);
|
||||
return () => {
|
||||
stopped = true;
|
||||
window.clearInterval(timer);
|
||||
};
|
||||
}, [detail, dialogOpen]);
|
||||
|
||||
const remove = useCallback(
|
||||
async (conversation: Conversation) => {
|
||||
const label = conversation.assistantName || "调试会话";
|
||||
@@ -729,7 +758,9 @@ export function HistoryPage() {
|
||||
{detail && detailTab === "session" && (
|
||||
<SessionInfoPanel detail={detail} />
|
||||
)}
|
||||
{detail && detailTab === "analysis" && <AnalysisPanel />}
|
||||
{detail && detailTab === "analysis" && (
|
||||
<AnalysisPanel analysis={detail.analysis} />
|
||||
)}
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
@@ -879,7 +910,79 @@ function SessionInfoPanel({ detail }: { detail: ConversationDetail }) {
|
||||
);
|
||||
}
|
||||
|
||||
function AnalysisPanel() {
|
||||
function analysisValue(value: unknown): string {
|
||||
if (value === null || value === undefined || value === "") return "未提取到";
|
||||
if (typeof value === "boolean") return value ? "是" : "否";
|
||||
if (typeof value === "object") return JSON.stringify(value);
|
||||
return String(value);
|
||||
}
|
||||
|
||||
function AnalysisPanel({
|
||||
analysis,
|
||||
}: {
|
||||
analysis: ConversationDetail["analysis"];
|
||||
}) {
|
||||
if (analysis.status === "pending" || analysis.status === "processing") {
|
||||
return (
|
||||
<div className="flex min-h-48 items-center justify-center gap-2 text-sm text-muted-foreground">
|
||||
<Loader2 size={16} className="animate-spin" />
|
||||
正在分析通话内容
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
if (analysis.status === "failed") {
|
||||
return (
|
||||
<div className="rounded-2xl border border-destructive/25 bg-destructive/5 px-4 py-4">
|
||||
<div className="text-sm font-medium text-destructive">分析失败</div>
|
||||
<p className="mt-1.5 break-words text-xs leading-5 text-muted-foreground">
|
||||
{analysis.error || "分析服务没有返回有效结果。"}
|
||||
</p>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
if (analysis.status === "completed") {
|
||||
return (
|
||||
<div className="space-y-4">
|
||||
<div>
|
||||
<div className="caption-label text-muted-soft">关键信息</div>
|
||||
{analysis.completedAt && (
|
||||
<div className="mt-1 text-xs text-muted-foreground">
|
||||
完成于 {formatDate(analysis.completedAt)}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<div className="divide-y divide-hairline overflow-hidden rounded-2xl border border-hairline bg-background">
|
||||
{analysis.fields.map((field) => (
|
||||
<div
|
||||
key={field.name}
|
||||
className="grid grid-cols-[minmax(0,0.9fr)_minmax(0,1.1fr)] gap-4 px-4 py-3"
|
||||
>
|
||||
<div className="min-w-0">
|
||||
<div className="break-all text-sm font-medium text-foreground">
|
||||
{field.name}
|
||||
</div>
|
||||
<div className="mt-0.5 text-[11px] text-muted-soft">
|
||||
{field.type}
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className={cn(
|
||||
"break-words text-sm text-foreground",
|
||||
(field.value === null || field.value === undefined) &&
|
||||
"text-muted-soft",
|
||||
)}
|
||||
>
|
||||
{analysisValue(field.value)}
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="flex min-h-48 flex-col items-center justify-center rounded-2xl border border-dashed border-hairline-strong bg-canvas-soft px-5 py-10 text-center">
|
||||
<div className="flex h-10 w-10 items-center justify-center rounded-full bg-surface-strong text-foreground">
|
||||
@@ -889,7 +992,7 @@ function AnalysisPanel() {
|
||||
暂无分析结果
|
||||
</div>
|
||||
<p className="mt-1.5 max-w-xs text-xs leading-5 text-muted-foreground">
|
||||
通话后分析接入后,将在这里展示从对话中提取的关键信息字段。
|
||||
该会话未开启通话后分析,或没有可分析的对话内容。
|
||||
</p>
|
||||
</div>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user