来源:lanhu-cockpit-asset-replacement 地图全部 20 张子票(8 决策 + 5 规格 + 5 执行 + 盘点/迁移各 1)的讨论与实施沉淀。
性质:本项目「设计素材接入」类任务的单一经验来源(single source of truth)。后续同类任务(换设计稿、接新素材、改视觉体系)先读本文,不再逐轮重新发明。
生效范围:城市生命线驾驶舱 /cockpit 的 2D UI 素材、图标、位置符号、字体、装饰。
配套文档(各自仍是其领域的单一事实来源):
设计稿差异默认归入素材替换,不无谓升级为结构决策;仅当差异触及状态语义 / 信息层级 / 交互契约 / 数据契约时才升级。
| 属视觉(可改) | 属结构(须升级) |
|---|---|
| 两栏宽、面板高、边距、间距、字号 | 面板数量、面板顺序、列排列、两栏改单栏 |
| 图标/颜色/字体/纹理/形状外观 | 状态集合与触发时机、图层显隐、拾取、聚合、状态语义 |
| 数据展示格式(时间/千分位/小数位) | 数据字段、单位、口径 |
| 视觉反馈层(光效、动效表现) | 相机交互、选择态、定位/拾取/联动契约 |
设计稿未覆盖的现有 UI 维持现状并标记「无设计稿依据」,不因蓝湖没画就删除或臆造样式。
色值只在 styles/tokens.css 声明一份;素材若自带彩色即成第二套色源。实测教训:素材成品色与项目语义色无一相同(素材 Red #E80000 vs --lv1 #ff4d5e),因此只采用纯白可着色母版 + 运行时注入状态色。
临时素材必须带标记(manifest status: temporary);验收不得以临时资源作为正式视觉通过;缺口清单必须列出仍未替换的临时项。
组件/地图服务/设备资产层只消费语义 key,不直接引用物理路径。条目须含:语义 key、路径、来源、格式/尺寸、发布版本、内容 hash、状态(formal/temporary)、适用范围、核心标记、fallback key。
所有资源引用走 import.meta.env.BASE_URL(或宿主注入基址),禁止硬编码 /cockpit/...,以兼容相对 publicPath 与 qiankun 注入路径。
本图建立的接缝(后续复用,不要另起):
domain/markerPlan.js):母版归属 / 内层图标几何 / 尺寸 / 锚点 / 着色 / 降饱和,纯数据产出,渲染媒介可换。点位状态(六态)与设备状态(五态)是两张平行表,色键可同、语义不混;认不出的状态如实落「状态未发布」,不猜成正常。颜色不是唯一线索(形状 + 文字并存)。
| 坑 | 现象 | 纪律 |
|---|---|---|
| manifest 被并发脚本整文件重写 | 另一会话跑 build-manifest.mjs 把 fonts 块抹掉(26409→15538 字节),字体静默失效 |
脚本重写前保留未知顶层块;build-manifest.mjs 已加跨批防覆盖闸门(未登记 entries 存在即中止) |
Vite 缓存 import 的 manifest 转译结果 |
外部脚本改写 manifest 后页面拿到旧模块,字体静默不生效 | 门禁如实报 fonts-unavailable 使其可观察;改完 manifest 必须硬刷新 |
| HMR 模块图陈旧 | HMR 只热更边界组件、不重载其传递依赖的 manifest,浏览器仍跑旧 manifest | 同上;判定效果前先硬刷新 |
| 「字体请求为 0」被误判为正常 | Web 字体排在回退链首位,页面文本必用到;请求为 0 说明字体没生效 | 「字体请求为 0」必须判 FAIL |
| 窄视口响应式缺陷 | --u 触底 1px 后顶栏总宽超视口,grid 挤压菜单列 → 按钮文字换行被定高裁成单字 |
响应式回归必须覆盖窄视口(此前十轮只在大视口验证) |
| 图片盒子被整图拉伸 | 装饰线可见段按百分比映射视口,挪图片盒子永远无效 | 用裁切窗口(background-size + position)而非挪盒子 |
| 切图撑高 grid 行 | 标题切图作为 grid 项内容把顶栏行撑高,「垂直居中」基准被改 | 定高容器 + 绝对定位让溢出不占布局 |
mask-image 不收层语法 |
四角切角染色自误 | 色值收口时验证 mask 语法 |
| 单点验证代替全域验证 | 同一代码在不同视口/环境表现不同(predev 有 54px 页头) | 明确验收环境;predev 差异不等于产品缺陷 |
| 锚点迁移留下假绿 | 断言按旧口径建立,改渲染后仍绿 | 锚点口径变更必须同步更新断言并以对抗方式确认能失败 |
维护者提供的字体目录 E:\_Design\字体 零授权文件,且含明确 All rights reserved 的字库(Modernia、Furore)与多款公认商用收费字库。不得以目录为单位放行——必须逐族取证。
中文开源字体单字重约 15–16 MB;必须子集化或限定字重档数,且必须保留系统回退链(动态数据可能含子集外汉字,否则出豆腐块)。
自动化只能校验「是否携带许可证据」,不声称能判定授权合法性——授权合法性是法律事实,由证据文件与责任人负责。
阻断:① 核心资源组(品牌标识 / 点位设备状态形状语义 / 状态色语义)不可用;② 视觉会误导业务语义;③ 法规/授权风险。 允许带回退交付:其余缺口,条件是登记缺口清单 + 临时资源带标记 + 验收不把临时资源当正式视觉。
品牌/图标、面板 token、位置符号、字体、装饰五批;位置符号依赖 token(外层母版着色),装饰最后;品牌/图标、token、字体可并行。
素材已入库且过 manifest 校验(存在、hash、fallback 齐全)+ 该批有可执行验收清单 + 已用差异判断表分类。
实现者自测(纯逻辑断言 + 宿主 data-* 读数 + 结构回归)+ 维护者走查真实 /cockpit 并签收。终稿验收是最后一道闸,不是第一道。
P0 阻断(复用上述三类判据)/ P1 高(1280px 不可读、位置符号不可辨、锚点错位)/ P2 中(观感、性能)/ P3 低(非核心装饰,入缺口清单后可发布)。
核心资源组全部换正式素材 + 缺口清单无「临时素材仍在使用」条目;非核心装饰留临时项时在缺口清单显式登记「未替换」。最终以逐项关闭清单留痕并由维护者签收。
最小 1280×720 下:文字可读、按钮可操作、面板不重叠优先;左右栏保持宽度,面板内纵向滚动,支持卷轴式展开/折叠,装饰可缩放/隐藏/降级。
| 环境 | 地址/状态 | 说明 |
|---|---|---|
真实 /cockpit |
http://127.0.0.1:8000/#/cockpit |
唯一开发/验收入口,所有会话统一使用,不另起端口 |
| 后端只读接口 | http://192.168.110.96:8301/api/cockpit/v1/** |
免鉴权;dataSource: real |
| qiankun 宿主 | 本仓不存在宿主工程 | 仅被嵌侧适配代码 src/.fes/plugin-qiankun/;宿主验收需临时自建(见下) |
| predev 预演站 | npm run pre.dev |
有 54px 页头,布局差异不等于产品缺陷 |
自建最小宿主可验证「加载 + 挂载 + 基址注入」:
TvT.js(dev HTML 实测);生命周期经 window.moudleQiankunAppLifeCycles['TvT.js'] 暴露。props.url(如 /cockpit),否则被嵌侧不切 memory history、/cockpit 不渲染。__INJECTED_PUBLIC_PATH_BY_QIANKUN__ = http://127.0.0.1:8000/,基址注入生效。src/.fes/plugin-qiankun/micro/runtime.js:24 解构 { router, history } 并在 :26 调 history.push(...),但 FES 4 的 onRouterCreated 契约只保证 router(同签名的 plugin-access 只解构 { router })→ 宿主内抛 Cannot read properties of undefined (reading 'push'),/cockpit 落在宿主默认页。该文件 git status 无本地改动,属宿主集成既有问题,不属素材替换范围。resolveCesiumBaseUrl() 对注入基址的三条断言已全绿)。开工前
实施中
tokens.css;无散落物理路径;无死资源BASE_URL;不硬编码绝对路径收口前
/cockpit 走查本文由 lanhu-cockpit-asset-replacement 地图收口时提取。后续同类任务请以本文为起点;若与本文冲突,以更新的决策票为准并回写本文。