扫描终端按需加载:后端支持 trading_region 过滤 + skip_polymarket 快速通道

scan_terminal_service:trading_region 参数预过滤城市列表。scan_terminal_city_row:快速模式跳过 Polymarket RPC。前端 hook 支持按区域查询。
This commit is contained in:
2569718930@qq.com
2026-05-25 06:32:42 +08:00
parent dd8f1c2d73
commit d64a92fd24
4 changed files with 22 additions and 4 deletions
@@ -280,7 +280,7 @@ export function MarketOverviewView({
</div>
</Panel>
<Panel title={isEn ? "Top Opportunities" : "Top Opportunities"}>
<Panel title={isEn ? "Top Opportunities" : "最佳机会"}>
<CompactRowsTable
empty={isEn ? "No opportunities" : "暂无机会"}
isEn={isEn}
@@ -289,7 +289,7 @@ export function MarketOverviewView({
/>
</Panel>
<Panel title={isEn ? "Risk / Watchlist" : "Risk / Watchlist"}>
<Panel title={isEn ? "Risk / Watchlist" : "风险 / 观察列表"}>
<CompactRowsTable
empty={isEn ? "No risk rows" : "暂无风险项"}
isEn={isEn}
@@ -53,6 +53,7 @@ type AiCityStreamEvent = {
type TerminalQueryOptions = {
forceRefresh?: boolean;
signal?: AbortSignal;
tradingRegion?: string;
};
type CityDetailQueryOptions = {
@@ -253,6 +254,7 @@ async function readAiCityForecastStream(
async function getTerminal({
forceRefresh = false,
signal,
tradingRegion,
}: TerminalQueryOptions = {}) {
const params = new URLSearchParams({
scan_mode: "tradable",
@@ -266,6 +268,9 @@ async function getTerminal({
force_refresh: String(forceRefresh),
skip_polymarket: "true",
});
if (tradingRegion && tradingRegion !== "all") {
params.set("trading_region", tradingRegion);
}
if (forceRefresh) {
params.set("_ts", String(Date.now()));
}
@@ -13,9 +13,11 @@ import type { ScanTerminalResponse } from "@/lib/dashboard-types";
export function useScanTerminalQuery({
isPro,
proAccessLoading,
tradingRegion,
}: {
isPro: boolean;
proAccessLoading: boolean;
tradingRegion?: string;
}) {
const {
data: terminalData,
@@ -48,11 +50,12 @@ export function useScanTerminalQuery({
scanTerminalClient.getTerminal({
forceRefresh,
signal,
tradingRegion,
}),
showLoading,
});
},
[isPro, proAccessLoading, run],
[isPro, proAccessLoading, run, tradingRegion],
);
useEffect(() => {
@@ -62,7 +65,7 @@ export function useScanTerminalQuery({
return;
}
void fetchScanTerminal({ forceRefresh: false, showLoading: true });
}, [fetchScanTerminal, isPro, proAccessLoading, reset]);
}, [fetchScanTerminal, isPro, proAccessLoading, reset, tradingRegion]);
const refreshScanTerminalManually = useCallback(() => {
if (
+10
View File
@@ -1230,6 +1230,16 @@ def _build_scan_terminal_payload_uncached(
try:
city_names = list(CITIES.keys())
region_filter = str(filters.get("trading_region") or "").strip().lower()
if region_filter and region_filter not in ("all", ""):
from web.scan_terminal_filters import market_region_from_tz_offset as _tz_region
def _city_in_region(city_name: str) -> bool:
city_meta = CITIES.get(city_name) or {}
tz = city_meta.get("tz", 0)
return _tz_region(tz)["key"] == region_filter
city_names = [c for c in city_names if _city_in_region(c)]
max_workers = max(1, min(SCAN_TERMINAL_MAX_WORKERS, len(city_names)))
city_results: List[Dict[str, Any]] = []
failed_cities: List[str] = []