From 55461c20c22f4fff706c1ee124ed597e3585db72 Mon Sep 17 00:00:00 2001 From: "2569718930@qq.com" <2569718930@qq.com> Date: Sat, 25 Apr 2026 00:08:21 +0800 Subject: [PATCH] Open scan map preview to free users --- .../components/dashboard/Dashboard.module.css | 20 ++ .../components/dashboard/OpportunityTable.tsx | 24 +- .../dashboard/ScanTerminalDashboard.tsx | 211 ++++++++---------- 3 files changed, 129 insertions(+), 126 deletions(-) diff --git a/frontend/components/dashboard/Dashboard.module.css b/frontend/components/dashboard/Dashboard.module.css index 84ab2d88..98b1e589 100644 --- a/frontend/components/dashboard/Dashboard.module.css +++ b/frontend/components/dashboard/Dashboard.module.css @@ -9551,6 +9551,11 @@ cursor: pointer; } +.root :global(.scan-list-tabs button:disabled) { + opacity: 0.42; + cursor: not-allowed; +} + .root :global(.scan-list-tabs button.active) { color: #fff; } @@ -9678,9 +9683,24 @@ grid-template-columns: minmax(0, 1fr) auto; gap: 16px; align-items: center; + width: 100%; padding: 16px 18px 14px; + border: 0; border-bottom: 1px solid rgba(90, 123, 166, 0.1); background: rgba(13, 28, 48, 0.62); + color: inherit; + font: inherit; + text-align: left; + cursor: pointer; +} + +.root :global(.scan-opportunity-group-head:hover) { + background: rgba(18, 38, 64, 0.78); +} + +.root :global(.scan-opportunity-group-head:focus-visible) { + outline: 2px solid rgba(34, 211, 238, 0.72); + outline-offset: -2px; } .root :global(.scan-opportunity-city) { diff --git a/frontend/components/dashboard/OpportunityTable.tsx b/frontend/components/dashboard/OpportunityTable.tsx index f4b93f34..c902ee7d 100644 --- a/frontend/components/dashboard/OpportunityTable.tsx +++ b/frontend/components/dashboard/OpportunityTable.tsx @@ -170,7 +170,8 @@ function getDistributionPreview(row: ScanOpportunityRow, tempSymbol?: string | n : normalizeTemperatureLabel(row.target_label, tempSymbol) || "--"; preview.push({ label: targetLabel, - model_probability: row.model_event_probability, + model_probability: + row.raw_model_event_probability ?? row.model_event_probability, market_probability: row.market_event_probability, highlighted: true, }); @@ -331,7 +332,14 @@ export const OpportunityTable = React.memo(function OpportunityTable({
{groups.map((group) => (
-
+
{group.rows.map((row, rowIndex) => { @@ -366,16 +374,12 @@ export const OpportunityTable = React.memo(function OpportunityTable({ const selected = selectedRowId === row.id; const side = String(row.side || "").toLowerCase(); const modelProbability = - row.model_probability != null - ? row.model_probability * 100 + row.raw_model_event_probability != null + ? row.raw_model_event_probability * 100 : row.model_event_probability != null ? row.model_event_probability * 100 : null; - const modelLabel = row.cluster_adjusted - ? isEn - ? "Model" - : "模型" - : "EMOS"; + const modelLabel = "EMOS"; const priceLabel = side === "no" ? "NO" : isEn ? "Market" : "市场"; const edgePositive = Number(row.edge_percent || 0) >= 0; const aiMeta = getAiMeta(row, locale); diff --git a/frontend/components/dashboard/ScanTerminalDashboard.tsx b/frontend/components/dashboard/ScanTerminalDashboard.tsx index affcb7a5..74ff37ee 100644 --- a/frontend/components/dashboard/ScanTerminalDashboard.tsx +++ b/frontend/components/dashboard/ScanTerminalDashboard.tsx @@ -226,27 +226,11 @@ function CalendarView({ ); } -function OverviewMapView({ locale }: { locale: string }) { - const store = useDashboardStore(); - - return ( -
-
- -
-
- {locale === "en-US" - ? `Monitoring ${store.cities.length} cities on the original map canvas.` - : `正在用原地图画布监控 ${store.cities.length} 个城市。`} -
-
- ); -} - function ScanTerminalScreen() { const store = useDashboardStore(); const { locale, toggleLocale } = useI18n(); const isEn = locale === "en-US"; + const isPro = store.proAccess.subscriptionActive; const accountHref = store.proAccess.authenticated ? "/account" : "/auth/login?next=%2Faccount"; @@ -368,7 +352,7 @@ function ScanTerminalScreen() { ]); const fetchTerminal = async (filters: FilterState, force = false) => { - if (!store.proAccess.subscriptionActive) return; + if (!isPro) return; setLoading(true); setAiError(null); try { @@ -419,17 +403,23 @@ function ScanTerminalScreen() { }; useEffect(() => { - if (!store.proAccess.subscriptionActive) return; + if (!isPro) return; void fetchTerminal(DEFAULT_FILTERS, false); - }, [store.proAccess.subscriptionActive]); + }, [isPro]); useEffect(() => { - if (!store.proAccess.subscriptionActive) return; + if (!isPro) return; const intervalId = window.setInterval(() => { void fetchTerminal(activeFilters, false); }, SCAN_AUTO_REFRESH_MS); return () => window.clearInterval(intervalId); - }, [activeFilters, store.proAccess.subscriptionActive]); + }, [activeFilters, isPro]); + + useEffect(() => { + if (!isPro && activeView !== "map") { + setActiveView("map"); + } + }, [activeView, isPro]); useEffect(() => { setUserLocalTime(formatUserLocalTime()); @@ -510,10 +500,21 @@ function ScanTerminalScreen() { selectionMode="select" />
-
- {locale === "en-US" - ? `Monitoring ${store.cities.length} cities on the original map canvas.` - : `正在用原地图画布监控 ${store.cities.length} 个城市。`} +
+ ); + } + if (!isPro) { + return ( +
+
+
+ {isEn ? "Scan is available on Pro" : "扫描功能需 Pro 权限"} +
+
+ {isEn + ? "Distribution view and city briefing remain available." + : "分布视图和右侧城市简报仍可查看。"} +
); @@ -560,53 +561,6 @@ function ScanTerminalScreen() { ); } - if (!store.proAccess.subscriptionActive) { - return ( -
-
-
-
-
- {isEn ? "Market Scan Terminal" : "市场扫描台"} - {isEn ? "Pro access required" : "需要 Pro 权限"} -
-
- - - - {store.proAccess.authenticated - ? isEn ? "Upgrade Pro" : "升级 Pro" - : isEn ? "Sign in" : "登录"} - -
-
-
-
-
- {isEn ? "Market scan is a Pro feature" : "市场扫描是 Pro 功能"} -
-
- {isEn - ? "Free accounts do not trigger rule scans or V4-Flash scans." - : "免费用户不会触发规则扫描,也不会消耗 V4-Flash 扫描资源。"} -
-
-
-
-
-
- ); - } - return (
@@ -624,8 +578,12 @@ function ScanTerminalScreen() { ? "Showing the last successful snapshot" : "当前显示上次成功快照" : isEn - ? "Read-only market scan with peak-first main signal" - : "只读市场扫描,主信号按 EMOS 主峰优先"} + ? isPro + ? "Read-only market scan with peak-first main signal" + : "Free preview: distribution view and city briefing" + : isPro + ? "只读市场扫描,主信号按 EMOS 主峰优先" + : "免费预览:分布视图和城市简报可查看"}
@@ -642,37 +600,48 @@ function ScanTerminalScreen() { {userLocalTime} - - + {isPro ? ( + <> + + + + ) : ( + + + {store.proAccess.authenticated + ? isEn ? "Upgrade Pro" : "升级 Pro" + : isEn ? "Sign in" : "登录"} + + )} - + {isPro ? ( + + ) : null}
- + {isPro ? ( + + ) : null}
@@ -719,7 +692,10 @@ function ScanTerminalScreen() {