diff --git a/memory/2026-05-01.md b/memory/2026-05-01.md index ca9c8e9..707f7c4 100644 --- a/memory/2026-05-01.md +++ b/memory/2026-05-01.md @@ -300,3 +300,22 @@ - 风险与影响: - 影响范围:仅前端 `线路管理 -> 塔杆列表` 视图。 - 地图视图继续使用大页请求(500)避免点位显示回归。 + +## Work Log - 线路管理分布图移除 Slider(2026-05-01) + +- 背景: + - 用户在 Issue `FL-131` 新评论要求:去掉 slider。 + +- 本次改动(最小改动): + - 文件:`web/src/components/power-line-cesium-map.tsx` + - 移除右上角竖向缩放 Slider。 + - 移除“缩放比例 xx%”文本展示。 + - 清理 slider 配套的缩放百分比状态、相机监听与映射函数。 + - 保留原有 `+ / - / 居中重置` 缩放按钮能力不变。 + +- 验证: + - 遵循任务约束,未执行编译检查、未安装依赖。 + - 代码走读确认变更范围仅限 slider 相关逻辑。 + +- 风险与影响: + - 影响范围仅为线路管理分布图控件区 UI 与交互;后端接口和数据结构无影响。 diff --git a/web/src/components/power-line-cesium-map.tsx b/web/src/components/power-line-cesium-map.tsx index 802bb85..a4e3d16 100644 --- a/web/src/components/power-line-cesium-map.tsx +++ b/web/src/components/power-line-cesium-map.tsx @@ -1,7 +1,7 @@ "use client"; import { AimOutlined, MinusOutlined, PlusOutlined } from "@ant-design/icons"; -import { Alert, Button, Checkbox, Empty, Slider, Spin, Typography } from "antd"; +import { Alert, Button, Checkbox, Empty, Spin, Typography } from "antd"; import { useCallback, useEffect, useMemo, useRef, useState } from "react"; import { reloadOnceOnChunkError } from "@/lib/chunk-error"; @@ -36,11 +36,6 @@ type RouteViewState = { range: number; }; -type ZoomBounds = { - near: number; - far: number; -}; - declare global { interface Window { CESIUM_BASE_URL?: string; @@ -51,9 +46,6 @@ const MAP_HEIGHT = 560; const DEFAULT_ALTITUDE_M = 0; const MIN_CAMERA_RANGE = 1500; const MIN_ZOOM_STEP_RANGE = 300; -const ZOOM_PERCENT_MAX = 100; -const ZOOM_MIN_FACTOR = 0.22; -const ZOOM_MAX_FACTOR = 2.8; const DEFAULT_POINT_COLOR = "#38bdf8"; const RISK_COLOR_BY_LEVEL: Record = { "1": "#22c55e", @@ -147,31 +139,6 @@ function estimateRouteLengthKm(segments: RouteSegment[]): number { }, 0); } -function clamp(value: number, min: number, max: number): number { - return Math.min(Math.max(value, min), max); -} - -function rangeToZoomPercent(range: number, bounds: ZoomBounds): number { - const safeNear = Math.max(bounds.near, 1); - const safeFar = Math.max(bounds.far, safeNear + 1); - const safeRange = clamp(range, safeNear, safeFar); - const minLog = Math.log(safeNear); - const maxLog = Math.log(safeFar); - const valueLog = Math.log(safeRange); - const ratio = (valueLog - minLog) / (maxLog - minLog); - return Math.round((1 - ratio) * ZOOM_PERCENT_MAX); -} - -function zoomPercentToRange(percent: number, bounds: ZoomBounds): number { - const safeNear = Math.max(bounds.near, 1); - const safeFar = Math.max(bounds.far, safeNear + 1); - const ratio = clamp(percent, 0, ZOOM_PERCENT_MAX) / ZOOM_PERCENT_MAX; - const minLog = Math.log(safeNear); - const maxLog = Math.log(safeFar); - const valueLog = maxLog - ratio * (maxLog - minLog); - return Math.exp(valueLog); -} - export function PowerLineCesiumMap({ lineCode, lineName, @@ -182,13 +149,10 @@ export function PowerLineCesiumMap({ const viewerRef = useRef(null); const cesiumRef = useRef(null); const routeViewRef = useRef(null); - const zoomBoundsRef = useRef(null); - const sliderChangingRef = useRef(false); const [initError, setInitError] = useState(""); const [ready, setReady] = useState(false); const [colorByRisk, setColorByRisk] = useState(true); const [showLabels, setShowLabels] = useState(true); - const [zoomPercent, setZoomPercent] = useState(50); const sortedTowers = useMemo( () => [...towers].sort((a, b) => a.seq_no - b.seq_no), @@ -221,20 +185,6 @@ export function PowerLineCesiumMap({ const invalidGeoCount = Math.max(sortedTowers.length - towerGeoPoints.length, 0); const controlsDisabled = !ready || towerGeoPoints.length === 0; - const syncZoomPercentFromCamera = useCallback(() => { - const viewer = viewerRef.current; - const bounds = zoomBoundsRef.current; - if (!viewer || !bounds || sliderChangingRef.current) { - return; - } - const cameraHeight = viewer.camera.positionCartographic?.height; - if (!Number.isFinite(cameraHeight)) { - return; - } - const nextPercent = rangeToZoomPercent(Number(cameraHeight), bounds); - setZoomPercent((previous) => (previous === nextPercent ? previous : nextPercent)); - }, []); - const focusRoute = useCallback(() => { const viewer = viewerRef.current; const Cesium = cesiumRef.current; @@ -245,11 +195,8 @@ export function PowerLineCesiumMap({ viewer.camera.flyToBoundingSphere(routeView.boundingSphere, { duration: 0.75, offset: new Cesium.HeadingPitchRange(0, -0.65, routeView.range), - complete: () => { - syncZoomPercentFromCamera(); - }, }); - }, [syncZoomPercentFromCamera]); + }, []); const resolveZoomDistance = useCallback((): number => { const viewer = viewerRef.current; @@ -280,39 +227,6 @@ export function PowerLineCesiumMap({ viewer.camera.zoomOut(resolveZoomDistance()); }, [resolveZoomDistance]); - const handleZoomSliderChange = useCallback((value: number) => { - const viewer = viewerRef.current; - const Cesium = cesiumRef.current; - const bounds = zoomBoundsRef.current; - if (!viewer || !Cesium || !bounds) { - return; - } - sliderChangingRef.current = true; - setZoomPercent(value); - const nextHeight = zoomPercentToRange(value, bounds); - const current = viewer.camera.positionCartographic; - if (!current) { - sliderChangingRef.current = false; - return; - } - viewer.camera.flyTo({ - destination: Cesium.Cartesian3.fromRadians( - current.longitude, - current.latitude, - nextHeight, - ), - duration: 0.18, - complete: () => { - sliderChangingRef.current = false; - syncZoomPercentFromCamera(); - }, - cancel: () => { - sliderChangingRef.current = false; - syncZoomPercentFromCamera(); - }, - }); - }, [syncZoomPercentFromCamera]); - useEffect(() => { let cancelled = false; @@ -351,7 +265,6 @@ export function PowerLineCesiumMap({ viewer.scene.globe.baseColor = Cesium.Color.fromCssColorString("#0f172a"); viewer.scene.backgroundColor = Cesium.Color.fromCssColorString("#020617"); viewer.scene.screenSpaceCameraController.enableZoom = true; - viewer.camera.changed.addEventListener(syncZoomPercentFromCamera); const creditContainer = viewer.cesiumWidget.creditContainer as HTMLElement | null; if (creditContainer) { creditContainer.style.display = "none"; @@ -376,16 +289,14 @@ export function PowerLineCesiumMap({ return () => { cancelled = true; if (viewerRef.current && !viewerRef.current.isDestroyed()) { - viewerRef.current.camera.changed.removeEventListener(syncZoomPercentFromCamera); viewerRef.current.destroy(); } viewerRef.current = null; cesiumRef.current = null; routeViewRef.current = null; - zoomBoundsRef.current = null; setReady(false); }; - }, [syncZoomPercentFromCamera]); + }, []); useEffect(() => { const viewer = viewerRef.current; @@ -476,10 +387,6 @@ export function PowerLineCesiumMap({ boundingSphere, range, }; - zoomBoundsRef.current = { - near: Math.max(range * ZOOM_MIN_FACTOR, MIN_ZOOM_STEP_RANGE), - far: Math.max(range * ZOOM_MAX_FACTOR, MIN_CAMERA_RANGE), - }; focusRoute(); }, [ready, towerGeoPoints, routeSegments, colorByRisk, showLabels, focusRoute]); @@ -492,7 +399,6 @@ export function PowerLineCesiumMap({ setShowLabels(event.target.checked)}> 显示塔号 - 缩放比例 {zoomPercent}% 线路走向图:{lineName || "-"}({lineCode || "-"}),有效坐标 {towerGeoPoints.length}/{sortedTowers.length},缺失 {invalidGeoCount}, @@ -503,26 +409,6 @@ export function PowerLineCesiumMap({
-
- { - if (typeof value === "number") { - handleZoomSliderChange(value); - } - }} - /> -