From fb2f11d7d502ceacbe7fbed176bea4ab0f152f69 Mon Sep 17 00:00:00 2001
From: liulin <lin.liu@88.com>
Date: 星期四, 03 七月 2025 18:17:59 +0800
Subject: [PATCH] 添加mqtt

---
 src/main/java/com/lunhan/water/entity/search/SearchThirdNotify.java                                 |   14 
 src/main/java/com/lunhan/water/host/controller/ThirdNotifyController.java                           |  113 +
 src/main/java/com/lunhan/water/service/HeartbeatDataService.java                                    |  244 ++
 src/main/java/com/lunhan/water/entity/enums/EBillPayStatus.java                                     |   68 
 src/main/java/com/lunhan/water/entity/enums/EPayNotifyState.java                                    |   64 
 src/main/java/com/lunhan/water/host/controller/HeartbeatDataController.java                         |  113 +
 src/main/java/com/lunhan/water/repository/vo/UserLoginVO.java                                       |   12 
 src/main/resources/application-prod.yml                                                             |   17 
 src/main/java/com/lunhan/water/repository/mapper/RechargeRecordsMapper.java                         |    6 
 src/main/java/com/lunhan/water/entity/request/heartbeatdata/ReqCreateHeartbeatData.java             |   45 
 src/main/java/com/lunhan/water/service/convert/FacilityAlarmRecordConvert.java                      |   48 
 src/main/java/com/lunhan/water/service/convert/ThirdNotifyConvert.java                              |   48 
 src/main/java/com/lunhan/water/entity/search/SearchWaterFacility.java                               |   23 
 src/main/java/com/lunhan/water/repository/vo/WaterFacilityVO.java                                   |   57 
 src/main/java/com/lunhan/water/repository/impl/WaterFacilityMapperImpl.java                         |  142 +
 src/main/java/com/lunhan/water/repository/po/ThirdNotifyPO.java                                     |  104 +
 src/main/java/com/lunhan/water/entity/search/SearchFacilityAlarmRecord.java                         |   14 
 src/main/java/com/lunhan/water/entity/search/SearchHeartbeatData.java                               |   14 
 src/main/java/com/lunhan/water/entity/request/adminuser/ReqAdminLogin.java                          |   13 
 src/main/java/com/lunhan/water/service/convert/HeartbeatDataConvert.java                            |   48 
 src/main/java/com/lunhan/water/repository/mapper/HeartbeatDataMapper.java                           |   10 
 src/main/resources/application-dev.yml                                                              |   29 
 src/main/java/com/lunhan/water/repository/vo/ThirdNotifyVO.java                                     |   54 
 src/main/java/com/lunhan/water/service/FacilityAlarmRecordService.java                              |  244 ++
 src/main/java/com/lunhan/water/entity/request/heartbeatdata/ReqModifyHeartbeatData.java             |   49 
 src/main/java/com/lunhan/water/repository/po/HeartbeatDataPO.java                                   |   74 
 src/main/java/com/lunhan/water/service/PaymentServices.java                                         |   12 
 src/main/java/com/lunhan/water/repository/vo/FacilityAlarmRecordVO.java                             |   54 
 src/main/java/com/lunhan/water/entity/request/thirdnotify/ReqCreateThirdNotify.java                 |   65 
 src/main/java/com/lunhan/water/host/controller/pay/PaymentServicesController.java                   |  166 
 src/main/java/com/lunhan/water/entity/request/userlogin/ReqCreateUserLogin.java                     |    2 
 src/main/java/com/lunhan/water/repository/impl/PaymentRecordsMapperImpl.java                        |   10 
 src/main/java/com/lunhan/water/host/controller/notify/NotifyController.java                         |  297 ++
 src/main/java/com/lunhan/water/host/controller/WaterFacilityController.java                         |  113 +
 src/main/java/com/lunhan/water/host/controller/PaymentRecordsController.java                        |   10 
 src/main/java/com/lunhan/water/repository/impl/RechargeRecordsMapperImpl.java                       |    8 
 src/main/java/com/lunhan/water/entity/response/pay/ResWeiXinPayNotify.java                          |   27 
 src/main/java/com/lunhan/water/entity/search/SearchRechargeRecords.java                             |    9 
 src/main/java/com/lunhan/water/repository/impl/UserLoginMapperImpl.java                             |  245 +-
 src/main/java/com/lunhan/water/repository/mapper/WaterFacilityMapper.java                           |   10 
 src/main/java/com/lunhan/water/service/PaymentRecordsService.java                                   |  284 ++
 src/main/java/com/lunhan/water/service/WaterFacilityService.java                                    |  281 ++
 src/main/java/com/lunhan/water/entity/request/facilityalarmrecord/ReqCreateFacilityAlarmRecord.java |   73 
 src/main/java/com/lunhan/water/repository/po/WaterFacilityPO.java                                   |  120 +
 src/main/java/com/lunhan/water/entity/request/facilityalarmrecord/ReqModifyFacilityAlarmRecord.java |   77 
 src/main/java/com/lunhan/water/service/RechargeOrderService.java                                    |   19 
 src/main/java/com/lunhan/water/service/UserLoginService.java                                        |   33 
 src/main/java/com/lunhan/water/repository/impl/HeartbeatDataMapperImpl.java                         |  142 +
 src/main/java/com/lunhan/water/common/util/LocalDateTimeUtils.java                                  |  501 ++++
 src/main/java/com/lunhan/water/service/AdminService.java                                            |   99 
 src/main/java/com/lunhan/water/host/mqtt/PushCallback.java                                          |   24 
 src/main/java/com/lunhan/water/service/ThirdNotifyService.java                                      |  283 ++
 src/main/java/com/lunhan/water/repository/vo/PaymentRecordsVO.java                                  |    4 
 src/main/java/com/lunhan/water/entity/request/thirdnotify/ReqModifyThirdNotify.java                 |   73 
 src/main/java/com/lunhan/water/service/RechargeRecordsService.java                                  |   37 
 pom.xml                                                                                             |    7 
 src/main/java/com/lunhan/water/entity/dto/pay/WeiXinRefundNotifyDto.java                            |  127 +
 src/main/java/com/lunhan/water/host/mqtt/CountVO.java                                               |    9 
 src/main/java/com/lunhan/water/repository/mapper/FacilityAlarmRecordMapper.java                     |   10 
 src/main/java/com/lunhan/water/host/controller/admin/AdminUserController.java                       |   31 
 src/main/java/com/lunhan/water/entity/dto/pay/WeiXinPayNotifyDto.java                               |   94 
 src/main/java/com/lunhan/water/host/controller/RechargeOrderController.java                         |    6 
 src/main/java/com/lunhan/water/entity/dto/pay/WeiXinPayNotifyDto_Amount.java                        |   40 
 src/main/java/com/lunhan/water/host/controller/api/UserController.java                              |  113 +
 src/main/java/com/lunhan/water/repository/impl/FacilityAlarmRecordMapperImpl.java                   |  137 +
 src/main/java/com/lunhan/water/repository/mapper/PaymentRecordsMapper.java                          |    8 
 src/main/java/com/lunhan/water/host/controller/FacilityAlarmRecordController.java                   |  113 +
 src/main/java/com/lunhan/water/service/convert/WaterFacilityConvert.java                            |   48 
 src/main/java/com/lunhan/water/entity/request/paymentrecords/ReqBuyWater.java                       |   11 
 src/main/java/com/lunhan/water/host/mqtt/MQTTServer.java                                            |   15 
 src/main/java/com/lunhan/water/entity/request/pay/ReqCreatePay.java                                 |    4 
 src/main/java/com/lunhan/water/repository/po/FacilityAlarmRecordPO.java                             |  109 +
 src/main/java/com/lunhan/water/host/controller/user/UserLoginController.java                        |   21 
 src/main/java/com/lunhan/water/entity/request/waterfacility/ReqCreateWaterFacility.java             |  106 +
 src/main/java/com/lunhan/water/entity/dto/pay/WeiXinRefundNotifyDto_Amount.java                     |   55 
 src/main/java/com/lunhan/water/repository/mapper/ThirdNotifyMapper.java                             |   10 
 src/main/java/com/lunhan/water/entity/search/SearchPaymentRecords.java                              |    8 
 src/main/java/com/lunhan/water/repository/po/RechargeRecordsPO.java                                 |   10 
 src/main/java/com/lunhan/water/repository/vo/HeartbeatDataVO.java                                   |   54 
 src/main/java/com/lunhan/water/entity/request/waterfacility/ReqModifyWaterFacility.java             |  114 +
 src/main/java/com/lunhan/water/repository/impl/ThirdNotifyMapperImpl.java                           |  142 +
 src/test/java/com/lunhan/water/GenCodeGauss.java                                                    |    2 
 src/main/java/com/lunhan/water/repository/po/UserLoginPO.java                                       |    5 
 src/main/resources/application.yml                                                                  |   22 
 84 files changed, 5,859 insertions(+), 317 deletions(-)

diff --git a/pom.xml b/pom.xml
index 88e71ab..eb8bd81 100644
--- a/pom.xml
+++ b/pom.xml
@@ -101,7 +101,12 @@
             <artifactId>mybatis-plus-boot-starter</artifactId>
             <version>3.5.7</version>
         </dependency>
-
+        <!--生成验证码工具-->
+        <dependency>
+            <groupId>com.github.whvcse</groupId>
+            <artifactId>easy-captcha</artifactId>
+            <version>1.6.2</version>
+        </dependency>
         <!-- logback + slf4j -->
         <dependency>
             <groupId>ch.qos.logback</groupId>
diff --git a/src/main/java/com/lunhan/water/common/util/LocalDateTimeUtils.java b/src/main/java/com/lunhan/water/common/util/LocalDateTimeUtils.java
new file mode 100644
index 0000000..c202c1d
--- /dev/null
+++ b/src/main/java/com/lunhan/water/common/util/LocalDateTimeUtils.java
@@ -0,0 +1,501 @@
+package com.lunhan.water.common.util;
+
+import java.sql.Timestamp;
+import java.time.*;
+import java.time.format.DateTimeFormatter;
+import java.time.temporal.ChronoUnit;
+import java.time.temporal.TemporalAdjusters;
+import java.util.Date;
+
+public class LocalDateTimeUtils {
+    /**
+     * 当前时间
+     *
+     * @return
+     */
+    public static LocalDateTime now() {
+        return LocalDateTime.now();
+    }
+
+    /**
+     * Date 转 LocalDateTime
+     *
+     * @return
+     */
+    public static LocalDateTime convert(Date date) {
+        return LocalDateTime.ofInstant(Instant.ofEpochMilli(date.getTime()), ZoneId.systemDefault());
+    }
+
+    /**
+     * LocalDateTime 转 Date
+     *
+     * @return
+     */
+    public static Date convert(LocalDateTime localDateTime) {
+        return Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant());
+    }
+    /**
+     * 当前小时开始时间
+     *
+     * @return
+     */
+    public static LocalDateTime hourStartTime() {
+        // 获取当前时间
+        LocalDateTime now = LocalDateTime.now();
+
+        // 获取当前小时的开始时间
+        return  now.withMinute(0).withSecond(0).withNano(0);
+    }
+
+    /**
+     * 当前小时结束时间
+     *
+     * @return
+     */
+    public static LocalDateTime hourEndTime() {
+        LocalDateTime now = LocalDateTime.now();
+        return   now.withMinute(59).withSecond(59).withNano(999999999); // 设置为最大毫秒数以确保包括最后一毫秒
+    }
+    /**
+     * 上个小时开始时间
+     *
+     * @return
+     */
+    public static LocalDateTime upHourStartTime() {
+
+        // 获取当前时间
+        LocalDateTime now = LocalDateTime.now();
+        // 获取一个小时前的时间
+        LocalDateTime oneHourAgo = now.minusHours(1);
+        // 获取当前小时的开始时间
+        return  oneHourAgo.withMinute(0).withSecond(0).withNano(0);
+    }
+    /**
+     * 上个小时结束时间
+     *
+     * @return
+     */
+    public static LocalDateTime upHourEndTime() {
+        // 获取当前时间
+        LocalDateTime now = LocalDateTime.now();
+        // 获取一个小时前的时间
+        LocalDateTime oneHourAgo = now.minusHours(1);
+
+        // 获取当前小时的开始时间
+        return  oneHourAgo.withMinute(59).withSecond(59).withNano(999999999); // 设置为最大毫秒数以确保包括最后一毫秒
+    }
+    /**
+     * 今天开始时间
+     *
+     * @return
+     */
+    public static LocalDateTime todayStartTime() {
+        return LocalDateTime.of(LocalDate.now(), LocalTime.MIN);
+    }
+
+    /**
+     * 今天结束时间
+     *
+     * @return
+     */
+    public static LocalDateTime todayEndTime() {
+        return LocalDateTime.of(LocalDate.now(), LocalTime.MAX);
+    }
+
+    /**
+     * 昨天开始时间
+     *
+     * @return
+     */
+    public static LocalDateTime yesterdayStartTime() {
+        return LocalDateTime.of(LocalDate.now().minus(1L, ChronoUnit.DAYS), LocalTime.MIN);
+    }
+
+    /**
+     * 昨天结束时间
+     *
+     * @return
+     */
+    public static LocalDateTime yesterdayEndTime() {
+        return LocalDateTime.of(LocalDate.now().minus(1L, ChronoUnit.DAYS), LocalTime.MAX);
+    }
+
+    /**
+     * 最近7天开始时间
+     *
+     * @return
+     */
+    public static LocalDateTime last7DaysStartTime() {
+        return LocalDateTime.of(LocalDate.now().minus(6L, ChronoUnit.DAYS), LocalTime.MIN);
+    }
+
+    /**
+     * 最近7天结束时间
+     *
+     * @return
+     */
+    public static LocalDateTime last7DaysEndTime() {
+        return LocalDateTime.of(LocalDate.now(), LocalTime.MAX);
+    }
+
+    /**
+     * 最近30天开始时间
+     *
+     * @return
+     */
+    public static LocalDateTime last30DaysStartTime() {
+        return LocalDateTime.of(LocalDate.now().minus(29L, ChronoUnit.DAYS), LocalTime.MIN);
+    }
+
+    /**
+     * 最近30天结束时间
+     *
+     * @return
+     */
+    public static LocalDateTime last30DaysEndTime() {
+        return LocalDateTime.of(LocalDate.now(), LocalTime.MAX);
+    }
+
+    /**
+     * 最近一年开始时间
+     *
+     * @return
+     */
+    public static LocalDateTime last1YearStartTime() {
+        return LocalDateTime.of(LocalDate.now().minus(1L, ChronoUnit.YEARS).plus(1L, ChronoUnit.DAYS), LocalTime.MIN);
+    }
+
+    /**
+     * 最近一年结束时间
+     *
+     * @return
+     */
+    public static LocalDateTime last1YearEndTime() {
+        return LocalDateTime.of(LocalDate.now(), LocalTime.MAX);
+    }
+    /**
+     * 本周开始时间
+     *
+     * @return
+     */
+    public static LocalDateTime weekStartTime() {
+        LocalDate now = LocalDate.now();
+        return LocalDateTime.of(now.minusDays(now.getDayOfWeek().getValue() - 1), LocalTime.MIN);
+    }
+
+    /**
+     * 本周结束时间
+     *
+     * @return
+     */
+    public static LocalDateTime weekEndTime() {
+        LocalDate now = LocalDate.now();
+        return LocalDateTime.of(now.plusDays(7 - now.getDayOfWeek().getValue()), LocalTime.MAX);
+    }
+
+    /**
+     * 本月开始时间
+     *
+     * @return
+     */
+    public static LocalDateTime monthStartTime() {
+        return LocalDateTime.of(LocalDate.now().with(TemporalAdjusters.firstDayOfMonth()), LocalTime.MIN);
+    }
+
+    /**
+     * 本月结束时间
+     *
+     * @return
+     */
+    public static LocalDateTime monthEndTime() {
+        return LocalDateTime.of(LocalDate.now().with(TemporalAdjusters.lastDayOfMonth()), LocalTime.MAX);
+    }
+
+    /**
+     * 本季度开始时间
+     *
+     * @return
+     */
+    public static LocalDateTime quarterStartTime() {
+        LocalDate now = LocalDate.now();
+        Month month = Month.of(now.getMonth().firstMonthOfQuarter().getValue());
+        return LocalDateTime.of(LocalDate.of(now.getYear(), month, 1), LocalTime.MIN);
+    }
+
+    /**
+     * 本季度结束时间
+     *
+     * @return
+     */
+    public static LocalDateTime quarterEndTime() {
+        LocalDate now = LocalDate.now();
+        Month month = Month.of(now.getMonth().firstMonthOfQuarter().getValue()).plus(2L);
+        return LocalDateTime.of(LocalDate.of(now.getYear(), month, month.length(now.isLeapYear())), LocalTime.MAX);
+    }
+
+    /**
+     * 本半年开始时间
+     *
+     * @return
+     */
+    public static LocalDateTime halfYearStartTime() {
+        LocalDate now = LocalDate.now();
+        Month month = (now.getMonthValue() > 6) ? Month.JULY : Month.JANUARY;
+        return LocalDateTime.of(LocalDate.of(now.getYear(), month, 1), LocalTime.MIN);
+    }
+
+    /**
+     * 本半年结束时间
+     *
+     * @return
+     */
+    public static LocalDateTime halfYearEndTime() {
+        LocalDate now = LocalDate.now();
+        Month month = (now.getMonthValue() > 6) ? Month.DECEMBER : Month.JUNE;
+        return LocalDateTime.of(LocalDate.of(now.getYear(), month, month.length(now.isLeapYear())), LocalTime.MAX);
+    }
+
+    /**
+     * 本年开始时间
+     *
+     * @return
+     */
+    public static LocalDateTime yearStartTime() {
+        return LocalDateTime.of(LocalDate.now().with(TemporalAdjusters.firstDayOfYear()), LocalTime.MIN);
+    }
+
+    /**
+     * 本年结束时间
+     *
+     * @return
+     */
+    public static LocalDateTime yearEndTime() {
+        return LocalDateTime.of(LocalDate.now().with(TemporalAdjusters.lastDayOfYear()), LocalTime.MAX);
+    }
+
+    /**
+     * 上周开始时间
+     *
+     * @return
+     */
+    public static LocalDateTime lastWeekStartTime() {
+        LocalDate lastWeek = LocalDate.now().minus(1L, ChronoUnit.WEEKS);
+        return LocalDateTime.of(lastWeek.minusDays(lastWeek.getDayOfWeek().getValue() - 1), LocalTime.MIN);
+    }
+
+    /**
+     * 上周结束时间
+     *
+     * @return
+     */
+    public static LocalDateTime lastWeekEndTime() {
+        LocalDate lastWeek = LocalDate.now().minus(1L, ChronoUnit.WEEKS);
+        return LocalDateTime.of(lastWeek.plusDays(7 - lastWeek.getDayOfWeek().getValue()), LocalTime.MAX);
+    }
+
+    /**
+     * 上月开始时间
+     *
+     * @return
+     */
+    public static LocalDateTime lastMonthStartTime() {
+        return LocalDateTime.of(LocalDate.now().minus(1L, ChronoUnit.MONTHS).with(TemporalAdjusters.firstDayOfMonth()), LocalTime.MIN);
+    }
+
+    /**
+     * 上月结束时间
+     *
+     * @return
+     */
+    public static LocalDateTime lastMonthEndTime() {
+        return LocalDateTime.of(LocalDate.now().minus(1L, ChronoUnit.MONTHS).with(TemporalAdjusters.lastDayOfMonth()), LocalTime.MAX);
+    }
+
+    /**
+     * 上季度开始时间
+     *
+     * @return
+     */
+    public static LocalDateTime lastQuarterStartTime() {
+        LocalDate now = LocalDate.now();
+        Month firstMonthOfQuarter = Month.of(now.getMonth().firstMonthOfQuarter().getValue());
+        Month firstMonthOfLastQuarter = firstMonthOfQuarter.minus(3L);
+        int yearOfLastQuarter = firstMonthOfQuarter.getValue() < 4 ? now.getYear() - 1 : now.getYear();
+        return LocalDateTime.of(LocalDate.of(yearOfLastQuarter, firstMonthOfLastQuarter, 1), LocalTime.MIN);
+    }
+
+    /**
+     * 上季度结束时间
+     *
+     * @return
+     */
+    public static LocalDateTime lastQuarterEndTime() {
+        LocalDate now = LocalDate.now();
+        Month firstMonthOfQuarter = Month.of(now.getMonth().firstMonthOfQuarter().getValue());
+        Month firstMonthOfLastQuarter = firstMonthOfQuarter.minus(1L);
+        int yearOfLastQuarter = firstMonthOfQuarter.getValue() < 4 ? now.getYear() - 1 : now.getYear();
+        return LocalDateTime.of(LocalDate.of(yearOfLastQuarter, firstMonthOfLastQuarter, firstMonthOfLastQuarter.maxLength()), LocalTime.MAX);
+    }
+
+    /**
+     * 上半年开始时间
+     *
+     * @return
+     */
+    public static LocalDateTime lastHalfYearStartTime() {
+        LocalDate now = LocalDate.now();
+        int lastHalfYear = (now.getMonthValue() > 6) ? now.getYear() : now.getYear() - 1;
+        Month firstMonthOfLastHalfYear = (now.getMonthValue() > 6) ? Month.JANUARY : Month.JULY;
+        return LocalDateTime.of(LocalDate.of(lastHalfYear, firstMonthOfLastHalfYear, 1), LocalTime.MIN);
+    }
+
+    /**
+     * 上半年结束时间
+     *
+     * @return
+     */
+    public static LocalDateTime lastHalfYearEndTime() {
+        LocalDate now = LocalDate.now();
+        int lastHalfYear = (now.getMonthValue() > 6) ? now.getYear() : now.getYear() - 1;
+        Month lastMonthOfLastHalfYear = (now.getMonthValue() > 6) ? Month.JUNE : Month.DECEMBER;
+        return LocalDateTime.of(LocalDate.of(lastHalfYear, lastMonthOfLastHalfYear, lastMonthOfLastHalfYear.maxLength()), LocalTime.MAX);
+    }
+
+    /**
+     * 上一年开始时间
+     *
+     * @return
+     */
+    public static LocalDateTime lastYearStartTime() {
+        return LocalDateTime.of(LocalDate.now().minus(1L, ChronoUnit.YEARS).with(TemporalAdjusters.firstDayOfYear()), LocalTime.MIN);
+    }
+
+    /**
+     * 上一年结束时间
+     *
+     * @return
+     */
+    public static LocalDateTime lastYearEndTime() {
+        return LocalDateTime.of(LocalDate.now().minus(1L, ChronoUnit.YEARS).with(TemporalAdjusters.lastDayOfYear()), LocalTime.MAX);
+    }
+
+    /**
+     * 下周开始时间
+     *
+     * @return
+     */
+    public static LocalDateTime nextWeekStartTime() {
+        LocalDate nextWeek = LocalDate.now().plus(1L, ChronoUnit.WEEKS);
+        return LocalDateTime.of(nextWeek.minusDays(nextWeek.getDayOfWeek().getValue() - 1), LocalTime.MIN);
+    }
+
+    /**
+     * 下周结束时间
+     *
+     * @return
+     */
+    public static LocalDateTime nextWeekEndTime() {
+        LocalDate nextWeek = LocalDate.now().plus(1L, ChronoUnit.WEEKS);
+        return LocalDateTime.of(nextWeek.plusDays(7 - nextWeek.getDayOfWeek().getValue()), LocalTime.MAX);
+    }
+
+    /**
+     * 下月开始时间
+     *
+     * @return
+     */
+    public static LocalDateTime nextMonthStartTime() {
+        return LocalDateTime.of(LocalDate.now().plus(1L, ChronoUnit.MONTHS).with(TemporalAdjusters.firstDayOfMonth()), LocalTime.MIN);
+    }
+
+    /**
+     * 下月结束时间
+     *
+     * @return
+     */
+    public static LocalDateTime nextMonthEndTime() {
+        return LocalDateTime.of(LocalDate.now().plus(1L, ChronoUnit.MONTHS).with(TemporalAdjusters.lastDayOfMonth()), LocalTime.MAX);
+    }
+
+    /**
+     * 下季度开始时间
+     *
+     * @return
+     */
+    public static LocalDateTime nextQuarterStartTime() {
+        LocalDate now = LocalDate.now();
+        Month firstMonthOfQuarter = Month.of(now.getMonth().firstMonthOfQuarter().getValue());
+        Month firstMonthOfNextQuarter = firstMonthOfQuarter.plus(3L);
+        int yearOfNextQuarter = firstMonthOfQuarter.getValue() > 9 ? now.getYear() + 1 : now.getYear();
+        return LocalDateTime.of(LocalDate.of(yearOfNextQuarter, firstMonthOfNextQuarter, 1), LocalTime.MIN);
+    }
+
+    /**
+     * 下季度结束时间
+     *
+     * @return
+     */
+    public static LocalDateTime nextQuarterEndTime() {
+        LocalDate now = LocalDate.now();
+        Month firstMonthOfQuarter = Month.of(now.getMonth().firstMonthOfQuarter().getValue());
+        Month firstMonthOfNextQuarter = firstMonthOfQuarter.plus(5L);
+        int yearOfNextQuarter = firstMonthOfQuarter.getValue() > 9 ? now.getYear() + 1 : now.getYear();
+        return LocalDateTime.of(LocalDate.of(yearOfNextQuarter, firstMonthOfNextQuarter, firstMonthOfNextQuarter.maxLength()), LocalTime.MAX);
+    }
+
+    /**
+     * 上半年开始时间
+     *
+     * @return
+     */
+    public static LocalDateTime nextHalfYearStartTime() {
+        LocalDate now = LocalDate.now();
+        int nextHalfYear = (now.getMonthValue() > 6) ? now.getYear() + 1 : now.getYear();
+        Month firstMonthOfNextHalfYear = (now.getMonthValue() > 6) ? Month.JANUARY : Month.JULY;
+        return LocalDateTime.of(LocalDate.of(nextHalfYear, firstMonthOfNextHalfYear, 1), LocalTime.MIN);
+    }
+
+    /**
+     * 上半年结束时间
+     *
+     * @return
+     */
+    public static LocalDateTime nextHalfYearEndTime() {
+        LocalDate now = LocalDate.now();
+        int lastHalfYear = (now.getMonthValue() > 6) ? now.getYear() + 1 : now.getYear();
+        Month lastMonthOfNextHalfYear = (now.getMonthValue() > 6) ? Month.JUNE : Month.DECEMBER;
+        return LocalDateTime.of(LocalDate.of(lastHalfYear, lastMonthOfNextHalfYear, lastMonthOfNextHalfYear.maxLength()), LocalTime.MAX);
+    }
+
+    /**
+     * 下一年开始时间
+     *
+     * @return
+     */
+    public static LocalDateTime nextYearStartTime() {
+        return LocalDateTime.of(LocalDate.now().plus(1L, ChronoUnit.YEARS).with(TemporalAdjusters.firstDayOfYear()), LocalTime.MIN);
+    }
+
+    /**
+     * 下一年结束时间
+     *
+     * @return
+     */
+    public static LocalDateTime nextYearEndTime() {
+        return LocalDateTime.of(LocalDate.now().plus(1L, ChronoUnit.YEARS).with(TemporalAdjusters.lastDayOfYear()), LocalTime.MAX);
+    }
+    public static Timestamp getDateStartTime(String dateTime, String format) {
+        DateTimeFormatter formatter = DateTimeFormatter.ofPattern(format);
+        // 解析日期字符串为LocalDate对象
+        LocalDate date = LocalDate.parse(dateTime, formatter);
+        LocalDateTime startOfDay = date.atStartOfDay();
+        return  LocalDateTimeUtil.getTimeStamp(startOfDay);
+    }
+    public static Timestamp getDateLastTime(String dateTime, String format) {
+        DateTimeFormatter formatter = DateTimeFormatter.ofPattern(format);
+        // 解析日期字符串为LocalDate对象
+        LocalDate date = LocalDate.parse(dateTime, formatter);
+        LocalDateTime endOfDay = date.atTime(LocalTime.MAX);
+        return  LocalDateTimeUtil.getTimeStamp(endOfDay);
+    }
+}
diff --git a/src/main/java/com/lunhan/water/entity/dto/pay/WeiXinPayNotifyDto.java b/src/main/java/com/lunhan/water/entity/dto/pay/WeiXinPayNotifyDto.java
new file mode 100644
index 0000000..245129f
--- /dev/null
+++ b/src/main/java/com/lunhan/water/entity/dto/pay/WeiXinPayNotifyDto.java
@@ -0,0 +1,94 @@
+package com.lunhan.water.entity.dto.pay;
+
+public class WeiXinPayNotifyDto {
+    private String transaction_id;
+    private String out_trade_no;
+    private String mchId;
+    private String appID;
+    private String trade_state;
+    private String trade_state_desc;
+    private String success_time;
+    private String trade_type;
+    private String bank_type;
+    private WeiXinPayNotifyDto_Amount amount;
+
+    public String getTransaction_id() {
+        return transaction_id;
+    }
+
+    public void setTransaction_id(String transaction_id) {
+        this.transaction_id = transaction_id;
+    }
+
+    public String getOut_trade_no() {
+        return out_trade_no;
+    }
+
+    public void setOut_trade_no(String out_trade_no) {
+        this.out_trade_no = out_trade_no;
+    }
+
+    public String getMchId() {
+        return mchId;
+    }
+
+    public void setMchId(String mchId) {
+        this.mchId = mchId;
+    }
+
+    public String getAppID() {
+        return appID;
+    }
+
+    public void setAppID(String appID) {
+        this.appID = appID;
+    }
+
+    public String getTrade_state() {
+        return trade_state;
+    }
+
+    public void setTrade_state(String trade_state) {
+        this.trade_state = trade_state;
+    }
+
+    public String getTrade_state_desc() {
+        return trade_state_desc;
+    }
+
+    public void setTrade_state_desc(String trade_state_desc) {
+        this.trade_state_desc = trade_state_desc;
+    }
+
+    public String getSuccess_time() {
+        return success_time;
+    }
+
+    public void setSuccess_time(String success_time) {
+        this.success_time = success_time;
+    }
+
+    public String getTrade_type() {
+        return trade_type;
+    }
+
+    public void setTrade_type(String trade_type) {
+        this.trade_type = trade_type;
+    }
+
+    public String getBank_type() {
+        return bank_type;
+    }
+
+    public void setBank_type(String bank_type) {
+        this.bank_type = bank_type;
+    }
+
+    public WeiXinPayNotifyDto_Amount getAmount() {
+        return amount;
+    }
+
+    public void setAmount(WeiXinPayNotifyDto_Amount amount) {
+        this.amount = amount;
+    }
+}
diff --git a/src/main/java/com/lunhan/water/entity/dto/pay/WeiXinPayNotifyDto_Amount.java b/src/main/java/com/lunhan/water/entity/dto/pay/WeiXinPayNotifyDto_Amount.java
new file mode 100644
index 0000000..c1c0b20
--- /dev/null
+++ b/src/main/java/com/lunhan/water/entity/dto/pay/WeiXinPayNotifyDto_Amount.java
@@ -0,0 +1,40 @@
+package com.lunhan.water.entity.dto.pay;
+
+public class WeiXinPayNotifyDto_Amount {
+    private Integer total;
+    private String currency;
+    private Integer payer_total;
+    private String payer_currency;
+
+    public Integer getTotal() {
+        return total;
+    }
+
+    public void setTotal(Integer total) {
+        this.total = total;
+    }
+
+    public String getCurrency() {
+        return currency;
+    }
+
+    public void setCurrency(String currency) {
+        this.currency = currency;
+    }
+
+    public Integer getPayer_total() {
+        return payer_total;
+    }
+
+    public void setPayer_total(Integer payer_total) {
+        this.payer_total = payer_total;
+    }
+
+    public String getPayer_currency() {
+        return payer_currency;
+    }
+
+    public void setPayer_currency(String payer_currency) {
+        this.payer_currency = payer_currency;
+    }
+}
diff --git a/src/main/java/com/lunhan/water/entity/dto/pay/WeiXinRefundNotifyDto.java b/src/main/java/com/lunhan/water/entity/dto/pay/WeiXinRefundNotifyDto.java
new file mode 100644
index 0000000..0aed11f
--- /dev/null
+++ b/src/main/java/com/lunhan/water/entity/dto/pay/WeiXinRefundNotifyDto.java
@@ -0,0 +1,127 @@
+package com.lunhan.water.entity.dto.pay;
+
+public class WeiXinRefundNotifyDto {
+    /**
+     * 直连商户的商户号,由微信支付生成并下发
+     */
+    private String mchid;
+
+    /**
+     * 返回的商户订单号
+     */
+    private String out_trade_no;
+
+    /**
+     * 返回的商户订单号
+     */
+    private String transaction_id;
+
+    /**
+     * 商户退款单号
+     */
+    private String out_refund_no;
+
+    /**
+     * 微信退款单号
+     */
+    private String refund_id;
+
+    /**
+     * 退款状态,枚举值:
+     * SUCCESS:退款成功
+     * CLOSED:退款关闭
+     * ABNORMAL:退款异常,退款到银行发现用户的卡作废或者冻结了,导致原路退款银行卡失败,可前往【商户平台—>交易中心】,手动处理此笔退款
+     */
+    private String refund_status;
+
+    /**
+     * 1、退款成功时间,遵循rfc3339标准格式,格式为yyyy-MM-DDTHH:mm:ss+TIMEZONE,yyyy-MM-DD表示年月日,T出现在字符串中,表示time元素的开头,HH:mm:ss表示时分秒,TIMEZONE表示时区(+08:00表示东八区时间,领先UTC 8小时,即北京时间)。例如:2015-05-20T13:29:35+08:00表示,北京时间2015年5月20日13点29分35秒
+     */
+    private String success_time;
+
+    /**
+     * 取当前退款单的退款入账方。
+     * 1、退回银行卡:{银行名称}{卡类型}{卡尾号}
+     * 2、退回支付用户零钱: 支付用户零钱
+     * 3、退还商户: 商户基本账户、商户结算银行账户
+     * 4、退回支付用户零钱通:支付用户零钱通
+     */
+    private String user_received_account;
+
+    /**
+     * 金额信息
+     */
+    private WeiXinRefundNotifyDto_Amount amount;
+
+    public String getMchid() {
+        return mchid;
+    }
+
+    public void setMchid(String mchid) {
+        this.mchid = mchid;
+    }
+
+    public String getOut_trade_no() {
+        return out_trade_no;
+    }
+
+    public void setOut_trade_no(String out_trade_no) {
+        this.out_trade_no = out_trade_no;
+    }
+
+    public String getTransaction_id() {
+        return transaction_id;
+    }
+
+    public void setTransaction_id(String transaction_id) {
+        this.transaction_id = transaction_id;
+    }
+
+    public String getOut_refund_no() {
+        return out_refund_no;
+    }
+
+    public void setOut_refund_no(String out_refund_no) {
+        this.out_refund_no = out_refund_no;
+    }
+
+    public String getRefund_id() {
+        return refund_id;
+    }
+
+    public void setRefund_id(String refund_id) {
+        this.refund_id = refund_id;
+    }
+
+    public String getRefund_status() {
+        return refund_status;
+    }
+
+    public void setRefund_status(String refund_status) {
+        this.refund_status = refund_status;
+    }
+
+    public String getSuccess_time() {
+        return success_time;
+    }
+
+    public void setSuccess_time(String success_time) {
+        this.success_time = success_time;
+    }
+
+    public String getUser_received_account() {
+        return user_received_account;
+    }
+
+    public void setUser_received_account(String user_received_account) {
+        this.user_received_account = user_received_account;
+    }
+
+    public WeiXinRefundNotifyDto_Amount getAmount() {
+        return amount;
+    }
+
+    public void setAmount(WeiXinRefundNotifyDto_Amount amount) {
+        this.amount = amount;
+    }
+}
diff --git a/src/main/java/com/lunhan/water/entity/dto/pay/WeiXinRefundNotifyDto_Amount.java b/src/main/java/com/lunhan/water/entity/dto/pay/WeiXinRefundNotifyDto_Amount.java
new file mode 100644
index 0000000..b53d445
--- /dev/null
+++ b/src/main/java/com/lunhan/water/entity/dto/pay/WeiXinRefundNotifyDto_Amount.java
@@ -0,0 +1,55 @@
+package com.lunhan.water.entity.dto.pay;
+
+public class WeiXinRefundNotifyDto_Amount {
+    /**
+     * 订单总金额,单位为分,只能为整数
+     */
+    private Integer total;
+
+    /**
+     * 退款金额,币种的最小单位,只能为整数,不能超过原订单支付金额,如果有使用券,后台会按比例退
+     */
+    private Integer refund;
+
+    /**
+     * 用户实际支付金额,单位为分,只能为整数
+     */
+    private Integer payer_total;
+
+    /**
+     * 退款给用户的金额,不包含所有优惠券金额
+     */
+    private Integer payer_refund;
+
+    public Integer getTotal() {
+        return total;
+    }
+
+    public void setTotal(Integer total) {
+        this.total = total;
+    }
+
+    public Integer getRefund() {
+        return refund;
+    }
+
+    public void setRefund(Integer refund) {
+        this.refund = refund;
+    }
+
+    public Integer getPayer_total() {
+        return payer_total;
+    }
+
+    public void setPayer_total(Integer payer_total) {
+        this.payer_total = payer_total;
+    }
+
+    public Integer getPayer_refund() {
+        return payer_refund;
+    }
+
+    public void setPayer_refund(Integer payer_refund) {
+        this.payer_refund = payer_refund;
+    }
+}
diff --git a/src/main/java/com/lunhan/water/entity/enums/EBillPayStatus.java b/src/main/java/com/lunhan/water/entity/enums/EBillPayStatus.java
new file mode 100644
index 0000000..7a9ad70
--- /dev/null
+++ b/src/main/java/com/lunhan/water/entity/enums/EBillPayStatus.java
@@ -0,0 +1,68 @@
+package com.lunhan.water.entity.enums;
+
+import java.util.Arrays;
+import java.util.Objects;
+
+/**
+ * 账单缴费状态
+ */
+public enum EBillPayStatus {
+    /**
+     * 待缴费=100,
+     */
+    WAITING("待缴费", 100),
+    /**
+     * 缴费中=102,
+     */
+    PAYING("缴费中", 102),
+    /**
+     * 交费成功=200
+     */
+    PAID("交费成功", 200),
+    /**
+     * 交费失败=300
+     */
+    FAILED("交费失败", 200)
+    ;
+
+    private String desc;//枚举描述
+    private Integer value;//枚举值
+
+    public Integer getValue() {
+        return value;
+    }
+    public String getDesc() {
+        return desc;
+    }
+
+    /**
+     * 构造方法
+     * @param desc 枚举描述
+     * @param value 枚举值
+     */
+    EBillPayStatus(String desc, Integer value) {
+        this.desc = desc;
+        this.value = value;
+    }
+
+    /**
+     * 根据值获取枚举
+     *
+     * @param value 枚举值
+     * @return
+     */
+    public static EBillPayStatus getByValue(Integer value) {
+        return Arrays.stream(EBillPayStatus.values())
+                .filter(e -> Objects.equals(e.getValue(), value))
+                .findAny()
+                .orElse(null);
+    }
+
+    @Override
+    public String toString() {
+        return "EBillPayStatus{" +
+                "desc='" + desc + '\'' +
+                ", value=" + value +
+                '}';
+    }
+}
diff --git a/src/main/java/com/lunhan/water/entity/enums/EPayNotifyState.java b/src/main/java/com/lunhan/water/entity/enums/EPayNotifyState.java
new file mode 100644
index 0000000..de050ae
--- /dev/null
+++ b/src/main/java/com/lunhan/water/entity/enums/EPayNotifyState.java
@@ -0,0 +1,64 @@
+package com.lunhan.water.entity.enums;
+
+import java.util.Arrays;
+
+/**
+ * 支付通知记录状态枚举 待处理=0,成功=1,失败=2
+ */
+public enum EPayNotifyState {
+    /**
+     * 待处理=0
+     */
+    WAITING("WAITING", 0),
+
+    /**
+     * 成功=1
+     */
+    SUCCESS("SUCCESS", 1),
+
+    /**
+     * 失败=2
+     */
+    FAILED("FAILED", 2);
+
+    private String desc;//枚举描述
+    private int value;//枚举值
+
+    public int getValue() {
+        return value;
+    }
+    public String getDesc() {
+        return desc;
+    }
+
+    /**
+     * 构造方法
+     * @param desc 枚举描述
+     * @param value 枚举值
+     */
+    EPayNotifyState(String desc, int value) {
+        this.desc = desc;
+        this.value = value;
+    }
+
+    /**
+     * 根据值获取枚举
+     *
+     * @param value 枚举值
+     * @return
+     */
+    public static EPayNotifyState getByValue(int value) {
+        return Arrays.stream(EPayNotifyState.values())
+                .filter(e -> e.getValue() == value)
+                .findFirst()
+                .orElse(null);
+    }
+
+    @Override
+    public String toString() {
+        return "EPayNotifyState{" +
+                "desc='" + desc + '\'' +
+                ", value=" + value +
+                '}';
+    }
+}
diff --git a/src/main/java/com/lunhan/water/entity/request/adminuser/ReqAdminLogin.java b/src/main/java/com/lunhan/water/entity/request/adminuser/ReqAdminLogin.java
index 372f4be..d7b2f33 100644
--- a/src/main/java/com/lunhan/water/entity/request/adminuser/ReqAdminLogin.java
+++ b/src/main/java/com/lunhan/water/entity/request/adminuser/ReqAdminLogin.java
@@ -5,6 +5,15 @@
 @Data
 public class ReqAdminLogin {
     /**
+     * uuid:随机字符串
+     */
+
+    private String uuid;
+    /**
+     * 验证码
+     */
+    private String code;
+    /**
      * 登录账户
      * @required
      */
@@ -14,4 +23,8 @@
      * @required
      */
     private String password;
+    /**
+     * 登录设备码
+     */
+    private String machineCode;
 }
diff --git a/src/main/java/com/lunhan/water/entity/request/facilityalarmrecord/ReqCreateFacilityAlarmRecord.java b/src/main/java/com/lunhan/water/entity/request/facilityalarmrecord/ReqCreateFacilityAlarmRecord.java
new file mode 100644
index 0000000..4b64132
--- /dev/null
+++ b/src/main/java/com/lunhan/water/entity/request/facilityalarmrecord/ReqCreateFacilityAlarmRecord.java
@@ -0,0 +1,73 @@
+/**
+#                                                    __----~~~~~~~~~~~------___
+#                                   .  .   ~~//====......          __--~ ~~
+#                   -.            \_|//     |||\\  ~~~~~~::::... /~
+#                ___-==_       _-~o~  \/    |||  \\            _/~~-
+#        __---~~~.==~||\=_    -_--~/_-~|-   |\\   \\        _/~
+#    _-~~     .=~    |  \\-_    '-~7  /-   /  ||    \      /
+#  .~       .~       |   \\ -_    /  /-   /   ||      \   /
+# /  ____  /         |     \\ ~-_/  /|- _/   .||       \ /
+# |~~    ~~|--~~~~--_ \     ~==-/   | \~--===~~        .\
+#          '         ~-|      /|    |-~\~~       __--~~
+#                      |-~~-_/ |    |   ~\_   _-~            /\
+#                           /  \     \__   \/~                \__
+#                       _--~ _/ | .-~~____--~-/                  ~~==.
+#                      ((->/~   '.|||' -_|    ~~-/ ,              . _||
+#                                 -_     ~\      ~~---l__i__i__i--~~_/
+#                                 _-~-__   ~)  \--______________--~~
+#                               //.-~~~-~_--~- |-------~~~~~~~~
+#                                      //.-~~~--\
+#                  神兽保佑
+#                  永无BUG!
+*/
+package com.lunhan.water.entity.request.facilityalarmrecord;
+
+import lombok.Data;
+
+/**
+ * 设备报警记录
+ * @author lin.liu
+ */
+@Data
+public class ReqCreateFacilityAlarmRecord {
+	/**
+	 * 设备id
+	 */
+	private Long facilityId;
+	/**
+	 * 设备名称
+	 */
+	private String facilityName;
+	/**
+	 * 参数编码
+	 */
+	private String columnsCode;
+	/**
+	 * 参数名称
+	 */
+	private String columnsName;
+	/**
+	 * 报警描述
+	 */
+	private String description;
+	/**
+	 * 报警次数
+	 */
+	private Integer alarmCount;
+	/**
+	 * 首次报警时间
+	 */
+	private String firstAlarmTime;
+	/**
+	 * 最后报警时间
+	 */
+	private String latestAlarmTime;
+	/**
+	 * 监控点id
+	 */
+	private Long pointId;
+	/**
+	 * 监控点名称
+	 */
+	private String pointName;
+}
diff --git a/src/main/java/com/lunhan/water/entity/request/facilityalarmrecord/ReqModifyFacilityAlarmRecord.java b/src/main/java/com/lunhan/water/entity/request/facilityalarmrecord/ReqModifyFacilityAlarmRecord.java
new file mode 100644
index 0000000..c52f05c
--- /dev/null
+++ b/src/main/java/com/lunhan/water/entity/request/facilityalarmrecord/ReqModifyFacilityAlarmRecord.java
@@ -0,0 +1,77 @@
+/**
+#                                                    __----~~~~~~~~~~~------___
+#                                   .  .   ~~//====......          __--~ ~~
+#                   -.            \_|//     |||\\  ~~~~~~::::... /~
+#                ___-==_       _-~o~  \/    |||  \\            _/~~-
+#        __---~~~.==~||\=_    -_--~/_-~|-   |\\   \\        _/~
+#    _-~~     .=~    |  \\-_    '-~7  /-   /  ||    \      /
+#  .~       .~       |   \\ -_    /  /-   /   ||      \   /
+# /  ____  /         |     \\ ~-_/  /|- _/   .||       \ /
+# |~~    ~~|--~~~~--_ \     ~==-/   | \~--===~~        .\
+#          '         ~-|      /|    |-~\~~       __--~~
+#                      |-~~-_/ |    |   ~\_   _-~            /\
+#                           /  \     \__   \/~                \__
+#                       _--~ _/ | .-~~____--~-/                  ~~==.
+#                      ((->/~   '.|||' -_|    ~~-/ ,              . _||
+#                                 -_     ~\      ~~---l__i__i__i--~~_/
+#                                 _-~-__   ~)  \--______________--~~
+#                               //.-~~~-~_--~- |-------~~~~~~~~
+#                                      //.-~~~--\
+#                  神兽保佑
+#                  永无BUG!
+*/
+package com.lunhan.water.entity.request.facilityalarmrecord;
+
+import lombok.Data;
+
+/**
+ * 设备报警记录
+ * @author lin.liu
+ */
+@Data
+public class ReqModifyFacilityAlarmRecord {
+	/**
+	 * 主键id
+	 */
+	private Long id;
+	/**
+	 * 设备id
+	 */
+	private Long facilityId;
+	/**
+	 * 设备名称
+	 */
+	private String facilityName;
+	/**
+	 * 参数编码
+	 */
+	private String columnsCode;
+	/**
+	 * 参数名称
+	 */
+	private String columnsName;
+	/**
+	 * 报警描述
+	 */
+	private String description;
+	/**
+	 * 报警次数
+	 */
+	private Integer alarmCount;
+	/**
+	 * 首次报警时间
+	 */
+	private String firstAlarmTime;
+	/**
+	 * 最后报警时间
+	 */
+	private String latestAlarmTime;
+	/**
+	 * 监控点id
+	 */
+	private Long pointId;
+	/**
+	 * 监控点名称
+	 */
+	private String pointName;
+}
diff --git a/src/main/java/com/lunhan/water/entity/request/heartbeatdata/ReqCreateHeartbeatData.java b/src/main/java/com/lunhan/water/entity/request/heartbeatdata/ReqCreateHeartbeatData.java
new file mode 100644
index 0000000..a5a50f6
--- /dev/null
+++ b/src/main/java/com/lunhan/water/entity/request/heartbeatdata/ReqCreateHeartbeatData.java
@@ -0,0 +1,45 @@
+/**
+#                                                    __----~~~~~~~~~~~------___
+#                                   .  .   ~~//====......          __--~ ~~
+#                   -.            \_|//     |||\\  ~~~~~~::::... /~
+#                ___-==_       _-~o~  \/    |||  \\            _/~~-
+#        __---~~~.==~||\=_    -_--~/_-~|-   |\\   \\        _/~
+#    _-~~     .=~    |  \\-_    '-~7  /-   /  ||    \      /
+#  .~       .~       |   \\ -_    /  /-   /   ||      \   /
+# /  ____  /         |     \\ ~-_/  /|- _/   .||       \ /
+# |~~    ~~|--~~~~--_ \     ~==-/   | \~--===~~        .\
+#          '         ~-|      /|    |-~\~~       __--~~
+#                      |-~~-_/ |    |   ~\_   _-~            /\
+#                           /  \     \__   \/~                \__
+#                       _--~ _/ | .-~~____--~-/                  ~~==.
+#                      ((->/~   '.|||' -_|    ~~-/ ,              . _||
+#                                 -_     ~\      ~~---l__i__i__i--~~_/
+#                                 _-~-__   ~)  \--______________--~~
+#                               //.-~~~-~_--~- |-------~~~~~~~~
+#                                      //.-~~~--\
+#                  神兽保佑
+#                  永无BUG!
+*/
+package com.lunhan.water.entity.request.heartbeatdata;
+
+import lombok.Data;
+
+/**
+ * HeartbeatData
+ * @author lin.liu
+ */
+@Data
+public class ReqCreateHeartbeatData {
+	/**
+	 * null
+	 */
+	private String dataKey;
+	/**
+	 * null
+	 */
+	private Integer dataValue;
+	/**
+	 * null
+	 */
+	private String remark;
+}
diff --git a/src/main/java/com/lunhan/water/entity/request/heartbeatdata/ReqModifyHeartbeatData.java b/src/main/java/com/lunhan/water/entity/request/heartbeatdata/ReqModifyHeartbeatData.java
new file mode 100644
index 0000000..136b6f0
--- /dev/null
+++ b/src/main/java/com/lunhan/water/entity/request/heartbeatdata/ReqModifyHeartbeatData.java
@@ -0,0 +1,49 @@
+/**
+#                                                    __----~~~~~~~~~~~------___
+#                                   .  .   ~~//====......          __--~ ~~
+#                   -.            \_|//     |||\\  ~~~~~~::::... /~
+#                ___-==_       _-~o~  \/    |||  \\            _/~~-
+#        __---~~~.==~||\=_    -_--~/_-~|-   |\\   \\        _/~
+#    _-~~     .=~    |  \\-_    '-~7  /-   /  ||    \      /
+#  .~       .~       |   \\ -_    /  /-   /   ||      \   /
+# /  ____  /         |     \\ ~-_/  /|- _/   .||       \ /
+# |~~    ~~|--~~~~--_ \     ~==-/   | \~--===~~        .\
+#          '         ~-|      /|    |-~\~~       __--~~
+#                      |-~~-_/ |    |   ~\_   _-~            /\
+#                           /  \     \__   \/~                \__
+#                       _--~ _/ | .-~~____--~-/                  ~~==.
+#                      ((->/~   '.|||' -_|    ~~-/ ,              . _||
+#                                 -_     ~\      ~~---l__i__i__i--~~_/
+#                                 _-~-__   ~)  \--______________--~~
+#                               //.-~~~-~_--~- |-------~~~~~~~~
+#                                      //.-~~~--\
+#                  神兽保佑
+#                  永无BUG!
+*/
+package com.lunhan.water.entity.request.heartbeatdata;
+
+import lombok.Data;
+
+/**
+ * HeartbeatData
+ * @author lin.liu
+ */
+@Data
+public class ReqModifyHeartbeatData {
+	/**
+	 * null
+	 */
+	private Long id;
+	/**
+	 * null
+	 */
+	private String dataKey;
+	/**
+	 * null
+	 */
+	private Integer dataValue;
+	/**
+	 * null
+	 */
+	private String remark;
+}
diff --git a/src/main/java/com/lunhan/water/entity/request/pay/ReqCreatePay.java b/src/main/java/com/lunhan/water/entity/request/pay/ReqCreatePay.java
index 2d562bf..f5f9ba1 100644
--- a/src/main/java/com/lunhan/water/entity/request/pay/ReqCreatePay.java
+++ b/src/main/java/com/lunhan/water/entity/request/pay/ReqCreatePay.java
@@ -29,7 +29,7 @@
     private String businessComment;
 
     /**
-     * 设备编号
+     * 验证支付的临时token
      */
-    private String facilityCode;
+    private String payToken;
 }
diff --git a/src/main/java/com/lunhan/water/entity/request/paymentrecords/ReqBuyWater.java b/src/main/java/com/lunhan/water/entity/request/paymentrecords/ReqBuyWater.java
new file mode 100644
index 0000000..17d213c
--- /dev/null
+++ b/src/main/java/com/lunhan/water/entity/request/paymentrecords/ReqBuyWater.java
@@ -0,0 +1,11 @@
+package com.lunhan.water.entity.request.paymentrecords;
+
+import lombok.Data;
+
+import java.math.BigDecimal;
+
+@Data
+public class ReqBuyWater {
+    private Long facilityId;
+    private BigDecimal amount;
+}
diff --git a/src/main/java/com/lunhan/water/entity/request/thirdnotify/ReqCreateThirdNotify.java b/src/main/java/com/lunhan/water/entity/request/thirdnotify/ReqCreateThirdNotify.java
new file mode 100644
index 0000000..7f543a2
--- /dev/null
+++ b/src/main/java/com/lunhan/water/entity/request/thirdnotify/ReqCreateThirdNotify.java
@@ -0,0 +1,65 @@
+/**
+#                                                    __----~~~~~~~~~~~------___
+#                                   .  .   ~~//====......          __--~ ~~
+#                   -.            \_|//     |||\\  ~~~~~~::::... /~
+#                ___-==_       _-~o~  \/    |||  \\            _/~~-
+#        __---~~~.==~||\=_    -_--~/_-~|-   |\\   \\        _/~
+#    _-~~     .=~    |  \\-_    '-~7  /-   /  ||    \      /
+#  .~       .~       |   \\ -_    /  /-   /   ||      \   /
+# /  ____  /         |     \\ ~-_/  /|- _/   .||       \ /
+# |~~    ~~|--~~~~--_ \     ~==-/   | \~--===~~        .\
+#          '         ~-|      /|    |-~\~~       __--~~
+#                      |-~~-_/ |    |   ~\_   _-~            /\
+#                           /  \     \__   \/~                \__
+#                       _--~ _/ | .-~~____--~-/                  ~~==.
+#                      ((->/~   '.|||' -_|    ~~-/ ,              . _||
+#                                 -_     ~\      ~~---l__i__i__i--~~_/
+#                                 _-~-__   ~)  \--______________--~~
+#                               //.-~~~-~_--~- |-------~~~~~~~~
+#                                      //.-~~~--\
+#                  神兽保佑
+#                  永无BUG!
+*/
+package com.lunhan.water.entity.request.thirdnotify;
+
+import lombok.Data;
+
+/**
+ * 第三方支付通知记录
+ * @author lin.liu
+ */
+@Data
+public class ReqCreateThirdNotify {
+	/**
+	 * 业务
+	 */
+	private String business;
+	/**
+	 * 业务类型 EBusinessType
+	 */
+	private Integer businessType;
+	/**
+	 * 业务编号
+	 */
+	private String businessCode;
+	/**
+	 * 支付渠道
+	 */
+	private Integer paymentChannel;
+	/**
+	 * 支付渠道名称
+	 */
+	private String channelName;
+	/**
+	 * 通知报文md5
+	 */
+	private String md5;
+	/**
+	 * 通知报文
+	 */
+	private String body;
+	/**
+	 * 备注
+	 */
+	private String comment;
+}
diff --git a/src/main/java/com/lunhan/water/entity/request/thirdnotify/ReqModifyThirdNotify.java b/src/main/java/com/lunhan/water/entity/request/thirdnotify/ReqModifyThirdNotify.java
new file mode 100644
index 0000000..527c66b
--- /dev/null
+++ b/src/main/java/com/lunhan/water/entity/request/thirdnotify/ReqModifyThirdNotify.java
@@ -0,0 +1,73 @@
+/**
+#                                                    __----~~~~~~~~~~~------___
+#                                   .  .   ~~//====......          __--~ ~~
+#                   -.            \_|//     |||\\  ~~~~~~::::... /~
+#                ___-==_       _-~o~  \/    |||  \\            _/~~-
+#        __---~~~.==~||\=_    -_--~/_-~|-   |\\   \\        _/~
+#    _-~~     .=~    |  \\-_    '-~7  /-   /  ||    \      /
+#  .~       .~       |   \\ -_    /  /-   /   ||      \   /
+# /  ____  /         |     \\ ~-_/  /|- _/   .||       \ /
+# |~~    ~~|--~~~~--_ \     ~==-/   | \~--===~~        .\
+#          '         ~-|      /|    |-~\~~       __--~~
+#                      |-~~-_/ |    |   ~\_   _-~            /\
+#                           /  \     \__   \/~                \__
+#                       _--~ _/ | .-~~____--~-/                  ~~==.
+#                      ((->/~   '.|||' -_|    ~~-/ ,              . _||
+#                                 -_     ~\      ~~---l__i__i__i--~~_/
+#                                 _-~-__   ~)  \--______________--~~
+#                               //.-~~~-~_--~- |-------~~~~~~~~
+#                                      //.-~~~--\
+#                  神兽保佑
+#                  永无BUG!
+*/
+package com.lunhan.water.entity.request.thirdnotify;
+
+import lombok.Data;
+
+/**
+ * 第三方支付通知记录
+ * @author lin.liu
+ */
+@Data
+public class ReqModifyThirdNotify {
+	/**
+	 * 自增id
+	 */
+	private Long id;
+	/**
+	 * 业务
+	 */
+	private String business;
+	/**
+	 * 业务类型 EBusinessType
+	 */
+	private Integer businessType;
+	/**
+	 * 业务编号
+	 */
+	private String businessCode;
+	/**
+	 * 支付渠道
+	 */
+	private Integer paymentChannel;
+	/**
+	 * 支付渠道名称
+	 */
+	private String channelName;
+	/**
+	 * 通知报文md5
+	 */
+	private String md5;
+	/**
+	 * 通知报文
+	 */
+	private String body;
+	/**
+	 * 备注
+	 */
+	private String comment;
+	/**
+	 * 状态(EPayNotifyState) 待处理=0,成功=1,失败=2
+	 */
+	private Integer status;
+}
diff --git a/src/main/java/com/lunhan/water/entity/request/userlogin/ReqCreateUserLogin.java b/src/main/java/com/lunhan/water/entity/request/userlogin/ReqCreateUserLogin.java
index 60066bf..92b374e 100644
--- a/src/main/java/com/lunhan/water/entity/request/userlogin/ReqCreateUserLogin.java
+++ b/src/main/java/com/lunhan/water/entity/request/userlogin/ReqCreateUserLogin.java
@@ -62,4 +62,6 @@
 	 * 备注
 	 */
 	private String comment;
+
+	private String userCode;
 }
diff --git a/src/main/java/com/lunhan/water/entity/request/waterfacility/ReqCreateWaterFacility.java b/src/main/java/com/lunhan/water/entity/request/waterfacility/ReqCreateWaterFacility.java
new file mode 100644
index 0000000..7c97338
--- /dev/null
+++ b/src/main/java/com/lunhan/water/entity/request/waterfacility/ReqCreateWaterFacility.java
@@ -0,0 +1,106 @@
+/**
+#                                                    __----~~~~~~~~~~~------___
+#                                   .  .   ~~//====......          __--~ ~~
+#                   -.            \_|//     |||\\  ~~~~~~::::... /~
+#                ___-==_       _-~o~  \/    |||  \\            _/~~-
+#        __---~~~.==~||\=_    -_--~/_-~|-   |\\   \\        _/~
+#    _-~~     .=~    |  \\-_    '-~7  /-   /  ||    \      /
+#  .~       .~       |   \\ -_    /  /-   /   ||      \   /
+# /  ____  /         |     \\ ~-_/  /|- _/   .||       \ /
+# |~~    ~~|--~~~~--_ \     ~==-/   | \~--===~~        .\
+#          '         ~-|      /|    |-~\~~       __--~~
+#                      |-~~-_/ |    |   ~\_   _-~            /\
+#                           /  \     \__   \/~                \__
+#                       _--~ _/ | .-~~____--~-/                  ~~==.
+#                      ((->/~   '.|||' -_|    ~~-/ ,              . _||
+#                                 -_     ~\      ~~---l__i__i__i--~~_/
+#                                 _-~-__   ~)  \--______________--~~
+#                               //.-~~~-~_--~- |-------~~~~~~~~
+#                                      //.-~~~--\
+#                  神兽保佑
+#                  永无BUG!
+*/
+package com.lunhan.water.entity.request.waterfacility;
+
+import lombok.Data;
+import java.math.BigDecimal;
+
+/**
+ * 设备表
+ * @author lin.liu
+ */
+@Data
+public class ReqCreateWaterFacility {
+	/**
+	 * 设备名称
+	 */
+	private String facilityName;
+	/**
+	 * 设备编号
+	 */
+	private String facilityCode;
+	/**
+	 * 经度
+	 */
+	private BigDecimal longitude;
+	/**
+	 * 纬度
+	 */
+	private BigDecimal latitude;
+	/**
+	 * 售水站点id
+	 */
+	private Long siteId;
+	/**
+	 * 1:在线 0:下线
+	 */
+	private Integer onLineState;
+	/**
+	 * 网络类型
+	 */
+	private String networkType;
+	/**
+	 * 地址
+	 */
+	private String address;
+	/**
+	 * 备注
+	 */
+	private String remark;
+	/**
+	 * 设备图片
+	 */
+	private String facilityUrl;
+	/**
+	 * 设备供应商
+	 */
+	private String supplier;
+	/**
+	 * 安装日期
+	 */
+	private String installDate;
+	/**
+	 * 售水开关(1开 2关)
+	 */
+	private Integer saleOpen;
+	/**
+	 * 制水开关(1开 2关)
+	 */
+	private Integer productionOpen;
+	/**
+	 * 温控开关(1开 2关)
+	 */
+	private Integer temperatureOpen;
+	/**
+	 * 信号值
+	 */
+	private Integer signalValue;
+	/**
+	 * 所属区域id
+	 */
+	private Long areaId;
+	/**
+	 * null
+	 */
+	private Integer facilityType;
+}
diff --git a/src/main/java/com/lunhan/water/entity/request/waterfacility/ReqModifyWaterFacility.java b/src/main/java/com/lunhan/water/entity/request/waterfacility/ReqModifyWaterFacility.java
new file mode 100644
index 0000000..e3248f4
--- /dev/null
+++ b/src/main/java/com/lunhan/water/entity/request/waterfacility/ReqModifyWaterFacility.java
@@ -0,0 +1,114 @@
+/**
+#                                                    __----~~~~~~~~~~~------___
+#                                   .  .   ~~//====......          __--~ ~~
+#                   -.            \_|//     |||\\  ~~~~~~::::... /~
+#                ___-==_       _-~o~  \/    |||  \\            _/~~-
+#        __---~~~.==~||\=_    -_--~/_-~|-   |\\   \\        _/~
+#    _-~~     .=~    |  \\-_    '-~7  /-   /  ||    \      /
+#  .~       .~       |   \\ -_    /  /-   /   ||      \   /
+# /  ____  /         |     \\ ~-_/  /|- _/   .||       \ /
+# |~~    ~~|--~~~~--_ \     ~==-/   | \~--===~~        .\
+#          '         ~-|      /|    |-~\~~       __--~~
+#                      |-~~-_/ |    |   ~\_   _-~            /\
+#                           /  \     \__   \/~                \__
+#                       _--~ _/ | .-~~____--~-/                  ~~==.
+#                      ((->/~   '.|||' -_|    ~~-/ ,              . _||
+#                                 -_     ~\      ~~---l__i__i__i--~~_/
+#                                 _-~-__   ~)  \--______________--~~
+#                               //.-~~~-~_--~- |-------~~~~~~~~
+#                                      //.-~~~--\
+#                  神兽保佑
+#                  永无BUG!
+*/
+package com.lunhan.water.entity.request.waterfacility;
+
+import lombok.Data;
+import java.math.BigDecimal;
+
+/**
+ * 设备表
+ * @author lin.liu
+ */
+@Data
+public class ReqModifyWaterFacility {
+	/**
+	 * null
+	 */
+	private Long id;
+	/**
+	 * 设备名称
+	 */
+	private String facilityName;
+	/**
+	 * 设备编号
+	 */
+	private String facilityCode;
+	/**
+	 * 经度
+	 */
+	private BigDecimal longitude;
+	/**
+	 * 纬度
+	 */
+	private BigDecimal latitude;
+	/**
+	 * 售水站点id
+	 */
+	private Long siteId;
+	/**
+	 * 1:在线 0:下线
+	 */
+	private Integer onLineState;
+	/**
+	 * 网络类型
+	 */
+	private String networkType;
+	/**
+	 * 地址
+	 */
+	private String address;
+	/**
+	 * 备注
+	 */
+	private String remark;
+	/**
+	 * 设备图片
+	 */
+	private String facilityUrl;
+	/**
+	 * 设备供应商
+	 */
+	private String supplier;
+	/**
+	 * 安装日期
+	 */
+	private String installDate;
+	/**
+	 * 售水开关(1开 2关)
+	 */
+	private Integer saleOpen;
+	/**
+	 * 制水开关(1开 2关)
+	 */
+	private Integer productionOpen;
+	/**
+	 * 温控开关(1开 2关)
+	 */
+	private Integer temperatureOpen;
+	/**
+	 * 信号值
+	 */
+	private Integer signalValue;
+	/**
+	 * 所属区域id
+	 */
+	private Long areaId;
+	/**
+	 * 设备状态(1正常 2故障)
+	 */
+	private Integer state;
+	/**
+	 * null
+	 */
+	private Integer facilityType;
+}
diff --git a/src/main/java/com/lunhan/water/entity/response/pay/ResWeiXinPayNotify.java b/src/main/java/com/lunhan/water/entity/response/pay/ResWeiXinPayNotify.java
new file mode 100644
index 0000000..e56fb1b
--- /dev/null
+++ b/src/main/java/com/lunhan/water/entity/response/pay/ResWeiXinPayNotify.java
@@ -0,0 +1,27 @@
+package com.lunhan.water.entity.response.pay;
+
+public class ResWeiXinPayNotify {
+    private String code;
+    private String message;
+
+    public String getCode() {
+        return code;
+    }
+
+    public void setCode(String code) {
+        this.code = code;
+    }
+
+    public String getMessage() {
+        return message;
+    }
+
+    public void setMessage(String message) {
+        this.message = message;
+    }
+
+    public ResWeiXinPayNotify(String code, String message) {
+        this.code = code;
+        this.message = message;
+    }
+}
diff --git a/src/main/java/com/lunhan/water/entity/search/SearchFacilityAlarmRecord.java b/src/main/java/com/lunhan/water/entity/search/SearchFacilityAlarmRecord.java
new file mode 100644
index 0000000..e3a8925
--- /dev/null
+++ b/src/main/java/com/lunhan/water/entity/search/SearchFacilityAlarmRecord.java
@@ -0,0 +1,14 @@
+package com.lunhan.water.entity.search;
+
+import lombok.Data;
+
+import com.lunhan.water.entity.dto.SearchBasicDTO;
+
+/**
+ * 设备报警记录
+ * @author lin.liu
+ */
+@Data
+public class SearchFacilityAlarmRecord extends SearchBasicDTO {
+
+}
diff --git a/src/main/java/com/lunhan/water/entity/search/SearchHeartbeatData.java b/src/main/java/com/lunhan/water/entity/search/SearchHeartbeatData.java
new file mode 100644
index 0000000..5b6d149
--- /dev/null
+++ b/src/main/java/com/lunhan/water/entity/search/SearchHeartbeatData.java
@@ -0,0 +1,14 @@
+package com.lunhan.water.entity.search;
+
+import lombok.Data;
+
+import com.lunhan.water.entity.dto.SearchBasicDTO;
+
+/**
+ * HeartbeatData
+ * @author lin.liu
+ */
+@Data
+public class SearchHeartbeatData extends SearchBasicDTO {
+
+}
diff --git a/src/main/java/com/lunhan/water/entity/search/SearchPaymentRecords.java b/src/main/java/com/lunhan/water/entity/search/SearchPaymentRecords.java
index 63408e6..f40627e 100644
--- a/src/main/java/com/lunhan/water/entity/search/SearchPaymentRecords.java
+++ b/src/main/java/com/lunhan/water/entity/search/SearchPaymentRecords.java
@@ -10,5 +10,13 @@
  */
 @Data
 public class SearchPaymentRecords extends SearchBasicDTO {
+    /**
+     * 日期筛选类型(1当日 2本周 3本月 4本年)
+     */
+    private  Integer dateType;
+    /**
+     * 用户id
+     */
+    private  Long userId;
 
 }
diff --git a/src/main/java/com/lunhan/water/entity/search/SearchRechargeRecords.java b/src/main/java/com/lunhan/water/entity/search/SearchRechargeRecords.java
index 46dd447..4ee60cd 100644
--- a/src/main/java/com/lunhan/water/entity/search/SearchRechargeRecords.java
+++ b/src/main/java/com/lunhan/water/entity/search/SearchRechargeRecords.java
@@ -10,5 +10,12 @@
  */
 @Data
 public class SearchRechargeRecords extends SearchBasicDTO {
-
+    /**
+     * 日期筛选类型(1当日 2本周 3本月 4本年)
+     */
+    private  Integer dateType;
+    /**
+     * 用户id
+     */
+    private  Long userId;
 }
diff --git a/src/main/java/com/lunhan/water/entity/search/SearchThirdNotify.java b/src/main/java/com/lunhan/water/entity/search/SearchThirdNotify.java
new file mode 100644
index 0000000..7c5e925
--- /dev/null
+++ b/src/main/java/com/lunhan/water/entity/search/SearchThirdNotify.java
@@ -0,0 +1,14 @@
+package com.lunhan.water.entity.search;
+
+import lombok.Data;
+
+import com.lunhan.water.entity.dto.SearchBasicDTO;
+
+/**
+ * 第三方支付通知记录
+ * @author lin.liu
+ */
+@Data
+public class SearchThirdNotify extends SearchBasicDTO {
+
+}
diff --git a/src/main/java/com/lunhan/water/entity/search/SearchWaterFacility.java b/src/main/java/com/lunhan/water/entity/search/SearchWaterFacility.java
new file mode 100644
index 0000000..c9b272d
--- /dev/null
+++ b/src/main/java/com/lunhan/water/entity/search/SearchWaterFacility.java
@@ -0,0 +1,23 @@
+package com.lunhan.water.entity.search;
+
+import lombok.Data;
+
+import com.lunhan.water.entity.dto.SearchBasicDTO;
+
+import java.math.BigDecimal;
+
+/**
+ * 设备表
+ * @author lin.liu
+ */
+@Data
+public class SearchWaterFacility extends SearchBasicDTO {
+    /**
+     * 经度
+     */
+    private BigDecimal longitude;
+    /**
+     * 纬度
+     */
+    private BigDecimal latitude;
+}
diff --git a/src/main/java/com/lunhan/water/host/controller/FacilityAlarmRecordController.java b/src/main/java/com/lunhan/water/host/controller/FacilityAlarmRecordController.java
new file mode 100644
index 0000000..2002bf9
--- /dev/null
+++ b/src/main/java/com/lunhan/water/host/controller/FacilityAlarmRecordController.java
@@ -0,0 +1,113 @@
+/**
+#                                                    __----~~~~~~~~~~~------___
+#                                   .  .   ~~//====......          __--~ ~~
+#                   -.            \_|//     |||\\  ~~~~~~::::... /~
+#                ___-==_       _-~o~  \/    |||  \\            _/~~-
+#        __---~~~.==~||\=_    -_--~/_-~|-   |\\   \\        _/~
+#    _-~~     .=~    |  \\-_    '-~7  /-   /  ||    \      /
+#  .~       .~       |   \\ -_    /  /-   /   ||      \   /
+# /  ____  /         |     \\ ~-_/  /|- _/   .||       \ /
+# |~~    ~~|--~~~~--_ \     ~==-/   | \~--===~~        .\
+#          '         ~-|      /|    |-~\~~       __--~~
+#                      |-~~-_/ |    |   ~\_   _-~            /\
+#                           /  \     \__   \/~                \__
+#                       _--~ _/ | .-~~____--~-/                  ~~==.
+#                      ((->/~   '.|||' -_|    ~~-/ ,              . _||
+#                                 -_     ~\      ~~---l__i__i__i--~~_/
+#                                 _-~-__   ~)  \--______________--~~
+#                               //.-~~~-~_--~- |-------~~~~~~~~
+#                                      //.-~~~--\
+#                  神兽保佑
+#                  永无BUG!
+*/
+package com.lunhan.water.host.controller;
+
+import com.lunhan.water.common.ExecutedResult;
+import com.lunhan.water.common.PagerResult;
+import com.lunhan.water.common.util.ParameterUtil;
+import com.lunhan.water.common.validator.ParameterValidateResult;
+import com.lunhan.water.common.validator.ParameterValidator;
+import com.lunhan.water.entity.request.ReqListId;
+import com.lunhan.water.host.BasicController;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+import java.util.List;
+import com.lunhan.water.service.FacilityAlarmRecordService;
+import com.lunhan.water.entity.request.facilityalarmrecord.ReqCreateFacilityAlarmRecord;
+import com.lunhan.water.entity.request.facilityalarmrecord.ReqModifyFacilityAlarmRecord;
+import com.lunhan.water.entity.search.SearchFacilityAlarmRecord;
+import com.lunhan.water.repository.vo.FacilityAlarmRecordVO;
+
+/**
+ * 9000.设备报警记录
+ * @author lin.liu
+ * @order 9000
+ */
+@RestController
+@RequestMapping(value = "facilityAlarmRecord")
+public class FacilityAlarmRecordController extends BasicController {
+    @Autowired
+    private FacilityAlarmRecordService service;
+
+    /**
+     * 创建[设备报警记录]
+     * @author lin.liu
+     */
+    @PostMapping(value = "create")
+    public ExecutedResult<Long> create(@RequestBody ReqCreateFacilityAlarmRecord request) {
+        //#region 参数验证
+        ParameterValidator validator = new ParameterValidator()
+                // 非空
+                //.addNotNullOrEmpty(ParameterUtil.named("名称"), request.getName())
+                // 限制最大长度
+                //.addLengthMax(ParameterUtil.named("名称"), request.getName(), ConstantFactory.LENGTH_MAX50)
+                ;
+        ParameterValidateResult result = validator.validate();
+        if (result.getIsFiled()) {
+            return failed(result.getErrorMsg());
+        }
+        //#endregion
+        return service.create(request);
+    }
+
+    /**
+     * 编辑[设备报警记录]
+     * @author lin.liu
+     */
+    @PostMapping(value = "modify")
+    public ExecutedResult<String> modify(@RequestBody ReqModifyFacilityAlarmRecord request) {
+        //#region 参数验证
+        ParameterValidator validator = new ParameterValidator()
+                // 必须大于0
+                .addGreater(ParameterUtil.named("[设备报警记录]id"), request.getId(), 0L)
+                // 非空
+                //.addNotNullOrEmpty(ParameterUtil.named("名称"), request.getName())
+                // 限制最大长度
+                //.addLengthMax(ParameterUtil.named("名称"), request.getName(), ConstantFactory.LENGTH_MAX50)
+                ;
+        ParameterValidateResult result = validator.validate();
+        if (result.getIsFiled()) {
+            return failed(result.getErrorMsg());
+        }
+        //#endregion
+        return service.modify(request);
+    }
+
+    /**
+     * 获取[设备报警记录]
+     * @author lin.liu
+     */
+    @GetMapping(value = "get/{id}")
+    public ExecutedResult<FacilityAlarmRecordVO> get(@PathVariable Long id) {
+        return service.get(id);
+    }
+
+    /**
+     * 查询[设备报警记录]
+     * @author lin.liu
+     */
+    @PostMapping(value = "search")
+    public ExecutedResult<PagerResult<FacilityAlarmRecordVO>> search(@RequestBody SearchFacilityAlarmRecord request) {
+        return service.search(request);
+    }
+}
diff --git a/src/main/java/com/lunhan/water/host/controller/HeartbeatDataController.java b/src/main/java/com/lunhan/water/host/controller/HeartbeatDataController.java
new file mode 100644
index 0000000..b8e0bd5
--- /dev/null
+++ b/src/main/java/com/lunhan/water/host/controller/HeartbeatDataController.java
@@ -0,0 +1,113 @@
+/**
+#                                                    __----~~~~~~~~~~~------___
+#                                   .  .   ~~//====......          __--~ ~~
+#                   -.            \_|//     |||\\  ~~~~~~::::... /~
+#                ___-==_       _-~o~  \/    |||  \\            _/~~-
+#        __---~~~.==~||\=_    -_--~/_-~|-   |\\   \\        _/~
+#    _-~~     .=~    |  \\-_    '-~7  /-   /  ||    \      /
+#  .~       .~       |   \\ -_    /  /-   /   ||      \   /
+# /  ____  /         |     \\ ~-_/  /|- _/   .||       \ /
+# |~~    ~~|--~~~~--_ \     ~==-/   | \~--===~~        .\
+#          '         ~-|      /|    |-~\~~       __--~~
+#                      |-~~-_/ |    |   ~\_   _-~            /\
+#                           /  \     \__   \/~                \__
+#                       _--~ _/ | .-~~____--~-/                  ~~==.
+#                      ((->/~   '.|||' -_|    ~~-/ ,              . _||
+#                                 -_     ~\      ~~---l__i__i__i--~~_/
+#                                 _-~-__   ~)  \--______________--~~
+#                               //.-~~~-~_--~- |-------~~~~~~~~
+#                                      //.-~~~--\
+#                  神兽保佑
+#                  永无BUG!
+*/
+package com.lunhan.water.host.controller;
+
+import com.lunhan.water.common.ExecutedResult;
+import com.lunhan.water.common.PagerResult;
+import com.lunhan.water.common.util.ParameterUtil;
+import com.lunhan.water.common.validator.ParameterValidateResult;
+import com.lunhan.water.common.validator.ParameterValidator;
+import com.lunhan.water.entity.request.ReqListId;
+import com.lunhan.water.host.BasicController;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+import java.util.List;
+import com.lunhan.water.service.HeartbeatDataService;
+import com.lunhan.water.entity.request.heartbeatdata.ReqCreateHeartbeatData;
+import com.lunhan.water.entity.request.heartbeatdata.ReqModifyHeartbeatData;
+import com.lunhan.water.entity.search.SearchHeartbeatData;
+import com.lunhan.water.repository.vo.HeartbeatDataVO;
+
+/**
+ * 9000.HeartbeatData
+ * @author lin.liu
+ * @order 9000
+ */
+@RestController
+@RequestMapping(value = "heartbeatData")
+public class HeartbeatDataController extends BasicController {
+    @Autowired
+    private HeartbeatDataService service;
+
+    /**
+     * 创建[null]
+     * @author lin.liu
+     */
+    @PostMapping(value = "create")
+    public ExecutedResult<Long> create(@RequestBody ReqCreateHeartbeatData request) {
+        //#region 参数验证
+        ParameterValidator validator = new ParameterValidator()
+                // 非空
+                //.addNotNullOrEmpty(ParameterUtil.named("名称"), request.getName())
+                // 限制最大长度
+                //.addLengthMax(ParameterUtil.named("名称"), request.getName(), ConstantFactory.LENGTH_MAX50)
+                ;
+        ParameterValidateResult result = validator.validate();
+        if (result.getIsFiled()) {
+            return failed(result.getErrorMsg());
+        }
+        //#endregion
+        return service.create(request);
+    }
+
+    /**
+     * 编辑[null]
+     * @author lin.liu
+     */
+    @PostMapping(value = "modify")
+    public ExecutedResult<String> modify(@RequestBody ReqModifyHeartbeatData request) {
+        //#region 参数验证
+        ParameterValidator validator = new ParameterValidator()
+                // 必须大于0
+                .addGreater(ParameterUtil.named("[null]id"), request.getId(), 0L)
+                // 非空
+                //.addNotNullOrEmpty(ParameterUtil.named("名称"), request.getName())
+                // 限制最大长度
+                //.addLengthMax(ParameterUtil.named("名称"), request.getName(), ConstantFactory.LENGTH_MAX50)
+                ;
+        ParameterValidateResult result = validator.validate();
+        if (result.getIsFiled()) {
+            return failed(result.getErrorMsg());
+        }
+        //#endregion
+        return service.modify(request);
+    }
+
+    /**
+     * 获取[null]
+     * @author lin.liu
+     */
+    @GetMapping(value = "get/{id}")
+    public ExecutedResult<HeartbeatDataVO> get(@PathVariable Long id) {
+        return service.get(id);
+    }
+
+    /**
+     * 查询[null]
+     * @author lin.liu
+     */
+    @PostMapping(value = "search")
+    public ExecutedResult<PagerResult<HeartbeatDataVO>> search(@RequestBody SearchHeartbeatData request) {
+        return service.search(request);
+    }
+}
diff --git a/src/main/java/com/lunhan/water/host/controller/PaymentRecordsController.java b/src/main/java/com/lunhan/water/host/controller/PaymentRecordsController.java
index c82a11d..405b388 100644
--- a/src/main/java/com/lunhan/water/host/controller/PaymentRecordsController.java
+++ b/src/main/java/com/lunhan/water/host/controller/PaymentRecordsController.java
@@ -39,7 +39,7 @@
 import com.lunhan.water.repository.vo.PaymentRecordsVO;
 
 /**
- * 9000.PaymentRecords
+ * 9000.消费记录
  * @author lin.liu
  * @order 9000
  */
@@ -50,7 +50,7 @@
     private PaymentRecordsService service;
 
     /**
-     * 创建[null]
+     * 创建[消费记录]
      * @author lin.liu
      */
     @PostMapping(value = "create")
@@ -71,7 +71,7 @@
     }
 
     /**
-     * 编辑[null]
+     * 编辑[消费记录]
      * @author lin.liu
      */
     @PostMapping(value = "modify")
@@ -94,7 +94,7 @@
     }
 
     /**
-     * 获取[null]
+     * 获取[消费记录]
      * @author lin.liu
      */
     @GetMapping(value = "get/{id}")
@@ -103,7 +103,7 @@
     }
 
     /**
-     * 查询[null]
+     * 查询[消费记录]
      * @author lin.liu
      */
     @PostMapping(value = "search")
diff --git a/src/main/java/com/lunhan/water/host/controller/RechargeOrderController.java b/src/main/java/com/lunhan/water/host/controller/RechargeOrderController.java
index 129ec75..2d4bd44 100644
--- a/src/main/java/com/lunhan/water/host/controller/RechargeOrderController.java
+++ b/src/main/java/com/lunhan/water/host/controller/RechargeOrderController.java
@@ -58,16 +58,14 @@
         //#region 参数验证
         ParameterValidator validator = new ParameterValidator()
                 // 非空
-                //.addNotNullOrEmpty(ParameterUtil.named("名称"), request.getName())
-                // 限制最大长度
-                //.addLengthMax(ParameterUtil.named("名称"), request.getName(), ConstantFactory.LENGTH_MAX50)
+                .addNotNullOrEmpty(ParameterUtil.named("订单金额"), request.getOrderAmount())
                 ;
         ParameterValidateResult result = validator.validate();
         if (result.getIsFiled()) {
             return failed(result.getErrorMsg());
         }
         //#endregion
-        return service.create(request);
+        return service.create(this.getTokenUser(),request);
     }
 
     /**
diff --git a/src/main/java/com/lunhan/water/host/controller/ThirdNotifyController.java b/src/main/java/com/lunhan/water/host/controller/ThirdNotifyController.java
new file mode 100644
index 0000000..6264e66
--- /dev/null
+++ b/src/main/java/com/lunhan/water/host/controller/ThirdNotifyController.java
@@ -0,0 +1,113 @@
+/**
+#                                                    __----~~~~~~~~~~~------___
+#                                   .  .   ~~//====......          __--~ ~~
+#                   -.            \_|//     |||\\  ~~~~~~::::... /~
+#                ___-==_       _-~o~  \/    |||  \\            _/~~-
+#        __---~~~.==~||\=_    -_--~/_-~|-   |\\   \\        _/~
+#    _-~~     .=~    |  \\-_    '-~7  /-   /  ||    \      /
+#  .~       .~       |   \\ -_    /  /-   /   ||      \   /
+# /  ____  /         |     \\ ~-_/  /|- _/   .||       \ /
+# |~~    ~~|--~~~~--_ \     ~==-/   | \~--===~~        .\
+#          '         ~-|      /|    |-~\~~       __--~~
+#                      |-~~-_/ |    |   ~\_   _-~            /\
+#                           /  \     \__   \/~                \__
+#                       _--~ _/ | .-~~____--~-/                  ~~==.
+#                      ((->/~   '.|||' -_|    ~~-/ ,              . _||
+#                                 -_     ~\      ~~---l__i__i__i--~~_/
+#                                 _-~-__   ~)  \--______________--~~
+#                               //.-~~~-~_--~- |-------~~~~~~~~
+#                                      //.-~~~--\
+#                  神兽保佑
+#                  永无BUG!
+*/
+package com.lunhan.water.host.controller;
+
+import com.lunhan.water.common.ExecutedResult;
+import com.lunhan.water.common.PagerResult;
+import com.lunhan.water.common.util.ParameterUtil;
+import com.lunhan.water.common.validator.ParameterValidateResult;
+import com.lunhan.water.common.validator.ParameterValidator;
+import com.lunhan.water.entity.request.ReqListId;
+import com.lunhan.water.host.BasicController;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+import java.util.List;
+import com.lunhan.water.service.ThirdNotifyService;
+import com.lunhan.water.entity.request.thirdnotify.ReqCreateThirdNotify;
+import com.lunhan.water.entity.request.thirdnotify.ReqModifyThirdNotify;
+import com.lunhan.water.entity.search.SearchThirdNotify;
+import com.lunhan.water.repository.vo.ThirdNotifyVO;
+
+/**
+ * 9000.第三方支付通知记录
+ * @author lin.liu
+ * @order 9000
+ */
+@RestController
+@RequestMapping(value = "thirdNotify")
+public class ThirdNotifyController extends BasicController {
+    @Autowired
+    private ThirdNotifyService service;
+
+    /**
+     * 创建[第三方支付通知记录]
+     * @author lin.liu
+     */
+    @PostMapping(value = "create")
+    public ExecutedResult<Long> create(@RequestBody ReqCreateThirdNotify request) {
+        //#region 参数验证
+        ParameterValidator validator = new ParameterValidator()
+                // 非空
+                //.addNotNullOrEmpty(ParameterUtil.named("名称"), request.getName())
+                // 限制最大长度
+                //.addLengthMax(ParameterUtil.named("名称"), request.getName(), ConstantFactory.LENGTH_MAX50)
+                ;
+        ParameterValidateResult result = validator.validate();
+        if (result.getIsFiled()) {
+            return failed(result.getErrorMsg());
+        }
+        //#endregion
+        return service.create(request);
+    }
+
+    /**
+     * 编辑[第三方支付通知记录]
+     * @author lin.liu
+     */
+    @PostMapping(value = "modify")
+    public ExecutedResult<String> modify(@RequestBody ReqModifyThirdNotify request) {
+        //#region 参数验证
+        ParameterValidator validator = new ParameterValidator()
+                // 必须大于0
+                .addGreater(ParameterUtil.named("[第三方支付通知记录]id"), request.getId(), 0L)
+                // 非空
+                //.addNotNullOrEmpty(ParameterUtil.named("名称"), request.getName())
+                // 限制最大长度
+                //.addLengthMax(ParameterUtil.named("名称"), request.getName(), ConstantFactory.LENGTH_MAX50)
+                ;
+        ParameterValidateResult result = validator.validate();
+        if (result.getIsFiled()) {
+            return failed(result.getErrorMsg());
+        }
+        //#endregion
+        return service.modify(request);
+    }
+
+    /**
+     * 获取[第三方支付通知记录]
+     * @author lin.liu
+     */
+    @GetMapping(value = "get/{id}")
+    public ExecutedResult<ThirdNotifyVO> get(@PathVariable Long id) {
+        return service.get(id);
+    }
+
+    /**
+     * 查询[第三方支付通知记录]
+     * @author lin.liu
+     */
+    @PostMapping(value = "search")
+    public ExecutedResult<PagerResult<ThirdNotifyVO>> search(@RequestBody SearchThirdNotify request) {
+        return service.search(request);
+    }
+}
diff --git a/src/main/java/com/lunhan/water/host/controller/WaterFacilityController.java b/src/main/java/com/lunhan/water/host/controller/WaterFacilityController.java
new file mode 100644
index 0000000..483227b
--- /dev/null
+++ b/src/main/java/com/lunhan/water/host/controller/WaterFacilityController.java
@@ -0,0 +1,113 @@
+/**
+#                                                    __----~~~~~~~~~~~------___
+#                                   .  .   ~~//====......          __--~ ~~
+#                   -.            \_|//     |||\\  ~~~~~~::::... /~
+#                ___-==_       _-~o~  \/    |||  \\            _/~~-
+#        __---~~~.==~||\=_    -_--~/_-~|-   |\\   \\        _/~
+#    _-~~     .=~    |  \\-_    '-~7  /-   /  ||    \      /
+#  .~       .~       |   \\ -_    /  /-   /   ||      \   /
+# /  ____  /         |     \\ ~-_/  /|- _/   .||       \ /
+# |~~    ~~|--~~~~--_ \     ~==-/   | \~--===~~        .\
+#          '         ~-|      /|    |-~\~~       __--~~
+#                      |-~~-_/ |    |   ~\_   _-~            /\
+#                           /  \     \__   \/~                \__
+#                       _--~ _/ | .-~~____--~-/                  ~~==.
+#                      ((->/~   '.|||' -_|    ~~-/ ,              . _||
+#                                 -_     ~\      ~~---l__i__i__i--~~_/
+#                                 _-~-__   ~)  \--______________--~~
+#                               //.-~~~-~_--~- |-------~~~~~~~~
+#                                      //.-~~~--\
+#                  神兽保佑
+#                  永无BUG!
+*/
+package com.lunhan.water.host.controller;
+
+import com.lunhan.water.common.ExecutedResult;
+import com.lunhan.water.common.PagerResult;
+import com.lunhan.water.common.util.ParameterUtil;
+import com.lunhan.water.common.validator.ParameterValidateResult;
+import com.lunhan.water.common.validator.ParameterValidator;
+import com.lunhan.water.entity.request.ReqListId;
+import com.lunhan.water.host.BasicController;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+import java.util.List;
+import com.lunhan.water.service.WaterFacilityService;
+import com.lunhan.water.entity.request.waterfacility.ReqCreateWaterFacility;
+import com.lunhan.water.entity.request.waterfacility.ReqModifyWaterFacility;
+import com.lunhan.water.entity.search.SearchWaterFacility;
+import com.lunhan.water.repository.vo.WaterFacilityVO;
+
+/**
+ * 9000.设备表
+ * @author lin.liu
+ * @order 9000
+ */
+@RestController
+@RequestMapping(value = "waterFacility")
+public class WaterFacilityController extends BasicController {
+    @Autowired
+    private WaterFacilityService service;
+
+    /**
+     * 创建[设备表]
+     * @author lin.liu
+     */
+    @PostMapping(value = "create")
+    public ExecutedResult<Long> create(@RequestBody ReqCreateWaterFacility request) {
+        //#region 参数验证
+        ParameterValidator validator = new ParameterValidator()
+                // 非空
+                //.addNotNullOrEmpty(ParameterUtil.named("名称"), request.getName())
+                // 限制最大长度
+                //.addLengthMax(ParameterUtil.named("名称"), request.getName(), ConstantFactory.LENGTH_MAX50)
+                ;
+        ParameterValidateResult result = validator.validate();
+        if (result.getIsFiled()) {
+            return failed(result.getErrorMsg());
+        }
+        //#endregion
+        return service.create(request);
+    }
+
+    /**
+     * 编辑[设备表]
+     * @author lin.liu
+     */
+    @PostMapping(value = "modify")
+    public ExecutedResult<String> modify(@RequestBody ReqModifyWaterFacility request) {
+        //#region 参数验证
+        ParameterValidator validator = new ParameterValidator()
+                // 必须大于0
+                .addGreater(ParameterUtil.named("[设备表]id"), request.getId(), 0L)
+                // 非空
+                //.addNotNullOrEmpty(ParameterUtil.named("名称"), request.getName())
+                // 限制最大长度
+                //.addLengthMax(ParameterUtil.named("名称"), request.getName(), ConstantFactory.LENGTH_MAX50)
+                ;
+        ParameterValidateResult result = validator.validate();
+        if (result.getIsFiled()) {
+            return failed(result.getErrorMsg());
+        }
+        //#endregion
+        return service.modify(request);
+    }
+
+    /**
+     * 获取[设备表]
+     * @author lin.liu
+     */
+    @GetMapping(value = "get/{id}")
+    public ExecutedResult<WaterFacilityVO> get(@PathVariable Long id) {
+        return service.get(id);
+    }
+
+    /**
+     * 查询[设备表]
+     * @author lin.liu
+     */
+    @PostMapping(value = "search")
+    public ExecutedResult<PagerResult<WaterFacilityVO>> search(@RequestBody SearchWaterFacility request) {
+        return service.search(request);
+    }
+}
diff --git a/src/main/java/com/lunhan/water/host/controller/admin/AdminUserController.java b/src/main/java/com/lunhan/water/host/controller/admin/AdminUserController.java
index c1ed422..a015047 100644
--- a/src/main/java/com/lunhan/water/host/controller/admin/AdminUserController.java
+++ b/src/main/java/com/lunhan/water/host/controller/admin/AdminUserController.java
@@ -1,5 +1,6 @@
 package com.lunhan.water.host.controller.admin;
 
+import com.lunhan.water.common.util.IPUtils;
 import com.lunhan.water.host.BasicController;
 import com.lunhan.water.host.api.MustAdmin;
 import com.lunhan.water.host.api.NonLogin;
@@ -25,6 +26,8 @@
 import com.lunhan.water.service.dto.ResAdminDetail;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.*;
+
+import javax.servlet.http.HttpServletRequest;
 
 /**
  * 40.管理员用户相关接口
@@ -116,7 +119,31 @@
         //#endregion
         return service.detail(userId);
     }
-
+    /**
+     * 获取登录设备ip地址
+     *
+     * @param request 获取登录设备ip地址
+     * @author lin.liu
+     * @date 2023/02/17
+     */
+    @GetMapping("/getIpAddress")
+    @NonLogin
+    public ExecutedResult<String> getIpAddress(HttpServletRequest request) {
+        return ExecutedResult.success(IPUtils.getIpAddress(request));
+    }
+    /**
+     * 保存前端登录验证码
+     *
+     * @param uuid 请求参数
+     * @author lin.liu
+     * @date 2023/02/17
+     */
+    @GetMapping("/generate")
+    @NonLogin
+    public ExecutedResult<String> generate(@RequestParam String uuid) {
+        //#endregion
+        return  service.generate(uuid);
+    }
     /**
      * 分页查询所有管理员
      *
@@ -146,7 +173,7 @@
      */
     @PostMapping("login")
     @NonLogin
-    public ExecutedResult<ResAdminLogin> adminLogin(@RequestBody ReqAdminLogin request) {
+    public ExecutedResult<ResAdminLogin> adminLogin(@RequestBody ReqAdminLogin request) throws Exception {
         //#region 参数验证
         ParameterValidator validator = new ParameterValidator()
                 .addNotNullOrEmpty(ParameterUtil.named("用户名"), request.getUserName())
diff --git a/src/main/java/com/lunhan/water/host/controller/api/UserController.java b/src/main/java/com/lunhan/water/host/controller/api/UserController.java
new file mode 100644
index 0000000..41c91f7
--- /dev/null
+++ b/src/main/java/com/lunhan/water/host/controller/api/UserController.java
@@ -0,0 +1,113 @@
+package com.lunhan.water.host.controller.api;
+
+import com.lunhan.water.common.ExecutedResult;
+import com.lunhan.water.common.PagerResult;
+import com.lunhan.water.common.jwt.LoginUserDTO;
+import com.lunhan.water.common.util.ParameterUtil;
+import com.lunhan.water.common.validator.ParameterValidateResult;
+import com.lunhan.water.common.validator.ParameterValidator;
+import com.lunhan.water.entity.request.paymentrecords.ReqBuyWater;
+import com.lunhan.water.entity.request.userlogin.ReqModifyUserLogin;
+import com.lunhan.water.entity.search.SearchPaymentRecords;
+import com.lunhan.water.entity.search.SearchRechargeRecords;
+import com.lunhan.water.entity.search.SearchWaterFacility;
+import com.lunhan.water.host.BasicController;
+import com.lunhan.water.repository.po.UserLoginPO;
+import com.lunhan.water.repository.vo.PaymentRecordsVO;
+import com.lunhan.water.repository.vo.RechargeRecordsVO;
+import com.lunhan.water.repository.vo.UserLoginVO;
+import com.lunhan.water.repository.vo.WaterFacilityVO;
+import com.lunhan.water.service.PaymentRecordsService;
+import com.lunhan.water.service.RechargeRecordsService;
+import com.lunhan.water.service.UserLoginService;
+import com.lunhan.water.service.WaterFacilityService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import java.math.BigDecimal;
+import java.util.Objects;
+
+@RestController
+@RequestMapping(value = "api/user")
+public class UserController extends BasicController {
+    @Autowired
+    private PaymentRecordsService paymentRecordsService;
+    @Autowired
+    private RechargeRecordsService rechargeRecordsService;
+    @Autowired
+    private UserLoginService userLoginService;
+    @Autowired
+    private WaterFacilityService waterFacilityService;
+    /**
+     * 查询用户信息
+     * @author lin.liu
+     */
+    @GetMapping(value = "getUser")
+    public ExecutedResult<UserLoginVO> getUser() {
+        return userLoginService.getUser(this.getTokenUser());
+    }
+    /**
+     * 编辑用户头像信息
+     * @author lin.liu
+     */
+    @PostMapping(value = "editUser")
+    public ExecutedResult<String> editUser(@RequestBody ReqModifyUserLogin request ) {
+        return userLoginService.modify(request);
+    }
+    /**
+     * 用户取水
+     * @author lin.liu
+     */
+    @PostMapping(value = "userWaterInTaking")
+    public ExecutedResult<String> userWaterInTaking(@RequestBody ReqBuyWater request) {
+        return paymentRecordsService.userWaterInTaking(this.getTokenUser(),request);
+    }
+    /**
+     * 查询取水设备列表
+     * @author lin.liu
+     */
+    @PostMapping(value = "searchFacility")
+    public ExecutedResult<PagerResult<WaterFacilityVO>> searchFacility(@RequestBody SearchWaterFacility request) {
+        //#region 参数验证
+        ParameterValidator validator = new ParameterValidator()
+                // 必须大于0
+                .addGreater(ParameterUtil.named("纬度"), request.getLatitude(), 0L)
+                .addGreater(ParameterUtil.named("经度"), request.getLongitude(), 0L)
+                ;
+        ParameterValidateResult result = validator.validate();
+        if (result.getIsFiled()) {
+            return failed(result.getErrorMsg());
+        }
+        return waterFacilityService.search(request);
+    }
+
+    /**
+     * 查询[消费记录]
+     * @author lin.liu
+     */
+    @PostMapping(value = "searchPaymentRecords")
+    public ExecutedResult<PagerResult<PaymentRecordsVO>> searchPaymentRecords(@RequestBody SearchPaymentRecords request) {
+        //#region 参数验证
+        LoginUserDTO tokenUser = this.getTokenUser();
+        UserLoginPO user = userLoginService.get4Openid(tokenUser.getUserId());
+        if(Objects.isNull(user)){
+            return ExecutedResult.failed("用户信息不存在!");
+        }
+        request.setUserId(user.getId());
+        return paymentRecordsService.search(request);
+    }
+    /**
+     * 查询[充值记录]
+     * @author lin.liu
+     */
+    @PostMapping(value = "searchRechargeRecords")
+    public ExecutedResult<PagerResult<RechargeRecordsVO>> searchRechargeRecords(@RequestBody SearchRechargeRecords request) {
+        LoginUserDTO tokenUser = this.getTokenUser();
+        UserLoginPO user = userLoginService.get4Openid(tokenUser.getUserId());
+        if(Objects.isNull(user)){
+            return ExecutedResult.failed("用户信息不存在!");
+        }
+        request.setUserId(user.getId());
+        return rechargeRecordsService.search(request);
+    }
+}
diff --git a/src/main/java/com/lunhan/water/host/controller/notify/NotifyController.java b/src/main/java/com/lunhan/water/host/controller/notify/NotifyController.java
new file mode 100644
index 0000000..c7ceb84
--- /dev/null
+++ b/src/main/java/com/lunhan/water/host/controller/notify/NotifyController.java
@@ -0,0 +1,297 @@
+package com.lunhan.water.host.controller.notify;
+
+import com.google.gson.Gson;
+import com.lunhan.water.common.ConstantFactory;
+import com.lunhan.water.common.ExecutedResult;
+import com.lunhan.water.common.config.SysConfig;
+import com.lunhan.water.common.enums.ELogger;
+import com.lunhan.water.common.util.LocalDateTimeUtil;
+import com.lunhan.water.common.util.LoggerUtil;
+import com.lunhan.water.common.util.SerializeUtil;
+import com.lunhan.water.common.util.StringUtil;
+import com.lunhan.water.common.wechat.WechatPayV3Util;
+import com.lunhan.water.entity.dto.pay.WeiXinPayNotifyDto;
+import com.lunhan.water.entity.dto.pay.WeiXinRefundNotifyDto;
+import com.lunhan.water.entity.enums.EPaymentChannel;
+import com.lunhan.water.entity.response.pay.ResWeiXinPayNotify;
+import com.lunhan.water.host.api.NonLogin;
+import com.lunhan.water.service.PaymentServices;
+import com.lunhan.water.service.ThirdNotifyService;
+import org.slf4j.Logger;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.math.BigDecimal;
+import java.nio.charset.StandardCharsets;
+import java.time.LocalDateTime;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Objects;
+
+/**
+ * 10010.异步通知相关接口
+ *
+ * @order 10010
+ */
+@NonLogin
+@RestController
+@RequestMapping("notify")
+public class NotifyController {
+    private Logger logger = LoggerUtil.get(ELogger.PAY_SERVICE);
+    @Autowired
+    private PaymentServices paymentService;
+    @Autowired
+    private ThirdNotifyService thirdNotifyService;
+
+    /**
+     * 微信支付结果通知
+     *
+     * @param reqBody 请求参数列表
+     */
+    @PostMapping(value = "pay/{channel}/{payWay}/{businessType}")
+    public Object pay(@RequestBody Map<String, Object> reqBody, @PathVariable Integer channel, @PathVariable Integer payWay, @PathVariable Integer businessType) {
+        String action = "pay";
+
+        if (Objects.isNull(reqBody) || reqBody.isEmpty()) {
+            logger.error(action + ", body cant't be null.");
+            return "body cant't be null.";
+        }
+        String body = SerializeUtil.toJson(reqBody);
+        logger.info(action + "-notify, channel: " + channel + "; payWay: " + payWay + "; body: " + body);
+
+        EPaymentChannel findChannel = EPaymentChannel.getByValue(channel);
+        if (Objects.isNull(findChannel)) {
+            return "支付渠道不支持." + channel;
+        }
+        Object result;
+        switch (findChannel) {
+            case WE_CHAT:
+                result = this.doWeiXinPayNotify(reqBody, body, businessType);
+                break;
+
+            case ALI_PAY:
+                // TODO
+                result = "支付宝支付待实现";
+                break;
+
+            default:
+                result = "支付渠道不支持." + channel;
+                break;
+        }
+        return result;
+    }
+
+    private ResWeiXinPayNotify doWeiXinPayNotify(Map<String, Object> reqBody, String body, Integer businessType) {
+        String action = "doWeiXinPayNotify";
+        ResWeiXinPayNotify result = new ResWeiXinPayNotify("FAILED", "unknown error.");
+
+        ExecutedResult<Long> saveWinXinNotify = thirdNotifyService.saveWinXinPayNotify(EPaymentChannel.WE_CHAT, "PAY", body, businessType);
+        if (saveWinXinNotify.isFailed()) {
+            if (Objects.equals(saveWinXinNotify.getMsgCode(), ConstantFactory.MCODE_TOKENERROR)) {
+                result.setCode("SUCCESS");
+                result.setMessage("SUCCESS");
+            } else {
+                result.setMessage(saveWinXinNotify.getMsg());
+            }
+            return result;
+        }
+        Long notifyId = saveWinXinNotify.getData();
+
+        // 处理微信支付结果通知
+        try {
+            if (reqBody.containsKey("event_type") && "TRANSACTION.SUCCESS".equals(reqBody.get("event_type").toString())) {
+                this.doWeiXinPayResult(SerializeUtil.toJson(reqBody.get("resource")), notifyId);
+            }
+        } catch (Exception e) {
+            logger.error(action, e);
+            result.setMessage(e.getMessage());
+            return result;
+        }
+        result.setCode("SUCCESS");
+        result.setMessage("SUCCESS");
+        return result;
+    }
+
+    /**
+     * 更新微信支付结果
+     *
+     * @param body     通知报文
+     * @param notifyId 通知报文记录id
+     */
+    private void doWeiXinPayResult(String body, Long notifyId) throws Exception {
+        String actionStr = "weiXinPay, ";
+        Map<String, Object> data = new Gson().fromJson(body, Map.class);
+        if (data.containsKey("algorithm") && "AEAD_AES_256_GCM".equals(data.get("algorithm").toString())) {
+            String signParams = data.get("ciphertext").toString();
+
+            String paramsStr = "";
+
+            byte[] bufferKey = SysConfig.weiXinPay.getMerchantKey().getBytes(StandardCharsets.UTF_8);
+            byte[] bufferAssociatedData = data.get("associated_data").toString().getBytes(StandardCharsets.UTF_8);
+            byte[] bufferNonce = data.get("nonce").toString().getBytes(StandardCharsets.UTF_8);
+            paramsStr = WechatPayV3Util.decryptToString(bufferAssociatedData, bufferNonce, signParams, bufferKey);
+            logger.info(actionStr + "支付结果解密: " + paramsStr);
+
+            WeiXinPayNotifyDto payInfo = SerializeUtil.toObject(paramsStr, WeiXinPayNotifyDto.class);
+
+            // 更新通知报文业务编号
+            thirdNotifyService.updateBusinessCode(notifyId, payInfo.getOut_trade_no());
+
+            if ("SUCCESS".equalsIgnoreCase(payInfo.getTrade_state())) {
+                LocalDateTime payTime = null;
+                if (StringUtil.isNotNullOrEmpty(payInfo.getSuccess_time())) {
+                    payTime = LocalDateTimeUtil.getDateTime(payInfo.getSuccess_time(), "yyyy-MM-d'T'HH:mm:ssXXX");
+                }
+                Integer paidAmount = payInfo.getAmount().getPayer_total();
+
+                ExecutedResult<String> doPaidSuccess = paymentService.doPaidSuccess(
+                        payInfo.getOut_trade_no(),
+                        payInfo.getTransaction_id(),
+                        new BigDecimal(paidAmount.toString()).divide(new BigDecimal(ConstantFactory.NUM100.toString())), // 微信支付金额乘了100
+                        payTime
+                );
+                logger.info(actionStr + "支付成功更新支付结果: " + SerializeUtil.toJson(doPaidSuccess));
+            } else if ("PAYERROR".equalsIgnoreCase(payInfo.getTrade_state())) {
+                ExecutedResult<String> doPaidFailed = paymentService.doPaidFailed(
+                        payInfo.getOut_trade_no(),
+                        payInfo.getTransaction_id(),
+                        payInfo.getTrade_state_desc()
+                );
+                logger.info(actionStr + "支付失败,更新支付结果: " + SerializeUtil.toJson(doPaidFailed));
+            }
+        } else {
+            logger.error(actionStr + "报文加密方式未能识别!" + body);
+        }
+    }
+
+
+    /**
+     * 微信退款结果通知
+     *
+     * @param reqBody 请求参数列表
+     */
+    @PostMapping(value = "refund/{channel}/{payWay}/{businessType}")
+    public Object refund(@RequestBody Map<String, Object> reqBody, @PathVariable Integer channel, @PathVariable Integer payWay, @PathVariable Integer businessType) {
+        String action = "refund";
+
+        if (Objects.isNull(reqBody)) {
+            logger.error(action + ", body cant't be null.");
+            return "请求正文不能为空.";
+        }
+        String body = SerializeUtil.toJson(reqBody);
+        logger.info(action + "-notify, channel: " + channel + "; payWay: " + payWay + "; body: " + body);
+
+        EPaymentChannel findChannel = EPaymentChannel.getByValue(channel);
+        if (Objects.isNull(findChannel)) {
+            return "支付渠道不支持." + channel;
+        }
+        Object result;
+        switch (findChannel) {
+            case WE_CHAT:
+                result = this.doWeiXinRefundNotify(reqBody, body, businessType);
+                break;
+
+            case ALI_PAY:
+                // TODO
+                result = "支付宝支付待实现";
+                break;
+
+            default:
+                result = "支付渠道不支持";
+                break;
+        }
+        return result;
+    }
+
+    private Object doWeiXinRefundNotify(Map<String, Object> reqBody, String body, Integer businessType) {
+        String action = "doWeiXinRefundNotify";
+        ResWeiXinPayNotify result = new ResWeiXinPayNotify("FAILED", "unknown error.");
+
+        ExecutedResult<Long> saveWinXinNotify = thirdNotifyService.saveWinXinPayNotify(EPaymentChannel.WE_CHAT, "REFUND", body, businessType);
+        if (saveWinXinNotify.isFailed()) {
+            if (Objects.equals(saveWinXinNotify.getMsgCode(), ConstantFactory.MCODE_TOKENERROR)) {
+                result.setCode("SUCCESS");
+                result.setMessage("SUCCESS");
+            } else {
+                result.setMessage(saveWinXinNotify.getMsg());
+            }
+            return result;
+        }
+        Long notifyId = saveWinXinNotify.getData();
+
+        // 处理微信支付结果通知
+        try {
+            if (reqBody.containsKey("event_type") && "REFUND.SUCCESS".equals(reqBody.get("event_type").toString())) {
+                this.doWeiXinRefundResult(SerializeUtil.toJson(reqBody.get("resource")), notifyId);
+            }
+        } catch (Exception e) {
+            logger.error(action, e);
+            result.setMessage(e.getMessage());
+            return result;
+        }
+        result.setCode("SUCCESS");
+        result.setMessage("SUCCESS");
+        return result;
+    }
+
+    /**
+     * 更新微信退款结果
+     *
+     * @param body     通知报文
+     * @param notifyId 通知报文记录id
+     */
+    private void doWeiXinRefundResult(String body, Long notifyId) throws Exception {
+        String actionStr = "weiXinRefund, ";
+        Map<String, Object> data = new Gson().fromJson(body, Map.class);
+        if (data.containsKey("algorithm") && "AEAD_AES_256_GCM".equals(data.get("algorithm").toString())) {
+            String signParams = data.get("ciphertext").toString();
+
+
+            String paramsStr = "";
+
+            byte[] bufferKey = SysConfig.weiXinPay.getMerchantKey().getBytes(StandardCharsets.UTF_8);
+            byte[] bufferAssociatedData = data.get("associated_data").toString().getBytes(StandardCharsets.UTF_8);
+            byte[] bufferNonce = data.get("nonce").toString().getBytes(StandardCharsets.UTF_8);
+            paramsStr = WechatPayV3Util.decryptToString(bufferAssociatedData, bufferNonce, signParams, bufferKey);
+            logger.info(actionStr + "退款结果解密: " + paramsStr);
+
+            WeiXinRefundNotifyDto refundInfo = SerializeUtil.toObject(paramsStr, WeiXinRefundNotifyDto.class);
+
+            // 更新通知报文业务编号
+            thirdNotifyService.updateBusinessCode(notifyId, refundInfo.getOut_trade_no());
+
+            if ("SUCCESS".equalsIgnoreCase(refundInfo.getRefund_status())) {
+                LocalDateTime refundTime = null;
+                if (StringUtil.isNotNullOrEmpty(refundInfo.getSuccess_time())) {
+                    refundTime = LocalDateTimeUtil.getDateTime(refundInfo.getSuccess_time(), "yyyy-MM-d'T'HH:mm:ssXXX");
+                }
+                Integer paidAmount = refundInfo.getAmount().getPayer_refund();
+
+                ExecutedResult<String> doRefundSuccess = paymentService.doRefundSuccess(
+                        refundInfo.getOut_trade_no(),
+                        refundInfo.getTransaction_id(),
+                        new BigDecimal(paidAmount.toString()).divide(new BigDecimal(ConstantFactory.NUM100.toString())), // 微信支付金额乘了100
+                        refundTime
+                );
+                logger.info(actionStr + "退款成功更新支付结果: " + SerializeUtil.toJson(doRefundSuccess));
+            } else {
+                String errorMsg = "refund_status: ABNORMAL. 退款异常,退款到银行发现用户的卡作废或者冻结了,导致原路退款银行卡失败,可前往【商户平台—>交易中心】,手动处理此笔退款";
+                if ("CLOSED".equalsIgnoreCase(refundInfo.getRefund_status())) {
+                    errorMsg = "refund_status: CLOSED. 退款关闭";
+                }
+                ExecutedResult<String> doRefundFailed = paymentService.doRefundFailed(
+                        refundInfo.getOut_trade_no(),
+                        refundInfo.getTransaction_id(),
+                        errorMsg
+                );
+                logger.info(actionStr + "退款失败,更新退款结果: " + SerializeUtil.toJson(doRefundFailed));
+            }
+        } else {
+            logger.error(actionStr + "报文加密方式未能识别!" + body);
+        }
+    }
+}
diff --git a/src/main/java/com/lunhan/water/host/controller/pay/PaymentServicesController.java b/src/main/java/com/lunhan/water/host/controller/pay/PaymentServicesController.java
index 045a487..a6a0f3b 100644
--- a/src/main/java/com/lunhan/water/host/controller/pay/PaymentServicesController.java
+++ b/src/main/java/com/lunhan/water/host/controller/pay/PaymentServicesController.java
@@ -1,74 +1,92 @@
-//package com.lunhan.water.host.controller.pay;
-//
-//import com.alipay.api.AlipayApiException;
-//import com.lunhan.water.common.ExecutedResult;
-//import com.lunhan.water.common.util.ParameterUtil;
-//import com.lunhan.water.common.validator.ParameterValidateResult;
-//import com.lunhan.water.common.validator.ParameterValidator;
-//import com.lunhan.water.entity.enums.EBusinessType;
-//import com.lunhan.water.entity.request.pay.ReqCreatePay;
-//import com.lunhan.water.entity.request.pay.ReqOrderPay;
-//import com.lunhan.water.entity.request.pay.ReqPayRefund;
-//import com.lunhan.water.host.BasicController;
-//import com.lunhan.water.service.PaymentServices;
-//import lombok.extern.slf4j.Slf4j;
-//import org.springframework.beans.factory.annotation.Autowired;
-//import org.springframework.web.bind.annotation.PostMapping;
-//import org.springframework.web.bind.annotation.RequestBody;
-//import org.springframework.web.bind.annotation.RequestMapping;
-//import org.springframework.web.bind.annotation.RestController;
-//
-//import java.util.Map;
-//
-///**
-// * 50.支付服务
-// *
-// * @author li。ling。yu
-// * @date 2023/10/19
-// * @order 50
-// */
-//@Slf4j
-//@RestController
-//@RequestMapping(value = "/pay/service")
-//public class PaymentServicesController extends BasicController {
-//
-//    @Autowired
-//    private PaymentServices services;
-//
-//    /**
-//     * 发起微信支付
-//     * @param request 请求参数
-//     *
-//     * @return 返回微信jsapi支付参数
-//     */
-//    @PostMapping(value = "wxPay")
-//    public ExecutedResult<Map<String, Object>> wxPay(@RequestBody ReqCreatePay request) {
-//        //#region 参数验证
-//        ParameterValidator validator = new ParameterValidator()
-//                // 必须是枚举值
-//                .addMustEnum(ParameterUtil.named("业务类型"), request.getBusinessType(), EBusinessType.class)
-//                // 必须大于0
-//                //.addNotNullOrEmpty(ParameterUtil.named("订单号"), request.getBusinessNo())
-//                ;
-//        ParameterValidateResult result = validator.validate();
-//        if (result.getIsFiled()) {
-//            return ExecutedResult.failed(result.getErrorMsg());
-//        }
-//        //#endregion
-//        return services.weiXinPay(this.getTokenUser(), request);
-//    }
-//
-//
-//
-//    /**
-//     * 发起微信退款
-//     * @param request 请求参数
-//     *
-//     * @return 返回退款流水号
-//     */
-//    @PostMapping(value = "wxRefund")
-//    public ExecutedResult<String> wxRefund(@RequestBody ReqPayRefund request) {
-//        //PaymentMerchantPO merchant = super.getTokenUser();
-//        return services.weiXinRefund(request);
-//    }
-//}
+package com.lunhan.water.host.controller.pay;
+
+import com.lunhan.water.common.ExecutedResult;
+import com.lunhan.water.common.util.ParameterUtil;
+import com.lunhan.water.common.util.StringUtil;
+import com.lunhan.water.common.validator.ParameterValidateResult;
+import com.lunhan.water.common.validator.ParameterValidator;
+import com.lunhan.water.entity.enums.EBusinessType;
+import com.lunhan.water.entity.request.pay.ReqCreatePay;
+import com.lunhan.water.entity.request.pay.ReqOrderPay;
+import com.lunhan.water.entity.request.pay.ReqPayRefund;
+import com.lunhan.water.host.BasicController;
+import com.lunhan.water.service.PaymentServices;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.web.bind.annotation.*;
+
+import java.math.BigDecimal;
+import java.util.Map;
+import java.util.UUID;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * 50.支付服务
+ *
+ * @author li。ling。yu
+ * @date 2023/10/19
+ * @order 50
+ */
+@Slf4j
+@RestController
+@RequestMapping(value = "/pay/service")
+public class PaymentServicesController extends BasicController {
+
+    @Autowired
+    private PaymentServices services;
+    @Autowired
+    private RedisTemplate<String, Object> redisTemplate;
+    /**
+     * 发起微信支付
+     * @param request 请求参数
+     *
+     * @return 返回微信jsapi支付参数
+     */
+    @PostMapping(value = "wxPay")
+    public ExecutedResult<Map<String, Object>> wxPay(@RequestBody ReqCreatePay request) {
+        //#region 参数验证
+        ParameterValidator validator = new ParameterValidator()
+                // 必须是枚举值
+                .addMustEnum(ParameterUtil.named("业务类型"), request.getBusinessType(), EBusinessType.class)
+                // 必须大于0
+                .addGreater(ParameterUtil.named("交易金额"), request.getTradeAmount(), BigDecimal.ZERO)
+                //水表编号不能为空
+                .addNotNullOrEmpty(ParameterUtil.named("支付token"), request.getPayToken());
+                ;
+        ParameterValidateResult result = validator.validate();
+        if (result.getIsFiled()) {
+            return ExecutedResult.failed(result.getErrorMsg());
+        }
+        //#endregion
+        return services.weiXinPay(this.getTokenUser(), request);
+    }
+
+    @PostMapping("/getPayToken")
+    public ExecutedResult<String>getPayToken(){
+        String token = UUID.randomUUID().toString();
+        redisTemplate.opsForValue().set(token,token,5, TimeUnit.MINUTES);
+        return ExecutedResult.success(token);
+    }
+    @GetMapping("/getRedisToken")
+    public ExecutedResult<String>getRedisToken(String token){
+        String string = redisTemplate.opsForValue().get(token).toString();
+        if(StringUtil.isNullOrEmpty(string)){
+            return ExecutedResult.failed("请勿重复提交订单");
+        }
+        redisTemplate.delete(string);
+        return ExecutedResult.success(string);
+    }
+
+    /**
+     * 发起微信退款
+     * @param request 请求参数
+     *
+     * @return 返回退款流水号
+     */
+    @PostMapping(value = "wxRefund")
+    public ExecutedResult<String> wxRefund(@RequestBody ReqPayRefund request) {
+        //PaymentMerchantPO merchant = super.getTokenUser();
+        return services.weiXinRefund(request);
+    }
+}
diff --git a/src/main/java/com/lunhan/water/host/controller/user/UserLoginController.java b/src/main/java/com/lunhan/water/host/controller/user/UserLoginController.java
index e16f758..a640838 100644
--- a/src/main/java/com/lunhan/water/host/controller/user/UserLoginController.java
+++ b/src/main/java/com/lunhan/water/host/controller/user/UserLoginController.java
@@ -22,6 +22,7 @@
 */
 package com.lunhan.water.host.controller.user;
 
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.google.gson.JsonObject;
 import com.google.gson.JsonParser;
 import com.lunhan.water.common.ConstantFactory;
@@ -44,10 +45,13 @@
 import com.lunhan.water.entity.request.ReqListId;
 import com.lunhan.water.entity.request.ReqNeedCode;
 import com.lunhan.water.entity.request.ReqUserLogin;
+import com.lunhan.water.entity.search.SearchRechargeOrder;
 import com.lunhan.water.entity.weixin.WeiXinUserDto;
 import com.lunhan.water.host.BasicController;
 import com.lunhan.water.host.api.NonLogin;
+import com.lunhan.water.repository.impl.UserLoginMapperImpl;
 import com.lunhan.water.repository.po.UserLoginPO;
+import com.lunhan.water.repository.vo.RechargeOrderVO;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.*;
 import java.util.List;
@@ -69,6 +73,8 @@
 public class UserLoginController extends BasicController {
     @Autowired
     private UserLoginService userLoginService;
+    @Autowired
+    private UserLoginMapperImpl userLoginMapper;
     /**
      * 微信小程序授权
      * @param request 请求参数
@@ -101,6 +107,13 @@
             reqCreateUser.setHeadImg(userInfo.getHeadImgUrl());
             reqCreateUser.setPhone("");
             reqCreateUser.setComment("");
+            UserLoginPO userLoginPO = userLoginMapper.getOrderByDesc();
+            if(Objects.nonNull(userLoginPO)){
+                int userCode = Integer.parseInt(userLoginPO.getUserCode()) + 1;
+                reqCreateUser.setUserCode(String.valueOf(userCode));
+            }else {
+                reqCreateUser.setUserCode("10001");
+            }
             ExecutedResult<Long> createAdmin = userLoginService.create(reqCreateUser);
             if (createAdmin.isFailed()) {
                 return ExecutedResult.failed(createAdmin.getMsg());
@@ -190,4 +203,12 @@
         //#endregion
         return userLoginService.login(request);
     }
+    /**
+     * 查询[用户]
+     * @author lin.liu
+     */
+    @PostMapping(value = "search")
+    public ExecutedResult<PagerResult<UserLoginVO>> search(@RequestBody SearchUserLogin request) {
+        return userLoginService.search(request);
+    }
 }
diff --git a/src/main/java/com/lunhan/water/host/mqtt/CountVO.java b/src/main/java/com/lunhan/water/host/mqtt/CountVO.java
new file mode 100644
index 0000000..2444f50
--- /dev/null
+++ b/src/main/java/com/lunhan/water/host/mqtt/CountVO.java
@@ -0,0 +1,9 @@
+package com.lunhan.water.host.mqtt;
+
+import lombok.Data;
+
+@Data
+public class CountVO {
+ private String name;
+ private String value;
+}
diff --git a/src/main/java/com/lunhan/water/host/mqtt/MQTTServer.java b/src/main/java/com/lunhan/water/host/mqtt/MQTTServer.java
index 7263803..7718962 100644
--- a/src/main/java/com/lunhan/water/host/mqtt/MQTTServer.java
+++ b/src/main/java/com/lunhan/water/host/mqtt/MQTTServer.java
@@ -63,11 +63,10 @@
      * @param topic 发布消息的主题
      * @param data 消息内容
      */
-    public boolean send(String topic, String data) throws MqttException {
-        MqttConnectOptions options = mqttConnect.getOptions();
+    public boolean send(String topic, String data) {
         try {
-            client.connect(mqttConnect.getOptions(options));
-        } catch (Exception e) {}
+            this.connect();
+        } catch (Exception ignored) {}
         MqttTopic mqttTopic = client.getTopic(topic);
 
         MqttMessage message = new MqttMessage();
@@ -81,7 +80,13 @@
 
         message.setPayload(data.getBytes());
 
-        return this.publish(mqttTopic, message);
+        LOGGER.debug(String.format("发送mqtt消息:%s, 消息内容:%s", topic, message));
+        try {
+            return this.publish(mqttTopic, message);
+        } catch (MqttException e) {
+            LOGGER.error("发送mqtt消息", e);
+            return Boolean.FALSE;
+        }
     }
 
     @Override
diff --git a/src/main/java/com/lunhan/water/host/mqtt/PushCallback.java b/src/main/java/com/lunhan/water/host/mqtt/PushCallback.java
index 261ab6f..7d88313 100644
--- a/src/main/java/com/lunhan/water/host/mqtt/PushCallback.java
+++ b/src/main/java/com/lunhan/water/host/mqtt/PushCallback.java
@@ -2,13 +2,17 @@
 
 import com.lunhan.water.common.enums.ELogger;
 import com.lunhan.water.common.util.LoggerUtil;
+import com.lunhan.water.common.util.SpringUtil;
 import com.lunhan.water.common.util.ThreadPoolUtil;
+import com.lunhan.water.service.PaymentRecordsService;
 import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken;
 import org.eclipse.paho.client.mqttv3.MqttCallback;
 import org.eclipse.paho.client.mqttv3.MqttMessage;
 import org.slf4j.Logger;
+import org.springframework.beans.factory.annotation.Autowired;
 
 import java.nio.charset.StandardCharsets;
+import java.util.Objects;
 
 ;
 
@@ -31,7 +35,8 @@
 public class PushCallback implements MqttCallback {
     private static final Logger LOGGER_DEBUG = LoggerUtil.get(ELogger.DEBUG);
     private static final Logger LOGGER_ERROR = LoggerUtil.get(ELogger.SYS_ERROR);
-
+    @Autowired
+    PaymentRecordsService paymentRecordsService;
     private MQTTSubsribe mqttSubsribe;
 
     public PushCallback(MQTTSubsribe mqttSubsribe) {
@@ -73,8 +78,21 @@
         //这里可以针对收到的消息做处理
         ThreadPoolUtil.getDefaultPool().execute(() -> {
             try {
-                //调用方法
-                //dataUploadYwjRecordService.mqttReceived(topic, msg);
+                if (Objects.nonNull(paymentRecordsService)) {
+                    //调用方法
+                    paymentRecordsService.mqttReceived(topic, msg);
+                } else {
+                    try {
+                        System.out.println("paymentRecordsService bean尚未初始化...");
+                        paymentRecordsService = SpringUtil.getBean(PaymentRecordsService.class);
+                        System.out.println("paymentRecordsService 初始化bean成功!");
+                    } catch (Exception ignored) {
+                    }
+                    if (Objects.nonNull(paymentRecordsService)) {
+                        //调用方法
+                        paymentRecordsService.mqttReceived(topic, msg);
+                    }
+                }
             } catch (Exception e) {
                 LOGGER_ERROR.error("messageArrived", e);
             }
diff --git a/src/main/java/com/lunhan/water/repository/impl/FacilityAlarmRecordMapperImpl.java b/src/main/java/com/lunhan/water/repository/impl/FacilityAlarmRecordMapperImpl.java
new file mode 100644
index 0000000..cc94193
--- /dev/null
+++ b/src/main/java/com/lunhan/water/repository/impl/FacilityAlarmRecordMapperImpl.java
@@ -0,0 +1,137 @@
+/**
+#                                                    __----~~~~~~~~~~~------___
+#                                   .  .   ~~//====......          __--~ ~~
+#                   -.            \_|//     |||\\  ~~~~~~::::... /~
+#                ___-==_       _-~o~  \/    |||  \\            _/~~-
+#        __---~~~.==~||\=_    -_--~/_-~|-   |\\   \\        _/~
+#    _-~~     .=~    |  \\-_    '-~7  /-   /  ||    \      /
+#  .~       .~       |   \\ -_    /  /-   /   ||      \   /
+# /  ____  /         |     \\ ~-_/  /|- _/   .||       \ /
+# |~~    ~~|--~~~~--_ \     ~==-/   | \~--===~~        .\
+#          '         ~-|      /|    |-~\~~       __--~~
+#                      |-~~-_/ |    |   ~\_   _-~            /\
+#                           /  \     \__   \/~                \__
+#                       _--~ _/ | .-~~____--~-/                  ~~==.
+#                      ((->/~   '.|||' -_|    ~~-/ ,              . _||
+#                                 -_     ~\      ~~---l__i__i__i--~~_/
+#                                 _-~-__   ~)  \--______________--~~
+#                               //.-~~~-~_--~- |-------~~~~~~~~
+#                                      //.-~~~--\
+#                  神兽保佑
+#                  永无BUG!
+*/
+package com.lunhan.water.repository.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.lunhan.water.common.PagerResult;
+import com.lunhan.water.common.enums.EYesOrNo;
+import com.lunhan.water.common.util.*;
+import com.lunhan.water.entity.dto.*;
+import com.lunhan.water.entity.enums.*;
+import com.lunhan.water.repository.BasicMapperImpl;
+import org.springframework.stereotype.Repository;
+
+import java.util.List;
+import com.lunhan.water.entity.search.SearchFacilityAlarmRecord;
+import com.lunhan.water.repository.mapper.FacilityAlarmRecordMapper;
+import com.lunhan.water.repository.po.FacilityAlarmRecordPO;
+
+/**
+ * 设备报警记录
+ * @author lin.liu
+ */
+@Repository
+public class FacilityAlarmRecordMapperImpl extends BasicMapperImpl<FacilityAlarmRecordPO, FacilityAlarmRecordMapper> {
+	FacilityAlarmRecordMapperImpl(FacilityAlarmRecordMapper mapper) {
+		super(mapper);
+	}
+
+	@Override
+	public PagerResult<FacilityAlarmRecordPO> search(SearchBasicDTO request) {
+		// 还原查询条件真实类型
+		SearchFacilityAlarmRecord search = (SearchFacilityAlarmRecord)request;
+		// 查询条件
+		LambdaQueryWrapper<FacilityAlarmRecordPO> queryWrapper = this.query();
+		// 非逻辑删除
+		queryWrapper.eq(FacilityAlarmRecordPO::getIsDelete, EYesOrNo.NO.getValue());
+		// 状态
+		//queryWrapper.eq(NumericUtil.tryParseInt(search.getStatus()).compareTo(0) > 0, FacilityAlarmRecordPO::getStatus, search.getStatus());
+		// 状态列表
+		//queryWrapper.in(ListUtil.isNotNullOrEmpty(search.getListStatus()), FacilityAlarmRecordPO::getStatus, search.getListStatus());
+
+		// 数据创建时间-起始
+		queryWrapper.ge(NumericUtil.tryParseLong(search.getCreateTimeStart()).compareTo(0L) > 0, FacilityAlarmRecordPO::getCreateTime, search.getCreateTimeStart());
+		// 数据创建时间-截止
+		queryWrapper.le(NumericUtil.tryParseLong(search.getCreateTimeEnd()).compareTo(0L) > 0, FacilityAlarmRecordPO::getCreateTime, search.getCreateTimeEnd());
+		// 关键字
+		//if (StringUtil.isNotNullOrEmpty(search.getKeywords())) {
+		//	queryWrapper.and(q ->
+		//		q.like(FacilityAlarmRecordPO::getName, search.getKeywords())
+		//		.or().like(FacilityAlarmRecordPO::getPhone, search.getKeywords())
+		//	);
+		//}
+
+		// 排序处理
+		if (ListUtil.isNotNullOrEmpty(search.getOrderBy())) {
+			for (OrderByDTO item : search.getOrderBy()) {
+				EOrderBy orderBy = EOrderBy.getByValue(item.getOrderBy());
+				// 顺序排序
+				if (item.getIsAsc()) {
+					switch (orderBy) {
+						// 主键
+						case ID:
+							queryWrapper.orderByAsc(FacilityAlarmRecordPO::getId);
+							break;
+						// 数据创建时间
+						case CREATE_TIME:
+							queryWrapper.orderByAsc(FacilityAlarmRecordPO::getCreateTime);
+							break;
+						// 最后更新时间
+						case UPDATE_TIME:
+							queryWrapper.orderByAsc(FacilityAlarmRecordPO::getUpdateTime);
+							break;
+					}
+				} else {
+					// 倒叙排序
+					switch (orderBy) {
+						// 主键
+						case ID:
+							queryWrapper.orderByDesc(FacilityAlarmRecordPO::getId);
+							break;
+						// 数据创建时间
+						case CREATE_TIME:
+							queryWrapper.orderByDesc(FacilityAlarmRecordPO::getCreateTime);
+							break;
+						// 最后更新时间
+						case UPDATE_TIME:
+							queryWrapper.orderByDesc(FacilityAlarmRecordPO::getUpdateTime);
+							break;
+					}
+				}
+			}
+		} else {
+			queryWrapper.orderByDesc(FacilityAlarmRecordPO::getId);
+		}
+		Page<FacilityAlarmRecordPO> pageResult = super.selectPage(new Page<>(search.getPage(), search.getLimit()), queryWrapper);
+		return new PagerResult<>(pageResult.getSize(), pageResult.getCurrent(), pageResult.getTotal(), pageResult.getRecords());
+	}
+
+	public Boolean add(FacilityAlarmRecordPO item) {
+		int rowCount = super.insert(item);
+		return rowCount == 1;
+	}
+
+	public Boolean addNotIncrement(FacilityAlarmRecordPO item) {
+		int rowCount = super.insert(item);
+		return rowCount == 1;
+	}
+
+	public FacilityAlarmRecordPO getById(Long id) {
+		return super.get(id);
+	}
+
+	public List<FacilityAlarmRecordPO> getListById(List<Long> listId) {
+		return super.getList(listId);
+	}
+}
diff --git a/src/main/java/com/lunhan/water/repository/impl/HeartbeatDataMapperImpl.java b/src/main/java/com/lunhan/water/repository/impl/HeartbeatDataMapperImpl.java
new file mode 100644
index 0000000..95be780
--- /dev/null
+++ b/src/main/java/com/lunhan/water/repository/impl/HeartbeatDataMapperImpl.java
@@ -0,0 +1,142 @@
+/**
+#                                                    __----~~~~~~~~~~~------___
+#                                   .  .   ~~//====......          __--~ ~~
+#                   -.            \_|//     |||\\  ~~~~~~::::... /~
+#                ___-==_       _-~o~  \/    |||  \\            _/~~-
+#        __---~~~.==~||\=_    -_--~/_-~|-   |\\   \\        _/~
+#    _-~~     .=~    |  \\-_    '-~7  /-   /  ||    \      /
+#  .~       .~       |   \\ -_    /  /-   /   ||      \   /
+# /  ____  /         |     \\ ~-_/  /|- _/   .||       \ /
+# |~~    ~~|--~~~~--_ \     ~==-/   | \~--===~~        .\
+#          '         ~-|      /|    |-~\~~       __--~~
+#                      |-~~-_/ |    |   ~\_   _-~            /\
+#                           /  \     \__   \/~                \__
+#                       _--~ _/ | .-~~____--~-/                  ~~==.
+#                      ((->/~   '.|||' -_|    ~~-/ ,              . _||
+#                                 -_     ~\      ~~---l__i__i__i--~~_/
+#                                 _-~-__   ~)  \--______________--~~
+#                               //.-~~~-~_--~- |-------~~~~~~~~
+#                                      //.-~~~--\
+#                  神兽保佑
+#                  永无BUG!
+*/
+package com.lunhan.water.repository.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.lunhan.water.common.PagerResult;
+import com.lunhan.water.common.enums.EYesOrNo;
+import com.lunhan.water.common.util.*;
+import com.lunhan.water.entity.dto.*;
+import com.lunhan.water.entity.enums.*;
+import com.lunhan.water.repository.BasicMapperImpl;
+import org.springframework.stereotype.Repository;
+
+import java.util.List;
+import com.lunhan.water.entity.search.SearchHeartbeatData;
+import com.lunhan.water.repository.mapper.HeartbeatDataMapper;
+import com.lunhan.water.repository.po.HeartbeatDataPO;
+
+/**
+ * HeartbeatData
+ * @author lin.liu
+ */
+@Repository
+public class HeartbeatDataMapperImpl extends BasicMapperImpl<HeartbeatDataPO, HeartbeatDataMapper> {
+	HeartbeatDataMapperImpl(HeartbeatDataMapper mapper) {
+		super(mapper);
+	}
+
+	@Override
+	public PagerResult<HeartbeatDataPO> search(SearchBasicDTO request) {
+		// 还原查询条件真实类型
+		SearchHeartbeatData search = (SearchHeartbeatData)request;
+		// 查询条件
+		LambdaQueryWrapper<HeartbeatDataPO> queryWrapper = this.query();
+		// 非逻辑删除
+		queryWrapper.eq(HeartbeatDataPO::getIsDelete, EYesOrNo.NO.getValue());
+		// 状态
+		//queryWrapper.eq(NumericUtil.tryParseInt(search.getStatus()).compareTo(0) > 0, HeartbeatDataPO::getStatus, search.getStatus());
+		// 状态列表
+		//queryWrapper.in(ListUtil.isNotNullOrEmpty(search.getListStatus()), HeartbeatDataPO::getStatus, search.getListStatus());
+
+		// 数据创建时间-起始
+		queryWrapper.ge(NumericUtil.tryParseLong(search.getCreateTimeStart()).compareTo(0L) > 0, HeartbeatDataPO::getCreateTime, search.getCreateTimeStart());
+		// 数据创建时间-截止
+		queryWrapper.le(NumericUtil.tryParseLong(search.getCreateTimeEnd()).compareTo(0L) > 0, HeartbeatDataPO::getCreateTime, search.getCreateTimeEnd());
+		// 关键字
+		//if (StringUtil.isNotNullOrEmpty(search.getKeywords())) {
+		//	queryWrapper.and(q ->
+		//		q.like(HeartbeatDataPO::getName, search.getKeywords())
+		//		.or().like(HeartbeatDataPO::getPhone, search.getKeywords())
+		//	);
+		//}
+
+		// 排序处理
+		if (ListUtil.isNotNullOrEmpty(search.getOrderBy())) {
+			for (OrderByDTO item : search.getOrderBy()) {
+				EOrderBy orderBy = EOrderBy.getByValue(item.getOrderBy());
+				// 顺序排序
+				if (item.getIsAsc()) {
+					switch (orderBy) {
+						// 主键
+						case ID:
+							queryWrapper.orderByAsc(HeartbeatDataPO::getId);
+							break;
+						// 数据创建时间
+						case CREATE_TIME:
+							queryWrapper.orderByAsc(HeartbeatDataPO::getCreateTime);
+							break;
+						// 最后更新时间
+						case UPDATE_TIME:
+							queryWrapper.orderByAsc(HeartbeatDataPO::getUpdateTime);
+							break;
+					}
+				} else {
+					// 倒叙排序
+					switch (orderBy) {
+						// 主键
+						case ID:
+							queryWrapper.orderByDesc(HeartbeatDataPO::getId);
+							break;
+						// 数据创建时间
+						case CREATE_TIME:
+							queryWrapper.orderByDesc(HeartbeatDataPO::getCreateTime);
+							break;
+						// 最后更新时间
+						case UPDATE_TIME:
+							queryWrapper.orderByDesc(HeartbeatDataPO::getUpdateTime);
+							break;
+					}
+				}
+			}
+		} else {
+			queryWrapper.orderByDesc(HeartbeatDataPO::getId);
+		}
+		Page<HeartbeatDataPO> pageResult = super.selectPage(new Page<>(search.getPage(), search.getLimit()), queryWrapper);
+		return new PagerResult<>(pageResult.getSize(), pageResult.getCurrent(), pageResult.getTotal(), pageResult.getRecords());
+	}
+
+	public Boolean add(HeartbeatDataPO item) {
+		int rowCount = super.insert(item);
+		return rowCount == 1;
+	}
+
+	public Boolean addNotIncrement(HeartbeatDataPO item) {
+		int rowCount = super.insert(item);
+		return rowCount == 1;
+	}
+
+	public HeartbeatDataPO getById(Long id) {
+		return super.get(id);
+	}
+	public HeartbeatDataPO getByKey(String key) {
+		LambdaQueryWrapper<HeartbeatDataPO> queryWrapper = this.query();
+		queryWrapper.eq(HeartbeatDataPO::getDataKey,key);
+		return super.selectOne(queryWrapper);
+	}
+
+	public List<HeartbeatDataPO> getListById(List<Long> listId) {
+		return super.getList(listId);
+	}
+}
diff --git a/src/main/java/com/lunhan/water/repository/impl/PaymentRecordsMapperImpl.java b/src/main/java/com/lunhan/water/repository/impl/PaymentRecordsMapperImpl.java
index 9567fc2..6a9b56e 100644
--- a/src/main/java/com/lunhan/water/repository/impl/PaymentRecordsMapperImpl.java
+++ b/src/main/java/com/lunhan/water/repository/impl/PaymentRecordsMapperImpl.java
@@ -32,6 +32,7 @@
 import com.lunhan.water.repository.BasicMapperImpl;
 import org.springframework.stereotype.Repository;
 
+import java.math.BigDecimal;
 import java.util.List;
 import com.lunhan.water.entity.search.SearchPaymentRecords;
 import com.lunhan.water.repository.mapper.PaymentRecordsMapper;
@@ -55,8 +56,9 @@
 		LambdaQueryWrapper<PaymentRecordsPO> queryWrapper = this.query();
 		// 非逻辑删除
 		queryWrapper.eq(PaymentRecordsPO::getIsDelete, EYesOrNo.NO.getValue());
-		// 状态
-		//queryWrapper.eq(NumericUtil.tryParseInt(search.getStatus()).compareTo(0) > 0, PaymentRecordsPO::getStatus, search.getStatus());
+		// 用户id查询
+		queryWrapper.ge(NumericUtil.tryParseLong(search.getUserId()).compareTo(0L) > 0, PaymentRecordsPO::getUserId, search.getUserId());
+
 		// 状态列表
 		//queryWrapper.in(ListUtil.isNotNullOrEmpty(search.getListStatus()), PaymentRecordsPO::getStatus, search.getListStatus());
 
@@ -130,6 +132,10 @@
 	public PaymentRecordsPO getById(Long id) {
 		return super.get(id);
 	}
+	public BigDecimal getSumUseCount(Long userId) {
+		return DB.getSumUseCount(userId);
+	}
+
 
 	public List<PaymentRecordsPO> getListById(List<Long> listId) {
 		return super.getList(listId);
diff --git a/src/main/java/com/lunhan/water/repository/impl/RechargeRecordsMapperImpl.java b/src/main/java/com/lunhan/water/repository/impl/RechargeRecordsMapperImpl.java
index db1a75c..4179ca5 100644
--- a/src/main/java/com/lunhan/water/repository/impl/RechargeRecordsMapperImpl.java
+++ b/src/main/java/com/lunhan/water/repository/impl/RechargeRecordsMapperImpl.java
@@ -32,6 +32,7 @@
 import com.lunhan.water.repository.BasicMapperImpl;
 import org.springframework.stereotype.Repository;
 
+import java.math.BigDecimal;
 import java.util.List;
 import com.lunhan.water.entity.search.SearchRechargeRecords;
 import com.lunhan.water.repository.mapper.RechargeRecordsMapper;
@@ -56,7 +57,7 @@
 		// 非逻辑删除
 		queryWrapper.eq(RechargeRecordsPO::getIsDelete, EYesOrNo.NO.getValue());
 		// 状态
-		//queryWrapper.eq(NumericUtil.tryParseInt(search.getStatus()).compareTo(0) > 0, RechargeRecordsPO::getStatus, search.getStatus());
+		queryWrapper.ge(NumericUtil.tryParseLong(search.getUserId()).compareTo(0L) > 0, RechargeRecordsPO::getUserId, search.getUserId());
 		// 状态列表
 		//queryWrapper.in(ListUtil.isNotNullOrEmpty(search.getListStatus()), RechargeRecordsPO::getStatus, search.getListStatus());
 
@@ -132,10 +133,13 @@
 				.eq(RechargeRecordsPO::getRechargeStatus,0);
 		return DB.selectOne(queryWrapper);
 	}
+
 	public RechargeRecordsPO getById(Long id) {
 		return super.get(id);
 	}
-
+	public BigDecimal getSumBuyCount(Long userId){
+		return DB.getSumBuyCount(userId);
+	}
 	public List<RechargeRecordsPO> getListById(List<Long> listId) {
 		return super.getList(listId);
 	}
diff --git a/src/main/java/com/lunhan/water/repository/impl/ThirdNotifyMapperImpl.java b/src/main/java/com/lunhan/water/repository/impl/ThirdNotifyMapperImpl.java
new file mode 100644
index 0000000..68cc87f
--- /dev/null
+++ b/src/main/java/com/lunhan/water/repository/impl/ThirdNotifyMapperImpl.java
@@ -0,0 +1,142 @@
+/**
+#                                                    __----~~~~~~~~~~~------___
+#                                   .  .   ~~//====......          __--~ ~~
+#                   -.            \_|//     |||\\  ~~~~~~::::... /~
+#                ___-==_       _-~o~  \/    |||  \\            _/~~-
+#        __---~~~.==~||\=_    -_--~/_-~|-   |\\   \\        _/~
+#    _-~~     .=~    |  \\-_    '-~7  /-   /  ||    \      /
+#  .~       .~       |   \\ -_    /  /-   /   ||      \   /
+# /  ____  /         |     \\ ~-_/  /|- _/   .||       \ /
+# |~~    ~~|--~~~~--_ \     ~==-/   | \~--===~~        .\
+#          '         ~-|      /|    |-~\~~       __--~~
+#                      |-~~-_/ |    |   ~\_   _-~            /\
+#                           /  \     \__   \/~                \__
+#                       _--~ _/ | .-~~____--~-/                  ~~==.
+#                      ((->/~   '.|||' -_|    ~~-/ ,              . _||
+#                                 -_     ~\      ~~---l__i__i__i--~~_/
+#                                 _-~-__   ~)  \--______________--~~
+#                               //.-~~~-~_--~- |-------~~~~~~~~
+#                                      //.-~~~--\
+#                  神兽保佑
+#                  永无BUG!
+*/
+package com.lunhan.water.repository.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.lunhan.water.common.PagerResult;
+import com.lunhan.water.common.enums.EYesOrNo;
+import com.lunhan.water.common.util.*;
+import com.lunhan.water.entity.dto.*;
+import com.lunhan.water.entity.enums.*;
+import com.lunhan.water.repository.BasicMapperImpl;
+import org.springframework.stereotype.Repository;
+
+import java.util.List;
+import com.lunhan.water.entity.search.SearchThirdNotify;
+import com.lunhan.water.repository.mapper.ThirdNotifyMapper;
+import com.lunhan.water.repository.po.ThirdNotifyPO;
+
+/**
+ * 第三方支付通知记录
+ * @author lin.liu
+ */
+@Repository
+public class ThirdNotifyMapperImpl extends BasicMapperImpl<ThirdNotifyPO, ThirdNotifyMapper> {
+	ThirdNotifyMapperImpl(ThirdNotifyMapper mapper) {
+		super(mapper);
+	}
+
+	@Override
+	public PagerResult<ThirdNotifyPO> search(SearchBasicDTO request) {
+		// 还原查询条件真实类型
+		SearchThirdNotify search = (SearchThirdNotify)request;
+		// 查询条件
+		LambdaQueryWrapper<ThirdNotifyPO> queryWrapper = this.query();
+		// 非逻辑删除
+		queryWrapper.eq(ThirdNotifyPO::getIsDelete, EYesOrNo.NO.getValue());
+		// 状态
+		//queryWrapper.eq(NumericUtil.tryParseInt(search.getStatus()).compareTo(0) > 0, ThirdNotifyPO::getStatus, search.getStatus());
+		// 状态列表
+		//queryWrapper.in(ListUtil.isNotNullOrEmpty(search.getListStatus()), ThirdNotifyPO::getStatus, search.getListStatus());
+
+		// 数据创建时间-起始
+		queryWrapper.ge(NumericUtil.tryParseLong(search.getCreateTimeStart()).compareTo(0L) > 0, ThirdNotifyPO::getCreateTime, search.getCreateTimeStart());
+		// 数据创建时间-截止
+		queryWrapper.le(NumericUtil.tryParseLong(search.getCreateTimeEnd()).compareTo(0L) > 0, ThirdNotifyPO::getCreateTime, search.getCreateTimeEnd());
+		// 关键字
+		//if (StringUtil.isNotNullOrEmpty(search.getKeywords())) {
+		//	queryWrapper.and(q ->
+		//		q.like(ThirdNotifyPO::getName, search.getKeywords())
+		//		.or().like(ThirdNotifyPO::getPhone, search.getKeywords())
+		//	);
+		//}
+
+		// 排序处理
+		if (ListUtil.isNotNullOrEmpty(search.getOrderBy())) {
+			for (OrderByDTO item : search.getOrderBy()) {
+				EOrderBy orderBy = EOrderBy.getByValue(item.getOrderBy());
+				// 顺序排序
+				if (item.getIsAsc()) {
+					switch (orderBy) {
+						// 主键
+						case ID:
+							queryWrapper.orderByAsc(ThirdNotifyPO::getId);
+							break;
+						// 数据创建时间
+						case CREATE_TIME:
+							queryWrapper.orderByAsc(ThirdNotifyPO::getCreateTime);
+							break;
+						// 最后更新时间
+						case UPDATE_TIME:
+							queryWrapper.orderByAsc(ThirdNotifyPO::getUpdateTime);
+							break;
+					}
+				} else {
+					// 倒叙排序
+					switch (orderBy) {
+						// 主键
+						case ID:
+							queryWrapper.orderByDesc(ThirdNotifyPO::getId);
+							break;
+						// 数据创建时间
+						case CREATE_TIME:
+							queryWrapper.orderByDesc(ThirdNotifyPO::getCreateTime);
+							break;
+						// 最后更新时间
+						case UPDATE_TIME:
+							queryWrapper.orderByDesc(ThirdNotifyPO::getUpdateTime);
+							break;
+					}
+				}
+			}
+		} else {
+			queryWrapper.orderByDesc(ThirdNotifyPO::getId);
+		}
+		Page<ThirdNotifyPO> pageResult = super.selectPage(new Page<>(search.getPage(), search.getLimit()), queryWrapper);
+		return new PagerResult<>(pageResult.getSize(), pageResult.getCurrent(), pageResult.getTotal(), pageResult.getRecords());
+	}
+
+	public Boolean add(ThirdNotifyPO item) {
+		int rowCount = super.insert(item);
+		return rowCount == 1;
+	}
+	public ThirdNotifyPO get4Md5(String md5) {
+		LambdaQueryWrapper<ThirdNotifyPO> queryWrapper = this.query();
+		queryWrapper.eq(ThirdNotifyPO::getMd5,md5);
+		//return super.get(new SqlBuilder().where(EThirdNotify.MD5.equal(md5)));
+		return super.selectOne(queryWrapper);
+	}
+	public Boolean addNotIncrement(ThirdNotifyPO item) {
+		int rowCount = super.insert(item);
+		return rowCount == 1;
+	}
+
+	public ThirdNotifyPO getById(Long id) {
+		return super.get(id);
+	}
+
+	public List<ThirdNotifyPO> getListById(List<Long> listId) {
+		return super.getList(listId);
+	}
+}
diff --git a/src/main/java/com/lunhan/water/repository/impl/UserLoginMapperImpl.java b/src/main/java/com/lunhan/water/repository/impl/UserLoginMapperImpl.java
index 7d5c29b..4e16da9 100644
--- a/src/main/java/com/lunhan/water/repository/impl/UserLoginMapperImpl.java
+++ b/src/main/java/com/lunhan/water/repository/impl/UserLoginMapperImpl.java
@@ -1,25 +1,25 @@
 /**
-#                                                    __----~~~~~~~~~~~------___
-#                                   .  .   ~~//====......          __--~ ~~
-#                   -.            \_|//     |||\\  ~~~~~~::::... /~
-#                ___-==_       _-~o~  \/    |||  \\            _/~~-
-#        __---~~~.==~||\=_    -_--~/_-~|-   |\\   \\        _/~
-#    _-~~     .=~    |  \\-_    '-~7  /-   /  ||    \      /
-#  .~       .~       |   \\ -_    /  /-   /   ||      \   /
-# /  ____  /         |     \\ ~-_/  /|- _/   .||       \ /
-# |~~    ~~|--~~~~--_ \     ~==-/   | \~--===~~        .\
-#          '         ~-|      /|    |-~\~~       __--~~
-#                      |-~~-_/ |    |   ~\_   _-~            /\
-#                           /  \     \__   \/~                \__
-#                       _--~ _/ | .-~~____--~-/                  ~~==.
-#                      ((->/~   '.|||' -_|    ~~-/ ,              . _||
-#                                 -_     ~\      ~~---l__i__i__i--~~_/
-#                                 _-~-__   ~)  \--______________--~~
-#                               //.-~~~-~_--~- |-------~~~~~~~~
-#                                      //.-~~~--\
-#                  神兽保佑
-#                  永无BUG!
-*/
+ #                                                    __----~~~~~~~~~~~------___
+ #                                   .  .   ~~//====......          __--~ ~~
+ #                   -.            \_|//     |||\\  ~~~~~~::::... /~
+ #                ___-==_       _-~o~  \/    |||  \\            _/~~-
+ #        __---~~~.==~||\=_    -_--~/_-~|-   |\\   \\        _/~
+ #    _-~~     .=~    |  \\-_    '-~7  /-   /  ||    \      /
+ #  .~       .~       |   \\ -_    /  /-   /   ||      \   /
+ # /  ____  /         |     \\ ~-_/  /|- _/   .||       \ /
+ # |~~    ~~|--~~~~--_ \     ~==-/   | \~--===~~        .\
+ #          '         ~-|      /|    |-~\~~       __--~~
+ #                      |-~~-_/ |    |   ~\_   _-~            /\
+ #                           /  \     \__   \/~                \__
+ #                       _--~ _/ | .-~~____--~-/                  ~~==.
+ #                      ((->/~   '.|||' -_|    ~~-/ ,              . _||
+ #                                 -_     ~\      ~~---l__i__i__i--~~_/
+ #                                 _-~-__   ~)  \--______________--~~
+ #                               //.-~~~-~_--~- |-------~~~~~~~~
+ #                                      //.-~~~--\
+ #                  神兽保佑
+ #                  永无BUG!
+ */
 package com.lunhan.water.repository.impl;
 
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
@@ -33,6 +33,7 @@
 import org.springframework.stereotype.Repository;
 
 import java.util.List;
+
 import com.lunhan.water.entity.search.SearchUserLogin;
 import com.lunhan.water.repository.mapper.UserLoginMapper;
 import com.lunhan.water.repository.po.UserLoginPO;
@@ -43,104 +44,118 @@
  */
 @Repository
 public class UserLoginMapperImpl extends BasicMapperImpl<UserLoginPO, UserLoginMapper> {
-	UserLoginMapperImpl(UserLoginMapper mapper) {
-		super(mapper);
-	}
+    UserLoginMapperImpl(UserLoginMapper mapper) {
+        super(mapper);
+    }
 
-	@Override
-	public PagerResult<UserLoginPO> search(SearchBasicDTO request) {
-		// 还原查询条件真实类型
-		SearchUserLogin search = (SearchUserLogin)request;
-		// 查询条件
-		LambdaQueryWrapper<UserLoginPO> queryWrapper = this.query();
-		// 非逻辑删除
-		queryWrapper.eq(UserLoginPO::getIsDelete, EYesOrNo.NO.getValue());
-		// 状态
-		//queryWrapper.eq(NumericUtil.tryParseInt(search.getStatus()).compareTo(0) > 0, UserLoginPO::getStatus, search.getStatus());
-		// 状态列表
-		//queryWrapper.in(ListUtil.isNotNullOrEmpty(search.getListStatus()), UserLoginPO::getStatus, search.getListStatus());
+    @Override
+    public PagerResult<UserLoginPO> search(SearchBasicDTO request) {
+        // 还原查询条件真实类型
+        SearchUserLogin search = (SearchUserLogin) request;
+        // 查询条件
+        LambdaQueryWrapper<UserLoginPO> queryWrapper = this.query();
+        // 非逻辑删除
+        queryWrapper.eq(UserLoginPO::getIsDelete, EYesOrNo.NO.getValue());
+        // 状态
+        //queryWrapper.eq(NumericUtil.tryParseInt(search.getStatus()).compareTo(0) > 0, UserLoginPO::getStatus, search.getStatus());
+        // 状态列表
+        //queryWrapper.in(ListUtil.isNotNullOrEmpty(search.getListStatus()), UserLoginPO::getStatus, search.getListStatus());
 
-		// 数据创建时间-起始
-		queryWrapper.ge(NumericUtil.tryParseLong(search.getCreateTimeStart()).compareTo(0L) > 0, UserLoginPO::getCreateTime, search.getCreateTimeStart());
-		// 数据创建时间-截止
-		queryWrapper.le(NumericUtil.tryParseLong(search.getCreateTimeEnd()).compareTo(0L) > 0, UserLoginPO::getCreateTime, search.getCreateTimeEnd());
-		// 关键字
-		//if (StringUtil.isNotNullOrEmpty(search.getKeywords())) {
-		//	queryWrapper.and(q ->
-		//		q.like(UserLoginPO::getName, search.getKeywords())
-		//		.or().like(UserLoginPO::getPhone, search.getKeywords())
-		//	);
-		//}
+        // 数据创建时间-起始
+        queryWrapper.ge(NumericUtil.tryParseLong(search.getCreateTimeStart()).compareTo(0L) > 0, UserLoginPO::getCreateTime, search.getCreateTimeStart());
+        // 数据创建时间-截止
+        queryWrapper.le(NumericUtil.tryParseLong(search.getCreateTimeEnd()).compareTo(0L) > 0, UserLoginPO::getCreateTime, search.getCreateTimeEnd());
+        // 关键字
+        //if (StringUtil.isNotNullOrEmpty(search.getKeywords())) {
+        //	queryWrapper.and(q ->
+        //		q.like(UserLoginPO::getName, search.getKeywords())
+        //		.or().like(UserLoginPO::getPhone, search.getKeywords())
+        //	);
+        //}
 
-		// 排序处理
-		if (ListUtil.isNotNullOrEmpty(search.getOrderBy())) {
-			for (OrderByDTO item : search.getOrderBy()) {
-				EOrderBy orderBy = EOrderBy.getByValue(item.getOrderBy());
-				// 顺序排序
-				if (item.getIsAsc()) {
-					switch (orderBy) {
-						// 主键
-						case ID:
-							queryWrapper.orderByAsc(UserLoginPO::getId);
-							break;
-						// 数据创建时间
-						case CREATE_TIME:
-							queryWrapper.orderByAsc(UserLoginPO::getCreateTime);
-							break;
-						// 最后更新时间
-						case UPDATE_TIME:
-							queryWrapper.orderByAsc(UserLoginPO::getUpdateTime);
-							break;
-					}
-				} else {
-					// 倒叙排序
-					switch (orderBy) {
-						// 主键
-						case ID:
-							queryWrapper.orderByDesc(UserLoginPO::getId);
-							break;
-						// 数据创建时间
-						case CREATE_TIME:
-							queryWrapper.orderByDesc(UserLoginPO::getCreateTime);
-							break;
-						// 最后更新时间
-						case UPDATE_TIME:
-							queryWrapper.orderByDesc(UserLoginPO::getUpdateTime);
-							break;
-					}
-				}
-			}
-		} else {
-			queryWrapper.orderByDesc(UserLoginPO::getId);
-		}
-		Page<UserLoginPO> pageResult = super.selectPage(new Page<>(search.getPage(), search.getLimit()), queryWrapper);
-		return new PagerResult<>(pageResult.getSize(), pageResult.getCurrent(), pageResult.getTotal(), pageResult.getRecords());
-	}
+        // 排序处理
+        if (ListUtil.isNotNullOrEmpty(search.getOrderBy())) {
+            for (OrderByDTO item : search.getOrderBy()) {
+                EOrderBy orderBy = EOrderBy.getByValue(item.getOrderBy());
+                // 顺序排序
+                if (item.getIsAsc()) {
+                    switch (orderBy) {
+                        // 主键
+                        case ID:
+                            queryWrapper.orderByAsc(UserLoginPO::getId);
+                            break;
+                        // 数据创建时间
+                        case CREATE_TIME:
+                            queryWrapper.orderByAsc(UserLoginPO::getCreateTime);
+                            break;
+                        // 最后更新时间
+                        case UPDATE_TIME:
+                            queryWrapper.orderByAsc(UserLoginPO::getUpdateTime);
+                            break;
+                    }
+                } else {
+                    // 倒叙排序
+                    switch (orderBy) {
+                        // 主键
+                        case ID:
+                            queryWrapper.orderByDesc(UserLoginPO::getId);
+                            break;
+                        // 数据创建时间
+                        case CREATE_TIME:
+                            queryWrapper.orderByDesc(UserLoginPO::getCreateTime);
+                            break;
+                        // 最后更新时间
+                        case UPDATE_TIME:
+                            queryWrapper.orderByDesc(UserLoginPO::getUpdateTime);
+                            break;
+                    }
+                }
+            }
+        } else {
+            queryWrapper.orderByDesc(UserLoginPO::getId);
+        }
+        Page<UserLoginPO> pageResult = super.selectPage(new Page<>(search.getPage(), search.getLimit()), queryWrapper);
+        return new PagerResult<>(pageResult.getSize(), pageResult.getCurrent(), pageResult.getTotal(), pageResult.getRecords());
+    }
 
-	public Boolean add(UserLoginPO item) {
-		int rowCount = super.insert(item);
-		return rowCount == 1;
-	}
+    public Boolean add(UserLoginPO item) {
+        int rowCount = super.insert(item);
+        return rowCount == 1;
+    }
 
-	public Boolean addNotIncrement(UserLoginPO item) {
-		int rowCount = super.insert(item);
-		return rowCount == 1;
-	}
+    public Boolean addNotIncrement(UserLoginPO item) {
+        int rowCount = super.insert(item);
+        return rowCount == 1;
+    }
 
-	public UserLoginPO getById(Long id) {
-		return super.get(id);
-	}
-	public UserLoginPO get4Openid(String openId) {
-		LambdaQueryWrapper<UserLoginPO> queryWrapper = this.query();
-		queryWrapper.eq(UserLoginPO::getWxOpenId, openId);
-		return DB.selectOne(queryWrapper);
-	}
-	public UserLoginPO get4UserName(String userName) {
-		LambdaQueryWrapper<UserLoginPO> queryWrapper = this.query();
-		queryWrapper.eq(UserLoginPO::getUserName, userName);
-		return DB.selectOne(queryWrapper);
-	}
-	public List<UserLoginPO> getListById(List<Long> listId) {
-		return super.getList(listId);
-	}
+    public UserLoginPO getById(Long id) {
+        return super.get(id);
+    }
+
+    public UserLoginPO get4Openid(String openId) {
+        LambdaQueryWrapper<UserLoginPO> queryWrapper = this.query();
+        queryWrapper.eq(UserLoginPO::getWxOpenId, openId);
+        return DB.selectOne(queryWrapper);
+    }
+
+    public UserLoginPO get4UserName(String userName) {
+        LambdaQueryWrapper<UserLoginPO> queryWrapper = this.query();
+        queryWrapper.eq(UserLoginPO::getUserName, userName);
+        return DB.selectOne(queryWrapper);
+    }
+    public UserLoginPO get4UserCode(String userCode) {
+        LambdaQueryWrapper<UserLoginPO> queryWrapper = this.query();
+        queryWrapper.eq(UserLoginPO::getUserCode, userCode);
+        return DB.selectOne(queryWrapper);
+    }
+    public UserLoginPO getOrderByDesc() {
+        LambdaQueryWrapper<UserLoginPO> queryWrapper = this.query();
+        queryWrapper.orderByDesc(UserLoginPO::getUserCode);
+        queryWrapper.last("limit 1");
+        return DB.selectOne(queryWrapper);
+    }
+
+    public List<UserLoginPO> getListById(List<Long> listId) {
+        return super.getList(listId);
+    }
 }
diff --git a/src/main/java/com/lunhan/water/repository/impl/WaterFacilityMapperImpl.java b/src/main/java/com/lunhan/water/repository/impl/WaterFacilityMapperImpl.java
new file mode 100644
index 0000000..0b76875
--- /dev/null
+++ b/src/main/java/com/lunhan/water/repository/impl/WaterFacilityMapperImpl.java
@@ -0,0 +1,142 @@
+/**
+#                                                    __----~~~~~~~~~~~------___
+#                                   .  .   ~~//====......          __--~ ~~
+#                   -.            \_|//     |||\\  ~~~~~~::::... /~
+#                ___-==_       _-~o~  \/    |||  \\            _/~~-
+#        __---~~~.==~||\=_    -_--~/_-~|-   |\\   \\        _/~
+#    _-~~     .=~    |  \\-_    '-~7  /-   /  ||    \      /
+#  .~       .~       |   \\ -_    /  /-   /   ||      \   /
+# /  ____  /         |     \\ ~-_/  /|- _/   .||       \ /
+# |~~    ~~|--~~~~--_ \     ~==-/   | \~--===~~        .\
+#          '         ~-|      /|    |-~\~~       __--~~
+#                      |-~~-_/ |    |   ~\_   _-~            /\
+#                           /  \     \__   \/~                \__
+#                       _--~ _/ | .-~~____--~-/                  ~~==.
+#                      ((->/~   '.|||' -_|    ~~-/ ,              . _||
+#                                 -_     ~\      ~~---l__i__i__i--~~_/
+#                                 _-~-__   ~)  \--______________--~~
+#                               //.-~~~-~_--~- |-------~~~~~~~~
+#                                      //.-~~~--\
+#                  神兽保佑
+#                  永无BUG!
+*/
+package com.lunhan.water.repository.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.lunhan.water.common.PagerResult;
+import com.lunhan.water.common.enums.EYesOrNo;
+import com.lunhan.water.common.util.*;
+import com.lunhan.water.entity.dto.*;
+import com.lunhan.water.entity.enums.*;
+import com.lunhan.water.repository.BasicMapperImpl;
+import org.springframework.stereotype.Repository;
+
+import java.util.List;
+import com.lunhan.water.entity.search.SearchWaterFacility;
+import com.lunhan.water.repository.mapper.WaterFacilityMapper;
+import com.lunhan.water.repository.po.WaterFacilityPO;
+
+/**
+ * 设备表
+ * @author lin.liu
+ */
+@Repository
+public class WaterFacilityMapperImpl extends BasicMapperImpl<WaterFacilityPO, WaterFacilityMapper> {
+	WaterFacilityMapperImpl(WaterFacilityMapper mapper) {
+		super(mapper);
+	}
+
+	@Override
+	public PagerResult<WaterFacilityPO> search(SearchBasicDTO request) {
+		// 还原查询条件真实类型
+		SearchWaterFacility search = (SearchWaterFacility)request;
+		// 查询条件
+		LambdaQueryWrapper<WaterFacilityPO> queryWrapper = this.query();
+		// 非逻辑删除
+		queryWrapper.eq(WaterFacilityPO::getIsDelete, EYesOrNo.NO.getValue());
+		// 状态
+		//queryWrapper.eq(NumericUtil.tryParseInt(search.getStatus()).compareTo(0) > 0, WaterFacilityPO::getStatus, search.getStatus());
+		// 状态列表
+		//queryWrapper.in(ListUtil.isNotNullOrEmpty(search.getListStatus()), WaterFacilityPO::getStatus, search.getListStatus());
+
+		// 数据创建时间-起始
+		queryWrapper.ge(NumericUtil.tryParseLong(search.getCreateTimeStart()).compareTo(0L) > 0, WaterFacilityPO::getCreateTime, search.getCreateTimeStart());
+		// 数据创建时间-截止
+		queryWrapper.le(NumericUtil.tryParseLong(search.getCreateTimeEnd()).compareTo(0L) > 0, WaterFacilityPO::getCreateTime, search.getCreateTimeEnd());
+		// 关键字
+		//if (StringUtil.isNotNullOrEmpty(search.getKeywords())) {
+		//	queryWrapper.and(q ->
+		//		q.like(WaterFacilityPO::getName, search.getKeywords())
+		//		.or().like(WaterFacilityPO::getPhone, search.getKeywords())
+		//	);
+		//}
+
+		// 排序处理
+		if (ListUtil.isNotNullOrEmpty(search.getOrderBy())) {
+			for (OrderByDTO item : search.getOrderBy()) {
+				EOrderBy orderBy = EOrderBy.getByValue(item.getOrderBy());
+				// 顺序排序
+				if (item.getIsAsc()) {
+					switch (orderBy) {
+						// 主键
+						case ID:
+							queryWrapper.orderByAsc(WaterFacilityPO::getId);
+							break;
+						// 数据创建时间
+						case CREATE_TIME:
+							queryWrapper.orderByAsc(WaterFacilityPO::getCreateTime);
+							break;
+						// 最后更新时间
+						case UPDATE_TIME:
+							queryWrapper.orderByAsc(WaterFacilityPO::getUpdateTime);
+							break;
+					}
+				} else {
+					// 倒叙排序
+					switch (orderBy) {
+						// 主键
+						case ID:
+							queryWrapper.orderByDesc(WaterFacilityPO::getId);
+							break;
+						// 数据创建时间
+						case CREATE_TIME:
+							queryWrapper.orderByDesc(WaterFacilityPO::getCreateTime);
+							break;
+						// 最后更新时间
+						case UPDATE_TIME:
+							queryWrapper.orderByDesc(WaterFacilityPO::getUpdateTime);
+							break;
+					}
+				}
+			}
+		} else {
+			queryWrapper.orderByDesc(WaterFacilityPO::getId);
+		}
+		Page<WaterFacilityPO> pageResult = super.selectPage(new Page<>(search.getPage(), search.getLimit()), queryWrapper);
+		return new PagerResult<>(pageResult.getSize(), pageResult.getCurrent(), pageResult.getTotal(), pageResult.getRecords());
+	}
+
+	public Boolean add(WaterFacilityPO item) {
+		int rowCount = super.insert(item);
+		return rowCount == 1;
+	}
+
+	public Boolean addNotIncrement(WaterFacilityPO item) {
+		int rowCount = super.insert(item);
+		return rowCount == 1;
+	}
+
+	public WaterFacilityPO getById(Long id) {
+		return super.get(id);
+	}
+	public WaterFacilityPO getCode(String  code) {
+		// 查询条件
+		LambdaQueryWrapper<WaterFacilityPO> queryWrapper = this.query();
+		queryWrapper.eq(WaterFacilityPO::getFacilityCode,code);
+		return super.selectOne(queryWrapper);
+	}
+	public List<WaterFacilityPO> getListById(List<Long> listId) {
+		return super.getList(listId);
+	}
+}
diff --git a/src/main/java/com/lunhan/water/repository/mapper/FacilityAlarmRecordMapper.java b/src/main/java/com/lunhan/water/repository/mapper/FacilityAlarmRecordMapper.java
new file mode 100644
index 0000000..6f849f4
--- /dev/null
+++ b/src/main/java/com/lunhan/water/repository/mapper/FacilityAlarmRecordMapper.java
@@ -0,0 +1,10 @@
+package com.lunhan.water.repository.mapper;
+
+import com.lunhan.water.repository.BasicMapper;import com.lunhan.water.repository.po.FacilityAlarmRecordPO;
+
+/**
+ * 设备报警记录 mapper
+ * @author lin.liu
+ */
+public interface FacilityAlarmRecordMapper extends BasicMapper<FacilityAlarmRecordPO> {
+}
diff --git a/src/main/java/com/lunhan/water/repository/mapper/HeartbeatDataMapper.java b/src/main/java/com/lunhan/water/repository/mapper/HeartbeatDataMapper.java
new file mode 100644
index 0000000..ab6ffa9
--- /dev/null
+++ b/src/main/java/com/lunhan/water/repository/mapper/HeartbeatDataMapper.java
@@ -0,0 +1,10 @@
+package com.lunhan.water.repository.mapper;
+
+import com.lunhan.water.repository.BasicMapper;import com.lunhan.water.repository.po.HeartbeatDataPO;
+
+/**
+ * HeartbeatData
+ * @author lin.liu
+ */
+public interface HeartbeatDataMapper extends BasicMapper<HeartbeatDataPO> {
+}
diff --git a/src/main/java/com/lunhan/water/repository/mapper/PaymentRecordsMapper.java b/src/main/java/com/lunhan/water/repository/mapper/PaymentRecordsMapper.java
index 2cec504..6d0fa90 100644
--- a/src/main/java/com/lunhan/water/repository/mapper/PaymentRecordsMapper.java
+++ b/src/main/java/com/lunhan/water/repository/mapper/PaymentRecordsMapper.java
@@ -1,10 +1,16 @@
 package com.lunhan.water.repository.mapper;
 
-import com.lunhan.water.repository.BasicMapper;import com.lunhan.water.repository.po.PaymentRecordsPO;
+import com.lunhan.water.repository.BasicMapper;
+import com.lunhan.water.repository.po.PaymentRecordsPO;
+import org.apache.ibatis.annotations.Select;
+
+import java.math.BigDecimal;
 
 /**
  * PaymentRecords
  * @author lin.liu
  */
 public interface PaymentRecordsMapper extends BasicMapper<PaymentRecordsPO> {
+    @Select("SELECT COALESCE(SUM(water_amount),0) FROM payment_records WHERE user_id=#{userId}")
+     BigDecimal getSumUseCount(Long userId);
 }
diff --git a/src/main/java/com/lunhan/water/repository/mapper/RechargeRecordsMapper.java b/src/main/java/com/lunhan/water/repository/mapper/RechargeRecordsMapper.java
index 8090db9..e457c59 100644
--- a/src/main/java/com/lunhan/water/repository/mapper/RechargeRecordsMapper.java
+++ b/src/main/java/com/lunhan/water/repository/mapper/RechargeRecordsMapper.java
@@ -1,10 +1,16 @@
 package com.lunhan.water.repository.mapper;
 
 import com.lunhan.water.repository.BasicMapper;import com.lunhan.water.repository.po.RechargeRecordsPO;
+import org.apache.ibatis.annotations.Select;
+
+import java.math.BigDecimal;
 
 /**
  * 充值记录 mapper
  * @author lin.liu
  */
 public interface RechargeRecordsMapper extends BasicMapper<RechargeRecordsPO> {
+   @Select("SELECT COALESCE(SUM(recharge_water),0) FROM recharge_records WHERE user_id=#{userId}")
+    BigDecimal getSumBuyCount(Long userId);
+
 }
diff --git a/src/main/java/com/lunhan/water/repository/mapper/ThirdNotifyMapper.java b/src/main/java/com/lunhan/water/repository/mapper/ThirdNotifyMapper.java
new file mode 100644
index 0000000..43501c2
--- /dev/null
+++ b/src/main/java/com/lunhan/water/repository/mapper/ThirdNotifyMapper.java
@@ -0,0 +1,10 @@
+package com.lunhan.water.repository.mapper;
+
+import com.lunhan.water.repository.BasicMapper;import com.lunhan.water.repository.po.ThirdNotifyPO;
+
+/**
+ * 第三方支付通知记录 mapper
+ * @author lin.liu
+ */
+public interface ThirdNotifyMapper extends BasicMapper<ThirdNotifyPO> {
+}
diff --git a/src/main/java/com/lunhan/water/repository/mapper/WaterFacilityMapper.java b/src/main/java/com/lunhan/water/repository/mapper/WaterFacilityMapper.java
new file mode 100644
index 0000000..84f0e55
--- /dev/null
+++ b/src/main/java/com/lunhan/water/repository/mapper/WaterFacilityMapper.java
@@ -0,0 +1,10 @@
+package com.lunhan.water.repository.mapper;
+
+import com.lunhan.water.repository.BasicMapper;import com.lunhan.water.repository.po.WaterFacilityPO;
+
+/**
+ * 设备表 mapper
+ * @author lin.liu
+ */
+public interface WaterFacilityMapper extends BasicMapper<WaterFacilityPO> {
+}
diff --git a/src/main/java/com/lunhan/water/repository/po/FacilityAlarmRecordPO.java b/src/main/java/com/lunhan/water/repository/po/FacilityAlarmRecordPO.java
new file mode 100644
index 0000000..5935478
--- /dev/null
+++ b/src/main/java/com/lunhan/water/repository/po/FacilityAlarmRecordPO.java
@@ -0,0 +1,109 @@
+/**
+#                                                    __----~~~~~~~~~~~------___
+#                                   .  .   ~~//====......          __--~ ~~
+#                   -.            \_|//     |||\\  ~~~~~~::::... /~
+#                ___-==_       _-~o~  \/    |||  \\            _/~~-
+#        __---~~~.==~||\=_    -_--~/_-~|-   |\\   \\        _/~
+#    _-~~     .=~    |  \\-_    '-~7  /-   /  ||    \      /
+#  .~       .~       |   \\ -_    /  /-   /   ||      \   /
+# /  ____  /         |     \\ ~-_/  /|- _/   .||       \ /
+# |~~    ~~|--~~~~--_ \     ~==-/   | \~--===~~        .\
+#          '         ~-|      /|    |-~\~~       __--~~
+#                      |-~~-_/ |    |   ~\_   _-~            /\
+#                           /  \     \__   \/~                \__
+#                       _--~ _/ | .-~~____--~-/                  ~~==.
+#                      ((->/~   '.|||' -_|    ~~-/ ,              . _||
+#                                 -_     ~\      ~~---l__i__i__i--~~_/
+#                                 _-~-__   ~)  \--______________--~~
+#                               //.-~~~-~_--~- |-------~~~~~~~~
+#                                      //.-~~~--\
+#                  神兽保佑
+#                  永无BUG!
+*/
+package com.lunhan.water.repository.po;
+
+import lombok.Data;
+
+import com.baomidou.mybatisplus.annotation.*;
+
+import java.io.Serializable;
+import java.sql.Timestamp;
+
+/**
+ * 设备报警记录
+ * @author lin.liu
+ */
+@Data
+@TableName("facility_alarm_record")
+public class FacilityAlarmRecordPO implements Serializable {
+	/**
+	 * 主键id
+	 */
+	private Long id;
+	/**
+	 * 设备id
+	 */
+	@TableField(value = "facility_id")
+	private Long facilityId;
+	/**
+	 * 设备名称
+	 */
+	@TableField(value = "facility_name")
+	private String facilityName;
+	/**
+	 * 参数编码
+	 */
+	@TableField(value = "columns_code")
+	private String columnsCode;
+	/**
+	 * 参数名称
+	 */
+	@TableField(value = "columns_name")
+	private String columnsName;
+	/**
+	 * 报警描述
+	 */
+	@TableField(value = "description")
+	private String description;
+	/**
+	 * 报警次数
+	 */
+	@TableField(value = "alarm_count")
+	private Integer alarmCount;
+	/**
+	 * 首次报警时间
+	 */
+	@TableField(value = "first_alarm_time")
+	private String firstAlarmTime;
+	/**
+	 * 最后报警时间
+	 */
+	@TableField(value = "latest_alarm_time")
+	private String latestAlarmTime;
+	/**
+	 * 数据创建时间
+	 */
+	@TableField(value = "create_time")
+	private Long createTime;
+	/**
+	 * 最后更新时间
+	 */
+	@TableField(value = "update_time")
+	private Timestamp updateTime;
+	/**
+	 * 是否删除(逻辑删除)
+	 */
+	@TableLogic
+	@TableField(value = "is_delete")
+	private Integer isDelete;
+	/**
+	 * 监控点id
+	 */
+	@TableField(value = "point_id")
+	private Long pointId;
+	/**
+	 * 监控点名称
+	 */
+	@TableField(value = "point_name")
+	private String pointName;
+}
diff --git a/src/main/java/com/lunhan/water/repository/po/HeartbeatDataPO.java b/src/main/java/com/lunhan/water/repository/po/HeartbeatDataPO.java
new file mode 100644
index 0000000..858d534
--- /dev/null
+++ b/src/main/java/com/lunhan/water/repository/po/HeartbeatDataPO.java
@@ -0,0 +1,74 @@
+/**
+#                                                    __----~~~~~~~~~~~------___
+#                                   .  .   ~~//====......          __--~ ~~
+#                   -.            \_|//     |||\\  ~~~~~~::::... /~
+#                ___-==_       _-~o~  \/    |||  \\            _/~~-
+#        __---~~~.==~||\=_    -_--~/_-~|-   |\\   \\        _/~
+#    _-~~     .=~    |  \\-_    '-~7  /-   /  ||    \      /
+#  .~       .~       |   \\ -_    /  /-   /   ||      \   /
+# /  ____  /         |     \\ ~-_/  /|- _/   .||       \ /
+# |~~    ~~|--~~~~--_ \     ~==-/   | \~--===~~        .\
+#          '         ~-|      /|    |-~\~~       __--~~
+#                      |-~~-_/ |    |   ~\_   _-~            /\
+#                           /  \     \__   \/~                \__
+#                       _--~ _/ | .-~~____--~-/                  ~~==.
+#                      ((->/~   '.|||' -_|    ~~-/ ,              . _||
+#                                 -_     ~\      ~~---l__i__i__i--~~_/
+#                                 _-~-__   ~)  \--______________--~~
+#                               //.-~~~-~_--~- |-------~~~~~~~~
+#                                      //.-~~~--\
+#                  神兽保佑
+#                  永无BUG!
+*/
+package com.lunhan.water.repository.po;
+
+import lombok.Data;
+
+import com.baomidou.mybatisplus.annotation.*;
+
+import java.io.Serializable;
+import java.sql.Timestamp;
+
+/**
+ * HeartbeatData
+ * @author lin.liu
+ */
+@Data
+@TableName("heartbeat_data")
+public class HeartbeatDataPO implements Serializable {
+	/**
+	 * null
+	 */
+	private Long id;
+	/**
+	 * null
+	 */
+	@TableField(value = "data_key")
+	private String dataKey;
+	/**
+	 * null
+	 */
+	@TableField(value = "data_value")
+	private Integer dataValue;
+	/**
+	 * null
+	 */
+	@TableLogic
+	@TableField(value = "is_delete")
+	private Integer isDelete;
+	/**
+	 * null
+	 */
+	@TableField(value = "remark")
+	private String remark;
+	/**
+	 * null
+	 */
+	@TableField(value = "create_time")
+	private Long createTime;
+	/**
+	 * null
+	 */
+	@TableField(value = "update_time")
+	private Timestamp updateTime;
+}
diff --git a/src/main/java/com/lunhan/water/repository/po/RechargeRecordsPO.java b/src/main/java/com/lunhan/water/repository/po/RechargeRecordsPO.java
index fc0a0a3..2c68cb3 100644
--- a/src/main/java/com/lunhan/water/repository/po/RechargeRecordsPO.java
+++ b/src/main/java/com/lunhan/water/repository/po/RechargeRecordsPO.java
@@ -42,6 +42,11 @@
 	 */
 	private Long id;
 	/**
+	 * 用户Id
+	 */
+	@TableField(value = "user_id")
+	private Long userId;
+	/**
 	 * 充值订单号
 	 */
 	@TableField(value = "recharge_order")
@@ -62,6 +67,11 @@
 	@TableField(value = "recharge_amount")
 	private BigDecimal rechargeAmount;
 	/**
+	 * 充值水量
+	 */
+	@TableField(value = "recharge_water")
+	private BigDecimal rechargeWater;
+	/**
 	 * 充值状态(0=未充值,1=已充值)
 	 */
 	@TableField(value = "recharge_status")
diff --git a/src/main/java/com/lunhan/water/repository/po/ThirdNotifyPO.java b/src/main/java/com/lunhan/water/repository/po/ThirdNotifyPO.java
new file mode 100644
index 0000000..c29ae7b
--- /dev/null
+++ b/src/main/java/com/lunhan/water/repository/po/ThirdNotifyPO.java
@@ -0,0 +1,104 @@
+/**
+#                                                    __----~~~~~~~~~~~------___
+#                                   .  .   ~~//====......          __--~ ~~
+#                   -.            \_|//     |||\\  ~~~~~~::::... /~
+#                ___-==_       _-~o~  \/    |||  \\            _/~~-
+#        __---~~~.==~||\=_    -_--~/_-~|-   |\\   \\        _/~
+#    _-~~     .=~    |  \\-_    '-~7  /-   /  ||    \      /
+#  .~       .~       |   \\ -_    /  /-   /   ||      \   /
+# /  ____  /         |     \\ ~-_/  /|- _/   .||       \ /
+# |~~    ~~|--~~~~--_ \     ~==-/   | \~--===~~        .\
+#          '         ~-|      /|    |-~\~~       __--~~
+#                      |-~~-_/ |    |   ~\_   _-~            /\
+#                           /  \     \__   \/~                \__
+#                       _--~ _/ | .-~~____--~-/                  ~~==.
+#                      ((->/~   '.|||' -_|    ~~-/ ,              . _||
+#                                 -_     ~\      ~~---l__i__i__i--~~_/
+#                                 _-~-__   ~)  \--______________--~~
+#                               //.-~~~-~_--~- |-------~~~~~~~~
+#                                      //.-~~~--\
+#                  神兽保佑
+#                  永无BUG!
+*/
+package com.lunhan.water.repository.po;
+
+import lombok.Data;
+
+import com.baomidou.mybatisplus.annotation.*;
+
+import java.io.Serializable;
+import java.sql.Timestamp;
+
+/**
+ * 第三方支付通知记录
+ * @author lin.liu
+ */
+@Data
+@TableName("third_notify")
+public class ThirdNotifyPO implements Serializable {
+	/**
+	 * 自增id
+	 */
+	private Long id;
+	/**
+	 * 业务
+	 */
+	@TableField(value = "business")
+	private String business;
+	/**
+	 * 业务类型 EBusinessType
+	 */
+	@TableField(value = "business_type")
+	private Integer businessType;
+	/**
+	 * 业务编号
+	 */
+	@TableField(value = "business_code")
+	private String businessCode;
+	/**
+	 * 支付渠道
+	 */
+	@TableField(value = "payment_channel")
+	private Integer paymentChannel;
+	/**
+	 * 支付渠道名称
+	 */
+	@TableField(value = "channel_name")
+	private String channelName;
+	/**
+	 * 通知报文md5
+	 */
+	@TableField(value = "md5")
+	private String md5;
+	/**
+	 * 通知报文
+	 */
+	@TableField(value = "body")
+	private String body;
+	/**
+	 * 备注
+	 */
+	@TableField(value = "comment")
+	private String comment;
+	/**
+	 * 状态(EPayNotifyState) 待处理=0,成功=1,失败=2
+	 */
+	@TableField(value = "status")
+	private Integer status;
+	/**
+	 * 创建时间
+	 */
+	@TableField(value = "create_time")
+	private Long createTime;
+	/**
+	 * 数据最后更新时间
+	 */
+	@TableField(value = "update_time")
+	private Timestamp updateTime;
+	/**
+	 * 是否删除(逻辑删除)
+	 */
+	@TableLogic
+	@TableField(value = "is_delete")
+	private Integer isDelete;
+}
diff --git a/src/main/java/com/lunhan/water/repository/po/UserLoginPO.java b/src/main/java/com/lunhan/water/repository/po/UserLoginPO.java
index 82e8cb7..daa8816 100644
--- a/src/main/java/com/lunhan/water/repository/po/UserLoginPO.java
+++ b/src/main/java/com/lunhan/water/repository/po/UserLoginPO.java
@@ -47,6 +47,11 @@
 	@TableField(value = "user_name")
 	private String userName;
 	/**
+	 * 用户编号
+	 */
+	@TableField(value = "user_code")
+	private String userCode;
+	/**
 	 * 密码
 	 */
 	@TableField(value = "password")
diff --git a/src/main/java/com/lunhan/water/repository/po/WaterFacilityPO.java b/src/main/java/com/lunhan/water/repository/po/WaterFacilityPO.java
new file mode 100644
index 0000000..541f30d
--- /dev/null
+++ b/src/main/java/com/lunhan/water/repository/po/WaterFacilityPO.java
@@ -0,0 +1,120 @@
+/**
+#                                                    __----~~~~~~~~~~~------___
+#                                   .  .   ~~//====......          __--~ ~~
+#                   -.            \_|//     |||\\  ~~~~~~::::... /~
+#                ___-==_       _-~o~  \/    |||  \\            _/~~-
+#        __---~~~.==~||\=_    -_--~/_-~|-   |\\   \\        _/~
+#    _-~~     .=~    |  \\-_    '-~7  /-   /  ||    \      /
+#  .~       .~       |   \\ -_    /  /-   /   ||      \   /
+# /  ____  /         |     \\ ~-_/  /|- _/   .||       \ /
+# |~~    ~~|--~~~~--_ \     ~==-/   | \~--===~~        .\
+#          '         ~-|      /|    |-~\~~       __--~~
+#                      |-~~-_/ |    |   ~\_   _-~            /\
+#                           /  \     \__   \/~                \__
+#                       _--~ _/ | .-~~____--~-/                  ~~==.
+#                      ((->/~   '.|||' -_|    ~~-/ ,              . _||
+#                                 -_     ~\      ~~---l__i__i__i--~~_/
+#                                 _-~-__   ~)  \--______________--~~
+#                               //.-~~~-~_--~- |-------~~~~~~~~
+#                                      //.-~~~--\
+#                  神兽保佑
+#                  永无BUG!
+*/
+package com.lunhan.water.repository.po;
+
+import lombok.Data;
+
+import com.baomidou.mybatisplus.annotation.*;
+
+import java.io.Serializable;
+import java.sql.Timestamp;
+import java.math.BigDecimal;
+
+/**
+ * 设备表
+ * @author lin.liu
+ */
+@Data
+@TableName("water_facility")
+public class WaterFacilityPO implements Serializable {
+	/**
+	 * null
+	 */
+	private Long id;
+	/**
+	 * 设备名称
+	 */
+	@TableField(value = "facility_name")
+	private String facilityName;
+	/**
+	 * 设备编号
+	 */
+	@TableField(value = "facility_code")
+	private String facilityCode;
+	/**
+	 * 经度
+	 */
+	@TableField(value = "longitude")
+	private BigDecimal longitude;
+	/**
+	 * 纬度
+	 */
+	@TableField(value = "latitude")
+	private BigDecimal latitude;
+	/**
+	 * 1:在线 0:下线
+	 */
+	@TableField(value = "on_line_state")
+	private Integer onLineState;
+	/**
+	 * 是否删除
+	 */
+	@TableLogic
+	@TableField(value = "is_delete")
+	private Integer isDelete;
+	/**
+	 * 地址
+	 */
+	@TableField(value = "address")
+	private String address;
+	/**
+	 * 备注
+	 */
+	@TableField(value = "remark")
+	private String remark;
+	/**
+	 * 创建时间
+	 */
+	@TableField(value = "create_time")
+	private Long createTime;
+	/**
+	 * 修改时间
+	 */
+	@TableField(value = "update_time")
+	private Timestamp updateTime;
+	/**
+	 * 设备图片
+	 */
+	@TableField(value = "facility_url")
+	private String facilityUrl;
+	/**
+	 * 设备供应商
+	 */
+	@TableField(value = "supplier")
+	private String supplier;
+	/**
+	 * 安装日期
+	 */
+	@TableField(value = "install_date")
+	private String installDate;
+	/**
+	 * 信号值
+	 */
+	@TableField(value = "signal_value")
+	private Integer signalValue;
+	/**
+	 * 设备状态(1正常 2故障)
+	 */
+	@TableField(value = "state")
+	private Integer state;
+}
diff --git a/src/main/java/com/lunhan/water/repository/vo/FacilityAlarmRecordVO.java b/src/main/java/com/lunhan/water/repository/vo/FacilityAlarmRecordVO.java
new file mode 100644
index 0000000..9e4a3f6
--- /dev/null
+++ b/src/main/java/com/lunhan/water/repository/vo/FacilityAlarmRecordVO.java
@@ -0,0 +1,54 @@
+/**
+#                                                    __----~~~~~~~~~~~------___
+#                                   .  .   ~~//====......          __--~ ~~
+#                   -.            \_|//     |||\\  ~~~~~~::::... /~
+#                ___-==_       _-~o~  \/    |||  \\            _/~~-
+#        __---~~~.==~||\=_    -_--~/_-~|-   |\\   \\        _/~
+#    _-~~     .=~    |  \\-_    '-~7  /-   /  ||    \      /
+#  .~       .~       |   \\ -_    /  /-   /   ||      \   /
+# /  ____  /         |     \\ ~-_/  /|- _/   .||       \ /
+# |~~    ~~|--~~~~--_ \     ~==-/   | \~--===~~        .\
+#          '         ~-|      /|    |-~\~~       __--~~
+#                      |-~~-_/ |    |   ~\_   _-~            /\
+#                           /  \     \__   \/~                \__
+#                       _--~ _/ | .-~~____--~-/                  ~~==.
+#                      ((->/~   '.|||' -_|    ~~-/ ,              . _||
+#                                 -_     ~\      ~~---l__i__i__i--~~_/
+#                                 _-~-__   ~)  \--______________--~~
+#                               //.-~~~-~_--~- |-------~~~~~~~~
+#                                      //.-~~~--\
+#                  神兽保佑
+#                  永无BUG!
+*/
+package com.lunhan.water.repository.vo;
+
+import lombok.Data;
+
+import com.lunhan.water.common.util.LocalDateTimeUtil;
+import com.lunhan.water.common.util.NumericUtil;
+import java.util.Objects;
+import com.lunhan.water.repository.po.FacilityAlarmRecordPO;
+
+/**
+ * 设备报警记录
+ * @author lin.liu
+ */
+@Data
+public class FacilityAlarmRecordVO extends FacilityAlarmRecordPO implements BasicVO {
+
+    @Override
+    public String getCreateTimeView() {
+        if (NumericUtil.tryParseLong(this.getCreateTime()).compareTo(0L) > 0) {
+            return LocalDateTimeUtil.toFormatString(this.getCreateTime());
+        }
+        return "";
+    }
+
+    @Override
+    public String getUpdateTimeView() {
+        if (Objects.isNull(this.getUpdateTime())) {
+            return "";
+        }
+        return LocalDateTimeUtil.toFormatFullString(this.getUpdateTime());
+    }
+}
diff --git a/src/main/java/com/lunhan/water/repository/vo/HeartbeatDataVO.java b/src/main/java/com/lunhan/water/repository/vo/HeartbeatDataVO.java
new file mode 100644
index 0000000..20f0340
--- /dev/null
+++ b/src/main/java/com/lunhan/water/repository/vo/HeartbeatDataVO.java
@@ -0,0 +1,54 @@
+/**
+#                                                    __----~~~~~~~~~~~------___
+#                                   .  .   ~~//====......          __--~ ~~
+#                   -.            \_|//     |||\\  ~~~~~~::::... /~
+#                ___-==_       _-~o~  \/    |||  \\            _/~~-
+#        __---~~~.==~||\=_    -_--~/_-~|-   |\\   \\        _/~
+#    _-~~     .=~    |  \\-_    '-~7  /-   /  ||    \      /
+#  .~       .~       |   \\ -_    /  /-   /   ||      \   /
+# /  ____  /         |     \\ ~-_/  /|- _/   .||       \ /
+# |~~    ~~|--~~~~--_ \     ~==-/   | \~--===~~        .\
+#          '         ~-|      /|    |-~\~~       __--~~
+#                      |-~~-_/ |    |   ~\_   _-~            /\
+#                           /  \     \__   \/~                \__
+#                       _--~ _/ | .-~~____--~-/                  ~~==.
+#                      ((->/~   '.|||' -_|    ~~-/ ,              . _||
+#                                 -_     ~\      ~~---l__i__i__i--~~_/
+#                                 _-~-__   ~)  \--______________--~~
+#                               //.-~~~-~_--~- |-------~~~~~~~~
+#                                      //.-~~~--\
+#                  神兽保佑
+#                  永无BUG!
+*/
+package com.lunhan.water.repository.vo;
+
+import lombok.Data;
+
+import com.lunhan.water.common.util.LocalDateTimeUtil;
+import com.lunhan.water.common.util.NumericUtil;
+import java.util.Objects;
+import com.lunhan.water.repository.po.HeartbeatDataPO;
+
+/**
+ * HeartbeatData
+ * @author lin.liu
+ */
+@Data
+public class HeartbeatDataVO extends HeartbeatDataPO implements BasicVO {
+
+    @Override
+    public String getCreateTimeView() {
+        if (NumericUtil.tryParseLong(this.getCreateTime()).compareTo(0L) > 0) {
+            return LocalDateTimeUtil.toFormatString(this.getCreateTime());
+        }
+        return "";
+    }
+
+    @Override
+    public String getUpdateTimeView() {
+        if (Objects.isNull(this.getUpdateTime())) {
+            return "";
+        }
+        return LocalDateTimeUtil.toFormatFullString(this.getUpdateTime());
+    }
+}
diff --git a/src/main/java/com/lunhan/water/repository/vo/PaymentRecordsVO.java b/src/main/java/com/lunhan/water/repository/vo/PaymentRecordsVO.java
index 5b68726..c44ec6b 100644
--- a/src/main/java/com/lunhan/water/repository/vo/PaymentRecordsVO.java
+++ b/src/main/java/com/lunhan/water/repository/vo/PaymentRecordsVO.java
@@ -26,6 +26,8 @@
 
 import com.lunhan.water.common.util.LocalDateTimeUtil;
 import com.lunhan.water.common.util.NumericUtil;
+
+import java.math.BigDecimal;
 import java.util.Objects;
 import com.lunhan.water.repository.po.PaymentRecordsPO;
 
@@ -35,7 +37,7 @@
  */
 @Data
 public class PaymentRecordsVO extends PaymentRecordsPO implements BasicVO {
-
+   private BigDecimal  balance;
     @Override
     public String getCreateTimeView() {
         if (NumericUtil.tryParseLong(this.getCreateTime()).compareTo(0L) > 0) {
diff --git a/src/main/java/com/lunhan/water/repository/vo/ThirdNotifyVO.java b/src/main/java/com/lunhan/water/repository/vo/ThirdNotifyVO.java
new file mode 100644
index 0000000..0ad7e54
--- /dev/null
+++ b/src/main/java/com/lunhan/water/repository/vo/ThirdNotifyVO.java
@@ -0,0 +1,54 @@
+/**
+#                                                    __----~~~~~~~~~~~------___
+#                                   .  .   ~~//====......          __--~ ~~
+#                   -.            \_|//     |||\\  ~~~~~~::::... /~
+#                ___-==_       _-~o~  \/    |||  \\            _/~~-
+#        __---~~~.==~||\=_    -_--~/_-~|-   |\\   \\        _/~
+#    _-~~     .=~    |  \\-_    '-~7  /-   /  ||    \      /
+#  .~       .~       |   \\ -_    /  /-   /   ||      \   /
+# /  ____  /         |     \\ ~-_/  /|- _/   .||       \ /
+# |~~    ~~|--~~~~--_ \     ~==-/   | \~--===~~        .\
+#          '         ~-|      /|    |-~\~~       __--~~
+#                      |-~~-_/ |    |   ~\_   _-~            /\
+#                           /  \     \__   \/~                \__
+#                       _--~ _/ | .-~~____--~-/                  ~~==.
+#                      ((->/~   '.|||' -_|    ~~-/ ,              . _||
+#                                 -_     ~\      ~~---l__i__i__i--~~_/
+#                                 _-~-__   ~)  \--______________--~~
+#                               //.-~~~-~_--~- |-------~~~~~~~~
+#                                      //.-~~~--\
+#                  神兽保佑
+#                  永无BUG!
+*/
+package com.lunhan.water.repository.vo;
+
+import lombok.Data;
+
+import com.lunhan.water.common.util.LocalDateTimeUtil;
+import com.lunhan.water.common.util.NumericUtil;
+import java.util.Objects;
+import com.lunhan.water.repository.po.ThirdNotifyPO;
+
+/**
+ * 第三方支付通知记录
+ * @author lin.liu
+ */
+@Data
+public class ThirdNotifyVO extends ThirdNotifyPO implements BasicVO {
+
+    @Override
+    public String getCreateTimeView() {
+        if (NumericUtil.tryParseLong(this.getCreateTime()).compareTo(0L) > 0) {
+            return LocalDateTimeUtil.toFormatString(this.getCreateTime());
+        }
+        return "";
+    }
+
+    @Override
+    public String getUpdateTimeView() {
+        if (Objects.isNull(this.getUpdateTime())) {
+            return "";
+        }
+        return LocalDateTimeUtil.toFormatFullString(this.getUpdateTime());
+    }
+}
diff --git a/src/main/java/com/lunhan/water/repository/vo/UserLoginVO.java b/src/main/java/com/lunhan/water/repository/vo/UserLoginVO.java
index f5804a8..f496965 100644
--- a/src/main/java/com/lunhan/water/repository/vo/UserLoginVO.java
+++ b/src/main/java/com/lunhan/water/repository/vo/UserLoginVO.java
@@ -26,6 +26,8 @@
 
 import com.lunhan.water.common.util.LocalDateTimeUtil;
 import com.lunhan.water.common.util.NumericUtil;
+
+import java.math.BigDecimal;
 import java.util.Objects;
 import com.lunhan.water.repository.po.UserLoginPO;
 
@@ -34,8 +36,16 @@
  * @author lin.liu
  */
 @Data
-public class UserLoginVO extends UserLoginPO implements BasicVO {
 
+public class UserLoginVO extends UserLoginPO implements BasicVO {
+    /**
+     * 总够水量
+     */
+   private BigDecimal sumBuyCount;
+    /**
+     * 累计用水量
+     */
+   private BigDecimal sumUseCount;
     @Override
     public String getCreateTimeView() {
         if (NumericUtil.tryParseLong(this.getCreateTime()).compareTo(0L) > 0) {
diff --git a/src/main/java/com/lunhan/water/repository/vo/WaterFacilityVO.java b/src/main/java/com/lunhan/water/repository/vo/WaterFacilityVO.java
new file mode 100644
index 0000000..87a5bc8
--- /dev/null
+++ b/src/main/java/com/lunhan/water/repository/vo/WaterFacilityVO.java
@@ -0,0 +1,57 @@
+/**
+#                                                    __----~~~~~~~~~~~------___
+#                                   .  .   ~~//====......          __--~ ~~
+#                   -.            \_|//     |||\\  ~~~~~~::::... /~
+#                ___-==_       _-~o~  \/    |||  \\            _/~~-
+#        __---~~~.==~||\=_    -_--~/_-~|-   |\\   \\        _/~
+#    _-~~     .=~    |  \\-_    '-~7  /-   /  ||    \      /
+#  .~       .~       |   \\ -_    /  /-   /   ||      \   /
+# /  ____  /         |     \\ ~-_/  /|- _/   .||       \ /
+# |~~    ~~|--~~~~--_ \     ~==-/   | \~--===~~        .\
+#          '         ~-|      /|    |-~\~~       __--~~
+#                      |-~~-_/ |    |   ~\_   _-~            /\
+#                           /  \     \__   \/~                \__
+#                       _--~ _/ | .-~~____--~-/                  ~~==.
+#                      ((->/~   '.|||' -_|    ~~-/ ,              . _||
+#                                 -_     ~\      ~~---l__i__i__i--~~_/
+#                                 _-~-__   ~)  \--______________--~~
+#                               //.-~~~-~_--~- |-------~~~~~~~~
+#                                      //.-~~~--\
+#                  神兽保佑
+#                  永无BUG!
+*/
+package com.lunhan.water.repository.vo;
+
+import lombok.Data;
+
+import com.lunhan.water.common.util.LocalDateTimeUtil;
+import com.lunhan.water.common.util.NumericUtil;
+
+import java.math.BigDecimal;
+import java.util.Objects;
+import com.lunhan.water.repository.po.WaterFacilityPO;
+
+/**
+ * 设备表
+ * @author lin.liu
+ */
+@Data
+public class WaterFacilityVO extends WaterFacilityPO implements BasicVO {
+    //距离
+    private BigDecimal distanceValue;
+    @Override
+    public String getCreateTimeView() {
+        if (NumericUtil.tryParseLong(this.getCreateTime()).compareTo(0L) > 0) {
+            return LocalDateTimeUtil.toFormatString(this.getCreateTime());
+        }
+        return "";
+    }
+
+    @Override
+    public String getUpdateTimeView() {
+        if (Objects.isNull(this.getUpdateTime())) {
+            return "";
+        }
+        return LocalDateTimeUtil.toFormatFullString(this.getUpdateTime());
+    }
+}
diff --git a/src/main/java/com/lunhan/water/service/AdminService.java b/src/main/java/com/lunhan/water/service/AdminService.java
index 53ed5bd..a91d136 100644
--- a/src/main/java/com/lunhan/water/service/AdminService.java
+++ b/src/main/java/com/lunhan/water/service/AdminService.java
@@ -28,11 +28,14 @@
 import com.lunhan.water.service.convert.AdminRoleConvert;
 import com.lunhan.water.service.convert.AdminUserConvert;
 import com.lunhan.water.service.dto.ResAdminDetail;
+import com.wf.captcha.SpecCaptcha;
 import org.apache.commons.lang3.BooleanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.redis.core.StringRedisTemplate;
 import org.springframework.stereotype.Service;
 
 import java.util.*;
+import java.util.concurrent.TimeUnit;
 import java.util.stream.Collectors;
 
 @Service
@@ -64,7 +67,8 @@
     @Autowired
     private AdminPowerService adminPowerService;
 
-
+    @Autowired
+    private StringRedisTemplate redisTemplate;
 
     // 添加后台管理员
     public ExecutedResult<Long> createAdmin(ReqCreateAdminUser request) {
@@ -130,36 +134,73 @@
         }
         return ExecutedResult.success(result);
     }
-
-    // 管理员登录
-    public ExecutedResult<ResAdminLogin> adminLogin(ReqAdminLogin request) {
-        AdminUserPO user = dao.get4Name(request.getUserName());
-        if(Objects.isNull(user)){
-            return ExecutedResult.failed("用户名或密码错误。");
-        }
-        if(BooleanUtils.isFalse(Objects.equals(user.getStatus(), EState.NORMAL.getValue()))) {
-            return ExecutedResult.failed("账号已锁定,请联系管理员。");
-        }
-        if(BooleanUtils.isFalse(MD5Util.encrypt(request.getPassword() + ConstantFactory.KEY_PASSWORD).equals(user.getPassword()))) {
-            return ExecutedResult.failed("用户名或密码错误。");
-        }
-        // 构建登录用户
-        LoginUserDTO loginUser = new LoginUserDTO();
-        loginUser.setUserId(user.getId().toString());
-        loginUser.setUserType(user.getUserType());
-        loginUser.setNickName(user.getNickName());
-        loginUser.setPhone(user.getContact());
-
-        // 保存用户信息到jwt
-        String token = JWTUtil.getToken(loginUser);
-
-        ResAdminLogin result = this.getListPower4Admin(user);
-        result.setName(user.getNickName());
-        result.setToken(token);
-
-        return ExecutedResult.success(result);
+    /**
+     * 生成验证码图片并返回其 Base64 编码字符串
+     *
+     * @param uuid 用于标识验证码的唯一标识符
+     * @return 包含验证码图片 Base64 编码的响应结果
+     */
+    public ExecutedResult<String> generate(String uuid) {
+        SpecCaptcha specCaptcha = new SpecCaptcha(100, 30, 4);
+        // captcha.setCharType(Captcha.TYPE_DEFAULT);
+        String code = specCaptcha.text().toLowerCase();
+        // 缓存验证码
+        redisTemplate.opsForValue().set(uuid, code);
+        // 设置验证码3分钟后过期
+        redisTemplate.expire(uuid, 3, TimeUnit.MINUTES);
+        return ExecutedResult.success(specCaptcha.toBase64());
     }
+    // 管理员登录
+    public ExecutedResult<ResAdminLogin> adminLogin(ReqAdminLogin request) throws Exception {
+        Integer maxNumber = 3;
+        AdminUserPO user = dao.get4Name(request.getUserName());
+        //获取缓存中的验证码
+        String realCode = redisTemplate.opsForValue().get(request.getUuid());
+        if (realCode == null) {
+            return ExecutedResult.failed("验证码已失效,请重新获取~");
+        }
+        // 验证码校验
+        if (!request.getCode().equalsIgnoreCase(realCode)) {
+            return ExecutedResult.failed("验证码错误");
+        }
+        //获取缓存中设备码
+        String machineCode = redisTemplate.opsForValue().get(request.getMachineCode());
+        if (StringUtil.isNotNullOrEmpty(machineCode) && Integer.valueOf(machineCode) >= maxNumber) {
+            return ExecutedResult.failed("登录次数限制,请10分钟后重新登录!");
+        }
+        if (checkPassword(user, request.getPassword())) {
+            // 构建登录用户
+            LoginUserDTO loginUser = new LoginUserDTO();
+            loginUser.setUserId(user.getId().toString());
+            loginUser.setUserType(user.getUserType());
+            loginUser.setNickName(user.getNickName());
+            loginUser.setPhone(user.getContact());
+            // 保存用户信息到jwt
+            String token = JWTUtil.getToken(loginUser);
+            ResAdminLogin result = this.getListPower4Admin(user);
+            result.setName(user.getNickName());
+            result.setToken(token);
+            return ExecutedResult.success(result);
+        } else {
+            Integer newAttempts = StringUtil.isNullOrEmpty(machineCode) ? 1 : Integer.valueOf(machineCode) + 1;
+            redisTemplate.opsForValue().set(request.getMachineCode(), newAttempts.toString());
+            redisTemplate.expire(request.getMachineCode(), 10, TimeUnit.MINUTES);
+        }
 
+        return ExecutedResult.failed("账号或密码错误!");
+    }
+    private static boolean checkPassword(AdminUserPO user, String passWord) throws Exception {
+        if (Objects.isNull(user)) {
+            return false;
+        }
+        if (BooleanUtils.isFalse(Objects.equals(user.getStatus(), EState.NORMAL.getValue()))) {
+            return false;
+        }
+        if (BooleanUtils.isFalse(MD5Util.encrypt(passWord + ConstantFactory.KEY_PASSWORD).equals(user.getPassword()))) {
+            return false;
+        }
+        return true;
+    }
     // 获取管理员权限列表
     public ExecutedResult<ResAdminPower> getPower(Long adminId) {
         ResAdminPower result = new ResAdminPower();
diff --git a/src/main/java/com/lunhan/water/service/FacilityAlarmRecordService.java b/src/main/java/com/lunhan/water/service/FacilityAlarmRecordService.java
new file mode 100644
index 0000000..7f8e8d7
--- /dev/null
+++ b/src/main/java/com/lunhan/water/service/FacilityAlarmRecordService.java
@@ -0,0 +1,244 @@
+/**
+#                                                    __----~~~~~~~~~~~------___
+#                                   .  .   ~~//====......          __--~ ~~
+#                   -.            \_|//     |||\\  ~~~~~~::::... /~
+#                ___-==_       _-~o~  \/    |||  \\            _/~~-
+#        __---~~~.==~||\=_    -_--~/_-~|-   |\\   \\        _/~
+#    _-~~     .=~    |  \\-_    '-~7  /-   /  ||    \      /
+#  .~       .~       |   \\ -_    /  /-   /   ||      \   /
+# /  ____  /         |     \\ ~-_/  /|- _/   .||       \ /
+# |~~    ~~|--~~~~--_ \     ~==-/   | \~--===~~        .\
+#          '         ~-|      /|    |-~\~~       __--~~
+#                      |-~~-_/ |    |   ~\_   _-~            /\
+#                           /  \     \__   \/~                \__
+#                       _--~ _/ | .-~~____--~-/                  ~~==.
+#                      ((->/~   '.|||' -_|    ~~-/ ,              . _||
+#                                 -_     ~\      ~~---l__i__i__i--~~_/
+#                                 _-~-__   ~)  \--______________--~~
+#                               //.-~~~-~_--~- |-------~~~~~~~~
+#                                      //.-~~~--\
+#                  神兽保佑
+#                  永无BUG!
+*/
+package com.lunhan.water.service;
+
+import com.lunhan.water.common.*;
+import com.lunhan.water.common.enums.*;
+import com.lunhan.water.common.model.Tuple;
+import com.lunhan.water.common.util.*;
+import org.apache.commons.lang3.BooleanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import java.util.*;
+import java.util.stream.Collectors;
+import com.lunhan.water.repository.impl.FacilityAlarmRecordMapperImpl;
+import com.lunhan.water.repository.po.FacilityAlarmRecordPO;
+import com.lunhan.water.entity.request.facilityalarmrecord.ReqCreateFacilityAlarmRecord;
+import com.lunhan.water.entity.request.facilityalarmrecord.ReqModifyFacilityAlarmRecord;
+import com.lunhan.water.entity.search.SearchFacilityAlarmRecord;
+import com.lunhan.water.repository.vo.FacilityAlarmRecordVO;
+import com.lunhan.water.service.convert.FacilityAlarmRecordConvert;
+
+/**
+ * 设备报警记录
+ * @author lin.liu
+ */
+@Service
+public class FacilityAlarmRecordService extends BaseService {
+    @Autowired
+    private FacilityAlarmRecordMapperImpl mapper;
+
+    public ExecutedResult<Long> create(ReqCreateFacilityAlarmRecord request) {
+        // 转换po
+        FacilityAlarmRecordPO item = FacilityAlarmRecordConvert.INSTANCE.toCreate(request);
+        // 设置状态
+        //item.setStatus(EState.NORMAL.getValue());
+        // 设置记录创建时间
+        item.setCreateTime(LocalDateTimeUtil.nowTimeStamp());
+        // 是否删除(逻辑删除)初始值
+        item.setIsDelete(EYesOrNo.NO.getValue());
+
+        int rowCount = mapper.insert(item);
+        if (rowCount != 1) {
+            return ExecutedResult.failed("创建[设备报警记录]失败。");
+        }
+        return ExecutedResult.success(item.getId());
+    }
+
+    public ExecutedResult<String> modify(ReqModifyFacilityAlarmRecord request) {
+        // 验证记录是否存在
+        ExecutedResult<FacilityAlarmRecordPO> checkExists = this.check4Id(request.getId());
+        if (checkExists.isFailed()) {
+            return ExecutedResult.failed(checkExists.getMsg());
+        }
+        // 转换po
+        FacilityAlarmRecordPO item = FacilityAlarmRecordConvert.INSTANCE.toModify(request);
+
+        int rowCount = mapper.updateById(item);
+        if (rowCount != 1) {
+            return ExecutedResult.failed("编辑[设备报警记录]失败。");
+        }
+        return ExecutedResult.success();
+    }
+
+    public ExecutedResult<FacilityAlarmRecordVO> get(Long id) {
+        FacilityAlarmRecordVO result = new FacilityAlarmRecordVO();
+
+        FacilityAlarmRecordPO find = mapper.get(id);
+        if (null != find) {
+            // 转换vo
+            result = FacilityAlarmRecordConvert.INSTANCE.toVo(find);
+        }
+        return ExecutedResult.success(result);
+    }
+
+//    public ExecutedResult<String> stop(Long id) {
+//        // 验证记录是否存在
+//        ExecutedResult<FacilityAlarmRecordPO> checkExists = this.check4Id(id);
+//        if (checkExists.isFailed()) {
+//            return ExecutedResult.failed(checkExists.getMsg());
+//        }
+//        FacilityAlarmRecordPO item = new FacilityAlarmRecordPO();
+//        item.setId(id);
+//        item.setStatus(EState.DISABLED.getValue());
+//
+//        int rowCount = mapper.updateById(item);
+//        if (rowCount != 1) {
+//           return ExecutedResult.failed("停用[设备报警记录]失败。");
+//       }
+//       return ExecutedResult.success();
+//   }
+//
+//    public ExecutedResult<String> enable(Long id) {
+//        // 验证记录是否存在
+//        ExecutedResult<FacilityAlarmRecordPO> checkExists = this.check4Id(id);
+//        if (checkExists.isFailed()) {
+//            return ExecutedResult.failed(checkExists.getMsg());
+//        }
+//        FacilityAlarmRecordPO item = new FacilityAlarmRecordPO();
+//        item.setId(id);
+//        item.setStatus(EState.NORMAL.getValue());
+//
+//        int rowCount = mapper.updateById(item);
+//        if (rowCount != 1) {
+//            return ExecutedResult.failed("启用[设备报警记录]失败。");
+//        }
+//        return ExecutedResult.success();
+//    }
+//
+//    public ExecutedResult<String> setSort(ReqSetSort request) {
+//        // 验证记录是否存在
+//        ExecutedResult<FacilityAlarmRecordPO> checkExists = this.check4Id(request.getId());
+//        if (checkExists.isFailed()) {
+//            return ExecutedResult.failed(checkExists.getMsg());
+//        }
+//        FacilityAlarmRecordPO item = new FacilityAlarmRecordPO();
+//        item.setId(request.getId());
+//        item.setSort(request.getSort());
+//
+//        int rowCount = mapper.updateById(item);
+//        if (rowCount != 1) {
+//            return ExecutedResult.failed("设置[设备报警记录]排序值失败。");
+//        }
+//        return ExecutedResult.success();
+//    }
+//
+//    public ExecutedResult<String> listSetSort(ReqListSetSort request) {
+//        // id列表
+//        List<Long> listId = request.getList().stream().map(ReqSetSort::getId).collect(Collectors.toList());
+//        // 验证记录是否存在
+//        ExecutedResult<List<FacilityAlarmRecordPO>> checkExists = this.check4Id(listId);
+//        if (checkExists.isFailed()) {
+//            return ExecutedResult.failed(checkExists.getMsg());
+//        }
+//
+//        List<FacilityAlarmRecordPO> listUpdate = request.getList().stream()
+//                .map(c -> {
+//                    FacilityAlarmRecordPO item = new FacilityAlarmRecordPO();
+//                    item.setId(c.getId());
+//                    item.setSort(c.getSort());
+//                    return item;
+//                })
+//                .collect(Collectors.toList());
+//        Boolean result = mapper.modifyList(listUpdate);
+//        if (result) {
+//            return ExecutedResult.success();
+//        }
+//        return ExecutedResult.failed("[设备报警记录]设置排序值失败");
+//    }
+//
+//    public ExecutedResult<String> remove(Long id) {
+//        Boolean result = mapper.deleteLogic(id);
+//        if (BooleanUtils.isFalse(result)) {
+//            return ExecutedResult.failed("删除[设备报警记录]失败。");
+//        }
+//        return ExecutedResult.success();
+//    }
+//
+//    public ExecutedResult<String> removeList(List<Long> ids) {
+//        Boolean result = mapper.deleteLogic(ids);
+//        if (BooleanUtils.isFalse(result)) {
+//            return ExecutedResult.failed("删除[设备报警记录]失败。");
+//        }
+//        return ExecutedResult.success();
+//    }
+
+    public ExecutedResult<List<FacilityAlarmRecordVO>> getList(List<Long> listId) {
+        List<FacilityAlarmRecordVO> result = new ArrayList<>();
+
+        List<FacilityAlarmRecordPO> list = mapper.getList(listId);
+        if (ListUtil.isNotNullOrEmpty(list)) {
+            // 转换vo
+            result = FacilityAlarmRecordConvert.INSTANCE.toVo(list);
+        }
+        return ExecutedResult.success(result);
+    }
+
+    public ExecutedResult<PagerResult<FacilityAlarmRecordVO>> search(SearchFacilityAlarmRecord search) {
+        // 处理创建时间范围-查询参数
+        Tuple<String, String> createTimeRange = ParameterUtil.getTimeRange(search.getCreateTimeRange());
+        if (StringUtil.isNotNullOrEmpty(createTimeRange.getItem1())) {
+            search.setCreateTimeStart(LocalDateTimeUtil.getTimeStamp(createTimeRange.getItem1()).getTime());
+        }
+        if (StringUtil.isNotNullOrEmpty(createTimeRange.getItem2())) {
+            search.setCreateTimeEnd(LocalDateTimeUtil.getTimeStamp(createTimeRange.getItem2()).getTime());
+        }
+
+        PagerResult<FacilityAlarmRecordPO> pageList = mapper.search(search);
+        List<FacilityAlarmRecordVO> listVo = new ArrayList<>();
+        List<FacilityAlarmRecordPO> list = pageList.getList();
+        if (ListUtil.isNotNullOrEmpty(list)) {
+            pageList.setLastId(list.get(list.size() - 1).getId());
+            // 转换vo
+            listVo = FacilityAlarmRecordConvert.INSTANCE.toVo(list);
+        }
+        PagerResult<FacilityAlarmRecordVO> result = new PagerResult<>(pageList.getLimit(), pageList.getPage(), pageList.getTotal(), listVo);
+        result.setLastId(pageList.getLastId());
+        return ExecutedResult.success(result);
+    }
+
+    protected ExecutedResult<FacilityAlarmRecordPO> check4Id(Long id) {
+        FacilityAlarmRecordPO exists = mapper.get(id);
+        if (Objects.isNull(exists)) {
+            return ExecutedResult.failed("[设备报警记录]不存在:" + id);
+        }
+        return ExecutedResult.success(exists);
+    }
+    protected ExecutedResult<List<FacilityAlarmRecordPO>> check4Id(List<Long> listId) {
+        // 从数据库查找设备报警记录
+        List<FacilityAlarmRecordPO> list = mapper.getList(listId);
+        if (ListUtil.isNullOrEmpty(list)) {
+            return ExecutedResult.failed("[设备报警记录]不存在." + listId);
+        }
+        // 数据库找到的id列表
+        List<Long> listIdFind = list.stream().map(FacilityAlarmRecordPO::getId).collect(Collectors.toList());
+        // 数量不一致
+        if (listId.size() != listIdFind.size()) {
+            // 筛选数据库不存在的设备报警记录
+            List<Long> listIdNotFound = listId.stream().filter(c -> !listIdFind.contains(c)).collect(Collectors.toList());
+            if (ListUtil.isNullOrEmpty(list)) {
+                return ExecutedResult.failed("[设备报警记录]不存在." + listIdNotFound);
+            }
+        }
+        return ExecutedResult.success(list);
+    }}
diff --git a/src/main/java/com/lunhan/water/service/HeartbeatDataService.java b/src/main/java/com/lunhan/water/service/HeartbeatDataService.java
new file mode 100644
index 0000000..4d4fb1e
--- /dev/null
+++ b/src/main/java/com/lunhan/water/service/HeartbeatDataService.java
@@ -0,0 +1,244 @@
+/**
+#                                                    __----~~~~~~~~~~~------___
+#                                   .  .   ~~//====......          __--~ ~~
+#                   -.            \_|//     |||\\  ~~~~~~::::... /~
+#                ___-==_       _-~o~  \/    |||  \\            _/~~-
+#        __---~~~.==~||\=_    -_--~/_-~|-   |\\   \\        _/~
+#    _-~~     .=~    |  \\-_    '-~7  /-   /  ||    \      /
+#  .~       .~       |   \\ -_    /  /-   /   ||      \   /
+# /  ____  /         |     \\ ~-_/  /|- _/   .||       \ /
+# |~~    ~~|--~~~~--_ \     ~==-/   | \~--===~~        .\
+#          '         ~-|      /|    |-~\~~       __--~~
+#                      |-~~-_/ |    |   ~\_   _-~            /\
+#                           /  \     \__   \/~                \__
+#                       _--~ _/ | .-~~____--~-/                  ~~==.
+#                      ((->/~   '.|||' -_|    ~~-/ ,              . _||
+#                                 -_     ~\      ~~---l__i__i__i--~~_/
+#                                 _-~-__   ~)  \--______________--~~
+#                               //.-~~~-~_--~- |-------~~~~~~~~
+#                                      //.-~~~--\
+#                  神兽保佑
+#                  永无BUG!
+*/
+package com.lunhan.water.service;
+
+import com.lunhan.water.common.*;
+import com.lunhan.water.common.enums.*;
+import com.lunhan.water.common.model.Tuple;
+import com.lunhan.water.common.util.*;
+import org.apache.commons.lang3.BooleanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import java.util.*;
+import java.util.stream.Collectors;
+import com.lunhan.water.repository.impl.HeartbeatDataMapperImpl;
+import com.lunhan.water.repository.po.HeartbeatDataPO;
+import com.lunhan.water.entity.request.heartbeatdata.ReqCreateHeartbeatData;
+import com.lunhan.water.entity.request.heartbeatdata.ReqModifyHeartbeatData;
+import com.lunhan.water.entity.search.SearchHeartbeatData;
+import com.lunhan.water.repository.vo.HeartbeatDataVO;
+import com.lunhan.water.service.convert.HeartbeatDataConvert;
+
+/**
+ * HeartbeatData
+ * @author lin.liu
+ */
+@Service
+public class HeartbeatDataService extends BaseService {
+    @Autowired
+    private HeartbeatDataMapperImpl mapper;
+
+    public ExecutedResult<Long> create(ReqCreateHeartbeatData request) {
+        // 转换po
+        HeartbeatDataPO item = HeartbeatDataConvert.INSTANCE.toCreate(request);
+        // 设置状态
+        //item.setStatus(EState.NORMAL.getValue());
+        // 设置记录创建时间
+        item.setCreateTime(LocalDateTimeUtil.nowTimeStamp());
+        // 是否删除(逻辑删除)初始值
+        item.setIsDelete(EYesOrNo.NO.getValue());
+
+        int rowCount = mapper.insert(item);
+        if (rowCount != 1) {
+            return ExecutedResult.failed("创建[null]失败。");
+        }
+        return ExecutedResult.success(item.getId());
+    }
+
+    public ExecutedResult<String> modify(ReqModifyHeartbeatData request) {
+        // 验证记录是否存在
+        ExecutedResult<HeartbeatDataPO> checkExists = this.check4Id(request.getId());
+        if (checkExists.isFailed()) {
+            return ExecutedResult.failed(checkExists.getMsg());
+        }
+        // 转换po
+        HeartbeatDataPO item = HeartbeatDataConvert.INSTANCE.toModify(request);
+
+        int rowCount = mapper.updateById(item);
+        if (rowCount != 1) {
+            return ExecutedResult.failed("编辑[null]失败。");
+        }
+        return ExecutedResult.success();
+    }
+
+    public ExecutedResult<HeartbeatDataVO> get(Long id) {
+        HeartbeatDataVO result = new HeartbeatDataVO();
+
+        HeartbeatDataPO find = mapper.get(id);
+        if (null != find) {
+            // 转换vo
+            result = HeartbeatDataConvert.INSTANCE.toVo(find);
+        }
+        return ExecutedResult.success(result);
+    }
+
+//    public ExecutedResult<String> stop(Long id) {
+//        // 验证记录是否存在
+//        ExecutedResult<HeartbeatDataPO> checkExists = this.check4Id(id);
+//        if (checkExists.isFailed()) {
+//            return ExecutedResult.failed(checkExists.getMsg());
+//        }
+//        HeartbeatDataPO item = new HeartbeatDataPO();
+//        item.setId(id);
+//        item.setStatus(EState.DISABLED.getValue());
+//
+//        int rowCount = mapper.updateById(item);
+//        if (rowCount != 1) {
+//           return ExecutedResult.failed("停用[null]失败。");
+//       }
+//       return ExecutedResult.success();
+//   }
+//
+//    public ExecutedResult<String> enable(Long id) {
+//        // 验证记录是否存在
+//        ExecutedResult<HeartbeatDataPO> checkExists = this.check4Id(id);
+//        if (checkExists.isFailed()) {
+//            return ExecutedResult.failed(checkExists.getMsg());
+//        }
+//        HeartbeatDataPO item = new HeartbeatDataPO();
+//        item.setId(id);
+//        item.setStatus(EState.NORMAL.getValue());
+//
+//        int rowCount = mapper.updateById(item);
+//        if (rowCount != 1) {
+//            return ExecutedResult.failed("启用[null]失败。");
+//        }
+//        return ExecutedResult.success();
+//    }
+//
+//    public ExecutedResult<String> setSort(ReqSetSort request) {
+//        // 验证记录是否存在
+//        ExecutedResult<HeartbeatDataPO> checkExists = this.check4Id(request.getId());
+//        if (checkExists.isFailed()) {
+//            return ExecutedResult.failed(checkExists.getMsg());
+//        }
+//        HeartbeatDataPO item = new HeartbeatDataPO();
+//        item.setId(request.getId());
+//        item.setSort(request.getSort());
+//
+//        int rowCount = mapper.updateById(item);
+//        if (rowCount != 1) {
+//            return ExecutedResult.failed("设置[null]排序值失败。");
+//        }
+//        return ExecutedResult.success();
+//    }
+//
+//    public ExecutedResult<String> listSetSort(ReqListSetSort request) {
+//        // id列表
+//        List<Long> listId = request.getList().stream().map(ReqSetSort::getId).collect(Collectors.toList());
+//        // 验证记录是否存在
+//        ExecutedResult<List<HeartbeatDataPO>> checkExists = this.check4Id(listId);
+//        if (checkExists.isFailed()) {
+//            return ExecutedResult.failed(checkExists.getMsg());
+//        }
+//
+//        List<HeartbeatDataPO> listUpdate = request.getList().stream()
+//                .map(c -> {
+//                    HeartbeatDataPO item = new HeartbeatDataPO();
+//                    item.setId(c.getId());
+//                    item.setSort(c.getSort());
+//                    return item;
+//                })
+//                .collect(Collectors.toList());
+//        Boolean result = mapper.modifyList(listUpdate);
+//        if (result) {
+//            return ExecutedResult.success();
+//        }
+//        return ExecutedResult.failed("[null]设置排序值失败");
+//    }
+//
+//    public ExecutedResult<String> remove(Long id) {
+//        Boolean result = mapper.deleteLogic(id);
+//        if (BooleanUtils.isFalse(result)) {
+//            return ExecutedResult.failed("删除[null]失败。");
+//        }
+//        return ExecutedResult.success();
+//    }
+//
+//    public ExecutedResult<String> removeList(List<Long> ids) {
+//        Boolean result = mapper.deleteLogic(ids);
+//        if (BooleanUtils.isFalse(result)) {
+//            return ExecutedResult.failed("删除[null]失败。");
+//        }
+//        return ExecutedResult.success();
+//    }
+
+    public ExecutedResult<List<HeartbeatDataVO>> getList(List<Long> listId) {
+        List<HeartbeatDataVO> result = new ArrayList<>();
+
+        List<HeartbeatDataPO> list = mapper.getList(listId);
+        if (ListUtil.isNotNullOrEmpty(list)) {
+            // 转换vo
+            result = HeartbeatDataConvert.INSTANCE.toVo(list);
+        }
+        return ExecutedResult.success(result);
+    }
+
+    public ExecutedResult<PagerResult<HeartbeatDataVO>> search(SearchHeartbeatData search) {
+        // 处理创建时间范围-查询参数
+        Tuple<String, String> createTimeRange = ParameterUtil.getTimeRange(search.getCreateTimeRange());
+        if (StringUtil.isNotNullOrEmpty(createTimeRange.getItem1())) {
+            search.setCreateTimeStart(LocalDateTimeUtil.getTimeStamp(createTimeRange.getItem1()).getTime());
+        }
+        if (StringUtil.isNotNullOrEmpty(createTimeRange.getItem2())) {
+            search.setCreateTimeEnd(LocalDateTimeUtil.getTimeStamp(createTimeRange.getItem2()).getTime());
+        }
+
+        PagerResult<HeartbeatDataPO> pageList = mapper.search(search);
+        List<HeartbeatDataVO> listVo = new ArrayList<>();
+        List<HeartbeatDataPO> list = pageList.getList();
+        if (ListUtil.isNotNullOrEmpty(list)) {
+            pageList.setLastId(list.get(list.size() - 1).getId());
+            // 转换vo
+            listVo = HeartbeatDataConvert.INSTANCE.toVo(list);
+        }
+        PagerResult<HeartbeatDataVO> result = new PagerResult<>(pageList.getLimit(), pageList.getPage(), pageList.getTotal(), listVo);
+        result.setLastId(pageList.getLastId());
+        return ExecutedResult.success(result);
+    }
+
+    protected ExecutedResult<HeartbeatDataPO> check4Id(Long id) {
+        HeartbeatDataPO exists = mapper.get(id);
+        if (Objects.isNull(exists)) {
+            return ExecutedResult.failed("[null]不存在:" + id);
+        }
+        return ExecutedResult.success(exists);
+    }
+    protected ExecutedResult<List<HeartbeatDataPO>> check4Id(List<Long> listId) {
+        // 从数据库查找null
+        List<HeartbeatDataPO> list = mapper.getList(listId);
+        if (ListUtil.isNullOrEmpty(list)) {
+            return ExecutedResult.failed("[null]不存在." + listId);
+        }
+        // 数据库找到的id列表
+        List<Long> listIdFind = list.stream().map(HeartbeatDataPO::getId).collect(Collectors.toList());
+        // 数量不一致
+        if (listId.size() != listIdFind.size()) {
+            // 筛选数据库不存在的null
+            List<Long> listIdNotFound = listId.stream().filter(c -> !listIdFind.contains(c)).collect(Collectors.toList());
+            if (ListUtil.isNullOrEmpty(list)) {
+                return ExecutedResult.failed("[null]不存在." + listIdNotFound);
+            }
+        }
+        return ExecutedResult.success(list);
+    }}
diff --git a/src/main/java/com/lunhan/water/service/PaymentRecordsService.java b/src/main/java/com/lunhan/water/service/PaymentRecordsService.java
index 366160b..e3bd5c6 100644
--- a/src/main/java/com/lunhan/water/service/PaymentRecordsService.java
+++ b/src/main/java/com/lunhan/water/service/PaymentRecordsService.java
@@ -1,38 +1,54 @@
 /**
-#                                                    __----~~~~~~~~~~~------___
-#                                   .  .   ~~//====......          __--~ ~~
-#                   -.            \_|//     |||\\  ~~~~~~::::... /~
-#                ___-==_       _-~o~  \/    |||  \\            _/~~-
-#        __---~~~.==~||\=_    -_--~/_-~|-   |\\   \\        _/~
-#    _-~~     .=~    |  \\-_    '-~7  /-   /  ||    \      /
-#  .~       .~       |   \\ -_    /  /-   /   ||      \   /
-# /  ____  /         |     \\ ~-_/  /|- _/   .||       \ /
-# |~~    ~~|--~~~~--_ \     ~==-/   | \~--===~~        .\
-#          '         ~-|      /|    |-~\~~       __--~~
-#                      |-~~-_/ |    |   ~\_   _-~            /\
-#                           /  \     \__   \/~                \__
-#                       _--~ _/ | .-~~____--~-/                  ~~==.
-#                      ((->/~   '.|||' -_|    ~~-/ ,              . _||
-#                                 -_     ~\      ~~---l__i__i__i--~~_/
-#                                 _-~-__   ~)  \--______________--~~
-#                               //.-~~~-~_--~- |-------~~~~~~~~
-#                                      //.-~~~--\
-#                  神兽保佑
-#                  永无BUG!
-*/
+ #                                                    __----~~~~~~~~~~~------___
+ #                                   .  .   ~~//====......          __--~ ~~
+ #                   -.            \_|//     |||\\  ~~~~~~::::... /~
+ #                ___-==_       _-~o~  \/    |||  \\            _/~~-
+ #        __---~~~.==~||\=_    -_--~/_-~|-   |\\   \\        _/~
+ #    _-~~     .=~    |  \\-_    '-~7  /-   /  ||    \      /
+ #  .~       .~       |   \\ -_    /  /-   /   ||      \   /
+ # /  ____  /         |     \\ ~-_/  /|- _/   .||       \ /
+ # |~~    ~~|--~~~~--_ \     ~==-/   | \~--===~~        .\
+ #          '         ~-|      /|    |-~\~~       __--~~
+ #                      |-~~-_/ |    |   ~\_   _-~            /\
+ #                           /  \     \__   \/~                \__
+ #                       _--~ _/ | .-~~____--~-/                  ~~==.
+ #                      ((->/~   '.|||' -_|    ~~-/ ,              . _||
+ #                                 -_     ~\      ~~---l__i__i__i--~~_/
+ #                                 _-~-__   ~)  \--______________--~~
+ #                               //.-~~~-~_--~- |-------~~~~~~~~
+ #                                      //.-~~~--\
+ #                  神兽保佑
+ #                  永无BUG!
+ */
 package com.lunhan.water.service;
 
+import com.google.gson.Gson;
+import com.google.gson.JsonArray;
+import com.google.gson.JsonObject;
+import com.google.gson.reflect.TypeToken;
 import com.lunhan.water.common.*;
 import com.lunhan.water.common.enums.*;
+import com.lunhan.water.common.jwt.LoginUserDTO;
 import com.lunhan.water.common.model.Tuple;
 import com.lunhan.water.common.util.*;
+import com.lunhan.water.entity.enums.EBillPayStatus;
+import com.lunhan.water.entity.enums.ECapitalChange;
+import com.lunhan.water.entity.request.paymentrecords.ReqBuyWater;
+import com.lunhan.water.host.mqtt.CountVO;
+import com.lunhan.water.host.mqtt.MQTTServer;
+import com.lunhan.water.repository.impl.*;
+import com.lunhan.water.repository.po.*;
+import com.lunhan.water.repository.vo.WaterFacilityVO;
 import org.apache.commons.lang3.BooleanUtils;
+import org.slf4j.Logger;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
+
+import java.lang.reflect.Type;
+import java.math.BigDecimal;
 import java.util.*;
 import java.util.stream.Collectors;
-import com.lunhan.water.repository.impl.PaymentRecordsMapperImpl;
-import com.lunhan.water.repository.po.PaymentRecordsPO;
+
 import com.lunhan.water.entity.request.paymentrecords.ReqCreatePaymentRecords;
 import com.lunhan.water.entity.request.paymentrecords.ReqModifyPaymentRecords;
 import com.lunhan.water.entity.search.SearchPaymentRecords;
@@ -45,8 +61,22 @@
  */
 @Service
 public class PaymentRecordsService extends BaseService {
+    private static final Logger DEBUG_LOGGER = LoggerUtil.get(ELogger.DEBUG);
+    private static final Logger ERROR_LOGGER = LoggerUtil.get(ELogger.SYS_ERROR);
     @Autowired
     private PaymentRecordsMapperImpl mapper;
+    @Autowired
+    private UserLoginMapperImpl userLoginMapper;
+    @Autowired
+    private WaterFacilityMapperImpl waterFacilityMapper;
+    @Autowired
+    private MQTTServer mqttServer;
+    @Autowired
+    private UserCapitalChangeMapperImpl userCapitalChangeMapper;
+    @Autowired
+    private HeartbeatDataMapperImpl heartbeatDataMapper;
+    @Autowired
+    private FacilityAlarmRecordMapperImpl facilityAlarmRecordMapper;
 
     public ExecutedResult<Long> create(ReqCreatePaymentRecords request) {
         // 转换po
@@ -92,7 +122,7 @@
         return ExecutedResult.success(result);
     }
 
-//    public ExecutedResult<String> stop(Long id) {
+    //    public ExecutedResult<String> stop(Long id) {
 //        // 验证记录是否存在
 //        ExecutedResult<PaymentRecordsPO> checkExists = this.check4Id(id);
 //        if (checkExists.isFailed()) {
@@ -183,6 +213,163 @@
 //        return ExecutedResult.success();
 //    }
 
+    /**
+     * mqtt发送取水指令
+     * @param request 消息内容
+     */
+    public ExecutedResult<String> userWaterInTaking(LoginUserDTO loginUser, ReqBuyWater request) {
+        WaterFacilityPO facilityPO = waterFacilityMapper.getById(request.getFacilityId());
+        if (Objects.isNull(facilityPO)) {
+            return ExecutedResult.failed("未查询到取水设备!");
+        }
+        UserLoginPO userLoginPO = userLoginMapper.get4Openid(loginUser.getUserId());
+        if (Objects.isNull(userLoginPO)) {
+            return ExecutedResult.failed("用户数据不存在!");
+        }
+        if (userLoginPO.getBalance().compareTo(request.getAmount()) < 0) {
+            return ExecutedResult.failed("余额水量不足!");
+        }
+        //发送mqtt取水指令
+        String topic = "zundong/" + facilityPO.getFacilityCode() + "/switch";
+        JsonObject data = new JsonObject();
+        data.addProperty(facilityPO.getFacilityCode() + "_amount", request.getAmount().multiply(BigDecimal.valueOf(100)));
+        data.addProperty(facilityPO.getFacilityCode() + "_user", userLoginPO.getUserCode());
+        data.addProperty(facilityPO.getFacilityCode() + "_state", 1);
+        if (Objects.nonNull(mqttServer)) {
+            mqttServer.send(topic, data.toString());
+        } else {
+            try {
+                System.out.println("mqttServer bean尚未初始化...");
+                mqttServer = SpringUtil.getBean(MQTTServer.class);
+                System.out.println("mqttServer 初始化bean成功!");
+            } catch (Exception ignored) {
+            }
+            if (Objects.nonNull(mqttServer)) {
+                mqttServer.send(topic, data.toString());
+            }
+        }
+        return ExecutedResult.success("请点击设备取水按钮取水");
+    }
+
+    /**
+     * mqtt收到消息
+     * @param topic 主题
+     * @param msg 消息内容
+     */
+    public void mqttReceived(String topic, String msg) {
+        if (StringUtil.isNullOrEmpty(topic)) {
+            ERROR_LOGGER.error("主题不能为空");
+            return;
+        }
+        if (StringUtil.isNullOrEmpty(msg)) {
+            ERROR_LOGGER.error("消息不能为空");
+            return;
+        }
+        String[] array = StringUtil.split(topic, "/");
+        if (array.length != 3) {
+            ERROR_LOGGER.error("主题未能解析, " + topic);
+            return;
+        }
+        WaterFacilityPO facilityPO = waterFacilityMapper.getCode(array[1]);
+        if (Objects.isNull(facilityPO)) {
+            DEBUG_LOGGER.error("设备数据未找到!");
+            return;
+        }
+
+//        数据上报格式:
+//        主题格式:zundong/QS001/data
+//        数据格式:{"Data":
+//          [
+//              {"name":"QS001_state","value":1}, //状态
+//              {"name":"QS001_fault","value":0}, //是否故障
+//              {"name":"QS001_count","value":10000} //总水量
+//          ],"time":"2025-07-02 15:19:17"
+//        }
+//        心跳上报格式:
+//        主题格式:zundong/QS001/state
+//        数据格式:{"Data":
+//              [
+//               {"name":"QS001_heartbeat","value":1} //心跳
+//              ],"time":"2025-07-02 15:19:17"
+//          }
+        //消息解析
+        Gson gson = new Gson();
+        JsonObject object = gson.fromJson(msg, JsonObject.class);
+        String time = object.get("time").getAsString();
+        //long time = LocalDateTimeUtil.getTimeStamp(asJsonObject).getTime();
+        Type listType = new TypeToken<List<CountVO>>() {
+        }.getType();
+        JsonArray data = object.getAsJsonArray("Data");
+        List<CountVO> listVo = gson.fromJson(data, listType);
+        switch (array[2]) {
+            case "data":
+                uploadData(time,facilityPO,listVo);
+                break;
+            case "state":
+                uploadState(time,facilityPO,listVo);
+                break;
+        }
+    }
+
+    public void uploadData(String time,WaterFacilityPO facilityPO, List<CountVO> listVo) {
+        CountVO stateVo = listVo.stream().filter(x -> x.getName().equals(facilityPO.getFacilityCode() + "_state")).findFirst().orElse(null);
+        CountVO faultVo = listVo.stream().filter(x -> x.getName().equals(facilityPO.getFacilityCode() + "_fault")).findFirst().orElse(null);
+        CountVO countVO = listVo.stream().filter(x -> x.getName().equals(facilityPO.getFacilityCode() + "_count")).findFirst().orElse(null);
+        CountVO userVo = listVo.stream().filter(x -> x.getName().equals(facilityPO.getFacilityCode() + "_user")).findFirst().orElse(null);
+        switch (stateVo.getValue()) {
+            case "0"://取水完成
+                //扣除余额
+                UserLoginPO user = userLoginMapper.get4UserCode(userVo.getValue());
+               //创建消费记录
+                PaymentRecordsPO recordsPO=new PaymentRecordsPO();
+                recordsPO.setUserId(user.getId());
+                recordsPO.setUserName(user.getUserName());
+                recordsPO.setFacilityCode(facilityPO.getFacilityCode());
+                BigDecimal bigDecimal = new BigDecimal(countVO.getValue()).divide(new BigDecimal(100)).setScale(2, BigDecimal.ROUND_DOWN);
+                recordsPO.setPaymentAmount(bigDecimal);
+                recordsPO.setWaterAmount(bigDecimal);
+                recordsPO.setPayTime(time);
+                recordsPO.setPayStatus(EBillPayStatus.PAID.getValue());
+                recordsPO.setComment("取水");
+                recordsPO.setCreateTime(LocalDateTimeUtil.nowTimeStamp());
+                mapper.insert(recordsPO);
+                //修改余额
+                BigDecimal beforeMoney=user.getBalance();
+                BigDecimal subtract = beforeMoney.subtract(bigDecimal);
+                user.setBalance(subtract);
+                userLoginMapper.updateById(user);
+                //生成余额变动记录
+                UserCapitalChangePO changePO=new UserCapitalChangePO();
+                changePO.setUserId(user.getId());
+                changePO.setBusiness(ECapitalChange.WATER_BILL_COUNTER_PAY.getValue());
+                changePO.setBusinessName("取水");
+                changePO.setBusinessCode("QS"+SnowFlakeUtil.getId());
+                changePO.setChangeMoney(bigDecimal);
+                changePO.setBeforeMoney(beforeMoney);
+                changePO.setAfterMoney(subtract);
+                changePO.setCreateTime(LocalDateTimeUtil.nowTimeStamp());
+                userCapitalChangeMapper.insert(changePO);
+                break;
+            case "1"://运行
+                break;
+            case "2"://停止
+                break;
+            case "3"://故障
+                break;
+        }
+    }
+    public void uploadState(String time,WaterFacilityPO facilityPO, List<CountVO> listVo){
+        CountVO heartbeatVO = listVo.stream().filter(x -> x.getName().equals(facilityPO.getFacilityCode() + "_heartbeat")).findFirst().orElse(null);
+        HeartbeatDataPO heartbeatDataPO = heartbeatDataMapper.getByKey(facilityPO.getFacilityCode());
+        if(Objects.isNull(heartbeatDataPO)){
+            HeartbeatDataPO dataPO=new HeartbeatDataPO();
+            dataPO.setDataKey(facilityPO.getFacilityCode());
+            dataPO.setDataValue(Integer.valueOf(heartbeatVO.getValue()));
+            dataPO.setCreateTime(LocalDateTimeUtil.nowTimeStamp());
+            dataPO.setRemark(LocalDateTimeUtil.nowDateTimeStr());
+            heartbeatDataMapper.insert(dataPO);
+        }
+    }
     public ExecutedResult<List<PaymentRecordsVO>> getList(List<Long> listId) {
         List<PaymentRecordsVO> result = new ArrayList<>();
 
@@ -196,21 +383,50 @@
 
     public ExecutedResult<PagerResult<PaymentRecordsVO>> search(SearchPaymentRecords search) {
         // 处理创建时间范围-查询参数
-        Tuple<String, String> createTimeRange = ParameterUtil.getTimeRange(search.getCreateTimeRange());
-        if (StringUtil.isNotNullOrEmpty(createTimeRange.getItem1())) {
-            search.setCreateTimeStart(LocalDateTimeUtil.getTimeStamp(createTimeRange.getItem1()).getTime());
+        if (search.getDateType() != null && search.getDateType() > 0) {
+            Long beginTime = 0L;
+            Long endTime = 0L;
+            switch (search.getDateType()) {
+                case 1:
+                    beginTime = LocalDateTimeUtil.getTimeStamp(LocalDateTimeUtils.todayStartTime()).getTime();
+                    endTime = LocalDateTimeUtil.getTimeStamp(LocalDateTimeUtils.todayEndTime()).getTime();
+                    break;
+                case 2:
+                    beginTime = LocalDateTimeUtil.getTimeStamp(LocalDateTimeUtils.weekStartTime()).getTime();
+                    endTime = LocalDateTimeUtil.getTimeStamp(LocalDateTimeUtils.weekEndTime()).getTime();
+                    break;
+                case 3:
+                    beginTime = LocalDateTimeUtil.getTimeStamp(LocalDateTimeUtils.monthStartTime()).getTime();
+                    endTime = LocalDateTimeUtil.getTimeStamp(LocalDateTimeUtils.monthEndTime()).getTime();
+                    break;
+                case 4:
+                    beginTime = LocalDateTimeUtil.getTimeStamp(LocalDateTimeUtils.yearStartTime()).getTime();
+                    endTime = LocalDateTimeUtil.getTimeStamp(LocalDateTimeUtils.yearEndTime()).getTime();
+                    break;
+            }
+            if (beginTime > 0) {
+                search.setCreateTimeStart(beginTime);
+            }
+            if (endTime > 0) {
+                search.setCreateTimeEnd(endTime);
+            }
         }
-        if (StringUtil.isNotNullOrEmpty(createTimeRange.getItem2())) {
-            search.setCreateTimeEnd(LocalDateTimeUtil.getTimeStamp(createTimeRange.getItem2()).getTime());
-        }
-
         PagerResult<PaymentRecordsPO> pageList = mapper.search(search);
         List<PaymentRecordsVO> listVo = new ArrayList<>();
         List<PaymentRecordsPO> list = pageList.getList();
         if (ListUtil.isNotNullOrEmpty(list)) {
             pageList.setLastId(list.get(list.size() - 1).getId());
             // 转换vo
-            listVo = PaymentRecordsConvert.INSTANCE.toVo(list);
+            listVo = CopierUtil.mapTo(list, PaymentRecordsVO.class);
+            //获取列表所有用户id
+            List<Long> idList = listVo.stream().map(PaymentRecordsVO::getUserId).distinct().collect(Collectors.toList());
+            List<UserLoginPO> userList = userLoginMapper.getListById(idList);
+            for (PaymentRecordsVO vo : listVo) {
+                UserLoginPO userLoginPO = userList.stream().filter(x -> x.getId().equals(vo.getUserId())).findFirst().orElse(null);
+                if (Objects.nonNull(userLoginPO)) {
+                    vo.setBalance(userLoginPO.getBalance());
+                }
+            }
         }
         PagerResult<PaymentRecordsVO> result = new PagerResult<>(pageList.getLimit(), pageList.getPage(), pageList.getTotal(), listVo);
         result.setLastId(pageList.getLastId());
@@ -224,6 +440,7 @@
         }
         return ExecutedResult.success(exists);
     }
+
     protected ExecutedResult<List<PaymentRecordsPO>> check4Id(List<Long> listId) {
         // 从数据库查找null
         List<PaymentRecordsPO> list = mapper.getList(listId);
@@ -241,4 +458,5 @@
             }
         }
         return ExecutedResult.success(list);
-    }}
+    }
+}
diff --git a/src/main/java/com/lunhan/water/service/PaymentServices.java b/src/main/java/com/lunhan/water/service/PaymentServices.java
index 1452abd..3e3a839 100644
--- a/src/main/java/com/lunhan/water/service/PaymentServices.java
+++ b/src/main/java/com/lunhan/water/service/PaymentServices.java
@@ -23,6 +23,7 @@
 import com.lunhan.water.repository.po.*;
 import org.slf4j.Logger;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.redis.core.RedisTemplate;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.web.bind.annotation.RequestBody;
@@ -55,7 +56,8 @@
     private UserCapitalChangeMapperImpl capitalChangeDao;
     @Autowired
     private TradeRecordMapperImpl tradeRecordDao;
-
+    @Autowired
+    private RedisTemplate<String, Object> redisTemplate;
 
 
     /**
@@ -66,6 +68,14 @@
      */
     @Transactional(rollbackFor = Exception.class)
     public ExecutedResult<Map<String, Object>> weiXinPay(LoginUserDTO loginUser, ReqCreatePay request) {
+        //判断token是否存在,如果不存在,说明重复提交订单
+        String redisToken = redisTemplate.opsForValue().get(request.getPayToken()).toString();
+        if (StringUtil.isNullOrEmpty(redisToken)) {
+            throw new RuntimeException("请勿重复提交充值订单!");
+        }
+        //删除token
+        redisTemplate.delete(request.getPayToken());
+
         EBusinessType type = EBusinessType.getByValue(request.getBusinessType());
         if (Objects.isNull(type)) {
             return ExecutedResult.failed("业务不支持." + request.getBusinessType());
diff --git a/src/main/java/com/lunhan/water/service/RechargeOrderService.java b/src/main/java/com/lunhan/water/service/RechargeOrderService.java
index 7f57680..f268740 100644
--- a/src/main/java/com/lunhan/water/service/RechargeOrderService.java
+++ b/src/main/java/com/lunhan/water/service/RechargeOrderService.java
@@ -24,11 +24,18 @@
 
 import com.lunhan.water.common.*;
 import com.lunhan.water.common.enums.*;
+import com.lunhan.water.common.jwt.LoginUserDTO;
 import com.lunhan.water.common.model.Tuple;
 import com.lunhan.water.common.util.*;
+import com.lunhan.water.entity.enums.EPayState;
+import com.lunhan.water.entity.enums.EPayType;
+import com.lunhan.water.repository.impl.UserLoginMapperImpl;
+import com.lunhan.water.repository.po.UserLoginPO;
 import org.apache.commons.lang3.BooleanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
+
+import java.math.BigDecimal;
 import java.util.*;
 import java.util.stream.Collectors;
 import com.lunhan.water.repository.impl.RechargeOrderMapperImpl;
@@ -47,12 +54,20 @@
 public class RechargeOrderService extends BaseService {
     @Autowired
     private RechargeOrderMapperImpl mapper;
+    @Autowired
+    private UserLoginMapperImpl userLoginMapper;
 
-    public ExecutedResult<Long> create(ReqCreateRechargeOrder request) {
+    public ExecutedResult<Long> create(LoginUserDTO loginUser,ReqCreateRechargeOrder request) {
         // 转换po
+        UserLoginPO user = userLoginMapper.get4Openid(loginUser.getUserId());
+        if(Objects.isNull(user)){
+            return ExecutedResult.failed("用户信息不存在!");
+        }
         RechargeOrderPO item = RechargeOrderConvert.INSTANCE.toCreate(request);
         // 设置状态
-        //item.setStatus(EState.NORMAL.getValue());
+        item.setOrderNo("CZ"+SnowFlakeUtil.getId());
+        item.setPayState(EPayState.WAITING.getValue());
+        item.setPayType(EPayType.WX_PAY.getValue());
         // 设置记录创建时间
         item.setCreateTime(LocalDateTimeUtil.nowTimeStamp());
         // 是否删除(逻辑删除)初始值
diff --git a/src/main/java/com/lunhan/water/service/RechargeRecordsService.java b/src/main/java/com/lunhan/water/service/RechargeRecordsService.java
index 54418cd..3c9054e 100644
--- a/src/main/java/com/lunhan/water/service/RechargeRecordsService.java
+++ b/src/main/java/com/lunhan/water/service/RechargeRecordsService.java
@@ -26,6 +26,7 @@
 import com.lunhan.water.common.enums.*;
 import com.lunhan.water.common.model.Tuple;
 import com.lunhan.water.common.util.*;
+import com.lunhan.water.repository.vo.PaymentRecordsVO;
 import org.apache.commons.lang3.BooleanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
@@ -196,21 +197,41 @@
 
     public ExecutedResult<PagerResult<RechargeRecordsVO>> search(SearchRechargeRecords search) {
         // 处理创建时间范围-查询参数
-        Tuple<String, String> createTimeRange = ParameterUtil.getTimeRange(search.getCreateTimeRange());
-        if (StringUtil.isNotNullOrEmpty(createTimeRange.getItem1())) {
-            search.setCreateTimeStart(LocalDateTimeUtil.getTimeStamp(createTimeRange.getItem1()).getTime());
+        if(search.getDateType()!=null&&search.getDateType()>0){
+            Long beginTime=0L;
+            Long endTime=0L;
+            switch (search.getDateType()){
+                case 1:
+                    beginTime=LocalDateTimeUtil.getTimeStamp(LocalDateTimeUtils.todayStartTime()).getTime();
+                    endTime=LocalDateTimeUtil.getTimeStamp(LocalDateTimeUtils.todayEndTime()).getTime();
+                    break;
+                case 2:
+                    beginTime=LocalDateTimeUtil.getTimeStamp(LocalDateTimeUtils.weekStartTime()).getTime();
+                    endTime=LocalDateTimeUtil.getTimeStamp(LocalDateTimeUtils.weekEndTime()).getTime();
+                    break;
+                case 3:
+                    beginTime=LocalDateTimeUtil.getTimeStamp(LocalDateTimeUtils.monthStartTime()).getTime();
+                    endTime=LocalDateTimeUtil.getTimeStamp(LocalDateTimeUtils.monthEndTime()).getTime();
+                    break;
+                case 4:
+                    beginTime=LocalDateTimeUtil.getTimeStamp(LocalDateTimeUtils.yearStartTime()).getTime();
+                    endTime=LocalDateTimeUtil.getTimeStamp(LocalDateTimeUtils.yearEndTime()).getTime();
+                    break;
+            }
+            if (beginTime>0) {
+                search.setCreateTimeStart(beginTime);
+            }
+            if (endTime>0) {
+                search.setCreateTimeEnd(endTime);
+            }
         }
-        if (StringUtil.isNotNullOrEmpty(createTimeRange.getItem2())) {
-            search.setCreateTimeEnd(LocalDateTimeUtil.getTimeStamp(createTimeRange.getItem2()).getTime());
-        }
-
         PagerResult<RechargeRecordsPO> pageList = mapper.search(search);
         List<RechargeRecordsVO> listVo = new ArrayList<>();
         List<RechargeRecordsPO> list = pageList.getList();
         if (ListUtil.isNotNullOrEmpty(list)) {
             pageList.setLastId(list.get(list.size() - 1).getId());
             // 转换vo
-            listVo = RechargeRecordsConvert.INSTANCE.toVo(list);
+            listVo =  CopierUtil.mapTo(list, RechargeRecordsVO.class);
         }
         PagerResult<RechargeRecordsVO> result = new PagerResult<>(pageList.getLimit(), pageList.getPage(), pageList.getTotal(), listVo);
         result.setLastId(pageList.getLastId());
diff --git a/src/main/java/com/lunhan/water/service/ThirdNotifyService.java b/src/main/java/com/lunhan/water/service/ThirdNotifyService.java
new file mode 100644
index 0000000..bcec067
--- /dev/null
+++ b/src/main/java/com/lunhan/water/service/ThirdNotifyService.java
@@ -0,0 +1,283 @@
+/**
+#                                                    __----~~~~~~~~~~~------___
+#                                   .  .   ~~//====......          __--~ ~~
+#                   -.            \_|//     |||\\  ~~~~~~::::... /~
+#                ___-==_       _-~o~  \/    |||  \\            _/~~-
+#        __---~~~.==~||\=_    -_--~/_-~|-   |\\   \\        _/~
+#    _-~~     .=~    |  \\-_    '-~7  /-   /  ||    \      /
+#  .~       .~       |   \\ -_    /  /-   /   ||      \   /
+# /  ____  /         |     \\ ~-_/  /|- _/   .||       \ /
+# |~~    ~~|--~~~~--_ \     ~==-/   | \~--===~~        .\
+#          '         ~-|      /|    |-~\~~       __--~~
+#                      |-~~-_/ |    |   ~\_   _-~            /\
+#                           /  \     \__   \/~                \__
+#                       _--~ _/ | .-~~____--~-/                  ~~==.
+#                      ((->/~   '.|||' -_|    ~~-/ ,              . _||
+#                                 -_     ~\      ~~---l__i__i__i--~~_/
+#                                 _-~-__   ~)  \--______________--~~
+#                               //.-~~~-~_--~- |-------~~~~~~~~
+#                                      //.-~~~--\
+#                  神兽保佑
+#                  永无BUG!
+*/
+package com.lunhan.water.service;
+
+import com.lunhan.water.common.*;
+import com.lunhan.water.common.enums.*;
+import com.lunhan.water.common.model.Tuple;
+import com.lunhan.water.common.security.MD5Util;
+import com.lunhan.water.common.util.*;
+import com.lunhan.water.entity.enums.EPayNotifyState;
+import com.lunhan.water.entity.enums.EPaymentChannel;
+import org.apache.commons.lang3.BooleanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import java.util.*;
+import java.util.stream.Collectors;
+import com.lunhan.water.repository.impl.ThirdNotifyMapperImpl;
+import com.lunhan.water.repository.po.ThirdNotifyPO;
+import com.lunhan.water.entity.request.thirdnotify.ReqCreateThirdNotify;
+import com.lunhan.water.entity.request.thirdnotify.ReqModifyThirdNotify;
+import com.lunhan.water.entity.search.SearchThirdNotify;
+import com.lunhan.water.repository.vo.ThirdNotifyVO;
+import com.lunhan.water.service.convert.ThirdNotifyConvert;
+
+/**
+ * 第三方支付通知记录
+ * @author lin.liu
+ */
+@Service
+public class ThirdNotifyService extends BaseService {
+    @Autowired
+    private ThirdNotifyMapperImpl mapper;
+
+    public ExecutedResult<Long> create(ReqCreateThirdNotify request) {
+        // 转换po
+        ThirdNotifyPO item = ThirdNotifyConvert.INSTANCE.toCreate(request);
+        // 设置状态
+        //item.setStatus(EState.NORMAL.getValue());
+        // 设置记录创建时间
+        item.setCreateTime(LocalDateTimeUtil.nowTimeStamp());
+        // 是否删除(逻辑删除)初始值
+        item.setIsDelete(EYesOrNo.NO.getValue());
+
+        int rowCount = mapper.insert(item);
+        if (rowCount != 1) {
+            return ExecutedResult.failed("创建[第三方支付通知记录]失败。");
+        }
+        return ExecutedResult.success(item.getId());
+    }
+
+    public ExecutedResult<String> modify(ReqModifyThirdNotify request) {
+        // 验证记录是否存在
+        ExecutedResult<ThirdNotifyPO> checkExists = this.check4Id(request.getId());
+        if (checkExists.isFailed()) {
+            return ExecutedResult.failed(checkExists.getMsg());
+        }
+        // 转换po
+        ThirdNotifyPO item = ThirdNotifyConvert.INSTANCE.toModify(request);
+
+        int rowCount = mapper.updateById(item);
+        if (rowCount != 1) {
+            return ExecutedResult.failed("编辑[第三方支付通知记录]失败。");
+        }
+        return ExecutedResult.success();
+    }
+
+    public ExecutedResult<ThirdNotifyVO> get(Long id) {
+        ThirdNotifyVO result = new ThirdNotifyVO();
+
+        ThirdNotifyPO find = mapper.get(id);
+        if (null != find) {
+            // 转换vo
+            result = ThirdNotifyConvert.INSTANCE.toVo(find);
+        }
+        return ExecutedResult.success(result);
+    }
+
+//    public ExecutedResult<String> stop(Long id) {
+//        // 验证记录是否存在
+//        ExecutedResult<ThirdNotifyPO> checkExists = this.check4Id(id);
+//        if (checkExists.isFailed()) {
+//            return ExecutedResult.failed(checkExists.getMsg());
+//        }
+//        ThirdNotifyPO item = new ThirdNotifyPO();
+//        item.setId(id);
+//        item.setStatus(EState.DISABLED.getValue());
+//
+//        int rowCount = mapper.updateById(item);
+//        if (rowCount != 1) {
+//           return ExecutedResult.failed("停用[第三方支付通知记录]失败。");
+//       }
+//       return ExecutedResult.success();
+//   }
+//
+//    public ExecutedResult<String> enable(Long id) {
+//        // 验证记录是否存在
+//        ExecutedResult<ThirdNotifyPO> checkExists = this.check4Id(id);
+//        if (checkExists.isFailed()) {
+//            return ExecutedResult.failed(checkExists.getMsg());
+//        }
+//        ThirdNotifyPO item = new ThirdNotifyPO();
+//        item.setId(id);
+//        item.setStatus(EState.NORMAL.getValue());
+//
+//        int rowCount = mapper.updateById(item);
+//        if (rowCount != 1) {
+//            return ExecutedResult.failed("启用[第三方支付通知记录]失败。");
+//        }
+//        return ExecutedResult.success();
+//    }
+//
+//    public ExecutedResult<String> setSort(ReqSetSort request) {
+//        // 验证记录是否存在
+//        ExecutedResult<ThirdNotifyPO> checkExists = this.check4Id(request.getId());
+//        if (checkExists.isFailed()) {
+//            return ExecutedResult.failed(checkExists.getMsg());
+//        }
+//        ThirdNotifyPO item = new ThirdNotifyPO();
+//        item.setId(request.getId());
+//        item.setSort(request.getSort());
+//
+//        int rowCount = mapper.updateById(item);
+//        if (rowCount != 1) {
+//            return ExecutedResult.failed("设置[第三方支付通知记录]排序值失败。");
+//        }
+//        return ExecutedResult.success();
+//    }
+//
+//    public ExecutedResult<String> listSetSort(ReqListSetSort request) {
+//        // id列表
+//        List<Long> listId = request.getList().stream().map(ReqSetSort::getId).collect(Collectors.toList());
+//        // 验证记录是否存在
+//        ExecutedResult<List<ThirdNotifyPO>> checkExists = this.check4Id(listId);
+//        if (checkExists.isFailed()) {
+//            return ExecutedResult.failed(checkExists.getMsg());
+//        }
+//
+//        List<ThirdNotifyPO> listUpdate = request.getList().stream()
+//                .map(c -> {
+//                    ThirdNotifyPO item = new ThirdNotifyPO();
+//                    item.setId(c.getId());
+//                    item.setSort(c.getSort());
+//                    return item;
+//                })
+//                .collect(Collectors.toList());
+//        Boolean result = mapper.modifyList(listUpdate);
+//        if (result) {
+//            return ExecutedResult.success();
+//        }
+//        return ExecutedResult.failed("[第三方支付通知记录]设置排序值失败");
+//    }
+//
+//    public ExecutedResult<String> remove(Long id) {
+//        Boolean result = mapper.deleteLogic(id);
+//        if (BooleanUtils.isFalse(result)) {
+//            return ExecutedResult.failed("删除[第三方支付通知记录]失败。");
+//        }
+//        return ExecutedResult.success();
+//    }
+//
+//    public ExecutedResult<String> removeList(List<Long> ids) {
+//        Boolean result = mapper.deleteLogic(ids);
+//        if (BooleanUtils.isFalse(result)) {
+//            return ExecutedResult.failed("删除[第三方支付通知记录]失败。");
+//        }
+//        return ExecutedResult.success();
+//    }
+public ExecutedResult<Long> saveWinXinPayNotify(EPaymentChannel channel, String business, String body, Integer businessType) {
+    String md5 = MD5Util.encrypt(body);
+    Long now = LocalDateTimeUtil.nowTimeStamp();
+
+    ThirdNotifyPO find = mapper.get4Md5(md5);
+    if (Objects.nonNull(find) && md5.equals(find.getMd5())) {
+        return ExecutedResult.failed("重复通知!", ConstantFactory.MCODE_TOKENERROR);
+    }
+    ThirdNotifyPO item = new ThirdNotifyPO();
+    item.setBusiness(business);
+    item.setBusinessType(businessType);
+    item.setBusinessCode("");
+    item.setPaymentChannel(channel.getValue());
+    item.setChannelName(channel.getDesc());
+    item.setMd5(md5);
+    item.setBody(body);
+    item.setComment("");
+    item.setStatus(EPayNotifyState.WAITING.getValue());
+    item.setCreateTime(now);
+
+    int saveNotify = mapper.insert(item);
+    if (saveNotify<1) {
+        return ExecutedResult.failed("保存报文失败!");
+    }
+    return ExecutedResult.success(item.getId());
+}
+    public void updateBusinessCode(Long notifyId, String businessCode) {
+        try {
+            ThirdNotifyPO upd = new ThirdNotifyPO();
+            upd.setId(notifyId);
+            upd.setBusinessCode(businessCode);
+
+            mapper.updateById(upd);
+        } catch (Exception e) {
+            LoggerUtil.get(ELogger.SYS_ERROR).error("ThirdNotifyService_updateBusinessCode", e);
+        }
+    }
+    public ExecutedResult<List<ThirdNotifyVO>> getList(List<Long> listId) {
+        List<ThirdNotifyVO> result = new ArrayList<>();
+
+        List<ThirdNotifyPO> list = mapper.getList(listId);
+        if (ListUtil.isNotNullOrEmpty(list)) {
+            // 转换vo
+            result = ThirdNotifyConvert.INSTANCE.toVo(list);
+        }
+        return ExecutedResult.success(result);
+    }
+
+    public ExecutedResult<PagerResult<ThirdNotifyVO>> search(SearchThirdNotify search) {
+        // 处理创建时间范围-查询参数
+        Tuple<String, String> createTimeRange = ParameterUtil.getTimeRange(search.getCreateTimeRange());
+        if (StringUtil.isNotNullOrEmpty(createTimeRange.getItem1())) {
+            search.setCreateTimeStart(LocalDateTimeUtil.getTimeStamp(createTimeRange.getItem1()).getTime());
+        }
+        if (StringUtil.isNotNullOrEmpty(createTimeRange.getItem2())) {
+            search.setCreateTimeEnd(LocalDateTimeUtil.getTimeStamp(createTimeRange.getItem2()).getTime());
+        }
+
+        PagerResult<ThirdNotifyPO> pageList = mapper.search(search);
+        List<ThirdNotifyVO> listVo = new ArrayList<>();
+        List<ThirdNotifyPO> list = pageList.getList();
+        if (ListUtil.isNotNullOrEmpty(list)) {
+            pageList.setLastId(list.get(list.size() - 1).getId());
+            // 转换vo
+            listVo = ThirdNotifyConvert.INSTANCE.toVo(list);
+        }
+        PagerResult<ThirdNotifyVO> result = new PagerResult<>(pageList.getLimit(), pageList.getPage(), pageList.getTotal(), listVo);
+        result.setLastId(pageList.getLastId());
+        return ExecutedResult.success(result);
+    }
+
+    protected ExecutedResult<ThirdNotifyPO> check4Id(Long id) {
+        ThirdNotifyPO exists = mapper.get(id);
+        if (Objects.isNull(exists)) {
+            return ExecutedResult.failed("[第三方支付通知记录]不存在:" + id);
+        }
+        return ExecutedResult.success(exists);
+    }
+    protected ExecutedResult<List<ThirdNotifyPO>> check4Id(List<Long> listId) {
+        // 从数据库查找第三方支付通知记录
+        List<ThirdNotifyPO> list = mapper.getList(listId);
+        if (ListUtil.isNullOrEmpty(list)) {
+            return ExecutedResult.failed("[第三方支付通知记录]不存在." + listId);
+        }
+        // 数据库找到的id列表
+        List<Long> listIdFind = list.stream().map(ThirdNotifyPO::getId).collect(Collectors.toList());
+        // 数量不一致
+        if (listId.size() != listIdFind.size()) {
+            // 筛选数据库不存在的第三方支付通知记录
+            List<Long> listIdNotFound = listId.stream().filter(c -> !listIdFind.contains(c)).collect(Collectors.toList());
+            if (ListUtil.isNullOrEmpty(list)) {
+                return ExecutedResult.failed("[第三方支付通知记录]不存在." + listIdNotFound);
+            }
+        }
+        return ExecutedResult.success(list);
+    }}
diff --git a/src/main/java/com/lunhan/water/service/UserLoginService.java b/src/main/java/com/lunhan/water/service/UserLoginService.java
index c530828..274fdb1 100644
--- a/src/main/java/com/lunhan/water/service/UserLoginService.java
+++ b/src/main/java/com/lunhan/water/service/UserLoginService.java
@@ -33,9 +33,14 @@
 import com.lunhan.water.entity.enums.EUserType;
 import com.lunhan.water.entity.request.ReqChangePassword;
 import com.lunhan.water.entity.request.ReqUserLogin;
+import com.lunhan.water.repository.impl.PaymentRecordsMapperImpl;
+import com.lunhan.water.repository.impl.RechargeRecordsMapperImpl;
 import org.apache.commons.lang3.BooleanUtils;
+import org.apache.ibatis.annotations.Select;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
+
+import java.math.BigDecimal;
 import java.util.*;
 import java.util.stream.Collectors;
 import com.lunhan.water.repository.impl.UserLoginMapperImpl;
@@ -54,6 +59,10 @@
 public class UserLoginService extends BaseService {
     @Autowired
     private UserLoginMapperImpl mapper;
+    @Autowired
+    private RechargeRecordsMapperImpl rechargeRecordsMapper;
+    @Autowired
+    private PaymentRecordsMapperImpl paymentRecordsMapper;
 
     public ExecutedResult<Long> create(ReqCreateUserLogin request) {
         // 转换po
@@ -78,12 +87,15 @@
         if (checkExists.isFailed()) {
             return ExecutedResult.failed(checkExists.getMsg());
         }
+        //UserLoginPO data = checkExists.getData();
         // 转换po
-        UserLoginPO item = UserLoginConvert.INSTANCE.toModify(request);
-
+        UserLoginPO item =new UserLoginPO();
+        item.setId( checkExists.getData().getId());
+        item.setNickName(request.getNickName());
+        item.setHeadImg(request.getHeadImg());
         int rowCount = mapper.updateById(item);
         if (rowCount != 1) {
-            return ExecutedResult.failed("编辑[null]失败。");
+            return ExecutedResult.failed("编辑用户信息失败。");
         }
         return ExecutedResult.success();
     }
@@ -98,7 +110,22 @@
         }
         return ExecutedResult.success(result);
     }
+    public ExecutedResult<UserLoginVO> getUser(LoginUserDTO loginUser){
+        UserLoginPO userLoginPO = mapper.get4Openid(loginUser.getUserId());
+        if(Objects.isNull(userLoginPO)){
+            return ExecutedResult.failed("未获取到用户信息!");
+        }
+        UserLoginVO userLoginVO = CopierUtil.mapTo(userLoginPO, UserLoginVO.class);
+        //查询总够水量
+        BigDecimal sumBuyCount = rechargeRecordsMapper.getSumBuyCount(userLoginPO.getId());
+        //查询总用水量
+        BigDecimal sumUseCount = paymentRecordsMapper.getSumUseCount(userLoginPO.getId());
+        userLoginVO.setSumBuyCount(sumBuyCount);
+        userLoginVO.setSumUseCount(sumUseCount);
 
+
+        return ExecutedResult.success(userLoginVO);
+    }
 //    public ExecutedResult<String> stop(Long id) {
 //        // 验证记录是否存在
 //        ExecutedResult<UserLoginPO> checkExists = this.check4Id(id);
diff --git a/src/main/java/com/lunhan/water/service/WaterFacilityService.java b/src/main/java/com/lunhan/water/service/WaterFacilityService.java
new file mode 100644
index 0000000..9761c3c
--- /dev/null
+++ b/src/main/java/com/lunhan/water/service/WaterFacilityService.java
@@ -0,0 +1,281 @@
+/**
+ #                                                    __----~~~~~~~~~~~------___
+ #                                   .  .   ~~//====......          __--~ ~~
+ #                   -.            \_|//     |||\\  ~~~~~~::::... /~
+ #                ___-==_       _-~o~  \/    |||  \\            _/~~-
+ #        __---~~~.==~||\=_    -_--~/_-~|-   |\\   \\        _/~
+ #    _-~~     .=~    |  \\-_    '-~7  /-   /  ||    \      /
+ #  .~       .~       |   \\ -_    /  /-   /   ||      \   /
+ # /  ____  /         |     \\ ~-_/  /|- _/   .||       \ /
+ # |~~    ~~|--~~~~--_ \     ~==-/   | \~--===~~        .\
+ #          '         ~-|      /|    |-~\~~       __--~~
+ #                      |-~~-_/ |    |   ~\_   _-~            /\
+ #                           /  \     \__   \/~                \__
+ #                       _--~ _/ | .-~~____--~-/                  ~~==.
+ #                      ((->/~   '.|||' -_|    ~~-/ ,              . _||
+ #                                 -_     ~\      ~~---l__i__i__i--~~_/
+ #                                 _-~-__   ~)  \--______________--~~
+ #                               //.-~~~-~_--~- |-------~~~~~~~~
+ #                                      //.-~~~--\
+ #                  神兽保佑
+ #                  永无BUG!
+ */
+package com.lunhan.water.service;
+
+import com.lunhan.water.common.*;
+import com.lunhan.water.common.enums.*;
+import com.lunhan.water.common.model.Tuple;
+import com.lunhan.water.common.util.*;
+import org.apache.commons.lang3.BooleanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.math.BigDecimal;
+import java.util.*;
+import java.util.stream.Collectors;
+
+import com.lunhan.water.repository.impl.WaterFacilityMapperImpl;
+import com.lunhan.water.repository.po.WaterFacilityPO;
+import com.lunhan.water.entity.request.waterfacility.ReqCreateWaterFacility;
+import com.lunhan.water.entity.request.waterfacility.ReqModifyWaterFacility;
+import com.lunhan.water.entity.search.SearchWaterFacility;
+import com.lunhan.water.repository.vo.WaterFacilityVO;
+import com.lunhan.water.service.convert.WaterFacilityConvert;
+
+/**
+ * 设备表
+ * @author lin.liu
+ */
+@Service
+public class WaterFacilityService extends BaseService {
+    private static final BigDecimal EARTH_RADIUS = new BigDecimal(6371000); // 地球半径,单位为米
+    @Autowired
+    private WaterFacilityMapperImpl mapper;
+
+    public ExecutedResult<Long> create(ReqCreateWaterFacility request) {
+        // 转换po
+        WaterFacilityPO item = WaterFacilityConvert.INSTANCE.toCreate(request);
+        // 设置状态
+        //item.setStatus(EState.NORMAL.getValue());
+        // 设置记录创建时间
+        item.setCreateTime(LocalDateTimeUtil.nowTimeStamp());
+        // 是否删除(逻辑删除)初始值
+        item.setIsDelete(EYesOrNo.NO.getValue());
+
+        int rowCount = mapper.insert(item);
+        if (rowCount != 1) {
+            return ExecutedResult.failed("创建[设备表]失败。");
+        }
+        return ExecutedResult.success(item.getId());
+    }
+
+    public ExecutedResult<String> modify(ReqModifyWaterFacility request) {
+        // 验证记录是否存在
+        ExecutedResult<WaterFacilityPO> checkExists = this.check4Id(request.getId());
+        if (checkExists.isFailed()) {
+            return ExecutedResult.failed(checkExists.getMsg());
+        }
+        // 转换po
+        WaterFacilityPO item = WaterFacilityConvert.INSTANCE.toModify(request);
+
+        int rowCount = mapper.updateById(item);
+        if (rowCount != 1) {
+            return ExecutedResult.failed("编辑[设备表]失败。");
+        }
+        return ExecutedResult.success();
+    }
+
+    public ExecutedResult<WaterFacilityVO> get(Long id) {
+        WaterFacilityVO result = new WaterFacilityVO();
+
+        WaterFacilityPO find = mapper.get(id);
+        if (null != find) {
+            // 转换vo
+            result = WaterFacilityConvert.INSTANCE.toVo(find);
+        }
+        return ExecutedResult.success(result);
+    }
+
+//    public ExecutedResult<String> stop(Long id) {
+//        // 验证记录是否存在
+//        ExecutedResult<WaterFacilityPO> checkExists = this.check4Id(id);
+//        if (checkExists.isFailed()) {
+//            return ExecutedResult.failed(checkExists.getMsg());
+//        }
+//        WaterFacilityPO item = new WaterFacilityPO();
+//        item.setId(id);
+//        item.setStatus(EState.DISABLED.getValue());
+//
+//        int rowCount = mapper.updateById(item);
+//        if (rowCount != 1) {
+//           return ExecutedResult.failed("停用[设备表]失败。");
+//       }
+//       return ExecutedResult.success();
+//   }
+//
+//    public ExecutedResult<String> enable(Long id) {
+//        // 验证记录是否存在
+//        ExecutedResult<WaterFacilityPO> checkExists = this.check4Id(id);
+//        if (checkExists.isFailed()) {
+//            return ExecutedResult.failed(checkExists.getMsg());
+//        }
+//        WaterFacilityPO item = new WaterFacilityPO();
+//        item.setId(id);
+//        item.setStatus(EState.NORMAL.getValue());
+//
+//        int rowCount = mapper.updateById(item);
+//        if (rowCount != 1) {
+//            return ExecutedResult.failed("启用[设备表]失败。");
+//        }
+//        return ExecutedResult.success();
+//    }
+//
+//    public ExecutedResult<String> setSort(ReqSetSort request) {
+//        // 验证记录是否存在
+//        ExecutedResult<WaterFacilityPO> checkExists = this.check4Id(request.getId());
+//        if (checkExists.isFailed()) {
+//            return ExecutedResult.failed(checkExists.getMsg());
+//        }
+//        WaterFacilityPO item = new WaterFacilityPO();
+//        item.setId(request.getId());
+//        item.setSort(request.getSort());
+//
+//        int rowCount = mapper.updateById(item);
+//        if (rowCount != 1) {
+//            return ExecutedResult.failed("设置[设备表]排序值失败。");
+//        }
+//        return ExecutedResult.success();
+//    }
+//
+//    public ExecutedResult<String> listSetSort(ReqListSetSort request) {
+//        // id列表
+//        List<Long> listId = request.getList().stream().map(ReqSetSort::getId).collect(Collectors.toList());
+//        // 验证记录是否存在
+//        ExecutedResult<List<WaterFacilityPO>> checkExists = this.check4Id(listId);
+//        if (checkExists.isFailed()) {
+//            return ExecutedResult.failed(checkExists.getMsg());
+//        }
+//
+//        List<WaterFacilityPO> listUpdate = request.getList().stream()
+//                .map(c -> {
+//                    WaterFacilityPO item = new WaterFacilityPO();
+//                    item.setId(c.getId());
+//                    item.setSort(c.getSort());
+//                    return item;
+//                })
+//                .collect(Collectors.toList());
+//        Boolean result = mapper.modifyList(listUpdate);
+//        if (result) {
+//            return ExecutedResult.success();
+//        }
+//        return ExecutedResult.failed("[设备表]设置排序值失败");
+//    }
+//
+//    public ExecutedResult<String> remove(Long id) {
+//        Boolean result = mapper.deleteLogic(id);
+//        if (BooleanUtils.isFalse(result)) {
+//            return ExecutedResult.failed("删除[设备表]失败。");
+//        }
+//        return ExecutedResult.success();
+//    }
+//
+//    public ExecutedResult<String> removeList(List<Long> ids) {
+//        Boolean result = mapper.deleteLogic(ids);
+//        if (BooleanUtils.isFalse(result)) {
+//            return ExecutedResult.failed("删除[设备表]失败。");
+//        }
+//        return ExecutedResult.success();
+//    }
+
+    public ExecutedResult<List<WaterFacilityVO>> getList(List<Long> listId) {
+        List<WaterFacilityVO> result = new ArrayList<>();
+
+        List<WaterFacilityPO> list = mapper.getList(listId);
+        if (ListUtil.isNotNullOrEmpty(list)) {
+            // 转换vo
+            result = WaterFacilityConvert.INSTANCE.toVo(list);
+        }
+        return ExecutedResult.success(result);
+    }
+
+    public static BigDecimal calculateDistance(BigDecimal lat1, BigDecimal lng1, BigDecimal lat2, BigDecimal lng2) {
+        //经纬度(角度)转弧度。弧度用作参数,以调用Math.cos和Math.sin
+        BigDecimal radiansAX = new BigDecimal(Math.toRadians(lng1.doubleValue()));//A经弧度
+        BigDecimal radiansAY = new BigDecimal(Math.toRadians(lat1.doubleValue()));//A纬弧度
+        BigDecimal radiansBX = new BigDecimal(Math.toRadians(lng2.doubleValue()));//B经弧度
+        BigDecimal radiansBY = new BigDecimal(Math.toRadians(lat2.doubleValue()));//B纬弧度
+       //公式中“cosβ1cosβ2cos(α1-α2)+sinβ1sinβ2”的部分,得到∠AOB的cos值
+        BigDecimal cos = new BigDecimal(Math.cos(radiansAY.doubleValue()) * Math.cos(radiansBY.doubleValue()) * Math.cos(radiansAX.doubleValue() - radiansBX.doubleValue())
+                + Math.sin(radiansAY.doubleValue()) * Math.sin(radiansBY.doubleValue()));
+       // log.info("cos = " + cos);//值域[-1,1]
+        BigDecimal acos = new BigDecimal(Math.acos(cos.doubleValue()));//反余弦值
+        // log.info("acos = " + acos);//值域[0,π]
+       // log.info("∠AOB = " + Math.toDegrees(acos));//球心角 值域[0,180]
+        return EARTH_RADIUS.multiply(acos).divide(new BigDecimal(1000)).setScale(2, BigDecimal.ROUND_DOWN);//最终结果
+    }
+
+    public ExecutedResult<PagerResult<WaterFacilityVO>> search(SearchWaterFacility search) {
+        // 处理创建时间范围-查询参数
+        Tuple<String, String> createTimeRange = ParameterUtil.getTimeRange(search.getCreateTimeRange());
+        if (StringUtil.isNotNullOrEmpty(createTimeRange.getItem1())) {
+            search.setCreateTimeStart(LocalDateTimeUtil.getTimeStamp(createTimeRange.getItem1()).getTime());
+        }
+        if (StringUtil.isNotNullOrEmpty(createTimeRange.getItem2())) {
+            search.setCreateTimeEnd(LocalDateTimeUtil.getTimeStamp(createTimeRange.getItem2()).getTime());
+        }
+
+        PagerResult<WaterFacilityPO> pageList = mapper.search(search);
+        List<WaterFacilityVO> listVo = new ArrayList<>();
+        List<WaterFacilityPO> list = pageList.getList();
+        if (ListUtil.isNotNullOrEmpty(list)) {
+            pageList.setLastId(list.get(list.size() - 1).getId());
+            // 转换vo
+            listVo = CopierUtil.mapTo(list, WaterFacilityVO.class);
+            if(search.getLatitude()!=null&& search.getLongitude()!=null){
+                for (WaterFacilityVO facilityVO : listVo) {
+                    BigDecimal decimal = calculateDistance(search.getLatitude(), search.getLongitude(), facilityVO.getLatitude(), facilityVO.getLongitude());
+                    facilityVO.setDistanceValue(decimal);
+                }
+                //根据距离排序
+                Collections.sort(listVo, new Comparator<WaterFacilityVO>() {
+                    @Override
+                    public int compare(WaterFacilityVO o1, WaterFacilityVO o2) {
+                        return o1.getDistanceValue().compareTo(o2.getDistanceValue());
+                    }
+                });
+            }
+
+
+        }
+        PagerResult<WaterFacilityVO> result = new PagerResult<>(pageList.getLimit(), pageList.getPage(), pageList.getTotal(), listVo);
+        result.setLastId(pageList.getLastId());
+        return ExecutedResult.success(result);
+    }
+
+    protected ExecutedResult<WaterFacilityPO> check4Id(Long id) {
+        WaterFacilityPO exists = mapper.get(id);
+        if (Objects.isNull(exists)) {
+            return ExecutedResult.failed("[设备表]不存在:" + id);
+        }
+        return ExecutedResult.success(exists);
+    }
+
+    protected ExecutedResult<List<WaterFacilityPO>> check4Id(List<Long> listId) {
+        // 从数据库查找设备表
+        List<WaterFacilityPO> list = mapper.getList(listId);
+        if (ListUtil.isNullOrEmpty(list)) {
+            return ExecutedResult.failed("[设备表]不存在." + listId);
+        }
+        // 数据库找到的id列表
+        List<Long> listIdFind = list.stream().map(WaterFacilityPO::getId).collect(Collectors.toList());
+        // 数量不一致
+        if (listId.size() != listIdFind.size()) {
+            // 筛选数据库不存在的设备表
+            List<Long> listIdNotFound = listId.stream().filter(c -> !listIdFind.contains(c)).collect(Collectors.toList());
+            if (ListUtil.isNullOrEmpty(list)) {
+                return ExecutedResult.failed("[设备表]不存在." + listIdNotFound);
+            }
+        }
+        return ExecutedResult.success(list);
+    }
+}
diff --git a/src/main/java/com/lunhan/water/service/convert/FacilityAlarmRecordConvert.java b/src/main/java/com/lunhan/water/service/convert/FacilityAlarmRecordConvert.java
new file mode 100644
index 0000000..323fd0d
--- /dev/null
+++ b/src/main/java/com/lunhan/water/service/convert/FacilityAlarmRecordConvert.java
@@ -0,0 +1,48 @@
+/**
+#                                                    __----~~~~~~~~~~~------___
+#                                   .  .   ~~//====......          __--~ ~~
+#                   -.            \_|//     |||\\  ~~~~~~::::... /~
+#                ___-==_       _-~o~  \/    |||  \\            _/~~-
+#        __---~~~.==~||\=_    -_--~/_-~|-   |\\   \\        _/~
+#    _-~~     .=~    |  \\-_    '-~7  /-   /  ||    \      /
+#  .~       .~       |   \\ -_    /  /-   /   ||      \   /
+# /  ____  /         |     \\ ~-_/  /|- _/   .||       \ /
+# |~~    ~~|--~~~~--_ \     ~==-/   | \~--===~~        .\
+#          '         ~-|      /|    |-~\~~       __--~~
+#                      |-~~-_/ |    |   ~\_   _-~            /\
+#                           /  \     \__   \/~                \__
+#                       _--~ _/ | .-~~____--~-/                  ~~==.
+#                      ((->/~   '.|||' -_|    ~~-/ ,              . _||
+#                                 -_     ~\      ~~---l__i__i__i--~~_/
+#                                 _-~-__   ~)  \--______________--~~
+#                               //.-~~~-~_--~- |-------~~~~~~~~
+#                                      //.-~~~--\
+#                  神兽保佑
+#                  永无BUG!
+*/
+package com.lunhan.water.service.convert;
+
+import com.lunhan.water.entity.request.facilityalarmrecord.ReqCreateFacilityAlarmRecord;
+import com.lunhan.water.entity.request.facilityalarmrecord.ReqModifyFacilityAlarmRecord;
+import com.lunhan.water.repository.po.FacilityAlarmRecordPO;
+import com.lunhan.water.repository.vo.FacilityAlarmRecordVO;
+
+import org.mapstruct.Mapper;
+import org.mapstruct.factory.Mappers;
+
+import java.util.List;
+
+/**
+ * 设备报警记录
+ * @author {#=author}
+ */
+@Mapper
+public interface FacilityAlarmRecordConvert {
+    FacilityAlarmRecordConvert INSTANCE = Mappers.getMapper(FacilityAlarmRecordConvert.class);
+
+    FacilityAlarmRecordPO toCreate(ReqCreateFacilityAlarmRecord request);
+    FacilityAlarmRecordPO toModify(ReqModifyFacilityAlarmRecord request);
+
+    FacilityAlarmRecordVO toVo(FacilityAlarmRecordPO item);
+    List<FacilityAlarmRecordVO> toVo(List<FacilityAlarmRecordPO> list);
+}
diff --git a/src/main/java/com/lunhan/water/service/convert/HeartbeatDataConvert.java b/src/main/java/com/lunhan/water/service/convert/HeartbeatDataConvert.java
new file mode 100644
index 0000000..6af81ec
--- /dev/null
+++ b/src/main/java/com/lunhan/water/service/convert/HeartbeatDataConvert.java
@@ -0,0 +1,48 @@
+/**
+#                                                    __----~~~~~~~~~~~------___
+#                                   .  .   ~~//====......          __--~ ~~
+#                   -.            \_|//     |||\\  ~~~~~~::::... /~
+#                ___-==_       _-~o~  \/    |||  \\            _/~~-
+#        __---~~~.==~||\=_    -_--~/_-~|-   |\\   \\        _/~
+#    _-~~     .=~    |  \\-_    '-~7  /-   /  ||    \      /
+#  .~       .~       |   \\ -_    /  /-   /   ||      \   /
+# /  ____  /         |     \\ ~-_/  /|- _/   .||       \ /
+# |~~    ~~|--~~~~--_ \     ~==-/   | \~--===~~        .\
+#          '         ~-|      /|    |-~\~~       __--~~
+#                      |-~~-_/ |    |   ~\_   _-~            /\
+#                           /  \     \__   \/~                \__
+#                       _--~ _/ | .-~~____--~-/                  ~~==.
+#                      ((->/~   '.|||' -_|    ~~-/ ,              . _||
+#                                 -_     ~\      ~~---l__i__i__i--~~_/
+#                                 _-~-__   ~)  \--______________--~~
+#                               //.-~~~-~_--~- |-------~~~~~~~~
+#                                      //.-~~~--\
+#                  神兽保佑
+#                  永无BUG!
+*/
+package com.lunhan.water.service.convert;
+
+import com.lunhan.water.entity.request.heartbeatdata.ReqCreateHeartbeatData;
+import com.lunhan.water.entity.request.heartbeatdata.ReqModifyHeartbeatData;
+import com.lunhan.water.repository.po.HeartbeatDataPO;
+import com.lunhan.water.repository.vo.HeartbeatDataVO;
+
+import org.mapstruct.Mapper;
+import org.mapstruct.factory.Mappers;
+
+import java.util.List;
+
+/**
+ * HeartbeatData
+ * @author {#=author}
+ */
+@Mapper
+public interface HeartbeatDataConvert {
+    HeartbeatDataConvert INSTANCE = Mappers.getMapper(HeartbeatDataConvert.class);
+
+    HeartbeatDataPO toCreate(ReqCreateHeartbeatData request);
+    HeartbeatDataPO toModify(ReqModifyHeartbeatData request);
+
+    HeartbeatDataVO toVo(HeartbeatDataPO item);
+    List<HeartbeatDataVO> toVo(List<HeartbeatDataPO> list);
+}
diff --git a/src/main/java/com/lunhan/water/service/convert/ThirdNotifyConvert.java b/src/main/java/com/lunhan/water/service/convert/ThirdNotifyConvert.java
new file mode 100644
index 0000000..95e3abe
--- /dev/null
+++ b/src/main/java/com/lunhan/water/service/convert/ThirdNotifyConvert.java
@@ -0,0 +1,48 @@
+/**
+#                                                    __----~~~~~~~~~~~------___
+#                                   .  .   ~~//====......          __--~ ~~
+#                   -.            \_|//     |||\\  ~~~~~~::::... /~
+#                ___-==_       _-~o~  \/    |||  \\            _/~~-
+#        __---~~~.==~||\=_    -_--~/_-~|-   |\\   \\        _/~
+#    _-~~     .=~    |  \\-_    '-~7  /-   /  ||    \      /
+#  .~       .~       |   \\ -_    /  /-   /   ||      \   /
+# /  ____  /         |     \\ ~-_/  /|- _/   .||       \ /
+# |~~    ~~|--~~~~--_ \     ~==-/   | \~--===~~        .\
+#          '         ~-|      /|    |-~\~~       __--~~
+#                      |-~~-_/ |    |   ~\_   _-~            /\
+#                           /  \     \__   \/~                \__
+#                       _--~ _/ | .-~~____--~-/                  ~~==.
+#                      ((->/~   '.|||' -_|    ~~-/ ,              . _||
+#                                 -_     ~\      ~~---l__i__i__i--~~_/
+#                                 _-~-__   ~)  \--______________--~~
+#                               //.-~~~-~_--~- |-------~~~~~~~~
+#                                      //.-~~~--\
+#                  神兽保佑
+#                  永无BUG!
+*/
+package com.lunhan.water.service.convert;
+
+import com.lunhan.water.entity.request.thirdnotify.ReqCreateThirdNotify;
+import com.lunhan.water.entity.request.thirdnotify.ReqModifyThirdNotify;
+import com.lunhan.water.repository.po.ThirdNotifyPO;
+import com.lunhan.water.repository.vo.ThirdNotifyVO;
+
+import org.mapstruct.Mapper;
+import org.mapstruct.factory.Mappers;
+
+import java.util.List;
+
+/**
+ * 第三方支付通知记录
+ * @author {#=author}
+ */
+@Mapper
+public interface ThirdNotifyConvert {
+    ThirdNotifyConvert INSTANCE = Mappers.getMapper(ThirdNotifyConvert.class);
+
+    ThirdNotifyPO toCreate(ReqCreateThirdNotify request);
+    ThirdNotifyPO toModify(ReqModifyThirdNotify request);
+
+    ThirdNotifyVO toVo(ThirdNotifyPO item);
+    List<ThirdNotifyVO> toVo(List<ThirdNotifyPO> list);
+}
diff --git a/src/main/java/com/lunhan/water/service/convert/WaterFacilityConvert.java b/src/main/java/com/lunhan/water/service/convert/WaterFacilityConvert.java
new file mode 100644
index 0000000..610d0e2
--- /dev/null
+++ b/src/main/java/com/lunhan/water/service/convert/WaterFacilityConvert.java
@@ -0,0 +1,48 @@
+/**
+#                                                    __----~~~~~~~~~~~------___
+#                                   .  .   ~~//====......          __--~ ~~
+#                   -.            \_|//     |||\\  ~~~~~~::::... /~
+#                ___-==_       _-~o~  \/    |||  \\            _/~~-
+#        __---~~~.==~||\=_    -_--~/_-~|-   |\\   \\        _/~
+#    _-~~     .=~    |  \\-_    '-~7  /-   /  ||    \      /
+#  .~       .~       |   \\ -_    /  /-   /   ||      \   /
+# /  ____  /         |     \\ ~-_/  /|- _/   .||       \ /
+# |~~    ~~|--~~~~--_ \     ~==-/   | \~--===~~        .\
+#          '         ~-|      /|    |-~\~~       __--~~
+#                      |-~~-_/ |    |   ~\_   _-~            /\
+#                           /  \     \__   \/~                \__
+#                       _--~ _/ | .-~~____--~-/                  ~~==.
+#                      ((->/~   '.|||' -_|    ~~-/ ,              . _||
+#                                 -_     ~\      ~~---l__i__i__i--~~_/
+#                                 _-~-__   ~)  \--______________--~~
+#                               //.-~~~-~_--~- |-------~~~~~~~~
+#                                      //.-~~~--\
+#                  神兽保佑
+#                  永无BUG!
+*/
+package com.lunhan.water.service.convert;
+
+import com.lunhan.water.entity.request.waterfacility.ReqCreateWaterFacility;
+import com.lunhan.water.entity.request.waterfacility.ReqModifyWaterFacility;
+import com.lunhan.water.repository.po.WaterFacilityPO;
+import com.lunhan.water.repository.vo.WaterFacilityVO;
+
+import org.mapstruct.Mapper;
+import org.mapstruct.factory.Mappers;
+
+import java.util.List;
+
+/**
+ * 设备表
+ * @author {#=author}
+ */
+@Mapper
+public interface WaterFacilityConvert {
+    WaterFacilityConvert INSTANCE = Mappers.getMapper(WaterFacilityConvert.class);
+
+    WaterFacilityPO toCreate(ReqCreateWaterFacility request);
+    WaterFacilityPO toModify(ReqModifyWaterFacility request);
+
+    WaterFacilityVO toVo(WaterFacilityPO item);
+    List<WaterFacilityVO> toVo(List<WaterFacilityPO> list);
+}
diff --git a/src/main/resources/application-dev.yml b/src/main/resources/application-dev.yml
index c1c084c..b566561 100644
--- a/src/main/resources/application-dev.yml
+++ b/src/main/resources/application-dev.yml
@@ -45,4 +45,31 @@
 # quartz定时任务配置
 quartz:
   # 是否启用
-  enable: false
\ No newline at end of file
+  enable: false
+mqtt:
+  # 是否启用
+  enable: true
+  host: 113.250.189.120
+  port: 1885
+  user: admin
+  password: public
+  # 订阅主题
+  topic: zundong/#
+  # 订阅消息的客户端id
+  clientId: water-ration-service-dev
+  # 连接超时时间
+  connectionTimeout: 10
+  # 心跳
+  keepAliveInterval: 20
+  # 发送消息的客户端id
+  serverClientId: water-ration-service-publish-dev
+pay:
+  weiXin:
+    merchantId: 1610112902
+    merchantKey: HWYTddj1235jdskDAS5353fgsdAD4S53
+    keyPath: d:/data/wxpay/apiclient_cert.p12 # 商户证书路径 xxx_cert.p12
+    privateKeyPath: d:/data/wxpay/apiclient_key.pem # 商户证书路径 xxx_key.pem
+    certificateSn: 48FC0C8D96B147CE751AEEBC882C20676F900581 # 微信支付API证书序列号
+    appID: wx08c82dac406bee56
+    notifyBasicUrl: https://www.huiwuyuntong.com/water-qinghe-local # 本地调试回调,请用frpc代理天翼云服务器端口 11101,到本机的8929
+
diff --git a/src/main/resources/application-prod.yml b/src/main/resources/application-prod.yml
index 8f66cf3..4fe407c 100644
--- a/src/main/resources/application-prod.yml
+++ b/src/main/resources/application-prod.yml
@@ -36,6 +36,23 @@
     root: info
     com.lunhan.water.host: debug
 
+
+mqtt:
+  host: 113.250.189.120
+  port: 1883
+  user: admin
+  password: public
+  # 订阅主题
+  topic: zundong/#
+  # 订阅消息的客户端id
+  clientId: water-ration-service-prod
+  # 连接超时时间
+  connectionTimeout: 10
+  # 心跳
+  keepAliveInterval: 20
+  # 发送消息的客户端id
+  serverClientId: water-ration-service-publish-prod
+
 # quartz定时任务配置
 quartz:
   # 是否启用
diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml
index cdb70be..83706c6 100644
--- a/src/main/resources/application.yml
+++ b/src/main/resources/application.yml
@@ -25,27 +25,9 @@
   expiration: 15811200 #JWT的超期限时间(60*60*24*183) 单位:秒
   head: 'Bearer '  #JWT负载中拿到开头
 
-wechat:
-  appid: wx1fc63488ed4b6f04
-  secret: 883d188be8593bd14c9b637ca5405c04
-  grant_type: authorization_code
-
 wx:
-  appId: wx08c82dac406bee56
-  secret: efb703be421ca95fc5191c07576e8938
-  miniapp:
-    #上面拿到的很重要的那个模板ID
-    template-id: kuVF5aAUw4LRVszKBm9pMxoDrOmXnvbsZYoeLNfdj10
-    configs:
-      #微信小程序的appid 开发者工具拿到
-      appid: wx51878700809c2e5c
-      #开发者工具拿到Secret
-      secret: 8b475e0b7905ef72dd014956f42cb558
-      #微信小程序消息服务器配置的token
-      token: 123456
-      #微信小程序消息服务器配置的EncodingAESKey
-      aesKey:
-      msgDataFormat: JSON
+  appId: wxd361a7f92bb0c73a
+  secret: abc1f8ff26100b480f5feb11ede66a1d
 
 # mybatis-plus 配置:
 mybatis-plus:
diff --git a/src/test/java/com/lunhan/water/GenCodeGauss.java b/src/test/java/com/lunhan/water/GenCodeGauss.java
index 772fa33..ab85fce 100644
--- a/src/test/java/com/lunhan/water/GenCodeGauss.java
+++ b/src/test/java/com/lunhan/water/GenCodeGauss.java
@@ -243,7 +243,7 @@
      * 只生成以下配置的表
      */
     private static final List<String> ONLY_TABLES = Arrays.asList(
-         "user_capital_change","recharge_records"
+         "facility_alarm_record"
     );
 
     public static void main(String[] args) {

--
Gitblit v1.9.3