diff --git a/zhixing-web/src/features/sector-radar/components/radar-detail-dialog.tsx b/zhixing-web/src/features/sector-radar/components/radar-detail-dialog.tsx
index ffadce9..95667c3 100644
--- a/zhixing-web/src/features/sector-radar/components/radar-detail-dialog.tsx
+++ b/zhixing-web/src/features/sector-radar/components/radar-detail-dialog.tsx
@@ -1,4 +1,4 @@
-import { lazy, Suspense, useState } from "react"
+import { lazy, Suspense, useState, type ReactNode } from "react"
import { Button } from "@/shared/ui/button"
import {
Dialog,
@@ -47,55 +47,91 @@ export function RadarDetailDialog({ row }: { row: RadarRankingRow }) {
{row.sector_name}
- {row.sector_name}
-
- {row.sector_type === "concept" ? "概念" : "行业"} · {row.sector_code}{" "}
- · {row.trade_date}
-
- {open ? (
-
- ) : null}
+ {open ? : null}
)
}
-function RadarDetail({
- query,
- initialMetric,
-}: {
- query: RadarSectorQuery
- initialMetric: RadarMetricKind
-}) {
+function RadarDetail({ row }: { row: RadarRankingRow }) {
+ const query: RadarSectorQuery = {
+ sectorType: row.sector_type,
+ sectorCode: row.sector_code,
+ tradeDate: row.trade_date,
+ }
const detail = useSectorRadarDetail(query)
- if (detail.isPending) return
正在加载板块详情…
+ if (detail.isPending)
+ return (
+ <>
+
+ 正在加载板块详情…
+ >
+ )
if (detail.isError)
return (
-
- 板块详情加载失败。
-
-
+ <>
+
+
+ 板块详情加载失败。
+
+
+ >
)
if (!detail.data || detail.data.status === "no_data")
- return 暂无板块详情数据。
- return
+ return (
+ <>
+
+ 暂无板块详情数据。
+ >
+ )
+ return (
+
+ )
+}
+
+function RadarDetailHeader({
+ row,
+ actions,
+}: {
+ row: RadarRankingRow
+ actions?: ReactNode
+}) {
+ return (
+
+
+ {row.sector_name}
+
+ {row.sector_type === "concept" ? "概念" : "行业"} · {row.sector_code}{" "}
+ · {row.trade_date}
+
+
+ {actions ? (
+
+ {actions}
+
+ ) : null}
+
+ )
}
function RadarDetailBody({
data,
initialMetric,
+ row,
}: {
data: RadarDetailResponse
initialMetric: RadarMetricKind
+ row: RadarRankingRow
}) {
const [metric, setMetric] = useState(initialMetric)
const [memberMetric, setMemberMetric] =
@@ -130,39 +166,50 @@ function RadarDetailBody({
}
return (
-
-
-
-
- {exportStatus ?
{exportStatus}
: null}
-
-
实际交易日:{data.trade_date ?? "—"}
-
- 当日涨跌幅:
-
- {formatRadarValue(data.pct_change, "percent")}
-
-
-
- 领涨股:
- {data.leading_stock
- ? `${data.leading_stock.name ?? ""} ${data.leading_stock.ts_code}`
- : "暂无数据"}
-
+
+
+ {exportStatus ? (
+
+ {exportStatus}
+
+ ) : null}
+
+
+ >
+ }
+ />
+
+
实际交易日:{data.trade_date ?? "—"}
+
+ 当日涨跌幅:
+
+ {formatRadarValue(data.pct_change, "percent")}
+
+
+
+ 领涨股:
+ {data.leading_stock
+ ? `${data.leading_stock.name ?? ""} ${data.leading_stock.ts_code}`
+ : "暂无数据"}
+
+
diff --git a/zhixing-web/src/features/sector-radar/components/radar-detail.test.tsx b/zhixing-web/src/features/sector-radar/components/radar-detail.test.tsx
index 6e0224a..5cd2b3b 100644
--- a/zhixing-web/src/features/sector-radar/components/radar-detail.test.tsx
+++ b/zhixing-web/src/features/sector-radar/components/radar-detail.test.tsx
@@ -142,6 +142,21 @@ describe("radar detail interactions", () => {
expect(detailQuery).not.toHaveBeenCalled()
fireEvent.click(screen.getByRole("button", { name: "机器人" }))
const dialog = await screen.findByRole("dialog")
+ const compactHeader = within(dialog).getByRole("group", {
+ name: "板块详情标题栏",
+ })
+ expect(
+ within(compactHeader).getByRole("heading", { name: "机器人" }),
+ ).toBeInTheDocument()
+ expect(
+ within(compactHeader).getByText(/概念 · BK01 · 2026-08-28/),
+ ).toBeInTheDocument()
+ expect(
+ within(compactHeader).getByRole("button", { name: "复制成员" }),
+ ).toBeInTheDocument()
+ expect(
+ within(compactHeader).getByRole("button", { name: "导出成员" }),
+ ).toBeInTheDocument()
expect(detailQuery).toHaveBeenCalledWith({
sectorType: "concept",
sectorCode: "BK01",