# -*- coding: utf-8 -*- """版本与安装信息的**唯一真源**(2026-09-17 用户令 1:安装时检查已装版本、提示差异、问是否重装)。 为什么单开一个模块:以前版本号散在三处(`scripts/pack_dist.py` 的 `VERSION`、README 抬头、说明书标题), 改一处忘一处就会出现"包说 0.4.0、安装记录说 0.2.0"这种对不上的事。现在: src/version.py ← 唯一真源(本文件) scripts/pack_dist.py ← 读它写进 dist-manifest.json 与默认包名 install.ps1 / install.sh ← 读它写进 <安装目录>/install-info.json,并与已装的比对 guanlan.py / 各文档 ← 读它(文档里的人工版本号以它为准) `install-info.json` 落在安装根本身(不在 run/ 里):它是**交付物级别的安装记录**, 卸载/重装/拷机都要跟着走,所以和 `configs/`、`dist-manifest.json` 同级。 """ from __future__ import annotations try: from ._root import install_root as _install_root except ImportError: # 直接当脚本跑(python <本文件>)时没有包上下文 from _root import install_root as _install_root import datetime as dt import json import pathlib NAME = '观澜·如东样板 v2' VERSION = '2.79.1' # ★ 版本只改这里 EDITION = 'offline-single-package' PACKAGE_STEM = 'app_guanlang' # 交付包文件名前缀(用户令 2026-09-17) INSTALL_INFO = 'install-info.json' # 相对安装根 SERVICE_NAME = 'guanlan' # Windows 服务名 / systemd 单元名(用户令 1) SERVICE_DISPLAY = '观澜·如东样板 v2 (Guanlan Wind Asset Intelligence)' # ── 版本号规则(用户令 2026-09-17)──────────────────────────────────────────────── # 编号: v<大版本号>.<中版本号>.<小版本号> 例: v2.5.0 # 定义: 大版本号 —— 系统解决方案、架构或核心功能改变 # 中版本号 —— 非核心功能新增、减少、修改 # 小版本号 —— 消缺完善 # 包名: 打包文件名 = app_guanlang_v<版本号>.zip 例: app_guanlang_v2.5.0.zip # 用法: 用户/发布者定"这次算哪一级"→ VERSION 改一行 → 打包器与安装脚本自动跟着变 # (级别判据见 BUMP_RULE;一次发布混了几类就取最高那一级) RULE = 'v<大版本号>.<中版本号>.<小版本号>' LEVEL_MEANING = { 'major': '大版本号 —— 系统解决方案、架构或核心功能改变', 'minor': '中版本号 —— 非核心功能新增、减少、修改', 'patch': '小版本号 —— 消缺完善', } BUMP_RULE = ('改动落在"解决方案/架构/核心功能" → 大 +1(中/小归 0);' '落在"非核心功能的新增/减少/修改" → 中 +1(小归 0);' '只是"消缺完善" → 小 +1;一次发布混了几类,取最高那一级') # 版本记录(人读的那份由 scripts/version_log.py 生成到 docs/版本记录.md;这里只有事实,不重复描述) # level: major/minor/patch 表示这一版**相对上一版**是哪一级变化;legacy 表示该版用的是 # 旧编号体系(0.x,未按本规则),仅作历史对账用。 HISTORY: tuple[dict, ...] = ( dict(version='2.79.1', date='2026-10-04', level='patch', title='入库「整页外壳对比」工具;回滚一次导致挂载失败的外壳对齐尝试', note='用户令:核对 `/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),必须**一步一验**,不能批量改。'), dict(version='2.79.0', date='2026-10-04', level='minor', title='工作台补全套时间窗控件(照 v2.9.2);门户装配改分阶段(壳先出、内嵌件流式注入)', note='用户两项:① **`/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)全到齐** → 才渲染" ✗ ⇒ 首屏要等全部下载完。改为**分阶段装配**:取壳后先用**空 `