无关风月
2025-02-14 84edf481b03102263f6a38fbe6568b45265d3224
小程序登录
2个文件已修改
961 ■■■■■ 已修改文件
ruoyi-admin/src/main/java/com/ruoyi/web/controller/task/TaskUtil.java 521 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TContractServiceImpl.java 440 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/java/com/ruoyi/web/controller/task/TaskUtil.java
@@ -68,535 +68,24 @@
    }
    // 每天凌晨00点执行的定时任务 用于合同生成第一笔账单
    @Scheduled(cron = "0 0 0 * * ?")
    public void dayOfFirstBill() {
        try {
            // 查询所有已签订的合同并且未生成第一笔账单的
            List<TContract> list = contractService.lambdaQuery().eq(TContract::getStatus, 4)
                    .isNull(TContract::getFirstPayTime).list();
            List<TBill> bills = new ArrayList<>();
            List<TContractRentType> contractRentTypes = contractRentTypeService.list();
            for (TContract contract : list) {
                contract.setFirstPayTime(contract.getStartTime().plusDays(10));
                // 第一次应缴费日期
                LocalDateTime firstPayTime = contract.getStartTime().plusDays(10).withHour(0).withMinute(0).withSecond(0);
                LocalDate localDate = contract.getStartTime().plusDays(10).toLocalDate();
                LocalDate now = LocalDate.now();
                // 如果应缴费日期和当前时间不相同 跳过
                if (!localDate.equals(now)) {
                    continue;
                }
                TBill rentBill = new TBill();
                rentBill.setContractId(contract.getId());
                rentBill.setContractNumber(contract.getContractNumber());
                LocalDateTime startPayTime = contract.getStartPayTime();
                LocalDateTime endTime1 = contract.getEndTime();
//                // 计算两个时间相差多少天
//                // 如果时间小于30天 需要计算每日租金
//                if (days<30){
//                    rentBill.setPayableFeesMoney(contract.getMonthRent().divide(new BigDecimal("30"),2,BigDecimal.ROUND_DOWN).multiply(new BigDecimal(days)));
//                }else{
//                    rentBill.setPayableFeesMoney(contract.getPayType().equals("1")?contract.getMonthRent():
//                            contract.getPayType().equals("2")?contract.getMonthRent().multiply(new BigDecimal("3")):contract.getMonthRent().multiply(new BigDecimal("12")).setScale(2,BigDecimal.ROUND_DOWN));
//                }
                rentBill.setPayableFeesTime(firstPayTime);
                rentBill.setPayFeesStatus("1");
                rentBill.setBillType("1");
                rentBill.setStartTime(contract.getStartPayTime());
                TContractRentType tContractRentType = contractRentTypes.stream().filter(e -> e.getContractId().equals(contract.getId())).findFirst().orElse(null);
                if (tContractRentType!=null && contract.getStartPayTime().plusMonths(contract.getPayType().equals("1")? 1:contract.getPayType().equals("2")? 3:12).isAfter(tContractRentType.getChangeTime())){
                    // 计算租金变动的天数
                    long moneyDays = ChronoUnit.DAYS.between(tContractRentType.getChangeTime(), contract.getStartPayTime().plusMonths(contract.getPayType().equals("1")? 1:contract.getPayType().equals("2")? 3:12))+1L;
                    contract.setChangeTime(LocalDateTime.now());
                    // 递增递减的租金
                    BigDecimal contractRentTypeMoney = new BigDecimal("0");
                    // 不递增递减的租金
                    BigDecimal originalMoney = new BigDecimal("0");
                    // 原租金
                    switch (tContractRentType.getIncreasingDecreasingType()){
                        case 1:
                            switch (tContractRentType.getIncreasingDecreasing()){
                                case 1:
                                    contractRentTypeMoney =contractRentTypeMoney.add(contract.getChangeRent().multiply(new BigDecimal(100).add(tContractRentType.getNumericalValue())).divide(new BigDecimal(100),2,BigDecimal.ROUND_DOWN).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays)));
                                    contract.setChangeRent(contractRentTypeMoney);
                                    break;
                                case 2:
                                    contractRentTypeMoney = contractRentTypeMoney.add(contract.getChangeRent().multiply((new BigDecimal(100).subtract(tContractRentType.getNumericalValue()))).divide(new BigDecimal(100),2,BigDecimal.ROUND_DOWN).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays)).divide(new BigDecimal(contract.getPayType().equals("1")? 1:contract.getPayType().equals("2")? 3:12),2,BigDecimal.ROUND_DOWN));
                                    contract.setChangeRent(contractRentTypeMoney);
                                    break;
                            }
                            break;
                        case 2:
                            switch (tContractRentType.getIncreasingDecreasing()){
                                case 1:
                                    contractRentTypeMoney =contractRentTypeMoney.add(contract.getChangeRent().add(tContractRentType.getNumericalValue())).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays));
                                    contract.setChangeRent(contractRentTypeMoney);
                                    break;
                                case 2:
                                    contractRentTypeMoney = contractRentTypeMoney.add(contract.getChangeRent().subtract(tContractRentType.getNumericalValue())).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays));
                                    contract.setChangeRent(contractRentTypeMoney);
                                    break;
                            }
                            break;
                    }
                    // 不需要涨租金的时间段
                    if (contract.getFirstPayTime().isBefore(tContractRentType.getChangeTime())){
                        long originalDays = ChronoUnit.DAYS.between(contract.getFirstPayTime(), tContractRentType.getChangeTime());
                        originalMoney=originalMoney.add(contract.getMonthRent().divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN))
                                .multiply(new BigDecimal(originalDays));
                        rentBill.setPayableFeesMoney(contractRentTypeMoney.add(originalMoney));
                        rentBill.setOutstandingMoney(rentBill.getPayableFeesMoney());
                    }else{
                        rentBill.setPayableFeesMoney(contractRentTypeMoney);
                        rentBill.setOutstandingMoney(rentBill.getPayableFeesMoney());
                    }
                    if (contract.getFirstPayTime().plusMonths(contract.getPayType().equals("1")? 1:contract.getPayType().equals("2")? 3:12).isAfter(contract.getEndTime())){
                        rentBill.setEndTime(contract.getFirstPayTime().plusMonths(contract.getPayType().equals("1")? 1:contract.getPayType().equals("2")? 3:12));
                    }else{
                        rentBill.setEndTime(contract.getEndTime());
                    }
                }else{
                    if (contract.getFirstPayTime().plusMonths(contract.getPayType().equals("1")? 1:contract.getPayType().equals("2")? 3:12).isAfter(contract.getEndTime())){
                        rentBill.setEndTime(contract.getFirstPayTime().plusMonths(contract.getPayType().equals("1")? 1:contract.getPayType().equals("2")? 3:12));
                    }else{
                        rentBill.setEndTime(contract.getEndTime());
                    }
                    // 不走递增递减
                    long allDays = ChronoUnit.DAYS.between(contract.getFirstPayTime(), rentBill.getEndTime());
                    rentBill.setPayableFeesMoney(contract.getMonthRent().divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(allDays)));
                    rentBill.setOutstandingMoney(rentBill.getPayableFeesMoney());
                }
                // 租金账单
                bills.add(rentBill);
                // 押金账单
                TBill depositBill = new TBill();
                depositBill.setContractId(contract.getId());
                depositBill.setContractNumber(contract.getContractNumber());
                depositBill.setPayableFeesMoney(contract.getDeposit());
                depositBill.setOutstandingMoney(depositBill.getPayableFeesMoney());
                depositBill.setPayableFeesTime(firstPayTime);
                depositBill.setPayFeesStatus("1");
                depositBill.setBillType("2");
                bills.add(depositBill);
            }
            contractService.updateBatchById(list);
            billService.saveBatch(bills);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    // 每天凌晨00点执行的定时任务 用于生成合同期最后一笔账单
    // 每天凌晨00点执行的定时任务 根据应缴费日期修改账单状态
    @Scheduled(cron = "0 0 0 * * ?")
    public void dayOfEndBill() {
        try {
            // 查询所有已签订的合同并且已经生成第一笔账单的
            List<TContract> list = contractService.lambdaQuery().eq(TContract::getStatus, 4)
                    .ge(TContract::getEndTime,LocalDateTime.now())
                    .isNotNull(TContract::getFirstPayTime).list();
            List<TContractRentType> contractRentTypes = contractRentTypeService.list();
            List<TBill> bills = new ArrayList<>();
            for (TContract contract : list) {
                TBill beforeBill = billService.lambdaQuery().eq(TBill::getContractId, contract.getId()).eq(TBill::getBillType, 1).orderByDesc(TBill::getCreateTime)
                        .last("limit 1").one();
                if (!(beforeBill.getEndTime().toLocalDate().equals(contract.getEndTime().toLocalDate()))
                    &&
                        (contract.getPayType().equals("1")?
                        beforeBill.getEndTime().plusMonths(1):contract.getPayType().equals("2")?
                        beforeBill.getEndTime().plusMonths(3):beforeBill.getEndTime().plusMonths(12))
                        .with(TemporalAdjusters.lastDayOfMonth()).isAfter(contract.getEndTime())
                && beforeBill.getEndTime().isBefore(contract.getEndTime())
                ){
                    TBill tBill = new TBill();
                    tBill.setContractId(contract.getId());
                    long days = ChronoUnit.DAYS.between((contract.getPayType().equals("1")?
                            beforeBill.getEndTime().plusMonths(1):contract.getPayType().equals("2")?
                            beforeBill.getEndTime().plusMonths(3):beforeBill.getEndTime().plusMonths(12)).with(TemporalAdjusters.firstDayOfMonth()), contract.getEndTime())+1L;
                    if (contract.getIsIncreasing()){
                        TContractRentType tContractRentType = contractRentTypes.stream().filter(e -> e.getContractId().equals(contract.getId())).findFirst().orElse(null);
                        if (tContractRentType!=null
                                && beforeBill.getEndTime().isBefore(tContractRentType.getChangeTime())
                                && beforeBill.getEndTime().plusMonths(contract.getPayType().equals("1")? 1:contract.getPayType().equals("2")? 3:12).with(TemporalAdjusters.lastDayOfMonth()).isAfter(tContractRentType.getChangeTime())){
                            // 如果没变过
                            if (contract.getChangeTime()==null){
                                contract.setChangeTime(LocalDateTime.now());
                                // 租金递增递减的时长 天
                                long moneyDays = ChronoUnit.DAYS.between(tContractRentType.getChangeTime(), contract.getEndTime());
                                // 递增递减的租金
                                BigDecimal contractRentTypeMoney = new BigDecimal("0");
                                // 不递增递减的租金
                                BigDecimal originalMoney = new BigDecimal("0");
                                // 原租金
                                switch (tContractRentType.getIncreasingDecreasingType()){
                                    case 1:
                                        switch (tContractRentType.getIncreasingDecreasing()){
                                            case 1:
                                                contractRentTypeMoney =contractRentTypeMoney.add(contract.getChangeRent().multiply(new BigDecimal(100).add(tContractRentType.getNumericalValue())).divide(new BigDecimal(100),2,BigDecimal.ROUND_DOWN).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays)));
                                                contract.setChangeRent(contractRentTypeMoney);
                                                break;
                                            case 2:
                                                contractRentTypeMoney = contractRentTypeMoney.add(contract.getChangeRent().multiply((new BigDecimal(100).subtract(tContractRentType.getNumericalValue()))).divide(new BigDecimal(100),2,BigDecimal.ROUND_DOWN).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays)).divide(new BigDecimal(contract.getPayType().equals("1")? 1:contract.getPayType().equals("2")? 3:12),2,BigDecimal.ROUND_DOWN));
                                                contract.setChangeRent(contractRentTypeMoney);
                                                break;
                                        }
                                        break;
                                    case 2:
                                        switch (tContractRentType.getIncreasingDecreasing()){
                                            case 1:
                                                contractRentTypeMoney =contractRentTypeMoney.add(contract.getChangeRent().add(tContractRentType.getNumericalValue())).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays));
                                                contract.setChangeRent(contractRentTypeMoney);
                                                break;
                                            case 2:
                                                contractRentTypeMoney = contractRentTypeMoney.add(contract.getChangeRent().subtract(tContractRentType.getNumericalValue())).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays));
                                                contract.setChangeRent(contractRentTypeMoney);
                                                break;
                                        }
                                        break;
                                }
                                // 不需要涨租金的时间段
                                long originalDays = ChronoUnit.DAYS.between(beforeBill.getEndTime(), tContractRentType.getChangeTime());
                                // 不需要涨租金的时间段
                                if (contract.getFirstPayTime().isBefore(tContractRentType.getChangeTime())){
                                    originalMoney=originalMoney.add(contract.getMonthRent().divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN))
                                            .multiply(new BigDecimal(originalDays));
                                    tBill.setPayableFeesMoney(contractRentTypeMoney.add(originalMoney));
                                    tBill.setOutstandingMoney(tBill.getPayableFeesMoney());
                                }else{
                                    tBill.setPayableFeesMoney(contractRentTypeMoney);
                                    tBill.setOutstandingMoney(tBill.getPayableFeesMoney());
                                }
                            }else{
                                // 之前已经涨、跌过租金了 需要判断周期是否还需要再涨、跌
                                if ((LocalDateTime.now().getYear() - contract.getChangeTime().getYear())%tContractRentType.getCycleTime()==0){
                                    contract.setChangeTime(LocalDateTime.now());
                                    // 租金递增递减的时长 天
                                    long moneyDays = ChronoUnit.DAYS.between(tContractRentType.getChangeTime(), contract.getEndTime());
                                    // 递增递减的租金
                                    BigDecimal contractRentTypeMoney = new BigDecimal("0");
                                    // 不递增递减的租金
                                    BigDecimal originalMoney = new BigDecimal("0");
                                    // 原租金
                                    switch (tContractRentType.getIncreasingDecreasingType()){
                                        case 1:
                                            switch (tContractRentType.getIncreasingDecreasing()){
                                                case 1:
                                                    contractRentTypeMoney =contractRentTypeMoney.add(contract.getChangeRent().multiply(new BigDecimal(100).add(tContractRentType.getNumericalValue())).divide(new BigDecimal(100),2,BigDecimal.ROUND_DOWN).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays)));
                                                    contract.setChangeRent(contractRentTypeMoney);
                                                    break;
                                                case 2:
                                                    contractRentTypeMoney = contractRentTypeMoney.add(contract.getChangeRent().multiply((new BigDecimal(100).subtract(tContractRentType.getNumericalValue()))).divide(new BigDecimal(100),2,BigDecimal.ROUND_DOWN).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays)).divide(new BigDecimal(contract.getPayType().equals("1")? 1:contract.getPayType().equals("2")? 3:12),2,BigDecimal.ROUND_DOWN));
                                                    contract.setChangeRent(contractRentTypeMoney);
                                                    break;
                                            }
                                            break;
                                        case 2:
                                            switch (tContractRentType.getIncreasingDecreasing()){
                                                case 1:
                                                    contractRentTypeMoney =contractRentTypeMoney.add(contract.getChangeRent().add(tContractRentType.getNumericalValue())).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays));
                                                    contract.setChangeRent(contractRentTypeMoney);
                                                    break;
                                                case 2:
                                                    contractRentTypeMoney = contractRentTypeMoney.add(contract.getChangeRent().subtract(tContractRentType.getNumericalValue())).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays));
                                                    contract.setChangeRent(contractRentTypeMoney);
                                                    break;
                                            }
                                            break;
                                    }
                                    // 不需要涨租金的时间段
                                    long originalDays = ChronoUnit.DAYS.between(beforeBill.getEndTime(), tContractRentType.getChangeTime());
                                    originalMoney=originalMoney.add(contract.getMonthRent().divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN))
                                            .multiply(new BigDecimal(originalDays));
                                    tBill.setPayableFeesMoney(contractRentTypeMoney.add(originalMoney));
                                    tBill.setOutstandingMoney(tBill.getPayableFeesMoney());
                                }else{
                                    // 不涨租金 用上次的
                                    // 租金递增递减的时长 天
                                    long moneyDays = ChronoUnit.DAYS.between(tContractRentType.getChangeTime(), contract.getEndTime());
                                    // 递增递减的租金
                                    BigDecimal contractRentTypeMoney = new BigDecimal("0");
                                    // 不递增递减的租金
                                    BigDecimal originalMoney = new BigDecimal("0");
                                    // 原租金
                                    switch (tContractRentType.getIncreasingDecreasingType()){
                                        case 1:
                                            switch (tContractRentType.getIncreasingDecreasing()){
                                                case 1:
                                                    contractRentTypeMoney =contractRentTypeMoney.add(contract.getChangeRent().multiply(new BigDecimal(100).add(tContractRentType.getNumericalValue())).divide(new BigDecimal(100),2,BigDecimal.ROUND_DOWN).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays)));
                                                    contract.setChangeRent(contractRentTypeMoney);
                                                    break;
                                                case 2:
                                                    contractRentTypeMoney = contractRentTypeMoney.add(contract.getChangeRent().multiply((new BigDecimal(100).subtract(tContractRentType.getNumericalValue()))).divide(new BigDecimal(100),2,BigDecimal.ROUND_DOWN).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays)).divide(new BigDecimal(contract.getPayType().equals("1")? 1:contract.getPayType().equals("2")? 3:12),2,BigDecimal.ROUND_DOWN));
                                                    contract.setChangeRent(contractRentTypeMoney);
                                                    break;
                                            }
                                            break;
                                        case 2:
                                            switch (tContractRentType.getIncreasingDecreasing()){
                                                case 1:
                                                    contractRentTypeMoney =contractRentTypeMoney.add(contract.getChangeRent().add(tContractRentType.getNumericalValue())).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays));
                                                    contract.setChangeRent(contractRentTypeMoney);
                                                    break;
                                                case 2:
                                                    contractRentTypeMoney = contractRentTypeMoney.add(contract.getChangeRent().subtract(tContractRentType.getNumericalValue())).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays));
                                                    contract.setChangeRent(contractRentTypeMoney);
                                                    break;
                                            }
                                            break;
                                    }
                                    // 不需要涨租金的时间段
                                    long originalDays = ChronoUnit.DAYS.between(beforeBill.getEndTime(), tContractRentType.getChangeTime());
                                    originalMoney=originalMoney.add(contract.getMonthRent().divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN))
                                            .multiply(new BigDecimal(originalDays));
                                    tBill.setPayableFeesMoney(contractRentTypeMoney.add(originalMoney));
                                    tBill.setOutstandingMoney(tBill.getPayableFeesMoney());
                                }
                            }
                        }
                    }else{
                        long allDays = ChronoUnit.DAYS.between(beforeBill.getEndTime(), contract.getEndTime());
                        tBill.setPayableFeesMoney(contract.getMonthRent().divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(allDays)));
                        tBill.setOutstandingMoney(tBill.getPayableFeesMoney());
                    }
                    tBill.setContractNumber(contract.getContractNumber());
                    if (beforeBill.getEndTime().plusMonths(contract.getPayType().equals("1")? 1:contract.getPayType().equals("2")? 3:12).getDayOfMonth()<=15){
                        tBill.setPayableFeesTime(contract.getEndTime().withHour(0).withMinute(0).withSecond(0));
                    }else{
                        tBill.setPayableFeesTime((contract.getPayType().equals("1")?
                                beforeBill.getEndTime().plusMonths(1).withDayOfMonth(15):contract.getPayType().equals("2")?
                                beforeBill.getEndTime().plusMonths(3).withDayOfMonth(15):beforeBill.getEndTime().withDayOfMonth(15).plusMonths(12).withHour(0).withMinute(0).withSecond(0)));
                    }
            List<TBill> list = billService.lambdaQuery().eq(TBill::getPayFeesStatus, "2").list();
            for (TBill tBill : list) {
                if (tBill.getPayableFeesTime().toLocalDate().equals(LocalDate.now())){
                    tBill.setPayFeesStatus("1");
                    tBill.setBillType("1");
                    tBill.setStartTime(beforeBill.getEndTime().plusDays(1));
                    tBill.setEndTime(beforeBill.getEndTime().plusMonths(contract.getPayType().equals("1")? 1:contract.getPayType().equals("2")? 3:12));
                    bills.add(tBill);
                }
            }
            billService.saveBatch(bills);
            billService.updateBatchById(list);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    // 每月15号凌晨执行的定时任务 用于生成租金账单
    @Scheduled(cron = "0 0 0 15 * ?")
    public void monthOfBill() {
        try {
            // 查询所有已签订的合同
            List<TContract> list = contractService.lambdaQuery().eq(TContract::getStatus, 4)
                    .isNotNull(TContract::getFirstPayTime)
                    .ge(TContract::getEndTime, LocalDateTime.now())
                    .list();
            List<TContractRentType> contractRentTypes = contractRentTypeService.list();
            List<TBill> bills = new ArrayList<>();
            for (TContract contract : list) {
                TBill beforeBill = billService.lambdaQuery().eq(TBill::getContractId, contract.getId()).eq(TBill::getBillType, 1).orderByDesc(TBill::getCreateTime)
                        .last("limit 1").one();
                if (beforeBill.getEndTime().toLocalDate().equals(contract.getEndTime().toLocalDate()))continue;
                if (beforeBill.getEndTime().plusMonths(contract.getPayType().equals("1")? 1:contract.getPayType().equals("2")? 3:12).with(TemporalAdjusters.lastDayOfMonth()).isBefore(contract.getEndTime())){
                    TBill tBill = new TBill();
                    tBill.setContractId(contract.getId());
                    tBill.setContractNumber(contract.getContractNumber());
                    // 根据支付方式判断需不需要生成订单
                    if (!(beforeBill.getEndTime().toLocalDate().equals(contract.getEndTime().toLocalDate()))
                            &&
                            (contract.getPayType().equals("1")?
                                    beforeBill.getEndTime().plusMonths(1):contract.getPayType().equals("2")?
                                    beforeBill.getEndTime().plusMonths(3):beforeBill.getEndTime().plusMonths(12))
                                    .with(TemporalAdjusters.lastDayOfMonth()).isBefore(contract.getEndTime())
                            && beforeBill.getEndTime().isBefore(contract.getEndTime())
                    ){
                        tBill.setContractId(contract.getId());
                        long days = ChronoUnit.DAYS.between(beforeBill.getEndTime(), (contract.getPayType().equals("1")?
                                beforeBill.getEndTime().plusMonths(1):contract.getPayType().equals("2")?
                                beforeBill.getEndTime().plusMonths(3):beforeBill.getEndTime().plusMonths(12)).with(TemporalAdjusters.lastDayOfMonth()))+1L;
                        if (contract.getIsIncreasing()){
                            TContractRentType tContractRentType = contractRentTypes.stream().filter(e -> e.getContractId().equals(contract.getId())).findFirst().orElse(null);
                            if (tContractRentType!=null
                                    && beforeBill.getEndTime().isBefore(tContractRentType.getChangeTime())
                                    && beforeBill.getEndTime().plusMonths(contract.getPayType().equals("1")? 1:contract.getPayType().equals("2")? 3:12).with(TemporalAdjusters.lastDayOfMonth()).isAfter(tContractRentType.getChangeTime())){
                                // 如果没变过
                                if (contract.getChangeTime()==null){
                                    contract.setChangeTime(LocalDateTime.now());
                                    // 租金递增递减的时长 天
                                    long moneyDays = ChronoUnit.DAYS.between(tContractRentType.getChangeTime(), contract.getEndTime());
                                    // 递增递减的租金
                                    BigDecimal contractRentTypeMoney = new BigDecimal("0");
                                    // 不递增递减的租金
                                    BigDecimal originalMoney = new BigDecimal("0");
                                    // 原租金
                                    switch (tContractRentType.getIncreasingDecreasingType()){
                                        case 1:
                                            switch (tContractRentType.getIncreasingDecreasing()){
                                                case 1:
                                                    contractRentTypeMoney =contractRentTypeMoney.add(contract.getChangeRent().multiply(new BigDecimal(100).add(tContractRentType.getNumericalValue())).divide(new BigDecimal(100),2,BigDecimal.ROUND_DOWN).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays)));
                                                    contract.setChangeRent(contractRentTypeMoney);
                                                    break;
                                                case 2:
                                                    contractRentTypeMoney = contractRentTypeMoney.add(contract.getChangeRent().multiply((new BigDecimal(100).subtract(tContractRentType.getNumericalValue()))).divide(new BigDecimal(100),2,BigDecimal.ROUND_DOWN).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays)).divide(new BigDecimal(contract.getPayType().equals("1")? 1:contract.getPayType().equals("2")? 3:12),2,BigDecimal.ROUND_DOWN));
                                                    contract.setChangeRent(contractRentTypeMoney);
                                                    break;
                                            }
                                            break;
                                        case 2:
                                            switch (tContractRentType.getIncreasingDecreasing()){
                                                case 1:
                                                    contractRentTypeMoney =contractRentTypeMoney.add(contract.getChangeRent().add(tContractRentType.getNumericalValue())).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays));
                                                    contract.setChangeRent(contractRentTypeMoney);
                                                    break;
                                                case 2:
                                                    contractRentTypeMoney = contractRentTypeMoney.add(contract.getChangeRent().subtract(tContractRentType.getNumericalValue())).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays));
                                                    contract.setChangeRent(contractRentTypeMoney);
                                                    break;
                                            }
                                            break;
                                    }
                                    // 不需要涨租金的时间段
                                    long originalDays = ChronoUnit.DAYS.between(beforeBill.getEndTime(), tContractRentType.getChangeTime());
                                    originalMoney=originalMoney.add(contract.getMonthRent().divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN))
                                            .multiply(new BigDecimal(originalDays));
                                    tBill.setPayableFeesMoney(contractRentTypeMoney.add(originalMoney));
                                    tBill.setOutstandingMoney(tBill.getPayableFeesMoney());
                                }else{
                                    // 之前已经涨、跌过租金了 需要判断周期是否还需要再涨、跌
                                    if ((LocalDateTime.now().getYear() - contract.getChangeTime().getYear())%tContractRentType.getCycleTime()==0){
                                        contract.setChangeTime(LocalDateTime.now());
                                        // 租金递增递减的时长 天
                                        long moneyDays = ChronoUnit.DAYS.between(tContractRentType.getChangeTime(), contract.getEndTime());
                                        // 递增递减的租金
                                        BigDecimal contractRentTypeMoney = new BigDecimal("0");
                                        // 不递增递减的租金
                                        BigDecimal originalMoney = new BigDecimal("0");
                                        // 原租金
                                        switch (tContractRentType.getIncreasingDecreasingType()){
                                            case 1:
                                                switch (tContractRentType.getIncreasingDecreasing()){
                                                    case 1:
                                                        contractRentTypeMoney =contractRentTypeMoney.add(contract.getChangeRent().multiply(new BigDecimal(100).add(tContractRentType.getNumericalValue())).divide(new BigDecimal(100),2,BigDecimal.ROUND_DOWN).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays)));
                                                        contract.setChangeRent(contractRentTypeMoney);
                                                        break;
                                                    case 2:
                                                        contractRentTypeMoney = contractRentTypeMoney.add(contract.getChangeRent().multiply((new BigDecimal(100).subtract(tContractRentType.getNumericalValue()))).divide(new BigDecimal(100),2,BigDecimal.ROUND_DOWN).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays)).divide(new BigDecimal(contract.getPayType().equals("1")? 1:contract.getPayType().equals("2")? 3:12),2,BigDecimal.ROUND_DOWN));
                                                        contract.setChangeRent(contractRentTypeMoney);
                                                        break;
                                                }
                                                break;
                                            case 2:
                                                switch (tContractRentType.getIncreasingDecreasing()){
                                                    case 1:
                                                        contractRentTypeMoney =contractRentTypeMoney.add(contract.getChangeRent().add(tContractRentType.getNumericalValue())).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays));
                                                        contract.setChangeRent(contractRentTypeMoney);
                                                        break;
                                                    case 2:
                                                        contractRentTypeMoney = contractRentTypeMoney.add(contract.getChangeRent().subtract(tContractRentType.getNumericalValue())).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays));
                                                        contract.setChangeRent(contractRentTypeMoney);
                                                        break;
                                                }
                                                break;
                                        }
                                        // 不需要涨租金的时间段
                                        long originalDays = ChronoUnit.DAYS.between(beforeBill.getEndTime(), tContractRentType.getChangeTime());
                                        originalMoney=originalMoney.add(contract.getMonthRent().divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN))
                                                .multiply(new BigDecimal(originalDays));
                                        tBill.setPayableFeesMoney(contractRentTypeMoney.add(originalMoney));
                                        tBill.setOutstandingMoney(tBill.getPayableFeesMoney());
                                    }else{
                                        // 不涨租金 用上次的
                                        // 租金递增递减的时长 天
                                        long moneyDays = ChronoUnit.DAYS.between(tContractRentType.getChangeTime(), contract.getEndTime());
                                        // 递增递减的租金
                                        BigDecimal contractRentTypeMoney = new BigDecimal("0");
                                        // 不递增递减的租金
                                        BigDecimal originalMoney = new BigDecimal("0");
                                        // 原租金
                                        switch (tContractRentType.getIncreasingDecreasingType()){
                                            case 1:
                                                switch (tContractRentType.getIncreasingDecreasing()){
                                                    case 1:
                                                        contractRentTypeMoney =contractRentTypeMoney.add(contract.getChangeRent().multiply(new BigDecimal(100).add(tContractRentType.getNumericalValue())).divide(new BigDecimal(100),2,BigDecimal.ROUND_DOWN).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays)));
                                                        contract.setChangeRent(contractRentTypeMoney);
                                                        break;
                                                    case 2:
                                                        contractRentTypeMoney = contractRentTypeMoney.add(contract.getChangeRent().multiply((new BigDecimal(100).subtract(tContractRentType.getNumericalValue()))).divide(new BigDecimal(100),2,BigDecimal.ROUND_DOWN).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays)).divide(new BigDecimal(contract.getPayType().equals("1")? 1:contract.getPayType().equals("2")? 3:12),2,BigDecimal.ROUND_DOWN));
                                                        contract.setChangeRent(contractRentTypeMoney);
                                                        break;
                                                }
                                                break;
                                            case 2:
                                                switch (tContractRentType.getIncreasingDecreasing()){
                                                    case 1:
                                                        contractRentTypeMoney =contractRentTypeMoney.add(contract.getChangeRent().add(tContractRentType.getNumericalValue())).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays));
                                                        contract.setChangeRent(contractRentTypeMoney);
                                                        break;
                                                    case 2:
                                                        contractRentTypeMoney = contractRentTypeMoney.add(contract.getChangeRent().subtract(tContractRentType.getNumericalValue())).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays));
                                                        contract.setChangeRent(contractRentTypeMoney);
                                                        break;
                                                }
                                                break;
                                        }
                                        // 不需要涨租金的时间段
                                        long originalDays = ChronoUnit.DAYS.between(beforeBill.getEndTime(), tContractRentType.getChangeTime());
                                        originalMoney=originalMoney.add(contract.getMonthRent().divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN))
                                                .multiply(new BigDecimal(originalDays));
                                        tBill.setPayableFeesMoney(contractRentTypeMoney.add(originalMoney));
                                        tBill.setOutstandingMoney(tBill.getPayableFeesMoney());
                                    }
                                }
                            }
                        }else{
                            long allDays = ChronoUnit.DAYS.between(beforeBill.getEndTime(), (contract.getPayType().equals("1")?
                                    beforeBill.getEndTime().plusMonths(1):contract.getPayType().equals("2")?
                                    beforeBill.getEndTime().plusMonths(3):beforeBill.getEndTime().plusMonths(12)).with(TemporalAdjusters.lastDayOfMonth()));
                            tBill.setPayableFeesMoney(contract.getMonthRent().divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(allDays)));
                            tBill.setOutstandingMoney(tBill.getPayableFeesMoney());
                        }
                        tBill.setContractNumber(contract.getContractNumber());
                        if (beforeBill.getEndTime().plusMonths(contract.getPayType().equals("1")? 1:contract.getPayType().equals("2")? 3:12).getDayOfMonth()<=15){
                            tBill.setPayableFeesTime(contract.getEndTime());
                        }else{
                            tBill.setPayableFeesTime((contract.getPayType().equals("1")?
                                    beforeBill.getEndTime().plusMonths(1).withDayOfMonth(15):contract.getPayType().equals("2")?
                                    beforeBill.getEndTime().plusMonths(3).withDayOfMonth(15):beforeBill.getEndTime().withDayOfMonth(15).plusMonths(12)));
                        }
                        tBill.setPayFeesStatus("1");
                        tBill.setBillType("1");
                        tBill.setStartTime(beforeBill.getEndTime().plusDays(1));
                        tBill.setEndTime(contract.getEndTime());
                        bills.add(tBill);
                    }
                }
            }
            billService.saveBatch(bills);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    public static void main(String[] args) {
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TContractServiceImpl.java
@@ -30,6 +30,7 @@
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.time.temporal.TemporalAdjusters;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@@ -143,30 +144,21 @@
        contract.setFirstPayTime(contract.getStartTime().plusDays(10));
        List<TBill> bills = new ArrayList<>();
        List<TContractRentType> contractRentTypes = contractRentTypeService.list();
        // 生成第一笔账单
        // 第一次应缴费日期
        LocalDateTime firstPayTime = contract.getStartTime().plusDays(10).withHour(0).withMinute(0).withSecond(0);
        LocalDate localDate = contract.getStartTime().plusDays(10).toLocalDate();
        LocalDate now = LocalDate.now();
        TBill rentBill = new TBill();
        rentBill.setContractId(contract.getId());
        rentBill.setContractNumber(contract.getContractNumber());
        LocalDateTime startPayTime = contract.getStartPayTime();
        LocalDateTime endTime1 = contract.getEndTime();
//                // 计算两个时间相差多少天
//                // 如果时间小于30天 需要计算每日租金
//                if (days<30){
//                    rentBill.setPayableFeesMoney(contract.getMonthRent().divide(new BigDecimal("30"),2,BigDecimal.ROUND_DOWN).multiply(new BigDecimal(days)));
//                }else{
//                    rentBill.setPayableFeesMoney(contract.getPayType().equals("1")?contract.getMonthRent():
//                            contract.getPayType().equals("2")?contract.getMonthRent().multiply(new BigDecimal("3")):contract.getMonthRent().multiply(new BigDecimal("12")).setScale(2,BigDecimal.ROUND_DOWN));
//                }
        rentBill.setPayableFeesTime(firstPayTime);
        rentBill.setPayFeesStatus("1");
        if (firstPayTime.toLocalDate().equals(LocalDate.now())){
            rentBill.setPayFeesStatus("1");
        }else {
            rentBill.setPayFeesStatus("2");
        }
        rentBill.setBillType("1");
        rentBill.setStartTime(contract.getStartPayTime());
        TContractRentType tContractRentType = contractRentTypes.stream().filter(e -> e.getContractId().equals(contract.getId())).findFirst().orElse(null);
        if (tContractRentType!=null && contract.getStartPayTime().plusMonths(contract.getPayType().equals("1")? 1:contract.getPayType().equals("2")? 3:12).isAfter(tContractRentType.getChangeTime())){
            // 计算租金变动的天数
            long moneyDays = ChronoUnit.DAYS.between(tContractRentType.getChangeTime(), contract.getStartPayTime().plusMonths(contract.getPayType().equals("1")? 1:contract.getPayType().equals("2")? 3:12))+1L;
@@ -226,8 +218,6 @@
            rentBill.setOutstandingMoney(rentBill.getPayableFeesMoney());
        }
        // 租金账单
        bills.add(rentBill);
        // 押金账单
        TBill depositBill = new TBill();
        depositBill.setContractId(contract.getId());
@@ -236,47 +226,385 @@
        depositBill.setOutstandingMoney(depositBill.getPayableFeesMoney());
        depositBill.setPayableFeesTime(firstPayTime);
        depositBill.setPayFeesStatus("1");
        if (firstPayTime.toLocalDate().equals(LocalDate.now())){
            depositBill.setPayFeesStatus("1");
        }else {
            depositBill.setPayFeesStatus("2");
        }
        depositBill.setBillType("2");
        bills.add(depositBill);
        this.updateById(contract);
        billService.saveBatch(bills);
        // 用户签订合同后 生成第一批账单包含租金账单和押金账单 后续账单通过定时任务生成
//        TBill rent = new TBill();
//        rent.setContractId(contract.getId());
//        // 应缴费租金
//        BigDecimal payableFeesMoney = new BigDecimal("0");
//        LocalDateTime startTime = contract.getStartTime();
//        LocalDateTime endTime = contract.getEndTime();
//        // 计算相差多少天
//        long days = ChronoUnit.DAYS.between(startTime, endTime);
//        // 计算相差多少个月
//        long months = ChronoUnit.MONTHS.between(startTime, endTime);
//        if (months<=31){
//            // 小于等于一个月 合计租金就是首笔账单金额
//            payableFeesMoney = contract.getTotalRent();
//        }else{
//            switch (contract.getPayType()){
//                case "1":
//                    break;
//                case "2":
//                    break;
//                case "3":
//                    break;
//            }
//        }
//
//        rent.setPayableFeesMoney(payableFeesMoney);
//        rent.setPayableFeesTime(contract.getFirstPayTime());
//        rent.setPayFeesStatus("1");
//        rent.setBillType("1");
//
//        TBill deposit = new TBill();
//        deposit.setContractId(contract.getId());
//        deposit.setPayableFeesMoney(contract.getDeposit());
//        deposit.setPayableFeesTime(contract.getFirstPayTime());
//        deposit.setPayFeesStatus("1");
//        deposit.setBillType("2");
        billService.save(rentBill);
        billService.save(depositBill);
        // 生成后续账单
        try {
            TBill beforeBill = billService.lambdaQuery().eq(TBill::getContractId, contract.getId()).eq(TBill::getBillType, 1).orderByDesc(TBill::getCreateTime)
                    .last("limit 1").one();
            while(beforeBill.getEndTime().plusMonths(contract.getPayType().equals("1")? 1:contract.getPayType().equals("2")? 3:12).isBefore(contract.getEndTime())){
                if (beforeBill.getEndTime().toLocalDate().equals(contract.getEndTime().toLocalDate()))break;
                    TBill tBill = new TBill();
                    tBill.setContractId(contract.getId());
                    tBill.setContractNumber(contract.getContractNumber());
                    // 根据支付方式判断需不需要生成订单
                    if (!(beforeBill.getEndTime().toLocalDate().equals(contract.getEndTime().toLocalDate()))
                            &&
                            (contract.getPayType().equals("1")?
                                    beforeBill.getEndTime().plusMonths(1):contract.getPayType().equals("2")?
                                    beforeBill.getEndTime().plusMonths(3):beforeBill.getEndTime().plusMonths(12))
                                    .with(TemporalAdjusters.lastDayOfMonth()).isBefore(contract.getEndTime())
                            && beforeBill.getEndTime().isBefore(contract.getEndTime())
                    ){
                        tBill.setContractId(contract.getId());
                        if (contract.getIsIncreasing()){
                            if (tContractRentType!=null
                                    && beforeBill.getEndTime().isBefore(tContractRentType.getChangeTime())
                                    && beforeBill.getEndTime().plusMonths(contract.getPayType().equals("1")? 1:contract.getPayType().equals("2")? 3:12).with(TemporalAdjusters.lastDayOfMonth()).isAfter(tContractRentType.getChangeTime())){
                                // 如果没变过
                                if (contract.getChangeTime()==null){
                                    contract.setChangeTime(LocalDateTime.now());
                                    // 租金递增递减的时长 天
                                    long moneyDays = ChronoUnit.DAYS.between(tContractRentType.getChangeTime(), contract.getEndTime());
                                    // 递增递减的租金
                                    BigDecimal contractRentTypeMoney = new BigDecimal("0");
                                    // 不递增递减的租金
                                    BigDecimal originalMoney = new BigDecimal("0");
                                    // 原租金
                                    switch (tContractRentType.getIncreasingDecreasingType()){
                                        case 1:
                                            switch (tContractRentType.getIncreasingDecreasing()){
                                                case 1:
                                                    contractRentTypeMoney =contractRentTypeMoney.add(contract.getChangeRent().multiply(new BigDecimal(100).add(tContractRentType.getNumericalValue())).divide(new BigDecimal(100),2,BigDecimal.ROUND_DOWN).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays)));
                                                    contract.setChangeRent(contractRentTypeMoney);
                                                    break;
                                                case 2:
                                                    contractRentTypeMoney = contractRentTypeMoney.add(contract.getChangeRent().multiply((new BigDecimal(100).subtract(tContractRentType.getNumericalValue()))).divide(new BigDecimal(100),2,BigDecimal.ROUND_DOWN).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays)).divide(new BigDecimal(contract.getPayType().equals("1")? 1:contract.getPayType().equals("2")? 3:12),2,BigDecimal.ROUND_DOWN));
                                                    contract.setChangeRent(contractRentTypeMoney);
                                                    break;
                                            }
                                            break;
                                        case 2:
                                            switch (tContractRentType.getIncreasingDecreasing()){
                                                case 1:
                                                    contractRentTypeMoney =contractRentTypeMoney.add(contract.getChangeRent().add(tContractRentType.getNumericalValue())).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays));
                                                    contract.setChangeRent(contractRentTypeMoney);
                                                    break;
                                                case 2:
                                                    contractRentTypeMoney = contractRentTypeMoney.add(contract.getChangeRent().subtract(tContractRentType.getNumericalValue())).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays));
                                                    contract.setChangeRent(contractRentTypeMoney);
                                                    break;
                                            }
                                            break;
                                    }
                                    // 不需要涨租金的时间段
                                    long originalDays = ChronoUnit.DAYS.between(beforeBill.getEndTime(), tContractRentType.getChangeTime());
                                    originalMoney=originalMoney.add(contract.getMonthRent().divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN))
                                            .multiply(new BigDecimal(originalDays));
                                    tBill.setPayableFeesMoney(contractRentTypeMoney.add(originalMoney));
                                    tBill.setOutstandingMoney(tBill.getPayableFeesMoney());
                                }else{
                                    // 之前已经涨、跌过租金了 需要判断周期是否还需要再涨、跌
                                    if ((LocalDateTime.now().getYear() - contract.getChangeTime().getYear())%tContractRentType.getCycleTime()==0){
                                        contract.setChangeTime(LocalDateTime.now());
                                        // 租金递增递减的时长 天
                                        long moneyDays = ChronoUnit.DAYS.between(tContractRentType.getChangeTime(), contract.getEndTime());
                                        // 递增递减的租金
                                        BigDecimal contractRentTypeMoney = new BigDecimal("0");
                                        // 不递增递减的租金
                                        BigDecimal originalMoney = new BigDecimal("0");
                                        // 原租金
                                        switch (tContractRentType.getIncreasingDecreasingType()){
                                            case 1:
                                                switch (tContractRentType.getIncreasingDecreasing()){
                                                    case 1:
                                                        contractRentTypeMoney =contractRentTypeMoney.add(contract.getChangeRent().multiply(new BigDecimal(100).add(tContractRentType.getNumericalValue())).divide(new BigDecimal(100),2,BigDecimal.ROUND_DOWN).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays)));
                                                        contract.setChangeRent(contractRentTypeMoney);
                                                        break;
                                                    case 2:
                                                        contractRentTypeMoney = contractRentTypeMoney.add(contract.getChangeRent().multiply((new BigDecimal(100).subtract(tContractRentType.getNumericalValue()))).divide(new BigDecimal(100),2,BigDecimal.ROUND_DOWN).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays)).divide(new BigDecimal(contract.getPayType().equals("1")? 1:contract.getPayType().equals("2")? 3:12),2,BigDecimal.ROUND_DOWN));
                                                        contract.setChangeRent(contractRentTypeMoney);
                                                        break;
                                                }
                                                break;
                                            case 2:
                                                switch (tContractRentType.getIncreasingDecreasing()){
                                                    case 1:
                                                        contractRentTypeMoney =contractRentTypeMoney.add(contract.getChangeRent().add(tContractRentType.getNumericalValue())).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays));
                                                        contract.setChangeRent(contractRentTypeMoney);
                                                        break;
                                                    case 2:
                                                        contractRentTypeMoney = contractRentTypeMoney.add(contract.getChangeRent().subtract(tContractRentType.getNumericalValue())).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays));
                                                        contract.setChangeRent(contractRentTypeMoney);
                                                        break;
                                                }
                                                break;
                                        }
                                        // 不需要涨租金的时间段
                                        long originalDays = ChronoUnit.DAYS.between(beforeBill.getEndTime(), tContractRentType.getChangeTime());
                                        originalMoney=originalMoney.add(contract.getMonthRent().divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN))
                                                .multiply(new BigDecimal(originalDays));
                                        tBill.setPayableFeesMoney(contractRentTypeMoney.add(originalMoney));
                                        tBill.setOutstandingMoney(tBill.getPayableFeesMoney());
                                    }else{
                                        // 不涨租金 用上次的
                                        // 租金递增递减的时长 天
                                        long moneyDays = ChronoUnit.DAYS.between(tContractRentType.getChangeTime(), contract.getEndTime());
                                        // 递增递减的租金
                                        BigDecimal contractRentTypeMoney = new BigDecimal("0");
                                        // 不递增递减的租金
                                        BigDecimal originalMoney = new BigDecimal("0");
                                        // 原租金
                                        switch (tContractRentType.getIncreasingDecreasingType()){
                                            case 1:
                                                switch (tContractRentType.getIncreasingDecreasing()){
                                                    case 1:
                                                        contractRentTypeMoney =contractRentTypeMoney.add(contract.getChangeRent().multiply(new BigDecimal(100).add(tContractRentType.getNumericalValue())).divide(new BigDecimal(100),2,BigDecimal.ROUND_DOWN).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays)));
                                                        contract.setChangeRent(contractRentTypeMoney);
                                                        break;
                                                    case 2:
                                                        contractRentTypeMoney = contractRentTypeMoney.add(contract.getChangeRent().multiply((new BigDecimal(100).subtract(tContractRentType.getNumericalValue()))).divide(new BigDecimal(100),2,BigDecimal.ROUND_DOWN).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays)).divide(new BigDecimal(contract.getPayType().equals("1")? 1:contract.getPayType().equals("2")? 3:12),2,BigDecimal.ROUND_DOWN));
                                                        contract.setChangeRent(contractRentTypeMoney);
                                                        break;
                                                }
                                                break;
                                            case 2:
                                                switch (tContractRentType.getIncreasingDecreasing()){
                                                    case 1:
                                                        contractRentTypeMoney =contractRentTypeMoney.add(contract.getChangeRent().add(tContractRentType.getNumericalValue())).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays));
                                                        contract.setChangeRent(contractRentTypeMoney);
                                                        break;
                                                    case 2:
                                                        contractRentTypeMoney = contractRentTypeMoney.add(contract.getChangeRent().subtract(tContractRentType.getNumericalValue())).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays));
                                                        contract.setChangeRent(contractRentTypeMoney);
                                                        break;
                                                }
                                                break;
                                        }
                                        // 不需要涨租金的时间段
                                        long originalDays = ChronoUnit.DAYS.between(beforeBill.getEndTime(), tContractRentType.getChangeTime());
                                        originalMoney=originalMoney.add(contract.getMonthRent().divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN))
                                                .multiply(new BigDecimal(originalDays));
                                        tBill.setPayableFeesMoney(contractRentTypeMoney.add(originalMoney));
                                        tBill.setOutstandingMoney(tBill.getPayableFeesMoney());
                                    }
                                }
                            }
                        }else{
                            long allDays = ChronoUnit.DAYS.between(beforeBill.getEndTime(), (contract.getPayType().equals("1")?
                                    beforeBill.getEndTime().plusMonths(1):contract.getPayType().equals("2")?
                                    beforeBill.getEndTime().plusMonths(3):beforeBill.getEndTime().plusMonths(12)).with(TemporalAdjusters.lastDayOfMonth()));
                            tBill.setPayableFeesMoney(contract.getMonthRent().divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(allDays)));
                            tBill.setOutstandingMoney(tBill.getPayableFeesMoney());
                        }
                        tBill.setContractNumber(contract.getContractNumber());
                        if (beforeBill.getEndTime().plusMonths(contract.getPayType().equals("1")? 1:contract.getPayType().equals("2")? 3:12).getDayOfMonth()<=15){
                            tBill.setPayableFeesTime(contract.getEndTime());
                        }else{
                            tBill.setPayableFeesTime((contract.getPayType().equals("1")?
                                    beforeBill.getEndTime().plusMonths(1).withDayOfMonth(15):contract.getPayType().equals("2")?
                                    beforeBill.getEndTime().plusMonths(3).withDayOfMonth(15):beforeBill.getEndTime().withDayOfMonth(15).plusMonths(12)));
                        }
                        tBill.setPayFeesStatus("2");
                        tBill.setBillType("1");
                        tBill.setStartTime(beforeBill.getEndTime().plusDays(1));
                        tBill.setEndTime(contract.getEndTime());
                    }
                    billMapper.insert(tBill);
                }
        } catch (Exception e) {
            e.printStackTrace();
        }
        TBill beforeBill = billService.lambdaQuery().eq(TBill::getContractId, contract.getId()).eq(TBill::getBillType, 1).orderByDesc(TBill::getCreateTime)
                .last("limit 1").one();
        // 生成最后一笔账单
        if (!(beforeBill.getEndTime().toLocalDate().equals(contract.getEndTime().toLocalDate()))
                &&
                (contract.getPayType().equals("1")?
                        beforeBill.getEndTime().plusMonths(1):contract.getPayType().equals("2")?
                        beforeBill.getEndTime().plusMonths(3):beforeBill.getEndTime().plusMonths(12))
                        .with(TemporalAdjusters.lastDayOfMonth()).isAfter(contract.getEndTime())
                && beforeBill.getEndTime().isBefore(contract.getEndTime())
        ){
            TBill tBill = new TBill();
            tBill.setContractId(contract.getId());
            if (contract.getIsIncreasing()){
                if (tContractRentType!=null
                        && beforeBill.getEndTime().isBefore(tContractRentType.getChangeTime())
                        && beforeBill.getEndTime().plusMonths(contract.getPayType().equals("1")? 1:contract.getPayType().equals("2")? 3:12).with(TemporalAdjusters.lastDayOfMonth()).isAfter(tContractRentType.getChangeTime())){
                    // 如果没变过
                    if (contract.getChangeTime()==null){
                        contract.setChangeTime(LocalDateTime.now());
                        // 租金递增递减的时长 天
                        long moneyDays = ChronoUnit.DAYS.between(tContractRentType.getChangeTime(), contract.getEndTime());
                        // 递增递减的租金
                        BigDecimal contractRentTypeMoney = new BigDecimal("0");
                        // 不递增递减的租金
                        BigDecimal originalMoney = new BigDecimal("0");
                        // 原租金
                        switch (tContractRentType.getIncreasingDecreasingType()){
                            case 1:
                                switch (tContractRentType.getIncreasingDecreasing()){
                                    case 1:
                                        contractRentTypeMoney =contractRentTypeMoney.add(contract.getChangeRent().multiply(new BigDecimal(100).add(tContractRentType.getNumericalValue())).divide(new BigDecimal(100),2,BigDecimal.ROUND_DOWN).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays)));
                                        contract.setChangeRent(contractRentTypeMoney);
                                        break;
                                    case 2:
                                        contractRentTypeMoney = contractRentTypeMoney.add(contract.getChangeRent().multiply((new BigDecimal(100).subtract(tContractRentType.getNumericalValue()))).divide(new BigDecimal(100),2,BigDecimal.ROUND_DOWN).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays)).divide(new BigDecimal(contract.getPayType().equals("1")? 1:contract.getPayType().equals("2")? 3:12),2,BigDecimal.ROUND_DOWN));
                                        contract.setChangeRent(contractRentTypeMoney);
                                        break;
                                }
                                break;
                            case 2:
                                switch (tContractRentType.getIncreasingDecreasing()){
                                    case 1:
                                        contractRentTypeMoney =contractRentTypeMoney.add(contract.getChangeRent().add(tContractRentType.getNumericalValue())).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays));
                                        contract.setChangeRent(contractRentTypeMoney);
                                        break;
                                    case 2:
                                        contractRentTypeMoney = contractRentTypeMoney.add(contract.getChangeRent().subtract(tContractRentType.getNumericalValue())).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays));
                                        contract.setChangeRent(contractRentTypeMoney);
                                        break;
                                }
                                break;
                        }
                        // 不需要涨租金的时间段
                        long originalDays = ChronoUnit.DAYS.between(beforeBill.getEndTime(), tContractRentType.getChangeTime());
                        // 不需要涨租金的时间段
                        if (contract.getFirstPayTime().isBefore(tContractRentType.getChangeTime())){
                            originalMoney=originalMoney.add(contract.getMonthRent().divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN))
                                    .multiply(new BigDecimal(originalDays));
                            tBill.setPayableFeesMoney(contractRentTypeMoney.add(originalMoney));
                            tBill.setOutstandingMoney(tBill.getPayableFeesMoney());
                        }else{
                            tBill.setPayableFeesMoney(contractRentTypeMoney);
                            tBill.setOutstandingMoney(tBill.getPayableFeesMoney());
                        }
                    }else{
                        // 之前已经涨、跌过租金了 需要判断周期是否还需要再涨、跌
                        if ((LocalDateTime.now().getYear() - contract.getChangeTime().getYear())%tContractRentType.getCycleTime()==0){
                            contract.setChangeTime(LocalDateTime.now());
                            // 租金递增递减的时长 天
                            long moneyDays = ChronoUnit.DAYS.between(tContractRentType.getChangeTime(), contract.getEndTime());
                            // 递增递减的租金
                            BigDecimal contractRentTypeMoney = new BigDecimal("0");
                            // 不递增递减的租金
                            BigDecimal originalMoney = new BigDecimal("0");
                            // 原租金
                            switch (tContractRentType.getIncreasingDecreasingType()){
                                case 1:
                                    switch (tContractRentType.getIncreasingDecreasing()){
                                        case 1:
                                            contractRentTypeMoney =contractRentTypeMoney.add(contract.getChangeRent().multiply(new BigDecimal(100).add(tContractRentType.getNumericalValue())).divide(new BigDecimal(100),2,BigDecimal.ROUND_DOWN).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays)));
                                            contract.setChangeRent(contractRentTypeMoney);
                                            break;
                                        case 2:
                                            contractRentTypeMoney = contractRentTypeMoney.add(contract.getChangeRent().multiply((new BigDecimal(100).subtract(tContractRentType.getNumericalValue()))).divide(new BigDecimal(100),2,BigDecimal.ROUND_DOWN).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays)).divide(new BigDecimal(contract.getPayType().equals("1")? 1:contract.getPayType().equals("2")? 3:12),2,BigDecimal.ROUND_DOWN));
                                            contract.setChangeRent(contractRentTypeMoney);
                                            break;
                                    }
                                    break;
                                case 2:
                                    switch (tContractRentType.getIncreasingDecreasing()){
                                        case 1:
                                            contractRentTypeMoney =contractRentTypeMoney.add(contract.getChangeRent().add(tContractRentType.getNumericalValue())).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays));
                                            contract.setChangeRent(contractRentTypeMoney);
                                            break;
                                        case 2:
                                            contractRentTypeMoney = contractRentTypeMoney.add(contract.getChangeRent().subtract(tContractRentType.getNumericalValue())).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays));
                                            contract.setChangeRent(contractRentTypeMoney);
                                            break;
                                    }
                                    break;
                            }
                            // 不需要涨租金的时间段
                            long originalDays = ChronoUnit.DAYS.between(beforeBill.getEndTime(), tContractRentType.getChangeTime());
                            originalMoney=originalMoney.add(contract.getMonthRent().divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN))
                                    .multiply(new BigDecimal(originalDays));
                            tBill.setPayableFeesMoney(contractRentTypeMoney.add(originalMoney));
                            tBill.setOutstandingMoney(tBill.getPayableFeesMoney());
                        }else{
                            // 不涨租金 用上次的
                            // 租金递增递减的时长 天
                            long moneyDays = ChronoUnit.DAYS.between(tContractRentType.getChangeTime(), contract.getEndTime());
                            // 递增递减的租金
                            BigDecimal contractRentTypeMoney = new BigDecimal("0");
                            // 不递增递减的租金
                            BigDecimal originalMoney = new BigDecimal("0");
                            // 原租金
                            switch (tContractRentType.getIncreasingDecreasingType()){
                                case 1:
                                    switch (tContractRentType.getIncreasingDecreasing()){
                                        case 1:
                                            contractRentTypeMoney =contractRentTypeMoney.add(contract.getChangeRent().multiply(new BigDecimal(100).add(tContractRentType.getNumericalValue())).divide(new BigDecimal(100),2,BigDecimal.ROUND_DOWN).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays)));
                                            contract.setChangeRent(contractRentTypeMoney);
                                            break;
                                        case 2:
                                            contractRentTypeMoney = contractRentTypeMoney.add(contract.getChangeRent().multiply((new BigDecimal(100).subtract(tContractRentType.getNumericalValue()))).divide(new BigDecimal(100),2,BigDecimal.ROUND_DOWN).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays)).divide(new BigDecimal(contract.getPayType().equals("1")? 1:contract.getPayType().equals("2")? 3:12),2,BigDecimal.ROUND_DOWN));
                                            contract.setChangeRent(contractRentTypeMoney);
                                            break;
                                    }
                                    break;
                                case 2:
                                    switch (tContractRentType.getIncreasingDecreasing()){
                                        case 1:
                                            contractRentTypeMoney =contractRentTypeMoney.add(contract.getChangeRent().add(tContractRentType.getNumericalValue())).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays));
                                            contract.setChangeRent(contractRentTypeMoney);
                                            break;
                                        case 2:
                                            contractRentTypeMoney = contractRentTypeMoney.add(contract.getChangeRent().subtract(tContractRentType.getNumericalValue())).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays));
                                            contract.setChangeRent(contractRentTypeMoney);
                                            break;
                                    }
                                    break;
                            }
                            // 不需要涨租金的时间段
                            long originalDays = ChronoUnit.DAYS.between(beforeBill.getEndTime(), tContractRentType.getChangeTime());
                            originalMoney=originalMoney.add(contract.getMonthRent().divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN))
                                    .multiply(new BigDecimal(originalDays));
                            tBill.setPayableFeesMoney(contractRentTypeMoney.add(originalMoney));
                            tBill.setOutstandingMoney(tBill.getPayableFeesMoney());
                        }
                    }
                }
            }else{
                long allDays = ChronoUnit.DAYS.between(beforeBill.getEndTime(), contract.getEndTime());
                tBill.setPayableFeesMoney(contract.getMonthRent().divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(allDays)));
                tBill.setOutstandingMoney(tBill.getPayableFeesMoney());
            }
            tBill.setContractNumber(contract.getContractNumber());
            if (beforeBill.getEndTime().plusMonths(contract.getPayType().equals("1")? 1:contract.getPayType().equals("2")? 3:12).getDayOfMonth()<=15){
                tBill.setPayableFeesTime(contract.getEndTime().withHour(0).withMinute(0).withSecond(0));
            }else{
                tBill.setPayableFeesTime((contract.getPayType().equals("1")?
                        beforeBill.getEndTime().plusMonths(1).withDayOfMonth(15):contract.getPayType().equals("2")?
                        beforeBill.getEndTime().plusMonths(3).withDayOfMonth(15):beforeBill.getEndTime().withDayOfMonth(15).plusMonths(12).withHour(0).withMinute(0).withSecond(0)));
            }
            tBill.setPayFeesStatus("1");
            tBill.setBillType("1");
            tBill.setStartTime(beforeBill.getEndTime().plusDays(1));
            tBill.setEndTime(beforeBill.getEndTime().plusMonths(contract.getPayType().equals("1")? 1:contract.getPayType().equals("2")? 3:12));
            billService.save(tBill);
        }
        return R.ok();
    }