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

Merge branch 'dev_jzg_lipf_v20260622'

lipf 2 месяцев назад
Родитель
Сommit
090d6e0d6a

+ 2 - 0
commons/src/main/java/com/jzg/commons/entity/finance/dto/CompanySuperviseSettlementReportDto.java

@@ -2,6 +2,7 @@ package com.jzg.commons.entity.finance.dto;
 
 import io.swagger.v3.oas.annotations.media.Schema;
 import lombok.Data;
+import lombok.NoArgsConstructor;
 
 import java.io.Serial;
 import java.io.Serializable;
@@ -13,6 +14,7 @@ import java.util.List;
  */
 
 @Data
+@NoArgsConstructor
 public class CompanySuperviseSettlementReportDto implements Serializable {
 
 

+ 3 - 0
commons/src/main/java/com/jzg/commons/entity/finance/po/InsFeeFollowOrder.java

@@ -30,6 +30,9 @@ public class InsFeeFollowOrder extends BaseModel {
     @Schema(description = "分支保险公司ID")
     private String partnerCompanyId;
 
+    @Schema(description = "开票类型  1、手续费  2、跟单费  3、驾意险手续费 4、驾意险跟单费 5、平台应收-车险 6、平台应收-非车险")
+    private String invoiceType;
+
     @Schema(description = "应收金额")
     private BigDecimal receivablePremium;
 

+ 3 - 0
commons/src/main/java/com/jzg/commons/entity/finance/vo/FollowInvoicePageListVo.java

@@ -15,6 +15,9 @@ import java.util.List;
 @Schema(description = "保费跟踪订单返回视图")
 public class FollowInvoicePageListVo implements Serializable {
 
+    // 区分类型,2:车险跟单,4:非车险跟单
+    private String invoiceType;
+
     // 逻辑判断符: "and" 或 "or"
     private String logicJudge;
 

+ 7 - 0
commons/src/main/java/com/jzg/commons/entity/finance/vo/InvoiceRecordQueryVo.java

@@ -3,6 +3,8 @@ package com.jzg.commons.entity.finance.vo;
 import com.jzg.commons.core.base.PageRequest;
 import lombok.Data;
 
+import java.util.List;
+
 /**
  * 开票记录查询vo
  */
@@ -24,6 +26,11 @@ public class InvoiceRecordQueryVo extends PageRequest {
      */
     private String invoiceType;
 
+    /**
+     * 开票类型
+     */
+    private List<String> invoiceTypes;
+
     /**
      * 开票方
      */

+ 13 - 0
commons/src/main/java/com/jzg/commons/entity/finance/vo/PlatformCompanyFeeVO.java

@@ -1,4 +1,17 @@
 package com.jzg.commons.entity.finance.vo;
 
+import lombok.Data;
+
 public class PlatformCompanyFeeVO extends FollowCompanyFeeVO{
+
+    // 结算状态
+    private String status;
+
+    public String getStatus() {
+        return status;
+    }
+
+    public void setStatus(String status) {
+        this.status = status;
+    }
 }

+ 6 - 0
commons/src/main/java/com/jzg/commons/entity/finance/vo/QueryFollowIncomeVo.java

@@ -27,4 +27,10 @@ public class QueryFollowIncomeVo  extends PageRequest implements Serializable {
     @Schema(description = "保险公司id")
     private String companyId;
 
+    @Schema(description = "创建开始时间")
+    private String startTime;
+
+    @Schema(description = "创建结束时间")
+    private String endTime;
+
 }

+ 447 - 128
tenant/organization/src/main/java/com/jzg/organization/service/impl/ReceivableServiceImpl.java

@@ -63,6 +63,7 @@ import java.nio.file.Files;
 import java.nio.file.Path;
 import java.nio.file.Paths;
 import java.time.Instant;
+import java.time.LocalDate;
 import java.time.LocalDateTime;
 import java.time.format.DateTimeFormatter;
 import java.time.format.DateTimeParseException;
@@ -745,132 +746,327 @@ public class ReceivableServiceImpl extends ServiceImpl<ReceivableMapper, InsPlyI
     @Override
     public List<FollowCompanyFeeVO> followCompanySuperviseSettlementReport(SettlementReportQueryVo settlementReportQueryVo) {
         log.info("私有协议-跟单结算记录-结算报表: settlementReportQueryVo=[{}]", JSONUtil.toJsonStr(settlementReportQueryVo));
+        List<FollowCompanyFeeVO> resultList = new ArrayList<>();
 
-        // 返回值
-        List<FollowCompanyFeeVO> resultList = CollUtil.newArrayList();
+        // 1. 一次性获取保险公司全量Map,全局复用
+        Map<String, EsmInsCompany> companyMap = getAllInsCompanyMap();
+        if (CollUtil.isEmpty(companyMap)) {
+            return resultList;
+        }
 
-        List<FollowCompanyFeeVO> followCompanyFeeVos = insFeeFollowOrderMapper.selectFollowCompanySettlementReport(settlementReportQueryVo);
-        // 查询所有保险公司,匹配保险公司的id和名称
-        HttpResult<Map<String, EsmInsCompany>> mapHttpResult = esmInsCompanyClient.queryAllCompanyMap();
-        Map<String, EsmInsCompany> data = mapHttpResult.getData();
-        if (CollUtil.isEmpty(data)){
+        // 2. 查询跟单主数据并分组聚合
+        List<FollowCompanyFeeVO> originalFollowList = insFeeFollowOrderMapper.selectFollowCompanySettlementReport(settlementReportQueryVo);
+        if (CollUtil.isNotEmpty(originalFollowList)) {
+            List<FollowCompanyFeeVO> followAggVoList = aggregateFollowData(originalFollowList, companyMap);
+            resultList.addAll(followAggVoList);
+        }
+
+        // 3. 查询额外其他费用收入数据,补充到结果集
+        List<InsPlyIncomeDto> incomeDtoList = queryFollowIncomeData(settlementReportQueryVo);
+        if (CollUtil.isEmpty(incomeDtoList)) {
             return resultList;
         }
 
-        if (CollUtil.isNotEmpty(followCompanyFeeVos)){
-            // 根据分支公司分组
-            Map<String, List<FollowCompanyFeeVO>> followMap = followCompanyFeeVos.stream().collect(Collectors.groupingBy(follow -> follow.getPartnerCompanyId() + "_" + follow.getYear() + "_" + follow.getMonth()));
-            for (Map.Entry<String, List<FollowCompanyFeeVO>> entry : followMap.entrySet()) {
-                // key = 合作公司ID
-                String key = entry.getKey();
-
-                // 分组参数
-                String[] arr = key.split("_");
-                String partnerCompanyId = arr[0];
-                String year = arr[1];
-                String month = arr[2];
-
-
-                // value = 当前公司下所有VO集合
-                List<FollowCompanyFeeVO> voList = entry.getValue();
-
-                // 返回值
-                FollowCompanyFeeVO followCompanyFeeVO = new FollowCompanyFeeVO();
-                followCompanyFeeVO.setPartnerCompanyId(partnerCompanyId);
-
-                List<String> followIds = voList.stream().map(FollowCompanyFeeVO::getFollowId).toList();
-                List<String> invoiceIds = voList.stream().map(FollowCompanyFeeVO::getInvoiceId).toList();
-                List<String> settlementIds = voList.stream().map(FollowCompanyFeeVO::getSettlementId).toList();
-
-                // 根据所有followCompanyFeeVos的followId统计出已开票
-                LambdaQueryWrapper<InsFeeFollowOrder> insFeeFollowOrderLambdaQueryWrapper = new LambdaQueryWrapper<>();
-                insFeeFollowOrderLambdaQueryWrapper.in(InsFeeFollowOrder::getId, followIds);
-                List<InsFeeFollowOrder> insFeeFollowOrders = insFeeFollowOrderMapper.selectList(insFeeFollowOrderLambdaQueryWrapper);
-                // 总金额
-                InsFeeFollowOrder feeFollowOrder = CollUtil.getFirst(insFeeFollowOrders);
-                // 取应收金额
-                BigDecimal receivablePremium = feeFollowOrder.getReceivablePremium();
-                followCompanyFeeVO.setTotalReceivable(receivablePremium);
-
-                BigDecimal totalInvoiced = insFeeFollowOrders.stream().map(InsFeeFollowOrder::getInvoiced).reduce(BigDecimal::add).orElse(BigDecimal.ZERO);
-                // 已开票总金额
-                followCompanyFeeVO.setTotalInvoiced(totalInvoiced);
-
-                // 未结算金额
-                followCompanyFeeVO.setTotalUnInvoiced(receivablePremium.subtract(totalInvoiced));
-
-                // 统计结算金额
-                LambdaQueryWrapper<InsPlyIncomeInvoiceSettlement> insPlyIncomeInvoiceSettlementLambdaQueryWrapper = new LambdaQueryWrapper<>();
-                insPlyIncomeInvoiceSettlementLambdaQueryWrapper.in(InsPlyIncomeInvoiceSettlement::getId, settlementIds);
-                List<InsPlyIncomeInvoiceSettlement> insPlyIncomeInvoiceSettlements = insPlyIncomeInvoiceSettlementMapper.selectList(insPlyIncomeInvoiceSettlementLambdaQueryWrapper);
-                BigDecimal totalSettlementAmount = insPlyIncomeInvoiceSettlements.stream().map(InsPlyIncomeInvoiceSettlement::getActualReceivedAmount).reduce(BigDecimal::add).orElse(BigDecimal.ZERO);
-                // 已结算总金额
-                followCompanyFeeVO.setTotalSettlementAmount(totalSettlementAmount);
+        // 4. 根据筛选条件过滤收入数据(发票、结算时间/状态过滤)
+        List<InsPlyIncomeDto> filterIncomeList = filterIncomeByInvoiceAndSettleCondition(incomeDtoList, settlementReportQueryVo);
+        if (CollUtil.isEmpty(filterIncomeList)) {
+            return resultList;
+        }
+
+        // 5. 将其他费用收入合并进结果集合
+        mergeOtherCostIncomeToResult(filterIncomeList, resultList, companyMap);
+
+        return resultList;
+    }
+
+    // ===================== 私有工具方法 =====================
+
+    /**
+     * 获取全量保险公司Map
+     */
+    private Map<String, EsmInsCompany> getAllInsCompanyMap() {
+        HttpResult<Map<String, EsmInsCompany>> mapHttpResult = esmInsCompanyClient.queryAllCompanyMap();
+        return Optional.ofNullable(mapHttpResult).map(HttpResult::getData).orElse(new HashMap<>(0));
+    }
+
+    /**
+     * 分组聚合跟单主数据(核心优化:批量一次性查ID,而非循环内查库)
+     */
+    private List<FollowCompanyFeeVO> aggregateFollowData(List<FollowCompanyFeeVO> followCompanyFeeVos, Map<String, EsmInsCompany> companyMap) {
+        List<FollowCompanyFeeVO> aggResult = new ArrayList<>();
+        // 按 合作公司ID_年_月 分组
+        Map<String, List<FollowCompanyFeeVO>> followGroupMap = followCompanyFeeVos.stream()
+                .collect(Collectors.groupingBy(this::buildGroupKey));
+
+        // 【核心优化】提前收集所有需要查询的ID,批量查询,彻底解决循环N+1
+        Set<String> allFollowIds = new HashSet<>();
+        Set<String> allSettlementIds = new HashSet<>();
+        followGroupMap.values().forEach(list -> {
+            list.forEach(vo -> {
+                allFollowIds.add(vo.getFollowId());
+                allSettlementIds.add(vo.getSettlementId());
+            });
+        });
+
+        // 批量查询跟单订单
+        Map<String, InsFeeFollowOrder> followOrderMap = batchQueryFollowOrder(allFollowIds);
+        // 批量查询结算单
+        Map<String, InsPlyIncomeInvoiceSettlement> settlementMap = batchQuerySettlement(allSettlementIds);
+
+        // 遍历分组组装VO
+        for (Map.Entry<String, List<FollowCompanyFeeVO>> entry : followGroupMap.entrySet()) {
+            String key = entry.getKey();
+            String[] splitArr = key.split("_");
+            String partnerCompanyId = splitArr[0];
+            String year = splitArr[1];
+            String month = splitArr[2];
+            List<FollowCompanyFeeVO> voList = entry.getValue();
+
+            FollowCompanyFeeVO vo = new FollowCompanyFeeVO();
+            vo.setPartnerCompanyId(partnerCompanyId);
+            vo.setYear(year);
+            vo.setMonth(month);
+            vo.setCompanyName(getCompanyName(partnerCompanyId, companyMap));
+
+            // 汇总当前分组所有followId、settlementId
+            List<String> followIds = voList.stream().map(FollowCompanyFeeVO::getFollowId).distinct().toList();
+            List<String> settlementIds = voList.stream().map(FollowCompanyFeeVO::getSettlementId).distinct().toList();
+
+            // 应收金额(取第一条)
+            InsFeeFollowOrder firstFollow = followOrderMap.get(followIds.get(0));
+            BigDecimal receivablePremium = Optional.ofNullable(firstFollow)
+                    .map(InsFeeFollowOrder::getReceivablePremium)
+                    .orElse(BigDecimal.ZERO);
+            vo.setTotalReceivable(receivablePremium);
+
+            // 已开票总额
+            BigDecimal totalInvoiced = followIds.stream()
+                    .map(followOrderMap::get)
+                    .filter(Objects::nonNull)
+                    .map(InsFeeFollowOrder::getInvoiced)
+                    .reduce(BigDecimal.ZERO, BigDecimal::add);
+            vo.setTotalInvoiced(totalInvoiced);
+            vo.setTotalUnInvoiced(receivablePremium.subtract(totalInvoiced));
+
+            // 已结算总额
+            BigDecimal totalSettlementAmount = settlementIds.stream()
+                    .map(settlementMap::get)
+                    .filter(Objects::nonNull)
+                    .map(InsPlyIncomeInvoiceSettlement::getActualReceivedAmount)
+                    .reduce(BigDecimal.ZERO, BigDecimal::add);
+            vo.setTotalSettlementAmount(totalSettlementAmount);
+            vo.setTotalUnSettlementAmount(totalInvoiced.subtract(totalSettlementAmount));
+
+            aggResult.add(vo);
+        }
+        return aggResult;
+    }
+
+    /**
+     * 批量查询跟单订单,返回ID->实体Map
+     */
+    private Map<String, InsFeeFollowOrder> batchQueryFollowOrder(Set<String> followIdSet) {
+        if (CollUtil.isEmpty(followIdSet)) {
+            return new HashMap<>(0);
+        }
+        LambdaQueryWrapper<InsFeeFollowOrder> wrapper = new LambdaQueryWrapper<>();
+        wrapper.in(InsFeeFollowOrder::getId, followIdSet);
+        List<InsFeeFollowOrder> orderList = insFeeFollowOrderMapper.selectList(wrapper);
+        return orderList.stream()
+                .collect(Collectors.toMap(InsFeeFollowOrder::getId, Function.identity(), (k1, k2) -> k1));
+    }
+
+    /**
+     * 批量查询结算单,返回ID->实体Map
+     */
+    private Map<String, InsPlyIncomeInvoiceSettlement> batchQuerySettlement(Set<String> settlementIdSet) {
+        if (CollUtil.isEmpty(settlementIdSet)) {
+            return new HashMap<>(0);
+        }
+        LambdaQueryWrapper<InsPlyIncomeInvoiceSettlement> wrapper = new LambdaQueryWrapper<>();
+        wrapper.in(InsPlyIncomeInvoiceSettlement::getId, settlementIdSet);
+        List<InsPlyIncomeInvoiceSettlement> settleList = insPlyIncomeInvoiceSettlementMapper.selectList(wrapper);
+        return settleList.stream()
+                .collect(Collectors.toMap(InsPlyIncomeInvoiceSettlement::getId, Function.identity(), (k1, k2) -> k1));
+    }
+
+    /**
+     * 构建分组Key:partnerCompanyId_year_month
+     */
+    private String buildGroupKey(FollowCompanyFeeVO vo) {
+        return StrUtil.format("{}_{}_{}", vo.getPartnerCompanyId(), vo.getYear(), vo.getMonth());
+    }
+
+    /**
+     * 根据合作公司ID获取公司名称
+     */
+    private String getCompanyName(String companyId, Map<String, EsmInsCompany> companyMap) {
+        return Optional.ofNullable(companyMap.get(companyId))
+                .map(EsmInsCompany::getName)
+                .orElse("");
+    }
+
+    /**
+     * 查询收入基础数据
+     */
+    private List<InsPlyIncomeDto> queryFollowIncomeData(SettlementReportQueryVo queryVo) {
+        QueryFollowIncomeVo incomeVo = new QueryFollowIncomeVo(
+                null, null, baseController.getSystemCode(), null,
+                queryVo.getCompanyId(), queryVo.getStartTime(), queryVo.getEndTime()
+        );
+        return baseMapper.queryFollowIncome(incomeVo);
+    }
+
+    /**
+     * 根据发票状态、开票时间、结算时间过滤收入数据
+     * 优化:嵌套anyMatch改为HashMapID映射匹配,O(n²) -> O(n)
+     */
+    private List<InsPlyIncomeDto> filterIncomeByInvoiceAndSettleCondition(List<InsPlyIncomeDto> incomeList, SettlementReportQueryVo queryVo) {
+        String status = queryVo.getStatus();
+        String invoiceStartTime = queryVo.getInvoiceStartTime();
+        String invoiceEndTime = queryVo.getInvoiceEndTime();
+        String settleStartTime = queryVo.getSettlementStartTime();
+        String settleEndTime = queryVo.getSettlementEndTime();
+
+        // 无筛选条件,直接原数据返回
+        boolean noFilterCond = StrUtil.isBlank(status)
+                && (StrUtil.isBlank(invoiceStartTime) || StrUtil.isBlank(invoiceEndTime))
+                && (StrUtil.isBlank(settleStartTime) || StrUtil.isBlank(settleEndTime));
+        if (noFilterCond) {
+            return incomeList;
+        }
 
-                // 未结算金额
-                followCompanyFeeVO.setTotalUnSettlementAmount(totalInvoiced.subtract(totalSettlementAmount));
-                followCompanyFeeVO.setCompanyName(null != data.get(partnerCompanyId) ? data.get(partnerCompanyId).getName() : "");
-                followCompanyFeeVO.setYear(year);
-                followCompanyFeeVO.setMonth(month);
+        // 查询收入关联链路
+        List<String> incomeIds = incomeList.stream().map(InsPlyIncomeDto::getId).distinct().toList();
+        LambdaQueryWrapper<InsPlyIncomeInvoiceLink> linkWrapper = new LambdaQueryWrapper<>();
+        linkWrapper.in(InsPlyIncomeInvoiceLink::getIncomeId, incomeIds);
+        List<InsPlyIncomeInvoiceLink> linkList = insPlyIncomeInvoiceLinkMapper.selectList(linkWrapper);
+        if (CollUtil.isEmpty(linkList)) {
+            return new ArrayList<>(0);
+        }
+
+        // 链路ID映射
+        Map<String, InsPlyIncomeInvoiceLink> linkInvoiceIdMap = linkList.stream()
+                .collect(Collectors.toMap(InsPlyIncomeInvoiceLink::getInvoiceId, Function.identity(), (k1, k2) -> k1));
+        Set<String> linkInvoiceIds = linkInvoiceIdMap.keySet();
+
+        // 查询发票
+        LambdaQueryWrapper<InsPlyIncomeInvoice> invoiceWrapper = new LambdaQueryWrapper<>();
+        invoiceWrapper.in(InsPlyIncomeInvoice::getId, linkInvoiceIds);
+        if (StrUtil.isNotBlank(status)) {
+            invoiceWrapper.eq(InsPlyIncomeInvoice::getStatus, status);
+        }
+        boolean invoiceTimeCond = StrUtil.isNotBlank(invoiceStartTime) && StrUtil.isNotBlank(invoiceEndTime);
+        if (invoiceTimeCond) {
+            invoiceWrapper.between(InsPlyIncomeInvoice::getInvoiceTime, toStartDateTime(invoiceStartTime), toEndDateTime(invoiceEndTime));
+        }
+        List<InsPlyIncomeInvoice> invoiceList = insPlyIncomeInvoiceMapper.selectList(invoiceWrapper);
+        if ((StrUtil.isNotBlank(status) || invoiceTimeCond) && CollUtil.isEmpty(invoiceList)) {
+            return new ArrayList<>(0);
+        }
 
-                resultList.add(followCompanyFeeVO);
+        // 结算时间过滤
+        boolean settleTimeCond = StrUtil.isNotBlank(settleStartTime) && StrUtil.isNotBlank(settleEndTime);
+        if (settleTimeCond) {
+            Set<String> invoiceIdSet = invoiceList.stream().map(InsPlyIncomeInvoice::getId).collect(Collectors.toSet());
+            LambdaQueryWrapper<InsPlyIncomeInvoiceSettlement> settleWrapper = new LambdaQueryWrapper<>();
+            settleWrapper.in(InsPlyIncomeInvoiceSettlement::getInvoiceId, invoiceIdSet);
+            settleWrapper.between(InsPlyIncomeInvoiceSettlement::getCreateTime, toStartDateTime(settleStartTime), toEndDateTime(settleEndTime));
+            List<InsPlyIncomeInvoiceSettlement> settleList = insPlyIncomeInvoiceSettlementMapper.selectList(settleWrapper);
+            if (CollUtil.isEmpty(settleList)) {
+                return new ArrayList<>(0);
             }
+            // 保留存在结算记录的发票
+            Set<String> validSettleInvoiceIds = settleList.stream()
+                    .map(InsPlyIncomeInvoiceSettlement::getInvoiceId)
+                    .collect(Collectors.toSet());
+            invoiceList = invoiceList.stream()
+                    .filter(invoice -> validSettleInvoiceIds.contains(invoice.getId()))
+                    .toList();
         }
 
-        // 根据incomes的partnerCompanyId + signYear + signMonth,过滤resultList的partnerCompanyId + year + month,根据过滤后的数据进行partnerCompanyId + signYear + signMonth的分组,然后将过滤后剩余的数据,将入到resultList中,
-        // 并且设置partnerCompanyId、year、month、totalReceivable为incomes的partnerCompanyId、signYear、signMonth、jq_other_costs_premiums + sy_other_costs_premiums
-        QueryFollowIncomeVo queryFollowIncomeVo = new QueryFollowIncomeVo(null, null, baseController.getSystemCode(), null, settlementReportQueryVo.getCompanyId());
-        List<InsPlyIncomeDto> incomes = baseMapper.queryFollowIncome(queryFollowIncomeVo);
-        if (CollUtil.isNotEmpty(incomes)) {
-            // 1. 将resultList现有数据构建 key: partnerCompanyId_year_month 映射,方便快速匹配
-            Map<String, FollowCompanyFeeVO> existVoMap = resultList.stream()
-                    .collect(Collectors.toMap(
-                            vo -> vo.getPartnerCompanyId() + "_" + vo.getYear() + "_" + vo.getMonth(),
-                            Function.identity(),
-                            (oldVal, newVal) -> oldVal // 重复key保留原有
-                    ));
-
-            // 2. 将incomes按 partnerCompanyId_signYear_signMonth 分组
-            Map<String, List<InsPlyIncomeDto>> incomeGroupMap = incomes.stream()
-                    .collect(Collectors.groupingBy(income -> income.getPartnerCompanyId() + "_" + income.getSignYear() + "_" + income.getSignMonth()));
-
-            // 3. 遍历分组后的收入数据
-            for (Map.Entry<String, List<InsPlyIncomeDto>> entry : incomeGroupMap.entrySet()) {
-                String groupKey = entry.getKey();
-                List<InsPlyIncomeDto> dtoList = entry.getValue();
-                InsPlyIncomeDto firstDto = CollUtil.getFirst(dtoList);
-                String partnerCompanyId = firstDto.getPartnerCompanyId();
-                String signYear = firstDto.getSignYear();
-                String signMonth = firstDto.getSignMonth();
-
-                // 汇总其他费用应收:jq_other_costs_premiums + sy_other_costs_premiums
-                BigDecimal totalOtherReceivable = dtoList.stream()
-                        .map(dto -> new BigDecimal(dto.getJqOtherCostsPremiums()).add(new BigDecimal(dto.getSyOtherCostsPremiums())))
-                        .reduce(BigDecimal::add).orElse(BigDecimal.ZERO);
-
-                // 4. 判断当前分组是否已经存在于resultList(原有跟单数据)
-                FollowCompanyFeeVO existVo = existVoMap.get(groupKey);
-                if (existVo == null) {
-                    // 不存在原有数据,新建VO加入结果集
-                    FollowCompanyFeeVO newVo = new FollowCompanyFeeVO();
-                    newVo.setPartnerCompanyId(partnerCompanyId);
-                    newVo.setYear(signYear);
-                    newVo.setMonth(signMonth);
-                    // 设置总应收为其他费用合计
-                    newVo.setTotalReceivable(totalOtherReceivable);
-                    // 其余金额默认0(无开票、结算数据)
-                    newVo.setTotalInvoiced(BigDecimal.ZERO);
-                    newVo.setTotalUnInvoiced(BigDecimal.ZERO);
-                    newVo.setTotalSettlementAmount(BigDecimal.ZERO);
-                    newVo.setTotalUnSettlementAmount(BigDecimal.ZERO);
-                    // 匹配公司名称
-                    newVo.setCompanyName(null != data.get(partnerCompanyId) ? data.get(partnerCompanyId).getName() : "");
-                    resultList.add(newVo);
-                }
+        // 合法发票ID集合
+        Set<String> validInvoiceIds = invoiceList.stream()
+                .map(InsPlyIncomeInvoice::getId)
+                .collect(Collectors.toSet());
+        // 过滤合法链路
+        List<InsPlyIncomeInvoiceLink> validLinkList = linkList.stream()
+                .filter(link -> validInvoiceIds.contains(link.getInvoiceId()))
+                .toList();
+        Set<String> validIncomeIds = validLinkList.stream()
+                .map(InsPlyIncomeInvoiceLink::getIncomeId)
+                .collect(Collectors.toSet());
+
+        // 最终过滤收入数据
+        return incomeList.stream()
+                .filter(income -> validIncomeIds.contains(income.getId()))
+                .toList();
+    }
+
+    /**
+     * 将其他费用收入合并至结果集,不存在则新增VO
+     */
+    private void mergeOtherCostIncomeToResult(List<InsPlyIncomeDto> incomeList, List<FollowCompanyFeeVO> resultList, Map<String, EsmInsCompany> companyMap) {
+        // 现有结果集Key缓存
+        Map<String, FollowCompanyFeeVO> existVoMap = resultList.stream()
+                .collect(Collectors.toMap(
+                        this::buildGroupKey,
+                        Function.identity(),
+                        (oldVal, newVal) -> oldVal
+                ));
+
+        // 收入分组
+        Map<String, List<InsPlyIncomeDto>> incomeGroupMap = incomeList.stream()
+                .collect(Collectors.groupingBy(dto -> StrUtil.format("{}_{}_{}",
+                        dto.getPartnerCompanyId(), dto.getSignYear(), dto.getSignMonth())));
+
+        for (Map.Entry<String, List<InsPlyIncomeDto>> entry : incomeGroupMap.entrySet()) {
+            String groupKey = entry.getKey();
+            List<InsPlyIncomeDto> dtoList = entry.getValue();
+            InsPlyIncomeDto firstDto = CollUtil.getFirst(dtoList);
+            String partnerCompanyId = firstDto.getPartnerCompanyId();
+            String signYear = firstDto.getSignYear();
+            String signMonth = firstDto.getSignMonth();
+
+            // 安全字符串转BigDecimal,兜底0
+            BigDecimal totalOtherReceivable = dtoList.stream()
+                    .map(dto -> {
+                        BigDecimal jq = safeBigDecimal(dto.getJqOtherCostsPremiums());
+                        BigDecimal sy = safeBigDecimal(dto.getSyOtherCostsPremiums());
+                        return jq.add(sy);
+                    })
+                    .reduce(BigDecimal.ZERO, BigDecimal::add);
+
+            // 已存在直接跳过,不存在新建VO
+            if (!existVoMap.containsKey(groupKey)) {
+                FollowCompanyFeeVO newVo = new FollowCompanyFeeVO();
+                newVo.setPartnerCompanyId(partnerCompanyId);
+                newVo.setYear(signYear);
+                newVo.setMonth(signMonth);
+                newVo.setTotalReceivable(totalOtherReceivable);
+                newVo.setTotalInvoiced(BigDecimal.ZERO);
+                newVo.setTotalUnInvoiced(BigDecimal.ZERO);
+                newVo.setTotalSettlementAmount(BigDecimal.ZERO);
+                newVo.setTotalUnSettlementAmount(BigDecimal.ZERO);
+                newVo.setCompanyName(getCompanyName(partnerCompanyId, companyMap));
+                resultList.add(newVo);
             }
         }
+    }
 
-        return resultList;
+    /**
+     * 字符串安全转为BigDecimal,空/空串返回0
+     */
+    private BigDecimal safeBigDecimal(String numStr) {
+        if (StrUtil.isBlank(numStr)) {
+            return BigDecimal.ZERO;
+        }
+        try {
+            return new BigDecimal(numStr);
+        } catch (NumberFormatException e) {
+            log.warn("数值转换异常,值:{}", numStr, e);
+            return BigDecimal.ZERO;
+        }
     }
 
     /**
@@ -913,6 +1109,16 @@ public class ReceivableServiceImpl extends ServiceImpl<ReceivableMapper, InsPlyI
             //platformCompanyFeeVo.setTotalUnSettlementAmount(BigDecimalUtil.subtract(BigDecimalUtil.subtract(platformCompanyFeeVo.getTotalReceivable(),platformCompanyFeeVo.getTotalSettlementAmount()), platformCompanyFeeVo.getTotalPaymentDifference()));
             platformCompanyFeeVo.setTotalUnSettlementAmount(BigDecimalUtil.subtract(platformCompanyFeeVo.getTotalReceivable(),platformCompanyFeeVo.getTotalSettlementAmount()));
         }
+        if (StrUtil.isNotBlank(settlementReportQueryVo.getStatus())){
+            if ("1".equals(settlementReportQueryVo.getStatus())){
+                // 过滤结算状态
+                platformCompanyFeeVos = platformCompanyFeeVos.stream().filter(plat -> null != plat.getTotalSettlementAmount() && BigDecimal.ZERO.compareTo(plat.getTotalSettlementAmount()) != 0).toList();
+            }else if ("0".equals(settlementReportQueryVo.getStatus())){
+                // 过滤结算状态
+                platformCompanyFeeVos = platformCompanyFeeVos.stream().filter(plat -> null == plat.getTotalSettlementAmount() || BigDecimal.ZERO.compareTo(plat.getTotalSettlementAmount()) == 0).toList();
+            }
+        }
+
         return platformCompanyFeeVos;
     }
 
@@ -1331,6 +1537,7 @@ public class ReceivableServiceImpl extends ServiceImpl<ReceivableMapper, InsPlyI
             invoice.setOverinflatedAmount(invoicingVo.getOverinflatedAmount());
             invoice.setReceivableSupervisePremium(invoicingVo.getReceivableSupervisePremium());
             invoice.setTaxPoint(invoicingVo.getTaxPoint());
+            invoice.setInvoiceTime(LocalDateTime.now());
             insPlyIncomeInvoiceMapper.insert(invoice);
             List<InsPlyIncomeInvoiceLink> invoicingLinkList = new ArrayList<>();
             invoicingVo.getIncomeIds().forEach(incomeId -> {
@@ -1651,6 +1858,7 @@ public class ReceivableServiceImpl extends ServiceImpl<ReceivableMapper, InsPlyI
             invoice.setTaxPoint(invoicingVo.getTaxPoint());
             invoice.setContactPerson(platformSettlementVo.getInvoicingVo().getContactPerson());
             invoice.setContactPersonPhone(platformSettlementVo.getInvoicingVo().getContactPersonPhone());
+            invoice.setInvoiceTime(LocalDateTime.now());
 
             List<InsPlyIncomeInvoiceLink> invoicingLinkList = new ArrayList<>();
 
@@ -3609,6 +3817,7 @@ public class ReceivableServiceImpl extends ServiceImpl<ReceivableMapper, InsPlyI
             order.setReconciliationAmount(item.getReconciliationAmount());
             order.setFalselyIncreasedDifference(item.getFalselyIncreasedDifference());
             order.setFalselyIncreasedReason(item.getFalselyIncreasedReason());
+            order.setInvoiceType(vo.getInvoiceType());
 
             orderList.add(order);
 
@@ -3664,6 +3873,7 @@ public class ReceivableServiceImpl extends ServiceImpl<ReceivableMapper, InsPlyI
         invoice.setPaymentReason(vo.getPaymentReason());
         invoice.setReceivableSupervisePremium(vo.getReceivableSupervisePremium());
         invoice.setTaxPoint(vo.getTaxPoint());
+        invoice.setInvoiceTime(LocalDateTime.now());
         // 初始状态:0-待处理
         invoice.setStatus("0");
         return invoice;
@@ -3724,7 +3934,7 @@ public class ReceivableServiceImpl extends ServiceImpl<ReceivableMapper, InsPlyI
         String systemCode = baseController.getUserSystemCode();
 
         // 查询该年份下的所有跟进收入数据,并按合作方公司ID进行分组
-        QueryFollowIncomeVo queryFollowIncomeVo = new QueryFollowIncomeVo(startYear, endYear, systemCode, null, null);
+        QueryFollowIncomeVo queryFollowIncomeVo = new QueryFollowIncomeVo(startYear, endYear, systemCode, null, null, null, null);
         List<InsPlyIncomeDto> incomes = baseMapper.queryFollowIncome(queryFollowIncomeVo);
 
         // ====================== 增加动态条件过滤 ======================
@@ -3793,7 +4003,7 @@ public class ReceivableServiceImpl extends ServiceImpl<ReceivableMapper, InsPlyI
                 .collect(Collectors.groupingBy(InsPlyIncomeDto::getPartnerCompanyId));
 
         // 查询该年份下已开票的数据,并聚合为 [合作方ID_月份 -> 已开票金额] 的映射
-        Map<String, BigDecimal> invoicedMap = buildInvoicedMap(startYear, endYear);
+        Map<String, BigDecimal> invoicedMap = buildInvoicedMap(startYear, endYear, followInvoicePageListVo.getInvoiceType());
 
         // 遍历分组数据,组装最终的返回结果
         List<InsFeeFollowOrderVo> result = new ArrayList<>();
@@ -3806,8 +4016,14 @@ public class ReceivableServiceImpl extends ServiceImpl<ReceivableMapper, InsPlyI
                 continue;
             }
 
+            Map<Integer, BigDecimal> monthReceivableMap = new HashMap<>();
+            // 2为车险,4为非车险
             // 计算该合作方每月的应收保费
-            Map<Integer, BigDecimal> monthReceivableMap = calculateMonthlyReceivable(list);
+            if ("2".equals(followInvoicePageListVo.getInvoiceType())){
+                monthReceivableMap = calculateMonthlyReceivable(list);
+            }else if ("4".equals(followInvoicePageListVo.getInvoiceType())){
+                monthReceivableMap = jyCalculateMonthlyReceivable(list);
+            }
 
             // 遍历12个月份,组装VO对象
             InsPlyIncomeDto firstItem = list.get(0);
@@ -3829,20 +4045,19 @@ public class ReceivableServiceImpl extends ServiceImpl<ReceivableMapper, InsPlyI
     /**
      * 构建已开票金额映射表
      * <p>
-     * 该方法用于查询指定年份范围内的跟单订单数据,并按"合作方ID_月份"维度聚合计算已开票金额,包括以下处理逻辑:
-     * 1. 根据起始年份和结束年份查询跟单订单列表
-     * 2. 按"合作方ID_月份"进行分组
-     * 3. 对每组数据进行归约计算,累加已开票金额
-     * 4. 返回合作方和月份到已开票总额的映射关系
+     * 根据指定的年份范围和发票类型,查询保险费用跟踪订单数据,
+     * 并按合作伙伴公司和月份分组统计已开票金额总和。
      * </p>
      *
-     * @param startYear 起始年份,用于指定查询范围的开始年份
-     * @param endYear 结束年份,用于指定查询范围的结束年份
-     * @return Map<String, BigDecimal> 返回已开票金额映射表,key为"合作方ID_月份"格式(如"COMP001_5"),value为该合作方在该月份的已开票金额总和
+     * @param startYear 起始年份
+     * @param endYear 结束年份
+     * @param invoiceType 发票类型
+     * @return Map<String, BigDecimal> 键格式为"合作伙伴公司ID_月份",值为该时间段内的已开票金额总和
      */
-    private Map<String, BigDecimal> buildInvoicedMap(Integer startYear, Integer endYear) {
+    private Map<String, BigDecimal> buildInvoicedMap(Integer startYear, Integer endYear, String invoiceType) {
         QueryWrapper<InsFeeFollowOrder> queryWrapper = new QueryWrapper<>();
         queryWrapper.between("year", startYear, endYear);
+        queryWrapper.eq("invoice_type", invoiceType);
         List<InsFeeFollowOrder> invoicedList = insFeeFollowOrderMapper.selectList(queryWrapper);
 
         return invoicedList.stream().collect(Collectors.groupingBy(
@@ -3889,6 +4104,27 @@ public class ReceivableServiceImpl extends ServiceImpl<ReceivableMapper, InsPlyI
                 ));
     }
 
+    /**
+     * 非车险跟单
+     * @param list
+     * @return
+     */
+    private Map<Integer, BigDecimal> jyCalculateMonthlyReceivable(List<InsPlyIncomeDto> list) {
+        return list.stream()
+                .filter(item -> item.getSigningTime() != null) // 防御性编程:过滤掉签约时间为空的数据
+                .collect(Collectors.groupingBy(
+                        item -> item.getSigningTime().getMonthValue(),
+                        Collectors.reducing(
+                                BigDecimal.ZERO,
+                                item -> {
+                                    // 优化点:将字符串转换为BigDecimal,避免在循环中频繁new对象
+                                    return BigDecimalUtil.valueOf(item.getJyOtherCostsPremiums());
+                                },
+                                BigDecimal::add
+                        )
+                ));
+    }
+
     /**
      * 组装单个月的发票跟进VO对象
      * <p>
@@ -4160,9 +4396,9 @@ public class ReceivableServiceImpl extends ServiceImpl<ReceivableMapper, InsPlyI
         }
         invoiceRecordQueryVo.setSystemCode(baseController.getSystemCode());
         Page<InvoiceRecordResult> invoiceRecordList = null;
-        if ("2".equals(invoiceRecordQueryVo.getInvoiceType())){
+        if (invoiceRecordQueryVo.getInvoiceTypes().contains("2") || invoiceRecordQueryVo.getInvoiceTypes().contains("4")){
             invoiceRecordList = baseMapper.getFollowInvoiceRecordList(invoiceRecordQueryVo.getPage(), invoiceRecordQueryVo);
-        }else if ("1".equals(invoiceRecordQueryVo.getInvoiceType())){
+        }else if(invoiceRecordQueryVo.getInvoiceTypes().contains("1") || invoiceRecordQueryVo.getInvoiceTypes().contains("3")){
             invoiceRecordList = baseMapper.getInvoiceRecordList(invoiceRecordQueryVo.getPage(), invoiceRecordQueryVo);
         }
         List<InvoiceRecordResult> records = invoiceRecordList.getRecords();
@@ -4972,10 +5208,63 @@ public class ReceivableServiceImpl extends ServiceImpl<ReceivableMapper, InsPlyI
         // 1. 先将有数据的保险公司进行汇总
         // 累计应收金额, 应收手续费(手续费), 应收手续费(手续费)
         List<CompanySuperviseSettlementReportDto> allCompaniesIncomeDatas = baseMapper.queryCumulativeAccountsReceivable(systemCode, queryVo);
-        allCompaniesIncomeDatas = allCompaniesIncomeDatas.stream().peek(action-> action.setId(action.getCompanyId())).toList();
         // for test, 查看一家公司的数据,将不可变对象变成 可变对象
 //        allCompaniesIncomeDatas = allCompaniesIncomeDatas.stream().filter(action-> "1738811735599338932".equals(action.getCompanyId())).toList();
 //        allCompaniesIncomeDatas = new ArrayList<>(allCompaniesIncomeDatas);
+
+        // 直接从allCompaniesIncomeDatas获取到incomeId,然后过滤数据
+        List<InsPlyIncomeDto> dtoList = allCompaniesIncomeDatas.stream()
+                .map(CompanySuperviseSettlementReportDto::getId)
+                .map(id -> {
+                    InsPlyIncomeDto dto = new InsPlyIncomeDto();
+                    dto.setId(id);
+                    return dto;
+                })
+                .toList();
+        // 过滤数据
+        List<InsPlyIncomeDto> filterIncomeList = filterIncomeByInvoiceAndSettleCondition(dtoList, queryVo);
+        allCompaniesIncomeDatas = allCompaniesIncomeDatas.stream().filter(all -> filterIncomeList.stream().anyMatch(x -> x.getId().equals(all.getId()))).toList();
+
+        // 将allCompaniesIncomeDatas中相同的companyId的totalReceivable、totalFollowFee、superviseFee、followFee数据相加,并只保留一条
+        // 按公司ID分组聚合求和
+        Map<String, List<CompanySuperviseSettlementReportDto>> groupByCompany = allCompaniesIncomeDatas.stream()
+                .collect(Collectors.groupingBy(CompanySuperviseSettlementReportDto::getCompanyId));
+
+        // 聚合结果集合
+        List<CompanySuperviseSettlementReportDto> resultList = new ArrayList<>();
+        for (Map.Entry<String, List<CompanySuperviseSettlementReportDto>> entry : groupByCompany.entrySet()) {
+            List<CompanySuperviseSettlementReportDto> groupList = entry.getValue();
+            CompanySuperviseSettlementReportDto sumDto = new CompanySuperviseSettlementReportDto();
+            // 赋值固定字段(取第一条即可)
+            sumDto.setCompanyId(entry.getKey());
+            CompanySuperviseSettlementReportDto first = groupList.get(0);
+            sumDto.setCompanyName(first.getCompanyName());
+            // 数值累加
+            BigDecimal totalReceivable = groupList.stream()
+                    .map(x -> new BigDecimal(x.getTotalReceivable()))
+                    .reduce(BigDecimal.ZERO, BigDecimal::add);
+            BigDecimal totalFollowFee = groupList.stream()
+                    .map(x -> new BigDecimal(x.getTotalFollowFee()))
+                    .reduce(BigDecimal.ZERO, BigDecimal::add);
+            BigDecimal superviseFee = groupList.stream()
+                    .map(x -> new BigDecimal(x.getSuperviseFee()))
+                    .reduce(BigDecimal.ZERO, BigDecimal::add);
+            BigDecimal followFee = groupList.stream()
+                    .map(x -> new BigDecimal(x.getFollowFee()))
+                    .reduce(BigDecimal.ZERO, BigDecimal::add);
+
+            sumDto.setTotalReceivable(totalReceivable.toString());
+            sumDto.setTotalFollowFee(totalFollowFee.toString());
+            sumDto.setSuperviseFee(superviseFee.toString());
+            sumDto.setFollowFee(followFee.toString());
+            sumDto.setParentId(first.getParentId());
+            resultList.add(sumDto);
+        }
+        // 最终聚合完成的数据
+        allCompaniesIncomeDatas = resultList;
+
+        allCompaniesIncomeDatas = allCompaniesIncomeDatas.stream().peek(action-> action.setId(action.getCompanyId())).toList();
+
         if (CollUtil.isEmpty(allCompaniesIncomeDatas)) {
             String msg = String.format("租户%s下暂时没有手续费",systemCode);
             log.info(msg);
@@ -4988,6 +5277,14 @@ public class ReceivableServiceImpl extends ServiceImpl<ReceivableMapper, InsPlyI
         }
         // 2. 汇总后,计算得到已开票,未开票,已结算,未结算的数据
         allCompaniesIncomeDatas = this.calStatisAmount(allCompaniesIncomeDatas, queryVo, systemCode);
+        // 保留已开票的数据
+        if ("1".equals(queryVo.getInvoiceStatus())){
+            allCompaniesIncomeDatas = allCompaniesIncomeDatas.stream().filter(action-> StrUtil.isNotBlank(action.getSxfUnSettledAmount()) && !"0".equals(action.getSxfUnSettledAmount())).toList();
+        }else if ("0".equals(queryVo.getInvoiceStatus())){
+            // 保留未开票的数据
+            allCompaniesIncomeDatas = allCompaniesIncomeDatas.stream().filter(action-> StrUtil.isBlank(action.getSxfUnSettledAmount()) || "0".equals(action.getSxfUnSettledAmount())).toList();
+        }
+
         // 3. 填充保险公司的父级保险公司
         allCompaniesIncomeDatas = this.fillParentCompany(allCompaniesIncomeDatas);
         log.info("构建树形结构之前的数据:allCompaniesIncomeDatas=[{}]", JSONUtil.toJsonStr(allCompaniesIncomeDatas));
@@ -5657,5 +5954,27 @@ public class ReceivableServiceImpl extends ServiceImpl<ReceivableMapper, InsPlyI
                 .set(InsPlyIncomeInvoice::getUpdateTime, LocalDateTime.now())
                 .eq(InsPlyIncomeInvoice::getId, invoiceId));
     }
+
+    /**
+     * yyyy-MM-dd 转当天起始 LocalDateTime
+     */
+    public static LocalDateTime toStartDateTime(String dateStr) {
+        if (StrUtil.isBlank(dateStr)){
+            return null;
+        }
+        LocalDate date = LocalDate.parse(dateStr, DateTimeFormatter.ISO_LOCAL_DATE);
+        return date.atStartOfDay();
+    }
+
+    /**
+     * yyyy-MM-dd 转当天结束 LocalDateTime
+     */
+    public static LocalDateTime toEndDateTime(String dateStr) {
+        if (StrUtil.isBlank(dateStr)){
+            return null;
+        }
+        LocalDate date = LocalDate.parse(dateStr, DateTimeFormatter.ISO_LOCAL_DATE);
+        return date.atTime(23, 59, 59, 999999999);
+    }
 }
 

+ 19 - 9
tenant/organization/src/main/resources/mapper/ReceivableMapper.xml

@@ -283,7 +283,6 @@
         LEFT JOIN esm_ins_company eic on ipi.company_id = eic.id AND eic.is_delete = 0
         where
             ipi.is_delete  = 0
-            -- and ipi.settlement_status = '0'  -- 已经结算的车辆,在应收订单里面,还需要能查询到
     </sql>
     <!-- 查询应收订单总额 lipf 2026年6月4日10:22:57 -->
     <select id="queryAllTotalReceivablePremiumByOrderNo" resultType="java.math.BigDecimal">
@@ -338,8 +337,6 @@
         </if>
         <if test="receivableQueryVo.queryType!= null and (receivableQueryVo.queryType == 3 or receivableQueryVo.queryType == 4)">
             AND ipi.jy_premium != 0
-<!--            AND ipi.jy_supervise_settlement = 0-->
-<!--            AND ipi.jy_other_settlement = 0-->
         </if>
         <if test="receivableQueryVo.licenseNo != null and receivableQueryVo.licenseNo != ''">
             AND ipi.license_no LIKE CONCAT('%', #{receivableQueryVo.licenseNo}, '%')
@@ -1471,6 +1468,7 @@
         eic.name as company_name,
         eic.name_simple as companyNameSimple,
         sum( ipiis.actual_received_amount ) AS actual_received_amount,
+        GROUP_CONCAT(DISTINCT ipiis.settlement_payment_reason SEPARATOR ',') AS settlement_payment_reason,
         ipii.status,
         ipii.payment_reason
         FROM
@@ -1491,6 +1489,12 @@
             <if test="invoiceRecordQueryVo.invoiceType != null and invoiceRecordQueryVo.invoiceType != ''">
                 AND ipii.invoice_type = #{invoiceRecordQueryVo.invoiceType}
             </if>
+            <if test="invoiceRecordQueryVo.invoiceTypes != null and invoiceRecordQueryVo.invoiceTypes != ''">
+                AND ipii.invoice_type IN
+                <foreach collection="invoiceRecordQueryVo.invoiceTypes" item="invoiceType" open="(" separator="," close=")">
+                    #{invoiceType}
+                </foreach>
+            </if>
             <if test="invoiceRecordQueryVo.invoiceParty != null and invoiceRecordQueryVo.invoiceParty != ''">
                 AND ipii.invoice_party = #{invoiceRecordQueryVo.invoiceParty}
             </if>
@@ -1561,6 +1565,12 @@
             <if test="invoiceRecordQueryVo.companyId != null and invoiceRecordQueryVo.companyId != ''">
                 AND ipii.company_id = #{invoiceRecordQueryVo.companyId}
             </if>
+            <if test="invoiceRecordQueryVo.invoiceTypes != null and invoiceRecordQueryVo.invoiceTypes != ''">
+                AND ipii.invoice_type IN
+                <foreach collection="invoiceRecordQueryVo.invoiceTypes" item="invoiceType" open="(" separator="," close=")">
+                    #{invoiceType}
+                </foreach>
+            </if>
             <if test="invoiceRecordQueryVo.invoiceParty != null and invoiceRecordQueryVo.invoiceParty != ''">
                 AND ipii.invoice_party = #{invoiceRecordQueryVo.invoiceParty}
             </if>
@@ -1905,6 +1915,7 @@
     <select id="queryCumulativeAccountsReceivable"
             resultType="com.jzg.commons.entity.finance.dto.CompanySuperviseSettlementReportDto">
         select
+        ipi.id,
         eic.parent_id,
         ipi.company_id,
         ipi.system_code,
@@ -1929,6 +1940,7 @@
             </if>
         </where>
         group by
+        ipi.id,
         eic.parent_id,
         ipi.company_id,
         ipi.system_code
@@ -2041,7 +2053,6 @@
         <where>
             a.is_delete=0
             AND a.agreement_type = 2
-            AND a.signing_time is not null
             <if test="query.startYear != null and query.endYear != null">
                 AND YEAR(a.signing_time) BETWEEN #{query.startYear} AND #{query.endYear}
             </if>
@@ -2051,6 +2062,9 @@
             <if test="query.companyId != null and query.companyId != ''">
                 AND a.company_id = #{query.companyId}
             </if>
+            <if test="query.startTime != null and query.startTime != '' and query.endTime != null and query.endTime != ''">
+                AND a.create_time between #{query.startTime} and #{query.endTime}
+            </if>
             <if test="query.companyIdList != null and query.companyIdList.size() > 0" >
                 AND a.company_id in
                 <foreach collection="query.companyIdList" item="item" open="(" separator="," close=")">
@@ -2102,11 +2116,7 @@
             </if>
             -- 跟单订单创建时间范围
             <if test="query.startTime != null and query.startTime != '' and query.endTime != null and query.endTime != ''">
-                AND ipii.create_time BETWEEN #{query.startTime} AND #{query.endTime}
-            </if>
-            -- 发票状态筛选
-            <if test="query.status != null">
-                AND ipii.status = #{query.status}
+                AND ipi.create_time BETWEEN #{query.startTime} AND #{query.endTime}
             </if>
             -- 开票时间范围
             <if test="query.invoiceStartTime != null and query.invoiceStartTime != '' and query.invoiceEndTime != null and query.invoiceEndTime != ''">