1.交通场景文字识别改造

This commit is contained in:
jiangtd 2026-05-31 01:05:08 +08:00
parent 0174c2bf95
commit 989fd4e612
17 changed files with 116 additions and 1336 deletions

View File

@ -1,55 +1,44 @@
package com.heyu.api.baidu.handle.traffic;
import com.heyu.api.baidu.BaiduBaseHandle;
import com.heyu.api.baidu.request.traffic.BMixedMultiVehicleRequest;
import com.heyu.api.data.annotation.CustomPath;
import com.heyu.api.data.constants.ApiConstants;
import com.heyu.api.data.utils.StringUtils;
import com.heyu.api.baidu.BaiduBaseHandle;
import com.heyu.api.baidu.request.traffic.BMixedMultiVehicleRequest;
import com.heyu.api.baidu.response.traffic.BLicensePlateResp;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
/**
* <p>
* <p>
* https://console.bce.baidu.com/support/?_=1740219852952&timestamp=1740325062124#/api?product=AI&project=%E6%96%87%E5%AD%97%E8%AF%86%E5%88%AB&parent=%E4%BA%A4%E9%80%9A%E5%9C%BA%E6%99%AFOCR&api=rest%2F2.0%2Focr%2Fv1%2Fdriving_license&method=post
* 驾驶证识别
*/
import java.util.Map;
@Component
@Slf4j
@CustomPath("unifiedValidPeriod")
public class BMixedMultiVehicleHandle extends BaiduBaseHandle<BMixedMultiVehicleRequest, BLicensePlateResp> {
@CustomPath("mixedMultiVehicle")
public class BMixedMultiVehicleHandle extends BaiduBaseHandle<BMixedMultiVehicleRequest, Map> {
@Override
public String getUri() {
return "/rest/2.0/ocr/v1/driving_license";
return "/rest/2.0/ocr/v1/mixed_multi_vehicle";
}
@Override
public String check(BMixedMultiVehicleRequest bVehicleLicenseRequest) {
if (checkNotTrueFalse(bVehicleLicenseRequest.getDetectDirection())) {
return "detectDirection 必须传 " + ApiConstants.trueOrFalse + ",false不进行图像方向自动矫正, true: 开启图像方向自动矫正功能,可对旋转 90/180/270 度的图片进行自动矫正并识别";
public String check(BMixedMultiVehicleRequest request) {
if (checkNotTrueFalse(request.getDetectDirection())) {
return "detectDirection must be one of " + ApiConstants.trueOrFalse;
}
if (checkNotFrontBack(bVehicleLicenseRequest.getUnified())) {
return "unified 必须传 " + ApiConstants.frontOrback + ",对输出字段进行归一化处理,将新/老版行驶证的“注册登记日期/注册日期”统一为”注册日期“进行输出";
if (checkNotTrueFalse(request.getUnified())) {
return "unified must be one of " + ApiConstants.trueOrFalse;
}
return checkImageUri(bVehicleLicenseRequest);
return checkImageUri(request);
}
@Override
public String getContent(BMixedMultiVehicleRequest bUnifiedValidPeriodRequest) {
StringBuffer sb = getImageContent(bUnifiedValidPeriodRequest);
if (StringUtils.isNotBlank(bUnifiedValidPeriodRequest.getDetectDirection())) {
sb.append("&detect_direction=").append(bUnifiedValidPeriodRequest.getDetectDirection());
public String getContent(BMixedMultiVehicleRequest request) {
StringBuffer sb = getImageContent(request);
if (StringUtils.isNotBlank(request.getDetectDirection())) {
sb.append("&detect_direction=").append(request.getDetectDirection());
}
if (StringUtils.isNotBlank(bUnifiedValidPeriodRequest.getUnified())) {
sb.append("&unified=").append(bUnifiedValidPeriodRequest.getUnified());
if (StringUtils.isNotBlank(request.getUnified())) {
sb.append("&unified=").append(request.getUnified());
}
return sb.toString();
}

View File

@ -25,7 +25,7 @@ public class BLicensePlateRequest extends BaiduImageUrlRequest {
* - true开启遮挡检测
* - false不开启遮挡检测
*/
private String detectComplete;
private String detectComplete = "false";
/**
@ -33,7 +33,7 @@ public class BLicensePlateRequest extends BaiduImageUrlRequest {
* - true开启PS检测
* - false不开启PS检测
*/
private String detectRisk;
private String detectRisk = "false";
}

View File

@ -17,13 +17,13 @@ public class BMixedMultiVehicleRequest extends BaiduImageUrlRequest {
* **- false默认值**不检测朝向朝向是指输入图像是正常方向逆时针旋转90/180/270度
* **- true**检测朝向
*/
private String detectDirection;
private String detectDirection = "false";
/**
* - false默认值不进行归一化处理
* - **true**对输出字段进行归一化处理将新/老版行驶证的注册登记日期/注册日期统一为注册日期进行输出
*/
private String unified;
private String unified = "false";
}

View File

@ -19,6 +19,6 @@ public class BWaybillRequest extends BaiduImageUrlRequest {
* - true需要识别隐私面单即此参数存在并填写为true的时候会增加返回隐私面单的3个字段详见下方返回参数列表
* - false不识别隐私面单
*/
private String isIdentifyVirtualWaybill;
private String isIdentifyVirtualWaybill = "false";
}

View File

@ -1,74 +1,30 @@
package com.heyu.api.controller.car;
import com.heyu.api.baidu.handle.traffic.BDriverLicenseHandle;
import com.heyu.api.baidu.request.traffic.BDriverLicenseRequest;
import com.heyu.api.controller.BaseController;
import com.heyu.api.controller.ocr.BaiduOcrResult;
import com.heyu.api.data.annotation.EbAuthentication;
import com.heyu.api.data.constants.ApiConstants;
import com.heyu.api.data.utils.MapUtils;
import com.heyu.api.data.utils.R;
import com.heyu.api.data.utils.StringUtils;
import com.heyu.api.request.car.DriverLicenseRecognizeRequest;
import com.heyu.api.resp.car.RecognizeDriverLicenseBackResp;
import com.heyu.api.resp.car.RecognizeDriverLicenseFaceResp;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.Map;
/**
* 驾驶证识别百度OCR
*
* 支持对机动车驾驶证正页及副页所有字段进行结构化识别
* 驾驶证正页证号姓名性别国籍出生日期初次领证日期准驾车型有效起始日期失效日期住址发证单位 11个字段
* 驾驶证副页姓名记录证号档案编号 4个字段
* 同时支持识别交管12123 APP 发放的电子驾驶证正页包括证号姓名性别国籍出生日期初次领证日期准驾车型有效起始日期失效日期累积记分状态档案编号生成时间当前时间条形码下编号 15个字段
*
* 百度文档https://console.bce.baidu.com/support/#/api?product=AI&project=文字识别&parent=交通场景OCR&api=rest%2F2.0%2Focr%2Fv1%2Fdriving_license&method=post
*/
@Slf4j
@RestController
@RequestMapping("/driver/license")
@SuppressWarnings("unchecked")
public class RecognizeDriverLicenseController extends BaseController {
private static final String DRIVER_LICENSE_URI = "/rest/2.0/ocr/v1/driving_license";
@Autowired
private BDriverLicenseHandle bDriverLicenseHandle;
@EbAuthentication(tencent = ApiConstants.TENCENT_AUTH)
@PostMapping("/recognize")
public R<RecognizeDriverLicenseFaceResp> recognize(DriverLicenseRecognizeRequest request) {
long start = System.currentTimeMillis();
long t1 = System.currentTimeMillis();
BDriverLicenseRequest bRequest = toBaiduRequest(request);
String checkMsg = checkRequest(bRequest);
if (!isBlank(checkMsg)) {
return R.error(checkMsg);
}
log.info("驾驶证识别-参数校验及构建请求耗时:{}ms", System.currentTimeMillis() - t1);
long t2 = System.currentTimeMillis();
Map<String, Object> data = requestBaidu(DRIVER_LICENSE_URI, getContent(bRequest));
long baiduCost = System.currentTimeMillis() - t2;
log.info("驾驶证识别-调用百度OCR接口耗时:{}ms", baiduCost);
if (data == null) {
log.info("驾驶证识别-识别失败, 耗时:{}ms", System.currentTimeMillis() - start);
return R.error("驾驶证识别失败");
}
long t3 = System.currentTimeMillis();
Object resp;
if (ApiConstants.face.equals(request.getSide())) {
resp = toFaceResp(data);
} else {
resp = toBackResp(data);
}
log.info("驾驶证识别-结果映射耗时:{}ms, side:{}", System.currentTimeMillis() - t3, request.getSide());
log.info("驾驶证识别-总耗时:{}ms, 其中第三方(百度OCR):{}ms", System.currentTimeMillis() - start, baiduCost);
return R.ok().setData(resp);
public R recognize(DriverLicenseRecognizeRequest request) {
return BaiduOcrResult.raw(bDriverLicenseHandle.handle(toBaiduRequest(request)));
}
private BDriverLicenseRequest toBaiduRequest(DriverLicenseRecognizeRequest request) {
@ -78,133 +34,9 @@ public class RecognizeDriverLicenseController extends BaseController {
}
bRequest.setImageBase64(request.getImageBase64());
bRequest.setImageUrl(request.getImageUrl());
// "face" 映射为百度API的 "front"
if (StringUtils.isNotBlank(request.getSide())) {
if (ApiConstants.face.equals(request.getSide())) {
bRequest.setDrivingLicenseSide("front");
} else {
bRequest.setDrivingLicenseSide(request.getSide());
}
bRequest.setDrivingLicenseSide(ApiConstants.face.equals(request.getSide()) ? ApiConstants.front : request.getSide());
}
return bRequest;
}
private String checkRequest(BDriverLicenseRequest request) {
if (!hasImage(request)) {
return "imageUrl和imageBase64不能同时为空";
}
if (checkNotTrueFalse(request.getDetectDirection())) {
return "detectDirection 必须传 " + ApiConstants.trueOrFalse
+ ",false默认值不检测朝向, true检测朝向";
}
if (checkNotFrontBack(request.getDrivingLicenseSide())) {
return "drivingLicenseSide 必须传 " + ApiConstants.frontOrback
+ ",front识别驾驶证正页、电子驾驶证正页, back识别驾驶证副页";
}
if (checkNotTrueFalse(request.getUnifiedValidPeriod())) {
return "unifiedValidPeriod 必须传 " + ApiConstants.trueOrFalse
+ ",false默认值不进行归一化处理, true归一化格式输出";
}
if (checkNotTrueFalse(request.getQualityWarn())) {
return "qualityWarn 必须传 " + ApiConstants.trueOrFalse
+ ",false不输出质量告警信息, true输出遮挡、不完整质量告警信息";
}
if (checkNotTrueFalse(request.getRiskWarn())) {
return "riskWarn 必须传 " + ApiConstants.trueOrFalse
+ ",false不输出风险告警信息, true开启输出驾驶正复印、翻拍、PS等告警信息";
}
return null;
}
private boolean hasImage(BDriverLicenseRequest request) {
return request != null && (!isBlank(request.getImageUrl()) || !isBlank(request.getImageBase64()));
}
private String getContent(BDriverLicenseRequest request) {
StringBuffer sb = getImageContent(request);
if (StringUtils.isNotBlank(request.getDetectDirection())) {
sb.append("&detect_direction=").append(request.getDetectDirection());
}
if (StringUtils.isNotBlank(request.getDrivingLicenseSide())) {
sb.append("&driving_license_side=").append(request.getDrivingLicenseSide());
}
if (StringUtils.isNotBlank(request.getUnifiedValidPeriod())) {
sb.append("&unified_valid_period=").append(request.getUnifiedValidPeriod());
}
if (StringUtils.isNotBlank(request.getQualityWarn())) {
sb.append("&quality_warn=").append(request.getQualityWarn());
}
if (StringUtils.isNotBlank(request.getRiskWarn())) {
sb.append("&risk_warn=").append(request.getRiskWarn());
}
return sb.toString();
}
private StringBuffer getImageContent(BDriverLicenseRequest request) {
StringBuffer sb = new StringBuffer();
if (StringUtils.isNotBlank(request.getImageBase64())) {
sb.append("&image=").append(request.getImageBase64());
}
if (StringUtils.isNotBlank(request.getImageUrl())) {
sb.append("&url=").append(request.getImageUrl());
}
return sb;
}
private boolean checkNotTrueFalse(String value) {
return !ApiConstants.trueOrFalse.contains(value);
}
private boolean checkNotFrontBack(String value) {
return !ApiConstants.frontOrback.contains(value);
}
private RecognizeDriverLicenseFaceResp toFaceResp(Map<String, Object> data) {
RecognizeDriverLicenseFaceResp resp = new RecognizeDriverLicenseFaceResp();
// 驾驶证正页 11个字段
resp.setLicenseNumber(MapUtils.getByExpr(data, "words_result.证号.words"));
resp.setName(MapUtils.getByExpr(data, "words_result.姓名.words"));
resp.setGender(MapUtils.getByExpr(data, "words_result.性别.words"));
resp.setNationality(MapUtils.getByExpr(data, "words_result.国籍.words"));
resp.setBirthDate(MapUtils.getByExpr(data, "words_result.出生日期.words"));
resp.setIssueDate(MapUtils.getByExpr(data, "words_result.初次领证日期.words"));
resp.setVehicleType(MapUtils.getByExpr(data, "words_result.准驾车型.words"));
// 电子/归一化模式返回 "有效起始日期"非归一化返回 "有效期限"
String startDate = MapUtils.getByExpr(data, "words_result.有效起始日期.words");
if (startDate == null) {
startDate = MapUtils.getByExpr(data, "words_result.有效期限.words");
}
resp.setStartDate(startDate);
// 电子/归一化模式返回 "失效日期"非归一化返回 ""
String endDate = MapUtils.getByExpr(data, "words_result.失效日期.words");
if (endDate == null) {
endDate = MapUtils.getByExpr(data, "words_result.至.words");
}
resp.setEndDate(endDate);
resp.setAddress(MapUtils.getByExpr(data, "words_result.住址.words"));
resp.setIssueUnit(MapUtils.getByExpr(data, "words_result.发证单位.words"));
// 电子驾驶证正页 额外字段
resp.setAccumulatedPoints(MapUtils.getByExpr(data, "words_result.累积记分.words"));
resp.setStatus(MapUtils.getByExpr(data, "words_result.状态.words"));
resp.setArchiveNumber(MapUtils.getByExpr(data, "words_result.档案编号.words"));
resp.setGenerateTime(MapUtils.getByExpr(data, "words_result.生成时间.words"));
resp.setCurrentTime(MapUtils.getByExpr(data, "words_result.当前时间.words"));
resp.setBarcodeNumber(MapUtils.getByExpr(data, "words_result.条形码下编号.words"));
return resp;
}
private RecognizeDriverLicenseBackResp toBackResp(Map<String, Object> data) {
RecognizeDriverLicenseBackResp resp = new RecognizeDriverLicenseBackResp();
resp.setName(MapUtils.getByExpr(data, "words_result.姓名.words"));
resp.setRecord(MapUtils.getByExpr(data, "words_result.记录.words"));
resp.setCardNumber(MapUtils.getByExpr(data, "words_result.证号.words"));
resp.setArchiveNumber(MapUtils.getByExpr(data, "words_result.档案编号.words"));
return resp;
}
}

View File

@ -1,263 +1,43 @@
package com.heyu.api.controller.car;
import com.heyu.api.baidu.handle.traffic.BVehicleLicenseHandle;
import com.heyu.api.baidu.request.traffic.BVehicleLicenseRequest;
import com.heyu.api.controller.BaseController;
import com.heyu.api.controller.ocr.BaiduOcrResult;
import com.heyu.api.data.annotation.EbAuthentication;
import com.heyu.api.data.constants.ApiConstants;
import com.heyu.api.data.utils.MapUtils;
import com.heyu.api.data.utils.R;
import com.heyu.api.data.utils.StringUtils;
import com.heyu.api.request.car.VehicleLicenseRequest;
import com.heyu.api.resp.car.RecognizeDrivingLicenseBackResp;
import com.heyu.api.resp.car.RecognizeDrivingLicenseFaceResp;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.Map;
/**
* 行驶证识别控制器
*
* <p>提供行驶证OCR识别功能基于百度云交通场景OCR接口实现</p>
* <p>支持功能</p>
* <ul>
* <li>行驶证正面识别包含号牌号码车辆类型所有人使用性质等基本信息</li>
* <li>行驶证反面识别包含核定载人数总质量检验记录等详细信息</li>
* <li>支持图片URL和Base64两种输入方式</li>
* <li>支持图像方向自动矫正质量告警等高级功能</li>
* </ul>
*
* <p>接口文档https://console.bce.baidu.com/support/#/api?product=AI&project=文字识别&parent=交通场景OCR&api=rest%2F2.0%2Focr%2Fv1%2Fvehicle_license&method=post</p>
*
* @author heyu
* @since 1.0.0
*/
@Slf4j
@RestController
@RequestMapping("/driving/license")
@SuppressWarnings("unchecked")
public class RecognizeDrivingLicenseController extends BaseController {
private static final String VEHICLE_LICENSE_URI = "/rest/2.0/ocr/v1/vehicle_license";
@Autowired
private BVehicleLicenseHandle bVehicleLicenseHandle;
/**
* 行驶证识别接口
* 支持行驶证正反面识别使用百度云OCR接口
*
* @param request 行驶证识别请求对象包含图片URL或base64编码正反面标识等参数
* @return 识别结果正面返回 {@link RecognizeDrivingLicenseFaceResp}反面返回 {@link RecognizeDrivingLicenseBackResp}
*/
@EbAuthentication(tencent = ApiConstants.TENCENT_AUTH)
@PostMapping("/recognize")
public R<Object> recognize(@RequestBody VehicleLicenseRequest request) {
long start = System.currentTimeMillis();
long t1 = System.currentTimeMillis();
BVehicleLicenseRequest bVehicleLicenseRequest = toBaiduRequest(request);
String checkMsg = checkRequest(bVehicleLicenseRequest);
if (!isBlank(checkMsg)) {
return R.error(checkMsg);
}
log.info("行驶证识别-参数校验及构建请求耗时:{}ms", System.currentTimeMillis() - t1);
long t2 = System.currentTimeMillis();
Map<String, Object> data = requestBaidu(VEHICLE_LICENSE_URI, getContent(bVehicleLicenseRequest));
long baiduCost = System.currentTimeMillis() - t2;
log.info("行驶证识别-调用百度OCR接口耗时:{}ms", baiduCost);
if (data == null) {
log.info("行驶证识别-识别失败, 耗时:{}ms", System.currentTimeMillis() - start);
return R.error("行驶证识别失败");
}
long t3 = System.currentTimeMillis();
R<Object> result = R.ok();
result.setData(toRecognizeResp(bVehicleLicenseRequest.getVehicleLicenseSide(), data));
log.info("行驶证识别-结果映射耗时:{}ms", System.currentTimeMillis() - t3);
log.info("行驶证识别-总耗时:{}ms, 其中第三方(百度OCR):{}ms", System.currentTimeMillis() - start, baiduCost);
return result;
public R recognize(@RequestBody VehicleLicenseRequest request) {
return BaiduOcrResult.raw(bVehicleLicenseHandle.handle(toBaiduRequest(request)));
}
/**
* 将前端请求对象转换为百度云请求对象
*
* @param request 前端行驶证识别请求
* @return 百度云行驶证识别请求对象
*/
private BVehicleLicenseRequest toBaiduRequest(VehicleLicenseRequest request) {
BVehicleLicenseRequest bVehicleLicenseRequest = new BVehicleLicenseRequest();
BVehicleLicenseRequest bRequest = new BVehicleLicenseRequest();
if (request == null) {
return bVehicleLicenseRequest;
return bRequest;
}
bVehicleLicenseRequest.setImageUrl(request.getImageUrl());
bVehicleLicenseRequest.setImageBase64(request.getImageBase64());
bRequest.setImageBase64(request.getImageBase64());
bRequest.setImageUrl(request.getImageUrl());
if (StringUtils.isNotBlank(request.getSide())) {
bVehicleLicenseRequest.setVehicleLicenseSide(request.getSide());
bRequest.setVehicleLicenseSide(request.getSide());
}
return bVehicleLicenseRequest;
return bRequest;
}
/**
* 校验请求参数的合法性
*
* @param request 百度云请求对象
* @return 校验通过返回null否则返回错误信息
*/
private String checkRequest(BVehicleLicenseRequest request) {
if (!hasImage(request)) {
return "imageUrl和imageBase64不能同时为空";
}
if (checkNotTrueFalse(request.getDetectDirection())) {
return "detectDirection 必须传 " + ApiConstants.trueOrFalse + ",false不进行图像方向自动矫正, true: 开启图像方向自动矫正功能,可对旋转 90/180/270 度的图片进行自动矫正并识别";
}
if (checkNotFrontBack(request.getVehicleLicenseSide())) {
return "front 必须传 " + ApiConstants.frontOrback + ",front正向 back反面";
}
if (checkNotTrueFalse(request.getUnified())) {
return "unified必须为 " + ApiConstants.trueOrFalse + ", false 不进行归一化处理, rue对输出字段进行归一化处理将新/老版行驶证的“注册登记日期/注册日期”统一为”注册日期“进行输出";
}
if (checkNotTrueFalse(request.getQualityWarn())) {
return "qualityWarn 必须为" + ApiConstants.trueOrFalse + ",false不输出质量告警信息, true : 输出行驶证遮挡、不完整质量告警信息";
}
return null;
}
/**
* 检查请求中是否包含有效的图片数据
*
* @param request 百度云请求对象
* @return 如果包含imageUrl或imageBase64则返回true
*/
private boolean hasImage(BVehicleLicenseRequest request) {
return request != null && (!isBlank(request.getImageUrl()) || !isBlank(request.getImageBase64()));
}
/**
* 构建百度云OCR接口的请求参数字符串
*
* @param request 百度云请求对象
* @return HTTP请求参数字符串
*/
private String getContent(BVehicleLicenseRequest request) {
StringBuffer sb = getImageContent(request);
if (StringUtils.isNotBlank(request.getDetectDirection())) {
sb.append("&detect_direction=").append(request.getDetectDirection());
}
if (StringUtils.isNotBlank(request.getVehicleLicenseSide())) {
sb.append("&vehicle_license_side=").append(request.getVehicleLicenseSide());
}
if (StringUtils.isNotBlank(request.getUnified())) {
sb.append("&unified=").append(request.getUnified());
}
if (StringUtils.isNotBlank(request.getQualityWarn())) {
sb.append("&quality_warn=").append(request.getQualityWarn());
}
if (StringUtils.isNotBlank(request.getRiskWarn())) {
sb.append("&risk_warn=").append(request.getRiskWarn());
}
return sb.toString();
}
/**
* 获取图片相关的请求参数
*
* @param request 百度云请求对象
* @return 包含image或url参数的StringBuffer
*/
private StringBuffer getImageContent(BVehicleLicenseRequest request) {
StringBuffer sb = new StringBuffer();
if (StringUtils.isNotBlank(request.getImageBase64())) {
sb.append("&image=").append(request.getImageBase64());
}
if (StringUtils.isNotBlank(request.getImageUrl())) {
sb.append("&url=").append(request.getImageUrl());
}
return sb;
}
/**
* 检查字符串是否不在允许的true/false范围内
*
* @param value 待检查的字符串
* @return 如果不是"true""false"返回true
*/
private boolean checkNotTrueFalse(String value) {
return !ApiConstants.trueOrFalse.contains(value);
}
/**
* 检查字符串是否不在允许的front/back范围内
*
* @param value 待检查的字符串
* @return 如果不是"front""back"返回true
*/
private boolean checkNotFrontBack(String value) {
return !ApiConstants.frontOrback.contains(value);
}
/**
* 根据正反面标识转换为对应的响应对象
*
* @param side 行驶证正反面标识front正面back反面
* @param data 百度云OCR识别的原始数据
* @return 正面返回 {@link RecognizeDrivingLicenseFaceResp}反面返回 {@link RecognizeDrivingLicenseBackResp}
*/
private Object toRecognizeResp(String side, Map<String, Object> data) {
if (ApiConstants.front.equals(side)) {
return toFaceResp(data);
}
return toBackResp(data);
}
/**
* 将百度云OCR识别结果转换为行驶证正面响应对象
*
* @param data 百度云OCR识别的原始数据
* @return 行驶证正面响应对象包含号牌号码车辆类型所有人等信息
*/
private RecognizeDrivingLicenseFaceResp toFaceResp(Map<String, Object> data) {
RecognizeDrivingLicenseFaceResp faceResp = new RecognizeDrivingLicenseFaceResp();
faceResp.setIssueDate(MapUtils.getByExpr(data, "words_result.发证日期.words"));
faceResp.setIssueAuthority(MapUtils.getByExpr(data, "words_result.发证单位.words"));
faceResp.setModel(MapUtils.getByExpr(data, "words_result.品牌型号.words"));
faceResp.setVehicleType(MapUtils.getByExpr(data, "words_result.车辆类型.words"));
faceResp.setOwner(MapUtils.getByExpr(data, "words_result.所有人.words"));
faceResp.setEngineNumber(MapUtils.getByExpr(data, "words_result.发动机号码.words"));
faceResp.setPlateNumber(MapUtils.getByExpr(data, "words_result.号牌号码.words"));
faceResp.setAddress(MapUtils.getByExpr(data, "words_result.住址.words"));
faceResp.setUseCharacter(MapUtils.getByExpr(data, "words_result.使用性质.words"));
faceResp.setVin(MapUtils.getByExpr(data, "words_result.车辆识别代号.words"));
faceResp.setRegisterDate(MapUtils.getByExpr(data, "words_result.注册日期.words"));
return faceResp;
}
/**
* 将百度云OCR识别结果转换为行驶证反面响应对象
*
* @param data 百度云OCR识别的原始数据
* @return 行驶证反面响应对象包含号牌号码核定载人数总质量等信息
*/
private RecognizeDrivingLicenseBackResp toBackResp(Map<String, Object> data) {
RecognizeDrivingLicenseBackResp backResp = new RecognizeDrivingLicenseBackResp();
backResp.setOverallDimension(MapUtils.getByExpr(data, "words_result.外廓尺寸.words"));
backResp.setInspectionRecord(MapUtils.getByExpr(data, "words_result.检验记录.words"));
backResp.setUnladenMass(MapUtils.getByExpr(data, "words_result.整备质量.words"));
backResp.setFileNumber(MapUtils.getByExpr(data, "words_result.档案编号.words"));
backResp.setTractionMass(MapUtils.getByExpr(data, "words_result.准牵引总质量.words"));
backResp.setGrossMass(MapUtils.getByExpr(data, "words_result.总质量.words"));
backResp.setPlateNumber(MapUtils.getByExpr(data, "words_result.号牌号码.words"));
backResp.setApprovedPassengerCapacity(MapUtils.getByExpr(data, "words_result.核定载人数.words"));
backResp.setEnergyType(MapUtils.getByExpr(data, "words_result.燃油类型.words"));
backResp.setApprovedLoad(MapUtils.getByExpr(data, "words_result.核定载质量.words"));
backResp.setRemark(MapUtils.getByExpr(data, "words_result.备注.words"));
backResp.setCertificateNumber(MapUtils.getByExpr(data, "words_result.证芯编号.words"));
return backResp;
}
}

View File

@ -1,93 +1,32 @@
package com.heyu.api.controller.car;
import com.heyu.api.baidu.handle.traffic.BLicensePlateHandle;
import com.heyu.api.baidu.request.traffic.BLicensePlateRequest;
import com.heyu.api.controller.BaseController;
import com.heyu.api.controller.ocr.BaiduOcrResult;
import com.heyu.api.data.annotation.EbAuthentication;
import com.heyu.api.data.annotation.NotIntercept;
import com.heyu.api.data.constants.ApiConstants;
import com.heyu.api.data.utils.MapUtils;
import com.heyu.api.data.utils.R;
import com.heyu.api.data.utils.StringUtils;
import com.heyu.api.request.car.LicensePlateRecognizeRequest;
import com.heyu.api.resp.car.RecognizeLicensePlateResp;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.List;
import java.util.Map;
/**
* 车牌识别百度OCR
*
* 支持识别中国大陆机动车蓝牌黄牌单双行绿牌大型新能源黄绿领使馆车牌警牌武警牌单双行
* 军牌单双行港澳出入境车牌农用车牌民航车牌非机动车车牌北京地区的地域编号和车牌号
* 并能同时识别图像中的多张车牌
*
* 百度文档https://console.bce.baidu.com/support/#/api?product=AI&project=文字识别&parent=交通场景OCR&api=rest%2F2.0%2Focr%2Fv1%2Flicense_plate&method=post
*/
@Slf4j
@RestController
@RequestMapping("/car/license/plate")
@NotIntercept
@SuppressWarnings("unchecked")
public class RecognizeLicensePlateController extends BaseController {
private static final String LICENSE_PLATE_URI = "/rest/2.0/ocr/v1/license_plate";
@Autowired
private BLicensePlateHandle bLicensePlateHandle;
@PostMapping("/recognize")
@EbAuthentication(tencent = ApiConstants.TENCENT_AUTH)
public R<RecognizeLicensePlateResp> recognize(@RequestBody LicensePlateRecognizeRequest request) {
long start = System.currentTimeMillis();
long t1 = System.currentTimeMillis();
BLicensePlateRequest bRequest = toBaiduRequest(request);
String checkMsg = checkRequest(bRequest);
if (!isBlank(checkMsg)) {
return R.error(checkMsg);
}
log.info("车牌识别-参数校验及构建请求耗时:{}ms", System.currentTimeMillis() - t1);
long t2 = System.currentTimeMillis();
Map<String, Object> data = requestBaidu(LICENSE_PLATE_URI, getContent(bRequest));
long baiduCost = System.currentTimeMillis() - t2;
log.info("车牌识别-调用百度OCR接口耗时:{}ms", baiduCost);
if (data == null) {
log.info("车牌识别-识别失败, 耗时:{}ms", System.currentTimeMillis() - start);
return R.error("车牌识别失败");
}
long t3 = System.currentTimeMillis();
List<Map<String, Object>> plates = MapUtils.getByExpr(data, "words_result");
if (CollectionUtils.isEmpty(plates)) {
log.info("车牌识别-未识别到车牌信息, 耗时:{}ms", System.currentTimeMillis() - start);
return R.error("未识别到车牌信息");
}
// 取第一张车牌
Map<String, Object> plate = plates.get(0);
RecognizeLicensePlateResp resp = new RecognizeLicensePlateResp();
resp.setPlateNumber((String) plate.get("number"));
resp.setPlateType(mapPlateColor((String) plate.get("color")));
// 百度返回字符级置信度列表取最小值作为整体置信度保守策略平均值作为车牌类型置信度
List<Number> probabilities = (List<Number>) plate.get("probability");
if (CollectionUtils.isNotEmpty(probabilities)) {
double minConf = probabilities.stream().mapToDouble(Number::doubleValue).min().orElse(0.0);
resp.setConfidence((float) minConf);
double avgConf = probabilities.stream().mapToDouble(Number::doubleValue).average().orElse(0.0);
resp.setPlateTypeConfidence((float) avgConf);
}
log.info("车牌识别-结果映射耗时:{}ms", System.currentTimeMillis() - t3);
log.info("车牌识别-总耗时:{}ms, 其中第三方(百度OCR):{}ms", System.currentTimeMillis() - start, baiduCost);
return R.ok().setData(resp);
public R recognize(@RequestBody LicensePlateRecognizeRequest request) {
return BaiduOcrResult.raw(bLicensePlateHandle.handle(toBaiduRequest(request)));
}
private BLicensePlateRequest toBaiduRequest(LicensePlateRecognizeRequest request) {
@ -95,108 +34,8 @@ public class RecognizeLicensePlateController extends BaseController {
if (request == null) {
return bRequest;
}
// base64编码后进行urlencode是百度API的要求因为base64的+/=在form-urlencoded中有特殊含义
if (StringUtils.isNotBlank(request.getImageBase64())) {
bRequest.setImageBase64(encodeUrl(request.getImageBase64()));
}
// imageUrl 中可能包含 & 等特殊字符需URL编码后再传给百度API否则会被解析为form分隔符
if (StringUtils.isNotBlank(request.getImageUrl())) {
bRequest.setImageUrl(encodeUrl(request.getImageUrl()));
}
// detectComplete和detectRisk在BLicensePlateRequest中无默认值下方check()要求必须为true/false
bRequest.setDetectComplete("false");
bRequest.setDetectRisk("false");
bRequest.setImageBase64(request.getImageBase64());
bRequest.setImageUrl(request.getImageUrl());
return bRequest;
}
private String checkRequest(BLicensePlateRequest request) {
if (!hasImage(request)) {
return "imageUrl和imageBase64不能同时为空";
}
if (checkNotTrueFalse(request.getMultiDetect())) {
return "multiDetect必须为true/false, 是否检测多张车牌默认为false当置为true的时候可以对一张图片内的多张车牌进行识别";
}
if (checkNotTrueFalse(request.getMultiScale())) {
return "multiScale必须为true/false, 在高拍等车牌较小的场景下可开启默认为false";
}
if (checkNotTrueFalse(request.getDetectComplete())) {
return "detectComplete必须为true/false, 是否开启车牌遮挡检测功能";
}
if (checkNotTrueFalse(request.getDetectRisk())) {
return "detectRisk必须为true/false, 是否开启车牌PS检测功能";
}
return null;
}
private boolean hasImage(BLicensePlateRequest request) {
return request != null && (!isBlank(request.getImageUrl()) || !isBlank(request.getImageBase64()));
}
private String getContent(BLicensePlateRequest request) {
StringBuffer sb = getImageContent(request);
if (StringUtils.isNotBlank(request.getMultiDetect())) {
sb.append("&multi_detect=").append(request.getMultiDetect());
}
if (StringUtils.isNotBlank(request.getMultiScale())) {
sb.append("&multi_scale=").append(request.getMultiScale());
}
if (StringUtils.isNotBlank(request.getDetectComplete())) {
sb.append("&detect_complete=").append(request.getDetectComplete());
}
if (StringUtils.isNotBlank(request.getDetectRisk())) {
sb.append("&detect_risk=").append(request.getDetectRisk());
}
return sb.toString();
}
private StringBuffer getImageContent(BLicensePlateRequest request) {
StringBuffer sb = new StringBuffer();
if (StringUtils.isNotBlank(request.getImageBase64())) {
sb.append("&image=").append(request.getImageBase64());
}
if (StringUtils.isNotBlank(request.getImageUrl())) {
sb.append("&url=").append(request.getImageUrl());
}
return sb;
}
private boolean checkNotTrueFalse(String value) {
if (value == null) {
return false;
}
return !"true".equals(value) && !"false".equals(value);
}
private String encodeUrl(String url) {
try {
return URLEncoder.encode(url, "UTF-8");
} catch (UnsupportedEncodingException e) {
log.error("URL编码失败:{}", url, e);
return url;
}
}
/**
* 将百度车牌颜色映射为中文车牌类型
*/
private String mapPlateColor(String color) {
if (color == null) {
return null;
}
switch (color.toLowerCase()) {
case "blue":
return "小型汽车";
case "green":
return "新能源车";
case "yellow":
return "大型汽车";
case "white":
return "警车";
case "black":
return "港澳车";
default:
return color;
}
}
}

View File

@ -1,132 +1,38 @@
package com.heyu.api.controller.tax;
import com.aliyun.ocr20191230.models.RecognizeVINCodeResponse;
import com.aliyun.ocr20191230.models.RecognizeVINCodeResponseBody;
import com.heyu.api.alibaba.handle.common.text.ARecognizeVINCodeHandle;
import com.heyu.api.alibaba.request.common.text.ARecognizeVINCodeRequest;
import com.heyu.api.baidu.handle.traffic.BVinCodeHandle;
import com.heyu.api.baidu.request.traffic.BVinCodeRequest;
import com.heyu.api.baidu.response.traffic.BVinCodeResp;
import com.heyu.api.controller.BaseController;
import com.heyu.api.request.tax.ARecognizeVATInvoiceReq;
import com.heyu.api.resp.tax.RecognizeVINCodeResp;
import com.heyu.api.controller.ocr.BaiduOcrResult;
import com.heyu.api.data.annotation.CacheResult;
import com.heyu.api.data.annotation.NotIntercept;
import com.heyu.api.data.utils.ApiR;
import com.heyu.api.data.utils.R;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import com.heyu.api.request.tax.ARecognizeVATInvoiceReq;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.ArrayList;
import java.util.List;
/***
*https://next.api.aliyun.com/api/ocr/2019-12-30/RecognizeVINCode?tab=DEMO&lang=JAVA
*
*
* VIN码识别
*
* RecognizeVINCode
*功能描述
*
*
*
* VIN 码识别能力可以识别车辆 VIN 输出车辆 VIN 码数值
*
*
*
*
*https://console.bce.baidu.com/support/?_=1740411162437&timestamp=1740411253251#/api?product=AI&project=%E6%96%87%E5%AD%97%E8%AF%86%E5%88%AB&parent=%E4%BA%A4%E9%80%9A%E5%9C%BA%E6%99%AFOCR&api=rest%2F2.0%2Focr%2Fv1%2Fvin_code&method=post
*
*
*
*/
@Slf4j
@RestController
@RequestMapping("/vin/invoice")
@RequestMapping({"/vin/invoice", "/vin/code"})
@NotIntercept
public class RecognizeVINCodeController extends BaseController {
@Autowired
private ARecognizeVINCodeHandle arecognizeVINCodeHandle;
@Autowired
private BVinCodeHandle bVinCodeHandle;
@RequestMapping("/recognize")
@CacheResult
public R recognize(ARecognizeVATInvoiceReq request) {
List<RecognizeVINCodeResp> respList = new ArrayList<>();
BVinCodeRequest bVinCodeRequest = new BVinCodeRequest();
bVinCodeRequest.setImageBase64(request.getImageBase64());
bVinCodeRequest.setImageUrl(request.getImageUrl());
ApiR<BVinCodeResp> bR = bVinCodeHandle.handle(bVinCodeRequest);
if (bR.isSuccess()) {
BVinCodeResp bVinCodeResp = bR.getData();
List<BVinCodeResp.WordsResultDTO> wordsResultDTOS = bVinCodeResp.getWordsResult();
if (CollectionUtils.isNotEmpty(wordsResultDTOS)) {
for (BVinCodeResp.WordsResultDTO wordsResultDTO : wordsResultDTOS) {
RecognizeVINCodeResp response = new RecognizeVINCodeResp();
response.setVinCode(wordsResultDTO.getWords());
respList.add(response);
}
}
return R.ok().setData(respList);
}
ARecognizeVINCodeRequest aRecognizeVINCodeRequest = new ARecognizeVINCodeRequest();
aRecognizeVINCodeRequest.setImageUrl(request.getImageUrl());
aRecognizeVINCodeRequest.setImageBase64(request.getImageBase64());
ApiR<RecognizeVINCodeResponse> aR = arecognizeVINCodeHandle.handle(aRecognizeVINCodeRequest);
if (aR.isSuccess() && isSuccessStatusCode(aR.getData().getStatusCode())) {
RecognizeVINCodeResponseBody responseBody = aR.getData().getBody();
RecognizeVINCodeResponseBody.RecognizeVINCodeResponseBodyData responseBodyData = responseBody.getData();
RecognizeVINCodeResp resp = new RecognizeVINCodeResp();
resp.setVinCode(responseBodyData.getVinCode());
respList.add(resp);
return R.ok().setData(respList);
}
return R.ok();
return BaiduOcrResult.raw(bVinCodeHandle.handle(toBaiduRequest(request)));
}
private BVinCodeRequest toBaiduRequest(ARecognizeVATInvoiceReq request) {
BVinCodeRequest bRequest = new BVinCodeRequest();
if (request == null) {
return bRequest;
}
bRequest.setImageBase64(request.getImageBase64());
bRequest.setImageUrl(request.getImageUrl());
return bRequest;
}
}

View File

@ -2,86 +2,26 @@ package com.heyu.api.controller.traffic;
import com.heyu.api.baidu.handle.traffic.BLicensePlateHandle;
import com.heyu.api.baidu.request.traffic.BLicensePlateRequest;
import com.heyu.api.baidu.response.traffic.BLicensePlateResp;
import com.heyu.api.controller.BaseController;
import com.heyu.api.controller.ocr.BaiduOcrResult;
import com.heyu.api.data.annotation.CacheResult;
import com.heyu.api.data.annotation.NotIntercept;
import com.heyu.api.data.utils.ApiR;
import com.heyu.api.data.utils.R;
import com.heyu.api.resp.traffic.LicensePlateResp;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.ArrayList;
import java.util.List;
/**
* https://console.bce.baidu.com/support/?_=1740219852952&timestamp=1740325926517#/api?product=AI&project=%E6%96%87%E5%AD%97%E8%AF%86%E5%88%AB&parent=%E4%BA%A4%E9%80%9A%E5%9C%BA%E6%99%AFOCR&api=rest%2F2.0%2Focr%2Fv1%2Flicense_plate&method=post
* <p>
* 车牌识别
*
*
* 接口描述
* 支持识别中国大陆机动车蓝牌黄牌单双行绿牌大型新能源黄绿领使馆车牌警牌武警牌单双行军牌单双行港澳出入境车牌
* 农用车牌民航车牌非机动车车牌北京地区的地域编号和车牌号并能同时识别图像中的多张车牌
*
*
*/
@Slf4j
@RestController
@RequestMapping("/license/plate")
@NotIntercept
public class LicensePlateController extends BaseController {
@Autowired
private BLicensePlateHandle bLicensePlateHandle;
@RequestMapping("/recognize")
@CacheResult
public R recognize(BLicensePlateRequest request) {
List<LicensePlateResp> respList = new ArrayList<>();
ApiR<BLicensePlateResp> bR = bLicensePlateHandle.handle(request);
if (bR.isSuccess()) {
BLicensePlateResp bLicensePlateResp = bR.getData();
List<BLicensePlateResp.WordsResultDTO> wordsResultDTOS = bLicensePlateResp.getWordsResult();
for (BLicensePlateResp.WordsResultDTO wordsResultDTO : wordsResultDTOS) {
LicensePlateResp licensePlateResp = new LicensePlateResp();
licensePlateResp.setColor(wordsResultDTO.getColor());
licensePlateResp.setProbability(wordsResultDTO.getProbability());
licensePlateResp.setCoverInfo(wordsResultDTO.getCoverInfo());
licensePlateResp.setNumber(wordsResultDTO.getNumber());
licensePlateResp.setEditTool(wordsResultDTO.getEditTool());
List<BLicensePlateResp.WordsResultDTO.VertexesLocationDTO> vertexesLocationDTOS = wordsResultDTO.getVertexesLocation();
if (CollectionUtils.isNotEmpty(vertexesLocationDTOS)) {
List<LicensePlateResp.VertexesLocationDTO> vertexesLocationDTOS1 = new ArrayList<>();
for (BLicensePlateResp.WordsResultDTO.VertexesLocationDTO vertexesLocationDTO : vertexesLocationDTOS) {
LicensePlateResp.VertexesLocationDTO locationDTO = new LicensePlateResp.VertexesLocationDTO();
locationDTO.setX(vertexesLocationDTO.getX());
locationDTO.setY(vertexesLocationDTO.getY());
vertexesLocationDTOS1.add(locationDTO);
}
licensePlateResp.setVertexesLocation(vertexesLocationDTOS1);
}
respList.add(licensePlateResp);
}
return R.ok().setData(respList);
}
return R.error(bR.getErrorMsg());
return BaiduOcrResult.raw(bLicensePlateHandle.handle(request));
}
}

View File

@ -0,0 +1,27 @@
package com.heyu.api.controller.traffic;
import com.heyu.api.baidu.handle.traffic.BMixedMultiVehicleHandle;
import com.heyu.api.baidu.request.traffic.BMixedMultiVehicleRequest;
import com.heyu.api.controller.BaseController;
import com.heyu.api.controller.ocr.BaiduOcrResult;
import com.heyu.api.data.annotation.CacheResult;
import com.heyu.api.data.annotation.NotIntercept;
import com.heyu.api.data.utils.R;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/mixed/multi/vehicle")
@NotIntercept
public class MixedMultiVehicleController extends BaseController {
@Autowired
private BMixedMultiVehicleHandle bMixedMultiVehicleHandle;
@RequestMapping("/recognize")
@CacheResult
public R recognize(BMixedMultiVehicleRequest request) {
return BaiduOcrResult.raw(bMixedMultiVehicleHandle.handle(request));
}
}

View File

@ -3,74 +3,25 @@ package com.heyu.api.controller.traffic;
import com.heyu.api.baidu.handle.traffic.BRoadTransportCertificateHandle;
import com.heyu.api.baidu.request.traffic.BRoadTransportCertificateRequest;
import com.heyu.api.controller.BaseController;
import com.heyu.api.controller.ocr.BaiduOcrResult;
import com.heyu.api.data.annotation.CacheResult;
import com.heyu.api.data.annotation.NotIntercept;
import com.heyu.api.data.utils.ApiR;
import com.heyu.api.data.utils.MapUtils;
import com.heyu.api.data.utils.R;
import com.heyu.api.resp.traffic.RoadTransportCertificateResp;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.Map;
/**
* https://console.bce.baidu.com/support/?_=1740411162437&timestamp=1740413029871#/api?product=AI&project=%E6%96%87%E5%AD%97%E8%AF%86%E5%88%AB&parent=%E4%BA%A4%E9%80%9A%E5%9C%BA%E6%99%AFOCR&api=rest%2F2.0%2Focr%2Fv1%2Froad_transport_certificate&method=post
* <p>
* <p>
* 道路运输证识别
*
*接口描述
* 结构化识别道路运输证的业户名称地址车辆号牌经营许可证经济类型车辆类型吨座位车辆规格经营范围初领日期备注发证日期道路运输证号等15个关键字段支持识别横版及竖版两种道路运输证
*
*/
@Slf4j
@RestController
@RequestMapping("/road/transport")
@NotIntercept
public class RoadTransportCertificateController extends BaseController {
@Autowired
private BRoadTransportCertificateHandle bRoadTransportCertificateHandle;
@RequestMapping("/recognize")
@CacheResult
public R recognize(BRoadTransportCertificateRequest request) {
RoadTransportCertificateResp resp = new RoadTransportCertificateResp();
ApiR<Map> bR = bRoadTransportCertificateHandle.handle(request);
if (bR.isSuccess()) {
Map<String, Object> data = bR.getData();
resp.setRoadTransportLicenseNumber(MapUtils.getByExpr(data, "words_result.道路运输证号.[0].word")); // 道路运输证号
resp.setVehicleLicensePlate(MapUtils.getByExpr(data, "words_result.车辆号牌.[0].word")); // 车辆号牌
resp.setEconomicType(MapUtils.getByExpr(data, "words_result.经济类型.[0].word")); //经济类型
resp.setBusinessScope(MapUtils.getByExpr(data, "words_result.经营范围.[0].word")); // 经营范围
resp.setVehicleType(MapUtils.getByExpr(data, "words_result.车辆类型.[0].word")); //车辆类型
resp.setTonsOfSeats(MapUtils.getByExpr(data, "words_result.吨座位.[0].word")); // 吨座位
resp.setRemark(MapUtils.getByExpr(data, "words_result.备注.[0].word"));//备注
resp.setBusinessLicense(MapUtils.getByExpr(data, "words_result.经营许可证.[0].word")); // 经营许可证
resp.setVehicleMMH(MapUtils.getByExpr(data, "words_result.车辆毫米_高.[0].word")); // 车辆毫米_高
resp.setVehicleMMWidth(MapUtils.getByExpr(data, "words_result.车辆毫米_宽.[0].word"));//车辆毫米_宽
resp.setCertificateIssuanceDate(MapUtils.getByExpr(data, "words_result.发证日期.[0].word")); // 发证日期
resp.setAddress(MapUtils.getByExpr(data, "words_result.地址.[0].word"));//地址
resp.setVehicleMMLength(MapUtils.getByExpr(data, "words_result.车辆毫米_长.[0].word"));// 车辆毫米_长
resp.setBusinessAccountName(MapUtils.getByExpr(data, "words_result.业户名称.[0].word")); // 业户名称
resp.setFirstDate(MapUtils.getByExpr(data, "words_result.初领日期.[0].word")); // 初领日期
return R.ok().setData(resp);
}
return R.error(bR.getErrorMsg());
return BaiduOcrResult.raw(bRoadTransportCertificateHandle.handle(request));
}
}

View File

@ -2,78 +2,26 @@ package com.heyu.api.controller.traffic;
import com.heyu.api.baidu.handle.traffic.BUsedVehicleInvoiceHandle;
import com.heyu.api.baidu.request.traffic.BUsedVehicleInvoiceRequest;
import com.heyu.api.baidu.response.traffic.BUsedVehicleInvoiceResp;
import com.heyu.api.controller.BaseController;
import com.heyu.api.controller.ocr.BaiduOcrResult;
import com.heyu.api.data.annotation.CacheResult;
import com.heyu.api.data.annotation.NotIntercept;
import com.heyu.api.data.utils.ApiR;
import com.heyu.api.data.utils.R;
import com.heyu.api.resp.traffic.UsedVehicleInvoiceResp;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* https://console.bce.baidu.com/support/?_=1740411162437&timestamp=1740411735793#/api?product=AI&project=%E6%96%87%E5%AD%97%E8%AF%86%E5%88%AB&parent=%E4%BA%A4%E9%80%9A%E5%9C%BA%E6%99%AFOCR&api=rest%2F2.0%2Focr%2Fv1%2Fused_vehicle_invoice&method=post
* 二手车销售发票识别
*
*接口描述
* 支持对二手车销售发票的25个关键字段进行结构化识别包括发票代码发票号码开票日期买方卖方车牌号车辆类型二手车市场等
*
*
*/
@Slf4j
@RestController
@RequestMapping("/used/vehicle/invoice")
@NotIntercept
public class UsedVehicleInvoiceController extends BaseController {
@Autowired
private BUsedVehicleInvoiceHandle bUsedVehicleInvoiceHandle;
@RequestMapping("/recognize")
@CacheResult
public R recognize(BUsedVehicleInvoiceRequest request) {
UsedVehicleInvoiceResp resp = new UsedVehicleInvoiceResp();
ApiR<BUsedVehicleInvoiceResp> bR = bUsedVehicleInvoiceHandle.handle(request);
if (bR.isSuccess()) {
BUsedVehicleInvoiceResp bUsedVehicleInvoiceResp = bR.getData();
BUsedVehicleInvoiceResp.WordResultDTO wordResultDTO = bUsedVehicleInvoiceResp.getWordResult();
if (wordResultDTO != null) {
resp.setTransferVehicleManagementOffice(wordResultDTO.getTransferVehicleManagementOffice().getWord()); // 转入地车管所名称
resp.setManuModel(wordResultDTO.getManuModel().getWord()); // 厂牌型号
resp.setRegistrationCode(wordResultDTO.getRegistrationCode().getWord()); //登记证号
resp.setTotalCarPriceLow(wordResultDTO.getTotalCarPriceLow().getWord()); //车价合计小写
resp.setTaxAddress(wordResultDTO.getTaxAddress().getWord()); //纳税人地址
resp.setPurchaserCode(wordResultDTO.getPurchaserCode().getWord()); // 买方身份证号
resp.setSaler(wordResultDTO.getSaler().getWord()); // 卖方
resp.setTaxCode(wordResultDTO.getTaxCode().getWord()); // 税控码
resp.setPurchaser(wordResultDTO.getPurchaser().getWord()); //买方
resp.setInvoiceCode(wordResultDTO.getInvoiceCode().getWord()); //发票代码
resp.setInvoiceDate(wordResultDTO.getInvoiceDate().getWord()); //开票日期
resp.setSalerAddress(wordResultDTO.getSalerAddress().getWord()); //卖方地址
resp.setSalerCode(wordResultDTO.getSalerCode().getWord()); //卖方身份证号
resp.setTaxPhone(wordResultDTO.getTaxPhone().getWord()); //纳税人电话
resp.setTaxNum(wordResultDTO.getTaxPhone().getWord()); //纳税人识别号
resp.setPurchaserPhone(wordResultDTO.getPurchaserPhone().getWord()); //买方电话
resp.setVehicleType(wordResultDTO.getVehicleType().getWord()); // 车辆类型
resp.setLicensePlateNum(wordResultDTO.getLicensePlateNum().getWord()); //车牌号
resp.setSheetNum(wordResultDTO.getSheetNum().getWord());//联次
resp.setVinNum(wordResultDTO.getVinNum().getWord()); //车架号
resp.setTotalCarPrice(wordResultDTO.getTotalCarPrice().getWord()); //车价合计大写
resp.setPurchaserAddress(wordResultDTO.getPurchaserAddress().getWord());
resp.setSalerPhone(wordResultDTO.getSalerPhone().getWord()); //卖方电话
resp.setUsedCarMarket(wordResultDTO.getUsedCarMarket().getWord()); //二手车市场
resp.setInvoiceNum(wordResultDTO.getInvoiceNum().getWord()); //发票号码
return R.ok().setData(resp);
}
}
return R.error(bR.getErrorMsg());
return BaiduOcrResult.raw(bUsedVehicleInvoiceHandle.handle(request));
}
}

View File

@ -2,89 +2,26 @@ package com.heyu.api.controller.traffic;
import com.heyu.api.baidu.handle.traffic.BVehicleCertificateHandle;
import com.heyu.api.baidu.request.traffic.BVehicleCertificateRequest;
import com.heyu.api.baidu.response.traffic.BVehicleCertificateResp;
import com.heyu.api.controller.BaseController;
import com.heyu.api.controller.ocr.BaiduOcrResult;
import com.heyu.api.data.annotation.CacheResult;
import com.heyu.api.data.annotation.NotIntercept;
import com.heyu.api.data.utils.ApiR;
import com.heyu.api.data.utils.R;
import com.heyu.api.resp.traffic.VehicleCertificateResp;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* https://console.bce.baidu.com/support/?_=1740411162437&timestamp=1740411968974#/api?product=AI&project=%E6%96%87%E5%AD%97%E8%AF%86%E5%88%AB&parent=%E4%BA%A4%E9%80%9A%E5%9C%BA%E6%99%AFOCR&api=rest%2F2.0%2Focr%2Fv1%2Fvehicle_certificate&method=post
* <p>
* 车辆合格证识别
*
*
* 接口描述
* 支持对车辆合格证的28个关键字段进行结构化识别包括合格证编号发证日期车辆制造企业名车辆品牌车辆名称车辆型号车架号车身颜色发动
* 机型号发动机号燃料种类排量功率排放标准轮胎数轴距轴数转向形式总质量整备质量驾驶室准乘人数最高设计车速车辆制造日期等
*
*/
@Slf4j
@RestController
@RequestMapping("/vehicle/certificate")
@NotIntercept
public class VehicleCertificateController extends BaseController {
@Autowired
private BVehicleCertificateHandle bVehicleCertificateHandle;
@RequestMapping("/recognize")
@CacheResult
public R recognize(BVehicleCertificateRequest request) {
VehicleCertificateResp resp = new VehicleCertificateResp();
ApiR<BVehicleCertificateResp> bR = bVehicleCertificateHandle.handle(request);
if (bR.isSuccess()) {
BVehicleCertificateResp bVehicleCertificateResp = bR.getData();
BVehicleCertificateResp.WordsResultDTO wordsResultDTO = bVehicleCertificateResp.getWordsResult();
resp.setManufactureDate(wordsResultDTO.getManufactureDate()); //车辆制造日期
resp.setCarColor(wordsResultDTO.getCarColor()); // 车身颜色
resp.setLimitPassenger(wordsResultDTO.getLimitPassenger()); //驾驶室准乘人数
resp.setEngineType(wordsResultDTO.getEngineType()); //发动机型号
resp.setTotalWeight(wordsResultDTO.getTotalWeight()); //总质量
resp.setPower(wordsResultDTO.getPower()); //功率
resp.setCertificationNo(wordsResultDTO.getCertificationNo()); //合格证编号
resp.setFuelType(wordsResultDTO.getFuelType()); //燃料种类
resp.setManufacturer(wordsResultDTO.getManufacturer()); // 车辆制造企业名
resp.setSteeringType(wordsResultDTO.getSteeringType()); //转向形式
resp.setWheelbase(wordsResultDTO.getWheelbase()); // 轴距
resp.setSpeedLimit(wordsResultDTO.getSpeedLimit()); //最高设计车速
resp.setEngineNo(wordsResultDTO.getEngineNo()); //发动机号
resp.setSaddleMass(wordsResultDTO.getSaddleMass()); // 轴数
resp.setAxleNum(wordsResultDTO.getAxleNum()); // 轴数
resp.setCarModel(wordsResultDTO.getCarModel()); //车辆型号
resp.setVinNo(wordsResultDTO.getVinNo()); // 车架号
resp.setCarBrand(wordsResultDTO.getCarBrand()); //车辆品牌
resp.setEmissionStandard(wordsResultDTO.getEmissionStandard()); //排放标准
resp.setDisplacement(wordsResultDTO.getDisplacement()); //排量n
resp.setCertificateDate(wordsResultDTO.getCertificateDate()); //发证日期
resp.setCarName(wordsResultDTO.getCarName()); // 车辆名称
resp.setTyreNum(wordsResultDTO.getTyreNum()); //轮胎数
resp.setChassisID(wordsResultDTO.getChassisID()); // 底盘ID
resp.setChassisModel(wordsResultDTO.getChassisModel()); //底盘型号
resp.setSeatingCapacity(wordsResultDTO.getSeatingCapacity()); //额定载客人数
resp.setQualifySeal(wordsResultDTO.getQualifySeal()); //合格印章1表示有0表示无
resp.setCGSSeal(wordsResultDTO.getCGSSeal()); //CGS印章1表示有0表示无
return R.ok().setData(resp);
}
return R.error();
return BaiduOcrResult.raw(bVehicleCertificateHandle.handle(request));
}
}

View File

@ -2,88 +2,26 @@ package com.heyu.api.controller.traffic;
import com.heyu.api.baidu.handle.traffic.BVehicleInvoiceHandle;
import com.heyu.api.baidu.request.traffic.BVehicleInvoiceRequest;
import com.heyu.api.baidu.response.traffic.BVehicleInvoiceResp;
import com.heyu.api.controller.BaseController;
import com.heyu.api.controller.ocr.BaiduOcrResult;
import com.heyu.api.data.annotation.CacheResult;
import com.heyu.api.data.annotation.NotIntercept;
import com.heyu.api.data.utils.ApiR;
import com.heyu.api.data.utils.R;
import com.heyu.api.resp.traffic.VehicleInvoiceResp;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* <p>
* <p>
* <p>
* https://console.bce.baidu.com/support/?_=1740411162437&timestamp=1740411519148#/api?product=AI&project=%E6%96%87%E5%AD%97%E8%AF%86%E5%88%AB&parent=%E4%BA%A4%E9%80%9A%E5%9C%BA%E6%99%AFOCR&api=rest%2F2.0%2Focr%2Fv1%2Fvehicle_invoice&method=post
* <p>
* 机动车销售发票识别
*
*
* 接口描述
* 支持对机动车销售发票的26个关键字段进行结构化识别包括发票代码发票号码开票日期机器编号购买方名称购买方身份证号码/组织机构代码车辆类型
* 厂牌型号产地合格证号发动机号码车架号码价税合计价税合计小写销货单位名称电话纳税人识别号账号地址开户银行税率税额
* 主管税务机关及代码不含税价格限乘人数
*
*
*
*/
@Slf4j
@RestController
@RequestMapping("/vehicle/invoice")
@NotIntercept
public class VehicleInvoiceController extends BaseController {
@Autowired
private BVehicleInvoiceHandle bVehicleInvoiceHandle;
@RequestMapping("/recognize")
@CacheResult
public R recognize(BVehicleInvoiceRequest request) {
VehicleInvoiceResp resp = new VehicleInvoiceResp();
ApiR<BVehicleInvoiceResp> bR = bVehicleInvoiceHandle.handle(request);
if (bR.isSuccess()) {
BVehicleInvoiceResp bVehicleInvoiceResp = bR.getData();
BVehicleInvoiceResp.WordsResultDTO wordsResultDTO = bVehicleInvoiceResp.getWordsResult();
resp.setInvoiceNum(wordsResultDTO.getInvoiceNum()); //发票号码/机打号码
resp.setSaler(wordsResultDTO.getSaler()); // 销货单位名称
resp.setLimitPassenger(wordsResultDTO.getLimitPassenger()); //限乘人数
resp.setMachineCode(wordsResultDTO.getMachineCode()); // 机器编号
resp.setVinNum(wordsResultDTO.getVinNum()); // 车架号码
resp.setTaxRate(wordsResultDTO.getTaxRate()); //税率
resp.setPriceTaxLow(wordsResultDTO.getPriceTaxLow()); //价税合计小写
resp.setInvoiceDate(wordsResultDTO.getInvoiceDate()); //开票日期
resp.setPrice(wordsResultDTO.getPrice()); //不含税价格
resp.setSalerBank(wordsResultDTO.getSalerBank()); //销货单位开户银行
resp.setTaxAuthor(wordsResultDTO.getTaxAuthor()); //主管税务机关
resp.setManuModel(wordsResultDTO.getManuModel()); //厂牌型号
resp.setCertificateNum(wordsResultDTO.getCertificateNum()); //合格证号
resp.setPurchaser(wordsResultDTO.getPurchaser()); //购买方名称
resp.setVehicleType(wordsResultDTO.getVehicleType()); // 车辆类型
resp.setInvoiceCode(wordsResultDTO.getInvoiceCode()); //发票代码/机打代码
resp.setPriceTax(wordsResultDTO.getPriceTax()); // 价税合计
resp.setSalerPhone(wordsResultDTO.getSalerPhone()); //销货单位电话
resp.setSalerAddress(wordsResultDTO.getSalerAddress()); // 销货单位地址
resp.setOrigin(wordsResultDTO.getOrigin()); //产地
resp.setEngineNum(wordsResultDTO.getEngineNum()); //发动机号码
resp.setTax(wordsResultDTO.getTax()); //税额
resp.setPurchaserCode(wordsResultDTO.getPurchaserCode()); //购买方身份证号码/组织机构代码
resp.setTaxAuthorCode(wordsResultDTO.getTaxAuthorCode()); // 主管税务机关代码
resp.setSalerAccountNum(wordsResultDTO.getSalerAccountNum()); //销货单位账号
resp.setSalerCode(wordsResultDTO.getSalerCode()); //销货单位纳税人识别号
return R.ok().setData(resp);
}
return R.error(bR.getErrorMsg());
return BaiduOcrResult.raw(bVehicleInvoiceHandle.handle(request));
}
}
}

View File

@ -1,69 +1,27 @@
package com.heyu.api.controller.traffic;
import com.heyu.api.baidu.handle.traffic.BVehicleRegistrationCertificateHandle;
import com.heyu.api.baidu.request.traffic.BVehicleRegistrationCertificateRequest;
import com.heyu.api.baidu.response.traffic.BVehicleRegistrationCertificateResp;
import com.heyu.api.controller.BaseController;
import com.heyu.api.controller.ocr.BaiduOcrResult;
import com.heyu.api.data.annotation.CacheResult;
import com.heyu.api.data.annotation.NotIntercept;
import com.heyu.api.data.utils.ApiR;
import com.heyu.api.data.utils.R;
import com.heyu.api.resp.traffic.VehicleRegistrationCertificateResp;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* https://console.bce.baidu.com/support/?_=1740411162437&timestamp=1740412165257#/api?product=AI&project=%E6%96%87%E5%AD%97%E8%AF%86%E5%88%AB&parent=%E4%BA%A4%E9%80%9A%E5%9C%BA%E6%99%AFOCR&api=rest%2F2.0%2Focr%2Fv1%2Fvehicle_registration_certificate&method=post
* <p>
* <p>
* 机动车登记证书识别
* <p>
* 接口描述
* 支持对机动车登记证书的15个关键字段进行结构化识别包括编号机动车所有人登记机关登记日期登记编号车辆类型等同时支持检测发证机关章
*/
@Slf4j
@RestController
@RequestMapping("/vehicle/registration/certificate")
@NotIntercept
public class VehicleRegistrationCertificateController extends BaseController {
@Autowired
private BVehicleRegistrationCertificateHandle bVehicleRegistrationCertificateHandle;
@RequestMapping("/recognize")
@CacheResult
public R recognize(BVehicleRegistrationCertificateRequest request) {
VehicleRegistrationCertificateResp resp = new VehicleRegistrationCertificateResp();
ApiR<BVehicleRegistrationCertificateResp> bR = bVehicleRegistrationCertificateHandle.handle(request);
if (bR.isSuccess()) {
BVehicleRegistrationCertificateResp bVehicleRegistrationCertificateResp = bR.getData();
BVehicleRegistrationCertificateResp.WordsResultDTO wordsResultDTO = bVehicleRegistrationCertificateResp.getWordsResult();
resp.setRegistrationAuthority(wordsResultDTO.getRegistrationAuthority().getWords()); //登记机关
resp.setVehicleModel(wordsResultDTO.getVehicleModel().getWords()); //车辆型号
resp.setVehicleType(wordsResultDTO.getVehicleType().getWords()); //车辆类型
resp.setRegistrationNum(wordsResultDTO.getRegistrationNum().getWords()); // 机动车登记编号
resp.setEngineNum(wordsResultDTO.getEngineNum().getWords()); //发动机号
resp.setNumber(wordsResultDTO.getNumber().getWords()); //编号
resp.setBodyColor(wordsResultDTO.getBodyColor().getWords()); // 车身颜色
resp.setRegistrationDate(wordsResultDTO.getRegistrationDate().getWords()); // 登记日期
resp.setDateOfProduction(wordsResultDTO.getDateOfProduction().getWords()); // 出厂日期
resp.setSeatingCapacity(wordsResultDTO.getSeatingCapacity().getWords()); // 核定载客
resp.setDateOfIssue(wordsResultDTO.getDateOfIssue().getWords()); // 发证日期
resp.setNatureOfUse(wordsResultDTO.getNatureOfUse().getWords()); // 使用性质
resp.setVin(wordsResultDTO.getVin().getWords()); // 车架号
resp.setSealOfIssueAuthority(wordsResultDTO.getSealOfIssueAuthority().getWords()); // 发证机关章1表示有0表示无
resp.setNameIdcardNo(wordsResultDTO.getNameIdcardNo().getWords()); // 机动车所有人/身份证明名称/号码
return R.ok().setData(resp);
}
return R.error(bR.getErrorMsg());
return BaiduOcrResult.raw(bVehicleRegistrationCertificateHandle.handle(request));
}
}

View File

@ -1,180 +1,27 @@
package com.heyu.api.controller.traffic;
import com.heyu.api.baidu.handle.traffic.BWaybillHandle;
import com.heyu.api.baidu.request.traffic.BWaybillRequest;
import com.heyu.api.baidu.response.traffic.BWaybillResp;
import com.heyu.api.controller.BaseController;
import com.heyu.api.controller.ocr.BaiduOcrResult;
import com.heyu.api.data.annotation.CacheResult;
import com.heyu.api.data.annotation.CustomPath;
import com.heyu.api.data.utils.ApiR;
import com.heyu.api.data.annotation.NotIntercept;
import com.heyu.api.data.utils.R;
import com.heyu.api.resp.traffic.WaybillResp;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.ArrayList;
import java.util.List;
/**
* https://console.bce.baidu.com/support/?_=1740411162437&timestamp=1740412723534#/api?product=AI&project=%E6%96%87%E5%AD%97%E8%AF%86%E5%88%AB&parent=%E4%BA%A4%E9%80%9A%E5%9C%BA%E6%99%AFOCR&api=rest%2F2.0%2Focr%2Fv1%2Fwaybill&method=post
* 快递面单识别
*
*
* 接口描述
* 支持市面上常见版式的快递面单识别包括申通/圆通/中通/百世汇通/韵达/顺丰/京东/邮政/极兔/天天等面单版式结构化识别运单号/寄件人姓名/寄件人电话/寄件人地址等字段同时支持识别隐私面单
*
*
*/
@Component
@Slf4j
@CustomPath("waybill")
@RestController
@RequestMapping("/waybill")
@NotIntercept
public class WaybillController extends BaseController {
@Autowired
private BWaybillHandle bWaybillHandle;
@RequestMapping("/recognize")
@CacheResult
public R recognize(BWaybillRequest request) {
List<WaybillResp> respList = new ArrayList<>();
ApiR<BWaybillResp> bR = bWaybillHandle.handle(request);
if (bR.isSuccess()) {
BWaybillResp bWaybillResp = bR.getData();
if (CollectionUtils.isNotEmpty(bWaybillResp.getWordsResult())) {
for (BWaybillResp.WordsResultDTO wordsResultDTO : bWaybillResp.getWordsResult()) {
WaybillResp resp = new WaybillResp();
resp.setImageInfo(wordsResultDTO.getImageInfo().getDirection()); // 图像四方向
List<String> barCode = new ArrayList<>(); //条形码
if (CollectionUtils.isNotEmpty(wordsResultDTO.getBarCode())) {
for (BWaybillResp.WordsResultDTO.BarCodeDTO barCodeDTO : wordsResultDTO.getBarCode()) {
barCode.add(barCodeDTO.getWord());
}
}
resp.setBarCode(barCode);
List<String> waybillNumber = new ArrayList<>(); //快递运单号
if (CollectionUtils.isNotEmpty(wordsResultDTO.getWaybillNumber())) {
for (BWaybillResp.WordsResultDTO.WaybillNumberDTO waybillNumberDTO : wordsResultDTO.getWaybillNumber()) {
waybillNumber.add(waybillNumberDTO.getWord());
}
}
resp.setWaybillNumber(waybillNumber);
List<String> threeSegmentCode = new ArrayList<>(); //三段码
if (CollectionUtils.isNotEmpty(wordsResultDTO.getThreeSegmentCode())) {
for (BWaybillResp.WordsResultDTO.ThreeSegmentCodeDTO threeSegmentCodeDTO : wordsResultDTO.getThreeSegmentCode()) {
threeSegmentCode.add(threeSegmentCodeDTO.getWord());
}
}
resp.setThreeSegmentCode(threeSegmentCode);
List<String> recipientName = new ArrayList<>(); //收件人姓名
if (CollectionUtils.isNotEmpty(wordsResultDTO.getRecipientName())) {
for (BWaybillResp.WordsResultDTO.RecipientNameDTO recipientNameDTO : wordsResultDTO.getRecipientName()) {
recipientName.add(recipientNameDTO.getWord());
}
}
resp.setRecipientName(recipientName);
List<String> senderName = new ArrayList<>(); //寄件人姓名
if (CollectionUtils.isNotEmpty(wordsResultDTO.getSenderName())) {
for (BWaybillResp.WordsResultDTO.SenderNameDTO senderNameDTO : wordsResultDTO.getSenderName()) {
senderName.add(senderNameDTO.getWord());
}
}
resp.setSenderName(senderName);
List<String> recipientAddr = new ArrayList<>(); //收件人地址
if (CollectionUtils.isNotEmpty(wordsResultDTO.getRecipientAddr())) {
for (BWaybillResp.WordsResultDTO.RecipientAddrDTO recipientAddrDTO : wordsResultDTO.getRecipientAddr()) {
recipientAddr.add(recipientAddrDTO.getWord());
}
}
resp.setRecipientAddr(recipientAddr);
List<String> senderAddr = new ArrayList<>(); //寄件人地址
if (CollectionUtils.isNotEmpty(wordsResultDTO.getSenderAddr())) {
for (BWaybillResp.WordsResultDTO.SenderAddrDTO senderAddrDTO : wordsResultDTO.getSenderAddr()) {
senderAddr.add(senderAddrDTO.getWord());
}
}
resp.setSenderAddr(senderAddr);
List<String> recipientPhone = new ArrayList<>(); //收件人电话
if (CollectionUtils.isNotEmpty(wordsResultDTO.getRecipientPhone())) {
for (BWaybillResp.WordsResultDTO.RecipientPhoneDTO recipientPhoneDTO : wordsResultDTO.getRecipientPhone()) {
recipientPhone.add(recipientPhoneDTO.getWord());
}
}
resp.setRecipientPhone(recipientPhone);
List<String> senderPhone = new ArrayList<>(); // 寄件人电话String
if (CollectionUtils.isNotEmpty(wordsResultDTO.getSenderPhone())) {
for (BWaybillResp.WordsResultDTO.SenderPhoneDTO senderPhoneDTO : wordsResultDTO.getSenderPhone()) {
senderPhone.add(senderPhoneDTO.getWord());
}
}
resp.setSenderPhone(senderPhone);
List<String> virtualNumber = new ArrayList<>(); //虚拟面单号当请求参数 is_identify_virtual_waybill = true 时返回该字段
if (CollectionUtils.isNotEmpty(wordsResultDTO.getVirtualNumber())) {
for (BWaybillResp.WordsResultDTO.SenderPhoneDTO senderPhoneDTO : wordsResultDTO.getVirtualNumber()) {
virtualNumber.add(senderPhoneDTO.getWord());
}
}
resp.setVirtualNumber(virtualNumber);
List<String> virtualNumberLast = new ArrayList<>(); //隐私面单的4位转接号当请求参数 is_identify_virtual_waybill = true 时返回该字段
if (CollectionUtils.isNotEmpty(wordsResultDTO.getVirtualNumberLast())) {
for (BWaybillResp.WordsResultDTO.SenderPhoneDTO senderPhoneDTO : wordsResultDTO.getVirtualNumberLast()) {
virtualNumberLast.add(senderPhoneDTO.getWord());
}
}
resp.setVirtualNumberLast(virtualNumberLast);
List<String> isVirtualWaybill = new ArrayList<>(); // 此张快递面单是否为隐私面单true代表false代表当请求参数 is_identify_virtual_waybill = true 时返回该字段
if (CollectionUtils.isNotEmpty(wordsResultDTO.getIsVirtualWaybill())) {
for (BWaybillResp.WordsResultDTO.SenderPhoneDTO senderPhoneDTO : wordsResultDTO.getIsVirtualWaybill()) {
isVirtualWaybill.add(senderPhoneDTO.getWord());
}
}
resp.setIsVirtualWaybill(isVirtualWaybill);
respList.add(resp);
}
}
return R.ok().setData(respList);
}
return R.error();
return BaiduOcrResult.raw(bWaybillHandle.handle(request));
}
}

View File

@ -2,32 +2,15 @@ package com.heyu.api.controller.traffic;
import com.heyu.api.baidu.handle.traffic.BWeightNoteHandle;
import com.heyu.api.baidu.request.traffic.BWeightNoteRequest;
import com.heyu.api.baidu.response.traffic.BWeightNoteResp;
import com.heyu.api.controller.BaseController;
import com.heyu.api.controller.ocr.BaiduOcrResult;
import com.heyu.api.data.annotation.CacheResult;
import com.heyu.api.data.annotation.NotIntercept;
import com.heyu.api.data.utils.ApiR;
import com.heyu.api.data.utils.R;
import com.heyu.api.resp.traffic.WeightNoteResp;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.ArrayList;
import java.util.List;
/***
* https://console.bce.baidu.com/support/?_=1740411162437&timestamp=1743167283288#/api?product=AI&project=%E6%96%87%E5%AD%97%E8%AF%86%E5%88%AB&parent=%E4%BA%A4%E9%80%9A%E5%9C%BA%E6%99%AFOCR&api=rest%2F2.0%2Focr%2Fv1%2Fweight_note&method=post
*
* 磅单识别
*
* 接口描述
* 结构化识别磅单的车牌号打印时间毛重皮重净重发货单位收货单位单号8个关键字段现阶段仅支持识别印刷体磅单
*/
@Slf4j
@RestController
@RequestMapping("/weight/note")
@NotIntercept
@ -39,101 +22,6 @@ public class WeightNoteController extends BaseController {
@RequestMapping("/recognize")
@CacheResult
public R recognize(BWeightNoteRequest request) {
List<WeightNoteResp> respList = new ArrayList<>();
ApiR<BWeightNoteResp> bR = bWeightNoteHandle.handle(request);
if (bR.isSuccess()) {
BWeightNoteResp bWeightNoteResp = bR.getData();
List<BWeightNoteResp.WordsResultDTO> wordsResultDTOS = bWeightNoteResp.getWordsResult();
if (CollectionUtils.isNotEmpty(wordsResultDTOS)) {
for (BWeightNoteResp.WordsResultDTO wordsResultDTO : wordsResultDTOS) {
WeightNoteResp resp = new WeightNoteResp();
List<String> tareWeight = new ArrayList<>(); //皮重
if (CollectionUtils.isNotEmpty(wordsResultDTO.getTareWeight())) {
for (BWeightNoteResp.WordsResultDTO.TareWeightDTO tareWeightDTO : wordsResultDTO.getTareWeight()) {
tareWeight.add(tareWeightDTO.getWord());
}
}
resp.setTareWeight(tareWeight);
List<String> crossWeight = new ArrayList<>(); //毛重
if (CollectionUtils.isNotEmpty(wordsResultDTO.getCrossWeight())) {
for (BWeightNoteResp.WordsResultDTO.CrossWeightDTO crossWeightDTO : wordsResultDTO.getCrossWeight()) {
crossWeight.add(crossWeightDTO.getWord());
}
}
resp.setCrossWeight(crossWeight);
List<String> plateNum = new ArrayList<>(); //车牌号
if (CollectionUtils.isNotEmpty(wordsResultDTO.getPlateNum())) {
for (BWeightNoteResp.WordsResultDTO.PlateNumDTO plateNumDTO : wordsResultDTO.getPlateNum()) {
plateNum.add(plateNumDTO.getWord());
}
}
resp.setPlateNum(plateNum);
List<String> sendingCompany = new ArrayList<>();//货单位
if (CollectionUtils.isNotEmpty(wordsResultDTO.getSendingCompany())) {
for (BWeightNoteResp.WordsResultDTO.SendingCompanyDTO sendingCompanyDTO : wordsResultDTO.getSendingCompany()) {
sendingCompany.add(sendingCompanyDTO.getWord());
}
}
resp.setSendingCompany(sendingCompany);
List<String> deliveryNumber = new ArrayList<>(); //单号
if (CollectionUtils.isNotEmpty(wordsResultDTO.getDeliveryNumber())) {
for (BWeightNoteResp.WordsResultDTO.DeliveryNumberDTO deliveryNumberDTO : wordsResultDTO.getDeliveryNumber()) {
deliveryNumber.add(deliveryNumberDTO.getWord());
}
}
resp.setDeliveryNumber(deliveryNumber);
List<String> receivingCompany = new ArrayList<>(); //收货单位
if (CollectionUtils.isNotEmpty(wordsResultDTO.getReceivingCompany())) {
for (BWeightNoteResp.WordsResultDTO.ReceivingCompanyDTO receivingCompanyDTO : wordsResultDTO.getReceivingCompany()) {
receivingCompany.add(receivingCompanyDTO.getWord());
}
}
resp.setReceivingCompany(receivingCompany);
List<String> printTime = new ArrayList<>(); //打印时间
if (CollectionUtils.isNotEmpty(wordsResultDTO.getPrintTime())) {
for (BWeightNoteResp.WordsResultDTO.PrintTimeDTO printTimeDTO : wordsResultDTO.getPrintTime()) {
printTime.add(printTimeDTO.getWord());
}
}
resp.setPrintTime(printTime);
List<String> netWeight = new ArrayList<>(); //净重
if (CollectionUtils.isNotEmpty(wordsResultDTO.getNetWeight())) {
for (BWeightNoteResp.WordsResultDTO.NetWeightDTO netWeightDTO : wordsResultDTO.getNetWeight()) {
netWeight.add(netWeightDTO.getWord());
}
}
resp.setNetWeight(netWeight);
respList.add(resp);
}
}
return R.ok().setData(respList);
}
return R.error(bR.getErrorMsg());
return BaiduOcrResult.raw(bWeightNoteHandle.handle(request));
}
}