|
@@ -107,6 +107,7 @@ public class HuaTaiCrawlerRequestImpl implements HuaTaiCrawlerRequest {
|
|
|
private static final Pattern PAT_MEAL_ID = Pattern.compile("\"mealid\":\"(.*?)\"");
|
|
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 LIMIT_AMOUNT = Pattern.compile("value=\"(.*?)\" id=\"js_actualvalue\"");
|
|
|
private static final Pattern PAT_END_DATE = Pattern.compile("终保日期\\s*([^;]+)");
|
|
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);
|
|
|
|
|
|
|
|
private static final Set<String> SPECIAL_USERS = Set.of(
|
|
private static final Set<String> SPECIAL_USERS = Set.of(
|
|
|
"EA27000180", "EA27000401", "EA27000098", "EA27000076",
|
|
"EA27000180", "EA27000401", "EA27000098", "EA27000076",
|
|
@@ -167,22 +168,6 @@ public class HuaTaiCrawlerRequestImpl implements HuaTaiCrawlerRequest {
|
|
|
return req.authenticate(dto, HtRequestConstant.REQUEST_NUMBER);
|
|
return req.authenticate(dto, HtRequestConstant.REQUEST_NUMBER);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- // ====================== 重试工具 ======================
|
|
|
|
|
- @FunctionalInterface
|
|
|
|
|
- public interface RetryableTask<T> { T execute() throws Exception; }
|
|
|
|
|
-
|
|
|
|
|
- private <T> T retry(RetryableTask<T> task, int max, long delay, String name) {
|
|
|
|
|
- for (int i = 0; i < max; i++) {
|
|
|
|
|
- try { return task.execute(); }
|
|
|
|
|
- catch (Exception e) {
|
|
|
|
|
- log.warn("{} 失败,第 {} 次重试", name, i + 1);
|
|
|
|
|
- if (i + 1 >= max) throw new SystemException(name + " 失败,已重试 " + max + " 次", e.getMessage());
|
|
|
|
|
- sleep(delay);
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- throw new SystemException(name + " 失败,已达到最大重试次数");
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
private void sleep(long ms) {
|
|
private void sleep(long ms) {
|
|
|
try { Thread.sleep(ms); }
|
|
try { Thread.sleep(ms); }
|
|
|
catch (InterruptedException ie) { Thread.currentThread().interrupt(); throw new RuntimeException("重试被中断", ie); }
|
|
catch (InterruptedException ie) { Thread.currentThread().interrupt(); throw new RuntimeException("重试被中断", ie); }
|
|
@@ -215,7 +200,7 @@ public class HuaTaiCrawlerRequestImpl implements HuaTaiCrawlerRequest {
|
|
|
|
|
|
|
|
Map<String, Object> res = decrypt(MAPPER.readValue(
|
|
Map<String, Object> res = decrypt(MAPPER.readValue(
|
|
|
post(props.getBaseUrl() + "/htcsp/VehicleInfoEntryAction.do?cmd=xbquery", buildJsonHeaders(cookie), postData),
|
|
post(props.getBaseUrl() + "/htcsp/VehicleInfoEntryAction.do?cmd=xbquery", buildJsonHeaders(cookie), postData),
|
|
|
- HashMap.class));
|
|
|
|
|
|
|
+ Map.class));
|
|
|
log.info("xbQuery result: {}", JSONObject.toJSONString(res));
|
|
log.info("xbQuery result: {}", JSONObject.toJSONString(res));
|
|
|
|
|
|
|
|
Map<String, Object> carmodel = (Map<String, Object>) res.get("carmodeldtojson");
|
|
Map<String, Object> carmodel = (Map<String, Object>) res.get("carmodeldtojson");
|
|
@@ -262,17 +247,16 @@ public class HuaTaiCrawlerRequestImpl implements HuaTaiCrawlerRequest {
|
|
|
//带重试的获取报价编号、车型型号
|
|
//带重试的获取报价编号、车型型号
|
|
|
Map<String, Object> xbResult = retry(() -> {
|
|
Map<String, Object> xbResult = retry(() -> {
|
|
|
try { return xbQuery(dto.getUsername(), cookie, car); }
|
|
try { return xbQuery(dto.getUsername(), cookie, car); }
|
|
|
- catch (Exception e) { refreshLogin(dto); throw e; }
|
|
|
|
|
|
|
+ catch (Exception e) { refreshLogin(dto); throw new SystemException(e.getMessage()); }
|
|
|
}, MAX_RETRIES, RETRY_DELAY_MS, "预报价获取登录信息");
|
|
}, MAX_RETRIES, RETRY_DELAY_MS, "预报价获取登录信息");
|
|
|
|
|
|
|
|
String quotationNo = str(xbResult, "quotationNo");
|
|
String quotationNo = str(xbResult, "quotationNo");
|
|
|
String modelcodexh = str(xbResult, "modelcodexh");
|
|
String modelcodexh = str(xbResult, "modelcodexh");
|
|
|
//报价前预处理-保存车辆信息、过滤车型等处理
|
|
//报价前预处理-保存车辆信息、过滤车型等处理
|
|
|
PreResult pre = prepareQuote(attr, mmap, car, modelcodexh, cookie, quotationNo);
|
|
PreResult pre = prepareQuote(attr, mmap, car, modelcodexh, cookie, quotationNo);
|
|
|
- //带重试的报价
|
|
|
|
|
- CoreResult core = executeQuoteWithRetry(quoteVo, quotationNo, dto, cookie, pre, gsInfo, attr);
|
|
|
|
|
-
|
|
|
|
|
- if (!core.success()) throw new RuntimeException("报价失败,已达到最大重试次数");
|
|
|
|
|
|
|
+ //报价
|
|
|
|
|
+ CoreResult core = executeQuote(quoteVo, quotationNo, dto, cookie, pre, gsInfo, attr);
|
|
|
|
|
+ if (!core.success()) throw new SystemException("报价失败");
|
|
|
//保存订单到MongoDB
|
|
//保存订单到MongoDB
|
|
|
saveOrder(quoteVo, core);
|
|
saveOrder(quoteVo, core);
|
|
|
//组装费用
|
|
//组装费用
|
|
@@ -400,41 +384,23 @@ public class HuaTaiCrawlerRequestImpl implements HuaTaiCrawlerRequest {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// ====================== 报价核心 ======================
|
|
// ====================== 报价核心 ======================
|
|
|
- private CoreResult executeQuoteWithRetry(QuoteVo quoteVo, String quotationNo, LoginDTO dto,
|
|
|
|
|
|
|
+ private CoreResult executeQuote(QuoteVo quoteVo, String quotationNo, LoginDTO dto,
|
|
|
String cookie, PreResult pre,
|
|
String cookie, PreResult pre,
|
|
|
Map<String, Object> gsInfo, AttributionInformationVo attr) {
|
|
Map<String, Object> gsInfo, AttributionInformationVo attr) {
|
|
|
- int retry = 0;
|
|
|
|
|
String fcPrice = "";
|
|
String fcPrice = "";
|
|
|
HtCrawlerQuoteResponse.DataDTO data = null;
|
|
HtCrawlerQuoteResponse.DataDTO data = null;
|
|
|
|
|
|
|
|
- while (retry < MAX_RETRIES) {
|
|
|
|
|
- try {
|
|
|
|
|
- if (retry > 0) { log.info("第 {} 次重试,重新开始报价流程...", retry + 1); sleep(SHORT_DELAY_MS); }
|
|
|
|
|
-
|
|
|
|
|
- StepResult step = executeQuoteSteps(quoteVo, quotationNo, dto, cookie, pre, gsInfo);
|
|
|
|
|
- data = step.data();
|
|
|
|
|
-
|
|
|
|
|
- if (data.getApplicationdto() != null) {
|
|
|
|
|
- if (StringUtils.isNotBlank(step.personalInsuredJSON())) {
|
|
|
|
|
- fcPrice = fetchNoCarPremium(cookie, quotationNo, attr, step.personalInsuredJSON());
|
|
|
|
|
- }
|
|
|
|
|
- return new CoreResult(fcPrice, data, true);
|
|
|
|
|
- }
|
|
|
|
|
- log.warn("applicationdto 为 null,第 {} 次重试...", ++retry);
|
|
|
|
|
- } catch (Exception e) {
|
|
|
|
|
- if (e.getMessage() != null && e.getMessage().contains("重试次数已达上限")) throw wrap(e);
|
|
|
|
|
- log.warn("报价异常,第 {} 次重试... 异常: {}", ++retry, e.getMessage());
|
|
|
|
|
- if (retry >= MAX_RETRIES) throw new RuntimeException("报价重试次数已达上限: " + e.getMessage());
|
|
|
|
|
- sleep(RETRY_DELAY_MS);
|
|
|
|
|
|
|
+ StepResult step = executeQuoteSteps(quoteVo, quotationNo, dto, cookie, pre, gsInfo);
|
|
|
|
|
+ data = step.data();
|
|
|
|
|
+ if (data.getApplicationdto() != null) {
|
|
|
|
|
+ if (StringUtils.isNotBlank(step.personalInsuredJSON())) {
|
|
|
|
|
+ fcPrice = fetchNoCarPremium(cookie, quotationNo, attr, step.personalInsuredJSON());
|
|
|
}
|
|
}
|
|
|
|
|
+ return new CoreResult(fcPrice, data, true);
|
|
|
}
|
|
}
|
|
|
return new CoreResult(fcPrice, data, false);
|
|
return new CoreResult(fcPrice, data, false);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- private RuntimeException wrap(Exception e) {
|
|
|
|
|
- return e instanceof RuntimeException ? (RuntimeException) e : new RuntimeException(e);
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
private String fetchNoCarPremium(String cookie, String quotationNo,
|
|
private String fetchNoCarPremium(String cookie, String quotationNo,
|
|
|
AttributionInformationVo attr, String personalInsuredJSON) {
|
|
AttributionInformationVo attr, String personalInsuredJSON) {
|
|
|
try {
|
|
try {
|
|
@@ -456,7 +422,7 @@ public class HuaTaiCrawlerRequestImpl implements HuaTaiCrawlerRequest {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
private StepResult executeQuoteSteps(QuoteVo q, String quotationNo, LoginDTO dto,
|
|
private StepResult executeQuoteSteps(QuoteVo q, String quotationNo, LoginDTO dto,
|
|
|
- String cookie, PreResult pre, Map<String, Object> gsInfo) throws Exception {
|
|
|
|
|
|
|
+ String cookie, PreResult pre, Map<String, Object> gsInfo) {
|
|
|
HttpHeaders h = buildQuoteStep1Headers(cookie);
|
|
HttpHeaders h = buildQuoteStep1Headers(cookie);
|
|
|
HtCrawlerSaveOneStepRequest r = new HtCrawlerSaveOneStepRequest(q, pre.carDTO(), pre.params(), quotationNo, pre.dataDTO(), dto, gsInfo);
|
|
HtCrawlerSaveOneStepRequest r = new HtCrawlerSaveOneStepRequest(q, pre.carDTO(), pre.params(), quotationNo, pre.dataDTO(), dto, gsInfo);
|
|
|
String body = req.saveOneStept(r, h).getBody().toString();
|
|
String body = req.saveOneStept(r, h).getBody().toString();
|
|
@@ -555,25 +521,8 @@ public class HuaTaiCrawlerRequestImpl implements HuaTaiCrawlerRequest {
|
|
|
private QuoteVo handleQuoteErrors(String decryptData, QuoteVo q) {
|
|
private QuoteVo handleQuoteErrors(String decryptData, QuoteVo q) {
|
|
|
boolean hasError = decryptData.contains("erroeInfo") || decryptData.contains("errrorFlag");
|
|
boolean hasError = decryptData.contains("erroeInfo") || decryptData.contains("errrorFlag");
|
|
|
if (!hasError) return q;
|
|
if (!hasError) return q;
|
|
|
- if (decryptData.contains("本机构并未配置此险种") || decryptData.contains("重复投保的其它公司") ||
|
|
|
|
|
- (decryptData.contains("发生重复投保") && !decryptData.contains("终保日期"))) {
|
|
|
|
|
- try {
|
|
|
|
|
- throw new SystemException(MAPPER.readValue(decryptData, Map.class).get("erroeInfo").toString());
|
|
|
|
|
- } catch (JsonProcessingException e) {
|
|
|
|
|
- throw new RuntimeException(e);
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- if (decryptData.contains("发生重复投保") && decryptData.contains("终保日期")) {
|
|
|
|
|
- q = handleDuplicateInsurance(decryptData, q);
|
|
|
|
|
- return q;
|
|
|
|
|
- }
|
|
|
|
|
- if (decryptData.contains("erroeInfo") || decryptData.contains("errrorFlag")) {
|
|
|
|
|
- try {
|
|
|
|
|
- throw new SystemException(MAPPER.readValue(decryptData, Map.class).get("erroeInfo").toString());
|
|
|
|
|
- } catch (JsonProcessingException e) {
|
|
|
|
|
- throw new RuntimeException(e);
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ if (decryptData.contains("发生重复投保") && decryptData.contains("终保日期") && !decryptData.contains("重复投保的其它公司")) {
|
|
|
|
|
+ return handleDuplicateInsurance(decryptData, q);
|
|
|
}
|
|
}
|
|
|
return q;
|
|
return q;
|
|
|
}
|
|
}
|
|
@@ -598,15 +547,17 @@ public class HuaTaiCrawlerRequestImpl implements HuaTaiCrawlerRequest {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
private HtCrawlerQuoteResponse.DataDTO resolveQuoteResponse(QuoteVo q, String decryptData, String mealid, String limitAmount,
|
|
private HtCrawlerQuoteResponse.DataDTO resolveQuoteResponse(QuoteVo q, String decryptData, String mealid, String limitAmount,
|
|
|
- HttpHeaders h, String personalInsuredJSON) throws Exception {
|
|
|
|
|
- //单交不能重复投
|
|
|
|
|
- if (decryptData.contains("存在有效交强险保单") || decryptData.contains("重复投保的其它公司")) throw new Exception(decryptData);
|
|
|
|
|
|
|
+ HttpHeaders h, String personalInsuredJSON) {
|
|
|
|
|
+ if (!decryptData.contains("录入的校验码有误") && decryptData.contains("erroeInfo")) {
|
|
|
|
|
+ log.error("报价失败: {}", decryptData);
|
|
|
|
|
+ throw new SystemException(ERR_PREFIX + convertResponseMsg(decryptData));
|
|
|
|
|
+ }
|
|
|
HtCrawlerQuoteResponse.DataDTO data = JSONObject.parseObject(decryptData, HtCrawlerQuoteResponse.DataDTO.class);
|
|
HtCrawlerQuoteResponse.DataDTO data = JSONObject.parseObject(decryptData, HtCrawlerQuoteResponse.DataDTO.class);
|
|
|
if (data.getApplicationdto() != null) return data;
|
|
if (data.getApplicationdto() != null) return data;
|
|
|
|
|
|
|
|
List<HtCrawlerQuoteResponse.DataDTO.BasePartDTOListDTO.BasePartDTO> list =
|
|
List<HtCrawlerQuoteResponse.DataDTO.BasePartDTOListDTO.BasePartDTO> list =
|
|
|
data.getBasepartdtolist() != null ? data.getBasepartdtolist().getBasepartdto() : null;
|
|
data.getBasepartdtolist() != null ? data.getBasepartdtolist().getBasepartdto() : null;
|
|
|
- if (list == null || list.isEmpty() || list.size() > 3) return data;
|
|
|
|
|
|
|
+ if (list == null || list.isEmpty()) return data;
|
|
|
|
|
|
|
|
for (int i = 0; i < MAX_RETRIES; i++) {
|
|
for (int i = 0; i < MAX_RETRIES; i++) {
|
|
|
String basePartJSON = buildBasePartJSON(list);
|
|
String basePartJSON = buildBasePartJSON(list);
|
|
@@ -630,15 +581,11 @@ public class HuaTaiCrawlerRequestImpl implements HuaTaiCrawlerRequest {
|
|
|
// 用新的 basePart 列表更新 list,下一轮循环会自动重新 buildBasePartJSON
|
|
// 用新的 basePart 列表更新 list,下一轮循环会自动重新 buildBasePartJSON
|
|
|
list = result != null && result.getBasepartdtolist() != null
|
|
list = result != null && result.getBasepartdtolist() != null
|
|
|
? result.getBasepartdtolist().getBasepartdto() : null;
|
|
? result.getBasepartdtolist().getBasepartdto() : null;
|
|
|
- if (list == null || list.isEmpty() || list.size() > 3) {
|
|
|
|
|
|
|
+ if (list == null || list.isEmpty()) {
|
|
|
return result != null ? result : data;
|
|
return result != null ? result : data;
|
|
|
}
|
|
}
|
|
|
continue;
|
|
continue;
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
- if (response.contains("erroeInfo")) {
|
|
|
|
|
- throw new Exception(ERR_PREFIX + JSONObject.parseObject(response, HtCrawlerQuoteResponse.DataErrDTO.class).getErroeInfo());
|
|
|
|
|
- }
|
|
|
|
|
return result != null ? result : data;
|
|
return result != null ? result : data;
|
|
|
}
|
|
}
|
|
|
return data;
|
|
return data;
|
|
@@ -649,7 +596,6 @@ public class HuaTaiCrawlerRequestImpl implements HuaTaiCrawlerRequest {
|
|
|
String basePartJSON = "";
|
|
String basePartJSON = "";
|
|
|
if (size == 1) {
|
|
if (size == 1) {
|
|
|
HtCrawlerQuoteResponse.DataDTO.BasePartDTOListDTO.BasePartDTO basePartDTO = list.get(0);
|
|
HtCrawlerQuoteResponse.DataDTO.BasePartDTOListDTO.BasePartDTO basePartDTO = list.get(0);
|
|
|
- log.info("buildBasePartJSON0: {}, {}", size, JSONObject.toJSONString(basePartDTO));
|
|
|
|
|
String querrysequenceno = basePartDTO.getQuerrysequenceno();
|
|
String querrysequenceno = basePartDTO.getQuerrysequenceno();
|
|
|
String autocheckcode = basePartDTO.getAutocheckcode();
|
|
String autocheckcode = basePartDTO.getAutocheckcode();
|
|
|
String riskfalg = "0".equals(querrysequenceno.substring(0, 1)) ? "0" : "1";
|
|
String riskfalg = "0".equals(querrysequenceno.substring(0, 1)) ? "0" : "1";
|
|
@@ -657,11 +603,9 @@ public class HuaTaiCrawlerRequestImpl implements HuaTaiCrawlerRequest {
|
|
|
}
|
|
}
|
|
|
if (size == 2) {
|
|
if (size == 2) {
|
|
|
HtCrawlerQuoteResponse.DataDTO.BasePartDTOListDTO.BasePartDTO basePartDTO = list.get(0);
|
|
HtCrawlerQuoteResponse.DataDTO.BasePartDTOListDTO.BasePartDTO basePartDTO = list.get(0);
|
|
|
- log.info("buildBasePartJSON0: {}, {}", size, JSONObject.toJSONString(basePartDTO));
|
|
|
|
|
String querrysequenceno = basePartDTO.getQuerrysequenceno();
|
|
String querrysequenceno = basePartDTO.getQuerrysequenceno();
|
|
|
String autocheckcode = basePartDTO.getAutocheckcode();
|
|
String autocheckcode = basePartDTO.getAutocheckcode();
|
|
|
HtCrawlerQuoteResponse.DataDTO.BasePartDTOListDTO.BasePartDTO basePartDTO1 = list.get(1);
|
|
HtCrawlerQuoteResponse.DataDTO.BasePartDTOListDTO.BasePartDTO basePartDTO1 = list.get(1);
|
|
|
- log.info("buildBasePartJSON1: {}, {}", size, JSONObject.toJSONString(basePartDTO1));
|
|
|
|
|
String querrysequenceno1 = basePartDTO1.getQuerrysequenceno();
|
|
String querrysequenceno1 = basePartDTO1.getQuerrysequenceno();
|
|
|
String autocheckcode1 = basePartDTO1.getAutocheckcode();
|
|
String autocheckcode1 = basePartDTO1.getAutocheckcode();
|
|
|
basePartJSON = "[{'riskfalg':'0','checktype':2,'querysequenceno':'"+querrysequenceno1+"','checkcode':'"+autocheckcode1+"','answer':''}," +
|
|
basePartJSON = "[{'riskfalg':'0','checktype':2,'querysequenceno':'"+querrysequenceno1+"','checkcode':'"+autocheckcode1+"','answer':''}," +
|
|
@@ -669,15 +613,12 @@ public class HuaTaiCrawlerRequestImpl implements HuaTaiCrawlerRequest {
|
|
|
}
|
|
}
|
|
|
if (size == 3) {
|
|
if (size == 3) {
|
|
|
HtCrawlerQuoteResponse.DataDTO.BasePartDTOListDTO.BasePartDTO basePartDTO = list.get(0);
|
|
HtCrawlerQuoteResponse.DataDTO.BasePartDTOListDTO.BasePartDTO basePartDTO = list.get(0);
|
|
|
- log.info("buildBasePartJSON0: {}, {}", size, JSONObject.toJSONString(basePartDTO));
|
|
|
|
|
String querrysequenceno = basePartDTO.getQuerrysequenceno();
|
|
String querrysequenceno = basePartDTO.getQuerrysequenceno();
|
|
|
String autocheckcode = basePartDTO.getAutocheckcode();
|
|
String autocheckcode = basePartDTO.getAutocheckcode();
|
|
|
HtCrawlerQuoteResponse.DataDTO.BasePartDTOListDTO.BasePartDTO basePartDTO1 = list.get(1);
|
|
HtCrawlerQuoteResponse.DataDTO.BasePartDTOListDTO.BasePartDTO basePartDTO1 = list.get(1);
|
|
|
- log.info("buildBasePartJSON1: {}, {}", size, JSONObject.toJSONString(basePartDTO1));
|
|
|
|
|
String querrysequenceno1 = basePartDTO1.getQuerrysequenceno();
|
|
String querrysequenceno1 = basePartDTO1.getQuerrysequenceno();
|
|
|
String autocheckcode1 = basePartDTO1.getAutocheckcode();
|
|
String autocheckcode1 = basePartDTO1.getAutocheckcode();
|
|
|
HtCrawlerQuoteResponse.DataDTO.BasePartDTOListDTO.BasePartDTO basePartDTO2 = list.get(2);
|
|
HtCrawlerQuoteResponse.DataDTO.BasePartDTOListDTO.BasePartDTO basePartDTO2 = list.get(2);
|
|
|
- log.info("buildBasePartJSON2: {}, {}", size, JSONObject.toJSONString(basePartDTO2));
|
|
|
|
|
String querrysequenceno2 = basePartDTO2.getQuerrysequenceno();
|
|
String querrysequenceno2 = basePartDTO2.getQuerrysequenceno();
|
|
|
String autocheckcode2 = basePartDTO2.getAutocheckcode();
|
|
String autocheckcode2 = basePartDTO2.getAutocheckcode();
|
|
|
basePartJSON = "[{'riskfalg':'0','checktype':2,'querysequenceno':'"+querrysequenceno1+"','checkcode':'"+autocheckcode1+"','answer':''}," +
|
|
basePartJSON = "[{'riskfalg':'0','checktype':2,'querysequenceno':'"+querrysequenceno1+"','checkcode':'"+autocheckcode1+"','answer':''}," +
|
|
@@ -704,7 +645,7 @@ public class HuaTaiCrawlerRequestImpl implements HuaTaiCrawlerRequest {
|
|
|
Map<String, Object> map = MAPPER.readValue(res, Map.class);
|
|
Map<String, Object> map = MAPPER.readValue(res, Map.class);
|
|
|
|
|
|
|
|
if (isUnderwritingFailed(order.getCiCategory(), map, res)) {
|
|
if (isUnderwritingFailed(order.getCiCategory(), map, res)) {
|
|
|
- throw new SystemException("核保失败-------" + map.get("MSG"));
|
|
|
|
|
|
|
+ throw new SystemException("核保失败-------" + convertResponseMsg(map.get("MSG").toString()));
|
|
|
}
|
|
}
|
|
|
if (res.contains("起保时间不正确")) {
|
|
if (res.contains("起保时间不正确")) {
|
|
|
throw new SystemException("起保时间不正确-------即时起保分钟数必须为00/15/30/45\n请重新选择起保时间!");
|
|
throw new SystemException("起保时间不正确-------即时起保分钟数必须为00/15/30/45\n请重新选择起保时间!");
|
|
@@ -755,10 +696,7 @@ public class HuaTaiCrawlerRequestImpl implements HuaTaiCrawlerRequest {
|
|
|
}
|
|
}
|
|
|
int s = html.indexOf("原因"), e = html.lastIndexOf("。");
|
|
int s = html.indexOf("原因"), e = html.lastIndexOf("。");
|
|
|
throw new SystemException("审核未通过:" + (s >= 0 && e > s ? html.substring(s, e) : "审核未通过"));
|
|
throw new SystemException("审核未通过:" + (s >= 0 && e > s ? html.substring(s, e) : "审核未通过"));
|
|
|
- } catch (SystemException se) { throw se; }
|
|
|
|
|
- catch (Exception e) {
|
|
|
|
|
- throw new SystemException(e.getMessage());
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ } catch (Exception e) { throw new SystemException(e.getMessage()); }
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
private UnderwritingResultsVo handlePassedUnderwriting(HtCrawlerOrder order, HtCrawlerConfigureParameters params, UnderwritingVo vo) {
|
|
private UnderwritingResultsVo handlePassedUnderwriting(HtCrawlerOrder order, HtCrawlerConfigureParameters params, UnderwritingVo vo) {
|
|
@@ -846,7 +784,7 @@ public class HuaTaiCrawlerRequestImpl implements HuaTaiCrawlerRequest {
|
|
|
} catch (Exception e) { throw new RuntimeException(e); }
|
|
} catch (Exception e) { throw new RuntimeException(e); }
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- private Map fetchUploadInitParam(String token) {
|
|
|
|
|
|
|
+ private Map<String, Object> fetchUploadInitParam(String token) {
|
|
|
HttpHeaders h = new HttpHeaders();
|
|
HttpHeaders h = new HttpHeaders();
|
|
|
h.set(HtRequestConstant.COOKIE, req.getCookie());
|
|
h.set(HtRequestConstant.COOKIE, req.getCookie());
|
|
|
h.set("Accept", "application/json, text/plain, */*");
|
|
h.set("Accept", "application/json, text/plain, */*");
|
|
@@ -1074,6 +1012,22 @@ public class HuaTaiCrawlerRequestImpl implements HuaTaiCrawlerRequest {
|
|
|
});
|
|
});
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ // ====================== 重试工具 ======================
|
|
|
|
|
+ @FunctionalInterface
|
|
|
|
|
+ public interface RetryableTask<T> { T execute() throws Exception; }
|
|
|
|
|
+
|
|
|
|
|
+ private <T> T retry(RetryableTask<T> task, int max, long delay, String name) {
|
|
|
|
|
+ for (int i = 0; i < max; i++) {
|
|
|
|
|
+ try { return task.execute(); }
|
|
|
|
|
+ catch (Exception e) {
|
|
|
|
|
+ log.warn("{} 失败,第 {} 次重试", name, i + 1);
|
|
|
|
|
+ if (i + 1 >= max) throw new SystemException(name + " 失败,已重试 " + max + " 次", e.getMessage());
|
|
|
|
|
+ sleep(delay);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ throw new SystemException(name + " 失败,已达到最大重试次数");
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
// ====================== HTTP 通用工具 ======================
|
|
// ====================== HTTP 通用工具 ======================
|
|
|
private String get(String url, HttpHeaders headers, MultiValueMap<String, String> params) {
|
|
private String get(String url, HttpHeaders headers, MultiValueMap<String, String> params) {
|
|
|
UriComponentsBuilder b = UriComponentsBuilder.fromHttpUrl(url);
|
|
UriComponentsBuilder b = UriComponentsBuilder.fromHttpUrl(url);
|
|
@@ -1087,7 +1041,7 @@ public class HuaTaiCrawlerRequestImpl implements HuaTaiCrawlerRequest {
|
|
|
|
|
|
|
|
@SuppressWarnings("unchecked")
|
|
@SuppressWarnings("unchecked")
|
|
|
private Map<String, Object> exchangeForm(String url, Map<String, String> queryParams,
|
|
private Map<String, Object> exchangeForm(String url, Map<String, String> queryParams,
|
|
|
- MultiValueMap<String, String> data, HttpHeaders headers) throws JsonProcessingException {
|
|
|
|
|
|
|
+ MultiValueMap<String, String> data, HttpHeaders headers) throws JsonProcessingException {
|
|
|
UriComponentsBuilder b = UriComponentsBuilder.fromHttpUrl(url);
|
|
UriComponentsBuilder b = UriComponentsBuilder.fromHttpUrl(url);
|
|
|
if (queryParams != null) queryParams.forEach(b::queryParam);
|
|
if (queryParams != null) queryParams.forEach(b::queryParam);
|
|
|
String body = RT.exchange(b.toUriString(), HttpMethod.POST, new HttpEntity<>(data, headers), String.class).getBody();
|
|
String body = RT.exchange(b.toUriString(), HttpMethod.POST, new HttpEntity<>(data, headers), String.class).getBody();
|
|
@@ -1153,4 +1107,24 @@ public class HuaTaiCrawlerRequestImpl implements HuaTaiCrawlerRequest {
|
|
|
}
|
|
}
|
|
|
return m;
|
|
return m;
|
|
|
}
|
|
}
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 提取 (infoName + infomsg) 或者 erroeInfo 拼接字符串
|
|
|
|
|
+ */
|
|
|
|
|
+ public static String convertResponseMsg(String responseStr) {
|
|
|
|
|
+ Matcher matcher = RESPONSE_ERR.matcher(responseStr);
|
|
|
|
|
+ StringBuilder sb = new StringBuilder();
|
|
|
|
|
+ while (matcher.find()) {
|
|
|
|
|
+ if (matcher.group(2) != null && matcher.group(3) != null) {
|
|
|
|
|
+ // 场景1:infoName + infomsg
|
|
|
|
|
+ String infoName = matcher.group(2).trim();
|
|
|
|
|
+ String infomsg = matcher.group(3).trim();
|
|
|
|
|
+ sb.append(infoName).append(":").append(infomsg).append("\n");
|
|
|
|
|
+ } else if (matcher.group(4) != null) {
|
|
|
|
|
+ // 场景2:erroeInfo 单独错误
|
|
|
|
|
+ sb.append(matcher.group(4).trim()).append("\n");
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ if (StringUtils.isBlank(sb)) sb.append(responseStr);
|
|
|
|
|
+ return sb.toString().trim();
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|