附图报价系统设计分析
模具附图报价系统设计分析文档
一、项目概述
1.1 项目背景
本项目是一个模具附图报价系统,主要面向模具制造行业的图纸处理和报价需求。系统通过集成DWG文件转换、AI视觉模型解析等技术,实现从CAD图纸到报价信息的自动化处理。
1.2 核心功能
- DWG文件转换:将AutoCAD的DWG格式文件转换为开放的DXF格式
- AI视觉解析:利用通义千问VL模型解析图纸内容
- 本地代理服务:解决浏览器CORS跨域限制

二、技术架构分析
2.1 整体架构
┌─────────────────────────────────────────────────────────────────────────┐
│ 模具附图报价系统 │
├─────────────────────────────────────────────────────────────────────────┤
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ Electron │ │ DWG转换服务 │ │ VL代理服务 │ │
│ │ 桌面客户端 │◄──►│ (Node.js) │ │ (Node.js) │ │
│ │ (主进程) │ │ Port:3002 │ │ Port:3001 │ │
│ └──────────────┘ └──────────────┘ └──────────────┘ │
│ │ │ │ │
│ ▼ ▼ ▼ │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────────────┐ │
│ │ 渲染进程 │ │ uploads/ │ │ DashScope API │ │
│ │ (UI界面) │ │ outputs/ │ │ (通义千问VL模型) │ │
│ └──────────────┘ └──────────────┘ └──────────────────────┘ │
└─────────────────────────────────────────────────────────────────────────┘
2.2 技术栈
| 层级 | 技术 | 用途 |
|---|---|---|
| 桌面框架 | Electron 40.8.1 | 跨平台桌面应用 |
| 后端服务 | Node.js + HTTP模块 | 本地服务搭建 |
| 文件处理 | Node.js FS模块 | 文件读写操作 |
| AI模型 | 通义千问VL (qwen-vl-plus) | 图纸内容识别 |
| API代理 | Node.js HTTP/HTTPS | 跨域请求转发 |
| 打包工具 | electron-builder | 应用打包分发 |
三、核心模块详解
3.1 DWG转换服务 (dwg-converter.js)
3.1.1 功能职责
- 接收DWG文件上传
- 解析DWG文件头信息
- 生成基础DXF文件结构
- 提供健康检查接口
3.1.2 接口设计
| 接口 | 方法 | 功能 |
|---|---|---|
/health |
GET | 服务健康检查 |
/convert |
POST | DWG转DXF转换 |
3.1.3 请求/响应格式
上传请求:
POST /convert
Content-Type: multipart/form-data
file: [DWG二进制文件]
成功响应:
{
"success": true,
"dxfContent": "DXF文件内容",
"fileName": "converted.dxf",
"dwgPath": "uploads/uploaded_xxx.dwg",
"dxfPath": "outputs/converted_xxx.dxf"
}
3.1.4 技术实现分析
// 核心转换逻辑
async function convertDWGToDXF(dwgPath, dxfPath) {
// 1. 读取DWG文件
const dwgData = fs.readFileSync(dwgPath);
// 2. 检查DWG文件头 (AC1018 = AutoCAD 2004)
const header = dwgData.slice(0, 6).toString('ascii');
// 3. 创建基础DXF结构
const dxfContent = createBasicDXF(dwgData);
// 4. 写入DXF文件
fs.writeFileSync(dxfPath, dxfContent);
}
技术局限:
- 当前实现为基础框架,仅生成DXF文件结构
- 未实现完整的DWG实体解析(需要专业库如@tarikjabiri/dwg)
- DWG是专有格式,完整解析需要授权
3.2 VL模型代理服务 (vl-proxy.js)
3.2.1 功能职责
- 解决浏览器CORS跨域限制
- 代理转发AI模型请求
- 提供静态文件服务
- 请求日志记录
3.2.2 接口设计
| 接口 | 方法 | 功能 |
|---|---|---|
/health |
GET | 服务健康检查 |
/proxy |
POST | 代理API请求 |
/* |
GET | 静态文件服务 |
3.2.3 代理请求格式
请求体:
{
"targetUrl": "https://dashscope.aliyuncs.com/compatible-mode/v1/chat/completions",
"headers": {
"Authorization": "Bearer sk-xxx"
},
"body": {
"model": "qwen-vl-plus",
"messages": [...]
}
}
3.2.4 CORS处理
// 设置跨域头
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');
res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization, X-Requested-With');
3.3 Electron桌面应用
3.3.1 应用配置
# builder-effective-config.yaml
appId: com.mold.quotation
productName: 模具附图报价系统
electronVersion: 40.8.1
win:
target: nsis
3.3.2 应用结构
win-unpacked/
├── 模具附图报价系统.exe # 主程序
├── resources/
│ ├── app.asar # 应用资源包
│ └── elevate.exe # 权限提升工具
├── locales/ # 多语言包
└── [Electron运行时DLL] # 依赖库
四、数据流分析
4.1 文件转换流程
┌─────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────┐
│ 用户 │────►│ 选择DWG文件 │────►│ 上传至服务 │────►│ 保存到 │
│ │ │ │ │ │ │ uploads │
└─────────┘ └─────────────┘ └─────────────┘ └────┬────┘
│
▼
┌─────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────┐
│ 用户 │◄────│ 返回DXF内容 │◄────│ 读取DXF文件 │◄────│ 生成DXF │
│ │ │ │ │ │ │ 到outputs│
└─────────┘ └─────────────┘ └─────────────┘ └─────────┘
4.2 AI解析流程
┌─────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ 用户 │────►│ 发送解析请求 │────►│ 本地代理服务 │────►│ DashScope │
│ │ │ (含图片) │ │ Port:3001 │ │ API │
└─────────┘ └─────────────┘ └─────────────┘ └──────┬──────┘
│
▼
┌─────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ 显示 │◄────│ 前端渲染 │◄────│ 代理返回 │◄────│ qwen-vl-plus│
│ 结果 │ │ │ │ 响应 │ │ 模型推理 │
└─────────┘ └─────────────┘ └─────────────┘ └─────────────┘
五、目录结构
edev/
├── uploads/ # 上传文件存储
│ └── uploaded_xxx.dwg # 原始DWG文件
├── outputs/ # 转换输出存储
│ └── converted_xxx.dxf # 转换后的DXF文件
├── win-unpacked/ # Electron解压版本
│ ├── 模具附图报价系统.exe # 可执行程序
│ ├── resources/
│ │ └── app.asar # 应用资源
│ └── locales/ # 国际化文件
├── dwg-converter.js # DWG转换服务源码
├── vl-proxy.js # VL代理服务源码
├── start-dwg-converter.bat # 服务启动脚本
├── builder-effective-config.yaml # 打包配置
├── dwg-converter.log # 转换服务日志
├── proxy.log # 代理服务日志
└── 模具附图报价系统 Setup 1.0.0.exe # 安装包
六、关键技术点
6.1 DWG文件格式
| 版本标识 | AutoCAD版本 | 说明 |
|---|---|---|
| AC1015 | AutoCAD 2000 | DXF R15 |
| AC1018 | AutoCAD 2004 | 实测文件版本 |
| AC1021 | AutoCAD 2007 | 支持UTF-8 |
| AC1024 | AutoCAD 2010 | 新实体类型 |
6.2 DXF文件结构
0 // 组码
SECTION // 段开始
2 // 组码
HEADER // 段名 (HEADER/TABLES/ENTITIES/OBJECTS)
... // 段内容
0
ENDSEC // 段结束
0
EOF // 文件结束
6.3 服务端口分配
| 服务 | 端口 | 用途 |
|---|---|---|
| VL代理服务 | 3001 | AI模型请求代理 |
| DWG转换服务 | 3002 | 文件转换服务 |
七、设计模式与最佳实践
7.1 设计模式应用
-
代理模式 (Proxy Pattern)
- vl-proxy.js 实现API请求的代理转发
- 解决浏览器同源策略限制
-
单例模式 (Singleton)
- HTTP服务器实例单一管理
- 全局日志记录器
-
工厂模式 (Factory)
- 文件名生成器
generateFileName()
- 文件名生成器
7.2 错误处理机制
// 全局异常捕获
process.on('uncaughtException', (error) => {
log('未捕获的异常:', error);
});
process.on('unhandledRejection', (reason, promise) => {
log('未处理的Promise拒绝:', reason);
});
7.3 日志记录规范
- 时间戳:ISO 8601格式
- 日志级别:INFO/ERROR
- 日志文件:按服务分离
八、安全分析
8.1 潜在风险
| 风险点 | 风险等级 | 说明 |
|---|---|---|
| API密钥硬编码 | 高 | proxy.log中发现API Key |
| 文件上传限制 | 中 | 无文件大小和类型校验 |
| CORS允许所有 | 中 | Access-Control-Allow-Origin: * |
| 路径遍历 | 低 | 文件名未做安全过滤 |
8.2 安全建议
-
API密钥管理
- 使用环境变量存储敏感信息
- 实现密钥轮换机制
-
文件上传安全
- 限制文件大小(如10MB)
- 验证文件魔数(Magic Number)
- 隔离存储目录
-
CORS策略
- 限制允许的来源域名
- 按需开放HTTP方法
九、性能优化建议
9.1 当前瓶颈
- DWG解析:未实现完整解析,仅生成空结构
- 文件IO:同步读写阻塞主线程
- 内存管理:大文件可能导致内存溢出
9.2 优化方案
-
异步处理
// 使用流式处理替代同步读写 const stream = fs.createReadStream(dwgPath); -
Worker线程
- 将文件转换放入独立线程
- 避免阻塞主服务
-
缓存机制
- 缓存已转换的文件
- 实现LRU淘汰策略
十、扩展性设计
10.1 可扩展点
-
转换引擎扩展
// 支持多种转换器 const converters = { 'dwg2dxf': DWGToDXFConverter, 'pdf2dxf': PDFToDXFConverter, 'svg2dxf': SVGToDXFConverter }; -
AI模型扩展
- 支持多模型切换
- 模型结果融合
-
插件系统
- 自定义解析规则
- 报价算法插件
10.2 微服务拆分建议
┌─────────────────────────────────────────┐
│ API Gateway │
├─────────────┬─────────────┬─────────────┤
│ 文件服务 │ 转换服务 │ AI服务 │
│ (File) │ (Convert) │ (AI) │
├─────────────┴─────────────┴─────────────┤
│ 消息队列 (MQ) │
└─────────────────────────────────────────┘
十一、部署与运维
11.1 启动脚本
@echo off
chcp 65001 >nul
echo 正在启动DWG转换服务...
node dwg-converter.js
pause
11.2 服务监控
| 监控项 | 检查端点 | 频率 |
|---|---|---|
| 服务存活 | /health | 30秒 |
| 磁盘空间 | uploads/outputs | 5分钟 |
| 错误日志 | *.log | 实时 |
11.3 日志轮转
// 建议实现日志分割
const logStream = fs.createWriteStream('app.log', {
flags: 'a',
highWaterMark: 1024 * 1024 // 1MB缓冲
});
十二、总结
12.1 设计亮点
- 模块化设计:服务分离,职责清晰
- 跨域解决方案:本地代理模式
- AI集成:通义千问VL模型应用
- 桌面化部署:Electron跨平台方案
12.2 改进方向
- 功能完善:实现完整DWG解析
- 架构升级:微服务化改造
- 安全加固:密钥管理和访问控制
- 性能优化:异步处理和缓存机制
12.3 技术债务
- DWG实体解析不完整
- API密钥硬编码
- 缺少单元测试
- 无数据库持久化
- 缺少用户认证
附报告
1. 项目概述
1.1 项目简介
模具附图报价系统是一个基于Electron开发的桌面应用程序,主要用于机械模具行业的图纸解析、工艺规划和报价计算。该系统集成了AI视觉识别、工艺路线自动规划、工时估算和报价计算等核心功能。
1.2 技术栈
- 前端框架:Electron 40.8.1(跨平台桌面应用)
- 开发语言:JavaScript(ES6+)
- UI技术:HTML5 + CSS3
- AI集成:通义千问(Qwen)、DeepSeek、本地AI模型
- PDF处理:PDF.js 3.11.174
- 数据存储:localStorage
- 构建工具:Electron-builder
1.3 项目定位
这是一个面向制造企业的B2B专业工具,旨在提高模具报价的效率和准确性,减少人工操作成本。
2. 系统架构设计
2.1 整体架构图
┌─────────────────────────────────────────────────────────────────┐
│ 用户界面层 (UI) │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────────────┐ │
│ │ 图纸解析模块 │ │ 工艺规划模块 │ │ 报价计算模块 │ │
│ └─────────────┘ └─────────────┘ └─────────────────────┘ │
└─────────────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────────────┐
│ 业务逻辑层 (Business) │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────────────┐ │
│ │ AI处理器 │ │ 计算器模块 │ │ 工时标定模块 │ │
│ └─────────────┘ └─────────────┘ └─────────────────────┘ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────────────┐ │
│ │ 策略模块 │ │ 解析器模块 │ │ CAD解析模块 │ │
│ └─────────────┘ └─────────────┘ └─────────────────────┘ │
└─────────────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────────────┐
│ 数据层 (Data) │
│ ┌──────────────────────────────────────────────────────────┐ │
│ │ 状态管理 (AppState) │ │
│ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌─────────┐│ │
│ │ │工件列表 │ │零件管理 │ │系统配置 │ │定额数据 ││ │
│ │ └──────────┘ └──────────┘ └──────────┘ └─────────┘│ │
│ └──────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────────────┐
│ 存储层 (Storage) │
│ ┌──────────────────────────────────────────────────────────┐ │
│ │ localStorage │ │
│ │ 材料配置 | 工序配置 | 标定数据 | 报价历史 | 策略配置 │ │
│ └──────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────┘
2.2 模块划分
| 模块名称 | 文件路径 | 主要职责 |
|---|---|---|
| 主进程 | electron-main.js | Electron主进程,创建窗口 |
| 预加载脚本 | preload.js | 预加载脚本,桥接主进程与渲染进程 |
| 主逻辑 | main.js | 业务逻辑整合,流程控制 |
| UI模块 | ui.js | 界面交互、通知、导出功能 |
| 状态管理 | state.js | 全局状态管理,数据持久化 |
| AI处理 | ai-handler.js | AI模型调用,图纸解析 |
| 计算器 | calculator.js | 工时计算、材料计算、报价计算 |
| 策略模块 | strategy.js | 报价策略管理与应用 |
| 工时标定 | calibration.js | 实测数据录入、参数拟合 |
| 解析器 | parsers.js | 数据解析与格式转换 |
| 定价数据 | pricing-data.js | 定额数据库、材料信息 |
2.3 核心设计模式
2.3.1 模块化设计
系统采用高度模块化的架构,每个功能模块相对独立,通过清晰的接口进行交互。
// 模块定义示例
const ModuleName = {
// 公共方法
method1() { ... },
method2() { ... },
// 私有方法(以下划线开头约定)
_privateMethod() { ... }
};
2.3.2 状态管理模式
使用单例模式的AppState进行全局状态管理:
const AppState = {
data: { ... },
get(key) { ... },
set(key, value) { ... },
subscribe(key, callback) { ... }
};
2.3.3 策略模式
报价策略模块采用策略模式,支持多种报价策略的切换和对比:
StrategyModule.getAllStrategies()
StrategyModule.recommendStrategy(workpiece, customerType, projectType)
StrategyModule.compareStrategies(workpiece)
3. 核心功能模块分析
3.1 图纸解析模块
3.1.1 功能概述
支持PDF和CAD两种格式的图纸解析,集成多种AI模型进行智能识别。
3.1.2 AI模型集成架构
图纸上传
↓
┌─────────────────────────────────────────┐
│ 多模型解析策略 │
├─────────────────────────────────────────┤
│ ┌──────────┐ ┌──────────┐ │
│ │ VL模型 │→ │ Qwen3.5 │ │
│ └──────────┘ └──────────┘ │
│ ↓ ↓ │
│ ┌──────────┐ ┌──────────┐ │
│ │DeepSeek │→ │ 本地AI │ │
│ └──────────┘ └──────────┘ │
└─────────────────────────────────────────┘
↓
解析结果确认
↓
数据标准化
3.1.3 关键技术点
多级降级策略:
async parseDrawing(pdfFile, vlConfig) {
const strategies = [
{ name: 'Qwen3.5多模态解析', request: ... },
{ name: 'VL视觉模型解析', request: ... },
{ name: '本地文本正则解析', request: ... }
];
return await this.executeWithStrategies(strategies, options);
}
容错机制:
- 请求重试(最多3次)
- 指数退避延迟
- 超时控制(2分钟)
- 自动降级到备用模型
数据提取:
支持多种JSON格式的自动识别和转换:
- 直接键值对格式
- part_info + dimensions结构
- 尺寸信息嵌套结构
3.2 工艺路线规划模块
3.2.1 功能概述
根据零件特征自动生成加工工艺路线,支持人工调整和优化。
3.2.2 工序配置数据结构
{
name: '粗车',
equipment: '车床',
rate: 30,
equipmentDomestic: '国产通用数控车床、沈阳机床、济南二机',
equipmentImport: '日本森精机(Mori Seiki) CNC车床、德国品牌',
description: '定位基准先行:通常先加工后续工序使用的精基准面...'
}
3.2.3 工序-设备映射
| 工序名称 | 对应设备 | 费率(元/小时) |
|---|---|---|
| 下料/锯切 | 锯床 | 30 |
| 粗车/精车 | 车床 | 30/35 |
| 粗铣/精铣 | 铣床 | 30/35 |
| CNC粗加工/精加工 | CNC | 60/70 |
| 粗磨/精磨 | 平面磨 | 30/40 |
| 线切割 | 线割 | 50 |
| 钻孔 | 钻孔 | 25 |
| 热处理 | 热处理 | 40 |
| 表面处理 | 表面处理 | 30 |
| 检验 | 检验 | 20 |
3.3 工时计算模块
3.3.1 工时计算公式
车削工时:
工时 = (π × 直径 × 长度) / 切削效率 / 60 × 材料系数 × 精度系数 + 基础工时
铣削/CNC工时:
工时 = (长度 × 宽度 × 高度) / 切削效率 / 60 × 材料系数 × 精度系数 + 基础工时
磨削工时:
工时 = (长度 × 宽度) / 切削效率 / 60 × 材料系数 × 精度系数 + 基础工时
线切割工时:
工时 = ((长度 + 宽度) × 2 × 高度) / 切削效率 / 60 × 材料系数 × 精度系数 + 基础工时
3.3.2 切削效率参数
| 工序类型 | 粗加工效率 | 精加工效率 |
|---|---|---|
| 车削 | 12,000 mm²/h | 6,000 mm²/h |
| 铣削 | 20,000 mm³/h | 10,000 mm³/h |
| 平面磨 | 20,000 mm²/h | 10,000 mm²/h |
3.3.3 材料系数
| 材料类型 | 系数 | 说明 |
|---|---|---|
| 铝材 | 1.5 | 易切削,效率高 |
| 碳钢(45#, A3) | 1.0 | 基准材料 |
| 合金钢 | 0.6 | 较难切削 |
| 不锈钢 | 0.65 | 较难切削 |
| 模具钢(Cr12MoV, H13) | 0.5 | 难切削 |
| 铜材 | 1.2 | 易切削 |
3.3.4 精度系数
| 精度等级 | 系数 |
|---|---|
| 粗加工 | 1.0 |
| 精加工 | 1.3 |
| 超精加工 | 1.8 |
3.4 报价计算模块
3.4.1 报价构成
最终报价 = (工件费用 + 外购件 + 包装 + 运输 + 设计 + 装配)
× (1 + 管理费率) × (1 + 税率)
3.4.2 工件费用明细
工件费用 = 材料费 + 加工费 + 热处理费 + 表面处理费
其中:
- 材料费 = 毛坯重量 × 材料单价 - 废料重量 × 退料单价
- 加工费 = Σ(工序工时 × 设备费率)
- 热处理费 = 重量 × 热处理费率
- 表面处理费 = 面积 × 表面处理费率
3.4.3 报价策略
| 策略ID | 策略名称 | 管理费率 | 利润率 | 适用场景 |
|---|---|---|---|---|
| standard | 标准报价策略 | 12% | 18% | 常规项目 |
| competitive | 竞争报价策略 | 10% | 12% | 竞争激烈项目 |
| premium | 高端报价策略 | 18% | 25% | 高精度/高难度项目 |
| batch | 批量报价策略 | 8% | 10% | 批量生产 |
3.5 工时标定模块
3.5.1 功能概述
通过实测数据对工时计算公式进行参数拟合和优化,提高计算准确性。
3.5.2 最小二乘法拟合
线性模型:
实际工时 = a × 加工面积 + b
其中:
- a = 1 / (切削效率 / 60)
- b = 基础工时
拟合算法:
leastSquaresFitting(data) {
const n = data.length;
let sumX = 0, sumY = 0, sumXY = 0, sumX2 = 0;
for (let i = 0; i < n; i++) {
const x = data[i].processingArea;
const y = data[i].actualHours;
sumX += x;
sumY += y;
sumXY += x * y;
sumX2 += x * x;
}
const denominator = n * sumX2 - sumX * sumX;
const a = (n * sumXY - sumX * sumY) / denominator;
const b = (sumY - a * sumX) / n;
return {
cuttingEfficiency: a > 0 ? 1 / a * 60 : 0,
baseHours: Math.max(0, b),
mae, rmse, rSquared
};
}
3.5.3 评估指标
| 指标 | 计算公式 | 说明 |
|---|---|---|
| MAE | Σ|实际-预测| / n | 平均绝对误差 |
| RMSE | √(Σ(实际-预测)² / n) | 均方根误差 |
| R² | 1 - Σ(实际-预测)² / Σ(实际-均值)² | 决定系数 |
4. 数据流设计
4.1 完整业务流程
┌─────────────────────────────────────────────────────────────────┐
│ 1. 图纸解析阶段 │
├─────────────────────────────────────────────────────────────────┤
│ 上传PDF/CAD → 预览图纸 → AI智能识别 → 解析结果确认 │
│ ↓ │
│ 提取零件信息: │
│ - 零件名称、图号 │
│ - 材质、尺寸 │
│ - 数量、公差 │
└─────────────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────────────┐
│ 2. 工艺规划阶段 │
├─────────────────────────────────────────────────────────────────┤
│ 零件特征分析 → 自动规划工艺路线 → 人工调整优化 → 确认路线 │
│ ↓ │
│ 生成工序序列: │
│ [下料 → 粗车 → 粗铣 → 热处理 → 精车 → ...] │
└─────────────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────────────┐
│ 3. 工时估算阶段 │
├─────────────────────────────────────────────────────────────────┤
│ 工序参数配置 → 公式计算工时 → 对标定数据 → 调整修正 │
│ ↓ │
│ 输出各工序工时: │
│ - 车削:0.5h │
│ - 铣削:1.2h │
│ - ... │
└─────────────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────────────┐
│ 4. 报价计算阶段 │
├─────────────────────────────────────────────────────────────────┤
│ 材料成本计算 → 加工成本计算 → 其他费用 → 应用策略 → 最终报价 │
│ ↓ │
│ 成本构成明细: │
│ - 材料费:¥XXX │
│ - 加工费:¥XXX │
│ - 热处理:¥XXX │
│ - 管理费、税费... │
└─────────────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────────────┐
│ 5. 输出阶段 │
├─────────────────────────────────────────────────────────────────┤
│ 生成报价单 → 导出PDF/Excel → 保存历史 → 打印/发送 │
└─────────────────────────────────────────────────────────────────┘
4.2 状态数据结构
AppState.data = {
// 工件列表
workpieces: [
{
id: string,
number: string,
name: string,
material: string,
length: number,
width: number,
height: number,
diameter: number,
weight: number,
quantity: number,
processes: [
{ name: string, hours: number, equipment: string, price: number }
],
materialCost: number,
processingCost: number,
heatTreatmentCost: number,
surfaceTreatmentCost: number
}
],
// 系统配置
config: {
materials: [
{ name: string, type: string, density: number, price: number, heatTreatment: string, hardness: string }
],
operations: [
{ name: string, equipment: string, rate: number, equipmentDomestic: string, equipmentImport: string, description: string }
],
terms: [
{ term: string, description: string }
]
},
// 工时标定数据
calibrationData: [
{
id: string,
processType: string,
material: string,
length: number,
width: number,
height: number,
diameter: number,
precision: string,
actualHours: number,
calculatedHours: number,
error: number,
errorRate: number,
date: string,
operator: string
}
],
// 报价策略
quotationStrategies: [
{ id: string, name: string, managementRate: number, profitRate: number, description: string, enabled: boolean }
],
// VL模型配置
vlConfig: {
apiKey: string,
apiUrl: string,
useProxy: boolean
}
};
5. 关键技术实现
5.1 PDF转图片优化
问题与解决方案
- 内存占用过高:限制PDF文件大小(3MB),降低缩放比例(0.7倍)
- 画布空白问题:检测画布内容,确保有内容才继续
- 内存泄漏:及时释放URL对象,强制垃圾回收
async convertPDFToImage(pdfFile) {
const url = URL.createObjectURL(pdfFile);
try {
if (pdfFile.size > 3 * 1024 * 1024) {
throw new Error('PDF文件大小超过限制(3MB)');
}
const pdfData = await pdfjsLib.getDocument({ ... }).promise;
const page = await pdfData.getPage(1);
const viewport = page.getViewport({ scale: 0.7 });
const canvas = document.createElement('canvas');
const context = canvas.getContext('2d');
await page.render({ canvasContext: context, viewport }).promise;
// 检查画布内容
const imageData = context.getImageData(0, 0, canvas.width, canvas.height);
let hasContent = false;
for (let i = 0; i < imageData.data.length; i += 4) {
if (imageData.data[i] !== 255 || imageData.data[i+1] !== 255 ||
imageData.data[i+2] !== 255 || imageData.data[i+3] !== 255) {
hasContent = true;
break;
}
}
if (!hasContent) {
throw new Error('PDF转图片失败:生成的图片为空白');
}
return canvas.toDataURL('image/jpeg', 0.6).split(',')[1];
} finally {
URL.revokeObjectURL(url);
if (typeof window.gc === 'function') {
window.gc();
}
}
}
5.2 数据标准化
材质名称标准化
const MATERIAL_NAME_MAPPING = {
'45': '45#', '45号': '45#', '45号钢': '45#',
'A3': 'A3', 'Q235': 'A3', 'Q235A': 'A3',
'SUS304': 'SUS304', '304': 'SUS304',
'CR12MOV': 'Cr12MoV', 'CR12': 'Cr12MoV',
// ... 更多映射
};
function normalizeMaterialName(material) {
const normalized = material.trim().replace(/[\s\-_]/g, '').toUpperCase();
if (MATERIAL_NAME_MAPPING[normalized]) {
return MATERIAL_NAME_MAPPING[normalized];
}
// 尝试模糊匹配
for (const [key, value] of Object.entries(MATERIAL_NAME_MAPPING)) {
if (normalized.includes(key) || key.includes(normalized)) {
return value;
}
}
return material;
}
尺寸字段标准化
const DIMENSION_FIELD_MAPPING = {
'length': 'length', '长': 'length', '长度': 'length', '总长': 'length',
'width': 'width', '宽': 'width', '宽度': 'width',
'height': 'height', '高': 'height', '高度': 'height', '厚度': 'height',
'diameter': 'diameter', '直径': 'diameter', 'D': 'diameter', 'Φ': 'diameter'
};
5.3 起步价保护
为确保最低利润,设置加工费起步价:
calculateProcessingCost(processes) {
let totalCost = 0;
let hasMachining = false;
for (const process of processes) {
const rate = this.EQUIPMENT_RATES[process.equipment] || 60;
totalCost += process.hours * rate;
if (['车床', '铣床', 'CNC', '加工中心', '平面磨', '外圆磨', '线割', '钻孔'].includes(process.equipment)) {
hasMachining = true;
}
}
// 起步价保护
if (hasMachining && totalCost < this.MINIMUM_PROCESSING_COST) {
totalCost = this.MINIMUM_PROCESSING_COST; // 18元
}
return totalCost;
}
6. 数据库设计
6.1 材料数据库
| 字段 | 类型 | 说明 | 示例 |
|---|---|---|---|
| name | string | 材料名称 | 45#, Cr12MoV |
| tp | string | 材料类型 | 软料/硬料/不锈钢 |
| den | number | 密度(kg/mm³) | 7.85e-6 |
| price | number | 单价(元/kg) | 8.5 |
| ht | string | 热处理要求 | 淬火+回火 |
| hrc | string | 硬度范围 | HRC28-32 |
6.2 工序数据库
| 字段 | 类型 | 说明 |
|---|---|---|
| name | string | 工序名称 |
| equipment | string | 设备类型 |
| rate | number | 设备费率(元/小时) |
| equipmentDomestic | string | 国产设备说明 |
| equipmentImport | string | 进口设备说明 |
| description | string | 工序描述 |
6.3 定额数据库(C类零件)
包含标准零件的定额信息,支持快速查询和导入。
7. UI/UX设计
7.1 界面布局
┌─────────────────────────────────────────────────────────────┐
│ 模具附图报价系统 [快捷键] [系统] [关于] │
├─────────────────────────────────────────────────────────────┤
│ [图纸解析] [工时简版] [工时复杂版] [报价计算] [零件管理] │
│ [定额查询] [工时标定] [报价策略] [系统配置] │
├─────────────────────────────────────────────────────────────┤
│ │
│ 主要内容区域 │
│ (标签页内容) │
│ │
└─────────────────────────────────────────────────────────────┘
7.2 标签页功能
| 标签页 | 主要功能 |
|---|---|
| 图纸解析 | 上传PDF/CAD,AI解析,结果确认 |
| 工时计算简版 | 快速工艺规划,简单工时估算 |
| 工时计算复杂版 | 详细工艺规划,精确工时计算 |
| 报价计算 | 工件清单,费用计算,报价生成 |
| 零件管理 | 零件记录,外购件管理 |
| 定额查询 | C类零件定额快速查询 |
| 工时标定 | 实测数据录入,参数拟合 |
| 报价策略 | 策略管理,策略对比 |
| 系统配置 | 材料配置,工序配置,术语配置 |
8. 安全与性能
8.1 安全考虑
-
API密钥管理
- 存储在localStorage中
- 支持代理服务器中转
- 不在日志中输出密钥
-
输入验证
- 数字输入范围校验
- 必填字段验证
- JSON解析安全防护
8.2 性能优化
-
内存管理
- 及时释放Canvas资源
- 限制PDF文件大小
- 监控内存使用情况
-
网络请求
- 请求重试机制
- 超时控制
- 多级降级策略
-
渲染优化
- 虚拟滚动(大数据列表)
- 懒加载
- 防抖/节流
9. 扩展与维护
9.1 可扩展点
-
新增AI模型
- 在ai-handler.js中添加新的解析策略
- 实现parseWithXXX方法
- 加入到strategies数组
-
新增报价策略
- 在state.js中添加策略配置
- 支持动态添加/编辑策略
-
新增工序类型
- 在系统配置中添加工序
- 在calculator.js中添加工时计算方法
- 在calibration.js中添加标定支持
9.2 测试文件
项目包含多个测试文件用于功能验证:
| 测试文件 | 测试内容 |
|---|---|
| test-calculation.js | 计算器模块测试 |
| test-complete-flow.js | 完整流程测试 |
| test-edit-workpiece.js | 工件编辑测试 |
| test-material-matching.js | 材料匹配测试 |
| test-operation-config.js | 工序配置测试 |
| test-parse-flow.js | 解析流程测试 |
| test-process-route-flow.js | 工艺路线测试 |
| test-quota-to-quotation.js | 定额转报价测试 |
10. 总结
10.1 项目亮点
- AI驱动:集成多种AI模型,智能识别图纸信息
- 算法精准:基于数学模型的工时计算,支持参数标定优化
- 策略灵活:多种报价策略,支持对比和推荐
- 数据完善:内置丰富的材料、工序、定额数据库
- 体验友好:清晰的界面设计,流畅的操作流程
10.2 技术价值
- 效率提升:将传统数小时的报价工作缩短至分钟级
- 准确性提高:基于科学计算和实测数据,减少人为误差
- 知识沉淀:将专家经验固化为系统规则和算法
- 数据驱动:支持数据积累和持续优化
10.3 应用前景
该系统适用于:
- 机械制造企业
- 模具加工厂
- 钣金加工厂
- 机加工车间
- 报价工程师团队
通过持续的数据积累和算法优化,系统的准确性将不断提高,为企业创造更大的价值。
附录
A. 核心文件清单
| 文件 | 行数 | 主要功能 |
|---|---|---|
| main.js | 40KB+ | 主业务逻辑 |
| state.js | 457行 | 状态管理 |
| calculator.js | 597行 | 计算器模块 |
| ai-handler.js | 824行 | AI处理 |
| ui.js | 40KB+ | UI交互 |
| calibration.js | 392行 | 工时标定 |
| strategy.js | 301行 | 报价策略 |
| pricing-data.js | 200+行 | 定价数据 |
B. 依赖项
{
"devDependencies": {
"electron": "40.8.1",
"electron-builder": "^24.0.0"
}
}
C. 构建配置
{
"build": {
"appId": "com.mold.quotation",
"productName": "模具附图报价系统",
"electronVersion": "40.8.1",
"win": {
"target": "nsis"
},
"directories": {
"output": "../edev"
}
}
}
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐

所有评论(0)