From 348dfe132a34c61e7b688e3118bd23f881ffa0b7 Mon Sep 17 00:00:00 2001 From: "2569718930@qq.com" <2569718930@qq.com> Date: Sat, 23 May 2026 12:16:19 +0800 Subject: [PATCH] =?UTF-8?q?=E7=A7=BB=E9=99=A4=20Polymarket=20=E4=BB=B7?= =?UTF-8?q?=E6=A0=BC=E5=B1=82=20UI=EF=BC=9A=E5=88=A0=E9=99=A4=20MarketDeci?= =?UTF-8?q?sionLine=20=E7=BB=84=E4=BB=B6=E5=8F=8A=E7=9B=B8=E5=85=B3?= =?UTF-8?q?=E6=95=B0=E6=8D=AE=E6=B5=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../scan-terminal/AiPinnedCityCard.tsx | 63 ------------------- .../scan-terminal/MobileDecisionCard.tsx | 11 ---- .../scan-terminal/WeatherDecisionBand.tsx | 19 +----- .../__tests__/buildCityDecisionState.test.ts | 7 --- .../__tests__/buildStatusTags.test.ts | 2 - .../scan-terminal/city-decision-state.ts | 30 +-------- 6 files changed, 3 insertions(+), 129 deletions(-) diff --git a/frontend/components/dashboard/scan-terminal/AiPinnedCityCard.tsx b/frontend/components/dashboard/scan-terminal/AiPinnedCityCard.tsx index dc758866..a0f2463c 100644 --- a/frontend/components/dashboard/scan-terminal/AiPinnedCityCard.tsx +++ b/frontend/components/dashboard/scan-terminal/AiPinnedCityCard.tsx @@ -10,7 +10,6 @@ import { MobileDecisionCard } from "@/components/dashboard/scan-terminal/MobileD import { ModelEvidencePanel } from "@/components/dashboard/scan-terminal/ModelEvidencePanel"; import { WeatherDecisionBand } from "@/components/dashboard/scan-terminal/WeatherDecisionBand"; import { - buildMarketDecisionView, buildWeatherDecisionView, resolveExpectedHighCandidate, } from "@/components/dashboard/scan-terminal/city-card-decision-utils"; @@ -24,7 +23,6 @@ import { LoadingSignal } from "@/components/dashboard/scan-terminal/LoadingSigna import type { AiPinnedCity } from "@/components/dashboard/scan-terminal/types"; import { useAiCityForecast, - useCityMarketScan, } from "@/components/dashboard/scan-terminal/use-ai-city-card-data"; import { getDisplayAirportPrimary } from "@/lib/airport-observation-display"; import type { CityDetail, ScanOpportunityRow } from "@/lib/dashboard-types"; @@ -184,28 +182,6 @@ function buildModelFreshnessValue(detail: CityDetail | null, locale: string, isE ); } -function buildMarketFreshnessValue({ - isEn, - marketScan, - marketStatus, -}: { - isEn: boolean; - marketScan: ReturnType["marketScan"]; - marketStatus: ReturnType["marketStatus"]; -}) { - if (marketStatus === "loading") return isEn ? "syncing" : "同步中"; - if (!marketScan?.available) return isEn ? "temporarily unavailable" : "暂不可用"; - const quoteAgeMs = Number( - marketScan.quote_age_ms ?? - marketScan.yes_token?.quote_age_ms ?? - marketScan.no_token?.quote_age_ms, - ); - if (Number.isFinite(quoteAgeMs) && quoteAgeMs >= 0) { - return formatFreshnessAge(quoteAgeMs / 60_000, isEn); - } - return isEn ? "synced" : "已同步"; -} - export function AiPinnedCityCard({ item, detail, @@ -287,11 +263,6 @@ export function AiPinnedCityCard({ locale, report, }); - const { marketScan, marketStatus } = useCityMarketScan({ - detail, - detailCityName, - enabled: Boolean(detail), - }); const isRefreshing = refreshingDetail || aiForecast.status === "loading"; const [isCompactCard, setIsCompactCard] = useState(false); @@ -382,13 +353,6 @@ export function AiPinnedCityCard({ debNumber != null ? formatTemperatureValue(debNumber, tempSymbol, { digits: 1 }) : "--"; - const marketDecisionView = buildMarketDecisionView({ - expectedHigh: decisionExpectedHighNumber, - isEn, - marketScan, - marketStatus, - tempSymbol, - }); const aiMeta = aiCityForecast?._polyweather_meta || null; const guardReason = aiMeta?.deterministic_guard_reason || {}; const observationStale = Boolean( @@ -436,7 +400,6 @@ export function AiPinnedCityCard({ aiRuleEvidenceMode, isEn, isHkoObservation, - marketDecisionView, modelHighlyConsistent, needsNextBulletin, observationStale, @@ -451,16 +414,6 @@ export function AiPinnedCityCard({ value: buildModelFreshnessValue(detail, locale, isEn), tone: "fresh" as const, }, - { - label: isEn ? "Market" : "市场价格", - value: buildMarketFreshnessValue({ isEn, marketScan, marketStatus }), - tone: - marketDecisionView.status === "ready" - ? ("fresh" as const) - : marketDecisionView.status === "loading" - ? ("loading" as const) - : ("stale" as const), - }, ]; const freshnessSeparator = isEn ? ": " : ":"; const localizedRisksRaw = @@ -480,17 +433,6 @@ export function AiPinnedCityCard({ (isEn ? aiForecast.payload?.reason_en : aiForecast.payload?.reason_zh) || aiForecast.payload?.reason || ""; - const marketLineText = - marketDecisionView.status === "ready" - ? `${marketDecisionView.bucketLabel} · ${marketDecisionView.priceText}` - : marketDecisionView.status === "loading" - ? isEn - ? "syncing" - : "同步中" - : isEn - ? "temporarily unavailable" - : "暂不可用"; - const collapseId = `ai-city-body-${normalizeCityKey(item.cityName) || item.addedAt}`; const loadingCopy = getCityLoadingCopy({ isEn, isHkoObservation }); const handleRefresh = (event: MouseEvent) => { @@ -522,7 +464,6 @@ export function AiPinnedCityCard({ tabIndex={-1} data-ai-status={decisionState.aiStatus} data-evidence-quality={decisionState.evidenceQuality} - data-market-status={decisionState.marketStatus} data-recommendation={decisionState.recommendation} data-urgency={decisionState.urgency} > @@ -550,8 +491,6 @@ export function AiPinnedCityCard({ isRefreshing={isRefreshing} localModelSupportNote={localModelSupportNote} localizedFinalJudgment={localizedFinalJudgment} - marketDecisionView={marketDecisionView} - marketLineText={marketLineText} onRefresh={handleRefresh} onRemove={handleRemove} peakWindow={peakWindow} @@ -587,8 +526,6 @@ export function AiPinnedCityCard({ decisionView={decisionView} decisionWhyText={decisionState.primaryReason} isEn={isEn} - marketDecisionView={marketDecisionView} - marketLineText={marketLineText} paceDeltaText={paceView?.deltaText || "--"} /> diff --git a/frontend/components/dashboard/scan-terminal/MobileDecisionCard.tsx b/frontend/components/dashboard/scan-terminal/MobileDecisionCard.tsx index 234a38de..7b52a0ee 100644 --- a/frontend/components/dashboard/scan-terminal/MobileDecisionCard.tsx +++ b/frontend/components/dashboard/scan-terminal/MobileDecisionCard.tsx @@ -11,9 +11,7 @@ import { type StatusTone, } from "@/components/dashboard/scan-terminal/CityStatusTags"; import { LoadingSignal } from "@/components/dashboard/scan-terminal/LoadingSignal"; -import { MarketDecisionLine } from "@/components/dashboard/scan-terminal/MarketDecisionLine"; import { ModelEvidencePanel } from "@/components/dashboard/scan-terminal/ModelEvidencePanel"; -import type { MarketDecisionView } from "@/components/dashboard/scan-terminal/city-card-decision-utils"; import type { CityDecisionState } from "@/components/dashboard/scan-terminal/city-decision-state"; import { getCityLoadingCopy, @@ -48,8 +46,6 @@ export function MobileDecisionCard({ isRefreshing, localModelSupportNote, localizedFinalJudgment, - marketDecisionView, - marketLineText, onRefresh, onRemove, peakWindow, @@ -78,8 +74,6 @@ export function MobileDecisionCard({ isRefreshing: boolean; localModelSupportNote: string; localizedFinalJudgment: string; - marketDecisionView: MarketDecisionView; - marketLineText: string; onRefresh: (event: MouseEvent) => void; onRemove: (event: MouseEvent) => void; peakWindow: string; @@ -140,11 +134,6 @@ export function MobileDecisionCard({

{decisionState.primaryReason}

- {!detail ? (
diff --git a/frontend/components/dashboard/scan-terminal/WeatherDecisionBand.tsx b/frontend/components/dashboard/scan-terminal/WeatherDecisionBand.tsx index b2fb2a47..fb7d48f0 100644 --- a/frontend/components/dashboard/scan-terminal/WeatherDecisionBand.tsx +++ b/frontend/components/dashboard/scan-terminal/WeatherDecisionBand.tsx @@ -1,25 +1,17 @@ "use client"; import clsx from "clsx"; -import type { - MarketDecisionView, - WeatherDecisionView, -} from "@/components/dashboard/scan-terminal/city-card-decision-utils"; -import { MarketDecisionLine } from "@/components/dashboard/scan-terminal/MarketDecisionLine"; +import type { WeatherDecisionView } from "@/components/dashboard/scan-terminal/city-card-decision-utils"; export function WeatherDecisionBand({ decisionView, decisionWhyText, isEn, - marketDecisionView, - marketLineText, paceDeltaText, }: { decisionView: WeatherDecisionView; decisionWhyText: string; isEn: boolean; - marketDecisionView: MarketDecisionView; - marketLineText: string; paceDeltaText: string; }) { return ( @@ -28,11 +20,6 @@ export function WeatherDecisionBand({ {decisionView.kicker} {decisionView.action}

{decisionWhyText}

-
@@ -42,10 +29,6 @@ export function WeatherDecisionBand({ {isEn ? "Path delta" : "路径偏差"} {paceDeltaText} - - {isEn ? "Quote status" : "报价状态"}{" "} - {marketDecisionView.status === "ready" ? (isEn ? "Ready" : "已同步") : marketDecisionView.status === "loading" ? (isEn ? "Loading" : "同步中") : (isEn ? "Unavailable" : "不可用")} -
); diff --git a/frontend/components/dashboard/scan-terminal/__tests__/buildCityDecisionState.test.ts b/frontend/components/dashboard/scan-terminal/__tests__/buildCityDecisionState.test.ts index ad26f5ce..28001006 100644 --- a/frontend/components/dashboard/scan-terminal/__tests__/buildCityDecisionState.test.ts +++ b/frontend/components/dashboard/scan-terminal/__tests__/buildCityDecisionState.test.ts @@ -29,7 +29,6 @@ export function runTests() { aiRuleEvidenceMode: false, isEn: false, isHkoObservation: false, - marketDecisionView: market("ready"), modelHighlyConsistent: true, needsNextBulletin: false, observationStale: false, @@ -51,7 +50,6 @@ export function runTests() { aiRuleEvidenceMode: false, isEn: false, isHkoObservation: false, - marketDecisionView: market("unavailable"), modelHighlyConsistent: false, needsNextBulletin: false, observationStale: false, @@ -61,9 +59,6 @@ export function runTests() { peakHasPassed: false, }); - assert.equal(marketUnavailable.marketStatus, "unavailable"); - assert.match(marketUnavailable.primaryReason, /暂无可交易价格/); - assert.doesNotMatch(marketUnavailable.primaryReason, /未接入|系统缺失|系统坏/); const fallback = buildCityDecisionState({ aiCityForecast: null, @@ -71,7 +66,6 @@ export function runTests() { aiRuleEvidenceMode: true, isEn: false, isHkoObservation: false, - marketDecisionView: market("ready"), modelHighlyConsistent: false, needsNextBulletin: false, observationStale: false, @@ -91,7 +85,6 @@ export function runTests() { aiRuleEvidenceMode: false, isEn: false, isHkoObservation: false, - marketDecisionView: market("ready"), modelHighlyConsistent: false, needsNextBulletin: true, observationStale: false, diff --git a/frontend/components/dashboard/scan-terminal/__tests__/buildStatusTags.test.ts b/frontend/components/dashboard/scan-terminal/__tests__/buildStatusTags.test.ts index 424fc1db..2eb82836 100644 --- a/frontend/components/dashboard/scan-terminal/__tests__/buildStatusTags.test.ts +++ b/frontend/components/dashboard/scan-terminal/__tests__/buildStatusTags.test.ts @@ -22,7 +22,6 @@ export function runTests() { aiRuleEvidenceMode: false, isEn: false, isHkoObservation: false, - marketDecisionView: readyMarket, modelHighlyConsistent: true, needsNextBulletin: false, observationStale: false, @@ -47,7 +46,6 @@ export function runTests() { aiRuleEvidenceMode: false, isEn: false, isHkoObservation: false, - marketDecisionView: readyMarket, modelHighlyConsistent: false, needsNextBulletin: false, observationStale: true, diff --git a/frontend/components/dashboard/scan-terminal/city-decision-state.ts b/frontend/components/dashboard/scan-terminal/city-decision-state.ts index b4731a6f..bcf0c5c7 100644 --- a/frontend/components/dashboard/scan-terminal/city-decision-state.ts +++ b/frontend/components/dashboard/scan-terminal/city-decision-state.ts @@ -1,4 +1,3 @@ -import type { MarketDecisionView } from "@/components/dashboard/scan-terminal/city-card-decision-utils"; import type { AiCityForecastPayload, AiCityForecastState, @@ -12,7 +11,6 @@ export type CityDecisionAiStatus = | "deepseek-loading" | "complete" | "fallback"; -export type CityDecisionMarketStatus = "ready" | "loading" | "unavailable"; export type StatusBadgeTone = "green" | "blue" | "amber" | "red" | "muted"; export type StatusBadge = { @@ -27,8 +25,6 @@ export type CityDecisionState = { aiStatus: CityDecisionAiStatus; aiStatusLabel: string; aiStatusTone: StatusBadgeTone; - marketStatus: CityDecisionMarketStatus; - marketStatusTone: StatusBadgeTone; badges: StatusBadge[]; primaryReason: string; }; @@ -82,19 +78,12 @@ function resolveAiStatusView(aiStatus: CityDecisionAiStatus, isEn: boolean) { }; } -function resolveMarketTone(status: CityDecisionMarketStatus): StatusBadgeTone { - if (status === "ready") return "green"; - if (status === "loading") return "blue"; - return "muted"; -} - export function buildCityDecisionState({ aiCityForecast, aiForecast, aiRuleEvidenceMode, isEn, isHkoObservation, - marketDecisionView, modelHighlyConsistent, needsNextBulletin, observationStale, @@ -108,7 +97,6 @@ export function buildCityDecisionState({ aiRuleEvidenceMode: boolean; isEn: boolean; isHkoObservation: boolean; - marketDecisionView: MarketDecisionView; modelHighlyConsistent: boolean; needsNextBulletin: boolean; observationStale: boolean; @@ -119,11 +107,9 @@ export function buildCityDecisionState({ }): CityDecisionState { const aiStatus = resolveAiStatus({ aiCityForecast, aiForecast, aiRuleEvidenceMode }); const aiStatusView = resolveAiStatusView(aiStatus, isEn); - const marketStatus = marketDecisionView.status; - const marketStatusTone = resolveMarketTone(marketStatus); const evidenceQuality: CityDecisionEvidenceQuality = observationStale ? "stale" - : aiStatus === "fallback" || marketStatus === "unavailable" + : aiStatus === "fallback" ? "mixed" : "fresh"; const urgency: CityDecisionUrgency = peakHasPassed @@ -152,11 +138,7 @@ export function buildCityDecisionState({ ? isEn ? "Observation is stale and needs the next report. Use only as background reference until fresh data arrives." : "观测已过旧,需要下一报文确认。当前数据仅作背景参考,建议等待新报文后再做判断。" - : marketStatus === "unavailable" - ? isEn - ? "Weather evidence is usable, but no tradable quote is available yet. Weather judgment still applies." - : "天气证据可参考,但暂无可交易价格。天气判断仍可参考,无需急于操作。" - : modelHighlyConsistent + : modelHighlyConsistent ? isEn ? "Models are aligned; wait for observation confirmation. A clear direction should emerge after the next report." : "模型高度一致,等待实测确认。下一报文后方向会更明确。" @@ -205,12 +187,6 @@ export function buildCityDecisionState({ tone: aiStatusView.tone, } : null, - marketStatus === "unavailable" - ? { - label: isEn ? "Market unavailable" : "市场价暂不可用", - tone: marketStatusTone, - } - : null, modelHighlyConsistent ? { label: isEn ? "Models agree" : "模型高度一致", @@ -232,8 +208,6 @@ export function buildCityDecisionState({ aiStatus, aiStatusLabel: aiStatusView.label, aiStatusTone: aiStatusView.tone, - marketStatus, - marketStatusTone, badges, primaryReason, };