|
|
@@ -6,10 +6,12 @@
|
|
|
|
|
|
Blocked by: 02
|
|
|
|
|
|
-Status: ready-for-agent
|
|
|
+Status: resolved
|
|
|
Labels: ready-for-agent
|
|
|
Category: enhancement
|
|
|
|
|
|
+> 请勿据标签重复接单:本票已完成并有关闭记录,`Labels` 保留只是为了让面板不把它退化成 `needs-triage`。
|
|
|
+
|
|
|
## 依赖与事实
|
|
|
|
|
|
- 决策地图的 Cesium 调研:[Cesium integration into Fes and Vite](../web-cockpit-decision-map/issues/06-cesium-fes-vite-integration.md),产物 [cesium-fes-vite.md](../web-cockpit-decision-map/research/cesium-fes-vite.md)(含冲突清单、静态资源拷贝、`CESIUM_BASE_URL` 时序、禁止项)
|
|
|
@@ -19,23 +21,59 @@ Category: enhancement
|
|
|
|
|
|
## 验收
|
|
|
|
|
|
-- [ ] 安装 `cesium` 为运行时依赖(版本固定),**不**放进 federation 的 `shared`,并加入 `manualChunks` 单独分包。
|
|
|
-- [ ] 构建期把 `node_modules/cesium/Build/Cesium/{Workers,ThirdParty,Assets,Widgets}` 拷到产物 `cesium/` 目录,且在 `yarn dev` 与 `pre.dev.one`(`copyPublicDir:false`)两种模式下都生效。
|
|
|
-- [ ] `window.CESIUM_BASE_URL` 在 **import `cesium` 之前**设置,取值来自 `publicPath: './'`(qiankun 下用 `__INJECTED_PUBLIC_PATH_BY_QIANKUN__`),不硬编码 `/cesium/`。
|
|
|
-- [ ] `services/mapService.js` 在宿主要素上创建**唯一** `Viewer`:`mountMap()` 仍是幂等的、`resizeMap()` 转调 `viewer.resize()`、`unmountMap()` 转调 `viewer.destroy()`;`getLifecycleStats()` 语义不变。
|
|
|
-- [ ] **不使用** Ion token、`Terrain.fromWorldTerrain`、`createOsmBuildings` 等需要账号的能力(票 06 明令禁止)。
|
|
|
-- [ ] 关闭 Cesium 自带的默认控件与默认相机输入(导航控件、时间轴等)——默认左键旋转/滚轮缩放会与票 03 的三键契约打架。
|
|
|
-- [ ] 底图未配置时**不伪造地理配准**:显示明确的「底图未配置」状态,而不是把临时影像硬塞进某个假坐标范围。
|
|
|
-- [ ] 引擎初始化失败时页面不白屏:给出明确失败状态,中央区域仍有可读兜底(现有临时影像或纯色 + 文案)。
|
|
|
-- [ ] 现有的 17 项走查断言全部仍然通过(尤其是 A14 地图宿主实例 id 不变、A12 铺满几何)。
|
|
|
-- [ ] 新增可观测证据:走查断言宿主内只有 **1** 个 Cesium 画布、实例 id 跨模式切换与面板收放保持不变、且 worker 静态资源可访问(HTTP 200)。
|
|
|
-- [ ] 逻辑断言脚本中的地图服务生命周期一节继续通过(幂等挂载、只创建一次、销毁语义)。
|
|
|
+- [x] 安装 `cesium` 为运行时依赖(版本固定),**不**放进 federation 的 `shared`,并加入 `manualChunks` 单独分包。
|
|
|
+- [x] 构建期把 `node_modules/cesium/Build/Cesium/{Workers,ThirdParty,Assets,Widgets}` 拷到产物 `cesium/` 目录,且在 `yarn dev` 与 `pre.dev.one`(`copyPublicDir:false`)两种模式下都生效。
|
|
|
+- [x] `window.CESIUM_BASE_URL` 在 **import `cesium` 之前**设置,取值来自 `publicPath: './'`(qiankun 下用 `__INJECTED_PUBLIC_PATH_BY_QIANKUN__`),不硬编码 `/cesium/`。
|
|
|
+- [x] `services/mapService.js` 在宿主要素上创建**唯一** `Viewer`:`mountMap()` 仍是幂等的、`resizeMap()` 转调 `viewer.resize()`、`unmountMap()` 转调 `viewer.destroy()`;`getLifecycleStats()` 语义不变。
|
|
|
+- [x] **不使用** Ion token、`Terrain.fromWorldTerrain`、`createOsmBuildings` 等需要账号的能力(票 06 明令禁止)。
|
|
|
+- [x] 关闭 Cesium 自带的默认控件与默认相机输入(导航控件、时间轴等)——默认左键旋转/滚轮缩放会与票 03 的三键契约打架。
|
|
|
+- [x] 底图未配置时**不伪造地理配准**:显示明确的「底图未配置」状态,而不是把临时影像硬塞进某个假坐标范围。
|
|
|
+- [x] 引擎初始化失败时页面不白屏:给出明确失败状态,中央区域仍有可读兜底(现有临时影像或纯色 + 文案)。
|
|
|
+- [x] 现有的 17 项走查断言全部仍然通过(尤其是 A14 地图宿主实例 id 不变、A12 铺满几何)。
|
|
|
+- [x] 新增可观测证据:走查断言宿主内只有 **1** 个 Cesium 画布、实例 id 跨模式切换与面板收放保持不变、且 worker 静态资源可访问(HTTP 200)。
|
|
|
+- [x] 逻辑断言脚本中的地图服务生命周期一节继续通过(幂等挂载、只创建一次、销毁语义)。
|
|
|
|
|
|
## 不在本票范围
|
|
|
|
|
|
- 相机三键契约(票 03)、3D Tiles/地形/倾斜摄影(票 21)、管线渲染(票 22)、监测点与事件图层(票 08/09)。
|
|
|
- 真底图来源(天地图/甲方本地瓦片):票 06 调研定性为「底图校验」与正式资源两条路,归票 21。
|
|
|
|
|
|
-## 进度:0%
|
|
|
+## 进度:100%
|
|
|
+
|
|
|
+**已完成并关闭(2026-09-17)。** 中央一张图现在挂的是真实 Cesium Viewer:引擎、静态资源、`CESIUM_BASE_URL` 时序都在**地图服务层**,外壳与 `MapCanvas` 组件未改。
|
|
|
+
|
|
|
+### 改动
|
|
|
+
|
|
|
+- `package.json` / `yarn.lock`:`cesium@1.145.0`(固定版本),不进 federation `shared`。
|
|
|
+- `.fes.js`:注册 `cesiumStatic()`;`manualChunks` 增加 `cesium: ['cesium']`。
|
|
|
+- 新增 `src/common/cesiumStaticPlugin.js`:dev / pre.dev(.one) 下把 `<base>/cesium/*` 映射到 `node_modules/cesium/Build/Cesium` 的**四个白名单目录**(Workers/ThirdParty/Assets/Widgets,防目录穿越);build 下把同样四个目录逐个拷进产物 `cesium/`(`pre.dev.one` 的 `copyPublicDir:false` 同样生效)。
|
|
|
+- 新增 `src/modules/cockpit/services/cesiumAssets.js`:`window.CESIUM_BASE_URL` 必须在 `import 'cesium'` 之前写入,所以本模块刻意不 import cesium —— 取值顺序为 qiankun 注入路径(有则优先)→ `import.meta.env.BASE_URL`(即 `publicPath: './'`)→ 相对 `document.baseURI` 解析成绝对 URL,全程无硬编码 `/cesium/`。
|
|
|
+- 新增 `src/modules/cockpit/services/cesiumEngine.js`:本仓库唯一 `import 'cesium'` 的地方(由服务层动态 import 触发,时序可控)。`new Viewer(host, …)`:自带控件全关、`baseLayer: false`(不配底图 → 不伪造地理配准)、逐项关掉默认相机输入(`enableRotate/Zoom/Tilt/Look/Translate = false`,不依赖临时的 `enableInputs`)、不碰任何需要账号的能力(无 Ion token / `Terrain.fromWorldTerrain` / `createOsmBuildings`)。
|
|
|
+- 改 `src/modules/cockpit/services/mapService.js`:`mountMap(host)` 仍幂等且只创建一次;宿主是真 DOM 元素时才异步起引擎(加载期间被销毁则不留实例、加载期间的尺寸变化会在就绪后补一次),`resizeMap()` → `viewer.resize()`、`unmountMap()` → `viewer.destroy()`;引擎态(idle/unavailable/booting/ready/failed)与底图态写进宿主 `data-map-engine` / `data-map-basemap`,并在宿主内自绘一块状态浮标(这样组件不必改);`getLifecycleStats()` 原六个字段语义不变,另加 `engine` / `engineError` / `basemap`。
|
|
|
+- 未改 `MapCanvas.vue` 与外壳:宿主元素、`data-map-instance`、临时影像兜底都保持原样(本票会话未改这两个文件;同期票 06 会话对它们的改动属票 06)。
|
|
|
+
|
|
|
+### 验证证据(本机 2026-09-17,服务 `http://localhost:8000`)
|
|
|
+
|
|
|
+- **逻辑断言**:`node .scratch/cockpit-shell-panel-layout/verify/t01-panel-catalog.mjs` → 通过。新增「Cesium 资源基址」一节:`./` + `#/cockpit` → `http://localhost:8000/cesium/`、子目录部署、qiankun 绝对基址、根相对基址都按预期解析;非 DOM 宿主不启动引擎且如实标注 `unavailable` / `not-configured`;地图服务生命周期一节(幂等挂载、只创建一次、销毁语义)继续通过。
|
|
|
+- **浏览器走查(`yarn dev`)**:`node .scratch/cockpit-shell-panel-layout/verify/t01-browser-walkthrough.mjs` → **20/20 通过**(原 17 项 + 本票新增 3 项):
|
|
|
+ - A15:宿主内恰好 1 个 `.cesium-viewer` / 1 个画布、`data-map-engine=ready`、`data-map-basemap=not-configured`、状态文案含「底图未配置」、工具栏内无任何自带控件、`CESIUM_BASE_URL=http://localhost:8000/cesium/`,且走完四模式切换 + 面板收放后实例 id 仍是 `cockpit-map-1`。
|
|
|
+ - A16:`Workers/transferTypedArrayTest.js`、`Assets/approximateTerrainHeights.json`、`Widgets/widgets.css` 全部 HTTP 200。
|
|
|
+ - A17(对抗式):用 CDP 拦掉 cesium 依赖包强制失败 → `data-map-engine=failed`、文案含「初始化失败」、画布数 0、临时影像兜底仍在、外壳照常渲染(不白屏)。
|
|
|
+- **`yarn pre.dev.one`(`copyPublicDir:false`)**:同一份走查 **19/20**,本票相关的 A14/A15/A16/A17/A11 全绿(静态资源同样 200);唯一红的是 A12「铺满视口」,证据里 `pageHeaderH=54` —— `pre.dev.*` 是 TvT 演示站点布局(`navigation:'top'` + 固定页头),外壳填的是容器而非视口。该环境差异已由票 06 会话查清并立票 28,与本票无关。
|
|
|
+- **构建期拷贝**:`yarn pre.build.one` 的构建日志里插件逐个拷贝四个目录 —— `✔ Copied: …\Build\Cesium\Workers → dist\cesium\Workers`(ThirdParty / Assets / Widgets 同),产物 `dist/cesium/` 下只有这四个目录,不再带 `Cesium.js` / `index.js` / `index.cjs` 三个 ESM 打包用不上的入口包(首轮曾整目录拷贝,已按验收收窄)。
|
|
|
+
|
|
|
+### 遗留 / 已排除为本票回归
|
|
|
+
|
|
|
+- **本工作区 `yarn build` / `pre.build.one` 目前跑不通(预先存在、与本票无关)**:两个未纳入版本管理的插件缺依赖 —— `src/plugins/useThreeGeospatial` → `@takram/three-3d-tiles-support`、`src/plugins/map2BuildingRoad` → `leaflet`;Rollup 在渲染 chunk 之前就失败,因此 `manualChunks` 的 cesium 分包**只有配置证据、没有产物证据**。本票的运行时证据取自 dev / pre.dev.one(走查也在这两个模式下跑)。
|
|
|
+- 与票 26 同类的**新触发源**:`pre.dev.one` 首次启动时 watcher 被 `src/modules/cockpit/components/.MapCanvas.vue.<pid>.<guid>.tmpdir/MapCanvas.vue.tmp` 击穿(DSH 编辑审阅临时目录这次落在源码目录旁,不匹配现有忽略清单 `**/.scratch/**` + `**/.dsh-*`)。目录是瞬时的,重试即过,故本票未改忽略清单;建议票 26 补一条 `**/*.tmpdir/**`,或由维护者定夺。
|
|
|
+- 相机三键契约与真底图分别归票 03 / 21;本票只保证「默认输入已关」与「不伪造配准」。默认相机仍是全球视角;无底图球体 + 默认星空背景会盖住外壳的全息网格/扫描线浮层(`.map-holo__grid` 等 `z-index: auto`,被后插入的画布遮住),观感收口建议随票 03/21 一并定。`MapCanvas` 底部那句「临时底图 aerial.webp · 票 02 已建常驻宿主」在引擎就绪后已过时,因票面要求「组件不改」未动,需维护者定夺改法。
|
|
|
+- `resizeMap()` / `unmountMap()` 的转调是**代码级**证据:走查不离开 `/cockpit`,所以 `viewer.destroy()` 未在运行时直接断言;`viewer.resize()` 因 Cesium 自带 postUpdate 自动 resize,也没有做「这次 resize 确由本服务发起」的观测。
|
|
|
+- 本票改动**未提交**(工作区里另有同期票 06 会话的提交 `74720b2` 与若干未跟踪的插件目录)。
|
|
|
+
|
|
|
+## 复跑复核(票 28 会话独立复核,2026-09-17)
|
|
|
+
|
|
|
+原先的长跑 dev server 停掉后,用 `yarn dev` 全新启动再跑同一份走查:**20/20 通过**,A15 `widgetChrome: 0`。用 DOM 探针确认这不是「被隐藏」而是真的没有:`.cesium-viewer-toolbar` 存在但**零子元素**,`.cesium-viewer-animationContainer` 与 `.cesium-viewer-timelineContainer` **都不存在**——票面「默认控件全关」的结论成立,A15 的选择器并不过严。
|
|
|
+
|
|
|
+此前同一份代码上出现过一次 19/20(A15 红、`widgetChrome: 1`)。两次唯一的差别是服务实例:那次打的是**长时间运行的旧 dev server**,最可能是它给浏览器发到了更早的 `cesiumEngine.js` 模块(陈旧模块),不是代码或断言问题;事后无法回溯证实,故只作推断记录。教训:涉及引擎/懒加载模块的走查,**复跑前重启 dev server**(该条已写进走查脚本头部与 `map.md` 的 Notes)。
|
|
|
|
|
|
-已立案。归属与依赖由维护者确认(新增票 27,并作为票 03 的前置——三键相机契约必须落在真实引擎上)。
|
|
|
+结论:票面 20/20 与关闭结论成立,本复核只是另起一份干净服务上的可复现证据;票面正文无需改动。
|