mirror of
https://ghfast.top/https://github.com/aeroxw/tick-stock-panel.git
synced 2026-09-12 16:44:15 +08:00
fix: 升级 Expert Key 后财务页「全部同步」无反应
启动时无 FINANCIAL 能力导致调度器 _capset 为 None, 后续在设置页更新 Key 时 app.state.capabilities 已刷新但调度器未同步, trigger() 仍报 no FINANCIAL capability 而拒绝同步。新增 update_capabilities 并在设置 API 刷新能力时同步推给调度器; 前端对 started:false 一律给出提示, 不再静默。
This commit is contained in:
@@ -29,6 +29,21 @@ router = APIRouter(prefix="/api/settings", tags=["settings"])
|
||||
DEFAULT_PAID_ENDPOINT = "https://api.tickflow.org"
|
||||
|
||||
|
||||
def _sync_financial_scheduler_caps(app_state, capset) -> None:
|
||||
"""把重新探测出的能力同步给财务调度器。
|
||||
|
||||
app.state.capabilities 在此已更新, 但 FinancialScheduler 在启动时捕获的是旧引用,
|
||||
需显式刷新, 否则用户升级到 Expert 后点「全部同步」仍会因调度器读旧 capset 而被拒。
|
||||
"""
|
||||
fs = getattr(app_state, "financial_scheduler", None)
|
||||
if fs is None:
|
||||
return
|
||||
try:
|
||||
fs.update_capabilities(capset)
|
||||
except Exception as e: # noqa: BLE001
|
||||
logging.getLogger(__name__).warning("update financial_scheduler capabilities failed: %s", e)
|
||||
|
||||
|
||||
class TickflowKeyIn(BaseModel):
|
||||
api_key: str
|
||||
|
||||
@@ -124,6 +139,7 @@ def save_tickflow_key(req: TickflowKeyIn, request: Request) -> dict:
|
||||
# 立即重新探测(此时 client 已按档位判定,但首次探测必然走付费端点验证)
|
||||
capset = detect_capabilities(force=True)
|
||||
request.app.state.capabilities = capset
|
||||
_sync_financial_scheduler_caps(request.app.state, capset)
|
||||
|
||||
# ===== 2) 判定为无效 key(连单只日K都拿不到)→ 不存,清除 =====
|
||||
if is_invalid_key() or base_tier_name() == "none":
|
||||
@@ -132,6 +148,7 @@ def save_tickflow_key(req: TickflowKeyIn, request: Request) -> dict:
|
||||
tf_client.reset_clients()
|
||||
capset = detect_capabilities(force=True)
|
||||
request.app.state.capabilities = capset
|
||||
_sync_financial_scheduler_caps(request.app.state, capset)
|
||||
return {
|
||||
"ok": False,
|
||||
"reason": "invalid",
|
||||
@@ -188,6 +205,7 @@ def clear_tickflow_key(request: Request) -> dict:
|
||||
|
||||
capset = detect_capabilities(force=True)
|
||||
request.app.state.capabilities = capset
|
||||
_sync_financial_scheduler_caps(request.app.state, capset)
|
||||
|
||||
return {
|
||||
"ok": True,
|
||||
|
||||
@@ -207,11 +207,15 @@ class FinancialScheduler:
|
||||
供 /api/financials/sync/* 手动同步使用, 不启动自动调度。
|
||||
auto_schedule=True: 额外启动每周一次的 metrics 自动同步 (启动后 60s 首跑)。
|
||||
"""
|
||||
# 先记录 data_dir/capset, 即使当前无 FINANCIAL 也保留引用:
|
||||
# 用户稍后在「设置」页升级到 Expert Key 时, update_capabilities() 会把新 capset
|
||||
# 推进来,trigger()/run_now() 才能用上 FINANCIAL。否则 _capset 永远是 None,
|
||||
# 即便 app.state.capabilities 已更新, 调度器仍报 "no FINANCIAL capability"。
|
||||
self._data_dir = data_dir
|
||||
self._capset = capset
|
||||
if not capset.has(Cap.FINANCIAL):
|
||||
logger.info("FinancialScheduler skipped: no FINANCIAL capability")
|
||||
return
|
||||
self._data_dir = data_dir
|
||||
self._capset = capset
|
||||
# 从持久化恢复上次同步时间: 重启后前端仍能显示真实最后同步时间,而非"尚未同步"
|
||||
try:
|
||||
from app.services import preferences
|
||||
@@ -254,7 +258,24 @@ class FinancialScheduler:
|
||||
from app.services import preferences
|
||||
preferences.set_financial_sync_time(table, ts)
|
||||
except Exception as e: # noqa: BLE001
|
||||
logger.warning("persist financial_sync_time(%s) failed: %s", table, e)
|
||||
logger.warning("persist financial_sync_time(%s) failed: %s", e)
|
||||
|
||||
def update_capabilities(self, capset: CapabilitySet) -> None:
|
||||
"""刷新调度器持有的能力集。
|
||||
|
||||
用户在「设置」页新增/清除 API Key 后, settings API 会重新探测能力并更新
|
||||
app.state.capabilities; 必须同步推给本调度器, 否则 trigger()/run_now() 仍读
|
||||
启动时的旧 capset, 即便 app.state 已含 FINANCIAL, 调度器仍报
|
||||
"no FINANCIAL capability" 而拒绝同步 (表现为前端「全部同步」按钮闪一下无动作)。
|
||||
"""
|
||||
prev = self._capset
|
||||
self._capset = capset
|
||||
had = bool(prev) and prev.has(Cap.FINANCIAL)
|
||||
now = capset.has(Cap.FINANCIAL)
|
||||
if had != now:
|
||||
logger.info(
|
||||
"FinancialScheduler capabilities updated: FINANCIAL %s -> %s", had, now
|
||||
)
|
||||
|
||||
def stop(self) -> None:
|
||||
self._running = False
|
||||
|
||||
@@ -108,6 +108,11 @@ export function Financials() {
|
||||
if (!r.synced?.started) {
|
||||
if (r.synced?.reason === 'already running') {
|
||||
toast('财务数据正在同步中,请稍候', 'success')
|
||||
} else if (r.synced?.reason === 'no FINANCIAL capability') {
|
||||
// 能力未就绪:通常发生在升级/刷新 Key 后调度器状态未同步 —— 提示用户检查 Key
|
||||
toast('财务数据能力未就绪,请检查 API Key 或刷新页面后重试', 'error')
|
||||
} else {
|
||||
toast(`同步未能开始${r.synced?.reason ? `:${r.synced.reason}` : ''}`, 'error')
|
||||
}
|
||||
setSyncStartedAt(null)
|
||||
setSyncSingleTable(null)
|
||||
|
||||
Reference in New Issue
Block a user