shiyunteng
2 天以前 8de09297dcc5393cc8542f29318b17f5696d4f8d
platformx-business-finance-biz/src/main/java/com/by4cloud/platformx/business/service/impl/StatisticServiceImpl.java
@@ -1,27 +1,34 @@
package com.by4cloud.platformx.business.service.impl;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.by4cloud.platformx.admin.api.entity.SysDept;
import com.by4cloud.platformx.admin.api.entity.SysDictItem;
import com.by4cloud.platformx.admin.api.feign.RemoteDeptService;
import com.by4cloud.platformx.admin.api.feign.RemoteDictService;
import com.by4cloud.platformx.business.dto.AgingQueryDTO;
import com.by4cloud.platformx.business.dto.AnalysisCommonDTO;
import com.by4cloud.platformx.business.entity.BusinessCustomer;
import com.by4cloud.platformx.business.mapper.BusinessCustomerMapper;
import com.by4cloud.platformx.business.mapper.ContractMapper;
import com.by4cloud.platformx.business.mapper.ContractPaymentScheduleMapper;
import com.by4cloud.platformx.business.dto.HomeQueryDTO;
import com.by4cloud.platformx.business.entity.*;
import com.by4cloud.platformx.business.mapper.*;
import com.by4cloud.platformx.business.service.StatisticService;
import com.by4cloud.platformx.business.vo.*;
import com.by4cloud.platformx.common.core.util.R;
import com.by4cloud.platformx.common.data.datascope.DataScope;
import com.by4cloud.platformx.common.security.util.SecurityUtils;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
@@ -34,6 +41,11 @@
   private final ContractMapper contractMapper;
   private final ContractPaymentScheduleMapper contractPaymentScheduleMapper;
   private final BusinessCustomerMapper businessCustomerMapper;
   private final PaymentSlipMapper paymentSlipMapper;
   private final ContractOutBoundMapper contractOutBoundMapper;
   private final ContractInvoiceMapper contractInvoiceMapper;
   private final CurrentOverdueMapper currentOverdueMapper;
   private final HistoryOverdueMapper historyOverdueMapper;
   private final RemoteDeptService remoteDeptService;
   private final RemoteDictService remoteDictService;
@@ -450,7 +462,7 @@
      R<List<SysDictItem>> r = remoteDictService.getDictByType("industry_sector");
      List<SysDictItem> items = r.getData();
      if (ArrayUtil.isEmpty(items.toArray())){
         return R.failed("地区字典分类获取异常");
         return R.failed("行业字典分类获取异常");
      }
      List<AgingAnalysisVo> result = new ArrayList<>();
      AgingQueryDTO queryDTO = new AgingQueryDTO();
@@ -699,4 +711,553 @@
      }
      return companyAgingVo;
   }
   @Override
   public R agingAnalysisByMarket(AnalysisCommonDTO commonDTO) {
      R<List<SysDictItem>> r = remoteDictService.getDictByType("market_type");
      List<SysDictItem> items = r.getData();
      if (ArrayUtil.isEmpty(items.toArray())){
         return R.failed("市场类型字典分类获取异常");
      }
      List<AgingAnalysisVo> result = new ArrayList<>();
      AgingQueryDTO queryDTO = new AgingQueryDTO();
      List<AgingVo> agingVoList = contractPaymentScheduleMapper.selectAgingTotal(null);
      items.stream().forEach(item->{
         AgingAnalysisVo agingAnalysisVo = new AgingAnalysisVo();
         agingAnalysisVo.setCompanyName(item.getLabel());
         queryDTO.setClassId(item.getItemValue());
         List<AgingVo> companyAgingVo = contractPaymentScheduleMapper.selectAgingTotal(queryDTO);
         //补全数据
         if (ArrayUtil.isEmpty(companyAgingVo.toArray())){
            companyAgingVo = new ArrayList<>();
            AgingVo agingVo1 = new AgingVo("0-30天",new BigDecimal("0"),null);
            AgingVo agingVo2 = new AgingVo("31-60天",new BigDecimal("0"),null);
            AgingVo agingVo3 = new AgingVo("61-90天",new BigDecimal("0"),null);
            AgingVo agingVo4 = new AgingVo("91-180天",new BigDecimal("0"),null);
            AgingVo agingVo5 = new AgingVo("181-365天",new BigDecimal("0"),null);
            AgingVo agingVo6 = new AgingVo("1年以上",new BigDecimal("0"),null);
            companyAgingVo.add(agingVo1);
            companyAgingVo.add(agingVo2);
            companyAgingVo.add(agingVo3);
            companyAgingVo.add(agingVo4);
            companyAgingVo.add(agingVo5);
            companyAgingVo.add(agingVo6);
         }else {
            List<String> overdueRanges = companyAgingVo.stream().map(AgingVo::getOverdueRange).collect(Collectors.toList());
            if (!ArrayUtil.contains(overdueRanges.toArray(),"0-30天")){
               AgingVo agingVo1 = new AgingVo("0-30天",new BigDecimal("0"),null);
               companyAgingVo.add(agingVo1);
            }
            if (!ArrayUtil.contains(overdueRanges.toArray(),"31-60天")){
               AgingVo agingVo2 = new AgingVo("31-60天",new BigDecimal("0"),null);
               companyAgingVo.add(agingVo2);
            }
            if (!ArrayUtil.contains(overdueRanges.toArray(),"61-90天")){
               AgingVo agingVo3 = new AgingVo("61-90天",new BigDecimal("0"),null);
               companyAgingVo.add(agingVo3);
            }
            if (!ArrayUtil.contains(overdueRanges.toArray(),"91-180天")){
               AgingVo agingVo4 = new AgingVo("91-180天",new BigDecimal("0"),null);
               companyAgingVo.add(agingVo4);
            }
            if (!ArrayUtil.contains(overdueRanges.toArray(),"181-365天")){
               AgingVo agingVo5 = new AgingVo("181-365天",new BigDecimal("0"),null);
               companyAgingVo.add(agingVo5);
            }
            if (!ArrayUtil.contains(overdueRanges.toArray(),"1年以上")){
               AgingVo agingVo6 = new AgingVo("1年以上",new BigDecimal("0"),null);
               companyAgingVo.add(agingVo6);
            }
         }
         agingAnalysisVo.setAmount(companyAgingVo.stream().map(AgingVo::getTotalAmount).collect(Collectors.toList()));
         List<AgingVo> finalCompanyAgingVo = companyAgingVo;
         agingAnalysisVo.setPercent(IntStream.range(0, agingVoList.size())
               .mapToObj(i -> {
                  BigDecimal part = finalCompanyAgingVo.get(i).getTotalAmount();
                  BigDecimal total = agingVoList.get(i).getTotalAmount();
                  if (total == null || total.compareTo(BigDecimal.ZERO) == 0) {
                     return null;
                  }
                  return part.divide(total, 4, RoundingMode.HALF_UP)
                        .multiply(new BigDecimal("100"))
                        .setScale(2, RoundingMode.HALF_UP);
               })
               .collect(Collectors.toList()));
         result.add(agingAnalysisVo);
      });
      //合计
      AgingAnalysisVo agingAnalysisVo = new AgingAnalysisVo();
      agingAnalysisVo.setCompanyName("合计");
      agingAnalysisVo.setAmount(agingVoList.stream().map(AgingVo::getTotalAmount).collect(Collectors.toList()));
      List<BigDecimal> percent = IntStream.range(0, agingAnalysisVo.getAmount().size())
            .mapToObj(i -> {
               if (agingAnalysisVo.getAmount().get(i) == null || agingAnalysisVo.getAmount().get(i).compareTo(BigDecimal.ZERO) == 0) {
                  return null;
               }else {
                  return new BigDecimal("100");
               }
            })
            .collect(Collectors.toList());
      agingAnalysisVo.setPercent(percent);
      result.add(agingAnalysisVo);
      return R.ok(result);
   }
   @Override
   public R agingAnalysisTotalScale(AnalysisCommonDTO commonDTO) {
      List<Long> compIds = new ArrayList<>();
      compIds.add(Long.valueOf(sgb));
      compIds.add(Long.valueOf(smj));
      compIds.add(Long.valueOf(tfgs));
      compIds.add(Long.valueOf(ymj));
      compIds.add(Long.valueOf(jxc));
      List<AgingAnalysisVo> result = new ArrayList<>();
      AgingQueryDTO queryDTO = new AgingQueryDTO();
      List<AgingVo> agingVoList = contractPaymentScheduleMapper.selectAgingTotalScale(null);
      compIds.stream().forEach(compId->{
         R<SysDept> r = remoteDeptService.getById(compId);
         if (!r.isOk()){
            return;
         }
         SysDept dept = r.getData();
         AgingAnalysisVo agingAnalysisVo = new AgingAnalysisVo();
         agingAnalysisVo.setCompanyName(dept.getOrgName());
         queryDTO.setCompanyId(dept.getDeptId());
         List<AgingVo> companyAgingVo = contractPaymentScheduleMapper.selectAgingTotalScale(queryDTO);
         //补全数据
         if (ArrayUtil.isEmpty(companyAgingVo.toArray())){
            companyAgingVo = new ArrayList<>();
            AgingVo agingVo1 = new AgingVo("0-30天",new BigDecimal("0"),null);
            AgingVo agingVo2 = new AgingVo("31-60天",new BigDecimal("0"),null);
            AgingVo agingVo3 = new AgingVo("61-90天",new BigDecimal("0"),null);
            AgingVo agingVo4 = new AgingVo("91-180天",new BigDecimal("0"),null);
            AgingVo agingVo5 = new AgingVo("181-365天",new BigDecimal("0"),null);
            AgingVo agingVo6 = new AgingVo("1年以上",new BigDecimal("0"),null);
            companyAgingVo.add(agingVo1);
            companyAgingVo.add(agingVo2);
            companyAgingVo.add(agingVo3);
            companyAgingVo.add(agingVo4);
            companyAgingVo.add(agingVo5);
            companyAgingVo.add(agingVo6);
         }else {
            List<String> overdueRanges = companyAgingVo.stream().map(AgingVo::getOverdueRange).collect(Collectors.toList());
            if (!ArrayUtil.contains(overdueRanges.toArray(),"0-30天")){
               AgingVo agingVo1 = new AgingVo("0-30天",new BigDecimal("0"),null);
               companyAgingVo.add(agingVo1);
            }
            if (!ArrayUtil.contains(overdueRanges.toArray(),"31-60天")){
               AgingVo agingVo2 = new AgingVo("31-60天",new BigDecimal("0"),null);
               companyAgingVo.add(agingVo2);
            }
            if (!ArrayUtil.contains(overdueRanges.toArray(),"61-90天")){
               AgingVo agingVo3 = new AgingVo("61-90天",new BigDecimal("0"),null);
               companyAgingVo.add(agingVo3);
            }
            if (!ArrayUtil.contains(overdueRanges.toArray(),"91-180天")){
               AgingVo agingVo4 = new AgingVo("91-180天",new BigDecimal("0"),null);
               companyAgingVo.add(agingVo4);
            }
            if (!ArrayUtil.contains(overdueRanges.toArray(),"181-365天")){
               AgingVo agingVo5 = new AgingVo("181-365天",new BigDecimal("0"),null);
               companyAgingVo.add(agingVo5);
            }
            if (!ArrayUtil.contains(overdueRanges.toArray(),"1年以上")){
               AgingVo agingVo6 = new AgingVo("1年以上",new BigDecimal("0"),null);
               companyAgingVo.add(agingVo6);
            }
         }
         agingAnalysisVo.setAmount(companyAgingVo.stream().map(AgingVo::getTotalAmount).collect(Collectors.toList()));
         List<AgingVo> finalCompanyAgingVo = companyAgingVo;
         agingAnalysisVo.setPercent(IntStream.range(0, agingVoList.size())
               .mapToObj(i -> {
                  BigDecimal part = finalCompanyAgingVo.get(i).getTotalAmount();
                  BigDecimal total = agingVoList.get(i).getTotalAmount();
                  if (total == null || total.compareTo(BigDecimal.ZERO) == 0) {
                     return null;
                  }
                  return part.divide(total, 4, RoundingMode.HALF_UP)
                        .multiply(new BigDecimal("100"))
                        .setScale(2, RoundingMode.HALF_UP);
               })
               .collect(Collectors.toList()));
         result.add(agingAnalysisVo);
      });
      //合计
      AgingAnalysisVo agingAnalysisVo = new AgingAnalysisVo();
      agingAnalysisVo.setCompanyName("合计");
      agingAnalysisVo.setAmount(agingVoList.stream().map(AgingVo::getTotalAmount).collect(Collectors.toList()));
      List<BigDecimal> percent = IntStream.range(0, agingAnalysisVo.getAmount().size())
            .mapToObj(i -> {
               if (agingAnalysisVo.getAmount().get(i) == null || agingAnalysisVo.getAmount().get(i).compareTo(BigDecimal.ZERO) == 0) {
                  return null;
               }else {
                  return new BigDecimal("100");
               }
            })
            .collect(Collectors.toList());
      agingAnalysisVo.setPercent(percent);
      result.add(agingAnalysisVo);
      return R.ok(result);
   }
   @Override
   public R homeZbjt() {
      List<HomeZbjtVo> homeZbjtVoList = new ArrayList<>();
      //合同签订 sgb smj jxc tfgs ymj
      HomeZbjtVo htqd = contractMapper.homeZbjt();
      homeZbjtVoList.add(htqd);
      //回款
      HomeZbjtVo hk = paymentSlipMapper.homeZbjt();
      homeZbjtVoList.add(hk);
      //出货
      HomeZbjtVo ch = contractOutBoundMapper.homeZbjt();
      homeZbjtVoList.add(ch);
      //开票
      HomeZbjtVo kp = contractInvoiceMapper.homeZbjt();
      homeZbjtVoList.add(kp);
      //赊销产生值 今天发货加今天开票额
//      if (ObjUtil.isNotNull(ch)&&ObjUtil.isNotNull(kp)){
//         HomeZbjtVo sxsy = ch.add(kp);
//         homeZbjtVoList.add(sxsy);
//      }else if (ObjUtil.isNotNull(ch)&&ObjUtil.isNull(kp)){
         homeZbjtVoList.add(ch);
//      }else if (ObjUtil.isNull(ch)&&ObjUtil.isNotNull(kp)){
//         homeZbjtVoList.add(kp);
//      }else {
//         homeZbjtVoList.add(new HomeZbjtVo());
//      }
      //赊销累计剩余值 今日发货且没开票的出货
      HomeZbjtVo sx = contractOutBoundMapper.homeZbjtSX();
      homeZbjtVoList.add(sx);
      HomeZbjtVo yq = currentOverdueMapper.homeZbjt();
      //逾期累计剩余 今日产生逾期 含历史
      HomeZbjtVo ls = historyOverdueMapper.homeZbjt();
      if (ObjUtil.isNotNull(ls)&&ObjUtil.isNotNull(yq)){
         homeZbjtVoList.add(yq.add(ls));
      }else if (ObjUtil.isNotNull(ls)&&ObjUtil.isNull(yq)){
         homeZbjtVoList.add(ls);
      }else if (ObjUtil.isNull(ls)&&ObjUtil.isNotNull(yq)){
         homeZbjtVoList.add(yq);
      }else {
         homeZbjtVoList.add(new HomeZbjtVo());
      }
      //逾期产生值 今天产生-今天已付
      homeZbjtVoList.add(yq);
      return R.ok(homeZbjtVoList);
   }
   @Override
   public R homeZgs() {
      List<HomeZgsVo> homeZbjtVoList = new ArrayList<>();
      //合同签订 华北  西北  东北  海外
      HomeZgsVo htqd = contractMapper.homeZgs(SecurityUtils.getUser().getCompId());
      homeZbjtVoList.add(htqd);
      //回款
      HomeZgsVo hk = paymentSlipMapper.homeZgs(SecurityUtils.getUser().getCompId());
      homeZbjtVoList.add(hk);
      //出货
      HomeZgsVo ch = contractOutBoundMapper.homeZgs(SecurityUtils.getUser().getCompId());
      homeZbjtVoList.add(ch);
      //开票
      HomeZgsVo kp = contractInvoiceMapper.homeZgs(SecurityUtils.getUser().getCompId());
      homeZbjtVoList.add(kp);
      //赊销产生值
//      if (ObjUtil.isNotNull(ch)&&ObjUtil.isNotNull(kp)){
//         HomeZgsVo sxsy = ch.add(kp);
//         homeZbjtVoList.add(sxsy);
//      }else if (ObjUtil.isNotNull(ch)&&ObjUtil.isNull(kp)){
         homeZbjtVoList.add(ch);
//      }else if (ObjUtil.isNull(ch)&&ObjUtil.isNotNull(kp)){
//         homeZbjtVoList.add(kp);
//      }else {
//         homeZbjtVoList.add(new HomeZgsVo());
//      }
      //赊销累计剩余值
      HomeZgsVo sx = contractOutBoundMapper.homeZgsSX(SecurityUtils.getUser().getCompId());
      homeZbjtVoList.add(sx);
      HomeZgsVo yq = currentOverdueMapper.homeZgs(SecurityUtils.getUser().getCompId());
      //逾期产生值
      HomeZgsVo ls = historyOverdueMapper.homeZgs(SecurityUtils.getUser().getCompId());
      if (ObjUtil.isNotNull(ls)&&ObjUtil.isNotNull(yq)){
         homeZbjtVoList.add(yq.add(ls));
      }else if (ObjUtil.isNotNull(ls)&&ObjUtil.isNull(yq)){
         homeZbjtVoList.add(ls);
      }else if (ObjUtil.isNull(ls)&&ObjUtil.isNotNull(yq)){
         homeZbjtVoList.add(yq);
      }else {
         homeZbjtVoList.add(new HomeZgsVo());
      }
      //逾期累计剩余
      homeZbjtVoList.add(yq);
      return R.ok(homeZbjtVoList);
   }
   @Override
   public R homeZbjtFlag() {
      Long userId = SecurityUtils.getUser().getCompId();
      List<Long> compIds = new ArrayList<>();
      compIds.add(Long.valueOf(sgb));
      compIds.add(Long.valueOf(smj));
      compIds.add(Long.valueOf(tfgs));
      compIds.add(Long.valueOf(ymj));
      compIds.add(Long.valueOf(jxc));
      if (compIds.contains(userId)){
         return R.ok(false);
      };
      return R.ok(true);
   }
   @Override
   public R homeContract(HomeQueryDTO queryDTO) {
      LocalDateTime now = LocalDateTime.now();
      LocalDate today = now.toLocalDate();
      // 开始时间:今天 00:00:00
      LocalDateTime startOfDay = today.atStartOfDay();
      // 结束时间:今天 23:59:59.999999999 (或者使用 nextDay 00:00:00 配合 lt)
      LocalDateTime endOfDay = today.atTime(LocalTime.MAX);
      // --- 场景二:查询当月数据 ---
      // 开始时间:当月1号 00:00:00
      LocalDateTime startOfMonth = today.withDayOfMonth(1).atStartOfDay();
      // 结束时间:当月最后一天 23:59:59
      LocalDateTime endOfMonth = today.withDayOfMonth(today.lengthOfMonth()).atTime(LocalTime.MAX);
      // 开始时间:当年1月1号 00:00:00
      LocalDateTime startOfYear = today.withDayOfYear(1).atStartOfDay();
      // 结束时间:当年12月31号 23:59:59
      LocalDateTime endOfYear = today.withDayOfYear(today.lengthOfYear()).atTime(LocalTime.MAX);
      MPJLambdaWrapper<Contract> wrapper = new MPJLambdaWrapper<Contract>()
      .selectAll(Contract.class)
            .leftJoin(BusinessCustomer.class,BusinessCustomer::getId,Contract::getPartyAId)
            .eq(ObjUtil.isNotNull(queryDTO.getQueryCompId()),Contract::getCompId,queryDTO.getQueryCompId())
            .ge(StrUtil.isNotEmpty(queryDTO.getQueryType())&&StrUtil.equals(queryDTO.getQueryType(),"1"),Contract::getSignDate,startOfDay)
            .le(StrUtil.isNotEmpty(queryDTO.getQueryType())&&StrUtil.equals(queryDTO.getQueryType(),"1"),Contract::getSignDate,endOfDay)
            .ge(StrUtil.isNotEmpty(queryDTO.getQueryType())&&StrUtil.equals(queryDTO.getQueryType(),"2"),Contract::getSignDate,startOfMonth)
            .le(StrUtil.isNotEmpty(queryDTO.getQueryType())&&StrUtil.equals(queryDTO.getQueryType(),"2"),Contract::getSignDate,endOfMonth)
            .ge(StrUtil.isNotEmpty(queryDTO.getQueryType())&&StrUtil.equals(queryDTO.getQueryType(),"3"),Contract::getSignDate,startOfYear)
            .le(StrUtil.isNotEmpty(queryDTO.getQueryType())&&StrUtil.equals(queryDTO.getQueryType(),"3"),Contract::getSignDate,endOfYear)
            .eq(StrUtil.isNotEmpty(queryDTO.getQueryArea()),BusinessCustomer::getAreaId,queryDTO.getQueryArea())
            .eq(StrUtil.isNotEmpty(queryDTO.getQueryServiceAttr()),BusinessCustomer::getExportServiceAttr,queryDTO.getQueryServiceAttr())
            .orderByDesc(Contract::getCreateTime)
            ;
      return R.ok(contractMapper.selectList(wrapper));
   }
   @Override
   public R homePaymentSlip(HomeQueryDTO queryDTO) {
      LocalDateTime now = LocalDateTime.now();
      LocalDate today = now.toLocalDate();
      // 开始时间:今天 00:00:00
      LocalDateTime startOfDay = today.atStartOfDay();
      // 结束时间:今天 23:59:59.999999999 (或者使用 nextDay 00:00:00 配合 lt)
      LocalDateTime endOfDay = today.atTime(LocalTime.MAX);
      // --- 场景二:查询当月数据 ---
      // 开始时间:当月1号 00:00:00
      LocalDateTime startOfMonth = today.withDayOfMonth(1).atStartOfDay();
      // 结束时间:当月最后一天 23:59:59
      LocalDateTime endOfMonth = today.withDayOfMonth(today.lengthOfMonth()).atTime(LocalTime.MAX);
      // 开始时间:当年1月1号 00:00:00
      LocalDateTime startOfYear = today.withDayOfYear(1).atStartOfDay();
      // 结束时间:当年12月31号 23:59:59
      LocalDateTime endOfYear = today.withDayOfYear(today.lengthOfYear()).atTime(LocalTime.MAX);
      MPJLambdaWrapper<PaymentSlip> wrapper = new MPJLambdaWrapper<PaymentSlip>()
            .selectAll(PaymentSlip.class)
            .leftJoin(BusinessCustomer.class,BusinessCustomer::getId,PaymentSlip::getBusGuestId)
            .eq(ObjUtil.isNotNull(queryDTO.getQueryCompId()),Contract::getCompId,queryDTO.getQueryCompId())
            .ge(StrUtil.isNotEmpty(queryDTO.getQueryType())&&StrUtil.equals(queryDTO.getQueryType(),"1"),PaymentSlip::getPaymentTime,startOfDay)
            .le(StrUtil.isNotEmpty(queryDTO.getQueryType())&&StrUtil.equals(queryDTO.getQueryType(),"1"),PaymentSlip::getPaymentTime,endOfDay)
            .ge(StrUtil.isNotEmpty(queryDTO.getQueryType())&&StrUtil.equals(queryDTO.getQueryType(),"2"),PaymentSlip::getPaymentTime,startOfMonth)
            .le(StrUtil.isNotEmpty(queryDTO.getQueryType())&&StrUtil.equals(queryDTO.getQueryType(),"2"),PaymentSlip::getPaymentTime,endOfMonth)
            .ge(StrUtil.isNotEmpty(queryDTO.getQueryType())&&StrUtil.equals(queryDTO.getQueryType(),"3"),PaymentSlip::getPaymentTime,startOfYear)
            .le(StrUtil.isNotEmpty(queryDTO.getQueryType())&&StrUtil.equals(queryDTO.getQueryType(),"3"),PaymentSlip::getPaymentTime,endOfYear)
            .eq(StrUtil.isNotEmpty(queryDTO.getQueryArea()),BusinessCustomer::getAreaId,queryDTO.getQueryArea())
            .eq(StrUtil.isNotEmpty(queryDTO.getQueryServiceAttr()),BusinessCustomer::getExportServiceAttr,queryDTO.getQueryServiceAttr())
            .orderByDesc(PaymentSlip::getCreateTime)
            ;
      return R.ok(paymentSlipMapper.selectList(wrapper));
   }
   @Override
   public R homeOutBound(HomeQueryDTO queryDTO) {
      LocalDateTime now = LocalDateTime.now();
      LocalDate today = now.toLocalDate();
      // 开始时间:今天 00:00:00
      LocalDateTime startOfDay = today.atStartOfDay();
      // 结束时间:今天 23:59:59.999999999 (或者使用 nextDay 00:00:00 配合 lt)
      LocalDateTime endOfDay = today.atTime(LocalTime.MAX);
      // --- 场景二:查询当月数据 ---
      // 开始时间:当月1号 00:00:00
      LocalDateTime startOfMonth = today.withDayOfMonth(1).atStartOfDay();
      // 结束时间:当月最后一天 23:59:59
      LocalDateTime endOfMonth = today.withDayOfMonth(today.lengthOfMonth()).atTime(LocalTime.MAX);
      // 开始时间:当年1月1号 00:00:00
      LocalDateTime startOfYear = today.withDayOfYear(1).atStartOfDay();
      // 结束时间:当年12月31号 23:59:59
      LocalDateTime endOfYear = today.withDayOfYear(today.lengthOfYear()).atTime(LocalTime.MAX);
      MPJLambdaWrapper<ContractOutBound> wrapper = new MPJLambdaWrapper<ContractOutBound>()
            .selectAll(ContractOutBound.class)
            .select(Contract::getContractNo)
            .selectAs(BusinessCustomer::getCompanyName,"busGuestName")
            .select(ContractSubjectMatter::getUnitPrice)
            .leftJoin(Contract.class,Contract::getId,ContractOutBound::getContractId)
            .leftJoin(BusinessCustomer.class,BusinessCustomer::getId,ContractOutBound::getBusGuestId)
            .leftJoin(ContractSubjectMatter.class, on->
                  on.eq(ContractSubjectMatter::getContractId,ContractOutBound::getContractId)
                        .eq(ContractSubjectMatter::getMaterialCode,ContractOutBound::getSubjectMatterCode)
            )
            .eq(ObjUtil.isNotNull(queryDTO.getQueryCompId()),Contract::getCompId,queryDTO.getQueryCompId())
            .ge(StrUtil.isNotEmpty(queryDTO.getQueryType())&&StrUtil.equals(queryDTO.getQueryType(),"1"),ContractOutBound::getOutBoundTime,startOfDay)
            .le(StrUtil.isNotEmpty(queryDTO.getQueryType())&&StrUtil.equals(queryDTO.getQueryType(),"1"),ContractOutBound::getOutBoundTime,endOfDay)
            .ge(StrUtil.isNotEmpty(queryDTO.getQueryType())&&StrUtil.equals(queryDTO.getQueryType(),"2"),ContractOutBound::getOutBoundTime,startOfMonth)
            .le(StrUtil.isNotEmpty(queryDTO.getQueryType())&&StrUtil.equals(queryDTO.getQueryType(),"2"),ContractOutBound::getOutBoundTime,endOfMonth)
            .ge(StrUtil.isNotEmpty(queryDTO.getQueryType())&&StrUtil.equals(queryDTO.getQueryType(),"3"),ContractOutBound::getOutBoundTime,startOfYear)
            .le(StrUtil.isNotEmpty(queryDTO.getQueryType())&&StrUtil.equals(queryDTO.getQueryType(),"3"),ContractOutBound::getOutBoundTime,endOfYear)
            .eq(StrUtil.isNotEmpty(queryDTO.getQueryArea()),BusinessCustomer::getAreaId,queryDTO.getQueryArea())
            .eq(StrUtil.isNotEmpty(queryDTO.getQueryServiceAttr()),BusinessCustomer::getExportServiceAttr,queryDTO.getQueryServiceAttr())
            .orderByDesc(ContractOutBound::getCreateTime)
            ;
      return R.ok(contractOutBoundMapper.selectJoinList(HomeOutBoundVo.class,wrapper));
   }
   @Override
   public R homeInvoice(HomeQueryDTO queryDTO) {
      LocalDateTime now = LocalDateTime.now();
      LocalDate today = now.toLocalDate();
      // 开始时间:今天 00:00:00
      LocalDateTime startOfDay = today.atStartOfDay();
      // 结束时间:今天 23:59:59.999999999 (或者使用 nextDay 00:00:00 配合 lt)
      LocalDateTime endOfDay = today.atTime(LocalTime.MAX);
      // --- 场景二:查询当月数据 ---
      // 开始时间:当月1号 00:00:00
      LocalDateTime startOfMonth = today.withDayOfMonth(1).atStartOfDay();
      // 结束时间:当月最后一天 23:59:59
      LocalDateTime endOfMonth = today.withDayOfMonth(today.lengthOfMonth()).atTime(LocalTime.MAX);
      // 开始时间:当年1月1号 00:00:00
      LocalDateTime startOfYear = today.withDayOfYear(1).atStartOfDay();
      // 结束时间:当年12月31号 23:59:59
      LocalDateTime endOfYear = today.withDayOfYear(today.lengthOfYear()).atTime(LocalTime.MAX);
      MPJLambdaWrapper<ContractInvoice> wrapper = new MPJLambdaWrapper<ContractInvoice>()
            .selectAll(ContractInvoice.class)
            .select(Contract::getContractNo)
            .selectAs(BusinessCustomer::getCompanyName,"busGuestName")
            .leftJoin(Contract.class,Contract::getId,ContractInvoice::getContractId)
            .leftJoin(BusinessCustomer.class,BusinessCustomer::getId,Contract::getPartyAId)
            .eq(ObjUtil.isNotNull(queryDTO.getQueryCompId()),Contract::getCompId,queryDTO.getQueryCompId())
            .ge(StrUtil.isNotEmpty(queryDTO.getQueryType())&&StrUtil.equals(queryDTO.getQueryType(),"1"),ContractInvoice::getInvoiceTime,startOfDay)
            .le(StrUtil.isNotEmpty(queryDTO.getQueryType())&&StrUtil.equals(queryDTO.getQueryType(),"1"),ContractInvoice::getInvoiceTime,endOfDay)
            .ge(StrUtil.isNotEmpty(queryDTO.getQueryType())&&StrUtil.equals(queryDTO.getQueryType(),"2"),ContractInvoice::getInvoiceTime,startOfMonth)
            .le(StrUtil.isNotEmpty(queryDTO.getQueryType())&&StrUtil.equals(queryDTO.getQueryType(),"2"),ContractInvoice::getInvoiceTime,endOfMonth)
            .ge(StrUtil.isNotEmpty(queryDTO.getQueryType())&&StrUtil.equals(queryDTO.getQueryType(),"3"),ContractInvoice::getInvoiceTime,startOfYear)
            .le(StrUtil.isNotEmpty(queryDTO.getQueryType())&&StrUtil.equals(queryDTO.getQueryType(),"3"),ContractInvoice::getInvoiceTime,endOfYear)
            .eq(StrUtil.isNotEmpty(queryDTO.getQueryArea()),BusinessCustomer::getAreaId,queryDTO.getQueryArea())
            .eq(StrUtil.isNotEmpty(queryDTO.getQueryServiceAttr()),BusinessCustomer::getExportServiceAttr,queryDTO.getQueryServiceAttr())
            .orderByDesc(ContractInvoice::getCreateTime)
            ;
      return R.ok(contractInvoiceMapper.selectJoinList(HomeInvoiceVo.class,wrapper));
   }
   @Override
   public R homeCreditSale(HomeQueryDTO queryDTO) {
      LocalDateTime now = LocalDateTime.now();
      LocalDate today = now.toLocalDate();
      // 开始时间:今天 00:00:00
      LocalDateTime startOfDay = today.atStartOfDay();
      // 结束时间:今天 23:59:59.999999999 (或者使用 nextDay 00:00:00 配合 lt)
      LocalDateTime endOfDay = today.atTime(LocalTime.MAX);
      // --- 场景二:查询当月数据 ---
      // 开始时间:当月1号 00:00:00
      LocalDateTime startOfMonth = today.withDayOfMonth(1).atStartOfDay();
      // 结束时间:当月最后一天 23:59:59
      LocalDateTime endOfMonth = today.withDayOfMonth(today.lengthOfMonth()).atTime(LocalTime.MAX);
      // 开始时间:当年1月1号 00:00:00
      LocalDateTime startOfYear = today.withDayOfYear(1).atStartOfDay();
      // 结束时间:当年12月31号 23:59:59
      LocalDateTime endOfYear = today.withDayOfYear(today.lengthOfYear()).atTime(LocalTime.MAX);
      MPJLambdaWrapper<ContractOutBound> wrapper = new MPJLambdaWrapper<ContractOutBound>()
            .selectAll(ContractOutBound.class)
            .select(Contract::getContractNo)
            .selectAs(BusinessCustomer::getCompanyName,"busGuestName")
            .select(ContractSubjectMatter::getUnitPrice)
            .leftJoin(Contract.class,Contract::getId,ContractOutBound::getContractId)
            .leftJoin(BusinessCustomer.class,BusinessCustomer::getId,Contract::getPartyAId)
            .leftJoin(ContractSubjectMatter.class, on->
                  on.eq(ContractSubjectMatter::getContractId,ContractOutBound::getContractId)
                  .eq(ContractSubjectMatter::getMaterialCode,ContractOutBound::getSubjectMatterCode)
            )
            .eq(ObjUtil.isNotNull(queryDTO.getQueryCompId()),Contract::getCompId,queryDTO.getQueryCompId())
            .ge(StrUtil.isNotEmpty(queryDTO.getQueryType())&&StrUtil.equals(queryDTO.getQueryType(),"1"),ContractOutBound::getOutBoundTime,startOfDay)
            .le(StrUtil.isNotEmpty(queryDTO.getQueryType())&&StrUtil.equals(queryDTO.getQueryType(),"1"),ContractOutBound::getOutBoundTime,endOfDay)
            .ge(StrUtil.isNotEmpty(queryDTO.getQueryType())&&StrUtil.equals(queryDTO.getQueryType(),"2"),ContractOutBound::getOutBoundTime,startOfMonth)
            .le(StrUtil.isNotEmpty(queryDTO.getQueryType())&&StrUtil.equals(queryDTO.getQueryType(),"2"),ContractOutBound::getOutBoundTime,endOfMonth)
            .ge(StrUtil.isNotEmpty(queryDTO.getQueryType())&&StrUtil.equals(queryDTO.getQueryType(),"3"),ContractOutBound::getOutBoundTime,startOfYear)
            .le(StrUtil.isNotEmpty(queryDTO.getQueryType())&&StrUtil.equals(queryDTO.getQueryType(),"3"),ContractOutBound::getOutBoundTime,endOfYear)
            .eq(StrUtil.isNotEmpty(queryDTO.getQueryArea()),BusinessCustomer::getAreaId,queryDTO.getQueryArea())
            .eq(StrUtil.isNotEmpty(queryDTO.getQueryServiceAttr()),BusinessCustomer::getExportServiceAttr,queryDTO.getQueryServiceAttr())
            .orderByDesc(ContractOutBound::getCreateTime)
            ;
      return R.ok(contractOutBoundMapper.selectJoinList(HomeCreditSaleVo.class,wrapper));
   }
   @Override
   public R homeOverdue(HomeQueryDTO queryDTO) {
      LocalDateTime now = LocalDateTime.now();
      LocalDate today = now.toLocalDate();
      // 开始时间:今天 00:00:00
      LocalDateTime startOfDay = today.atStartOfDay();
      // 结束时间:今天 23:59:59.999999999 (或者使用 nextDay 00:00:00 配合 lt)
      LocalDateTime endOfDay = today.atTime(LocalTime.MAX);
      // --- 场景二:查询当月数据 ---
      // 开始时间:当月1号 00:00:00
      LocalDateTime startOfMonth = today.withDayOfMonth(1).atStartOfDay();
      // 结束时间:当月最后一天 23:59:59
      LocalDateTime endOfMonth = today.withDayOfMonth(today.lengthOfMonth()).atTime(LocalTime.MAX);
      // 开始时间:当年1月1号 00:00:00
      LocalDateTime startOfYear = today.withDayOfYear(1).atStartOfDay();
      // 结束时间:当年12月31号 23:59:59
      LocalDateTime endOfYear = today.withDayOfYear(today.lengthOfYear()).atTime(LocalTime.MAX);
      MPJLambdaWrapper<CurrentOverdue> wrapper = new MPJLambdaWrapper<CurrentOverdue>()
            .selectAll(CurrentOverdue.class)
            .select(Contract::getContractNo)
            .selectAs(BusinessCustomer::getCompanyName,"busGuestName")
            .leftJoin(BusinessCustomer.class,BusinessCustomer::getId,CurrentOverdue::getBusGuestId)
            .leftJoin(Contract.class,Contract::getId,CurrentOverdue::getContractId)
            .eq(ObjUtil.isNotNull(queryDTO.getQueryCompId()),Contract::getCompId,queryDTO.getQueryCompId())
            .ge(StrUtil.isNotEmpty(queryDTO.getQueryType())&&StrUtil.equals(queryDTO.getQueryType(),"1"),CurrentOverdue::getContractExpirTime,startOfDay)
            .le(StrUtil.isNotEmpty(queryDTO.getQueryType())&&StrUtil.equals(queryDTO.getQueryType(),"1"),CurrentOverdue::getContractExpirTime,endOfDay)
            .ge(StrUtil.isNotEmpty(queryDTO.getQueryType())&&StrUtil.equals(queryDTO.getQueryType(),"2"),CurrentOverdue::getContractExpirTime,startOfMonth)
            .le(StrUtil.isNotEmpty(queryDTO.getQueryType())&&StrUtil.equals(queryDTO.getQueryType(),"2"),CurrentOverdue::getContractExpirTime,endOfMonth)
            .ge(StrUtil.isNotEmpty(queryDTO.getQueryType())&&StrUtil.equals(queryDTO.getQueryType(),"3"),CurrentOverdue::getContractExpirTime,startOfYear)
            .le(StrUtil.isNotEmpty(queryDTO.getQueryType())&&StrUtil.equals(queryDTO.getQueryType(),"3"),CurrentOverdue::getContractExpirTime,endOfYear)
            .eq(StrUtil.isNotEmpty(queryDTO.getQueryArea()),BusinessCustomer::getAreaId,queryDTO.getQueryArea())
            .eq(StrUtil.isNotEmpty(queryDTO.getQueryServiceAttr()),BusinessCustomer::getExportServiceAttr,queryDTO.getQueryServiceAttr())
            .orderByDesc(CurrentOverdue::getCreateTime)
            ;
      return R.ok(currentOverdueMapper.selectJoinList(HomeOverdueVo.class,wrapper));
   }
   @Override
   public R homeOverdueHis(HomeQueryDTO queryDTO) {
      List<HomeOverdueStaVo> homeOverdueVos = new ArrayList<>();
      HomeOverdueStaVo current = currentOverdueMapper.selectCurrentOverdue(queryDTO);
      if (ObjUtil.isNotNull(current)){
         current.setOverdueType("当前");
         homeOverdueVos.add(current);
      }
      HomeOverdueStaVo history = historyOverdueMapper.selectHistoryOverdue(queryDTO);
      if (ObjUtil.isNotNull(history)){
         history.setOverdueType("历史");
         homeOverdueVos.add(history);
      }
      return R.ok(homeOverdueVos);
   }
}