Просмотр исходного кода

Merge remote-tracking branch 'origin/master'

Kazerin 1 месяц назад
Родитель
Сommit
fb99cf9422
70 измененных файлов с 4621 добавлено и 148 удалено
  1. 4 1
      .gitignore
  2. 38 0
      audio-service/.gitignore
  3. 38 0
      firefighting-pressure-service/.gitignore
  4. 38 0
      flammable-gas-service/.gitignore
  5. 54 0
      manhole-service/src/main/java/com/zksy/manhole/domain/BaseDevicesManhole.java
  6. 13 0
      pipe-network-service/pom.xml
  7. 71 0
      pipe-network-service/zksy-admin/src/main/java/com/zksy/web/controller/base/AlarmAssignDetailController.java
  8. 98 0
      pipe-network-service/zksy-admin/src/main/java/com/zksy/web/controller/base/AlarmAssignListController.java
  9. 60 22
      pipe-network-service/zksy-admin/src/main/java/com/zksy/web/controller/base/EquipmentBaseController.java
  10. 143 0
      pipe-network-service/zksy-admin/src/main/java/com/zksy/web/controller/manhole/ManholeDeviceController.java
  11. 364 0
      pipe-network-service/zksy-admin/src/main/java/com/zksy/web/controller/warning/EarlyWarningController.java
  12. 4 1
      pipe-network-service/zksy-common/pom.xml
  13. 49 0
      pipe-network-service/zksy-common/src/main/java/com/zksy/common/core/domain/AjaxResult2.java
  14. 4 0
      pipe-network-service/zksy-system/pom.xml
  15. 35 0
      pipe-network-service/zksy-system/src/main/java/com/zksy/base/alarm/domain/WarningThreshold.java
  16. 53 0
      pipe-network-service/zksy-system/src/main/java/com/zksy/base/domain/AlarmAssignDetail.java
  17. 81 0
      pipe-network-service/zksy-system/src/main/java/com/zksy/base/domain/AlarmAssignList.java
  18. 36 40
      pipe-network-service/zksy-system/src/main/java/com/zksy/base/domain/EquipmentBase.java
  19. 36 0
      pipe-network-service/zksy-system/src/main/java/com/zksy/base/domain/EquipmentPointRel.java
  20. 2 1
      pipe-network-service/zksy-system/src/main/java/com/zksy/base/domain/EquipmentStatus.java
  21. 49 0
      pipe-network-service/zksy-system/src/main/java/com/zksy/base/domain/EquipmentTest.java
  22. 73 0
      pipe-network-service/zksy-system/src/main/java/com/zksy/base/domain/MonitorPoint.java
  23. 85 0
      pipe-network-service/zksy-system/src/main/java/com/zksy/base/domain/PipeNetworkBase.java
  24. 39 0
      pipe-network-service/zksy-system/src/main/java/com/zksy/base/dto/AlarmAssignListPageInDTO.java
  25. 65 0
      pipe-network-service/zksy-system/src/main/java/com/zksy/base/mapper/AlarmAssignDetailMapper.java
  26. 65 0
      pipe-network-service/zksy-system/src/main/java/com/zksy/base/mapper/AlarmAssignListMapper.java
  27. 9 0
      pipe-network-service/zksy-system/src/main/java/com/zksy/base/mapper/EquipmentPointRelMapper.java
  28. 9 0
      pipe-network-service/zksy-system/src/main/java/com/zksy/base/mapper/EquipmentTestMapper.java
  29. 25 26
      pipe-network-service/zksy-system/src/main/java/com/zksy/base/service/EquipmentBaseService.java
  30. 8 0
      pipe-network-service/zksy-system/src/main/java/com/zksy/base/service/EquipmentStatusService.java
  31. 61 0
      pipe-network-service/zksy-system/src/main/java/com/zksy/base/service/IAlarmAssignDetailService.java
  32. 72 0
      pipe-network-service/zksy-system/src/main/java/com/zksy/base/service/IAlarmAssignListService.java
  33. 93 0
      pipe-network-service/zksy-system/src/main/java/com/zksy/base/service/impl/AlarmAssignDetailServiceImpl.java
  34. 131 0
      pipe-network-service/zksy-system/src/main/java/com/zksy/base/service/impl/AlarmAssignListServiceImpl.java
  35. 328 57
      pipe-network-service/zksy-system/src/main/java/com/zksy/base/service/impl/EquipmentBaseServiceImpl.java
  36. 26 0
      pipe-network-service/zksy-system/src/main/java/com/zksy/base/service/impl/EquipmentStatusServiceImpl.java
  37. 39 0
      pipe-network-service/zksy-system/src/main/java/com/zksy/base/warning/domain/AlarmWarningRel.java
  38. 110 0
      pipe-network-service/zksy-system/src/main/java/com/zksy/base/warning/domain/EarlyWarning.java
  39. 100 0
      pipe-network-service/zksy-system/src/main/java/com/zksy/base/warning/domain/WarningArchive.java
  40. 55 0
      pipe-network-service/zksy-system/src/main/java/com/zksy/base/warning/domain/WarningAttachment.java
  41. 67 0
      pipe-network-service/zksy-system/src/main/java/com/zksy/base/warning/domain/WarningDisposal.java
  42. 82 0
      pipe-network-service/zksy-system/src/main/java/com/zksy/base/warning/domain/WarningItem.java
  43. 70 0
      pipe-network-service/zksy-system/src/main/java/com/zksy/base/warning/domain/WarningReason.java
  44. 18 0
      pipe-network-service/zksy-system/src/main/java/com/zksy/base/warning/domain/WarningSaveDTO.java
  45. 60 0
      pipe-network-service/zksy-system/src/main/java/com/zksy/base/warning/domain/WarningTodo.java
  46. 15 0
      pipe-network-service/zksy-system/src/main/java/com/zksy/base/warning/mapper/AlarmWarningRelMapper.java
  47. 30 0
      pipe-network-service/zksy-system/src/main/java/com/zksy/base/warning/mapper/EarlyWarningMapper.java
  48. 9 0
      pipe-network-service/zksy-system/src/main/java/com/zksy/base/warning/mapper/WarningArchiveMapper.java
  49. 9 0
      pipe-network-service/zksy-system/src/main/java/com/zksy/base/warning/mapper/WarningAttachmentMapper.java
  50. 15 0
      pipe-network-service/zksy-system/src/main/java/com/zksy/base/warning/mapper/WarningDisposalMapper.java
  51. 9 0
      pipe-network-service/zksy-system/src/main/java/com/zksy/base/warning/mapper/WarningItemMapper.java
  52. 9 0
      pipe-network-service/zksy-system/src/main/java/com/zksy/base/warning/mapper/WarningReasonMapper.java
  53. 9 0
      pipe-network-service/zksy-system/src/main/java/com/zksy/base/warning/mapper/WarningTodoMapper.java
  54. 78 0
      pipe-network-service/zksy-system/src/main/java/com/zksy/base/warning/service/EarlyWarningService.java
  55. 768 0
      pipe-network-service/zksy-system/src/main/java/com/zksy/base/warning/service/impl/EarlyWarningServiceImpl.java
  56. 24 0
      pipe-network-service/zksy-system/src/main/java/com/zksy/manhole/dto/in/EquipmentStatusInDTO.java
  57. 30 0
      pipe-network-service/zksy-system/src/main/java/com/zksy/manhole/dto/in/ManholeDeviceListInDTO.java
  58. 42 0
      pipe-network-service/zksy-system/src/main/java/com/zksy/manhole/dto/in/ManholeDevicePageInDTO.java
  59. 32 0
      pipe-network-service/zksy-system/src/main/java/com/zksy/manhole/dto/out/EquipmentBaseOutDTO.java
  60. 33 0
      pipe-network-service/zksy-system/src/main/java/com/zksy/manhole/dto/out/EquipmentStatusOutDTO.java
  61. 36 0
      pipe-network-service/zksy-system/src/main/java/com/zksy/manhole/dto/out/ManholeDataOutDTO.java
  62. 30 0
      pipe-network-service/zksy-system/src/main/java/com/zksy/manhole/dto/out/WarningThresholdOutDTO.java
  63. 77 0
      pipe-network-service/zksy-system/src/main/resources/mapper/base/AlarmAssignDetailMapper.xml
  64. 101 0
      pipe-network-service/zksy-system/src/main/resources/mapper/base/AlarmAssignListMapper.xml
  65. 23 0
      pipe-network-service/zksy-system/src/main/resources/mapper/warning/AlarmWarningRelMapper.xml
  66. 146 0
      pipe-network-service/zksy-system/src/main/resources/mapper/warning/EarlyWarningMapper.xml
  67. 22 0
      pipe-network-service/zksy-system/src/main/resources/mapper/warning/WarningDisposalMapper.xml
  68. 38 0
      radar-service/.gitignore
  69. 38 0
      telemetry-service/.gitignore
  70. 38 0
      water-level-service/.gitignore

+ 4 - 1
.gitignore

@@ -36,4 +36,7 @@ build/
 .vscode/
 
 ### Mac OS ###
-.DS_Store
+.DS_Store
+
+logs/
+

+ 38 - 0
audio-service/.gitignore

@@ -0,0 +1,38 @@
+target/
+!.mvn/wrapper/maven-wrapper.jar
+!**/src/main/**/target/
+!**/src/test/**/target/
+
+### IntelliJ IDEA ###
+.idea/modules.xml
+.idea/jarRepositories.xml
+.idea/compiler.xml
+.idea/libraries/
+*.iws
+*.iml
+*.ipr
+
+### Eclipse ###
+.apt_generated
+.classpath
+.factorypath
+.project
+.settings
+.springBeans
+.sts4-cache
+
+### NetBeans ###
+/nbproject/private/
+/nbbuild/
+/dist/
+/nbdist/
+/.nb-gradle/
+build/
+!**/src/main/**/build/
+!**/src/test/**/build/
+
+### VS Code ###
+.vscode/
+
+### Mac OS ###
+.DS_Store

+ 38 - 0
firefighting-pressure-service/.gitignore

@@ -0,0 +1,38 @@
+target/
+!.mvn/wrapper/maven-wrapper.jar
+!**/src/main/**/target/
+!**/src/test/**/target/
+
+### IntelliJ IDEA ###
+.idea/modules.xml
+.idea/jarRepositories.xml
+.idea/compiler.xml
+.idea/libraries/
+*.iws
+*.iml
+*.ipr
+
+### Eclipse ###
+.apt_generated
+.classpath
+.factorypath
+.project
+.settings
+.springBeans
+.sts4-cache
+
+### NetBeans ###
+/nbproject/private/
+/nbbuild/
+/dist/
+/nbdist/
+/.nb-gradle/
+build/
+!**/src/main/**/build/
+!**/src/test/**/build/
+
+### VS Code ###
+.vscode/
+
+### Mac OS ###
+.DS_Store

+ 38 - 0
flammable-gas-service/.gitignore

@@ -0,0 +1,38 @@
+target/
+!.mvn/wrapper/maven-wrapper.jar
+!**/src/main/**/target/
+!**/src/test/**/target/
+
+### IntelliJ IDEA ###
+.idea/modules.xml
+.idea/jarRepositories.xml
+.idea/compiler.xml
+.idea/libraries/
+*.iws
+*.iml
+*.ipr
+
+### Eclipse ###
+.apt_generated
+.classpath
+.factorypath
+.project
+.settings
+.springBeans
+.sts4-cache
+
+### NetBeans ###
+/nbproject/private/
+/nbbuild/
+/dist/
+/nbdist/
+/.nb-gradle/
+build/
+!**/src/main/**/build/
+!**/src/test/**/build/
+
+### VS Code ###
+.vscode/
+
+### Mac OS ###
+.DS_Store

+ 54 - 0
manhole-service/src/main/java/com/zksy/manhole/domain/BaseDevicesManhole.java

@@ -1,5 +1,6 @@
 package com.zksy.manhole.domain;
 
+import cn.hutool.core.date.DateTime;
 import com.baomidou.mybatisplus.annotation.IdType;
 import com.baomidou.mybatisplus.annotation.TableId;
 import com.baomidou.mybatisplus.annotation.TableName;
@@ -10,6 +11,7 @@ import lombok.Data;
 import lombok.EqualsAndHashCode;
 
 import java.io.Serializable;
+import java.math.BigDecimal;
 import java.util.Date;
 
 /**
@@ -86,10 +88,62 @@ public class BaseDevicesManhole implements Serializable {
      */
     @ApiModelProperty(value = "预计使用年限")
     private Integer useLife;
+    /**
+     * 经度
+     */
+    @ApiModelProperty(value = "经度")
+    private BigDecimal longitude;
 
+    /**
+     * 纬度
+     */
+    @ApiModelProperty(value = "纬度")
+    private BigDecimal latitude;
+
+    /**
+     * 设备安装位置描述
+     */
+    @ApiModelProperty(value = "设备安装位置描述")
+    private String equipmentLocation;
+
+    /**
+     * 设备安装日期
+     */
+    @ApiModelProperty(value = "设备安装日期")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private DateTime installTime;
+
+    /**
+     * 设备维护人员
+     */
+    @ApiModelProperty(value = "设备维护人员")
+    private String maintainer;
+
+    /**
+     * 设备维护人员联系方式
+     */
+    @ApiModelProperty(value = "设备维护人员联系方式")
+    private String maintainerPhone;
+    /**
+     * 设备权属单位
+     */
+    @ApiModelProperty(value = "设备权属单位")
+    private String ownershipUnit;
     /**
      * 备注信息
      */
     @ApiModelProperty(value = "备注信息")
     private String remark;
+    /**
+     * 创建时间
+     */
+    @ApiModelProperty(value = "创建时间")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private DateTime createTime;
+    /**
+     * 更新时间
+     */
+    @ApiModelProperty(value = "更新时间")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private DateTime updateTime;
 }

+ 13 - 0
pipe-network-service/pom.xml

@@ -42,6 +42,8 @@
         <spring-security.version>5.7.12</spring-security.version>
         <spring-framework.version>5.3.39</spring-framework.version>
         <mybatis-plus.version>3.5.7</mybatis-plus.version>
+        <hutool.version>5.7.14</hutool.version>
+        <minioutil.version>1.0.1</minioutil.version>
     </properties>
 
     <!-- 依赖声明 -->
@@ -230,6 +232,17 @@
                 <artifactId>mybatis-plus-boot-starter</artifactId>
                 <version>${mybatis-plus.version}</version>
             </dependency>
+            <!-- hutool工具包-->
+            <dependency>
+                <groupId>cn.hutool</groupId>
+                <artifactId>hutool-all</artifactId>
+                <version>${hutool.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>com.zksy</groupId>
+                <artifactId>minioutil</artifactId>
+                <version>${minioutil.version}</version>
+            </dependency>
         </dependencies>
     </dependencyManagement>
 

+ 71 - 0
pipe-network-service/zksy-admin/src/main/java/com/zksy/web/controller/base/AlarmAssignDetailController.java

@@ -0,0 +1,71 @@
+package com.zksy.web.controller.base;
+
+import com.zksy.base.domain.AlarmAssignDetail;
+import com.zksy.base.service.IAlarmAssignDetailService;
+import com.zksy.common.annotation.Anonymous;
+import com.zksy.common.core.controller.BaseController;
+import com.zksy.common.core.domain.AjaxResult;
+import com.zksy.common.core.domain.AjaxResult2;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+/**
+ * 报警清单处理明细Controller
+ * 
+ * @author zksy
+ * @date 2026-05-06
+ */
+@RestController
+@RequestMapping("/alarmAssignDetail")
+@Api(tags = "报警清单处理明细")
+public class AlarmAssignDetailController extends BaseController
+{
+    @Autowired
+    private IAlarmAssignDetailService alarmAssignDetailService;
+
+    /**
+     * 获取报警清单处理明细详细信息
+     */
+    @Anonymous
+    @GetMapping(value = "/getById/{id}")
+    @ApiOperation(value = "获取报警清单处理明细详细信息")
+    public AjaxResult2<AlarmAssignDetail> getById(@PathVariable("id") Long id)
+    {
+        return AjaxResult2.success(alarmAssignDetailService.selectAlarmAssignDetailByAlarmAssignDetailId(id));
+    }
+
+    /**
+     * 新增报警清单处理明细
+     */
+    @Anonymous
+    @PostMapping(value = "/save")
+    @ApiOperation(value = "新增报警清单处理明细")
+    public AjaxResult save(@RequestBody AlarmAssignDetail alarmAssignDetail)
+    {
+        return toAjax(alarmAssignDetailService.insertAlarmAssignDetail(alarmAssignDetail));
+    }
+
+    /**
+     * 修改报警清单处理明细
+     */
+    @Anonymous
+    @PostMapping(value = "/update")
+    @ApiOperation(value = "修改报警清单处理明细")
+    public AjaxResult update(@RequestBody AlarmAssignDetail alarmAssignDetail)
+    {
+        return toAjax(alarmAssignDetailService.updateAlarmAssignDetail(alarmAssignDetail));
+    }
+
+    /**
+     * 批量删除报警清单处理明细
+     */
+    @Anonymous
+    @PostMapping(value = "/deleteBatch")
+    @ApiOperation(value = "批量删除报警清单处理明细")
+    public AjaxResult deleteBatch(@RequestBody Long[] ids)
+    {
+        return toAjax(alarmAssignDetailService.deleteAlarmAssignDetailByAlarmAssignDetailIds(ids));
+    }
+}

+ 98 - 0
pipe-network-service/zksy-admin/src/main/java/com/zksy/web/controller/base/AlarmAssignListController.java

@@ -0,0 +1,98 @@
+package com.zksy.web.controller.base;
+
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.zksy.base.domain.AlarmAssignList;
+import com.zksy.base.dto.AlarmAssignListPageInDTO;
+import com.zksy.base.service.IAlarmAssignListService;
+import com.zksy.common.annotation.Anonymous;
+import com.zksy.common.core.controller.BaseController;
+import com.zksy.common.core.domain.AjaxResult;
+import com.zksy.common.core.domain.AjaxResult2;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+/**
+ * 报警清单Controller
+ * 
+ * @author zksy
+ * @date 2026-05-06
+ */
+@RestController
+@RequestMapping("/alarmAssignList")
+@Api(tags = "报警清单")
+public class AlarmAssignListController extends BaseController
+{
+    @Autowired
+    private IAlarmAssignListService alarmAssignListService;
+
+    /**
+     * 分页查询报警清单列表
+     */
+    @Anonymous
+    @GetMapping(value = "/findByPage")
+    @ApiOperation(value = "分页查询报警清单列表")
+    public AjaxResult2<Page<AlarmAssignList>> findByPage(@RequestBody AlarmAssignListPageInDTO pageInDTO)
+    {
+        return AjaxResult2.success(alarmAssignListService.findByPage(pageInDTO));
+    }
+
+    /**
+     * 导出报警清单列表
+     */
+    /*@Anonymous
+    @PostMapping("/export")
+    @ApiOperation(value = "导出报警清单列表")
+    public void export(HttpServletResponse response, AlarmAssignList alarmAssignList)
+    {
+        List<AlarmAssignList> list = alarmAssignListService.selectAlarmAssignListList(alarmAssignList);
+        ExcelUtil<AlarmAssignList> util = new ExcelUtil<AlarmAssignList>(AlarmAssignList.class);
+        util.exportExcel(response, list, "报警清单数据");
+    }*/
+
+    /**
+     * 获取报警清单详细信息
+     */
+    @Anonymous
+    @GetMapping(value = "/getById/{id}")
+    @ApiOperation(value = "获取报警清单详细信息")
+    public AjaxResult2<AlarmAssignList> getById(@PathVariable("id") Long id)
+    {
+        return AjaxResult2.success(alarmAssignListService.selectAlarmAssignListByAlarmAssignId(id));
+    }
+
+    /**
+     * 新增报警清单
+     */
+    @Anonymous
+    @PostMapping(value = "/save")
+    @ApiOperation(value = "新增报警清单")
+    public AjaxResult save(@RequestBody AlarmAssignList alarmAssignList)
+    {
+        return toAjax(alarmAssignListService.insertAlarmAssignList(alarmAssignList));
+    }
+
+    /**
+     * 修改报警清单
+     */
+    @Anonymous
+    @PostMapping(value = "/update")
+    @ApiOperation(value = "修改报警清单")
+    public AjaxResult update(@RequestBody AlarmAssignList alarmAssignList)
+    {
+        return toAjax(alarmAssignListService.updateAlarmAssignList(alarmAssignList));
+    }
+
+    /**
+     * 批量删除报警清单
+     */
+    @Anonymous
+    @PostMapping(value = "/deleteBatch")
+    @ApiOperation(value = "批量删除报警清单")
+    public AjaxResult deleteBatch(@RequestBody Long[] ids)
+    {
+        return toAjax(alarmAssignListService.deleteAlarmAssignListByAlarmAssignIds(ids));
+    }
+}

+ 60 - 22
pipe-network-service/zksy-admin/src/main/java/com/zksy/web/controller/base/EquipmentBaseController.java

@@ -11,15 +11,14 @@ import com.zksy.common.core.domain.AjaxResult;
 import com.zksy.common.enums.BusinessType;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.*;
 
 import java.util.List;
+import java.util.Map;
 
-/**
- * 设备基础信息
- */
 @Slf4j
 @RestController
 @RequestMapping("/EquipmentBase")
@@ -34,22 +33,21 @@ public class EquipmentBaseController {
     @Anonymous
     public AjaxResult getById(@PathVariable String id) {
         EquipmentBase equipmentBase = service.getById(id);
-        if(equipmentBase==null){
+        if (equipmentBase == null) {
             return AjaxResult.error("该设备信息不存在");
         }
         return AjaxResult.success(equipmentBase);
     }
 
-    //TODO 待优化
     @Anonymous
     @GetMapping("/findByPage")
     @ApiOperation(value = "设备基础信息分页")
     public Page findByPage(long pageNum, long pageSize,
-                           @RequestParam(required = false)String equipmentCode,
-                           @RequestParam(required = false)String equipmentName,
-                           @RequestParam(required = false)String equipmentModel,
-                           @RequestParam(required = false)String manufacturer) throws Exception {
-        return service.findByPage(pageNum, pageSize, equipmentCode,equipmentName,equipmentModel,manufacturer);
+                           @RequestParam(required = false) String equipmentCode,
+                           @RequestParam(required = false) String equipmentName,
+                           @RequestParam(required = false) String equipmentModel,
+                           @RequestParam(required = false) String manufacturer) throws Exception {
+        return service.findByPage(pageNum, pageSize, equipmentCode, equipmentName, equipmentModel, manufacturer);
     }
 
     @Anonymous
@@ -64,22 +62,20 @@ public class EquipmentBaseController {
     @Log(title = "新增设备基础信息", businessType = BusinessType.INSERT)
     public AjaxResult save(@RequestBody EquipmentBase entity) {
         boolean saved = service.saveWithCheck(entity);
-        return saved ? AjaxResult.success("新增成功",saved)
-                : AjaxResult.error("新增失败",saved);
+        return saved ? AjaxResult.success("新增成功", saved)
+                : AjaxResult.error("新增失败", saved);
     }
 
     @PostMapping("/saveBatch")
     @ApiOperation(value = "设备基础信息批量新增")
     @Log(title = "批量新增设备基础信息", businessType = BusinessType.INSERT)
     public AjaxResult saveBatch(@RequestBody List<EquipmentBase> entityList) {
-        // 基础校验:列表不能为空
         if (CollectionUtils.isEmpty(entityList)) {
             return AjaxResult.error("批量新增失败:设备列表不能为空");
         }
-
         boolean saved = service.saveBatchWithCheck(entityList);
-        return saved ? AjaxResult.success("新增成功",saved)
-                : AjaxResult.error("新增失败",saved);
+        return saved ? AjaxResult.success("新增成功", saved)
+                : AjaxResult.error("新增失败", saved);
     }
 
     @PutMapping("/updateById")
@@ -87,8 +83,8 @@ public class EquipmentBaseController {
     @Log(title = "修改设备基础信息", businessType = BusinessType.UPDATE)
     public AjaxResult updateById(@RequestBody EquipmentBase entity) {
         boolean updated = service.updateWithCheck(entity);
-        return updated ? AjaxResult.success("修改成功",updated)
-                : AjaxResult.error("修改失败",updated);
+        return updated ? AjaxResult.success("修改成功", updated)
+                : AjaxResult.error("修改失败", updated);
     }
 
     @DeleteMapping("/deleteById")
@@ -96,8 +92,8 @@ public class EquipmentBaseController {
     @Log(title = "删除设备基础信息", businessType = BusinessType.DELETE)
     public AjaxResult deleteById(String id) {
         boolean deleted = service.removeWithCheck(id);
-        return deleted ? AjaxResult.success("删除成功",deleted)
-                : AjaxResult.error("删除失败",deleted);
+        return deleted ? AjaxResult.success("删除成功", deleted)
+                : AjaxResult.error("删除失败", deleted);
     }
 
     @DeleteMapping("/deleteBatchById")
@@ -105,7 +101,49 @@ public class EquipmentBaseController {
     @Log(title = "设备基础信息批量删除", businessType = BusinessType.DELETE)
     public AjaxResult deleteBatchById(@RequestParam List<String> ids) {
         boolean deleted = service.removeBatchWithCheck(ids);
-        return deleted ? AjaxResult.success("删除成功",deleted)
-                : AjaxResult.error("删除失败",deleted);
+        return deleted ? AjaxResult.success("删除成功", deleted)
+                : AjaxResult.error("删除失败", deleted);
+    }
+
+    @PutMapping("/updateStatus")
+    @ApiOperation(value = "设备状态维护(启用/禁用/维修等)")
+    @Log(title = "设备状态维护", businessType = BusinessType.UPDATE)
+    @Anonymous
+    public AjaxResult updateEquipmentStatus(
+            @ApiParam("设备ID") @RequestParam String equipmentId,
+            @ApiParam("状态值") @RequestParam Integer currentStatus) {
+        boolean updated = service.updateEquipmentStatus(equipmentId, currentStatus);
+        return updated ? AjaxResult.success("状态更新成功")
+                : AjaxResult.error("状态更新失败");
+    }
+
+    @PostMapping("/test")
+    @ApiOperation(value = "设备测试验证")
+    @Log(title = "设备测试验证", businessType = BusinessType.OTHER)
+    @Anonymous
+    public AjaxResult testEquipment(
+            @ApiParam("设备ID") @RequestParam String equipmentId,
+            @ApiParam("测试类型") @RequestParam(required = false) String testType,
+            @ApiParam("测试详情") @RequestParam(required = false) String testDetail,
+            @ApiParam("测试人") @RequestParam(required = false) String testUser) {
+        boolean tested = service.testEquipment(equipmentId, testType, testDetail, testUser);
+        return tested ? AjaxResult.success("测试成功")
+                : AjaxResult.error("测试失败");
+    }
+
+    @GetMapping("/detail/{equipmentId}")
+    @ApiOperation(value = "设备详情(含关联信息)")
+    @Anonymous
+    public AjaxResult getEquipmentDetail(@PathVariable String equipmentId) {
+        Map<String, Object> detail = service.getEquipmentDetail(equipmentId);
+        return AjaxResult.success(detail);
+    }
+
+    @GetMapping("/byPoint/{pointId}")
+    @ApiOperation(value = "根据监测点查询设备")
+    @Anonymous
+    public AjaxResult getEquipmentByPoint(@PathVariable String pointId) {
+        List<EquipmentBase> list = service.getEquipmentByPoint(pointId);
+        return AjaxResult.success(list);
     }
 }

+ 143 - 0
pipe-network-service/zksy-admin/src/main/java/com/zksy/web/controller/manhole/ManholeDeviceController.java

@@ -0,0 +1,143 @@
+package com.zksy.web.controller.manhole;
+
+
+import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.collection.CollUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.zksy.base.alarm.domain.WarningThreshold;
+import com.zksy.base.alarm.service.WarningThresholdService;
+import com.zksy.base.domain.EquipmentBase;
+import com.zksy.base.domain.EquipmentStatus;
+import com.zksy.base.domain.EquipmentType;
+import com.zksy.base.manhole.domain.ManholeData;
+import com.zksy.base.manhole.service.ManholeDataService;
+import com.zksy.base.service.EquipmentBaseService;
+import com.zksy.base.service.EquipmentStatusService;
+import com.zksy.base.service.EquipmentTypeService;
+import com.zksy.common.annotation.Anonymous;
+import com.zksy.common.core.controller.BaseController;
+import com.zksy.common.core.domain.AjaxResult;
+import com.zksy.common.core.domain.AjaxResult2;
+import com.zksy.manhole.dto.in.EquipmentStatusInDTO;
+import com.zksy.manhole.dto.in.ManholeDeviceListInDTO;
+import com.zksy.manhole.dto.in.ManholeDevicePageInDTO;
+import com.zksy.manhole.dto.out.EquipmentBaseOutDTO;
+import com.zksy.manhole.dto.out.EquipmentStatusOutDTO;
+import com.zksy.manhole.dto.out.ManholeDataOutDTO;
+import com.zksy.manhole.dto.out.WarningThresholdOutDTO;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+/**
+ * 窨井盖监测系统-监测设备信息管理Controller
+ * 
+ * @author xianggx
+ * @date 2026-05-06
+ */
+@RestController
+@RequestMapping("/manhole/device")
+@Api(tags = "窨井盖监测系统-监测设备信息管理")
+public class ManholeDeviceController extends BaseController
+{
+    @Autowired
+    private EquipmentBaseService equipmentBaseService;
+
+    @Autowired
+    private EquipmentStatusService equipmentStatusService;
+
+    @Autowired
+    private EquipmentTypeService equipmentTypeService;
+
+    @Autowired
+    private ManholeDataService manholeDataService;
+
+    @Autowired
+    private WarningThresholdService warningThresholdService;
+
+    /**
+     * 分页查询监测设备台账列表
+     */
+    @Anonymous
+    @GetMapping(value = "/findByPage")
+    @ApiOperation(value = "分页查询监测设备台账列表")
+    public AjaxResult2<Page<EquipmentBaseOutDTO>> findByPage(@RequestBody ManholeDevicePageInDTO pageInDTO)
+    {
+        return AjaxResult2.success(equipmentBaseService.findManholeDeviceByPage(pageInDTO));
+    }
+
+    /**
+     * 查询井盖监测设备列表
+     */
+    @Anonymous
+    @GetMapping(value = "/getManholeDataList")
+    @ApiOperation(value = "查询井盖监测设备列表")
+    public AjaxResult2<List<EquipmentBaseOutDTO>> getManholeDataList(@RequestBody ManholeDeviceListInDTO listInDTO)
+    {
+        return AjaxResult2.success(equipmentBaseService.getManholeDataList(listInDTO));
+    }
+
+    /**
+     * 获取监测设备台账详情
+     */
+    @Anonymous
+    @GetMapping(value = "/getById/{id}")
+    @ApiOperation(value = "获取监测设备台账详情")
+    public AjaxResult2<EquipmentBaseOutDTO> getById(@PathVariable("id") Long id)
+    {
+        EquipmentBase equipmentBase = equipmentBaseService.getById(id);
+        if(equipmentBase == null){
+            return AjaxResult2.error("设备ID不存在");
+        }
+        EquipmentBaseOutDTO outDTO = BeanUtil.copyProperties(equipmentBase, EquipmentBaseOutDTO.class);
+        // 查询设备状态
+        EquipmentStatus equipmentStatus = equipmentStatusService.lambdaQuery()
+                .eq(EquipmentStatus::getEquipmentId, outDTO.getEquipmentId())
+                .one();
+        if(equipmentStatus != null){
+            EquipmentStatusOutDTO equipmentStatusOutDTO = BeanUtil.copyProperties(equipmentStatus, EquipmentStatusOutDTO.class);
+            outDTO.setEquipmentStatus(equipmentStatusOutDTO);
+        }
+        // 查询设备类别名称
+        EquipmentType equipmentType = equipmentTypeService.getById(outDTO.getEquipmentTypeId());
+        if(equipmentType != null){
+            outDTO.setEquipmentTypeName(equipmentType.getTypeName());
+        }
+        // 查询设备监测状态
+        List<ManholeData> manholeDataList = manholeDataService.list(new LambdaQueryWrapper<ManholeData>()
+                .eq(ManholeData::getImeiCardNumber, outDTO.getEquipmentCode())
+                .orderByDesc(ManholeData::getCreateTime));
+        if(CollUtil.isNotEmpty(manholeDataList)){
+            ManholeData manholeData = manholeDataList.get(0);
+            ManholeDataOutDTO manholeDataOutDTO = BeanUtil.copyProperties(manholeData, ManholeDataOutDTO.class);
+            outDTO.setManholeData(manholeDataOutDTO);
+        }
+        // 查询设备预警阈值
+        List<WarningThreshold> warningThresholdList = warningThresholdService.list(new LambdaQueryWrapper<WarningThreshold>()
+                .eq(WarningThreshold::getDeviceCode, outDTO.getEquipmentCode())
+                .orderByDesc(WarningThreshold::getCreateTime));
+        if(CollUtil.isNotEmpty(warningThresholdList)){
+            List<WarningThresholdOutDTO> warningThresholdOutDTOList = BeanUtil.copyToList(warningThresholdList, WarningThresholdOutDTO.class);
+            outDTO.setWarningThresholdList(warningThresholdOutDTOList);
+        }
+        return AjaxResult2.success(outDTO);
+    }
+
+    /**
+     * 修改设备状态
+     * @param inDTO
+     * @return
+     */
+    @Anonymous
+    @PostMapping("/updateDeviceStatus")
+    @ApiOperation(value = "修改设备状态")
+    public AjaxResult updateDeviceStatus(@RequestBody EquipmentStatusInDTO inDTO) {
+        boolean updated = equipmentStatusService.updateDeviceStatus(inDTO);
+        return updated ? AjaxResult.success("修改成功",updated)
+                : AjaxResult.error("修改失败",updated);
+    }
+}

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

@@ -0,0 +1,364 @@
+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.domain.WarningArchive;
+import com.zksy.base.warning.domain.WarningDisposal;
+import com.zksy.base.warning.domain.WarningSaveDTO;
+import com.zksy.base.warning.service.EarlyWarningService;
+import com.zksy.common.annotation.Anonymous;
+import com.zksy.common.annotation.Log;
+import com.zksy.common.core.domain.AjaxResult;
+import com.zksy.common.enums.BusinessType;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.format.annotation.DateTimeFormat;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.time.LocalDateTime;
+import java.util.List;
+import java.util.Map;
+
+@Slf4j
+@RestController
+@RequestMapping("/warning")
+@Api(tags = "预警管理")
+public class EarlyWarningController {
+
+    @Autowired
+    private EarlyWarningService earlyWarningService;
+
+    @GetMapping("/list")
+    @ApiOperation("分页查询预警列表")
+    @Anonymous
+    public AjaxResult getWarningList(
+            @ApiParam("页码") @RequestParam(defaultValue = "1") Integer pageNum,
+            @ApiParam("每页数量") @RequestParam(defaultValue = "10") Integer pageSize,
+            @ApiParam("预警名称") @RequestParam(required = false) String warningName,
+            @ApiParam("预警类型") @RequestParam(required = false) String warningType,
+            @ApiParam("预警级别") @RequestParam(required = false) String warningLevel,
+            @ApiParam("状态") @RequestParam(required = false) String status) {
+        Page<?> page = new Page<>(pageNum, pageSize);
+        IPage<Map<String, Object>> result = earlyWarningService.getWarningList(page, warningName, warningType, warningLevel, status);
+        return AjaxResult.success(result);
+    }
+
+    @GetMapping("/todo/list")
+    @ApiOperation("待办预警列表")
+    @Anonymous
+    public AjaxResult getTodoList(
+            @ApiParam("页码") @RequestParam(defaultValue = "1") Integer pageNum,
+            @ApiParam("每页数量") @RequestParam(defaultValue = "10") Integer pageSize,
+            @ApiParam("用户ID") @RequestParam String userId,
+            @ApiParam("待办类型") @RequestParam(required = false) String todoType,
+            @ApiParam("预警名称") @RequestParam(required = false) String warningName) {
+        Page<?> page = new Page<>(pageNum, pageSize);
+        IPage<Map<String, Object>> result = earlyWarningService.getTodoList(page, userId, todoType, warningName);
+        return AjaxResult.success(result);
+    }
+
+    @GetMapping("/detail/{warningId}")
+    @ApiOperation("预警详情")
+    @Anonymous
+    public AjaxResult getWarningDetail(@PathVariable String warningId) {
+        Map<String, Object> detail = earlyWarningService.getWarningDetail(warningId);
+        if (detail == null) {
+            return AjaxResult.error("预警信息不存在");
+        }
+        return AjaxResult.success(detail);
+    }
+
+    @PostMapping("/save")
+    @ApiOperation("保存预警信息")
+    @Log(title = "保存预警信息", businessType = BusinessType.INSERT)
+    public AjaxResult saveWarning(WarningSaveDTO entity) {
+        boolean result = earlyWarningService.saveWarning(entity.getWarning(), entity.getAlarmIds(), entity.getFiles());
+        return result ? AjaxResult.success("保存成功", entity.getWarning().getWarningId()) : AjaxResult.error("保存失败");
+    }
+
+    @PutMapping("/update")
+    @ApiOperation("修改预警信息")
+    @Log(title = "修改预警信息", businessType = BusinessType.UPDATE)
+    public AjaxResult updateWarning(EarlyWarning warning, List<MultipartFile> files) {
+        boolean result = earlyWarningService.updateWarning(warning, files);
+        return result ? AjaxResult.success("修改成功") : AjaxResult.error("修改失败");
+    }
+
+    @DeleteMapping("/delete")
+    @ApiOperation("删除预警信息")
+    @Log(title = "删除预警信息", businessType = BusinessType.DELETE)
+    public AjaxResult deleteWarning(@RequestParam String warningId) {
+        boolean result = earlyWarningService.deleteWarning(warningId);
+        return result ? AjaxResult.success("删除成功") : AjaxResult.error("删除失败");
+    }
+
+    @DeleteMapping("/delete/batch")
+    @ApiOperation("批量删除预警信息")
+    @Log(title = "批量删除预警信息", businessType = BusinessType.DELETE)
+    public AjaxResult deleteBatchWarning(@RequestParam List<String> warningIds) {
+        boolean result = earlyWarningService.deleteBatchWarning(warningIds);
+        return result ? AjaxResult.success("批量删除成功") : AjaxResult.error("批量删除失败");
+    }
+
+    @PostMapping("/publish/{warningId}")
+    @ApiOperation("发布预警")
+    @Log(title = "发布预警", businessType = BusinessType.UPDATE)
+    public AjaxResult publishWarning(
+            @PathVariable String warningId,
+            @ApiParam("处置人") @RequestParam(required = false, defaultValue = "system") String disposalUser) {
+        boolean result = earlyWarningService.publishWarning(warningId, disposalUser);
+        return result ? AjaxResult.success("发布成功") : AjaxResult.error("发布失败");
+    }
+
+    @PostMapping("/upgrade")
+    @ApiOperation("预警升级")
+    @Log(title = "预警升级", businessType = BusinessType.UPDATE)
+    public AjaxResult upgradeWarning(
+            @ApiParam("预警ID") @RequestParam String warningId,
+            @ApiParam("新预警级别") @RequestParam String newLevel,
+            @ApiParam("处置人") @RequestParam(required = false, defaultValue = "system") String disposalUser,
+            @ApiParam("处置说明") @RequestParam String disposalContent) {
+        boolean result = earlyWarningService.upgradeWarning(warningId, newLevel, disposalUser, disposalContent);
+        return result ? AjaxResult.success("升级成功") : AjaxResult.error("升级失败");
+    }
+
+    @PostMapping("/resolve")
+    @ApiOperation("解除预警")
+    @Log(title = "解除预警", businessType = BusinessType.UPDATE)
+    public AjaxResult resolveWarning(
+            @ApiParam("预警ID") @RequestParam String warningId,
+            @ApiParam("处置人") @RequestParam(required = false, defaultValue = "system") String disposalUser,
+            @ApiParam("处置说明") @RequestParam String disposalContent) {
+        boolean result = earlyWarningService.resolveWarning(warningId, disposalUser, disposalContent);
+        return result ? AjaxResult.success("解除成功") : AjaxResult.error("解除失败");
+    }
+
+    @PostMapping("/return")
+    @ApiOperation("退回重办")
+    @Log(title = "退回重办", businessType = BusinessType.UPDATE)
+    public AjaxResult returnWarning(
+            @ApiParam("预警ID") @RequestParam String warningId,
+            @ApiParam("处置人") @RequestParam(required = false, defaultValue = "system") String disposalUser,
+            @ApiParam("退回说明") @RequestParam String disposalContent) {
+        boolean result = earlyWarningService.returnWarning(warningId, disposalUser, disposalContent);
+        return result ? AjaxResult.success("退回成功") : AjaxResult.error("退回失败");
+    }
+
+    @PostMapping("/supervision")
+    @ApiOperation("预警督办")
+    @Log(title = "预警督办", businessType = BusinessType.OTHER)
+    public AjaxResult supervisionWarning(
+            @ApiParam("预警ID") @RequestParam String warningId,
+            @ApiParam("督办人员") @RequestParam String supervisionUser,
+            @ApiParam("督办意见") @RequestParam String supervisionContent,
+            @ApiParam("通知方式") @RequestParam String notificationType,
+            @ApiParam("通知内容") @RequestParam(required = false) String notificationContent,
+            @ApiParam("附件地址") @RequestParam(required = false) String attachmentUrl) {
+        boolean result = earlyWarningService.supervisionWarning(warningId, supervisionUser, supervisionContent, notificationType, notificationContent, attachmentUrl);
+        return result ? AjaxResult.success("督办成功") : AjaxResult.error("督办失败");
+    }
+
+    @PostMapping("/instruction")
+    @ApiOperation("领导批示")
+    @Log(title = "领导批示", businessType = BusinessType.OTHER)
+    public AjaxResult addLeaderInstruction(
+            @ApiParam("预警ID") @RequestParam String warningId,
+            @ApiParam("领导姓名") @RequestParam String leaderName,
+            @ApiParam("批示内容") @RequestParam String instructionContent,
+            @ApiParam("短信接收人") @RequestParam(required = false) String smsReceivers) {
+        boolean result = earlyWarningService.addLeaderInstruction(warningId, leaderName, instructionContent, smsReceivers);
+        return result ? AjaxResult.success("批示成功") : AjaxResult.error("批示失败");
+    }
+
+    @PostMapping("/link/alarms")
+    @ApiOperation("关联报警信息")
+    public AjaxResult linkAlarms(
+            @ApiParam("预警ID") @RequestParam String warningId,
+            @ApiParam("报警ID列表") @RequestParam List<String> alarmIds) {
+        boolean result = earlyWarningService.linkAlarms(warningId, alarmIds);
+        return result ? AjaxResult.success("关联成功") : AjaxResult.error("关联失败");
+    }
+
+    @GetMapping("/link/alarms/{warningId}")
+    @ApiOperation("获取关联的报警列表")
+    public AjaxResult getLinkedAlarms(@PathVariable String warningId) {
+        List<Map<String, Object>> result = earlyWarningService.getLinkedAlarms(warningId);
+        return AjaxResult.success(result);
+    }
+
+    @GetMapping("/disposal/{warningId}")
+    @ApiOperation("获取处置记录列表")
+    public AjaxResult getDisposalList(@PathVariable String warningId) {
+        List<Map<String, Object>> result = earlyWarningService.getDisposalList(warningId);
+        return AjaxResult.success(result);
+    }
+
+    @GetMapping("/statistics")
+    @ApiOperation("获取统计数据")
+    @Anonymous
+    public AjaxResult getStatistics() {
+        Map<String, Object> result = earlyWarningService.getStatistics();
+        return AjaxResult.success(result);
+    }
+
+    /*@GetMapping("/config/types")
+    @ApiOperation("获取预警类型配置")
+    public AjaxResult getTypeConfigList() {
+        List<Map<String, Object>> result = earlyWarningService.getTypeConfigList();
+        return AjaxResult.success(result);
+    }*/
+
+    @GetMapping("/search")
+    @ApiOperation("综合搜索预警信息")
+    @Anonymous
+    public AjaxResult searchWarnings(
+            @ApiParam("页码") @RequestParam(defaultValue = "1") Integer pageNum,
+            @ApiParam("每页数量") @RequestParam(defaultValue = "10") Integer pageSize,
+            @ApiParam("预警名称") @RequestParam(required = false) String warningName,
+            @ApiParam("预警编号") @RequestParam(required = false) String warningNo,
+            @ApiParam("预警类型") @RequestParam(required = false) String warningType,
+            @ApiParam("预警级别") @RequestParam(required = false) String warningLevel,
+            @ApiParam("状态") @RequestParam(required = false) String status,
+            @ApiParam("预警位置") @RequestParam(required = false) String location,
+            @ApiParam("发布人") @RequestParam(required = false) String publisher,
+            @ApiParam("权属单位") @RequestParam(required = false) String ownershipUnit,
+            @ApiParam("开始时间") @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime startTime,
+            @ApiParam("结束时间") @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime endTime) {
+        Page<?> page = new Page<>(pageNum, pageSize);
+        IPage<Map<String, Object>> result = earlyWarningService.searchWarnings(page, warningName, warningNo, warningType, warningLevel, status, location, publisher, ownershipUnit, startTime, endTime);
+        return AjaxResult.success(result);
+    }
+
+    @GetMapping("/detail/full/{warningId}")
+    @ApiOperation("获取预警完整详情(含GIS定位和电子存档)")
+    @Anonymous
+    public AjaxResult getWarningFullDetail(@PathVariable String warningId) {
+        Map<String, Object> detail = earlyWarningService.getWarningFullDetail(warningId);
+        if (detail == null) {
+            return AjaxResult.error("预警信息不存在");
+        }
+        return AjaxResult.success(detail);
+    }
+
+    @GetMapping("/processing/list")
+    @ApiOperation("获取处置过程跟踪 - 进行中的预警")
+    @Anonymous
+    public AjaxResult getProcessingWarnings(
+            @ApiParam("页码") @RequestParam(defaultValue = "1") Integer pageNum,
+            @ApiParam("每页数量") @RequestParam(defaultValue = "10") Integer pageSize,
+            @ApiParam("预警类型") @RequestParam(required = false) String warningType,
+            @ApiParam("预警级别") @RequestParam(required = false) String warningLevel) {
+        Page<?> page = new Page<>(pageNum, pageSize);
+        IPage<Map<String, Object>> result = earlyWarningService.getProcessingWarnings(page, warningType, warningLevel);
+        return AjaxResult.success(result);
+    }
+
+    @GetMapping("/completed/list")
+    @ApiOperation("获取处置过程跟踪 - 已完成的预警")
+    @Anonymous
+    public AjaxResult getCompletedWarnings(
+            @ApiParam("页码") @RequestParam(defaultValue = "1") Integer pageNum,
+            @ApiParam("每页数量") @RequestParam(defaultValue = "10") Integer pageSize,
+            @ApiParam("预警类型") @RequestParam(required = false) String warningType,
+            @ApiParam("预警级别") @RequestParam(required = false) String warningLevel,
+            @ApiParam("开始时间") @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime startTime,
+            @ApiParam("结束时间") @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime endTime) {
+        Page<?> page = new Page<>(pageNum, pageSize);
+        IPage<Map<String, Object>> result = earlyWarningService.getCompletedWarnings(page, warningType, warningLevel, startTime, endTime);
+        return AjaxResult.success(result);
+    }
+
+    @GetMapping("/disposal/history/{warningId}")
+    @ApiOperation("获取预警处置历史记录")
+    @Anonymous
+    public AjaxResult getDisposalHistory(@PathVariable String warningId) {
+        List<Map<String, Object>> result = earlyWarningService.getDisposalHistory(warningId);
+        return AjaxResult.success(result);
+    }
+
+    @GetMapping("/attachments/{warningId}")
+    @ApiOperation("获取预警附件列表")
+    @Anonymous
+    public AjaxResult getAttachments(@PathVariable String warningId) {
+        List<Map<String, Object>> result = earlyWarningService.getAttachments(warningId);
+        return AjaxResult.success(result);
+    }
+
+    @GetMapping("/dashboard/statistics")
+    @ApiOperation("获取仪表盘统计数据")
+    @Anonymous
+    public AjaxResult getDashboardStatistics() {
+        Map<String, Object> result = earlyWarningService.getDashboardStatistics();
+        return AjaxResult.success(result);
+    }
+
+    @GetMapping("/archive/{warningId}")
+    @ApiOperation("获取预警归档信息")
+    @Anonymous
+    public AjaxResult getArchive(@PathVariable String warningId) {
+        WarningArchive archive = earlyWarningService.getArchiveByWarningId(warningId);
+        if (archive == null) {
+            return AjaxResult.error("归档信息不存在");
+        }
+        return AjaxResult.success(archive);
+    }
+
+    @GetMapping("/archive/list")
+    @ApiOperation("获取归档列表")
+    @Anonymous
+    public AjaxResult getArchiveList(
+            @ApiParam("页码") @RequestParam(defaultValue = "1") Integer pageNum,
+            @ApiParam("每页数量") @RequestParam(defaultValue = "10") Integer pageSize,
+            @ApiParam("预警名称") @RequestParam(required = false) String warningName,
+            @ApiParam("预警类型") @RequestParam(required = false) String warningType,
+            @ApiParam("预警级别") @RequestParam(required = false) String warningLevel,
+            @ApiParam("开始时间") @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime startTime,
+            @ApiParam("结束时间") @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime endTime) {
+        Page<WarningArchive> page = new Page<>(pageNum, pageSize);
+        IPage<WarningArchive> result = earlyWarningService.getArchiveList(page, warningName, warningType, warningLevel, startTime, endTime);
+        return AjaxResult.success(result);
+    }
+
+    @GetMapping("/process/{warningId}")
+    @ApiOperation("获取预警处置过程记录(完整流程)")
+    @Anonymous
+    public AjaxResult getDisposalProcess(@PathVariable String warningId) {
+        List<WarningDisposal> result = earlyWarningService.getDisposalProcess(warningId);
+        return AjaxResult.success(result);
+    }
+
+    @GetMapping("/diagram/{warningId}")
+    @ApiOperation("获取预警流程可视化数据(路线图)")
+    @Anonymous
+    public AjaxResult getProcessDiagram(@PathVariable String warningId) {
+        Map<String, Object> result = earlyWarningService.getProcessDiagram(warningId);
+        if (result != null && result.containsKey("error")) {
+            return AjaxResult.error(result.get("error").toString());
+        }
+        return AjaxResult.success(result);
+    }
+
+    @GetMapping("/disposal/detail/{disposalId}")
+    @ApiOperation("获取预警处置详情")
+    @Anonymous
+    public AjaxResult getDisposalDetail(@PathVariable String disposalId) {
+        Map<String, Object> result = earlyWarningService.getDisposalDetail(disposalId);
+        if (result == null) {
+            return AjaxResult.error("处置记录不存在");
+        }
+        return AjaxResult.success(result);
+    }
+
+    @GetMapping("/process/statistics/{warningId}")
+    @ApiOperation("获取预警流程统计信息")
+    @Anonymous
+    public AjaxResult getProcessStatistics(@PathVariable String warningId) {
+        Map<String, Object> result = earlyWarningService.getProcessStatistics(warningId);
+        return AjaxResult.success(result);
+    }
+}

+ 4 - 1
pipe-network-service/zksy-common/pom.xml

@@ -124,7 +124,10 @@
             <artifactId>knife4j-openapi2-spring-boot-starter</artifactId>
             <version>4.1.0</version>
         </dependency>
-
+        <dependency>
+            <groupId>com.zksy</groupId>
+            <artifactId>minioutil</artifactId>
+        </dependency>
     </dependencies>
 
 </project>

+ 49 - 0
pipe-network-service/zksy-common/src/main/java/com/zksy/common/core/domain/AjaxResult2.java

@@ -0,0 +1,49 @@
+package com.zksy.common.core.domain;
+
+import com.zksy.common.constant.HttpStatus;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+/**
+ * 操作消息提醒2
+ *
+ * @author xianggx
+ */
+@Data
+public class AjaxResult2<T> {
+
+    @ApiModelProperty(value = "状态码", required = true)
+    private int code;
+
+    @ApiModelProperty(value = "返回内容", required = true)
+    private String msg;
+
+    @ApiModelProperty(value = "返回数据对象", required = false)
+    private T data;
+
+    /**
+     * 返回错误消息
+     *
+     * @param msg 返回内容
+     * @return 错误消息
+     */
+    public static <T> AjaxResult2<T> error(String msg) {
+        AjaxResult2<T> apiResult = new AjaxResult2();
+        apiResult.setCode(HttpStatus.ERROR);
+        apiResult.setMsg(msg);
+        return apiResult;
+    }
+
+    /**
+     * 返回成功数据
+     *
+     * @return 成功消息
+     */
+    public static <T> AjaxResult2<T> success(T data) {
+        AjaxResult2<T> apiResult = new AjaxResult2();
+        apiResult.setCode(HttpStatus.SUCCESS);
+        apiResult.setMsg("操作成功");
+        apiResult.setData(data);
+        return apiResult;
+    }
+}

+ 4 - 0
pipe-network-service/zksy-system/pom.xml

@@ -35,6 +35,10 @@
             <groupId>com.github.xiaoymin</groupId>
             <artifactId>knife4j-openapi2-spring-boot-starter</artifactId>
         </dependency>
+        <dependency>
+            <groupId>cn.hutool</groupId>
+            <artifactId>hutool-all</artifactId>
+        </dependency>
     </dependencies>
     <build>
         <plugins>

+ 35 - 0
pipe-network-service/zksy-system/src/main/java/com/zksy/base/alarm/domain/WarningThreshold.java

@@ -73,6 +73,41 @@ public class WarningThreshold implements Serializable {
     @ApiModelProperty(value = "备注")
     private String remark;
 
+    /**
+     * 关联设备ID
+     */
+    @TableField(value = "equipment_id")
+    @ApiModelProperty(value = "关联设备ID")
+    private String equipmentId;
+
+    /**
+     * 关联监测点ID
+     */
+    @TableField(value = "point_id")
+    @ApiModelProperty(value = "关联监测点ID")
+    private String pointId;
+
+    /**
+     * 监测类型
+     */
+    @TableField(value = "monitor_type")
+    @ApiModelProperty(value = "监测类型(水位、流量、压力、温度等)")
+    private String monitorType;
+
+    /**
+     * 预警级别
+     */
+    @TableField(value = "warning_level")
+    @ApiModelProperty(value = "预警级别(1-蓝色 2-黄色 3-橙色 4-红色)")
+    private String warningLevel;
+
+    /**
+     * 比较运算符
+     */
+    @TableField(value = "operator")
+    @ApiModelProperty(value = "比较运算符(>、<、>=、<=、=、!=)")
+    private String operator;
+
     /**
      * 创建时间
      */

+ 53 - 0
pipe-network-service/zksy-system/src/main/java/com/zksy/base/domain/AlarmAssignDetail.java

@@ -0,0 +1,53 @@
+package com.zksy.base.domain;
+
+import com.zksy.common.annotation.Excel;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * 报警清单处理明细对象 alarm_assign_detail
+ * 
+ * @author zksy
+ * @date 2026-05-06
+ */
+@Data
+@ApiModel(value = "报警清单处理明细入参", description = "报警清单处理明细入参")
+public class AlarmAssignDetail implements Serializable
+{
+    private static final long serialVersionUID = 1L;
+
+    /** 报警清单明细ID */
+    @ApiModelProperty(value = "报警清单明细ID", required = true)
+    private Long alarmAssignDetailId;
+
+    /** 报警清单ID */
+    @ApiModelProperty(value = "报警清单ID", required = true)
+    private Long alarmAssignId;
+
+    /** 处理人ID */
+    @Excel(name = "处理人ID")
+    @ApiModelProperty(value = "处理人ID", required = true)
+    private Long handleUserId;
+
+    /** 处理人姓名 */
+    @Excel(name = "处理人姓名")
+    @ApiModelProperty(value = "处理人姓名", required = true)
+    private String handleUserName;
+
+    /** 处理人手机号 */
+    @Excel(name = "处理人手机号")
+    @ApiModelProperty(value = "处理人手机号", required = true)
+    private String handlePhone;
+
+    /** 处理人部门名称 */
+    @Excel(name = "处理人部门名称")
+    @ApiModelProperty(value = "处理人部门名称", required = false)
+    private String handleDeptName;
+
+    /** 备注 */
+    @ApiModelProperty(value = "备注", required = false)
+    private String remark;
+}

+ 81 - 0
pipe-network-service/zksy-system/src/main/java/com/zksy/base/domain/AlarmAssignList.java

@@ -0,0 +1,81 @@
+package com.zksy.base.domain;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.zksy.common.annotation.Excel;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * 报警清单对象 alarm_assign_list
+ * 
+ * @author zksy
+ * @date 2026-05-06
+ */
+@Data
+@ApiModel(value = "报警清单入参", description = "报警清单入参")
+public class AlarmAssignList implements Serializable
+{
+    private static final long serialVersionUID = 1L;
+
+    /** 报警清单ID */
+    @Excel(name = "报警清单ID")
+    @ApiModelProperty(value = "报警清单ID", required = true)
+    private Long alarmAssignId;
+
+    /** 设备编码 */
+    @Excel(name = "设备编码")
+    @ApiModelProperty(value = "设备编码", required = true)
+    private String deviceCode;
+
+    /** 设备名称 */
+    @Excel(name = "设备名称")
+    @ApiModelProperty(value = "设备名称", required = true)
+    private String deviceName;
+
+    /** 设备厂商 */
+    @Excel(name = "设备厂商")
+    @ApiModelProperty(value = "设备厂商", required = false)
+    private String manufacturer;
+
+    /** 设备报警状态:(0-正常,1-报警) */
+    @Excel(name = "设备报警状态:(0-正常,1-报警)")
+    @ApiModelProperty(value = "设备报警状态:(0-正常,1-报警)", required = true)
+    private Integer alarmStatus;
+
+    /** 隐患类型 */
+    @Excel(name = "隐患类型")
+    @ApiModelProperty(value = "隐患类型", required = true)
+    private String hiddenDangerType;
+
+    /** 隐患描述 */
+    @ApiModelProperty(value = "隐患描述", required = true)
+    private String hiddenDangerRemark;
+
+    /** 报警时间 */
+    @Excel(name = "报警时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
+    @ApiModelProperty(value = "报警时间", required = true)
+    @JsonFormat(locale = "zh",pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
+    private Date alarmTime;
+
+    /** 处理状态:0-未处理 1-已处理 */
+    @Excel(name = "处理状态:0-未处理 1-已处理")
+    @ApiModelProperty(value = "处理状态:0-未处理 1-已处理", required = true)
+    private Integer assignStatus;
+
+    /** 派发时间 */
+    @ApiModelProperty(value = "派发时间", required = false)
+    @JsonFormat(locale = "zh",pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
+    private Date assignTime;
+
+    /** 派发人 */
+    @ApiModelProperty(value = "派发人", required = false)
+    private Long assignUserId;
+
+    /** 派发备注 */
+    @ApiModelProperty(value = "派发备注", required = false)
+    private String assignRemark;
+}

+ 36 - 40
pipe-network-service/zksy-system/src/main/java/com/zksy/base/domain/EquipmentBase.java

@@ -1,15 +1,16 @@
 package com.zksy.base.domain;
 
 import com.baomidou.mybatisplus.annotation.IdType;
-import com.baomidou.mybatisplus.annotation.TableField;
 import com.baomidou.mybatisplus.annotation.TableId;
 import com.baomidou.mybatisplus.annotation.TableName;
 import com.fasterxml.jackson.annotation.JsonFormat;
+import io.swagger.annotations.ApiModelProperty;
 import lombok.AllArgsConstructor;
 import lombok.Data;
 import lombok.NoArgsConstructor;
 
 import java.math.BigDecimal;
+import java.time.LocalDateTime;
 import java.util.Date;
 
 /**
@@ -22,69 +23,64 @@ import java.util.Date;
 public class EquipmentBase {
 
     @TableId(value = "equipment_id", type = IdType.ASSIGN_UUID)
-    /**
-     * 设备唯一ID(主键)
-     */
+    @ApiModelProperty("设备唯一ID(主键)")
     private String equipmentId;
 
-    /**
-     * 设备编码(唯一标识)
-     */
+    @ApiModelProperty("设备编码(唯一标识)")
     private String equipmentCode;
 
-    /**
-     * 设备名称
-     */
+    @ApiModelProperty("设备名称")
     private String equipmentName;
 
-    /**
-     * 设备型号
-     */
+    @ApiModelProperty("设备型号")
     private String equipmentModel;
 
-    /**
-     * 设备规格参数
-     */
+    @ApiModelProperty("设备规格参数")
     private String equipmentSpec;
 
-    /**
-     * 设备制造商
-     */
+    @ApiModelProperty("设备制造商")
     private String manufacturer;
 
-    /**
-     * 设备生产日期
-     */
+    @ApiModelProperty("设备生产日期")
     @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
     private Date productionDate;
 
-    /**
-     * 设备类别ID(关联equipment_type表)
-     */
+    @ApiModelProperty("设备类别ID(关联equipment_type表)")
     private String equipmentTypeId;
 
-    /**
-     * 设备资产价值(元)
-     */
+    @ApiModelProperty("设备资产价值(元)")
     private Double assetValue;
 
-    /**
-     * 预计使用年限(年)
-     */
+    @ApiModelProperty("预计使用年限(年)")
     private Integer useLife;
 
-    /**
-     * 设备经度
-     */
+    @ApiModelProperty("设备经度")
     private BigDecimal longitude;
 
-    /**
-     * 设备纬度
-     */
+    @ApiModelProperty("设备纬度")
     private BigDecimal latitude;
 
-    /**
-     * 备注信息
-     */
+    @ApiModelProperty("设备位置描述")
+    private String equipmentLocation;
+
+    @ApiModelProperty("安装时间")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private LocalDateTime installTime;
+
+    @ApiModelProperty("设备维护人员")
+    private String maintainer;
+
+    @ApiModelProperty("联系方式")
+    private String maintainerPhone;
+
+    @ApiModelProperty("备注信息")
     private String remark;
+
+    @ApiModelProperty("创建时间")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private LocalDateTime createTime;
+
+    @ApiModelProperty("更新时间")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private LocalDateTime updateTime;
 }

+ 36 - 0
pipe-network-service/zksy-system/src/main/java/com/zksy/base/domain/EquipmentPointRel.java

@@ -0,0 +1,36 @@
+package com.zksy.base.domain;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.time.LocalDateTime;
+
+/**
+ * 设备-监控点关联表
+ */
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+@TableName("equipment_point_rel")
+public class EquipmentPointRel {
+
+    @TableId(value = "rel_id", type = IdType.ASSIGN_UUID)
+    @ApiModelProperty("关联ID")
+    private String relId;
+
+    @ApiModelProperty("设备ID")
+    private String equipmentId;
+
+    @ApiModelProperty("监测点ID")
+    private String pointId;
+
+    @ApiModelProperty("创建时间")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private LocalDateTime createTime;
+}

+ 2 - 1
pipe-network-service/zksy-system/src/main/java/com/zksy/base/domain/EquipmentStatus.java

@@ -66,10 +66,11 @@ public class EquipmentStatus {
      * 下次预计维护日期
      */
     @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
-    private Date nextMaintainDate;
+    private LocalDateTime nextMaintainDate;
 
     /**
      * 状态更新时间
      */
+    @JsonFormat(locale = "zh",pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
     private LocalDateTime statusUpdateTime;
 }

+ 49 - 0
pipe-network-service/zksy-system/src/main/java/com/zksy/base/domain/EquipmentTest.java

@@ -0,0 +1,49 @@
+package com.zksy.base.domain;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.time.LocalDateTime;
+
+/**
+ * 设备测试记录表
+ */
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+@TableName("equipment_test")
+public class EquipmentTest {
+
+    @TableId(value = "test_id", type = IdType.ASSIGN_UUID)
+    @ApiModelProperty("测试记录ID")
+    private String testId;
+
+    @ApiModelProperty("设备ID")
+    private String equipmentId;
+
+    @ApiModelProperty("测试类型")
+    private String testType;
+
+    @ApiModelProperty("测试结果")
+    private String testResult;
+
+    @ApiModelProperty("测试详情")
+    private String testDetail;
+
+    @ApiModelProperty("测试时间")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private LocalDateTime testTime;
+
+    @ApiModelProperty("测试人")
+    private String testUser;
+
+    @ApiModelProperty("创建时间")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private LocalDateTime createTime;
+}

+ 73 - 0
pipe-network-service/zksy-system/src/main/java/com/zksy/base/domain/MonitorPoint.java

@@ -0,0 +1,73 @@
+package com.zksy.base.domain;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+import java.util.Date;
+
+/**
+ * 关键监控点位表
+ */
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+@TableName("monitor_point")
+public class MonitorPoint {
+
+    @TableId(value = "point_id", type = IdType.ASSIGN_UUID)
+    @ApiModelProperty("监测点ID")
+    private String pointId;
+
+    @ApiModelProperty("监测点编码")
+    private String pointCode;
+
+    @ApiModelProperty("监测点名称")
+    private String pointName;
+
+    @ApiModelProperty("关联管网设施ID")
+    private String networkId;
+
+    @ApiModelProperty("监测点类型")
+    private String pointType;
+
+    @ApiModelProperty("位置描述")
+    private String location;
+
+    @ApiModelProperty("经度")
+    private BigDecimal longitude;
+
+    @ApiModelProperty("纬度")
+    private BigDecimal latitude;
+
+    @ApiModelProperty("安装日期")
+    @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
+    private Date installationDate;
+
+    @ApiModelProperty("状态")
+    private String status;
+
+    @ApiModelProperty("备注")
+    private String remark;
+
+    @ApiModelProperty("创建人")
+    private String createBy;
+
+    @ApiModelProperty("创建时间")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private LocalDateTime createTime;
+
+    @ApiModelProperty("更新人")
+    private String updateBy;
+
+    @ApiModelProperty("更新时间")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private LocalDateTime updateTime;
+}

+ 85 - 0
pipe-network-service/zksy-system/src/main/java/com/zksy/base/domain/PipeNetworkBase.java

@@ -0,0 +1,85 @@
+package com.zksy.base.domain;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+import java.util.Date;
+
+/**
+ * 管网基础设施信息表
+ */
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+@TableName("pipe_network_base")
+public class PipeNetworkBase {
+
+    @TableId(value = "network_id", type = IdType.ASSIGN_UUID)
+    @ApiModelProperty("管网设施ID")
+    private String networkId;
+
+    @ApiModelProperty("设施编码")
+    private String networkCode;
+
+    @ApiModelProperty("设施名称")
+    private String networkName;
+
+    @ApiModelProperty("设施类型")
+    private String networkType;
+
+    @ApiModelProperty("等级")
+    private String networkLevel;
+
+    @ApiModelProperty("管养单位")
+    private String managementUnit;
+
+    @ApiModelProperty("位置描述")
+    private String location;
+
+    @ApiModelProperty("经度")
+    private BigDecimal longitude;
+
+    @ApiModelProperty("纬度")
+    private BigDecimal latitude;
+
+    @ApiModelProperty("长度(米)")
+    private BigDecimal length;
+
+    @ApiModelProperty("管径(毫米)")
+    private BigDecimal diameter;
+
+    @ApiModelProperty("材质")
+    private String material;
+
+    @ApiModelProperty("建设日期")
+    @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
+    private Date buildDate;
+
+    @ApiModelProperty("状态")
+    private String status;
+
+    @ApiModelProperty("备注")
+    private String remark;
+
+    @ApiModelProperty("创建人")
+    private String createBy;
+
+    @ApiModelProperty("创建时间")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private LocalDateTime createTime;
+
+    @ApiModelProperty("更新人")
+    private String updateBy;
+
+    @ApiModelProperty("更新时间")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private LocalDateTime updateTime;
+}

+ 39 - 0
pipe-network-service/zksy-system/src/main/java/com/zksy/base/dto/AlarmAssignListPageInDTO.java

@@ -0,0 +1,39 @@
+package com.zksy.base.dto;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * 分页查询报警清单列表-入参
+ *
+ * @author xianggx
+ */
+@Data
+@ApiModel(value = "分页查询报警清单列表-入参", description = "分页查询报警清单列表-入参")
+public class AlarmAssignListPageInDTO implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    @ApiModelProperty(value = "设备编码")
+    private String deviceCode;
+
+    @ApiModelProperty(value = "设备名称")
+    private String deviceName;
+
+    @ApiModelProperty(value = "设备报警状态:(0-正常,1-报警)")
+    private Integer alarmStatus;
+
+    @ApiModelProperty(value = "处理状态:0-未处理 1-已处理")
+    private Integer assignStatus;
+
+    @ApiModelProperty(value = "设备厂商")
+    private String manufacturer;
+
+    @ApiModelProperty(value = "当前记录起始索引", required = true)
+    private Long pageNum;
+
+    @ApiModelProperty(value = "每页显示记录数", required = true)
+    private Long pageSize;
+}

+ 65 - 0
pipe-network-service/zksy-system/src/main/java/com/zksy/base/mapper/AlarmAssignDetailMapper.java

@@ -0,0 +1,65 @@
+package com.zksy.base.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.zksy.base.domain.AlarmAssignDetail;
+import org.apache.ibatis.annotations.Mapper;
+
+import java.util.List;
+
+/**
+ * 报警清单处理明细Mapper接口
+ * 
+ * @author zksy
+ * @date 2026-05-06
+ */
+@Mapper
+public interface AlarmAssignDetailMapper extends BaseMapper<AlarmAssignDetail>
+{
+    /**
+     * 查询报警清单处理明细
+     * 
+     * @param alarmAssignDetailId 报警清单处理明细主键
+     * @return 报警清单处理明细
+     */
+    public AlarmAssignDetail selectAlarmAssignDetailByAlarmAssignDetailId(Long alarmAssignDetailId);
+
+    /**
+     * 查询报警清单处理明细列表
+     * 
+     * @param alarmAssignDetail 报警清单处理明细
+     * @return 报警清单处理明细集合
+     */
+    public List<AlarmAssignDetail> selectAlarmAssignDetailList(AlarmAssignDetail alarmAssignDetail);
+
+    /**
+     * 新增报警清单处理明细
+     * 
+     * @param alarmAssignDetail 报警清单处理明细
+     * @return 结果
+     */
+    public int insertAlarmAssignDetail(AlarmAssignDetail alarmAssignDetail);
+
+    /**
+     * 修改报警清单处理明细
+     * 
+     * @param alarmAssignDetail 报警清单处理明细
+     * @return 结果
+     */
+    public int updateAlarmAssignDetail(AlarmAssignDetail alarmAssignDetail);
+
+    /**
+     * 删除报警清单处理明细
+     * 
+     * @param alarmAssignDetailId 报警清单处理明细主键
+     * @return 结果
+     */
+    public int deleteAlarmAssignDetailByAlarmAssignDetailId(Long alarmAssignDetailId);
+
+    /**
+     * 批量删除报警清单处理明细
+     * 
+     * @param alarmAssignDetailIds 需要删除的数据主键集合
+     * @return 结果
+     */
+    public int deleteAlarmAssignDetailByAlarmAssignDetailIds(Long[] alarmAssignDetailIds);
+}

+ 65 - 0
pipe-network-service/zksy-system/src/main/java/com/zksy/base/mapper/AlarmAssignListMapper.java

@@ -0,0 +1,65 @@
+package com.zksy.base.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.zksy.base.domain.AlarmAssignList;
+import org.apache.ibatis.annotations.Mapper;
+
+import java.util.List;
+
+/**
+ * 报警清单Mapper接口
+ * 
+ * @author zksy
+ * @date 2026-05-06
+ */
+@Mapper
+public interface AlarmAssignListMapper extends BaseMapper<AlarmAssignList>
+{
+    /**
+     * 查询报警清单
+     * 
+     * @param alarmAssignId 报警清单主键
+     * @return 报警清单
+     */
+    public AlarmAssignList selectAlarmAssignListByAlarmAssignId(Long alarmAssignId);
+
+    /**
+     * 查询报警清单列表
+     * 
+     * @param alarmAssignList 报警清单
+     * @return 报警清单集合
+     */
+    public List<AlarmAssignList> selectAlarmAssignListList(AlarmAssignList alarmAssignList);
+
+    /**
+     * 新增报警清单
+     * 
+     * @param alarmAssignList 报警清单
+     * @return 结果
+     */
+    public int insertAlarmAssignList(AlarmAssignList alarmAssignList);
+
+    /**
+     * 修改报警清单
+     * 
+     * @param alarmAssignList 报警清单
+     * @return 结果
+     */
+    public int updateAlarmAssignList(AlarmAssignList alarmAssignList);
+
+    /**
+     * 删除报警清单
+     * 
+     * @param alarmAssignId 报警清单主键
+     * @return 结果
+     */
+    public int deleteAlarmAssignListByAlarmAssignId(Long alarmAssignId);
+
+    /**
+     * 批量删除报警清单
+     * 
+     * @param alarmAssignIds 需要删除的数据主键集合
+     * @return 结果
+     */
+    public int deleteAlarmAssignListByAlarmAssignIds(Long[] alarmAssignIds);
+}

+ 9 - 0
pipe-network-service/zksy-system/src/main/java/com/zksy/base/mapper/EquipmentPointRelMapper.java

@@ -0,0 +1,9 @@
+package com.zksy.base.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.zksy.base.domain.EquipmentPointRel;
+import org.apache.ibatis.annotations.Mapper;
+
+@Mapper
+public interface EquipmentPointRelMapper extends BaseMapper<EquipmentPointRel> {
+}

+ 9 - 0
pipe-network-service/zksy-system/src/main/java/com/zksy/base/mapper/EquipmentTestMapper.java

@@ -0,0 +1,9 @@
+package com.zksy.base.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.zksy.base.domain.EquipmentTest;
+import org.apache.ibatis.annotations.Mapper;
+
+@Mapper
+public interface EquipmentTestMapper extends BaseMapper<EquipmentTest> {
+}

+ 25 - 26
pipe-network-service/zksy-system/src/main/java/com/zksy/base/service/EquipmentBaseService.java

@@ -3,51 +3,50 @@ package com.zksy.base.service;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.IService;
 import com.zksy.base.domain.EquipmentBase;
+import com.zksy.manhole.dto.in.ManholeDeviceListInDTO;
+import com.zksy.manhole.dto.in.ManholeDevicePageInDTO;
+import com.zksy.manhole.dto.out.EquipmentBaseOutDTO;
 import org.springframework.stereotype.Service;
 
 import java.util.List;
+import java.util.Map;
 
-@Service
 public interface EquipmentBaseService extends IService<EquipmentBase> {
 
     Page<EquipmentBase> findByPage(long pageNum, long pageSize,
-                                   String equipmentCode,String equipmentName,
-                                   String equipmentModel,String manufacturer);
+                                   String equipmentCode, String equipmentName,
+                                   String equipmentModel, String manufacturer);
 
-    /**
-     * 新增仪器信息
-     * @param entity
-     * @return
-     */
     boolean saveWithCheck(EquipmentBase entity);
 
-    /**
-     * 新增仪器信息
-     * @param entityList
-     * @return
-     */
     boolean saveBatchWithCheck(List<EquipmentBase> entityList);
 
-    /**
-     * 修改仪器信息
-     * @param entity
-     * @return
-     */
     boolean updateWithCheck(EquipmentBase entity);
 
+    boolean removeWithCheck(String id);
+
+    boolean removeBatchWithCheck(List<String> ids);
+
+    boolean updateEquipmentStatus(String equipmentId, Integer currentStatus);
+
+    boolean testEquipment(String equipmentId, String testType, String testDetail, String testUser);
+
+    Map<String, Object> getEquipmentDetail(String equipmentId);
+
+    List<EquipmentBase> getEquipmentByPoint(String pointId);
+//    EquipmentBase getByIdTest(String id);
+
     /**
-     * 删除设备基础信息
-     * @param id
+     * 分页查询监测设备台账列表
+     * @param pageInDTO
      * @return
      */
-    boolean removeWithCheck(String id);
+    Page<EquipmentBaseOutDTO> findManholeDeviceByPage(ManholeDevicePageInDTO pageInDTO);
 
     /**
-     * 设备基础信息批量删除
-     * @param ids
+     * 查询井盖监测设备列表
+     * @param listInDTO
      * @return
      */
-    boolean removeBatchWithCheck(List<String> ids);
-
-//    EquipmentBase getByIdTest(String id);
+    List<EquipmentBaseOutDTO> getManholeDataList(ManholeDeviceListInDTO listInDTO);
 }

+ 8 - 0
pipe-network-service/zksy-system/src/main/java/com/zksy/base/service/EquipmentStatusService.java

@@ -3,6 +3,7 @@ package com.zksy.base.service;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.IService;
 import com.zksy.base.domain.EquipmentStatus;
+import com.zksy.manhole.dto.in.EquipmentStatusInDTO;
 import org.springframework.stereotype.Service;
 
 import java.util.List;
@@ -31,4 +32,11 @@ public interface EquipmentStatusService extends IService<EquipmentStatus> {
      * @return
      */
     boolean updateWithCheck(EquipmentStatus entity);
+
+    /**
+     * 修改设备状态
+     * @param inDTO
+     * @return
+     */
+    boolean updateDeviceStatus(EquipmentStatusInDTO inDTO);
 }

+ 61 - 0
pipe-network-service/zksy-system/src/main/java/com/zksy/base/service/IAlarmAssignDetailService.java

@@ -0,0 +1,61 @@
+package com.zksy.base.service;
+
+import java.util.List;
+import com.zksy.base.domain.AlarmAssignDetail;
+
+/**
+ * 报警清单处理明细Service接口
+ * 
+ * @author zksy
+ * @date 2026-05-06
+ */
+public interface IAlarmAssignDetailService 
+{
+    /**
+     * 查询报警清单处理明细
+     * 
+     * @param alarmAssignDetailId 报警清单处理明细主键
+     * @return 报警清单处理明细
+     */
+    public AlarmAssignDetail selectAlarmAssignDetailByAlarmAssignDetailId(Long alarmAssignDetailId);
+
+    /**
+     * 查询报警清单处理明细列表
+     * 
+     * @param alarmAssignDetail 报警清单处理明细
+     * @return 报警清单处理明细集合
+     */
+    public List<AlarmAssignDetail> selectAlarmAssignDetailList(AlarmAssignDetail alarmAssignDetail);
+
+    /**
+     * 新增报警清单处理明细
+     * 
+     * @param alarmAssignDetail 报警清单处理明细
+     * @return 结果
+     */
+    public int insertAlarmAssignDetail(AlarmAssignDetail alarmAssignDetail);
+
+    /**
+     * 修改报警清单处理明细
+     * 
+     * @param alarmAssignDetail 报警清单处理明细
+     * @return 结果
+     */
+    public int updateAlarmAssignDetail(AlarmAssignDetail alarmAssignDetail);
+
+    /**
+     * 批量删除报警清单处理明细
+     * 
+     * @param alarmAssignDetailIds 需要删除的报警清单处理明细主键集合
+     * @return 结果
+     */
+    public int deleteAlarmAssignDetailByAlarmAssignDetailIds(Long[] alarmAssignDetailIds);
+
+    /**
+     * 删除报警清单处理明细信息
+     * 
+     * @param alarmAssignDetailId 报警清单处理明细主键
+     * @return 结果
+     */
+    public int deleteAlarmAssignDetailByAlarmAssignDetailId(Long alarmAssignDetailId);
+}

+ 72 - 0
pipe-network-service/zksy-system/src/main/java/com/zksy/base/service/IAlarmAssignListService.java

@@ -0,0 +1,72 @@
+package com.zksy.base.service;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.zksy.base.domain.AlarmAssignList;
+import com.zksy.base.dto.AlarmAssignListPageInDTO;
+
+import java.util.List;
+
+/**
+ * 报警清单Service接口
+ * 
+ * @author zksy
+ * @date 2026-05-06
+ */
+public interface IAlarmAssignListService extends IService<AlarmAssignList>
+{
+    /**
+     * 查询报警清单
+     * 
+     * @param alarmAssignId 报警清单主键
+     * @return 报警清单
+     */
+    public AlarmAssignList selectAlarmAssignListByAlarmAssignId(Long alarmAssignId);
+
+    /**
+     * 查询报警清单列表
+     * 
+     * @param alarmAssignList 报警清单
+     * @return 报警清单集合
+     */
+    public List<AlarmAssignList> selectAlarmAssignListList(AlarmAssignList alarmAssignList);
+
+    /**
+     * 新增报警清单
+     * 
+     * @param alarmAssignList 报警清单
+     * @return 结果
+     */
+    public int insertAlarmAssignList(AlarmAssignList alarmAssignList);
+
+    /**
+     * 修改报警清单
+     * 
+     * @param alarmAssignList 报警清单
+     * @return 结果
+     */
+    public int updateAlarmAssignList(AlarmAssignList alarmAssignList);
+
+    /**
+     * 批量删除报警清单
+     * 
+     * @param alarmAssignIds 需要删除的报警清单主键集合
+     * @return 结果
+     */
+    public int deleteAlarmAssignListByAlarmAssignIds(Long[] alarmAssignIds);
+
+    /**
+     * 删除报警清单信息
+     * 
+     * @param alarmAssignId 报警清单主键
+     * @return 结果
+     */
+    public int deleteAlarmAssignListByAlarmAssignId(Long alarmAssignId);
+
+    /**
+     * 分页查询报警清单列表
+     * @param pageInDTO
+     * @return
+     */
+    public Page<AlarmAssignList> findByPage(AlarmAssignListPageInDTO pageInDTO);
+}

+ 93 - 0
pipe-network-service/zksy-system/src/main/java/com/zksy/base/service/impl/AlarmAssignDetailServiceImpl.java

@@ -0,0 +1,93 @@
+package com.zksy.base.service.impl;
+
+import java.util.List;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import com.zksy.base.mapper.AlarmAssignDetailMapper;
+import com.zksy.base.domain.AlarmAssignDetail;
+import com.zksy.base.service.IAlarmAssignDetailService;
+
+/**
+ * 报警清单处理明细Service业务层处理
+ * 
+ * @author zksy
+ * @date 2026-05-06
+ */
+@Service
+public class AlarmAssignDetailServiceImpl implements IAlarmAssignDetailService 
+{
+    @Autowired
+    private AlarmAssignDetailMapper alarmAssignDetailMapper;
+
+    /**
+     * 查询报警清单处理明细
+     * 
+     * @param alarmAssignDetailId 报警清单处理明细主键
+     * @return 报警清单处理明细
+     */
+    @Override
+    public AlarmAssignDetail selectAlarmAssignDetailByAlarmAssignDetailId(Long alarmAssignDetailId)
+    {
+        return alarmAssignDetailMapper.selectAlarmAssignDetailByAlarmAssignDetailId(alarmAssignDetailId);
+    }
+
+    /**
+     * 查询报警清单处理明细列表
+     * 
+     * @param alarmAssignDetail 报警清单处理明细
+     * @return 报警清单处理明细
+     */
+    @Override
+    public List<AlarmAssignDetail> selectAlarmAssignDetailList(AlarmAssignDetail alarmAssignDetail)
+    {
+        return alarmAssignDetailMapper.selectAlarmAssignDetailList(alarmAssignDetail);
+    }
+
+    /**
+     * 新增报警清单处理明细
+     * 
+     * @param alarmAssignDetail 报警清单处理明细
+     * @return 结果
+     */
+    @Override
+    public int insertAlarmAssignDetail(AlarmAssignDetail alarmAssignDetail)
+    {
+        return alarmAssignDetailMapper.insertAlarmAssignDetail(alarmAssignDetail);
+    }
+
+    /**
+     * 修改报警清单处理明细
+     * 
+     * @param alarmAssignDetail 报警清单处理明细
+     * @return 结果
+     */
+    @Override
+    public int updateAlarmAssignDetail(AlarmAssignDetail alarmAssignDetail)
+    {
+        return alarmAssignDetailMapper.updateAlarmAssignDetail(alarmAssignDetail);
+    }
+
+    /**
+     * 批量删除报警清单处理明细
+     * 
+     * @param alarmAssignDetailIds 需要删除的报警清单处理明细主键
+     * @return 结果
+     */
+    @Override
+    public int deleteAlarmAssignDetailByAlarmAssignDetailIds(Long[] alarmAssignDetailIds)
+    {
+        return alarmAssignDetailMapper.deleteAlarmAssignDetailByAlarmAssignDetailIds(alarmAssignDetailIds);
+    }
+
+    /**
+     * 删除报警清单处理明细信息
+     * 
+     * @param alarmAssignDetailId 报警清单处理明细主键
+     * @return 结果
+     */
+    @Override
+    public int deleteAlarmAssignDetailByAlarmAssignDetailId(Long alarmAssignDetailId)
+    {
+        return alarmAssignDetailMapper.deleteAlarmAssignDetailByAlarmAssignDetailId(alarmAssignDetailId);
+    }
+}

+ 131 - 0
pipe-network-service/zksy-system/src/main/java/com/zksy/base/service/impl/AlarmAssignListServiceImpl.java

@@ -0,0 +1,131 @@
+package com.zksy.base.service.impl;
+
+import cn.hutool.core.collection.CollUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.zksy.base.domain.AlarmAssignDetail;
+import com.zksy.base.domain.AlarmAssignList;
+import com.zksy.base.dto.AlarmAssignListPageInDTO;
+import com.zksy.base.mapper.AlarmAssignDetailMapper;
+import com.zksy.base.mapper.AlarmAssignListMapper;
+import com.zksy.base.service.IAlarmAssignListService;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+/**
+ * 报警清单Service业务层处理
+ * 
+ * @author zksy
+ * @date 2026-05-06
+ */
+@Service
+public class AlarmAssignListServiceImpl extends ServiceImpl<AlarmAssignListMapper, AlarmAssignList> implements IAlarmAssignListService
+{
+    @Autowired
+    private AlarmAssignDetailMapper alarmAssignDetailMapper;
+
+    /**
+     * 查询报警清单
+     * 
+     * @param alarmAssignId 报警清单主键
+     * @return 报警清单
+     */
+    @Override
+    public AlarmAssignList selectAlarmAssignListByAlarmAssignId(Long alarmAssignId)
+    {
+        AlarmAssignList alarmAssignList = this.baseMapper.selectAlarmAssignListByAlarmAssignId(alarmAssignId);
+        if(alarmAssignList == null){
+            return alarmAssignList;
+        }
+        LambdaQueryWrapper<AlarmAssignDetail> lambdaQueryWrapper = new LambdaQueryWrapper<AlarmAssignDetail>()
+                .eq(AlarmAssignDetail::getAlarmAssignId, alarmAssignId)
+                .orderByDesc(AlarmAssignDetail::getAlarmAssignDetailId);
+        List<AlarmAssignDetail> detailList = alarmAssignDetailMapper.selectList(lambdaQueryWrapper);
+        if(CollUtil.isNotEmpty(detailList)){
+
+        }
+        return alarmAssignList;
+    }
+
+    /**
+     * 查询报警清单列表
+     * 
+     * @param alarmAssignList 报警清单
+     * @return 报警清单
+     */
+    @Override
+    public List<AlarmAssignList> selectAlarmAssignListList(AlarmAssignList alarmAssignList)
+    {
+        return this.baseMapper.selectAlarmAssignListList(alarmAssignList);
+    }
+
+    /**
+     * 新增报警清单
+     * 
+     * @param alarmAssignList 报警清单
+     * @return 结果
+     */
+    @Override
+    public int insertAlarmAssignList(AlarmAssignList alarmAssignList)
+    {
+        return this.baseMapper.insertAlarmAssignList(alarmAssignList);
+    }
+
+    /**
+     * 修改报警清单
+     * 
+     * @param alarmAssignList 报警清单
+     * @return 结果
+     */
+    @Override
+    public int updateAlarmAssignList(AlarmAssignList alarmAssignList)
+    {
+        return this.baseMapper.updateAlarmAssignList(alarmAssignList);
+    }
+
+    /**
+     * 批量删除报警清单
+     * 
+     * @param alarmAssignIds 需要删除的报警清单主键
+     * @return 结果
+     */
+    @Override
+    public int deleteAlarmAssignListByAlarmAssignIds(Long[] alarmAssignIds)
+    {
+        return this.baseMapper.deleteAlarmAssignListByAlarmAssignIds(alarmAssignIds);
+    }
+
+    /**
+     * 删除报警清单信息
+     * 
+     * @param alarmAssignId 报警清单主键
+     * @return 结果
+     */
+    @Override
+    public int deleteAlarmAssignListByAlarmAssignId(Long alarmAssignId)
+    {
+        return this.baseMapper.deleteAlarmAssignListByAlarmAssignId(alarmAssignId);
+    }
+
+    /**
+     * 分页查询报警清单列表
+     * @param pageInDTO
+     * @return
+     */
+    @Override
+    public Page<AlarmAssignList> findByPage(AlarmAssignListPageInDTO pageInDTO) {
+        Page<AlarmAssignList> page = new Page<>(pageInDTO.getPageNum(), pageInDTO.getPageSize());
+        LambdaQueryWrapper<AlarmAssignList> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.eq(StringUtils.isNotEmpty(pageInDTO.getDeviceCode()), AlarmAssignList::getDeviceCode, pageInDTO.getDeviceCode())
+                .eq(pageInDTO.getAlarmStatus() != null, AlarmAssignList::getAlarmStatus, pageInDTO.getAlarmStatus())
+                .eq(pageInDTO.getAssignStatus() != null, AlarmAssignList::getAssignStatus, pageInDTO.getAssignStatus())
+                .like(StringUtils.isNotEmpty(pageInDTO.getDeviceName()), AlarmAssignList::getDeviceName, pageInDTO.getDeviceName())
+                .like(StringUtils.isNotEmpty(pageInDTO.getManufacturer()), AlarmAssignList::getManufacturer, pageInDTO.getManufacturer());
+        queryWrapper.orderByDesc(AlarmAssignList::getAlarmTime);
+        return this.page(page, queryWrapper);
+    }
+}

+ 328 - 57
pipe-network-service/zksy-system/src/main/java/com/zksy/base/service/impl/EquipmentBaseServiceImpl.java

@@ -1,28 +1,43 @@
 package com.zksy.base.service.impl;
 
 
+import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.collection.CollUtil;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.zksy.base.domain.*;
+import com.zksy.base.mapper.*;
+import com.zksy.base.alarm.domain.WarningThreshold;
+import com.zksy.base.alarm.mapper.WarningThresholdMapper;
 import com.zksy.base.domain.EquipmentBase;
 import com.zksy.base.domain.EquipmentMaintain;
 import com.zksy.base.domain.EquipmentStatus;
 import com.zksy.base.domain.EquipmentType;
+import com.zksy.base.manhole.domain.ManholeData;
+import com.zksy.base.manhole.mapper.ManholeDataMapper;
 import com.zksy.base.mapper.EquipmentBaseMapper;
 import com.zksy.base.mapper.EquipmentMaintainMapper;
 import com.zksy.base.mapper.EquipmentStatusMapper;
 import com.zksy.base.mapper.EquipmentTypeMapper;
 import com.zksy.base.service.EquipmentBaseService;
 import com.zksy.common.exception.ServiceException;
+import com.zksy.manhole.dto.in.ManholeDeviceListInDTO;
+import com.zksy.manhole.dto.in.ManholeDevicePageInDTO;
+import com.zksy.manhole.dto.out.EquipmentBaseOutDTO;
+import com.zksy.manhole.dto.out.EquipmentStatusOutDTO;
+import com.zksy.manhole.dto.out.ManholeDataOutDTO;
 import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
+import java.time.LocalDateTime;
+import java.util.*;
+import java.util.*;
+import java.util.function.Function;
 import java.util.stream.Collectors;
 
 @Slf4j
@@ -39,13 +54,22 @@ public class EquipmentBaseServiceImpl extends ServiceImpl<EquipmentBaseMapper, E
     @Autowired
     private EquipmentStatusMapper equipmentStatusMapper;
 
-//    @Autowired
-//    private EquipmentBaseMapper equipmentBaseMapper;
+    @Autowired
+    private EquipmentPointRelMapper equipmentPointRelMapper;
+
+    @Autowired
+    private EquipmentTestMapper equipmentTestMapper;
+
+    @Autowired
+    private WarningThresholdMapper warningThresholdMapper;
+
+    @Autowired
+    private ManholeDataMapper manholeDataMapper;
 
     @Override
     public Page<EquipmentBase> findByPage(long pageNum, long pageSize,
-                                          String equipmentCode,String equipmentName,
-                                          String equipmentModel,String manufacturer) {
+                                          String equipmentCode, String equipmentName,
+                                          String equipmentModel, String manufacturer) {
         Page<EquipmentBase> page = new Page<>(pageNum, pageSize);
         LambdaQueryWrapper<EquipmentBase> queryWrapper = new LambdaQueryWrapper<>();
         if (equipmentCode != null && !equipmentCode.isEmpty()) {
@@ -60,22 +84,17 @@ public class EquipmentBaseServiceImpl extends ServiceImpl<EquipmentBaseMapper, E
         if (manufacturer != null && !manufacturer.isEmpty()) {
             queryWrapper.like(EquipmentBase::getManufacturer, manufacturer);
         }
+        queryWrapper.orderByDesc(EquipmentBase::getCreateTime);
         return this.page(page, queryWrapper);
     }
 
-    /**
-     * 新增仪器信息
-     * @param entity
-     * @return
-     */
     @Override
     public boolean saveWithCheck(EquipmentBase entity) {
         String equipmentTypeId = entity.getEquipmentTypeId();
         EquipmentType equipmentType = equipmentTypeMapper.selectById(equipmentTypeId);
-        if(equipmentType==null){
+        if (equipmentType == null) {
             throw new ServiceException("设备类型不存在,请检查equipment_type_id:");
         }
-        //校验设备编码是否已存在
         LambdaQueryWrapper<EquipmentBase> queryWrapper = new LambdaQueryWrapper<>();
         queryWrapper.eq(EquipmentBase::getEquipmentCode, entity.getEquipmentCode());
         long count = this.count(queryWrapper);
@@ -85,15 +104,8 @@ public class EquipmentBaseServiceImpl extends ServiceImpl<EquipmentBaseMapper, E
         return this.save(entity);
     }
 
-    /**
-     * 批量新增
-     * @param entityList
-     * @return
-     */
     @Override
     public boolean saveBatchWithCheck(List<EquipmentBase> entityList) {
-
-        //是否有重复编码
         Set<String> codeSet = new HashSet<>();
         for (EquipmentBase entity : entityList) {
             String code = entity.getEquipmentCode();
@@ -103,93 +115,81 @@ public class EquipmentBaseServiceImpl extends ServiceImpl<EquipmentBaseMapper, E
             codeSet.add(code);
         }
 
-        //校验
         for (EquipmentBase entity : entityList) {
-            //校验设备类型是否存在
             if (equipmentTypeMapper.selectById(entity.getEquipmentTypeId()) == null) {
                 throw new ServiceException("设备类型不存在:" + entity.getEquipmentTypeId());
             }
-            //校验设备编码是否已存在
             LambdaQueryWrapper<EquipmentBase> wrapper = new LambdaQueryWrapper<>();
             wrapper.eq(EquipmentBase::getEquipmentCode, entity.getEquipmentCode());
             if (this.count(wrapper) > 0) {
                 throw new ServiceException("设备编码已存在:" + entity.getEquipmentCode());
             }
         }
-        //保存
         return this.saveBatch(entityList);
     }
 
-    /**
-     * 修改仪器信息
-     * @param entity
-     * @return
-     */
     @Override
     @Transactional
     public boolean updateWithCheck(EquipmentBase entity) {
-        //设备是否存在
         String equipmentId = entity.getEquipmentId();
         if (this.getById(equipmentId) == null) {
             throw new ServiceException("设备不存在,无法修改:" + equipmentId);
         }
 
-        //修改设备类型ID,需要校验新类型是否存在
         String newTypeId = entity.getEquipmentTypeId();
         if (newTypeId != null && equipmentTypeMapper.selectById(newTypeId) == null) {
             throw new ServiceException("设备类型不存在:" + newTypeId);
         }
 
-        //修改设备编码,需要校验新编码是否已被使用
         String newCode = entity.getEquipmentCode();
         if (newCode != null) {
             LambdaQueryWrapper<EquipmentBase> wrapper = new LambdaQueryWrapper<>();
             wrapper.eq(EquipmentBase::getEquipmentCode, newCode)
-                    .ne(EquipmentBase::getEquipmentId, equipmentId); // 排除自身
+                    .ne(EquipmentBase::getEquipmentId, equipmentId);
             if (this.count(wrapper) > 0) {
                 throw new ServiceException("设备编码已被使用:" + newCode);
             }
         }
-        //修改
         return this.updateById(entity);
     }
 
-    /**
-     * 删除设备基础信息
-     * @param equipmentId
-     * @return
-     */
     @Override
     @Transactional
     public boolean removeWithCheck(String equipmentId) {
-        //校验设备是否存在
         EquipmentBase equipment = this.getById(equipmentId);
         if (equipment == null) {
             throw new ServiceException("设备不存在:" + equipmentId);
         }
 
-        //删除关联的维护记录
         LambdaQueryWrapper<EquipmentMaintain> maintainWrapper = new LambdaQueryWrapper<>();
         maintainWrapper.eq(EquipmentMaintain::getEquipmentId, equipmentId);
         equipmentMaintainMapper.delete(maintainWrapper);
         log.info("已删除设备[{}]的维护记录", equipmentId);
 
-        //删除关联的状态记录
         LambdaQueryWrapper<EquipmentStatus> statusWrapper = new LambdaQueryWrapper<>();
         statusWrapper.eq(EquipmentStatus::getEquipmentId, equipmentId);
         equipmentStatusMapper.delete(statusWrapper);
         log.info("已删除设备[{}]的状态记录", equipmentId);
 
-        //删除设备
-        boolean deleted = this.baseMapper.deleteById(equipmentId) > 0;
-        return deleted;
+        LambdaQueryWrapper<EquipmentPointRel> relWrapper = new LambdaQueryWrapper<>();
+        relWrapper.eq(EquipmentPointRel::getEquipmentId, equipmentId);
+        equipmentPointRelMapper.delete(relWrapper);
+        log.info("已删除设备[{}]的监测点关联", equipmentId);
+
+        // 现在 WarningThreshold 有了 equipmentId 字段,直接匹配
+        LambdaQueryWrapper<WarningThreshold> thresholdWrapper = new LambdaQueryWrapper<>();
+        thresholdWrapper.eq(WarningThreshold::getEquipmentId, equipmentId);
+        warningThresholdMapper.delete(thresholdWrapper);
+        log.info("已删除设备[{}]的预警阈值配置", equipmentId);
+
+        LambdaQueryWrapper<EquipmentTest> testWrapper = new LambdaQueryWrapper<>();
+        testWrapper.eq(EquipmentTest::getEquipmentId, equipmentId);
+        equipmentTestMapper.delete(testWrapper);
+        log.info("已删除设备[{}]的测试记录", equipmentId);
+
+        return this.baseMapper.deleteById(equipmentId) > 0;
     }
 
-    /**
-     * 设备基础信息批量删除
-     * @param equipmentIds
-     * @return
-     */
     @Override
     @Transactional
     public boolean removeBatchWithCheck(List<String> equipmentIds) {
@@ -197,16 +197,14 @@ public class EquipmentBaseServiceImpl extends ServiceImpl<EquipmentBaseMapper, E
             throw new ServiceException("批量删除失败:设备ID列表不能为空");
         }
 
-        //校验设备是否存在
         List<EquipmentBase> existEquipments = this.listByIds(equipmentIds);
         if (existEquipments.isEmpty()) {
             throw new ServiceException("批量删除失败:所有设备ID均不存在");
         }
-        // 提取存在的设备ID
         List<String> existIds = existEquipments.stream()
                 .map(EquipmentBase::getEquipmentId)
                 .collect(Collectors.toList());
-        //无效ID
+
         List<String> invalidIds = equipmentIds.stream()
                 .filter(id -> !existIds.contains(id))
                 .collect(Collectors.toList());
@@ -214,19 +212,292 @@ public class EquipmentBaseServiceImpl extends ServiceImpl<EquipmentBaseMapper, E
             log.warn("批量删除中存在无效设备ID:{}", invalidIds);
         }
 
-        //批量删除关联的维护记录
         LambdaQueryWrapper<EquipmentMaintain> maintainWrapper = new LambdaQueryWrapper<>();
         maintainWrapper.in(EquipmentMaintain::getEquipmentId, existIds);
         equipmentMaintainMapper.delete(maintainWrapper);
         log.info("已批量删除{}条设备的维护记录", existIds.size());
 
-        //批量删除关联的状态记录
         LambdaQueryWrapper<EquipmentStatus> statusWrapper = new LambdaQueryWrapper<>();
         statusWrapper.in(EquipmentStatus::getEquipmentId, existIds);
         equipmentStatusMapper.delete(statusWrapper);
         log.info("已批量删除{}条设备的状态记录", existIds.size());
-        //删除
+
+        LambdaQueryWrapper<EquipmentPointRel> relWrapper = new LambdaQueryWrapper<>();
+        relWrapper.in(EquipmentPointRel::getEquipmentId, existIds);
+        equipmentPointRelMapper.delete(relWrapper);
+        log.info("已批量删除{}条设备的监测点关联", existIds.size());
+
+        // 现在 WarningThreshold 有了 equipmentId 字段,直接匹配
+        LambdaQueryWrapper<WarningThreshold> thresholdWrapper = new LambdaQueryWrapper<>();
+        thresholdWrapper.in(WarningThreshold::getEquipmentId, existIds);
+        warningThresholdMapper.delete(thresholdWrapper);
+        log.info("已批量删除{}条设备的预警阈值配置", existIds.size());
+
+        LambdaQueryWrapper<EquipmentTest> testWrapper = new LambdaQueryWrapper<>();
+        testWrapper.in(EquipmentTest::getEquipmentId, existIds);
+        equipmentTestMapper.delete(testWrapper);
+        log.info("已批量删除{}条设备的测试记录", existIds.size());
+
         return this.removeByIds(existIds);
     }
 
+    /**
+     * 分页查询监测设备台账列表
+     * @param pageInDTO
+     * @return
+     */
+    @Override
+    public Page<EquipmentBaseOutDTO> findManholeDeviceByPage(ManholeDevicePageInDTO pageInDTO) {
+        log.info("分页查询监测设备台账列表-入参:{}", pageInDTO);
+        List<String> equipmentIds = null;
+        if(pageInDTO.getCurrentStatus() != null){
+            List<EquipmentStatus> equipmentStatusList = equipmentStatusMapper.selectList(new LambdaQueryWrapper<EquipmentStatus>()
+                    .eq(EquipmentStatus::getCurrentStatus, pageInDTO.getCurrentStatus()));
+            if(CollUtil.isEmpty(equipmentStatusList)){
+                return new Page<>(pageInDTO.getPageNum(), pageInDTO.getPageSize(), 0);
+            }
+            equipmentIds = equipmentStatusList.stream().map(EquipmentStatus::getEquipmentId).distinct().collect(Collectors.toList());
+        }
+        Page<EquipmentBase> page = new Page<>(pageInDTO.getPageNum(), pageInDTO.getPageSize());
+        LambdaQueryWrapper<EquipmentBase> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.eq(StringUtils.isNotEmpty(pageInDTO.getDeviceCode()), EquipmentBase::getEquipmentCode, pageInDTO.getDeviceCode())
+                .eq(StringUtils.isNotEmpty(pageInDTO.getEquipmentTypeId()), EquipmentBase::getEquipmentTypeId, pageInDTO.getEquipmentTypeId())
+                .in(CollUtil.isNotEmpty(equipmentIds), EquipmentBase::getEquipmentId, equipmentIds)
+                .like(StringUtils.isNotEmpty(pageInDTO.getDeviceName()), EquipmentBase::getEquipmentName, pageInDTO.getDeviceName())
+                .like(StringUtils.isNotEmpty(pageInDTO.getEquipmentLocation()), EquipmentBase::getEquipmentLocation, pageInDTO.getEquipmentLocation())
+                .orderByDesc(EquipmentBase::getUpdateTime);
+        Page<EquipmentBase> rs = this.page(page, queryWrapper);
+        List<EquipmentBaseOutDTO> outDTOList = BeanUtil.copyToList(rs.getRecords(), EquipmentBaseOutDTO.class);
+        if (CollUtil.isNotEmpty(outDTOList)) {
+            //查询设备类型
+            List<String> equipmentTypeIdList = outDTOList.stream().map(EquipmentBaseOutDTO::getEquipmentTypeId).distinct().collect(Collectors.toList());
+            List<EquipmentType> equipmentTypeList = equipmentTypeMapper.selectBatchIds(equipmentTypeIdList);
+            Map<String, EquipmentType> equipmentTypeMap = new HashMap<>();
+            if(CollUtil.isNotEmpty(equipmentTypeList)){
+                equipmentTypeMap.putAll(equipmentTypeList.stream().collect(Collectors.toMap(EquipmentType::getTypeId, Function.identity(), (key1, key2) -> key2)));
+            }
+            //查询设备状态
+            List<String> equipmentIdList = outDTOList.stream().map(EquipmentBaseOutDTO::getEquipmentId).distinct().collect(Collectors.toList());
+            List<EquipmentStatus> equipmentStatusList = equipmentStatusMapper.selectList(new LambdaQueryWrapper<EquipmentStatus>()
+                    .in(EquipmentStatus::getEquipmentId, equipmentIdList));
+            Map<String, EquipmentStatus> EquipmentStatusMap = new HashMap<>();
+            if(CollUtil.isNotEmpty(equipmentStatusList)){
+                EquipmentStatusMap.putAll(equipmentStatusList.stream().collect(Collectors.toMap(EquipmentStatus::getEquipmentId, Function.identity(), (key1, key2) -> key2)));
+            }
+            //查询设备监测状态
+            Map<String, List<ManholeData>> imeiCardNumberMapList = new HashMap<>();
+            if(pageInDTO.getIsQueryManholeData()){
+                List<String> equipmentCodeList = outDTOList.stream().map(EquipmentBaseOutDTO::getEquipmentCode).distinct().collect(Collectors.toList());
+                List<ManholeData> manholeDataList = manholeDataMapper.selectList(new LambdaQueryWrapper<ManholeData>()
+                        .in(ManholeData::getImeiCardNumber, equipmentCodeList)
+                        .orderByDesc(ManholeData::getCreateTime));
+                imeiCardNumberMapList.putAll(manholeDataList.stream().collect(Collectors.groupingBy(ManholeData::getImeiCardNumber)));
+            }
+            List<ManholeData> manholeDataList = null;
+            for(EquipmentBaseOutDTO outDTO : outDTOList) {
+                EquipmentType equipmentType = equipmentTypeMap.get(outDTO.getEquipmentTypeId());
+                if(equipmentType != null){
+                    outDTO.setEquipmentTypeName(equipmentType.getTypeName());
+                }
+                EquipmentStatus equipmentStatus = EquipmentStatusMap.get(outDTO.getEquipmentId());
+                if(equipmentStatus != null){
+                    EquipmentStatusOutDTO equipmentStatusOutDTO = BeanUtil.copyProperties(equipmentStatus, EquipmentStatusOutDTO.class);
+                    outDTO.setEquipmentStatus(equipmentStatusOutDTO);
+                }
+                if(pageInDTO.getIsQueryManholeData()){
+                    manholeDataList = imeiCardNumberMapList.get(outDTO.getEquipmentCode());
+                    if(CollUtil.isNotEmpty(manholeDataList)){
+                        ManholeData manholeData = manholeDataList.get(0);
+                        ManholeDataOutDTO manholeDataOutDTO = BeanUtil.copyProperties(manholeData, ManholeDataOutDTO.class);
+                        outDTO.setManholeData(manholeDataOutDTO);
+                    }
+                }
+            }
+        }
+        Page<EquipmentBaseOutDTO> outPage = new Page<>(pageInDTO.getPageNum(), pageInDTO.getPageSize(), rs.getTotal());
+        outPage.setRecords(outDTOList);
+        return outPage;
+    }
+
+    /**
+     * 查询井盖监测设备列表
+     * @param listInDTO
+     * @return
+     */
+    @Override
+    public List<EquipmentBaseOutDTO> getManholeDataList(ManholeDeviceListInDTO listInDTO) {
+        log.info("查询井盖监测设备列表-入参:{}", listInDTO);
+        List<String> equipmentIds = null;
+        if(listInDTO.getCurrentStatus() != null || listInDTO.getAlarmStatus() != null || listInDTO.getOnlineStatus() != null){
+            List<EquipmentStatus> equipmentStatusList = equipmentStatusMapper.selectList(new LambdaQueryWrapper<EquipmentStatus>()
+                    .eq(listInDTO.getCurrentStatus() != null, EquipmentStatus::getCurrentStatus, listInDTO.getCurrentStatus())
+                    .eq(listInDTO.getAlarmStatus() != null, EquipmentStatus::getAlarmStatus, listInDTO.getAlarmStatus())
+                    .eq(listInDTO.getOnlineStatus() != null, EquipmentStatus::getOnlineStatus, listInDTO.getOnlineStatus()));
+            if(CollUtil.isEmpty(equipmentStatusList)){
+                return new ArrayList<>();
+            }
+            equipmentIds = equipmentStatusList.stream().map(EquipmentStatus::getEquipmentId).distinct().collect(Collectors.toList());
+        }
+        LambdaQueryWrapper<EquipmentBase> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.in(CollUtil.isNotEmpty(equipmentIds), EquipmentBase::getEquipmentId, equipmentIds)
+                .orderByDesc(EquipmentBase::getUpdateTime);
+        List<EquipmentBase> equipmentBaseList = this.list(queryWrapper);
+        if (CollUtil.isEmpty(equipmentBaseList)) {
+            return new ArrayList<>();
+        }
+        List<EquipmentBaseOutDTO> outDTOList = BeanUtil.copyToList(equipmentBaseList, EquipmentBaseOutDTO.class);
+        //查询设备类型
+        List<String> equipmentTypeIdList = outDTOList.stream().map(EquipmentBaseOutDTO::getEquipmentTypeId).distinct().collect(Collectors.toList());
+        List<EquipmentType> equipmentTypeList = equipmentTypeMapper.selectBatchIds(equipmentTypeIdList);
+        Map<String, EquipmentType> equipmentTypeMap = new HashMap<>();
+        if(CollUtil.isNotEmpty(equipmentTypeList)){
+            equipmentTypeMap.putAll(equipmentTypeList.stream().collect(Collectors.toMap(EquipmentType::getTypeId, Function.identity(), (key1, key2) -> key2)));
+        }
+        //查询设备状态
+        List<String> equipmentIdList = outDTOList.stream().map(EquipmentBaseOutDTO::getEquipmentId).distinct().collect(Collectors.toList());
+        List<EquipmentStatus> equipmentStatusList = equipmentStatusMapper.selectList(new LambdaQueryWrapper<EquipmentStatus>()
+                .in(EquipmentStatus::getEquipmentId, equipmentIdList));
+        Map<String, EquipmentStatus> EquipmentStatusMap = new HashMap<>();
+        if(CollUtil.isNotEmpty(equipmentStatusList)){
+            EquipmentStatusMap.putAll(equipmentStatusList.stream().collect(Collectors.toMap(EquipmentStatus::getEquipmentId, Function.identity(), (key1, key2) -> key2)));
+        }
+        //查询设备监测状态
+        Map<String, List<ManholeData>> imeiCardNumberMapList = new HashMap<>();
+        if(listInDTO.getIsQueryManholeData()){
+            List<String> equipmentCodeList = outDTOList.stream().map(EquipmentBaseOutDTO::getEquipmentCode).distinct().collect(Collectors.toList());
+            List<ManholeData> manholeDataList = manholeDataMapper.selectList(new LambdaQueryWrapper<ManholeData>()
+                    .in(ManholeData::getImeiCardNumber, equipmentCodeList)
+                    .orderByDesc(ManholeData::getCreateTime));
+            imeiCardNumberMapList.putAll(manholeDataList.stream().collect(Collectors.groupingBy(ManholeData::getImeiCardNumber)));
+        }
+        List<ManholeData> manholeDataList = null;
+        for(EquipmentBaseOutDTO outDTO : outDTOList) {
+            EquipmentType equipmentType = equipmentTypeMap.get(outDTO.getEquipmentTypeId());
+            if(equipmentType != null){
+                outDTO.setEquipmentTypeName(equipmentType.getTypeName());
+            }
+            EquipmentStatus equipmentStatus = EquipmentStatusMap.get(outDTO.getEquipmentId());
+            if(equipmentStatus != null){
+                EquipmentStatusOutDTO equipmentStatusOutDTO = BeanUtil.copyProperties(equipmentStatus, EquipmentStatusOutDTO.class);
+                outDTO.setEquipmentStatus(equipmentStatusOutDTO);
+            }
+            if(listInDTO.getIsQueryManholeData()){
+                manholeDataList = imeiCardNumberMapList.get(outDTO.getEquipmentCode());
+                if(CollUtil.isNotEmpty(manholeDataList)){
+                    ManholeData manholeData = manholeDataList.get(0);
+                    ManholeDataOutDTO manholeDataOutDTO = BeanUtil.copyProperties(manholeData, ManholeDataOutDTO.class);
+                    outDTO.setManholeData(manholeDataOutDTO);
+                }
+            }
+        }
+        return outDTOList;
+    }
+
+    @Override
+    @Transactional
+    public boolean updateEquipmentStatus(String equipmentId, Integer currentStatus) {
+        EquipmentBase equipment = this.getById(equipmentId);
+        if (equipment == null) {
+            throw new ServiceException("设备不存在:" + equipmentId);
+        }
+
+        LambdaQueryWrapper<EquipmentStatus> wrapper = new LambdaQueryWrapper<>();
+        wrapper.eq(EquipmentStatus::getEquipmentId, equipmentId);
+        EquipmentStatus status = equipmentStatusMapper.selectOne(wrapper);
+
+        if (status == null) {
+            status = new EquipmentStatus();
+            status.setEquipmentId(equipmentId);
+            status.setCurrentStatus(currentStatus);
+            status.setAlarmStatus(0);
+            status.setOnlineStatus(1);
+            status.setStatusUpdateTime(LocalDateTime.now());
+            return equipmentStatusMapper.insert(status) > 0;
+        } else {
+            status.setCurrentStatus(currentStatus);
+            status.setStatusUpdateTime(LocalDateTime.now());
+            return equipmentStatusMapper.updateById(status) > 0;
+        }
+    }
+
+    @Override
+    @Transactional
+    public boolean testEquipment(String equipmentId, String testType, String testDetail, String testUser) {
+        EquipmentBase equipment = this.getById(equipmentId);
+        if (equipment == null) {
+            throw new ServiceException("设备不存在:" + equipmentId);
+        }
+
+        EquipmentTest test = new EquipmentTest();
+        test.setEquipmentId(equipmentId);
+        test.setTestType(testType);
+        test.setTestResult("SUCCESS");
+        test.setTestDetail(testDetail);
+        test.setTestTime(LocalDateTime.now());
+        test.setTestUser(testUser);
+        return equipmentTestMapper.insert(test) > 0;
+    }
+
+    @Override
+    public Map<String, Object> getEquipmentDetail(String equipmentId) {
+        EquipmentBase equipment = this.getById(equipmentId);
+        if (equipment == null) {
+            throw new ServiceException("设备不存在:" + equipmentId);
+        }
+
+        Map<String, Object> result = new HashMap<>();
+        result.put("equipmentInfo", equipment);
+
+        if (equipment.getEquipmentTypeId() != null) {
+            EquipmentType type = equipmentTypeMapper.selectById(equipment.getEquipmentTypeId());
+            result.put("typeInfo", type);
+        }
+
+        LambdaQueryWrapper<EquipmentStatus> statusWrapper = new LambdaQueryWrapper<>();
+        statusWrapper.eq(EquipmentStatus::getEquipmentId, equipmentId);
+        EquipmentStatus status = equipmentStatusMapper.selectOne(statusWrapper);
+        result.put("statusInfo", status);
+
+        LambdaQueryWrapper<EquipmentMaintain> maintainWrapper = new LambdaQueryWrapper<>();
+        maintainWrapper.eq(EquipmentMaintain::getEquipmentId, equipmentId);
+        maintainWrapper.orderByDesc(EquipmentMaintain::getMaintainDate);
+        List<EquipmentMaintain> maintainList = equipmentMaintainMapper.selectList(maintainWrapper);
+        result.put("maintainList", maintainList);
+
+        LambdaQueryWrapper<EquipmentPointRel> relWrapper = new LambdaQueryWrapper<>();
+        relWrapper.eq(EquipmentPointRel::getEquipmentId, equipmentId);
+        List<EquipmentPointRel> relList = equipmentPointRelMapper.selectList(relWrapper);
+        result.put("pointRelList", relList);
+
+        // 现在 WarningThreshold 有了 equipmentId 字段,直接匹配
+        LambdaQueryWrapper<WarningThreshold> thresholdWrapper = new LambdaQueryWrapper<>();
+        thresholdWrapper.eq(WarningThreshold::getEquipmentId, equipmentId);
+        List<WarningThreshold> thresholdList = warningThresholdMapper.selectList(thresholdWrapper);
+        result.put("thresholdList", thresholdList);
+
+        LambdaQueryWrapper<EquipmentTest> testWrapper = new LambdaQueryWrapper<>();
+        testWrapper.eq(EquipmentTest::getEquipmentId, equipmentId);
+        testWrapper.orderByDesc(EquipmentTest::getTestTime);
+        List<EquipmentTest> testList = equipmentTestMapper.selectList(testWrapper);
+        result.put("testList", testList);
+
+        return result;
+    }
+
+    @Override
+    public List<EquipmentBase> getEquipmentByPoint(String pointId) {
+        LambdaQueryWrapper<EquipmentPointRel> relWrapper = new LambdaQueryWrapper<>();
+        relWrapper.eq(EquipmentPointRel::getPointId, pointId);
+        List<EquipmentPointRel> relList = equipmentPointRelMapper.selectList(relWrapper);
+
+        if (relList.isEmpty()) {
+            return new ArrayList<>();
+        }
+
+        List<String> equipmentIds = relList.stream()
+                .map(EquipmentPointRel::getEquipmentId)
+                .collect(Collectors.toList());
+
+        return this.listByIds(equipmentIds);
+    }
 }

+ 26 - 0
pipe-network-service/zksy-system/src/main/java/com/zksy/base/service/impl/EquipmentStatusServiceImpl.java

@@ -10,16 +10,20 @@ import com.zksy.base.mapper.EquipmentStatusMapper;
 import com.zksy.base.service.EquipmentStatusService;
 import com.zksy.common.core.domain.entity.SysUser;
 import com.zksy.common.exception.ServiceException;
+import com.zksy.manhole.dto.in.EquipmentStatusInDTO;
 import com.zksy.system.service.ISysUserService;
+import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
+import java.util.Date;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
 import java.util.stream.Collectors;
 
+@Slf4j
 @Service
 public class EquipmentStatusServiceImpl extends ServiceImpl<EquipmentStatusMapper, EquipmentStatus>
         implements EquipmentStatusService {
@@ -189,4 +193,26 @@ public class EquipmentStatusServiceImpl extends ServiceImpl<EquipmentStatusMappe
         //更新
         return this.updateById(entity);
     }
+
+    /**
+     * 修改设备状态
+     * @param inDTO
+     * @return
+     */
+    @Override
+    public boolean updateDeviceStatus(EquipmentStatusInDTO inDTO) {
+        log.info("修改设备状态-入参:{}", inDTO);
+        //校验状态值合法性
+        Integer status = inDTO.getCurrentStatus();
+        if (status != null && (status < 1 || status > 5)) {
+            throw new ServiceException("设备状态值无效(必须为1-5):" + status);
+        }
+        //校验当前状态记录是否存在
+        boolean update = this.lambdaUpdate()
+                .set(EquipmentStatus::getCurrentStatus, inDTO.getCurrentStatus())
+                .set(EquipmentStatus::getStatusUpdateTime, new Date())
+                .eq(EquipmentStatus::getEquipmentId, inDTO.getEquipmentId())
+                .update();
+        return update;
+    }
 }

+ 39 - 0
pipe-network-service/zksy-system/src/main/java/com/zksy/base/warning/domain/AlarmWarningRel.java

@@ -0,0 +1,39 @@
+package com.zksy.base.warning.domain;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.time.LocalDateTime;
+
+@TableName("alarm_warning_rel")
+@Api("报警预警关联表")
+@Data
+public class AlarmWarningRel implements Serializable {
+
+    @TableId(value = "rel_id", type = IdType.ASSIGN_UUID)
+    @ApiModelProperty("关联ID")
+    private String relId;
+
+    @TableField("warning_id")
+    @ApiModelProperty("预警ID")
+    private String warningId;
+
+    @TableField("alarm_id")
+    @ApiModelProperty("报警ID")
+    private String alarmId;
+
+    @TableField("create_time")
+    @ApiModelProperty("创建时间")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private LocalDateTime createTime;
+
+    @TableField(exist = false)
+    private static final long serialVersionUID = 1L;
+}

+ 110 - 0
pipe-network-service/zksy-system/src/main/java/com/zksy/base/warning/domain/EarlyWarning.java

@@ -0,0 +1,110 @@
+package com.zksy.base.warning.domain;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+
+@TableName("early_warning")
+@Api(value = "预警信息")
+@Data
+public class EarlyWarning implements Serializable {
+
+    @TableId(value = "warning_id", type = IdType.ASSIGN_UUID)
+    @ApiModelProperty("预警ID")
+    private String warningId;
+
+    @TableField("warning_no")
+    @ApiModelProperty("预警编号")
+    private String warningNo;
+
+    @TableField("warning_name")
+    @ApiModelProperty("预警名称")
+    private String warningName;
+
+    @TableField("warning_type")
+    @ApiModelProperty("预警类型")
+    private String warningType;
+
+    @TableField("warning_level")
+    @ApiModelProperty("预警级别")
+    private String warningLevel;
+
+    @TableField("warning_special")
+    @ApiModelProperty("预警专项")
+    private String warningSpecial;
+
+    @TableField("location")
+    @ApiModelProperty("预警位置")
+    private String location;
+
+    @TableField("longitude")
+    @ApiModelProperty("经度")
+    private BigDecimal longitude;
+
+    @TableField("latitude")
+    @ApiModelProperty("纬度")
+    private BigDecimal latitude;
+
+    @TableField("ownership_unit")
+    @ApiModelProperty("权属单位")
+    private String ownershipUnit;
+
+    @TableField("publisher")
+    @ApiModelProperty("发布人")
+    private String publisher;
+
+    @TableField("publish_time")
+    @ApiModelProperty("发布时间")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private LocalDateTime publishTime;
+
+    @TableField("handler")
+    @ApiModelProperty("处置人")
+    private String handler;
+
+    @TableField("status")
+    @ApiModelProperty("状态")
+    private String status;
+
+    @TableField("warning_content")
+    @ApiModelProperty("预警内容描述")
+    private String warningContent;
+
+    @TableField("process_instance_id")
+    @ApiModelProperty("工作流实例ID")
+    private String processInstanceId;
+
+    @TableField("create_by")
+    @ApiModelProperty("创建人")
+    private String createBy;
+
+    @TableField("create_time")
+    @ApiModelProperty("创建时间")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private LocalDateTime createTime;
+
+    @TableField("update_by")
+    @ApiModelProperty("更新人")
+    private String updateBy;
+
+    @TableField("update_time")
+    @ApiModelProperty("更新时间")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private LocalDateTime updateTime;
+
+    @TableField("remark")
+    @ApiModelProperty("备注")
+    private String remark;
+
+    @TableField(exist = false)
+    private static final long serialVersionUID = 1L;
+}

+ 100 - 0
pipe-network-service/zksy-system/src/main/java/com/zksy/base/warning/domain/WarningArchive.java

@@ -0,0 +1,100 @@
+package com.zksy.base.warning.domain;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.time.LocalDateTime;
+
+@TableName("warning_archive")
+@Api(value = "预警归档")
+@Data
+public class WarningArchive implements Serializable {
+
+    @TableId(value = "archive_id", type = IdType.ASSIGN_UUID)
+    @ApiModelProperty("归档ID")
+    private String archiveId;
+
+    @TableField("warning_id")
+    @ApiModelProperty("预警ID")
+    private String warningId;
+
+    @TableField("archive_no")
+    @ApiModelProperty("归档编号")
+    private String archiveNo;
+
+    @TableField("warning_no")
+    @ApiModelProperty("预警编号")
+    private String warningNo;
+
+    @TableField("warning_name")
+    @ApiModelProperty("预警名称")
+    private String warningName;
+
+    @TableField("warning_type")
+    @ApiModelProperty("预警类型")
+    private String warningType;
+
+    @TableField("warning_level")
+    @ApiModelProperty("预警级别")
+    private String warningLevel;
+
+    @TableField("location")
+    @ApiModelProperty("预警位置")
+    private String location;
+
+    @TableField("longitude")
+    @ApiModelProperty("经度")
+    private Double longitude;
+
+    @TableField("latitude")
+    @ApiModelProperty("纬度")
+    private Double latitude;
+
+    @TableField("ownership_unit")
+    @ApiModelProperty("权属单位")
+    private String ownershipUnit;
+
+    @TableField("publisher")
+    @ApiModelProperty("发布人")
+    private String publisher;
+
+    @TableField("publish_time")
+    @ApiModelProperty("发布时间")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private LocalDateTime publishTime;
+
+    @TableField("handler")
+    @ApiModelProperty("处置人")
+    private String handler;
+
+    @TableField("warning_content")
+    @ApiModelProperty("预警内容")
+    private String warningContent;
+
+    @TableField("archive_content")
+    @ApiModelProperty("归档内容")
+    private String archiveContent;
+
+    @TableField("archive_status")
+    @ApiModelProperty("归档状态")
+    private String archiveStatus;
+
+    @TableField("create_by")
+    @ApiModelProperty("创建人")
+    private String createBy;
+
+    @TableField("create_time")
+    @ApiModelProperty("创建时间")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private LocalDateTime createTime;
+
+    @TableField(exist = false)
+    private static final long serialVersionUID = 1L;
+}

+ 55 - 0
pipe-network-service/zksy-system/src/main/java/com/zksy/base/warning/domain/WarningAttachment.java

@@ -0,0 +1,55 @@
+package com.zksy.base.warning.domain;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.time.LocalDateTime;
+
+@TableName("warning_attachment")
+@Api("预警附件")
+@Data
+public class WarningAttachment implements Serializable {
+
+    @TableId(value = "attachment_id", type = IdType.ASSIGN_UUID)
+    @ApiModelProperty("附件ID")
+    private String attachmentId;
+
+    @TableField("warning_id")
+    @ApiModelProperty("预警ID")
+    private String warningId;
+
+    @TableField("attachment_name")
+    @ApiModelProperty("附件名称")
+    private String attachmentName;
+
+    @TableField("attachment_url")
+    @ApiModelProperty("附件地址")
+    private String attachmentUrl;
+
+    @TableField("attachment_type")
+    @ApiModelProperty("附件类型")
+    private String attachmentType;
+
+    @TableField("attachment_size")
+    @ApiModelProperty("附件大小(字节)")
+    private Long attachmentSize;
+
+    @TableField("create_by")
+    @ApiModelProperty("上传人")
+    private String createBy;
+
+    @TableField("create_time")
+    @ApiModelProperty("上传时间")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private LocalDateTime createTime;
+
+    @TableField(exist = false)
+    private static final long serialVersionUID = 1L;
+}

+ 67 - 0
pipe-network-service/zksy-system/src/main/java/com/zksy/base/warning/domain/WarningDisposal.java

@@ -0,0 +1,67 @@
+package com.zksy.base.warning.domain;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.time.LocalDateTime;
+
+@TableName("warning_disposal")
+@Api(value = "预警处置记录")
+@Data
+public class WarningDisposal implements Serializable {
+
+    @TableId(value = "disposal_id", type = IdType.ASSIGN_UUID)
+    @ApiModelProperty("处置记录ID")
+    private String disposalId;
+
+    @TableField("warning_id")
+    @ApiModelProperty("预警ID")
+    private String warningId;
+
+    @TableField("disposal_type")
+    @ApiModelProperty("处置类型")
+    private String disposalType;
+
+    @TableField("old_level")
+    @ApiModelProperty("原预警级别")
+    private String oldLevel;
+
+    @TableField("new_level")
+    @ApiModelProperty("新预警级别")
+    private String newLevel;
+
+    @TableField("disposal_user")
+    @ApiModelProperty("处置人")
+    private String disposalUser;
+
+    @TableField("disposal_content")
+    @ApiModelProperty("处置内容/意见")
+    private String disposalContent;
+
+    @TableField("supervision_user")
+    @ApiModelProperty("督办人员")
+    private String supervisionUser;
+
+    @TableField("supervision_content")
+    @ApiModelProperty("督办意见")
+    private String supervisionContent;
+
+    @TableField("notification_type")
+    @ApiModelProperty("通知方式")
+    private String notificationType;
+
+    @TableField("create_time")
+    @ApiModelProperty("处置时间")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private LocalDateTime createTime;
+
+    @TableField(exist = false)
+    private static final long serialVersionUID = 1L;
+}

+ 82 - 0
pipe-network-service/zksy-system/src/main/java/com/zksy/base/warning/domain/WarningItem.java

@@ -0,0 +1,82 @@
+package com.zksy.base.warning.domain;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.time.LocalDateTime;
+
+@TableName("warning_item")
+@Data
+public class WarningItem implements Serializable {
+
+    @TableId(value = "item_id", type = IdType.ASSIGN_UUID)
+    @ApiModelProperty("事项ID")
+    private String itemId;
+
+    @TableField("item_code")
+    @ApiModelProperty("事项编码")
+    private String itemCode;
+
+    @TableField("item_name")
+    @ApiModelProperty("事项名称")
+    private String itemName;
+
+    @TableField("warning_type")
+    @ApiModelProperty("预警类型")
+    private String warningType;
+
+    @TableField("warning_level")
+    @ApiModelProperty("预警级别")
+    private String warningLevel;
+
+    @TableField("warning_special")
+    @ApiModelProperty("预警专项")
+    private String warningSpecial;
+
+    @TableField("industry")
+    @ApiModelProperty("所属行业")
+    private String industry;
+
+    @TableField("duration")
+    @ApiModelProperty("预警时长(小时)")
+    private Integer duration;
+
+    @TableField("link_config")
+    @ApiModelProperty("预警环节配置")
+    private String linkConfig;
+
+    @TableField("status")
+    @ApiModelProperty("状态(ENABLED-启用 DISABLED-禁用 INVALID-作废)")
+    private String status;
+
+    @TableField("create_by")
+    @ApiModelProperty("创建人")
+    private String createBy;
+
+    @TableField("create_time")
+    @ApiModelProperty("创建时间")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private LocalDateTime createTime;
+
+    @TableField("update_by")
+    @ApiModelProperty("更新人")
+    private String updateBy;
+
+    @TableField("update_time")
+    @ApiModelProperty("更新时间")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private LocalDateTime updateTime;
+
+    @TableField("remark")
+    @ApiModelProperty("备注")
+    private String remark;
+
+    @TableField(exist = false)
+    private static final long serialVersionUID = 1L;
+}

+ 70 - 0
pipe-network-service/zksy-system/src/main/java/com/zksy/base/warning/domain/WarningReason.java

@@ -0,0 +1,70 @@
+package com.zksy.base.warning.domain;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.time.LocalDateTime;
+
+@TableName("warning_reason")
+@Data
+public class WarningReason implements Serializable {
+
+    @TableId(value = "reason_id", type = IdType.ASSIGN_UUID)
+    @ApiModelProperty("原因ID")
+    private String reasonId;
+
+    @TableField("reason_code")
+    @ApiModelProperty("原因编码")
+    private String reasonCode;
+
+    @TableField("reason_name")
+    @ApiModelProperty("原因名称")
+    private String reasonName;
+
+    @TableField("warning_type")
+    @ApiModelProperty("预警类型")
+    private String warningType;
+
+    @TableField("warning_level")
+    @ApiModelProperty("预警级别")
+    private String warningLevel;
+
+    @TableField("description")
+    @ApiModelProperty("原因描述")
+    private String description;
+
+    @TableField("sort_order")
+    @ApiModelProperty("排序")
+    private Integer sortOrder;
+
+    @TableField("status")
+    @ApiModelProperty("状态(0-正常 1-停用)")
+    private String status;
+
+    @TableField("create_by")
+    @ApiModelProperty("创建人")
+    private String createBy;
+
+    @TableField("create_time")
+    @ApiModelProperty("创建时间")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private LocalDateTime createTime;
+
+    @TableField("update_by")
+    @ApiModelProperty("更新人")
+    private String updateBy;
+
+    @TableField("update_time")
+    @ApiModelProperty("更新时间")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private LocalDateTime updateTime;
+
+    @TableField(exist = false)
+    private static final long serialVersionUID = 1L;
+}

+ 18 - 0
pipe-network-service/zksy-system/src/main/java/com/zksy/base/warning/domain/WarningSaveDTO.java

@@ -0,0 +1,18 @@
+package com.zksy.base.warning.domain;
+
+import lombok.Data;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.util.List;
+
+@Data
+public class WarningSaveDTO {
+    // 预警实体(JSON对象)
+    private EarlyWarning warning;
+    
+    // 数报警id
+    private List<String> alarmIds;
+
+    // 文件
+    private List<MultipartFile> files;
+}

+ 60 - 0
pipe-network-service/zksy-system/src/main/java/com/zksy/base/warning/domain/WarningTodo.java

@@ -0,0 +1,60 @@
+package com.zksy.base.warning.domain;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.time.LocalDateTime;
+
+@TableName("warning_todo")
+@Api(tags = "预警待办")
+@Data
+public class WarningTodo implements Serializable {
+
+    @TableId(value = "todo_id", type = IdType.ASSIGN_UUID)
+    @ApiModelProperty("待办ID")
+    private String todoId;
+
+    @TableField("warning_id")
+    @ApiModelProperty("预警ID")
+    private String warningId;
+
+    @TableField("user_id")
+    @ApiModelProperty("用户ID")
+    private String userId;
+
+    @TableField("user_name")
+    @ApiModelProperty("用户姓名")
+    private String userName;
+
+    @TableField("todo_type")
+    @ApiModelProperty("待办类型")
+    private String todoType;
+
+    @TableField("read_status")
+    @ApiModelProperty("阅读状态")
+    private String readStatus;
+
+    @TableField("task_name")
+    @ApiModelProperty("任务名称")
+    private String taskName;
+
+    @TableField("create_time")
+    @ApiModelProperty("创建时间")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private LocalDateTime createTime;
+
+    @TableField("complete_time")
+    @ApiModelProperty("完成时间")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private LocalDateTime completeTime;
+
+    @TableField(exist = false)
+    private static final long serialVersionUID = 1L;
+}

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

@@ -0,0 +1,15 @@
+package com.zksy.base.warning.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.zksy.base.warning.domain.AlarmWarningRel;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+import java.util.Map;
+
+@Mapper
+public interface AlarmWarningRelMapper extends BaseMapper<AlarmWarningRel> {
+
+    List<Map<String, Object>> selectAlarmListByWarningId(@Param("warningId") String warningId);
+}

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

@@ -0,0 +1,30 @@
+package com.zksy.base.warning.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.zksy.base.warning.domain.EarlyWarning;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+import java.time.LocalDateTime;
+import java.util.List;
+import java.util.Map;
+
+@Mapper
+public interface EarlyWarningMapper extends BaseMapper<EarlyWarning> {
+
+    IPage<Map<String, Object>> selectWarningList(Page<?> page, @Param("warningName") String warningName, @Param("warningType") String warningType, @Param("warningLevel") String warningLevel, @Param("status") String status);
+
+    IPage<Map<String, Object>> searchWarnings(Page<?> page, @Param("warningName") String warningName, @Param("warningNo") String warningNo, @Param("warningType") String warningType, @Param("warningLevel") String warningLevel, @Param("status") String status, @Param("location") String location, @Param("publisher") String publisher, @Param("ownershipUnit") String ownershipUnit, @Param("startTime") LocalDateTime startTime, @Param("endTime") LocalDateTime endTime);
+
+    IPage<Map<String, Object>> selectTodoList(Page<?> page, @Param("userId") String userId, @Param("todoType") String todoType, @Param("warningName") String warningName);
+
+    IPage<Map<String, Object>> selectProcessingWarnings(Page<?> page, @Param("warningType") String warningType, @Param("warningLevel") String warningLevel);
+
+    IPage<Map<String, Object>> selectCompletedWarnings(Page<?> page, @Param("warningType") String warningType, @Param("warningLevel") String warningLevel, @Param("startTime") LocalDateTime startTime, @Param("endTime") LocalDateTime endTime);
+
+    Map<String, Object> selectWarningDetail(@Param("warningId") String warningId);
+
+    List<Map<String, Object>> selectStatistics();
+}

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

@@ -0,0 +1,9 @@
+package com.zksy.base.warning.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.zksy.base.warning.domain.WarningArchive;
+import org.apache.ibatis.annotations.Mapper;
+
+@Mapper
+public interface WarningArchiveMapper extends BaseMapper<WarningArchive> {
+}

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

@@ -0,0 +1,9 @@
+package com.zksy.base.warning.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.zksy.base.warning.domain.WarningAttachment;
+import org.apache.ibatis.annotations.Mapper;
+
+@Mapper
+public interface WarningAttachmentMapper extends BaseMapper<WarningAttachment> {
+}

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

@@ -0,0 +1,15 @@
+package com.zksy.base.warning.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.zksy.base.warning.domain.WarningDisposal;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+import java.util.Map;
+
+@Mapper
+public interface WarningDisposalMapper extends BaseMapper<WarningDisposal> {
+
+    List<Map<String, Object>> selectDisposalList(@Param("warningId") String warningId);
+}

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

@@ -0,0 +1,9 @@
+package com.zksy.base.warning.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.zksy.base.warning.domain.WarningItem;
+import org.apache.ibatis.annotations.Mapper;
+
+@Mapper
+public interface WarningItemMapper extends BaseMapper<WarningItem> {
+}

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

@@ -0,0 +1,9 @@
+package com.zksy.base.warning.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.zksy.base.warning.domain.WarningReason;
+import org.apache.ibatis.annotations.Mapper;
+
+@Mapper
+public interface WarningReasonMapper extends BaseMapper<WarningReason> {
+}

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

@@ -0,0 +1,9 @@
+package com.zksy.base.warning.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.zksy.base.warning.domain.WarningTodo;
+import org.apache.ibatis.annotations.Mapper;
+
+@Mapper
+public interface WarningTodoMapper extends BaseMapper<WarningTodo> {
+}

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

@@ -0,0 +1,78 @@
+package com.zksy.base.warning.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.base.warning.domain.EarlyWarning;
+import com.zksy.base.warning.domain.WarningArchive;
+import com.zksy.base.warning.domain.WarningDisposal;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.time.LocalDateTime;
+import java.util.List;
+import java.util.Map;
+
+public interface EarlyWarningService extends IService<EarlyWarning> {
+
+    IPage<Map<String, Object>> getWarningList(Page<?> page, String warningName, String warningType, String warningLevel, String status);
+
+    IPage<Map<String, Object>> searchWarnings(Page<?> page, String warningName, String warningNo, String warningType, String warningLevel, String status, String location, String publisher, String ownershipUnit, LocalDateTime startTime, LocalDateTime endTime);
+
+    IPage<Map<String, Object>> getTodoList(Page<?> page, String userId, String todoType, String warningName);
+
+    Map<String, Object> getWarningDetail(String warningId);
+
+    Map<String, Object> getWarningFullDetail(String warningId);
+
+    boolean saveWarning(EarlyWarning warning, List<String> alarmIds, List<MultipartFile> files);
+
+    boolean updateWarning(EarlyWarning warning, List<MultipartFile> files);
+
+    boolean deleteWarning(String warningId);
+
+    boolean deleteBatchWarning(List<String> warningIds);
+
+    boolean publishWarning(String warningId, String disposalUser);
+
+    boolean upgradeWarning(String warningId, String newLevel, String disposalUser, String disposalContent);
+
+    boolean resolveWarning(String warningId, String disposalUser, String disposalContent);
+
+    boolean returnWarning(String warningId, String disposalUser, String disposalContent);
+
+    boolean supervisionWarning(String warningId, String supervisionUser, String supervisionContent, String notificationType, String notificationContent, String attachmentUrl);
+
+    boolean addLeaderInstruction(String warningId, String leaderName, String instructionContent, String smsReceivers);
+
+    boolean linkAlarms(String warningId, List<String> alarmIds);
+
+    List<Map<String, Object>> getLinkedAlarms(String warningId);
+
+    List<Map<String, Object>> getDisposalList(String warningId);
+
+    List<Map<String, Object>> getDisposalHistory(String warningId);
+
+    IPage<Map<String, Object>> getProcessingWarnings(Page<?> page, String warningType, String warningLevel);
+
+    IPage<Map<String, Object>> getCompletedWarnings(Page<?> page, String warningType, String warningLevel, LocalDateTime startTime, LocalDateTime endTime);
+
+    List<Map<String, Object>> getAttachments(String warningId);
+
+    Map<String, Object> getStatistics();
+
+    Map<String, Object> getDashboardStatistics();
+
+    List<Map<String, Object>> getTypeConfigList();
+
+    WarningArchive getArchiveByWarningId(String warningId);
+
+    IPage<WarningArchive> getArchiveList(Page<WarningArchive> page, String warningName, String warningType, String warningLevel, LocalDateTime startTime, LocalDateTime endTime);
+
+    List<WarningDisposal> getDisposalProcess(String warningId);
+
+    Map<String, Object> getProcessDiagram(String warningId);
+
+    Map<String, Object> getDisposalDetail(String disposalId);
+
+    Map<String, Object> getProcessStatistics(String warningId);
+}

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

@@ -0,0 +1,768 @@
+package com.zksy.base.warning.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.base.warning.domain.*;
+import com.zksy.base.warning.mapper.*;
+import com.zksy.base.warning.service.EarlyWarningService;
+import com.zksy.common.config.ZksyConfig;
+import com.zksy.common.core.domain.entity.SysDictData;
+import com.zksy.common.utils.DictUtils;
+import com.zksy.common.utils.file.FileUploadUtils;
+import com.zksy.common.utils.file.FileUtils;
+import com.zksy.service.MinioFileStorageService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+import java.util.*;
+
+@Service
+public class EarlyWarningServiceImpl extends ServiceImpl<EarlyWarningMapper, EarlyWarning>
+        implements EarlyWarningService {
+
+    @Autowired
+    private EarlyWarningMapper earlyWarningMapper;
+    @Autowired
+    private AlarmWarningRelMapper alarmWarningRelMapper;
+    @Autowired
+    private WarningAttachmentMapper warningAttachmentMapper;
+    @Autowired
+    private WarningDisposalMapper warningDisposalMapper;
+    @Autowired
+    private WarningTodoMapper warningTodoMapper;
+
+    @Autowired
+    private WarningArchiveMapper warningArchiveMapper;
+    @Autowired
+    private MinioFileStorageService minioFileStorageService;
+
+    @Override
+    public IPage<Map<String, Object>> getWarningList(Page<?> page, String warningName, String warningType, String warningLevel, String status) {
+        return earlyWarningMapper.selectWarningList(page, warningName, warningType, warningLevel, status);
+    }
+
+    @Override
+    public IPage<Map<String, Object>> searchWarnings(Page<?> page, String warningName, String warningNo, String warningType, String warningLevel, String status, String location, String publisher, String ownershipUnit, LocalDateTime startTime, LocalDateTime endTime) {
+        return earlyWarningMapper.searchWarnings(page, warningName, warningNo, warningType, warningLevel, status, location, publisher, ownershipUnit, startTime, endTime);
+    }
+
+    @Override
+    public IPage<Map<String, Object>> getTodoList(Page<?> page, String userId, String todoType, String warningName) {
+        return earlyWarningMapper.selectTodoList(page, userId, todoType, warningName);
+    }
+
+    @Override
+    public Map<String, Object> getWarningDetail(String warningId) {
+        Map<String, Object> detail = earlyWarningMapper.selectWarningDetail(warningId);
+        if (detail != null) {
+            detail.put("attachmentList", getAttachmentList(warningId));
+            detail.put("disposalList", getDisposalList(warningId));
+            detail.put("alarmList", getLinkedAlarms(warningId));
+        }
+        return detail;
+    }
+
+    @Override
+    public Map<String, Object> getWarningFullDetail(String warningId) {
+        Map<String, Object> result = new HashMap<>();
+        Map<String, Object> basicInfo = earlyWarningMapper.selectWarningDetail(warningId);
+        if (basicInfo == null) {
+            return null;
+        }
+
+        result.put("basicInfo", basicInfo);
+        result.put("gisLocation", getGisLocation(basicInfo));
+        result.put("disposalHistory", getDisposalHistory(warningId));
+        result.put("attachmentList", getAttachmentList(warningId));
+        result.put("alarmList", getLinkedAlarms(warningId));
+        result.put("electronicArchive", generateElectronicArchive(basicInfo));
+
+        return result;
+    }
+
+    private Map<String, Object> getGisLocation(Map<String, Object> warningInfo) {
+        Map<String, Object> gis = new HashMap<>();
+        gis.put("longitude", warningInfo.get("longitude"));
+        gis.put("latitude", warningInfo.get("latitude"));
+        gis.put("location", warningInfo.get("location"));
+        return gis;
+    }
+
+    private Map<String, Object> generateElectronicArchive(Map<String, Object> warningInfo) {
+        String warningId = (String) warningInfo.get("warningId");
+        
+        // 先查询是否已存在归档记录
+        LambdaQueryWrapper<WarningArchive> wrapper = new LambdaQueryWrapper<>();
+        wrapper.eq(WarningArchive::getWarningId, warningId);
+        WarningArchive existingArchive = warningArchiveMapper.selectOne(wrapper);
+        
+        if (existingArchive != null) {
+            // 如果已存在,直接返回
+            Map<String, Object> archive = new HashMap<>();
+            archive.put("archiveId", existingArchive.getArchiveId());
+            archive.put("archiveNo", existingArchive.getArchiveNo());
+            archive.put("createTime", existingArchive.getCreateTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
+            archive.put("archiveContent", existingArchive.getArchiveContent());
+            archive.put("archiveStatus", existingArchive.getArchiveStatus());
+            return archive;
+        }
+        
+        // 如果不存在,创建新归档
+        WarningArchive archive = new WarningArchive();
+        archive.setWarningId(warningId);
+        archive.setArchiveNo("EA_" + warningInfo.get("warningNo"));
+        archive.setWarningNo((String) warningInfo.get("warningNo"));
+        archive.setWarningName((String) warningInfo.get("warningName"));
+        archive.setWarningType((String) warningInfo.get("warningType"));
+        archive.setWarningLevel((String) warningInfo.get("warningLevel"));
+        archive.setLocation((String) warningInfo.get("location"));
+        archive.setLongitude(warningInfo.get("longitude") != null ? ((Number) warningInfo.get("longitude")).doubleValue() : null);
+        archive.setLatitude(warningInfo.get("latitude") != null ? ((Number) warningInfo.get("latitude")).doubleValue() : null);
+        archive.setOwnershipUnit((String) warningInfo.get("ownershipUnit"));
+        archive.setPublisher((String) warningInfo.get("publisher"));
+        archive.setPublishTime(warningInfo.get("publishTime") instanceof LocalDateTime ? (LocalDateTime) warningInfo.get("publishTime") : null);
+        archive.setHandler((String) warningInfo.get("handler"));
+        archive.setWarningContent((String) warningInfo.get("warningContent"));
+        archive.setArchiveContent((String) warningInfo.get("warningContent"));
+        archive.setArchiveStatus("已归档");
+        archive.setCreateTime(LocalDateTime.now());
+        
+        warningArchiveMapper.insert(archive);
+        
+        Map<String, Object> result = new HashMap<>();
+        result.put("archiveId", archive.getArchiveId());
+        result.put("archiveNo", archive.getArchiveNo());
+        result.put("createTime", archive.getCreateTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
+        result.put("archiveContent", archive.getArchiveContent());
+        result.put("archiveStatus", archive.getArchiveStatus());
+        return result;
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean saveWarning(EarlyWarning warning, List<String> alarmIds, List<MultipartFile> files) {
+        String warningNo = "WJ" + LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"));
+        warning.setWarningNo(warningNo);
+        warning.setStatus("DRAFT");
+        warning.setCreateTime(LocalDateTime.now());
+        warning.setUpdateTime(LocalDateTime.now());
+
+        boolean result = save(warning);
+        if (result) {
+            if (alarmIds != null && !alarmIds.isEmpty()) {
+                linkAlarms(warning.getWarningId(), alarmIds);
+            }
+            if (files != null && !files.isEmpty()) {
+                saveAttachments(warning.getWarningId(), files);
+            }
+        }
+        return result;
+    }
+
+    /**
+     * 保存附件
+     */
+    private void saveAttachments(String warningId, List<MultipartFile> files) {
+        try {
+            for (MultipartFile file : files) {
+                String path = minioFileStorageService.uploadFile(file, "warning");
+                // 上传文件
+                String fileName = path.substring(path.lastIndexOf("/") + 1);
+                // 保存附件信息
+                WarningAttachment attachment = new WarningAttachment();
+                attachment.setWarningId(warningId);
+                attachment.setAttachmentName(fileName);
+                attachment.setAttachmentUrl(path);
+                attachment.setAttachmentType(file.getContentType());
+                attachment.setAttachmentSize(file.getSize());
+                attachment.setCreateTime(LocalDateTime.now());
+                warningAttachmentMapper.insert(attachment);
+            }
+        } catch (Exception e) {
+            throw new RuntimeException("附件保存失败", e);
+        }
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean updateWarning(EarlyWarning warning, List<MultipartFile> files) {
+        warning.setUpdateTime(LocalDateTime.now());
+        boolean result = updateById(warning);
+        if (result && files != null && !files.isEmpty()) {
+            saveAttachments(warning.getWarningId(), files);
+        }
+        return result;
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean deleteWarning(String warningId) {
+        // 先查询附件列表,删除物理文件
+        List<WarningAttachment> attachments = warningAttachmentMapper.selectList(
+                new LambdaQueryWrapper<WarningAttachment>()
+                        .eq(WarningAttachment::getWarningId, warningId)
+        );
+        for (WarningAttachment attachment : attachments) {
+            String attachmentUrl = attachment.getAttachmentUrl();
+            if (attachmentUrl != null && !attachmentUrl.isEmpty()) {
+                // 删除minio文件
+                minioFileStorageService.deleteFile(attachmentUrl);
+            }
+        }
+
+        // 删除关联数据
+        LambdaQueryWrapper<AlarmWarningRel> relWrapper = new LambdaQueryWrapper<>();
+        relWrapper.eq(AlarmWarningRel::getWarningId, warningId);
+        alarmWarningRelMapper.delete(relWrapper);
+
+        LambdaQueryWrapper<WarningAttachment> attachmentWrapper = new LambdaQueryWrapper<>();
+        attachmentWrapper.eq(WarningAttachment::getWarningId, warningId);
+        warningAttachmentMapper.delete(attachmentWrapper);
+
+        LambdaQueryWrapper<WarningDisposal> disposalWrapper = new LambdaQueryWrapper<>();
+        disposalWrapper.eq(WarningDisposal::getWarningId, warningId);
+        warningDisposalMapper.delete(disposalWrapper);
+
+        LambdaQueryWrapper<WarningTodo> todoWrapper = new LambdaQueryWrapper<>();
+        todoWrapper.eq(WarningTodo::getWarningId, warningId);
+        warningTodoMapper.delete(todoWrapper);
+
+        LambdaQueryWrapper<WarningArchive> archiveWrapper = new LambdaQueryWrapper<>();
+        archiveWrapper.eq(WarningArchive::getWarningId, warningId);
+        warningArchiveMapper.delete(archiveWrapper);
+
+        // 删除主表记录
+        return removeById(warningId);
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean deleteBatchWarning(List<String> warningIds) {
+        for (String warningId : warningIds) {
+            deleteWarning(warningId);
+        }
+        return true;
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean publishWarning(String warningId, String disposalUser) {
+        EarlyWarning warning = getById(warningId);
+        if (warning == null) return false;
+
+        warning.setStatus("PENDING");
+        warning.setPublishTime(LocalDateTime.now());
+        warning.setUpdateTime(LocalDateTime.now());
+
+        boolean result = updateById(warning);
+
+        if (result) {
+            addDisposalRecord(warningId, "RELEASE", null, null, disposalUser, "系统发布预警信息");
+            createTodo(warningId, warning.getHandler(), "待办预警", "TODO");
+        }
+
+        return result;
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean upgradeWarning(String warningId, String newLevel, String disposalUser, String disposalContent) {
+        EarlyWarning warning = getById(warningId);
+        if (warning == null) return false;
+
+        String oldLevel = warning.getWarningLevel();
+        warning.setWarningLevel(newLevel);
+        warning.setUpdateTime(LocalDateTime.now());
+
+        boolean result = updateById(warning);
+        if (result) {
+            addDisposalRecord(warningId, "UPGRADE", oldLevel, newLevel, disposalUser, disposalContent);
+        }
+        return result;
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean resolveWarning(String warningId, String disposalUser, String disposalContent) {
+        EarlyWarning warning = getById(warningId);
+        if (warning == null) return false;
+
+        warning.setStatus("CLOSED");
+        warning.setUpdateTime(LocalDateTime.now());
+
+        boolean result = updateById(warning);
+        if (result) {
+            addDisposalRecord(warningId, "RESOLVE", null, null, disposalUser, disposalContent);
+            completeTodo(warningId);
+            
+            // 解除预警时自动创建归档
+            Map<String, Object> warningDetail = earlyWarningMapper.selectWarningDetail(warningId);
+            if (warningDetail != null) {
+                generateElectronicArchive(warningDetail);
+            }
+        }
+        return result;
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean returnWarning(String warningId, String disposalUser, String disposalContent) {
+        EarlyWarning warning = getById(warningId);
+        if (warning == null) return false;
+
+        warning.setStatus("PENDING");
+        warning.setUpdateTime(LocalDateTime.now());
+
+        boolean result = updateById(warning);
+        if (result) {
+            addDisposalRecord(warningId, "RETURN", null, null, disposalUser, disposalContent);
+        }
+        return result;
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean supervisionWarning(String warningId, String supervisionUser, String supervisionContent, String notificationType, String notificationContent, String attachmentUrl) {
+        WarningDisposal disposal = new WarningDisposal();
+        disposal.setWarningId(warningId);
+        disposal.setDisposalType("SUPERVISION");
+        disposal.setDisposalUser(supervisionUser);
+        disposal.setDisposalContent(supervisionContent);
+        disposal.setSupervisionUser(supervisionUser);
+        disposal.setSupervisionContent(supervisionContent);
+        disposal.setNotificationType(notificationType);
+        disposal.setCreateTime(LocalDateTime.now());
+
+        return warningDisposalMapper.insert(disposal) > 0;
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean addLeaderInstruction(String warningId, String leaderName, String instructionContent, String smsReceivers) {
+        WarningDisposal disposal = new WarningDisposal();
+        disposal.setWarningId(warningId);
+        disposal.setDisposalType("INSTRUCTION");
+        disposal.setDisposalUser(leaderName);
+        disposal.setDisposalContent(instructionContent);
+        disposal.setCreateTime(LocalDateTime.now());
+
+        return warningDisposalMapper.insert(disposal) > 0;
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean linkAlarms(String warningId, List<String> alarmIds) {
+        LambdaQueryWrapper<AlarmWarningRel> wrapper = new LambdaQueryWrapper<>();
+        wrapper.eq(AlarmWarningRel::getWarningId, warningId);
+        alarmWarningRelMapper.delete(wrapper);
+
+        if (alarmIds != null && !alarmIds.isEmpty()) {
+            for (String alarmId : alarmIds) {
+                AlarmWarningRel rel = new AlarmWarningRel();
+                rel.setWarningId(warningId);
+                rel.setAlarmId(alarmId);
+                rel.setCreateTime(LocalDateTime.now());
+                alarmWarningRelMapper.insert(rel);
+            }
+        }
+        return true;
+    }
+
+    @Override
+    public List<Map<String, Object>> getLinkedAlarms(String warningId) {
+        return alarmWarningRelMapper.selectAlarmListByWarningId(warningId);
+    }
+
+    @Override
+    public List<Map<String, Object>> getDisposalList(String warningId) {
+        return warningDisposalMapper.selectDisposalList(warningId);
+    }
+
+    @Override
+    public List<Map<String, Object>> getDisposalHistory(String warningId) {
+        return warningDisposalMapper.selectDisposalList(warningId);
+    }
+
+    @Override
+    public IPage<Map<String, Object>> getProcessingWarnings(Page<?> page, String warningType, String warningLevel) {
+        return earlyWarningMapper.selectProcessingWarnings(page, warningType, warningLevel);
+    }
+
+    @Override
+    public IPage<Map<String, Object>> getCompletedWarnings(Page<?> page, String warningType, String warningLevel, LocalDateTime startTime, LocalDateTime endTime) {
+        return earlyWarningMapper.selectCompletedWarnings(page, warningType, warningLevel, startTime, endTime);
+    }
+
+    @Override
+    public List<Map<String, Object>> getAttachments(String warningId) {
+        return getAttachmentList(warningId);
+    }
+
+    @Override
+    public Map<String, Object> getStatistics() {
+        List<Map<String, Object>> statsList = earlyWarningMapper.selectStatistics();
+        if (statsList != null && !statsList.isEmpty()) {
+            return statsList.get(0);
+        }
+        return new HashMap<>();
+    }
+
+    @Override
+    public Map<String, Object> getDashboardStatistics() {
+        Map<String, Object> result = new HashMap<>();
+        
+        Map<String, Object> basicStats = getStatistics();
+        result.put("basicStats", basicStats);
+        
+        List<Map<String, Object>> typeStats = getWarningTypeStatistics();
+        result.put("typeStats", typeStats);
+        
+        List<Map<String, Object>> levelStats = getWarningLevelStatistics();
+        result.put("levelStats", levelStats);
+        
+        List<Map<String, Object>> trendStats = getWarningTrendStatistics();
+        result.put("trendStats", trendStats);
+        
+        return result;
+    }
+
+    private List<Map<String, Object>> getWarningTypeStatistics() {
+        List<SysDictData> types = DictUtils.getDictCache("warning_type");
+        List<Map<String, Object>> result = new ArrayList<>();
+        if (types != null) {
+            for (SysDictData type : types) {
+                LambdaQueryWrapper<EarlyWarning> wrapper = new LambdaQueryWrapper<>();
+                wrapper.eq(EarlyWarning::getWarningType, type.getDictValue());
+                long count = count(wrapper);
+                
+                Map<String, Object> item = new HashMap<>();
+                item.put("typeCode", type.getDictValue());
+                item.put("typeName", type.getDictLabel());
+                item.put("count", count);
+                result.add(item);
+            }
+        }
+        return result;
+    }
+
+    private List<Map<String, Object>> getWarningLevelStatistics() {
+        List<Map<String, Object>> result = new ArrayList<>();
+        // 预警级别:1-4
+        for (int i = 1; i <= 4; i++) {
+            String levelCode = String.valueOf(i);
+            LambdaQueryWrapper<EarlyWarning> wrapper = new LambdaQueryWrapper<>();
+            wrapper.eq(EarlyWarning::getWarningLevel, levelCode);
+            long count = count(wrapper);
+            
+            Map<String, Object> item = new HashMap<>();
+            item.put("levelCode", levelCode);
+            item.put("count", count);
+            result.add(item);
+        }
+        return result;
+    }
+
+    private List<Map<String, Object>> getWarningTrendStatistics() {
+        List<Map<String, Object>> result = new ArrayList<>();
+        for (int i = 6; i >= 0; i--) {
+            LocalDateTime date = LocalDateTime.now().minusDays(i);
+            LocalDateTime startOfDay = date.toLocalDate().atStartOfDay();
+            LocalDateTime endOfDay = date.toLocalDate().atTime(23, 59, 59);
+            
+            LambdaQueryWrapper<EarlyWarning> wrapper = new LambdaQueryWrapper<>();
+            wrapper.ge(EarlyWarning::getCreateTime, startOfDay);
+            wrapper.le(EarlyWarning::getCreateTime, endOfDay);
+            long count = count(wrapper);
+            
+            Map<String, Object> item = new HashMap<>();
+            item.put("date", date.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
+            item.put("count", count);
+            result.add(item);
+        }
+        return result;
+    }
+
+    @Override
+    public List<Map<String, Object>> getTypeConfigList() {
+        List<SysDictData> list = DictUtils.getDictCache("warning_type");
+        List<Map<String, Object>> result = new ArrayList<>();
+        if (list != null) {
+            for (SysDictData config : list) {
+                Map<String, Object> map = new HashMap<>();
+                map.put("dictCode", config.getDictCode());
+                map.put("typeCode", config.getDictValue());
+                map.put("typeName", config.getDictLabel());
+                result.add(map);
+            }
+        }
+        return result;
+    }
+
+    private void addDisposalRecord(String warningId, String disposalType, String oldLevel, String newLevel, String disposalUser, String content) {
+        WarningDisposal disposal = new WarningDisposal();
+        disposal.setWarningId(warningId);
+        disposal.setDisposalType(disposalType);
+        disposal.setOldLevel(oldLevel);
+        disposal.setNewLevel(newLevel);
+        disposal.setDisposalUser(disposalUser);
+        disposal.setDisposalContent(content);
+        disposal.setCreateTime(LocalDateTime.now());
+        warningDisposalMapper.insert(disposal);
+    }
+
+    private List<Map<String, Object>> getAttachmentList(String warningId) {
+        List<WarningAttachment> list = warningAttachmentMapper.selectList(
+                new LambdaQueryWrapper<WarningAttachment>()
+                        .eq(WarningAttachment::getWarningId, warningId)
+                        .orderByDesc(WarningAttachment::getCreateTime)
+        );
+
+        List<Map<String, Object>> result = new ArrayList<>();
+        for (WarningAttachment attachment : list) {
+            Map<String, Object> map = new HashMap<>();
+            map.put("attachmentId", attachment.getAttachmentId());
+            map.put("attachmentName", attachment.getAttachmentName());
+            map.put("attachmentUrl", attachment.getAttachmentUrl());
+            map.put("attachmentType", attachment.getAttachmentType());
+            map.put("attachmentSize", attachment.getAttachmentSize());
+            map.put("createTime", attachment.getCreateTime());
+            result.add(map);
+        }
+        return result;
+    }
+
+    private void createTodo(String warningId, String userId, String taskName, String todoType) {
+        WarningTodo todo = new WarningTodo();
+        todo.setWarningId(warningId);
+        todo.setUserId(userId);
+        todo.setUserName(userId);
+        todo.setTodoType(todoType);
+        todo.setReadStatus("UNREAD");
+        todo.setTaskName(taskName);
+        todo.setCreateTime(LocalDateTime.now());
+        warningTodoMapper.insert(todo);
+    }
+
+    private void completeTodo(String warningId) {
+        LambdaQueryWrapper<WarningTodo> wrapper = new LambdaQueryWrapper<>();
+        wrapper.eq(WarningTodo::getWarningId, warningId)
+                .eq(WarningTodo::getTodoType, "TODO");
+        List<WarningTodo> todos = warningTodoMapper.selectList(wrapper);
+
+        for (WarningTodo todo : todos) {
+            todo.setTodoType("DONE");
+            todo.setReadStatus("READ");
+            todo.setCompleteTime(LocalDateTime.now());
+            warningTodoMapper.updateById(todo);
+        }
+    }
+
+    @Override
+    public WarningArchive getArchiveByWarningId(String warningId) {
+        LambdaQueryWrapper<WarningArchive> wrapper = new LambdaQueryWrapper<>();
+        wrapper.eq(WarningArchive::getWarningId, warningId);
+        return warningArchiveMapper.selectOne(wrapper);
+    }
+
+    @Override
+    public IPage<WarningArchive> getArchiveList(Page<WarningArchive> page, String warningName, String warningType, String warningLevel, LocalDateTime startTime, LocalDateTime endTime) {
+        LambdaQueryWrapper<WarningArchive> wrapper = new LambdaQueryWrapper<>();
+        
+        if (warningName != null && !warningName.isEmpty()) {
+            wrapper.like(WarningArchive::getWarningName, warningName);
+        }
+        if (warningType != null && !warningType.isEmpty()) {
+            wrapper.eq(WarningArchive::getWarningType, warningType);
+        }
+        if (warningLevel != null && !warningLevel.isEmpty()) {
+            wrapper.eq(WarningArchive::getWarningLevel, warningLevel);
+        }
+        if (startTime != null) {
+            wrapper.ge(WarningArchive::getCreateTime, startTime);
+        }
+        if (endTime != null) {
+            wrapper.le(WarningArchive::getCreateTime, endTime);
+        }
+        
+        wrapper.orderByDesc(WarningArchive::getCreateTime);
+        return warningArchiveMapper.selectPage(page, wrapper);
+    }
+
+    private static final Map<String, String> DISPOSAL_TYPE_MAP = new HashMap<>();
+    static {
+        DISPOSAL_TYPE_MAP.put("RELEASE", "发布预警");
+        DISPOSAL_TYPE_MAP.put("UPGRADE", "升级预警");
+        DISPOSAL_TYPE_MAP.put("RESOLVE", "解除预警");
+        DISPOSAL_TYPE_MAP.put("RETURN", "退回重办");
+        DISPOSAL_TYPE_MAP.put("SUPERVISION", "预警督办");
+        DISPOSAL_TYPE_MAP.put("INSTRUCTION", "领导批示");
+    }
+
+    @Override
+    public List<WarningDisposal> getDisposalProcess(String warningId) {
+        LambdaQueryWrapper<WarningDisposal> wrapper = new LambdaQueryWrapper<>();
+        wrapper.eq(WarningDisposal::getWarningId, warningId);
+        wrapper.orderByAsc(WarningDisposal::getCreateTime);
+        return warningDisposalMapper.selectList(wrapper);
+    }
+
+    @Override
+    public Map<String, Object> getProcessDiagram(String warningId) {
+        Map<String, Object> result = new HashMap<>();
+        List<Map<String, Object>> nodes = new ArrayList<>();
+        List<Map<String, Object>> edges = new ArrayList<>();
+
+        EarlyWarning warning = earlyWarningMapper.selectById(warningId);
+        if (warning == null) {
+            result.put("error", "预警不存在");
+            return result;
+        }
+
+        List<WarningDisposal> disposals = getDisposalProcess(warningId);
+
+        Map<String, Object> startNode = new HashMap<>();
+        startNode.put("id", "start");
+        startNode.put("name", "预警创建");
+        startNode.put("type", "startEvent");
+        startNode.put("x", 50);
+        startNode.put("y", 150);
+        startNode.put("status", "completed");
+        nodes.add(startNode);
+
+        int x = 180;
+        String lastNodeId = "start";
+
+        for (int i = 0; i < disposals.size(); i++) {
+            WarningDisposal disposal = disposals.get(i);
+            String nodeId = "task_" + i;
+            String typeName = DISPOSAL_TYPE_MAP.getOrDefault(disposal.getDisposalType(), "处置");
+
+            Map<String, Object> taskNode = new HashMap<>();
+            taskNode.put("id", nodeId);
+            taskNode.put("name", typeName);
+            taskNode.put("type", "userTask");
+            taskNode.put("x", x);
+            taskNode.put("y", 150);
+            taskNode.put("status", "completed");
+            taskNode.put("disposalUser", disposal.getDisposalUser());
+            taskNode.put("disposalTime", disposal.getCreateTime() != null ? 
+                    disposal.getCreateTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")) : null);
+            taskNode.put("disposalId", disposal.getDisposalId());
+            nodes.add(taskNode);
+
+            Map<String, Object> edge = new HashMap<>();
+            edge.put("source", lastNodeId);
+            edge.put("target", nodeId);
+            edge.put("label", "");
+            edge.put("status", "completed");
+            edges.add(edge);
+
+            lastNodeId = nodeId;
+            x += 180;
+        }
+
+        String status = warning.getStatus();
+        String currentStatus = "waiting";
+        if ("CLOSED".equals(status) || "HANDLED".equals(status)) {
+            currentStatus = "completed";
+        } else if ("PROCESSING".equals(status) || "PENDING".equals(status) || "RELEASED".equals(status)) {
+            currentStatus = "active";
+        }
+
+        Map<String, Object> endNode = new HashMap<>();
+        endNode.put("id", "end");
+        endNode.put("name", "处置完成");
+        endNode.put("type", "endEvent");
+        endNode.put("x", x);
+        endNode.put("y", 150);
+        endNode.put("status", currentStatus);
+        nodes.add(endNode);
+
+        if (!disposals.isEmpty()) {
+            Map<String, Object> lastEdge = new HashMap<>();
+            lastEdge.put("source", lastNodeId);
+            lastEdge.put("target", "end");
+            lastEdge.put("label", "");
+            lastEdge.put("status", currentStatus);
+            edges.add(lastEdge);
+        }
+
+        result.put("nodes", nodes);
+        result.put("edges", edges);
+        result.put("warningId", warningId);
+        result.put("warningName", warning.getWarningName());
+        result.put("warningNo", warning.getWarningNo());
+        result.put("status", warning.getStatus());
+        result.put("totalTasks", disposals.size());
+        result.put("processDefinitionName", "预警处置流程");
+
+        return result;
+    }
+
+    @Override
+    public Map<String, Object> getDisposalDetail(String disposalId) {
+        WarningDisposal disposal = warningDisposalMapper.selectById(disposalId);
+        if (disposal == null) {
+            return null;
+        }
+
+        Map<String, Object> result = new HashMap<>();
+        result.put("disposalId", disposal.getDisposalId());
+        result.put("warningId", disposal.getWarningId());
+        result.put("disposalType", disposal.getDisposalType());
+        result.put("disposalTypeName", DISPOSAL_TYPE_MAP.getOrDefault(disposal.getDisposalType(), "未知"));
+        result.put("oldLevel", disposal.getOldLevel());
+        result.put("newLevel", disposal.getNewLevel());
+        result.put("disposalUser", disposal.getDisposalUser());
+        result.put("disposalContent", disposal.getDisposalContent());
+        result.put("supervisionUser", disposal.getSupervisionUser());
+        result.put("supervisionContent", disposal.getSupervisionContent());
+        result.put("notificationType", disposal.getNotificationType());
+        result.put("createTime", disposal.getCreateTime() != null ? 
+                disposal.getCreateTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")) : null);
+
+        return result;
+    }
+
+    @Override
+    public Map<String, Object> getProcessStatistics(String warningId) {
+        Map<String, Object> result = new HashMap<>();
+
+        List<WarningDisposal> disposals = getDisposalProcess(warningId);
+        EarlyWarning warning = earlyWarningMapper.selectById(warningId);
+
+        result.put("warningId", warningId);
+        result.put("warningName", warning != null ? warning.getWarningName() : null);
+        result.put("totalDisposals", disposals.size());
+
+        Map<String, Integer> typeCount = new HashMap<>();
+        for (WarningDisposal disposal : disposals) {
+            String type = disposal.getDisposalType();
+            typeCount.put(type, typeCount.getOrDefault(type, 0) + 1);
+        }
+        result.put("typeDistribution", typeCount);
+
+        Set<String> handlers = new HashSet<>();
+        for (WarningDisposal disposal : disposals) {
+            if (disposal.getDisposalUser() != null) {
+                handlers.add(disposal.getDisposalUser());
+            }
+        }
+        result.put("handlerCount", handlers.size());
+
+        if (!disposals.isEmpty()) {
+            result.put("firstDisposalTime", disposals.get(0).getCreateTime() != null ? 
+                    disposals.get(0).getCreateTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")) : null);
+            result.put("lastDisposalTime", disposals.get(disposals.size() - 1).getCreateTime() != null ? 
+                    disposals.get(disposals.size() - 1).getCreateTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")) : null);
+        }
+
+        return result;
+    }
+}

+ 24 - 0
pipe-network-service/zksy-system/src/main/java/com/zksy/manhole/dto/in/EquipmentStatusInDTO.java

@@ -0,0 +1,24 @@
+package com.zksy.manhole.dto.in;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * 修改设备状态-入参
+ *
+ * @author xianggx
+ */
+@Data
+@ApiModel(value = "修改设备状态-入参", description = "修改设备状态-入参")
+public class EquipmentStatusInDTO implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    @ApiModelProperty(value = "设备ID", required = true)
+    private String equipmentId;
+
+    @ApiModelProperty(value = "运维状态:1-在用,2-闲置", required = true)
+    private Integer currentStatus;
+}

+ 30 - 0
pipe-network-service/zksy-system/src/main/java/com/zksy/manhole/dto/in/ManholeDeviceListInDTO.java

@@ -0,0 +1,30 @@
+package com.zksy.manhole.dto.in;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * 查询井盖监测设备列表-入参
+ *
+ * @author xianggx
+ */
+@Data
+@ApiModel(value = "查询井盖监测设备列表-入参", description = "查询井盖监测设备列表-入参")
+public class ManholeDeviceListInDTO implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    @ApiModelProperty(value = "运维状态:1-在用,2-闲置,3-维修,4-报废,5-待入库")
+    private Integer currentStatus;
+
+    @ApiModelProperty(value = "报警状态(0-正常,1-报警)")
+    private Integer alarmStatus;
+
+    @ApiModelProperty(value = "在线状态(0-离线,1-在线)")
+    private Integer onlineStatus;
+
+    @ApiModelProperty("是否查询井盖监测数据:默认不查询")
+    private Boolean isQueryManholeData = false;
+}

+ 42 - 0
pipe-network-service/zksy-system/src/main/java/com/zksy/manhole/dto/in/ManholeDevicePageInDTO.java

@@ -0,0 +1,42 @@
+package com.zksy.manhole.dto.in;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * 分页查询监测设备台账列表-入参
+ *
+ * @author xianggx
+ */
+@Data
+@ApiModel(value = "分页查询监测设备台账列表-入参", description = "分页查询监测设备台账列表-入参")
+public class ManholeDevicePageInDTO implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    @ApiModelProperty(value = "设备编码")
+    private String deviceCode;
+
+    @ApiModelProperty(value = "设备名称")
+    private String deviceName;
+
+    @ApiModelProperty(value = "运维状态:1-在用,2-闲置,3-维修,4-报废,5-待入库")
+    private Integer currentStatus;
+
+    @ApiModelProperty(value = "设备类别ID")
+    private String equipmentTypeId;
+
+    @ApiModelProperty("设备位置描述")
+    private String equipmentLocation;
+
+    @ApiModelProperty("是否查询井盖监测数据:默认不查询")
+    private Boolean isQueryManholeData = false;
+
+    @ApiModelProperty(value = "当前记录起始索引", required = true)
+    private Long pageNum;
+
+    @ApiModelProperty(value = "每页显示记录数", required = true)
+    private Long pageSize;
+}

+ 32 - 0
pipe-network-service/zksy-system/src/main/java/com/zksy/manhole/dto/out/EquipmentBaseOutDTO.java

@@ -0,0 +1,32 @@
+package com.zksy.manhole.dto.out;
+
+import com.zksy.base.domain.EquipmentBase;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * 获取监测设备台账详情-出参
+ *
+ * @author xianggx
+ */
+@Data
+@ApiModel(value = "获取监测设备台账详情-出参", description = "获取监测设备台账详情-出参")
+public class EquipmentBaseOutDTO extends EquipmentBase implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    @ApiModelProperty("设备类别名称")
+    private String equipmentTypeName;
+
+    @ApiModelProperty(value = "设备状态详情")
+    private EquipmentStatusOutDTO equipmentStatus;
+
+    @ApiModelProperty(value = "井盖实时监测数据")
+    private ManholeDataOutDTO manholeData;
+
+    @ApiModelProperty(value = "设备预警阈值列表")
+    private List<WarningThresholdOutDTO> warningThresholdList;
+}

+ 33 - 0
pipe-network-service/zksy-system/src/main/java/com/zksy/manhole/dto/out/EquipmentStatusOutDTO.java

@@ -0,0 +1,33 @@
+package com.zksy.manhole.dto.out;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * 设备状态详情-出参
+ *
+ * @author xianggx
+ */
+@Data
+@ApiModel(value = "设备状态详情-出参", description = "设备状态详情-出参")
+public class EquipmentStatusOutDTO implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    @ApiModelProperty(value = "运维状态:1-在用,2-闲置,3-维修,4-报废,5-待入库")
+    private Integer currentStatus;
+
+    @ApiModelProperty(value = "报警状态(0-正常,1-报警)")
+    private Integer alarmStatus;
+
+    @ApiModelProperty(value = "在线状态(0-离线,1-在线)")
+    private Integer onlineStatus;
+
+    @ApiModelProperty(value = "状态更新时间")
+    @JsonFormat(locale = "zh",pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
+    private Date statusUpdateTime;
+}

+ 36 - 0
pipe-network-service/zksy-system/src/main/java/com/zksy/manhole/dto/out/ManholeDataOutDTO.java

@@ -0,0 +1,36 @@
+package com.zksy.manhole.dto.out;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * 井盖实时监测数据-出参
+ *
+ * @author xianggx
+ */
+@Data
+@ApiModel(value = "井盖实时监测数据-出参", description = "井盖实时监测数据-出参")
+public class ManholeDataOutDTO implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    @ApiModelProperty(value = "电池电量")
+    private String batteryLevel;
+
+    @ApiModelProperty(value = "信号量")
+    private String signalStrength;
+
+    @ApiModelProperty(value = "倾斜角度")
+    private String tiltAngle;
+
+    @ApiModelProperty(value = "激活状态")
+    private String activationStatus;
+
+    @ApiModelProperty(value = "水浸报警状态(0正常,1报警)")
+    private String waterInfiltrationAlarmStatus;
+
+    @ApiModelProperty(value = "水位报警状态(0正常,1报警)")
+    private String waterLevelAlarmStatus;
+}

+ 30 - 0
pipe-network-service/zksy-system/src/main/java/com/zksy/manhole/dto/out/WarningThresholdOutDTO.java

@@ -0,0 +1,30 @@
+package com.zksy.manhole.dto.out;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * 设备预警阈值-出参
+ *
+ * @author xianggx
+ */
+@Data
+@ApiModel(value = "设备预警阈值-出参", description = "设备预警阈值-出参")
+public class WarningThresholdOutDTO implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    @ApiModelProperty(value = "预警类型")
+    private String warningType;
+
+    @ApiModelProperty(value = "预警编码")
+    private String warningCode;
+
+    @ApiModelProperty(value = "预警值")
+    private Double warningValue;
+
+    @ApiModelProperty(value = "备注")
+    private String remark;
+}

+ 77 - 0
pipe-network-service/zksy-system/src/main/resources/mapper/base/AlarmAssignDetailMapper.xml

@@ -0,0 +1,77 @@
+<?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.base.mapper.AlarmAssignDetailMapper">
+    
+    <resultMap type="AlarmAssignDetail" id="AlarmAssignDetailResult">
+        <result property="alarmAssignDetailId"    column="alarm_assign_detail_id"    />
+        <result property="alarmAssignId"    column="alarm_assign_id"    />
+        <result property="handleUserId"    column="handle_user_id"    />
+        <result property="handleUserName"    column="handle_user_name"    />
+        <result property="handlePhone"    column="handle_phone"    />
+        <result property="handleDeptName"    column="handle_dept_name"    />
+        <result property="remark"    column="remark"    />
+    </resultMap>
+
+    <sql id="selectAlarmAssignDetailVo">
+        select alarm_assign_detail_id, alarm_assign_id, handle_user_id, handle_user_name, handle_phone, handle_dept_name, remark from alarm_assign_detail
+    </sql>
+
+    <select id="selectAlarmAssignDetailList" parameterType="AlarmAssignDetail" resultMap="AlarmAssignDetailResult">
+        <include refid="selectAlarmAssignDetailVo"/>
+        <where>  
+            <if test="alarmAssignDetailId != null "> and alarm_assign_detail_id = #{alarmAssignDetailId}</if>
+            <if test="alarmAssignId != null "> and alarm_assign_id = #{alarmAssignId}</if>
+        </where>
+    </select>
+    
+    <select id="selectAlarmAssignDetailByAlarmAssignDetailId" parameterType="Long" resultMap="AlarmAssignDetailResult">
+        <include refid="selectAlarmAssignDetailVo"/>
+        where alarm_assign_detail_id = #{alarmAssignDetailId}
+    </select>
+
+    <insert id="insertAlarmAssignDetail" parameterType="AlarmAssignDetail" useGeneratedKeys="true" keyProperty="alarmAssignDetailId">
+        insert into alarm_assign_detail
+        <trim prefix="(" suffix=")" suffixOverrides=",">
+            <if test="alarmAssignId != null">alarm_assign_id,</if>
+            <if test="handleUserId != null">handle_user_id,</if>
+            <if test="handleUserName != null">handle_user_name,</if>
+            <if test="handlePhone != null">handle_phone,</if>
+            <if test="handleDeptName != null">handle_dept_name,</if>
+            <if test="remark != null">remark,</if>
+         </trim>
+        <trim prefix="values (" suffix=")" suffixOverrides=",">
+            <if test="alarmAssignId != null">#{alarmAssignId},</if>
+            <if test="handleUserId != null">#{handleUserId},</if>
+            <if test="handleUserName != null">#{handleUserName},</if>
+            <if test="handlePhone != null">#{handlePhone},</if>
+            <if test="handleDeptName != null">#{handleDeptName},</if>
+            <if test="remark != null">#{remark},</if>
+         </trim>
+    </insert>
+
+    <update id="updateAlarmAssignDetail" parameterType="AlarmAssignDetail">
+        update alarm_assign_detail
+        <trim prefix="SET" suffixOverrides=",">
+            <if test="alarmAssignId != null">alarm_assign_id = #{alarmAssignId},</if>
+            <if test="handleUserId != null">handle_user_id = #{handleUserId},</if>
+            <if test="handleUserName != null">handle_user_name = #{handleUserName},</if>
+            <if test="handlePhone != null">handle_phone = #{handlePhone},</if>
+            <if test="handleDeptName != null">handle_dept_name = #{handleDeptName},</if>
+            <if test="remark != null">remark = #{remark},</if>
+        </trim>
+        where alarm_assign_detail_id = #{alarmAssignDetailId}
+    </update>
+
+    <delete id="deleteAlarmAssignDetailByAlarmAssignDetailId" parameterType="Long">
+        delete from alarm_assign_detail where alarm_assign_detail_id = #{alarmAssignDetailId}
+    </delete>
+
+    <delete id="deleteAlarmAssignDetailByAlarmAssignDetailIds" parameterType="String">
+        delete from alarm_assign_detail where alarm_assign_detail_id in 
+        <foreach item="alarmAssignDetailId" collection="array" open="(" separator="," close=")">
+            #{alarmAssignDetailId}
+        </foreach>
+    </delete>
+</mapper>

+ 101 - 0
pipe-network-service/zksy-system/src/main/resources/mapper/base/AlarmAssignListMapper.xml

@@ -0,0 +1,101 @@
+<?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.base.mapper.AlarmAssignListMapper">
+    
+    <resultMap type="AlarmAssignList" id="AlarmAssignListResult">
+        <result property="alarmAssignId"    column="alarm_assign_id"    />
+        <result property="deviceCode"    column="device_code"    />
+        <result property="deviceName"    column="device_name"    />
+        <result property="manufacturer"    column="manufacturer"    />
+        <result property="alarmStatus"    column="alarm_status"    />
+        <result property="hiddenDangerType"    column="hidden_danger_type"    />
+        <result property="hiddenDangerRemark"    column="hidden_danger_remark"    />
+        <result property="alarmTime"    column="alarm_time"    />
+        <result property="assignStatus"    column="assign_status"    />
+        <result property="assignTime"    column="assign_time"    />
+        <result property="assignUserId"    column="assign_user_id"    />
+        <result property="assignRemark"    column="assign_remark"    />
+    </resultMap>
+
+    <sql id="selectAlarmAssignListVo">
+        select alarm_assign_id, device_code, device_name, manufacturer, alarm_status, hidden_danger_type, hidden_danger_remark, alarm_time, assign_status, assign_time, assign_user_id, assign_remark from alarm_assign_list
+    </sql>
+
+    <select id="selectAlarmAssignListList" parameterType="AlarmAssignList" resultMap="AlarmAssignListResult">
+        <include refid="selectAlarmAssignListVo"/>
+        <where>  
+            <if test="alarmAssignId != null "> and alarm_assign_id = #{alarmAssignId}</if>
+            <if test="deviceCode != null  and deviceCode != ''"> and device_code = #{deviceCode}</if>
+            <if test="manufacturer != null  and manufacturer != ''"> and manufacturer like concat('%', #{manufacturer}, '%')</if>
+            <if test="alarmStatus != null "> and alarm_status = #{alarmStatus}</if>
+            <!-- <if test="params.beginAlarmTime != null and params.beginAlarmTime != '' and params.endAlarmTime != null and params.endAlarmTime != ''"> and alarm_time between #{params.beginAlarmTime} and #{params.endAlarmTime}</if> -->
+            <if test="assignStatus != null "> and assign_status = #{assignStatus}</if>
+        </where>
+    </select>
+    
+    <select id="selectAlarmAssignListByAlarmAssignId" parameterType="Long" resultMap="AlarmAssignListResult">
+        <include refid="selectAlarmAssignListVo"/>
+        where alarm_assign_id = #{alarmAssignId}
+    </select>
+
+    <insert id="insertAlarmAssignList" parameterType="AlarmAssignList" useGeneratedKeys="true" keyProperty="alarmAssignId">
+        insert into alarm_assign_list
+        <trim prefix="(" suffix=")" suffixOverrides=",">
+            <if test="deviceCode != null and deviceCode != ''">device_code,</if>
+            <if test="deviceName != null and deviceName != ''">device_name,</if>
+            <if test="manufacturer != null">manufacturer,</if>
+            <if test="alarmStatus != null">alarm_status,</if>
+            <if test="hiddenDangerType != null">hidden_danger_type,</if>
+            <if test="hiddenDangerRemark != null">hidden_danger_remark,</if>
+            <if test="alarmTime != null">alarm_time,</if>
+            <if test="assignStatus != null">assign_status,</if>
+            <if test="assignTime != null">assign_time,</if>
+            <if test="assignUserId != null">assign_user_id,</if>
+            <if test="assignRemark != null">assign_remark,</if>
+         </trim>
+        <trim prefix="values (" suffix=")" suffixOverrides=",">
+            <if test="deviceCode != null and deviceCode != ''">#{deviceCode},</if>
+            <if test="deviceName != null and deviceName != ''">#{deviceName},</if>
+            <if test="manufacturer != null">#{manufacturer},</if>
+            <if test="alarmStatus != null">#{alarmStatus},</if>
+            <if test="hiddenDangerType != null">#{hiddenDangerType},</if>
+            <if test="hiddenDangerRemark != null">#{hiddenDangerRemark},</if>
+            <if test="alarmTime != null">#{alarmTime},</if>
+            <if test="assignStatus != null">#{assignStatus},</if>
+            <if test="assignTime != null">#{assignTime},</if>
+            <if test="assignUserId != null">#{assignUserId},</if>
+            <if test="assignRemark != null">#{assignRemark},</if>
+         </trim>
+    </insert>
+
+    <update id="updateAlarmAssignList" parameterType="AlarmAssignList">
+        update alarm_assign_list
+        <trim prefix="SET" suffixOverrides=",">
+            <if test="deviceCode != null and deviceCode != ''">device_code = #{deviceCode},</if>
+            <if test="deviceName != null and deviceName != ''">device_name = #{deviceName},</if>
+            <if test="manufacturer != null">manufacturer = #{manufacturer},</if>
+            <if test="alarmStatus != null">alarm_status = #{alarmStatus},</if>
+            <if test="hiddenDangerType != null">hidden_danger_type = #{hiddenDangerType},</if>
+            <if test="hiddenDangerRemark != null">hidden_danger_remark = #{hiddenDangerRemark},</if>
+            <if test="alarmTime != null">alarm_time = #{alarmTime},</if>
+            <if test="assignStatus != null">assign_status = #{assignStatus},</if>
+            <if test="assignTime != null">assign_time = #{assignTime},</if>
+            <if test="assignUserId != null">assign_user_id = #{assignUserId},</if>
+            <if test="assignRemark != null">assign_remark = #{assignRemark},</if>
+        </trim>
+        where alarm_assign_id = #{alarmAssignId}
+    </update>
+
+    <delete id="deleteAlarmAssignListByAlarmAssignId" parameterType="Long">
+        delete from alarm_assign_list where alarm_assign_id = #{alarmAssignId}
+    </delete>
+
+    <delete id="deleteAlarmAssignListByAlarmAssignIds" parameterType="String">
+        delete from alarm_assign_list where alarm_assign_id in 
+        <foreach item="alarmAssignId" collection="array" open="(" separator="," close=")">
+            #{alarmAssignId}
+        </foreach>
+    </delete>
+</mapper>

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

@@ -0,0 +1,23 @@
+<?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.base.warning.mapper.AlarmWarningRelMapper">
+
+    <select id="selectAlarmListByWarningId" resultType="java.util.Map">
+        SELECT
+            r.*,
+            a.device_name,
+            a.device_code,
+            a.device_type,
+            a.warning_type,
+            a.warning_code,
+            a.warning_value,
+            a.actual_value,
+            a.alarm_status,
+            a.alarm_time
+        FROM alarm_warning_rel r
+        LEFT JOIN alarm_data a ON r.alarm_id = a.id
+        WHERE r.warning_id = #{warningId}
+        ORDER BY a.alarm_time DESC
+    </select>
+
+</mapper>

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

@@ -0,0 +1,146 @@
+<?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.base.warning.mapper.EarlyWarningMapper">
+
+    <select id="selectWarningList" resultType="java.util.Map">
+        SELECT w.*
+        FROM early_warning w
+        <where>
+            <if test="warningName != null and warningName != ''">
+                AND w.warning_name LIKE CONCAT('%', #{warningName}, '%')
+            </if>
+            <if test="warningType != null and warningType != ''">
+                AND w.warning_type = #{warningType}
+            </if>
+            <if test="warningLevel != null and warningLevel != ''">
+                AND w.warning_level = #{warningLevel}
+            </if>
+            <if test="status != null and status != ''">
+                AND w.status = #{status}
+            </if>
+        </where>
+        ORDER BY w.create_time DESC
+    </select>
+
+    <select id="searchWarnings" resultType="java.util.Map">
+        SELECT w.*
+        FROM early_warning w
+        <where>
+            <if test="warningName != null and warningName != ''">
+                AND w.warning_name LIKE CONCAT('%', #{warningName}, '%')
+            </if>
+            <if test="warningNo != null and warningNo != ''">
+                AND w.warning_no LIKE CONCAT('%', #{warningNo}, '%')
+            </if>
+            <if test="warningType != null and warningType != ''">
+                AND w.warning_type = #{warningType}
+            </if>
+            <if test="warningLevel != null and warningLevel != ''">
+                AND w.warning_level = #{warningLevel}
+            </if>
+            <if test="status != null and status != ''">
+                AND w.status = #{status}
+            </if>
+            <if test="location != null and location != ''">
+                AND w.location LIKE CONCAT('%', #{location}, '%')
+            </if>
+            <if test="publisher != null and publisher != ''">
+                AND w.publisher LIKE CONCAT('%', #{publisher}, '%')
+            </if>
+            <if test="ownershipUnit != null and ownershipUnit != ''">
+                AND w.ownership_unit LIKE CONCAT('%', #{ownershipUnit}, '%')
+            </if>
+            <if test="startTime != null">
+                AND w.create_time >= #{startTime}
+            </if>
+            <if test="endTime != null">
+                AND w.create_time &lt;= #{endTime}
+            </if>
+        </where>
+        ORDER BY w.create_time DESC
+    </select>
+
+    <select id="selectTodoList" resultType="java.util.Map">
+        SELECT
+            t.*,
+            w.warning_name,
+            w.warning_type,
+            w.warning_level,
+            w.handler,
+            w.publisher,
+            w.location,
+            w.ownership_unit,
+            w.publish_time
+        FROM warning_todo t
+        LEFT JOIN early_warning w ON t.warning_id = w.warning_id
+        <where>
+            t.user_id = #{userId}
+            <if test="todoType != null and todoType != ''">
+                AND t.todo_type = #{todoType}
+            </if>
+            <if test="warningName != null and warningName != ''">
+                AND w.warning_name LIKE CONCAT('%', #{warningName}, '%')
+            </if>
+        </where>
+        ORDER BY t.create_time DESC
+    </select>
+
+    <select id="selectProcessingWarnings" resultType="java.util.Map">
+        SELECT w.*
+        FROM early_warning w
+        <where>
+            AND w.status IN ('PENDING', 'PROCESSING', 'RELEASED')
+            <if test="warningType != null and warningType != ''">
+                AND w.warning_type = #{warningType}
+            </if>
+            <if test="warningLevel != null and warningLevel != ''">
+                AND w.warning_level = #{warningLevel}
+            </if>
+        </where>
+        ORDER BY w.publish_time DESC
+    </select>
+
+    <select id="selectCompletedWarnings" resultType="java.util.Map">
+        SELECT w.*
+        FROM early_warning w
+        <where>
+            AND w.status IN ('HANDLED', 'CLOSED')
+            <if test="warningType != null and warningType != ''">
+                AND w.warning_type = #{warningType}
+            </if>
+            <if test="warningLevel != null and warningLevel != ''">
+                AND w.warning_level = #{warningLevel}
+            </if>
+            <if test="startTime != null">
+                AND w.update_time >= #{startTime}
+            </if>
+            <if test="endTime != null">
+                AND w.update_time &lt;= #{endTime}
+            </if>
+        </where>
+        ORDER BY w.update_time DESC
+    </select>
+
+    <select id="selectWarningDetail" resultType="java.util.Map">
+        SELECT w.*
+        FROM early_warning w
+        WHERE w.warning_id = #{warningId}
+    </select>
+
+    <select id="selectStatistics" resultType="java.util.Map">
+        SELECT
+            COUNT(*) AS total,
+            SUM(CASE WHEN status = 'DRAFT' THEN 1 ELSE 0 END) AS draftCount,
+            SUM(CASE WHEN status = 'PENDING' THEN 1 ELSE 0 END) AS pendingCount,
+            SUM(CASE WHEN status = 'PROCESSING' THEN 1 ELSE 0 END) AS processingCount,
+            SUM(CASE WHEN status = 'RELEASED' THEN 1 ELSE 0 END) AS releasedCount,
+            SUM(CASE WHEN status = 'HANDLED' THEN 1 ELSE 0 END) AS handledCount,
+            SUM(CASE WHEN status = 'CLOSED' THEN 1 ELSE 0 END) AS closedCount,
+            SUM(CASE WHEN warning_level = '1' THEN 1 ELSE 0 END) AS level1Count,
+            SUM(CASE WHEN warning_level = '2' THEN 1 ELSE 0 END) AS level2Count,
+            SUM(CASE WHEN warning_level = '3' THEN 1 ELSE 0 END) AS level3Count,
+            SUM(CASE WHEN warning_level = '4' THEN 1 ELSE 0 END) AS level4Count
+        FROM early_warning
+    </select>
+
+</mapper>

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

@@ -0,0 +1,22 @@
+<?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.base.warning.mapper.WarningDisposalMapper">
+
+    <select id="selectDisposalList" resultType="java.util.Map">
+        SELECT
+            d.*,
+            CASE d.disposal_type
+                WHEN 'UPGRADE' THEN '预警升级'
+                WHEN 'DOWNGRADE' THEN '预警降级'
+                WHEN 'RESOLVE' THEN '解除预警'
+                WHEN 'RETURN' THEN '退回重办'
+                WHEN 'SUPERVISION' THEN '预警督办'
+                WHEN 'INSTRUCTION' THEN '领导批示'
+                ELSE d.disposal_type
+            END AS disposalTypeName
+        FROM warning_disposal d
+        WHERE d.warning_id = #{warningId}
+        ORDER BY d.create_time DESC
+    </select>
+
+</mapper>

+ 38 - 0
radar-service/.gitignore

@@ -0,0 +1,38 @@
+target/
+!.mvn/wrapper/maven-wrapper.jar
+!**/src/main/**/target/
+!**/src/test/**/target/
+
+### IntelliJ IDEA ###
+.idea/modules.xml
+.idea/jarRepositories.xml
+.idea/compiler.xml
+.idea/libraries/
+*.iws
+*.iml
+*.ipr
+
+### Eclipse ###
+.apt_generated
+.classpath
+.factorypath
+.project
+.settings
+.springBeans
+.sts4-cache
+
+### NetBeans ###
+/nbproject/private/
+/nbbuild/
+/dist/
+/nbdist/
+/.nb-gradle/
+build/
+!**/src/main/**/build/
+!**/src/test/**/build/
+
+### VS Code ###
+.vscode/
+
+### Mac OS ###
+.DS_Store

+ 38 - 0
telemetry-service/.gitignore

@@ -0,0 +1,38 @@
+target/
+!.mvn/wrapper/maven-wrapper.jar
+!**/src/main/**/target/
+!**/src/test/**/target/
+
+### IntelliJ IDEA ###
+.idea/modules.xml
+.idea/jarRepositories.xml
+.idea/compiler.xml
+.idea/libraries/
+*.iws
+*.iml
+*.ipr
+
+### Eclipse ###
+.apt_generated
+.classpath
+.factorypath
+.project
+.settings
+.springBeans
+.sts4-cache
+
+### NetBeans ###
+/nbproject/private/
+/nbbuild/
+/dist/
+/nbdist/
+/.nb-gradle/
+build/
+!**/src/main/**/build/
+!**/src/test/**/build/
+
+### VS Code ###
+.vscode/
+
+### Mac OS ###
+.DS_Store

+ 38 - 0
water-level-service/.gitignore

@@ -0,0 +1,38 @@
+target/
+!.mvn/wrapper/maven-wrapper.jar
+!**/src/main/**/target/
+!**/src/test/**/target/
+
+### IntelliJ IDEA ###
+.idea/modules.xml
+.idea/jarRepositories.xml
+.idea/compiler.xml
+.idea/libraries/
+*.iws
+*.iml
+*.ipr
+
+### Eclipse ###
+.apt_generated
+.classpath
+.factorypath
+.project
+.settings
+.springBeans
+.sts4-cache
+
+### NetBeans ###
+/nbproject/private/
+/nbbuild/
+/dist/
+/nbdist/
+/.nb-gradle/
+build/
+!**/src/main/**/build/
+!**/src/test/**/build/
+
+### VS Code ###
+.vscode/
+
+### Mac OS ###
+.DS_Store