Răsfoiți Sursa

Merge remote-tracking branch 'origin/master'

wanghao 3 luni în urmă
părinte
comite
3f44dd397e
16 a modificat fișierele cu 347 adăugiri și 235 ștergeri
  1. 13 0
      commons/src/main/java/com/jzg/commons/entity/finance/po/InsPlyIncome.java
  2. 36 0
      commons/src/main/java/com/jzg/commons/entity/finance/vo/FollowCompanyFeeVO.java
  3. 7 1
      tenant/insurance/quotation-guoren/src/main/java/com/jzg/quotation/guoren/crawler/build/GuoRenCrawlerQuoteResultsVoBuild.java
  4. 2 1
      tenant/insurance/quotation-summary/src/main/java/com/jzg/quotation/summary/SummaryQuotationApplication.java
  5. 1 1
      tenant/insurance/quotation-taikang/src/main/java/com/jzg/quotation/taikang/crawler/build/TkCrawlerQuoteResultsBuild.java
  6. 1 1
      tenant/insurance/quotation-taikang/src/main/java/com/jzg/quotation/taikang/crawler/service/impl/TKCrawlerOrderServiceImpl.java
  7. 2 2
      tenant/insurance/quotation-taikang/src/main/java/com/jzg/quotation/taikang/crawler/service/impl/TKQuotationBaseServiceImpl.java
  8. 4 4
      tenant/insurance/quotation-taishan/src/main/java/com/jzg/quotation/taishan/crawler/build/TaiShanCrawlerQuoteResultsVoBuild.java
  9. 104 87
      tenant/insurance/quotation-zhongan/src/main/java/com/jzg/quotation/zhongan/crawler/component/ZhongAnCrawlerCacheComponent.java
  10. 5 137
      tenant/insurance/quotation-zijin/src/main/java/com/jzg/quotation/zijin/crawler/service/impl/ZiJinCrawlerRequestImpl.java
  11. 19 1
      tenant/organization/src/main/java/com/jzg/organization/controller/ReceivableController.java
  12. 9 0
      tenant/organization/src/main/java/com/jzg/organization/mapper/InsFeeFollowOrderMapper.java
  13. 4 0
      tenant/organization/src/main/java/com/jzg/organization/service/ReceivableService.java
  14. 45 0
      tenant/organization/src/main/java/com/jzg/organization/service/impl/ReceivableServiceImpl.java
  15. 92 0
      tenant/organization/src/main/resources/mapper/InsFeeFollowOrderMapper.xml
  16. 3 0
      tenant/organization/src/main/resources/mapper/ReceivableMapper.xml

+ 13 - 0
commons/src/main/java/com/jzg/commons/entity/finance/po/InsPlyIncome.java

@@ -310,4 +310,17 @@ public class InsPlyIncome extends BaseModel {
     @Schema(description = "地区归属")
     @Schema(description = "地区归属")
     private String companyNameSimple;
     private String companyNameSimple;
 
 
+    @TableField(exist = false)
+    @Schema(description = "交强总比例")
+    private String jqTotalProportion;
+
+    @TableField(exist = false)
+    @Schema(description = "商业总比例")
+    private String syTotalProportion;
+
+    @TableField(exist = false)
+    @Schema(description = "非车总比例")
+    private String jyTotalProportion;
+
+
 }
 }

+ 36 - 0
commons/src/main/java/com/jzg/commons/entity/finance/vo/FollowCompanyFeeVO.java

@@ -0,0 +1,36 @@
+package com.jzg.commons.entity.finance.vo;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+
+import java.math.BigDecimal;
+
+/**
+ * 保险公司结算费用实体
+ */
+@Data
+public class FollowCompanyFeeVO {
+
+    private String companyName;
+
+    private String companyId;
+
+    /** 分支保险公司ID partner_company_id */
+    private String partnerCompanyId;
+
+    /** 已开票总金额 SUM(invoiced) */
+    private BigDecimal totalInvoiced;
+
+    /** 未开票总金额 SUM(uninvoiced) */
+    private BigDecimal totalUnInvoiced;
+
+    /** 已结算总金额 SUM(实收金额 actual_received_amount) */
+    private BigDecimal totalSettlementAmount;
+
+    /** 未结算总金额  totalInvoiced - totalSettlementAmount */
+    private BigDecimal totalUnSettlementAmount;
+
+    /** 累计应收  totalReceivable */
+    private BigDecimal totalReceivable;
+
+}

+ 7 - 1
tenant/insurance/quotation-guoren/src/main/java/com/jzg/quotation/guoren/crawler/build/GuoRenCrawlerQuoteResultsVoBuild.java

@@ -59,13 +59,19 @@ public final class GuoRenCrawlerQuoteResultsVoBuild {
         quoteResultsVo.getCosts().setVvTax(vvTax);
         quoteResultsVo.getCosts().setVvTax(vvTax);
         quoteResultsVo.setQuoteStatusEnum(InsOrderStatusEnum.WAIT_AUDIT);
         quoteResultsVo.setQuoteStatusEnum(InsOrderStatusEnum.WAIT_AUDIT);
 
 
+
+        quoteVo.getBiRiskInfoVo().setStartDate(calculationPremium.getCi().getPrptitemkindList().get(0).getStartDate() + " 00:00:00");
+        quoteVo.getBiRiskInfoVo().setEndDate(calculationPremium.getCi().getPrptitemkindList().get(0).getEndDate() + " 00:00:00");
         quoteResultsVo.setCiRiskInfoVo(quoteVo.getCiRiskInfoVo());
         quoteResultsVo.setCiRiskInfoVo(quoteVo.getCiRiskInfoVo());
-        quoteResultsVo.setBiRiskInfoVo(quoteVo.getBiRiskInfoVo());
 
 
         if (calculationPremium.getBi().getPrptitemkindList() != null) {
         if (calculationPremium.getBi().getPrptitemkindList() != null) {
             List<KindInfoVo> kindInfoVo = buildKindInfoVo(quoteVo.getKindInfoVo(), calculationPremium.getBi().getPrptitemkindList());
             List<KindInfoVo> kindInfoVo = buildKindInfoVo(quoteVo.getKindInfoVo(), calculationPremium.getBi().getPrptitemkindList());
+            quoteVo.getBiRiskInfoVo().setStartDate(calculationPremium.getBi().getPrptitemkindList().get(0).getStartDate() + " 00:00:00");
+            quoteVo.getBiRiskInfoVo().setEndDate(calculationPremium.getBi().getPrptitemkindList().get(0).getEndDate() + " 00:00:00");
             quoteResultsVo.setKindInfoVo(kindInfoVo);
             quoteResultsVo.setKindInfoVo(kindInfoVo);
         }
         }
+        quoteResultsVo.setBiRiskInfoVo(quoteVo.getBiRiskInfoVo());
+
 
 
         QuoteResultsVo.ScoreVo scoreVo = new QuoteResultsVo.ScoreVo();
         QuoteResultsVo.ScoreVo scoreVo = new QuoteResultsVo.ScoreVo();
         scoreVo.setLossRation(calculationPremium.getBc().getAutoPriceOutputXOMRespVo().getStrBillELR2());
         scoreVo.setLossRation(calculationPremium.getBc().getAutoPriceOutputXOMRespVo().getStrBillELR2());

+ 2 - 1
tenant/insurance/quotation-summary/src/main/java/com/jzg/quotation/summary/SummaryQuotationApplication.java

@@ -19,7 +19,8 @@ import org.springframework.scheduling.annotation.EnableAsync;
 @EnableConfigurationProperties(YcConfigurationProperties.class)
 @EnableConfigurationProperties(YcConfigurationProperties.class)
 @EnableMongoRepositories(
 @EnableMongoRepositories(
         basePackages = {
         basePackages = {
-                "com.jzg.quotation.**.repository"
+                "com.jzg.quotation.**.repository",
+                "com.jzg.quotation.**.crawler.repository"
         },
         },
         repositoryBaseClass = SimpleMongoRepository.class // 强制同步模式
         repositoryBaseClass = SimpleMongoRepository.class // 强制同步模式
 )
 )

+ 1 - 1
tenant/insurance/quotation-taikang/src/main/java/com/jzg/quotation/taikang/crawler/build/TkCrawlerQuoteResultsBuild.java

@@ -180,7 +180,7 @@ public class TkCrawlerQuoteResultsBuild {
         if (!StringUtils.hasText(renewalFlag)) {
         if (!StringUtils.hasText(renewalFlag)) {
             return null;
             return null;
         }
         }
-        if (renewalFlag.equals("0")) {
+        if ("0".equals(renewalFlag)) {
             return String.valueOf(RenewalEnum.Renewal.getCode());
             return String.valueOf(RenewalEnum.Renewal.getCode());
         } else {
         } else {
             return String.valueOf(RenewalEnum.Transfer.getCode());
             return String.valueOf(RenewalEnum.Transfer.getCode());

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

@@ -12,7 +12,7 @@ import org.springframework.stereotype.Service;
 import java.time.LocalDateTime;
 import java.time.LocalDateTime;
 
 
 /**
 /**
- * @description: 紫金财险爬虫订单服务实现
+ * @description: 泰康财险爬虫订单服务实现
  * @author:
  * @author:
  * @date:
  * @date:
  **/
  **/

+ 2 - 2
tenant/insurance/quotation-taikang/src/main/java/com/jzg/quotation/taikang/crawler/service/impl/TKQuotationBaseServiceImpl.java

@@ -249,11 +249,11 @@ public class TKQuotationBaseServiceImpl implements TKQuotationBaseService {
             // 保司订单号
             // 保司订单号
             underwritingResultsVo.setCompanyOrderNo(proposalNo);
             underwritingResultsVo.setCompanyOrderNo(proposalNo);
 
 
-            // tkCrawlerOrderService.save(underwritingVo, underwritingResultsVo, preciseInitResult.getMainOrderId(), true);
+            tkCrawlerOrderService.save(underwritingVo, underwritingResultsVo, preciseInitResult.getMainOrderId(), true);
         } else {
         } else {
             underwritingResultsVo.setUnderwritingResult("核保失败");
             underwritingResultsVo.setUnderwritingResult("核保失败");
             underwritingResultsVo.setUnderwritingStatus(InsOrderStatusEnum.AUDIT_FAIL);
             underwritingResultsVo.setUnderwritingStatus(InsOrderStatusEnum.AUDIT_FAIL);
-            // tkCrawlerOrderService.save(underwritingVo, underwritingResultsVo, preciseInitResult.getMainOrderId(), false);
+            tkCrawlerOrderService.save(underwritingVo, underwritingResultsVo, preciseInitResult.getMainOrderId(), false);
         }
         }
 
 
         return underwritingResultsVo;
         return underwritingResultsVo;

+ 4 - 4
tenant/insurance/quotation-taishan/src/main/java/com/jzg/quotation/taishan/crawler/build/TaiShanCrawlerQuoteResultsVoBuild.java

@@ -206,10 +206,10 @@ public class TaiShanCrawlerQuoteResultsVoBuild {
             quoteResultsVo.getCosts().setNiPremium(saveResponse.getResult().getDiInsurance().getPremium());
             quoteResultsVo.getCosts().setNiPremium(saveResponse.getResult().getDiInsurance().getPremium());
         }
         }
         // 设置总费用
         // 设置总费用
-        BigDecimal bi = quoteResultsVo.getCosts().getBiPremium() == null ? BigDecimal.ZERO : new BigDecimal(quoteResultsVo.getCosts().getBiPremium());
-        BigDecimal ci = quoteResultsVo.getCosts().getCiPremium() == null ? BigDecimal.ZERO : new BigDecimal(quoteResultsVo.getCosts().getCiPremium());
-        BigDecimal vv = quoteResultsVo.getCosts().getVvTax() == null ? BigDecimal.ZERO : new BigDecimal(quoteResultsVo.getCosts().getVvTax());
-        BigDecimal ni = quoteResultsVo.getCosts().getNiPremium() == null ? BigDecimal.ZERO : new BigDecimal(quoteResultsVo.getCosts().getNiPremium());
+        BigDecimal bi = StringUtils.hasText(quoteResultsVo.getCosts().getBiPremium()) ? new BigDecimal(quoteResultsVo.getCosts().getBiPremium()) : BigDecimal.ZERO;
+        BigDecimal ci = StringUtils.hasText(quoteResultsVo.getCosts().getCiPremium()) ? new BigDecimal(quoteResultsVo.getCosts().getCiPremium()) : BigDecimal.ZERO;
+        BigDecimal vv = StringUtils.hasText(quoteResultsVo.getCosts().getVvTax()) ? new BigDecimal(quoteResultsVo.getCosts().getVvTax()) : BigDecimal.ZERO;
+        BigDecimal ni = StringUtils.hasText(quoteResultsVo.getCosts().getNiPremium()) ? new BigDecimal(quoteResultsVo.getCosts().getNiPremium()) : BigDecimal.ZERO;
 
 
         BigDecimal total = bi.add(ci).add(vv).add(ni);
         BigDecimal total = bi.add(ci).add(vv).add(ni);
         quoteResultsVo.getCosts().setSumPremium(total.toPlainString());
         quoteResultsVo.getCosts().setSumPremium(total.toPlainString());

+ 104 - 87
tenant/insurance/quotation-zhongan/src/main/java/com/jzg/quotation/zhongan/crawler/component/ZhongAnCrawlerCacheComponent.java

@@ -2,13 +2,17 @@ package com.jzg.quotation.zhongan.crawler.component;
 
 
 import com.alibaba.fastjson2.JSON;
 import com.alibaba.fastjson2.JSON;
 import com.alibaba.fastjson2.JSONObject;
 import com.alibaba.fastjson2.JSONObject;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
 import com.jzg.commons.util.AssertionUtils;
 import com.jzg.commons.util.AssertionUtils;
 import com.jzg.quotation.zhongan.crawler.client.LoginResult;
 import com.jzg.quotation.zhongan.crawler.client.LoginResult;
 import com.jzg.quotation.zhongan.crawler.entity.request.ZhongAnCrawlerQueryInitInfoRequest;
 import com.jzg.quotation.zhongan.crawler.entity.request.ZhongAnCrawlerQueryInitInfoRequest;
 import com.jzg.quotation.zhongan.crawler.entity.response.ZhongAnCrawlerPaymentResponse;
 import com.jzg.quotation.zhongan.crawler.entity.response.ZhongAnCrawlerPaymentResponse;
 import com.jzg.quotation.zhongan.crawler.entity.response.ZhongAnCrawlerUploadInitDateResponse;
 import com.jzg.quotation.zhongan.crawler.entity.response.ZhongAnCrawlerUploadInitDateResponse;
+import lombok.Data;
 import lombok.RequiredArgsConstructor;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import lombok.extern.slf4j.Slf4j;
+import okhttp3.*;
 import org.apache.hc.core5.net.URIBuilder;
 import org.apache.hc.core5.net.URIBuilder;
 import org.apache.http.Header;
 import org.apache.http.Header;
 import org.apache.http.client.methods.CloseableHttpResponse;
 import org.apache.http.client.methods.CloseableHttpResponse;
@@ -26,6 +30,7 @@ import org.springframework.stereotype.Component;
 import java.net.URI;
 import java.net.URI;
 import java.time.Duration;
 import java.time.Duration;
 import java.util.HashMap;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
 import java.util.Map;
 import java.util.regex.Matcher;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 import java.util.regex.Pattern;
@@ -111,107 +116,119 @@ public class ZhongAnCrawlerCacheComponent {
         return JSON.parseObject(bucket1.get(), ZhongAnCrawlerPaymentResponse.ValueDTO.DatasDTO.InitInfoDTO.class);
         return JSON.parseObject(bucket1.get(), ZhongAnCrawlerPaymentResponse.ValueDTO.DatasDTO.InitInfoDTO.class);
     }
     }
 
 
-    //登录
-    private static final CloseableHttpClient HTTP_CLIENT =HttpClients.custom().disableRedirectHandling().build(); // 关闭自动重定向
+    private static final OkHttpClient session = new OkHttpClient.Builder()
+            .followRedirects(false)
+            .build();
 
 
-    // 正则表达式 获取cookie、flowId
-    private static final Pattern ZA_COOKIE_PATTERN = Pattern.compile("zaLoginCookieKey=(.*?);");
-    private static final Pattern FLOW_ID_PATTERN = Pattern.compile("flowId=(.*?)&");
-
-    // 构造 GET 请求
-    private HttpGet buildGet(URI uri) {
-        HttpGet get = new HttpGet(uri);
-        get.setHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36");
-        get.setHeader("Accept", "application/json, text/plain, */*");
-        return get;
-    }
-
-    // 获取重定向 Location
-    private String getLocationHeader(CloseableHttpResponse response) {
-        Header header = response.getLastHeader("Location");
-        return header != null ? header.getValue() : "";
-    }
+    private static final ObjectMapper objectMapper = new ObjectMapper();
     public LoginResult loginCookieCache(String zhongAnId,String productId) {
     public LoginResult loginCookieCache(String zhongAnId,String productId) {
-        HttpClientContext context = HttpClientContext.create();
         try {
         try {
-            String firstUrl = "http://zhongan.bjhfbx.cn/subao-proxy-customer/api/redirectToCoopUserProductExclusivePage";
-            URI uri1 = new URIBuilder(firstUrl)
-                    .addParameter("coopUserId", zhongAnId)
-                    .addParameter("productId", productId)
-                    .addParameter("isOpenByPC", "N")
-                    .addParameter("promotionScene", "16")
-                    .addParameter("bizContent", "")
-                    .addParameter("insurePlaceCode", "140100")
+            // ========== 第一步 POST 请求 ==========
+            Headers.Builder postHeaderBuilder = new Headers.Builder();
+            postHeaderBuilder.add("Accept-Language", "zh-CN,zh;q=0.9");
+            postHeaderBuilder.add("Connection", "keep-alive");
+            postHeaderBuilder.add("Content-Type", "application/json");
+            postHeaderBuilder.add("Host", "www.yuanqingtech.com");
+            postHeaderBuilder.add("Referer", "https://servicewechat.com/wx46d2e1aaa28335ea/47/page-frame.html");
+            postHeaderBuilder.add("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Safari/537.36 MicroMessenger/7.0.20.1781(0x6700143B) NetType/WIFI MiniProgramEnv/Windows WindowsWechat/WMPF WindowsWechat(0x63090a13) UnifiedPCWindowsWechat(0xf2541a1f) XWEB/19921");
+            postHeaderBuilder.add("accessKey", "");
+            postHeaderBuilder.add("appCode", "");
+            postHeaderBuilder.add("channel", "");
+            postHeaderBuilder.add("openIdToken", "");
+            postHeaderBuilder.add("platform", "MINI_WECHAT");
+            postHeaderBuilder.add("t", "ios");
+            postHeaderBuilder.add("unionId", "");
+            postHeaderBuilder.add("wxSDKVersion", "3.16.1");
+            postHeaderBuilder.add("wxVersion", "4.1.10.31");
+            postHeaderBuilder.add("xweb_xhr", "1");
+            postHeaderBuilder.add("zaLoginCookieKey", "");
+
+            Headers postHeaders = postHeaderBuilder.build();
+
+            String urlPost = "https://www.yuanqingtech.com/dmapi/dm-innovation-front/api/config-info/findIssuingLink";
+
+            FirstReqData reqData = new FirstReqData();
+            reqData.setInviterAccountId(zhongAnId);
+            reqData.setActivityCode(productId);
+
+            String jsonBody = objectMapper.writeValueAsString(reqData);
+            RequestBody body = RequestBody.create(jsonBody, MediaType.get("application/json; charset=utf-8"));
+            Request postReq = new Request.Builder()
+                    .url(urlPost)
+                    .headers(postHeaders)
+                    .post(body)
                     .build();
                     .build();
-            // 发送第一个请求,不跟随重定向
-            HttpGet get1 = buildGet(uri1);
-            CloseableHttpResponse resp1 = HTTP_CLIENT.execute(get1, context);
-            AssertionUtils.isEmpty(resp1, "第一次请求失败,请联系管理员");
-            String location1 = resp1.getFirstHeader("Location").getValue();
-            resp1.close();
-            // 发送第二个请求
-            HttpGet get2 = buildGet(new URI(location1));
-            CloseableHttpResponse resp2 = HTTP_CLIENT.execute(get2, context);
-            AssertionUtils.isEmpty(resp2, "第二次请求失败,请联系管理员");
-            String location2 = getLocationHeader(resp2);
-            resp2.close();
-            // 发送第三个请求
-            HttpGet get3 = buildGet(new URI(location2));
-            CloseableHttpResponse resp3 = HTTP_CLIENT.execute(get3, context);
-            AssertionUtils.isEmpty(resp3, "第三次请求失败,请联系管理员");
-            String location3 = resp3.getFirstHeader("Location").getValue();
-            resp3.close();
-            // 发送第四个请求
-            HttpGet get4 = buildGet(new URI(location3));
-            CloseableHttpResponse resp4 = HTTP_CLIENT.execute(get4, context);
-            AssertionUtils.isEmpty(resp4, "第四次请求失败,请联系管理员");
-            String location4 = resp4.getFirstHeader("Location").getValue();
-            resp4.close();
-            // 第五次请求,拿cookie
-            HttpGet get5 = buildGet(new URI(location4));
-            CloseableHttpResponse resp5 = HTTP_CLIENT.execute(get5, context);
-            AssertionUtils.isEmpty(resp5, "第五次请求失败,请联系管理员");
-            String location5 = resp5.getFirstHeader("Location").getValue();
-            // 提取 zaLoginCookieKey
-            String cookieKey = null;
-            if (resp5.getHeaders("Set-Cookie") != null) {
-                for (org.apache.http.Header h : resp5.getHeaders("Set-Cookie")) {
-                    Matcher m = ZA_COOKIE_PATTERN.matcher(h.getValue());
-                    if (m.find()) {
-                        cookieKey = m.group(1).trim();
-                        break;
-                    }
-                }
-            }
-            resp5.close();
 
 
-            if (cookieKey == null || cookieKey.isEmpty()) {
+            Response postResp = session.newCall(postReq).execute();
+            String respBody = postResp.body().string();
+            postResp.close();
+
+            JsonNode root = objectMapper.readTree(respBody);
+            JsonNode valueNode = root.path("value");
+            if (!valueNode.isArray() || valueNode.size() == 0) {
                 return new LoginResult(400, "账号错误", null, null);
                 return new LoginResult(400, "账号错误", null, null);
             }
             }
 
 
-            // 提取 flowId
-            Matcher flowMatcher = FLOW_ID_PATTERN.matcher(location5);
-            String flowId = flowMatcher.find() ? flowMatcher.group(1).trim() : "";
-
-            String finalUrl = "https://c.zhongan.com/insure/index.html";
-            URI finalUri = new URIBuilder(finalUrl)
-                    .addParameter("flowId", flowId)
-                    .addParameter("i", "e")
-                    .addParameter("insurePlaceCode", "140100")
-                    .addParameter("newPage", "1")
+            String linkUrl = valueNode.get(0).path("link").asText("");
+            Headers.Builder getHeaderBuilder = new Headers.Builder();
+            getHeaderBuilder.add("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/wxpic,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7");
+            getHeaderBuilder.add("Accept-Encoding", "gzip, deflate, br");
+            getHeaderBuilder.add("Accept-Language", "zh-CN,zh;q=0.9");
+            getHeaderBuilder.add("Connection", "keep-alive");
+            getHeaderBuilder.add("Host", "c.zhongan.com");
+            getHeaderBuilder.add("Sec-Fetch-Dest", "document");
+            getHeaderBuilder.add("Sec-Fetch-Mode", "navigate");
+            getHeaderBuilder.add("Sec-Fetch-Site", "none");
+            getHeaderBuilder.add("Sec-Fetch-User", "?1");
+            getHeaderBuilder.add("Upgrade-Insecure-Requests", "1");
+            getHeaderBuilder.add("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Safari/537.36 MicroMessenger/7.0.20.1781(0x6700143B) NetType/WIFI MiniProgramEnv/Windows WindowsWechat/WMPF WindowsWechat(0x63090a13) UnifiedPCWindowsWechat(0xf2541a1f) XWEB/19921 miniProgram/wx46d2e1aaa28335ea");
+
+            Headers getHeaders = getHeaderBuilder.build();
+            Request getReq = new Request.Builder()
+                    .url(linkUrl)
+                    .headers(getHeaders)
+                    .get()
                     .build();
                     .build();
 
 
-            HttpGet finalGet = buildGet(finalUri);
-            finalGet.setHeader("Cookie", "zaLoginCookieKey=" + cookieKey);
-            CloseableHttpResponse finalResp = HTTP_CLIENT.execute(finalGet, context);
-            finalResp.close();
-            cacheCookie(cookieKey, flowId, zhongAnId);
-            return new LoginResult(200, "登录成功", cookieKey, flowId);
+            Response getResp = session.newCall(getReq).execute();
+            String flowIdUrl = getResp.header("Location", "");
+            getResp.close();
+
+            Pattern flowPattern = Pattern.compile("flowId=(.*?)&");
+            Matcher flowMatcher = null;
+            if (flowIdUrl != null) {
+                flowMatcher = flowPattern.matcher(flowIdUrl);
+            }
+            String flowId = "";
+            if (flowMatcher.find()) {
+                flowId = flowMatcher.group(1);
+            }
+            String zaLoginCookieKey = "";
+            List<String> setCookieList = getResp.headers("Set-Cookie");
+            for (String cookie : setCookieList) {
+                Pattern cookiePattern = Pattern.compile("zaLoginCookieKey=(.*?);", Pattern.DOTALL);
+                Matcher cookieMatcher = cookiePattern.matcher(cookie);
+                if (cookieMatcher.find()) {
+                    zaLoginCookieKey = cookieMatcher.group(1);
+                }
+            }
+            cacheCookie(zaLoginCookieKey, flowId, zhongAnId);
+            return new LoginResult(200, "登录成功", zaLoginCookieKey, flowId);
         } catch (Exception e) {
         } catch (Exception e) {
             e.printStackTrace();
             e.printStackTrace();
             return new LoginResult(400, "登录异常:" + e.getMessage(), null, null);
             return new LoginResult(400, "登录异常:" + e.getMessage(), null, null);
         }
         }
     }
     }
 
 
-
+    @Data
+    public static class FirstReqData {
+        private String bizOrigin = "CAR_ZYHS_XXSYTG";
+        private String inviterAccountId;
+        private String activityCode;
+        private BizParams bizParams = new BizParams();
+    }
+    @Data
+    public static class BizParams {
+        private final String insurePlaceCode = "140100";
+    }
 }
 }

+ 5 - 137
tenant/insurance/quotation-zijin/src/main/java/com/jzg/quotation/zijin/crawler/service/impl/ZiJinCrawlerRequestImpl.java

@@ -836,20 +836,6 @@ public class ZiJinCrawlerRequestImpl implements ZiJinCrawlerRequest {
         return baseInfo;
         return baseInfo;
     }
     }
 
 
-    /**
-     * 构建车主信息对象
-     *
-     * @return ZiJinCrawlerQuotationRequest.CarOwnerInfo
-     */
-//    private ZiJinCrawlerQuotationRequest.CarOwnerInfo buildCarOwnerInfo() {
-//        ZiJinCrawlerQuotationRequest.CarOwnerInfo carOwnerInfo = new ZiJinCrawlerQuotationRequest.CarOwnerInfo();
-//        carOwnerInfo.setCarOwner("王婧");//车主姓名
-//        carOwnerInfo.setOwnerIdentifyNumber("14092519990322002X");//车主证件号码
-//        carOwnerInfo.setOwnerIdentifyType("01");//车主证件类型(01-身份证)
-//        carOwnerInfo.setVehicleOwnerNature("1");//车主性质(1-个人)
-//        return carOwnerInfo;
-//    }
-
 
 
     /**
     /**
      * 构建车主信息对象
      * 构建车主信息对象
@@ -919,42 +905,6 @@ public class ZiJinCrawlerRequestImpl implements ZiJinCrawlerRequest {
         }
         }
     }
     }
 
 
-//    /**
-//     * 构建被保险人列表
-//     *
-//     * @return List<ZiJinCrawlerQuotationRequest.InsuredList>
-//     */
-//    private List<ZiJinCrawlerQuotationRequest.InsuredList> buildInsuredList() {
-//        List<ZiJinCrawlerQuotationRequest.InsuredList> insuredList = new ArrayList<>();
-//
-//        // 第一个被保险人
-//        ZiJinCrawlerQuotationRequest.InsuredList insured1 = new ZiJinCrawlerQuotationRequest.InsuredList();
-//        insured1.setInsuredName("王婧");
-//        insured1.setInsuredNature("3");
-//        insured1.setIdentifyType("01");
-//        insured1.setIdentifyNumber("14092519990322002X");
-//        insured1.setSex("2");
-//        insured1.setInsuredType("1");
-//        insured1.setMobile("18840186946");
-//        insured1.setPostCode("030053");
-//        insured1.setInsuredFlag(2);
-//        insuredList.add(insured1);
-//
-//        // 第二个被保险人
-//        ZiJinCrawlerQuotationRequest.InsuredList insured2 = new ZiJinCrawlerQuotationRequest.InsuredList();
-//        insured2.setInsuredName("王婧");
-//        insured2.setInsuredNature("3");
-//        insured2.setIdentifyType("01");
-//        insured2.setIdentifyNumber("14092519990322002X");
-//        insured2.setSex("2");
-//        insured2.setInsuredType("1");
-//        insured2.setMobile("18840186946");
-//        insured2.setPostCode("030053");
-//        insured2.setInsuredFlag(1);
-//        insuredList.add(insured2);
-//        return insuredList;
-//    }
-
     /**
     /**
      * 构建被保险人列表
      * 构建被保险人列表
      *
      *
@@ -1384,31 +1334,19 @@ public class ZiJinCrawlerRequestImpl implements ZiJinCrawlerRequest {
     private List<ZiJinCrawlerQuotationRequest.CarPolicySubInfoList> buildCarPolicySubInfoList(QuoteVo quoteVo) {
     private List<ZiJinCrawlerQuotationRequest.CarPolicySubInfoList> buildCarPolicySubInfoList(QuoteVo quoteVo) {
         List<ZiJinCrawlerQuotationRequest.CarPolicySubInfoList> carPolicySubInfoList = new ArrayList<>();
         List<ZiJinCrawlerQuotationRequest.CarPolicySubInfoList> carPolicySubInfoList = new ArrayList<>();
 
 
-        List<AccidentalDrivingVo> accidentalDrivings = quoteVo.getAccidentalDrivings();
-        if (CollectionUtils.isEmpty(accidentalDrivings)) {
+        if (CollectionUtils.isEmpty(quoteVo.getAccidentalDrivings())) {
             return carPolicySubInfoList;
             return carPolicySubInfoList;
         }
         }
 
 
-        // for (AccidentalDrivingVo drivingInsurance : accidentalDrivings) {
-        //     String rideRiskCode = drivingInsurance.getRiskCode();
-        //     // 目前只支持 rideRiskCode == "0733"(紫金驾驶人意外伤害保险)
-        //     if (AccidentHealthInsuranceProductsEnum.ZIJIN_JIASHI_REN_ACCIDENT.getCode().equals(rideRiskCode)) {
-        //         carPolicySubInfoList.add(buildRideRisk0733(drivingInsurance));
-        //     }
-        //     // 其他风险代码暂未配置,Python中会抛出异常
-        //     // 这里暂时跳过,不抛出异常
-        // }
-
-        // 默认选中"0767"->"紫金驾乘人员人生意外保险"
         for (AccidentalDrivingVo accidentalDriving : quoteVo.getAccidentalDrivings()) {
         for (AccidentalDrivingVo accidentalDriving : quoteVo.getAccidentalDrivings()) {
             ZiJinCrawlerQuotationRequest.CarPolicySubInfoList carPolicySubInfo = new ZiJinCrawlerQuotationRequest.CarPolicySubInfoList();
             ZiJinCrawlerQuotationRequest.CarPolicySubInfoList carPolicySubInfo = new ZiJinCrawlerQuotationRequest.CarPolicySubInfoList();
             carPolicySubInfo.setPlanName(accidentalDriving.getProductName());
             carPolicySubInfo.setPlanName(accidentalDriving.getProductName());
             carPolicySubInfo.setInsureGradeNo("200000736004"); // 前端没传
             carPolicySubInfo.setInsureGradeNo("200000736004"); // 前端没传
-            carPolicySubInfo.setProductCode("0736");// 这个值前端传过来的是乱码200000736004%%0736%%%0
+            carPolicySubInfo.setProductCode(accidentalDriving.getProductCode());// 这个值前端传过来的是乱码200000736004%%0736%%%0
             carPolicySubInfo.setPlanName(accidentalDriving.getProductName());
             carPolicySubInfo.setPlanName(accidentalDriving.getProductName());
-            carPolicySubInfo.setRiskCode("0736"); // 完了要调整编码,是否要转换
-            carPolicySubInfo.setRiskName("全家安行保"); // 前端没传
-            carPolicySubInfo.setSumAmount(ObjectUtils.isEmpty(accidentalDriving.getSumAmount()) ? 2350000 : (int) Double.parseDouble(accidentalDriving.getSumAmount()));
+            carPolicySubInfo.setRiskCode(accidentalDriving.getRiskCode()); // 完了要调整编码,是否要转换
+            carPolicySubInfo.setRiskName(accidentalDriving.getProductName()); // 前端没传
+            carPolicySubInfo.setSumAmount(ObjectUtils.isEmpty(accidentalDriving.getSumAmount()) ? 0 : (int) Double.parseDouble(accidentalDriving.getSumAmount()));
             carPolicySubInfo.setQuantity(accidentalDriving.getQuantity() == 0 ? "0" : String.valueOf(accidentalDriving.getQuantity()));
             carPolicySubInfo.setQuantity(accidentalDriving.getQuantity() == 0 ? "0" : String.valueOf(accidentalDriving.getQuantity()));
             carPolicySubInfo.setIsUseInsured("1");
             carPolicySubInfo.setIsUseInsured("1");
             carPolicySubInfo.setSumPremium(ObjectUtils.isEmpty(accidentalDriving.getPremium()) ? 0 : (int) Double.parseDouble(accidentalDriving.getPremium()));
             carPolicySubInfo.setSumPremium(ObjectUtils.isEmpty(accidentalDriving.getPremium()) ? 0 : (int) Double.parseDouble(accidentalDriving.getPremium()));
@@ -1478,76 +1416,6 @@ public class ZiJinCrawlerRequestImpl implements ZiJinCrawlerRequest {
     }
     }
 
 
 
 
-    /**
-     * 构建车辆信息对象
-     *
-     * @return ZiJinCrawlerQuotationRequest.VehicleInfo
-     */
-//    private ZiJinCrawlerQuotationRequest.VehicleInfo buildVehicleInfo() {
-//        ZiJinCrawlerQuotationRequest.VehicleInfo vehicleInfo = new ZiJinCrawlerQuotationRequest.VehicleInfo();
-//
-//        // 基础车辆信息
-//        vehicleInfo.setActualValue(73905.6);
-//        vehicleInfo.setAgreeActualValue(73905.6);
-//        vehicleInfo.setBrandName("荣威CSA6452NEAQ多用途乘用车");
-//        vehicleInfo.setCarKindCode("A0");
-//        vehicleInfo.setCarKindDetailId("KA");
-//        vehicleInfo.setCarLoanFlag("1");
-//        vehicleInfo.setCertificateDate("2021-11-01");
-//        vehicleInfo.setChgOwnerFlag("1");
-//        vehicleInfo.setCompletekerbmass(1539);
-//        vehicleInfo.setEcdemicVehicleFlag("0");
-//        vehicleInfo.setEngineNo("DNSM9070392");
-//
-//        // 日期相关
-//        vehicleInfo.setEnrollDate("2021-11-01");
-//        vehicleInfo.setUpdateEnrollDate("2021-11-01");
-//        vehicleInfo.setIssueDate("2025-10-16");
-//        vehicleInfo.setMakeDate("2025-10-16");
-//        vehicleInfo.setMakeDateJQ("2025-10-16");
-//
-//        // 车辆技术参数
-//        vehicleInfo.setExhaustCapacity(1490);
-//        vehicleInfo.setFuelType("0");
-//        vehicleInfo.setFuelTypeJY("D1");
-//        vehicleInfo.setNewEnergyFlag("0");
-//        vehicleInfo.setPower("133");
-//        vehicleInfo.setModelEnergyType("D1");
-//
-//        // 牌照和车辆识别
-//        vehicleInfo.setLicenseColorCode("01");
-//        vehicleInfo.setLicenseKindCode("02");
-//        vehicleInfo.setLicenseNo("晋HJW581");
-//        vehicleInfo.setLoanVehicleFlag("0");
-//        vehicleInfo.setModelCode("RWD1598SQQ");
-//        vehicleInfo.setNoLicenseFlag("1");
-//        vehicleInfo.setVehicleId("1");
-//        vehicleInfo.setVinNo("LSJA24U69MS091895");
-//
-//        // 车辆分类和用途
-//        vehicleInfo.setSeatCount(5);
-//        vehicleInfo.setUseNatureCode("85");
-//        vehicleInfo.setOriCarKindName("K33");
-//        vehicleInfo.setPlatVehicleCode("CRWARJUC0001");
-//        vehicleInfo.setVehicleStyleUniqueId("800004584");
-//
-//        // 价格和商业信息
-//        vehicleInfo.setPurchasePrice("103800");
-//        vehicleInfo.setSale4SFlag("0");
-//        vehicleInfo.setOriPurchasePrice("103800");
-//        vehicleInfo.setIsInvokeJingYou("1");
-//
-//        // 型号名称
-//        vehicleInfo.setPrintVehicleModelName("荣威CSA6452NEAQ多用途乘用车");
-//        vehicleInfo.setAliasName("荣威RX5 PLUS 330TGI 1.5T TST国潮智臻版");
-//        vehicleInfo.setOriBrandName("荣威CSA6452NEAQ多用途乘用车");
-//        vehicleInfo.setOriModelName("荣威CSA6452NEAQ多用途乘用车");
-//        vehicleInfo.setPrintModelName("荣威CSA6452NEAQ多用途乘用车");
-//
-//        return vehicleInfo;
-//    }
-
-
     /**
     /**
      * 构建车辆信息对象
      * 构建车辆信息对象
      *
      *

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

@@ -508,6 +508,12 @@ public class ReceivableController {
         return HttpResult.ok(receivableService.deleteInvoiceById(id) ? "删除成功":"删除失败");
         return HttpResult.ok(receivableService.deleteInvoiceById(id) ? "删除成功":"删除失败");
     }
     }
 
 
+    @DeleteMapping("/deleteFollowInvoiceById/{id}")
+    @Operation(summary = "删除跟单开票记录")
+    public HttpResult<Boolean> deleteFollowInvoiceById(@PathVariable String id){
+        return HttpResult.ok(receivableService.deleteFollowInvoiceById(id) ? "删除成功":"删除失败");
+    }
+
     /**
     /**
      * 私有协议批量修改
      * 私有协议批量修改
      *      修改手续费比例(商业险手续费比例, 交强险手续费比例)
      *      修改手续费比例(商业险手续费比例, 交强险手续费比例)
@@ -679,7 +685,7 @@ public class ReceivableController {
     }
     }
 
 
     /**
     /**
-     * 私有协议-手续费,跟单费,平台协议三个页面的保险公司报表统计接口
+     * 私有协议-手续费,平台协议两个页面的保险公司报表统计接口
      *
      *
      * @author lipf
      * @author lipf
      * @date 2026/5/28 11:15
      * @date 2026/5/28 11:15
@@ -690,6 +696,18 @@ public class ReceivableController {
         return receivableService.companySuperviseSettlementReport(settlementReportQueryVo);
         return receivableService.companySuperviseSettlementReport(settlementReportQueryVo);
     }
     }
 
 
+    /**
+     * 跟单费保险公司报表统计接口
+     *
+     * @author jk
+     * @date 2026/5/28 11:15
+     */
+    @PostMapping("/followCompanySuperviseSettlementReport")
+    @Operation(summary = "保险公司结算报表")
+    public HttpResult<List<FollowCompanyFeeVO>> followCompanySuperviseSettlementReport(@RequestBody SettlementReportQueryVo settlementReportQueryVo) {
+        return HttpResult.ok(receivableService.followCompanySuperviseSettlementReport(settlementReportQueryVo));
+    }
+
     /**
     /**
      * 设置指定发票为结算完成状态
      * 设置指定发票为结算完成状态
      *
      *

+ 9 - 0
tenant/organization/src/main/java/com/jzg/organization/mapper/InsFeeFollowOrderMapper.java

@@ -2,7 +2,10 @@ package com.jzg.organization.mapper;
 
 
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import com.jzg.commons.entity.finance.po.InsFeeFollowOrder;
 import com.jzg.commons.entity.finance.po.InsFeeFollowOrder;
+import com.jzg.commons.entity.finance.vo.FollowCompanyFeeVO;
+import com.jzg.commons.entity.finance.vo.SettlementReportQueryVo;
 import org.apache.ibatis.annotations.Mapper;
 import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
 
 
 import java.util.List;
 import java.util.List;
 
 
@@ -11,4 +14,10 @@ import java.util.List;
  */
  */
 @Mapper
 @Mapper
 public interface InsFeeFollowOrderMapper extends BaseMapper<InsFeeFollowOrder> {
 public interface InsFeeFollowOrderMapper extends BaseMapper<InsFeeFollowOrder> {
+
+    /**
+     * 私有协议跟单结算报表 多表联查分组统计
+     */
+    List<FollowCompanyFeeVO> selectFollowCompanySettlementReport(@Param("query") SettlementReportQueryVo queryVo);
+
 }
 }

+ 4 - 0
tenant/organization/src/main/java/com/jzg/organization/service/ReceivableService.java

@@ -501,4 +501,8 @@ public interface ReceivableService extends IService<InsPlyIncome> {
      * @date 2026/6/22 11:40
      * @date 2026/6/22 11:40
      */
      */
     HttpResult<String> deletePlatformSettlementById(String id);
     HttpResult<String> deletePlatformSettlementById(String id);
+
+    Boolean deleteFollowInvoiceById(String id);
+
+    List<FollowCompanyFeeVO> followCompanySuperviseSettlementReport(SettlementReportQueryVo settlementReportQueryVo);
 }
 }

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

@@ -563,6 +563,51 @@ public class ReceivableServiceImpl extends ServiceImpl<ReceivableMapper, InsPlyI
         return insPlyIncomeInvoiceMapper.deleteById(invoiceId) > 0;
         return insPlyIncomeInvoiceMapper.deleteById(invoiceId) > 0;
     }
     }
 
 
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public Boolean deleteFollowInvoiceById(String invoiceId) {
+        log.info("私有协议-跟单开票记录-删除: id=[{}]", invoiceId);
+        QueryWrapper<InsPlyFollowInvoiceLink> queryWrapper = new QueryWrapper<>();
+        queryWrapper.lambda().eq(InsPlyFollowInvoiceLink::getInvoiceId, invoiceId);
+        queryWrapper.lambda().eq(InsPlyFollowInvoiceLink::getIsDelete, 0);
+        List<InsPlyFollowInvoiceLink> insPlyFollowInvoiceLinks = insPlyFollowInvoiceLinkMapper.selectList(queryWrapper);
+
+        if (CollUtil.isNotEmpty(insPlyFollowInvoiceLinks)){
+            List<String> ids = insPlyFollowInvoiceLinks.stream().map(InsPlyFollowInvoiceLink::getId).toList();
+            List<String> followIds = insPlyFollowInvoiceLinks.stream().map(InsPlyFollowInvoiceLink::getFollowId).toList();
+            insPlyFollowInvoiceLinkMapper.deleteByIds(ids);
+            return insFeeFollowOrderMapper.deleteByIds(followIds) > 0;
+        }
+        return Boolean.FALSE;
+    }
+
+    @Override
+    public List<FollowCompanyFeeVO> followCompanySuperviseSettlementReport(SettlementReportQueryVo settlementReportQueryVo) {
+        log.info("私有协议-跟单结算记录-结算报表: settlementReportQueryVo=[{}]", JSONUtil.toJsonStr(settlementReportQueryVo));
+
+        List<FollowCompanyFeeVO> followCompanyFeeVos = insFeeFollowOrderMapper.selectFollowCompanySettlementReport(settlementReportQueryVo);
+        // 查询所有保险公司,匹配保险公司的id和名称
+        HttpResult<Map<String, EsmInsCompany>> mapHttpResult = esmInsCompanyClient.queryAllCompanyMap();
+        Map<String, EsmInsCompany> data = mapHttpResult.getData();
+        if (CollUtil.isEmpty(data)){
+            return followCompanyFeeVos;
+        }
+        for (FollowCompanyFeeVO followCompanyFeeVo : followCompanyFeeVos) {
+            followCompanyFeeVo.setCompanyName(null != data.get(followCompanyFeeVo.getPartnerCompanyId()) ? data.get(followCompanyFeeVo.getPartnerCompanyId()).getName() : "");
+            followCompanyFeeVo.setTotalUnSettlementAmount(followCompanyFeeVo.getTotalInvoiced().subtract(followCompanyFeeVo.getTotalSettlementAmount()));
+        }
+        return followCompanyFeeVos;
+    }
+
+    /**
+     * BigDecimal安全相加工具:null值转为0
+     */
+    private BigDecimal addBigDecimal(BigDecimal base, BigDecimal num) {
+        if (num == null) {
+            return base;
+        }
+        return base.add(num);
+    }
 
 
     /**
     /**
      * 填充必要的字段
      * 填充必要的字段

+ 92 - 0
tenant/organization/src/main/resources/mapper/InsFeeFollowOrderMapper.xml

@@ -0,0 +1,92 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper
+        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.jzg.organization.mapper.InsFeeFollowOrderMapper">
+
+    <!-- 通用查询映射结果 -->
+    <resultMap id="BaseResultMap" type="com.jzg.commons.entity.finance.po.InsFeeFollowOrder">
+        <id column="id" property="id" />
+        <result column="year" property="year" />
+        <result column="month" property="month" />
+        <result column="company_id" property="companyId" />
+        <result column="partner_company_id" property="partnerCompanyId" />
+        <result column="receivable_premium" property="receivablePremium" />
+        <result column="signing_time" property="signingTime" />
+        <result column="invoiced" property="invoiced" />
+        <result column="uninvoiced" property="uninvoiced" />
+        <result column="invoiced_amount_time" property="invoicedAmountTime" />
+        <result column="reconciliation_amount" property="reconciliationAmount" />
+        <result column="falsely_increased_difference" property="falselyIncreasedDifference" />
+        <result column="falsely_increased_reason" property="falselyIncreasedReason" />
+        <result column="system_code" property="systemCode" />
+        <!-- 继承自 BaseModel 的公共字段 -->
+        <result column="create_by" property="createBy" />
+        <result column="create_time" property="createTime" />
+        <result column="update_by" property="updateBy" />
+        <result column="update_time" property="updateTime" />
+        <result column="is_delete" property="isDelete" />
+    </resultMap>
+
+    <!-- 通用查询结果列 -->
+    <sql id="Base_Column_List">
+        id, `year`, `month`, company_id, partner_company_id, receivable_premium,
+        signing_time, invoiced, uninvoiced, invoiced_amount_time, reconciliation_amount,
+        falsely_increased_difference, falsely_increased_reason, system_code,
+        create_by, create_time, update_by, update_time, is_delete
+    </sql>
+
+    <!-- 根据主键查询 -->
+    <select id="selectById" parameterType="java.lang.String" resultMap="BaseResultMap">
+        SELECT
+        <include refid="Base_Column_List" />
+        FROM ins_fee_follow_order
+        WHERE id = #{id} AND is_delete = 0
+    </select>
+
+
+    <select id="selectFollowCompanySettlementReport" resultType="com.jzg.commons.entity.finance.vo.FollowCompanyFeeVO">
+        SELECT
+        ffo.partner_company_id AS partnerCompanyId,
+        COALESCE(SUM(ffo.invoiced), 0.00) AS totalInvoiced,
+        COALESCE(SUM(ffo.uninvoiced), 0.00) AS totalUnInvoiced,
+        COALESCE(SUM(sett.actual_received_amount), 0.00) AS totalSettlementAmount,
+        COALESCE(SUM(ffo.reconciliation_amount), 0.00) AS totalReceivable
+        FROM ins_fee_follow_order ffo
+        -- 跟单订单关联发票中间表
+        INNER JOIN ins_ply_follow_invoice_link link
+        ON ffo.id = link.follow_id AND link.is_delete = 0
+        -- 关联发票主表
+        INNER JOIN ins_ply_income_invoice inv
+        ON link.invoice_id = inv.id AND inv.is_delete = 0
+        -- 左连结算表(无结算数据时金额为0)
+        LEFT JOIN ins_ply_income_invoice_settlement sett
+        ON inv.id = sett.invoice_id AND sett.is_delete = 0
+        <where>
+            ffo.is_delete = 0
+            -- 保险公司companyId筛选
+            <if test="query.companyId != null and query.companyId != ''">
+                AND ffo.company_id = #{query.companyId}
+            </if>
+            -- 跟单订单创建时间范围
+            <if test="query.startTime != null and query.startTime != '' and query.endTime != null and query.endTime != ''">
+                AND ffo.create_time BETWEEN #{query.startTime} AND #{query.endTime}
+            </if>
+            -- 发票状态筛选
+            <if test="query.status != null">
+                AND inv.status = #{query.status}
+            </if>
+            -- 开票时间范围
+            <if test="query.invoiceStartTime != null and query.invoiceStartTime != '' and query.invoiceEndTime != null and query.invoiceEndTime != ''">
+                AND inv.invoice_time BETWEEN #{query.invoiceStartTime} AND #{query.invoiceEndTime}
+            </if>
+            -- 结算创建时间范围(子查询过滤结算时间)
+            <if test="query.settlementStartTime != null and query.settlementStartTime != '' and query.settlementEndTime != null and query.settlementEndTime != ''">
+                AND sett.create_time BETWEEN #{query.settlementStartTime} AND #{query.settlementEndTime}
+            </if>
+        </where>
+        GROUP BY ffo.partner_company_id
+    </select>
+
+
+</mapper>

+ 3 - 0
tenant/organization/src/main/resources/mapper/ReceivableMapper.xml

@@ -230,6 +230,9 @@
         (COALESCE(ipi.jq_supervise_costs_premiums, 0) + COALESCE(ipi.sy_supervise_costs_premiums, 0) + COALESCE(ipi.jy_supervise_costs_premiums, 0)) AS superviseCostsPremiums,
         (COALESCE(ipi.jq_supervise_costs_premiums, 0) + COALESCE(ipi.sy_supervise_costs_premiums, 0) + COALESCE(ipi.jy_supervise_costs_premiums, 0)) AS superviseCostsPremiums,
         -- 3. 总应收跟单费 (修复了括号位置错误,并为最后一个字段补充了默认值 0)
         -- 3. 总应收跟单费 (修复了括号位置错误,并为最后一个字段补充了默认值 0)
         (COALESCE(ipi.jq_other_costs_premiums, 0) + COALESCE(ipi.sy_other_costs_premiums, 0) + COALESCE(ipi.jy_other_costs_premiums, 0)) AS otherCostsPremiums,
         (COALESCE(ipi.jq_other_costs_premiums, 0) + COALESCE(ipi.sy_other_costs_premiums, 0) + COALESCE(ipi.jy_other_costs_premiums, 0)) AS otherCostsPremiums,
+        (COALESCE(ipi.jq_supervise_costs_proportion, 0) + COALESCE(ipi.jq_other_costs_proportion, 0)) AS jqTotalProportion,
+        (COALESCE(ipi.sy_supervise_costs_proportion, 0) + COALESCE(ipi.sy_other_costs_proportion, 0)) AS syTotalProportion,
+        (COALESCE(ipi.jy_supervise_costs_proportion, 0) + COALESCE(ipi.jy_other_costs_proportion, 0)) AS jyTotalProportion,
         ipi.jq_supervise_costs_premiums,
         ipi.jq_supervise_costs_premiums,
         ipi.sy_supervise_costs_premiums,
         ipi.sy_supervise_costs_premiums,
         ipi.jy_supervise_costs_premiums,
         ipi.jy_supervise_costs_premiums,