附图报价系统设计分析2

一、项目概览
| 项目 | 信息 |
|---|---|
| 项目名称 | QuoteApp 附图报价助手桌面应用 |
| 项目位置 | d:\QuoteApp\ |
| 技术栈 | Python 3.10+ / PyQt6 / SQLite(SQLAlchemy ORM)/ openpyxl / python-docx |
| 可选依赖 | pythonOCC(STEP高精度解析)/ pymupdf / PaddleOCR / OpenVINO |
| 代码初版完成 | 2026-03-27 |
| 本日优化完成 | 2026-03-28 |
| 测试状态 | 53 个单元测试全部通过;冒烟测试通过 |
| 启动命令 | pip install -r requirements.txt && python main.py |

二、目录结构
QuoteApp/
├── main.py # 应用入口(PyQt6 QApplication)
├── requirements.txt # 依赖清单(含 OCR 依赖说明)
├── smoke_test.py # 集成冒烟测试(in-memory DB)
├── src/
│ ├── core/
│ │ ├── geometry_extractor.py # 几何解析(STEP/STL/PDF/DXF)★ 本日升级
│ │ ├── process_engine.py # 工艺推断(11道工序+工时定额)
│ │ ├── quota_formulas.py # 工时定额手册公式库
│ │ ├── cost_calculator.py # 成本核算(材料费+加工费+税费+利润)
│ │ └── quote_generator.py # 报价单导出(Excel/Word)
│ ├── models/
│ │ ├── database.py # SQLAlchemy init_db + SessionFactory
│ │ ├── material.py # 材料 ORM(7种预置材料)
│ │ ├── process.py # 工序 ORM(11道工序)
│ │ ├── auxiliary_cost.py # 辅材费 ORM(20种)
│ │ ├── quota_coeff.py # 定额系数 ORM(24条)
│ │ └── quote_record.py # 报价历史记录 ORM
│ └── ui/
│ ├── theme.py # 集中式主题管理 ★ 本日新增
│ ├── main_window.py # 主窗口(三Tab)
│ ├── quote_panel.py # 报价Tab(含 DimReviewDialog)★ 本日升级
│ ├── settings_panel.py # 参数维护Tab ★ 本日修复
│ ├── history_panel.py # 历史记录Tab
│ └── process_table.py # 工序明细表格组件
├── templates/
│ ├── quote_template.xlsx # Excel 报价模板
│ └── quote_template.docx # Word 报价模板
└── tests/ # 53 个单元测试
三、核心功能模块
3.1 几何解析引擎(geometry_extractor.py)
支持四种文件格式,按精度分级处理:
| 格式 | 解析方式 | 置信度 |
|---|---|---|
| STEP / STP | pythonOCC(高精度)→ trimesh(降级) | 0.95 / 0.85 |
| STL | trimesh 网格体积 | 0.80 |
| DXF | ezdxf 矢量解析 | 0.82 |
| 三级降级链(见下节) | 0.50 ~ 0.85 |
提取信息:长/宽/高、体积、表面积、孔特征(直径/深度/数量)、复杂度(简单/中等/复杂)
3.2 PDF 三级降级解析链
PDF 文件
│
├─► Level 1: pymupdf 矢量提取 置信度 ~78%
│ ├─ 工程标注正则(Ø/φ/R/×)
│ ├─ 出现频次过滤(量化到 0.5mm)
│ └─ 中位数离群剔除
│
├─► Level 2: PaddleOCR(扫描版) 置信度 ~85%
│ ├─ pymupdf 渲染 300DPI PNG
│ ├─ CLAHE 自适应对比度增强
│ ├─ PaddleOCR 中英文识别
│ └─ 置信度 < 60% 的词丢弃
│
└─► Level 3: pdfplumber 文本兜底 置信度 ~50%
└─ 原始暴力提取(最后保障)
升级前 vs 升级后对比:
| 指标 | 升级前 | 升级后 |
|---|---|---|
| 平均置信度 | 50% | 78% ~ 85% |
| 孔特征识别 | ❌ 无 | ✅ 识别 Ø/φ/R 标注 |
| 扫描版图纸 | ❌ 无法识别 | ✅ PaddleOCR 识别 |
| 置信度不足时提示 | ❌ 无 | ✅ 弹出核对对话框 |
3.3 工艺推断引擎(process_engine.py)
根据几何特征推断 11 道工序及对应工时:
| 工序 | 定额来源 |
|---|---|
| 编程 | 复杂度系数 × 特征数 |
| 准终时间 | 手册查表(简单/中等/复杂三档) |
| 车削 | 一章 C620 公式(外圆/端面/车孔/钻孔) |
| 孔加工 | 十一章钻床公式(D/L/K材料系数) |
| 铣削 | 面积 × 铣削系数 |
| 磨削 | 六章磨床(平面磨 F 面积公式) |
| 热处理 | 重量 × 处理系数 |
| 线切割 | 轮廓长度 × 切割系数 |
| 检测/包装/表面处理 | 固定系数 + 面积系数 |
3.4 成本核算(cost_calculator.py)
总成本 = 材料费 + 加工费 + 辅材费 + 管理费
含税报价 = 总成本 × (1 + 利润率) × (1 + 税率)
- 材料费:体积 × 密度 × 单价(损耗系数 1.05)
- 加工费:Σ(工时 × 工序单价)
- 辅材费:用户在参数维护中勾选的辅材合计(默认 ¥13)
- 利润率/税率:参数维护中可配置
3.5 报价单导出
支持 Excel 和 Word 两种格式,报价单包含:
表头字段:客户名称 / 收货地址 / 收件人 / 电话 / 备注 / 报价单号(QT-YYYYMMDD-XXXX)/ 客户单号 / 付款方式(在线支付/账期支付/线下电汇)/ 税率 / 物流费用 / 审核员 / 报价员 / 平台签章 / 客户签章
工件清单:物料名称 / 平台型号 / 客户型号 / 模具编号 / 零件编号 / 材质 / 品牌 / 单位 / 数量 / 含税单价 / 合计金额 / 交期(天)
四、数据预置
| 类型 | 数量 | 内容 |
|---|---|---|
| 材料库 | 7种 | 铝6061 / 铝T6 / 钢45# / 冷拉钢 / 不锈钢304 / 灰铸铁 / 黄铜 |
| 工序 | 11道 | 编程/准终/热处理/线切割/孔加工/车削/铣削/磨削/检测/包装/表面处理 |
| 定额系数 | 24条 | 车/钻/铣/磨/编程/准终/装卸全覆盖 |
| 辅材 | 20种 | 按刀具/冷却/磨料/量具/包材/其他分类,默认选中电费分摊+清洗(¥13) |
五、优化内容
5.1 UI 主题升级
新增 src/ui/theme.py 集中式主题管理:
- 自动检测 Windows 注册表
AppsUseLightTheme,切换深色/浅色主题 Theme.apply(app)一次性应用 QSS + QPaletteTheme.C颜色 token 字典统一管理所有 UI 颜色- 浅色:Win11 Fluent Design(白底 /
#0078D4强调蓝) - 深色:工业深色风(
#1C1F26背景 /#2B82F0强调蓝)
受影响文件:main.py / main_window.py / quote_panel.py / settings_panel.py / history_panel.py / process_table.py
5.2 参数维护-材料库列表高度修复
问题根因 :QTableWidget 未设置 minimumHeight 和 SizePolicy,Qt 布局引擎将其压缩到只显示表头的高度。
修复内容:
| 修复点 | 改动 |
|---|---|
mat_table 初始高度 |
setMinimumHeight(220) + setSizePolicy(Expanding, Expanding) |
| 数据加载后动态调整 | resizeRowsToContents() + 按行数计算 minimumHeight(最多 12 行) |
| 列宽优化 | 材料名称列改为 Stretch 自适应 |
quota_table |
同步修复(最小 200px,最多 10 行) |
| 布局权重 | 材料库卡片 stretch=3,定额系数卡片 stretch=2 |
| 视觉优化 | 交替行颜色、隐藏垂直表头、按行选中 |
5.3 参数维护-辅材费复选框无法勾选 BUG 修复
问题根因 :QGroupBox.setCheckable(True) + setChecked(False) --- Qt 的 checkable GroupBox 在 checked=False 时自动禁用组内所有子控件 ,导致 20 个 QCheckBox 全部变为 disabled,无法点击。
修复内容:
| 修复点 | 改动 |
|---|---|
| 根本修复 | 辅材费 GroupBox 去掉 setCheckable(True),改为普通 GroupBox |
| 布局清空 | deleteLater()(异步)→ takeAt() + setParent(None)(同步),防止布局错位 |
| 信号改用 | toggled → checkStateChanged,避免重复触发保存 |
| 新增分类标题 | 刀具/冷却/磨料/量具/包材/其他 分隔显示 |
| 滚动区域 | 20 条辅材放入最大 280px 的 QScrollArea |
| "全部取消"按钮 | 一键清空所有选中 |
| 验证结果 | headless 测试:CB total:20 enabled:20 ✅ |
5.4 PDF 图纸解析置信度升级
问题根因:原代码取 PDF 文本中最大的三个数字作为 L/W/H,图框编号、公差值、零件号全部混入,置信度天然只有 50%,报价严重虚高。
新增依赖:
pymupdf >= 1.23.0 # 矢量PDF文字精确提取
paddlepaddle + paddleocr # 扫描版OCR识别(CPU版,约700MB模型)
opencv-python-headless # 图像预处理(CLAHE对比度增强)
# 可选加速:
openvino # Intel CPU 推理加速(速度提升3~5x)
三级降级链架构:
python
def _parse_pdf(file_path):
# Level 1: pymupdf 矢量提取(置信度 ~78%)
try:
feat = _parse_pdf_vector(file_path)
if feat.confidence >= 0.70: return feat
except: pass
# Level 2: PaddleOCR 扫描识别(置信度 ~85%)
try:
return _parse_pdf_ocr(file_path)
except: pass
# Level 3: pdfplumber 兜底(置信度 ~50%)
return _parse_pdf_fallback(file_path)
智能尺寸过滤算法 (_filter_engineering_dims):
- 范围过滤:保留 2~3000mm(排除页码/版次/公差)
- 量化聚合:量化到 0.5mm 精度,统计出现频次
- 频次优先:同一尺寸重复标注 → 更可信
- 离群剔除:排除 > 中位数 20 倍的异常值
新增 UI:尺寸核对对话框 (DimReviewDialog):
- 当 PDF 解析置信度 < 80% 时自动弹出
- 允许用户手动修正 L/W/H / 孔数 / 复杂度
- 修正后置信度自动标记为 ≥ 80%
置信度提升对比:
| 图纸类型 | 升级前 | 升级后 |
|---|---|---|
| 矢量 PDF(CAD直出) | 50% | 78% |
| 扫描版 PDF | 50% | 85% |
| 所有 PDF(手工核对后) | 50% | ≥80% |
六、已知限制与后续建议
| 项目 | 当前状态 | 建议 |
|---|---|---|
| STEP 高精度解析 | 需单独安装 pythonocc-core(conda) |
提供 conda 环境配置文件 |
| PaddleOCR 首次加载 | 约 3~5 秒(下载并加载约 300MB 模型) | 增加启动进度提示 |
| OpenVINO 加速 | 可选安装,Intel CPU 速度提升 3~5x | 推荐 Intel 平台用户安装 |
| PDF 孔特征识别 | 通过正则识别 Ø/φ/R 标注,需图纸标注规范 | 后续可增加 CNN 检测圆形特征 |
| 批量报价 | 当前只支持单件报价 | 可增加批量导入 Excel 功能 |
| EXE 打包 | 已更新 dist/QuoteApp/QuoteApp.exe |
建议增加版本号管理 |

七、规格文档清单
| 文档 | 状态 |
|---|---|
| REQUIREMENT.md | ✅ 完成 |
| DESIGN.md | ✅ 完成 |
| QUOTA_ENGINE_DESIGN.md | ✅ 完成 |
| BUSINESS_RULES.md | ✅ 完成 |
| UML_MODELS.md | ✅ 完成 |
| PROCESS_FLOWS.md | ✅ 完成 |
| TASK_PLAN.md | ✅ 完成 |