Explorar el Código

Merge branch 'master' into wrq_dev

wangrq hace 3 meses
padre
commit
d99d35bd47
Se han modificado 19 ficheros con 177 adiciones y 119 borrados
  1. 3 0
      commons/src/main/java/com/jzg/commons/entity/orders/po/InsOrderAdjust.java
  2. 4 0
      commons/src/main/java/com/jzg/commons/entity/orders/po/InsOrdersTrack.java
  3. 0 4
      commons/src/main/java/com/jzg/commons/entity/rights/po/InsOrderRights.java
  4. 0 3
      commons/src/main/java/com/jzg/commons/entity/rights/po/InsOrderRightsPackage.java
  5. 2 2
      commons/src/main/java/com/jzg/commons/entity/rights/vo/InsOrderRightsPackageVo.java
  6. 2 2
      commons/src/main/java/com/jzg/commons/entity/rights/vo/InsOrderRightsVo.java
  7. 2 2
      tenant/insurance/quotation-huatai/src/main/java/com/jzg/quotation/huatai/crawler/component/HtCrawlerRequestComponent.java
  8. 63 89
      tenant/insurance/quotation-huatai/src/main/java/com/jzg/quotation/huatai/crawler/service/Impl/HuaTaiCrawlerRequestImpl.java
  9. 1 0
      tenant/insurance/quotation-summary/src/main/java/com/jzg/quotation/summary/aop/OrderOperationLog.java
  10. 57 4
      tenant/insurance/quotation-summary/src/main/java/com/jzg/quotation/summary/aop/OrderOperationLogAspect.java
  11. 1 1
      tenant/insurance/quotation-summary/src/main/java/com/jzg/quotation/summary/constants/QuoteNumberConstant.java
  12. 15 4
      tenant/insurance/quotation-summary/src/main/java/com/jzg/quotation/summary/controller/InsFeeAuditController.java
  13. 4 0
      tenant/insurance/quotation-summary/src/main/java/com/jzg/quotation/summary/controller/UnifyOrderManager.java
  14. 14 2
      tenant/insurance/quotation-summary/src/main/java/com/jzg/quotation/summary/service/impl/InsFeeOrdersServiceImpl.java
  15. 1 1
      tenant/insurance/quotation-summary/src/main/java/com/jzg/quotation/summary/service/impl/InsOrderRightsPackageServiceImpl.java
  16. 1 1
      tenant/insurance/quotation-summary/src/main/java/com/jzg/quotation/summary/service/impl/InsOrderRightsServiceImpl.java
  17. 2 2
      tenant/insurance/quotation-summary/src/main/resources/mapper/InsOrderRightsMapper.xml
  18. 2 2
      tenant/insurance/quotation-summary/src/main/resources/mapper/InsOrderRightsPackageMapper.xml
  19. 3 0
      tenant/insurance/quotation-summary/src/main/resources/mapper/InsOrdersMapper.xml

+ 3 - 0
commons/src/main/java/com/jzg/commons/entity/orders/po/InsOrderAdjust.java

@@ -1,5 +1,6 @@
 package com.jzg.commons.entity.orders.po;
 
+import java.io.Serial;
 import java.io.Serializable;
 import java.math.BigDecimal;
 import java.util.Date;
@@ -21,6 +22,8 @@ import lombok.Data;
 @Schema(description = "订单批改表")
 public class InsOrderAdjust extends BaseModel {
 
+    @Serial
+    private static final long serialVersionUID = -1135351989246912814L;
     @Schema(description = "主键ID")
     @TableId(value = "id", type = IdType.ASSIGN_ID)
     private String id;

+ 4 - 0
commons/src/main/java/com/jzg/commons/entity/orders/po/InsOrdersTrack.java

@@ -8,6 +8,8 @@ import io.swagger.v3.oas.annotations.media.Schema;
 import lombok.Data;
 import lombok.NoArgsConstructor;
 
+import java.io.Serial;
+
 /**
  * 订单轨迹表
  * @TableName ins_orders_track
@@ -17,6 +19,8 @@ import lombok.NoArgsConstructor;
 @NoArgsConstructor
 public class InsOrdersTrack extends BaseModel {
 
+    @Serial
+    private static final long serialVersionUID = -6698449789374697351L;
     @Schema(description = "轨迹ID")
     @TableId(value = "id", type = IdType.ASSIGN_ID)
     private String id;

+ 0 - 4
commons/src/main/java/com/jzg/commons/entity/rights/po/InsOrderRights.java

@@ -78,10 +78,6 @@ public class InsOrderRights {
     /**服务说明*/
     @Schema(description = "服务说明")
     private String description;
-
-    /**是否删除(0,:否 1:是)*/
-    @Schema(description = "是否删除(0,:否 1:是)")
-    private Integer delFlag;
     /**创建者*/
     @Schema(description = "创建者")
     private String createBy;

+ 0 - 3
commons/src/main/java/com/jzg/commons/entity/rights/po/InsOrderRightsPackage.java

@@ -60,9 +60,6 @@ public class InsOrderRightsPackage {
     /**行业id*/
     @Schema(description = "行业id")
     private String industryId;
-    /**是否删除(0,:否 1:是)*/
-    @Schema(description = "是否删除(0,:否 1:是)")
-    private Integer delFlag;
     /**创建者*/
     @Schema(description = "创建者")
     private String createBy;

+ 2 - 2
commons/src/main/java/com/jzg/commons/entity/rights/vo/InsOrderRightsPackageVo.java

@@ -61,7 +61,7 @@ public class InsOrderRightsPackageVo {
     private String industryId;
     /**是否删除(0,:否 1:是)*/
     @Schema(description = "是否删除(0,:否 1:是)")
-    private Integer delFlag;
+    private Integer isDelete;
     /**创建者*/
     @Schema(description = "创建者")
     private String createBy;
@@ -144,7 +144,7 @@ public class InsOrderRightsPackageVo {
 
             this.packagePrice = rightsPackage.getPackagePrice();
             this.industryId = rightsPackage.getIndustryId();
-            this.delFlag = rightsPackage.getDelFlag();
+            this.isDelete = rightsPackage.getIsDelete();
             this.createBy = rightsPackage.getCreateBy();
             this.createTime = rightsPackage.getCreateTime();
             this.updateBy = rightsPackage.getUpdateBy();

+ 2 - 2
commons/src/main/java/com/jzg/commons/entity/rights/vo/InsOrderRightsVo.java

@@ -78,7 +78,7 @@ public class InsOrderRightsVo {
 
     /**是否删除(0,:否 1:是)*/
     @Schema(description = "是否删除(0,:否 1:是)")
-    private Integer delFlag;
+    private Integer isDelete;
     /**创建者*/
     @Schema(description = "创建者")
     private String createBy;
@@ -139,7 +139,6 @@ public class InsOrderRightsVo {
         this.contractRate = rights.getContractRate();
         this.settlePrice = rights.getSettlePrice();
         this.description = rights.getDescription();
-        this.delFlag = rights.getDelFlag();
         this.createBy = rights.getCreateBy();
         this.createTime = rights.getCreateTime();
         this.updateBy = rights.getUpdateBy();
@@ -150,6 +149,7 @@ public class InsOrderRightsVo {
         this.receiverType = rights.getReceiverType();
         this.receiverName = rights.getReceiverName();
         this.receiverMobile = rights.getReceiverMobile();
+        this.isDelete = rights.getIsDelete();
         //该订单下该权益券总价
         BigDecimal price = rights.getAmount();
         Integer count = rights.getRightsCount();

+ 2 - 2
tenant/insurance/quotation-huatai/src/main/java/com/jzg/quotation/huatai/crawler/component/HtCrawlerRequestComponent.java

@@ -152,7 +152,7 @@ public class HtCrawlerRequestComponent {
      * @param headers
      * @return
      */
-    public HtCrawlerCarQueryResponse.DataDTO carQuery(HtCrawlerCarQueryRequest htCrawlerCarQueryRequest, HttpHeaders headers, CarInfoVo carInfoVo) throws Exception {
+    public HtCrawlerCarQueryResponse.DataDTO carQuery(HtCrawlerCarQueryRequest htCrawlerCarQueryRequest, HttpHeaders headers, CarInfoVo carInfoVo) {
         List<String> cookie = headers.get("Cookie");
         log.info("huatai_cookie:{}", cookie);
         ResponseEntity<HtCrawlerCarQueryResponse> carQueryResponseEntity = requestComponent.objectPostWithProxy(RequestUrl.CAR_QUERY.getRequestUrl(huaTaiCrawlerProperties.getBaseUrl()), htCrawlerCarQueryRequest, HtCrawlerCarQueryResponse.class, headers, proxyHostName, proxyPort);
@@ -182,7 +182,7 @@ public class HtCrawlerRequestComponent {
      * @return
      * @throws Exception
      */
-    public String quote(HtCrawlerQuoteRequest htCrawlerQuoteRequest, HttpHeaders headers) throws Exception {
+    public String quote(HtCrawlerQuoteRequest htCrawlerQuoteRequest, HttpHeaders headers) {
         headers.remove("Referer");
         headers.add("Referer", "https://cspxp.pc.ehuatai.com/htcsp/VehicleInfoEntryAction.do?cmd=saveOneStept");
         ResponseEntity<HtCrawlerQuoteResponse> responseEntity = requestComponent.objectPostWithProxy(RequestUrl.QUOTE_PRICE.getRequestUrl(huaTaiCrawlerProperties.getBaseUrl()), htCrawlerQuoteRequest, HtCrawlerQuoteResponse.class, headers, proxyHostName, proxyPort);

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

@@ -107,6 +107,7 @@ public class HuaTaiCrawlerRequestImpl implements HuaTaiCrawlerRequest {
     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 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(
             "EA27000180", "EA27000401", "EA27000098", "EA27000076",
@@ -167,22 +168,6 @@ public class HuaTaiCrawlerRequestImpl implements HuaTaiCrawlerRequest {
         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) {
         try { Thread.sleep(ms); }
         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(
                 post(props.getBaseUrl() + "/htcsp/VehicleInfoEntryAction.do?cmd=xbquery", buildJsonHeaders(cookie), postData),
-                HashMap.class));
+                Map.class));
         log.info("xbQuery result: {}", JSONObject.toJSONString(res));
 
         Map<String, Object> carmodel = (Map<String, Object>) res.get("carmodeldtojson");
@@ -262,17 +247,16 @@ public class HuaTaiCrawlerRequestImpl implements HuaTaiCrawlerRequest {
         //带重试的获取报价编号、车型型号
         Map<String, Object> xbResult = retry(() -> {
             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, "预报价获取登录信息");
 
         String quotationNo = str(xbResult, "quotationNo");
         String modelcodexh = str(xbResult, "modelcodexh");
         //报价前预处理-保存车辆信息、过滤车型等处理
         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
         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,
                                              Map<String, Object> gsInfo, AttributionInformationVo attr) {
-        int retry = 0;
         String fcPrice = "";
         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);
     }
 
-    private RuntimeException wrap(Exception e) {
-        return e instanceof RuntimeException ? (RuntimeException) e : new RuntimeException(e);
-    }
-
     private String fetchNoCarPremium(String cookie, String quotationNo,
                                      AttributionInformationVo attr, String personalInsuredJSON) {
         try {
@@ -456,7 +422,7 @@ public class HuaTaiCrawlerRequestImpl implements HuaTaiCrawlerRequest {
     }
 
     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);
         HtCrawlerSaveOneStepRequest r = new HtCrawlerSaveOneStepRequest(q, pre.carDTO(), pre.params(), quotationNo, pre.dataDTO(), dto, gsInfo);
         String body = req.saveOneStept(r, h).getBody().toString();
@@ -555,25 +521,8 @@ public class HuaTaiCrawlerRequestImpl implements HuaTaiCrawlerRequest {
     private QuoteVo handleQuoteErrors(String decryptData, QuoteVo q) {
         boolean hasError = decryptData.contains("erroeInfo") || decryptData.contains("errrorFlag");
         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;
     }
@@ -598,15 +547,17 @@ public class HuaTaiCrawlerRequestImpl implements HuaTaiCrawlerRequest {
     }
 
     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);
         if (data.getApplicationdto() != null) return data;
 
         List<HtCrawlerQuoteResponse.DataDTO.BasePartDTOListDTO.BasePartDTO> list =
                 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++) {
             String basePartJSON = buildBasePartJSON(list);
@@ -630,15 +581,11 @@ public class HuaTaiCrawlerRequestImpl implements HuaTaiCrawlerRequest {
                 // 用新的 basePart 列表更新 list,下一轮循环会自动重新 buildBasePartJSON
                 list = result != null && result.getBasepartdtolist() != null
                         ? result.getBasepartdtolist().getBasepartdto() : null;
-                if (list == null || list.isEmpty() || list.size() > 3) {
+                if (list == null || list.isEmpty()) {
                     return result != null ? result : data;
                 }
                 continue;
             }
-
-            if (response.contains("erroeInfo")) {
-                throw new Exception(ERR_PREFIX + JSONObject.parseObject(response, HtCrawlerQuoteResponse.DataErrDTO.class).getErroeInfo());
-            }
             return result != null ? result : data;
         }
         return data;
@@ -649,7 +596,6 @@ public class HuaTaiCrawlerRequestImpl implements HuaTaiCrawlerRequest {
         String basePartJSON = "";
         if (size == 1) {
             HtCrawlerQuoteResponse.DataDTO.BasePartDTOListDTO.BasePartDTO basePartDTO = list.get(0);
-            log.info("buildBasePartJSON0: {}, {}", size, JSONObject.toJSONString(basePartDTO));
             String querrysequenceno = basePartDTO.getQuerrysequenceno();
             String autocheckcode = basePartDTO.getAutocheckcode();
             String riskfalg = "0".equals(querrysequenceno.substring(0, 1)) ? "0" : "1";
@@ -657,11 +603,9 @@ public class HuaTaiCrawlerRequestImpl implements HuaTaiCrawlerRequest {
         }
         if (size == 2) {
             HtCrawlerQuoteResponse.DataDTO.BasePartDTOListDTO.BasePartDTO basePartDTO = list.get(0);
-            log.info("buildBasePartJSON0: {}, {}", size, JSONObject.toJSONString(basePartDTO));
             String querrysequenceno = basePartDTO.getQuerrysequenceno();
             String autocheckcode = basePartDTO.getAutocheckcode();
             HtCrawlerQuoteResponse.DataDTO.BasePartDTOListDTO.BasePartDTO basePartDTO1 = list.get(1);
-            log.info("buildBasePartJSON1: {}, {}", size, JSONObject.toJSONString(basePartDTO1));
             String querrysequenceno1 = basePartDTO1.getQuerrysequenceno();
             String autocheckcode1 = basePartDTO1.getAutocheckcode();
             basePartJSON = "[{'riskfalg':'0','checktype':2,'querysequenceno':'"+querrysequenceno1+"','checkcode':'"+autocheckcode1+"','answer':''}," +
@@ -669,15 +613,12 @@ public class HuaTaiCrawlerRequestImpl implements HuaTaiCrawlerRequest {
         }
         if (size == 3) {
             HtCrawlerQuoteResponse.DataDTO.BasePartDTOListDTO.BasePartDTO basePartDTO = list.get(0);
-            log.info("buildBasePartJSON0: {}, {}", size, JSONObject.toJSONString(basePartDTO));
             String querrysequenceno = basePartDTO.getQuerrysequenceno();
             String autocheckcode = basePartDTO.getAutocheckcode();
             HtCrawlerQuoteResponse.DataDTO.BasePartDTOListDTO.BasePartDTO basePartDTO1 = list.get(1);
-            log.info("buildBasePartJSON1: {}, {}", size, JSONObject.toJSONString(basePartDTO1));
             String querrysequenceno1 = basePartDTO1.getQuerrysequenceno();
             String autocheckcode1 = basePartDTO1.getAutocheckcode();
             HtCrawlerQuoteResponse.DataDTO.BasePartDTOListDTO.BasePartDTO basePartDTO2 = list.get(2);
-            log.info("buildBasePartJSON2: {}, {}", size, JSONObject.toJSONString(basePartDTO2));
             String querrysequenceno2 = basePartDTO2.getQuerrysequenceno();
             String autocheckcode2 = basePartDTO2.getAutocheckcode();
             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);
 
         if (isUnderwritingFailed(order.getCiCategory(), map, res)) {
-            throw new SystemException("核保失败-------" + map.get("MSG"));
+            throw new SystemException("核保失败-------" + convertResponseMsg(map.get("MSG").toString()));
         }
         if (res.contains("起保时间不正确")) {
             throw new SystemException("起保时间不正确-------即时起保分钟数必须为00/15/30/45\n请重新选择起保时间!");
@@ -755,10 +696,7 @@ public class HuaTaiCrawlerRequestImpl implements HuaTaiCrawlerRequest {
             }
             int s = html.indexOf("原因"), e = html.lastIndexOf("。");
             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) {
@@ -846,7 +784,7 @@ public class HuaTaiCrawlerRequestImpl implements HuaTaiCrawlerRequest {
         } catch (Exception e) { throw new RuntimeException(e); }
     }
 
-    private Map fetchUploadInitParam(String token) {
+    private Map<String, Object> fetchUploadInitParam(String token) {
         HttpHeaders h = new HttpHeaders();
         h.set(HtRequestConstant.COOKIE, req.getCookie());
         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 通用工具 ======================
     private String get(String url, HttpHeaders headers, MultiValueMap<String, String> params) {
         UriComponentsBuilder b = UriComponentsBuilder.fromHttpUrl(url);
@@ -1087,7 +1041,7 @@ public class HuaTaiCrawlerRequestImpl implements HuaTaiCrawlerRequest {
 
     @SuppressWarnings("unchecked")
     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);
         if (queryParams != null) queryParams.forEach(b::queryParam);
         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;
     }
+    /**
+     * 提取 (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();
+    }
 }

+ 1 - 0
tenant/insurance/quotation-summary/src/main/java/com/jzg/quotation/summary/aop/OrderOperationLog.java

@@ -16,4 +16,5 @@ public @interface OrderOperationLog {
     String description() default "";   // 说明
     String feedbackSpEl() default ""; // 使用 SpEL 表达式提取返回字段(可选)
     String orderSpEl() default "";  // NEW: 用 SpEL 指定 入参 提取路径
+
 }

+ 57 - 4
tenant/insurance/quotation-summary/src/main/java/com/jzg/quotation/summary/aop/OrderOperationLogAspect.java

@@ -1,8 +1,9 @@
 package com.jzg.quotation.summary.aop;
 
+import cn.hutool.json.JSONUtil;
 import com.alibaba.fastjson2.JSON;
-import com.fasterxml.jackson.databind.ObjectMapper;
 import com.jzg.commons.constants.dict.InsOrderStatusEnum;
+import com.jzg.commons.core.page.HttpResult;
 import com.jzg.commons.entity.dto.VerifyAdjustParam;
 import com.jzg.commons.entity.orders.po.InsOrderAdjust;
 import com.jzg.commons.entity.orders.po.InsOrders;
@@ -11,7 +12,6 @@ import com.jzg.commons.entity.orders.po.InsOrdersTrack;
 import com.jzg.commons.entity.quote.vo.QuoteVo;
 import com.jzg.commons.entity.quote.vo.aggregated.*;
 import com.jzg.commons.entity.vo.AdjustAllRefundVo;
-import com.jzg.commons.exception.SystemException;
 import com.jzg.quotation.commons.constant.SpElMapping;
 import com.jzg.quotation.commons.utils.SpElFieldExtractor;
 import com.jzg.quotation.summary.constants.QuoteNumberConstant;
@@ -24,6 +24,8 @@ import org.aspectj.lang.annotation.Around;
 import org.aspectj.lang.annotation.Aspect;
 import org.aspectj.lang.reflect.MethodSignature;
 import org.hibernate.validator.internal.util.stereotypes.Lazy;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.expression.EvaluationContext;
 import org.springframework.expression.ExpressionParser;
@@ -31,7 +33,6 @@ import org.springframework.expression.spel.standard.SpelExpressionParser;
 import org.springframework.expression.spel.support.StandardEvaluationContext;
 import org.springframework.stereotype.Component;
 
-import java.lang.reflect.Method;
 import java.util.List;
 import java.util.Map;
 import java.util.Objects;
@@ -40,6 +41,8 @@ import java.util.Objects;
 @Component
 public class OrderOperationLogAspect {
 
+    private static final Logger logger = LoggerFactory.getLogger(OrderOperationLogAspect.class);
+
     @Autowired
     @Lazy
     private InsOrdersService orderService;
@@ -141,10 +144,59 @@ public class OrderOperationLogAspect {
                 result = joinPoint.proceed();
                 this.adjustSubmitLog(orderNo,result,log);
                 break;
+            // 订单审核
+            case 14:
+                // 通过 SpEL 提取 入参
+                //orderNo = parser.parseExpression(log.orderSpEl()).getValue(context, String.class);
+                result = joinPoint.proceed();
+                HttpResult<String> res = (HttpResult)result;
+                this.dealApproveOrders(res.getData(),res,log);
+                break;
         }
         return result;
     }
 
+    /**
+     * 订单审核(通过/驳回)
+     *
+     * @author lipf
+     * @date 2026/6/13 14:27
+     */
+    void dealApproveOrders(String orderNo, HttpResult<String> result, OrderOperationLog log){
+        logger.info("订单审核通过或驳回时记录。orderNo=[{}],result=[{}]", orderNo, JSONUtil.toJsonStr(result));
+        // 定义要提取的字段
+        List<SpElMapping> mappings = List.of(
+                new SpElMapping("msg", "#ret.msg"),
+                new SpElMapping("code", "#ret.code"),
+                new SpElMapping("data", "#ret.data")
+        );
+        // 执行提取
+        Map<String, Object> extracted = fieldExtractor.extractFields(result, mappings);
+        logger.info("extracted=[{}]", JSONUtil.toJsonStr(extracted));
+        InsOrdersTrack track = new InsOrdersTrack();
+        InsOrders insOrders = orderService.getById(orderNo);
+        if(insOrders != null){
+            InsOrdersCarInfo carInfo = carInfoService.getByOrderId(insOrders.getId());
+            track.setLicenseNo(carInfo.getLicenseNo());
+            track.setCompanyId(insOrders.getCompanyId());
+            track.setResult(result.getMsg());
+        }else{
+            track.setResult("要审核的订单不存在");
+        }
+        track.setOrderNo(orderNo);
+        track.setModule(log.module());
+        track.setSubModule(log.subModule());
+        track.setOptType(log.optType().getCode());
+        track.setOptContent(log.description());
+        if(extracted.get("code").equals(200)){
+            track.setStatus(1);
+        }else{
+            track.setStatus(0);
+        }
+        traceService.save(track);
+    }
+
+
     /**
      * 审核批改订单
      * @param param
@@ -152,6 +204,7 @@ public class OrderOperationLogAspect {
      * @param log
      */
     private void adjustVerifyLog(VerifyAdjustParam param, Object result, OrderOperationLog log) {
+        logger.info("adjustVerifyLog. param=[{}], result=[{}],log=[{}]", JSONUtil.toJsonStr(param), JSONUtil.toJsonStr(result), JSONUtil.toJsonStr(log));
 
         // 定义要提取的字段
         List<SpElMapping> mappings = List.of(
@@ -215,7 +268,7 @@ public class OrderOperationLogAspect {
         track.setOptContent(log.description());
         track.setCompanyId(insOrders.getCompanyId());
         track.setLicenseNo(carInfo.getLicenseNo());
-
+        //track.setResult(JSONUtil.toJsonStr(result));
         if(extracted.get("code").equals(200)){
             track.setStatus(QuoteNumberConstant.QuoteResult.SUCCESS.getCode());
             traceService.save(track);

+ 1 - 1
tenant/insurance/quotation-summary/src/main/java/com/jzg/quotation/summary/constants/QuoteNumberConstant.java

@@ -92,7 +92,7 @@ public class QuoteNumberConstant {
         OPT_TYPE_11(11,"提交批改申请"),
         OPT_TYPE_12(12,"批改审核"),
         OPT_TYPE_13(13,"撤销批改"),
-
+        OPT_TYPE_14(14,"订单审核"),
         ;
         private Integer code;
         private String desc;

+ 15 - 4
tenant/insurance/quotation-summary/src/main/java/com/jzg/quotation/summary/controller/InsFeeAuditController.java

@@ -12,6 +12,8 @@ import com.jzg.commons.entity.orders.vo.AuditCostInfoVo;
 import com.jzg.commons.entity.orders.vo.FeeAuditVo;
 import com.jzg.commons.entity.quote.vo.aggregated.QuoteEchoVo;
 import com.jzg.commons.entity.vo.PtlAgreementCostRatioVo;
+import com.jzg.quotation.summary.aop.OrderOperationLog;
+import com.jzg.quotation.summary.constants.QuoteNumberConstant;
 import com.jzg.quotation.summary.service.InsFeeAuditService;
 import io.swagger.v3.oas.annotations.Operation;
 import io.swagger.v3.oas.annotations.tags.Tag;
@@ -126,6 +128,14 @@ public class InsFeeAuditController {
      *
      * @return HttpResult<String>
      */
+    @OrderOperationLog(
+            module = "订单审核",
+            subModule = "我的审核",
+            optType = QuoteNumberConstant.QuoteOptType.OPT_TYPE_14,
+            description = "订单审核",
+            orderSpEl = "#quoteVo",
+            feedbackSpEl = "#ret.code + ' - ' + #ret.msg+ ' - ' + #ret.data"
+    )
     @PostMapping("/verifyOrder")
     @Operation(summary = "审核订单")
     public HttpResult<String> verifyOrder(@RequestBody VerifyOrderParam param){
@@ -133,14 +143,15 @@ public class InsFeeAuditController {
             insFeeAuditService.verifyOrder(param);
         }catch (Exception e){
             log.info("审核订单发生异常:param=[{}], e", JSONUtil.toJsonStr(param), e);
-            return HttpResult.ok(e.getMessage());
+            return HttpResult.error(e.getMessage(),param.getOrderNo());
         }
+        // add by lipf ,2026年6月13日14:50:24 这里将orderNo 作为result的data传回去。 在记录订单轨迹的时候使用
         if("1".equals(Objects.toString(param.getAuditStatus(),"") )){
-            return HttpResult.ok("订单审核成功");
+            return HttpResult.ok("订单审核成功",param.getOrderNo());
         }else if("2".equals(Objects.toString(param.getAuditStatus(),""))){
-            return HttpResult.ok("订单审核驳回成功");
+            return HttpResult.ok("订单审核驳回成功",param.getOrderNo());
         }else{
-            return HttpResult.ok("订单审核状态不支持。"+param.getAuditStatus());
+            return HttpResult.ok("订单审核状态不支持。"+param.getAuditStatus(),param.getOrderNo());
         }
     }
 

+ 4 - 0
tenant/insurance/quotation-summary/src/main/java/com/jzg/quotation/summary/controller/UnifyOrderManager.java

@@ -391,6 +391,10 @@ public class UnifyOrderManager {
             log.error("车险报价异常", e);
             Throwable root = e.getCause() != null ? e.getCause() : e;
             String errMsg = root.getMessage() != null ? root.getMessage() : "系统异常,报价失败";
+            // 去除异常类名前缀
+            if (errMsg.matches("^[a-zA-Z0-9.]+Exception:.*")) {
+                errMsg = errMsg.substring(errMsg.indexOf(":") + 1).trim();
+            }
             try {
                 insOrdersService.orderAfterUpdateFailedQuote(ordersNo, errMsg);
             } catch (Exception ex) {

+ 14 - 2
tenant/insurance/quotation-summary/src/main/java/com/jzg/quotation/summary/service/impl/InsFeeOrdersServiceImpl.java

@@ -14,6 +14,7 @@ import com.jzg.commons.entity.orders.po.InsOrdersCosts;
 import com.jzg.commons.entity.po.InsFeeOrders;
 import com.jzg.commons.entity.po.PtlAgreement;
 import com.jzg.commons.entity.vo.PtlAgreementCostRatioVo;
+import com.jzg.commons.exception.SystemException;
 import com.jzg.commons.util.AssertionUtils;
 import com.jzg.commons.util.StringUtils;
 import com.jzg.quotation.commons.client.OrgClient;
@@ -380,9 +381,20 @@ public class InsFeeOrdersServiceImpl extends ServiceImpl<InsFeeOrdersMapper, Ins
         // 2. 查询订单
         InsFeeOrders insFeeOrders = getFeeOrderByOrderNo(orderNo);
         AssertionUtils.isFail(insFeeOrders == null, "根据订单号查询订单费用表查无数据,订单号:" + orderNo);
-
-        // 3. 更新
+        BigDecimal jqExportKeepPointRatio = insFeeOrders.getJqExportKeepPointRatio(); // 交强险出口留点比例
+        BigDecimal syExportKeepPointRatio = insFeeOrders.getSyExportKeepPointRatio(); // 商业险出口留点比例
+        BigDecimal jyExportKeepPointRatio = insFeeOrders.getJyExportKeepPointRatio(); // 驾意险出口留点比例
+        if (jqExportKeepPointRatio.compareTo(BigDecimal.ZERO) != 0 || syExportKeepPointRatio.compareTo(BigDecimal.ZERO) != 0 || jyExportKeepPointRatio.compareTo(BigDecimal.ZERO) != 0) {
+            throw new SystemException("该订单留点比例不为0,无法修改可用金额");
+        }
+        // 校验修改金额 不能比现在的金额大
+        AssertionUtils.isFail(availableAmount.compareTo(insFeeOrders.getAvailableAmount()) > 0, "可用金额不能大于当前金额");
+        // 3. 更新 可用金额
+        BigDecimal availableAmountBefore = insFeeOrders.getAvailableAmount();
+        BigDecimal availableAmountAfter = availableAmountBefore.subtract(availableAmount);
         insFeeOrders.setAvailableAmount(availableAmount);
+        // 修改后 将相差的金额 加到剩余金额中
+        insFeeOrders.setRemainingAmount(insFeeOrders.getRemainingAmount().add(availableAmountAfter));
         int updateCount = insFeeOrdersMapper.updateById(insFeeOrders);
         AssertionUtils.isFail(updateCount <= 0, "更新失败,订单号:" + orderNo);
 

+ 1 - 1
tenant/insurance/quotation-summary/src/main/java/com/jzg/quotation/summary/service/impl/InsOrderRightsPackageServiceImpl.java

@@ -45,7 +45,7 @@ public class InsOrderRightsPackageServiceImpl extends ServiceImpl<InsOrderRights
         // 定义查询条件
         LambdaQueryWrapper<InsOrderRightsPackage> lambdaQueryWrapper = new LambdaQueryWrapper<>();
         lambdaQueryWrapper.eq(InsOrderRightsPackage::getOrderId, orderNo)
-                .eq(InsOrderRightsPackage::getDelFlag, 0);
+                .eq(InsOrderRightsPackage::getIsDelete, 0);
 
         // 执行删除操作,返回受影响的行数
         return insOrderRightsPackageMapper.delete(lambdaQueryWrapper);

+ 1 - 1
tenant/insurance/quotation-summary/src/main/java/com/jzg/quotation/summary/service/impl/InsOrderRightsServiceImpl.java

@@ -43,7 +43,7 @@ public class InsOrderRightsServiceImpl extends ServiceImpl<InsOrderRightsMapper,
         // 定义查询条件
         LambdaQueryWrapper<InsOrderRights> lambdaQueryWrapper = new LambdaQueryWrapper<>();
         lambdaQueryWrapper.eq(InsOrderRights::getOrderId, orderNo)
-                .eq(InsOrderRights::getDelFlag, 0);
+                .eq(InsOrderRights::getIsDelete, 0);
         // 执行删除操作,返回受影响的行数
         return insOrderRightsMapper.delete(lambdaQueryWrapper);
     }

+ 2 - 2
tenant/insurance/quotation-summary/src/main/resources/mapper/InsOrderRightsMapper.xml

@@ -38,14 +38,14 @@
     <sql id="Base_Column_List">
             id,order_id,rights_id,
             rights_name,classify,rebate,amount,rights_picture,use_condition,day_num,start_time,end_time,
-               market_price,contract_rate,settle_price,description,del_flag,create_by,
+               market_price,contract_rate,settle_price,description,is_delete,create_by,
                 create_time,update_by,update_time,rights_status,rights_count,rights_type,receiver_type,receiver_name,receiver_mobile
     </sql>
     <select id="queryByOrderNo" resultType="com.jzg.commons.entity.rights.po.InsOrderRights">
         SELECT <include refid="Base_Column_List"/>
         FROM ins_order_rights
         <where>
-            and del_flag = 0
+            and is_delete = 0
             <if test="orderNo != null and orderNo != ''">
                 and order_id = #{orderNo}
             </if>

+ 2 - 2
tenant/insurance/quotation-summary/src/main/resources/mapper/InsOrderRightsPackageMapper.xml

@@ -31,14 +31,14 @@
     <sql id="Base_Column_List">
             id,order_id,rights_id,equity_package_name,cost_price_max,cost_price_min,
             market_price,agreement_price,three_settlement_price,
-                package_price,industry_id,del_flag,create_by,create_time,update_by,
+                package_price,industry_id,is_delete,create_by,create_time,update_by,
                 update_time,status,rights_type,rights_count,receiver_type,receiver_name,receiver_mobile
     </sql>
     <select id="queryByOrderNo" resultType="com.jzg.commons.entity.rights.po.InsOrderRightsPackage">
         SELECT <include refid="Base_Column_List"/>
         FROM ins_order_rights_package
         <where>
-            and del_flag = 0
+            and is_delete = 0
             <if test="orderNo != null and orderNo != ''">
                 and order_id = #{orderNo}
             </if>

+ 3 - 0
tenant/insurance/quotation-summary/src/main/resources/mapper/InsOrdersMapper.xml

@@ -578,6 +578,9 @@
         ) ioa1 ON o.id = ioa1.order_no
         <where>
             and o.is_delete = 0 and o.parent_id != 0
+            <if test="insOrdersParam.systemCode != null and insOrdersParam.systemCode != ''">
+                AND o.system_code = #{insOrdersParam.systemCode}
+            </if>
             <if test="insOrdersParam.orderNo != null and insOrdersParam.orderNo != ''">
                 AND o.quote_no = #{insOrdersParam.orderNo}
             </if>