编辑 | blame | 历史 | 原始文档

CRM 销售报价单 AI OCR 识别 - 前端联调方案

涉及页面

  • saleQuotation/index.vue — 报价单列表页,新增"AI 识别录入"按钮
  • saleQuotation/form.vue — 报价单新增/编辑弹窗,接收 OCR 识别结果预填表单

业务流程与数据带入

  1. 报价单列表页 → 点击"AI 识别录入"按钮 → 弹出上传弹窗
  2. 上传弹窗中:选择文件上传 → 调用 /admin-api/system/storage-blob/upload → 获得 blobId
  3. 调用 /admin-api/crm/sale-quotation/ai/ocr 传入 blobId → 获得识别结果
  4. 预览识别结果 → 用户点击"确认并填入表单" → 关闭上传弹窗 → 打开新增报价单弹窗
  5. 新增弹窗中:识别结果预填到对应字段,用户补充完善后保存

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 中包含错误提示(如"文件不存在")时,前端应展示错误信息,不要继续填入表单流程