# OCR 识别接口文档 ## 接口概述 本接口提供阿里云 OCR(Optical Character Recognition,光学字符识别)服务,支持多种证件和文档的智能识别,包括身份证、营业执照、食品经营许可证等。 **接口路径**: `POST /ali/ocrRequestUrl` **接口描述**: 调用阿里云 OCR 识别服务,支持批量图片识别 **请求方式**: POST **Content-Type**: application/json **登录验证**: ✅ 需要 --- ## 请求参数 ### 请求体 (JSON) | 参数名 | 类型 | 必填 | 说明 | 示例值 | |--------|------|------|------|--------| | imageUrls | String | 是 | 图片URL地址,多个用逗号分隔 | `https://example.com/image1.jpg,https://example.com/image2.jpg` | | ocrType | String | 是 | OCR识别类型 | `idCard`, `businessLicense`, `foodLicense` | | storeId | String | 否 | 店铺ID(用于记录识别来源) | `103` | | userId | String | 否 | 用户ID(用于记录识别来源) | `12345` | | storeUserId | String | 否 | 店铺用户ID(用于记录识别来源) | `67890` | ### OCR 类型说明 | ocrType 值 | 识别类型 | 说明 | |-----------|----------|------| | `idCard` | 身份证识别 | 识别身份证正反面信息 | | `businessLicense` | 营业执照识别 | 识别营业执照信息 | | `foodLicense` | 食品经营许可证识别 | 识别食品经营许可证信息 | --- ## 请求示例 ### 示例 1: 身份证识别(单张) ```http POST /ali/ocrRequestUrl Content-Type: application/json { "imageUrls": "https://example.com/idcard-front.jpg", "ocrType": "idCard", "storeId": "103", "userId": "12345", "storeUserId": "67890" } ``` ```bash curl -X POST "http://localhost:8080/ali/ocrRequestUrl" \ -H "Content-Type: application/json" \ -H "Authorization: Bearer YOUR_TOKEN" \ -d '{ "imageUrls": "https://example.com/idcard-front.jpg", "ocrType": "idCard", "storeId": "103" }' ``` --- ### 示例 2: 营业执照识别(批量) ```http POST /ali/ocrRequestUrl Content-Type: application/json { "imageUrls": "https://example.com/license1.jpg,https://example.com/license2.jpg", "ocrType": "businessLicense", "storeId": "103", "storeUserId": "67890" } ``` --- ### 示例 3: 食品经营许可证识别 ```http POST /ali/ocrRequestUrl Content-Type: application/json { "imageUrls": "https://example.com/food-license.jpg", "ocrType": "foodLicense", "storeId": "103" } ``` --- ## 响应参数 ### 成功响应 #### 响应结构 ```json { "code": 200, "success": true, "data": [ { // OCR识别结果(根据不同类型返回不同字段) } ], "msg": "操作成功" } ``` --- ### 身份证识别响应字段 ```json { "code": 200, "success": true, "data": [ { "name": "张三", "gender": "男", "nationality": "汉", "birthDate": "19900101", "address": "北京市朝阳区XX街道XX号", "idNumber": "110101199001011234", "issueAuthority": "北京市公安局朝阳分局", "validDate": "2020.01.01-2030.01.01" } ], "msg": "操作成功" } ``` #### 字段说明 | 字段名 | 类型 | 说明 | |--------|------|------| | name | String | 姓名 | | gender | String | 性别 | | nationality | String | 民族 | | birthDate | String | 出生日期(格式:yyyyMMdd) | | address | String | 地址 | | idNumber | String | 身份证号码 | | issueAuthority | String | 签发机关(反面) | | validDate | String | 有效期限(反面) | --- ### 营业执照识别响应字段 ```json { "code": 200, "success": true, "data": [ { "name": "北京XX科技有限公司", "creditCode": "91110000MA01ABC123", "legalPerson": "李四", "address": "北京市海淀区XX路XX号", "registerDate": "2020-01-01", "registerCapital": "100万元人民币", "businessScope": "技术开发、技术咨询...", "validPeriod": "2020-01-01至2040-01-01", "type": "有限责任公司", "establishDate": "2020-01-01" } ], "msg": "操作成功" } ``` #### 字段说明 | 字段名 | 类型 | 说明 | |--------|------|------| | name | String | 企业名称 | | creditCode | String | 统一社会信用代码 | | legalPerson | String | 法定代表人 | | address | String | 注册地址 | | registerDate | String | 注册日期 | | registerCapital | String | 注册资本 | | businessScope | String | 经营范围 | | validPeriod | String | 营业期限 | | type | String | 企业类型 | | establishDate | String | 成立日期 | --- ### 食品经营许可证识别响应字段 ```json { "code": 200, "success": true, "data": [ { "licenseName": "食品经营许可证", "businessLicenseName": "北京XX餐饮有限公司", "businessAddress": "北京市朝阳区XX街XX号", "legalPerson": "王五", "creditCode": "91110000MA01XYZ456", "businessItem": "热食类食品制售", "licenseNumber": "JY11234567890123", "validPeriod": "2020-01-01至2025-01-01", "issueDate": "2020-01-01", "issueAuthority": "北京市朝阳区市场监督管理局" } ], "msg": "操作成功" } ``` #### 字段说明 | 字段名 | 类型 | 说明 | |--------|------|------| | licenseName | String | 许可证名称 | | businessLicenseName | String | 经营者名称 | | businessAddress | String | 经营场所 | | legalPerson | String | 法定代表人(负责人) | | creditCode | String | 社会信用代码 | | businessItem | String | 经营项目 | | licenseNumber | String | 许可证编号 | | validPeriod | String | 有效期限 | | issueDate | String | 发证日期 | | issueAuthority | String | 发证机关 | --- ### 失败响应 ```json { "code": 500, "success": false, "data": null, "msg": "身份证识别失败" // 或其他错误信息 } ``` #### 常见错误信息 | 错误信息 | 原因 | 解决方案 | |---------|------|---------| | OCR识别返回结果为空 | 图片质量差或格式错误 | 上传清晰的图片 | | 身份证识别失败 | 图片不是身份证或无法识别 | 检查图片内容 | | 营业执照识别失败 | 图片不是营业执照或无法识别 | 检查图片内容 | | 图片URL无法访问 | 图片链接失效或网络问题 | 检查图片URL | | OCR识别异常 | 系统异常或参数错误 | 检查请求参数 | --- ## 业务流程 ### 识别流程图 ``` 用户上传图片 ↓ 前端获取图片URL ↓ 调用 /ali/ocrRequestUrl 接口 ↓ 根据 ocrType 选择识别策略 ↓ 调用阿里云OCR服务 ↓ 解析识别结果 ↓ 保存识别记录到数据库 ↓ 返回识别结果 ``` ### 核心业务逻辑 1. **参数接收**: 接收图片URL列表和识别类型 2. **策略选择**: 根据 ocrType 选择对应的识别策略 3. **批量识别**: 遍历图片URL列表,逐一调用阿里云OCR 4. **结果解析**: 解析阿里云返回的JSON数据 5. **数据存储**: 保存识别结果到 `ocr_image_upload` 表 6. **结果返回**: 返回识别结果数组 --- ## 技术实现 ### 技术架构 ``` Controller层 (AliController) ↓ Service层 (AliApi) ↓ 策略模式 (OcrStrategy) ├── IdCardOcrStrategy (身份证识别) ├── BusinessLicenseOcrStrategy (营业执照识别) └── FoodManageLicenseOcrStrategy (食品许可证识别) ↓ 阿里云OCR API ``` ### 关键类说明 | 类名 | 说明 | 路径 | |------|------|------| | AliController | 控制器,接收请求 | `shop.alien.store.controller.AliController` | | AliApi | 服务类,业务逻辑 | `shop.alien.store.util.ali.AliApi` | | OcrStrategy | 策略接口 | `shop.alien.store.util.ali.ocr.OcrStrategy` | | AbstractOcrStrategy | 策略抽象类 | `shop.alien.store.util.ali.ocr.AbstractOcrStrategy` | | IdCardOcrStrategy | 身份证识别策略 | `shop.alien.store.util.ali.ocr.strategy.IdCardOcrStrategy` | | BusinessLicenseOcrStrategy | 营业执照识别策略 | `shop.alien.store.util.ali.ocr.strategy.BusinessLicenseOcrStrategy` | | FoodManageLicenseOcrStrategy | 食品许可证识别策略 | `shop.alien.store.util.ali.ocr.strategy.FoodManageLicenseOcrStrategy` | ### 核心代码 #### Controller 层 ```java @ApiOperation("调用OCR识别接口") @PostMapping("/ocrRequestUrl") public R ocrRequestUrl(@RequestBody Map params) { try { return aliApi.ocrRequestParams(params); } catch (Exception e) { return R.fail(e.getMessage()); } } ``` #### Service 层 ```java public R ocrRequestParams(Map params) throws Exception { // 根据 ocrType 获取对应的识别策略 OcrStrategy strategy = ocrStrategyFactory.getStrategy(params.get("ocrType")); // 执行识别 return strategy.recognizeParams(params); } ``` #### 策略实现(以身份证为例) ```java @Override public R recognizeParams(Map params) throws Exception { String[] imageUrls = params.get("imageUrls").split(","); JSONArray resultArray = new JSONArray(); for (String imageUrl : imageUrls) { // 创建阿里云OCR客户端 Client client = createOcrClient(); // 创建识别请求 RecognizeIdcardRequest request = new RecognizeIdcardRequest() .setUrl(imageUrl); // 调用识别接口 RecognizeIdcardResponse response = client.recognizeIdcardWithOptions( request, new RuntimeOptions()); // 解析结果 RecognizeIdcardResponseBody body = response.getBody(); JSONObject jsonObject = JSONObject.parseObject(body.getData()); // 保存识别记录 OcrImageUpload ocrImageUpload = new OcrImageUpload(); ocrImageUpload.setImageUrl(imageUrl); ocrImageUpload.setOcrResult(jsonObject.getJSONObject("data").toJSONString()); ocrImageUpload.setOcrType(OcrTypeEnum.ID_CARD.getCode()); saveOcrImage(ocrImageUpload); // 添加到结果集 resultArray.add(jsonObject.getJSONObject("data")); } return R.data(resultArray); } ``` --- ## 数据库设计 ### ocr_image_upload 表 OCR识别记录表,用于保存每次识别的结果。 | 字段名 | 类型 | 说明 | |--------|------|------| | id | INT | 主键ID | | user_id | VARCHAR | 用户ID | | store_id | VARCHAR | 店铺ID | | store_user_id | VARCHAR | 店铺用户ID | | image_url | VARCHAR | 图片URL | | ocr_result | TEXT | OCR识别结果(JSON格式) | | ocr_type | VARCHAR | OCR类型 | | create_time | DATETIME | 创建时间 | | update_time | DATETIME | 更新时间 | --- ## 配置说明 ### 阿里云 OCR 配置 在 `application.yml` 中配置阿里云 OCR 参数: ```yaml ali: ocr: accessKeyId: YOUR_ACCESS_KEY_ID accessKeySecret: YOUR_ACCESS_KEY_SECRET endpoint: ocr-api.cn-hangzhou.aliyuncs.com ``` ### 配置项说明 | 配置项 | 说明 | 示例值 | |--------|------|--------| | accessKeyId | 阿里云访问密钥ID | `LTAI4G...` | | accessKeySecret | 阿里云访问密钥Secret | `xxx...` | | endpoint | OCR服务端点 | `ocr-api.cn-hangzhou.aliyuncs.com` | --- ## 使用限制 ### 图片要求 | 项目 | 要求 | |------|------| | **格式** | JPG、PNG、BMP、PDF | | **大小** | 不超过 4MB | | **分辨率** | 建议大于 600x600 像素 | | **清晰度** | 图片清晰,无模糊、反光 | | **完整性** | 证件信息完整,无遮挡 | ### 调用限制 | 项目 | 限制 | |------|------| | **QPS限制** | 根据阿里云账户配置 | | **并发数** | 建议不超过10个并发请求 | | **批量数量** | 单次请求建议不超过5张图片 | --- ## 注意事项 ### 1. 图片URL要求 ⚠️ **图片URL必须可公网访问** ```java // ✅ 正确:公网可访问的URL "imageUrls": "https://cdn.example.com/image.jpg" // ❌ 错误:本地路径 "imageUrls": "file:///C:/Users/image.jpg" // ❌ 错误:内网地址 "imageUrls": "http://192.168.1.100/image.jpg" ``` ### 2. 批量识别建议 ⚠️ **批量识别时注意错误处理** ```java // 当前实现:遇到错误会中断整个批量 // 建议:改进为部分失败不影响其他图片识别 ``` ### 3. 数据隐私 ⚠️ **敏感信息处理** - 识别结果包含个人身份信息,需妥善保存 - 建议加密存储敏感字段 - 遵守数据保护法规 ### 4. 成本控制 ⚠️ **接口调用成本** - 阿里云OCR按调用次数计费 - 建议添加调用频率限制 - 避免重复识别相同图片 --- ## 错误处理 ### 异常类型 | 异常类型 | 说明 | 处理方式 | |---------|------|---------| | TeaException | 阿里云API异常 | 记录日志,返回友好提示 | | Exception | 通用异常 | 记录详细日志,返回错误信息 | | NullPointerException | 空指针异常 | 参数校验,防止空值 | ### 异常处理代码 ```java try { // OCR识别逻辑 } catch (TeaException error) { log.error("OCR识别失败: code={}, message={}", error.getCode(), error.getMessage()); return R.fail("身份证识别失败"); } catch (Exception error) { log.error("OCR识别异常", error); return R.fail("身份证识别异常"); } ``` --- ## 性能优化建议 ### 1. 图片预处理 ```java // 建议:上传前压缩图片 - 控制图片大小在 1MB 以内 - 分辨率调整到 1200x1200 左右 - 使用 JPG 格式(压缩率更高) ``` ### 2. 异步处理 ```java // 建议:批量识别时使用异步 @Async public CompletableFuture recognizeAsync(String imageUrl) { // 异步识别逻辑 } ``` ### 3. 缓存机制 ```java // 建议:相同图片不重复识别 @Cacheable(value = "ocrResult", key = "#imageUrl") public R recognizeWithCache(String imageUrl, String ocrType) { // 识别逻辑 } ``` --- ## 测试建议 ### 测试场景 | 测试场景 | 测试目的 | 预期结果 | |---------|---------|---------| | **正常识别** | 验证识别准确性 | 返回正确的识别结果 | | **图片模糊** | 验证容错能力 | 返回友好错误提示 | | **批量识别** | 验证批量处理 | 所有图片都能识别 | | **无效URL** | 验证参数校验 | 返回错误信息 | | **并发请求** | 验证并发安全 | 结果正确,无遗漏 | ### 测试用例 ```bash # 测试1:身份证识别 curl -X POST "http://localhost:8080/ali/ocrRequestUrl" \ -H "Content-Type: application/json" \ -d '{ "imageUrls": "https://example.com/idcard.jpg", "ocrType": "idCard", "storeId": "103" }' # 测试2:营业执照批量识别 curl -X POST "http://localhost:8080/ali/ocrRequestUrl" \ -H "Content-Type: application/json" \ -d '{ "imageUrls": "https://example.com/license1.jpg,https://example.com/license2.jpg", "ocrType": "businessLicense", "storeId": "103" }' ``` --- ## 相关接口 ### 其他 OCR 接口 | 接口路径 | 说明 | 区别 | |---------|------|------| | GET /ali/ocrRequest | OCR识别方式一 | 通过图片ID识别 | | POST /ali/ocrRequestByBase64 | OCR识别方式二 | 通过Base64编码识别 | | POST /ali/secondClient | 二手委托人识别 | 专用于二手业务 | --- ## 更新日志 ### v1.0 (2025-11-18) **初始版本**: - ✅ 支持身份证识别 - ✅ 支持营业执照识别 - ✅ 支持食品经营许可证识别 - ✅ 支持批量图片识别 - ✅ 自动保存识别记录 - ✅ 采用策略模式设计 **开发团队**:lyx --- ### v1.1 (预计) **计划功能**: - 🔜 增加图片缓存机制 - 🔜 支持异步批量识别 - 🔜 增加识别结果校验 - 🔜 优化错误处理逻辑 - 🔜 增加调用频率限制 --- ## 相关文档 - [阿里云OCR API文档](https://help.aliyun.com/document_detail/442275.html) - [身份证识别文档](https://help.aliyun.com/document_detail/442322.html) - [营业执照识别文档](https://help.aliyun.com/document_detail/442338.html) --- ## 联系方式 | 角色 | 负责内容 | 联系方式 | |------|---------|---------| | 后端开发 | 接口开发与维护 | - | | 技术负责人 | 技术方案审核 | - | | 产品经理 | 业务需求对接 | - | --- **文档版本**: v1.0 **最后更新**: 2025-11-28 **维护人员**: AI Assistant **接口状态**: ✅ 已上线