feat(selection): enhance PatternScore component with detailed breakdown labels and update tests for accuracy
This commit is contained in:
@@ -6,6 +6,13 @@ interface PatternScoreProps {
|
|||||||
score: SelectionPatternScore | null
|
score: SelectionPatternScore | null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const breakdownLabels = {
|
||||||
|
trend_structure: "趋势",
|
||||||
|
kdj_state: "KDJ",
|
||||||
|
volume_pattern: "量能",
|
||||||
|
price_shape: "价格形态",
|
||||||
|
} as const
|
||||||
|
|
||||||
export function PatternScoreSummary({ score }: PatternScoreProps) {
|
export function PatternScoreSummary({ score }: PatternScoreProps) {
|
||||||
if (!score) return <span className="text-muted-foreground">未评分</span>
|
if (!score) return <span className="text-muted-foreground">未评分</span>
|
||||||
if (score.status === "failed") {
|
if (score.status === "failed") {
|
||||||
@@ -44,9 +51,20 @@ export function PatternScoreDetails({ score }: PatternScoreProps) {
|
|||||||
<p className="text-xl font-semibold tabular-nums">
|
<p className="text-xl font-semibold tabular-nums">
|
||||||
{formatScore(score.value)} 分
|
{formatScore(score.value)} 分
|
||||||
</p>
|
</p>
|
||||||
<Badge variant={score.status === "matched" ? "default" : "outline"}>
|
{score.breakdown ? (
|
||||||
{score.status === "matched" ? "已匹配" : "低于匹配阈值"}
|
<dl className="grid grid-cols-2 gap-1.5 text-xs">
|
||||||
</Badge>
|
{Object.entries(breakdownLabels).map(([key, label]) => (
|
||||||
|
<div key={key} className="rounded-md border border-border/60 p-1.5">
|
||||||
|
<dt className="text-muted-foreground">{label}</dt>
|
||||||
|
<dd className="mt-0.5 font-semibold tabular-nums">
|
||||||
|
{formatScore(
|
||||||
|
score.breakdown?.[key as keyof typeof breakdownLabels],
|
||||||
|
)}
|
||||||
|
</dd>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</dl>
|
||||||
|
) : null}
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -212,7 +212,10 @@ describe("SelectionResultsPage", () => {
|
|||||||
expect(
|
expect(
|
||||||
within(detailPanel).getByText("最接近案例:华纳药厂"),
|
within(detailPanel).getByText("最接近案例:华纳药厂"),
|
||||||
).toBeInTheDocument()
|
).toBeInTheDocument()
|
||||||
expect(within(detailPanel).queryByText("价格形态")).not.toBeInTheDocument()
|
expect(within(detailPanel).getByText("价格形态")).toBeInTheDocument()
|
||||||
|
expect(within(detailPanel).getByText("趋势")).toBeInTheDocument()
|
||||||
|
expect(within(detailPanel).getByText("量能")).toBeInTheDocument()
|
||||||
|
expect(within(detailPanel).queryByText("已匹配")).not.toBeInTheDocument()
|
||||||
expect(within(detailPanel).getByText("J 值")).toBeInTheDocument()
|
expect(within(detailPanel).getByText("J 值")).toBeInTheDocument()
|
||||||
expect(within(detailPanel).getByText("RSI")).toBeInTheDocument()
|
expect(within(detailPanel).getByText("RSI")).toBeInTheDocument()
|
||||||
expect(within(detailPanel).getByText("日涨跌幅")).toBeInTheDocument()
|
expect(within(detailPanel).getByText("日涨跌幅")).toBeInTheDocument()
|
||||||
@@ -239,7 +242,7 @@ describe("SelectionResultsPage", () => {
|
|||||||
score: null,
|
score: null,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
expected: "低于匹配阈值",
|
expected: "低于阈值",
|
||||||
score: {
|
score: {
|
||||||
breakdown: {
|
breakdown: {
|
||||||
kdj_state: 42,
|
kdj_state: 42,
|
||||||
|
|||||||
Reference in New Issue
Block a user