|
|
@@ -154,41 +154,45 @@ public class HengBangCrawlerRequestImpl implements HengBangCrawlerRequest {
|
|
|
HbCrawlerCalculationRequest calculationRequest = new HbCrawlerCalculationRequest(quoteVo, plyappno, depreciationPrice);
|
|
|
// 非车信息匹配核心
|
|
|
matchingAccident(quoteVo, headers, plyappno, calculationRequest);
|
|
|
- String resJson = hbCrawlerRequestComponent.getCalculationResult(calculationRequest, headers);
|
|
|
- JSONObject resJsonObj = JSONObject.parseObject(resJson);
|
|
|
+
|
|
|
+ return executeCalculationWithRetry(calculationRequest, headers, quoteVo, plyappno);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 执行报价计算并处理重试逻辑(脱保、重复投保、转保车验证码)
|
|
|
+ */
|
|
|
+ private QuoteResultsVo executeCalculationWithRetry(HbCrawlerCalculationRequest calculationRequest, HttpHeaders headers, QuoteVo quoteVo, String plyappno) {
|
|
|
+ JSONObject resJsonObj = callCalculation(calculationRequest, headers);
|
|
|
if (resJsonObj == null) {
|
|
|
- return HbCrawlerQuoteResultVoBuild.build(quoteVo, null, "恒邦calculation接口返回异常");
|
|
|
+ return buildErrorResult(quoteVo);
|
|
|
}
|
|
|
String errorMsg = resJsonObj.getString("message");
|
|
|
- String status = resJsonObj.getString("status");
|
|
|
|
|
|
HbCrawlerProposalResponse proposalResponse = null;
|
|
|
// 脱保情况 重新赋值核心建议起保时间 二次报价
|
|
|
if (errorMsg.contains("脱保")) {
|
|
|
calculationRequest.setOutofwarrantytype("N");
|
|
|
- resJson = hbCrawlerRequestComponent.getCalculationResult(calculationRequest, headers);
|
|
|
- resJsonObj = JSONObject.parseObject(resJson);
|
|
|
- if (resJsonObj == null) {
|
|
|
- return HbCrawlerQuoteResultVoBuild.build(quoteVo, null, "恒邦calculation接口返回异常");
|
|
|
+ errorMsg = retryCalculation(calculationRequest, headers);
|
|
|
+ if (errorMsg == null) {
|
|
|
+ return buildErrorResult(quoteVo);
|
|
|
}
|
|
|
- errorMsg = resJsonObj.getString("message");
|
|
|
- status = resJsonObj.getString("status");
|
|
|
}
|
|
|
|
|
|
- if (errorMsg.contains("重复投保")) {
|
|
|
- String time = hbCrawlerRequestComponent.extractDuplicateEndTime(errorMsg);
|
|
|
- if (time != null) {
|
|
|
- calculationRequest.setBegintimeCi(DateUtil.toUtcDateTime(time));
|
|
|
- calculationRequest.setBegintimeBi(DateUtil.toUtcDateTime(time));
|
|
|
+ // 重复投保:循环重试,优先从responseBody.begintimeBi获取建议起保时间
|
|
|
+ int maxRetry = 3;
|
|
|
+ while (errorMsg.contains("重复投保") && maxRetry-- > 0) {
|
|
|
+ String time = getDuplicateBegintime(resJsonObj, errorMsg);
|
|
|
+ log.info("重复投保,重试次数:{}, 建议起保时间:{}", 3 - maxRetry, time);
|
|
|
+ if (time == null) {
|
|
|
+ break;
|
|
|
}
|
|
|
-
|
|
|
- resJson = hbCrawlerRequestComponent.getCalculationResult(calculationRequest, headers);
|
|
|
- resJsonObj = JSONObject.parseObject(resJson);
|
|
|
+ calculationRequest.setBegintimeCi(DateUtil.toUtcDateTime(time));
|
|
|
+ calculationRequest.setBegintimeBi(DateUtil.toUtcDateTime(time));
|
|
|
+ resJsonObj = callCalculation(calculationRequest, headers);
|
|
|
if (resJsonObj == null) {
|
|
|
- return HbCrawlerQuoteResultVoBuild.build(quoteVo, null, "恒邦calculation接口返回异常");
|
|
|
+ return buildErrorResult(quoteVo);
|
|
|
}
|
|
|
errorMsg = resJsonObj.getString("message");
|
|
|
- status = resJsonObj.getString("status");
|
|
|
}
|
|
|
|
|
|
if (errorMsg.contains("该车是转保车,请输入对应的转保验证码")) {
|
|
|
@@ -196,27 +200,23 @@ public class HengBangCrawlerRequestImpl implements HengBangCrawlerRequest {
|
|
|
HbCrawlerRecordResponse recordResponse = JSONObject.parseObject(responseBody, HbCrawlerRecordResponse.class);
|
|
|
// 识别验证码
|
|
|
String systemJqCode = exteriorUtilsRequest.captchaIdentify(recordResponse.getCheckcodeJqImg());
|
|
|
- log.info( "系统识别的交强验证码为:" + systemJqCode);
|
|
|
+ log.info("系统识别的交强验证码为:{}", systemJqCode);
|
|
|
recordResponse.setCheckcodeJq(systemJqCode);
|
|
|
// 识别验证码
|
|
|
String systemSyCode = exteriorUtilsRequest.captchaIdentify(recordResponse.getCheckcodeSyImg());
|
|
|
- log.info( "系统识别的商业验证码为:" + systemSyCode);
|
|
|
+ log.info("系统识别的商业验证码为:{}", systemSyCode);
|
|
|
recordResponse.setCheckcodeSy(systemSyCode);
|
|
|
- recordResponse.getCheckcodeJq().replace("0","o");
|
|
|
- recordResponse.getCheckcodeSy().replace("0","o");
|
|
|
+ recordResponse.setCheckcodeJq(recordResponse.getCheckcodeJq().replace("0", "o"));
|
|
|
+ recordResponse.setCheckcodeSy(recordResponse.getCheckcodeSy().replace("0", "o"));
|
|
|
calculationRequest.setTransferVehicle(recordResponse);
|
|
|
|
|
|
- resJson = hbCrawlerRequestComponent.getCalculationResult(calculationRequest, headers);
|
|
|
- resJsonObj = JSONObject.parseObject(resJson);
|
|
|
- if (resJsonObj == null) {
|
|
|
- return HbCrawlerQuoteResultVoBuild.build(quoteVo, null, "恒邦calculation接口返回异常");
|
|
|
+ errorMsg = retryCalculation(calculationRequest, headers);
|
|
|
+ if (errorMsg == null) {
|
|
|
+ return buildErrorResult(quoteVo);
|
|
|
}
|
|
|
- errorMsg = resJsonObj.getString("message");
|
|
|
- status = resJsonObj.getString("status");
|
|
|
}
|
|
|
|
|
|
- if (errorMsg.equals("成功")) {
|
|
|
- errorMsg = "成功";
|
|
|
+ if ("成功".equals(errorMsg)) {
|
|
|
// 5.2 报价第三步,获取报价数据
|
|
|
proposalResponse = hbCrawlerRequestComponent.carInsureItem(plyappno, headers);
|
|
|
HbCrawlerOrder hbCrawlerOrder = new HbCrawlerOrder();
|
|
|
@@ -227,6 +227,64 @@ public class HengBangCrawlerRequestImpl implements HengBangCrawlerRequest {
|
|
|
return HbCrawlerQuoteResultVoBuild.build(quoteVo, proposalResponse, errorMsg);
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * 调用报价接口并返回解析结果
|
|
|
+ */
|
|
|
+ private JSONObject callCalculation(HbCrawlerCalculationRequest calculationRequest, HttpHeaders headers) {
|
|
|
+ String resJson = hbCrawlerRequestComponent.getCalculationResult(calculationRequest, headers);
|
|
|
+ return JSONObject.parseObject(resJson);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 重试报价并返回错误消息,null表示接口异常
|
|
|
+ */
|
|
|
+ private String retryCalculation(HbCrawlerCalculationRequest calculationRequest, HttpHeaders headers) {
|
|
|
+ JSONObject resJsonObj = callCalculation(calculationRequest, headers);
|
|
|
+ return resJsonObj != null ? resJsonObj.getString("message") : null;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 构建异常返回结果
|
|
|
+ */
|
|
|
+ private QuoteResultsVo buildErrorResult(QuoteVo quoteVo) {
|
|
|
+ return HbCrawlerQuoteResultVoBuild.build(quoteVo, null, "恒邦calculation接口返回异常");
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取重复投保场景的建议起保时间(yyyy-MM-dd HH:mm:ss 格式)
|
|
|
+ * 优先从 responseBody.begintimeBi 获取,兜底从 message 正则提取
|
|
|
+ */
|
|
|
+ private String getDuplicateBegintime(JSONObject resJsonObj, String errorMsg) {
|
|
|
+ // 优先从 responseBody.begintimeBi 获取
|
|
|
+ JSONObject responseBody = resJsonObj.getJSONObject("responseBody");
|
|
|
+ if (responseBody != null) {
|
|
|
+ String begintimeBi = responseBody.getString("begintimeBi");
|
|
|
+ if (begintimeBi != null) {
|
|
|
+ return normalizeTimeFormat(begintimeBi);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // 兼容:从 message 正则提取终保日期
|
|
|
+ return hbCrawlerRequestComponent.extractDuplicateEndTime(errorMsg);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 统一时间格式为 yyyy-MM-dd HH:mm:ss
|
|
|
+ */
|
|
|
+ private String normalizeTimeFormat(String time) {
|
|
|
+ if (time == null) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ // "2026-07-23" → "2026-07-23 00:00:00"
|
|
|
+ if (time.length() <= 10) {
|
|
|
+ return time + " 00:00:00";
|
|
|
+ }
|
|
|
+ // "2025-12-14 16:00" → "2025-12-14 16:00:00"
|
|
|
+ if (time.length() == 16) {
|
|
|
+ return time + ":00";
|
|
|
+ }
|
|
|
+ return time;
|
|
|
+ }
|
|
|
+
|
|
|
/**
|
|
|
* 注释
|
|
|
*
|