From 4b0be4cb762e764a60adcbc5d6451d5d8f780ce3 Mon Sep 17 00:00:00 2001 From: rayd1o Date: Tue, 21 Apr 2026 22:49:39 +0800 Subject: [PATCH] release: bump version to 0.31.1 --- README.md | 10 +- VERSION | 2 +- docs/CHANGELOG.md | 37 ++- docs/deprecated/README.md | 5 + .../sisyphus-earth-architecture-refactor.md | 2 + .../deprecated/sisyphus-predicted-orbit.md | 2 + .../deprecated/sisyphus-ue5-client.md | 2 + .../sisyphus-webgl-instancing-satellites.md | 2 + docs/plans/README.md | 34 +++ .../agents-agent-architecture-plan.md} | 0 .../agents-agent-runtime-roadmap.md} | 6 +- .../agents-datasource-health-plan.md} | 0 .../agents-datasource-health-stage2-tasks.md} | 0 ...-situational-awareness-foundation-plan.md} | 0 .../backend-collected-data-history-plan.md} | 0 .../backend-system-settings-plan.md} | 0 .../earth-bgp-earth-rendering-plan.md} | 0 .../earth-bgp-observability-plan.md} | 0 .../earth-bgp-region-aggregation-plan.md} | 4 +- .../earth-celestial-background-plan.md | 0 docs/plans/earth-predicted-orbit-plan.md | 98 +++++++ .../earth-prefix-geography-plan.md} | 0 .../earth-real-terrain-plan.md | 0 ...h-renderer-architecture-separation-plan.md | 111 ++++++++ .../earth-webgl-instancing-satellites-plan.md | 82 ++++++ ...rontend-ai-playground-development-plan.md} | 4 +- .../ue5-mvp-fused-plan.md} | 34 +++ docs/technical/README.md | 26 ++ .../agents-aiprovider.md} | 0 .../backend-collectors.md} | 0 .../backend-system-service-control.md} | 0 .../earth-bgp-context.md} | 2 +- docs/technical/earth-frontend-context.md | 263 ++++++++++++++++++ ...rth-news-live-streams-collector-format.md} | 0 .../frontend-admin-frontend-context.md | 236 ++++++++++++++++ .../frontend-layout-guidelines.md | 0 .../ops-docker-compose-buildx-upgrade.md} | 0 docs/version-history.md | 3 +- frontend/package.json | 2 +- frontend/public/earth/css/layer-panel.css | 43 +++ frontend/public/earth/index.html | 2 +- frontend/public/earth/js/controls.js | 111 ++++++-- .../public/earth/js/layer-button-state.js | 46 +++ frontend/public/earth/js/main.js | 20 +- pyproject.toml | 2 +- uv.lock | 2 +- 46 files changed, 1129 insertions(+), 64 deletions(-) rename .sisyphus/plans/earth-architecture-refactor.md => docs/deprecated/sisyphus-earth-architecture-refactor.md (95%) rename .sisyphus/plans/predicted-orbit.md => docs/deprecated/sisyphus-predicted-orbit.md (95%) rename .sisyphus/plans/ue5_client.md => docs/deprecated/sisyphus-ue5-client.md (97%) rename .sisyphus/plans/webgl-instancing-satellites.md => docs/deprecated/sisyphus-webgl-instancing-satellites.md (97%) create mode 100644 docs/plans/README.md rename docs/{agents/agent-architecture-plan.md => plans/agents-agent-architecture-plan.md} (100%) rename docs/{agents/agent-runtime-roadmap.md => plans/agents-agent-runtime-roadmap.md} (95%) rename docs/{agents/datasource-health-plan.md => plans/agents-datasource-health-plan.md} (100%) rename docs/{agents/datasource-health-stage2-tasks.md => plans/agents-datasource-health-stage2-tasks.md} (100%) rename docs/{agents/situational-awareness-foundation-plan.md => plans/agents-situational-awareness-foundation-plan.md} (100%) rename docs/{backend/collected-data-history-plan.md => plans/backend-collected-data-history-plan.md} (100%) rename docs/{backend/system-settings-plan.md => plans/backend-system-settings-plan.md} (100%) rename docs/{earth/bgp-earth-rendering-plan.md => plans/earth-bgp-earth-rendering-plan.md} (100%) rename docs/{earth/bgp-observability-plan.md => plans/earth-bgp-observability-plan.md} (100%) rename docs/{earth/bgp-region-aggregation-plan.md => plans/earth-bgp-region-aggregation-plan.md} (98%) rename docs/{earth => plans}/earth-celestial-background-plan.md (100%) create mode 100644 docs/plans/earth-predicted-orbit-plan.md rename docs/{earth/prefix-geography-plan.md => plans/earth-prefix-geography-plan.md} (100%) rename docs/{earth => plans}/earth-real-terrain-plan.md (100%) create mode 100644 docs/plans/earth-renderer-architecture-separation-plan.md create mode 100644 docs/plans/earth-webgl-instancing-satellites-plan.md rename docs/{frontend/ai-playground-development-plan.md => plans/frontend-ai-playground-development-plan.md} (97%) rename docs/{ue5/ue5_mvp_fused_plan.md => plans/ue5-mvp-fused-plan.md} (95%) create mode 100644 docs/technical/README.md rename docs/{agents/aiprovider.md => technical/agents-aiprovider.md} (100%) rename docs/{backend/collectors.md => technical/backend-collectors.md} (100%) rename docs/{backend/system-service-control.md => technical/backend-system-service-control.md} (100%) rename docs/{earth/bgp-context.md => technical/earth-bgp-context.md} (99%) create mode 100644 docs/technical/earth-frontend-context.md rename docs/{earth/news-live-streams-collector-format.md => technical/earth-news-live-streams-collector-format.md} (100%) create mode 100644 docs/technical/frontend-admin-frontend-context.md rename docs/{frontend => technical}/frontend-layout-guidelines.md (100%) rename docs/{ops/docker-compose-buildx-upgrade.md => technical/ops-docker-compose-buildx-upgrade.md} (100%) create mode 100644 frontend/public/earth/js/layer-button-state.js diff --git a/README.md b/README.md index 1a46c0f3..a91acf37 100644 --- a/README.md +++ b/README.md @@ -328,11 +328,11 @@ AI_PROVIDER_SERVICE_TOKEN=change_me 详细文档: -- [docs/agents/aiprovider.md](/home/ray/dev/linkong/planet/docs/agents/aiprovider.md) +- [docs/technical/agents-aiprovider.md](/home/ray/dev/linkong/planet/docs/technical/agents-aiprovider.md) - [aiprovider/README.md](/home/ray/dev/linkong/planet/aiprovider/README.md) -- [docs/frontend/frontend-layout-guidelines.md](/home/ray/dev/linkong/planet/docs/frontend/frontend-layout-guidelines.md) -- [docs/frontend/ai-playground-development-plan.md](/home/ray/dev/linkong/planet/docs/frontend/ai-playground-development-plan.md) -- [docs/agents/situational-awareness-foundation-plan.md](/home/ray/dev/linkong/planet/docs/agents/situational-awareness-foundation-plan.md) +- [docs/technical/frontend-layout-guidelines.md](/home/ray/dev/linkong/planet/docs/technical/frontend-layout-guidelines.md) +- [docs/plans/frontend-ai-playground-development-plan.md](/home/ray/dev/linkong/planet/docs/plans/frontend-ai-playground-development-plan.md) +- [docs/plans/agents-situational-awareness-foundation-plan.md](/home/ray/dev/linkong/planet/docs/plans/agents-situational-awareness-foundation-plan.md) ## 前端页面布局规范 @@ -346,7 +346,7 @@ AI_PROVIDER_SERVICE_TOKEN=change_me 当前推荐参考实现: - [frontend/src/pages/BGP/BGP.tsx](/home/ray/dev/linkong/planet/frontend/src/pages/BGP/BGP.tsx) -- [docs/frontend/frontend-layout-guidelines.md](/home/ray/dev/linkong/planet/docs/frontend/frontend-layout-guidelines.md) +- [docs/technical/frontend-layout-guidelines.md](/home/ray/dev/linkong/planet/docs/technical/frontend-layout-guidelines.md) ## License diff --git a/VERSION b/VERSION index 26bea73e..f176c944 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.31.0 +0.31.1 diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index dab3b5a3..4de72e27 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -10,6 +10,23 @@ This project follows the repository versioning rule: ## [0.31.0] — 2026-04-21 +## [0.31.1] — 2026-04-21 + +### ✨ Highlights +- Earth 图层开关状态统一成可复用的 `active / loading` 状态机,首次启用地形和卫星时不再像按钮失效 +- 文档目录重构为 `docs/technical`、`docs/plans`、`docs/deprecated`,并吸收 `.sisyphus/plans` 中有价值的 Earth / 卫星 / UE5 草案 + +### 🔧 Improvements +- 新增 [layer-button-state.js](/home/ray/dev/linkong/planet/frontend/public/earth/js/layer-button-state.js),统一按钮 tooltip、`aria-busy`、禁用态和状态文本同步 +- 地形图层支持 hover/focus 预热与空闲预热,首次点击等待前移,加载中状态持续可见 +- 卫星图层启用前会立即切换为 `loading` 中间态,请求完成后再切回正常开关表现 + +### 🐛 Fixes +- 修复地形首次加载时通知过早消失、开关仍像关闭状态导致用户误判按钮损坏的问题 +- 修复卫星接口较慢时按钮没有任何中间态反馈的问题 + +--- + ### ✨ Features - Earth 新增"巡航展示"模式:自动轮播 BGP 异常事件,逐帧追踪连接线位置,支持外部交互立即中断序列(cancel notifier 模式) - 巡航目标事件点高亮显示:hover 外观 + 锁定脉冲动画,并与点击行为统一展示周边受影响卫星与海缆 @@ -310,7 +327,7 @@ Released: 2026-04-12 - Added [backend/app/api/v1/tv.py](/home/ray/dev/linkong/planet/backend/app/api/v1/tv.py), [backend/app/services/tv_streams.py](/home/ray/dev/linkong/planet/backend/app/services/tv_streams.py), and [backend/app/services/collectors/news_live_streams.py](/home/ray/dev/linkong/planet/backend/app/services/collectors/news_live_streams.py) to provide TV source configuration, public stream payloads, a guarded HLS proxy path, and a collector entry point for future world-news live-source ingestion. - Added the Earth TV HUD workspace through [frontend/public/earth/index.html](/home/ray/dev/linkong/planet/frontend/public/earth/index.html), [frontend/public/earth/js/tv.js](/home/ray/dev/linkong/planet/frontend/public/earth/js/tv.js), and [frontend/public/earth/css/tv-panel.css](/home/ray/dev/linkong/planet/frontend/public/earth/css/tv-panel.css), including toolbar access, draggable/closable behavior, resize support, direct video/HLS playback, iframe fallback, and per-channel external-open handling. -- Added [docs/deprecated/earth-tv-live-module-plan.md](/home/ray/dev/linkong/planet/docs/deprecated/earth-tv-live-module-plan.md) and [docs/earth/news-live-streams-collector-format.md](/home/ray/dev/linkong/planet/docs/earth/news-live-streams-collector-format.md) to document the TV module rollout plan and the expected collector payload format for future curated live-channel ingestion. +- Added [docs/deprecated/earth-tv-live-module-plan.md](/home/ray/dev/linkong/planet/docs/deprecated/earth-tv-live-module-plan.md) and [docs/earth/technical/news-live-streams-collector-format.md](/home/ray/dev/linkong/planet/docs/technical/earth-news-live-streams-collector-format.md) to document the TV module rollout plan and the expected collector payload format for future curated live-channel ingestion. ### Improved @@ -396,7 +413,7 @@ Released: 2026-04-10 - Improved [frontend/src/pages/Playground/Playground.tsx](/home/ray/dev/linkong/planet/frontend/src/pages/Playground/Playground.tsx) and [frontend/src/index.css](/home/ray/dev/linkong/planet/frontend/src/index.css) by rebuilding Playground into a true chatbox workflow with persistent history, edit-and-resend behavior, grounded message actions, responsive composer behavior, bottom-stick scrolling, and tighter mobile layout handling. - Improved [frontend/src/components/AppLayout/AppLayout.tsx](/home/ray/dev/linkong/planet/frontend/src/components/AppLayout/AppLayout.tsx), [frontend/src/App.tsx](/home/ray/dev/linkong/planet/frontend/src/App.tsx), and [frontend/src/pages/Alerts/Alerts.tsx](/home/ray/dev/linkong/planet/frontend/src/pages/Alerts/Alerts.tsx) by reorganizing navigation around `采集与数据`, `专题观测`, and split alert entries so the app can scale to more observability and situational modules without turning the top-level UI into a single overloaded page. -- Improved [README.md](/home/ray/dev/linkong/planet/README.md) and [docs/agents/situational-awareness-foundation-plan.md](/home/ray/dev/linkong/planet/docs/agents/situational-awareness-foundation-plan.md) by documenting the current AI/alerts base, planned situational-awareness direction, and the new persistent Playground foundation. +- Improved [README.md](/home/ray/dev/linkong/planet/README.md) and [docs/agents/situational-awareness-foundation-plan.md](/home/ray/dev/linkong/planet/docs/plans/agents-situational-awareness-foundation-plan.md) by documenting the current AI/alerts base, planned situational-awareness direction, and the new persistent Playground foundation. ### Fixed @@ -434,7 +451,7 @@ Released: 2026-04-10 ### Improved - Improved [rules.md](/home/ray/dev/linkong/planet/rules.md) by adding mandatory release-workflow requirements and a new frontend layout constraint section covering single-screen workspaces, overflow ownership, tab-pane behavior, compact-mode expectations, and readable-card fallbacks. -- Improved [frontend-layout-guidelines.md](/home/ray/dev/linkong/planet/docs/frontend/frontend-layout-guidelines.md) by summarizing the recurring Earth, Playground, BGP, and admin-layout regressions into concrete constraints for future frontend work, including “prefer scrollbars over unreadable compression” and “do not treat every tab as a table pane.” +- Improved [frontend-layout-guidelines.md](/home/ray/dev/linkong/planet/docs/technical/frontend-layout-guidelines.md) by summarizing the recurring Earth, Playground, BGP, and admin-layout regressions into concrete constraints for future frontend work, including “prefer scrollbars over unreadable compression” and “do not treat every tab as a table pane.” ## 0.24.6 @@ -451,7 +468,7 @@ Released: 2026-04-10 - Improved [backend/app/services/bgp_incidents.py](/home/ray/dev/linkong/planet/backend/app/services/bgp_incidents.py) and [backend/app/services/bgp_enrichment.py](/home/ray/dev/linkong/planet/backend/app/services/bgp_enrichment.py) by avoiding historical full-table infrastructure scans, narrowing observation baseline payloads to required columns, and pushing more ASN filtering into the database. - Improved [backend/app/api/v1/alerts.py](/home/ray/dev/linkong/planet/backend/app/api/v1/alerts.py), [backend/app/api/v1/dashboard.py](/home/ray/dev/linkong/planet/backend/app/api/v1/dashboard.py), and [backend/app/api/v1/settings.py](/home/ray/dev/linkong/planet/backend/app/api/v1/settings.py) by collapsing several repeated count and settings queries into fewer aggregate or batched reads. - Improved [frontend/src/pages/BGP/BGP.tsx](/home/ray/dev/linkong/planet/frontend/src/pages/BGP/BGP.tsx), [frontend/src/index.css](/home/ray/dev/linkong/planet/frontend/src/index.css), and [frontend/src/components/MarkdownRenderer/MarkdownRenderer.tsx](/home/ray/dev/linkong/planet/frontend/src/components/MarkdownRenderer/MarkdownRenderer.tsx) by rebuilding the `AI 简报` tab layout, fixing saved brief scrolling behavior, and extending the renderer to handle tables, separators, and stored metadata comments more gracefully. -- Improved [docs/frontend/ai-playground-development-plan.md](/home/ray/dev/linkong/planet/docs/frontend/ai-playground-development-plan.md) by explicitly recording that the current BGP brief is only the first-stage summary flow and that regional prefix-geography analysis remains a planned Phase B follow-up. +- Improved [docs/frontend/plans/ai-playground-development-plan.md](/home/ray/dev/linkong/planet/docs/plans/frontend-ai-playground-development-plan.md) by explicitly recording that the current BGP brief is only the first-stage summary flow and that regional prefix-geography analysis remains a planned Phase B follow-up. ### Fixed @@ -557,8 +574,8 @@ Released: 2026-04-09 ### Added - Added [frontend/src/pages/Playground/Playground.tsx](/home/ray/dev/linkong/planet/frontend/src/pages/Playground/Playground.tsx), introducing the first dedicated AI testing workspace with provider status visibility, prompt/result tabs, and collapsible operator guidance. -- Added [docs/frontend/frontend-layout-guidelines.md](/home/ray/dev/linkong/planet/docs/frontend/frontend-layout-guidelines.md), documenting the repository standard for one-screen admin workspaces and module-local overflow handling. -- Added [docs/frontend/ai-playground-development-plan.md](/home/ray/dev/linkong/planet/docs/frontend/ai-playground-development-plan.md), capturing the completed AI gateway/UI work and the next delivery phases for BGP briefs, evidence-first inputs, and future agent runtime expansion. +- Added [docs/frontend/technical/frontend-layout-guidelines.md](/home/ray/dev/linkong/planet/docs/technical/frontend-layout-guidelines.md), documenting the repository standard for one-screen admin workspaces and module-local overflow handling. +- Added [docs/frontend/plans/ai-playground-development-plan.md](/home/ray/dev/linkong/planet/docs/plans/frontend-ai-playground-development-plan.md), capturing the completed AI gateway/UI work and the next delivery phases for BGP briefs, evidence-first inputs, and future agent runtime expansion. ### Improved @@ -663,7 +680,7 @@ Released: 2026-04-07 - Added [backend/app/services/ai_client.py](/home/ray/dev/linkong/planet/backend/app/services/ai_client.py), introducing an internal HTTP client for `backend -> aiprovider` calls with request-id propagation and lightweight retry. - Added [aiprovider/main.py](/home/ray/dev/linkong/planet/aiprovider/main.py), [aiprovider/provider_service.py](/home/ray/dev/linkong/planet/aiprovider/provider_service.py), and related config/schema files to stand up the dedicated adapter service. - Added [aiprovider/.env.example](/home/ray/dev/linkong/planet/aiprovider/.env.example) and [docker-compose.local-model.yml](/home/ray/dev/linkong/planet/docker-compose.local-model.yml) as ready-to-edit local-model templates. -- Added [docs/agents/aiprovider.md](/home/ray/dev/linkong/planet/docs/agents/aiprovider.md), documenting architecture, configuration, single-machine and multi-machine deployment, and cross-service calling patterns. +- Added [docs/agents/aiprovider.md](/home/ray/dev/linkong/planet/docs/technical/agents-aiprovider.md), documenting architecture, configuration, single-machine and multi-machine deployment, and cross-service calling patterns. - Added a dedicated `重启 AI Provider` control path in [Dashboard.tsx](/home/ray/dev/linkong/planet/frontend/src/pages/Dashboard/Dashboard.tsx), [system_control.py](/home/ray/dev/linkong/planet/backend/app/services/system_control.py), and [system_restart_runner.py](/home/ray/dev/linkong/planet/backend/scripts/system_restart_runner.py). ### Improved @@ -789,7 +806,7 @@ Released: 2026-04-02 - Added a new `IPtoASN Prefix Geography` collector in [iptoasn.py](/home/ray/dev/linkong/planet/backend/app/services/collectors/iptoasn.py) and registered it through [data_sources.yaml](/home/ray/dev/linkong/planet/backend/app/core/data_sources.yaml), [data_sources.py](/home/ray/dev/linkong/planet/backend/app/core/data_sources.py), [datasource_defaults.py](/home/ray/dev/linkong/planet/backend/app/core/datasource_defaults.py), and [collectors/__init__.py](/home/ray/dev/linkong/planet/backend/app/services/collectors/__init__.py). - Added country centroid helpers in [countries.py](/home/ray/dev/linkong/planet/backend/app/core/countries.py) so country-level prefix geography can produce map coordinates instead of only labels. -- Added a dedicated prefix-geography implementation note in [prefix-geography-plan.md](/home/ray/dev/linkong/planet/docs/earth/prefix-geography-plan.md). +- Added a dedicated prefix-geography implementation note in [prefix-geography-plan.md](/home/ray/dev/linkong/planet/docs/plans/earth-prefix-geography-plan.md). - Added recent `15m` collector activity dimensions to BGP coverage output in [bgp_collectors.py](/home/ray/dev/linkong/planet/backend/app/services/bgp_collectors.py) and [visualization.py](/home/ray/dev/linkong/planet/backend/app/api/v1/visualization.py). - Added additional BGP detector coverage for `route_leak_candidate` and `path_flap` flows in [test_bgp.py](/home/ray/dev/linkong/planet/backend/tests/test_bgp.py). - Added a local Earth cloud texture at [earth_clouds_1024.png](/home/ray/dev/linkong/planet/frontend/public/earth/assets/earth_clouds_1024.png) to avoid remote cloud-map dependency failures. @@ -804,7 +821,7 @@ Released: 2026-04-02 - Improved Earth event animation semantics in [bgp.js](/home/ray/dev/linkong/planet/frontend/public/earth/js/bgp.js) by separating icon pulse from ring expansion so the center marker can breathe while the ring expands independently. - Improved Earth texture reliability in [earth.js](/home/ray/dev/linkong/planet/frontend/public/earth/js/earth.js) by switching clouds back to a local static asset under the restored `public/earth` runtime. - Improved frontend boot noise in [frontend/index.html](/home/ray/dev/linkong/planet/frontend/index.html) by removing the default Vite favicon request that was generating irrelevant `vite.svg` timeouts during Earth debugging. -- Improved project planning docs in [bgp-context.md](/home/ray/dev/linkong/planet/docs/earth/bgp-context.md) and [TODO.md](/home/ray/dev/linkong/planet/TODO.md) so the roadmap now explicitly prioritizes `activity layer`, `prefix-centric geography`, and follow-up geofeed/whois work. +- Improved project planning docs in [bgp-context.md](/home/ray/dev/linkong/planet/docs/technical/earth-bgp-context.md) and [TODO.md](/home/ray/dev/linkong/planet/TODO.md) so the roadmap now explicitly prioritizes `activity layer`, `prefix-centric geography`, and follow-up geofeed/whois work. ### Fixed @@ -962,7 +979,7 @@ Released: 2026-03-31 - Added restart-task Redis helpers and whitelist command mapping in [system_control.py](/home/ray/dev/linkong/planet/backend/app/services/system_control.py). - Added detached restart runner orchestration in [system_restart_runner.py](/home/ray/dev/linkong/planet/backend/scripts/system_restart_runner.py). - Added `-d` / `--database` support to [planet.sh](/home/ray/dev/linkong/planet/planet.sh) for database-only restarts. -- Added restart control documentation in [system-service-control.md](/home/ray/dev/linkong/planet/docs/backend/system-service-control.md). +- Added restart control documentation in [system-service-control.md](/home/ray/dev/linkong/planet/docs/technical/backend-system-service-control.md). ### Improved diff --git a/docs/deprecated/README.md b/docs/deprecated/README.md index 7aa28489..30596739 100644 --- a/docs/deprecated/README.md +++ b/docs/deprecated/README.md @@ -15,3 +15,8 @@ - 明确写明“已完成”的计划,优先归档 - 已被正式实现替代、继续放在 `docs/` 根目录会误导后续开发的计划,归档 - 仍然指导未来开发、尚未完成或仍有明确执行价值的文档,继续保留在 `docs/` + +补充说明: + +- 一部分归档文档来自外部或临时工作流草案,例如 sisyphus 生成的初稿 +- 这类文档如果有可用内容,应先吸收到 `docs/plans/` 或 `docs/technical/`,再归档保留来源记录 diff --git a/.sisyphus/plans/earth-architecture-refactor.md b/docs/deprecated/sisyphus-earth-architecture-refactor.md similarity index 95% rename from .sisyphus/plans/earth-architecture-refactor.md rename to docs/deprecated/sisyphus-earth-architecture-refactor.md index 2ce150a7..6f5c9042 100644 --- a/.sisyphus/plans/earth-architecture-refactor.md +++ b/docs/deprecated/sisyphus-earth-architecture-refactor.md @@ -1,3 +1,5 @@ +> Archived note: this document was originally created by sisyphus and later reviewed against the main docs set. Useful content has been absorbed into `docs/plans/` where appropriate. + # 地球3D可视化架构重构计划 ## 背景 diff --git a/.sisyphus/plans/predicted-orbit.md b/docs/deprecated/sisyphus-predicted-orbit.md similarity index 95% rename from .sisyphus/plans/predicted-orbit.md rename to docs/deprecated/sisyphus-predicted-orbit.md index bc407693..3adae115 100644 --- a/.sisyphus/plans/predicted-orbit.md +++ b/docs/deprecated/sisyphus-predicted-orbit.md @@ -1,3 +1,5 @@ +> Archived note: this document was originally created by sisyphus and later reviewed against the main docs set. Useful content has been absorbed into `docs/plans/` where appropriate. + # 卫星预测轨道显示功能 ## TL;DR diff --git a/.sisyphus/plans/ue5_client.md b/docs/deprecated/sisyphus-ue5-client.md similarity index 97% rename from .sisyphus/plans/ue5_client.md rename to docs/deprecated/sisyphus-ue5-client.md index 2c8c619a..b230bd7f 100644 --- a/.sisyphus/plans/ue5_client.md +++ b/docs/deprecated/sisyphus-ue5-client.md @@ -1,3 +1,5 @@ +> Archived note: this document was originally created by sisyphus and later reviewed against the main docs set. Useful content has been absorbed into `docs/plans/` where appropriate. + # UE5 3D 大屏客户端开发计划 ## 项目概述 diff --git a/.sisyphus/plans/webgl-instancing-satellites.md b/docs/deprecated/sisyphus-webgl-instancing-satellites.md similarity index 97% rename from .sisyphus/plans/webgl-instancing-satellites.md rename to docs/deprecated/sisyphus-webgl-instancing-satellites.md index c9a61e95..30306151 100644 --- a/.sisyphus/plans/webgl-instancing-satellites.md +++ b/docs/deprecated/sisyphus-webgl-instancing-satellites.md @@ -1,3 +1,5 @@ +> Archived note: this document was originally created by sisyphus and later reviewed against the main docs set. Useful content has been absorbed into `docs/plans/` where appropriate. + # WebGL Instancing 卫星渲染优化计划 ## 背景 diff --git a/docs/plans/README.md b/docs/plans/README.md new file mode 100644 index 00000000..fd8b1424 --- /dev/null +++ b/docs/plans/README.md @@ -0,0 +1,34 @@ +# Plans Docs + +这里放“未来实施方案和未完成计划”的文档,重点回答: + +- 我们准备做什么 +- 为什么要做 +- 分几期做 +- 当前差距和下一步是什么 + +适合放入这里的内容: + +- Earth / BGP / 地形 / 天球实施方案 +- AI Playground 发展计划 +- backend / datasource / agent roadmap +- UE5 MVP 方案 + +当前重点入口: + +- [earth-renderer-architecture-separation-plan.md](/home/ray/dev/linkong/planet/docs/plans/earth-renderer-architecture-separation-plan.md) +- [earth-predicted-orbit-plan.md](/home/ray/dev/linkong/planet/docs/plans/earth-predicted-orbit-plan.md) +- [earth-webgl-instancing-satellites-plan.md](/home/ray/dev/linkong/planet/docs/plans/earth-webgl-instancing-satellites-plan.md) +- [earth-real-terrain-plan.md](/home/ray/dev/linkong/planet/docs/plans/earth-real-terrain-plan.md) +- [frontend-ai-playground-development-plan.md](/home/ray/dev/linkong/planet/docs/plans/frontend-ai-playground-development-plan.md) +- [ue5-mvp-fused-plan.md](/home/ray/dev/linkong/planet/docs/plans/ue5-mvp-fused-plan.md) + +不适合放入这里的内容: + +- 当前代码结构说明 +- 组件现状和实现入口 +- 已经落地的技术上下文说明 + +这些应放入: + +- [docs/technical/README.md](/home/ray/dev/linkong/planet/docs/technical/README.md) diff --git a/docs/agents/agent-architecture-plan.md b/docs/plans/agents-agent-architecture-plan.md similarity index 100% rename from docs/agents/agent-architecture-plan.md rename to docs/plans/agents-agent-architecture-plan.md diff --git a/docs/agents/agent-runtime-roadmap.md b/docs/plans/agents-agent-runtime-roadmap.md similarity index 95% rename from docs/agents/agent-runtime-roadmap.md rename to docs/plans/agents-agent-runtime-roadmap.md index c42a7469..ced65307 100644 --- a/docs/agents/agent-runtime-roadmap.md +++ b/docs/plans/agents-agent-runtime-roadmap.md @@ -10,9 +10,9 @@ This document connects three existing planning threads into one implementation r Related documents: -- [aiprovider](/home/ray/dev/linkong/planet/docs/agents/aiprovider.md) -- [datasource-health-plan](/home/ray/dev/linkong/planet/docs/agents/datasource-health-plan.md) -- [agent-architecture-plan](/home/ray/dev/linkong/planet/docs/agents/agent-architecture-plan.md) +- [aiprovider](/home/ray/dev/linkong/planet/docs/technical/agents-aiprovider.md) +- [datasource-health-plan](/home/ray/dev/linkong/planet/docs/plans/agents-datasource-health-plan.md) +- [agent-architecture-plan](/home/ray/dev/linkong/planet/docs/plans/agents-agent-architecture-plan.md) ## Big Picture diff --git a/docs/agents/datasource-health-plan.md b/docs/plans/agents-datasource-health-plan.md similarity index 100% rename from docs/agents/datasource-health-plan.md rename to docs/plans/agents-datasource-health-plan.md diff --git a/docs/agents/datasource-health-stage2-tasks.md b/docs/plans/agents-datasource-health-stage2-tasks.md similarity index 100% rename from docs/agents/datasource-health-stage2-tasks.md rename to docs/plans/agents-datasource-health-stage2-tasks.md diff --git a/docs/agents/situational-awareness-foundation-plan.md b/docs/plans/agents-situational-awareness-foundation-plan.md similarity index 100% rename from docs/agents/situational-awareness-foundation-plan.md rename to docs/plans/agents-situational-awareness-foundation-plan.md diff --git a/docs/backend/collected-data-history-plan.md b/docs/plans/backend-collected-data-history-plan.md similarity index 100% rename from docs/backend/collected-data-history-plan.md rename to docs/plans/backend-collected-data-history-plan.md diff --git a/docs/backend/system-settings-plan.md b/docs/plans/backend-system-settings-plan.md similarity index 100% rename from docs/backend/system-settings-plan.md rename to docs/plans/backend-system-settings-plan.md diff --git a/docs/earth/bgp-earth-rendering-plan.md b/docs/plans/earth-bgp-earth-rendering-plan.md similarity index 100% rename from docs/earth/bgp-earth-rendering-plan.md rename to docs/plans/earth-bgp-earth-rendering-plan.md diff --git a/docs/earth/bgp-observability-plan.md b/docs/plans/earth-bgp-observability-plan.md similarity index 100% rename from docs/earth/bgp-observability-plan.md rename to docs/plans/earth-bgp-observability-plan.md diff --git a/docs/earth/bgp-region-aggregation-plan.md b/docs/plans/earth-bgp-region-aggregation-plan.md similarity index 98% rename from docs/earth/bgp-region-aggregation-plan.md rename to docs/plans/earth-bgp-region-aggregation-plan.md index fa93b05b..75b6f0dc 100644 --- a/docs/earth/bgp-region-aggregation-plan.md +++ b/docs/plans/earth-bgp-region-aggregation-plan.md @@ -17,7 +17,7 @@ It is an aggregation/view-model layer: ## Why This Layer Exists -Current product gap from [bgp-context.md](/home/ray/dev/linkong/planet/docs/earth/bgp-context.md): +Current product gap from [bgp-context.md](/home/ray/dev/linkong/planet/docs/technical/earth-bgp-context.md): - incident density is naturally low - anomaly density is higher, but still not enough to keep the globe expressive all the time @@ -290,7 +290,7 @@ Each feature should include: ## Earth Rendering Plan -Detailed visual layering guidance is expanded in [bgp-earth-rendering-plan.md](/home/ray/dev/linkong/planet/docs/earth/bgp-earth-rendering-plan.md). +Detailed visual layering guidance is expanded in [bgp-earth-rendering-plan.md](/home/ray/dev/linkong/planet/docs/plans/earth-bgp-earth-rendering-plan.md). ### Layer Relationship diff --git a/docs/earth/earth-celestial-background-plan.md b/docs/plans/earth-celestial-background-plan.md similarity index 100% rename from docs/earth/earth-celestial-background-plan.md rename to docs/plans/earth-celestial-background-plan.md diff --git a/docs/plans/earth-predicted-orbit-plan.md b/docs/plans/earth-predicted-orbit-plan.md new file mode 100644 index 00000000..df963f24 --- /dev/null +++ b/docs/plans/earth-predicted-orbit-plan.md @@ -0,0 +1,98 @@ +# Earth Predicted Orbit Plan + +> Source note: this plan absorbs useful ideas from a sisyphus-created draft formerly stored at `.sisyphus/plans/predicted-orbit.md`. + +## Goal + +在 Earth 中锁定卫星时,显示“预测轨道”而不是只有历史尾迹: + +- 从当前时刻开始 +- 绕地球一圈 +- 当前点最亮 +- 向后沿轨道逐步衰减 + +## Current State + +当前已经有: + +- 卫星历史轨迹 +- 锁定卫星 +- 轨道高亮与相关联动 + +但“预测轨道”仍然不是一套稳定、可验证的单独功能计划。 + +## Why It Is Valuable + +预测轨道可以明显提升: + +- 锁定卫星后的空间可读性 +- 轨道类型辨识 +- 演示解释力 + +相比短历史尾迹,预测轨道更符合用户对“这颗卫星接下来会怎么走”的预期。 + +## Scope + +### Phase 1 + +- 锁定卫星时显示一整圈预测轨道 +- 解锁时隐藏 +- 不替代现有普通轨迹系统 + +### Phase 2 + +- 根据轨道类型调整采样率 +- GEO / MEO / LEO 不同密度 +- 进一步减少 fallback 轨迹的比例 + +## Implementation Direction + +### 1. Orbit period + +基于 `meanMotion` 估算轨道周期。 + +### 2. Predicted samples + +以固定采样步长从 `now -> now + period` 推算轨迹点。 + +### 3. Render object lifecycle + +预测轨道应是一个独立渲染对象: + +- show +- update +- hide +- dispose + +### 4. Visual semantics + +预测轨道不应与普通尾迹混淆: + +- 更稳定 +- 更完整 +- 透明度沿轨道衰减 +- 当前点附近更亮 + +## Known Risks + +### 1. TLE propagation gaps + +部分卫星可能出现 SGP4 计算不足,需要 fallback。 + +### 2. Multiple orbit lines + +必须确保: + +- 锁定切换前先清旧轨道 +- 页面隐藏/销毁时清理 + +### 3. Performance + +GEO 轨道点数高,采样率需要按轨道类型分层。 + +## Acceptance + +1. 锁定单颗卫星时只显示一条预测轨道 +2. 解锁后轨道立即清除 +3. 不同轨道类型下点数可控 +4. 页面切换回来不会闪出旧轨道残留 diff --git a/docs/earth/prefix-geography-plan.md b/docs/plans/earth-prefix-geography-plan.md similarity index 100% rename from docs/earth/prefix-geography-plan.md rename to docs/plans/earth-prefix-geography-plan.md diff --git a/docs/earth/earth-real-terrain-plan.md b/docs/plans/earth-real-terrain-plan.md similarity index 100% rename from docs/earth/earth-real-terrain-plan.md rename to docs/plans/earth-real-terrain-plan.md diff --git a/docs/plans/earth-renderer-architecture-separation-plan.md b/docs/plans/earth-renderer-architecture-separation-plan.md new file mode 100644 index 00000000..649c20ac --- /dev/null +++ b/docs/plans/earth-renderer-architecture-separation-plan.md @@ -0,0 +1,111 @@ +# Earth Renderer / Logic Separation Plan + +> Source note: this plan absorbs useful ideas from a sisyphus-created draft formerly stored at `.sisyphus/plans/earth-architecture-refactor.md`. + +## Goal + +将 Earth 前端继续往“逻辑层 / 状态层 / 渲染层”分离推进,降低后续这几类工作的耦合成本: + +- Three.js 渲染重构 +- 部分图层替换实现 +- 未来 UE / Cesium 客户端迁移 +- Earth 行为逻辑复用 + +## Why This Matters + +当前 Earth 已经有一些良好分层,例如: + +- 图层显隐入口 +- Cable state 枚举与状态 map +- 交互逻辑与实际视觉效果的部分分离 + +但还没有形成一套更明确的统一规则。现在的风险是: + +- 同一类对象的 hover / locked / hidden / loading 语义不一致 +- 状态和渲染更新散落在多个模块 +- 后续再加新图层时容易复制旧逻辑 + +## Target Architecture + +Earth 对每类对象都尽量拆成三层: + +1. `state layer` + - 保存对象状态 + - 例如:`normal / hovered / locked / hidden / loading` + +2. `logic layer` + - 处理点击、悬停、锁定、过滤、显隐切换 + - 不直接关心 Three.js 具体材质怎么改 + +3. `renderer layer` + - 根据状态更新 Three.js / HUD 外观 + - 是最容易针对不同渲染引擎替换的一层 + +## Current Good Signals + +当前已经接近这条方向的地方: + +- cable 状态管理 +- 部分 landing point 状态同步 +- layer button 的统一状态入口 +- tooltip / legend / info-card 开始朝状态驱动靠拢 + +## Next Steps + +### 1. Standardize object state enums + +优先为这些对象建立更稳定的状态语义: + +- cables +- satellites +- landing points +- BGP markers +- media / news 面板入口按钮 + +### 2. Unify state-to-visual adapters + +为各模块建立更清晰的渲染适配函数,例如: + +- `applyCableVisualState()` +- `applySatelliteVisualState()` +- `applyBGPVisualState()` + +要求: + +- 逻辑层只改状态 +- 视觉层负责把状态映射到材质、透明度、发光、尺寸、文字 + +### 3. Separate Earth UI state from render state + +HUD / 面板 / 图层按钮状态也需要和渲染状态分离: + +- `loading` +- `active` +- `locked` +- `hidden` +- `error` + +不要再让 UI 通过“猜渲染结果”推导业务状态。 + +### 4. Prepare migration-safe boundaries + +后续如果做 UE / Cesium 客户端,尽量保留: + +- 状态枚举 +- 交互规则 +- 数据层接口 + +只替换: + +- Three.js 具体渲染实现 +- HUD 展示实现 + +## Practical Rule + +后续 Earth 新功能开发时,优先问三个问题: + +1. 这个状态由谁持有? +2. 这个交互逻辑在哪一层处理? +3. 这个视觉变化是否能在不改逻辑的情况下单独替换? + +如果答不上来,就说明还在把状态、逻辑、渲染揉在一起。 diff --git a/docs/plans/earth-webgl-instancing-satellites-plan.md b/docs/plans/earth-webgl-instancing-satellites-plan.md new file mode 100644 index 00000000..7ef05fab --- /dev/null +++ b/docs/plans/earth-webgl-instancing-satellites-plan.md @@ -0,0 +1,82 @@ +# Earth WebGL Instancing Satellites Plan + +> Source note: this plan absorbs useful ideas from a sisyphus-created draft formerly stored at `.sisyphus/plans/webgl-instancing-satellites.md`. + +## Goal + +把 Earth 卫星渲染从当前方案继续推进到更适合高数量卫星的 instancing 方向,目标是: + +- 支持更多卫星 +- 降低渲染压力 +- 仍然保留当前数据层和交互层 + +## Why It Matters + +当前卫星系统已经具备: + +- 数据加载 +- 轨迹 +- 选择/锁定 +- 图例 +- 相关区域联动 + +但当卫星数量持续增加时,渲染层会越来越接近瓶颈。 + +## Recommended Direction + +优先调研并原型验证: + +- `InstancedBufferGeometry + custom shader` + +而不是一开始就推倒重写成 raw WebGL。 + +原因: + +- 仍能保留 Three.js 主架构 +- 更容易渐进迁移 +- 比继续堆普通点渲染更有上限 + +## What Should Stay + +尽量保留这些层: + +- 卫星数据获取 +- 位置计算 +- 锁定/悬停逻辑 +- legend / info-card / 相关联动 + +主要替换的是: + +- 卫星点渲染实现 +- 颜色/大小等实例属性更新方式 + +## Phases + +### Phase 1: Prototype + +- 用 instancing 做最小原型 +- 先只渲染卫星点 +- 不碰轨迹系统 + +### Phase 2: Integrate + +- 接入当前 `satellites.js` 数据层 +- 保留当前选择和高亮语义 + +### Phase 3: Tune + +- 调整可视大小 +- 调整选中高亮方式 +- 评估是否需要分层 LOD + +## Risks + +1. 透明度排序更复杂 +2. Shader 调试成本更高 +3. 选中态和 hover 态不能简单复用旧材质逻辑 + +## Acceptance + +1. 在更高卫星数量下保持可接受帧率 +2. 不破坏现有锁定/高亮语义 +3. 图例、信息卡、相关卫星联动仍然成立 diff --git a/docs/frontend/ai-playground-development-plan.md b/docs/plans/frontend-ai-playground-development-plan.md similarity index 97% rename from docs/frontend/ai-playground-development-plan.md rename to docs/plans/frontend-ai-playground-development-plan.md index 77738c50..fb318989 100644 --- a/docs/frontend/ai-playground-development-plan.md +++ b/docs/plans/frontend-ai-playground-development-plan.md @@ -30,7 +30,7 @@ - [backend/app/services/ai_client.py](/home/ray/dev/linkong/planet/backend/app/services/ai_client.py) - [aiprovider/main.py](/home/ray/dev/linkong/planet/aiprovider/main.py) - [aiprovider/provider_service.py](/home/ray/dev/linkong/planet/aiprovider/provider_service.py) -- [docs/agents/aiprovider.md](/home/ray/dev/linkong/planet/docs/agents/aiprovider.md) +- [docs/technical/agents-aiprovider.md](/home/ray/dev/linkong/planet/docs/technical/agents-aiprovider.md) ### 2. 本地运行与配置打通 @@ -77,7 +77,7 @@ 相关文件: -- [docs/frontend/frontend-layout-guidelines.md](/home/ray/dev/linkong/planet/docs/frontend/frontend-layout-guidelines.md) +- [docs/technical/frontend-layout-guidelines.md](/home/ray/dev/linkong/planet/docs/technical/frontend-layout-guidelines.md) - [frontend/src/pages/BGP/BGP.tsx](/home/ray/dev/linkong/planet/frontend/src/pages/BGP/BGP.tsx) ## 当前限制 diff --git a/docs/ue5/ue5_mvp_fused_plan.md b/docs/plans/ue5-mvp-fused-plan.md similarity index 95% rename from docs/ue5/ue5_mvp_fused_plan.md rename to docs/plans/ue5-mvp-fused-plan.md index ac98d434..2def1cfd 100644 --- a/docs/ue5/ue5_mvp_fused_plan.md +++ b/docs/plans/ue5-mvp-fused-plan.md @@ -979,3 +979,37 @@ Content/ 如果你按这份方案推进,一期最现实的目标不是“立刻做出完整 UE 大屏”,而是: **在 14 天左右,做出一个能显示真实地球、能显示超算点、能点击看详情、能接后端的可用 UE 客户端 MVP。** + +--- + +# 附录:来自 sisyphus 草案的补充 + +> 这部分吸收自一个 sisyphus-created draft,原始草案已归档,不再单独维护为主计划。 + +## 1. 项目骨架建议 + +原草案给过一个更偏“工程初始化”的目录示意,适合拿来做一期的命名参考: + +- `Levels/` +- `Blueprints/` +- `Materials/` +- `Widgets/` +- `Source/PlanetAPI/` +- `Source/CesiumIntegration/` +- `Source/Visualization/` + +这不是强制结构,但对 UE 初期整理目录很有帮助。 + +## 2. API 契约意识 + +原草案有一个很对的提醒: + +- 一期虽然可以先走 HTTP +- 但数据模型命名不应只服务于一次性演示 +- 后续 WebSocket 接入时,字段设计最好能沿用 + +所以当前主计划继续建议: + +- 先做 HTTP 拉取 +- 尽量把 UE 侧数据模型定义清楚 +- 不要在蓝图各处散写临时 JSON 字段解析 diff --git a/docs/technical/README.md b/docs/technical/README.md new file mode 100644 index 00000000..a8a585de --- /dev/null +++ b/docs/technical/README.md @@ -0,0 +1,26 @@ +# Technical Docs + +这里放“当前实现和当前结构”的文档,重点回答: + +- 现在代码是怎么组织的 +- 当前入口在哪 +- 状态和组件如何工作 +- 后续改动应该沿着哪条实现边界继续走 + +适合放入这里的内容: + +- 前端上下文 +- Earth 前端结构 +- 后端运行控制 +- collector 现状 +- 采集格式约定 + +不适合放入这里的内容: + +- 尚未完成的 roadmap +- 未来迭代方案 +- 大范围重构计划 + +这些应放入: + +- [docs/plans/README.md](/home/ray/dev/linkong/planet/docs/plans/README.md) diff --git a/docs/agents/aiprovider.md b/docs/technical/agents-aiprovider.md similarity index 100% rename from docs/agents/aiprovider.md rename to docs/technical/agents-aiprovider.md diff --git a/docs/backend/collectors.md b/docs/technical/backend-collectors.md similarity index 100% rename from docs/backend/collectors.md rename to docs/technical/backend-collectors.md diff --git a/docs/backend/system-service-control.md b/docs/technical/backend-system-service-control.md similarity index 100% rename from docs/backend/system-service-control.md rename to docs/technical/backend-system-service-control.md diff --git a/docs/earth/bgp-context.md b/docs/technical/earth-bgp-context.md similarity index 99% rename from docs/earth/bgp-context.md rename to docs/technical/earth-bgp-context.md index 5150c43b..bd0eb8ef 100644 --- a/docs/earth/bgp-context.md +++ b/docs/technical/earth-bgp-context.md @@ -187,7 +187,7 @@ Current reality: - that is expected, because incidents are aggregated and de-noised - but incident-first rendering makes the Earth view look too quiet unless there is another always-available activity layer -Implementation detail for the recommended `activity layer` is expanded in [bgp-region-aggregation-plan.md](/home/ray/dev/linkong/planet/docs/earth/bgp-region-aggregation-plan.md). +Implementation detail for the recommended `activity layer` is expanded in [bgp-region-aggregation-plan.md](/home/ray/dev/linkong/planet/docs/plans/earth-bgp-region-aggregation-plan.md). So the immediate next milestone is: diff --git a/docs/technical/earth-frontend-context.md b/docs/technical/earth-frontend-context.md new file mode 100644 index 00000000..e7f6a12d --- /dev/null +++ b/docs/technical/earth-frontend-context.md @@ -0,0 +1,263 @@ +# Earth Frontend Context + +本文件描述当前 Earth 大屏前端的真实结构,重点是帮助后续继续改 HUD、图层、媒体面板、真实地形、BGP 可视化时,不再重复踩结构和状态同步上的坑。 + +相关规则建议一起参考: + +- [rules.md](/home/ray/dev/linkong/planet/rules.md) +- [frontend-layout-guidelines.md](/home/ray/dev/linkong/planet/docs/technical/frontend-layout-guidelines.md) + +## 当前目标 + +Earth 前端不是普通管理页,它是独立的大屏展示前端。当前产品目标是: + +- 维持地球视图的空间感和可读性 +- 让 HUD、图层、媒体面板、BGP、卫星、海缆等保持统一交互 +- 把加载中、已启用、已隐藏、锁定中这类状态做清楚 + +## 当前入口 + +React 路由入口: + +- [Earth.tsx](/home/ray/dev/linkong/planet/frontend/src/pages/Earth/Earth.tsx) + +当前做法很简单: + +- React 页面只负责提供一个全屏 `iframe` +- 真正的 Earth 应用运行在: + - [index.html](/home/ray/dev/linkong/planet/frontend/public/earth/index.html) + +所以 Earth 前端本质上是 `public/earth` 下的一套独立静态应用。 + +## 当前文件分层 + +### 1. 页面入口与结构 + +- [index.html](/home/ray/dev/linkong/planet/frontend/public/earth/index.html) + +职责: + +- HUD 基础 DOM +- 图层面板 +- 媒体面板 +- 工具栏 +- 设置弹窗 +- 兼容旧元素 id + +### 2. 主运行时 + +- [main.js](/home/ray/dev/linkong/planet/frontend/public/earth/js/main.js) + +职责: + +- 地球初始化 +- Three.js 场景组装 +- 数据加载与刷新 +- 各图层集成 +- Earth 级别状态同步 + +### 3. 地球控制层 + +- [controls.js](/home/ray/dev/linkong/planet/frontend/public/earth/js/controls.js) + +职责: + +- 工具栏交互 +- 图层面板交互 +- 旋转/缩放/布局 +- HUD 面板拖拽 +- 图层开关状态机 + +这份文件是 Earth 前端当前最核心的 UI 控制入口。 + +### 4. UI 与状态消息 + +- [ui.js](/home/ray/dev/linkong/planet/frontend/public/earth/js/ui.js) + +职责: + +- loading 面板 +- status message +- tooltip / error / 清理逻辑 + +### 5. 地球与地形 + +- [earth.js](/home/ray/dev/linkong/planet/frontend/public/earth/js/earth.js) +- [terrain.js](/home/ray/dev/linkong/planet/frontend/public/earth/js/terrain.js) + +职责: + +- 地球球体、云层、大气 +- 真实地形 mesh +- terrain tile 拉取、解码、位移、着色 + +### 6. 图层模块 + +- [satellites.js](/home/ray/dev/linkong/planet/frontend/public/earth/js/satellites.js) +- [cables.js](/home/ray/dev/linkong/planet/frontend/public/earth/js/cables.js) +- [bgp.js](/home/ray/dev/linkong/planet/frontend/public/earth/js/bgp.js) +- [news.js](/home/ray/dev/linkong/planet/frontend/public/earth/js/news.js) +- [tv.js](/home/ray/dev/linkong/planet/frontend/public/earth/js/tv.js) + +职责: + +- 各自的数据层 +- 开关行为 +- 面板内容 +- hover/lock/selection 语义 + +## 当前样式分层 + +Earth 的 CSS 不是一份大样式表,而是分层管理: + +- [base.css](/home/ray/dev/linkong/planet/frontend/public/earth/css/base.css) +- [hud.css](/home/ray/dev/linkong/planet/frontend/public/earth/css/hud.css) +- [toolbar.css](/home/ray/dev/linkong/planet/frontend/public/earth/css/toolbar.css) +- [layer-panel.css](/home/ray/dev/linkong/planet/frontend/public/earth/css/layer-panel.css) +- [info-panel.css](/home/ray/dev/linkong/planet/frontend/public/earth/css/info-panel.css) +- [legend.css](/home/ray/dev/linkong/planet/frontend/public/earth/css/legend.css) +- [earth-stats.css](/home/ray/dev/linkong/planet/frontend/public/earth/css/earth-stats.css) +- [coordinates-display.css](/home/ray/dev/linkong/planet/frontend/public/earth/css/coordinates-display.css) +- [tv-panel.css](/home/ray/dev/linkong/planet/frontend/public/earth/css/tv-panel.css) + +当前建议: + +- 通用 HUD 壳层写进 `hud.css` +- 单一面板特性写进各自子文件 +- 不要把业务状态样式再散回 `index.html` + +## 当前图层开关状态语义 + +Earth 图层按钮现在不应再只有“开/关”两态,而应支持: + +- `inactive` +- `active` +- `loading` + +当前入口在: + +- [controls.js](/home/ray/dev/linkong/planet/frontend/public/earth/js/controls.js) +- [layer-button-state.js](/home/ray/dev/linkong/planet/frontend/public/earth/js/layer-button-state.js) + +关键函数: + +- `updateLayerButtonState(button, isActive)` +- `setLayerButtonState(button, options)` + +`setLayerButtonState` 负责: + +- `loading` 样式 +- `aria-busy` +- 按钮禁用 +- tooltip 更新 +- 绑定状态文本更新 +- 可选同步 `active` + +因此后续如果别的图层也需要异步启用,应该直接走这套状态机,而不是再手写一套临时 loading class。 + +### `data-status-target` + +图层按钮可以通过: + +- `data-status-target` + +指向一个状态文本节点。当前 terrain 已接入: + +- 按钮:`#toggle-terrain` +- 状态节点:`#terrain-status` + +以后别的异步图层也可以沿用这套约定。 + +## 当前地形链路 + +真实地形首次启用会慢,原因不只是一个: + +1. 需要拉取 Terrarium 瓦片 +2. 需要解码图片 +3. 需要按顶点采样高程 +4. 需要重新写入 geometry 和 color +5. 需要重新计算法线与包围体 + +当前入口在: + +- [terrain.js](/home/ray/dev/linkong/planet/frontend/public/earth/js/terrain.js) + +当前已经做了两层体验优化: + +1. 图层开关 loading 状态持续可见 +2. 页面空闲时会预热 `ensureTerrainReady()` + +也就是说,后续再继续优化 terrain 时,优先顺序应该是: + +1. 先保证用户感知正确 +2. 再压缩首次等待 +3. 最后才做更激进的几何/瓦片优化 + +## 当前高频风险点 + +### 1. 视觉状态和业务状态不同步 + +Earth 里最常见的 bug 不是“没渲染”,而是: + +- 图层关了,tooltip 还在 +- 锁定对象隐藏了,info card 还在 +- legend 没跟图层切换 +- loading 已结束,但按钮还像没开 + +后续改动必须优先检查状态同步。 + +### 2. HUD 布局问题先查结构,不要先打 CSS 补丁 + +Earth HUD 历史上反复出现: + +- 面板只剩一条缝 +- markdown 被裁掉 +- tabs/iframe 被 `overflow: hidden` 吃掉 + +优先检查: + +1. 谁负责高度 +2. 谁负责滚动 +3. 哪一层在裁剪 + +不要上来先加 `overflow: hidden` 或额外包装层。 + +### 3. Transitional path 必须收口 + +Earth 已经经历过多轮 HUD、toolbar、media panel 重构,所以最容易积累: + +- 旧 helper +- 旧 class +- 旧 fallback 逻辑 +- 已废弃变体 + +每次大功能完成后,都要做一次 cleanup pass。 + +## 当前推荐改动方式 + +如果后续继续改 Earth,建议按这个顺序: + +1. 先确认改的是: + - Three.js 渲染层 + - HUD 结构层 + - 图层状态层 + - 面板内容层 +2. 如果涉及图层按钮,优先接入统一状态机 +3. 如果涉及可见性切换,检查 tooltip / legend / info-card / lock 是否一起收口 +4. 如果涉及面板布局,先查结构再动 CSS + +## 当前与控制台前端的边界 + +Earth 前端和控制台前端不是同一套 UI 系统: + +- 控制台前端:React + Ant Design 工作台 +- Earth 前端:`public/earth` 原生 HUD + Three.js 展示面 + +因此: + +- Earth 不应该直接复用 Ant Table / AppLayout 语义 +- 控制台也不应该照搬 Earth HUD 动画和玻璃层语言 + +控制台相关结构见: + +- [admin-frontend-context.md](/home/ray/dev/linkong/planet/docs/technical/frontend-admin-frontend-context.md) diff --git a/docs/earth/news-live-streams-collector-format.md b/docs/technical/earth-news-live-streams-collector-format.md similarity index 100% rename from docs/earth/news-live-streams-collector-format.md rename to docs/technical/earth-news-live-streams-collector-format.md diff --git a/docs/technical/frontend-admin-frontend-context.md b/docs/technical/frontend-admin-frontend-context.md new file mode 100644 index 00000000..bbcab832 --- /dev/null +++ b/docs/technical/frontend-admin-frontend-context.md @@ -0,0 +1,236 @@ +# Admin Frontend Context + +本文件描述当前控制台前端的真实结构,目标是帮助后续页面开发、表格改造、布局治理和状态收口时快速找到正确入口。 + +相关规则建议一起参考: + +- [rules.md](/home/ray/dev/linkong/planet/rules.md) +- [frontend-layout-guidelines.md](/home/ray/dev/linkong/planet/docs/technical/frontend-layout-guidelines.md) + +## 当前目标 + +控制台前端承担的是后台工作台,而不是展示型大屏。当前约束是: + +- 页面默认遵循单屏工作区 +- 主交互在内部模块滚动,而不是依赖整页无限变长 +- 列表、表格、分析页优先保证主工作区可见 +- 通用布局、滚动条、表格滚动行为尽量复用,不要每页各写一套 + +## 当前路由入口 + +主入口在: + +- [App.tsx](/home/ray/dev/linkong/planet/frontend/src/App.tsx) + +当前后台相关路由包括: + +- `/admin` +- `/users` +- `/datasources` +- `/data` +- `/alerts/system` +- `/alerts/bgp` +- `/alerts/situational` +- `/bgp` +- `/playground` +- `/settings` + +`/earth` 是独立展示页,不属于控制台骨架。 + +## 当前页面骨架 + +控制台公共壳层在: + +- [AppLayout.tsx](/home/ray/dev/linkong/planet/frontend/src/components/AppLayout/AppLayout.tsx) + +职责: + +- 左侧导航 +- 折叠与展开 +- 当前账号/版本信息 +- 内容区高度闭合 +- 全站统一侧边栏滚动条 + +当前结构是: + +```tsx + + ... + + +
{children}
+
+
+
+``` + +后续控制台页面应优先适配这套壳层,而不是重新定义全页高度语义。 + +## 当前共享组件 + +### 1. `Scrollbar` + +文件: + +- [Scrollbar.tsx](/home/ray/dev/linkong/planet/frontend/src/components/Scrollbar/Scrollbar.tsx) + +用途: + +- 控制台侧边栏这类普通内容容器 +- 组件内部管理可见性、thumb 尺寸、拖拽和双轴 overflow 判定 + +当前约束: + +- 滚动条必须是浮层,不参与布局 +- 无 overflow 时不应留下可见痕迹 +- 真实滚动仍交给原生容器,只替换可见层和交互层 + +### 2. `ScrollbarOverlay` + +文件: + +- [ScrollbarOverlay.tsx](/home/ray/dev/linkong/planet/frontend/src/components/Scrollbar/ScrollbarOverlay.tsx) + +用途: + +- Ant Table 这类内部已有滚动容器的区域 +- 不接管滚动语义,只叠加新的滚动条可见层 + +当前使用场景: + +- 数据源 +- 采集数据 +- 用户管理 +- 设置页 +- 告警页 +- BGP 页面 + +### 3. `TableScrollRegion` + +文件: + +- [TableScrollRegion.tsx](/home/ray/dev/linkong/planet/frontend/src/components/Scrollbar/TableScrollRegion.tsx) + +用途: + +- 为表格滚动区提供统一包裹层 +- 后续新表格页优先复用,不要重复写“表格区域 + overlay scrollbar”样板 + +### 4. 其他共享组件 + +- [MarkdownRenderer.tsx](/home/ray/dev/linkong/planet/frontend/src/components/MarkdownRenderer/MarkdownRenderer.tsx) +- [TableActions.tsx](/home/ray/dev/linkong/planet/frontend/src/components/TableActions/TableActions.tsx) + +## 当前状态来源 + +### 1. 认证状态 + +文件: + +- [auth.ts](/home/ray/dev/linkong/planet/frontend/src/stores/auth.ts) + +职责: + +- token +- 当前用户 +- 登录/退出 + +`App.tsx` 用它判断是否进入登录页。 + +### 2. 业务数据网关 + +目前 AI / 态势感知相关服务集中在: + +- [http-gateway.ts](/home/ray/dev/linkong/planet/frontend/src/services/situational-awareness/http-gateway.ts) +- [port.ts](/home/ray/dev/linkong/planet/frontend/src/services/situational-awareness/port.ts) +- [types.ts](/home/ray/dev/linkong/planet/frontend/src/services/situational-awareness/types.ts) + +约束: + +- 页面不要直接散落拼 URL +- 先通过 port/types 定义边界 +- 再由 http/mock gateway 实现 + +## 当前页面分层建议 + +### 1. 仪表盘和摘要型页面 + +例如: + +- [Dashboard.tsx](/home/ray/dev/linkong/planet/frontend/src/pages/Dashboard/Dashboard.tsx) + +优先目标: + +- 页头稳定 +- 摘要卡片先紧凑化 +- 主工作区占据主要高度 + +### 2. 表格型页面 + +例如: + +- [DataSources.tsx](/home/ray/dev/linkong/planet/frontend/src/pages/DataSources/DataSources.tsx) +- [DataList.tsx](/home/ray/dev/linkong/planet/frontend/src/pages/DataList/DataList.tsx) +- [Users.tsx](/home/ray/dev/linkong/planet/frontend/src/pages/Users/Users.tsx) +- [Settings.tsx](/home/ray/dev/linkong/planet/frontend/src/pages/Settings/Settings.tsx) + +约束: + +- 优先内部滚动 +- 不要让表格撑爆整页 +- 新表格区域优先复用 `TableScrollRegion` / `ScrollbarOverlay` + +### 3. 复杂工作区页面 + +例如: + +- [BGP.tsx](/home/ray/dev/linkong/planet/frontend/src/pages/BGP/BGP.tsx) +- [Playground.tsx](/home/ray/dev/linkong/planet/frontend/src/pages/Playground/Playground.tsx) + +约束: + +- Tabs 里的内容不能套同一套高度逻辑 +- 表格 tab、Markdown tab、配置 tab 要各自定义滚动责任 +- AI 结果区、长文本区优先保证最小可读高度 + +## 当前布局约束 + +这些原则已经在项目里反复验证过: + +1. 父容器高度链要闭合 +2. `min-height: 0` 不能漏 +3. overflow 责任必须明确 +4. 不要用 `overflow: hidden` 掩盖结构问题 +5. 不要为了摘要卡完整显示去压缩主工作区 +6. 自定义滚动条必须是浮层,不得挤压内容宽度 + +详细经验见: + +- [frontend-layout-guidelines.md](/home/ray/dev/linkong/planet/docs/technical/frontend-layout-guidelines.md) + +## 当前推荐改动方式 + +如果后续继续改后台页面,建议按这个顺序: + +1. 先确认页面属于摘要页、表格页还是复杂工作区 +2. 先接入现有壳层和滚动语义 +3. 优先复用共享滚动组件 +4. 最后再改视觉和细节交互 + +不要先写局部 CSS 补丁,再回头补结构。 + +## 当前明显边界 + +控制台前端和 Earth 前端不是一套系统: + +- 控制台前端是 React + Ant Design 工作台 +- Earth 前端是 `public/earth` 下的独立原生 HUD 系统 + +因此: + +- 不要把 Earth 的 HUD/动画/状态机直接挪进控制台 +- 不要把控制台表格/滚动策略硬套到 Earth HUD + +Earth 相关结构见: + +- [earth-frontend-context.md](/home/ray/dev/linkong/planet/docs/technical/earth-frontend-context.md) diff --git a/docs/frontend/frontend-layout-guidelines.md b/docs/technical/frontend-layout-guidelines.md similarity index 100% rename from docs/frontend/frontend-layout-guidelines.md rename to docs/technical/frontend-layout-guidelines.md diff --git a/docs/ops/docker-compose-buildx-upgrade.md b/docs/technical/ops-docker-compose-buildx-upgrade.md similarity index 100% rename from docs/ops/docker-compose-buildx-upgrade.md rename to docs/technical/ops-docker-compose-buildx-upgrade.md diff --git a/docs/version-history.md b/docs/version-history.md index 5af0ea57..930ea810 100644 --- a/docs/version-history.md +++ b/docs/version-history.md @@ -16,12 +16,13 @@ ## Current Version - `main` 当前主线历史推导到:`0.16.5` -- `dev` 当前开发分支历史推导到:`0.31.0` +- `dev` 当前开发分支历史推导到:`0.31.1` ## Timeline | Version | Type | Branch | Commit | Summary | | --- | --- | --- | --- | --- | +| `0.31.1` | bugfix | `dev` | `pending` | Earth 图层开关统一 loading 状态机,卫星首次加载可见化,并将文档按 technical / plans / deprecated 重构归档 | | `0.31.0` | feature | `dev` | `pending` | Earth 巡航展示模式:自动轮播 BGP 事件,连线逐帧追踪,卫星/海缆联动高亮,视觉状态全面统一 | | `0.30.0` | feature | `dev` | `pending` | Earth 新增真实地形图层(Terrarium DEM 代理 + 前端瓦片解码着色),设置弹窗支持地形透明度滑块 | | `0.29.2` | bugfix | `dev` | `pending` | 修正 Earth 设置弹窗展开表现与系统入口,继续统一液态玻璃 HUD,并校正太阳受光方向 | diff --git a/frontend/package.json b/frontend/package.json index 8bdc04bd..01771325 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -1,6 +1,6 @@ { "name": "planet-frontend", - "version": "0.31.0", + "version": "0.31.1", "private": true, "packageManager": "bun@1", "dependencies": { diff --git a/frontend/public/earth/css/layer-panel.css b/frontend/public/earth/css/layer-panel.css index f99b2acc..2c9511fe 100644 --- a/frontend/public/earth/css/layer-panel.css +++ b/frontend/public/earth/css/layer-panel.css @@ -235,6 +235,7 @@ border: none; background: transparent; cursor: pointer; + transition: opacity 0.18s ease; } .layer-row-toggle-track { @@ -247,6 +248,11 @@ transition: background 0.18s ease, border-color 0.18s ease; } +.layer-row-toggle:disabled { + cursor: progress; + opacity: 1; +} + /* Thumb */ .layer-row-toggle-track::after { content: ""; @@ -261,6 +267,24 @@ transition: transform 0.18s ease, background 0.18s ease; } +.layer-row-toggle.is-loading .layer-row-toggle-track { + background: linear-gradient( + 90deg, + rgba(104, 147, 221, 0.38), + rgba(143, 185, 255, 0.72), + rgba(104, 147, 221, 0.38) + ); + background-size: 180% 100%; + border-color: rgba(223, 236, 252, 0.28); + animation: layer-toggle-loading-track 1.2s linear infinite; +} + +.layer-row-toggle.is-loading .layer-row-toggle-track::after { + background: #f0f6ff; + transform: translateX(calc(7px * var(--hud-scale))); + animation: layer-toggle-loading-thumb 1s ease-in-out infinite; +} + /* Active (ON) state */ .layer-row-toggle.active .layer-row-toggle-track { background: linear-gradient(180deg, rgba(143, 185, 255, 0.72), rgba(104, 147, 221, 0.78)); @@ -272,5 +296,24 @@ transform: translateX(calc(14px * var(--hud-scale))); } +@keyframes layer-toggle-loading-track { + 0% { + background-position: 0% 50%; + } + 100% { + background-position: 180% 50%; + } +} + +@keyframes layer-toggle-loading-thumb { + 0%, + 100% { + box-shadow: 0 2px 6px rgba(1, 8, 18, 0.3), 0 0 0 rgba(174, 205, 255, 0.18); + } + 50% { + box-shadow: 0 2px 6px rgba(1, 8, 18, 0.3), 0 0 calc(10px * var(--hud-scale)) rgba(174, 205, 255, 0.42); + } +} + /* Layout-expanded: layer panel slides off with .earth-left-column — no individual rule needed since the whole column translates together. */ diff --git a/frontend/public/earth/index.html b/frontend/public/earth/index.html index 7d2726fb..d0f94d7a 100644 --- a/frontend/public/earth/index.html +++ b/frontend/public/earth/index.html @@ -98,7 +98,7 @@ 地形 Terrain - diff --git a/frontend/public/earth/js/controls.js b/frontend/public/earth/js/controls.js index fe9dbf46..6e5feedd 100644 --- a/frontend/public/earth/js/controls.js +++ b/frontend/public/earth/js/controls.js @@ -30,6 +30,11 @@ import { ensureNewsPanelReady, updateNewsToggleUI, } from "./news.js"; +import { + setButtonTooltip, + setLayerButtonState, + updateLayerButtonState, +} from "./layer-button-state.js"; export let autoRotate = true; export let zoomLevel = 1.0; @@ -67,6 +72,8 @@ const SETTINGS_SHEET_MAX_SCALE_Y = 0.18; let settingsModalTimer = null; let settingsSheetAnimation = null; let terrainToggleToken = 0; +let terrainPrefetchStarted = false; +let terrainPrefetchScheduled = false; let focusViewAnimationToken = 0; function getViewRotation(targetLat, targetRotLon) { @@ -91,10 +98,40 @@ function dispatchRotationModeChange() { function applyTerrainUiState(button, enabled) { showTerrain = enabled; toggleTerrain(enabled); - updateLayerButtonState(button, enabled); - setButtonTooltip(button, enabled ? "隐藏地形" : "显示地形"); - const terrainStatus = document.getElementById("terrain-status"); - if (terrainStatus) terrainStatus.textContent = enabled ? "开启" : "关闭"; + setLayerButtonState(button, { + active: enabled, + loading: false, + tooltip: enabled ? "隐藏地形" : "显示地形", + statusText: enabled ? "开启" : "关闭", + }); +} + +function prewarmTerrainIfNeeded() { + if (terrainPrefetchStarted || isTerrainReady()) return; + terrainPrefetchStarted = true; + ensureTerrainReady().catch((error) => { + terrainPrefetchStarted = false; + console.warn("地形预热加载失败:", error); + }); +} + +function scheduleTerrainPrefetch() { + if (terrainPrefetchScheduled || terrainPrefetchStarted || isTerrainReady()) { + return; + } + terrainPrefetchScheduled = true; + + const runPrefetch = () => { + terrainPrefetchScheduled = false; + prewarmTerrainIfNeeded(); + }; + + if (typeof window !== "undefined" && "requestIdleCallback" in window) { + window.requestIdleCallback(runPrefetch, { timeout: 2200 }); + return; + } + + window.setTimeout(runPrefetch, 1400); } export function applyImmediateView(targetEarthObj, camera, options = {}) { @@ -670,24 +707,6 @@ function setFloatingMenuOpen(group, shouldOpen) { group?.classList.toggle("open", shouldOpen); } -function setButtonTooltip(button, text) { - const tooltip = button?.querySelector(".earth-toolbar-tooltip"); - if (tooltip) { - tooltip.textContent = text; - } -} - -export function updateLayerButtonState(button, isActive) { - if (!button) return; - button.classList.toggle("active", isActive); - button.setAttribute("aria-checked", isActive ? "true" : "false"); - // Legacy badge text (kept for compatibility) - const state = button.querySelector(".earth-layer-btn__state"); - if (state) { - state.textContent = isActive ? "ON" : "OFF"; - } -} - function clearSelectionIfHiding(shouldHide) { if (shouldHide) { clearLockedObject(); @@ -1070,15 +1089,30 @@ function setupTerrainControls() { setupLayerPanel(); if (trailsBtn) { - updateLayerButtonState(trailsBtn, true); - setButtonTooltip(trailsBtn, "隐藏轨迹"); + setLayerButtonState(trailsBtn, { + active: true, + tooltip: "隐藏轨迹", + }); } bindListener(searchBtn, "click", () => { showStatusMessage("搜索功能待开发", "info"); }); + bindListener(terrainBtn, "pointerenter", () => { + prewarmTerrainIfNeeded(); + }); + + bindListener(terrainBtn, "focus", () => { + prewarmTerrainIfNeeded(); + }); + + scheduleTerrainPrefetch(); + bindListener(terrainBtn, "click", async function () { + if (this.classList.contains("is-loading")) { + return; + } const nextShowTerrain = !showTerrain; const toggleToken = ++terrainToggleToken; @@ -1090,6 +1124,11 @@ function setupTerrainControls() { try { if (!isTerrainReady()) { + setLayerButtonState(this, { + loading: true, + tooltip: "地形加载中...", + statusText: "加载中", + }); showStatusMessage("正在加载真实地形数据...", "info"); await ensureTerrainReady(); } @@ -1108,6 +1147,13 @@ function setupTerrainControls() { const showSats = !getShowSatellites(); clearSelectionIfHiding(!showSats); try { + if (showSats) { + setLayerButtonState(this, { + active: false, + loading: true, + tooltip: "卫星加载中...", + }); + } await setSatellitesEnabled(showSats); if (!showSats) { showStatusMessage("卫星已隐藏", "info"); @@ -1119,6 +1165,11 @@ function setupTerrainControls() { } } catch (error) { console.error("切换卫星显示失败:", error); + setLayerButtonState(this, { + active: false, + loading: false, + tooltip: "显示卫星", + }); } }); @@ -1129,8 +1180,10 @@ function setupTerrainControls() { if (!showNextBGP && rotationMode === ROTATION_MODE.CRUISE && autoRotate) { setAutoRotate(false); } - updateLayerButtonState(this, showNextBGP); - setButtonTooltip(this, showNextBGP ? "隐藏BGP观测" : "显示BGP观测"); + setLayerButtonState(this, { + active: showNextBGP, + tooltip: showNextBGP ? "隐藏BGP观测" : "显示BGP观测", + }); const bgpCountEl = document.getElementById("bgp-anomaly-count"); if (bgpCountEl) { bgpCountEl.textContent = `${getBGPCount()} 条`; @@ -1142,8 +1195,10 @@ function setupTerrainControls() { const isActive = this.classList.contains("active"); const nextShowTrails = !isActive; toggleTrails(nextShowTrails); - updateLayerButtonState(this, nextShowTrails); - setButtonTooltip(this, nextShowTrails ? "隐藏轨迹" : "显示轨迹"); + setLayerButtonState(this, { + active: nextShowTrails, + tooltip: nextShowTrails ? "隐藏轨迹" : "显示轨迹", + }); showStatusMessage(nextShowTrails ? "轨迹已显示" : "轨迹已隐藏", "info"); }); diff --git a/frontend/public/earth/js/layer-button-state.js b/frontend/public/earth/js/layer-button-state.js new file mode 100644 index 00000000..8497fde4 --- /dev/null +++ b/frontend/public/earth/js/layer-button-state.js @@ -0,0 +1,46 @@ +export function setButtonTooltip(button, text) { + if (button instanceof HTMLElement) { + button.title = text; + } + const tooltip = button?.querySelector(".earth-toolbar-tooltip"); + if (tooltip) { + tooltip.textContent = text; + } +} + +export function updateLayerButtonState(button, isActive) { + if (!button) return; + button.classList.toggle("active", isActive); + button.setAttribute("aria-checked", isActive ? "true" : "false"); + const state = button.querySelector(".earth-layer-btn__state"); + if (state) { + state.textContent = isActive ? "ON" : "OFF"; + } +} + +export function setLayerButtonState(button, options = {}) { + if (!(button instanceof HTMLButtonElement)) return; + const { + active = null, + loading = false, + tooltip = null, + statusText = null, + } = options; + button.classList.toggle("is-loading", loading); + button.toggleAttribute("aria-busy", loading); + button.disabled = loading; + if (typeof active === "boolean") { + updateLayerButtonState(button, active); + } + if (tooltip) { + setButtonTooltip(button, tooltip); + } + if (statusText) { + const statusTarget = button.dataset.statusTarget + ? document.getElementById(button.dataset.statusTarget) + : null; + if (statusTarget) { + statusTarget.textContent = statusText; + } + } +} diff --git a/frontend/public/earth/js/main.js b/frontend/public/earth/js/main.js index 5effba34..63cb1a05 100644 --- a/frontend/public/earth/js/main.js +++ b/frontend/public/earth/js/main.js @@ -134,8 +134,10 @@ import { focusEarthView, getZoomLevel, teardownControls, - updateLayerButtonState, } from "./controls.js"; +import { + setLayerButtonState, +} from "./layer-button-state.js"; import { initInfoCard, showInfoCard, @@ -1502,9 +1504,11 @@ function buildLoadErrorMessage(errors) { function updateSatelliteToggleUi(enabled, satelliteCount = getSatelliteCount()) { const satBtn = document.getElementById("toggle-satellites"); if (satBtn) { - updateLayerButtonState(satBtn, enabled); - const tooltip = satBtn.querySelector(".earth-toolbar-tooltip"); - if (tooltip) tooltip.textContent = enabled ? "隐藏卫星" : "显示卫星"; + setLayerButtonState(satBtn, { + active: enabled, + loading: false, + tooltip: enabled ? "隐藏卫星" : "显示卫星", + }); } const satelliteCountEl = document.getElementById("satellite-count"); @@ -1516,9 +1520,11 @@ function updateSatelliteToggleUi(enabled, satelliteCount = getSatelliteCount()) function updateCableToggleUi(enabled) { const cableBtn = document.getElementById("toggle-cables"); if (cableBtn) { - updateLayerButtonState(cableBtn, enabled); - const tooltip = cableBtn.querySelector(".earth-toolbar-tooltip"); - if (tooltip) tooltip.textContent = enabled ? "隐藏线缆" : "显示线缆"; + setLayerButtonState(cableBtn, { + active: enabled, + loading: false, + tooltip: enabled ? "隐藏线缆" : "显示线缆", + }); } const cableCountEl = document.getElementById("cable-count"); diff --git a/pyproject.toml b/pyproject.toml index f2e5fb1d..5e3c7a3e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "planet" -version = "0.31.0" +version = "0.31.1" description = "智能星球计划 - 态势感知系统" requires-python = ">=3.14" dependencies = [ diff --git a/uv.lock b/uv.lock index cdfa66db..83b2c4e0 100644 --- a/uv.lock +++ b/uv.lock @@ -475,7 +475,7 @@ wheels = [ [[package]] name = "planet" -version = "0.31.0" +version = "0.31.1" source = { virtual = "." } dependencies = [ { name = "aiofiles" },