观澜 v2 源代码快照(旁证实验)

zhouyang.xie 51cad23885 2.41.0 rpt_export 端到端一致(docx 36873B/xlsx 4792B, PK) + 裁判加二进制比对(解包 XML 剔除时间戳) => 16/17, Java 范围无未实现端点, 仅余 POST /api/ask 1 тиждень тому
app_ETL 899d17147f 2.14.0 分别打包: pack_dist --module(四模块各自成包, 真实依赖闭包=全模块) + MODULE_PACKAGE.json 标记 + 模块 install/run/uninstall 双模 + app_common bootstrap.py(独立装/检/跑/卸) + --verify --module; 根 VERSION 镜像纳入版本门; 文档与版本表同步 1 тиждень тому
app_algorithmModel 0edf335a78 2.40.1 rpt_export 组装侧就绪: report_views.py + /api/rpt_export_raw(字节) + 补搬 _jclean/_redact 与别名导入; 自检导出 36873B docx 成功; 修 app.py 缩进与命名冲突; HTTP/Java/裁判二进制比对待下轮 1 тиждень тому
app_backEnd 51cad23885 2.41.0 rpt_export 端到端一致(docx 36873B/xlsx 4792B, PK) + 裁判加二进制比对(解包 XML 剔除时间戳) => 16/17, Java 范围无未实现端点, 仅余 POST /api/ask 1 тиждень тому
app_common 51cad23885 2.41.0 rpt_export 端到端一致(docx 36873B/xlsx 4792B, PK) + 裁判加二进制比对(解包 XML 剔除时间戳) => 16/17, Java 范围无未实现端点, 仅余 POST /api/ask 1 тиждень тому
app_frontEnd af78b0bf82 2.28.1 灰度第一步: Vue 产物经网关可作并列入口 + 新增产物级冒烟门(scripts/spa_smoke.py, 10 页签标签取自语言包); 路线: 并列入口->Java 42 端点迁移->最后一次性删 Python 源码 1 тиждень тому
app_ontology 899d17147f 2.14.0 分别打包: pack_dist --module(四模块各自成包, 真实依赖闭包=全模块) + MODULE_PACKAGE.json 标记 + 模块 install/run/uninstall 双模 + app_common bootstrap.py(独立装/检/跑/卸) + --verify --module; 根 VERSION 镜像纳入版本门; 文档与版本表同步 1 тиждень тому
app_qualityGate 506648803c 2.18.0 后端 Java 化(P12 起步): app_backEnd/backend-java (Spring Boot 2.7.18 + springfox Swagger + RestTemplate 调算法 FastAPI) 离线可编可跑; /java/healthz(algorithm_ok=true) + /java/algorithm/* + Swagger UI + /v3/api-docs 实测 200; build_offline.py(环境变量优先) + settings-offline.xml 可移植; target/ 不进包; 设计说明 §3.7; 文档/版本表同步 1 тиждень тому
configs d35bd1acd6 2.29.0 Java 后端迁移开工: 逐条比对裁判 scripts/java_contract_parity.py + 同源灰度路由 /java->28120 + FactsController(/api/facts 已一致, 计分板 1/42) + run_java.py 启动器 1 тиждень тому
data 54f7e34e1a A2: 数据层四项数据源目录改为 data/raw/<场站名称>/{scada_10min,故障报警,风机故障记录,油样报告} 1 місяць тому
docs 51cad23885 2.41.0 rpt_export 端到端一致(docx 36873B/xlsx 4792B, PK) + 裁判加二进制比对(解包 XML 剔除时间戳) => 16/17, Java 范围无未实现端点, 仅余 POST /api/ask 1 тиждень тому
reference 31129f2f84 oem_frequency_scan 行骨架 + 分母列 2,420/2,420 逐值复现; 只差 ratio 三对列的分子 3 тижнів тому
release e1f67f5a42 2.28.0 report 页签迁移完成 => 10/10 页签全部通过严格整页签对拍(Vue 前端迁完); 修 report 模型默认值同 decision; 如实记录: 对拍为首屏呈现口径 + 3 条后端数据来源差异例外 1 тиждень тому
resources 26f1eca47f 2.13.0 P9 源码目录结构变更: 实现包上提模块根(app_X/app_X_guanlan)+旧前缀别名(同名同体)+每模块 common/configs/data/README.MD/install-run-uninstall 包装+配置双根(app_ETL/app_frontEnd configs 下放, 取用口多根+单源+owner); 修文档构建器死循环(落单反引号)并支持代码栅栏 1 тиждень тому
scripts 51cad23885 2.41.0 rpt_export 端到端一致(docx 36873B/xlsx 4792B, PK) + 裁判加二进制比对(解包 XML 剔除时间戳) => 16/17, Java 范围无未实现端点, 仅余 POST /api/ask 1 тиждень тому
src 26f1eca47f 2.13.0 P9 源码目录结构变更: 实现包上提模块根(app_X/app_X_guanlan)+旧前缀别名(同名同体)+每模块 common/configs/data/README.MD/install-run-uninstall 包装+配置双根(app_ETL/app_frontEnd configs 下放, 取用口多根+单源+owner); 修文档构建器死循环(落单反引号)并支持代码栅栏 1 тиждень тому
vendor 1a3867e369 2.15.0 P10 算法服务化: FastAPI 服务(app_algorithmModel/service: app/registry/jsonable/deps) 11 个只读端点 + /docs + /api/{名}/raw 对拍; 端口 18050 登记 serve.json; FastAPI 栈离线随包 vendor/pyfastapi(15.9MB)+deps 兜底; 逐值对拍 11 端点+3 带参全一致; 设计说明 §3.5; 文档/版本表同步 1 тиждень тому
.gitattributes 42f6613290 备份(用户令): 把含产物的旧交付包 guanlan-rudong-v2_0.2.0_test_win64.zip 纳入 git 管理 —— 它是'包内无生成端'那 567 件产物的唯一来源(交付包默认不含产物 + 清除产物不留备份 ⇒ 清了就没来源); 附 旧包_补救源_说明.md (用途/补齐命令/代价/与当前产物差异); .gitignore 只放行这一个 zip, .gitattributes 标 binary 3 тижнів тому
.gitignore 4b641e021f 仓库卫生: target/ 与 *.log 加入 .gitignore 并停止跟踪 Java 构建输出 1 тиждень тому
README_先读我.MD 48703cb080 输入数据自动扫描识别 (用户令 2026-09-19): 发现新增 → 纳入重算 3 тижнів тому
VERSION 51cad23885 2.41.0 rpt_export 端到端一致(docx 36873B/xlsx 4792B, PK) + 裁判加二进制比对(解包 XML 剔除时间戳) => 16/17, Java 范围无未实现端点, 仅余 POST /api/ask 1 тиждень тому
check.bat 4866f71f27 按用户令去掉 VBScript: 无窗口启动改为 pythonw.exe + Python 启动器 + 安装时建快捷方式; 并修两处入口脚本编码事故 (install.ps1 掉 BOM / install.sh 是 CRLF), 编码守则 + .gitattributes 机器强制 (只钉 .bat/.ps1/.sh, 不制造 EOL 全仓改动) 3 тижнів тому
guanlan.py 26f1eca47f 2.13.0 P9 源码目录结构变更: 实现包上提模块根(app_X/app_X_guanlan)+旧前缀别名(同名同体)+每模块 common/configs/data/README.MD/install-run-uninstall 包装+配置双根(app_ETL/app_frontEnd configs 下放, 取用口多根+单源+owner); 修文档构建器死循环(落单反引号)并支持代码栅栏 1 тиждень тому
install.bat 4866f71f27 按用户令去掉 VBScript: 无窗口启动改为 pythonw.exe + Python 启动器 + 安装时建快捷方式; 并修两处入口脚本编码事故 (install.ps1 掉 BOM / install.sh 是 CRLF), 编码守则 + .gitattributes 机器强制 (只钉 .bat/.ps1/.sh, 不制造 EOL 全仓改动) 3 тижнів тому
install.ps1 26f1eca47f 2.13.0 P9 源码目录结构变更: 实现包上提模块根(app_X/app_X_guanlan)+旧前缀别名(同名同体)+每模块 common/configs/data/README.MD/install-run-uninstall 包装+配置双根(app_ETL/app_frontEnd configs 下放, 取用口多根+单源+owner); 修文档构建器死循环(落单反引号)并支持代码栅栏 1 тиждень тому
install.sh 26f1eca47f 2.13.0 P9 源码目录结构变更: 实现包上提模块根(app_X/app_X_guanlan)+旧前缀别名(同名同体)+每模块 common/configs/data/README.MD/install-run-uninstall 包装+配置双根(app_ETL/app_frontEnd configs 下放, 取用口多根+单源+owner); 修文档构建器死循环(落单反引号)并支持代码栅栏 1 тиждень тому
pack.bat b82640cb38 pack.bat 文案对齐版本规则: 包名 app_guanlang_v<版本号>.zip(src/version.py 单一真源) 3 тижнів тому
pack.sh 0c468367ff 用户令: 实现打包功能(默认不含 输入数据/产物/运行日志/临时文件; 零开关一条命令) + 打包入口 pack.bat/pack.sh/pack_verify_entry.py + README_先读我.txt 改名 .MD 并新增「打包」一节; 打包器新增 logs/临时文件兜底排除与 no_temp 清单, pack 入口纳入引用闭合检查 3 тижнів тому
requirements.txt 01ddb723e1 数据链补齐: 从 data/raw 重算/更新产物 (报警/工单/油样) + 等价验收 1 місяць тому
start.bat 6fb9dcc88d 现场事故修复: start.bat 注释里的中文被 cmd 当命令执行 + echo 里写 <<shortcut>> 触发重定向错 —— 包里 .bat 一律纯 ASCII(英文), 中文说明移入 README/docs; install.ps1 增设 ASCII 名快捷方式 start_guanlan.lnk; 编码守则新增 .bat 纯 ASCII/无 << / 重定向符三条(变异测试两类可拦); 顺带把 portability 门禁的 3 处绝对路径清零 3 тижнів тому
stop.bat 4866f71f27 按用户令去掉 VBScript: 无窗口启动改为 pythonw.exe + Python 启动器 + 安装时建快捷方式; 并修两处入口脚本编码事故 (install.ps1 掉 BOM / install.sh 是 CRLF), 编码守则 + .gitattributes 机器强制 (只钉 .bat/.ps1/.sh, 不制造 EOL 全仓改动) 3 тижнів тому
uninstall.bat b91d7f7890 用户令: ① 增加卸载脚本 uninstall.bat/uninstall.sh; ② 版本号规则与打包版本管理 (本次打包 v2.5.0) 3 тижнів тому
uninstall.sh b91d7f7890 用户令: ① 增加卸载脚本 uninstall.bat/uninstall.sh; ② 版本号规则与打包版本管理 (本次打包 v2.5.0) 3 тижнів тому
旧包_补救源_说明.md 42f6613290 备份(用户令): 把含产物的旧交付包 guanlan-rudong-v2_0.2.0_test_win64.zip 纳入 git 管理 —— 它是'包内无生成端'那 567 件产物的唯一来源(交付包默认不含产物 + 清除产物不留备份 ⇒ 清了就没来源); 附 旧包_补救源_说明.md (用途/补齐命令/代价/与当前产物差异); .gitignore 只放行这一个 zip, .gitattributes 标 binary 3 тижнів тому
测试须知.txt c5cb06a962 观澜·如东样板 v2 v0.2.0 基线入库 (含 2026-09-11 现场修复) 1 місяць тому

README_先读我.MD

观澜·如东样板 v2 0.4.0 — 单包全量离线应用 (Windows / Linux / macOS)

= Windows 的 .venv\Scripts\python.exe, 或 Linux·macOS 的 .venv/bin/python;

   命令里路径写 / 即可两平台通用; Windows 也可以只双击 .bat, 不必敲命令。

★ 本包不含 输入数据(data/) · 产物/输出数据(outputs/) · 运行日志(logs/、run/、任何 .log/.jsonl) · 临时文件(缓存/备份/系统索引)(用户令 2026-09-17; 打包方法与逐条理由见第五节): 解压安装后页面会显示"无产物"; 把现场数据包放好后跑一次重算(第四节), 页面立刻有数。 随包内容 = 程序/配置/门户与三维资产/交付文档/离线依赖轮子/便携运行时 (没有数据、产物、日志)。

一、安装 (约 10 分钟; 安装目录不要有空格和中文) Windows : 解压到 D:\guanlan\app → 双击 install.bat (自动选 Python → 建 .venv → 包内轮子离线装依赖) Linux : 解压到 /opt/guanlan → sh install.sh (麒麟 V10 / 统信 UOS 20 / Ubuntu / CentOS / macOS;

                                                        多版本机器: GUANLAN_PY=/usr/bin/python3.11 sh install.sh)

没装 Python 的机器也能装: 包内有便携运行时(Windows / Linux x86_64 / Linux aarch64), 安装脚本自动用。 离线边界: Windows 侧包内带全部轮子, 完全离线可装; Linux·macOS 侧包内没带轮子, install.sh 会自动 改为联网安装 —— 要离线装就把对应平台轮子放进 wheels/linux_x86_64 或 wheels/macos_arm64 再装。 模型(可选, 只影响问答与本地审核页): ollama pull qwen3:8b / deepseek-r1:14b / bge-m3

二、启动 / 停止 Windows : 双击 check.bat 全绿 → 双击「启动观澜」快捷方式(安装时自动建: 根目录 + 桌面各一份;

        同一目标还有一份 ASCII 名的 start_guanlan.lnk 供控制台/脚本引用;
        目标 = .venv\Scripts\pythonw.exe, **完全不出现命令窗口**) 或双击 start.bat
        (会闪一下窗口 —— .bat 是控制台程序, 想完全无窗就用上面那个快捷方式)   停止: 双击 stop.bat

Linux : guanlan.py check → guanlan.py serve 停止: guanlan.py stop 三个入口: 门户 http://127.0.0.1:28084/ · 工作台 /detail/ · 运维控制台 /ops ★ 别的机器怎么打开 (用户令 2026-09-19「观澜改为监听所有 IP」): 出厂已是 this 口径 ——

configs/serve.json 的 "public_host": "0.0.0.0" ⇒ 门户网关绑所有网卡, 别的机器开
http://<本机IP>:28084/ 。**只有门户网关**对外, 组件(detail/cms/viewer/sim)仍绑 127.0.0.1。
Windows 还要放行入站端口: netsh advfirewall firewall add rule name=guanlan28084 dir=in action=allow protocol=TCP localport=28084
只给本机用就把它改回 ""(跟 host) 或 "127.0.0.1"; 也可以填某个内网 IP 只放那一个地址。改完重启服务。
★★ 页面**没有鉴权** ⇒ 对外监听等于把全场运行数据摊开。请同时限来源 (防火墙只放自己的 IP / 反代加认证),
   不要直接挂公网; 只给运维看时更稳的是 public_host 留空 + SSH 隧道
   (ssh -L 28084:127.0.0.1:28084 <user>@<服务器>) —— 启动日志里每次都会提醒这一条。

★ 无人值守/远程部署: 用 Windows 服务(开机自启 + 崩溃自动重启):

(管理员) <PY> scripts\service_ctl.py install        服务名 = guanlan (显示名「观澜·如东样板 v2 …」)
查状态: sc query guanlan   ·   Linux 对应 systemd 单元 guanlan.service
★ 反面教材(2026-09-19 实逮): 用 SSH 会话里跑 <PY> guanlan.py serve 起的服务, **会话断开就被一起收掉**
  (SSH 作业对象随会话结束终止子进程) ⇒ 远程部署一律用服务, 别用 SSH 前台起。

排障要看见实时日志: 双击 start.bat console (前台模式, 关窗即停服务); 本包不含 VBScript, 无窗口启动不依赖 Windows 脚本宿主(WSH 被策略禁用的服务器上同样可用)。 ★ .bat 一律纯 ASCII(英文): 中文写进批处理会随控制台代码页被曲解, 现场出现过"注释被当命令执行"。

中文说明请看本文件与 docs/; 机器守卫见 src/entry_refs.py(guanlan.py check 会报一行)。

三、重算与产物 (门户菜单「数据重算」, 或直接开 http://127.0.0.1:28084/ops) ★ 输入数据自动扫描识别 (用户令 2026-09-19): data/raw 下逐族指纹 (件数/体积/最新时间/清单摘要),

与上次快照比 —— 有新增/变化就报出来并列出"该跑哪几步":
  <PY> scripts/raw_scan.py                 # 看当前状态
  <PY> scripts/raw_scan.py --check         # 与快照比: rc=0 无变化 · rc=4 有新数据 · rc=5 还没基线
  <PY> scripts/raw_scan.py --write         # 记/更新基线 (重算链第 ①b 步每次都会顺手记)
→ 重算链里它就是 **①b 步**; 想让"新数据不被 --skip-* 漏掉", 用:
  <PY> scripts/rebuild_all.py --auto       # 先扫一遍: 新数据落在被跳过的族里就自动取消跳过
→ 服务侧看门狗 (默认关, 现场自己开): configs/serve.json 的 "raw_watch"
  {"enabled": true, "minutes": 30, "auto_rebuild": false}
  开了以后每 30 分钟扫一次, 有新数据就写 logs/service.log 并列出该跑的步; auto_rebuild=true 时
  顺手发起一次重算 (与运维控制台同一条路; 已在跑则不重复发起)。

一个按钮一件事: 停/启服务 · 执行重算 · 清除产物。按钮按真实状态启用(不能做的灰, 后端也拒绝, 直接打 API 返回 409); "启动服务"起来后自动打开门户; "停止组件服务"保留控制台本身; 同时刻只允许 一个动作, 页面上有进度/退出码/实时日志尾巴。重算进行中按钮按设计禁用 —— 那不是坏了。 ★ 清除产物 = 直接删除, 不留备份(用户令 2026-09-16; 旧的 --on 还原已移除), 不动 data/raw、release;

要补回"包内没有生成端"的随包件: **运行期不由交付包补齐**(用户令 2026-09-17) —— 放原始件后重跑重算, 或由研发补生成端(逐族可逆性见 docs §13.6); 仅离线人工补救时可用 <PY> scripts/products_restore_missing.py --stash <…>

★ 清完产物后页面会显示"无产物"(工作台左栏/CMS 页都会给出"缺哪件、怎么补"的说明, 不会崩) ——

跑一次第四节的重算即恢复; 若某页仍打不开, 先看 /healthz 与 logs/<组件>.log 尾部。

四、放数据后重算 (一条命令; 控制台点"执行重算"等价) scripts/raw_data_check.py --src <现场包目录> ★ 先体检: 结构/命名/增量(新增·跳过·冲突) + 放置指导 scripts/place_raw_data.py --src <现场包目录> --scope full 放数据(同尺寸自动跳过, 可反复跑;

   落位前自动跑体检, "同名不同大小"的冲突会拦下, 确要覆盖加 --force)

scripts/rebuild_all.py [--skip-scada] [--src <现场包目录>] 默认含 SCADA 侧约 15 分钟;

   只换台账类数据加 --skip-scada(约 2 分钟); --dry-run 只看计划; 完事自动重启组件服务。

放置规范与常见错误: docs/输入数据放置指导_v0.1.md (目录树/命名/增量语义/放完跑什么) 算成功判据: /detail/ 左栏「系统维护」两屏, 或 -m src.ontology.maintenance 重算后应达锚点: 报警 39211 · 工单 5876 · 油样 404 · temp_monthly 19494 · 本体 9702 对象(审计 0 问题)

五、打包 (做交付包; 用户令 2026-09-17) 一条命令就够(不需要任何开关); Windows 也可以直接双击 pack.bat:

Windows : 双击 pack.bat            或  <PY> scripts/pack_dist.py
Linux   : sh pack.sh               或  <PY> scripts/pack_dist.py
pack.bat dry      只预演: 报表里会打什么、多大, 以及逐条排除理由(不写文件)
pack.bat verify   对已打好的 zip 做开箱验证: 解压 → 离线安装 → 起服务核验页面 → 清理
<PY> scripts/pack_dist.py --out <目标.zip>     指定输出路径

输出: 默认写到安装目录的上一级, 文件名 app_guanlang_v<版本号>.zip

    (例: 装到 D:\guanlan\app 且本包版本 2.6.0, 则产物在 D:\guanlan\app_guanlang_v2.6.0.zip)

★ 版本号规则 (用户令 2026-09-17): 编号 v<大版本号>.<中版本号>.<小版本号>, 例 v2.5.0

  大版本号 —— 系统解决方案、架构或核心功能改变
  中版本号 —— 非核心功能新增、减少、修改
  小版本号 —— 消缺完善
版本号只写在 src/version.py 一行(VERSION), 打包器/安装脚本/安装记录/自检都读它;
改完跑 <PY> scripts/version_log.py --write 让 docs/版本记录.md 跟上(自检会校验两者一致);
看当前版本与规则: <PY> guanlan.py version

★ 包里不含这四类(默认口径; 每条理由都写进包内 dist-manifest.json):

① 输入数据     data/                    现场原始件; 例外要带用 --with-data (约 31 GB)
② 产物/输出数据 outputs/                 目标机放数据后 place_raw_data.py + rebuild_all.py 重算;
                                        无生成端的那批**运行期不从交付包补**(用户令 2026-09-17), 由研发补生成端(docs §13.6)
③ 运行日志     logs/ run/ 以及**任何位置**的 *.log、*.jsonl (含 logs/build、logs/legacy)
④ 临时文件     各种缓存(*_cache、__pycache__、.pytest_cache、.npm-cache、.qa-profile)、
               编辑器临时与备份(*.tmp *.bak* *.old *.orig *.rej *.swp *~ ~$*)、
               系统索引(.DS_Store、Thumbs.db、desktop.ini), 以及 .git/.venv/*.pyc/*.lnk/顶层 *.zip

包里有: src/ scripts/ guanlan.py · configs/ · release/(门户/仿真/三维/交付件) · resources/ · reference/ ·

         docs/ · README 与 测试须知 · wheels/ · vendor/ · install/check/start/stop/pack/uninstall 脚本 · requirements.txt

打完自查: 包内 dist-manifest.json 记着 version / no_data / no_products / no_logs / no_temp + 逐条排除理由;

        打包器自己还会核"入口脚本引用的文件都在包里"与"入口脚本编码守则", 不合格的包会被删掉并返回非 0。

要让页面开箱即有数(例外做法): scripts/pack_dist.py --with-products

六、必读 (如实) · 页面的数来自 outputs/<场站> 下的产物, 产物由 data/raw 下的原始件算出来(下一级目录名=场站名, 扫描辨识)。

本包两样都没带: 没有 data/raw 时重算会"没有源件可算", 没有 outputs/ 时页面显示"无产物"。

· 有一批产物没有生成端(pitch_daily、pc_monthly_bins、CMS/TCM 链等): 从交付包按需补齐

(**运行期不从交付包补**: 放原始件后重算; 缺生成端的族由研发补, 见 docs §13.6), 逐件来源见 outputs/<场站>/_provenance.json。

· 某页没数据: 先看控制台的退出码与 logs/, 再看 docs/重算缺口与补件清单_v0.1.md。

包内含: 程序与配置 / 门户与仿真 / 三维资产 release/viewer / 治理清单交付件 release/如东(客户交付物勿外传) /

    离线依赖轮子 wheels/ / 便携运行时 vendor/ / 交付文档 docs/ / 打包脚本 pack.bat · pack.sh /
    安装与卸载脚本 install.bat · install.sh · uninstall.bat · uninstall.sh

包内不含: data/(输入数据) · outputs/(产物) · logs/ run/(运行日志) · 临时文件与缓存 ·

      .venv(安装时重建) · .git(版本库)

七、服务化 (装成 Windows 服务 / systemd; 用户令 2026-09-17) Windows (管理员 PowerShell): scripts/service_ctl.py install 注册为 Windows 服务(开机自起)

                            <PY> scripts/service_ctl.py install --dry-run  先看它要做什么(免管理员)
                            不想提权: <PY> scripts/service_ctl.py install --user-login   登录后自启

Linux (root): sudo scripts/service_ctl.py install 写 guanlan.service + systemctl enable --now 起停状态: scripts/service_ctl.py status|start|stop|restart|uninstall 装了服务就不必再双击快捷方式; 手工启动(start.bat / guanlan.py serve)仍然可用, 两者互不冲突。 ★ 安装时会先检查是否已安装及版本: 读 <安装目录>/install-info.json 与本包版本比较,

同版本/升级/降级/老安装无版本记录 四类都会提示并询问是否重装;
跳过询问用 install.bat -Force (Linux: sh install.sh --force)。版本单一真源 = src/version.py。

八、卸载 (用户令 2026-09-17) Windows : 双击 uninstall.bat Linux / macOS : sh uninstall.sh 带开关的用法 (两种平台一样):

--dry-run      只打印"将要做什么", 一个字节都不动 (先看这个最稳妥)
--yes          不再询问, 直接执行 (脚本/无人值守用)
--purge        连 数据/产物/日志/虚拟环境 一起删 (会再问一次; 加 --keep-logs 保留日志)
--all          连程序本体一起删 (删不掉的逐条列出, 并给一条收尾命令)
--selftest     自检: 六个步骤齐全 + dry-run 无副作用

默认只拆"本程序装上去的东西", 顺序是:

① 停服务(服务化常驻体 + 手工启动的组件)  ② 注销服务(sc.exe delete / systemctl disable; 需管理员/root)
③ 撤开机自启(登录自启项)  ④ 删快捷方式(启动观澜.lnk / start_guanlan.lnk, 含桌面)
⑤ 清运行态(run/、*.pid)  ⑥ 删安装记录 install-info.json (删掉它 = 这台机器回到"没装过")

★ 默认保留: data/(输入数据) · outputs/(产物) · logs/ · .venv/ · 整棵程序目录。

卸载程序 ≠ 销毁数据; 要连数据一起清, 显式给 --purge。

★ 程序目录不自己删(Windows 上正在跑的 python.exe 就在 .venv 里, 删自己必然只删一半):

要清干净用 --all, 或卸载完直接删目录 `rmdir /s /q <安装目录>`。

免管理员也能卸: 服务注销那一步缺权限时照做其余步骤, 并打印你该手工执行的那两条命令。

详细说明: docs/系统设计说明.md(§9 交付包组成 · §11 配置与日志口径 · §14 服务化与卸载 · §15 版本管理与打包命名)

      docs/版本记录.md(版本号规则与版本表) · docs/重算操作手册_v0.1.md
      docs/数据目录结构与落位约定_v0.2.md · docs/重算缺口与补件清单_v0.1.md
      docs/输入数据放置指导_v0.1.md · docs/振动数据接入_v0.1.md · docs/说明书_观澜如东样板v2_v0.2.md