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

Merge remote-tracking branch 'origin/master'

Kazerin 1 месяц назад
Родитель
Сommit
ee00950a60
92 измененных файлов с 5427 добавлено и 57 удалено
  1. 72 0
      pipe-network-service/zksy-admin/src/main/java/com/zksy/web/controller/alarm/AlarmController.java
  2. 1 1
      pipe-network-service/zksy-admin/src/main/java/com/zksy/web/controller/base/EquipmentBaseController.java
  3. 148 0
      pipe-network-service/zksy-admin/src/main/java/com/zksy/web/controller/base/MonitorPointController.java
  4. 107 0
      pipe-network-service/zksy-admin/src/main/java/com/zksy/web/controller/base/PipeNetworkBaseController.java
  5. 118 0
      pipe-network-service/zksy-admin/src/main/java/com/zksy/web/controller/gasbasic/GasEquipmentController.java
  6. 79 0
      pipe-network-service/zksy-admin/src/main/java/com/zksy/web/controller/gasbasic/GasManholeController.java
  7. 65 0
      pipe-network-service/zksy-admin/src/main/java/com/zksy/web/controller/gasbasic/GasMonitorPointController.java
  8. 81 0
      pipe-network-service/zksy-admin/src/main/java/com/zksy/web/controller/gasbasic/GasPipeNetworkController.java
  9. 129 0
      pipe-network-service/zksy-admin/src/main/java/com/zksy/web/controller/gasbasic/GasPipePointController.java
  10. 72 0
      pipe-network-service/zksy-admin/src/main/java/com/zksy/web/controller/gasbasic/GasRepairRecordController.java
  11. 120 0
      pipe-network-service/zksy-admin/src/main/java/com/zksy/web/controller/gasbasic/GisController.java
  12. 151 0
      pipe-network-service/zksy-admin/src/main/java/com/zksy/web/controller/hidden/HazardController.java
  13. 161 0
      pipe-network-service/zksy-admin/src/main/java/com/zksy/web/controller/manhole/CaseInfoController.java
  14. 117 0
      pipe-network-service/zksy-admin/src/main/java/com/zksy/web/controller/manhole/WorkOrderController.java
  15. 85 0
      pipe-network-service/zksy-admin/src/main/java/com/zksy/web/controller/monitor/RealtimeMonitorController.java
  16. 72 0
      pipe-network-service/zksy-admin/src/main/java/com/zksy/web/controller/risk/RiskController.java
  17. 2 0
      pipe-network-service/zksy-admin/src/main/java/com/zksy/web/controller/system/SysDictDataController.java
  18. 38 32
      pipe-network-service/zksy-admin/src/main/java/com/zksy/web/controller/warning/EarlyWarningController.java
  19. 102 0
      pipe-network-service/zksy-admin/src/main/java/com/zksy/web/controller/warning/WarningItemController.java
  20. 103 0
      pipe-network-service/zksy-admin/src/main/java/com/zksy/web/controller/warning/WarningReasonController.java
  21. 133 0
      pipe-network-service/zksy-system/src/main/java/com/zksy/base/domain/CaseInfo.java
  22. 84 0
      pipe-network-service/zksy-system/src/main/java/com/zksy/base/domain/GasPipePoint.java
  23. 42 0
      pipe-network-service/zksy-system/src/main/java/com/zksy/base/domain/GasPipePointDeviceRel.java
  24. 103 0
      pipe-network-service/zksy-system/src/main/java/com/zksy/base/domain/HazardHiddenAccount.java
  25. 71 0
      pipe-network-service/zksy-system/src/main/java/com/zksy/base/domain/ManholeBase.java
  26. 57 0
      pipe-network-service/zksy-system/src/main/java/com/zksy/base/domain/PipeRepairRecord.java
  27. 72 0
      pipe-network-service/zksy-system/src/main/java/com/zksy/base/domain/RiskAssessment.java
  28. 58 0
      pipe-network-service/zksy-system/src/main/java/com/zksy/base/domain/StationVideoDevice.java
  29. 178 0
      pipe-network-service/zksy-system/src/main/java/com/zksy/base/domain/WorkOrder.java
  30. 70 0
      pipe-network-service/zksy-system/src/main/java/com/zksy/base/domain/WorkOrderLog.java
  31. 124 0
      pipe-network-service/zksy-system/src/main/java/com/zksy/base/domain/vo/EquipmentFullVO.java
  32. 34 0
      pipe-network-service/zksy-system/src/main/java/com/zksy/base/dto/GasPipePointPageInDTO.java
  33. 31 0
      pipe-network-service/zksy-system/src/main/java/com/zksy/base/dto/HazardPageInDTO.java
  34. 28 0
      pipe-network-service/zksy-system/src/main/java/com/zksy/base/dto/ManholePageInDTO.java
  35. 25 0
      pipe-network-service/zksy-system/src/main/java/com/zksy/base/dto/MonitorPointPageInDTO.java
  36. 34 0
      pipe-network-service/zksy-system/src/main/java/com/zksy/base/dto/PipeNetworkPageInDTO.java
  37. 25 0
      pipe-network-service/zksy-system/src/main/java/com/zksy/base/dto/RepairRecordPageInDTO.java
  38. 25 0
      pipe-network-service/zksy-system/src/main/java/com/zksy/base/dto/RiskPageInDTO.java
  39. 20 0
      pipe-network-service/zksy-system/src/main/java/com/zksy/base/mapper/CaseInfoMapper.java
  40. 9 0
      pipe-network-service/zksy-system/src/main/java/com/zksy/base/mapper/GasPipePointDeviceRelMapper.java
  41. 9 0
      pipe-network-service/zksy-system/src/main/java/com/zksy/base/mapper/GasPipePointMapper.java
  42. 9 0
      pipe-network-service/zksy-system/src/main/java/com/zksy/base/mapper/HazardHiddenAccountMapper.java
  43. 9 0
      pipe-network-service/zksy-system/src/main/java/com/zksy/base/mapper/ManholeBaseMapper.java
  44. 9 0
      pipe-network-service/zksy-system/src/main/java/com/zksy/base/mapper/MonitorPointMapper.java
  45. 9 0
      pipe-network-service/zksy-system/src/main/java/com/zksy/base/mapper/PipeNetworkBaseMapper.java
  46. 9 0
      pipe-network-service/zksy-system/src/main/java/com/zksy/base/mapper/PipeRepairRecordMapper.java
  47. 9 0
      pipe-network-service/zksy-system/src/main/java/com/zksy/base/mapper/RiskAssessmentMapper.java
  48. 9 0
      pipe-network-service/zksy-system/src/main/java/com/zksy/base/mapper/StationVideoDeviceMapper.java
  49. 20 0
      pipe-network-service/zksy-system/src/main/java/com/zksy/base/mapper/WorkOrderLogMapper.java
  50. 20 0
      pipe-network-service/zksy-system/src/main/java/com/zksy/base/mapper/WorkOrderMapper.java
  51. 22 0
      pipe-network-service/zksy-system/src/main/java/com/zksy/base/service/CaseInfoService.java
  52. 5 0
      pipe-network-service/zksy-system/src/main/java/com/zksy/base/service/EquipmentBaseService.java
  53. 23 0
      pipe-network-service/zksy-system/src/main/java/com/zksy/base/service/GasPipePointService.java
  54. 40 0
      pipe-network-service/zksy-system/src/main/java/com/zksy/base/service/HazardHiddenAccountService.java
  55. 15 0
      pipe-network-service/zksy-system/src/main/java/com/zksy/base/service/ManholeBaseService.java
  56. 35 0
      pipe-network-service/zksy-system/src/main/java/com/zksy/base/service/MonitorPointService.java
  57. 27 0
      pipe-network-service/zksy-system/src/main/java/com/zksy/base/service/PipeNetworkBaseService.java
  58. 15 0
      pipe-network-service/zksy-system/src/main/java/com/zksy/base/service/PipeRepairRecordService.java
  59. 16 0
      pipe-network-service/zksy-system/src/main/java/com/zksy/base/service/RiskAssessmentService.java
  60. 11 0
      pipe-network-service/zksy-system/src/main/java/com/zksy/base/service/StationVideoDeviceService.java
  61. 13 0
      pipe-network-service/zksy-system/src/main/java/com/zksy/base/service/WorkOrderLogService.java
  62. 30 0
      pipe-network-service/zksy-system/src/main/java/com/zksy/base/service/WorkOrderService.java
  63. 119 0
      pipe-network-service/zksy-system/src/main/java/com/zksy/base/service/impl/CaseInfoServiceImpl.java
  64. 118 8
      pipe-network-service/zksy-system/src/main/java/com/zksy/base/service/impl/EquipmentBaseServiceImpl.java
  65. 89 0
      pipe-network-service/zksy-system/src/main/java/com/zksy/base/service/impl/GasPipePointServiceImpl.java
  66. 279 0
      pipe-network-service/zksy-system/src/main/java/com/zksy/base/service/impl/HazardHiddenAccountServiceImpl.java
  67. 38 0
      pipe-network-service/zksy-system/src/main/java/com/zksy/base/service/impl/ManholeBaseServiceImpl.java
  68. 270 0
      pipe-network-service/zksy-system/src/main/java/com/zksy/base/service/impl/MonitorPointServiceImpl.java
  69. 156 0
      pipe-network-service/zksy-system/src/main/java/com/zksy/base/service/impl/PipeNetworkBaseServiceImpl.java
  70. 37 0
      pipe-network-service/zksy-system/src/main/java/com/zksy/base/service/impl/PipeRepairRecordServiceImpl.java
  71. 73 0
      pipe-network-service/zksy-system/src/main/java/com/zksy/base/service/impl/RiskAssessmentServiceImpl.java
  72. 28 0
      pipe-network-service/zksy-system/src/main/java/com/zksy/base/service/impl/StationVideoDeviceServiceImpl.java
  73. 24 0
      pipe-network-service/zksy-system/src/main/java/com/zksy/base/service/impl/WorkOrderLogServiceImpl.java
  74. 126 0
      pipe-network-service/zksy-system/src/main/java/com/zksy/base/service/impl/WorkOrderServiceImpl.java
  75. 2 0
      pipe-network-service/zksy-system/src/main/java/com/zksy/base/warning/domain/EarlyWarning.java
  76. 5 5
      pipe-network-service/zksy-system/src/main/java/com/zksy/base/warning/service/EarlyWarningService.java
  77. 27 0
      pipe-network-service/zksy-system/src/main/java/com/zksy/base/warning/service/WarningItemService.java
  78. 24 0
      pipe-network-service/zksy-system/src/main/java/com/zksy/base/warning/service/WarningReasonService.java
  79. 16 11
      pipe-network-service/zksy-system/src/main/java/com/zksy/base/warning/service/impl/EarlyWarningServiceImpl.java
  80. 113 0
      pipe-network-service/zksy-system/src/main/java/com/zksy/base/warning/service/impl/WarningItemServiceImpl.java
  81. 116 0
      pipe-network-service/zksy-system/src/main/java/com/zksy/base/warning/service/impl/WarningReasonServiceImpl.java
  82. 30 0
      pipe-network-service/zksy-system/src/main/java/com/zksy/manhole/dto/in/CaseInfoPageInDTO.java
  83. 54 0
      pipe-network-service/zksy-system/src/main/java/com/zksy/manhole/dto/in/CaseInfoSaveInDTO.java
  84. 27 0
      pipe-network-service/zksy-system/src/main/java/com/zksy/manhole/dto/in/CaseInfoVerifyInDTO.java
  85. 42 0
      pipe-network-service/zksy-system/src/main/java/com/zksy/manhole/dto/in/WorkOrderOperInDTO.java
  86. 30 0
      pipe-network-service/zksy-system/src/main/java/com/zksy/manhole/dto/in/WorkOrderPageInDTO.java
  87. 25 0
      pipe-network-service/zksy-system/src/main/java/com/zksy/manhole/dto/out/CaseInfoOutDTO.java
  88. 19 0
      pipe-network-service/zksy-system/src/main/java/com/zksy/manhole/dto/out/WorkOrderLogOutDTO.java
  89. 29 0
      pipe-network-service/zksy-system/src/main/java/com/zksy/manhole/dto/out/WorkOrderOutDTO.java
  90. 35 0
      pipe-network-service/zksy-system/src/main/resources/mapper/CaseInfoMapper.xml
  91. 22 0
      pipe-network-service/zksy-system/src/main/resources/mapper/WorkOrderLogMapper.xml
  92. 44 0
      pipe-network-service/zksy-system/src/main/resources/mapper/WorkOrderMapper.xml

+ 72 - 0
pipe-network-service/zksy-admin/src/main/java/com/zksy/web/controller/alarm/AlarmController.java

@@ -0,0 +1,72 @@
+package com.zksy.web.controller.alarm;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.zksy.base.alarm.domain.AlarmData;
+import com.zksy.base.alarm.service.AlarmDataService;
+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.web.bind.annotation.*;
+
+import java.time.LocalDateTime;
+
+@Slf4j
+@RestController
+@RequestMapping("/api/alarm")
+@Api(tags = "监测预警")
+public class AlarmController {
+
+    @Autowired
+    private AlarmDataService service;
+
+    @GetMapping("/findByPage")
+    @ApiOperation("报警分页查询")
+    @Anonymous
+    public AjaxResult findByPage(@ApiParam("页码") long pageNum,
+                                  @ApiParam("每页条数") long pageSize,
+                                  @RequestParam(required = false) String warningType,
+                                  @RequestParam(required = false) Integer alarmStatus) {
+        Page<AlarmData> page = service.findByPage(pageNum, pageSize, null, warningType, null, alarmStatus);
+        return AjaxResult.success(page);
+    }
+
+    @GetMapping("/getById/{id}")
+    @ApiOperation("根据ID查询报警")
+    @Anonymous
+    public AjaxResult getById(@PathVariable String id) {
+        AlarmData entity = service.getById(id);
+        return entity != null ? AjaxResult.success(entity) : AjaxResult.error("报警信息不存在");
+    }
+
+    @PutMapping("/handle/{alarmId}")
+    @ApiOperation("处理报警")
+    @Log(title = "处理报警", businessType = BusinessType.UPDATE)
+    public AjaxResult handle(@PathVariable String alarmId,
+                              @RequestParam String handleUser,
+                              @RequestParam(required = false) String handleRemark) {
+        AlarmData entity = service.getById(alarmId);
+        if (entity == null) {
+            return AjaxResult.error("报警信息不存在");
+        }
+        entity.setAlarmStatus(1);
+        entity.setHandleTime(LocalDateTime.now());
+        entity.setHandleUser(handleUser);
+        entity.setHandleRemark(handleRemark);
+        entity.setUpdateTime(LocalDateTime.now());
+        boolean updated = service.updateById(entity);
+        return updated ? AjaxResult.success("处理成功") : AjaxResult.error("处理失败");
+    }
+
+    @GetMapping("/active-points")
+    @ApiOperation("获取未处理报警点位(报警一张图)")
+    @Anonymous
+    public AjaxResult getActivePoints() {
+        return AjaxResult.success(service.getAlarmDataList(null, null, null, 0));
+    }
+}

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

@@ -22,7 +22,7 @@ import java.util.Map;
 @Slf4j
 @RestController
 @RequestMapping("/EquipmentBase")
-@Api(tags = "设备基础信息")
+@Api(tags = "设备基础信息-物联网感知设备")
 public class EquipmentBaseController {
 
     @Autowired

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

@@ -0,0 +1,148 @@
+package com.zksy.web.controller.base;
+
+import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.zksy.base.domain.MonitorPoint;
+import com.zksy.base.service.MonitorPointService;
+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.web.bind.annotation.*;
+
+import java.util.List;
+import java.util.Map;
+
+@Slf4j
+@RestController
+@RequestMapping("/MonitorPoint")
+@Api(tags = "关键监测点管理")
+public class MonitorPointController {
+
+    @Autowired
+    private MonitorPointService service;
+
+    @GetMapping("/getById/{id}")
+    @ApiOperation(value = "获取监测点详情")
+    @Anonymous
+    public AjaxResult getById(@PathVariable String id) {
+        MonitorPoint entity = service.getById(id);
+        if (entity == null) {
+            return AjaxResult.error("该监测点信息不存在");
+        }
+        return AjaxResult.success(entity);
+    }
+
+    @Anonymous
+    @GetMapping("/findByPage")
+    @ApiOperation(value = "监测点分页查询")
+    public Page findByPage(
+            @ApiParam("页码") @RequestParam(defaultValue = "1") long pageNum,
+            @ApiParam("每页数量") @RequestParam(defaultValue = "10") long pageSize,
+            @ApiParam("监测点编码") @RequestParam(required = false) String pointCode,
+            @ApiParam("监测点名称") @RequestParam(required = false) String pointName,
+            @ApiParam("监测点类型") @RequestParam(required = false) String pointType,
+            @ApiParam("状态") @RequestParam(required = false) String status) {
+        return service.findByPage(pageNum, pageSize, pointCode, pointName, pointType, status);
+    }
+
+    @Anonymous
+    @GetMapping("/getList")
+    @ApiOperation(value = "查询所有监测点")
+    public AjaxResult getList() {
+        return AjaxResult.success(service.list());
+    }
+
+    @Anonymous
+    @GetMapping("/byNetwork/{networkId}")
+    @ApiOperation(value = "根据管网设施查询监测点")
+    public AjaxResult getPointsByNetwork(@PathVariable String networkId) {
+        List<MonitorPoint> list = service.getPointsByNetwork(networkId);
+        return AjaxResult.success(list);
+    }
+
+    @PostMapping("/save")
+    @ApiOperation(value = "新增监测点")
+    @Log(title = "新增监测点", businessType = BusinessType.INSERT)
+    public AjaxResult save(@RequestBody MonitorPoint entity) {
+        boolean saved = service.saveWithCheck(entity);
+        return saved ? AjaxResult.success("新增成功", saved)
+                : AjaxResult.error("新增失败", saved);
+    }
+
+    @PostMapping("/saveBatch")
+    @ApiOperation(value = "监测点批量新增")
+    @Log(title = "批量新增监测点", businessType = BusinessType.INSERT)
+    public AjaxResult saveBatch(@RequestBody List<MonitorPoint> entityList) {
+        if (CollectionUtils.isEmpty(entityList)) {
+            return AjaxResult.error("批量新增失败:列表不能为空");
+        }
+        boolean saved = service.saveBatchWithCheck(entityList);
+        return saved ? AjaxResult.success("新增成功", saved)
+                : AjaxResult.error("新增失败", saved);
+    }
+
+    @PutMapping("/updateById")
+    @ApiOperation(value = "监测点修改")
+    @Log(title = "修改监测点", businessType = BusinessType.UPDATE)
+    public AjaxResult updateById(@RequestBody MonitorPoint entity) {
+        boolean updated = service.updateWithCheck(entity);
+        return updated ? AjaxResult.success("修改成功", updated)
+                : AjaxResult.error("修改失败", updated);
+    }
+
+    @DeleteMapping("/deleteById")
+    @ApiOperation(value = "监测点删除")
+    @Log(title = "删除监测点", businessType = BusinessType.DELETE)
+    public AjaxResult deleteById(String id) {
+        boolean deleted = service.removeWithCheck(id);
+        return deleted ? AjaxResult.success("删除成功", deleted)
+                : AjaxResult.error("删除失败", deleted);
+    }
+
+    @DeleteMapping("/deleteBatchById")
+    @ApiOperation(value = "监测点批量删除")
+    @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);
+    }
+
+    @PostMapping("/bindEquipment")
+    @ApiOperation(value = "监测点关联设备")
+    @Log(title = "监测点关联设备", businessType = BusinessType.UPDATE)
+    @Anonymous
+    public AjaxResult bindEquipment(
+            @ApiParam("监测点ID") @RequestParam String pointId,
+            @ApiParam("设备ID列表") @RequestParam List<String> equipmentIds) {
+        boolean bound = service.bindEquipment(pointId, equipmentIds);
+        return bound ? AjaxResult.success("关联成功")
+                : AjaxResult.error("关联失败");
+    }
+
+    @PostMapping("/unbindEquipment")
+    @ApiOperation(value = "监测点取消关联设备")
+    @Log(title = "监测点取消关联设备", businessType = BusinessType.UPDATE)
+    @Anonymous
+    public AjaxResult unbindEquipment(
+            @ApiParam("监测点ID") @RequestParam String pointId,
+            @ApiParam("设备ID列表") @RequestParam List<String> equipmentIds) {
+        boolean unbound = service.unbindEquipment(pointId, equipmentIds);
+        return unbound ? AjaxResult.success("取消关联成功")
+                : AjaxResult.error("取消关联失败");
+    }
+
+    @GetMapping("/pointDetail/{pointId}")
+    @ApiOperation(value = "监测点详情(含关联设备和管网)")
+    @Anonymous
+    public AjaxResult getPointDetail(@PathVariable String pointId) {
+        Map<String, Object> detail = service.getPointDetail(pointId);
+        return AjaxResult.success(detail);
+    }
+}

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

@@ -0,0 +1,107 @@
+package com.zksy.web.controller.base;
+
+import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.zksy.base.domain.PipeNetworkBase;
+import com.zksy.base.service.PipeNetworkBaseService;
+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.web.bind.annotation.*;
+
+import java.util.List;
+
+@Slf4j
+@RestController
+@RequestMapping("/PipeNetworkBase")
+@Api(tags = "管网基础信息管理")
+public class PipeNetworkBaseController {
+
+    @Autowired
+    private PipeNetworkBaseService service;
+
+    @GetMapping("/getById/{id}")
+    @ApiOperation(value = "获取管网基础信息详情")
+    @Anonymous
+    public AjaxResult getById(@PathVariable String id) {
+        PipeNetworkBase entity = service.getById(id);
+        if (entity == null) {
+            return AjaxResult.error("该管网信息不存在");
+        }
+        return AjaxResult.success(entity);
+    }
+
+    @Anonymous
+    @GetMapping("/findByPage")
+    @ApiOperation(value = "管网基础信息分页查询")
+    public Page findByPage(
+            @ApiParam("页码") @RequestParam(defaultValue = "1") long pageNum,
+            @ApiParam("每页数量") @RequestParam(defaultValue = "10") long pageSize,
+            @ApiParam("设施编码") @RequestParam(required = false) String networkCode,
+            @ApiParam("设施名称") @RequestParam(required = false) String networkName,
+            @ApiParam("设施类型") @RequestParam(required = false) String networkType,
+            @ApiParam("状态") @RequestParam(required = false) String status) {
+        return service.findByPage(pageNum, pageSize, networkCode, networkName, networkType, status);
+    }
+
+    @Anonymous
+    @GetMapping("/getList")
+    @ApiOperation(value = "查询所有管网基础信息")
+    public AjaxResult getList() {
+        return AjaxResult.success(service.list());
+    }
+
+    @PostMapping("/save")
+    @ApiOperation(value = "新增管网基础信息")
+    @Log(title = "新增管网基础信息", businessType = BusinessType.INSERT)
+    public AjaxResult save(@RequestBody PipeNetworkBase entity) {
+        boolean saved = service.saveWithCheck(entity);
+        return saved ? AjaxResult.success("新增成功", saved)
+                : AjaxResult.error("新增失败", saved);
+    }
+
+    @PostMapping("/saveBatch")
+    @ApiOperation(value = "管网基础信息批量新增")
+    @Log(title = "批量新增管网基础信息", businessType = BusinessType.INSERT)
+    public AjaxResult saveBatch(@RequestBody List<PipeNetworkBase> entityList) {
+        if (CollectionUtils.isEmpty(entityList)) {
+            return AjaxResult.error("批量新增失败:列表不能为空");
+        }
+        boolean saved = service.saveBatchWithCheck(entityList);
+        return saved ? AjaxResult.success("新增成功", saved)
+                : AjaxResult.error("新增失败", saved);
+    }
+
+    @PutMapping("/updateById")
+    @ApiOperation(value = "管网基础信息修改")
+    @Log(title = "修改管网基础信息", businessType = BusinessType.UPDATE)
+    public AjaxResult updateById(@RequestBody PipeNetworkBase entity) {
+        boolean updated = service.updateWithCheck(entity);
+        return updated ? AjaxResult.success("修改成功", updated)
+                : AjaxResult.error("修改失败", updated);
+    }
+
+    @DeleteMapping("/deleteById")
+    @ApiOperation(value = "管网基础信息删除")
+    @Log(title = "删除管网基础信息", businessType = BusinessType.DELETE)
+    public AjaxResult deleteById(String id) {
+        boolean deleted = service.removeWithCheck(id);
+        return deleted ? AjaxResult.success("删除成功", deleted)
+                : AjaxResult.error("删除失败", deleted);
+    }
+
+    @DeleteMapping("/deleteBatchById")
+    @ApiOperation(value = "管网基础信息批量删除")
+    @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);
+    }
+}

+ 118 - 0
pipe-network-service/zksy-admin/src/main/java/com/zksy/web/controller/gasbasic/GasEquipmentController.java

@@ -0,0 +1,118 @@
+package com.zksy.web.controller.gasbasic;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.zksy.base.domain.EquipmentPointRel;
+import com.zksy.base.domain.EquipmentStatus;
+import com.zksy.base.domain.vo.EquipmentFullVO;
+import com.zksy.base.service.EquipmentBaseService;
+import com.zksy.base.mapper.EquipmentPointRelMapper;
+import com.zksy.base.mapper.EquipmentStatusMapper;
+import com.zksy.common.annotation.Anonymous;
+import com.zksy.common.core.domain.AjaxResult;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+@Slf4j
+@RestController
+@RequestMapping("/api/equipment")
+@Api(tags = "监测设备管理")
+public class GasEquipmentController {
+
+    @Autowired
+    private EquipmentBaseService equipmentBaseService;
+
+    @Autowired
+    private EquipmentStatusMapper equipmentStatusMapper;
+
+    @Autowired
+    private EquipmentPointRelMapper equipmentPointRelMapper;
+
+    @GetMapping("/status/{equipmentId}")
+    @ApiOperation("获取设备实时运行状态")
+    @Anonymous
+    public AjaxResult getEquipmentStatus(@PathVariable String equipmentId) {
+        LambdaQueryWrapper<EquipmentStatus> wrapper = new LambdaQueryWrapper<>();
+        wrapper.eq(EquipmentStatus::getEquipmentId, equipmentId);
+        EquipmentStatus status = equipmentStatusMapper.selectOne(wrapper);
+        return status != null ? AjaxResult.success(status) : AjaxResult.error("设备状态信息不存在");
+    }
+
+    @GetMapping("/abnormal")
+    @ApiOperation("异常设备列表(关联报警统计)")
+    @Anonymous
+    public AjaxResult getAbnormalList() {
+        LambdaQueryWrapper<EquipmentStatus> wrapper = new LambdaQueryWrapper<>();
+        wrapper.eq(EquipmentStatus::getAlarmStatus, 1);
+        List<EquipmentStatus> list = equipmentStatusMapper.selectList(wrapper);
+        return AjaxResult.success(list);
+    }
+
+    @GetMapping("/point-rel/{equipmentId}")
+    @ApiOperation("获取设备关联的测点")
+    @Anonymous
+    public AjaxResult getPointRelByEquipment(@PathVariable String equipmentId) {
+        LambdaQueryWrapper<EquipmentPointRel> wrapper = new LambdaQueryWrapper<>();
+        wrapper.eq(EquipmentPointRel::getEquipmentId, equipmentId);
+        List<EquipmentPointRel> list = equipmentPointRelMapper.selectList(wrapper);
+        return AjaxResult.success(list);
+    }
+
+    @PostMapping("/point-rel/save")
+    @ApiOperation("新增设备测点关联")
+    @Anonymous
+    public AjaxResult savePointRel(@RequestBody EquipmentPointRel rel) {
+        boolean saved = equipmentPointRelMapper.insert(rel) > 0;
+        return saved ? AjaxResult.success("关联成功") : AjaxResult.error("关联失败");
+    }
+
+    @DeleteMapping("/point-rel/delete")
+    @ApiOperation("删除设备测点关联")
+    @Anonymous
+    public AjaxResult deletePointRel(@RequestParam String relId) {
+        boolean deleted = equipmentPointRelMapper.deleteById(relId) > 0;
+        return deleted ? AjaxResult.success("删除成功") : AjaxResult.error("删除失败");
+    }
+
+    @GetMapping("/point-rel/by-point/{pointId}")
+    @ApiOperation("获取管点关联的设备")
+    @Anonymous
+    public AjaxResult getPointRelByPoint(@PathVariable String pointId) {
+        LambdaQueryWrapper<EquipmentPointRel> wrapper = new LambdaQueryWrapper<>();
+        wrapper.eq(EquipmentPointRel::getPointId, pointId);
+        List<EquipmentPointRel> list = equipmentPointRelMapper.selectList(wrapper);
+        return AjaxResult.success(list);
+    }
+
+    @PostMapping("/point-rel/save-batch")
+    @ApiOperation("批量关联设备到管点")
+    @Anonymous
+    public AjaxResult savePointRelBatch(@RequestBody List<EquipmentPointRel> relList) {
+        if (relList == null || relList.isEmpty()) {
+            return AjaxResult.error("关联列表不能为空");
+        }
+        for (EquipmentPointRel rel : relList) {
+            equipmentPointRelMapper.insert(rel);
+        }
+        return AjaxResult.success("批量关联成功");
+    }
+
+    @GetMapping("/findFullByPage")
+    @ApiOperation("设备全信息分页查询(联查管点→管线→状态)")
+    @Anonymous
+    public AjaxResult findFullByPage(@RequestParam(defaultValue = "1") Long pageNum,
+                                     @RequestParam(defaultValue = "10") Long pageSize,
+                                     @RequestParam(required = false) String equipmentCode,
+                                     @RequestParam(required = false) String equipmentName,
+                                     @RequestParam(required = false) String equipmentModel,
+                                     @RequestParam(required = false) String manufacturer) {
+        Page<EquipmentFullVO> page = equipmentBaseService.findFullByPage(pageNum, pageSize,
+                equipmentCode, equipmentName, equipmentModel, manufacturer);
+        return AjaxResult.success(page);
+    }
+}

+ 79 - 0
pipe-network-service/zksy-admin/src/main/java/com/zksy/web/controller/gasbasic/GasManholeController.java

@@ -0,0 +1,79 @@
+package com.zksy.web.controller.gasbasic;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.zksy.base.domain.ManholeBase;
+import com.zksy.base.dto.ManholePageInDTO;
+import com.zksy.base.service.ManholeBaseService;
+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 lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+@Slf4j
+@RestController
+@RequestMapping("/api/manhole")
+@Api(tags = "窨井管理")
+public class GasManholeController {
+
+    @Autowired
+    private ManholeBaseService service;
+
+    @GetMapping("/findByPage")
+    @ApiOperation("窨井分页查询")
+    @Anonymous
+    public AjaxResult findByPage(ManholePageInDTO dto) {
+        Page<ManholeBase> page = service.findByPage(dto);
+        return AjaxResult.success(page);
+    }
+
+    @GetMapping("/getById/{id}")
+    @ApiOperation("根据ID查询窨井")
+    @Anonymous
+    public AjaxResult getById(@PathVariable String id) {
+        ManholeBase entity = service.getById(id);
+        return entity != null ? AjaxResult.success(entity) : AjaxResult.error("窨井信息不存在");
+    }
+
+    @GetMapping("/options")
+    @ApiOperation("窨井下拉选项")
+    @Anonymous
+    public AjaxResult options() {
+        return AjaxResult.success(service.getOptions());
+    }
+
+    @GetMapping("/list")
+    @ApiOperation("窨井列表(全量,用于地图展示)")
+    @Anonymous
+    public AjaxResult list() {
+        return AjaxResult.success(service.list());
+    }
+
+    @PostMapping("/save")
+    @ApiOperation("新增窨井")
+    @Log(title = "新增窨井信息", businessType = BusinessType.INSERT)
+    public AjaxResult save(@RequestBody ManholeBase entity) {
+        boolean saved = service.save(entity);
+        return saved ? AjaxResult.success("新增成功", saved) : AjaxResult.error("新增失败");
+    }
+
+    @PutMapping("/updateById")
+    @ApiOperation("修改窨井")
+    @Log(title = "修改窨井信息", businessType = BusinessType.UPDATE)
+    public AjaxResult updateById(@RequestBody ManholeBase entity) {
+        boolean updated = service.updateById(entity);
+        return updated ? AjaxResult.success("修改成功", updated) : AjaxResult.error("修改失败");
+    }
+
+    @DeleteMapping("/deleteById")
+    @ApiOperation("删除窨井")
+    @Log(title = "删除窨井信息", businessType = BusinessType.DELETE)
+    public AjaxResult deleteById(@RequestParam String id) {
+        boolean deleted = service.removeById(id);
+        return deleted ? AjaxResult.success("删除成功") : AjaxResult.error("删除失败");
+    }
+}

+ 65 - 0
pipe-network-service/zksy-admin/src/main/java/com/zksy/web/controller/gasbasic/GasMonitorPointController.java

@@ -0,0 +1,65 @@
+package com.zksy.web.controller.gasbasic;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.zksy.base.domain.MonitorPoint;
+import com.zksy.base.dto.MonitorPointPageInDTO;
+import com.zksy.base.service.MonitorPointService;
+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 lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+@Slf4j
+@RestController
+@RequestMapping("/api/monitor-point")
+@Api(tags = "监测点管理")
+public class GasMonitorPointController {
+
+    @Autowired
+    private MonitorPointService service;
+
+    @GetMapping("/findByPage")
+    @ApiOperation("监测点分页查询")
+    @Anonymous
+    public AjaxResult findByPage(MonitorPointPageInDTO dto) {
+        Page<MonitorPoint> page = service.queryByPage(dto);
+        return AjaxResult.success(page);
+    }
+
+    @GetMapping("/getById/{id}")
+    @ApiOperation("根据ID查询监测点")
+    @Anonymous
+    public AjaxResult getById(@PathVariable String id) {
+        MonitorPoint entity = service.getById(id);
+        return entity != null ? AjaxResult.success(entity) : AjaxResult.error("监测点信息不存在");
+    }
+
+    @PostMapping("/save")
+    @ApiOperation("新增监测点")
+    @Log(title = "新增监测点", businessType = BusinessType.INSERT)
+    public AjaxResult save(@RequestBody MonitorPoint entity) {
+        boolean saved = service.save(entity);
+        return saved ? AjaxResult.success("新增成功", saved) : AjaxResult.error("新增失败");
+    }
+
+    @PutMapping("/updateById")
+    @ApiOperation("修改监测点")
+    @Log(title = "修改监测点", businessType = BusinessType.UPDATE)
+    public AjaxResult updateById(@RequestBody MonitorPoint entity) {
+        boolean updated = service.updateById(entity);
+        return updated ? AjaxResult.success("修改成功", updated) : AjaxResult.error("修改失败");
+    }
+
+    @DeleteMapping("/deleteById")
+    @ApiOperation("删除监测点")
+    @Log(title = "删除监测点", businessType = BusinessType.DELETE)
+    public AjaxResult deleteById(@RequestParam String id) {
+        boolean deleted = service.removeById(id);
+        return deleted ? AjaxResult.success("删除成功") : AjaxResult.error("删除失败");
+    }
+}

+ 81 - 0
pipe-network-service/zksy-admin/src/main/java/com/zksy/web/controller/gasbasic/GasPipeNetworkController.java

@@ -0,0 +1,81 @@
+package com.zksy.web.controller.gasbasic;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.zksy.base.domain.PipeNetworkBase;
+import com.zksy.base.dto.PipeNetworkPageInDTO;
+import com.zksy.base.service.PipeNetworkBaseService;
+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 lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+@Slf4j
+@RestController
+@RequestMapping("/api/pipe-network")
+@Api(tags = "燃气管网基础数据")
+public class GasPipeNetworkController {
+
+    @Autowired
+    private PipeNetworkBaseService service;
+
+    @GetMapping("/findByPage")
+    @ApiOperation("管网分页查询")
+    @Anonymous
+    public AjaxResult findByPage(PipeNetworkPageInDTO dto) {
+        Page<PipeNetworkBase> page = service.queryByPage(dto);
+        return AjaxResult.success(page);
+    }
+
+    @GetMapping("/getById/{id}")
+    @ApiOperation("根据ID查询管网")
+    @Anonymous
+    public AjaxResult getById(@PathVariable String id) {
+        PipeNetworkBase entity = service.getById(id);
+        return entity != null ? AjaxResult.success(entity) : AjaxResult.error("管网信息不存在");
+    }
+
+    @GetMapping("/options")
+    @ApiOperation("管网下拉选项")
+    @Anonymous
+    public AjaxResult options() {
+        return AjaxResult.success(service.getOptions());
+    }
+
+    @PostMapping("/save")
+    @ApiOperation("新增管网")
+    @Log(title = "新增管网基础数据", businessType = BusinessType.INSERT)
+    public AjaxResult save(@RequestBody PipeNetworkBase entity) {
+        boolean saved = service.save(entity);
+        return saved ? AjaxResult.success("新增成功", saved) : AjaxResult.error("新增失败");
+    }
+
+    @PutMapping("/updateById")
+    @ApiOperation("修改管网")
+    @Log(title = "修改管网基础数据", businessType = BusinessType.UPDATE)
+    public AjaxResult updateById(@RequestBody PipeNetworkBase entity) {
+        boolean updated = service.updateById(entity);
+        return updated ? AjaxResult.success("修改成功", updated) : AjaxResult.error("修改失败");
+    }
+
+    @DeleteMapping("/deleteById")
+    @ApiOperation("删除管网")
+    @Log(title = "删除管网基础数据", businessType = BusinessType.DELETE)
+    public AjaxResult deleteById(@RequestParam String id) {
+        boolean deleted = service.removeById(id);
+        return deleted ? AjaxResult.success("删除成功") : AjaxResult.error("删除失败");
+    }
+
+    @GetMapping("/export")
+    @ApiOperation("导出Excel")
+    @Anonymous
+    public AjaxResult exportData(@RequestParam(required = false) String networkName,
+                                  @RequestParam(required = false) String status) {
+        // TODO: 实现Excel导出
+        return AjaxResult.success("导出功能待实现");
+    }
+}

+ 129 - 0
pipe-network-service/zksy-admin/src/main/java/com/zksy/web/controller/gasbasic/GasPipePointController.java

@@ -0,0 +1,129 @@
+package com.zksy.web.controller.gasbasic;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.zksy.base.domain.GasPipePoint;
+import com.zksy.base.domain.GasPipePointDeviceRel;
+import com.zksy.base.dto.GasPipePointPageInDTO;
+import com.zksy.base.mapper.GasPipePointDeviceRelMapper;
+import com.zksy.base.service.GasPipePointService;
+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 lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+@Slf4j
+@RestController
+@RequestMapping("/api/gas-pipe-point")
+@Api(tags = "燃气管点管理")
+public class GasPipePointController {
+
+    @Autowired
+    private GasPipePointService service;
+
+    @Autowired
+    private GasPipePointDeviceRelMapper deviceRelMapper;
+
+    @GetMapping("/findByPage")
+    @ApiOperation("管点分页查询")
+    @Anonymous
+    public AjaxResult findByPage(GasPipePointPageInDTO dto) {
+        Page<GasPipePoint> page = service.queryByPage(dto);
+        return AjaxResult.success(page);
+    }
+
+    @GetMapping("/getById/{id}")
+    @ApiOperation("根据ID查询管点")
+    @Anonymous
+    public AjaxResult getById(@PathVariable Long id) {
+        GasPipePoint entity = service.getById(id);
+        return entity != null ? AjaxResult.success(entity) : AjaxResult.error("管点信息不存在");
+    }
+
+    @GetMapping("/list-by-network/{networkId}")
+    @ApiOperation("按管线ID查询管点列表")
+    @Anonymous
+    public AjaxResult listByNetworkId(@PathVariable String networkId) {
+        return AjaxResult.success(service.listByNetworkId(networkId));
+    }
+
+    @GetMapping("/options")
+    @ApiOperation("管点下拉选项")
+    @Anonymous
+    public AjaxResult options() {
+        return AjaxResult.success(service.getOptions());
+    }
+
+    @PostMapping("/save")
+    @ApiOperation("新增管点")
+    @Log(title = "新增燃气管点", businessType = BusinessType.INSERT)
+    public AjaxResult save(@RequestBody GasPipePoint entity) {
+        boolean saved = service.saveWithCheck(entity);
+        return saved ? AjaxResult.success("新增成功", saved) : AjaxResult.error("新增失败");
+    }
+
+    @PutMapping("/updateById")
+    @ApiOperation("修改管点")
+    @Log(title = "修改燃气管点", businessType = BusinessType.UPDATE)
+    public AjaxResult updateById(@RequestBody GasPipePoint entity) {
+        boolean updated = service.updateWithCheck(entity);
+        return updated ? AjaxResult.success("修改成功", updated) : AjaxResult.error("修改失败");
+    }
+
+    @DeleteMapping("/deleteById")
+    @ApiOperation("删除管点")
+    @Log(title = "删除燃气管点", businessType = BusinessType.DELETE)
+    public AjaxResult deleteById(@RequestParam Long id) {
+        boolean deleted = service.removeWithCheck(id);
+        return deleted ? AjaxResult.success("删除成功") : AjaxResult.error("删除失败");
+    }
+
+    // ============ 管点-设备关联 ============
+
+    @GetMapping("/device/list/{pointId}")
+    @ApiOperation("获取管点关联的设备列表")
+    @Anonymous
+    public AjaxResult listDevices(@PathVariable Long pointId) {
+        LambdaQueryWrapper<GasPipePointDeviceRel> wrapper = new LambdaQueryWrapper<>();
+        wrapper.eq(GasPipePointDeviceRel::getPointId, pointId);
+        wrapper.orderByDesc(GasPipePointDeviceRel::getCreateTime);
+        List<GasPipePointDeviceRel> list = deviceRelMapper.selectList(wrapper);
+        return AjaxResult.success(list);
+    }
+
+    @PostMapping("/device/save")
+    @ApiOperation("关联设备到管点")
+    @Anonymous
+    public AjaxResult saveDeviceRel(@RequestBody GasPipePointDeviceRel rel) {
+        boolean saved = deviceRelMapper.insert(rel) > 0;
+        return saved ? AjaxResult.success("关联成功") : AjaxResult.error("关联失败");
+    }
+
+    @PostMapping("/device/save-batch")
+    @ApiOperation("批量关联设备到管点")
+    @Anonymous
+    public AjaxResult saveDeviceRelBatch(@RequestBody List<GasPipePointDeviceRel> relList) {
+        if (relList == null || relList.isEmpty()) {
+            return AjaxResult.error("关联列表不能为空");
+        }
+        for (GasPipePointDeviceRel rel : relList) {
+            deviceRelMapper.insert(rel);
+        }
+        return AjaxResult.success("批量关联成功");
+    }
+
+    @DeleteMapping("/device/delete")
+    @ApiOperation("删除管点设备关联")
+    @Anonymous
+    public AjaxResult deleteDeviceRel(@RequestParam Long relId) {
+        boolean deleted = deviceRelMapper.deleteById(relId) > 0;
+        return deleted ? AjaxResult.success("删除成功") : AjaxResult.error("删除失败");
+    }
+}

+ 72 - 0
pipe-network-service/zksy-admin/src/main/java/com/zksy/web/controller/gasbasic/GasRepairRecordController.java

@@ -0,0 +1,72 @@
+package com.zksy.web.controller.gasbasic;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.zksy.base.domain.PipeRepairRecord;
+import com.zksy.base.dto.RepairRecordPageInDTO;
+import com.zksy.base.service.PipeRepairRecordService;
+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 lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+@Slf4j
+@RestController
+@RequestMapping("/api/repair-record")
+@Api(tags = "燃气管网维修记录")
+public class GasRepairRecordController {
+
+    @Autowired
+    private PipeRepairRecordService service;
+
+    @GetMapping("/findByPage")
+    @ApiOperation("维修记录分页查询")
+    @Anonymous
+    public AjaxResult findByPage(RepairRecordPageInDTO dto) {
+        Page<PipeRepairRecord> page = service.findByPage(dto);
+        return AjaxResult.success(page);
+    }
+
+    @GetMapping("/getById/{id}")
+    @ApiOperation("根据ID查询维修记录")
+    @Anonymous
+    public AjaxResult getById(@PathVariable String id) {
+        PipeRepairRecord entity = service.getById(id);
+        return entity != null ? AjaxResult.success(entity) : AjaxResult.error("维修记录不存在");
+    }
+
+    @GetMapping("/list-by-network/{networkId}")
+    @ApiOperation("按管网ID查询历史维修记录")
+    @Anonymous
+    public AjaxResult listByNetworkId(@PathVariable String networkId) {
+        return AjaxResult.success(service.listByNetworkId(networkId));
+    }
+
+    @PostMapping("/save")
+    @ApiOperation("新增维修记录")
+    @Log(title = "新增维修记录", businessType = BusinessType.INSERT)
+    public AjaxResult save(@RequestBody PipeRepairRecord entity) {
+        boolean saved = service.save(entity);
+        return saved ? AjaxResult.success("新增成功", saved) : AjaxResult.error("新增失败");
+    }
+
+    @PutMapping("/updateById")
+    @ApiOperation("修改维修记录")
+    @Log(title = "修改维修记录", businessType = BusinessType.UPDATE)
+    public AjaxResult updateById(@RequestBody PipeRepairRecord entity) {
+        boolean updated = service.updateById(entity);
+        return updated ? AjaxResult.success("修改成功", updated) : AjaxResult.error("修改失败");
+    }
+
+    @DeleteMapping("/deleteById")
+    @ApiOperation("删除维修记录")
+    @Log(title = "删除维修记录", businessType = BusinessType.DELETE)
+    public AjaxResult deleteById(@RequestParam String id) {
+        boolean deleted = service.removeById(id);
+        return deleted ? AjaxResult.success("删除成功") : AjaxResult.error("删除失败");
+    }
+}

+ 120 - 0
pipe-network-service/zksy-admin/src/main/java/com/zksy/web/controller/gasbasic/GisController.java

@@ -0,0 +1,120 @@
+package com.zksy.web.controller.gasbasic;
+
+import com.zksy.base.domain.EquipmentBase;
+import com.zksy.base.domain.ManholeBase;
+import com.zksy.base.domain.PipeNetworkBase;
+import com.zksy.base.service.EquipmentBaseService;
+import com.zksy.base.service.ManholeBaseService;
+import com.zksy.base.service.PipeNetworkBaseService;
+import com.zksy.common.annotation.Anonymous;
+import com.zksy.common.core.domain.AjaxResult;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.*;
+
+@Slf4j
+@RestController
+@RequestMapping("/api/gis")
+@Api(tags = "GIS一张图")
+public class GisController {
+
+    @Autowired
+    private PipeNetworkBaseService pipeNetworkService;
+
+    @Autowired
+    private ManholeBaseService manholeService;
+
+    @Autowired
+    private EquipmentBaseService equipmentService;
+
+    @GetMapping("/pipe-lines")
+    @ApiOperation("获取管网GeoJSON数据")
+    @Anonymous
+    public AjaxResult getPipeLines(@RequestParam(required = false) String networkType,
+                                    @RequestParam(required = false) String status) {
+        List<PipeNetworkBase> list = pipeNetworkService.list();
+        List<Map<String, Object>> features = new ArrayList<>();
+        for (PipeNetworkBase pipe : list) {
+            if (pipe.getLongitude() == null || pipe.getLatitude() == null) continue;
+            Map<String, Object> feature = new HashMap<>();
+            feature.put("type", "Feature");
+            Map<String, Object> props = new HashMap<>();
+            props.put("networkId", pipe.getNetworkId());
+            props.put("networkName", pipe.getNetworkName());
+            props.put("networkType", pipe.getNetworkType());
+            props.put("networkCode", pipe.getNetworkCode());
+            props.put("status", pipe.getStatus());
+            props.put("material", pipe.getMaterial());
+            feature.put("properties", props);
+            Map<String, Object> geometry = new HashMap<>();
+            geometry.put("type", "Point");
+            geometry.put("coordinates", new double[]{pipe.getLongitude().doubleValue(), pipe.getLatitude().doubleValue()});
+            feature.put("geometry", geometry);
+            features.add(feature);
+        }
+        Map<String, Object> geojson = new HashMap<>();
+        geojson.put("type", "FeatureCollection");
+        geojson.put("features", features);
+        return AjaxResult.success(geojson);
+    }
+
+    @GetMapping("/manholes")
+    @ApiOperation("获取窨井点位")
+    @Anonymous
+    public AjaxResult getManholes() {
+        List<ManholeBase> list = manholeService.list();
+        List<Map<String, Object>> features = new ArrayList<>();
+        for (ManholeBase m : list) {
+            if (m.getLongitude() == null || m.getLatitude() == null) continue;
+            Map<String, Object> feature = new HashMap<>();
+            feature.put("type", "Feature");
+            Map<String, Object> props = new HashMap<>();
+            props.put("manholeId", m.getManholeId());
+            props.put("manholeName", m.getManholeName());
+            props.put("manholeCode", m.getManholeCode());
+            props.put("status", m.getStatus());
+            feature.put("properties", props);
+            Map<String, Object> geometry = new HashMap<>();
+            geometry.put("type", "Point");
+            geometry.put("coordinates", new double[]{m.getLongitude().doubleValue(), m.getLatitude().doubleValue()});
+            feature.put("geometry", geometry);
+            features.add(feature);
+        }
+        Map<String, Object> geojson = new HashMap<>();
+        geojson.put("type", "FeatureCollection");
+        geojson.put("features", features);
+        return AjaxResult.success(geojson);
+    }
+
+    @GetMapping("/equipments")
+    @ApiOperation("获取设备点位")
+    @Anonymous
+    public AjaxResult getEquipments(@RequestParam(required = false) String equipmentTypeId) {
+        List<EquipmentBase> list = equipmentService.list();
+        List<Map<String, Object>> features = new ArrayList<>();
+        for (EquipmentBase e : list) {
+            if (e.getLongitude() == null || e.getLatitude() == null) continue;
+            Map<String, Object> feature = new HashMap<>();
+            feature.put("type", "Feature");
+            Map<String, Object> props = new HashMap<>();
+            props.put("equipmentId", e.getEquipmentId());
+            props.put("equipmentName", e.getEquipmentName());
+            props.put("equipmentCode", e.getEquipmentCode());
+            props.put("equipmentTypeId", e.getEquipmentTypeId());
+            feature.put("properties", props);
+            Map<String, Object> geometry = new HashMap<>();
+            geometry.put("type", "Point");
+            geometry.put("coordinates", new double[]{e.getLongitude().doubleValue(), e.getLatitude().doubleValue()});
+            feature.put("geometry", geometry);
+            features.add(feature);
+        }
+        Map<String, Object> geojson = new HashMap<>();
+        geojson.put("type", "FeatureCollection");
+        geojson.put("features", features);
+        return AjaxResult.success(geojson);
+    }
+}

+ 151 - 0
pipe-network-service/zksy-admin/src/main/java/com/zksy/web/controller/hidden/HazardController.java

@@ -0,0 +1,151 @@
+package com.zksy.web.controller.hidden;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.zksy.base.domain.HazardHiddenAccount;
+import com.zksy.base.dto.HazardPageInDTO;
+import com.zksy.base.service.HazardHiddenAccountService;
+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 lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+@Slf4j
+@RestController
+@RequestMapping("/api/hazard")
+@Api(tags = "隐患台账管理")
+public class HazardController {
+
+    @Autowired
+    private HazardHiddenAccountService service;
+
+    @GetMapping("/page")
+    @ApiOperation("隐患分页查询")
+    @Anonymous
+    public AjaxResult page(HazardPageInDTO dto) {
+        Page<HazardHiddenAccount> result = service.findByPage(dto);
+        return AjaxResult.success(result);
+    }
+
+    @GetMapping("/getById/{id}")
+    @ApiOperation("根据ID查询隐患")
+    @Anonymous
+    public AjaxResult getById(@PathVariable String id) {
+        HazardHiddenAccount entity = service.getById(id);
+        return entity != null ? AjaxResult.success(entity) : AjaxResult.error("隐患信息不存在");
+    }
+
+    @PostMapping("/save")
+    @ApiOperation("新增隐患")
+    @Log(title = "新增隐患台账", businessType = BusinessType.INSERT)
+    public AjaxResult save(@RequestBody HazardHiddenAccount entity) {
+        boolean saved = service.save(entity);
+        return saved ? AjaxResult.success("新增成功", saved) : AjaxResult.error("新增失败");
+    }
+
+    @PutMapping("/updateById")
+    @ApiOperation("修改隐患")
+    @Log(title = "修改隐患台账", businessType = BusinessType.UPDATE)
+    public AjaxResult updateById(@RequestBody HazardHiddenAccount entity) {
+        boolean updated = service.updateById(entity);
+        return updated ? AjaxResult.success("修改成功", updated) : AjaxResult.error("修改失败");
+    }
+
+    @DeleteMapping("/deleteById")
+    @ApiOperation("删除隐患")
+    @Log(title = "删除隐患台账", businessType = BusinessType.DELETE)
+    public AjaxResult deleteById(@RequestParam String id) {
+        boolean deleted = service.removeById(id);
+        return deleted ? AjaxResult.success("删除成功") : AjaxResult.error("删除失败");
+    }
+
+    @PutMapping("/submit/{hazardId}")
+    @ApiOperation("隐患报送")
+    @Log(title = "隐患报送", businessType = BusinessType.UPDATE)
+    public AjaxResult submit(@PathVariable String hazardId) {
+        boolean submitted = service.submitHazard(hazardId);
+        return submitted ? AjaxResult.success("报送成功") : AjaxResult.error("报送失败");
+    }
+
+    @GetMapping("/map-points")
+    @ApiOperation("获取未闭环隐患点位(隐患一张图)")
+    @Anonymous
+    public AjaxResult getMapPoints() {
+        return AjaxResult.success(service.getActiveMapPoints());
+    }
+
+    @GetMapping("/statistics/type")
+    @ApiOperation("按隐患类型统计")
+    @Anonymous
+    public AjaxResult statisticsByType(
+            @RequestParam(required = false) String startDate,
+            @RequestParam(required = false) String endDate) {
+        return AjaxResult.success(service.statisticsByType(startDate, endDate));
+    }
+
+    @GetMapping("/statistics/status")
+    @ApiOperation("按整改状态统计")
+    @Anonymous
+    public AjaxResult statisticsByStatus(
+            @RequestParam(required = false) String startDate,
+            @RequestParam(required = false) String endDate) {
+        return AjaxResult.success(service.statisticsByStatus(startDate, endDate));
+    }
+
+    @GetMapping("/statistics/overview")
+    @ApiOperation("隐患统计概览(总数、已整改、按等级分布)")
+    @Anonymous
+    public AjaxResult statisticsOverview(
+            @RequestParam(required = false) String startDate,
+            @RequestParam(required = false) String endDate) {
+        return AjaxResult.success(service.statisticsOverview(startDate, endDate));
+    }
+
+    @GetMapping("/statistics/level")
+    @ApiOperation("按隐患等级统计")
+    @Anonymous
+    public AjaxResult statisticsByLevel(
+            @RequestParam(required = false) String startDate,
+            @RequestParam(required = false) String endDate) {
+        return AjaxResult.success(service.statisticsByLevel(startDate, endDate));
+    }
+
+    @GetMapping("/statistics/region")
+    @ApiOperation("按上报单位(区域)统计")
+    @Anonymous
+    public AjaxResult statisticsByRegion(
+            @RequestParam(required = false) String startDate,
+            @RequestParam(required = false) String endDate) {
+        return AjaxResult.success(service.statisticsByRegion(startDate, endDate));
+    }
+
+    @GetMapping("/statistics/type-timeline")
+    @ApiOperation("隐患类型时间线统计(按天汇总,每条类型一条折线)")
+    @Anonymous
+    public AjaxResult statisticsTypeTimeline(
+            @RequestParam(required = false) String startDate,
+            @RequestParam(required = false) String endDate) {
+        return AjaxResult.success(service.statisticsTypeTimeline(startDate, endDate));
+    }
+
+    @GetMapping("/statistics/status-timeline")
+    @ApiOperation("整改状态时间线统计(按天汇总,每个状态一组柱)")
+    @Anonymous
+    public AjaxResult statisticsStatusTimeline(
+            @RequestParam(required = false) String startDate,
+            @RequestParam(required = false) String endDate) {
+        return AjaxResult.success(service.statisticsStatusTimeline(startDate, endDate));
+    }
+
+    @GetMapping("/export")
+    @ApiOperation("隐患导出Excel")
+    @Anonymous
+    public AjaxResult exportData() {
+        // TODO: 实现Excel导出
+        return AjaxResult.success("导出功能待实现");
+    }
+}

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

@@ -0,0 +1,161 @@
+package com.zksy.web.controller.manhole;
+
+
+import cn.hutool.core.bean.BeanUtil;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.zksy.base.domain.CaseInfo;
+import com.zksy.base.domain.EquipmentBase;
+import com.zksy.base.domain.EquipmentStatus;
+import com.zksy.base.domain.EquipmentType;
+import com.zksy.base.service.CaseInfoService;
+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.CaseInfoPageInDTO;
+import com.zksy.manhole.dto.in.CaseInfoSaveInDTO;
+import com.zksy.manhole.dto.in.CaseInfoVerifyInDTO;
+import com.zksy.manhole.dto.out.CaseInfoOutDTO;
+import com.zksy.manhole.dto.out.EquipmentStatusOutDTO;
+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.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+import java.util.Date;
+import java.util.Random;
+
+/**
+ * 窨井盖监测系统-案件流转管理Controller
+ * 
+ * @author xianggx
+ * @date 2026-05-06
+ */
+@RestController
+@RequestMapping("/manhole/caseInfo")
+@Api(tags = "窨井盖监测系统-案件流转管理")
+public class CaseInfoController extends BaseController
+{
+    @Autowired
+    private CaseInfoService caseInfoService;
+
+    @Autowired
+    private EquipmentBaseService equipmentBaseService;
+
+    @Autowired
+    private EquipmentStatusService equipmentStatusService;
+
+    @Autowired
+    private EquipmentTypeService equipmentTypeService;
+
+    /**
+     * 生成案件编号
+     * @return
+     */
+    public static String generateCaseNo() {
+        // 1. 获取当前时间,格式化为14位年月日时分秒
+        String currentDateTime = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"));
+        // 2. 生成4位随机数,不足补0
+        String randomNum = String.format("%04d", new Random().nextInt(10000));
+        // 3. 拼接完整编号
+        return "CS" + currentDateTime + randomNum;
+    }
+
+    /**
+     * 分页查询案件信息列表
+     */
+    @Anonymous
+    @GetMapping(value = "/findByPage")
+    @ApiOperation(value = "分页查询案件信息列表")
+    public AjaxResult2<Page<CaseInfoOutDTO>> findByPage(@RequestBody CaseInfoPageInDTO pageInDTO)
+    {
+        return AjaxResult2.success(caseInfoService.findByPage(pageInDTO));
+    }
+
+    /**
+     * 获取案件信息详情
+     */
+    @Anonymous
+    @GetMapping(value = "/getById/{id}")
+    @ApiOperation(value = "获取案件信息详情")
+    public AjaxResult2<CaseInfoOutDTO> getById(@PathVariable("id") Long id)
+    {
+        CaseInfo caseInfo = caseInfoService.getById(id);
+        if(caseInfo == null){
+            return AjaxResult2.error("案件ID不存在");
+        }
+        CaseInfoOutDTO outDTO = BeanUtil.copyProperties(caseInfo, CaseInfoOutDTO.class);
+        // 查询设备状态
+        EquipmentStatus equipmentStatus = equipmentStatusService.lambdaQuery()
+                .eq(EquipmentStatus::getEquipmentId, outDTO.getDeviceId())
+                .one();
+        if(equipmentStatus != null){
+            EquipmentStatusOutDTO equipmentStatusOutDTO = BeanUtil.copyProperties(equipmentStatus, EquipmentStatusOutDTO.class);
+            outDTO.setEquipmentStatus(equipmentStatusOutDTO);
+        }
+        // 查询设备类别名称
+        EquipmentBase equipmentBase = equipmentBaseService.getById(outDTO.getDeviceId());
+        if(equipmentBase != null){
+            outDTO.setDeviceCode(equipmentBase.getEquipmentCode());
+            EquipmentType equipmentType = equipmentTypeService.getById(equipmentBase.getEquipmentTypeId());
+            if(equipmentType != null){
+                outDTO.setEquipmentTypeName(equipmentType.getTypeName());
+            }
+        }
+        return AjaxResult2.success(outDTO);
+    }
+
+    /**
+     * 核查案件信息
+     * @param inDTO
+     * @return
+     */
+    @Anonymous
+    @PostMapping("/verifyCaseInfo")
+    @ApiOperation(value = "核查案件信息")
+    public AjaxResult verifyCaseInfo(@RequestBody CaseInfoVerifyInDTO inDTO) {
+        CaseInfo caseInfo = caseInfoService.getById(inDTO.getCaseId());
+        if(caseInfo == null){
+            return AjaxResult.error("案件ID不存在");
+        }
+        CaseInfo entity = new CaseInfo();
+        entity.setCaseId(inDTO.getCaseId());
+        entity.setVerifyUser(inDTO.getVerifyUser());
+        entity.setVerifyTime(new Date());
+        if(inDTO.getVerifyResult() != null){
+            if(inDTO.getVerifyResult() == 1){
+                //1-待处理
+                entity.setCaseStatus(2);
+            } if(inDTO.getVerifyResult() == 2){
+                //2-误报
+                entity.setCaseStatus(4);
+            }
+        }
+        boolean updated = caseInfoService.updateById(entity);
+        return updated ? AjaxResult.success("操作成功",updated)
+                : AjaxResult.error("操作失败",updated);
+    }
+
+    /**
+     * 新增案件信息
+     * @param inDTO
+     * @return
+     */
+    @Anonymous
+    @PostMapping("/saveCaseInfo")
+    @ApiOperation(value = "新增案件信息")
+    public AjaxResult saveWarningThreshold(@RequestBody CaseInfoSaveInDTO inDTO) {
+        CaseInfo caseInfo = BeanUtil.copyProperties(inDTO, CaseInfo.class);
+        caseInfo.setCaseNo(generateCaseNo());
+        caseInfo.setCaseSource(4);
+        caseInfo.setCaseStatus(1);
+        boolean result = caseInfoService.save(caseInfo);
+        return result ? AjaxResult.success("保存成功",result)
+                : AjaxResult.error("保存失败",result);
+    }
+}

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

@@ -0,0 +1,117 @@
+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.domain.*;
+import com.zksy.base.service.*;
+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.WorkOrderOperInDTO;
+import com.zksy.manhole.dto.in.WorkOrderPageInDTO;
+import com.zksy.manhole.dto.out.EquipmentStatusOutDTO;
+import com.zksy.manhole.dto.out.WorkOrderLogOutDTO;
+import com.zksy.manhole.dto.out.WorkOrderOutDTO;
+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/workOrder")
+@Api(tags = "窨井盖监测系统-工单处置管理")
+public class WorkOrderController extends BaseController
+{
+    @Autowired
+    private WorkOrderService workOrderService;
+
+    @Autowired
+    private WorkOrderLogService workOrderLogService;
+
+    @Autowired
+    private EquipmentBaseService equipmentBaseService;
+
+    @Autowired
+    private EquipmentStatusService equipmentStatusService;
+
+    @Autowired
+    private EquipmentTypeService equipmentTypeService;
+
+    /**
+     * 分页查询工单信息列表
+     */
+    @Anonymous
+    @GetMapping(value = "/findByPage")
+    @ApiOperation(value = "分页查询工单信息列表")
+    public AjaxResult2<Page<WorkOrderOutDTO>> findByPage(@RequestBody WorkOrderPageInDTO pageInDTO)
+    {
+        return AjaxResult2.success(workOrderService.findByPage(pageInDTO));
+    }
+
+    /**
+     * 获取工单信息详情
+     */
+    @Anonymous
+    @GetMapping(value = "/getById/{id}")
+    @ApiOperation(value = "获取工单信息详情")
+    public AjaxResult2<WorkOrderOutDTO> getById(@PathVariable("id") Long id)
+    {
+        WorkOrder workOrder = workOrderService.getById(id);
+        if(workOrder == null){
+            return AjaxResult2.error("工单ID不存在");
+        }
+        WorkOrderOutDTO outDTO = BeanUtil.copyProperties(workOrder, WorkOrderOutDTO.class);
+        // 查询设备状态
+        EquipmentStatus equipmentStatus = equipmentStatusService.lambdaQuery()
+                .eq(EquipmentStatus::getEquipmentId, outDTO.getDeviceId())
+                .one();
+        if(equipmentStatus != null){
+            EquipmentStatusOutDTO equipmentStatusOutDTO = BeanUtil.copyProperties(equipmentStatus, EquipmentStatusOutDTO.class);
+            outDTO.setEquipmentStatus(equipmentStatusOutDTO);
+        }
+        // 查询设备类别名称
+        EquipmentBase equipmentBase = equipmentBaseService.getById(outDTO.getDeviceId());
+        if(equipmentBase != null){
+            outDTO.setDeviceCode(equipmentBase.getEquipmentCode());
+            EquipmentType equipmentType = equipmentTypeService.getById(equipmentBase.getEquipmentTypeId());
+            if(equipmentType != null){
+                outDTO.setEquipmentTypeName(equipmentType.getTypeName());
+            }
+        }
+        // 查询工单操作日志
+        List<WorkOrderLog> workOrderLogList = workOrderLogService.list(new LambdaQueryWrapper<WorkOrderLog>()
+                .eq(WorkOrderLog::getOrderId, outDTO.getOrderId())
+                .orderByAsc(WorkOrderLog::getOperTime));
+        if(CollUtil.isNotEmpty(workOrderLogList)){
+            List<WorkOrderLogOutDTO> workOrderLogOutDTOList = BeanUtil.copyToList(workOrderLogList, WorkOrderLogOutDTO.class);
+            outDTO.setWorkOrderLogList(workOrderLogOutDTOList);
+        }
+        return AjaxResult2.success(outDTO);
+    }
+
+    /**
+     * 操作工单
+     * @param inDTO
+     * @return
+     */
+    @Anonymous
+    @PostMapping("/operWorkOrder")
+    @ApiOperation(value = "操作工单")
+    public AjaxResult operWorkOrder(@RequestBody WorkOrderOperInDTO inDTO) {
+        boolean result = workOrderService.operWorkOrder(inDTO);
+        return result ? AjaxResult.success("操作成功",result)
+                : AjaxResult.error("操作失败",result);
+    }
+}

+ 85 - 0
pipe-network-service/zksy-admin/src/main/java/com/zksy/web/controller/monitor/RealtimeMonitorController.java

@@ -0,0 +1,85 @@
+package com.zksy.web.controller.monitor;
+
+import com.zksy.base.domain.StationVideoDevice;
+import com.zksy.base.service.EquipmentBaseService;
+import com.zksy.base.service.StationVideoDeviceService;
+import com.zksy.common.annotation.Anonymous;
+import com.zksy.common.core.domain.AjaxResult;
+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.*;
+
+@Slf4j
+@RestController
+@RequestMapping("/api/monitor")
+@Api(tags = "实时监测看板")
+public class RealtimeMonitorController {
+
+    @Autowired
+    private StationVideoDeviceService videoDeviceService;
+
+    @Autowired
+    private EquipmentBaseService equipmentService;
+
+    @GetMapping("/pressure-history")
+    @ApiOperation("压力历史曲线")
+    @Anonymous
+    public AjaxResult getPressureHistory(@RequestParam(required = false) String pointId,
+                                          @RequestParam(defaultValue = "24") Integer hours) {
+        // TODO: 从监测数据表获取真实压力历史数据
+        List<Map<String, Object>> mockData = new ArrayList<>();
+        long now = System.currentTimeMillis();
+        for (int i = hours; i >= 0; i--) {
+            Map<String, Object> point = new HashMap<>();
+            point.put("time", System.currentTimeMillis() - i * 3600000L);
+            point.put("value", 0.3 + Math.random() * 0.4);
+            mockData.add(point);
+        }
+        return AjaxResult.success(mockData);
+    }
+
+    @GetMapping("/flow-history")
+    @ApiOperation("流量历史曲线")
+    @Anonymous
+    public AjaxResult getFlowHistory(@RequestParam(required = false) String pointId,
+                                      @RequestParam(defaultValue = "24") Integer hours) {
+        // TODO: 从监测数据表获取真实流量历史数据
+        List<Map<String, Object>> mockData = new ArrayList<>();
+        for (int i = hours; i >= 0; i--) {
+            Map<String, Object> point = new HashMap<>();
+            point.put("time", System.currentTimeMillis() - i * 3600000L);
+            point.put("value", 50 + Math.random() * 100);
+            mockData.add(point);
+        }
+        return AjaxResult.success(mockData);
+    }
+
+    @GetMapping("/gas-alarm-latest")
+    @ApiOperation("最新10条气体浓度报警")
+    @Anonymous
+    public AjaxResult getGasAlarmLatest() {
+        // TODO: 从alarm_data表获取最新报警数据
+        return AjaxResult.success(new ArrayList<>());
+    }
+
+    @GetMapping("/video-list")
+    @ApiOperation("获取视频设备列表")
+    @Anonymous
+    public AjaxResult getVideoList() {
+        return AjaxResult.success(videoDeviceService.list());
+    }
+
+    @GetMapping("/points-with-latest-data")
+    @ApiOperation("获取测点最新数据")
+    @Anonymous
+    public AjaxResult getPointsWithLatestData() {
+        // TODO: 从监测数据表获取各测点最新数据
+        List<Map<String, Object>> mockData = new ArrayList<>();
+        return AjaxResult.success(mockData);
+    }
+}

+ 72 - 0
pipe-network-service/zksy-admin/src/main/java/com/zksy/web/controller/risk/RiskController.java

@@ -0,0 +1,72 @@
+package com.zksy.web.controller.risk;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.zksy.base.domain.RiskAssessment;
+import com.zksy.base.dto.RiskPageInDTO;
+import com.zksy.base.service.RiskAssessmentService;
+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 lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+@Slf4j
+@RestController
+@RequestMapping("/api/risk")
+@Api(tags = "管网风险评估")
+public class RiskController {
+
+    @Autowired
+    private RiskAssessmentService service;
+
+    @GetMapping("/findByPage")
+    @ApiOperation("风险评估分页查询")
+    @Anonymous
+    public AjaxResult findByPage(RiskPageInDTO dto) {
+        Page<RiskAssessment> page = service.findByPage(dto);
+        return AjaxResult.success(page);
+    }
+
+    @GetMapping("/{riskId}")
+    @ApiOperation("风险评估详情")
+    @Anonymous
+    public AjaxResult getById(@PathVariable String riskId) {
+        RiskAssessment entity = service.getById(riskId);
+        return entity != null ? AjaxResult.success(entity) : AjaxResult.error("风险评估信息不存在");
+    }
+
+    @PostMapping("/save")
+    @ApiOperation("新增风险评估")
+    @Log(title = "新增风险评估", businessType = BusinessType.INSERT)
+    public AjaxResult save(@RequestBody RiskAssessment entity) {
+        boolean saved = service.save(entity);
+        return saved ? AjaxResult.success("新增成功", saved) : AjaxResult.error("新增失败");
+    }
+
+    @PutMapping("/updateById")
+    @ApiOperation("修改风险评估")
+    @Log(title = "修改风险评估", businessType = BusinessType.UPDATE)
+    public AjaxResult updateById(@RequestBody RiskAssessment entity) {
+        boolean updated = service.updateById(entity);
+        return updated ? AjaxResult.success("修改成功", updated) : AjaxResult.error("修改失败");
+    }
+
+    @DeleteMapping("/deleteById")
+    @ApiOperation("删除风险评估")
+    @Log(title = "删除风险评估", businessType = BusinessType.DELETE)
+    public AjaxResult deleteById(@RequestParam String id) {
+        boolean deleted = service.removeById(id);
+        return deleted ? AjaxResult.success("删除成功") : AjaxResult.error("删除失败");
+    }
+
+    @GetMapping("/four-color-map")
+    @ApiOperation("管线风险评估四色图数据")
+    @Anonymous
+    public AjaxResult getFourColorMap() {
+        return AjaxResult.success(service.getFourColorMapData());
+    }
+}

+ 2 - 0
pipe-network-service/zksy-admin/src/main/java/com/zksy/web/controller/system/SysDictDataController.java

@@ -14,6 +14,7 @@ import org.springframework.web.bind.annotation.PutMapping;
 import org.springframework.web.bind.annotation.RequestBody;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RestController;
+import com.zksy.common.annotation.Anonymous;
 import com.zksy.common.annotation.Log;
 import com.zksy.common.core.controller.BaseController;
 import com.zksy.common.core.domain.AjaxResult;
@@ -72,6 +73,7 @@ public class SysDictDataController extends BaseController
     /**
      * 根据字典类型查询字典数据信息
      */
+    @Anonymous
     @GetMapping(value = "/type/{dictType}")
     public AjaxResult dictType(@PathVariable String dictType)
     {

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

@@ -2,12 +2,10 @@ 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;
@@ -17,8 +15,8 @@ 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.security.access.prepost.PreAuthorize;
 import org.springframework.web.bind.annotation.*;
-import org.springframework.web.multipart.MultipartFile;
 
 import java.time.LocalDateTime;
 import java.util.List;
@@ -35,7 +33,7 @@ public class EarlyWarningController {
 
     @GetMapping("/list")
     @ApiOperation("分页查询预警列表")
-    @Anonymous
+    @PreAuthorize("@ss.hasPermi('warning:warning:list')")
     public AjaxResult getWarningList(
             @ApiParam("页码") @RequestParam(defaultValue = "1") Integer pageNum,
             @ApiParam("每页数量") @RequestParam(defaultValue = "10") Integer pageSize,
@@ -50,7 +48,7 @@ public class EarlyWarningController {
 
     @GetMapping("/todo/list")
     @ApiOperation("待办预警列表")
-    @Anonymous
+    @PreAuthorize("@ss.hasPermi('warning:warning:list')")
     public AjaxResult getTodoList(
             @ApiParam("页码") @RequestParam(defaultValue = "1") Integer pageNum,
             @ApiParam("每页数量") @RequestParam(defaultValue = "10") Integer pageSize,
@@ -64,7 +62,7 @@ public class EarlyWarningController {
 
     @GetMapping("/detail/{warningId}")
     @ApiOperation("预警详情")
-    @Anonymous
+    @PreAuthorize("@ss.hasPermi('warning:warning:query')")
     public AjaxResult getWarningDetail(@PathVariable String warningId) {
         Map<String, Object> detail = earlyWarningService.getWarningDetail(warningId);
         if (detail == null) {
@@ -76,6 +74,7 @@ public class EarlyWarningController {
     @PostMapping("/save")
     @ApiOperation("保存预警信息")
     @Log(title = "保存预警信息", businessType = BusinessType.INSERT)
+    @PreAuthorize("@ss.hasPermi('warning:warning:add')")
     public AjaxResult saveWarning(WarningSaveDTO entity) {
         boolean result = earlyWarningService.saveWarning(entity.getWarning(), entity.getAlarmIds(), entity.getFiles());
         return result ? AjaxResult.success("保存成功", entity.getWarning().getWarningId()) : AjaxResult.error("保存失败");
@@ -84,14 +83,16 @@ public class EarlyWarningController {
     @PutMapping("/update")
     @ApiOperation("修改预警信息")
     @Log(title = "修改预警信息", businessType = BusinessType.UPDATE)
-    public AjaxResult updateWarning(EarlyWarning warning, List<MultipartFile> files) {
-        boolean result = earlyWarningService.updateWarning(warning, files);
+    @PreAuthorize("@ss.hasPermi('warning:warning:edit')")
+    public AjaxResult updateWarning(WarningSaveDTO entity) {
+        boolean result = earlyWarningService.updateWarning(entity.getWarning(), entity.getAlarmIds(), entity.getFiles());
         return result ? AjaxResult.success("修改成功") : AjaxResult.error("修改失败");
     }
 
     @DeleteMapping("/delete")
     @ApiOperation("删除预警信息")
     @Log(title = "删除预警信息", businessType = BusinessType.DELETE)
+    @PreAuthorize("@ss.hasPermi('warning:warning:remove')")
     public AjaxResult deleteWarning(@RequestParam String warningId) {
         boolean result = earlyWarningService.deleteWarning(warningId);
         return result ? AjaxResult.success("删除成功") : AjaxResult.error("删除失败");
@@ -100,6 +101,7 @@ public class EarlyWarningController {
     @DeleteMapping("/delete/batch")
     @ApiOperation("批量删除预警信息")
     @Log(title = "批量删除预警信息", businessType = BusinessType.DELETE)
+    @PreAuthorize("@ss.hasPermi('warning:warning:remove')")
     public AjaxResult deleteBatchWarning(@RequestParam List<String> warningIds) {
         boolean result = earlyWarningService.deleteBatchWarning(warningIds);
         return result ? AjaxResult.success("批量删除成功") : AjaxResult.error("批量删除失败");
@@ -108,50 +110,50 @@ public class EarlyWarningController {
     @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);
+    @PreAuthorize("@ss.hasPermi('warning:warning:publish')")
+    public AjaxResult publishWarning(@PathVariable String warningId) {
+        boolean result = earlyWarningService.publishWarning(warningId);
         return result ? AjaxResult.success("发布成功") : AjaxResult.error("发布失败");
     }
 
     @PostMapping("/upgrade")
     @ApiOperation("预警升级")
     @Log(title = "预警升级", businessType = BusinessType.UPDATE)
+    @PreAuthorize("@ss.hasPermi('warning:warning:handle')")
     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);
+        boolean result = earlyWarningService.upgradeWarning(warningId, newLevel, disposalContent);
         return result ? AjaxResult.success("升级成功") : AjaxResult.error("升级失败");
     }
 
     @PostMapping("/resolve")
     @ApiOperation("解除预警")
     @Log(title = "解除预警", businessType = BusinessType.UPDATE)
+    @PreAuthorize("@ss.hasPermi('warning:warning:handle')")
     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);
+        boolean result = earlyWarningService.resolveWarning(warningId, disposalContent);
         return result ? AjaxResult.success("解除成功") : AjaxResult.error("解除失败");
     }
 
     @PostMapping("/return")
     @ApiOperation("退回重办")
     @Log(title = "退回重办", businessType = BusinessType.UPDATE)
+    @PreAuthorize("@ss.hasPermi('warning:warning:handle')")
     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);
+        boolean result = earlyWarningService.returnWarning(warningId, disposalContent);
         return result ? AjaxResult.success("退回成功") : AjaxResult.error("退回失败");
     }
 
     @PostMapping("/supervision")
     @ApiOperation("预警督办")
     @Log(title = "预警督办", businessType = BusinessType.OTHER)
+    @PreAuthorize("@ss.hasPermi('warning:warning:supervision')")
     public AjaxResult supervisionWarning(
             @ApiParam("预警ID") @RequestParam String warningId,
             @ApiParam("督办人员") @RequestParam String supervisionUser,
@@ -166,6 +168,7 @@ public class EarlyWarningController {
     @PostMapping("/instruction")
     @ApiOperation("领导批示")
     @Log(title = "领导批示", businessType = BusinessType.OTHER)
+    @PreAuthorize("@ss.hasPermi('warning:warning:instruction')")
     public AjaxResult addLeaderInstruction(
             @ApiParam("预警ID") @RequestParam String warningId,
             @ApiParam("领导姓名") @RequestParam String leaderName,
@@ -177,6 +180,7 @@ public class EarlyWarningController {
 
     @PostMapping("/link/alarms")
     @ApiOperation("关联报警信息")
+    @PreAuthorize("@ss.hasPermi('warning:warning:edit')")
     public AjaxResult linkAlarms(
             @ApiParam("预警ID") @RequestParam String warningId,
             @ApiParam("报警ID列表") @RequestParam List<String> alarmIds) {
@@ -186,6 +190,7 @@ public class EarlyWarningController {
 
     @GetMapping("/link/alarms/{warningId}")
     @ApiOperation("获取关联的报警列表")
+    @PreAuthorize("@ss.hasPermi('warning:warning:query')")
     public AjaxResult getLinkedAlarms(@PathVariable String warningId) {
         List<Map<String, Object>> result = earlyWarningService.getLinkedAlarms(warningId);
         return AjaxResult.success(result);
@@ -193,6 +198,7 @@ public class EarlyWarningController {
 
     @GetMapping("/disposal/{warningId}")
     @ApiOperation("获取处置记录列表")
+    @PreAuthorize("@ss.hasPermi('warning:warning:query')")
     public AjaxResult getDisposalList(@PathVariable String warningId) {
         List<Map<String, Object>> result = earlyWarningService.getDisposalList(warningId);
         return AjaxResult.success(result);
@@ -200,7 +206,7 @@ public class EarlyWarningController {
 
     @GetMapping("/statistics")
     @ApiOperation("获取统计数据")
-    @Anonymous
+    @PreAuthorize("@ss.hasPermi('warning:warning:query')")
     public AjaxResult getStatistics() {
         Map<String, Object> result = earlyWarningService.getStatistics();
         return AjaxResult.success(result);
@@ -215,7 +221,7 @@ public class EarlyWarningController {
 
     @GetMapping("/search")
     @ApiOperation("综合搜索预警信息")
-    @Anonymous
+    @PreAuthorize("@ss.hasPermi('warning:warning:list')")
     public AjaxResult searchWarnings(
             @ApiParam("页码") @RequestParam(defaultValue = "1") Integer pageNum,
             @ApiParam("每页数量") @RequestParam(defaultValue = "10") Integer pageSize,
@@ -236,7 +242,7 @@ public class EarlyWarningController {
 
     @GetMapping("/detail/full/{warningId}")
     @ApiOperation("获取预警完整详情(含GIS定位和电子存档)")
-    @Anonymous
+    @PreAuthorize("@ss.hasPermi('warning:warning:query')")
     public AjaxResult getWarningFullDetail(@PathVariable String warningId) {
         Map<String, Object> detail = earlyWarningService.getWarningFullDetail(warningId);
         if (detail == null) {
@@ -247,7 +253,7 @@ public class EarlyWarningController {
 
     @GetMapping("/processing/list")
     @ApiOperation("获取处置过程跟踪 - 进行中的预警")
-    @Anonymous
+    @PreAuthorize("@ss.hasPermi('warning:warning:list')")
     public AjaxResult getProcessingWarnings(
             @ApiParam("页码") @RequestParam(defaultValue = "1") Integer pageNum,
             @ApiParam("每页数量") @RequestParam(defaultValue = "10") Integer pageSize,
@@ -260,7 +266,7 @@ public class EarlyWarningController {
 
     @GetMapping("/completed/list")
     @ApiOperation("获取处置过程跟踪 - 已完成的预警")
-    @Anonymous
+    @PreAuthorize("@ss.hasPermi('warning:warning:list')")
     public AjaxResult getCompletedWarnings(
             @ApiParam("页码") @RequestParam(defaultValue = "1") Integer pageNum,
             @ApiParam("每页数量") @RequestParam(defaultValue = "10") Integer pageSize,
@@ -275,7 +281,7 @@ public class EarlyWarningController {
 
     @GetMapping("/disposal/history/{warningId}")
     @ApiOperation("获取预警处置历史记录")
-    @Anonymous
+    @PreAuthorize("@ss.hasPermi('warning:warning:query')")
     public AjaxResult getDisposalHistory(@PathVariable String warningId) {
         List<Map<String, Object>> result = earlyWarningService.getDisposalHistory(warningId);
         return AjaxResult.success(result);
@@ -283,7 +289,7 @@ public class EarlyWarningController {
 
     @GetMapping("/attachments/{warningId}")
     @ApiOperation("获取预警附件列表")
-    @Anonymous
+    @PreAuthorize("@ss.hasPermi('warning:warning:query')")
     public AjaxResult getAttachments(@PathVariable String warningId) {
         List<Map<String, Object>> result = earlyWarningService.getAttachments(warningId);
         return AjaxResult.success(result);
@@ -291,7 +297,7 @@ public class EarlyWarningController {
 
     @GetMapping("/dashboard/statistics")
     @ApiOperation("获取仪表盘统计数据")
-    @Anonymous
+    @PreAuthorize("@ss.hasPermi('warning:warning:query')")
     public AjaxResult getDashboardStatistics() {
         Map<String, Object> result = earlyWarningService.getDashboardStatistics();
         return AjaxResult.success(result);
@@ -299,7 +305,7 @@ public class EarlyWarningController {
 
     @GetMapping("/archive/{warningId}")
     @ApiOperation("获取预警归档信息")
-    @Anonymous
+    @PreAuthorize("@ss.hasPermi('warning:warning:query')")
     public AjaxResult getArchive(@PathVariable String warningId) {
         WarningArchive archive = earlyWarningService.getArchiveByWarningId(warningId);
         if (archive == null) {
@@ -310,7 +316,7 @@ public class EarlyWarningController {
 
     @GetMapping("/archive/list")
     @ApiOperation("获取归档列表")
-    @Anonymous
+    @PreAuthorize("@ss.hasPermi('warning:warning:list')")
     public AjaxResult getArchiveList(
             @ApiParam("页码") @RequestParam(defaultValue = "1") Integer pageNum,
             @ApiParam("每页数量") @RequestParam(defaultValue = "10") Integer pageSize,
@@ -326,7 +332,7 @@ public class EarlyWarningController {
 
     @GetMapping("/process/{warningId}")
     @ApiOperation("获取预警处置过程记录(完整流程)")
-    @Anonymous
+    @PreAuthorize("@ss.hasPermi('warning:warning:query')")
     public AjaxResult getDisposalProcess(@PathVariable String warningId) {
         List<WarningDisposal> result = earlyWarningService.getDisposalProcess(warningId);
         return AjaxResult.success(result);
@@ -334,7 +340,7 @@ public class EarlyWarningController {
 
     @GetMapping("/diagram/{warningId}")
     @ApiOperation("获取预警流程可视化数据(路线图)")
-    @Anonymous
+    @PreAuthorize("@ss.hasPermi('warning:warning:query')")
     public AjaxResult getProcessDiagram(@PathVariable String warningId) {
         Map<String, Object> result = earlyWarningService.getProcessDiagram(warningId);
         if (result != null && result.containsKey("error")) {
@@ -345,7 +351,7 @@ public class EarlyWarningController {
 
     @GetMapping("/disposal/detail/{disposalId}")
     @ApiOperation("获取预警处置详情")
-    @Anonymous
+    @PreAuthorize("@ss.hasPermi('warning:warning:query')")
     public AjaxResult getDisposalDetail(@PathVariable String disposalId) {
         Map<String, Object> result = earlyWarningService.getDisposalDetail(disposalId);
         if (result == null) {
@@ -356,7 +362,7 @@ public class EarlyWarningController {
 
     @GetMapping("/process/statistics/{warningId}")
     @ApiOperation("获取预警流程统计信息")
-    @Anonymous
+    @PreAuthorize("@ss.hasPermi('warning:warning:query')")
     public AjaxResult getProcessStatistics(@PathVariable String warningId) {
         Map<String, Object> result = earlyWarningService.getProcessStatistics(warningId);
         return AjaxResult.success(result);

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

@@ -0,0 +1,102 @@
+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.WarningItem;
+import com.zksy.base.warning.service.WarningItemService;
+import com.zksy.common.core.domain.AjaxResult;
+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.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.*;
+
+@Slf4j
+@RestController
+@RequestMapping("/warning/item")
+@Api(tags = "预警清单管理")
+public class WarningItemController {
+
+    @Autowired
+    private WarningItemService warningItemService;
+
+    @GetMapping("/list")
+    @ApiOperation("事项信息查询-分页查询预警事项列表")
+    @PreAuthorize("@ss.hasPermi('warning:item:list')")
+    public AjaxResult queryWarningItems(
+            @ApiParam("页码") @RequestParam(defaultValue = "1") Integer pageNum,
+            @ApiParam("每页数量") @RequestParam(defaultValue = "10") Integer pageSize,
+            @ApiParam("事项编码") @RequestParam(required = false) String itemCode,
+            @ApiParam("事项名称") @RequestParam(required = false) String itemName,
+            @ApiParam("预警类型") @RequestParam(required = false) String warningType,
+            @ApiParam("预警级别") @RequestParam(required = false) String warningLevel,
+            @ApiParam("预警专项") @RequestParam(required = false) String warningSpecial,
+            @ApiParam("状态") @RequestParam(required = false) String status) {
+        Page<WarningItem> page = new Page<>(pageNum, pageSize);
+        IPage<WarningItem> result = warningItemService.queryWarningItems(page, itemCode, itemName, 
+                                                                          warningType, warningLevel, warningSpecial, status);
+        return AjaxResult.success(result);
+    }
+
+    @PostMapping("/add")
+    @ApiOperation("预警事项管理-新增预警事项")
+    @PreAuthorize("@ss.hasPermi('warning:item:add')")
+    public AjaxResult addWarningItem(@RequestBody WarningItem warningItem) {
+        boolean success = warningItemService.addWarningItem(warningItem);
+        if (success) {
+            return AjaxResult.success(warningItem);
+        } else {
+            return AjaxResult.error("新增预警事项失败");
+        }
+    }
+
+    @PutMapping("/update")
+    @ApiOperation("预警事项管理-修改预警事项")
+    @PreAuthorize("@ss.hasPermi('warning:item:edit')")
+    public AjaxResult updateWarningItem(@RequestBody WarningItem warningItem) {
+        boolean success = warningItemService.updateWarningItem(warningItem);
+        if (success) {
+            return AjaxResult.success();
+        } else {
+            return AjaxResult.error("修改预警事项失败");
+        }
+    }
+
+    @PutMapping("/status")
+    @ApiOperation("预警事项管理-更新事项状态(启用/禁用/作废)")
+    @PreAuthorize("@ss.hasPermi('warning:item:edit')")
+    public AjaxResult updateItemStatus(
+            @ApiParam("事项ID") @RequestParam String itemId,
+            @ApiParam("状态(ENABLED-启用 DISABLED-禁用 INVALID-作废)") @RequestParam String status) {
+        boolean success = warningItemService.updateItemStatus(itemId, status);
+        if (success) {
+            return AjaxResult.success();
+        } else {
+            return AjaxResult.error("更新状态失败");
+        }
+    }
+
+    @GetMapping("/detail/{itemId}")
+    @ApiOperation("预警事项详情-获取事项详细信息")
+    @PreAuthorize("@ss.hasPermi('warning:item:query')")
+    public AjaxResult getItemDetail(@PathVariable String itemId) {
+        WarningItem item = warningItemService.getItemDetail(itemId);
+        if (item != null) {
+            return AjaxResult.success(item);
+        } else {
+            return AjaxResult.error("预警事项不存在");
+        }
+    }
+
+    @GetMapping("/code/generate")
+    @ApiOperation("事项编码生成-自动生成事项编码")
+    @PreAuthorize("@ss.hasPermi('warning:item:query')")
+    public AjaxResult generateItemCode(
+            @ApiParam("预警类型") @RequestParam String warningType,
+            @ApiParam("预警级别") @RequestParam String warningLevel) {
+        String itemCode = warningItemService.generateItemCode(warningType, warningLevel);
+        return AjaxResult.success(itemCode);
+    }
+}

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

@@ -0,0 +1,103 @@
+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.WarningReason;
+import com.zksy.base.warning.service.WarningReasonService;
+import com.zksy.common.core.domain.AjaxResult;
+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.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+@Slf4j
+@RestController
+@RequestMapping("/warning/reason")
+@Api(tags = "预警原因库管理")
+public class WarningReasonController {
+
+    @Autowired
+    private WarningReasonService warningReasonService;
+
+    @GetMapping("/list")
+    @ApiOperation("预警原因库管理-分页查询预警原因列表")
+    @PreAuthorize("@ss.hasPermi('warning:reason:list')")
+    public AjaxResult queryWarningReasons(
+            @ApiParam("页码") @RequestParam(defaultValue = "1") Integer pageNum,
+            @ApiParam("每页数量") @RequestParam(defaultValue = "10") Integer pageSize,
+            @ApiParam("原因编码") @RequestParam(required = false) String reasonCode,
+            @ApiParam("原因名称") @RequestParam(required = false) String reasonName,
+            @ApiParam("预警类型") @RequestParam(required = false) String warningType,
+            @ApiParam("预警级别") @RequestParam(required = false) String warningLevel,
+            @ApiParam("状态") @RequestParam(required = false) String status) {
+        Page<WarningReason> page = new Page<>(pageNum, pageSize);
+        IPage<WarningReason> result = warningReasonService.queryWarningReasons(page, reasonCode, reasonName, 
+                                                                                 warningType, warningLevel, status);
+        return AjaxResult.success(result);
+    }
+
+    @GetMapping("/query")
+    @ApiOperation("预警原因库管理-根据类型和级别查询原因列表")
+    @PreAuthorize("@ss.hasPermi('warning:reason:query')")
+    public AjaxResult getReasonsByTypeAndLevel(
+            @ApiParam("预警类型") @RequestParam String warningType,
+            @ApiParam("预警级别") @RequestParam String warningLevel) {
+        List<WarningReason> result = warningReasonService.getReasonsByTypeAndLevel(warningType, warningLevel);
+        return AjaxResult.success(result);
+    }
+
+    @PostMapping("/add")
+    @ApiOperation("预警原因库管理-新增预警原因")
+    @PreAuthorize("@ss.hasPermi('warning:reason:add')")
+    public AjaxResult addWarningReason(@RequestBody WarningReason warningReason) {
+        boolean success = warningReasonService.addWarningReason(warningReason);
+        if (success) {
+            return AjaxResult.success(warningReason);
+        } else {
+            return AjaxResult.error("新增预警原因失败");
+        }
+    }
+
+    @PutMapping("/update")
+    @ApiOperation("预警原因库管理-修改预警原因")
+    @PreAuthorize("@ss.hasPermi('warning:reason:edit')")
+    public AjaxResult updateWarningReason(@RequestBody WarningReason warningReason) {
+        boolean success = warningReasonService.updateWarningReason(warningReason);
+        if (success) {
+            return AjaxResult.success();
+        } else {
+            return AjaxResult.error("修改预警原因失败");
+        }
+    }
+
+    @PutMapping("/status")
+    @ApiOperation("预警原因库管理-更新原因状态")
+    @PreAuthorize("@ss.hasPermi('warning:reason:edit')")
+    public AjaxResult updateReasonStatus(
+            @ApiParam("原因ID") @RequestParam String reasonId,
+            @ApiParam("状态(0-正常 1-停用)") @RequestParam String status) {
+        boolean success = warningReasonService.updateReasonStatus(reasonId, status);
+        if (success) {
+            return AjaxResult.success();
+        } else {
+            return AjaxResult.error("更新状态失败");
+        }
+    }
+
+    @GetMapping("/detail/{reasonId}")
+    @ApiOperation("预警原因库管理-获取原因详细信息")
+    @PreAuthorize("@ss.hasPermi('warning:reason:query')")
+    public AjaxResult getReasonDetail(@PathVariable String reasonId) {
+        WarningReason reason = warningReasonService.getReasonDetail(reasonId);
+        if (reason != null) {
+            return AjaxResult.success(reason);
+        } else {
+            return AjaxResult.error("预警原因不存在");
+        }
+    }
+}

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

@@ -0,0 +1,133 @@
+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.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * 案件信息表
+ * @TableName case_info
+ */
+@TableName(value ="case_info")
+@Data
+@ApiModel(value = "案件信息入参", description = "案件信息入参")
+public class CaseInfo implements Serializable {
+
+    @TableField(exist = false)
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 案件ID
+     */
+    @ApiModelProperty(value = "案件ID")
+    @TableId(type = IdType.AUTO)
+    private Long caseId;
+
+    /**
+     * 案件编号
+     */
+    @ApiModelProperty(value = "案件编号")
+    private String caseNo;
+
+    /**
+     * 关联报警ID,手动立案可为空
+     */
+    @ApiModelProperty(value = "报警ID")
+    private String alarmId;
+
+    /**
+     * 关联设备ID
+     */
+    @ApiModelProperty(value = "设备ID")
+    private String deviceId;
+
+    /**
+     * 设备编码
+     */
+    @ApiModelProperty(value = "设备编码")
+    private String deviceCode;
+
+    /**
+     * 案件等级:1-严重 2-一般 3-轻微
+     */
+    @ApiModelProperty(value = "案件等级:1-严重 2-一般 3-轻微")
+    private Integer caseLevel;
+
+    /**
+     * 案件描述
+     */
+    @ApiModelProperty(value = "案件描述")
+    private String caseDesc;
+
+    /**
+     * 案件来源:1-系统自动报警 2-运维巡检上报 3-人工投诉上报 4-平台录入
+     */
+    @ApiModelProperty(value = "案件来源:1-系统自动报警 2-运维巡检上报 3-人工投诉上报 4-平台录入")
+    private Integer caseSource;
+
+    /**
+     * 案件状态:1-待核查 2-办理中 3-已办结 4-误报关闭
+     */
+    @ApiModelProperty(value = "案件状态:1-待核查 2-办理中 3-已办结 4-误报关闭")
+    private Integer caseStatus;
+
+    /**
+     * 立案人ID
+     */
+    @ApiModelProperty(value = "立案人ID")
+    private Long fileUser;
+
+    /**
+     * 核查人ID
+     */
+    @ApiModelProperty(value = "核查人ID")
+    private Long verifyUser;
+
+    /**
+     * 核查完成时间
+     */
+    @ApiModelProperty(value = "核查完成时间")
+    @JsonFormat(locale = "zh",pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
+    private Date verifyTime;
+
+    /**
+     * 案件办结时间
+     */
+    @ApiModelProperty(value = "案件办结时间")
+    @JsonFormat(locale = "zh",pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
+    private Date finishTime;
+
+    /**
+     * 案件处置结果、整改说明
+     */
+    @ApiModelProperty(value = "案件处置结果")
+    private String handleResult;
+
+    /**
+     * 案件佐证图片、附件地址
+     */
+    @ApiModelProperty(value = "案件佐证图片、附件地址")
+    private String attachUrl;
+
+    /**
+     * 创建时间
+     */
+    @ApiModelProperty(value = "创建时间")
+    @JsonFormat(locale = "zh",pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
+    private Date createTime;
+
+    /**
+     * 更新时间
+     */
+    @ApiModelProperty(value = "更新时间")
+    @JsonFormat(locale = "zh",pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
+    private Date updateTime;
+}

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

@@ -0,0 +1,84 @@
+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;
+
+/**
+ * 燃气管点信息表
+ */
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+@TableName("gas_pipe_point")
+public class GasPipePoint {
+
+    @TableId(value = "point_id", type = IdType.AUTO)
+    @ApiModelProperty("管点ID")
+    private Long pointId;
+
+    @ApiModelProperty("管点编码")
+    private String pointCode;
+
+    @ApiModelProperty("管点名称")
+    private String pointName;
+
+    @ApiModelProperty("所属管线ID")
+    private String networkId;
+
+    @ApiModelProperty("所属管线名称")
+    private String networkName;
+
+    @ApiModelProperty("管点类型(阀门/调压/计量/阴极保护/弯头/三通/其它)")
+    private String pointType;
+
+    @ApiModelProperty("经度")
+    private BigDecimal longitude;
+
+    @ApiModelProperty("纬度")
+    private BigDecimal latitude;
+
+    @ApiModelProperty("地址/位置描述")
+    private String address;
+
+    @ApiModelProperty("管径(毫米)")
+    private BigDecimal diameter;
+
+    @ApiModelProperty("材质")
+    private String material;
+
+    @ApiModelProperty("埋深(米)")
+    private BigDecimal depth;
+
+    @ApiModelProperty("建设日期")
+    @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
+    private String buildDate;
+
+    @ApiModelProperty("状态(0-正常 1-异常 2-停用)")
+    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;
+}

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

@@ -0,0 +1,42 @@
+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("gas_pipe_point_device_rel")
+public class GasPipePointDeviceRel {
+
+    @TableId(value = "rel_id", type = IdType.AUTO)
+    @ApiModelProperty("关联ID")
+    private Long relId;
+
+    @ApiModelProperty("管点ID")
+    private Long pointId;
+
+    @ApiModelProperty("设备ID")
+    private String equipmentId;
+
+    @ApiModelProperty("设备名称(冗余字段,便于列表展示)")
+    private String equipmentName;
+
+    @ApiModelProperty("设备类型(冗余字段)")
+    private String equipmentType;
+
+    @ApiModelProperty("创建时间")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private LocalDateTime createTime;
+}

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

@@ -0,0 +1,103 @@
+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.LocalDate;
+import java.time.LocalDateTime;
+
+/**
+ * 隐患台账表
+ */
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+@TableName("hazard_hidden_account")
+public class HazardHiddenAccount {
+
+    @TableId(value = "hazard_id", type = IdType.ASSIGN_UUID)
+    @ApiModelProperty("隐患ID")
+    private String hazardId;
+
+    @ApiModelProperty("隐患编号")
+    private String hazardNo;
+
+    @ApiModelProperty("关联管网设施ID")
+    private String networkId;
+
+    @ApiModelProperty("关联设备ID")
+    private String equipmentId;
+
+    @ApiModelProperty("隐患类型")
+    private String hazardType;
+
+    @ApiModelProperty("隐患等级")
+    private String hazardLevel;
+
+    @ApiModelProperty("隐患描述")
+    private String hazardDesc;
+
+    @ApiModelProperty("隐患来源")
+    private String hazardSource;
+
+    @ApiModelProperty("状态")
+    private String hazardStatus;
+
+    @ApiModelProperty("上报单位")
+    private String reportUnit;
+
+    @ApiModelProperty("上报时间")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private LocalDateTime reportTime;
+
+    @ApiModelProperty("整改方案")
+    private String rectifyPlan;
+
+    @ApiModelProperty("整改期限")
+    @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
+    private LocalDate rectifyDeadline;
+
+    @ApiModelProperty("整改责任人")
+    private String rectifyPerson;
+
+    @ApiModelProperty("整改反馈")
+    private String rectifyFeedback;
+
+    @ApiModelProperty("核查人")
+    private String verifyPerson;
+
+    @ApiModelProperty("核查时间")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private LocalDateTime verifyTime;
+
+    @ApiModelProperty("是否已报送")
+    private Integer isSubmitted;
+
+    @ApiModelProperty("报送时间")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private LocalDateTime submitTime;
+
+    @ApiModelProperty("经度")
+    private BigDecimal longitude;
+
+    @ApiModelProperty("纬度")
+    private BigDecimal latitude;
+
+    @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;
+}

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

@@ -0,0 +1,71 @@
+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;
+
+/**
+ * 窨井基础信息表
+ */
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+@TableName("manhole_base")
+public class ManholeBase {
+
+    @TableId(value = "manhole_id", type = IdType.ASSIGN_UUID)
+    @ApiModelProperty("窨井ID")
+    private String manholeId;
+
+    @ApiModelProperty("窨井编码")
+    private String manholeCode;
+
+    @ApiModelProperty("窨井名称")
+    private String manholeName;
+
+    @ApiModelProperty("关联管网设施ID")
+    private String networkId;
+
+    @ApiModelProperty("位置描述")
+    private String location;
+
+    @ApiModelProperty("经度")
+    private BigDecimal longitude;
+
+    @ApiModelProperty("纬度")
+    private BigDecimal latitude;
+
+    @ApiModelProperty("窨井深度(米)")
+    private BigDecimal manholeDepth;
+
+    @ApiModelProperty("形状")
+    private String manholeShape;
+
+    @ApiModelProperty("材质")
+    private String material;
+
+    @ApiModelProperty("权属单位")
+    private String ownershipUnit;
+
+    @ApiModelProperty("状态")
+    private String status;
+
+    @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;
+}

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

@@ -0,0 +1,57 @@
+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.LocalDate;
+import java.time.LocalDateTime;
+
+/**
+ * 燃气管网维修记录表
+ */
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+@TableName("pipe_repair_record")
+public class PipeRepairRecord {
+
+    @TableId(value = "repair_id", type = IdType.ASSIGN_UUID)
+    @ApiModelProperty("维修记录ID")
+    private String repairId;
+
+    @ApiModelProperty("关联管网设施ID")
+    private String networkId;
+
+    @ApiModelProperty("维修日期")
+    @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
+    private LocalDate repairDate;
+
+    @ApiModelProperty("维修类型")
+    private String repairType;
+
+    @ApiModelProperty("维修内容")
+    private String repairContent;
+
+    @ApiModelProperty("维修单位")
+    private String repairCompany;
+
+    @ApiModelProperty("维修费用(元)")
+    private BigDecimal repairCost;
+
+    @ApiModelProperty("维修负责人")
+    private String repairPerson;
+
+    @ApiModelProperty("备注")
+    private String remark;
+
+    @ApiModelProperty("创建时间")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private LocalDateTime createTime;
+}

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

@@ -0,0 +1,72 @@
+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;
+
+/**
+ * 燃气管网风险评估表
+ */
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+@TableName("risk_assessment")
+public class RiskAssessment {
+
+    @TableId(value = "risk_id", type = IdType.ASSIGN_UUID)
+    @ApiModelProperty("风险评估ID")
+    private String riskId;
+
+    @ApiModelProperty("关联管网设施ID")
+    private String networkId;
+
+    @ApiModelProperty("风险等级")
+    private String riskLevel;
+
+    @ApiModelProperty("风险评分")
+    private BigDecimal riskScore;
+
+    @ApiModelProperty("风险颜色")
+    private String riskColor;
+
+    @ApiModelProperty("评估模型名称/版本")
+    private String assessmentModel;
+
+    @ApiModelProperty("评估时间")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private LocalDateTime assessmentTime;
+
+    @ApiModelProperty("评估人")
+    private String assessmentPerson;
+
+    @ApiModelProperty("风险构成要素")
+    private String riskFactors;
+
+    @ApiModelProperty("周边防护目标")
+    private String protectiveTargets;
+
+    @ApiModelProperty("周边危险源")
+    private String hazardSources;
+
+    @ApiModelProperty("历史维修记录摘要")
+    private String repairHistorySummary;
+
+    @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;
+}

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

@@ -0,0 +1,58 @@
+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("station_video_device")
+public class StationVideoDevice {
+
+    @TableId(value = "video_id", type = IdType.ASSIGN_UUID)
+    @ApiModelProperty("视频设备ID")
+    private String videoId;
+
+    @ApiModelProperty("关联场站ID")
+    private String stationId;
+
+    @ApiModelProperty("摄像头名称")
+    private String deviceName;
+
+    @ApiModelProperty("设备编码")
+    private String deviceCode;
+
+    @ApiModelProperty("视频流地址")
+    private String videoUrl;
+
+    @ApiModelProperty("安装位置描述")
+    private String location;
+
+    @ApiModelProperty("状态")
+    private String status;
+
+    @ApiModelProperty("厂商")
+    private String manufacturer;
+
+    @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;
+}

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

@@ -0,0 +1,178 @@
+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.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * 运维工单表
+ * @TableName work_order
+ */
+@TableName(value ="work_order")
+@Data
+@ApiModel(value = "运维工单入参", description = "运维工单入参")
+public class WorkOrder implements Serializable {
+
+    @TableField(exist = false)
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 工单ID
+     */
+    @ApiModelProperty(value = "工单ID")
+    @TableId(type = IdType.AUTO)
+    private Long orderId;
+
+    /**
+     * 工单编号
+     */
+    @ApiModelProperty(value = "工单编号")
+    private String orderNo;
+
+    /**
+     * 关联报警ID
+     */
+    @ApiModelProperty(value = "报警ID")
+    private String alarmId;
+
+    /**
+     * 关联案件ID
+     */
+    @ApiModelProperty(value = "案件ID")
+    private Long caseId;
+
+    /**
+     * 案件编号
+     */
+    @ApiModelProperty(value = "案件编号")
+    private String caseNo;
+
+    /**
+     * 关联设备ID
+     */
+    @ApiModelProperty(value = "设备ID")
+    private String deviceId;
+
+    /**
+     * 设备编码
+     */
+    @ApiModelProperty(value = "设备编码")
+    private String deviceCode;
+
+    /**
+     * 工单类型:1-故障维修 2-日常巡检 3-设备保养
+     */
+    @ApiModelProperty(value = "工单类型:1-故障维修 2-日常巡检 3-设备保养")
+    private Integer orderType;
+
+    /**
+     * 工单优先级:1-紧急 2-一般 3-低
+     */
+    @ApiModelProperty(value = "工单优先级:1-紧急 2-一般 3-低")
+    private Integer orderLevel;
+
+    /**
+     * 工单问题描述
+     */
+    @ApiModelProperty(value = "工单问题描述")
+    private String orderDesc;
+
+    /**
+     * 负责部门ID
+     */
+    @ApiModelProperty(value = "负责部门ID")
+    private Long deptId;
+
+    /**
+     * 派单人ID
+     */
+    @ApiModelProperty(value = "派单人ID")
+    private Long dispatchUser;
+
+    /**
+     * 派单时间
+     */
+    @ApiModelProperty(value = "派单时间")
+    @JsonFormat(locale = "zh",pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
+    private Date dispatchTime;
+
+    /**
+     * 接单运维人员ID
+     */
+    @ApiModelProperty(value = "接单运维人员ID")
+    private Long receiveUser;
+
+    /**
+     * 工单状态:1-待派单 2-待接单 3-已接单 4-处理中 5-待验收 6-已结案 7-已驳回 8-延期审核 9-已延期
+     */
+    @ApiModelProperty(value = "工单状态:1-待派单 2-待接单 3-已接单 4-处理中 5-待验收 6-已结案 7-已驳回 8-延期审核 9-已延期")
+    private Integer orderStatus;
+
+    /**
+     * 延期原因
+     */
+    @ApiModelProperty(value = "延期原因")
+    private String delayedReason;
+
+    /**
+     * 延期截止时间
+     */
+    @ApiModelProperty(value = "延期截止时间")
+    @JsonFormat(locale = "zh",pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
+    private Date delayedDeadline;
+
+    /**
+     * 计划完成时间
+     */
+    @ApiModelProperty(value = "计划完成时间")
+    @JsonFormat(locale = "zh",pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
+    private Date planFinishTime;
+
+    /**
+     * 实际完成时间
+     */
+    @ApiModelProperty(value = "实际完成时间")
+    @JsonFormat(locale = "zh",pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
+    private Date realFinishTime;
+
+    /**
+     * 维修处置结果
+     */
+    @ApiModelProperty(value = "维修处置结果")
+    private String repairResult;
+
+    /**
+     * 验收人ID
+     */
+    @ApiModelProperty(value = "验收人ID")
+    private Long verifyUser;
+
+    /**
+     * 验收时间
+     */
+    @ApiModelProperty(value = "验收时间")
+    @JsonFormat(locale = "zh",pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
+    private Date verifyTime;
+
+    /**
+     * 创建时间
+     */
+    @ApiModelProperty(value = "创建时间")
+    @JsonFormat(locale = "zh",pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
+    private Date createTime;
+
+    /**
+     * 更新时间
+     */
+    @ApiModelProperty(value = "更新时间")
+    @JsonFormat(locale = "zh",pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
+    private Date updateTime;
+}

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

@@ -0,0 +1,70 @@
+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.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * 工单操作日志表
+ * @TableName work_order_log
+ */
+@TableName(value ="work_order_log")
+@Data
+@ApiModel(value = "工单操作日志入参", description = "工单操作日志入参")
+public class WorkOrderLog implements Serializable {
+
+    @TableField(exist = false)
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 日志ID
+     */
+    @ApiModelProperty(value = "日志ID")
+    @TableId(type = IdType.AUTO)
+    private Long logId;
+
+    /**
+     * 关联工单ID
+     */
+    @ApiModelProperty(value = "工单ID")
+    private Long orderId;
+
+    /**
+     * 操作类型:1-创建工单 2-派单 3-接单 4-开始维修 5-提交验收 6-验收通过 7-驳回工单 8-申请延期
+     */
+    @ApiModelProperty(value = "操作类型:1-创建工单 2-派单 3-接单 4-开始维修 5-提交验收 6-验收通过 7-驳回工单 8-申请延期 9-延期审核通过")
+    private Integer operType;
+
+    /**
+     * 操作详情描述
+     */
+    @ApiModelProperty(value = "操作详情描述")
+    private String operDesc;
+
+    /**
+     * 操作人ID
+     */
+    @ApiModelProperty(value = "操作人ID")
+    private Long operUserId;
+
+    /**
+     * 操作人姓名
+     */
+    @ApiModelProperty(value = "操作人姓名")
+    private String operUserName;
+
+    /**
+     * 操作时间
+     */
+    @ApiModelProperty(value = "操作时间")
+    @JsonFormat(locale = "zh",pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
+    private Date operTime;
+}

+ 124 - 0
pipe-network-service/zksy-system/src/main/java/com/zksy/base/domain/vo/EquipmentFullVO.java

@@ -0,0 +1,124 @@
+package com.zksy.base.domain.vo;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+import java.util.Date;
+
+/**
+ * 设备全信息VO — 联查管线→管点→设备→状态
+ */
+@Data
+public class EquipmentFullVO {
+
+    // ===== equipment_base =====
+    @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;
+
+    @ApiModelProperty("设备类别ID")
+    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;
+
+    // ===== equipment_status =====
+    @ApiModelProperty("设备当前状态:1-在用,2-闲置,3-维修,4-报废,5-待入库")
+    private Integer currentStatus;
+
+    @ApiModelProperty("报警状态:0-正常,1-报警")
+    private Integer alarmStatus;
+
+    @ApiModelProperty("在线状态:0-离线,1-在线")
+    private Integer onlineStatus;
+
+    @ApiModelProperty("最后一次维护日期")
+    @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
+    private Date lastMaintainDate;
+
+    @ApiModelProperty("下次预计维护日期")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private LocalDateTime nextMaintainDate;
+
+    // ===== gas_pipe_point =====
+    @ApiModelProperty("管点ID")
+    private Long pointId;
+
+    @ApiModelProperty("管点编码")
+    private String pointCode;
+
+    @ApiModelProperty("管点名称")
+    private String pointName;
+
+    @ApiModelProperty("管点类型")
+    private String pointType;
+
+    @ApiModelProperty("管点地址")
+    private String pointAddress;
+
+    // ===== pipe_network_base =====
+    @ApiModelProperty("管线ID")
+    private String networkId;
+
+    @ApiModelProperty("管线编码")
+    private String networkCode;
+
+    @ApiModelProperty("管线名称")
+    private String networkName;
+
+    @ApiModelProperty("管线类型")
+    private String networkType;
+
+    @ApiModelProperty("管线等级")
+    private String networkLevel;
+}

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

@@ -0,0 +1,34 @@
+package com.zksy.base.dto;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+
+@Data
+@ApiModel(value = "管点分页查询入参", description = "管点分页查询入参")
+public class GasPipePointPageInDTO implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    @ApiModelProperty(value = "管点名称")
+    private String pointName;
+
+    @ApiModelProperty(value = "管点编码")
+    private String pointCode;
+
+    @ApiModelProperty(value = "所属管线ID")
+    private String networkId;
+
+    @ApiModelProperty(value = "管点类型")
+    private String pointType;
+
+    @ApiModelProperty(value = "状态")
+    private String status;
+
+    @ApiModelProperty(value = "当前记录起始索引", required = true)
+    private Long pageNum;
+
+    @ApiModelProperty(value = "每页显示记录数", required = true)
+    private Long pageSize;
+}

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

@@ -0,0 +1,31 @@
+package com.zksy.base.dto;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+
+@Data
+@ApiModel(value = "隐患分页查询入参", description = "隐患分页查询入参")
+public class HazardPageInDTO implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    @ApiModelProperty(value = "隐患类型")
+    private String hazardType;
+
+    @ApiModelProperty(value = "隐患级别")
+    private String hazardLevel;
+
+    @ApiModelProperty(value = "隐患状态")
+    private String hazardStatus;
+
+    @ApiModelProperty(value = "是否已报送:0-未报送 1-已报送")
+    private Integer isSubmitted;
+
+    @ApiModelProperty(value = "当前记录起始索引", required = true)
+    private Long pageNum;
+
+    @ApiModelProperty(value = "每页显示记录数", required = true)
+    private Long pageSize;
+}

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

@@ -0,0 +1,28 @@
+package com.zksy.base.dto;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+
+@Data
+@ApiModel(value = "窨井分页查询入参", description = "窨井分页查询入参")
+public class ManholePageInDTO implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    @ApiModelProperty(value = "窨井名称")
+    private String manholeName;
+
+    @ApiModelProperty(value = "窨井编码")
+    private String manholeCode;
+
+    @ApiModelProperty(value = "状态")
+    private String status;
+
+    @ApiModelProperty(value = "当前记录起始索引", required = true)
+    private Long pageNum;
+
+    @ApiModelProperty(value = "每页显示记录数", required = true)
+    private Long pageSize;
+}

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

@@ -0,0 +1,25 @@
+package com.zksy.base.dto;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+
+@Data
+@ApiModel(value = "监测点分页查询入参", description = "监测点分页查询入参")
+public class MonitorPointPageInDTO implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    @ApiModelProperty(value = "监测点名称")
+    private String pointName;
+
+    @ApiModelProperty(value = "监测点类型")
+    private String pointType;
+
+    @ApiModelProperty(value = "当前记录起始索引", required = true)
+    private Long pageNum;
+
+    @ApiModelProperty(value = "每页显示记录数", required = true)
+    private Long pageSize;
+}

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

@@ -0,0 +1,34 @@
+package com.zksy.base.dto;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+
+@Data
+@ApiModel(value = "管网分页查询入参", description = "管网分页查询入参")
+public class PipeNetworkPageInDTO implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    @ApiModelProperty(value = "管网名称")
+    private String networkName;
+
+    @ApiModelProperty(value = "管理单位")
+    private String managementUnit;
+
+    @ApiModelProperty(value = "管网级别")
+    private String networkLevel;
+
+    @ApiModelProperty(value = "材质")
+    private String material;
+
+    @ApiModelProperty(value = "状态")
+    private String status;
+
+    @ApiModelProperty(value = "当前记录起始索引", required = true)
+    private Long pageNum;
+
+    @ApiModelProperty(value = "每页显示记录数", required = true)
+    private Long pageSize;
+}

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

@@ -0,0 +1,25 @@
+package com.zksy.base.dto;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+
+@Data
+@ApiModel(value = "维修记录分页查询入参", description = "维修记录分页查询入参")
+public class RepairRecordPageInDTO implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    @ApiModelProperty(value = "管网ID")
+    private String networkId;
+
+    @ApiModelProperty(value = "维修类型")
+    private String repairType;
+
+    @ApiModelProperty(value = "当前记录起始索引", required = true)
+    private Long pageNum;
+
+    @ApiModelProperty(value = "每页显示记录数", required = true)
+    private Long pageSize;
+}

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

@@ -0,0 +1,25 @@
+package com.zksy.base.dto;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+
+@Data
+@ApiModel(value = "风险评估分页查询入参", description = "风险评估分页查询入参")
+public class RiskPageInDTO implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    @ApiModelProperty(value = "管网ID")
+    private String networkId;
+
+    @ApiModelProperty(value = "风险等级")
+    private String riskLevel;
+
+    @ApiModelProperty(value = "当前记录起始索引", required = true)
+    private Long pageNum;
+
+    @ApiModelProperty(value = "每页显示记录数", required = true)
+    private Long pageSize;
+}

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

@@ -0,0 +1,20 @@
+package com.zksy.base.mapper;
+
+import com.zksy.base.domain.CaseInfo;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+* @author Administrator
+* @description 针对表【case_info(案件信息表)】的数据库操作Mapper
+* @createDate 2026-06-08 15:01:11
+* @Entity com.zksy.base.domain.CaseInfo
+*/
+@Mapper
+public interface CaseInfoMapper extends BaseMapper<CaseInfo> {
+
+}
+
+
+
+

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

@@ -0,0 +1,20 @@
+package com.zksy.base.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.zksy.base.domain.WorkOrderLog;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+* @author Administrator
+* @description 针对表【work_order_log(工单操作日志表)】的数据库操作Mapper
+* @createDate 2026-06-11 11:51:09
+* @Entity com.zksy.base.domain.WorkOrderLog
+*/
+@Mapper
+public interface WorkOrderLogMapper extends BaseMapper<WorkOrderLog> {
+
+}
+
+
+
+

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

@@ -0,0 +1,20 @@
+package com.zksy.base.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.zksy.base.domain.WorkOrder;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+* @author Administrator
+* @description 针对表【work_order(运维工单表)】的数据库操作Mapper
+* @createDate 2026-06-11 11:50:08
+* @Entity com.zksy.base.domain.WorkOrder
+*/
+@Mapper
+public interface WorkOrderMapper extends BaseMapper<WorkOrder> {
+
+}
+
+
+
+

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

@@ -0,0 +1,22 @@
+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.CaseInfo;
+import com.zksy.manhole.dto.in.CaseInfoPageInDTO;
+import com.zksy.manhole.dto.out.CaseInfoOutDTO;
+
+/**
+* @author Administrator
+* @description 针对表【case_info(案件信息表)】的数据库操作Service
+* @createDate 2026-06-08 15:01:11
+*/
+public interface CaseInfoService extends IService<CaseInfo> {
+
+    /**
+     * 分页查询案件信息列表
+     * @param pageInDTO
+     * @return
+     */
+    Page<CaseInfoOutDTO> findByPage(CaseInfoPageInDTO pageInDTO);
+}

+ 5 - 0
pipe-network-service/zksy-system/src/main/java/com/zksy/base/service/EquipmentBaseService.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.EquipmentBase;
+import com.zksy.base.domain.vo.EquipmentFullVO;
 import com.zksy.manhole.dto.in.ManholeDeviceListInDTO;
 import com.zksy.manhole.dto.in.ManholeDevicePageInDTO;
 import com.zksy.manhole.dto.out.EquipmentBaseOutDTO;
@@ -13,6 +14,10 @@ import java.util.Map;
 
 public interface EquipmentBaseService extends IService<EquipmentBase> {
 
+    Page<EquipmentFullVO> findFullByPage(long pageNum, long pageSize,
+                                         String equipmentCode, String equipmentName,
+                                         String equipmentModel, String manufacturer);
+
     Page<EquipmentBase> findByPage(long pageNum, long pageSize,
                                    String equipmentCode, String equipmentName,
                                    String equipmentModel, String manufacturer);

+ 23 - 0
pipe-network-service/zksy-system/src/main/java/com/zksy/base/service/GasPipePointService.java

@@ -0,0 +1,23 @@
+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.GasPipePoint;
+import com.zksy.base.dto.GasPipePointPageInDTO;
+
+import java.util.List;
+
+public interface GasPipePointService extends IService<GasPipePoint> {
+
+    Page<GasPipePoint> queryByPage(GasPipePointPageInDTO dto);
+
+    List<GasPipePoint> listByNetworkId(String networkId);
+
+    List<GasPipePoint> getOptions();
+
+    boolean saveWithCheck(GasPipePoint entity);
+
+    boolean updateWithCheck(GasPipePoint entity);
+
+    boolean removeWithCheck(Long pointId);
+}

+ 40 - 0
pipe-network-service/zksy-system/src/main/java/com/zksy/base/service/HazardHiddenAccountService.java

@@ -0,0 +1,40 @@
+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.HazardHiddenAccount;
+import com.zksy.base.dto.HazardPageInDTO;
+
+import java.util.List;
+import java.util.Map;
+
+public interface HazardHiddenAccountService extends IService<HazardHiddenAccount> {
+
+    Page<HazardHiddenAccount> findByPage(HazardPageInDTO dto);
+
+    boolean submitHazard(String hazardId);
+
+    List<HazardHiddenAccount> getActiveMapPoints();
+
+    List<Map<String, Object>> statisticsByType(String startDate, String endDate);
+
+    List<Map<String, Object>> statisticsByStatus(String startDate, String endDate);
+
+    Map<String, Object> statisticsOverview(String startDate, String endDate);
+
+    List<Map<String, Object>> statisticsByLevel(String startDate, String endDate);
+
+    List<Map<String, Object>> statisticsByRegion(String startDate, String endDate);
+
+    /**
+     * 隐患类型时间线统计(按天汇总,每条类型一条折线)
+     * 返回: { categories: [日期...], series: [{ name: 类型, data: [数量...] }] }
+     */
+    Map<String, Object> statisticsTypeTimeline(String startDate, String endDate);
+
+    /**
+     * 整改状态时间线统计(按天汇总,每个状态一组柱)
+     * 返回: { categories: [日期...], series: [{ name: 状态, data: [数量...] }] }
+     */
+    Map<String, Object> statisticsStatusTimeline(String startDate, String endDate);
+}

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

@@ -0,0 +1,15 @@
+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.ManholeBase;
+import com.zksy.base.dto.ManholePageInDTO;
+
+import java.util.List;
+
+public interface ManholeBaseService extends IService<ManholeBase> {
+
+    Page<ManholeBase> findByPage(ManholePageInDTO dto);
+
+    List<ManholeBase> getOptions();
+}

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

@@ -0,0 +1,35 @@
+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.MonitorPoint;
+import com.zksy.base.dto.MonitorPointPageInDTO;
+
+import java.util.List;
+import java.util.Map;
+
+public interface MonitorPointService extends IService<MonitorPoint> {
+
+    Page<MonitorPoint> queryByPage(MonitorPointPageInDTO dto);
+    Page<MonitorPoint> findByPage(long pageNum, long pageSize,
+                                    String pointCode, String pointName,
+                                    String pointType, String status);
+
+    boolean saveWithCheck(MonitorPoint entity);
+
+    boolean saveBatchWithCheck(List<MonitorPoint> entityList);
+
+    boolean updateWithCheck(MonitorPoint entity);
+
+    boolean removeWithCheck(String id);
+
+    boolean removeBatchWithCheck(List<String> ids);
+
+    boolean bindEquipment(String pointId, List<String> equipmentIds);
+
+    boolean unbindEquipment(String pointId, List<String> equipmentIds);
+
+    Map<String, Object> getPointDetail(String pointId);
+
+    List<MonitorPoint> getPointsByNetwork(String networkId);
+}

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

@@ -0,0 +1,27 @@
+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.PipeNetworkBase;
+import com.zksy.base.dto.PipeNetworkPageInDTO;
+
+import java.util.List;
+
+public interface PipeNetworkBaseService extends IService<PipeNetworkBase> {
+
+    Page<PipeNetworkBase> queryByPage(PipeNetworkPageInDTO dto);
+    Page<PipeNetworkBase> findByPage(long pageNum, long pageSize,
+                                      String networkCode, String networkName,
+                                      String networkType, String status);
+
+    boolean saveWithCheck(PipeNetworkBase entity);
+
+    boolean saveBatchWithCheck(List<PipeNetworkBase> entityList);
+
+    boolean updateWithCheck(PipeNetworkBase entity);
+
+    List<PipeNetworkBase> getOptions();
+    boolean removeWithCheck(String id);
+
+    boolean removeBatchWithCheck(List<String> ids);
+}

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

@@ -0,0 +1,15 @@
+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.PipeRepairRecord;
+import com.zksy.base.dto.RepairRecordPageInDTO;
+
+import java.util.List;
+
+public interface PipeRepairRecordService extends IService<PipeRepairRecord> {
+
+    Page<PipeRepairRecord> findByPage(RepairRecordPageInDTO dto);
+
+    List<PipeRepairRecord> listByNetworkId(String networkId);
+}

+ 16 - 0
pipe-network-service/zksy-system/src/main/java/com/zksy/base/service/RiskAssessmentService.java

@@ -0,0 +1,16 @@
+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.RiskAssessment;
+import com.zksy.base.dto.RiskPageInDTO;
+
+import java.util.List;
+import java.util.Map;
+
+public interface RiskAssessmentService extends IService<RiskAssessment> {
+
+    Page<RiskAssessment> findByPage(RiskPageInDTO dto);
+
+    List<Map<String, Object>> getFourColorMapData();
+}

+ 11 - 0
pipe-network-service/zksy-system/src/main/java/com/zksy/base/service/StationVideoDeviceService.java

@@ -0,0 +1,11 @@
+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.StationVideoDevice;
+
+public interface StationVideoDeviceService extends IService<StationVideoDevice> {
+
+    Page<StationVideoDevice> findByPage(long pageNum, long pageSize,
+                                        String deviceName, String stationId, String status);
+}

+ 13 - 0
pipe-network-service/zksy-system/src/main/java/com/zksy/base/service/WorkOrderLogService.java

@@ -0,0 +1,13 @@
+package com.zksy.base.service;
+
+import com.zksy.base.domain.WorkOrderLog;
+import com.baomidou.mybatisplus.extension.service.IService;
+
+/**
+* @author Administrator
+* @description 针对表【work_order_log(工单操作日志表)】的数据库操作Service
+* @createDate 2026-06-11 11:51:09
+*/
+public interface WorkOrderLogService extends IService<WorkOrderLog> {
+
+}

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

@@ -0,0 +1,30 @@
+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.WorkOrder;
+import com.zksy.manhole.dto.in.WorkOrderOperInDTO;
+import com.zksy.manhole.dto.in.WorkOrderPageInDTO;
+import com.zksy.manhole.dto.out.WorkOrderOutDTO;
+
+/**
+* @author Administrator
+* @description 针对表【work_order(运维工单表)】的数据库操作Service
+* @createDate 2026-06-11 11:50:08
+*/
+public interface WorkOrderService extends IService<WorkOrder> {
+
+    /**
+     * 分页查询工单信息列表
+     * @param pageInDTO
+     * @return
+     */
+    Page<WorkOrderOutDTO> findByPage(WorkOrderPageInDTO pageInDTO);
+
+    /**
+     * 操作工单
+     * @param inDTO
+     * @return
+     */
+    boolean operWorkOrder(WorkOrderOperInDTO inDTO);
+}

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

@@ -0,0 +1,119 @@
+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.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.zksy.base.domain.CaseInfo;
+import com.zksy.base.domain.EquipmentBase;
+import com.zksy.base.domain.EquipmentStatus;
+import com.zksy.base.domain.EquipmentType;
+import com.zksy.base.mapper.CaseInfoMapper;
+import com.zksy.base.mapper.EquipmentBaseMapper;
+import com.zksy.base.mapper.EquipmentStatusMapper;
+import com.zksy.base.mapper.EquipmentTypeMapper;
+import com.zksy.base.service.CaseInfoService;
+import com.zksy.manhole.dto.in.CaseInfoPageInDTO;
+import com.zksy.manhole.dto.out.CaseInfoOutDTO;
+import com.zksy.manhole.dto.out.EquipmentStatusOutDTO;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+
+/**
+* @author Administrator
+* @description 针对表【case_info(案件信息表)】的数据库操作Service实现
+* @createDate 2026-06-08 15:01:11
+*/
+@Slf4j
+@Service
+public class CaseInfoServiceImpl extends ServiceImpl<CaseInfoMapper, CaseInfo>
+    implements CaseInfoService{
+
+    @Autowired
+    private EquipmentBaseMapper equipmentBaseMapper;
+
+    @Autowired
+    private EquipmentTypeMapper equipmentTypeMapper;
+
+    @Autowired
+    private EquipmentStatusMapper equipmentStatusMapper;
+
+    /**
+     * 分页查询案件信息列表
+     * @param pageInDTO
+     * @return
+     */
+    @Override
+    public Page<CaseInfoOutDTO> findByPage(CaseInfoPageInDTO pageInDTO) {
+        log.info("分页查询案件信息列表-入参:{}", pageInDTO);
+        List<String> equipmentIds = null;
+        if(StringUtils.isNotEmpty(pageInDTO.getEquipmentLocation())){
+            List<EquipmentBase> equipmentBaseList = equipmentBaseMapper.selectList(new LambdaQueryWrapper<EquipmentBase>()
+                    .like(EquipmentBase::getEquipmentLocation, pageInDTO.getEquipmentLocation()));
+            if(CollUtil.isEmpty(equipmentBaseList)){
+                return new Page<>(pageInDTO.getPageNum(), pageInDTO.getPageSize(), 0);
+            }
+            equipmentIds = equipmentBaseList.stream().map(EquipmentBase::getEquipmentId).distinct().collect(Collectors.toList());
+        }
+        Page<CaseInfo> page = new Page<>(pageInDTO.getPageNum(), pageInDTO.getPageSize());
+        LambdaQueryWrapper<CaseInfo> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.like(StringUtils.isNotEmpty(pageInDTO.getCaseNo()), CaseInfo::getCaseNo, pageInDTO.getCaseNo())
+                .in(CollUtil.isNotEmpty(equipmentIds), CaseInfo::getDeviceId, equipmentIds)
+                .orderByDesc(CaseInfo::getUpdateTime);
+        Page<CaseInfo> rs = this.page(page, queryWrapper);
+        List<CaseInfoOutDTO> outDTOList = BeanUtil.copyToList(rs.getRecords(), CaseInfoOutDTO.class);
+        if (CollUtil.isNotEmpty(outDTOList)) {
+            //查询设备状态
+            List<String> equipmentIdList = outDTOList.stream().map(CaseInfoOutDTO::getDeviceId).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)));
+            }
+            //查询设备类型
+            List<EquipmentBase> equipmentBaseList = equipmentBaseMapper.selectBatchIds(equipmentIdList);
+            Map<String, EquipmentBase> equipmentBaseMap = new HashMap<>();
+            if(CollUtil.isNotEmpty(equipmentBaseList)){
+                equipmentBaseMap.putAll(equipmentBaseList.stream().collect(Collectors.toMap(EquipmentBase::getEquipmentId, Function.identity(), (key1, key2) -> key2)));
+            }
+            List<String> equipmentTypeIdList = equipmentBaseList.stream().map(EquipmentBase::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)));
+            }
+            for(CaseInfoOutDTO outDTO : outDTOList) {
+                EquipmentBase equipmentBase = equipmentBaseMap.get(outDTO.getDeviceId());
+                if(equipmentBase != null){
+                    outDTO.setDeviceCode(equipmentBase.getEquipmentCode());
+                    EquipmentType equipmentType = equipmentTypeMap.get(equipmentBase.getEquipmentTypeId());
+                    if(equipmentType != null){
+                        outDTO.setEquipmentTypeName(equipmentType.getTypeName());
+                    }
+                }
+                EquipmentStatus equipmentStatus = equipmentStatusMap.get(outDTO.getDeviceId());
+                if(equipmentStatus != null){
+                    EquipmentStatusOutDTO equipmentStatusOutDTO = BeanUtil.copyProperties(equipmentStatus, EquipmentStatusOutDTO.class);
+                    outDTO.setEquipmentStatus(equipmentStatusOutDTO);
+                }
+            }
+        }
+        Page<CaseInfoOutDTO> outPage = new Page<>(pageInDTO.getPageNum(), pageInDTO.getPageSize(), rs.getTotal());
+        outPage.setRecords(outDTOList);
+        return outPage;
+    }
+}
+
+
+
+

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

@@ -11,16 +11,11 @@ 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.domain.*;
+import com.zksy.base.domain.vo.EquipmentFullVO;
 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.mapper.*;
 import com.zksy.base.service.EquipmentBaseService;
 import com.zksy.common.exception.ServiceException;
 import com.zksy.manhole.dto.in.ManholeDeviceListInDTO;
@@ -66,6 +61,15 @@ public class EquipmentBaseServiceImpl extends ServiceImpl<EquipmentBaseMapper, E
     @Autowired
     private ManholeDataMapper manholeDataMapper;
 
+    @Autowired
+    private GasPipePointDeviceRelMapper gasPipePointDeviceRelMapper;
+
+    @Autowired
+    private GasPipePointMapper gasPipePointMapper;
+
+    @Autowired
+    private PipeNetworkBaseMapper pipeNetworkBaseMapper;
+
     @Override
     public Page<EquipmentBase> findByPage(long pageNum, long pageSize,
                                           String equipmentCode, String equipmentName,
@@ -484,6 +488,112 @@ public class EquipmentBaseServiceImpl extends ServiceImpl<EquipmentBaseMapper, E
         return result;
     }
 
+    @Override
+    public Page<EquipmentFullVO> findFullByPage(long pageNum, long pageSize,
+                                                String equipmentCode, String equipmentName,
+                                                String equipmentModel, String manufacturer) {
+        // 1. 分页查询设备基础信息
+        Page<EquipmentBase> page = new Page<>(pageNum, pageSize);
+        LambdaQueryWrapper<EquipmentBase> qw = new LambdaQueryWrapper<>();
+        if (equipmentCode != null && !equipmentCode.isEmpty()) {
+            qw.like(EquipmentBase::getEquipmentCode, equipmentCode);
+        }
+        if (equipmentName != null && !equipmentName.isEmpty()) {
+            qw.like(EquipmentBase::getEquipmentName, equipmentName);
+        }
+        if (equipmentModel != null && !equipmentModel.isEmpty()) {
+            qw.like(EquipmentBase::getEquipmentModel, equipmentModel);
+        }
+        if (manufacturer != null && !manufacturer.isEmpty()) {
+            qw.like(EquipmentBase::getManufacturer, manufacturer);
+        }
+        qw.orderByDesc(EquipmentBase::getCreateTime);
+        Page<EquipmentBase> basePage = this.page(page, qw);
+        List<EquipmentBase> equipmentList = basePage.getRecords();
+        if (CollUtil.isEmpty(equipmentList)) {
+            Page<EquipmentFullVO> emptyPage = new Page<>(pageNum, pageSize, 0);
+            emptyPage.setRecords(new ArrayList<>());
+            return emptyPage;
+        }
+
+        List<String> equipmentIds = equipmentList.stream()
+                .map(EquipmentBase::getEquipmentId).collect(Collectors.toList());
+
+        // 2. 批量查设备状态
+        List<EquipmentStatus> statusList = equipmentStatusMapper.selectList(
+                new LambdaQueryWrapper<EquipmentStatus>().in(EquipmentStatus::getEquipmentId, equipmentIds));
+        Map<String, EquipmentStatus> statusMap = statusList.stream()
+                .collect(Collectors.toMap(EquipmentStatus::getEquipmentId, Function.identity(), (a, b) -> a));
+
+        // 3. 批量查管点-设备关联 (gas_pipe_point_device_rel)
+        List<GasPipePointDeviceRel> allRels = gasPipePointDeviceRelMapper.selectList(
+                new LambdaQueryWrapper<GasPipePointDeviceRel>().in(GasPipePointDeviceRel::getEquipmentId, equipmentIds));
+        Map<String, GasPipePointDeviceRel> relMap = allRels.stream()
+                .collect(Collectors.toMap(GasPipePointDeviceRel::getEquipmentId, Function.identity(), (a, b) -> a));
+
+        // 4. 批量查管点
+        List<Long> pointIds = allRels.stream().map(GasPipePointDeviceRel::getPointId).distinct().collect(Collectors.toList());
+        Map<Long, GasPipePoint> pointMap = new HashMap<>();
+        if (CollUtil.isNotEmpty(pointIds)) {
+            List<GasPipePoint> pointList = gasPipePointMapper.selectBatchIds(pointIds);
+            pointMap = pointList.stream()
+                    .collect(Collectors.toMap(GasPipePoint::getPointId, Function.identity(), (a, b) -> a));
+        }
+
+        // 5. 批量查管线
+        List<String> networkIds = pointMap.values().stream()
+                .map(GasPipePoint::getNetworkId).filter(Objects::nonNull).distinct().collect(Collectors.toList());
+        Map<String, PipeNetworkBase> networkMap = new HashMap<>();
+        if (CollUtil.isNotEmpty(networkIds)) {
+            List<PipeNetworkBase> networkList = pipeNetworkBaseMapper.selectBatchIds(networkIds);
+            networkMap = networkList.stream()
+                    .collect(Collectors.toMap(PipeNetworkBase::getNetworkId, Function.identity(), (a, b) -> a));
+        }
+
+        // 6. 组装VO
+        List<EquipmentFullVO> voList = new ArrayList<>();
+        for (EquipmentBase equip : equipmentList) {
+            EquipmentFullVO vo = new EquipmentFullVO();
+            BeanUtil.copyProperties(equip, vo);
+
+            EquipmentStatus status = statusMap.get(equip.getEquipmentId());
+            if (status != null) {
+                vo.setCurrentStatus(status.getCurrentStatus());
+                vo.setAlarmStatus(status.getAlarmStatus());
+                vo.setOnlineStatus(status.getOnlineStatus());
+                vo.setLastMaintainDate(status.getLastMaintainDate());
+                vo.setNextMaintainDate(status.getNextMaintainDate());
+            }
+
+            GasPipePointDeviceRel rel = relMap.get(equip.getEquipmentId());
+            if (rel != null) {
+                GasPipePoint point = pointMap.get(rel.getPointId());
+                if (point != null) {
+                    vo.setPointId(point.getPointId());
+                    vo.setPointCode(point.getPointCode());
+                    vo.setPointName(point.getPointName());
+                    vo.setPointType(point.getPointType());
+                    vo.setPointAddress(point.getAddress());
+
+                    PipeNetworkBase network = networkMap.get(point.getNetworkId());
+                    if (network != null) {
+                        vo.setNetworkId(network.getNetworkId());
+                        vo.setNetworkCode(network.getNetworkCode());
+                        vo.setNetworkName(network.getNetworkName());
+                        vo.setNetworkType(network.getNetworkType());
+                        vo.setNetworkLevel(network.getNetworkLevel());
+                    }
+                }
+            }
+
+            voList.add(vo);
+        }
+
+        Page<EquipmentFullVO> resultPage = new Page<>(pageNum, pageSize, basePage.getTotal());
+        resultPage.setRecords(voList);
+        return resultPage;
+    }
+
     @Override
     public List<EquipmentBase> getEquipmentByPoint(String pointId) {
         LambdaQueryWrapper<EquipmentPointRel> relWrapper = new LambdaQueryWrapper<>();

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

@@ -0,0 +1,89 @@
+package com.zksy.base.service.impl;
+
+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.GasPipePoint;
+import com.zksy.base.dto.GasPipePointPageInDTO;
+import com.zksy.base.mapper.GasPipePointMapper;
+import com.zksy.base.service.GasPipePointService;
+import com.zksy.common.exception.ServiceException;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.List;
+
+@Slf4j
+@Service
+public class GasPipePointServiceImpl extends ServiceImpl<GasPipePointMapper, GasPipePoint>
+        implements GasPipePointService {
+
+    @Override
+    public Page<GasPipePoint> queryByPage(GasPipePointPageInDTO dto) {
+        Page<GasPipePoint> page = new Page<>(dto.getPageNum(), dto.getPageSize());
+        LambdaQueryWrapper<GasPipePoint> wrapper = new LambdaQueryWrapper<>();
+        wrapper.like(dto.getPointName() != null && !dto.getPointName().isEmpty(), GasPipePoint::getPointName, dto.getPointName());
+        wrapper.like(dto.getPointCode() != null && !dto.getPointCode().isEmpty(), GasPipePoint::getPointCode, dto.getPointCode());
+        wrapper.eq(dto.getNetworkId() != null && !dto.getNetworkId().isEmpty(), GasPipePoint::getNetworkId, dto.getNetworkId());
+        wrapper.eq(dto.getPointType() != null && !dto.getPointType().isEmpty(), GasPipePoint::getPointType, dto.getPointType());
+        wrapper.eq(dto.getStatus() != null && !dto.getStatus().isEmpty(), GasPipePoint::getStatus, dto.getStatus());
+        wrapper.orderByDesc(GasPipePoint::getCreateTime);
+        return this.page(page, wrapper);
+    }
+
+    @Override
+    public List<GasPipePoint> listByNetworkId(String networkId) {
+        LambdaQueryWrapper<GasPipePoint> wrapper = new LambdaQueryWrapper<>();
+        wrapper.eq(GasPipePoint::getNetworkId, networkId);
+        wrapper.orderByAsc(GasPipePoint::getPointCode);
+        return this.list(wrapper);
+    }
+
+    @Override
+    public List<GasPipePoint> getOptions() {
+        LambdaQueryWrapper<GasPipePoint> wrapper = new LambdaQueryWrapper<>();
+        wrapper.select(GasPipePoint::getPointId, GasPipePoint::getPointName, GasPipePoint::getPointCode);
+        wrapper.orderByAsc(GasPipePoint::getPointName);
+        return this.list(wrapper);
+    }
+
+    @Override
+    public boolean saveWithCheck(GasPipePoint entity) {
+        LambdaQueryWrapper<GasPipePoint> wrapper = new LambdaQueryWrapper<>();
+        wrapper.eq(GasPipePoint::getPointCode, entity.getPointCode());
+        if (this.count(wrapper) > 0) {
+            throw new ServiceException("管点编码已存在:" + entity.getPointCode());
+        }
+        return this.save(entity);
+    }
+
+    @Override
+    @Transactional
+    public boolean updateWithCheck(GasPipePoint entity) {
+        Long pointId = entity.getPointId();
+        if (this.getById(pointId) == null) {
+            throw new ServiceException("管点不存在:" + pointId);
+        }
+        String newCode = entity.getPointCode();
+        if (newCode != null) {
+            LambdaQueryWrapper<GasPipePoint> wrapper = new LambdaQueryWrapper<>();
+            wrapper.eq(GasPipePoint::getPointCode, newCode)
+                    .ne(GasPipePoint::getPointId, pointId);
+            if (this.count(wrapper) > 0) {
+                throw new ServiceException("管点编码已被使用:" + newCode);
+            }
+        }
+        return this.updateById(entity);
+    }
+
+    @Override
+    @Transactional
+    public boolean removeWithCheck(Long pointId) {
+        GasPipePoint point = this.getById(pointId);
+        if (point == null) {
+            throw new ServiceException("管点不存在:" + pointId);
+        }
+        return this.baseMapper.deleteById(pointId) > 0;
+    }
+}

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

@@ -0,0 +1,279 @@
+package com.zksy.base.service.impl;
+
+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.HazardHiddenAccount;
+import com.zksy.base.dto.HazardPageInDTO;
+import com.zksy.base.mapper.HazardHiddenAccountMapper;
+import com.zksy.base.service.HazardHiddenAccountService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import com.zksy.common.utils.StringUtils;
+import com.zksy.system.service.ISysDictDataService;
+import org.springframework.beans.factory.annotation.Autowired;
+
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.LocalTime;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+@Slf4j
+@Service
+public class HazardHiddenAccountServiceImpl extends ServiceImpl<HazardHiddenAccountMapper, HazardHiddenAccount>
+        implements HazardHiddenAccountService {
+
+    @Autowired
+    private ISysDictDataService dictDataService;
+
+    @Override
+    public Page<HazardHiddenAccount> findByPage(HazardPageInDTO dto) {
+        Page<HazardHiddenAccount> page = new Page<>(dto.getPageNum(), dto.getPageSize());
+        LambdaQueryWrapper<HazardHiddenAccount> wrapper = new LambdaQueryWrapper<>();
+        wrapper.eq(dto.getHazardType() != null && !dto.getHazardType().isEmpty(), HazardHiddenAccount::getHazardType, dto.getHazardType());
+        wrapper.eq(dto.getHazardLevel() != null && !dto.getHazardLevel().isEmpty(), HazardHiddenAccount::getHazardLevel, dto.getHazardLevel());
+        wrapper.eq(dto.getHazardStatus() != null && !dto.getHazardStatus().isEmpty(), HazardHiddenAccount::getHazardStatus, dto.getHazardStatus());
+        wrapper.eq(dto.getIsSubmitted() != null, HazardHiddenAccount::getIsSubmitted, dto.getIsSubmitted());
+        wrapper.orderByDesc(HazardHiddenAccount::getCreateTime);
+        return this.page(page, wrapper);
+    }
+
+    @Override
+    @Transactional
+    public boolean submitHazard(String hazardId) {
+        HazardHiddenAccount hazard = this.getById(hazardId);
+        if (hazard == null) {
+            return false;
+        }
+        hazard.setIsSubmitted(1);
+        hazard.setSubmitTime(LocalDateTime.now());
+        return this.updateById(hazard);
+    }
+
+    @Override
+    public List<HazardHiddenAccount> getActiveMapPoints() {
+        LambdaQueryWrapper<HazardHiddenAccount> wrapper = new LambdaQueryWrapper<>();
+        wrapper.ne(HazardHiddenAccount::getHazardStatus, "3");
+        wrapper.isNotNull(HazardHiddenAccount::getLongitude);
+        wrapper.isNotNull(HazardHiddenAccount::getLatitude);
+        wrapper.select(HazardHiddenAccount::getHazardId, HazardHiddenAccount::getHazardNo,
+                HazardHiddenAccount::getHazardType, HazardHiddenAccount::getHazardLevel,
+                HazardHiddenAccount::getHazardStatus, HazardHiddenAccount::getHazardDesc,
+                HazardHiddenAccount::getLongitude, HazardHiddenAccount::getLatitude,
+                HazardHiddenAccount::getRectifyFeedback, HazardHiddenAccount::getReportTime);
+        return this.list(wrapper);
+    }
+
+    @Override
+    public List<Map<String, Object>> statisticsByType(String startDate, String endDate) {
+        List<HazardHiddenAccount> list = this.list(buildDateWrapper(startDate, endDate));
+        Map<String, Long> grouped = list.stream()
+                .collect(Collectors.groupingBy(h -> h.getHazardType() != null ? h.getHazardType() : "未知", Collectors.counting()));
+        List<Map<String, Object>> result = new ArrayList<>();
+        for (Map.Entry<String, Long> entry : grouped.entrySet()) {
+            Map<String, Object> item = new HashMap<>();
+            item.put("name", entry.getKey());
+            item.put("value", entry.getValue());
+            result.add(item);
+        }
+        return result;
+    }
+
+    @Override
+    public List<Map<String, Object>> statisticsByStatus(String startDate, String endDate) {
+        List<HazardHiddenAccount> list = this.list(buildDateWrapper(startDate, endDate));
+        Map<String, Long> grouped = list.stream()
+                .collect(Collectors.groupingBy(h -> h.getHazardStatus() != null ? h.getHazardStatus() : "未知", Collectors.counting()));
+        List<Map<String, Object>> result = new ArrayList<>();
+        for (Map.Entry<String, Long> entry : grouped.entrySet()) {
+            Map<String, Object> item = new HashMap<>();
+            item.put("name", entry.getKey());
+            item.put("value", entry.getValue());
+            result.add(item);
+        }
+        return result;
+    }
+
+    @Override
+    public Map<String, Object> statisticsOverview(String startDate, String endDate) {
+        List<HazardHiddenAccount> list = this.list(buildDateWrapper(startDate, endDate));
+        long total = list.size();
+        long rectified = list.stream()
+                .filter(h -> "3".equals(h.getHazardStatus()))
+                .count();
+
+        // 按隐患等级分组
+        Map<String, Long> levelGrouped = list.stream()
+                .collect(Collectors.groupingBy(h -> h.getHazardLevel() != null ? h.getHazardLevel() : "未知", Collectors.counting()));
+        List<Map<String, Object>> byLevel = new ArrayList<>();
+        for (Map.Entry<String, Long> entry : levelGrouped.entrySet()) {
+            Map<String, Object> item = new HashMap<>();
+            item.put("level", entry.getKey());
+            item.put("count", entry.getValue());
+            byLevel.add(item);
+        }
+
+        Map<String, Object> result = new HashMap<>();
+        result.put("total", total);
+        result.put("rectified", rectified);
+        result.put("byLevel", byLevel);
+        return result;
+    }
+
+    @Override
+    public List<Map<String, Object>> statisticsByLevel(String startDate, String endDate) {
+        List<HazardHiddenAccount> list = this.list(buildDateWrapper(startDate, endDate));
+        Map<String, Long> grouped = list.stream()
+                .collect(Collectors.groupingBy(h -> h.getHazardLevel() != null ? h.getHazardLevel() : "未知", Collectors.counting()));
+        List<Map<String, Object>> result = new ArrayList<>();
+        for (Map.Entry<String, Long> entry : grouped.entrySet()) {
+            Map<String, Object> item = new HashMap<>();
+            item.put("name", entry.getKey());
+            item.put("value", entry.getValue());
+            result.add(item);
+        }
+        return result;
+    }
+
+    @Override
+    public List<Map<String, Object>> statisticsByRegion(String startDate, String endDate) {
+        // 无日期参数时默认最近7天
+        if (!StringUtils.hasText(startDate)) {
+            startDate = LocalDate.now().minusDays(6).toString();
+        }
+        if (!StringUtils.hasText(endDate)) {
+            endDate = LocalDate.now().toString();
+        }
+        List<HazardHiddenAccount> list = this.list(buildDateWrapper(startDate, endDate));
+        Map<String, Long> grouped = list.stream()
+                .collect(Collectors.groupingBy(h -> h.getReportUnit() != null && !h.getReportUnit().isEmpty()
+                        ? h.getReportUnit() : "未知区域", Collectors.counting()));
+        List<Map<String, Object>> result = new ArrayList<>();
+        for (Map.Entry<String, Long> entry : grouped.entrySet()) {
+            Map<String, Object> item = new HashMap<>();
+            item.put("name", entry.getKey());
+            item.put("value", entry.getValue());
+            result.add(item);
+        }
+        return result;
+    }
+
+    @Override
+    public Map<String, Object> statisticsTypeTimeline(String startDate, String endDate) {
+        // 无日期参数时默认最近7天
+        LocalDate rangeStart, rangeEnd;
+        if (StringUtils.hasText(startDate) && StringUtils.hasText(endDate)) {
+            rangeStart = LocalDate.parse(startDate);
+            rangeEnd = LocalDate.parse(endDate);
+        } else {
+            rangeEnd = LocalDate.now();
+            rangeStart = rangeEnd.minusDays(6);
+            startDate = rangeStart.toString();
+            endDate = rangeEnd.toString();
+        }
+        return buildTimeline(startDate, endDate, rangeStart, rangeEnd,
+                HazardHiddenAccount::getHazardType, "hazard_type");
+    }
+
+    @Override
+    public Map<String, Object> statisticsStatusTimeline(String startDate, String endDate) {
+        // 无日期参数时默认最近7天
+        LocalDate rangeStart, rangeEnd;
+        if (StringUtils.hasText(startDate) && StringUtils.hasText(endDate)) {
+            rangeStart = LocalDate.parse(startDate);
+            rangeEnd = LocalDate.parse(endDate);
+        } else {
+            rangeEnd = LocalDate.now();
+            rangeStart = rangeEnd.minusDays(6);
+            startDate = rangeStart.toString();
+            endDate = rangeEnd.toString();
+        }
+        return buildTimeline(startDate, endDate, rangeStart, rangeEnd,
+                HazardHiddenAccount::getHazardStatus, "hazard_status");
+    }
+
+    /**
+     * 通用时间线构建:按 reportTime 天 + 指定字段分组
+     *
+     * @param startDate  查询起始日期字符串
+     * @param endDate    查询结束日期字符串
+     * @param rangeStart 日期轴起点
+     * @param rangeEnd   日期轴终点
+     * @param classifier 分组字段 (hazardType / hazardStatus)
+     * @param dictType   字典类型,用于将字典值转为标签 (hazard_type / hazard_status)
+     * @return { categories: [...], series: [{name: 中文标签, data}, ...] }
+     */
+    private Map<String, Object> buildTimeline(String startDate, String endDate,
+                                              LocalDate rangeStart, LocalDate rangeEnd,
+                                              java.util.function.Function<HazardHiddenAccount, String> classifier,
+                                              String dictType) {
+        List<HazardHiddenAccount> list = this.list(buildDateWrapper(startDate, endDate));
+        List<String> categories = generateDateRange(rangeStart, rangeEnd);
+
+        // 二级分组: 字段值 → 日期 → 数量
+        Map<String, Map<LocalDate, Long>> fieldDateMap = list.stream()
+                .collect(Collectors.groupingBy(
+                        h -> {
+                            String val = classifier.apply(h);
+                            return val != null && !val.isEmpty() ? val : "未知";
+                        },
+                        Collectors.groupingBy(
+                                h -> h.getReportTime() != null ? h.getReportTime().toLocalDate() : LocalDate.now(),
+                                Collectors.counting()
+                        )
+                ));
+
+        List<Map<String, Object>> series = new ArrayList<>();
+        for (Map.Entry<String, Map<LocalDate, Long>> entry : fieldDateMap.entrySet()) {
+            Map<String, Object> s = new HashMap<>();
+            // 通过字典服务将字典值转为中文标签
+            String label = dictDataService.selectDictLabel(dictType, entry.getKey());
+            s.put("name", StringUtils.hasText(label) ? label : entry.getKey());
+            Map<LocalDate, Long> dateCount = entry.getValue();
+            List<Long> data = new ArrayList<>();
+            for (String dateStr : categories) {
+                LocalDate d = LocalDate.parse(dateStr);
+                data.add(dateCount.getOrDefault(d, 0L));
+            }
+            s.put("data", data);
+            series.add(s);
+        }
+
+        Map<String, Object> result = new HashMap<>();
+        result.put("categories", categories);
+        result.put("series", series);
+        return result;
+    }
+
+    /**
+     * 生成日期序列(包含首尾)
+     */
+    private List<String> generateDateRange(LocalDate start, LocalDate end) {
+        List<String> dates = new ArrayList<>();
+        LocalDate current = start;
+        while (!current.isAfter(end)) {
+            dates.add(current.toString());
+            current = current.plusDays(1);
+        }
+        return dates;
+    }
+
+    /**
+     * 根据日期范围构建查询条件,使用 reportTime 字段过滤
+     */
+    private LambdaQueryWrapper<HazardHiddenAccount> buildDateWrapper(String startDate, String endDate) {
+        LambdaQueryWrapper<HazardHiddenAccount> wrapper = new LambdaQueryWrapper<>();
+        if (StringUtils.hasText(startDate)) {
+            wrapper.ge(HazardHiddenAccount::getReportTime, LocalDate.parse(startDate).atStartOfDay());
+        }
+        if (StringUtils.hasText(endDate)) {
+            wrapper.le(HazardHiddenAccount::getReportTime, LocalDate.parse(endDate).atTime(LocalTime.MAX));
+        }
+        return wrapper;
+    }
+}

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

@@ -0,0 +1,38 @@
+package com.zksy.base.service.impl;
+
+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.ManholeBase;
+import com.zksy.base.dto.ManholePageInDTO;
+import com.zksy.base.mapper.ManholeBaseMapper;
+import com.zksy.base.service.ManholeBaseService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+@Slf4j
+@Service
+public class ManholeBaseServiceImpl extends ServiceImpl<ManholeBaseMapper, ManholeBase>
+        implements ManholeBaseService {
+
+    @Override
+    public Page<ManholeBase> findByPage(ManholePageInDTO dto) {
+        Page<ManholeBase> page = new Page<>(dto.getPageNum(), dto.getPageSize());
+        LambdaQueryWrapper<ManholeBase> wrapper = new LambdaQueryWrapper<>();
+        wrapper.like(dto.getManholeName() != null && !dto.getManholeName().isEmpty(), ManholeBase::getManholeName, dto.getManholeName());
+        wrapper.like(dto.getManholeCode() != null && !dto.getManholeCode().isEmpty(), ManholeBase::getManholeCode, dto.getManholeCode());
+        wrapper.eq(dto.getStatus() != null && !dto.getStatus().isEmpty(), ManholeBase::getStatus, dto.getStatus());
+        wrapper.orderByDesc(ManholeBase::getCreateTime);
+        return this.page(page, wrapper);
+    }
+
+    @Override
+    public List<ManholeBase> getOptions() {
+        LambdaQueryWrapper<ManholeBase> wrapper = new LambdaQueryWrapper<>();
+        wrapper.select(ManholeBase::getManholeId, ManholeBase::getManholeName, ManholeBase::getManholeCode);
+        wrapper.orderByAsc(ManholeBase::getManholeName);
+        return this.list(wrapper);
+    }
+}

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

@@ -0,0 +1,270 @@
+package com.zksy.base.service.impl;
+
+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.EquipmentBase;
+import com.zksy.base.domain.EquipmentPointRel;
+import com.zksy.base.domain.MonitorPoint;
+import com.zksy.base.domain.PipeNetworkBase;
+import com.zksy.base.dto.MonitorPointPageInDTO;
+import com.zksy.base.mapper.EquipmentBaseMapper;
+import com.zksy.base.mapper.EquipmentPointRelMapper;
+import com.zksy.base.mapper.MonitorPointMapper;
+import com.zksy.base.mapper.PipeNetworkBaseMapper;
+import com.zksy.base.service.MonitorPointService;
+import com.zksy.common.exception.ServiceException;
+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.*;
+import java.util.stream.Collectors;
+
+@Slf4j
+@Service
+public class MonitorPointServiceImpl extends ServiceImpl<MonitorPointMapper, MonitorPoint>
+        implements MonitorPointService {
+
+    @Autowired
+    private EquipmentPointRelMapper equipmentPointRelMapper;
+
+    @Autowired
+    private EquipmentBaseMapper equipmentBaseMapper;
+
+    @Autowired
+    private PipeNetworkBaseMapper pipeNetworkBaseMapper;
+
+    @Override
+    public Page<MonitorPoint> queryByPage(MonitorPointPageInDTO dto) {
+        Page<MonitorPoint> page = new Page<>(dto.getPageNum(), dto.getPageSize());
+        LambdaQueryWrapper<MonitorPoint> wrapper = new LambdaQueryWrapper<>();
+        wrapper.like(dto.getPointName() != null && !dto.getPointName().isEmpty(), MonitorPoint::getPointName, dto.getPointName());
+        wrapper.eq(dto.getPointType() != null && !dto.getPointType().isEmpty(), MonitorPoint::getPointType, dto.getPointType());
+        wrapper.orderByDesc(MonitorPoint::getCreateTime);
+        return this.page(page, wrapper);
+    }
+
+    @Override
+    public Page<MonitorPoint> findByPage(long pageNum, long pageSize,
+                                          String pointCode, String pointName,
+                                          String pointType, String status) {
+        Page<MonitorPoint> page = new Page<>(pageNum, pageSize);
+        LambdaQueryWrapper<MonitorPoint> queryWrapper = new LambdaQueryWrapper<>();
+        if (pointCode != null && !pointCode.isEmpty()) {
+            queryWrapper.like(MonitorPoint::getPointCode, pointCode);
+        }
+        if (pointName != null && !pointName.isEmpty()) {
+            queryWrapper.like(MonitorPoint::getPointName, pointName);
+        }
+        if (pointType != null && !pointType.isEmpty()) {
+            queryWrapper.eq(MonitorPoint::getPointType, pointType);
+        }
+        if (status != null && !status.isEmpty()) {
+            queryWrapper.eq(MonitorPoint::getStatus, status);
+        }
+        queryWrapper.orderByDesc(MonitorPoint::getCreateTime);
+        return this.page(page, queryWrapper);
+    }
+
+    @Override
+    public boolean saveWithCheck(MonitorPoint entity) {
+        if (entity.getNetworkId() != null) {
+            PipeNetworkBase network = pipeNetworkBaseMapper.selectById(entity.getNetworkId());
+            if (network == null) {
+                throw new ServiceException("关联管网设施不存在:" + entity.getNetworkId());
+            }
+        }
+        LambdaQueryWrapper<MonitorPoint> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.eq(MonitorPoint::getPointCode, entity.getPointCode());
+        long count = this.count(queryWrapper);
+        if (count > 0) {
+            throw new ServiceException("监测点编码已存在,请更换:" + entity.getPointCode());
+        }
+        return this.save(entity);
+    }
+
+    @Override
+    public boolean saveBatchWithCheck(List<MonitorPoint> entityList) {
+        Set<String> codeSet = new HashSet<>();
+        for (MonitorPoint entity : entityList) {
+            String code = entity.getPointCode();
+            if (codeSet.contains(code)) {
+                throw new ServiceException("列表中存在重复编码:" + code);
+            }
+            codeSet.add(code);
+        }
+
+        for (MonitorPoint entity : entityList) {
+            if (entity.getNetworkId() != null) {
+                if (pipeNetworkBaseMapper.selectById(entity.getNetworkId()) == null) {
+                    throw new ServiceException("关联管网设施不存在:" + entity.getNetworkId());
+                }
+            }
+            LambdaQueryWrapper<MonitorPoint> wrapper = new LambdaQueryWrapper<>();
+            wrapper.eq(MonitorPoint::getPointCode, entity.getPointCode());
+            if (this.count(wrapper) > 0) {
+                throw new ServiceException("监测点编码已存在:" + entity.getPointCode());
+            }
+        }
+        return this.saveBatch(entityList);
+    }
+
+    @Override
+    @Transactional
+    public boolean updateWithCheck(MonitorPoint entity) {
+        String pointId = entity.getPointId();
+        if (this.getById(pointId) == null) {
+            throw new ServiceException("监测点不存在,无法修改:" + pointId);
+        }
+
+        if (entity.getNetworkId() != null) {
+            if (pipeNetworkBaseMapper.selectById(entity.getNetworkId()) == null) {
+                throw new ServiceException("关联管网设施不存在:" + entity.getNetworkId());
+            }
+        }
+
+        String newCode = entity.getPointCode();
+        if (newCode != null) {
+            LambdaQueryWrapper<MonitorPoint> wrapper = new LambdaQueryWrapper<>();
+            wrapper.eq(MonitorPoint::getPointCode, newCode)
+                    .ne(MonitorPoint::getPointId, pointId);
+            if (this.count(wrapper) > 0) {
+                throw new ServiceException("监测点编码已被使用:" + newCode);
+            }
+        }
+        return this.updateById(entity);
+    }
+
+    @Override
+    @Transactional
+    public boolean removeWithCheck(String pointId) {
+        MonitorPoint point = this.getById(pointId);
+        if (point == null) {
+            throw new ServiceException("监测点不存在:" + pointId);
+        }
+
+        LambdaQueryWrapper<EquipmentPointRel> relWrapper = new LambdaQueryWrapper<>();
+        relWrapper.eq(EquipmentPointRel::getPointId, pointId);
+        equipmentPointRelMapper.delete(relWrapper);
+        log.info("已删除监测点[{}]的设备关联关系", pointId);
+
+        return this.baseMapper.deleteById(pointId) > 0;
+    }
+
+    @Override
+    @Transactional
+    public boolean removeBatchWithCheck(List<String> pointIds) {
+        if (CollectionUtils.isEmpty(pointIds)) {
+            throw new ServiceException("批量删除失败:监测点ID列表不能为空");
+        }
+
+        List<MonitorPoint> existPoints = this.listByIds(pointIds);
+        if (existPoints.isEmpty()) {
+            throw new ServiceException("批量删除失败:所有监测点ID均不存在");
+        }
+
+        List<String> existIds = existPoints.stream()
+                .map(MonitorPoint::getPointId)
+                .collect(Collectors.toList());
+
+        List<String> invalidIds = pointIds.stream()
+                .filter(id -> !existIds.contains(id))
+                .collect(Collectors.toList());
+        if (!invalidIds.isEmpty()) {
+            log.warn("批量删除中存在无效监测点ID:{}", invalidIds);
+        }
+
+        LambdaQueryWrapper<EquipmentPointRel> relWrapper = new LambdaQueryWrapper<>();
+        relWrapper.in(EquipmentPointRel::getPointId, existIds);
+        equipmentPointRelMapper.delete(relWrapper);
+        log.info("已批量删除{}条监测点的设备关联关系", existIds.size());
+
+        return this.removeByIds(existIds);
+    }
+
+    @Override
+    @Transactional
+    public boolean bindEquipment(String pointId, List<String> equipmentIds) {
+        MonitorPoint point = this.getById(pointId);
+        if (point == null) {
+            throw new ServiceException("监测点不存在:" + pointId);
+        }
+
+        for (String equipmentId : equipmentIds) {
+            EquipmentBase equipment = equipmentBaseMapper.selectById(equipmentId);
+            if (equipment == null) {
+                throw new ServiceException("设备不存在:" + equipmentId);
+            }
+            LambdaQueryWrapper<EquipmentPointRel> checkWrapper = new LambdaQueryWrapper<>();
+            checkWrapper.eq(EquipmentPointRel::getPointId, pointId)
+                    .eq(EquipmentPointRel::getEquipmentId, equipmentId);
+            if (equipmentPointRelMapper.selectCount(checkWrapper) > 0) {
+                throw new ServiceException("设备已绑定此监测点:" + equipmentId);
+            }
+        }
+
+        List<EquipmentPointRel> relList = new ArrayList<>();
+        for (String equipmentId : equipmentIds) {
+            EquipmentPointRel rel = new EquipmentPointRel();
+            rel.setPointId(pointId);
+            rel.setEquipmentId(equipmentId);
+            relList.add(rel);
+        }
+
+        // 逐个插入或批量插入,因为 relList 类型和 this.saveBatch 不匹配
+        int count = 0;
+        for (EquipmentPointRel rel : relList) {
+            count += equipmentPointRelMapper.insert(rel);
+        }
+        return count > 0;
+    }
+
+    @Override
+    @Transactional
+    public boolean unbindEquipment(String pointId, List<String> equipmentIds) {
+        LambdaQueryWrapper<EquipmentPointRel> wrapper = new LambdaQueryWrapper<>();
+        wrapper.eq(EquipmentPointRel::getPointId, pointId)
+                .in(EquipmentPointRel::getEquipmentId, equipmentIds);
+        return equipmentPointRelMapper.delete(wrapper) > 0;
+    }
+
+    @Override
+    public Map<String, Object> getPointDetail(String pointId) {
+        MonitorPoint point = this.getById(pointId);
+        if (point == null) {
+            throw new ServiceException("监测点不存在:" + pointId);
+        }
+
+        Map<String, Object> result = new HashMap<>();
+        result.put("pointInfo", point);
+
+        if (point.getNetworkId() != null) {
+            PipeNetworkBase network = pipeNetworkBaseMapper.selectById(point.getNetworkId());
+            result.put("networkInfo", network);
+        }
+
+        LambdaQueryWrapper<EquipmentPointRel> relWrapper = new LambdaQueryWrapper<>();
+        relWrapper.eq(EquipmentPointRel::getPointId, pointId);
+        List<EquipmentPointRel> relList = equipmentPointRelMapper.selectList(relWrapper);
+        if (!relList.isEmpty()) {
+            List<String> equipmentIds = relList.stream()
+                    .map(EquipmentPointRel::getEquipmentId)
+                    .collect(Collectors.toList());
+            List<EquipmentBase> equipmentList = equipmentBaseMapper.selectBatchIds(equipmentIds);
+            result.put("equipmentList", equipmentList);
+        }
+
+        return result;
+    }
+
+    @Override
+    public List<MonitorPoint> getPointsByNetwork(String networkId) {
+        LambdaQueryWrapper<MonitorPoint> wrapper = new LambdaQueryWrapper<>();
+        wrapper.eq(MonitorPoint::getNetworkId, networkId);
+        wrapper.orderByDesc(MonitorPoint::getCreateTime);
+        return this.list(wrapper);
+    }
+}

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

@@ -0,0 +1,156 @@
+package com.zksy.base.service.impl;
+
+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.PipeNetworkBase;
+import com.zksy.base.dto.PipeNetworkPageInDTO;
+import com.zksy.base.mapper.PipeNetworkBaseMapper;
+import com.zksy.base.service.PipeNetworkBaseService;
+import com.zksy.common.exception.ServiceException;
+import lombok.extern.slf4j.Slf4j;
+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.util.stream.Collectors;
+
+@Slf4j
+@Service
+public class PipeNetworkBaseServiceImpl extends ServiceImpl<PipeNetworkBaseMapper, PipeNetworkBase>
+        implements PipeNetworkBaseService {
+
+    @Override
+    public Page<PipeNetworkBase> queryByPage(PipeNetworkPageInDTO dto) {
+        Page<PipeNetworkBase> page = new Page<>(dto.getPageNum(), dto.getPageSize());
+        LambdaQueryWrapper<PipeNetworkBase> wrapper = new LambdaQueryWrapper<>();
+        wrapper.like(dto.getNetworkName() != null && !dto.getNetworkName().isEmpty(), PipeNetworkBase::getNetworkName, dto.getNetworkName());
+        wrapper.like(dto.getManagementUnit() != null && !dto.getManagementUnit().isEmpty(), PipeNetworkBase::getManagementUnit, dto.getManagementUnit());
+        wrapper.eq(dto.getNetworkLevel() != null && !dto.getNetworkLevel().isEmpty(), PipeNetworkBase::getNetworkLevel, dto.getNetworkLevel());
+        wrapper.like(dto.getMaterial() != null && !dto.getMaterial().isEmpty(), PipeNetworkBase::getMaterial, dto.getMaterial());
+        wrapper.eq(dto.getStatus() != null && !dto.getStatus().isEmpty(), PipeNetworkBase::getStatus, dto.getStatus());
+        wrapper.orderByDesc(PipeNetworkBase::getCreateTime);
+        return this.page(page, wrapper);
+    }
+
+    @Override
+    public Page<PipeNetworkBase> findByPage(long pageNum, long pageSize,
+                                             String networkCode, String networkName,
+                                             String networkType, String status) {
+        Page<PipeNetworkBase> page = new Page<>(pageNum, pageSize);
+        LambdaQueryWrapper<PipeNetworkBase> queryWrapper = new LambdaQueryWrapper<>();
+        if (networkCode != null && !networkCode.isEmpty()) {
+            queryWrapper.like(PipeNetworkBase::getNetworkCode, networkCode);
+        }
+        if (networkName != null && !networkName.isEmpty()) {
+            queryWrapper.like(PipeNetworkBase::getNetworkName, networkName);
+        }
+        if (networkType != null && !networkType.isEmpty()) {
+            queryWrapper.eq(PipeNetworkBase::getNetworkType, networkType);
+        }
+        if (status != null && !status.isEmpty()) {
+            queryWrapper.eq(PipeNetworkBase::getStatus, status);
+        }
+        queryWrapper.orderByDesc(PipeNetworkBase::getCreateTime);
+        return this.page(page, queryWrapper);
+    }
+
+    @Override
+    public boolean saveWithCheck(PipeNetworkBase entity) {
+        LambdaQueryWrapper<PipeNetworkBase> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.eq(PipeNetworkBase::getNetworkCode, entity.getNetworkCode());
+        long count = this.count(queryWrapper);
+        if (count > 0) {
+            throw new ServiceException("设施编码已存在,请更换:" + entity.getNetworkCode());
+        }
+        return this.save(entity);
+    }
+
+    @Override
+    public boolean saveBatchWithCheck(List<PipeNetworkBase> entityList) {
+        Set<String> codeSet = new HashSet<>();
+        for (PipeNetworkBase entity : entityList) {
+            String code = entity.getNetworkCode();
+            if (codeSet.contains(code)) {
+                throw new ServiceException("列表中存在重复编码:" + code);
+            }
+            codeSet.add(code);
+        }
+
+        for (PipeNetworkBase entity : entityList) {
+            LambdaQueryWrapper<PipeNetworkBase> wrapper = new LambdaQueryWrapper<>();
+            wrapper.eq(PipeNetworkBase::getNetworkCode, entity.getNetworkCode());
+            if (this.count(wrapper) > 0) {
+                throw new ServiceException("设施编码已存在:" + entity.getNetworkCode());
+            }
+        }
+        return this.saveBatch(entityList);
+    }
+
+    @Override
+    @Transactional
+    public boolean updateWithCheck(PipeNetworkBase entity) {
+        String networkId = entity.getNetworkId();
+        if (this.getById(networkId) == null) {
+            throw new ServiceException("设施不存在,无法修改:" + networkId);
+        }
+
+        String newCode = entity.getNetworkCode();
+        if (newCode != null) {
+            LambdaQueryWrapper<PipeNetworkBase> wrapper = new LambdaQueryWrapper<>();
+            wrapper.eq(PipeNetworkBase::getNetworkCode, newCode)
+                    .ne(PipeNetworkBase::getNetworkId, networkId);
+            if (this.count(wrapper) > 0) {
+                throw new ServiceException("设施编码已被使用:" + newCode);
+            }
+        }
+        return this.updateById(entity);
+    }
+
+    @Override
+    public List<PipeNetworkBase> getOptions() {
+        LambdaQueryWrapper<PipeNetworkBase> wrapper = new LambdaQueryWrapper<>();
+        wrapper.select(PipeNetworkBase::getNetworkId, PipeNetworkBase::getNetworkName, PipeNetworkBase::getNetworkCode);
+        wrapper.orderByAsc(PipeNetworkBase::getNetworkName);
+        return this.list(wrapper);
+    }
+
+    @Override
+    @Transactional
+    public boolean removeWithCheck(String networkId) {
+        PipeNetworkBase network = this.getById(networkId);
+        if (network == null) {
+            throw new ServiceException("设施不存在:" + networkId);
+        }
+        return this.baseMapper.deleteById(networkId) > 0;
+    }
+
+    @Override
+    @Transactional
+    public boolean removeBatchWithCheck(List<String> networkIds) {
+        if (CollectionUtils.isEmpty(networkIds)) {
+            throw new ServiceException("批量删除失败:设施ID列表不能为空");
+        }
+
+        List<PipeNetworkBase> existNetworks = this.listByIds(networkIds);
+        if (existNetworks.isEmpty()) {
+            throw new ServiceException("批量删除失败:所有设施ID均不存在");
+        }
+
+        List<String> existIds = existNetworks.stream()
+                .map(PipeNetworkBase::getNetworkId)
+                .collect(Collectors.toList());
+
+        List<String> invalidIds = networkIds.stream()
+                .filter(id -> !existIds.contains(id))
+                .collect(Collectors.toList());
+        if (!invalidIds.isEmpty()) {
+            log.warn("批量删除中存在无效设施ID:{}", invalidIds);
+        }
+
+        return this.removeByIds(existIds);
+    }
+}

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

@@ -0,0 +1,37 @@
+package com.zksy.base.service.impl;
+
+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.PipeRepairRecord;
+import com.zksy.base.dto.RepairRecordPageInDTO;
+import com.zksy.base.mapper.PipeRepairRecordMapper;
+import com.zksy.base.service.PipeRepairRecordService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+@Slf4j
+@Service
+public class PipeRepairRecordServiceImpl extends ServiceImpl<PipeRepairRecordMapper, PipeRepairRecord>
+        implements PipeRepairRecordService {
+
+    @Override
+    public Page<PipeRepairRecord> findByPage(RepairRecordPageInDTO dto) {
+        Page<PipeRepairRecord> page = new Page<>(dto.getPageNum(), dto.getPageSize());
+        LambdaQueryWrapper<PipeRepairRecord> wrapper = new LambdaQueryWrapper<>();
+        wrapper.eq(dto.getNetworkId() != null && !dto.getNetworkId().isEmpty(), PipeRepairRecord::getNetworkId, dto.getNetworkId());
+        wrapper.eq(dto.getRepairType() != null && !dto.getRepairType().isEmpty(), PipeRepairRecord::getRepairType, dto.getRepairType());
+        wrapper.orderByDesc(PipeRepairRecord::getRepairDate);
+        return this.page(page, wrapper);
+    }
+
+    @Override
+    public List<PipeRepairRecord> listByNetworkId(String networkId) {
+        LambdaQueryWrapper<PipeRepairRecord> wrapper = new LambdaQueryWrapper<>();
+        wrapper.eq(PipeRepairRecord::getNetworkId, networkId);
+        wrapper.orderByDesc(PipeRepairRecord::getRepairDate);
+        return this.list(wrapper);
+    }
+}

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

@@ -0,0 +1,73 @@
+package com.zksy.base.service.impl;
+
+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.PipeNetworkBase;
+import com.zksy.base.domain.RiskAssessment;
+import com.zksy.base.dto.RiskPageInDTO;
+import com.zksy.base.mapper.PipeNetworkBaseMapper;
+import com.zksy.base.mapper.RiskAssessmentMapper;
+import com.zksy.base.service.RiskAssessmentService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.*;
+import java.util.stream.Collectors;
+
+@Slf4j
+@Service
+public class RiskAssessmentServiceImpl extends ServiceImpl<RiskAssessmentMapper, RiskAssessment>
+        implements RiskAssessmentService {
+
+    @Autowired
+    private PipeNetworkBaseMapper pipeNetworkBaseMapper;
+
+    @Override
+    public Page<RiskAssessment> findByPage(RiskPageInDTO dto) {
+        Page<RiskAssessment> page = new Page<>(dto.getPageNum(), dto.getPageSize());
+        LambdaQueryWrapper<RiskAssessment> wrapper = new LambdaQueryWrapper<>();
+        wrapper.eq(dto.getNetworkId() != null && !dto.getNetworkId().isEmpty(), RiskAssessment::getNetworkId, dto.getNetworkId());
+        wrapper.eq(dto.getRiskLevel() != null && !dto.getRiskLevel().isEmpty(), RiskAssessment::getRiskLevel, dto.getRiskLevel());
+        wrapper.orderByDesc(RiskAssessment::getAssessmentTime);
+        return this.page(page, wrapper);
+    }
+
+    @Override
+    public List<Map<String, Object>> getFourColorMapData() {
+        List<RiskAssessment> riskList = this.list(new LambdaQueryWrapper<RiskAssessment>()
+                .orderByDesc(RiskAssessment::getAssessmentTime));
+
+        Set<String> networkIds = riskList.stream()
+                .map(RiskAssessment::getNetworkId)
+                .filter(Objects::nonNull)
+                .collect(Collectors.toSet());
+
+        List<PipeNetworkBase> pipeList = new ArrayList<>();
+        if (!networkIds.isEmpty()) {
+            pipeList = pipeNetworkBaseMapper.selectBatchIds(networkIds);
+        }
+        Map<String, PipeNetworkBase> pipeMap = pipeList.stream()
+                .collect(Collectors.toMap(PipeNetworkBase::getNetworkId, p -> p, (k1, k2) -> k1));
+
+        List<Map<String, Object>> result = new ArrayList<>();
+        for (RiskAssessment risk : riskList) {
+            Map<String, Object> item = new HashMap<>();
+            item.put("riskId", risk.getRiskId());
+            item.put("networkId", risk.getNetworkId());
+            item.put("riskLevel", risk.getRiskLevel());
+            item.put("riskScore", risk.getRiskScore());
+            item.put("riskColor", risk.getRiskColor());
+            PipeNetworkBase pipe = pipeMap.get(risk.getNetworkId());
+            if (pipe != null) {
+                item.put("networkName", pipe.getNetworkName());
+                item.put("longitude", pipe.getLongitude());
+                item.put("latitude", pipe.getLatitude());
+                item.put("networkCode", pipe.getNetworkCode());
+            }
+            result.add(item);
+        }
+        return result;
+    }
+}

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

@@ -0,0 +1,28 @@
+package com.zksy.base.service.impl;
+
+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.StationVideoDevice;
+import com.zksy.base.mapper.StationVideoDeviceMapper;
+import com.zksy.base.service.StationVideoDeviceService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+
+@Slf4j
+@Service
+public class StationVideoDeviceServiceImpl extends ServiceImpl<StationVideoDeviceMapper, StationVideoDevice>
+        implements StationVideoDeviceService {
+
+    @Override
+    public Page<StationVideoDevice> findByPage(long pageNum, long pageSize,
+                                               String deviceName, String stationId, String status) {
+        Page<StationVideoDevice> page = new Page<>(pageNum, pageSize);
+        LambdaQueryWrapper<StationVideoDevice> wrapper = new LambdaQueryWrapper<>();
+        wrapper.like(deviceName != null && !deviceName.isEmpty(), StationVideoDevice::getDeviceName, deviceName);
+        wrapper.eq(stationId != null && !stationId.isEmpty(), StationVideoDevice::getStationId, stationId);
+        wrapper.eq(status != null && !status.isEmpty(), StationVideoDevice::getStatus, status);
+        wrapper.orderByDesc(StationVideoDevice::getCreateTime);
+        return this.page(page, wrapper);
+    }
+}

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

@@ -0,0 +1,24 @@
+package com.zksy.base.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.zksy.base.domain.WorkOrderLog;
+import com.zksy.base.mapper.WorkOrderLogMapper;
+import com.zksy.base.service.WorkOrderLogService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+
+/**
+* @author Administrator
+* @description 针对表【work_order_log(工单操作日志表)】的数据库操作Service实现
+* @createDate 2026-06-11 11:51:09
+*/
+@Slf4j
+@Service
+public class WorkOrderLogServiceImpl extends ServiceImpl<WorkOrderLogMapper, WorkOrderLog>
+    implements WorkOrderLogService{
+
+}
+
+
+
+

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

@@ -0,0 +1,126 @@
+package com.zksy.base.service.impl;
+
+import cn.hutool.core.bean.BeanUtil;
+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.WorkOrder;
+import com.zksy.base.domain.WorkOrderLog;
+import com.zksy.base.mapper.WorkOrderLogMapper;
+import com.zksy.base.mapper.WorkOrderMapper;
+import com.zksy.base.service.WorkOrderService;
+import com.zksy.common.core.domain.entity.SysUser;
+import com.zksy.common.exception.ServiceException;
+import com.zksy.manhole.dto.in.WorkOrderOperInDTO;
+import com.zksy.manhole.dto.in.WorkOrderPageInDTO;
+import com.zksy.manhole.dto.out.WorkOrderOutDTO;
+import com.zksy.system.service.ISysUserService;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.Date;
+import java.util.List;
+
+/**
+* @author Administrator
+* @description 针对表【work_order(运维工单表)】的数据库操作Service实现
+* @createDate 2026-06-11 11:50:08
+*/
+@Slf4j
+@Service
+public class WorkOrderServiceImpl extends ServiceImpl<WorkOrderMapper, WorkOrder>
+    implements WorkOrderService{
+
+    @Autowired
+    private ISysUserService sysUserService;
+
+    @Autowired
+    private WorkOrderLogMapper workOrderLogMapper;
+
+    /**
+     * 分页查询工单信息列表
+     * @param pageInDTO
+     * @return
+     */
+    @Override
+    public Page<WorkOrderOutDTO> findByPage(WorkOrderPageInDTO pageInDTO) {
+        log.info("分页查询工单信息列表-入参:{}", pageInDTO);
+        Page<WorkOrder> page = new Page<>(pageInDTO.getPageNum(), pageInDTO.getPageSize());
+        LambdaQueryWrapper<WorkOrder> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.like(StringUtils.isNotEmpty(pageInDTO.getOrderNo()), WorkOrder::getOrderNo, pageInDTO.getOrderNo())
+                .like(StringUtils.isNotEmpty(pageInDTO.getCaseNo()), WorkOrder::getCaseNo, pageInDTO.getCaseNo())
+                .orderByDesc(WorkOrder::getUpdateTime);
+        Page<WorkOrder> rs = this.page(page, queryWrapper);
+        List<WorkOrderOutDTO> outDTOList = BeanUtil.copyToList(rs.getRecords(), WorkOrderOutDTO.class);
+        Page<WorkOrderOutDTO> outPage = new Page<>(pageInDTO.getPageNum(), pageInDTO.getPageSize(), rs.getTotal());
+        outPage.setRecords(outDTOList);
+        return outPage;
+    }
+
+    /**
+     * 操作工单
+     * @param inDTO
+     * @return
+     */
+    @Override
+    public boolean operWorkOrder(WorkOrderOperInDTO inDTO) {
+        log.info("操作工单-入参:{}", inDTO);
+        WorkOrder workOrder = this.getById(inDTO.getOrderId());
+        if(workOrder == null){
+            throw new ServiceException("工单ID不存在");
+        }
+        SysUser user = sysUserService.selectUserById(inDTO.getOperUserId());
+        if(user == null){
+            throw new ServiceException("操作人ID不存在");
+        }
+        if(inDTO.getOperType() == null){
+            throw new ServiceException("操作类型不能为空");
+        }
+        WorkOrder entity = new WorkOrder();
+        entity.setOrderId(inDTO.getOrderId());
+        if(inDTO.getOperType() == 2){
+            //2-派单
+            entity.setOrderStatus(2);
+            entity.setDispatchUser(inDTO.getOperUserId());
+            entity.setDispatchTime(new Date());
+            entity.setReceiveUser(inDTO.getReceiveUser());
+        } else if(inDTO.getOperType() == 3){
+            //3-接单
+            entity.setOrderStatus(3);
+            entity.setReceiveUser(inDTO.getOperUserId());
+        } else if(inDTO.getOperType() == 4){
+            //4-开始维修
+            entity.setOrderStatus(4);
+        } else if(inDTO.getOperType() == 5){
+            //5-提交验收
+            entity.setOrderStatus(5);
+            entity.setVerifyUser(workOrder.getDispatchUser());
+        } else if(inDTO.getOperType() == 6){
+            //6-验收通过
+            entity.setOrderStatus(6);
+            entity.setVerifyUser(inDTO.getOperUserId());
+            entity.setVerifyTime(new Date());
+        } else if(inDTO.getOperType() == 7){
+            //7-驳回工单
+            entity.setOrderStatus(7);
+        } else if(inDTO.getOperType() == 8){
+            //8-申请延期
+            entity.setOrderStatus(8);
+            entity.setDelayedReason(inDTO.getDelayedReason());
+            entity.setDelayedDeadline(inDTO.getDelayedDeadline());
+        } else if(inDTO.getOperType() == 9){
+            //9-延期审核通过
+            entity.setOrderStatus(9);
+        }
+        WorkOrderLog workOrderLog = BeanUtil.copyProperties(inDTO, WorkOrderLog.class);
+        workOrderLog.setOperUserName(user.getNickName());
+        workOrderLogMapper.insert(workOrderLog);
+        return this.updateById(entity);
+    }
+}
+
+
+
+

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

@@ -8,6 +8,7 @@ import com.fasterxml.jackson.annotation.JsonFormat;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
+import org.springframework.format.annotation.DateTimeFormat;
 
 import java.io.Serializable;
 import java.math.BigDecimal;
@@ -64,6 +65,7 @@ public class EarlyWarning implements Serializable {
 
     @TableField("publish_time")
     @ApiModelProperty("发布时间")
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
     @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
     private LocalDateTime publishTime;
 

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

@@ -26,19 +26,19 @@ public interface EarlyWarningService extends IService<EarlyWarning> {
 
     boolean saveWarning(EarlyWarning warning, List<String> alarmIds, List<MultipartFile> files);
 
-    boolean updateWarning(EarlyWarning warning, List<MultipartFile> files);
+    boolean updateWarning(EarlyWarning warning, List<String> alarmIds, List<MultipartFile> files);
 
     boolean deleteWarning(String warningId);
 
     boolean deleteBatchWarning(List<String> warningIds);
 
-    boolean publishWarning(String warningId, String disposalUser);
+    boolean publishWarning(String warningId);
 
-    boolean upgradeWarning(String warningId, String newLevel, String disposalUser, String disposalContent);
+    boolean upgradeWarning(String warningId, String newLevel, String disposalContent);
 
-    boolean resolveWarning(String warningId, String disposalUser, String disposalContent);
+    boolean resolveWarning(String warningId, String disposalContent);
 
-    boolean returnWarning(String warningId, String disposalUser, String disposalContent);
+    boolean returnWarning(String warningId, String disposalContent);
 
     boolean supervisionWarning(String warningId, String supervisionUser, String supervisionContent, String notificationType, String notificationContent, String attachmentUrl);
 

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

@@ -0,0 +1,27 @@
+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.WarningItem;
+import com.zksy.base.warning.domain.WarningReason;
+
+import java.util.List;
+
+public interface WarningItemService extends IService<WarningItem> {
+
+    IPage<WarningItem> queryWarningItems(Page<WarningItem> page, String itemCode, String itemName, 
+                                         String warningType, String warningLevel, String warningSpecial, String status);
+
+    boolean addWarningItem(WarningItem warningItem);
+
+    boolean updateWarningItem(WarningItem warningItem);
+
+    boolean updateItemStatus(String itemId, String status);
+
+    WarningItem getItemDetail(String itemId);
+
+    WarningItem getItemByCode(String itemCode);
+
+    String generateItemCode(String warningType, String warningLevel);
+}

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

@@ -0,0 +1,24 @@
+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.WarningReason;
+
+import java.util.List;
+
+public interface WarningReasonService extends IService<WarningReason> {
+
+    IPage<WarningReason> queryWarningReasons(Page<WarningReason> page, String reasonCode, String reasonName, 
+                                             String warningType, String warningLevel, String status);
+
+    List<WarningReason> getReasonsByTypeAndLevel(String warningType, String warningLevel);
+
+    boolean addWarningReason(WarningReason warningReason);
+
+    boolean updateWarningReason(WarningReason warningReason);
+
+    boolean updateReasonStatus(String reasonId, String status);
+
+    WarningReason getReasonDetail(String reasonId);
+}

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

@@ -191,11 +191,16 @@ public class EarlyWarningServiceImpl extends ServiceImpl<EarlyWarningMapper, Ear
 
     @Override
     @Transactional(rollbackFor = Exception.class)
-    public boolean updateWarning(EarlyWarning warning, List<MultipartFile> files) {
+    public boolean updateWarning(EarlyWarning warning, List<String> alarmIds, List<MultipartFile> files) {
         warning.setUpdateTime(LocalDateTime.now());
         boolean result = updateById(warning);
-        if (result && files != null && !files.isEmpty()) {
-            saveAttachments(warning.getWarningId(), files);
+        if (result) {
+            if (alarmIds != null) {
+                linkAlarms(warning.getWarningId(), alarmIds);
+            }
+            if (files != null && !files.isEmpty()) {
+                saveAttachments(warning.getWarningId(), files);
+            }
         }
         return result;
     }
@@ -252,7 +257,7 @@ public class EarlyWarningServiceImpl extends ServiceImpl<EarlyWarningMapper, Ear
 
     @Override
     @Transactional(rollbackFor = Exception.class)
-    public boolean publishWarning(String warningId, String disposalUser) {
+    public boolean publishWarning(String warningId) {
         EarlyWarning warning = getById(warningId);
         if (warning == null) return false;
 
@@ -263,7 +268,7 @@ public class EarlyWarningServiceImpl extends ServiceImpl<EarlyWarningMapper, Ear
         boolean result = updateById(warning);
 
         if (result) {
-            addDisposalRecord(warningId, "RELEASE", null, null, disposalUser, "系统发布预警信息");
+            addDisposalRecord(warningId, "RELEASE", null, null, warning.getHandler(), "系统发布预警信息");
             createTodo(warningId, warning.getHandler(), "待办预警", "TODO");
         }
 
@@ -272,7 +277,7 @@ public class EarlyWarningServiceImpl extends ServiceImpl<EarlyWarningMapper, Ear
 
     @Override
     @Transactional(rollbackFor = Exception.class)
-    public boolean upgradeWarning(String warningId, String newLevel, String disposalUser, String disposalContent) {
+    public boolean upgradeWarning(String warningId, String newLevel, String disposalContent) {
         EarlyWarning warning = getById(warningId);
         if (warning == null) return false;
 
@@ -282,14 +287,14 @@ public class EarlyWarningServiceImpl extends ServiceImpl<EarlyWarningMapper, Ear
 
         boolean result = updateById(warning);
         if (result) {
-            addDisposalRecord(warningId, "UPGRADE", oldLevel, newLevel, disposalUser, disposalContent);
+            addDisposalRecord(warningId, "UPGRADE", oldLevel, newLevel, warning.getHandler(), disposalContent);
         }
         return result;
     }
 
     @Override
     @Transactional(rollbackFor = Exception.class)
-    public boolean resolveWarning(String warningId, String disposalUser, String disposalContent) {
+    public boolean resolveWarning(String warningId, String disposalContent) {
         EarlyWarning warning = getById(warningId);
         if (warning == null) return false;
 
@@ -298,7 +303,7 @@ public class EarlyWarningServiceImpl extends ServiceImpl<EarlyWarningMapper, Ear
 
         boolean result = updateById(warning);
         if (result) {
-            addDisposalRecord(warningId, "RESOLVE", null, null, disposalUser, disposalContent);
+            addDisposalRecord(warningId, "RESOLVE", null, null, warning.getHandler(), disposalContent);
             completeTodo(warningId);
             
             // 解除预警时自动创建归档
@@ -312,7 +317,7 @@ public class EarlyWarningServiceImpl extends ServiceImpl<EarlyWarningMapper, Ear
 
     @Override
     @Transactional(rollbackFor = Exception.class)
-    public boolean returnWarning(String warningId, String disposalUser, String disposalContent) {
+    public boolean returnWarning(String warningId, String disposalContent) {
         EarlyWarning warning = getById(warningId);
         if (warning == null) return false;
 
@@ -321,7 +326,7 @@ public class EarlyWarningServiceImpl extends ServiceImpl<EarlyWarningMapper, Ear
 
         boolean result = updateById(warning);
         if (result) {
-            addDisposalRecord(warningId, "RETURN", null, null, disposalUser, disposalContent);
+            addDisposalRecord(warningId, "RETURN", null, null, warning.getHandler(), disposalContent);
         }
         return result;
     }

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

@@ -0,0 +1,113 @@
+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.WarningItem;
+import com.zksy.base.warning.mapper.WarningItemMapper;
+import com.zksy.base.warning.service.WarningItemService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+@Slf4j
+@Service
+public class WarningItemServiceImpl extends ServiceImpl<WarningItemMapper, WarningItem> implements WarningItemService {
+
+    @Override
+    public IPage<WarningItem> queryWarningItems(Page<WarningItem> page, String itemCode, String itemName, 
+                                                 String warningType, String warningLevel, String warningSpecial, String status) {
+        LambdaQueryWrapper<WarningItem> wrapper = new LambdaQueryWrapper<>();
+        
+        if (itemCode != null && !itemCode.isEmpty()) {
+            wrapper.like(WarningItem::getItemCode, itemCode);
+        }
+        if (itemName != null && !itemName.isEmpty()) {
+            wrapper.like(WarningItem::getItemName, itemName);
+        }
+        if (warningType != null && !warningType.isEmpty()) {
+            wrapper.eq(WarningItem::getWarningType, warningType);
+        }
+        if (warningLevel != null && !warningLevel.isEmpty()) {
+            wrapper.eq(WarningItem::getWarningLevel, warningLevel);
+        }
+        if (warningSpecial != null && !warningSpecial.isEmpty()) {
+            wrapper.like(WarningItem::getWarningSpecial, warningSpecial);
+        }
+        if (status != null && !status.isEmpty()) {
+            wrapper.eq(WarningItem::getStatus, status);
+        }
+        
+        wrapper.orderByDesc(WarningItem::getCreateTime);
+        return this.page(page, wrapper);
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean addWarningItem(WarningItem warningItem) {
+        if (warningItem.getItemCode() == null || warningItem.getItemCode().isEmpty()) {
+            warningItem.setItemCode(generateItemCode(warningItem.getWarningType(), warningItem.getWarningLevel()));
+        }
+        if (warningItem.getStatus() == null) {
+            warningItem.setStatus("ENABLED");
+        }
+        return this.save(warningItem);
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean updateWarningItem(WarningItem warningItem) {
+        return this.updateById(warningItem);
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean updateItemStatus(String itemId, String status) {
+        WarningItem item = new WarningItem();
+        item.setItemId(itemId);
+        item.setStatus(status);
+        return this.updateById(item);
+    }
+
+    @Override
+    public WarningItem getItemDetail(String itemId) {
+        return this.getById(itemId);
+    }
+
+    @Override
+    public WarningItem getItemByCode(String itemCode) {
+        LambdaQueryWrapper<WarningItem> wrapper = new LambdaQueryWrapper<>();
+        wrapper.eq(WarningItem::getItemCode, itemCode);
+        return this.getOne(wrapper);
+    }
+
+    @Override
+    public String generateItemCode(String warningType, String warningLevel) {
+        String dateStr = new SimpleDateFormat("yyyyMMdd").format(new Date());
+        String prefix = "WI" + warningType.substring(0, Math.min(3, warningType.length())).toUpperCase() + warningLevel;
+        
+        LambdaQueryWrapper<WarningItem> wrapper = new LambdaQueryWrapper<>();
+        wrapper.likeRight(WarningItem::getItemCode, prefix + dateStr);
+        wrapper.orderByDesc(WarningItem::getItemCode);
+        wrapper.last("LIMIT 1");
+        
+        WarningItem lastItem = this.getOne(wrapper);
+        int sequence = 1;
+        
+        if (lastItem != null) {
+            String lastCode = lastItem.getItemCode();
+            String lastSeqStr = lastCode.substring(lastCode.length() - 4);
+            try {
+                sequence = Integer.parseInt(lastSeqStr) + 1;
+            } catch (NumberFormatException e) {
+                sequence = 1;
+            }
+        }
+        
+        return prefix + dateStr + String.format("%04d", sequence);
+    }
+}

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

@@ -0,0 +1,116 @@
+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.WarningReason;
+import com.zksy.base.warning.mapper.WarningReasonMapper;
+import com.zksy.base.warning.service.WarningReasonService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.List;
+
+@Slf4j
+@Service
+public class WarningReasonServiceImpl extends ServiceImpl<WarningReasonMapper, WarningReason> implements WarningReasonService {
+
+    @Override
+    public IPage<WarningReason> queryWarningReasons(Page<WarningReason> page, String reasonCode, String reasonName, 
+                                                     String warningType, String warningLevel, String status) {
+        LambdaQueryWrapper<WarningReason> wrapper = new LambdaQueryWrapper<>();
+        
+        if (reasonCode != null && !reasonCode.isEmpty()) {
+            wrapper.like(WarningReason::getReasonCode, reasonCode);
+        }
+        if (reasonName != null && !reasonName.isEmpty()) {
+            wrapper.like(WarningReason::getReasonName, reasonName);
+        }
+        if (warningType != null && !warningType.isEmpty()) {
+            wrapper.eq(WarningReason::getWarningType, warningType);
+        }
+        if (warningLevel != null && !warningLevel.isEmpty()) {
+            wrapper.eq(WarningReason::getWarningLevel, warningLevel);
+        }
+        if (status != null && !status.isEmpty()) {
+            wrapper.eq(WarningReason::getStatus, status);
+        }
+        
+        wrapper.orderByAsc(WarningReason::getSortOrder).orderByDesc(WarningReason::getCreateTime);
+        return this.page(page, wrapper);
+    }
+
+    @Override
+    public List<WarningReason> getReasonsByTypeAndLevel(String warningType, String warningLevel) {
+        LambdaQueryWrapper<WarningReason> wrapper = new LambdaQueryWrapper<>();
+        wrapper.eq(WarningReason::getWarningType, warningType)
+               .eq(WarningReason::getWarningLevel, warningLevel)
+               .eq(WarningReason::getStatus, "0")
+               .orderByAsc(WarningReason::getSortOrder);
+        return this.list(wrapper);
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean addWarningReason(WarningReason warningReason) {
+        if (warningReason.getReasonCode() == null || warningReason.getReasonCode().isEmpty()) {
+            warningReason.setReasonCode(generateReasonCode(warningReason.getWarningType(), warningReason.getWarningLevel()));
+        }
+        if (warningReason.getStatus() == null) {
+            warningReason.setStatus("0");
+        }
+        if (warningReason.getSortOrder() == null) {
+            warningReason.setSortOrder(0);
+        }
+        return this.save(warningReason);
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean updateWarningReason(WarningReason warningReason) {
+        return this.updateById(warningReason);
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean updateReasonStatus(String reasonId, String status) {
+        WarningReason reason = new WarningReason();
+        reason.setReasonId(reasonId);
+        reason.setStatus(status);
+        return this.updateById(reason);
+    }
+
+    @Override
+    public WarningReason getReasonDetail(String reasonId) {
+        return this.getById(reasonId);
+    }
+
+    private String generateReasonCode(String warningType, String warningLevel) {
+        String dateStr = new SimpleDateFormat("yyyyMMdd").format(new Date());
+        String prefix = "WR" + warningType.substring(0, Math.min(3, warningType.length())).toUpperCase() + warningLevel;
+        
+        LambdaQueryWrapper<WarningReason> wrapper = new LambdaQueryWrapper<>();
+        wrapper.likeRight(WarningReason::getReasonCode, prefix + dateStr);
+        wrapper.orderByDesc(WarningReason::getReasonCode);
+        wrapper.last("LIMIT 1");
+        
+        WarningReason lastReason = this.getOne(wrapper);
+        int sequence = 1;
+        
+        if (lastReason != null) {
+            String lastCode = lastReason.getReasonCode();
+            String lastSeqStr = lastCode.substring(lastCode.length() - 4);
+            try {
+                sequence = Integer.parseInt(lastSeqStr) + 1;
+            } catch (NumberFormatException e) {
+                sequence = 1;
+            }
+        }
+        
+        return prefix + dateStr + String.format("%04d", sequence);
+    }
+}

+ 30 - 0
pipe-network-service/zksy-system/src/main/java/com/zksy/manhole/dto/in/CaseInfoPageInDTO.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 CaseInfoPageInDTO implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    @ApiModelProperty(value = "案件编号")
+    private String caseNo;
+
+    @ApiModelProperty("设备位置描述")
+    private String equipmentLocation;
+
+    @ApiModelProperty(value = "当前记录起始索引", required = true)
+    private Long pageNum;
+
+    @ApiModelProperty(value = "每页显示记录数", required = true)
+    private Long pageSize;
+}

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

@@ -0,0 +1,54 @@
+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 CaseInfoSaveInDTO implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 关联设备ID
+     */
+    @ApiModelProperty(value = "设备ID", required = true)
+    private String deviceId;
+
+    /**
+     * 设备编码
+     */
+    @ApiModelProperty(value = "设备编码", required = true)
+    private String deviceCode;
+
+    /**
+     * 案件等级:1-严重 2-一般 3-轻微
+     */
+    @ApiModelProperty(value = "案件等级:1-严重 2-一般 3-轻微", required = true)
+    private Integer caseLevel;
+
+    /**
+     * 案件描述
+     */
+    @ApiModelProperty(value = "案件描述", required = true)
+    private String caseDesc;
+
+    /**
+     * 立案人ID
+     */
+    @ApiModelProperty(value = "立案人ID", required = true)
+    private Long fileUser;
+
+    /**
+     * 案件佐证图片、附件地址
+     */
+    @ApiModelProperty(value = "案件佐证图片、附件地址")
+    private String attachUrl;
+}

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

@@ -0,0 +1,27 @@
+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 CaseInfoVerifyInDTO implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    @ApiModelProperty(value = "案件ID", required = true)
+    private Long caseId;
+
+    @ApiModelProperty(value = "核查人ID", required = true)
+    private Long verifyUser;
+
+    @ApiModelProperty(value = "核查结果:1-待处理,2-误报", required = true)
+    private Integer verifyResult;
+}

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

@@ -0,0 +1,42 @@
+package com.zksy.manhole.dto.in;
+
+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 WorkOrderOperInDTO implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    @ApiModelProperty(value = "工单ID", required = true)
+    private Long orderId;
+
+    @ApiModelProperty(value = "操作类型:2-派单 3-接单 4-开始维修 5-提交验收 6-验收通过 7-驳回工单 8-申请延期 9-延期审核通过", required = true)
+    private Integer operType;
+
+    @ApiModelProperty(value = "操作详情描述", required = true)
+    private String operDesc;
+
+    @ApiModelProperty(value = "操作人ID", required = true)
+    private Long operUserId;
+
+    @ApiModelProperty(value = "接单运维人员ID(操作类型为 2-派单 时,必填)")
+    private Long receiveUser;
+
+    @ApiModelProperty(value = "延期原因(操作类型为 8-申请延期 时,必填)")
+    private String delayedReason;
+
+    @ApiModelProperty(value = "延期截止时间(操作类型为 8-申请延期 时,必填)")
+    @JsonFormat(locale = "zh",pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
+    private Date delayedDeadline;
+}

+ 30 - 0
pipe-network-service/zksy-system/src/main/java/com/zksy/manhole/dto/in/WorkOrderPageInDTO.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 WorkOrderPageInDTO implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    @ApiModelProperty(value = "工单编号")
+    private String orderNo;
+
+    @ApiModelProperty(value = "案件编号")
+    private String caseNo;
+
+    @ApiModelProperty(value = "当前记录起始索引", required = true)
+    private Long pageNum;
+
+    @ApiModelProperty(value = "每页显示记录数", required = true)
+    private Long pageSize;
+}

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

@@ -0,0 +1,25 @@
+package com.zksy.manhole.dto.out;
+
+import com.zksy.base.domain.CaseInfo;
+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 CaseInfoOutDTO extends CaseInfo implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    @ApiModelProperty("设备类别名称")
+    private String equipmentTypeName;
+
+    @ApiModelProperty(value = "设备状态详情")
+    private EquipmentStatusOutDTO equipmentStatus;
+}

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

@@ -0,0 +1,19 @@
+package com.zksy.manhole.dto.out;
+
+import com.zksy.base.domain.WorkOrderLog;
+import io.swagger.annotations.ApiModel;
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * 工单操作日志-出参
+ *
+ * @author xianggx
+ */
+@Data
+@ApiModel(value = "工单操作日志-出参", description = "工单操作日志-出参")
+public class WorkOrderLogOutDTO extends WorkOrderLog implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+}

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

@@ -0,0 +1,29 @@
+package com.zksy.manhole.dto.out;
+
+import com.zksy.base.domain.WorkOrder;
+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 WorkOrderOutDTO extends WorkOrder implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    @ApiModelProperty("设备类别名称")
+    private String equipmentTypeName;
+
+    @ApiModelProperty(value = "设备状态详情")
+    private EquipmentStatusOutDTO equipmentStatus;
+
+    @ApiModelProperty(value = "工单操作日志列表")
+    private List<WorkOrderLogOutDTO> workOrderLogList;
+}

+ 35 - 0
pipe-network-service/zksy-system/src/main/resources/mapper/CaseInfoMapper.xml

@@ -0,0 +1,35 @@
+<?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.CaseInfoMapper">
+
+    <resultMap id="BaseResultMap" type="com.zksy.base.domain.CaseInfo">
+            <id property="caseId" column="case_id" jdbcType="BIGINT"/>
+            <result property="caseNo" column="case_no" jdbcType="VARCHAR"/>
+            <result property="alarmId" column="alarm_id" jdbcType="VARCHAR"/>
+            <result property="deviceId" column="device_id" jdbcType="VARCHAR"/>
+            <result property="deviceCode" column="device_code" jdbcType="VARCHAR"/>
+            <result property="caseLevel" column="case_level" jdbcType="TINYINT"/>
+            <result property="caseDesc" column="case_desc" jdbcType="VARCHAR"/>
+            <result property="caseSource" column="case_source" jdbcType="TINYINT"/>
+            <result property="caseStatus" column="case_status" jdbcType="TINYINT"/>
+            <result property="fileUser" column="file_user" jdbcType="BIGINT"/>
+            <result property="verifyUser" column="verify_user" jdbcType="BIGINT"/>
+            <result property="verifyTime" column="verify_time" jdbcType="TIMESTAMP"/>
+            <result property="finishTime" column="finish_time" jdbcType="TIMESTAMP"/>
+            <result property="handleResult" column="handle_result" jdbcType="VARCHAR"/>
+            <result property="attachUrl" column="attach_url" jdbcType="VARCHAR"/>
+            <result property="createTime" column="create_time" jdbcType="TIMESTAMP"/>
+            <result property="updateTime" column="update_time" jdbcType="TIMESTAMP"/>
+    </resultMap>
+
+    <sql id="Base_Column_List">
+        case_id,case_no,alarm_id,
+        device_id,device_code,case_level,
+        case_desc,case_source,case_status,
+        file_user,verify_user,verify_time,
+        finish_time,handle_result,attach_url,
+        create_time,update_time
+    </sql>
+</mapper>

+ 22 - 0
pipe-network-service/zksy-system/src/main/resources/mapper/WorkOrderLogMapper.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.mapper.WorkOrderLogMapper">
+
+    <resultMap id="BaseResultMap" type="com.zksy.base.domain.WorkOrderLog">
+            <id property="logId" column="log_id" jdbcType="BIGINT"/>
+            <result property="orderId" column="order_id" jdbcType="BIGINT"/>
+            <result property="operType" column="oper_type" jdbcType="TINYINT"/>
+            <result property="operDesc" column="oper_desc" jdbcType="VARCHAR"/>
+            <result property="operUserId" column="oper_user_id" jdbcType="BIGINT"/>
+            <result property="operUserName" column="oper_user_name" jdbcType="VARCHAR"/>
+            <result property="operTime" column="oper_time" jdbcType="TIMESTAMP"/>
+    </resultMap>
+
+    <sql id="Base_Column_List">
+        log_id,order_id,oper_type,
+        oper_desc,oper_user_id,oper_user_name,
+        oper_time
+    </sql>
+</mapper>

+ 44 - 0
pipe-network-service/zksy-system/src/main/resources/mapper/WorkOrderMapper.xml

@@ -0,0 +1,44 @@
+<?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.WorkOrderMapper">
+
+    <resultMap id="BaseResultMap" type="com.zksy.base.domain.WorkOrder">
+            <id property="orderId" column="order_id" jdbcType="BIGINT"/>
+            <result property="orderNo" column="order_no" jdbcType="VARCHAR"/>
+            <result property="alarmId" column="alarm_id" jdbcType="VARCHAR"/>
+            <result property="caseId" column="case_id" jdbcType="BIGINT"/>
+            <result property="caseNo" column="case_no" jdbcType="VARCHAR"/>
+            <result property="deviceId" column="device_id" jdbcType="VARCHAR"/>
+            <result property="deviceCode" column="device_code" jdbcType="VARCHAR"/>
+            <result property="orderType" column="order_type" jdbcType="TINYINT"/>
+            <result property="orderLevel" column="order_level" jdbcType="TINYINT"/>
+            <result property="orderDesc" column="order_desc" jdbcType="VARCHAR"/>
+            <result property="deptId" column="dept_id" jdbcType="BIGINT"/>
+            <result property="dispatchUser" column="dispatch_user" jdbcType="BIGINT"/>
+            <result property="dispatchTime" column="dispatch_time" jdbcType="TIMESTAMP"/>
+            <result property="receiveUser" column="receive_user" jdbcType="BIGINT"/>
+            <result property="orderStatus" column="order_status" jdbcType="TINYINT"/>
+            <result property="delayedReason" column="delayed_reason" jdbcType="VARCHAR"/>
+            <result property="delayedDeadline" column="delayed_deadline" jdbcType="TIMESTAMP"/>
+            <result property="planFinishTime" column="plan_finish_time" jdbcType="TIMESTAMP"/>
+            <result property="realFinishTime" column="real_finish_time" jdbcType="TIMESTAMP"/>
+            <result property="repairResult" column="repair_result" jdbcType="VARCHAR"/>
+            <result property="verifyUser" column="verify_user" jdbcType="BIGINT"/>
+            <result property="verifyTime" column="verify_time" jdbcType="TIMESTAMP"/>
+            <result property="createTime" column="create_time" jdbcType="TIMESTAMP"/>
+            <result property="updateTime" column="update_time" jdbcType="TIMESTAMP"/>
+    </resultMap>
+
+    <sql id="Base_Column_List">
+        order_id,order_no,alarm_id,
+        case_id,case_no,device_id,
+        device_code,order_type,order_level,
+        order_desc,dept_id,dispatch_user,
+        dispatch_time,receive_user,order_status,
+        delayed_reason,delayed_deadline,plan_finish_time,
+        real_finish_time,repair_result,verify_user,
+        verify_time,create_time,update_time
+    </sql>
+</mapper>