Просмотр исходного кода

Merge remote-tracking branch 'origin/dev_jzg_lipf_v20260506' into dev_jzg_lipf_v20260506

jiakai 4 месяцев назад
Родитель
Сommit
85246cc30d
57 измененных файлов с 752 добавлено и 104 удалено
  1. 5 4
      commons/src/main/java/com/jzg/commons/entity/finance/po/InsPlyIncomeInvoice.java
  2. 5 0
      commons/src/main/java/com/jzg/commons/entity/finance/vo/InvoiceRecordResult.java
  3. 4 0
      commons/src/main/java/com/jzg/commons/entity/po/EsmInsCompany.java
  4. 15 0
      commons/src/main/java/com/jzg/commons/util/MinioUtils.java
  5. 10 0
      platform/src/main/java/com/jzg/controller/EsmInsCompanyController.java
  6. 8 0
      platform/src/main/java/com/jzg/service/EsmInsCompanyService.java
  7. 71 0
      platform/src/main/java/com/jzg/service/impl/EsmInsCompanyServiceImpl.java
  8. 1 1
      tenant/insurance/quotation-ansheng/src/main/java/com/jzg/quotation/ansheng/crawler/build/AnShengCrawlerApplyApplicationRequestBuild.java
  9. 5 0
      tenant/insurance/quotation-ansheng/src/main/java/com/jzg/quotation/ansheng/crawler/entity/response/AnShengCrawlerSearchVehicleByVinResponse.java
  10. 5 0
      tenant/insurance/quotation-bohai/src/main/java/com/jzg/quotation/bohai/crawler/entity/response/BoHaiCrawlerCarResponse1.java
  11. 5 0
      tenant/insurance/quotation-chengtai/src/main/java/com/jzg/quotation/chengtai/api/entity/response/CarModelQueryResponse.java
  12. 2 0
      tenant/insurance/quotation-chengtai/src/main/java/com/jzg/quotation/chengtai/api/entity/response/PremiumCalculationResponse.java
  13. 5 0
      tenant/insurance/quotation-chengtai/src/main/java/com/jzg/quotation/chengtai/crawler/entity/response/ChengTaiFindCarModelResponse.java
  14. 73 0
      tenant/insurance/quotation-commons/src/main/java/com/jzg/quotation/commons/component/RequestComponent.java
  15. 7 0
      tenant/insurance/quotation-commons/src/main/java/com/jzg/quotation/commons/filter/CarModelsFilter.java
  16. 8 1
      tenant/insurance/quotation-commons/src/main/java/com/jzg/quotation/commons/filter/CarModelsFilterUtils.java
  17. 52 2
      tenant/insurance/quotation-dajia/src/main/java/com/jzg/quotation/dajia/crawler/build/DaJiaCrawlerQuoteResultsVoBuild.java
  18. 1 1
      tenant/insurance/quotation-dajia/src/main/java/com/jzg/quotation/dajia/crawler/build/DajiaCrawlerAuditResultsVoBuild.java
  19. 13 0
      tenant/insurance/quotation-dajia/src/main/java/com/jzg/quotation/dajia/crawler/component/DaJiaCrawlerCacheComponent.java
  20. 30 3
      tenant/insurance/quotation-dajia/src/main/java/com/jzg/quotation/dajia/crawler/component/DaJiaCrawlerRequestComponent.java
  21. 2 0
      tenant/insurance/quotation-dajia/src/main/java/com/jzg/quotation/dajia/crawler/constant/enums/RequestUrl.java
  22. 3 0
      tenant/insurance/quotation-dajia/src/main/java/com/jzg/quotation/dajia/crawler/entity/po/DaJiaCrawlerOrder.java
  23. 1 1
      tenant/insurance/quotation-dajia/src/main/java/com/jzg/quotation/dajia/crawler/entity/request/DaJiaCrawlerChannelPackagesRequest.java
  24. 8 4
      tenant/insurance/quotation-dajia/src/main/java/com/jzg/quotation/dajia/crawler/entity/request/DaJiaCrawlerPriceRequest.java
  25. 5 0
      tenant/insurance/quotation-dajia/src/main/java/com/jzg/quotation/dajia/crawler/entity/response/DaJiaCrawlerCarResponse.java
  26. 1 0
      tenant/insurance/quotation-dajia/src/main/java/com/jzg/quotation/dajia/crawler/service/impl/DaJiaCrawlerOrderServiceImpl.java
  27. 24 1
      tenant/insurance/quotation-dajia/src/main/java/com/jzg/quotation/dajia/crawler/service/impl/DaJiaCrawlerQuoteProcessServiceImpl.java
  28. 35 8
      tenant/insurance/quotation-dajia/src/main/java/com/jzg/quotation/dajia/crawler/service/impl/DaJiaCrawlerRequestImpl.java
  29. 12 13
      tenant/insurance/quotation-guoren/src/main/java/com/jzg/quotation/guoren/api/build/GuoRenApiQuoteResultsVoBuild.java
  30. 5 0
      tenant/insurance/quotation-guoren/src/main/java/com/jzg/quotation/guoren/crawler/entity/response/GuoRenCrawlerQueryByVinNoData.java
  31. 5 0
      tenant/insurance/quotation-guoren/src/main/java/com/jzg/quotation/guoren/crawler/entity/response/GuoRenCrawlerQueryCarModelData.java
  32. 1 1
      tenant/insurance/quotation-guoren/src/main/java/com/jzg/quotation/guoren/crawler/service/impl/GuoRenCrawlerQuoteProcessServiceImpl.java
  33. 5 0
      tenant/insurance/quotation-guoshou/src/main/java/com/jzg/quotation/guoshou/crawler/entity/response/GsCrawlerCarQueryResponse.java
  34. 42 18
      tenant/insurance/quotation-hengbang/src/main/java/com/jzg/quotation/hengbang/crawler/build/HbCrawlerQuoteResultVoBuild.java
  35. 27 21
      tenant/insurance/quotation-hengbang/src/main/java/com/jzg/quotation/hengbang/crawler/component/HengBangCrawlerRequestComponent.java
  36. 18 2
      tenant/insurance/quotation-hengbang/src/main/java/com/jzg/quotation/hengbang/crawler/service/Impl/HengBangCrawlerRequestImpl.java
  37. 1 1
      tenant/insurance/quotation-hengbang/src/main/java/com/jzg/quotation/hengbang/crawler/utils/HengBangAESUtil.java
  38. 3 1
      tenant/insurance/quotation-huanong/src/main/java/com/jzg/quotation/huanong/crawler/build/HuaNongCrawlerQuoteResultsVoBuild.java
  39. 5 0
      tenant/insurance/quotation-huanong/src/main/java/com/jzg/quotation/huanong/crawler/entity/response/HuaNongCrawlerModelsQueryResponse.java
  40. 5 0
      tenant/insurance/quotation-huanong/src/main/java/com/jzg/quotation/huanong/crawler/entity/response/HuaNongCrawlerPrecisionServiceSearchResponse.java
  41. 127 15
      tenant/insurance/quotation-huanong/src/main/java/com/jzg/quotation/huanong/crawler/service/impl/HuaNongCrawlerRequestImpl.java
  42. 5 0
      tenant/insurance/quotation-huatai/src/main/java/com/jzg/quotation/huatai/api/entity/response/HuaTaiModelsQueryResponse.java
  43. 5 0
      tenant/insurance/quotation-huatai/src/main/java/com/jzg/quotation/huatai/crawler/entity/Response/HtCrawlerCarQueryResponse.java
  44. 5 0
      tenant/insurance/quotation-renbao/src/main/java/com/jzg/quotation/renbao/crawler/entity/response/RenBaoCrawlerVehicleQueryData.java
  45. 3 0
      tenant/insurance/quotation-summary/src/main/java/com/jzg/quotation/summary/controller/UnifyOrderManager.java
  46. 12 2
      tenant/insurance/quotation-summary/src/main/java/com/jzg/quotation/summary/service/impl/InsOrdersServiceImpl.java
  47. 5 0
      tenant/insurance/quotation-taishan/src/main/java/com/jzg/quotation/taishan/crawler/entity/response/TaiShanCrawlerCarResponse.java
  48. 5 0
      tenant/insurance/quotation-yangguang/src/main/java/com/jzg/quotation/yangguang/api/entity/response/YangGuangQueryVehicleModelResponse.java
  49. 5 0
      tenant/insurance/quotation-zhongan/src/main/java/com/jzg/quotation/zhongan/crawler/entity/response/ZhongAnCrawlerCarQueryResponse.java
  50. 5 0
      tenant/insurance/quotation-zhongmei/src/main/java/com/jzg/quotation/zhongmei/api/entity/response/ModelsQueryResponse.java
  51. 17 1
      tenant/insurance/quotation-zhongmei/src/main/java/com/jzg/quotation/zhongmei/crawler/build/ZmCrawlerQuoteResultVoBuild.java
  52. 1 1
      tenant/insurance/quotation-zhongmei/src/main/java/com/jzg/quotation/zhongmei/crawler/entity/Request/ZmCrawlerModelQueryRequest.java
  53. 4 0
      tenant/insurance/quotation-zhongmei/src/main/java/com/jzg/quotation/zhongmei/crawler/entity/Response/ZmCrawlerModelQueryResponse.java
  54. 1 1
      tenant/insurance/quotation-zhongmei/src/main/java/com/jzg/quotation/zhongmei/crawler/service/Impl/ZhongMeiCrawlerRequestImpl.java
  55. 9 0
      tenant/organization/src/main/java/com/jzg/organization/client/EsmInsCompanyClient.java
  56. 2 1
      tenant/organization/src/main/java/com/jzg/organization/controller/ReceivableController.java
  57. 8 0
      tenant/organization/src/main/java/com/jzg/organization/service/impl/ReceivableServiceImpl.java

+ 5 - 4
commons/src/main/java/com/jzg/commons/entity/finance/po/InsPlyIncomeInvoice.java

@@ -6,6 +6,7 @@ import lombok.Data;
 
 import java.io.Serial;
 import java.math.BigDecimal;
+import java.util.Objects;
 
 @Data
 @Schema(description = "财务应收开票表")
@@ -26,11 +27,11 @@ public class InsPlyIncomeInvoice extends BaseModel {
     @Schema(description = "虚增金额")
     private BigDecimal overinflatedAmount;
 
+    @Schema(description = "应收项")
+    private String invoickRiskType;
+
     public BigDecimal getOverinflatedAmount(){
-        if(this.overinflatedAmount == null){
-            return BigDecimal.ZERO;
-        }
-        return this.overinflatedAmount;
+        return Objects.requireNonNullElse(this.overinflatedAmount, BigDecimal.ZERO);
     }
 
     @Schema(description = "应收费用")

+ 5 - 0
commons/src/main/java/com/jzg/commons/entity/finance/vo/InvoiceRecordResult.java

@@ -23,6 +23,11 @@ public class InvoiceRecordResult extends PageRequest {
      */
     private String companyName;
 
+    /**
+     * 保险公司名称及父级的名称,例如
+     */
+    private String companyALlName;
+
     /**
      * 开票方
      */

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

@@ -6,11 +6,15 @@ import com.baomidou.mybatisplus.annotation.TableId;
 import com.baomidou.mybatisplus.annotation.TableName;
 import com.jzg.commons.core.base.BaseModel;
 import lombok.Data;
+
+import java.io.Serial;
 import java.util.List;
 @TableName(value = "esm_ins_company")
 @Data
 public class EsmInsCompany extends BaseModel {
 
+    @Serial
+    private static final long serialVersionUID = 3082765270221772930L;
     @TableId(type = IdType.ASSIGN_ID)
     private String id;
 

+ 15 - 0
commons/src/main/java/com/jzg/commons/util/MinioUtils.java

@@ -9,6 +9,7 @@ import io.minio.messages.DeleteObject;
 import io.minio.messages.Item;
 import lombok.SneakyThrows;
 import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.compress.utils.IOUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
@@ -195,6 +196,20 @@ public class MinioUtils {
         return minioClient.getObject(GetObjectArgs.builder().bucket(bucketName).object(objectName).build());
     }
 
+    /**
+     * 获取base64 文件
+     *
+     * @param bucketName 存储桶
+     * @param objectName 文件名
+     * @return base64字符串
+     */
+    @SneakyThrows(Exception.class)
+    public String getBase64Str(String bucketName, String objectName) {
+        InputStream inputStream = getObject(bucketName, objectName);
+        return Base64Convert.byteToBase64(IOUtils.toByteArray(inputStream));
+    }
+
+
     /**
      * 断点下载
      *

+ 10 - 0
platform/src/main/java/com/jzg/controller/EsmInsCompanyController.java

@@ -455,4 +455,14 @@ public class EsmInsCompanyController extends BaseController {
         return HttpResult.ok(esmInsCompanyService.getTopCompanyId(companyId));
     }
 
+    /**
+     * 获取所有保险公司的全路径名称
+     * Key: 公司ID
+     * Value: 总公司/分公司/支公司
+     */
+    @Operation(summary = "获取所有保险公司的全路径名称")
+    @GetMapping("getAllCompanyHierarchyPaths")
+    public Map<String, String> getAllCompanyHierarchyPaths(){
+        return esmInsCompanyService.getAllCompanyHierarchyPaths();
+    }
 }

+ 8 - 0
platform/src/main/java/com/jzg/service/EsmInsCompanyService.java

@@ -9,6 +9,7 @@ import com.jzg.commons.entity.vo.EsmInsCompanyVo;
 
 
 import java.util.List;
+import java.util.Map;
 
 public interface EsmInsCompanyService extends IService<EsmInsCompany> {
 
@@ -144,6 +145,13 @@ public interface EsmInsCompanyService extends IService<EsmInsCompany> {
      * @return
      */
     String getTopCompanyId(String companyId);
+
+    /**
+     * 获取所有保险公司的全路径名称
+     * Key: 公司ID
+     * Value: 总公司/分公司/支公司
+     */
+    public Map<String, String> getAllCompanyHierarchyPaths();
 }
 
 

+ 71 - 0
platform/src/main/java/com/jzg/service/impl/EsmInsCompanyServiceImpl.java

@@ -359,6 +359,77 @@ public class EsmInsCompanyServiceImpl extends ServiceImpl<EsmInsCompanyMapper, E
     public String getTopCompanyId(String companyId) {
         return baseMapper.getTopCompanyId(companyId);
     }
+
+    /**
+     * 获取所有保险公司的全路径名称
+     * Key: 公司ID
+     * Value: 总公司/分公司/支公司
+     */
+    public Map<String, String> getAllCompanyHierarchyPaths() {
+        log.info("获取所有保险公司的全路径名称");
+        // 1. 查询所有未删除的保险公司(一次性加载,避免循环查库)
+        List<EsmInsCompany> allCompanies = baseMapper.selectList(null);
+        allCompanies = allCompanies.stream().filter(action->action.getIsDelete()==0).toList();
+
+        // 2. 将列表转换为 Map,以便通过 ID 快速查找对象 (ID -> Company Object)
+        Map<String, EsmInsCompany> companyMap = allCompanies.stream()
+                .collect(Collectors.toMap(EsmInsCompany::getId, c -> c));
+
+        // 3. 结果缓存 Map (ID -> "A/B/C" Path)
+        // 使用 ConcurrentHashMap 或者普通 HashMap 均可,视并发需求而定
+        Map<String, String> pathCache = new HashMap<>();
+
+        // 4. 遍历所有公司,构建路径
+        for (EsmInsCompany company : allCompanies) {
+            buildPath(company.getId(), companyMap, pathCache);
+        }
+        log.info("构建得到的公司的层级结构如下: [{}]", JSONUtil.toJsonStr(pathCache));
+        return pathCache;
+    }
+
+    /**
+     * 递归构建单个公司的路径(带缓存优化,防止重复计算)
+     */
+    private String buildPath(String currentId, Map<String, EsmInsCompany> companyMap, Map<String, String> pathCache) {
+        // 如果已经计算过,直接返回(记忆化搜索,防止重复递归)
+        if (pathCache.containsKey(currentId)) {
+            return pathCache.get(currentId);
+        }
+
+        EsmInsCompany currentCompany = companyMap.get(currentId);
+        if (currentCompany == null) {
+            return "";
+        }
+
+        // 获取父级 ID
+        String parentId = currentCompany.getParentId();
+
+        String fullPath;
+
+        // 判断是否有父级 (根据数据库设计,根节点的 parent_id 通常为 0 或 null)
+        if (parentId == null || parentId.equals("0")) {
+            // 如果是根节点,路径就是它自己的名字
+            //fullPath = currentCompany.getName();
+            fullPath = currentCompany.getNameSimple();
+        } else {
+            // 如果有父级,递归获取父级的路径,然后拼接当前名字
+            // 注意:这里递归调用 buildPath,利用缓存避免死循环和重复计算
+            String parentPath = buildPath(parentId, companyMap, pathCache);
+
+            if (parentPath.isEmpty()) {
+                //fullPath = currentCompany.getName();
+                fullPath = currentCompany.getNameSimple();
+            } else {
+                //fullPath = parentPath + "/" + currentCompany.getName();
+                fullPath = parentPath + "/" + currentCompany.getNameSimple();
+            }
+        }
+
+        // 存入缓存
+        pathCache.put(currentId, fullPath);
+        return fullPath;
+    }
+
 }
 
 

+ 1 - 1
tenant/insurance/quotation-ansheng/src/main/java/com/jzg/quotation/ansheng/crawler/build/AnShengCrawlerApplyApplicationRequestBuild.java

@@ -56,7 +56,7 @@ public final class AnShengCrawlerApplyApplicationRequestBuild {
             AnShengCrawlerApplyApplicationRequest.ContractsDTO.BillInfoDetailDTO billInfoDetailDTO = buildBillInfoDetailDTO(insuranerName, personDTO.getMobileTelephone());
             contractsDTO.setBillInfoDetail(billInfoDetailDTO);
             AnShengCrawlerApplyApplicationRequest.ContractsDTO.BrandAutoModelDTO brandAutoModelDTO = buildBrandAutoModelDTO(responseContracts.getVehicle());
-            contractsDTO.setBrandAutoModel(brandAutoModelDTO);
+            //contractsDTO.setBrandAutoModel(brandAutoModelDTO);
             contractsDTO.setSaleChannelSource(new AnShengCrawlerApplyApplicationRequest.ContractsDTO.SaleChannelSourceDTO(""));
             contractsDTO.setUnderwriteInfos(List.of(new AnShengCrawlerApplyApplicationRequest.ContractsDTO.UnderwriteInfosDTO("1", "")));
             AnShengCrawlerApplyApplicationRequest.ContractsDTO.PolicyExtendDTO policyExtendDTO = buildPolicyExtend(insuranerName, personDTO.getMobileTelephone());

+ 5 - 0
tenant/insurance/quotation-ansheng/src/main/java/com/jzg/quotation/ansheng/crawler/entity/response/AnShengCrawlerSearchVehicleByVinResponse.java

@@ -60,6 +60,11 @@ public class AnShengCrawlerSearchVehicleByVinResponse  implements Serializable,
             return this.brandAutoModel.purchasePrice;
         }
 
+        @Override
+        public String getSeatCount() {
+            return this.brandAutoModel.seatCom;
+        }
+
         @NoArgsConstructor
         @Data
         public static class BrandAutoModelDTO {

+ 5 - 0
tenant/insurance/quotation-bohai/src/main/java/com/jzg/quotation/bohai/crawler/entity/response/BoHaiCrawlerCarResponse1.java

@@ -398,5 +398,10 @@ public class BoHaiCrawlerCarResponse1 implements Serializable {
         public String getPurchasePrice() {
             return vehiclePrice;
         }
+
+        @Override
+        public String getSeatCount() {
+            return String.valueOf(vehicleSeat);
+        }
     }
 }

+ 5 - 0
tenant/insurance/quotation-chengtai/src/main/java/com/jzg/quotation/chengtai/api/entity/response/CarModelQueryResponse.java

@@ -165,5 +165,10 @@ public class CarModelQueryResponse {
         public String getPurchasePrice() {
             return null;
         }
+
+        @Override
+        public String getSeatCount() {
+            return null;
+        }
     }
 }

+ 2 - 0
tenant/insurance/quotation-chengtai/src/main/java/com/jzg/quotation/chengtai/api/entity/response/PremiumCalculationResponse.java

@@ -1,5 +1,6 @@
 package com.jzg.quotation.chengtai.api.entity.response;
 
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
 import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper;
 import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
 import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
@@ -17,6 +18,7 @@ import java.util.List;
 @NoArgsConstructor
 @Data
 @JacksonXmlRootElement(localName = "policyFeeCountResponseBody")
+@JsonIgnoreProperties(ignoreUnknown = true)
 public class PremiumCalculationResponse {
     /**
      * 报文头信息(Head)

+ 5 - 0
tenant/insurance/quotation-chengtai/src/main/java/com/jzg/quotation/chengtai/crawler/entity/response/ChengTaiFindCarModelResponse.java

@@ -150,5 +150,10 @@ public class ChengTaiFindCarModelResponse implements Serializable {
         public String getPurchasePrice() {
             return purchaseprice;
         }
+
+        @Override
+        public String getSeatCount() {
+            return seatcount;
+        }
     }
 }

+ 73 - 0
tenant/insurance/quotation-commons/src/main/java/com/jzg/quotation/commons/component/RequestComponent.java

@@ -461,6 +461,79 @@ public class RequestComponent {
     }
 
 
+    /**
+     * 构造post请求
+     *
+     * @param url
+     * @param body
+     * @param responseClass
+     * @param headers
+     * @param <Response>    响应实体
+     * @return <Response> ResponseEntity<Response>
+     */
+    public <Response> ResponseEntity<Response> daJiaImgPost(String url, Object body, Class<Response> responseClass, HttpHeaders headers) {
+        log.info("URL的值:{},body的值:{}", url, body);
+        WebClient webClient = selectNoSSLWebClient2();
+        try {
+            // 创建一个不带Accept-Encoding的请求头,避免服务器返回压缩数据
+            HttpHeaders requestHeaders = new HttpHeaders();
+            if (headers != null) {
+                requestHeaders.addAll(headers);
+            }
+            // 移除Accept-Encoding头,让服务器返回未压缩的数据
+            requestHeaders.remove("Accept-Encoding");
+
+            // 获取响应实体
+            ResponseEntity<String> rawResponse = webClient.post()
+                    .uri(url)
+                    .headers(setHeaders(requestHeaders))
+                    .body(BodyInserters.fromValue(body))
+                    .retrieve()
+                    .toEntity(String.class)
+                    .block();
+            if (rawResponse == null) {
+                throw new WebClientResponseException(500, "No response received", HttpHeaders.EMPTY, "No response received".getBytes(StandardCharsets.UTF_8), null);
+            }
+
+            String responseBody = rawResponse.getBody();
+            if (responseBody == null) {
+                responseBody = "";
+            }
+
+            Response result;
+            // 判断返回的字符串是否为有效的JSON格式
+            if (isValidJson(responseBody)) {
+                result = JSON.parseObject(responseBody, responseClass);
+            }else{
+                result = (Response)responseBody;
+            }
+            // 构建返回的ResponseEntity
+            return ResponseEntity.status(rawResponse.getStatusCode()).headers(rawResponse.getHeaders()).body(result);
+        } catch (WebClientResponseException e) {
+            // 如果是WebClientResponseException,记录详细信息
+            log.error("WebClient请求失败,状态码: {}, 响应头: {}", e.getStatusCode(), e.getHeaders(), e);
+            throw e;
+        } catch (Exception e) {
+            // 处理其他异常(修复NPE)
+            log.error("请求失败", e);
+
+            // 核心修复:e.getMessage() 可能为 null,必须判空
+            String errorMsg = e.getMessage();
+            if (errorMsg == null) {
+                errorMsg = "网络请求超时或服务端无响应";
+            }
+
+            throw new WebClientResponseException(
+                    500,
+                    "Request failed: " + errorMsg,
+                    HttpHeaders.EMPTY,
+                    errorMsg.getBytes(StandardCharsets.UTF_8),
+                    null
+            );
+        }
+    }
+
+
     /**
      * 构造post请求
      *

+ 7 - 0
tenant/insurance/quotation-commons/src/main/java/com/jzg/quotation/commons/filter/CarModelsFilter.java

@@ -21,4 +21,11 @@ public interface CarModelsFilter {
      */
     String getPurchasePrice();
 
+    /**
+     * 获取车辆座位数
+     *
+     * @return 车辆类型
+     */
+    String getSeatCount();
+
 }

+ 8 - 1
tenant/insurance/quotation-commons/src/main/java/com/jzg/quotation/commons/filter/CarModelsFilterUtils.java

@@ -19,7 +19,6 @@ public final class CarModelsFilterUtils {
         if (carModelsFilterList.isEmpty()) {
             throw new SystemException("核心查询车型失败 请联系业务人员处理");
         }
-
         List<T> stadarCarDTOS = new ArrayList<>();
         if (!StringUtils.isEmpty(carInfo.getCarYear())) {
             stadarCarDTOS = carModelsFilterList
@@ -29,6 +28,14 @@ public final class CarModelsFilterUtils {
                             .equals(car.getCarYear()))
                     .collect(Collectors.toList());
         }
+        if (!StringUtils.isEmpty(carInfo.getSeatCount())) {
+            stadarCarDTOS = stadarCarDTOS
+                    .stream()
+                    .filter(car -> carInfo
+                            .getSeatCount()
+                            .equals(car.getSeatCount()))
+                    .collect(Collectors.toList());
+        }
 
         if (!stadarCarDTOS.isEmpty()) {
             carModelsFilterList = stadarCarDTOS;

+ 52 - 2
tenant/insurance/quotation-dajia/src/main/java/com/jzg/quotation/dajia/crawler/build/DaJiaCrawlerQuoteResultsVoBuild.java

@@ -9,6 +9,7 @@ import com.jzg.commons.entity.quote.vo.QuoteVo;
 import com.jzg.commons.entity.quote.vo.RiskInfoVo;
 import com.jzg.commons.entity.quote.vo.aggregated.OrderStatusResultVo;
 import com.jzg.commons.entity.quote.vo.aggregated.QuoteResultsVo;
+import com.jzg.commons.util.StringUtils;
 import com.jzg.quotation.commons.utils.TimeProcessing;
 import com.jzg.quotation.dajia.crawler.constant.enums.DaJiaCrawlerOrderState;
 import com.jzg.quotation.dajia.crawler.entity.request.quote.BusinessInsuranceDTO;
@@ -148,10 +149,10 @@ public final class DaJiaCrawlerQuoteResultsVoBuild {
         CompulsoryInsuranceDTO compulsoryInsurance = daJiaCrawlerSaveResponse.getCompulsoryInsurance(); // 交强险
         BusinessInsuranceDTO businessInsurance = daJiaCrawlerSaveResponse.getBusinessInsurance(); // 商业险
         if (!ObjectUtils.isEmpty(compulsoryInsurance)) {
-            scoreVo.setJqLossRation(compulsoryInsurance.getCoefficientInfo().getLossRatioCi());
+            scoreVo.setJqLossRation(StringUtils.isNotEmpty(compulsoryInsurance.getCoefficientInfo().getLossRatioCi()) ? compulsoryInsurance.getCoefficientInfo().getLossRatioCi() : null);
         }
         if (!ObjectUtils.isEmpty(businessInsurance)) {
-            scoreVo.setSyLossRation(businessInsurance.getCoefficientInfo().getLossRatioBi());
+            scoreVo.setSyLossRation(StringUtils.isNotEmpty(businessInsurance.getCoefficientInfo().getLossRatioBi()) ? businessInsurance.getCoefficientInfo().getLossRatioBi() : null);
         }
         // 总赔付率 违章评分 高速风险分
         String carIllegalScore;
@@ -165,6 +166,7 @@ public final class DaJiaCrawlerQuoteResultsVoBuild {
             carIllegalScore = daJiaCrawlerSaveResponse.getBusinessInsurance().getCoefficientInfo().getCarIllegalScore();
             highwayScore = daJiaCrawlerSaveResponse.getBusinessInsurance().getCoefficientInfo().getHighwayScore();
         }
+        CompulsoryInsuranceDTO.CoefficientInfoDTO coefficientInfo = daJiaCrawlerSaveResponse.getCompulsoryInsurance().getCoefficientInfo();
         JSONArray scoreArray = new JSONArray();
         scoreArray.add(new JSONObject()
                 .fluentPut("scoreName","交强定价评分")
@@ -182,6 +184,54 @@ public final class DaJiaCrawlerQuoteResultsVoBuild {
                 .fluentPut("scoreName","高速风险分")
                 .fluentPut("scoreKey","highwayScore")
                 .fluentPut("score",highwayScore));
+        scoreArray.add(new JSONObject()
+                .fluentPut("scoreName","醉酒驾驶行为违法次数")
+                .fluentPut("scoreKey","drunkTotalCoef")
+                .fluentPut("score",coefficientInfo.getDrunkTotalCoef()));
+        scoreArray.add(new JSONObject()
+                .fluentPut("scoreName","理赔调整系数")
+                .fluentPut("scoreKey","claimAdjustValue")
+                .fluentPut("score",coefficientInfo.getClaimAdjustValue()));
+        scoreVo.setScoreJson(scoreArray);
+        scoreArray.add(new JSONObject()
+                .fluentPut("scoreName","交强险手续费")
+                .fluentPut("scoreKey","handFeeCi")
+                .fluentPut("score",coefficientInfo.getHandFeeCi()));
+        scoreVo.setScoreJson(scoreArray);
+        scoreArray.add(new JSONObject()
+                .fluentPut("scoreName","商业险手续费")
+                .fluentPut("scoreKey","handFeeBi")
+                .fluentPut("score",coefficientInfo.getHandFeeBi()));
+        scoreVo.setScoreJson(scoreArray);
+        scoreArray.add(new JSONObject()
+                .fluentPut("scoreName","续保次数")
+                .fluentPut("scoreKey","renewalFrequency")
+                .fluentPut("score",coefficientInfo.getRenewalFrequency()));
+        scoreVo.setScoreJson(scoreArray);
+        scoreArray.add(new JSONObject()
+                .fluentPut("scoreName","违法调整系数")
+                .fluentPut("scoreKey","carIllegalScore")
+                .fluentPut("score",coefficientInfo.getCarIllegalScore()));
+        scoreVo.setScoreJson(scoreArray);
+        scoreArray.add(new JSONObject()
+                .fluentPut("scoreName","商业险连续承保年数")
+                .fluentPut("scoreKey","insureYears")
+                .fluentPut("score",coefficientInfo.getInsureYears()));
+        scoreVo.setScoreJson(scoreArray);
+        scoreArray.add(new JSONObject()
+                .fluentPut("scoreName","商业险建议折扣")
+                .fluentPut("scoreKey","suggestedDiscount")
+                .fluentPut("score",coefficientInfo.getSuggestedDiscount()));
+        scoreVo.setScoreJson(scoreArray);
+        scoreArray.add(new JSONObject()
+                .fluentPut("scoreName","无赔款优待系数")
+                .fluentPut("scoreKey","totalCoefNum")
+                .fluentPut("score",coefficientInfo.getTotalCoefNum()));
+        scoreVo.setScoreJson(scoreArray);
+        scoreArray.add(new JSONObject()
+                .fluentPut("scoreName","无赔优系数级别")
+                .fluentPut("scoreKey","claimAdjustLvl")
+                .fluentPut("score",coefficientInfo.getClaimAdjustLvl()));
         scoreVo.setScoreJson(scoreArray);
         return scoreVo;
     }

+ 1 - 1
tenant/insurance/quotation-dajia/src/main/java/com/jzg/quotation/dajia/crawler/build/DajiaCrawlerAuditResultsVoBuild.java

@@ -42,7 +42,7 @@ public final class DajiaCrawlerAuditResultsVoBuild {
             if (null != daJiaCrawlerGenerateResponse.getJqGenerate().getErrorMessage()) {
                 sb.append(String.format("交强险提示信息:%s", daJiaCrawlerGenerateResponse.getJqGenerate().getErrorMessage()));
             }
-            if (null != daJiaCrawlerGenerateResponse.getSyGenerate().getErrorMessage()) {
+            if (!Objects.isNull(daJiaCrawlerGenerateResponse.getSyGenerate()) && null != daJiaCrawlerGenerateResponse.getSyGenerate().getErrorMessage()) {
                 sb.append(String.format("商业险提示信息:%s", daJiaCrawlerGenerateResponse.getSyGenerate().getErrorMessage()));
             }
             underwritingResultsVo.setUnderwritingResult(sb.toString());

+ 13 - 0
tenant/insurance/quotation-dajia/src/main/java/com/jzg/quotation/dajia/crawler/component/DaJiaCrawlerCacheComponent.java

@@ -43,6 +43,8 @@ public class DaJiaCrawlerCacheComponent {
 
     public static final String USER_CODE = "USER_CODE";
 
+    public static final String TOKEN_ID = "TOKEN_ID";
+
     /**
      * 缓存授权信息
      *
@@ -56,6 +58,7 @@ public class DaJiaCrawlerCacheComponent {
         String authorization = BEARER + token;
         authorizationMap.put(AUTHORIZATION, authorization);
         authorizationMap.put(USER_CODE, userCode);
+        authorizationMap.put(TOKEN_ID, token);
         RMap<Object, Object> map = redissonClient.getMap(DAJIA_AUTHORIZATION + userName);
         map.putAll(authorizationMap);
         map.expire(Duration.ofHours(DAJIA_AUTHORIZATION_TIME));
@@ -104,4 +107,14 @@ public class DaJiaCrawlerCacheComponent {
         return (String) redissonClient.getMap(DAJIA_AUTHORIZATION + username).get(AUTHORIZATION);
     }
 
+    /**
+     * 获取授权信息
+     *
+     * @param username 用户名
+     * @return 授权token
+     */
+    public String getTokenId(String username) {
+        return (String) redissonClient.getMap(DAJIA_AUTHORIZATION + username).get(TOKEN_ID);
+    }
+
 }

+ 30 - 3
tenant/insurance/quotation-dajia/src/main/java/com/jzg/quotation/dajia/crawler/component/DaJiaCrawlerRequestComponent.java

@@ -4,6 +4,7 @@ package com.jzg.quotation.dajia.crawler.component;
 import com.alibaba.fastjson2.JSON;
 import com.jzg.commons.exception.SystemException;
 import com.jzg.commons.util.AssertionUtils;
+import com.jzg.commons.util.StringUtils;
 import com.jzg.quotation.commons.component.RequestComponent;
 import com.jzg.quotation.commons.service.ExteriorUtilsRequest;
 import com.jzg.quotation.commons.standard.CrawlerRequestUrlStandard;
@@ -24,9 +25,7 @@ import org.springframework.util.MultiValueMap;
 import org.springframework.web.reactive.function.BodyInserters;
 import org.springframework.web.reactive.function.client.WebClient;
 
-import java.nio.charset.StandardCharsets;
 import java.util.List;
-import java.util.Map;
 import java.util.UUID;
 
 @Slf4j
@@ -279,7 +278,20 @@ public class DaJiaCrawlerRequestComponent {
      */
     public void initData(DaJiaCrawlerInitDataRequest request, HttpHeaders headers) {
         String url = daJiaCrawlerProperties.getBaseUrl() + RequestUrl.INIT_DATA.uri();
-        requestComponent.objectPost(url, request, String.class, headers);
+        requestComponent.post(url, request, String.class, headers);
+    }
+
+    /**
+     * 初始化数据
+     *
+     * @param request 初始化数据
+     * @param headers 请求头
+     * @return 初始化数据响应
+     */
+    public String  initImgData(DaJiaCrawlerInitDataRequest request, HttpHeaders headers) {
+        String url = daJiaCrawlerProperties.getBaseUrl() + RequestUrl.INIT_DATA.uri();
+        ResponseEntity<String> stringResponseEntity = requestComponent.daJiaImgPost(url, request, String.class, headers);
+        return stringResponseEntity.getHeaders().getFirst("X-Imp-Token");
     }
 
     /**
@@ -356,6 +368,11 @@ public class DaJiaCrawlerRequestComponent {
         String url = RequestUrl.QRCODE.getRequestUrl(daJiaCrawlerProperties.getBaseUrl()) + "/" + orderNo + "/1";
         MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
         map.add("operatorCode", operatorCode);
+        try {
+            Thread.sleep(5000);
+        }catch (Exception e){
+            e.printStackTrace();
+        }
         DaJiaCrawlerBaseResponse daJiaCrawlerBaseResponse = requestComponent.get(url, map, "", DaJiaCrawlerBaseResponse.class, headers);
         return DESEncryption.decryptStrToObject(daJiaCrawlerBaseResponse.getResult(), DaJiaCrawlerQrcodeResponse.class);
     }
@@ -388,4 +405,14 @@ public class DaJiaCrawlerRequestComponent {
         return  DESEncryption.decryptStrToObject(response.getResult(), DaJiaCrawlerDownloadResponse.class);
     }
 
+    public void policyQuery(String lastPolicyNo, HttpHeaders headers,String userCode) {
+        if (StringUtils.isEmpty(lastPolicyNo)){
+            return;
+        }
+        MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
+        map.add("operatorCode",userCode);
+        String body = requestComponent.get(RequestUrl.POLICY_QUERY.getRequestUrl(daJiaCrawlerProperties.getBaseUrl()) + lastPolicyNo, map, "", String.class, headers);
+        String string1 = DESEncryption.decryptStrToObject(body, String.class);
+        log.info("返回数据:{}",string1);
+    }
 }

+ 2 - 0
tenant/insurance/quotation-dajia/src/main/java/com/jzg/quotation/dajia/crawler/constant/enums/RequestUrl.java

@@ -38,6 +38,8 @@ public enum RequestUrl implements CrawlerRequestUrlStandard {
     ELECTRON_POLICY_IO_DOWNLOAD("/api_vhl_prod/api/electronPolicyIODownload", "下载保单"),
     // 状态查询
     ORDER_LIST_REVISED("/api_vhl_prod/api/orderListRevised", "订单状态查询"),
+    // 政策查询
+    POLICY_QUERY("/api_vhl_prod/api/policyquery/","政策查询"),
     ;
 
     private final String uri;

+ 3 - 0
tenant/insurance/quotation-dajia/src/main/java/com/jzg/quotation/dajia/crawler/entity/po/DaJiaCrawlerOrder.java

@@ -1,5 +1,6 @@
 package com.jzg.quotation.dajia.crawler.entity.po;
 
+import com.jzg.quotation.dajia.crawler.entity.response.DaJiaCrawlerSaveResponse;
 import lombok.AllArgsConstructor;
 import lombok.Data;
 import lombok.NoArgsConstructor;
@@ -64,4 +65,6 @@ public class DaJiaCrawlerOrder {
      */
     private String createTime;
 
+    private DaJiaCrawlerSaveResponse saveResponse;
+
 }

+ 1 - 1
tenant/insurance/quotation-dajia/src/main/java/com/jzg/quotation/dajia/crawler/entity/request/DaJiaCrawlerChannelPackagesRequest.java

@@ -43,7 +43,7 @@ public class DaJiaCrawlerChannelPackagesRequest {
     public DaJiaCrawlerChannelPackagesRequest(DaJiaCrawlerConfigureParameters parameters, String operatorCode) {
         this.loginCompany = parameters.getLoginCompany();
         this.companyCode = parameters.getCDptCde();
-        this.combineProductCode = parameters.getCombineProductCode();
+        this.combineProductCode = "1469";
         this.operatorCode = operatorCode;
     }
 }

+ 8 - 4
tenant/insurance/quotation-dajia/src/main/java/com/jzg/quotation/dajia/crawler/entity/request/DaJiaCrawlerPriceRequest.java

@@ -137,13 +137,17 @@ public class DaJiaCrawlerPriceRequest implements Serializable {
         // 商业险
         if (!ObjectUtils.isEmpty(quoteVo.getBiRiskInfoVo())) {
             this.businessInsurance = new BusinessInsuranceDTO(quoteVo.getBiRiskInfoVo(), quoteVo.getKindInfoVo());
-            proposalInfo.setMark("3");
         }else {
             this.businessInsurance = new BusinessInsuranceDTO();
         }
-
-        if (!ObjectUtils.isEmpty(quoteVo.getBiRiskInfoVo()) && !ObjectUtils.isEmpty(quoteVo.getCiRiskInfoVo())) {
+        boolean hasBiRisk = !ObjectUtils.isEmpty(quoteVo.getBiRiskInfoVo());
+        boolean hasCiRisk = !ObjectUtils.isEmpty(quoteVo.getCiRiskInfoVo());
+        if (hasBiRisk && hasCiRisk) {
             proposalInfo.setMark("1");
+        } else if (hasCiRisk) {
+            proposalInfo.setMark("2");
+        } else if (hasBiRisk) {
+            proposalInfo.setMark("3");
         }
         this.checkCarInformationDTO = new CheckCarInfomationDTO();
         String vehicleExhaust = car.getVehicleExhaust();
@@ -157,7 +161,7 @@ public class DaJiaCrawlerPriceRequest implements Serializable {
         }
         String startTime;
         String endTime;
-        if (!compulsoryInsurance.getProductInfo().getStartDate().equals("")) {
+        if (!ObjectUtils.isEmpty(quoteVo.getCiRiskInfoVo())) {
             startTime = compulsoryInsurance.getProductInfo().getStartDate();
             endTime = compulsoryInsurance.getProductInfo().getEndDate();
         } else {

+ 5 - 0
tenant/insurance/quotation-dajia/src/main/java/com/jzg/quotation/dajia/crawler/entity/response/DaJiaCrawlerCarResponse.java

@@ -280,5 +280,10 @@ public class DaJiaCrawlerCarResponse implements Serializable {
         public String getPurchasePrice() {
             return vehiclePrice;
         }
+
+        @Override
+        public String getSeatCount() {
+            return String.valueOf(vehicleSeat);
+        }
     }
 }

+ 1 - 0
tenant/insurance/quotation-dajia/src/main/java/com/jzg/quotation/dajia/crawler/service/impl/DaJiaCrawlerOrderServiceImpl.java

@@ -22,6 +22,7 @@ public class DaJiaCrawlerOrderServiceImpl implements DaJiaCrawlerOrderService {
     @Override
     public void saveOrderInfo(QuoteVo quoteVo, DaJiaCrawlerSaveResponse daJiaCrawlerSaveResponse,  String businessNo) {
         DaJiaCrawlerOrder daJiaCrawlerOrder = new DaJiaCrawlerOrder();
+        daJiaCrawlerOrder.setSaveResponse(daJiaCrawlerSaveResponse);
         daJiaCrawlerOrder.setId(quoteVo.getOrder().getOrdersNo());
         daJiaCrawlerOrder.setOrdersNo(daJiaCrawlerSaveResponse.getProposalInfo().getOrderNo());
         // 交强投保单号

+ 24 - 1
tenant/insurance/quotation-dajia/src/main/java/com/jzg/quotation/dajia/crawler/service/impl/DaJiaCrawlerQuoteProcessServiceImpl.java

@@ -10,6 +10,7 @@ import com.jzg.quotation.dajia.crawler.entity.response.DaJiaCrawlerCheckTokenRes
 import com.jzg.quotation.dajia.crawler.service.DaJiaCrawlerQuoteProcessService;
 import com.jzg.quotation.dajia.crawler.utils.DESEncryption;
 import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
 import org.springframework.http.HttpHeaders;
 import org.springframework.http.ResponseEntity;
 import org.springframework.stereotype.Service;
@@ -17,6 +18,8 @@ import org.springframework.util.StringUtils;
 
 import java.util.Optional;
 
+
+@Slf4j
 @Service
 @RequiredArgsConstructor
 public class DaJiaCrawlerQuoteProcessServiceImpl implements DaJiaCrawlerQuoteProcessService {
@@ -62,7 +65,7 @@ public class DaJiaCrawlerQuoteProcessServiceImpl implements DaJiaCrawlerQuotePro
     @Override
     public HttpHeaders getHeaders(String username, String password) {
         String authorization = daJiaCrawlerCacheComponent.getAuthorization(username);
-        if (!StringUtils.hasLength(authorization)) {
+        if (!StringUtils.hasText(authorization) || isTokenInvalid(username)) {
             authorization = login(username, password);
         }
         HttpHeaders headers = new HttpHeaders();
@@ -74,6 +77,26 @@ public class DaJiaCrawlerQuoteProcessServiceImpl implements DaJiaCrawlerQuotePro
         return headers;
     }
 
+    private boolean isTokenInvalid(String username) {
+        String userCode = daJiaCrawlerCacheComponent.getUserCode(username);
+        String tokenId = daJiaCrawlerCacheComponent.getTokenId(username);
+
+        try {
+            checkToken(userCode, tokenId);
+            return false;
+        } catch (Exception e) {
+            String errorMsg = e.getMessage();
+            // 401 代表 token 过期/未授权 → 标记为无效
+            if (errorMsg != null && errorMsg.contains("401 Unauthorized from")) {
+                log.warn("token 过期,自动重新登录: {}", errorMsg);
+                return true;
+            }
+            // 其他异常直接抛出
+            log.error("登录校验异常: {}", e.getMessage(), e);
+            throw new SystemException("登录异常");
+        }
+    }
+
     /**
      * 校验token
      * @param userCode

+ 35 - 8
tenant/insurance/quotation-dajia/src/main/java/com/jzg/quotation/dajia/crawler/service/impl/DaJiaCrawlerRequestImpl.java

@@ -1,13 +1,13 @@
 package com.jzg.quotation.dajia.crawler.service.impl;
 
 
-import com.jzg.commons.constants.dict.InsOrderStatusEnum;
+import com.alibaba.fastjson2.JSONObject;
 import com.jzg.commons.entity.quote.vo.AttributionInformationVo;
 import com.jzg.commons.entity.quote.vo.QuoteVo;
 import com.jzg.commons.entity.quote.vo.aggregated.*;
 import com.jzg.commons.entity.quote.vo.base.LoginBase;
 import com.jzg.commons.entity.quote.vo.image.InsuranceImageVo;
-import com.jzg.commons.util.MinioUtils;
+import com.jzg.commons.exception.SystemException;
 import com.jzg.quotation.commons.annotation.QuoteCrawlerService;
 import com.jzg.quotation.commons.constant.InsuranceCode;
 import com.jzg.quotation.commons.filter.CarModelsFilterUtils;
@@ -18,7 +18,6 @@ import com.jzg.quotation.dajia.crawler.build.DajiaCrawlerAuditResultsVoBuild;
 import com.jzg.quotation.dajia.crawler.component.BuildingAttributionInformation;
 import com.jzg.quotation.dajia.crawler.component.DaJiaCrawlerCacheComponent;
 import com.jzg.quotation.dajia.crawler.component.DaJiaCrawlerRequestComponent;
-import com.jzg.quotation.dajia.crawler.constant.enums.DaJiaCrawlerOrderState;
 import com.jzg.quotation.dajia.crawler.entity.DaJiaCrawlerConfigureParameters;
 import com.jzg.quotation.dajia.crawler.entity.po.DaJiaCrawlerOrder;
 import com.jzg.quotation.dajia.crawler.entity.request.*;
@@ -31,6 +30,8 @@ import com.jzg.quotation.dajia.crawler.service.DaJiaCrawlerQuoteProcessService;
 import com.jzg.quotation.dajia.crawler.service.DaJiaCrawlerRequest;
 import com.jzg.quotation.dajia.crawler.utils.ImagesEncrypt;
 import lombok.RequiredArgsConstructor;
+import lombok.extern.log4j.Log4j2;
+import org.redisson.api.RedissonClient;
 import org.springframework.http.HttpHeaders;
 import org.springframework.util.StringUtils;
 
@@ -57,6 +58,7 @@ import java.util.stream.Collectors;
  * @author wenks
  * @since 2025/2/12
  */
+@Log4j2
 @QuoteCrawlerService(value = InsuranceCode.INSURANCE_DJPC)
 @RequiredArgsConstructor
 public class DaJiaCrawlerRequestImpl implements DaJiaCrawlerRequest {
@@ -76,6 +78,8 @@ public class DaJiaCrawlerRequestImpl implements DaJiaCrawlerRequest {
     /** 大家财险爬虫报价流程服务,负责登录认证和请求头管理 */
     private final DaJiaCrawlerQuoteProcessService daJiaCrawlerQuoteProcessService;
 
+    private final RedissonClient redissonClient;
+
     /**
      * 用户登录认证
      * 
@@ -110,12 +114,10 @@ public class DaJiaCrawlerRequestImpl implements DaJiaCrawlerRequest {
         AttributionInformationVo attributionInformationVo = quoteVo.getOrder().getAttributionInformationVo();
         HttpHeaders headers = daJiaCrawlerQuoteProcessService.getHeaders(attributionInformationVo.getUsername(), attributionInformationVo.getPassword());
         String userCode = daJiaCrawlerCacheComponent.getUserCode(attributionInformationVo.getUsername());
-
         // 1.1 解析配置参数
         DaJiaCrawlerConfigureParameters parameters = ConfigureParametersConversion.conversionEntity(DaJiaCrawlerConfigureParameters.class, attributionInformationVo.getConfigInfo());
         // 1.2 构建归属信息(机构、套餐、渠道信息)
         ProposalInfoDTO proposalInfoDTO = buildingAttributionInformation.build(parameters, userCode, headers);
-
         // 2.0 车型查询
         DaJiaCrawlerCarRequest daJiaCrawlerCarRequest = new DaJiaCrawlerCarRequest(quoteVo.getCarInfoVo(), parameters.getLoginCompany(), parameters.getCDptCde(), userCode);
         DaJiaCrawlerCarResponse daJiaCrawlerCarResponse = daJiaCrawlerRequestComponent.car(daJiaCrawlerCarRequest, headers);
@@ -142,9 +144,15 @@ public class DaJiaCrawlerRequestImpl implements DaJiaCrawlerRequest {
             businessInsuranceDTO.getProductInfo().setEndDate(endTime);
             crawlerPriceResponse = daJiaCrawlerRequestComponent.price(daJiaCrawlerPriceRequest, headers);
         }
+        String lastPolicyNo = crawlerPriceResponse.getCompulsoryInsurance().getProductInfo().getLastPolicyNo();
+
+        daJiaCrawlerRequestComponent.policyQuery(lastPolicyNo,headers,userCode);
+
+        log.info("报价返回参数:{}", JSONObject.toJSONString(crawlerPriceResponse));
         // 3.1 保存订单到保险公司系统
         DaJiaCrawlerSaveRequest daJiaCrawlerSaveRequest = new DaJiaCrawlerSaveRequest(crawlerPriceResponse, userCode, quoteVo);
         DaJiaCrawlerSaveResponse daJiaCrawlerSaveResponse = daJiaCrawlerRequestComponent.save(daJiaCrawlerSaveRequest, headers);
+        log.info("daJiaCrawlerSaveResponse:{}",JSONObject.toJSONString(daJiaCrawlerSaveResponse));
         // 3.2 初始化订单数据
         DaJiaCrawlerInitDataRequest daJiaCrawlerInitDataRequest = new DaJiaCrawlerInitDataRequest(daJiaCrawlerSaveResponse.getCompulsoryInsurance(), daJiaCrawlerSaveResponse.getBusinessInsurance());
         daJiaCrawlerRequestComponent.initData(daJiaCrawlerInitDataRequest, headers);
@@ -158,6 +166,8 @@ public class DaJiaCrawlerRequestImpl implements DaJiaCrawlerRequest {
         return DaJiaCrawlerQuoteResultsVoBuild.buildQuoteResultsVo(quoteVo.getOrder().getOrdersNo(), quoteVo, daJiaCrawlerSaveResponse);
     }
 
+
+
     // 截取重复投保终保日期
     private static final Pattern DUPLICATE_END_TIME_PATTERN = Pattern.compile("终保日期 (\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2})");
 
@@ -176,6 +186,8 @@ public class DaJiaCrawlerRequestImpl implements DaJiaCrawlerRequest {
     }
 
 
+
+
     /**
      * 订单核保处理
      * 
@@ -194,7 +206,15 @@ public class DaJiaCrawlerRequestImpl implements DaJiaCrawlerRequest {
         DaJiaCrawlerSaveResponse daJiaCrawlerSaveResponse = daJiaCrawlerCacheComponent.getDaJiaCrawlerSaveResponse(daJiaCrawlerOrder.getOrdersNo());
         // 提交核保申请
         DaJiaCrawlerGenerateResponse response = daJiaCrawlerRequestComponent.generate(daJiaCrawlerSaveResponse, headers);
-        return DajiaCrawlerAuditResultsVoBuild.buildUnderwritingResultsVo(daJiaCrawlerOrder.getOrdersNo(), response);
+        log.info("大家核保数据返回:{}",JSONObject.toJSONString(response));
+        UnderwritingResultsVo underwritingResultsVo = DajiaCrawlerAuditResultsVoBuild.buildUnderwritingResultsVo(daJiaCrawlerOrder.getOrdersNo(), response);
+        if (response.getStatus().equals("4")){
+            PaymentLinkVo paymentLinkVo = new PaymentLinkVo();
+            paymentLinkVo.setOrder(underwritingVo.getOrder());
+            PaymentLinkResultsVo paymentLink = getPaymentLink(paymentLinkVo);
+            underwritingResultsVo.setPaymentLink(paymentLink.getPaymentLink());
+        }
+        return underwritingResultsVo;
     }
 
     /**
@@ -207,13 +227,15 @@ public class DaJiaCrawlerRequestImpl implements DaJiaCrawlerRequest {
      */
     @Override
     public PaymentLinkResultsVo getPaymentLink(PaymentLinkVo paymentLinkVo) {
+
         AttributionInformationVo attributionInformationVo = paymentLinkVo.getOrder().getAttributionInformationVo();
         DaJiaCrawlerOrder daJiaCrawlerOrder = daJiaCrawlerOrderService.getById(paymentLinkVo.getOrder().getOrdersNo());
         HttpHeaders headers = daJiaCrawlerQuoteProcessService.getHeaders(attributionInformationVo.getUsername(), attributionInformationVo.getPassword());
         String userCode = daJiaCrawlerCacheComponent.getUserCode(attributionInformationVo.getUsername());
         // 生成支付二维码
         DaJiaCrawlerQrcodeResponse daJiaCrawlerQrcodeResponse = daJiaCrawlerRequestComponent.qrcode(daJiaCrawlerOrder.getOrdersNo(), userCode, headers);
-        return new PaymentLinkResultsVo(true, daJiaCrawlerQrcodeResponse.getUrl(), "");
+        log.info("获取支付链接返回数据:{}",JSONObject.toJSONString(daJiaCrawlerQrcodeResponse));
+        return new PaymentLinkResultsVo(true, daJiaCrawlerQrcodeResponse.getImageContent(), "");
     }
 
     /**
@@ -238,12 +260,17 @@ public class DaJiaCrawlerRequestImpl implements DaJiaCrawlerRequest {
         DaJiaCrawlerOrder daJiaCrawlerOrder = daJiaCrawlerOrderService.getById(insuranceUploadImageVo.getOrder()
                 .getOrdersNo());
         List<InsuranceImageVo> imageVoList = insuranceUploadImageVo.getImageVoList();
-        
+        DaJiaCrawlerInitDataRequest daJiaCrawlerInitDataRequest = new DaJiaCrawlerInitDataRequest(daJiaCrawlerOrder.getSaveResponse().getCompulsoryInsurance(), daJiaCrawlerOrder.getSaveResponse().getBusinessInsurance());
+        headers.set("X-Imp-Token",daJiaCrawlerRequestComponent.initImgData(daJiaCrawlerInitDataRequest, headers));
+
         // 按影像类型分组处理
         imageVoList.forEach(imageVo -> {
             // 1. 获取上传文件标志和预签名URL
             DaJiaCrawlerUploadSignsRequest daJiaCrawlerUploadSignsRequest = new DaJiaCrawlerUploadSignsRequest(daJiaCrawlerOrder.getBusinessNo(), imageVo.getInsuranceImageCode(), imageVo.getImageBase64List());
             DaJiaCrawlerUploadSignsResponse daJiaCrawlerUploadSignsResponse = daJiaCrawlerRequestComponent.uploadSigns(daJiaCrawlerUploadSignsRequest, headers);
+            if (com.jzg.commons.util.StringUtils.equals("FAIL",daJiaCrawlerUploadSignsResponse.getCode())){
+                throw new SystemException("获取上传影像异常:" + daJiaCrawlerUploadSignsResponse.getMessage());
+            }
             // 2. 构建文件名到上传信息的映射
             Map<String, DaJiaCrawlerUploadSignsResponse.DataDTO> dataDTOMap = daJiaCrawlerUploadSignsResponse.getData()
                     .stream()

+ 12 - 13
tenant/insurance/quotation-guoren/src/main/java/com/jzg/quotation/guoren/api/build/GuoRenApiQuoteResultsVoBuild.java

@@ -34,29 +34,25 @@ public class GuoRenApiQuoteResultsVoBuild {
         quoteResultsVo.setQuoteStatusEnum(InsOrderStatusEnum.WAIT_AUDIT);
 
         // 交强保费 车船税 商业保费
-        buildPremium(quoteResultsVo, premiumResponse,nonAutoInsOrderResponse);
+        buildPremium(quoteResultsVo, premiumResponse, nonAutoInsOrderResponse);
 
         QuoteResultsVo.ScoreVo scoreVo = new QuoteResultsVo.ScoreVo();
         scoreVo.setLossRation(premiumResponse.getData().getAutoPriceOutputXOMRespVo().getBillELR());
         scoreVo.setJqLossRation(premiumResponse.getData().getAutoPriceOutputXOMRespVo().getBillCTPELR());
         scoreVo.setSyLossRation(premiumResponse.getData().getAutoPriceOutputXOMRespVo().getBillCOMELR());
-        scoreVo.setCiClaims(premiumResponse.getData().getCiInsureDemandDTOS().get(0).getClaimTimes());
-        scoreVo.setBiClaims(premiumResponse.getData().getCiInsureDemandDTOS().get(0).getClaimTimes());
+        if (premiumResponse.getData().getCiInsureDemandDTOS() != null && premiumResponse.getData().getCiInsureDemandDTOS().size() > 0) {
+            scoreVo.setCiClaims(premiumResponse.getData().getCiInsureDemandDTOS().get(0).getClaimTimes());
+            scoreVo.setBiClaims(premiumResponse.getData().getCiInsureDemandDTOS().get(0).getClaimTimes());
+        }
         scoreVo.setTotalAdjustRate(premiumResponse.getData().getSignDiscount());
 
         // 保司评分
         JSONArray scoreJson = new JSONArray();
         //光博评分
-        scoreJson.add(new JSONObject()
-                .fluentPut("scoreName", "交强光博分")
-                .fluentPut("scoreKey", "score")
-                .fluentPut("score", premiumResponse.getData().getCirate().getBillcomeGroup()));
+        scoreJson.add(new JSONObject().fluentPut("scoreName", "交强光博分").fluentPut("scoreKey", "score").fluentPut("score", premiumResponse.getData().getCirate().getBillcomeGroup()));
 
         if (premiumResponse.getData().getBirate() != null) {
-            scoreJson.add(new JSONObject()
-                    .fluentPut("scoreName", "商业光博分")
-                    .fluentPut("scoreKey", "score")
-                    .fluentPut("score", premiumResponse.getData().getBirate().getBillcomeGroup()));
+            scoreJson.add(new JSONObject().fluentPut("scoreName", "商业光博分").fluentPut("scoreKey", "score").fluentPut("score", premiumResponse.getData().getBirate().getBillcomeGroup()));
         }
 
         scoreVo.setScoreJson(scoreJson);
@@ -67,6 +63,7 @@ public class GuoRenApiQuoteResultsVoBuild {
 
     /**
      * 处理商业险数据
+     *
      * @param premiumResponse
      * @return
      */
@@ -81,6 +78,7 @@ public class GuoRenApiQuoteResultsVoBuild {
 
     /**
      * 处理交强险数据
+     *
      * @param premiumResponse
      * @return riskInfoVo
      */
@@ -95,13 +93,13 @@ public class GuoRenApiQuoteResultsVoBuild {
 
     /**
      * 处理商业险信息
+     *
      * @param kindInfoVo
      * @param itemVOListDTOS
      * @return
      */
     private static List<KindInfoVo> buildKindInfoVo(List<KindInfoVo> kindInfoVo, List<PremiumResponse.DataDTO.ItemVOListDTO> itemVOListDTOS) {
-        Map<String, PremiumResponse.DataDTO.ItemVOListDTO> collect = itemVOListDTOS.stream()
-                .collect(Collectors.toMap(PremiumResponse.DataDTO.ItemVOListDTO::getKindCode, x -> x));
+        Map<String, PremiumResponse.DataDTO.ItemVOListDTO> collect = itemVOListDTOS.stream().collect(Collectors.toMap(PremiumResponse.DataDTO.ItemVOListDTO::getKindCode, x -> x));
         kindInfoVo.forEach(kind -> {
             PremiumResponse.DataDTO.ItemVOListDTO itemVOListDTO = collect.get(kind.getKindCode());
             if (itemVOListDTO.getKindCode().equals(kind.getKindCode())) {
@@ -116,6 +114,7 @@ public class GuoRenApiQuoteResultsVoBuild {
 
     /**
      * 设置商业险,交强险保费
+     *
      * @param quoteResultsVo
      * @param premiumResponse
      */

+ 5 - 0
tenant/insurance/quotation-guoren/src/main/java/com/jzg/quotation/guoren/crawler/entity/response/GuoRenCrawlerQueryByVinNoData.java

@@ -223,6 +223,11 @@ public class GuoRenCrawlerQueryByVinNoData implements Serializable, CarModelsFil
         return this.carYear;
     }
 
+    @Override
+    public String getSeatCount(){
+        return String.valueOf((int) Double.parseDouble(seatCount.toString()));
+    }
+
     @NoArgsConstructor
     @Data
     public static class ContentDTO {

+ 5 - 0
tenant/insurance/quotation-guoren/src/main/java/com/jzg/quotation/guoren/crawler/entity/response/GuoRenCrawlerQueryCarModelData.java

@@ -181,6 +181,11 @@ public class GuoRenCrawlerQueryCarModelData implements Serializable {
             return String.valueOf(purchasePrice);
         }
 
+        @Override
+        public String getSeatCount() {
+            return String.valueOf((int) Double.parseDouble(seatCount.toString()));
+        }
+
     }
 
 }

+ 1 - 1
tenant/insurance/quotation-guoren/src/main/java/com/jzg/quotation/guoren/crawler/service/impl/GuoRenCrawlerQuoteProcessServiceImpl.java

@@ -52,7 +52,7 @@ public class GuoRenCrawlerQuoteProcessServiceImpl implements GuoRenCrawlerQuoteP
     public HttpHeaders getHeaders(String username) {
         HttpHeaders headers = new HttpHeaders();
 //        String token = guoRenCrawlerCacheComponent.getToken(username);
-        String token = "eyJhbGciOiJSUzI1NiJ9.eyJzdWIiOiJXMzAwMDM5OSIsInVzZXJJZCI6IjQ5NjE4MSIsIm5hbWUiOiLmnY7mmKXmooUiLCJleHAiOjE3Nzg4MTAyNzh9.h_xSPQiUCs_yJDjjr_Dz6vtM4J5rmIteytOmjDrjOXDDjd-n0nEVkw6sdtJJIZ1Z8BUcucyfsTy5R1sR5KHrkvlOWUvGMcfh0rjf5WtyYkfjZIH68abjTQmBuvf3BnZqHgGhaS-75wyfJ2d0t7dSAZx1VDFYIUwP51tmOl4awX4";
+        String token = "eyJhbGciOiJSUzI1NiJ9.eyJzdWIiOiJXMzAwMDM5OSIsInVzZXJJZCI6IjQ5NjE4MSIsIm5hbWUiOiLmnY7mmKXmooUiLCJleHAiOjE3Nzg5MjY2MDB9.UYGTs0DQgbZJinMWJExUV18JhfJW23JonveQVVq6N5Muy_vu6Py8pL-AI5Ohv0BDoCCfdOD7SjLmiCqGy4uU9130O1_QlLzyxsriiBKUPXPJKbipftpqSdjYyFSgfNSIySO99hs005Ip89HnkaT34ephMA-C8jyyxGShQdNkuxI";
         if (!StringUtils.hasText(token)) {
             throw new SystemException("登录失败,请重新登录");
         }

+ 5 - 0
tenant/insurance/quotation-guoshou/src/main/java/com/jzg/quotation/guoshou/crawler/entity/response/GsCrawlerCarQueryResponse.java

@@ -591,6 +591,11 @@ public class GsCrawlerCarQueryResponse implements BaseResponse{
         public String getPurchasePrice() {
             return this.purchasePrice;
         }
+
+        @Override
+        public String getSeatCount() {
+            return this.seat;
+        }
     }
 
 

+ 42 - 18
tenant/insurance/quotation-hengbang/src/main/java/com/jzg/quotation/hengbang/crawler/build/HbCrawlerQuoteResultVoBuild.java

@@ -1,6 +1,7 @@
 package com.jzg.quotation.hengbang.crawler.build;
 
 import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.util.StrUtil;
 import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
 import com.jzg.commons.constants.dict.InsOrderStatusEnum;
@@ -10,6 +11,8 @@ import com.jzg.commons.entity.quote.vo.aggregated.QuoteResultsVo;
 import com.jzg.commons.entity.quote.vo.QuoteVo;
 import com.jzg.quotation.hengbang.crawler.entity.response.HbCrawlerProposalResponse;
 
+import java.time.ZonedDateTime;
+import java.time.format.DateTimeFormatter;
 import java.util.List;
 import java.util.Map;
 import java.util.Objects;
@@ -37,7 +40,7 @@ public final class HbCrawlerQuoteResultVoBuild {
         //交强险
         quoteResultsVo.setCiRiskInfoVo(buildCiInfo(proposalResponse));
         //商业险
-        quoteResultsVo.setBiRiskInfoVo(buildbiInfo(proposalResponse));
+        quoteResultsVo.setBiRiskInfoVo(buildBiInfo(proposalResponse));
         quoteResultsVo.setKindInfoVo(buildKindInfoList(proposalResponse, quoteVo));
 
         QuoteResultsVo.ScoreVo scoreVo = new QuoteResultsVo.ScoreVo();
@@ -45,22 +48,13 @@ public final class HbCrawlerQuoteResultVoBuild {
         JSONArray scoreJson = new JSONArray();
         if (proposalResponse.getForceLiability() != null && proposalResponse.getCarInsureLiabilityList().size() > 0) {
             //光博评分
-            scoreJson.add(new JSONObject()
-                    .fluentPut("scoreName", "交强光博分")
-                    .fluentPut("scoreKey", "score")
-                    .fluentPut("score", proposalResponse.getBusiCarInsureRisk().getBillelr2()));
+            scoreJson.add(new JSONObject().fluentPut("scoreName", "交强光博分").fluentPut("scoreKey", "score").fluentPut("score", proposalResponse.getBusiCarInsureRisk().getBillelr2()));
         } else if (proposalResponse.getForceLiability() != null) {
             //光博评分
-            scoreJson.add(new JSONObject()
-                    .fluentPut("scoreName", "交强光博分")
-                    .fluentPut("scoreKey", "score")
-                    .fluentPut("score", proposalResponse.getForceCarInsureRisk().getBillelr2()));
+            scoreJson.add(new JSONObject().fluentPut("scoreName", "交强光博分").fluentPut("scoreKey", "score").fluentPut("score", proposalResponse.getForceCarInsureRisk().getBillelr2()));
         } else if (proposalResponse.getCarInsureLiabilityList().size() > 0) {
             //光博评分
-            scoreJson.add(new JSONObject()
-                    .fluentPut("scoreName", "交强光博分")
-                    .fluentPut("scoreKey", "score")
-                    .fluentPut("score", proposalResponse.getBusiCarInsureRisk().getBillelr2()));
+            scoreJson.add(new JSONObject().fluentPut("scoreName", "交强光博分").fluentPut("scoreKey", "score").fluentPut("score", proposalResponse.getBusiCarInsureRisk().getBillelr2()));
 
         }
 
@@ -78,20 +72,20 @@ public final class HbCrawlerQuoteResultVoBuild {
         HbCrawlerProposalResponse.ForceCarInsureRiskDTO forceCarInsureRisk = proposalResponse.getForceCarInsureRisk();
         if (Objects.nonNull(forceCarInsureRisk)) {
             ciRiskInfoVo.setRiskCode(forceCarInsureRisk.getRiskcode());
-            ciRiskInfoVo.setStartDate(forceCarInsureRisk.getBegintime());
-            ciRiskInfoVo.setEndDate(forceCarInsureRisk.getEndtime());
+            ciRiskInfoVo.setStartDate(parseDate(forceCarInsureRisk.getBegintime()));
+            ciRiskInfoVo.setEndDate(parseDate(forceCarInsureRisk.getEndtime()));
         }
         return ciRiskInfoVo;
 
     }
 
-    public static RiskInfoVo buildbiInfo(HbCrawlerProposalResponse proposalResponse) {
+    public static RiskInfoVo buildBiInfo(HbCrawlerProposalResponse proposalResponse) {
         RiskInfoVo biRiskInfoVo = new RiskInfoVo();
         HbCrawlerProposalResponse.BusiCarInsureRiskDTO busiCarInsureRisk = proposalResponse.getBusiCarInsureRisk();
         if (Objects.nonNull(busiCarInsureRisk)) {
             biRiskInfoVo.setRiskCode(busiCarInsureRisk.getRiskcode());
-            biRiskInfoVo.setStartDate(busiCarInsureRisk.getBegintime());
-            biRiskInfoVo.setEndDate(busiCarInsureRisk.getEndtime());
+            biRiskInfoVo.setStartDate(parseDate(busiCarInsureRisk.getBegintime()));
+            biRiskInfoVo.setEndDate(parseDate(busiCarInsureRisk.getEndtime()));
         }
         return biRiskInfoVo;
     }
@@ -131,4 +125,34 @@ public final class HbCrawlerQuoteResultVoBuild {
         //设置非车保费
         quoteResultsVo.getCosts().setNiPremium(proposalResponse.getAccidentTotalPremium());
     }
+
+    /**
+     * 将日期字符串标准化为 yyyy-MM-dd HH:mm:ss 格式
+     * 支持多种日期格式:
+     * - ISO格式:yyyy-MM-ddTHH:mm:ss+08:00(含时区)
+     * - 完整格式:yyyy-MM-dd HH:mm:ss
+     * - 简短格式:yyyy-MM-dd(自动补充时间为00:00:00)
+     *
+     * @param dateStr 日期字符串,可以为null或空字符串
+     * @return 标准化后的日期字符串,如果输入为空则返回null
+     */
+    private static String parseDate(String dateStr) {
+        if (StrUtil.isEmpty(dateStr)) {
+            return null;
+        }
+
+        // 处理仅包含日期的字符串(长度为10),补充默认时间
+        if (dateStr.length() == 10) {
+            return dateStr + " 00:00:00";
+        }
+
+        // 如果包含T或时区信息,使用ISO格式解析后转换
+        if (dateStr.contains("T") || dateStr.contains("+") || dateStr.contains("Z")) {
+            ZonedDateTime zonedDateTime = ZonedDateTime.parse(dateStr, DateTimeFormatter.ISO_OFFSET_DATE_TIME);
+            return zonedDateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
+        }
+
+        // 已满足 yyyy-MM-dd HH:mm:ss 格式,直接返回
+        return dateStr;
+    }
 }

+ 27 - 21
tenant/insurance/quotation-hengbang/src/main/java/com/jzg/quotation/hengbang/crawler/component/HengBangCrawlerRequestComponent.java

@@ -83,7 +83,7 @@ public class HengBangCrawlerRequestComponent {
      * @param loginsNumber 登录次数
      * @return token
      */
-    public String  authenticate(String username, String password, int loginsNumber) {
+    public String authenticate(String username, String password, int loginsNumber) {
         // 登录验证码获取
         HbCrawlerCaptchaResponse captchaResponse = captcha(RequestConstant.REQUEST_NUMBER);
         // 登录存入缓存当中
@@ -146,26 +146,27 @@ public class HengBangCrawlerRequestComponent {
         param.set("sysCategory", "2");
         param.set("resourceType", "HBXSH");
         HttpHeaders headers = new HttpHeaders();
-        headers.set(HttpHeaders.ACCEPT,"*/*");
-        headers.set(HttpHeaders.CONTENT_TYPE,"application/x-www-form-urlencode;charset=utf-8");
-        headers.set(HttpHeaders.USER_AGENT,"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/135.0.0.0 Safari/537.36");
-        headers.set(HttpHeaders.AUTHORIZATION,getAuthorization(username));
-        HbCrawlerQueryUserInfoResponse response = requestComponent.get(RequestUrl.QUERY_USER_INFO.getRequestUrl(hbCrawlerProperties.getBaseUrl()) + "/" + username,param,RequestUrl.QUERY_USER_INFO.getRequestDescription(),HbCrawlerQueryUserInfoResponse.class,headers);
+        headers.set(HttpHeaders.ACCEPT, "*/*");
+        headers.set(HttpHeaders.CONTENT_TYPE, "application/x-www-form-urlencode;charset=utf-8");
+        headers.set(HttpHeaders.USER_AGENT, "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/135.0.0.0 Safari/537.36");
+        headers.set(HttpHeaders.AUTHORIZATION, getAuthorization(username));
+        HbCrawlerQueryUserInfoResponse response = requestComponent.get(RequestUrl.QUERY_USER_INFO.getRequestUrl(hbCrawlerProperties.getBaseUrl()) + "/" + username, param, RequestUrl.QUERY_USER_INFO.getRequestDescription(), HbCrawlerQueryUserInfoResponse.class, headers);
         return response;
     }
 
     /**
      * 获取行业车型信息
+     *
      * @param queryCarInfoRequest
      * @param headers
      */
     public HbCrawlerQueryCarRequest.CbitDataDTO queryCarInfo(HbCrawlerQueryCarInfoRequest queryCarInfoRequest, HttpHeaders headers) {
         MultiValueMap<String, String> param = RequestObjectConversion.convertMultiValueStringMap(queryCarInfoRequest);
-        String response = requestComponent.get(RequestUrl.QUERY_CAR_INFO.getRequestUrl(hbCrawlerProperties.getBaseUrl()) ,param,RequestUrl.QUERY_CAR_INFO.getRequestDescription(),String.class,headers);
+        String response = requestComponent.get(RequestUrl.QUERY_CAR_INFO.getRequestUrl(hbCrawlerProperties.getBaseUrl()), param, RequestUrl.QUERY_CAR_INFO.getRequestDescription(), String.class, headers);
         JSONObject res = JSONObject.parseObject(response);
         String ciphertextB64 = res.getString("hb_enc_d");
         String plaintext = null;
-        try{
+        try {
             plaintext = HengBangAESUtil.decryptStr(ciphertextB64);
         } catch (Exception e) {
             throw new SystemException("解密失败");
@@ -193,8 +194,9 @@ public class HengBangCrawlerRequestComponent {
 
     /**
      * AES-256-CBC 解密
+     *
      * @param ciphertextB64 Base64 编码的密文(前16字节是IV)
-     * @param key 32字节密钥(256位)
+     * @param key           32字节密钥(256位)
      * @return 解密后的明文
      * @throws Exception
      */
@@ -231,7 +233,7 @@ public class HengBangCrawlerRequestComponent {
      * @return
      */
     public List<HbCrawlerQueryCarResponse.ContentDTO> queryCar(HbCrawlerQueryCarRequest queryCarRequest, HttpHeaders headers) {
-        HbCrawlerQueryCarResponse queryCarResponse = requestComponent.toStringPost(RequestUrl.QUERY_CAR.getRequestUrl(hbCrawlerProperties.getBaseUrl()), queryCarRequest,RequestUrl.QUERY_CAR.getRequestDescription(), HbCrawlerQueryCarResponse.class, headers);
+        HbCrawlerQueryCarResponse queryCarResponse = requestComponent.toStringPost(RequestUrl.QUERY_CAR.getRequestUrl(hbCrawlerProperties.getBaseUrl()), queryCarRequest, RequestUrl.QUERY_CAR.getRequestDescription(), HbCrawlerQueryCarResponse.class, headers);
         return queryCarResponse.getContent();
     }
 
@@ -293,18 +295,19 @@ public class HengBangCrawlerRequestComponent {
             mapper.setSerializationInclusion(JsonInclude.Include.ALWAYS);
             String json = mapper.writeValueAsString(calculationRequest);
             req.setHbEncD(HengBangAESUtil.encryptStr(json));
-            HbCrawlerSaleInfoResponse response = requestComponent.toStringPost(RequestUrl.CALCULATION.getRequestUrl(hbCrawlerProperties.getBaseUrl()), req, RequestUrl.CALCULATION.getRequestDescription(),HbCrawlerSaleInfoResponse.class, headers);
+            HbCrawlerSaleInfoResponse response = requestComponent.toStringPost(RequestUrl.CALCULATION.getRequestUrl(hbCrawlerProperties.getBaseUrl()), req, RequestUrl.CALCULATION.getRequestDescription(), HbCrawlerSaleInfoResponse.class, headers);
             System.out.println(HengBangAESUtil.decryptStr(response.getHbEncD()));
             String resJson = HengBangAESUtil.decryptStr(response.getHbEncD());
             return resJson;
         } catch (WebClientResponseException e) {
-            if(e.getStatusCode().equals(HttpStatusCode.valueOf(500))){
-                return JSONObject.parseObject(e.getMessage()).getString("detail");
-            }else{
+            log.error("恒邦calculation接口调用失败[{}]: {}", e.getStatusCode(), e.getResponseBodyAsString());
+            final JSONObject jsonObject = JSONObject.parseObject(e.getResponseBodyAsString());
+            if (jsonObject.getInteger("status") == 500) {
+                return jsonObject.getString("detail");
+            } else {
                 throw new SystemException(e.getMessage());
             }
-        }
-        catch (Exception e) {
+        } catch (Exception e) {
             throw new SystemException(e.getMessage());
         }
     }
@@ -320,7 +323,7 @@ public class HengBangCrawlerRequestComponent {
         MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
         String encryptPlyappno;
         try {
-            encryptPlyappno =  HengBangAESUtil.encryptStr(plyappno);
+            encryptPlyappno = HengBangAESUtil.encryptStr(plyappno);
             System.out.println("encryptPlyappno1 ===========" + encryptPlyappno);
             encryptPlyappno = new StringBuilder(RequestConstant.ENCRYPTPRE).append(encryptPlyappno)
                     .toString();
@@ -382,12 +385,13 @@ public class HengBangCrawlerRequestComponent {
     public String coreProposal(String plyappno, HttpHeaders headers, List<Map<String, String>> paramList) {
         try {
             String requestBody = JSON.toJSONString(paramList);
-            ResponseEntity<String> responseEntity = requestComponent.objectPost(RequestUrl.SUBMIT.getRequestUrl(hbCrawlerProperties.getBaseUrl()) + "/" +plyappno, requestBody, String.class, headers);
+            ResponseEntity<String> responseEntity = requestComponent.objectPost(RequestUrl.SUBMIT.getRequestUrl(hbCrawlerProperties.getBaseUrl()) + "/" + plyappno, requestBody, String.class, headers);
             return JSONObject.parseObject(responseEntity.getBody()).getString("message");
         } catch (WebClientResponseException e) {
-            if(e.getStatusCode().equals(HttpStatusCode.valueOf(500))){
+            log.error("恒邦calculation接口调用失败[{}]: {}", e.getStatusCode(), e.getResponseBodyAsString());
+            if (e.getStatusCode().equals(HttpStatusCode.valueOf(500))) {
                 return JSONObject.parseObject(e.getMessage()).getString("detail");
-            }else{
+            } else {
                 throw new SystemException(e.getMessage());
             }
         }
@@ -395,6 +399,7 @@ public class HengBangCrawlerRequestComponent {
 
     /**
      * 获取核保信息
+     *
      * @param plyappno
      * @param headers
      * @return
@@ -481,7 +486,8 @@ public class HengBangCrawlerRequestComponent {
         List<Object> response = requestComponent.get(RequestUrl.LAST_ACCIDENT.getRequestUrl(hbCrawlerProperties.getBaseUrl()).concat(plyappno),
                 map,
                 "",
-                new ParameterizedTypeReference<>(){},
+                new ParameterizedTypeReference<>() {
+                },
                 headers);
         return CollectionUtils.emptyIfNull(response)
                 .stream()

+ 18 - 2
tenant/insurance/quotation-hengbang/src/main/java/com/jzg/quotation/hengbang/crawler/service/Impl/HengBangCrawlerRequestImpl.java

@@ -14,6 +14,7 @@ import com.jzg.commons.constants.ProductsType;
 import com.jzg.commons.constants.dict.InsOrderStatusEnum;
 import com.jzg.commons.constants.quote.enums.base.InsuranceImageEnum;
 import com.jzg.commons.entity.orders.po.InsOrdersCarUserInfo;
+import com.jzg.commons.entity.po.SysUploadFiles;
 import com.jzg.commons.entity.quote.vo.AttributionInformationVo;
 import com.jzg.commons.entity.quote.vo.CarInfoVo;
 import com.jzg.commons.entity.quote.vo.QuoteVo;
@@ -21,7 +22,10 @@ import com.jzg.commons.entity.quote.vo.aggregated.*;
 import com.jzg.commons.entity.quote.vo.base.LoginBase;
 import com.jzg.commons.entity.quote.vo.image.InsuranceImageVo;
 import com.jzg.commons.exception.SystemException;
+import com.jzg.commons.util.Base64Convert;
+import com.jzg.commons.util.MinioUtils;
 import com.jzg.quotation.commons.annotation.QuoteCrawlerService;
+import com.jzg.quotation.commons.client.PlatformClient;
 import com.jzg.quotation.commons.constant.InsuranceCode;
 import com.jzg.quotation.commons.filter.CarModelsFilterUtils;
 import com.jzg.quotation.commons.standard.conversion.ConfigureParametersConversion;
@@ -38,9 +42,12 @@ import com.jzg.quotation.hengbang.crawler.properties.HengBangCrawlerProperties;
 import com.jzg.quotation.hengbang.crawler.service.HbCrawlerOrderService;
 import com.jzg.quotation.hengbang.crawler.service.HengBangCrawlerRequest;
 import lombok.RequiredArgsConstructor;
+import org.apache.commons.compress.utils.IOUtils;
 import org.springframework.http.HttpHeaders;
 
 
+import java.io.IOException;
+import java.io.InputStream;
 import java.time.LocalDateTime;
 import java.time.format.DateTimeFormatter;
 import java.time.temporal.ChronoUnit;
@@ -63,6 +70,10 @@ public class HengBangCrawlerRequestImpl implements HengBangCrawlerRequest {
 
     private final HengBangCrawlerProperties hbCrawlerProperties;
 
+    private final PlatformClient platformClient;
+
+    private final MinioUtils minioUtils;
+
     /**
      * 登录
      *
@@ -85,7 +96,6 @@ public class HengBangCrawlerRequestImpl implements HengBangCrawlerRequest {
         //http://192.168.5.250:8080/quote/quote
 
 
-
         // 1.0 获取token的请求头
         AttributionInformationVo attributionInformationVo = quoteVo.getOrder().getAttributionInformationVo();
         HttpHeaders headers = hbCrawlerRequestComponent.getHeaders(attributionInformationVo.getUsername(), attributionInformationVo.getPassword());
@@ -349,7 +359,13 @@ public class HengBangCrawlerRequestImpl implements HengBangCrawlerRequest {
             for (InsuranceImageVo insuranceImageVo : imageVoList) {
                 List<InsuranceImageVo.ImageDTO> imageBase64List = insuranceImageVo.getImageBase64List();
                 if (CollUtil.isNotEmpty(imageBase64List)) {
-                    fileBuff.add("data:image/jpeg;base64," + imageBase64List.get(0).getImageBase64Str());
+                    InsuranceImageVo.ImageDTO imageDTO = imageBase64List.get(0);
+                    String base64Str = imageDTO.getImageBase64Str();
+                    if (base64Str.startsWith("http")) {
+                        SysUploadFiles uploadFile = platformClient.getUploadFile(imageDTO.getImageId());
+                        base64Str =  minioUtils.getBase64Str(uploadFile.getBucketName(), uploadFile.getFileName());
+                    }
+                    fileBuff.add("data:image/jpeg;base64," + base64Str);
                     if (InsuranceImageEnum.C02.getCode().equals(insuranceImageVo.getImageCode())) {
                         fileType.add("01,06,03,投保业务-旧车-证件");
                         mark3.add("6");

+ 1 - 1
tenant/insurance/quotation-hengbang/src/main/java/com/jzg/quotation/hengbang/crawler/utils/HengBangAESUtil.java

@@ -46,7 +46,7 @@ public class HengBangAESUtil {
 
     public static void main(String[] args) throws Exception {
         String input =
-                "IDH83VBWNOrvNUPpVrdsmDYSP5mnY6UPq6OcbU6xJR4=";
+                "+JTEWrnKYuBWvJEwfftpAEP3zAsrpI0vAF0D1lWpUzulgmrb950t3X8fzzySTcytGMsbHsymR4cqADhc4wO6XDegVAl4ccA5Jn+GXNU8Jcya5muO5LAd0VK5bjI7MW+pJa1RPjKSWphvUt+HEtheIfJOUsOIAEc8wITYSYMLlaeoc/PmFqLgnEE45xppZRsQrmA9oSuijNpbATYPhMvRTYzK6RGEGI42pRaOFRqi+d0vZE7WeV/h5kcFAxIFFWJqY1I5SxlHW4+5dW0KPz2lrLAwxFh7qK6G38cu/RkGgGyD3lHdbCoUMYZzZ7Cgf5DDUrdQxjLvscJSge0f11ia2g==";
         System.out.println(decryptStr(input));
 
         String json = "T070302080120260014158";

+ 3 - 1
tenant/insurance/quotation-huanong/src/main/java/com/jzg/quotation/huanong/crawler/build/HuaNongCrawlerQuoteResultsVoBuild.java

@@ -24,6 +24,8 @@ public final class HuaNongCrawlerQuoteResultsVoBuild {
     public static QuoteResultsVo buildQuoteResultsVo(String orderNo, QuoteVo quoteVo, HuaNongCrawlerQuotedPriceResponse huaNongCrawlerQuotedPriceResponse, HuaNongCrawlerSaveResponse saveResponse) {
         QuoteResultsVo quoteResultsVo = new QuoteResultsVo();
         quoteResultsVo.setOrdersNo(orderNo);
+        quoteResultsVo.setCiRiskInfoVo(quoteVo.getCiRiskInfoVo());
+        quoteResultsVo.setBiRiskInfoVo(quoteVo.getBiRiskInfoVo());
 
         List<HuaNongCrawlerQuotedPriceResponse.BusinessDataDTO.ContractDTO> contract = huaNongCrawlerQuotedPriceResponse.getBusinessData()
                 .getContract();
@@ -58,7 +60,7 @@ public final class HuaNongCrawlerQuoteResultsVoBuild {
             if (Risk.RISK_0507.getRiskCode().equals(contractDTO.getContractMain().getRiskCode())) {
                 // 交强险
                 buildRiskInfoVo(quoteVo.getCiRiskInfoVo(), contractDTO.getContractMain());
-                quoteResultsVo.getCosts().setCiPremium(String.valueOf(contractDTO.getContractMain().getTotalStandardPremium()));
+                quoteResultsVo.getCosts().setCiPremium(String.valueOf(contractDTO.getContractMain().getTotalPremium()));
                 quoteResultsVo.getCosts().setVvTax(String.valueOf(contractDTO.getTax().getSumTax()));
                 quoteResultsVo.setCiPolicyNumber(contractDTO1.getContractMain().getContractNo());
             } else {

+ 5 - 0
tenant/insurance/quotation-huanong/src/main/java/com/jzg/quotation/huanong/crawler/entity/response/HuaNongCrawlerModelsQueryResponse.java

@@ -56,6 +56,11 @@ public class HuaNongCrawlerModelsQueryResponse implements HuaNongHeadResponse {
             return fullCarData.getPurchasePrice();
         }
 
+        @Override
+        public String getSeatCount() {
+            return String.valueOf(fullCarData.approvedPassengersCapacity);
+        }
+
         @NoArgsConstructor
         @Data
         public static class FullCarDataDTO {

+ 5 - 0
tenant/insurance/quotation-huanong/src/main/java/com/jzg/quotation/huanong/crawler/entity/response/HuaNongCrawlerPrecisionServiceSearchResponse.java

@@ -76,6 +76,11 @@ public class HuaNongCrawlerPrecisionServiceSearchResponse implements HuaNongHead
             return fullCarData.getPurchasePrice();
         }
 
+        @Override
+        public String getSeatCount() {
+            return String.valueOf(fullCarData.approvedPassengersCapacity);
+        }
+
         @NoArgsConstructor
         @Data
         public static class FullCarDataDTO {

+ 127 - 15
tenant/insurance/quotation-huanong/src/main/java/com/jzg/quotation/huanong/crawler/service/impl/HuaNongCrawlerRequestImpl.java

@@ -123,47 +123,155 @@ public class HuaNongCrawlerRequestImpl implements HuaNongCrawlerRequest {
             HuaNongCrawlerQuotedPriceRequestRequest request,
             HuaNongCrawlerQuotedPriceResponse response,
             HttpHeaders httpHeaders) {
-        // 检查是否有重复投保
+
         if (response == null || response.getBusinessData() == null) {
             return response;
         }
 
         List<HuaNongCrawlerQuotedPriceResponse.BusinessDataDTO.ContractDTO> contractList = response.getBusinessData().getContract();
-        if (contractList == null) {
+        if (contractList == null || contractList.isEmpty()) {
             return response;
         }
 
-        // 遍历检查并处理重复投保
+        boolean hasDuplicateInsurance = false;
+
+        // 第一次遍历:检查是否有需要处理的重复投保
         for (HuaNongCrawlerQuotedPriceResponse.BusinessDataDTO.ContractDTO contract : contractList) {
             if (contract.getPlatFormMessage() == null) {
                 continue;
             }
+
             String ciReinsureMsg = contract.getPlatFormMessage().getCiReinsureMessage();
             String biReinsureMsg = contract.getPlatFormMessage().getBiReinsureMessage();
-            boolean isCiReInsure = StringUtils.hasText(ciReinsureMsg) && ciReinsureMsg.contains("重复投保");
-            boolean isBiReInsure = StringUtils.hasText(biReinsureMsg) && biReinsureMsg.contains("重复投保");
 
-            if (isCiReInsure || isBiReInsure) {
-                // 调整日期并重试
-                response = repeatQuote(request, contract, httpHeaders);
+            // 同时检查"重复投保"和"终保日期"
+            boolean isCiDuplicate = StringUtils.hasText(ciReinsureMsg) &&
+                    (ciReinsureMsg.contains("重复投保") || ciReinsureMsg.contains("终保日期"));
+            boolean isBiDuplicate = StringUtils.hasText(biReinsureMsg) &&
+                    (biReinsureMsg.contains("重复投保") || biReinsureMsg.contains("终保日期"));
+
+            if (isCiDuplicate || isBiDuplicate) {
+                hasDuplicateInsurance = true;
+                break;
             }
         }
 
-        // 重试后再次检查,如果仍然重复投保则抛出异常
+        if (!hasDuplicateInsurance) {
+            return response;
+        }
+
+        // 处理重复投保:调整日期并重试
+        response = processDuplicateInsurance(request, response, httpHeaders);
+
+        // 检查重试后是否仍然重复投保
+        return checkAndHandleRemainingDuplicate(response);
+    }
+
+    private HuaNongCrawlerQuotedPriceResponse processDuplicateInsurance(
+            HuaNongCrawlerQuotedPriceRequestRequest request,
+            HuaNongCrawlerQuotedPriceResponse response,
+            HttpHeaders httpHeaders) {
+
         for (HuaNongCrawlerQuotedPriceResponse.BusinessDataDTO.ContractDTO contract : response.getBusinessData().getContract()) {
             if (contract.getPlatFormMessage() == null) {
                 continue;
             }
+
+            String riskCode = contract.getContractMain().getRiskCode();
             String ciReinsureMsg = contract.getPlatFormMessage().getCiReinsureMessage();
             String biReinsureMsg = contract.getPlatFormMessage().getBiReinsureMessage();
-            if ((StringUtils.hasText(ciReinsureMsg) && ciReinsureMsg.contains("重复投保")) ||
-                    (StringUtils.hasText(biReinsureMsg) && biReinsureMsg.contains("重复投保"))) {
-                String errorMsg = (StringUtils.hasText(ciReinsureMsg) ? "交强险:" + ciReinsureMsg : "") +
-                        (StringUtils.hasText(biReinsureMsg) ? " 商业险:" + biReinsureMsg : "");
-                throw new SystemException("重复投保处理失败:" + errorMsg);
+
+            boolean needAdjustCi = "0507".equals(riskCode) &&
+                    StringUtils.hasText(ciReinsureMsg) &&
+                    (ciReinsureMsg.contains("重复投保") || ciReinsureMsg.contains("终保日期"));
+
+            boolean needAdjustBi = "0510".equals(riskCode) &&
+                    StringUtils.hasText(biReinsureMsg) &&
+                    (biReinsureMsg.contains("重复投保") || biReinsureMsg.contains("终保日期"));
+
+            if (needAdjustCi || needAdjustBi) {
+                adjustPolicyDate(request, riskCode, contract);
+            }
+        }
+
+        return huaNongCrawlerRequestComponent.quotedPrice(request, httpHeaders);
+    }
+
+    private void adjustPolicyDate(HuaNongCrawlerQuotedPriceRequestRequest request,
+                                  String riskCode, HuaNongCrawlerQuotedPriceResponse.BusinessDataDTO.ContractDTO contract) {
+
+        String lastExpireDate = "";
+
+        if ("0507".equals(riskCode)) {
+            // 交强险:优先使用 ciReinsureEndDate
+            lastExpireDate = contract.getPlatFormMessage().getCiReinsureEndDate();
+        } else if ("0510".equals(riskCode)) {
+            // 商业险:优先使用 biReinsureEndDate,其次使用 lastPolicyExpireDate
+            String biReinsureEndDate = contract.getPlatFormMessage().getBiReinsureEndDate();
+            String lastPolicyExpireDate = contract.getPlatFormMessage().getLastPolicyExpireDate();
+
+            if (StringUtils.hasText(biReinsureEndDate)) {
+                lastExpireDate = biReinsureEndDate;
+            } else if (StringUtils.hasText(lastPolicyExpireDate)) {
+                lastExpireDate = lastPolicyExpireDate;
             }
         }
 
+        if (StringUtils.hasText(lastExpireDate)) {
+            // 统一日期格式
+            lastExpireDate = ensureDateTimeFormat(lastExpireDate);
+
+            String finalLastExpireDate = lastExpireDate;
+            request.getBusinessData().getContract().stream()
+                    .filter(dto -> riskCode.equals(dto.getContractMain().getRiskCode()))
+                    .findFirst()
+                    .ifPresent(dto -> {
+                        dto.getContractMain().setValidDate(finalLastExpireDate);
+                        dto.getContractMain().setExpiryDate(TimeProcessing.minusOneSecondAfterYear(finalLastExpireDate));
+                    });
+        }
+    }
+
+    private HuaNongCrawlerQuotedPriceResponse checkAndHandleRemainingDuplicate(HuaNongCrawlerQuotedPriceResponse response) {
+        if (response == null || response.getBusinessData() == null ||
+                response.getBusinessData().getContract() == null) {
+            return response;
+        }
+
+        StringBuilder errorMsg = new StringBuilder();
+
+        for (HuaNongCrawlerQuotedPriceResponse.BusinessDataDTO.ContractDTO contract : response.getBusinessData().getContract()) {
+            if (contract.getPlatFormMessage() == null) {
+                continue;
+            }
+
+            String ciReinsureMsg = contract.getPlatFormMessage().getCiReinsureMessage();
+            String biReinsureMsg = contract.getPlatFormMessage().getBiReinsureMessage();
+
+            boolean stillCiDuplicate = StringUtils.hasText(ciReinsureMsg) &&
+                    (ciReinsureMsg.contains("重复投保") || ciReinsureMsg.contains("终保日期"));
+            boolean stillBiDuplicate = StringUtils.hasText(biReinsureMsg) &&
+                    (biReinsureMsg.contains("重复投保") || biReinsureMsg.contains("终保日期"));
+
+            if (stillCiDuplicate) {
+                if (errorMsg.length() > 0) {
+                    errorMsg.append("----------------------");
+                }
+                errorMsg.append("交强险:").append(ciReinsureMsg);
+            }
+
+            if (stillBiDuplicate) {
+                if (errorMsg.length() > 0) {
+                    errorMsg.append("----------------------");
+                }
+                errorMsg.append("商业险:").append(biReinsureMsg);
+            }
+        }
+
+        if (errorMsg.length() > 0) {
+            throw new SystemException("重复投保处理失败:" + errorMsg.toString());
+        }
+
         return response;
     }
 
@@ -557,7 +665,11 @@ public class HuaNongCrawlerRequestImpl implements HuaNongCrawlerRequest {
         HuaNongCrawlerFindBusinessesRequestRequest huaNongCrawlerFindBusinessesRequest
                 = new HuaNongCrawlerFindBusinessesRequestRequest(loginInfoDto.getToken(), loginInfoDto.getLoginComCode(), policyNo, order.getRecordingTime());
         HuaNongCrawlerFindBusinessesResponse businesses = huaNongCrawlerRequestComponent.findBusinesses(huaNongCrawlerFindBusinessesRequest, httpHeaders);
-        return new OrderStatusResultVo();
+        OrderStatusResultVo vo  =  new OrderStatusResultVo();
+        vo.setOrderStatus(InsOrderStatusEnum.UNDERWRITED);
+        vo.setJqPolicyno(order.getCiPolicyNumber());
+        vo.setJyPolicyno(order.getNiInfos().get(0).getNiPolicyNumber());
+        return vo;
     }
 
     /**

+ 5 - 0
tenant/insurance/quotation-huatai/src/main/java/com/jzg/quotation/huatai/api/entity/response/HuaTaiModelsQueryResponse.java

@@ -101,6 +101,11 @@ public class HuaTaiModelsQueryResponse extends HuaTaiBaseResponse {
             public String getPurchasePrice() {
                 return String.valueOf(purchasePrice);
             }
+
+            @Override
+            public String getSeatCount() {
+                return String.valueOf(approvedPassengersCapacity);
+            }
         }
     }
 

+ 5 - 0
tenant/insurance/quotation-huatai/src/main/java/com/jzg/quotation/huatai/crawler/entity/Response/HtCrawlerCarQueryResponse.java

@@ -165,6 +165,11 @@ public class HtCrawlerCarQueryResponse implements Serializable {
             public String getPurchasePrice() {
                 return this.purchasePrice;
             }
+
+            @Override
+            public String getSeatCount() {
+                return this.limitloadperson;
+            }
         }
 
         @Data

+ 5 - 0
tenant/insurance/quotation-renbao/src/main/java/com/jzg/quotation/renbao/crawler/entity/response/RenBaoCrawlerVehicleQueryData.java

@@ -174,6 +174,11 @@ public class RenBaoCrawlerVehicleQueryData {
             public String getPurchasePrice() {
                 return this.priceT;
             }
+
+            @Override
+            public String getSeatCount() {
+                return String.valueOf(this.vehicleSeat);
+            }
         }
     }
 }

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

@@ -6,6 +6,7 @@ import cn.hutool.core.date.DateTime;
 import cn.hutool.core.util.ArrayUtil;
 import cn.hutool.core.util.StrUtil;
 import cn.hutool.json.JSONUtil;
+import com.alibaba.fastjson.JSON;
 import com.alibaba.nacos.common.utils.CollectionUtils;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.fasterxml.jackson.core.JsonProcessingException;
@@ -273,6 +274,7 @@ public class UnifyOrderManager {
             if (CollUtil.isNotEmpty(quoteVo.getKindInfoVo())) {
                 QuoteInfoConverter.converterKindInfoVo(quoteVo.getKindInfoVo(), quoteKindMappingMap.get(QuoteRuleCategory.KIND.getCode()), quoteVo.getCarInfoVo());
             }
+            log.info("报价后数据");
             quoteResultsVo = quoteService.quote(quoteVo);
             // 格式化保费为两位小数
             QuoteResultsVo.CostsVo costs = quoteResultsVo.getCosts();
@@ -287,6 +289,7 @@ public class UnifyOrderManager {
             quoteResultsVo.setOrdersNo(ordersNo);
             // 报价后更新订单
             insOrdersService.orderAfterUpdateQuote(ordersNo, quoteResultsVo);
+            log.info("报价返回:{}", JSON.toJSONString(quoteResultsVo));
 
             //////////////////////////////////////////新增营销抽奖活动////////////////////////////////////////////////
             //远程调用活动列表

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

@@ -79,6 +79,7 @@ import java.net.URL;
 import java.time.Instant;
 import java.time.LocalDate;
 import java.time.LocalDateTime;
+import java.time.ZonedDateTime;
 import java.time.format.DateTimeFormatter;
 import java.util.*;
 import java.util.stream.Collectors;
@@ -720,7 +721,8 @@ public class InsOrdersServiceImpl extends ServiceImpl<InsOrdersMapper, InsOrders
 
     /**
      * 将日期字符串解析为LocalDateTime对象
-     * 支持两种日期格式:
+     * 支持多种日期格式:
+     * - ISO格式:yyyy-MM-ddTHH:mm:ss+08:00(含时区)
      * - 完整格式:yyyy-MM-dd HH:mm:ss
      * - 简短格式:yyyy-MM-dd(自动补充时间为00:00:00)
      *
@@ -731,12 +733,20 @@ public class InsOrdersServiceImpl extends ServiceImpl<InsOrdersMapper, InsOrders
         if (StrUtil.isEmpty(dateStr)) {
             return null;
         }
-        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
 
         // 处理仅包含日期的字符串(长度为10),补充默认时间
         if (dateStr.length() == 10) {
+            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
             return LocalDateTime.parse(dateStr + " 00:00:00", formatter);
         }
+
+        // 如果包含T或时区信息,使用ISO格式解析
+        if (dateStr.contains("T") || dateStr.contains("+") || dateStr.contains("Z")) {
+            return ZonedDateTime.parse(dateStr, DateTimeFormatter.ISO_OFFSET_DATE_TIME).toLocalDateTime();
+        }
+
+        // 使用标准格式解析
+        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
         return LocalDateTime.parse(dateStr, formatter);
     }
 

+ 5 - 0
tenant/insurance/quotation-taishan/src/main/java/com/jzg/quotation/taishan/crawler/entity/response/TaiShanCrawlerCarResponse.java

@@ -264,5 +264,10 @@ public class TaiShanCrawlerCarResponse implements Serializable,TaiShanCrawlerBas
         public String getPurchasePrice() {
             return this.newVehiclePrice;
         }
+
+        @Override
+        public String getSeatCount() {
+            return this.newSeatNumber;
+        }
     }
 }

+ 5 - 0
tenant/insurance/quotation-yangguang/src/main/java/com/jzg/quotation/yangguang/api/entity/response/YangGuangQueryVehicleModelResponse.java

@@ -219,6 +219,11 @@ public class YangGuangQueryVehicleModelResponse extends YangGuangBaseResponse {
         public String getPurchasePrice() {
             return Purchaseprice;
         }
+
+        @Override
+        public String getSeatCount() {
+            return Seatcount;
+        }
     }
 
     /**

+ 5 - 0
tenant/insurance/quotation-zhongan/src/main/java/com/jzg/quotation/zhongan/crawler/entity/response/ZhongAnCrawlerCarQueryResponse.java

@@ -167,6 +167,11 @@ public class ZhongAnCrawlerCarQueryResponse extends ZhongAnCrawlerBaseResponse {
                     public String getCarYear() {
                         return marketDate;
                     }
+
+                    @Override
+                    public String getSeatCount() {
+                        return seat;
+                    }
                 }
 
                 @Data

+ 5 - 0
tenant/insurance/quotation-zhongmei/src/main/java/com/jzg/quotation/zhongmei/api/entity/response/ModelsQueryResponse.java

@@ -240,5 +240,10 @@ public class ModelsQueryResponse extends BaseResponse{
             return purchasePrice;
         }
 
+        @Override
+        public String getSeatCount() {
+            return String.valueOf(approvedPassengersCapacity);
+        }
+
     }
 }

+ 17 - 1
tenant/insurance/quotation-zhongmei/src/main/java/com/jzg/quotation/zhongmei/crawler/build/ZmCrawlerQuoteResultVoBuild.java

@@ -1,5 +1,7 @@
 package com.jzg.quotation.zhongmei.crawler.build;
 
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
 import com.jzg.commons.constants.ProductsType;
 import com.jzg.commons.constants.dict.InsOrderStatusEnum;
 import com.jzg.commons.entity.quote.vo.KindInfoVo;
@@ -23,7 +25,6 @@ public final class ZmCrawlerQuoteResultVoBuild {
     public static QuoteResultsVo build(QuoteVo quoteVo, ZmCrawlerQuotedPriceResponse quotedPriceResponse) {
         QuoteResultsVo quoteResultsVo = new QuoteResultsVo();
         if(!"0".equals(quotedPriceResponse.getHead().getReturnCode())){
-            quoteResultsVo.setCiRiskInfoVo(buildCiInfo(quotedPriceResponse));
             quoteResultsVo.setQuoteStatusEnum(InsOrderStatusEnum.QUOTE_FAIL);
             quoteResultsVo.setErrorMessage(quotedPriceResponse.getHead().getReturnMessage());
             return quoteResultsVo;
@@ -36,6 +37,8 @@ public final class ZmCrawlerQuoteResultVoBuild {
         //商业险
         quoteResultsVo.setBiRiskInfoVo(buildbiInfo(quotedPriceResponse));
         quoteResultsVo.setKindInfoVo(buildKindInfoList(quotedPriceResponse, quoteVo));
+        // 评分
+        quoteResultsVo.setScoreVo(buildScore(quotedPriceResponse));
         //设置保费,车船税,投保单号
         buildParams(quotedPriceResponse, quoteResultsVo);
         return quoteResultsVo;
@@ -121,4 +124,17 @@ public final class ZmCrawlerQuoteResultVoBuild {
         }
     }
 
+    public static QuoteResultsVo.ScoreVo buildScore(ZmCrawlerQuotedPriceResponse quotedPriceResponse) {
+        QuoteResultsVo.ScoreVo scoreVo = new QuoteResultsVo.ScoreVo();
+        ZmCrawlerQuotedPriceResponse.BussinessMainDTO.ContractDTO.APQtnResultXomDTO apQtnResultXomDTO = quotedPriceResponse.getBussinessMain().getContract().get(0).getAPQtnResultXom();
+        if (apQtnResultXomDTO.getGusunlightresultmainDto() != null) {
+            JSONArray scoreJson = new JSONArray();
+            scoreJson.add(new JSONObject()
+                    .fluentPut("scoreName", "中煤分")
+                    .fluentPut("scoreKey","zmScore")
+                    .fluentPut("score", apQtnResultXomDTO.getGusunlightresultmainDto().getZmScore()));
+        }
+        return scoreVo;
+    }
+
 }

+ 1 - 1
tenant/insurance/quotation-zhongmei/src/main/java/com/jzg/quotation/zhongmei/crawler/entity/Request/ZmCrawlerModelQueryRequest.java

@@ -81,7 +81,7 @@ public class ZmCrawlerModelQueryRequest extends BaseRequest {
             this.planCode= "1382";
         }
 
-        this.vin = carInfoVo.getVinNo();
+        this.vin = "";
         this.carYear = "";
         this.carType = "";
         this.deptcode = "";

+ 4 - 0
tenant/insurance/quotation-zhongmei/src/main/java/com/jzg/quotation/zhongmei/crawler/entity/Response/ZmCrawlerModelQueryResponse.java

@@ -65,6 +65,10 @@ public class ZmCrawlerModelQueryResponse extends BaseResponse {
             return String.valueOf(this.fullCarData.getPurchasePrice());
         }
 
+        public String getSeatCount() {
+            return String.valueOf(this.fullCarData.getApprovedPassengersCapacity());
+        }
+
         @NoArgsConstructor
         @Data
         public static class FullCarData implements Serializable{

+ 1 - 1
tenant/insurance/quotation-zhongmei/src/main/java/com/jzg/quotation/zhongmei/crawler/service/Impl/ZhongMeiCrawlerRequestImpl.java

@@ -334,7 +334,7 @@ public class ZhongMeiCrawlerRequestImpl implements ZhongMeiCrawlerRequest {
                 ZmCrawlerOrderApplyResponse orderApplyResponse = zmCrawlerRequestComponent.orderApply(orderApplyRequest);
                 transSerialNo = orderApplyResponse.getTransSerialNo();
             } else {
-                ZmCrawlerOrderUpdateRequest orderUpdateRequest = new ZmCrawlerOrderUpdateRequest(zmCrawlerConfigureParameters.getComCode(), zfTaskResponse.getBizTask().get(0).getTransactionNo(), "213");
+                ZmCrawlerOrderUpdateRequest orderUpdateRequest = new ZmCrawlerOrderUpdateRequest(zmCrawlerConfigureParameters.getComCode(), zfTaskResponse.getBizTask().get(0).getTransactionNo(), "216");
                 orderUpdateRequest.setHead(head);
                 ZmCrawlerOrderUpdateResponse orderUpdateResponse = zmCrawlerRequestComponent.orderUpdate(orderUpdateRequest);
                 transSerialNo = orderUpdateResponse.getTransSerialNo();

+ 9 - 0
tenant/organization/src/main/java/com/jzg/organization/client/EsmInsCompanyClient.java

@@ -9,11 +9,20 @@ import org.springframework.cloud.openfeign.FeignClient;
 import org.springframework.web.bind.annotation.*;
 
 import java.util.List;
+import java.util.Map;
 
 @FeignClient(name = "jzg-platform")
 public interface EsmInsCompanyClient {
 
 
+    /**
+     * 获取所有保险公司的全路径名称
+     * Key: 公司ID
+     * Value: 总公司/分公司/支公司
+     */
+    @GetMapping("esmInsCompany/getAllCompanyHierarchyPaths")
+    public Map<String, String> getAllCompanyHierarchyPaths();
+
     /**
      * 根据id获取保险公司信息
      *

+ 2 - 1
tenant/organization/src/main/java/com/jzg/organization/controller/ReceivableController.java

@@ -4,6 +4,7 @@ import cn.hutool.core.util.StrUtil;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.jzg.commons.core.page.HttpResult;
 import com.jzg.commons.entity.finance.dto.CompanySuperviseSettlementReportDto;
+import com.jzg.commons.entity.finance.dto.ExportSuperviseSettlementExcelDto;
 import com.jzg.commons.entity.finance.po.InsPlyIncome;
 import com.jzg.commons.entity.finance.po.InsPlyIncomeInvoiceSettlement;
 import com.jzg.commons.entity.finance.vo.*;
@@ -280,7 +281,7 @@ public class ReceivableController {
 
     @PostMapping("superviseSettlementExcel")
     @Operation(summary = "应收手续费结算记录")
-    public HttpResult superviseSettlementExcel(@RequestBody SettlementQueryVo settlementQueryVo) {
+    public HttpResult<Page<ExportSuperviseSettlementExcelDto>> superviseSettlementExcel(@RequestBody SettlementQueryVo settlementQueryVo) {
         Page page = settlementQueryVo.getPage();
         return HttpResult.ok(receivableService.superviseSettlementExcel(page,settlementQueryVo));
     }

+ 8 - 0
tenant/organization/src/main/java/com/jzg/organization/service/impl/ReceivableServiceImpl.java

@@ -495,6 +495,12 @@ public class ReceivableServiceImpl extends ServiceImpl<ReceivableMapper, InsPlyI
             invoice.setId(IdGenerate.nextId());
             invoice.setCompanyId(invoicingVo.getCompanyId());
             invoice.setInvoiceType(invoicingVo.getInvoiceType());
+            // 开票类型  1 手续费  2 跟单费  3 驾意险手续费 4 驾意险跟单费
+            if("1".equals(invoicingVo.getInvoiceType()) || "2".equals(invoicingVo.getInvoiceType())){
+                invoice.setInvoickRiskType("10");
+            }else{
+                invoice.setInvoickRiskType("20");
+            }
             invoice.setInvoiceParty(invoicingVo.getInvoiceParty());
             invoice.setOverinflatedAmount(invoicingVo.getOverinflatedAmount());
             invoice.setReceivableSupervisePremium(invoicingVo.getReceivablePremium());
@@ -1188,6 +1194,7 @@ public class ReceivableServiceImpl extends ServiceImpl<ReceivableMapper, InsPlyI
         Page<InvoiceRecordResult> invoiceRecordList = baseMapper.getInvoiceRecordList(invoiceRecordQueryVo.getPage(), invoiceRecordQueryVo);
         List<InvoiceRecordResult> records = invoiceRecordList.getRecords();
         if(CollUtil.isNotEmpty(records)){
+            Map<String, String> allCompanyHierarchyPaths = esmInsCompanyClient.getAllCompanyHierarchyPaths();
             records = records.stream().peek(action->{
                 String settlementStatusName = Constant.settlementStatusMap.get(Objects.toString(action.getStatus(),""));
                 action.setSettlementStatusName(settlementStatusName);
@@ -1206,6 +1213,7 @@ public class ReceivableServiceImpl extends ServiceImpl<ReceivableMapper, InsPlyI
                 action.setSettlementAmount(settlementAmount);
                 // 设置待结算金额
                 action.setRemainSettlementAmount(remainSettlementAmount);
+                action.setCompanyALlName(allCompanyHierarchyPaths.get(Objects.toString(action.getCompanyId(),"")));
             }).toList();
             invoiceRecordList.setRecords(records);
         }