ソースを参照

设备管理统一管理

zengy 4 週間 前
親
コミット
e6f3b9fed1
47 ファイル変更、568 行追加、3421 行削除
  1. 6 5
      T6-water-device-handoff.md
  2. 6 32
      manhole-service/src/main/java/com/zksy/manhole/domain/EquipmentStatus.java
  3. 2 2
      manhole-service/src/main/java/com/zksy/manhole/mapper/EquipmentStatusMapper.java
  4. 2 2
      manhole-service/src/main/java/com/zksy/manhole/service/EquipmentStatusService.java
  5. 7 7
      manhole-service/src/main/java/com/zksy/manhole/service/impl/BaseDevicesManholeServiceImpl.java
  6. 0 12
      manhole-service/src/main/java/com/zksy/manhole/service/impl/EquipmentStatusManholeServiceImpl.java
  7. 12 0
      manhole-service/src/main/java/com/zksy/manhole/service/impl/EquipmentStatusServiceImpl.java
  8. 8 13
      pipe-network-service/sql/iot_equipment_management.sql
  9. 0 1
      pipe-network-service/sql/water_supply_monitoring_alarm_rebuild_test_data.sql
  10. 0 130
      pipe-network-service/zksy-admin/src/main/java/com/zksy/web/controller/WaterSupply/DeviceAbnormal/DeviceAbnormalController.java
  11. 0 128
      pipe-network-service/zksy-admin/src/main/java/com/zksy/web/controller/WaterSupply/DeviceLedger/DeviceLedgerController.java
  12. 0 167
      pipe-network-service/zksy-admin/src/main/java/com/zksy/web/controller/WaterSupply/DeviceMaintain/DeviceMaintainController.java
  13. 45 64
      pipe-network-service/zksy-admin/src/main/java/com/zksy/web/controller/base/EquipmentBaseController.java
  14. 19 86
      pipe-network-service/zksy-admin/src/main/java/com/zksy/web/controller/base/EquipmentStatusController.java
  15. 10 2
      pipe-network-service/zksy-admin/src/main/java/com/zksy/web/controller/base/EquipmentTypeController.java
  16. 0 71
      pipe-network-service/zksy-admin/src/main/java/com/zksy/web/controller/drainage/DrainageEquipmentController.java
  17. 5 80
      pipe-network-service/zksy-admin/src/main/java/com/zksy/web/controller/gasbasic/GasEquipmentController.java
  18. 0 198
      pipe-network-service/zksy-admin/src/test/java/com/zksy/web/controller/WaterSupply/DeviceAbnormal/DeviceAbnormalControllerTest.java
  19. 0 50
      pipe-network-service/zksy-admin/src/test/java/com/zksy/web/controller/WaterSupply/DeviceLedger/DeviceLedgerControllerTest.java
  20. 0 76
      pipe-network-service/zksy-system/src/main/java/com/zksy/WaterSupply/export/WaterDeviceAbnormalExportDTO.java
  21. 0 51
      pipe-network-service/zksy-system/src/main/java/com/zksy/WaterSupply/export/WaterDeviceLedgerExportDTO.java
  22. 0 55
      pipe-network-service/zksy-system/src/main/java/com/zksy/WaterSupply/importing/WaterDeviceLedgerImportDTO.java
  23. 0 126
      pipe-network-service/zksy-system/src/main/java/com/zksy/WaterSupply/importing/WaterDeviceLedgerImportService.java
  24. 7 27
      pipe-network-service/zksy-system/src/main/java/com/zksy/base/domain/EquipmentStatus.java
  25. 0 49
      pipe-network-service/zksy-system/src/main/java/com/zksy/base/domain/EquipmentTest.java
  26. 0 8
      pipe-network-service/zksy-system/src/main/java/com/zksy/base/domain/vo/EquipmentFullVO.java
  27. 39 0
      pipe-network-service/zksy-system/src/main/java/com/zksy/base/enums/AlarmStatusEnum.java
  28. 40 0
      pipe-network-service/zksy-system/src/main/java/com/zksy/base/enums/CurrentStatusEnum.java
  29. 39 0
      pipe-network-service/zksy-system/src/main/java/com/zksy/base/enums/OnlineStatusEnum.java
  30. 0 9
      pipe-network-service/zksy-system/src/main/java/com/zksy/base/mapper/EquipmentTestMapper.java
  31. 2 3
      pipe-network-service/zksy-system/src/main/java/com/zksy/base/service/EquipmentBaseService.java
  32. 14 0
      pipe-network-service/zksy-system/src/main/java/com/zksy/base/service/EquipmentStatusService.java
  33. 0 19
      pipe-network-service/zksy-system/src/main/java/com/zksy/base/service/GasEquipmentService.java
  34. 8 70
      pipe-network-service/zksy-system/src/main/java/com/zksy/base/service/WaterSupplyDeviceService.java
  35. 82 56
      pipe-network-service/zksy-system/src/main/java/com/zksy/base/service/impl/EquipmentBaseServiceImpl.java
  36. 95 45
      pipe-network-service/zksy-system/src/main/java/com/zksy/base/service/impl/EquipmentStatusServiceImpl.java
  37. 0 286
      pipe-network-service/zksy-system/src/main/java/com/zksy/base/service/impl/GasEquipmentServiceImpl.java
  38. 4 648
      pipe-network-service/zksy-system/src/main/java/com/zksy/base/service/impl/WaterSupplyDeviceServiceImpl.java
  39. 0 23
      pipe-network-service/zksy-system/src/main/java/com/zksy/drainage/service/DrainageEquipmentTestService.java
  40. 0 107
      pipe-network-service/zksy-system/src/main/java/com/zksy/drainage/service/impl/DrainageEquipmentTestServiceImpl.java
  41. 1 27
      pipe-network-service/zksy-system/src/main/java/com/zksy/utils/DevicePhoneFetchUtil.java
  42. 0 18
      pipe-network-service/zksy-system/src/test/java/com/zksy/WaterSupply/AbnormalWorkOrderStatusContractTest.java
  43. 1 1
      pipe-network-service/zksy-system/src/test/java/com/zksy/WaterSupply/MonitorAlarm/WaterSupplyAlarmAuditServiceTest.java
  44. 0 90
      pipe-network-service/zksy-system/src/test/java/com/zksy/WaterSupply/importing/WaterDeviceLedgerImportServiceTest.java
  45. 0 6
      pipe-network-service/zksy-system/src/test/java/com/zksy/base/service/impl/EquipmentBaseServiceImplTest.java
  46. 114 557
      pipe-network-service/zksy-system/src/test/java/com/zksy/base/service/impl/WaterSupplyDeviceServiceImplTest.java
  47. 0 14
      zk-api-service/src/main/java/com/zksy/api/domain/EquipmentStatus.java

+ 6 - 5
T6-water-device-handoff.md

@@ -26,11 +26,12 @@
   - 关联工单使用真实 `order_no`,并映射为 `relatedWorkOrderNo`、`relatedWorkOrderStatus`、`relatedWorkOrderPerson`。
   - 异常页只关联“未结案的故障维修工单”。
 - `WaterSupplyDeviceService` / `WaterSupplyDeviceServiceImplTest`
-  - 补齐供水过滤、空数据、状态分离、异常原因、关联工单、报警等级筛选等测试。
-- 控制器与导出
-  - `DeviceLedgerController`、`DeviceAbnormalController` 已支持分页、筛选、Excel 导出。
-  - 新增 `WaterDeviceLedgerExportDTO`、`WaterDeviceAbnormalExportDTO`。
-  - 对应控制器测试已添加。
+  - 仅保留 GIS 一张图所需的 4 个方法:`getDeviceTypeStatistics`、`getAllDeviceGisPoints`、`getDeviceDetail`、`getAbnormalDeviceGisPoints`。
+  - 测试收敛为仅覆盖上述 4 个 GIS 方法(类型统计、GIS 点位、详情、异常点位)。
+- 设备台账管理(已收口)
+  - 供水设备台账/异常/维保管理页面与 Controller(`DeviceLedgerController`、`DeviceAbnormalController`、`DeviceMaintainController`)已下线,统一收口至 `EquipmentBaseController`(`/equipment-base`)。
+  - 台账/异常导出 DTO(`WaterDeviceLedgerExportDTO`、`WaterDeviceAbnormalExportDTO`)与导入服务(`WaterDeviceLedgerImportService`)已随台账管理下线删除。
+  - 窨井设备关联、测点关联、状态查询及 `DeviceGisController` 所需的供水 GIS 查询方法保留。
 - 测试数据
 - 测试数据统一由 `pipe-network-service/sql/water_supply_monitoring_alarm_rebuild_test_data.sql` 重建(原 `water_supply_device_test_data.sql` 已随 #56 退役),覆盖真实供水类型 11/12/14 下的设备、正常/报警/维修/离线状态、异常原因与真实工单编号。
 

+ 6 - 32
manhole-service/src/main/java/com/zksy/manhole/domain/EquipmentStatusManhole.java → manhole-service/src/main/java/com/zksy/manhole/domain/EquipmentStatus.java

@@ -9,7 +9,6 @@ import lombok.Data;
 import lombok.NoArgsConstructor;
 
 import java.time.LocalDateTime;
-import java.util.Date;
 
 /**
  * 设备状态表
@@ -18,13 +17,10 @@ import java.util.Date;
 @AllArgsConstructor
 @NoArgsConstructor
 @TableName(value = "equipment_status", schema = "app_user")
-public class EquipmentStatusManhole {
+public class EquipmentStatus {
 
-    @TableId(value = "status_id", type = IdType.ASSIGN_UUID)
-    /**
-     * 状态记录ID(主键)
-     */
-    private String statusId;
+    @TableId(value = "status_id", type = IdType.AUTO)
+    private Integer statusId;
 
     /**
      * 设备ID(关联equipment_base表)
@@ -32,42 +28,20 @@ public class EquipmentStatusManhole {
     private String equipmentId;
 
     /**
-     * 设备当前状态:1-在用,2-闲置,3-维修,4-报废,5-待入库
+     * 设备当前(资产)状态:0-在用,1-维修,2-报废
      */
     private Integer currentStatus;
 
     /**
-     * 报警状态(0-正常,1-报警)
+     * 报警状态:0-正常,1-报警
      */
     private Integer alarmStatus;
 
     /**
-     * 在线状态(0-离线,1-在线)
+     * 在线状态:0-离线,1-在线
      */
     private Integer onlineStatus;
 
-    /**
-     * 负责人ID(可关联用户表)
-     */
-    private Long userId;
-
-    /**
-     * 安装/存放地址
-     */
-    private String installationAddr;
-
-    /**
-     * 最后一次维护日期
-     */
-    @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
-    private Date lastMaintainDate;
-
-    /**
-     * 下次预计维护日期
-     */
-    @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
-    private Date nextMaintainDate;
-
     /**
      * 状态更新时间
      */

+ 2 - 2
manhole-service/src/main/java/com/zksy/manhole/mapper/EquipmentStatusManholeMapper.java → manhole-service/src/main/java/com/zksy/manhole/mapper/EquipmentStatusMapper.java

@@ -1,9 +1,9 @@
 package com.zksy.manhole.mapper;
 
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
-import com.zksy.manhole.domain.EquipmentStatusManhole;
+import com.zksy.manhole.domain.EquipmentStatus;
 import org.apache.ibatis.annotations.Mapper;
 
 @Mapper
-public interface EquipmentStatusManholeMapper extends BaseMapper<EquipmentStatusManhole> {
+public interface EquipmentStatusMapper extends BaseMapper<EquipmentStatus> {
 }

+ 2 - 2
manhole-service/src/main/java/com/zksy/manhole/service/EquipmentStatusManholeService.java → manhole-service/src/main/java/com/zksy/manhole/service/EquipmentStatusService.java

@@ -1,9 +1,9 @@
 package com.zksy.manhole.service;
 
 import com.baomidou.mybatisplus.extension.service.IService;
-import com.zksy.manhole.domain.EquipmentStatusManhole;
+import com.zksy.manhole.domain.EquipmentStatus;
 import org.springframework.stereotype.Service;
 
 @Service
-public interface EquipmentStatusManholeService extends IService<EquipmentStatusManhole> {
+public interface EquipmentStatusService extends IService<EquipmentStatus> {
 }

+ 7 - 7
manhole-service/src/main/java/com/zksy/manhole/service/impl/BaseDevicesManholeServiceImpl.java

@@ -6,9 +6,9 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.zksy.api.event.DeviceStatusChangePublisher;
 import com.zksy.common.exception.ServiceException;
 import com.zksy.manhole.domain.BaseDevicesManhole;
-import com.zksy.manhole.domain.EquipmentStatusManhole;
+import com.zksy.manhole.domain.EquipmentStatus;
 import com.zksy.manhole.mapper.BaseDevicesManholeMapper;
-import com.zksy.manhole.mapper.EquipmentStatusManholeMapper;
+import com.zksy.manhole.mapper.EquipmentStatusMapper;
 import com.zksy.manhole.service.BaseDevicesManholeService;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
@@ -28,7 +28,7 @@ public class BaseDevicesManholeServiceImpl extends ServiceImpl<BaseDevicesManhol
     private BaseDevicesManholeMapper baseDevicesBaseDevicesMapper;
 
     @Autowired
-    private EquipmentStatusManholeMapper equipmentStatusBaseDevicesMapper;
+    private EquipmentStatusMapper equipmentStatusBaseDevicesMapper;
 
     @Autowired
     private DeviceStatusChangePublisher deviceStatusChangePublisher;
@@ -46,11 +46,11 @@ public class BaseDevicesManholeServiceImpl extends ServiceImpl<BaseDevicesManhol
         }
         //在线状态,从状态表中获取
         String deviceEquipmentId = device.getEquipmentId();
-        LambdaQueryWrapper<EquipmentStatusManhole> queryWrapper = new LambdaQueryWrapper<>();
-        queryWrapper.eq(EquipmentStatusManhole::getEquipmentId,deviceEquipmentId);
-        queryWrapper.eq(EquipmentStatusManhole::getOnlineStatus,queryStatus);
+        LambdaQueryWrapper<EquipmentStatus> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.eq(EquipmentStatus::getEquipmentId,deviceEquipmentId);
+        queryWrapper.eq(EquipmentStatus::getOnlineStatus,queryStatus);
 
-        EquipmentStatusManhole equipmentStatus = equipmentStatusBaseDevicesMapper.selectOne(queryWrapper);
+        EquipmentStatus equipmentStatus = equipmentStatusBaseDevicesMapper.selectOne(queryWrapper);
 
         //修改状态表
         if(equipmentStatus != null){

+ 0 - 12
manhole-service/src/main/java/com/zksy/manhole/service/impl/EquipmentStatusManholeServiceImpl.java

@@ -1,12 +0,0 @@
-package com.zksy.manhole.service.impl;
-
-import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
-import com.zksy.manhole.domain.EquipmentStatusManhole;
-import com.zksy.manhole.mapper.EquipmentStatusManholeMapper;
-import com.zksy.manhole.service.EquipmentStatusManholeService;
-import org.springframework.stereotype.Service;
-
-@Service
-public class EquipmentStatusManholeServiceImpl extends ServiceImpl<EquipmentStatusManholeMapper, EquipmentStatusManhole>
-        implements EquipmentStatusManholeService {
-}

+ 12 - 0
manhole-service/src/main/java/com/zksy/manhole/service/impl/EquipmentStatusServiceImpl.java

@@ -0,0 +1,12 @@
+package com.zksy.manhole.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.zksy.manhole.domain.EquipmentStatus;
+import com.zksy.manhole.mapper.EquipmentStatusMapper;
+import com.zksy.manhole.service.EquipmentStatusService;
+import org.springframework.stereotype.Service;
+
+@Service
+public class EquipmentStatusServiceImpl extends ServiceImpl<EquipmentStatusMapper, EquipmentStatus>
+        implements EquipmentStatusService {
+}

+ 8 - 13
pipe-network-service/sql/iot_equipment_management.sql

@@ -24,6 +24,13 @@ ADD COLUMN IF NOT EXISTS `create_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMEN
 ALTER TABLE `equipment_status` 
 ADD COLUMN IF NOT EXISTS `create_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间' AFTER `status_update_time`;
 
+-- 移除已停用的设备状态冗余字段(负责人/安装地址/维护日期)
+ALTER TABLE `equipment_status` 
+DROP COLUMN IF EXISTS `user_id`,
+DROP COLUMN IF EXISTS `installation_addr`,
+DROP COLUMN IF EXISTS `last_maintain_date`,
+DROP COLUMN IF EXISTS `next_maintain_date`;
+
 -- -----------------------------------------------------
 -- 2. 管网基础信息表(5.2.4.1.2)
 -- -----------------------------------------------------
@@ -117,21 +124,9 @@ ADD COLUMN IF NOT EXISTS `max_value` DECIMAL(10, 2) COMMENT '预警最大值,
 -- ALTER TABLE `warning_threshold` DROP COLUMN IF EXISTS `warning_level`;
 
 -- -----------------------------------------------------
--- 6. 设备测试记录表
+-- 6. 设备测试记录表(已废弃,删除表)
 -- -----------------------------------------------------
 DROP TABLE IF EXISTS `equipment_test`;
-CREATE TABLE `equipment_test` (
-  `test_id` VARCHAR(64) NOT NULL COMMENT '测试记录ID',
-  `equipment_id` VARCHAR(64) NOT NULL COMMENT '设备ID',
-  `test_type` VARCHAR(64) COMMENT '测试类型(CONNECT-连接测试 DATA-数据传输 FUNCTION-功能测试)',
-  `test_result` VARCHAR(32) COMMENT '测试结果(SUCCESS-成功 FAIL-失败)',
-  `test_detail` TEXT COMMENT '测试详情',
-  `test_time` DATETIME COMMENT '测试时间',
-  `test_user` VARCHAR(128) COMMENT '测试人',
-  `create_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
-  PRIMARY KEY (`test_id`),
-  KEY `idx_equipment_id` (`equipment_id`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='设备测试记录表';
 
 -- -----------------------------------------------------
 -- 7. 初始化数据

+ 0 - 1
pipe-network-service/sql/water_supply_monitoring_alarm_rebuild_test_data.sql

@@ -125,7 +125,6 @@ DELETE FROM app_user.noise_info            WHERE encode                IN (SELEC
 DELETE FROM app_user.equipment_status      WHERE equipment_id          IN (SELECT equipment_id FROM wsr_deleted_devices);
 DELETE FROM app_user.equipment_maintain    WHERE equipment_id          IN (SELECT equipment_id FROM wsr_deleted_devices);
 DELETE FROM app_user.equipment_point_rel   WHERE equipment_id          IN (SELECT equipment_id FROM wsr_deleted_devices);
-DELETE FROM app_user.equipment_test        WHERE equipment_id          IN (SELECT equipment_id FROM wsr_deleted_devices);
 DELETE FROM app_user.equipment_base        WHERE equipment_id          IN (SELECT equipment_id FROM wsr_deleted_devices);
 
 -- ------------------------------------------------------------

+ 0 - 130
pipe-network-service/zksy-admin/src/main/java/com/zksy/web/controller/WaterSupply/DeviceAbnormal/DeviceAbnormalController.java

@@ -1,130 +0,0 @@
-package com.zksy.web.controller.WaterSupply.DeviceAbnormal;
-
-import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
-import com.zksy.base.domain.vo.AbnormalDeviceVO;
-import com.zksy.base.domain.vo.MaintainOrderVO;
-import com.zksy.ops.domain.WorkOrder;
-import com.zksy.ops.domain.vo.WorkOrderVO;
-import com.zksy.base.service.WaterSupplyDeviceService;
-import com.zksy.ops.service.WorkOrderService;
-import com.zksy.WaterSupply.export.WaterDeviceAbnormalExportDTO;
-import com.zksy.common.annotation.Log;
-import com.zksy.common.core.domain.AjaxResult;
-import com.zksy.common.enums.BusinessType;
-import com.zksy.common.utils.poi.ExcelUtil;
-import com.zksy.common.exception.ServiceException;
-import com.zksy.ops.enums.WorkOrderStatusEnum;
-import com.zksy.ops.dto.WorkOrderDispatchDTO;
-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 javax.servlet.http.HttpServletResponse;
-import java.util.List;
-import java.util.stream.Collectors;
-
-@Slf4j
-@RestController
-@RequestMapping("/waterSupply/device/abnormal")
-@Api(tags = "供水设备-异常管理")
-public class DeviceAbnormalController {
-
-    @Autowired
-    private WaterSupplyDeviceService waterSupplyDeviceService;
-
-    @Autowired
-    private WorkOrderService businessWorkOrderService;
-
-    @GetMapping("/page")
-    @ApiOperation("异常设备分页查询")
-    @PreAuthorize("@ss.hasPermi('waterSupply:device:abnormal:list')")
-    public AjaxResult getAbnormalDevicePage(
-            @ApiParam("页码") @RequestParam(defaultValue = "1") long pageNum,
-            @ApiParam("每页数量") @RequestParam(defaultValue = "10") long pageSize,
-            @ApiParam("设备名称") @RequestParam(required = false) String equipmentName,
-            @ApiParam("设备编码") @RequestParam(required = false) String equipmentCode,
-            @ApiParam("设备类型ID") @RequestParam(required = false) String equipmentTypeId,
-            @ApiParam("告警等级 1-4") @RequestParam(required = false) Integer alertLevel,
-            @ApiParam("异常类型 alarm-报警 repair-维修 offline-离线") @RequestParam(required = false) String abnormalType,
-            @ApiParam("区域") @RequestParam(required = false) String region,
-            @ApiParam("仅返回没有未结束故障维修工单的可派单设备")
-            @RequestParam(required = false, defaultValue = "false") Boolean dispatchableOnly) {
-        Page<AbnormalDeviceVO> page = waterSupplyDeviceService.getAbnormalDevicePage(
-                pageNum, pageSize, equipmentName, equipmentCode, equipmentTypeId, alertLevel,
-                abnormalType, region, dispatchableOnly);
-        return AjaxResult.success(page);
-    }
-
-    @GetMapping("/stats")
-    @ApiOperation("供水设备异常统计")
-    @PreAuthorize("@ss.hasPermi('waterSupply:device:abnormal:list')")
-    public AjaxResult getAbnormalDeviceStats() {
-        return AjaxResult.success(waterSupplyDeviceService.getAbnormalDeviceStats());
-    }
-
-    @GetMapping("/gisPoints")
-    @ApiOperation("获取异常设备GIS点位(地图高亮用)")
-    @PreAuthorize("@ss.hasPermi('waterSupply:device:abnormal:list')")
-    public AjaxResult getAbnormalGisPoints(
-            @ApiParam("设备类型ID") @RequestParam(required = false) String equipmentTypeId) {
-        List<AbnormalDeviceVO> list = waterSupplyDeviceService.getAbnormalDeviceGisPoints(equipmentTypeId);
-        return AjaxResult.success(list);
-    }
-
-    @PostMapping("/order")
-    @ApiOperation("供水异常设备创建故障维修工单")
-    @Log(title = "供水异常设备派单", businessType = BusinessType.INSERT)
-    @PreAuthorize("@ss.hasPermi('waterSupply:device:maintain')")
-    public AjaxResult createAbnormalOrder(@RequestBody MaintainOrderVO vo) {
-        try {
-            Long receiveUserId = vo == null ? null : vo.getReceiveUserId();
-            WorkOrder order = waterSupplyDeviceService.createAbnormalWorkOrder(vo);
-            if (order == null || order.getOrderId() == null) {
-                return AjaxResult.error("派单失败:工单创建未返回有效工单ID");
-            }
-            if (receiveUserId == null) {
-                order.setOrderStatus(WorkOrderStatusEnum.PENDING_DISPATCH.getCode());
-                return AjaxResult.success("工单创建成功,待派单", WorkOrderVO.from(order));
-            }
-            WorkOrderDispatchDTO dispatchDTO = new WorkOrderDispatchDTO();
-            dispatchDTO.setHandlerId(receiveUserId);
-            dispatchDTO.setRemarks(vo.getMaintainRemark());
-            boolean dispatched = businessWorkOrderService.dispatch(order.getOrderId(), dispatchDTO);
-            if (!dispatched) {
-                return AjaxResult.error("派单失败:工单仍为待派单状态,请稍后重试");
-            }
-            order.setReceiveUser(receiveUserId);
-            order.setOrderStatus(WorkOrderStatusEnum.PENDING_ACCEPT.getCode());
-            return AjaxResult.success("派单成功", WorkOrderVO.from(order));
-        } catch (ServiceException e) {
-            log.warn("供水异常设备派单业务失败: {}", e.getMessage());
-            return AjaxResult.error("派单失败:" + e.getMessage());
-        } catch (Exception e) {
-            log.error("供水异常设备派单系统异常", e);
-            return AjaxResult.error("派单失败:服务暂不可用");
-        }
-    }
-
-    @PostMapping("/export")
-    @ApiOperation("导出异常设备台账")
-    @Log(title = "导出异常设备", businessType = BusinessType.EXPORT)
-    @PreAuthorize("@ss.hasPermi('waterSupply:device:abnormal:export')")
-    public void exportAbnormalDevices(HttpServletResponse response,
-            @ApiParam("设备名称") @RequestParam(required = false) String equipmentName,
-            @ApiParam("设备编码") @RequestParam(required = false) String equipmentCode,
-            @ApiParam("设备类型ID") @RequestParam(required = false) String equipmentTypeId,
-            @ApiParam("告警等级") @RequestParam(required = false) Integer alertLevel,
-            @ApiParam("异常类型 alarm-报警 repair-维修 offline-离线") @RequestParam(required = false) String abnormalType,
-            @ApiParam("区域") @RequestParam(required = false) String region) {
-        List<WaterDeviceAbnormalExportDTO> rows = waterSupplyDeviceService.getAbnormalDeviceExport(
-                        equipmentName, equipmentCode, equipmentTypeId, alertLevel, abnormalType, region)
-                .stream()
-                .map(WaterDeviceAbnormalExportDTO::from)
-                .collect(Collectors.toList());
-        new ExcelUtil<>(WaterDeviceAbnormalExportDTO.class).exportExcel(response, rows, "供水异常设备台账");
-    }
-}

+ 0 - 128
pipe-network-service/zksy-admin/src/main/java/com/zksy/web/controller/WaterSupply/DeviceLedger/DeviceLedgerController.java

@@ -1,128 +0,0 @@
-package com.zksy.web.controller.WaterSupply.DeviceLedger;
-
-import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
-import com.zksy.base.domain.vo.DeviceGisVO;
-import com.zksy.base.domain.vo.DeviceTypeStatisticsVO;
-import com.zksy.base.service.WaterSupplyDeviceService;
-import com.zksy.WaterSupply.export.WaterDeviceLedgerExportDTO;
-import com.zksy.WaterSupply.importing.WaterDeviceLedgerImportDTO;
-import com.zksy.WaterSupply.importing.WaterDeviceLedgerImportService;
-import com.zksy.base.domain.EquipmentBase;
-import com.zksy.common.annotation.Log;
-import com.zksy.common.core.domain.AjaxResult;
-import com.zksy.common.enums.BusinessType;
-import com.zksy.common.utils.poi.ExcelUtil;
-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 org.springframework.web.multipart.MultipartFile;
-
-import javax.servlet.http.HttpServletResponse;
-import java.util.List;
-import java.util.stream.Collectors;
-
-@Slf4j
-@RestController
-@RequestMapping("/waterSupply/device/ledger")
-@Api(tags = "供水设备-设备台账管理")
-public class DeviceLedgerController {
-
-    @Autowired
-    private WaterSupplyDeviceService waterSupplyDeviceService;
-
-    @Autowired
-    private WaterDeviceLedgerImportService waterDeviceLedgerImportService;
-
-    @GetMapping("/typeStatistics")
-    @ApiOperation("设备分类统计(树形结构)")
-    @PreAuthorize("@ss.hasPermi('waterSupply:device:list')")
-    public AjaxResult getTypeStatistics() {
-        List<DeviceTypeStatisticsVO> list = waterSupplyDeviceService.getDeviceTypeStatistics();
-        return AjaxResult.success(list);
-    }
-
-    @GetMapping("/statistics")
-    @ApiOperation("设备台账运行状态统计")
-    @PreAuthorize("@ss.hasPermi('waterSupply:device:list')")
-    public AjaxResult getLedgerStatistics() {
-        return AjaxResult.success(waterSupplyDeviceService.getDeviceLedgerStatistics());
-    }
-
-    @GetMapping("/page")
-    @ApiOperation("设备台账分页查询")
-    @PreAuthorize("@ss.hasPermi('waterSupply:device:list')")
-    public AjaxResult getDevicePage(
-            @ApiParam("页码") @RequestParam(defaultValue = "1") long pageNum,
-            @ApiParam("每页数量") @RequestParam(defaultValue = "10") long pageSize,
-            @ApiParam("设备名称") @RequestParam(required = false) String equipmentName,
-            @ApiParam("设备编码") @RequestParam(required = false) String equipmentCode,
-            @ApiParam("设备类型ID") @RequestParam(required = false) String equipmentTypeId,
-            @ApiParam("设备状态") @RequestParam(required = false) Integer status,
-            @ApiParam("报警状态") @RequestParam(required = false) Integer alarmStatus,
-            @ApiParam("报警等级") @RequestParam(required = false) Integer alertLevel) {
-        Page<DeviceGisVO> page = waterSupplyDeviceService.getDeviceLedgerPage(
-                pageNum, pageSize, equipmentName, equipmentCode, equipmentTypeId,
-                status, alarmStatus, alertLevel);
-        return AjaxResult.success(page);
-    }
-
-    @GetMapping("/gisPoints")
-    @ApiOperation("获取所有设备GIS点位")
-    @PreAuthorize("@ss.hasPermi('waterSupply:device:list')")
-    public AjaxResult getGisPoints(
-            @ApiParam("设备类型ID") @RequestParam(required = false) String equipmentTypeId) {
-        List<DeviceGisVO> list = waterSupplyDeviceService.getAllDeviceGisPoints(equipmentTypeId);
-        return AjaxResult.success(list);
-    }
-
-    @PostMapping("/export")
-    @ApiOperation("批量导出设备台账")
-    @Log(title = "导出设备台账", businessType = BusinessType.EXPORT)
-    @PreAuthorize("@ss.hasPermi('waterSupply:device:export')")
-    public void exportDeviceLedger(HttpServletResponse response,
-            @ApiParam("设备名称") @RequestParam(required = false) String equipmentName,
-            @ApiParam("设备编码") @RequestParam(required = false) String equipmentCode,
-            @ApiParam("设备类型ID") @RequestParam(required = false) String equipmentTypeId,
-            @ApiParam("设备状态") @RequestParam(required = false) Integer status,
-            @ApiParam("报警状态") @RequestParam(required = false) Integer alarmStatus,
-            @ApiParam("报警等级") @RequestParam(required = false) Integer alertLevel) {
-        List<WaterDeviceLedgerExportDTO> rows = waterSupplyDeviceService.getDeviceLedgerExport(
-                        equipmentName, equipmentCode, equipmentTypeId, status, alarmStatus, alertLevel)
-                .stream()
-                .map(WaterDeviceLedgerExportDTO::from)
-                .collect(Collectors.toList());
-        new ExcelUtil<>(WaterDeviceLedgerExportDTO.class).exportExcel(response, rows, "供水设备台账");
-    }
-
-    @PostMapping("/import")
-    @ApiOperation("批量导入设备台账")
-    @Log(title = "导入设备台账", businessType = BusinessType.IMPORT)
-    @PreAuthorize("@ss.hasPermi('waterSupply:device:list')")
-    public AjaxResult importDeviceLedger(
-            @ApiParam("Excel 文件") @RequestParam("file") MultipartFile file,
-            @ApiParam("是否更新已存在设备") @RequestParam(defaultValue = "false") boolean updateSupport) throws Exception {
-        List<WaterDeviceLedgerImportDTO> rows = new ExcelUtil<>(WaterDeviceLedgerImportDTO.class)
-                .importExcel(file.getInputStream());
-        return AjaxResult.success(waterDeviceLedgerImportService.importDevices(rows, updateSupport));
-    }
-
-    @PostMapping("/create")
-    @ApiOperation("新增供水设备")
-    @Log(title = "新增供水设备", businessType = BusinessType.INSERT)
-    @PreAuthorize("@ss.hasPermi('waterSupply:device:list')")
-    public AjaxResult createDevice(@RequestBody EquipmentBase device) {
-        return AjaxResult.success("新增成功", waterSupplyDeviceService.createWaterDevice(device));
-    }
-
-    @DeleteMapping("/delete")
-    @ApiOperation("删除供水设备")
-    @Log(title = "删除供水设备", businessType = BusinessType.DELETE)
-    @PreAuthorize("@ss.hasPermi('waterSupply:device:list')")
-    public AjaxResult deleteDevices(@RequestParam List<String> equipmentIds) {
-        return AjaxResult.success("删除成功", waterSupplyDeviceService.deleteWaterDevices(equipmentIds));
-    }
-}

+ 0 - 167
pipe-network-service/zksy-admin/src/main/java/com/zksy/web/controller/WaterSupply/DeviceMaintain/DeviceMaintainController.java

@@ -1,167 +0,0 @@
-package com.zksy.web.controller.WaterSupply.DeviceMaintain;
-
-import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
-import com.zksy.base.domain.vo.EquipmentMaintainDataVO;
-import com.zksy.base.domain.vo.MaintainOrderVO;
-import com.zksy.ops.domain.WorkOrder;
-import com.zksy.ops.domain.vo.WorkOrderVO;
-import com.zksy.ops.service.WorkOrderService;
-import com.zksy.base.service.WaterSupplyDeviceService;
-import com.zksy.common.annotation.Log;
-import com.zksy.common.core.domain.AjaxResult;
-import com.zksy.common.enums.BusinessType;
-import com.zksy.common.utils.SecurityUtils;
-import com.zksy.common.exception.ServiceException;
-import com.zksy.ops.enums.WorkOrderStatusEnum;
-import com.zksy.ops.dto.WorkOrderDispatchDTO;
-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;
-import java.util.Map;
-
-@Slf4j
-@RestController
-@RequestMapping("/waterSupply/device/maintain")
-@Api(tags = "供水设备-维修派单管理")
-public class DeviceMaintainController {
-
-    @Autowired
-    private WaterSupplyDeviceService waterSupplyDeviceService;
-
-    @Autowired
-    private WorkOrderService businessWorkOrderService;
-
-    @PostMapping("/order")
-    @ApiOperation("创建维修派单")
-    @Log(title = "设备维修派单", businessType = BusinessType.INSERT)
-    @PreAuthorize("@ss.hasPermi('waterSupply:device:maintain')")
-    public AjaxResult createMaintainOrder(@RequestBody MaintainOrderVO vo) {
-        try {
-            Long receiveUserId = vo == null ? null : vo.getReceiveUserId();
-            WorkOrder order = waterSupplyDeviceService.createAbnormalWorkOrder(vo);
-            if (order == null || order.getOrderId() == null) {
-                return AjaxResult.error("派单失败:工单创建未返回有效工单ID");
-            }
-            if (receiveUserId == null) {
-                order.setOrderStatus(WorkOrderStatusEnum.PENDING_DISPATCH.getCode());
-                return AjaxResult.success("工单创建成功,待派单", WorkOrderVO.from(order));
-            }
-            WorkOrderDispatchDTO dispatchDTO = new WorkOrderDispatchDTO();
-            dispatchDTO.setHandlerId(receiveUserId);
-            dispatchDTO.setRemarks(vo.getMaintainRemark());
-            boolean dispatched = businessWorkOrderService.dispatch(order.getOrderId(), dispatchDTO);
-            if (!dispatched) {
-                return AjaxResult.error("派单失败:工单仍为待派单状态,请稍后重试");
-            }
-            order.setReceiveUser(receiveUserId);
-            order.setOrderStatus(WorkOrderStatusEnum.PENDING_ACCEPT.getCode());
-            return AjaxResult.success("派单成功", WorkOrderVO.from(order));
-        } catch (ServiceException e) {
-            log.warn("创建维修派单业务失败: {}", e.getMessage());
-            return AjaxResult.error("派单失败:" + e.getMessage());
-        } catch (Exception e) {
-            log.error("创建维修派单系统异常", e);
-            return AjaxResult.error("派单失败:服务暂不可用");
-        }
-    }
-
-    @GetMapping("/record/page")
-    @ApiOperation("维修记录分页查询")
-    @PreAuthorize("@ss.hasPermi('waterSupply:device:maintain:list')")
-    public AjaxResult getMaintainRecordPage(
-            @ApiParam("页码") @RequestParam(defaultValue = "1") long pageNum,
-            @ApiParam("每页数量") @RequestParam(defaultValue = "10") long pageSize,
-            @ApiParam("设备名称") @RequestParam(required = false) String equipmentName,
-            @ApiParam("维修人员") @RequestParam(required = false) String maintainPerson,
-            @ApiParam("维修类型") @RequestParam(required = false) String maintainType,
-            @ApiParam("工单状态") @RequestParam(required = false) String status,
-            @ApiParam("开始时间") @RequestParam(required = false) String startTime,
-            @ApiParam("结束时间") @RequestParam(required = false) String endTime) {
-        Page<EquipmentMaintainDataVO> page = waterSupplyDeviceService.getMaintainRecordPage(
-                pageNum, pageSize, equipmentName, maintainPerson, maintainType, status, startTime, endTime);
-        return AjaxResult.success(page);
-    }
-
-    @GetMapping("/record/myPage")
-    @ApiOperation("我的维修单(根据当前登录人查询)")
-    @PreAuthorize("@ss.hasPermi('waterSupply:device:maintain:list')")
-    public AjaxResult getMyMaintainRecordPage(
-            @ApiParam("页码") @RequestParam(defaultValue = "1") long pageNum,
-            @ApiParam("每页数量") @RequestParam(defaultValue = "10") long pageSize,
-            @ApiParam("维修类型") @RequestParam(required = false) String maintainType,
-            @ApiParam("工单状态") @RequestParam(required = false) String status,
-            @ApiParam("开始时间") @RequestParam(required = false) String startTime,
-            @ApiParam("结束时间") @RequestParam(required = false) String endTime) {
-        String username = SecurityUtils.getUsername();
-        Page<EquipmentMaintainDataVO> page = waterSupplyDeviceService.getMyMaintainRecordPage(
-                pageNum, pageSize, username, maintainType, status, startTime, endTime);
-        return AjaxResult.success(page);
-    }
-
-    @GetMapping("/record/list/{equipmentId}")
-    @ApiOperation("查询设备维修记录列表")
-    @PreAuthorize("@ss.hasPermi('waterSupply:device:maintain:list')")
-    public AjaxResult getMaintainRecordList(@PathVariable String equipmentId) {
-        List<Map<String, Object>> list = waterSupplyDeviceService.getMaintainRecordList(equipmentId);
-        return AjaxResult.success(list);
-    }
-
-    @PostMapping("/record")
-    @ApiOperation("新增维修记录(历史补录)")
-    @Log(title = "新增维修记录", businessType = BusinessType.INSERT)
-    @PreAuthorize("@ss.hasPermi('waterSupply:device:maintain:add')")
-    public AjaxResult saveMaintainRecord(@RequestBody EquipmentMaintainDataVO vo) {
-        try {
-            boolean result = waterSupplyDeviceService.saveMaintainRecord(vo);
-            return result ? AjaxResult.success("新增成功") : AjaxResult.error("新增失败");
-        } catch (Exception e) {
-            log.error("新增维修记录失败", e);
-            return AjaxResult.error("新增失败:" + e.getMessage());
-        }
-    }
-
-    @PutMapping("/record")
-    @ApiOperation("修改维修记录")
-    @Log(title = "修改维修记录", businessType = BusinessType.UPDATE)
-    @PreAuthorize("@ss.hasPermi('waterSupply:device:maintain:edit')")
-    public AjaxResult updateMaintainRecord(@RequestBody EquipmentMaintainDataVO vo) {
-        try {
-            boolean result = waterSupplyDeviceService.updateMaintainRecord(vo);
-            return result ? AjaxResult.success("修改成功") : AjaxResult.error("修改失败");
-        } catch (Exception e) {
-            log.error("修改维修记录失败", e);
-            return AjaxResult.error("修改失败:" + e.getMessage());
-        }
-    }
-
-    @DeleteMapping("/record/{maintainId}")
-    @ApiOperation("删除维修记录")
-    @Log(title = "删除维修记录", businessType = BusinessType.DELETE)
-    @PreAuthorize("@ss.hasPermi('waterSupply:device:maintain:remove')")
-    public AjaxResult deleteMaintainRecord(@PathVariable String maintainId) {
-        boolean result = waterSupplyDeviceService.deleteMaintainRecord(maintainId);
-        return result ? AjaxResult.success("删除成功") : AjaxResult.error("删除失败");
-    }
-
-    @PostMapping("/record/import")
-    @ApiOperation("批量导入维修记录")
-    @Log(title = "批量导入维修记录", businessType = BusinessType.IMPORT)
-    @PreAuthorize("@ss.hasPermi('waterSupply:device:maintain:import')")
-    public AjaxResult importMaintainRecords() {
-        return AjaxResult.success("导入功能待对接EasyExcel");
-    }
-
-    @PostMapping("/record/export")
-    @ApiOperation("批量导出维修记录")
-    @Log(title = "导出维修记录", businessType = BusinessType.EXPORT)
-    @PreAuthorize("@ss.hasPermi('waterSupply:device:maintain:export')")
-    public AjaxResult exportMaintainRecords() {
-        return AjaxResult.success("导出功能待对接EasyExcel");
-    }
-}

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

@@ -21,43 +21,47 @@ import java.util.Map;
 
 @Slf4j
 @RestController
-@RequestMapping("/EquipmentBase")
-@Api(tags = "设备基础信息-物联网感知设备")
+@RequestMapping("/equipment-base")
+@Api(tags = "物联感知设备-设备管理")
 public class EquipmentBaseController {
 
     @Autowired
     private EquipmentBaseService service;
 
-    @GetMapping("/getById/{id}")
-    @ApiOperation(value = "设备基础信息搜索getById")
-    @Anonymous
-    public AjaxResult getById(@PathVariable String id) {
-        EquipmentBase equipmentBase = service.getById(id);
-        if (equipmentBase == null) {
-            return AjaxResult.error("该设备信息不存在");
-        }
-        return AjaxResult.success(equipmentBase);
-    }
-
-    @Anonymous
-    @GetMapping("/findByPage")
+    @GetMapping
     @ApiOperation(value = "设备基础信息分页")
+    @Anonymous
     public Page findByPage(long pageNum, long pageSize,
                            @RequestParam(required = false) String equipmentCode,
                            @RequestParam(required = false) String equipmentName,
-                           @RequestParam(required = false) String equipmentModel,
-                           @RequestParam(required = false) String manufacturer) throws Exception {
-        return service.findByPage(pageNum, pageSize, equipmentCode, equipmentName, equipmentModel, manufacturer);
+                           @ApiParam("设备类型ID") @RequestParam(required = false) String equipmentTypeId,
+                           @ApiParam("设备根类型ID(菜单 rootTypeId 数据范围过滤,空=全部)")
+                           @RequestParam(required = false) Integer rootTypeId,
+                           @ApiParam("在线状态(0-离线,1-在线)") @RequestParam(required = false) Integer onlineStatus,
+                           @ApiParam("报警状态(1-报警,仅勾选报警时传)") @RequestParam(required = false) Integer alarmStatus) throws Exception {
+        return service.findByPage(pageNum, pageSize, equipmentCode, equipmentName, equipmentTypeId,
+                rootTypeId, onlineStatus, alarmStatus);
     }
 
-    @Anonymous
-    @GetMapping("/getList")
+    @GetMapping("/all")
     @ApiOperation(value = "查询所有设备基础信息")
-    public AjaxResult getList() throws Exception {
+    @Anonymous
+    public AjaxResult getAll() throws Exception {
         return AjaxResult.success(service.list());
     }
 
-    @PostMapping("/save")
+    @GetMapping("/{id}")
+    @ApiOperation(value = "设备基础信息查询")
+    @Anonymous
+    public AjaxResult getById(@PathVariable String id) {
+        EquipmentBase equipmentBase = service.getById(id);
+        if (equipmentBase == null) {
+            return AjaxResult.error("该设备信息不存在");
+        }
+        return AjaxResult.success(equipmentBase);
+    }
+
+    @PostMapping
     @ApiOperation(value = "新增设备基础信息")
     @Log(title = "新增设备基础信息", businessType = BusinessType.INSERT)
     public AjaxResult save(@RequestBody EquipmentBase entity) {
@@ -66,80 +70,57 @@ public class EquipmentBaseController {
                 : AjaxResult.error("新增失败", saved);
     }
 
-    @PostMapping("/saveBatch")
-    @ApiOperation(value = "设备基础信息批量新增")
-    @Log(title = "批量新增设备基础信息", businessType = BusinessType.INSERT)
-    public AjaxResult saveBatch(@RequestBody List<EquipmentBase> entityList) {
-        if (CollectionUtils.isEmpty(entityList)) {
-            return AjaxResult.error("批量新增失败:设备列表不能为空");
-        }
-        boolean saved = service.saveBatchWithCheck(entityList);
-        return saved ? AjaxResult.success("新增成功", saved)
-                : AjaxResult.error("新增失败", saved);
-    }
-
-    @PutMapping("/updateById")
+    @PutMapping("/{id}")
     @ApiOperation(value = "设备基础信息修改")
     @Log(title = "修改设备基础信息", businessType = BusinessType.UPDATE)
-    public AjaxResult updateById(@RequestBody EquipmentBase entity) {
+    public AjaxResult updateById(@PathVariable String id, @RequestBody EquipmentBase entity) {
+        if (entity.getEquipmentId() == null) {
+            entity.setEquipmentId(id);
+        }
         boolean updated = service.updateWithCheck(entity);
         return updated ? AjaxResult.success("修改成功", updated)
                 : AjaxResult.error("修改失败", updated);
     }
 
-    @DeleteMapping("/deleteById")
+    @DeleteMapping("/{id}")
     @ApiOperation(value = "设备基础信息删除")
     @Log(title = "删除设备基础信息", businessType = BusinessType.DELETE)
-    public AjaxResult deleteById(String id) {
+    public AjaxResult deleteById(@PathVariable String id) {
         boolean deleted = service.removeWithCheck(id);
         return deleted ? AjaxResult.success("删除成功", deleted)
                 : AjaxResult.error("删除失败", deleted);
     }
 
-    @DeleteMapping("/deleteBatchById")
+    @DeleteMapping("/batch")
     @ApiOperation(value = "设备基础信息批量删除")
-    @Log(title = "设备基础信息批量删除", businessType = BusinessType.DELETE)
+    @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);
     }
 
-    @PutMapping("/updateStatus")
-    @ApiOperation(value = "设备状态维护(启用/禁用/维修等)")
+    @PutMapping("/{id}/status")
+    @ApiOperation(value = "设备状态维护(在用/维修/报废)")
     @Log(title = "设备状态维护", businessType = BusinessType.UPDATE)
     @Anonymous
     public AjaxResult updateEquipmentStatus(
-            @ApiParam("设备ID") @RequestParam String equipmentId,
+            @ApiParam("设备ID") @PathVariable String id,
             @ApiParam("状态值") @RequestParam Integer currentStatus) {
-        boolean updated = service.updateEquipmentStatus(equipmentId, currentStatus);
+        boolean updated = service.updateEquipmentStatus(id, currentStatus);
         return updated ? AjaxResult.success("状态更新成功")
                 : AjaxResult.error("状态更新失败");
     }
 
-    @PostMapping("/test")
-    @ApiOperation(value = "设备测试验证")
-    @Log(title = "设备测试验证", businessType = BusinessType.OTHER)
-    @Anonymous
-    public AjaxResult testEquipment(
-            @ApiParam("设备ID") @RequestParam String equipmentId,
-            @ApiParam("测试类型") @RequestParam(required = false) String testType,
-            @ApiParam("测试详情") @RequestParam(required = false) String testDetail,
-            @ApiParam("测试人") @RequestParam(required = false) String testUser) {
-        boolean tested = service.testEquipment(equipmentId, testType, testDetail, testUser);
-        return tested ? AjaxResult.success("测试成功")
-                : AjaxResult.error("测试失败");
-    }
-
-    @GetMapping("/detail/{equipmentId}")
+    @GetMapping("/{id}/detail")
     @ApiOperation(value = "设备详情(含关联信息)")
     @Anonymous
-    public AjaxResult getEquipmentDetail(@PathVariable String equipmentId) {
-        Map<String, Object> detail = service.getEquipmentDetail(equipmentId);
+    public AjaxResult getEquipmentDetail(@PathVariable String id) {
+        Map<String, Object> detail = service.getEquipmentDetail(id);
         return AjaxResult.success(detail);
     }
 
-    @GetMapping("/byPoint/{pointId}")
+    @GetMapping("/point/{pointId}")
     @ApiOperation(value = "根据监测点查询设备")
     @Anonymous
     public AjaxResult getEquipmentByPoint(@PathVariable String pointId) {
@@ -147,9 +128,9 @@ public class EquipmentBaseController {
         return AjaxResult.success(list);
     }
 
-    @Anonymous
-    @GetMapping("/findByTopLevelType")
+    @GetMapping("/top-level-type")
     @ApiOperation(value = "按顶级设备类型(燃气/排水/供水)查询设备列表")
+    @Anonymous
     public AjaxResult findByTopLevelType(
             @ApiParam("顶级类型名称,如:燃气、排水、供水") @RequestParam String typeName) {
         List<EquipmentBase> list = service.findByTopLevelType(typeName);

+ 19 - 86
pipe-network-service/zksy-admin/src/main/java/com/zksy/web/controller/base/EquipmentStatusController.java

@@ -1,111 +1,44 @@
 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.EquipmentStatus;
 import com.zksy.base.service.EquipmentStatusService;
 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 io.swagger.annotations.ApiParam;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.web.bind.annotation.*;
-
-import java.util.List;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+import java.util.Map;
 
 /**
  * 设备状态
  */
-@Slf4j
 @RestController
-@RequestMapping("/EquipmentStatus")
-@Api(tags = "设备状态")
+@RequestMapping("/equipment-status")
+@Api(tags = "物联感知设备-设备状态")
 public class EquipmentStatusController {
 
     @Autowired
     private EquipmentStatusService service;
 
-    @GetMapping("/getById/{id}")
-    @ApiOperation(value = "设备状态搜索getById")
-    @Anonymous
-    public AjaxResult getById(@PathVariable String id) {
-        EquipmentStatus equipmentStatus = service.getById(id);
-        if(equipmentStatus==null){
-            return AjaxResult.error("该设备状态不存在");
-        }
-        return AjaxResult.success(equipmentStatus);
-    }
-
-    @GetMapping("/findByPage")
-    @ApiOperation(value = "设备状态分页")
-    @Anonymous
-    public Page findByPage(long pageNum, long pageSize,
-                           @RequestParam(required = false) String statusId,
-                           @RequestParam(required = false) String equipmentId,
-                           @RequestParam(required = false) Integer currentStatus,
-                           @RequestParam(required = false) Integer alarmStatus,
-                           @RequestParam(required = false) Integer onlineStatus,
-                           @RequestParam(required = false) Long userId) throws Exception {
-        return service.findByPage(pageNum, pageSize, statusId,equipmentId,currentStatus,alarmStatus,onlineStatus,userId);
-    }
-
-    @GetMapping("/getList")
+    @GetMapping("/all")
     @ApiOperation(value = "查询所有设备状态")
     @Anonymous
-    public AjaxResult getList() throws Exception {
-        return AjaxResult.success(service.list());
-    }
-
-    @PostMapping("/save")
-    @ApiOperation(value = "新增设备状态")
-    @Log(title = "新增设备状态", businessType = BusinessType.INSERT)
-    public AjaxResult save(@RequestBody EquipmentStatus 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<EquipmentStatus> entityList) {
-        // 基础校验:列表不能为空
-        if (CollectionUtils.isEmpty(entityList)) {
-            return AjaxResult.error("批量新增失败:设备状态列表不能为空");
-        }
-
-        boolean saved = service.saveBatchWithCheck(entityList);
-        return saved ? AjaxResult.success("新增成功",saved)
-                : AjaxResult.error("新增失败",saved);
+    public AjaxResult getAll(@ApiParam("设备根类型ID(数据范围过滤,空=全部)")
+                             @RequestParam(required = false) Integer rootTypeId) {
+        return AjaxResult.success(service.listByRootType(rootTypeId));
     }
 
-    @PutMapping("/updateById")
-    @ApiOperation(value = "设备状态修改")
-    @Log(title = "修改设备状态", businessType = BusinessType.UPDATE)
-    public AjaxResult updateById(@RequestBody EquipmentStatus 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.removeById(id);
-        return deleted ? AjaxResult.success("删除成功",deleted)
-                : AjaxResult.error("删除失败",deleted);
+    @GetMapping("/statistics")
+    @ApiOperation(value = "设备状态统计:设备总数/在线/离线/报警")
+    @Anonymous
+    public AjaxResult statistics(@ApiParam("设备根类型ID(数据范围过滤,空=全部)")
+                                 @RequestParam(required = false) Integer rootTypeId) {
+        Map<String, Object> statistics = service.statistics(rootTypeId);
+        return AjaxResult.success(statistics);
     }
 
-    @DeleteMapping("/deleteBatchById")
-    @ApiOperation(value = "设备状态批量删除")
-    @Log(title = "设备状态批量删除", businessType = BusinessType.DELETE)
-    public AjaxResult deleteBatchById(@RequestParam List<String> ids) {
-        boolean deleted = service.removeByIds(ids);
-        return deleted ? AjaxResult.success("删除成功",deleted)
-                : AjaxResult.error("删除失败",deleted);
-    }
 }

+ 10 - 2
pipe-network-service/zksy-admin/src/main/java/com/zksy/web/controller/base/EquipmentTypeController.java

@@ -10,6 +10,7 @@ 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.*;
@@ -49,8 +50,15 @@ public class EquipmentTypeController {
     @GetMapping("/getList")
     @ApiOperation(value = "查询所有设备类型")
     @Anonymous
-    public AjaxResult getList() throws Exception {
-        return AjaxResult.success(service.list());
+    public AjaxResult getList(@ApiParam("设备根类型ID(仅返回该大类下的子类型,空=全部)")
+                              @RequestParam(required = false) Integer rootTypeId) {
+        if (rootTypeId == null || rootTypeId <= 0) {
+            return AjaxResult.success(service.list());
+        }
+        return AjaxResult.success(service.lambdaQuery()
+                .eq(EquipmentType::getParentId, rootTypeId)
+                .orderByAsc(EquipmentType::getId)
+                .list());
     }
 
     @PostMapping("/save")

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

@@ -14,7 +14,6 @@ import com.zksy.common.core.domain.AjaxResult;
 import com.zksy.common.enums.BusinessType;
 import com.zksy.drainage.service.DrainageEquipmentPointRelService;
 import com.zksy.drainage.service.DrainageEquipmentBindingService;
-import com.zksy.drainage.service.DrainageEquipmentTestService;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import io.swagger.annotations.ApiParam;
@@ -47,17 +46,12 @@ public class DrainageEquipmentController {
     @Autowired
     private EquipmentMaintainService equipmentMaintainService;
 
-    @Autowired
-    private DrainageEquipmentTestService equipmentTestService;
-
     @Autowired
     private DrainageEquipmentPointRelService equipmentPointRelService;
 
     @Autowired
     private DrainageEquipmentBindingService equipmentBindingService;
 
-    // ==================== 设备基础信息 ====================
-
     @Anonymous
     @GetMapping("/boundEquipmentIds")
     @ApiOperation(value = "查询排水基础数据中已占用的设备")
@@ -335,71 +329,6 @@ public class DrainageEquipmentController {
         return deleted ? AjaxResult.success("批量删除成功") : AjaxResult.error("批量删除失败");
     }
 
-    // ==================== 设备测试记录 ====================
-
-    @Anonymous
-    @GetMapping("/test/page")
-    @ApiOperation(value = "设备测试记录分页查询")
-    public Page<EquipmentTest> testPage(
-            @ApiParam("页码") @RequestParam(defaultValue = "1") long pageNum,
-            @ApiParam("每页数量") @RequestParam(defaultValue = "10") long pageSize,
-            @ApiParam("设备ID") @RequestParam(required = false) String equipmentId,
-            @ApiParam("测试类型") @RequestParam(required = false) String testType,
-            @ApiParam("测试结果") @RequestParam(required = false) String testResult) {
-        return equipmentTestService.findByPage(pageNum, pageSize, equipmentId, testType, testResult);
-    }
-
-    @Anonymous
-    @GetMapping("/test/{id}")
-    @ApiOperation(value = "查询设备测试记录详情")
-    public AjaxResult testGetById(@PathVariable String id) {
-        EquipmentTest entity = equipmentTestService.getById(id);
-        if (entity == null) {
-            return AjaxResult.error("该测试记录不存在");
-        }
-        return AjaxResult.success(entity);
-    }
-
-    @Anonymous
-    @PostMapping("/test")
-    @ApiOperation(value = "新增设备测试记录")
-    @Log(title = "新增设备测试记录", businessType = BusinessType.INSERT)
-    @Transactional
-    public AjaxResult testSave(@RequestBody EquipmentTest entity) {
-        boolean saved = equipmentTestService.saveWithCheck(entity);
-        return saved ? AjaxResult.success("新增成功") : AjaxResult.error("新增失败");
-    }
-
-    @Anonymous
-    @PutMapping("/test")
-    @ApiOperation(value = "修改设备测试记录")
-    @Log(title = "修改设备测试记录", businessType = BusinessType.UPDATE)
-    @Transactional
-    public AjaxResult testUpdate(@RequestBody EquipmentTest entity) {
-        boolean updated = equipmentTestService.updateWithCheck(entity);
-        return updated ? AjaxResult.success("修改成功") : AjaxResult.error("修改失败");
-    }
-
-    @Anonymous
-    @DeleteMapping("/test/{id}")
-    @ApiOperation(value = "删除设备测试记录")
-    @Log(title = "删除设备测试记录", businessType = BusinessType.DELETE)
-    @Transactional
-    public AjaxResult testDelete(@PathVariable String id) {
-        boolean deleted = equipmentTestService.removeWithCheck(id);
-        return deleted ? AjaxResult.success("删除成功") : AjaxResult.error("删除失败");
-    }
-
-    @Anonymous
-    @DeleteMapping("/test/batch")
-    @ApiOperation(value = "批量删除设备测试记录")
-    @Log(title = "批量删除设备测试记录", businessType = BusinessType.DELETE)
-    @Transactional
-    public AjaxResult testDeleteBatch(@RequestBody List<String> ids) {
-        boolean deleted = equipmentTestService.removeBatchWithCheck(ids);
-        return deleted ? AjaxResult.success("批量删除成功") : AjaxResult.error("批量删除失败");
-    }
-
     // ==================== 设备-监控点关联 ====================
 
     @Anonymous

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

@@ -1,22 +1,14 @@
 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.EquipmentBase;
 import com.zksy.base.domain.EquipmentPointRel;
 import com.zksy.base.domain.EquipmentStatus;
-import com.zksy.base.domain.GasPipePoint;
 import com.zksy.base.domain.GasPipePointDeviceRel;
-import com.zksy.base.domain.vo.EquipmentFullVO;
-import com.zksy.base.service.GasEquipmentService;
 import com.zksy.base.mapper.EquipmentPointRelMapper;
 import com.zksy.base.mapper.EquipmentStatusMapper;
 import com.zksy.base.mapper.GasPipePointDeviceRelMapper;
-import com.zksy.base.mapper.GasPipePointMapper;
 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;
@@ -25,24 +17,22 @@ import org.springframework.web.bind.annotation.*;
 
 import java.util.List;
 
+/**
+ * 燃气监测设备-测点关联与运行状态查询。
+ * 设备台账的新增/修改/删除已统一收口至 EquipmentBaseController(/equipment-base)。
+ */
 @Slf4j
 @RestController
 @RequestMapping("/api/equipment")
-@Api(tags = "监测设备管理")
+@Api(tags = "监测设备管理-测点关联")
 public class GasEquipmentController {
 
-    @Autowired
-    private GasEquipmentService gasEquipmentService;
-
     @Autowired
     private GasPipePointDeviceRelMapper gasPipePointDeviceRelMapper;
 
     @Autowired
     private EquipmentStatusMapper equipmentStatusMapper;
 
-    @Autowired
-    private GasPipePointMapper gasPipePointMapper;
-
     @Autowired
     private EquipmentPointRelMapper equipmentPointRelMapper;
 
@@ -125,69 +115,4 @@ public class GasEquipmentController {
         gasPipePointDeviceRelMapper.insert(rel);
         return AjaxResult.success("关联成功");
     }
-
-    @PostMapping("/save")
-    @ApiOperation("新增燃气设备(含管网关联)")
-    @Log(title = "新增燃气设备", businessType = BusinessType.INSERT)
-    public AjaxResult save(@RequestBody EquipmentBase entity,
-                           @RequestParam(required = false) String networkId,
-                           @RequestParam(required = false) Long pointId) {
-        boolean saved = gasEquipmentService.saveWithCheck(entity);
-        if (!saved) return AjaxResult.error("新增失败");
-        saveDeviceRel(entity.getEquipmentId(), networkId, pointId);
-        return AjaxResult.success("新增成功", entity.getEquipmentId());
-    }
-
-    @PutMapping("/updateById")
-    @ApiOperation("修改燃气设备(含管网关联)")
-    @Log(title = "修改燃气设备", businessType = BusinessType.UPDATE)
-    public AjaxResult updateById(@RequestBody EquipmentBase entity,
-                                  @RequestParam(required = false) String networkId,
-                                  @RequestParam(required = false) Long pointId) {
-        boolean updated = gasEquipmentService.updateWithCheck(entity);
-        if (!updated) return AjaxResult.error("修改失败");
-        saveDeviceRel(entity.getEquipmentId(), networkId, pointId);
-        return AjaxResult.success("修改成功");
-    }
-
-    private void saveDeviceRel(String equipmentId, String networkId, Long pointId) {
-        // 优先用 pointId;否则通过 networkId 找管点
-        Long pid = pointId;
-        if (pid == null && networkId != null && !networkId.isEmpty()) {
-            List<GasPipePoint> points = gasPipePointMapper.selectList(
-                    new LambdaQueryWrapper<GasPipePoint>().eq(GasPipePoint::getNetworkId, networkId));
-            if (!points.isEmpty()) pid = points.get(0).getPointId();
-        }
-        if (pid == null) return;
-        LambdaQueryWrapper<GasPipePointDeviceRel> w = new LambdaQueryWrapper<>();
-        w.eq(GasPipePointDeviceRel::getEquipmentId, equipmentId);
-        gasPipePointDeviceRelMapper.delete(w);
-        GasPipePointDeviceRel rel = new GasPipePointDeviceRel();
-        rel.setEquipmentId(equipmentId);
-        rel.setPointId(pid);
-        gasPipePointDeviceRelMapper.insert(rel);
-    }
-
-    @DeleteMapping("/deleteById")
-    @ApiOperation("删除燃气设备")
-    @Log(title = "删除燃气设备", businessType = BusinessType.DELETE)
-    public AjaxResult deleteById(@RequestParam String id) {
-        boolean deleted = gasEquipmentService.removeWithCheck(id);
-        return deleted ? AjaxResult.success("删除成功") : AjaxResult.error("删除失败");
-    }
-
-    @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,
-                                     @RequestParam(required = false) String district) {
-        Page<EquipmentFullVO> page = gasEquipmentService.findFullByPage(pageNum, pageSize,
-                equipmentCode, equipmentName, equipmentModel, manufacturer, district);
-        return AjaxResult.success(page);
-    }
 }

+ 0 - 198
pipe-network-service/zksy-admin/src/test/java/com/zksy/web/controller/WaterSupply/DeviceAbnormal/DeviceAbnormalControllerTest.java

@@ -1,198 +0,0 @@
-package com.zksy.web.controller.WaterSupply.DeviceAbnormal;
-
-import com.zksy.base.domain.vo.AbnormalDeviceVO;
-import com.zksy.base.domain.vo.DeviceAbnormalStatsVO;
-import com.zksy.base.service.WaterSupplyDeviceService;
-import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
-import com.zksy.ops.domain.WorkOrder;
-import com.zksy.ops.domain.vo.WorkOrderVO;
-import com.zksy.base.domain.vo.MaintainOrderVO;
-import com.zksy.ops.service.WorkOrderService;
-import com.zksy.common.core.domain.AjaxResult;
-import com.zksy.common.core.domain.entity.SysUser;
-import com.zksy.common.core.domain.model.LoginUser;
-import com.fasterxml.jackson.databind.JsonNode;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.zksy.ops.dto.WorkOrderDispatchDTO;
-import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
-import org.springframework.security.core.context.SecurityContextHolder;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-import org.springframework.test.util.ReflectionTestUtils;
-import org.springframework.test.web.servlet.MockMvc;
-import org.springframework.test.web.servlet.setup.MockMvcBuilders;
-
-import java.util.Collections;
-
-import static org.junit.jupiter.api.Assertions.assertTrue;
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.verify;
-import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
-import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
-import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.header;
-import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
-
-class DeviceAbnormalControllerTest {
-
-    private WaterSupplyDeviceService deviceService;
-    private WorkOrderService businessWorkOrderService;
-    private MockMvc mockMvc;
-
-    @BeforeEach
-    void setUp() {
-        deviceService = mock(WaterSupplyDeviceService.class);
-        businessWorkOrderService = mock(WorkOrderService.class);
-        DeviceAbnormalController controller = new DeviceAbnormalController();
-        ReflectionTestUtils.setField(controller, "waterSupplyDeviceService", deviceService);
-        ReflectionTestUtils.setField(controller, "businessWorkOrderService", businessWorkOrderService);
-        mockMvc = MockMvcBuilders.standaloneSetup(controller).build();
-        SysUser user = new SysUser();
-        user.setUserId(7L);
-        user.setUserName("operator");
-        LoginUser loginUser = new LoginUser(7L, 1L, user, java.util.Collections.emptySet());
-        SecurityContextHolder.getContext().setAuthentication(
-                new UsernamePasswordAuthenticationToken(loginUser, null, java.util.Collections.emptyList()));
-    }
-
-    @Test
-    void abnormalExportWritesExcelResponse() throws Exception {
-        AbnormalDeviceVO row = new AbnormalDeviceVO();
-        row.setEquipmentId("water-pressure-1");
-        row.setEquipmentName("供水压力监测点");
-        row.setAbnormalReason("供水压力超限");
-        when(deviceService.getAbnormalDeviceExport("供水", null, null, 1, null, null))
-                .thenReturn(Collections.singletonList(row));
-
-        mockMvc.perform(post("/waterSupply/device/abnormal/export")
-                        .param("equipmentName", "供水")
-                        .param("alertLevel", "1"))
-                .andExpect(status().isOk())
-                .andExpect(header().string("Content-Type",
-                        org.hamcrest.Matchers.containsString("spreadsheetml.sheet")))
-                .andExpect(result -> assertTrue(
-                        result.getResponse().getContentAsByteArray().length > 0));
-    }
-
-    @Test
-    void abnormalStatsReturnsAggregatedCounts() throws Exception {
-        DeviceAbnormalStatsVO stats = new DeviceAbnormalStatsVO();
-        stats.setTotal(3);
-        stats.setAlarm(1);
-        stats.setRepair(1);
-        stats.setOffline(1);
-        when(deviceService.getAbnormalDeviceStats()).thenReturn(stats);
-
-        mockMvc.perform(get("/waterSupply/device/abnormal/stats"))
-                .andExpect(status().isOk())
-                .andExpect(result -> {
-                    String body = result.getResponse().getContentAsString();
-                    assertTrue(body.contains("\"total\":3"));
-                    assertTrue(body.contains("\"alarm\":1"));
-                    assertTrue(body.contains("\"repair\":1"));
-                    assertTrue(body.contains("\"offline\":1"));
-                });
-    }
-
-    @Test
-    void abnormalPagePassesAbnormalTypeAndRegionFilters() throws Exception {
-        Page<AbnormalDeviceVO> page = new Page<>(1, 10, 0);
-        page.setRecords(Collections.emptyList());
-        when(deviceService.getAbnormalDevicePage(
-                1, 10, null, null, null, null, "repair", "城北", false)).thenReturn(page);
-
-        mockMvc.perform(get("/waterSupply/device/abnormal/page")
-                        .param("pageNum", "1")
-                        .param("pageSize", "10")
-                        .param("abnormalType", "repair")
-                        .param("region", "城北"))
-                .andExpect(status().isOk());
-
-        verify(deviceService).getAbnormalDevicePage(
-                1, 10, null, null, null, null, "repair", "城北", false);
-    }
-
-    @Test
-    void abnormalOrderReturnsUnifiedWorkOrderSummary() throws Exception {
-        WorkOrder order = new WorkOrder();
-        order.setOrderId(12L);
-        order.setOrderNo("WO-T6-001");
-        order.setOrderStatus(1);
-        when(deviceService.createAbnormalWorkOrder(any())).thenReturn(order);
-        when(businessWorkOrderService.dispatch(any(), any(WorkOrderDispatchDTO.class))).thenReturn(true);
-
-        mockMvc.perform(post("/waterSupply/device/abnormal/order")
-                        .contentType("application/json")
-                        .content("{\"equipmentId\":\"water-1\",\"faultDescription\":\"压力异常\",\"receiveUserId\":88}"))
-                .andExpect(status().isOk())
-                .andExpect(result -> {
-                    String body = result.getResponse().getContentAsString();
-                    assertTrue(body.contains("WO-T6-001"));
-                    assertTrue(body.contains("orderId"));
-                    assertTrue(body.contains("orderStatus"));
-                    assertTrue(body.contains("\"orderStatus\":1"));
-                    assertTrue(body.contains("\"receiveUser\":88"));
-                });
-        verify(businessWorkOrderService).dispatch(any(), any(WorkOrderDispatchDTO.class));
-    }
-
-    @Test
-    void abnormalOrderWithoutReceiverCreatesPendingOrderWithoutDispatch() {
-        WorkOrder order = new WorkOrder();
-        order.setOrderId(14L);
-        order.setOrderNo("WO-T6-PENDING");
-        order.setOrderStatus(1);
-        when(deviceService.createAbnormalWorkOrder(any())).thenReturn(order);
-
-        MaintainOrderVO request = new MaintainOrderVO();
-        request.setEquipmentId("water-1");
-        request.setFaultDescription("压力异常");
-        AjaxResult result = new DeviceAbnormalController() {{
-            ReflectionTestUtils.setField(this, "waterSupplyDeviceService", deviceService);
-            ReflectionTestUtils.setField(this, "businessWorkOrderService", businessWorkOrderService);
-        }}.createAbnormalOrder(request);
-
-        assertEquals(200, result.get("code"));
-        assertEquals(0, ((WorkOrderVO) result.get("data")).getOrderStatus());
-        org.mockito.Mockito.verify(businessWorkOrderService, org.mockito.Mockito.never())
-                .dispatch(org.mockito.ArgumentMatchers.any(), org.mockito.ArgumentMatchers.any(WorkOrderDispatchDTO.class));
-    }
-
-    @Test
-    void abnormalOrderHidesUnexpectedExceptionDetails() {
-        DeviceAbnormalController controller = new DeviceAbnormalController();
-        ReflectionTestUtils.setField(controller, "waterSupplyDeviceService", deviceService);
-        ReflectionTestUtils.setField(controller, "businessWorkOrderService", businessWorkOrderService);
-        when(deviceService.createAbnormalWorkOrder(any())).thenThrow(new IllegalStateException("database password"));
-        MaintainOrderVO request = new MaintainOrderVO();
-        request.setEquipmentId("water-1");
-        request.setReceiveUserId(88L);
-        AjaxResult result = controller.createAbnormalOrder(request);
-        assertEquals("派单失败:服务暂不可用", String.valueOf(result.get("msg")));
-        assertTrue(!String.valueOf(result.get("msg")).contains("database password"));
-    }
-
-    @Test
-    void abnormalOrderReportsDispatchFailureAndKeepsPendingStatus() throws Exception {
-        WorkOrder order = new WorkOrder();
-        order.setOrderId(13L);
-        order.setOrderNo("WO-T6-002");
-        order.setOrderStatus(1);
-        when(deviceService.createAbnormalWorkOrder(any())).thenReturn(order);
-        when(businessWorkOrderService.dispatch(any(), any(WorkOrderDispatchDTO.class))).thenReturn(false);
-
-        mockMvc.perform(post("/waterSupply/device/abnormal/order")
-                        .contentType("application/json")
-                        .content("{\"equipmentId\":\"water-1\",\"faultDescription\":\"压力异常\",\"receiveUserId\":88}"))
-                .andExpect(status().isOk())
-                .andExpect(result -> {
-                    JsonNode json = new ObjectMapper().readTree(result.getResponse().getContentAsString());
-                    assertEquals(500, json.get("code").asInt());
-                    assertTrue(json.hasNonNull("msg"));
-                    assertTrue(!json.get("msg").asText().isEmpty());
-                });
-        assertEquals(1, order.getOrderStatus());
-    }
-}

+ 0 - 50
pipe-network-service/zksy-admin/src/test/java/com/zksy/web/controller/WaterSupply/DeviceLedger/DeviceLedgerControllerTest.java

@@ -1,50 +0,0 @@
-package com.zksy.web.controller.WaterSupply.DeviceLedger;
-
-import com.zksy.base.domain.vo.DeviceGisVO;
-import com.zksy.base.service.WaterSupplyDeviceService;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-import org.springframework.test.util.ReflectionTestUtils;
-import org.springframework.test.web.servlet.MockMvc;
-import org.springframework.test.web.servlet.setup.MockMvcBuilders;
-
-import java.util.Collections;
-
-import static org.junit.jupiter.api.Assertions.assertTrue;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
-import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.header;
-import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
-
-class DeviceLedgerControllerTest {
-
-    private WaterSupplyDeviceService deviceService;
-    private MockMvc mockMvc;
-
-    @BeforeEach
-    void setUp() {
-        deviceService = mock(WaterSupplyDeviceService.class);
-        DeviceLedgerController controller = new DeviceLedgerController();
-        ReflectionTestUtils.setField(controller, "waterSupplyDeviceService", deviceService);
-        mockMvc = MockMvcBuilders.standaloneSetup(controller).build();
-    }
-
-    @Test
-    void ledgerExportWritesExcelResponse() throws Exception {
-        DeviceGisVO row = new DeviceGisVO();
-        row.setEquipmentId("water-pressure-1");
-        row.setEquipmentName("供水压力监测点");
-        when(deviceService.getDeviceLedgerExport("供水", null, null, 1, null, null))
-                .thenReturn(Collections.singletonList(row));
-
-        mockMvc.perform(post("/waterSupply/device/ledger/export")
-                        .param("equipmentName", "供水")
-                        .param("status", "1"))
-                .andExpect(status().isOk())
-                .andExpect(header().string("Content-Type",
-                        org.hamcrest.Matchers.containsString("spreadsheetml.sheet")))
-                .andExpect(result -> assertTrue(
-                        result.getResponse().getContentAsByteArray().length > 0));
-    }
-}

+ 0 - 76
pipe-network-service/zksy-system/src/main/java/com/zksy/WaterSupply/export/WaterDeviceAbnormalExportDTO.java

@@ -1,76 +0,0 @@
-package com.zksy.WaterSupply.export;
-
-import com.zksy.base.domain.vo.AbnormalDeviceVO;
-import com.zksy.common.annotation.Excel;
-import lombok.Data;
-
-import java.math.BigDecimal;
-import java.time.LocalDateTime;
-
-@Data
-public class WaterDeviceAbnormalExportDTO {
-    @Excel(name = "设备编码")
-    private String equipmentCode;
-
-    @Excel(name = "设备名称")
-    private String equipmentName;
-
-    @Excel(name = "设备类型")
-    private String equipmentTypeName;
-
-    @Excel(name = "安装位置")
-    private String equipmentLocation;
-
-    @Excel(name = "设备状态", readConverterExp = "1=在用,2=闲置,3=维修,4=报废,5=待入库")
-    private Integer currentStatus;
-
-    @Excel(name = "在线状态", readConverterExp = "0=离线,1=在线")
-    private Integer onlineStatus;
-
-    @Excel(name = "报警状态", readConverterExp = "0=正常,1=报警")
-    private Integer alarmStatus;
-
-    @Excel(name = "报警等级", readConverterExp = "1=一级,2=二级,3=三级,4=四级")
-    private Integer alertLevel;
-
-    @Excel(name = "异常原因")
-    private String abnormalReason;
-
-    @Excel(name = "关联工单号")
-    private String relatedWorkOrderNo;
-
-    @Excel(name = "工单状态", readConverterExp = "0=待派单,1=待接单,2=已接单,3=处理中,4=待验收,5=已结案,6=延期中,7=已取消")
-    private Integer relatedWorkOrderStatus;
-
-    @Excel(name = "接单责任人")
-    private String relatedWorkOrderPerson;
-
-    @Excel(name = "经度")
-    private BigDecimal longitude;
-
-    @Excel(name = "纬度")
-    private BigDecimal latitude;
-
-    @Excel(name = "状态更新时间", dateFormat = "yyyy-MM-dd HH:mm:ss")
-    private LocalDateTime statusUpdateTime;
-
-    public static WaterDeviceAbnormalExportDTO from(AbnormalDeviceVO value) {
-        WaterDeviceAbnormalExportDTO dto = new WaterDeviceAbnormalExportDTO();
-        dto.equipmentCode = value.getEquipmentCode();
-        dto.equipmentName = value.getEquipmentName();
-        dto.equipmentTypeName = value.getEquipmentTypeName();
-        dto.equipmentLocation = value.getEquipmentLocation();
-        dto.currentStatus = value.getCurrentStatus();
-        dto.onlineStatus = value.getOnlineStatus();
-        dto.alarmStatus = value.getAlarmStatus();
-        dto.alertLevel = value.getAlertLevel();
-        dto.abnormalReason = value.getAbnormalReason();
-        dto.relatedWorkOrderNo = value.getRelatedWorkOrderNo();
-        dto.relatedWorkOrderStatus = value.getRelatedWorkOrderStatus();
-        dto.relatedWorkOrderPerson = value.getRelatedWorkOrderPerson();
-        dto.longitude = value.getLongitude();
-        dto.latitude = value.getLatitude();
-        dto.statusUpdateTime = value.getStatusUpdateTime();
-        return dto;
-    }
-}

+ 0 - 51
pipe-network-service/zksy-system/src/main/java/com/zksy/WaterSupply/export/WaterDeviceLedgerExportDTO.java

@@ -1,51 +0,0 @@
-package com.zksy.WaterSupply.export;
-
-import com.zksy.base.domain.vo.DeviceGisVO;
-import com.zksy.common.annotation.Excel;
-import lombok.Data;
-
-import java.math.BigDecimal;
-
-@Data
-public class WaterDeviceLedgerExportDTO {
-    @Excel(name = "设备编码")
-    private String equipmentCode;
-
-    @Excel(name = "设备名称")
-    private String equipmentName;
-
-    @Excel(name = "设备类型")
-    private String equipmentTypeName;
-
-    @Excel(name = "安装位置")
-    private String equipmentLocation;
-
-    @Excel(name = "设备状态", readConverterExp = "1=在用,2=闲置,3=维修,4=报废,5=待入库")
-    private Integer currentStatus;
-
-    @Excel(name = "在线状态", readConverterExp = "0=离线,1=在线")
-    private Integer onlineStatus;
-
-    @Excel(name = "报警状态", readConverterExp = "0=正常,1=报警")
-    private Integer alarmStatus;
-
-    @Excel(name = "经度")
-    private BigDecimal longitude;
-
-    @Excel(name = "纬度")
-    private BigDecimal latitude;
-
-    public static WaterDeviceLedgerExportDTO from(DeviceGisVO value) {
-        WaterDeviceLedgerExportDTO dto = new WaterDeviceLedgerExportDTO();
-        dto.equipmentCode = value.getEquipmentCode();
-        dto.equipmentName = value.getEquipmentName();
-        dto.equipmentTypeName = value.getEquipmentTypeName();
-        dto.equipmentLocation = value.getEquipmentLocation();
-        dto.currentStatus = value.getCurrentStatus();
-        dto.onlineStatus = value.getOnlineStatus();
-        dto.alarmStatus = value.getAlarmStatus();
-        dto.longitude = value.getLongitude();
-        dto.latitude = value.getLatitude();
-        return dto;
-    }
-}

+ 0 - 55
pipe-network-service/zksy-system/src/main/java/com/zksy/WaterSupply/importing/WaterDeviceLedgerImportDTO.java

@@ -1,55 +0,0 @@
-package com.zksy.WaterSupply.importing;
-
-import com.zksy.common.annotation.Excel;
-import lombok.Data;
-
-import java.math.BigDecimal;
-
-/** 供水设备台账 Excel 导入行。 */
-@Data
-public class WaterDeviceLedgerImportDTO {
-    @Excel(name = "设备编码")
-    private String equipmentCode;
-
-    @Excel(name = "设备名称")
-    private String equipmentName;
-
-    @Excel(name = "设备类型")
-    private String equipmentTypeName;
-
-    @Excel(name = "设备型号")
-    private String equipmentModel;
-
-    @Excel(name = "设备规格参数")
-    private String equipmentSpec;
-
-    @Excel(name = "制造商")
-    private String manufacturer;
-
-    @Excel(name = "所属片区", readConverterExp = "CN=城南,CB=城北,TC=太常,城南=城南,城北=城北,太常=太常")
-    private String district;
-
-    @Excel(name = "经度")
-    private BigDecimal longitude;
-
-    @Excel(name = "纬度")
-    private BigDecimal latitude;
-
-    @Excel(name = "安装位置")
-    private String equipmentLocation;
-
-    @Excel(name = "设备负责人")
-    private String maintainer;
-
-    @Excel(name = "联系方式")
-    private String maintainerPhone;
-
-    @Excel(name = "权属单位")
-    private String ownershipUnit;
-
-    @Excel(name = "备注")
-    private String remark;
-
-    @Excel(name = "设备图片URL")
-    private String equipmentImage;
-}

+ 0 - 126
pipe-network-service/zksy-system/src/main/java/com/zksy/WaterSupply/importing/WaterDeviceLedgerImportService.java

@@ -1,126 +0,0 @@
-package com.zksy.WaterSupply.importing;
-
-import cn.hutool.core.bean.BeanUtil;
-import cn.hutool.core.bean.copier.CopyOptions;
-import cn.hutool.core.util.StrUtil;
-import com.baomidou.mybatisplus.core.toolkit.Wrappers;
-import com.zksy.base.domain.EquipmentBase;
-import com.zksy.base.domain.EquipmentType;
-import com.zksy.base.mapper.EquipmentTypeMapper;
-import com.zksy.base.service.EquipmentBaseService;
-import org.springframework.stereotype.Service;
-import org.springframework.transaction.annotation.Transactional;
-
-import java.time.LocalDateTime;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-import java.util.Set;
-import java.util.function.Function;
-import java.util.stream.Collectors;
-
-/** 供水设备台账 Excel 导入服务;设备类型必须归属供水顶级类型。 */
-@Service
-@Transactional(rollbackFor = Exception.class)
-public class WaterDeviceLedgerImportService {
-    private static final String WATER_TOP_TYPE_NAME = "供水";
-
-    private final EquipmentBaseService equipmentBaseService;
-    private final EquipmentTypeMapper equipmentTypeMapper;
-
-    public WaterDeviceLedgerImportService(EquipmentBaseService equipmentBaseService,
-                                          EquipmentTypeMapper equipmentTypeMapper) {
-        this.equipmentBaseService = equipmentBaseService;
-        this.equipmentTypeMapper = equipmentTypeMapper;
-    }
-
-    public String importDevices(List<WaterDeviceLedgerImportDTO> rows, boolean updateSupport) {
-        if (rows == null || rows.isEmpty()) {
-            throw new IllegalArgumentException("导入文件不能为空");
-        }
-
-        Set<String> seenCodes = new HashSet<>();
-        int count = 0;
-        for (int index = 0; index < rows.size(); index++) {
-            WaterDeviceLedgerImportDTO row = rows.get(index);
-            String code = StrUtil.trimToNull(row.getEquipmentCode());
-            if (code == null) {
-                throw new IllegalArgumentException("导入失败:第 " + (index + 1) + " 行设备编码不能为空");
-            }
-            if (!seenCodes.add(code)) {
-                throw new IllegalArgumentException("导入失败:设备编码重复:" + code);
-            }
-
-            String typeName = StrUtil.trimToNull(row.getEquipmentTypeName());
-            if (typeName == null) {
-                throw new IllegalArgumentException("导入失败:设备编码 " + code + " 的设备类型不能为空");
-            }
-            String waterTypeId = resolveWaterTypeId(typeName);
-
-            EquipmentBase existing = equipmentBaseService.getOne(
-                    Wrappers.<EquipmentBase>lambdaQuery().eq(EquipmentBase::getEquipmentCode, code), false);
-            boolean update = existing != null;
-            if (update && !updateSupport) {
-                continue;
-            }
-
-            EquipmentBase device = update ? existing : new EquipmentBase();
-            BeanUtil.copyProperties(row, device, CopyOptions.create().setIgnoreNullValue(true));
-            device.setEquipmentCode(code);
-            device.setEquipmentTypeId(waterTypeId);
-            LocalDateTime now = LocalDateTime.now();
-            if (update) {
-                device.setUpdateTime(now);
-                if (!equipmentBaseService.updateById(device)) {
-                    throw new IllegalStateException("供水设备数据更新失败:" + code);
-                }
-            } else {
-                device.setCreateTime(now);
-                device.setUpdateTime(now);
-                if (!equipmentBaseService.save(device)) {
-                    throw new IllegalStateException("供水设备数据保存失败:" + code);
-                }
-            }
-            count++;
-        }
-        return "成功导入 " + count + " 台供水设备";
-    }
-
-    private String resolveWaterTypeId(String typeName) {
-        List<EquipmentType> allTypes = equipmentTypeMapper.selectList(Wrappers.emptyWrapper());
-        Map<String, EquipmentType> typesById = allTypes.stream()
-                .collect(Collectors.toMap(type -> String.valueOf(type.getId()), Function.identity(), (left, right) -> left));
-        List<EquipmentType> matches = allTypes.stream()
-                .filter(type -> typeName.equals(type.getTypeName()))
-                .collect(Collectors.toList());
-        if (matches.isEmpty()) {
-            throw new IllegalArgumentException("导入失败:设备类型不存在:" + typeName);
-        }
-
-        Set<String> waterTypeIds = matches.stream()
-                .filter(type -> isWaterType(type, typesById))
-                .map(type -> String.valueOf(type.getId()))
-                .collect(Collectors.toSet());
-        if (waterTypeIds.isEmpty()) {
-            throw new IllegalArgumentException("导入失败:设备类型不属于供水:" + typeName);
-        }
-        if (waterTypeIds.size() > 1) {
-            throw new IllegalArgumentException("导入失败:存在多个同名供水设备类型:" + typeName);
-        }
-        return waterTypeIds.iterator().next();
-    }
-
-    private boolean isWaterType(EquipmentType type, Map<String, EquipmentType> typesById) {
-        EquipmentType cursor = type;
-        int guard = 0;
-        while (cursor != null && guard++ <= typesById.size()) {
-            if (WATER_TOP_TYPE_NAME.equals(cursor.getTypeName())
-                    && Integer.valueOf(0).equals(cursor.getParentId())) {
-                return true;
-            }
-            cursor = typesById.get(String.valueOf(cursor.getParentId()));
-        }
-        return false;
-    }
-}

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

@@ -5,12 +5,14 @@ import com.baomidou.mybatisplus.annotation.TableId;
 import com.baomidou.mybatisplus.annotation.TableLogic;
 import com.baomidou.mybatisplus.annotation.TableName;
 import com.fasterxml.jackson.annotation.JsonFormat;
+import com.zksy.base.enums.AlarmStatusEnum;
+import com.zksy.base.enums.CurrentStatusEnum;
+import com.zksy.base.enums.OnlineStatusEnum;
 import lombok.AllArgsConstructor;
 import lombok.Data;
 import lombok.NoArgsConstructor;
 
 import java.time.LocalDateTime;
-import java.util.Date;
 
 /**
  * 设备状态表
@@ -33,46 +35,24 @@ public class EquipmentStatus {
     private String equipmentId;
 
     /**
-     * 设备当前状态:1-在用,2-闲置,3-维修,4-报废,5-待入库
+     * 设备当前(资产)状态:0-在用,1-维修,2-报废(见 {@link CurrentStatusEnum})
      */
     private Integer currentStatus;
 
     /**
-     * 报警状态(0-正常,1-报警)
+     * 报警状态:0-正常,1-报警(见 {@link AlarmStatusEnum})
      */
     private Integer alarmStatus;
 
     /**
-     * 在线状态(0-离线,1-在线)
+     * 在线状态:0-离线,1-在线(见 {@link OnlineStatusEnum})
      */
     private Integer onlineStatus;
 
-    /**
-     * 负责人ID(可关联用户表)
-     */
-    private Long userId;
-
-    /**
-     * 安装/存放地址
-     */
-    private String installationAddr;
-
-    /**
-     * 最后一次维护日期
-     */
-    @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
-    private Date lastMaintainDate;
-
-    /**
-     * 下次预计维护日期
-     */
-    @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
-    private Date nextMaintainDate;
-
     /**
      * 状态更新时间
      */
-    @JsonFormat(locale = "zh",pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
+    @JsonFormat(locale = "zh", pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
     private LocalDateTime statusUpdateTime;
 
     /**

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

@@ -1,49 +0,0 @@
-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(value = "equipment_test", schema = "app_user")
-public class EquipmentTest {
-
-    @TableId(value = "test_id", type = IdType.ASSIGN_UUID)
-    @ApiModelProperty("测试记录ID")
-    private String testId;
-
-    @ApiModelProperty("设备ID")
-    private String equipmentId;
-
-    @ApiModelProperty("测试类型")
-    private String testType;
-
-    @ApiModelProperty("测试结果")
-    private String testResult;
-
-    @ApiModelProperty("测试详情")
-    private String testDetail;
-
-    @ApiModelProperty("测试时间")
-    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
-    private LocalDateTime testTime;
-
-    @ApiModelProperty("测试人")
-    private String testUser;
-
-    @ApiModelProperty("创建时间")
-    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
-    private LocalDateTime createTime;
-}

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

@@ -94,14 +94,6 @@ public class EquipmentFullVO {
     @ApiModelProperty("在线状态:0-离线,1-在线")
     private Integer onlineStatus;
 
-    @ApiModelProperty("最后一次维护日期")
-    @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
-    private Date lastMaintainDate;
-
-    @ApiModelProperty("下次预计维护日期")
-    @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
-    private Date nextMaintainDate;
-
     // ===== gas_pipe_point =====
     @ApiModelProperty("管点ID")
     private Long pointId;

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

@@ -0,0 +1,39 @@
+package com.zksy.base.enums;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+import java.util.Objects;
+
+/**
+ * 设备报警状态枚举
+ *
+ * <p>新增设备默认状态:{@link #NORMAL}(正常)。
+ */
+@Getter
+@AllArgsConstructor
+public enum AlarmStatusEnum {
+
+    NORMAL(0, "正常"),
+    ALARM(1, "报警");
+
+    private final Integer code;
+    private final String desc;
+
+    public static AlarmStatusEnum getByCode(Integer code) {
+        if (code == null) {
+            return null;
+        }
+        for (AlarmStatusEnum item : values()) {
+            if (Objects.equals(item.code, code)) {
+                return item;
+            }
+        }
+        return null;
+    }
+
+    public static String getDescByCode(Integer code) {
+        AlarmStatusEnum item = getByCode(code);
+        return item == null ? "" : item.getDesc();
+    }
+}

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

@@ -0,0 +1,40 @@
+package com.zksy.base.enums;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+import java.util.Objects;
+
+/**
+ * 设备当前(资产)状态枚举
+ *
+ * <p>新增设备默认状态:{@link #IN_USE}(在用)。
+ */
+@Getter
+@AllArgsConstructor
+public enum CurrentStatusEnum {
+
+    IN_USE(0, "在用"),
+    REPAIR(1, "维修"),
+    SCRAPPED(2, "报废");
+
+    private final Integer code;
+    private final String desc;
+
+    public static CurrentStatusEnum getByCode(Integer code) {
+        if (code == null) {
+            return null;
+        }
+        for (CurrentStatusEnum item : values()) {
+            if (Objects.equals(item.code, code)) {
+                return item;
+            }
+        }
+        return null;
+    }
+
+    public static String getDescByCode(Integer code) {
+        CurrentStatusEnum item = getByCode(code);
+        return item == null ? "" : item.getDesc();
+    }
+}

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

@@ -0,0 +1,39 @@
+package com.zksy.base.enums;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+import java.util.Objects;
+
+/**
+ * 设备在线状态枚举
+ *
+ * <p>新增设备默认状态:{@link #OFFLINE}(离线)。
+ */
+@Getter
+@AllArgsConstructor
+public enum OnlineStatusEnum {
+
+    OFFLINE(0, "离线"),
+    ONLINE(1, "在线");
+
+    private final Integer code;
+    private final String desc;
+
+    public static OnlineStatusEnum getByCode(Integer code) {
+        if (code == null) {
+            return null;
+        }
+        for (OnlineStatusEnum item : values()) {
+            if (Objects.equals(item.code, code)) {
+                return item;
+            }
+        }
+        return null;
+    }
+
+    public static String getDescByCode(Integer code) {
+        OnlineStatusEnum item = getByCode(code);
+        return item == null ? "" : item.getDesc();
+    }
+}

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

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

+ 2 - 3
pipe-network-service/zksy-system/src/main/java/com/zksy/base/service/EquipmentBaseService.java

@@ -27,7 +27,8 @@ public interface EquipmentBaseService extends IService<EquipmentBase> {
 
     Page<EquipmentBase> findByPage(long pageNum, long pageSize,
                                    String equipmentCode, String equipmentName,
-                                   String equipmentModel, String manufacturer);
+                                   String equipmentTypeId, Integer rootTypeId,
+                                   Integer onlineStatus, Integer alarmStatus);
 
     boolean saveWithCheck(EquipmentBase entity);
 
@@ -41,8 +42,6 @@ public interface EquipmentBaseService extends IService<EquipmentBase> {
 
     boolean updateEquipmentStatus(String equipmentId, Integer currentStatus);
 
-    boolean testEquipment(String equipmentId, String testType, String testDetail, String testUser);
-
     Map<String, Object> getEquipmentDetail(String equipmentId);
 
     List<EquipmentBase> getEquipmentByPoint(String pointId);

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

@@ -3,6 +3,8 @@ package com.zksy.base.service;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.IService;
 import com.zksy.base.domain.EquipmentStatus;
+
+import java.util.Map;
 import com.zksy.manhole.dto.in.EquipmentStatusInDTO;
 import org.springframework.stereotype.Service;
 
@@ -54,4 +56,16 @@ public interface EquipmentStatusService extends IService<EquipmentStatus> {
      * 判断设备编码对应的智能设备是否存在。
      */
     boolean existsByDeviceCode(String deviceCode);
+
+    /**
+     * 设备状态统计:设备总数 / 在线设备数 / 离线设备数 / 报警设备数。
+     * @param rootTypeId 设备根类型ID(数据范围过滤,空=全部)
+     */
+    Map<String, Object> statistics(Integer rootTypeId);
+
+    /**
+     * 查询指定根设备类型范围内所有设备的状态记录。
+     * @param rootTypeId 设备根类型ID(空=全部)
+     */
+    List<EquipmentStatus> listByRootType(Integer rootTypeId);
 }

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

@@ -1,19 +0,0 @@
-package com.zksy.base.service;
-
-import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
-import com.zksy.base.domain.EquipmentBase;
-import com.zksy.base.domain.vo.EquipmentFullVO;
-
-public interface GasEquipmentService {
-
-    boolean saveWithCheck(EquipmentBase entity);
-
-    boolean updateWithCheck(EquipmentBase entity);
-
-    boolean removeWithCheck(String equipmentId);
-
-    Page<EquipmentFullVO> findFullByPage(long pageNum, long pageSize,
-                                         String equipmentCode, String equipmentName,
-                                         String equipmentModel, String manufacturer,
-                                         String district);
-}

+ 8 - 70
pipe-network-service/zksy-system/src/main/java/com/zksy/base/service/WaterSupplyDeviceService.java

@@ -1,87 +1,25 @@
 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.ops.domain.WorkOrder;
-import com.zksy.base.domain.vo.*;
+import com.zksy.base.domain.vo.AbnormalDeviceVO;
+import com.zksy.base.domain.vo.DeviceDetailVO;
+import com.zksy.base.domain.vo.DeviceGisVO;
+import com.zksy.base.domain.vo.DeviceTypeStatisticsVO;
 
 import java.util.List;
-import java.util.Map;
 
+/**
+ * 供水设备 GIS 一张图支撑服务。
+ * 设备台账管理已统一迁移至 EquipmentBaseService / 设备台账总页(subSystem/pipeNetwork/pdeviceInform/index)。
+ */
 public interface WaterSupplyDeviceService extends IService<EquipmentBase> {
 
     List<DeviceTypeStatisticsVO> getDeviceTypeStatistics();
 
-    DeviceLedgerStatisticsVO getDeviceLedgerStatistics();
-
-    Page<DeviceGisVO> getDeviceLedgerPage(long pageNum, long pageSize,
-                                           String equipmentName, String equipmentCode,
-                                           String equipmentTypeId, Integer status,
-                                           Integer alarmStatus, Integer alertLevel);
-
-    List<DeviceGisVO> getDeviceLedgerExport(String equipmentName, String equipmentCode,
-                                             String equipmentTypeId, Integer status,
-                                             Integer alarmStatus, Integer alertLevel);
-
-    boolean createWaterDevice(EquipmentBase device);
-
-    boolean deleteWaterDevices(List<String> equipmentIds);
-
     List<DeviceGisVO> getAllDeviceGisPoints(String equipmentTypeId);
 
     DeviceDetailVO getDeviceDetail(String equipmentId);
 
-    boolean createMaintainOrder(MaintainOrderVO vo);
-
-    WorkOrder createAbnormalWorkOrder(MaintainOrderVO vo);
-
-    Page<AbnormalDeviceVO> getAbnormalDevicePage(long pageNum, long pageSize,
-                                                  String equipmentName, String equipmentCode,
-                                                  String equipmentTypeId, Integer alertLevel);
-
-    Page<AbnormalDeviceVO> getAbnormalDevicePage(long pageNum, long pageSize,
-                                                  String equipmentName, String equipmentCode,
-                                                  String equipmentTypeId, Integer alertLevel,
-                                                  Boolean dispatchableOnly);
-
-    Page<AbnormalDeviceVO> getAbnormalDevicePage(long pageNum, long pageSize,
-                                                  String equipmentName, String equipmentCode,
-                                                  String equipmentTypeId, Integer alertLevel,
-                                                  String abnormalType, String region);
-
-    Page<AbnormalDeviceVO> getAbnormalDevicePage(long pageNum, long pageSize,
-                                                  String equipmentName, String equipmentCode,
-                                                  String equipmentTypeId, Integer alertLevel,
-                                                  String abnormalType, String region,
-                                                  Boolean dispatchableOnly);
-
-    DeviceAbnormalStatsVO getAbnormalDeviceStats();
-
-    List<AbnormalDeviceVO> getAbnormalDeviceExport(String equipmentName, String equipmentCode,
-                                                    String equipmentTypeId, Integer alertLevel);
-
-    List<AbnormalDeviceVO> getAbnormalDeviceExport(String equipmentName, String equipmentCode,
-                                                    String equipmentTypeId, Integer alertLevel,
-                                                    String abnormalType, String region);
-
     List<AbnormalDeviceVO> getAbnormalDeviceGisPoints(String equipmentTypeId);
-
-    List<Map<String, Object>> getMaintainRecordList(String equipmentId);
-
-    boolean saveMaintainRecord(EquipmentMaintainDataVO vo);
-
-    boolean updateMaintainRecord(EquipmentMaintainDataVO vo);
-
-    boolean deleteMaintainRecord(String maintainId);
-
-    Page<EquipmentMaintainDataVO> getMaintainRecordPage(long pageNum, long pageSize,
-                                                          String equipmentName, String maintainPerson,
-                                                          String maintainType, String status,
-                                                          String startTime, String endTime);
-
-    Page<EquipmentMaintainDataVO> getMyMaintainRecordPage(long pageNum, long pageSize,
-                                                            String maintainPerson,
-                                                            String maintainType, String status,
-                                                            String startTime, String endTime);
 }

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

@@ -11,7 +11,10 @@ import com.zksy.base.alarm.domain.WarningThreshold;
 import com.zksy.base.alarm.mapper.WarningThresholdMapper;
 import com.zksy.base.constant.GasEquipmentTypeEnum;
 import com.zksy.base.domain.*;
+import com.zksy.base.enums.AlarmStatusEnum;
+import com.zksy.base.enums.CurrentStatusEnum;
 import com.zksy.base.enums.EquipmentTypeEnum;
+import com.zksy.base.enums.OnlineStatusEnum;
 import com.zksy.base.domain.vo.EquipmentFullVO;
 import com.zksy.base.event.DeviceStatusChangePublisher;
 import com.zksy.base.manhole.domain.ManholeData;
@@ -61,9 +64,6 @@ public class EquipmentBaseServiceImpl extends ServiceImpl<EquipmentBaseMapper, E
     @Autowired
     private EquipmentPointRelMapper equipmentPointRelMapper;
 
-    @Autowired
-    private EquipmentTestMapper equipmentTestMapper;
-
     @Autowired
     private WarningThresholdMapper warningThresholdMapper;
 
@@ -85,7 +85,8 @@ public class EquipmentBaseServiceImpl extends ServiceImpl<EquipmentBaseMapper, E
     @Override
     public Page<EquipmentBase> findByPage(long pageNum, long pageSize,
                                           String equipmentCode, String equipmentName,
-                                          String equipmentModel, String manufacturer) {
+                                          String equipmentTypeId, Integer rootTypeId,
+                                          Integer onlineStatus, Integer alarmStatus) {
         Page<EquipmentBase> page = new Page<>(pageNum, pageSize);
         LambdaQueryWrapper<EquipmentBase> queryWrapper = new LambdaQueryWrapper<>();
         if (equipmentCode != null && !equipmentCode.isEmpty()) {
@@ -94,16 +95,63 @@ public class EquipmentBaseServiceImpl extends ServiceImpl<EquipmentBaseMapper, E
         if (equipmentName != null && !equipmentName.isEmpty()) {
             queryWrapper.like(EquipmentBase::getEquipmentName, equipmentName);
         }
-        if (equipmentModel != null && !equipmentModel.isEmpty()) {
-            queryWrapper.like(EquipmentBase::getEquipmentModel, equipmentModel);
+        if (equipmentTypeId != null && !equipmentTypeId.isEmpty()) {
+            queryWrapper.eq(EquipmentBase::getEquipmentTypeId, equipmentTypeId);
         }
-        if (manufacturer != null && !manufacturer.isEmpty()) {
-            queryWrapper.like(EquipmentBase::getManufacturer, manufacturer);
+        // 在线/报警条件位于 equipment_status,先取出命中的设备ID再回主表过滤
+        if (onlineStatus != null || (alarmStatus != null && alarmStatus == 1)) {
+            LambdaQueryWrapper<EquipmentStatus> statusWrapper = new LambdaQueryWrapper<>();
+            if (onlineStatus != null) {
+                statusWrapper.eq(EquipmentStatus::getOnlineStatus, onlineStatus);
+            }
+            if (alarmStatus != null && alarmStatus == 1) {
+                statusWrapper.eq(EquipmentStatus::getAlarmStatus, 1);
+            }
+            List<String> matchedIds = equipmentStatusMapper.selectList(statusWrapper).stream()
+                    .map(EquipmentStatus::getEquipmentId)
+                    .filter(Objects::nonNull)
+                    .distinct()
+                    .collect(Collectors.toList());
+            if (matchedIds.isEmpty()) {
+                page.setRecords(Collections.emptyList());
+                page.setTotal(0);
+                return page;
+            }
+            queryWrapper.in(EquipmentBase::getEquipmentId, matchedIds);
+        }
+        Set<String> allowedTypeIds = resolveChildTypeIds(rootTypeId);
+        if (allowedTypeIds != null) {
+            if (allowedTypeIds.isEmpty()) {
+                page.setRecords(Collections.emptyList());
+                page.setTotal(0);
+                return page;
+            }
+            queryWrapper.in(EquipmentBase::getEquipmentTypeId, allowedTypeIds);
         }
         queryWrapper.orderByDesc(EquipmentBase::getCreateTime);
         return this.page(page, queryWrapper);
     }
 
+    /**
+     * 解析根设备类型下的子类型ID集合;rootTypeId 为空时返回 null(不过滤),
+     * 根类型无效时抛出异常。
+     */
+    private Set<String> resolveChildTypeIds(Integer rootTypeId) {
+        if (rootTypeId == null || rootTypeId <= 0) {
+            return null;
+        }
+        EquipmentTypeEnum rootEnum = EquipmentTypeEnum.getById(rootTypeId);
+        if (rootEnum == null || !rootEnum.isRoot()) {
+            throw new ServiceException("无效的设备根类型:" + rootTypeId);
+        }
+        return equipmentTypeMapper.selectList(new LambdaQueryWrapper<EquipmentType>()
+                        .eq(EquipmentType::getParentId, rootTypeId)).stream()
+                .map(EquipmentType::getId)
+                .filter(Objects::nonNull)
+                .map(String::valueOf)
+                .collect(Collectors.toSet());
+    }
+
     @Override
     public boolean saveWithCheck(EquipmentBase entity) {
         String equipmentTypeId = entity.getEquipmentTypeId();
@@ -117,14 +165,19 @@ public class EquipmentBaseServiceImpl extends ServiceImpl<EquipmentBaseMapper, E
         if (count > 0) {
             throw new ServiceException("设备编码已存在,请更换:" + entity.getEquipmentCode());
         }
+        boolean saved;
         try {
-            return this.save(entity);
+            saved = this.save(entity);
         } catch (org.springframework.dao.DataIntegrityViolationException e) {
             if (e.getMessage() != null && e.getMessage().contains("uk_equipment_code")) {
                 throw new ServiceException("设备编码已存在, 请更换: " + entity.getEquipmentCode());
             }
             throw e;
         }
+        if (saved) {
+            initEquipmentStatus(entity.getEquipmentId());
+        }
+        return saved;
     }
 
     @Override
@@ -148,7 +201,26 @@ public class EquipmentBaseServiceImpl extends ServiceImpl<EquipmentBaseMapper, E
                 throw new ServiceException("设备编码已存在:" + entity.getEquipmentCode());
             }
         }
-        return this.saveBatch(entityList);
+        boolean saved = this.saveBatch(entityList);
+        if (saved) {
+            for (EquipmentBase entity : entityList) {
+                initEquipmentStatus(entity.getEquipmentId());
+            }
+        }
+        return saved;
+    }
+
+    /**
+     * 新增设备时初始化一条设备状态记录(默认:在用 / 正常 / 离线)。
+     */
+    private void initEquipmentStatus(String equipmentId) {
+        EquipmentStatus status = new EquipmentStatus();
+        status.setEquipmentId(equipmentId);
+        status.setCurrentStatus(CurrentStatusEnum.IN_USE.getCode());
+        status.setAlarmStatus(AlarmStatusEnum.NORMAL.getCode());
+        status.setOnlineStatus(OnlineStatusEnum.OFFLINE.getCode());
+        status.setStatusUpdateTime(LocalDateTime.now());
+        equipmentStatusMapper.insert(status);
     }
 
     @Override
@@ -203,11 +275,6 @@ public class EquipmentBaseServiceImpl extends ServiceImpl<EquipmentBaseMapper, E
         warningThresholdMapper.delete(thresholdWrapper);
         log.info("已删除设备[{}]的预警阈值配置", equipmentId);*/
 
-        LambdaQueryWrapper<EquipmentTest> testWrapper = new LambdaQueryWrapper<>();
-        testWrapper.eq(EquipmentTest::getEquipmentId, equipmentId);
-        equipmentTestMapper.delete(testWrapper);
-        log.info("已删除设备[{}]的测试记录", equipmentId);
-
         return this.baseMapper.deleteById(equipmentId) > 0;
     }
 
@@ -251,11 +318,6 @@ public class EquipmentBaseServiceImpl extends ServiceImpl<EquipmentBaseMapper, E
         warningThresholdMapper.delete(thresholdWrapper);
         log.info("已批量删除{}条设备的预警阈值配置", existIds.size());*/
 
-        LambdaQueryWrapper<EquipmentTest> testWrapper = new LambdaQueryWrapper<>();
-        testWrapper.in(EquipmentTest::getEquipmentId, existIds);
-        equipmentTestMapper.delete(testWrapper);
-        log.info("已批量删除{}条设备的测试记录", existIds.size());
-
         return this.removeByIds(existIds);
     }
 
@@ -804,24 +866,6 @@ public class EquipmentBaseServiceImpl extends ServiceImpl<EquipmentBaseMapper, E
                 status.getOnlineStatus(), source);
     }
 
-    @Override
-    @Transactional
-    public boolean testEquipment(String equipmentId, String testType, String testDetail, String testUser) {
-        EquipmentBase equipment = this.getById(equipmentId);
-        if (equipment == null) {
-            throw new ServiceException("设备不存在:" + equipmentId);
-        }
-
-        EquipmentTest test = new EquipmentTest();
-        test.setEquipmentId(equipmentId);
-        test.setTestType(testType);
-        test.setTestResult("SUCCESS");
-        test.setTestDetail(testDetail);
-        test.setTestTime(LocalDateTime.now());
-        test.setTestUser(testUser);
-        return equipmentTestMapper.insert(test) > 0;
-    }
-
     @Override
     public Map<String, Object> getEquipmentDetail(String equipmentId) {
         EquipmentBase equipment = this.getById(equipmentId);
@@ -842,28 +886,12 @@ public class EquipmentBaseServiceImpl extends ServiceImpl<EquipmentBaseMapper, E
         EquipmentStatus status = equipmentStatusMapper.selectOne(statusWrapper);
         result.put("statusInfo", status);
 
-        LambdaQueryWrapper<EquipmentMaintain> maintainWrapper = new LambdaQueryWrapper<>();
-        maintainWrapper.eq(EquipmentMaintain::getEquipmentId, equipmentId);
-        maintainWrapper.orderByDesc(EquipmentMaintain::getMaintainDate);
-        List<EquipmentMaintain> maintainList = equipmentMaintainMapper.selectList(maintainWrapper);
-        result.put("maintainList", maintainList);
-
-        // 联表查询设备关联的监测点(含 point_code / point_name)
-        List<Map<String, Object>> pointRelList = equipmentPointRelMapper.selectPointRelByEquipmentId(equipmentId);
-        result.put("pointRelList", pointRelList);
-
         // 现在 WarningThreshold 有了 equipmentId 字段,直接匹配
         LambdaQueryWrapper<WarningThreshold> thresholdWrapper = new LambdaQueryWrapper<>();
         thresholdWrapper.eq(WarningThreshold::getDeviceCode, equipment.getEquipmentCode());
         List<WarningThreshold> thresholdList = warningThresholdMapper.selectList(thresholdWrapper);
         result.put("thresholdList", thresholdList);
 
-        LambdaQueryWrapper<EquipmentTest> testWrapper = new LambdaQueryWrapper<>();
-        testWrapper.eq(EquipmentTest::getEquipmentId, equipmentId);
-        testWrapper.orderByDesc(EquipmentTest::getTestTime);
-        List<EquipmentTest> testList = equipmentTestMapper.selectList(testWrapper);
-        result.put("testList", testList);
-
         return result;
     }
 
@@ -979,8 +1007,6 @@ public class EquipmentBaseServiceImpl extends ServiceImpl<EquipmentBaseMapper, E
                 vo.setCurrentStatus(status.getCurrentStatus());
                 vo.setAlarmStatus(status.getAlarmStatus());
                 vo.setOnlineStatus(status.getOnlineStatus());
-                vo.setLastMaintainDate(status.getLastMaintainDate());
-                vo.setNextMaintainDate(status.getNextMaintainDate());
             } else {
                 vo.setCurrentStatus(1);
                 vo.setAlarmStatus(0);

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

@@ -5,22 +5,29 @@ 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.EquipmentStatus;
+import com.zksy.base.domain.EquipmentType;
+import com.zksy.base.enums.AlarmStatusEnum;
+import com.zksy.base.enums.CurrentStatusEnum;
+import com.zksy.base.enums.EquipmentTypeEnum;
+import com.zksy.base.enums.OnlineStatusEnum;
 import com.zksy.base.event.DeviceStatusChangePublisher;
 import com.zksy.base.mapper.EquipmentBaseMapper;
 import com.zksy.base.mapper.EquipmentStatusMapper;
+import com.zksy.base.mapper.EquipmentTypeMapper;
 import com.zksy.base.service.EquipmentStatusService;
-import com.zksy.common.core.domain.entity.SysUser;
 import com.zksy.common.exception.ServiceException;
 import com.zksy.manhole.dto.in.EquipmentStatusInDTO;
-import com.zksy.system.service.ISysUserService;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
+import java.util.Collections;
 import java.util.Date;
+import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
+import java.util.Map;
 import java.util.Objects;
 import java.util.Set;
 import java.util.stream.Collectors;
@@ -31,10 +38,10 @@ public class EquipmentStatusServiceImpl extends ServiceImpl<EquipmentStatusMappe
         implements EquipmentStatusService {
 
     @Autowired
-    private ISysUserService sysUserService;
+    private EquipmentBaseMapper equipmentBaseMapper;
 
     @Autowired
-    private EquipmentBaseMapper equipmentBaseMapper;
+    private EquipmentTypeMapper equipmentTypeMapper;
 
     @Autowired
     private DeviceStatusChangePublisher deviceStatusChangePublisher;
@@ -49,8 +56,7 @@ public class EquipmentStatusServiceImpl extends ServiceImpl<EquipmentStatusMappe
         queryWrapper.eq(EquipmentStatus::getStatusId,statusId)
                     .eq(EquipmentStatus::getCurrentStatus,currentStatus)
                     .eq(EquipmentStatus::getAlarmStatus,alarmStatus)
-                    .eq(EquipmentStatus::getOnlineStatus,onlineStatus)
-                    .eq(EquipmentStatus::getUserId,userId);
+                    .eq(EquipmentStatus::getOnlineStatus,onlineStatus);
         return this.page(page,queryWrapper);
     }
 
@@ -82,20 +88,12 @@ public class EquipmentStatusServiceImpl extends ServiceImpl<EquipmentStatusMappe
             return updated;
         }
 
-        //校验当前状态值是否合法(1-在用,2-闲置,3-维修,4-报废,5-待入库)
+        //校验当前状态值是否合法(0-在用,1-维修,2-报废)
         Integer currentStatus = entity.getCurrentStatus();
-        if (currentStatus == null || currentStatus < 1 || currentStatus > 5) {
-            throw new ServiceException("设备状态值无效,必须为1-5之间的整数:" + currentStatus);
+        if (currentStatus == null || CurrentStatusEnum.getByCode(currentStatus) == null) {
+            throw new ServiceException("设备状态值无效,必须为0-2之间的整数:" + currentStatus);
         }
 
-        //校验负责人ID
-        Long userId = entity.getUserId();
-        if (userId != null) {
-            SysUser user = sysUserService.selectUserById(userId);
-            if (user == null || "2".equals(user.getDelFlag())) { // 排除已删除的用户
-                throw new ServiceException("负责人ID不存在或已删除:" + userId);
-            }
-        }
         //新增
         boolean saved = this.save(entity);
         if (saved) {
@@ -153,19 +151,10 @@ public class EquipmentStatusServiceImpl extends ServiceImpl<EquipmentStatusMappe
 
         //校验
         for (EquipmentStatus entity : entityList) {
-            //校验状态值范围是否合法
+            //校验状态值范围是否合法(0-在用,1-维修,2-报废)
             Integer status = entity.getCurrentStatus();
-            if (status == null || status < 1 || status > 5) {
-                throw new ServiceException("设备状态值无效(必须为1-5):" + status + "(状态记录ID:" + entity.getStatusId() + ")");
-            }
-
-            //校验负责人ID
-            Long userId = entity.getUserId();
-            if (userId != null) {
-                SysUser user = sysUserService.selectUserById(userId);
-                if (user == null || "2".equals(user.getDelFlag())) { // 检查用户是否存在且未被删除
-                    throw new ServiceException("负责人不存在或已删除:" + userId + "(状态记录ID:" + entity.getStatusId() + ")");
-                }
+            if (status == null || CurrentStatusEnum.getByCode(status) == null) {
+                throw new ServiceException("设备状态值无效(必须为0-2):" + status + "(状态记录ID:" + entity.getStatusId() + ")");
             }
         }
         //批量新增
@@ -180,8 +169,8 @@ public class EquipmentStatusServiceImpl extends ServiceImpl<EquipmentStatusMappe
 
     /**
      * 修改仪器状态
-     * @param entity
-     * @return
+     * @param entity 设备状态记录
+     * @return 是否更新成功
      */
     @Override
     @Transactional
@@ -212,20 +201,12 @@ public class EquipmentStatusServiceImpl extends ServiceImpl<EquipmentStatusMappe
             throw new ServiceException("不允许修改设备ID(如需更换设备,请删除旧记录后重新新增)");
         }
 
-        //校验状态值合法性
+        //校验状态值合法性(0-在用,1-维修,2-报废)
         Integer status = entity.getCurrentStatus();
-        if (status != null && (status < 1 || status > 5)) {
-            throw new ServiceException("设备状态值无效(必须为1-5):" + status);
+        if (status != null && CurrentStatusEnum.getByCode(status) == null) {
+            throw new ServiceException("设备状态值无效(必须为0-2):" + status);
         }
 
-        // 校验负责人ID
-        Long newUserId = entity.getUserId();
-        if (newUserId != null) {
-            SysUser user = sysUserService.selectUserById(newUserId);
-            if (user == null || "2".equals(user.getDelFlag())) {
-                throw new ServiceException("负责人不存在或已删除:" + newUserId);
-            }
-        }
         //更新
         boolean changed = hasStateChange(oldStatus, entity);
         boolean updated = this.updateById(entity);
@@ -244,10 +225,10 @@ public class EquipmentStatusServiceImpl extends ServiceImpl<EquipmentStatusMappe
     @Transactional
     public boolean updateDeviceStatus(EquipmentStatusInDTO inDTO) {
         log.info("修改设备状态-入参:{}", inDTO);
-        //校验状态值合法性
+        //校验状态值合法性(0-在用,1-维修,2-报废)
         Integer status = inDTO.getCurrentStatus();
-        if (status != null && (status < 1 || status > 5)) {
-            throw new ServiceException("设备状态值无效(必须为1-5):" + status);
+        if (status != null && CurrentStatusEnum.getByCode(status) == null) {
+            throw new ServiceException("设备状态值无效(必须为0-2):" + status);
         }
         //校验当前状态记录是否存在
         EquipmentStatus oldStatus = this.lambdaQuery()
@@ -304,6 +285,75 @@ public class EquipmentStatusServiceImpl extends ServiceImpl<EquipmentStatusMappe
         return equipmentBaseMapper.selectCount(wrapper) > 0;
     }
 
+    @Override
+    public Map<String, Object> statistics(Integer rootTypeId) {
+        Map<String, Object> result = new HashMap<>();
+        Set<String> allowedEquipmentIds = resolveRootEquipmentIds(rootTypeId);
+        // 设备总数以 equipment_base 为准
+        LambdaQueryWrapper<EquipmentBase> baseWrapper = new LambdaQueryWrapper<>();
+        if (allowedEquipmentIds != null) {
+            baseWrapper.in(EquipmentBase::getEquipmentId, allowedEquipmentIds.isEmpty() ? Collections.singleton("") : allowedEquipmentIds);
+        }
+        long total = equipmentBaseMapper.selectCount(baseWrapper);
+        LambdaQueryWrapper<EquipmentStatus> onlineWrapper = new LambdaQueryWrapper<EquipmentStatus>()
+                .eq(EquipmentStatus::getOnlineStatus, OnlineStatusEnum.ONLINE.getCode());
+        LambdaQueryWrapper<EquipmentStatus> offlineWrapper = new LambdaQueryWrapper<EquipmentStatus>()
+                .eq(EquipmentStatus::getOnlineStatus, OnlineStatusEnum.OFFLINE.getCode());
+        LambdaQueryWrapper<EquipmentStatus> alarmWrapper = new LambdaQueryWrapper<EquipmentStatus>()
+                .eq(EquipmentStatus::getAlarmStatus, AlarmStatusEnum.ALARM.getCode());
+        if (allowedEquipmentIds != null) {
+            onlineWrapper.in(EquipmentStatus::getEquipmentId, allowedEquipmentIds.isEmpty() ? Collections.singleton("") : allowedEquipmentIds);
+            offlineWrapper.in(EquipmentStatus::getEquipmentId, allowedEquipmentIds.isEmpty() ? Collections.singleton("") : allowedEquipmentIds);
+            alarmWrapper.in(EquipmentStatus::getEquipmentId, allowedEquipmentIds.isEmpty() ? Collections.singleton("") : allowedEquipmentIds);
+        }
+        result.put("total", total);
+        result.put("online", this.count(onlineWrapper));
+        result.put("offline", this.count(offlineWrapper));
+        result.put("alarm", this.count(alarmWrapper));
+        return result;
+    }
+
+    @Override
+    public List<EquipmentStatus> listByRootType(Integer rootTypeId) {
+        Set<String> allowedEquipmentIds = resolveRootEquipmentIds(rootTypeId);
+        if (allowedEquipmentIds == null) {
+            return this.list();
+        }
+        if (allowedEquipmentIds.isEmpty()) {
+            return Collections.emptyList();
+        }
+        return this.list(new LambdaQueryWrapper<EquipmentStatus>()
+                .in(EquipmentStatus::getEquipmentId, allowedEquipmentIds));
+    }
+
+    /**
+     * 解析根设备类型范围内的设备ID集合;rootTypeId 为空时返回 null(不过滤),
+     * 根类型无效时抛出异常,范围内无设备时返回空集合。
+     */
+    private Set<String> resolveRootEquipmentIds(Integer rootTypeId) {
+        if (rootTypeId == null || rootTypeId <= 0) {
+            return null;
+        }
+        EquipmentTypeEnum rootEnum = EquipmentTypeEnum.getById(rootTypeId);
+        if (rootEnum == null || !rootEnum.isRoot()) {
+            throw new ServiceException("无效的设备根类型:" + rootTypeId);
+        }
+        List<String> childTypeIds = equipmentTypeMapper.selectList(new LambdaQueryWrapper<EquipmentType>()
+                        .eq(EquipmentType::getParentId, rootTypeId)).stream()
+                .map(EquipmentType::getId)
+                .filter(Objects::nonNull)
+                .map(String::valueOf)
+                .collect(Collectors.toList());
+        if (childTypeIds.isEmpty()) {
+            return Collections.emptySet();
+        }
+        return equipmentBaseMapper.selectList(new LambdaQueryWrapper<EquipmentBase>()
+                        .in(EquipmentBase::getEquipmentTypeId, childTypeIds)).stream()
+                .map(EquipmentBase::getEquipmentId)
+                .filter(Objects::nonNull)
+                .collect(Collectors.toSet());
+    }
+
     private boolean hasStateChange(EquipmentStatus oldStatus, EquipmentStatus patch) {
         if (oldStatus == null || patch == null) {
             return false;

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

@@ -1,286 +0,0 @@
-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.zksy.base.constant.GasEquipmentTypeEnum;
-import com.zksy.base.domain.*;
-import com.zksy.base.domain.vo.EquipmentFullVO;
-import com.zksy.base.mapper.*;
-import com.zksy.base.service.GasEquipmentService;
-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.function.Function;
-import java.util.stream.Collectors;
-
-@Slf4j
-@Service
-public class GasEquipmentServiceImpl implements GasEquipmentService {
-
-    @Autowired
-    private EquipmentBaseMapper equipmentBaseMapper;
-
-    @Autowired
-    private EquipmentTypeMapper equipmentTypeMapper;
-
-    @Autowired
-    private EquipmentMaintainMapper equipmentMaintainMapper;
-
-    @Autowired
-    private EquipmentStatusMapper equipmentStatusMapper;
-
-    @Autowired
-    private EquipmentPointRelMapper equipmentPointRelMapper;
-
-    @Autowired
-    private EquipmentTestMapper equipmentTestMapper;
-
-    @Autowired
-    private GasPipePointDeviceRelMapper gasPipePointDeviceRelMapper;
-
-    @Autowired
-    private GasPipePointMapper gasPipePointMapper;
-
-    @Autowired
-    private PipeNetworkBaseMapper pipeNetworkBaseMapper;
-
-    @Override
-    public boolean saveWithCheck(EquipmentBase entity) {
-        String equipmentTypeId = entity.getEquipmentTypeId();
-        EquipmentType equipmentType = equipmentTypeMapper.selectById(equipmentTypeId);
-        if (equipmentType == null) {
-            throw new ServiceException("设备类型不存在,请检查 equipment_type_id");
-        }
-            
-        // ========== 新增:根据片区自动生成设备编码 ==========
-        String district = entity.getDistrict();
-        if (district != null && !district.trim().isEmpty() && 
-            (entity.getEquipmentCode() == null || entity.getEquipmentCode().trim().isEmpty())) {
-            String prefix = getDistrictPrefix(district);
-                
-            // 查询该片区已存在的设备数量
-            LambdaQueryWrapper<EquipmentBase> codeWrapper = new LambdaQueryWrapper<>();
-            codeWrapper.likeRight(EquipmentBase::getEquipmentCode, prefix + "-GAS-");
-            Long count = equipmentBaseMapper.selectCount(codeWrapper);
-                
-            // 生成下一个序列号
-            String seq = String.format("%03d", count + 1);
-            entity.setEquipmentCode(prefix + "-GAS-" + seq);
-        }
-        // ===============================================
-            
-        // 检查唯一性
-        LambdaQueryWrapper<EquipmentBase> queryWrapper = new LambdaQueryWrapper<>();
-        queryWrapper.eq(EquipmentBase::getEquipmentCode, entity.getEquipmentCode());
-        long totalCount = equipmentBaseMapper.selectCount(queryWrapper);
-        if (totalCount > 0) {
-            throw new ServiceException("设备编码已存在,请更换:" + entity.getEquipmentCode());
-        }
-            
-        try {
-            return equipmentBaseMapper.insert(entity) > 0;
-        } catch (org.springframework.dao.DataIntegrityViolationException e) {
-            if (e.getMessage() != null && e.getMessage().contains("uk_equipment_code")) {
-                throw new ServiceException("设备编码已存在,请更换:" + entity.getEquipmentCode());
-            }
-            throw e;
-        }
-    }
-        
-    /**
-     * 获取片区前缀映射
-     */
-    private String getDistrictPrefix(String district) {
-        if ("城南".equals(district)) {
-            return "CN";
-        } else if ("城北".equals(district)) {
-            return "CB";
-        } else if ("太常".equals(district)) {
-            return "TC";
-        }
-        return "QT"; // 其他区域默认前缀
-    }
-
-    @Override
-    @Transactional
-    public boolean updateWithCheck(EquipmentBase entity) {
-        String equipmentId = entity.getEquipmentId();
-        if (equipmentBaseMapper.selectById(equipmentId) == null) {
-            throw new ServiceException("设备不存在,无法修改:" + equipmentId);
-        }
-
-        String newTypeId = entity.getEquipmentTypeId();
-        if (newTypeId != null && equipmentTypeMapper.selectById(newTypeId) == null) {
-            throw new ServiceException("设备类型不存在:" + newTypeId);
-        }
-
-        String newCode = entity.getEquipmentCode();
-        if (newCode != null) {
-            LambdaQueryWrapper<EquipmentBase> wrapper = new LambdaQueryWrapper<>();
-            wrapper.eq(EquipmentBase::getEquipmentCode, newCode)
-                    .ne(EquipmentBase::getEquipmentId, equipmentId);
-            if (equipmentBaseMapper.selectCount(wrapper) > 0) {
-                throw new ServiceException("设备编码已被使用:" + newCode);
-            }
-        }
-        return equipmentBaseMapper.updateById(entity) > 0;
-    }
-
-    @Override
-    @Transactional
-    public boolean removeWithCheck(String equipmentId) {
-        EquipmentBase equipment = equipmentBaseMapper.selectById(equipmentId);
-        if (equipment == null) {
-            throw new ServiceException("设备不存在:" + equipmentId);
-        }
-
-        LambdaQueryWrapper<EquipmentMaintain> maintainWrapper = new LambdaQueryWrapper<>();
-        maintainWrapper.eq(EquipmentMaintain::getEquipmentId, equipmentId);
-        equipmentMaintainMapper.delete(maintainWrapper);
-        log.info("已删除设备[{}]的维护记录", equipmentId);
-
-        LambdaQueryWrapper<EquipmentStatus> statusWrapper = new LambdaQueryWrapper<>();
-        statusWrapper.eq(EquipmentStatus::getEquipmentId, equipmentId);
-        equipmentStatusMapper.delete(statusWrapper);
-        log.info("已删除设备[{}]的状态记录", equipmentId);
-
-        LambdaQueryWrapper<EquipmentPointRel> relWrapper = new LambdaQueryWrapper<>();
-        relWrapper.eq(EquipmentPointRel::getEquipmentId, equipmentId);
-        equipmentPointRelMapper.delete(relWrapper);
-        log.info("已删除设备[{}]的监测点关联", equipmentId);
-
-        LambdaQueryWrapper<EquipmentTest> testWrapper = new LambdaQueryWrapper<>();
-        testWrapper.eq(EquipmentTest::getEquipmentId, equipmentId);
-        equipmentTestMapper.delete(testWrapper);
-        log.info("已删除设备[{}]的测试记录", equipmentId);
-
-        return equipmentBaseMapper.deleteById(equipmentId) > 0;
-    }
-
-    @Override
-    public Page<EquipmentFullVO> findFullByPage(long pageNum, long pageSize,
-                                                 String equipmentCode, String equipmentName,
-                                                 String equipmentModel, String manufacturer,String district) {
-        // 只查燃气类型设备:parent_id = 燃气根节点主键
-        List<String> gasTypeIds = equipmentTypeMapper.selectList(
-                new LambdaQueryWrapper<EquipmentType>().eq(EquipmentType::getParentId, GasEquipmentTypeEnum.parent_id)
-        ).stream().map(type -> String.valueOf(type.getId())).collect(Collectors.toList());
-
-        Page<EquipmentBase> page = new Page<>(pageNum, pageSize);
-        LambdaQueryWrapper<EquipmentBase> qw = new LambdaQueryWrapper<>();
-        if (!gasTypeIds.isEmpty()) {
-            qw.in(EquipmentBase::getEquipmentTypeId, gasTypeIds);
-        }
-        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);
-        }
-        // 添加片区筛选条件
-        if (district != null && !district.isEmpty()) {
-            qw.eq(EquipmentBase::getDistrict, district);
-        }
-        qw.orderByDesc(EquipmentBase::getCreateTime);
-        Page<EquipmentBase> basePage = equipmentBaseMapper.selectPage(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. 批量查管点-设备关联
-        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());
-            } else {
-                vo.setCurrentStatus(1);
-                vo.setAlarmStatus(0);
-                vo.setOnlineStatus(0);
-            }
-
-            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;
-    }
-}

+ 4 - 648
pipe-network-service/zksy-system/src/main/java/com/zksy/base/service/impl/WaterSupplyDeviceServiceImpl.java

@@ -4,7 +4,6 @@ import cn.hutool.core.bean.BeanUtil;
 import cn.hutool.core.collection.CollUtil;
 import cn.hutool.core.util.StrUtil;
 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.alarm.domain.AlarmData;
 import com.zksy.base.alarm.mapper.AlarmDataMapper;
@@ -16,10 +15,8 @@ import com.zksy.base.domain.EquipmentStatus;
 import com.zksy.base.domain.EquipmentType;
 import com.zksy.ops.domain.WorkOrder;
 import com.zksy.base.domain.vo.*;
-import com.zksy.base.event.DeviceStatusChangePublisher;
 import com.zksy.base.environment.domain.ERealTimeData;
 import com.zksy.ops.enums.WorkOrderStatusEnum;
-import com.zksy.ops.dto.WorkOrderDispatchDTO;
 import com.zksy.base.environment.mapper.ERealTimeDataMapper;
 import com.zksy.base.gas.domain.GasMonitorData;
 import com.zksy.base.gas.mapper.GasMonitorDataMapper;
@@ -38,22 +35,22 @@ import com.zksy.base.telemetry.domain.TelemetryData;
 import com.zksy.base.telemetry.mapper.TelemetryDataMapper;
 import com.zksy.base.water.domain.WaterMonitorData;
 import com.zksy.base.water.mapper.WaterMonitorDataMapper;
-import com.zksy.common.sms.SmsTemplate;
 import com.zksy.common.core.domain.entity.SysUser;
-import com.zksy.common.utils.SecurityUtils;
-import com.zksy.ops.service.WorkOrderService;
 import com.zksy.system.service.ISysUserService;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Service;
-import org.springframework.transaction.annotation.Transactional;
 
 import java.math.BigDecimal;
 import java.time.LocalDateTime;
 import java.util.*;
 import java.util.stream.Collectors;
 
+/**
+ * 供水设备 GIS 一张图支撑服务实现。
+ * 设备台账管理已统一迁移至 EquipmentBaseService / 设备台账总页(subSystem/pipeNetwork/pdeviceInform/index)。
+ */
 @Slf4j
 @Service
 public class WaterSupplyDeviceServiceImpl extends ServiceImpl<EquipmentBaseMapper, EquipmentBase>
@@ -65,9 +62,6 @@ public class WaterSupplyDeviceServiceImpl extends ServiceImpl<EquipmentBaseMappe
     @Autowired
     private EquipmentStatusMapper equipmentStatusMapper;
 
-    @Autowired
-    private DeviceStatusChangePublisher deviceStatusChangePublisher;
-
     @Autowired
     private EquipmentMaintainMapper equipmentMaintainMapper;
 
@@ -101,18 +95,12 @@ public class WaterSupplyDeviceServiceImpl extends ServiceImpl<EquipmentBaseMappe
     @Autowired
     private WorkOrderMapper workOrderMapper;
 
-    @Autowired
-    private WorkOrderService businessWorkOrderService;
-
     @Autowired
     private ISysUserService sysUserService;
 
     @Value("${waterSupply.device.top-level-type:供水}")
     private String waterTopLevelTypeName = "供水";
 
-    @Autowired(required = false)
-    private SmsTemplate smsTemplate;
-
     @Override
     public List<DeviceTypeStatisticsVO> getDeviceTypeStatistics() {
         List<EquipmentBase> waterDevices = findWaterDevices();
@@ -181,168 +169,6 @@ public class WaterSupplyDeviceServiceImpl extends ServiceImpl<EquipmentBaseMappe
         return total;
     }
 
-    @Override
-    public DeviceLedgerStatisticsVO getDeviceLedgerStatistics() {
-        List<EquipmentBase> devices = findWaterDevices();
-        DeviceLedgerStatisticsVO stats = new DeviceLedgerStatisticsVO();
-        stats.setTotal(devices.size());
-        stats.setOnline(0);
-        stats.setOffline(devices.size());
-        stats.setOnlineRate(0.0);
-        if (CollUtil.isEmpty(devices)) {
-            return stats;
-        }
-        Map<String, EquipmentStatus> statusMap = getStatusMap(devices.stream()
-                .map(EquipmentBase::getEquipmentId)
-                .collect(Collectors.toList()));
-        int onlineCount = (int) devices.stream()
-                .map(device -> statusMap.get(device.getEquipmentId()))
-                .filter(Objects::nonNull)
-                .filter(status -> Integer.valueOf(1).equals(status.getOnlineStatus()))
-                .count();
-        stats.setOnline(onlineCount);
-        stats.setOffline(devices.size() - onlineCount);
-        stats.setOnlineRate(Math.round(onlineCount * 1000.0 / devices.size()) / 10.0);
-        return stats;
-    }
-
-
-    @Override
-    public Page<DeviceGisVO> getDeviceLedgerPage(long pageNum, long pageSize,
-                                                  String equipmentName, String equipmentCode,
-                                                  String equipmentTypeId, Integer status,
-                                                  Integer alarmStatus, Integer alertLevel) {
-        List<EquipmentBase> waterDevices = findWaterDevices();
-        if (CollUtil.isEmpty(waterDevices)) {
-            return emptyPage(pageNum, pageSize);
-        }
-
-        Map<String, EquipmentStatus> statusMap = status != null || alarmStatus != null || alertLevel != null
-                ? getStatusMap(waterDevices.stream().map(EquipmentBase::getEquipmentId).collect(Collectors.toList()))
-                : new HashMap<>();
-        final Map<String, EquipmentStatus> filterStatusMap = statusMap;
-        Map<String, AlarmData> alarmMap = alertLevel != null ? getActiveAlarmMap(waterDevices) : new HashMap<>();
-
-        List<EquipmentBase> records = waterDevices.stream()
-                .filter(device -> matchesLedgerFilters(device, equipmentName, equipmentCode, equipmentTypeId))
-                .filter(device -> status == null || status.equals(Optional.ofNullable(filterStatusMap
-                        .get(device.getEquipmentId())).map(EquipmentStatus::getCurrentStatus).orElse(null)))
-                .filter(device -> alarmStatus == null || alarmStatus.equals(Optional.ofNullable(filterStatusMap
-                        .get(device.getEquipmentId())).map(EquipmentStatus::getAlarmStatus).orElse(null)))
-                .filter(device -> alertLevel == null || alertLevel.equals(resolveAlertLevel(device,
-                        filterStatusMap.get(device.getEquipmentId()), alarmMap)))
-                .sorted(Comparator.comparing(EquipmentBase::getCreateTime,
-                        Comparator.nullsLast(Comparator.reverseOrder())))
-                .collect(Collectors.toList());
-
-        Page<EquipmentBase> basePage = paginate(records, pageNum, pageSize);
-        Page<DeviceGisVO> resultPage = new Page<>(pageNum, pageSize, basePage.getTotal());
-        if (CollUtil.isEmpty(basePage.getRecords())) {
-            resultPage.setRecords(new ArrayList<>());
-            return resultPage;
-        }
-
-        records = basePage.getRecords();
-        List<String> equipmentIds = records.stream().map(EquipmentBase::getEquipmentId).collect(Collectors.toList());
-
-        if (status == null && alarmStatus == null && alertLevel == null) {
-            statusMap = getStatusMap(equipmentIds);
-        }
-        Map<String, AlarmData> displayAlarmMap = CollUtil.isEmpty(alarmMap)
-                ? getActiveAlarmMap(records)
-                : alarmMap;
-        Map<String, EquipmentType> typeMap = getTypeMap(records);
-
-        List<DeviceGisVO> voList = new ArrayList<>();
-        for (EquipmentBase base : records) {
-            DeviceGisVO vo = BeanUtil.copyProperties(base, DeviceGisVO.class);
-            EquipmentStatus es = statusMap.get(base.getEquipmentId());
-            if (es != null) {
-                vo.setOnlineStatus(es.getOnlineStatus());
-                vo.setAlarmStatus(es.getAlarmStatus());
-                vo.setCurrentStatus(es.getCurrentStatus());
-            }
-            AlarmData alarm = displayAlarmMap.get(base.getEquipmentCode());
-            if (alarm != null) {
-                vo.setAlertLevel(alarm.getAlarmLevel());
-            }
-            EquipmentType et = typeMap.get(base.getEquipmentTypeId());
-            if (et != null) {
-                vo.setEquipmentTypeName(et.getTypeName());
-            }
-            fillGpsFields(vo, base.getLongitude(), base.getLatitude());
-            voList.add(vo);
-        }
-        resultPage.setRecords(voList);
-        return resultPage;
-    }
-
-    @Override
-    public List<DeviceGisVO> getDeviceLedgerExport(String equipmentName, String equipmentCode,
-                                                    String equipmentTypeId, Integer status,
-                                                    Integer alarmStatus, Integer alertLevel) {
-        return getDeviceLedgerPage(1, Integer.MAX_VALUE, equipmentName, equipmentCode,
-                equipmentTypeId, status, alarmStatus, alertLevel).getRecords();
-    }
-
-    @Override
-    @Transactional
-    public boolean createWaterDevice(EquipmentBase device) {
-        if (device == null || StrUtil.isBlank(device.getEquipmentCode())) {
-            throw new IllegalArgumentException("设备编码不能为空");
-        }
-        if (StrUtil.isBlank(device.getEquipmentTypeId())) {
-            throw new IllegalArgumentException("设备类型不能为空");
-        }
-        EquipmentType type = equipmentTypeMapper.selectById(device.getEquipmentTypeId());
-        if (type == null || !isWaterTypeRecord(type)) {
-            throw new IllegalArgumentException("设备类型不属于供水:" + device.getEquipmentTypeId());
-        }
-        LambdaQueryWrapper<EquipmentBase> wrapper = new LambdaQueryWrapper<>();
-        wrapper.eq(EquipmentBase::getEquipmentCode, device.getEquipmentCode());
-        if (this.count(wrapper) > 0) {
-            throw new IllegalArgumentException("设备编码已存在:" + device.getEquipmentCode());
-        }
-        LocalDateTime now = LocalDateTime.now();
-        device.setEquipmentId(null);
-        device.setCreateTime(now);
-        device.setUpdateTime(now);
-        return save(device);
-    }
-
-    @Override
-    @Transactional
-    public boolean deleteWaterDevices(List<String> equipmentIds) {
-        if (CollUtil.isEmpty(equipmentIds)) {
-            throw new IllegalArgumentException("设备ID列表不能为空");
-        }
-        List<String> invalidIds = equipmentIds.stream()
-                .filter(equipmentId -> findWaterDeviceById(equipmentId) == null)
-                .collect(Collectors.toList());
-        if (!invalidIds.isEmpty()) {
-            throw new IllegalArgumentException("存在非供水设备,无法删除:" + String.join(",", invalidIds));
-        }
-        return equipmentBaseService.removeBatchWithCheck(equipmentIds);
-    }
-
-    private boolean isWaterTypeRecord(EquipmentType type) {
-        List<EquipmentType> allTypes = equipmentTypeMapper.selectList(new LambdaQueryWrapper<EquipmentType>());
-        Map<String, EquipmentType> typesById = new HashMap<>();
-        for (EquipmentType item : allTypes) {
-            typesById.putIfAbsent(String.valueOf(item.getId()), item);
-        }
-        EquipmentType cursor = type;
-        int guard = 0;
-        while (cursor != null && guard++ <= typesById.size()) {
-            if (waterTopLevelTypeName.equals(cursor.getTypeName())
-                    && Integer.valueOf(0).equals(cursor.getParentId())) {
-                return true;
-            }
-            cursor = typesById.get(String.valueOf(cursor.getParentId()));
-        }
-        return false;
-    }
-
     @Override
     public List<DeviceGisVO> getAllDeviceGisPoints(String equipmentTypeId) {
         List<EquipmentBase> list = findWaterDevices().stream()
@@ -445,290 +271,6 @@ public class WaterSupplyDeviceServiceImpl extends ServiceImpl<EquipmentBaseMappe
         return vo;
     }
 
-    @Override
-    @Transactional(rollbackFor = Exception.class)
-    @Deprecated
-    public boolean createMaintainOrder(MaintainOrderVO vo) {
-        // Keep the legacy service signature for binary compatibility, but route it
-        // through the same unified WorkOrder lifecycle as the current endpoint.
-        WorkOrder workOrder = createAbnormalWorkOrder(vo);
-        if (workOrder == null || workOrder.getOrderId() == null) {
-            return false;
-        }
-        if (vo.getReceiveUserId() == null) {
-            return true;
-        }
-        WorkOrderDispatchDTO dispatchDTO = new WorkOrderDispatchDTO();
-        dispatchDTO.setHandlerId(vo.getReceiveUserId());
-        dispatchDTO.setRemarks(vo.getMaintainRemark());
-        return businessWorkOrderService.dispatch(workOrder.getOrderId(), dispatchDTO);
-    }
-
-    private Long currentUserIdOrNull() {
-        try {
-            return SecurityUtils.getUserId();
-        } catch (Exception e) {
-            return null;
-        }
-    }
-
-    private String currentUserNameOrNull() {
-        try {
-            return SecurityUtils.getUsername();
-        } catch (Exception e) {
-            return null;
-        }
-    }
-
-    @Override
-    @Transactional(rollbackFor = Exception.class)
-    public WorkOrder createAbnormalWorkOrder(MaintainOrderVO vo) {
-        if (vo == null || StrUtil.isBlank(vo.getEquipmentId())) {
-            throw new RuntimeException("设备ID不能为空");
-        }
-        EquipmentBase device = findWaterDeviceById(vo.getEquipmentId());
-        if (device == null) {
-            throw new RuntimeException("仅支持供水设备派发维修工单");
-        }
-        if (getLatestWorkOrderMap(Collections.singletonList(device)).containsKey(device.getEquipmentId())) {
-            throw new RuntimeException("该设备已有未结束故障维修工单,不能重复创建");
-        }
-        WorkOrder workOrder = new WorkOrder();
-        workOrder.setDeviceId(device.getEquipmentId());
-        workOrder.setDeviceCode(device.getEquipmentCode());
-        workOrder.setOrderLevel(vo.getOrderLevel() == null ? 1 : vo.getOrderLevel());
-        workOrder.setOrderDesc(StrUtil.isNotBlank(vo.getFaultDescription()) ? vo.getFaultDescription() : vo.getMaintainContent());
-        Long orderId = businessWorkOrderService.createWorkOrder(workOrder);
-        workOrder.setOrderId(orderId);
-        return workOrder;
-    }
-
-    private void publishEquipmentStatusChange(EquipmentBase equipment, EquipmentStatus status, String source) {
-        if (equipment == null || status == null || StrUtil.isBlank(equipment.getEquipmentCode())) {
-            return;
-        }
-        deviceStatusChangePublisher.publishAfterCommit(equipment.getEquipmentCode(),
-                status.getEquipmentId(), status.getCurrentStatus(), status.getAlarmStatus(),
-                status.getOnlineStatus(), source);
-    }
-
-    private void sendMaintainSmsNotify(EquipmentBase device, EquipmentMaintain maintain) {
-        try {
-            if (smsTemplate == null) {
-                log.debug("短信服务未注入,跳过维修派单短信通知");
-                return;
-            }
-            String phone = null;
-            if (maintain.getMaintainPersonPhone() != null) {
-                phone = String.valueOf(maintain.getMaintainPersonPhone());
-            } else if (device.getMaintainerPhone() != null) {
-                phone = device.getMaintainerPhone();
-            }
-            if (StrUtil.isBlank(phone)) {
-                log.warn("维修派单短信通知失败:无维修人手机号,设备={}", device.getEquipmentId());
-                return;
-            }
-
-            Map<String, Boolean> result = smsTemplate.sendMaintainNotify(
-                    Collections.singletonList(phone),
-                    device.getEquipmentName(),
-                    device.getEquipmentCode(),
-                    device.getEquipmentLocation(),
-                    maintain.getMaintainContent()
-            );
-            boolean success = result.values().stream().anyMatch(Boolean::booleanValue);
-            log.info("维修派单短信通知结果:设备={}, 维修人={}, 电话={}, 成功={}",
-                    device.getEquipmentId(), maintain.getMaintainPerson(), phone, success);
-        } catch (Exception e) {
-            log.warn("维修派单短信通知异常:{}", e.getMessage());
-        }
-    }
-
-    @Override
-    public Page<AbnormalDeviceVO> getAbnormalDevicePage(long pageNum, long pageSize,
-                                                         String equipmentName, String equipmentCode,
-                                                         String equipmentTypeId, Integer alertLevel) {
-        return getAbnormalDevicePage(pageNum, pageSize, equipmentName, equipmentCode,
-                equipmentTypeId, alertLevel, false);
-    }
-
-    @Override
-    public Page<AbnormalDeviceVO> getAbnormalDevicePage(long pageNum, long pageSize,
-                                                         String equipmentName, String equipmentCode,
-                                                         String equipmentTypeId, Integer alertLevel,
-                                                         Boolean dispatchableOnly) {
-        return queryAbnormalDevices(pageNum, pageSize, equipmentName, equipmentCode,
-                equipmentTypeId, alertLevel, null, null, dispatchableOnly);
-    }
-
-    @Override
-    public Page<AbnormalDeviceVO> getAbnormalDevicePage(long pageNum, long pageSize,
-                                                         String equipmentName, String equipmentCode,
-                                                         String equipmentTypeId, Integer alertLevel,
-                                                         String abnormalType, String region) {
-        return queryAbnormalDevices(pageNum, pageSize, equipmentName, equipmentCode,
-                equipmentTypeId, alertLevel, abnormalType, region, false);
-    }
-
-    @Override
-    public Page<AbnormalDeviceVO> getAbnormalDevicePage(long pageNum, long pageSize,
-                                                         String equipmentName, String equipmentCode,
-                                                         String equipmentTypeId, Integer alertLevel,
-                                                         String abnormalType, String region,
-                                                         Boolean dispatchableOnly) {
-        return queryAbnormalDevices(pageNum, pageSize, equipmentName, equipmentCode,
-                equipmentTypeId, alertLevel, abnormalType, region, dispatchableOnly);
-    }
-
-    @Override
-    public DeviceAbnormalStatsVO getAbnormalDeviceStats() {
-        List<EquipmentBase> waterDevices = findWaterDevices();
-        DeviceAbnormalStatsVO stats = new DeviceAbnormalStatsVO();
-        stats.setTotal(0);
-        stats.setAlarm(0);
-        stats.setRepair(0);
-        stats.setOffline(0);
-        if (CollUtil.isEmpty(waterDevices)) {
-            return stats;
-        }
-
-        Map<String, EquipmentStatus> statusMap = getStatusMap(waterDevices.stream()
-                .map(EquipmentBase::getEquipmentId)
-                .collect(Collectors.toList()));
-        Map<String, AlarmData> activeAlarmMap = getActiveAlarmMap(waterDevices);
-
-        int total = 0;
-        int alarm = 0;
-        int repair = 0;
-        int offline = 0;
-        for (EquipmentBase device : waterDevices) {
-            EquipmentStatus status = statusMap.get(device.getEquipmentId());
-            boolean alarmAbnormal = status != null && Objects.equals(status.getAlarmStatus(), 1)
-                    || (status == null && activeAlarmMap.containsKey(device.getEquipmentCode()));
-            boolean repairAbnormal = status != null && Objects.equals(status.getCurrentStatus(), 3);
-            boolean offlineAbnormal = status != null && Objects.equals(status.getOnlineStatus(), 0);
-            if (alarmAbnormal) {
-                alarm++;
-            }
-            if (repairAbnormal) {
-                repair++;
-            }
-            if (offlineAbnormal) {
-                offline++;
-            }
-            if (alarmAbnormal || repairAbnormal || offlineAbnormal) {
-                total++;
-            }
-        }
-        stats.setTotal(total);
-        stats.setAlarm(alarm);
-        stats.setRepair(repair);
-        stats.setOffline(offline);
-        return stats;
-    }
-
-    private Page<AbnormalDeviceVO> queryAbnormalDevices(long pageNum, long pageSize,
-                                                         String equipmentName, String equipmentCode,
-                                                         String equipmentTypeId, Integer alertLevel,
-                                                         String abnormalType, String region,
-                                                         Boolean dispatchableOnly) {
-        List<EquipmentBase> waterDevices = findWaterDevices();
-        if (CollUtil.isEmpty(waterDevices)) {
-            return emptyAbnormalPage(pageNum, pageSize, 0);
-        }
-
-        LambdaQueryWrapper<EquipmentStatus> statusWrapper = new LambdaQueryWrapper<>();
-        statusWrapper.and(w -> w.eq(EquipmentStatus::getAlarmStatus, 1)
-                .or().eq(EquipmentStatus::getCurrentStatus, 3));
-
-        List<EquipmentStatus> allAbnormalStatus = equipmentStatusMapper.selectList(statusWrapper);
-        Map<String, EquipmentStatus> statusMap = allAbnormalStatus.stream()
-                .collect(Collectors.toMap(EquipmentStatus::getEquipmentId, s -> s, (a, b) -> a));
-
-        Map<String, AlarmData> activeAlarmMap = getActiveAlarmMap(waterDevices);
-        List<EquipmentBase> allDevices = waterDevices.stream()
-                .filter(device -> {
-                    EquipmentStatus status = statusMap.get(device.getEquipmentId());
-                    if (status == null) {
-                        return activeAlarmMap.containsKey(device.getEquipmentCode());
-                    }
-                    return Objects.equals(status.getAlarmStatus(), 1)
-                            || Objects.equals(status.getCurrentStatus(), 3);
-                })
-                .filter(device -> matchesLedgerFilters(device, equipmentName, equipmentCode, equipmentTypeId))
-                .filter(device -> matchesAbnormalType(device, statusMap.get(device.getEquipmentId()),
-                        activeAlarmMap, abnormalType))
-                .filter(device -> StrUtil.isBlank(region) || region.equals(device.getDistrict()))
-                .collect(Collectors.toList());
-
-        Map<String, AlarmData> alarmMap = activeAlarmMap;
-        Map<String, WorkOrder> workOrderMap = getLatestWorkOrderMap(allDevices);
-        Map<String, EquipmentMaintain> maintainMap = getLatestMaintainMap(
-                allDevices.stream().map(EquipmentBase::getEquipmentId).collect(Collectors.toList())
-        );
-
-        List<EquipmentBase> filteredDevices = allDevices.stream()
-                .filter(device -> !Boolean.TRUE.equals(dispatchableOnly)
-                        || !workOrderMap.containsKey(device.getEquipmentId()))
-                .filter(device -> alertLevel == null
-                        || alertLevel.equals(resolveAlertLevel(device, statusMap.get(device.getEquipmentId()), alarmMap)))
-                .collect(Collectors.toList());
-        if (CollUtil.isEmpty(filteredDevices)) {
-            return emptyAbnormalPage(pageNum, pageSize, filteredDevices.size());
-        }
-
-        Page<EquipmentBase> basePage = paginate(filteredDevices, pageNum, pageSize);
-        List<EquipmentBase> pageDevices = basePage.getRecords();
-        Map<String, EquipmentType> typeMap = getTypeMap(pageDevices);
-
-        List<AbnormalDeviceVO> voList = new ArrayList<>();
-        for (EquipmentBase base : pageDevices) {
-            AbnormalDeviceVO vo = BeanUtil.copyProperties(base, AbnormalDeviceVO.class);
-            fillAbnormalDeviceVO(vo, base, statusMap.get(base.getEquipmentId()),
-                    typeMap.get(base.getEquipmentTypeId()), alarmMap.get(base.getEquipmentCode()),
-                    workOrderMap.get(base.getEquipmentId()), maintainMap.get(base.getEquipmentId()));
-            voList.add(vo);
-        }
-
-        Page<AbnormalDeviceVO> resultPage = new Page<>(pageNum, pageSize, basePage.getTotal());
-        resultPage.setRecords(voList);
-        return resultPage;
-    }
-
-    @Override
-    public List<AbnormalDeviceVO> getAbnormalDeviceExport(String equipmentName, String equipmentCode,
-                                                           String equipmentTypeId, Integer alertLevel) {
-        return getAbnormalDeviceExport(equipmentName, equipmentCode,
-                equipmentTypeId, alertLevel, null, null);
-    }
-
-    @Override
-    public List<AbnormalDeviceVO> getAbnormalDeviceExport(String equipmentName, String equipmentCode,
-                                                           String equipmentTypeId, Integer alertLevel,
-                                                           String abnormalType, String region) {
-        return queryAbnormalDevices(1, Integer.MAX_VALUE, equipmentName, equipmentCode,
-                equipmentTypeId, alertLevel, abnormalType, region, false).getRecords();
-    }
-
-    private boolean matchesAbnormalType(EquipmentBase device, EquipmentStatus status,
-                                        Map<String, AlarmData> activeAlarmMap, String abnormalType) {
-        if (StrUtil.isBlank(abnormalType)) {
-            return true;
-        }
-        boolean alarmAbnormal = status != null && Objects.equals(status.getAlarmStatus(), 1)
-                || (status == null && activeAlarmMap.containsKey(device.getEquipmentCode()));
-        if ("alarm".equals(abnormalType)) {
-            return alarmAbnormal;
-        }
-        if ("repair".equals(abnormalType)) {
-            return status != null && Objects.equals(status.getCurrentStatus(), 3);
-        }
-        if ("offline".equals(abnormalType)) {
-            return status != null && Objects.equals(status.getOnlineStatus(), 0);
-        }
-        return false;
-    }
-
     @Override
     public List<AbnormalDeviceVO> getAbnormalDeviceGisPoints(String equipmentTypeId) {
         List<EquipmentBase> ownedDevices = findWaterDevices();
@@ -774,137 +316,6 @@ public class WaterSupplyDeviceServiceImpl extends ServiceImpl<EquipmentBaseMappe
         return result;
     }
 
-    @Override
-    public List<Map<String, Object>> getMaintainRecordList(String equipmentId) {
-        if (findWaterDeviceById(equipmentId) == null) {
-            return new ArrayList<>();
-        }
-        List<EquipmentMaintain> list = equipmentMaintainMapper.selectList(
-                new LambdaQueryWrapper<EquipmentMaintain>()
-                        .eq(EquipmentMaintain::getEquipmentId, equipmentId)
-                        .orderByDesc(EquipmentMaintain::getMaintainDate)
-        );
-        List<Map<String, Object>> result = new ArrayList<>();
-        for (EquipmentMaintain m : list) {
-            Map<String, Object> map = new HashMap<>();
-            map.put("maintainId", m.getMaintainId());
-            map.put("maintainType", m.getMaintainType());
-            map.put("maintainContent", m.getMaintainContent());
-            map.put("maintainPerson", m.getMaintainPerson());
-            map.put("maintainDate", m.getMaintainDate());
-            map.put("maintainCost", m.getMaintainCost());
-            map.put("maintainRemark", m.getMaintainRemark());
-            result.add(map);
-        }
-        return result;
-    }
-
-    @Override
-    @Transactional(rollbackFor = Exception.class)
-    public boolean saveMaintainRecord(EquipmentMaintainDataVO vo) {
-        if (StrUtil.isBlank(vo.getEquipmentId())) {
-            throw new RuntimeException("设备ID不能为空");
-        }
-        EquipmentBase device = findWaterDeviceById(vo.getEquipmentId());
-        if (device == null) {
-            throw new RuntimeException("仅支持供水设备维护记录");
-        }
-        EquipmentMaintain maintain = BeanUtil.copyProperties(vo, EquipmentMaintain.class);
-        return equipmentMaintainMapper.insert(maintain) > 0;
-    }
-
-    @Override
-    @Transactional(rollbackFor = Exception.class)
-    public boolean updateMaintainRecord(EquipmentMaintainDataVO vo) {
-        if (StrUtil.isBlank(vo.getMaintainId())) {
-            throw new RuntimeException("维护记录ID不能为空");
-        }
-        EquipmentMaintain existing = equipmentMaintainMapper.selectById(vo.getMaintainId());
-        if (existing == null) {
-            return false;
-        }
-        if (findWaterDeviceById(existing.getEquipmentId()) == null
-                || (StrUtil.isNotBlank(vo.getEquipmentId())
-                && !vo.getEquipmentId().equals(existing.getEquipmentId()))) {
-            throw new RuntimeException("仅支持供水设备维护记录");
-        }
-        EquipmentMaintain maintain = BeanUtil.copyProperties(vo, EquipmentMaintain.class);
-        maintain.setEquipmentId(existing.getEquipmentId());
-        return equipmentMaintainMapper.updateById(maintain) > 0;
-    }
-
-    @Override
-    @Transactional(rollbackFor = Exception.class)
-    public boolean deleteMaintainRecord(String maintainId) {
-        EquipmentMaintain existing = equipmentMaintainMapper.selectById(maintainId);
-        if (existing == null) {
-            return false;
-        }
-        if (findWaterDeviceById(existing.getEquipmentId()) == null) {
-            throw new RuntimeException("仅支持供水设备维护记录");
-        }
-        return equipmentMaintainMapper.deleteById(maintainId) > 0;
-    }
-
-    @Override
-    public Page<EquipmentMaintainDataVO> getMaintainRecordPage(long pageNum, long pageSize,
-                                                                String equipmentName, String maintainPerson,
-                                                                String maintainType, String status,
-                                                                String startTime, String endTime) {
-        LambdaQueryWrapper<EquipmentMaintain> wrapper = maintainRecordWrapper(maintainPerson, maintainType);
-        return buildMaintainRecordPage(equipmentMaintainMapper.selectList(wrapper),
-                pageNum, pageSize, equipmentName);
-    }
-
-    @Override
-    public Page<EquipmentMaintainDataVO> getMyMaintainRecordPage(long pageNum, long pageSize,
-                                                                   String maintainPerson,
-                                                                   String maintainType, String status,
-                                                                   String startTime, String endTime) {
-        LambdaQueryWrapper<EquipmentMaintain> wrapper = maintainRecordWrapper(maintainPerson, maintainType);
-        return buildMaintainRecordPage(equipmentMaintainMapper.selectList(wrapper),
-                pageNum, pageSize, null);
-    }
-
-    private LambdaQueryWrapper<EquipmentMaintain> maintainRecordWrapper(String maintainPerson,
-                                                                        String maintainType) {
-        LambdaQueryWrapper<EquipmentMaintain> wrapper = new LambdaQueryWrapper<>();
-        wrapper.like(StrUtil.isNotBlank(maintainPerson), EquipmentMaintain::getMaintainPerson, maintainPerson)
-                .eq(StrUtil.isNotBlank(maintainType), EquipmentMaintain::getMaintainType, maintainType)
-                .orderByDesc(EquipmentMaintain::getMaintainDate);
-        return wrapper;
-    }
-
-    private Page<EquipmentMaintainDataVO> buildMaintainRecordPage(List<EquipmentMaintain> records,
-                                                                  long pageNum, long pageSize,
-                                                                  String equipmentName) {
-        Map<String, EquipmentBase> deviceMap = findWaterDevices().stream()
-                .collect(Collectors.toMap(EquipmentBase::getEquipmentId, device -> device, (left, right) -> left));
-        List<EquipmentMaintain> ownedRecords = records == null ? Collections.emptyList() : records.stream()
-                .filter(record -> deviceMap.containsKey(record.getEquipmentId()))
-                .filter(record -> StrUtil.isBlank(equipmentName) || Optional.ofNullable(deviceMap.get(record.getEquipmentId()))
-                        .map(EquipmentBase::getEquipmentName)
-                        .map(name -> name.contains(equipmentName))
-                        .orElse(false))
-                .collect(Collectors.toList());
-
-        Page<EquipmentMaintain> maintainPage = paginate(ownedRecords, pageNum, pageSize);
-        Page<EquipmentMaintainDataVO> resultPage = new Page<>(pageNum, pageSize, maintainPage.getTotal());
-        List<EquipmentMaintainDataVO> voList = new ArrayList<>();
-        for (EquipmentMaintain m : maintainPage.getRecords()) {
-            EquipmentMaintainDataVO vo = BeanUtil.copyProperties(m, EquipmentMaintainDataVO.class);
-            EquipmentBase device = deviceMap.get(m.getEquipmentId());
-            vo.setEquipmentCode(device.getEquipmentCode());
-            vo.setEquipmentName(device.getEquipmentName());
-            vo.setEquipmentLocation(device.getEquipmentLocation());
-            vo.setLongitude(device.getLongitude());
-            vo.setLatitude(device.getLatitude());
-            voList.add(vo);
-        }
-        resultPage.setRecords(voList);
-        return resultPage;
-    }
-
     private List<EquipmentBase> findWaterDevices() {
         return equipmentBaseService.findByTopLevelType(waterTopLevelTypeName);
     }
@@ -956,39 +367,6 @@ public class WaterSupplyDeviceServiceImpl extends ServiceImpl<EquipmentBaseMappe
         }
     }
 
-    private boolean matchesLedgerFilters(EquipmentBase device, String equipmentName,
-                                         String equipmentCode, String equipmentTypeId) {
-        return (StrUtil.isBlank(equipmentName)
-                || (device.getEquipmentName() != null && device.getEquipmentName().contains(equipmentName)))
-                && (StrUtil.isBlank(equipmentCode)
-                || (device.getEquipmentCode() != null && device.getEquipmentCode().contains(equipmentCode)))
-                && (StrUtil.isBlank(equipmentTypeId) || equipmentTypeId.equals(device.getEquipmentTypeId()));
-    }
-
-    private <T> Page<T> paginate(List<T> records, long pageNum, long pageSize) {
-        Page<T> page = new Page<>(pageNum, pageSize, records.size());
-        if (pageNum < 1 || pageSize < 1) {
-            page.setRecords(new ArrayList<>());
-            return page;
-        }
-        int fromIndex = (int) Math.min((pageNum - 1) * pageSize, records.size());
-        int toIndex = (int) Math.min(fromIndex + pageSize, records.size());
-        page.setRecords(new ArrayList<>(records.subList(fromIndex, toIndex)));
-        return page;
-    }
-
-    private Page<DeviceGisVO> emptyPage(long pageNum, long pageSize) {
-        Page<DeviceGisVO> page = new Page<>(pageNum, pageSize, 0);
-        page.setRecords(new ArrayList<>());
-        return page;
-    }
-
-    private Page<AbnormalDeviceVO> emptyAbnormalPage(long pageNum, long pageSize, long total) {
-        Page<AbnormalDeviceVO> page = new Page<>(pageNum, pageSize, total);
-        page.setRecords(new ArrayList<>());
-        return page;
-    }
-
     private Map<String, AlarmData> getActiveAlarmMap(List<EquipmentBase> devices) {
         if (CollUtil.isEmpty(devices)) {
             return new HashMap<>();
@@ -1297,28 +675,6 @@ public class WaterSupplyDeviceServiceImpl extends ServiceImpl<EquipmentBaseMappe
         return result;
     }
 
-    private Integer calcAlertLevel(String deviceCode, EquipmentStatus status) {
-        if (status == null || status.getAlarmStatus() == null || status.getAlarmStatus() == 0) {
-            return null;
-        }
-        int maxLevel = 4;
-        try {
-            List<com.zksy.base.alarm.domain.AlarmData> alarms = alarmDataMapper.selectList(
-                    new LambdaQueryWrapper<com.zksy.base.alarm.domain.AlarmData>()
-                            .eq(com.zksy.base.alarm.domain.AlarmData::getDeviceCode, deviceCode)
-                            .eq(com.zksy.base.alarm.domain.AlarmData::getAlarmStatus, 0)
-                            .orderByAsc(com.zksy.base.alarm.domain.AlarmData::getAlarmLevel)
-                            .last("LIMIT 1")
-            );
-            if (CollUtil.isNotEmpty(alarms) && alarms.get(0).getAlarmLevel() != null) {
-                maxLevel = alarms.get(0).getAlarmLevel();
-            }
-        } catch (Exception e) {
-            log.warn("计算告警等级异常:{}", e.getMessage());
-        }
-        return maxLevel;
-    }
-
     private void fillGpsFields(Object vo, BigDecimal longitude, BigDecimal latitude) {
         if (vo == null) return;
         try {

+ 0 - 23
pipe-network-service/zksy-system/src/main/java/com/zksy/drainage/service/DrainageEquipmentTestService.java

@@ -1,23 +0,0 @@
-package com.zksy.drainage.service;
-
-import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
-import com.baomidou.mybatisplus.extension.service.IService;
-import com.zksy.base.domain.EquipmentTest;
-
-import java.util.List;
-
-public interface DrainageEquipmentTestService extends IService<EquipmentTest> {
-
-    Page<EquipmentTest> findByPage(long pageNum, long pageSize,
-                                   String equipmentId, String testType, String testResult);
-
-    boolean saveWithCheck(EquipmentTest entity);
-
-    boolean saveBatchWithCheck(List<EquipmentTest> entityList);
-
-    boolean updateWithCheck(EquipmentTest entity);
-
-    boolean removeWithCheck(String id);
-
-    boolean removeBatchWithCheck(List<String> ids);
-}

+ 0 - 107
pipe-network-service/zksy-system/src/main/java/com/zksy/drainage/service/impl/DrainageEquipmentTestServiceImpl.java

@@ -1,107 +0,0 @@
-package com.zksy.drainage.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.EquipmentBase;
-import com.zksy.base.domain.EquipmentTest;
-import com.zksy.base.mapper.EquipmentBaseMapper;
-import com.zksy.base.mapper.EquipmentTestMapper;
-import com.zksy.common.exception.ServiceException;
-import com.zksy.drainage.service.DrainageEquipmentTestService;
-import lombok.extern.slf4j.Slf4j;
-import org.apache.commons.lang3.StringUtils;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Service;
-import org.springframework.transaction.annotation.Transactional;
-
-import java.time.LocalDateTime;
-import java.util.List;
-import java.util.Set;
-import java.util.stream.Collectors;
-
-@Slf4j
-@Service
-public class DrainageEquipmentTestServiceImpl extends ServiceImpl<EquipmentTestMapper, EquipmentTest>
-        implements DrainageEquipmentTestService {
-
-    @Autowired
-    private EquipmentBaseMapper equipmentBaseMapper;
-
-    @Override
-    public Page<EquipmentTest> findByPage(long pageNum, long pageSize,
-                                          String equipmentId, String testType, String testResult) {
-        Page<EquipmentTest> page = new Page<>(pageNum, pageSize);
-        LambdaQueryWrapper<EquipmentTest> wrapper = new LambdaQueryWrapper<>();
-        if (StringUtils.isNotBlank(equipmentId)) {
-            wrapper.eq(EquipmentTest::getEquipmentId, equipmentId);
-        }
-        if (StringUtils.isNotBlank(testType)) {
-            wrapper.like(EquipmentTest::getTestType, testType);
-        }
-        if (StringUtils.isNotBlank(testResult)) {
-            wrapper.like(EquipmentTest::getTestResult, testResult);
-        }
-        wrapper.orderByDesc(EquipmentTest::getTestTime);
-        return this.page(page, wrapper);
-    }
-
-    @Override
-    @Transactional
-    public boolean saveWithCheck(EquipmentTest entity) {
-        String equipmentId = entity.getEquipmentId();
-        if (StringUtils.isBlank(equipmentId)) {
-            throw new ServiceException("设备ID不能为空");
-        }
-        if (equipmentBaseMapper.selectById(equipmentId) == null) {
-            throw new ServiceException("关联的设备不存在:" + equipmentId);
-        }
-        entity.setCreateTime(LocalDateTime.now());
-        return this.save(entity);
-    }
-
-    @Override
-    @Transactional
-    public boolean saveBatchWithCheck(List<EquipmentTest> entityList) {
-        Set<String> equipmentIds = entityList.stream()
-                .map(EquipmentTest::getEquipmentId)
-                .collect(Collectors.toSet());
-        List<String> existIds = equipmentBaseMapper.selectBatchIds(equipmentIds).stream()
-                .map(EquipmentBase::getEquipmentId)
-                .collect(Collectors.toList());
-        Set<String> invalidIds = equipmentIds.stream()
-                .filter(id -> !existIds.contains(id))
-                .collect(Collectors.toSet());
-        if (!invalidIds.isEmpty()) {
-            throw new ServiceException("存在无效的设备ID:" + invalidIds);
-        }
-        LocalDateTime now = LocalDateTime.now();
-        entityList.forEach(e -> e.setCreateTime(now));
-        return this.saveBatch(entityList);
-    }
-
-    @Override
-    @Transactional
-    public boolean updateWithCheck(EquipmentTest entity) {
-        String testId = entity.getTestId();
-        if (this.getById(testId) == null) {
-            throw new ServiceException("测试记录不存在:" + testId);
-        }
-        return this.updateById(entity);
-    }
-
-    @Override
-    @Transactional
-    public boolean removeWithCheck(String id) {
-        if (this.getById(id) == null) {
-            throw new ServiceException("测试记录不存在:" + id);
-        }
-        return this.removeById(id);
-    }
-
-    @Override
-    @Transactional
-    public boolean removeBatchWithCheck(List<String> ids) {
-        return this.removeByIds(ids);
-    }
-}

+ 1 - 27
pipe-network-service/zksy-system/src/main/java/com/zksy/utils/DevicePhoneFetchUtil.java

@@ -2,11 +2,7 @@ package com.zksy.utils;
 
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.zksy.base.domain.EquipmentMaintain;
-import com.zksy.base.domain.EquipmentStatus;
 import com.zksy.base.mapper.EquipmentMaintainMapper;
-import com.zksy.base.mapper.EquipmentStatusMapper;
-import com.zksy.common.core.domain.entity.SysUser;
-import com.zksy.system.service.ISysUserService;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
 
@@ -21,21 +17,14 @@ public class DevicePhoneFetchUtil {
     @Autowired
     private EquipmentMaintainMapper equipmentMaintainMapper;
 
-    @Autowired
-    private EquipmentStatusMapper equipmentStatusMapper;
-
-    @Autowired
-    private ISysUserService sysUserService;
-
     /**
-     * 根据设备ID获取所有关联手机号
+     * 根据设备ID获取所有关联手机号(维护人员联系方式)
      * @param deviceId 设备ID
      * @return 去重后的有效手机号列表
      */
     public List<String> getPhoneListByDeviceId(String deviceId) {
         Set<String> phoneSet = new HashSet<>();
         addAllMaintainPersonPhones(phoneSet, deviceId);
-        addUserPhoneByStatus(phoneSet, deviceId);
         return phoneSet.stream()
                 .filter(this::isValidPhone)
                 .collect(Collectors.toList());
@@ -55,21 +44,6 @@ public class DevicePhoneFetchUtil {
         });
     }
 
-    private void addUserPhoneByStatus(Set<String> phoneSet, String deviceId) {
-        LambdaQueryWrapper<EquipmentStatus> statusWrapper = new LambdaQueryWrapper<>();
-        statusWrapper.eq(EquipmentStatus::getEquipmentId, deviceId);
-        EquipmentStatus equipmentStatus = equipmentStatusMapper.selectOne(statusWrapper);
-
-        if (equipmentStatus == null || equipmentStatus.getUserId() == null) {
-            return;
-        }
-        SysUser sysUser = sysUserService.selectUserById(equipmentStatus.getUserId());
-
-        if (sysUser != null && sysUser.getPhonenumber() != null && "0".equals(sysUser.getDelFlag())) {
-            phoneSet.add(sysUser.getPhonenumber());
-        }
-    }
-
     private boolean isValidPhone(String phone) {
         return phone != null && phone.matches("^1[3-9]\\d{9}$");
     }

+ 0 - 18
pipe-network-service/zksy-system/src/test/java/com/zksy/WaterSupply/AbnormalWorkOrderStatusContractTest.java

@@ -1,8 +1,6 @@
 package com.zksy.WaterSupply;
 
-import com.zksy.WaterSupply.export.WaterDeviceAbnormalExportDTO;
 import com.zksy.base.domain.vo.AbnormalDeviceVO;
-import com.zksy.common.annotation.Excel;
 import com.zksy.ops.enums.WorkOrderStatusEnum;
 import io.swagger.annotations.ApiModelProperty;
 import org.junit.jupiter.api.Test;
@@ -17,22 +15,6 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
  */
 class AbnormalWorkOrderStatusContractTest {
 
-    @Test
-    void abnormalExportWorkOrderStatusFollowsAuthoritativeEnum() throws Exception {
-        Field field = WaterDeviceAbnormalExportDTO.class.getDeclaredField("relatedWorkOrderStatus");
-        Excel excel = field.getAnnotation(Excel.class);
-        assertNotNull(excel, "工单状态导出列缺少 @Excel 注解");
-
-        String mapping = excel.readConverterExp();
-        for (WorkOrderStatusEnum status : WorkOrderStatusEnum.values()) {
-            assertTrue(mapping.contains(status.getCode() + "=" + status.getDesc()),
-                    "导出工单状态映射缺少权威枚举项:" + status.getCode() + "=" + status.getDesc()
-                            + ",实际=" + mapping);
-        }
-        assertTrue(!mapping.contains("已驳回") && !mapping.contains("延期审核"),
-                "导出工单状态映射仍包含废弃状态:" + mapping);
-    }
-
     @Test
     void abnormalDeviceVoWorkOrderStatusDocFollowsAuthoritativeEnum() throws Exception {
         Field field = AbnormalDeviceVO.class.getDeclaredField("relatedWorkOrderStatus");

+ 1 - 1
pipe-network-service/zksy-system/src/test/java/com/zksy/WaterSupply/MonitorAlarm/WaterSupplyAlarmAuditServiceTest.java

@@ -94,7 +94,7 @@ class WaterSupplyAlarmAuditServiceTest {
 
     @BeforeEach
     void setUp() {
-        // 与 DeviceAbnormalControllerTest 一致:为 SecurityUtils 提供登录态
+        // 为 SecurityUtils 提供登录态
         SysUser user = new SysUser();
         user.setUserId(7L);
         user.setUserName("operator");

+ 0 - 90
pipe-network-service/zksy-system/src/test/java/com/zksy/WaterSupply/importing/WaterDeviceLedgerImportServiceTest.java

@@ -1,90 +0,0 @@
-package com.zksy.WaterSupply.importing;
-
-import com.zksy.base.domain.EquipmentBase;
-import com.zksy.base.domain.EquipmentType;
-import com.zksy.base.mapper.EquipmentTypeMapper;
-import com.zksy.base.service.EquipmentBaseService;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-import org.mockito.ArgumentCaptor;
-
-import java.math.BigDecimal;
-import java.util.Arrays;
-import java.util.Collections;
-
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertThrows;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-class WaterDeviceLedgerImportServiceTest {
-    private WaterDeviceLedgerImportService service;
-    private EquipmentBaseService equipmentBaseService;
-    private EquipmentTypeMapper equipmentTypeMapper;
-
-    @BeforeEach
-    void setUp() {
-        equipmentBaseService = mock(EquipmentBaseService.class);
-        equipmentTypeMapper = mock(EquipmentTypeMapper.class);
-        service = new WaterDeviceLedgerImportService(equipmentBaseService, equipmentTypeMapper);
-    }
-    @Test
-    void importDevicesSavesWaterTypeWithEquipmentImage() {
-        EquipmentType waterRoot = type(1, "供水", 0);
-        EquipmentType pressureType = type(12, "压力计", 1);
-        EquipmentType gasRoot = type(3, "燃气设备", 0);
-        when(equipmentTypeMapper.selectList(any())).thenReturn(Arrays.asList(waterRoot, pressureType, gasRoot));
-        when(equipmentBaseService.getOne(any(), eq(false))).thenReturn(null);
-        when(equipmentBaseService.save(any(EquipmentBase.class))).thenReturn(true);
-
-        WaterDeviceLedgerImportDTO row = new WaterDeviceLedgerImportDTO();
-        row.setEquipmentCode(" CN-GS-202609050001 ");
-        row.setEquipmentName("导入压力计");
-        row.setEquipmentTypeName("压力计");
-        row.setEquipmentLocation("测试位置");
-        row.setLongitude(new BigDecimal("113.28"));
-        row.setLatitude(new BigDecimal("23.12"));
-        row.setEquipmentImage("https://example.com/device.jpg");
-
-        assertEquals("成功导入 1 台供水设备", service.importDevices(Collections.singletonList(row), false));
-
-        ArgumentCaptor<EquipmentBase> captor = ArgumentCaptor.forClass(EquipmentBase.class);
-        verify(equipmentBaseService).save(captor.capture());
-        assertEquals("CN-GS-202609050001", captor.getValue().getEquipmentCode());
-        assertEquals("12", captor.getValue().getEquipmentTypeId());
-        assertEquals("https://example.com/device.jpg", captor.getValue().getEquipmentImage());
-        verify(equipmentBaseService, never()).updateById(any(EquipmentBase.class));
-    }
-
-    @Test
-    void importDevicesRejectsNonWaterTypeWithoutSaving() {
-        EquipmentType waterRoot = type(1, "供水", 0);
-        EquipmentType gasChild = type(22, "燃气压力计", 3);
-        EquipmentType gasRoot = type(3, "燃气设备", 0);
-        when(equipmentTypeMapper.selectList(any())).thenReturn(Arrays.asList(waterRoot, gasChild, gasRoot));
-
-        WaterDeviceLedgerImportDTO row = new WaterDeviceLedgerImportDTO();
-        row.setEquipmentCode("CN-RQ-202609050001");
-        row.setEquipmentName("燃气压力计");
-        row.setEquipmentTypeName("燃气压力计");
-
-        IllegalArgumentException error = assertThrows(IllegalArgumentException.class,
-                () -> service.importDevices(Collections.singletonList(row), true));
-
-        assertEquals("导入失败:设备类型不属于供水:燃气压力计", error.getMessage());
-        verify(equipmentBaseService, never()).save(any(EquipmentBase.class));
-        verify(equipmentBaseService, never()).updateById(any(EquipmentBase.class));
-    }
-
-    private static EquipmentType type(Integer id, String name, Integer parentId) {
-        EquipmentType value = new EquipmentType();
-        value.setId(id);
-        value.setTypeName(name);
-        value.setParentId(parentId);
-        return value;
-    }
-}

+ 0 - 6
pipe-network-service/zksy-system/src/test/java/com/zksy/base/service/impl/EquipmentBaseServiceImplTest.java

@@ -7,7 +7,6 @@ import com.zksy.base.mapper.EquipmentBaseMapper;
 import com.zksy.base.mapper.EquipmentMaintainMapper;
 import com.zksy.base.mapper.EquipmentPointRelMapper;
 import com.zksy.base.mapper.EquipmentStatusMapper;
-import com.zksy.base.mapper.EquipmentTestMapper;
 import org.apache.ibatis.annotations.Delete;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
@@ -51,9 +50,6 @@ class EquipmentBaseServiceImplTest {
     @Mock
     private EquipmentMaintainMapper equipmentMaintainMapper;
 
-    @Mock
-    private EquipmentTestMapper equipmentTestMapper;
-
     private EquipmentBaseServiceImpl service;
 
     @BeforeEach
@@ -63,7 +59,6 @@ class EquipmentBaseServiceImplTest {
         ReflectionTestUtils.setField(service, "equipmentStatusMapper", equipmentStatusMapper);
         ReflectionTestUtils.setField(service, "equipmentPointRelMapper", equipmentPointRelMapper);
         ReflectionTestUtils.setField(service, "equipmentMaintainMapper", equipmentMaintainMapper);
-        ReflectionTestUtils.setField(service, "equipmentTestMapper", equipmentTestMapper);
     }
 
     @Test
@@ -79,7 +74,6 @@ class EquipmentBaseServiceImplTest {
         verify(equipmentStatusMapper, never()).delete(any());
         verify(equipmentPointRelMapper, never()).delete(any());
         verify(equipmentMaintainMapper).delete(any());
-        verify(equipmentTestMapper).delete(any());
     }
 
     @Test

+ 114 - 557
pipe-network-service/zksy-system/src/test/java/com/zksy/base/service/impl/WaterSupplyDeviceServiceImplTest.java

@@ -1,10 +1,7 @@
 package com.zksy.base.service.impl;
 
-import com.baomidou.mybatisplus.core.conditions.Wrapper;
-import com.baomidou.mybatisplus.core.conditions.AbstractWrapper;
 import com.baomidou.mybatisplus.core.MybatisConfiguration;
 import com.baomidou.mybatisplus.core.metadata.TableInfoHelper;
-import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.zksy.base.alarm.domain.AlarmData;
 import com.zksy.base.alarm.mapper.AlarmDataMapper;
 import com.zksy.base.domain.EquipmentBase;
@@ -13,24 +10,20 @@ import com.zksy.base.domain.EquipmentStatus;
 import com.zksy.base.domain.EquipmentType;
 import com.zksy.ops.domain.WorkOrder;
 import com.zksy.base.domain.vo.AbnormalDeviceVO;
+import com.zksy.base.domain.vo.DeviceDetailVO;
 import com.zksy.base.domain.vo.DeviceGisVO;
-import com.zksy.base.domain.vo.DeviceLedgerStatisticsVO;
 import com.zksy.base.domain.vo.DeviceTypeStatisticsVO;
-import com.zksy.base.domain.vo.MaintainOrderVO;
 import com.zksy.base.mapper.EquipmentMaintainMapper;
 import com.zksy.base.mapper.EquipmentStatusMapper;
 import com.zksy.base.mapper.EquipmentTypeMapper;
 import com.zksy.ops.mapper.WorkOrderMapper;
 import com.zksy.base.service.EquipmentBaseService;
 import com.zksy.common.core.domain.entity.SysUser;
-import com.zksy.ops.dto.WorkOrderDispatchDTO;
-import com.zksy.ops.service.WorkOrderService;
 import com.zksy.system.service.ISysUserService;
-import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 import org.apache.ibatis.builder.MapperBuilderAssistant;
-import org.mockito.ArgumentCaptor;
 import org.mockito.Mockito;
 import org.springframework.test.util.ReflectionTestUtils;
 
@@ -41,16 +34,11 @@ import java.util.Collections;
 import java.util.List;
 import java.util.stream.Collectors;
 
-import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertNull;
-import static org.junit.jupiter.api.Assertions.assertThrows;
 import static org.junit.jupiter.api.Assertions.assertTrue;
 import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
 class WaterSupplyDeviceServiceImplTest {
@@ -71,7 +59,7 @@ class WaterSupplyDeviceServiceImplTest {
     private EquipmentMaintainMapper equipmentMaintainMapper;
     private AlarmDataMapper alarmDataMapper;
     private WorkOrderMapper workOrderMapper;
-    private WorkOrderService businessWorkOrderService;
+    private ISysUserService sysUserService;
 
     private EquipmentBase pressureDevice;
     private EquipmentBase repairDevice;
@@ -86,7 +74,7 @@ class WaterSupplyDeviceServiceImplTest {
         equipmentMaintainMapper = mock(EquipmentMaintainMapper.class);
         alarmDataMapper = mock(AlarmDataMapper.class);
         workOrderMapper = mock(WorkOrderMapper.class);
-        businessWorkOrderService = mock(WorkOrderService.class);
+        sysUserService = mock(ISysUserService.class);
 
         ReflectionTestUtils.setField(service, "equipmentBaseService", equipmentBaseService);
         ReflectionTestUtils.setField(service, "equipmentTypeMapper", equipmentTypeMapper);
@@ -94,7 +82,7 @@ class WaterSupplyDeviceServiceImplTest {
         ReflectionTestUtils.setField(service, "equipmentMaintainMapper", equipmentMaintainMapper);
         ReflectionTestUtils.setField(service, "alarmDataMapper", alarmDataMapper);
         ReflectionTestUtils.setField(service, "workOrderMapper", workOrderMapper);
-        ReflectionTestUtils.setField(service, "businessWorkOrderService", businessWorkOrderService);
+        ReflectionTestUtils.setField(service, "sysUserService", sysUserService);
 
         pressureDevice = device("water-pressure-1", "WS-PRESSURE-001", "供水压力监测点", "12");
         repairDevice = device("water-flow-1", "WS-FLOW-001", "供水流量监测点", "11");
@@ -104,13 +92,21 @@ class WaterSupplyDeviceServiceImplTest {
                 pressureDevice, repairDevice));
         when(equipmentTypeMapper.selectList(any())).thenReturn(Arrays.asList(
                 type(1, "供水", 0),
-                type(12, "供水压力计", 1),
-                type(11, "供水流量计", 1),
-                type(3, "燃气设备", 0)));
+                type(12, "供水设备甲", 1),
+                type(11, "供水设备乙", 1),
+                type(3, "其他设备", 0)));
         when(equipmentTypeMapper.selectBatchIds(any())).thenReturn(Arrays.asList(
-                type(12, "供水压力计", 1),
-                type(11, "供水流量计", 1),
-                type(3, "燃气设备", 0)));
+                type(12, "供水设备甲", 1),
+                type(11, "供水设备乙", 1),
+                type(3, "其他设备", 0)));
+        when(equipmentTypeMapper.selectById(any())).thenReturn(null);
+        when(equipmentStatusMapper.selectList(any())).thenReturn(Collections.emptyList());
+        when(equipmentStatusMapper.selectOne(any())).thenReturn(null);
+        when(alarmDataMapper.selectList(any())).thenReturn(Collections.emptyList());
+        when(workOrderMapper.selectList(any())).thenReturn(Collections.emptyList());
+        when(equipmentMaintainMapper.selectList(any())).thenReturn(Collections.emptyList());
+        when(equipmentMaintainMapper.selectOne(any())).thenReturn(null);
+        when(sysUserService.selectUserById(any(Long.class))).thenReturn(null);
     }
 
     @Test
@@ -132,388 +128,87 @@ class WaterSupplyDeviceServiceImplTest {
     }
 
     @Test
-    void ledgerStatisticsCountsOnlyWaterDevicesAndMissingStatusAsOffline() {
-        when(equipmentStatusMapper.selectList(any())).thenReturn(Arrays.asList(
-                status(pressureDevice.getEquipmentId(), 1, 1, 1),
-                status(gasDevice.getEquipmentId(), 1, 1, 1)));
-
-        DeviceLedgerStatisticsVO stats = service.getDeviceLedgerStatistics();
-
-        assertEquals(2, stats.getTotal());
-        assertEquals(1, stats.getOnline());
-        assertEquals(1, stats.getOffline());
-        assertEquals(50.0, stats.getOnlineRate());
-    }
-
-    @Test
-    void ledgerResolvesTypeNameByEquipmentTypePrimaryKey() {
-        pressureDevice.setEquipmentTypeId("99");
-        when(equipmentStatusMapper.selectList(any())).thenReturn(Collections.singletonList(
-                status(pressureDevice.getEquipmentId(), 1, 0, 1)));
-        EquipmentType resolvedType = type(99, "business-pressure", 1);
-        when(equipmentTypeMapper.selectBatchIds(any())).thenReturn(Collections.singletonList(resolvedType));
-
-        Page<DeviceGisVO> result = service.getDeviceLedgerPage(
-                1, 10, null, null, null, null, null, null);
-
-        assertEquals("business-pressure", result.getRecords().get(0).getEquipmentTypeName());
+    void typeStatisticsReturnsEmptyWhenNoWaterDevices() {
+        when(equipmentBaseService.findByTopLevelType("供水")).thenReturn(Collections.emptyList());
+        assertTrue(service.getDeviceTypeStatistics().isEmpty());
     }
 
     @Test
-    void ledgerPageReturnsEquipmentImage() {
-        pressureDevice.setEquipmentImage("https://example.com/pressure-device.jpg");
+    void gisPointsIncludeWaterOnlyWithCoordinatesAndStatuses() {
+        pressureDevice.setLongitude(new BigDecimal("113.28000000"));
+        pressureDevice.setLatitude(new BigDecimal("23.12000000"));
+        gasDevice.setLongitude(new BigDecimal("113.32000000"));
+        gasDevice.setLatitude(new BigDecimal("23.16000000"));
         when(equipmentStatusMapper.selectList(any())).thenReturn(Collections.singletonList(
-                status(pressureDevice.getEquipmentId(), 1, 0, 1)));
+                status(pressureDevice.getEquipmentId(), 1, 1, 1)));
         when(equipmentTypeMapper.selectBatchIds(any())).thenReturn(Collections.singletonList(
-                type(12, "water-pressure", 1)));
-
-        Page<DeviceGisVO> result = service.getDeviceLedgerPage(
-                1, 10, null, null, null, null, null, null);
-
-        assertEquals("https://example.com/pressure-device.jpg",
-                result.getRecords().get(0).getEquipmentImage());
-    }
-
-    @Test
-    void ledgerPageAppliesWaterOwnershipAndCurrentStatusFilter() {
-        when(equipmentStatusMapper.selectList(any())).thenReturn(Arrays.asList(
-                status(pressureDevice.getEquipmentId(), 1, 1, 1),
-                status(repairDevice.getEquipmentId(), 3, 0, 0),
-                status(gasDevice.getEquipmentId(), 1, 1, 1)));
-
-        Page<DeviceGisVO> result = service.getDeviceLedgerPage(
-                1, 10, null, null, null, 1, null, null);
-
-        assertEquals(1, result.getTotal());
-        assertEquals(Collections.singletonList("water-pressure-1"), result.getRecords().stream()
-                .map(DeviceGisVO::getEquipmentId)
-                .collect(Collectors.toList()));
-        assertEquals(1, result.getRecords().get(0).getCurrentStatus());
-    }
-
-    @Test
-    void ledgerExportReturnsAllMatchingWaterDevicesWithoutPagination() {
-        EquipmentBase secondPressure = device("water-pressure-2", "WS-PRESSURE-002",
-                "第二供水压力监测点", "water-pressure");
-        when(equipmentBaseService.findByTopLevelType("供水")).thenReturn(Arrays.asList(
-                pressureDevice, secondPressure, repairDevice));
-        when(equipmentStatusMapper.selectList(any())).thenReturn(Arrays.asList(
-                status(pressureDevice.getEquipmentId(), 1, 1, 1),
-                status(secondPressure.getEquipmentId(), 1, 0, 1),
-                status(repairDevice.getEquipmentId(), 3, 0, 0),
-                status(gasDevice.getEquipmentId(), 1, 1, 1)));
+                type(12, "压力监测", 1)));
 
-        List<DeviceGisVO> result = service.getDeviceLedgerExport(
-                null, null, null, 1, null, null);
+        List<DeviceGisVO> points = service.getAllDeviceGisPoints(null);
 
-        assertEquals(Arrays.asList("water-pressure-1", "water-pressure-2"), result.stream()
+        assertEquals(Collections.singletonList("water-pressure-1"), points.stream()
                 .map(DeviceGisVO::getEquipmentId)
                 .collect(Collectors.toList()));
+        assertEquals("压力监测", points.get(0).getEquipmentTypeName());
+        assertEquals(1, points.get(0).getOnlineStatus());
+        assertEquals(1, points.get(0).getAlarmStatus());
+        assertEquals(1, points.get(0).getCurrentStatus());
+        assertEquals(new BigDecimal("113.28000000"), points.get(0).getLongitude());
     }
 
     @Test
-    void createWaterDeviceAcceptsWaterTypeAndRejectsNonWaterType() {
-        EquipmentBase device = new EquipmentBase();
-        device.setEquipmentCode("WS-NEW-001");
-        device.setEquipmentName("新增供水设备");
-        device.setEquipmentTypeId("12");
-        when(equipmentTypeMapper.selectById("12"))
-                .thenReturn(type(12, "供水压力计", 1));
-        when(equipmentTypeMapper.selectList(any())).thenReturn(Arrays.asList(
-                type(1, "供水", 0),
-                type(12, "供水压力计", 1)));
-        doReturn(0L).when(service).count(any());
-        doReturn(true).when(service).save(any(EquipmentBase.class));
-
-        assertTrue(service.createWaterDevice(device));
-        assertEquals("12", device.getEquipmentTypeId());
-
-        EquipmentBase gasDevice = new EquipmentBase();
-        gasDevice.setEquipmentCode("GAS-NEW-001");
-        gasDevice.setEquipmentTypeId("3");
-        when(equipmentTypeMapper.selectById("3"))
-                .thenReturn(type(3, "燃气设备", 0));
-        RuntimeException error = assertThrows(RuntimeException.class,
-                () -> service.createWaterDevice(gasDevice));
-        assertEquals("设备类型不属于供水:3", error.getMessage());
-    }
-
-    @Test
-    void deleteWaterDevicesRejectsNonWaterDevices() {
-        RuntimeException error = assertThrows(RuntimeException.class,
-                () -> service.deleteWaterDevices(Collections.singletonList("gas-1")));
-        assertEquals("存在非供水设备,无法删除:gas-1", error.getMessage());
-    }
-
-    @Test
-    void ledgerPageAppliesAlarmStatusAndAlertLevelFilters() {
-        when(equipmentStatusMapper.selectList(any())).thenReturn(Arrays.asList(
-                status(pressureDevice.getEquipmentId(), 1, 1, 1),
-                status(repairDevice.getEquipmentId(), 1, 0, 1),
-                status(gasDevice.getEquipmentId(), 1, 1, 1)));
-        when(alarmDataMapper.selectList(any())).thenReturn(Arrays.asList(
-                alarm(pressureDevice.getEquipmentCode(), "供水压力超限", 1),
-                alarm(gasDevice.getEquipmentCode(), "燃气浓度超限", 2)));
+    void gisPointsExcludesDevicesWithoutCoordinates() {
+        pressureDevice.setLongitude(new BigDecimal("113.28000000"));
+        pressureDevice.setLatitude(new BigDecimal("23.12000000"));
+        // repairDevice 无坐标,应被过滤
 
-        Page<DeviceGisVO> result = service.getDeviceLedgerPage(
-                1, 10, null, null, null, null, 1, 1);
+        List<DeviceGisVO> points = service.getAllDeviceGisPoints(null);
 
-        assertEquals(1, result.getTotal());
-        assertEquals(Collections.singletonList("water-pressure-1"), result.getRecords().stream()
+        assertEquals(Collections.singletonList("water-pressure-1"), points.stream()
                 .map(DeviceGisVO::getEquipmentId)
                 .collect(Collectors.toList()));
-        assertEquals(1, result.getRecords().get(0).getAlarmStatus());
-        assertEquals(1, result.getRecords().get(0).getAlertLevel());
-    }
-
-    @Test
-    void abnormalPageUsesAlarmReasonAlertLevelAndUnifiedWorkOrder() {
-        when(equipmentStatusMapper.selectList(any())).thenReturn(Arrays.asList(
-                status(pressureDevice.getEquipmentId(), 1, 1, 1),
-                status(repairDevice.getEquipmentId(), 3, 0, 0),
-                status(gasDevice.getEquipmentId(), 1, 1, 1)));
-        when(alarmDataMapper.selectList(any())).thenReturn(Arrays.asList(
-                alarm(pressureDevice.getEquipmentCode(), "供水压力超限", 1),
-                alarm(gasDevice.getEquipmentCode(), "燃气浓度超限", 2)));
-        ISysUserService sysUserService = mock(ISysUserService.class);
-        ReflectionTestUtils.setField(service, "sysUserService", sysUserService);
-        when(sysUserService.selectUserById(1L)).thenReturn(sysUser(1L, "zhangsan", "张三"));
-        when(sysUserService.selectUserById(2L)).thenReturn(sysUser(2L, "lisi", "李四"));
-        when(workOrderMapper.selectList(any())).thenReturn(Arrays.asList(
-                workOrder(pressureDevice.getEquipmentId(), "WO-WS-001", 4, 1L),
-                workOrder(repairDevice.getEquipmentId(), "WO-WS-002", 4, 2L),
-                workOrder(gasDevice.getEquipmentId(), "WO-GAS-001", 2)));
-
-        Page<AbnormalDeviceVO> result = service.getAbnormalDevicePage(
-                1, 10, null, null, null, null);
-
-        assertEquals(2, result.getTotal());
-        assertEquals(Arrays.asList("water-pressure-1", "water-flow-1"), result.getRecords().stream()
-                .map(AbnormalDeviceVO::getEquipmentId)
-                .collect(Collectors.toList()));
-
-        AbnormalDeviceVO alarmRow = result.getRecords().get(0);
-        assertEquals(1, alarmRow.getAlarmStatus());
-        assertEquals(1, alarmRow.getCurrentStatus());
-        assertEquals(1, alarmRow.getOnlineStatus());
-        assertEquals(1, alarmRow.getAlertLevel());
-        assertEquals("供水压力超限", ReflectionTestUtils.getField(alarmRow, "abnormalReason"));
-        assertEquals("WO-WS-001", ReflectionTestUtils.getField(alarmRow, "relatedWorkOrderNo"));
-        assertEquals(4, ReflectionTestUtils.getField(alarmRow, "relatedWorkOrderStatus"));
-        assertEquals("张三", ReflectionTestUtils.getField(alarmRow, "relatedWorkOrderPerson"));
-
-        AbnormalDeviceVO repairRow = result.getRecords().get(1);
-        assertEquals(0, repairRow.getAlarmStatus());
-        assertEquals(3, repairRow.getCurrentStatus());
-        assertEquals(0, repairRow.getOnlineStatus());
-        assertNull(repairRow.getAlertLevel());
-        assertEquals("设备维修中", ReflectionTestUtils.getField(repairRow, "abnormalReason"));
-        assertEquals("WO-WS-002", ReflectionTestUtils.getField(repairRow, "relatedWorkOrderNo"));
-        assertEquals(4, ReflectionTestUtils.getField(repairRow, "relatedWorkOrderStatus"));
-        assertEquals("李四", ReflectionTestUtils.getField(repairRow, "relatedWorkOrderPerson"));
-
-        @SuppressWarnings("unchecked")
-        ArgumentCaptor<Wrapper<WorkOrder>> orderWrapperCaptor =
-                ArgumentCaptor.forClass(Wrapper.class);
-        verify(workOrderMapper).selectList(orderWrapperCaptor.capture());
-        String orderWrapperSql = orderWrapperCaptor.getValue().getSqlSegment();
-        assertTrue(orderWrapperSql.contains("order_status"), "异常设备关联工单必须限定未办结状态: " + orderWrapperSql);
-        AbstractWrapper<?, ?, ?> orderWrapper = (AbstractWrapper<?, ?, ?>) orderWrapperCaptor.getValue();
-        assertTrue(orderWrapper.getParamNameValuePairs().containsValue(5), "关联工单必须排除 5-已结案");
-        assertTrue(orderWrapper.getParamNameValuePairs().containsValue(7), "关联工单必须排除 7-已取消");
-    }
-
-    @Test
-    void abnormalPageResolvesWorkOrderReceiverToDisplayName() {
-        ISysUserService sysUserService = mock(ISysUserService.class);
-        ReflectionTestUtils.setField(service, "sysUserService", sysUserService);
-        when(sysUserService.selectUserById(1L)).thenReturn(sysUser(1L, "zhangsan", "张三丰"));
-        when(sysUserService.selectUserById(2L)).thenReturn(sysUser(2L, "lisi", null));
-
-        when(equipmentStatusMapper.selectList(any())).thenReturn(Collections.singletonList(
-                status(pressureDevice.getEquipmentId(), 1, 1, 1)));
-        when(alarmDataMapper.selectList(any())).thenReturn(Collections.singletonList(
-                alarm(pressureDevice.getEquipmentCode(), "供水压力超限", 1)));
-        when(workOrderMapper.selectList(any())).thenReturn(Collections.singletonList(
-                workOrder(pressureDevice.getEquipmentId(), "WO-WS-003", 4, 1L)));
-
-        Page<AbnormalDeviceVO> result = service.getAbnormalDevicePage(
-                1, 10, null, null, null, null);
-
-        assertEquals(1, result.getTotal());
-        assertEquals("张三丰", ReflectionTestUtils.getField(
-                result.getRecords().get(0), "relatedWorkOrderPerson"));
-        verify(sysUserService).selectUserById(1L);
-
-        // 责任人没有昵称时回退展示用户名
-        when(workOrderMapper.selectList(any())).thenReturn(Collections.singletonList(
-                workOrder(pressureDevice.getEquipmentId(), "WO-WS-004", 4, 2L)));
-
-        Page<AbnormalDeviceVO> fallback = service.getAbnormalDevicePage(
-                1, 10, null, null, null, null);
-
-        assertEquals("lisi", ReflectionTestUtils.getField(
-                fallback.getRecords().get(0), "relatedWorkOrderPerson"));
-        verify(sysUserService).selectUserById(2L);
-    }
-
-    @Test
-    void abnormalExportReturnsAllWaterAbnormalDevicesWithoutPagination() {
-        when(equipmentStatusMapper.selectList(any())).thenReturn(Arrays.asList(
-                status(pressureDevice.getEquipmentId(), 1, 1, 1),
-                status(repairDevice.getEquipmentId(), 3, 0, 0),
-                status(gasDevice.getEquipmentId(), 1, 1, 1)));
-        when(alarmDataMapper.selectList(any())).thenReturn(Arrays.asList(
-                alarm(pressureDevice.getEquipmentCode(), "供水压力超限", 1),
-                alarm(gasDevice.getEquipmentCode(), "燃气浓度超限", 2)));
-        when(workOrderMapper.selectList(any())).thenReturn(Arrays.asList(
-                workOrder(pressureDevice.getEquipmentId(), "WO-WS-001", 4),
-                workOrder(repairDevice.getEquipmentId(), "WO-WS-002", 6),
-                workOrder(gasDevice.getEquipmentId(), "WO-GAS-001", 2)));
-
-        List<AbnormalDeviceVO> result = service.getAbnormalDeviceExport(
-                null, null, null, null);
-
-        assertEquals(Arrays.asList("water-pressure-1", "water-flow-1"), result.stream()
-                .map(AbnormalDeviceVO::getEquipmentId)
-                .collect(Collectors.toList()));
-        assertEquals("供水压力超限", result.get(0).getAbnormalReason());
-        assertEquals("设备维修中", result.get(1).getAbnormalReason());
-        assertNull(result.get(1).getAlertLevel());
-    }
-
-    @Test
-    void abnormalPageIncludesActiveAlarmWhenRuntimeStatusRecordIsMissing() {
-        when(equipmentStatusMapper.selectList(any())).thenReturn(Collections.emptyList());
-        when(alarmDataMapper.selectList(any())).thenReturn(Collections.singletonList(
-                alarm(pressureDevice.getEquipmentCode(), "供水压力超限", 1)));
-        when(workOrderMapper.selectList(any())).thenReturn(Collections.emptyList());
-
-        Page<AbnormalDeviceVO> result = service.getAbnormalDevicePage(1, 10, null, null, null, null);
-
-        assertEquals(1, result.getTotal());
-        AbnormalDeviceVO row = result.getRecords().get(0);
-        assertEquals(pressureDevice.getEquipmentId(), row.getEquipmentId());
-        assertEquals(1, row.getAlertLevel());
-        assertEquals("供水压力超限", ReflectionTestUtils.getField(row, "abnormalReason"));
-    }
-
-    @Test
-    void abnormalAlertLevelFilterUsesActiveAlarmLevel() {
-        when(equipmentStatusMapper.selectList(any())).thenReturn(Collections.singletonList(
-                status(pressureDevice.getEquipmentId(), 1, 1, 1)));
-        when(alarmDataMapper.selectList(any())).thenReturn(Collections.singletonList(
-                alarm(pressureDevice.getEquipmentCode(), "供水压力超限", 1)));
-
-        Page<AbnormalDeviceVO> result = service.getAbnormalDevicePage(
-                1, 10, null, null, null, 2);
-
-        assertEquals(0, result.getTotal());
-        assertTrue(result.getRecords().isEmpty());
-    }
-
-    @Test
-    void multipleActiveAlarmsChooseMostSevereLevelOne() {
-        when(equipmentStatusMapper.selectList(any())).thenReturn(Collections.singletonList(
-                status(pressureDevice.getEquipmentId(), 1, 1, 1)));
-        when(alarmDataMapper.selectList(any())).thenReturn(Arrays.asList(
-                alarm(pressureDevice.getEquipmentCode(), "一般告警", 3),
-                alarm(pressureDevice.getEquipmentCode(), "严重告警", 1),
-                alarm(pressureDevice.getEquipmentCode(), "较重告警", 2)));
-
-        Page<AbnormalDeviceVO> result = service.getAbnormalDevicePage(1, 10, null, null, null, null);
-
-        assertEquals(1, result.getRecords().get(0).getAlertLevel());
-        assertEquals("严重告警", result.getRecords().get(0).getAbnormalReason());
-    }
-
-    @Test
-    void abnormalPageExcludesClosedAndCancelledWorkOrders() {
-        when(equipmentStatusMapper.selectList(any())).thenReturn(Collections.singletonList(
-                status(pressureDevice.getEquipmentId(), 1, 1, 1)));
-        when(alarmDataMapper.selectList(any())).thenReturn(Collections.singletonList(
-                alarm(pressureDevice.getEquipmentCode(), "供水压力超限", 1)));
-        when(workOrderMapper.selectList(any())).thenReturn(Arrays.asList(
-                workOrder(pressureDevice.getEquipmentId(), "WO-CANCELLED", 7),
-                workOrder(pressureDevice.getEquipmentId(), "WO-CLOSED", 5)));
-
-        Page<AbnormalDeviceVO> result = service.getAbnormalDevicePage(1, 10, null, null, null, null);
-
-        assertNull(result.getRecords().get(0).getRelatedWorkOrderNo());
-        ArgumentCaptor<Wrapper<WorkOrder>> wrapperCaptor = ArgumentCaptor.forClass(Wrapper.class);
-        verify(workOrderMapper).selectList(wrapperCaptor.capture());
-        AbstractWrapper<?, ?, ?> wrapper = (AbstractWrapper<?, ?, ?>) wrapperCaptor.getValue();
-        assertTrue(wrapper.getSqlSegment().contains("order_status"));
-    }
-
-    @Test
-    void dispatchableOnlyExcludesDevicesWithActiveFaultWorkOrders() {
-        when(equipmentStatusMapper.selectList(any())).thenReturn(Arrays.asList(
-                status(pressureDevice.getEquipmentId(), 1, 1, 1),
-                status(repairDevice.getEquipmentId(), 3, 0, 1)));
-        when(alarmDataMapper.selectList(any())).thenReturn(Collections.emptyList());
-        when(workOrderMapper.selectList(any())).thenReturn(Arrays.asList(
-                workOrder(pressureDevice.getEquipmentId(), "WO-ACTIVE", 2),
-                workOrder(repairDevice.getEquipmentId(), "WO-CLOSED", 5)));
-
-        Page<AbnormalDeviceVO> result = service.getAbnormalDevicePage(
-                1, 10, null, null, null, null, true);
-
-        assertEquals(Collections.singletonList(repairDevice.getEquipmentId()), result.getRecords().stream()
-                .map(AbnormalDeviceVO::getEquipmentId)
-                .collect(Collectors.toList()));
     }
 
     @Test
-    void deviceGisPointsIncludeWaterOnlyWithCoordinatesAndStatuses() {
+    void gisPointsFilterByEquipmentTypeId() {
         pressureDevice.setLongitude(new BigDecimal("113.28000000"));
         pressureDevice.setLatitude(new BigDecimal("23.12000000"));
-        gasDevice.setLongitude(new BigDecimal("113.32000000"));
-        gasDevice.setLatitude(new BigDecimal("23.16000000"));
-        when(equipmentStatusMapper.selectList(any())).thenReturn(Collections.singletonList(
-                status(pressureDevice.getEquipmentId(), 1, 1, 1)));
-        when(equipmentTypeMapper.selectBatchIds(any())).thenReturn(Collections.singletonList(
-                type(12, "压力监测", 1)));
+        repairDevice.setLongitude(new BigDecimal("113.29000000"));
+        repairDevice.setLatitude(new BigDecimal("23.13000000"));
 
-        List<DeviceGisVO> points = service.getAllDeviceGisPoints(null);
+        List<DeviceGisVO> points = service.getAllDeviceGisPoints("12");
 
         assertEquals(Collections.singletonList("water-pressure-1"), points.stream()
                 .map(DeviceGisVO::getEquipmentId)
                 .collect(Collectors.toList()));
-        assertEquals("压力监测", points.get(0).getEquipmentTypeName());
-        assertEquals(1, points.get(0).getOnlineStatus());
-        assertEquals(1, points.get(0).getAlarmStatus());
-        assertEquals(1, points.get(0).getCurrentStatus());
-        assertEquals(new BigDecimal("113.28000000"), points.get(0).getLongitude());
     }
 
     @Test
     void deviceDetailIncludesAlarmAndRelatedWorkOrderSummary() {
-        doReturn(pressureDevice).when(service).getById(pressureDevice.getEquipmentId());
         when(equipmentStatusMapper.selectOne(any())).thenReturn(status(pressureDevice.getEquipmentId(), 1, 1, 1));
         when(alarmDataMapper.selectList(any())).thenReturn(Collections.singletonList(
                 alarm(pressureDevice.getEquipmentCode(), "供水压力超限", 1)));
         when(workOrderMapper.selectList(any())).thenReturn(Collections.singletonList(
                 workOrder(pressureDevice.getEquipmentId(), "WO-DETAIL", 2, 1L)));
+        when(sysUserService.selectUserById(1L)).thenReturn(sysUser(1L, "zhangsan", "张三"));
 
-        com.zksy.base.domain.vo.DeviceDetailVO detail = service.getDeviceDetail(pressureDevice.getEquipmentId());
+        DeviceDetailVO detail = service.getDeviceDetail(pressureDevice.getEquipmentId());
 
         assertEquals(1, detail.getAlertLevel());
         assertEquals("供水压力超限", detail.getAbnormalReason());
         assertEquals("WO-DETAIL", detail.getRelatedWorkOrderNo());
         assertEquals(2, detail.getRelatedWorkOrderStatus());
-        assertEquals("1", detail.getRelatedWorkOrderPerson());
+        assertEquals("张三", detail.getRelatedWorkOrderPerson());
     }
 
     @Test
     void deviceDetailKeepsMaintenanceStateSeparateFromAlarmLevel() {
-        doReturn(repairDevice).when(service).getById(repairDevice.getEquipmentId());
         when(equipmentStatusMapper.selectOne(any())).thenReturn(
                 status(repairDevice.getEquipmentId(), 3, 0, 1));
         when(alarmDataMapper.selectList(any())).thenReturn(Collections.emptyList());
         when(workOrderMapper.selectList(any())).thenReturn(Collections.emptyList());
 
-        com.zksy.base.domain.vo.DeviceDetailVO detail = service.getDeviceDetail(repairDevice.getEquipmentId());
+        DeviceDetailVO detail = service.getDeviceDetail(repairDevice.getEquipmentId());
 
         assertEquals(3, detail.getCurrentStatus());
         assertEquals(0, detail.getAlarmStatus());
@@ -521,58 +216,8 @@ class WaterSupplyDeviceServiceImplTest {
         assertEquals("设备维修中", detail.getAbnormalReason());
     }
 
-    @Test
-    void abnormalOrderCreatesUnifiedFaultWorkOrderWithSingleReceiver() {
-        MaintainOrderVO request = new MaintainOrderVO();
-        request.setEquipmentId(pressureDevice.getEquipmentId());
-        request.setMaintainContent("压力异常");
-        request.setReceiveUserId(88L);
-        when(businessWorkOrderService.createWorkOrder(any(WorkOrder.class))).thenAnswer(invocation -> {
-            WorkOrder input = invocation.getArgument(0);
-            input.setOrderId(99L);
-            input.setOrderNo("WO-T6");
-            input.setOrderStatus(1);
-            return 99L;
-        });
-        WorkOrder result = service.createAbnormalWorkOrder(request);
-
-        assertEquals(99L, result.getOrderId());
-        assertEquals(1, result.getOrderLevel());
-        assertEquals(1, result.getOrderStatus());
-        assertNull(result.getReceiveUser());
-        ArgumentCaptor<WorkOrder> workOrderCaptor = ArgumentCaptor.forClass(WorkOrder.class);
-        verify(businessWorkOrderService).createWorkOrder(workOrderCaptor.capture());
-        WorkOrder submitted = workOrderCaptor.getValue();
-        assertEquals(pressureDevice.getEquipmentId(), submitted.getDeviceId());
-        assertEquals(pressureDevice.getEquipmentCode(), submitted.getDeviceCode());
-        assertEquals(1, submitted.getOrderLevel());
-        assertEquals("压力异常", submitted.getOrderDesc());
-        assertNull(submitted.getReceiveUser());
-        verify(equipmentMaintainMapper, never()).insert(any(EquipmentMaintain.class));
-    }
-
-    @Test
-    void abnormalOrderCanCreatePendingWorkOrderWithoutReceiverId() {
-        MaintainOrderVO request = new MaintainOrderVO();
-        request.setEquipmentId(pressureDevice.getEquipmentId());
-        when(businessWorkOrderService.createWorkOrder(any(WorkOrder.class))).thenAnswer(invocation -> {
-            WorkOrder submitted = invocation.getArgument(0);
-            submitted.setOrderId(101L);
-            submitted.setOrderStatus(1);
-            return 101L;
-        });
-
-        WorkOrder result = service.createAbnormalWorkOrder(request);
-
-        assertEquals(101L, result.getOrderId());
-        assertEquals(1, result.getOrderStatus());
-        assertNull(result.getReceiveUser());
-        verify(businessWorkOrderService).createWorkOrder(any(WorkOrder.class));
-    }
-
     @Test
     void deviceDetailIgnoresProcessedAlarmRecordWhenEquipmentIsNormal() {
-        doReturn(repairDevice).when(service).getById(repairDevice.getEquipmentId());
         when(equipmentStatusMapper.selectOne(any())).thenReturn(
                 status(repairDevice.getEquipmentId(), 1, 0, 1));
         AlarmData processedAlarm = new AlarmData();
@@ -583,179 +228,96 @@ class WaterSupplyDeviceServiceImplTest {
         when(alarmDataMapper.selectList(any())).thenReturn(Collections.singletonList(processedAlarm));
         when(workOrderMapper.selectList(any())).thenReturn(Collections.emptyList());
 
-        com.zksy.base.domain.vo.DeviceDetailVO detail = service.getDeviceDetail(repairDevice.getEquipmentId());
+        DeviceDetailVO detail = service.getDeviceDetail(repairDevice.getEquipmentId());
 
         assertEquals(0, detail.getAlarmStatus());
         assertNull(detail.getAlertLevel());
         assertNull(detail.getAbnormalReason());
     }
 
-    @Test
-    void noWaterDevicesReturnsEmptyAbnormalPageWithoutReadingStatuses() {
-        when(equipmentBaseService.findByTopLevelType("供水")).thenReturn(Collections.emptyList());
-        Page<AbnormalDeviceVO> result = service.getAbnormalDevicePage(
-                1, 10, null, null, null, null);
-
-        assertEquals(0, result.getTotal());
-        assertTrue(result.getRecords().isEmpty());
-        verify(equipmentStatusMapper, never()).selectList(any());
-    }
-
     @Test
     void deviceDetailDoesNotExposeNonWaterDevices() {
-        doReturn(gasDevice).when(service).getById(gasDevice.getEquipmentId());
-
+        // gasDevice 不属于供水设备,findWaterDeviceById 找不到,应返回 null
         assertNull(service.getDeviceDetail(gasDevice.getEquipmentId()));
     }
 
     @Test
-    void createMaintainOrderRejectsNonWaterDevices() {
-        MaintainOrderVO order = new MaintainOrderVO();
-        order.setEquipmentId(gasDevice.getEquipmentId());
-        doReturn(gasDevice).when(service).getById(gasDevice.getEquipmentId());
+    void deviceDetailIncludesLatestMaintainRecord() {
+        when(equipmentStatusMapper.selectOne(any())).thenReturn(
+                status(pressureDevice.getEquipmentId(), 1, 0, 1));
+        when(alarmDataMapper.selectList(any())).thenReturn(Collections.emptyList());
+        when(workOrderMapper.selectList(any())).thenReturn(Collections.emptyList());
+        EquipmentMaintain maintain = maintain("m1", pressureDevice.getEquipmentId());
+        when(equipmentMaintainMapper.selectOne(any())).thenReturn(maintain);
 
-        RuntimeException error = assertThrows(RuntimeException.class,
-                () -> service.createMaintainOrder(order));
+        DeviceDetailVO detail = service.getDeviceDetail(pressureDevice.getEquipmentId());
 
-        assertEquals("仅支持供水设备派发维修工单", error.getMessage());
-        verify(equipmentMaintainMapper, never()).insert(any(EquipmentMaintain.class));
+        assertTrue(detail.getLatestMaintain() != null);
+        assertEquals("m1", detail.getLatestMaintain().get("maintainId"));
     }
 
     @Test
-    void legacyMaintainOrderSignatureUsesUnifiedWorkOrderLifecycle() {
-        MaintainOrderVO request = new MaintainOrderVO();
-        request.setEquipmentId(pressureDevice.getEquipmentId());
-        request.setMaintainContent("压力异常");
-        request.setOrderLevel(1);
-        request.setMaintainRemark("请尽快处理");
-        request.setReceiveUserId(88L);
-        when(businessWorkOrderService.createWorkOrder(any(WorkOrder.class))).thenAnswer(invocation -> {
-            WorkOrder submitted = invocation.getArgument(0);
-            submitted.setOrderId(100L);
-            submitted.setOrderStatus(1);
-            return 100L;
-        });
-        when(businessWorkOrderService.dispatch(any(), any(WorkOrderDispatchDTO.class)))
-                .thenReturn(true);
-
-        assertTrue(service.createMaintainOrder(request));
-
-        verify(equipmentMaintainMapper, never()).insert(any(EquipmentMaintain.class));
-        ArgumentCaptor<WorkOrder> orderCaptor = ArgumentCaptor.forClass(WorkOrder.class);
-        verify(businessWorkOrderService).createWorkOrder(orderCaptor.capture());
-        assertEquals(1, orderCaptor.getValue().getOrderLevel());
-        ArgumentCaptor<WorkOrderDispatchDTO> dispatchCaptor = ArgumentCaptor.forClass(WorkOrderDispatchDTO.class);
-        verify(businessWorkOrderService).dispatch(any(), dispatchCaptor.capture());
-        assertEquals(88L, dispatchCaptor.getValue().getHandlerId());
-        assertEquals("请尽快处理", dispatchCaptor.getValue().getRemarks());
-    }
+    void abnormalGisPointsReturnsWaterDevicesWithAlarmOrMaintenanceStatus() {
+        pressureDevice.setLongitude(new BigDecimal("113.28000000"));
+        pressureDevice.setLatitude(new BigDecimal("23.12000000"));
+        repairDevice.setLongitude(new BigDecimal("113.29000000"));
+        repairDevice.setLatitude(new BigDecimal("23.13000000"));
+        when(equipmentStatusMapper.selectList(any())).thenReturn(Arrays.asList(
+                status(pressureDevice.getEquipmentId(), 1, 1, 1),
+                status(repairDevice.getEquipmentId(), 3, 0, 1)));
+        when(alarmDataMapper.selectList(any())).thenReturn(Collections.singletonList(
+                alarm(pressureDevice.getEquipmentCode(), "供水压力超限", 1)));
+        when(workOrderMapper.selectList(any())).thenReturn(Collections.singletonList(
+                workOrder(pressureDevice.getEquipmentId(), "WO-A", 2, 1L)));
+        when(equipmentMaintainMapper.selectList(any())).thenReturn(Collections.singletonList(
+                maintain("m1", pressureDevice.getEquipmentId())));
+        when(sysUserService.selectUserById(1L)).thenReturn(sysUser(1L, "zhangsan", "张三"));
 
-    @Test
-    void createAbnormalWorkOrderRejectsWhenDeviceHasActiveWorkOrder() {
-        MaintainOrderVO request = new MaintainOrderVO();
-        request.setEquipmentId(pressureDevice.getEquipmentId());
-        request.setMaintainContent("压力异常");
-        doReturn(pressureDevice).when(service).getById(pressureDevice.getEquipmentId());
-
-        WorkOrder activeOrder = new WorkOrder();
-        activeOrder.setDeviceId(pressureDevice.getEquipmentId());
-        activeOrder.setOrderNo("WO-ACTIVE");
-        activeOrder.setOrderStatus(2);
-        when(workOrderMapper.selectList(any())).thenReturn(Collections.singletonList(activeOrder));
-
-        RuntimeException error = assertThrows(RuntimeException.class,
-                () -> service.createAbnormalWorkOrder(request));
-
-        assertEquals("该设备已有未结束故障维修工单,不能重复创建", error.getMessage());
-        verify(businessWorkOrderService, never()).createWorkOrder(any(WorkOrder.class));
+        List<AbnormalDeviceVO> result = service.getAbnormalDeviceGisPoints(null);
+
+        assertEquals(2, result.size());
+        AbnormalDeviceVO pressureRow = result.stream()
+                .filter(r -> "water-pressure-1".equals(r.getEquipmentId()))
+                .findFirst().orElseThrow();
+        assertEquals(1, pressureRow.getAlarmStatus());
+        assertEquals(1, pressureRow.getCurrentStatus());
+        assertEquals(1, pressureRow.getOnlineStatus());
+        assertEquals(1, pressureRow.getAlertLevel());
+        assertEquals("供水压力超限", pressureRow.getAbnormalReason());
+        assertEquals("WO-A", pressureRow.getRelatedWorkOrderNo());
+        assertEquals(2, pressureRow.getRelatedWorkOrderStatus());
+        assertEquals("张三", pressureRow.getRelatedWorkOrderPerson());
+        assertEquals("m1", pressureRow.getLatestMaintainId());
+
+        AbnormalDeviceVO repairRow = result.stream()
+                .filter(r -> "water-flow-1".equals(r.getEquipmentId()))
+                .findFirst().orElseThrow();
+        assertEquals(0, repairRow.getAlarmStatus());
+        assertEquals(3, repairRow.getCurrentStatus());
+        assertNull(repairRow.getAlertLevel());
+        assertEquals("设备维修中", repairRow.getAbnormalReason());
+        assertNull(repairRow.getLatestMaintainId());
     }
 
     @Test
-    void maintainRecordListDoesNotExposeNonWaterDevices() {
-        EquipmentMaintain gasRecord = new EquipmentMaintain();
-        gasRecord.setEquipmentId(gasDevice.getEquipmentId());
-        gasRecord.setMaintainId("gas-record");
-        when(equipmentMaintainMapper.selectList(any())).thenReturn(Collections.singletonList(gasRecord));
-
-        assertTrue(service.getMaintainRecordList(gasDevice.getEquipmentId()).isEmpty());
-    }
+    void abnormalGisPointsExcludesNonWaterAndMissingCoordinates() {
+        // gasDevice 有坐标但非供水设备;repairDevice 供水但无坐标;仅 pressureDevice 符合
+        gasDevice.setLongitude(new BigDecimal("113.32000000"));
+        gasDevice.setLatitude(new BigDecimal("23.16000000"));
+        pressureDevice.setLongitude(new BigDecimal("113.28000000"));
+        pressureDevice.setLatitude(new BigDecimal("23.12000000"));
+        when(equipmentStatusMapper.selectList(any())).thenReturn(Arrays.asList(
+                status(pressureDevice.getEquipmentId(), 1, 1, 1),
+                status(gasDevice.getEquipmentId(), 1, 1, 1),
+                status(repairDevice.getEquipmentId(), 3, 0, 1)));
 
-    @Test
-    void maintainRecordPageReturnsOnlyWaterDevices() {
-        EquipmentMaintain waterRecord = maintain("water-record", pressureDevice.getEquipmentId());
-        EquipmentMaintain gasRecord = maintain("gas-record", gasDevice.getEquipmentId());
-        Page<EquipmentMaintain> mapperPage = new Page<>(1, 10, 2);
-        mapperPage.setRecords(Arrays.asList(gasRecord, waterRecord));
-        when(equipmentMaintainMapper.selectPage(any(), any())).thenReturn(mapperPage);
-        when(equipmentMaintainMapper.selectList(any())).thenReturn(Arrays.asList(gasRecord, waterRecord));
-        doReturn(Arrays.asList(pressureDevice, gasDevice)).when(service).listByIds(any());
-
-        Page<com.zksy.base.domain.vo.EquipmentMaintainDataVO> result =
-                service.getMaintainRecordPage(1, 10, null, null, null, null, null, null);
-
-        assertEquals(1, result.getTotal());
-        assertEquals(Collections.singletonList("water-record"), result.getRecords().stream()
-                .map(com.zksy.base.domain.vo.EquipmentMaintainDataVO::getMaintainId)
-                .collect(Collectors.toList()));
-    }
+        List<AbnormalDeviceVO> result = service.getAbnormalDeviceGisPoints(null);
 
-    @Test
-    void myMaintainRecordPageReturnsOnlyWaterDevices() {
-        EquipmentMaintain waterRecord = maintain("water-record", pressureDevice.getEquipmentId());
-        EquipmentMaintain gasRecord = maintain("gas-record", gasDevice.getEquipmentId());
-        Page<EquipmentMaintain> mapperPage = new Page<>(1, 10, 2);
-        mapperPage.setRecords(Arrays.asList(gasRecord, waterRecord));
-        when(equipmentMaintainMapper.selectPage(any(), any())).thenReturn(mapperPage);
-        when(equipmentMaintainMapper.selectList(any())).thenReturn(Arrays.asList(gasRecord, waterRecord));
-        doReturn(Arrays.asList(pressureDevice, gasDevice)).when(service).listByIds(any());
-
-        Page<com.zksy.base.domain.vo.EquipmentMaintainDataVO> result =
-                service.getMyMaintainRecordPage(1, 10, "张三", null, null, null, null);
-
-        assertEquals(1, result.getTotal());
-        assertEquals(Collections.singletonList("water-record"), result.getRecords().stream()
-                .map(com.zksy.base.domain.vo.EquipmentMaintainDataVO::getMaintainId)
+        assertEquals(Collections.singletonList("water-pressure-1"), result.stream()
+                .map(AbnormalDeviceVO::getEquipmentId)
                 .collect(Collectors.toList()));
     }
 
-    @Test
-    void updateMaintainRecordRejectsNonWaterRecords() {
-        com.zksy.base.domain.vo.EquipmentMaintainDataVO vo =
-                new com.zksy.base.domain.vo.EquipmentMaintainDataVO();
-        vo.setMaintainId("gas-record");
-        when(equipmentMaintainMapper.selectById("gas-record"))
-                .thenReturn(maintain("gas-record", gasDevice.getEquipmentId()));
-
-        RuntimeException error = assertThrows(RuntimeException.class,
-                () -> service.updateMaintainRecord(vo));
-
-        assertEquals("仅支持供水设备维护记录", error.getMessage());
-        verify(equipmentMaintainMapper, never()).updateById(any(EquipmentMaintain.class));
-    }
-
-    @Test
-    void deleteMaintainRecordRejectsNonWaterRecords() {
-        when(equipmentMaintainMapper.selectById("gas-record"))
-                .thenReturn(maintain("gas-record", gasDevice.getEquipmentId()));
-
-        RuntimeException error = assertThrows(RuntimeException.class,
-                () -> service.deleteMaintainRecord("gas-record"));
-
-        assertEquals("仅支持供水设备维护记录", error.getMessage());
-        verify(equipmentMaintainMapper, never()).deleteById("gas-record");
-    }
-
-    @Test
-    void returnsEmptyRecordsWhenRequestedPageIsBeyondAbnormalDevices() {
-        when(equipmentStatusMapper.selectList(any())).thenReturn(Collections.singletonList(
-                status(pressureDevice.getEquipmentId(), 1, 1, 1)));
-        Page<AbnormalDeviceVO> result = assertDoesNotThrow(() -> service.getAbnormalDevicePage(
-                2, 10, null, null, null, null));
-
-        assertEquals(1, result.getTotal());
-        assertEquals(0, result.getRecords().size());
-    }
-
     private static EquipmentBase device(String id, String code, String name, String typeId) {
         EquipmentBase device = new EquipmentBase();
         device.setEquipmentId(id);
@@ -804,11 +366,6 @@ class WaterSupplyDeviceServiceImplTest {
         return order;
     }
 
-    private static WorkOrder workOrder(String deviceId, String orderNo, int orderStatus) {
-        return workOrder(deviceId, orderNo, orderStatus, null);
-    }
-
-
     private static SysUser sysUser(Long userId, String userName, String nickName) {
         SysUser user = new SysUser();
         user.setUserId(userId);

+ 0 - 14
zk-api-service/src/main/java/com/zksy/api/domain/EquipmentStatus.java

@@ -33,20 +33,6 @@ public class EquipmentStatus {
     @TableField(value = "online_status")
     private Integer onlineStatus;
 
-    @TableField(value = "user_id")
-    private Long userId;
-
-    @TableField(value = "installation_addr")
-    private String installationAddr;
-
-    @TableField(value = "last_maintain_date")
-    @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
-    private Date lastMaintainDate;
-
-    @TableField(value = "next_maintain_date")
-    @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
-    private Date nextMaintainDate;
-
     @TableField(value = "status_update_time")
     @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
     private LocalDateTime statusUpdateTime;