# 版本记录(观澜·如东样板 v2) > 本文件由 `scripts/version_log.py` 生成,**勿手改**:事实(版本号、级别、变更)写在 > `src/version.py` 的 `HISTORY` 里,改完跑 `python scripts/version_log.py --write`。 > `guanlan.py check` 与打包器都会校验本文件与代码里的版本号是否一致。 ## 版本号规则(用户令 2026-09-17) 编号 **`v<大版本号>.<中版本号>.<小版本号>`**,例如 `v2.79.1`。 | 级别 | 含义 | |---|---| | 大版本号 | 系统解决方案、架构或核心功能改变 | | 中版本号 | 非核心功能新增、减少、修改 | | 小版本号 | 消缺完善 | **怎么改**:改动落在"解决方案/架构/核心功能" → 大 +1(中/小归 0);落在"非核心功能的新增/减少/修改" → 中 +1(小归 0);只是"消缺完善" → 小 +1;一次发布混了几类,取最高那一级 **打包文件名** = `app_guanlang_v2.79.1.zip`(规则:`app_guanlang_v<版本号>.zip`)。 版本号只写在 `src/version.py` 一行(`VERSION = '2.79.1'`);打包器、安装脚本、安装记录 `install-info.json`、自检都读它,不另设真源。 | 版本 | 日期 | 级别 | 主要变更 | 说明 | |---|---|---|---|---| | `v2.79.1` | 2026-10-04 | 小 | 入库「整页外壳对比」工具;回滚一次导致挂载失败的外壳对齐尝试 | 用户令:核对 `/detail/v2#workbench` 与 v2.9.2 对应页(工作台)的差异。① 此前的结构判据只比 `#root`(页签内容,已 10/10),**页头/页签栏等外壳从未比过**。新增 `app_frontEnd/web/tools/full_diff.mjs`:把 v2.9.2 原文页与新版 `/detail/v2#workbench` 的 **整个 `
` 元素骨架**(tag.class 序列)逐项对比。② 实测差异(基线 354 元素 · 新版 357 元素):(a)品牌区:基线 `span.mark`(≋) + `span.brand`(观澜 + `small` 英文),新版只有单个 `div.brand`;(b)右侧簇:基线 `div.right` 内含 `a.back-portal`(返回门户) + `button.reselect` + `label` + `select#win` + `span.winrng`,新版**缺 `div.right` 与「返回门户」**,且时间窗控件被放在**页头下方的 .page-head** 里(基线在页头右侧);(c)页签栏:基线是 `nav.tabs#tabs`,位于**页头与 main 之间(main 之外)**;新版是 `nav.wb-tabs`,位于 **main 内部**;(d)新版页头多了 Vue 应用自己的三个按钮(工作台/契约自检/关于);(e)新版 body 下多一层 `div#app`(Vue 挂载点,`#root` 比较域之外,不影响页签级一致性)。③ 我尝试按基线一次性对齐(页头 mark/brand/right + 页签栏外移),但**改坏了挂载**(漏 import ⇒ `t is not a function`、随后 `TABS` 未定义 ⇒ 页面只剩挂载点)。**已回滚** `App.vue` / `Workbench.vue` 到 2.79.0 并重新部署,远端 `/detail/v2` 与资源已恢复 200 ✓。教训:外壳比页签内容牵连更多(挂载/导入/VA),必须**一步一验**,不能批量改。 | | `v2.79.0` | 2026-10-04 | 中 | 工作台补全套时间窗控件(照 v2.9.2);门户装配改分阶段(壳先出、内嵌件流式注入) | 用户两项:① **`/detail/v2#workbench` 找不到时间窗控件** —— 旧页的控件是"重选按钮 + 时间窗下拉(预设/自定义/月份 三组)+ 起止日期 + 应用"(`app.js:126-135`),而 Vue 工作台此前**只显示一个徽标文字** ✗。已按旧页逐项补齐:`WIN_PRESETS`(近30日/近90日/2026年/2026H1/2025H2/全程)与 `WIN_SLUG`(近30日→30d 等)**照抄**、月份组取 `d.all_months` 反转、自定义组按 `^\d{4}-\d{2}-\d{2}~\d{4}-\d{2}-\d{2}$` 判定;选择/应用后 emit `win` ⇒ App 的 `watch(win)` 触发重新取数(与旧页同一数据面);「重选」回到总览并重载。实测(jsdom 真跑 `/detail/v2`):`#win` 下拉存在 · **27 个选项 / 2 个分组** · 重选按钮 ✓ · 起止日期输入 ✓ · 应用按钮 ✓;**结构对拍仍 10/10**(控件在页头,不在 `#root` 比较域内)✓。② **门户装配慢** —— 原实现是"取壳 → **await 28 个内嵌件(19.3 MB)全到齐** → 才渲染" ✗ ⇒ 首屏要等全部下载完。改为**分阶段装配**:取壳后先用**空 `` 占位**立即渲染(首屏秒出),随后 6 路并发取回内嵌件、边到边把占位替换为真正的 ``(惰性元素,可后填),并在页面上显示进度 `内嵌件 n/28`;取件带 `cache: "force-cache"` ⇒ 二次访问走浏览器缓存。 | | `v2.78.4` | 2026-10-04 | 小 | 修 `/detail/v2` 空白:vite base 由相对 `./` 改为绝对 `/web/` | 用户反馈 `/detail/v2` 页面**空白**。**真因**:构建产物的资源引用是**相对路径**(`./assets/index-*.js`,来自 vite `base: "./"`),而该路由的页面地址是 `/detail/v2` ⇒ 浏览器把相对路径解析成 `/detail/assets/index-*.js` ⇒ **404** ⇒ 没有 JS/CSS ⇒ 整页空白。修正:`vite.config.ts` 的 `base` 改为 `"/web/"` ⇒ 产物统一引用 `/web/assets/…`(绝对),于是 `/`、`/web/index.html`、`/detail/v2` 三个入口都能正确加载。验证(远端逐项取回):产物资源引用变为 `/web/assets/index-7L39KHl9.js` 与 `/web/assets/index-BrpeqDO1.css`;三个入口各自引用的资源**均 200**:`/detail/v2` → js 200·246,564 B · css 200·57,425 B;`/` 与 `/web/index.html` 同 ✓。远端已部署 36 件。 | | `v2.78.3` | 2026-10-04 | 小 | 修「点登录不进工作台」:iframe 内捕获期接管 4 个入口 + 外层 hashchange | 用户反馈点右上「登录」仍不进工作台。**真因**:门户自己的脚本给导航项挂了点击处理并 `preventDefault()` 拦截默认跳转 ⇒ 我此前改写的 `href="/detail/v2#workbench"` 被吃掉(点了等于没点)。修正(双保险):① `PortalView.vue` 在 iframe **load 后**、以**捕获期**(`addEventListener(…, true)`)给四个入口挂处理器,先于门户脚本执行并 `preventDefault + stopImmediatePropagation`,随后直接导航**顶层窗口**到工作台:选择器 —— `nav a[data-nav="cms"]` → `/detail/v2#tab=vibration`、`nav a[data-nav="documents"]` → `#tab=documents`、`nav a[data-nav="recalc"]` → `#tab=recalc`;「登录」= `nav a:not([data-nav])` → `/detail/v2#workbench`。(已核实门户导航锚点:cms/documents/recalc 均带 data-nav,「登录」是导航里唯一没有 data-nav 的锚 ⇒ 选择器全部命中。)② `App.vue` 增加 `hashchange` 监听:运行期把 hash 变成 `#workbench` / `#tab=…` 也会切到工作台(修掉"外层「工作台」按钮改了 hash 但不切模式"的问题)。远端已部署 36 件并探活 `/` 200 · `/detail/v2` 200 ✓。 | | `v2.78.2` | 2026-10-04 | 小 | 修「登录后进不了工作台」:补 /detail/v2 路径判定 + 修 TDZ;门户三入口改 target=_top | 用户反馈「登陆后没有进入工作台」。**两个真因**:① `App.vue` 只按 hash 判模式,**没有 `/detail/v2` 路径判定** ⇒ 门户里的「登录」(指向 `/detail/v2`)打开后仍是**门户模式** ⇒ 看起来"没进工作台"(且会回到门户,形成循环)。补 `const _isDetail = /\/detail\/v2\/?$/.test(location.pathname)` 并纳入模式判定。② 补判定时又踩到 JS **暂时性死区(TDZ)**:`if (_tabInHash) tab.value = _tabInHash` 被我写在 `const tab = ref(...)` **之前** ⇒ 抛错导致**整页空白**(`#tab=…` 场景全白)。已把赋值移到声明之后。③ 门户里的入口改写:门户跑在 iframe 内,链接必须 `target="_top"` 才能打到顶层窗口(此前改成 `#workbench` ✗,外层 Vue 收不到 ⇒ "迁移看起来没生效")。现改为:振动·CMS → `/detail/v2#tab=vibration`、交付文档 → `/detail/v2#tab=documents`、数据重算 → `/detail/v2#tab=recalc`、登录 → `/detail/v2#workbench`(均 `target="_top"`)。**行为实测(jsdom 真跑、用远端真实 fleet 214 KB 作夹具)**:`/detail/v2` ⇒ `wrap=true tabs=14 active=总览`(进工作台 ✓);`/detail/v2#tab=vibration` ⇒ `wrap=true tabs=14 active=振动融合分析`,子选项卡 `["融合矩阵","端到端闭环","逐台情况","报警工单","振动分析"]` ✓ —— 即用户要求的三项迁移(振动 5 子视图随窗 · 交付文档 · 数据重算 与系统维护并列)在 `/detail/v2` 下均已可用。远端已部署(36 件)。 | | `v2.78.1` | 2026-10-04 | 小 | 修门户正文出现原始标记文字:装配口径照 portal_build.py(模板包进 ) | 用户反馈根路径页面出现 `