Show synastry evidence report card

This commit is contained in:
732642856
2026-07-17 18:07:11 +08:00
parent 618a01f65e
commit 4fc98f4e92
3 changed files with 49 additions and 1 deletions
+5
View File
@@ -392,6 +392,11 @@ button:disabled { cursor: default; opacity: .45; }
.chart-library-item small, .chart-library-item > span, .empty-library-copy { color: var(--color-ink-secondary); font-size: var(--type-caption); }
.chart-library-actions { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: var(--space-2); }
.chart-library-form { padding-top: var(--space-4); border-top: 1px solid var(--color-border); }
.synastry-report-card { display: grid; gap: var(--space-3); padding: var(--space-4); border: 1px solid var(--color-border); border-radius: var(--radius-lg); background: var(--color-surface-subtle); }
.synastry-report-card span, .synastry-report-card small, .synastry-report-card li { color: var(--color-ink-secondary); font-size: var(--type-caption); }
.synastry-report-card strong, .synastry-report-card p { color: var(--color-ink); }
.synastry-report-card strong { display: block; margin-top: 4px; font-size: var(--type-body); font-weight: 500; }
.synastry-report-card p, .synastry-report-card ul { margin: 0; }
input, select { width: 100%; min-height: 44px; padding: 0 12px; border: 1px solid var(--color-border-strong); color: var(--color-ink); border-color: var(--color-border-strong); border-radius: var(--radius-md); background: var(--color-canvas); font-size: 14px; }
input:disabled, select:disabled { color: var(--color-ink-tertiary); background: var(--color-canvas-muted); }
+42 -1
View File
@@ -45,6 +45,17 @@ type ChartLibraryApiRecord = {
profile: Profile;
updated_at?: string;
};
type SynastryReportCard = {
partnerName: string;
score?: number;
maxScore?: number;
assessment?: string;
headline?: string;
scoreBand?: string;
strengths?: string[];
risks?: string[];
nextEvidence?: string[];
};
type ChatSession = { id: string; title: string; theme: Theme; modelId: string; messages: Message[]; updatedAt: number };
type RequestError = { sessionId: string; message: string };
type StreamingReply = { sessionId: string; text: string };
@@ -519,6 +530,7 @@ export default function Home() {
const [chartLibrary, setChartLibrary] = useState<ChartLibraryRecord[]>([]);
const [chartLibraryOpen, setChartLibraryOpen] = useState(false);
const [otherProfileDraft, setOtherProfileDraft] = useState<Profile>(emptyProfile);
const [synastryReportCard, setSynastryReportCard] = useState<SynastryReportCard | null>(null);
const [profileOpen, setProfileOpen] = useState(false);
const [mobileSidebarOpen, setMobileSidebarOpen] = useState(false);
const [profileNotice, setProfileNotice] = useState("");
@@ -1256,12 +1268,23 @@ export default function Home() {
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ selfProfile: profile, partnerProfile: record.profile }),
});
const payload = await response.json().catch(() => null) as { status?: string; evidenceLayers?: string[]; synastry?: { total_score?: number; max_score?: number; assessment?: string }; relationshipReport?: { headline?: string } } | null;
const payload = await response.json().catch(() => null) as { status?: string; evidenceLayers?: string[]; synastry?: { total_score?: number; max_score?: number; assessment?: string }; relationshipReport?: { headline?: string; scoreBand?: string; strengths?: string[]; risks?: string[]; nextEvidence?: string[] } } | null;
if (response.ok && payload?.status === "ok") {
const score = payload.synastry?.total_score;
const max = payload.synastry?.max_score;
const assessment = payload.synastry?.assessment;
const layers = (payload.evidenceLayers || []).join(" / ") || "Ashtakoot / Moon / D9";
setSynastryReportCard({
partnerName: record.profile.name || "对方",
score,
maxScore: max,
assessment,
headline: payload.relationshipReport?.headline,
scoreBand: payload.relationshipReport?.scoreBand,
strengths: payload.relationshipReport?.strengths,
risks: payload.relationshipReport?.risks,
nextEvidence: payload.relationshipReport?.nextEvidence,
});
chooseSuggestedQuestion([
baseQuestion,
"",
@@ -1983,6 +2006,24 @@ export default function Home() {
</article>
))}
</div>
{synastryReportCard && (
<article className="synastry-report-card" aria-label="合盘结果摘要">
<div>
<span></span>
<strong>{synastryReportCard.partnerName}</strong>
<small>Ashtakoot {synastryReportCard.score ?? "?"}/{synastryReportCard.maxScore ?? "?"} · {synastryReportCard.assessment || synastryReportCard.scoreBand || "待解释"}</small>
</div>
{synastryReportCard.headline && <p>{synastryReportCard.headline}</p>}
<details>
<summary></summary>
<ul>
{(synastryReportCard.strengths || []).map((item) => <li key={item}>{item}</li>)}
{(synastryReportCard.risks || []).map((item) => <li key={item}>{item}</li>)}
</ul>
<small>{(synastryReportCard.nextEvidence || []).join(" / ") || "双方 Dasha / UL-DK / D9 7宫"}</small>
</details>
</article>
)}
<form className="profile-form chart-library-form" onSubmit={saveOtherChart}>
<div className="section-heading"><b></b><small></small></div>
<ProfileFields value={otherProfileDraft} onChange={setOtherProfileDraft} nameInputId="other-profile-name" />
@@ -143,6 +143,8 @@ def test_chart_profile_library_has_cloud_table_api_and_local_fallback() -> None:
"deleteCloudChartProfile",
"buildSynastryQuestion",
"draftSynastryQuestionFromChart",
"synastryReportCard",
"synastry-report-card",
'fetch("/api/synastry"',
"Ashtakoot",
"chartLibraryStorageKey",