fix(minute,monitoring): 自定义数据源用户单股补拉/监控页打通 (#121)

承接 #126: 能力探测已补 KLINE_MINUTE_BATCH, 但两处取数/UI 仍按 TickFlow
档位拦截, 配了自定义分钟/实时源的 None 档用户依旧被挡。

- kline_sync.fetch_minute_single: 与 sync_minute_batch 一致, 先查
  preferences.get_minute_data_provider(), 非 tickflow 且自定义源有
  minute dataset 时走 custom provider, 避免分时图首次打开(本地无数据)
  补拉返回空。
- Monitoring.tsx: None 档但配了自定义实时源时, 后端
  is_realtime_allowed(realtime_mode=full_market) 仍返回 True。
  以 quoteStatus.realtime_allowed 作为最终判据, 不再用 isNoneTier
  一刀切拦截实时监控页。

Co-authored-by: shy3130 <shy3130@users.noreply.github.com>
This commit is contained in:
intfoo
2026-07-19 13:26:52 +08:00
co-authored by shy3130
parent 8e4258cf20
commit e2ffde99d5
2 changed files with 16 additions and 2 deletions
+12 -1
View File
@@ -738,10 +738,21 @@ def fetch_intraday_monitor_batch(
def fetch_minute_single(symbol: str, trade_date: date) -> pl.DataFrame:
"""从 TickFlow 实时拉取单股单日分钟 K不写入本地"""
"""实时拉取单股单日分钟 K(不写入本地)。优先自定义分钟源, 回退 TickFlow"""
from datetime import datetime
start_time = datetime(trade_date.year, trade_date.month, trade_date.day, 9, 25, 0)
end_time = datetime(trade_date.year, trade_date.month, trade_date.day, 15, 5, 0)
# 自定义数据源分流: 与 sync_minute_batch 一致, 配了自定义分钟源时走 custom provider,
# 避免无 TickFlow Pro+ 权限的用户分时图首次打开(本地无数据)时补拉失败返回空。
provider_name = preferences.get_minute_data_provider()
if provider_name != "tickflow":
from app.data_providers import custom as custom_sources
if custom_sources.provider_has_dataset(provider_name, "minute"):
provider = custom_sources.get_provider(provider_name)
return provider.get_minute([symbol], start_time=start_time, end_time=end_time)
# 未配置 minute dataset → 回退 TickFlow
tf = get_client()
try:
raw = tf.klines.batch(
+4 -1
View File
@@ -49,6 +49,9 @@ export function SettingsMonitoringPanel({ highlight }: { highlight?: string } =
const toggleQuote = useToggleRealtimeQuotes()
const tier = tierRank(caps?.label ?? '')
const isNoneTier = tier < 0
// None 档但配了自定义实时源时, 后端 is_realtime_allowed 仍返回 True (realtime_mode=full_market)
// 此时不应拦截实时监控页 — 用 quoteStatus.realtime_allowed 作为最终判据
const realtimeAllowed = quoteStatus?.realtime_allowed ?? !isNoneTier
const isFreeTier = tier === 0
const realtimeEnabled = prefs?.realtime_quotes_enabled ?? false
// 分时图实时刷新间隔 (秒), 与后端 [3,60] clamp 对齐; 默认 6
@@ -278,7 +281,7 @@ export function SettingsMonitoringPanel({ highlight }: { highlight?: string } =
}
}, [highlight])
if (isNoneTier) {
if (isNoneTier && !realtimeAllowed) {
return (
<div className="flex flex-col items-center justify-center py-20 text-center">
<div className="inline-flex items-center justify-center w-14 h-14 rounded-2xl