# 欧霓博目录软件 —— 项目总览（继续开发前先读这个）

> 本文件是项目全貌的汇总。继续开发时，先让 AI 读本文件 + `README.md`（同目录）+ `文件夹说明.md` 即可接上上下文。
> 最后更新：2026-08-28（**NX 按需生成服务二期 A 版全链路打通**：批处理导出 0 solid 根因定位+独立翻译器正解+worker 改造+nxBin 配置化+后台 /admin 密码登录三 tab+一键启动+网页状态圆球+生成后 3D 预览选格式下载+模型管理定时/手动清理；详见 `docs\工作交接.md` + `开发记录-NX2506批处理攻坚.md` §4.6）

## 1. 项目背景

- 公司：**欧霓博**（气动元件/气缸制造商）
- 目标：**自研**气动元件电子目录软件，对标 Airtac 的 CADENAS PARTdataManager 目录光盘（工作目录里的 Airtac 包即对标物），**不使用任何 CADENAS 组件**
- 核心目标一句话：**普通客户通过软件选型并下载 STEP 文件**，导入自己的 CAD 使用

## 2. 需求定稿（多次收敛后的最终范围）

| 项 | 结论 |
|---|---|
| 交付对象 | 普通客户（各类 CAD 用户），不限定 Teamcenter/NX/SolidWorks |
| 核心功能 | 浏览目录 → 参数选型（规则过滤）→ 3D 预览 → **下载 STEP** |
| 增强功能 | 搜索（型号/中文/英文/拼音）、参数范围筛选、批量下载 zip+BOM |
| 维护端 | 维护入口内置在同一个软件里（密码保护，客户不可见）；内含 Builder 制作器 |
| 发布 | 维护入口/命令行一键编译发布 → **客户版单文件 exe**（数据内置、无维护入口）+ 光盘目录 + 增量更新包 |
| 平台 | Windows 10/11，完全离线单机，中英双语 |
| 一致性（2026-08-24 定） | **桌面版功能与页面排版始终与在线版保持一致**——任何界面/功能改动两端同步做 |
| Teamcenter 集成 | 默认不做，仅当客户明确需要时作为可选扩展（M4） |

## 3. 里程碑状态：M1/M2/M3 全部完成 ✅

- **M1 核心闭环**：目录树、参数化选型（规则 R1~R3 实时过滤）、3D 预览（拖拽旋转/滚轮缩放）、尺寸图/参数表/数据表 PDF、STEP 下载、维护入口（`--admin`）、中英切换
- **M2 制作与检索**：维护入口内 Builder 5 步向导（含保存/加载配置）、全文搜索+拼音关键词、参数范围筛选、批量下载、校验器（STEP 缺失/编码重复/规则冲突/附件缺失）、CLI 打包模式 `--build`
- **M3 一键发布**：`publish.ps1`（自测门禁 → 客户版 exe 数据内置+物理剔除维护入口 → 光盘目录+增量包）、数据包版本校验、用户/维护手册
- **自测全过**（`--selftest`，结果看 `sample/selftest.log`；样例包 40 项、ONEBOT 包 25 项，新增"手册页附件可读"与"真实 B-rep 兼容"检查）

## 4. 技术栈与关键决策（含与设计文档的偏差）

本机环境：**无 .NET SDK**，有 VS 2022 Build Tools（含 Roslyn csc.exe）+ Windows 自带 .NET Framework 4.8/WPF。

| 设计文档原案 | 实际实现 | 原因 |
|---|---|---|
| C# / .NET 8 (WPF+MVVM) | C# / net48 **代码式 WPF（无 XAML）**，csc 编译 | 零安装；net48 内置于 Win10/11，客户机免装运行时 |
| SQLite + FTS5 | **zip + catalog.json**，内存 LINQ 查询 | 避免外部依赖，10 万级变体足够 |
| Helix Toolkit | WPF 内置 **Viewport3D** | 零依赖 |
| 预生成预览网格 | 运行时直接解析**自有极简 STEP**（4 圆柱组合）→ 网格 | 自有格式简单；真实 CAD 通用 STEP 由 NX Journal 批量生成预生成变体 |
| — | 数据包 .opc = zip（catalog.json + step/ + docs/） | schema_version=1.0，向前兼容校验 |

**关键架构决策**（详见 `欧霓博_目录软件_M1设计文档.md` 决策 2）：
- **预生成变体策略**：一个型号组合一个 STEP 文件，选型=命中文件。**离散档位行程够用**；若行程连续（任意值）需"参数化二期"（运行时建模，最难部分，已预留 `geometry_source` 扩展点）

## 5. 目录结构地图（工作目录根 = Airtac 包目录）

```
airtac_0602_2026_v11sp5_world_version/     ← 工作目录根 (Airtac 原始 CD 内容: data/ + cip/ + software/)
├── OnebotCatalog_2026.08_客户版.zip   ← 客户交付包示例
├── ONEBOT目录-维护版.lnk / ONEBOT目录-客户版.lnk   ← 快捷方式
└── OnebotCatalog/                 ← ★项目主目录 (自包含: 文档+软件+数据+工具)
│   ├── 项目总览.md                ← 本文件 (继续开发的入口)
│   ├── 文件夹说明.md / README.md  ← 目录用途 / 开发说明
│   ├── 欧霓博_电子目录系统_开发提示词.md + M1/M2/M3设计文档.md  ← 历史文档
│   ├── src/  (App + CatalogCore + Viewer3D, 10+ 个 .cs)
│   ├── web/  (在线站前端: index.html/app.js/style.css + OneBot-logo.png)
│   ├── viewer/STEPViewer/         ← 新迪 3D 查看器【本地副本】(原项目 Z:\...\上海新迪3D\dev 只读不改;
│   │                                menu=min 精简菜单/无模型树已改; 菜单精简-生产部署补丁.txt = 部署补丁)
│   ├── assets/ (OneBot-logo.png 嵌入资源 + OneBot-logo.ico exe 图标)
│   ├── tools/ (build.ps1, publish.ps1, serve-web.ps1, fix-bom.ps1, make-icon.ps1,
│   │          make-opc.ps1, extract-pdf.py, ui-diagnose.ps1, ui-diagnose2.ps1)
│   ├── bin/   (OnebotCatalog.exe 开发版, OnebotCatalog-Customer.exe 客户版, 维护入口.bat)
│   ├── sample/ (OnebotCatalog_2026.08.opc 真实目录; 2026.06 旧版已删, SC-meta.json)
│   ├── release/ (2026.08 真实三份产物: 离线包+增量包+在线站)
│   ├── docs/ (用户手册.md, 维护手册.md)
│   ├── README.md (开发说明, 必读)
│   ├── onebot-data/               ← ONEBOT 数据管线 (统一路线, 2026-08-22 并入自包含布局)
│   │   ├── catalog/               ← ★唯一数据源★ (catalog.json + series\*.meta.json + csv\ + step\ + manual\)
│   │   ├── tools/ (gen-onebot-source.ps1 源生成器, render-manual-pages.py 手册拆页, scan-manual-pages.py)
│   │   ├── 数据维护说明书.md        ← 团队操作指南 (数模替换/新增系列/打包/排查)
│   │   └── (旧 build-onebot-catalog.ps1 与 out\ 旧布局残留已于 2026-08-23 删除, 防止误用)
│   └── sample-data/               ← 样例数据 + NX 工具 (2026-08-22 并入)
│       ├── onb-sc/ (SC 标准气缸 72 变体 + MAQ 迷你气缸 36 变体, step/ 108 个 STEP, params.csv)
│       └── tools/ (gen-step/gen-images/gen-pdf/gen-xlsx/verify-step/fix-bom,
│                  nx-batch-export.vb NX 批量导出模板, nx-batch-export-glb.vb,
│                  NX母模建模操作说明书.md)
│
├── airtac-benchmark/              ← 亚德客目录对标分析 (2026-08-22, 仅结构/格式, 不含对方几何)
│   ├── 亚德客目录对标分析.md      ← 主报告 (.cip 容器格式/目录组织/参数格式/架构对照/可借鉴点)
│   ├── cip-tool.py (解析器) + series-tree.txt (系列树) + *-listing.txt (两容器条目清单)
│   └── out\ (解出的文本配置: dir.prj/categories.prj/系列.tab 等, 仅明文, 无几何)
```

### 真实数据 (ONEBOT, 2026-08-22 入库)

- 来源：《ONEBOT - 直线气缸 - 中文.pdf》(152 页, 71MB)。提取方式：`OnebotCatalog/tools/extract-pdf.py` (PyMuPDF) + 私有区数字解码（0xF6B1~0xF6BA = 0~9）。
- 产物：`OnebotCatalog\onebot-data\catalog\`（★唯一数据源★：catalog.json + series\*.meta.json + csv\ + step\ 1,309 个占位几何 STEP + manual\ 38 页）→ C# FullCatalogBuilder → `OnebotCatalog/sample/OnebotCatalog_2026.08.opc`（11 系列 52,154 变体, 5.5MB）。
- 系列：KC(32-320)/KCB/KSB/KCS/KS/KSU/M/MS/MSC/MAL/MALC；规则按手册提取（YB→缸径≤125；KS/KSU 双轴型固定形式受限）。
- **2026-08-23 新增 6 个 UNIVER 系样板系列**（参照官网 universal-onebot.com 产品数据）：UCBM 气动夹紧缸(6 型号)/ULP 可伸缩定位销(3)/USP 勾销缸(3)/UGP 夹爪缸(2, 含规则)/UAGP 翻转缸(22)/LAE 电动气缸(3)——共 39 型号，几何为占位，参数仅"规格(±型式)"两列，**作为各分类的填数模板**（现 17 系列 52,193 变体）。
- **几何为占位**：NX 母模批量导出真实 STEP 后，按相同文件名（`系列-型号缸径x行程.step`）替换 `catalog\step\` 并【重建全量目录】即可（KC-00-32x10 已试点）。

## 6. 日常操作手册（浓缩）

```powershell
# 编译开发版 / 客户版
powershell -NoProfile -ExecutionPolicy Bypass -File OnebotCatalog\tools\build.ps1
powershell -NoProfile -ExecutionPolicy Bypass -File OnebotCatalog\tools\build.ps1 -Customer -Opc sample\xxx.opc

# 自测 (结果看 OnebotCatalog\sample\selftest.log)
OnebotCatalog\bin\OnebotCatalog.exe --selftest OnebotCatalog\sample\OnebotCatalog_2026.08.opc

# CLI 打包 (与向导同一 Builder 内核; --meta 元数据模板见 sample\SC-meta.json)
OnebotCatalog\bin\OnebotCatalog.exe --build params.csv step目录 输出.opc --series SC --meta 配置.json

# CLI 全量打包 (统一路线: 源目录 → .opc; 结果看 <out 同目录>\build.log)
OnebotCatalog\bin\OnebotCatalog.exe --buildfull OnebotCatalog\onebot-data\catalog OnebotCatalog\sample\OnebotCatalog_2026.08.opc

# 刷新源数据 (占位几何+CSV+meta 重生成; NX 真实 STEP 直接替换 catalog\step\ 同名文件即可, 无需跑这个)
powershell -NoProfile -ExecutionPolicy Bypass -File OnebotCatalog\onebot-data\tools\gen-onebot-source.ps1

# 一键发布 (自测不过不允许发布; ★发布前必须先停 serve-web 和客户版 exe★)
powershell -NoProfile -ExecutionPolicy Bypass -File OnebotCatalog\tools\publish.ps1 -Opc sample\xxx.opc -Version 2026.08

# 本地网页预览 (并发服务器, 默认站点 release\web_2026.08; 关掉即停)
powershell -NoProfile -ExecutionPolicy Bypass -File OnebotCatalog\tools\serve-web.ps1

# 运行
OnebotCatalog\bin\OnebotCatalog.exe sample\xxx.opc            # 客户模式
OnebotCatalog\bin\OnebotCatalog.exe sample\xxx.opc --admin    # 维护入口 (密码: onebot888)
```

**维护入口在哪里（用户常问）**：
- 双击 `OnebotCatalog\bin\维护入口.bat` = 开发版 + --admin + 密码框（密码 onebot888）→ 顶栏出现【维护入口】按钮
- **客户版 exe（release\ 里那个）编译时已彻底移除维护入口**——这是设计需求，不是 bug；客户永远看不到编辑功能
- 若需在客户版也留隐藏入口（如 Ctrl+Shift+A 弹密码框），改 MainWindow.cs 一处即可（未做）

**放数据/编辑数据流程**（核心概念：.opc 是编译产物，不可直接改；编辑 = 改源头 CSV/STEP → 重新生成）：
1. 准备：参数表 CSV（首列=型号编码 + 参数列 + 必须的 step_file 列）+ STEP 目录 + 可选附件
2. 首次：维护入口 → 目录制作器 → 5 步向导（导入→参数→编码→规则→附件生成）→ 【保存配置】
3. 编辑：改 CSV/STEP → 向导【加载配置】→ 重新导入 → 生成 → 校验 → publish 或替换客户 catalog.opc
4. **编辑当前数据（2026-08-22 统一路线）**：唯一数据源 = `OnebotCatalog\onebot-data\catalog\`（catalog.json + series\<代码>.meta.json + csv\ + step\ + manual\）。维护窗口显示当前包系列清单；目录制作器 Step1 顶部选【数据源目录】(默认已填) → 下拉选系列 → 编辑参数/规则/显示名/附件 →【保存配置】(直接写回 series\*.meta.json) → 点【重建全量目录】→ 全量 .opc 生成并可加载到主窗口。同一内核另有 CLI：`--buildfull <源目录> <输出.opc>`。旧 build-onebot-catalog.ps1 已废弃（存档）；源数据刷新用 `OnebotCatalog\onebot-data\tools\gen-onebot-source.ps1`（几何+CSV+meta 生成，NX 真实 STEP 直接替换 catalog\step\ 同名文件）
5. **团队完整操作指南**：`OnebotCatalog\onebot-data\数据维护说明书.md` —— 数模替换 / 新增产品系列（CSV+meta+挂分类+STEP 全流程）/ 只改参数规则 / 常见问题排查表（含"桌面 3D 对真实 B-rep 空白"等已知边界），可直接转给维护同事

**环境陷阱（重要！）**：
- PowerShell 5.1 与 csc 对**无 BOM 文件按 GBK 读取** → 编辑任何含中文的 .ps1/.cs/.vb 后必须先运行 `fix-bom.ps1`（幂等，可重复跑）再编译/运行
- winexe（GUI 程序）退出码不可靠 → 自测结果以 selftest.log 文本为准（"结果: X 通过, Y 失败"）
- 外层 PowerShell 调用里不要用双引号包裹含 `$` 的命令（外层会先插值吞掉变量）
- **发布前必须先停 serve-web 与客户版 exe**（站点目录/编译产物被占用会失败；publish 已带删除重试，但 exe 锁仍会卡编译）
- 嵌套 powershell 传数组参数会被揉成单串 → fix-bom 等带 -Files 数组的脚本用当前会话 `& (Resolve-Path ...).Path -Files @(...)` 调用；`&` 相对路径偶发"模块加载"报错，一律先 Resolve-Path 取绝对路径

## 7. NX 数据准备（母模参数化 + Journal 批量导出）

用户使用 **NX 2506**。流程（★完整操作说明书：`OnebotCatalog\sample-data\tools\NX母模建模操作说明书.md`——表达式规划/建模五步/验收表/journal CONFIG/常见问题）：
1. **建参数化母模**：所有会变尺寸用表达式（`bore`/`stroke`/`rodLen=stroke+40` 公式联动），表达式名与 CSV 列名一字不差；磁石槽等"有无"特征用【按表达式抑制】（magOn=0/1）；**固定形式/磁石/双轴都改变外形 → 母模内做特征组+按表达式抑制切换**（mountIdx 0~6、twinOn 0/1）；草图必须全约束
2. **安装方式建议做法②**：母模只建气缸本体，安装件（法兰/脚座/中摆）独立 STEP 当选配件发；参数表 mount 列照写，多型号可共用同一 step_file（Builder 支持）
3. **批量导出**：NX 里 工具→日记→播放（**不是 Ctrl+U**，Ctrl+U 只认 .dll），选 `OnebotCatalog\sample-data\tools\nx-batch-export.vb`（已适配 NX 10~2506 的 DexBuilder API；改 CONFIG 区三个路径即可）
4. 验收：母模手动改 stroke/magOn/bore 验证联动，再 2~3 档小批量试跑，最后全量
5. **GLB 轻量化批量导出（待办 9）**：`nx-batch-export-glb.vb` 同款骨架；NX 2506 原生支持（文件→导出→Extended Reality→GLB，NX 2206 起有此功能）；导出 API 需用【工具→日记→录制】录一次真实调用再填入 ExportGlb 函数体（模板已留接缝）

## 8. 双发布管线（离线 + 在线，一次编辑两处发布）

目标：**同一份数据，一次编辑，离线/在线同步发布，零二次编辑**。

```
        CSV + STEP + 配置 meta（唯一数据源）
                  ↓ Builder 打包
            .opc 数据包（唯一中间产物）
                  ↓ publish 流水线（扩展现有 publish.ps1）
      ┌───────────┴─────────────┐
  离线发布                       在线发布
  ├─ 客户版 exe（数据内置）        ├─ 解包 .opc 内容
  ├─ 发布 zip（官网下载）          │  (catalog.json + step/ + docs/)
  └─ 增量包 catalog.opc          └─ 上传 Web 服务器静态目录
                                      ↓
                                网页选型应用（读同一份 catalog.json）
```

**一致性三保障**：① 格式同源——网页消费的 catalog.json 与离线包内部完全同一份；② 校验同源——两端用同一 PackageValidator；③ 版本同源——catalogVersion 统一，在线即时更新，离线客户走增量包；后续给客户版 exe 加"检查更新"（启动时读服务器 version.json 对比版本号提示升级），离线客户永不落后。

**网页版技术要点**：纯静态托管（云服务器/OSS/CDN）即可；一期做目录树+参数选型+尺寸图+下载（无 3D）；二期 3D 预览需构建期把 STEP 预转 **glTF**（three.js 渲染）；附加价值：搜索引擎收录获客、下载/选型统计、SEO。

**在线 MVP 已实现（2026-08-22，持续增强）**：
- `OnebotCatalog/web/` — 前端三件套（index.html / app.js / style.css，零依赖纯静态）；规则引擎与离线版 C# 同语义；支持目录树/选型/尺寸图/参数表+范围筛选/搜索/双语/STEP 下载；URL 加 `?selftest=1` 页面底部显示断言结果
- **网页版增强（2026-08-22）**：目录树/参数面板**拖拽调宽**（split1/split2 分隔条）；STEP 下载**点击即时反馈 + 3 秒防连点**；尺寸图窗口显示**系列手册页**（kind=manual）；3D iframe 带 `&menu=min` 精简菜单；品牌 ONEBOT；app.js 版本号 `?v=4`
- publish.ps1 第 5 步：解包 .opc + 复制前端 → `release/web_<版本>/`，**整目录上传到网站根目录即上线**（站点目录删除带重试）
- `OnebotCatalog/tools/serve-web.ps1` — 零依赖本地预览服务器（localhost:8080，**Runspace 池 16 并发**，大文件不阻塞下载，含防目录穿越 + /viewer/ 双根目录）

## 9. 待办清单（按优先级，状态更新于 2026-08-22）

| # | 待办 | 状态 | 依赖 |
|---|---|---|---|
| 1 | **真实数据接入**：真实系列参数表 + NX 母模导出 STEP → 套用 Builder 流程 | 🔄 目录数据已入库；**KC-00-32x10 真实数模已试点接入**（网页渲染/下载验证通过），待批量导出其余 1,308 个 | 用户 NX 母模批量导出 |
| 2 | **离线交付完善**：代码签名证书 + 官网 zip 下载流程 | ⏳ 未开始 | 证书需用户购买 |
| 3 | **虚拟机验收**：纯净 Win10/11 断网跑客户版 + CAD 核对 STEP | ⏳ 未开始 | 可随时做 |
| 4 | **在线 MVP**：网页选型（目录树+参数+尺寸图+下载，无 3D）；publish.ps1 增加"解包上传"输出分支 | ✅ 完成（2026-08-22） | 待上传部署 |
| 5 | **检查更新**：客户版 exe 启动时读服务器 version.json 提示升级 | ⏳ 未开始 | 在线 MVP 之后 |
| 6 | **在线 3D 预览** | ✅ 完成 | 新迪 STEPViewer iframe 联动 + Canvas 回退 |
| 7 | **参数化**：**一期选型数据参数化**（2026-08-25 上线，进展 23）+ **二期 NX 按需生成服务**（服务器现算 STEP，CADENAS 模式；A 版：轻量自建队列 + run_journal 常驻 worker，单个+批量、输出留存不删、检索先行、多格式 STEP/Parasolid/IGES/STL） | ✅ 一期上线；**二期 A 版全链路打通（2026-08-28）**：批处理导出 0 solid 根因定位 + 独立翻译器正解 + worker 改造 + 后台 /admin 密码登录三 tab + 一键启动 + 网页状态圆球 + 生成后 3D 预览选格式下载 + 模型管理定时/手动清理；Parasolid/STL 已砍（只留 step/iges/prt）| **真母模**（建模工程师，唯一卡进度）+ NX 2512 实测 + 云部署 |
| 8 | **M4 可选扩展**：Teamcenter 集成 | ⏳ 未开始 | 仅客户明确需要 |
| 9 | **网页/桌面 3D 轻量化（预转换）**：NX 把 STEP 离线批量转轻量网格，预览读网格（快/稳），STEP 照旧下载 | ✅ **桌面窗口内部分完成（2026-08-23）**：开源 Helix Toolkit (MIT) 直渲 STL 网格，NX journal 同步导出 STL（进展 17）；网页端轻量化（glTF）待做：`nx-batch-export-glb.vb` 模板已写 | 网页轻量化随 NX 母模批量导出一起做 |
| 10 | **网站集成/云部署**：目录网页版融入公司网站（onebot251231_n2PB6，React+Supabase）或腾讯云+宝塔部署；已出三方案（静态模块/网站后台/维护服务），等用户命令 | 📋 方案已分析待命令 | 需备案域名 + 服务器预算确认 |

共 9 项待办，**完成 4/6，1 试点中**，剩 2/3/5/7/8/9。核心软件（M1-M3）已完成。

**2026-08-22 全天进展记录（按序）**：
1. 占位 STEP 全量重建（OCCT 拓扑+颜色）→ 自测 25/25 → 2026.08 三份产物发布（2026.06 旧产物已全删，脚本默认参数统一指向 2026.08）
2. **统一路线重构**：源目录 `OnebotCatalog\onebot-data\catalog\` = 唯一数据源；C# FullCatalogBuilder（维护窗口【重建全量目录】/ CLI --buildfull）；向导编辑源目录 meta JSON（含 Display 显示名列）；旧打包脚本废弃
3. 尺寸图窗口**手册页对照**（38 页 2MB，kind=manual）
4. 新迪查看器 **menu=min 精简菜单 + 隐藏模型树**（本地副本；生产补丁文件备好）
5. 窗口拖拽：桌面版三分区 GridSplitter + 全部窗口可调/最小尺寸；网页版目录树/参数面板分隔条
6. **真实数模试点**：KC-00-32x10 真实 NX STEP 接入全链路，无头浏览器验证渲染成功（自测兼容真实 B-rep）
7. STEP 下载反馈+防连点；serve-web 并发化（Runspace 池）；publish 删除重试
8. 品牌统一 ONEBOT
9. 注意：release 站点 app.js 里 `VIEWER_BASE` 目前是本地 `/viewer/` 前缀，**上传生产前需改成 `/STEPViewer/index.html`**（§12）

**2026-08-23 进展记录（续）**：
10. **平替对照功能**：数据源 `catalog\crossref.csv`（brand,foreign_model,our_model,note；构建自动校验我方型号存在）；桌面【平替对照】标签页+搜索直达（SearchEngine 挂 AltCodes，竞品型号精确命中 900 分）、网页同款标签页；佳尔灵英文目录自动提取工具 `onebot-data\tools\jelpc-crossref.py`（系列对照 SI↔KC/SIB↔KCB/SQ↔KCS/SC↔KS/SU↔KSU/SCT↔KSB/MAL/MALC 同名；完整订购码需逐系列解析订购码页）
11. **.stp 后缀兼容**：构建内核 ResolveStepFile（优先 .step，找不到同名 .stp），NX 导出的 .stp 直接放无需改名（已实测）
12. 桌面 3D 真实数模**自动弹浏览器预览**（本机微型服务器，静默失败降级）；网页手册页标题只显序号、未选型不显示占位图
13. 修复向导前导零 bug（踩坑 #18），KC meta 数据还原，自测恢复 25/25
14. **产品种类扩充（空壳）**：catalog.json 新增 6 个分类——气动夹紧缸 CLM / 气动可伸缩定位销 PIN / 气动勾销缸 HOK / 气动夹爪缸 GRP / 气动翻转缸 ROT / 电动气缸 ELEC（中英名**参照官网 universal-onebot.com 与网站源码** `06_update_execution_categories.sql` + `translate-categories.sql`；series 暂为空，系列数据待 CSV+meta 按维护说明书场景 4 补充）→ 重建 25/25 自测 → 三份产物已发布
15. **6 个分类各建样板系列**（型号取自网站产品数据，几何占位、参数极简，作为填数模板）：UCBM/ULP/USP/UGP/UAGP/LAE（39 型号，占位 STEP 按型号命名——将来 NX 真实数模**同名替换**即可，CSV 都不用改）→ 17 系列 52,193 变体 → 自测 31/31 → 三份产物已发布
16. **新系列 .stp 原生约定**（按用户 NX 导出习惯）：6 个新系列的 step_file 列与占位文件统一为 `.stp`——NX 导出的 .stp 拷进 `catalog\step\` 同名覆盖即可，无后缀差异；老 11 个系列仍为 .step 列（.stp 自动兼容，但同前缀时 .step 优先，换 .stp 需先删 .step 占位）
17. **开源窗口内 3D（Helix Toolkit, MIT）**：桌面 3D 标签页接入 HelixViewport3D——选型后找 `<数据包目录>\mesh\<step同名>.stl`，有网格就**窗口内直渲**（不再弹浏览器），无网格回退浏览器方案；管线：NX journal 同步导出 STL 到 `catalog\mesh\`（exportStl 开关，公差 0.5mm）→ publish 同步到 sample\mesh\ + 发布目录 mesh\；`gen-mesh-preview.py` 生成占位网格（40 个已就位）；lib\ 放 HelixToolkit.Wpf.dll(2.27.3, net462)+HelixToolkit.dll，build/publish 自动附带（客户版 +580KB）
18. **STEP→STL 开源转换链路**（手头真实 STEP 不必等 NX）：`step-to-stl.py`（cadquery/OCP，LGPL，1.5mm 公差，**二进制 STL**）批量把 `catalog\step\` 真实数模转 `catalog\mesh\`；`simplify-stl.py`（纯 numpy 顶点聚类 0.75mm）把 >2MB 网格压小——UCBM32 装配体 22MB→2.1MB、USP63 4.8MB→0.5MB；已转真实网格：UCBM32/USP63/KC-00-32x10
19. **方案 B 落地：窗口内嵌 WebView2 3D（2026-08-24）**：lib\ 引入 Microsoft.Web.WebView2 三件套（1.0.4129.50, net462）；MainWindow 3D 标签页四级优先级——**STL 网格(Helix) > WebView2 内嵌新迪查看器(真实 STEP 直显) > 外部浏览器回退 > 占位自绘**；WebView2 初始化失败静默降级（Win11 自带运行时, Win10 装 Edge 即有）；真实数模不再弹浏览器窗口；发布目录附带三件套 DLL（开发提示词文档：`开发提示词-窗口内3D-WebView2方案B.md`）
20. **桌面/网页一致性 + 布局合并（2026-08-24，用户新规矩：桌面版功能与排版始终与在线版一致）**：两端 3D 与尺寸图合并为同一页（左 3D | 可拖拽分隔条 | 右 尺寸图+手册页）；网页无头实测分隔条拖拽生效；37 个占位网格已删，保留 3 个真实网格（UCBM32/USP63/KC-00-32x10）作无 WebView2 环境降级；新 6 系列手册占位（manual\<系列>\p01.png + meta 附件，`gen-manual-placeholders.py` 纯标准库生成，真实手册到货同名覆盖）
21. **PDF 下载 + 精确视图定稿（2026-08-24）**：① 17 个系列手册页打包成 PDF（`manual-pages-to-pdf.py`，纯标准库 PNG 解码+手写 PDF）挂 datasheet 附件——网页【下载 PDF】按钮直接下载、桌面数据表标签新增【下载数据表 (PDF)】（SaveFileDialog），与 STEP 下载一致；② **真实数模直接进 WebView2 精确视图**（用户定稿，不做网格快显+按钮）；显示链：占位→自绘 / 真实→WebView2 直显 / 无运行时→Helix 网格降级 / 都无→浏览器回退；③ 桌面参数表**双击行→参数带入选型**（与网页一致）；④ 新迪查看器防闪烁补丁（body 首帧前应用 embed/menu-min 类，生产部署补丁文件已更新）；⑤ crossref.csv 用户行 S0032-50 修正为 KCS0032-50
22. **购物车批量导出（2026-08-24，淘宝式，两端一致）**：三处入口（参数面板【加入清单】/参数表行尾"+"与勾选批量加入/顶栏【清单 (N)】角标）→ 清单面板（桌面非模态窗口/网页右侧抽屉；数量可改仅体现于 BOM，zip 每型号一份）→ **一键打包** zip（全部 STEP+BOM.csv UTF-8 BOM+清单.txt，重名加系列码后缀）；桌面 ZipArchive 零新依赖，网页 JSZip 3.10.1 (MIT, web\libs\) 前端内存打包纯静态；购物车生命周期=浏览器刷新/软件重启才清空，切系列/标签页/搜索/平替均不动购物车；原"参数表批量导出所选"改造为批量加入清单；无头 E2E 验证：两系列各加一件 → 角标 (2) 抽屉 2 条 0 报错；开发提示词：`开发提示词-批量导出购物车.md`
23. **参数化选型引擎一期（2026-08-25，两端一致，KC 试点）**：meta.json 扩展 `mode=parametric` + `modelCodeTemplate`（语法 `{field[:padN]}`）+ range 参数域（min/max/step/gridValues）；CSV 降级为"标准档位网格"，非标组合由引擎实时生成编码（无 STEP）；**对拍门禁**（构建期强制：KC 全部 2,628 编码模板重生成 100% 一致）；**双端一致性** = 一份规则 JSON + C#/JS 各一解释器 + 同一份测试向量 `catalog\parametric-vectors.json`（随 .opc 发布，桌面 selftest 36/36 含向量 7/7 + 网页无头 e2e-parametric.js 16/16）；非标档位行为：标题徽标 + 下载按钮置灰（统一文案）+ 3D 展示最近标准档位（按域距离，平局取小）+ 购物车条目标注"非标档位（打包时无 STEP）"、zip 打包跳过并注明；range 参数 UI = 桌面可编辑下拉（标准档位标"标准"）/ 网页输入框+datalist；非法输入红字提示不生效；开发提示词：`开发提示词-参数化选型引擎.md`、二期：`开发提示词-NX按需生成服务.md`（A 版已含 单个+批量/输出留存/检索先行/多格式）
24. **NX 按需生成服务二期 A 版（2026-08-25，开发+本地联调完成，待 NX 实测/部署）**：`bin\GenServer.exe`（独立控制台 exe，tools\build-genserver.ps1 单独编译，复用 CatalogCore 规则引擎做服务端二次校验——红线）+ `sample-data\tools\worker_journal.vb`（run_journal 常驻轮询，母模副本绝不保存、批量单会话顺序处理、逐项 .prog 进度）；**检索先行**（入队前+认领后双重检索，输出目录 `output\<系列>\<型号>\` 留存不删，全格式齐全即命中复用）；**多格式** STEP(214)/Parasolid/IGES/STL（DexBuilder+StlManager，与 nx-batch-export.vb 同源）；**单个+批量**（/gen、/gen-batch、/status、/file、/files、/download，token 一次性+限流+CORS+匿名模式）；两端接入：网页 config.js api（空=置灰过渡态）+ 桌面 catalog.json genApi；购物车含非标时打包前自动批量生成（型号子文件夹）；本地联调全过（状态机/检索/批量/zip/token；网页 e2e-gen.js 8/8：按钮升级/立即命中/排队轮询/标准回归）；**待用户**：masters.json 表达式名确认、KC 母模就位、NX run_journal 实测、IGES/Parasolid 枚举名按版本核对、云部署指令
25. **NX 2506 批处理攻坚（2026-08-26 凌晨，接续见 `OnebotCatalog\开发记录-NX2506批处理攻坚.md`）**：本机确认 **NX 2506 已装**（`C:\Program Files\Siemens\NX2506\NXBIN\run_journal.exe`）；全部 API 通过反射探针实测适配（probe-api1~6.vb）：OpenBaseDisplay（批处理 OpenBase 后 Work=NULL）、CloseAll 两参数、CreateExpression("Number","名=值")、UF EditExp 只改已存在、ufs.Modl.Update()、Session.DexManager 各格式独立 Creator（StepCreator/IgesCreator/ParasolidExporter/STLCreator）、SaveAs 两参数、journal 无 JSON 库（任务文件改行式键值，GenServer 烘焙母模配置）；worker 编译运行全管线通过（心跳/认领/改表达式/写结果）；**新增 PRT 格式**（用户需求：SaveAs 输出 NX 原生参数化部件）+ 格式下拉两端齐；**卡点**：批处理模式翻译器导出全部空几何（STEP/IGES 空文件、Parasolid "no valid export objects"、STL 不产出；已排除中文路径/只读/引用集/几何来源）——交互式导出正常；**明天方案**：用户交互式 NX 录制导出宏修正 worker 导出函数（首选），或真母模直接实测（可能直接成功）；**教训**：停 worker 时按时间条件批量杀 ugraf 误杀了用户交互会话，今后停进程必须精确 PID；用户新需求待做：生成后先 3D 预览再选格式下载（GenServer 加 /preview 端点）

## 10. 重要踩坑记录（2026-08-22，修复都带回归自测）

| # | 坑 | 根因与修复 | 影响面 |
|---|---|---|---|
| 1 | **选型选项一选就被清空**（"已选 0/5，无法选择"） | `AllowedOptions` 跳过了"已选参数"的键，UI 刷新拿空列表把刚选的值删掉（M1 就潜伏，样例期未暴露） | 桌面+网页 |
| 2 | **选完型号后参数锁死** | 修复#1 后，已选参数的可选值被"自己的当前值"锁死 → 改为"除自身外的其他已选"约束计算可改值 | 桌面+网页 |
| 3 | **网页磁石/固定形式点不了** | 空字符串 ""（无磁石/基本型）是合法枚举值，`<option value="">` 与"未选择"混淆 → 用 `__EMPTY__` 哨兵值 | 仅网页 |
| 4 | 本地预览服务器卡死 | `while ($reader.ReadLine() -ne '')` 遇客户端断连（返回 null）死循环 → EOF 判空退出 + 读写超时 + no-cache 响应头 | serve-web |
| 5 | PS 5.1/csc 按 GBK 读无 BOM 文件 → 中文乱码甚至吞掉语法符号 | 编辑任何含中文 .ps1/.cs/.vb 后**必须**跑 `fix-bom.ps1`（幂等）再编译 | 所有脚本 |
| 6 | PDF 手册数字提取为私有区字符 | 内嵌字体把 0~9 映射到 0xF6B1~0xF6BA，用 PyMuPDF 提取后按码点解码（ISO15552/-20~80°C 交叉验证） | extract-pdf.py |
| 7 | winexe 退出码不可靠 / robocopy 退出码 1=成功 | 自测结果以 selftest.log 文本为准；robocopy 0-7 均成功；**GUI 子系统 exe（OnebotCatalog.exe）用 `&` 启动后 PowerShell 不等待**（$LASTEXITCODE 空），构建可能在后台跑——必须 `Start-Process -Wait` 并核对 build.log/.opc 时间戳再发布，否则会把旧包发布出去（2026-08-23 踩过） | 脚本 |
| 8 | 客户版 exe 被运行中实例锁文件 | 编译前 `Stop-Process -Name OnebotCatalog` | 构建 |
| 9 | JavaScriptSerializer 默认 2M 字符上限 | 大目录 catalog.json 超限 → `MaxJsonLength = int.MaxValue` | 客户端 |
| 10 | 手写极简 STEP 在 occt-import-js 0.0.23 (新迪查看器) 崩溃 "RuntimeError: null function" | 试过拓扑升级(顶点上圆周+闭圆边+接缝边)/注入 STYLED_ITEM 颜色/颜色实体顺序重排, 该库对极简 B-rep 仍不稳定; **真实 CAD 导出的 STEP 全部正常** → 网页 iframe 联动 + 8 秒 Canvas 回退并存, 真实 NX STEP 替换占位后自动用新迪渲染 | 网页 3D 占位期 |
| 11 | serve-web 把 URL 查询串 `?file=` 当文件路径 → GetFullPath 抛异常 → 空响应 | 解析路径前先剥离 `?` 之后的部分 | serve-web |
| 12 | 单线程服务器扛不住浏览器并行/预连接 (ERR_EMPTY_RESPONSE) | 读超时降到 2s 快速失败 + 监听循环异常不退出 + no-cache | serve-web |
| 13 | 发布时站点目录删不掉 (句柄未释放竞态); STEP 下载点击无反馈被连点重复下载 | publish.ps1 站点目录删除加重试(6 次×2s); serve-web 改 **Runspace 池并发** (16 并发, 大文件不再阻塞下载); app.js 下载点击即时状态提示 + 3 秒防重复 | publish/serve-web/网页 |
| 14 | 用户把真实 STEP 放错目录/扩展名 (out\step\*.stp 旧目录) 导致网页看不到 | 统一路线后数据源只有 `OnebotCatalog\onebot-data\catalog\step\` 且文件名须与 CSV step_file 列一致 (.step); 真实 NX STEP 已接入验证 (自测兼容真实 B-rep: 网页走新迪渲染, Canvas 仅占位用) | 数据管线 |
| 15 | 网页数据"变回旧版" | serve-web.ps1/publish.ps1 默认参数残留 2026.06 版本号, 重启服务器时没带 -Root 就服务了旧站点 → 默认参数统一指向当前版本 + 旧版产物全删 + 发布产物只保留最新 | 脚本/运维 |
| 18 | 向导保存把枚举码 00/02/03 数值化成 0/2/3 (KC 系列 2 项自测挂掉) + 保存清空系列搜索关键词 | ToNumOrStr 前导零保持字符串; SaveConfig 覆盖时保留原关键词; 由"type 初始可选值非空/完整选型后可改"两项自测守卫 | 向导/数据 |
| 19 | 软件运行中点【重建全量目录】报"全量打包异常: .opc 正由另一进程使用" | OpcPackage.Open 用 ZipFile.OpenRead 持有文件句柄到退出 → 改为整包读入内存(FileShare.ReadWrite)后立即释放, 5.7MB 小包无压力; 实测软件开着包同时重建成功; 注意重建后内存中的包是旧的, 需重新加载数据包 | 数据管线/核心 |
| 20 | 新放的真实数模 (UCBM32.stp 6.3MB) 网页 3D 加载失败 | iframe `file=` 原为查看器目录内相对路径 → 查看器从自己 `STEPViewer\step\` 取文件, 该目录未随数据更新 → 404。改为**站点根绝对路径 `/step/xxx`**: 模型直接取站点 step\ (发布时从 .opc 解包), 查看器无需模型副本, 也不再需要双份同步; 无头验证 6.3MB 真实数模渲染成功 | 网页 3D |
| 21 | 桌面软件 UI 连发 OutOfMemoryException (crash.log, WPF DUCE 渲染通道) | 系统内存压力 (NX+浏览器+软件同开, 31.5GB 机器空闲仅 3.7GB) + WPF 软件渲染回退导致; 非代码 bug。缓解: 网格简化阈值 5MB→2MB (USP63 4.8MB→0.5MB); 新版 WebView2 路径把真实数模渲染移出 WPF (Edge GPU 进程); 全局异常日志 crash.log 是程序自带功能, 发布前删除残留 | 桌面 3D/环境 |
| 16 | 文件夹改名被占用删不掉 | 用户把 Excel 报价单放在软件文件夹里且正被 Excel 打开 (~$ 锁文件), 根目录被锁 → 用 robocopy /E /MOVE 把全部内容搬到新名目录 (文件级移动不受根目录锁影响), 遗留空壳等 Excel 关闭后手动删; **教训: 业务文件别放软件目录** | 运维 |
| 17 | 离线桌面版看不了真实数模 3D | 桌面内置解析器只支持占位圆柱几何, 真实 NX B-rep 空白 → 检测到真实数模时 3D 标签显示【在浏览器中打开 3D 预览】按钮: 程序内嵌 LocalViewerServer (127.0.0.1 随机端口 TcpListener, 零权限) + 系统浏览器 + 本地新迪副本; 客户版发布目录附带查看器组件 (~8MB, 剔除 samples/uploads/step)。**2026-08-23 升级**: 开源 Helix Toolkit (MIT) 窗口内直渲 STL 网格 (进展 17), 有网格时不再弹浏览器; 浏览器+新迪查看器降级为无网格时的回退 | 桌面版 3D |
| 22 | **参数化联动清空选项**（2026-08-25，两端同源） | ① AllowedOptions 原按"网格行存在性"过滤候选值——选 stroke=87 这类自由值后网格无此行 → 其他参数选项瞬间清空。改为按**域+规则**判合法（ValidatePartial + RuleViolatedPartial: Then 参数未选不判违背，否则选 mount=YB 会清空未选参数选项）；② 网页 domainValid 把空串一律判非法，但枚举空值（磁石=""）是合法值——只对 range 拦截空串。修复后桌面 36/36、网页 E2E 16/16 + 购物车回归全过 | 参数化联动 |
| 23 | **GenServer 三连坑**（2026-08-25） | ① JavaScriptSerializer **泛型** Deserialize\<Dictionary\> 路径下 JSON 数组是 **ArrayList** 而非 object[]（DeserializeObject 路径才是 object[]，selftest 向量没踩到）——gen-batch 解析失败；② job 完成后 .done 结果里没有 token，下载校验查不到 → **.tok 侧车文件**独立存 token（24h 过期），且 /files 必须先读 .done 再消费 token（顺序反了会 404）；③ 输出留存导致联调测试跨轮次残留 → 测试脚本开头加夹具清理（生产留存在是特性、测试环境是干扰） | GenServer |
| 24 | **NX 2506 批处理连环坑**（2026-08-26，全部实测+探针定位） | ① run_journal 只接受一个参数 → 配置走"当前工作目录\worker-config.txt + worker-no.txt"；② 批处理 OpenBase 打开后 Work=NULL → **OpenBaseDisplay**；③ Program Files 复制的模板带只读属性 → NX 只读打开拒绝保存（syslog 里 "Read only part modified"），母模/worker 副本都要清只读；④ 表达式 API 全变：CreateExpression("Number","名=值")、EditExp 只改已存在；⑤ journal 编译环境无 System.Web.Script.Serialization 也无泛型隐式导入 → 任务文件/配置全部改行式键值格式 + 显式 Imports System.Collections.Generic；⑥ 导出器从 Part.DexManager 挪到 Session.DexManager 且各格式独立 Creator；⑦ **未解**：批处理翻译器导出空几何（进展 25） | NX 2506 / worker |

**UI 回归诊断手段**：`tools/ui-diagnose.ps1`（逐系列检查下拉数据源）、`tools/ui-diagnose2.ps1`（模拟点击选型全链路，STA 模式）——UI 问题先跑这两个再猜。

## 11. ONEBOT 真实数据管线（2026-08-22 入库）

**数据源**：《ONEBOT - 直线气缸 - 中文.pdf》（152 页/71MB，品牌 **ONEBOT**）。

**提取与构建（统一路线，2026-08-22 重构后）**：
```
手册 PDF ──extract-pdf.py(PyMuPDF+数字解码)──→ 每页文本
   ↓ 人工/模型整理
OnebotCatalog\onebot-data\tools\gen-onebot-source.ps1（系列定义+规则+占位几何+CSV → 源目录）
   ↓ 源目录 = 唯一数据源
OnebotCatalog\onebot-data\catalog\  (catalog.json + series\*.meta.json + csv\ + step\ + manual\)
   ↓ 打包 = C# 统一内核 (维护窗口【重建全量目录】/ CLI --buildfull)
OnebotCatalog\sample\OnebotCatalog_2026.08.opc (17 系列, 52,193 变体, 5.6MB, 手册页 2MB)
   ↓ publish.ps1 → 客户 exe / 光盘目录 / 增量包 / 网页站
```
- NX 真实 STEP 直接替换 `catalog\step\` 同名文件后【重建全量目录】即可，全链路自动更新

- 系列：KC(32~320)/KCB/KSB(双行程)/KCS/KS/KSU/M/MS/MSC/MAL/MALC；规则按手册提取（YB→缸径≤125；KS/KSU 双轴型固定形式受限）
- 行程取标准档 10/20/30/50/75/100；"可调行程 25~1000mm"属**参数化二期**
- **几何占位**：NX 母模批量导出真实 STEP 后按同名（`系列-型号缸径x行程.step`）替换 **`catalog\step\`** 再【重建全量目录】即可，全链路（桌面/网页/发布）自动更新；**KC-00-32x10 真实数模已试点接入验证通过**
- 型号编码按订购码表拼接（如 KC0032-100MLB），与 ERP 真实编码有出入时改 CSV 的 model_code 列
- **手册页对照（2026-08-22）**：尺寸图窗口新增系列级手册页（附件 kind=manual）。`OnebotCatalog\onebot-data\tools\render-manual-pages.py` 从手册 PDF 按系列拆页渲染灰度 PNG（110dpi，38 页 2MB，映射表在脚本 SERIES_PAGES 里；KC 全缸径合并 p2-6+p11-12，KS/KSU 共享双轴页 p14-15）→ `catalog\manual\<系列>\pXX.png` → gen-onebot-source.ps1 在 meta JSON 里写附件引用 → 全量构建时打包进 .opc。桌面/网页均"选中系列即显示"，滚动对照；改映射/DPI 后重跑渲染脚本+重建即可

## 12. 新迪 3D 查看器联动（网页 3D 升级）

**两个项目的关系（重要）**：新迪 2D/3D 查看器是**独立项目**，原代码在 `Z:\web\FTP_ObjectStorage\上海新迪3D\dev`（生产部署于 3d.ruiguo.wang，FTP 双向同步）。**原项目代码只读、不许改动**；集成使用**本地副本** `OnebotCatalog\viewer\STEPViewer\`。

**嵌入协议**（见其 开发文档.md + embed_demo.html）：
```
<iframe src="STEPViewer/index.html?file=/step/<站点根绝对路径>&embed=1&bg=grey">
```

**集成方式**：
- **file 参数用站点根绝对路径 `/step/xxx`（2026-08-23 改，踩坑 #20）**：模型直接从站点 step\ 目录取，查看器目录无需自带模型副本（不再维护 STEPViewer\step\ 双份拷贝）；本地/生产同规则——发布时 .opc 解包出的站点 step\ 即查看器数据源
- 网页 app.js：`VIEWER_BASE` 配置——本地联调 `/viewer/STEPViewer/index.html`（serve-web.ps1 `-ViewerRoot` 双根目录同端口避免跨域），生产同域改为 `/STEPViewer/index.html`
- **8 秒回退机制**：查看器 404/离线时自动退回内置 Canvas 渲染（保留的零依赖方案）
- **精简菜单 + 无模型树（2026-08-22）**：iframe 带 `&menu=min` → 只保留 剖切/线框/透明/视角/测量，模型树面板隐藏、3D 视口占满 iframe（本地副本 app.js/style.css 已改；生产 Z 盘原版未动，补丁见 `OnebotCatalog\viewer\菜单精简-生产部署补丁.txt`，部署时自行应用；**无头浏览器已验证**：真实 STEP 渲染成功零报错、菜单恰 5 项、模型树隐藏）
- 本地服务命令：`serve-web.ps1 -Root release\web_2026.08 -ViewerRoot OnebotCatalog\viewer`
- 无头验证脚本：`%TEMP%\nds3dtest\check_real_model.js`（playwright-core + Edge，仿照它验证新模型渲染）

## 13. 新对话接续方式

开始新对话时直接说：**"读一下 项目总览.md 和 OnebotCatalog\开发记录-NX2506批处理攻坚.md，我们继续开发欧霓博目录软件二期"**，AI 即可恢复全部上下文（本文件 = 范围/架构/进度/踩坑；开发记录 = 二期 NX 攻坚的最新卡点与明天方案；README + OnebotCatalog\文件夹说明.md 为补充）。
