From e2e8eb99ea59a4bbbc887dfb4cf5e7efdb05ed22 Mon Sep 17 00:00:00 2001 From: wanglei <3085637232@qq.com> Date: Tue, 30 Dec 2025 15:32:45 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/campus/water/service/AreaService.java | 144 +++++++++++++++--- 1 file changed, 121 insertions(+), 23 deletions(-) diff --git a/src/main/java/com/campus/water/service/AreaService.java b/src/main/java/com/campus/water/service/AreaService.java index 49c99c1..7aaaddd 100644 --- a/src/main/java/com/campus/water/service/AreaService.java +++ b/src/main/java/com/campus/water/service/AreaService.java @@ -1,11 +1,14 @@ -// src/main/java/com/campus/water/service/AreaService.java package com.campus.water.service; import com.campus.water.entity.Area; +import com.campus.water.entity.Device; import com.campus.water.mapper.AreaRepository; import com.campus.water.entity.Admin; import com.campus.water.mapper.AdminRepository; +import com.campus.water.mapper.DeviceRepository; +import com.campus.water.mapper.DeviceTerminalMappingRepository; import com.campus.water.security.RoleConstants; +import com.campus.water.entity.vo.AreaDeviceStatsVO; import org.springframework.beans.factory.annotation.Autowired; import java.util.List; import org.springframework.stereotype.Service; @@ -14,6 +17,7 @@ import org.springframework.transaction.annotation.Transactional; import java.time.LocalDateTime; import java.util.List; import java.util.Optional; +import java.util.stream.Collectors; /** * 区域管理服务类 @@ -27,10 +31,17 @@ public class AreaService { // 新增:管理员仓库注入 private final AdminRepository adminRepository; - // 改造构造器,添加AdminRepository参数 - public AreaService(AreaRepository areaRepository, AdminRepository adminRepository) { + // 新增:注入现有设备、终端映射Repository(无新增Mapper方法) + private final DeviceRepository deviceRepository; + private final DeviceTerminalMappingRepository deviceTerminalMappingRepository; + + public AreaService(AreaRepository areaRepository, AdminRepository adminRepository, + DeviceRepository deviceRepository, + DeviceTerminalMappingRepository deviceTerminalMappingRepository) { this.areaRepository = areaRepository; this.adminRepository = adminRepository; + this.deviceRepository = deviceRepository; + this.deviceTerminalMappingRepository = deviceTerminalMappingRepository; } /** @@ -96,14 +107,7 @@ public class AreaService { existingArea.setUpdatedTime(LocalDateTime.now()); // 5. 保存修改 - Area updatedArea = areaRepository.save(existingArea); - - // 6. 更新关联管理员的areaId - if (existingArea.getManager() != null && !existingArea.getManager().trim().isEmpty()) { - bindAdminToArea(existingArea.getManager(), updatedArea.getAreaId()); - } - - return updatedArea; + return areaRepository.save(existingArea); } /** @@ -203,11 +207,8 @@ public class AreaService { String adminId = area.getManager(); if (adminId != null && !adminId.trim().isEmpty()) { // 校验管理员是否存在 - Optional adminOpt = adminRepository.findByAdminId(adminId); - if (adminOpt.isEmpty()) { - throw new RuntimeException("区域管理员不存在,ID:" + adminId); - } - Admin admin = adminOpt.get(); + Admin admin = adminRepository.findById(adminId) + .orElseThrow(() -> new RuntimeException("区域管理员不存在,ID:" + adminId)); // 校验管理员角色是否为区域管理员 if (!RoleConstants.ROLE_AREA_ADMIN.equals(admin.getRole().name())) { @@ -223,15 +224,112 @@ public class AreaService { */ private void bindAdminToArea(String adminId, String areaId) { if (adminId != null && !adminId.trim().isEmpty() && areaId != null) { - Optional adminOpt = adminRepository.findByAdminId(adminId); - if (adminOpt.isPresent()) { - Admin admin = adminOpt.get(); - admin.setAreaId(areaId); // 给管理员设置关联的区域ID - adminRepository.save(admin); - } else { - throw new RuntimeException("管理员不存在,ID:" + adminId); + Admin admin = adminRepository.findById(adminId).get(); // 已在前序校验,无需再次处理空值 + admin.setAreaId(areaId); // 给管理员设置关联的区域ID(Admin实体需有areaId字段) + adminRepository.save(admin); + } + } + + + /** + * 获取指定片区的设备统计(校区:自身数据;市区:自身+下属所有校区汇总数据) + * @param areaId 片区ID(市区/校园) + * @return 片区设备统计结果(适配现有实体) + */ + @Transactional(readOnly = true) // 只读事务提升查询性能,不修改数据 + public AreaDeviceStatsVO getAreaDeviceStats(String areaId) { + // 1. 校验片区是否存在,获取片区基础信息 + Area targetArea = getAreaById(areaId); + AreaDeviceStatsVO statsVO = new AreaDeviceStatsVO(); + + // 2. 填充片区基础信息(复用Area实体字段) + statsVO.setAreaId(targetArea.getAreaId()); + statsVO.setAreaName(targetArea.getAreaName()); + statsVO.setAreaTypeDesc(targetArea.getAreaType().getDesc()); + + // 3. 区分片区类型执行统计(核心逻辑,复用现有Mapper方法) + if (Area.AreaType.campus.equals(targetArea.getAreaType())) { + // 校区:仅统计自身关联的设备/终端 + fillSelfDeviceStats(statsVO, areaId); + } else if (Area.AreaType.zone.equals(targetArea.getAreaType())) { + // 市区:统计自身 + 下属所有校区的汇总数据 + fillCityTotalDeviceStats(statsVO, areaId); + } + + return statsVO; + } + + /** + * 填充单个片区(校区/市区自身)的设备统计数据(复用现有Mapper的count方法) + * @param statsVO 统计结果VO + * @param areaId 片区ID + */ + private void fillSelfDeviceStats(AreaDeviceStatsVO statsVO, String areaId) { + // 复用DeviceRepository.countByAreaIdAndDeviceType(已存在,无需新增) + long waterMakerCount = deviceRepository.countByAreaIdAndDeviceType( + areaId, Device.DeviceType.water_maker); // 假设Device枚举包含WATER_MAKER/WATER_SUPPLY + long waterSupplyCount = deviceRepository.countByAreaIdAndDeviceType( + areaId, Device.DeviceType.water_supply); + + // 复用DeviceTerminalMappingRepository.countByAreaId(已存在,无需新增) + long terminalCount = deviceTerminalMappingRepository.countByAreaId(areaId); + + // 赋值到VO(强转int,若数量过大可改为long,兼容现有数据) + statsVO.setWaterMakerCount((int) waterMakerCount); + statsVO.setWaterSupplyCount((int) waterSupplyCount); + statsVO.setTerminalCount((int) terminalCount); + } + + /** + * 填充市区的总设备统计数据(仅汇总下属所有校区,市区自身无设备/终端) + * @param statsVO 统计结果VO + * @param cityId 市区ID + */ + private void fillCityTotalDeviceStats(AreaDeviceStatsVO statsVO, String cityId) { + // 第一步:获取市区下属所有校区的ID列表(复用现有getCampusesByCityId方法) + List campusList = getCampusesByCityId(cityId); + List campusIds = campusList.stream() + .map(Area::getAreaId) + .collect(Collectors.toList()); + + // 第二步:汇总下属所有校区的设备/终端数量(循环复用现有count方法,适配现有Mapper) + long campusWaterMaker = 0; + long campusWaterSupply = 0; + long campusTerminal = 0; + if (!campusIds.isEmpty()) { + for (String campusId : campusIds) { + campusWaterMaker += deviceRepository.countByAreaIdAndDeviceType(campusId, Device.DeviceType.water_maker); + campusWaterSupply += deviceRepository.countByAreaIdAndDeviceType(campusId, Device.DeviceType.water_supply); + campusTerminal += deviceTerminalMappingRepository.countByAreaId(campusId); } } + + // 第三步:直接赋值校区汇总数据(市区自身无数据) + statsVO.setWaterMakerCount((int) campusWaterMaker); + statsVO.setWaterSupplyCount((int) campusWaterSupply); + statsVO.setTerminalCount((int) campusTerminal); + } + + /** + * 获取指定市区下所有校区的单独设备统计(每个校区各自的统计结果,不汇总) + * @param cityId 市区ID + * @return 校区统计列表(复用现有方法,无新增依赖) + */ + @Transactional(readOnly = true) + public List getCampusDeviceStatsUnderCity(String cityId) { + // 1. 校验市区存在且类型正确 + Area cityArea = getAreaById(cityId); + if (!Area.AreaType.zone.equals(cityArea.getAreaType())) { + throw new RuntimeException("指定区域不是市区,无法查询下属校区统计"); + } + + // 2. 获取下属所有校区(复用现有方法) + List campusList = getCampusesByCityId(cityId); + + // 3. 逐个生成校区统计结果(复用getAreaDeviceStats方法) + return campusList.stream() + .map(campus -> getAreaDeviceStats(campus.getAreaId())) + .collect(Collectors.toList()); } } \ No newline at end of file -- 2.34.1