From 592ac14eba76040426f590d8eb079fc75e968b84 Mon Sep 17 00:00:00 2001
From: luofl <1442745593@qq.com>
Date: 星期五, 28 三月 2025 19:18:37 +0800
Subject: [PATCH] 1.租户数量趋势统计

---
 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/resources/mapper/system/SysUserMapper.xml                              |    5 
 ruoyi-system/src/main/java/com/ruoyi/system/model/TRentalReturnRecord.java                   |   85 +++++
 ruoyi-system/src/main/java/com/ruoyi/system/query/RentalReturnRecordQuery.java               |   51 +++
 ruoyi-system/src/main/java/com/ruoyi/system/vo/HouseMapDistributionVO.java                   |    2 
 ruoyi-system/src/main/resources/mapper/system/TCheckAcceptRecordMapper.xml                   |    2 
 ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/THouseController.java                 |    3 
 ruoyi-system/src/main/java/com/ruoyi/system/service/ITRentalReturnRecordService.java         |   21 +
 ruoyi-system/src/main/java/com/ruoyi/system/service/impl/ScreenService.java                  |   55 ++-
 ruoyi-system/src/main/resources/mapper/system/TRentalReturnRecordMapper.xml                  |   74 ++++
 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/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                 |  136 +++-----
 ruoyi-system/src/main/resources/mapper/system/THouseMapper.xml                               |    2 
 ruoyi-system/src/main/resources/mapper/system/TContractMapper.xml                            |    2 
 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              |   74 +++-
 ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TRentalReturnRecordController.java    |   79 ++++
 ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TContractServiceImpl.java           |    4 
 ruoyi-system/src/main/java/com/ruoyi/system/model/TFaultRepairMessage.java                   |    4 
 26 files changed, 820 insertions(+), 134 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..d8d82e6 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,5 +1,7 @@
 package com.ruoyi.web.controller.api;
 
+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;
@@ -14,7 +16,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;
@@ -65,7 +66,7 @@
     }
 
     @GetMapping("/getTenantCountTrend")
-    @ApiModelProperty(value = "租户数量趋势统计")
+    @ApiOperation(value = "租户数量趋势统计")
     public R<List<TenantCountTrendVO>> getTenantCountTrend() {
 
         Date currentDate = new Date();
@@ -98,10 +99,12 @@
         return R.ok(trendData);
     }
 
+
     /**
      * 实时租赁数据
      */
     @GetMapping("/getRealTimeRentData")
+    @ApiOperation("获取实时租赁数据")
     public R<List<RealTimeRentDataVO>> getRealTimeRentData() {
         // 随机获取十条房源
         List<THouse> houses = houseService.list(new LambdaQueryWrapper<THouse>()
@@ -133,6 +136,7 @@
      * 获取房屋地图分布
      */
     @GetMapping("/getHouseMapDistribution")
+    @ApiOperation("获取房屋地图分布")
     public R<List<HouseMapDistributionVO>> getHouseMapDistribution() {
         // 获取所有房屋信息
         List<THouse> houses = houseService.list();
@@ -142,90 +146,58 @@
             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>()
+                    .gt(TContract::getEndTime, LocalDateTime.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(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 paidAlready = tBills.stream()
+                        .map(TBill::getPayableFeesMoney)
+                        .reduce(BigDecimal::add)
+                        .orElse(BigDecimal.ZERO);
+                String rentStatus = String.format("%.2f/%.2f", paidAlready, payableFeesMoney);
+                houseMapDistributionVO.setRentStatus(rentStatus);
+
+
+                TBill one = billService.getOne(new LambdaQueryWrapper<TBill>()
+                        .le(TBill::getStartTime, LocalDateTime.now())
+                        .gt(TBill::getEndTime, LocalDateTime.now())
+                        .eq(TBill::getBillType, 1)
+                        .eq(TBill::getContractId, contract.getId()));
+
+                if ("4".equals(one.getPayFeesStatus())){
+                    houseMapDistributionVO.setHouseStatus("4");
+                }
+
+
+
+                BigDecimal payFeesMoney = one.getPayFeesMoney();
+                BigDecimal payableFeesMoney1 = one.getPayableFeesMoney();
+                String rent = String.format("%.2f/%.2f", payFeesMoney, payableFeesMoney1);
+
+                houseMapDistributionVO.setRent(rent);
+            }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/TContractController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TContractController.java
index 58477ae..c9c99b2 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
@@ -50,6 +50,7 @@
 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;
@@ -98,7 +99,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("合同编号不可重复");
         }
@@ -137,7 +139,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 +212,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 +242,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 +264,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);
@@ -498,10 +521,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 +534,32 @@
             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();
-            }
         }
     }
+
+
 }
 
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-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 989234b..aa0105d 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/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-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/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/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/impl/ScreenService.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/ScreenService.java
index 084db02..59f1cae 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
@@ -16,12 +16,7 @@
 
 import java.math.BigDecimal;
 import java.math.RoundingMode;
-import java.util.ArrayList;
-import java.util.Calendar;
-import java.util.Date;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
+import java.util.*;
 
 /**
  * @author mitao
@@ -41,36 +36,60 @@
         ScreenTopStaticsDataVO vo = new ScreenTopStaticsDataVO();
         //房屋总面积
         List<THouse> houseList = tHouseService.list();
-        Double totalArea = houseList.stream().map(item -> Double.parseDouble(item.getHouseArea())).reduce(0D, Double::sum);
+        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);
+        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);
+        BigDecimal totalReceivableRent = billList.stream()
+                .filter(item -> !item.getPayFeesStatus().equals("5"))
+                .map(TBill::getPayableFeesMoney)
+                .reduce(BigDecimal.ZERO, BigDecimal::add)
+                .divide(new BigDecimal("10000"),2, RoundingMode.HALF_UP);
         vo.setTotalReceivableRent(totalReceivableRent);
         //总计已收租金
-        BigDecimal totalReceivedRent = billList.stream().map(TBill::getPayFeesMoney).reduce(BigDecimal.ZERO, BigDecimal::add);
+        BigDecimal totalReceivedRent = billList.stream()
+                .map(TBill::getPayFeesMoney)
+                .reduce(BigDecimal.ZERO, BigDecimal::add)
+                .divide(new BigDecimal("10000"),2, RoundingMode.HALF_UP);
         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());
+        List<TContract> tContracts = tContractService.lambdaQuery()
+                .in(TContract::getStatus, "4", "5", "6", "7", "8", "9")
+                .list();
+        long count = tContracts.stream()
+                .map(TContract::getTenantId)
+                .distinct()
+                .count();
+        vo.setTotalTenantCount((int) count);
         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();
+        List<TBill> currentQuarterBillList = tBillService.lambdaQuery()
+                .between(TBill::getPayableFeesTime, first, last)
+                .list();
         //本季度已交租金
-        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.HALF_UP);
         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.HALF_UP);
         vo.setTotalRentShould(totalRentShould);
         //本季度欠费
         BigDecimal totalRentOwe = currentQuarterBillList.stream()
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 e67701e..b8c2b1d 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
@@ -92,7 +92,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())
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/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 21458b9..0e84df6 100644
--- a/ruoyi-system/src/main/resources/mapper/system/SysUserMapper.xml
+++ b/ruoyi-system/src/main/resources/mapper/system/SysUserMapper.xml
@@ -250,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
@@ -276,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>
@@ -294,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>
@@ -320,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/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 0404766..1b7f6ac 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()}
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..dcde782 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()}
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