diff --git a/frontend/src/components/Layout.tsx b/frontend/src/components/Layout.tsx
index bc34732..b7bfed3 100644
--- a/frontend/src/components/Layout.tsx
+++ b/frontend/src/components/Layout.tsx
@@ -141,7 +141,7 @@ function MonitorBadge({ active }: { active: boolean }) {
)
}
-function SidebarIndexQuotes({ rows, items }: { rows: IndexQuote[] | undefined; items: CoreIndex[] }) {
+function SidebarIndexQuotes({ rows, items }: { rows: IndexQuote[] | undefined; items: readonly CoreIndex[] }) {
if (items.length === 0) return null
const quoteBySymbol = new Map((rows ?? []).map(q => [q.symbol, q]))
return (
@@ -445,15 +445,12 @@ export function Layout() {
return next
})
}
- const indicesPinned = prefs?.indices_nav_pinned ?? true
- const sidebarIndexSymbols = prefs?.sidebar_index_symbols ?? CORE_INDEXES.map(p => p.symbol)
- const sidebarIndexes = CORE_INDEXES.filter(item => sidebarIndexSymbols.includes(item.symbol))
- // 卡片数据:固定显示时也拉取(即使实时行情关闭)
- const showSidebarQuotes = indicesPinned || realtimeEnabled
+ // 指数条: 固定核心四只 (产品契约, 不再可配置), 常驻显示
+ const sidebarIndexes = CORE_INDEXES
const { data: sidebarIndexQuotes } = useQuery({
- queryKey: [...QK.indexQuotes, 'sidebar', sidebarIndexSymbols.join(',')] as const,
+ queryKey: [...QK.indexQuotes, 'sidebar', 'core'] as const,
queryFn: () => api.indexQuotes(sidebarIndexes.map(p => p.symbol)),
- enabled: showSidebarQuotes && sidebarIndexes.length > 0,
+ enabled: sidebarIndexes.length > 0,
placeholderData: (prev) => prev,
})
@@ -877,7 +874,7 @@ export function Layout() {
)}
)}
- {showSidebarQuotes && !isWatchlistMode && (!realtimeUnavailable || !!realtimeProviderName) && (
+ {!isWatchlistMode && (!realtimeUnavailable || !!realtimeProviderName) && (
)}
diff --git a/frontend/src/lib/api.ts b/frontend/src/lib/api.ts
index a960d9f..86f603d 100644
--- a/frontend/src/lib/api.ts
+++ b/frontend/src/lib/api.ts
@@ -1595,7 +1595,6 @@ export interface WecomBotStatus {
export interface Preferences {
realtime_quotes_enabled: boolean
- indices_nav_pinned: boolean
watchlist_groups_in_nav: boolean
minute_sync_enabled: boolean
minute_sync_days: number
@@ -1614,9 +1613,6 @@ export interface Preferences {
data_source_long_job_timeout_s: number
realtime_pull_stock?: boolean
realtime_pull_etf?: boolean
- realtime_pull_index?: boolean
- realtime_index_mode?: 'core' | 'all'
- realtime_index_symbols?: string[]
pipeline_pull_a_share: boolean
pipeline_pull_etf: boolean
pipeline_pull_index: boolean
@@ -1645,7 +1641,6 @@ export interface Preferences {
wecom_bot_enabled?: boolean
webhook_enabled_default?: boolean
webhook_default_channels?: string[]
- sidebar_index_symbols: string[]
nav_order: string[]
nav_hidden: string[]
screener_auto_run: boolean
@@ -1851,16 +1846,11 @@ export const api = {
method: 'PUT',
body: JSON.stringify({ realtime_quotes_enabled: enabled }),
}),
- updateRealtimeQuoteScope: (cfg: Partial>) =>
+ updateRealtimeQuoteScope: (cfg: Partial>) =>
request>('/api/settings/preferences/realtime-quote-scope', {
method: 'PUT',
body: JSON.stringify(cfg),
}),
- updateIndicesNavPinned: (pinned: boolean) =>
- request<{ indices_nav_pinned: boolean }>('/api/settings/preferences/indices-nav-pinned', {
- method: 'PUT',
- body: JSON.stringify({ indices_nav_pinned: pinned }),
- }),
updateWatchlistGroupsInNav: (enabled: boolean) =>
request<{ watchlist_groups_in_nav: boolean }>('/api/settings/preferences/watchlist-groups-in-nav', {
method: 'PUT',
@@ -1904,7 +1894,6 @@ export const api = {
sse_refresh_pages?: Record
strategy_monitor_enabled?: boolean
strategy_monitor_ids?: string[]
- sidebar_index_symbols?: string[]
screener_auto_run?: boolean
minute_intraday_refresh?: boolean
minute_intraday_refresh_interval?: number
@@ -1914,7 +1903,6 @@ export const api = {
sse_refresh_pages: Record
strategy_monitor_enabled: boolean
strategy_monitor_ids: string[]
- sidebar_index_symbols: string[]
screener_auto_run: boolean
minute_intraday_refresh: boolean
minute_intraday_refresh_interval: number
@@ -2105,11 +2093,6 @@ export const api = {
}>(
`/api/kline/minute-range?symbol=${encodeURIComponent(symbol)}&days=${days}`,
),
- indexList: () => request<{ results: IndexInstrument[]; count: number }>('/api/index/list'),
- indexSearch: (q: string, limit = 20) =>
- request<{ results: IndexInstrument[] }>(
- `/api/index/search?q=${encodeURIComponent(q)}&limit=${limit}`,
- ),
indexDaily: (symbol: string, days = 120, dateRange?: { start: string; end: string }) =>
request<{
symbol: string
@@ -2126,7 +2109,6 @@ export const api = {
request<{
symbol: string
name?: string
- index_info?: IndexInstrument
date: string | null
rows: MinuteKlineRow[]
source?: string
diff --git a/frontend/src/lib/queryKeys.ts b/frontend/src/lib/queryKeys.ts
index a05eefd..50c4780 100644
--- a/frontend/src/lib/queryKeys.ts
+++ b/frontend/src/lib/queryKeys.ts
@@ -20,7 +20,6 @@ export const QK = {
quoteInterval: ['quote-interval'] as const,
overviewMarket: (asOf?: string) => ['overview-market', asOf ?? 'latest'] as const,
indexQuotes: ['index-quotes'] as const,
- indexList: ['index-list'] as const,
// Watchlist
watchlist: ['watchlist'] as const,
@@ -86,9 +85,9 @@ export const QK = {
klineMinuteRange: (symbol: string, days: number) =>
['kline-minute-range', symbol, days] as const,
indexDaily: (symbol: string, start: string, end: string) =>
- ['index-daily', symbol, start, end] as const,
+ ['index-daily', symbol, start, end] as const,
indexMinute: (symbol: string, date: string) =>
- ['index-minute', symbol, date] as const,
+ ['index-minute', symbol, date] as const,
// Schema
extDataSchemaAll: ['ext-data-schema-all'] as const,
diff --git a/frontend/src/pages/Data.tsx b/frontend/src/pages/Data.tsx
index d3a8046..c2a88b2 100644
--- a/frontend/src/pages/Data.tsx
+++ b/frontend/src/pages/Data.tsx
@@ -162,7 +162,6 @@ export function Data() {
mutationFn: () => api.syncIndexDaily(indexSyncDays),
onSuccess: () => {
qc.invalidateQueries({ queryKey: QK.dataStatus })
- qc.invalidateQueries({ queryKey: QK.indexList })
qc.invalidateQueries({ queryKey: QK.indexQuotes })
qc.invalidateQueries({ queryKey: ['index-daily'] })
},
diff --git a/frontend/src/pages/Indices.tsx b/frontend/src/pages/Indices.tsx
index ae51cd3..e48a9f3 100644
--- a/frontend/src/pages/Indices.tsx
+++ b/frontend/src/pages/Indices.tsx
@@ -1,7 +1,7 @@
import { useEffect, useMemo, useState } from 'react'
import { useSearchParams } from 'react-router-dom'
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'
-import { Activity, Loader2, Lock, RefreshCw, Search } from 'lucide-react'
+import { Activity, Loader2, Lock, RefreshCw } from 'lucide-react'
import { api, type IndexInstrument, type KlineRow, type MinuteKlineRow } from '@/lib/api'
import { QK } from '@/lib/queryKeys'
import { useCapabilities } from '@/lib/useSharedQueries'
@@ -61,14 +61,9 @@ const PINNED_INDEXES = [
{ symbol: '000680.SH', name: '科创综指' },
]
-function pinnedRank(item: IndexInstrument) {
- return PINNED_INDEXES.findIndex(p => item.symbol === p.symbol || item.name === p.name)
-}
-
export function Indices() {
const qc = useQueryClient()
const [searchParams, setSearchParams] = useSearchParams()
- const [keyword, setKeyword] = useState('')
const symbolParam = searchParams.get('symbol') ?? ''
const [selected, setSelected] = useState(symbolParam)
const [range, setRange] = useState(defaultRange)
@@ -79,29 +74,12 @@ export function Indices() {
const caps = useCapabilities()
const hasMinuteCap = !!caps.data?.capabilities?.['kline.minute.batch']
- const list = useQuery({
- queryKey: QK.indexList,
- queryFn: api.indexList,
- })
+ // 指数标的固定核心四只 (产品契约, 不再提供全指数搜索/浏览)
+ const topRows: IndexInstrument[] = PINNED_INDEXES.map(p => ({
+ symbol: p.symbol, name: p.name, asset_type: 'index' as const,
+ }))
- const search = useQuery({
- queryKey: ['index-search', keyword],
- queryFn: () => api.indexSearch(keyword, 50),
- enabled: keyword.trim().length > 0,
- })
-
- const rows: IndexInstrument[] = keyword.trim()
- ? (search.data?.results ?? [])
- : (list.data?.results ?? [])
- const topRows = useMemo(() => {
- const all = list.data?.results ?? []
- return PINNED_INDEXES.map(p => (
- all.find(item => item.symbol === p.symbol || item.name === p.name) ?? { symbol: p.symbol, name: p.name, asset_type: 'index' as const }
- ))
- }, [list.data?.results])
- const listRows = useMemo(() => rows.filter(item => pinnedRank(item) < 0), [rows])
-
- const selectedSymbol = selected || topRows[0]?.symbol || listRows[0]?.symbol || ''
+ const selectedSymbol = selected || topRows[0]?.symbol || ''
useEffect(() => {
if (symbolParam && symbolParam !== selected) setSelected(symbolParam)
@@ -132,18 +110,9 @@ export function Indices() {
placeholderData: (prev) => prev,
})
- const syncInstruments = useMutation({
- mutationFn: api.syncIndexInstruments,
- onSuccess: () => {
- qc.invalidateQueries({ queryKey: QK.indexList })
- qc.invalidateQueries({ queryKey: QK.indexQuotes })
- },
- })
-
const syncDaily = useMutation({
mutationFn: () => api.syncIndexDaily(365),
onSuccess: () => {
- qc.invalidateQueries({ queryKey: QK.indexList })
qc.invalidateQueries({ queryKey: QK.indexQuotes })
qc.invalidateQueries({ queryKey: ['index-daily'] })
},
@@ -159,7 +128,7 @@ export function Indices() {
const selectedQuotePct = selectedQuote?.change_pct ?? selectedQuote?.pct
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.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
@@ -211,14 +180,6 @@ export function Indices() {
-