# 批次 1 验收说明:品牌/图标替换 关联:[执行-批次1:品牌/图标替换](issues/14-exec-batch1-brand-icons.md) 蓝湖来源:项目「城市生命线驾驶舱」,9 个画板 2026-10-12 版(v3/v4) 本文档只讲**怎么验收**;改动理由与映射过程见票 14 与[复查附录](research/19-lanhu-artboard-inventory.md)。 --- ## 0. 一句话:改了什么 驾驶舱顶栏品牌位与地图四个图层 chip 的图标,从**代码内联的几何占位图形**换成**蓝湖导出的正式切图**,经统一资产解析层按语义 key 消费。 只有 6 个位置会看到变化: | 位置 | 改动前(占位) | 改动后(正式切图) | | --- | --- | --- | | 顶栏品牌位 | 同心圆 + 十字轴线,白色描边 | 渐变浅蓝底板 + 顶部青色亮边(蓝湖 `nav/title-bg`) | | chip「管线图层」 | 三层叠片菱形 | 网格方块 | | chip「监测点」 | 双同心圆 | 水滴 | | chip「事件定位」 | 空心三角 + 感叹号 | 实心警告三角(橙黄) | | chip「应急资源」 | 屋顶+门框线稿 | 火焰(红橙) | | 空面板占位 | 折线框 + 折线 | **不变**(设计稿未覆盖,仍走原占位) | > **首次交付未能生效,2026-10-12 已修复。** 审核发现「图标没有应用到场景中」,连到真实运行地址定位到两个叠加缺陷: > ① **资源路径少一级目录**——manifest 写 `icons/brand.png`,文件实际在 `public/cockpit/assets/icons/`,导致浏览器请求 `/cockpit/icons/brand.png` 落到 Vite 的 dev 兜底页上,**返回 200 + `index.html`**,`status: 200` 骗过了 HTTP 层与原格式校验两层检查(复现坑见 §3); > ② **品牌位改宽挤掉标题**——品牌槽从 32×32 改成 90×34 后,顶栏「城市生命线驾驶舱系统」被截断,已按切图原比例收回 50×19。 > 修复后复验:6/6 资源返回正确 `image/png` / `image/svg+xml` 与正确字节;标题完整显示;品牌底板在顶栏可见。 > 同时把校验补强到**文件真实可达 + 拒绝 HTML 兜底页 + 内容 hash 一致**,避免同类问题再靠人工发现。 > 另需知悉:`icon.brand` 素材本身像素级实测 **alpha 仅 10–18%**,是半透明装饰板,叠在深色顶栏上呈低调浅蓝光晕——这是素材特性,不是渲染故障;其余四枚为完全不透明的实心彩色图标。 --- ## 1. 验收方式一:静态核对(不跑任何服务,1 分钟) 在仓库根目录执行,逐条比对: ```powershell # 1.1 正式切图已入库(17 个 PNG + 1 个临时 SVG) Get-ChildItem public/cockpit/assets/icons | Select-Object Name, Length # 1.2 旧占位 SVG 已删除(应只余 blank.svg) Get-ChildItem public/cockpit/assets/icons -Filter *.svg # 1.3 manifest 状态:17 条 formal + 1 条 temporary(且文件真实可达) node .scratch/lanhu-cockpit-asset-replacement/research/check-manifest.mjs # 1.4 确认组件与地图服务中没有散落的物理路径(只应命中解析层 1 处) git grep -n "cockpit/assets" -- src # 1.5 四处交叉引用一致性:注册表 ↔ manifest ↔ 组件引用 ↔ 面板/行业映射 node .scratch/lanhu-cockpit-asset-replacement/research/cross-check-icons.mjs ``` **判定**:1.1 看到 17 个 png + `blank.svg`;1.2 只剩 `blank.svg`;1.3 打印 `manifest 校验通过(含文件可达性与 hash 一致性)`,**退出码 0**;1.4 只出现 `runtimeAssets.js:15` 一行;1.5 打印 `✅ 四处交叉引用完全一致`。 > 1.3 现在会比对磁盘上的真实文件、拒绝 HTML 兜底页、并核对内容 sha256——这三项正是本次缺陷 1(路径少一级目录、被 dev 兜底成 200 HTML)漏掉的口子,已补上。 补充人工核对(打开文件看): - [ ] `public/cockpit/assets/manifest.json` 中每条含 `source.board`(蓝湖画板名)、`source.layer`(图层路径)、`source.url`(导出地址)、`hash`(sha256)、`dimensions`、`status` - [ ] `src/modules/cockpit/components/CockpitIcon.vue` 有 `renderMode === 'image'` 分支(彩色切图)与 mask 分支(单色)并存 - [ ] `src/modules/cockpit/CockpitShell.vue:1709` 附近 `.cockpit-shell__mark` 为 `width: calc(50 * var(--u))`、`height: calc(19 * var(--u))`(按切图 90:34 原比例缩放;直接用 90×34 会把标题挤出顶栏),且选择器含 `img` - [ ] `src/modules/cockpit/CockpitShell.vue` 的 `.cockpit-shell__brand-text` 带 `flex: none`(保证标题不被压缩) --- ## 2. 验收方式二:看切图本身(30 秒) 直接看蓝湖导出的正式切图: | key | 文件 | 应看到 | | --- | --- | --- | | `icon.brand` | [brand.png](../../public/cockpit/assets/icons/brand.png) | 浅蓝渐变矩形板,顶部一条青色亮线 | | `icon.layers` | [pipe-facility.png](../../public/cockpit/assets/icons/pipe-facility.png) | 管网设施(弯管,蓝渐变) | | `icon.points` | [pipe-alert.png](../../public/cockpit/assets/icons/pipe-alert.png) | 预警处置(警灯,蓝渐变) | | `icon.event` | [pipe-command.png](../../public/cockpit/assets/icons/pipe-command.png) | 应急指挥(文档+警示三角,蓝渐变) | | `icon.resource` | [scale-kind.png](../../public/cockpit/assets/icons/scale-kind.png) | 规模种类(双层数据库堆叠,蓝渐变) | | `icon.manhole` | [manhole.png](../../public/cockpit/assets/icons/manhole.png) | 井盖(紫色网格球) | | `icon.infrastructure` | [infrastructure.png](../../public/cockpit/assets/icons/infrastructure.png) | 楼宇 | | `icon.facility` | [facility.png](../../public/cockpit/assets/icons/facility.png) | 立方体(红) | | `icon.safety` | [safety.png](../../public/cockpit/assets/icons/safety.png) | 盾牌对勾 | | `icon.history` | [history.png](../../public/cockpit/assets/icons/history.png) | 时钟 | | `icon.efficiency` | [efficiency.png](../../public/cockpit/assets/icons/efficiency.png) | 绿色对勾圆 | | `icon.pulse` | [pulse.png](../../public/cockpit/assets/icons/pulse.png) | 信号波形 | | `icon.close` | [close.png](../../public/cockpit/assets/icons/close.png) | 关闭叉 | | `icon.emergency` | [emergency.png](../../public/cockpit/assets/icons/emergency.png) | 大火焰 | | `icon.industry.gas` | [industry-gas.png](../../public/cockpit/assets/icons/industry-gas.png) | 消防栓(绿) | | `icon.industry.water` | [industry-water.png](../../public/cockpit/assets/icons/industry-water.png) | 水波 | | `icon.industry.drainage` | [industry-drainage.png](../../public/cockpit/assets/icons/industry-drainage.png) | 雨云 | **判定**:17 张都能正常显示(不是空白/破损);语义对得上——弯管=管线图层、警灯=监测点、文档警示=事件定位、数据库堆叠=应急资源(均为维护者指派的 Pipe/Q 系列切图)、紫网格球=井盖(行业筛选「窨井」)、楼宇=基础设施、消防栓=燃气、水波=供水、雨云=排水、时钟=历史、对勾=效率、波形=实时监测。 > 若图片显示不出来,先确认浏览器没有拦截本地相对路径;也可直接用系统图片查看器打开。 --- ## 3. 验收方式三:跑起来看真实效果 **真实运行地址:`http://127.0.0.1:8000/#/cockpit`**(维护者已提供并在运行,无需重启)。 ### ⚠ 三个必须知道的坑(第一次验收就是在这里翻车的) 1. **入口遮罩**:打开后先点画面中央「**点击进入系统**」,否则看到的是入口页而非驾驶舱。 2. **chip 图标在折叠面板里**:四个图层图标(网格/水滴/三角/火焰)渲染在地图右上角「**地图摘要**」浮标的**展开态**。默认是折叠的,必须点开才能看到——它们不在地图表面。 3. **本仓 dev 会把不存在的路径兜底成 200 + index.html**:所以「Network 里状态码是 200」**不能**证明图片拿到了。要看 `Content-Type` 是不是 `image/png`;若是 `text/html` 说明路径错了(这正是本次修复的缺陷 1)。 ### 走查清单(真实页面) **① 顶栏品牌位** - [ ] 品牌位左侧有一块**浅蓝色半透明底板**(不是改动前的白色同心圆) - [ ] 标题「城市生命线驾驶舱系统」**完整显示**,没有被模式按钮压住或截断 - [ ] 顶栏无溢出、四个一级模式按钮位置正常 **② 16 个面板标题图标(切换四个一级模式逐一看)** - [ ] 每个面板标题文字**前**有一个小图标,位置在青色竖条之后 - [ ] 语义对应正确:基础设施=楼宇、基础档案/管理信息=立方体、应急保障=大火焰、运行监测类=波形、监测点台账=水滴、历史分析=时钟、预警效率=对勾、预警/事件类=三角、汇总类=网格 - [ ] 图标没有被标题的发光糊成一团,边缘可辨 - [ ] 面板标题文字未被图标挤压(不换行、不截断) - [ ] 面板收放(+/-)功能正常,`data-panel-id` 仍在 **③ 行业筛选按钮图标(顶栏「行业」一栏)** - [ ] 燃气=消防栓、供水=水波、排水=雨云、窨井=井盖(紫色网格球) - [ ] 「全部」按钮**没有**图标(它不对应任何行业语义) - [ ] 图标与文字间距均匀,点击/选中态正常,`data-industry` 仍在 **④ 四个图层 chip(需先点开「地图摘要」浮标;须与文字同行)** - [ ] 「管线图层」= 管网设施(弯管) - [ ] 「监测点」= 预警处置(警灯) - [ ] 「事件定位」= 应急指挥(文档+警示) - [ ] 「应急资源」= 规模种类(数据库堆叠) - [ ] 四个 chip 的**图标与文字在同一行**(若文字折到图标下方即为回归,`.map-info__layer-chip` 失效) - [ ] 四个图标**颜色正确**(发白或全黑说明错走单色 mask 分支,是 bug) **⑤ 无地图位置浮块** - [ ] 「无地图位置」标题前的水滴图标正常显示 **⑥ 空面板占位** - [ ] 任一无数据面板内的占位图示仍为原折线框样式(**预期不变**,`icon.blank` 是 `temporary`) **⑦ 结构未受影响(重点回归)** - [ ] 四个一级模式切换正常,面板内容随之变化 - [ ] 行业筛选点击后面板数据随之刷新 - [ ] 地图标记、状态图例、点选与定位行为与改动前一致 - [ ] 控制台无 Vue 报错、无资源 404 - [ ] 按钮可访问名仍是纯文字(图标不参与命名,控制台读 `button.textContent.trim` 应与改动前一致) ### 读数断言(浏览器控制台执行,用于留证) ```js // 应输出渲染出来的图标:17 条 formal + 1 条 temporary(品牌位 1 + 行业 4 + 面板按当前模式若干 + chip 4) Array.from(document.querySelectorAll('[data-icon-name]')) .map(el => `${el.dataset.iconName}=${el.dataset.assetStatus}`) // 面板图标覆盖度:切四个一级模式,看 16 个 panelId 是否都出图标 Array.from(document.querySelectorAll('[data-panel-id]')) .map(el => `${el.dataset.panelId}:${el.querySelector('[data-icon-name]')?.dataset.iconName || 'MISSING'}`) ``` **期望**:所有条目的 status 为 `formal`,只有 `blank=temporary`;`data-panel-id` 列表 16 项且**无 `MISSING`**。 若某条为空 → 该图标没渲染出来;Resource 面板里搜 `cockpit/assets/icons`,确认 `Status` 列是 `200` 且 `Content-Type` 为 `image/png`(若为 `text/html` 即路径错误)。 截图留存:顶栏品牌位一张、行业筛选栏一张、某模式的左/右栏面板标题一张、地图摘要展开后的四个 chip 一张。 --- ## 4. 判定标准 | 结果 | 结论 | | --- | --- | | 静态全过 + 走查 ①–⑦ 全过 | 批次 1 通过,可关闭票 14 | | 静态全过 + ① 或 ② 观感不可接受 | 记为视觉偏差,登记进票 06 缺口清单 | | ② 图标发白/全黑 | **缺陷**:走了单色渲染分支,需要修 `CockpitIcon.vue` 的 image 分支 | | ⑤ 出现模式/面板/地图行为变化 | **阻断**:说明改动越界,需回退并复查 | --- ## 5. 不通过怎么回滚 本批改动是自包含的,回滚成本低: ```powershell # 回滚代码与 manifest(会一并恢复 5 个占位 SVG) git checkout -- src/modules/cockpit public/cockpit # 或只回滚品牌位尺寸调整(切图本身保留) # 编辑 src/modules/cockpit/CockpitShell.vue 的 .cockpit-shell__mark,恢复 32×32 ``` 回滚后:顶栏恢复白色同心圆,四个 chip 恢复几何占位图形,其余功能不受影响(资产层改动已隔离在 `icons.js` / `runtimeAssets.js` / `CockpitIcon.vue` 三处)。 --- ## 6. 本次未做的事(避免误判) - **未运行 build/dev/浏览器**:受 `AGENTS.md` 限制,视觉效果的最终判定必须由方式三完成。 - **未改动**:四个一级模式、16 个二级面板、`panelId`、状态词表、地图图层、拾取与定位契约——本批只换素材来源。 - **`icon.blank` 仍是占位**:设计稿确实没有空面板占位图示,属「设计稿未覆盖」,不算缺陷。 - **切图取自面板内同义图标**:蓝湖的图层 chip 本身仍是纯文字,本批按语义对应取用面板内的网格/水滴/三角/火焰;若设计方本意是 chip 专用图标,可在走查时提出。