CRM 销售报价单 AI OCR 识别 - 前端联调方案
涉及页面
saleQuotation/index.vue — 报价单列表页,新增"AI 识别录入"按钮
saleQuotation/form.vue — 报价单新增/编辑弹窗,接收 OCR 识别结果预填表单
业务流程与数据带入
- 报价单列表页 → 点击"AI 识别录入"按钮 → 弹出上传弹窗
- 上传弹窗中:选择文件上传 → 调用
/admin-api/system/storage-blob/upload → 获得 blobId
- 调用
/admin-api/crm/sale-quotation/ai/ocr 传入 blobId → 获得识别结果
- 预览识别结果 → 用户点击"确认并填入表单" → 关闭上传弹窗 → 打开新增报价单弹窗
- 新增弹窗中:识别结果预填到对应字段,用户补充完善后保存
API
| 方法 |
路径 |
说明 |
| POST |
/admin-api/crm/sale-quotation/ai/ocr |
AI OCR 识别报价文件 |
请求参数:
| 参数 |
类型 |
必填 |
说明 |
| blobId |
Long |
是 |
已上传文件的 blob ID(通过 /admin-api/system/storage-blob/upload 获取) |
响应字段:
| 字段 |
类型 |
说明 |
| name |
String |
报价单名称 |
| customerName |
String |
客户名称(文本,需用户手动匹配 CRM 客户) |
| quotationTime |
String (LocalDate) |
报价日期,格式 yyyy-MM-dd |
| validUntil |
String (LocalDate) |
有效期至,格式 yyyy-MM-dd |
| taxRate |
BigDecimal |
税率(百分比),如 13.0 |
| discountPercent |
BigDecimal |
折扣率(百分比),如 5.0 |
| remark |
String |
备注 |
| items |
Array<Item> |
物料明细列表 |
| items[].itemName |
String |
物料名称(文本,需用户在 MdmItemSelect 中匹配) |
| items[].itemSpec |
String |
物料规格型号 |
| items[].count |
BigDecimal |
数量 |
| items[].quotationPrice |
BigDecimal |
单价 |
| rawText |
String |
原始识别文本,前端可选展示用于调试/参考 |
所有字段均为可选,AI 未识别到的字段为 null。
响应示例:
{
"code": 0,
"data": {
"name": "XX公司报价单",
"customerName": "XX科技有限公司",
"quotationTime": "2026-07-31",
"validUntil": "2026-08-30",
"taxRate": 13.0,
"discountPercent": 5.0,
"remark": "含税含运费",
"items": [
{
"itemName": "伺服电机",
"itemSpec": "SV-1000W",
"count": 10,
"quotationPrice": 1500.00
}
],
"rawText": "原始文件内容..."
}
}
错误情况(HTTP 200,所有字段为 null,rawText 中包含错误提示):
| rawText 值 |
场景 |
| 文件不存在 |
blobId 无效 |
| 不支持的文件类型,请上传 PDF/Word/Excel/图片文件 |
文件后缀不在白名单内 |
| 文件读取失败 |
文件下载失败 |
| 文件内容为空,无法识别 |
文件解析出空内容 |
| AI 识别暂时不可用,请手动录入 |
AI 服务异常 |
支持的文件类型
| 类型 |
后缀 |
| PDF |
.pdf |
| Word |
.doc, .docx |
| Excel |
.xls, .xlsx |
| 图片 |
.png, .jpg, .jpeg, .gif, .bmp |
| 纯文本 |
.txt, .csv |
数据填入规则
| OCR 字段 |
填入新增表单字段 |
说明 |
| name |
报价单名称 |
直接填入 |
| customerName |
客户名称(文本展示) |
不自动匹配 CRM 客户,用户需手动通过 CrmCustomerSelect 选择 |
| quotationTime |
报价日期 |
直接填入日期选择器 |
| validUntil |
有效期至 |
直接填入日期选择器 |
| taxRate |
税率 |
直接填入,单位为百分比 |
| discountPercent |
折扣率 |
直接填入,单位为百分比 |
| remark |
备注 |
直接填入 |
| items[].itemName + itemSpec |
物料明细行 |
填入物料名称和规格文本,用户需在 MdmItemSelect 中手动匹配实际物料 |
| items[].count |
物料明细行 - 数量 |
直接填入 |
| items[].quotationPrice |
物料明细行 - 单价 |
直接填入 |
业务规则说明
| 场景 |
规则 |
| AI 识别结果全为 null |
弹窗提示"未识别到报价数据",用户可手动录入或重新上传 |
| 部分字段识别成功 |
预填已有字段,缺失字段留空由用户手动填写 |
| 识别到多个物料但用户只需部分 |
用户在新增弹窗中增删调整物料行 |
| 客户名称无法匹配 CRM 客户 |
用户通过 CrmCustomerSelect 搜索并选择正确的客户 |
注意事项
- 文件上传使用现有的
/admin-api/system/storage-blob/upload 接口,不要使用 /infra/file/upload
- 文件大小限制由 system 模块的 storage-blob 上传接口控制
- AI OCR 识别可能需要几秒时间,前端需显示 loading 状态
customerName 是纯文本,前端不要尝试自动匹配,需要用户通过 CrmCustomerSelect 手动选择
itemName 同理,用户需在 MdmItemSelect 中搜索物料编码/名称来匹配实际物料
- 识别结果中的日期格式为
yyyy-MM-dd,直接可用于日期选择器
- 当 rawText 中包含错误提示(如"文件不存在")时,前端应展示错误信息,不要继续填入表单流程