指数页移除分时数据面板,K线图占满

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2026-07-06 14:51:50 +08:00
parent 26a7c02887
commit ef6e308ad1
+15 -69
View File
@@ -1,12 +1,11 @@
import { useEffect, useMemo, useState } from 'react' import { useEffect, useMemo, useState } from 'react'
import { useSearchParams } from 'react-router-dom' import { useSearchParams } from 'react-router-dom'
import { useQuery } from '@tanstack/react-query' import { useQuery } from '@tanstack/react-query'
import { Activity, Lock, Search } from 'lucide-react' import { Activity, Search } from 'lucide-react'
import { api, type IndexInstrument, type KlineRow, type MinuteKlineRow } from '@/lib/api' import { api, type IndexInstrument, type KlineRow } from '@/lib/api'
import { QK } from '@/lib/queryKeys' import { QK } from '@/lib/queryKeys'
import { useCapabilities } from '@/lib/useSharedQueries'
import { EChartsCandlestick, type OHLC } from '@/components/EChartsCandlestick' import { EChartsCandlestick, type OHLC } from '@/components/EChartsCandlestick'
import { EChartsIntraday } from '@/components/EChartsIntraday'
function defaultRange() { function defaultRange() {
const now = new Date() const now = new Date()
@@ -64,10 +63,6 @@ export function Indices() {
const [selectedDate, setSelectedDate] = useState<string | null>(null) const [selectedDate, setSelectedDate] = useState<string | null>(null)
const [linkedPrice, setLinkedPrice] = useState<number | null>(null) const [linkedPrice, setLinkedPrice] = useState<number | null>(null)
// 分时数据需 Pro+ (kline.minute.batch) 能力
const caps = useCapabilities()
const hasMinuteCap = !!caps.data?.capabilities?.['kline.minute.batch']
const list = useQuery({ const list = useQuery({
queryKey: QK.indexList, queryKey: QK.indexList,
queryFn: api.indexList, queryFn: api.indexList,
@@ -108,23 +103,8 @@ export function Indices() {
placeholderData: (prev) => prev, placeholderData: (prev) => prev,
}) })
const minute = useQuery({
queryKey: QK.indexMinute(selectedSymbol, selectedDate ?? ''),
queryFn: () => api.indexMinute(selectedSymbol, selectedDate ?? undefined),
enabled: !!selectedSymbol && !!selectedDate && hasMinuteCap,
placeholderData: (prev) => prev,
})
const chartRows = useMemo(() => toOHLC(daily.data?.rows ?? []), [daily.data?.rows]) const chartRows = useMemo(() => toOHLC(daily.data?.rows ?? []), [daily.data?.rows])
const selectedInfo = [...topRows, ...listRows].find(r => r.symbol === selectedSymbol) || daily.data?.index_info const selectedInfo = [...topRows, ...listRows].find(r => r.symbol === selectedSymbol) || daily.data?.index_info
const minuteRows: MinuteKlineRow[] = minute.data?.rows ?? []
const selectedIdx = selectedDate ? chartRows.findIndex(r => r.date === selectedDate) : -1
const prevClose = selectedIdx > 0
? chartRows[selectedIdx - 1].close
: chartRows.length >= 2
? chartRows[chartRows.length - 2].close
: undefined
useEffect(() => { useEffect(() => {
setSelectedDate(null) setSelectedDate(null)
setLinkedPrice(null) setLinkedPrice(null)
@@ -221,52 +201,18 @@ export function Indices() {
</div> </div>
)} )}
{chartRows.length > 0 && ( {chartRows.length > 0 && (
<div className="flex items-start gap-3"> <EChartsCandlestick
<div className="min-w-0 flex-1"> data={chartRows}
<EChartsCandlestick height={620}
data={chartRows} showMA={true}
height={620} showInfoBar={true}
showMA={true} showMarkers={false}
showInfoBar={true} symbol={selectedSymbol}
showMarkers={false} linkedPrice={linkedPrice}
symbol={selectedSymbol} onDateClick={setSelectedDate}
linkedPrice={linkedPrice} visibleBars={48}
onDateClick={setSelectedDate} activeIndicators={['vol', 'macd']}
visibleBars={48} />
activeIndicators={['vol', 'macd']}
/>
</div>
<div className="min-w-0 flex-1 border-l border-border pl-3" style={{ height: 620 }}>
{!hasMinuteCap ? (
<div className="flex h-full flex-col items-center justify-center gap-2 text-center">
<Lock className="h-5 w-5 text-muted" />
<div className="text-xs text-secondary"> Pro+</div>
<div className="text-[10px] text-muted"></div>
</div>
) : (
<>
{minute.isLoading && <div className="py-2 text-xs text-muted"></div>}
{!minute.isLoading && minuteRows.length === 0 && (
<div className="flex h-full items-center justify-center text-xs text-muted">
</div>
)}
{minuteRows.length > 0 && (
<EChartsIntraday
data={minuteRows}
height={620}
prevClose={prevClose}
date={selectedDate ?? undefined}
symbol={selectedSymbol}
showLimitLines={false}
showAvgLine={false}
onPriceHover={setLinkedPrice}
/>
)}
</>
)}
</div>
</div>
)} )}
</main> </main>
</div> </div>