xuqiang 1 год назад
Родитель
Сommit
26fdb07e92
39 измененных файлов с 1643 добавлено и 5 удалено
  1. 6 0
      commons/pom.xml
  2. 33 0
      commons/src/main/java/com/jzg/commons/config/resttemplate/CustomResponseErrorHandler.java
  3. 77 0
      commons/src/main/java/com/jzg/commons/config/resttemplate/IgnoreSSLRequestFactory.java
  4. 90 0
      commons/src/main/java/com/jzg/commons/config/resttemplate/RestTemplateConfig.java
  5. 33 0
      commons/src/main/java/com/jzg/commons/config/resttemplate/RestTemplateRequestInterceptor.java
  6. 28 0
      commons/src/main/java/com/jzg/commons/config/resttemplate/RestTemplateServiceUnavailableRetryStrategy.java
  7. 12 0
      commons/src/main/java/com/jzg/commons/constants/RedisKeyConstants.java
  8. 21 0
      commons/src/main/java/com/jzg/commons/constants/dict/EnabledEnum.java
  9. 65 0
      commons/src/main/java/com/jzg/commons/constants/dict/InsOrderStatusEnum.java
  10. 18 0
      commons/src/main/java/com/jzg/commons/constants/dict/VehicleTypeType.java
  11. 3 1
      commons/src/main/java/com/jzg/commons/entity/dto/InsOrdersAdd.java
  12. 43 0
      commons/src/main/java/com/jzg/commons/entity/dto/SysQueryVehicleConfigDTO.java
  13. 25 0
      commons/src/main/java/com/jzg/commons/entity/dto/SysQueryVehicleConfigQueryPageVo.java
  14. 115 0
      commons/src/main/java/com/jzg/commons/entity/po/SysQueryVehicleConfig.java
  15. 88 0
      commons/src/main/java/com/jzg/commons/entity/po/SysQueryVehicleUrl.java
  16. 38 0
      commons/src/main/java/com/jzg/commons/entity/vo/CarModelDTO.java
  17. 53 0
      commons/src/main/java/com/jzg/commons/entity/vo/InsOrdersOtherInfoVo.java
  18. 27 0
      commons/src/main/java/com/jzg/commons/entity/vo/SysQueryVehicleConfigQueryVo.java
  19. 80 0
      commons/src/main/java/com/jzg/commons/entity/vo/SysQueryVehicleConfigSaveVo.java
  20. 25 0
      tenant/insurance/quotation-summary/src/main/java/com/jzg/quotation/summary/components/FrameNumberInquiryRequest.java
  21. 61 0
      tenant/insurance/quotation-summary/src/main/java/com/jzg/quotation/summary/components/InsCrawlerOrderComponents.java
  22. 64 0
      tenant/insurance/quotation-summary/src/main/java/com/jzg/quotation/summary/components/QueryVehicleComponents.java
  23. 44 0
      tenant/insurance/quotation-summary/src/main/java/com/jzg/quotation/summary/controller/CarModelController.java
  24. 32 0
      tenant/insurance/quotation-summary/src/main/java/com/jzg/quotation/summary/extension/BaseIService.java
  25. 27 0
      tenant/insurance/quotation-summary/src/main/java/com/jzg/quotation/summary/mapper/SysQueryVehicleConfigMapper.java
  26. 16 0
      tenant/insurance/quotation-summary/src/main/java/com/jzg/quotation/summary/mapper/SysQueryVehicleUrlMapper.java
  27. 23 0
      tenant/insurance/quotation-summary/src/main/java/com/jzg/quotation/summary/request/vehicle/BaseVehicleRequest.java
  28. 25 0
      tenant/insurance/quotation-summary/src/main/java/com/jzg/quotation/summary/request/vehicle/FrameNumberInquiryRequest.java
  29. 26 0
      tenant/insurance/quotation-summary/src/main/java/com/jzg/quotation/summary/request/vehicle/VehicleModelInquiryRequest.java
  30. 25 0
      tenant/insurance/quotation-summary/src/main/java/com/jzg/quotation/summary/response/BaseVehicleResponse.java
  31. 14 0
      tenant/insurance/quotation-summary/src/main/java/com/jzg/quotation/summary/service/CarModelService.java
  32. 4 0
      tenant/insurance/quotation-summary/src/main/java/com/jzg/quotation/summary/service/InsOrdersService.java
  33. 91 0
      tenant/insurance/quotation-summary/src/main/java/com/jzg/quotation/summary/service/SysQueryVehicleConfigService.java
  34. 46 0
      tenant/insurance/quotation-summary/src/main/java/com/jzg/quotation/summary/service/SysQueryVehicleUrlService.java
  35. 99 0
      tenant/insurance/quotation-summary/src/main/java/com/jzg/quotation/summary/service/impl/CarModelServiceImpl.java
  36. 7 4
      tenant/insurance/quotation-summary/src/main/java/com/jzg/quotation/summary/service/impl/InsOrdersServiceImpl.java
  37. 124 0
      tenant/insurance/quotation-summary/src/main/java/com/jzg/quotation/summary/service/impl/SysQueryVehicleConfigServiceImpl.java
  38. 14 0
      tenant/insurance/quotation-summary/src/main/java/com/jzg/quotation/summary/service/impl/SysQueryVehicleUrlServiceImpl.java
  39. 21 0
      tenant/insurance/quotation-summary/src/main/resources/mapper/SysQueryVehicleConfigMapper.xml

+ 6 - 0
commons/pom.xml

@@ -81,6 +81,12 @@
             <artifactId>bcpkix-jdk15on</artifactId>
             <version>1.70</version>
         </dependency>
+
+        <dependency>
+            <groupId>org.apache.httpcomponents.client5</groupId>
+            <artifactId>httpclient5</artifactId>
+            <version>5.2.1</version> <!-- 请使用最新版本 -->
+        </dependency>
     </dependencies>
 
 <!--    <build>-->

+ 33 - 0
commons/src/main/java/com/jzg/commons/config/resttemplate/CustomResponseErrorHandler.java

@@ -0,0 +1,33 @@
+package com.jzg.commons.config.resttemplate;
+
+import com.jzg.commons.exception.SystemException;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.client.ClientHttpResponse;
+import org.springframework.web.client.ResponseErrorHandler;
+
+import java.io.IOException;
+
+public class CustomResponseErrorHandler implements ResponseErrorHandler {
+
+    @Override
+    public boolean hasError(ClientHttpResponse response) throws IOException {
+        int rawStatusCode = response.getRawStatusCode();
+        return rawStatusCode > 200;
+    }
+
+    // 处理错误
+    @Override
+    public void handleError(ClientHttpResponse response) throws IOException {
+        if (response.getStatusCode() == HttpStatus.REQUEST_TIMEOUT) {
+            throw new SystemException("网络超时, 请重试!");
+        }
+        if (response.getStatusCode().value() > 500) {
+            throw new SystemException("网络异常, 请重试!");
+        }
+        throw new SystemException("请求异常" + response.getStatusText());
+    }
+
+}
+
+
+

+ 77 - 0
commons/src/main/java/com/jzg/commons/config/resttemplate/IgnoreSSLRequestFactory.java

@@ -0,0 +1,77 @@
+package com.jzg.commons.config.resttemplate;
+
+import org.apache.hc.client5.http.classic.HttpClient;
+import org.springframework.http.client.SimpleClientHttpRequestFactory;
+
+import javax.net.ssl.*;
+import java.io.IOException;
+import java.net.HttpURLConnection;
+import java.security.SecureRandom;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+
+/**
+ * 绕过证书
+ */
+public class IgnoreSSLRequestFactory extends SimpleClientHttpRequestFactory {
+
+    public IgnoreSSLRequestFactory(HttpClient httpClient) {
+        super();
+    }
+
+    @Override
+    protected void prepareConnection(HttpURLConnection connection, String httpMethod)
+            throws IOException {
+        if (connection instanceof HttpsURLConnection) {
+            prepareHttpsConnection((HttpsURLConnection) connection);
+        }
+        connection.setConnectTimeout(3000);
+        connection.setReadTimeout(3000);
+        super.prepareConnection(connection, httpMethod);
+    }
+
+    private void prepareHttpsConnection(HttpsURLConnection connection) {
+        connection.setHostnameVerifier(new SkipHostnameVerifier());
+        try {
+            connection.setSSLSocketFactory(createSslSocketFactory());
+        } catch (Exception ex) {
+            // Ignore
+        }
+    }
+
+    private SSLSocketFactory createSslSocketFactory() throws Exception {
+        SSLContext context = SSLContext.getInstance("TLS");
+        context.init(null, new TrustManager[]{new SkipX509TrustManager()},
+                new SecureRandom());
+        return context.getSocketFactory();
+    }
+
+    private class SkipHostnameVerifier implements HostnameVerifier {
+
+        @Override
+        public boolean verify(String s, SSLSession sslSession) {
+            return true;
+        }
+
+    }
+
+    private static class SkipX509TrustManager implements X509TrustManager {
+
+
+        @Override
+        public void checkClientTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
+
+        }
+
+        @Override
+        public void checkServerTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
+
+        }
+
+        @Override
+        public X509Certificate[] getAcceptedIssuers() {
+            return new X509Certificate[0];
+        }
+    }
+}
+

+ 90 - 0
commons/src/main/java/com/jzg/commons/config/resttemplate/RestTemplateConfig.java

@@ -0,0 +1,90 @@
+package com.jzg.commons.config.resttemplate;
+
+import org.apache.hc.client5.http.classic.HttpClient;
+import org.apache.hc.client5.http.config.RequestConfig;
+import org.apache.hc.client5.http.impl.classic.HttpClientBuilder;
+import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManager;
+import org.apache.hc.core5.util.Timeout;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Primary;
+import org.springframework.http.client.ClientHttpRequestFactory;
+import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
+import org.springframework.web.client.RestTemplate;
+
+import java.security.KeyManagementException;
+import java.security.NoSuchAlgorithmException;
+import java.util.Collections;
+
+@Configuration
+public class RestTemplateConfig {
+
+    // 连接池最大连接数
+    private static final int MAX_TOTAL = 6400;
+
+    // 默认每条路线的最大值
+    private static final int DEFAULT_MAX_PER_ROUTE = 3200;
+
+    // 每个主机的并发
+    private static final int VALIDATE_AFTER_INACTIVITY = 30000;
+
+    private static final int IDLE_CONNECTIONS = 30;
+
+    // 返回数据的超时时间
+    private static final int SOCKET_TIMEOUT = 90 * 1000;
+
+    // 连接上服务器的超时时间
+    private static final int CONNECT_TIMEOUT = 3 * 1000;
+
+    // 从连接池中获取连接的超时时间
+    private static final int CONNECTION_REQUEST_TIMEOUT = 1000;
+
+    @Bean("restTemplate")
+    @Primary
+    public RestTemplate restTemplate() throws NoSuchAlgorithmException, KeyManagementException {
+        RestTemplate restTemplate = new RestTemplate(httpRequestFactory());
+        restTemplate.setErrorHandler(new CustomResponseErrorHandler());
+        restTemplate.setInterceptors(Collections.singletonList(new RestTemplateRequestInterceptor()));
+        return restTemplate;
+    }
+
+    @Bean
+    public ClientHttpRequestFactory httpRequestFactory() throws NoSuchAlgorithmException, KeyManagementException {
+        return new HttpComponentsClientHttpRequestFactory(httpClient());
+    }
+
+    @Bean
+    public HttpClient httpClient() {
+        // 连接池配置
+        PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager();
+        // 最大连接数
+        connectionManager.setMaxTotal(200);
+        // 每路由最大连接数
+        connectionManager.setDefaultMaxPerRoute(50);
+
+        RequestConfig requestConfig = RequestConfig.custom()
+                .setResponseTimeout(Timeout.ofMinutes(SOCKET_TIMEOUT))  //返回数据的超时时间
+                .setConnectionRequestTimeout(Timeout.ofMinutes(CONNECTION_REQUEST_TIMEOUT)) //从连接池中获取连接的超时时间
+                .build();
+
+        return HttpClientBuilder.create()
+                .setDefaultRequestConfig(requestConfig)
+                .setConnectionManager(connectionManager)
+                .evictIdleConnections(Timeout.ofMinutes(1)) // 清理空闲连接
+                .build();
+    }
+
+    /**
+     * 绕过ssl对证书进行验证,无需将证书导出到jdk管理仓库
+     */
+    @Bean("restTemplateIgnoreSSL")
+    public RestTemplate restTemplateIgnoreSSL() throws NoSuchAlgorithmException, KeyManagementException {
+        IgnoreSSLRequestFactory requestFactory = new IgnoreSSLRequestFactory(httpClient());
+        requestFactory.setConnectTimeout(60000); //连接上服务器(握手成功)的时间
+        requestFactory.setReadTimeout(60000); //返回数据时间
+        RestTemplate restTemplate = new RestTemplate(requestFactory);
+        return restTemplate;
+    }
+
+
+}

+ 33 - 0
commons/src/main/java/com/jzg/commons/config/resttemplate/RestTemplateRequestInterceptor.java

@@ -0,0 +1,33 @@
+package com.jzg.commons.config.resttemplate;
+
+import com.jzg.commons.exception.SystemException;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.http.HttpRequest;
+import org.springframework.http.client.ClientHttpRequestExecution;
+import org.springframework.http.client.ClientHttpRequestInterceptor;
+import org.springframework.http.client.ClientHttpResponse;
+
+import java.io.IOException;
+import java.net.SocketTimeoutException;
+
+@Slf4j
+public class RestTemplateRequestInterceptor implements ClientHttpRequestInterceptor {
+
+    @Override
+    public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException {
+        ClientHttpResponse execute;
+        try {
+            execute = execution.execute(request, body);
+        } catch (IOException e) {
+            log.info("appRestTemplate...error:" + e);
+            // 特殊处理超时异常
+            if (e instanceof SocketTimeoutException) {
+                // 返回自定义异常
+                throw new SystemException("请求超时请重试");
+            }
+            throw e;
+        }
+        return execute;
+    }
+
+}

+ 28 - 0
commons/src/main/java/com/jzg/commons/config/resttemplate/RestTemplateServiceUnavailableRetryStrategy.java

@@ -0,0 +1,28 @@
+package com.jzg.commons.config.resttemplate;
+
+import lombok.extern.slf4j.Slf4j;
+import org.apache.http.HttpResponse;
+import org.apache.http.annotation.Contract;
+import org.apache.http.annotation.ThreadingBehavior;
+import org.apache.http.client.ServiceUnavailableRetryStrategy;
+import org.apache.http.protocol.HttpContext;
+
+@Slf4j
+@Contract(
+        threading = ThreadingBehavior.IMMUTABLE
+)
+public class RestTemplateServiceUnavailableRetryStrategy implements ServiceUnavailableRetryStrategy {
+
+
+    @Override
+    public boolean retryRequest(HttpResponse httpResponse, int i, HttpContext httpContext) {
+        return i <= 3 &&
+                httpResponse.getStatusLine().getStatusCode() >= 500;
+    }
+
+    @Override
+    public long getRetryInterval() {
+        return 1000;
+    }
+
+}

+ 12 - 0
commons/src/main/java/com/jzg/commons/constants/RedisKeyConstants.java

@@ -21,4 +21,16 @@ public class RedisKeyConstants {
     public static final String SMS_CODE_KEY = "SMS_CODE_KEY:";
 
 
+    /**
+     * VIN查询Key
+     */
+    public static final String VIN_SEARCH_KEY = "vin:search:";
+
+
+    /**
+     * VIN查询Key存储时间 单位(小时)
+     */
+    public static final long VIN_SEARCH_KEY_TIME = 1L;
+
+
 }

+ 21 - 0
commons/src/main/java/com/jzg/commons/constants/dict/EnabledEnum.java

@@ -0,0 +1,21 @@
+package com.jzg.commons.constants.dict;
+
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+/**
+ * 开关
+ */
+@AllArgsConstructor
+@Getter
+public enum EnabledEnum {
+
+    EE_0(0, "关闭"),
+    EE_1(1, "开启");
+
+    private final Integer code;
+
+    private final String desc;
+
+}

+ 65 - 0
commons/src/main/java/com/jzg/commons/constants/dict/InsOrderStatusEnum.java

@@ -0,0 +1,65 @@
+package com.jzg.commons.constants.dict;
+
+import com.jzg.commons.constants.DictEnum;
+import com.jzg.commons.constants.IBaseEnum;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+import java.util.Objects;
+
+@Getter
+@AllArgsConstructor
+@DictEnum(key = "insOrderStatus", desc = "保险订单状态")
+public enum InsOrderStatusEnum implements IBaseEnum {
+
+    //所有未提交核保的均为报价中(包括拒保订单 )
+    QUOTE_ING("0", "报价完成", 1, 0),
+
+    //已提交核保,并转人工核保状态
+    WAIT_AUDIT("1", "待核保", 2, 0),
+
+    //自动核保或者人工核保审核通过
+    WAIT_PAY("2", "已核保待缴费", 3, 0),
+
+    //客户缴费完成生成保单状态
+    ACCEPT_INSURANCE("3", "已承保", 4, 0),
+
+    //人工核保退回状态,直至再次提交核保,状态修改为待核保
+    TO_BACK("4", "核保退回", 6, 0),
+
+    //报价失败
+    QUOTE_FAILED("10","报价失败",8,0),
+
+    //重复投保
+    REPEAT_INSURE("11","重复投保",9,0)
+
+    //撤回二维码
+//    BACK_QR_CODE("5", "撤销二维码", 7, 0),
+    ;
+
+
+    private final String code;
+
+    private final String desc;
+    //排序
+    private final Integer sort;
+    //状态  0 启用  1 不启用
+    private final Integer status;
+
+
+    public static InsOrderStatusEnum matchKey(String key) {
+        InsOrderStatusEnum result = null;
+        for (InsOrderStatusEnum e : values()) {
+            if (Objects.equals(e.getCode(), key)) {
+                result = e;
+                break;
+            }
+        }
+        return result;
+    }
+
+    public static String[] getRefuseUnderwriting() {
+        return new String[]{WAIT_AUDIT.getCode(), TO_BACK.getCode()};
+    }
+
+}

+ 18 - 0
commons/src/main/java/com/jzg/commons/constants/dict/VehicleTypeType.java

@@ -0,0 +1,18 @@
+package com.jzg.commons.constants.dict;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+@Getter
+@AllArgsConstructor
+public enum VehicleTypeType {
+
+    VTT_1(1, "车架号查询"),
+    VTT_2(2, "车辆类型查询");
+
+    private final Integer code;
+
+    private final String desc;
+
+}
+

+ 3 - 1
commons/src/main/java/com/jzg/commons/entity/dto/InsOrdersAdd.java

@@ -2,6 +2,7 @@ package com.jzg.commons.entity.dto;
 
 
 import com.jzg.commons.entity.orders.po.*;
+import com.jzg.commons.entity.vo.InsOrdersOtherInfoVo;
 import io.swagger.v3.oas.annotations.media.Schema;
 import lombok.Data;
 
@@ -24,7 +25,7 @@ public class InsOrdersAdd {
     private InsuranceInfo insuranceInfo;
 
     @Schema(description = "订单其他信息")
-    private InsOrdersOther insOrdersOther;
+    private InsOrdersOtherInfoVo insOrdersOtherInfo;
 
     @Schema(description = "电子保单")
     private InsOrdersExternalPolicy ordersExternalPolicy;
@@ -33,4 +34,5 @@ public class InsOrdersAdd {
     private InsOrdersExternalFee ordersExternal;
 
 
+
 }

+ 43 - 0
commons/src/main/java/com/jzg/commons/entity/dto/SysQueryVehicleConfigDTO.java

@@ -0,0 +1,43 @@
+package com.jzg.commons.entity.dto;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+@Schema(name = "配置信息")
+public class SysQueryVehicleConfigDTO {
+
+    @Schema(name = "保险公司id")
+    private String companyId;
+
+    @Schema(name = "保险公司名称")
+    private String companyName;
+
+    @Schema(name = "请求地址")
+    private String url;
+
+    @Schema(name = "是否开启 0 开启 1 未开启")
+    private Integer enabled;
+
+    @Schema(name = "保险公司核心用户名")
+    private String username;
+
+    @Schema(name = "保险公司核心密码")
+    private String password;
+
+    @Schema(name = "配置类型")
+    private Integer type;
+
+    @Schema(name = "请求路劲")
+    private String link;
+
+    public String getBaseUrl(){
+        return this.url + this.link;
+    }
+
+
+}

+ 25 - 0
commons/src/main/java/com/jzg/commons/entity/dto/SysQueryVehicleConfigQueryPageVo.java

@@ -0,0 +1,25 @@
+package com.jzg.commons.entity.dto;
+
+import com.jzg.commons.core.base.PageRequest;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+
+@EqualsAndHashCode(callSuper = true)
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@Schema(name = "车型查询配置实体")
+public class SysQueryVehicleConfigQueryPageVo extends PageRequest {
+
+    private static final long serialVersionUID = 1585826286550153895L;
+
+    @Schema(name = "保险公司id")
+    private String companyId;
+
+    @Schema(name = "是否开启 0 关闭 1 开启")
+    private Integer enabled;
+
+}

+ 115 - 0
commons/src/main/java/com/jzg/commons/entity/po/SysQueryVehicleConfig.java

@@ -0,0 +1,115 @@
+package com.jzg.commons.entity.po;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * 车型查询配置信息
+ * @TableName sys_query_vehicle_config
+ */
+@TableName(value ="sys_query_vehicle_config")
+@Data
+public class SysQueryVehicleConfig implements Serializable {
+    /**
+     * id 主键
+     */
+    @TableId(value = "id", type = IdType.AUTO)
+    private Integer id;
+
+    /**
+     * 保险公司id
+     */
+    @TableField(value = "company_id")
+    private String companyId;
+
+    /**
+     * 保险公司名称
+     */
+    @TableField(value = "company_name")
+    private String companyName;
+
+    /**
+     * 请求地址
+     */
+    @TableField(value = "url")
+    private String url;
+
+    /**
+     * 是否开启 0 开启 1 未开启
+     */
+    @TableField(value = "enabled")
+    private Integer enabled;
+
+    /**
+     * 保险公司核心用户名
+     */
+    @TableField(value = "username")
+    private String username;
+
+    /**
+     * 保险公司核心密码
+     */
+    @TableField(value = "password")
+    private String password;
+
+    @TableField(exist = false)
+    private static final long serialVersionUID = 1L;
+
+    @Override
+    public boolean equals(Object that) {
+        if (this == that) {
+            return true;
+        }
+        if (that == null) {
+            return false;
+        }
+        if (getClass() != that.getClass()) {
+            return false;
+        }
+        SysQueryVehicleConfig other = (SysQueryVehicleConfig) that;
+        return (this.getId() == null ? other.getId() == null : this.getId().equals(other.getId()))
+                && (this.getCompanyId() == null ? other.getCompanyId() == null : this.getCompanyId().equals(other.getCompanyId()))
+                && (this.getCompanyName() == null ? other.getCompanyName() == null : this.getCompanyName().equals(other.getCompanyName()))
+                && (this.getUrl() == null ? other.getUrl() == null : this.getUrl().equals(other.getUrl()))
+                && (this.getEnabled() == null ? other.getEnabled() == null : this.getEnabled().equals(other.getEnabled()))
+                && (this.getUsername() == null ? other.getUsername() == null : this.getUsername().equals(other.getUsername()))
+                && (this.getPassword() == null ? other.getPassword() == null : this.getPassword().equals(other.getPassword()));
+    }
+
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + ((getId() == null) ? 0 : getId().hashCode());
+        result = prime * result + ((getCompanyId() == null) ? 0 : getCompanyId().hashCode());
+        result = prime * result + ((getCompanyName() == null) ? 0 : getCompanyName().hashCode());
+        result = prime * result + ((getUrl() == null) ? 0 : getUrl().hashCode());
+        result = prime * result + ((getEnabled() == null) ? 0 : getEnabled().hashCode());
+        result = prime * result + ((getUsername() == null) ? 0 : getUsername().hashCode());
+        result = prime * result + ((getPassword() == null) ? 0 : getPassword().hashCode());
+        return result;
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        sb.append(getClass().getSimpleName());
+        sb.append(" [");
+        sb.append("Hash = ").append(hashCode());
+        sb.append(", id=").append(id);
+        sb.append(", companyId=").append(companyId);
+        sb.append(", companyName=").append(companyName);
+        sb.append(", url=").append(url);
+        sb.append(", enabled=").append(enabled);
+        sb.append(", username=").append(username);
+        sb.append(", password=").append(password);
+        sb.append(", serialVersionUID=").append(serialVersionUID);
+        sb.append("]");
+        return sb.toString();
+    }
+}

+ 88 - 0
commons/src/main/java/com/jzg/commons/entity/po/SysQueryVehicleUrl.java

@@ -0,0 +1,88 @@
+package com.jzg.commons.entity.po;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * 配置链接
+ * @TableName sys_query_vehicle_url
+ */
+@TableName(value ="sys_query_vehicle_url")
+@Data
+public class SysQueryVehicleUrl implements Serializable {
+    /**
+     * id 主键
+     */
+    @TableId(value = "id", type = IdType.AUTO)
+    private Integer id;
+
+    /**
+     * 配置类型
+     */
+    @TableField(value = "type")
+    private Integer type;
+
+    /**
+     * 请求路劲
+     */
+    @TableField(value = "link")
+    private String link;
+
+    /**
+     * 配置id
+     */
+    @TableField(value = "config_id")
+    private Integer configId;
+
+    @TableField(exist = false)
+    private static final long serialVersionUID = 1L;
+
+    @Override
+    public boolean equals(Object that) {
+        if (this == that) {
+            return true;
+        }
+        if (that == null) {
+            return false;
+        }
+        if (getClass() != that.getClass()) {
+            return false;
+        }
+        SysQueryVehicleUrl other = (SysQueryVehicleUrl) that;
+        return (this.getId() == null ? other.getId() == null : this.getId().equals(other.getId()))
+                && (this.getType() == null ? other.getType() == null : this.getType().equals(other.getType()))
+                && (this.getLink() == null ? other.getLink() == null : this.getLink().equals(other.getLink()))
+                && (this.getConfigId() == null ? other.getConfigId() == null : this.getConfigId().equals(other.getConfigId()));
+    }
+
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + ((getId() == null) ? 0 : getId().hashCode());
+        result = prime * result + ((getType() == null) ? 0 : getType().hashCode());
+        result = prime * result + ((getLink() == null) ? 0 : getLink().hashCode());
+        result = prime * result + ((getConfigId() == null) ? 0 : getConfigId().hashCode());
+        return result;
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        sb.append(getClass().getSimpleName());
+        sb.append(" [");
+        sb.append("Hash = ").append(hashCode());
+        sb.append(", id=").append(id);
+        sb.append(", type=").append(type);
+        sb.append(", link=").append(link);
+        sb.append(", configId=").append(configId);
+        sb.append(", serialVersionUID=").append(serialVersionUID);
+        sb.append("]");
+        return sb.toString();
+    }
+}

+ 38 - 0
commons/src/main/java/com/jzg/commons/entity/vo/CarModelDTO.java

@@ -0,0 +1,38 @@
+package com.jzg.commons.entity.vo;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import lombok.Data;
+
+/**
+ * @author gws
+ * @description:TODO
+ * @date 2022-07-13 17:11
+ */
+@Data
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class CarModelDTO {
+
+    private String modelCode;//车型编码 autoModelCode
+    private String modelName;//车型库名称 比亚迪QCJ7153A5轿车
+    private String brandCN;//品牌名称 brandName
+    private String series;//车系名称
+    private String importFlag;//车型种类
+    private String ratedPassengerCapacity;//核定载客人数
+    private String displacement;//排量
+    private String marketYear;//上市年份
+    private String replacementValue;//默认购置价
+    private String vehicleDescription;//车型描述
+    private String refCode1;//参考代码1
+    private String refCode2;//参考代码2
+    private String gearboxType;//变速箱类型
+    private String remark;//
+    private String fuelType;//能源种类
+    private String fuelTypeCode;//能源类别
+    private String energyTypes; // 能源种类
+    private String wholeWeight;//
+    private String powerScale;//
+    //    private VehicleJingyou vehicleJingyo;
+    private String vehicleSeatMax; // 最大座位数
+    private String vehicleSeatMin; // 最小座位数
+
+}

+ 53 - 0
commons/src/main/java/com/jzg/commons/entity/vo/InsOrdersOtherInfoVo.java

@@ -0,0 +1,53 @@
+package com.jzg.commons.entity.vo;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+import java.time.LocalDateTime;
+
+
+@Data
+@Schema(description = "险种信息")
+public class InsOrdersOtherInfoVo {
+
+    @Schema(description = "保险公司ID")
+    private String companyId;
+
+    @Schema(description = "保险公司名称")
+    private String companyName;
+
+    @Schema(description = "签单时间")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private LocalDateTime signingTime;
+
+    @Schema(description = "评分")
+    private String scope;
+
+    @Schema(description = "车船税")
+    private String taxPremium;
+
+    @Schema(description = "交强险单号")
+    private String jqApplyNo;
+
+    @Schema(description = "交强续保")
+    private String jqRenewal;
+
+    @Schema(description = "商业续保")
+    private String syRenewal;
+
+    @Schema(description = "商业保单号")
+    private String syPolicyNo;
+
+    @Schema(description = "交强险保费")
+    private String jqPremium;
+
+    @Schema(description = "商业险保费")
+    private String syPremium;
+
+    @Schema(description = "驾意险保费")
+    private String jyPremium;
+
+    @Schema(description = "总保费")
+    private String sumPremium;
+
+}

+ 27 - 0
commons/src/main/java/com/jzg/commons/entity/vo/SysQueryVehicleConfigQueryVo.java

@@ -0,0 +1,27 @@
+package com.jzg.commons.entity.vo;
+
+import com.jzg.commons.entity.po.SysQueryVehicleConfig;
+import com.jzg.commons.entity.po.SysQueryVehicleUrl;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+import java.util.List;
+
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+@Schema(name = "单独查询实体")
+public class SysQueryVehicleConfigQueryVo implements Serializable {
+
+    private static final long serialVersionUID = 5588764078957578412L;
+
+    @Schema(name = "配置信息")
+    private SysQueryVehicleConfig sysQueryVehicleConfig;
+
+    @Schema(name = "链接信息")
+    private List<SysQueryVehicleUrl> sysQueryVehicleUrlList;
+
+}

+ 80 - 0
commons/src/main/java/com/jzg/commons/entity/vo/SysQueryVehicleConfigSaveVo.java

@@ -0,0 +1,80 @@
+package com.jzg.commons.entity.vo;
+
+import com.jzg.commons.entity.po.SysQueryVehicleConfig;
+import com.jzg.commons.entity.po.SysQueryVehicleUrl;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.util.List;
+
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@Schema(name =  "车型查询配置实体")
+public class SysQueryVehicleConfigSaveVo {
+
+    @Schema(name = "车型查询配置实体")
+    private SysQueryVehicleConfigDTO sysQueryVehicleConfigDTO;
+
+    @Schema(name = "请求地址配置实体")
+    private List<SysQueryVehicleUrlDTO> sysQueryVehicleUrlDTOList;
+
+    @Data
+    @NoArgsConstructor
+    @AllArgsConstructor
+    public static class SysQueryVehicleConfigDTO {
+
+        @Schema(name = "保险公司id")
+        private String companyId;
+
+        @Schema(name = "保险公司名称")
+        private String companyName;
+
+        @Schema(name = "请求地址")
+        private String url;
+
+        @Schema(name = "是否开启 1 开启 0 未开启")
+        private Integer enabled;
+
+        @Schema(name = "保险公司核心用户名")
+        private String username;
+
+        @Schema(name = "保险公司核心密码")
+        private String password;
+
+        public SysQueryVehicleConfig toSysQueryVehicleConfig(){
+            SysQueryVehicleConfig sysQueryVehicleConfig = new SysQueryVehicleConfig();
+            sysQueryVehicleConfig.setCompanyId(companyId);
+            sysQueryVehicleConfig.setCompanyName(companyName);
+            sysQueryVehicleConfig.setUrl(url);
+            sysQueryVehicleConfig.setUsername(username);
+            sysQueryVehicleConfig.setPassword(password);
+            sysQueryVehicleConfig.setEnabled(enabled);
+            return sysQueryVehicleConfig;
+        }
+
+    }
+
+    @Data
+    @NoArgsConstructor
+    @AllArgsConstructor
+    public static class SysQueryVehicleUrlDTO {
+
+        @Schema(name = "配置类型")
+        private Integer type;
+
+        @Schema(name = "请求路劲")
+        private String link;
+
+        public SysQueryVehicleUrl toSysQueryVehicleConfig(Integer configId){
+            SysQueryVehicleUrl sysQueryVehicleUrl = new SysQueryVehicleUrl();
+            sysQueryVehicleUrl.setConfigId(configId);
+            sysQueryVehicleUrl.setType(type);
+            sysQueryVehicleUrl.setLink(link);
+            return sysQueryVehicleUrl;
+        }
+    }
+
+}

+ 25 - 0
tenant/insurance/quotation-summary/src/main/java/com/jzg/quotation/summary/components/FrameNumberInquiryRequest.java

@@ -0,0 +1,25 @@
+package com.jzg.quotation.summary.components;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.jzg.quotation.summary.request.vehicle.BaseVehicleRequest;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+
+@EqualsAndHashCode(callSuper = true)
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class FrameNumberInquiryRequest extends BaseVehicleRequest {
+
+    private static final long serialVersionUID = 4659780653816463073L;
+
+    @JsonProperty("vin")
+    private String vin;
+
+    public FrameNumberInquiryRequest(String frameNumber, String username, String password) {
+        super(username, password);
+        this.vin = frameNumber;
+    }
+}

+ 61 - 0
tenant/insurance/quotation-summary/src/main/java/com/jzg/quotation/summary/components/InsCrawlerOrderComponents.java

@@ -0,0 +1,61 @@
+package com.jzg.quotation.summary.components;
+
+import com.alibaba.fastjson.JSON;
+import com.jzg.commons.exception.SystemException;
+import com.jzg.quotation.commons.constant.enums.base.InsuranceEnum;
+import jakarta.annotation.Resource;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.http.HttpEntity;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.MediaType;
+import org.springframework.http.ResponseEntity;
+import org.springframework.lang.Nullable;
+import org.springframework.stereotype.Component;
+import org.springframework.web.client.RestTemplate;
+
+@Slf4j
+@Component
+public class InsCrawlerOrderComponents {
+
+    @Resource
+    private  RestTemplate restTemplate;
+
+    public <T, B> B post(String url, String logId, String message, @Nullable T requestBody, Class<B> responseType, HttpHeaders httpHeaders) {
+        httpHeaders.setContentType(MediaType.APPLICATION_JSON);
+        HttpEntity<T> yaQuoteInfoVoHttpEntity = new HttpEntity<>(requestBody, httpHeaders);
+
+        String request = JSON.toJSONString(requestBody);
+        log.info(logId, "\n\t---------> {} \n\t---------> URL: {} \n\t---------> 请求参数: {}", message, url, request);
+        ResponseEntity<B> stringResponseEntity = restTemplate.postForEntity(url, yaQuoteInfoVoHttpEntity, responseType);
+        B body = stringResponseEntity.getBody();
+        if (body == null) {
+            throw new SystemException(message + "接口请求失败");
+        }
+
+        String response = JSON.toJSONString(body);
+        log.info(logId, "\n\t---------> {} \n\t---------> 响应参数:{}", message, response);
+        return body;
+    }
+
+    public <T, B> B request(String url, String companyId, String apiType, T requestBody, Class<B> responseType) {
+        // 获取保险公司枚举
+        String substring = companyId.substring(0, 4);
+        InsuranceEnum insuranceEnum = Enum.valueOf(InsuranceEnum.class, substring);
+        return this.request(url, insuranceEnum, apiType, requestBody, responseType, new HttpHeaders());
+    }
+
+    public <T, B> B request(String url, InsuranceEnum insuranceEnum, String apiType, T requestBody, Class<B> responseType) {
+        return this.request(url, insuranceEnum, apiType, requestBody, responseType, new HttpHeaders());
+    }
+
+    public <T, B> B request(String url, InsuranceEnum insuranceEnum, String apiType, T requestBody, Class<B> responseType, HttpHeaders httpHeaders) {
+        String message = insuranceEnum.getName() + apiType;
+        return this.post(url, insuranceEnum.getPinyin(), message, requestBody, responseType, httpHeaders);
+    }
+
+    public <T, B> B request(String url, String logId, String message, T requestBody, Class<B> responseType, HttpHeaders httpHeaders) {
+        return this.post(url, logId, message, requestBody, responseType, httpHeaders);
+    }
+
+}
+

+ 64 - 0
tenant/insurance/quotation-summary/src/main/java/com/jzg/quotation/summary/components/QueryVehicleComponents.java

@@ -0,0 +1,64 @@
+package com.jzg.quotation.summary.components;
+
+import com.jzg.commons.constants.dict.VehicleTypeType;
+import com.jzg.commons.entity.dto.SysQueryVehicleConfigDTO;
+import com.jzg.commons.entity.vo.CarModelDTO;
+import com.jzg.quotation.summary.request.vehicle.VehicleModelInquiryRequest;
+import com.jzg.quotation.summary.response.BaseVehicleResponse;
+import com.jzg.quotation.summary.service.SysQueryVehicleConfigService;
+import lombok.RequiredArgsConstructor;
+import org.springframework.http.HttpHeaders;
+import org.springframework.stereotype.Component;
+import org.springframework.util.ObjectUtils;
+
+import java.util.Collections;
+import java.util.List;
+
+@Component
+@RequiredArgsConstructor
+public class QueryVehicleComponents {
+
+    private final SysQueryVehicleConfigService sysQueryVehicleConfigService;
+
+    private final InsCrawlerOrderComponents insCrawlerOrderComponents;
+
+    /**
+     * 车架号查询
+     *
+     * @param frameNumber 车架号查询
+     */
+    public List<CarModelDTO> frameNumberInquiry(String frameNumber) {
+        VehicleTypeType vtt1 = VehicleTypeType.VTT_1;
+        SysQueryVehicleConfigDTO sysQueryVehicleConfigDTO = sysQueryVehicleConfigService.getByType(String.valueOf(vtt1.getCode()));
+        if(ObjectUtils.isEmpty(sysQueryVehicleConfigDTO)) {
+            return Collections.emptyList();
+        }
+
+        FrameNumberInquiryRequest frameNumberInquiryRequest = new FrameNumberInquiryRequest(frameNumber, sysQueryVehicleConfigDTO.getUsername(), sysQueryVehicleConfigDTO.getPassword());
+        String url = sysQueryVehicleConfigDTO.getBaseUrl();
+        BaseVehicleResponse response = insCrawlerOrderComponents.post(url, "vehicle", vtt1.getDesc(), frameNumberInquiryRequest, BaseVehicleResponse.class, new HttpHeaders());
+        return response.getContent();
+    }
+
+    /**
+     * 车型查询
+     *
+     * @param vehicleModel 车辆类型
+     */
+    public List<CarModelDTO> vehicleModelInquiry(String vehicleModel) {
+        VehicleTypeType vtt2 = VehicleTypeType.VTT_2;
+        SysQueryVehicleConfigDTO sysQueryVehicleConfigDTO = sysQueryVehicleConfigService.getByType(String.valueOf(vtt2.getCode()));
+        if(ObjectUtils.isEmpty(sysQueryVehicleConfigDTO)) {
+            return Collections.emptyList();
+        }
+
+        VehicleModelInquiryRequest frameNumberInquiryRequest = new VehicleModelInquiryRequest(vehicleModel, sysQueryVehicleConfigDTO.getUsername(), sysQueryVehicleConfigDTO.getPassword());
+        String url = sysQueryVehicleConfigDTO.getBaseUrl();
+        BaseVehicleResponse response = insCrawlerOrderComponents.post(url, "vehicle", vtt2.getDesc(), frameNumberInquiryRequest, BaseVehicleResponse.class, new HttpHeaders());
+        return response.getContent();
+    }
+
+
+
+}
+

+ 44 - 0
tenant/insurance/quotation-summary/src/main/java/com/jzg/quotation/summary/controller/CarModelController.java

@@ -0,0 +1,44 @@
+package com.jzg.quotation.summary.controller;
+
+import com.alibaba.fastjson.JSONObject;
+import com.jzg.commons.core.page.HttpResult;
+import com.jzg.commons.entity.vo.CarModelDTO;
+import com.jzg.quotation.summary.service.CarModelService;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.Comparator;
+import java.util.List;
+import java.util.stream.Collectors;
+
+@Tag(name = "车型")
+@RestController
+@RequestMapping("/order/carModel")
+public class  CarModelController {
+
+    private final CarModelService carModelService;
+
+    public CarModelController(CarModelService carModelService) {
+        this.carModelService = carModelService;
+    }
+
+    @GetMapping("/vinSearch")
+    @Operation(description = "vin码查询")
+    public HttpResult<List<CarModelDTO>> vinSearch(@RequestParam String frameNo) {
+        List<CarModelDTO> map = carModelService.vinSearch(frameNo);
+        List<CarModelDTO> carModelDTOS =
+                map.stream().sorted(Comparator.comparing(CarModelDTO::getReplacementValue)).collect(Collectors.toList());
+        return HttpResult.ok(carModelDTOS);
+    }
+
+    @GetMapping("/licenseSearch")
+    @Operation(description = "车牌查询")
+    public HttpResult licenseSearch(@RequestParam String licenseNo){
+        JSONObject jsonObject = carModelService.licenseSearch(licenseNo);
+        return HttpResult.ok(jsonObject);
+    }
+}

+ 32 - 0
tenant/insurance/quotation-summary/src/main/java/com/jzg/quotation/summary/extension/BaseIService.java

@@ -0,0 +1,32 @@
+package com.jzg.quotation.summary.extension;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.jzg.commons.exception.SystemException;
+import org.springframework.util.ObjectUtils;
+
+import java.io.Serializable;
+
+/**
+ * 扩展 IService
+ *
+ * @param <T>
+ */
+public interface BaseIService<T> extends IService<T> {
+
+    /**
+     * 判断是否存在
+     *
+     * @param id 订单表
+     * @param message 报错信息
+     * @return 实体
+     */
+    default T getByIdExist(Serializable id, String message) {
+        T t = getById(id);
+        if (ObjectUtils.isEmpty(t)) {
+            throw new SystemException(message);
+        }
+        return t;
+    }
+
+
+}

+ 27 - 0
tenant/insurance/quotation-summary/src/main/java/com/jzg/quotation/summary/mapper/SysQueryVehicleConfigMapper.java

@@ -0,0 +1,27 @@
+package com.jzg.quotation.summary.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.jzg.commons.entity.dto.SysQueryVehicleConfigDTO;
+import com.jzg.commons.entity.po.SysQueryVehicleConfig;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+/**
+ * @author Administrator
+ * @description 针对表【sys_query_vehicle_config(车型查询配置信息)】的数据库操作Mapper
+ * @createDate 2024-08-16 10:20:52
+ * @Entity generator.domain.SysQueryVehicleConfig
+ */
+@Mapper
+public interface SysQueryVehicleConfigMapper extends BaseMapper<SysQueryVehicleConfig> {
+
+    /**
+     * 通过类型查看开启的配置信息
+     * @param type 类型
+     * @return
+     */
+    SysQueryVehicleConfigDTO getByType(@Param("type") String type);
+
+
+}
+

+ 16 - 0
tenant/insurance/quotation-summary/src/main/java/com/jzg/quotation/summary/mapper/SysQueryVehicleUrlMapper.java

@@ -0,0 +1,16 @@
+package com.jzg.quotation.summary.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.jzg.commons.entity.po.SysQueryVehicleUrl;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * @author Administrator
+ * @description 针对表【sys_query_vehicle_url(配置链接)】的数据库操作Mapper
+ * @createDate 2024-08-16 10:20:52
+ * @Entity generator.domain.SysQueryVehicleUrl
+ */
+@Mapper
+public interface SysQueryVehicleUrlMapper extends BaseMapper<SysQueryVehicleUrl> {
+
+}

+ 23 - 0
tenant/insurance/quotation-summary/src/main/java/com/jzg/quotation/summary/request/vehicle/BaseVehicleRequest.java

@@ -0,0 +1,23 @@
+package com.jzg.quotation.summary.request.vehicle;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class BaseVehicleRequest implements Serializable {
+
+    private static final long serialVersionUID = 1742373042317777831L;
+
+    @JsonProperty("username")
+    private String username;
+
+    @JsonProperty("password")
+    private String password;
+
+}

+ 25 - 0
tenant/insurance/quotation-summary/src/main/java/com/jzg/quotation/summary/request/vehicle/FrameNumberInquiryRequest.java

@@ -0,0 +1,25 @@
+package com.jzg.quotation.summary.request.vehicle;
+
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+
+@EqualsAndHashCode(callSuper = true)
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class FrameNumberInquiryRequest extends BaseVehicleRequest{
+
+    private static final long serialVersionUID = 4659780653816463073L;
+
+    @JsonProperty("vin")
+    private String vin;
+
+    public FrameNumberInquiryRequest(String frameNumber, String username, String password) {
+        super(username, password);
+        this.vin = frameNumber;
+    }
+}

+ 26 - 0
tenant/insurance/quotation-summary/src/main/java/com/jzg/quotation/summary/request/vehicle/VehicleModelInquiryRequest.java

@@ -0,0 +1,26 @@
+package com.jzg.quotation.summary.request.vehicle;
+
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+
+@EqualsAndHashCode(callSuper = true)
+@NoArgsConstructor
+@Data
+@AllArgsConstructor
+public class VehicleModelInquiryRequest extends BaseVehicleRequest {
+
+    private static final long serialVersionUID = 2577862656332358550L;
+
+    @JsonProperty("modelcname")
+    private String modelName;
+
+    public VehicleModelInquiryRequest(String vehicleModel, String username, String password) {
+        super(username, password);
+        this.modelName = vehicleModel;
+    }
+
+}

+ 25 - 0
tenant/insurance/quotation-summary/src/main/java/com/jzg/quotation/summary/response/BaseVehicleResponse.java

@@ -0,0 +1,25 @@
+package com.jzg.quotation.summary.response;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.jzg.commons.entity.vo.CarModelDTO;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+import java.util.List;
+
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class BaseVehicleResponse implements Serializable {
+
+    private static final long serialVersionUID = -1927930007075223492L;
+
+    @JsonProperty("code")
+    private Integer code;
+
+    @JsonProperty("content")
+    private List<CarModelDTO> content;
+
+}

+ 14 - 0
tenant/insurance/quotation-summary/src/main/java/com/jzg/quotation/summary/service/CarModelService.java

@@ -0,0 +1,14 @@
+package com.jzg.quotation.summary.service;
+
+import com.alibaba.fastjson.JSONObject;
+import com.jzg.commons.entity.vo.CarModelDTO;
+
+import java.util.List;
+
+public interface CarModelService {
+
+    List<CarModelDTO> vinSearch(String frameNo);
+
+    JSONObject licenseSearch(String licenseNo);
+
+}

+ 4 - 0
tenant/insurance/quotation-summary/src/main/java/com/jzg/quotation/summary/service/InsOrdersService.java

@@ -22,4 +22,8 @@ public interface InsOrdersService extends IService<InsOrders> {
 
 
     HttpResult updateOrders(InsOrdersAdd ordersAdd);
+
+
+
+
 }

+ 91 - 0
tenant/insurance/quotation-summary/src/main/java/com/jzg/quotation/summary/service/SysQueryVehicleConfigService.java

@@ -0,0 +1,91 @@
+package com.jzg.quotation.summary.service;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.jzg.commons.constants.dict.EnabledEnum;
+import com.jzg.commons.entity.dto.SysQueryVehicleConfigDTO;
+import com.jzg.commons.entity.dto.SysQueryVehicleConfigQueryPageVo;
+import com.jzg.commons.entity.po.SysQueryVehicleConfig;
+import com.jzg.commons.entity.vo.SysQueryVehicleConfigQueryVo;
+import com.jzg.commons.entity.vo.SysQueryVehicleConfigSaveVo;
+import com.jzg.quotation.summary.extension.BaseIService;
+
+import java.util.List;
+
+/**
+ * @author Administrator
+ * @description 针对表【sys_query_vehicle_config(车型查询配置信息)】的数据库操作Service
+ * @createDate 2024-08-16 10:20:52
+ */
+public interface SysQueryVehicleConfigService extends BaseIService<SysQueryVehicleConfig> {
+
+    /**
+     * 配置
+     *
+     * @param sysQueryVehicleConfigSaveVo 车型配置实体
+     */
+    void disposition(SysQueryVehicleConfigSaveVo sysQueryVehicleConfigSaveVo);
+
+    /**
+     * 查询
+     *
+     * @param sysQueryVehicleConfigQueryPageVo 车险查询配置实体
+     */
+    Page<SysQueryVehicleConfig> inquire(SysQueryVehicleConfigQueryPageVo sysQueryVehicleConfigQueryPageVo);
+
+    /**
+     * 删除
+     *
+     * @param id 配置id
+     */
+    void deleteVehicleConfig(Integer id);
+
+    /**
+     * 修改
+     *
+     * @param sysQueryVehicleConfigSaveVo 车型配置实体
+     */
+    void modify(Integer id, SysQueryVehicleConfigSaveVo sysQueryVehicleConfigSaveVo);
+
+    /**
+     * 查询单个配置信息
+     *
+     * @param id 配置信息id
+     * @return 配置信息
+     */
+    SysQueryVehicleConfigQueryVo queryById(Integer id);
+
+    /**
+     * 通过类型查看开启的配置信息
+     *
+     * @param type 类型
+     * @return
+     */
+    SysQueryVehicleConfigDTO getByType(String type);
+
+    /**
+     * 把修改改为关闭
+     *
+     * @param enabled 开启关闭状态
+     */
+    default boolean updateEnabled(int enabled) {
+        List<SysQueryVehicleConfig> list = lambdaQuery().eq(SysQueryVehicleConfig::getEnabled, EnabledEnum.EE_1.getCode()).list();
+        if (list.isEmpty()) {
+            return true;
+        }
+
+        if (EnabledEnum.EE_1.getCode() == enabled) {
+            return lambdaUpdate()
+                    .set(SysQueryVehicleConfig::getEnabled, EnabledEnum.EE_0.getCode())
+                    .eq(SysQueryVehicleConfig::getEnabled, EnabledEnum.EE_1.getCode())
+                    .update();
+        }
+        return true;
+    }
+
+    /**
+     * 开关修改
+     *
+     * @param id 配置信息id
+     */
+    void openOne(Integer id);
+}

+ 46 - 0
tenant/insurance/quotation-summary/src/main/java/com/jzg/quotation/summary/service/SysQueryVehicleUrlService.java

@@ -0,0 +1,46 @@
+package com.jzg.quotation.summary.service;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.jzg.commons.entity.po.SysQueryVehicleUrl;
+import com.jzg.commons.entity.vo.SysQueryVehicleConfigSaveVo;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * @author Administrator
+ * @description 针对表【sys_query_vehicle_url(配置链接)】的数据库操作Service
+ * @createDate 2024-08-16 10:20:52
+ */
+public interface SysQueryVehicleUrlService extends IService<SysQueryVehicleUrl> {
+
+    /**
+     * 删除配置链接信息
+     *
+     * @param configId 配置id
+     * @return 成功失败
+     */
+    default boolean deleteByConfigId(Integer configId) {
+        LambdaQueryWrapper<SysQueryVehicleUrl> wrapper = new LambdaQueryWrapper<>();
+        wrapper.eq(SysQueryVehicleUrl::getConfigId, configId);
+        return remove(wrapper);
+    }
+
+    /**
+     *
+     * @param configId 配置id
+     * @param sysQueryVehicleUrlDTOList 配置列表
+     * @return
+     */
+    @Transactional
+    default boolean saveVehicleUrlDTOs(Integer configId, List<SysQueryVehicleConfigSaveVo.SysQueryVehicleUrlDTO> sysQueryVehicleUrlDTOList){
+        List<SysQueryVehicleUrl> sysQueryVehicleUrls = sysQueryVehicleUrlDTOList.stream()
+                .map(x -> x.toSysQueryVehicleConfig(configId))
+                .collect(Collectors.toList());
+        return saveBatch(sysQueryVehicleUrls);
+    }
+
+}
+

+ 99 - 0
tenant/insurance/quotation-summary/src/main/java/com/jzg/quotation/summary/service/impl/CarModelServiceImpl.java

@@ -0,0 +1,99 @@
+package com.jzg.quotation.summary.service.impl;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.jzg.commons.constants.RedisKeyConstants;
+import com.jzg.commons.entity.vo.CarModelDTO;
+import com.jzg.quotation.summary.components.QueryVehicleComponents;
+import com.jzg.quotation.summary.service.CarModelService;
+import com.jzg.quotation.summary.service.InsOrdersService;
+import lombok.RequiredArgsConstructor;
+import okhttp3.*;
+import org.springframework.data.redis.core.StringRedisTemplate;
+import org.springframework.stereotype.Service;
+
+import java.io.IOException;
+import java.util.Collections;
+import java.util.List;
+import java.util.Objects;
+import java.util.concurrent.TimeUnit;
+
+@Service
+@RequiredArgsConstructor
+public class CarModelServiceImpl implements CarModelService {
+
+    //private final ZhongMeiOrderService zhongMeiOrderService;
+
+    private final InsOrdersService insOrdersService;
+
+    private final StringRedisTemplate redisTemplate;
+
+    private final QueryVehicleComponents queryVehicleComponents;
+
+    @Override
+    public List<CarModelDTO> vinSearch(String frameNo) {
+        //初始Key
+        StringBuilder redisKey = new StringBuilder();
+        redisKey.append(RedisKeyConstants.VIN_SEARCH_KEY);
+        redisKey.append(frameNo);
+        //从缓存中查数据
+        if (!Objects.isNull(redisTemplate.opsForValue().get(redisKey.toString()))) {
+            String carModeStr = redisTemplate.opsForValue().get(redisKey.toString());
+            return JSON.parseArray(carModeStr, CarModelDTO.class);
+
+        }
+
+        //从数据库中查数据
+
+        List<CarModelDTO> carModelDTOS = queryVehicleComponents.frameNumberInquiry(frameNo);
+        if (carModelDTOS.isEmpty()) {
+            //carModelDTOS = insOrdersService.vinSearch(frameNo);
+        }
+
+        if (!carModelDTOS.isEmpty()) {
+            //进行缓存存储
+            redisTemplate.opsForValue().set(redisKey.toString(), JSON.toJSONString(carModelDTOS), RedisKeyConstants.VIN_SEARCH_KEY_TIME, TimeUnit.HOURS);
+            return carModelDTOS;
+        }
+
+//        List<CarModelDTO> carModelDTOS1 = zhongMeiOrderService.vinSearch(frameNo);
+//        if (!carModelDTOS1.isEmpty()) {
+//            //进行缓存存储
+//            redisTemplate.opsForValue().set(redisKey.toString(), JSON.toJSONString(carModelDTOS1), 1, TimeUnit.HOURS);
+//            return carModelDTOS1;
+//        }
+//        List<CarModelDTO> carModelDTOS2 = yongAnOrderService.vinSearch(frameNo);
+//        if (!carModelDTOS2.isEmpty()) {
+//            return HttpResult.ok(carModelDTOS2);
+//        }
+        return Collections.emptyList();
+    }
+
+    @Override
+    public JSONObject licenseSearch(String licenseNo) {
+        String requestUrl = "http://39.98.41.104:8088/lsearch/1";
+        JSONObject params = new JSONObject();
+        params.put("license",licenseNo);
+        OkHttpClient client = new OkHttpClient().newBuilder()
+                .build();
+        MediaType mediaType = MediaType.parse("application/json");
+        RequestBody body = RequestBody.create(mediaType, params.toString());
+        Request request = new Request.Builder()
+                .url(requestUrl)
+                .method("POST", body)
+                .build();
+        try {
+            Response response = client.newCall(request).execute();
+            if(response.isSuccessful()){
+                String responseBody = response.body().string();
+                JSONObject jsonResponse = JSONObject.parseObject(responseBody);
+                return jsonResponse;
+            }
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        }
+        return null;
+
+    }
+
+}

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

@@ -7,6 +7,7 @@ import com.jzg.commons.entity.dto.InsOrdersAdd;
 import com.jzg.commons.entity.dto.InsOrdersParam;
 import com.jzg.commons.entity.dto.InsuranceInfo;
 import com.jzg.commons.entity.orders.po.*;
+import com.jzg.commons.entity.vo.InsOrdersOtherInfoVo;
 import com.jzg.commons.entity.vo.InsOrdersVo;
 import com.jzg.commons.entity.vo.OrdersListVo;
 import com.jzg.quotation.commons.utils.SnowFlakeUtil;
@@ -53,7 +54,7 @@ public class InsOrdersServiceImpl extends ServiceImpl<InsOrdersMapper, InsOrders
     public HttpResult saveOrders(InsOrdersAdd ordersAdd) {
         // 检查输入参数是否为空,如果为空则返回错误信息
         if (ordersAdd == null || ordersAdd.getInsOrders() == null || ordersAdd.getCarInfoVo() == null
-                || ordersAdd.getCarUserInfoList() == null || ordersAdd.getInsOrdersOther() == null
+                || ordersAdd.getCarUserInfoList() == null || ordersAdd.getInsOrdersOtherInfo() == null
                 || ordersAdd.getInsuranceInfo() == null) {
             return HttpResult.error("参数不能为空");
         }
@@ -88,9 +89,9 @@ public class InsOrdersServiceImpl extends ServiceImpl<InsOrdersMapper, InsOrders
             ordersCarUserInfoService.saveBatch(carUserInfoList);
 
             // 保险订单其他信息
-            InsOrdersOther insOrdersOther = ordersAdd.getInsOrdersOther();
-            insOrdersOther.setOrderNo(quoteNo);
-            insOrdersOtherService.save(insOrdersOther);
+            InsOrdersOtherInfoVo insOrdersOtherInfo = ordersAdd.getInsOrdersOtherInfo();
+//            insOrdersOther.setOrderNo(quoteNo);
+//            insOrdersOtherService.save(insOrdersOther);
 
             // 保险信息
             InsuranceInfo insuranceInfo = ordersAdd.getInsuranceInfo();
@@ -143,4 +144,6 @@ public class InsOrdersServiceImpl extends ServiceImpl<InsOrdersMapper, InsOrders
     }
 
 
+
+
 }

+ 124 - 0
tenant/insurance/quotation-summary/src/main/java/com/jzg/quotation/summary/service/impl/SysQueryVehicleConfigServiceImpl.java

@@ -0,0 +1,124 @@
+package com.jzg.quotation.summary.service.impl;
+
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.jzg.commons.constants.dict.EnabledEnum;
+import com.jzg.commons.entity.dto.SysQueryVehicleConfigDTO;
+import com.jzg.commons.entity.dto.SysQueryVehicleConfigQueryPageVo;
+import com.jzg.commons.entity.po.SysQueryVehicleConfig;
+import com.jzg.commons.entity.po.SysQueryVehicleUrl;
+import com.jzg.commons.entity.vo.SysQueryVehicleConfigQueryVo;
+import com.jzg.commons.entity.vo.SysQueryVehicleConfigSaveVo;
+import com.jzg.commons.util.AssertionUtils;
+import com.jzg.commons.util.StringUtils;
+import com.jzg.quotation.summary.mapper.SysQueryVehicleConfigMapper;
+import com.jzg.quotation.summary.service.SysQueryVehicleConfigService;
+import com.jzg.quotation.summary.service.SysQueryVehicleUrlService;
+import jakarta.annotation.Resource;
+import lombok.RequiredArgsConstructor;
+import org.apache.commons.lang3.ObjectUtils;
+import org.springframework.beans.BeanUtils;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * @author Administrator
+ * @description 针对表【sys_query_vehicle_config(车型查询配置信息)】的数据库操作Service实现
+ * @createDate 2024-08-16 10:20:52
+ */
+@Service
+@RequiredArgsConstructor
+public class SysQueryVehicleConfigServiceImpl extends ServiceImpl<SysQueryVehicleConfigMapper, SysQueryVehicleConfig> implements SysQueryVehicleConfigService {
+
+    @Resource
+    private  SysQueryVehicleUrlService sysQueryVehicleUrlService;
+
+    @Override
+    @Transactional
+    public void disposition(SysQueryVehicleConfigSaveVo sysQueryVehicleConfigSaveVo) {
+        SysQueryVehicleConfigSaveVo.SysQueryVehicleConfigDTO sysQueryVehicleConfigDTO = sysQueryVehicleConfigSaveVo.getSysQueryVehicleConfigDTO();
+
+        // 保证项目中只能出险一个开启的车险配置
+        boolean b1 = updateEnabled(sysQueryVehicleConfigDTO.getEnabled());
+
+        SysQueryVehicleConfig sysQueryVehicleConfig = sysQueryVehicleConfigDTO.toSysQueryVehicleConfig();
+        boolean save = save(sysQueryVehicleConfig);
+        boolean b = sysQueryVehicleUrlService.saveVehicleUrlDTOs(sysQueryVehicleConfig.getId(), sysQueryVehicleConfigSaveVo.getSysQueryVehicleUrlDTOList());
+        AssertionUtils.isSucceed(save && b && b1, "配置信息保存失败");
+    }
+
+    @Override
+    public Page<SysQueryVehicleConfig> inquire(SysQueryVehicleConfigQueryPageVo sysQueryVehicleConfigQueryVo) {
+        Page page = baseMapper.selectPage(sysQueryVehicleConfigQueryVo.getPage(), new LambdaQueryWrapper<>(SysQueryVehicleConfig.class)
+                .eq(StringUtils.isNotEmpty(sysQueryVehicleConfigQueryVo.getCompanyId()), SysQueryVehicleConfig::getCompanyId, sysQueryVehicleConfigQueryVo.getCompanyId())
+                .eq(ObjectUtils.isNotEmpty(sysQueryVehicleConfigQueryVo.getEnabled()), SysQueryVehicleConfig::getEnabled, sysQueryVehicleConfigQueryVo.getEnabled()));
+        return page;
+    }
+
+    @Override
+    @Transactional
+    public void deleteVehicleConfig(Integer id) {
+        // 删除配置信息
+        boolean b = removeById(id);
+        // 删除配置链接信息
+        boolean remove = sysQueryVehicleUrlService.deleteByConfigId(id);
+        AssertionUtils.isSucceed(remove && b, "配置信息删除失败");
+    }
+
+    @Override
+    @Transactional
+    public void modify(Integer id, SysQueryVehicleConfigSaveVo sysQueryVehicleConfigSaveVo) {
+        // 修改配置信息
+        SysQueryVehicleConfig sysQueryVehicleConfig = getByIdExist(id, "查询配置信息不存在");
+        BeanUtils.copyProperties(sysQueryVehicleConfigSaveVo.getSysQueryVehicleConfigDTO(), sysQueryVehicleConfig);
+
+        // 保证项目中只能出险一个开启的车险配置
+        boolean b = updateEnabled(sysQueryVehicleConfigSaveVo.getSysQueryVehicleConfigDTO().getEnabled());
+
+        sysQueryVehicleConfig.setId(id);
+        boolean update = updateById(sysQueryVehicleConfig);
+
+        // 删除并添加
+        boolean remove = sysQueryVehicleUrlService.deleteByConfigId(id);
+        // 批量添加配置信息
+        boolean saveBatch = sysQueryVehicleUrlService.saveVehicleUrlDTOs(id, sysQueryVehicleConfigSaveVo.getSysQueryVehicleUrlDTOList());
+        AssertionUtils.isSucceed(update && remove && saveBatch && b, "配置信息修改失败");
+    }
+
+    @Override
+    public SysQueryVehicleConfigQueryVo queryById(Integer id) {
+        SysQueryVehicleConfig sysQueryVehicleConfig = getByIdExist(id, "查询配置信息不存在");
+        SysQueryVehicleConfigQueryVo sysQueryVehicleConfigQueryDTO = new SysQueryVehicleConfigQueryVo();
+        sysQueryVehicleConfigQueryDTO.setSysQueryVehicleConfig(sysQueryVehicleConfig);
+        List<SysQueryVehicleUrl> list = sysQueryVehicleUrlService.lambdaQuery().eq(SysQueryVehicleUrl::getConfigId, id).list();
+        sysQueryVehicleConfigQueryDTO.setSysQueryVehicleUrlList(list);
+        return sysQueryVehicleConfigQueryDTO;
+    }
+
+    @Override
+    public SysQueryVehicleConfigDTO getByType(String type) {
+        SysQueryVehicleConfigDTO sysQueryVehicleConfigDTO = baseMapper.getByType(type);
+        if(ObjectUtils.isEmpty(sysQueryVehicleConfigDTO)) {
+            return null;
+        }
+        return sysQueryVehicleConfigDTO;
+    }
+
+    @Override
+    @Transactional
+    public void openOne(Integer id) {
+        SysQueryVehicleConfig sysQueryVehicleConfig = getByIdExist(id, "查询配置信息不存在");
+        Integer enabled = sysQueryVehicleConfig.getEnabled();
+        Integer i = Objects.equals(EnabledEnum.EE_1.getCode(), enabled) ? EnabledEnum.EE_0.getCode() : EnabledEnum.EE_1.getCode();
+        boolean b = updateEnabled(i);
+        sysQueryVehicleConfig.setEnabled(i);
+        boolean b1 = updateById(sysQueryVehicleConfig);
+        AssertionUtils.isSucceed(b1 && b, "成功");
+    }
+}
+

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

@@ -0,0 +1,14 @@
+package com.jzg.quotation.summary.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.jzg.commons.entity.po.SysQueryVehicleUrl;
+import com.jzg.quotation.summary.mapper.SysQueryVehicleUrlMapper;
+import com.jzg.quotation.summary.service.SysQueryVehicleUrlService;
+import org.springframework.stereotype.Service;
+
+@Service
+public class SysQueryVehicleUrlServiceImpl extends ServiceImpl<SysQueryVehicleUrlMapper, SysQueryVehicleUrl> implements SysQueryVehicleUrlService {
+
+
+
+}

+ 21 - 0
tenant/insurance/quotation-summary/src/main/resources/mapper/SysQueryVehicleConfigMapper.xml

@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
+<mapper namespace="com.jzg.quotation.summary.mapper.SysQueryVehicleConfigMapper">
+
+
+    <sql id="Base_Column_List">
+        id,company_id,company_name,
+        url,enabled,username,
+        password
+    </sql>
+
+    <select id="getByType" resultType="com.jzg.commons.entity.dto.SysQueryVehicleConfigDTO">
+        select *
+        from sys_query_vehicle_config c
+                 left join sys_query_vehicle_url u
+                           on c.id = config_id
+        where u.type = #{type}
+          and enabled = 1
+    </select>
+
+</mapper>