|
|
@@ -16,10 +16,12 @@ import com.zksy.base.manhole.mapper.ManholeDataMapper;
|
|
|
import com.zksy.base.mapper.*;
|
|
|
import com.zksy.base.service.EquipmentBaseService;
|
|
|
import com.zksy.common.exception.ServiceException;
|
|
|
+import com.zksy.manhole.dto.in.AlarmMonitorListInDTO;
|
|
|
import com.zksy.manhole.dto.in.EquipmentCountByTypeInDTO;
|
|
|
import com.zksy.manhole.dto.in.EquipmentExportInDTO;
|
|
|
import com.zksy.manhole.dto.in.ManholeDeviceListInDTO;
|
|
|
import com.zksy.manhole.dto.in.ManholeDevicePageInDTO;
|
|
|
+import com.zksy.manhole.dto.in.ManholeDeviceStatisticsInDTO;
|
|
|
import com.zksy.manhole.dto.out.*;
|
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
import org.apache.commons.lang3.StringUtils;
|
|
|
@@ -27,6 +29,8 @@ import org.springframework.beans.factory.annotation.Autowired;
|
|
|
import org.springframework.stereotype.Service;
|
|
|
import org.springframework.transaction.annotation.Transactional;
|
|
|
|
|
|
+import java.math.BigDecimal;
|
|
|
+import java.math.RoundingMode;
|
|
|
import java.time.LocalDateTime;
|
|
|
import java.util.*;
|
|
|
import java.util.function.Function;
|
|
|
@@ -67,6 +71,9 @@ public class EquipmentBaseServiceImpl extends ServiceImpl<EquipmentBaseMapper, E
|
|
|
@Autowired
|
|
|
private PipeNetworkBaseMapper pipeNetworkBaseMapper;
|
|
|
|
|
|
+ @Autowired
|
|
|
+ private WorkOrderMapper workOrderMapper;
|
|
|
+
|
|
|
@Override
|
|
|
public Page<EquipmentBase> findByPage(long pageNum, long pageSize,
|
|
|
String equipmentCode, String equipmentName,
|
|
|
@@ -256,7 +263,7 @@ public class EquipmentBaseServiceImpl extends ServiceImpl<EquipmentBaseMapper, E
|
|
|
*/
|
|
|
@Override
|
|
|
public Page<EquipmentBaseOutDTO> findManholeDeviceByPage(ManholeDevicePageInDTO pageInDTO) {
|
|
|
- log.info("分页查询监测设备台账列表-入参:{}", pageInDTO);
|
|
|
+ //log.info("分页查询监测设备台账列表-入参:{}", pageInDTO);
|
|
|
List<String> equipmentIds = null;
|
|
|
if(pageInDTO.getCurrentStatus() != null){
|
|
|
List<EquipmentStatus> equipmentStatusList = equipmentStatusMapper.selectList(new LambdaQueryWrapper<EquipmentStatus>()
|
|
|
@@ -268,8 +275,11 @@ public class EquipmentBaseServiceImpl extends ServiceImpl<EquipmentBaseMapper, E
|
|
|
}
|
|
|
Page<EquipmentBase> page = new Page<>(pageInDTO.getPageNum(), pageInDTO.getPageSize());
|
|
|
LambdaQueryWrapper<EquipmentBase> queryWrapper = new LambdaQueryWrapper<>();
|
|
|
- queryWrapper.eq(StringUtils.isNotEmpty(pageInDTO.getDeviceCode()), EquipmentBase::getEquipmentCode, pageInDTO.getDeviceCode())
|
|
|
- .eq(StringUtils.isNotEmpty(pageInDTO.getEquipmentTypeId()), EquipmentBase::getEquipmentTypeId, pageInDTO.getEquipmentTypeId())
|
|
|
+ // 窨井盖设备类型过滤:排水窨井(equipment_type_id=9)/供水窨井(equipment_type_id=10),筛选时仅查所选类别
|
|
|
+ List<String> manholeTypeIds = StringUtils.isNotEmpty(pageInDTO.getEquipmentTypeId())
|
|
|
+ ? Collections.singletonList(pageInDTO.getEquipmentTypeId()) : Arrays.asList("5", "9", "10");
|
|
|
+ queryWrapper.in(EquipmentBase::getEquipmentTypeId, manholeTypeIds)
|
|
|
+ .eq(StringUtils.isNotEmpty(pageInDTO.getDeviceCode()), EquipmentBase::getEquipmentCode, pageInDTO.getDeviceCode())
|
|
|
.in(CollUtil.isNotEmpty(equipmentIds), EquipmentBase::getEquipmentId, equipmentIds)
|
|
|
.like(StringUtils.isNotEmpty(pageInDTO.getDeviceName()), EquipmentBase::getEquipmentName, pageInDTO.getDeviceName())
|
|
|
.like(StringUtils.isNotEmpty(pageInDTO.getEquipmentLocation()), EquipmentBase::getEquipmentLocation, pageInDTO.getEquipmentLocation())
|
|
|
@@ -330,13 +340,78 @@ public class EquipmentBaseServiceImpl extends ServiceImpl<EquipmentBaseMapper, E
|
|
|
return outPage;
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * 窨井设备统计:区域分布(数量/占比)+ 类型分布(数量/占比)
|
|
|
+ * @param inDTO 筛选条件(区域/设备类型)
|
|
|
+ * @return regionDistribution + typeDistribution + total
|
|
|
+ */
|
|
|
+ @Override
|
|
|
+ public Map<String, Object> getManholeDeviceStatistics(ManholeDeviceStatisticsInDTO inDTO) {
|
|
|
+ // 窨井设备:排水窨井(equipment_type_id=9)/供水窨井(equipment_type_id=10),筛选时仅统计所选类别
|
|
|
+ List<String> manholeTypeIds = StringUtils.isNotEmpty(inDTO.getEquipmentTypeId())
|
|
|
+ ? Collections.singletonList(inDTO.getEquipmentTypeId()) : Arrays.asList("5", "9", "10");
|
|
|
+ List<EquipmentBase> devices = this.list(new LambdaQueryWrapper<EquipmentBase>()
|
|
|
+ .in(EquipmentBase::getEquipmentTypeId, manholeTypeIds)
|
|
|
+ .eq(StringUtils.isNotEmpty(inDTO.getDistrict()), EquipmentBase::getDistrict, inDTO.getDistrict()));
|
|
|
+ int total = devices.size();
|
|
|
+
|
|
|
+ // 区域分布:按所属片区(district)分组统计
|
|
|
+ Map<String, Long> regionCountMap = devices.stream()
|
|
|
+ .filter(d -> StringUtils.isNotBlank(d.getDistrict()))
|
|
|
+ .collect(Collectors.groupingBy(EquipmentBase::getDistrict, Collectors.counting()));
|
|
|
+ List<Map<String, Object>> regionDistribution = regionCountMap.entrySet().stream()
|
|
|
+ .sorted((a, b) -> Long.compare(b.getValue(), a.getValue()))
|
|
|
+ .map(e -> {
|
|
|
+ Map<String, Object> item = new HashMap<>();
|
|
|
+ item.put("name", e.getKey());
|
|
|
+ item.put("count", e.getValue());
|
|
|
+ item.put("percent", calcPercent(e.getValue(), total));
|
|
|
+ return item;
|
|
|
+ })
|
|
|
+ .collect(Collectors.toList());
|
|
|
+
|
|
|
+ // 类型分布:按设备类型分组统计(9=排水窨井设备,10=供水窨井设备)
|
|
|
+ Map<String, String> typeNameMap = new HashMap<>();
|
|
|
+ typeNameMap.put("9", "排水窨井设备");
|
|
|
+ typeNameMap.put("10", "供水窨井设备");
|
|
|
+ Map<String, Long> typeCountMap = devices.stream()
|
|
|
+ .filter(d -> StringUtils.isNotBlank(d.getEquipmentTypeId()))
|
|
|
+ .collect(Collectors.groupingBy(EquipmentBase::getEquipmentTypeId, Collectors.counting()));
|
|
|
+ List<Map<String, Object>> typeDistribution = typeCountMap.entrySet().stream()
|
|
|
+ .sorted((a, b) -> Long.compare(b.getValue(), a.getValue()))
|
|
|
+ .map(e -> {
|
|
|
+ Map<String, Object> item = new HashMap<>();
|
|
|
+ item.put("name", typeNameMap.getOrDefault(e.getKey(), e.getKey()));
|
|
|
+ item.put("count", e.getValue());
|
|
|
+ item.put("percent", calcPercent(e.getValue(), total));
|
|
|
+ return item;
|
|
|
+ })
|
|
|
+ .collect(Collectors.toList());
|
|
|
+
|
|
|
+ Map<String, Object> result = new HashMap<>();
|
|
|
+ result.put("total", total);
|
|
|
+ result.put("regionDistribution", regionDistribution);
|
|
|
+ result.put("typeDistribution", typeDistribution);
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 计算占比(保留1位小数)
|
|
|
+ */
|
|
|
+ private BigDecimal calcPercent(Long count, int total) {
|
|
|
+ if (total <= 0) {
|
|
|
+ return BigDecimal.ZERO;
|
|
|
+ }
|
|
|
+ return new BigDecimal(count * 100.0 / total).setScale(1, RoundingMode.HALF_UP);
|
|
|
+ }
|
|
|
+
|
|
|
/**
|
|
|
* 查询井盖监测设备列表
|
|
|
* @param listInDTO
|
|
|
* @return
|
|
|
*/
|
|
|
@Override
|
|
|
- public List<EquipmentBaseOutDTO> getManholeDataList(ManholeDeviceListInDTO listInDTO) {
|
|
|
+ public Page<EquipmentBaseOutDTO> getManholeDataList(ManholeDeviceListInDTO listInDTO) {
|
|
|
log.info("查询井盖监测设备列表-入参:{}", listInDTO);
|
|
|
List<String> equipmentIds = null;
|
|
|
if(listInDTO.getCurrentStatus() != null || listInDTO.getAlarmStatus() != null || listInDTO.getOnlineStatus() != null){
|
|
|
@@ -345,12 +420,18 @@ public class EquipmentBaseServiceImpl extends ServiceImpl<EquipmentBaseMapper, E
|
|
|
.eq(listInDTO.getAlarmStatus() != null, EquipmentStatus::getAlarmStatus, listInDTO.getAlarmStatus())
|
|
|
.eq(listInDTO.getOnlineStatus() != null, EquipmentStatus::getOnlineStatus, listInDTO.getOnlineStatus()));
|
|
|
if(CollUtil.isEmpty(equipmentStatusList)){
|
|
|
- return new ArrayList<>();
|
|
|
+ return new Page<>(1, 10, 0);
|
|
|
}
|
|
|
equipmentIds = equipmentStatusList.stream().map(EquipmentStatus::getEquipmentId).distinct().collect(Collectors.toList());
|
|
|
}
|
|
|
+ // 仅查询窨井类型设备:排水窨井(equipment_type_id=9)/供水窨井(equipment_type_id=10)
|
|
|
+ List<String> manholeTypeIds = Arrays.asList("5", "9", "10");
|
|
|
+ // 按报警级别过滤时需要 manholeData 参与判定,须全量查出后内存过滤+内存分页
|
|
|
+ boolean needLevelFilter = listInDTO.getAlarmLevel() != null;
|
|
|
+ boolean needManholeData = Boolean.TRUE.equals(listInDTO.getIsQueryManholeData()) || needLevelFilter;
|
|
|
LambdaQueryWrapper<EquipmentBase> queryWrapper = new LambdaQueryWrapper<>();
|
|
|
- queryWrapper.in(CollUtil.isNotEmpty(equipmentIds), EquipmentBase::getEquipmentId, equipmentIds)
|
|
|
+ queryWrapper.in(EquipmentBase::getEquipmentTypeId, manholeTypeIds)
|
|
|
+ .in(CollUtil.isNotEmpty(equipmentIds), EquipmentBase::getEquipmentId, equipmentIds)
|
|
|
.and(StringUtils.isNotBlank(listInDTO.getKeyword()), wrapper -> wrapper
|
|
|
.like(EquipmentBase::getEquipmentCode, listInDTO.getKeyword())
|
|
|
.or()
|
|
|
@@ -358,59 +439,321 @@ public class EquipmentBaseServiceImpl extends ServiceImpl<EquipmentBaseMapper, E
|
|
|
.or()
|
|
|
.like(EquipmentBase::getEquipmentLocation, listInDTO.getKeyword()))
|
|
|
.orderByDesc(EquipmentBase::getUpdateTime);
|
|
|
- List<EquipmentBase> equipmentBaseList = this.list(queryWrapper);
|
|
|
- if (CollUtil.isEmpty(equipmentBaseList)) {
|
|
|
+
|
|
|
+ Page<EquipmentBase> rs;
|
|
|
+ if (needLevelFilter) {
|
|
|
+ // 报警级别需基于最新监测数据判定,先全量查询再内存过滤/分页
|
|
|
+ List<EquipmentBase> allList = this.list(queryWrapper);
|
|
|
+ rs = new Page<>(1, Math.max(allList.size(), 1), allList.size());
|
|
|
+ rs.setRecords(allList);
|
|
|
+ } else if (listInDTO.getPageNum() != null && listInDTO.getPageSize() != null) {
|
|
|
+ Page<EquipmentBase> page = new Page<>(listInDTO.getPageNum(), listInDTO.getPageSize());
|
|
|
+ rs = this.page(page, queryWrapper);
|
|
|
+ } else {
|
|
|
+ List<EquipmentBase> allList = this.list(queryWrapper);
|
|
|
+ rs = new Page<>(1, Math.max(allList.size(), 1), allList.size());
|
|
|
+ rs.setRecords(allList);
|
|
|
+ }
|
|
|
+ List<EquipmentBaseOutDTO> outDTOList = BeanUtil.copyToList(rs.getRecords(), EquipmentBaseOutDTO.class);
|
|
|
+ if (CollUtil.isNotEmpty(outDTOList)) {
|
|
|
+ //查询设备类型
|
|
|
+ List<String> equipmentTypeIdList = outDTOList.stream().map(EquipmentBaseOutDTO::getEquipmentTypeId).distinct().collect(Collectors.toList());
|
|
|
+ LambdaQueryWrapper<EquipmentType> batchQw = new LambdaQueryWrapper<>();
|
|
|
+ batchQw.in(EquipmentType::getId, equipmentTypeIdList);
|
|
|
+ List<EquipmentType> equipmentTypeList = equipmentTypeMapper.selectList(batchQw);
|
|
|
+ Map<String, EquipmentType> equipmentTypeMap = new HashMap<>();
|
|
|
+ if(CollUtil.isNotEmpty(equipmentTypeList)){
|
|
|
+ equipmentTypeMap.putAll(equipmentTypeList.stream().collect(
|
|
|
+ Collectors.toMap(t -> String.valueOf(t.getId()), Function.identity(), (key1, key2) -> key2)));
|
|
|
+ }
|
|
|
+ //查询设备状态
|
|
|
+ List<String> equipmentIdList = outDTOList.stream().map(EquipmentBaseOutDTO::getEquipmentId).distinct().collect(Collectors.toList());
|
|
|
+ List<EquipmentStatus> equipmentStatusList = equipmentStatusMapper.selectList(new LambdaQueryWrapper<EquipmentStatus>()
|
|
|
+ .in(EquipmentStatus::getEquipmentId, equipmentIdList));
|
|
|
+ Map<String, EquipmentStatus> equipmentStatusMap = new HashMap<>();
|
|
|
+ if(CollUtil.isNotEmpty(equipmentStatusList)){
|
|
|
+ equipmentStatusMap.putAll(equipmentStatusList.stream().collect(Collectors.toMap(EquipmentStatus::getEquipmentId, Function.identity(), (key1, key2) -> key2)));
|
|
|
+ }
|
|
|
+ //查询设备监测状态
|
|
|
+ Map<String, List<ManholeData>> imeiCardNumberMapList = new HashMap<>();
|
|
|
+ if(needManholeData){
|
|
|
+ List<String> equipmentCodeList = outDTOList.stream().map(EquipmentBaseOutDTO::getEquipmentCode).distinct().collect(Collectors.toList());
|
|
|
+ List<ManholeData> manholeDataList = manholeDataMapper.selectList(new LambdaQueryWrapper<ManholeData>()
|
|
|
+ .in(ManholeData::getImeiCardNumber, equipmentCodeList)
|
|
|
+ .orderByDesc(ManholeData::getCreateTime));
|
|
|
+ imeiCardNumberMapList.putAll(manholeDataList.stream().collect(Collectors.groupingBy(ManholeData::getImeiCardNumber)));
|
|
|
+ }
|
|
|
+ List<ManholeData> manholeDataList = null;
|
|
|
+ for(EquipmentBaseOutDTO outDTO : outDTOList) {
|
|
|
+ EquipmentType equipmentType = equipmentTypeMap.get(outDTO.getEquipmentTypeId());
|
|
|
+ if(equipmentType != null){
|
|
|
+ outDTO.setEquipmentTypeName(equipmentType.getTypeName());
|
|
|
+ }
|
|
|
+ EquipmentStatus equipmentStatus = equipmentStatusMap.get(outDTO.getEquipmentId());
|
|
|
+ if(equipmentStatus != null){
|
|
|
+ EquipmentStatusOutDTO equipmentStatusOutDTO = BeanUtil.copyProperties(equipmentStatus, EquipmentStatusOutDTO.class);
|
|
|
+ outDTO.setEquipmentStatus(equipmentStatusOutDTO);
|
|
|
+ }
|
|
|
+ if(needManholeData){
|
|
|
+ manholeDataList = imeiCardNumberMapList.get(outDTO.getEquipmentCode());
|
|
|
+ if(CollUtil.isNotEmpty(manholeDataList)){
|
|
|
+ ManholeData manholeData = manholeDataList.get(0);
|
|
|
+ ManholeDataOutDTO manholeDataOutDTO = BeanUtil.copyProperties(manholeData, ManholeDataOutDTO.class);
|
|
|
+ outDTO.setManholeData(manholeDataOutDTO);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ long total;
|
|
|
+ List<EquipmentBaseOutDTO> pageRecords;
|
|
|
+ if (needLevelFilter) {
|
|
|
+ // 内存过滤报警级别
|
|
|
+ List<EquipmentBaseOutDTO> filteredList = outDTOList.stream()
|
|
|
+ .filter(dto -> matchAlarmLevel(dto, listInDTO.getAlarmLevel()))
|
|
|
+ .collect(Collectors.toList());
|
|
|
+ total = filteredList.size();
|
|
|
+ pageRecords = applyPage(filteredList, listInDTO.getPageNum(), listInDTO.getPageSize());
|
|
|
+ } else {
|
|
|
+ total = rs.getTotal();
|
|
|
+ pageRecords = outDTOList;
|
|
|
+ }
|
|
|
+ long pageSize = listInDTO.getPageSize() != null ? listInDTO.getPageSize()
|
|
|
+ : (total > 0 ? total : 1);
|
|
|
+ Page<EquipmentBaseOutDTO> outPage = new Page<>(listInDTO.getPageNum() != null ? listInDTO.getPageNum() : 1, pageSize, total);
|
|
|
+ outPage.setRecords(pageRecords);
|
|
|
+ return outPage;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 报警级别判定(与前端 buildAlertInfo 保持一致):
|
|
|
+ * 严重报警(1):设备报警状态=1 或 水位/水浸报警;
|
|
|
+ * 一般报警(2):非严重报警且 低电量(<=20%)或 弱信号(<=20%);
|
|
|
+ * 有报警(0):严重报警或一般报警的并集;不传则不过滤。
|
|
|
+ */
|
|
|
+ private boolean matchAlarmLevel(EquipmentBaseOutDTO dto, Integer alarmLevel) {
|
|
|
+ if (alarmLevel == null) {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ boolean isCritical = (dto.getEquipmentStatus() != null
|
|
|
+ && Integer.valueOf(1).equals(dto.getEquipmentStatus().getAlarmStatus()))
|
|
|
+ || (dto.getManholeData() != null
|
|
|
+ && ("1".equals(dto.getManholeData().getWaterLevelAlarmStatus())
|
|
|
+ || "1".equals(dto.getManholeData().getWaterInfiltrationAlarmStatus())));
|
|
|
+ if (Integer.valueOf(1).equals(alarmLevel)) {
|
|
|
+ return isCritical;
|
|
|
+ }
|
|
|
+ if (dto.getManholeData() == null) {
|
|
|
+ return Integer.valueOf(0).equals(alarmLevel) && isCritical;
|
|
|
+ }
|
|
|
+ boolean lowBattery = dto.getManholeData().getBatteryLevel() != null
|
|
|
+ && toInt(dto.getManholeData().getBatteryLevel()) <= 20;
|
|
|
+ boolean weakSignal = dto.getManholeData().getSignalStrength() != null
|
|
|
+ && toInt(dto.getManholeData().getSignalStrength()) <= 20;
|
|
|
+ boolean hasAlarm = isCritical || lowBattery || weakSignal;
|
|
|
+ if (Integer.valueOf(0).equals(alarmLevel)) {
|
|
|
+ return hasAlarm;
|
|
|
+ }
|
|
|
+ // alarmLevel = 2:一般报警
|
|
|
+ return hasAlarm && !isCritical;
|
|
|
+ }
|
|
|
+
|
|
|
+ private int toInt(String value) {
|
|
|
+ try {
|
|
|
+ return (int) Double.parseDouble(value.trim());
|
|
|
+ } catch (Exception e) {
|
|
|
+ return Integer.MAX_VALUE;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 内存分页(报警级别过滤后使用)
|
|
|
+ */
|
|
|
+ private List<EquipmentBaseOutDTO> applyPage(List<EquipmentBaseOutDTO> list, Long pageNum, Long pageSize) {
|
|
|
+ if (pageNum == null || pageSize == null) {
|
|
|
+ return list;
|
|
|
+ }
|
|
|
+ int start = (int) ((pageNum - 1) * pageSize);
|
|
|
+ if (start >= list.size()) {
|
|
|
return new ArrayList<>();
|
|
|
}
|
|
|
- List<EquipmentBaseOutDTO> outDTOList = BeanUtil.copyToList(equipmentBaseList, EquipmentBaseOutDTO.class);
|
|
|
- //查询设备类型
|
|
|
- List<String> equipmentTypeIdList = outDTOList.stream().map(EquipmentBaseOutDTO::getEquipmentTypeId).distinct().collect(Collectors.toList());
|
|
|
- LambdaQueryWrapper<EquipmentType> batchQw = new LambdaQueryWrapper<>();
|
|
|
- batchQw.in(EquipmentType::getId, equipmentTypeIdList);
|
|
|
- List<EquipmentType> equipmentTypeList = equipmentTypeMapper.selectList(batchQw);
|
|
|
+ int end = (int) Math.min(start + pageSize, list.size());
|
|
|
+ return new ArrayList<>(list.subList(start, end));
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 窨井盖实时监测-设备报警监控列表
|
|
|
+ * 查询所有窨井类型设备(equipment_type_id IN (9,10))的 jg_device_data 最新一条记录
|
|
|
+ * 告警等级判定:
|
|
|
+ * 严重告警(critical) — 倾斜角度超阈值 / 水浸报警 / 水位报警
|
|
|
+ * 一般告警(warning) — 低电量(battery<=20) / 弱信号(signal<=20)
|
|
|
+ */
|
|
|
+ @Override
|
|
|
+ public AlarmMonitorListOutDTO getAlarmMonitorList(AlarmMonitorListInDTO inDTO) {
|
|
|
+ log.info("窨井盖实时监测-设备报警监控列表入参:{}", inDTO);
|
|
|
+ // 仅查询窨井类型设备:排水窨井(9)/供水窨井(10)
|
|
|
+ List<String> manholeTypeIds = Arrays.asList("5", "9", "10");
|
|
|
+ LambdaQueryWrapper<EquipmentBase> queryWrapper = new LambdaQueryWrapper<>();
|
|
|
+ queryWrapper.in(EquipmentBase::getEquipmentTypeId, manholeTypeIds)
|
|
|
+ .and(StringUtils.isNotBlank(inDTO.getKeyword()), w -> w
|
|
|
+ .like(EquipmentBase::getEquipmentCode, inDTO.getKeyword())
|
|
|
+ .or()
|
|
|
+ .like(EquipmentBase::getEquipmentName, inDTO.getKeyword())
|
|
|
+ .or()
|
|
|
+ .like(EquipmentBase::getEquipmentLocation, inDTO.getKeyword()))
|
|
|
+ .orderByDesc(EquipmentBase::getUpdateTime);
|
|
|
+ List<EquipmentBase> equipmentList = this.list(queryWrapper);
|
|
|
+ if (CollUtil.isEmpty(equipmentList)) {
|
|
|
+ AlarmMonitorListOutDTO emptyResult = new AlarmMonitorListOutDTO();
|
|
|
+ emptyResult.setDevices(new ArrayList<>());
|
|
|
+ Map<String, Object> emptyStats = new HashMap<>();
|
|
|
+ emptyStats.put("total", 0);
|
|
|
+ emptyStats.put("critical", 0);
|
|
|
+ emptyStats.put("warning", 0);
|
|
|
+ emptyStats.put("normal", 0);
|
|
|
+ emptyStats.put("onlineCount", 0);
|
|
|
+ emptyStats.put("avgBattery", 0);
|
|
|
+ emptyResult.setStatistics(emptyStats);
|
|
|
+ return emptyResult;
|
|
|
+ }
|
|
|
+ List<EquipmentBaseOutDTO> outDTOList = BeanUtil.copyToList(equipmentList, EquipmentBaseOutDTO.class);
|
|
|
+
|
|
|
+ // 批量查询设备类型名称
|
|
|
+ List<String> typeIdList = outDTOList.stream().map(EquipmentBaseOutDTO::getEquipmentTypeId).distinct().collect(Collectors.toList());
|
|
|
+ List<EquipmentType> equipmentTypeList = equipmentTypeMapper.selectList(new LambdaQueryWrapper<EquipmentType>()
|
|
|
+ .in(EquipmentType::getId, typeIdList));
|
|
|
Map<String, EquipmentType> equipmentTypeMap = new HashMap<>();
|
|
|
- if(CollUtil.isNotEmpty(equipmentTypeList)){
|
|
|
- equipmentTypeMap.putAll(equipmentTypeList.stream().collect(
|
|
|
- Collectors.toMap(t -> String.valueOf(t.getId()), Function.identity(), (key1, key2) -> key2)));
|
|
|
+ if (CollUtil.isNotEmpty(equipmentTypeList)) {
|
|
|
+ equipmentTypeMap.putAll(equipmentTypeList.stream().collect(Collectors.toMap(t -> String.valueOf(t.getId()), Function.identity(), (k1, k2) -> k2)));
|
|
|
}
|
|
|
- //查询设备状态
|
|
|
+
|
|
|
+ // 批量查询设备运维状态
|
|
|
List<String> equipmentIdList = outDTOList.stream().map(EquipmentBaseOutDTO::getEquipmentId).distinct().collect(Collectors.toList());
|
|
|
List<EquipmentStatus> equipmentStatusList = equipmentStatusMapper.selectList(new LambdaQueryWrapper<EquipmentStatus>()
|
|
|
.in(EquipmentStatus::getEquipmentId, equipmentIdList));
|
|
|
- Map<String, EquipmentStatus> EquipmentStatusMap = new HashMap<>();
|
|
|
- if(CollUtil.isNotEmpty(equipmentStatusList)){
|
|
|
- EquipmentStatusMap.putAll(equipmentStatusList.stream().collect(Collectors.toMap(EquipmentStatus::getEquipmentId, Function.identity(), (key1, key2) -> key2)));
|
|
|
- }
|
|
|
- //查询设备监测状态
|
|
|
- Map<String, List<ManholeData>> imeiCardNumberMapList = new HashMap<>();
|
|
|
- if(listInDTO.getIsQueryManholeData()){
|
|
|
- List<String> equipmentCodeList = outDTOList.stream().map(EquipmentBaseOutDTO::getEquipmentCode).distinct().collect(Collectors.toList());
|
|
|
- List<ManholeData> manholeDataList = manholeDataMapper.selectList(new LambdaQueryWrapper<ManholeData>()
|
|
|
- .in(ManholeData::getImeiCardNumber, equipmentCodeList)
|
|
|
- .orderByDesc(ManholeData::getCreateTime));
|
|
|
- imeiCardNumberMapList.putAll(manholeDataList.stream().collect(Collectors.groupingBy(ManholeData::getImeiCardNumber)));
|
|
|
- }
|
|
|
- List<ManholeData> manholeDataList = null;
|
|
|
- for(EquipmentBaseOutDTO outDTO : outDTOList) {
|
|
|
+ Map<String, EquipmentStatus> equipmentStatusMap = new HashMap<>();
|
|
|
+ if (CollUtil.isNotEmpty(equipmentStatusList)) {
|
|
|
+ equipmentStatusMap.putAll(equipmentStatusList.stream().collect(Collectors.toMap(EquipmentStatus::getEquipmentId, Function.identity(), (k1, k2) -> k2)));
|
|
|
+ }
|
|
|
+
|
|
|
+ // 批量查询最新 jg_device_data 记录(按 imei_card_number = equipment_code 关联)
|
|
|
+ List<String> equipmentCodeList = outDTOList.stream().map(EquipmentBaseOutDTO::getEquipmentCode).distinct().collect(Collectors.toList());
|
|
|
+ List<ManholeData> manholeDataList = manholeDataMapper.selectList(new LambdaQueryWrapper<ManholeData>()
|
|
|
+ .in(ManholeData::getImeiCardNumber, equipmentCodeList)
|
|
|
+ .orderByDesc(ManholeData::getCreateTime));
|
|
|
+ Map<String, List<ManholeData>> imeiMapList = new HashMap<>();
|
|
|
+ if (CollUtil.isNotEmpty(manholeDataList)) {
|
|
|
+ imeiMapList.putAll(manholeDataList.stream().collect(Collectors.groupingBy(ManholeData::getImeiCardNumber)));
|
|
|
+ }
|
|
|
+
|
|
|
+ // 批量查询未办结工单(待派单/待接单/已接单/处理中/待验收/延期审核)
|
|
|
+ List<Integer> activeStatusList = Arrays.asList(1, 2, 3, 4, 5, 8);
|
|
|
+ List<WorkOrder> activeWorkOrders = workOrderMapper.selectList(new LambdaQueryWrapper<WorkOrder>()
|
|
|
+ .in(WorkOrder::getDeviceId, equipmentIdList)
|
|
|
+ .in(WorkOrder::getOrderStatus, activeStatusList));
|
|
|
+ Set<String> deviceWithActiveOrder = activeWorkOrders.stream()
|
|
|
+ .map(WorkOrder::getDeviceId)
|
|
|
+ .collect(Collectors.toSet());
|
|
|
+
|
|
|
+ // 统计变量
|
|
|
+ int critical = 0, warning = 0, normal = 0, onlineCount = 0;
|
|
|
+ double batterySum = 0;
|
|
|
+ int batteryCount = 0;
|
|
|
+
|
|
|
+ for (EquipmentBaseOutDTO outDTO : outDTOList) {
|
|
|
+ // 设备类型名称
|
|
|
EquipmentType equipmentType = equipmentTypeMap.get(outDTO.getEquipmentTypeId());
|
|
|
- if(equipmentType != null){
|
|
|
+ if (equipmentType != null) {
|
|
|
outDTO.setEquipmentTypeName(equipmentType.getTypeName());
|
|
|
}
|
|
|
- EquipmentStatus equipmentStatus = EquipmentStatusMap.get(outDTO.getEquipmentId());
|
|
|
- if(equipmentStatus != null){
|
|
|
- EquipmentStatusOutDTO equipmentStatusOutDTO = BeanUtil.copyProperties(equipmentStatus, EquipmentStatusOutDTO.class);
|
|
|
- outDTO.setEquipmentStatus(equipmentStatusOutDTO);
|
|
|
+ // 设备运维状态
|
|
|
+ EquipmentStatus equipmentStatus = equipmentStatusMap.get(outDTO.getEquipmentId());
|
|
|
+ if (equipmentStatus != null) {
|
|
|
+ EquipmentStatusOutDTO statusOutDTO = BeanUtil.copyProperties(equipmentStatus, EquipmentStatusOutDTO.class);
|
|
|
+ outDTO.setEquipmentStatus(statusOutDTO);
|
|
|
+ if (Integer.valueOf(1).equals(equipmentStatus.getOnlineStatus())) {
|
|
|
+ onlineCount++;
|
|
|
+ }
|
|
|
}
|
|
|
- if(listInDTO.getIsQueryManholeData()){
|
|
|
- manholeDataList = imeiCardNumberMapList.get(outDTO.getEquipmentCode());
|
|
|
- if(CollUtil.isNotEmpty(manholeDataList)){
|
|
|
- ManholeData manholeData = manholeDataList.get(0);
|
|
|
- ManholeDataOutDTO manholeDataOutDTO = BeanUtil.copyProperties(manholeData, ManholeDataOutDTO.class);
|
|
|
- outDTO.setManholeData(manholeDataOutDTO);
|
|
|
+ // 是否有未办结工单
|
|
|
+ outDTO.setWorkOrderSubmitted(deviceWithActiveOrder.contains(outDTO.getEquipmentId()));
|
|
|
+ // 最新 jg_device_data 记录
|
|
|
+ List<ManholeData> dataList = imeiMapList.get(outDTO.getEquipmentCode());
|
|
|
+ if (CollUtil.isNotEmpty(dataList)) {
|
|
|
+ ManholeData latest = dataList.get(0);
|
|
|
+ ManholeDataOutDTO manholeDataOutDTO = BeanUtil.copyProperties(latest, ManholeDataOutDTO.class);
|
|
|
+ outDTO.setManholeData(manholeDataOutDTO);
|
|
|
+
|
|
|
+ // 统计电量
|
|
|
+ if (StringUtils.isNotBlank(latest.getBatteryLevel())) {
|
|
|
+ try {
|
|
|
+ batterySum += Double.parseDouble(latest.getBatteryLevel().trim());
|
|
|
+ batteryCount++;
|
|
|
+ } catch (NumberFormatException ignored) {}
|
|
|
}
|
|
|
+
|
|
|
+ // 告警等级判定
|
|
|
+ boolean isCritical = isCriticalAlarm(latest);
|
|
|
+ boolean isWarning = !isCritical && isGeneralAlarm(latest);
|
|
|
+ if (isCritical) critical++;
|
|
|
+ else if (isWarning) warning++;
|
|
|
+ else normal++;
|
|
|
+ } else {
|
|
|
+ normal++;
|
|
|
}
|
|
|
}
|
|
|
- return outDTOList;
|
|
|
+
|
|
|
+ // 构建统计信息
|
|
|
+ Map<String, Object> statistics = new HashMap<>();
|
|
|
+ statistics.put("total", outDTOList.size());
|
|
|
+ statistics.put("critical", critical);
|
|
|
+ statistics.put("warning", warning);
|
|
|
+ statistics.put("normal", normal);
|
|
|
+ statistics.put("onlineCount", onlineCount);
|
|
|
+ statistics.put("avgBattery", batteryCount > 0 ? (int) (batterySum / batteryCount) : 0);
|
|
|
+
|
|
|
+ AlarmMonitorListOutDTO result = new AlarmMonitorListOutDTO();
|
|
|
+ result.setDevices(outDTOList);
|
|
|
+ result.setStatistics(statistics);
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 严重告警判定:倾斜角度超阈值 / 水浸报警 / 水位报警
|
|
|
+ */
|
|
|
+ private boolean isCriticalAlarm(ManholeData data) {
|
|
|
+ if (data == null) return false;
|
|
|
+ // 水浸报警
|
|
|
+ if ("1".equals(data.getWaterInfiltrationAlarmStatus())) return true;
|
|
|
+ // 水位报警
|
|
|
+ if ("1".equals(data.getWaterLevelAlarmStatus())) return true;
|
|
|
+ // 倾斜角度超阈值
|
|
|
+ if (StringUtils.isNotBlank(data.getTiltAngle()) && StringUtils.isNotBlank(data.getAngleAlarmThreshold())) {
|
|
|
+ try {
|
|
|
+ double angle = Double.parseDouble(data.getTiltAngle().trim());
|
|
|
+ double threshold = Double.parseDouble(data.getAngleAlarmThreshold().trim());
|
|
|
+ if (angle > threshold) return true;
|
|
|
+ } catch (NumberFormatException ignored) {}
|
|
|
+ }
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 一般告警判定:低电量(battery<=20) / 弱信号(signal<=20)
|
|
|
+ */
|
|
|
+ private boolean isGeneralAlarm(ManholeData data) {
|
|
|
+ if (data == null) return false;
|
|
|
+ if (StringUtils.isNotBlank(data.getBatteryLevel())) {
|
|
|
+ try {
|
|
|
+ if (Double.parseDouble(data.getBatteryLevel().trim()) <= 20) return true;
|
|
|
+ } catch (NumberFormatException ignored) {}
|
|
|
+ }
|
|
|
+ if (StringUtils.isNotBlank(data.getSignalStrength())) {
|
|
|
+ try {
|
|
|
+ if (Double.parseDouble(data.getSignalStrength().trim()) <= 20) return true;
|
|
|
+ } catch (NumberFormatException ignored) {}
|
|
|
+ }
|
|
|
+ return false;
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
@@ -828,15 +1171,25 @@ public class EquipmentBaseServiceImpl extends ServiceImpl<EquipmentBaseMapper, E
|
|
|
return new ArrayList<>();
|
|
|
}
|
|
|
|
|
|
- List<String> typeIds = new ArrayList<>();
|
|
|
- List<EquipmentType> children = equipmentTypeMapper.selectList(
|
|
|
- new LambdaQueryWrapper<EquipmentType>()
|
|
|
- .eq(EquipmentType::getParentTypeId, topType.getId()));
|
|
|
- for (EquipmentType child : children) {
|
|
|
- typeIds.add(child.getId());
|
|
|
+ // 设备类型可能存在多级子分类,查询整个模块的类型树,避免漏掉深层燃气设备。
|
|
|
+ Set<String> typeIds = new LinkedHashSet<>();
|
|
|
+ Set<String> parentIds = new LinkedHashSet<>();
|
|
|
+ typeIds.add(topType.getId());
|
|
|
+ parentIds.add(topType.getId());
|
|
|
+ while (!parentIds.isEmpty()) {
|
|
|
+ List<EquipmentType> children = equipmentTypeMapper.selectList(
|
|
|
+ new LambdaQueryWrapper<EquipmentType>()
|
|
|
+ .in(EquipmentType::getParentTypeId, parentIds));
|
|
|
+ Set<String> nextParentIds = new LinkedHashSet<>();
|
|
|
+ for (EquipmentType child : children) {
|
|
|
+ if (typeIds.add(child.getId())) {
|
|
|
+ nextParentIds.add(child.getId());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ parentIds = nextParentIds;
|
|
|
}
|
|
|
LambdaQueryWrapper<EquipmentBase> wrapper = new LambdaQueryWrapper<>();
|
|
|
- wrapper.in(EquipmentBase::getEquipmentTypeId, typeIds);
|
|
|
+ wrapper.in(EquipmentBase::getEquipmentTypeId, new ArrayList<>(typeIds));
|
|
|
wrapper.orderByDesc(EquipmentBase::getCreateTime);
|
|
|
return this.list(wrapper);
|
|
|
}
|