@@ -1,7 +1,7 @@
|
|||||||
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 { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'
|
import { useQuery } from '@tanstack/react-query'
|
||||||
import { Activity, Loader2, Lock, RefreshCw, Search } from 'lucide-react'
|
import { Activity, Lock, Search } from 'lucide-react'
|
||||||
import { api, type IndexInstrument, type KlineRow, type MinuteKlineRow } from '@/lib/api'
|
import { api, type IndexInstrument, type KlineRow, type MinuteKlineRow } from '@/lib/api'
|
||||||
import { QK } from '@/lib/queryKeys'
|
import { QK } from '@/lib/queryKeys'
|
||||||
import { useCapabilities } from '@/lib/useSharedQueries'
|
import { useCapabilities } from '@/lib/useSharedQueries'
|
||||||
@@ -56,7 +56,6 @@ function pinnedRank(item: IndexInstrument) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function Indices() {
|
export function Indices() {
|
||||||
const qc = useQueryClient()
|
|
||||||
const [searchParams, setSearchParams] = useSearchParams()
|
const [searchParams, setSearchParams] = useSearchParams()
|
||||||
const [keyword, setKeyword] = useState('')
|
const [keyword, setKeyword] = useState('')
|
||||||
const symbolParam = searchParams.get('symbol') ?? ''
|
const symbolParam = searchParams.get('symbol') ?? ''
|
||||||
@@ -116,21 +115,6 @@ export function Indices() {
|
|||||||
placeholderData: (prev) => prev,
|
placeholderData: (prev) => prev,
|
||||||
})
|
})
|
||||||
|
|
||||||
const syncInstruments = useMutation({
|
|
||||||
mutationFn: api.syncIndexInstruments,
|
|
||||||
onSuccess: () => {
|
|
||||||
qc.invalidateQueries({ queryKey: QK.indexList })
|
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
||||||
const syncDaily = useMutation({
|
|
||||||
mutationFn: () => api.syncIndexDaily(365),
|
|
||||||
onSuccess: () => {
|
|
||||||
qc.invalidateQueries({ queryKey: QK.indexList })
|
|
||||||
qc.invalidateQueries({ queryKey: ['index-daily'] })
|
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
||||||
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 minuteRows: MinuteKlineRow[] = minute.data?.rows ?? []
|
||||||
@@ -174,24 +158,6 @@ export function Indices() {
|
|||||||
指数使用独立 kline_index_* parquet,不进入股票选股和策略链路。
|
指数使用独立 kline_index_* parquet,不进入股票选股和策略链路。
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex items-center gap-2">
|
|
||||||
<button
|
|
||||||
onClick={() => syncInstruments.mutate()}
|
|
||||||
disabled={syncInstruments.isPending}
|
|
||||||
className="inline-flex items-center gap-1.5 rounded-btn bg-elevated px-3 py-1.5 text-xs text-secondary hover:text-foreground disabled:opacity-50"
|
|
||||||
>
|
|
||||||
{syncInstruments.isPending ? <Loader2 className="h-3.5 w-3.5 animate-spin" /> : <RefreshCw className="h-3.5 w-3.5" />}
|
|
||||||
同步指数列表
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
onClick={() => syncDaily.mutate()}
|
|
||||||
disabled={syncDaily.isPending}
|
|
||||||
className="inline-flex items-center gap-1.5 rounded-btn bg-accent px-3 py-1.5 text-xs font-medium text-base hover:bg-accent/90 disabled:opacity-50"
|
|
||||||
>
|
|
||||||
{syncDaily.isPending ? <Loader2 className="h-3.5 w-3.5 animate-spin" /> : <RefreshCw className="h-3.5 w-3.5" />}
|
|
||||||
同步指数日K
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="grid grid-cols-[15rem_1fr] gap-4">
|
<div className="grid grid-cols-[15rem_1fr] gap-4">
|
||||||
|
|||||||
Reference in New Issue
Block a user