@@ -1,12 +1,11 @@
|
||||
import { useEffect, useMemo, useState } from 'react'
|
||||
import { useSearchParams } from 'react-router-dom'
|
||||
import { useQuery } from '@tanstack/react-query'
|
||||
import { Activity, Lock, Search } from 'lucide-react'
|
||||
import { api, type IndexInstrument, type KlineRow, type MinuteKlineRow } from '@/lib/api'
|
||||
import { Activity, Search } from 'lucide-react'
|
||||
import { api, type IndexInstrument, type KlineRow } from '@/lib/api'
|
||||
import { QK } from '@/lib/queryKeys'
|
||||
import { useCapabilities } from '@/lib/useSharedQueries'
|
||||
|
||||
import { EChartsCandlestick, type OHLC } from '@/components/EChartsCandlestick'
|
||||
import { EChartsIntraday } from '@/components/EChartsIntraday'
|
||||
|
||||
function defaultRange() {
|
||||
const now = new Date()
|
||||
@@ -64,10 +63,6 @@ export function Indices() {
|
||||
const [selectedDate, setSelectedDate] = useState<string | 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({
|
||||
queryKey: QK.indexList,
|
||||
queryFn: api.indexList,
|
||||
@@ -108,23 +103,8 @@ export function Indices() {
|
||||
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 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(() => {
|
||||
setSelectedDate(null)
|
||||
setLinkedPrice(null)
|
||||
@@ -221,52 +201,18 @@ export function Indices() {
|
||||
</div>
|
||||
)}
|
||||
{chartRows.length > 0 && (
|
||||
<div className="flex items-start gap-3">
|
||||
<div className="min-w-0 flex-1">
|
||||
<EChartsCandlestick
|
||||
data={chartRows}
|
||||
height={620}
|
||||
showMA={true}
|
||||
showInfoBar={true}
|
||||
showMarkers={false}
|
||||
symbol={selectedSymbol}
|
||||
linkedPrice={linkedPrice}
|
||||
onDateClick={setSelectedDate}
|
||||
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>
|
||||
<EChartsCandlestick
|
||||
data={chartRows}
|
||||
height={620}
|
||||
showMA={true}
|
||||
showInfoBar={true}
|
||||
showMarkers={false}
|
||||
symbol={selectedSymbol}
|
||||
linkedPrice={linkedPrice}
|
||||
onDateClick={setSelectedDate}
|
||||
visibleBars={48}
|
||||
activeIndicators={['vol', 'macd']}
|
||||
/>
|
||||
)}
|
||||
</main>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user