|
|
@@ -108,6 +108,7 @@ public class HuaTaiCrawlerRequestImpl implements HuaTaiCrawlerRequest {
|
|
|
private static final Pattern PAT_QNO_SPECIAL = Pattern.compile("name=\"quotationNo\" value=\"(.*?)\"");
|
|
|
private static final Pattern PAT_MEAL_ID = Pattern.compile("\"mealid\":\"(.*?)\"");
|
|
|
private static final Pattern LIMIT_AMOUNT = Pattern.compile("value=\"(.*?)\" id=\"js_actualvalue\"");
|
|
|
+ private static final Pattern TRANSFER_FLAG = Pattern.compile("\"erroeType\":\"(.*?)\"");
|
|
|
private static final Pattern PAT_END_DATE = Pattern.compile("终保日期\\s*([^;]+)");
|
|
|
private static final Pattern RESPONSE_ERR = Pattern.compile("(\"infoName\"\\s*:\\s*\"([^\"]*)\",\\s*\"infomsg\"\\s*:\\s*\"([^\"]*)\"|\"erroeInfo\"\\s*:\\s*\"([^\"]*)\")",Pattern.DOTALL);
|
|
|
|
|
|
@@ -507,9 +508,10 @@ public class HuaTaiCrawlerRequestImpl implements HuaTaiCrawlerRequest {
|
|
|
|
|
|
// 重新执行报价预处理流程
|
|
|
AttributionInformationVo attr = q.getOrder().getAttributionInformationVo();
|
|
|
+ log.info(map.get("unMatchVehicleFrameMessage")+"已重新执行prepareQuote,新modelcodexh:{}", currentModelCodexh);
|
|
|
currentPre = prepareQuote(attr, gsInfo, q.getCarInfoVo(),
|
|
|
currentModelCodexh, cookie, quotationNo);
|
|
|
- log.info("已重新执行prepareQuote,新modelcodexh:{}", currentModelCodexh);
|
|
|
+ executeQuoteSteps(q, quotationNo, dto, cookie, currentPre, gsInfo);
|
|
|
|
|
|
// 跳过当前循环,重新执行报价流程
|
|
|
continue;
|
|
|
@@ -619,9 +621,7 @@ public class HuaTaiCrawlerRequestImpl implements HuaTaiCrawlerRequest {
|
|
|
q.getCiRiskInfoVo().setStartDate(start);
|
|
|
try {
|
|
|
LocalDateTime dt = LocalDateTime.parse(start.replace(" ", "T"), DateTimeFormatter.ofPattern(DATE_FMT_T));
|
|
|
- String newStart = dt.format(DateTimeFormatter.ofPattern(DATE_FMT));
|
|
|
String newEnd = dt.plusYears(1).minusDays(1).format(DateTimeFormatter.ofPattern(DATE_FMT));
|
|
|
- q.getCiRiskInfoVo().setStartDate(newStart.substring(0, 10) + " 00:00:00");
|
|
|
q.getCiRiskInfoVo().setEndDate(newEnd.substring(0, 10) + " 23:59:59");
|
|
|
log.info("重复投保,重新设置 起保: {}, 终保: {}", q.getCiRiskInfoVo().getStartDate(), q.getCiRiskInfoVo().getEndDate());
|
|
|
return q;
|
|
|
@@ -634,12 +634,13 @@ public class HuaTaiCrawlerRequestImpl implements HuaTaiCrawlerRequest {
|
|
|
log.info("报价结果: {}", convertResponseMsg(decryptData));
|
|
|
if (decryptData.contains("未传送车辆过户标志")) {
|
|
|
log.error("报价失败: {}", convertResponseMsg(decryptData));
|
|
|
- throw new SystemException(ERR_PREFIX + convertResponseMsg(decryptData));
|
|
|
+ throw new SystemException(ERR_PREFIX + convertResponseMsg(decryptData)+(decryptData.contains("1251BI") ? ",请勾选'商业险是否过户'选项" : ""));
|
|
|
}
|
|
|
if (!decryptData.contains("录入的校验码有误") && decryptData.contains("erroeInfo") && !duplQuoteResult.dupl()) {
|
|
|
log.error("报价失败: {}", convertResponseMsg(decryptData));
|
|
|
throw new SystemException(ERR_PREFIX + convertResponseMsg(decryptData));
|
|
|
}
|
|
|
+ //车损险保额过高 limitAmount
|
|
|
if (decryptData.contains("车损险保额不能高于")) {
|
|
|
Pattern pattern = Pattern.compile("车损险保额不能高于(\\d+\\.?\\d*)元");
|
|
|
Matcher matcher = pattern.matcher(decryptData);
|
|
|
@@ -647,30 +648,70 @@ public class HuaTaiCrawlerRequestImpl implements HuaTaiCrawlerRequest {
|
|
|
decryptData = req.quote(new HtCrawlerQuoteRequest(duplQuoteResult.q(), mealid, limitAmount, "", personalInsuredJSON), h);
|
|
|
return resolveQuoteResponse(duplQuoteResult, decryptData, mealid, limitAmount, h, personalInsuredJSON);
|
|
|
}
|
|
|
- HtCrawlerQuoteResponse.DataDTO data = JSONObject.parseObject(decryptData, HtCrawlerQuoteResponse.DataDTO.class);
|
|
|
+ if (decryptData.contains("传送了车辆过户标志,请确认")) {
|
|
|
+ Pattern pattern = Pattern.compile(TRANSFER_FLAG.pattern());
|
|
|
+ Matcher matcher = pattern.matcher(decryptData);
|
|
|
+ String transferFlag = "";
|
|
|
+ if (matcher.find()) transferFlag = matcher.group(1);
|
|
|
+ decryptData = req.quote(new HtCrawlerQuoteRequest(duplQuoteResult.q(), mealid, limitAmount+","+transferFlag, "", personalInsuredJSON), h);
|
|
|
+ return resolveQuoteResponse(duplQuoteResult, decryptData, mealid, limitAmount, h, personalInsuredJSON);
|
|
|
+ }
|
|
|
+ if (decryptData.contains("TRANS_MESSAGE") && decryptData.contains("终保日期")) {
|
|
|
+ Map<String, String> map = JSONObject.parseObject(decryptData, Map.class);
|
|
|
+ if (map.containsKey("TRANS_MESSAGE") && map.get("TRANS_MESSAGE").contains("交强")) {
|
|
|
+ Matcher m = PAT_END_DATE.matcher(decryptData);
|
|
|
+ if (!m.find()) {
|
|
|
+ String jiaoqiang_startDate = m.group(1);
|
|
|
+ duplQuoteResult.q().getCiRiskInfoVo().setStartDate(jiaoqiang_startDate + ":00");
|
|
|
+ LocalDateTime dt = LocalDateTime.parse(jiaoqiang_startDate.replace(" ", "T"), DateTimeFormatter.ofPattern(DATE_FMT_T));
|
|
|
+ String newEnd = dt.plusYears(1).minusDays(1).format(DateTimeFormatter.ofPattern(DATE_FMT));
|
|
|
+ duplQuoteResult.q().getCiRiskInfoVo().setEndDate(newEnd.substring(0, 10) + " 23:59:59");
|
|
|
+ decryptData = req.quote(new HtCrawlerQuoteRequest(duplQuoteResult.q(), mealid, limitAmount, "", personalInsuredJSON), h);
|
|
|
+ return resolveQuoteResponse(duplQuoteResult, decryptData, mealid, limitAmount, h, personalInsuredJSON);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (map.containsKey("TRANS_MESSAGE") && map.get("TRANS_MESSAGE").contains("商业")) {
|
|
|
+ Matcher m = PAT_END_DATE.matcher(decryptData);
|
|
|
+ if (!m.find()) {
|
|
|
+ String chesun_startDate = m.group(1);
|
|
|
+ duplQuoteResult.q().getBiRiskInfoVo().setStartDate(chesun_startDate);
|
|
|
+ LocalDateTime dt = LocalDateTime.parse(chesun_startDate.replace(" ", "T"), DateTimeFormatter.ofPattern(DATE_FMT_T));
|
|
|
+ String newEnd = dt.plusYears(1).minusDays(1).format(DateTimeFormatter.ofPattern(DATE_FMT));
|
|
|
+ duplQuoteResult.q().getBiRiskInfoVo().setEndDate(newEnd.substring(0, 10) + " 23:59:59");
|
|
|
+ decryptData = req.quote(new HtCrawlerQuoteRequest(duplQuoteResult.q(), mealid, limitAmount, "", personalInsuredJSON), h);
|
|
|
+ return resolveQuoteResponse(duplQuoteResult, decryptData, mealid, limitAmount, h, personalInsuredJSON);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (decryptData.contains("errrorFlag") && decryptData.contains("carChange")) {
|
|
|
+ throw new SystemException(decryptData);
|
|
|
+ }
|
|
|
+ HtCrawlerQuoteResponse.DataDTO data = null;
|
|
|
+ data = JSONObject.parseObject(decryptData, HtCrawlerQuoteResponse.DataDTO.class);
|
|
|
+
|
|
|
if (data.getApplicationdto() != null && !decryptData.contains("车损险保额不能高于")) return data;
|
|
|
|
|
|
- List<HtCrawlerQuoteResponse.DataDTO.BasePartDTOListDTO.BasePartDTO> list =
|
|
|
+ List<HtCrawlerQuoteResponse.DataDTO.BasePartDTOListDTO.BasePartDTO> basePartDTO =
|
|
|
data.getBasepartdtolist() != null ? data.getBasepartdtolist().getBasepartdto() : null;
|
|
|
- if ((list == null || list.isEmpty()) && !decryptData.contains("车损险保额不能高于")) return data;
|
|
|
+ if ((basePartDTO == null || basePartDTO.isEmpty()) && !decryptData.contains("车损险保额不能高于")) throw new SystemException(ERR_PREFIX + convertResponseMsg(decryptData));
|
|
|
|
|
|
for (int i = 0; i < MAX_RETRIES; i++) {
|
|
|
- String basePartJSON = buildBasePartJSON(list);
|
|
|
- String response = req.quote(new HtCrawlerQuoteRequest(duplQuoteResult.q(), mealid, limitAmount, basePartJSON, personalInsuredJSON), h);
|
|
|
- log.info("resolveQuoteResponse attempt {}/{}: {}", i + 1, MAX_RETRIES, response);
|
|
|
+ String basePartJSON = buildBasePartJSON(basePartDTO);
|
|
|
+ decryptData = req.quote(new HtCrawlerQuoteRequest(duplQuoteResult.q(), mealid, limitAmount, basePartJSON, personalInsuredJSON), h);
|
|
|
+ log.info("resolveQuoteResponse attempt {}/{}: {}", i + 1, MAX_RETRIES, decryptData);
|
|
|
|
|
|
HtCrawlerQuoteResponse.DataDTO result = null;
|
|
|
try {
|
|
|
- result = JSONObject.parseObject(response, HtCrawlerQuoteResponse.DataDTO.class);
|
|
|
+ result = JSONObject.parseObject(decryptData, HtCrawlerQuoteResponse.DataDTO.class);
|
|
|
} catch (Exception e) {
|
|
|
- throw new RuntimeException(response);
|
|
|
+ throw new RuntimeException(decryptData);
|
|
|
}
|
|
|
if (result != null && result.getApplicationdto() != null) {
|
|
|
return result;
|
|
|
}
|
|
|
|
|
|
// autocheckcode 可能不准确,重新获取 quote 刷新验证码
|
|
|
- if (response.contains("录入的校验码有误") && i < MAX_RETRIES - 1) {
|
|
|
+ if (decryptData.contains("录入的校验码有误") && i < MAX_RETRIES - 1) {
|
|
|
log.warn("验证码 校验失败,重新获取 刷新验证码 (尝试 {}/{})", i + 1, MAX_RETRIES);
|
|
|
// 必须传空 basePart,接口才会返回新的 basePart 列表(含新 autocheckcode)
|
|
|
String fresh = req.quote(new HtCrawlerQuoteRequest(duplQuoteResult.q(), mealid, limitAmount, "", personalInsuredJSON), h);
|
|
|
@@ -679,9 +720,9 @@ public class HuaTaiCrawlerRequestImpl implements HuaTaiCrawlerRequest {
|
|
|
return result;
|
|
|
}
|
|
|
// 用新的 basePart 列表更新 list,下一轮循环会自动重新 buildBasePartJSON
|
|
|
- list = result != null && result.getBasepartdtolist() != null
|
|
|
+ basePartDTO = result != null && result.getBasepartdtolist() != null
|
|
|
? result.getBasepartdtolist().getBasepartdto() : null;
|
|
|
- if (list == null || list.isEmpty()) {
|
|
|
+ if (basePartDTO == null || basePartDTO.isEmpty()) {
|
|
|
return result != null ? result : data;
|
|
|
}
|
|
|
continue;
|