From 4c2d11e44c2960ccad17225d222d40b17e4dd4da Mon Sep 17 00:00:00 2001 From: wanglei <3085637232@qq.com> Date: Mon, 29 Dec 2025 10:57:18 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E6=A0=B9=E6=8D=AE=E7=89=87?= =?UTF-8?q?=E5=8C=BA=E5=A2=9E=E5=8A=A0=E7=BB=88=E7=AB=AF=E6=9C=BA=E4=BB=A3?= =?UTF-8?q?=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/web/DeviceController.java | 30 ++++++++ .../controller/web/TerminalController.java | 76 ++++++++++--------- .../water/entity/DeviceTerminalMapping.java | 3 + .../water/entity/vo/TerminalManageVO.java | 3 + .../campus/water/service/DeviceService.java | 45 +++++++++-- .../water/service/TerminalServiceImpl.java | 22 +++++- 6 files changed, 135 insertions(+), 44 deletions(-) diff --git a/src/main/java/com/campus/water/controller/web/DeviceController.java b/src/main/java/com/campus/water/controller/web/DeviceController.java index ffbbc2f..df5c356 100644 --- a/src/main/java/com/campus/water/controller/web/DeviceController.java +++ b/src/main/java/com/campus/water/controller/web/DeviceController.java @@ -203,4 +203,34 @@ public class DeviceController { } }*/ + // ========== 新增1:获取所有片区列表(假设从Device表中提取唯一片区ID,若有Area实体可直接查询) ========== + @GetMapping("/areas") + @Operation(summary = "获取所有片区列表", description = "返回系统中所有已配置的片区ID和相关信息") + public ResponseEntity>> getAllAreas() { + try { + // 从设备表中提取唯一的片区ID(若有独立Area表,可替换为AreaRepository查询) + List allDevices = deviceService.queryDevices(null, null, null); + List areaList = allDevices.stream() + .map(Device::getAreaId) + .filter(areaId -> areaId != null && !areaId.trim().isEmpty()) + .distinct() + .toList(); + return ResponseEntity.ok(ResultVO.success(areaList, "片区列表查询成功")); + } catch (Exception e) { + return ResponseEntity.ok(ResultVO.error(500, "片区列表查询失败: " + e.getMessage())); + } + } + + // ========== 新增2:根据片区ID查询该片区的供水机列表 ========== + @GetMapping("/area/{areaId}/water-supplies") + @Operation(summary = "查询片区内供水机", description = "根据片区ID获取该片区下所有可用的供水机") + public ResponseEntity>> getWaterSuppliesByArea(@PathVariable String areaId) { + try { + List waterSupplies = deviceService.getWaterSuppliesByArea(areaId); + return ResponseEntity.ok(ResultVO.success(waterSupplies, "片区供水机查询成功")); + } catch (Exception e) { + return ResponseEntity.ok(ResultVO.error(500, "片区供水机查询失败: " + e.getMessage())); + } + } + } \ No newline at end of file diff --git a/src/main/java/com/campus/water/controller/web/TerminalController.java b/src/main/java/com/campus/water/controller/web/TerminalController.java index ce99ca8..f0a0ec4 100644 --- a/src/main/java/com/campus/water/controller/web/TerminalController.java +++ b/src/main/java/com/campus/water/controller/web/TerminalController.java @@ -29,80 +29,86 @@ public class TerminalController { @PostMapping("/add") @PreAuthorize("hasAnyRole('SUPER_ADMIN', 'AREA_ADMIN')") - @Operation(summary = "新增终端", description = "同时保存终端位置和基础映射信息") - // 泛型改为?,兼容TerminalManageVO和Map - public ResponseEntity addTerminal(@Valid @RequestBody TerminalManageVO terminalVO) { + @Operation(summary = "新增终端", description = "同时保存终端位置、基础映射信息和片区信息") + public ResponseEntity> addTerminal(@Valid @RequestBody TerminalManageVO terminalVO) { try { TerminalManageVO newTerminal = terminalService.addTerminal(terminalVO); - return new ResponseEntity<>(newTerminal, HttpStatus.CREATED); + return ResponseEntity.ok(ResultVO.success(newTerminal, "终端新增成功")); } catch (Exception e) { - Map errorMap = new HashMap<>(); - errorMap.put("message", "终端新增失败: " + e.getMessage()); - return new ResponseEntity<>(errorMap, HttpStatus.BAD_REQUEST); + return ResponseEntity.ok(ResultVO.error(500, "终端新增失败: " + e.getMessage())); } } @PutMapping("/update") @PreAuthorize("hasAnyRole('SUPER_ADMIN', 'AREA_ADMIN')") - @Operation(summary = "更新终端", description = "支持更新终端名称、状态、经纬度等信息") - // 泛型改为?,兼容TerminalManageVO和Map - public ResponseEntity updateTerminal(@Valid @RequestBody TerminalManageVO terminalVO) { + @Operation(summary = "更新终端", description = "支持更新终端名称、状态、经纬度、片区等信息") + public ResponseEntity> updateTerminal(@Valid @RequestBody TerminalManageVO terminalVO) { try { TerminalManageVO updated = terminalService.updateTerminal(terminalVO); - return ResponseEntity.ok(updated); + return ResponseEntity.ok(ResultVO.success(updated, "终端更新成功")); } catch (Exception e) { - Map errorMap = new HashMap<>(); - errorMap.put("message", "终端更新失败: " + e.getMessage()); - return new ResponseEntity<>(errorMap, HttpStatus.BAD_REQUEST); + return ResponseEntity.ok(ResultVO.error(500, "终端更新失败: " + e.getMessage())); } } + /** + * 删除终端 + * 先校验设备绑定状态,再级联删除终端位置表和映射表的相关数据 + */ @DeleteMapping("/delete/{terminalId}") @PreAuthorize("hasAnyRole('SUPER_ADMIN', 'AREA_ADMIN')") @Operation(summary = "删除终端", description = "先校验设备绑定状态,再级联删除相关数据") - // 该方法成功/失败均返回Map,泛型可保留Map(无冲突) - public ResponseEntity> deleteTerminal(@PathVariable String terminalId) { + public ResponseEntity> deleteTerminal(@PathVariable String terminalId) { try { + // 调用服务层删除终端 terminalService.deleteTerminal(terminalId); - Map successMap = new HashMap<>(); - successMap.put("message", "终端删除成功"); - return ResponseEntity.ok(successMap); + // 用ResultVO封装成功结果,返回提示信息 + return ResponseEntity.ok(ResultVO.success("终端删除成功")); } catch (Exception e) { - Map errorMap = new HashMap<>(); - errorMap.put("message", "终端删除失败: " + e.getMessage()); - return new ResponseEntity<>(errorMap, HttpStatus.BAD_REQUEST); + // 用ResultVO封装错误结果,携带异常信息 + return ResponseEntity.ok(ResultVO.error(500, "终端删除失败: " + e.getMessage())); } } + /** + * 查询终端详情 + * 根据终端ID获取整合后的完整信息(包含位置、映射、片区areaId信息) + */ @GetMapping("/{terminalId}") @PreAuthorize("hasAnyRole('SUPER_ADMIN', 'AREA_ADMIN')") @Operation(summary = "查询终端详情", description = "根据终端ID获取整合后的完整信息") - // 泛型改为?,兼容TerminalManageVO和Map - public ResponseEntity getTerminal(@PathVariable String terminalId) { + public ResponseEntity> getTerminal(@PathVariable String terminalId) { try { + // 调用服务层查询终端详情,返回包含areaId的VO TerminalManageVO terminal = terminalService.getTerminalById(terminalId); - return ResponseEntity.ok(terminal); + // 用ResultVO封装成功结果,自定义提示信息 + return ResponseEntity.ok(ResultVO.success(terminal, "终端查询成功")); } catch (Exception e) { - Map errorMap = new HashMap<>(); - errorMap.put("message", "终端查询失败: " + e.getMessage()); - return new ResponseEntity<>(errorMap, HttpStatus.NOT_FOUND); + // 用ResultVO封装404错误结果,携带异常信息 + return ResponseEntity.ok(ResultVO.notFound("终端查询失败: " + e.getMessage())); } } + + /** + * 查询终端列表 + * 支持按终端名称模糊筛选,返回整合后的完整列表(每条数据均包含areaId) + */ @GetMapping("/list") @PreAuthorize("hasAnyRole('SUPER_ADMIN', 'AREA_ADMIN')") @Operation(summary = "查询终端列表", description = "支持按终端名称模糊筛选") - // 泛型改为?,兼容List和Map - public ResponseEntity getTerminalList( + public ResponseEntity>> getTerminalList( @RequestParam(required = false) String terminalName) { try { - List terminals = terminalService.getTerminalList(terminalName); - return ResponseEntity.ok(terminals); + // 调用服务层查询终端列表,返回包含areaId的VO列表 + List terminalList = terminalService.getTerminalList(terminalName); + // 用ResultVO封装成功结果,自定义提示信息 + return ResponseEntity.ok(ResultVO.success(terminalList, "终端列表查询成功")); } catch (Exception e) { - Map errorMap = new HashMap<>(); - errorMap.put("message", "终端列表查询失败: " + e.getMessage()); - return new ResponseEntity<>(errorMap, HttpStatus.BAD_REQUEST); + // 用ResultVO封装错误结果,携带异常信息 + return ResponseEntity.ok(ResultVO.error(500, "终端列表查询失败: " + e.getMessage())); } } + } \ No newline at end of file diff --git a/src/main/java/com/campus/water/entity/DeviceTerminalMapping.java b/src/main/java/com/campus/water/entity/DeviceTerminalMapping.java index 22f4a9a..8d2b696 100644 --- a/src/main/java/com/campus/water/entity/DeviceTerminalMapping.java +++ b/src/main/java/com/campus/water/entity/DeviceTerminalMapping.java @@ -22,6 +22,9 @@ public class DeviceTerminalMapping { @Column(name = "device_id", length = 20) private String deviceId; + @Column(name = "area_id", length = 36) + private String areaId; + @Column(name = "terminal_id", length = 20) private String terminalId; diff --git a/src/main/java/com/campus/water/entity/vo/TerminalManageVO.java b/src/main/java/com/campus/water/entity/vo/TerminalManageVO.java index 96090ae..855cfe4 100644 --- a/src/main/java/com/campus/water/entity/vo/TerminalManageVO.java +++ b/src/main/java/com/campus/water/entity/vo/TerminalManageVO.java @@ -31,4 +31,7 @@ public class TerminalManageVO { // 设备ID(关联的设备,来自映射表) private String deviceId; + + // ========== 新增:片区ID字段(前端传递选中的片区ID) ========== + private String areaId; } \ No newline at end of file diff --git a/src/main/java/com/campus/water/service/DeviceService.java b/src/main/java/com/campus/water/service/DeviceService.java index ed5f841..1e8cfbf 100644 --- a/src/main/java/com/campus/water/service/DeviceService.java +++ b/src/main/java/com/campus/water/service/DeviceService.java @@ -12,6 +12,7 @@ import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import java.time.LocalDate; import java.time.LocalDateTime; import java.util.List; import java.util.Optional; @@ -112,23 +113,28 @@ public class DeviceService { /** * 关联设备与终端 */ + // ========== 改造:原有bindTerminal方法,添加areaId参数和校验 ========== @Transactional - public DeviceTerminalMapping bindTerminal(String deviceId, String terminalId, String terminalName) { - // 校验设备是否存在 - getDeviceById(deviceId); - - // 检查终端是否已绑定 + public DeviceTerminalMapping bindTerminal(String deviceId, String terminalId, String terminalName, String areaId) { + // 1. 校验片区非空(终端必须归属片区) + if (areaId == null || areaId.trim().isEmpty()) { + throw new RuntimeException("片区ID不能为空,请先选择片区"); + } + // 2. 校验设备存在且属于该片区的供水机 + validateDeviceBelongsToArea(deviceId, areaId); + // 3. 检查终端是否已绑定(原有逻辑保留) Optional existing = terminalMappingRepository.findByTerminalId(terminalId); if (existing.isPresent()) { throw new RuntimeException("终端已绑定设备:" + existing.get().getDeviceId()); } - + // 4. 构建映射对象(新增设置areaId) DeviceTerminalMapping mapping = new DeviceTerminalMapping(); mapping.setDeviceId(deviceId); mapping.setTerminalId(terminalId); mapping.setTerminalName(terminalName); - mapping.setTerminalStatus(TerminalStatus.active); - mapping.setInstallDate(java.time.LocalDate.now()); + mapping.setTerminalStatus(DeviceTerminalMapping.TerminalStatus.active); + mapping.setInstallDate(LocalDate.now()); + mapping.setAreaId(areaId); // 保存终端所属片区 return terminalMappingRepository.save(mapping); } @@ -222,6 +228,29 @@ public class DeviceService { return deviceRepository.findById(supplier.getParentMakerId()).orElse(null); } + // ========== 新增1:查询指定片区的所有供水机 ========== + public List getWaterSuppliesByArea(String areaId) { + // 1. 校验片区ID非空 + if (areaId == null || areaId.trim().isEmpty()) { + throw new RuntimeException("片区ID不能为空"); + } + // 2. 查询该片区下类型为供水机的设备 + return deviceRepository.findByAreaIdAndDeviceType(areaId, Device.DeviceType.water_supply); + } + + // ========== 新增2:校验设备是否属于指定片区 ========== + public void validateDeviceBelongsToArea(String deviceId, String areaId) { + // 1. 校验设备存在 + Device device = getDeviceById(deviceId); + // 2. 校验设备是供水机 + if (!Device.DeviceType.water_supply.equals(device.getDeviceType())) { + throw new RuntimeException("只能关联供水机设备,当前设备类型不合法"); + } + // 3. 校验设备所属片区与选中片区一致 + if (!areaId.equals(device.getAreaId())) { + throw new RuntimeException("该供水机不属于所选片区(设备所属片区:" + device.getAreaId() + ")"); + } + } } \ No newline at end of file diff --git a/src/main/java/com/campus/water/service/TerminalServiceImpl.java b/src/main/java/com/campus/water/service/TerminalServiceImpl.java index 655dc2c..9700fc3 100644 --- a/src/main/java/com/campus/water/service/TerminalServiceImpl.java +++ b/src/main/java/com/campus/water/service/TerminalServiceImpl.java @@ -21,6 +21,8 @@ public class TerminalServiceImpl implements TerminalService { private final WaterTerminalLocationRepository locationRepository; private final DeviceTerminalMappingRepository mappingRepository; + // ========== 新增:注入DeviceService,用于片区和供水机校验 ========== + private final DeviceService deviceService; @Override @Transactional @@ -34,6 +36,14 @@ public class TerminalServiceImpl implements TerminalService { if (terminalVO.getLongitude() == null || terminalVO.getLatitude() == null) { throw new RuntimeException("终端经度和纬度为必填项,不可为空"); } + // ========== 新增:校验片区ID非空 ========== + if (terminalVO.getAreaId() == null || terminalVO.getAreaId().trim().isEmpty()) { + throw new RuntimeException("片区ID不能为空,请先选择片区"); + } + // ========== 新增:若传递了deviceId,校验供水机是否属于该片区 ========== + if (terminalVO.getDeviceId() != null && !terminalVO.getDeviceId().trim().isEmpty()) { + deviceService.validateDeviceBelongsToArea(terminalVO.getDeviceId(), terminalVO.getAreaId()); + } WaterTerminalLocation location = new WaterTerminalLocation(); location.setTerminalId(terminalVO.getTerminalId()); location.setLongitude(terminalVO.getLongitude()); @@ -49,6 +59,7 @@ public class TerminalServiceImpl implements TerminalService { : terminalVO.getTerminalStatus()); mapping.setDeviceId(terminalVO.getDeviceId()); mapping.setInstallDate(terminalVO.getInstallDate()); + mapping.setAreaId(terminalVO.getAreaId()); // 保存片区ID mappingRepository.save(mapping); // 4. 封装返回结果 @@ -61,7 +72,12 @@ public class TerminalServiceImpl implements TerminalService { // 1. 校验终端是否存在(通过位置表查询,复用原有findById方法) WaterTerminalLocation existingLocation = locationRepository.findById(terminalVO.getTerminalId()) .orElseThrow(() -> new RuntimeException("终端不存在,无法更新:" + terminalVO.getTerminalId())); - + // ========== 新增:若更新片区/设备,校验供水机与片区的关联 ========== + if (terminalVO.getAreaId() != null && !terminalVO.getAreaId().trim().isEmpty()) { + if (terminalVO.getDeviceId() != null && !terminalVO.getDeviceId().trim().isEmpty()) { + deviceService.validateDeviceBelongsToArea(terminalVO.getDeviceId(), terminalVO.getAreaId()); + } + } // 2. 更新终端位置信息(仅更新有值字段,复用原有save方法) if (terminalVO.getLongitude() != null) { existingLocation.setLongitude(terminalVO.getLongitude()); @@ -87,6 +103,9 @@ public class TerminalServiceImpl implements TerminalService { if (terminalVO.getInstallDate() != null) { existingMapping.setInstallDate(terminalVO.getInstallDate()); } + if (terminalVO.getAreaId() != null && !terminalVO.getAreaId().trim().isEmpty()) { + existingMapping.setAreaId(terminalVO.getAreaId()); // 更新片区ID + } mappingRepository.save(existingMapping); // 4. 封装返回结果 @@ -166,6 +185,7 @@ public void deleteTerminal(String terminalId) { vo.setTerminalStatus(mapping.getTerminalStatus()); vo.setDeviceId(mapping.getDeviceId()); vo.setInstallDate(mapping.getInstallDate()); + vo.setAreaId(mapping.getAreaId()); // 封装片区ID返回给前端 return vo; } } \ No newline at end of file -- 2.34.1