|
|
@@ -2,6 +2,8 @@ package com.jzg.quotation.huatai.crawler.service.Impl;
|
|
|
|
|
|
import com.alibaba.fastjson.JSONObject;
|
|
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
|
|
+import com.fasterxml.jackson.core.type.TypeReference;
|
|
|
+import com.fasterxml.jackson.databind.DeserializationFeature;
|
|
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
|
|
import com.jzg.commons.constants.ProductsType;
|
|
|
import com.jzg.commons.constants.dict.InsOrderStatusEnum;
|
|
|
@@ -325,13 +327,35 @@ public class HuaTaiCrawlerRequestImpl implements HuaTaiCrawlerRequest {
|
|
|
//车辆查询
|
|
|
HtCrawlerCarQueryResponse.DataDTO dataDTO = req.carQuery(
|
|
|
new HtCrawlerCarQueryRequest(car, modelcodexh), req.getHeaders1(), car);
|
|
|
- //过滤车型
|
|
|
+ //过滤车辆
|
|
|
HtCrawlerCarQueryResponse.DataDTO.DataListDTO carDTO = CarModelsFilterUtils.to(dataDTO.getDatalist(), car);
|
|
|
log.info("过滤后的车型carDTO: {}", JSONObject.toJSONString(carDTO));
|
|
|
//保存车辆信息
|
|
|
executeSaveCarQuery(carDTO, dataDTO, car, cookie);
|
|
|
//车型查询
|
|
|
- executeCarModelCodexhQuery(carDTO, car, cookie, quotationNo);
|
|
|
+ String carData = executeCarModelCodexhQuery(carDTO, car, cookie, quotationNo);
|
|
|
+ // 核心:关闭「未知字段抛出异常」,优先级 > 类注解
|
|
|
+ MAPPER.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
|
|
|
+ // 可选:兼容空字符串、大小写字段(对接第三方接口常用)
|
|
|
+ MAPPER.configure(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT, true);
|
|
|
+ Map<String, Object> rootMap = MAPPER.readValue(carData, new TypeReference<Map<String, Object>>() {});
|
|
|
+ String datalistStr = (String) rootMap.get("datalist");
|
|
|
+ String datalist2Str = (String) rootMap.get("datalist2");
|
|
|
+ if (StringUtils.hasText(datalistStr) && StringUtils.hasText(datalist2Str)) {
|
|
|
+ List<HtCrawlerCarQueryResponse.DataDTO.DataListDTO> dataList = new ArrayList<>();
|
|
|
+ if (StringUtils.hasText(datalistStr)) {
|
|
|
+ dataList = MAPPER.readValue(datalistStr, new TypeReference<List<HtCrawlerCarQueryResponse.DataDTO.DataListDTO>>() {});
|
|
|
+ }
|
|
|
+ List<HtCrawlerCarQueryResponse.DataDTO.DataList2DTO> dataList2 = new ArrayList<>();
|
|
|
+ if (StringUtils.hasText(datalist2Str)) {
|
|
|
+ dataList2 = MAPPER.readValue(datalist2Str, new TypeReference<List<HtCrawlerCarQueryResponse.DataDTO.DataList2DTO>>() {});
|
|
|
+ }
|
|
|
+ dataDTO = new HtCrawlerCarQueryResponse.DataDTO();
|
|
|
+ dataDTO.setDatalist(dataList);
|
|
|
+ dataDTO.setDatalist2(dataList2);
|
|
|
+ //过滤车型
|
|
|
+ carDTO = CarModelsFilterUtils.to(dataDTO.getDatalist(), car);
|
|
|
+ }
|
|
|
//额外请求
|
|
|
executeMessageCentreTimeBoom(cookie);
|
|
|
//以上请求模拟浏览器请求流程,否则报价失败
|
|
|
@@ -355,7 +379,7 @@ public class HuaTaiCrawlerRequestImpl implements HuaTaiCrawlerRequest {
|
|
|
post(BASE_URL + "/htcsp/VehicleInfoEntryAction.do?cmd=savecarquery", buildCarQueryHeaders(cookie), fd);
|
|
|
}
|
|
|
|
|
|
- private void executeCarModelCodexhQuery(HtCrawlerCarQueryResponse.DataDTO.DataListDTO carDTO,
|
|
|
+ private String executeCarModelCodexhQuery(HtCrawlerCarQueryResponse.DataDTO.DataListDTO carDTO,
|
|
|
CarInfoVo car, String cookie, String quotationNo) {
|
|
|
MultiValueMap<String, String> fd = new LinkedMultiValueMap<>();
|
|
|
fd.add("modelCode", carDTO.getModelcodexh());
|
|
|
@@ -376,7 +400,9 @@ public class HuaTaiCrawlerRequestImpl implements HuaTaiCrawlerRequest {
|
|
|
fd.add("carModelComCode", XBCOM_CODE);
|
|
|
fd.add("quotationNo", quotationNo);
|
|
|
|
|
|
- post(BASE_URL + "/htcsp/VehicleInfoEntryAction.do?cmd=carModelCodexhQuery", buildCarModelCodexhHeaders(cookie), fd);
|
|
|
+ String carDataResponse = post(BASE_URL + "/htcsp/VehicleInfoEntryAction.do?cmd=carModelCodexhQuery", buildCarModelCodexhHeaders(cookie), fd);
|
|
|
+ log.info("carModelCodexhQuery carDataResponse: {}", carDataResponse);
|
|
|
+ return carDataResponse;
|
|
|
}
|
|
|
|
|
|
private void executeMessageCentreTimeBoom(String cookie) {
|
|
|
@@ -437,6 +463,7 @@ public class HuaTaiCrawlerRequestImpl implements HuaTaiCrawlerRequest {
|
|
|
HttpHeaders h = buildQuoteStep1Headers(cookie);
|
|
|
HtCrawlerSaveOneStepRequest r = new HtCrawlerSaveOneStepRequest(q, currentPre.carDTO(),
|
|
|
currentPre.params(), quotationNo, currentPre.dataDTO(), dto, gsInfo);
|
|
|
+ log.info("saveOneStept: {}", JSONObject.toJSONString(r));
|
|
|
String body = req.saveOneStept(r, h).getBody().toString();
|
|
|
String mealid = extractMealId(body);
|
|
|
//机动车损失保险
|
|
|
@@ -604,16 +631,28 @@ public class HuaTaiCrawlerRequestImpl implements HuaTaiCrawlerRequest {
|
|
|
|
|
|
private HtCrawlerQuoteResponse.DataDTO resolveQuoteResponse(DuplQuoteResult duplQuoteResult, String decryptData, String mealid, String limitAmount,
|
|
|
HttpHeaders h, String personalInsuredJSON) {
|
|
|
+ log.info("报价结果: {}", convertResponseMsg(decryptData));
|
|
|
+ if (decryptData.contains("未传送车辆过户标志")) {
|
|
|
+ log.error("报价失败: {}", convertResponseMsg(decryptData));
|
|
|
+ throw new SystemException(ERR_PREFIX + convertResponseMsg(decryptData));
|
|
|
+ }
|
|
|
if (!decryptData.contains("录入的校验码有误") && decryptData.contains("erroeInfo") && !duplQuoteResult.dupl()) {
|
|
|
- log.error("报价失败: {}", decryptData);
|
|
|
+ log.error("报价失败: {}", convertResponseMsg(decryptData));
|
|
|
throw new SystemException(ERR_PREFIX + convertResponseMsg(decryptData));
|
|
|
}
|
|
|
+ if (decryptData.contains("车损险保额不能高于")) {
|
|
|
+ Pattern pattern = Pattern.compile("车损险保额不能高于(\\d+\\.?\\d*)元");
|
|
|
+ Matcher matcher = pattern.matcher(decryptData);
|
|
|
+ if (matcher.find()) limitAmount = matcher.group(1);
|
|
|
+ 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 (data.getApplicationdto() != null) return data;
|
|
|
+ if (data.getApplicationdto() != null && !decryptData.contains("车损险保额不能高于")) return data;
|
|
|
|
|
|
List<HtCrawlerQuoteResponse.DataDTO.BasePartDTOListDTO.BasePartDTO> list =
|
|
|
data.getBasepartdtolist() != null ? data.getBasepartdtolist().getBasepartdto() : null;
|
|
|
- if (list == null || list.isEmpty()) return data;
|
|
|
+ if ((list == null || list.isEmpty()) && !decryptData.contains("车损险保额不能高于")) return data;
|
|
|
|
|
|
for (int i = 0; i < MAX_RETRIES; i++) {
|
|
|
String basePartJSON = buildBasePartJSON(list);
|
|
|
@@ -704,36 +743,29 @@ public class HuaTaiCrawlerRequestImpl implements HuaTaiCrawlerRequest {
|
|
|
HtCrawlerSubmitRequest submit = new HtCrawlerSubmitRequest(vo, params, order.getCiCategory(), order.getBiCategory());
|
|
|
String res = req.submit2(submit, req.getHeaders());
|
|
|
log.info("提交核保结果: {}", res);
|
|
|
+
|
|
|
Map<String, Object> map = new HashMap<>();
|
|
|
try {
|
|
|
map = MAPPER.readValue(res, Map.class);
|
|
|
} catch (JsonProcessingException e) {
|
|
|
- throw new SystemException("核保失败,未知异常");
|
|
|
+ throw new SystemException("核保失败,未知异常, {}", convertResponseMsg(res));
|
|
|
}
|
|
|
|
|
|
- if (isUnderwritingFailed(order.getCiCategory(), map, res)) {
|
|
|
- throw new SystemException("核保失败-------" + convertResponseMsg(map.get("MSG").toString()));
|
|
|
+ if (!"1,2,3,4".contains(order.getCiCategory()) || "Y".equals(str(map, "isOver"))
|
|
|
+ || "重新计算保费".equals(str(map, "MSG")) || res.contains("下发修改意见") || res.contains("转人工意见")) {
|
|
|
+ throw new SystemException("核保失败-------" + convertResponseMsg(res));
|
|
|
}
|
|
|
if (res.contains("起保时间不正确")) {
|
|
|
throw new SystemException("起保时间不正确-------即时起保分钟数必须为00/15/30/45\n请重新选择起保时间!");
|
|
|
}
|
|
|
if (res.contains("转人工")) return handleManualUnderwriting(order, params);
|
|
|
- if (res.contains("已通过核保未实收") || isPassHB(map)) return handlePassedUnderwriting(order, params, vo);
|
|
|
+ if (res.contains("已通过核保未实收") || "Y".equals(str(map, "isPassHB"))) return handlePassedUnderwriting(order, params, vo);
|
|
|
|
|
|
UnderwritingResultsVo r = new UnderwritingResultsVo();
|
|
|
r.setUnderwritingStatus(InsOrderStatusEnum.WAIT_AUDIT);
|
|
|
return r;
|
|
|
}
|
|
|
|
|
|
- private boolean isUnderwritingFailed(String ci, Map<String, Object> m, String res) {
|
|
|
- return !"1,2,3,4".contains(ci)
|
|
|
- || "Y".equals(str(m, "isOver"))
|
|
|
- || "重新计算保费".equals(str(m, "MSG"))
|
|
|
- || res.contains("强制下发修改意见");
|
|
|
- }
|
|
|
-
|
|
|
- private boolean isPassHB(Map<String, Object> m) { return "Y".equals(str(m, "isPassHB")); }
|
|
|
-
|
|
|
private UnderwritingResultsVo handleManualUnderwriting(HtCrawlerOrder order, HtCrawlerConfigureParameters params) {
|
|
|
try {
|
|
|
// 提交人工核保
|