提交修改
This commit is contained in:
parent
395e8e7d84
commit
0280372258
@ -73,32 +73,28 @@ public class RecognizeDrivingLicenseController extends AbstractRecognizeControll
|
||||
@PostMapping("/recognize")
|
||||
public R recognize(@RequestBody VehicleLicenseRequest request) {
|
||||
long start = System.currentTimeMillis();
|
||||
RecognizeContext ctx = null;
|
||||
// 入口处一次性解析:整个请求中 ImageInputUtils.validate / resolve 仅执行一次,后续主流程与 catch 块复用 ctx。
|
||||
ImageInputUtils.ValidationResult imageValidation = request != null
|
||||
? ImageInputUtils.validate(request.getImageUrlOrBase64()) : null;
|
||||
ResolvedImageInput imageInput = imageValidation != null && imageValidation.isValid()
|
||||
? imageValidation.getResolved() : null;
|
||||
String resolvedSide = request != null ? resolveVehicleLicenseSide(request) : null;
|
||||
RecognizeContext ctx = new RecognizeContext(
|
||||
resolvedSide != null ? resolvedSide : ApiConstants.front,
|
||||
imageInput,
|
||||
buildInputLogContext(request, imageInput, resolvedSide));
|
||||
try {
|
||||
// ---------- 步骤①:参数校验(不调百度、不扣费) ----------
|
||||
String validateError = validateRequest(request);
|
||||
String validateError = validateRequest(request, imageValidation, resolvedSide, ctx);
|
||||
if (validateError != null) {
|
||||
String side = request != null ? resolveVehicleLicenseSide(request) : null;
|
||||
if (side == null) {
|
||||
side = ApiConstants.front;
|
||||
}
|
||||
ResolvedImageInput validateImage = request != null
|
||||
? ImageInputUtils.resolve(request.getImageUrlOrBase64()) : null;
|
||||
log.info("行驶证识别:参数检查没通过,接口仍返回成功并附带提示(还没调识别、不扣费)。{} 返回给客户:{}",
|
||||
buildInputLogContext(request, validateImage),
|
||||
abbreviate(validateError, 120));
|
||||
return okResult(side, validateError, null);
|
||||
ctx.inputLog, abbreviate(validateError, 120));
|
||||
return okResult(ctx.side, validateError, null);
|
||||
}
|
||||
// 校验通过后 ctx.imageInput 与 ctx.side 必然有效,下文可直接使用。
|
||||
|
||||
// ---------- 步骤②:解析影像入参 & 构建上下文 ----------
|
||||
ResolvedImageInput imageInput = ImageInputUtils.resolve(request.getImageUrlOrBase64());
|
||||
ctx = new RecognizeContext(
|
||||
resolveVehicleLicenseSide(request),
|
||||
imageInput,
|
||||
buildInputLogContext(request, imageInput));
|
||||
|
||||
// ---------- 步骤③:组装百度 API 请求体 ----------
|
||||
String content = buildRequestContent(imageInput, ctx.side);
|
||||
// ---------- 步骤②:组装百度 API 请求体 ----------
|
||||
String content = buildRequestContent(ctx.imageInput, ctx.side);
|
||||
if (isBlank(content)) {
|
||||
log.error("行驶证识别:组装请求失败,请求里没带有效图片。识别{},{}。{}",
|
||||
sideDesc(ctx.side), ctx.imageInput.getType().getDesc(), ctx.inputLog);
|
||||
@ -106,44 +102,39 @@ public class RecognizeDrivingLicenseController extends AbstractRecognizeControll
|
||||
"报文组装异常",
|
||||
"识别请求体在序列化后未包含任何影像载荷,平台侧无法受理本次识别",
|
||||
"请核对 imageUrlOrBase64 是否非空且为有效 Base64 或 HTTP(S) 链接",
|
||||
"目标页面=" + sideLabel(ctx.side) + ",影像模式=" + ctx.imageInput.getType().name()
|
||||
locator(ctx)
|
||||
), null);
|
||||
}
|
||||
|
||||
// ---------- 步骤④:调用百度平台识别 ----------
|
||||
// ---------- 步骤③:调用百度平台识别 ----------
|
||||
Map<String, Object> platformResult = callPlatform(content, ctx);
|
||||
if (platformResult == null) {
|
||||
return okResult(ctx.side, formatHint(
|
||||
"服务无回执",
|
||||
"识别指令已下发,但在约定时间内未收到平台可解析的 JSON 回执",
|
||||
"建议间隔 3~5 秒重试;若连续失败,请记录 traceId、调用时刻与 side 并联系技术支持",
|
||||
"目标页面=" + sideLabel(ctx.side) + ",影像模式=" + ctx.imageInput.getType().name()
|
||||
locator(ctx)
|
||||
), null);
|
||||
}
|
||||
|
||||
// ---------- 步骤⑤:解析平台结果 → 根据 side 构建正页/副页响应 ----------
|
||||
// ---------- 步骤④:解析平台结果 → 根据 side 构建正页/副页响应 ----------
|
||||
Object data = ApiConstants.back.equals(ctx.side)
|
||||
? buildBackResp(platformResult)
|
||||
: buildFaceResp(platformResult);
|
||||
String hint = resolvePlatformHint(platformResult, ctx, data);
|
||||
|
||||
// ---------- 步骤⑥:日志记录 & 返回 ----------
|
||||
// ---------- 步骤⑤:日志记录 & 返回 ----------
|
||||
logRecognizeResult(ctx, platformResult, data, hint, start);
|
||||
return okResult(ctx.side, hint, data);
|
||||
|
||||
} catch (Exception e) {
|
||||
long cost = System.currentTimeMillis() - start;
|
||||
String side = ctx != null ? ctx.side
|
||||
: (request != null ? resolveVehicleLicenseSide(request) : ApiConstants.front);
|
||||
ResolvedImageInput fallbackImage = request != null
|
||||
? ImageInputUtils.resolve(request.getImageUrlOrBase64()) : null;
|
||||
String mode = ctx != null ? ctx.imageInput.getType().getDesc()
|
||||
: (fallbackImage != null ? fallbackImage.getType().getDesc() : "未知");
|
||||
String modeDesc = ctx.imageInput != null ? ctx.imageInput.getType().getDesc() : "影像未解析";
|
||||
log.error("行驶证识别:程序运行出错,耗时 {} ms。识别{},{}。客户传的:{}。异常:{} - {}",
|
||||
cost, sideDesc(side), mode, buildInputLogContext(request, fallbackImage),
|
||||
cost, sideDesc(ctx.side), modeDesc, ctx.inputLog,
|
||||
e.getClass().getSimpleName(),
|
||||
e.getMessage() != null ? e.getMessage() : "无具体说明", e);
|
||||
return okResult(side, formatHint(
|
||||
return okResult(ctx.side, formatHint(
|
||||
"运行时故障",
|
||||
"服务端在处理识别流程时抛出未预期异常,识别结果不可用",
|
||||
"请勿重复高频重试;请保存 traceId、异常发生时间及 side,由技术支持结合堆栈进一步定位",
|
||||
@ -243,9 +234,15 @@ public class RecognizeDrivingLicenseController extends AbstractRecognizeControll
|
||||
|
||||
// ===================== 校验与上下文 =====================
|
||||
|
||||
private String validateRequest(VehicleLicenseRequest request) {
|
||||
/**
|
||||
* 纯逻辑校验:基于入口处已完成的 imageValidation / resolvedSide 做判断,自身不再触发 IO。
|
||||
*/
|
||||
private String validateRequest(VehicleLicenseRequest request,
|
||||
ImageInputUtils.ValidationResult imageValidation,
|
||||
String resolvedSide,
|
||||
RecognizeContext ctx) {
|
||||
if (request == null) {
|
||||
log.info("行驶证识别:没收到任何请求参数,直接拒绝,未调用识别、不扣费");
|
||||
log.info("行驶证识别:没收到任何请求参数(请求体未绑定成功),直接拒绝,未调用识别、不扣费");
|
||||
return formatHint(
|
||||
"入参绑定失败",
|
||||
"控制器未接收到可绑定的请求对象,所有业务字段均为空",
|
||||
@ -254,13 +251,9 @@ public class RecognizeDrivingLicenseController extends AbstractRecognizeControll
|
||||
"绑定结果=VehicleLicenseRequest 为 null"
|
||||
);
|
||||
}
|
||||
ImageInputUtils.ValidationResult imageValidation =
|
||||
ImageInputUtils.validate(request.getImageUrlOrBase64());
|
||||
if (!imageValidation.isValid()) {
|
||||
if (imageValidation != null && !imageValidation.isValid()) {
|
||||
log.info("行驶证识别:imageUrlOrBase64 校验未通过({}),未调用识别、不扣费。原因:{}。{}",
|
||||
imageValidation.getCategory(),
|
||||
imageValidation.getReason(),
|
||||
buildInputLogContext(request, null));
|
||||
imageValidation.getCategory(), imageValidation.getReason(), ctx.inputLog);
|
||||
return formatHint(
|
||||
imageValidation.getCategory(),
|
||||
imageValidation.getReason(),
|
||||
@ -269,9 +262,9 @@ public class RecognizeDrivingLicenseController extends AbstractRecognizeControll
|
||||
+ (isBlank(request.getSide()) ? SIDE_DEFAULT_HINT : request.getSide().trim())
|
||||
);
|
||||
}
|
||||
if (resolveVehicleLicenseSide(request) == null) {
|
||||
if (resolvedSide == null) {
|
||||
log.info("行驶证识别:side 参数写错了(只支持 front 正页、back 副页),直接拒绝,未调用识别、不扣费。{}",
|
||||
buildInputLogContext(request, ImageInputUtils.resolve(request.getImageUrlOrBase64())));
|
||||
ctx.inputLog);
|
||||
return formatHint(
|
||||
"页面标识无效",
|
||||
"参数 side 的取值无法映射到行驶证主页或副页识别模式",
|
||||
@ -378,13 +371,18 @@ public class RecognizeDrivingLicenseController extends AbstractRecognizeControll
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/** 入参日志说明(不打印影像正文,只说类型与长度) */
|
||||
private String buildInputLogContext(VehicleLicenseRequest request, ResolvedImageInput imageInput) {
|
||||
/**
|
||||
* 入参日志说明(不打印影像正文,只说类型与长度)。
|
||||
*
|
||||
* @param resolvedSide 已在调用方解析过的 side(无效时为 null),避免本方法内重复 resolve
|
||||
*/
|
||||
private String buildInputLogContext(VehicleLicenseRequest request,
|
||||
ResolvedImageInput imageInput,
|
||||
String resolvedSide) {
|
||||
if (request == null) {
|
||||
return "未收到请求体";
|
||||
}
|
||||
String sideParam = isBlank(request.getSide()) ? "未传(默认按正页)" : request.getSide().trim();
|
||||
String resolvedSide = resolveVehicleLicenseSide(request);
|
||||
String targetPage = resolvedSide == null ? "side 无法识别" : sideDesc(resolvedSide);
|
||||
String modeDesc = imageInput != null ? imageInput.getType().getDesc() : "影像未解析";
|
||||
int rawLen = imageInput != null
|
||||
@ -393,4 +391,10 @@ public class RecognizeDrivingLicenseController extends AbstractRecognizeControll
|
||||
return String.format("识别%s,side 参数=%s,%s,影像原始长度 %d 字符",
|
||||
targetPage, sideParam, modeDesc, rawLen);
|
||||
}
|
||||
|
||||
/** "目标页面=xx,影像模式=xx" 拼接,formatHint 的 detail 字段共用此格式。 */
|
||||
private String locator(RecognizeContext ctx) {
|
||||
return "目标页面=" + sideLabel(ctx.side) + ",影像模式="
|
||||
+ (ctx.imageInput != null ? ctx.imageInput.getType().name() : "未解析");
|
||||
}
|
||||
}
|
||||
|
||||
@ -94,28 +94,27 @@ public class RecognizeLicensePlateController extends AbstractRecognizeController
|
||||
@PostMapping("/recognize")
|
||||
public R recognize(@RequestBody LicensePlateRecognizeRequest request) {
|
||||
long start = System.currentTimeMillis();
|
||||
RecognizeContext ctx = null;
|
||||
try {
|
||||
// ---------- 步骤①:参数校验(不调百度、不扣费) ----------
|
||||
String validateError = validateRequest(request);
|
||||
if (validateError != null) {
|
||||
ResolvedImageInput validateImage = request != null
|
||||
? ImageInputUtils.resolve(request.getImageUrlOrBase64()) : null;
|
||||
log.info("车牌识别:参数检查没通过,接口仍返回成功并附带提示(还没调识别、不扣费)。{} 返回给客户:{}",
|
||||
buildInputLogContext(request, validateImage),
|
||||
abbreviate(validateError, 120));
|
||||
return okResult(SIDE_PLACEHOLDER, validateError, null);
|
||||
}
|
||||
|
||||
// ---------- 步骤②:解析影像入参 & 构建上下文 ----------
|
||||
ResolvedImageInput imageInput = ImageInputUtils.resolve(request.getImageUrlOrBase64());
|
||||
ctx = new RecognizeContext(
|
||||
// 入口处一次性解析:整个请求中 ImageInputUtils.validate / resolve 仅执行一次,后续主流程与 catch 块复用 ctx。
|
||||
ImageInputUtils.ValidationResult imageValidation = request != null
|
||||
? ImageInputUtils.validate(request.getImageUrlOrBase64()) : null;
|
||||
ResolvedImageInput imageInput = imageValidation != null && imageValidation.isValid()
|
||||
? imageValidation.getResolved() : null;
|
||||
RecognizeContext ctx = new RecognizeContext(
|
||||
SIDE_PLACEHOLDER,
|
||||
imageInput,
|
||||
buildInputLogContext(request, imageInput));
|
||||
try {
|
||||
// ---------- 步骤①:参数校验(不调百度、不扣费) ----------
|
||||
String validateError = validateRequest(request, imageValidation, ctx);
|
||||
if (validateError != null) {
|
||||
log.info("车牌识别:参数检查没通过,接口仍返回成功并附带提示(还没调识别、不扣费)。{} 返回给客户:{}",
|
||||
ctx.inputLog, abbreviate(validateError, 120));
|
||||
return okResult(SIDE_PLACEHOLDER, validateError, null);
|
||||
}
|
||||
// 校验通过后 ctx.imageInput 必然有效,下文可直接使用。
|
||||
|
||||
// ---------- 步骤③:组装百度 API 请求体 ----------
|
||||
String content = buildRequestContent(imageInput);
|
||||
// ---------- 步骤②:组装百度 API 请求体 ----------
|
||||
String content = buildRequestContent(ctx.imageInput);
|
||||
if (isBlank(content)) {
|
||||
log.error("车牌识别:组装请求失败,请求里没带有效图片。{}。{}",
|
||||
ctx.imageInput.getType().getDesc(), ctx.inputLog);
|
||||
@ -123,38 +122,35 @@ public class RecognizeLicensePlateController extends AbstractRecognizeController
|
||||
"报文组装异常",
|
||||
"识别请求体在序列化后未包含任何影像载荷,平台侧无法受理本次识别",
|
||||
"请核对 imageUrlOrBase64 是否非空且为有效 Base64 或 HTTP(S) 链接",
|
||||
"影像模式=" + ctx.imageInput.getType().name()
|
||||
locator(ctx)
|
||||
), null);
|
||||
}
|
||||
|
||||
// ---------- 步骤④:调用百度平台识别 ----------
|
||||
// ---------- 步骤③:调用百度平台识别 ----------
|
||||
Map<String, Object> platformResult = callPlatform(content, ctx);
|
||||
if (platformResult == null) {
|
||||
return okResult(SIDE_PLACEHOLDER, formatHint(
|
||||
"服务无回执",
|
||||
"识别指令已下发,但在约定时间内未收到平台可解析的 JSON 回执",
|
||||
"建议间隔 3~5 秒重试;若连续失败,请记录 traceId、调用时刻并联系技术支持排查链路",
|
||||
"影像模式=" + ctx.imageInput.getType().name()
|
||||
locator(ctx)
|
||||
), null);
|
||||
}
|
||||
|
||||
// ---------- 步骤⑤:解析平台结果 → 构建车牌响应 ----------
|
||||
// ---------- 步骤④:解析平台结果 → 构建车牌响应 ----------
|
||||
Map<String, Object> primary = pickPrimaryPlate(platformResult);
|
||||
RecognizeLicensePlateResp data = buildPlateResp(primary);
|
||||
String hint = resolvePlatformHint(platformResult, primary, ctx, data);
|
||||
|
||||
// ---------- 步骤⑥:日志记录 & 返回 ----------
|
||||
// ---------- 步骤⑤:日志记录 & 返回 ----------
|
||||
logRecognizeResult(ctx, platformResult, data, hint, start);
|
||||
return okResult(SIDE_PLACEHOLDER, hint, data);
|
||||
|
||||
} catch (Exception e) {
|
||||
long cost = System.currentTimeMillis() - start;
|
||||
ResolvedImageInput fallbackImage = request != null
|
||||
? ImageInputUtils.resolve(request.getImageUrlOrBase64()) : null;
|
||||
String mode = ctx != null ? ctx.imageInput.getType().getDesc()
|
||||
: (fallbackImage != null ? fallbackImage.getType().getDesc() : "未知");
|
||||
String modeDesc = ctx.imageInput != null ? ctx.imageInput.getType().getDesc() : "影像未解析";
|
||||
log.error("车牌识别:程序运行出错,耗时 {} ms。{}。客户传的:{}。异常:{} - {}",
|
||||
cost, mode, buildInputLogContext(request, fallbackImage),
|
||||
cost, modeDesc, ctx.inputLog,
|
||||
e.getClass().getSimpleName(),
|
||||
e.getMessage() != null ? e.getMessage() : "无具体说明", e);
|
||||
return okResult(SIDE_PLACEHOLDER, formatHint(
|
||||
@ -274,9 +270,14 @@ public class RecognizeLicensePlateController extends AbstractRecognizeController
|
||||
|
||||
// ===================== 校验 =====================
|
||||
|
||||
private String validateRequest(LicensePlateRecognizeRequest request) {
|
||||
/**
|
||||
* 纯逻辑校验:基于入口处已完成的 imageValidation 做判断,自身不再触发 IO。
|
||||
*/
|
||||
private String validateRequest(LicensePlateRecognizeRequest request,
|
||||
ImageInputUtils.ValidationResult imageValidation,
|
||||
RecognizeContext ctx) {
|
||||
if (request == null) {
|
||||
log.info("车牌识别:没收到任何请求参数(表单未绑定成功),直接拒绝,未调用识别、不扣费");
|
||||
log.info("车牌识别:没收到任何请求参数(请求体未绑定成功),直接拒绝,未调用识别、不扣费");
|
||||
return formatHint(
|
||||
"入参绑定失败",
|
||||
"控制器未接收到可绑定的请求对象,所有业务字段均为空",
|
||||
@ -285,13 +286,9 @@ public class RecognizeLicensePlateController extends AbstractRecognizeController
|
||||
"绑定结果=LicensePlateRecognizeRequest 为 null"
|
||||
);
|
||||
}
|
||||
ImageInputUtils.ValidationResult imageValidation =
|
||||
ImageInputUtils.validate(request.getImageUrlOrBase64());
|
||||
if (!imageValidation.isValid()) {
|
||||
if (imageValidation != null && !imageValidation.isValid()) {
|
||||
log.info("车牌识别:imageUrlOrBase64 校验未通过({}),未调用识别、不扣费。原因:{}。{}",
|
||||
imageValidation.getCategory(),
|
||||
imageValidation.getReason(),
|
||||
buildInputLogContext(request, null));
|
||||
imageValidation.getCategory(), imageValidation.getReason(), ctx.inputLog);
|
||||
return formatHint(
|
||||
imageValidation.getCategory(),
|
||||
imageValidation.getReason(),
|
||||
@ -501,4 +498,9 @@ public class RecognizeLicensePlateController extends AbstractRecognizeController
|
||||
: textLength(request.getImageUrlOrBase64());
|
||||
return String.format("%s,影像原始长度 %d 字符", modeDesc, rawLen);
|
||||
}
|
||||
|
||||
/** "影像模式=xx" 拼接,formatHint 的 detail 字段共用此格式。 */
|
||||
private String locator(RecognizeContext ctx) {
|
||||
return "影像模式=" + (ctx.imageInput != null ? ctx.imageInput.getType().name() : "未解析");
|
||||
}
|
||||
}
|
||||
|
||||
@ -94,28 +94,27 @@ public class RecognizeTrainTicketController extends AbstractRecognizeController
|
||||
@PostMapping("/recognize")
|
||||
public R recognize(@RequestBody TrainTicketRecognizeRequest request) {
|
||||
long start = System.currentTimeMillis();
|
||||
RecognizeContext ctx = null;
|
||||
try {
|
||||
// ---------- 步骤①:参数校验(不调百度、不扣费) ----------
|
||||
String validateError = validateRequest(request);
|
||||
if (validateError != null) {
|
||||
ResolvedImageInput validateImage = request != null
|
||||
? ImageInputUtils.resolve(request.getImageUrlOrBase64()) : null;
|
||||
log.info("火车票识别:参数检查没通过,接口仍返回成功并附带提示(还没调识别、不扣费)。{} 返回给客户:{}",
|
||||
buildInputLogContext(request, validateImage),
|
||||
abbreviate(validateError, 120));
|
||||
return okResult(SIDE_PLACEHOLDER, validateError, null);
|
||||
}
|
||||
|
||||
// ---------- 步骤②:解析影像入参 & 构建上下文 ----------
|
||||
ResolvedImageInput imageInput = ImageInputUtils.resolve(request.getImageUrlOrBase64());
|
||||
ctx = new RecognizeContext(
|
||||
// 入口处一次性解析:整个请求中 ImageInputUtils.validate / resolve 仅执行一次,后续主流程与 catch 块复用 ctx。
|
||||
ImageInputUtils.ValidationResult imageValidation = request != null
|
||||
? ImageInputUtils.validate(request.getImageUrlOrBase64()) : null;
|
||||
ResolvedImageInput imageInput = imageValidation != null && imageValidation.isValid()
|
||||
? imageValidation.getResolved() : null;
|
||||
RecognizeContext ctx = new RecognizeContext(
|
||||
SIDE_PLACEHOLDER,
|
||||
imageInput,
|
||||
buildInputLogContext(request, imageInput));
|
||||
try {
|
||||
// ---------- 步骤①:参数校验(不调百度、不扣费) ----------
|
||||
String validateError = validateRequest(request, imageValidation, ctx);
|
||||
if (validateError != null) {
|
||||
log.info("火车票识别:参数检查没通过,接口仍返回成功并附带提示(还没调识别、不扣费)。{} 返回给客户:{}",
|
||||
ctx.inputLog, abbreviate(validateError, 120));
|
||||
return okResult(SIDE_PLACEHOLDER, validateError, null);
|
||||
}
|
||||
// 校验通过后 ctx.imageInput 必然有效,下文可直接使用。
|
||||
|
||||
// ---------- 步骤③:组装百度 API 请求体 ----------
|
||||
String content = buildRequestContent(imageInput);
|
||||
// ---------- 步骤②:组装百度 API 请求体 ----------
|
||||
String content = buildRequestContent(ctx.imageInput);
|
||||
if (isBlank(content)) {
|
||||
log.error("火车票识别:组装请求失败,请求里没带有效图片。{}。{}",
|
||||
ctx.imageInput.getType().getDesc(), ctx.inputLog);
|
||||
@ -123,37 +122,34 @@ public class RecognizeTrainTicketController extends AbstractRecognizeController
|
||||
"报文组装异常",
|
||||
"识别请求体在序列化后未包含任何影像载荷,平台侧无法受理本次识别",
|
||||
"请核对 imageUrlOrBase64 是否非空且为有效 Base64 或 HTTP(S) 链接",
|
||||
"影像模式=" + ctx.imageInput.getType().name()
|
||||
locator(ctx)
|
||||
), null);
|
||||
}
|
||||
|
||||
// ---------- 步骤④:调用百度平台识别 ----------
|
||||
// ---------- 步骤③:调用百度平台识别 ----------
|
||||
Map<String, Object> platformResult = callPlatform(content, ctx);
|
||||
if (platformResult == null) {
|
||||
return okResult(SIDE_PLACEHOLDER, formatHint(
|
||||
"服务无回执",
|
||||
"识别指令已下发,但在约定时间内未收到平台可解析的 JSON 回执",
|
||||
"建议间隔 3~5 秒重试;若连续失败,请记录 traceId、调用时刻并联系技术支持排查链路",
|
||||
"影像模式=" + ctx.imageInput.getType().name()
|
||||
locator(ctx)
|
||||
), null);
|
||||
}
|
||||
|
||||
// ---------- 步骤⑤:解析平台结果 → 构建车票响应(含 PII 脱敏) ----------
|
||||
// ---------- 步骤④:解析平台结果 → 构建车票响应(含 PII 脱敏) ----------
|
||||
RecognizeTrainTicketResp data = buildResp(platformResult);
|
||||
String hint = resolvePlatformHint(platformResult, ctx, data);
|
||||
|
||||
// ---------- 步骤⑥:日志记录 & 返回 ----------
|
||||
// ---------- 步骤⑤:日志记录 & 返回 ----------
|
||||
logRecognizeResult(ctx, platformResult, data, hint, start);
|
||||
return okResult(SIDE_PLACEHOLDER, hint, data);
|
||||
|
||||
} catch (Exception e) {
|
||||
long cost = System.currentTimeMillis() - start;
|
||||
ResolvedImageInput fallbackImage = request != null
|
||||
? ImageInputUtils.resolve(request.getImageUrlOrBase64()) : null;
|
||||
String mode = ctx != null ? ctx.imageInput.getType().getDesc()
|
||||
: (fallbackImage != null ? fallbackImage.getType().getDesc() : "未知");
|
||||
String modeDesc = ctx.imageInput != null ? ctx.imageInput.getType().getDesc() : "影像未解析";
|
||||
log.error("火车票识别:程序运行出错,耗时 {} ms。{}。客户传的:{}。异常:{} - {}",
|
||||
cost, mode, buildInputLogContext(request, fallbackImage),
|
||||
cost, modeDesc, ctx.inputLog,
|
||||
e.getClass().getSimpleName(),
|
||||
e.getMessage() != null ? e.getMessage() : "无具体说明", e);
|
||||
return okResult(SIDE_PLACEHOLDER, formatHint(
|
||||
@ -261,9 +257,14 @@ public class RecognizeTrainTicketController extends AbstractRecognizeController
|
||||
|
||||
// ===================== 校验 =====================
|
||||
|
||||
private String validateRequest(TrainTicketRecognizeRequest request) {
|
||||
/**
|
||||
* 纯逻辑校验:基于入口处已完成的 imageValidation 做判断,自身不再触发 IO。
|
||||
*/
|
||||
private String validateRequest(TrainTicketRecognizeRequest request,
|
||||
ImageInputUtils.ValidationResult imageValidation,
|
||||
RecognizeContext ctx) {
|
||||
if (request == null) {
|
||||
log.info("火车票识别:没收到任何请求参数(表单未绑定成功),直接拒绝,未调用识别、不扣费");
|
||||
log.info("火车票识别:没收到任何请求参数(请求体未绑定成功),直接拒绝,未调用识别、不扣费");
|
||||
return formatHint(
|
||||
"入参绑定失败",
|
||||
"控制器未接收到可绑定的请求对象,所有业务字段均为空",
|
||||
@ -271,13 +272,9 @@ public class RecognizeTrainTicketController extends AbstractRecognizeController
|
||||
"绑定结果=TrainTicketRecognizeRequest 为 null"
|
||||
);
|
||||
}
|
||||
ImageInputUtils.ValidationResult imageValidation =
|
||||
ImageInputUtils.validate(request.getImageUrlOrBase64());
|
||||
if (!imageValidation.isValid()) {
|
||||
if (imageValidation != null && !imageValidation.isValid()) {
|
||||
log.info("火车票识别:imageUrlOrBase64 校验未通过({}),未调用识别、不扣费。原因:{}。{}",
|
||||
imageValidation.getCategory(),
|
||||
imageValidation.getReason(),
|
||||
buildInputLogContext(request, null));
|
||||
imageValidation.getCategory(), imageValidation.getReason(), ctx.inputLog);
|
||||
return formatHint(
|
||||
imageValidation.getCategory(),
|
||||
imageValidation.getReason(),
|
||||
@ -398,4 +395,9 @@ public class RecognizeTrainTicketController extends AbstractRecognizeController
|
||||
: textLength(request.getImageUrlOrBase64());
|
||||
return String.format("%s,影像原始长度 %d 字符", modeDesc, rawLen);
|
||||
}
|
||||
|
||||
/** "影像模式=xx" 拼接,formatHint 的 detail 字段共用此格式。 */
|
||||
private String locator(RecognizeContext ctx) {
|
||||
return "影像模式=" + (ctx.imageInput != null ? ctx.imageInput.getType().name() : "未解析");
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
package com.heyu.api.vv;
|
||||
package com.heyu.api.vv.controller;
|
||||
|
||||
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
@ -1,4 +1,4 @@
|
||||
package com.heyu.api.vv;
|
||||
package com.heyu.api.vv.controller;
|
||||
|
||||
|
||||
import com.heyu.api.alibaba.request.vv.AppBuyerRequest;
|
||||
@ -1,4 +1,4 @@
|
||||
package com.heyu.api.vv;
|
||||
package com.heyu.api.vv.controller;
|
||||
|
||||
|
||||
import com.heyu.api.alibaba.request.mm.VvAppCategoryRequest;
|
||||
@ -1,4 +1,4 @@
|
||||
package com.heyu.api.vv;
|
||||
package com.heyu.api.vv.controller;
|
||||
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
@ -1,4 +1,4 @@
|
||||
package com.heyu.api.vv;
|
||||
package com.heyu.api.vv.controller;
|
||||
|
||||
|
||||
import com.heyu.api.alibaba.request.mm.AppPromoterTradeOrderDrawRequest;
|
||||
@ -1,4 +1,4 @@
|
||||
package com.heyu.api.vv;
|
||||
package com.heyu.api.vv.controller;
|
||||
|
||||
|
||||
import com.heyu.api.common.annotation.Describe;
|
||||
@ -1,4 +1,4 @@
|
||||
package com.heyu.api.vv;
|
||||
package com.heyu.api.vv.controller;
|
||||
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
@ -1,4 +1,4 @@
|
||||
package com.heyu.api.vv;
|
||||
package com.heyu.api.vv.controller;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.heyu.api.common.annotation.AppRealyLogin;
|
||||
@ -1,4 +1,4 @@
|
||||
package com.heyu.api.vv;
|
||||
package com.heyu.api.vv.controller;
|
||||
|
||||
|
||||
import com.heyu.api.alibaba.request.vv.AppLinkRequest;
|
||||
@ -1,4 +1,4 @@
|
||||
package com.heyu.api.vv;
|
||||
package com.heyu.api.vv.controller;
|
||||
|
||||
|
||||
import com.heyu.api.alibaba.request.mm.VvAppLogisticsRequest;
|
||||
@ -1,4 +1,4 @@
|
||||
package com.heyu.api.vv;
|
||||
package com.heyu.api.vv.controller;
|
||||
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
@ -1,4 +1,4 @@
|
||||
package com.heyu.api.vv;
|
||||
package com.heyu.api.vv.controller;
|
||||
|
||||
|
||||
import com.heyu.api.common.annotation.AppRealyLogin;
|
||||
@ -1,5 +1,5 @@
|
||||
|
||||
package com.heyu.api.vv;
|
||||
package com.heyu.api.vv.controller;
|
||||
|
||||
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
@ -1,4 +1,4 @@
|
||||
package com.heyu.api.vv;
|
||||
package com.heyu.api.vv.controller;
|
||||
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
@ -1,5 +1,5 @@
|
||||
|
||||
package com.heyu.api.vv;
|
||||
package com.heyu.api.vv.controller;
|
||||
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
@ -1,4 +1,4 @@
|
||||
package com.heyu.api.vv;
|
||||
package com.heyu.api.vv.controller;
|
||||
|
||||
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
@ -1,4 +1,4 @@
|
||||
package com.heyu.api.vv;
|
||||
package com.heyu.api.vv.controller;
|
||||
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
@ -1,4 +1,4 @@
|
||||
package com.heyu.api.vv;
|
||||
package com.heyu.api.vv.controller;
|
||||
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
@ -1,4 +1,4 @@
|
||||
package com.heyu.api.vv;
|
||||
package com.heyu.api.vv.controller;
|
||||
|
||||
|
||||
import com.heyu.api.data.service.impl.AppBaseRequest;
|
||||
@ -1,4 +1,4 @@
|
||||
package com.heyu.api.vv;
|
||||
package com.heyu.api.vv.controller;
|
||||
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
@ -1,4 +1,4 @@
|
||||
package com.heyu.api.vv;
|
||||
package com.heyu.api.vv.controller;
|
||||
|
||||
|
||||
import com.heyu.api.common.annotation.AppRealyLogin;
|
||||
@ -1,4 +1,4 @@
|
||||
package com.heyu.api.vv;
|
||||
package com.heyu.api.vv.controller;
|
||||
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
@ -1,4 +1,4 @@
|
||||
package com.heyu.api.vv;
|
||||
package com.heyu.api.vv.controller;
|
||||
|
||||
|
||||
import com.heyu.api.data.utils.WeChatCallbackUtil;
|
||||
@ -1,4 +1,4 @@
|
||||
package com.heyu.api.vv;
|
||||
package com.heyu.api.vv.controller;
|
||||
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
@ -1,4 +1,4 @@
|
||||
package com.heyu.api.vv;
|
||||
package com.heyu.api.vv.controller;
|
||||
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
@ -1,5 +1,5 @@
|
||||
|
||||
package com.heyu.api.vv;
|
||||
package com.heyu.api.vv.controller;
|
||||
|
||||
|
||||
import com.heyu.api.alibaba.request.vv.AppQrCodeRequest;
|
||||
Loading…
x
Reference in New Issue
Block a user