扫描终端按需加载:后端支持 trading_region 过滤 + skip_polymarket 快速通道
scan_terminal_service:trading_region 参数预过滤城市列表。scan_terminal_city_row:快速模式跳过 Polymarket RPC。前端 hook 支持按区域查询。
This commit is contained in:
@@ -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 (
|
||||
|
||||
@@ -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] = []
|
||||
|
||||
Reference in New Issue
Block a user