From 099ea14bba367fd86f0dde37d908f07cc04c3d39 Mon Sep 17 00:00:00 2001
From: 无关风月 <443237572@qq.com>
Date: 星期四, 10 四月 2025 15:38:01 +0800
Subject: [PATCH] Merge branch 'dev' of http://120.76.84.145:10101/gitblit/r/java/xizang

---
 ruoyi-admin/src/main/resources/application-test.yml                                           |    2 
 ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TCheckAcceptRecordController.java      |   21 
 ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TFaultRepairMessageServiceImpl.java  |    6 
 ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TBusinessDeptServiceImpl.java        |   20 
 ruoyi-system/src/main/java/com/ruoyi/system/query/SysUserQuery.java                           |    3 
 ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TBillController.java                   |   73 
 ruoyi-applet/src/main/java/com/ruoyi/web/controller/api/TBillController.java                  |   29 
 ruoyi-system/src/main/java/com/ruoyi/system/service/impl/StateProcessTemplateServiceImpl.java |   28 
 ruoyi-system/src/main/java/com/ruoyi/system/service/THouseService.java                        |    7 
 ruoyi-system/src/main/java/com/ruoyi/system/service/ITBusinessDeptService.java                |   16 
 ruoyi-common/src/main/java/com/ruoyi/common/utils/CodeGenerateUtils.java                      |   19 
 ruoyi-applet/src/main/java/com/ruoyi/web/controller/api/TRentalReturnRecordController.java    |   57 
 ruoyi-system/src/main/java/com/ruoyi/system/model/THouse.java                                 |   31 
 ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/ScreenController.java                  |  260 +++
 ruoyi-system/src/main/java/com/ruoyi/system/vo/ScreenTopStaticsDataVO.java                    |   47 
 ruoyi-system/src/main/java/com/ruoyi/system/mapper/TBankFlowMapper.java                       |    2 
 ruoyi-system/src/main/java/com/ruoyi/system/mapper/THouseMapper.java                          |    7 
 ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TBannerController.java                 |    2 
 ruoyi-system/src/main/java/com/ruoyi/system/model/TStreet.java                                |   38 
 ruoyi-system/src/main/java/com/ruoyi/system/dto/OfflinePayCheckDto.java                       |    2 
 ruoyi-system/src/main/java/com/ruoyi/system/mapper/TFlowManagementMapper.java                 |    3 
 ruoyi-system/src/main/java/com/ruoyi/system/service/TContractService.java                     |    7 
 ruoyi-system/src/main/java/com/ruoyi/system/service/ITStreetService.java                      |   16 
 ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TRentalReturnRecordController.java     |   79 +
 ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TBankFlowServiceImpl.java            |   10 
 ruoyi-system/src/main/java/com/ruoyi/system/mapper/TBillMapper.java                           |   24 
 ruoyi-admin/src/main/java/com/ruoyi/web/controller/tool/WordUtil.java                         |   39 
 ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TCheckAcceptRecordServiceImpl.java   |   22 
 ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TInvoiceServiceImpl.java             |   67 
 ruoyi-system/src/main/java/com/ruoyi/system/model/TFaultRepairMessage.java                    |    4 
 ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TBusinessDeptController.java           |   46 
 ruoyi-common/src/main/java/com/ruoyi/common/utils/TencentMailUtil.java                        |   71 
 ruoyi-system/src/main/java/com/ruoyi/system/model/TFlowManagement.java                        |    4 
 ruoyi-system/src/main/resources/mapper/system/SysUserMapper.xml                               |   14 
 ruoyi-system/src/main/resources/mapper/system/TStreetMapper.xml                               |    5 
 pom.xml                                                                                       |   28 
 ruoyi-system/src/main/java/com/ruoyi/system/mapper/TStreetMapper.java                         |   16 
 ruoyi-system/src/main/java/com/ruoyi/system/model/TBankFlow.java                              |    4 
 ruoyi-system/src/main/java/com/ruoyi/system/task/utils/TaskUtil.java                          |   33 
 ruoyi-system/src/main/resources/mapper/system/TFlowManagementMapper.xml                       |    3 
 ruoyi-system/src/main/java/com/ruoyi/system/service/impl/ScreenService.java                   |  245 +++
 ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TRentalReturnRecordServiceImpl.java  |  122 +
 ruoyi-system/src/main/java/com/ruoyi/system/vo/MyHouseVO.java                                 |    3 
 ruoyi-system/src/main/java/com/ruoyi/system/model/TInformation.java                           |   12 
 ruoyi-system/src/main/resources/mapper/system/THouseMapper.xml                                |   14 
 ruoyi-common/src/main/java/com/ruoyi/common/utils/DateUtils.java                              |   19 
 ruoyi-system/src/main/java/com/ruoyi/system/mapper/TContractMapper.java                       |   12 
 ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TBankFlowController.java               |    2 
 ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TTenantController.java                 |    5 
 ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TFaultRepairMessageController.java     |    2 
 ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TInvoiceController.java                |   56 
 ruoyi-system/src/main/resources/mapper/system/TFaultRepairMessageMapper.xml                   |    5 
 ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TFaultDescribeDicController.java       |    2 
 ruoyi-system/src/main/java/com/ruoyi/system/vo/RealTimeRentDataVO.java                        |   28 
 ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysUserServiceImpl.java              |   47 
 ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TContractController.java               |  638 +++++++-
 ruoyi-system/src/main/java/com/ruoyi/system/query/TFaultRepairMessageQuery.java               |    4 
 ruoyi-system/src/main/java/com/ruoyi/system/service/TInvoiceService.java                      |    3 
 ruoyi-system/src/main/java/com/ruoyi/system/service/impl/FlowListenerService.java             |  150 +
 ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TContractServiceImpl.java            |   50 
 ruoyi-system/src/main/java/com/ruoyi/system/model/TTenant.java                                |   26 
 ruoyi-system/src/main/java/com/ruoyi/system/query/TContractQuery.java                         |    3 
 ruoyi-system/src/main/java/com/ruoyi/system/query/TTenantQuery.java                           |    4 
 ruoyi-system/src/main/java/com/ruoyi/system/service/impl/StateTaskCenterServiceImpl.java      |    1 
 ruoyi-system/src/main/java/com/ruoyi/system/mapper/TTenantMapper.java                         |    7 
 ruoyi-system/src/main/java/com/ruoyi/system/model/TBusinessDept.java                          |   39 
 ruoyi-system/src/main/java/com/ruoyi/system/vo/ScreenRentRankVO.java                          |   21 
 ruoyi-system/src/main/resources/mapper/system/TBankFlowMapper.xml                             |    3 
 ruoyi-admin/src/main/java/com/ruoyi/web/controller/tool/TencentCosUtil.java                   |   30 
 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/dto/TContractDTO.java                             |    2 
 ruoyi-system/src/main/java/com/ruoyi/system/model/TRentalReturnRecord.java                    |   85 +
 ruoyi-system/src/main/java/com/ruoyi/system/model/TBill.java                                  |   37 
 ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TFlowManagementServiceImpl.java      |    4 
 ruoyi-system/src/main/java/com/ruoyi/system/vo/HouseMapDistributionVO.java                    |   35 
 ruoyi-system/src/main/resources/mapper/system/TBillMapper.xml                                 |  196 ++
 ruoyi-system/src/main/java/com/ruoyi/system/service/TBillService.java                         |   41 
 ruoyi-system/src/main/resources/mapper/system/TCheckAcceptRecordMapper.xml                    |    6 
 ruoyi-system/src/main/java/com/ruoyi/system/query/THouseQuery.java                            |    3 
 ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TStreetController.java                 |   50 
 ruoyi-system/src/main/java/com/ruoyi/system/dto/TbillSaveDto.java                             |    8 
 ruoyi-system/src/main/java/com/ruoyi/system/service/impl/THouseServiceImpl.java               |   29 
 ruoyi-system/src/main/resources/mapper/system/TRentalReturnRecordMapper.xml                   |   74 
 ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TTenantServiceImpl.java              |   13 
 ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/SysUser.java                   |   18 
 ruoyi-system/src/main/java/com/ruoyi/system/dto/TerminateContractDTO.java                     |    8 
 ruoyi-system/src/main/java/com/ruoyi/system/vo/RentalReturnRecordVO.java                      |   90 +
 ruoyi-system/src/main/java/com/ruoyi/system/query/TInvoiceQuery.java                          |    3 
 ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TBillServiceImpl.java                |  245 ++
 ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TStreetServiceImpl.java              |   20 
 ruoyi-system/src/main/java/com/ruoyi/system/vo/TenantCountTrendVO.java                        |   22 
 ruoyi-system/src/main/java/com/ruoyi/system/model/TInvoice.java                               |    4 
 ruoyi-admin/src/main/java/com/ruoyi/web/controller/tool/WordTemplateProcessor.java            |  174 +-
 ruoyi-system/src/main/java/com/ruoyi/system/model/TContract.java                              |   34 
 ruoyi-system/src/main/java/com/ruoyi/system/query/TCheckAcceptRecordQuery.java                |    4 
 ruoyi-system/src/main/java/com/ruoyi/system/query/TBankFlowQuery.java                         |    3 
 ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/BankOutController.java                 |  201 ++
 ruoyi-system/src/main/java/com/ruoyi/system/query/RentalReturnRecordQuery.java                |   51 
 ruoyi-common/src/main/java/com/ruoyi/common/utils/SecurityUtils.java                          |   21 
 ruoyi-system/src/main/resources/mapper/system/TTenantMapper.xml                               |   23 
 ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/THouseController.java                  |    3 
 ruoyi-system/src/main/java/com/ruoyi/system/query/TBillQuery.java                             |    6 
 ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/SysLoginService.java            |   30 
 ruoyi-system/src/main/java/com/ruoyi/system/service/ITRentalReturnRecordService.java          |   21 
 ruoyi-system/src/main/java/com/ruoyi/system/query/TCheckAcceptRecordAppletQuery.java          |    4 
 ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysUserController.java              |    4 
 ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TFaultAreaDicController.java           |    2 
 ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TDeptController.java                   |    2 
 ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TFlowManagementController.java         |    2 
 ruoyi-system/src/main/java/com/ruoyi/system/query/TFlowManagementQuery.java                   |    3 
 ruoyi-system/src/main/resources/mapper/system/TContractMapper.xml                             |   53 
 ruoyi-system/src/main/java/com/ruoyi/system/vo/ScreenRentIncomeTrendVO.java                   |   26 
 ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/SysFileController.java                 |   25 
 ruoyi-common/pom.xml                                                                          |    7 
 ruoyi-applet/src/main/java/com/ruoyi/web/controller/api/IndexController.java                  |   68 
 ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysRoleController.java              |    4 
 ruoyi-system/src/main/java/com/ruoyi/system/vo/YearQuarter.java                               |   31 
 ruoyi-system/src/main/resources/mapper/system/TBusinessDeptMapper.xml                         |    5 
 ruoyi-system/src/main/java/com/ruoyi/system/mapper/TBusinessDeptMapper.java                   |   16 
 121 files changed, 3,996 insertions(+), 613 deletions(-)

diff --git a/pom.xml b/pom.xml
index fbf1dea..b573aee 100644
--- a/pom.xml
+++ b/pom.xml
@@ -87,24 +87,18 @@
             </dependency>
 
             <!-- excel工具 -->
-           <dependency>
-               <groupId>org.apache.poi</groupId>
-               <artifactId>poi-ooxml</artifactId>
-               <version>${poi.version}</version>
-           </dependency>
+            <!-- Apache POI核心依赖 -->
+            <dependency>
+                <groupId>org.apache.poi</groupId>
+                <artifactId>poi</artifactId>
+                <version>3.17</version>
+            </dependency>
+            <dependency>
+                <groupId>org.apache.poi</groupId>
+                <artifactId>poi-ooxml</artifactId>
+                <version>3.17</version>
+            </dependency>
 
-
-           <dependency>
-               <groupId>org.apache.poi</groupId>
-               <artifactId>poi</artifactId>
-               <version>${poi.version}</version>
-           </dependency>
-
-           <dependency>
-               <groupId>org.apache.poi</groupId>
-               <artifactId>poi-ooxml-schemas</artifactId>
-               <version>${poi.version}</version>
-           </dependency>
 
             <!-- velocity代码生成使用模板 -->
             <dependency>
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/BankOutController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/BankOutController.java
index 56ef4cd..b45ecd7 100644
--- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/BankOutController.java
+++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/BankOutController.java
@@ -6,6 +6,7 @@
 import com.alibaba.fastjson.TypeReference;
 import com.ruoyi.common.constant.AmountConstant;
 import com.ruoyi.common.enums.BillTypeEnum;
+import com.ruoyi.common.exception.ServiceException;
 import com.ruoyi.common.utils.StringUtils;
 import com.ruoyi.system.dto.TBillDto;
 import com.ruoyi.system.model.TOrderBill;
@@ -13,9 +14,7 @@
 import com.ruoyi.system.service.TBillService;
 import com.ruoyi.system.service.TOrderBillService;
 import com.ruoyi.system.service.TPayOrderService;
-import com.taxi591.bankapi.dto.CovertPayBackResult;
-import com.taxi591.bankapi.dto.QueryBillRequest;
-import com.taxi591.bankapi.dto.QueryBillResponse;
+import com.taxi591.bankapi.dto.*;
 import com.taxi591.bankapi.service.BankService;
 import com.taxi591.bankapi.service.SignatureAndVerification;
 import lombok.extern.slf4j.Slf4j;
@@ -28,9 +27,14 @@
 
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
 import java.math.BigDecimal;
 import java.math.RoundingMode;
 import java.util.*;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 import java.util.stream.Collectors;
 import java.util.stream.Stream;
 
@@ -54,13 +58,188 @@
     @Autowired
     TPayOrderService payOrderService;
 
+    public static String getRequestBody(HttpServletRequest request)
+            throws IOException {
+        /** 读取httpbody内容 */
+        StringBuilder httpBody = new StringBuilder();
+        BufferedReader br = null;
+        try {
+            br = new BufferedReader(new InputStreamReader(
+                    request.getInputStream()));
+            String line = null;
+            while ((line = br.readLine()) != null) {
+                httpBody.append(line);
+            }
+        } catch (IOException ex) {
+            throw ex;
+        } finally {
+            if (br != null) {
+                try {
+                    br.close();
+                } catch (IOException ex) {
+                    ex.printStackTrace();
+                }
+            }
+        }
+        return httpBody.toString();
+    }
+
     @PostMapping(value = "payCallback")
-    public @ResponseBody String payCallback(HttpServletRequest request){
-        CovertPayBackResult result = bankService.covertPayCallBack(request, (billRequest) -> {
-            tBillService.completePay(billRequest);
-            return true;
-        });
-        return result.getBack();
+    public void payCallback(HttpServletRequest servletRequest,HttpServletResponse servletResponse){
+        String request = null;
+        String responseJson = null;
+        try {
+            log.info("--------进入getRequest4Sale----------------------------------");
+            // 接收报文
+            String requestContent = getRequestBody(servletRequest).trim();
+            String signatureString = requestContent.substring(0,
+                    requestContent.indexOf("||"));
+            log.info("-----ChargeBillController------------截取报文的signatureString:{}", signatureString);
+            String requestBody = requestContent.substring(signatureString
+                    .length() + 2);
+            log.info("-----ChargeBillController------------截取报文的requestBody:{}", requestBody);
+            //如果有双引号,则截取双引号内requestBody的内容
+            Pattern p=Pattern.compile("\"");
+            Matcher m=p.matcher(requestBody);
+            while(m.find()){
+                requestBody=requestBody.replace(m.group(), "");
+                log.info("-----ChargeBillController------如果有双引号,则截取后的requestBody:{}", requestBody);
+            }
+            //requestBody是base64加密后的数据,需解析出来
+            request = new String(
+                    com.alibaba.fastjson.util.Base64.decodeFast(requestBody));
+            log.info("-----ChargeBillController------------解析完成后的requestBody-------{}" + request);
+            ChargeBillRequest chargeBillRequest = JSON.parseObject(request,
+                    new TypeReference<ChargeBillRequest>() {
+                    });
+            boolean b = signatureAndVerification.read_cer_and_verify_sign(requestBody,
+                    signatureString);
+            if (!b){
+                throw new ServiceException("验签失败");
+            }
+            /** 销账报文重发次数,通过resendTimes此字段识别销账报文是否为重发的,0表示首次、1表示重发一次,2表示重发2次,最多重发3次*/
+            if(chargeBillRequest!=null && "0".equals(chargeBillRequest.getMessage().getInfo().getResendTimes())){
+                ChargeBillResponse chargeBillResponse = new ChargeBillResponse(
+                        chargeBillRequest);
+                ChargeBillResponse.Message respMessage = chargeBillResponse
+                        .getMessage();
+                ChargeBillResponse.Message.Head respHead = chargeBillResponse
+                        .getMessage().getHead();
+                ChargeBillResponse.Message.Info respInfo = chargeBillResponse
+                        .getMessage().getInfo();
+                respHead.setTransFlag("02");
+                respHead.setTimeStamp(DateUtil.format(new Date(),"yyyyMMddHHmmssSSS"));
+                // respHead.setChannel("MBNK");
+                respHead.setChannel(chargeBillRequest.getMessage().getHead()
+                        .getChannel());
+                // respHead.setTranCode("chargeBill");
+                respHead.setTransCode(chargeBillRequest.getMessage().getHead()
+                        .getTransCode());
+                respHead.setTransSeqNum(chargeBillRequest.getMessage().getHead()
+                        .getTransSeqNum());
+                //测试销账返回报文中,本来是销账成功的报文,但是不要送0000成功码   (JF190510134746710555这个流水号是在Demo的returnCode设置成null的时候产生的,流水状态为6;)
+
+                String epayCode = chargeBillRequest.getMessage().getInfo()
+                        .getEpayCode();
+                String traceNo = chargeBillRequest.getMessage().getInfo()
+                        .getTraceNo();
+                String numOpenMerchantOrder = chargeBillRequest.getMessage()
+                        .getInfo().getNumOpenMerchantOrder();
+                respInfo.setNumOpenMerchantOrder(numOpenMerchantOrder);
+                respInfo.setEpayCode(epayCode);
+                respInfo.setTraceNo(traceNo);
+
+                try{
+                    tBillService.completePay(chargeBillRequest);
+                    respHead.setReturnCode("0000");
+                    respHead.setReturnMessage("账单缴费成功");
+                }catch (Exception e){
+                    respHead.setReturnCode("1111");
+                    respHead.setReturnMessage("账单处理失败");
+                    log.error("支付第一次回调出现异常,{}",request,e);
+                }
+                //第一次处理失败,不退款
+                respInfo.setRefundFlag("false");
+                respMessage.setInfo(respInfo);
+                respMessage.setHead(respHead);
+                chargeBillResponse.setMessage(respMessage);
+                responseJson = JSON.toJSONString(chargeBillResponse);
+                //加签名
+                String signatrue = signatureAndVerification
+                        .signWhithsha1withrsa(responseJson);
+                log.info("-----ChargeBillController------------responseJson打印结果是(responseJson加密前):" + responseJson);
+                responseJson = signatrue + "||"
+                        + new String(Base64.encodeBase64(responseJson.getBytes("utf-8")));
+                log.info("-----ChargeBillController------------responseJson打印结果是(responseJson加密后):" + responseJson);
+                servletResponse.setCharacterEncoding("utf-8");
+                servletResponse.setContentType("text/plain");
+                servletResponse.getWriter().write(responseJson);
+            }else{
+                //销账报文重发次数,通过resendTimes此字段识别销账报文是否为重发的,0表示首次、1表示重发一次,2表示重发2次,最多重发3次
+                //商户端要注意销账重复通知的情况,要进行订单唯一性处理
+
+
+                ChargeBillResponse chargeBillResponse = new ChargeBillResponse(
+                        chargeBillRequest);
+                ChargeBillResponse.Message respMessage = chargeBillResponse
+                        .getMessage();
+                ChargeBillResponse.Message.Head respHead = chargeBillResponse
+                        .getMessage().getHead();
+                ChargeBillResponse.Message.Info respInfo = chargeBillResponse
+                        .getMessage().getInfo();
+                respHead.setTransFlag("02");
+                respHead.setTimeStamp(DateUtil.format(new Date(),"yyyyMMddHHmmssSSS"));
+                // respHead.setChannel("MBNK");
+                respHead.setChannel(chargeBillRequest.getMessage().getHead()
+                        .getChannel());
+                // respHead.setTranCode("chargeBill");
+                respHead.setTransCode(chargeBillRequest.getMessage().getHead()
+                        .getTransCode());
+                respHead.setTransSeqNum(chargeBillRequest.getMessage().getHead()
+                        .getTransSeqNum());
+                try{
+                    tBillService.completePay(chargeBillRequest);
+                    respHead.setReturnCode("0000");
+                    respHead.setReturnMessage("账单缴费成功");
+                }catch (Exception e){
+                    respHead.setReturnCode("1111");
+                    respHead.setReturnMessage("账单处理失败");
+                    log.error("支付第一次回调出现异常,{}",request,e);
+                }
+                // 再次推送未处理成功,则返回退款标志
+                if (!"0000".equals(respHead.getReturnCode())) {
+                    respInfo.setRefundFlag("true");
+                }
+                String epayCode = chargeBillRequest.getMessage().getInfo()
+                        .getEpayCode();
+                String traceNo = chargeBillRequest.getMessage().getInfo()
+                        .getTraceNo();
+                String numOpenMerchantOrder = chargeBillRequest.getMessage()
+                        .getInfo().getNumOpenMerchantOrder();
+                respInfo.setNumOpenMerchantOrder(numOpenMerchantOrder);
+                respInfo.setEpayCode(epayCode);
+                respInfo.setTraceNo(traceNo);
+
+                respMessage.setInfo(respInfo);
+                respMessage.setHead(respHead);
+                chargeBillResponse.setMessage(respMessage);
+                responseJson = JSON.toJSONString(chargeBillResponse);
+                //加签名
+                String signatrue = signatureAndVerification
+                        .signWhithsha1withrsa(responseJson);
+                log.info("-----ChargeBillController------------responseJson打印结果是(responseJson加密前):" + responseJson);
+                responseJson = signatrue + "||"
+                        + new String(Base64.encodeBase64(responseJson.getBytes("utf-8")));
+                log.info("-----ChargeBillController------------responseJson打印结果是(responseJson加密后):" + responseJson);
+                servletResponse.setCharacterEncoding("utf-8");
+                servletResponse.setContentType("text/plain");
+                servletResponse.getWriter().write(responseJson);
+
+            }
+
+        }catch (Exception e) {
+            log.error("处理支付回调发生异常:返回内容:{}",request,e);
+        }
     }
 
     @PostMapping(value = "queryBill")
@@ -99,8 +278,8 @@
                     .getInfo();
             //缴费账单子账单
             ArrayList<QueryBillResponse.Message.Info.Bill> respBills = new ArrayList<QueryBillResponse.Message.Info.Bill>();
-            ArrayList<QueryBillResponse.Message.Info.Bill.DescDetail> respDescDetail =
-                    new ArrayList<QueryBillResponse.Message.Info.Bill.DescDetail>();
+//            ArrayList<QueryBillResponse.Message.Info.Bill.DescDetail> respDescDetail =
+//                    new ArrayList<QueryBillResponse.Message.Info.Bill.DescDetail>();
             QueryBillResponse.Message.Info.Bill respBill = respInfo.new Bill();
             //缴费子商户账单
 //            ArrayList<QueryBillResponse.Message.Info.Bill.SplitSubMerInfo> splitSubMerInfos = new ArrayList<QueryBillResponse.Message.Info.Bill.SplitSubMerInfo>();
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
new file mode 100644
index 0000000..29e2b16
--- /dev/null
+++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/ScreenController.java
@@ -0,0 +1,260 @@
+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;
+import com.ruoyi.system.model.TStreet;
+import com.ruoyi.system.service.ITStreetService;
+import com.ruoyi.system.service.TBillService;
+import com.ruoyi.system.service.TContractService;
+import com.ruoyi.system.service.THouseService;
+import com.ruoyi.system.service.impl.ScreenService;
+import com.ruoyi.system.vo.*;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.RequiredArgsConstructor;
+import org.springframework.context.annotation.Lazy;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.math.BigDecimal;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.YearMonth;
+import java.time.format.DateTimeFormatter;
+import java.time.temporal.ChronoUnit;
+import java.util.*;
+import java.util.stream.Collectors;
+
+import static org.checkerframework.checker.units.qual.Prefix.one;
+
+/**
+ * @author mitao
+ * @date 2025/3/19
+ */
+@Api(tags = {"大屏相关接口"})
+@RestController
+@RequestMapping("/screen")
+@RequiredArgsConstructor(onConstructor_ = {@Lazy})
+public class ScreenController {
+    private final ScreenService screenService;
+    private final TContractService contractService;
+    private final THouseService houseService;
+    private final ITStreetService streetService;
+    private final TBillService billService;
+
+    @GetMapping("/statics-data")
+    @ApiOperation(value = "获取顶部统计数据")
+    public R<ScreenTopStaticsDataVO> getTopStaticsData() {
+        return R.ok(screenService.getTopStaticsData());
+    }
+
+    @GetMapping("/rent-rank")
+    @ApiOperation("区域租金排名")
+    public R<List<ScreenRentRankVO>> rentRank() {
+        return R.ok(screenService.streetRentRank());
+    }
+
+    @GetMapping("/rent-income-trend")
+    @ApiOperation("租金收入趋势")
+    public R<ScreenRentIncomeTrendVO> rentIncomeTrend() {
+        return R.ok(screenService.rentIncomeTrend());
+    }
+
+
+    @GetMapping("/getTenantCountTrend")
+    @ApiOperation(value = "租户数量趋势统计")
+    public R<List<TenantCountTrendVO>> getTenantCountTrend() {
+        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()
+                .map(THouse::getStreetId)
+                .collect(Collectors.toList());
+
+        // 获取街道信息
+        Map<String, String> streetMap = streetService.listByIds(streetIds).stream()
+                .collect(Collectors.toMap(TStreet::getId, TStreet::getStreetName));
+
+        // 转换为返回格式
+        List<RealTimeRentDataVO> result = houses.stream().map(house -> {
+            RealTimeRentDataVO vo = new RealTimeRentDataVO();
+            vo.setStreetName(streetMap.getOrDefault(house.getStreetId(), "未知"));
+            vo.setRoomName(house.getHouseName());
+            vo.setLeaseStatus(house.getLeaseStatus());
+            return vo;
+        }).collect(Collectors.toList());
+
+        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(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());
+            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);
+    }
+}
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/SysFileController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/SysFileController.java
index b213e84..097a86e 100644
--- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/SysFileController.java
+++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/SysFileController.java
@@ -1,8 +1,18 @@
 package com.ruoyi.web.controller.api;
 
 
+import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
+import org.apache.poi.util.Units;
+import org.apache.poi.xwpf.usermodel.*;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RestController;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
 
 /**
  * <p>
@@ -16,7 +26,22 @@
 @RequestMapping("/sys-file")
 public class SysFileController {
 
+    public static void main(String[] args) throws IOException, InvalidFormatException {
+        XWPFDocument document= new XWPFDocument();
+        FileOutputStream out = new FileOutputStream(new File("D:\\a.docx"));
+        //基本信息表格
+        XWPFParagraph pic = document.createParagraph();
+        XWPFRun picRun = pic.createRun();
+            picRun.addPicture(
+                    new FileInputStream("C:\\Users\\Admin\\Pictures\\Camera Roll\\1.jpg"),XWPFDocument.PICTURE_TYPE_JPEG,
+                    "C:\\Users\\Admin\\Pictures\\Camera Roll\\1.jpg",
+                    Units.toEMU(60),
+                    Units.toEMU(30)
+            );
 
+        document.write(out);
+        out.close();
+    }
 
 }
 
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TBankFlowController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TBankFlowController.java
index 07154a0..ceb85db 100644
--- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TBankFlowController.java
+++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TBankFlowController.java
@@ -6,6 +6,7 @@
 import com.alibaba.excel.event.AnalysisEventListener;
 import com.ruoyi.common.basic.PageInfo;
 import com.ruoyi.common.core.domain.R;
+import com.ruoyi.common.utils.SecurityUtils;
 import com.ruoyi.common.utils.StringUtils;
 import com.ruoyi.common.utils.WebUtils;
 import com.ruoyi.system.importExcel.TBankFlowImportExcel;
@@ -48,6 +49,7 @@
     @ApiOperation(value = "获取银行流水列表")
     @PostMapping("/list")
     public R<PageInfo<TBankFlow>> list(@RequestBody TBankFlowQuery query) {
+        query.setBusinessDeptId(SecurityUtils.getBusinessDeptId());
         return R.ok(flowService.pageList(query));
     }
 
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TBannerController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TBannerController.java
index 634f1ce..cbca2b9 100644
--- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TBannerController.java
+++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TBannerController.java
@@ -39,7 +39,7 @@
     /**
      * 获取轮播图管理列表
      */
-    @PreAuthorize("@ss.hasPermi('system:banner:list')")
+    @PreAuthorize("@ss.hasPermi('system:banner')")
     @ApiOperation(value = "获取轮播图分页列表")
     @PostMapping(value = "/pageList")
     public R<PageInfo<TBanner>> pageList(@RequestBody TBannerQuery query) {
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 a0340a0..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,25 +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.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>
@@ -45,19 +59,63 @@
     @Autowired
     TBillConfirmService tBillConfirmService;
 
+    @Autowired
+    TContractService contractService;
+
     @PreAuthorize("@ss.hasPermi('bill:list')")
     @PostMapping("list")
     @ApiOperation("分页查询账单列表")
     public R<PageInfo<TBillDto>> list(@RequestBody TBillQuery query){
+        query.setBusinessDeptId(SecurityUtils.getBusinessDeptId());
         PageInfo<TBillDto> pageInfo = tBillService.queryPage(query);
         return R.ok(pageInfo);
+    }
+
+    @ApiOperation("统计")
+    @PostMapping("statistics")
+    public R<BillStatisticsDto> statistics(@RequestBody TBillQuery query){
+        query.setBusinessDeptId(SecurityUtils.getBusinessDeptId());
+        BillStatisticsDto dto = tBillService.statistics(query);
+        return R.ok(dto);
+    }
+
+
+    @ApiOperation(value = "获取合同分页列表")
+    @PostMapping(value = "/contractList")
+    public R<PageInfo<TContract>> contractList(@RequestBody TContractQuery query) {
+        query.setBusinessDeptId(SecurityUtils.getBusinessDeptId());
+        return R.ok(contractService.queryPage(query));
     }
 
     @PreAuthorize("@ss.hasPermi('bill:list:addRent')")
     @PostMapping("add")
     @ApiOperation("新增账单")
     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();
+    }
+
+
+    @PreAuthorize("@ss.hasPermi('bill:list:editAmount')")
+    @PostMapping("editAmount")
+    @ApiOperation("修改账单金额")
+    public R editAmount(@Validated @RequestBody TbillSaveDto bill){
+        if (StringUtils.isEmpty(bill.getId())){
+            return R.fail("参数错误");
+        }
+        if (bill.getEditAmount().compareTo(BigDecimal.ZERO)==0){
+            return R.fail("调整金额不能为0");
+        }
+
+        tBillService.editAmount(bill);
         return R.ok();
     }
 
@@ -120,12 +178,7 @@
     }
 
 
-    @ApiOperation("统计")
-    @GetMapping("statistics")
-    public R<BillStatisticsDto> statistics(){
-        BillStatisticsDto dto = tBillService.statistics();
-        return R.ok(dto);
-    }
+
 
 
 
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TBusinessDeptController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TBusinessDeptController.java
new file mode 100644
index 0000000..2da5025
--- /dev/null
+++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TBusinessDeptController.java
@@ -0,0 +1,46 @@
+package com.ruoyi.web.controller.api;
+
+
+import com.ruoyi.common.core.domain.R;
+import com.ruoyi.system.model.TBusinessDept;
+import com.ruoyi.system.service.ITBusinessDeptService;
+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.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.List;
+
+/**
+ * <p>
+ * 营业部 前端控制器
+ * </p>
+ *
+ * @author mitao
+ * @since 2025-03-24
+ */
+@Api(tags = {"营业部相关接口"})
+@Validated
+@RestController
+@RequestMapping("/t-business-dept")
+@RequiredArgsConstructor(onConstructor_ = @Lazy)
+public class TBusinessDeptController {
+    private final ITBusinessDeptService businessDeptService;
+    @ApiOperation(value = "获取营业部列表")
+    @GetMapping("/list/type")
+    public R<List<TBusinessDept>> list(@ApiParam(name = "type",value = "是否添加人员使用 1:是 0:否",required = true) Integer type ) {
+        List<TBusinessDept> list = businessDeptService.list();
+        if (type == 1){
+            TBusinessDept tBusinessDept = new TBusinessDept();
+            tBusinessDept.setId("0");
+            tBusinessDept.setName("领导层");
+            list.add(0,tBusinessDept);
+        }
+        return R.ok(list);
+    }
+}
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 ab20a9b..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>
@@ -49,6 +44,8 @@
     @Autowired
     private TBillService billService;
     @Autowired
+    private TTenantService tenantService;
+    @Autowired
     public TCheckAcceptRecordController(TCheckAcceptRecordService checkAcceptRecordService, TContractService contractService, THouseService houseService) {
         this.checkAcceptRecordService = checkAcceptRecordService;
         this.contractService = contractService;
@@ -58,7 +55,7 @@
     /**
      * 获取验收记录管理列表
      */
-    @PreAuthorize("@ss.hasPermi('houseManage:check:list')")
+    @PreAuthorize("@ss.hasPermi('houseManage:check')")
     @ApiOperation(value = "获取验收记录分页列表")
     @PostMapping(value = "/pageList")
     public R<PageInfo<TCheckAcceptRecordVO>> pageList(@RequestBody TCheckAcceptRecordQuery query) {
@@ -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);
     }
 
@@ -113,10 +114,12 @@
             tBill.setContractId(dto.getContractId());
             tBill.setContractNumber(contract.getContractNumber());
             tBill.setPayableFeesMoney(dto.getCheckMoney());
+            tBill.setOutstandingMoney(dto.getCheckMoney());
             tBill.setPayableFeesTime(LocalDate.now());
             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 8a363c6..8e4acc0 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
@@ -3,6 +3,7 @@
 
 import cn.afterturn.easypoi.excel.ExcelExportUtil;
 import cn.afterturn.easypoi.excel.entity.ExportParams;
+import cn.hutool.core.bean.BeanUtil;
 import com.aizuda.bpm.engine.entity.FlwTask;
 import com.aizuda.bpm.mybatisplus.mapper.FlwTaskMapper;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
@@ -13,21 +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.utils.DateUtils;
-import com.ruoyi.common.utils.DictUtils;
-import com.ruoyi.common.utils.StringUtils;
-import com.ruoyi.common.utils.WebUtils;
+import com.ruoyi.common.exception.ServiceException;
+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;
@@ -43,16 +54,31 @@
 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.time.temporal.TemporalAdjusters;
+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>
@@ -80,6 +106,8 @@
     private StateProcessTemplateService stateProcessTemplateService;
     @Autowired
     private FlwTaskMapper flwTaskMapper;
+    @Autowired
+    private TTenantService tenantService;
 
     @ApiOperation(value = "获取合同分页列表")
     @PostMapping(value = "/contractList")
@@ -93,12 +121,23 @@
     @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("合同编号不可重复");
         }
         dto.setChangeRent(dto.getMonthRent());
         dto.setChangeTime(null);
+        //查询房产信息,获取所属营业部
+        THouse house = houseService.getById(dto.getHouseId());
+        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")){
             //发起合同新增审批
@@ -126,7 +165,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
+                    );
                 }
             }
         }
@@ -148,6 +193,12 @@
     @PreAuthorize("@ss.hasPermi('contract:list:edit')")
     public R<Boolean> updateContract(@Validated @RequestBody TContractDTO dto) {
         dto.setChangeTime(null);
+        //查询房产信息,获取所属营业部
+        THouse house = houseService.getById(dto.getHouseId());
+        if (Objects.isNull(house)) {
+            throw new ServiceException("房产信息不存在");
+        }
+        dto.setBusinessDeptId(house.getBusinessDeptId());
         contractService.updateById(dto);
         contractRentTypeService.remove(new LambdaQueryWrapper<TContractRentType>()
                 .eq(TContractRentType::getContractId,dto.getId()));
@@ -187,7 +238,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
+                    );
                 }
             }
         }
@@ -211,7 +268,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);
         }
@@ -231,8 +290,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);
@@ -254,7 +320,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");
@@ -262,11 +327,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")
@@ -295,55 +366,432 @@
         List<TContract> list = contractService.lambdaQuery().in(TContract::getId, dto.getIds()).list();
         List<String> res = new ArrayList<>();
         for (TContract contract : list) {
-            TBill firstBill = billService.lambdaQuery().eq(TBill::getContractId, contract.getId())
-                    .orderByDesc(TBill::getStartTime).last("limit 1").one();
-
-            THouse tHouse = houseService.getById(contract.getHouseId());
-            Map<String, Object> templateParam = new HashMap<>(5);
-            templateParam.put("${partyOneName}", contract.getPartyOneName());
-            templateParam.put("${partyTwoName}", contract.getPartyTwoName());
-            templateParam.put("${houseAddress}", tHouse.getHouseAddress());
-            templateParam.put("${houseArea}", tHouse.getHouseArea()+"m²");
-            long between = ChronoUnit.DAYS.between(contract.getStartTime(), contract.getStartPayTime())+1;
-            templateParam.put("${day}", between);
-            templateParam.put("${endTimeFree}", DateUtils.localDateTimeToStringYear(contract.getStartPayTime().plusDays(1)));
-            templateParam.put("${startPayTime}", DateUtils.localDateTimeToStringYear(contract.getStartPayTime()));
-            templateParam.put("${startTime}", DateUtils.localDateTimeToStringYear(contract.getStartTime()));
-            templateParam.put("${endTime}", DateUtils.localDateTimeToStringYear(contract.getEndTime()));
-            templateParam.put("${monthRent}", "¥"+contract.getMonthRent()+"元");
-            templateParam.put("${monthRentString}", "人民币"+NumberToChineseUtils.numberToChinese(contract.getMonthRent().setScale(2, BigDecimal.ROUND_DOWN).doubleValue()));
-            String totalYear = Objects.nonNull(contract.getTotalYear())?contract.getTotalYear().toString():"";
-            templateParam.put("${totalYear}", "¥"+totalYear+"元");
-            String totalYearString = StringUtils.isNotEmpty(totalYear)?NumberToChineseUtils.numberToChinese(contract.getTotalYear().setScale(2, BigDecimal.ROUND_DOWN).doubleValue()):"";
-            templateParam.put("${totalYearString}", "人民币"+totalYearString);
-            templateParam.put("${payType}", contract.getPayType().equals("1")?"月":contract.getPayType().equals("2")?"季":"年");
-            if(firstBill!=null){
-                templateParam.put("${firstRent}", "¥"+(firstBill.getPayableFeesMoney())+"元");
-            }else{
-                templateParam.put("${firstRent}", "");
-
-            }
-            templateParam.put("${firstRentString}", "人民币"+NumberToChineseUtils.numberToChinese((contract.getPayType().equals("1")?contract.getMonthRent():contract.getPayType().equals("2")?contract.getMonthRent().multiply(new BigDecimal("3")):contract.getMonthRent().multiply(new BigDecimal("12")).setScale(2,BigDecimal.ROUND_DOWN)).doubleValue()));
-            templateParam.put("${nextPayTime}", contract.getPayType().equals("1")?"月":contract.getPayType().equals("2")?"季":"年");
-            templateParam.put("${deposit}", "¥"+contract.getDeposit()+"元");
-            templateParam.put("${depositString}", NumberToChineseUtils.numberToChinese(contract.getDeposit().setScale(2, BigDecimal.ROUND_DOWN).doubleValue()));
-            templateParam.put("${partyOnePerson}", contract.getPartyOnePerson());
-            templateParam.put("${partyOnePhone}", contract.getPartyOnePhone());
-            templateParam.put("${partyTwoPerson}", contract.getPartyTwoPerson());
-            templateParam.put("${partyTwoPhone}", contract.getPartyTwoPhone());
-            // 验收时间
-            TCheckAcceptRecord tCheckAcceptRecord = checkAcceptRecordService.lambdaQuery().eq(TCheckAcceptRecord::getContractId, contract.getId()).last("limit 1").one();
-            if (tCheckAcceptRecord!=null &&tCheckAcceptRecord.getCheckTime()!=null ){
-                templateParam.put("${checkTime}", DateUtils.localDateTimeToStringYear(tCheckAcceptRecord.getCheckTime()));
-            }else{
-                templateParam.put("${checkTime}", "");
-
-            }
-            String url = wordUtil.generatePdf("/usr/local/project/file/", "1_yzj_租赁合同.docx", templateParam, "租赁合同", "/usr/local/project/file/");
+            String url = generateContract(contract,new TContractDTO());
             res.add(url);
         }
 
         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,TContractDTO dto) {
+        String templateFileName = "1_yzj_租赁合同_个人.docx";
+        String contractId = contract.getId();
+        TBill firstBill = null;
+        TCheckAcceptRecord tCheckAcceptRecord = null;
+
+        if (StringUtils.isNotEmpty(contractId)) {
+            firstBill = billService.lambdaQuery()
+                    .eq(TBill::getContractId, contractId)
+                    .eq(TBill::getBillType, 1)
+                    .orderByAsc(TBill::getStartTime)
+                    .ne(TBill::getManualAddition, DisabledEnum.YES.getCode())
+                    .last("limit 1")
+                    .one();
+            tCheckAcceptRecord = checkAcceptRecordService.lambdaQuery()
+                    .eq(TCheckAcceptRecord::getContractId, contractId)
+                    .last("limit 1")
+                    .one();
+        }
+
+        TTenant tenant = null;
+        THouse tHouse = null;
+        if (StringUtils.isNotEmpty(contract.getTenantId())) {
+            tenant = tenantService.getById(contract.getTenantId());
+            tHouse = houseService.getById(contract.getHouseId());
+        }
+
+        Map<String, Object> templateParam = new HashMap<>(5);
+        fill(templateParam, "contractNumber", contract.getContractNumber());
+        fill(templateParam, "partyOneName", contract.getPartyOneName());
+
+
+        if (Objects.nonNull(tenant)) {
+            fill(templateParam, "mailAddress", tenant.getMailAddress());
+            fill(templateParam, "idCard", tenant.getIdCard());
+            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.getTenantAttributes())
+                    && (tenant.getTenantAttributes().equals("2")
+                    || tenant.getTenantAttributes().equals("5")
+                    || tenant.getTenantAttributes().equals("7"))) {
+                fill(templateParam, "creditCode", tenant.getCreditCode());
+                fill(templateParam, "legalPerson", tenant.getLegalPerson());
+                templateFileName = "1_yzj_租赁合同_企业.docx";
+            }
+        }
+
+
+
+        if (Objects.nonNull(tHouse)) {
+            fill(templateParam, "houseAddress", tHouse.getHouseAddress());
+            fill(templateParam, "houseArea", tHouse.getHouseArea() + "m²");
+        }
+
+        // 日期相关参数处理
+        fill(templateParam, "remark", contract.getRemark());
+        fill(templateParam, "houseUseScope", StringUtils.isNotEmpty(contract.getHouseUseScope()) ? contract.getHouseUseScope() : "————");
+        fill(templateParam, "days", ChronoUnit.DAYS.between(
+                contract.getStartTime(), contract.getEndTime()));
+
+        long between = ChronoUnit.DAYS.between(
+                contract.getStartTime(), contract.getStartPayTime()) + 1;
+        fill(templateParam, "day", between);
+
+        // 财务相关参数处理
+        fill(templateParam, "endTimeFree", DateUtils.localDateTimeToStringYear(
+                contract.getStartPayTime().plusDays(1)));
+        fill(templateParam, "startPayTime", DateUtils.localDateTimeToStringYear(
+                contract.getStartPayTime()));
+        fill(templateParam, "startTime", DateUtils.localDateTimeToStringYear(
+                contract.getStartTime()));
+        fill(templateParam, "endTime", DateUtils.localDateTimeToStringYear(
+                contract.getEndTime()));
+
+        // 金额格式化处理
+        fill(templateParam, "monthRent", "¥" + contract.getMonthRent() + "元");
+        fill(templateParam, "monthRentString", "人民币" + NumberToChineseUtils.numberToChinese(
+                contract.getMonthRent().setScale(2, RoundingMode.DOWN).doubleValue()));
+
+        String totalYear = Objects.nonNull(contract.getTotalYear())
+                ? contract.getTotalYear().toString()
+                : "";
+        fill(templateParam, "totalYear", "¥" + totalYear + "元");
+
+        String totalYearString = StringUtils.isNotEmpty(totalYear)
+                ? NumberToChineseUtils.numberToChinese(
+                contract.getTotalYear().setScale(2, RoundingMode.DOWN).doubleValue())
+                : "";
+        fill(templateParam, "totalYearString", "人民币" + totalYearString);
+
+        // 支付类型处理
+        String payType = contract.getPayType().equals("1") ? "月"
+                : contract.getPayType().equals("2") ? "季"
+                : "年";
+        fill(templateParam, "payType", payType);
+        BigDecimal extracted = extracted(contract,dto);
+        System.out.println("金额========================="+extracted);
+        fill(templateParam, "firstRent", "¥" + extracted + "元");
+        // 其他财务字段
+        fill(templateParam, "firstRentString", "人民币" + NumberToChineseUtils.numberToChinese(extracted.doubleValue()));
+
+
+//        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()+"元");
+//
+//
+//        fill(templateParam, "firstRentString",
+//                "人民币"+NumberToChineseUtils.numberToChinese(
+//                        (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, "nextPayTime", payType);
+        fill(templateParam, "deposit", "¥" + contract.getDeposit() + "元");
+        fill(templateParam, "depositString", NumberToChineseUtils.numberToChinese(
+                contract.getDeposit().setScale(2, RoundingMode.DOWN).doubleValue()));
+
+        // 联系方式
+        fill(templateParam, "partyOnePerson", contract.getPartyOnePerson());
+        fill(templateParam, "partyOnePhone", contract.getPartyOnePhone());
+        fill(templateParam, "partyTwoPerson", contract.getPartyTwoPerson());
+        fill(templateParam, "partyTwoPhone", contract.getPartyTwoPhone());
+
+        // 验收时间处理
+        if (tCheckAcceptRecord != null && tCheckAcceptRecord.getCheckTime() != null) {
+            fill(templateParam, "checkTime", DateUtils.localDateTimeToStringYear(
+                    tCheckAcceptRecord.getCheckTime()));
+        } else {
+            fill(templateParam, "checkTime", "");
+        }
+
+        return wordUtil.generatePdf(
+                "/usr/local/project/file/",
+                templateFileName,
+                templateParam,
+                "租赁合同",
+                "/usr/local/project/file/");
+    }
+
+    private BigDecimal extracted(TContract contract,TContractDTO dto) {
+        TContractRentType tContractRentType = null;
+        if (contract.getIsIncreasing()){
+            tContractRentType = new TContractRentType();
+            tContractRentType.setContractId(contract.getId());
+            tContractRentType.setIncreasingDecreasing(dto.getIncreasingDecreasing());
+            tContractRentType.setIncreasingDecreasingType(dto.getIncreasingDecreasingType());
+            tContractRentType.setNumericalValue(dto.getNumericalValue());
+            tContractRentType.setChangeTime(dto.getChangeTime());
+            tContractRentType.setCycleTime(dto.getCycleTime());
+        }
+        // 生成第一笔账单
+        // 第一次应缴费日期
+
+        LocalDateTime firstPayTime = contract.getStartTime().plusDays(10).withHour(0).withMinute(0).withSecond(0);
+        TBill rentBill = new TBill();
+        rentBill.setContractId(contract.getId());
+        rentBill.setContractNumber(contract.getContractNumber());
+        rentBill.setPayableFeesTime(firstPayTime.toLocalDate());
+        rentBill.setPayFeesStatus("1");
+        rentBill.setBillType("1");
+        rentBill.setStartTime(contract.getStartPayTime());
+        if (contract.getPayType().equals("2")) {
+            // 季付 取3 6 9 12
+            int temp = 0 ;
+            if (contract.getStartPayTime().getMonthValue() <= 3 ) {
+                temp = 3;
+            } else if (contract.getStartPayTime().getMonthValue() <= 6) {
+                temp = 6;
+            } else if (contract.getStartPayTime().getMonthValue() <= 9) {
+                temp = 9;
+            } else {
+                temp = 12;
+            }
+            if (contract.getEndTime().isAfter(contract.getStartPayTime().withMonth(temp).with(TemporalAdjusters.lastDayOfMonth()))){
+                rentBill.setEndTime(contract.getStartPayTime().withMonth(temp).with(TemporalAdjusters.lastDayOfMonth()));
+            }else {
+                rentBill.setEndTime(contract.getEndTime());
+            }
+        } else if (contract.getPayType().equals("3")) {
+            if (contract.getEndTime().isAfter(contract.getStartPayTime().withMonth(12).with(TemporalAdjusters.lastDayOfMonth()))){
+                rentBill.setEndTime(contract.getStartPayTime().withMonth(12).with(TemporalAdjusters.lastDayOfMonth()));
+            }else {
+                rentBill.setEndTime(contract.getEndTime());
+            }
+        } else {
+            rentBill.setEndTime(rentBill.getStartTime().with(TemporalAdjusters.lastDayOfMonth()));
+        }
+        if (tContractRentType != null && rentBill.getEndTime().isAfter(tContractRentType.getChangeTime())){
+            long moneyDays = 0;
+            if (tContractRentType.getChangeTime().with(TemporalAdjusters.lastDayOfMonth()).isBefore(rentBill.getEndTime())){
+                moneyDays = ChronoUnit.DAYS.between(tContractRentType.getChangeTime(), tContractRentType.getChangeTime().with(TemporalAdjusters.lastDayOfMonth())) + 1;
+            }else{
+                moneyDays = ChronoUnit.DAYS.between(tContractRentType.getChangeTime(),rentBill.getEndTime()) + 1;
+            }
+            // 计算租金变动的天数
+            contract.setChangeTime(tContractRentType.getChangeTime());
+            // 递增递减的租金
+            BigDecimal contractRentTypeMoney = new BigDecimal("0");
+            // 不递增递减的租金
+            BigDecimal originalMoney = new BigDecimal("0");
+            switch (tContractRentType.getIncreasingDecreasingType()) {
+                case 1:
+                    switch (tContractRentType.getIncreasingDecreasing()) {
+                        case 1:
+                            contractRentTypeMoney = contractRentTypeMoney.add(contract.getChangeRent().multiply(new BigDecimal(100).add(tContractRentType.getNumericalValue())).divide(new BigDecimal(100), 2, BigDecimal.ROUND_DOWN).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays)).setScale(2, BigDecimal.ROUND_DOWN));
+                            // 变动后的每月租金
+                            contract.setChangeRent(contract.getChangeRent().multiply(new BigDecimal(100).add(tContractRentType.getNumericalValue())).divide(new BigDecimal(100), 2, BigDecimal.ROUND_DOWN));
+                            break;
+                        case 2:
+                            contractRentTypeMoney = contractRentTypeMoney.add(contract.getChangeRent().multiply((new BigDecimal(100).subtract(tContractRentType.getNumericalValue()))).divide(new BigDecimal(100), 2, BigDecimal.ROUND_DOWN).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays)).setScale(2, BigDecimal.ROUND_DOWN));
+                            contract.setChangeRent(contract.getChangeRent().multiply((new BigDecimal(100).subtract(tContractRentType.getNumericalValue()))).divide(new BigDecimal(100), 2, BigDecimal.ROUND_DOWN));
+                            break;
+                    }
+                    break;
+                case 2:
+                    switch (tContractRentType.getIncreasingDecreasing()) {
+                        case 1:
+                            contractRentTypeMoney = contractRentTypeMoney.add(contract.getChangeRent().add(tContractRentType.getNumericalValue())).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays)).setScale(2, BigDecimal.ROUND_DOWN);
+                            contract.setChangeRent(contract.getChangeRent().add(tContractRentType.getNumericalValue()));
+                            break;
+                        case 2:
+                            contractRentTypeMoney = contractRentTypeMoney.add(contract.getChangeRent().subtract(tContractRentType.getNumericalValue())).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays)).setScale(2, BigDecimal.ROUND_DOWN);
+                            contract.setChangeRent(contract.getChangeRent().subtract(tContractRentType.getNumericalValue()));
+                            break;
+                    }
+                    break;
+            }
+            LocalDateTime localDateTime = tContractRentType.getChangeTime().with(TemporalAdjusters.lastDayOfMonth()).plusDays(1);
+            while(true){
+                if (localDateTime.isBefore(rentBill.getEndTime())){
+                    if (localDateTime.plusMonths(1).isBefore(rentBill.getEndTime())){
+                        contractRentTypeMoney = contractRentTypeMoney.add(contract.getChangeRent());
+                        localDateTime = localDateTime.plusMonths(1);
+                    }else {
+                        break;
+                    }
+                }else{
+                    break;
+                }
+            }
+            long temp  = ChronoUnit.DAYS.between(localDateTime,rentBill.getEndTime()) + 1;
+            contractRentTypeMoney = contractRentTypeMoney.add(contract.getChangeRent().divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(temp)));
+            // 不需要涨租金的时间段
+            long originalDays = 0;
+            if (contract.getFirstPayTime().with(TemporalAdjusters.lastDayOfMonth()).isBefore(tContractRentType.getChangeTime())){
+                originalDays = Math.abs(ChronoUnit.DAYS.between(contract.getFirstPayTime(), contract.getFirstPayTime().with(TemporalAdjusters.lastDayOfMonth())));
+            }else{
+                originalDays = Math.abs(ChronoUnit.DAYS.between(contract.getFirstPayTime(), tContractRentType.getChangeTime()));
+            }
+            originalMoney = originalMoney.add(contract.getMonthRent().divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(originalDays)));
+            LocalDateTime originalTime = contract.getFirstPayTime().with(TemporalAdjusters.lastDayOfMonth()).plusDays(1);
+            while(true){
+                if (originalTime.isBefore(tContractRentType.getChangeTime())){
+                    if (originalTime.plusMonths(1).isBefore(tContractRentType.getChangeTime())){
+                        originalMoney = originalMoney.add(contract.getMonthRent());
+                        originalTime = originalTime.plusMonths(1);
+                    }else {
+                        break;
+                    }
+                }else{
+                    break;
+                }
+            }
+            long tempOriginal  = ChronoUnit.DAYS.between(localDateTime,tContractRentType.getChangeTime()) ;
+            originalMoney = originalMoney.add(contract.getChangeRent().divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(tempOriginal)));
+            rentBill.setPayableFeesMoney(contractRentTypeMoney.add(originalMoney));
+            rentBill.setOutstandingMoney(rentBill.getPayableFeesMoney());
+        } else {
+            // 不走递增递减
+            if (contract.getPayType().equals("2")){
+                BigDecimal money = new BigDecimal("0");
+                // 第一个月计算天
+                int dayOfMonth = rentBill.getStartTime().getDayOfMonth();
+                if (dayOfMonth == 1) {
+                    System.err.println("第一笔账单 1号计算整月:");
+                    money = money.add(contract.getMonthRent());
+                } else {
+                    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.toLocalDate().isBefore(rentBill.getEndTime().toLocalDate())){
+                            System.err.println("后续while 在结束之前");
+                            money = money.add(contract.getMonthRent());
+                        }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());
+                    }
+                    rentBill.setPayableFeesMoney(money);
+                    rentBill.setOutstandingMoney(rentBill.getPayableFeesMoney());
+                }
+            }else if (contract.getPayType().equals("3")){
+                BigDecimal money = new BigDecimal("0");
+                // 第一个月计算天
+                int dayOfMonth = rentBill.getStartTime().getDayOfMonth();
+                if (dayOfMonth == 1) {
+                    money = money.add(contract.getMonthRent());
+                } else {
+                    long allDays = ChronoUnit.DAYS.between(rentBill.getStartTime(), rentBill.getStartTime().with(TemporalAdjusters.lastDayOfMonth())) ;
+                    money =money.add(contract.getMonthRent().divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(allDays)));
+                }
+                // 后续
+                if (contract.getStartPayTime().getMonthValue()==12){
+                    rentBill.setPayableFeesMoney(money);
+                    rentBill.setOutstandingMoney(rentBill.getPayableFeesMoney());
+                }else{
+//                                LocalDateTime localDateTime = rentBill.getStartTime().plusMonths(1).with(TemporalAdjusters.lastDayOfMonth());
+                    LocalDateTime localDateTime = rentBill.getStartTime().with(TemporalAdjusters.lastDayOfMonth()).plusDays(1);
+                    while (true){
+                        if (localDateTime.isBefore(rentBill.getEndTime())){
+                            localDateTime = localDateTime.plusMonths(1);
+                            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())))));
+                            break;
+                        }
+                    }
+                    rentBill.setPayableFeesMoney(money);
+                    rentBill.setOutstandingMoney(rentBill.getPayableFeesMoney());
+                }
+            }else {
+                long allDays = ChronoUnit.DAYS.between(contract.getStartPayTime(), rentBill.getEndTime()) + 1;
+                int dayOfMonth = rentBill.getStartTime().getDayOfMonth();
+                if (dayOfMonth == 1) {
+                    rentBill.setPayableFeesMoney(contract.getMonthRent());
+                } else {
+                    rentBill.setPayableFeesMoney(contract.getMonthRent().divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(allDays)));
+                }
+                rentBill.setOutstandingMoney(rentBill.getPayableFeesMoney());
+            }
+        }
+        // 押金账单
+        TBill depositBill = new TBill();
+        depositBill.setContractId(contract.getId());
+        depositBill.setContractNumber(contract.getContractNumber());
+        depositBill.setPayableFeesMoney(contract.getDeposit());
+        depositBill.setOutstandingMoney(depositBill.getPayableFeesMoney());
+        depositBill.setStartTime(contract.getStartPayTime());
+        depositBill.setEndTime(contract.getEndTime());
+        depositBill.setPayableFeesTime(firstPayTime.toLocalDate());
+        depositBill.setPayFeesStatus("1");
+        depositBill.setBillType("2");
+        rentBill.setBusinessDeptId(contract.getBusinessDeptId());
+        depositBill.setBusinessDeptId(contract.getBusinessDeptId());
+        return rentBill.getPayableFeesMoney() ;
+
+    }
+
+
+    private void fill(Map<String, Object> templateParam, String key, Object value) {
+        if (StringUtils.isEmpty(key)){
+            throw new RuntimeException("key不能为空");
+        }
+        templateParam.put("${"+key+"}", value != null ? value : "");
+    }
+
+    /**
+     * 生成预览版合同附件
+     */
+    @ApiOperation(value = "生成预览版合同附件")
+    @PostMapping("/generateContractPreview")
+    public R<String> generateContractPreview(@RequestBody TContractDTO dto)
+    {
+        TContract contract = new TContract();
+        BeanUtil.copyProperties(dto,contract);
+        return R.ok(generateContract(contract,dto));
     }
 
     /**
@@ -353,10 +801,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());
@@ -366,33 +814,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/TDeptController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TDeptController.java
index 772f34c..c09648f 100644
--- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TDeptController.java
+++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TDeptController.java
@@ -51,7 +51,7 @@
     /**
      * 获取部门管理管理列表
      */
-    @PreAuthorize("@ss.hasPermi('system:department:list')")
+    @PreAuthorize("@ss.hasPermi('system:department')")
     @ApiOperation(value = "获取部门管理分页列表")
     @PostMapping(value = "/pageList")
     public R<PageInfo<DeptVO>> pageList(@RequestBody TDeptQuery query) {
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TFaultAreaDicController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TFaultAreaDicController.java
index 5225de3..061ca8e 100644
--- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TFaultAreaDicController.java
+++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TFaultAreaDicController.java
@@ -46,7 +46,7 @@
     /**
      * 获取故障区域管理列表
      */
-    @PreAuthorize("@ss.hasPermi('system:faultArea:list')")
+    @PreAuthorize("@ss.hasPermi('system:faultArea')")
     @ApiOperation(value = "获取故障区域分页列表")
     @PostMapping(value = "/pageList")
     public R<PageInfo<TFaultAreaDic>> pageList(@RequestBody TFaultAreaDicQuery query) {
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TFaultDescribeDicController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TFaultDescribeDicController.java
index d3530a7..9e1b211 100644
--- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TFaultDescribeDicController.java
+++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TFaultDescribeDicController.java
@@ -42,7 +42,7 @@
     /**
      * 获取故障描述管理列表
      */
-    @PreAuthorize("@ss.hasPermi('system:tag:list')")
+    @PreAuthorize("@ss.hasPermi('system:tag')")
     @ApiOperation(value = "获取故障描述分页列表")
     @PostMapping(value = "/pageList")
     public R<PageInfo<TFaultDescribeDicVO>> pageList(@RequestBody TFaultDescribeDicQuery query) {
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TFaultRepairMessageController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TFaultRepairMessageController.java
index 6365ad9..35a751a 100644
--- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TFaultRepairMessageController.java
+++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TFaultRepairMessageController.java
@@ -41,7 +41,7 @@
     /**
      * 获取报修管理列表
      */
-    @PreAuthorize("@ss.hasPermi('houseManage:acceptance:list')")
+    @PreAuthorize("@ss.hasPermi('houseManage:acceptance')")
     @ApiOperation(value = "获取报修分页列表")
     @PostMapping(value = "/pageList")
     public R<PageInfo<TFaultRepairMessageVO>> pageList(@RequestBody TFaultRepairMessageQuery query) {
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TFlowManagementController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TFlowManagementController.java
index 1da2389..32a11ec 100644
--- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TFlowManagementController.java
+++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TFlowManagementController.java
@@ -3,6 +3,7 @@
 
 import com.ruoyi.common.basic.PageInfo;
 import com.ruoyi.common.core.domain.R;
+import com.ruoyi.common.utils.SecurityUtils;
 import com.ruoyi.system.model.TFlowManagement;
 import com.ruoyi.system.query.TFlowManagementQuery;
 import com.ruoyi.system.service.TFlowManagementService;
@@ -36,6 +37,7 @@
     @ApiOperation(value = "获取流水列表")
     @PostMapping("/list")
     public R<PageInfo<TFlowManagement>> list(@RequestBody TFlowManagementQuery query) {
+        query.setBusinessDeptId(SecurityUtils.getBusinessDeptId());
         return R.ok(flowService.pageList(query));
     }
 
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/TInvoiceController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TInvoiceController.java
index 157d180..7ff668d 100644
--- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TInvoiceController.java
+++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TInvoiceController.java
@@ -5,6 +5,7 @@
 import com.ruoyi.common.basic.PageInfo;
 import com.ruoyi.common.core.domain.R;
 import com.ruoyi.common.enums.BusinessType;
+import com.ruoyi.common.utils.SecurityUtils;
 import com.ruoyi.common.utils.TencentMailUtil;
 import com.ruoyi.system.dto.TBillDto;
 import com.ruoyi.system.model.TBill;
@@ -12,10 +13,16 @@
 import com.ruoyi.system.query.TInvoiceQuery;
 import com.ruoyi.system.service.TBillService;
 import com.ruoyi.system.service.TInvoiceService;
+import com.ruoyi.web.controller.tool.TencentCosUtil;
 import io.swagger.annotations.ApiOperation;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.web.bind.annotation.*;
+
+import javax.servlet.http.HttpServletResponse;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.*;
 
 
 /**
@@ -33,10 +40,13 @@
     private TInvoiceService invoiceService;
     @Autowired
     TBillService tBillService;
+    @Autowired
+    TencentCosUtil tencentCosUtil;
     @PreAuthorize("@ss.hasPermi('invoice:list')")
     @ApiOperation(value = "获取开票列表")
     @PostMapping("/list")
     public R<PageInfo<TInvoice>> list(@RequestBody TInvoiceQuery query) {
+        query.setBusinessDeptId(SecurityUtils.getBusinessDeptId());
         return R.ok(invoiceService.pageList(query));
     }
 
@@ -58,7 +68,51 @@
     @PostMapping("/uploadVoucher")
     @PreAuthorize("@ss.hasPermi('invoice:list:payment')")
     public R<Boolean> uploadVoucher(@RequestBody TInvoiceQuery query) {
-        return R.ok(invoiceService.uploadVoucher(query));
+        String invoiceVoucher = query.getInvoiceVoucher();
+        String invoiceVoucherName = query.getInvoiceVoucherName();
+        if (invoiceVoucher == null || invoiceVoucherName == null) {
+            return R.fail("请上传发票文件");
+        }
+        String[] voucherUrls = invoiceVoucher.split(",");
+        String[] voucherNames = invoiceVoucherName.split(",");
+
+        // 确保两个数组长度一致
+        int length = Math.min(voucherUrls.length, voucherNames.length);
+        if (length == 0) {
+            return R.fail("请上传发票文件");
+        }
+        // 构建附件列表
+        List<Map<String, String>> attachments = new ArrayList<>(length);
+        for (int i = 0; i < length; i++) {
+            String voucherUrl = voucherUrls[i];
+            String fileName = voucherNames[i];
+            Map<String, String> attachment = new HashMap<>(2); // 初始容量为2,避免扩容
+            String tempDir = System.getProperty("java.io.tmpdir");
+            Path filePath = Paths.get(tempDir, "invoice");
+            // 保存到临时目录
+            tencentCosUtil.download(voucherUrl,filePath.toString(),fileName);
+
+            attachment.put("filePath", filePath.toString());
+            attachment.put("fileName", fileName);
+            attachments.add(attachment);
+        }
+        return R.ok(invoiceService.uploadVoucher(query,attachments));
     }
 }
 
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
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/TStreetController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TStreetController.java
new file mode 100644
index 0000000..3f34a19
--- /dev/null
+++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TStreetController.java
@@ -0,0 +1,50 @@
+package com.ruoyi.web.controller.api;
+
+
+import com.google.common.collect.Lists;
+import com.ruoyi.common.core.domain.R;
+import com.ruoyi.system.model.TStreet;
+import com.ruoyi.system.service.ITStreetService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.RequiredArgsConstructor;
+import org.springframework.context.annotation.Lazy;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * <p>
+ * 街道 前端控制器
+ * </p>
+ *
+ * @author mitao
+ * @since 2025-03-19
+ */
+@Api(tags = {"街道相关接口"})
+@RestController
+@RequestMapping("/t-street")
+@RequiredArgsConstructor(onConstructor_ = {@Lazy})
+public class TStreetController {
+    private final ITStreetService tStreetService;
+
+    @GetMapping("/list")
+    @ApiOperation(value = "获取街道列表")
+    public R<List<TStreet>> list() {
+        return R.ok(tStreetService.list());
+    }
+    @GetMapping("/init")
+    @ApiOperation(value = "初始化街道列表")
+    public R<?> init(){
+        ArrayList<String> strings = Lists.newArrayList("八廓街道", "吉日街道", "布达拉宫广场街道", "公德林街道", "扎细街道", "纳金街道", "娘热街道", "金珠西路街道", "堆龙德庆区东嘎街道", "两岛街道", "柳梧新区柳梧乡", "色拉街道", "蔡公堂街道", "娘热路街道", "夺底街道", "纳如街道");
+        strings.forEach(streetName->{
+            TStreet tStreet = new TStreet();
+            tStreet.setStreetName(streetName);
+            tStreetService.save(tStreet);
+        });
+        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/system/SysRoleController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysRoleController.java
index 494ff97..5c53a61 100644
--- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysRoleController.java
+++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysRoleController.java
@@ -62,7 +62,7 @@
     @Autowired
     private ISysMenuService menuService;
 
-    @PreAuthorize("@ss.hasPermi('system:role:list')")
+    @PreAuthorize("@ss.hasPermi('system:role')")
     @ApiOperation(value = "角色列表")
     @PostMapping("/list")
     public AjaxResult list(@RequestBody SysRoleQuery query)
@@ -71,7 +71,7 @@
         return AjaxResult.success(list);
     }
 
-    @PreAuthorize("@ss.hasPermi('system:role:list')")
+    @PreAuthorize("@ss.hasPermi('system:role')")
     @ApiOperation(value = "角色列表不分页")
     @PostMapping("/listNotPage")
     public AjaxResult list()
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysUserController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysUserController.java
index b44867f..53ed772 100644
--- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysUserController.java
+++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysUserController.java
@@ -22,6 +22,7 @@
 import io.swagger.annotations.ApiOperation;
 import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.util.CollectionUtils;
 import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.*;
@@ -56,6 +57,7 @@
      */
     @ApiOperation(value = "获取用户列表")
     @PostMapping("/list")
+    @PreAuthorize("@ss.hasPermi('system:user')")
     public AjaxResult list(@RequestBody SysUserQuery query)
     {
         PageInfo<SysUserVO> list = userService.pageList(query);
@@ -64,6 +66,8 @@
 
     @ApiOperation(value = "获取用户列表-不分页")
     @PostMapping("/listNotPage")
+    @PreAuthorize("@ss.hasPermi('system:user')")
+
     public AjaxResult listNotPage()
     {
         List<SysUser> list = userService.selectList();
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/tool/TencentCosUtil.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/tool/TencentCosUtil.java
index 3133f3a..9a9ac21 100644
--- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/tool/TencentCosUtil.java
+++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/tool/TencentCosUtil.java
@@ -27,6 +27,11 @@
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
+import java.net.URL;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.StandardCopyOption;
 import java.util.Base64;
 import java.util.Date;
 import java.util.UUID;
@@ -256,4 +261,29 @@
     }
 
 
+    /**
+     * 将文件下载到指定目录
+     * @param fileUrl
+     * @param saveDir
+     * @param fileName
+     * @throws IOException
+     */
+    public void download(String fileUrl, String saveDir, String fileName){
+        fileUrl = fileUrl.replace(cosConfig.getRootSrc(), "");
+        // 下载文件并获取输入流
+        COSObject object = cosClient.getObject(cosConfig.getBucketName(),fileUrl);
+        try (
+                InputStream in = object.getObjectContent();
+                ){
+            Path targetPath = Paths.get(saveDir, fileName);
+            // 确保目录存在
+            Files.createDirectories(targetPath.getParent());
+            // 将文件保存到目标路径
+            Files.copy(in, targetPath, StandardCopyOption.REPLACE_EXISTING);
+        }catch (IOException e){
+            log.error("读取cos图片发生异常", e);
+        }
+    }
+
+
 }
\ No newline at end of file
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..7fb9d31 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,17 +5,22 @@
 import freemarker.template.Template;
 import freemarker.template.TemplateException;
 import lombok.extern.slf4j.Slf4j;
-
+import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
+import org.apache.poi.util.Units;
 import org.apache.poi.xwpf.usermodel.*;
 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.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.*;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
@@ -174,10 +179,19 @@
             System.setProperty("file.encoding", "UTF-8");
 
             XWPFDocument document = new XWPFDocument(fis);
-
+            XWPFParagraph pic = document.createParagraph();
+            XWPFRun picRun = pic.createRun();
+            Map<String, Object> dataMap1 = new HashMap<>();
+//            dataMap.put("${picture}", picRun.addPicture(
+//                    new FileInputStream("/usr/local/project/file/1.jpg"), XWPFDocument.PICTURE_TYPE_JPEG,
+//                    "/usr/local/project/file/1.jpg",
+//                    Units.toEMU(60),
+//                    Units.toEMU(30)
+//            ));
             // 处理段落
             for (XWPFParagraph paragraph : document.getParagraphs()) {
                 replaceParagraph(paragraph, dataMap);
+                replaceParagraph1(paragraph);
             }
 
             // 处理表格
@@ -266,6 +280,19 @@
             replaceRunRange(paragraph, info);
         }
     }
+    private static void replaceParagraph1(XWPFParagraph paragraph) throws IOException, InvalidFormatException {
+        List<XWPFRun> runs = paragraph.getRuns();
+        for (XWPFRun r : runs) {
+            String text = r.getText(0);
+            if (text != null && text.contains("{{image}}")) {
+                r.setText("", 0);
+                FileInputStream is = new FileInputStream("/usr/local/project/file/1.jpg");
+                r.addBreak();
+                r.addPicture(is, XWPFDocument.PICTURE_TYPE_JPEG, "/usr/local/project/file/1.jpg", Units.toEMU(60), Units.toEMU(30));
+                is.close();
+            }
+        }
+    }
 
     private static String processPlaceholder(String text, Map<String, Object> dataMap) {
         // 处理括号内的占位符
diff --git a/ruoyi-admin/src/main/resources/application-test.yml b/ruoyi-admin/src/main/resources/application-test.yml
index 7e3b361..14887f4 100644
--- a/ruoyi-admin/src/main/resources/application-test.yml
+++ b/ruoyi-admin/src/main/resources/application-test.yml
@@ -162,7 +162,7 @@
   # 令牌密钥
   secret: abcdefghijklmnopqrstuvwxyz
   # 令牌有效期(默认30分钟)
-  expireTime: 1
+  expireTime: 120
 
 mybatis-plus:
   # 此处在多数据源中生效
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..6e8189f 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
@@ -2,7 +2,6 @@
 
 
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
-import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.ruoyi.common.annotation.Log;
 import com.ruoyi.common.basic.PageInfo;
 import com.ruoyi.common.constant.DictConstants;
@@ -15,23 +14,53 @@
 import com.ruoyi.common.utils.DictUtils;
 import com.ruoyi.framework.web.service.TokenService;
 import com.ruoyi.system.bo.ProcessTaskListBO;
-import com.ruoyi.system.dto.TBillDto;
-import com.ruoyi.system.dto.TInvoiceDTO;
-import com.ruoyi.system.model.*;
-import com.ruoyi.system.query.*;
-import com.ruoyi.system.service.*;
-import com.ruoyi.system.vo.*;
+import com.ruoyi.system.model.TBanner;
+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.TFaultRepairMessage;
+import com.ruoyi.system.model.THouse;
+import com.ruoyi.system.model.TTenant;
+import com.ruoyi.system.query.TBannerQuery;
+import com.ruoyi.system.query.TBillAppletQuery;
+import com.ruoyi.system.query.TCheckAcceptRecordAppletQuery;
+import com.ruoyi.system.query.TExamineAppletQuery;
+import com.ruoyi.system.query.TFaultRepairMessageAppletQuery;
+import com.ruoyi.system.query.TTenantAppletQuery;
+import com.ruoyi.system.service.ISysUserService;
+import com.ruoyi.system.service.StateProcessTemplateService;
+import com.ruoyi.system.service.TBannerService;
+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.TFaultRepairMessageService;
+import com.ruoyi.system.service.THouseService;
+import com.ruoyi.system.service.TTenantService;
+import com.ruoyi.system.vo.ExamineVO;
+import com.ruoyi.system.vo.MyHouseVO;
+import com.ruoyi.system.vo.MyToDoVO;
+import com.ruoyi.system.vo.PayListVO;
+import com.ruoyi.system.vo.ProcessTaskListVO;
+import com.ruoyi.system.vo.TBillVO;
+import com.ruoyi.system.vo.TCheckAcceptRecordVO;
+import com.ruoyi.system.vo.TContractVO;
+import com.ruoyi.system.vo.TFaultRepairMessageVO;
+import com.ruoyi.system.vo.TenantVO;
 import com.ruoyi.web.controller.tool.MyFileUtil;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
-import jdk.nashorn.internal.parser.Token;
 import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.util.CollectionUtils;
-import org.springframework.util.StringUtils;
 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 org.springframework.web.multipart.MultipartFile;
 
 import java.io.File;
@@ -202,6 +231,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) {
@@ -257,6 +287,8 @@
     @ApiOperation(value = "管理员-房屋验收单列表")
     @PostMapping(value = "/admin/houseCheck")
     public R<PageInfo<TCheckAcceptRecordVO>> houseCheck(@RequestBody TCheckAcceptRecordAppletQuery query) {
+        LoginUserApplet loginUserApplet = tokenService.getLoginUserApplet();
+        query.setSysUserId(loginUserApplet.getUserId());
         return R.ok(checkAcceptRecordService.pageListApplet(query));
     }
 
@@ -295,6 +327,20 @@
         // 添加验收记录
         dto.setCheckPerson(tokenService.getLoginUser().getUser().getNickName());
         checkAcceptRecordService.updateById(dto);
+        TCheckAcceptRecord checkAcceptRecord = checkAcceptRecordService.getById(dto.getId());
+        TContract contract = contractService.getById(checkAcceptRecord.getContractId());
+        // 添加账单
+        TBill tBill = new TBill();
+        tBill.setContractId(checkAcceptRecord.getContractId());
+        tBill.setContractNumber(contract.getContractNumber());
+        tBill.setPayableFeesMoney(dto.getCheckMoney());
+        tBill.setPayableFeesTime(LocalDate.now());
+        tBill.setPayFeesStatus("1");
+        tBill.setBillType("4");
+        tBill.setOverDays(0);
+        tBill.setBusinessDeptId(contract.getBusinessDeptId());
+        tBill.setOutstandingMoney(dto.getCheckMoney());
+        billService.save(tBill);
         return R.ok();
     }
     /**
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 2ab98bb..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>
@@ -64,7 +65,7 @@
     public R<PageInfo<TBillDto>> list(@RequestBody TBillQuery query){
         String userId = tokenService.getLoginUserApplet().getUserId();
         query.setUserId(userId);
-        PageInfo<TBillDto> pageInfo = tBillService.queryPage(query);
+        PageInfo<TBillDto> pageInfo = tBillService.queryPageForApplet(query);
         return R.ok(pageInfo);
     }
 
@@ -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/pom.xml b/ruoyi-common/pom.xml
index 16aa070..99ab005 100644
--- a/ruoyi-common/pom.xml
+++ b/ruoyi-common/pom.xml
@@ -144,10 +144,15 @@
             <artifactId>javax.servlet-api</artifactId>
         </dependency>
         <!--mybatis-plus-->
+<!--        <dependency>-->
+<!--            <groupId>com.baomidou</groupId>-->
+<!--            <artifactId>mybatis-plus-boot-starter</artifactId>-->
+<!--            <version>3.5.2</version>-->
+<!--        </dependency>-->
         <dependency>
             <groupId>com.baomidou</groupId>
             <artifactId>mybatis-plus-boot-starter</artifactId>
-            <version>3.5.2</version>
+            <version>3.5.7</version>
         </dependency>
         <!--lombok-->
         <dependency>
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/SysUser.java b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/SysUser.java
index 9a6eea2..246a26d 100644
--- a/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/SysUser.java
+++ b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/SysUser.java
@@ -1,18 +1,18 @@
 package com.ruoyi.common.core.domain.entity;
 
-import java.util.Date;
-import java.util.List;
-import javax.validation.constraints.*;
-
 import com.baomidou.mybatisplus.annotation.TableField;
-import com.baomidou.mybatisplus.annotation.TableName;
 import com.fasterxml.jackson.annotation.JsonFormat;
+import com.ruoyi.common.core.domain.BaseEntity;
+import com.ruoyi.common.xss.Xss;
 import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
 import org.apache.commons.lang3.builder.ToStringBuilder;
 import org.apache.commons.lang3.builder.ToStringStyle;
-import com.ruoyi.common.core.domain.BaseEntity;
-import com.ruoyi.common.xss.Xss;
+
+import javax.validation.constraints.Email;
+import javax.validation.constraints.Size;
+import java.util.Date;
+import java.util.List;
 
 /**
  * 用户对象 sys_user
@@ -131,6 +131,10 @@
     @TableField(exist = false)
     private List<String> deptIds;
 
+    @ApiModelProperty(value = "营业部id")
+    @TableField("business_dept_id")
+    private String businessDeptId;
+
     public String getRoleName() {
         return roleName;
     }
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-common/src/main/java/com/ruoyi/common/utils/DateUtils.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/DateUtils.java
index 3df99a9..cd58196 100644
--- a/ruoyi-common/src/main/java/com/ruoyi/common/utils/DateUtils.java
+++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/DateUtils.java
@@ -1,16 +1,21 @@
 package com.ruoyi.common.utils;
 
+import org.apache.commons.lang3.time.DateFormatUtils;
+
 import java.lang.management.ManagementFactory;
 import java.text.ParseException;
 import java.text.SimpleDateFormat;
-import java.time.*;
+import java.time.Instant;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.LocalTime;
+import java.time.ZoneId;
+import java.time.ZonedDateTime;
 import java.time.format.DateTimeFormatter;
 import java.util.Calendar;
 import java.util.Date;
 import java.util.HashMap;
 import java.util.Map;
-
-import org.apache.commons.lang3.time.DateFormatUtils;
 
 /**
  * 时间工具类
@@ -267,7 +272,7 @@
         cal.set(Calendar.YEAR, year);
         cal.set(Calendar.MONTH, startMonth);
         cal.set(Calendar.DAY_OF_MONTH, 1);
-        cal.set(Calendar.HOUR, 0);
+        cal.set(Calendar.HOUR_OF_DAY, 0);
         cal.set(Calendar.MINUTE, 0);
         cal.set(Calendar.SECOND, 0);
         Date first = cal.getTime();
@@ -279,9 +284,9 @@
         cal.set(Calendar.YEAR, year);
         cal.set(Calendar.MONTH, lastMonth);
         cal.set(Calendar.DAY_OF_MONTH, cal.getActualMaximum(Calendar.DAY_OF_MONTH));
-        cal.set(Calendar.HOUR, 0);
-        cal.set(Calendar.MINUTE, 0);
-        cal.set(Calendar.SECOND, 0);
+        cal.set(Calendar.HOUR_OF_DAY, 23);
+        cal.set(Calendar.MINUTE, 59);
+        cal.set(Calendar.SECOND, 59);
         Date last = cal.getTime();
         map.put("last", last);
 
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/SecurityUtils.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/SecurityUtils.java
index adea656..6d0ea4a 100644
--- a/ruoyi-common/src/main/java/com/ruoyi/common/utils/SecurityUtils.java
+++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/SecurityUtils.java
@@ -1,6 +1,7 @@
 package com.ruoyi.common.utils;
 
 import com.ruoyi.common.core.domain.model.LoginUserApplet;
+import lombok.extern.slf4j.Slf4j;
 import org.springframework.security.core.Authentication;
 import org.springframework.security.core.context.SecurityContextHolder;
 import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
@@ -13,6 +14,7 @@
  * 
  * @author ruoyi
  */
+@Slf4j
 public class SecurityUtils
 {
     /**
@@ -44,7 +46,20 @@
             throw new ServiceException("获取部门ID异常", HttpStatus.UNAUTHORIZED);
         }
     }
-    
+    /**
+     * 获取营业部ID
+     **/
+    public static String getBusinessDeptId()
+    {
+        try
+        {
+            return getLoginUser().getUser().getBusinessDeptId();
+        }
+        catch (Exception e)
+        {
+            throw new ServiceException("获取营业部ID异常", HttpStatus.UNAUTHORIZED);
+        }
+    }
     /**
      * 获取用户账户
      **/
@@ -56,8 +71,10 @@
         }
         catch (Exception e)
         {
-            throw new ServiceException("获取用户账户异常", HttpStatus.UNAUTHORIZED);
+            log.error("获取用户信息发生异常",e);
+//            throw new ServiceException("获取用户账户异常", HttpStatus.UNAUTHORIZED);
         }
+        return "";
     }
     /**
      * 获取用户账户小程序
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/TencentMailUtil.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/TencentMailUtil.java
index a6e40ba..5e7ea1b 100644
--- a/ruoyi-common/src/main/java/com/ruoyi/common/utils/TencentMailUtil.java
+++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/TencentMailUtil.java
@@ -8,17 +8,17 @@
 
 import javax.activation.DataHandler;
 import javax.activation.FileDataSource;
-import java.net.URLEncoder;
-import javax.activation.URLDataSource;
+import javax.annotation.Resource;
 import javax.mail.*;
 import javax.mail.internet.*;
+import java.io.IOException;
 import java.io.UnsupportedEncodingException;
 import java.net.MalformedURLException;
-import java.net.URL;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-import java.util.Properties;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.*;
 import java.util.concurrent.CompletableFuture;
 
 @Component
@@ -132,14 +132,44 @@
             // 设置邮件标题
             message.setSubject("发票");
             // 创建邮件内容
-            Multipart multipart = createMultipart(list);
+            Multipart multipart = new MimeMultipart();
+            // 添加文本消息部分
+            BodyPart messageBodyPart = new MimeBodyPart();
+            messageBodyPart.setHeader("Content-Type", "text/plain;charset=utf-8");
+            messageBodyPart.setContent("您在小程序提交的开票申请已开票成功,请查看附件内容","text/html;charset=UTF-8");
+            multipart.addBodyPart(messageBodyPart);
+            List<Path> tempFilePath = new ArrayList<>();
+            // 添加附件部分
+            for (Map<String, String> map : list) {
+                messageBodyPart = new MimeBodyPart();
+                String filePath = map.get("filePath");
+                String fileName = map.get("fileName");
+                Path path = Paths.get(filePath, fileName);
+                tempFilePath.add(path);
+                FileDataSource source = new FileDataSource(path.toString());
+                messageBodyPart.setDataHandler(new DataHandler(source));
+                // String filenameEncode = MimeUtility.encodeText(fileName, "UTF-8", "base64");
+                // String encodedFileName = Base64.getEncoder().encodeToString(fileName.getBytes(StandardCharsets.UTF_8));
+                // String filenameEncode = MimeUtility.encodeText(encodedFileName);
+                messageBodyPart.setFileName(fileName);
+                messageBodyPart.setHeader("Content-Transfer-Encoding", "base64");
+                messageBodyPart.setHeader("Content-Disposition", "attachment");
+                messageBodyPart.setHeader("Content-Type", "application/octet-stream;name=\"" + fileName + "\"");
+                multipart.addBodyPart(messageBodyPart);
+            }
             // 设置邮件内容
             message.setContent(multipart);
             // 发送邮件
             Transport.send(message);
+            // 删除临时目录里面的文件
+            for (Path path : tempFilePath) {
+                Files.deleteIfExists(path);
+            }
         } catch (MessagingException | UnsupportedEncodingException | MalformedURLException e) {
             log.error("发送邮件发生异常", e);
             throw new ServiceException("发送邮件失败, 请检查");
+        } catch (IOException e) {
+            throw new RuntimeException("文件下载发生异常");
         }
     }
 
@@ -167,31 +197,6 @@
                 return new PasswordAuthentication(userName, password);
             }
         };
-    }
-
-    private Multipart createMultipart(List<Map<String, String>> list) throws MessagingException, UnsupportedEncodingException, MalformedURLException {
-        Multipart multipart = new MimeMultipart();
-        // 添加文本消息部分
-        BodyPart messageBodyPart = new MimeBodyPart();
-        messageBodyPart.setHeader("Content-Type", "text/plain;charset=utf-8");
-        messageBodyPart.setContent("您在小程序提交的开票申请已开票成功,请查看附件内容","text/html;charset=UTF-8");
-        multipart.addBodyPart(messageBodyPart);
-        // 添加附件部分
-        for (Map<String, String> map : list) {
-            messageBodyPart = new MimeBodyPart();
-            String url = map.get("url");
-            String fileName = map.get("fileName");
-            URLDataSource source = new URLDataSource(new URL(url));
-            messageBodyPart.setDataHandler(new DataHandler(source));
-            String filenameEncode = MimeUtility.encodeText(fileName, "UTF-8", "base64");
-            messageBodyPart.setFileName(filenameEncode);
-            messageBodyPart.setHeader("Content-Transfer-Encoding", "base64");
-            messageBodyPart.setHeader("Content-Disposition", "attachment");
-            messageBodyPart.setHeader("Content-Type", "application/octet-stream;name=\"" + filenameEncode + "\"");
-            multipart.addBodyPart(messageBodyPart);
-        }
-
-        return multipart;
     }
 
    // public static void main(String[] args) throws UnsupportedEncodingException {
diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/SysLoginService.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/SysLoginService.java
index e54ccc2..c7302b8 100644
--- a/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/SysLoginService.java
+++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/SysLoginService.java
@@ -1,27 +1,15 @@
 package com.ruoyi.framework.web.service;
 
-import javax.annotation.Resource;
-
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
-import com.ruoyi.common.core.domain.entity.TTenantResp;
-import com.ruoyi.common.core.domain.model.LoginUserApplet;
-import com.ruoyi.common.enums.UserStatus;
-import com.ruoyi.system.model.TTenant;
-import com.ruoyi.system.service.TTenantService;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.beans.BeanUtils;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.security.authentication.AuthenticationManager;
-import org.springframework.security.authentication.BadCredentialsException;
-import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
-import org.springframework.security.core.Authentication;
-import org.springframework.stereotype.Component;
 import com.ruoyi.common.constant.CacheConstants;
 import com.ruoyi.common.constant.Constants;
 import com.ruoyi.common.constant.UserConstants;
 import com.ruoyi.common.core.domain.entity.SysUser;
+import com.ruoyi.common.core.domain.entity.TTenantResp;
 import com.ruoyi.common.core.domain.model.LoginUser;
+import com.ruoyi.common.core.domain.model.LoginUserApplet;
 import com.ruoyi.common.core.redis.RedisCache;
+import com.ruoyi.common.enums.UserStatus;
 import com.ruoyi.common.exception.ServiceException;
 import com.ruoyi.common.exception.user.BlackListException;
 import com.ruoyi.common.exception.user.CaptchaException;
@@ -35,8 +23,20 @@
 import com.ruoyi.framework.manager.AsyncManager;
 import com.ruoyi.framework.manager.factory.AsyncFactory;
 import com.ruoyi.framework.security.context.AuthenticationContextHolder;
+import com.ruoyi.system.model.TTenant;
 import com.ruoyi.system.service.ISysConfigService;
 import com.ruoyi.system.service.ISysUserService;
+import com.ruoyi.system.service.TTenantService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.authentication.AuthenticationManager;
+import org.springframework.security.authentication.BadCredentialsException;
+import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
+import org.springframework.security.core.Authentication;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.Resource;
 
 /**
  * 登录校验方法
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/dto/OfflinePayCheckDto.java b/ruoyi-system/src/main/java/com/ruoyi/system/dto/OfflinePayCheckDto.java
index 51a9e92..74eaa36 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/dto/OfflinePayCheckDto.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/dto/OfflinePayCheckDto.java
@@ -41,7 +41,7 @@
     private String flowId;
 
     @ApiModelProperty("支付类型")
-    @NotEmpty(message = "支付类型不能为空")
+    @NotNull(message = "支付类型不能为空")
     private Integer payType;
 
 
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/dto/TContractDTO.java b/ruoyi-system/src/main/java/com/ruoyi/system/dto/TContractDTO.java
index 0659eb1..11206fd 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/dto/TContractDTO.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/dto/TContractDTO.java
@@ -1,9 +1,7 @@
 package com.ruoyi.system.dto;
 
-import com.baomidou.mybatisplus.annotation.TableField;
 import com.fasterxml.jackson.annotation.JsonFormat;
 import com.ruoyi.system.model.TContract;
-import com.ruoyi.system.model.TTenant;
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/dto/TbillSaveDto.java b/ruoyi-system/src/main/java/com/ruoyi/system/dto/TbillSaveDto.java
index c7869f5..53a19ad 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/dto/TbillSaveDto.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/dto/TbillSaveDto.java
@@ -6,6 +6,7 @@
 import lombok.Data;
 
 import java.io.Serializable;
+import java.math.BigDecimal;
 import java.util.List;
 
 @Data
@@ -13,8 +14,11 @@
 
     @ApiModelProperty(value = "水电费列表")
     private List<TBillDetail> details;
-
-
+    /**
+     *
+     */
+    @ApiModelProperty(value = "调整金额(有违约金,就调整违约金并调整欠费,没有违约金,就直接调整欠费)")
+    private BigDecimal editAmount;
 
 
 }
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 c2f05a3..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,10 +1,13 @@
 package com.ruoyi.system.dto;
 
+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.io.Serializable;
+import java.time.LocalDateTime;
 
 @Data
 @ApiModel(value = "终止合同DTO")
@@ -16,4 +19,9 @@
     @ApiModelProperty(value = "备注说明")
     private String terminateRemark;
 
+    @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/TBankFlowMapper.java b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/TBankFlowMapper.java
index 20398af..3e9a980 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/mapper/TBankFlowMapper.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/TBankFlowMapper.java
@@ -15,6 +15,6 @@
  * @since 2025-02-07
  */
 public interface TBankFlowMapper extends BaseMapper<TBankFlow> {
-    TBankFlowStatisticsVo getPaymentStats(@Param("req") TBankFlowQuery query);
+    TBankFlowStatisticsVo getPaymentStats(@Param("req") TBankFlowQuery query,@Param("businessDeptId") String businessDeptId);
 
 }
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 357d516..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
@@ -5,11 +5,12 @@
 import com.ruoyi.system.dto.TBillDto;
 import com.ruoyi.system.model.TBill;
 import com.ruoyi.system.query.TBillQuery;
+import com.ruoyi.system.vo.ScreenRentRankVO;
 import org.apache.ibatis.annotations.Mapper;
 import org.apache.ibatis.annotations.Param;
-import org.apache.ibatis.annotations.Select;
 
 import java.math.BigDecimal;
+import java.util.Date;
 import java.util.List;
 
 /**
@@ -25,6 +26,8 @@
 
     PageInfo<TBillDto> page(@Param("pageInfo") PageInfo<TBill> pageInfo, @Param("query") TBillQuery query);
 
+    PageInfo<TBillDto> pageForApplet(@Param("pageInfo") PageInfo<TBill> pageInfo, @Param("query") TBillQuery query);
+
     List<TBillDto> getBillList(@Param("query")TBillQuery query);
 
     /**
@@ -37,13 +40,24 @@
 
     TBillDto selectDetailByBillId(@Param("billId") String billId);
 
-    BigDecimal statisticsAllRent();
+    BigDecimal statisticsAllRent(@Param("query") TBillQuery query);
 
-    BigDecimal statisticsNoPay();
+    BigDecimal statisticsNoPay(@Param("query") TBillQuery query);
 
-    BigDecimal statisticsPayed();
+    BigDecimal statisticsPayed(@Param("query") TBillQuery query);
 
-    BigDecimal statisticsOverdue();
+    BigDecimal statisticsOverdue(@Param("query") TBillQuery query);
 
     Integer batchBillCount(@Param("userId")String userId, @Param("billIds")List<String> billIds);
+    /**
+     * 街道租金排行
+     * @return
+     */
+    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/TBusinessDeptMapper.java b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/TBusinessDeptMapper.java
new file mode 100644
index 0000000..651f548
--- /dev/null
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/TBusinessDeptMapper.java
@@ -0,0 +1,16 @@
+package com.ruoyi.system.mapper;
+
+import com.ruoyi.system.model.TBusinessDept;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+/**
+ * <p>
+ * 营业部 Mapper 接口
+ * </p>
+ *
+ * @author mitao
+ * @since 2025-03-24
+ */
+public interface TBusinessDeptMapper extends BaseMapper<TBusinessDept> {
+
+}
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 4be10f7..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
@@ -2,7 +2,10 @@
 
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import com.ruoyi.common.basic.PageInfo;
+import com.ruoyi.system.dto.TBillDto;
+import com.ruoyi.system.model.TBill;
 import com.ruoyi.system.model.TContract;
+import com.ruoyi.system.query.TBillQuery;
 import com.ruoyi.system.query.TContractAppletQuery;
 import com.ruoyi.system.query.TContractBillQuery;
 import com.ruoyi.system.query.TContractQuery;
@@ -21,11 +24,18 @@
  */
 public interface TContractMapper extends BaseMapper<TContract> {
 
-    List<TContract> contractList(@Param("query") TContractQuery query, @Param("pageInfo") PageInfo<TContract> pageInfo);
+    List<TContract> contractList(@Param("query") TContractQuery query, @Param("pageInfo") PageInfo<TContract> pageInfo,@Param("businessDeptId") String businessDeptId);
 
     List<TContract> contractAppletList(@Param("query")TContractAppletQuery query, @Param("pageInfo")  PageInfo<TContract> pageInfo);
 
     List<BillVO> contractBillList(@Param("query") TContractBillQuery query, @Param("pageInfo") PageInfo<BillVO> pageInfo);
 
     List<TContract> contractExportList(@Param("query")TContractQuery query);
+    /**
+     * 本月新增租户数
+     * @return
+     */
+    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/TFlowManagementMapper.java b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/TFlowManagementMapper.java
index deca07e..6ea732c 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/mapper/TFlowManagementMapper.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/TFlowManagementMapper.java
@@ -15,5 +15,6 @@
  * @since 2025-01-17
  */
 public interface TFlowManagementMapper extends BaseMapper<TFlowManagement> {
-    TFlowManagementStatisticsVo getPaymentStats(@Param("req") TFlowManagementQuery query);
+    TFlowManagementStatisticsVo getPaymentStats(@Param("req") TFlowManagementQuery query,@Param("businessDeptId") String businessDeptId);
+
 }
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/mapper/TStreetMapper.java b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/TStreetMapper.java
new file mode 100644
index 0000000..5b6275f
--- /dev/null
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/TStreetMapper.java
@@ -0,0 +1,16 @@
+package com.ruoyi.system.mapper;
+
+import com.ruoyi.system.model.TStreet;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+/**
+ * <p>
+ * 街道 Mapper 接口
+ * </p>
+ *
+ * @author mitao
+ * @since 2025-03-19
+ */
+public interface TStreetMapper extends BaseMapper<TStreet> {
+
+}
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/mapper/TTenantMapper.java b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/TTenantMapper.java
index e0812d5..c30a287 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/mapper/TTenantMapper.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/TTenantMapper.java
@@ -38,4 +38,11 @@
 
     List<ExamineVO> examineList(@Param("query")TExamineAppletQuery dto, @Param("pageInfo")PageInfo<ExamineVO> pageInfo);
 
+    /**
+     * 根据营业部id获取租户列表
+     * @param query
+     * @param pageInfo
+     * @return
+     */
+    List<TenantVO> pageListByBusinessDeptId(@Param("query") TTenantQuery query, @Param("pageInfo")PageInfo<TenantVO> pageInfo);
 }
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/model/TBankFlow.java b/ruoyi-system/src/main/java/com/ruoyi/system/model/TBankFlow.java
index 2340d46..1064ff6 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/model/TBankFlow.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/model/TBankFlow.java
@@ -32,6 +32,10 @@
     @TableId("id")
     private String id;
 
+    @ApiModelProperty(value = "营运部门ID")
+    @TableField("business_dept_id")
+    private String businessDeptId;
+
     @ApiModelProperty(value = "银行流水号")
     @TableField("bank_serial_number")
     private String bankSerialNumber;
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 cee2df3..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>
@@ -76,6 +75,10 @@
     @TableField("contract_id")
     private String contractId;
 
+    @ApiModelProperty(value = "营运部门ID")
+    @TableField("business_dept_id")
+    private String businessDeptId;
+
     @ApiModelProperty(value = "合同编号")
     @TableField("contract_number")
     private String contractNumber;
@@ -98,7 +101,7 @@
     private BigDecimal payFeesMoney;
 
     @ApiModelProperty(value = "缴费日期")
-    @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
     @TableField("pay_fees_time")
     private LocalDateTime payFeesTime;
 
@@ -180,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/TBusinessDept.java b/ruoyi-system/src/main/java/com/ruoyi/system/model/TBusinessDept.java
new file mode 100644
index 0000000..a16c85b
--- /dev/null
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/model/TBusinessDept.java
@@ -0,0 +1,39 @@
+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 lombok.experimental.Accessors;
+
+import java.io.Serializable;
+
+/**
+ * <p>
+ * 营业部
+ * </p>
+ *
+ * @author mitao
+ * @since 2025-03-24
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@TableName("t_business_dept")
+@ApiModel(value="TBusinessDept对象", description="营业部")
+public class TBusinessDept extends BaseModel implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    @ApiModelProperty(value = "主键")
+    @TableId(value = "id", type = IdType.ASSIGN_ID)
+    private String id;
+
+    @ApiModelProperty(value = "营业部名称")
+    private String name;
+
+}
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 14257ff..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
@@ -1,14 +1,9 @@
 package com.ruoyi.system.model;
 
 import com.baomidou.mybatisplus.annotation.IdType;
-import com.baomidou.mybatisplus.annotation.TableName;
-import com.baomidou.mybatisplus.annotation.TableId;
-
-import java.math.BigDecimal;
-import java.time.LocalDateTime;
 import com.baomidou.mybatisplus.annotation.TableField;
-import java.io.Serializable;
-
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
 import com.fasterxml.jackson.annotation.JsonFormat;
 import com.ruoyi.common.core.domain.BaseModel;
 import io.swagger.annotations.ApiModel;
@@ -16,7 +11,8 @@
 import lombok.Data;
 import lombok.EqualsAndHashCode;
 
-import javax.validation.constraints.NotBlank;
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
 
 /**
  * <p>
@@ -129,7 +125,6 @@
 
     @ApiModelProperty(value = "合同附件,多个逗号拼接")
     @TableField("contract_file")
-    @NotBlank(message = "合同附件不能为空")
     private String contractFile;
 
     @ApiModelProperty(value = "备注")
@@ -149,6 +144,15 @@
     @ApiModelProperty(value = "合同状态 1=待提交 2=待审批 3=未签订 4=已签订 5=已驳回 6=已终止 7=待结算 8=已结算 9 = 签订待审核")
     @TableField("status")
     private String status;
+
+    /**
+     * 签订时间
+     */
+    @ApiModelProperty(value = "签订时间")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    @TableField("sign_time")
+    private LocalDateTime signTime;
+
     @ApiModelProperty(value = "内存大小多个文件逗号拼接")
     @TableField("memory")
     private String memory;
@@ -174,4 +178,16 @@
     @TableField(exist = false)
     private String instanceId;
 
+    @ApiModelProperty(value = "房屋使用范围")
+    @TableField("house_use_scope")
+    private String houseUseScope;
+
+    @ApiModelProperty(value = "终止日期-前端传的")
+    @TableField("terminate_time")
+    private LocalDateTime terminateTime;
+
+    @ApiModelProperty(value = "营业部id")
+    @TableField("business_dept_id")
+    private String businessDeptId;
+
 }
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/TFlowManagement.java b/ruoyi-system/src/main/java/com/ruoyi/system/model/TFlowManagement.java
index 0f72ebf..de4b72e 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/model/TFlowManagement.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/model/TFlowManagement.java
@@ -35,6 +35,10 @@
     @TableId(value = "id", type = IdType.ASSIGN_ID)
     private String id;
 
+    @ApiModelProperty(value = "营运部门ID")
+    @TableField("business_dept_id")
+    private String businessDeptId;
+
     @ApiModelProperty(value = "系统流水号")
     @TableField("sys_serial_number")
     private String sysSerialNumber;
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 9a03ab2..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
@@ -1,18 +1,18 @@
 package com.ruoyi.system.model;
 
 import com.baomidou.mybatisplus.annotation.IdType;
-import com.baomidou.mybatisplus.annotation.TableName;
-import com.baomidou.mybatisplus.annotation.TableId;
-import java.time.LocalDateTime;
 import com.baomidou.mybatisplus.annotation.TableField;
-import java.io.Serializable;
-
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
 import com.fasterxml.jackson.annotation.JsonFormat;
 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.math.BigDecimal;
+import java.time.LocalDateTime;
 
 /**
  * <p>
@@ -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;
@@ -94,4 +99,20 @@
     @ApiModelProperty(value = "住户类型 1月租 2季租 3年租")
     @TableField(exist = false)
     private String tenantType;
+
+    @ApiModelProperty(value = "所属街道id")
+    @TableField("street_id")
+    private String streetId;
+
+    @ApiModelProperty(value = "经度")
+    @TableField("longitude")
+    private BigDecimal longitude;
+
+    @ApiModelProperty(value = "纬度")
+    @TableField("latitude")
+    private BigDecimal latitude;
+
+    @ApiModelProperty(value = "营业部id")
+    @TableField("business_dept_id")
+    private String businessDeptId;
 }
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/model/TInformation.java b/ruoyi-system/src/main/java/com/ruoyi/system/model/TInformation.java
index 3132361..70a3e56 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/model/TInformation.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/model/TInformation.java
@@ -1,12 +1,9 @@
 package com.ruoyi.system.model;
 
 import com.baomidou.mybatisplus.annotation.IdType;
-import com.baomidou.mybatisplus.annotation.TableName;
-import com.baomidou.mybatisplus.annotation.TableId;
-import java.time.LocalDateTime;
 import com.baomidou.mybatisplus.annotation.TableField;
-import java.io.Serializable;
-
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
 import com.fasterxml.jackson.annotation.JsonFormat;
 import com.ruoyi.common.core.domain.BaseModel;
 import io.swagger.annotations.ApiModel;
@@ -16,6 +13,7 @@
 
 import javax.validation.constraints.NotBlank;
 import javax.validation.constraints.NotNull;
+import java.time.LocalDateTime;
 
 /**
  * <p>
@@ -79,4 +77,8 @@
     @TableField(exist = false)
     private Integer viewCount;
 
+    @ApiModelProperty(value = "营业部id")
+    @TableField("business_dept_id")
+    private String businessDeptId;
+
 }
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/model/TInvoice.java b/ruoyi-system/src/main/java/com/ruoyi/system/model/TInvoice.java
index cf29a4f..701b285 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/model/TInvoice.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/model/TInvoice.java
@@ -35,6 +35,10 @@
     @TableId(value = "id", type = IdType.ASSIGN_ID)
     private String id;
 
+    @ApiModelProperty(value = "营运部门ID")
+    @TableField("business_dept_id")
+    private String businessDeptId;
+
     @ApiModelProperty(value = "申请编号")
     @TableField("invoice_number")
     private String invoiceNumber;
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/TStreet.java b/ruoyi-system/src/main/java/com/ruoyi/system/model/TStreet.java
new file mode 100644
index 0000000..7a86d29
--- /dev/null
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/model/TStreet.java
@@ -0,0 +1,38 @@
+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 lombok.experimental.Accessors;
+
+import java.io.Serializable;
+
+/**
+ * <p>
+ * 街道
+ * </p>
+ *
+ * @author mitao
+ * @since 2025-03-19
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@TableName("t_street")
+@ApiModel(value="TStreet对象", description="街道")
+public class TStreet extends BaseModel implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    @TableId(value = "id", type = IdType.ASSIGN_ID)
+    private String id;
+
+    @ApiModelProperty(value = "物品名称")
+    private String streetName;
+
+}
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 cca42c8..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
@@ -1,14 +1,9 @@
 package com.ruoyi.system.model;
 
 import com.baomidou.mybatisplus.annotation.IdType;
-import com.baomidou.mybatisplus.annotation.TableName;
-import com.baomidou.mybatisplus.annotation.TableId;
-
-import java.time.LocalDate;
-import java.time.LocalDateTime;
 import com.baomidou.mybatisplus.annotation.TableField;
-import java.io.Serializable;
-
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
 import com.fasterxml.jackson.annotation.JsonFormat;
 import com.ruoyi.common.core.domain.BaseModel;
 import io.swagger.annotations.ApiModel;
@@ -18,6 +13,7 @@
 
 import javax.validation.constraints.NotBlank;
 import javax.validation.constraints.NotNull;
+import java.time.LocalDate;
 
 /**
  * <p>
@@ -92,4 +88,20 @@
     @TableField("open_id")
     private String openId;
 
+    @ApiModelProperty(value = "法人")
+    @TableField("legal_person")
+    private String legalPerson;
+
+    @ApiModelProperty(value = "社会统一信用代码")
+    @TableField("credit_code")
+    private String creditCode;
+
+    @ApiModelProperty(value = "开户行")
+    @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/query/SysUserQuery.java b/ruoyi-system/src/main/java/com/ruoyi/system/query/SysUserQuery.java
index 3c7b3d4..5b12765 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/query/SysUserQuery.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/query/SysUserQuery.java
@@ -23,4 +23,7 @@
     @ApiModelProperty(value = "状态  0=正常 1=停用")
     private String status;
 
+    @ApiModelProperty(value = "营业部id",hidden = true)
+    private String businessDeptId;
+
 }
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/query/TBankFlowQuery.java b/ruoyi-system/src/main/java/com/ruoyi/system/query/TBankFlowQuery.java
index ae33250..a11bf7e 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/query/TBankFlowQuery.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/query/TBankFlowQuery.java
@@ -57,4 +57,7 @@
     @ApiModelProperty(value = "支付结束时间")
     private String payEndTime;
 
+    @ApiModelProperty(value = "营运部门ID")
+    private String businessDeptId;
+
 }
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/query/TBillQuery.java b/ruoyi-system/src/main/java/com/ruoyi/system/query/TBillQuery.java
index 1d66290..497dd30 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/query/TBillQuery.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/query/TBillQuery.java
@@ -1,11 +1,15 @@
 package com.ruoyi.system.query;
 
+import com.baomidou.mybatisplus.annotation.TableField;
 import com.ruoyi.common.core.domain.BasePage;
 import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
 
 @Data
 public class TBillQuery extends BasePage {
+
+    @ApiModelProperty(value = "营运部门ID")
+    private String businessDeptId;
     /**
      * 缴费状态 1=未缴费 2=待确认 3=已缴费 4=已逾期
      */
@@ -31,4 +35,6 @@
 
 
 
+
+
 }
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/query/TCheckAcceptRecordAppletQuery.java b/ruoyi-system/src/main/java/com/ruoyi/system/query/TCheckAcceptRecordAppletQuery.java
index 9c6ff23..c7b3b45 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/query/TCheckAcceptRecordAppletQuery.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/query/TCheckAcceptRecordAppletQuery.java
@@ -15,4 +15,8 @@
     @ApiModelProperty(value = "状态 不传为全部 1待验收 2已验收")
     private Integer status;
 
+    private String sysUserId;
+
+    private String businessDeptId;
+
 }
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/query/TCheckAcceptRecordQuery.java b/ruoyi-system/src/main/java/com/ruoyi/system/query/TCheckAcceptRecordQuery.java
index 89da8f4..bb14ad0 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/query/TCheckAcceptRecordQuery.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/query/TCheckAcceptRecordQuery.java
@@ -1,6 +1,5 @@
 package com.ruoyi.system.query;
 
-import com.baomidou.mybatisplus.annotation.TableField;
 import com.ruoyi.common.core.domain.model.TimeRangeQueryBody;
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
@@ -19,4 +18,7 @@
     @ApiModelProperty(value = "验收结果 1=合格 0=不合格")
     private Boolean checkResult;
 
+    @ApiModelProperty(value = "营业部id",hidden = true)
+    private String businessDeptId;
+
 }
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/query/TContractQuery.java b/ruoyi-system/src/main/java/com/ruoyi/system/query/TContractQuery.java
index 0cb2c3a..bfa74dd 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/query/TContractQuery.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/query/TContractQuery.java
@@ -27,4 +27,7 @@
     @ApiModelProperty(value = "查询多个状态")
     private List<Integer> statuses;
 
+    @ApiModelProperty(value = "营运部门ID")
+    private String businessDeptId;
+
 }
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/query/TFaultRepairMessageQuery.java b/ruoyi-system/src/main/java/com/ruoyi/system/query/TFaultRepairMessageQuery.java
index cd0015b..b1256e5 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/query/TFaultRepairMessageQuery.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/query/TFaultRepairMessageQuery.java
@@ -1,6 +1,5 @@
 package com.ruoyi.system.query;
 
-import com.baomidou.mybatisplus.annotation.TableField;
 import com.ruoyi.common.core.domain.BasePage;
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
@@ -24,4 +23,7 @@
 
     @ApiModelProperty(value = "处理人")
     private String handlePerson;
+
+    @ApiModelProperty(value = "营业部id", hidden = true)
+    private String businessDeptId;
 }
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/query/TFlowManagementQuery.java b/ruoyi-system/src/main/java/com/ruoyi/system/query/TFlowManagementQuery.java
index 19fd59f..59a4d74 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/query/TFlowManagementQuery.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/query/TFlowManagementQuery.java
@@ -59,5 +59,8 @@
     @ApiModelProperty(value = "支付结束时间")
     private String payEndTime;
 
+    @ApiModelProperty(value = "营运部门ID")
+    private String businessDeptId;
+
 
 }
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/query/THouseQuery.java b/ruoyi-system/src/main/java/com/ruoyi/system/query/THouseQuery.java
index 1eb82ac..9c8a5d8 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/query/THouseQuery.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/query/THouseQuery.java
@@ -18,4 +18,7 @@
     @ApiModelProperty(value = "租赁状态 1=待出租 2=已出租 3=维修中")
     private String leaseStatus;
 
+    @ApiModelProperty(value = "所属营业部", hidden = true)
+    private String businessDeptId;
+
 }
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/query/TInvoiceQuery.java b/ruoyi-system/src/main/java/com/ruoyi/system/query/TInvoiceQuery.java
index 7a7cf34..a66cfa3 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/query/TInvoiceQuery.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/query/TInvoiceQuery.java
@@ -58,4 +58,7 @@
     @ApiModelProperty(value = "开票文件名称")
     private String invoiceVoucherName;
 
+    @ApiModelProperty(value = "营运部门ID")
+    private String businessDeptId;
+
 }
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/query/TTenantQuery.java b/ruoyi-system/src/main/java/com/ruoyi/system/query/TTenantQuery.java
index 83e1748..8eff3eb 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/query/TTenantQuery.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/query/TTenantQuery.java
@@ -1,7 +1,6 @@
 package com.ruoyi.system.query;
 
 import com.ruoyi.common.core.domain.BasePage;
-import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
@@ -16,6 +15,9 @@
     @ApiModelProperty(value = "联系电话")
     private String phone;
 
+    @ApiModelProperty(value = "营业部id")
+    private String businessDeptId;
+
 
 
 }
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/ITBusinessDeptService.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/ITBusinessDeptService.java
new file mode 100644
index 0000000..549694d
--- /dev/null
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/ITBusinessDeptService.java
@@ -0,0 +1,16 @@
+package com.ruoyi.system.service;
+
+import com.ruoyi.system.model.TBusinessDept;
+import com.baomidou.mybatisplus.extension.service.IService;
+
+/**
+ * <p>
+ * 营业部 服务类
+ * </p>
+ *
+ * @author mitao
+ * @since 2025-03-24
+ */
+public interface ITBusinessDeptService extends IService<TBusinessDept> {
+
+}
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/ITStreetService.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/ITStreetService.java
new file mode 100644
index 0000000..f677154
--- /dev/null
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/ITStreetService.java
@@ -0,0 +1,16 @@
+package com.ruoyi.system.service;
+
+import com.ruoyi.system.model.TStreet;
+import com.baomidou.mybatisplus.extension.service.IService;
+
+/**
+ * <p>
+ * 街道 服务类
+ * </p>
+ *
+ * @author mitao
+ * @since 2025-03-19
+ */
+public interface ITStreetService extends IService<TStreet> {
+
+}
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 0015ee5..1946395 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
@@ -2,18 +2,22 @@
 
 import com.baomidou.mybatisplus.extension.service.IService;
 import com.ruoyi.common.basic.PageInfo;
-import com.ruoyi.system.dto.*;
+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.TBill;
 import com.ruoyi.system.query.TBillQuery;
+import com.ruoyi.system.vo.ScreenRentRankVO;
 import com.taxi591.bankapi.dto.ChargeBillRequest;
 
 import javax.validation.constraints.NotEmpty;
 import java.math.BigDecimal;
+import java.util.Date;
 import java.util.List;
 import java.util.function.Consumer;
-import java.util.function.Function;
-
-import java.util.List;
 
 /**
  * <p>
@@ -26,6 +30,9 @@
 public interface TBillService extends IService<TBill> {
 
     PageInfo<TBillDto> queryPage(TBillQuery query);
+
+
+    PageInfo<TBillDto> queryPageForApplet(TBillQuery query);
 
     /**
      *
@@ -84,7 +91,31 @@
 
     Boolean cashPay(CachPayDto offlinePayDto);
 
-    BillStatisticsDto statistics();
+    BillStatisticsDto statistics(TBillQuery query);
 
     Integer batchBillCount(String userId, List<String> billIds);
+
+    /**
+     * 查询街道租金排行
+     * @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);
+
+    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 00b2a31..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;
 
@@ -43,4 +44,10 @@
 
     Boolean updateContractAuditStatus(String projectId, Integer submitStatus);
 
+    /**
+     * 本月新增租户数
+     * @return
+     */
+    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/TInvoiceService.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/TInvoiceService.java
index 62a2e34..4b27c65 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/service/TInvoiceService.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/TInvoiceService.java
@@ -7,6 +7,7 @@
 import com.ruoyi.system.query.TInvoiceQuery;
 
 import java.util.List;
+import java.util.Map;
 
 /**
  * <p>
@@ -19,5 +20,5 @@
 public interface TInvoiceService extends IService<TInvoice> {
     PageInfo<TInvoice> pageList(TInvoiceQuery query);
     List<TInvoice> makeQuery(TInvoiceQuery query);
-    Boolean uploadVoucher(TInvoiceQuery query);
+    Boolean uploadVoucher(TInvoiceQuery query, List<Map<String, String>> map);
 }
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 b2e6c81..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
@@ -28,17 +28,23 @@
 import com.google.common.collect.ImmutableMap;
 import com.ruoyi.common.core.domain.entity.SysRole;
 import com.ruoyi.common.enums.ProcessCategoryEnum;
-import com.ruoyi.common.enums.SubmitStatusEnum;
 import com.ruoyi.common.exception.ServiceException;
 import com.ruoyi.system.mapper.TCheckAcceptRecordMapper;
-import com.ruoyi.system.model.*;
-import com.ruoyi.system.service.*;
+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.service.ISysRoleService;
+import com.ruoyi.system.service.TBillService;
+import com.ruoyi.system.service.TContractRentTypeService;
+import com.ruoyi.system.service.TContractService;
+import com.ruoyi.system.service.THouseService;
 import com.ruoyi.system.task.base.QuartzManager;
 import com.ruoyi.system.task.base.TimeJobType;
 import com.ruoyi.system.task.jobs.StateProcessJob;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
 
 import java.math.BigDecimal;
@@ -46,7 +52,11 @@
 import java.time.LocalDateTime;
 import java.time.temporal.ChronoUnit;
 import java.time.temporal.TemporalAdjusters;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
 import java.util.function.Supplier;
 import java.util.stream.Collectors;
 
@@ -81,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
@@ -259,6 +272,7 @@
     }
 
 
+
     /**
      * 业务状态变更
      */
@@ -291,9 +305,9 @@
                     }
                     List<TContractRentType> contractRentTypes = contractRentTypeService.list();
                     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());
@@ -415,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());
@@ -445,7 +478,7 @@
                             if (dayOfMonth == 1) {
                                 money = money.add(contract.getMonthRent());
                             } else {
-                                long allDays = ChronoUnit.DAYS.between(contract.getStartPayTime(), contract.getStartPayTime().with(TemporalAdjusters.lastDayOfMonth())) + 1;
+                                long allDays = ChronoUnit.DAYS.between(rentBill.getStartTime(), rentBill.getStartTime().with(TemporalAdjusters.lastDayOfMonth())) ;
                                 money =money.add(contract.getMonthRent().divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(allDays)));
                             }
                             // 后续
@@ -453,15 +486,16 @@
                                 rentBill.setPayableFeesMoney(money);
                                 rentBill.setOutstandingMoney(rentBill.getPayableFeesMoney());
                             }else{
-                                LocalDateTime localDateTime = rentBill.getStartTime().plusMonths(1).with(TemporalAdjusters.lastDayOfMonth());
+//                                LocalDateTime localDateTime = rentBill.getStartTime().plusMonths(1).with(TemporalAdjusters.lastDayOfMonth());
+                                LocalDateTime localDateTime = rentBill.getStartTime().with(TemporalAdjusters.lastDayOfMonth()).plusDays(1);
                                 while (true){
                                     if (localDateTime.isBefore(rentBill.getEndTime())){
+                                        localDateTime = localDateTime.plusMonths(1);
                                         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)));
+                                        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())))));
                                         break;
                                     }
-                                    localDateTime = localDateTime.plusMonths(1).with(TemporalAdjusters.lastDayOfMonth());
                                 }
                                 rentBill.setPayableFeesMoney(money);
                                 rentBill.setOutstandingMoney(rentBill.getPayableFeesMoney());
@@ -492,6 +526,8 @@
 
                     depositBill.setBillType("2");
                     contractService.updateById(contract);
+                    rentBill.setBusinessDeptId(contract.getBusinessDeptId());
+                    depositBill.setBusinessDeptId(contract.getBusinessDeptId());
                     billService.save(rentBill);
                     billService.save(depositBill);
                     // 生成后续账单
@@ -711,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()));
@@ -919,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);
@@ -947,16 +990,28 @@
                             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().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()));
+                                // 计算天
+                                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())){
-                                    if (originalTime.plusMonths(1).isBefore(tContractRentType.getChangeTime())){
+                                    if (originalTime.plusMonths(1).isBefore(tBill.getEndTime())){
                                         originalMoney = originalMoney.add(contract.getChangeRent());
                                         originalTime = originalTime.plusMonths(1);
                                     }else {
@@ -966,19 +1021,22 @@
                                     break;
                                 }
                             }
-                            long tempOriginal  = ChronoUnit.DAYS.between(originalTime,tBill.getEndTime());
-                            originalMoney = originalMoney.add(contract.getChangeRent().divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(tempOriginal)));
+                            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);
                     }
                 }
@@ -986,10 +1044,18 @@
             }
             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());
                 tCheckAcceptRecord.setHouseId(contract.getHouseId());
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
new file mode 100644
index 0000000..07e1869
--- /dev/null
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/ScreenService.java
@@ -0,0 +1,245 @@
+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;
+import com.ruoyi.system.service.TBillService;
+import com.ruoyi.system.service.TContractService;
+import com.ruoyi.system.service.THouseService;
+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;
+
+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;
+
+/**
+ * @author mitao
+ * @date 2025/3/19
+ */
+@Service
+@RequiredArgsConstructor(onConstructor_ = {@Lazy})
+public class ScreenService {
+    private final THouseService tHouseService;
+    private final TContractService tContractService;
+    private final TBillService tBillService;
+    private final TContractService contractService;
+    /**
+     * 获取顶部统计数据
+     * @return
+     */
+    public ScreenTopStaticsDataVO getTopStaticsData() {
+        String businessDeptId = SecurityUtils.getBusinessDeptId();
+        Map<String, Date> quarterDate = DateUtils.getQuarterDate(new Date());
+        Date first = quarterDate.get("first");
+        Date last = quarterDate.get("last");
+        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)
+                .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)
+                .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.DOWN);
+        vo.setTotalRentOwe(totalRentOwe);
+        //总计欠费
+        BigDecimal totalRentOweAll = billList.stream()
+                .map(TBill::getOutstandingMoney)
+                .reduce(BigDecimal.ZERO, BigDecimal::add)
+                .divide(BigDecimal.valueOf(10000L), 2, RoundingMode.DOWN);
+        vo.setTotalRentOweAll(totalRentOweAll);
+        return vo;
+    }
+
+    /**
+     * 区域租金排名
+     * @return
+     */
+    public List<ScreenRentRankVO> streetRentRank() {
+        String businessDeptId = SecurityUtils.getBusinessDeptId();
+        return  tBillService.getStreetRentRank(businessDeptId);
+    }
+
+    /**
+     * 租金收入趋势
+     * @return
+     */
+    public ScreenRentIncomeTrendVO rentIncomeTrend() {
+        ScreenRentIncomeTrendVO vo = new ScreenRentIncomeTrendVO();
+        String businessDeptId = SecurityUtils.getBusinessDeptId();
+        // 获取当前日期
+        Date currentDate = new Date();
+        List<String> quarterLabels = new ArrayList<>(); // 季度标签列表
+        List<BigDecimal> incomeData = new ArrayList<>(); //收入数据列表
+        List<BigDecimal> outstandingData = new ArrayList<>();  // 欠费数据列表
+        
+        // 获取最近7个季度的数据
+        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");
+
+            // 获取该季度的账单数据
+            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.DOWN);
+
+            // 计算季度欠费总和
+            BigDecimal quarterOutstanding = quarterBills.stream()
+                    .map(TBill::getOutstandingMoney)
+                    .filter(Objects::nonNull)
+                    .reduce(BigDecimal.ZERO, BigDecimal::add)
+                    .divide(BigDecimal.valueOf(10000L), 2, RoundingMode.DOWN);
+
+            // 生成季度标签 (格式: 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);
+
+            quarterLabels.add(label);
+            incomeData.add(quarterIncome);
+            outstandingData.add(quarterOutstanding);  // 添加欠费数据
+        }
+        
+        vo.setQuarters(quarterLabels);
+        vo.setIncomeData(incomeData);
+        vo.setOutstandingData(outstandingData);  // 设置欠费数据到VO
+        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 14e744d..70c7101 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,14 @@
         if (processTaskListBO.getSortBy() == 2) {
             stateTaskQuery.orderByDesc(BaseModel::getCreateTime);
         }
+        // 查询合同信息
+        List<TContract> tContracts = contractMapper.selectList(Wrappers.<TContract>lambdaQuery()
+                .in(TContract::getStatus, 2,3,4));
+        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);
@@ -803,6 +811,14 @@
         if (processTaskListBO.getSortBy() == 2) {
             stateTaskQuery.orderByDesc(BaseModel::getCreateTime);
         }
+        // 查询合同信息
+        List<TContract> tContracts = contractMapper.selectList(Wrappers.<TContract>lambdaQuery()
+                .in(TContract::getStatus, 2,3,4));
+        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, instanceId);
         PageInfo pageInfo = new PageInfo<>(processTaskListBO.getPageNum(), processTaskListBO.getPageSize());
         PageInfo<StateTaskCenter> taskCenters = stateTaskCenterService.page(pageInfo,stateTaskQuery);
@@ -1004,6 +1020,7 @@
         FlwTask flwTask = flwTaskMapper.selectById(taskId);
         // 直接拒绝当前流程
         flowLongEngine.runtimeService().reject(flwTask.getInstanceId(), currentFlowCreator());
+        flwTaskMapper.deleteById(taskId);
         // 动作执行记录
         StateProcessInstanceAction record = new StateProcessInstanceAction();
         record.setId(IdUtils.simpleUUID());
@@ -1334,6 +1351,17 @@
         if (processTaskListBO.getSortBy() == 2) {
             stateTaskQuery.orderByDesc(FlwHisTask::getCreateTime);
         }
+        List<TContract> tContracts = contractMapper.selectList(Wrappers.<TContract>lambdaQuery()
+                .in(TContract::getStatus, 2,3,4));
+        List<String> contractIds = tContracts.stream().map(TContract::getId).collect(Collectors.toList());
+        if(CollectionUtils.isEmpty(contractIds)){
+            return new PageInfo<>();
+        }
+        List<StateTaskCenter> list = stateTaskCenterService.list(Wrappers.<StateTaskCenter>lambdaQuery().in(StateTaskCenter::getProjectId, contractIds));
+        if(!CollectionUtils.isEmpty(list)){
+            List<String> flowIds = list.stream().map(StateTaskCenter::getFlowId).collect(Collectors.toList());
+            stateTaskQuery.in(FlwHisTask::getInstanceId, flowIds);
+        }
         stateTaskQuery.eq(FlwHisTask::getParentTaskId, 0L);
         stateTaskQuery.like(FlwHisTask::getCreateId, userId);
         PageInfo pageInfo = new PageInfo<>(processTaskListBO.getPageNum(), processTaskListBO.getPageSize());
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/StateTaskCenterServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/StateTaskCenterServiceImpl.java
index 83ad381..a0cc43d 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/StateTaskCenterServiceImpl.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/StateTaskCenterServiceImpl.java
@@ -5,7 +5,6 @@
 import com.ruoyi.system.bo.ProcessTaskListBO;
 import com.ruoyi.system.mapper.StateTaskCenterMapper;
 import com.ruoyi.system.model.StateTaskCenter;
-import com.ruoyi.system.model.TFaultAreaDic;
 import com.ruoyi.system.service.StateTaskCenterService;
 import com.ruoyi.system.vo.ProcessTaskListVO;
 import org.springframework.stereotype.Service;
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysUserServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysUserServiceImpl.java
index 82743d4..ba35a11 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysUserServiceImpl.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysUserServiceImpl.java
@@ -1,27 +1,8 @@
 package com.ruoyi.system.service.impl;
 
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Objects;
-import java.util.stream.Collectors;
-import javax.validation.Validator;
-
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
-import com.ruoyi.common.basic.PageInfo;
-import com.ruoyi.common.core.domain.entity.SysDept;
-import com.ruoyi.system.mapper.*;
-import com.ruoyi.system.model.TDept;
-import com.ruoyi.system.model.TDeptToUser;
-import com.ruoyi.system.query.SysUserQuery;
-import com.ruoyi.system.service.TDeptToUserService;
-import com.ruoyi.system.vo.SysUserVO;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Service;
-import org.springframework.transaction.annotation.Transactional;
-import org.springframework.util.CollectionUtils;
 import com.ruoyi.common.annotation.DataScope;
+import com.ruoyi.common.basic.PageInfo;
 import com.ruoyi.common.constant.UserConstants;
 import com.ruoyi.common.core.domain.entity.SysRole;
 import com.ruoyi.common.core.domain.entity.SysUser;
@@ -33,8 +14,32 @@
 import com.ruoyi.system.domain.SysPost;
 import com.ruoyi.system.domain.SysUserPost;
 import com.ruoyi.system.domain.SysUserRole;
+import com.ruoyi.system.mapper.SysPostMapper;
+import com.ruoyi.system.mapper.SysRoleMapper;
+import com.ruoyi.system.mapper.SysUserMapper;
+import com.ruoyi.system.mapper.SysUserPostMapper;
+import com.ruoyi.system.mapper.SysUserRoleMapper;
+import com.ruoyi.system.mapper.TDeptMapper;
+import com.ruoyi.system.mapper.TDeptToUserMapper;
+import com.ruoyi.system.model.TDept;
+import com.ruoyi.system.model.TDeptToUser;
+import com.ruoyi.system.query.SysUserQuery;
 import com.ruoyi.system.service.ISysConfigService;
 import com.ruoyi.system.service.ISysUserService;
+import com.ruoyi.system.service.TDeptToUserService;
+import com.ruoyi.system.vo.SysUserVO;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.util.CollectionUtils;
+
+import javax.validation.Validator;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+import java.util.stream.Collectors;
 
 /**
  * 用户 业务层处理
@@ -665,6 +670,8 @@
     @Override
     public PageInfo<SysUserVO> pageList(SysUserQuery query) {
         PageInfo<SysUserVO> pageInfo = new PageInfo<>(query.getPageNum(), query.getPageSize());
+        String businessDeptId = SecurityUtils.getBusinessDeptId();
+        query.setBusinessDeptId(businessDeptId);
         List<SysUserVO> list = userMapper.pageList(query,pageInfo);
         if(CollectionUtils.isEmpty(list)){
             return pageInfo;
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TBankFlowServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TBankFlowServiceImpl.java
index 147a3ea..a643025 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TBankFlowServiceImpl.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TBankFlowServiceImpl.java
@@ -3,6 +3,7 @@
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.ruoyi.common.basic.PageInfo;
+import com.ruoyi.common.utils.SecurityUtils;
 import com.ruoyi.common.utils.StringUtils;
 import com.ruoyi.system.importExcel.TBankFlowImportExcel;
 import com.ruoyi.system.mapper.TBankFlowMapper;
@@ -46,13 +47,14 @@
                 .ge(StringUtils.isNotEmpty(query.getPayStartTime()),TBankFlow::getPayTime,query.getPayStartTime())
                 .lt(StringUtils.isNotEmpty(query.getPayEndTime()),TBankFlow::getPayTime,query.getPayEndTime())
                 .eq(null != query.getFlowStatus(),TBankFlow::getFlowStatus,query.getFlowStatus())
+                .eq(StringUtils.isNotEmpty(query.getBusinessDeptId())&& !"0".equals(query.getBusinessDeptId()),TBankFlow::getBusinessDeptId,query.getBusinessDeptId())
                 .orderByDesc(TBankFlow::getCreateTime);
         return this.baseMapper.selectPage(pageInfo, queryWrapper);
     }
 
     @Override
     public TBankFlowStatisticsVo getPaymentStats(TBankFlowQuery query) {
-        return this.baseMapper.getPaymentStats(query);
+        return this.baseMapper.getPaymentStats(query,SecurityUtils.getBusinessDeptId());
     }
 
     /**
@@ -62,10 +64,12 @@
      */
     @Override
     public List<TBankFlow> searchByBankSerialNumber(String bankSerialNumber) {
+        String businessDeptId = SecurityUtils.getBusinessDeptId();
+
         LambdaQueryWrapper<TBankFlow> queryWrapper = new LambdaQueryWrapper<>();
         queryWrapper.like(StringUtils.isNotEmpty(bankSerialNumber),TBankFlow::getBankSerialNumber,bankSerialNumber)
+                .eq(StringUtils.isNotEmpty(bankSerialNumber) && !"0".equals(bankSerialNumber),TBankFlow::getBusinessDeptId,businessDeptId)
                 .orderByDesc(TBankFlow::getPayTime);
-
         PageInfo<TBankFlow> pageInfo = new PageInfo<>(1, 20);
         pageInfo = this.baseMapper.selectPage(pageInfo, queryWrapper);
         return pageInfo.getRecords();
@@ -73,6 +77,7 @@
 
     @Override
     public void saveImportBatch(List<TBankFlowImportExcel> list, List<TBankFlowImportExcel> failList) {
+        String businessDeptId = SecurityUtils.getBusinessDeptId();
         for (TBankFlowImportExcel row : list) {
             try {
                 TBankFlow preexist = findUniq(row.getBankSerialNumber());
@@ -83,6 +88,7 @@
                 }
                 TBankFlow flow = new TBankFlow();
                 BeanUtils.copyProperties(row,flow);
+                flow.setBusinessDeptId(businessDeptId);
                 try {
                     LocalDateTime parse = LocalDateTime.parse(row.getPayTime(), DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
                     flow.setPayTime(parse);
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 0376220..c5bd162 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
@@ -1,24 +1,43 @@
 package com.ruoyi.system.service.impl;
 
-import cn.hutool.core.date.DateUtil;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.ruoyi.common.basic.PageInfo;
-import com.ruoyi.common.config.SmsProperties;
 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;
-import com.ruoyi.system.dto.*;
+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.mapper.TBillMapper;
-import com.ruoyi.system.model.*;
+import com.ruoyi.system.model.TBankFlow;
+import com.ruoyi.system.model.TBill;
+import com.ruoyi.system.model.TBillDetail;
+import com.ruoyi.system.model.TFlowManagement;
+import com.ruoyi.system.model.TInvoiceToBill;
+import com.ruoyi.system.model.TOrderBill;
+import com.ruoyi.system.model.TPayOrder;
 import com.ruoyi.system.query.TBillQuery;
 import com.ruoyi.system.query.TInvoiceToBillQuery;
-import com.ruoyi.system.service.*;
+import com.ruoyi.system.service.TBankFlowService;
+import com.ruoyi.system.service.TBillConfirmService;
+import com.ruoyi.system.service.TBillDetailService;
+import com.ruoyi.system.service.TBillService;
+import com.ruoyi.system.service.TFlowManagementService;
+import com.ruoyi.system.service.TInvoiceToBillService;
+import com.ruoyi.system.service.TOrderBillService;
+import com.ruoyi.system.service.TPayOrderService;
+import com.ruoyi.system.vo.ScreenRentRankVO;
 import com.taxi591.bankapi.dto.ChargeBillRequest;
 import lombok.extern.slf4j.Slf4j;
 import org.jetbrains.annotations.NotNull;
+import org.joda.time.LocalDateTime;
 import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
@@ -28,7 +47,6 @@
 import javax.validation.constraints.NotEmpty;
 import java.math.BigDecimal;
 import java.text.ParseException;
-import java.time.LocalDateTime;
 import java.util.ArrayList;
 import java.util.Comparator;
 import java.util.Date;
@@ -88,6 +106,12 @@
         return info;
     }
 
+    public PageInfo<TBillDto> queryPageForApplet(TBillQuery query){
+        PageInfo<TBill> pageInfo = new PageInfo<>(query.getPageNum(), query.getPageSize());
+        PageInfo<TBillDto> info = tBillMapper.pageForApplet(pageInfo, query);
+        return info;
+    }
+
     @Override
     public List<String> getBillIds(TBillQuery query) {
         List<TBillDto> billDtos = tBillMapper.getBillList(query);
@@ -124,11 +148,13 @@
         if (isok){
             try {
                 TBill save = new TBill();
+                save.setId(tBill.getId());
                 TBill presist = getById(tBill.getId());
                 //如果账单是已缴费状态,本方法不再进行更新账单
                 if (presist.getPayFeesStatus().equals("3")){
                     throw new ServiceException("该账单已缴费完成");
                 }
+                save.setBusinessDeptId(presist.getBusinessDeptId());
                 switch (type){
                     // 仅更新除金额字段外的属性
                     case 1:
@@ -161,6 +187,7 @@
                             BigDecimal outstand = presist.getPayableFeesMoney()
                                     .add(save.getPayableFeesPenalty())
                                     .subtract(presist.getPayFeesMoney());
+
                             save.setOutstandingMoney(outstand);
                         }
                         //处理缴费金额
@@ -226,6 +253,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){
@@ -280,6 +308,7 @@
             TFlowManagement save = new TFlowManagement();
             save.setPayType(3);
             save.setPayer(dto.getPayer());
+            save.setBusinessDeptId(bill.getBusinessDeptId());
             save.setPayTime(bankflow.getPayTime());
             save.setSysSerialNumber(OrderNos.getDid(30));
             save.setBankSerialNumber(bankflow.getBankSerialNumber());
@@ -305,6 +334,7 @@
         save.setPayType(3);
         save.setPayer(dto.getPayer());
         save.setPayTime(billSave.getPayFeesTime());
+        save.setBusinessDeptId(bill.getBusinessDeptId());
         save.setSysSerialNumber(OrderNos.getDid(30));
         save.setFlowType(1);
         save.setPaymentBillId(back.getId());
@@ -323,62 +353,67 @@
         String uuid = UUID.fastUUID().toString();
         boolean lock = redisCache.trylockLoop(CacheConstants.COMPLETE_PAY_LOCK_KEY + orderNo, uuid, 60);
         if (lock){
-            TPayOrder order = tPayOrderService.getById(orderNo);
-            if (order==null){
-                throw new ServiceException("订单不存在");
-            }
-            if (StringUtils.isNotEmpty(order.getPayNo())){
-                log.info("订单号已处理:{}",orderNo);
-                return;
-            }
-            /**
-             * 更新订单状态
-             */
-            TPayOrder save = new TPayOrder();
-            save.setId(order.getId());
-            save.setStatus(1);
-            save.setPayNo(billRequest.getMessage().getInfo().getTraceNo());
-            save.setPayType(billRequest.getMessage().getHead().getChannel());
             try {
-                save.setPayTime(DateUtils.parseDate(billRequest.getMessage().getHead().getTimeStamp(),"yyyyMMddHHmmssSSS"));
-            } catch (ParseException e) {
-                throw new ServiceException("日期格式化错误");
+                TPayOrder order = tPayOrderService.getById(orderNo);
+                if (order==null){
+                    throw new ServiceException("订单不存在");
+                }
+                if (StringUtils.isNotEmpty(order.getPayNo())){
+                    log.info("订单号已处理:{}",orderNo);
+                    return;
+                }
+                /**
+                 * 更新订单状态
+                 */
+                TPayOrder save = new TPayOrder();
+                save.setId(order.getId());
+                save.setStatus(1);
+                save.setPayNo(billRequest.getMessage().getInfo().getTraceNo());
+                save.setPayType(billRequest.getMessage().getHead().getChannel());
+                try {
+                    save.setPayTime(DateUtils.parseDate(billRequest.getMessage().getHead().getTimeStamp(),"yyyyMMddHHmmssSSS"));
+                } catch (ParseException e) {
+                    throw new ServiceException("日期格式化错误");
+                }
+                save.setCallbackTime(new Date());
+                BigDecimal payAmount = new BigDecimal(billRequest.getMessage().getInfo().getPayBillAmt());
+                save.setActPayAmount(payAmount
+                        .multiply(AmountConstant.b100).longValue());
+                save.setStatus(1);
+                save.setPayInfo(billRequest.getMessage().toString());
+                tPayOrderService.updateById(save);
+                /**
+                 * 更新账单状态
+                 */
+                List<TOrderBill> orderBills = orderBillService.getByOrderNo(order.getId());
+                List<TBill> bills = orderBills.stream().map(ob -> getById(ob.getBillId())).collect(Collectors.toList());
+                lockAndUpdateByAmountBatch(bills,payAmount,(bill)->{
+                    TFlowManagement saveFlow = new TFlowManagement();
+                    saveFlow.setPayType(1);
+                    saveFlow.setPayer(order.getUserId());
+                    saveFlow.setBusinessDeptId(bill.getBusinessDeptId());
+                    saveFlow.setPayTime(DateUtils.dateToLocalDateTime(save.getPayTime()));
+                    saveFlow.setSysSerialNumber(OrderNos.getDid(30));
+                    saveFlow.setBankSerialNumber(save.getPayNo());
+                    saveFlow.setFlowType(2);
+                    saveFlow.setPaymentBillId(bill.getId());
+                    saveFlow.setDeductionMoney(bill.getDeductionMoney());
+                    saveFlow.setFlowMoney(payAmount);
+                    saveFlow.setRemainingMoney(bill.getOutstandingMoney());
+                    saveFlow.setPreOutstand(bill.getPreOutstand());
+                    tFlowManagementService.save(saveFlow);
+                });
+//                TBankFlow bankFlow = new TBankFlow();
+//                bankFlow.setPayType(1);
+//                bankFlow.setPayer(order.getUserId());
+//                bankFlow.setPayTime(DateUtils.dateToLocalDateTime(save.getPayTime()));
+//                bankFlow.setBankSerialNumber(save.getPayNo());
+//                bankFlow.setFlowMoney(payAmount);
+//                bankFlow.setFlowStatus(1);
+//                tBankFlowService.save(bankFlow);
+            }finally {
+                redisCache.unlock(CacheConstants.COMPLETE_PAY_LOCK_KEY + orderNo,uuid);
             }
-            save.setCallbackTime(new Date());
-            BigDecimal payAmount = new BigDecimal(billRequest.getMessage().getInfo().getPayBillAmt());
-            save.setActPayAmount(payAmount
-                    .multiply(AmountConstant.b100).longValue());
-            save.setStatus(1);
-            save.setPayInfo(billRequest.getMessage().toString());
-            tPayOrderService.updateById(save);
-            /**
-             * 更新账单状态
-             */
-            List<TOrderBill> orderBills = orderBillService.getByOrderNo(order.getId());
-            List<TBill> bills = orderBills.stream().map(ob -> getById(ob.getBillId())).collect(Collectors.toList());
-            lockAndUpdateByAmountBatch(bills,payAmount,(bill)->{
-                TFlowManagement saveFlow = new TFlowManagement();
-                saveFlow.setPayType(1);
-                saveFlow.setPayer(order.getUserId());
-                saveFlow.setPayTime(DateUtils.dateToLocalDateTime(save.getPayTime()));
-                saveFlow.setSysSerialNumber(OrderNos.getDid(30));
-                saveFlow.setBankSerialNumber(save.getPayNo());
-                saveFlow.setFlowType(2);
-                saveFlow.setPaymentBillId(bill.getId());
-                saveFlow.setDeductionMoney(bill.getDeductionMoney());
-                saveFlow.setFlowMoney(payAmount);
-                saveFlow.setRemainingMoney(bill.getOutstandingMoney());
-                saveFlow.setPreOutstand(bill.getPreOutstand());
-                tFlowManagementService.save(saveFlow);
-            });
-            TBankFlow bankFlow = new TBankFlow();
-            bankFlow.setPayType(1);
-            bankFlow.setPayer(order.getUserId());
-            bankFlow.setPayTime(DateUtils.dateToLocalDateTime(save.getPayTime()));
-            bankFlow.setBankSerialNumber(save.getPayNo());
-            bankFlow.setFlowMoney(payAmount);
-            bankFlow.setFlowStatus(1);
-            tBankFlowService.save(bankFlow);
 
         }
 
@@ -524,6 +559,7 @@
         TFlowManagement save = new TFlowManagement();
         save.setPayType(3);
         save.setPayer(dto.getPayer());
+        save.setBusinessDeptId(bill.getBusinessDeptId());
         save.setPayTime(bankflow!=null?bankflow.getPayTime():DateUtils.dateToLocalDateTime(new Date()));
         save.setSysSerialNumber(OrderNos.getDid());
         save.setBankSerialNumber(bankflow!=null?bankflow.getBankSerialNumber():null);
@@ -538,12 +574,12 @@
     }
 
     @Override
-    public BillStatisticsDto statistics() {
+    public BillStatisticsDto statistics(TBillQuery query) {
         BillStatisticsDto dto = new BillStatisticsDto();
-        dto.setRent(getBaseMapper().statisticsAllRent());
-        dto.setNopay(getBaseMapper().statisticsNoPay());
-        dto.setPayed(getBaseMapper().statisticsPayed());
-        dto.setOverdue(getBaseMapper().statisticsOverdue());
+        dto.setRent(getBaseMapper().statisticsAllRent(query));
+        dto.setNopay(getBaseMapper().statisticsNoPay(query));
+        dto.setPayed(getBaseMapper().statisticsPayed(query));
+        dto.setOverdue(getBaseMapper().statisticsOverdue(query));
         return dto;
     }
 
@@ -552,5 +588,84 @@
         return this.baseMapper.batchBillCount(userId,billIds);
     }
 
+    /**
+     * 街道租金排行
+     * @return
+     */
+    @Override
+    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
+    public void editAmount(TbillSaveDto bill) {
+        String requestId = UUID.fastUUID().toString();
+        String lockkey = CacheConstants.BILL_UPDATE_LOCK_KEY + bill.getId();
+        boolean isok = redisCache.trylockLoop(lockkey, requestId, 60);
+        if (isok){
+            try {
+                TBill presist = getById(bill.getId());
+                TBill save = new TBill();
+                save.setId(bill.getId());
+                BigDecimal preOutstand = presist.getOutstandingMoney();
+                // 如果传入的金额小于0,则是扣减,如果大于0,是增加金额,增加金额只加入欠费金额中
+                if (bill.getEditAmount().compareTo(BigDecimal.ZERO)<0
+                        && presist.getPayableFeesPenalty().compareTo(BigDecimal.ZERO)>0){
+                    BigDecimal prePayableFeesPenalty = presist.getPayableFeesPenalty();
+                    //违约金大于调整金额,够减
+                    if (prePayableFeesPenalty.compareTo(bill.getEditAmount().abs())>=0){
+                        BigDecimal afterPenalty = prePayableFeesPenalty.add(bill.getEditAmount());
+                        save.setPayableFeesPenalty(afterPenalty);
+                    }else{
+                        BigDecimal afterPenalty = BigDecimal.ZERO;
+                        save.setPayableFeesPenalty(afterPenalty);
+                    }
+                }
+                BigDecimal afterOutstand = preOutstand.add(bill.getEditAmount());
+                save.setOutstandingMoney(afterOutstand);
+                updateById(save);
+            }finally {
+                redisCache.unlock(lockkey,requestId);
+            }
+        }
+
+        //todo 记录金额修改记录
+//        TFlowManagement flow = new TFlowManagement();
+//        flow.setPayType(3);
+//        flow.setPayer("管理员修改");
+//        flow.setBusinessDeptId(presist.getBusinessDeptId());
+//        flow.setPayTime(DateUtils.dateToLocalDateTime(new Date()));
+//        flow.setSysSerialNumber(OrderNos.getDid(30));
+//        flow.setFlowType(1);
+//        flow.setPaymentBillId(back.getId());
+//        flow.setDeductionMoney(back.getDeductionMoney());
+//        flow.setFlowMoney(save.getOutstandingMoney());
+//        flow.setRemainingMoney(back.getOutstandingMoney());
+//        flow.setPreOutstand(back.getPreOutstand());
+//        flow.setCreateBy(SecurityUtils.getUsername());
+//        tFlowManagementService.save(flow);
+    }
+
 
 }
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TBusinessDeptServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TBusinessDeptServiceImpl.java
new file mode 100644
index 0000000..419f956
--- /dev/null
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TBusinessDeptServiceImpl.java
@@ -0,0 +1,20 @@
+package com.ruoyi.system.service.impl;
+
+import com.ruoyi.system.model.TBusinessDept;
+import com.ruoyi.system.mapper.TBusinessDeptMapper;
+import com.ruoyi.system.service.ITBusinessDeptService;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springframework.stereotype.Service;
+
+/**
+ * <p>
+ * 营业部 服务实现类
+ * </p>
+ *
+ * @author mitao
+ * @since 2025-03-24
+ */
+@Service
+public class TBusinessDeptServiceImpl extends ServiceImpl<TBusinessDeptMapper, TBusinessDept> implements ITBusinessDeptService {
+
+}
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TCheckAcceptRecordServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TCheckAcceptRecordServiceImpl.java
index 7006063..d4670a0 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TCheckAcceptRecordServiceImpl.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TCheckAcceptRecordServiceImpl.java
@@ -1,8 +1,12 @@
 package com.ruoyi.system.service.impl;
 
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.ruoyi.common.basic.PageInfo;
 import com.ruoyi.common.constant.DictConstants;
+import com.ruoyi.common.core.domain.entity.SysUser;
 import com.ruoyi.common.utils.DictUtils;
+import com.ruoyi.common.utils.SecurityUtils;
 import com.ruoyi.system.mapper.TCheckAcceptRecordMapper;
 import com.ruoyi.system.mapper.TContractMapper;
 import com.ruoyi.system.mapper.THouseMapper;
@@ -11,15 +15,15 @@
 import com.ruoyi.system.model.THouse;
 import com.ruoyi.system.query.TCheckAcceptRecordAppletQuery;
 import com.ruoyi.system.query.TCheckAcceptRecordQuery;
+import com.ruoyi.system.service.ISysUserService;
 import com.ruoyi.system.service.TCheckAcceptRecordService;
-import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
-import com.ruoyi.system.vo.SysUserVO;
 import com.ruoyi.system.vo.TCheckAcceptRecordVO;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.util.StringUtils;
 
 import java.util.List;
+import java.util.Objects;
 
 /**
  * <p>
@@ -36,9 +40,13 @@
     private TContractMapper contractMapper;
     @Autowired
     private THouseMapper houseMapper;
+    @Autowired
+    private ISysUserService sysUserService;
     @Override
     public PageInfo<TCheckAcceptRecordVO> pageList(TCheckAcceptRecordQuery query) {
         PageInfo<TCheckAcceptRecordVO> pageInfo = new PageInfo<>(query.getPageNum(), query.getPageSize());
+        String businessDeptId = SecurityUtils.getBusinessDeptId();
+        query.setBusinessDeptId(businessDeptId);
         List<TCheckAcceptRecordVO> list = this.baseMapper.pageList(query,pageInfo);
         list.forEach(item -> {
             item.setCleanSituation(StringUtils.hasLength(item.getCleanSituation()) ?(DictUtils.getDictLabel(DictConstants.DICT_TYPE_CHECK_SITUATION,item.getCleanSituation())):"");
@@ -53,8 +61,14 @@
 
     @Override
     public PageInfo<TCheckAcceptRecordVO> pageListApplet(TCheckAcceptRecordAppletQuery query) {
-        List<TContract> tContracts = contractMapper.selectList(null);
-        List<THouse> tHouses = houseMapper.selectList(null);
+        SysUser sysUser = sysUserService.selectUserById(Long.valueOf(query.getSysUserId()));
+        String businessDeptId = "";
+        if (Objects.nonNull(sysUser) && !sysUser.getBusinessDeptId().equals("0")){
+            businessDeptId = sysUser.getBusinessDeptId();
+            query.setBusinessDeptId(businessDeptId);
+        }
+        List<TContract> tContracts = contractMapper.selectList(new LambdaQueryWrapper<TContract>().eq(StringUtils.hasLength(businessDeptId),TContract::getBusinessDeptId,businessDeptId));
+        List<THouse> tHouses = houseMapper.selectList(new LambdaQueryWrapper<THouse>().eq(StringUtils.hasLength(businessDeptId),THouse::getBusinessDeptId,businessDeptId));
         PageInfo<TCheckAcceptRecordVO> pageInfo = new PageInfo<>(query.getPageNum(), query.getPageSize());
         List<TCheckAcceptRecordVO> list = this.baseMapper.pageListApplet(query,pageInfo);
         list.forEach(item -> {
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 30368c2..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
@@ -4,11 +4,13 @@
 import com.aizuda.bpm.mybatisplus.mapper.FlwHisTaskMapper;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.ruoyi.common.basic.PageInfo;
 import com.ruoyi.common.constant.DictConstants;
 import com.ruoyi.common.core.domain.R;
 import com.ruoyi.common.enums.ProcessCategoryEnum;
 import com.ruoyi.common.utils.DictUtils;
+import com.ruoyi.common.utils.SecurityUtils;
 import com.ruoyi.common.utils.bean.BeanUtils;
 import com.ruoyi.system.bo.ProcessStartBO;
 import com.ruoyi.system.dto.SignContractDTO;
@@ -17,7 +19,9 @@
 import com.ruoyi.system.mapper.TCheckAcceptRecordMapper;
 import com.ruoyi.system.mapper.TContractMapper;
 import com.ruoyi.system.mapper.THouseMapper;
-import com.ruoyi.system.model.*;
+import com.ruoyi.system.model.TCheckAcceptRecord;
+import com.ruoyi.system.model.TContract;
+import com.ruoyi.system.model.THouse;
 import com.ruoyi.system.query.TContractAppletQuery;
 import com.ruoyi.system.query.TContractBillQuery;
 import com.ruoyi.system.query.TContractQuery;
@@ -25,21 +29,18 @@
 import com.ruoyi.system.service.TBillService;
 import com.ruoyi.system.service.TContractRentTypeService;
 import com.ruoyi.system.service.TContractService;
-import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 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;
-import org.springframework.util.CollectionUtils;
 
 import javax.annotation.Resource;
-import java.math.BigDecimal;
-import java.time.LocalDate;
 import java.time.LocalDateTime;
-import java.time.temporal.ChronoUnit;
-import java.time.temporal.TemporalAdjusters;
-import java.util.*;
-import java.util.stream.Collectors;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
 
 /**
  * <p>
@@ -69,7 +70,9 @@
     @Override
     public PageInfo<TContract> contractList(TContractQuery query) {
         PageInfo<TContract> pageInfo = new PageInfo<>(query.getPageNum(), query.getPageSize());
-        List<TContract> list = this.baseMapper.contractList(query,pageInfo);
+        //获取当前登录用户信息
+        String businessDeptId = SecurityUtils.getBusinessDeptId();
+        List<TContract> list = this.baseMapper.contractList(query,pageInfo,businessDeptId);
         for (TContract tContract : list) {
             tContract.setPayType(DictUtils.getDictLabel(DictConstants.DICT_TYPE_CONTRACT_PAY_TYPE,tContract.getPayType()));
             tContract.setStatus(DictUtils.getDictLabel(DictConstants.DICT_TYPE_CONTRACT_STATUS,tContract.getStatus()));
@@ -90,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())
@@ -120,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();
@@ -195,7 +201,27 @@
     @Override
     public Boolean updateContractAuditStatus(String projectId, Integer status) {
         LambdaUpdateWrapper<TContract> contractLambdaUpdateWrapper = new LambdaUpdateWrapper<>();
-        contractLambdaUpdateWrapper.eq(TContract::getId, projectId).set(TContract::getStatus, status);
+        contractLambdaUpdateWrapper
+                .eq(TContract::getId, projectId)
+                .set(TContract::getStatus, status)
+                .set(TContract::getSignTime, LocalDateTime.now());
         return this.update(contractLambdaUpdateWrapper);
     }
+
+    /**
+     * 本月新增租户数
+     * @return
+     */
+    @Override
+    public Integer getCurrentMonthRentCount(String businessDeptId) {
+        return baseMapper.getCurrentMonthRentCount(businessDeptId);
+    }
+
+    @Override
+    public PageInfo<TContract> queryPage(TContractQuery query) {
+        PageInfo<TContract> pageInfo = new PageInfo<>(query.getPageNum(), query.getPageSize());
+        pageInfo = this.baseMapper.page(pageInfo,query);
+        return pageInfo;
+    }
+
 }
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TFaultRepairMessageServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TFaultRepairMessageServiceImpl.java
index e763517..40e8985 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TFaultRepairMessageServiceImpl.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TFaultRepairMessageServiceImpl.java
@@ -1,13 +1,13 @@
 package com.ruoyi.system.service.impl;
 
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.ruoyi.common.basic.PageInfo;
+import com.ruoyi.common.utils.SecurityUtils;
 import com.ruoyi.system.mapper.TFaultRepairMessageMapper;
 import com.ruoyi.system.model.TFaultRepairMessage;
 import com.ruoyi.system.query.TFaultRepairMessageAppletQuery;
 import com.ruoyi.system.query.TFaultRepairMessageQuery;
 import com.ruoyi.system.service.TFaultRepairMessageService;
-import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
-import com.ruoyi.system.vo.SysOperLogVO;
 import com.ruoyi.system.vo.TFaultRepairMessageVO;
 import org.springframework.stereotype.Service;
 
@@ -31,6 +31,8 @@
 
     @Override
     public PageInfo<TFaultRepairMessageVO> pageList(TFaultRepairMessageQuery query) {
+        String businessDeptId = SecurityUtils.getBusinessDeptId();
+        query.setBusinessDeptId(businessDeptId);
         PageInfo<TFaultRepairMessageVO> pageInfo = new PageInfo<>(query.getPageNum(), query.getPageSize());
         List<TFaultRepairMessageVO> list = this.baseMapper.pageList(query,pageInfo);
         pageInfo.setRecords(list);
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TFlowManagementServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TFlowManagementServiceImpl.java
index 9cf988d..0a3c5ec 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TFlowManagementServiceImpl.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TFlowManagementServiceImpl.java
@@ -2,6 +2,7 @@
 
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.ruoyi.common.basic.PageInfo;
+import com.ruoyi.common.utils.SecurityUtils;
 import com.ruoyi.common.utils.StringUtils;
 import com.ruoyi.system.mapper.TFlowManagementMapper;
 import com.ruoyi.system.model.TFlowManagement;
@@ -34,6 +35,7 @@
                 .ge(StringUtils.isNotEmpty(query.getPayStartTime()),TFlowManagement::getPayTime,query.getPayStartTime())
                 .lt(StringUtils.isNotEmpty(query.getPayEndTime()),TFlowManagement::getPayTime,query.getPayEndTime())
                 .eq(null != query.getPayType(),TFlowManagement::getPayType,query.getPayType())
+                .eq(StringUtils.isNotEmpty(query.getBusinessDeptId()) && !"0".equals(query.getBusinessDeptId()),TFlowManagement::getBusinessDeptId,query.getBusinessDeptId())
                 .orderByDesc(TFlowManagement::getCreateTime)
         ;
         return this.baseMapper.selectPage(pageInfo,queryWrapper);
@@ -41,7 +43,7 @@
 
     @Override
     public TFlowManagementStatisticsVo getPaymentStats(TFlowManagementQuery query) {
-        return this.baseMapper.getPaymentStats(query);
+        return this.baseMapper.getPaymentStats(query, SecurityUtils.getBusinessDeptId());
     }
 
     @Override
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 259962e..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
@@ -1,9 +1,11 @@
 package com.ruoyi.system.service.impl;
 
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 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.mapper.TContractMapper;
 import com.ruoyi.system.mapper.THouseMapper;
@@ -12,12 +14,12 @@
 import com.ruoyi.system.query.THouseQuery;
 import com.ruoyi.system.query.TUserHistoryQuery;
 import com.ruoyi.system.service.THouseService;
-import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.ruoyi.system.vo.HouseVO;
 import org.springframework.stereotype.Service;
 
 import javax.annotation.Resource;
 import java.time.LocalDateTime;
+import java.util.Arrays;
 import java.util.List;
 
 /**
@@ -34,10 +36,13 @@
     private TContractMapper contractMapper;
     @Override
     public PageInfo<THouse> houseList(THouseQuery query) {
+        //查询当前登录用户所属部门
+        String businessDeptId = SecurityUtils.getBusinessDeptId();
+        query.setBusinessDeptId(businessDeptId);
         PageInfo<THouse> pageInfo = new PageInfo<>(query.getPageNum(), query.getPageSize());
         List<THouse> list = this.baseMapper.houseList(query,pageInfo);
         List<TContract> tContracts = contractMapper.selectList(new LambdaQueryWrapper<TContract>()
-                .eq(TContract::getStatus, 4)
+                .in(TContract::getStatus, Arrays.asList(4,6,7))
                 .le(TContract::getStartTime, LocalDateTime.now())
                 .ge(TContract::getEndTime, LocalDateTime.now()));
         for (THouse tHouse : list) {
@@ -46,10 +51,16 @@
             if (tContract!=null){
                 tHouse.setTenantType(DictUtils.getDictLabel(DictConstants.DICT_TYPE_CONTRACT_PAY_TYPE,tContract.getPayType()));
 //                tHouse.setLeaseStatus(DictUtils.getDictLabel(DictConstants.DICT_TYPE_LEASE_STATUS,"2"));
+                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"));
+
+                }
             }
-                            tHouse.setLeaseStatus(DictUtils.getDictLabel(DictConstants.DICT_TYPE_LEASE_STATUS,tHouse.getLeaseStatus()));
 
         }
         pageInfo.setRecords(list);
@@ -67,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/TInvoiceServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TInvoiceServiceImpl.java
index c0be87b..1fbb4db 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TInvoiceServiceImpl.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TInvoiceServiceImpl.java
@@ -53,12 +53,13 @@
                 .eq(null != query.getStatus(),TInvoice::getStatus,query.getStatus())
                 .ge(StringUtils.isNotEmpty(query.getInvoiceStartTime()),TInvoice::getInvoiceTime,query.getInvoiceStartTime())
                 .le(StringUtils.isNotEmpty(query.getInvoiceEndTime()),TInvoice::getInvoiceTime,query.getInvoiceEndTime())
+                .eq(StringUtils.isNotEmpty(query.getBusinessDeptId())&& ! "0".equals(query.getBusinessDeptId()),TInvoice::getBusinessDeptId,query.getBusinessDeptId())
                 .orderByDesc(TInvoice::getCreateTime);
         return this.baseMapper.selectList(queryWrapper);
     }
 
     @Override
-    public Boolean uploadVoucher(TInvoiceQuery query) {
+    public Boolean uploadVoucher(TInvoiceQuery query, List<Map<String, String>> map) {
         // 检查是否存在对应的发票记录
         TInvoice preexist = getById(query.getId());
         if (preexist == null) {
@@ -73,77 +74,15 @@
         tInvoice.setInvoiceVoucherName(query.getInvoiceVoucherName());
         tInvoice.setInvoiceTime(query.getInvoiceTime());
         tInvoice.setStatus(2);
-
-        // 处理附件信息
-        List<Map<String, String>> attachments = buildAttachments(query.getInvoiceVoucher(), query.getInvoiceVoucherName());
-        if (attachments.isEmpty()) {
-            log.warn("未找到有效的附件信息");
-            return updateById(tInvoice);
-        }
-
         // 异步发送邮件
         CompletableFuture.runAsync(() -> {
             try {
-                mailUtil.sendInvoice(preexist.getEmail(), attachments);
+                mailUtil.sendInvoice(preexist.getEmail(), map);
             } catch (ServiceException e) {
                 log.error("邮件发送失败", e);
             }
         });
-
         // 更新数据库
         return updateById(tInvoice);
     }
-
-    private List<Map<String, String>> buildAttachments(String invoiceVoucher, String invoiceVoucherName) {
-        if (invoiceVoucher == null || invoiceVoucherName == null) {
-            return Collections.emptyList();
-        }
-
-        String[] voucherUrls = invoiceVoucher.split(",");
-        String[] voucherNames = invoiceVoucherName.split(",");
-
-        // 确保两个数组长度一致
-        int length = Math.min(voucherUrls.length, voucherNames.length);
-        if (length == 0) {
-            return Collections.emptyList();
-        }
-
-        // 构建附件列表
-        List<Map<String, String>> attachments = new ArrayList<>(length);
-        for (int i = 0; i < length; i++) {
-            Map<String, String> attachment = new HashMap<>(2); // 初始容量为2,避免扩容
-            attachment.put("url", voucherUrls[i]);
-            attachment.put("fileName", voucherNames[i]);
-            attachments.add(attachment);
-        }
-
-        return attachments;
-    }
-
-    // @Override
-    // public Boolean uploadVoucher(TInvoiceQuery query) {
-    //     TInvoice preexist = getById(query.getId());
-    //     if (preexist == null){
-    //         return false;
-    //     }
-    //     TInvoice tInvoice = new TInvoice();
-    //     tInvoice.setId(query.getId());
-    //     tInvoice.setInvoiceVoucher(query.getInvoiceVoucher());
-    //     tInvoice.setInvoiceVoucherName(query.getInvoiceVoucherName());
-    //     tInvoice.setInvoiceTime(query.getInvoiceTime());
-    //     tInvoice.setStatus(2);
-    //     List<Map<String, String>> mapArrayList = new ArrayList<>();
-    //     String invoiceVoucher = query.getInvoiceVoucher();
-    //     String invoiceVoucherName = query.getInvoiceVoucherName();
-    //
-    //     List<String> list = Arrays.stream(invoiceVoucher.split(",")).collect(Collectors.toList());
-    //     for (int i = 0; i < list.size()-1; i++) {
-    //         Map<String, String> map = new HashMap<>();
-    //         map.put("url", list.get(i));
-    //         map.put("fileName",invoiceVoucherName.split(",")[i]);
-    //         mapArrayList.add(map);
-    //     }
-    //     mailUtil.sendInvoice(preexist.getEmail(),mapArrayList);
-    //     return updateById(tInvoice);
-    // }
 }
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..138b8dd
--- /dev/null
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TRentalReturnRecordServiceImpl.java
@@ -0,0 +1,122 @@
+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());
+            contract.setTerminateTime(record.getCreateTime());
+            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/TStreetServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TStreetServiceImpl.java
new file mode 100644
index 0000000..b303626
--- /dev/null
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TStreetServiceImpl.java
@@ -0,0 +1,20 @@
+package com.ruoyi.system.service.impl;
+
+import com.ruoyi.system.model.TStreet;
+import com.ruoyi.system.mapper.TStreetMapper;
+import com.ruoyi.system.service.ITStreetService;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springframework.stereotype.Service;
+
+/**
+ * <p>
+ * 街道 服务实现类
+ * </p>
+ *
+ * @author mitao
+ * @since 2025-03-19
+ */
+@Service
+public class TStreetServiceImpl extends ServiceImpl<TStreetMapper, TStreet> implements ITStreetService {
+
+}
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 0c1e19f..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
@@ -8,12 +8,10 @@
 import com.ruoyi.common.utils.DictUtils;
 import com.ruoyi.common.utils.StringUtils;
 import com.ruoyi.system.dto.TTenantDTO;
-import com.ruoyi.system.mapper.SysUserMapper;
 import com.ruoyi.system.mapper.TContractMapper;
 import com.ruoyi.system.mapper.THouseMapper;
 import com.ruoyi.system.mapper.TTenantMapper;
 import com.ruoyi.system.model.TContract;
-import com.ruoyi.system.model.TDept;
 import com.ruoyi.system.model.THouse;
 import com.ruoyi.system.model.TTenant;
 import com.ruoyi.system.query.TBillAppletQuery;
@@ -25,7 +23,6 @@
 import com.ruoyi.system.vo.TBillVO;
 import com.ruoyi.system.vo.TenantVO;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.security.core.token.TokenService;
 import org.springframework.stereotype.Service;
 import org.springframework.util.CollectionUtils;
 
@@ -51,7 +48,15 @@
     @Override
     public PageInfo<TenantVO> pageList(TTenantQuery query) {
         PageInfo<TenantVO> pageInfo = new PageInfo<>(query.getPageNum(), query.getPageSize());
-        List<TenantVO> list = this.baseMapper.pageList(query,pageInfo);
+ /*       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..7697d8f 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;
     // 用于更新违约金账单
     // 每分钟执行一次的定时任务
 
@@ -34,8 +39,8 @@
     public void dayOfProportionBill() {
         try {
             // 查询所有未缴费账单
-            List<TBill> list = billMapper.selectList(new LambdaQueryWrapper<TBill>().eq(TBill::getPayFeesStatus, 1)
-                    .le(TBill::getPayableFeesTime,LocalDate.now()));
+            List<TBill> list = billMapper.selectList(new LambdaQueryWrapper<TBill>().ne(TBill::getPayFeesStatus, 5)
+                    .ne(TBill::getOutstandingMoney,0));
             for (TBill tBill : list) {
                 tBill.setPayFeesStatus("4");
                 TContract contract = contractService.getById(tBill.getContractId());
@@ -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
new file mode 100644
index 0000000..7a409d3
--- /dev/null
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/vo/HouseMapDistributionVO.java
@@ -0,0 +1,35 @@
+package com.ruoyi.system.vo;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.math.BigDecimal;
+
+@Data
+@ApiModel("房屋分布")
+public class HouseMapDistributionVO {
+    @ApiModelProperty(value = "房屋名称")
+    private String houseName;
+
+    @ApiModelProperty(value = "房屋地址")
+    private String houseAddress;
+
+    @ApiModelProperty(value = "房屋状态 1=待出租 2=已出租 3=维修中 4=欠费")
+    private String houseStatus;
+
+    @ApiModelProperty(value = "租户")
+    private String tenant;
+
+    @ApiModelProperty(value = "租金状态")
+    private String rentStatus;
+
+    @ApiModelProperty(value = "本季租金")
+    private String rent;
+
+    @ApiModelProperty(value = "经度")
+    private BigDecimal longitude;
+
+    @ApiModelProperty(value = "纬度")
+    private BigDecimal latitude;
+}
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/RealTimeRentDataVO.java b/ruoyi-system/src/main/java/com/ruoyi/system/vo/RealTimeRentDataVO.java
new file mode 100644
index 0000000..1f7eedd
--- /dev/null
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/vo/RealTimeRentDataVO.java
@@ -0,0 +1,28 @@
+package com.ruoyi.system.vo;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+@Data
+@ApiModel(value = "实时租赁数据")
+public class RealTimeRentDataVO {
+
+    @ApiModelProperty(value = "街道名称")
+    private String streetName;
+
+    @ApiModelProperty(value = "房间名称")
+    private String roomName;
+
+    @ApiModelProperty(value = "租赁状态 1=待出租 2=已出租 3=维修中")
+    private String leaseStatus;
+
+    public RealTimeRentDataVO(String streetName, String roomName, String leaseStatus) {
+        this.streetName = streetName;
+        this.roomName = roomName;
+        this.leaseStatus = leaseStatus;
+    }
+
+    public RealTimeRentDataVO() {
+    }
+}
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/java/com/ruoyi/system/vo/ScreenRentIncomeTrendVO.java b/ruoyi-system/src/main/java/com/ruoyi/system/vo/ScreenRentIncomeTrendVO.java
new file mode 100644
index 0000000..1f01605
--- /dev/null
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/vo/ScreenRentIncomeTrendVO.java
@@ -0,0 +1,26 @@
+package com.ruoyi.system.vo;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.math.BigDecimal;
+import java.util.List;
+
+/**
+ * @author mitao
+ * @date 2025/3/20
+ */
+@Data
+@ApiModel("租金收入区域视图对象")
+public class ScreenRentIncomeTrendVO {
+
+    @ApiModelProperty("x轴 时间列表")
+    private List<String> quarters;
+
+    @ApiModelProperty("y轴 收入列表(万元)")
+    private List<BigDecimal> incomeData;
+
+    @ApiModelProperty("y轴 欠费列表(万元)")
+    private List<BigDecimal> outstandingData;
+}
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/vo/ScreenRentRankVO.java b/ruoyi-system/src/main/java/com/ruoyi/system/vo/ScreenRentRankVO.java
new file mode 100644
index 0000000..4b1f3f1
--- /dev/null
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/vo/ScreenRentRankVO.java
@@ -0,0 +1,21 @@
+package com.ruoyi.system.vo;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.math.BigDecimal;
+
+/**
+ * @author mitao
+ * @date 2025/3/19
+ */
+@Data
+@ApiModel("区域租金排名")
+public class ScreenRentRankVO {
+    @ApiModelProperty("街道名称")
+    private String streetName;
+
+    @ApiModelProperty("租金")
+    private BigDecimal rentAmount;
+}
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/vo/ScreenTopStaticsDataVO.java b/ruoyi-system/src/main/java/com/ruoyi/system/vo/ScreenTopStaticsDataVO.java
new file mode 100644
index 0000000..a76573d
--- /dev/null
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/vo/ScreenTopStaticsDataVO.java
@@ -0,0 +1,47 @@
+package com.ruoyi.system.vo;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.math.BigDecimal;
+
+/**
+ * @author mitao
+ * @date 2025/3/19
+ */
+@Data
+@ApiModel("顶部统计数据")
+public class ScreenTopStaticsDataVO {
+
+    @ApiModelProperty("房屋总面积")
+    private Double houseTotalArea;
+
+    @ApiModelProperty("已出租面积")
+    private Double houseRentedArea;
+
+    @ApiModelProperty("总计应收租金(万元)")
+    private BigDecimal totalReceivableRent;
+
+    @ApiModelProperty("总计已收租金(万元)")
+    private BigDecimal totalReceivedRent;
+
+    @ApiModelProperty("本月新增租户数")
+    private Integer newTenantCount;
+
+    @ApiModelProperty("总计租户数")
+    private Integer totalTenantCount;
+
+    @ApiModelProperty("本季度已交租金(万元)")
+    private BigDecimal totalRentPaid;
+
+    @ApiModelProperty("本季度应交租金(万元)")
+    private BigDecimal totalRentShould;
+
+    @ApiModelProperty("本季度欠费(万元)")
+    private BigDecimal totalRentOwe;
+
+    @ApiModelProperty("总计欠费(万元)")
+    private BigDecimal totalRentOweAll;
+}
+
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/vo/TenantCountTrendVO.java b/ruoyi-system/src/main/java/com/ruoyi/system/vo/TenantCountTrendVO.java
new file mode 100644
index 0000000..75684bc
--- /dev/null
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/vo/TenantCountTrendVO.java
@@ -0,0 +1,22 @@
+package com.ruoyi.system.vo;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+@Data
+@ApiModel("租户数量趋势统计")
+public class TenantCountTrendVO {
+    @ApiModelProperty(value = "日期")
+    private String date;
+    @ApiModelProperty(value = "租户数量")
+    private Long count;
+
+    public TenantCountTrendVO(String date, Long count) {
+        this.date = date;
+        this.count = count;
+    }
+
+    public TenantCountTrendVO() {
+    }
+}
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/vo/YearQuarter.java b/ruoyi-system/src/main/java/com/ruoyi/system/vo/YearQuarter.java
new file mode 100644
index 0000000..8e175c7
--- /dev/null
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/vo/YearQuarter.java
@@ -0,0 +1,31 @@
+package com.ruoyi.system.vo;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+
+import java.time.LocalDate;
+import java.time.format.DateTimeFormatter;
+import java.util.Comparator;
+
+@Data
+@AllArgsConstructor
+public class YearQuarter implements Comparable<YearQuarter> {
+    private int year;
+    private int quarter;
+
+    public static YearQuarter from(LocalDate date) {
+        int quarter = (date.getMonthValue() - 1) / 3 + 1;
+        return new YearQuarter(date.getYear(), quarter);
+    }
+
+    public String format(DateTimeFormatter formatter) {
+        return formatter.format(LocalDate.of(year, quarter * 3 - 2, 1));
+    }
+
+    @Override
+    public int compareTo(YearQuarter other) {
+        return Comparator.comparingInt(YearQuarter::getYear)
+                .thenComparingInt(YearQuarter::getQuarter)
+                .compare(this, other);
+    }
+}
diff --git a/ruoyi-system/src/main/resources/mapper/system/SysUserMapper.xml b/ruoyi-system/src/main/resources/mapper/system/SysUserMapper.xml
index a3fff3f..0e84df6 100644
--- a/ruoyi-system/src/main/resources/mapper/system/SysUserMapper.xml
+++ b/ruoyi-system/src/main/resources/mapper/system/SysUserMapper.xml
@@ -25,6 +25,7 @@
         <result property="remark"       column="remark"       />
         <result property="ifBlack"       column="ifBlack"       />
         <result property="districtId"       column="districtId"       />
+        <result property="businessDeptId"       column="business_dept_id"       />
         <association property="dept"    javaType="SysDept"         resultMap="deptResult" />
         <collection  property="roles"   javaType="java.util.List"  resultMap="RoleResult" />
     </resultMap>
@@ -49,7 +50,7 @@
     </resultMap>
 	
 	<sql id="selectUserVo">
-        select u.user_id, u.dept_id, u.user_name, u.nick_name, u.email, u.avatar, u.phonenumber, u.password, u.sex, u.status, u.del_flag, u.login_ip, u.login_date, u.create_by, u.create_time, u.remark, 
+        select u.user_id, u.dept_id, u.user_name, u.nick_name, u.email, u.avatar, u.phonenumber, u.password, u.sex, u.status, u.del_flag, u.login_ip, u.login_date, u.create_by, u.create_time, u.remark, u.business_dept_id,
         d.dept_id, d.parent_id, d.ancestors, d.dept_name, d.order_num, d.leader, d.status as dept_status,
         r.role_id, r.role_name, r.role_key, r.role_sort, r.data_scope, r.status as role_status
         from sys_user u
@@ -131,7 +132,7 @@
 	<select id="selectUserById" parameterType="Long" resultType="com.ruoyi.common.core.domain.entity.SysUser">
 		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.phonenumber AS phonenumber, u.sex AS sex, u.status AS status, u.del_flag AS delFlag, u.login_ip AS loginIp,
-			   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,
+			   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,u.business_dept_id AS businessDeptId,
 			   ur.role_id AS roleId,sr.role_name AS roleName,u.deptName as deptName
 		from sys_user u
 		left join sys_user_role ur on u.user_id = ur.user_id
@@ -224,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
@@ -247,6 +249,9 @@
 			<foreach collection="query.roleIds" close=")" open="(" item="roleId" separator=",">
 				#{roleId}
 			</foreach>
+		</if>
+		<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
 	</select>
@@ -271,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>
@@ -289,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>
@@ -315,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/TBankFlowMapper.xml b/ruoyi-system/src/main/resources/mapper/system/TBankFlowMapper.xml
index 8995310..06126b6 100644
--- a/ruoyi-system/src/main/resources/mapper/system/TBankFlowMapper.xml
+++ b/ruoyi-system/src/main/resources/mapper/system/TBankFlowMapper.xml
@@ -58,6 +58,9 @@
             <if test="req.payEndTime != null and req.payEndTime != ''">
                 and pay_time &lt;= #{req.payEndTime}
             </if>
+            <if test='businessDeptId != null and businessDeptId != "" and businessDeptId != "0"'>
+                and business_dept_id = #{businessDeptId}
+            </if>
             AND disabled = ${@com.ruoyi.common.enums.DisabledEnum@NO.getCode()}
         </where>
     </select>
diff --git a/ruoyi-system/src/main/resources/mapper/system/TBillMapper.xml b/ruoyi-system/src/main/resources/mapper/system/TBillMapper.xml
index 81d281c..d362ce5 100644
--- a/ruoyi-system/src/main/resources/mapper/system/TBillMapper.xml
+++ b/ruoyi-system/src/main/resources/mapper/system/TBillMapper.xml
@@ -45,6 +45,7 @@
         LEFT JOIN t_contract c ON c.contract_number = b.contract_number and c.disabled=0
         LEFT JOIN t_house h ON h.id = c.house_id and h.disabled=0
         LEFT JOIN t_tenant t ON t.id = c.tenant_id and t.disabled=0
+        LEFT JOIN t_bill_type_sort_weight sw on sw.code=b.pay_fees_status
         <where>
             b.disabled=0
             <if test="query.payFeesStatus != null">
@@ -62,9 +63,57 @@
             <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'>
+                and b.business_dept_id = #{query.businessDeptId}
+            </if>
+            <if test="query.billType != null">
+                and b.bill_type = #{query.billType}
+            </if>
         </where>
-        order by b.payable_fees_time desc,b.create_time desc
+        order by sw.sort_weight desc,b.payable_fees_time asc
+<!--        order by b.payable_fees_time desc,b.create_time desc-->
     </select>
+
+    <select id="pageForApplet" resultType="com.ruoyi.system.dto.TBillDto">
+        SELECT
+        b.*,
+        t.resident_name as residentName,
+        t.phone,
+        t.account,
+        h.house_name as houseName
+        FROM
+        t_bill b
+        LEFT JOIN t_contract c ON c.contract_number = b.contract_number and c.disabled=0
+        LEFT JOIN t_house h ON h.id = c.house_id and h.disabled=0
+        LEFT JOIN t_tenant t ON t.id = c.tenant_id and t.disabled=0
+        LEFT JOIN t_bill_type_sort_weight sw on sw.code=b.pay_fees_status
+        <where>
+            b.disabled=0
+            <if test="query.payFeesStatus != null">
+                and b.pay_fees_status = #{query.payFeesStatus}
+            </if>
+            <if test="query.phone != null and query.phone !=''">
+                and t.phone = #{query.phone}
+            </if>
+            <if test="query.residentName != null and query.residentName !=''">
+                and t.resident_name like concat('%',#{query.residentName},'%')
+            </if>
+            <if test="query.contractNumber != null and query.contractNumber !=''">
+                and b.contract_number = #{query.contractNumber}
+            </if>
+            <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"'>
+                and b.business_dept_id = #{query.businessDeptId}
+            </if>
+            <if test="query.billType != null">
+                and b.bill_type = #{query.billType}
+            </if>
+        </where>
+        order by sw.sort_weight desc,b.payable_fees_time asc
+    </select>
+
     <select id="getBillList" resultType="com.ruoyi.system.dto.TBillDto">
         SELECT
         b.*,
@@ -151,19 +200,128 @@
     </select>
 
     <select id="statisticsAllRent" resultType="java.math.BigDecimal">
-        SELECT ifnull(sum(payable_fees_money),0) as amount FROM t_bill
+        SELECT ifnull(sum(payable_fees_money),0) as amount FROM t_bill b
+        LEFT JOIN t_contract c ON c.contract_number = b.contract_number and c.disabled=0
+        LEFT JOIN t_house h ON h.id = c.house_id and h.disabled=0
+        LEFT JOIN t_tenant t ON t.id = c.tenant_id and t.disabled=0
+        <where>
+            b.disabled=0 and b.pay_fees_status!='5'
+            <if test="query.payFeesStatus != null">
+                and b.pay_fees_status = #{query.payFeesStatus}
+            </if>
+            <if test="query.phone != null and query.phone !=''">
+                and t.phone = #{query.phone}
+            </if>
+            <if test="query.residentName != null and query.residentName !=''">
+                and t.resident_name like concat('%',#{query.residentName},'%')
+            </if>
+            <if test="query.contractNumber != null and query.contractNumber !=''">
+                and b.contract_number = #{query.contractNumber}
+            </if>
+            <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"'>
+                and b.business_dept_id = #{query.businessDeptId}
+            </if>
+            <if test="query.billType != null">
+                and b.bill_type = #{query.billType}
+            </if>
+        </where>
+
     </select>
 
     <select id="statisticsNoPay" resultType="java.math.BigDecimal">
-        SELECT ifnull(sum(outstanding_money),0) as amount FROM t_bill where pay_fees_status!=3
+        SELECT ifnull(sum(outstanding_money),0) as amount FROM t_bill b
+        LEFT JOIN t_contract c ON c.contract_number = b.contract_number and c.disabled=0
+        LEFT JOIN t_house h ON h.id = c.house_id and h.disabled=0
+        LEFT JOIN t_tenant t ON t.id = c.tenant_id and t.disabled=0
+        <where>
+            b.disabled=0 and b.pay_fees_status!='3' and b.pay_fees_status!='5'
+            <if test="query.payFeesStatus != null">
+                and b.pay_fees_status = #{query.payFeesStatus}
+            </if>
+            <if test="query.phone != null and query.phone !=''">
+                and t.phone = #{query.phone}
+            </if>
+            <if test="query.residentName != null and query.residentName !=''">
+                and t.resident_name like concat('%',#{query.residentName},'%')
+            </if>
+            <if test="query.contractNumber != null and query.contractNumber !=''">
+                and b.contract_number = #{query.contractNumber}
+            </if>
+            <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"'>
+                and b.business_dept_id = #{query.businessDeptId}
+            </if>
+            <if test="query.billType != null">
+                and b.bill_type = #{query.billType}
+            </if>
+        </where>
     </select>
 
     <select id="statisticsPayed" resultType="java.math.BigDecimal">
-        SELECT ifnull(sum(pay_fees_money),0) as amount FROM t_bill
+        SELECT ifnull(sum(pay_fees_money),0) as amount FROM t_bill b
+        LEFT JOIN t_contract c ON c.contract_number = b.contract_number and c.disabled=0
+        LEFT JOIN t_house h ON h.id = c.house_id and h.disabled=0
+        LEFT JOIN t_tenant t ON t.id = c.tenant_id and t.disabled=0
+        <where>
+            b.disabled=0 and b.pay_fees_status!='5'
+            <if test="query.payFeesStatus != null">
+                and b.pay_fees_status = #{query.payFeesStatus}
+            </if>
+            <if test="query.phone != null and query.phone !=''">
+                and t.phone = #{query.phone}
+            </if>
+            <if test="query.residentName != null and query.residentName !=''">
+                and t.resident_name like concat('%',#{query.residentName},'%')
+            </if>
+            <if test="query.contractNumber != null and query.contractNumber !=''">
+                and b.contract_number = #{query.contractNumber}
+            </if>
+            <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"'>
+                and b.business_dept_id = #{query.businessDeptId}
+            </if>
+            <if test="query.billType != null">
+                and b.bill_type = #{query.billType}
+            </if>
+        </where>
     </select>
 
     <select id="statisticsOverdue" resultType="java.math.BigDecimal">
-        SELECT ifnull(sum(outstanding_money),0) as amount FROM t_bill where pay_fees_status=4
+        SELECT ifnull(sum(outstanding_money),0) as amount FROM t_bill b
+        LEFT JOIN t_contract c ON c.contract_number = b.contract_number and c.disabled=0
+        LEFT JOIN t_house h ON h.id = c.house_id and h.disabled=0
+        LEFT JOIN t_tenant t ON t.id = c.tenant_id and t.disabled=0
+        <where>
+            b.disabled=0 and b.pay_fees_status='4'
+            <if test="query.payFeesStatus != null">
+                and b.pay_fees_status = #{query.payFeesStatus}
+            </if>
+            <if test="query.phone != null and query.phone !=''">
+                and t.phone = #{query.phone}
+            </if>
+            <if test="query.residentName != null and query.residentName !=''">
+                and t.resident_name like concat('%',#{query.residentName},'%')
+            </if>
+            <if test="query.contractNumber != null and query.contractNumber !=''">
+                and b.contract_number = #{query.contractNumber}
+            </if>
+            <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"'>
+                and b.business_dept_id = #{query.businessDeptId}
+            </if>
+            <if test="query.billType != null">
+                and b.bill_type = #{query.billType}
+            </if>
+        </where>
     </select>
     <select id="batchBillCount" resultType="java.lang.Integer">
         SELECT
@@ -186,4 +344,32 @@
             AND b.bill_type = 3
         </where>
     </select>
+    <select id="getStreetRentRank" resultType="com.ruoyi.system.vo.ScreenRentRankVO">
+        SELECT
+            ts.street_name,ROUND(COALESCE(SUM(tb.pay_fees_money),0) /10000,2) AS rentAmount
+        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 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/TBusinessDeptMapper.xml b/ruoyi-system/src/main/resources/mapper/system/TBusinessDeptMapper.xml
new file mode 100644
index 0000000..d14b117
--- /dev/null
+++ b/ruoyi-system/src/main/resources/mapper/system/TBusinessDeptMapper.xml
@@ -0,0 +1,5 @@
+<?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.TBusinessDeptMapper">
+
+</mapper>
diff --git a/ruoyi-system/src/main/resources/mapper/system/TCheckAcceptRecordMapper.xml b/ruoyi-system/src/main/resources/mapper/system/TCheckAcceptRecordMapper.xml
index f0f1693..1b95b44 100644
--- a/ruoyi-system/src/main/resources/mapper/system/TCheckAcceptRecordMapper.xml
+++ b/ruoyi-system/src/main/resources/mapper/system/TCheckAcceptRecordMapper.xml
@@ -76,6 +76,9 @@
                 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">
+                AND c.business_dept_id = #{query.businessDeptId}
+            </if>
             AND t.disabled = ${@com.ruoyi.common.enums.DisabledEnum@NO.getCode()}
         </where>
         ORDER BY t.create_time DESC
@@ -99,6 +102,9 @@
             <if test="query.houseNameOrAddress != null and query.houseNameOrAddress != ''">
                 AND (h.house_name LIKE concat('%', #{query.houseNameOrAddress}, '%') or h.house_address LIKE concat('%', #{query.houseNameOrAddress}, '%'))
             </if>
+            <if test="query.businessDeptId != null and query.businessDeptId != ''">
+                AND h.business_dept_id =#{query.businessDeptId}
+            </if>
             AND t.disabled = ${@com.ruoyi.common.enums.DisabledEnum@NO.getCode()}
         </where>
         ORDER BY t.create_time DESC
diff --git a/ruoyi-system/src/main/resources/mapper/system/TContractMapper.xml b/ruoyi-system/src/main/resources/mapper/system/TContractMapper.xml
index 66ccabf..81dc703 100644
--- a/ruoyi-system/src/main/resources/mapper/system/TContractMapper.xml
+++ b/ruoyi-system/src/main/resources/mapper/system/TContractMapper.xml
@@ -68,6 +68,9 @@
                     #{item}
                 </foreach>
             </if>
+            <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()}
         </where>
         order by t1.create_time desc
@@ -124,5 +127,55 @@
 
         </where>
     </select>
+    <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 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">
+        select * from t_contract
+        <where>
+            <if test="query.partyTwoName != null and query.partyTwoName != ''">
+                and party_two_name like concat('%',#{query.partyTwoName},'%')
+            </if>
+            <if test="query.contractNumber != null and query.contractNumber != ''">
+                and contract_number like concat('%',#{query.contractNumber},'%')
+            </if>
+            <if test="query.contractName != null and query.contractName != ''">
+                and contract_name like concat('%',#{query.contractName},'%')
+            </if>
+            <if test="query.status != null">
+                and status = #{query.status}
+            </if>
+            <if test="query.tenantId != null">
+                and tenant_id = #{query.tenantId}
+            </if>
+            <if test="query.statuses != null and query.statuses.size()>0">
+                and status in
+                <foreach collection="query.statuses" item="item" open="(" separator="," close=")">
+                    #{item}
+                </foreach>
+            </if>
+            <if test='query.businessDeptId!=null and query.businessDeptId !="" and query.businessDeptId != "0"'>
+                and business_dept_id = #{query.businessDeptId}
+            </if>
+            AND disabled = ${@com.ruoyi.common.enums.DisabledEnum@NO.getCode()}
+        </where>
+        order by create_time desc
+    </select>
 </mapper>
diff --git a/ruoyi-system/src/main/resources/mapper/system/TFaultRepairMessageMapper.xml b/ruoyi-system/src/main/resources/mapper/system/TFaultRepairMessageMapper.xml
index ba2c3f1..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
@@ -112,6 +113,7 @@
                  LEFT JOIN t_item i ON t.item_id = i.id
                  LEFT JOIN t_item_type it ON t.item_type_id = it.id
                  LEFT JOIN t_tenant tnt ON t.tenant_id = tnt.id
+                 LEFT JOIN t_contract tc ON t.contract_id = tc.id
         <where>
             <if test="query.residentName != null and query.residentName != ''">
                 AND tnt.resident_name LIKE CONCAT('%', #{query.residentName}, '%')
@@ -128,6 +130,9 @@
             <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">
+                AND tc.business_dept_id = #{query.businessDeptId}
+            </if>
             AND t.disabled = ${@com.ruoyi.common.enums.DisabledEnum@NO.getCode()}
         </where>
         ORDER BY t.create_time DESC
diff --git a/ruoyi-system/src/main/resources/mapper/system/TFlowManagementMapper.xml b/ruoyi-system/src/main/resources/mapper/system/TFlowManagementMapper.xml
index 136ec5f..6e2d276 100644
--- a/ruoyi-system/src/main/resources/mapper/system/TFlowManagementMapper.xml
+++ b/ruoyi-system/src/main/resources/mapper/system/TFlowManagementMapper.xml
@@ -64,6 +64,9 @@
             <if test="req.payEndTime != null and req.payEndTime != ''">
                  and pay_time &lt;= #{req.payEndTime}
             </if>
+            <if test='businessDeptId != null and businessDeptId != "" and businessDeptId != "0"'>
+                and business_dept_id = #{businessDeptId}
+            </if>
             AND disabled = ${@com.ruoyi.common.enums.DisabledEnum@NO.getCode()}
         </where>
     </select>
diff --git a/ruoyi-system/src/main/resources/mapper/system/THouseMapper.xml b/ruoyi-system/src/main/resources/mapper/system/THouseMapper.xml
index d5450f9..f6a5a13 100644
--- a/ruoyi-system/src/main/resources/mapper/system/THouseMapper.xml
+++ b/ruoyi-system/src/main/resources/mapper/system/THouseMapper.xml
@@ -55,6 +55,9 @@
             <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">
+                and t1.business_dept_id = #{req.businessDeptId}
+            </if>
             AND t1.disabled = ${@com.ruoyi.common.enums.DisabledEnum@NO.getCode()}
         </where>
         order by t1.create_time desc
@@ -83,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>
diff --git a/ruoyi-system/src/main/resources/mapper/system/TStreetMapper.xml b/ruoyi-system/src/main/resources/mapper/system/TStreetMapper.xml
new file mode 100644
index 0000000..296a7b9
--- /dev/null
+++ b/ruoyi-system/src/main/resources/mapper/system/TStreetMapper.xml
@@ -0,0 +1,5 @@
+<?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.TStreetMapper">
+
+</mapper>
diff --git a/ruoyi-system/src/main/resources/mapper/system/TTenantMapper.xml b/ruoyi-system/src/main/resources/mapper/system/TTenantMapper.xml
index 112f54f..5795000 100644
--- a/ruoyi-system/src/main/resources/mapper/system/TTenantMapper.xml
+++ b/ruoyi-system/src/main/resources/mapper/system/TTenantMapper.xml
@@ -112,5 +112,28 @@
             </otherwise>
         </choose>
     </select>
+    <select id="pageListByBusinessDeptId" resultType="com.ruoyi.system.vo.TenantVO">
+        SELECT * FROM (
+        SELECT tt.id, tt.resident_name, tt.checkIn_time, tt.tenant_attributes, tt.tenant_type, tt.phone,
+        tt.id_card, tt.email,
+        tt.bank_number, tt.mail_address, tt.create_time, tt.disabled,tt.account
+        FROM t_tenant tt
+        WHERE EXISTS (
+        SELECT 1
+        FROM t_contract tc
+        WHERE tc.tenant_id = tt.id AND tc.business_dept_id = #{query.businessDeptId}
+        )
+        ) AS te
+        <where>
+            <if test="query.residentName != null and query.residentName != ''">
+                AND te.resident_name LIKE concat('%',#{query.residentName},'%')
+            </if>
+            <if test="query.phone != null and query.phone != ''">
+                AND te.phone LIKE concat('%',#{query.phone},'%')
+            </if>
+            AND te.disabled = ${@com.ruoyi.common.enums.DisabledEnum@NO.getCode()}
+        </where>
+        ORDER BY te.create_time DESC
+    </select>
 
 </mapper>

--
Gitblit v1.7.1