19 Commity 8d55317cdf ... 39c4541cf9

Autor SHA1 Wiadomość Data
  Kazerin 39c4541cf9 - 添加 @MapperScan 识别供水Mapper接口 2 tygodni temu
  Kazerin 22ba59f3d5 Merge remote-tracking branch 'origin/master' 2 tygodni temu
  Kazerin b23db57124 - 添加 预警信息-接警效率 接口 1 miesiąc temu
  Kazerin 43b210f662 Merge remote-tracking branch 'origin/master' 1 miesiąc temu
  Kazerin 1cebfbb3d2 Merge remote-tracking branch 'origin/master' 1 miesiąc temu
  Kazerin 4b47422456 - 添加 预警信息-处置时效分析 接口 1 miesiąc temu
  Kazerin 0117573e67 - 添加 预警信息-处置状态分析 接口 1 miesiąc temu
  Kazerin ee00950a60 Merge remote-tracking branch 'origin/master' 1 miesiąc temu
  Kazerin db63dead82 - 添加 预警信息-预警发展趋势 接口 1 miesiąc temu
  Kazerin a792c2e26e - 添加 预警信息-今日预警统计 接口 1 miesiąc temu
  Kazerin 4fc0999fe3 Merge remote-tracking branch 'origin/master' 1 miesiąc temu
  Kazerin 6d740a5fda Merge remote-tracking branch 'origin/master' 1 miesiąc temu
  Kazerin 7fd2636dfb - 添加 WaterUserInfo 供水用水户信息数据接口 1 miesiąc temu
  Kazerin 1442b768eb - 为 WaterPipeInfo 供水管网信息分页查询数据接口添加时间查询条件 1 miesiąc temu
  Kazerin 1b31232361 - 添加WaterSourceInfo供水水源地信息数据接口 1 miesiąc temu
  Kazerin fb99cf9422 Merge remote-tracking branch 'origin/master' 1 miesiąc temu
  Kazerin e3c2e963a4 - 添加WaterPlantInfo供水水厂信息数据接口 1 miesiąc temu
  Kazerin d4d06f0491 - 添加WaterPumpStation供水泵站信息数据接口 1 miesiąc temu
  Kazerin f44a0626a6 - 添加WaterPipeInfo供水管网信息数据接口 2 miesięcy temu
50 zmienionych plików z 4688 dodań i 3 usunięć
  1. 290 0
      pipe-network-service/zksy-admin/src/main/java/com/zksy/web/controller/WaterSupply/WaterPipeInfo/WaterPipeInfoController.java
  2. 227 0
      pipe-network-service/zksy-admin/src/main/java/com/zksy/web/controller/WaterSupply/WaterPlantInfo/WaterPlantInfoController.java
  3. 227 0
      pipe-network-service/zksy-admin/src/main/java/com/zksy/web/controller/WaterSupply/WaterPumpStation/WaterPumpStationController.java
  4. 225 0
      pipe-network-service/zksy-admin/src/main/java/com/zksy/web/controller/WaterSupply/WaterSourceInfo/WaterSourceInfoController.java
  5. 226 0
      pipe-network-service/zksy-admin/src/main/java/com/zksy/web/controller/WaterSupply/WaterUserInfo/WaterUserInfoController.java
  6. 142 0
      pipe-network-service/zksy-admin/src/main/java/com/zksy/web/controller/warning/EarlyWarningDisposeEfficiencyController.java
  7. 62 0
      pipe-network-service/zksy-admin/src/main/java/com/zksy/web/controller/warning/EarlyWarningDisposeStatusController.java
  8. 163 0
      pipe-network-service/zksy-admin/src/main/java/com/zksy/web/controller/warning/EarlyWarningReceiveEfficiencyController.java
  9. 68 0
      pipe-network-service/zksy-admin/src/main/java/com/zksy/web/controller/warning/EarlyWarningTodayController.java
  10. 80 0
      pipe-network-service/zksy-admin/src/main/java/com/zksy/web/controller/warning/EarlyWarningTrendController.java
  11. 8 1
      pipe-network-service/zksy-admin/src/main/resources/application-dev.yml
  12. 8 1
      pipe-network-service/zksy-admin/src/main/resources/application-prod.yml
  13. 1 1
      pipe-network-service/zksy-framework/src/main/java/com/zksy/framework/config/ApplicationConfig.java
  14. 82 0
      pipe-network-service/zksy-system/src/main/java/com/zksy/WaterSupply/WaterPipeInfo/domain/WaterPipeInfo.java
  15. 63 0
      pipe-network-service/zksy-system/src/main/java/com/zksy/WaterSupply/WaterPipeInfo/mapper/WaterPipeInfoMapper.java
  16. 67 0
      pipe-network-service/zksy-system/src/main/java/com/zksy/WaterSupply/WaterPipeInfo/service/IWaterPipeInfoService.java
  17. 85 0
      pipe-network-service/zksy-system/src/main/java/com/zksy/WaterSupply/WaterPipeInfo/service/impl/WaterPipeInfoServiceImpl.java
  18. 197 0
      pipe-network-service/zksy-system/src/main/java/com/zksy/WaterSupply/WaterPlantInfo/domain/WaterPlantInfo.java
  19. 42 0
      pipe-network-service/zksy-system/src/main/java/com/zksy/WaterSupply/WaterPlantInfo/mapper/WaterPlantInfoMapper.java
  20. 43 0
      pipe-network-service/zksy-system/src/main/java/com/zksy/WaterSupply/WaterPlantInfo/service/IWaterPlantInfoService.java
  21. 60 0
      pipe-network-service/zksy-system/src/main/java/com/zksy/WaterSupply/WaterPlantInfo/service/impl/WaterPlantInfoServiceImpl.java
  22. 189 0
      pipe-network-service/zksy-system/src/main/java/com/zksy/WaterSupply/WaterPumpStation/domain/WaterPumpStation.java
  23. 43 0
      pipe-network-service/zksy-system/src/main/java/com/zksy/WaterSupply/WaterPumpStation/mapper/WaterPumpStationMapper.java
  24. 43 0
      pipe-network-service/zksy-system/src/main/java/com/zksy/WaterSupply/WaterPumpStation/service/IWaterPumpStationService.java
  25. 60 0
      pipe-network-service/zksy-system/src/main/java/com/zksy/WaterSupply/WaterPumpStation/service/impl/WaterPumpStationServiceImpl.java
  26. 176 0
      pipe-network-service/zksy-system/src/main/java/com/zksy/WaterSupply/WaterSourceInfo/domain/WaterSourceInfo.java
  27. 30 0
      pipe-network-service/zksy-system/src/main/java/com/zksy/WaterSupply/WaterSourceInfo/mapper/WaterSourceInfoMapper.java
  28. 31 0
      pipe-network-service/zksy-system/src/main/java/com/zksy/WaterSupply/WaterSourceInfo/service/IWaterSourceInfoService.java
  29. 56 0
      pipe-network-service/zksy-system/src/main/java/com/zksy/WaterSupply/WaterSourceInfo/service/impl/WaterSourceInfoServiceImpl.java
  30. 175 0
      pipe-network-service/zksy-system/src/main/java/com/zksy/WaterSupply/WaterUserInfo/domain/WaterUserInfo.java
  31. 29 0
      pipe-network-service/zksy-system/src/main/java/com/zksy/WaterSupply/WaterUserInfo/mapper/WaterUserInfoMapper.java
  32. 30 0
      pipe-network-service/zksy-system/src/main/java/com/zksy/WaterSupply/WaterUserInfo/service/IWaterUserInfoService.java
  33. 55 0
      pipe-network-service/zksy-system/src/main/java/com/zksy/WaterSupply/WaterUserInfo/service/impl/WaterUserInfoServiceImpl.java
  34. 154 0
      pipe-network-service/zksy-system/src/main/java/com/zksy/base/warning/mapper/EarlyWarningMapper.java
  35. 35 0
      pipe-network-service/zksy-system/src/main/java/com/zksy/base/warning/service/IEarlyWarningDisposeEfficiencyService.java
  36. 19 0
      pipe-network-service/zksy-system/src/main/java/com/zksy/base/warning/service/IEarlyWarningDisposeStatusService.java
  37. 45 0
      pipe-network-service/zksy-system/src/main/java/com/zksy/base/warning/service/IEarlyWarningReceiveEfficiencyService.java
  38. 22 0
      pipe-network-service/zksy-system/src/main/java/com/zksy/base/warning/service/IEarlyWarningTodayService.java
  39. 24 0
      pipe-network-service/zksy-system/src/main/java/com/zksy/base/warning/service/IEarlyWarningTrendService.java
  40. 46 0
      pipe-network-service/zksy-system/src/main/java/com/zksy/base/warning/service/impl/EarlyWarningDisposeEfficiencyServiceImpl.java
  41. 24 0
      pipe-network-service/zksy-system/src/main/java/com/zksy/base/warning/service/impl/EarlyWarningDisposeStatusServiceImpl.java
  42. 57 0
      pipe-network-service/zksy-system/src/main/java/com/zksy/base/warning/service/impl/EarlyWarningReceiveEfficiencyServiceImpl.java
  43. 32 0
      pipe-network-service/zksy-system/src/main/java/com/zksy/base/warning/service/impl/EarlyWarningTodayServiceImpl.java
  44. 27 0
      pipe-network-service/zksy-system/src/main/java/com/zksy/base/warning/service/impl/EarlyWarningTrendServiceImpl.java
  45. 133 0
      pipe-network-service/zksy-system/src/main/resources/mapper/WaterSupply/WaterPipeInfo/WaterPipeInfoMapper.xml
  46. 100 0
      pipe-network-service/zksy-system/src/main/resources/mapper/WaterSupply/WaterPlantInfo/WaterPlantInfoMapper.xml
  47. 99 0
      pipe-network-service/zksy-system/src/main/resources/mapper/WaterSupply/WaterPumpStation/WaterPumpStationMapper.xml
  48. 98 0
      pipe-network-service/zksy-system/src/main/resources/mapper/WaterSupply/WaterSourceInfo/WaterSourceInfoMapper.xml
  49. 98 0
      pipe-network-service/zksy-system/src/main/resources/mapper/WaterSupply/WaterUserInfo/WaterUserInfoMapper.xml
  50. 392 0
      pipe-network-service/zksy-system/src/main/resources/mapper/warning/EarlyWarningMapper.xml

+ 290 - 0
pipe-network-service/zksy-admin/src/main/java/com/zksy/web/controller/WaterSupply/WaterPipeInfo/WaterPipeInfoController.java

@@ -0,0 +1,290 @@
+package com.zksy.web.controller.WaterSupply.WaterPipeInfo;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.zksy.WaterSupply.WaterPipeInfo.domain.WaterPipeInfo;
+import com.zksy.WaterSupply.WaterPipeInfo.service.IWaterPipeInfoService;
+import com.zksy.common.annotation.Anonymous;
+import com.zksy.common.core.domain.AjaxResult;
+import com.zksy.common.utils.SecurityUtils;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
+import io.swagger.annotations.ApiResponse;
+import io.swagger.annotations.ApiResponses;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.format.annotation.DateTimeFormat;
+import org.springframework.web.bind.annotation.*;
+
+import java.time.LocalDateTime;
+import java.util.List;
+
+/**
+ * 管网数据统计分析接口
+ */
+@RestController
+@RequestMapping("/api/water/pipe")
+@Api(tags = "供水管网-管网信息数据接口")
+public class WaterPipeInfoController {
+
+    private static final Logger log = LoggerFactory.getLogger(WaterPipeInfoController.class);
+
+    @Autowired
+    private IWaterPipeInfoService waterPipeInfoService;
+
+    // -------------------------- 基础CRUD接口 --------------------------
+    @GetMapping("/page")
+    @ApiOperation(value = "分页查询管网数据", notes = "支持按管网编号、名称、材质、状态、时间范围模糊查询")
+    @ApiResponses({
+            @ApiResponse(code = 200, message = "查询成功", response = AjaxResult.class),
+            @ApiResponse(code = 500, message = "服务器内部错误,查询失败", response = AjaxResult.class)
+    })
+    public AjaxResult queryPage(
+            @ApiParam(value = "页码", defaultValue = "1") @RequestParam(defaultValue = "1") Integer pageNum,
+            @ApiParam(value = "每页大小", defaultValue = "10") @RequestParam(defaultValue = "10") Integer pageSize,
+            @ApiParam(value = "管网编号") @RequestParam(required = false) String pipeCode,
+            @ApiParam(value = "管网名称") @RequestParam(required = false) String pipeName,
+            @ApiParam(value = "管网材质") @RequestParam(required = false) String pipeMaterial,
+            @ApiParam(value = "状态(0正常 1停用)") @RequestParam(required = false) String status,
+            @ApiParam(value = "开始时间(格式:yyyy-MM-dd HH:mm:ss)", example = "2026-01-01 00:00:00") @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime startTime,
+            @ApiParam(value = "结束时间(格式:yyyy-MM-dd HH:mm:ss)", example = "2026-12-31 23:59:59") @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime endTime) {
+        try {
+            Page<WaterPipeInfo> page = new Page<>(pageNum, pageSize);
+            IPage<WaterPipeInfo> resultPage = waterPipeInfoService.queryPage(page, pipeCode, pipeName, pipeMaterial, status, startTime, endTime);
+            return AjaxResult.success("查询成功", resultPage);
+        } catch (Exception e) {
+            log.error("分页查询管网数据异常", e);
+            return AjaxResult.error("查询失败:" + e.getMessage());
+        }
+    }
+
+    @GetMapping("/{id}")
+    @ApiOperation(value = "根据ID查询管网详情", notes = "传入管网ID获取完整信息")
+    @ApiResponses({
+            @ApiResponse(code = 200, message = "查询成功", response = AjaxResult.class),
+            @ApiResponse(code = 404, message = "未找到指定ID的管网信息", response = AjaxResult.class),
+            @ApiResponse(code = 500, message = "服务器内部错误,查询失败", response = AjaxResult.class)
+    })
+    public AjaxResult getById(
+            @ApiParam(value = "管网ID", required = true, example = "1") @PathVariable Long id) {
+        try {
+            WaterPipeInfo data = waterPipeInfoService.getById(id);
+            return data == null ? AjaxResult.warn("未找到该管网信息") : AjaxResult.success("查询成功", data);
+        } catch (Exception e) {
+            log.error("查询管网详情异常", e);
+            return AjaxResult.error("查询失败:" + e.getMessage());
+        }
+    }
+
+    @PostMapping
+    @ApiOperation(value = "新增管网信息", notes = "传入管网实体对象进行新增")
+    @ApiResponses({
+            @ApiResponse(code = 200, message = "新增成功", response = AjaxResult.class),
+            @ApiResponse(code = 400, message = "请求参数错误", response = AjaxResult.class),
+            @ApiResponse(code = 500, message = "服务器内部错误,新增失败", response = AjaxResult.class)
+    })
+    public AjaxResult add(@RequestBody WaterPipeInfo waterPipeInfo) {
+        try {
+            waterPipeInfo.setDelFlag("0");
+            try {
+                waterPipeInfo.setCreateBy(SecurityUtils.getUsername());
+            } catch (Exception e) {
+                waterPipeInfo.setCreateBy("system");
+            }
+            waterPipeInfo.setCreateTime(LocalDateTime.now());
+            boolean result = waterPipeInfoService.save(waterPipeInfo);
+            return result ? AjaxResult.success("新增成功") : AjaxResult.error("新增失败");
+        } catch (Exception e) {
+            log.error("新增管网信息异常", e);
+            return AjaxResult.error("新增失败:" + e.getMessage());
+        }
+    }
+
+    @PutMapping
+    @ApiOperation(value = "修改管网信息", notes = "传入管网实体对象进行修改,仅更新非空字段")
+    @ApiResponses({
+            @ApiResponse(code = 200, message = "修改成功", response = AjaxResult.class),
+            @ApiResponse(code = 400, message = "请求参数错误", response = AjaxResult.class),
+            @ApiResponse(code = 500, message = "服务器内部错误,修改失败", response = AjaxResult.class)
+    })
+    public AjaxResult update(@RequestBody WaterPipeInfo waterPipeInfo) {
+        try {
+            // 禁止修改关键字段
+            waterPipeInfo.setDelFlag(null);
+            waterPipeInfo.setCreateBy(null);
+            waterPipeInfo.setCreateTime(null);
+
+            try {
+                waterPipeInfo.setUpdateBy(SecurityUtils.getUsername());
+            } catch (Exception e) {
+                waterPipeInfo.setUpdateBy("system");
+            }
+            waterPipeInfo.setUpdateTime(LocalDateTime.now());
+
+            boolean result = waterPipeInfoService.updateById(waterPipeInfo);
+            return result ? AjaxResult.success("修改成功") : AjaxResult.error("修改失败");
+        } catch (Exception e) {
+            log.error("修改管网信息异常", e);
+            return AjaxResult.error("修改失败:" + e.getMessage());
+        }
+    }
+
+    @DeleteMapping("/{ids}")
+    @ApiOperation(value = "批量逻辑删除管网信息", notes = "多个ID用逗号分隔,逻辑删除(移入回收站),不物理删除数据")
+    @ApiResponses({
+            @ApiResponse(code = 200, message = "修改成功", response = AjaxResult.class),
+            @ApiResponse(code = 400, message = "请求参数错误", response = AjaxResult.class),
+            @ApiResponse(code = 500, message = "服务器内部错误,修改失败", response = AjaxResult.class)
+    })
+    public AjaxResult remove(
+            @ApiParam(value = "管网ID数组,多个用逗号分隔", required = true, example = "1,2,3") @PathVariable Long[] ids) {
+        try {
+            log.info("开始删除管网数据,ids: {}", (Object) ids);
+            boolean result = waterPipeInfoService.removeByIds(List.of(ids));
+            return result
+                    ? AjaxResult.success("删除成功,已移入回收站,共删除 " + ids.length + " 条数据")
+                    : AjaxResult.error("删除失败");
+        } catch (Exception e) {
+            log.error("删除管网数据异常", e);
+            return AjaxResult.error("删除失败:" + e.getMessage());
+        }
+    }
+
+    // -------------------------- 统计分析接口 --------------------------
+    @GetMapping("/latest")
+    @ApiOperation(value = "获取最新添加的管网信息", notes = "返回创建时间最晚的一条管网数据")
+    @ApiResponses({
+            @ApiResponse(code = 200, message = "查询成功", response = AjaxResult.class),
+            @ApiResponse(code = 500, message = "服务器内部错误,查询失败", response = AjaxResult.class)
+    })
+    public AjaxResult getLatestPipe() {
+        try {
+            WaterPipeInfo data = waterPipeInfoService.getLatestPipe();
+            return data == null ? AjaxResult.warn("未查询到管网数据") : AjaxResult.success("查询成功", data);
+        } catch (Exception e) {
+            log.error("查询最新管网异常", e);
+            return AjaxResult.error("查询失败:" + e.getMessage());
+        }
+    }
+
+    @GetMapping("/visualization/stat/status")
+    @ApiOperation(value = "按状态统计管网数据", notes = "统计正常和停用状态的管网数量")
+    @ApiResponses({
+            @ApiResponse(code = 200, message = "统计成功", response = AjaxResult.class),
+            @ApiResponse(code = 500, message = "服务器内部错误,统计失败", response = AjaxResult.class)
+    })
+    public AjaxResult statPipeByStatus() {
+        try {
+            return AjaxResult.success("统计成功", waterPipeInfoService.statPipeByStatus());
+        } catch (Exception e) {
+            log.error("按状态统计管网异常", e);
+            return AjaxResult.error("统计失败:" + e.getMessage());
+        }
+    }
+
+    @GetMapping("/visualization/stat/material")
+    @ApiOperation(value = "按材质统计管网数据", notes = "统计不同材质管网的数量和总长度")
+    @ApiResponses({
+            @ApiResponse(code = 200, message = "统计成功", response = AjaxResult.class),
+            @ApiResponse(code = 500, message = "服务器内部错误,统计失败", response = AjaxResult.class)
+    })
+    public AjaxResult statPipeByMaterial() {
+        try {
+            return AjaxResult.success("统计成功", waterPipeInfoService.statPipeByMaterial());
+        } catch (Exception e) {
+            log.error("按材质统计管网异常", e);
+            return AjaxResult.error("统计失败:" + e.getMessage());
+        }
+    }
+
+    @GetMapping("/visualization/stat/overall")
+    @ApiOperation(value = "获取管网整体统计数据", notes = "返回总管网数、总长度、运行中数量、停用数量")
+    @ApiResponses({
+            @ApiResponse(code = 200, message = "统计成功", response = AjaxResult.class),
+            @ApiResponse(code = 500, message = "服务器内部错误,统计失败", response = AjaxResult.class)
+    })
+    public AjaxResult getOverallStatistics() {
+        try {
+            return AjaxResult.success("统计成功", waterPipeInfoService.getPipeOverallStatistics());
+        } catch (Exception e) {
+            log.error("获取整体统计异常", e);
+            return AjaxResult.error("统计失败:" + e.getMessage());
+        }
+    }
+
+    // -------------------------- 回收站接口 --------------------------
+    @GetMapping("/recycle/list")
+    @ApiOperation(value = "查询回收站数据", notes = "分页查询已删除的管网数据,支持筛选和时间范围")
+    @ApiResponses({
+            @ApiResponse(code = 200, message = "查询成功", response = AjaxResult.class),
+            @ApiResponse(code = 500, message = "服务器内部错误,查询失败", response = AjaxResult.class)
+    })
+    public AjaxResult recycleList(
+            @ApiParam(value = "页码", defaultValue = "1") @RequestParam(defaultValue = "1") Integer pageNum,
+            @ApiParam(value = "每页大小", defaultValue = "10") @RequestParam(defaultValue = "10") Integer pageSize,
+            @ApiParam(value = "管网编号") @RequestParam(required = false) String pipeCode,
+            @ApiParam(value = "管网名称") @RequestParam(required = false) String pipeName,
+            @ApiParam(value = "管网材质") @RequestParam(required = false) String pipeMaterial,
+            @ApiParam(value = "开始时间(格式:yyyy-MM-dd HH:mm:ss)", example = "2026-01-01 00:00:00") @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime startTime,
+            @ApiParam(value = "结束时间(格式:yyyy-MM-dd HH:mm:ss)", example = "2026-12-31 23:59:59") @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime endTime) {
+        try {
+            Page<WaterPipeInfo> page = new Page<>(pageNum, pageSize);
+            IPage<WaterPipeInfo> resultPage = waterPipeInfoService.queryDeletedPage(page, pipeCode, pipeName, pipeMaterial, startTime, endTime);
+            return AjaxResult.success("查询成功", resultPage);
+        } catch (Exception e) {
+            log.error("查询回收站数据异常", e);
+            return AjaxResult.error("查询失败:" + e.getMessage());
+        }
+    }
+
+    @PostMapping("/recycle/restore/{ids}")
+    @ApiOperation(value = "批量恢复已删除数据", notes = "多个ID用逗号分隔,将数据从回收站恢复为正常状态")
+    @ApiResponses({
+            @ApiResponse(code = 200, message = "恢复成功", response = AjaxResult.class),
+            @ApiResponse(code = 400, message = "请选择要恢复的数据", response = AjaxResult.class),
+            @ApiResponse(code = 500, message = "服务器内部错误,恢复失败", response = AjaxResult.class)
+    })
+    public AjaxResult restore(
+            @ApiParam(value = "管网ID数组,多个用逗号分隔", required = true, example = "3,4") @PathVariable Long[] ids) {
+        try {
+            log.info("开始恢复管网数据,ids: {}", (Object) ids);
+            String updateBy = "system";
+            try {
+                updateBy = SecurityUtils.getUsername();
+            } catch (Exception e) {
+                log.warn("未获取到登录用户,使用默认值system");
+            }
+
+            boolean result = waterPipeInfoService.restoreByIds(List.of(ids), updateBy);
+            return result
+                    ? AjaxResult.success("恢复成功,共恢复 " + ids.length + " 条数据")
+                    : AjaxResult.error("恢复失败");
+        } catch (Exception e) {
+            log.error("恢复数据异常", e);
+            return AjaxResult.error("恢复失败:" + e.getMessage());
+        }
+    }
+
+    @DeleteMapping("/recycle/delete/{ids}")
+    @ApiOperation(value = "批量彻底删除数据(不可恢复)", notes = "多个ID用逗号分隔,物理删除数据库中的数据,谨慎使用")
+    @ApiResponses({
+            @ApiResponse(code = 200, message = "恢复成功", response = AjaxResult.class),
+            @ApiResponse(code = 400, message = "请选择要恢复的数据", response = AjaxResult.class),
+            @ApiResponse(code = 500, message = "服务器内部错误,恢复失败", response = AjaxResult.class)
+    })
+    public AjaxResult deletePhysically(
+            @ApiParam(value = "管网ID数组,多个用逗号分隔", required = true, example = "5") @PathVariable Long[] ids) {
+        try {
+            log.info("开始彻底删除管网数据,ids: {}", (Object) ids);
+            boolean result = waterPipeInfoService.deleteByIdsPhysically(List.of(ids));
+            return result
+                    ? AjaxResult.success("彻底删除成功,共删除 " + ids.length + " 条数据")
+                    : AjaxResult.error("彻底删除失败");
+        } catch (Exception e) {
+            log.error("彻底删除数据异常", e);
+            return AjaxResult.error("彻底删除失败:" + e.getMessage());
+        }
+    }
+}

+ 227 - 0
pipe-network-service/zksy-admin/src/main/java/com/zksy/web/controller/WaterSupply/WaterPlantInfo/WaterPlantInfoController.java

@@ -0,0 +1,227 @@
+package com.zksy.web.controller.WaterSupply.WaterPlantInfo;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.zksy.WaterSupply.WaterPlantInfo.domain.WaterPlantInfo;
+import com.zksy.WaterSupply.WaterPlantInfo.service.IWaterPlantInfoService;
+import com.zksy.common.core.domain.AjaxResult;
+import com.zksy.common.utils.SecurityUtils;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
+import io.swagger.annotations.ApiResponse;
+import io.swagger.annotations.ApiResponses;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.format.annotation.DateTimeFormat;
+import org.springframework.web.bind.annotation.*;
+
+import java.time.LocalDateTime;
+import java.util.List;
+
+/**
+ * 水厂信息管理接口
+ */
+@RestController
+@RequestMapping("/api/water/plantInfo")
+@Api(tags = "供水管网-水厂信息数据接口")
+public class WaterPlantInfoController {
+
+    private static final Logger log = LoggerFactory.getLogger(WaterPlantInfoController.class);
+
+    @Autowired
+    private IWaterPlantInfoService waterPlantInfoService;
+
+    // -------------------------- 基础CRUD接口 --------------------------
+    @GetMapping("/page")
+    @ApiOperation(value = "分页查询水厂数据", notes = "支持按水厂编号、名称、状态、负责人、时间范围模糊查询")
+    @ApiResponses({
+            @ApiResponse(code = 200, message = "查询成功", response = AjaxResult.class),
+            @ApiResponse(code = 500, message = "服务器内部错误,查询失败", response = AjaxResult.class)
+    })
+    public AjaxResult queryPage(
+            @ApiParam(value = "页码", defaultValue = "1") @RequestParam(defaultValue = "1") Integer pageNum,
+            @ApiParam(value = "每页大小", defaultValue = "10") @RequestParam(defaultValue = "10") Integer pageSize,
+            @ApiParam(value = "水厂编号") @RequestParam(required = false) String plantCode,
+            @ApiParam(value = "水厂名称") @RequestParam(required = false) String plantName,
+            @ApiParam(value = "运行状态(0正常 1停产)") @RequestParam(required = false) String status,
+            @ApiParam(value = "负责人") @RequestParam(required = false) String principal,
+            @ApiParam(value = "开始时间(格式:yyyy-MM-dd HH:mm:ss)", example = "2026-01-01 00:00:00") @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime startTime,
+            @ApiParam(value = "结束时间(格式:yyyy-MM-dd HH:mm:ss)", example = "2026-12-31 23:59:59") @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime endTime) {
+        try {
+            Page<WaterPlantInfo> page = new Page<>(pageNum, pageSize);
+            IPage<WaterPlantInfo> resultPage = waterPlantInfoService.queryPage(page, plantCode, plantName, status, principal, startTime, endTime);
+            return AjaxResult.success("查询成功", resultPage);
+        } catch (Exception e) {
+            log.error("分页查询水厂数据异常", e);
+            return AjaxResult.error("查询失败:" + e.getMessage());
+        }
+    }
+
+    @GetMapping("/{id}")
+    @ApiOperation(value = "根据ID查询水厂详情", notes = "传入水厂ID获取完整信息")
+    @ApiResponses({
+            @ApiResponse(code = 200, message = "查询成功", response = AjaxResult.class),
+            @ApiResponse(code = 404, message = "未找到指定ID的水厂信息", response = AjaxResult.class),
+            @ApiResponse(code = 500, message = "服务器内部错误,查询失败", response = AjaxResult.class)
+    })
+    public AjaxResult getById(
+            @ApiParam(value = "水厂ID", required = true, example = "1") @PathVariable Long id) {
+        try {
+            WaterPlantInfo data = waterPlantInfoService.getById(id);
+            return data == null ? AjaxResult.warn("未找到该水厂信息") : AjaxResult.success("查询成功", data);
+        } catch (Exception e) {
+            log.error("查询水厂详情异常", e);
+            return AjaxResult.error("查询失败:" + e.getMessage());
+        }
+    }
+
+    @PostMapping
+    @ApiOperation(value = "新增水厂信息", notes = "传入水厂实体对象进行新增")
+    @ApiResponses({
+            @ApiResponse(code = 200, message = "新增成功", response = AjaxResult.class),
+            @ApiResponse(code = 400, message = "请求参数错误", response = AjaxResult.class),
+            @ApiResponse(code = 500, message = "服务器内部错误,新增失败", response = AjaxResult.class)
+    })
+    public AjaxResult add(@RequestBody WaterPlantInfo waterPlantInfo) {
+        try {
+            waterPlantInfo.setDelFlag("0");
+            try {
+                waterPlantInfo.setCreateBy(SecurityUtils.getUsername());
+            } catch (Exception e) {
+                waterPlantInfo.setCreateBy("system");
+            }
+            waterPlantInfo.setCreateTime(LocalDateTime.now());
+            boolean result = waterPlantInfoService.save(waterPlantInfo);
+            return result ? AjaxResult.success("新增成功") : AjaxResult.error("新增失败");
+        } catch (Exception e) {
+            log.error("新增水厂信息异常", e);
+            return AjaxResult.error("新增失败:" + e.getMessage());
+        }
+    }
+
+    @PutMapping
+    @ApiOperation(value = "修改水厂信息", notes = "传入水厂实体对象进行修改,仅更新非空字段")
+    @ApiResponses({
+            @ApiResponse(code = 200, message = "修改成功", response = AjaxResult.class),
+            @ApiResponse(code = 400, message = "请求参数错误", response = AjaxResult.class),
+            @ApiResponse(code = 500, message = "服务器内部错误,修改失败", response = AjaxResult.class)
+    })
+    public AjaxResult update(@RequestBody WaterPlantInfo waterPlantInfo) {
+        try {
+            // 禁止修改关键字段
+            waterPlantInfo.setDelFlag(null);
+            waterPlantInfo.setCreateBy(null);
+            waterPlantInfo.setCreateTime(null);
+
+            try {
+                waterPlantInfo.setUpdateBy(SecurityUtils.getUsername());
+            } catch (Exception e) {
+                waterPlantInfo.setUpdateBy("system");
+            }
+            waterPlantInfo.setUpdateTime(LocalDateTime.now());
+
+            boolean result = waterPlantInfoService.updateById(waterPlantInfo);
+            return result ? AjaxResult.success("修改成功") : AjaxResult.error("修改失败");
+        } catch (Exception e) {
+            log.error("修改水厂信息异常", e);
+            return AjaxResult.error("修改失败:" + e.getMessage());
+        }
+    }
+
+    @DeleteMapping("/{ids}")
+    @ApiOperation(value = "批量逻辑删除水厂信息", notes = "多个ID用逗号分隔,逻辑删除(移入回收站),不物理删除数据")
+    @ApiResponses({
+            @ApiResponse(code = 200, message = "修改成功", response = AjaxResult.class),
+            @ApiResponse(code = 400, message = "请求参数错误", response = AjaxResult.class),
+            @ApiResponse(code = 500, message = "服务器内部错误,修改失败", response = AjaxResult.class)
+    })
+    public AjaxResult remove(
+            @ApiParam(value = "水厂ID数组,多个用逗号分隔", required = true, example = "1,2,3") @PathVariable Long[] ids) {
+        try {
+            log.info("开始删除水厂数据,ids: {}", (Object) ids);
+            boolean result = waterPlantInfoService.removeByIds(List.of(ids));
+            return result
+                    ? AjaxResult.success("删除成功,已移入回收站,共删除 " + ids.length + " 条数据")
+                    : AjaxResult.error("删除失败");
+        } catch (Exception e) {
+            log.error("删除水厂数据异常", e);
+            return AjaxResult.error("删除失败:" + e.getMessage());
+        }
+    }
+
+    // -------------------------- 回收站接口 --------------------------
+    @GetMapping("/recycle/list")
+    @ApiOperation(value = "查询回收站数据", notes = "分页查询已删除的水厂数据,支持筛选和时间范围")
+    @ApiResponses({
+            @ApiResponse(code = 200, message = "查询成功", response = AjaxResult.class),
+            @ApiResponse(code = 500, message = "服务器内部错误,查询失败", response = AjaxResult.class)
+    })
+    public AjaxResult recycleList(
+            @ApiParam(value = "页码", defaultValue = "1") @RequestParam(defaultValue = "1") Integer pageNum,
+            @ApiParam(value = "每页大小", defaultValue = "10") @RequestParam(defaultValue = "10") Integer pageSize,
+            @ApiParam(value = "水厂编号") @RequestParam(required = false) String plantCode,
+            @ApiParam(value = "水厂名称") @RequestParam(required = false) String plantName,
+            @ApiParam(value = "运行状态(0正常 1停产)") @RequestParam(required = false) String status,
+            @ApiParam(value = "开始时间(格式:yyyy-MM-dd HH:mm:ss)", example = "2026-01-01 00:00:00") @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime startTime,
+            @ApiParam(value = "结束时间(格式:yyyy-MM-dd HH:mm:ss)", example = "2026-12-31 23:59:59") @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime endTime) {
+        try {
+            Page<WaterPlantInfo> page = new Page<>(pageNum, pageSize);
+            IPage<WaterPlantInfo> resultPage = waterPlantInfoService.queryDeletedPage(page, plantCode, plantName, status, startTime, endTime);
+            return AjaxResult.success("查询成功", resultPage);
+        } catch (Exception e) {
+            log.error("查询回收站数据异常", e);
+            return AjaxResult.error("查询失败:" + e.getMessage());
+        }
+    }
+
+    @PostMapping("/recycle/restore/{ids}")
+    @ApiOperation(value = "批量恢复已删除数据", notes = "多个ID用逗号分隔,将数据从回收站恢复为正常状态")
+    @ApiResponses({
+            @ApiResponse(code = 200, message = "恢复成功", response = AjaxResult.class),
+            @ApiResponse(code = 400, message = "请选择要恢复的数据", response = AjaxResult.class),
+            @ApiResponse(code = 500, message = "服务器内部错误,恢复失败", response = AjaxResult.class)
+    })
+    public AjaxResult restore(
+            @ApiParam(value = "水厂ID数组,多个用逗号分隔", required = true, example = "3,4") @PathVariable Long[] ids) {
+        try {
+            log.info("开始恢复水厂数据,ids: {}", (Object) ids);
+            String updateBy = "system";
+            try {
+                updateBy = SecurityUtils.getUsername();
+            } catch (Exception e) {
+                log.warn("未获取到登录用户,使用默认值system");
+            }
+
+            boolean result = waterPlantInfoService.restoreByIds(List.of(ids), updateBy);
+            return result
+                    ? AjaxResult.success("恢复成功,共恢复 " + ids.length + " 条数据")
+                    : AjaxResult.error("恢复失败");
+        } catch (Exception e) {
+            log.error("恢复数据异常", e);
+            return AjaxResult.error("恢复失败:" + e.getMessage());
+        }
+    }
+
+    @DeleteMapping("/recycle/delete/{ids}")
+    @ApiOperation(value = "批量彻底删除数据(不可恢复)", notes = "多个ID用逗号分隔,物理删除数据库中的数据,谨慎使用")
+    @ApiResponses({
+            @ApiResponse(code = 200, message = "恢复成功", response = AjaxResult.class),
+            @ApiResponse(code = 400, message = "请选择要恢复的数据", response = AjaxResult.class),
+            @ApiResponse(code = 500, message = "服务器内部错误,恢复失败", response = AjaxResult.class)
+    })
+    public AjaxResult deletePhysically(
+            @ApiParam(value = "水厂ID数组,多个用逗号分隔", required = true, example = "5") @PathVariable Long[] ids) {
+        try {
+            log.info("开始彻底删除水厂数据,ids: {}", (Object) ids);
+            boolean result = waterPlantInfoService.deleteByIdsPhysically(List.of(ids));
+            return result
+                    ? AjaxResult.success("彻底删除成功,共删除 " + ids.length + " 条数据")
+                    : AjaxResult.error("彻底删除失败");
+        } catch (Exception e) {
+            log.error("彻底删除数据异常", e);
+            return AjaxResult.error("彻底删除失败:" + e.getMessage());
+        }
+    }
+}

+ 227 - 0
pipe-network-service/zksy-admin/src/main/java/com/zksy/web/controller/WaterSupply/WaterPumpStation/WaterPumpStationController.java

@@ -0,0 +1,227 @@
+package com.zksy.web.controller.WaterSupply.WaterPumpStation;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.zksy.WaterSupply.WaterPumpStation.domain.WaterPumpStation;
+import com.zksy.WaterSupply.WaterPumpStation.service.IWaterPumpStationService;
+import com.zksy.common.core.domain.AjaxResult;
+import com.zksy.common.utils.SecurityUtils;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
+import io.swagger.annotations.ApiResponse;
+import io.swagger.annotations.ApiResponses;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.format.annotation.DateTimeFormat;
+import org.springframework.web.bind.annotation.*;
+
+import java.time.LocalDateTime;
+import java.util.List;
+
+/**
+ * 泵站信息管理接口
+ */
+@RestController
+@RequestMapping("/api/water/pumpStation")
+@Api(tags = "供水管网-泵站信息数据接口")
+public class WaterPumpStationController {
+
+    private static final Logger log = LoggerFactory.getLogger(WaterPumpStationController.class);
+
+    @Autowired
+    private IWaterPumpStationService pumpStationService;
+
+    // -------------------------- 基础CRUD接口 --------------------------
+    @GetMapping("/page")
+    @ApiOperation(value = "分页查询泵站数据", notes = "支持按泵站编号、名称、状态、负责人、时间范围模糊查询")
+    @ApiResponses({
+            @ApiResponse(code = 200, message = "查询成功", response = AjaxResult.class),
+            @ApiResponse(code = 500, message = "服务器内部错误,查询失败", response = AjaxResult.class)
+    })
+    public AjaxResult queryPage(
+            @ApiParam(value = "页码", defaultValue = "1") @RequestParam(defaultValue = "1") Integer pageNum,
+            @ApiParam(value = "每页大小", defaultValue = "10") @RequestParam(defaultValue = "10") Integer pageSize,
+            @ApiParam(value = "泵站编号") @RequestParam(required = false) String stationCode,
+            @ApiParam(value = "泵站名称") @RequestParam(required = false) String stationName,
+            @ApiParam(value = "运行状态(0正常 1故障 2检修)") @RequestParam(required = false) String status,
+            @ApiParam(value = "负责人") @RequestParam(required = false) String principal,
+            @ApiParam(value = "开始时间(格式:yyyy-MM-dd HH:mm:ss)", example = "2026-01-01 00:00:00") @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime startTime,
+            @ApiParam(value = "结束时间(格式:yyyy-MM-dd HH:mm:ss)", example = "2026-12-31 23:59:59") @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime endTime) {
+        try {
+            Page<WaterPumpStation> page = new Page<>(pageNum, pageSize);
+            IPage<WaterPumpStation> resultPage = pumpStationService.queryPage(page, stationCode, stationName, status, principal, startTime, endTime);
+            return AjaxResult.success("查询成功", resultPage);
+        } catch (Exception e) {
+            log.error("分页查询泵站数据异常", e);
+            return AjaxResult.error("查询失败:" + e.getMessage());
+        }
+    }
+
+    @GetMapping("/{id}")
+    @ApiOperation(value = "根据ID查询泵站详情", notes = "传入泵站ID获取完整信息")
+    @ApiResponses({
+            @ApiResponse(code = 200, message = "查询成功", response = AjaxResult.class),
+            @ApiResponse(code = 404, message = "未找到指定ID的泵站信息", response = AjaxResult.class),
+            @ApiResponse(code = 500, message = "服务器内部错误,查询失败", response = AjaxResult.class)
+    })
+    public AjaxResult getById(
+            @ApiParam(value = "泵站ID", required = true, example = "1") @PathVariable Long id) {
+        try {
+            WaterPumpStation data = pumpStationService.getById(id);
+            return data == null ? AjaxResult.warn("未找到该泵站信息") : AjaxResult.success("查询成功", data);
+        } catch (Exception e) {
+            log.error("查询泵站详情异常", e);
+            return AjaxResult.error("查询失败:" + e.getMessage());
+        }
+    }
+
+    @PostMapping
+    @ApiOperation(value = "新增泵站信息", notes = "传入泵站实体对象进行新增")
+    @ApiResponses({
+            @ApiResponse(code = 200, message = "新增成功", response = AjaxResult.class),
+            @ApiResponse(code = 400, message = "请求参数错误", response = AjaxResult.class),
+            @ApiResponse(code = 500, message = "服务器内部错误,新增失败", response = AjaxResult.class)
+    })
+    public AjaxResult add(@RequestBody WaterPumpStation pumpStation) {
+        try {
+            pumpStation.setDelFlag("0");
+            try {
+                pumpStation.setCreateBy(SecurityUtils.getUsername());
+            } catch (Exception e) {
+                pumpStation.setCreateBy("system");
+            }
+            pumpStation.setCreateTime(LocalDateTime.now());
+            boolean result = pumpStationService.save(pumpStation);
+            return result ? AjaxResult.success("新增成功") : AjaxResult.error("新增失败");
+        } catch (Exception e) {
+            log.error("新增泵站信息异常", e);
+            return AjaxResult.error("新增失败:" + e.getMessage());
+        }
+    }
+
+    @PutMapping
+    @ApiOperation(value = "修改泵站信息", notes = "传入泵站实体对象进行修改,仅更新非空字段")
+    @ApiResponses({
+            @ApiResponse(code = 200, message = "修改成功", response = AjaxResult.class),
+            @ApiResponse(code = 400, message = "请求参数错误", response = AjaxResult.class),
+            @ApiResponse(code = 500, message = "服务器内部错误,修改失败", response = AjaxResult.class)
+    })
+    public AjaxResult update(@RequestBody WaterPumpStation pumpStation) {
+        try {
+            // 禁止修改关键字段
+            pumpStation.setDelFlag(null);
+            pumpStation.setCreateBy(null);
+            pumpStation.setCreateTime(null);
+
+            try {
+                pumpStation.setUpdateBy(SecurityUtils.getUsername());
+            } catch (Exception e) {
+                pumpStation.setUpdateBy("system");
+            }
+            pumpStation.setUpdateTime(LocalDateTime.now());
+
+            boolean result = pumpStationService.updateById(pumpStation);
+            return result ? AjaxResult.success("修改成功") : AjaxResult.error("修改失败");
+        } catch (Exception e) {
+            log.error("修改泵站信息异常", e);
+            return AjaxResult.error("修改失败:" + e.getMessage());
+        }
+    }
+
+    @DeleteMapping("/{ids}")
+    @ApiOperation(value = "批量逻辑删除泵站信息", notes = "多个ID用逗号分隔,逻辑删除(移入回收站),不物理删除数据")
+    @ApiResponses({
+            @ApiResponse(code = 200, message = "修改成功", response = AjaxResult.class),
+            @ApiResponse(code = 400, message = "请求参数错误", response = AjaxResult.class),
+            @ApiResponse(code = 500, message = "服务器内部错误,修改失败", response = AjaxResult.class)
+    })
+    public AjaxResult remove(
+            @ApiParam(value = "泵站ID数组,多个用逗号分隔", required = true, example = "1,2,3") @PathVariable Long[] ids) {
+        try {
+            log.info("开始删除泵站数据,ids: {}", (Object) ids);
+            boolean result = pumpStationService.removeByIds(List.of(ids));
+            return result
+                    ? AjaxResult.success("删除成功,已移入回收站,共删除 " + ids.length + " 条数据")
+                    : AjaxResult.error("删除失败");
+        } catch (Exception e) {
+            log.error("删除泵站数据异常", e);
+            return AjaxResult.error("删除失败:" + e.getMessage());
+        }
+    }
+
+    // -------------------------- 回收站接口 --------------------------
+    @GetMapping("/recycle/list")
+    @ApiOperation(value = "查询回收站数据", notes = "分页查询已删除的泵站数据,支持筛选和时间范围")
+    @ApiResponses({
+            @ApiResponse(code = 200, message = "查询成功", response = AjaxResult.class),
+            @ApiResponse(code = 500, message = "服务器内部错误,查询失败", response = AjaxResult.class)
+    })
+    public AjaxResult recycleList(
+            @ApiParam(value = "页码", defaultValue = "1") @RequestParam(defaultValue = "1") Integer pageNum,
+            @ApiParam(value = "每页大小", defaultValue = "10") @RequestParam(defaultValue = "10") Integer pageSize,
+            @ApiParam(value = "泵站编号") @RequestParam(required = false) String stationCode,
+            @ApiParam(value = "泵站名称") @RequestParam(required = false) String stationName,
+            @ApiParam(value = "运行状态(0正常 1故障 2检修)") @RequestParam(required = false) String status,
+            @ApiParam(value = "开始时间(格式:yyyy-MM-dd HH:mm:ss)", example = "2026-01-01 00:00:00") @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime startTime,
+            @ApiParam(value = "结束时间(格式:yyyy-MM-dd HH:mm:ss)", example = "2026-12-31 23:59:59") @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime endTime) {
+        try {
+            Page<WaterPumpStation> page = new Page<>(pageNum, pageSize);
+            IPage<WaterPumpStation> resultPage = pumpStationService.queryDeletedPage(page, stationCode, stationName, status, startTime, endTime);
+            return AjaxResult.success("查询成功", resultPage);
+        } catch (Exception e) {
+            log.error("查询回收站数据异常", e);
+            return AjaxResult.error("查询失败:" + e.getMessage());
+        }
+    }
+
+    @PostMapping("/recycle/restore/{ids}")
+    @ApiOperation(value = "批量恢复已删除数据", notes = "多个ID用逗号分隔,将数据从回收站恢复为正常状态")
+    @ApiResponses({
+            @ApiResponse(code = 200, message = "恢复成功", response = AjaxResult.class),
+            @ApiResponse(code = 400, message = "请选择要恢复的数据", response = AjaxResult.class),
+            @ApiResponse(code = 500, message = "服务器内部错误,恢复失败", response = AjaxResult.class)
+    })
+    public AjaxResult restore(
+            @ApiParam(value = "泵站ID数组,多个用逗号分隔", required = true, example = "3,4") @PathVariable Long[] ids) {
+        try {
+            log.info("开始恢复泵站数据,ids: {}", (Object) ids);
+            String updateBy = "system";
+            try {
+                updateBy = SecurityUtils.getUsername();
+            } catch (Exception e) {
+                log.warn("未获取到登录用户,使用默认值system");
+            }
+
+            boolean result = pumpStationService.restoreByIds(List.of(ids), updateBy);
+            return result
+                    ? AjaxResult.success("恢复成功,共恢复 " + ids.length + " 条数据")
+                    : AjaxResult.error("恢复失败");
+        } catch (Exception e) {
+            log.error("恢复数据异常", e);
+            return AjaxResult.error("恢复失败:" + e.getMessage());
+        }
+    }
+
+    @DeleteMapping("/recycle/delete/{ids}")
+    @ApiOperation(value = "批量彻底删除数据(不可恢复)", notes = "多个ID用逗号分隔,物理删除数据库中的数据,谨慎使用")
+    @ApiResponses({
+            @ApiResponse(code = 200, message = "恢复成功", response = AjaxResult.class),
+            @ApiResponse(code = 400, message = "请选择要恢复的数据", response = AjaxResult.class),
+            @ApiResponse(code = 500, message = "服务器内部错误,恢复失败", response = AjaxResult.class)
+    })
+    public AjaxResult deletePhysically(
+            @ApiParam(value = "泵站ID数组,多个用逗号分隔", required = true, example = "5") @PathVariable Long[] ids) {
+        try {
+            log.info("开始彻底删除泵站数据,ids: {}", (Object) ids);
+            boolean result = pumpStationService.deleteByIdsPhysically(List.of(ids));
+            return result
+                    ? AjaxResult.success("彻底删除成功,共删除 " + ids.length + " 条数据")
+                    : AjaxResult.error("彻底删除失败");
+        } catch (Exception e) {
+            log.error("彻底删除数据异常", e);
+            return AjaxResult.error("彻底删除失败:" + e.getMessage());
+        }
+    }
+}

+ 225 - 0
pipe-network-service/zksy-admin/src/main/java/com/zksy/web/controller/WaterSupply/WaterSourceInfo/WaterSourceInfoController.java

@@ -0,0 +1,225 @@
+package com.zksy.web.controller.WaterSupply.WaterSourceInfo;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.zksy.WaterSupply.WaterSourceInfo.domain.WaterSourceInfo;
+import com.zksy.WaterSupply.WaterSourceInfo.service.IWaterSourceInfoService;
+import com.zksy.common.core.domain.AjaxResult;
+import com.zksy.common.utils.SecurityUtils;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
+import io.swagger.annotations.ApiResponse;
+import io.swagger.annotations.ApiResponses;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.format.annotation.DateTimeFormat;
+import org.springframework.web.bind.annotation.*;
+import java.time.LocalDateTime;
+import java.util.List;
+
+/**
+ * 水源地信息管理接口
+ */
+@RestController
+@RequestMapping("/api/water/sourceInfo")
+@Api(tags = "供水管网-水源地信息数据接口")
+public class WaterSourceInfoController {
+
+    private static final Logger log = LoggerFactory.getLogger(WaterSourceInfoController.class);
+
+    @Autowired
+    private IWaterSourceInfoService waterSourceInfoService;
+
+    // -------------------------- 基础CRUD接口 --------------------------
+    @GetMapping("/page")
+    @ApiOperation(value = "分页查询水源地数据", notes = "支持按水源地ID、名称、状态、所属单位、时间范围模糊查询")
+    @ApiResponses({
+            @ApiResponse(code = 200, message = "查询成功", response = AjaxResult.class),
+            @ApiResponse(code = 500, message = "服务器内部错误,查询失败", response = AjaxResult.class)
+    })
+    public AjaxResult queryPage(
+            @ApiParam(value = "页码", defaultValue = "1") @RequestParam(defaultValue = "1") Integer pageNum,
+            @ApiParam(value = "每页大小", defaultValue = "10") @RequestParam(defaultValue = "10") Integer pageSize,
+            @ApiParam(value = "水源地ID") @RequestParam(required = false) String sourceId,
+            @ApiParam(value = "水源地名称") @RequestParam(required = false) String sourceName,
+            @ApiParam(value = "状态(0正常 1异常)") @RequestParam(required = false) String status,
+            @ApiParam(value = "所属单位") @RequestParam(required = false) String unit,
+            @ApiParam(value = "开始时间(格式:yyyy-MM-dd HH:mm:ss)", example = "2026-01-01 00:00:00") @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime startTime,
+            @ApiParam(value = "结束时间(格式:yyyy-MM-dd HH:mm:ss)", example = "2026-12-31 23:59:59") @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime endTime) {
+        try {
+            Page<WaterSourceInfo> page = new Page<>(pageNum, pageSize);
+            IPage<WaterSourceInfo> resultPage = waterSourceInfoService.queryPage(page, sourceId, sourceName, status, unit, startTime, endTime);
+            return AjaxResult.success("查询成功", resultPage);
+        } catch (Exception e) {
+            log.error("分页查询水源地数据异常", e);
+            return AjaxResult.error("查询失败:" + e.getMessage());
+        }
+    }
+
+    @GetMapping("/{id}")
+    @ApiOperation(value = "根据ID查询水源地详情", notes = "传入水源地ID获取完整信息")
+    @ApiResponses({
+            @ApiResponse(code = 200, message = "查询成功", response = AjaxResult.class),
+            @ApiResponse(code = 404, message = "未找到指定ID的水源地信息", response = AjaxResult.class),
+            @ApiResponse(code = 500, message = "服务器内部错误,查询失败", response = AjaxResult.class)
+    })
+    public AjaxResult getById(
+            @ApiParam(value = "水源地ID", required = true, example = "0") @PathVariable Long id) {
+        try {
+            WaterSourceInfo data = waterSourceInfoService.getById(id);
+            return data == null ? AjaxResult.warn("未找到该水源地信息") : AjaxResult.success("查询成功", data);
+        } catch (Exception e) {
+            log.error("查询水源地详情异常", e);
+            return AjaxResult.error("查询失败:" + e.getMessage());
+        }
+    }
+
+    @PostMapping
+    @ApiOperation(value = "新增水源地信息", notes = "传入水源地实体对象进行新增")
+    @ApiResponses({
+            @ApiResponse(code = 200, message = "新增成功", response = AjaxResult.class),
+            @ApiResponse(code = 400, message = "请求参数错误", response = AjaxResult.class),
+            @ApiResponse(code = 500, message = "服务器内部错误,新增失败", response = AjaxResult.class)
+    })
+    public AjaxResult add(@RequestBody WaterSourceInfo waterSourceInfo) {
+        try {
+            waterSourceInfo.setDelFlag("0");
+            try {
+                waterSourceInfo.setCreateBy(SecurityUtils.getUsername());
+            } catch (Exception e) {
+                waterSourceInfo.setCreateBy("system");
+            }
+            waterSourceInfo.setCreateTime(LocalDateTime.now());
+            boolean result = waterSourceInfoService.save(waterSourceInfo);
+            return result ? AjaxResult.success("新增成功") : AjaxResult.error("新增失败");
+        } catch (Exception e) {
+            log.error("新增水源地信息异常", e);
+            return AjaxResult.error("新增失败:" + e.getMessage());
+        }
+    }
+
+    @PutMapping
+    @ApiOperation(value = "修改水源地信息", notes = "传入水源地实体对象进行修改,仅更新非空字段")
+    @ApiResponses({
+            @ApiResponse(code = 200, message = "修改成功", response = AjaxResult.class),
+            @ApiResponse(code = 400, message = "请求参数错误", response = AjaxResult.class),
+            @ApiResponse(code = 500, message = "服务器内部错误,修改失败", response = AjaxResult.class)
+    })
+    public AjaxResult update(@RequestBody WaterSourceInfo waterSourceInfo) {
+        try {
+            waterSourceInfo.setDelFlag(null);
+            waterSourceInfo.setCreateBy(null);
+            waterSourceInfo.setCreateTime(null);
+
+            try {
+                waterSourceInfo.setUpdateBy(SecurityUtils.getUsername());
+            } catch (Exception e) {
+                waterSourceInfo.setUpdateBy("system");
+            }
+            waterSourceInfo.setUpdateTime(LocalDateTime.now());
+
+            boolean result = waterSourceInfoService.updateById(waterSourceInfo);
+            return result ? AjaxResult.success("修改成功") : AjaxResult.error("修改失败");
+        } catch (Exception e) {
+            log.error("修改水源地信息异常", e);
+            return AjaxResult.error("修改失败:" + e.getMessage());
+        }
+    }
+
+    @DeleteMapping("/{ids}")
+    @ApiOperation(value = "批量逻辑删除水源地信息", notes = "多个ID用逗号分隔,逻辑删除(移入回收站),不物理删除数据")
+    @ApiResponses({
+            @ApiResponse(code = 200, message = "删除成功", response = AjaxResult.class),
+            @ApiResponse(code = 400, message = "请求参数错误", response = AjaxResult.class),
+            @ApiResponse(code = 500, message = "服务器内部错误,删除失败", response = AjaxResult.class)
+    })
+    public AjaxResult remove(
+            @ApiParam(value = "水源地ID数组,多个用逗号分隔", required = true, example = "1,2,3") @PathVariable Long[] ids) {
+        try {
+            log.info("开始删除水源地数据,ids: {}", (Object) ids);
+            boolean result = waterSourceInfoService.removeByIds(List.of(ids));
+            return result
+                    ? AjaxResult.success("删除成功,已移入回收站,共删除 " + ids.length + " 条数据")
+                    : AjaxResult.error("删除失败");
+        } catch (Exception e) {
+            log.error("删除水源地数据异常", e);
+            return AjaxResult.error("删除失败:" + e.getMessage());
+        }
+    }
+
+    // -------------------------- 回收站接口 --------------------------
+    @GetMapping("/recycle/list")
+    @ApiOperation(value = "查询回收站数据", notes = "分页查询已删除的水源地数据,支持筛选和时间范围")
+    @ApiResponses({
+            @ApiResponse(code = 200, message = "查询成功", response = AjaxResult.class),
+            @ApiResponse(code = 500, message = "服务器内部错误,查询失败", response = AjaxResult.class)
+    })
+    public AjaxResult recycleList(
+            @ApiParam(value = "页码", defaultValue = "1") @RequestParam(defaultValue = "1") Integer pageNum,
+            @ApiParam(value = "每页大小", defaultValue = "10") @RequestParam(defaultValue = "10") Integer pageSize,
+            @ApiParam(value = "水源地ID") @RequestParam(required = false) String sourceId,
+            @ApiParam(value = "水源地名称") @RequestParam(required = false) String sourceName,
+            @ApiParam(value = "状态(0正常 1异常)") @RequestParam(required = false) String status,
+            @ApiParam(value = "开始时间(格式:yyyy-MM-dd HH:mm:ss)", example = "2025-01-01 00:00:00") @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime startTime,
+            @ApiParam(value = "结束时间(格式:yyyy-MM-dd HH:mm:ss)", example = "2025-12-31 23:59:59") @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime endTime) {
+        try {
+            Page<WaterSourceInfo> page = new Page<>(pageNum, pageSize);
+            IPage<WaterSourceInfo> resultPage = waterSourceInfoService.queryDeletedPage(page, sourceId, sourceName, status, startTime, endTime);
+            return AjaxResult.success("查询成功", resultPage);
+        } catch (Exception e) {
+            log.error("查询回收站数据异常", e);
+            return AjaxResult.error("查询失败:" + e.getMessage());
+        }
+    }
+
+    @PostMapping("/recycle/restore/{ids}")
+    @ApiOperation(value = "批量恢复已删除数据", notes = "多个ID用逗号分隔,将数据从回收站恢复为正常状态")
+    @ApiResponses({
+            @ApiResponse(code = 200, message = "恢复成功", response = AjaxResult.class),
+            @ApiResponse(code = 400, message = "请选择要恢复的数据", response = AjaxResult.class),
+            @ApiResponse(code = 500, message = "服务器内部错误,恢复失败", response = AjaxResult.class)
+    })
+    public AjaxResult restore(
+            @ApiParam(value = "水源地ID数组,多个用逗号分隔", required = true, example = "3,4") @PathVariable Long[] ids) {
+        try {
+            log.info("开始恢复水源地数据,ids: {}", (Object) ids);
+            String updateBy = "system";
+            try {
+                updateBy = SecurityUtils.getUsername();
+            } catch (Exception e) {
+                log.warn("未获取到登录用户,使用默认值system");
+            }
+
+            boolean result = waterSourceInfoService.restoreByIds(List.of(ids), updateBy);
+            return result
+                    ? AjaxResult.success("恢复成功,共恢复 " + ids.length + " 条数据")
+                    : AjaxResult.error("恢复失败");
+        } catch (Exception e) {
+            log.error("恢复数据异常", e);
+            return AjaxResult.error("恢复失败:" + e.getMessage());
+        }
+    }
+
+    @DeleteMapping("/recycle/delete/{ids}")
+    @ApiOperation(value = "批量彻底删除数据(不可恢复)", notes = "多个ID用逗号分隔,物理删除数据库中的数据,谨慎使用")
+    @ApiResponses({
+            @ApiResponse(code = 200, message = "彻底删除成功", response = AjaxResult.class),
+            @ApiResponse(code = 400, message = "请选择要删除的数据", response = AjaxResult.class),
+            @ApiResponse(code = 500, message = "服务器内部错误,删除失败", response = AjaxResult.class)
+    })
+    public AjaxResult deletePhysically(
+            @ApiParam(value = "水源地ID数组,多个用逗号分隔", required = true, example = "5") @PathVariable Long[] ids) {
+        try {
+            log.info("开始彻底删除水源地数据,ids: {}", (Object) ids);
+            boolean result = waterSourceInfoService.deleteByIdsPhysically(List.of(ids));
+            return result
+                    ? AjaxResult.success("彻底删除成功,共删除 " + ids.length + " 条数据")
+                    : AjaxResult.error("彻底删除失败");
+        } catch (Exception e) {
+            log.error("彻底删除数据异常", e);
+            return AjaxResult.error("彻底删除失败:" + e.getMessage());
+        }
+    }
+}

+ 226 - 0
pipe-network-service/zksy-admin/src/main/java/com/zksy/web/controller/WaterSupply/WaterUserInfo/WaterUserInfoController.java

@@ -0,0 +1,226 @@
+package com.zksy.web.controller.WaterSupply.WaterUserInfo;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.zksy.WaterSupply.WaterUserInfo.domain.WaterUserInfo;
+import com.zksy.WaterSupply.WaterUserInfo.service.IWaterUserInfoService;
+import com.zksy.common.core.domain.AjaxResult;
+import com.zksy.common.utils.SecurityUtils;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
+import io.swagger.annotations.ApiResponse;
+import io.swagger.annotations.ApiResponses;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.format.annotation.DateTimeFormat;
+import org.springframework.web.bind.annotation.*;
+import java.time.LocalDateTime;
+import java.util.List;
+
+/**
+ * 用水户信息管理接口
+ */
+@RestController
+@RequestMapping("/api/water/userInfo")
+@Api(tags = "供水管网-用水户信息数据接口")
+public class WaterUserInfoController {
+
+    private static final Logger log = LoggerFactory.getLogger(WaterUserInfoController.class);
+
+    @Autowired
+    private IWaterUserInfoService waterUserInfoService;
+
+    // -------------------------- 基础CRUD接口 --------------------------
+    @GetMapping("/page")
+    @ApiOperation(value = "分页查询用水户数据", notes = "支持按用户编号、名称、状态、用户类型、时间范围模糊查询")
+    @ApiResponses({
+            @ApiResponse(code = 200, message = "查询成功", response = AjaxResult.class),
+            @ApiResponse(code = 500, message = "服务器内部错误,查询失败", response = AjaxResult.class)
+    })
+    public AjaxResult queryPage(
+            @ApiParam(value = "页码", defaultValue = "1") @RequestParam(defaultValue = "1") Integer pageNum,
+            @ApiParam(value = "每页大小", defaultValue = "10") @RequestParam(defaultValue = "10") Integer pageSize,
+            @ApiParam(value = "用户编号") @RequestParam(required = false) String userCode,
+            @ApiParam(value = "用户名称") @RequestParam(required = false) String userName,
+            @ApiParam(value = "用户状态(0正常 1欠费 2停用)") @RequestParam(required = false) String status,
+            @ApiParam(value = "用户类型(居民/工业/商业/行政事业)") @RequestParam(required = false) String userType,
+            @ApiParam(value = "开始时间(格式:yyyy-MM-dd HH:mm:ss)", example = "2025-01-01 00:00:00") @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime startTime,
+            @ApiParam(value = "结束时间(格式:yyyy-MM-dd HH:mm:ss)", example = "2025-12-31 23:59:59") @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime endTime) {
+        try {
+            Page<WaterUserInfo> page = new Page<>(pageNum, pageSize);
+            IPage<WaterUserInfo> resultPage = waterUserInfoService.queryPage(page, userCode, userName, status, userType, startTime, endTime);
+            return AjaxResult.success("查询成功", resultPage);
+        } catch (Exception e) {
+            log.error("分页查询用水户数据异常", e);
+            return AjaxResult.error("查询失败:" + e.getMessage());
+        }
+    }
+
+    @GetMapping("/{id}")
+    @ApiOperation(value = "根据ID查询用水户详情", notes = "传入用水户ID获取完整信息")
+    @ApiResponses({
+            @ApiResponse(code = 200, message = "查询成功", response = AjaxResult.class),
+            @ApiResponse(code = 404, message = "未找到指定ID的用水户信息", response = AjaxResult.class),
+            @ApiResponse(code = 500, message = "服务器内部错误,查询失败", response = AjaxResult.class)
+    })
+    public AjaxResult getById(
+            @ApiParam(value = "用水户ID", required = true, example = "0") @PathVariable Long id) {
+        try {
+            WaterUserInfo data = waterUserInfoService.getById(id);
+            return data == null ? AjaxResult.warn("未找到该用水户信息") : AjaxResult.success("查询成功", data);
+        } catch (Exception e) {
+            log.error("查询用水户详情异常", e);
+            return AjaxResult.error("查询失败:" + e.getMessage());
+        }
+    }
+
+    @PostMapping
+    @ApiOperation(value = "新增用水户信息", notes = "传入用水户实体对象进行新增")
+    @ApiResponses({
+            @ApiResponse(code = 200, message = "新增成功", response = AjaxResult.class),
+            @ApiResponse(code = 400, message = "请求参数错误", response = AjaxResult.class),
+            @ApiResponse(code = 500, message = "服务器内部错误,新增失败", response = AjaxResult.class)
+    })
+    public AjaxResult add(@RequestBody WaterUserInfo waterUserInfo) {
+        try {
+            waterUserInfo.setDelFlag("0");
+            try {
+                waterUserInfo.setCreateBy(SecurityUtils.getUsername());
+            } catch (Exception e) {
+                waterUserInfo.setCreateBy("system");
+            }
+            waterUserInfo.setCreateTime(LocalDateTime.now());
+            boolean result = waterUserInfoService.save(waterUserInfo);
+            return result ? AjaxResult.success("新增成功") : AjaxResult.error("新增失败");
+        } catch (Exception e) {
+            log.error("新增用水户信息异常", e);
+            return AjaxResult.error("新增失败:" + e.getMessage());
+        }
+    }
+
+    @PutMapping
+    @ApiOperation(value = "修改用水户信息", notes = "传入用水户实体对象进行修改,仅更新非空字段")
+    @ApiResponses({
+            @ApiResponse(code = 200, message = "修改成功", response = AjaxResult.class),
+            @ApiResponse(code = 400, message = "请求参数错误", response = AjaxResult.class),
+            @ApiResponse(code = 500, message = "服务器内部错误,修改失败", response = AjaxResult.class)
+    })
+    public AjaxResult update(@RequestBody WaterUserInfo waterUserInfo) {
+        try {
+            // 禁止修改关键字段
+            waterUserInfo.setDelFlag(null);
+            waterUserInfo.setCreateBy(null);
+            waterUserInfo.setCreateTime(null);
+
+            try {
+                waterUserInfo.setUpdateBy(SecurityUtils.getUsername());
+            } catch (Exception e) {
+                waterUserInfo.setUpdateBy("system");
+            }
+            waterUserInfo.setUpdateTime(LocalDateTime.now());
+
+            boolean result = waterUserInfoService.updateById(waterUserInfo);
+            return result ? AjaxResult.success("修改成功") : AjaxResult.error("修改失败");
+        } catch (Exception e) {
+            log.error("修改用水户信息异常", e);
+            return AjaxResult.error("修改失败:" + e.getMessage());
+        }
+    }
+
+    @DeleteMapping("/{ids}")
+    @ApiOperation(value = "批量逻辑删除用水户信息", notes = "多个ID用逗号分隔,逻辑删除(移入回收站),不物理删除数据")
+    @ApiResponses({
+            @ApiResponse(code = 200, message = "删除成功", response = AjaxResult.class),
+            @ApiResponse(code = 400, message = "请求参数错误", response = AjaxResult.class),
+            @ApiResponse(code = 500, message = "服务器内部错误,删除失败", response = AjaxResult.class)
+    })
+    public AjaxResult remove(
+            @ApiParam(value = "用水户ID数组,多个用逗号分隔", required = true, example = "1,2,3") @PathVariable Long[] ids) {
+        try {
+            log.info("开始删除用水户数据,ids: {}", (Object) ids);
+            boolean result = waterUserInfoService.removeByIds(List.of(ids));
+            return result
+                    ? AjaxResult.success("删除成功,已移入回收站,共删除 " + ids.length + " 条数据")
+                    : AjaxResult.error("删除失败");
+        } catch (Exception e) {
+            log.error("删除用水户数据异常", e);
+            return AjaxResult.error("删除失败:" + e.getMessage());
+        }
+    }
+
+    // -------------------------- 回收站接口 --------------------------
+    @GetMapping("/recycle/list")
+    @ApiOperation(value = "查询回收站数据", notes = "分页查询已删除的用水户数据,支持筛选和时间范围")
+    @ApiResponses({
+            @ApiResponse(code = 200, message = "查询成功", response = AjaxResult.class),
+            @ApiResponse(code = 500, message = "服务器内部错误,查询失败", response = AjaxResult.class)
+    })
+    public AjaxResult recycleList(
+            @ApiParam(value = "页码", defaultValue = "1") @RequestParam(defaultValue = "1") Integer pageNum,
+            @ApiParam(value = "每页大小", defaultValue = "10") @RequestParam(defaultValue = "10") Integer pageSize,
+            @ApiParam(value = "用户编号") @RequestParam(required = false) String userCode,
+            @ApiParam(value = "用户名称") @RequestParam(required = false) String userName,
+            @ApiParam(value = "用户状态(0正常 1欠费 2停用)") @RequestParam(required = false) String status,
+            @ApiParam(value = "开始时间(格式:yyyy-MM-dd HH:mm:ss)", example = "2025-01-01 00:00:00") @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime startTime,
+            @ApiParam(value = "结束时间(格式:yyyy-MM-dd HH:mm:ss)", example = "2025-12-31 23:59:59") @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime endTime) {
+        try {
+            Page<WaterUserInfo> page = new Page<>(pageNum, pageSize);
+            IPage<WaterUserInfo> resultPage = waterUserInfoService.queryDeletedPage(page, userCode, userName, status, startTime, endTime);
+            return AjaxResult.success("查询成功", resultPage);
+        } catch (Exception e) {
+            log.error("查询回收站数据异常", e);
+            return AjaxResult.error("查询失败:" + e.getMessage());
+        }
+    }
+
+    @PostMapping("/recycle/restore/{ids}")
+    @ApiOperation(value = "批量恢复已删除数据", notes = "多个ID用逗号分隔,将数据从回收站恢复为正常状态")
+    @ApiResponses({
+            @ApiResponse(code = 200, message = "恢复成功", response = AjaxResult.class),
+            @ApiResponse(code = 400, message = "请选择要恢复的数据", response = AjaxResult.class),
+            @ApiResponse(code = 500, message = "服务器内部错误,恢复失败", response = AjaxResult.class)
+    })
+    public AjaxResult restore(
+            @ApiParam(value = "用水户ID数组,多个用逗号分隔", required = true, example = "3,4") @PathVariable Long[] ids) {
+        try {
+            log.info("开始恢复用水户数据,ids: {}", (Object) ids);
+            String updateBy = "system";
+            try {
+                updateBy = SecurityUtils.getUsername();
+            } catch (Exception e) {
+                log.warn("未获取到登录用户,使用默认值system");
+            }
+
+            boolean result = waterUserInfoService.restoreByIds(List.of(ids), updateBy);
+            return result
+                    ? AjaxResult.success("恢复成功,共恢复 " + ids.length + " 条数据")
+                    : AjaxResult.error("恢复失败");
+        } catch (Exception e) {
+            log.error("恢复数据异常", e);
+            return AjaxResult.error("恢复失败:" + e.getMessage());
+        }
+    }
+
+    @DeleteMapping("/recycle/delete/{ids}")
+    @ApiOperation(value = "批量彻底删除数据(不可恢复)", notes = "多个ID用逗号分隔,物理删除数据库中的数据,谨慎使用")
+    @ApiResponses({
+            @ApiResponse(code = 200, message = "彻底删除成功", response = AjaxResult.class),
+            @ApiResponse(code = 400, message = "请选择要删除的数据", response = AjaxResult.class),
+            @ApiResponse(code = 500, message = "服务器内部错误,删除失败", response = AjaxResult.class)
+    })
+    public AjaxResult deletePhysically(
+            @ApiParam(value = "用水户ID数组,多个用逗号分隔", required = true, example = "5") @PathVariable Long[] ids) {
+        try {
+            log.info("开始彻底删除用水户数据,ids: {}", (Object) ids);
+            boolean result = waterUserInfoService.deleteByIdsPhysically(List.of(ids));
+            return result
+                    ? AjaxResult.success("彻底删除成功,共删除 " + ids.length + " 条数据")
+                    : AjaxResult.error("彻底删除失败");
+        } catch (Exception e) {
+            log.error("彻底删除数据异常", e);
+            return AjaxResult.error("彻底删除失败:" + e.getMessage());
+        }
+    }
+}

+ 142 - 0
pipe-network-service/zksy-admin/src/main/java/com/zksy/web/controller/warning/EarlyWarningDisposeEfficiencyController.java

@@ -0,0 +1,142 @@
+package com.zksy.web.controller.warning;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.zksy.base.warning.service.IEarlyWarningDisposeEfficiencyService;
+import com.zksy.common.core.domain.AjaxResult;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
+import io.swagger.annotations.ApiResponse;
+import io.swagger.annotations.ApiResponses;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.format.annotation.DateTimeFormat;
+import org.springframework.web.bind.annotation.*;
+
+import java.time.LocalDateTime;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 预警统计-处置时效分析接口
+ */
+@RestController
+@RequestMapping("/api/warning/disposeEfficiency")
+@Api(tags = "预警信息-处置时效分析模块")
+public class EarlyWarningDisposeEfficiencyController {
+
+    private static final Logger log = LoggerFactory.getLogger(EarlyWarningDisposeEfficiencyController.class);
+
+    @Autowired
+    private IEarlyWarningDisposeEfficiencyService efficiencyService;
+
+    @GetMapping("/overview")
+    @ApiOperation(value = "处置时效概览统计", notes = "返回平均、最长、最短处置时长及总数量核心指标")
+    @ApiResponses({
+            @ApiResponse(code = 200, message = "统计成功", response = AjaxResult.class),
+            @ApiResponse(code = 500, message = "统计异常", response = AjaxResult.class)
+    })
+    public AjaxResult getOverview(
+            @ApiParam(value = "发布开始时间 yyyy-MM-dd HH:mm:ss", example = "2026-01-01 00:00:00")
+            @RequestParam(required = false)
+            @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime startTime,
+
+            @ApiParam(value = "发布结束时间 yyyy-MM-dd HH:mm:ss", example = "2026-06-01 23:59:59")
+            @RequestParam(required = false)
+            @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime endTime,
+
+            @ApiParam(value = "预警专项", example = "管网压力专项")
+            @RequestParam(required = false) String warningSpecial) {
+        try {
+            Map<String, Object> result = efficiencyService.getEfficiencyOverview(startTime, endTime, warningSpecial);
+            return AjaxResult.success("概览统计查询成功", result);
+        } catch (Exception e) {
+            log.error("处置时效概览统计异常", e);
+            return AjaxResult.error("统计失败:" + e.getMessage());
+        }
+    }
+
+    @GetMapping("/range")
+    @ApiOperation(value = "处置时效区间分布", notes = "按时长区间统计预警数量,适配柱状图展示")
+    @ApiResponses({
+            @ApiResponse(code = 200, message = "统计成功", response = AjaxResult.class),
+            @ApiResponse(code = 500, message = "统计异常", response = AjaxResult.class)
+    })
+    public AjaxResult getRange(
+            @ApiParam(value = "发布开始时间 yyyy-MM-dd HH:mm:ss", example = "2026-01-01 00:00:00")
+            @RequestParam(required = false)
+            @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime startTime,
+
+            @ApiParam(value = "发布结束时间 yyyy-MM-dd HH:mm:ss", example = "2026-06-01 23:59:59")
+            @RequestParam(required = false)
+            @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime endTime,
+
+            @ApiParam(value = "预警专项", example = "管网压力专项")
+            @RequestParam(required = false) String warningSpecial) {
+        try {
+            List<Map<String, Object>> result = efficiencyService.getEfficiencyRange(startTime, endTime, warningSpecial);
+            return AjaxResult.success("区间分布统计查询成功", result);
+        } catch (Exception e) {
+            log.error("处置时效区间统计异常", e);
+            return AjaxResult.error("统计失败:" + e.getMessage());
+        }
+    }
+
+    @GetMapping("/special")
+    @ApiOperation(value = "按专项统计处置时效", notes = "按预警专项维度统计平均处置时长,从高到低排序")
+    @ApiResponses({
+            @ApiResponse(code = 200, message = "统计成功", response = AjaxResult.class),
+            @ApiResponse(code = 500, message = "统计异常", response = AjaxResult.class)
+    })
+    public AjaxResult getBySpecial(
+            @ApiParam(value = "发布开始时间 yyyy-MM-dd HH:mm:ss", example = "2026-01-01 00:00:00")
+            @RequestParam(required = false)
+            @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime startTime,
+
+            @ApiParam(value = "发布结束时间 yyyy-MM-dd HH:mm:ss", example = "2026-06-01 23:59:59")
+            @RequestParam(required = false)
+            @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime endTime) {
+        try {
+            List<Map<String, Object>> result = efficiencyService.getEfficiencyBySpecial(startTime, endTime);
+            return AjaxResult.success("专项时效统计查询成功", result);
+        } catch (Exception e) {
+            log.error("专项处置时效统计异常", e);
+            return AjaxResult.error("统计失败:" + e.getMessage());
+        }
+    }
+
+    @GetMapping("/page")
+    @ApiOperation(value = "处置时效明细列表", notes = "分页查询预警处置时效明细,支持按时长排序,定位低效案例")
+    @ApiResponses({
+            @ApiResponse(code = 200, message = "查询成功", response = AjaxResult.class),
+            @ApiResponse(code = 500, message = "查询异常", response = AjaxResult.class)
+    })
+    public AjaxResult queryPage(
+            @ApiParam(value = "页码", defaultValue = "1") @RequestParam(defaultValue = "1") Integer pageNum,
+            @ApiParam(value = "每页大小", defaultValue = "10") @RequestParam(defaultValue = "10") Integer pageSize,
+
+            @ApiParam(value = "发布开始时间 yyyy-MM-dd HH:mm:ss", example = "2026-01-01 00:00:00")
+            @RequestParam(required = false)
+            @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime startTime,
+
+            @ApiParam(value = "发布结束时间 yyyy-MM-dd HH:mm:ss", example = "2026-06-01 23:59:59")
+            @RequestParam(required = false)
+            @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime endTime,
+
+            @ApiParam(value = "预警专项", example = "管网压力专项")
+            @RequestParam(required = false) String warningSpecial,
+
+            @ApiParam(value = "排序方式", allowableValues = "asc,desc", example = "desc")
+            @RequestParam(defaultValue = "desc") String sortType) {
+        try {
+            Page<Map<String, Object>> page = new Page<>(pageNum, pageSize);
+            IPage<Map<String, Object>> resultPage = efficiencyService.queryEfficiencyPage(page, startTime, endTime, warningSpecial, sortType);
+            return AjaxResult.success("明细查询成功", resultPage);
+        } catch (Exception e) {
+            log.error("处置时效明细查询异常", e);
+            return AjaxResult.error("查询失败:" + e.getMessage());
+        }
+    }
+}

+ 62 - 0
pipe-network-service/zksy-admin/src/main/java/com/zksy/web/controller/warning/EarlyWarningDisposeStatusController.java

@@ -0,0 +1,62 @@
+package com.zksy.web.controller.warning;
+
+import com.zksy.base.warning.service.IEarlyWarningDisposeStatusService;
+import com.zksy.common.core.domain.AjaxResult;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
+import io.swagger.annotations.ApiResponse;
+import io.swagger.annotations.ApiResponses;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.format.annotation.DateTimeFormat;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.time.LocalDateTime;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 预警统计-处置状态分析接口
+ */
+@RestController
+@RequestMapping("/warning/disposeStatus")
+@Api(tags = "预警信息-处置状态分析模块")
+public class EarlyWarningDisposeStatusController {
+
+    private static final Logger log = LoggerFactory.getLogger(EarlyWarningDisposeStatusController.class);
+
+    @Autowired
+    private IEarlyWarningDisposeStatusService disposeStatusService;
+
+    @GetMapping("/stat")
+    @ApiOperation(value = "处置状态统计分析",
+            notes = "按预警处置状态分组统计数量,支持时间范围、预警专项筛选,返回数据适配饼图/柱状图")
+    @ApiResponses({
+            @ApiResponse(code = 200, message = "统计成功", response = AjaxResult.class),
+            @ApiResponse(code = 500, message = "统计异常", response = AjaxResult.class)
+    })
+    public AjaxResult getDisposeStatusStat(
+            @ApiParam(value = "发布开始时间 yyyy-MM-dd HH:mm:ss", example = "2026-01-01 00:00:00")
+            @RequestParam(required = false)
+            @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime startTime,
+
+            @ApiParam(value = "发布结束时间 yyyy-MM-dd HH:mm:ss", example = "2026-06-01 23:59:59")
+            @RequestParam(required = false)
+            @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime endTime,
+
+            @ApiParam(value = "预警专项", example = "管网压力专项")
+            @RequestParam(required = false) String warningSpecial) {
+        try {
+            List<Map<String, Object>> result = disposeStatusService.getWarningStatusStat(startTime, endTime, warningSpecial);
+            return AjaxResult.success("处置状态统计查询成功", result);
+        } catch (Exception e) {
+            log.error("处置状态统计查询异常", e);
+            return AjaxResult.error("统计失败:" + e.getMessage());
+        }
+    }
+}

+ 163 - 0
pipe-network-service/zksy-admin/src/main/java/com/zksy/web/controller/warning/EarlyWarningReceiveEfficiencyController.java

@@ -0,0 +1,163 @@
+package com.zksy.web.controller.warning;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.zksy.base.warning.service.IEarlyWarningReceiveEfficiencyService;
+import com.zksy.common.core.domain.AjaxResult;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
+import io.swagger.annotations.ApiResponse;
+import io.swagger.annotations.ApiResponses;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.format.annotation.DateTimeFormat;
+import org.springframework.web.bind.annotation.*;
+
+import java.time.LocalDateTime;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 预警统计-接警效率分析接口
+ */
+@RestController
+@RequestMapping("/warning/receiveEfficiency")
+@Api(tags = "预警信息-接警效率统计模块")
+public class EarlyWarningReceiveEfficiencyController {
+
+    private static final Logger log = LoggerFactory.getLogger(EarlyWarningReceiveEfficiencyController.class);
+
+    @Autowired
+    private IEarlyWarningReceiveEfficiencyService receiveEfficiencyService;
+
+    @GetMapping("/overview")
+    @ApiOperation(value = "接警效率概览统计", notes = "返回平均、最长、最短接警时长及接警总数核心指标")
+    @ApiResponses({
+            @ApiResponse(code = 200, message = "统计成功", response = AjaxResult.class),
+            @ApiResponse(code = 500, message = "统计异常", response = AjaxResult.class)
+    })
+    public AjaxResult getOverview(
+            @ApiParam(value = "发布开始时间 yyyy-MM-dd HH:mm:ss", example = "2026-01-01 00:00:00")
+            @RequestParam(required = false)
+            @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime startTime,
+
+            @ApiParam(value = "发布结束时间 yyyy-MM-dd HH:mm:ss", example = "2026-06-01 23:59:59")
+            @RequestParam(required = false)
+            @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime endTime,
+
+            @ApiParam(value = "预警类型", example = "压力预警")
+            @RequestParam(required = false) String warningType,
+
+            @ApiParam(value = "预警专项", example = "供水管网专项")
+            @RequestParam(required = false) String warningSpecial,
+
+            @ApiParam(value = "处置状态", example = "HANDLED")
+            @RequestParam(required = false) String status) {
+        try {
+            Map<String, Object> result = receiveEfficiencyService.getEfficiencyOverview(
+                    startTime, endTime, warningType, warningSpecial, status);
+            return AjaxResult.success("概览统计查询成功", result);
+        } catch (Exception e) {
+            log.error("接警效率概览统计异常", e);
+            return AjaxResult.error("统计失败:" + e.getMessage());
+        }
+    }
+
+    @GetMapping("/range")
+    @ApiOperation(value = "接警时效区间分布", notes = "按响应时长区间统计预警数量,适配柱状图展示")
+    @ApiResponses({
+            @ApiResponse(code = 200, message = "统计成功", response = AjaxResult.class),
+            @ApiResponse(code = 500, message = "统计异常", response = AjaxResult.class)
+    })
+    public AjaxResult getRange(
+            @ApiParam(value = "发布开始时间 yyyy-MM-dd HH:mm:ss", example = "2026-01-01 00:00:00")
+            @RequestParam(required = false)
+            @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime startTime,
+
+            @ApiParam(value = "发布结束时间 yyyy-MM-dd HH:mm:ss", example = "2026-06-01 23:59:59")
+            @RequestParam(required = false)
+            @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime endTime,
+
+            @ApiParam(value = "预警类型", example = "压力预警")
+            @RequestParam(required = false) String warningType,
+
+            @ApiParam(value = "预警专项", example = "供水管网专项")
+            @RequestParam(required = false) String warningSpecial,
+
+            @ApiParam(value = "处置状态", example = "HANDLED")
+            @RequestParam(required = false) String status) {
+        try {
+            List<Map<String, Object>> result = receiveEfficiencyService.getEfficiencyRange(
+                    startTime, endTime, warningType, warningSpecial, status);
+            return AjaxResult.success("区间分布统计查询成功", result);
+        } catch (Exception e) {
+            log.error("接警时效区间统计异常", e);
+            return AjaxResult.error("统计失败:" + e.getMessage());
+        }
+    }
+
+    @GetMapping("/type")
+    @ApiOperation(value = "按类型接警统计接警效率", notes = "按预警类型维度统计平均接警时长,从高到低排序")
+    @ApiResponses({
+            @ApiResponse(code = 200, message = "统计成功", response = AjaxResult.class),
+            @ApiResponse(code = 500, message = "统计异常", response = AjaxResult.class)
+    })
+    public AjaxResult getByType(
+            @ApiParam(value = "发布开始时间 yyyy-MM-dd HH:mm:ss", example = "2026-01-01 00:00:00")
+            @RequestParam(required = false)
+            @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime startTime,
+
+            @ApiParam(value = "发布结束时间 yyyy-MM-dd HH:mm:ss", example = "2026-06-01 23:59:59")
+            @RequestParam(required = false)
+            @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime endTime) {
+        try {
+            List<Map<String, Object>> result = receiveEfficiencyService.getEfficiencyByType(startTime, endTime);
+            return AjaxResult.success("类型维度统计查询成功", result);
+        } catch (Exception e) {
+            log.error("按类型统计接警效率异常", e);
+            return AjaxResult.error("统计失败:" + e.getMessage());
+        }
+    }
+
+    @GetMapping("/page")
+    @ApiOperation(value = "接警时效明细列表", notes = "分页查询预警接警时效明细,支持按时长排序,定位低效响应案例")
+    @ApiResponses({
+            @ApiResponse(code = 200, message = "查询成功", response = AjaxResult.class),
+            @ApiResponse(code = 500, message = "查询异常", response = AjaxResult.class)
+    })
+    public AjaxResult queryPage(
+            @ApiParam(value = "页码", defaultValue = "1") @RequestParam(defaultValue = "1") Integer pageNum,
+            @ApiParam(value = "每页大小", defaultValue = "10") @RequestParam(defaultValue = "10") Integer pageSize,
+
+            @ApiParam(value = "发布开始时间 yyyy-MM-dd HH:mm:ss", example = "2026-01-01 00:00:00")
+            @RequestParam(required = false)
+            @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime startTime,
+
+            @ApiParam(value = "发布结束时间 yyyy-MM-dd HH:mm:ss", example = "2026-06-01 23:59:59")
+            @RequestParam(required = false)
+            @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime endTime,
+
+            @ApiParam(value = "预警类型", example = "压力预警")
+            @RequestParam(required = false) String warningType,
+
+            @ApiParam(value = "预警专项", example = "供水管网专项")
+            @RequestParam(required = false) String warningSpecial,
+
+            @ApiParam(value = "处置状态", example = "HANDLED")
+            @RequestParam(required = false) String status,
+
+            @ApiParam(value = "排序方式", allowableValues = "asc,desc", example = "desc")
+            @RequestParam(defaultValue = "desc") String sortType) {
+        try {
+            Page<Map<String, Object>> page = new Page<>(pageNum, pageSize);
+            IPage<Map<String, Object>> resultPage = receiveEfficiencyService.queryEfficiencyPage(
+                    page, startTime, endTime, warningType, warningSpecial, status, sortType);
+            return AjaxResult.success("明细查询成功", resultPage);
+        } catch (Exception e) {
+            log.error("接警时效明细查询异常", e);
+            return AjaxResult.error("查询失败:" + e.getMessage());
+        }
+    }
+}

+ 68 - 0
pipe-network-service/zksy-admin/src/main/java/com/zksy/web/controller/warning/EarlyWarningTodayController.java

@@ -0,0 +1,68 @@
+package com.zksy.web.controller.warning;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.zksy.base.warning.domain.EarlyWarning;
+import com.zksy.base.warning.service.IEarlyWarningTodayService;
+import com.zksy.common.core.domain.AjaxResult;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
+import io.swagger.annotations.ApiResponse;
+import io.swagger.annotations.ApiResponses;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.Map;
+
+/**
+ * 今日预警统计接口
+ */
+@RestController
+@RequestMapping("/warning/today")
+@Api(tags = "预警信息-今日预警统计接口")
+public class EarlyWarningTodayController {
+
+    private static final Logger log = LoggerFactory.getLogger(EarlyWarningTodayController.class);
+
+    @Autowired
+    private IEarlyWarningTodayService earlyWarningTodayService;
+
+    @GetMapping("/stats")
+    @ApiOperation(value = "获取今日预警统计指标", notes = "返回今日预警总数、已处置数、已解除数三个核心指标")
+    @ApiResponses({
+            @ApiResponse(code = 200, message = "查询成功", response = AjaxResult.class),
+            @ApiResponse(code = 500, message = "服务器内部错误,查询失败", response = AjaxResult.class)
+    })
+    public AjaxResult getTodayStats() {
+        try {
+            Map<String, Object> stats = earlyWarningTodayService.getTodayWarningStats();
+            return AjaxResult.success("查询成功", stats);
+        } catch (Exception e) {
+            log.error("查询今日预警统计异常", e);
+            return AjaxResult.error("查询失败:" + e.getMessage());
+        }
+    }
+
+    @GetMapping("/page")
+    @ApiOperation(value = "分页查询今日预警列表", notes = "支持按状态筛选,为空则查询所有非草稿状态的今日预警")
+    @ApiResponses({
+            @ApiResponse(code = 200, message = "查询成功", response = AjaxResult.class),
+            @ApiResponse(code = 500, message = "服务器内部错误,查询失败", response = AjaxResult.class)
+    })
+    public AjaxResult queryTodayPage(
+            @ApiParam(value = "页码", defaultValue = "1") @RequestParam(defaultValue = "1") Integer pageNum,
+            @ApiParam(value = "每页大小", defaultValue = "10") @RequestParam(defaultValue = "10") Integer pageSize,
+            @ApiParam(value = "预警状态", allowableValues = "PENDING,PROCESSING,RELEASED,HANDLED,CLOSED") @RequestParam(required = false) String status) {
+        try {
+            Page<EarlyWarning> page = new Page<>(pageNum, pageSize);
+            IPage<EarlyWarning> resultPage = earlyWarningTodayService.queryTodayWarningPage(page, status);
+            return AjaxResult.success("查询成功", resultPage);
+        } catch (Exception e) {
+            log.error("分页查询今日预警列表异常", e);
+            return AjaxResult.error("查询失败:" + e.getMessage());
+        }
+    }
+}

+ 80 - 0
pipe-network-service/zksy-admin/src/main/java/com/zksy/web/controller/warning/EarlyWarningTrendController.java

@@ -0,0 +1,80 @@
+package com.zksy.web.controller.warning;
+
+import com.zksy.base.warning.service.IEarlyWarningTrendService;
+import com.zksy.common.core.domain.AjaxResult;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
+import io.swagger.annotations.ApiResponse;
+import io.swagger.annotations.ApiResponses;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.format.annotation.DateTimeFormat;
+import org.springframework.web.bind.annotation.*;
+
+import java.time.LocalDateTime;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 预警发展趋势接口
+ */
+@RestController
+@RequestMapping("/warning/trend")
+@Api(tags = "预警信息-预警发展趋势接口")
+public class EarlyWarningTrendController {
+
+    private static final Logger log = LoggerFactory.getLogger(EarlyWarningTrendController.class);
+
+    @Autowired
+    private IEarlyWarningTrendService earlyWarningTrendService;
+
+    @GetMapping("/day")
+    @ApiOperation(value = "按日统计预警发展趋势", notes = "按日期维度统计各专项预警数量趋势,支持时间范围、预警专项筛选")
+    @ApiResponses({
+            @ApiResponse(code = 200, message = "统计成功", response = AjaxResult.class),
+            @ApiResponse(code = 500, message = "服务器内部错误,统计失败", response = AjaxResult.class)
+    })
+    public AjaxResult getTrendByDay(
+            @ApiParam(value = "开始时间(格式:yyyy-MM-dd HH:mm:ss)", example = "2026-01-01 00:00:00")
+            @RequestParam(required = false)
+            @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime startTime,
+            @ApiParam(value = "结束时间(格式:yyyy-MM-dd HH:mm:ss)", example = "2026-12-31 23:59:59")
+            @RequestParam(required = false)
+            @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime endTime,
+            @ApiParam(value = "预警专项")
+            @RequestParam(required = false) String warningSpecial) {
+        try {
+            List<Map<String, Object>> list = earlyWarningTrendService.getTrendByDay(startTime, endTime, warningSpecial);
+            return AjaxResult.success("统计成功", list);
+        } catch (Exception e) {
+            log.error("按日统计预警发展趋势异常", e);
+            return AjaxResult.error("统计失败:" + e.getMessage());
+        }
+    }
+
+    @GetMapping("/month")
+    @ApiOperation(value = "按月统计预警发展趋势", notes = "按月份维度统计各专项预警数量趋势,支持时间范围、预警专项筛选")
+    @ApiResponses({
+            @ApiResponse(code = 200, message = "统计成功", response = AjaxResult.class),
+            @ApiResponse(code = 500, message = "服务器内部错误,统计失败", response = AjaxResult.class)
+    })
+    public AjaxResult getTrendByMonth(
+            @ApiParam(value = "开始时间(格式:yyyy-MM-dd HH:mm:ss)", example = "2026-01-01 00:00:00")
+            @RequestParam(required = false)
+            @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime startTime,
+            @ApiParam(value = "结束时间(格式:yyyy-MM-dd HH:mm:ss)", example = "2026-12-31 23:59:59")
+            @RequestParam(required = false)
+            @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime endTime,
+            @ApiParam(value = "预警专项")
+            @RequestParam(required = false) String warningSpecial) {
+        try {
+            List<Map<String, Object>> list = earlyWarningTrendService.getTrendByMonth(startTime, endTime, warningSpecial);
+            return AjaxResult.success("统计成功", list);
+        } catch (Exception e) {
+            log.error("按月统计预警发展趋势异常", e);
+            return AjaxResult.error("统计失败:" + e.getMessage());
+        }
+    }
+}

+ 8 - 1
pipe-network-service/zksy-admin/src/main/resources/application-dev.yml

@@ -4,4 +4,11 @@ minio:
   secretKey: minio123
   bucket: pipe
   readPath: http://192.168.110.30:9000
-imgAddress: D:/Temp/%s.jpg
+imgAddress: D:/Temp/%s.jpg
+
+mybatis-plus:
+  global-config:
+    db-config:
+      logic-delete-field: delFlag
+      logic-delete-value: "2"
+      logic-not-delete-value: "0"

+ 8 - 1
pipe-network-service/zksy-admin/src/main/resources/application-prod.yml

@@ -4,4 +4,11 @@ minio:
     secretKey: minio123
     bucket: pipe
     readPath: http://47.107.107.47:9000
-imgAddress: /home/img-repository/%s.jpg
+imgAddress: /home/img-repository/%s.jpg
+
+mybatis-plus:
+    global-config:
+        db-config:
+            logic-delete-field: delFlag
+            logic-delete-value: "2"
+            logic-not-delete-value: "0"

+ 1 - 1
pipe-network-service/zksy-framework/src/main/java/com/zksy/framework/config/ApplicationConfig.java

@@ -17,7 +17,7 @@ import java.util.TimeZone;
 // 表示通过aop框架暴露该代理对象,AopContext能够访问
 @EnableAspectJAutoProxy(exposeProxy = true)
 // 指定要扫描的Mapper类的包的路径
-@MapperScan({"com.zksy.base.**.mapper", "com.zksy.system.**.mapper", "com.zksy.quartz.**.mapper", "com.zksy.generator.**.mapper", "com.zksy.drainage.**.mapper"})
+@MapperScan({"com.zksy.base.**.mapper", "com.zksy.system.**.mapper", "com.zksy.quartz.**.mapper", "com.zksy.generator.**.mapper", "com.zksy.drainage.**.mapper","com.zksy.WaterSupply.**.mapper"})
 public class ApplicationConfig
 {
     /**

+ 82 - 0
pipe-network-service/zksy-system/src/main/java/com/zksy/WaterSupply/WaterPipeInfo/domain/WaterPipeInfo.java

@@ -0,0 +1,82 @@
+package com.zksy.WaterSupply.WaterPipeInfo.domain;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableLogic;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+
+/**
+ * 管网信息实体
+ */
+@Data
+@TableName("water_pipe_info")
+@ApiModel(value = "WaterPipeInfo", description = "管网信息对象")
+public class WaterPipeInfo {
+
+    @ApiModelProperty(value = "主键ID", example = "0", position = 1)
+    @TableId(type = IdType.AUTO)
+    private Long id;
+
+    @ApiModelProperty(value = "管网编号", example = "P001", required = true, position = 2)
+    private String pipeCode;
+
+    @ApiModelProperty(value = "管网名称", example = "XX路主管网", required = true, position = 3)
+    private String pipeName;
+
+    @ApiModelProperty(value = "管道材质(铸铁/PE/钢管等)", example = "PE", position = 4)
+    private String pipeMaterial;
+
+    @ApiModelProperty(value = "管径(mm)", example = "200", position = 5)
+    private Integer pipeDiameter;
+
+    @ApiModelProperty(value = "管道长度(m)", example = "120.50", position = 6)
+    private BigDecimal pipeLength;
+
+    @ApiModelProperty(value = "起点位置", example = "XX路1号", position = 7)
+    private String startPoint;
+
+    @ApiModelProperty(value = "终点位置", example = "XX路100号", position = 8)
+    private String endPoint;
+
+    @ApiModelProperty(value = "铺设年份", example = "2026", position = 9)
+    private Integer layingYear;
+
+    @ApiModelProperty(value = "设计压力(MPa)", example = "1.60", position = 10)
+    private BigDecimal pressureRating;
+
+    @ApiModelProperty(value = "运行状态(0正常 1停用)", example = "0", allowableValues = "0,1", position = 11)
+    private String status;
+
+    @ApiModelProperty(value = "备注", example = "主干管道", position = 12)
+    private String remark;
+
+    @ApiModelProperty(value = "删除标志(0存在 2删除)", example = "0", allowableValues = "0,2", hidden = true, position = 13)
+    @TableLogic
+    private String delFlag;
+
+    @ApiModelProperty(value = "创建者", example = "admin", hidden = true, position = 14)
+    @TableField(fill = com.baomidou.mybatisplus.annotation.FieldFill.INSERT)
+    private String createBy;
+
+    @ApiModelProperty(value = "创建时间", example = "2026-05-18 10:00:00", hidden = true, position = 15)
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    @TableField(fill = com.baomidou.mybatisplus.annotation.FieldFill.INSERT)
+    private LocalDateTime createTime;
+
+    @ApiModelProperty(value = "更新者", example = "admin", hidden = true, position = 16)
+    @TableField(fill = com.baomidou.mybatisplus.annotation.FieldFill.UPDATE)
+    private String updateBy;
+
+    @ApiModelProperty(value = "更新时间", example = "2026-05-18 14:00:00", hidden = true, position = 17)
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    @TableField(fill = com.baomidou.mybatisplus.annotation.FieldFill.UPDATE)
+    private LocalDateTime updateTime;
+}

+ 63 - 0
pipe-network-service/zksy-system/src/main/java/com/zksy/WaterSupply/WaterPipeInfo/mapper/WaterPipeInfoMapper.java

@@ -0,0 +1,63 @@
+package com.zksy.WaterSupply.WaterPipeInfo.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.zksy.WaterSupply.WaterPipeInfo.domain.WaterPipeInfo;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+import org.apache.ibatis.annotations.Update;
+
+import java.time.LocalDateTime;
+import java.util.List;
+import java.util.Map;
+
+@Mapper
+public interface WaterPipeInfoMapper extends BaseMapper<WaterPipeInfo> {
+
+    /**
+     * 分页条件查询
+     */
+    List<WaterPipeInfo> selectPipeList(@Param("pipeCode") String pipeCode,
+                                       @Param("pipeName") String pipeName,
+                                       @Param("pipeMaterial") String pipeMaterial,
+                                       @Param("status") String status,
+                                       @Param("startTime") LocalDateTime startTime,
+                                       @Param("endTime") LocalDateTime endTime);
+
+    /**
+     * 按状态统计管网
+     */
+    List<Map<String, Object>> statPipeByStatus();
+
+    /**
+     * 按材质统计管网
+     */
+    List<Map<String, Object>> statPipeByMaterial();
+
+    /**
+     * 获取最新管网
+     */
+    WaterPipeInfo getLatestPipe();
+
+    /**
+     * 整体统计
+     */
+    Map<String, Object> getPipeOverallStatistics();
+
+    /**
+     * 查询已删除的管网数据
+     */
+    List<WaterPipeInfo> selectDeletedList(@Param("pipeCode") String pipeCode,
+                                          @Param("pipeName") String pipeName,
+                                          @Param("pipeMaterial") String pipeMaterial,
+                                          @Param("startTime") LocalDateTime startTime,
+                                          @Param("endTime") LocalDateTime endTime);
+    /**
+     * 批量恢复已删除数据
+     */
+    int restoreByIds(@Param("ids") List<Long> ids, @Param("updateBy") String updateBy);
+
+    /**
+     * 批量彻底物理删除数据
+     */
+    int deleteByIdsPhysically(@Param("ids") List<Long> ids);
+}

+ 67 - 0
pipe-network-service/zksy-system/src/main/java/com/zksy/WaterSupply/WaterPipeInfo/service/IWaterPipeInfoService.java

@@ -0,0 +1,67 @@
+package com.zksy.WaterSupply.WaterPipeInfo.service;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.zksy.WaterSupply.WaterPipeInfo.domain.WaterPipeInfo;
+
+import java.time.LocalDateTime;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 管网信息 服务层接口
+ */
+public interface IWaterPipeInfoService extends IService<WaterPipeInfo> {
+
+    /**
+     * 分页条件查询
+     */
+    IPage<WaterPipeInfo> queryPage(Page<WaterPipeInfo> page,
+                                   String pipeCode,
+                                   String pipeName,
+                                   String pipeMaterial,
+                                   String status,
+                                   LocalDateTime startTime,
+                                   LocalDateTime endTime);
+
+    /**
+     * 按状态统计管网
+     */
+    List<Map<String, Object>> statPipeByStatus();
+
+    /**
+     * 按材质统计管网
+     */
+    List<Map<String, Object>> statPipeByMaterial();
+
+    /**
+     * 获取最新管网
+     */
+    WaterPipeInfo getLatestPipe();
+
+    /**
+     * 整体统计
+     */
+    Map<String, Object> getPipeOverallStatistics();
+
+    /**
+     * 分页查询回收站数据
+     */
+    IPage<WaterPipeInfo> queryDeletedPage(Page<WaterPipeInfo> page,
+                                          String pipeCode,
+                                          String pipeName,
+                                          String pipeMaterial,
+                                          LocalDateTime startTime,
+                                          LocalDateTime endTime);
+
+    /**
+     * 批量恢复已删除数据
+     */
+    boolean restoreByIds(List<Long> ids, String updateBy);
+
+    /**
+     * 批量彻底物理删除数据
+     */
+    boolean deleteByIdsPhysically(List<Long> ids);
+}

+ 85 - 0
pipe-network-service/zksy-system/src/main/java/com/zksy/WaterSupply/WaterPipeInfo/service/impl/WaterPipeInfoServiceImpl.java

@@ -0,0 +1,85 @@
+package com.zksy.WaterSupply.WaterPipeInfo.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.zksy.WaterSupply.WaterPipeInfo.domain.WaterPipeInfo;
+import com.zksy.WaterSupply.WaterPipeInfo.mapper.WaterPipeInfoMapper;
+import com.zksy.WaterSupply.WaterPipeInfo.service.IWaterPipeInfoService;
+import org.springframework.stereotype.Service;
+import org.springframework.util.StringUtils;
+
+import java.time.LocalDateTime;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+@Service
+public class WaterPipeInfoServiceImpl extends ServiceImpl<WaterPipeInfoMapper, WaterPipeInfo>
+        implements IWaterPipeInfoService {
+
+    @Override
+    public IPage<WaterPipeInfo> queryPage(Page<WaterPipeInfo> page,
+                                          String pipeCode,
+                                          String pipeName,
+                                          String pipeMaterial,
+                                          String status,
+                                          LocalDateTime startTime,
+                                          LocalDateTime endTime) {
+        List<WaterPipeInfo> list = baseMapper.selectPipeList(pipeCode, pipeName, pipeMaterial, status, startTime, endTime);
+        page.setRecords(list);
+        page.setTotal(list.size());
+        return page;
+    }
+
+    @Override
+    public List<Map<String, Object>> statPipeByStatus() {
+        return baseMapper.statPipeByStatus();
+    }
+
+    @Override
+    public List<Map<String, Object>> statPipeByMaterial() {
+        return baseMapper.statPipeByMaterial();
+    }
+
+    @Override
+    public WaterPipeInfo getLatestPipe() {
+        return baseMapper.getLatestPipe();
+    }
+
+    @Override
+    public Map<String, Object> getPipeOverallStatistics() {
+        return baseMapper.getPipeOverallStatistics();
+    }
+
+    @Override
+    public IPage<WaterPipeInfo> queryDeletedPage(Page<WaterPipeInfo> page,
+                                                 String pipeCode,
+                                                 String pipeName,
+                                                 String pipeMaterial,
+                                                 LocalDateTime startTime,
+                                                 LocalDateTime endTime) {
+        List<WaterPipeInfo> list = baseMapper.selectDeletedList(pipeCode, pipeName, pipeMaterial, startTime, endTime);
+        page.setRecords(list);
+        page.setTotal(list.size());
+        return page;
+    }
+
+    @Override
+    public boolean restoreByIds(List<Long> ids, String updateBy) {
+        if (ids == null || ids.isEmpty()) {
+            return false;
+        }
+        // 直接传递List,不需要再转字符串
+        return baseMapper.restoreByIds(ids, updateBy) > 0;
+    }
+
+    @Override
+    public boolean deleteByIdsPhysically(List<Long> ids) {
+        if (ids == null || ids.isEmpty()) {
+            return false;
+        }
+        return baseMapper.deleteByIdsPhysically(ids) > 0;
+    }
+}

+ 197 - 0
pipe-network-service/zksy-system/src/main/java/com/zksy/WaterSupply/WaterPlantInfo/domain/WaterPlantInfo.java

@@ -0,0 +1,197 @@
+package com.zksy.WaterSupply.WaterPlantInfo.domain;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableLogic;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.math.BigDecimal;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+
+/**
+ * 水厂信息实体
+ */
+@Data
+@TableName("water_plant_info")
+@ApiModel(
+        value = "WaterPlantInfo",
+        description = "水厂信息对象,包含供水水厂的所有基础属性"
+)
+public class WaterPlantInfo {
+
+    @ApiModelProperty(
+            value = "主键ID",
+            example = "0",
+            position = 1,
+            notes = "数据库自增主键,新增时不需要传入"
+    )
+    @TableId(type = IdType.AUTO)
+    private Long id;
+
+    @ApiModelProperty(
+            value = "水厂编号",
+            example = "WP001",
+            required = true,
+            position = 2,
+            notes = "水厂唯一标识,系统内唯一"
+    )
+    private String plantCode;
+
+    @ApiModelProperty(
+            value = "水厂名称",
+            example = "XX自来水厂",
+            required = true,
+            position = 3,
+            notes = "水厂的中文名称,用于显示"
+    )
+    private String plantName;
+
+    @ApiModelProperty(
+            value = "水厂地址",
+            example = "XX大道88号",
+            position = 4,
+            notes = "水厂的详细地理位置"
+    )
+    private String location;
+
+    @ApiModelProperty(
+            value = "水源类型",
+            example = "地表水",
+            position = 5,
+            notes = "水源类型"
+    )
+    private String waterSourceType;
+
+    @ApiModelProperty(
+            value = "设计日供水能力",
+            example = "10.00",
+            position = 6,
+            notes = "水厂设计日供水能力,单位:万立方米/天(万m³/d)"
+    )
+    private BigDecimal designCapacity;
+
+    @ApiModelProperty(
+            value = "实际日供水能力",
+            example = "8.50",
+            position = 7,
+            notes = "水厂实际日供水能力,单位:万立方米/天(万m³/d)"
+    )
+    private BigDecimal currentCapacity;
+
+    @ApiModelProperty(
+            value = "处理工艺",
+            example = "混凝-沉淀-过滤-消毒",
+            position = 8,
+            notes = "水厂采用的水处理工艺流程"
+    )
+    private String treatmentProcess;
+
+    @ApiModelProperty(
+            value = "投运日期",
+            example = "2026-06-20",
+            position = 9,
+            notes = "水厂正式投入运行的日期"
+    )
+    @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
+    private LocalDate commissionDate;
+
+    @ApiModelProperty(
+            value = "水质执行标准",
+            example = "GB5749-2022",
+            position = 10,
+            notes = "水厂出水水质执行的国家标准"
+    )
+    private String waterQualityStandard;
+
+    @ApiModelProperty(
+            value = "运行状态",
+            example = "0",
+            allowableValues = "0,1",
+            position = 11,
+            notes = "0-正常运行,1-停产"
+    )
+    private String status;
+
+    @ApiModelProperty(
+            value = "负责人",
+            example = "李四",
+            position = 12,
+            notes = "水厂日常运维负责人姓名"
+    )
+    private String principal;
+
+    @ApiModelProperty(
+            value = "联系电话",
+            example = "13800000000",
+            position = 13,
+            notes = "负责人联系电话"
+    )
+    private String contactPhone;
+
+    @ApiModelProperty(
+            value = "备注",
+            example = "主要供水水厂",
+            position = 14,
+            notes = "其他补充说明信息"
+    )
+    private String remark;
+
+    @ApiModelProperty(
+            value = "删除标志",
+            example = "0",
+            allowableValues = "0,2",
+            hidden = true,
+            position = 15,
+            notes = "0-正常存在,2-已删除(逻辑删除)"
+    )
+    @TableLogic
+    private String delFlag;
+
+    @ApiModelProperty(
+            value = "创建者",
+            example = "admin",
+            hidden = true,
+            position = 16,
+            notes = "创建该记录的用户账号"
+    )
+    @TableField(fill = com.baomidou.mybatisplus.annotation.FieldFill.INSERT)
+    private String createBy;
+
+    @ApiModelProperty(
+            value = "创建时间",
+            example = "2026-05-25 09:00:00",
+            hidden = true,
+            position = 17,
+            notes = "记录创建的时间"
+    )
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    @TableField(fill = com.baomidou.mybatisplus.annotation.FieldFill.INSERT)
+    private LocalDateTime createTime;
+
+    @ApiModelProperty(
+            value = "更新者",
+            example = "admin",
+            hidden = true,
+            position = 18,
+            notes = "最后修改该记录的用户账号"
+    )
+    @TableField(fill = com.baomidou.mybatisplus.annotation.FieldFill.UPDATE)
+    private String updateBy;
+
+    @ApiModelProperty(
+            value = "更新时间",
+            example = "2026-05-25 10:00:00",
+            hidden = true,
+            position = 19,
+            notes = "记录最后修改的时间"
+    )
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    @TableField(fill = com.baomidou.mybatisplus.annotation.FieldFill.UPDATE)
+    private LocalDateTime updateTime;
+}

+ 42 - 0
pipe-network-service/zksy-system/src/main/java/com/zksy/WaterSupply/WaterPlantInfo/mapper/WaterPlantInfoMapper.java

@@ -0,0 +1,42 @@
+package com.zksy.WaterSupply.WaterPlantInfo.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.zksy.WaterSupply.WaterPlantInfo.domain.WaterPlantInfo;
+import org.apache.ibatis.annotations.Param;
+
+import java.time.LocalDateTime;
+import java.util.List;
+
+public interface WaterPlantInfoMapper extends BaseMapper<WaterPlantInfo> {
+
+    /**
+     * 条件查询水厂列表
+     */
+    List<WaterPlantInfo> selectPlantList(
+            @Param("plantCode") String plantCode,
+            @Param("plantName") String plantName,
+            @Param("status") String status,
+            @Param("principal") String principal,
+            @Param("startTime") LocalDateTime startTime,
+            @Param("endTime") LocalDateTime endTime);
+
+    /**
+     * 查询已删除的水厂数据
+     */
+    List<WaterPlantInfo> selectDeletedList(
+            @Param("plantCode") String plantCode,
+            @Param("plantName") String plantName,
+            @Param("status") String status,
+            @Param("startTime") LocalDateTime startTime,
+            @Param("endTime") LocalDateTime endTime);
+
+    /**
+     * 批量恢复已删除数据
+     */
+    int restoreByIds(@Param("ids") List<Long> ids, @Param("updateBy") String updateBy);
+
+    /**
+     * 批量彻底物理删除数据
+     */
+    int deleteByIdsPhysically(@Param("ids") List<Long> ids);
+}

+ 43 - 0
pipe-network-service/zksy-system/src/main/java/com/zksy/WaterSupply/WaterPlantInfo/service/IWaterPlantInfoService.java

@@ -0,0 +1,43 @@
+package com.zksy.WaterSupply.WaterPlantInfo.service;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.zksy.WaterSupply.WaterPlantInfo.domain.WaterPlantInfo;
+
+import java.time.LocalDateTime;
+import java.util.List;
+
+public interface IWaterPlantInfoService extends IService<WaterPlantInfo> {
+
+    /**
+     * 分页查询水厂数据
+     */
+    IPage<WaterPlantInfo> queryPage(Page<WaterPlantInfo> page,
+                                    String plantCode,
+                                    String plantName,
+                                    String status,
+                                    String principal,
+                                    LocalDateTime startTime,
+                                    LocalDateTime endTime);
+
+    /**
+     * 分页查询回收站数据
+     */
+    IPage<WaterPlantInfo> queryDeletedPage(Page<WaterPlantInfo> page,
+                                           String plantCode,
+                                           String plantName,
+                                           String status,
+                                           LocalDateTime startTime,
+                                           LocalDateTime endTime);
+
+    /**
+     * 批量恢复已删除数据
+     */
+    boolean restoreByIds(List<Long> ids, String updateBy);
+
+    /**
+     * 批量彻底物理删除数据
+     */
+    boolean deleteByIdsPhysically(List<Long> ids);
+}

+ 60 - 0
pipe-network-service/zksy-system/src/main/java/com/zksy/WaterSupply/WaterPlantInfo/service/impl/WaterPlantInfoServiceImpl.java

@@ -0,0 +1,60 @@
+package com.zksy.WaterSupply.WaterPlantInfo.service.impl;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.zksy.WaterSupply.WaterPlantInfo.domain.WaterPlantInfo;
+import com.zksy.WaterSupply.WaterPlantInfo.mapper.WaterPlantInfoMapper;
+import com.zksy.WaterSupply.WaterPlantInfo.service.IWaterPlantInfoService;
+import org.springframework.stereotype.Service;
+
+import java.time.LocalDateTime;
+import java.util.List;
+
+@Service
+public class WaterPlantInfoServiceImpl extends ServiceImpl<WaterPlantInfoMapper, WaterPlantInfo>
+        implements IWaterPlantInfoService {
+
+    @Override
+    public IPage<WaterPlantInfo> queryPage(Page<WaterPlantInfo> page,
+                                           String plantCode,
+                                           String plantName,
+                                           String status,
+                                           String principal,
+                                           LocalDateTime startTime,
+                                           LocalDateTime endTime) {
+        List<WaterPlantInfo> list = baseMapper.selectPlantList(plantCode, plantName, status, principal, startTime, endTime);
+        page.setRecords(list);
+        page.setTotal(list.size());
+        return page;
+    }
+
+    @Override
+    public IPage<WaterPlantInfo> queryDeletedPage(Page<WaterPlantInfo> page,
+                                                  String plantCode,
+                                                  String plantName,
+                                                  String status,
+                                                  LocalDateTime startTime,
+                                                  LocalDateTime endTime) {
+        List<WaterPlantInfo> list = baseMapper.selectDeletedList(plantCode, plantName, status, startTime, endTime);
+        page.setRecords(list);
+        page.setTotal(list.size());
+        return page;
+    }
+
+    @Override
+    public boolean restoreByIds(List<Long> ids, String updateBy) {
+        if (ids == null || ids.isEmpty()) {
+            return false;
+        }
+        return baseMapper.restoreByIds(ids, updateBy) > 0;
+    }
+
+    @Override
+    public boolean deleteByIdsPhysically(List<Long> ids) {
+        if (ids == null || ids.isEmpty()) {
+            return false;
+        }
+        return baseMapper.deleteByIdsPhysically(ids) > 0;
+    }
+}

+ 189 - 0
pipe-network-service/zksy-system/src/main/java/com/zksy/WaterSupply/WaterPumpStation/domain/WaterPumpStation.java

@@ -0,0 +1,189 @@
+package com.zksy.WaterSupply.WaterPumpStation.domain;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableLogic;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.math.BigDecimal;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+
+/**
+ * 泵站信息实体
+ */
+@Data
+@TableName("water_pump_station")
+@ApiModel(
+        value = "WaterPumpStation",
+        description = "泵站信息对象,包含供水泵站的所有基础属性"
+)
+public class WaterPumpStation {
+
+    @ApiModelProperty(
+            value = "主键ID",
+            example = "0",
+            position = 1,
+            notes = "数据库自增主键,新增时不需要传入"
+    )
+    @TableId(type = IdType.AUTO)
+    private Long id;
+
+    @ApiModelProperty(
+            value = "泵站编号",
+            example = "PS001",
+            required = true,
+            position = 2,
+            notes = "泵站唯一标识,系统内唯一"
+    )
+    private String stationCode;
+
+    @ApiModelProperty(
+            value = "泵站名称",
+            example = "xx加压泵站1",
+            required = true,
+            position = 3,
+            notes = "泵站的中文名称,用于显示"
+    )
+    private String stationName;
+
+    @ApiModelProperty(
+            value = "泵站地址",
+            example = "xx大道123号",
+            position = 4,
+            notes = "泵站的详细地理位置"
+    )
+    private String location;
+
+    @ApiModelProperty(
+            value = "水泵数量",
+            example = "4",
+            position = 5,
+            notes = "泵站内安装的水泵总台数"
+    )
+    private Integer pumpCount;
+
+    @ApiModelProperty(
+            value = "设计流量",
+            example = "500.00",
+            position = 6,
+            notes = "泵站设计最大供水流量,单位:立方米/小时(m³/h)"
+    )
+    private BigDecimal designFlow;
+
+    @ApiModelProperty(
+            value = "设计扬程",
+            example = "60.00",
+            position = 7,
+            notes = "泵站设计最大供水扬程,单位:米(m)"
+    )
+    private BigDecimal designHead;
+
+    @ApiModelProperty(
+            value = "装机容量",
+            example = "200.00",
+            position = 8,
+            notes = "泵站所有水泵总装机功率,单位:千瓦(kW)"
+    )
+    private BigDecimal powerCapacity;
+
+    @ApiModelProperty(
+            value = "投运日期",
+            example = "2026-05-18",
+            position = 9,
+            notes = "泵站正式投入运行的日期"
+    )
+    @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
+    private LocalDate commissionDate;
+
+    @ApiModelProperty(
+            value = "运行状态",
+            example = "0",
+            allowableValues = "0,1,2",
+            position = 10,
+            notes = "0-正常运行,1-故障停运,2-检修中"
+    )
+    private String status;
+
+    @ApiModelProperty(
+            value = "负责人",
+            example = "张三",
+            position = 11,
+            notes = "泵站日常运维负责人姓名"
+    )
+    private String principal;
+
+    @ApiModelProperty(
+            value = "联系电话",
+            example = "13800138000",
+            position = 12,
+            notes = "负责人联系电话"
+    )
+    private String contactPhone;
+
+    @ApiModelProperty(
+            value = "备注",
+            example = "片区主要加压泵站",
+            position = 13,
+            notes = "其他补充说明信息"
+    )
+    private String remark;
+
+    @ApiModelProperty(
+            value = "删除标志",
+            example = "0",
+            allowableValues = "0,2",
+            hidden = true,
+            position = 14,
+            notes = "0-正常存在,2-已删除(逻辑删除)"
+    )
+    @TableLogic
+    private String delFlag;
+
+    @ApiModelProperty(
+            value = "创建者",
+            example = "admin",
+            hidden = true,
+            position = 15,
+            notes = "创建该记录的用户账号"
+    )
+    @TableField(fill = com.baomidou.mybatisplus.annotation.FieldFill.INSERT)
+    private String createBy;
+
+    @ApiModelProperty(
+            value = "创建时间",
+            example = "2026-05-18 10:00:00",
+            hidden = true,
+            position = 16,
+            notes = "记录创建的时间"
+    )
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    @TableField(fill = com.baomidou.mybatisplus.annotation.FieldFill.INSERT)
+    private LocalDateTime createTime;
+
+    @ApiModelProperty(
+            value = "更新者",
+            example = "admin",
+            hidden = true,
+            position = 17,
+            notes = "最后修改该记录的用户账号"
+    )
+    @TableField(fill = com.baomidou.mybatisplus.annotation.FieldFill.UPDATE)
+    private String updateBy;
+
+    @ApiModelProperty(
+            value = "更新时间",
+            example = "2026-05-18 14:00:00",
+            hidden = true,
+            position = 18,
+            notes = "记录最后修改的时间"
+    )
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    @TableField(fill = com.baomidou.mybatisplus.annotation.FieldFill.UPDATE)
+    private LocalDateTime updateTime;
+}

+ 43 - 0
pipe-network-service/zksy-system/src/main/java/com/zksy/WaterSupply/WaterPumpStation/mapper/WaterPumpStationMapper.java

@@ -0,0 +1,43 @@
+package com.zksy.WaterSupply.WaterPumpStation.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.zksy.WaterSupply.WaterPumpStation.domain.WaterPumpStation;
+import org.apache.ibatis.annotations.Param;
+import org.apache.ibatis.annotations.Update;
+
+import java.time.LocalDateTime;
+import java.util.List;
+
+public interface WaterPumpStationMapper extends BaseMapper<WaterPumpStation> {
+
+    /**
+     * 条件查询泵站列表
+     */
+    List<WaterPumpStation> selectStationList(
+            @Param("stationCode") String stationCode,
+            @Param("stationName") String stationName,
+            @Param("status") String status,
+            @Param("principal") String principal,
+            @Param("startTime") LocalDateTime startTime,
+            @Param("endTime") LocalDateTime endTime);
+
+    /**
+     * 查询已删除的泵站数据
+     */
+    List<WaterPumpStation> selectDeletedList(
+            @Param("stationCode") String stationCode,
+            @Param("stationName") String stationName,
+            @Param("status") String status,
+            @Param("startTime") LocalDateTime startTime,
+            @Param("endTime") LocalDateTime endTime);
+
+    /**
+     * 批量恢复已删除数据
+     */
+    int restoreByIds(@Param("ids") List<Long> ids, @Param("updateBy") String updateBy);
+
+    /**
+     * 批量彻底物理删除数据
+     */
+    int deleteByIdsPhysically(@Param("ids") List<Long> ids);
+}

+ 43 - 0
pipe-network-service/zksy-system/src/main/java/com/zksy/WaterSupply/WaterPumpStation/service/IWaterPumpStationService.java

@@ -0,0 +1,43 @@
+package com.zksy.WaterSupply.WaterPumpStation.service;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.zksy.WaterSupply.WaterPumpStation.domain.WaterPumpStation;
+
+import java.time.LocalDateTime;
+import java.util.List;
+
+public interface IWaterPumpStationService extends IService<WaterPumpStation> {
+
+    /**
+     * 分页查询泵站数据
+     */
+    IPage<WaterPumpStation> queryPage(Page<WaterPumpStation> page,
+                                      String stationCode,
+                                      String stationName,
+                                      String status,
+                                      String principal,
+                                      LocalDateTime startTime,
+                                      LocalDateTime endTime);
+
+    /**
+     * 分页查询回收站数据
+     */
+    IPage<WaterPumpStation> queryDeletedPage(Page<WaterPumpStation> page,
+                                             String stationCode,
+                                             String stationName,
+                                             String status,
+                                             LocalDateTime startTime,
+                                             LocalDateTime endTime);
+
+    /**
+     * 批量恢复已删除数据
+     */
+    boolean restoreByIds(List<Long> ids, String updateBy);
+
+    /**
+     * 批量彻底物理删除数据
+     */
+    boolean deleteByIdsPhysically(List<Long> ids);
+}

+ 60 - 0
pipe-network-service/zksy-system/src/main/java/com/zksy/WaterSupply/WaterPumpStation/service/impl/WaterPumpStationServiceImpl.java

@@ -0,0 +1,60 @@
+package com.zksy.WaterSupply.WaterPumpStation.service.impl;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.zksy.WaterSupply.WaterPumpStation.domain.WaterPumpStation;
+import com.zksy.WaterSupply.WaterPumpStation.mapper.WaterPumpStationMapper;
+import com.zksy.WaterSupply.WaterPumpStation.service.IWaterPumpStationService;
+import org.springframework.stereotype.Service;
+
+import java.time.LocalDateTime;
+import java.util.List;
+
+@Service
+public class WaterPumpStationServiceImpl extends ServiceImpl<WaterPumpStationMapper, WaterPumpStation>
+        implements IWaterPumpStationService {
+
+    @Override
+    public IPage<WaterPumpStation> queryPage(Page<WaterPumpStation> page,
+                                             String stationCode,
+                                             String stationName,
+                                             String status,
+                                             String principal,
+                                             LocalDateTime startTime,
+                                             LocalDateTime endTime) {
+        List<WaterPumpStation> list = baseMapper.selectStationList(stationCode, stationName, status, principal, startTime, endTime);
+        page.setRecords(list);
+        page.setTotal(list.size());
+        return page;
+    }
+
+    @Override
+    public IPage<WaterPumpStation> queryDeletedPage(Page<WaterPumpStation> page,
+                                                    String stationCode,
+                                                    String stationName,
+                                                    String status,
+                                                    LocalDateTime startTime,
+                                                    LocalDateTime endTime) {
+        List<WaterPumpStation> list = baseMapper.selectDeletedList(stationCode, stationName, status, startTime, endTime);
+        page.setRecords(list);
+        page.setTotal(list.size());
+        return page;
+    }
+
+    @Override
+    public boolean restoreByIds(List<Long> ids, String updateBy) {
+        if (ids == null || ids.isEmpty()) {
+            return false;
+        }
+        return baseMapper.restoreByIds(ids, updateBy) > 0;
+    }
+
+    @Override
+    public boolean deleteByIdsPhysically(List<Long> ids) {
+        if (ids == null || ids.isEmpty()) {
+            return false;
+        }
+        return baseMapper.deleteByIdsPhysically(ids) > 0;
+    }
+}

+ 176 - 0
pipe-network-service/zksy-system/src/main/java/com/zksy/WaterSupply/WaterSourceInfo/domain/WaterSourceInfo.java

@@ -0,0 +1,176 @@
+package com.zksy.WaterSupply.WaterSourceInfo.domain;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableLogic;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+
+/**
+ * 水源地信息实体
+ */
+@Data
+@TableName("water_source_info")
+@ApiModel(
+        value = "WaterSourceInfo",
+        description = "水源地信息对象,包含水源地基础属性"
+)
+public class WaterSourceInfo {
+
+    @ApiModelProperty(
+            value = "主键ID",
+            example = "0",
+            position = 1,
+            notes = "数据库自增主键,新增时不需要传入"
+    )
+    @TableId(type = IdType.AUTO)
+    private Long id;
+
+    @ApiModelProperty(
+            value = "水源地ID",
+            example = "SOURCE_XX",
+            required = true,
+            position = 2
+    )
+    private String sourceId;
+
+    @ApiModelProperty(
+            value = "水源地名称",
+            example = "XX水源地",
+            required = true,
+            position = 3
+    )
+    private String sourceName;
+
+    @ApiModelProperty(
+            value = "水源地类型",
+            example = "系统辨识",
+            position = 4,
+            notes = "系统辨识/企业上报/政府检查"
+    )
+    private String sourceType;
+
+    @ApiModelProperty(
+            value = "所属单位",
+            example = "XX供水公司",
+            position = 5
+    )
+    private String unit;
+
+    @ApiModelProperty(
+            value = "详细地址",
+            example = "XX大道XX号",
+            position = 6
+    )
+    private String address;
+
+    @ApiModelProperty(
+            value = "水源类型",
+            example = "地表水",
+            position = 7,
+            notes = "地表水/地下水"
+    )
+    private String waterType;
+
+    @ApiModelProperty(
+            value = "保护等级",
+            example = "一级",
+            position = 8,
+            notes = "一级/二级/准保护区"
+    )
+    private String protectionLevel;
+
+    @ApiModelProperty(
+            value = "水质等级",
+            example = "Ⅱ类",
+            position = 9,
+            notes = "Ⅰ-Ⅴ类"
+    )
+    private String waterQualityLevel;
+
+    @ApiModelProperty(
+            value = "保护范围描述",
+            example = "XX区域范围内水源保护区",
+            position = 10
+    )
+    private String protectionScope;
+
+    @ApiModelProperty(
+            value = "上报时间",
+            example = "2025-01-01",
+            position = 11
+    )
+    @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
+    private LocalDate reportTime;
+
+    @ApiModelProperty(
+            value = "状态",
+            example = "0",
+            allowableValues = "0,1",
+            position = 12,
+            notes = "0正常 1异常"
+    )
+    private String status;
+
+    @ApiModelProperty(
+            value = "备注",
+            example = "XX区域重要水源地",
+            position = 13
+    )
+    private String remark;
+
+    @ApiModelProperty(
+            value = "删除标志",
+            example = "0",
+            allowableValues = "0,2",
+            hidden = true,
+            position = 14
+    )
+    @TableLogic
+    private String delFlag;
+
+    @ApiModelProperty(
+            value = "创建者",
+            example = "admin",
+            hidden = true,
+            position = 15
+    )
+    @TableField(fill = com.baomidou.mybatisplus.annotation.FieldFill.INSERT)
+    private String createBy;
+
+    @ApiModelProperty(
+            value = "创建时间",
+            example = "2025-01-01 00:00:00",
+            hidden = true,
+            position = 16
+    )
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    @TableField(fill = com.baomidou.mybatisplus.annotation.FieldFill.INSERT)
+    private LocalDateTime createTime;
+
+    @ApiModelProperty(
+            value = "更新者",
+            example = "admin",
+            hidden = true,
+            position = 17
+    )
+    @TableField(fill = com.baomidou.mybatisplus.annotation.FieldFill.UPDATE)
+    private String updateBy;
+
+    @ApiModelProperty(
+            value = "更新时间",
+            example = "2025-01-01 00:00:00",
+            hidden = true,
+            position = 18
+    )
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    @TableField(fill = com.baomidou.mybatisplus.annotation.FieldFill.UPDATE)
+    private LocalDateTime updateTime;
+}

+ 30 - 0
pipe-network-service/zksy-system/src/main/java/com/zksy/WaterSupply/WaterSourceInfo/mapper/WaterSourceInfoMapper.java

@@ -0,0 +1,30 @@
+package com.zksy.WaterSupply.WaterSourceInfo.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.zksy.WaterSupply.WaterSourceInfo.domain.WaterSourceInfo;
+import org.apache.ibatis.annotations.Param;
+
+import java.time.LocalDateTime;
+import java.util.List;
+
+public interface WaterSourceInfoMapper extends BaseMapper<WaterSourceInfo> {
+
+    List<WaterSourceInfo> selectSourceList(
+            @Param("sourceId") String sourceId,
+            @Param("sourceName") String sourceName,
+            @Param("status") String status,
+            @Param("unit") String unit,
+            @Param("startTime") LocalDateTime startTime,
+            @Param("endTime") LocalDateTime endTime);
+
+    List<WaterSourceInfo> selectDeletedList(
+            @Param("sourceId") String sourceId,
+            @Param("sourceName") String sourceName,
+            @Param("status") String status,
+            @Param("startTime") LocalDateTime startTime,
+            @Param("endTime") LocalDateTime endTime);
+
+    int restoreByIds(@Param("ids") List<Long> ids, @Param("updateBy") String updateBy);
+
+    int deleteByIdsPhysically(@Param("ids") List<Long> ids);
+}

+ 31 - 0
pipe-network-service/zksy-system/src/main/java/com/zksy/WaterSupply/WaterSourceInfo/service/IWaterSourceInfoService.java

@@ -0,0 +1,31 @@
+package com.zksy.WaterSupply.WaterSourceInfo.service;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.zksy.WaterSupply.WaterSourceInfo.domain.WaterSourceInfo;
+
+import java.time.LocalDateTime;
+import java.util.List;
+
+public interface IWaterSourceInfoService extends IService<WaterSourceInfo> {
+
+    IPage<WaterSourceInfo> queryPage(Page<WaterSourceInfo> page,
+                                     String sourceId,
+                                     String sourceName,
+                                     String status,
+                                     String unit,
+                                     LocalDateTime startTime,
+                                     LocalDateTime endTime);
+
+    IPage<WaterSourceInfo> queryDeletedPage(Page<WaterSourceInfo> page,
+                                            String sourceId,
+                                            String sourceName,
+                                            String status,
+                                            LocalDateTime startTime,
+                                            LocalDateTime endTime);
+
+    boolean restoreByIds(List<Long> ids, String updateBy);
+
+    boolean deleteByIdsPhysically(List<Long> ids);
+}

+ 56 - 0
pipe-network-service/zksy-system/src/main/java/com/zksy/WaterSupply/WaterSourceInfo/service/impl/WaterSourceInfoServiceImpl.java

@@ -0,0 +1,56 @@
+package com.zksy.WaterSupply.WaterSourceInfo.service.impl;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.zksy.WaterSupply.WaterSourceInfo.domain.WaterSourceInfo;
+import com.zksy.WaterSupply.WaterSourceInfo.mapper.WaterSourceInfoMapper;
+import com.zksy.WaterSupply.WaterSourceInfo.service.IWaterSourceInfoService;
+import org.springframework.stereotype.Service;
+
+import java.time.LocalDateTime;
+import java.util.List;
+
+@Service
+public class WaterSourceInfoServiceImpl extends ServiceImpl<WaterSourceInfoMapper, WaterSourceInfo>
+        implements IWaterSourceInfoService {
+
+    @Override
+    public IPage<WaterSourceInfo> queryPage(Page<WaterSourceInfo> page,
+                                            String sourceId,
+                                            String sourceName,
+                                            String status,
+                                            String unit,
+                                            LocalDateTime startTime,
+                                            LocalDateTime endTime) {
+        List<WaterSourceInfo> list = baseMapper.selectSourceList(sourceId, sourceName, status, unit, startTime, endTime);
+        page.setRecords(list);
+        page.setTotal(list.size());
+        return page;
+    }
+
+    @Override
+    public IPage<WaterSourceInfo> queryDeletedPage(Page<WaterSourceInfo> page,
+                                                   String sourceId,
+                                                   String sourceName,
+                                                   String status,
+                                                   LocalDateTime startTime,
+                                                   LocalDateTime endTime) {
+        List<WaterSourceInfo> list = baseMapper.selectDeletedList(sourceId, sourceName, status, startTime, endTime);
+        page.setRecords(list);
+        page.setTotal(list.size());
+        return page;
+    }
+
+    @Override
+    public boolean restoreByIds(List<Long> ids, String updateBy) {
+        if (ids == null || ids.isEmpty()) return false;
+        return baseMapper.restoreByIds(ids, updateBy) > 0;
+    }
+
+    @Override
+    public boolean deleteByIdsPhysically(List<Long> ids) {
+        if (ids == null || ids.isEmpty()) return false;
+        return baseMapper.deleteByIdsPhysically(ids) > 0;
+    }
+}

+ 175 - 0
pipe-network-service/zksy-system/src/main/java/com/zksy/WaterSupply/WaterUserInfo/domain/WaterUserInfo.java

@@ -0,0 +1,175 @@
+package com.zksy.WaterSupply.WaterUserInfo.domain;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableLogic;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+
+/**
+ * 用水户信息实体
+ */
+@Data
+@TableName("water_user_info")
+@ApiModel(
+        value = "WaterUserInfo",
+        description = "用水户信息对象,包含用水户基础属性"
+)
+public class WaterUserInfo {
+
+    @ApiModelProperty(
+            value = "主键ID",
+            example = "0",
+            position = 1,
+            notes = "数据库自增主键,新增时不需要传入"
+    )
+    @TableId(type = IdType.AUTO)
+    private Long id;
+
+    @ApiModelProperty(
+            value = "用户编号",
+            example = "USER_XX",
+            required = true,
+            position = 2
+    )
+    private String userCode;
+
+    @ApiModelProperty(
+            value = "用户名称",
+            example = "XX用户",
+            required = true,
+            position = 3
+    )
+    private String userName;
+
+    @ApiModelProperty(
+            value = "用户类型",
+            example = "居民",
+            position = 4,
+            notes = "居民/工业/商业/行政事业"
+    )
+    private String userType;
+
+    @ApiModelProperty(
+            value = "用水地址",
+            example = "XX小区XX栋XX单元XX室",
+            position = 5
+    )
+    private String address;
+
+    @ApiModelProperty(
+            value = "联系人",
+            example = "XX",
+            position = 6
+    )
+    private String contactPerson;
+
+    @ApiModelProperty(
+            value = "联系电话",
+            example = "13800138000",
+            position = 7
+    )
+    private String contactPhone;
+
+    @ApiModelProperty(
+            value = "水表编号",
+            example = "METER_XX",
+            position = 8
+    )
+    private String meterNumber;
+
+    @ApiModelProperty(
+            value = "初始读数",
+            example = "0.00",
+            position = 9,
+            notes = "单位:立方米(m³)"
+    )
+    private BigDecimal initialReading;
+
+    @ApiModelProperty(
+            value = "当前读数",
+            example = "125.50",
+            position = 10,
+            notes = "单位:立方米(m³)"
+    )
+    private BigDecimal currentReading;
+
+    @ApiModelProperty(
+            value = "年用水量",
+            example = "180.00",
+            position = 11,
+            notes = "单位:立方米(m³)"
+    )
+    private BigDecimal annualWaterConsumption;
+
+    @ApiModelProperty(
+            value = "用户状态",
+            example = "0",
+            allowableValues = "0,1,2",
+            position = 12,
+            notes = "0正常 1欠费 2停用"
+    )
+    private String status;
+
+    @ApiModelProperty(
+            value = "备注",
+            example = "XX区域重要用水户",
+            position = 13
+    )
+    private String remark;
+
+    @ApiModelProperty(
+            value = "删除标志",
+            example = "0",
+            allowableValues = "0,2",
+            hidden = true,
+            position = 14
+    )
+    @TableLogic
+    private String delFlag;
+
+    @ApiModelProperty(
+            value = "创建者",
+            example = "admin",
+            hidden = true,
+            position = 15
+    )
+    @TableField(fill = com.baomidou.mybatisplus.annotation.FieldFill.INSERT)
+    private String createBy;
+
+    @ApiModelProperty(
+            value = "创建时间",
+            example = "2025-01-01 00:00:00",
+            hidden = true,
+            position = 16
+    )
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    @TableField(fill = com.baomidou.mybatisplus.annotation.FieldFill.INSERT)
+    private LocalDateTime createTime;
+
+    @ApiModelProperty(
+            value = "更新者",
+            example = "admin",
+            hidden = true,
+            position = 17
+    )
+    @TableField(fill = com.baomidou.mybatisplus.annotation.FieldFill.UPDATE)
+    private String updateBy;
+
+    @ApiModelProperty(
+            value = "更新时间",
+            example = "2025-01-01 00:00:00",
+            hidden = true,
+            position = 18
+    )
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    @TableField(fill = com.baomidou.mybatisplus.annotation.FieldFill.UPDATE)
+    private LocalDateTime updateTime;
+}

+ 29 - 0
pipe-network-service/zksy-system/src/main/java/com/zksy/WaterSupply/WaterUserInfo/mapper/WaterUserInfoMapper.java

@@ -0,0 +1,29 @@
+package com.zksy.WaterSupply.WaterUserInfo.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.zksy.WaterSupply.WaterUserInfo.domain.WaterUserInfo;
+import org.apache.ibatis.annotations.Param;
+import java.time.LocalDateTime;
+import java.util.List;
+
+public interface WaterUserInfoMapper extends BaseMapper<WaterUserInfo> {
+
+    List<WaterUserInfo> selectUserList(
+            @Param("userCode") String userCode,
+            @Param("userName") String userName,
+            @Param("status") String status,
+            @Param("userType") String userType,
+            @Param("startTime") LocalDateTime startTime,
+            @Param("endTime") LocalDateTime endTime);
+
+    List<WaterUserInfo> selectDeletedList(
+            @Param("userCode") String userCode,
+            @Param("userName") String userName,
+            @Param("status") String status,
+            @Param("startTime") LocalDateTime startTime,
+            @Param("endTime") LocalDateTime endTime);
+
+    int restoreByIds(@Param("ids") List<Long> ids, @Param("updateBy") String updateBy);
+
+    int deleteByIdsPhysically(@Param("ids") List<Long> ids);
+}

+ 30 - 0
pipe-network-service/zksy-system/src/main/java/com/zksy/WaterSupply/WaterUserInfo/service/IWaterUserInfoService.java

@@ -0,0 +1,30 @@
+package com.zksy.WaterSupply.WaterUserInfo.service;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.zksy.WaterSupply.WaterUserInfo.domain.WaterUserInfo;
+import java.time.LocalDateTime;
+import java.util.List;
+
+public interface IWaterUserInfoService extends IService<WaterUserInfo> {
+
+    IPage<WaterUserInfo> queryPage(Page<WaterUserInfo> page,
+                                   String userCode,
+                                   String userName,
+                                   String status,
+                                   String userType,
+                                   LocalDateTime startTime,
+                                   LocalDateTime endTime);
+
+    IPage<WaterUserInfo> queryDeletedPage(Page<WaterUserInfo> page,
+                                          String userCode,
+                                          String userName,
+                                          String status,
+                                          LocalDateTime startTime,
+                                          LocalDateTime endTime);
+
+    boolean restoreByIds(List<Long> ids, String updateBy);
+
+    boolean deleteByIdsPhysically(List<Long> ids);
+}

+ 55 - 0
pipe-network-service/zksy-system/src/main/java/com/zksy/WaterSupply/WaterUserInfo/service/impl/WaterUserInfoServiceImpl.java

@@ -0,0 +1,55 @@
+package com.zksy.WaterSupply.WaterUserInfo.service.impl;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.zksy.WaterSupply.WaterUserInfo.domain.WaterUserInfo;
+import com.zksy.WaterSupply.WaterUserInfo.mapper.WaterUserInfoMapper;
+import com.zksy.WaterSupply.WaterUserInfo.service.IWaterUserInfoService;
+import org.springframework.stereotype.Service;
+import java.time.LocalDateTime;
+import java.util.List;
+
+@Service
+public class WaterUserInfoServiceImpl extends ServiceImpl<WaterUserInfoMapper, WaterUserInfo>
+        implements IWaterUserInfoService {
+
+    @Override
+    public IPage<WaterUserInfo> queryPage(Page<WaterUserInfo> page,
+                                          String userCode,
+                                          String userName,
+                                          String status,
+                                          String userType,
+                                          LocalDateTime startTime,
+                                          LocalDateTime endTime) {
+        List<WaterUserInfo> list = baseMapper.selectUserList(userCode, userName, status, userType, startTime, endTime);
+        page.setRecords(list);
+        page.setTotal(list.size());
+        return page;
+    }
+
+    @Override
+    public IPage<WaterUserInfo> queryDeletedPage(Page<WaterUserInfo> page,
+                                                 String userCode,
+                                                 String userName,
+                                                 String status,
+                                                 LocalDateTime startTime,
+                                                 LocalDateTime endTime) {
+        List<WaterUserInfo> list = baseMapper.selectDeletedList(userCode, userName, status, startTime, endTime);
+        page.setRecords(list);
+        page.setTotal(list.size());
+        return page;
+    }
+
+    @Override
+    public boolean restoreByIds(List<Long> ids, String updateBy) {
+        if (ids == null || ids.isEmpty()) return false;
+        return baseMapper.restoreByIds(ids, updateBy) > 0;
+    }
+
+    @Override
+    public boolean deleteByIdsPhysically(List<Long> ids) {
+        if (ids == null || ids.isEmpty()) return false;
+        return baseMapper.deleteByIdsPhysically(ids) > 0;
+    }
+}

+ 154 - 0
pipe-network-service/zksy-system/src/main/java/com/zksy/base/warning/mapper/EarlyWarningMapper.java

@@ -27,4 +27,158 @@ public interface EarlyWarningMapper extends BaseMapper<EarlyWarning> {
     Map<String, Object> selectWarningDetail(@Param("warningId") String warningId);
 
     List<Map<String, Object>> selectStatistics();
+
+    /**
+     * 统计今日预警核心指标
+     * @return 包含今日预警总数、已处置数、已解除数的Map
+     */
+    Map<String, Object> selectTodayWarningStats();
+
+    /**
+     * 查询今日预警列表(支持按状态筛选)
+     * @param status 预警状态,为空则查询所有非草稿状态
+     */
+    List<EarlyWarning> selectTodayWarningList(@Param("status") String status);
+
+    /**
+     * 按日统计预警发展趋势(按专项分组)
+     * @param startTime 开始时间
+     * @param endTime 结束时间
+     * @param warningSpecial 预警专项(可选)
+     */
+    List<Map<String, Object>> selectWarningTrendByDay(
+            @Param("startTime") LocalDateTime startTime,
+            @Param("endTime") LocalDateTime endTime,
+            @Param("warningSpecial") String warningSpecial);
+
+    /**
+     * 按月统计预警发展趋势(按专项分组)
+     * @param startTime 开始时间
+     * @param endTime 结束时间
+     * @param warningSpecial 预警专项(可选)
+     */
+    List<Map<String, Object>> selectWarningTrendByMonth(
+            @Param("startTime") LocalDateTime startTime,
+            @Param("endTime") LocalDateTime endTime,
+            @Param("warningSpecial") String warningSpecial);
+
+    /**
+     * 按处置状态分组统计预警数量
+     * @param startTime 开始发布时间
+     * @param endTime 结束发布时间
+     * @param warningSpecial 预警专项(可选)
+     * @return 分组结果:status状态、count数量
+     */
+    List<Map<String, Object>> selectWarningGroupByStatus(
+            @Param("startTime") LocalDateTime startTime,
+            @Param("endTime") LocalDateTime endTime,
+            @Param("warningSpecial") String warningSpecial);
+
+    /**
+     * 处置时效分析-概览指标统计
+     * @param startTime 发布开始时间
+     * @param endTime 发布结束时间
+     * @param warningSpecial 预警专项(可选)
+     * @return 平均/最长/最短处置时长 + 总数
+     */
+    Map<String, Object> selectDisposeEfficiencyOverview(
+            @Param("startTime") LocalDateTime startTime,
+            @Param("endTime") LocalDateTime endTime,
+            @Param("warningSpecial") String warningSpecial);
+
+    /**
+     * 处置时效分析-时效区间分布统计
+     * @param startTime 发布开始时间
+     * @param endTime 发布结束时间
+     * @param warningSpecial 预警专项(可选)
+     * @return 各时长区间预警数量
+     */
+    List<Map<String, Object>> selectDisposeEfficiencyRange(
+            @Param("startTime") LocalDateTime startTime,
+            @Param("endTime") LocalDateTime endTime,
+            @Param("warningSpecial") String warningSpecial);
+
+    /**
+     * 处置时效分析-按预警专项统计平均时效
+     * @param startTime 发布开始时间
+     * @param endTime 发布结束时间
+     * @return 各专项平均处置时长
+     */
+    List<Map<String, Object>> selectDisposeEfficiencyBySpecial(
+            @Param("startTime") LocalDateTime startTime,
+            @Param("endTime") LocalDateTime endTime);
+
+    /**
+     * 处置时效分析-明细列表
+     * @param startTime 发布开始时间
+     * @param endTime 发布结束时间
+     * @param warningSpecial 预警专项(可选)
+     * @param sortType 排序方式 asc-时效从短到长 desc-时效从长到短
+     * @return 预警时效明细
+     */
+    List<Map<String, Object>> selectDisposeEfficiencyList(
+            @Param("startTime") LocalDateTime startTime,
+            @Param("endTime") LocalDateTime endTime,
+            @Param("warningSpecial") String warningSpecial,
+            @Param("sortType") String sortType);
+
+    /**
+     * 接警效率分析-概览指标统计
+     * @param startTime 发布开始时间
+     * @param endTime 发布结束时间
+     * @param warningType 预警类型(可选)
+     * @param warningSpecial 预警专项(可选)
+     * @param status 处置状态(可选)
+     * @return 平均/最长/最短接警时长 + 接警总数
+     */
+    Map<String, Object> selectReceiveEfficiencyOverview(
+            @Param("startTime") LocalDateTime startTime,
+            @Param("endTime") LocalDateTime endTime,
+            @Param("warningType") String warningType,
+            @Param("warningSpecial") String warningSpecial,
+            @Param("status") String status);
+
+    /**
+     * 接警效率分析-时效区间分布统计
+     * @param startTime 发布开始时间
+     * @param endTime 发布结束时间
+     * @param warningType 预警类型(可选)
+     * @param warningSpecial 预警专项(可选)
+     * @param status 处置状态(可选)
+     * @return 各时长区间预警数量
+     */
+    List<Map<String, Object>> selectReceiveEfficiencyRange(
+            @Param("startTime") LocalDateTime startTime,
+            @Param("endTime") LocalDateTime endTime,
+            @Param("warningType") String warningType,
+            @Param("warningSpecial") String warningSpecial,
+            @Param("status") String status);
+
+    /**
+     * 接警效率分析-按预警类型统计平均时效
+     * @param startTime 发布开始时间
+     * @param endTime 发布结束时间
+     * @return 各类型平均接警时长、数量
+     */
+    List<Map<String, Object>> selectReceiveEfficiencyByType(
+            @Param("startTime") LocalDateTime startTime,
+            @Param("endTime") LocalDateTime endTime);
+
+    /**
+     * 接警效率分析-明细列表
+     * @param startTime 发布开始时间
+     * @param endTime 发布结束时间
+     * @param warningType 预警类型(可选)
+     * @param warningSpecial 预警专项(可选)
+     * @param status 处置状态(可选)
+     * @param sortType 排序方式 asc-时效从短到长 desc-时效从长到短
+     * @return 预警接警时效明细
+     */
+    List<Map<String, Object>> selectReceiveEfficiencyList(
+            @Param("startTime") LocalDateTime startTime,
+            @Param("endTime") LocalDateTime endTime,
+            @Param("warningType") String warningType,
+            @Param("warningSpecial") String warningSpecial,
+            @Param("status") String status,
+            @Param("sortType") String sortType);
 }

+ 35 - 0
pipe-network-service/zksy-system/src/main/java/com/zksy/base/warning/service/IEarlyWarningDisposeEfficiencyService.java

@@ -0,0 +1,35 @@
+package com.zksy.base.warning.service;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+
+import java.time.LocalDateTime;
+import java.util.List;
+import java.util.Map;
+
+public interface IEarlyWarningDisposeEfficiencyService {
+
+    /**
+     * 获取处置时效概览指标
+     */
+    Map<String, Object> getEfficiencyOverview(LocalDateTime startTime, LocalDateTime endTime, String warningSpecial);
+
+    /**
+     * 获取处置时效区间分布
+     */
+    List<Map<String, Object>> getEfficiencyRange(LocalDateTime startTime, LocalDateTime endTime, String warningSpecial);
+
+    /**
+     * 按预警专项统计平均处置时效
+     */
+    List<Map<String, Object>> getEfficiencyBySpecial(LocalDateTime startTime, LocalDateTime endTime);
+
+    /**
+     * 分页查询处置时效明细列表
+     */
+    IPage<Map<String, Object>> queryEfficiencyPage(Page<Map<String, Object>> page,
+                                                   LocalDateTime startTime,
+                                                   LocalDateTime endTime,
+                                                   String warningSpecial,
+                                                   String sortType);
+}

+ 19 - 0
pipe-network-service/zksy-system/src/main/java/com/zksy/base/warning/service/IEarlyWarningDisposeStatusService.java

@@ -0,0 +1,19 @@
+package com.zksy.base.warning.service;
+
+import java.time.LocalDateTime;
+import java.util.List;
+import java.util.Map;
+
+public interface IEarlyWarningDisposeStatusService {
+
+    /**
+     * 处置状态分析:按状态分组统计预警数量
+     * @param startTime 发布开始时间
+     * @param endTime 发布结束时间
+     * @param warningSpecial 预警专项
+     * @return 状态+数量集合
+     */
+    List<Map<String, Object>> getWarningStatusStat(LocalDateTime startTime,
+                                                   LocalDateTime endTime,
+                                                   String warningSpecial);
+}

+ 45 - 0
pipe-network-service/zksy-system/src/main/java/com/zksy/base/warning/service/IEarlyWarningReceiveEfficiencyService.java

@@ -0,0 +1,45 @@
+package com.zksy.base.warning.service;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+
+import java.time.LocalDateTime;
+import java.util.List;
+import java.util.Map;
+
+public interface IEarlyWarningReceiveEfficiencyService {
+
+    /**
+     * 获取接警效率概览指标
+     */
+    Map<String, Object> getEfficiencyOverview(LocalDateTime startTime,
+                                              LocalDateTime endTime,
+                                              String warningType,
+                                              String warningSpecial,
+                                              String status);
+
+    /**
+     * 获取接警时效区间分布
+     */
+    List<Map<String, Object>> getEfficiencyRange(LocalDateTime startTime,
+                                                 LocalDateTime endTime,
+                                                 String warningType,
+                                                 String warningSpecial,
+                                                 String status);
+
+    /**
+     * 按预警类型统计平均接警时效
+     */
+    List<Map<String, Object>> getEfficiencyByType(LocalDateTime startTime, LocalDateTime endTime);
+
+    /**
+     * 分页查询接警时效明细列表
+     */
+    IPage<Map<String, Object>> queryEfficiencyPage(Page<Map<String, Object>> page,
+                                                   LocalDateTime startTime,
+                                                   LocalDateTime endTime,
+                                                   String warningType,
+                                                   String warningSpecial,
+                                                   String status,
+                                                   String sortType);
+}

+ 22 - 0
pipe-network-service/zksy-system/src/main/java/com/zksy/base/warning/service/IEarlyWarningTodayService.java

@@ -0,0 +1,22 @@
+package com.zksy.base.warning.service;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.zksy.base.warning.domain.EarlyWarning;
+
+import java.util.Map;
+
+public interface IEarlyWarningTodayService {
+
+    /**
+     * 获取今日预警统计指标
+     */
+    Map<String, Object> getTodayWarningStats();
+
+    /**
+     * 分页查询今日预警列表
+     * @param page 分页参数
+     * @param status 预警状态,为空查所有非草稿
+     */
+    IPage<EarlyWarning> queryTodayWarningPage(Page<EarlyWarning> page, String status);
+}

+ 24 - 0
pipe-network-service/zksy-system/src/main/java/com/zksy/base/warning/service/IEarlyWarningTrendService.java

@@ -0,0 +1,24 @@
+package com.zksy.base.warning.service;
+
+import java.time.LocalDateTime;
+import java.util.List;
+import java.util.Map;
+
+public interface IEarlyWarningTrendService {
+
+    /**
+     * 按日统计预警发展趋势
+     * @param startTime 开始时间
+     * @param endTime 结束时间
+     * @param warningSpecial 预警专项(可选)
+     */
+    List<Map<String, Object>> getTrendByDay(LocalDateTime startTime, LocalDateTime endTime, String warningSpecial);
+
+    /**
+     * 按月统计预警发展趋势
+     * @param startTime 开始时间
+     * @param endTime 结束时间
+     * @param warningSpecial 预警专项(可选)
+     */
+    List<Map<String, Object>> getTrendByMonth(LocalDateTime startTime, LocalDateTime endTime, String warningSpecial);
+}

+ 46 - 0
pipe-network-service/zksy-system/src/main/java/com/zksy/base/warning/service/impl/EarlyWarningDisposeEfficiencyServiceImpl.java

@@ -0,0 +1,46 @@
+package com.zksy.base.warning.service.impl;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.zksy.base.warning.mapper.EarlyWarningMapper;
+import com.zksy.base.warning.service.IEarlyWarningDisposeEfficiencyService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.time.LocalDateTime;
+import java.util.List;
+import java.util.Map;
+
+@Service
+public class EarlyWarningDisposeEfficiencyServiceImpl implements IEarlyWarningDisposeEfficiencyService {
+
+    @Autowired
+    private EarlyWarningMapper earlyWarningMapper;
+
+    @Override
+    public Map<String, Object> getEfficiencyOverview(LocalDateTime startTime, LocalDateTime endTime, String warningSpecial) {
+        return earlyWarningMapper.selectDisposeEfficiencyOverview(startTime, endTime, warningSpecial);
+    }
+
+    @Override
+    public List<Map<String, Object>> getEfficiencyRange(LocalDateTime startTime, LocalDateTime endTime, String warningSpecial) {
+        return earlyWarningMapper.selectDisposeEfficiencyRange(startTime, endTime, warningSpecial);
+    }
+
+    @Override
+    public List<Map<String, Object>> getEfficiencyBySpecial(LocalDateTime startTime, LocalDateTime endTime) {
+        return earlyWarningMapper.selectDisposeEfficiencyBySpecial(startTime, endTime);
+    }
+
+    @Override
+    public IPage<Map<String, Object>> queryEfficiencyPage(Page<Map<String, Object>> page,
+                                                          LocalDateTime startTime,
+                                                          LocalDateTime endTime,
+                                                          String warningSpecial,
+                                                          String sortType) {
+        List<Map<String, Object>> list = earlyWarningMapper.selectDisposeEfficiencyList(startTime, endTime, warningSpecial, sortType);
+        page.setRecords(list);
+        page.setTotal(list.size());
+        return page;
+    }
+}

+ 24 - 0
pipe-network-service/zksy-system/src/main/java/com/zksy/base/warning/service/impl/EarlyWarningDisposeStatusServiceImpl.java

@@ -0,0 +1,24 @@
+package com.zksy.base.warning.service.impl;
+
+import com.zksy.base.warning.mapper.EarlyWarningMapper;
+import com.zksy.base.warning.service.IEarlyWarningDisposeStatusService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.time.LocalDateTime;
+import java.util.List;
+import java.util.Map;
+
+@Service
+public class EarlyWarningDisposeStatusServiceImpl implements IEarlyWarningDisposeStatusService {
+
+    @Autowired
+    private EarlyWarningMapper earlyWarningMapper;
+
+    @Override
+    public List<Map<String, Object>> getWarningStatusStat(LocalDateTime startTime,
+                                                          LocalDateTime endTime,
+                                                          String warningSpecial) {
+        return earlyWarningMapper.selectWarningGroupByStatus(startTime, endTime, warningSpecial);
+    }
+}

+ 57 - 0
pipe-network-service/zksy-system/src/main/java/com/zksy/base/warning/service/impl/EarlyWarningReceiveEfficiencyServiceImpl.java

@@ -0,0 +1,57 @@
+package com.zksy.base.warning.service.impl;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.zksy.base.warning.mapper.EarlyWarningMapper;
+import com.zksy.base.warning.service.IEarlyWarningReceiveEfficiencyService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.time.LocalDateTime;
+import java.util.List;
+import java.util.Map;
+
+@Service
+public class EarlyWarningReceiveEfficiencyServiceImpl implements IEarlyWarningReceiveEfficiencyService {
+
+    @Autowired
+    private EarlyWarningMapper earlyWarningMapper;
+
+    @Override
+    public Map<String, Object> getEfficiencyOverview(LocalDateTime startTime,
+                                                     LocalDateTime endTime,
+                                                     String warningType,
+                                                     String warningSpecial,
+                                                     String status) {
+        return earlyWarningMapper.selectReceiveEfficiencyOverview(startTime, endTime, warningType, warningSpecial, status);
+    }
+
+    @Override
+    public List<Map<String, Object>> getEfficiencyRange(LocalDateTime startTime,
+                                                        LocalDateTime endTime,
+                                                        String warningType,
+                                                        String warningSpecial,
+                                                        String status) {
+        return earlyWarningMapper.selectReceiveEfficiencyRange(startTime, endTime, warningType, warningSpecial, status);
+    }
+
+    @Override
+    public List<Map<String, Object>> getEfficiencyByType(LocalDateTime startTime, LocalDateTime endTime) {
+        return earlyWarningMapper.selectReceiveEfficiencyByType(startTime, endTime);
+    }
+
+    @Override
+    public IPage<Map<String, Object>> queryEfficiencyPage(Page<Map<String, Object>> page,
+                                                          LocalDateTime startTime,
+                                                          LocalDateTime endTime,
+                                                          String warningType,
+                                                          String warningSpecial,
+                                                          String status,
+                                                          String sortType) {
+        List<Map<String, Object>> list = earlyWarningMapper.selectReceiveEfficiencyList(
+                startTime, endTime, warningType, warningSpecial, status, sortType);
+        page.setRecords(list);
+        page.setTotal(list.size());
+        return page;
+    }
+}

+ 32 - 0
pipe-network-service/zksy-system/src/main/java/com/zksy/base/warning/service/impl/EarlyWarningTodayServiceImpl.java

@@ -0,0 +1,32 @@
+package com.zksy.base.warning.service.impl;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.zksy.base.warning.domain.EarlyWarning;
+import com.zksy.base.warning.mapper.EarlyWarningMapper;
+import com.zksy.base.warning.service.IEarlyWarningTodayService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+import java.util.Map;
+
+@Service
+public class EarlyWarningTodayServiceImpl implements IEarlyWarningTodayService {
+
+    @Autowired
+    private EarlyWarningMapper earlyWarningMapper;
+
+    @Override
+    public Map<String, Object> getTodayWarningStats() {
+        return earlyWarningMapper.selectTodayWarningStats();
+    }
+
+    @Override
+    public IPage<EarlyWarning> queryTodayWarningPage(Page<EarlyWarning> page, String status) {
+        List<EarlyWarning> list = earlyWarningMapper.selectTodayWarningList(status);
+        page.setRecords(list);
+        page.setTotal(list.size());
+        return page;
+    }
+}

+ 27 - 0
pipe-network-service/zksy-system/src/main/java/com/zksy/base/warning/service/impl/EarlyWarningTrendServiceImpl.java

@@ -0,0 +1,27 @@
+package com.zksy.base.warning.service.impl;
+
+import com.zksy.base.warning.mapper.EarlyWarningMapper;
+import com.zksy.base.warning.service.IEarlyWarningTrendService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.time.LocalDateTime;
+import java.util.List;
+import java.util.Map;
+
+@Service
+public class EarlyWarningTrendServiceImpl implements IEarlyWarningTrendService {
+
+    @Autowired
+    private EarlyWarningMapper earlyWarningMapper;
+
+    @Override
+    public List<Map<String, Object>> getTrendByDay(LocalDateTime startTime, LocalDateTime endTime, String warningSpecial) {
+        return earlyWarningMapper.selectWarningTrendByDay(startTime, endTime, warningSpecial);
+    }
+
+    @Override
+    public List<Map<String, Object>> getTrendByMonth(LocalDateTime startTime, LocalDateTime endTime, String warningSpecial) {
+        return earlyWarningMapper.selectWarningTrendByMonth(startTime, endTime, warningSpecial);
+    }
+}

+ 133 - 0
pipe-network-service/zksy-system/src/main/resources/mapper/WaterSupply/WaterPipeInfo/WaterPipeInfoMapper.xml

@@ -0,0 +1,133 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.zksy.WaterSupply.WaterPipeInfo.mapper.WaterPipeInfoMapper">
+
+    <resultMap id="BaseResultMap" type="com.zksy.WaterSupply.WaterPipeInfo.domain.WaterPipeInfo">
+        <id column="id" property="id"/>
+        <result column="pipe_code" property="pipeCode"/>
+        <result column="pipe_name" property="pipeName"/>
+        <result column="pipe_material" property="pipeMaterial"/>
+        <result column="pipe_diameter" property="pipeDiameter"/>
+        <result column="pipe_length" property="pipeLength"/>
+        <result column="start_point" property="startPoint"/>
+        <result column="end_point" property="endPoint"/>
+        <result column="laying_year" property="layingYear"/>
+        <result column="pressure_rating" property="pressureRating"/>
+        <result column="status" property="status"/>
+        <result column="remark" property="remark"/>
+        <result column="del_flag" property="delFlag"/>
+        <result column="create_by" property="createBy"/>
+        <result column="create_time" property="createTime"/>
+        <result column="update_by" property="updateBy"/>
+        <result column="update_time" property="updateTime"/>
+    </resultMap>
+
+    <sql id="Base_Column_List">
+        id, pipe_code, pipe_name, pipe_material, pipe_diameter, pipe_length,
+        start_point, end_point, laying_year, pressure_rating, status, remark,
+        del_flag, create_by, create_time, update_by, update_time
+    </sql>
+
+    <select id="selectPipeList" resultMap="BaseResultMap">
+        SELECT <include refid="Base_Column_List"/>
+        FROM water_pipe_info
+        WHERE del_flag = '0'
+        <if test="pipeCode != null and pipeCode != ''">
+            AND pipe_code LIKE CONCAT('%', #{pipeCode}, '%')
+        </if>
+        <if test="pipeName != null and pipeName != ''">
+            AND pipe_name LIKE CONCAT('%', #{pipeName}, '%')
+        </if>
+        <if test="pipeMaterial != null and pipeMaterial != ''">
+            AND pipe_material = #{pipeMaterial}
+        </if>
+        <if test="status != null and status != ''">
+            AND status = #{status}
+        </if>
+        <if test="startTime != null">
+            AND create_time &gt;= #{startTime}
+        </if>
+        <if test="endTime != null">
+            AND create_time &lt;= #{endTime}
+        </if>
+        ORDER BY create_time DESC
+    </select>
+
+    <select id="statPipeByStatus" resultType="java.util.Map">
+        SELECT
+        status,
+        COUNT(*) AS pipeCount
+        FROM water_pipe_info
+        WHERE del_flag = '0'
+        GROUP BY status
+    </select>
+
+    <select id="statPipeByMaterial" resultType="java.util.Map">
+        SELECT
+        pipe_material AS pipeMaterial,
+        COUNT(*) AS pipeCount,
+        SUM(pipe_length) AS totalLength
+        FROM water_pipe_info
+        WHERE del_flag = '0'
+        GROUP BY pipe_material
+    </select>
+
+    <select id="getLatestPipe" resultMap="BaseResultMap">
+        SELECT <include refid="Base_Column_List"/>
+        FROM water_pipe_info
+        WHERE del_flag = '0'
+        ORDER BY create_time DESC
+        LIMIT 1
+    </select>
+
+    <select id="getPipeOverallStatistics" resultType="java.util.Map">
+        SELECT
+        COUNT(*) AS totalPipeCount,
+        SUM(pipe_length) AS totalLength,
+        SUM(CASE WHEN status = '0' THEN 1 ELSE 0 END) AS runningCount,
+        SUM(CASE WHEN status = '1' THEN 1 ELSE 0 END) AS stopCount
+        FROM water_pipe_info
+        WHERE del_flag = '0'
+    </select>
+
+    <select id="selectDeletedList" resultMap="BaseResultMap">
+        SELECT <include refid="Base_Column_List"/>
+        FROM water_pipe_info
+        WHERE del_flag = '2'
+        <if test="pipeCode != null and pipeCode != ''">
+            AND pipe_code LIKE CONCAT('%', #{pipeCode}, '%')
+        </if>
+        <if test="pipeName != null and pipeName != ''">
+            AND pipe_name LIKE CONCAT('%', #{pipeName}, '%')
+        </if>
+        <if test="pipeMaterial != null and pipeMaterial != ''">
+            AND pipe_material = #{pipeMaterial}
+        </if>
+        <if test="startTime != null">
+            AND update_time &gt;= #{startTime}
+        </if>
+        <if test="endTime != null">
+            AND update_time &lt;= #{endTime}
+        </if>
+        ORDER BY update_time DESC
+    </select>
+
+    <delete id="deleteByIdsPhysically">
+        DELETE FROM water_pipe_info WHERE id IN
+        <foreach collection="ids" item="id" open="(" separator="," close=")">
+            #{id}
+        </foreach>
+    </delete>
+
+    <update id="restoreByIds">
+        UPDATE water_pipe_info
+        SET del_flag = '0',
+        update_by = #{updateBy},
+        update_time = NOW()
+        WHERE id IN
+        <foreach collection="ids" item="id" open="(" separator="," close=")">
+            #{id}
+        </foreach>
+    </update>
+
+</mapper>

+ 100 - 0
pipe-network-service/zksy-system/src/main/resources/mapper/WaterSupply/WaterPlantInfo/WaterPlantInfoMapper.xml

@@ -0,0 +1,100 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.zksy.WaterSupply.WaterPlantInfo.mapper.WaterPlantInfoMapper">
+
+    <resultMap id="BaseResultMap" type="com.zksy.WaterSupply.WaterPlantInfo.domain.WaterPlantInfo">
+        <id column="id" property="id" />
+        <result column="plant_code" property="plantCode" />
+        <result column="plant_name" property="plantName" />
+        <result column="location" property="location" />
+        <result column="water_source_type" property="waterSourceType" />
+        <result column="design_capacity" property="designCapacity" />
+        <result column="current_capacity" property="currentCapacity" />
+        <result column="treatment_process" property="treatmentProcess" />
+        <result column="commission_date" property="commissionDate" />
+        <result column="water_quality_standard" property="waterQualityStandard" />
+        <result column="status" property="status" />
+        <result column="principal" property="principal" />
+        <result column="contact_phone" property="contactPhone" />
+        <result column="remark" property="remark" />
+        <result column="del_flag" property="delFlag" />
+        <result column="create_by" property="createBy" />
+        <result column="create_time" property="createTime" />
+        <result column="update_by" property="updateBy" />
+        <result column="update_time" property="updateTime" />
+    </resultMap>
+
+    <sql id="Base_Column_List">
+        id, plant_code, plant_name, location, water_source_type, design_capacity,
+        current_capacity, treatment_process, commission_date, water_quality_standard,
+        status, principal, contact_phone, remark, del_flag, create_by, create_time,
+        update_by, update_time
+    </sql>
+
+    <!-- 条件查询水厂列表 -->
+    <select id="selectPlantList" resultMap="BaseResultMap">
+        SELECT <include refid="Base_Column_List"/>
+        FROM water_plant_info
+        WHERE del_flag = '0'
+        <if test="plantCode != null and plantCode != ''">
+            AND plant_code LIKE CONCAT('%', #{plantCode}, '%')
+        </if>
+        <if test="plantName != null and plantName != ''">
+            AND plant_name LIKE CONCAT('%', #{plantName}, '%')
+        </if>
+        <if test="status != null and status != ''">
+            AND status = #{status}
+        </if>
+        <if test="principal != null and principal != ''">
+            AND principal LIKE CONCAT('%', #{principal}, '%')
+        </if>
+        <if test="startTime != null">
+            AND create_time &gt;= #{startTime}
+        </if>
+        <if test="endTime != null">
+            AND create_time &lt;= #{endTime}
+        </if>
+        ORDER BY create_time DESC
+    </select>
+
+    <select id="selectDeletedList" resultMap="BaseResultMap">
+        SELECT <include refid="Base_Column_List"/>
+        FROM water_plant_info
+        WHERE del_flag = '2'
+        <if test="plantCode != null and plantCode != ''">
+            AND plant_code LIKE CONCAT('%', #{plantCode}, '%')
+        </if>
+        <if test="plantName != null and plantName != ''">
+            AND plant_name LIKE CONCAT('%', #{plantName}, '%')
+        </if>
+        <if test="status != null and status != ''">
+            AND status = #{status}
+        </if>
+        <if test="startTime != null">
+            AND update_time &gt;= #{startTime}
+        </if>
+        <if test="endTime != null">
+            AND update_time &lt;= #{endTime}
+        </if>
+        ORDER BY update_time DESC
+    </select>
+
+    <update id="restoreByIds">
+        UPDATE water_plant_info
+        SET del_flag = '0',
+        update_by = #{updateBy},
+        update_time = NOW()
+        WHERE id IN
+        <foreach collection="ids" item="id" open="(" separator="," close=")">
+            #{id}
+        </foreach>
+    </update>
+
+    <delete id="deleteByIdsPhysically">
+        DELETE FROM water_plant_info WHERE id IN
+        <foreach collection="ids" item="id" open="(" separator="," close=")">
+            #{id}
+        </foreach>
+    </delete>
+
+</mapper>

+ 99 - 0
pipe-network-service/zksy-system/src/main/resources/mapper/WaterSupply/WaterPumpStation/WaterPumpStationMapper.xml

@@ -0,0 +1,99 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.zksy.WaterSupply.WaterPumpStation.mapper.WaterPumpStationMapper">
+
+    <resultMap id="BaseResultMap" type="com.zksy.WaterSupply.WaterPumpStation.domain.WaterPumpStation">
+        <id column="id" property="id" />
+        <result column="station_code" property="stationCode" />
+        <result column="station_name" property="stationName" />
+        <result column="location" property="location" />
+        <result column="pump_count" property="pumpCount" />
+        <result column="design_flow" property="designFlow" />
+        <result column="design_head" property="designHead" />
+        <result column="power_capacity" property="powerCapacity" />
+        <result column="commission_date" property="commissionDate" />
+        <result column="status" property="status" />
+        <result column="principal" property="principal" />
+        <result column="contact_phone" property="contactPhone" />
+        <result column="remark" property="remark" />
+        <result column="del_flag" property="delFlag" />
+        <result column="create_by" property="createBy" />
+        <result column="create_time" property="createTime" />
+        <result column="update_by" property="updateBy" />
+        <result column="update_time" property="updateTime" />
+    </resultMap>
+
+    <sql id="Base_Column_List">
+        id, station_code, station_name, location, pump_count, design_flow, design_head,
+        power_capacity, commission_date, status, principal, contact_phone, remark,
+        del_flag, create_by, create_time, update_by, update_time
+    </sql>
+
+    <!-- 条件查询泵站列表 -->
+    <select id="selectStationList" resultMap="BaseResultMap">
+        SELECT <include refid="Base_Column_List"/>
+        FROM water_pump_station
+        WHERE del_flag = '0'
+        <if test="stationCode != null and stationCode != ''">
+            AND station_code LIKE CONCAT('%', #{stationCode}, '%')
+        </if>
+        <if test="stationName != null and stationName != ''">
+            AND station_name LIKE CONCAT('%', #{stationName}, '%')
+        </if>
+        <if test="status != null and status != ''">
+            AND status = #{status}
+        </if>
+        <if test="principal != null and principal != ''">
+            AND principal LIKE CONCAT('%', #{principal}, '%')
+        </if>
+        <if test="startTime != null">
+            AND create_time &gt;= #{startTime}
+        </if>
+        <if test="endTime != null">
+            AND create_time &lt;= #{endTime}
+        </if>
+        ORDER BY create_time DESC
+    </select>
+
+    <!-- 回收站SQL -->
+    <select id="selectDeletedList" resultMap="BaseResultMap">
+        SELECT <include refid="Base_Column_List"/>
+        FROM water_pump_station
+        WHERE del_flag = '2'
+        <if test="stationCode != null and stationCode != ''">
+            AND station_code LIKE CONCAT('%', #{stationCode}, '%')
+        </if>
+        <if test="stationName != null and stationName != ''">
+            AND station_name LIKE CONCAT('%', #{stationName}, '%')
+        </if>
+        <if test="status != null and status != ''">
+            AND status = #{status}
+        </if>
+        <if test="startTime != null">
+            AND update_time &gt;= #{startTime}
+        </if>
+        <if test="endTime != null">
+            AND update_time &lt;= #{endTime}
+        </if>
+        ORDER BY update_time DESC
+    </select>
+
+    <update id="restoreByIds">
+        UPDATE water_pump_station
+        SET del_flag = '0',
+        update_by = #{updateBy},
+        update_time = NOW()
+        WHERE id IN
+        <foreach collection="ids" item="id" open="(" separator="," close=")">
+            #{id}
+        </foreach>
+    </update>
+
+    <delete id="deleteByIdsPhysically">
+        DELETE FROM water_pump_station WHERE id IN
+        <foreach collection="ids" item="id" open="(" separator="," close=")">
+            #{id}
+        </foreach>
+    </delete>
+
+</mapper>

+ 98 - 0
pipe-network-service/zksy-system/src/main/resources/mapper/WaterSupply/WaterSourceInfo/WaterSourceInfoMapper.xml

@@ -0,0 +1,98 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.zksy.WaterSupply.WaterSourceInfo.mapper.WaterSourceInfoMapper">
+
+    <resultMap id="BaseResultMap" type="com.zksy.WaterSupply.WaterSourceInfo.domain.WaterSourceInfo">
+        <id column="id" property="id"/>
+        <result column="source_id" property="sourceId"/>
+        <result column="source_name" property="sourceName"/>
+        <result column="source_type" property="sourceType"/>
+        <result column="unit" property="unit"/>
+        <result column="address" property="address"/>
+        <result column="water_type" property="waterType"/>
+        <result column="protection_level" property="protectionLevel"/>
+        <result column="water_quality_level" property="waterQualityLevel"/>
+        <result column="protection_scope" property="protectionScope"/>
+        <result column="report_time" property="reportTime"/>
+        <result column="status" property="status"/>
+        <result column="remark" property="remark"/>
+        <result column="del_flag" property="delFlag"/>
+        <result column="create_by" property="createBy"/>
+        <result column="create_time" property="createTime"/>
+        <result column="update_by" property="updateBy"/>
+        <result column="update_time" property="updateTime"/>
+    </resultMap>
+
+    <sql id="Base_Column_List">
+        id, source_id, source_name, source_type, unit, address, water_type,
+        protection_level, water_quality_level, protection_scope, report_time,
+        status, remark, del_flag, create_by, create_time, update_by, update_time
+    </sql>
+
+    <select id="selectSourceList" resultMap="BaseResultMap">
+        SELECT <include refid="Base_Column_List"/>
+        FROM water_source_info
+        WHERE del_flag = '0'
+        <if test="sourceId != null and sourceId != ''">
+            AND source_id LIKE CONCAT('%', #{sourceId}, '%')
+        </if>
+        <if test="sourceName != null and sourceName != ''">
+            AND source_name LIKE CONCAT('%', #{sourceName}, '%')
+        </if>
+        <if test="status != null and status != ''">
+            AND status = #{status}
+        </if>
+        <if test="unit != null and unit != ''">
+            AND unit LIKE CONCAT('%', #{unit}, '%')
+        </if>
+        <if test="startTime != null">
+            AND create_time &gt;= #{startTime}
+        </if>
+        <if test="endTime != null">
+            AND create_time &lt;= #{endTime}
+        </if>
+        ORDER BY create_time DESC
+    </select>
+
+    <select id="selectDeletedList" resultMap="BaseResultMap">
+        SELECT <include refid="Base_Column_List"/>
+        FROM water_source_info
+        WHERE del_flag = '2'
+        <if test="sourceId != null and sourceId != ''">
+            AND source_id LIKE CONCAT('%', #{sourceId}, '%')
+        </if>
+        <if test="sourceName != null and sourceName != ''">
+            AND source_name LIKE CONCAT('%', #{sourceName}, '%')
+        </if>
+        <if test="status != null and status != ''">
+            AND status = #{status}
+        </if>
+        <if test="startTime != null">
+            AND update_time &gt;= #{startTime}
+        </if>
+        <if test="endTime != null">
+            AND update_time &lt;= #{endTime}
+        </if>
+        ORDER BY update_time DESC
+    </select>
+
+    <update id="restoreByIds">
+        UPDATE water_source_info
+        SET del_flag = '0',
+        update_by = #{updateBy},
+        update_time = NOW()
+        WHERE id IN
+        <foreach collection="ids" item="id" open="(" separator="," close=")">
+            #{id}
+        </foreach>
+    </update>
+
+    <delete id="deleteByIdsPhysically">
+        DELETE FROM water_source_info WHERE id IN
+        <foreach collection="ids" item="id" open="(" separator="," close=")">
+            #{id}
+        </foreach>
+    </delete>
+
+</mapper>

+ 98 - 0
pipe-network-service/zksy-system/src/main/resources/mapper/WaterSupply/WaterUserInfo/WaterUserInfoMapper.xml

@@ -0,0 +1,98 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.zksy.WaterSupply.WaterUserInfo.mapper.WaterUserInfoMapper">
+
+    <resultMap id="BaseResultMap" type="com.zksy.WaterSupply.WaterUserInfo.domain.WaterUserInfo">
+        <id column="id" property="id"/>
+        <result column="user_code" property="userCode"/>
+        <result column="user_name" property="userName"/>
+        <result column="user_type" property="userType"/>
+        <result column="address" property="address"/>
+        <result column="contact_person" property="contactPerson"/>
+        <result column="contact_phone" property="contactPhone"/>
+        <result column="meter_number" property="meterNumber"/>
+        <result column="initial_reading" property="initialReading"/>
+        <result column="current_reading" property="currentReading"/>
+        <result column="annual_water_consumption" property="annualWaterConsumption"/>
+        <result column="status" property="status"/>
+        <result column="remark" property="remark"/>
+        <result column="del_flag" property="delFlag"/>
+        <result column="create_by" property="createBy"/>
+        <result column="create_time" property="createTime"/>
+        <result column="update_by" property="updateBy"/>
+        <result column="update_time" property="updateTime"/>
+    </resultMap>
+
+    <sql id="Base_Column_List">
+        id, user_code, user_name, user_type, address, contact_person, contact_phone,
+        meter_number, initial_reading, current_reading, annual_water_consumption,
+        status, remark, del_flag, create_by, create_time, update_by, update_time
+    </sql>
+
+    <select id="selectUserList" resultMap="BaseResultMap">
+        SELECT <include refid="Base_Column_List"/>
+        FROM water_user_info
+        WHERE del_flag = '0'
+        <if test="userCode != null and userCode != ''">
+            AND user_code LIKE CONCAT('%', #{userCode}, '%')
+        </if>
+        <if test="userName != null and userName != ''">
+            AND user_name LIKE CONCAT('%', #{userName}, '%')
+        </if>
+        <if test="status != null and status != ''">
+            AND status = #{status}
+        </if>
+        <if test="userType != null and userType != ''">
+            AND user_type = #{userType}
+        </if>
+        <if test="startTime != null">
+            AND create_time &gt;= #{startTime}
+        </if>
+        <if test="endTime != null">
+            AND create_time &lt;= #{endTime}
+        </if>
+        ORDER BY create_time DESC
+    </select>
+
+    <select id="selectDeletedList" resultMap="BaseResultMap">
+        SELECT <include refid="Base_Column_List"/>
+        FROM water_user_info
+        WHERE del_flag = '2'
+        <if test="userCode != null and userCode != ''">
+            AND user_code LIKE CONCAT('%', #{userCode}, '%')
+        </if>
+        <if test="userName != null and userName != ''">
+            AND user_name LIKE CONCAT('%', #{userName}, '%')
+        </if>
+        <if test="status != null and status != ''">
+            AND status = #{status}
+        </if>
+        <if test="startTime != null">
+            AND update_time &gt;= #{startTime}
+        </if>
+        <if test="endTime != null">
+            AND update_time &lt;= #{endTime}
+        </if>
+        ORDER BY update_time DESC
+    </select>
+
+    <update id="restoreByIds">
+        UPDATE water_user_info
+        SET del_flag = '0',
+        update_by = #{updateBy},
+        update_time = NOW()
+        WHERE id IN
+        <foreach collection="ids" item="id" open="(" separator="," close=")">
+            #{id}
+        </foreach>
+    </update>
+
+    <delete id="deleteByIdsPhysically">
+        DELETE FROM water_user_info WHERE id IN
+        <foreach collection="ids" item="id" open="(" separator="," close=")">
+            #{id}
+        </foreach>
+    </delete>
+
+</mapper>

+ 392 - 0
pipe-network-service/zksy-system/src/main/resources/mapper/warning/EarlyWarningMapper.xml

@@ -2,6 +2,398 @@
 <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
 <mapper namespace="com.zksy.base.warning.mapper.EarlyWarningMapper">
 
+    <resultMap id="BaseResultMap" type="com.zksy.base.warning.domain.EarlyWarning">
+        <id column="warning_id" property="warningId"/>
+        <result column="warning_no" property="warningNo"/>
+        <result column="warning_name" property="warningName"/>
+        <result column="warning_type" property="warningType"/>
+        <result column="warning_level" property="warningLevel"/>
+        <result column="warning_special" property="warningSpecial"/>
+        <result column="location" property="location"/>
+        <result column="longitude" property="longitude"/>
+        <result column="latitude" property="latitude"/>
+        <result column="ownership_unit" property="ownershipUnit"/>
+        <result column="publisher" property="publisher"/>
+        <result column="publish_time" property="publishTime"/>
+        <result column="handler" property="handler"/>
+        <result column="status" property="status"/>
+        <result column="warning_content" property="warningContent"/>
+        <result column="process_instance_id" property="processInstanceId"/>
+        <result column="create_by" property="createBy"/>
+        <result column="create_time" property="createTime"/>
+        <result column="update_by" property="updateBy"/>
+        <result column="update_time" property="updateTime"/>
+        <result column="remark" property="remark"/>
+    </resultMap>
+
+    <sql id="Base_Column_List">
+        warning_id, warning_no, warning_name, warning_type, warning_level, warning_special,
+        location, longitude, latitude, ownership_unit, publisher, publish_time, handler,
+        status, warning_content, process_instance_id, create_by, create_time, update_by,
+        update_time, remark
+    </sql>
+
+    <!-- 统计今日预警核心指标 -->
+    <select id="selectTodayWarningStats" resultType="java.util.Map">
+        SELECT
+        COUNT(CASE WHEN status != 'DRAFT' THEN 1 END) AS today_total,
+        COUNT(CASE WHEN status = 'HANDLED' THEN 1 END) AS handled_today,
+        COUNT(CASE WHEN status = 'CLOSED' THEN 1 END) AS closed_today
+        FROM early_warning
+        WHERE publish_time &gt;= DATE_FORMAT(NOW(), '%Y-%m-%d 00:00:00')
+        AND publish_time &lt; DATE_ADD(DATE_FORMAT(NOW(), '%Y-%m-%d'), INTERVAL 1 DAY)
+    </select>
+
+    <!-- 查询今日预警列表 -->
+    <select id="selectTodayWarningList" resultMap="BaseResultMap">
+        SELECT <include refid="Base_Column_List"/>
+        FROM early_warning
+        WHERE publish_time &gt;= DATE_FORMAT(NOW(), '%Y-%m-%d 00:00:00')
+        AND publish_time &lt; DATE_ADD(DATE_FORMAT(NOW(), '%Y-%m-%d'), INTERVAL 1 DAY)
+        <choose>
+            <when test="status != null and status != ''">
+                AND status = #{status}
+            </when>
+            <otherwise>
+                AND status != 'DRAFT'
+            </otherwise>
+        </choose>
+        ORDER BY publish_time DESC
+    </select>
+
+    <!-- 按日统计预警发展趋势 -->
+    <select id="selectWarningTrendByDay" resultType="java.util.Map">
+        SELECT
+        DATE_FORMAT(publish_time, '%Y-%m-%d') AS stat_date,
+        IFNULL(warning_special, '其他') AS warning_special,
+        COUNT(*) AS warning_count
+        FROM early_warning
+        WHERE status != 'DRAFT'
+        <if test="startTime != null">
+            AND publish_time &gt;= #{startTime}
+        </if>
+        <if test="endTime != null">
+            AND publish_time &lt; #{endTime}
+        </if>
+        <if test="warningSpecial != null and warningSpecial != ''">
+            AND warning_special = #{warningSpecial}
+        </if>
+        GROUP BY stat_date, warning_special
+        ORDER BY stat_date ASC, warning_special ASC
+    </select>
+
+    <!-- 按月统计预警发展趋势 -->
+    <select id="selectWarningTrendByMonth" resultType="java.util.Map">
+        SELECT
+        DATE_FORMAT(publish_time, '%Y-%m') AS stat_month,
+        IFNULL(warning_special, '其他') AS warning_special,
+        COUNT(*) AS warning_count
+        FROM early_warning
+        WHERE status != 'DRAFT'
+        <if test="startTime != null">
+            AND publish_time &gt;= #{startTime}
+        </if>
+        <if test="endTime != null">
+            AND publish_time &lt; #{endTime}
+        </if>
+        <if test="warningSpecial != null and warningSpecial != ''">
+            AND warning_special = #{warningSpecial}
+        </if>
+        GROUP BY stat_month, warning_special
+        ORDER BY stat_month ASC, warning_special ASC
+    </select>
+
+    <!-- 处置状态分析:按预警状态分组统计数量 -->
+    <select id="selectWarningGroupByStatus" resultType="java.util.Map">
+        SELECT
+        status,
+        COUNT(warning_id) AS status_count
+        FROM early_warning
+        WHERE status != 'DRAFT'
+        <if test="startTime != null">
+            AND publish_time &gt;= #{startTime}
+        </if>
+        <if test="endTime != null">
+            AND publish_time &lt; #{endTime}
+        </if>
+        <if test="warningSpecial != null and warningSpecial != ''">
+            AND warning_special = #{warningSpecial}
+        </if>
+        GROUP BY status
+        ORDER BY status_count DESC
+    </select>
+
+    <!-- 处置时效分析-概览指标统计 -->
+    <select id="selectDisposeEfficiencyOverview" resultType="java.util.Map">
+        SELECT
+        ROUND(AVG(dispose_hours), 2) AS avg_hours,
+        ROUND(MAX(dispose_hours), 2) AS max_hours,
+        ROUND(MIN(dispose_hours), 2) AS min_hours,
+        COUNT(*) AS total_count
+        FROM (
+        SELECT
+        TIMESTAMPDIFF(SECOND, w.publish_time, MAX(d.create_time)) / 3600 AS dispose_hours
+        FROM early_warning w
+        LEFT JOIN warning_disposal d ON w.warning_id = d.warning_id
+        WHERE w.status IN ('HANDLED', 'CLOSED')
+        <if test="startTime != null">
+            AND w.publish_time &gt;= #{startTime}
+        </if>
+        <if test="endTime != null">
+            AND w.publish_time &lt; #{endTime}
+        </if>
+        <if test="warningSpecial != null and warningSpecial != ''">
+            AND w.warning_special = #{warningSpecial}
+        </if>
+        GROUP BY w.warning_id
+        HAVING dispose_hours IS NOT NULL
+        ) AS temp
+    </select>
+
+    <!-- 处置时效分析-时效区间分布统计 -->
+    <select id="selectDisposeEfficiencyRange" resultType="java.util.Map">
+        SELECT
+        CASE
+        WHEN dispose_hours &lt;= 2 THEN '0-2小时'
+        WHEN dispose_hours &lt;= 6 THEN '2-6小时'
+        WHEN dispose_hours &lt;= 24 THEN '6-24小时'
+        ELSE '24小时以上'
+        END AS time_range,
+        COUNT(*) AS warning_count
+        FROM (
+        SELECT
+        TIMESTAMPDIFF(SECOND, w.publish_time, MAX(d.create_time)) / 3600 AS dispose_hours
+        FROM early_warning w
+        LEFT JOIN warning_disposal d ON w.warning_id = d.warning_id
+        WHERE w.status IN ('HANDLED', 'CLOSED')
+        <if test="startTime != null">
+            AND w.publish_time &gt;= #{startTime}
+        </if>
+        <if test="endTime != null">
+            AND w.publish_time &lt; #{endTime}
+        </if>
+        <if test="warningSpecial != null and warningSpecial != ''">
+            AND w.warning_special = #{warningSpecial}
+        </if>
+        GROUP BY w.warning_id
+        HAVING dispose_hours IS NOT NULL
+        ) AS temp
+        GROUP BY time_range
+        ORDER BY
+        CASE time_range
+        WHEN '0-2小时' THEN 1
+        WHEN '2-6小时' THEN 2
+        WHEN '6-24小时' THEN 3
+        ELSE 4
+        END ASC
+    </select>
+
+    <!-- 处置时效分析-按预警专项统计平均时效 -->
+    <select id="selectDisposeEfficiencyBySpecial" resultType="java.util.Map">
+        SELECT
+        IFNULL(warning_special, '其他') AS warning_special,
+        COUNT(*) AS warning_count,
+        ROUND(AVG(dispose_hours), 2) AS avg_dispose_hours
+        FROM (
+        SELECT
+        w.warning_special,
+        TIMESTAMPDIFF(SECOND, w.publish_time, MAX(d.create_time)) / 3600 AS dispose_hours
+        FROM early_warning w
+        LEFT JOIN warning_disposal d ON w.warning_id = d.warning_id
+        WHERE w.status IN ('HANDLED', 'CLOSED')
+        <if test="startTime != null">
+            AND w.publish_time &gt;= #{startTime}
+        </if>
+        <if test="endTime != null">
+            AND w.publish_time &lt; #{endTime}
+        </if>
+        GROUP BY w.warning_id
+        HAVING dispose_hours IS NOT NULL
+        ) AS temp
+        GROUP BY warning_special
+        ORDER BY avg_dispose_hours DESC
+    </select>
+
+    <!-- 处置时效分析-明细列表 -->
+    <select id="selectDisposeEfficiencyList" resultType="java.util.Map">
+        SELECT
+        w.warning_id,
+        w.warning_no,
+        w.warning_name,
+        IFNULL(w.warning_special, '其他') AS warning_special,
+        w.publish_time,
+        MAX(d.create_time) AS dispose_time,
+        ROUND(TIMESTAMPDIFF(SECOND, w.publish_time, MAX(d.create_time)) / 3600, 2) AS dispose_hours,
+        w.status
+        FROM early_warning w
+        LEFT JOIN warning_disposal d ON w.warning_id = d.warning_id
+        WHERE w.status IN ('HANDLED', 'CLOSED')
+        <if test="startTime != null">
+            AND w.publish_time &gt;= #{startTime}
+        </if>
+        <if test="endTime != null">
+            AND w.publish_time &lt; #{endTime}
+        </if>
+        <if test="warningSpecial != null and warningSpecial != ''">
+            AND w.warning_special = #{warningSpecial}
+        </if>
+        GROUP BY w.warning_id
+        HAVING dispose_hours IS NOT NULL
+        ORDER BY dispose_hours
+        <if test="sortType != null and sortType == 'desc'">
+            DESC
+        </if>
+        <if test="sortType == null or sortType == 'asc'">
+            ASC
+        </if>
+    </select>
+
+    <!-- 接警效率分析-概览指标统计 -->
+    <select id="selectReceiveEfficiencyOverview" resultType="java.util.Map">
+        SELECT
+        ROUND(AVG(receive_hours), 2) AS avg_hours,
+        ROUND(MAX(receive_hours), 2) AS max_hours,
+        ROUND(MIN(receive_hours), 2) AS min_hours,
+        COUNT(*) AS total_count
+        FROM (
+        SELECT
+        TIMESTAMPDIFF(SECOND, w.publish_time, MIN(d.create_time)) / 3600 AS receive_hours
+        FROM early_warning w
+        INNER JOIN warning_disposal d ON w.warning_id = d.warning_id
+        WHERE w.status != 'DRAFT'
+        <if test="startTime != null">
+            AND w.publish_time &gt;= #{startTime}
+        </if>
+        <if test="endTime != null">
+            AND w.publish_time &lt; #{endTime}
+        </if>
+        <if test="warningType != null and warningType != ''">
+            AND w.warning_type = #{warningType}
+        </if>
+        <if test="warningSpecial != null and warningSpecial != ''">
+            AND w.warning_special = #{warningSpecial}
+        </if>
+        <if test="status != null and status != ''">
+            AND w.status = #{status}
+        </if>
+        GROUP BY w.warning_id
+        HAVING receive_hours IS NOT NULL
+        ) AS temp
+    </select>
+
+    <!-- 接警效率分析-时效区间分布统计 -->
+    <select id="selectReceiveEfficiencyRange" resultType="java.util.Map">
+        SELECT
+        CASE
+        WHEN receive_hours &lt;= 0.5 THEN '0-30分钟'
+        WHEN receive_hours &lt;= 2 THEN '30分钟-2小时'
+        WHEN receive_hours &lt;= 6 THEN '2-6小时'
+        ELSE '6小时以上'
+        END AS time_range,
+        COUNT(*) AS warning_count
+        FROM (
+        SELECT
+        TIMESTAMPDIFF(SECOND, w.publish_time, MIN(d.create_time)) / 3600 AS receive_hours
+        FROM early_warning w
+        INNER JOIN warning_disposal d ON w.warning_id = d.warning_id
+        WHERE w.status != 'DRAFT'
+        <if test="startTime != null">
+            AND w.publish_time &gt;= #{startTime}
+        </if>
+        <if test="endTime != null">
+            AND w.publish_time &lt; #{endTime}
+        </if>
+        <if test="warningType != null and warningType != ''">
+            AND w.warning_type = #{warningType}
+        </if>
+        <if test="warningSpecial != null and warningSpecial != ''">
+            AND w.warning_special = #{warningSpecial}
+        </if>
+        <if test="status != null and status != ''">
+            AND w.status = #{status}
+        </if>
+        GROUP BY w.warning_id
+        HAVING receive_hours IS NOT NULL
+        ) AS temp
+        GROUP BY time_range
+        ORDER BY
+        CASE time_range
+        WHEN '0-30分钟' THEN 1
+        WHEN '30分钟-2小时' THEN 2
+        WHEN '2-6小时' THEN 3
+        ELSE 4
+        END ASC
+    </select>
+
+    <!-- 接警效率分析-按预警类型统计平均时效 -->
+    <select id="selectReceiveEfficiencyByType" resultType="java.util.Map">
+        SELECT
+        IFNULL(warning_type, '其他') AS warning_type,
+        COUNT(*) AS warning_count,
+        ROUND(AVG(receive_hours), 2) AS avg_receive_hours
+        FROM (
+        SELECT
+        w.warning_type,
+        TIMESTAMPDIFF(SECOND, w.publish_time, MIN(d.create_time)) / 3600 AS receive_hours
+        FROM early_warning w
+        INNER JOIN warning_disposal d ON w.warning_id = d.warning_id
+        WHERE w.status != 'DRAFT'
+        <if test="startTime != null">
+            AND w.publish_time &gt;= #{startTime}
+        </if>
+        <if test="endTime != null">
+            AND w.publish_time &lt; #{endTime}
+        </if>
+        GROUP BY w.warning_id
+        HAVING receive_hours IS NOT NULL
+        ) AS temp
+        GROUP BY warning_type
+        ORDER BY avg_receive_hours DESC
+    </select>
+
+    <!-- 接警效率分析-明细列表 -->
+    <select id="selectReceiveEfficiencyList" resultType="java.util.Map">
+        SELECT
+        w.warning_id,
+        w.warning_no,
+        w.warning_name,
+        IFNULL(w.warning_type, '其他') AS warning_type,
+        IFNULL(w.warning_special, '其他') AS warning_special,
+        w.publish_time,
+        MIN(d.create_time) AS receive_time,
+        ROUND(TIMESTAMPDIFF(SECOND, w.publish_time, MIN(d.create_time)) / 3600, 2) AS receive_hours,
+        w.status
+        FROM early_warning w
+        INNER JOIN warning_disposal d ON w.warning_id = d.warning_id
+        WHERE w.status != 'DRAFT'
+        <if test="startTime != null">
+            AND w.publish_time &gt;= #{startTime}
+        </if>
+        <if test="endTime != null">
+            AND w.publish_time &lt; #{endTime}
+        </if>
+        <if test="warningType != null and warningType != ''">
+            AND w.warning_type = #{warningType}
+        </if>
+        <if test="warningSpecial != null and warningSpecial != ''">
+            AND w.warning_special = #{warningSpecial}
+        </if>
+        <if test="status != null and status != ''">
+            AND w.status = #{status}
+        </if>
+        GROUP BY w.warning_id
+        HAVING receive_hours IS NOT NULL
+        ORDER BY receive_hours
+        <if test="sortType != null and sortType == 'desc'">
+            DESC
+        </if>
+        <if test="sortType == null or sortType == 'asc'">
+            ASC
+        </if>
+    </select>
+
+    <!-- ————————————————————————————————————————————————————————————— -->
+
     <select id="selectWarningList" resultType="java.util.Map">
         SELECT w.*
         FROM early_warning w