Parcourir la source

华泰-处理报价车型异常的逻辑调整问题

lixiaolong il y a 3 mois
Parent
commit
0e88e2811c

+ 70 - 139
tenant/insurance/quotation-huatai/src/main/java/com/jzg/quotation/huatai/crawler/service/Impl/HuaTaiCrawlerRequestImpl.java

@@ -436,84 +436,69 @@ public class HuaTaiCrawlerRequestImpl implements HuaTaiCrawlerRequest {
 
     private StepResult executeQuoteSteps(QuoteVo q, String quotationNo, LoginDTO dto,
                                          String cookie, PreResult pre, Map<String, Object> gsInfo) {
-        // 初始化重试次数和最大重试阈值
-        int modelCodeRetryCount = 0;
-        final int MAX_MODEL_CODE_RETRY = 2; // 限制最大重试次数,避免死循环
-        String currentModelCodexh = pre.carDTO().getModelcodexh();
         PreResult currentPre = pre;
-        while (modelCodeRetryCount < MAX_MODEL_CODE_RETRY) {
-            String decryptData = "";
-            try {
-                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);
-                //机动车损失保险
-                String limitAmount = extractLimitAmount(body);
-                log.info("mealid: {}", mealid);
-                log.info("limitAmount: {}", limitAmount);
-                //组装驾意险参数,没有就空字符串
-                String personalInsuredJSON = buildPersonalInsuredJSON(q);
-
-                h = buildQuoteStep2Headers(cookie);
-                //组装报价参数
-                HtCrawlerQuoteRequest qr = new HtCrawlerQuoteRequest(q, mealid, limitAmount, "", personalInsuredJSON);
-                //报价第一次
-                decryptData = req.quote(qr, h);
-                //处理重复投保返回终保日期的
-                DuplQuoteResult duplQuoteResult = handleQuoteErrors(decryptData, q);
-                if (duplQuoteResult.dupl()) {
-                    qr = new HtCrawlerQuoteRequest(duplQuoteResult.q(), mealid, limitAmount, "", personalInsuredJSON);
-                    decryptData = req.quote(qr, h);
-                }
+        String decryptData = "";
+        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);
+        //机动车损失保险
+        String limitAmount = extractLimitAmount(body);
+        log.info("mealid: {}", mealid);
+        log.info("limitAmount: {}", limitAmount);
+        //组装驾意险参数,没有就空字符串
+        String personalInsuredJSON = buildPersonalInsuredJSON(q);
+
+        h = buildQuoteStep2Headers(cookie);
+        //组装报价参数
+        HtCrawlerQuoteRequest qr = new HtCrawlerQuoteRequest(q, mealid, limitAmount, "", personalInsuredJSON);
+        //报价第一次
+        decryptData = req.quote(qr, h);
+        //处理重复投保返回终保日期的
+        DuplQuoteResult duplQuoteResult = handleQuoteErrors(decryptData, q);
+        if (duplQuoteResult.dupl()) {
+            qr = new HtCrawlerQuoteRequest(duplQuoteResult.q(), mealid, limitAmount, "", personalInsuredJSON);
+            decryptData = req.quote(qr, h);
+        }
+
+        // 处理报价响应各种结果
+        HtCrawlerQuoteResponse.DataDTO data = null;
+        try {
+            data = resolveQuoteResponse(duplQuoteResult, decryptData, mealid,
+                    limitAmount, h, personalInsuredJSON);
+        } catch (Exception e) {
+            log.info("车型异常或其他错误的报价结果: {}", decryptData);
+            decryptData = e.getMessage();
+            // 检测modelcodexh不在平台车型范围内的异常在这里处理,需要重走新查车型流程再报价
+            if (decryptData.contains("errrorFlag") && decryptData.contains("carChange")) {
 
-                // 处理可能的录入的校验码有误
-                HtCrawlerQuoteResponse.DataDTO data = null;
+                // 提取新的modelcodexh
+                Map<String, Object> map = null;
                 try {
-                    data = resolveQuoteResponse(duplQuoteResult, decryptData, mealid,
-                            limitAmount, h, personalInsuredJSON);
-                } catch (Exception e) {
-                    decryptData = e.getMessage();
-                    // 检测modelcodexh不在平台车型范围内的异常
-                    if (decryptData.contains("errrorFlag") && decryptData.contains("carChange")) {
-                        modelCodeRetryCount++;
-                        log.warn("检测到modelcodexh[{}]不在平台车型范围内,开始第{}次重试获取新编码",
-                                currentModelCodexh, modelCodeRetryCount);
-
-                        // 提取新的modelcodexh
-                        Map<String, Object> map = MAPPER.readValue(decryptData, Map.class);
-                        List<Map<String, String>> list = (List)map.get("carModelList");
-                        String newModelCodexh = list.get(0).get("vehiclecode");
-
-                        currentModelCodexh = newModelCodexh;
-
-                        // 重新执行报价预处理流程
-                        AttributionInformationVo attr = q.getOrder().getAttributionInformationVo();
-                        log.info(map.get("unMatchVehicleFrameMessage")+"已重新执行prepareQuote,新modelcodexh:{}", currentModelCodexh);
-                        currentPre = prepareQuote(attr, gsInfo, q.getCarInfoVo(),
-                                currentModelCodexh, cookie, quotationNo, map);
-                        executeQuoteSteps(q, quotationNo, dto, cookie, currentPre, gsInfo);
-
-                        // 跳过当前循环,重新执行报价流程
-                        continue;
-                    } else {
-                        throw new SystemException(decryptData);
-                    }
+                    map = MAPPER.readValue(decryptData, Map.class);
+                } catch (JsonProcessingException ex) {
+                    throw new RuntimeException(ex);
                 }
-                return new StepResult(data, personalInsuredJSON);
+                List<Map<String, String>> list = (List)map.get("carModelList");
+                String newModelCodexh = list.get(0).get("vehiclecode");
 
-            } catch (Exception e) {
-                modelCodeRetryCount++;
-                if (modelCodeRetryCount >= MAX_MODEL_CODE_RETRY) {
-                    throw new SystemException(decryptData);
+                // 重新执行报价预处理流程
+                AttributionInformationVo attr = q.getOrder().getAttributionInformationVo();
+                log.info(map.get("unMatchVehicleFrameMessage")+"已重新执行prepareQuote,新modelcodexh:{}", newModelCodexh);
+                try {
+                    currentPre = prepareQuote(attr, gsInfo, q.getCarInfoVo(),
+                            newModelCodexh, cookie, quotationNo, map);
+                } catch (Exception ex) {
+                    throw new RuntimeException(ex);
                 }
-                // 重试前短暂休眠,避免高频请求
-                sleep(SHORT_DELAY_MS);
+                executeQuoteSteps(q, quotationNo, dto, cookie, currentPre, gsInfo);
+            } else {
+                throw new SystemException(decryptData);
             }
         }
-        throw new SystemException("报价失败");
+        return new StepResult(data, personalInsuredJSON);
     }
 
     private String extractMealId(String body) {
@@ -661,10 +646,6 @@ public class HuaTaiCrawlerRequestImpl implements HuaTaiCrawlerRequest {
             }
         }
         if (decryptData.contains("传送了车辆过户标志,请确认")) {
-            //HtCrawlerQuoteResponse.DataDTO dataDTO = JSONObject.parseObject(decryptData, HtCrawlerQuoteResponse.DataDTO.class);
-            //List<HtCrawlerQuoteResponse.DataDTO.BasePartDTOListDTO.BasePartDTO> basePartDTO =
-            //        dataDTO.getBasepartdtolist() != null ? dataDTO.getBasepartdtolist().getBasepartdto() : null;
-            //String basePartJSON = buildBasePartJSON(basePartDTO==null?new ArrayList<>():basePartDTO);
             Pattern pattern = Pattern.compile(TRANSFER_FLAG.pattern());
             Matcher matcher = pattern.matcher(decryptData);
             String transferFlag =  "";
@@ -672,82 +653,32 @@ public class HuaTaiCrawlerRequestImpl implements HuaTaiCrawlerRequest {
             decryptData = req.quote(new HtCrawlerQuoteRequest(duplQuoteResult.q(), mealid, limitAmount+","+transferFlag, "", personalInsuredJSON), h);
             return resolveQuoteResponse(duplQuoteResult, decryptData, mealid, limitAmount, h, personalInsuredJSON);
         }
-        if (!decryptData.contains("录入的校验码有误") && decryptData.contains("erroeInfo") && !duplQuoteResult.dupl()) {
+
+        // autocheckcode 可能不准确,重新获取 quote 刷新验证码
+        if (decryptData.contains("录入的校验码有误")) {
+            // 必须传空 basePart,接口才会返回新的 basePart 列表(含新 autocheckcode)
+            String fresh = req.quote(new HtCrawlerQuoteRequest(duplQuoteResult.q(), mealid, limitAmount, "", personalInsuredJSON), h);
+            return resolveQuoteResponse(duplQuoteResult, fresh, mealid, limitAmount, h, personalInsuredJSON);
+        }
+
+        if (decryptData.contains("erroeInfo")) {
+            log.error("报价失败: {}", decryptData);
             log.error("报价失败: {}", convertResponseMsg(decryptData));
             throw new SystemException(ERR_PREFIX + convertResponseMsg(decryptData));
         }
         HtCrawlerQuoteResponse.DataDTO data = null;
         data = JSONObject.parseObject(decryptData, HtCrawlerQuoteResponse.DataDTO.class);
 
-        if (data.getApplicationdto() != null && !decryptData.contains("车损险保额不能高于")) return data;
+        if (data.getApplicationdto() != null) return data;
 
         List<HtCrawlerQuoteResponse.DataDTO.BasePartDTOListDTO.BasePartDTO> basePartDTO =
                 data.getBasepartdtolist() != null ? data.getBasepartdtolist().getBasepartdto() : null;
-        if ((basePartDTO == null || basePartDTO.isEmpty()) && !decryptData.contains("车损险保额不能高于")) throw new SystemException(ERR_PREFIX + convertResponseMsg(decryptData));
+        if ((basePartDTO == null || basePartDTO.isEmpty())) throw new SystemException(ERR_PREFIX + convertResponseMsg(decryptData));
 
-        for (int i = 0; i < MAX_RETRIES; i++) {
-            String basePartJSON = buildBasePartJSON(basePartDTO);
+        String basePartJSON = buildBasePartJSON(basePartDTO);
+        if (StringUtils.isNotBlank(basePartJSON)) {
             decryptData = req.quote(new HtCrawlerQuoteRequest(duplQuoteResult.q(), mealid, limitAmount, basePartJSON, personalInsuredJSON), h);
-            log.info("resolveQuoteResponse attempt {}/{}: {}", i + 1, MAX_RETRIES, decryptData);
-
-            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_DATE2.matcher(decryptData);
-                    if (m.find()) {
-                        String jiaoqiang_startDate = m.group(1);
-                        log.info("报价响应结果CI,终保日期{}", jiaoqiang_startDate);
-                        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).format(DateTimeFormatter.ofPattern(DATE_FMT));
-                        duplQuoteResult.q().getCiRiskInfoVo().setEndDate(newEnd);
-                        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_DATE2.matcher(decryptData);
-                    if (m.find()) {
-                        String chesun_startDate = m.group(1);
-                        log.info("报价响应结果BI,终保日期{}", chesun_startDate);
-                        duplQuoteResult.q().getBiRiskInfoVo().setStartDate(chesun_startDate);
-                        LocalDateTime dt = LocalDateTime.parse(chesun_startDate.replace(" ", "T"), DateTimeFormatter.ofPattern(DATE_FMT_T));
-                        String newEnd = dt.plusYears(1).format(DateTimeFormatter.ofPattern(DATE_FMT));
-                        duplQuoteResult.q().getBiRiskInfoVo().setEndDate(newEnd);
-                        decryptData = req.quote(new HtCrawlerQuoteRequest(duplQuoteResult.q(), mealid, limitAmount, "", personalInsuredJSON), h);
-                        return resolveQuoteResponse(duplQuoteResult, decryptData, mealid, limitAmount, h, personalInsuredJSON);
-                    }
-                }
-            }
-
-            HtCrawlerQuoteResponse.DataDTO result = null;
-            try {
-                result = JSONObject.parseObject(decryptData, HtCrawlerQuoteResponse.DataDTO.class);
-            } catch (Exception e) {
-                throw new RuntimeException(decryptData);
-            }
-            if (result != null && result.getApplicationdto() != null) {
-                return result;
-            }
-
-            // autocheckcode 可能不准确,重新获取 quote 刷新验证码
-            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);
-                result = JSONObject.parseObject(fresh, HtCrawlerQuoteResponse.DataDTO.class);
-                if (result != null && result.getApplicationdto() != null) {
-                    return result;
-                }
-                // 用新的 basePart 列表更新 list,下一轮循环会自动重新 buildBasePartJSON
-                basePartDTO = result != null && result.getBasepartdtolist() != null
-                        ? result.getBasepartdtolist().getBasepartdto() : null;
-                if (basePartDTO == null || basePartDTO.isEmpty()) {
-                    return result != null ? result : data;
-                }
-                continue;
-            }
-            return result != null ? result : data;
+            return resolveQuoteResponse(duplQuoteResult, decryptData, mealid, limitAmount, h, personalInsuredJSON);
         }
         return data;
     }