Przeglądaj źródła

报价次数限制

785834757 1 rok temu
rodzic
commit
c685a1ec0a
50 zmienionych plików z 3156 dodań i 176 usunięć
  1. 4 2
      src/main/java/com/ydtech/modules/admin/controller/SysUserController.java
  2. 8 0
      src/main/java/com/ydtech/modules/esm/controller/EsmInsCompanyController.java
  3. 4 0
      src/main/java/com/ydtech/modules/esm/dao/EsmInsCompanyMapper.java
  4. 6 0
      src/main/java/com/ydtech/modules/esm/service/EsmInsCompanyService.java
  5. 9 0
      src/main/java/com/ydtech/modules/esm/service/impl/EsmInsCompanyServiceImpl.java
  6. 4 0
      src/main/java/com/ydtech/modules/ins/model/vo/QuoteRespVo.java
  7. 14 0
      src/main/java/com/ydtech/modules/order/aop/QuoteNumberVerification.java
  8. 42 4
      src/main/java/com/ydtech/modules/order/aop/aspect/QuoteVerificationAspect.java
  9. 37 5
      src/main/java/com/ydtech/modules/order/components/huatai/HuaTaiQuotationProcessorComponent.java
  10. 3 1
      src/main/java/com/ydtech/modules/order/components/zhongmei/ZhongmeiRepeatInsuranceComponents.java
  11. 89 0
      src/main/java/com/ydtech/modules/order/constants/QuoteNumberConstant.java
  12. 151 0
      src/main/java/com/ydtech/modules/order/controller/QuoteConfigController.java
  13. 15 0
      src/main/java/com/ydtech/modules/order/dao/SysQuoteConfigMapper.java
  14. 30 0
      src/main/java/com/ydtech/modules/order/dao/SysQuoteRecordMapper.java
  15. 21 0
      src/main/java/com/ydtech/modules/order/dao/SysQuoteUserConfigAppendMapper.java
  16. 19 0
      src/main/java/com/ydtech/modules/order/dao/SysQuoteUserMapper.java
  17. 8 0
      src/main/java/com/ydtech/modules/order/entity/crawler/request/CrawlerQuoteRequest.java
  18. 3 0
      src/main/java/com/ydtech/modules/order/entity/crawler/response/CrawlerQuoteResponse.java
  19. 91 0
      src/main/java/com/ydtech/modules/order/entity/po/SysQuoteConfig.java
  20. 80 0
      src/main/java/com/ydtech/modules/order/entity/po/SysQuoteRecord.java
  21. 55 0
      src/main/java/com/ydtech/modules/order/entity/po/SysQuoteUser.java
  22. 80 0
      src/main/java/com/ydtech/modules/order/entity/po/SysQuoteUserConfigAppend.java
  23. 7 0
      src/main/java/com/ydtech/modules/order/entity/vo/BaseQuoteVo.java
  24. 56 0
      src/main/java/com/ydtech/modules/order/entity/vo/QuoteDetailsQueryVo.java
  25. 80 0
      src/main/java/com/ydtech/modules/order/entity/vo/QuoteDetailsVo.java
  26. 92 0
      src/main/java/com/ydtech/modules/order/entity/vo/QuoteNumRedisVo.java
  27. 4 1
      src/main/java/com/ydtech/modules/order/service/InsAreaCompanyService.java
  28. 4 1
      src/main/java/com/ydtech/modules/order/service/InsOrdersService.java
  29. 89 0
      src/main/java/com/ydtech/modules/order/service/SysQuoteConfigService.java
  30. 100 0
      src/main/java/com/ydtech/modules/order/service/SysQuoteRedisService.java
  31. 159 57
      src/main/java/com/ydtech/modules/order/service/impl/BoHaiOrderApiServiceImpl.java
  32. 49 4
      src/main/java/com/ydtech/modules/order/service/impl/ChengTaiOrderApiServiceImpl.java
  33. 53 4
      src/main/java/com/ydtech/modules/order/service/impl/DaJiaOrderServiceImpl.java
  34. 62 12
      src/main/java/com/ydtech/modules/order/service/impl/GuorenOrderApiServiceImpl.java
  35. 35 1
      src/main/java/com/ydtech/modules/order/service/impl/HuaTaiOrderApiServiceImpl.java
  36. 28 1
      src/main/java/com/ydtech/modules/order/service/impl/InsAreaCompanyServiceImpl.java
  37. 50 3
      src/main/java/com/ydtech/modules/order/service/impl/InsCrawlerOrderServiceImpl.java
  38. 8 3
      src/main/java/com/ydtech/modules/order/service/impl/InsOrdersServiceImpl.java
  39. 349 0
      src/main/java/com/ydtech/modules/order/service/impl/SysQuoteConfigServiceImpl.java
  40. 423 0
      src/main/java/com/ydtech/modules/order/service/impl/SysQuoteRedisServiceImpl.java
  41. 183 52
      src/main/java/com/ydtech/modules/order/service/impl/YangGuangOrderApiServiceImpl.java
  42. 84 16
      src/main/java/com/ydtech/modules/order/service/impl/YongchengOrderApiServiceImpl.java
  43. 48 1
      src/main/java/com/ydtech/modules/order/service/impl/ZhongMeiOrderApiServiceImpl.java
  44. 2 1
      src/main/java/com/ydtech/modules/order/service/impl/ZijinOrderApiServiceImpl.java
  45. 27 0
      src/main/java/com/ydtech/modules/order/timer/QuoteNumTimer.java
  46. 10 7
      src/main/resources/mapper/modules/admin/SysUserMapper.xml
  47. 32 0
      src/main/resources/mapper/modules/esm/EsmInsCompanyMapper.xml
  48. 280 0
      src/main/resources/mapper/modules/order/SysQuoteRecordMapper.xml
  49. 40 0
      src/main/resources/mapper/modules/order/SysQuoteUserConfigAppendMapper.xml
  50. 29 0
      src/main/resources/mapper/modules/order/SysQuoteUserMapper.xml

+ 4 - 2
src/main/java/com/ydtech/modules/admin/controller/SysUserController.java

@@ -148,18 +148,20 @@ public class SysUserController extends BaseController {
      */
     @PostMapping(value = "/queryPage")
     public HttpResult queryPage(@RequestBody PageRequest pageRequest) {
-        String deptid = pageRequest.getColumnFilterValue(pageRequest, "deptid");
+        String deptId = pageRequest.getColumnFilterValue(pageRequest, "deptId");
         String name = pageRequest.getColumnFilterValue(pageRequest, "name");
         String containsSubDept = pageRequest.getColumnFilterValue(pageRequest, "containsSubDept");
         String mobile = pageRequest.getColumnFilterValue(pageRequest, "mobile");
         String roleId = pageRequest.getColumnFilterValue(pageRequest, "roleId");
         String deptName = pageRequest.getColumnFilterValue(pageRequest, "deptName");
+        String id = pageRequest.getColumnFilterValue(pageRequest,"id");
         SysUser sysUser = new SysUser();
-        sysUser.setDeptId(deptid);
+        sysUser.setDeptId(deptId);
         sysUser.setName(name);
         sysUser.setMobile(mobile);
         sysUser.setRoleId(roleId);
         sysUser.setDeptName(deptName);
+        sysUser.setId(id);
         Page page = PageRequest.buildPageRequest(pageRequest);
         IPage<SysUser> pResult = sysUserService.selectUserPage(page, sysUser, containsSubDept);
         //传入查询条件

+ 8 - 0
src/main/java/com/ydtech/modules/esm/controller/EsmInsCompanyController.java

@@ -300,4 +300,12 @@ public class EsmInsCompanyController extends BaseController {
         List<EsmInsCompanyResVo> lst = esmInsCompanyService.getExternalAgreementCompanyList(name);
         return HttpResult.ok(lst);
     }
+
+
+    @ApiOperation(value = "查找存在协议的保险公司列表")
+    @GetMapping(value = "/liveCompanyList")
+    public HttpResult liveCompanyList(){
+        List<EsmInsCompanyResVo> list = esmInsCompanyService.liveCompanyList();
+        return HttpResult.ok(list);
+    }
 }

+ 4 - 0
src/main/java/com/ydtech/modules/esm/dao/EsmInsCompanyMapper.java

@@ -43,4 +43,8 @@ public interface EsmInsCompanyMapper extends BaseMapper<EsmInsCompany> {
      *  @Description:  获取外部协议的公司列表
      */
     List<EsmInsCompanyResVo> getExternalAgreementCompanyList( @Param("name")  String name);
+
+
+    List<EsmInsCompanyResVo> liveCompanyList();
+
 }

+ 6 - 0
src/main/java/com/ydtech/modules/esm/service/EsmInsCompanyService.java

@@ -91,6 +91,12 @@ public interface EsmInsCompanyService extends IService<EsmInsCompany> {
      *  @Description:  获取外部协议的保险公司列表
      */
     List<EsmInsCompanyResVo> getExternalAgreementCompanyList(String name);
+
+    /**
+     * 获取已经存在协议的保险公司列表
+     * @return
+     */
+    public List<EsmInsCompanyResVo> liveCompanyList();
 }
 
 

+ 9 - 0
src/main/java/com/ydtech/modules/esm/service/impl/EsmInsCompanyServiceImpl.java

@@ -207,6 +207,15 @@ public class EsmInsCompanyServiceImpl extends ServiceImpl<EsmInsCompanyMapper, E
     public List<EsmInsCompanyResVo> getExternalAgreementCompanyList(String name) {
         return baseMapper.getExternalAgreementCompanyList(name);
     }
+
+    /**
+     * 获取已经存在协议的保险公司列表
+     * @return
+     */
+    @Override
+    public List<EsmInsCompanyResVo> liveCompanyList() {
+        return baseMapper.liveCompanyList();
+    }
 }
 
 

+ 4 - 0
src/main/java/com/ydtech/modules/ins/model/vo/QuoteRespVo.java

@@ -5,6 +5,7 @@ import com.baomidou.mybatisplus.annotation.TableField;
 import com.fasterxml.jackson.annotation.JsonProperty;
 import com.ydtech.modules.order.entity.TaxArrears;
 import com.ydtech.modules.order.entity.crawler.response.CrawlerQuoteResponse;
+import com.ydtech.modules.order.entity.po.SysQuoteRecord;
 import com.ydtech.modules.order.entity.vo.CoreModelsVo;
 import com.ydtech.utils.BigDecimalUtils;
 import com.ydtech.utils.StringUtils;
@@ -216,6 +217,9 @@ public class QuoteRespVo {
     @TableField(value = "syappoint")
     private String syappoint;
 
+    @ApiModelProperty("报价记录")
+    private List<SysQuoteRecord> quoteRecords;
+
     public void setJqClaims(String jqClaims) {
         this.jqClaims = StringUtils.isEmpty(jqClaims) ? null : jqClaims;
     }

+ 14 - 0
src/main/java/com/ydtech/modules/order/aop/QuoteNumberVerification.java

@@ -0,0 +1,14 @@
+package com.ydtech.modules.order.aop;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+@Retention(RetentionPolicy.RUNTIME)
+public @interface QuoteNumberVerification {
+
+    String value() default "";
+
+}
+
+
+

+ 42 - 4
src/main/java/com/ydtech/modules/order/aop/aspect/QuoteVerificationAspect.java

@@ -6,6 +6,7 @@ import com.ydtech.constants.enums.InsuranceRisk;
 import com.ydtech.constants.enums.dict.agreement.ProductsType;
 import com.ydtech.constants.sys.SystemConstant;
 import com.ydtech.core.page.HttpResult;
+import com.ydtech.exception.SystemException;
 import com.ydtech.modules.admin.model.SysUser;
 import com.ydtech.modules.admin.model.SysUserRole;
 import com.ydtech.modules.admin.service.SysSwitchConfigService;
@@ -21,17 +22,16 @@ import com.ydtech.modules.ins.model.vo.KindInfoVo;
 import com.ydtech.modules.ins.model.vo.QuoteRespVo;
 import com.ydtech.modules.ins.model.vo.RiskInfoVo;
 import com.ydtech.modules.order.components.InsOrdersComponents;
+import com.ydtech.modules.order.constants.QuoteNumberConstant;
 import com.ydtech.modules.order.entity.InsAreaCompany;
 import com.ydtech.modules.order.entity.InsAreaCompanyAccidentalDriving;
 import com.ydtech.modules.order.entity.InsOrders;
 import com.ydtech.modules.order.entity.po.InsAreaCompanyError;
 import com.ydtech.modules.order.entity.vo.BaseQuoteInfoVo;
 import com.ydtech.modules.order.entity.vo.BaseQuoteVo;
+import com.ydtech.modules.order.entity.vo.QuoteNumRedisVo;
 import com.ydtech.modules.order.entity.vo.SubOrderExportFeeVo;
-import com.ydtech.modules.order.service.InsAreaCompanyAccidentalDrivingService;
-import com.ydtech.modules.order.service.InsAreaCompanyErrorService;
-import com.ydtech.modules.order.service.InsAreaCompanyService;
-import com.ydtech.modules.order.service.InsOrdersService;
+import com.ydtech.modules.order.service.*;
 import com.ydtech.modules.protocol.constants.TaxSourceStatusConstants;
 import com.ydtech.modules.protocol.dao.PtlTaxSourceNewMapper;
 import com.ydtech.modules.protocol.entity.dto.TaxSourceExcludeDto;
@@ -54,8 +54,11 @@ import org.aspectj.lang.annotation.Aspect;
 import org.aspectj.lang.annotation.Before;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
+import org.springframework.data.redis.core.StringRedisTemplate;
 import org.springframework.stereotype.Component;
 
+import java.math.BigDecimal;
+import java.math.BigInteger;
 import java.util.*;
 
 @Aspect
@@ -103,6 +106,12 @@ public class QuoteVerificationAspect {
 
     private  final SysSwitchConfigService sysSwitchConfigService;
 
+    private final StringRedisTemplate redisTemplate;
+
+    private final SysQuoteConfigService sysQuoteConfigService;
+
+    private final SysQuoteRedisService sysQuoteRedisService;
+
     @AfterReturning(pointcut = "@annotation(com.ydtech.modules.order.aop.QuoteVerification)", returning = "result")
     public void doAfter(HttpResult<QuoteRespVo> result) {
         //计算费用因子
@@ -164,6 +173,35 @@ public class QuoteVerificationAspect {
                 String companyId = ((BaseQuoteVo<?>) arg).getCompanyId();
                 String agreementId = ((BaseQuoteVo<?>) arg).getAgreementId();
                 String orderno = ((BaseQuoteVo<?>) arg).getOrderNo();
+                InsOrders insOrders = insOrdersService.getById(orderno);
+                //获取用户在保险公司的报价次数
+                boolean checkQuoteLimitation = sysQuoteConfigService.checkQuoteLimitation(insOrders.getUserid(), companyId, insOrders.getLicenseno());
+                BigDecimal quoteRatio = sysQuoteRedisService.getQuoteRatio(companyId, insOrders.getUserid());
+                if(Objects.isNull(quoteRatio)){
+                    quoteRatio = new BigDecimal(BigInteger.ZERO);
+                }
+                if(checkQuoteLimitation){
+                    Integer maxQuoteNum = sysQuoteRedisService.getMaxQuoteNum(companyId, insOrders.getUserid(), insOrders.getLicenseno());
+                    System.out.printf("返回可报价次数:" + maxQuoteNum.toString());
+                    //设置最大报价次数
+                    ((BaseQuoteVo<?>) arg).setMaxQuoteNum(maxQuoteNum);
+                    ((BaseQuoteVo<?>) arg).setQuoteRatio(quoteRatio);
+                }else{
+                    //如果次数为0 则 获取出单比
+                    QuoteNumRedisVo quoteNumberRedisData = sysQuoteRedisService.getQuoteNumberRedisData(insOrders.getUserid());
+                    QuoteNumRedisVo.QuoteNumberCompanyVo quoteNumberCompanyVo = quoteNumberRedisData.getOriginalCompanyList().stream().filter(item -> item.getCompanyId().equals(companyId)).findFirst().orElse(null);
+                    if(!Objects.isNull(quoteNumberCompanyVo) && (quoteRatio.equals(BigDecimal.ZERO) || quoteNumberCompanyVo.getOrderRatio().compareTo(quoteRatio) < 0))
+                    {
+                        System.out.printf("报价比例成功:");
+                        //还可以报价 设置最大报价次数为5  报价比例为100%
+                        ((BaseQuoteVo<?>) arg).setMaxQuoteNum(5);
+                        ((BaseQuoteVo<?>) arg).setQuoteRatio(new BigDecimal(100));
+                    }else{
+                        throw new SystemException("报价次数限制!");
+                    }
+                }
+
+
                 //由于前台未传userid判断不了,从主订单表获取用户id和机构id保证待客录单和录单员录单的信息一致
                 /**
                  String deptId = ((BaseQuoteVo<?>) arg).getDeptId();

+ 37 - 5
src/main/java/com/ydtech/modules/order/components/huatai/HuaTaiQuotationProcessorComponent.java

@@ -1,8 +1,12 @@
 package com.ydtech.modules.order.components.huatai;
 
 
+import com.ydtech.modules.order.constants.QuoteNumberConstant;
 import com.ydtech.modules.order.entity.api.huatai.request.HuaTaiQuotedPriceRequest;
 import com.ydtech.modules.order.entity.api.huatai.response.HuaTaiQuotedPriceResponse;
+import com.ydtech.modules.order.entity.po.SysQuoteRecord;
+import com.ydtech.modules.order.entity.vo.BaseQuoteInfoVo;
+import com.ydtech.modules.order.entity.vo.BaseQuoteVo;
 import lombok.RequiredArgsConstructor;
 import org.springframework.stereotype.Component;
 
@@ -25,10 +29,12 @@ public class HuaTaiQuotationProcessorComponent {
 
     private final HuaTaiRepeatInsuranceComponents huaTaiRepeatInsuranceComponents;
 
-    public HuaTaiQuotedPriceResponse handler(HuaTaiQuotedPriceRequest quotedPriceRequest, List<String> warnMessageList, String insuredCode) {
+    public HuaTaiQuotedPriceResponse handler(BaseQuoteInfoVo quoteInfoVo, HuaTaiQuotedPriceRequest quotedPriceRequest, List<String> warnMessageList, String insuredCode,
+                                             String companyId,Integer maxQuoteNum, List<SysQuoteRecord> sysQuoteRecords) {
         boolean b;
         HuaTaiQuotedPriceResponse quotedPriceResponse = huaTaiRequestApiComponents.quotedPrice(quotedPriceRequest,
                 HuaTaiQuotedPriceResponse.class,  insuredCode);
+        maxQuoteNum--;
 
         // 将报价号和校验码置空
         List<HuaTaiQuotedPriceRequest.ContractDto> contract1 = quotedPriceRequest.getBusinessData().getContract();
@@ -40,25 +46,51 @@ public class HuaTaiQuotationProcessorComponent {
         // 交强险重复投保
         b = huaTaiRepeatInsuranceComponents.compulsoryInsurance(quotedPriceRequest, quotedPriceResponse, warnMessageList);
         if (b) {
-            quotedPriceResponse = handler(quotedPriceRequest, warnMessageList, insuredCode);
+            SysQuoteRecord sysQuoteRecord = new SysQuoteRecord(quoteInfoVo.getUserid(),companyId ,quoteInfoVo.getCarInfo().getLicenseNo(),
+                    QuoteNumberConstant.QuoteAction.DATE_DEAL.getCode().toString(),QuoteNumberConstant.QuoteResult.FAIL.getCode().toString());
+            sysQuoteRecords.add(sysQuoteRecord);
+            if(maxQuoteNum <= 0){
+                return quotedPriceResponse;
+            }
+            quotedPriceResponse = handler(quoteInfoVo,quotedPriceRequest, warnMessageList, insuredCode, companyId,maxQuoteNum, sysQuoteRecords);
+
         }
 
         // 商业险重复投保
         b = huaTaiRepeatInsuranceComponents.commercialInsurance(quotedPriceRequest, quotedPriceResponse, warnMessageList);
         if (b) {
-            quotedPriceResponse = handler(quotedPriceRequest, warnMessageList, insuredCode);
+            SysQuoteRecord sysQuoteRecord = new SysQuoteRecord(quoteInfoVo.getUserid(),companyId ,quoteInfoVo.getCarInfo().getLicenseNo(),
+                    QuoteNumberConstant.QuoteAction.DATE_DEAL.getCode().toString(),QuoteNumberConstant.QuoteResult.FAIL.getCode().toString());
+            sysQuoteRecords.add(sysQuoteRecord);
+            if(maxQuoteNum <= 0){
+                return quotedPriceResponse;
+            }
+            quotedPriceResponse = handler(quoteInfoVo,quotedPriceRequest, warnMessageList, insuredCode,companyId, maxQuoteNum, sysQuoteRecords);
         }
 
         // 校验码
         b = huaTaiReinsuranceComponents.processor(quotedPriceResponse, quotedPriceRequest);
         if (b) {
-            quotedPriceResponse = handler(quotedPriceRequest, warnMessageList, insuredCode);
+            SysQuoteRecord sysQuoteRecord = new SysQuoteRecord(quoteInfoVo.getUserid(),companyId ,quoteInfoVo.getCarInfo().getLicenseNo(),
+                    QuoteNumberConstant.QuoteAction.TRANSFER_INSRUANCE.getCode().toString(),QuoteNumberConstant.QuoteResult.FAIL.getCode().toString());
+            sysQuoteRecords.add(sysQuoteRecord);
+            if(maxQuoteNum <= 0){
+                return quotedPriceResponse;
+            }
+            quotedPriceResponse = handler(quoteInfoVo,quotedPriceRequest, warnMessageList, insuredCode, companyId,maxQuoteNum, sysQuoteRecords);
         }
 
         // 校验码有误
         b = huaTaiReinsuranceComponents.processor(quotedPriceResponse);
         if (b) {
-            quotedPriceResponse = handler(quotedPriceRequest, warnMessageList, insuredCode);
+            SysQuoteRecord sysQuoteRecord = new SysQuoteRecord(quoteInfoVo.getUserid(),companyId ,quoteInfoVo.getCarInfo().getLicenseNo(),
+                    QuoteNumberConstant.QuoteAction.TRANSFER_INSRUANCE.getCode().toString(),QuoteNumberConstant.QuoteResult.FAIL.getCode().toString());
+            sysQuoteRecords.add(sysQuoteRecord);
+            if(maxQuoteNum <= 0){
+                return quotedPriceResponse;
+            }
+            quotedPriceResponse = handler(quoteInfoVo,quotedPriceRequest, warnMessageList, insuredCode, companyId,maxQuoteNum, sysQuoteRecords);
+
         }
 
 

+ 3 - 1
src/main/java/com/ydtech/modules/order/components/zhongmei/ZhongmeiRepeatInsuranceComponents.java

@@ -202,7 +202,9 @@ public class ZhongmeiRepeatInsuranceComponents {
             }
         }
 
-        return zhongmeiRequestApiComponents.quotedPrice(quotedPriceRequest, QuotedPriceResponse.class);
+        quotedPriceResponse = zhongmeiRequestApiComponents.quotedPrice(quotedPriceRequest, QuotedPriceResponse.class);
+
+        return quotedPriceResponse;
     }
 
     private QuotedPriceRequest.ContractDTO.ContractMainDTO getPeriodDate(String startDate,

+ 89 - 0
src/main/java/com/ydtech/modules/order/constants/QuoteNumberConstant.java

@@ -0,0 +1,89 @@
+package com.ydtech.modules.order.constants;
+
+import com.alibaba.fastjson.JSONObject;
+import com.ydtech.modules.order.entity.po.SysQuoteConfig;
+import com.ydtech.modules.order.entity.vo.QuoteNumRedisVo;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.var;
+import net.minidev.json.JSONArray;
+import org.springframework.data.redis.core.RedisCallback;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.data.redis.core.ScanOptions;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class QuoteNumberConstant {
+    public static final String QUOTE_NUMBER_KEY = "QUOTE_NUMBER_";
+
+
+    //region 维护redis中的用户报价次数数据
+
+    @AllArgsConstructor
+    @Getter
+    public enum QuoteAuthorizeType{
+        ALL(0,"全部代理人"),
+        PART(1,"部分代理人");
+        private Integer code;
+        private String desc;
+    }
+
+
+    @AllArgsConstructor
+    @Getter
+    public enum QuoteAction{
+        QUOTE_FAILED(0,"报价失败"),
+        QUOTE_SUCCESS(1,"报价成功"),
+        DATE_DEAL(2,"重复投保处理"),
+        TRANSFER_INSRUANCE(3,"转投保");
+        private Integer code;
+        private String desc;
+
+        public static String getByCode(String code){
+            for(var item : values()){
+                if(item.getCode().toString().equals(code)){
+                    return item.desc;
+                }
+            }
+            return "";
+        }
+    }
+
+    @AllArgsConstructor
+    @Getter
+    public enum QuoteResult{
+        FAIL(0,"报价失败"),
+        SUCCESS(1,"报价成功"),
+        QUOTE_NUM_NOT_ENOUGH(2,"次数不足"),;
+        private Integer code;
+        private String desc;
+        public static String getByCode(String code){
+            for(var item : values()){
+                if(item.getCode().toString().equals(code)){
+                    return item.desc;
+                }
+            }
+            return "";
+        }
+    }
+
+    @AllArgsConstructor
+    @Getter
+    public enum QuoteStatus{
+        FAIL(0,"报价失败"),
+        SUCCESS(1,"重复投保"),
+        QUOTE_NUM_NOT_ENOUGH(2,"次数不足"),;
+        private Integer code;
+        private String desc;
+        public static String getByCode(String code){
+            for(var item : values()){
+                if(item.getCode().toString().equals(code)){
+                    return item.desc;
+                }
+            }
+            return "";
+        }
+    }
+
+}

+ 151 - 0
src/main/java/com/ydtech/modules/order/controller/QuoteConfigController.java

@@ -0,0 +1,151 @@
+package com.ydtech.modules.order.controller;
+
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.ydtech.core.page.HttpResult;
+import com.ydtech.modules.base.controller.BaseController;
+import com.ydtech.modules.esm.model.vo.res.EsmInsCompanyResVo;
+import com.ydtech.modules.esm.service.EsmInsCompanyService;
+import com.ydtech.modules.order.constants.QuoteNumberConstant;
+import com.ydtech.modules.order.entity.po.SysQuoteConfig;
+import com.ydtech.modules.order.entity.po.SysQuoteRecord;
+import com.ydtech.modules.order.entity.po.SysQuoteUserConfigAppend;
+import com.ydtech.modules.order.entity.vo.QuoteDetailsQueryVo;
+import com.ydtech.modules.order.entity.vo.QuoteDetailsVo;
+import com.ydtech.modules.order.entity.vo.QuoteNumRedisVo;
+import com.ydtech.modules.order.service.SysQuoteConfigService;
+import com.ydtech.modules.order.service.SysQuoteRedisService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiModelProperty;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.HashMap;
+import java.util.List;
+
+@Api(tags = "报价次数配置")
+@RestController
+@RequestMapping(value = "/quoteConfig")
+public class QuoteConfigController extends BaseController {
+
+    @Autowired
+    SysQuoteConfigService sysQuoteConfigService;
+
+    @Autowired
+    SysQuoteRedisService sysQuoteRedisService;
+
+    @Autowired
+    EsmInsCompanyService esmInsCompanyService;
+
+    @GetMapping(value = "/getQuoteConfigInfo")
+    @ApiOperation(value = "获取报价配置信息")
+    public HttpResult getQuoteConfigInfo(String companyId){
+        SysQuoteConfig quoteConfigInfo = sysQuoteConfigService.getQuoteConfigInfo(companyId);
+        return HttpResult.ok(quoteConfigInfo);
+    }
+
+    @PostMapping(value = "setQuoteInfo")
+    @ApiOperation(value = "设置报价配置信息")
+    public HttpResult setQuoteInfo(@RequestBody SysQuoteConfig sysQuoteConfig){
+
+        return sysQuoteConfigService.setQuoteInfo(sysQuoteConfig) ? HttpResult.ok("设置报价配置成功") : HttpResult.error("设置报价配置失败");
+    }
+
+    @PostMapping(value = "syncQuoteInfo")
+    @ApiOperation(value = "同步报价配置信息")
+    public HttpResult syncQuoteInfo(@RequestBody SysQuoteConfig sysQuoteConfig){
+        List<EsmInsCompanyResVo> esmInsCompanyResVos = esmInsCompanyService.liveCompanyList();
+        esmInsCompanyResVos.forEach(item->{
+            sysQuoteConfig.setCompanyId(item.getId());
+            sysQuoteConfigService.setQuoteInfo(sysQuoteConfig);
+        });
+        return HttpResult.ok("同步配置成功");
+    }
+
+    @PostMapping(value = "appendUserConfig")
+    @ApiOperation(value = "用户配置追加配置信息")
+    public HttpResult appendUserCOnfig(@RequestBody SysQuoteUserConfigAppend sysQuoteUserConfigAppend){
+        return sysQuoteConfigService.quoteConfigAppend(sysQuoteUserConfigAppend)? HttpResult.ok("设置用户配置成功") : HttpResult.error("设置用户配置失败");
+    }
+
+    @PostMapping(value = "quoteDetails")
+    @ApiOperation(value = "报价明细")
+    public HttpResult quoteDetails(@RequestBody QuoteDetailsQueryVo quoteDetailsQueryVo){
+        Page page = buildPageRequest(quoteDetailsQueryVo.getPageDto());
+        Page<QuoteDetailsVo> quoteRecordPage = sysQuoteConfigService.getQuoteRecordPage(page, quoteDetailsQueryVo);
+        return HttpResult.ok(quoteRecordPage);
+    }
+
+    @PostMapping(value = "quoteUserDetails")
+    @ApiOperation(value = "报价信息")
+    public HttpResult quoteUserDetails(@RequestBody QuoteDetailsQueryVo quoteDetailsQueryVo){
+        Page page = buildPageRequest(quoteDetailsQueryVo.getPageDto());
+        Page<QuoteDetailsVo> quoteDetails = sysQuoteConfigService.getQuoteDetails(page, quoteDetailsQueryVo);
+        return HttpResult.ok(quoteDetails);
+    }
+
+    @PostMapping(value = "quoteRequestDetail")
+    @ApiOperation(value = "报价请求明细")
+    public HttpResult quoteRequestDetail(@RequestBody QuoteDetailsQueryVo quoteDetailsQueryVo){
+        Page page = buildPageRequest(quoteDetailsQueryVo.getPageDto());
+        Page<QuoteDetailsVo> quoteRecordPage = sysQuoteConfigService.getQuoteRecordPage(page, quoteDetailsQueryVo);
+        return HttpResult.ok(quoteRecordPage);
+    }
+
+    @PostMapping(value = "getAppendUserQuotePage")
+    @ApiOperation(value = "用户追加报价次数信息")
+    public HttpResult getAppendUserQuotePage(@RequestBody QuoteDetailsQueryVo quoteDetailsQueryVo){
+        Page page = buildPageRequest(quoteDetailsQueryVo.getPageDto());
+        Page<QuoteDetailsVo> quoteDetails = sysQuoteConfigService.getAppendUserQuote(page, quoteDetailsQueryVo);
+        return HttpResult.ok(quoteDetails);
+    }
+
+    @GetMapping(value = "getQuoteAction")
+    @ApiModelProperty(value = "获取报价动作字典")
+    public HttpResult getQuoteAction(){
+        JSONArray resultArray = new JSONArray();
+        for (QuoteNumberConstant.QuoteAction value : QuoteNumberConstant.QuoteAction.values()) {
+            JSONObject jsonObject = new JSONObject();
+            jsonObject.put("code",value.getCode());
+            jsonObject.put("desc",value.getDesc());
+            resultArray.add(jsonObject);
+        }
+        return HttpResult.ok(resultArray);
+    }
+
+    @GetMapping(value = "getQuoteResult")
+    @ApiModelProperty(value = "获取报价结果字典")
+    public HttpResult getQuoteResult(){
+        JSONArray resultArray = new JSONArray();
+        for (QuoteNumberConstant.QuoteResult value : QuoteNumberConstant.QuoteResult.values()) {
+            JSONObject jsonObject = new JSONObject();
+            jsonObject.put("code",value.getCode());
+            jsonObject.put("desc",value.getDesc());
+            resultArray.add(jsonObject);
+        }
+        return HttpResult.ok(resultArray);
+    }
+
+    @GetMapping(value = "getRedisData")
+    public HttpResult getRedisData(String userId) {
+        QuoteNumRedisVo quoteNumberRedisData = sysQuoteRedisService.getQuoteNumberRedisData(userId);
+        return HttpResult.ok(JSONObject.toJSON(quoteNumberRedisData));
+    }
+
+    @PostMapping(value = "setRedisData")
+    public HttpResult setRedisData(@RequestBody JSONObject jsonObject) {
+        String userId = jsonObject.getString("userId");
+        QuoteNumRedisVo data = jsonObject.getJSONObject("data").toJavaObject(QuoteNumRedisVo.class);
+        sysQuoteRedisService.setQuoteRecordRedis(userId,data);
+        return HttpResult.ok("设置成功");
+    }
+
+    @GetMapping(value = "delRedisData")
+    public HttpResult delRedisData(String userId){
+        sysQuoteRedisService.delQuoteRedis(userId);
+        return HttpResult.ok("");
+    }
+
+}

+ 15 - 0
src/main/java/com/ydtech/modules/order/dao/SysQuoteConfigMapper.java

@@ -0,0 +1,15 @@
+package com.ydtech.modules.order.dao;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.ydtech.modules.order.entity.po.SysQuoteConfig;
+import com.ydtech.modules.order.entity.vo.dajia.InsAccidentalDrivingDajia;
+
+/**
+ * @author Administrator
+ * @description 针对表【ins_accidental_driving(驾意险)】的数据库操作Mapper
+ * @createDate 2023-03-09 14:45:58
+ * @Entity generator.domain.InsAccidentalDriving
+ */
+public interface SysQuoteConfigMapper extends BaseMapper<SysQuoteConfig> {
+
+}

+ 30 - 0
src/main/java/com/ydtech/modules/order/dao/SysQuoteRecordMapper.java

@@ -0,0 +1,30 @@
+package com.ydtech.modules.order.dao;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.ydtech.modules.order.entity.po.SysQuoteRecord;
+import com.ydtech.modules.order.entity.po.SysQuoteUser;
+import com.ydtech.modules.order.entity.vo.QuoteDetailsQueryVo;
+import com.ydtech.modules.order.entity.vo.QuoteDetailsVo;
+import org.apache.ibatis.annotations.Param;
+
+import java.math.BigDecimal;
+import java.util.List;
+
+/**
+ * @author Administrator
+ * @description 针对表【ins_accidental_driving(驾意险)】的数据库操作Mapper
+ * @createDate 2023-03-09 14:45:58
+ * @Entity generator.domain.InsAccidentalDriving
+ */
+public interface SysQuoteRecordMapper extends BaseMapper<SysQuoteRecord> {
+    public boolean insertBatch(List<SysQuoteRecord> list);
+
+    public Page<QuoteDetailsVo> getQuoteRecordPage(Page page, @Param("param") QuoteDetailsQueryVo quoteDetailsQueryVo);
+
+    public Page<QuoteDetailsVo> getQuoteRequestRecordPage(Page page,@Param("param") QuoteDetailsQueryVo quoteDetailsQueryVo);
+
+    public Page<QuoteDetailsVo> getQuoteDetails(Page page, @Param("param") QuoteDetailsQueryVo quoteDetailsQueryVo);
+
+    public BigDecimal getQuoteRatio(@Param("userId") String userId, @Param("companyId") String companyId);
+}

+ 21 - 0
src/main/java/com/ydtech/modules/order/dao/SysQuoteUserConfigAppendMapper.java

@@ -0,0 +1,21 @@
+package com.ydtech.modules.order.dao;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.ydtech.modules.order.entity.po.SysQuoteConfig;
+import com.ydtech.modules.order.entity.po.SysQuoteUserConfigAppend;
+import com.ydtech.modules.order.entity.vo.QuoteDetailsQueryVo;
+import com.ydtech.modules.order.entity.vo.QuoteDetailsVo;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+/**
+ * @author Administrator
+ * @description 针对表【ins_accidental_driving(驾意险)】的数据库操作Mapper
+ * @createDate 2023-03-09 14:45:58
+ * @Entity generator.domain.InsAccidentalDriving
+ */
+public interface SysQuoteUserConfigAppendMapper extends BaseMapper<SysQuoteUserConfigAppend> {
+    public Page<QuoteDetailsVo> getAppendUserQuote(Page page,@Param("param") QuoteDetailsQueryVo quoteDetailsQueryVo);
+}

+ 19 - 0
src/main/java/com/ydtech/modules/order/dao/SysQuoteUserMapper.java

@@ -0,0 +1,19 @@
+package com.ydtech.modules.order.dao;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.ydtech.modules.order.entity.po.SysQuoteConfig;
+import com.ydtech.modules.order.entity.po.SysQuoteUser;
+
+import java.util.List;
+
+/**
+ * @author Administrator
+ * @description 针对表【ins_accidental_driving(驾意险)】的数据库操作Mapper
+ * @createDate 2023-03-09 14:45:58
+ * @Entity generator.domain.InsAccidentalDriving
+ */
+public interface SysQuoteUserMapper extends BaseMapper<SysQuoteUser> {
+    public boolean insertBatch(List<SysQuoteUser> list);
+
+    public List<SysQuoteConfig> getQuoteUserConfig(String userId);
+}

+ 8 - 0
src/main/java/com/ydtech/modules/order/entity/crawler/request/CrawlerQuoteRequest.java

@@ -4,6 +4,8 @@ import com.ydtech.modules.order.entity.vo.BaseQuoteInfoVo;
 import lombok.Data;
 import lombok.EqualsAndHashCode;
 
+import java.math.BigDecimal;
+
 @EqualsAndHashCode(callSuper = true)
 @Data
 public class CrawlerQuoteRequest extends BaseQuoteInfoVo {
@@ -47,4 +49,10 @@ public class CrawlerQuoteRequest extends BaseQuoteInfoVo {
      * 是否需要验车
      */
     private Boolean isInspect;
+
+    /**
+     * 最大报价次数
+     */
+    private Integer maxQuoteNum;
+
 }

+ 3 - 0
src/main/java/com/ydtech/modules/order/entity/crawler/response/CrawlerQuoteResponse.java

@@ -314,6 +314,9 @@ public class CrawlerQuoteResponse extends CrawlerBaseResponse {
         @JsonProperty("upimage_url")
         private String upimageUrl;
 
+        @JsonProperty("maxQuoteNum")
+        private String maxQuoteNum;
+
         public String getDiscount() {
             return StringUtils.isEmpty(discount) ? "0" : discount;
         }

+ 91 - 0
src/main/java/com/ydtech/modules/order/entity/po/SysQuoteConfig.java

@@ -0,0 +1,91 @@
+package com.ydtech.modules.order.entity.po;
+
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.ydtech.modules.admin.model.SysUser;
+import com.ydtech.modules.order.entity.api.pingan.response.QuoteResponse;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * 
+ * @TableName sys_quote_config
+ */
+@TableName(value ="sys_quote_config")
+@Data
+public class SysQuoteConfig implements Serializable {
+    /**
+     * 主键
+     */
+    @TableId
+    private String id;
+
+    /**
+     * 保险公司id
+     */
+    @TableField(value = "company_id")
+    private String companyId;
+
+    /**
+     * 是否开启
+     */
+    @TableField(value = "is_enabled")
+    private Integer isEnabled;
+
+    /**
+     * 每天最大报价次数
+     */
+    @TableField(value = "day_max_quote_num")
+    private Integer dayMaxQuoteNum;
+
+    /**
+     * 每车最大报价次数
+     */
+    @TableField(value = "car_max_quote_num")
+    private Integer carMaxQuoteNum;
+
+    /**
+     * 订单比率
+     */
+    @TableField(value = "order_ratio")
+    private BigDecimal orderRatio;
+
+    /**
+     * 授权类型 0 全部代理人  1部分代理人
+     */
+    @TableField(value = "authorize")
+    private Integer authorize;
+
+    @TableField(value = "create_time")
+    private LocalDateTime createTime;
+
+    @TableField(value = "create_by")
+    private String createBy;
+
+    @TableField(value = "update_time")
+    private LocalDateTime updateTime;
+
+    @TableField(value = "update_by")
+    private String updateBy;
+
+    /**
+     * 代理人id list
+     */
+    @TableField(exist = false)
+    List<SysUser> proxyList;
+
+    public SysQuoteConfig(){
+        if(Objects.isNull(proxyList)){
+            this.proxyList = new ArrayList<>();
+        }
+    }
+
+}

+ 80 - 0
src/main/java/com/ydtech/modules/order/entity/po/SysQuoteRecord.java

@@ -0,0 +1,80 @@
+package com.ydtech.modules.order.entity.po;
+
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.ydtech.modules.base.controller.BaseController;
+import com.ydtech.modules.order.entity.vo.BaseQuoteInfoVo;
+import com.ydtech.utils.idgen.IdGenerate;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import javax.persistence.Table;
+import java.io.Serializable;
+import java.time.LocalDateTime;
+
+/**
+ * 
+ * @TableName sys_quote_user
+ */
+@TableName(value ="sys_quote_record")
+@Data
+@NoArgsConstructor
+public class SysQuoteRecord implements Serializable {
+    /**
+     * 主键
+     */
+    @TableId
+    private String id;
+
+    @TableField(value = "user_id")
+    private String userId;
+
+    @TableField(value = "company_id")
+    private String companyId;
+
+    @TableField(value = "sub_order_no")
+    private String subOrderNo;
+
+    @TableField(value = "license_no")
+    private String licenseNo;
+
+    @TableField(value = "action")
+    private String action;
+
+    @TableField(value = "result")
+    private String result;
+
+    @TableField(value = "status")
+    private Integer status;
+
+    @TableField(value = "agent")
+    private String agent;
+
+    @TableField(value = "operator")
+    private String operator;
+
+    @TableField(value = "create_time")
+    private LocalDateTime createTime;
+
+    public SysQuoteRecord(BaseQuoteInfoVo quoteInfoVo,String action,String result){
+        this.id = IdGenerate.nextId();
+        this.userId = quoteInfoVo.getUserid();
+        this.companyId = quoteInfoVo.getOrderCompanyId();
+        this.licenseNo = quoteInfoVo.getCarInfo().getLicenseNo();
+
+
+    }
+
+    public SysQuoteRecord(String userId,String companyId,String licenseNo,String action,String result){
+        this.id = IdGenerate.nextId();
+        this.userId = userId;
+        this.companyId = companyId;
+        this.licenseNo = licenseNo;
+        this.action = action;
+        this.result = result;
+        this.operator = BaseController.getUserId();
+        this.createTime = LocalDateTime.now();
+
+    }
+}

+ 55 - 0
src/main/java/com/ydtech/modules/order/entity/po/SysQuoteUser.java

@@ -0,0 +1,55 @@
+package com.ydtech.modules.order.entity.po;
+
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.ydtech.modules.order.entity.api.pingan.response.QuoteResponse;
+import com.ydtech.utils.idgen.IdGenerate;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * 
+ * @TableName sys_quote_user
+ */
+@TableName(value ="sys_quote_user")
+@Data
+public class SysQuoteUser implements Serializable {
+    /**
+     * 主键
+     */
+    @TableId
+    private String id;
+
+    @TableField(value = "config_id")
+    private String configId;
+
+    @TableField(value = "user_id")
+    private String userId;
+
+    public SysQuoteUser(String configId,String userId){
+        this.id = IdGenerate.nextId();
+        this.configId = configId;
+        this.userId = userId;
+    }
+
+    public SysQuoteUser(){
+
+    }
+
+
+
+    public static List<SysQuoteUser> getSysQuoteUserList(String configId,List<String> userIds){
+        List<SysQuoteUser> sysQuoteConfigs = new ArrayList<>();
+        userIds.forEach(user->{
+            SysQuoteUser sysQuoteUser = new SysQuoteUser(configId,user);
+            sysQuoteConfigs.add(sysQuoteUser);
+        });
+        return sysQuoteConfigs;
+    }
+}

+ 80 - 0
src/main/java/com/ydtech/modules/order/entity/po/SysQuoteUserConfigAppend.java

@@ -0,0 +1,80 @@
+package com.ydtech.modules.order.entity.po;
+
+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;
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+
+/**
+ * 
+ * @TableName sys_quote_user_config_append
+ */
+@TableName(value ="sys_quote_user_config_append")
+@Data
+public class SysQuoteUserConfigAppend implements Serializable {
+    /**
+     * 主键
+     */
+    @TableId
+    private Long id;
+
+    @TableField(value = "user_id")
+    private String userId;
+
+    /**
+     * 保险公司id
+     */
+    @TableField(value = "company_id")
+    private String companyId;
+
+    /**
+     * 每天最大报价次数
+     */
+    @TableField(value = "day_max_quote_num")
+    private Integer dayMaxQuoteNum;
+
+    /**
+     * 每车最大报价次数
+     */
+    @TableField(value = "car_max_quote_num")
+    private Integer carMaxQuoteNum;
+
+    @TableField(exist = false)
+    private Integer quoteNumber;
+
+    /**
+     * 订单比率
+     */
+    @TableField(value = "order_ratio")
+    private BigDecimal orderRatio;
+
+    /**
+     * 备注
+     */
+    @TableField(value = "remark")
+    private String remark;
+
+    @TableField(value = "start_time")
+    private LocalDateTime startTime;
+
+    @TableField(value = "end_time")
+    private LocalDateTime endTime;
+
+    @TableField(value = "create_time")
+    private LocalDateTime createTime;
+
+    @TableField(value = "create_by")
+    private String createBy;
+
+
+    public SysQuoteUserConfigAppend(){
+        dayMaxQuoteNum = 0;
+        carMaxQuoteNum = 0;
+        orderRatio = new BigDecimal(0);
+    }
+
+}

+ 7 - 0
src/main/java/com/ydtech/modules/order/entity/vo/BaseQuoteVo.java

@@ -169,4 +169,11 @@ public class BaseQuoteVo<T> {
 
     @ApiModelProperty("特别约定")
     private List<GuoRenSpecialAgreementVo> guoRenSpecialAgreementVo;
+
+    //2024-11-29 新增 本次的最大报价次数
+    @ApiModelProperty("报价次数")
+    private Integer maxQuoteNum;
+
+    @ApiModelProperty("报价比例")
+    private BigDecimal quoteRatio;
 }

+ 56 - 0
src/main/java/com/ydtech/modules/order/entity/vo/QuoteDetailsQueryVo.java

@@ -0,0 +1,56 @@
+package com.ydtech.modules.order.entity.vo;
+
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.ydtech.core.page.PageRequest;
+import com.ydtech.modules.order.entity.po.SysQuoteConfig;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.math.BigDecimal;
+import java.util.List;
+
+/**
+ * 报价次数的redis缓存数据实体
+ */
+@Data
+public class QuoteDetailsQueryVo extends PageRequest {
+    @ApiModelProperty(value = "子订单号")
+    private String subOrderNo;
+
+    @ApiModelProperty(value = "动作")
+    private String action;
+
+    @ApiModelProperty(value = "车牌")
+    private String licenseNo;
+
+    @ApiModelProperty(value = "结果")
+    private String result;
+
+    @ApiModelProperty(value = "起始时间")
+    private String startTime;
+
+    @ApiModelProperty(value = "止期时间")
+    private String endTime;
+
+    @ApiModelProperty(value = "保险公司id")
+    private String companyId;
+
+    @ApiModelProperty(value = "工号id")
+    private String agentId;
+
+    @ApiModelProperty(value = "代理人")
+    private String agent;
+
+    @ApiModelProperty(value = "操作人")
+    private String operator;
+
+    @ApiModelProperty(value = "部门id")
+    private String deptId;
+
+    @ApiModelProperty(value = "创建人")
+    private String createBy;
+}

+ 80 - 0
src/main/java/com/ydtech/modules/order/entity/vo/QuoteDetailsVo.java

@@ -0,0 +1,80 @@
+package com.ydtech.modules.order.entity.vo;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+/**
+ * 报价次数的redis缓存数据实体
+ */
+@Data
+public class QuoteDetailsVo {
+    @ApiModelProperty(value = "子订单号")
+    private String subOrderNo;
+
+    @ApiModelProperty(value = "动作")
+    private String action;
+
+    @ApiModelProperty(value = "车牌")
+    private String licenseNo;
+
+    @ApiModelProperty(value = "保险公司Id")
+    private String companyId;
+
+    @ApiModelProperty(value = "保险公司")
+    private String company;
+
+    @ApiModelProperty(value = "部门id")
+    private String deptId;
+
+    @ApiModelProperty(value = "部门名称")
+    private String deptName;
+
+    @ApiModelProperty(value = "工号")
+    private String userId;
+
+    @ApiModelProperty(value = "姓名")
+    private String name;
+
+    @ApiModelProperty(value = "联系电话")
+    private String mobile;
+
+    @ApiModelProperty(value = "结果")
+    private String result;
+
+    @ApiModelProperty(value = "报价时间")
+    private String createTime;
+
+    @ApiModelProperty(value = "创建人")
+    private String createBy;
+
+    @ApiModelProperty(value = "报价失败次数")
+    private String failedCount;
+
+    @ApiModelProperty(value = "报价成功次数")
+    private String successCount;
+
+    @ApiModelProperty(value = "报价比例")
+    private String rate;
+
+    @ApiModelProperty(value = "最大报价次数")
+    private String dayMaxQuoteNum;
+
+    @ApiModelProperty(value = "最大车辆报价次数")
+    private String carMaxQuoteNum;
+
+    @ApiModelProperty(value = "今日报价次数")
+    private Integer numCount;
+
+    @ApiModelProperty(value = "今日报价单数")
+    private Integer dayAllOrder;
+
+    @ApiModelProperty(value = "今日承保单数")
+    private Integer dayCoverOrder;
+
+    @ApiModelProperty(value = "累计报价单数")
+    private Integer wholeAllOrder;
+
+    @ApiModelProperty(value = "累计承保单数")
+    private Integer wholeCoverOrder;
+
+}

+ 92 - 0
src/main/java/com/ydtech/modules/order/entity/vo/QuoteNumRedisVo.java

@@ -0,0 +1,92 @@
+package com.ydtech.modules.order.entity.vo;
+
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.ydtech.modules.order.entity.po.SysQuoteConfig;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import org.apache.poi.hpsf.Decimal;
+
+import java.math.BigDecimal;
+import java.util.List;
+
+/**
+ * 报价次数的redis缓存数据实体
+ */
+@Data
+public class QuoteNumRedisVo {
+
+    //用户id
+    private String userId;
+
+    //标准的保险公司报价次数列表
+    private List<QuoteNumberCompanyVo> originalCompanyList;
+
+    //保险公司报价的列表次数
+    private List<QuoteNumberCompanyVo> quoteCompanyList;
+
+    //车辆的报价次数列表
+    private List<CarQuoteNumberVo> carList;
+
+
+    @Data
+    @AllArgsConstructor
+    public static class QuoteNumberCompanyVo{
+        private String companyId;
+
+        private Integer dayMaxQuoteNum;
+
+        private Integer carMaxQuoteNum;
+
+        private BigDecimal orderRatio;
+
+        public QuoteNumberCompanyVo(){
+
+        }
+
+        public QuoteNumberCompanyVo(SysQuoteConfig sysQuoteConfig){
+            this.companyId = sysQuoteConfig.getCompanyId();
+            this.dayMaxQuoteNum = sysQuoteConfig.getDayMaxQuoteNum();
+            this.carMaxQuoteNum = sysQuoteConfig.getCarMaxQuoteNum();
+            this.orderRatio = sysQuoteConfig.getOrderRatio();
+        }
+
+
+    }
+
+    @Data
+    @AllArgsConstructor
+    @NoArgsConstructor
+    public static class CarQuoteNumberVo{
+
+        private String companyId;
+
+        private String licenseNo;
+
+        private Integer quoteNum;
+    }
+
+    public String toJsonString(QuoteNumRedisVo vo){
+        return JSONObject.toJSONString(this);
+    }
+
+    public QuoteNumRedisVo(){
+
+    }
+
+
+
+    public QuoteNumRedisVo(String json){
+        //反序列化
+        JSONObject jsonObject = JSONObject.parseObject(json);
+        this.originalCompanyList = JSONArray.parseArray(jsonObject.getString("originalCompanyList"),QuoteNumberCompanyVo.class);
+        this.quoteCompanyList = JSONArray.parseArray(jsonObject.getString("quoteCompanyList"),QuoteNumberCompanyVo.class);
+        this.carList = JSONArray.parseArray(jsonObject.getString("carList"),CarQuoteNumberVo.class);
+    }
+
+    public QuoteNumRedisVo toObject(String json){
+        return JSONObject.parseObject(json,QuoteNumRedisVo.class);
+    }
+
+}

+ 4 - 1
src/main/java/com/ydtech/modules/order/service/InsAreaCompanyService.java

@@ -76,7 +76,10 @@ public interface InsAreaCompanyService extends IService<InsAreaCompany> {
      * @param insAreaCompany
      * @param insAreaCompanyAccidentalDriving 驾意险信息
      */
-    void insertCompanyAndOrders(InsAreaCompany insAreaCompany, InsAreaCompanyAccidentalDriving insAreaCompanyAccidentalDriving);
+    String insertCompanyAndOrders(InsAreaCompany insAreaCompany, InsAreaCompanyAccidentalDriving insAreaCompanyAccidentalDriving);
+
+    String insertCompanyAndOrders(String subOrderNo,InsAreaCompany insAreaCompany, InsAreaCompanyAccidentalDriving insAreaCompanyAccidentalDriving);
+
 
     void insertCompanyAndOrders(InsAreaCompany insAreaCompany, List<InsAreaCompanyAccidentalDriving> insAreaCompanyAccidentalDriving);
 

+ 4 - 1
src/main/java/com/ydtech/modules/order/service/InsOrdersService.java

@@ -281,7 +281,10 @@ public interface InsOrdersService extends IService<InsOrders> {
      * 生成失败订单数据
      * @return
      */
-    boolean responseFailedOrder(BaseQuoteVo quoteVo, PtlAgreementAttribution ptlAgreementAttribution, InsOrders insOrder, String errorMessage, InsOrderStatusEnum statusEnum);
+    String responseFailedOrder(BaseQuoteVo quoteVo, PtlAgreementAttribution ptlAgreementAttribution, InsOrders insOrder, String errorMessage, InsOrderStatusEnum statusEnum);
+
+    String responseFailedOrder(String subOrderNo,BaseQuoteVo quoteVo, PtlAgreementAttribution ptlAgreementAttribution, InsOrders insOrder, String errorMessage, InsOrderStatusEnum statusEnum);
+
     /**
      *  @version
      *  @author: hxl

+ 89 - 0
src/main/java/com/ydtech/modules/order/service/SysQuoteConfigService.java

@@ -0,0 +1,89 @@
+package com.ydtech.modules.order.service;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.ydtech.modules.order.entity.InsAreaCompany;
+import com.ydtech.modules.order.entity.InsDrivingIntentionInsuranceType;
+import com.ydtech.modules.order.entity.InsOrders;
+import com.ydtech.modules.order.entity.po.SysQuoteConfig;
+import com.ydtech.modules.order.entity.po.SysQuoteRecord;
+import com.ydtech.modules.order.entity.po.SysQuoteUserConfigAppend;
+import com.ydtech.modules.order.entity.vo.QuoteDetailsQueryVo;
+import com.ydtech.modules.order.entity.vo.QuoteDetailsVo;
+import com.ydtech.modules.order.entity.vo.QuoteNumRedisVo;
+
+import java.util.List;
+
+/**
+ * 针对表【SysQuoteConfig】的数据库操作Service
+ */
+public interface SysQuoteConfigService extends IService<SysQuoteConfig> {
+
+
+
+
+    /**
+     * 检查报价限制
+     * @return
+     */
+    public boolean checkQuoteLimitation(String userId,String companyId,String licenseNo);
+
+    /**
+     * 获取保险公司的报价次数
+     * @param userId
+     * @param companyId
+     * @return
+     */
+    public QuoteNumRedisVo.QuoteNumberCompanyVo getUserQuoteNumber(String userId, String companyId);
+
+    /**
+     * 获取保险公司的报价次数
+     * @param userId
+     * @return
+     */
+    public List<SysQuoteConfig> getUserQuoteNumber(String userId);
+
+    /**
+     * 设置配置信息
+     */
+    public boolean setQuoteInfo(SysQuoteConfig sysQuoteConfig);
+
+    /**
+     * 获取报价次数配置信息
+     */
+    public SysQuoteConfig getQuoteConfigInfo(String companyId);
+
+    /**
+     * 关联用户
+     */
+    public boolean connectUser(String configId,List<String> userIds);
+
+    /**
+     * 追加配置
+     */
+    public boolean quoteConfigAppend(SysQuoteUserConfigAppend sysQuoteUserConfigAppend);
+
+    /**
+     * 获取用户追加报价的列表
+     * @param quoteDetailsQueryVo
+     * @return
+     */
+    public Page<QuoteDetailsVo> getAppendUserQuote(Page page,QuoteDetailsQueryVo quoteDetailsQueryVo);
+
+    /**
+     * 根据保险公司获取今天用户追加的数据
+     */
+    public List<SysQuoteUserConfigAppend> getTodayAppendData(String companyId);
+
+    /**
+     * 获取报价历史分页
+     * @param page
+     * @param quoteDetailsQueryVo
+     * @return
+     */
+    public Page<QuoteDetailsVo> getQuoteRecordPage(Page page, QuoteDetailsQueryVo quoteDetailsQueryVo);
+
+    public Page<QuoteDetailsVo> getQuoteRequestRecordPage(Page page, QuoteDetailsQueryVo quoteDetailsQueryVo);
+
+    public Page<QuoteDetailsVo> getQuoteDetails(Page page, QuoteDetailsQueryVo quoteDetailsQueryVo);
+}

+ 100 - 0
src/main/java/com/ydtech/modules/order/service/SysQuoteRedisService.java

@@ -0,0 +1,100 @@
+package com.ydtech.modules.order.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.ydtech.modules.order.entity.po.SysQuoteConfig;
+import com.ydtech.modules.order.entity.po.SysQuoteRecord;
+import com.ydtech.modules.order.entity.po.SysQuoteUserConfigAppend;
+import com.ydtech.modules.order.entity.vo.QuoteNumRedisVo;
+import org.springframework.data.redis.core.RedisTemplate;
+
+import java.math.BigDecimal;
+import java.util.List;
+
+/**
+ * 针对表【SysQuoteConfig】的数据库操作Service
+ */
+public interface SysQuoteRedisService {
+
+    /**
+     * 模糊搜索报价次数的keys
+     * @param pattern
+     * @return
+     */
+    public List<String> searchKeysWithScan(String pattern);
+
+
+    /**
+     * 组装报价次数的redis数据
+     * @return
+     */
+    public QuoteNumRedisVo assembleQuoteRedisData(String userId,List<SysQuoteConfig> sysQuoteConfigs);
+
+    /**
+     * 保存redis数据
+     * @param quoteNumberRedis
+     */
+    public void saveRedisData(QuoteNumRedisVo quoteNumberRedis);
+
+    /**
+     * 获取报价次数缓存key
+     * @param userId
+     * @return
+     */
+    public String getQuoteNumberRedisKey(String userId);
+
+    /**
+     * 从redis获取用户报价次数的数据
+     * @param userId
+     * @return
+     */
+    public QuoteNumRedisVo getQuoteNumberRedisData(String userId);
+
+    public void setQuoteRecordRedis(String userId, QuoteNumRedisVo quoteNumRedisVo);
+
+    public void delQuoteRedis(String userId);
+
+    /**
+     * 更新所有的缓存数据
+     * @param sysQuoteConfig
+     * @return
+     */
+    public boolean updateAllQuoteRedis(SysQuoteConfig sysQuoteConfig);
+
+    /**
+     * 更新用户追加的缓存数据
+     * @param sysQuoteUserConfigAppend
+     * @return
+     */
+    public boolean updateUserQuoteAppendRedis(SysQuoteUserConfigAppend sysQuoteUserConfigAppend);
+
+    /**
+     * 报价之后redis数据更新
+     * @param companyId
+     * @param userId
+     * @param licenseNo
+     * @param num
+     * @return
+     */
+    public void quoteAfterRedisData(String companyId,String userId,String licenseNo,Integer num);
+
+    /**
+     * 根据车辆信息获取最大的报价次数
+     */
+    public Integer getMaxQuoteNum(String companyId,String userId,String licenseNo);
+
+    /**
+     * 获取出单比例
+     * @param companyId
+     * @param userId
+     * @return
+     */
+    public BigDecimal getQuoteRatio(String companyId, String userId);
+
+    /**
+     * 刷新报价次数
+     * @param companyId
+     * @param userId
+     * @return
+     */
+    public void refreshQuoteNum(String companyId, String userId, List<SysQuoteRecord> sysQuoteRecords);
+}

+ 159 - 57
src/main/java/com/ydtech/modules/order/service/impl/BoHaiOrderApiServiceImpl.java

@@ -13,7 +13,9 @@ import com.ydtech.modules.ins.model.vo.*;
 import com.ydtech.modules.order.components.ConfigureParametersComponents;
 import com.ydtech.modules.order.components.FileComponents;
 import com.ydtech.modules.order.components.bohai.BoHaiRequestApiComponent;
+import com.ydtech.modules.order.constants.QuoteNumberConstant;
 import com.ydtech.modules.order.constants.UnderwritingStatus;
+import com.ydtech.modules.order.dao.SysQuoteRecordMapper;
 import com.ydtech.modules.order.entity.*;
 import com.ydtech.modules.order.entity.api.bohai.constants.*;
 import com.ydtech.modules.order.entity.api.bohai.request.*;
@@ -23,6 +25,7 @@ import com.ydtech.modules.order.entity.crawler.vo.CrawlerPolicyPrintVo;
 import com.ydtech.modules.order.entity.dto.DrivingInsuranceDto;
 import com.ydtech.modules.order.entity.dto.ReadPdfUrlListDto;
 import com.ydtech.modules.order.entity.po.InsTaskImagesBase64;
+import com.ydtech.modules.order.entity.po.SysQuoteRecord;
 import com.ydtech.modules.order.entity.vo.BaseQuoteInfoVo;
 import com.ydtech.modules.order.entity.vo.BaseQuoteVo;
 import com.ydtech.modules.order.entity.vo.bohai.BoHaiQuoteAccidentVo;
@@ -82,6 +85,12 @@ public class BoHaiOrderApiServiceImpl implements BoHaiOrderApiService {
     @Value("${api.url}")
     private String apiUrl;
 
+    @Autowired
+    private SysQuoteRecordMapper sysQuoteRecordMapper;
+
+    @Autowired
+    private SysQuoteRedisService sysQuoteRedisService;
+
     @Override
     public HttpResult<List<NonAutomotiveProductsResponse.DataDTO.ProductsDTO>> productQuery(ProductQueryVo productQueryVo) throws Exception {
         // 账号信息
@@ -111,8 +120,119 @@ public class BoHaiOrderApiServiceImpl implements BoHaiOrderApiService {
         return HttpResult.ok(coverages);
     }
 
+    /**
+     * 重复投保 获取新的报价对象
+     * @param response
+     * @return
+     */
+    private QuotationRequest getQuotationRequest(QuotationResponse response,QuotationRequest quotationRequest,String businessPolicyEndDateStr){
+
+        //结束投保日期为开始日期,结束日期为结束投保日期后一年的日期
+        businessPolicyEndDateStr = businessPolicyEndDateStr + "00";
+        String beginDateStr = DateUtil_N.strAllToDateToStr(businessPolicyEndDateStr, "yyyyMMddHHmmss", "yyyy-MM-dd HH:mm:ss");
+        // 结束日期为59:59:59
+        String endDateStr = DateUtil_N.getNextYearDateStrTranfer(businessPolicyEndDateStr);
+        QuotationRequest.BusinessPolicyDTO businessPolicy = quotationRequest.getBusinessPolicy();
+        businessPolicy.setStartDate(beginDateStr);
+        businessPolicy.setEndDate(endDateStr);
+        quotationRequest.setBusinessPolicy(businessPolicy);
+        return quotationRequest;
+    }
+
+    /**
+     * 重复报价
+     * @return
+     */
+    private QuotationResponse repeatQuote(QuotationRequest quotationRequest,String sysSourceCode,BaseQuoteInfoVo quoteInfoVo,String companyId,Integer maxQuoteNum,
+                                          List<SysQuoteRecord> records,QuotationResponse response) throws Exception {
+
+        if(maxQuoteNum <= 0)
+        {
+            return response;
+        }
+        //报价接口调用
+        response = boHaiRequestApiComponent.quotation(quotationRequest, sysSourceCode);
+        maxQuoteNum--;
+
+        //商业险重复投保  重复投保保单信息 :保单号:314042303060007485车牌号:晋A881SR车架号:LMGAC1381K1535834发动机号:F699317保险公司代码:YAIC签单日期:20230414起保日期:202305030000
+        // 终保日期:202405030000险别:机动车第三者责任保险,附加医保外用药责任险(机动车第三者责任保险)
+
+        List<RiskInfoVo> collect =
+                quoteInfoVo.getRiskList().stream().filter(x -> InsuranceRisk.BUSINESS.getCode().equals(x.getRiskCode())).collect(Collectors.toList());
+        //商业险重复投保处理
+        if (!collect.isEmpty()) {
+            if (ResponseCode.R_Z00001.getCode().equals(response.getResponseCode()) && response.getData().getBusinessPolicy().getErrorMsg() != null) {
+                String errorMsg = response.getData().getBusinessPolicy().getErrorMsg();
+                if (errorMsg.contains("重复投保")) {
+                    //重新给商业险的开始和结束时间赋值赋值重新填报
+                    String businessPolicyEndDateStr = StringSubStringUtils.subjectStringContentByBusinessPolicyEndDate(errorMsg, "终保日期:");
+                    if (!StringUtils.isEmpty(businessPolicyEndDateStr) && !StringUtils.isEmpty((businessPolicyEndDateStr))) {
+                        //结束投保日期为开始日期,结束日期为结束投保日期后一年的日期
+                        businessPolicyEndDateStr = businessPolicyEndDateStr + "00";
+                        String beginDateStr = DateUtil_N.strAllToDateToStr(businessPolicyEndDateStr, "yyyyMMddHHmmss", "yyyy-MM-dd HH:mm:ss");
+                        // 结束日期为59:59:59
+                        String endDateStr = DateUtil_N.getNextYearDateStrTranfer(businessPolicyEndDateStr);
+                        QuotationRequest.BusinessPolicyDTO businessPolicy = quotationRequest.getBusinessPolicy();
+                        businessPolicy.setStartDate(beginDateStr);
+                        businessPolicy.setEndDate(endDateStr);
+                        quotationRequest.setBusinessPolicy(businessPolicy);
+                        SysQuoteRecord sysQuoteRecord = new SysQuoteRecord(quoteInfoVo.getUserid(),companyId,quoteInfoVo.getCarInfo().getLicenseNo(),
+                                QuoteNumberConstant.QuoteAction.DATE_DEAL.getCode().toString(),QuoteNumberConstant.QuoteResult.FAIL.getCode().toString());
+                        records.add(sysQuoteRecord);
+                        response = repeatQuote(quotationRequest, sysSourceCode, quoteInfoVo, companyId, maxQuoteNum, records,response);
+                    }
+                }
+            }
+        }
+
+        //add by  2024-04-03  会发生重复投保   算费微服务返回报错信息_保信返回错误信息:
+        // 平台返回错误信息号牌号码“晋J60L55”的保单发生重复投保,与其重复投保的其它公司的保单信息如下:投保确认码 02PAIC140023031919549498257741;保单号 13312993901973801278;起保日期
+        // 2023-04-11 00:00;终保日期 2024-04-11 00:00;号牌号码 晋J60L55;号牌种类 02;车架号 LZWADAGA5LG477030;发动机号 8LB1921291;地区 山西。
+        //重新赋值交强的投保开始日期
+        if (ResponseCode.R_Z00004.getCode().equals(response.getResponseCode())) {
+            String responseMsg = response.getResponseMsg();
+            if (responseMsg.contains("发生重复投保")) {
+                //交强重复投保
+                String trafficPolicyDTOBenginDateStr = StringSubStringUtils.subjectStringContentByTrafficPolicyDTOBenginDate(responseMsg,
+                        ":", "起保日期");
+                String trafficPolicyDTOEndDateStr = StringSubStringUtils.subjectStringContentByTrafficPolicyDTOBenginDate(responseMsg,
+                        ":", "终保日期");
+                if (!StringUtils.isEmpty(trafficPolicyDTOBenginDateStr) && !StringUtils.isEmpty(trafficPolicyDTOEndDateStr)) {
+                    //结束投保日期为开始日期,结束日期为结束投保日期后一年的日期
+                    trafficPolicyDTOEndDateStr = trafficPolicyDTOEndDateStr + ":00";
+                    // 结束日期为59:59:59
+                    String endDateStr = DateUtil_N.getNextYearDateStr(trafficPolicyDTOEndDateStr);
+                    QuotationRequest.TrafficPolicyDTO trafficPolicy = quotationRequest.getTrafficPolicy();
+                    trafficPolicy.setStartDate(trafficPolicyDTOEndDateStr);
+                    trafficPolicy.setEndDate(endDateStr);
+                    quotationRequest.setTrafficPolicy(trafficPolicy);
+                    SysQuoteRecord sysQuoteRecord = new SysQuoteRecord(quoteInfoVo.getUserid(),companyId,quoteInfoVo.getCarInfo().getLicenseNo(),
+                            QuoteNumberConstant.QuoteAction.DATE_DEAL.getCode().toString(),QuoteNumberConstant.QuoteResult.FAIL.getCode().toString());
+                    records.add(sysQuoteRecord);
+                    response = repeatQuote(quotationRequest, sysSourceCode, quoteInfoVo, companyId, maxQuoteNum, records,response);
+                }
+            }
+        }
+        SysQuoteRecord sysQuoteRecord = null;
+        if(!ResponseCode.R_Z00001.getCode().equals(response.getResponseCode())) {
+            sysQuoteRecord = new SysQuoteRecord(quoteInfoVo.getUserid(),companyId,quoteInfoVo.getCarInfo().getLicenseNo(),
+                    QuoteNumberConstant.QuoteAction.QUOTE_FAILED.getCode().toString(),QuoteNumberConstant.QuoteResult.FAIL.getCode().toString());
+
+        }else{
+            sysQuoteRecord = new SysQuoteRecord(quoteInfoVo.getUserid(),companyId,quoteInfoVo.getCarInfo().getLicenseNo(),
+                    QuoteNumberConstant.QuoteAction.QUOTE_SUCCESS.getCode().toString(),QuoteNumberConstant.QuoteResult.SUCCESS.getCode().toString());
+        }
+        records.add(sysQuoteRecord);
+        return response;
+
+    }
+
     @Override
     public HttpResult<QuoteRespVo> quote(BaseQuoteInfoVo quoteInfoVo, BaseQuoteVo<List<BoHaiQuoteAccidentVo>> quoteVo) throws Exception {
+        //获取最大报价次数
+        Integer maxQuoteNum = quoteVo.getMaxQuoteNum();
+        List<SysQuoteRecord> quoteRecords = new ArrayList<>();
+
         // 协议id获取配置实体
         String agreementId = quoteVo.getAgreementId();
         // 账号信息
@@ -160,68 +280,44 @@ public class BoHaiOrderApiServiceImpl implements BoHaiOrderApiService {
 
         QuotationRequest quotationRequest = new QuotationRequest(parameters, quoteInfoVo.getRiskList(), quoteInfoVo.getKindList(),
                 currentValue, orderNo, carInfo, quoteVo.getAccidentalDrivingVo(), discount);
-        QuotationResponse response = boHaiRequestApiComponent.quotation(quotationRequest, parameters.getSysSourceCode());
-        //商业险重复投保  重复投保保单信息 :保单号:314042303060007485车牌号:晋A881SR车架号:LMGAC1381K1535834发动机号:F699317保险公司代码:YAIC签单日期:20230414起保日期:202305030000
-        // 终保日期:202405030000险别:机动车第三者责任保险,附加医保外用药责任险(机动车第三者责任保险)
 
-        List<RiskInfoVo> collect =
-                quoteInfoVo.getRiskList().stream().filter(x -> InsuranceRisk.BUSINESS.getCode().equals(x.getRiskCode())).collect(Collectors.toList());
+        //报价接口调用
+        QuotationResponse quotationResponse = repeatQuote(quotationRequest, parameters.getSysSourceCode(), quoteInfoVo, quoteVo.getCompanyId(),
+                maxQuoteNum,quoteRecords,null);
 
-        if (!collect.isEmpty()) {
-            response = getQuotationResponse(response, quotationRequest, parameters.getSysSourceCode());
-        }
 
-        //response = getQuotationResponseNew(quoteInfoVo, quoteVo, parameters, orderNo, carInfo, currentValue, response);
-        //add by  2024-04-03  会发生重复投保   算费微服务返回报错信息_保信返回错误信息:
-        // 平台返回错误信息号牌号码“晋J60L55”的保单发生重复投保,与其重复投保的其它公司的保单信息如下:投保确认码 02PAIC140023031919549498257741;保单号 13312993901973801278;起保日期
-        // 2023-04-11 00:00;终保日期 2024-04-11 00:00;号牌号码 晋J60L55;号牌种类 02;车架号 LZWADAGA5LG477030;发动机号 8LB1921291;地区 山西。
-        //重新赋值交强的投保开始日期
-        if (ResponseCode.R_Z00004.getCode().equals(response.getResponseCode())) {
-            String responseMsg = response.getResponseMsg();
-            if (responseMsg.contains("发生重复投保")) {
-                //交强重复投保
-                String trafficPolicyDTOBenginDateStr = StringSubStringUtils.subjectStringContentByTrafficPolicyDTOBenginDate(responseMsg,
-                        ":", "起保日期");
-                String trafficPolicyDTOEndDateStr = StringSubStringUtils.subjectStringContentByTrafficPolicyDTOBenginDate(responseMsg,
-                        ":", "终保日期");
-                if (!StringUtils.isEmpty(trafficPolicyDTOBenginDateStr) && !StringUtils.isEmpty(trafficPolicyDTOEndDateStr)) {
-                    //结束投保日期为开始日期,结束日期为结束投保日期后一年的日期
-                    trafficPolicyDTOEndDateStr = trafficPolicyDTOEndDateStr + ":00";
-                    // 结束日期为59:59:59
-                    String endDateStr = DateUtil_N.getNextYearDateStr(trafficPolicyDTOEndDateStr);
-                    QuotationRequest.TrafficPolicyDTO trafficPolicy = quotationRequest.getTrafficPolicy();
-                    trafficPolicy.setStartDate(trafficPolicyDTOEndDateStr);
-                    trafficPolicy.setEndDate(endDateStr);
-                    quotationRequest.setTrafficPolicy(trafficPolicy);
-                    response = boHaiRequestApiComponent.quotation(quotationRequest, parameters.getSysSourceCode());
-                    // 判断是否商业险重复投保
-                    if (!collect.isEmpty()) {
-                        response = getQuotationResponse(response, quotationRequest, parameters.getSysSourceCode());
-                    }
-                    if (!ResponseCode.R_Z00001.getCode().equals(response.getResponseCode())) {
-                        throw new SystemException(response.getResponseMsg());
-                    }
-                } else {
-                    InsOrderStatusEnum insOrderStatusEnum = InsOrderStatusEnum.QUOTE_FAILED;
-                    InsOrders byId = insOrdersService.getById(quoteVo.getOrderNo());
-                    if(responseMsg.contains("重复投保")){
-                        insOrderStatusEnum = InsOrderStatusEnum.REPEAT_INSURE;
-                    }
-                    insOrdersService.responseFailedOrder(quoteVo,ptlAgreementAttribution,byId,responseMsg,insOrderStatusEnum);
-                    throw new SystemException(responseMsg);
-                }
-                // add by hxl  2024-04-07  报价接口报错  算费微服务返回报错信息_保信返回错误信息:录入的校验码有误
-                // 需要调用 获取交管查询校验码接口   传入到报价参数中  暂未复现不处理 注释掉
-            } else if (responseMsg.contains("录入的校验码有误")) {
-                //response = getQuotationResponseNew(quoteInfoVo, quoteVo, parameters, orderNo, carInfo, currentValue, response);
-            } else {
-                throw new SystemException(responseMsg);
+        //处理报价失败
+        if(!ResponseCode.R_Z00001.getCode().equals(quotationResponse.getResponseCode())) {
+            InsOrderStatusEnum insOrderStatusEnum = InsOrderStatusEnum.QUOTE_FAILED;
+            InsOrders byId = insOrdersService.getById(quoteInfoVo.getOrderNo());
+            String responseMsg = quotationResponse.getResponseMsg();
+            if(responseMsg.contains("重复投保")){
+                insOrderStatusEnum = InsOrderStatusEnum.REPEAT_INSURE;
             }
+            String subOrderNo = insOrdersService.responseFailedOrder(quoteVo, ptlAgreementAttribution, byId, responseMsg, insOrderStatusEnum);
+
+            //存储报价记录
+            quoteRecords.forEach(item->{
+                item.setSubOrderNo(subOrderNo);
+            });
+            sysQuoteRecordMapper.insertBatch(quoteRecords);
+            //刷新redis中的报价次数
+            sysQuoteRedisService.refreshQuoteNum(quoteVo.getCompanyId(),quoteInfoVo.getUserid(),quoteRecords);
+            throw new SystemException(responseMsg);
         }
+
         List<BoHaiQuoteAccidentVo> accidentalDrivingVo = Optional.ofNullable(quoteVo.getAccidentalDrivingVo()).orElse(new ArrayList<>());
-//        InsAreaCompanyAccidentalDriving insAreaCompanyAccidentalDriving = new InsAreaCompanyAccidentalDriving();
-//        insAreaCompanyAccidentalDriving.setQuantity(quoteVo.getAccidentalDrivingVo());
-        return getQuoteRespVo(response, quoteInfoVo, vehicleModelsDTO, ptlAgreementAttribution, orderNo, accidentalDrivingVo);
+
+
+        HttpResult<QuoteRespVo> quoteRespVo = getQuoteRespVo(quotationResponse, quoteInfoVo, vehicleModelsDTO, ptlAgreementAttribution, orderNo, accidentalDrivingVo);
+        //存储报价记录
+        quoteRecords.forEach(item->{
+            item.setSubOrderNo(quoteRespVo.getData().getCompanyId());
+        });
+        sysQuoteRecordMapper.insertBatch(quoteRecords);
+        //刷新redis中的报价次数
+        sysQuoteRedisService.refreshQuoteNum(quoteVo.getCompanyId(),quoteInfoVo.getUserid(),quoteRecords);
+        return quoteRespVo;
     }
 
     /**
@@ -260,13 +356,17 @@ public class BoHaiOrderApiServiceImpl implements BoHaiOrderApiService {
      * @Date: 2024/4/7 16:07
      * @Description:
      */
-    private QuotationResponse getQuotationResponse(QuotationResponse response, QuotationRequest quotationRequest, String sysSourCode) throws Exception {
+    private QuotationResponse getQuotationResponse(QuotationResponse response, QuotationRequest quotationRequest, String sysSourCode,
+                                                   List<SysQuoteRecord> records,Integer maxQuoteNum) throws Exception {
         if (ResponseCode.R_Z00001.getCode().equals(response.getResponseCode()) && response.getData().getBusinessPolicy().getErrorMsg() != null) {
             String errorMsg = response.getData().getBusinessPolicy().getErrorMsg();
             if (errorMsg.contains("重复投保")) {
                 //重新给商业险的开始和结束时间赋值赋值重新填报
                 String businessPolicyEndDateStr = StringSubStringUtils.subjectStringContentByBusinessPolicyEndDate(errorMsg, "终保日期:");
                 if (!StringUtils.isEmpty(businessPolicyEndDateStr) && !StringUtils.isEmpty((businessPolicyEndDateStr))) {
+                    if(maxQuoteNum <= 0){
+                        return response;
+                    }
                     //结束投保日期为开始日期,结束日期为结束投保日期后一年的日期
                     businessPolicyEndDateStr = businessPolicyEndDateStr + "00";
                     String beginDateStr = DateUtil_N.strAllToDateToStr(businessPolicyEndDateStr, "yyyyMMddHHmmss", "yyyy-MM-dd HH:mm:ss");
@@ -277,6 +377,8 @@ public class BoHaiOrderApiServiceImpl implements BoHaiOrderApiService {
                     businessPolicy.setEndDate(endDateStr);
                     quotationRequest.setBusinessPolicy(businessPolicy);
                     response = boHaiRequestApiComponent.quotation(quotationRequest, sysSourCode);
+                    SysQuoteRecord record = new SysQuoteRecord();
+                    records.add(record);
                     if (!ResponseCode.R_Z00001.getCode().equals(response.getResponseCode())) {
                         throw new SystemException(response.getResponseMsg());
                     }

+ 49 - 4
src/main/java/com/ydtech/modules/order/service/impl/ChengTaiOrderApiServiceImpl.java

@@ -20,8 +20,10 @@ import com.ydtech.modules.order.components.ConfigureParametersComponents;
 import com.ydtech.modules.order.components.InsImagesUploadCacheComponents;
 import com.ydtech.modules.order.components.VerificationCodeIdentification;
 import com.ydtech.modules.order.components.chengtai.ChengTaiRequestApiComponents;
+import com.ydtech.modules.order.constants.QuoteNumberConstant;
 import com.ydtech.modules.order.components.gouren.GuorenDuplicateInsuranceComponent;
 import com.ydtech.modules.order.constants.UnderwritingStatus;
+import com.ydtech.modules.order.dao.SysQuoteRecordMapper;
 import com.ydtech.modules.order.entity.*;
 import com.ydtech.modules.order.entity.api.chengtai.constants.CtKindCodeEnum;
 import com.ydtech.modules.order.entity.api.chengtai.constants.OrderStatusEnum;
@@ -36,6 +38,7 @@ import com.ydtech.modules.order.entity.crawler.response.RecognitionResponse;
 import com.ydtech.modules.order.entity.dto.ReadPdfUrlListDto;
 import com.ydtech.modules.order.entity.filter.CarModelsFilterUtils;
 import com.ydtech.modules.order.entity.po.InsTaskImagesBase64;
+import com.ydtech.modules.order.entity.po.SysQuoteRecord;
 import com.ydtech.modules.order.entity.vo.BaseQuoteInfoVo;
 import com.ydtech.modules.order.entity.vo.BaseQuoteVo;
 import com.ydtech.modules.order.entity.vo.PolicyPrintVo;
@@ -90,6 +93,12 @@ public class ChengTaiOrderApiServiceImpl implements ChengTaiOrderApiService {
     @Autowired
     private InsSubOrderUpdateDetailService insSubOrderUpdateDetailService;
 
+    @Autowired
+    private SysQuoteRecordMapper sysQuoteRecordMapper;
+
+    @Autowired
+    private SysQuoteRedisService sysQuoteRedisService;
+
     @Value("${upload.file.path}")
     private String uploadFilePath;
 
@@ -101,6 +110,10 @@ public class ChengTaiOrderApiServiceImpl implements ChengTaiOrderApiService {
 
     @Override
     public HttpResult<QuoteRespVo> quoteApi(BaseQuoteInfoVo quoteInfoVo, BaseQuoteVo<InsDrivingIntentionInsurance> quoteVo) throws Exception {
+        Integer maxQuoteNum = quoteVo.getMaxQuoteNum();
+
+        List<SysQuoteRecord> sysQuoteRecords = new ArrayList<>();
+
         /** 1. 协议id获取配置实体 */
         String agreementId = quoteVo.getAgreementId();
         // 1.1 账号信息
@@ -123,7 +136,7 @@ public class ChengTaiOrderApiServiceImpl implements ChengTaiOrderApiService {
         /** 4. 报价 */
         InsurePremiumRequest insurePremiumRequest = new InsurePremiumRequest(quoteInfoVo,carModelListDTO, carActualValueResponse,parameters,quoteVo);
         // 重复报价
-        InsurePremiumResponse insurePremiumResponse = this.getResponse(insurePremiumRequest, httpHeaders);
+        InsurePremiumResponse insurePremiumResponse = this.getResponse(insurePremiumRequest, httpHeaders,quoteInfoVo, quoteVo.getCompanyId(),maxQuoteNum,sysQuoteRecords);
 
         String message = "";
         if(!ResponseCode.R_000.getCode().equals(insurePremiumResponse.getCode())){
@@ -134,7 +147,18 @@ public class ChengTaiOrderApiServiceImpl implements ChengTaiOrderApiService {
             {
                 insOrderStatusEnum = InsOrderStatusEnum.REPEAT_INSURE;
             }
-            insOrdersService.responseFailedOrder(quoteVo,ptlAgreementAttribution, order,insurePremiumResponse.getMessage(),insOrderStatusEnum);
+            String subOrderNo = insOrdersService.responseFailedOrder(quoteVo, ptlAgreementAttribution, order, insurePremiumResponse.getMessage(), insOrderStatusEnum);
+            SysQuoteRecord sysQuoteRecord = new SysQuoteRecord(quoteInfoVo.getUserid(),quoteVo.getCompanyId(),quoteInfoVo.getCarInfo().getLicenseNo(),
+                    QuoteNumberConstant.QuoteAction.QUOTE_FAILED.getCode().toString(),QuoteNumberConstant.QuoteResult.FAIL.getCode().toString());
+            sysQuoteRecords.add(sysQuoteRecord);
+            //存储报价记录
+            sysQuoteRecords.forEach(item->{
+                item.setSubOrderNo(subOrderNo);
+            });
+
+            sysQuoteRecordMapper.insertBatch(sysQuoteRecords);
+            //刷新redis中的报价次数
+            sysQuoteRedisService.refreshQuoteNum(quoteVo.getCompanyId(),quoteInfoVo.getUserid(),sysQuoteRecords);
             throw new SystemException(insurePremiumResponse.getMessage());
         }
 
@@ -156,7 +180,19 @@ public class ChengTaiOrderApiServiceImpl implements ChengTaiOrderApiService {
 
         // 设置核心报价车型
         quoteRespVo.setCoreModels(carModelListDTO.toCoreModelsVo());
-        return responseOrder(insurePremiumResponse, quoteRespVo, ptlAgreementAttribution, insurePremiumResponse.getOrderId());
+        HttpResult<QuoteRespVo> quoteRespVoHttpResult = responseOrder(insurePremiumResponse, quoteRespVo, ptlAgreementAttribution, insurePremiumResponse.getOrderId());
+        SysQuoteRecord sysQuoteRecord = new SysQuoteRecord(quoteInfoVo.getUserid(),quoteVo.getCompanyId(),quoteInfoVo.getCarInfo().getLicenseNo(),
+                QuoteNumberConstant.QuoteAction.QUOTE_SUCCESS.getCode().toString(),QuoteNumberConstant.QuoteResult.SUCCESS.getCode().toString());
+        sysQuoteRecords.add(sysQuoteRecord);
+        //存储报价记录
+        sysQuoteRecords.forEach(item->{
+            item.setSubOrderNo(quoteRespVoHttpResult.getData().getCompanyId());
+        });
+        sysQuoteRecordMapper.insertBatch(sysQuoteRecords);
+
+        sysQuoteRedisService.refreshQuoteNum(quoteVo.getCompanyId(),quoteInfoVo.getUserid(),sysQuoteRecords);
+
+        return quoteRespVoHttpResult;
     }
 
     /**
@@ -165,11 +201,20 @@ public class ChengTaiOrderApiServiceImpl implements ChengTaiOrderApiService {
      * @param httpHeaders
      * @return
      */
-    private InsurePremiumResponse getResponse(InsurePremiumRequest insurePremiumRequest, HttpHeaders httpHeaders) throws Exception {
+    private InsurePremiumResponse getResponse(InsurePremiumRequest insurePremiumRequest, HttpHeaders httpHeaders,BaseQuoteInfoVo quoteInfoVo,
+                                              String companyId,Integer maxQuoteNum,List<SysQuoteRecord> sysQuoteRecords) throws Exception {
+
         InsurePremiumResponse insurePremiumResponse = chengTaiRequestApiComponents.quoteApi(insurePremiumRequest,httpHeaders);
+        maxQuoteNum--;
         if(!ResponseCode.R_000.getCode().equals(insurePremiumResponse.getCode()) && insurePremiumResponse.getMessage().contains("重复投保")){
             // 交强险 商业险 重复投保处理
             this.repetitionInsure(insurePremiumResponse,insurePremiumRequest);
+            SysQuoteRecord sysQuoteRecord = new SysQuoteRecord(quoteInfoVo.getUserid(),companyId,quoteInfoVo.getCarInfo().getLicenseNo(),
+                    QuoteNumberConstant.QuoteAction.DATE_DEAL.getCode().toString(),QuoteNumberConstant.QuoteResult.FAIL.getCode().toString());
+            sysQuoteRecords.add(sysQuoteRecord);
+            if(maxQuoteNum <= 0){
+                return insurePremiumResponse;
+            }
             insurePremiumResponse = chengTaiRequestApiComponents.quoteApi(insurePremiumRequest,httpHeaders);
         }
 

+ 53 - 4
src/main/java/com/ydtech/modules/order/service/impl/DaJiaOrderServiceImpl.java

@@ -18,7 +18,9 @@ import com.ydtech.modules.ins.model.vo.*;
 import com.ydtech.modules.order.components.ConfigureParametersComponents;
 import com.ydtech.modules.order.components.InsImagesUploadCacheComponents;
 import com.ydtech.modules.order.components.dajia.DaJiaRequestApiComponents;
+import com.ydtech.modules.order.constants.QuoteNumberConstant;
 import com.ydtech.modules.order.constants.UnderwritingStatus;
+import com.ydtech.modules.order.dao.SysQuoteRecordMapper;
 import com.ydtech.modules.order.entity.*;
 import com.ydtech.modules.order.entity.api.dajia.DaJiaConfigureParameters;
 import com.ydtech.modules.order.entity.api.dajia.constants.CCvrgNo;
@@ -28,6 +30,7 @@ import com.ydtech.modules.order.entity.api.dajia.request.*;
 import com.ydtech.modules.order.entity.api.dajia.response.*;
 import com.ydtech.modules.order.entity.dto.ReadPdfUrlListDto;
 import com.ydtech.modules.order.entity.po.InsTaskImagesBase64;
+import com.ydtech.modules.order.entity.po.SysQuoteRecord;
 import com.ydtech.modules.order.entity.vo.BaseQuoteInfoVo;
 import com.ydtech.modules.order.entity.vo.BaseQuoteVo;
 import com.ydtech.modules.order.entity.vo.CoreModelsVo;
@@ -115,6 +118,12 @@ public class DaJiaOrderServiceImpl implements DaJiaOrderService {
     @Autowired
     private InsSubOrderUpdateDetailService insSubOrderUpdateDetailService;
 
+    @Autowired
+    private SysQuoteRedisService sysQuoteRedisService;
+
+    @Autowired
+    private SysQuoteRecordMapper sysQuoteRecordMapper;
+
     //region 报价
 
     /**
@@ -167,6 +176,10 @@ public class DaJiaOrderServiceImpl implements DaJiaOrderService {
     @Override
     public HttpResult<QuoteRespVo> quote(BaseQuoteInfoVo quoteInfoVo, BaseQuoteVo<Object> t) {
         try {
+            //获取报价次数
+            Integer maxQuoteNum = t.getMaxQuoteNum();
+            List<SysQuoteRecord> sysQuoteRecords = new ArrayList<>();
+
             //获取公司配置信息
             DaJiaConfigureParameters daJiaConfigureParameters = new DaJiaConfigureParameters();
             configureParametersComponents.toEntity(daJiaConfigureParameters, t.getAgreementId());
@@ -237,7 +250,9 @@ public class DaJiaOrderServiceImpl implements DaJiaOrderService {
                 listByAccId = insAccidentalDrivingSubDaJiaService.getListByAccId(accidentalDriving.getId());
             }
             //6.报价
-            ODR1009Response odr1009Response = quotation(orderNo, kindList, riskList, quoteInfoVo, odr1016Response, accidentalDriving, listByAccId, daJiaConfigureParameters, isEnergy);
+            ODR1009Response odr1009Response = quotation(orderNo, kindList, riskList, quoteInfoVo, odr1016Response, accidentalDriving, listByAccId,
+                    daJiaConfigureParameters, isEnergy, t.getCompanyId(), maxQuoteNum, sysQuoteRecords);
+
 
             NVHLODR1001Response nvhlodr1001Response = null;
 
@@ -258,7 +273,18 @@ public class DaJiaOrderServiceImpl implements DaJiaOrderService {
 
                 // 设置报价车型
                 quoteRespVo.setCoreModels(coreModelsVo);
+                SysQuoteRecord sysQuoteRecord = new SysQuoteRecord(quoteInfoVo.getUserid(),t.getCompanyId(),quoteInfoVo.getCarInfo().getLicenseNo(),
+                        QuoteNumberConstant.QuoteAction.QUOTE_SUCCESS.getCode().toString(),QuoteNumberConstant.QuoteResult.SUCCESS.getCode().toString());
+                sysQuoteRecords.add(sysQuoteRecord);
+
                 HttpResult<QuoteRespVo> quoteRespVoHttpResult = responseOrder(odr1009Response, quoteRespVo, ptlAgreementAttribution, orderNo, quoteInfoVo, busiId, nvhlodr1001Response, insAreaCompanyAccidentalDriving);
+
+                sysQuoteRecords.forEach(item->{
+                    sysQuoteRecord.setSubOrderNo(quoteRespVoHttpResult.getData().getCompanyId());
+                });
+                sysQuoteRecordMapper.insertBatch(sysQuoteRecords);
+                //刷新redis中的报价次数
+                sysQuoteRedisService.refreshQuoteNum(t.getCompanyId(),quoteInfoVo.getUserid(),sysQuoteRecords);
                 return quoteRespVoHttpResult;
             } else {
                 String errorMessage = odr1009Response.getResult().getJqAppStatusMessage().toString() + odr1009Response.getResult().getSyAppStatusMessage().toString();
@@ -267,7 +293,7 @@ public class DaJiaOrderServiceImpl implements DaJiaOrderService {
                 if(odr1009Response.getResult().getJqAppStatusMessage().toString().contains("重复投保")) {
                     orderStatusEnum = InsOrderStatusEnum.REPEAT_INSURE;
                 }
-                insOrdersService.responseFailedOrder(t,ptlAgreementAttribution, insOrders, errorMessage, orderStatusEnum);
+                String subOrderNo = insOrdersService.responseFailedOrder(t, ptlAgreementAttribution, insOrders, errorMessage, orderStatusEnum);
 
                 if (Message.M0003.getCode().equals(odr1009Response.getStatus())) {
                     return HttpResult.error("报价失败,原因:" + odr1009Response.getMessage());
@@ -277,6 +303,16 @@ public class DaJiaOrderServiceImpl implements DaJiaOrderService {
                 } else if ("0".equals(odr1009Response.getResult().getSyAppStatus()) && "0002".equals(odr1009Response.getStatus())) {
                     return HttpResult.error("报价失败,原因:" + odr1009Response.getResult().getSyAppStatusMessage());
                 }
+
+                SysQuoteRecord sysQuoteRecord = new SysQuoteRecord(quoteInfoVo.getUserid(),t.getCompanyId(),quoteInfoVo.getCarInfo().getLicenseNo(),
+                        QuoteNumberConstant.QuoteAction.QUOTE_FAILED.getCode().toString(),QuoteNumberConstant.QuoteResult.FAIL.getCode().toString());
+                sysQuoteRecords.add(sysQuoteRecord);
+                sysQuoteRecords.forEach(item->{
+                    sysQuoteRecord.setSubOrderNo(subOrderNo);
+                });
+                sysQuoteRecordMapper.insertBatch(sysQuoteRecords);
+                //刷新redis中的报价次数
+                sysQuoteRedisService.refreshQuoteNum(t.getCompanyId(),quoteInfoVo.getUserid(),sysQuoteRecords);
                 return HttpResult.error("报价失败");
             }
         } catch (Exception e) {
@@ -337,10 +373,14 @@ public class DaJiaOrderServiceImpl implements DaJiaOrderService {
      * @return
      * @throws Exception
      */
-    public ODR1009Response quotation(String orderNo, List<KindInfoVo> kindInfoVos, List<RiskInfoVo> riskInfoVos, BaseQuoteInfoVo quoteInfoVo, ODR1016Response odr1016Response, InsAccidentalDrivingDajia insAccidentalDrivingDajia, List<InsAccidentalDrivingSubDajia> insAccidentalDrivingSubDajias, DaJiaConfigureParameters daJiaConfigureParameters, boolean isEnergy) throws Exception {
+    public ODR1009Response quotation(String orderNo, List<KindInfoVo> kindInfoVos, List<RiskInfoVo> riskInfoVos, BaseQuoteInfoVo quoteInfoVo, ODR1016Response odr1016Response,
+                                     InsAccidentalDrivingDajia insAccidentalDrivingDajia, List<InsAccidentalDrivingSubDajia> insAccidentalDrivingSubDajias,
+                                     DaJiaConfigureParameters daJiaConfigureParameters, boolean isEnergy,String companyId,Integer maxQuoteNum, List<SysQuoteRecord> sysQuoteRecords) throws Exception {
 
         ODR1009Request odr1009Request = new ODR1009Request(orderNo, kindInfoVos, riskInfoVos, quoteInfoVo, odr1016Response, insAccidentalDrivingDajia, insAccidentalDrivingSubDajias, daJiaConfigureParameters, isEnergy);
         ODR1009Response odr1009Response = daJiaRequestApiComponents.newPremiumXnyCalculation(odr1009Request);
+        maxQuoteNum--;
+
         if (odr1009Response.getStatus().equals(Message.M0002.getCode())) {
             //获取重复投保信息
             String jqAppStatusMessage = odr1009Response.getResult().getJqAppStatusMessage() == null ? "" : odr1009Response.getResult().getJqAppStatusMessage().toString();
@@ -362,7 +402,16 @@ public class DaJiaOrderServiceImpl implements DaJiaOrderService {
                         riskInfoVo.setEndDate(duplicateDate.get(1));
                     }
                 }
-                return quotation(orderNo, kindInfoVos, riskInfoVos, quoteInfoVo, odr1016Response, insAccidentalDrivingDajia, insAccidentalDrivingSubDajias, daJiaConfigureParameters, isEnergy);
+
+                SysQuoteRecord sysQuoteRecord = new SysQuoteRecord(quoteInfoVo.getUserid(),companyId,quoteInfoVo.getCarInfo().getLicenseNo(),
+                        QuoteNumberConstant.QuoteAction.DATE_DEAL.getCode().toString(),QuoteNumberConstant.QuoteResult.FAIL.getCode().toString());
+                sysQuoteRecords.add(sysQuoteRecord);
+                if(maxQuoteNum <= 0){
+                    return odr1009Response;
+                }
+
+                return quotation(orderNo, kindInfoVos, riskInfoVos, quoteInfoVo, odr1016Response, insAccidentalDrivingDajia, insAccidentalDrivingSubDajias,
+                        daJiaConfigureParameters, isEnergy, companyId, maxQuoteNum, sysQuoteRecords);
             }
         }
         return odr1009Response;

+ 62 - 12
src/main/java/com/ydtech/modules/order/service/impl/GuorenOrderApiServiceImpl.java

@@ -23,8 +23,10 @@ import com.ydtech.modules.order.components.InsImagesUploadCacheComponents;
 import com.ydtech.modules.order.components.InsOrdersComponents;
 import com.ydtech.modules.order.components.gouren.GuorenDuplicateInsuranceComponent;
 import com.ydtech.modules.order.components.gouren.GuorenRequestApiComponent;
+import com.ydtech.modules.order.constants.QuoteNumberConstant;
 import com.ydtech.modules.order.constants.UnderwritingStatus;
 import com.ydtech.modules.order.dao.InsTaskImagesMapper;
+import com.ydtech.modules.order.dao.SysQuoteRecordMapper;
 import com.ydtech.modules.order.entity.InsAreaCompany;
 import com.ydtech.modules.order.entity.InsAreaCompanyAccidentalDriving;
 import com.ydtech.modules.order.entity.InsAreaCompanyExternalPolicy;
@@ -42,13 +44,11 @@ import com.ydtech.modules.order.entity.api.guoren.response.SignatureResponse;
 import com.ydtech.modules.order.entity.api.guoren.response.SpecialAgreementResponse;
 import com.ydtech.modules.order.entity.dto.InsUploadImagesDto;
 import com.ydtech.modules.order.entity.dto.ReadPdfUrlListDto;
+import com.ydtech.modules.order.entity.po.SysQuoteRecord;
 import com.ydtech.modules.order.entity.vo.BaseQuoteInfoVo;
 import com.ydtech.modules.order.entity.vo.PolicyPrintVo;
 import com.ydtech.modules.order.entity.vo.guoren.*;
-import com.ydtech.modules.order.service.GuorenOrderApiService;
-import com.ydtech.modules.order.service.InsAreaCompanyService;
-import com.ydtech.modules.order.service.InsOrdersService;
-import com.ydtech.modules.order.service.InsSubOrderUpdateDetailService;
+import com.ydtech.modules.order.service.*;
 import com.ydtech.modules.protocol.entity.po.PtlAgreementAttribution;
 import com.ydtech.modules.protocol.service.PtlAgreementAttributionService;
 import com.ydtech.modules.protocol.utils.AssertionUtils;
@@ -126,6 +126,12 @@ public class GuorenOrderApiServiceImpl implements GuorenOrderApiService {
     @Autowired
     private InsSubOrderUpdateDetailService insSubOrderUpdateDetailService;
 
+    @Autowired
+    private SysQuoteRecordMapper sysQuoteRecordMapper;
+
+    @Autowired
+    private SysQuoteRedisService sysQuoteRedisService;
+
     /**
      * 获取渠道信息
      *
@@ -234,6 +240,9 @@ public class GuorenOrderApiServiceImpl implements GuorenOrderApiService {
     @Override
     public HttpResult quoteApi(GuoRenQuoteVo<GuorenAccidentalDrivingVo> quoteVo) {
         log.debug("--------报价开始,订单号:{},协议号:{}--------------", quoteVo.getOrderNo(), quoteVo.getAgreementId());
+
+        Integer maxQuoteNum = quoteVo.getMaxQuoteNum();
+        List<SysQuoteRecord> sysQuoteRecords = new ArrayList<>();
         // 获取协议配置信息
         ChannelInfoDto channelInfo = gainChannelConfigInfo(quoteVo.getAgreementId());
         BaseQuoteInfoVo yaQuoteInfoVo = insOrdersComponents.getQuoteInfo(quoteVo.getOrderNo(), quoteVo.getKinds());
@@ -275,7 +284,7 @@ public class GuorenOrderApiServiceImpl implements GuorenOrderApiService {
         List<GuoRenSpecialAgreementVo> specialAgreementVo = quoteVo.getGuoRenSpecialAgreementVo();
         // 4、保费计算
         PremiumResp resp = premiumQuery(yaQuoteInfoVo, carPriceResult, vinQ, isNoCar,
-                specialAgreementVo, noCarPremium, goodsCode);
+                specialAgreementVo, noCarPremium, goodsCode, quoteVo.getCompanyId(), maxQuoteNum, sysQuoteRecords);
 
         if (resp.getResultCode() == 1) {
             InsOrderStatusEnum insOrderStatusEnum = InsOrderStatusEnum.QUOTE_FAILED;
@@ -284,7 +293,16 @@ public class GuorenOrderApiServiceImpl implements GuorenOrderApiService {
                 insOrderStatusEnum = InsOrderStatusEnum.REPEAT_INSURE;
             }
             PtlAgreementAttribution ptlAgreementAttribution = ptlAgreementAttributionService.getById(quoteVo.getAgreementId());
-            insOrdersService.responseFailedOrder(quoteVo,ptlAgreementAttribution, order,resp.getResultMsg(),insOrderStatusEnum);
+            String subOrderNo = insOrdersService.responseFailedOrder(quoteVo, ptlAgreementAttribution, order, resp.getResultMsg(), insOrderStatusEnum);
+            SysQuoteRecord sysQuoteRecord = new SysQuoteRecord(yaQuoteInfoVo.getUserid(),quoteVo.getCompanyId(),yaQuoteInfoVo.getCarInfo().getLicenseNo(),
+                    QuoteNumberConstant.QuoteAction.QUOTE_FAILED.getCode().toString(),QuoteNumberConstant.QuoteResult.FAIL.getCode().toString());
+            sysQuoteRecords.add(sysQuoteRecord);
+            sysQuoteRecords.forEach(item->{
+                item.setSubOrderNo(subOrderNo);
+            });
+            sysQuoteRecordMapper.insertBatch(sysQuoteRecords);
+            //刷新redis中的报价次数
+            sysQuoteRedisService.refreshQuoteNum(quoteVo.getCompanyId(),yaQuoteInfoVo.getUserid(),sysQuoteRecords);
             throw new SystemException(resp.getResultMsg() == null ? "保费计算失败,请联系管理员" : resp.getResultMsg());
         }
 
@@ -325,6 +343,15 @@ public class GuorenOrderApiServiceImpl implements GuorenOrderApiService {
         //这里调用费用匹配功能
 //        feeRuleSchemeService.dealFeeOrderInfo(yaQuoteInfoVo, quoteRespVo, quoteVo.getAgreementId(), iac.getId());
 
+        SysQuoteRecord sysQuoteRecord = new SysQuoteRecord(yaQuoteInfoVo.getUserid(),quoteVo.getCompanyId(),yaQuoteInfoVo.getCarInfo().getLicenseNo(),
+                QuoteNumberConstant.QuoteAction.QUOTE_SUCCESS.getCode().toString(),QuoteNumberConstant.QuoteResult.SUCCESS.getCode().toString());
+        sysQuoteRecords.add(sysQuoteRecord);
+        sysQuoteRecords.forEach(item->{
+            item.setSubOrderNo(iac.getId());
+        });
+        sysQuoteRecordMapper.insertBatch(sysQuoteRecords);
+        //刷新redis中的报价次数
+        sysQuoteRedisService.refreshQuoteNum(quoteVo.getCompanyId(),quoteVo.getUserId(),sysQuoteRecords);
         log.debug("--------报价结束,车牌:{},vin:{}--------------", carInfo.getLicenseNo(), carInfo.getVinNo());
         return HttpResult.ok("报价成功", quoteRespVo);
 
@@ -1081,12 +1108,15 @@ public class GuorenOrderApiServiceImpl implements GuorenOrderApiService {
      * 保费计算
      */
     public PremiumResp premiumQuery(BaseQuoteInfoVo yaQuoteInfoVo,
-                                            CarPriceResp.DataDTO carPriceResult,
-                                            VinQueryResp.DataDTO vinQ,
-                                            boolean isNoCar,
-                                            List<GuoRenSpecialAgreementVo> specialAgreementVo,
-                                            String noCarPremium,
-                                            String goodsCode) {
+                                    CarPriceResp.DataDTO carPriceResult,
+                                    VinQueryResp.DataDTO vinQ,
+                                    boolean isNoCar,
+                                    List<GuoRenSpecialAgreementVo> specialAgreementVo,
+                                    String noCarPremium,
+                                    String goodsCode,
+                                    String companyId,
+                                    Integer maxQuoteNum,
+                                    List<SysQuoteRecord> sysQuoteRecords) {
 
         //请求信息列表
         List<String> requestInfoList = new ArrayList<>();
@@ -1097,23 +1127,43 @@ public class GuorenOrderApiServiceImpl implements GuorenOrderApiService {
         int a = 0;
         for (; ; ) {
             resp = guorenRequestApiComponent.request(req, PlatformInterfaceCode.API_IIRBT00004, PremiumResp.class);
+            maxQuoteNum--;
+
             req.getCi().getPrpTmain().setAnswer(null);
             req.getBi().getPrpTmain().setAnswer(null);
             //1、 交强险重复投保 替换时间
             boo = GuorenDuplicateInsuranceComponent.processor(resp, requestInfoList, req);
             if (boo) {
                 a++;
+                SysQuoteRecord sysQuoteRecord = new SysQuoteRecord(yaQuoteInfoVo.getUserid(),companyId,yaQuoteInfoVo.getCarInfo().getLicenseNo(),
+                        QuoteNumberConstant.QuoteAction.DATE_DEAL.getCode().toString(),QuoteNumberConstant.QuoteResult.FAIL.getCode().toString());
+                sysQuoteRecords.add(sysQuoteRecord);
+                if(maxQuoteNum <= 0){
+                    return resp;
+                }
                 continue;
             }
 
             boo = GuorenDuplicateInsuranceComponent.theCheckCodeIsWrong(resp);
             if (boo) {
                 a++;
+                SysQuoteRecord sysQuoteRecord = new SysQuoteRecord(yaQuoteInfoVo.getUserid(),companyId,yaQuoteInfoVo.getCarInfo().getLicenseNo(),
+                        QuoteNumberConstant.QuoteAction.DATE_DEAL.getCode().toString(),QuoteNumberConstant.QuoteResult.FAIL.getCode().toString());
+                sysQuoteRecords.add(sysQuoteRecord);
+                if(maxQuoteNum <= 0){
+                    return resp;
+                }
                 continue;
             }
             //2、 转保
             boo = GuorenDuplicateInsuranceComponent.buildCheckCodeParam(resp, requestInfoList, req);
             if (boo) {
+                SysQuoteRecord sysQuoteRecord = new SysQuoteRecord(yaQuoteInfoVo.getUserid(),companyId,yaQuoteInfoVo.getCarInfo().getLicenseNo(),
+                        QuoteNumberConstant.QuoteAction.TRANSFER_INSRUANCE.getCode().toString(),QuoteNumberConstant.QuoteResult.FAIL.getCode().toString());
+                sysQuoteRecords.add(sysQuoteRecord);
+                if(maxQuoteNum <= 0){
+                    return resp;
+                }
                 continue;
             }
 

+ 35 - 1
src/main/java/com/ydtech/modules/order/service/impl/HuaTaiOrderApiServiceImpl.java

@@ -17,7 +17,9 @@ import com.ydtech.modules.order.components.huatai.HuaTaiQuotationProcessorCompon
 import com.ydtech.modules.order.components.huatai.HuaTaiRequestApiComponents;
 import com.ydtech.modules.order.components.huatai.HuiTaiUploadImageComponents;
 import com.ydtech.modules.order.constants.InsuranceTypeCorrespondence;
+import com.ydtech.modules.order.constants.QuoteNumberConstant;
 import com.ydtech.modules.order.constants.UnderwritingStatus;
+import com.ydtech.modules.order.dao.SysQuoteRecordMapper;
 import com.ydtech.modules.order.entity.InsAreaCompany;
 import com.ydtech.modules.order.entity.InsAreaCompanyExternalPolicy;
 import com.ydtech.modules.order.entity.InsOrders;
@@ -33,6 +35,7 @@ import com.ydtech.modules.order.entity.dto.InsUploadImagesDto;
 import com.ydtech.modules.order.entity.dto.ReadPdfUrlListDto;
 import com.ydtech.modules.order.entity.filter.CarModelsFilterUtils;
 import com.ydtech.modules.order.entity.po.InsHuataiContributing;
+import com.ydtech.modules.order.entity.po.SysQuoteRecord;
 import com.ydtech.modules.order.entity.vo.*;
 import com.ydtech.modules.order.entity.vo.huatai.InsHuataiContributingVo;
 import com.ydtech.modules.order.service.*;
@@ -97,9 +100,18 @@ public class HuaTaiOrderApiServiceImpl implements HuaTaiOrderApiService {
     @Autowired
     private InsSubOrderUpdateDetailService insSubOrderUpdateDetailService;
 
+    @Autowired
+    private SysQuoteRecordMapper sysQuoteRecordMapper;
+
+    @Autowired
+    private SysQuoteRedisService sysQuoteRedisService;
 
     @Override
     public HttpResult<QuoteRespVo> quote(BaseQuoteInfoVo quoteInfo, BaseQuoteVo<AccidentalDrivingVo> zmQuoteVo) {
+        Integer maxQuoteNum = zmQuoteVo.getMaxQuoteNum();
+
+        List<SysQuoteRecord> sysQuoteRecords = new ArrayList<>();
+
         // 1. 协议id获取配置实体
         String agreementId = zmQuoteVo.getAgreementId();
         // 账号信息
@@ -146,10 +158,23 @@ public class HuaTaiOrderApiServiceImpl implements HuaTaiOrderApiService {
 
         // 3.1 处理报价请求
         List<String> warnMessageList = new ArrayList<>();
-        HuaTaiQuotedPriceResponse quotedPriceResponse = huaTaiQuotationProcessorComponent.handler(quotedPriceRequest, warnMessageList, huaTaiConfigureParameters.getInsuredCode());
+        HuaTaiQuotedPriceResponse quotedPriceResponse = huaTaiQuotationProcessorComponent.handler(quoteInfo, quotedPriceRequest, warnMessageList,
+                huaTaiConfigureParameters.getInsuredCode(), zmQuoteVo.getCompanyId() ,maxQuoteNum,sysQuoteRecords);
 
         if (!"0".equals(quotedPriceResponse.getHead().getReturnCode())) {
             log.error(quotedPriceResponse.getHead().getReturnMessage());
+            InsOrders order = insOrdersService.getById(quoteInfo.getOrderNo());
+            String subOrderNo = insOrdersService.responseFailedOrder(zmQuoteVo,ptlAgreementAttribution, order,quotedPriceResponse.getHead().getReturnMessage(),InsOrderStatusEnum.QUOTE_FAILED);
+            SysQuoteRecord sysQuoteRecord = new SysQuoteRecord(quoteInfo.getUserid(),zmQuoteVo.getCompanyId() ,quoteInfo.getCarInfo().getLicenseNo(),
+                    QuoteNumberConstant.QuoteAction.QUOTE_FAILED.getCode().toString(),QuoteNumberConstant.QuoteResult.FAIL.getCode().toString());
+            sysQuoteRecords.add(sysQuoteRecord);
+            sysQuoteRecords.forEach(item->{
+                item.setSubOrderNo(subOrderNo);
+            });
+            sysQuoteRecordMapper.insertBatch(sysQuoteRecords);
+
+            sysQuoteRedisService.refreshQuoteNum(zmQuoteVo.getCompanyId(),quoteInfo.getUserid(),sysQuoteRecords);
+
             throw new SystemException("该车两率管控不建议承保");
         }
 
@@ -157,6 +182,15 @@ public class HuaTaiOrderApiServiceImpl implements HuaTaiOrderApiService {
         // 核心返回车型
         quoteRespVo.setCoreModels(fullCarDataDto.toCoreModelsVo());
 
+        SysQuoteRecord sysQuoteRecord = new SysQuoteRecord(quoteInfo.getUserid(),zmQuoteVo.getCompanyId() ,quoteInfo.getCarInfo().getLicenseNo(),
+                QuoteNumberConstant.QuoteAction.QUOTE_SUCCESS.getCode().toString(),QuoteNumberConstant.QuoteResult.SUCCESS.getCode().toString());
+        sysQuoteRecords.add(sysQuoteRecord);
+        sysQuoteRecords.forEach(item->{
+            item.setSubOrderNo(quoteRespVo.getCompanyId());
+        });
+        sysQuoteRecordMapper.insertBatch(sysQuoteRecords);
+        //刷新redis中的报价次数
+        sysQuoteRedisService.refreshQuoteNum(zmQuoteVo.getCompanyId(),quoteInfo.getUserid(),sysQuoteRecords);
         return responseOrder(quotedPriceResponse, quoteRespVo, ptlAgreementAttribution, quoteInfo);
     }
 

+ 28 - 1
src/main/java/com/ydtech/modules/order/service/impl/InsAreaCompanyServiceImpl.java

@@ -168,7 +168,7 @@ public class InsAreaCompanyServiceImpl extends ServiceImpl<InsAreaCompanyMapper,
     }
 
     @Override
-    public void insertCompanyAndOrders(InsAreaCompany insAreaCompany, InsAreaCompanyAccidentalDriving insAreaCompanyAccidentalDriving) {
+    public String insertCompanyAndOrders(InsAreaCompany insAreaCompany, InsAreaCompanyAccidentalDriving insAreaCompanyAccidentalDriving) {
         //add by hxl   解决部分数据更新不了险种信息
         insAreaCompany = updateEntityPruductAndPruductid(insAreaCompany);
 
@@ -176,8 +176,34 @@ public class InsAreaCompanyServiceImpl extends ServiceImpl<InsAreaCompanyMapper,
         //更新主订单的投保时间
         insOrdersService.updateOrderStartingInsruanceTime(insAreaCompany.getOrderno(), insAreaCompany.getJqStartDate(), insAreaCompany.getJqEndDate(),
                 insAreaCompany.getSyStartDate(), insAreaCompany.getSyEndDate(), insAreaCompany);
+        String subOrderNo = IdGenerate.nextId();
+        insAreaCompany.setId(subOrderNo);
+        baseMapper.insert(insAreaCompany);
+        //保存驾意险信息
+
+        final InsAreaCompany finalInsAreaCompany = insAreaCompany;
+        Optional.ofNullable(insAreaCompanyAccidentalDriving)
+                .filter(x -> StringUtils.isNotEmpty(x.getRideRiskName()) && !ObjectUtils.isEmpty(x.getQuantity()))
+                .ifPresent(x -> {
+                    x.setCompanyId(finalInsAreaCompany.getId());
+                    x.setId(IdGenerate.nextId());
+                    insAreaCompanyAccidentalDrivingService.save(insAreaCompanyAccidentalDriving);
+                });
+
+        insOrdersTrackService.addingTrajectories(insAreaCompany);
+        insOrdersService.updateByOrderStatus(insAreaCompany);
+        return subOrderNo;
+    }
+
+    @Override
+    public String insertCompanyAndOrders(String subOrderNo, InsAreaCompany insAreaCompany, InsAreaCompanyAccidentalDriving insAreaCompanyAccidentalDriving) {
+        insAreaCompany = updateEntityPruductAndPruductid(insAreaCompany);
 
 
+        //更新主订单的投保时间
+        insOrdersService.updateOrderStartingInsruanceTime(insAreaCompany.getOrderno(), insAreaCompany.getJqStartDate(), insAreaCompany.getJqEndDate(),
+                insAreaCompany.getSyStartDate(), insAreaCompany.getSyEndDate(), insAreaCompany);
+        insAreaCompany.setId(subOrderNo);
         baseMapper.insert(insAreaCompany);
         //保存驾意险信息
 
@@ -192,6 +218,7 @@ public class InsAreaCompanyServiceImpl extends ServiceImpl<InsAreaCompanyMapper,
 
         insOrdersTrackService.addingTrajectories(insAreaCompany);
         insOrdersService.updateByOrderStatus(insAreaCompany);
+        return subOrderNo;
     }
 
     @Override

+ 50 - 3
src/main/java/com/ydtech/modules/order/service/impl/InsCrawlerOrderServiceImpl.java

@@ -11,7 +11,9 @@ import com.ydtech.exception.SystemException;
 import com.ydtech.modules.ins.model.vo.*;
 import com.ydtech.modules.order.components.InsCrawlerOrderComponents;
 import com.ydtech.modules.order.components.InsImagesUploadCacheComponents;
+import com.ydtech.modules.order.constants.QuoteNumberConstant;
 import com.ydtech.modules.order.constants.UnderwritingStatus;
+import com.ydtech.modules.order.dao.SysQuoteRecordMapper;
 import com.ydtech.modules.order.entity.*;
 import com.ydtech.modules.order.entity.crawler.constants.CrawlerAuditStatus;
 import com.ydtech.modules.order.entity.crawler.constants.CrawlerVerifyPaymentConstants;
@@ -20,6 +22,7 @@ import com.ydtech.modules.order.entity.crawler.response.*;
 import com.ydtech.modules.order.entity.crawler.vo.CrawlerPolicyPrintVo;
 import com.ydtech.modules.order.entity.dto.ReadPdfUrlListDto;
 import com.ydtech.modules.order.entity.po.InsTaskImagesBase64;
+import com.ydtech.modules.order.entity.po.SysQuoteRecord;
 import com.ydtech.modules.order.entity.vo.BaseQuoteInfoVo;
 import com.ydtech.modules.order.entity.vo.BaseQuoteVo;
 import com.ydtech.modules.order.service.*;
@@ -86,6 +89,11 @@ public class InsCrawlerOrderServiceImpl implements InsCrawlerOrderService {
     @Autowired
     private InsSubOrderUpdateDetailService insSubOrderUpdateDetailService;
 
+    @Autowired
+    private SysQuoteRecordMapper sysQuoteRecordMapper;
+
+    @Autowired
+    private SysQuoteRedisService sysQuoteRedisService;
 
     @Override
     public void isLogin(PtlAgreementAttributionDto attribution, String companyId, String insCompanyName) {
@@ -100,6 +108,11 @@ public class InsCrawlerOrderServiceImpl implements InsCrawlerOrderService {
 
     @Override
     public HttpResult<QuoteRespVo> quote(BaseQuoteInfoVo quoteInfoVo, BaseQuoteVo<Object> t) {
+
+        //获取报价次数
+        Integer maxQuoteNum = t.getMaxQuoteNum();
+        List<SysQuoteRecord> sysQuoteRecords = new ArrayList<>();
+        InsOrders order = insOrdersService.getById(t.getOrderNo());
         // 协议id
         String agreementId = t.getAgreementId();
         // 请求地址
@@ -109,7 +122,7 @@ public class InsCrawlerOrderServiceImpl implements InsCrawlerOrderService {
 
         CrawlerQuoteRequest crawlerQuoteRequest = new CrawlerQuoteRequest();
         BeanUtils.copyProperties(quoteInfoVo, crawlerQuoteRequest);
-
+        crawlerQuoteRequest.setMaxQuoteNum(maxQuoteNum);
         crawlerQuoteRequest.setUsername(ptlAgreementAttribution.getUsername());
         // 前端传入的驾意险信息
         crawlerQuoteRequest.setAccidentalDriving(t.getAccidentalDrivingVo());
@@ -138,13 +151,27 @@ public class InsCrawlerOrderServiceImpl implements InsCrawlerOrderService {
         CrawlerQuoteResponse response = insCrawlerOrderComponents.request(apiUrl, ptlAgreementAttribution.getInsCompanyId(),
                 PtlCrawlerApiType.API_2.getDesc(), crawlerQuoteRequest, CrawlerQuoteResponse.class);
         if (response.getCode() != 200) {
-            InsOrders order = insOrdersService.getById(t.getOrderNo());
+
             //判断错误订单是否是重复投保
             InsOrderStatusEnum insOrderStatusEnum = InsOrderStatusEnum.QUOTE_FAILED;
             if(response.getMessage().contains("重复投保")){
                 insOrderStatusEnum = InsOrderStatusEnum.REPEAT_INSURE;
             }
-            insOrdersService.responseFailedOrder(t,ptlAgreementAttribution,order,response.getMessage(),insOrderStatusEnum);
+            String subOrderNo = insOrdersService.responseFailedOrder(t, ptlAgreementAttribution, order, response.getMessage(), insOrderStatusEnum);
+            if(!Objects.isNull(response.getOther().getMaxQuoteNum())) {
+                int quoteNum = maxQuoteNum - Integer.parseInt(response.getOther().getMaxQuoteNum());
+                for (int i = 0; i < quoteNum; i++) {
+                    SysQuoteRecord sysQuoteRecord = new SysQuoteRecord(quoteInfoVo.getUserid(),t.getCompanyId(),quoteInfoVo.getCarInfo().getLicenseNo(),
+                            QuoteNumberConstant.QuoteAction.QUOTE_FAILED.getCode().toString(),QuoteNumberConstant.QuoteResult.FAIL.getCode().toString());
+                    sysQuoteRecords.add(sysQuoteRecord);
+                }
+                sysQuoteRecords.forEach(item -> {
+                    item.setSubOrderNo(subOrderNo);
+                });
+                sysQuoteRecordMapper.insertBatch(sysQuoteRecords);
+                //刷新redis中的报价次数
+                sysQuoteRedisService.refreshQuoteNum(t.getCompanyId(), quoteInfoVo.getUserid(), sysQuoteRecords);
+            }
             throw new SystemException(response.getMessage());
         }
 
@@ -175,7 +202,27 @@ public class InsCrawlerOrderServiceImpl implements InsCrawlerOrderService {
 
         //处理订单信息
         QuoteRespVo responseVo = responseOrder(response, quoteRespVo, ptlAgreementAttribution, insAreaCompanyAccidentalDriving);
+        if(!Objects.isNull(response.getOther().getMaxQuoteNum())) {
+            int quoteNum = maxQuoteNum - Integer.parseInt(response.getOther().getMaxQuoteNum());
+            for (int i = 0; i < quoteNum; i++) {
+                SysQuoteRecord sysQuoteRecord;
+                if (i == quoteNum - 1) {
+                    sysQuoteRecord = new SysQuoteRecord(quoteInfoVo.getUserid(),t.getCompanyId(),quoteInfoVo.getCarInfo().getLicenseNo(),
+                            QuoteNumberConstant.QuoteAction.QUOTE_SUCCESS.getCode().toString(),QuoteNumberConstant.QuoteResult.SUCCESS.getCode().toString());
+                }else{
+                    sysQuoteRecord = new SysQuoteRecord(quoteInfoVo.getUserid(),t.getCompanyId(),quoteInfoVo.getCarInfo().getLicenseNo(),
+                            QuoteNumberConstant.QuoteAction.QUOTE_FAILED.getCode().toString(),QuoteNumberConstant.QuoteResult.FAIL.getCode().toString());
+                }
 
+                sysQuoteRecords.add(sysQuoteRecord);
+            }
+            sysQuoteRecords.forEach(item -> {
+                item.setSubOrderNo(responseVo.getCompanyId());
+            });
+            sysQuoteRecordMapper.insertBatch(sysQuoteRecords);
+            //刷新redis中的报价次数
+            sysQuoteRedisService.refreshQuoteNum(t.getCompanyId(), quoteInfoVo.getUserid(), sysQuoteRecords);
+        }
         return HttpResult.ok("成功", responseVo);
     }
 

+ 8 - 3
src/main/java/com/ydtech/modules/order/service/impl/InsOrdersServiceImpl.java

@@ -2291,7 +2291,7 @@ public class InsOrdersServiceImpl extends ServiceImpl<InsOrdersMapper, InsOrders
     }
 
     @Override
-    public boolean responseFailedOrder(BaseQuoteVo quoteVo, PtlAgreementAttribution ptlAgreementAttribution, InsOrders insOrder, String errorMessage, InsOrderStatusEnum statusEnum) {
+    public String responseFailedOrder(BaseQuoteVo quoteVo, PtlAgreementAttribution ptlAgreementAttribution, InsOrders insOrder, String errorMessage, InsOrderStatusEnum statusEnum) {
 
         //保存订单信息
         InsAreaCompany insAreaCompany = new InsAreaCompany();
@@ -2324,8 +2324,13 @@ public class InsOrdersServiceImpl extends ServiceImpl<InsOrdersMapper, InsOrders
         insAreaCompany.setQuoteErrMsg(errorMessage);
 
         InsAreaCompanyAccidentalDriving insAreaCompanyAccidentalDriving = new InsAreaCompanyAccidentalDriving();
-        insAreaCompanyService.insertCompanyAndOrders(insAreaCompany, insAreaCompanyAccidentalDriving);
-        return true;
+        String s = insAreaCompanyService.insertCompanyAndOrders(insAreaCompany, insAreaCompanyAccidentalDriving);
+        return s;
+    }
+
+    @Override
+    public String responseFailedOrder(String subOrderNo, BaseQuoteVo quoteVo, PtlAgreementAttribution ptlAgreementAttribution, InsOrders insOrder, String errorMessage, InsOrderStatusEnum statusEnum) {
+        return null;
     }
 
     /**

+ 349 - 0
src/main/java/com/ydtech/modules/order/service/impl/SysQuoteConfigServiceImpl.java

@@ -0,0 +1,349 @@
+package com.ydtech.modules.order.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.ydtech.exception.SystemException;
+import com.ydtech.modules.admin.model.SysUser;
+import com.ydtech.modules.admin.service.SysUserService;
+import com.ydtech.modules.base.controller.BaseController;
+import com.ydtech.modules.order.constants.QuoteNumberConstant;
+import com.ydtech.modules.order.dao.*;
+import com.ydtech.modules.order.entity.InsOrders;
+import com.ydtech.modules.order.entity.PtlAgreementNonCarProductRule;
+import com.ydtech.modules.order.entity.po.SysQuoteConfig;
+import com.ydtech.modules.order.entity.po.SysQuoteRecord;
+import com.ydtech.modules.order.entity.po.SysQuoteUser;
+import com.ydtech.modules.order.entity.po.SysQuoteUserConfigAppend;
+import com.ydtech.modules.order.entity.vo.DrivingInsuranceQueryVo;
+import com.ydtech.modules.order.entity.vo.QuoteDetailsQueryVo;
+import com.ydtech.modules.order.entity.vo.QuoteDetailsVo;
+import com.ydtech.modules.order.entity.vo.QuoteNumRedisVo;
+import com.ydtech.modules.order.service.InsOrdersService;
+import com.ydtech.modules.order.service.PtlAgreementNonCarProductRuleService;
+import com.ydtech.modules.order.service.SysQuoteConfigService;
+import com.ydtech.modules.order.service.SysQuoteRedisService;
+import com.ydtech.modules.protocol.entity.po.PtlAgreement;
+import com.ydtech.modules.protocol.service.PtlAgreementService;
+import com.ydtech.utils.idgen.IdGenerate;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.LocalTime;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+/**
+ * 服务实现类
+ */
+@Service
+public class SysQuoteConfigServiceImpl extends ServiceImpl<SysQuoteConfigMapper, SysQuoteConfig>
+        implements SysQuoteConfigService {
+
+    @Autowired
+    SysQuoteUserMapper sysQuoteUserMapper;
+
+    @Autowired
+    SysQuoteUserConfigAppendMapper sysQuoteUserConfigAppendMapper;
+
+    @Autowired
+    InsOrdersService insOrdersService;
+
+    @Autowired
+    SysQuoteRecordMapper sysQuoteRecordMapper;
+
+    @Autowired
+    SysQuoteRedisService sysQuoteRedisService;
+
+    @Autowired
+    SysUserService sysUserService;
+
+    /**
+     * 检查报价限制
+     * @return
+     */
+    @Override
+    public boolean checkQuoteLimitation(String userId,String companyId,String licenseNo) {
+        //读取配置
+        QuoteNumRedisVo quoteNumberRedisData = sysQuoteRedisService.getQuoteNumberRedisData(userId);
+
+        //如果没有数据则查询数据库
+        if(Objects.isNull(quoteNumberRedisData)){
+            List<SysQuoteConfig> sysQuoteConfigs = this.getUserQuoteNumber(userId);
+            quoteNumberRedisData = sysQuoteRedisService.assembleQuoteRedisData(userId, sysQuoteConfigs);
+            //存储redis数据
+            sysQuoteRedisService.saveRedisData(quoteNumberRedisData);
+        }
+//
+//        //获取规则报价次数数据
+//        QuoteNumRedisVo.QuoteNumberCompanyVo quoteNumberCompanyVo = quoteNumberRedisData.getOriginalCompanyList().stream()
+//                .filter(company -> company.getCompanyId().equals(companyId)).findFirst().orElse(null);
+//
+//        if(!Objects.isNull(quoteNumberCompanyVo)){
+//            Integer dayMaxQuote = quoteNumberCompanyVo.getDayMaxQuoteNum();
+//            Integer carMaxQuote = quoteNumberCompanyVo.getCarMaxQuoteNum();
+//            BigDecimal orderRatio = quoteNumberCompanyVo.getOrderRatio();
+//            //获取已报价次数数据
+//            QuoteNumRedisVo.QuoteNumberCompanyVo alreadyQuoteNumberCompanyVo = quoteNumberRedisData.getQuoteCompanyList().stream()
+//                    .filter(company -> company.getCompanyId().equals(companyId)).findFirst().orElse(null);
+//            Integer alreadyDayQuoteNum = alreadyQuoteNumberCompanyVo.getDayMaxQuoteNum();
+//
+//            //获取车牌已报价次数
+//            Integer alreadyCarQuoteNum = 0;
+//            QuoteNumRedisVo.CarQuoteNumberVo carQuoteNumberVo = quoteNumberRedisData.getCarList().stream()
+//                    .filter(car -> car.getLicenseNo().equals(licenseNo)).findFirst().orElse(null);
+//            if(!Objects.isNull(carQuoteNumberVo)){
+//                alreadyCarQuoteNum = carQuoteNumberVo.getQuoteNum();
+//            }
+//
+//            //校验规则 是否能报价
+//            if(dayMaxQuote <= alreadyDayQuoteNum || carMaxQuote <= alreadyCarQuoteNum){
+//                return false;
+//            }
+//        }
+        Integer maxQuoteNum = sysQuoteRedisService.getMaxQuoteNum(companyId, userId, licenseNo);
+        if(maxQuoteNum <= 0) {
+            return false;
+        }
+        sysQuoteRedisService.quoteAfterRedisData(companyId, userId, licenseNo, 0);
+        return true;
+    }
+
+    /**
+     * 获取保险公司的报价次数
+     * @param userId
+     * @return
+     */
+    @Override
+    public QuoteNumRedisVo.QuoteNumberCompanyVo getUserQuoteNumber(String userId, String companyId) {
+
+        QuoteNumRedisVo.QuoteNumberCompanyVo quoteNumberCompanyVo = new QuoteNumRedisVo.QuoteNumberCompanyVo();
+        quoteNumberCompanyVo.setCompanyId(companyId);
+
+        //查询保险公司报价次数配置
+        SysQuoteConfig sysQuoteConfig = baseMapper.selectOne(new LambdaQueryWrapper<SysQuoteConfig>()
+                .eq(SysQuoteConfig::getCompanyId, companyId));
+
+        if(!Objects.isNull(sysQuoteConfig)) {
+            //查询是否有附加的用户报价次数配置
+            List<SysQuoteUserConfigAppend> sysQuoteUserConfigAppends = sysQuoteUserConfigAppendMapper.selectList(new LambdaQueryWrapper<SysQuoteUserConfigAppend>()
+                    .eq(SysQuoteUserConfigAppend::getUserId, BaseController.getUserId())
+                    .eq(SysQuoteUserConfigAppend::getCompanyId, companyId));
+
+            //与配置的总次数累加
+            SysQuoteUserConfigAppend sysQuoteUserConfigAppend = new SysQuoteUserConfigAppend();
+            sysQuoteUserConfigAppends.forEach(item -> {
+                sysQuoteUserConfigAppend.setCarMaxQuoteNum(item.getCarMaxQuoteNum() + sysQuoteUserConfigAppend.getCarMaxQuoteNum());
+                sysQuoteUserConfigAppend.setDayMaxQuoteNum(item.getDayMaxQuoteNum() + sysQuoteUserConfigAppend.getDayMaxQuoteNum());
+            });
+            //合成总次数
+            quoteNumberCompanyVo.setDayMaxQuoteNum(sysQuoteConfig.getDayMaxQuoteNum() + sysQuoteUserConfigAppend.getDayMaxQuoteNum());
+            quoteNumberCompanyVo.setCarMaxQuoteNum(sysQuoteConfig.getCarMaxQuoteNum() + sysQuoteUserConfigAppend.getCarMaxQuoteNum());
+        }
+        return quoteNumberCompanyVo;
+    }
+
+    /**
+     * 获取保险公司的报价次数
+     * @param userId
+     * @return
+     */
+    public List<SysQuoteConfig> getUserQuoteNumber(String userId){
+//        List<SysQuoteConfig> sysQuoteConfigs = baseMapper.selectList(new LambdaQueryWrapper<SysQuoteConfig>()
+//                .eq(SysQuoteConfig::getIsEnabled,1));
+        List<SysQuoteConfig> sysQuoteConfigs = sysQuoteUserMapper.getQuoteUserConfig(userId);
+        return sysQuoteConfigs;
+    }
+
+    /**
+     * 设置配置信息
+     */
+    @Override
+    @Transactional
+    public boolean setQuoteInfo(SysQuoteConfig sysQuoteConfig) {
+        boolean result = false;
+        if(Objects.isNull(sysQuoteConfig.getCompanyId())){
+            throw new SystemException("未找到公司信息");
+        }
+
+        //判断是否存在配置信息
+        SysQuoteConfig quoteConfig = baseMapper.selectOne(new LambdaQueryWrapper<SysQuoteConfig>()
+                .eq(SysQuoteConfig::getCompanyId, sysQuoteConfig.getCompanyId()));
+        if(Objects.isNull(quoteConfig)){
+            //新增操作
+            String id = IdGenerate.nextId();
+            sysQuoteConfig.setId(id);
+            sysQuoteConfig.setCreateTime(LocalDateTime.now());
+            sysQuoteConfig.setCreateBy(BaseController.getUserId());
+            result = this.save(sysQuoteConfig);
+            if(Objects.equals(sysQuoteConfig.getAuthorize(), QuoteNumberConstant.QuoteAuthorizeType.PART.getCode())){
+                //组装用户数据
+                List<String> userIds = sysQuoteConfig.getProxyList().stream().map(proxy->proxy.getId()).collect(Collectors.toList());
+                List<SysQuoteUser> sysQuoteUsers = SysQuoteUser.getSysQuoteUserList(sysQuoteConfig.getId(), userIds);
+                sysQuoteUserMapper.insertBatch(sysQuoteUsers);
+                //更新redis数据
+                sysQuoteRedisService.updateAllQuoteRedis(sysQuoteConfig);
+            }
+        }else{
+            quoteConfig.setUpdateTime(LocalDateTime.now());
+            quoteConfig.setUpdateBy(BaseController.getUserId());
+            quoteConfig.setCarMaxQuoteNum(Objects.isNull(sysQuoteConfig.getCarMaxQuoteNum()) ? 0 : sysQuoteConfig.getCarMaxQuoteNum());
+            quoteConfig.setDayMaxQuoteNum(Objects.isNull(sysQuoteConfig.getDayMaxQuoteNum())? 0 : sysQuoteConfig.getDayMaxQuoteNum());
+            quoteConfig.setOrderRatio(Objects.isNull(sysQuoteConfig.getOrderRatio())? new BigDecimal(BigInteger.ZERO) : sysQuoteConfig.getOrderRatio());
+            quoteConfig.setAuthorize(sysQuoteConfig.getAuthorize());
+            quoteConfig.setIsEnabled(sysQuoteConfig.getIsEnabled());
+            result = this.updateById(quoteConfig);
+
+            if(Objects.equals(sysQuoteConfig.getAuthorize(), QuoteNumberConstant.QuoteAuthorizeType.PART.getCode())){
+                sysQuoteUserMapper.delete(new LambdaQueryWrapper<SysQuoteUser>()
+                        .eq(SysQuoteUser::getConfigId, sysQuoteConfig.getId()));
+                //组装用户数据
+                List<String> userIds = sysQuoteConfig.getProxyList().stream().map(proxy->proxy.getId()).collect(Collectors.toList());
+                List<SysQuoteUser> sysQuoteUsers = SysQuoteUser.getSysQuoteUserList(sysQuoteConfig.getId(), userIds);
+                sysQuoteUserMapper.insertBatch(sysQuoteUsers);
+            }
+            List<String> redisUserIds = sysQuoteRedisService.searchKeysWithScan(QuoteNumberConstant.QUOTE_NUMBER_KEY + "*");
+            redisUserIds.forEach(item->{
+                sysQuoteRedisService.delQuoteRedis(item.substring(QuoteNumberConstant.QUOTE_NUMBER_KEY.length()));
+            });
+        }
+
+        return result;
+    }
+
+    /**
+     * 获取报价次数配置信息
+     */
+    @Override
+    public SysQuoteConfig getQuoteConfigInfo(String companyId) {
+        SysQuoteConfig sysQuoteConfig = baseMapper.selectOne(new LambdaQueryWrapper<SysQuoteConfig>()
+                .eq(SysQuoteConfig::getCompanyId, companyId));
+        if(Objects.isNull(sysQuoteConfig)){
+            throw new SystemException("未找到配置信息");
+        }
+
+        if(Objects.equals(sysQuoteConfig.getAuthorize(), QuoteNumberConstant.QuoteAuthorizeType.PART.getCode())){
+            //查询关联的用户
+            List<SysQuoteUser> sysQuoteUsers = sysQuoteUserMapper.selectList(new LambdaQueryWrapper<SysQuoteUser>()
+                  .eq(SysQuoteUser::getConfigId, sysQuoteConfig.getId()));
+            List<String> users = sysQuoteUsers.stream().map(user -> user.getUserId()).collect(Collectors.toList());
+            List<SysUser> sysUsers = sysUserService.getByIds(users);
+            sysQuoteConfig.setProxyList(sysUsers);
+        }
+        return sysQuoteConfig;
+    }
+
+    /**
+     * 关联用户
+     */
+    @Override
+    @Transactional
+    public boolean connectUser(String configId, List<String> userIds) {
+        //删除原数据
+        sysQuoteUserMapper.delete(new LambdaQueryWrapper<SysQuoteUser>()
+                .eq(SysQuoteUser::getConfigId, configId));
+
+        List<SysQuoteUser> sysQuoteUsers = new ArrayList<>();
+
+        userIds.forEach(userId->{
+            SysQuoteUser sysQuoteUser = new SysQuoteUser();
+            sysQuoteUser.setId(IdGenerate.nextId());
+            sysQuoteUser.setConfigId(configId);
+            sysQuoteUser.setUserId(userId);
+            sysQuoteUsers.add(sysQuoteUser);
+        });
+
+        sysQuoteUsers.forEach(item->{
+            sysQuoteUserMapper.insert(item);
+        });
+        return true;
+    }
+
+    /**
+     * 追加配置
+     */
+    @Override
+    public boolean quoteConfigAppend(SysQuoteUserConfigAppend sysQuoteUserConfigAppend){
+        if(Objects.isNull(sysQuoteUserConfigAppend.getUserId()) || "".equals(sysQuoteUserConfigAppend.getUserId())){
+            throw new SystemException("未找到用户信息");
+        }
+        sysQuoteUserConfigAppend.setCarMaxQuoteNum(sysQuoteUserConfigAppend.getQuoteNumber());
+        sysQuoteUserConfigAppend.setDayMaxQuoteNum(sysQuoteUserConfigAppend.getQuoteNumber());
+        sysQuoteUserConfigAppend.setStartTime(LocalDateTime.of(LocalDate.now(), LocalTime.MIDNIGHT));
+        sysQuoteUserConfigAppend.setEndTime(LocalDateTime.of(LocalDate.now(), LocalTime.MAX));
+        sysQuoteUserConfigAppend.setCreateTime(LocalDateTime.now());
+        sysQuoteUserConfigAppend.setCreateBy(BaseController.getUserId());
+        int insert = sysQuoteUserConfigAppendMapper.insert(sysQuoteUserConfigAppend);
+        if(insert > 0){
+            sysQuoteRedisService.updateUserQuoteAppendRedis(sysQuoteUserConfigAppend);
+        }
+        return insert > 0;
+    }
+
+    @Override
+    public Page<QuoteDetailsVo> getAppendUserQuote(Page page,QuoteDetailsQueryVo quoteDetailsQueryVo) {
+        Page<QuoteDetailsVo> appendUserQuote = sysQuoteUserConfigAppendMapper.getAppendUserQuote(page,quoteDetailsQueryVo);
+        return appendUserQuote;
+    }
+
+    /**
+     * 根据保险公司获取今天用户追加的数据
+     */
+    @Override
+    public List<SysQuoteUserConfigAppend> getTodayAppendData(String companyId){
+        List<SysQuoteUserConfigAppend> sysQuoteUserConfigAppends = sysQuoteUserConfigAppendMapper.selectList(new LambdaQueryWrapper<SysQuoteUserConfigAppend>()
+                .eq(SysQuoteUserConfigAppend::getCompanyId, companyId)
+                .ge(SysQuoteUserConfigAppend::getCreateTime, LocalDate.now().atStartOfDay()) // 起始时间
+                .lt(SysQuoteUserConfigAppend::getCreateTime, LocalDate.now().plusDays(1).atStartOfDay()));
+        return sysQuoteUserConfigAppends;
+    }
+
+    @Override
+    public Page<QuoteDetailsVo> getQuoteRecordPage(Page page, QuoteDetailsQueryVo quoteDetailsQueryVo) {
+        if(quoteDetailsQueryVo.getDeptId() == null) {
+            quoteDetailsQueryVo.setDeptId(BaseController.getDeptId());
+        }
+        Page<QuoteDetailsVo> quoteRecordPage = sysQuoteRecordMapper.getQuoteRecordPage(page, quoteDetailsQueryVo);
+        quoteRecordPage.getRecords().forEach(item -> {
+            item.setAction(QuoteNumberConstant.QuoteAction.getByCode(item.getAction()));
+            item.setResult(QuoteNumberConstant.QuoteResult.getByCode(item.getResult()));
+        });
+        return quoteRecordPage;
+    }
+
+    @Override
+    public Page<QuoteDetailsVo> getQuoteRequestRecordPage(Page page, QuoteDetailsQueryVo quoteDetailsQueryVo) {
+        if(quoteDetailsQueryVo.getDeptId() == null) {
+            quoteDetailsQueryVo.setDeptId(BaseController.getDeptId());
+        }
+        Page<QuoteDetailsVo> quoteRecordPage = sysQuoteRecordMapper.getQuoteRequestRecordPage(page, quoteDetailsQueryVo);
+        quoteRecordPage.getRecords().forEach(item -> {
+            item.setAction(QuoteNumberConstant.QuoteAction.getByCode(item.getAction()));
+            item.setResult(QuoteNumberConstant.QuoteResult.getByCode(item.getResult()));
+        });
+        return quoteRecordPage;
+    }
+
+    @Override
+    public Page<QuoteDetailsVo> getQuoteDetails(Page page, QuoteDetailsQueryVo quoteDetailsQueryVo){
+        if(quoteDetailsQueryVo.getDeptId() == null) {
+            quoteDetailsQueryVo.setDeptId(BaseController.getDeptId());
+        }
+        Page<QuoteDetailsVo> quoteDetailsVoPage = sysQuoteRecordMapper.getQuoteDetails(page, quoteDetailsQueryVo);
+        quoteDetailsVoPage.getRecords().forEach(item -> {
+            item.setAction(QuoteNumberConstant.QuoteAction.getByCode(item.getAction()));
+            item.setResult(QuoteNumberConstant.QuoteResult.getByCode(item.getResult()));
+        });
+        return quoteDetailsVoPage;
+    }
+
+}

+ 423 - 0
src/main/java/com/ydtech/modules/order/service/impl/SysQuoteRedisServiceImpl.java

@@ -0,0 +1,423 @@
+package com.ydtech.modules.order.service.impl;
+
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.ydtech.exception.SystemException;
+import com.ydtech.modules.base.controller.BaseController;
+import com.ydtech.modules.order.constants.QuoteNumberConstant;
+import com.ydtech.modules.order.dao.SysQuoteConfigMapper;
+import com.ydtech.modules.order.dao.SysQuoteRecordMapper;
+import com.ydtech.modules.order.dao.SysQuoteUserConfigAppendMapper;
+import com.ydtech.modules.order.dao.SysQuoteUserMapper;
+import com.ydtech.modules.order.entity.po.SysQuoteConfig;
+import com.ydtech.modules.order.entity.po.SysQuoteRecord;
+import com.ydtech.modules.order.entity.po.SysQuoteUser;
+import com.ydtech.modules.order.entity.po.SysQuoteUserConfigAppend;
+import com.ydtech.modules.order.entity.vo.QuoteNumRedisVo;
+import com.ydtech.modules.order.service.InsOrdersService;
+import com.ydtech.modules.order.service.SysQuoteConfigService;
+import com.ydtech.modules.order.service.SysQuoteRedisService;
+import com.ydtech.utils.idgen.IdGenerate;
+import lombok.var;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.redis.core.RedisCallback;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.data.redis.core.ScanOptions;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.math.BigDecimal;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.util.*;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import static com.ydtech.modules.order.constants.QuoteNumberConstant.QUOTE_NUMBER_KEY;
+
+/**
+ * 服务实现类
+ */
+@Service
+public class SysQuoteRedisServiceImpl implements SysQuoteRedisService {
+
+    @Autowired
+    SysQuoteUserMapper sysQuoteUserMapper;
+
+    @Autowired
+    SysQuoteUserConfigAppendMapper sysQuoteUserConfigAppendMapper;
+
+    @Autowired
+    InsOrdersService insOrdersService;
+
+    @Autowired
+    SysQuoteRecordMapper sysQuoteRecordMapper;
+
+    @Autowired
+    RedisTemplate redisTemplate;
+
+
+    @Autowired
+    SysQuoteConfigService sysQuoteConfigService;
+
+    /**
+     * 模糊搜索报价次数的keys
+     * @param pattern
+     * @return
+     */
+    @Override
+    public List<String> searchKeysWithScan(String pattern) {
+        List<String> keys = new ArrayList<>();
+
+        redisTemplate.execute((RedisCallback<Object>) connection -> {
+            ScanOptions options = ScanOptions.scanOptions()
+                    .match(pattern) // 匹配
+                    .build();
+
+            try (var cursor = connection.scan(options)) {
+                cursor.forEachRemaining(item -> keys.add(new String(item)));
+            }
+            return null;
+        });
+
+        return keys;
+    }
+
+
+    /**
+     * 组装报价次数的redis数据
+     * @return
+     */
+    @Override
+    public QuoteNumRedisVo assembleQuoteRedisData(String userId,List<SysQuoteConfig> sysQuoteConfigs){
+        QuoteNumRedisVo quoteNumRedisVo = new QuoteNumRedisVo();
+        quoteNumRedisVo.setUserId(userId);
+
+        //查询用户今日的追加报价配置
+        List<SysQuoteUserConfigAppend> sysQuoteUserConfigAppendList = sysQuoteUserConfigAppendMapper.selectList(new LambdaQueryWrapper<SysQuoteUserConfigAppend>()
+              .eq(SysQuoteUserConfigAppend::getUserId, userId)
+                .ge(SysQuoteUserConfigAppend::getStartTime, LocalDate.now())
+                .le(SysQuoteUserConfigAppend::getEndTime, LocalDate.now().plusDays(1)));
+
+        sysQuoteConfigs.forEach(quoteConfig -> {
+            List<SysQuoteUserConfigAppend> appends = sysQuoteUserConfigAppendList.stream()
+                    .filter(append -> append.getCompanyId().equals(quoteConfig.getCompanyId())).collect(Collectors.toList());
+            //用户的追加报价次数
+            appends.forEach(append->{
+                quoteConfig.setDayMaxQuoteNum(quoteConfig.getDayMaxQuoteNum() + append.getDayMaxQuoteNum());
+                quoteConfig.setCarMaxQuoteNum(quoteConfig.getCarMaxQuoteNum() + append.getCarMaxQuoteNum());
+            });
+        });
+
+        List<QuoteNumRedisVo.QuoteNumberCompanyVo> originalCompanyList = new ArrayList<>();
+        sysQuoteConfigs.forEach(quoteConfig -> {
+            QuoteNumRedisVo.QuoteNumberCompanyVo quoteNumberCompanyVo = new QuoteNumRedisVo.QuoteNumberCompanyVo(quoteConfig);
+            originalCompanyList.add(quoteNumberCompanyVo);
+        });
+
+        //原始的报价数据
+        quoteNumRedisVo.setOriginalCompanyList(originalCompanyList);
+
+        // 获取今日报价的次数 进行数组组装
+        List<SysQuoteRecord> sysQuoteRecords = sysQuoteRecordMapper.selectList(new LambdaQueryWrapper<SysQuoteRecord>()
+                .eq(SysQuoteRecord::getUserId, userId)
+                .ge(SysQuoteRecord::getCreateTime, LocalDate.now())
+                .lt(SysQuoteRecord::getCreateTime, LocalDate.now().plusDays(1)));
+
+        //根据保险公司分组
+        Map<String, List<SysQuoteRecord>> sysQuoteRecordGroup = sysQuoteRecords.stream().collect(Collectors.groupingBy(SysQuoteRecord::getCompanyId));
+
+        List<QuoteNumRedisVo.QuoteNumberCompanyVo> quoteNumberCompanyList = new ArrayList<>();
+        sysQuoteRecordGroup.forEach((key, value) -> {
+            QuoteNumRedisVo.QuoteNumberCompanyVo quoteNumberCompanyVo = new QuoteNumRedisVo.QuoteNumberCompanyVo();
+            quoteNumberCompanyVo.setCompanyId(key);
+            quoteNumberCompanyVo.setDayMaxQuoteNum(value.size());
+            quoteNumberCompanyList.add(quoteNumberCompanyVo);
+        });
+        quoteNumRedisVo.setQuoteCompanyList(quoteNumberCompanyList);
+
+        //根据车牌进行分组
+        List<QuoteNumRedisVo.CarQuoteNumberVo> carQuoteNumberList = new ArrayList<>();
+
+        Map<Map.Entry<String, String>, List<SysQuoteRecord>> grouped = sysQuoteRecords.stream()
+                .collect(Collectors.groupingBy(record -> new AbstractMap.SimpleEntry<>(record.getCompanyId(), record.getLicenseNo())));
+
+        grouped.forEach((key, value) -> {
+            QuoteNumRedisVo.CarQuoteNumberVo carQuoteNumberVo = new QuoteNumRedisVo.CarQuoteNumberVo();
+            carQuoteNumberVo.setCompanyId(key.getKey());
+            carQuoteNumberVo.setLicenseNo(key.getValue());
+            carQuoteNumberVo.setQuoteNum(value.size());
+            carQuoteNumberList.add(carQuoteNumberVo);
+        });
+        quoteNumRedisVo.setCarList(carQuoteNumberList);
+
+        return quoteNumRedisVo;
+    }
+
+    @Override
+    public void saveRedisData(QuoteNumRedisVo quoteNumberRedis) {
+        redisTemplate.opsForValue().set(getQuoteNumberRedisKey(quoteNumberRedis.getUserId()), JSONObject.toJSONString(quoteNumberRedis));
+    }
+
+    /**
+     * 获取报价次数缓存key
+     * @param userId
+     * @return
+     */
+    @Override
+    public String getQuoteNumberRedisKey(String userId){
+        return QUOTE_NUMBER_KEY + userId;
+    }
+
+    /**
+     * 从redis获取用户报价次数的数据
+     * @param userId
+     * @return
+     */
+    @Override
+    public QuoteNumRedisVo getQuoteNumberRedisData(String userId) {
+        QuoteNumRedisVo quoteNumRedisVo = null;
+        if(!Objects.isNull(redisTemplate.opsForValue().get(getQuoteNumberRedisKey(userId))))
+        {
+            String jsonStr = redisTemplate.opsForValue().get(getQuoteNumberRedisKey(userId)).toString();
+            quoteNumRedisVo = JSONObject.parseObject(jsonStr, QuoteNumRedisVo.class);
+        }
+        return quoteNumRedisVo;
+    }
+
+    @Override
+    public void setQuoteRecordRedis(String userId,QuoteNumRedisVo quoteNumRedisVo) {
+        redisTemplate.opsForValue().set(getQuoteNumberRedisKey(userId), JSONObject.toJSONString(quoteNumRedisVo));
+    }
+
+    @Override
+    public void delQuoteRedis(String userId) {
+        redisTemplate.delete(getQuoteNumberRedisKey(userId));
+    }
+
+    @Override
+    public boolean updateAllQuoteRedis(SysQuoteConfig sysQuoteConfig) {
+        Map<String,String> updateRedisMap = new HashMap<>();
+
+        //查找出所有的key
+        List<String> keys = this.searchKeysWithScan(QuoteNumberConstant.QUOTE_NUMBER_KEY + "*");
+
+        //查找出所有的追加的配置信息
+        List<SysQuoteUserConfigAppend> sysQuoteUserConfigAppendList = sysQuoteUserConfigAppendMapper.selectList(new LambdaQueryWrapper<SysQuoteUserConfigAppend>()
+                .eq(SysQuoteUserConfigAppend::getCompanyId, sysQuoteConfig.getCompanyId())
+                .ge(SysQuoteUserConfigAppend::getCreateTime, LocalDate.now())
+                .lt(SysQuoteUserConfigAppend::getCreateTime, LocalDate.now()));
+
+        keys.forEach(key->{
+            QuoteNumRedisVo quoteNumRedisVo;
+            if(Objects.isNull(redisTemplate.opsForValue().get(getQuoteNumberRedisKey(BaseController.getUserId())))){
+                List<SysQuoteConfig> sysQuoteConfigs = sysQuoteConfigService.getUserQuoteNumber(BaseController.getUserId());
+                quoteNumRedisVo = assembleQuoteRedisData(BaseController.getUserId(), sysQuoteConfigs);
+            }else{
+                String jsonStr = redisTemplate.opsForValue().get(getQuoteNumberRedisKey(BaseController.getUserId())).toString();
+                quoteNumRedisVo = new QuoteNumRedisVo(jsonStr);
+
+            }
+            //判断是否存在 新加规则的保险公司
+            if(quoteNumRedisVo.getOriginalCompanyList().stream().anyMatch(x-> x.getCompanyId().equals(sysQuoteConfig.getCompanyId()))) {
+                quoteNumRedisVo.getOriginalCompanyList().forEach(company -> {
+                    if (company.getCompanyId().equals(sysQuoteConfig.getCompanyId())) {
+                        List<SysQuoteUserConfigAppend> appends = sysQuoteUserConfigAppendList.stream()
+                                .filter(append -> append.getUserId().equals(quoteNumRedisVo.getUserId())).collect(Collectors.toList());
+                        company.setDayMaxQuoteNum(sysQuoteConfig.getDayMaxQuoteNum());
+                        company.setCarMaxQuoteNum(sysQuoteConfig.getCarMaxQuoteNum());
+                        company.setOrderRatio(sysQuoteConfig.getOrderRatio());
+                        //每个用户的追加次数
+                        appends.forEach(append -> {
+                            company.setDayMaxQuoteNum(company.getDayMaxQuoteNum() + append.getDayMaxQuoteNum());
+                            company.setCarMaxQuoteNum(company.getCarMaxQuoteNum() + append.getCarMaxQuoteNum());
+                        });
+                    }
+                });
+            }else{
+                QuoteNumRedisVo.QuoteNumberCompanyVo redisVo = new QuoteNumRedisVo.QuoteNumberCompanyVo();
+                redisVo.setCompanyId(sysQuoteConfig.getCompanyId());
+                redisVo.setCarMaxQuoteNum(sysQuoteConfig.getCarMaxQuoteNum());
+                redisVo.setDayMaxQuoteNum(sysQuoteConfig.getDayMaxQuoteNum());
+                redisVo.setOrderRatio(sysQuoteConfig.getOrderRatio());
+                quoteNumRedisVo.getOriginalCompanyList().add(redisVo);
+            }
+            updateRedisMap.put(key, JSONObject.toJSONString(quoteNumRedisVo));
+        });
+        //批量更新数据
+        redisTemplate.opsForValue().multiSet(updateRedisMap);
+        return true;
+    }
+
+    /**
+     * 更新用户追加的缓存数据
+     * @param sysQuoteUserConfigAppend
+     * @return
+     */
+    @Override
+    public boolean updateUserQuoteAppendRedis(SysQuoteUserConfigAppend sysQuoteUserConfigAppend) {
+        QuoteNumRedisVo quoteNumRedisVo;
+        if(Objects.isNull(redisTemplate.opsForValue().get(getQuoteNumberRedisKey(sysQuoteUserConfigAppend.getUserId())))){
+            List<SysQuoteConfig> sysQuoteConfigs = sysQuoteConfigService.getUserQuoteNumber(sysQuoteUserConfigAppend.getUserId());
+            quoteNumRedisVo = assembleQuoteRedisData(sysQuoteUserConfigAppend.getUserId(), sysQuoteConfigs);
+        }else{
+            String jsonStr = redisTemplate.opsForValue().get(getQuoteNumberRedisKey(sysQuoteUserConfigAppend.getUserId())).toString();
+            quoteNumRedisVo = new QuoteNumRedisVo(jsonStr);
+
+        }
+        quoteNumRedisVo.getOriginalCompanyList().forEach(company->{
+            if(company.getCompanyId().equals(sysQuoteUserConfigAppend.getCompanyId())){
+                company.setDayMaxQuoteNum(company.getDayMaxQuoteNum() + sysQuoteUserConfigAppend.getDayMaxQuoteNum());
+                company.setCarMaxQuoteNum(company.getCarMaxQuoteNum() + sysQuoteUserConfigAppend.getCarMaxQuoteNum());
+            }
+        });
+        redisTemplate.opsForValue().set(getQuoteNumberRedisKey(sysQuoteUserConfigAppend.getUserId()), JSONObject.toJSONString(quoteNumRedisVo));
+        return true;
+    }
+
+    /**
+     * 报价之后redis数据更新
+     * @param companyId
+     * @param userId
+     * @param licenseNo
+     * @param num
+     * @return
+     */
+    @Override
+    public void quoteAfterRedisData(String companyId,String userId,String licenseNo,Integer num){
+        QuoteNumRedisVo quoteNumberRedisData = getQuoteNumberRedisData(userId);
+        //判断缓存中的报价保险公司是否存在
+        boolean isExists = quoteNumberRedisData.getQuoteCompanyList().stream().anyMatch(company -> company.getCompanyId().equals(companyId));
+        if(isExists) {
+            quoteNumberRedisData.getQuoteCompanyList().forEach(company -> {
+                if (company.getCompanyId().equals(companyId)) {
+                    company.setDayMaxQuoteNum(company.getDayMaxQuoteNum() + num);
+                }
+            });
+        }else{
+            List<QuoteNumRedisVo.QuoteNumberCompanyVo> quoteCompanyList = quoteNumberRedisData.getQuoteCompanyList();
+            QuoteNumRedisVo.QuoteNumberCompanyVo quoteNumberCompanyVo = new QuoteNumRedisVo.QuoteNumberCompanyVo();
+            quoteNumberCompanyVo.setCompanyId(companyId);
+            quoteNumberCompanyVo.setDayMaxQuoteNum(num);
+            quoteCompanyList.add(quoteNumberCompanyVo);
+            quoteNumberRedisData.setQuoteCompanyList(quoteCompanyList);
+        }
+
+        //判断缓存中的车牌报价是否存在
+        boolean carIsExists = quoteNumberRedisData.getCarList().stream().anyMatch(car -> car.getLicenseNo().equals(licenseNo));
+        if(carIsExists){
+            quoteNumberRedisData.getCarList().forEach(car -> {
+                if(car.getLicenseNo().equals(licenseNo)){
+                    car.setQuoteNum(car.getQuoteNum() + num);
+                }
+            });
+        }else{
+            List<QuoteNumRedisVo.CarQuoteNumberVo> carList = quoteNumberRedisData.getCarList();
+            QuoteNumRedisVo.CarQuoteNumberVo carQuoteNumberVo = new QuoteNumRedisVo.CarQuoteNumberVo();
+            carQuoteNumberVo.setLicenseNo(licenseNo);
+            carQuoteNumberVo.setQuoteNum(num);
+            carQuoteNumberVo.setCompanyId(companyId);
+            carList.add(carQuoteNumberVo);
+            quoteNumberRedisData.setCarList(carList);
+        }
+
+        redisTemplate.opsForValue().set(getQuoteNumberRedisKey(userId), JSONObject.toJSONString(quoteNumberRedisData));
+    }
+
+    /**
+     * 根据车辆信息获取最大的报价次数
+     */
+    @Override
+    public Integer getMaxQuoteNum(String companyId, String userId, String licenseNo) {
+        Integer maxQuoteNum = 9999;
+        //当天最大报价的次数
+        Integer dayMaxQuoteNum = 0;
+        // 当天已经报价的次数
+        Integer dayAlreadyQuoteNum = 0;
+        //车辆最大报价的次数
+        Integer carMaxQuoteNum = 0;
+        //车辆已经报价的次数
+        Integer carAlreadyQuoteNum = 0;
+        QuoteNumRedisVo quoteNumberRedisData = getQuoteNumberRedisData(userId);
+        QuoteNumRedisVo.QuoteNumberCompanyVo quoteNumberCompanyVo1 = quoteNumberRedisData.getOriginalCompanyList().stream()
+                .filter(company -> company.getCompanyId().equals(companyId)).findFirst().orElse(null);
+        if(!Objects.isNull(quoteNumberCompanyVo1)){
+
+            dayMaxQuoteNum = quoteNumberCompanyVo1.getDayMaxQuoteNum();
+            carMaxQuoteNum = quoteNumberCompanyVo1.getCarMaxQuoteNum();
+
+
+            QuoteNumRedisVo.QuoteNumberCompanyVo quoteNumberCompanyVo = quoteNumberRedisData.getQuoteCompanyList().stream()
+                    .filter(company -> company.getCompanyId().equals(companyId)).findFirst().orElse(null);
+            if(!Objects.isNull(quoteNumberCompanyVo)){
+                dayAlreadyQuoteNum = quoteNumberCompanyVo.getDayMaxQuoteNum();
+            }
+
+            QuoteNumRedisVo.CarQuoteNumberVo carQuoteNumberVo = quoteNumberRedisData.getCarList().stream()
+                    .filter(car -> car.getLicenseNo().equals(licenseNo) && car.getCompanyId().equals(companyId))
+                    .findAny().orElse(null);
+            if(!Objects.isNull(carQuoteNumberVo)){
+                carAlreadyQuoteNum = carQuoteNumberVo.getQuoteNum();
+            }
+
+            //最大报价次数 - 已报价 = 剩余    当天剩余  与 车辆剩余报价  取最小值
+            maxQuoteNum = Math.min(dayMaxQuoteNum - dayAlreadyQuoteNum,carMaxQuoteNum - carAlreadyQuoteNum);
+        }
+
+        return maxQuoteNum;
+    }
+
+    @Override
+    public BigDecimal getQuoteRatio(String companyId, String userId) {
+        BigDecimal quoteRatio = sysQuoteRecordMapper.getQuoteRatio(userId, companyId);
+        return quoteRatio;
+    }
+
+    /**
+     * 刷新报价次数
+     * @param companyId
+     * @param userId
+     * @return
+     */
+    @Override
+    public void refreshQuoteNum(String companyId, String userId, List<SysQuoteRecord> sysQuoteRecords) {
+        String licenseNo = sysQuoteRecords.get(0).getLicenseNo();
+        QuoteNumRedisVo quoteNumberRedisData = getQuoteNumberRedisData(userId);
+        QuoteNumRedisVo.QuoteNumberCompanyVo quoteNumberCompanyVo = quoteNumberRedisData.getQuoteCompanyList().stream()
+                .filter(company -> company.getCompanyId().equals(companyId)).findFirst().orElse(null);
+
+        if(!Objects.isNull(quoteNumberCompanyVo)){
+            quoteNumberRedisData.getQuoteCompanyList().forEach(item->{
+                if(item.getCompanyId().equals(companyId)){
+                    item.setDayMaxQuoteNum(item.getDayMaxQuoteNum() + sysQuoteRecords.size());
+                }
+            });
+        }else{
+            QuoteNumRedisVo.QuoteNumberCompanyVo quoteNumberCompanyVo1 = new QuoteNumRedisVo.QuoteNumberCompanyVo();
+            quoteNumberCompanyVo1.setCompanyId(companyId);
+            quoteNumberCompanyVo1.setDayMaxQuoteNum(sysQuoteRecords.size());
+            quoteNumberRedisData.getQuoteCompanyList().add(quoteNumberCompanyVo1);
+        }
+
+        QuoteNumRedisVo.CarQuoteNumberVo carQuoteNumberVo = quoteNumberRedisData.getCarList().stream()
+                .filter(car -> car.getLicenseNo().equals(licenseNo) && car.getCompanyId().equals(companyId))
+                .findFirst().orElse(null);
+        if(!Objects.isNull(carQuoteNumberVo)){
+            quoteNumberRedisData.getCarList().forEach(item->{
+                if(item.getLicenseNo().equals(licenseNo)){
+                    item.setQuoteNum(item.getQuoteNum() + sysQuoteRecords.size());
+                }
+            });
+        }else{
+            carQuoteNumberVo = new QuoteNumRedisVo.CarQuoteNumberVo();
+            carQuoteNumberVo.setCompanyId(companyId);
+            carQuoteNumberVo.setLicenseNo(licenseNo);
+            carQuoteNumberVo.setQuoteNum(sysQuoteRecords.size());
+            quoteNumberRedisData.getCarList().add(carQuoteNumberVo);
+        }
+        redisTemplate.opsForValue().set(getQuoteNumberRedisKey(userId), JSONObject.toJSONString(quoteNumberRedisData));
+    }
+
+
+}

+ 183 - 52
src/main/java/com/ydtech/modules/order/service/impl/YangGuangOrderApiServiceImpl.java

@@ -19,7 +19,9 @@ import com.ydtech.modules.order.components.FileComponents;
 import com.ydtech.modules.order.components.InsImagesUploadCacheComponents;
 import com.ydtech.modules.order.components.yangguang.YangGuangRequestApiComponents;
 import com.ydtech.modules.order.constants.InsuranceTypeCorrespondence;
+import com.ydtech.modules.order.constants.QuoteNumberConstant;
 import com.ydtech.modules.order.constants.UnderwritingStatus;
+import com.ydtech.modules.order.dao.SysQuoteRecordMapper;
 import com.ydtech.modules.order.entity.*;
 import com.ydtech.modules.order.entity.api.yangguang.request.*;
 import com.ydtech.modules.order.entity.api.yangguang.response.*;
@@ -30,6 +32,7 @@ import com.ydtech.modules.order.entity.dto.ReadPdfUrlListDto;
 import com.ydtech.modules.order.entity.filter.CarModelsFilterUtils;
 import com.ydtech.modules.order.entity.po.InsTaskImagesBase64;
 import com.ydtech.modules.order.entity.po.InsUploadFiles;
+import com.ydtech.modules.order.entity.po.SysQuoteRecord;
 import com.ydtech.modules.order.entity.vo.BaseQuoteInfoVo;
 import com.ydtech.modules.order.entity.vo.BaseQuoteVo;
 import com.ydtech.modules.order.entity.vo.PolicyPrintVo;
@@ -83,6 +86,10 @@ public class YangGuangOrderApiServiceImpl implements YangGuangOrderApiService {
 
     private final FileComponents fileComponents;
 
+    private final SysQuoteRecordMapper sysQuoteRecordMapper;
+
+    private final SysQuoteRedisService sysQuoteRedisService;
+
     @Value("${upload.file.path}")
     private String uploadFilePath;
 
@@ -93,6 +100,12 @@ public class YangGuangOrderApiServiceImpl implements YangGuangOrderApiService {
     private String apiUrl;
     @Override
     public HttpResult<QuoteRespVo> quote(BaseQuoteInfoVo quoteInfoVo, BaseQuoteVo<List<YgQuoteAccidentVo>> quoteVo) throws JsonProcessingException {
+
+        Integer maxQuoteNum = quoteVo.getMaxQuoteNum();
+
+        List<SysQuoteRecord> sysQuoteRecords = new ArrayList<>();
+
+
         // 通过协议获取配置实体
         String agreementId = quoteVo.getAgreementId();
         PtlAgreementAttribution ptlAgreementAttribution = ptlAgreementAttributionService.getById(agreementId);
@@ -138,58 +151,123 @@ public class YangGuangOrderApiServiceImpl implements YangGuangOrderApiService {
             DateTimeFormatter inputFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");
             DateTimeFormatter outputFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
 
-            LocalDateTime dateTime = LocalDateTime.parse(endDate, inputFormatter);
-            String newDateStr = dateTime.format(outputFormatter);
-            YangGuangAccuracyCalculateRequest yangGuangAccuracyCalculateRequestRe = new YangGuangAccuracyCalculateRequest(quoteInfoVo, purchasePrice, carModelList1, riskList.get(0),newDateStr,ygConfigureParameters,quoteVo);
-            yangGuangAccuracyCalculateRequestRe.setInfotransNo(yangGuangQueryVehicleModelResponse.getInfotransNo());
-            YangGuangAccuracyCalculateResponse yangGuangAccuracyCalculateResponseRe = yangGuangRequestApiComponents.accuracyCalculaye(yangGuangAccuracyCalculateRequestRe);
-            if (insOrders.getProductid().equals("034001") || insOrders.getProductid().equals("0330034001") || insOrders.getProductid().equals("0330034002")) {
-                if (yangGuangAccuracyCalculateResponseRe.getErrorCode().equals("0")) {
-                    YangGuangAccuracyCalculateResponse.itemcar itemcar = yangGuangAccuracyCalculateResponseRe.getItemcar();
-                    String actualValue = itemcar.getActualValue();
-                    YangGuangAccuracyCalculateRequest yangGuangAccuracyCalculateRequest1 = new YangGuangAccuracyCalculateRequest(quoteInfoVo, actualValue, carModelList1, riskList.get(0),newDateStr,ygConfigureParameters,quoteVo);
-                    yangGuangAccuracyCalculateRequest1.setInfotransNo(yangGuangQueryVehicleModelResponse.getInfotransNo());
-                    YangGuangAccuracyCalculateResponse yangGuangAccuracyCalculateResponse1 = yangGuangRequestApiComponents.accuracyCalculaye(yangGuangAccuracyCalculateRequest1);
-                    boolean isEnergy = carInfo.isNewEnergy();
-
-                    if (!yangGuangAccuracyCalculateResponse1.getErrorCode().equals("0")) {
-                    InsOrders order = insOrdersService.getById(quoteInfoVo.getOrderNo());
-                    InsOrderStatusEnum insOrderStatusEnum = InsOrderStatusEnum.QUOTE_FAILED;
-                        if (yangGuangAccuracyCalculateResponse1.getErrorMessage().contains("重复投保")) {
-                        insOrderStatusEnum = InsOrderStatusEnum.REPEAT_INSURE;
+                LocalDateTime dateTime = LocalDateTime.parse(endDate, inputFormatter);
+                String newDateStr = dateTime.format(outputFormatter);
+                YangGuangAccuracyCalculateRequest yangGuangAccuracyCalculateRequestRe = new YangGuangAccuracyCalculateRequest(quoteInfoVo, purchasePrice, carModelList1, riskList.get(0),newDateStr,ygConfigureParameters,quoteVo);
+                yangGuangAccuracyCalculateRequestRe.setInfotransNo(yangGuangQueryVehicleModelResponse.getInfotransNo());
+                maxQuoteNum--;
+                SysQuoteRecord sysQuoteRecord = new SysQuoteRecord(quoteInfoVo.getUserid(),quoteVo.getCompanyId(),quoteInfoVo.getCarInfo().getLicenseNo(),
+                        QuoteNumberConstant.QuoteAction.DATE_DEAL.getCode().toString(),QuoteNumberConstant.QuoteResult.FAIL.getCode().toString());
+                sysQuoteRecords.add(sysQuoteRecord);
+                if(maxQuoteNum <= 0){
+                    sysQuoteRecordMapper.insertBatch(sysQuoteRecords);
+                    //刷新redis中的报价次数
+                    sysQuoteRedisService.refreshQuoteNum(quoteVo.getCompanyId(),quoteInfoVo.getUserid(),sysQuoteRecords);
+                    throw new SystemException("报价次数限制");
+                }
+                YangGuangAccuracyCalculateResponse yangGuangAccuracyCalculateResponseRe = yangGuangRequestApiComponents.accuracyCalculaye(yangGuangAccuracyCalculateRequestRe);
+                if (insOrders.getProductid().equals("034001") || insOrders.getProductid().equals("0330034001") || insOrders.getProductid().equals("0330034002")) {
+                    if (yangGuangAccuracyCalculateResponseRe.getErrorCode().equals("0")) {
+                        YangGuangAccuracyCalculateResponse.itemcar itemcar = yangGuangAccuracyCalculateResponseRe.getItemcar();
+                        String actualValue = itemcar.getActualValue();
+                        YangGuangAccuracyCalculateRequest yangGuangAccuracyCalculateRequest1 = new YangGuangAccuracyCalculateRequest(quoteInfoVo, actualValue, carModelList1, riskList.get(0),newDateStr,ygConfigureParameters,quoteVo);
+                        yangGuangAccuracyCalculateRequest1.setInfotransNo(yangGuangQueryVehicleModelResponse.getInfotransNo());
+                        maxQuoteNum--;
+                        SysQuoteRecord sysQuoteRecord1 = new SysQuoteRecord(quoteInfoVo.getUserid(),quoteVo.getCompanyId(),quoteInfoVo.getCarInfo().getLicenseNo(),
+                                QuoteNumberConstant.QuoteAction.DATE_DEAL.getCode().toString(),QuoteNumberConstant.QuoteResult.FAIL.getCode().toString());
+                        sysQuoteRecords.add(sysQuoteRecord1);
+                        if(maxQuoteNum <= 0){
+                            sysQuoteRecordMapper.insertBatch(sysQuoteRecords);
+                            //刷新redis中的报价次数
+                            sysQuoteRedisService.refreshQuoteNum(quoteVo.getCompanyId(),quoteInfoVo.getUserid(),sysQuoteRecords);
+                            throw new SystemException("报价次数限制");
                         }
-                    insOrdersService.responseFailedOrder(quoteVo,ptlAgreementAttribution, order, yangGuangAccuracyCalculateResponse1.getErrorMessage(),insOrderStatusEnum);
-                    throw new SystemException(yangGuangAccuracyCalculateResponse1.getErrorMessage());
+                        YangGuangAccuracyCalculateResponse yangGuangAccuracyCalculateResponse1 = yangGuangRequestApiComponents.accuracyCalculaye(yangGuangAccuracyCalculateRequest1);
+                        boolean isEnergy = carInfo.isNewEnergy();
+
+                        if (!yangGuangAccuracyCalculateResponse1.getErrorCode().equals("0")) {
+                        InsOrders order = insOrdersService.getById(quoteInfoVo.getOrderNo());
+                        InsOrderStatusEnum insOrderStatusEnum = InsOrderStatusEnum.QUOTE_FAILED;
+                            if (yangGuangAccuracyCalculateResponse1.getErrorMessage().contains("重复投保")) {
+                            insOrderStatusEnum = InsOrderStatusEnum.REPEAT_INSURE;
+                            }
+                            String subOrderNo = insOrdersService.responseFailedOrder(quoteVo, ptlAgreementAttribution, order, yangGuangAccuracyCalculateResponse1.getErrorMessage(), insOrderStatusEnum);
+                            SysQuoteRecord sysQuoteRecord2 = new SysQuoteRecord(quoteInfoVo.getUserid(),quoteVo.getCompanyId(),quoteInfoVo.getCarInfo().getLicenseNo(),
+                                    QuoteNumberConstant.QuoteAction.QUOTE_FAILED.getCode().toString(),QuoteNumberConstant.QuoteResult.FAIL.getCode().toString());
+                            sysQuoteRecords.add(sysQuoteRecord2);
+                            //存储报价记录
+                            sysQuoteRecords.forEach(item->{
+                                item.setSubOrderNo(subOrderNo);
+                            });
+
+                            sysQuoteRecordMapper.insertBatch(sysQuoteRecords);
+                            //刷新redis中的报价次数
+                            sysQuoteRedisService.refreshQuoteNum(quoteVo.getCompanyId(),quoteInfoVo.getUserid(),sysQuoteRecords);
+                            throw new SystemException(yangGuangAccuracyCalculateResponse1.getErrorMessage());
+                        }
+                        // 处理数据
+                        QuoteRespVo quoteRespVo = getQuoteRespVo(yangGuangAccuracyCalculateResponse1, quoteInfoVo, quoteVo.getAccidentalDrivingVo(), isEnergy);
+
+                        // 设置核心报价车型
+                        quoteRespVo.setCoreModels(carModelList1.toCoreModelsVo());
+                        HttpResult<QuoteRespVo> quoteRespVoHttpResult = responseOrder(yangGuangAccuracyCalculateResponse1, quoteRespVo, ptlAgreementAttribution, quoteInfoVo.getOrderNo(),
+                                quoteVo.getAccidentalDrivingVo());
+
+                        SysQuoteRecord sysQuoteRecord3 = new SysQuoteRecord(quoteInfoVo.getUserid(),quoteVo.getCompanyId(),quoteInfoVo.getCarInfo().getLicenseNo(),
+                                QuoteNumberConstant.QuoteAction.QUOTE_SUCCESS.getCode().toString(),QuoteNumberConstant.QuoteResult.SUCCESS.getCode().toString());
+                        sysQuoteRecords.add(sysQuoteRecord3);
+                        //存储报价记录
+                        sysQuoteRecords.forEach(item->{
+                            item.setSubOrderNo(quoteRespVoHttpResult.getData().getCompanyId());
+                        });
+                        sysQuoteRecordMapper.insertBatch(sysQuoteRecords);
+                        sysQuoteRedisService.refreshQuoteNum(quoteVo.getCompanyId(),quoteInfoVo.getUserid(),sysQuoteRecords);
+                        return quoteRespVoHttpResult;
+                    } else {
+                        InsOrders order = insOrdersService.getById(quoteInfoVo.getOrderNo());
+                        InsOrderStatusEnum insOrderStatusEnum = InsOrderStatusEnum.QUOTE_FAILED;
+                        if (yangGuangAccuracyCalculateResponse.getErrorMessage().contains("重复投保")) {
+                            insOrderStatusEnum = InsOrderStatusEnum.REPEAT_INSURE;
+                        }
+                        String subOrderNo = insOrdersService.responseFailedOrder(quoteVo, ptlAgreementAttribution, order, yangGuangAccuracyCalculateResponse.getErrorMessage(), insOrderStatusEnum);
+                        SysQuoteRecord sysQuoteRecord2 = new SysQuoteRecord(quoteInfoVo.getUserid(),quoteVo.getCompanyId(),quoteInfoVo.getCarInfo().getLicenseNo(),
+                                QuoteNumberConstant.QuoteAction.QUOTE_FAILED.getCode().toString(),QuoteNumberConstant.QuoteResult.FAIL.getCode().toString());
+                        sysQuoteRecords.add(sysQuoteRecord2);
+                        //存储报价记录
+                        sysQuoteRecords.forEach(item->{
+                            item.setSubOrderNo(subOrderNo);
+                        });
+
+                        sysQuoteRecordMapper.insertBatch(sysQuoteRecords);
+                        //刷新redis中的报价次数
+                        sysQuoteRedisService.refreshQuoteNum(quoteVo.getCompanyId(),quoteInfoVo.getUserid(),sysQuoteRecords);
+                        throw new SystemException(yangGuangAccuracyCalculateResponse.getErrorMessage());
                     }
-                    // 处理数据
-                    QuoteRespVo quoteRespVo = getQuoteRespVo(yangGuangAccuracyCalculateResponse1, quoteInfoVo, quoteVo.getAccidentalDrivingVo(), isEnergy);
-
-                    // 设置核心报价车型
-                    quoteRespVo.setCoreModels(carModelList1.toCoreModelsVo());
-                    return responseOrder(yangGuangAccuracyCalculateResponse1, quoteRespVo, ptlAgreementAttribution, quoteInfoVo.getOrderNo(),
-                            quoteVo.getAccidentalDrivingVo());
                 } else {
-                    InsOrders order = insOrdersService.getById(quoteInfoVo.getOrderNo());
-                    InsOrderStatusEnum insOrderStatusEnum = InsOrderStatusEnum.QUOTE_FAILED;
-                    if (yangGuangAccuracyCalculateResponse.getErrorMessage().contains("重复投保")) {
+                    boolean isEnergy = carInfo.isNewEnergy();
+                    if (!yangGuangAccuracyCalculateResponse.getErrorCode().equals("0")) {
+                        QuoteRespVo resp  = new QuoteRespVo();
+                        InsOrders order = insOrdersService.getById(quoteInfoVo.getOrderNo());
+                        InsOrderStatusEnum insOrderStatusEnum = InsOrderStatusEnum.QUOTE_FAILED;
+                        if (yangGuangAccuracyCalculateResponse.getErrorMessage().contains("重复投保")) {
                         insOrderStatusEnum = InsOrderStatusEnum.REPEAT_INSURE;
+                        }
+                        String subOrderNo = insOrdersService.responseFailedOrder(quoteVo, ptlAgreementAttribution, order, yangGuangAccuracyCalculateResponse.getErrorMessage(), insOrderStatusEnum);
+                        SysQuoteRecord sysQuoteRecord2 = new SysQuoteRecord(quoteInfoVo.getUserid(),quoteVo.getCompanyId(),quoteInfoVo.getCarInfo().getLicenseNo(),
+                                QuoteNumberConstant.QuoteAction.QUOTE_FAILED.getCode().toString(),QuoteNumberConstant.QuoteResult.FAIL.getCode().toString());
+                        sysQuoteRecords.add(sysQuoteRecord2);
+                        //存储报价记录
+                        sysQuoteRecords.forEach(item->{
+                            item.setSubOrderNo(subOrderNo);
+                        });
+
+                        sysQuoteRecordMapper.insertBatch(sysQuoteRecords);
+                        //刷新redis中的报价次数
+                        sysQuoteRedisService.refreshQuoteNum(quoteVo.getCompanyId(),quoteInfoVo.getUserid(),sysQuoteRecords);
+                        throw new SystemException(yangGuangAccuracyCalculateResponse.getErrorMessage());
                     }
-                    insOrdersService.responseFailedOrder(quoteVo,ptlAgreementAttribution, order, yangGuangAccuracyCalculateResponse.getErrorMessage(),insOrderStatusEnum);
-                    throw new SystemException(yangGuangAccuracyCalculateResponse.getErrorMessage());
-                }
-            } else {
-                boolean isEnergy = carInfo.isNewEnergy();
-                if (!yangGuangAccuracyCalculateResponseRe.getErrorCode().equals("0")) {
-                    InsOrders order = insOrdersService.getById(quoteInfoVo.getOrderNo());
-                    InsOrderStatusEnum insOrderStatusEnum = InsOrderStatusEnum.QUOTE_FAILED;
-                    if (yangGuangAccuracyCalculateResponseRe.getErrorMessage().contains("重复投保")) {
-                    insOrderStatusEnum = InsOrderStatusEnum.REPEAT_INSURE;
-                    }
-                    insOrdersService.responseFailedOrder(quoteVo,ptlAgreementAttribution, order, yangGuangAccuracyCalculateResponseRe.getErrorMessage(),insOrderStatusEnum);
-                    throw new SystemException(yangGuangAccuracyCalculateResponseRe.getErrorMessage());
-                }
-                // 处理数据
-                QuoteRespVo quoteRespVo = getQuoteRespVo(yangGuangAccuracyCalculateResponseRe, quoteInfoVo, quoteVo.getAccidentalDrivingVo(), isEnergy);
+                    // 处理数据
+                    QuoteRespVo quoteRespVo = getQuoteRespVo(yangGuangAccuracyCalculateResponse, quoteInfoVo, quoteVo.getAccidentalDrivingVo(), isEnergy);
 
                 // 设置核心报价车型
                 quoteRespVo.setCoreModels(carModelList1.toCoreModelsVo());
@@ -213,7 +291,18 @@ public class YangGuangOrderApiServiceImpl implements YangGuangOrderApiService {
                     if (yangGuangAccuracyCalculateResponse1.getErrorMessage().contains("重复投保")) {
                         insOrderStatusEnum = InsOrderStatusEnum.REPEAT_INSURE;
                     }
-                    insOrdersService.responseFailedOrder(quoteVo,ptlAgreementAttribution, order, yangGuangAccuracyCalculateResponse1.getErrorMessage(),insOrderStatusEnum);
+                    String s = insOrdersService.responseFailedOrder(quoteVo, ptlAgreementAttribution, order, yangGuangAccuracyCalculateResponse1.getErrorMessage(), insOrderStatusEnum);
+                    SysQuoteRecord sysQuoteRecord2 = new SysQuoteRecord(quoteInfoVo.getUserid(),quoteVo.getCompanyId(),quoteInfoVo.getCarInfo().getLicenseNo(),
+                            QuoteNumberConstant.QuoteAction.QUOTE_FAILED.getCode().toString(),QuoteNumberConstant.QuoteResult.FAIL.getCode().toString());
+                    sysQuoteRecords.add(sysQuoteRecord2);
+                    //存储报价记录
+                    sysQuoteRecords.forEach(item->{
+                        item.setSubOrderNo(s);
+                    });
+
+                    sysQuoteRecordMapper.insertBatch(sysQuoteRecords);
+                    //刷新redis中的报价次数
+                    sysQuoteRedisService.refreshQuoteNum(quoteVo.getCompanyId(),quoteInfoVo.getUserid(),sysQuoteRecords);
                     throw new SystemException(yangGuangAccuracyCalculateResponse1.getErrorMessage());
                 }
 
@@ -222,15 +311,36 @@ public class YangGuangOrderApiServiceImpl implements YangGuangOrderApiService {
 
                 // 设置核心报价车型
                 quoteRespVo.setCoreModels(carModelList1.toCoreModelsVo());
-                return responseOrder(yangGuangAccuracyCalculateResponse1, quoteRespVo, ptlAgreementAttribution, quoteInfoVo.getOrderNo(),
+                HttpResult<QuoteRespVo> quoteRespVoHttpResult = responseOrder(yangGuangAccuracyCalculateResponse1, quoteRespVo, ptlAgreementAttribution, quoteInfoVo.getOrderNo(),
                         quoteVo.getAccidentalDrivingVo());
+                SysQuoteRecord sysQuoteRecord3 = new SysQuoteRecord(quoteInfoVo.getUserid(),quoteVo.getCompanyId(),quoteInfoVo.getCarInfo().getLicenseNo(),
+                        QuoteNumberConstant.QuoteAction.QUOTE_SUCCESS.getCode().toString(),QuoteNumberConstant.QuoteResult.SUCCESS.getCode().toString());
+                sysQuoteRecords.add(sysQuoteRecord3);
+                //存储报价记录
+                sysQuoteRecords.forEach(item->{
+                    item.setSubOrderNo(quoteRespVoHttpResult.getData().getCompanyId());
+                });
+                sysQuoteRecordMapper.insertBatch(sysQuoteRecords);
+                sysQuoteRedisService.refreshQuoteNum(quoteVo.getCompanyId(),quoteInfoVo.getUserid(),sysQuoteRecords);
+                return quoteRespVoHttpResult;
             } else {
                 InsOrders order = insOrdersService.getById(quoteInfoVo.getOrderNo());
                 InsOrderStatusEnum insOrderStatusEnum = InsOrderStatusEnum.QUOTE_FAILED;
                 if (yangGuangAccuracyCalculateResponse.getErrorMessage().contains("重复投保")) {
                     insOrderStatusEnum = InsOrderStatusEnum.REPEAT_INSURE;
                 }
-                insOrdersService.responseFailedOrder(quoteVo,ptlAgreementAttribution, order, yangGuangAccuracyCalculateResponse.getErrorMessage(),insOrderStatusEnum);
+                String s = insOrdersService.responseFailedOrder(quoteVo, ptlAgreementAttribution, order, yangGuangAccuracyCalculateResponse.getErrorMessage(), insOrderStatusEnum);
+                SysQuoteRecord sysQuoteRecord2 = new SysQuoteRecord(quoteInfoVo.getUserid(),quoteVo.getCompanyId(),quoteInfoVo.getCarInfo().getLicenseNo(),
+                        QuoteNumberConstant.QuoteAction.QUOTE_FAILED.getCode().toString(),QuoteNumberConstant.QuoteResult.FAIL.getCode().toString());
+                sysQuoteRecords.add(sysQuoteRecord2);
+                //存储报价记录
+                sysQuoteRecords.forEach(item->{
+                    item.setSubOrderNo(s);
+                });
+
+                sysQuoteRecordMapper.insertBatch(sysQuoteRecords);
+                //刷新redis中的报价次数
+                sysQuoteRedisService.refreshQuoteNum(quoteVo.getCompanyId(),quoteInfoVo.getUserid(),sysQuoteRecords);
                 throw new SystemException(yangGuangAccuracyCalculateResponse.getErrorMessage());
             }
         } else {
@@ -243,7 +353,18 @@ public class YangGuangOrderApiServiceImpl implements YangGuangOrderApiService {
                 if (yangGuangAccuracyCalculateResponse.getErrorMessage().contains("重复投保")) {
                     insOrderStatusEnum = InsOrderStatusEnum.REPEAT_INSURE;
                 }
-                insOrdersService.responseFailedOrder(quoteVo,ptlAgreementAttribution, order, yangGuangAccuracyCalculateResponse.getErrorMessage(),insOrderStatusEnum);
+                String s = insOrdersService.responseFailedOrder(quoteVo, ptlAgreementAttribution, order, yangGuangAccuracyCalculateResponse.getErrorMessage(), insOrderStatusEnum);
+                SysQuoteRecord sysQuoteRecord2 = new SysQuoteRecord(quoteInfoVo.getUserid(),quoteVo.getCompanyId(),quoteInfoVo.getCarInfo().getLicenseNo(),
+                        QuoteNumberConstant.QuoteAction.QUOTE_FAILED.getCode().toString(),QuoteNumberConstant.QuoteResult.FAIL.getCode().toString());
+                sysQuoteRecords.add(sysQuoteRecord2);
+                //存储报价记录
+                sysQuoteRecords.forEach(item->{
+                    item.setSubOrderNo(s);
+                });
+
+                sysQuoteRecordMapper.insertBatch(sysQuoteRecords);
+                //刷新redis中的报价次数
+                sysQuoteRedisService.refreshQuoteNum(quoteVo.getCompanyId(),quoteInfoVo.getUserid(),sysQuoteRecords);
                 throw new SystemException(yangGuangAccuracyCalculateResponse.getErrorMessage());
             }
             // 处理数据
@@ -251,8 +372,18 @@ public class YangGuangOrderApiServiceImpl implements YangGuangOrderApiService {
 
             // 设置核心报价车型
             quoteRespVo.setCoreModels(carModelList1.toCoreModelsVo());
-            return responseOrder(yangGuangAccuracyCalculateResponse, quoteRespVo, ptlAgreementAttribution, quoteInfoVo.getOrderNo(),
+            HttpResult<QuoteRespVo> quoteRespVoHttpResult = responseOrder(yangGuangAccuracyCalculateResponse, quoteRespVo, ptlAgreementAttribution, quoteInfoVo.getOrderNo(),
                     quoteVo.getAccidentalDrivingVo());
+            SysQuoteRecord sysQuoteRecord3 = new SysQuoteRecord(quoteInfoVo.getUserid(),quoteVo.getCompanyId(),quoteInfoVo.getCarInfo().getLicenseNo(),
+                    QuoteNumberConstant.QuoteAction.QUOTE_SUCCESS.getCode().toString(),QuoteNumberConstant.QuoteResult.SUCCESS.getCode().toString());
+            sysQuoteRecords.add(sysQuoteRecord3);
+            //存储报价记录
+            sysQuoteRecords.forEach(item->{
+                item.setSubOrderNo(quoteRespVoHttpResult.getData().getCompanyId());
+            });
+            sysQuoteRecordMapper.insertBatch(sysQuoteRecords);
+            sysQuoteRedisService.refreshQuoteNum(quoteVo.getCompanyId(),quoteInfoVo.getUserid(),sysQuoteRecords);
+            return quoteRespVoHttpResult;
         }
     }
 

+ 84 - 16
src/main/java/com/ydtech/modules/order/service/impl/YongchengOrderApiServiceImpl.java

@@ -56,7 +56,9 @@ import com.ydtech.modules.order.components.InsOrdersComponents;
 import com.ydtech.modules.order.components.VerificationCodeIdentification;
 import com.ydtech.modules.order.components.gouren.GuorenDuplicateInsuranceComponent;
 import com.ydtech.modules.order.components.yongcheng.YongchengRequestApiComponents;
+import com.ydtech.modules.order.constants.QuoteNumberConstant;
 import com.ydtech.modules.order.constants.UnderwritingStatus;
+import com.ydtech.modules.order.dao.SysQuoteRecordMapper;
 import com.ydtech.modules.order.entity.InsAreaCompany;
 import com.ydtech.modules.order.entity.InsAreaCompanyAccidentalDriving;
 import com.ydtech.modules.order.entity.InsAreaCompanyExternalPolicy;
@@ -70,6 +72,8 @@ import com.ydtech.modules.order.entity.crawler.response.RecognitionResponse;
 import com.ydtech.modules.order.entity.dto.DrivingInsuranceDto;
 import com.ydtech.modules.order.entity.dto.ReadPdfUrlListDto;
 import com.ydtech.modules.order.entity.po.InsTaskImagesBase64;
+import com.ydtech.modules.order.entity.po.SysQuoteConfig;
+import com.ydtech.modules.order.entity.po.SysQuoteRecord;
 import com.ydtech.modules.order.entity.vo.*;
 import com.ydtech.modules.order.service.*;
 import com.ydtech.modules.order.utils.InsuranceLog;
@@ -176,6 +180,15 @@ public class YongchengOrderApiServiceImpl implements YongchengOrderApiService {
     @Autowired
     private PtlAgreementAttributionService ptlAgreementAttributionService;
 
+    @Autowired
+    private SysQuoteRedisService sysQuoteRedisService;
+
+    @Autowired
+    private SysQuoteConfigService sysQuoteConfigService;
+
+    @Autowired
+    private SysQuoteRecordMapper sysQuoteRecordMapper;
+
     public void gainVehicleModel(YcConfigureParameters ycConfigureParameters, CarInfoVo carInfo, CoreModelsVo coreModelsVo) {
         CarModel_Req carModelReq = new CarModel_Req();
         carModelReq.setFrameNo(carInfo.getFrameNo());
@@ -315,9 +328,11 @@ public class YongchengOrderApiServiceImpl implements YongchengOrderApiService {
      * @return
      * @throws JsonProcessingException
      */
-    private RuoteResponse getResponse(Ruote m, String vinNo, List<String> requestInfoList, BaseQuoteInfoVo yaQuoteInfoVo) throws JsonProcessingException {
+    private RuoteResponse getResponse(Ruote m, String vinNo, List<String> requestInfoList, BaseQuoteInfoVo yaQuoteInfoVo,String companyId,Integer maxQuoteNum,List<SysQuoteRecord> sysQuoteRecords) throws JsonProcessingException {
         boolean boo;
         RuoteResponse rr = yongchengRequestApiComponents.newPremiumXnyCalculation(m);
+        maxQuoteNum--;
+
         //存储 报价返回的查询码  交强和商业
         if (rr.getVhl() != null) {
             if (rr.getVhl().getCQryCdeJQ() != null) {
@@ -369,7 +384,13 @@ public class YongchengOrderApiServiceImpl implements YongchengOrderApiService {
 
             if (!jq.isEmpty() || !sy.isEmpty()) {
                 InsuranceLog.infoLog(InsuranceEnum.AICS.getPinyin(), "\n\n---------> {} - 重复投保处理", vinNo);
-                return this.getResponse(m, vinNo, requestInfoList, yaQuoteInfoVo);
+                SysQuoteRecord sysQuoteRecord = new SysQuoteRecord(yaQuoteInfoVo.getUserid(),companyId,yaQuoteInfoVo.getCarInfo().getLicenseNo(),
+                        QuoteNumberConstant.QuoteAction.DATE_DEAL.getCode().toString(),QuoteNumberConstant.QuoteResult.FAIL.getCode().toString());
+                sysQuoteRecords.add(sysQuoteRecord);
+                if(maxQuoteNum <= 0){
+                    return rr;
+                }
+                return this.getResponse(m, vinNo, requestInfoList, yaQuoteInfoVo,companyId,maxQuoteNum,sysQuoteRecords);
             }
 
         }
@@ -378,21 +399,39 @@ public class YongchengOrderApiServiceImpl implements YongchengOrderApiService {
         boo = reinsurance(rr, m);
         if (!boo) {
             InsuranceLog.infoLog(InsuranceEnum.AICS.getPinyin(), "\n\n---------> {} - 转保处理", vinNo);
-            return this.getResponse(m, vinNo, requestInfoList, yaQuoteInfoVo);
+            SysQuoteRecord sysQuoteRecord = new SysQuoteRecord(yaQuoteInfoVo.getUserid(),companyId,yaQuoteInfoVo.getCarInfo().getLicenseNo(),
+                    QuoteNumberConstant.QuoteAction.TRANSFER_INSRUANCE.getCode().toString(),QuoteNumberConstant.QuoteResult.FAIL.getCode().toString());
+            sysQuoteRecords.add(sysQuoteRecord);
+            if(maxQuoteNum <= 0){
+                return rr;
+            }
+            return this.getResponse(m, vinNo, requestInfoList, yaQuoteInfoVo,companyId,maxQuoteNum,sysQuoteRecords);
         }
 
         //3、商业险日期处理
         boo = biRepetitionInsure(rr, m, requestInfoList);
         if (!boo) {
             InsuranceLog.infoLog(InsuranceEnum.AICS.getPinyin(), "\n\n---------> {} - 商业险日期处理", vinNo);
-            return this.getResponse(m, vinNo, requestInfoList, yaQuoteInfoVo);
+            SysQuoteRecord sysQuoteRecord = new SysQuoteRecord(yaQuoteInfoVo.getUserid(),companyId,yaQuoteInfoVo.getCarInfo().getLicenseNo(),
+                    QuoteNumberConstant.QuoteAction.DATE_DEAL.getCode().toString(),QuoteNumberConstant.QuoteResult.FAIL.getCode().toString());
+            sysQuoteRecords.add(sysQuoteRecord);
+            if(maxQuoteNum <= 0){
+                return rr;
+            }
+            return this.getResponse(m, vinNo, requestInfoList, yaQuoteInfoVo,companyId,maxQuoteNum,sysQuoteRecords);
         }
 
         // 转保验证码
         boo = reinsuranceCodeError(rr, m);
         if (!boo) {
             InsuranceLog.infoLog(InsuranceEnum.AICS.getPinyin(), "\n\n---------> {} - 转保处理", vinNo);
-            return this.getResponse(m, vinNo, requestInfoList, yaQuoteInfoVo);
+            SysQuoteRecord sysQuoteRecord = new SysQuoteRecord(yaQuoteInfoVo.getUserid(),companyId,yaQuoteInfoVo.getCarInfo().getLicenseNo(),
+                    QuoteNumberConstant.QuoteAction.TRANSFER_INSRUANCE.getCode().toString(),QuoteNumberConstant.QuoteResult.FAIL.getCode().toString());
+            sysQuoteRecords.add(sysQuoteRecord);
+            if(maxQuoteNum <= 0){
+                return rr;
+            }
+            return this.getResponse(m, vinNo, requestInfoList, yaQuoteInfoVo,companyId,maxQuoteNum,sysQuoteRecords);
         }
         return rr;
     }
@@ -432,37 +471,54 @@ public class YongchengOrderApiServiceImpl implements YongchengOrderApiService {
      */
     @Override
     public HttpResult quoteApi(BaseQuoteVo<AccidentalDrivingVo> quoteVo) throws JsonProcessingException {
+        Integer maxQuoteNum = quoteVo.getMaxQuoteNum();
 
         List<String> requestInfoList = new ArrayList<>();
+
+
         //获取报价信息
         BaseQuoteInfoVo yaQuoteInfoVo = insOrdersComponents.getQuoteInfo(quoteVo.getOrderNo(), quoteVo.getKinds());
         CoreModelsVo coreModelsVo = new CoreModelsVo();
 
+        //查询订单信息
+        InsOrders order = insOrdersService.getById(yaQuoteInfoVo.getOrderNo());
+
         //build参数
         Ruote m = this.builderParams(quoteVo, yaQuoteInfoVo, coreModelsVo);
 
+        List<SysQuoteRecord> sysQuoteRecords = new ArrayList<>();
         //递归报价
-        RuoteResponse rr = this.getResponse(m, yaQuoteInfoVo.getCarInfo().getVinNo(), requestInfoList, yaQuoteInfoVo);
-
-        //错误信息
-        StringBuilder errorInfo = this.getErrorInfo(rr);
-        if (StringUtils.isNotEmpty(errorInfo)) {
-            throw new SystemException(errorInfo.toString());
-        }
-
-        //查询订单信息
-        InsOrders order = insOrdersService.getById(yaQuoteInfoVo.getOrderNo());
+        RuoteResponse rr = this.getResponse(m, yaQuoteInfoVo.getCarInfo().getVinNo(), requestInfoList, yaQuoteInfoVo,quoteVo.getCompanyId(),maxQuoteNum,sysQuoteRecords);
 
         //报价失败
         if (!"000000".equals(rr.getHead().getErrorCode())) {
             //保存报价失败的子订单
             InsOrderStatusEnum insOrderStatusEnum = InsOrderStatusEnum.QUOTE_FAILED;
+
+            //错误信息
+            StringBuilder errorInfo = this.getErrorInfo(rr);
+            if (StringUtils.isNotEmpty(errorInfo)) {
+                rr.getHead().setErrorMessage(errorInfo.toString());
+            }
+
             if(rr.getHead().getErrorMessage().contains("重复投保"))
             {
                 insOrderStatusEnum = InsOrderStatusEnum.REPEAT_INSURE;
             }
+
             PtlAgreementAttribution ptlAgreementAttribution = ptlAgreementAttributionService.getById(quoteVo.getAgreementId());
-            insOrdersService.responseFailedOrder(quoteVo,ptlAgreementAttribution, order,rr.getHead().getErrorMessage(),insOrderStatusEnum);
+            String subOrderNo = insOrdersService.responseFailedOrder(quoteVo,ptlAgreementAttribution, order,rr.getHead().getErrorMessage(),insOrderStatusEnum);
+            SysQuoteRecord sysQuoteRecord = new SysQuoteRecord(yaQuoteInfoVo.getUserid(),quoteVo.getCompanyId(),yaQuoteInfoVo.getCarInfo().getLicenseNo(),
+                    QuoteNumberConstant.QuoteAction.QUOTE_FAILED.getCode().toString(),QuoteNumberConstant.QuoteResult.FAIL.getCode().toString());
+            sysQuoteRecords.add(sysQuoteRecord);
+            //存储报价记录
+            sysQuoteRecords.forEach(item->{
+                item.setSubOrderNo(subOrderNo);
+            });
+
+            sysQuoteRecordMapper.insertBatch(sysQuoteRecords);
+            //刷新redis中的报价次数
+            sysQuoteRedisService.refreshQuoteNum(quoteVo.getCompanyId(),yaQuoteInfoVo.getUserid(),sysQuoteRecords);
             return HttpResult.error(rr.getHead().getErrorMessage());
         }
 
@@ -470,6 +526,15 @@ public class YongchengOrderApiServiceImpl implements YongchengOrderApiService {
         //8 生成订单
         InsAreaCompany iac = responseOrder(order, quoteRespVo, rr, quoteVo);
 
+        SysQuoteRecord sysQuoteRecord = new SysQuoteRecord(yaQuoteInfoVo.getUserid(),quoteVo.getCompanyId(),yaQuoteInfoVo.getCarInfo().getLicenseNo(),
+                QuoteNumberConstant.QuoteAction.QUOTE_SUCCESS.getCode().toString(),QuoteNumberConstant.QuoteResult.SUCCESS.getCode().toString());
+        sysQuoteRecords.add(sysQuoteRecord);
+        //存储报价记录
+        sysQuoteRecords.forEach(item->{
+            item.setSubOrderNo(iac.getId());
+        });
+        sysQuoteRecordMapper.insertBatch(sysQuoteRecords);
+
         quoteRespVo.setCompanyId(iac.getId());
 
         if (CollUtil.isNotEmpty(requestInfoList)) {
@@ -491,6 +556,9 @@ public class YongchengOrderApiServiceImpl implements YongchengOrderApiService {
             }
         }
 
+        //刷新redis中的报价次数
+        sysQuoteRedisService.refreshQuoteNum(quoteVo.getCompanyId(),yaQuoteInfoVo.getUserid(),sysQuoteRecords);
+
         return HttpResult.ok("报价成功", quoteRespVo);
 
     }

+ 48 - 1
src/main/java/com/ydtech/modules/order/service/impl/ZhongMeiOrderApiServiceImpl.java

@@ -19,7 +19,9 @@ import com.ydtech.modules.order.components.ZhongmeiRequestApiComponents;
 import com.ydtech.modules.order.components.vehicle.QueryVehicleComponents;
 import com.ydtech.modules.order.components.zhongmei.ZhongmeiRepeatInsuranceComponents;
 import com.ydtech.modules.order.constants.InsuranceTypeCorrespondence;
+import com.ydtech.modules.order.constants.QuoteNumberConstant;
 import com.ydtech.modules.order.constants.UnderwritingStatus;
+import com.ydtech.modules.order.dao.SysQuoteRecordMapper;
 import com.ydtech.modules.order.entity.*;
 import com.ydtech.modules.order.entity.api.zhongmei.BaseRequestHead;
 import com.ydtech.modules.order.entity.api.zhongmei.constants.enums.AuditStatusEnum;
@@ -32,6 +34,7 @@ import com.ydtech.modules.order.entity.config.ZmConfigureParameters;
 import com.ydtech.modules.order.entity.dto.ReadPdfUrlListDto;
 import com.ydtech.modules.order.entity.filter.CarModelsFilterUtils;
 import com.ydtech.modules.order.entity.po.InsTaskImagesBase64;
+import com.ydtech.modules.order.entity.po.SysQuoteRecord;
 import com.ydtech.modules.order.entity.vo.AccidentalDrivingVo;
 import com.ydtech.modules.order.entity.vo.BaseQuoteInfoVo;
 import com.ydtech.modules.order.entity.vo.BaseQuoteVo;
@@ -96,6 +99,10 @@ public class ZhongMeiOrderApiServiceImpl implements ZhongMeiOrderApiService {
 
     private final InsImagesUploadCacheComponents insImagesUploadCacheComponents;
 
+    private final SysQuoteRecordMapper sysQuoteRecordMapper;
+
+    private final SysQuoteRedisService sysQuoteRedisService;
+
     @Value("${upload.file.path}")
     private String uploadFilePath;
 
@@ -161,6 +168,9 @@ public class ZhongMeiOrderApiServiceImpl implements ZhongMeiOrderApiService {
 
     @Override
     public HttpResult<QuoteRespVo> quote(BaseQuoteInfoVo quoteInfo, BaseQuoteVo<AccidentalDrivingVo> zmQuoteVo) {
+        Integer maxQuoteNum = zmQuoteVo.getMaxQuoteNum();
+        List<SysQuoteRecord> sysQuoteRecords = new ArrayList<>();
+
         // 1. 协议id获取配置实体
         String agreementId = zmQuoteVo.getAgreementId();
         // 账号信息
@@ -199,10 +209,26 @@ public class ZhongMeiOrderApiServiceImpl implements ZhongMeiOrderApiService {
         quotedPriceRequest.setHead(baseRequestHead);
 
         QuotedPriceResponse quotedPriceResponse = zhongmeiRequestApiComponents.quotedPrice(quotedPriceRequest, QuotedPriceResponse.class);
+        maxQuoteNum--;
+        SysQuoteRecord sysQuoteRecord = new SysQuoteRecord(quoteInfo.getUserid(),zmQuoteVo.getCompanyId(),quoteInfo.getCarInfo().getLicenseNo(),
+                QuoteNumberConstant.QuoteAction.DATE_DEAL.getCode().toString(),QuoteNumberConstant.QuoteResult.FAIL.getCode().toString());
+        sysQuoteRecords.add(sysQuoteRecord);
+
         if ("-1".equals(quotedPriceResponse.getHead().getReturnCode())) {
             if (StringUtils.isNotEmpty(quotedPriceResponse.getHead().getReturnMessage()) && quotedPriceResponse.getHead().getReturnMessage().contains("商业险重复投保") && quotedPriceResponse.getHead().getReturnMessage().contains("重复投保的本公司的保单信息")) {
                 quotedPriceResponse = zhongmeiRepeatInsuranceComponents.dealRepeatDateFormError(quotedPriceRequest, quotedPriceResponse,
                         quoteInfo);
+                maxQuoteNum--;
+                SysQuoteRecord deplSysQuoteRecord = new SysQuoteRecord(quoteInfo.getUserid(),zmQuoteVo.getCompanyId(),quoteInfo.getCarInfo().getLicenseNo(),
+                        QuoteNumberConstant.QuoteAction.DATE_DEAL.getCode().toString(),QuoteNumberConstant.QuoteResult.FAIL.getCode().toString());
+                sysQuoteRecords.add(deplSysQuoteRecord);
+
+                if(maxQuoteNum < 0) {
+                    sysQuoteRecordMapper.insertBatch(sysQuoteRecords);
+                    //刷新redis中的报价次数
+                    sysQuoteRedisService.refreshQuoteNum(zmQuoteVo.getCompanyId(), quoteInfo.getUserid(), sysQuoteRecords);
+                    throw new SystemException("报价次数限制");
+                }
             }
         }
         QuoteRespVo quoteRespVo = getQuoteRespVo(quotedPriceResponse, quoteInfo);
@@ -215,12 +241,33 @@ public class ZhongMeiOrderApiServiceImpl implements ZhongMeiOrderApiService {
         }
         if (repeatFlag) {
             quotedPriceResponse = zhongmeiRepeatInsuranceComponents.dealRepeatDate(quotedPriceRequest, quotedPriceResponse, quoteInfo);
+            maxQuoteNum--;
+            SysQuoteRecord deplSysQuoteRecord = new SysQuoteRecord(quoteInfo.getUserid(),zmQuoteVo.getCompanyId(),quoteInfo.getCarInfo().getLicenseNo(),
+                    QuoteNumberConstant.QuoteAction.DATE_DEAL.getCode().toString(),QuoteNumberConstant.QuoteResult.FAIL.getCode().toString());
+            sysQuoteRecords.add(deplSysQuoteRecord);
+
+            if(maxQuoteNum < 0) {
+                sysQuoteRecordMapper.insertBatch(sysQuoteRecords);
+                //刷新redis中的报价次数
+                sysQuoteRedisService.refreshQuoteNum(zmQuoteVo.getCompanyId(), quoteInfo.getUserid(), sysQuoteRecords);
+                throw new SystemException("报价次数限制");
+            }
             quoteRespVo = getQuoteRespVo(quotedPriceResponse, quoteInfo);
         }
 
         // 核心返回车型
         quoteRespVo.setCoreModels(simpleStadarCarDTO.toCoreModelsVo());
-        return responseOrder(quotedPriceResponse, quoteRespVo, ptlAgreementAttribution, quoteInfo,zmQuoteVo.getAccidentalDrivingVo());
+        HttpResult<QuoteRespVo> quoteRespVoHttpResult = responseOrder(quotedPriceResponse, quoteRespVo, ptlAgreementAttribution, quoteInfo, zmQuoteVo.getAccidentalDrivingVo());
+        SysQuoteRecord deplSysQuoteRecord = new SysQuoteRecord(quoteInfo.getUserid(),zmQuoteVo.getCompanyId(),quoteInfo.getCarInfo().getLicenseNo(),
+                QuoteNumberConstant.QuoteAction.QUOTE_SUCCESS.getCode().toString(),QuoteNumberConstant.QuoteResult.SUCCESS.getCode().toString());
+        sysQuoteRecords.add(deplSysQuoteRecord);
+        sysQuoteRecords.forEach(item->{
+            item.setSubOrderNo(quoteRespVoHttpResult.getData().getCompanyId());
+        });
+        sysQuoteRecordMapper.insertBatch(sysQuoteRecords);
+        //刷新redis中的报价次数
+        sysQuoteRedisService.refreshQuoteNum(zmQuoteVo.getCompanyId(), quoteInfo.getUserid(), sysQuoteRecords);
+        return quoteRespVoHttpResult;
     }
 
 

+ 2 - 1
src/main/java/com/ydtech/modules/order/service/impl/ZijinOrderApiServiceImpl.java

@@ -159,7 +159,8 @@ public class ZijinOrderApiServiceImpl implements ZijinOrderApiService {
             {
                 insOrderStatusEnum = InsOrderStatusEnum.REPEAT_INSURE;
             }
-            insOrdersService.responseFailedOrder(quoteVo,ptlAgreementAttribution, order,calculatePremiumResponse.getRtnMsg(),insOrderStatusEnum);
+            String subOrderNo = insOrdersService.responseFailedOrder(quoteVo, ptlAgreementAttribution, order, calculatePremiumResponse.getRtnMsg(), insOrderStatusEnum);
+
             throw new SystemException(calculatePremiumResponse.getRtnMsg());
         }
 

+ 27 - 0
src/main/java/com/ydtech/modules/order/timer/QuoteNumTimer.java

@@ -0,0 +1,27 @@
+package com.ydtech.modules.order.timer;
+
+import com.ydtech.modules.order.constants.QuoteNumberConstant;
+import com.ydtech.modules.order.service.SysQuoteRedisService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Component;
+
+import java.util.List;
+
+@Slf4j
+@Component
+public class QuoteNumTimer {
+
+    @Autowired
+    private SysQuoteRedisService sysQuoteRedisService;
+
+    //每天0点清空报价次数的redis数据
+    @Scheduled(cron = "0 0 0 * * ?")
+    public void executeAtMidnight() {
+        List<String> keys = sysQuoteRedisService.searchKeysWithScan(QuoteNumberConstant.QUOTE_NUMBER_KEY + "*");
+        keys.forEach(key->{
+            sysQuoteRedisService.delQuoteRedis(key);
+        });
+    }
+}

+ 10 - 7
src/main/resources/mapper/modules/admin/SysUserMapper.xml

@@ -21,10 +21,7 @@
     </resultMap>
 
     <sql id="Sys_User_Column_List">
-        su
-        .
-        id
-        ,
+        su.id,
             su.name,
             su.mobile,
             su.status,
@@ -51,8 +48,11 @@
 
     <sql id="Sys_User_Where_Clause">
         <where>
+            <if test="sysUser.id != null &amp;&amp; sysUser.name != ''">
+                and su.id = #{sysUser.id}
+            </if>
             <if test="sysUser.name != null &amp;&amp; sysUser.name != ''">
-                and su.name = #{sysUser.name}
+                and (su.name = #{sysUser.name} or su.id = #{sysUser.name})
             </if>
             <if test="sysUser.mobile != null &amp;&amp; sysUser.mobile != ''">
                 and su.mobile = #{sysUser.mobile}
@@ -77,7 +77,7 @@
     <sql id="Sys_User_Where_Clause_deptName">
         <where>
             <if test="sysUser.name != null &amp;&amp; sysUser.name != ''">
-                and su.name = #{sysUser.name}
+                and (su.name = #{sysUser.name} or su.id = #{sysUser.name})
             </if>
             <if test="sysUser.mobile != null &amp;&amp; sysUser.mobile != ''">
                 and su.mobile = #{sysUser.mobile}
@@ -92,6 +92,9 @@
             <if test="sysUser.deptName != null &amp;&amp; sysUser.deptName != ''">
                 and sd.name like concat('%',#{sysUser.deptName},'%')
             </if>
+            <if test="sysUser.id != null and sysUser.id!= ''">
+                and su.id = #{sysUser.id}
+            </if>
         </where>
     </sql>
 
@@ -103,7 +106,7 @@
             <include refid="Sys_User_Where_Clause"></include>
         </if>
 
-        <if test="sysUser.deptName != null &amp;&amp; sysUser.deptName != ''">
+         <if test="sysUser.deptName != null &amp;&amp; sysUser.deptName != ''">
             <include refid="Sys_User_Where_Clause_deptName"></include>
         </if>
     </select>

+ 32 - 0
src/main/resources/mapper/modules/esm/EsmInsCompanyMapper.xml

@@ -98,4 +98,36 @@
             insurance_company_id,
             insurance_company
     </select>
+    <select id="getExternalAgreementCompanyList" resultType="com.ydtech.modules.esm.model.vo.res.EsmInsCompanyResVo">
+        SELECT DISTINCT
+            insurance_company_id AS id,
+            insurance_company AS NAME
+        FROM
+            ptl_agreement
+        <where>
+            is_external = '1'
+            <if test="name != null and name != ''">
+                and insurance_company like  concat('%',#{name},'%')
+            </if>
+
+        </where>
+        GROUP BY
+            insurance_company_id,
+            insurance_company
+    </select>
+
+    <select id="liveCompanyList" resultType="com.ydtech.modules.esm.model.vo.res.EsmInsCompanyResVo">
+        SELECT
+            eic.id,
+            eic.name,
+            eic.namesimple,
+            eic.remark
+        FROM
+            ptl_agreement pa
+                LEFT JOIN esm_ins_company eic ON pa.insurance_company_id = eic.id
+        where
+            pa.is_external = 0
+        GROUP BY
+            eic.id
+    </select>
 </mapper>

+ 280 - 0
src/main/resources/mapper/modules/order/SysQuoteRecordMapper.xml

@@ -0,0 +1,280 @@
+<?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.ydtech.modules.order.dao.SysQuoteRecordMapper">
+
+    <insert id="insertBatch">
+        INSERT INTO sys_quote_record (id, user_id, company_id, sub_order_no, license_no, action, result, status, agent, operator, create_time)
+        VALUES
+        <foreach collection="list" item="item" index="index" separator=",">
+            (#{item.id}, #{item.userId}, #{item.companyId}, #{item.subOrderNo}, #{item.licenseNo}, #{item.action}, #{item.result}, #{item.status}, #{item.agent}, #{item.operator}, #{item.createTime})
+        </foreach>
+    </insert>
+
+    <select id="getQuoteRequestRecordPage" resultType="com.ydtech.modules.order.entity.vo.QuoteDetailsVo">
+        SELECT
+            eic.namesimple as company,
+            sqr.*
+        FROM
+            sys_quote_record sqr
+                LEFT JOIN esm_ins_company eic ON sqr.company_id = eic.id
+                LEFT JOIN sys_user su ON sqr.user_id = su.id
+                LEFT JOIN sys_dept sd ON su.dept_id = sd.id
+        WHERE
+            1=1
+        <if test="param.deptId != null and param.deptId!= ''">
+            AND sd.id like '${param.deptId}%'
+        </if>
+
+    </select>
+
+    <select id="getQuoteRecordPage" resultType="com.ydtech.modules.order.entity.vo.QuoteDetailsVo">
+        SELECT
+            su.id,
+            su.NAME,
+            su.mobile,
+            sqr.*
+        FROM
+            sys_quote_record sqr
+                LEFT JOIN sys_user su ON sqr.user_id = su.id
+                LEFT JOIN sys_dept sd ON su.dept_id = sd.id
+        WHERE
+            1=1
+            <if test="param.subOrderNo!= null and param.subOrderNo!= ''">
+                AND sqr.sub_order_no = #{param.subOrderNo}
+            </if>
+            <if test="param.startTime != null and param.startTime!= ''">
+                AND sqr.create_time BETWEEN #{param.startTime}
+                    AND #{param.endTime}
+            </if>
+            <if test="param.licenseNo!= null and param.licenseNo!= ''">
+                AND sqr.license_no = #{param.licenseNo}
+            </if>
+            <if test="param.result!= null and param.result!= ''">
+                AND sqr.result = #{param.result}
+            </if>
+            <if test="param.agent != null and param.agent != ''">
+                AND sqr.agent = #{param.agent}
+            </if>
+            <if test="param.operator != null and param.operator != ''">
+                AND sqr.operator = #{param.operator}
+            </if>
+            <if test="param.deptId!= null and param.deptId!= ''">
+                AND sd.id like '${param.deptId}%'
+            </if>
+            <if test="param.action != null and param.action!= ''">
+                AND sqr.action = #{param.action}
+            </if>
+        ORDER BY sqr.create_time DESC
+    </select>
+
+    <select id="getQuoteDetails" resultType="com.ydtech.modules.order.entity.vo.QuoteDetailsVo">
+        WITH day_all_num AS (
+        SELECT
+        user_id,
+        company_id,
+        COALESCE ( SUM( count ), 0 ) AS count
+        FROM
+        ( SELECT user_id, company_id, COUNT( id ) AS count FROM sys_quote_record WHERE DATE( create_time ) = CURRENT_DATE GROUP BY user_id, company_id ) AS subquery
+        GROUP BY
+        user_id,
+        company_id
+        ),
+        day_all_order AS (
+        SELECT
+        user_id,
+        company_id,
+        COALESCE ( SUM( count ), 0 ) AS count
+        FROM
+        (
+        SELECT
+        user_id,
+        company_id,
+        COUNT( DISTINCT sub_order_no ) AS count
+        FROM
+        sys_quote_record
+        WHERE
+        DATE( create_time ) = CURRENT_DATE
+        GROUP BY
+        user_id,
+        sub_order_no,
+        company_id
+        ) AS subquery
+        GROUP BY
+        user_id,
+        company_id
+        ),
+        day_cover_order AS (
+        SELECT
+        user_id,
+        company_id,
+        COALESCE ( SUM( count ), 0 ) AS count
+        FROM
+        (
+        SELECT
+        sqr.user_id,
+        sqr.company_id,
+        COUNT( DISTINCT sqr.sub_order_no ) AS count
+        FROM
+        sys_quote_record sqr
+        LEFT JOIN ins_area_company iac ON sqr.sub_order_no = iac.id
+        WHERE
+        iac.orderstatus = 3
+        AND DATE( sqr.create_time ) = CURRENT_DATE
+        GROUP BY
+        sqr.user_id,
+        sqr.sub_order_no,
+        company_id
+        ) AS subquery
+        GROUP BY
+        user_id,
+        company_id
+        ),
+        whole_all_order AS (
+        SELECT
+        user_id,
+        company_id,
+        COALESCE ( SUM( count ), 0 ) AS count
+        FROM
+        ( SELECT user_id, company_id, COUNT( DISTINCT sub_order_no ) AS count FROM sys_quote_record GROUP BY user_id, sub_order_no, company_id ) AS subquery
+        GROUP BY
+        user_id,
+        company_id
+        ),
+        whole_cover_order AS (
+        SELECT
+        user_id,
+        company_id,
+        COALESCE ( SUM( count ), 0 ) AS count
+        FROM
+        (
+        SELECT
+        sqr.user_id,
+        sqr.company_id,
+        COUNT( DISTINCT sqr.sub_order_no ) AS count
+        FROM
+        sys_quote_record sqr
+        LEFT JOIN ins_area_company iac ON sqr.sub_order_no = iac.id
+        WHERE
+        iac.orderstatus = 3
+        GROUP BY
+        sqr.user_id,
+        sqr.sub_order_no,
+        sqr.company_id
+        ) AS subquery
+        GROUP BY
+        user_id,
+        company_id
+        ) SELECT
+        su.dept_id,
+        sd.NAME AS dept_name,
+        su.NAME,
+        su.mobile,
+        sqr.user_id,
+        sqr.company_id,
+        eic.namesimple AS company,
+        COUNT( CASE WHEN sqr.result = 0 THEN 1 END ) AS failed_count,
+        COUNT( CASE WHEN sqr.result = 1 THEN 1 END ) AS success_count,
+        COALESCE ( dan.count, 0 ) AS num_count,
+        COALESCE ( dao.count, 0 ) AS day_all_order,
+        COALESCE ( dco.count, 0 ) AS day_cover_order,
+        COALESCE ( wao.count, 0 ) AS whole_all_order,
+        COALESCE ( wco.count, 0 ) AS whole_cover_order,
+        COALESCE (( COALESCE ( dco.count, 0 ) / NULLIF( dao.count, 0 )), 0 ) * 100 AS rate
+        FROM
+        sys_quote_record sqr
+        LEFT JOIN sys_user su ON sqr.user_id = su.id
+        LEFT JOIN sys_dept sd ON su.dept_id = sd.id
+        LEFT JOIN esm_ins_company eic ON eic.id = sqr.company_id
+        LEFT JOIN day_all_order dao ON sqr.user_id = dao.user_id
+        AND sqr.company_id = dao.company_id
+        LEFT JOIN day_cover_order dco ON sqr.user_id = dco.user_id
+        AND dco.company_id = sqr.company_id
+        LEFT JOIN whole_all_order wao ON sqr.user_id = wao.user_id
+        AND wao.company_id = sqr.company_id
+        LEFT JOIN whole_cover_order wco ON sqr.user_id = wco.user_id
+        AND wco.company_id = sqr.company_id
+        LEFT JOIN day_all_num dan ON sqr.user_id = dan.user_id
+        AND dan.company_id = sqr.company_id
+        WHERE
+        1 = 1
+        <if test="param.companyId!= null and param.companyId!= ''">
+            AND sqr.company_id = #{param.companyId}
+        </if>
+        <if test="param.agent!= null and param.agent!= ''">
+            AND (su.name = #{param.agent} or su.mobile = #{param.agent})
+        </if>
+        <if test="param.agentId!= null and param.agentId != ''">
+        AND sqr.user_id = #{param.agentId}
+        </if>
+        <if test="param.deptId!= null and param.deptId!= ''">
+            AND sd.id like '${param.deptId}%'
+        </if>
+        GROUP BY
+        sqr.user_id,
+        company_id,
+        eic.namesimple,
+        dao.count,
+        dco.count,
+        wao.count,
+        wco.count,
+        su.dept_id,
+        sd.NAME,
+        su.NAME,
+        su.mobile
+    </select>
+
+    <select id="getQuoteRatio" resultType="BigDecimal">
+        WITH
+            day_all_order AS (
+                SELECT user_id, COALESCE(SUM(count), 0) AS count
+                FROM (
+                         SELECT user_id, COUNT(DISTINCT sub_order_no) AS count
+                         FROM sys_quote_record
+                         WHERE  DATE(create_time) = CURRENT_DATE
+                         AND company_id  = #{companyId}
+                         AND user_id = #{userId}
+                         GROUP BY user_id, sub_order_no
+                     ) AS subquery
+                GROUP BY user_id
+            ),
+            day_cover_order AS (
+                SELECT user_id, COALESCE(SUM(count), 0) AS count
+                FROM (
+                         SELECT sqr.user_id, COUNT(DISTINCT sqr.sub_order_no) AS count
+                         FROM sys_quote_record sqr
+                                  LEFT JOIN ins_area_company iac ON sqr.sub_order_no = iac.id
+                         WHERE iac.orderstatus = 3 AND  DATE(sqr.create_time) = CURRENT_DATE
+                           AND iac.company_id  = #{companyId}
+                           AND sqr.user_id = #{userId}
+                         GROUP BY sqr.user_id, sqr.sub_order_no
+                     ) AS subquery
+                GROUP BY user_id
+            )
+        SELECT
+                COALESCE((COALESCE(day_cover_order.count, 0) / NULLIF(day_all_order.count, 0)),0) * 100 AS rate
+        FROM
+            sys_quote_record sqr
+                LEFT JOIN sys_user su ON sqr.user_id = su.id
+                LEFT JOIN sys_dept sd ON su.dept_id = sd.id
+                LEFT JOIN esm_ins_company eic ON eic.id = sqr.company_id
+                LEFT JOIN day_all_order ON sqr.user_id = day_all_order.user_id
+                LEFT JOIN day_cover_order ON sqr.user_id = day_cover_order.user_id
+        WHERE
+            1=1
+          AND sqr.user_id = #{userId}
+          and sqr.company_id = #{companyId}
+            and sqr.create_time BETWEEN CURDATE() AND DATE_ADD(CURDATE(), INTERVAL 1 DAY)
+        GROUP BY
+            sqr.user_id,
+            company_id,
+            eic.namesimple,
+            day_all_order.count,
+            day_cover_order.count,
+            su.dept_id,
+            sd.NAME,
+            su.NAME,
+            su.mobile
+    </select>
+</mapper>

+ 40 - 0
src/main/resources/mapper/modules/order/SysQuoteUserConfigAppendMapper.xml

@@ -0,0 +1,40 @@
+<?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.ydtech.modules.order.dao.SysQuoteUserConfigAppendMapper">
+
+    <select id="getAppendUserQuote" resultType="com.ydtech.modules.order.entity.vo.QuoteDetailsVo">
+        SELECT
+            eic.namesimple as company,
+            sd.id,
+            sd.name as dept_name,
+            sd.id as dept_id,
+            su.name,
+            su.mobile,
+            squca.*
+        FROM
+            sys_quote_user_config_append squca
+                LEFT JOIN sys_user su ON squca.user_id = su.id
+                LEFT JOIN sys_dept sd ON su.dept_id = sd.id
+                left join esm_ins_company eic on squca.company_id = eic.id
+        WHERE
+            1=1
+        <if test="param.companyId!= null and param.companyId!= ''">
+            AND squca.company_id = #{param.companyId}
+        </if>
+        <if test="param.startTime != null and param.startTime!= ''">
+            AND squca.create_time &gt;= #{param.startTime}
+            AND squca.create_time &lt;= #{param.endTime}
+        </if>
+        <if test="param.createBy != null and param.createBy!= ''">
+            AND squca.create_by = #{param.createBy}
+        </if>
+        <if test="param.agent != null and param.agent!= ''">
+            AND (squca.user_id = #{param.agent} or su.`name` = #{param.agent})
+        </if>
+        ORDER BY
+            squca.create_time DESC
+    </select>
+
+</mapper>

+ 29 - 0
src/main/resources/mapper/modules/order/SysQuoteUserMapper.xml

@@ -0,0 +1,29 @@
+<?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.ydtech.modules.order.dao.SysQuoteUserMapper">
+
+    <insert id="insertBatch">
+        INSERT INTO sys_quote_user (id, config_id, user_id)
+        VALUES
+        <foreach collection="list" item="item" index="index" separator=",">
+            (#{item.id}, #{item.configId}, #{item.userId})
+        </foreach>
+    </insert>
+
+
+    <select id="getQuoteUserConfig" resultType="com.ydtech.modules.order.entity.po.SysQuoteConfig">
+        select sqc.*
+        from sys_quote_config sqc
+        where is_enabled = 1
+          and authorize = 0
+        UNION
+        select sqc.*
+        from sys_quote_config sqc
+                 left join sys_quote_user squ on squ.config_id = sqc.id
+        where is_enabled = 1
+          and authorize = 1
+          and squ.user_id = #{userId};
+    </select>
+</mapper>