From da81542b6dc8984f639687f30e7e610dc139b085 Mon Sep 17 00:00:00 2001
From: 无关风月 <443237572@qq.com>
Date: 星期二, 18 三月 2025 13:21:12 +0800
Subject: [PATCH] Merge branch 'master' of https://gitee.com/xiaochen991015/xizang

---
 ruoyi-common/src/main/java/com/ruoyi/common/utils/TencentMailUtil.java                     |  113 ++++
 ruoyi-admin/src/main/resources/application-test.yml                                        |    5 
 ruoyi-applet/src/main/java/com/ruoyi/web/controller/api/TFaultRepairMessageController.java |    2 
 ruoyi-system/src/main/resources/mapper/system/TBillMapper.xml                              |   24 +
 ruoyi-system/src/main/java/com/ruoyi/system/service/TBillService.java                      |    2 
 ruoyi-system/src/main/java/com/ruoyi/system/query/TBillQuery.java                          |    5 
 generator/src/test/java/com/xizang/CodeGeneratorTests.java                                 |    6 
 ruoyi-applet/src/main/resources/application-prod.yml                                       |   32 
 ruoyi-applet/src/main/java/com/ruoyi/web/controller/api/TBillController.java               |   14 
 ruoyi-admin/src/main/java/com/ruoyi/web/controller/task/TaskUtil.java                      |   20 
 ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysUserController.java           |    2 
 ruoyi-system/src/main/resources/mapper/system/THouseMapper.xml                             |    2 
 ruoyi-applet/src/main/resources/application.yml                                            |    2 
 ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TBillServiceImpl.java             |   87 +++-
 ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TInvoiceController.java             |    9 
 ruoyi-system/src/main/java/com/ruoyi/system/dto/OfflinePayCheckDto.java                    |    6 
 ruoyi-admin/src/main/resources/application.yml                                             |    2 
 ruoyi-applet/src/main/resources/application-test.yml                                       |    3 
 ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TFaultDescribeDicController.java    |    4 
 ruoyi-admin/src/main/resources/application-prod.yml                                        |   41 +
 ruoyi-system/src/main/java/com/ruoyi/system/service/TInvoiceService.java                   |    1 
 ruoyi-system/src/main/java/com/ruoyi/system/service/impl/FlowListenerService.java          |  750 +++++++++++++++++-----------------
 ruoyi-system/src/main/java/com/ruoyi/system/mapper/TBillMapper.java                        |    2 
 ruoyi-system/src/main/java/com/ruoyi/system/dto/BatchBillDTO.java                          |   18 
 ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TInvoiceServiceImpl.java          |   99 ++++
 25 files changed, 779 insertions(+), 472 deletions(-)

diff --git a/generator/src/test/java/com/xizang/CodeGeneratorTests.java b/generator/src/test/java/com/xizang/CodeGeneratorTests.java
index 64dd914..8a5e34c 100644
--- a/generator/src/test/java/com/xizang/CodeGeneratorTests.java
+++ b/generator/src/test/java/com/xizang/CodeGeneratorTests.java
@@ -35,9 +35,9 @@
 
         // 全局配置
         GlobalConfig gc = new GlobalConfig();
-        String projectPath = "F:\\workSpace\\xizang\\generator";
+        String projectPath = "D:\\workspaces\\Project\\company\\changyun\\xizang\\xizang\\generator";
         gc.setOutputDir(projectPath + "/src/main/java")
-                .setAuthor("xiaochen")
+                .setAuthor("yupeng")
                 .setMapperName("%sMapper")
                 .setXmlName("%sMapper")
                 .setServiceName("%sService")
@@ -144,7 +144,7 @@
 //         strategy.setTablePrefix(pc.getModuleName() + "");
 //        strategy.setLikeTable(new LikeTable("room"));
         //strategy.setLikeTable(new LikeTable("member"));
-        strategy.setLikeTable(new LikeTable("t_bank_flow"));// 生成表名
+        strategy.setLikeTable(new LikeTable("sys_file"));// 生成表名
 //        strategy.setLikeTable(new LikeTable("t_hotel"));// 生成表名
 //        strategy.setLikeTable(new LikeTable("t_scan_message"));// 生成表名
 //        strategy.setNotLikeTable(new LikeTable("hotel_info"));// 不生成表名
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 ddd4270..d3530a7 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
@@ -16,6 +16,7 @@
 import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.*;
 
+import java.time.LocalDateTime;
 import java.util.List;
 
 /**
@@ -67,6 +68,7 @@
     @ApiOperation(value = "修改故障描述")
     @PostMapping(value = "/update")
     public R<Boolean> update(@Validated @RequestBody TFaultDescribeDic dto) {
+        dto.setUpdateTime(LocalDateTime.now());
         return R.ok(faultDescribeDicService.updateById(dto));
     }
 
@@ -101,6 +103,6 @@
     public R<Boolean> deleteByIds(@RequestBody List<String> ids) {
         return R.ok(faultDescribeDicService.removeByIds(ids));
     }
-    
+
 }
 
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 f074175..157d180 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.TencentMailUtil;
 import com.ruoyi.system.dto.TBillDto;
 import com.ruoyi.system.model.TBill;
 import com.ruoyi.system.model.TInvoice;
@@ -57,13 +58,7 @@
     @PostMapping("/uploadVoucher")
     @PreAuthorize("@ss.hasPermi('invoice:list:payment')")
     public R<Boolean> uploadVoucher(@RequestBody TInvoiceQuery query) {
-        TInvoice tInvoice = new TInvoice();
-        tInvoice.setId(query.getId());
-        tInvoice.setInvoiceVoucher(query.getInvoiceVoucher());
-        tInvoice.setInvoiceVoucherName(query.getInvoiceVoucherName());
-        tInvoice.setInvoiceTime(query.getInvoiceTime());
-        tInvoice.setStatus(2);
-        return R.ok(invoiceService.updateById(tInvoice));
+        return R.ok(invoiceService.uploadVoucher(query));
     }
 }
 
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 e4755e8..b44867f 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
@@ -156,7 +156,7 @@
     @PostMapping("/add")
     public AjaxResult add(@Validated @RequestBody SysUser user)
     {
-        user.setUserName(user.getPhonenumber());
+        user.setUserName(user.getUserName());
         if (!userService.checkUserNameUnique(user))
         {
             return error("新增用户'" + user.getUserName() + "'失败,登录账号已存在");
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/task/TaskUtil.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/task/TaskUtil.java
index 1b8b4e9..2fc75ee 100644
--- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/task/TaskUtil.java
+++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/task/TaskUtil.java
@@ -2,6 +2,7 @@
 //
 //
 //import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+//import com.ruoyi.common.utils.SmsUtil;
 //import com.ruoyi.system.mapper.TBillMapper;
 //import com.ruoyi.system.model.TBill;
 //import com.ruoyi.system.model.TContract;
@@ -40,7 +41,6 @@
 //    // 用于更新违约金账单
 //    // 每分钟执行一次的定时任务
 //
-////    @Scheduled(cron = "0 0 0 * * ?")
 //    @Scheduled(cron = "0 * * * * ?")
 //    public void dayOfProportionBill() {
 //        try {
@@ -79,23 +79,5 @@
 //        }
 //    }
 //
-//    public static void main(String[] args) {
-//
-////        LocalDateTime now = LocalDateTime.now().minusMonths(1).withDayOfMonth(31);
-////        System.err.println(now);
-////        LocalDateTime now2 = now.plusMonths(1);
-////        System.err.println(now2);
-////
-////        LocalDateTime now1 = LocalDateTime.now();
-////        long days = ChronoUnit.DAYS.between(now, now1);
-////        long days2 = ChronoUnit.DAYS.between(now.plusDays(1), now1);
-////
-////        System.err.println(days);
-////        System.err.println(days2);
-////        LocalDateTime endTime = now.with(TemporalAdjusters.lastDayOfMonth()).withSecond(59).withHour(23).withMinute(59);
-////
-////        System.err.println(endTime);
-//
-//    }
 //
 //}
diff --git a/ruoyi-admin/src/main/resources/application-prod.yml b/ruoyi-admin/src/main/resources/application-prod.yml
index db91005..b00292d 100644
--- a/ruoyi-admin/src/main/resources/application-prod.yml
+++ b/ruoyi-admin/src/main/resources/application-prod.yml
@@ -14,14 +14,13 @@
   addressEnabled: false
   # 验证码类型 math 数字计算 char 字符验证
   captchaType: math
-
 # 开发环境配置
 server:
   # 服务器的HTTP端口,默认为8080
-  port: 8081
+  port: 8080
   servlet:
     # 应用的访问路径
-    context-path: /admin
+    context-path: /
   tomcat:
     # tomcat的URI编码
     uri-encoding: UTF-8
@@ -70,13 +69,20 @@
   # redis 配置
   redis:
     # 地址
+    #    host: 127.0.0.1
+    #    # 端口,默认为6379
+    #    port: 6379
+    #    # 数据库索引
+    #    database: 0
+    #    # 密码
+    #    password: 123456
     host: 127.0.0.1
     # 端口,默认为6379
-    port: 6379
+    port: 16379
     # 数据库索引
     database: 0
     # 密码
-    password: 123456
+    password: 8f5z9g52gx4bg
     # 连接超时时间
     timeout: 10s
     lettuce:
@@ -89,16 +95,16 @@
         max-active: 8
         # #连接池最大阻塞等待时间(使用负值表示没有限制)
         max-wait: -1ms
-# 数据源配置
+  # 数据源配置
   datasource:
     type: com.alibaba.druid.pool.DruidDataSource
     driverClassName: com.mysql.cj.jdbc.Driver
     druid:
       # 主库数据源
       master:
-        url: jdbc:mysql://127.0.0.1:10633/xizang?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=Asia/Shanghai
-        username: root
-        password: XiZang@2025!
+        url: jdbc:mysql://172.27.0.13:3306/xizang?autoReconnect=true&useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=Asia/Shanghai
+        username: xzgt
+        password: changyun!6f2gshj6h3j
       # 从库数据源
       slave:
         # 从数据源开关/默认关闭
@@ -149,7 +155,6 @@
         wall:
           config:
             multi-statement-allow: true
-
 # token配置
 token:
   # 令牌自定义标识
@@ -167,7 +172,7 @@
     db-config:
       logic-not-delete-value: 0
       logic-delete-value: 1
-  type-aliases-package: com.ruoyi.**.domain,com.ruoyi.**.vo
+  type-aliases-package: com.ruoyi.**.domain,com.ruoyi.**.vo,com.ruoyi.**.model
   # 指定Mapper文件位置
   mapper-locations: classpath*:mapper/**/*.xml
 
@@ -193,10 +198,12 @@
     qrLocation: /file/qrCode/
     accessPath: /file/
     allowExt: .jpg|.png|.gif|.jpeg|.doc|.docx|.apk|.MP4|.mp4|.pdf|.PDF
+  url:
+    prefix: https://xzgt.test.591taxi.cn:${server.port}${server.servlet.context-path}
 wx:
-  config:
-    appId: wxc3985a05da7d86dc
-    secret: 5cca42633c25439613b328c08ef20cc9
+  conf:
+    appId: wxe91f1af7638aa5dd
+    secretId: a787e1a462715604e0c9528b6d8960d1
 #OSS及短信配置
 code:
   config:
@@ -214,6 +221,12 @@
     bucketAddr: ap-chengdu
     rootSrc: https://xzgttest-1305134071.cos.ap-chengdu.myqcloud.com/
     location: /xizang
+sms:
+  enable: true
+  appId: 1400957506
+  secretid: AKIDCF5EF2c0DE1e5JK8r4EGJF4mNsMgp26x
+  secretkey: lLl184rUyFOOE0d5KNGC3kmfNsCWk4GU
+  sign: 畅云出行
 com:
   taxi591:
     bank:
diff --git a/ruoyi-admin/src/main/resources/application-test.yml b/ruoyi-admin/src/main/resources/application-test.yml
index 59dae4a..7e3b361 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: 120
+  expireTime: 1
 
 mybatis-plus:
   # 此处在多数据源中生效
@@ -199,7 +199,8 @@
     accessPath: /file/
     allowExt: .jpg|.png|.gif|.jpeg|.doc|.docx|.apk|.MP4|.mp4|.pdf|.PDF
   url:
-    prefix: http://localhost:${server.port}${server.servlet.context-path}
+#    prefix: http://localhost:${server.port}${server.servlet.context-path}
+    prefix: https://xzgt.test.591taxi.cn:${server.port}${server.servlet.context-path}
 wx:
   conf:
     appId: wxe91f1af7638aa5dd
diff --git a/ruoyi-admin/src/main/resources/application.yml b/ruoyi-admin/src/main/resources/application.yml
index dcc106d..e673e36 100644
--- a/ruoyi-admin/src/main/resources/application.yml
+++ b/ruoyi-admin/src/main/resources/application.yml
@@ -1,4 +1,4 @@
 # 项目相关配置
 spring:
   profiles:
-    active: test
+    active: prod
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 b275980..2ab98bb 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
@@ -1,6 +1,7 @@
 package com.ruoyi.web.controller.api;
 
 
+import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.ruoyi.common.basic.PageInfo;
 import com.ruoyi.common.constant.DictConstants;
@@ -10,6 +11,7 @@
 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;
 import com.ruoyi.system.dto.TInvoiceDTO;
 import com.ruoyi.system.model.*;
@@ -82,6 +84,18 @@
         return R.ok(billIds);
     }
 
+    @ApiOperation(value = "跳转批量缴费")
+    @PostMapping("/batchBill")
+    public R<String> batchBill(@RequestBody BatchBillDTO dto){
+        String userId = tokenService.getLoginUserApplet().getUserId();
+        List<String> billIds = dto.getBillIds();
+        Integer count = tBillService.batchBillCount(userId, billIds);
+        if(count>0){
+            return R.fail("请优先缴纳水电费");
+        }
+        return R.ok();
+    }
+
     @ApiOperation(value = "查看缴费账单详情")
     @GetMapping(value = "/getDetailById")
     public R<TBillVO> getDetailById(@RequestParam String id) {
diff --git a/ruoyi-applet/src/main/java/com/ruoyi/web/controller/api/TFaultRepairMessageController.java b/ruoyi-applet/src/main/java/com/ruoyi/web/controller/api/TFaultRepairMessageController.java
index e6cbbd3..d53226b 100644
--- a/ruoyi-applet/src/main/java/com/ruoyi/web/controller/api/TFaultRepairMessageController.java
+++ b/ruoyi-applet/src/main/java/com/ruoyi/web/controller/api/TFaultRepairMessageController.java
@@ -134,7 +134,7 @@
             for (SysUser sysUser : sysUsers) {
                 if (StringUtils.hasLength(sysUser.getPhonenumber())){
                     System.err.println("发送短信");
-                    smsUtil.sendSms(sysUser.getPhonenumber(),"2375194",new String[]{""});
+                    smsUtil.sendSms(sysUser.getPhonenumber(),"2375194",new String[]{});
                 }
             }
         }
diff --git a/ruoyi-applet/src/main/resources/application-prod.yml b/ruoyi-applet/src/main/resources/application-prod.yml
index a8e94fe..10c4c27 100644
--- a/ruoyi-applet/src/main/resources/application-prod.yml
+++ b/ruoyi-applet/src/main/resources/application-prod.yml
@@ -70,13 +70,20 @@
   # redis 配置
   redis:
     # 地址
+    #    host: 127.0.0.1
+    #    # 端口,默认为6379
+    #    port: 6379
+    #    # 数据库索引
+    #    database: 0
+    #    # 密码
+    #    password: 123456
     host: 127.0.0.1
     # 端口,默认为6379
-    port: 6379
+    port: 16379
     # 数据库索引
     database: 0
     # 密码
-    password: 123456
+    password: 8f5z9g52gx4bg
     # 连接超时时间
     timeout: 10s
     lettuce:
@@ -89,16 +96,16 @@
         max-active: 8
         # #连接池最大阻塞等待时间(使用负值表示没有限制)
         max-wait: -1ms
-# 数据源配置
+  # 数据源配置
   datasource:
     type: com.alibaba.druid.pool.DruidDataSource
     driverClassName: com.mysql.cj.jdbc.Driver
     druid:
       # 主库数据源
       master:
-        url: jdbc:mysql://127.0.0.1:10633/xizang?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=Asia/Shanghai
-        username: root
-        password: XiZang@2025!
+        url: jdbc:mysql://172.27.0.13:3306/xizang?autoReconnect=true&useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=Asia/Shanghai
+        username: xzgt
+        password: changyun!6f2gshj6h3j
       # 从库数据源
       slave:
         # 从数据源开关/默认关闭
@@ -149,7 +156,6 @@
         wall:
           config:
             multi-statement-allow: true
-
 # token配置
 token:
   # 令牌自定义标识
@@ -167,7 +173,7 @@
     db-config:
       logic-not-delete-value: 0
       logic-delete-value: 1
-  type-aliases-package: com.ruoyi.**.domain,com.ruoyi.**.vo
+  type-aliases-package: com.ruoyi.**.domain,com.ruoyi.**.vo,com.ruoyi.**.model
   # 指定Mapper文件位置
   mapper-locations: classpath*:mapper/**/*.xml
 
@@ -193,10 +199,12 @@
     qrLocation: /file/qrCode/
     accessPath: /file/
     allowExt: .jpg|.png|.gif|.jpeg|.doc|.docx|.apk|.MP4|.mp4|.pdf|.PDF
+  url:
+    prefix: https://xzgt.test.591taxi.cn:${server.port}${server.servlet.context-path}
 wx:
-  config:
-    appId: wxc3985a05da7d86dc
-    secret: 5cca42633c25439613b328c08ef20cc9
+  conf:
+    appId: wxe91f1af7638aa5dd
+    secretId: a787e1a462715604e0c9528b6d8960d1
 #OSS及短信配置
 code:
   config:
@@ -219,4 +227,4 @@
   appId: 1400957506
   secretid: AKIDCF5EF2c0DE1e5JK8r4EGJF4mNsMgp26x
   secretkey: lLl184rUyFOOE0d5KNGC3kmfNsCWk4GU
-  sign: 畅云出行
\ No newline at end of file
+  sign: 畅云出行
diff --git a/ruoyi-applet/src/main/resources/application-test.yml b/ruoyi-applet/src/main/resources/application-test.yml
index 3bfc62b..40d4e3f 100644
--- a/ruoyi-applet/src/main/resources/application-test.yml
+++ b/ruoyi-applet/src/main/resources/application-test.yml
@@ -199,6 +199,9 @@
     qrLocation: /file/qrCode/
     accessPath: /file/
     allowExt: .jpg|.png|.gif|.jpeg|.doc|.docx|.apk|.MP4|.mp4|.pdf|.PDF
+  url:
+#    prefix: http://localhost:${server.port}${server.servlet.context-path}
+    prefix: https://xzgt.test.591taxi.cn:${server.port}${server.servlet.context-path}
 wx:
   conf:
     appId: wxe91f1af7638aa5dd
diff --git a/ruoyi-applet/src/main/resources/application.yml b/ruoyi-applet/src/main/resources/application.yml
index dcc106d..e673e36 100644
--- a/ruoyi-applet/src/main/resources/application.yml
+++ b/ruoyi-applet/src/main/resources/application.yml
@@ -1,4 +1,4 @@
 # 项目相关配置
 spring:
   profiles:
-    active: test
+    active: prod
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 99d7bb9..a6e40ba 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
@@ -6,11 +6,20 @@
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
 
+import javax.activation.DataHandler;
+import javax.activation.FileDataSource;
+import java.net.URLEncoder;
+import javax.activation.URLDataSource;
 import javax.mail.*;
-import javax.mail.internet.InternetAddress;
-import javax.mail.internet.MimeMessage;
+import javax.mail.internet.*;
 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.util.concurrent.CompletableFuture;
 
 @Component
 @Slf4j
@@ -43,7 +52,8 @@
         // 访问SMTP服务时需要提供的密码(在控制台选择发信地址进行设置)
         props.put("mail.password", properties.getPassword());
         props.setProperty("mail.smtp.socketFactory.fallback", "false");
-        props.put("mail.smtp.ssl.enable", "false");
+        props.put("mail.smtp.ssl.enable", "true");
+        props.put("mail.smtp.ssl.protocols", "TLSv1.2");
         // 构建授权信息,用于进行SMTP进行身份验证
         Authenticator authenticator = new Authenticator() {
             @Override
@@ -94,17 +104,100 @@
             e.printStackTrace();
             log.error("发送邮件发生异常",e);
         }
-
     }
 
-    public static void main(String[] args) {
-        TencentMailUtil tencentMailUtil = new TencentMailUtil();
-        MailProperties properties = new MailProperties();
-        tencentMailUtil.properties = properties;
-        tencentMailUtil.send("214491528@qq.com","大学城揽院24栋");
-
+    public void sendInvoice(String emailAddress, List<Map<String, String>> list) {
+        // 异步发送邮件
+        CompletableFuture.runAsync(() -> {
+            try {
+                sendEmail(emailAddress, list);
+            } catch (ServiceException e) {
+                log.error("邮件发送失败", e);
+            }
+        });
     }
 
+    private void sendEmail(String emailAddress, List<Map<String, String>> list) throws ServiceException {
+        try {
+            // 创建邮件会话
+            Session mailSession = Session.getInstance(getMailProperties(), getAuthenticator());
+            // 创建邮件消息
+            MimeMessage message = new MimeMessage(mailSession);
+            // 设置发件人
+            InternetAddress from = new InternetAddress(properties.getUserAddr(), properties.getUserName());
+            message.setFrom(from);
+            // 设置收件人
+            InternetAddress to = new InternetAddress(emailAddress);
+            message.setRecipient(MimeMessage.RecipientType.TO, to);
+            // 设置邮件标题
+            message.setSubject("发票");
+            // 创建邮件内容
+            Multipart multipart = createMultipart(list);
+            // 设置邮件内容
+            message.setContent(multipart);
+            // 发送邮件
+            Transport.send(message);
+        } catch (MessagingException | UnsupportedEncodingException | MalformedURLException e) {
+            log.error("发送邮件发生异常", e);
+            throw new ServiceException("发送邮件失败, 请检查");
+        }
+    }
 
+    private Properties getMailProperties() {
+        Properties props = new Properties();
+        props.put("mail.smtp.auth", "true");
+        props.put("mail.smtp.host", properties.getSmtpHost());
+        props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
+        props.put("mail.smtp.socketFactory.port", properties.getSmtpPort());
+        props.put("mail.smtp.port", properties.getSmtpPort());
+        props.put("mail.user", properties.getUserAddr());
+        props.put("mail.password", properties.getPassword());
+        props.setProperty("mail.smtp.socketFactory.fallback", "false");
+        props.put("mail.smtp.ssl.enable", "true");
+        props.put("mail.smtp.ssl.protocols", "TLSv1.2");
+        return props;
+    }
 
+    private Authenticator getAuthenticator() {
+        return new Authenticator() {
+            @Override
+            protected PasswordAuthentication getPasswordAuthentication() {
+                String userName = properties.getUserAddr();
+                String password = properties.getPassword();
+                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 {
+   //     TencentMailUtil tencentMailUtil = new TencentMailUtil();
+   //     MailProperties properties = new MailProperties();
+   //     tencentMailUtil.properties = properties;
+   //     tencentMailUtil.send("645025773@qq.com","大学城揽院24栋");
+   // }
 }
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/dto/BatchBillDTO.java b/ruoyi-system/src/main/java/com/ruoyi/system/dto/BatchBillDTO.java
new file mode 100644
index 0000000..4910ba6
--- /dev/null
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/dto/BatchBillDTO.java
@@ -0,0 +1,18 @@
+package com.ruoyi.system.dto;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.List;
+
+@Data
+@ApiModel(value = "批量缴费校验")
+public class BatchBillDTO implements Serializable {
+
+    @ApiModelProperty(value = "账单id集合")
+    private List<String> billIds;
+
+
+}
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 8a78c2d..51a9e92 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
@@ -38,7 +38,11 @@
     @ApiModelProperty("支付凭证")
     private String voucher;
     @ApiModelProperty("银行流水ID")
-    @NotEmpty(message = "银行流水ID不能为空")
     private String flowId;
 
+    @ApiModelProperty("支付类型")
+    @NotEmpty(message = "支付类型不能为空")
+    private Integer payType;
+
+
 }
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 2ad934f..357d516 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
@@ -44,4 +44,6 @@
     BigDecimal statisticsPayed();
 
     BigDecimal statisticsOverdue();
+
+    Integer batchBillCount(@Param("userId")String userId, @Param("billIds")List<String> billIds);
 }
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 e5a60cd..1d66290 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
@@ -22,6 +22,11 @@
      */
     @ApiModelProperty("租户ID")
     private String userId;
+    /**
+     * 账单类型
+     */
+    @ApiModelProperty("账单类型 1=租金 2=押金 3=生活费用 4=房屋验收")
+    private Integer billType;
 
 
 
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 19b7f69..0015ee5 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
@@ -85,4 +85,6 @@
     Boolean cashPay(CachPayDto offlinePayDto);
 
     BillStatisticsDto statistics();
+
+    Integer batchBillCount(String userId, List<String> billIds);
 }
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 c637d9d..62a2e34 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
@@ -19,4 +19,5 @@
 public interface TInvoiceService extends IService<TInvoice> {
     PageInfo<TInvoice> pageList(TInvoiceQuery query);
     List<TInvoice> makeQuery(TInvoiceQuery query);
+    Boolean uploadVoucher(TInvoiceQuery query);
 }
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 6a0642b..96320ad 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
@@ -31,14 +31,8 @@
 import com.ruoyi.common.enums.SubmitStatusEnum;
 import com.ruoyi.common.exception.ServiceException;
 import com.ruoyi.system.mapper.TCheckAcceptRecordMapper;
-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.service.ISysRoleService;
-import com.ruoyi.system.service.TBillService;
-import com.ruoyi.system.service.TContractRentTypeService;
-import com.ruoyi.system.service.TContractService;
+import com.ruoyi.system.model.*;
+import com.ruoyi.system.service.*;
 import com.ruoyi.system.task.base.QuartzManager;
 import com.ruoyi.system.task.base.TimeJobType;
 import com.ruoyi.system.task.jobs.StateProcessJob;
@@ -84,6 +78,7 @@
     private final TContractRentTypeService contractRentTypeService;
     private final TBillService billService;
     private final TCheckAcceptRecordMapper checkAcceptRecordMapper;
+    private final THouseService houseService;
 
     public static void main(String[] args) {
 //        LocalDate localDate1 = LocalDate.now().withYear(2025).withMonth(4).withDayOfMonth(1);
@@ -268,404 +263,413 @@
         switch (categoryEnum) {
             case CATEGORY1: {
                 // 合同新增审批
-                int submitStatus = status == 0 ? 2 : (status == 1 ? 3 : 5);
+                int submitStatus = status == 0 ? 2 : (status == 1 ? 3 : 1);
                 contractService.updateContractAuditStatus(processParameter.getString("projectId"), submitStatus);
                 // TODO 发短信
                 break;
             }
             case CATEGORY2: {
                 // 合同签订审批
-                int submitStatus = status == 0 ? 3 : (status == 1 ? 4 : 5);
+                int submitStatus = status == 0 ? 3 : (status == 1 ? 4 : 1);
                 contractService.updateContractAuditStatus(processParameter.getString("projectId"), submitStatus);
                 TContract contract = contractService.getById(processParameter.getString("projectId"));
-                List<TContractRentType> contractRentTypes = contractRentTypeService.list();
-                TContractRentType tContractRentType = contractRentTypes.stream().filter(e -> e.getContractId().equals(contract.getId())).findFirst().orElse(null);
+                if(contract.getStatus().equals("4")){
 
-                // 生成第一笔账单
-                // 第一次应缴费日期
-                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");
+                    // 修改房屋状态
+                    THouse house = houseService.getById(contract.getHouseId());
+                    if(Objects.nonNull(house)){
+                        house.setLeaseStatus("2");
+                        houseService.updateById(house);
+                    }
+                    List<TContractRentType> contractRentTypes = contractRentTypeService.list();
+                    TContractRentType tContractRentType = contractRentTypes.stream().filter(e -> e.getContractId().equals(contract.getId())).findFirst().orElse(null);
 
-                rentBill.setBillType("1");
-                rentBill.setStartTime(contract.getStartPayTime());
-                if (rentBill.getStartTime().with(TemporalAdjusters.lastDayOfMonth()).isAfter(contract.getEndTime())) {
-                    if (rentBill.getStartTime().getDayOfMonth() != 1) {
+                    // 生成第一笔账单
+                    // 第一次应缴费日期
+                    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 (rentBill.getStartTime().with(TemporalAdjusters.lastDayOfMonth()).isAfter(contract.getEndTime())) {
+                        if (rentBill.getStartTime().getDayOfMonth() != 1) {
+                            rentBill.setEndTime(rentBill.getStartTime().with(TemporalAdjusters.lastDayOfMonth()));
+                        } else {
+                            rentBill.setEndTime(rentBill.getStartTime().plusMonths(contract.getPayType().equals("1") ? 1 : contract.getPayType().equals("2") ? 3 : 12).with(TemporalAdjusters.lastDayOfMonth()));
+                        }
+                    } else {
                         rentBill.setEndTime(rentBill.getStartTime().with(TemporalAdjusters.lastDayOfMonth()));
+                    }
+                    if (tContractRentType != null && rentBill.getEndTime().isAfter(tContractRentType.getChangeTime())) {
+                        long moneyDays = 0;
+                        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;
+                        }
+                        // 不需要涨租金的时间段
+                        long 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));
+                        rentBill.setPayableFeesMoney(contractRentTypeMoney.add(originalMoney));
+                        rentBill.setOutstandingMoney(rentBill.getPayableFeesMoney());
                     } else {
-                        rentBill.setEndTime(rentBill.getStartTime().plusMonths(contract.getPayType().equals("1") ? 1 : contract.getPayType().equals("2") ? 3 : 12).with(TemporalAdjusters.lastDayOfMonth()));
+                        // 不走递增递减
+                        long allDays = ChronoUnit.DAYS.between(contract.getStartPayTime(), rentBill.getEndTime())+1;
+                        int dayOfMonth = rentBill.getStartTime().getDayOfMonth();
+                        if (dayOfMonth == 1) {
+                            rentBill.setPayableFeesMoney(contract.getMonthRent().multiply(new BigDecimal(contract.getPayType().equals("1") ? 1 : contract.getPayType().equals("2") ? 3 : 12)));
+                        } else {
+                            rentBill.setPayableFeesMoney(contract.getMonthRent().divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(allDays)));
+                        }
+                        rentBill.setOutstandingMoney(rentBill.getPayableFeesMoney());
                     }
-                } else {
-                    rentBill.setEndTime(rentBill.getStartTime().with(TemporalAdjusters.lastDayOfMonth()));
-                }
-                if (tContractRentType != null && rentBill.getEndTime().isAfter(tContractRentType.getChangeTime())) {
-                    long moneyDays = 0;
-                    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;
-                    }
-                    // 不需要涨租金的时间段
-                    long 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));
-                    rentBill.setPayableFeesMoney(contractRentTypeMoney.add(originalMoney));
-                    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().multiply(new BigDecimal(contract.getPayType().equals("1") ? 1 : contract.getPayType().equals("2") ? 3 : 12)));
-                    } 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());
+                    // 押金账单
+                    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.setPayFeesStatus("1");
 
 
-                depositBill.setBillType("2");
-                contractService.updateById(contract);
-                billService.save(rentBill);
-                billService.save(depositBill);
-                // 生成后续账单
-                try {
-                    TBill beforeBill = billService.lambdaQuery().eq(TBill::getContractId, contract.getId()).eq(TBill::getBillType, 1).orderByDesc(TBill::getStartTime)
-                            .last("limit 1").one();
-                    if (!beforeBill.getEndTime().toLocalDate().equals(contract.getEndTime().toLocalDate())) {
-                        while (beforeBill.getEndTime().plusMonths(contract.getPayType().equals("1") ? 1 : contract.getPayType().equals("2") ? 3 : 12).isBefore(contract.getEndTime())) {
-                            System.err.println("生成后续账单");
-                            TBill tBill = new TBill();
-                            tBill.setContractId(contract.getId());
-                            tBill.setStartTime(beforeBill.getEndTime().plusDays(1));
-                            tBill.setEndTime(beforeBill.getEndTime().plusMonths(contract.getPayType().equals("1") ? 1 : contract.getPayType().equals("2") ? 3 : 12).with(TemporalAdjusters.lastDayOfMonth()));
-                            tBill.setContractNumber(contract.getContractNumber());
-                            if (beforeBill.getEndTime().plusMonths(contract.getPayType().equals("1") ? 1 : contract.getPayType().equals("2") ? 3 : 12).getDayOfMonth() <= 15) {
-                                tBill.setPayableFeesTime(contract.getEndTime().toLocalDate());
-                            } else {
-                                tBill.setPayableFeesTime((contract.getPayType().equals("1") ?
-                                        beforeBill.getEndTime().plusMonths(1).withDayOfMonth(15).toLocalDate() : contract.getPayType().equals("2") ?
-                                        beforeBill.getEndTime().plusMonths(3).withDayOfMonth(15).toLocalDate() : beforeBill.getEndTime().withDayOfMonth(15).plusMonths(12).toLocalDate()));
-                            }
-                            tBill.setContractId(contract.getId());
-                            if (contract.getIsIncreasing()) {
-                                System.err.println("执行递增递减");
-                                if (tContractRentType != null) {
-                                    // 如果变过 并且时间在递增递减时间段内
-                                    if (contract.getChangeTime() != null) {
-                                        // 下次递增递减时间
-                                        LocalDateTime changeTime = contract.getChangeTime().plusYears(tContractRentType.getCycleTime());
-                                        // 之前已经涨、跌过租金了 需要判断周期是否还需要再涨、跌
-                                        if (changeTime.isBefore(tBill.getEndTime()) && changeTime.isAfter(tBill.getStartTime())) {
-                                            contract.setChangeTime(changeTime);
-                                            // 租金递增递减的时长 天
-                                            long moneyDays = Math.abs(ChronoUnit.DAYS.between(tContractRentType.getChangeTime(), tBill.getEndTime()))+1;
-                                            // 递增递减的租金
-                                            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;
-                                            }
-                                            // 不需要涨租金的时间段
-                                            long originalDays = ChronoUnit.DAYS.between(tBill.getStartTime(), tContractRentType.getChangeTime());
-                                            if (originalDays > 0) {
-                                                originalMoney = originalMoney.add(contract.getChangeRent().divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN))
-                                                        .multiply(new BigDecimal(originalDays));
-                                            }
-                                            tBill.setPayableFeesMoney(contractRentTypeMoney.add(originalMoney));
-                                            tBill.setOutstandingMoney(tBill.getPayableFeesMoney());
-                                            contractService.updateById(contract);
-                                        } else {
-                                            // 不涨租金 用上次的
-                                            tBill.setPayableFeesMoney(contract.getChangeRent().multiply(new BigDecimal(contract.getPayType().equals("1")?1:contract.getPayType().equals("2")?3:12)));
-                                            tBill.setOutstandingMoney(tBill.getPayableFeesMoney());
-                                        }
-                                    }else{
-                                        if (tContractRentType.getChangeTime().isBefore(tBill.getEndTime()) && tContractRentType.getChangeTime().isAfter(tBill.getStartTime())) {
-                                            System.err.println("首次递增递减");
-                                            contract.setChangeTime(tContractRentType.getChangeTime());
-                                            // 租金递增递减的时长 天
-                                            long moneyDays = Math.abs(ChronoUnit.DAYS.between(tContractRentType.getChangeTime(), tBill.getEndTime()))+1;
-                                            // 递增递减的租金
-                                            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;
-                                            }
-                                            // 不需要涨租金的时间段
-                                            long originalDays = ChronoUnit.DAYS.between(tBill.getStartTime(), tContractRentType.getChangeTime());
-                                            System.err.println("不需要长租金时长"+originalDays);
-                                            if (originalDays > 0) {
-                                                originalMoney = originalMoney.add(contract.getMonthRent().divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN))
-                                                        .multiply(new BigDecimal(originalDays));
-                                            }
-                                            tBill.setPayableFeesMoney(contractRentTypeMoney.add(originalMoney));
-                                            tBill.setOutstandingMoney(tBill.getPayableFeesMoney());
-                                            contractService.updateById(contract);
-                                        }else{
-                                            tBill.setPayableFeesMoney(contract.getChangeRent().multiply(new BigDecimal(contract.getPayType().equals("1") ? 1 : contract.getPayType().equals("2") ? 3 : 12)));
-                                            tBill.setOutstandingMoney(tBill.getPayableFeesMoney());
-                                        }
-                                    }
+                    depositBill.setBillType("2");
+                    contractService.updateById(contract);
+                    billService.save(rentBill);
+                    billService.save(depositBill);
+                    // 生成后续账单
+                    try {
+                        TBill beforeBill = billService.lambdaQuery().eq(TBill::getContractId, contract.getId()).eq(TBill::getBillType, 1).orderByDesc(TBill::getStartTime)
+                                .last("limit 1").one();
+                        if (!beforeBill.getEndTime().toLocalDate().equals(contract.getEndTime().toLocalDate())) {
+                            while (beforeBill.getEndTime().plusMonths(contract.getPayType().equals("1") ? 1 : contract.getPayType().equals("2") ? 3 : 12).isBefore(contract.getEndTime())) {
+                                System.err.println("生成后续账单");
+                                TBill tBill = new TBill();
+                                tBill.setContractId(contract.getId());
+                                tBill.setStartTime(beforeBill.getEndTime().plusDays(1));
+                                tBill.setEndTime(beforeBill.getEndTime().plusMonths(contract.getPayType().equals("1") ? 1 : contract.getPayType().equals("2") ? 3 : 12).with(TemporalAdjusters.lastDayOfMonth()));
+                                tBill.setContractNumber(contract.getContractNumber());
+                                if (beforeBill.getEndTime().plusMonths(contract.getPayType().equals("1") ? 1 : contract.getPayType().equals("2") ? 3 : 12).getDayOfMonth() <= 15) {
+                                    tBill.setPayableFeesTime(contract.getEndTime().toLocalDate());
                                 } else {
+                                    tBill.setPayableFeesTime(beforeBill.getEndTime().plusMonths(1).withDayOfMonth(15).toLocalDate());
+                                }
+                                tBill.setContractId(contract.getId());
+                                if (contract.getIsIncreasing()) {
+                                    System.err.println("执行递增递减");
+                                    if (tContractRentType != null) {
+                                        // 如果变过 并且时间在递增递减时间段内
+                                        if (contract.getChangeTime() != null) {
+                                            // 下次递增递减时间
+                                            LocalDateTime changeTime = contract.getChangeTime().plusYears(tContractRentType.getCycleTime());
+                                            // 之前已经涨、跌过租金了 需要判断周期是否还需要再涨、跌
+                                            if (changeTime.isBefore(tBill.getEndTime()) && changeTime.isAfter(tBill.getStartTime())) {
+                                                contract.setChangeTime(changeTime);
+                                                // 租金递增递减的时长 天
+                                                long moneyDays = Math.abs(ChronoUnit.DAYS.between(tContractRentType.getChangeTime(), tBill.getEndTime()))+1;
+                                                // 递增递减的租金
+                                                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;
+                                                }
+                                                // 不需要涨租金的时间段
+                                                long originalDays = ChronoUnit.DAYS.between(tBill.getStartTime(), tContractRentType.getChangeTime());
+                                                if (originalDays > 0) {
+                                                    originalMoney = originalMoney.add(contract.getChangeRent().divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN))
+                                                            .multiply(new BigDecimal(originalDays));
+                                                }
+                                                tBill.setPayableFeesMoney(contractRentTypeMoney.add(originalMoney));
+                                                tBill.setOutstandingMoney(tBill.getPayableFeesMoney());
+                                                contractService.updateById(contract);
+                                            } else {
+                                                // 不涨租金 用上次的
+                                                tBill.setPayableFeesMoney(contract.getChangeRent().multiply(new BigDecimal(contract.getPayType().equals("1")?1:contract.getPayType().equals("2")?3:12)));
+                                                tBill.setOutstandingMoney(tBill.getPayableFeesMoney());
+                                            }
+                                        }else{
+                                            if (tContractRentType.getChangeTime().isBefore(tBill.getEndTime()) && tContractRentType.getChangeTime().isAfter(tBill.getStartTime())) {
+                                                System.err.println("首次递增递减");
+                                                contract.setChangeTime(tContractRentType.getChangeTime());
+                                                // 租金递增递减的时长 天
+                                                long moneyDays = Math.abs(ChronoUnit.DAYS.between(tContractRentType.getChangeTime(), tBill.getEndTime()))+1;
+                                                // 递增递减的租金
+
+                                                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;
+                                                }
+                                                // 不需要涨租金的时间段
+                                                long originalDays = ChronoUnit.DAYS.between(tBill.getStartTime(), tContractRentType.getChangeTime());
+                                                System.err.println("不需要长租金时长"+originalDays);
+                                                if (originalDays > 0) {
+                                                    originalMoney = originalMoney.add(contract.getMonthRent().divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN))
+                                                            .multiply(new BigDecimal(originalDays));
+                                                }
+                                                tBill.setPayableFeesMoney(contractRentTypeMoney.add(originalMoney));
+                                                tBill.setOutstandingMoney(tBill.getPayableFeesMoney());
+                                                contractService.updateById(contract);
+                                            }else{
+                                                tBill.setPayableFeesMoney(contract.getChangeRent().multiply(new BigDecimal(contract.getPayType().equals("1") ? 1 : contract.getPayType().equals("2") ? 3 : 12)));
+                                                tBill.setOutstandingMoney(tBill.getPayableFeesMoney());
+                                            }
+                                        }
+                                    } else {
+                                        tBill.setPayableFeesMoney(contract.getChangeRent().multiply(new BigDecimal(contract.getPayType().equals("1") ? 1 : contract.getPayType().equals("2") ? 3 : 12)));
+                                        tBill.setOutstandingMoney(tBill.getPayableFeesMoney());
+                                    }
+                                }else {
+                                    System.err.println("不执行递增递减");
                                     tBill.setPayableFeesMoney(contract.getChangeRent().multiply(new BigDecimal(contract.getPayType().equals("1") ? 1 : contract.getPayType().equals("2") ? 3 : 12)));
                                     tBill.setOutstandingMoney(tBill.getPayableFeesMoney());
                                 }
-                            }else {
-                                System.err.println("不执行递增递减");
-                                tBill.setPayableFeesMoney(contract.getChangeRent().multiply(new BigDecimal(contract.getPayType().equals("1") ? 1 : contract.getPayType().equals("2") ? 3 : 12)));
-                                tBill.setOutstandingMoney(tBill.getPayableFeesMoney());
-                            }
-                            tBill.setContractNumber(contract.getContractNumber());
-                            tBill.setPayFeesStatus("1");
-                            tBill.setBillType("1");
+                                tBill.setContractNumber(contract.getContractNumber());
+                                tBill.setPayFeesStatus("1");
+                                tBill.setBillType("1");
 
-                            billService.save(tBill);
-                            beforeBill.setEndTime(beforeBill.getEndTime().plusMonths(contract.getPayType().equals("1") ? 1 : contract.getPayType().equals("2") ? 3 : 12).with(TemporalAdjusters.lastDayOfMonth()));
+                                billService.save(tBill);
+                                beforeBill.setEndTime(beforeBill.getEndTime().plusMonths(contract.getPayType().equals("1") ? 1 : contract.getPayType().equals("2") ? 3 : 12).with(TemporalAdjusters.lastDayOfMonth()));
+                            }
                         }
+                    } catch (Exception e) {
+                        e.printStackTrace();
                     }
-                } catch (Exception e) {
-                    e.printStackTrace();
-                }
-                TBill beforeBill = billService.lambdaQuery().eq(TBill::getContractId, contract.getId()).eq(TBill::getBillType, 1).orderByDesc(TBill::getStartTime)
-                        .last("limit 1").one();
-                // 生成最后一笔账单
-                if (!(beforeBill.getEndTime().toLocalDate().equals(contract.getEndTime().toLocalDate()))
-                        && beforeBill.getEndTime().isBefore(contract.getEndTime())
-                ) {
-                    TBill tBill = new TBill();
-                    tBill.setContractId(contract.getId());
-                    tBill.setPayFeesStatus("1");
-                    tBill.setBillType("1");
-                    tBill.setStartTime(beforeBill.getEndTime().plusDays(1));
-                    tBill.setEndTime(contract.getEndTime());
-                    tBill.setContractNumber(contract.getContractNumber());
-                    if (contract.getIsIncreasing()) {
-                        if (tContractRentType != null) {
-                            // 如果变过 并且时间在递增递减时间段内
-                            if (contract.getChangeTime() != null) {
-                                // 下次递增递减时间
-                                LocalDateTime changeTime = contract.getChangeTime().plusYears(tContractRentType.getCycleTime());
-                                // 之前已经涨、跌过租金了 需要判断周期是否还需要再涨、跌
-                                if (changeTime.isBefore(tBill.getEndTime()) && changeTime.isAfter(tBill.getStartTime())) {
-                                    contract.setChangeTime(changeTime);
-                                    // 租金递增递减的时长 天
-                                    long moneyDays = Math.abs(ChronoUnit.DAYS.between(changeTime, tBill.getEndTime()))+1;
-                                    // 递增递减的租金
-                                    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;
+                    TBill beforeBill = billService.lambdaQuery().eq(TBill::getContractId, contract.getId()).eq(TBill::getBillType, 1).orderByDesc(TBill::getStartTime)
+                            .last("limit 1").one();
+                    // 生成最后一笔账单
+                    if (!(beforeBill.getEndTime().toLocalDate().equals(contract.getEndTime().toLocalDate()))
+                            && beforeBill.getEndTime().isBefore(contract.getEndTime())
+                    ) {
+                        TBill tBill = new TBill();
+                        tBill.setContractId(contract.getId());
+                        tBill.setPayFeesStatus("1");
+                        tBill.setBillType("1");
+                        tBill.setStartTime(beforeBill.getEndTime().plusDays(1));
+                        tBill.setEndTime(contract.getEndTime());
+                        tBill.setContractNumber(contract.getContractNumber());
+                        if (contract.getIsIncreasing()) {
+                            if (tContractRentType != null) {
+                                // 如果变过 并且时间在递增递减时间段内
+                                if (contract.getChangeTime() != null) {
+                                    // 下次递增递减时间
+                                    LocalDateTime changeTime = contract.getChangeTime().plusYears(tContractRentType.getCycleTime());
+                                    // 之前已经涨、跌过租金了 需要判断周期是否还需要再涨、跌
+                                    if (changeTime.isBefore(tBill.getEndTime()) && changeTime.isAfter(tBill.getStartTime())) {
+                                        contract.setChangeTime(changeTime);
+                                        // 租金递增递减的时长 天
+                                        long moneyDays = Math.abs(ChronoUnit.DAYS.between(changeTime, tBill.getEndTime()))+1;
+                                        // 递增递减的租金
+                                        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;
+                                        }
+                                        // 不需要涨租金的时间段
+                                        long originalDays = ChronoUnit.DAYS.between(tBill.getStartTime(), changeTime);
+                                        if (originalDays > 0) {
+                                            originalMoney = originalMoney.add(contract.getMonthRent().divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN))
+                                                    .multiply(new BigDecimal(originalDays));
+                                        }
+                                        tBill.setPayableFeesMoney(contractRentTypeMoney.add(originalMoney));
+                                        tBill.setOutstandingMoney(tBill.getPayableFeesMoney());
+                                        contractService.updateById(contract);
+                                    } else {
+                                        long finalDays = ChronoUnit.DAYS.between(beforeBill.getEndTime(), contract.getEndTime());
+                                        tBill.setPayableFeesMoney(contract.getChangeRent().divide(new BigDecimal("30"),2,BigDecimal.ROUND_DOWN).multiply(new BigDecimal(finalDays)));
+                                        tBill.setOutstandingMoney(tBill.getPayableFeesMoney());
                                     }
-                                    // 不需要涨租金的时间段
-                                    long originalDays = ChronoUnit.DAYS.between(tBill.getStartTime(), changeTime);
-                                    if (originalDays > 0) {
-                                        originalMoney = originalMoney.add(contract.getMonthRent().divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN))
-                                                .multiply(new BigDecimal(originalDays));
+                                }else{
+                                    if (tContractRentType.getChangeTime().isBefore(tBill.getEndTime()) && tContractRentType.getChangeTime().isAfter(tBill.getStartTime())) {
+                                        contract.setChangeTime(tContractRentType.getChangeTime());
+                                        // 租金递增递减的时长 天
+                                        long moneyDays = Math.abs(ChronoUnit.DAYS.between(tContractRentType.getChangeTime(), tBill.getEndTime()))+1;
+                                        // 递增递减的租金
+                                        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;
+                                        }
+                                        // 不需要涨租金的时间段
+                                        long originalDays = ChronoUnit.DAYS.between(tBill.getStartTime(), tContractRentType.getChangeTime());
+                                        if (originalDays > 0) {
+                                            originalMoney = originalMoney.add(contract.getMonthRent().divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN))
+                                                    .multiply(new BigDecimal(originalDays)).setScale(2,BigDecimal.ROUND_DOWN);
+                                        }
+                                        tBill.setPayableFeesMoney(contractRentTypeMoney.add(originalMoney));
+                                        tBill.setOutstandingMoney(tBill.getPayableFeesMoney());
+                                        contractService.updateById(contract);
+
                                     }
-                                    tBill.setPayableFeesMoney(contractRentTypeMoney.add(originalMoney));
+                                }
+                            } else {
+                                if (tBill.getStartTime().getDayOfMonth()==1 && tBill.getEndTime().toLocalDate().equals(tBill.getEndTime().with(TemporalAdjusters.lastDayOfMonth()).toLocalDate())){
+                                    tBill.setPayableFeesMoney(contract.getChangeRent().multiply(new BigDecimal(contract.getPayType().equals("1") ? 1 : contract.getPayType().equals("2") ? 3 : 12)));
                                     tBill.setOutstandingMoney(tBill.getPayableFeesMoney());
-                                    contractService.updateById(contract);
-                                } else {
+                                }else{
+                                    // 最后一笔账单时间
                                     long finalDays = ChronoUnit.DAYS.between(beforeBill.getEndTime(), contract.getEndTime());
                                     tBill.setPayableFeesMoney(contract.getChangeRent().divide(new BigDecimal("30"),2,BigDecimal.ROUND_DOWN).multiply(new BigDecimal(finalDays)));
                                     tBill.setOutstandingMoney(tBill.getPayableFeesMoney());
                                 }
-                            }else{
-                                if (tContractRentType.getChangeTime().isBefore(tBill.getEndTime()) && tContractRentType.getChangeTime().isAfter(tBill.getStartTime())) {
-                                    contract.setChangeTime(tContractRentType.getChangeTime());
-                                    // 租金递增递减的时长 天
-                                    long moneyDays = Math.abs(ChronoUnit.DAYS.between(tContractRentType.getChangeTime(), tBill.getEndTime()))+1;
-                                    // 递增递减的租金
-                                    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;
-                                    }
-                                    // 不需要涨租金的时间段
-                                    long originalDays = ChronoUnit.DAYS.between(tBill.getStartTime(), tContractRentType.getChangeTime());
-                                    if (originalDays > 0) {
-                                        originalMoney = originalMoney.add(contract.getMonthRent().divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN))
-                                                .multiply(new BigDecimal(originalDays)).setScale(2,BigDecimal.ROUND_DOWN);
-                                    }
-                                    tBill.setPayableFeesMoney(contractRentTypeMoney.add(originalMoney));
-                                    tBill.setOutstandingMoney(tBill.getPayableFeesMoney());
-                                    contractService.updateById(contract);
-                                }
                             }
-                        } else {
-                            if (tBill.getStartTime().getDayOfMonth()==1 && tBill.getEndTime().toLocalDate().equals(tBill.getEndTime().with(TemporalAdjusters.lastDayOfMonth()).toLocalDate())){
-                                tBill.setPayableFeesMoney(contract.getChangeRent().multiply(new BigDecimal(contract.getPayType().equals("1") ? 1 : contract.getPayType().equals("2") ? 3 : 12)));
-                                tBill.setOutstandingMoney(tBill.getPayableFeesMoney());
-                            }else{
-                                // 最后一笔账单时间
-                                long finalDays = ChronoUnit.DAYS.between(beforeBill.getEndTime(), contract.getEndTime());
-                                tBill.setPayableFeesMoney(contract.getChangeRent().divide(new BigDecimal("30"),2,BigDecimal.ROUND_DOWN).multiply(new BigDecimal(finalDays)));
-                                tBill.setOutstandingMoney(tBill.getPayableFeesMoney());
-                            }
+                        }else{
+                            long finalDays = ChronoUnit.DAYS.between(beforeBill.getEndTime(), contract.getEndTime());
+                            tBill.setPayableFeesMoney(contract.getChangeRent().divide(new BigDecimal("30"),2,BigDecimal.ROUND_DOWN).multiply(new BigDecimal(finalDays)));
+                            tBill.setOutstandingMoney(tBill.getPayableFeesMoney());
                         }
-                    }else{
-                        long finalDays = ChronoUnit.DAYS.between(beforeBill.getEndTime(), contract.getEndTime());
-                        tBill.setPayableFeesMoney(contract.getChangeRent().divide(new BigDecimal("30"),2,BigDecimal.ROUND_DOWN).multiply(new BigDecimal(finalDays)));
-                        tBill.setOutstandingMoney(tBill.getPayableFeesMoney());
+                        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());
+                        }
+                        billService.save(tBill);
                     }
-                    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());
-                    }
-                    billService.save(tBill);
                 }
                 break;
             }
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 1dd6cad..0376220 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
@@ -241,42 +241,72 @@
     @Override
     @Transactional(rollbackFor = Exception.class)
     public boolean checkOfflinePay(OfflinePayCheckDto dto) {
-        TBankFlow bankflow = tBankFlowService.getById(dto.getFlowId());
         TBillDto bill = getDetailByBillId(dto.getBillId());
-        if (bankflow.getRemainingMoney().compareTo(BigDecimal.ZERO)<=0){
-            throw new ServiceException("该流水已无可抵扣剩余金额");
-        }
-        if (bankflow.getRemainingMoney().compareTo(dto.getAmount())<0){
-            throw new ServiceException("实付金额不能高于于流水可抵扣剩余金额");
-        }
-        //如果实付金额大于欠费金额
-        if (dto.getAmount().compareTo(bill.getOutstandingMoney())>0){
-            throw new ServiceException("实付金额不能高于该账单欠费金额");
-        }
+        if (dto.getPayType()==1){ //银行
+            if (StringUtils.isEmpty(dto.getFlowId())){
+                throw new ServiceException("银行流水ID不能为空");
+            }
+            TBankFlow bankflow = tBankFlowService.getById(dto.getFlowId());
+            if (bankflow.getRemainingMoney().compareTo(BigDecimal.ZERO)<=0){
+                throw new ServiceException("该流水已无可抵扣剩余金额");
+            }
+            if (bankflow.getRemainingMoney().compareTo(dto.getAmount())<0){
+                throw new ServiceException("实付金额不能高于于流水可抵扣剩余金额");
+            }
+            //如果实付金额大于欠费金额
+            if (dto.getAmount().compareTo(bill.getOutstandingMoney())>0){
+                throw new ServiceException("实付金额不能高于该账单欠费金额");
+            }
+            TBill billSave = new TBill();
+            billSave.setId(bill.getId());
+            billSave.setPayFeesMoney(dto.getAmount());
+            billSave.setBankSerialNumber(bankflow.getBankSerialNumber());
+            billSave.setPayFeesTime(bankflow.getPayTime());
+            billSave.setVoucher(dto.getVoucher());
+            billSave.setPayFeesType(2);
+            TBill back = lockAndUpdateInfo(billSave, 2);
+            TBankFlow saveBankFlow = new TBankFlow();
+            saveBankFlow.setId(bankflow.getId());
+            saveBankFlow.setDeductionMoney(bankflow.getDeductionMoney().add(dto.getAmount()));
+            BigDecimal subtract = bankflow.getRemainingMoney().subtract(dto.getAmount());
+            saveBankFlow.setRemainingMoney(subtract);
+            if (BigDecimal.ZERO.compareTo(subtract) == 0){
+                saveBankFlow.setFlowStatus(1);
+            }
+            tBankFlowService.updateById(saveBankFlow);
+            //更新银行流水的已抵扣金额和剩余可抵扣金额
 
+            //存流水
+            TFlowManagement save = new TFlowManagement();
+            save.setPayType(3);
+            save.setPayer(dto.getPayer());
+            save.setPayTime(bankflow.getPayTime());
+            save.setSysSerialNumber(OrderNos.getDid(30));
+            save.setBankSerialNumber(bankflow.getBankSerialNumber());
+            save.setFlowType(2);
+            save.setPaymentBillId(back.getId());
+            save.setDeductionMoney(back.getDeductionMoney());
+            save.setFlowMoney(dto.getAmount());
+            save.setRemainingMoney(back.getOutstandingMoney());
+            save.setPreOutstand(back.getPreOutstand());
+            tFlowManagementService.save(save);
+            return true;
+        }
+        //现金支付
         TBill billSave = new TBill();
         billSave.setId(bill.getId());
         billSave.setPayFeesMoney(dto.getAmount());
-        billSave.setBankSerialNumber(bankflow.getBankSerialNumber());
-        billSave.setPayFeesTime(bankflow.getPayTime());
+        billSave.setPayFeesTime(dto.getPayTime()!=null?dto.getPayTime():DateUtils.dateToLocalDateTime(new Date()));
         billSave.setVoucher(dto.getVoucher());
         billSave.setPayFeesType(2);
         TBill back = lockAndUpdateInfo(billSave, 2);
 
-        //更新银行流水的已抵扣金额和剩余可抵扣金额
-        TBankFlow saveBankFlow = new TBankFlow();
-        saveBankFlow.setId(bankflow.getId());
-        saveBankFlow.setDeductionMoney(bankflow.getDeductionMoney().add(dto.getAmount()));
-        saveBankFlow.setRemainingMoney(bankflow.getRemainingMoney().subtract(dto.getAmount()));
-        tBankFlowService.updateById(saveBankFlow);
-        //存流水
         TFlowManagement save = new TFlowManagement();
         save.setPayType(3);
         save.setPayer(dto.getPayer());
-        save.setPayTime(bankflow.getPayTime());
+        save.setPayTime(billSave.getPayFeesTime());
         save.setSysSerialNumber(OrderNos.getDid(30));
-        save.setBankSerialNumber(bankflow.getBankSerialNumber());
-        save.setFlowType(2);
+        save.setFlowType(1);
         save.setPaymentBillId(back.getId());
         save.setDeductionMoney(back.getDeductionMoney());
         save.setFlowMoney(dto.getAmount());
@@ -483,7 +513,11 @@
             TBankFlow saveBankFlow = new TBankFlow();
             saveBankFlow.setId(bankflow.getId());
             saveBankFlow.setDeductionMoney(bankflow.getDeductionMoney().add(dto.getAmount()));
-            saveBankFlow.setRemainingMoney(bankflow.getRemainingMoney().subtract(dto.getAmount()));
+            BigDecimal subtract = bankflow.getRemainingMoney().subtract(dto.getAmount());
+            saveBankFlow.setRemainingMoney(subtract);
+            if (BigDecimal.ZERO.compareTo(subtract) == 0){
+                saveBankFlow.setFlowStatus(1);
+            }
             tBankFlowService.updateById(saveBankFlow);
         }
         //存流水
@@ -513,5 +547,10 @@
         return dto;
     }
 
+    @Override
+    public Integer batchBillCount(String userId, List<String> billIds) {
+        return this.baseMapper.batchBillCount(userId,billIds);
+    }
+
 
 }
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 36dbad6..c0be87b 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
@@ -3,7 +3,9 @@
 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.core.exception.ServiceException;
 import com.ruoyi.common.utils.StringUtils;
+import com.ruoyi.common.utils.TencentMailUtil;
 import com.ruoyi.system.mapper.TInvoiceMapper;
 import com.ruoyi.system.model.TInvoice;
 import com.ruoyi.system.query.TInvoiceQuery;
@@ -12,7 +14,10 @@
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
-import java.util.List;
+import javax.annotation.Resource;
+import java.util.*;
+import java.util.concurrent.CompletableFuture;
+import java.util.stream.Collectors;
 
 /**
  * <p>
@@ -28,6 +33,8 @@
     TInvoiceToBillServiceImpl tInvoiceToBillService;
     @Autowired
     TBillService tBillService;
+    @Resource
+    TencentMailUtil mailUtil;
 
     @Override
     public PageInfo<TInvoice> pageList(TInvoiceQuery query) {
@@ -49,4 +56,94 @@
                 .orderByDesc(TInvoice::getCreateTime);
         return this.baseMapper.selectList(queryWrapper);
     }
+
+    @Override
+    public Boolean uploadVoucher(TInvoiceQuery query) {
+        // 检查是否存在对应的发票记录
+        TInvoice preexist = getById(query.getId());
+        if (preexist == null) {
+            log.error("未找到对应的发票记录,ID: {}"+query.getId());
+            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>> attachments = buildAttachments(query.getInvoiceVoucher(), query.getInvoiceVoucherName());
+        if (attachments.isEmpty()) {
+            log.warn("未找到有效的附件信息");
+            return updateById(tInvoice);
+        }
+
+        // 异步发送邮件
+        CompletableFuture.runAsync(() -> {
+            try {
+                mailUtil.sendInvoice(preexist.getEmail(), attachments);
+            } 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/resources/mapper/system/TBillMapper.xml b/ruoyi-system/src/main/resources/mapper/system/TBillMapper.xml
index 5415d26..81d281c 100644
--- a/ruoyi-system/src/main/resources/mapper/system/TBillMapper.xml
+++ b/ruoyi-system/src/main/resources/mapper/system/TBillMapper.xml
@@ -93,6 +93,9 @@
             <if test="query.userId != null and query.userId !=''">
                 and t.id = #{query.userId}
             </if>
+            <if test="query.billType != null">
+                and b.bill_type = #{query.billType}
+            </if>
             and b.disabled = ${@com.ruoyi.common.enums.DisabledEnum@NO.getCode()}
         </where>
         order by b.bill_type,b.payable_fees_time
@@ -162,4 +165,25 @@
     <select id="statisticsOverdue" resultType="java.math.BigDecimal">
         SELECT ifnull(sum(outstanding_money),0) as amount FROM t_bill where pay_fees_status=4
     </select>
+    <select id="batchBillCount" resultType="java.lang.Integer">
+        SELECT
+            count(b.id)
+        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>
+            <if test="userId != null and userId !=''">
+                AND t.id = #{userId}
+            </if>
+            <if test="billIds != null and billIds.size() > 0">
+                AND b.id NOT IN
+                <foreach collection="billIds" item="item" index="index" open="(" separator="," close=")">
+                    #{item}
+                </foreach>
+            </if>
+            AND b.bill_type = 3
+        </where>
+    </select>
 </mapper>
diff --git a/ruoyi-system/src/main/resources/mapper/system/THouseMapper.xml b/ruoyi-system/src/main/resources/mapper/system/THouseMapper.xml
index 47b75b6..d5450f9 100644
--- a/ruoyi-system/src/main/resources/mapper/system/THouseMapper.xml
+++ b/ruoyi-system/src/main/resources/mapper/system/THouseMapper.xml
@@ -53,7 +53,7 @@
                 and (t2.start_time is not null)
             </if>
             <if test="req.leaseStatus == 1">
-                and (t2.start_time is null)
+                and (t2.start_time is null) and t1.lease_status = 1
             </if>
             AND t1.disabled = ${@com.ruoyi.common.enums.DisabledEnum@NO.getCode()}
         </where>

--
Gitblit v1.7.1