Quellcode durchsuchen

feat(water): guard ledger create and delete for water devices

Kazerin vor 8 Stunden
Ursprung
Commit
b21dda02d2

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

@@ -7,6 +7,7 @@ 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;
@@ -101,4 +102,20 @@ public class DeviceLedgerController {
                 .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));
+    }
 }

+ 4 - 0
pipe-network-service/zksy-system/src/main/java/com/zksy/base/service/WaterSupplyDeviceService.java

@@ -22,6 +22,10 @@ public interface WaterSupplyDeviceService extends IService<EquipmentBase> {
                                              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);

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

@@ -253,6 +253,63 @@ public class WaterSupplyDeviceServiceImpl extends ServiceImpl<EquipmentBaseMappe
                 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(item.getId(), item);
+        }
+        EquipmentType cursor = type;
+        int guard = 0;
+        while (cursor != null && guard++ <= typesById.size()) {
+            if (waterTopLevelTypeName.equals(cursor.getTypeName()) && "0".equals(cursor.getParentTypeId())) {
+                return true;
+            }
+            cursor = typesById.get(cursor.getParentTypeId());
+        }
+        return false;
+    }
+
     @Override
     public List<DeviceGisVO> getAllDeviceGisPoints(String equipmentTypeId) {
         List<EquipmentBase> list = findWaterDevices().stream()

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

@@ -194,6 +194,40 @@ class WaterSupplyDeviceServiceImplTest {
                 .collect(Collectors.toList()));
     }
 
+    @Test
+    void createWaterDeviceAcceptsWaterTypeAndRejectsNonWaterType() {
+        EquipmentBase device = new EquipmentBase();
+        device.setEquipmentCode("WS-NEW-001");
+        device.setEquipmentName("新增供水设备");
+        device.setEquipmentTypeId("water-child");
+        when(equipmentTypeMapper.selectById("water-child"))
+                .thenReturn(type("water-child", "供水压力计", "water-root"));
+        when(equipmentTypeMapper.selectList(any())).thenReturn(Arrays.asList(
+                type("water-root", "供水", "0"),
+                type("water-child", "供水压力计", "water-root")));
+        doReturn(0L).when(service).count(any());
+        doReturn(true).when(service).save(any(EquipmentBase.class));
+
+        assertTrue(service.createWaterDevice(device));
+        assertEquals("water-child", device.getEquipmentTypeId());
+
+        EquipmentBase gasDevice = new EquipmentBase();
+        gasDevice.setEquipmentCode("GAS-NEW-001");
+        gasDevice.setEquipmentTypeId("gas-root");
+        when(equipmentTypeMapper.selectById("gas-root"))
+                .thenReturn(type("gas-root", "燃气", "0"));
+        RuntimeException error = assertThrows(RuntimeException.class,
+                () -> service.createWaterDevice(gasDevice));
+        assertEquals("设备类型不属于供水:gas-root", 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(