diff --git a/VERSION b/VERSION
index 7b52f5e5..731b95d7 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-0.35.0
+0.35.1
diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md
index 876f5399..22e9ae1e 100644
--- a/docs/CHANGELOG.md
+++ b/docs/CHANGELOG.md
@@ -8,6 +8,19 @@ This project follows the repository versioning rule:
- `improvement` -> `+0.0.1`(bugfix + 小功能混合)
- `bugfix` -> `+0.0.1`
+## [0.35.1] — 2026-04-22
+
+### ✨ Highlights
+- Earth 统计展示改为统一 `data-earth-stat` 绑定机制,桌面 HUD 和移动端抽屉复用同一套状态更新入口
+
+### 🔧 Improvements
+- 收口海缆、登陆点、卫星、BGP 事件与 BGP 状态的统计写入逻辑,减少后续继续补桌面/移动双写分支的成本
+
+### 🐛 Fixes
+- 修复移动端态势抽屉中的海缆、登陆点与 BGP 统计在图层切换后可能停留旧值的问题
+
+---
+
## [0.35.0] — 2026-04-22
### ✨ Highlights
diff --git a/docs/version-history.md b/docs/version-history.md
index 976d268c..806a7494 100644
--- a/docs/version-history.md
+++ b/docs/version-history.md
@@ -16,12 +16,13 @@
## Current Version
- `main` 当前主线历史推导到:`0.16.5`
-- `dev` 当前开发分支历史推导到:`0.35.0`
+- `dev` 当前开发分支历史推导到:`0.35.1`
## Timeline
| Version | Type | Branch | Commit | Summary |
| --- | --- | --- | --- | --- |
+| `0.35.1` | bugfix | `dev` | `pending` | 收口 Earth 桌面 HUD 与移动端抽屉的统一统计绑定机制,修复态势统计在图层切换后的同步遗漏 |
| `0.35.0` | feature | `dev` | `pending` | Earth 移动端抽屉系统与悬浮卡片全面上线:手势驱动抽屉、点击物件弹出可拖动详情卡、单指旋转双指缩放地球 |
| `0.34.0` | feature | `dev` | `pending` | Earth 搜索面板正式接入,`planet.sh --allow-lan` 打通 Bun + Vite 局域网开放链路,并自动输出推荐访问地址与健康检查地址 |
| `0.33.0` | feature | `dev` | `pending` | `news_live_streams` 默认接入 iptv-org 频道目录,内置数据源支持直接编辑 override,并修复 TV 合并采集源后默认频道消失的问题 |
diff --git a/frontend/package.json b/frontend/package.json
index 0ae84d4c..aa8f86b9 100644
--- a/frontend/package.json
+++ b/frontend/package.json
@@ -1,6 +1,6 @@
{
"name": "planet-frontend",
- "version": "0.35.0",
+ "version": "0.35.1",
"private": true,
"packageManager": "bun@1",
"dependencies": {
diff --git a/frontend/public/earth/index.html b/frontend/public/earth/index.html
index 656d2c9a..1fba5009 100644
--- a/frontend/public/earth/index.html
+++ b/frontend/public/earth/index.html
@@ -282,23 +282,23 @@
- —
+ —
海缆系统
- —
+ —
登陆点
- —
+ —
在轨卫星
- —
+ —
BGP 事件
- —
+ —
BGP 观测站
@@ -310,12 +310,12 @@
-
-
+
+
@@ -486,19 +486,19 @@
- —
+ —
海缆系统
- —
+ —
登陆点
- —
+ —
在轨卫星
- —
+ —
BGP 事件
@@ -509,7 +509,7 @@
diff --git a/frontend/public/earth/js/cables.js b/frontend/public/earth/js/cables.js
index d0456819..0158cf01 100644
--- a/frontend/public/earth/js/cables.js
+++ b/frontend/public/earth/js/cables.js
@@ -10,7 +10,7 @@ import {
CABLE_CONFIG,
} from "./constants.js";
import { latLonToVector3 } from "./utils.js";
-import { updateEarthStats, showStatusMessage } from "./ui.js";
+import { setEarthStatValue, updateEarthStats, showStatusMessage } from "./ui.js";
import { showInfoCard } from "./info-card.js";
import { setLegendItems, setLegendMode } from "./legend.js";
@@ -336,9 +336,8 @@ export async function loadGeoJSONFromPath(scene, earthObj, options = {}) {
feature.properties.status === "In Service"),
).length;
- const cableCountEl = document.getElementById("cable-count");
const statusEl = document.getElementById("cable-status-summary");
- if (cableCountEl) cableCountEl.textContent = cableCount + "个";
+ setEarthStatValue("cable-count", `${cableCount}个`);
if (statusEl) statusEl.textContent = `${inServiceCount}/${cableCount} 运行中`;
updateEarthStats({
@@ -435,10 +434,7 @@ export async function loadLandingPoints(scene, earthObj, options = {}) {
validCount++;
}
- const landingPointCountEl = document.getElementById("landing-point-count");
- if (landingPointCountEl) {
- landingPointCountEl.textContent = validCount + "个";
- }
+ setEarthStatValue("landing-point-count", `${validCount}个`);
if (!silent) {
showStatusMessage(`成功加载 ${validCount} 个登陆点`, "success");
diff --git a/frontend/public/earth/js/controls.js b/frontend/public/earth/js/controls.js
index deb1f81e..13aee384 100644
--- a/frontend/public/earth/js/controls.js
+++ b/frontend/public/earth/js/controls.js
@@ -2,7 +2,7 @@
import * as THREE from "three";
import { CONFIG, EARTH_CONFIG, ROTATION_MODE } from "./constants.js";
-import { updateZoomDisplay, showStatusMessage } from "./ui.js";
+import { setEarthStatValue, updateZoomDisplay, showStatusMessage } from "./ui.js";
import { toggleTerrain, setDayNightEnabled } from "./earth.js";
import { setCelestialDayNightEnabled } from "./celestial.js";
import {
@@ -873,12 +873,7 @@ async function setSatellitesLayerEnabled(button, enabled, { persist = true, sile
if (!enabled && !silent) {
showStatusMessage("卫星已隐藏", "info");
} else if (enabled) {
- ["satellite-count", "mobile-satellite-count"].forEach((id) => {
- const satelliteCountEl = document.getElementById(id);
- if (satelliteCountEl) {
- satelliteCountEl.textContent = `${getSatelliteCount()} 颗`;
- }
- });
+ setEarthStatValue("satellite-count", `${getSatelliteCount()} 颗`);
}
syncMobileLayerCards();
if (persist) persistEarthSettings();
@@ -906,10 +901,7 @@ function setBGPLayerEnabled(button, enabled, { persist = true, silent = false }
active: enabled,
tooltip: enabled ? "隐藏BGP观测" : "显示BGP观测",
});
- const bgpCountEl = document.getElementById("bgp-anomaly-count");
- if (bgpCountEl) {
- bgpCountEl.textContent = `${getBGPCount()} 条`;
- }
+ setEarthStatValue("bgp-anomaly-count", `${getBGPCount()} 条`);
syncMobileLayerCards();
if (persist) persistEarthSettings();
if (!silent) {
diff --git a/frontend/public/earth/js/main.js b/frontend/public/earth/js/main.js
index 918b42ce..e725422c 100644
--- a/frontend/public/earth/js/main.js
+++ b/frontend/public/earth/js/main.js
@@ -19,6 +19,7 @@ import {
updateCoordinatesDisplay,
updateZoomDisplay,
updateEarthStats,
+ setEarthStatValue,
setLoading,
setLoadingMessage,
showTooltip,
@@ -1032,22 +1033,9 @@ function updateBGPHud(bgpResult) {
}
}
- const bgpCountEl = document.getElementById("bgp-anomaly-count");
- if (bgpCountEl) {
- bgpCountEl.textContent = `${bgpResult.totalCount} 起`;
- }
-
- const bgpCollectorEl = document.getElementById("bgp-collector-count");
- if (bgpCollectorEl) {
- bgpCollectorEl.textContent = `${bgpResult.collectorCount} 个`;
- }
-
- ["bgp-status-summary", "mobile-bgp-status-summary"].forEach((id) => {
- const bgpStatusEl = document.getElementById(id);
- if (bgpStatusEl) {
- bgpStatusEl.textContent = getBGPStatusText(bgpResult);
- }
- });
+ setEarthStatValue("bgp-anomaly-count", `${bgpResult.totalCount} 起`);
+ setEarthStatValue("bgp-collector-count", `${bgpResult.collectorCount} 个`);
+ setEarthStatValue("bgp-status-summary", getBGPStatusText(bgpResult));
}
function ensureCruiseConnector() {
@@ -1410,12 +1398,7 @@ function updateSatelliteToggleUi(enabled, satelliteCount = getSatelliteCount())
});
}
- ["satellite-count", "mobile-satellite-count"].forEach((id) => {
- const satelliteCountEl = document.getElementById(id);
- if (satelliteCountEl) {
- satelliteCountEl.textContent = `${satelliteCount} 颗`;
- }
- });
+ setEarthStatValue("satellite-count", `${satelliteCount} 颗`);
}
function updateCableToggleUi(enabled) {
@@ -1428,15 +1411,8 @@ function updateCableToggleUi(enabled) {
});
}
- const cableCountEl = document.getElementById("cable-count");
- if (cableCountEl) {
- cableCountEl.textContent = `${getCableLines().length}个`;
- }
-
- const landingPointCountEl = document.getElementById("landing-point-count");
- if (landingPointCountEl) {
- landingPointCountEl.textContent = `${getLandingPoints().length}个`;
- }
+ setEarthStatValue("cable-count", `${getCableLines().length}个`);
+ setEarthStatValue("landing-point-count", `${getLandingPoints().length}个`);
}
async function ensureCablesEnabled() {
@@ -1553,8 +1529,7 @@ function disableSatellites() {
function updateStatsSummary() {
updateEarthStats({
cableCount: getCableLines().length,
- landingPointCount:
- document.getElementById("landing-point-count")?.textContent || 0,
+ landingPointCount: getLandingPoints().length,
bgpAnomalyCount: `${getBGPCount()} 条`,
bgpCollectorCount: `${getBGPCollectorCount()} 个`,
bgpStatusSummary: getBGPStatusSummary(),
diff --git a/frontend/public/earth/js/ui.js b/frontend/public/earth/js/ui.js
index 1963b88c..cebc40c8 100644
--- a/frontend/public/earth/js/ui.js
+++ b/frontend/public/earth/js/ui.js
@@ -19,10 +19,15 @@ function getElement(id) {
return document.getElementById(id);
}
-function setTextTargets(ids, value) {
- ids.forEach((id) => {
- const element = getElement(id);
- if (element) {
+function getEarthStatTargets(statKey) {
+ return Array.from(
+ document.querySelectorAll(`[data-earth-stat="${statKey}"]`),
+ );
+}
+
+export function setEarthStatValue(statKey, value) {
+ getEarthStatTargets(statKey).forEach((element) => {
+ if (element instanceof HTMLElement) {
element.textContent = value;
}
});
@@ -180,13 +185,13 @@ export function updateZoomDisplay(zoomLevel, distance) {
// Update earth stats
export function updateEarthStats(stats) {
- setTextTargets(["cable-count", "mobile-cable-count"], String(stats.cableCount || 0));
- setTextTargets(["landing-point-count", "mobile-landing-point-count"], String(stats.landingPointCount || 0));
- setTextTargets(["bgp-anomaly-count", "mobile-bgp-anomaly-count"], String(stats.bgpAnomalyCount || 0));
- setTextTargets(["bgp-collector-count"], String(stats.bgpCollectorCount || 0));
- setTextTargets(["bgp-status-summary", "mobile-bgp-status-summary"], stats.bgpStatusSummary || "-");
- setTextTargets(["terrain-status"], stats.terrainOn ? "开启" : "关闭");
- setTextTargets(["texture-quality"], stats.textureQuality || "8K 卫星图");
+ setEarthStatValue("cable-count", String(stats.cableCount || 0));
+ setEarthStatValue("landing-point-count", String(stats.landingPointCount || 0));
+ setEarthStatValue("bgp-anomaly-count", String(stats.bgpAnomalyCount || 0));
+ setEarthStatValue("bgp-collector-count", String(stats.bgpCollectorCount || 0));
+ setEarthStatValue("bgp-status-summary", stats.bgpStatusSummary || "-");
+ setEarthStatValue("terrain-status", stats.terrainOn ? "开启" : "关闭");
+ setEarthStatValue("texture-quality", stats.textureQuality || "8K 卫星图");
}
// Show/hide loading via status message
diff --git a/pyproject.toml b/pyproject.toml
index 94747434..615aa818 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -1,6 +1,6 @@
[project]
name = "planet"
-version = "0.35.0"
+version = "0.35.1"
description = "智能星球计划 - 态势感知系统"
requires-python = ">=3.14"
dependencies = [
diff --git a/uv.lock b/uv.lock
index 7885e459..eb0cfdc6 100644
--- a/uv.lock
+++ b/uv.lock
@@ -475,7 +475,7 @@ wheels = [
[[package]]
name = "planet"
-version = "0.35.0"
+version = "0.35.1"
source = { virtual = "." }
dependencies = [
{ name = "aiofiles" },