package com.gkhy.fourierSpecialGasMonitor.service.impl; import com.gkhy.fourierSpecialGasMonitor.commons.domain.Result; import com.gkhy.fourierSpecialGasMonitor.commons.domain.SearchResult; import com.gkhy.fourierSpecialGasMonitor.commons.enums.ResultCode; import com.gkhy.fourierSpecialGasMonitor.commons.exception.BusinessException; import com.gkhy.fourierSpecialGasMonitor.commons.model.PageQuery; import com.gkhy.fourierSpecialGasMonitor.entity.SummaryStats; import com.gkhy.fourierSpecialGasMonitor.entity.req.SummaryStatsReqDTO; import com.gkhy.fourierSpecialGasMonitor.entity.resp.GasAtmospherePageRespDTO; import com.gkhy.fourierSpecialGasMonitor.entity.resp.SummaryStatsPageRespDTO; import com.gkhy.fourierSpecialGasMonitor.repository.SummaryStatsRepository; import com.gkhy.fourierSpecialGasMonitor.service.SummaryStatsService; import com.gkhy.fourierSpecialGasMonitor.utils.SummaryUtils; import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Sort; import org.springframework.data.jpa.domain.Specification; import org.springframework.stereotype.Service; import org.springframework.util.CollectionUtils; import javax.persistence.criteria.CriteriaBuilder; import javax.persistence.criteria.CriteriaQuery; import javax.persistence.criteria.Predicate; import javax.persistence.criteria.Root; import java.time.LocalDateTime; import java.util.*; import java.util.stream.Collectors; @Service public class SummaryStatsServiceImpl implements SummaryStatsService { @Autowired private SummaryStatsRepository summaryStatsRepository; @Override public void save(SummaryStats stats) { summaryStatsRepository.save(stats); } @Override public Result listSummaryStats(PageQuery pageQuery) { // 分页参数校验(复用已有逻辑,补充非空判断) if (pageQuery == null || pageQuery.getPageIndex() == null || pageQuery.getPageSize() == null) { throw new BusinessException(this.getClass(), ResultCode.PARAM_ERROR_NULL, "分页参数不能为空"); } // 校验分页索引和大小合法性(避免负数或过大值) if (pageQuery.getPageIndex() < 1 || pageQuery.getPageSize() < 1 || pageQuery.getPageSize() > 1000) { throw new BusinessException(this.getClass(), ResultCode.PARAM_ERROR, "分页索引必须≥1,分页大小必须在1-1000之间"); } //查询参数校验(处理 searchParams 为 null 的情况) SummaryStatsReqDTO searchParams = pageQuery.getSearchParams(); if (searchParams == null) { searchParams = new SummaryStatsReqDTO(); // 避免后续调用 NPE } LocalDateTime startTime = searchParams.getStartTime(); LocalDateTime endTime = searchParams.getEndTime(); String type = searchParams.getType(); // type 改为 String 类型 // 校验 type 合法性(允许为 null,若不为 null 则必须是指定值) List validTypes = Arrays.asList("temp", "humidity", "windSpeed", "windDirection", "pressure"); if (type != null && !validTypes.contains(type)) { throw new BusinessException(this.getClass(), ResultCode.PARAM_ERROR, "type 必须为 temp、humidity、windSpeed、windDirection、pressure 中的一种"); } // 初始化返回结果 SearchResult> searchResult = new SearchResult<>(); searchResult.setPageIndex(pageQuery.getPageIndex()); searchResult.setPageSize(pageQuery.getPageSize()); searchResult.setSuccess(); // 构建查询条件(使用 List 而非 Set,逻辑更清晰;补充时间范围非空判断) Specification specification = (root, query, criteriaBuilder) -> { List predicates = new ArrayList<>(); // 时间范围条件:仅当 start/endTime 非空时添加(避免 null 导致的查询异常) if (startTime != null && endTime != null) { predicates.add(criteriaBuilder.between(root.get("time"), startTime, endTime)); } else if (startTime != null) { predicates.add(criteriaBuilder.greaterThanOrEqualTo(root.get("time"), startTime)); } else if (endTime != null) { predicates.add(criteriaBuilder.lessThanOrEqualTo(root.get("time"), endTime)); } // 可扩展其他条件(如按位置、设备筛选) return criteriaBuilder.and(predicates.toArray(new Predicate[0])); }; // 构建分页参数(封装分页索引转换逻辑,避免硬编码) Pageable pageable = PageRequest.of(pageQuery.getPageIndex()-1, pageQuery.getPageSize(), Sort.Direction.DESC, "time"); // 执行查询 Page statsPage = summaryStatsRepository.findAll(specification, pageable); if (statsPage.isEmpty()) { return searchResult; // 空结果直接返回 } SummaryUtils summaryUtils = new SummaryUtils(); // 转换结果(使用枚举映射处理 type 逻辑) List respDTOS = statsPage.getContent().stream() .map(stats -> summaryUtils.convertToResp(stats, type)) .collect(Collectors.toList()); // 填充返回结果 searchResult.setTotal(statsPage.getTotalElements()); searchResult.setPages(statsPage.getTotalPages()); searchResult.setData(respDTOS); return searchResult; } }