From db7e077ea8f2d995e922bc11b77dc149592a7455 Mon Sep 17 00:00:00 2001
From: yupeng <roc__yu@163.com>
Date: 星期三, 09 四月 2025 12:35:49 +0800
Subject: [PATCH] Merge remote-tracking branch 'origin/master' into xizang-changyun

---
 ruoyi-system/src/main/java/com/ruoyi/system/query/RentalReturnAuditQuery.java                 |   27 
 ruoyi-system/src/main/java/com/ruoyi/system/mapper/TRentalReturnRecordMapper.java             |   18 
 ruoyi-system/src/main/java/com/ruoyi/system/vo/RentalRetureApplyVO.java                       |   30 
 ruoyi-system/src/main/java/com/ruoyi/system/model/TRentalReturnRecord.java                    |   85 ++
 ruoyi-system/src/main/java/com/ruoyi/system/model/TBill.java                                  |   31 
 ruoyi-system/src/main/java/com/ruoyi/system/vo/HouseMapDistributionVO.java                    |    2 
 ruoyi-system/src/main/resources/mapper/system/TBillMapper.xml                                 |   23 
 ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TCheckAcceptRecordController.java      |   18 
 ruoyi-system/src/main/java/com/ruoyi/system/service/TBillService.java                         |   18 
 ruoyi-system/src/main/resources/mapper/system/TCheckAcceptRecordMapper.xml                    |    2 
 ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TBillController.java                   |   33 
 ruoyi-applet/src/main/java/com/ruoyi/web/controller/api/TBillController.java                  |   27 
 ruoyi-system/src/main/java/com/ruoyi/system/service/impl/THouseServiceImpl.java               |   17 
 ruoyi-system/src/main/resources/mapper/system/TRentalReturnRecordMapper.xml                   |   74 ++
 ruoyi-system/src/main/java/com/ruoyi/system/service/impl/StateProcessTemplateServiceImpl.java |    7 
 ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TTenantServiceImpl.java              |    6 
 ruoyi-system/src/main/java/com/ruoyi/system/service/THouseService.java                        |    7 
 ruoyi-common/src/main/java/com/ruoyi/common/utils/CodeGenerateUtils.java                      |   19 
 ruoyi-system/src/main/java/com/ruoyi/system/dto/TerminateContractDTO.java                     |    2 
 ruoyi-system/src/main/java/com/ruoyi/system/vo/RentalReturnRecordVO.java                      |   90 ++
 ruoyi-applet/src/main/java/com/ruoyi/web/controller/api/TRentalReturnRecordController.java    |   57 +
 ruoyi-system/src/main/java/com/ruoyi/system/model/THouse.java                                 |    5 
 ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/ScreenController.java                  |  255 ++++---
 ruoyi-system/src/main/java/com/ruoyi/system/mapper/THouseMapper.java                          |    7 
 ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TBillServiceImpl.java                |   27 
 ruoyi-system/src/main/java/com/ruoyi/system/service/TContractService.java                     |    4 
 ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TRentalReturnRecordController.java     |   79 ++
 ruoyi-admin/src/main/java/com/ruoyi/web/controller/tool/WordTemplateProcessor.java            |  174 ++--
 ruoyi-system/src/main/java/com/ruoyi/system/mapper/TBillMapper.java                           |    9 
 ruoyi-system/src/main/java/com/ruoyi/system/model/TContract.java                              |    2 
 ruoyi-admin/src/main/java/com/ruoyi/web/controller/tool/WordUtil.java                         |   27 
 ruoyi-system/src/main/java/com/ruoyi/system/model/TFaultRepairMessage.java                    |    4 
 ruoyi-system/src/main/resources/mapper/system/SysUserMapper.xml                               |    8 
 ruoyi-system/src/main/java/com/ruoyi/system/query/RentalReturnRecordQuery.java                |   51 +
 ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/THouseController.java                  |    3 
 ruoyi-system/src/main/java/com/ruoyi/system/task/utils/TaskUtil.java                          |   29 
 ruoyi-system/src/main/java/com/ruoyi/system/service/ITRentalReturnRecordService.java          |   21 
 ruoyi-system/src/main/java/com/ruoyi/system/service/impl/ScreenService.java                   |  162 +++-
 ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TRentalReturnRecordServiceImpl.java  |  121 +++
 ruoyi-system/src/main/java/com/ruoyi/system/vo/MyHouseVO.java                                 |    3 
 ruoyi-system/src/main/resources/mapper/system/THouseMapper.xml                                |   13 
 ruoyi-system/src/main/java/com/ruoyi/system/mapper/TContractMapper.java                       |    2 
 ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TTenantController.java                 |    5 
 ruoyi-system/src/main/resources/mapper/system/TContractMapper.xml                             |   27 
 ruoyi-system/src/main/resources/mapper/system/TFaultRepairMessageMapper.xml                   |    3 
 ruoyi-applet/src/main/java/com/ruoyi/web/controller/api/IndexController.java                  |    1 
 ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TContractController.java               |  199 ++++-
 ruoyi-system/src/main/java/com/ruoyi/system/service/impl/FlowListenerService.java             |  112 ++
 ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TContractServiceImpl.java            |   11 
 ruoyi-system/src/main/java/com/ruoyi/system/model/TTenant.java                                |    4 
 50 files changed, 1,562 insertions(+), 399 deletions(-)

diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/ScreenController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/ScreenController.java
index c65a613..29e2b16 100644
--- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/ScreenController.java
+++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/ScreenController.java
@@ -1,8 +1,12 @@
 package com.ruoyi.web.controller.api;
 
+import cn.hutool.core.collection.CollectionUtil;
+import com.alibaba.fastjson2.JSONArray;
+import com.alibaba.fastjson2.JSONObject;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.ruoyi.common.core.domain.R;
 import com.ruoyi.common.utils.DateUtils;
+import com.ruoyi.common.utils.SecurityUtils;
 import com.ruoyi.system.model.TBill;
 import com.ruoyi.system.model.TContract;
 import com.ruoyi.system.model.THouse;
@@ -14,7 +18,6 @@
 import com.ruoyi.system.service.impl.ScreenService;
 import com.ruoyi.system.vo.*;
 import io.swagger.annotations.Api;
-import io.swagger.annotations.ApiModelProperty;
 import io.swagger.annotations.ApiOperation;
 import lombok.RequiredArgsConstructor;
 import org.springframework.context.annotation.Lazy;
@@ -30,6 +33,8 @@
 import java.time.temporal.ChronoUnit;
 import java.util.*;
 import java.util.stream.Collectors;
+
+import static org.checkerframework.checker.units.qual.Prefix.one;
 
 /**
  * @author mitao
@@ -64,49 +69,29 @@
         return R.ok(screenService.rentIncomeTrend());
     }
 
+
     @GetMapping("/getTenantCountTrend")
-    @ApiModelProperty(value = "租户数量趋势统计")
+    @ApiOperation(value = "租户数量趋势统计")
     public R<List<TenantCountTrendVO>> getTenantCountTrend() {
-
-        Date currentDate = new Date();
-        Date targetDate = DateUtils.addMonths(currentDate, -3 * 6);
-        Map<String, Date> startQuarterDate = DateUtils.getQuarterDate(targetDate);
-
-        Date targetDate2 = DateUtils.addMonths(currentDate, 0);
-        Map<String, Date> endQuarterDate = DateUtils.getQuarterDate(targetDate2);
-
-        List<TContract> contracts = contractService.list(new LambdaQueryWrapper<TContract>()
-                .isNotNull(TContract::getSignTime)
-                .between(TContract::getSignTime, startQuarterDate.get("first"), endQuarterDate.get("last"))
-                .orderByAsc(TContract::getSignTime));
-
-        // 创建季度格式化工具(示例:2025-Q1)
-        DateTimeFormatter quarterFormatter = DateTimeFormatter.ofPattern("yyyy-'Q'Q");
-
-        List<TenantCountTrendVO> trendData = contracts.stream()
-                .collect(Collectors.groupingBy(contract -> {
-                    LocalDate date = contract.getSignTime().toLocalDate();
-                    int quarter = (date.getMonthValue() - 1) / 3 + 1;
-                    return YearQuarter.from(date.withMonth(quarter * 3 - 2));
-                }, TreeMap::new, Collectors.counting()))
-                .entrySet().stream()
-                .map(entry -> new TenantCountTrendVO(
-                        entry.getKey().format(quarterFormatter),
-                        entry.getValue()))
-                .collect(Collectors.toList());
-
-        return R.ok(trendData);
+        return screenService.getTenantCountTrend();
     }
+
 
     /**
      * 实时租赁数据
      */
     @GetMapping("/getRealTimeRentData")
+    @ApiOperation("获取实时租赁数据")
     public R<List<RealTimeRentDataVO>> getRealTimeRentData() {
         // 随机获取十条房源
+        String businessDeptId = SecurityUtils.getBusinessDeptId();
         List<THouse> houses = houseService.list(new LambdaQueryWrapper<THouse>()
+                .eq(!"0".equals(businessDeptId),THouse::getBusinessDeptId, businessDeptId)
                 .last("ORDER BY RAND() LIMIT 10"));
 
+        if (CollectionUtil.isEmpty(houses)){
+            return R.ok(new ArrayList<>());
+        }
 
         // 提取streetIds
         List<String> streetIds = houses.stream()
@@ -121,7 +106,7 @@
         List<RealTimeRentDataVO> result = houses.stream().map(house -> {
             RealTimeRentDataVO vo = new RealTimeRentDataVO();
             vo.setStreetName(streetMap.getOrDefault(house.getStreetId(), "未知"));
-            vo.setRoomName(house.getRoomNumber());
+            vo.setRoomName(house.getHouseName());
             vo.setLeaseStatus(house.getLeaseStatus());
             return vo;
         }).collect(Collectors.toList());
@@ -129,103 +114,147 @@
         return R.ok(result);
     }
 
+
+    public static void main(String[] args) {
+        // 获取当前季度的开始和结束时间
+        // 获取当前季度的开始和结束时间的实现示例:
+        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
+        LocalDate now = LocalDate.now();
+        int month = now.getMonthValue();
+        int year = now.getYear();
+
+        // 计算季度起始月份(1,4,7,10)
+        int quarterStartMonth = ((month - 1) / 3) * 3 + 1;
+        int quarterEndMonth = quarterStartMonth + 2;
+        // 构建季度起止日期
+        LocalDate quarterStart = YearMonth.of(year, quarterStartMonth).atDay(1);
+        LocalDate quarterEnd = YearMonth.of(year, quarterEndMonth).atEndOfMonth();
+
+        System.out.println("季度开始:" + quarterStart.format(formatter));
+        System.out.println("季度结束:" + quarterEnd.format(formatter));
+    }
+
     /**
      * 获取房屋地图分布
      */
     @GetMapping("/getHouseMapDistribution")
+    @ApiOperation("获取房屋地图分布")
     public R<List<HouseMapDistributionVO>> getHouseMapDistribution() {
+
+        String businessDeptId = SecurityUtils.getBusinessDeptId();
+
+        List<TContract> tContracts = contractService.list(new LambdaQueryWrapper<TContract>()
+                .eq(!"0".equals(businessDeptId), TContract::getBusinessDeptId, businessDeptId)
+                .eq(TContract::getPayType, 2));
+        List<String> houseIds = tContracts.stream().map(TContract::getHouseId).collect(Collectors.toList());
+
+
         // 获取所有房屋信息
-        List<THouse> houses = houseService.list();
+        List<THouse> houses = houseService.list(new LambdaQueryWrapper<THouse>()
+                        .and(wrapper -> wrapper.in(!houseIds.isEmpty(),THouse::getId, houseIds)
+                                        .or(!houseIds.isEmpty())
+                                        .eq(THouse::getLeaseStatus, "1")
+                        )
+                .eq(!"0".equals(businessDeptId),THouse::getBusinessDeptId, businessDeptId)
+        );
         List<HouseMapDistributionVO> result = new ArrayList<>();
         for (THouse house : houses) {
             HouseMapDistributionVO houseMapDistributionVO = new HouseMapDistributionVO();
             houseMapDistributionVO.setHouseName(house.getHouseName());
             houseMapDistributionVO.setHouseAddress(house.getHouseAddress());
             houseMapDistributionVO.setHouseStatus(house.getLeaseStatus());
-            TContract contract = contractService.getOne(new LambdaQueryWrapper<TContract>()
-                    .eq(TContract::getHouseId, house.getId()));
-            TBill bill = billService.getOne(new LambdaQueryWrapper<TBill>()
-                    .eq(TBill::getContractId, contract.getId())
-                    .eq(TBill::getBillType, 1));
-
-
-            houseMapDistributionVO.setTenant(contract.getPartyTwoName());
-
-
-            LocalDateTime startTime = contract.getStartTime();
-            LocalDateTime endTime = contract.getEndTime();
-            BigDecimal monthRent = contract.getMonthRent();
-            // 计算相差月份
-            long monthsBetween = ChronoUnit.MONTHS.between(startTime, endTime);
-            BigDecimal payableFeesMoney = monthRent.multiply(new BigDecimal(monthsBetween));
-            BigDecimal remainingPayment = bill.getPayableFeesMoney();
-            BigDecimal paidAlready = payableFeesMoney.subtract(remainingPayment);
-            String rentStatus = String.format("%.2f/%.2f", paidAlready, payableFeesMoney);
-            houseMapDistributionVO.setRentStatus(rentStatus);
-
-            String payType = contract.getPayType();
-            String rent = "";
-            LocalDateTime payFeesTime = bill.getPayFeesTime();
-            switch (payType) {
-                case "1":
-                    if (isCurrentMonth(payFeesTime)) {
-                        rent = String.format("%.2f/%.2f", monthRent, monthRent);
-                    } else {
-                        rent = String.format("%.2f/%.2f", new BigDecimal("0"), monthRent);
-                    }
-                    break;
-                case "2":
-                    // 季付价格
-                    BigDecimal quarterRent = monthRent.multiply(new BigDecimal(3));
-                    if (isCurrentQuarter(payFeesTime)) {
-                        rent = String.format("%.2f/%.2f", quarterRent, quarterRent);
-                    } else {
-                        rent = String.format("%.2f/%.2f", new BigDecimal("0"), quarterRent);
-                    }
-                    break;
-                case "3":
-                    // 年付价格
-                    BigDecimal yearRent = monthRent.multiply(new BigDecimal(12));
-                    if (isCurrentYear(payFeesTime)) {
-                        rent = String.format("%.2f/%.2f", yearRent, yearRent);
-                    } else {
-                        rent = String.format("%.2f/%.2f", new BigDecimal("0"), yearRent);
-                    }
-                    break;
-            }
-            houseMapDistributionVO.setRent(rent);
             houseMapDistributionVO.setLongitude(house.getLongitude());
             houseMapDistributionVO.setLatitude(house.getLatitude());
+
+
+
+            TContract contract = contractService.getOne(new LambdaQueryWrapper<TContract>()
+                    .eq(!"0".equals(businessDeptId),TContract::getBusinessDeptId, businessDeptId)
+                    .eq(TContract::getPayType, 2)
+                    .gt(TContract::getEndTime, LocalDate.now())
+                    .eq(TContract::getHouseId, house.getId())
+                    .eq(TContract::getStatus, 4)
+                    .last("limit 1"));
+
+            if (contract != null){
+                List<TBill> tBills = billService.list(new LambdaQueryWrapper<TBill>()
+                        .eq(!"0".equals(businessDeptId),TBill::getBusinessDeptId, businessDeptId)
+                        .eq(TBill::getContractId, contract.getId())
+                        .eq(TBill::getBillType, 1));
+                houseMapDistributionVO.setTenant(contract.getPartyTwoName());
+
+                BigDecimal payFeesMoney = tBills.stream()
+                        .map(TBill::getPayFeesMoney)
+                        .reduce(BigDecimal::add)
+                        .orElse(BigDecimal.ZERO);
+
+                BigDecimal payableFeesMoney = tBills.stream()
+                        .map(TBill::getPayableFeesMoney)
+                        .reduce(BigDecimal::add)
+                        .orElse(BigDecimal.ZERO);
+                String rentStatus = String.format("%.2f/%.2f", payFeesMoney, payableFeesMoney);
+                houseMapDistributionVO.setRentStatus(rentStatus);
+
+
+//                TBill one = billService.getOne(new LambdaQueryWrapper<TBill>()
+//                        .le(TBill::getStartTime, LocalDate.now())
+//                        .ge(TBill::getEndTime, LocalDate.now())
+//                        .eq(TBill::getBillType, 1)
+//                        .eq(TBill::getContractId, contract.getId()));
+
+
+                // 获取当前季度的开始和结束时间
+                // 获取当前季度的开始和结束时间的实现示例:
+                DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
+                LocalDate now = LocalDate.now();
+                int month = now.getMonthValue();
+                int year = now.getYear();
+
+                // 计算季度起始月份(1,4,7,10)
+                int quarterStartMonth = ((month - 1) / 3) * 3 + 1;
+                int quarterEndMonth = quarterStartMonth + 2;
+                // 构建季度起止日期
+                LocalDate quarterStart = YearMonth.of(year, quarterStartMonth).atDay(1);
+                LocalDate quarterEnd = YearMonth.of(year, quarterEndMonth).atEndOfMonth();
+
+                System.out.println("季度开始:" + quarterStart.format(formatter));
+                System.out.println("季度结束:" + quarterEnd.format(formatter));
+
+                List<TBill> ones = billService.list(new LambdaQueryWrapper<TBill>()
+                        .eq(!"0".equals(businessDeptId),TBill::getBusinessDeptId, businessDeptId)
+                        .between(TBill::getStartTime, quarterStart, quarterEnd)
+                        .eq(TBill::getBillType, 1)
+                        .eq(TBill::getContractId, contract.getId()));
+                if (!ones.isEmpty()){
+
+                    long count = ones.stream().filter(tBill -> "4".equals(tBill.getPayFeesStatus())).count();
+                    if (count > 0){
+                        houseMapDistributionVO.setHouseStatus("4");
+                    }
+
+                    BigDecimal payFeesMoney1 = ones.stream()
+                            .map(TBill::getPayFeesMoney)
+                            .reduce(BigDecimal::add)
+                            .orElse(BigDecimal.ZERO);
+
+                    BigDecimal payableFeesMoney1 = ones.stream()
+                            .map(TBill::getPayableFeesMoney)
+                            .reduce(BigDecimal::add)
+                            .orElse(BigDecimal.ZERO);
+
+                    String rent = String.format("%.2f/%.2f", payFeesMoney1, payableFeesMoney1);
+                    houseMapDistributionVO.setRent(rent);
+                }else {
+                    houseMapDistributionVO.setRent("欠费");
+                }
+
+            }else {
+                houseMapDistributionVO.setTenant("暂无");
+                houseMapDistributionVO.setRentStatus("待出租");
+                houseMapDistributionVO.setRent("暂无");
+            }
             result.add(houseMapDistributionVO);
         }
         return R.ok(result);
     }
-
-
-    /**
-     * 判断是否是当前月份
-     * @param dateTime 日期时间
-     * @return boolean
-     */
-    public static boolean isCurrentMonth(LocalDateTime dateTime) {
-        YearMonth currentYearMonth = YearMonth.now();
-        YearMonth targetYearMonth = YearMonth.from(dateTime);
-        return currentYearMonth.equals(targetYearMonth);
-    }
-
-    public static boolean isCurrentQuarter(LocalDateTime dateTime) {
-        int currentMonth = LocalDateTime.now().getMonthValue();
-        int targetMonth = dateTime.getMonthValue();
-
-        // 计算当前季度和目标时间所属季度
-        int currentQuarter = (currentMonth - 1) / 3 + 1;
-        int targetQuarter = (targetMonth - 1) / 3 + 1;
-
-        return LocalDateTime.now().getYear() == dateTime.getYear() && currentQuarter == targetQuarter;
-    }
-
-    public static boolean isCurrentYear(LocalDateTime dateTime) {
-        return LocalDateTime.now().getYear() == dateTime.getYear();
-    }
-
 }
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TBillController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TBillController.java
index c9c2a91..7077198 100644
--- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TBillController.java
+++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TBillController.java
@@ -3,27 +3,39 @@
 
 import com.ruoyi.common.basic.PageInfo;
 import com.ruoyi.common.core.domain.R;
-import com.ruoyi.common.exception.ServiceException;
 import com.ruoyi.common.utils.SecurityUtils;
 import com.ruoyi.common.utils.StringUtils;
-import com.ruoyi.system.dto.*;
-import com.ruoyi.system.model.TBill;
+import com.ruoyi.system.dto.BillStatisticsDto;
+import com.ruoyi.system.dto.CachPayDto;
+import com.ruoyi.system.dto.OfflinePayCheckDto;
+import com.ruoyi.system.dto.SmsByBillDto;
+import com.ruoyi.system.dto.TBillDto;
+import com.ruoyi.system.dto.TbillSaveDto;
 import com.ruoyi.system.model.TBillConfirm;
 import com.ruoyi.system.model.TBillDetail;
 import com.ruoyi.system.model.TContract;
 import com.ruoyi.system.query.TBillQuery;
 import com.ruoyi.system.query.TContractQuery;
-import com.ruoyi.system.service.*;
+import com.ruoyi.system.service.TBillConfirmService;
+import com.ruoyi.system.service.TBillDetailService;
+import com.ruoyi.system.service.TBillService;
+import com.ruoyi.system.service.TContractService;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.validation.annotation.Validated;
-import org.springframework.web.bind.annotation.*;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
 
 import javax.validation.constraints.NotEmpty;
 import java.math.BigDecimal;
 import java.util.List;
+import java.util.Objects;
 
 /**
  * <p>
@@ -78,8 +90,15 @@
     @PreAuthorize("@ss.hasPermi('bill:list:addRent')")
     @PostMapping("add")
     @ApiOperation("新增账单")
-    public R add(@Validated @RequestBody TbillSaveDto bill){
-        bill.setBusinessDeptId(SecurityUtils.getBusinessDeptId());
+    public R<PageInfo<TBillDto>> add(@Validated @RequestBody TbillSaveDto bill){
+        String businessDeptId = SecurityUtils.getBusinessDeptId();
+        if (SecurityUtils.getBusinessDeptId().equals("0")) {
+            TContract contract = contractService.getById(bill.getContractId());
+            if (Objects.nonNull(contract)) {
+                businessDeptId = contract.getBusinessDeptId();
+            }
+        }
+        bill.setBusinessDeptId(businessDeptId);
         tBillService.saveBill(bill);
         return R.ok();
     }
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TCheckAcceptRecordController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TCheckAcceptRecordController.java
index 5b51c0a..11f61d4 100644
--- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TCheckAcceptRecordController.java
+++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TCheckAcceptRecordController.java
@@ -7,15 +7,9 @@
 import com.ruoyi.common.basic.PageInfo;
 import com.ruoyi.common.core.domain.R;
 import com.ruoyi.common.enums.BusinessType;
-import com.ruoyi.system.model.TBill;
-import com.ruoyi.system.model.TCheckAcceptRecord;
-import com.ruoyi.system.model.TContract;
-import com.ruoyi.system.model.THouse;
+import com.ruoyi.system.model.*;
 import com.ruoyi.system.query.TCheckAcceptRecordQuery;
-import com.ruoyi.system.service.TBillService;
-import com.ruoyi.system.service.TCheckAcceptRecordService;
-import com.ruoyi.system.service.TContractService;
-import com.ruoyi.system.service.THouseService;
+import com.ruoyi.system.service.*;
 import com.ruoyi.system.vo.TCheckAcceptRecordVO;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
@@ -29,6 +23,7 @@
 import java.time.LocalDate;
 import java.time.LocalDateTime;
 import java.util.List;
+import java.util.Objects;
 
 /**
  * <p>
@@ -48,6 +43,8 @@
     private final THouseService houseService;
     @Autowired
     private TBillService billService;
+    @Autowired
+    private TTenantService tenantService;
     @Autowired
     public TCheckAcceptRecordController(TCheckAcceptRecordService checkAcceptRecordService, TContractService contractService, THouseService houseService) {
         this.checkAcceptRecordService = checkAcceptRecordService;
@@ -73,6 +70,10 @@
     public R<THouse> getHouseByContractId(@RequestParam String contractId) {
         TContract contract = contractService.getById(contractId);
         THouse house = houseService.getById(contract.getHouseId());
+        TTenant tenant = tenantService.getById(contract.getTenantId());
+        if(Objects.nonNull(tenant)){
+            house.setTenantType(tenant.getTenantType());
+        }
         return R.ok(house);
     }
 
@@ -118,6 +119,7 @@
             tBill.setPayFeesStatus("1");
             tBill.setBillType("4");
             tBill.setSmsStatus(0);
+            tBill.setBusinessDeptId(contract.getBusinessDeptId());
             billService.save(tBill);
         }
 
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TContractController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TContractController.java
index 58477ae..3bdf4f4 100644
--- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TContractController.java
+++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TContractController.java
@@ -14,22 +14,31 @@
 import com.ruoyi.common.constant.DictConstants;
 import com.ruoyi.common.core.domain.R;
 import com.ruoyi.common.enums.BusinessType;
+import com.ruoyi.common.enums.DisabledEnum;
 import com.ruoyi.common.enums.ProcessCategoryEnum;
 import com.ruoyi.common.exception.ServiceException;
-import com.ruoyi.common.utils.DateUtils;
-import com.ruoyi.common.utils.DictUtils;
-import com.ruoyi.common.utils.StringUtils;
-import com.ruoyi.common.utils.WebUtils;
+import com.ruoyi.common.utils.*;
 import com.ruoyi.system.bo.ProcessStartBO;
 import com.ruoyi.system.dto.RevokeDTO;
 import com.ruoyi.system.dto.SetContractDto;
 import com.ruoyi.system.dto.TContractDTO;
 import com.ruoyi.system.dto.TerminateContractDTO;
 import com.ruoyi.system.export.ContractExport;
-import com.ruoyi.system.model.*;
+import com.ruoyi.system.model.TBill;
+import com.ruoyi.system.model.TCheckAcceptRecord;
+import com.ruoyi.system.model.TContract;
+import com.ruoyi.system.model.TContractRentType;
+import com.ruoyi.system.model.THouse;
+import com.ruoyi.system.model.TTenant;
 import com.ruoyi.system.query.TContractBillQuery;
 import com.ruoyi.system.query.TContractQuery;
-import com.ruoyi.system.service.*;
+import com.ruoyi.system.service.StateProcessTemplateService;
+import com.ruoyi.system.service.TBillService;
+import com.ruoyi.system.service.TCheckAcceptRecordService;
+import com.ruoyi.system.service.TContractRentTypeService;
+import com.ruoyi.system.service.TContractService;
+import com.ruoyi.system.service.THouseService;
+import com.ruoyi.system.service.TTenantService;
 import com.ruoyi.system.task.base.QuartzManager;
 import com.ruoyi.system.task.base.TimeJobType;
 import com.ruoyi.system.task.jobs.StateProcessJob;
@@ -45,17 +54,30 @@
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.validation.annotation.Validated;
-import org.springframework.web.bind.annotation.*;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
 
 import javax.servlet.ServletOutputStream;
 import javax.servlet.http.HttpServletResponse;
 import java.io.IOException;
+import java.io.UnsupportedEncodingException;
 import java.math.BigDecimal;
 import java.math.RoundingMode;
 import java.net.URLEncoder;
 import java.time.LocalDateTime;
 import java.time.temporal.ChronoUnit;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
 
 /**
  * <p>
@@ -98,7 +120,8 @@
     @PreAuthorize("@ss.hasPermi('contract:list:add')")
     public R<Boolean> addContract(@Validated @RequestBody TContractDTO dto) {
         LocalDateTime changeTime = dto.getChangeTime();
-        long count = contractService.count(new LambdaQueryWrapper<TContract>().eq(TContract::getContractNumber, dto.getContractNumber()));
+        long count = contractService.count(new LambdaQueryWrapper<TContract>()
+                .eq(TContract::getContractNumber, dto.getContractNumber()));
         if (count!=0){
             return R.fail("合同编号不可重复");
         }
@@ -109,7 +132,11 @@
         if (Objects.isNull(house)) {
             throw new ServiceException("房产信息不存在");
         }
+        house.setRentalReturnStatus("1");
+        houseService.updateById(house);
         dto.setBusinessDeptId(house.getBusinessDeptId());
+        // 生成合同编号
+        dto.setContractNumber(CodeGenerateUtils.generateVolumeSn(house.getBusinessDeptId()));
         contractService.save(dto);
         if (dto.getStatus().equals("2")){
             //发起合同新增审批
@@ -137,7 +164,13 @@
                             new ImmutableMap.Builder<String, Long>().
                                     put("id", flwTask.getId())
                                     .build();
-                    QuartzManager.addJob(StateProcessJob.class, (StateProcessJob.name+flwTask.getId()).toUpperCase(), TimeJobType.AUTO_AUDIT,new Date(new Date().getTime()+48*60*60*1000L), maps);
+                    QuartzManager.addJob(
+                            StateProcessJob.class,
+                            (StateProcessJob.name+flwTask.getId()).toUpperCase(),
+                            TimeJobType.AUTO_AUDIT,
+                            new Date(new Date().getTime()+48*60*60*1000L),
+                            maps
+                    );
                 }
             }
         }
@@ -204,7 +237,13 @@
                             new ImmutableMap.Builder<String, Long>().
                                     put("id", flwTask.getId())
                                     .build();
-                    QuartzManager.addJob(StateProcessJob.class, (StateProcessJob.name+flwTask.getId()).toUpperCase(), TimeJobType.AUTO_AUDIT,new Date(new Date().getTime()+48*60*60*1000L), maps);
+                    QuartzManager.addJob(
+                            StateProcessJob.class,
+                            (StateProcessJob.name + flwTask.getId()).toUpperCase(),
+                            TimeJobType.AUTO_AUDIT,
+                            new Date(new Date().getTime() + 48 * 60 * 60 * 1000L),
+                            maps
+                    );
                 }
             }
         }
@@ -228,7 +267,9 @@
         TContractVO res = new TContractVO();
         TContract contract = contractService.getById(id);
         BeanUtils.copyProperties(contract,res);
-        TContractRentType contractRentType = contractRentTypeService.lambdaQuery().eq(TContractRentType::getContractId, id).one();
+        TContractRentType contractRentType = contractRentTypeService.lambdaQuery()
+                .eq(TContractRentType::getContractId, id)
+                .one();
         if (contractRentType!=null){
             BeanUtils.copyProperties(contractRentType,res);
         }
@@ -248,8 +289,15 @@
         for (TBill tBill : list) {
             payMoney = payMoney.add(tBill.getOutstandingMoney()).add(tBill.getPayableFeesPenalty());
         }
-        TCheckAcceptRecord tCheckAcceptRecord = checkAcceptRecordService.lambdaQuery().eq(TCheckAcceptRecord::getContractId, id).one();
-        res.setCheckResult(Objects.nonNull(tCheckAcceptRecord)&&Objects.nonNull(tCheckAcceptRecord.getCheckResult())?tCheckAcceptRecord.getCheckResult():null);
+        TCheckAcceptRecord tCheckAcceptRecord = checkAcceptRecordService.lambdaQuery()
+                .eq(TCheckAcceptRecord::getContractId, id)
+                .one();
+        res.setCheckResult(
+                Objects.nonNull(tCheckAcceptRecord)
+                        &&Objects.nonNull(tCheckAcceptRecord.getCheckResult())
+                        ?tCheckAcceptRecord.getCheckResult()
+                        :null
+        );
         res.setPayMoney(payMoney);
 
         return R.ok(res);
@@ -271,7 +319,6 @@
     @Log(title = "合同管理-确认结算", businessType =  BusinessType.UPDATE)
     @ApiOperation(value = "确认结算")
     @PostMapping(value = "/confirmSettlement")
-
     public R<Boolean> confirmSettlement(String id) {
         TContract contract = contractService.getById(id);
         contract.setStatus("8");
@@ -279,11 +326,17 @@
         // 将所有未缴费账单设置未已失效
         List<TBill> tBills = billService.list(new LambdaQueryWrapper<TBill>()
                 .ne(TBill::getPayFeesStatus, 3)
+                        .ne(TBill::getBillType,4)
                 .eq(TBill::getContractId, contract.getId()));
         for (TBill tBill : tBills) {
             tBill.setPayFeesStatus("5");
         }
-        billService.updateBatchById(tBills);        return R.ok();
+        billService.updateBatchById(tBills);
+        // 将房屋改成待出租
+        THouse house = houseService.getById(contract.getHouseId());
+        house.setLeaseStatus("1");
+        houseService.updateById(house);
+        return R.ok();
     }
     @ApiOperation(value = "终止合同剩余未缴费账单列表")
     @PostMapping(value = "/contractBillList")
@@ -319,6 +372,18 @@
         return R.ok(res);
     }
 
+    // 计算两个日期相差天数的方法实现:
+    public static long calculateDaysBetween(LocalDateTime start, LocalDateTime end) {
+        return ChronoUnit.DAYS.between(start, end);
+    }
+
+    public static void main(String[] args) {
+        LocalDateTime start = LocalDateTime.of(2024, 1, 1, 0, 0);
+        LocalDateTime end = LocalDateTime.of(2024, 1, 5, 12, 0);
+        long days = calculateDaysBetween(start, end); // 返回4天(不满一天不计)
+
+    }
+
     private String generateContract(TContract contract) {
         String templateFileName = "1_yzj_租赁合同_个人.docx";
         String contractId = contract.getId();
@@ -328,7 +393,9 @@
         if (StringUtils.isNotEmpty(contractId)) {
             firstBill = billService.lambdaQuery()
                     .eq(TBill::getContractId, contractId)
-                    .orderByDesc(TBill::getStartTime)
+                    .eq(TBill::getBillType, 1)
+                    .orderByAsc(TBill::getStartTime)
+                    .ne(TBill::getManualAddition, DisabledEnum.YES.getCode())
                     .last("limit 1")
                     .one();
             tCheckAcceptRecord = checkAcceptRecordService.lambdaQuery()
@@ -347,7 +414,7 @@
         Map<String, Object> templateParam = new HashMap<>(5);
         fill(templateParam, "contractNumber", contract.getContractNumber());
         fill(templateParam, "partyOneName", contract.getPartyOneName());
-        fill(templateParam, "partyTwoName", contract.getPartyTwoName());
+
 
         if (Objects.nonNull(tenant)) {
             fill(templateParam, "mailAddress", tenant.getMailAddress());
@@ -355,6 +422,8 @@
             fill(templateParam, "residentName", tenant.getResidentName());
             fill(templateParam, "bankNumber", tenant.getBankNumber());
             fill(templateParam, "bankName", tenant.getBankName());
+            fill(templateParam, "partyTwoName", tenant.getLessee());
+            fill(templateParam, "email", tenant.getEmail());
 
             // 企业、政府机构、国有企业
             if (Objects.nonNull(tenant.getTenantType())
@@ -418,19 +487,27 @@
 
         // 首期租金处理
         if (firstBill != null) {
+            double firstRent = (contract.getPayType().equals("1")
+                    ? contract.getMonthRent()
+                    : contract.getPayType().equals("2")
+                    ? contract.getMonthRent().multiply(new BigDecimal("3"))
+                    : contract.getMonthRent().multiply(new BigDecimal("12")))
+                    .setScale(2, RoundingMode.DOWN).doubleValue();
             fill(templateParam, "firstRent", "¥" + firstBill.getPayableFeesMoney() + "元");
+            // 其他财务字段
+            fill(templateParam, "firstRentString", "人民币" + NumberToChineseUtils.numberToChinese(firstBill.getPayableFeesMoney().doubleValue()));
         } else {
-            fill(templateParam, "firstRent", "");
+//            fill(templateParam, "firstRent", "");
         }
 
-        // 其他财务字段
-        fill(templateParam, "firstRentString", "人民币" + NumberToChineseUtils.numberToChinese(
-                (contract.getPayType().equals("1")
+        fill(templateParam, "firstRent",
+                "¥"+(contract.getPayType().equals("1")
                         ? contract.getMonthRent()
-                        : contract.getPayType().equals("2")
-                        ? contract.getMonthRent().multiply(new BigDecimal("3"))
-                        : contract.getMonthRent().multiply(new BigDecimal("12")))
-                        .setScale(2, RoundingMode.DOWN).doubleValue()));
+                        :contract.getPayType().equals("2")
+                        ?contract.getMonthRent().multiply(new BigDecimal("3"))
+                        :contract.getMonthRent().multiply(new BigDecimal("12"))
+                        .setScale(2, RoundingMode.DOWN)).doubleValue()+"元");
+
 
         fill(templateParam, "firstRentString",
                 "人民币"+NumberToChineseUtils.numberToChinese(
@@ -476,7 +553,7 @@
         if (StringUtils.isEmpty(key)){
             throw new RuntimeException("key不能为空");
         }
-        templateParam.put(StringUtils.format("${{}}", "contractNumber"), value != null ? value : "");
+        templateParam.put("${"+key+"}", value != null ? value : "");
     }
 
     /**
@@ -498,10 +575,10 @@
     @PreAuthorize("@ss.hasPermi('contract:list:export')")
     @Log(title = "导出", businessType = BusinessType.EXPORT)
     @PostMapping("/export")
-    public void exportOpticalInspection(@RequestBody TContractQuery query)
-    {
+    public void exportOpticalInspection(@RequestBody TContractQuery query) throws UnsupportedEncodingException {
         List<ContractExport> contractExports = new ArrayList<>();
         List<TContract> exportList = contractService.contractExportList(query);
+
         for (TContract contract : exportList) {
             ContractExport contractExport = new ContractExport();
             contractExport.setContractNumber(contract.getContractNumber());
@@ -511,33 +588,61 @@
             contractExport.setCreateTime(DateUtils.localDateTimeToStringYear(contract.getCreateTime()));
             contractExport.setStartTime(DateUtils.localDateTimeToStringYear(contract.getStartTime()));
             contractExport.setEndTime(DateUtils.localDateTimeToStringYear(contract.getEndTime()));
-            contractExport.setPayType(DictUtils.getDictLabel(DictConstants.DICT_TYPE_CONTRACT_PAY_TYPE,contract.getPayType()));
-            contractExport.setDeposit(contract.getDeposit()+"");
-            contractExport.setStatus(DictUtils.getDictLabel(DictConstants.DICT_TYPE_CONTRACT_STATUS,contract.getStatus()));
+            contractExport.setDeposit(contract.getDeposit() + "");
             contractExports.add(contractExport);
+            contractExport.setPayType(
+                    DictUtils.getDictLabel(
+                            DictConstants.DICT_TYPE_CONTRACT_PAY_TYPE, contract.getPayType())
+            );
+            contractExport.setStatus(
+                    DictUtils.getDictLabel(DictConstants.DICT_TYPE_CONTRACT_STATUS, contract.getStatus()));
         }
-        Workbook workbook = ExcelExportUtil.exportExcel(new ExportParams(), ContractExport.class, contractExports);
+
         HttpServletResponse response = WebUtils.response();
         response.setContentType("application/vnd.ms-excel");
         response.setCharacterEncoding("utf-8");
-        ServletOutputStream outputStream = null;
-        try {
-            String fileName = URLEncoder.encode("合同列表.xls", "utf-8");
-            response.setHeader("Content-Disposition", "attachment;filename=" + fileName);
-            response.setContentType("application/vnd.ms-excel;charset=UTF-8");
-            response.setHeader("Pragma", "no-cache");
-            response.setHeader("Cache-Control", "no-cache");
-            outputStream = response.getOutputStream();
+        response.setHeader("Content-Disposition",
+                "attachment;filename=" + URLEncoder.encode("合同列表.xls", "utf-8"));
+        response.setHeader("Pragma", "no-cache");
+        response.setHeader("Cache-Control", "no-cache");
+
+        try (Workbook workbook = ExcelExportUtil.exportExcel(new ExportParams(), ContractExport.class, contractExports);
+             ServletOutputStream outputStream = response.getOutputStream()) {
             workbook.write(outputStream);
         } catch (IOException e) {
             e.printStackTrace();
-        } finally {
-            try {
-                outputStream.close();
-            } catch (IOException e) {
-                e.printStackTrace();
-            }
         }
     }
+    @ApiOperation("上传合同附件")
+    @PostMapping(value = "/upload-file")
+    public R<Boolean> uploadFile(@RequestBody TContractDTO dto ) {
+        if (Objects.isNull(dto.getId())) {
+            throw new ServiceException("合同id不能为空");
+        }
+        TContract contract = contractService.getById(dto.getId());
+        if (Objects.isNull(contract)) {
+            throw new ServiceException("合同不存在");
+        }
+  /*      if (StringUtils.isNotBlank(contract.getContractFile())) {
+            List<String> contractFileList = Arrays.stream(contract.getContractFile().split(",")).collect(Collectors.toList());
+            List<String> memoryList = Arrays.stream(contract.getMemory().split(",")).collect(Collectors.toList());
+            List<String> contractNameList = Arrays.stream(contract.getContractFileName().split(",")).collect(Collectors.toList());
+            contractFileList.addAll(Arrays.asList(dto.getContractFile().split(",")));
+            contractNameList.addAll(Arrays.asList(dto.getContractFileName().split(",")));
+            memoryList.addAll(Arrays.asList(dto.getMemory().split(",")));
+            contract.setContractFile(String.join(",", contractFileList));
+            contract.setContractFileName(String.join(",", contractNameList));
+            contract.setMemory(String.join(",", memoryList));
+        } else {
+            contract.setContractFile(dto.getContractFile());
+            contract.setContractFileName(dto.getContractFileName());
+            contract.setMemory(dto.getMemory());
+        }*/
+        contract.setContractFile(dto.getContractFile());
+        contract.setContractFileName(dto.getContractFileName());
+        contract.setMemory(dto.getMemory());
+        return R.ok(contractService.updateById(contract));
+    }
+
 }
 
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/THouseController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/THouseController.java
index f126710..3ff9bba 100644
--- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/THouseController.java
+++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/THouseController.java
@@ -1,6 +1,7 @@
 package com.ruoyi.web.controller.api;
 
 
+import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.ruoyi.common.annotation.Log;
 import com.ruoyi.common.basic.PageInfo;
 import com.ruoyi.common.constant.DictConstants;
@@ -77,7 +78,7 @@
     @ApiOperation(value = "获取房屋分页列表")
     @PostMapping(value = "/houseList")
     @PreAuthorize("@ss.hasPermi('house:list')")
-    public R<PageInfo<THouse>> houseList(@RequestBody THouseQuery query) {
+    public R<IPage<THouse>> houseList(@RequestBody THouseQuery query) {
         return R.ok(tHouseService.houseList(query));
     }
     @ApiOperation(value = "历史租户列表")
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TRentalReturnRecordController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TRentalReturnRecordController.java
new file mode 100644
index 0000000..9d9665d
--- /dev/null
+++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TRentalReturnRecordController.java
@@ -0,0 +1,79 @@
+package com.ruoyi.web.controller.api;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.ruoyi.common.core.controller.BaseController;
+import com.ruoyi.common.core.domain.R;
+import com.ruoyi.system.model.TRentalReturnRecord;
+import com.ruoyi.system.query.RentalReturnAuditQuery;
+import com.ruoyi.system.query.RentalReturnRecordQuery;
+import com.ruoyi.system.service.ITRentalReturnRecordService;
+import com.ruoyi.system.vo.RentalReturnRecordVO;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
+import lombok.RequiredArgsConstructor;
+import org.springframework.context.annotation.Lazy;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.*;
+
+@RestController
+@RequestMapping("/api/rentalReturnRecord")
+@RequiredArgsConstructor(onConstructor_ = {@Lazy})
+@Api(tags = {"房屋管理-退租申请"})
+public class TRentalReturnRecordController extends BaseController {
+    private final ITRentalReturnRecordService rentalReturnRecordService;
+
+    /**
+     * 申请记录列表
+     */
+    @ApiOperation(value = "申请记录列表")
+    @GetMapping("list")
+    @PreAuthorize("@ss.hasPermi('houseManage:apply:list')")
+    public R<IPage<RentalReturnRecordVO>> list(Page<RentalReturnRecordVO> page, RentalReturnRecordQuery query) {
+        return R.ok(rentalReturnRecordService.queryRentalReturnRecordList(page, query));
+    }
+
+    /**
+     * 审核记录删除
+     */
+    @ApiOperation(value = "审核记录删除")
+    @GetMapping("delete")
+    @PreAuthorize("@ss.hasPermi('houseManage:apply:delete')")
+    public R<String> delete(@ApiParam (value = "id") String id) {
+        boolean remove = rentalReturnRecordService.update(new LambdaUpdateWrapper<TRentalReturnRecord>()
+                .set(TRentalReturnRecord::getIsAdminDelete, true)
+                .eq(TRentalReturnRecord::getId, id)
+                .ne(TRentalReturnRecord::getAuditStatus, 1));
+        if (!remove){
+            return R.fail("删除失败");
+        }
+        return R.ok("删除成功");
+    }
+
+    /**
+     * 申请记录详情
+     */
+    @ApiOperation(value = "申请记录详情")
+    @GetMapping("detail")
+    @PreAuthorize("@ss.hasPermi('houseManage:apply:detail')")
+    public R<RentalReturnRecordVO> detail(@ApiParam (value = "id") String id) {
+        RentalReturnRecordVO rentalReturnRecordVO = rentalReturnRecordService.queryRentalReturnRecordById(id);
+        return R.ok(rentalReturnRecordVO);
+    }
+
+    /**
+     * 申请审核
+     */
+    @ApiOperation(value = "申请审核")
+    @PostMapping("audit")
+    @PreAuthorize("@ss.hasPermi('houseManage:apply:audit')")
+    public R<String> audit(@RequestBody RentalReturnAuditQuery returnAuditQuery) {
+        rentalReturnRecordService.audit(returnAuditQuery, getUserId(), getUsername());
+        return R.ok("审核成功");
+    }
+
+
+}
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TTenantController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TTenantController.java
index c1d5f10..d9dd9c7 100644
--- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TTenantController.java
+++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TTenantController.java
@@ -115,7 +115,10 @@
     @ApiOperation(value = "获取合同分页列表")
     @GetMapping(value = "/contractListByTenantId")
     public R<List<TContract>> contractListByTenantId(@RequestParam String tenantId) {
-        return R.ok(contractService.list(Wrappers.lambdaQuery(TContract.class).eq(TContract::getTenantId, tenantId)));
+        String businessDeptId = SecurityUtils.getBusinessDeptId();
+        return R.ok(contractService.list(Wrappers.lambdaQuery(TContract.class)
+                .eq(!businessDeptId.equals("0"), TContract::getBusinessDeptId, businessDeptId)
+                .eq(TContract::getTenantId, tenantId)));
     }
 
     /**
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/tool/WordTemplateProcessor.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/tool/WordTemplateProcessor.java
index 6b32fe3..f847008 100644
--- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/tool/WordTemplateProcessor.java
+++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/tool/WordTemplateProcessor.java
@@ -1,87 +1,87 @@
-package com.ruoyi.web.controller.tool;
-
-import org.apache.poi.xwpf.usermodel.*;
-import java.io.*;
-import java.util.*;
-
-public class WordTemplateProcessor {
-    
-    public static void fillTemplate(String templatePath, String outputPath,Map<String, String> dataMap) {
-        try {
-            // 读取模板文件
-            FileInputStream fis = new FileInputStream(templatePath);
-            XWPFDocument document = new XWPFDocument(fis);
-            
-            // 替换段落中的标记
-            for (XWPFParagraph paragraph : document.getParagraphs()) {
-                replaceParagraph(paragraph, dataMap);
-            }
-            
-            // 替换表格中的标记
-            for (XWPFTable table : document.getTables()) {
-                for (XWPFTableRow row : table.getRows()) {
-                    for (XWPFTableCell cell : row.getTableCells()) {
-                        for (XWPFParagraph paragraph : cell.getParagraphs()) {
-                            replaceParagraph(paragraph, dataMap);
-                        }
-                    }
-                }
-            }
-            
-            // 保存文件
-            FileOutputStream fos = new FileOutputStream(outputPath);
-            document.write(fos);
-            
-            // 关闭资源
-            fos.close();
-            fis.close();
-            document.close();
-            
-            System.out.println("模板填充完成!文件保存在: " + outputPath);
-            
-        } catch (Exception e) {
-            e.printStackTrace();
-        }
-    }
-    
-    private static void replaceParagraph(XWPFParagraph paragraph, Map<String, String> dataMap) {
-        String paragraphText = paragraph.getText();
-        for (Map.Entry<String, String> entry : dataMap.entrySet()) {
-            if (paragraphText.contains(entry.getKey())) {
-                List<XWPFRun> runs = paragraph.getRuns();
-                TextSegment found = paragraph.searchText(entry.getKey(), new PositionInParagraph());
-                if (found != null) {
-                    // 替换文本
-                    int beginRun = found.getBeginRun();
-                    int endRun = found.getEndRun();
-                    
-                    if (beginRun >= 0 && endRun >= 0) {
-                        // 删除原有runs
-                        for (int runPos = beginRun; runPos <= endRun; runPos++) {
-                            paragraph.removeRun(runPos);
-                        }
-                        // 创建新run
-                        XWPFRun newRun = paragraph.insertNewRun(beginRun);
-                        newRun.setText(entry.getValue());
-                        // 复制原有格式
-                        if (runs.size() > 0 && runs.get(0) != null) {
-                            XWPFRun styleRun = runs.get(0);
-                            newRun.setFontFamily(styleRun.getFontFamily());
-                            newRun.setFontSize(styleRun.getFontSize());
-                            newRun.setBold(styleRun.isBold());
-                            newRun.setItalic(styleRun.isItalic());
-                        }
-                    }
-                }
-            }
-        }
-    }
-    
-    public static void main(String[] args) {
-
-        String templatePath = "/path/to/template.docx";
-        String outputPath = "/path/to/output.docx";
-        
-//        fillTemplate(templatePath, outputPath, user);
-    }
-}
\ No newline at end of file
+//package com.ruoyi.web.controller.tool;
+//
+//import org.apache.poi.xwpf.usermodel.*;
+//import java.io.*;
+//import java.util.*;
+//
+//public class WordTemplateProcessor {
+//
+//    public static void fillTemplate(String templatePath, String outputPath,Map<String, String> dataMap) {
+//        try {
+//            // 读取模板文件
+//            FileInputStream fis = new FileInputStream(templatePath);
+//            XWPFDocument document = new XWPFDocument(fis);
+//
+//            // 替换段落中的标记
+//            for (XWPFParagraph paragraph : document.getParagraphs()) {
+//                replaceParagraph(paragraph, dataMap);
+//            }
+//
+//            // 替换表格中的标记
+//            for (XWPFTable table : document.getTables()) {
+//                for (XWPFTableRow row : table.getRows()) {
+//                    for (XWPFTableCell cell : row.getTableCells()) {
+//                        for (XWPFParagraph paragraph : cell.getParagraphs()) {
+//                            replaceParagraph(paragraph, dataMap);
+//                        }
+//                    }
+//                }
+//            }
+//
+//            // 保存文件
+//            FileOutputStream fos = new FileOutputStream(outputPath);
+//            document.write(fos);
+//
+//            // 关闭资源
+//            fos.close();
+//            fis.close();
+//            document.close();
+//
+//            System.out.println("模板填充完成!文件保存在: " + outputPath);
+//
+//        } catch (Exception e) {
+//            e.printStackTrace();
+//        }
+//    }
+//
+//    private static void replaceParagraph(XWPFParagraph paragraph, Map<String, String> dataMap) {
+//        String paragraphText = paragraph.getText();
+//        for (Map.Entry<String, String> entry : dataMap.entrySet()) {
+//            if (paragraphText.contains(entry.getKey())) {
+//                List<XWPFRun> runs = paragraph.getRuns();
+//                TextSegment found = paragraph.searchText(entry.getKey(), new PositionInParagraph());
+//                if (found != null) {
+//                    // 替换文本
+//                    int beginRun = found.getBeginRun();
+//                    int endRun = found.getEndRun();
+//
+//                    if (beginRun >= 0 && endRun >= 0) {
+//                        // 删除原有runs
+//                        for (int runPos = beginRun; runPos <= endRun; runPos++) {
+//                            paragraph.removeRun(runPos);
+//                        }
+//                        // 创建新run
+//                        XWPFRun newRun = paragraph.insertNewRun(beginRun);
+//                        newRun.setText(entry.getValue());
+//                        // 复制原有格式
+//                        if (runs.size() > 0 && runs.get(0) != null) {
+//                            XWPFRun styleRun = runs.get(0);
+//                            newRun.setFontFamily(styleRun.getFontFamily());
+//                            newRun.setFontSize(styleRun.getFontSize());
+//                            newRun.setBold(styleRun.isBold());
+//                            newRun.setItalic(styleRun.isItalic());
+//                        }
+//                    }
+//                }
+//            }
+//        }
+//    }
+//
+//    public static void main(String[] args) {
+//
+//        String templatePath = "/path/to/template.docx";
+//        String outputPath = "/path/to/output.docx";
+//
+////        fillTemplate(templatePath, outputPath, user);
+//    }
+//}
\ No newline at end of file
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/tool/WordUtil.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/tool/WordUtil.java
index 60d821a..e3153a8 100644
--- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/tool/WordUtil.java
+++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/tool/WordUtil.java
@@ -5,18 +5,31 @@
 import freemarker.template.Template;
 import freemarker.template.TemplateException;
 import lombok.extern.slf4j.Slf4j;
-
-import org.apache.poi.xwpf.usermodel.*;
+import org.apache.poi.xwpf.usermodel.UnderlinePatterns;
+import org.apache.poi.xwpf.usermodel.XWPFDocument;
+import org.apache.poi.xwpf.usermodel.XWPFParagraph;
+import org.apache.poi.xwpf.usermodel.XWPFRun;
+import org.apache.poi.xwpf.usermodel.XWPFTable;
+import org.apache.poi.xwpf.usermodel.XWPFTableCell;
+import org.apache.poi.xwpf.usermodel.XWPFTableRow;
 import org.springframework.mock.web.MockMultipartFile;
 import org.springframework.stereotype.Component;
 import org.springframework.web.multipart.MultipartFile;
 
 import javax.annotation.Resource;
-import javax.servlet.http.HttpServletResponse;
-import java.io.*;
-import java.net.URLEncoder;
-import java.nio.charset.StandardCharsets;
-import java.util.*;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.Writer;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
diff --git a/ruoyi-applet/src/main/java/com/ruoyi/web/controller/api/IndexController.java b/ruoyi-applet/src/main/java/com/ruoyi/web/controller/api/IndexController.java
index f41d87b..a8bcb1d 100644
--- a/ruoyi-applet/src/main/java/com/ruoyi/web/controller/api/IndexController.java
+++ b/ruoyi-applet/src/main/java/com/ruoyi/web/controller/api/IndexController.java
@@ -202,6 +202,7 @@
                 myToDoVO.setStartTime(DateUtils.localDateTimeToStringYear(contract.getStartTime()));
                 myToDoVO.setPropertyRightPerson(tHouse.getPropertyRightPerson());
                 myToDoVO.setPhone(tHouse.getPhone());
+                myToDoVO.setRentalReturnStatus(tHouse.getRentalReturnStatus() == null ? "1" : tHouse.getRentalReturnStatus());
                 List<TBill> billList = bills.stream().filter(e -> e.getContractId().equals(contract.getId())).collect(Collectors.toList());
                 List<PayListVO> payList = new ArrayList<>();
                 for (TBill tBill : billList) {
diff --git a/ruoyi-applet/src/main/java/com/ruoyi/web/controller/api/TBillController.java b/ruoyi-applet/src/main/java/com/ruoyi/web/controller/api/TBillController.java
index e0f5eb7..b9d8a9e 100644
--- a/ruoyi-applet/src/main/java/com/ruoyi/web/controller/api/TBillController.java
+++ b/ruoyi-applet/src/main/java/com/ruoyi/web/controller/api/TBillController.java
@@ -9,7 +9,6 @@
 import com.ruoyi.common.exception.ServiceException;
 import com.ruoyi.common.utils.CodeGenerateUtils;
 import com.ruoyi.common.utils.DictUtils;
-import com.ruoyi.common.utils.StringUtils;
 import com.ruoyi.framework.web.service.TokenService;
 import com.ruoyi.system.dto.BatchBillDTO;
 import com.ruoyi.system.dto.TBillDto;
@@ -22,12 +21,14 @@
 import io.swagger.annotations.ApiOperation;
 import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.util.StringUtils;
 import org.springframework.web.bind.annotation.*;
 
 import java.time.LocalDateTime;
 import java.time.temporal.ChronoUnit;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Objects;
 
 /**
  * <p>
@@ -129,17 +130,39 @@
     @PostMapping(value = "/invoice")
     public R<String> invoice(@RequestBody TInvoiceDTO dto) {
         String userId = tokenService.getLoginUserApplet().getUserId();
+        List<String> billIds = dto.getBillIds();
         dto.setApplyName(tenantService.getById(userId).getResidentName());
         String code;
         do {
             code = CodeGenerateUtils.generateVolumeSn();
         } while (invoiceService.count(Wrappers.lambdaQuery(TInvoice.class).eq(TInvoice::getInvoiceNumber, code)) > 0);
         dto.setInvoiceNumber(CodeGenerateUtils.generateVolumeSn());
+        String deptId = "";
+        List<TBill> list = tBillService.list(Wrappers.lambdaQuery(TBill.class).in(TBill::getId, billIds));
+        for (String billId : billIds) {
+            TBill tBill = list.stream().filter(bill -> bill.getId().equals(billId)).findFirst().orElse(null);
+            if(StringUtils.hasLength(deptId)){
+                if(Objects.nonNull(tBill)){
+                    if(!deptId.equals(tBill.getBusinessDeptId())){
+                        return R.fail("请选择同一运营部门账单开票");
+                    }else {
+                        deptId = tBill.getBusinessDeptId();
+                    }
+                }
+            }else {
+                if(Objects.nonNull(tBill)){
+                    deptId = tBill.getBusinessDeptId();
+                }else {
+                    return R.fail("请选择同一运营部门账单开票");
+                }
+            }
+        }
+        dto.setBusinessDeptId(deptId);
+
         // 添加开票信息
         invoiceService.save(dto);
 
         // 添加开票信息中间表信息
-        List<String> billIds = dto.getBillIds();
         List<TInvoiceToBill> sysInvoiceToBills = new ArrayList<>();
         for (String billId : billIds) {
             TInvoiceToBill tInvoiceToBill = new TInvoiceToBill();
diff --git a/ruoyi-applet/src/main/java/com/ruoyi/web/controller/api/TRentalReturnRecordController.java b/ruoyi-applet/src/main/java/com/ruoyi/web/controller/api/TRentalReturnRecordController.java
new file mode 100644
index 0000000..bdab3a9
--- /dev/null
+++ b/ruoyi-applet/src/main/java/com/ruoyi/web/controller/api/TRentalReturnRecordController.java
@@ -0,0 +1,57 @@
+package com.ruoyi.web.controller.api;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.ruoyi.common.core.controller.BaseController;
+import com.ruoyi.common.core.domain.R;
+import com.ruoyi.common.core.domain.model.LoginUserApplet;
+import com.ruoyi.framework.web.service.TokenService;
+import com.ruoyi.system.model.TContract;
+import com.ruoyi.system.model.TRentalReturnRecord;
+import com.ruoyi.system.service.ITRentalReturnRecordService;
+import com.ruoyi.system.service.TContractService;
+import com.ruoyi.system.vo.RentalRetureApplyVO;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
+import lombok.RequiredArgsConstructor;
+import org.springframework.context.annotation.Lazy;
+import org.springframework.web.bind.annotation.*;
+
+import java.time.LocalDateTime;
+
+@RestController
+@RequestMapping("/rentalReturnRecord")
+@RequiredArgsConstructor(onConstructor_ = {@Lazy})
+@Api(tags = {"房屋管理-退租申请"})
+public class TRentalReturnRecordController extends BaseController {
+    private final ITRentalReturnRecordService rentalReturnRecordService;
+    private final TokenService tokenService;
+
+    /**
+     * 申请退租
+     */
+    @ApiOperation(value = "申请退租")
+    @PostMapping("/apply")
+    public R<?> apply(@RequestBody RentalRetureApplyVO rentalReture) {
+        rentalReturnRecordService.apply(rentalReture, tokenService.getLoginUserApplet().getUserId());
+        return R.ok();
+    }
+
+    /**
+     * 申请详情
+     */
+    @ApiOperation(value = "申请详情")
+    @GetMapping("/detail")
+    public R<TRentalReturnRecord> detail(@ApiParam (value = "合同id") @RequestParam String contractId) {
+        TRentalReturnRecord rentalReturnRecord = rentalReturnRecordService.getOne(new LambdaQueryWrapper<TRentalReturnRecord>()
+                .eq(TRentalReturnRecord::getContractId, contractId)
+                .last("limit 1")
+                .orderByDesc(TRentalReturnRecord::getCreateTime));
+        if (rentalReturnRecord == null){
+            return R.fail("暂无申请记录");
+        }
+        TRentalReturnRecord detail = rentalReturnRecordService.getOne(new LambdaQueryWrapper<TRentalReturnRecord>()
+                .eq(TRentalReturnRecord::getId, rentalReturnRecord.getId()));
+        return R.ok(detail);
+    }
+}
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/CodeGenerateUtils.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/CodeGenerateUtils.java
index 76492bc..a75c51d 100644
--- a/ruoyi-common/src/main/java/com/ruoyi/common/utils/CodeGenerateUtils.java
+++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/CodeGenerateUtils.java
@@ -72,5 +72,24 @@
         timestampPart = timestampPart.substring(0, 0);
         return dateTime + timestampPart;
     }
+    /**
+     * @return
+     * @Description 生成统一支付单号  规则:年(2)月(2)日(2)时(2)分(2)+timestamp*5位随机整数取后5位
+     * @Author xiaochen
+     */
+    public static String generateVolumeSn(String code) {
+        Calendar calendar = Calendar.getInstance();
+        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMddhhmmss");
+        String dateTime = dateFormat.format(calendar.getTime());
+        dateTime = dateTime.substring(0,8);
+        String timestampPart = "" + (Math.random() * 10000) * (System.currentTimeMillis() / 10000);
+        timestampPart = timestampPart.replace(".", "").replace("E", "");
+        timestampPart = timestampPart.substring(0, 6);
+        return dateTime + code + timestampPart;
+    }
+
+    public static void main(String[] args) {
+        System.err.println(generateVolumeSn("2"));
+    }
 
 }
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/dto/TerminateContractDTO.java b/ruoyi-system/src/main/java/com/ruoyi/system/dto/TerminateContractDTO.java
index 351f424..ca20d5a 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/dto/TerminateContractDTO.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/dto/TerminateContractDTO.java
@@ -1,5 +1,6 @@
 package com.ruoyi.system.dto;
 
+import com.fasterxml.jackson.annotation.JsonFormat;
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
@@ -20,6 +21,7 @@
 
     @ApiModelProperty(value = "终止日期")
     @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
     private LocalDateTime terminateTime;
 
 }
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/mapper/TBillMapper.java b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/TBillMapper.java
index 2cdf39a..e0c85e5 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/mapper/TBillMapper.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/TBillMapper.java
@@ -10,6 +10,7 @@
 import org.apache.ibatis.annotations.Param;
 
 import java.math.BigDecimal;
+import java.util.Date;
 import java.util.List;
 
 /**
@@ -52,5 +53,11 @@
      * 街道租金排行
      * @return
      */
-    List<ScreenRentRankVO> getStreetRentRank();
+    List<ScreenRentRankVO> getStreetRentRank(@Param("businessDeptId") String businessDeptId);
+    /**
+     * 查询季付账单
+     * @param businessDeptId
+     * @return
+     */
+    List<TBill> getJiFuBillList(@Param("businessDeptId") String businessDeptId, @Param("first") Date first, @Param("last") Date last);
 }
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/mapper/TContractMapper.java b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/TContractMapper.java
index 178c3bd..6b77c06 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/mapper/TContractMapper.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/TContractMapper.java
@@ -35,7 +35,7 @@
      * 本月新增租户数
      * @return
      */
-    Integer getCurrentMonthRentCount();
+    Integer getCurrentMonthRentCount(@Param("businessDeptId") String businessDeptId);
 
     PageInfo<TContract> page(@Param("pageInfo") PageInfo<TContract> pageInfo,@Param("query") TContractQuery query);
 }
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/mapper/THouseMapper.java b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/THouseMapper.java
index 1cafeac..6828ec3 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/mapper/THouseMapper.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/THouseMapper.java
@@ -23,5 +23,10 @@
     List<THouse> houseList(@Param("req") THouseQuery query, @Param("pageInfo") PageInfo<THouse> pageInfo);
 
     List<HouseVO> userHistoryList(@Param("req")TUserHistoryQuery query, @Param("pageInfo")PageInfo<HouseVO> pageInfo);
-
+    /**
+     * 获取本季度已出租面积
+     * @param businessDeptId
+     * @return
+     */
+    Double getRentedArea(@Param("businessDeptId") String businessDeptId);
 }
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/mapper/TRentalReturnRecordMapper.java b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/TRentalReturnRecordMapper.java
new file mode 100644
index 0000000..a0ac99d
--- /dev/null
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/TRentalReturnRecordMapper.java
@@ -0,0 +1,18 @@
+package com.ruoyi.system.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.ruoyi.system.model.TRentalReturnRecord;
+import com.ruoyi.system.query.RentalReturnRecordQuery;
+import com.ruoyi.system.vo.RentalReturnRecordVO;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+public interface TRentalReturnRecordMapper extends BaseMapper<TRentalReturnRecord> {
+
+    IPage<RentalReturnRecordVO> queryRentalReturnRecordList(@Param("page") IPage<RentalReturnRecordVO> page,
+                                                           @Param("query") RentalReturnRecordQuery query);
+
+    RentalReturnRecordVO queryRentalReturnRecordById(@Param("id") String id);
+}
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/model/TBill.java b/ruoyi-system/src/main/java/com/ruoyi/system/model/TBill.java
index 2970b75..2ea41f2 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/model/TBill.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/model/TBill.java
@@ -1,24 +1,23 @@
 package com.ruoyi.system.model;
 
-import com.baomidou.mybatisplus.annotation.*;
-
-import java.math.BigDecimal;
-import java.time.LocalDate;
-import java.time.LocalDateTime;
-import java.io.Serializable;
-import java.util.Date;
-import java.util.List;
-
+import com.baomidou.mybatisplus.annotation.FieldFill;
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableLogic;
+import com.baomidou.mybatisplus.annotation.TableName;
 import com.fasterxml.jackson.annotation.JsonFormat;
 import com.fasterxml.jackson.annotation.JsonIgnore;
-import com.ruoyi.common.core.domain.BaseModel;
-import com.ruoyi.common.core.domain.BasePage;
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
 import lombok.EqualsAndHashCode;
-import org.springframework.data.annotation.Transient;
-import springfox.documentation.annotations.ApiIgnore;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.util.Date;
 
 /**
  * <p>
@@ -184,6 +183,12 @@
     @TableField(exist = false)
     private BigDecimal preOutstand;
 
+    @ApiModelProperty(value = "是否管理后台添加 1=是 0=否 用于生成合同附件时过滤管理后台添加的账单,查询首个账单")
+    @TableField("is_manual_addition")
+    private Integer manualAddition;
+
+
+
 
 
 
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/model/TContract.java b/ruoyi-system/src/main/java/com/ruoyi/system/model/TContract.java
index d36bc2b..254c8f9 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/model/TContract.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/model/TContract.java
@@ -11,7 +11,6 @@
 import lombok.Data;
 import lombok.EqualsAndHashCode;
 
-import javax.validation.constraints.NotBlank;
 import java.math.BigDecimal;
 import java.time.LocalDateTime;
 
@@ -126,7 +125,6 @@
 
     @ApiModelProperty(value = "合同附件,多个逗号拼接")
     @TableField("contract_file")
-    @NotBlank(message = "合同附件不能为空")
     private String contractFile;
 
     @ApiModelProperty(value = "备注")
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/model/TFaultRepairMessage.java b/ruoyi-system/src/main/java/com/ruoyi/system/model/TFaultRepairMessage.java
index ea3d9ec..22979e3 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/model/TFaultRepairMessage.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/model/TFaultRepairMessage.java
@@ -119,4 +119,8 @@
     @TableField("status")
     private Integer status;
 
+    @ApiModelProperty(value = "故障因素: 1-人为因素 2-市政因素")
+    @TableField("fault_cause")
+    private Integer faultCause;
+
 }
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/model/THouse.java b/ruoyi-system/src/main/java/com/ruoyi/system/model/THouse.java
index 7960382..9e35655 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/model/THouse.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/model/THouse.java
@@ -81,6 +81,11 @@
     @ApiModelProperty(value = "租赁状态 1=待出租 2=已出租 3=维修中")
     @TableField("lease_status")
     private String leaseStatus;
+
+    @ApiModelProperty(value = "退租状态 1=未退租 2=退租申请中 3=已退租")
+    @TableField("rental_return_status")
+    private String rentalReturnStatus;
+
     @ApiModelProperty(value = "楼栋")
     @TableField("building")
     private String building;
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/model/TRentalReturnRecord.java b/ruoyi-system/src/main/java/com/ruoyi/system/model/TRentalReturnRecord.java
new file mode 100644
index 0000000..0484623
--- /dev/null
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/model/TRentalReturnRecord.java
@@ -0,0 +1,85 @@
+package com.ruoyi.system.model;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.ruoyi.common.core.domain.BaseModel;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.time.LocalDateTime;
+
+@EqualsAndHashCode(callSuper = true)
+@Data
+@TableName("t_rental_return_record")
+@ApiModel("退租记录")
+public class TRentalReturnRecord extends BaseModel {
+    private static final long serialVersionUID = 1L;
+
+    @TableId(value = "id", type = IdType.ASSIGN_ID)
+    @ApiModelProperty(value = "退租记录id")
+    private String id;
+
+    /**
+     * 租户id
+     */
+    @ApiModelProperty(value = "租户id")
+    private String tenantId;
+
+    /**
+     * 房屋id
+     */
+    @ApiModelProperty(value = "房屋id")
+    private String houseId;
+
+    /**
+     * 合同id
+     */
+    @ApiModelProperty(value = "合同id")
+    private String contractId;
+
+    /**
+     * 图片
+     */
+    @ApiModelProperty(value = "图片")
+    private String images;
+
+
+    /**
+     * 退租说明
+     */
+    @ApiModelProperty(value = "退租说明")
+    private String reasonForReturn;
+
+    /**
+     * 审批意见
+     */
+    @ApiModelProperty(value = "审批意见")
+    private String auditOpinion;
+
+    /**
+     * 审批时间
+     */
+    @ApiModelProperty(value = "审批时间")
+    private LocalDateTime auditTime;
+
+    /**
+     * 审批状态: 1-待审核 2-审核通过 3-审核驳回
+     */
+    @ApiModelProperty(value = "审批状态: 1-待审核 2-审核通过 3-审核驳回")
+    private Integer auditStatus;
+
+    /**
+     * 审批人id
+     */
+    @ApiModelProperty(value = "审批人id")
+    private Long auditUserId;
+
+    /**
+     * 管理后台删除标识
+     */
+    @ApiModelProperty(value = "管理后台删除标识")
+    private Boolean isAdminDelete;
+}
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/model/TTenant.java b/ruoyi-system/src/main/java/com/ruoyi/system/model/TTenant.java
index afa3846..31150c5 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/model/TTenant.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/model/TTenant.java
@@ -100,4 +100,8 @@
     @TableField("bank_name")
     private String bankName;
 
+    @ApiModelProperty(value = "承租人")
+    @TableField("lessee")
+    private String lessee;
+
 }
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/query/RentalReturnAuditQuery.java b/ruoyi-system/src/main/java/com/ruoyi/system/query/RentalReturnAuditQuery.java
new file mode 100644
index 0000000..23242fe
--- /dev/null
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/query/RentalReturnAuditQuery.java
@@ -0,0 +1,27 @@
+package com.ruoyi.system.query;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+@Data
+@ApiModel("退租审核查询")
+public class RentalReturnAuditQuery {
+    /**
+     * id
+     */
+    @ApiModelProperty(value = "id")
+    private String id;
+
+    /**
+     * 审核结果:2-审核通过 3-审核驳回
+     */
+    @ApiModelProperty(value = "审核结果:2-审核通过 3-审核驳回")
+    private Integer auditResult;
+
+    /**
+     * 审核意见
+     */
+    @ApiModelProperty(value = "审核意见")
+    private String auditOpinion;
+}
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/query/RentalReturnRecordQuery.java b/ruoyi-system/src/main/java/com/ruoyi/system/query/RentalReturnRecordQuery.java
new file mode 100644
index 0000000..81ca557
--- /dev/null
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/query/RentalReturnRecordQuery.java
@@ -0,0 +1,51 @@
+package com.ruoyi.system.query;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.time.LocalDateTime;
+
+@Data
+@ApiModel("退租记录查询")
+public class RentalReturnRecordQuery {
+    /**
+     * 申请开始日期
+     */
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @ApiModelProperty(value = "申请开始日期")
+    private LocalDateTime startDate;
+
+    /**
+     * 申请结束日期
+     */
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @ApiModelProperty(value = "申请结束日期")
+    private LocalDateTime endDate;
+
+    /**
+     * 房屋名称
+     */
+    @ApiModelProperty(value = "房屋名称")
+    private String houseName;
+
+    /**
+     * 合同编号
+     */
+    @ApiModelProperty(value = "合同编号")
+    private String contractNumber;
+
+    /**
+     * 提交人
+     */
+    @ApiModelProperty(value = "提交人")
+    private String submitter;
+
+    private String businessDeptId;
+
+    private Boolean isAdminDelete;
+}
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/ITRentalReturnRecordService.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/ITRentalReturnRecordService.java
new file mode 100644
index 0000000..64eb4c9
--- /dev/null
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/ITRentalReturnRecordService.java
@@ -0,0 +1,21 @@
+package com.ruoyi.system.service;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.ruoyi.system.model.TRentalReturnRecord;
+import com.ruoyi.system.query.RentalReturnAuditQuery;
+import com.ruoyi.system.query.RentalReturnRecordQuery;
+import com.ruoyi.system.vo.RentalRetureApplyVO;
+import com.ruoyi.system.vo.RentalReturnRecordVO;
+
+public interface ITRentalReturnRecordService extends IService<TRentalReturnRecord> {
+
+    IPage<RentalReturnRecordVO> queryRentalReturnRecordList(Page<RentalReturnRecordVO> page, RentalReturnRecordQuery query);
+
+    RentalReturnRecordVO queryRentalReturnRecordById(String id);
+
+    void apply(RentalRetureApplyVO rentalReture,String tenantId);
+
+    void audit(RentalReturnAuditQuery returnAuditQuery, Long userId, String userName);
+}
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/TBillService.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/TBillService.java
index b0028c7..619dd06 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/service/TBillService.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/TBillService.java
@@ -15,6 +15,7 @@
 
 import javax.validation.constraints.NotEmpty;
 import java.math.BigDecimal;
+import java.util.Date;
 import java.util.List;
 import java.util.function.Consumer;
 
@@ -98,6 +99,23 @@
      * 查询街道租金排行
      * @return
      */
+    List<ScreenRentRankVO> getStreetRentRank(String businessDeptId);
+
+    /**
+     * 查询季付账单
+     * @param businessDeptId
+     * @return
+     */
+    List<TBill> getJiFuBillList(String businessDeptId);
+
+    /**
+     * 查询当前季度的季付账单
+     * @param businessDeptId
+     * @param first
+     * @param last
+     * @return
+     */
+    List<TBill> getJiFuBillListByTime(String businessDeptId, Date first, Date last);
     List<ScreenRentRankVO> getStreetRentRank();
 
     void editAmount(TbillSaveDto bill);
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/TContractService.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/TContractService.java
index 43b7c9d..76018de 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/service/TContractService.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/TContractService.java
@@ -11,6 +11,7 @@
 import com.ruoyi.system.query.TContractQuery;
 import com.ruoyi.system.vo.BillVO;
 import com.ruoyi.system.vo.CheckAcceptRecordVO;
+import com.ruoyi.system.vo.ScreenRentIncomeTrendVO;
 
 import java.util.List;
 
@@ -47,7 +48,6 @@
      * 本月新增租户数
      * @return
      */
-    Integer getCurrentMonthRentCount();
-
+    Integer getCurrentMonthRentCount(String businessDeptId);
     PageInfo<TContract> queryPage(TContractQuery query);
 }
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/THouseService.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/THouseService.java
index c68346c..42370d1 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/service/THouseService.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/THouseService.java
@@ -20,4 +20,11 @@
     PageInfo<THouse> houseList(THouseQuery query);
 
     PageInfo<HouseVO> userHistoryList(TUserHistoryQuery query);
+
+    /**
+     * 获取本季度已出租面积
+     * @param businessDeptId
+     * @return
+     */
+    Double getRentedArea(String businessDeptId);
 }
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/FlowListenerService.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/FlowListenerService.java
index a18f96b..52f1852 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/FlowListenerService.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/FlowListenerService.java
@@ -91,19 +91,22 @@
     private final THouseService houseService;
 
     public static void main(String[] args) {
-        LocalDate localDate1 = LocalDate.now().withYear(2025).withMonth(1).withDayOfMonth(31);
-        System.err.println(localDate1.plusMonths(1));
+//        LocalDate localDate1 = LocalDate.now().withYear(2025).withMonth(2).withDayOfMonth(10).with;
+//        System.err.println(localDate1.plusMonths(1));
 
 ////        LocalDate localDate2 = LocalDate.now().withYear(2025).withMonth(4).withDayOfMonth(16);
-//        LocalDateTime localDate1 = LocalDateTime.now().withYear(2025).withMonth(4).withDayOfMonth(16);
-//        LocalDateTime localDate2 = LocalDateTime.now().withYear(2025).withMonth(10).withDayOfMonth(24);
-//
+//        LocalDateTime localDate1 = LocalDateTime.now().withYear(2025).withMonth(2).withDayOfMonth(10).withHour(00).withMinute(00).withSecond(00);
+//        LocalDateTime localDate2 = LocalDateTime.now().withYear(2025).withMonth(3).withDayOfMonth(31).withHour(00).withMinute(00).withSecond(00);
+//        LocalDateTime with = localDate1.plusMonths(1).with(TemporalAdjusters.lastDayOfMonth());
+//        boolean before = with.isBefore(localDate2);
+//        System.err.println(before);
 //        long between = ChronoUnit.DAYS.between(localDate1, localDate2)+1;
-        int monthValue = LocalDateTime.now().getMonthValue();
-         LocalDateTime.now();
-         LocalDateTime.now();
-
-        System.err.println(LocalDateTime.now().isBefore(LocalDateTime.now()));
+//        int monthValue = LocalDateTime.now().getMonthValue();
+//         LocalDateTime.now();
+//         LocalDateTime.now();
+        int dayOfMonth = LocalDateTime.now().getMonthValue();
+        System.err.println(dayOfMonth);
+//        System.err.println(LocalDateTime.now().isBefore(LocalDateTime.now()));
     }
 
     @Override
@@ -269,6 +272,7 @@
     }
 
 
+
     /**
      * 业务状态变更
      */
@@ -303,6 +307,7 @@
                     TContractRentType tContractRentType = contractRentTypes.stream().filter(e -> e.getContractId().equals(contract.getId())).findFirst().orElse(null);
                     // 生成第一笔账单
                     // 第一次应缴费日期
+
                     LocalDateTime firstPayTime = contract.getStartTime().plusDays(10).withHour(0).withMinute(0).withSecond(0);
                     TBill rentBill = new TBill();
                     rentBill.setContractId(contract.getId());
@@ -424,22 +429,41 @@
                             // 第一个月计算天
                             int dayOfMonth = rentBill.getStartTime().getDayOfMonth();
                             if (dayOfMonth == 1) {
+                                System.err.println("第一笔账单 1号计算整月:");
                                 money = money.add(contract.getMonthRent());
                             } else {
-                                long allDays = ChronoUnit.DAYS.between(contract.getStartPayTime(), contract.getStartPayTime().with(TemporalAdjusters.lastDayOfMonth())) + 1;
+                                long allDays = Math.abs(ChronoUnit.DAYS.between(rentBill.getStartTime(), rentBill.getStartTime().with(TemporalAdjusters.lastDayOfMonth())) + 1);
+                                System.err.println("第一笔账单 计算天数"+allDays);
                                 money =money.add(contract.getMonthRent().divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(allDays)));
+                                System.err.println("第一笔账单 计算天数金额"+money);
                             }
                             // 后续
                             if (contract.getStartPayTime().getMonthValue()==3||contract.getStartPayTime().getMonthValue()==6||contract.getStartPayTime().getMonthValue()==9||contract.getStartPayTime().getMonthValue()==12){
+                                System.err.println("后续账单 月为3 6 9 12金额"+money);
                                 rentBill.setPayableFeesMoney(money);
                                 rentBill.setOutstandingMoney(rentBill.getPayableFeesMoney());
                             }else{
+
                                 LocalDateTime localDateTime = rentBill.getStartTime().plusMonths(1).with(TemporalAdjusters.lastDayOfMonth());
+                                System.err.println("后续账单逻辑时间"+localDateTime);
                                 while (true){
-                                    if (localDateTime.isBefore(rentBill.getEndTime())){
+                                    if (localDateTime.toLocalDate().isBefore(rentBill.getEndTime().toLocalDate())){
+                                        System.err.println("后续while 在结束之前");
                                         money = money.add(contract.getMonthRent());
-                                    }else{
-                                        money = money.add(contract.getMonthRent().divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(ChronoUnit.DAYS.between(rentBill.getEndTime(),localDateTime.with(TemporalAdjusters.firstDayOfMonth()))+1)));
+                                    }else if(localDateTime.toLocalDate().equals(rentBill.getEndTime().toLocalDate())){
+                                        System.err.println("后续while 结束");
+                                        money = money.add(contract.getMonthRent());
+                                        break;
+                                    }else {
+                                        System.err.println("后续while 加一个月大于结束时间");
+                                        if (localDateTime.with(TemporalAdjusters.firstDayOfMonth()).isBefore(rentBill.getEndTime())){
+                                            long a = ChronoUnit.DAYS.between(localDateTime.with(TemporalAdjusters.firstDayOfMonth()),rentBill.getEndTime())+1;
+                                            System.err.println("后续while 加一个月大于结束时间 计算天数"+a);
+                                            money = money.add(contract.getMonthRent().divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(
+                                                    new BigDecimal(ChronoUnit.DAYS.between(localDateTime.with(TemporalAdjusters.firstDayOfMonth()),rentBill.getEndTime())+1))
+                                            );
+                                        }
+
                                         break;
                                     }
                                     localDateTime = localDateTime.plusMonths(1).with(TemporalAdjusters.lastDayOfMonth());
@@ -502,6 +526,8 @@
 
                     depositBill.setBillType("2");
                     contractService.updateById(contract);
+                    rentBill.setBusinessDeptId(contract.getBusinessDeptId());
+                    depositBill.setBusinessDeptId(contract.getBusinessDeptId());
                     billService.save(rentBill);
                     billService.save(depositBill);
                     // 生成后续账单
@@ -721,6 +747,7 @@
                                 tBill.setContractNumber(contract.getContractNumber());
                                 tBill.setPayFeesStatus("1");
                                 tBill.setBillType("1");
+                                tBill.setBusinessDeptId(contract.getBusinessDeptId());
 
                                 billService.save(tBill);
                                 beforeBill.setEndTime(beforeBill.getEndTime().plusMonths(contract.getPayType().equals("1") ? 1 : contract.getPayType().equals("2") ? 3 : 12).with(TemporalAdjusters.lastDayOfMonth()));
@@ -929,10 +956,16 @@
                                 BigDecimal originalMoney = new BigDecimal("0");
                                 // 不需要涨租金的时间段
                                 long originalDays = 0;
-                                if (tBill.getStartTime().with(TemporalAdjusters.lastDayOfMonth()).isBefore(tBill.getEndTime())){
-                                    originalDays = Math.abs(ChronoUnit.DAYS.between(tBill.getStartTime(), tBill.getStartTime().with(TemporalAdjusters.lastDayOfMonth())));
+                                if (tBill.getStartTime().getDayOfMonth()==1&&(tBill.getStartTime().with(TemporalAdjusters.lastDayOfMonth()).toLocalDate().isAfter(tBill.getEndTime().toLocalDate())||tBill.getStartTime().with(TemporalAdjusters.lastDayOfMonth()).toLocalDate().equals(tBill.getEndTime().toLocalDate()))){
+                                    // 计算整月
+                                    originalMoney = originalMoney.add(contract.getChangeRent());
                                 }else{
-                                    originalDays = Math.abs(ChronoUnit.DAYS.between(tBill.getStartTime(), tBill.getEndTime()));
+                                    // 计算天
+                                    if (tBill.getStartTime().with(TemporalAdjusters.lastDayOfMonth()).isBefore(tBill.getEndTime())){
+                                        originalDays = Math.abs(ChronoUnit.DAYS.between(tBill.getStartTime(), tBill.getStartTime().with(TemporalAdjusters.lastDayOfMonth())))+1;
+                                    }else{
+                                        originalDays = Math.abs(ChronoUnit.DAYS.between(tBill.getStartTime(), tBill.getEndTime()))+1;
+                                    }
                                 }
                                 originalMoney = originalMoney.add(contract.getChangeRent().divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(originalDays)));
                                 LocalDateTime originalTime = tBill.getStartTime().with(TemporalAdjusters.lastDayOfMonth()).plusDays(1);
@@ -957,12 +990,24 @@
                             BigDecimal originalMoney = new BigDecimal("0");
                             // 不需要涨租金的时间段
                             long originalDays = 0;
-                            if (tBill.getStartTime().with(TemporalAdjusters.lastDayOfMonth()).isBefore(tBill.getEndTime())){
-                                originalDays = Math.abs(ChronoUnit.DAYS.between(tBill.getStartTime(), tBill.getStartTime().with(TemporalAdjusters.lastDayOfMonth())))+1;
+                            if (tBill.getStartTime().getDayOfMonth()==1
+                                    &&
+                                    (
+                                            tBill.getStartTime().with(TemporalAdjusters.lastDayOfMonth()).toLocalDate().isBefore(tBill.getEndTime().toLocalDate())
+                                            ||tBill.getStartTime().with(TemporalAdjusters.lastDayOfMonth()).toLocalDate().equals(tBill.getEndTime().toLocalDate())
+                                    )
+                            ){
+                                // 计算整月
+                                originalMoney = originalMoney.add(contract.getChangeRent());
                             }else{
-                                originalDays = Math.abs(ChronoUnit.DAYS.between(tBill.getStartTime(), tBill.getEndTime()))+1;
+                                // 计算天
+                                if (tBill.getStartTime().with(TemporalAdjusters.lastDayOfMonth()).isBefore(tBill.getEndTime())){
+                                    originalDays = Math.abs(ChronoUnit.DAYS.between(tBill.getStartTime(), tBill.getStartTime().with(TemporalAdjusters.lastDayOfMonth())))+1;
+                                }else{
+                                    originalDays = Math.abs(ChronoUnit.DAYS.between(tBill.getStartTime(), tBill.getEndTime()))+1;
+                                }
+                                originalMoney = originalMoney.add(contract.getChangeRent().divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(originalDays)));
                             }
-                            originalMoney = originalMoney.add(contract.getChangeRent().divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(originalDays)));
                             LocalDateTime originalTime = tBill.getStartTime().with(TemporalAdjusters.lastDayOfMonth()).plusDays(1);
                             while(true){
                                 if (originalTime.isBefore(tBill.getEndTime())){
@@ -976,21 +1021,22 @@
                                     break;
                                 }
                             }
-                            if (originalTime.isBefore(tBill.getEndTime())){
-                                long tempOriginal  = ChronoUnit.DAYS.between(originalTime,tBill.getEndTime());
+                            if (originalTime.isBefore(tBill.getEndTime())||originalTime.toLocalDate().equals(tBill.getEndTime().toLocalDate())){
+                                long tempOriginal  = ChronoUnit.DAYS.between(originalTime,tBill.getEndTime())+1;
                                 originalMoney = originalMoney.add(contract.getChangeRent().divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(tempOriginal)));
                             }
                             tBill.setPayableFeesMoney(originalMoney);
                             tBill.setOutstandingMoney(tBill.getPayableFeesMoney());
                         }
-                        if (tBill.getEndTime().getDayOfMonth() >= 15) {
+//                        if (tBill.getEndTime().getDayOfMonth() >= 15) {
+//                            tBill.setPayableFeesTime(tBill.getStartTime().withDayOfMonth(15).toLocalDate());
+//                        } else if (tBill.getStartTime().getYear() == tBill.getEndTime().getYear() && tBill.getStartTime().getMonthValue() == tBill.getEndTime().getMonthValue()) {
+//                            // 如果同年同月 且日小于15 缴费时间取合同
+//                            tBill.setPayableFeesTime(tBill.getStartTime().toLocalDate());
+//                        } else {
                             tBill.setPayableFeesTime(tBill.getStartTime().withDayOfMonth(15).toLocalDate());
-                        } else if (tBill.getStartTime().getYear() == tBill.getEndTime().getYear() && tBill.getStartTime().getMonthValue() == tBill.getEndTime().getMonthValue()) {
-                            // 如果同年同月 且日小于15 缴费时间取合同
-                            tBill.setPayableFeesTime(tBill.getStartTime().toLocalDate());
-                        } else {
-                            tBill.setPayableFeesTime(tBill.getStartTime().withDayOfMonth(15).toLocalDate());
-                        }
+//                        }
+                        tBill.setBusinessDeptId(contract.getBusinessDeptId());
                         billService.save(tBill);
                     }
                 }
@@ -998,13 +1044,17 @@
             }
             case CATEGORY3: {
                 // 合同提前终止审批
-                int submitStatus = status == 0 ? 4 : (status == 1 ? 7 : 5);
+                int submitStatus = status == 0 ? 4 : (status == 1 ? 7 : 4);
                 contractService.updateContractAuditStatus(processParameter.getString("projectId"), submitStatus);
                 // 生成验收记录
                 TContract contract = contractService.getById(processParameter.getString("projectId"));
                 //更新合同结束时间
                 contract.setEndTime(contract.getTerminateTime());
                 contractService.updateById(contract);
+                // 修改房屋状态
+                THouse house = houseService.getById(contract.getHouseId());
+                house.setLeaseStatus("1");
+                houseService.updateById(house);
 
                 TCheckAcceptRecord tCheckAcceptRecord = new TCheckAcceptRecord();
                 tCheckAcceptRecord.setContractId(contract.getId());
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/ScreenService.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/ScreenService.java
index 084db02..07e1869 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/ScreenService.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/ScreenService.java
@@ -1,6 +1,9 @@
 package com.ruoyi.system.service.impl;
 
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.ruoyi.common.core.domain.R;
 import com.ruoyi.common.utils.DateUtils;
+import com.ruoyi.common.utils.SecurityUtils;
 import com.ruoyi.system.model.TBill;
 import com.ruoyi.system.model.TContract;
 import com.ruoyi.system.model.THouse;
@@ -10,6 +13,7 @@
 import com.ruoyi.system.vo.ScreenRentIncomeTrendVO;
 import com.ruoyi.system.vo.ScreenRentRankVO;
 import com.ruoyi.system.vo.ScreenTopStaticsDataVO;
+import com.ruoyi.system.vo.TenantCountTrendVO;
 import lombok.RequiredArgsConstructor;
 import org.springframework.context.annotation.Lazy;
 import org.springframework.stereotype.Service;
@@ -33,57 +37,81 @@
     private final THouseService tHouseService;
     private final TContractService tContractService;
     private final TBillService tBillService;
+    private final TContractService contractService;
     /**
      * 获取顶部统计数据
      * @return
      */
     public ScreenTopStaticsDataVO getTopStaticsData() {
-        ScreenTopStaticsDataVO vo = new ScreenTopStaticsDataVO();
-        //房屋总面积
-        List<THouse> houseList = tHouseService.list();
-        Double totalArea = houseList.stream().map(item -> Double.parseDouble(item.getHouseArea())).reduce(0D, Double::sum);
-        vo.setHouseTotalArea(totalArea);
-        //已出租面积
-        Double totalRentedArea = houseList.stream().filter(item -> !item.getLeaseStatus().equals("1"))
-                .map(item -> Double.parseDouble(item.getHouseArea())).reduce(0D, Double::sum);
-        vo.setHouseRentedArea(totalRentedArea);
-        //总计应收租金
-        List<TBill> billList = tBillService.list();
-        BigDecimal totalReceivableRent = billList.stream().filter(item -> !item.getPayFeesStatus().equals("5"))
-                .map(TBill::getPayableFeesMoney).reduce(BigDecimal.ZERO, BigDecimal::add);
-        vo.setTotalReceivableRent(totalReceivableRent);
-        //总计已收租金
-        BigDecimal totalReceivedRent = billList.stream().map(TBill::getPayFeesMoney).reduce(BigDecimal.ZERO, BigDecimal::add);
-        vo.setTotalReceivedRent(totalReceivedRent);
-        //本月新增租户数
-        Integer newTenantCount = tContractService.getCurrentMonthRentCount();
-        vo.setNewTenantCount(newTenantCount);
-        //总计租户数 系统租户列表里有生效合同绑定的租户总数。
-        Long count = tContractService.lambdaQuery().in(TContract::getStatus, "4", "5", "6", "7", "8", "9").groupBy(TContract::getTenantId).count();
-        vo.setTotalTenantCount(count.intValue());
+        String businessDeptId = SecurityUtils.getBusinessDeptId();
         Map<String, Date> quarterDate = DateUtils.getQuarterDate(new Date());
         Date first = quarterDate.get("first");
         Date last = quarterDate.get("last");
-        List<TBill> currentQuarterBillList = tBillService.lambdaQuery().between(TBill::getPayableFeesTime, first, last).list();
+        ScreenTopStaticsDataVO vo = new ScreenTopStaticsDataVO();
+        //房屋总面积
+        List<THouse> houseList = tHouseService.lambdaQuery()
+                .eq(!businessDeptId.equals("0"), THouse::getBusinessDeptId, businessDeptId)
+                .list();
+        Double totalArea = houseList.stream()
+                .map(item -> Double.parseDouble(item.getHouseArea()))
+                .reduce(0D, Double::sum);
+        vo.setHouseTotalArea(totalArea);
+        //已出租面积
+        Double totalRentedArea =  tHouseService.getRentedArea(businessDeptId);
+        vo.setHouseRentedArea(totalRentedArea);
+        //总计应收租金
+        List<TBill> billList = tBillService.getJiFuBillList(businessDeptId);
+        BigDecimal totalReceivableRent = billList.stream()
+                .filter(item -> !item.getPayFeesStatus().equals("5"))
+                .map(TBill::getPayableFeesMoney)
+                .reduce(BigDecimal.ZERO, BigDecimal::add)
+                .divide(new BigDecimal("10000"),2, RoundingMode.DOWN);
+        vo.setTotalReceivableRent(totalReceivableRent);
+        //总计已收租金
+        BigDecimal totalReceivedRent = billList.stream()
+                .map(TBill::getPayFeesMoney)
+                .reduce(BigDecimal.ZERO, BigDecimal::add)
+                .divide(new BigDecimal("10000"),2, RoundingMode.DOWN);
+        vo.setTotalReceivedRent(totalReceivedRent);
+        //本月新增租户数
+        Integer newTenantCount = tContractService.getCurrentMonthRentCount(businessDeptId);
+        vo.setNewTenantCount(newTenantCount);
+        //总计租户数 系统租户列表里有生效合同绑定的租户总数。
+        List<TContract> tContracts = tContractService.lambdaQuery()
+                .eq(TContract::getPayType,2) //季付
+                .in(TContract::getStatus, "4", "5", "6", "7", "8", "9")
+                .eq(!businessDeptId.equals("0"), TContract::getBusinessDeptId, businessDeptId)
+                .list();
+        long count = tContracts.stream()
+                .map(TContract::getTenantId)
+                .distinct()
+                .count();
+        vo.setTotalTenantCount((int) count);
+        List<TBill> currentQuarterBillList = tBillService.getJiFuBillListByTime(businessDeptId, first, last);
         //本季度已交租金
-        BigDecimal totalRentPaid = currentQuarterBillList.stream().map(TBill::getPayFeesMoney).reduce(BigDecimal.ZERO, BigDecimal::add);
+        BigDecimal totalRentPaid = currentQuarterBillList.stream()
+                .map(TBill::getPayFeesMoney)
+                .reduce(BigDecimal.ZERO, BigDecimal::add)
+                .divide(new BigDecimal("10000"),2, RoundingMode.DOWN);
         vo.setTotalRentPaid(totalRentPaid);
         //本季度应交租金
-        BigDecimal totalRentShould = currentQuarterBillList.stream().filter(item -> !item.getPayFeesStatus().equals("5"))
-                .map(TBill::getPayableFeesMoney).reduce(BigDecimal.ZERO, BigDecimal::add);
+        BigDecimal totalRentShould = currentQuarterBillList.stream()
+                .filter(item -> !item.getPayFeesStatus().equals("5"))
+                .map(TBill::getPayableFeesMoney)
+                .reduce(BigDecimal.ZERO, BigDecimal::add)
+                .divide(new BigDecimal("10000"),2, RoundingMode.DOWN);
         vo.setTotalRentShould(totalRentShould);
         //本季度欠费
         BigDecimal totalRentOwe = currentQuarterBillList.stream()
                 .map(TBill::getOutstandingMoney)
                 .reduce(BigDecimal.ZERO, BigDecimal::add)
-                .divide(BigDecimal.valueOf(10000L), 2, RoundingMode.HALF_UP);
+                .divide(BigDecimal.valueOf(10000L), 2, RoundingMode.DOWN);
         vo.setTotalRentOwe(totalRentOwe);
         //总计欠费
-        List<TBill> allBillList = tBillService.lambdaQuery().le(TBill::getPayableFeesTime, last).list();
-        BigDecimal totalRentOweAll = allBillList.stream()
+        BigDecimal totalRentOweAll = billList.stream()
                 .map(TBill::getOutstandingMoney)
                 .reduce(BigDecimal.ZERO, BigDecimal::add)
-                .divide(BigDecimal.valueOf(10000L), 2, RoundingMode.HALF_UP);
+                .divide(BigDecimal.valueOf(10000L), 2, RoundingMode.DOWN);
         vo.setTotalRentOweAll(totalRentOweAll);
         return vo;
     }
@@ -93,7 +121,8 @@
      * @return
      */
     public List<ScreenRentRankVO> streetRentRank() {
-        return  tBillService.getStreetRentRank();
+        String businessDeptId = SecurityUtils.getBusinessDeptId();
+        return  tBillService.getStreetRentRank(businessDeptId);
     }
 
     /**
@@ -102,7 +131,7 @@
      */
     public ScreenRentIncomeTrendVO rentIncomeTrend() {
         ScreenRentIncomeTrendVO vo = new ScreenRentIncomeTrendVO();
-        
+        String businessDeptId = SecurityUtils.getBusinessDeptId();
         // 获取当前日期
         Date currentDate = new Date();
         List<String> quarterLabels = new ArrayList<>(); // 季度标签列表
@@ -118,23 +147,21 @@
             Date quarterEnd = quarterDate.get("last");
 
             // 获取该季度的账单数据
-            List<TBill> quarterBills = tBillService.lambdaQuery()
-                    .between(TBill::getPayableFeesTime, quarterStart, quarterEnd)
-                    .list();
+            List<TBill> quarterBills = tBillService.getJiFuBillListByTime(businessDeptId, quarterStart, quarterEnd);
 
             // 计算季度租金收入总和
             BigDecimal quarterIncome = quarterBills.stream()
                     .map(TBill::getPayFeesMoney)
                     .filter(Objects::nonNull)
                     .reduce(BigDecimal.ZERO, BigDecimal::add)
-                    .divide(BigDecimal.valueOf(10000L), 2, RoundingMode.HALF_UP);
+                    .divide(BigDecimal.valueOf(10000L), 2, RoundingMode.DOWN);
 
             // 计算季度欠费总和
             BigDecimal quarterOutstanding = quarterBills.stream()
                     .map(TBill::getOutstandingMoney)
                     .filter(Objects::nonNull)
                     .reduce(BigDecimal.ZERO, BigDecimal::add)
-                    .divide(BigDecimal.valueOf(10000L), 2, RoundingMode.HALF_UP);
+                    .divide(BigDecimal.valueOf(10000L), 2, RoundingMode.DOWN);
 
             // 生成季度标签 (格式: YY-MM月)
             Calendar cal = Calendar.getInstance();
@@ -154,6 +181,65 @@
         return vo;
     }
 
+    public R<List<TenantCountTrendVO>> getTenantCountTrend() {
+
+        // 获取当前日期
+        Date currentDate = new Date();
+        String businessDeptId = SecurityUtils.getBusinessDeptId();
+        List<TenantCountTrendVO> list = new ArrayList<>();
+        for (int i = 6; i >= 0; i--) {
+            Date targetDate = DateUtils.addMonths(currentDate, -3 * i);
+            Map<String, Date> quarterDate = DateUtils.getQuarterDate(targetDate);
+            Date quarterStart = quarterDate.get("first");
+            Date quarterEnd = quarterDate.get("last");
+            System.out.println("第" + (i + 1) + "季度的起止时间:" + quarterStart + " - " + quarterEnd);
+
+            List<TContract> contracts = contractService.list(new LambdaQueryWrapper<TContract>()
+                    .eq(!"0".equals(businessDeptId), TContract::getBusinessDeptId, businessDeptId)
+                    .eq(TContract::getPayType, 2)
+                    .isNotNull(TContract::getSignTime)
+                    .between(TContract::getSignTime, quarterStart, quarterEnd)
+                    .orderByAsc(TContract::getSignTime));
+
+
+            TenantCountTrendVO vo = new TenantCountTrendVO();
+            // 生成季度标签 (格式: YY-MM月)
+            Calendar cal = Calendar.getInstance();
+            cal.setTime(quarterEnd);
+            String label = String.format("%02d-%d月",
+                    cal.get(Calendar.YEAR) % 100,
+                    cal.get(Calendar.MONTH) + 1);
+            vo.setDate(label);
+            long count = contracts.stream().map(TContract::getTenantId).distinct().count();
+            vo.setCount(count);
+            list.add(vo);
+        }
+        return R.ok(list);
+    }
+//
+//
+//
+//
+//
+//
+//
+//        DateTimeFormatter quarterFormatter = DateTimeFormatter.ofPattern("yyyy-MM");
+//
+//        List<TenantCountTrendVO> trendData = contracts.stream()
+//                .collect(Collectors.groupingBy(contract -> {
+//                    LocalDate date = contract.getSignTime().toLocalDate();
+//                    int quarter = (date.getMonthValue() - 1) / 3 + 1;
+//                    return YearQuarter.from(date.withMonth(quarter * 3 - 2));
+//                }, TreeMap::new, Collectors.counting()))
+//                .entrySet().stream()
+//                .map(entry -> new TenantCountTrendVO(
+//                        entry.getKey().format(quarterFormatter),
+//                        entry.getValue()))
+//                .collect(Collectors.toList());
+//
+//        return R.ok(trendData);
+//    }
+
 
 
 }
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/StateProcessTemplateServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/StateProcessTemplateServiceImpl.java
index 6ae87fc..b7eb5cb 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/StateProcessTemplateServiceImpl.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/StateProcessTemplateServiceImpl.java
@@ -580,6 +580,13 @@
         if (processTaskListBO.getSortBy() == 2) {
             stateTaskQuery.orderByDesc(BaseModel::getCreateTime);
         }
+        // 查询合同信息
+        List<TContract> tContracts = contractMapper.selectList(Wrappers.<TContract>lambdaQuery());
+        List<String> contractIds = tContracts.stream().map(TContract::getId).collect(Collectors.toList());
+        if(CollectionUtils.isEmpty(contractIds)){
+            return new PageInfo<>();
+        }
+        stateTaskQuery.in(StateTaskCenter::getProjectId, contractIds);
         stateTaskQuery.in(StateTaskCenter::getFlowId, instanceIds);
         PageInfo pageInfo = new PageInfo(processTaskListBO.getPageNum(), processTaskListBO.getPageSize());
         PageInfo<StateTaskCenter> taskCenters = stateTaskCenterService.page(pageInfo,stateTaskQuery);
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TBillServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TBillServiceImpl.java
index 52cebac..dcc56e1 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TBillServiceImpl.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TBillServiceImpl.java
@@ -5,6 +5,7 @@
 import com.ruoyi.common.constant.AmountConstant;
 import com.ruoyi.common.constant.CacheConstants;
 import com.ruoyi.common.core.redis.RedisCache;
+import com.ruoyi.common.enums.DisabledEnum;
 import com.ruoyi.common.exception.ServiceException;
 import com.ruoyi.common.utils.*;
 import com.ruoyi.common.utils.uuid.UUID;
@@ -251,6 +252,7 @@
     @Override
     @Transactional(rollbackFor = Exception.class)
     public void saveBill(TbillSaveDto bill) {
+        bill.setManualAddition(DisabledEnum.YES.getCode());
         save(bill);
         if (bill.getBillType().equals("3")){
             if (bill.getDetails()==null || bill.getDetails().size()==0){
@@ -590,8 +592,29 @@
      * @return
      */
     @Override
-    public List<ScreenRentRankVO> getStreetRentRank() {
-        return baseMapper.getStreetRentRank();
+    public List<ScreenRentRankVO> getStreetRentRank(String businessDeptId) {
+        return baseMapper.getStreetRentRank(businessDeptId);
+    }
+    /**
+     * 查询季付账单
+     * @param businessDeptId
+     * @return
+     */
+    @Override
+    public List<TBill> getJiFuBillList(String businessDeptId) {
+        return baseMapper.getJiFuBillList(businessDeptId,null,null);
+    }
+
+    /**
+     * 查询当前季度的季付账单
+     * @param businessDeptId
+     * @param first
+     * @param last
+     * @return
+     */
+    @Override
+    public List<TBill> getJiFuBillListByTime(String businessDeptId, Date first, Date last) {
+        return baseMapper.getJiFuBillList(businessDeptId,first,last);
     }
 
     @Override
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TContractServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TContractServiceImpl.java
index dd04199..9abc49d 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TContractServiceImpl.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TContractServiceImpl.java
@@ -31,6 +31,7 @@
 import com.ruoyi.system.service.TContractService;
 import com.ruoyi.system.vo.BillVO;
 import com.ruoyi.system.vo.CheckAcceptRecordVO;
+import com.ruoyi.system.vo.ScreenRentIncomeTrendVO;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
@@ -92,7 +93,9 @@
         PageInfo<TContract> pageInfo = new PageInfo<>(query.getPageNum(), query.getPageSize());
         List<TContract> list = this.baseMapper.contractAppletList(query,pageInfo);
         for (TContract tContract : list) {
-            tContract.setPayType(DictUtils.getDictLabel(DictConstants.DICT_TYPE_CONTRACT_PAY_TYPE,tContract.getPayType()));
+            tContract.setPayType(
+                    DictUtils.getDictLabel(DictConstants.DICT_TYPE_CONTRACT_PAY_TYPE, tContract.getPayType())
+            );
             tContract.setStatus(DictUtils.getDictLabel(DictConstants.DICT_TYPE_CONTRACT_STATUS,tContract.getStatus()));
             FlwHisTask flwHisTask = flwHisTaskMapper.selectOne(new LambdaQueryWrapper<FlwHisTask>()
                     .like(FlwHisTask::getVariable, tContract.getId())
@@ -122,6 +125,7 @@
     public void terminateContract(TerminateContractDTO dto) {
         TContract contract = this.baseMapper.selectById(dto.getId());
         contract.setTerminateRemark(dto.getTerminateRemark());
+        contract.setTerminateTime(dto.getTerminateTime());
         this.baseMapper.updateById(contract);
         // 进入合同提前终止审批流程
         ProcessStartBO processStartBO = new ProcessStartBO();
@@ -209,8 +213,8 @@
      * @return
      */
     @Override
-    public Integer getCurrentMonthRentCount() {
-        return baseMapper.getCurrentMonthRentCount();
+    public Integer getCurrentMonthRentCount(String businessDeptId) {
+        return baseMapper.getCurrentMonthRentCount(businessDeptId);
     }
 
     @Override
@@ -219,4 +223,5 @@
         pageInfo = this.baseMapper.page(pageInfo,query);
         return pageInfo;
     }
+
 }
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/THouseServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/THouseServiceImpl.java
index 1c0cbbb..768b25a 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/THouseServiceImpl.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/THouseServiceImpl.java
@@ -54,7 +54,12 @@
                 tHouse.setLeaseStatus(DictUtils.getDictLabel(DictConstants.DICT_TYPE_LEASE_STATUS,"2"));
 
             }else{
-                tHouse.setLeaseStatus(DictUtils.getDictLabel(DictConstants.DICT_TYPE_LEASE_STATUS,tHouse.getLeaseStatus()));
+                if (tHouse.getLeaseStatus().equals("3")){
+                    tHouse.setLeaseStatus(DictUtils.getDictLabel(DictConstants.DICT_TYPE_LEASE_STATUS,tHouse.getLeaseStatus()));
+                }else{
+                    tHouse.setLeaseStatus(DictUtils.getDictLabel(DictConstants.DICT_TYPE_LEASE_STATUS,"1"));
+
+                }
             }
 
         }
@@ -73,4 +78,14 @@
         pageInfo.setRecords(list);
         return pageInfo;
     }
+    /**
+     * 获取本季度已出租面积
+     *
+     * @param businessDeptId
+     * @return
+     */
+    @Override
+    public Double getRentedArea(String businessDeptId) {
+        return baseMapper.getRentedArea(businessDeptId);
+    }
 }
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TRentalReturnRecordServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TRentalReturnRecordServiceImpl.java
new file mode 100644
index 0000000..c7f07fa
--- /dev/null
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TRentalReturnRecordServiceImpl.java
@@ -0,0 +1,121 @@
+package com.ruoyi.system.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.ruoyi.common.core.domain.R;
+import com.ruoyi.common.core.domain.model.LoginUserApplet;
+import com.ruoyi.common.core.exception.ServiceException;
+import com.ruoyi.common.enums.ProcessCategoryEnum;
+import com.ruoyi.common.utils.SecurityUtils;
+import com.ruoyi.system.bo.ProcessStartBO;
+import com.ruoyi.system.mapper.TRentalReturnRecordMapper;
+import com.ruoyi.system.model.TContract;
+import com.ruoyi.system.model.THouse;
+import com.ruoyi.system.model.TRentalReturnRecord;
+import com.ruoyi.system.query.RentalReturnAuditQuery;
+import com.ruoyi.system.query.RentalReturnRecordQuery;
+import com.ruoyi.system.service.ITRentalReturnRecordService;
+import com.ruoyi.system.service.StateProcessTemplateService;
+import com.ruoyi.system.service.TContractService;
+import com.ruoyi.system.service.THouseService;
+import com.ruoyi.system.vo.RentalRetureApplyVO;
+import com.ruoyi.system.vo.RentalReturnRecordVO;
+import lombok.RequiredArgsConstructor;
+import org.springframework.context.annotation.Lazy;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.time.LocalDateTime;
+import java.util.HashMap;
+import java.util.Map;
+
+@Service
+@RequiredArgsConstructor(onConstructor_ = @__(@Lazy))
+public class TRentalReturnRecordServiceImpl extends ServiceImpl<TRentalReturnRecordMapper, TRentalReturnRecord>
+        implements ITRentalReturnRecordService {
+    private final TContractService contractService;
+    private final StateProcessTemplateService stateProcessTemplateService;
+    private final THouseService houseService;
+
+    @Override
+    public IPage<RentalReturnRecordVO> queryRentalReturnRecordList(Page<RentalReturnRecordVO> page, RentalReturnRecordQuery query) {
+        String businessDeptId = SecurityUtils.getBusinessDeptId();
+        query.setBusinessDeptId(businessDeptId);
+        query.setIsAdminDelete(true);
+        return this.baseMapper.queryRentalReturnRecordList(page, query);
+    }
+
+    @Override
+    public RentalReturnRecordVO queryRentalReturnRecordById(String id) {
+        return this.baseMapper.queryRentalReturnRecordById(id);
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public void apply(RentalRetureApplyVO rentalReture,String tenantId) {
+        TContract contract = contractService.getById(rentalReture.getContractId());
+        if (contract == null) {
+            throw new ServiceException("该房屋暂无合同");
+        }
+
+        TRentalReturnRecord tRentalReturnRecord = new TRentalReturnRecord();
+        tRentalReturnRecord.setTenantId(tenantId);
+        tRentalReturnRecord.setHouseId(contract.getHouseId());
+        tRentalReturnRecord.setContractId(contract.getId());
+        tRentalReturnRecord.setReasonForReturn(rentalReture.getReasonForReturn());
+        tRentalReturnRecord.setImages(rentalReture.getImages());
+        tRentalReturnRecord.setAuditStatus(1);
+        save(tRentalReturnRecord);
+        boolean update = houseService.update(new LambdaUpdateWrapper<THouse>()
+                .set(THouse::getRentalReturnStatus, "2")
+                .eq(THouse::getId, contract.getHouseId()));
+        if (!update){
+            throw new ServiceException("更新房屋状态失败");
+        }
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public void audit(RentalReturnAuditQuery returnAuditQuery, Long userId,String userName) {
+        TRentalReturnRecord record = getById(returnAuditQuery.getId());
+        if (record == null){
+            throw new ServiceException("申请记录不存在");
+        }
+        if (record.getAuditStatus() != 1){
+            throw new ServiceException("申请记录已审核");
+        }
+
+        THouse house = houseService.getById(record.getHouseId());
+        if (returnAuditQuery.getAuditResult() == 2){
+            TContract contract = contractService.getById(record.getContractId());
+            contract.setTerminateRemark(returnAuditQuery.getAuditOpinion());
+            contractService.updateById(contract);
+            // 进入合同提前终止审批流程
+            ProcessStartBO processStartBO = new ProcessStartBO();
+            processStartBO.setCategory(ProcessCategoryEnum.CATEGORY3.getValue().toString());
+            processStartBO.setModuleName("房屋退租合同终止审批");
+            processStartBO.setName(contract.getContractName());
+            processStartBO.setRemark("");
+            Map<String, Object> variable = new HashMap<>();
+            variable.put("projectId", record.getContractId());
+            processStartBO.setVariable(variable);
+            //开启工作流程
+            stateProcessTemplateService.start(processStartBO);
+            house.setRentalReturnStatus("3");
+            houseService.updateById(house);
+        }else {
+            house.setRentalReturnStatus("1");
+            houseService.updateById(house);
+        }
+        record.setAuditTime(LocalDateTime.now());
+        record.setAuditStatus(returnAuditQuery.getAuditResult());
+        record.setAuditOpinion(returnAuditQuery.getAuditOpinion());
+        record.setAuditUserId(userId);
+        record.setUpdateBy(userName);
+        record.setUpdateTime(LocalDateTime.now());
+        updateById(record);
+    }
+}
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TTenantServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TTenantServiceImpl.java
index aeeec8d..8f869f1 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TTenantServiceImpl.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TTenantServiceImpl.java
@@ -6,7 +6,6 @@
 import com.ruoyi.common.basic.PageInfo;
 import com.ruoyi.common.constant.DictConstants;
 import com.ruoyi.common.utils.DictUtils;
-import com.ruoyi.common.utils.SecurityUtils;
 import com.ruoyi.common.utils.StringUtils;
 import com.ruoyi.system.dto.TTenantDTO;
 import com.ruoyi.system.mapper.TContractMapper;
@@ -49,14 +48,15 @@
     @Override
     public PageInfo<TenantVO> pageList(TTenantQuery query) {
         PageInfo<TenantVO> pageInfo = new PageInfo<>(query.getPageNum(), query.getPageSize());
-        String businessDeptId = SecurityUtils.getBusinessDeptId();
+ /*       String businessDeptId = SecurityUtils.getBusinessDeptId();
         List<TenantVO> list = null;
         if (StringUtils.isBlank(businessDeptId) || "0".equals(businessDeptId)) {
             list = this.baseMapper.pageList(query, pageInfo);
         } else {
             query.setBusinessDeptId(businessDeptId);
             list = this.baseMapper.pageListByBusinessDeptId(query,pageInfo);
-        }
+        }*/
+        List<TenantVO> list = this.baseMapper.pageList(query, pageInfo);
         for (TenantVO tenantVO : list) {
             tenantVO.setTenantAttributesName(StringUtils.isNotBlank(tenantVO.getTenantAttributes())?DictUtils.getDictLabel(DictConstants.DICT_TYPE_TENANT_ATTRIBUTE,tenantVO.getTenantAttributes()):"");
             tenantVO.setTenantTypeName(StringUtils.isNotBlank(tenantVO.getTenantType())?DictUtils.getDictLabel(DictConstants.DICT_TYPE_TENANT_TYPE,tenantVO.getTenantType()):"");
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/task/utils/TaskUtil.java b/ruoyi-system/src/main/java/com/ruoyi/system/task/utils/TaskUtil.java
index 4e6e2f7..d6d21a6 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/task/utils/TaskUtil.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/task/utils/TaskUtil.java
@@ -2,6 +2,9 @@
 
 
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.ruoyi.common.constant.CacheConstants;
+import com.ruoyi.common.core.redis.RedisCache;
+import com.ruoyi.common.utils.uuid.UUID;
 import com.ruoyi.system.mapper.TBillMapper;
 import com.ruoyi.system.model.TBill;
 import com.ruoyi.system.model.TContract;
@@ -27,6 +30,8 @@
     private TContractService contractService;
     @Autowired
     private TBillMapper billMapper;
+    @Autowired
+    RedisCache redisCache;
     // 用于更新违约金账单
     // 每分钟执行一次的定时任务
 
@@ -50,18 +55,26 @@
                     // 违约金比例
                     BigDecimal proportion = contract.getProportion();
                     // 按每天 待缴费金额 * XX% 增加违约金费用
-                    if (tBill.getOutstandingMoney().compareTo(new BigDecimal("0"))==0){
+                    if (contract.getTotalYear().compareTo(new BigDecimal("0"))==0){
                         tBill.setPayFeesStatus("3");
                         billMapper.updateById(tBill);
                         continue;
                     }
-                    BigDecimal money = tBill.getOutstandingMoney().multiply(new BigDecimal(100).add(proportion)).divide(new BigDecimal(100),2, BigDecimal.ROUND_DOWN);
-                    tBill.setOverDays((int) l);
-                    BigDecimal bigDecimal = tBill.getOutstandingMoney().multiply(proportion).setScale(2, BigDecimal.ROUND_DOWN);
-                    tBill.setPayableFeesPenalty(tBill.getPayableFeesPenalty()!=null?tBill.getPayableFeesPenalty():new BigDecimal("0").add(bigDecimal));
-                    tBill.setOutstandingMoney(money);
-                    billMapper.updateById(tBill);
-
+                    String requestId = UUID.fastUUID().toString();
+                    String lockkey = CacheConstants.BILL_UPDATE_LOCK_KEY + tBill.getId();
+                    boolean isok = redisCache.trylockLoop(lockkey, requestId, 60);
+                    if (isok){
+                        try {
+                            BigDecimal money = tBill.getOutstandingMoney().multiply(new BigDecimal(100).add(proportion)).divide(new BigDecimal(100),2, BigDecimal.ROUND_DOWN);
+                            tBill.setOverDays((int) l);
+                            BigDecimal bigDecimal = tBill.getOutstandingMoney().multiply(proportion).setScale(2, BigDecimal.ROUND_DOWN);
+                            tBill.setPayableFeesPenalty(tBill.getPayableFeesPenalty()!=null?tBill.getPayableFeesPenalty():new BigDecimal("0").add(bigDecimal));
+                            tBill.setOutstandingMoney(money);
+                            billMapper.updateById(tBill);
+                        }finally {
+                            redisCache.unlock(lockkey,requestId);
+                        }
+                    }
                 }
             }
         } catch (Exception e) {
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/vo/HouseMapDistributionVO.java b/ruoyi-system/src/main/java/com/ruoyi/system/vo/HouseMapDistributionVO.java
index 5547a6d..7a409d3 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/vo/HouseMapDistributionVO.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/vo/HouseMapDistributionVO.java
@@ -15,7 +15,7 @@
     @ApiModelProperty(value = "房屋地址")
     private String houseAddress;
 
-    @ApiModelProperty(value = "房屋状态 1=待出租 2=已出租 3=维修中")
+    @ApiModelProperty(value = "房屋状态 1=待出租 2=已出租 3=维修中 4=欠费")
     private String houseStatus;
 
     @ApiModelProperty(value = "租户")
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/vo/MyHouseVO.java b/ruoyi-system/src/main/java/com/ruoyi/system/vo/MyHouseVO.java
index a591dbb..a8a10b9 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/vo/MyHouseVO.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/vo/MyHouseVO.java
@@ -1,5 +1,6 @@
 package com.ruoyi.system.vo;
 
+import com.baomidou.mybatisplus.annotation.TableField;
 import com.fasterxml.jackson.annotation.JsonFormat;
 import com.ruoyi.system.model.TBill;
 import io.swagger.annotations.ApiModel;
@@ -35,6 +36,8 @@
     private String propertyRightPerson;
     @ApiModelProperty(value = "房东联系方式")
     private String phone;
+    @ApiModelProperty(value = "退租状态 1=未退租 2=退租申请中 3=已退租")
+    private String rentalReturnStatus;
     @ApiModelProperty(value = "交租记录")
     private List<PayListVO> payList;
 }
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/vo/RentalRetureApplyVO.java b/ruoyi-system/src/main/java/com/ruoyi/system/vo/RentalRetureApplyVO.java
new file mode 100644
index 0000000..bd3e26d
--- /dev/null
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/vo/RentalRetureApplyVO.java
@@ -0,0 +1,30 @@
+package com.ruoyi.system.vo;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+@Data
+@ApiModel("退租申请")
+public class RentalRetureApplyVO {
+
+
+    /**
+     * 合同id
+     */
+    @ApiModelProperty(value = "合同id")
+    private String contractId;
+
+    /**
+     * 退租说明
+     */
+    @ApiModelProperty(value = "退租说明")
+    private String reasonForReturn;
+
+    /**
+     * 图片
+     */
+    @ApiModelProperty(value = "图片")
+    private String images;
+
+}
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/vo/RentalReturnRecordVO.java b/ruoyi-system/src/main/java/com/ruoyi/system/vo/RentalReturnRecordVO.java
new file mode 100644
index 0000000..8bebd43
--- /dev/null
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/vo/RentalReturnRecordVO.java
@@ -0,0 +1,90 @@
+package com.ruoyi.system.vo;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.time.LocalDateTime;
+
+@Data
+@ApiModel("退租记录")
+public class RentalReturnRecordVO {
+    /**
+     * 退租记录id
+     */
+    @ApiModelProperty(value = "退租记录id")
+    private String id;
+
+    /**
+     * 提交时间
+     */
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @ApiModelProperty(value = "提交时间")
+    private LocalDateTime applicationDate;
+
+    /**
+     * 房屋名称
+     */
+    @ApiModelProperty(value = "房屋名称")
+    private String houseName;
+
+    /**
+     * 房屋地址
+     */
+    @ApiModelProperty(value = "房屋地址")
+    private String houseAddress;
+
+    /**
+     * 租赁合同编号
+     */
+    @ApiModelProperty(value = "租赁合同编号")
+    private String contractNumber;
+
+    /**
+     * 图片
+     */
+    @ApiModelProperty(value = "图片")
+    private String images;
+
+    /**
+     * 提交人
+     */
+    @ApiModelProperty(value = "提交人")
+    private String submitter;
+
+    /**
+     * 联系方式
+     */
+    @ApiModelProperty(value = "联系方式")
+    private String submitterPhone;
+
+    /**
+     * 退租说明
+     */
+    @ApiModelProperty(value = "退租说明")
+    private String reasonForReturn;
+
+    /**
+     * 验收状态
+     */
+    @ApiModelProperty(value = "验收状态: 1-待审核 2-审核通过 3-审核驳回")
+    private String auditStatus;
+
+    /**
+     * 提交时间
+     */
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @ApiModelProperty(value = "提交时间")
+    private LocalDateTime createTime;
+
+    /**
+     * 审批意见
+     */
+    @ApiModelProperty(value = "审批意见")
+    private String auditOpinion;
+
+}
diff --git a/ruoyi-system/src/main/resources/mapper/system/SysUserMapper.xml b/ruoyi-system/src/main/resources/mapper/system/SysUserMapper.xml
index 63e273c..0e84df6 100644
--- a/ruoyi-system/src/main/resources/mapper/system/SysUserMapper.xml
+++ b/ruoyi-system/src/main/resources/mapper/system/SysUserMapper.xml
@@ -225,7 +225,8 @@
 		select u.user_id AS userId, u.dept_id AS deptId, u.user_name AS userName, u.nick_name AS nickName, u.email AS email, u.avatar AS avatar,u.disable_remark AS disableRemark,
 			   u.phonenumber AS phonenumber, u.sex AS sex, u.status AS status, u.del_flag AS delFlag, u.login_ip AS loginIp,u.operating_time AS operatingTime,u.operating_person AS operatingPerson,
 			   u.login_date AS loginDate, u.create_by AS createBy, u.create_time AS createTime, u.remark AS remark,u.ifBlack AS ifBlack, u.districtId AS districtId,
-			   r.role_id AS roleId, r.role_name AS roleName, r.role_key AS roleKey, r.role_sort AS roleSort, r.data_scope AS dataScope, r.status as role_status,u.deptName as deptName
+			   r.role_id AS roleId, r.role_name AS roleName, r.role_key AS roleKey, r.role_sort AS roleSort, r.data_scope AS dataScope, r.status as role_status,u.deptName as deptName,
+			   u.business_dept_id AS businessDeptId
 		from sys_user u
 		left join sys_user_role ur on u.user_id = ur.user_id
 		left join sys_role r on r.role_id = ur.role_id
@@ -249,7 +250,7 @@
 				#{roleId}
 			</foreach>
 		</if>
-		<if test="query.businessDeptId != null and query.businessDeptId != '' and query.businessDeptId != '0'">
+		<if test="query.businessDeptId != null and query.businessDeptId != '' and query.businessDeptId != 0">
 			AND u.business_dept_id = #{query.businessDeptId}
 		</if>
 		ORDER BY u.create_time DESC
@@ -275,6 +276,7 @@
  			<if test="remark != null and remark != ''">remark,</if>
  			<if test="ifBlack != null">ifBlack,</if>
  			<if test="districtId != null">districtId,</if>
+			<if test="businessDeptId != null">business_dept_id,</if>
  			create_time
  		)values(
  			<if test="userId != null and userId != ''">#{userId},</if>
@@ -293,6 +295,7 @@
  			<if test="remark != null and remark != ''">#{remark},</if>
 			<if test="ifBlack != null">#{ifBlack},</if>
 			<if test="districtId != null">#{districtId},</if>
+			<if test="businessDeptId != null">#{businessDeptId},</if>
  			sysdate()
  		)
 	</insert>
@@ -319,6 +322,7 @@
 			<if test="disableRemark != null">disable_remark = #{disableRemark},</if>
 			<if test="operatingTime != null">operating_time = #{operatingTime},</if>
 			<if test="operatingPerson != null">operating_person = #{operatingPerson},</if>
+			<if test="businessDeptId != null">business_dept_id = #{businessDeptId},</if>
  			update_time = sysdate()
  		</set>
  		where user_id = #{userId}
diff --git a/ruoyi-system/src/main/resources/mapper/system/TBillMapper.xml b/ruoyi-system/src/main/resources/mapper/system/TBillMapper.xml
index b0d10bc..d362ce5 100644
--- a/ruoyi-system/src/main/resources/mapper/system/TBillMapper.xml
+++ b/ruoyi-system/src/main/resources/mapper/system/TBillMapper.xml
@@ -63,7 +63,7 @@
             <if test="query.userId != null and query.userId !=''">
                 and t.id = #{query.userId}
             </if>
-            <if test='query.businessDeptId != null and query.businessDeptId != "" and query.businessDeptId!="0"'>
+            <if test='query.businessDeptId != null and query.businessDeptId != "" and query.businessDeptId!=0'>
                 and b.business_dept_id = #{query.businessDeptId}
             </if>
             <if test="query.billType != null">
@@ -350,9 +350,26 @@
         FROM
             t_street ts
                 LEFT JOIN t_house th ON ts.id = th.street_id
-                LEFT JOIN t_contract tc ON tc.house_id = th.id
-                LEFT JOIN t_bill tb ON tc.id = tb.contract_id
+                LEFT JOIN t_contract tc ON tc.house_id = th.id AND tc.pay_type = 2
+                LEFT JOIN t_bill tb ON tc.id = tb.contract_id AND tb.pay_fees_status != 5
+            <where>
+                <if test="businessDeptId != 0">
+                    AND th.business_dept_id = #{businessDeptId}
+                </if>
+            </where>
         GROUP BY ts.id
         ORDER BY rentAmount DESC
     </select>
+    <select id="getJiFuBillList" resultType="com.ruoyi.system.model.TBill" parameterType="java.lang.String">
+        SELECT tb.* FROM t_bill tb LEFT JOIN t_contract tt ON tb.contract_id = tt.id
+        <where>
+            tt.pay_type = 2 AND tb.bill_type = ${@com.ruoyi.common.enums.BillTypeEnum@Zujin.getCode()} AND tb.pay_fees_status != 5
+            <if test="businessDeptId != null and businessDeptId != 0">
+                AND tb.business_dept_id = #{businessDeptId}
+            </if>
+            <if test="first!=null and last !=null">
+                AND tb.payable_fees_time BETWEEN #{first} AND #{last}
+            </if>
+        </where>
+    </select>
 </mapper>
diff --git a/ruoyi-system/src/main/resources/mapper/system/TCheckAcceptRecordMapper.xml b/ruoyi-system/src/main/resources/mapper/system/TCheckAcceptRecordMapper.xml
index df64a73..aa98a8f 100644
--- a/ruoyi-system/src/main/resources/mapper/system/TCheckAcceptRecordMapper.xml
+++ b/ruoyi-system/src/main/resources/mapper/system/TCheckAcceptRecordMapper.xml
@@ -76,7 +76,7 @@
                 AND t.check_time &gt;= #{query.startTime}
                 AND t.check_time &lt;= #{query.endTime}
             </if>
-            <if test="query.businessDeptId != null and query.businessDeptId != '' and query.businessDeptId != '0'">
+            <if test="query.businessDeptId != null and query.businessDeptId != '' and query.businessDeptId != 0">
                 AND c.business_dept_id = #{query.businessDeptId}
             </if>
             AND t.disabled = ${@com.ruoyi.common.enums.DisabledEnum@NO.getCode()}
diff --git a/ruoyi-system/src/main/resources/mapper/system/TContractMapper.xml b/ruoyi-system/src/main/resources/mapper/system/TContractMapper.xml
index 422e1d3..81dc703 100644
--- a/ruoyi-system/src/main/resources/mapper/system/TContractMapper.xml
+++ b/ruoyi-system/src/main/resources/mapper/system/TContractMapper.xml
@@ -68,7 +68,7 @@
                     #{item}
                 </foreach>
             </if>
-            <if test="businessDeptId!=null and businessDeptId !='' and businessDeptId != '0'">
+            <if test="businessDeptId!=null and businessDeptId !='' and businessDeptId != 0">
                 and t1.business_dept_id = #{businessDeptId}
             </if>
             AND t1.disabled = ${@com.ruoyi.common.enums.DisabledEnum@NO.getCode()}
@@ -130,16 +130,21 @@
     <select id="getCurrentMonthRentCount" resultType="java.lang.Integer">
         SELECT COUNT(DISTINCT tc.tenant_id) AS new_tenant_count
         FROM t_contract tc
-        WHERE
-        -- 筛选本月签订的合同
-        DATE_FORMAT(tc.sign_time, '%Y%m') = DATE_FORMAT(CURDATE(), '%Y%m') AND tc.status IN ("4", "5", "6", "7", "8", "9")
-        -- 且租户在本月前从未签订过任何合同
-        AND NOT EXISTS (
-        SELECT 1
-        FROM t_contract tc_hist
-        WHERE tc_hist.tenant_id = tc.tenant_id
-        AND tc_hist.sign_time <![CDATA[ < ]]> DATE_FORMAT(CURDATE(), '%Y-%m-01') AND tc_hist.status IN ("4", "5", "6", "7", "8", "9")
-        )
+        <where>
+            -- 筛选本月签订的合同
+            DATE_FORMAT(tc.sign_time, '%Y%m') = DATE_FORMAT(CURDATE(), '%Y%m') AND tc.status IN ("4", "5", "6", "7", "8", "9") AND tc.pay_type = 2
+            -- 且租户在本月前从未签订过任何合同
+            AND NOT EXISTS (
+            SELECT 1
+            FROM t_contract tc_hist
+            WHERE tc_hist.tenant_id = tc.tenant_id
+            AND tc_hist.sign_time <![CDATA[ < ]]> DATE_FORMAT(CURDATE(), '%Y-%m-01') AND tc_hist.status IN ("4", "5", "6", "7", "8", "9")
+            )
+            <if test="businessDeptId!=0">
+                AND tc.business_dept_id = #{businessDeptId}
+            </if>
+        </where>
+
     </select>
 
     <select id="page" resultType="com.ruoyi.system.model.TContract">
diff --git a/ruoyi-system/src/main/resources/mapper/system/TFaultRepairMessageMapper.xml b/ruoyi-system/src/main/resources/mapper/system/TFaultRepairMessageMapper.xml
index 3e9f773..890c59c 100644
--- a/ruoyi-system/src/main/resources/mapper/system/TFaultRepairMessageMapper.xml
+++ b/ruoyi-system/src/main/resources/mapper/system/TFaultRepairMessageMapper.xml
@@ -67,6 +67,7 @@
         t.create_by,
         t.update_by,
         t.disabled,
+        t.fault_cause,
         i.item_name AS itemName,
         it.type_name AS itemTypeName,
         tnt.resident_name AS residentName
@@ -129,7 +130,7 @@
             <if test="query.handlePerson != null and query.handlePerson != ''">
                 AND t.handle_person LIKE CONCAT('%', #{query.handlePerson}, '%')
             </if>
-            <if test="query.businessDeptId != null and query.businessDeptId != '' and query.businessDeptId != '0'">
+            <if test="query.businessDeptId != null and query.businessDeptId != '' and query.businessDeptId != 0">
                 AND tc.business_dept_id = #{query.businessDeptId}
             </if>
             AND t.disabled = ${@com.ruoyi.common.enums.DisabledEnum@NO.getCode()}
diff --git a/ruoyi-system/src/main/resources/mapper/system/THouseMapper.xml b/ruoyi-system/src/main/resources/mapper/system/THouseMapper.xml
index 39b0c9c..f6a5a13 100644
--- a/ruoyi-system/src/main/resources/mapper/system/THouseMapper.xml
+++ b/ruoyi-system/src/main/resources/mapper/system/THouseMapper.xml
@@ -55,7 +55,7 @@
             <if test="req.leaseStatus == 1">
                 and (t2.start_time is null) and t1.lease_status = 1
             </if>
-            <if test="req.businessDeptId != null and req.businessDeptId != '' and req.businessDeptId!='0'">
+            <if test="req.businessDeptId != null and req.businessDeptId != '' and req.businessDeptId!=0">
                 and t1.business_dept_id = #{req.businessDeptId}
             </if>
             AND t1.disabled = ${@com.ruoyi.common.enums.DisabledEnum@NO.getCode()}
@@ -86,5 +86,16 @@
           AND t1.disabled = ${@com.ruoyi.common.enums.DisabledEnum@NO.getCode()}
 
     </select>
+    <select id="getRentedArea" resultType="java.lang.Double">
+        SELECT COALESCE(SUM(t1.house_area),0) FROM t_house t1
+        LEFT JOIN t_contract t2 ON t1.id = t2.house_id AND t2.status = 4 AND t2.pay_type = 2
+        <where>
+            t1.lease_status != 1
+            <if test="businessDeptId!=0">
+                AND t1.business_dept_id = #{businessDeptId}
+            </if>
+            AND t1.disabled = ${@com.ruoyi.common.enums.DisabledEnum@NO.getCode()}
+        </where>
+    </select>
 
 </mapper>
diff --git a/ruoyi-system/src/main/resources/mapper/system/TRentalReturnRecordMapper.xml b/ruoyi-system/src/main/resources/mapper/system/TRentalReturnRecordMapper.xml
new file mode 100644
index 0000000..1cbbad7
--- /dev/null
+++ b/ruoyi-system/src/main/resources/mapper/system/TRentalReturnRecordMapper.xml
@@ -0,0 +1,74 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.ruoyi.system.mapper.TRentalReturnRecordMapper">
+
+
+    <select id="queryRentalReturnRecordList" resultType="com.ruoyi.system.vo.RentalReturnRecordVO">
+        SELECT
+        trrr.id,
+        trrr.tenant_id,
+        trrr.house_id,
+        trrr.contract_id,
+        trrr.reason_for_return,
+        trrr.audit_status,
+        trrr.audit_user_id,
+        trrr.create_time applicationDate,
+        th.house_name,
+        th.house_address,
+        tc.contract_number,
+        tt.resident_name submitter,
+        tt.phone submitterPhone
+        FROM
+        t_rental_return_record trrr
+        LEFT JOIN t_house th ON trrr.house_id = th.id
+        LEFT JOIN t_contract tc ON trrr.contract_id = tc.id
+        LEFT JOIN t_tenant tt ON tt.id = trrr.tenant_id
+        <where>
+            trrr.disabled = 0
+            <if test="query.startDate != null and query.endDate !=null">
+            AND trrr.create_time BETWEEN #{query.startDate} AND DATE_ADD(#{query.endDate}, INTERVAL 1 DAY)
+            </if>
+            <if test="query.isAdminDelete != null and query.isAdminDelete">
+            AND trrr.is_admin_delete = 0
+            </if>
+            <if test="query.houseName != null and query.houseName != ''">
+            AND th.house_name LIKE CONCAT('%',#{query.houseName},'%')
+            </if>
+            <if test="query.contractNumber != null and query.contractNumber != ''">
+            AND tc.contract_number LIKE CONCAT('%',#{query.contractNumber},'%')
+            </if>
+            <if test="query.businessDeptId != null and query.businessDeptId != '' and query.businessDeptId != 0">
+                AND tc.business_dept_id = #{query.businessDeptId}
+            </if>
+            <if test="query.submitter != null and query.submitter != ''">
+            AND tt.resident_name LIKE CONCAT('%',#{query.submitter},'%')
+            </if>
+        </where>
+        order by trrr.create_time desc
+    </select>
+    <select id="queryRentalReturnRecordById" resultType="com.ruoyi.system.vo.RentalReturnRecordVO"
+            parameterType="java.lang.String">
+        SELECT
+            trrr.id,
+            trrr.tenant_id,
+            trrr.house_id,
+            trrr.contract_id,
+            trrr.reason_for_return,
+            trrr.audit_status,
+            trrr.audit_user_id,
+            trrr.images,
+            trrr.create_time,
+            trrr.audit_opinion,
+            th.house_name,
+            th.house_address,
+            tc.contract_number,
+            tt.resident_name submitter,
+            tt.phone submitterPhone
+        FROM
+            t_rental_return_record trrr
+                LEFT JOIN t_house th ON trrr.house_id = th.id
+                LEFT JOIN t_contract tc ON trrr.contract_id = tc.id
+                LEFT JOIN t_tenant tt ON tt.id = trrr.tenant_id
+        WHERE trrr.disabled = 0 AND trrr.id = #{id}
+    </select>
+</mapper>

--
Gitblit v1.7.1