From f0e1c14644371c648fee91e5143d2367c42bf4eb Mon Sep 17 00:00:00 2001 From: mmc <1556375442@qq.com> Date: Fri, 4 Sep 2026 16:22:28 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=9C=B0=E5=9B=BE=20?= =?UTF-8?q?=E8=B7=B3=E8=BD=AC=E7=9A=84=E9=A1=BA=E5=BA=8F=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .workbuddy/memory/2026-09-04.md | 19 ++++++++ src/components/Map.jsx | 47 ++++++++++++++----- src/components/devices/DeviceOverviewPage.tsx | 2 +- src/components/devices/RobotTaskPage.tsx | 1 + src/components/devices/WayLinePage.tsx | 5 +- 5 files changed, 59 insertions(+), 15 deletions(-) create mode 100644 .workbuddy/memory/2026-09-04.md diff --git a/.workbuddy/memory/2026-09-04.md b/.workbuddy/memory/2026-09-04.md new file mode 100644 index 0000000..cdbd101 --- /dev/null +++ b/.workbuddy/memory/2026-09-04.md @@ -0,0 +1,19 @@ +# 2026-09-04 + +### 任务1:补全 SOP v2.0 文档 +- 源文件:D:\工作\绩效文档\202609\机器人智慧服务系统_SOP_v2.0_目录可点击.docx +- 输出:同上 _已完善.docx +- 工作内容: + - 为 19 章 + 5 附录共 24 个标题插入 Word 书签 + - 将目录条目改造为内部超链接(HYPERLINK \\l 锚点) + - 用 matplotlib 生成 27 张界面示意图,替换所有【截图 X-Y】占位符 + - 在登录、监控、设备控制、任务控制、AI 编排等关键位置补充 💡 使用提示 +- 工具:python-docx + matplotlib + Pillow,隔离 venv:C:\Users\15563\.workbuddy\binaries\python\envs\sopenv + +### 任务2:编写版本发布说明(V2.4.1 / V2.4.0 / V2.3.x) +- 输出:D:\工作\绩效文档\202609\机器人智慧服务系统_版本发布说明_V2.4.1.docx(42.9 KB) +- 工作内容: + - 基于 git log 三个分支(master / feat-suanfaceshi-0817 / feat-yanshi0821 / feat-lazyLoad-0602)梳理实际迭代历史 + - 覆盖三个发布版本,含 1.1-1.6 / 2.1-2.6 / 3.1-3.5 完整结构 + - 含 1 张能力对比表(4 列 14 行) + - 22 个 Word 书签便于跨文档引用 \ No newline at end of file diff --git a/src/components/Map.jsx b/src/components/Map.jsx index 4763133..fd6b295 100644 --- a/src/components/Map.jsx +++ b/src/components/Map.jsx @@ -55,6 +55,21 @@ const CesiumMap = React.forwardRef(({ ifClear, ifClearPlanLine, ifClearNavLine, const isCameraFlyingRef = useRef(false); const lastFlightPromiseRef = useRef(null); + // ============================== + // 飞行优先级调度:优先级高的可打断低的;同级不重复起飞 + // realtime(100) > focus(90) > devices(80) > track(70) > layer(10) + // ============================== + const lastFlightPriorityRef = useRef(-1); + const FLIGHT_PRIORITY = { realtime: 100, focus: 90, devices: 80, track: 70, layer: 10 }; + const flyToView = (viewer, priority, config) => { + if (!viewer) return; + if (priority <= lastFlightPriorityRef.current) return; // 同级或更低不重复/覆盖;更高优先级才打断 + lastFlightPriorityRef.current = priority; + try { viewer.camera.cancelFlight(); } catch (e) { /* 忽略取消异常 */ } + viewer.camera.flyTo(config); + }; + const resetFlightPriority = () => { lastFlightPriorityRef.current = -1; }; + const [drawPoints, setDrawPoints] = useState([]); const drawLineRef = useRef(null); const pointEntitiesRef = useRef([]); @@ -262,7 +277,7 @@ const CesiumMap = React.forwardRef(({ ifClear, ifClearPlanLine, ifClearNavLine, const p = validPoints[0]; viewer.scene.requestRender(); - viewer.camera.flyTo({ + flyToView(viewer, FLIGHT_PRIORITY.track, { destination: Cesium.Cartesian3.fromDegrees( p.lng, p.lat, @@ -284,7 +299,7 @@ const CesiumMap = React.forwardRef(({ ifClear, ifClearPlanLine, ifClearNavLine, viewer.scene.requestRender(); - viewer.camera.flyTo({ + flyToView(viewer, FLIGHT_PRIORITY.track, { destination: rectangle, duration: 1.2 }); @@ -400,7 +415,7 @@ const CesiumMap = React.forwardRef(({ ifClear, ifClearPlanLine, ifClearNavLine, const p = validPoints[0]; viewer.scene.requestRender(); - viewer.camera.flyTo({ + flyToView(viewer, FLIGHT_PRIORITY.track, { destination: Cesium.Cartesian3.fromDegrees( p.lng, p.lat, @@ -422,7 +437,7 @@ const CesiumMap = React.forwardRef(({ ifClear, ifClearPlanLine, ifClearNavLine, viewer.scene.requestRender(); - viewer.camera.flyTo({ + flyToView(viewer, FLIGHT_PRIORITY.track, { destination: rectangle, duration: 1.2 }); @@ -435,6 +450,7 @@ const CesiumMap = React.forwardRef(({ ifClear, ifClearPlanLine, ifClearNavLine, }; useEffect(() => { + resetFlightPriority(); if (polyPoints && polyPoints.length > 0) { drawPolygon(polyPoints) } else { @@ -452,6 +468,7 @@ const CesiumMap = React.forwardRef(({ ifClear, ifClearPlanLine, ifClearNavLine, useEffect(() => { + resetFlightPriority(); if (viewerRef.current) { drawTrackLine(points); } @@ -527,7 +544,7 @@ const CesiumMap = React.forwardRef(({ ifClear, ifClearPlanLine, ifClearNavLine, `; } -const getCursorLngLat = (viewer, screenPos) => { + const getCursorLngLat = (viewer, screenPos) => { const cartesian = viewer.camera.pickEllipsoid(screenPos, viewer.scene.globe.ellipsoid); if (!window.Cesium.defined(cartesian)) return { lon: NaN, lat: NaN }; const cartographic = window.Cesium.Cartographic.fromCartesian(cartesian); @@ -846,7 +863,7 @@ const getCursorLngLat = (viewer, screenPos) => { const centerLon = (minx + maxx) / 2; const centerLat = (miny + maxy) / 2; - viewerRef.current.camera.flyTo({ + flyToView(viewerRef.current, FLIGHT_PRIORITY.layer, { // 固定高度,第三个参数就是高度(单位米) destination: window.Cesium.Cartesian3.fromDegrees(centerLon, centerLat, flyHeight), orientation: { @@ -994,9 +1011,12 @@ const getCursorLngLat = (viewer, screenPos) => { }; }, []); - // 根据场站映射图层定位地图 + // 根据场站映射图层定位地图:切换场站时始终飞向该场站的图层 + // 不再用可能滞后的 devices 判断(避免用上一场站的机器决策); + // 若场站有机器,由 devices 效果按更高优先级接管飞向机器 useEffect(() => { if (!mapLayer || !viewerRef.current) return; + resetFlightPriority(); flyToLayer(mapLayer, envConfig.geoserver_url, 100); }, [mapLayer]); @@ -1054,7 +1074,7 @@ const getCursorLngLat = (viewer, screenPos) => { } }); - viewer.camera.flyTo({ + flyToView(viewer, FLIGHT_PRIORITY.focus, { destination: Cesium.Cartesian3.fromDegrees(Number(focusLocation.lon), Number(focusLocation.lat), focusLocation.height || 800), orientation: { heading: Cesium.Math.toRadians(0.0), @@ -1081,7 +1101,7 @@ const getCursorLngLat = (viewer, screenPos) => { }); const rectangle = window.Cesium.Rectangle.fromDegrees(west, south, east, north); - viewer.camera.flyTo({ destination: rectangle, duration: 1.5 }); + flyToView(viewer, FLIGHT_PRIORITY.devices, { destination: rectangle, duration: 1.5 }); } function parseLngLat(lon, lat) { @@ -1530,7 +1550,7 @@ const getCursorLngLat = (viewer, screenPos) => { const p = validPositions[0]; - viewer.camera.flyTo({ + flyToView(viewer, FLIGHT_PRIORITY.devices, { destination: Cesium.Cartesian3.fromDegrees( p.lon, p.lat, @@ -1548,7 +1568,7 @@ const getCursorLngLat = (viewer, screenPos) => { maxLat ); - viewer.camera.flyTo({ + flyToView(viewer, FLIGHT_PRIORITY.devices, { destination: rectangle, duration: 1.2 }); @@ -1731,6 +1751,7 @@ const getCursorLngLat = (viewer, screenPos) => { realtimeLastPointRef.current = null; realtimeHiddenRef.current = false; hasFlownRef.current = false; + resetFlightPriority(); // 恢复所有设备显示 entityMapRef.current.forEach(e => { @@ -1891,7 +1912,7 @@ const getCursorLngLat = (viewer, screenPos) => { hasFlownRef.current = true; if (getCameraMode() !== "realtime") return; - viewer.camera.flyTo({ + flyToView(viewer, FLIGHT_PRIORITY.realtime, { destination: Cesium.Cartesian3.fromDegrees(lon, lat, 30), orientation: { heading: 0, @@ -2031,7 +2052,7 @@ const getCursorLngLat = (viewer, screenPos) => { hasFlownRef.current = true; if (getCameraMode() !== "realtime") return; - viewer.camera.flyTo({ + flyToView(viewer, FLIGHT_PRIORITY.realtime, { destination: Cesium.Cartesian3.fromDegrees( lon, diff --git a/src/components/devices/DeviceOverviewPage.tsx b/src/components/devices/DeviceOverviewPage.tsx index b930b2e..88afea9 100644 --- a/src/components/devices/DeviceOverviewPage.tsx +++ b/src/components/devices/DeviceOverviewPage.tsx @@ -642,7 +642,7 @@ export default function DeviceOverviewPage() {
■{t('devices.s9')}
- + diff --git a/src/components/devices/RobotTaskPage.tsx b/src/components/devices/RobotTaskPage.tsx index 6c5c918..48879bf 100644 --- a/src/components/devices/RobotTaskPage.tsx +++ b/src/components/devices/RobotTaskPage.tsx @@ -1245,6 +1245,7 @@ export default function RobotTaskPage() { ifClearNavLine={clearNavLine} ifClearPlanLine={clearPlanLine} routeMode={routeMode} + mapLayer={currentStation?.siteMapName} /> {/* 机器人状态悬浮面板 - 绝对定位左上角 */} diff --git a/src/components/devices/WayLinePage.tsx b/src/components/devices/WayLinePage.tsx index e56e9b6..7437ac0 100644 --- a/src/components/devices/WayLinePage.tsx +++ b/src/components/devices/WayLinePage.tsx @@ -39,6 +39,8 @@ export default function WayLinePage({ onRefresh }) { const { t } = useTranslation(); const { userInfo } = useSelector((state: RootState) => state.user); const { stationId } = useSelector((state: RootState) => state.station); + const { currentStation } = useSelector((state: RootState) => state.station); + const fontSmall = 'clamp(10px, 0.7vw, 11px)'; const fontNormal = 'clamp(12px, 0.75vw, 13px)'; @@ -896,7 +898,8 @@ export default function WayLinePage({ onRefresh }) { style={{ ...cardStyle, marginBottom: 10 }} >
-