feat: 添加线索引擎、NLQ、场景检测、前端界面等核心功能模块

This commit is contained in:
freedakgmail
2026-06-16 08:15:15 +08:00
parent 7b1e2b10a8
commit 48340f6011
62 changed files with 6772 additions and 65 deletions
+51
View File
@@ -0,0 +1,51 @@
import { useEffect, useState } from "react";
import { api, type DashboardSummary } from "./api";
import { L, confidenceLabel, scenarioLabel, statusLabel } from "./labels";
export default function Dashboard() {
const [data, setData] = useState<DashboardSummary | null>(null);
const [err, setErr] = useState<string>("");
useEffect(() => {
api.summary().then(setData).catch((e) => setErr(String(e)));
}, []);
if (err) return <div className="error">{err}</div>;
if (!data) return <div className="status"></div>;
const wan = (data.total_amount_involved / 10000).toFixed(1);
return (
<div>
<div className="cards">
<div className="card"><div className="k">线</div><div className="v">{data.total}</div></div>
<div className="card"><div className="k"></div><div className="v" style={{ color: "var(--high)" }}>{data.by_confidence.high ?? 0}</div></div>
<div className="card"><div className="k">()</div><div className="v">{wan}</div></div>
<div className="card"><div className="k"></div><div className="v">{Object.keys(data.by_scenario).length}</div></div>
</div>
<div className="panel">
<h3></h3>
<div className="row">
{Object.entries(data.by_status).map(([k, v]) => (
<span key={k} className="tag">{L(statusLabel, k)}: {v}</span>
))}
</div>
</div>
<div className="panel">
<h3></h3>
<div className="row">
{Object.entries(data.by_scenario).map(([k, v]) => (
<span key={k} className="tag">{k} {L(scenarioLabel, k)}: {v}</span>
))}
</div>
</div>
<div className="panel">
<h3></h3>
<div className="row">
{Object.entries(data.by_confidence).map(([k, v]) => (
<span key={k} className="tag">{L(confidenceLabel, k)}: {v}</span>
))}
</div>
</div>
</div>
);
}