|
|
@@ -9,6 +9,7 @@ import com.zksy.WaterSupply.MonitorAlarm.domain.AlarmAudit;
|
|
|
import com.zksy.WaterSupply.MonitorAlarm.dto.in.AlarmAuditInDTO;
|
|
|
import com.zksy.WaterSupply.MonitorAlarm.dto.in.AlarmDispatchInDTO;
|
|
|
import com.zksy.WaterSupply.MonitorAlarm.dto.out.AlarmAuditOutDTO;
|
|
|
+import com.zksy.WaterSupply.MonitorAlarm.dto.out.AlarmDashboardOutDTO;
|
|
|
import com.zksy.WaterSupply.MonitorAlarm.dto.out.AlarmFlowOutDTO;
|
|
|
import com.zksy.WaterSupply.MonitorAlarm.dto.out.AlarmMapPointOutDTO;
|
|
|
import com.zksy.WaterSupply.MonitorAlarm.dto.out.AlarmStatsOutDTO;
|
|
|
@@ -18,6 +19,10 @@ import com.zksy.WaterSupply.MonitorAlarm.service.IWaterSupplyAlarmService;
|
|
|
import com.zksy.base.alarm.domain.AlarmData;
|
|
|
import com.zksy.base.alarm.service.AlarmDataService;
|
|
|
import com.zksy.base.domain.EquipmentBase;
|
|
|
+import com.zksy.base.domain.EquipmentStatus;
|
|
|
+import com.zksy.base.domain.EquipmentType;
|
|
|
+import com.zksy.base.mapper.EquipmentStatusMapper;
|
|
|
+import com.zksy.base.mapper.EquipmentTypeMapper;
|
|
|
import com.zksy.ops.domain.WorkOrder;
|
|
|
import com.zksy.ops.domain.WorkOrderLog;
|
|
|
import com.zksy.ops.domain.vo.WorkOrderLogVO;
|
|
|
@@ -41,6 +46,7 @@ import java.time.LocalDate;
|
|
|
import java.time.LocalDateTime;
|
|
|
import java.time.format.DateTimeFormatter;
|
|
|
import java.util.ArrayList;
|
|
|
+import java.util.Collection;
|
|
|
import java.util.Collections;
|
|
|
import java.util.Comparator;
|
|
|
import java.util.LinkedHashMap;
|
|
|
@@ -85,6 +91,17 @@ public class WaterSupplyAlarmServiceImpl implements IWaterSupplyAlarmService {
|
|
|
@Autowired
|
|
|
private AlarmAuditMapper alarmAuditMapper;
|
|
|
|
|
|
+ @Autowired
|
|
|
+ private EquipmentStatusMapper equipmentStatusMapper;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private EquipmentTypeMapper equipmentTypeMapper;
|
|
|
+
|
|
|
+ /** 报警展示状态:1-待审核 2-已转工单 3-已解除 */
|
|
|
+ private static final int DISPLAY_PENDING_AUDIT = 1;
|
|
|
+ private static final int DISPLAY_TRANSFERRED = 2;
|
|
|
+ private static final int DISPLAY_RELEASED = 3;
|
|
|
+
|
|
|
// ------------------------------------------------------------------
|
|
|
// 供水设备范围解析
|
|
|
// ------------------------------------------------------------------
|
|
|
@@ -107,6 +124,18 @@ public class WaterSupplyAlarmServiceImpl implements IWaterSupplyAlarmService {
|
|
|
.collect(Collectors.toMap(EquipmentBase::getEquipmentCode, Function.identity(), (a, b) -> a));
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * 指定设备编码 -> 设备信息映射:只取台账当前涉及的设备,避免按报警量放大全表查询。
|
|
|
+ */
|
|
|
+ private Map<String, EquipmentBase> loadEquipmentCodeMap(Collection<String> deviceCodes) {
|
|
|
+ if (CollUtil.isEmpty(deviceCodes)) {
|
|
|
+ return Collections.emptyMap();
|
|
|
+ }
|
|
|
+ return equipmentBaseMapper.selectList(new LambdaQueryWrapper<EquipmentBase>()
|
|
|
+ .in(EquipmentBase::getEquipmentCode, deviceCodes)).stream()
|
|
|
+ .collect(Collectors.toMap(EquipmentBase::getEquipmentCode, Function.identity(), (a, b) -> a));
|
|
|
+ }
|
|
|
+
|
|
|
/**
|
|
|
* 设备编码 -> 工单映射(同一报警派发多个工单时取最新)
|
|
|
*/
|
|
|
@@ -232,6 +261,309 @@ public class WaterSupplyAlarmServiceImpl implements IWaterSupplyAlarmService {
|
|
|
return vos.isEmpty() ? null : vos.get(0);
|
|
|
}
|
|
|
|
|
|
+ // ------------------------------------------------------------------
|
|
|
+ // 报警管理只读台账(供水设备 + 后端推导展示状态)
|
|
|
+ // ------------------------------------------------------------------
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public Page<WaterAlarmOutDTO> getAlarmLedgerPage(long pageNum, long pageSize,
|
|
|
+ String deviceCode, String warningType,
|
|
|
+ Integer alarmLevel, Integer displayStatus,
|
|
|
+ Integer deviceAlarmStatus,
|
|
|
+ LocalDateTime startTime, LocalDateTime endTime,
|
|
|
+ String keyword) {
|
|
|
+ List<WaterAlarmOutDTO> rows = getAlarmLedgerExport(deviceCode, warningType, alarmLevel,
|
|
|
+ displayStatus, deviceAlarmStatus, startTime, endTime, keyword);
|
|
|
+ Page<WaterAlarmOutDTO> page = new Page<>(pageNum, pageSize, rows.size());
|
|
|
+ if (pageNum < 1 || pageSize < 1) {
|
|
|
+ page.setRecords(new ArrayList<>());
|
|
|
+ return page;
|
|
|
+ }
|
|
|
+ int from = (int) Math.min((pageNum - 1) * pageSize, rows.size());
|
|
|
+ int to = (int) Math.min(from + pageSize, rows.size());
|
|
|
+ page.setRecords(new ArrayList<>(rows.subList(from, to)));
|
|
|
+ return page;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public List<WaterAlarmOutDTO> getAlarmLedgerExport(String deviceCode, String warningType,
|
|
|
+ Integer alarmLevel, Integer displayStatus,
|
|
|
+ Integer deviceAlarmStatus,
|
|
|
+ LocalDateTime startTime, LocalDateTime endTime,
|
|
|
+ String keyword) {
|
|
|
+ Set<String> waterCodes = resolveWaterDeviceCodes();
|
|
|
+ if (waterCodes.isEmpty()) {
|
|
|
+ return new ArrayList<>();
|
|
|
+ }
|
|
|
+ LambdaQueryWrapper<AlarmData> wrapper = new LambdaQueryWrapper<AlarmData>()
|
|
|
+ .in(AlarmData::getDeviceCode, waterCodes)
|
|
|
+ .eq(StrUtil.isNotBlank(deviceCode), AlarmData::getDeviceCode, deviceCode)
|
|
|
+ .like(StrUtil.isNotBlank(warningType), AlarmData::getWarningType, warningType)
|
|
|
+ .eq(alarmLevel != null, AlarmData::getAlarmLevel, alarmLevel)
|
|
|
+ .ge(startTime != null, AlarmData::getAlarmTime, startTime)
|
|
|
+ .le(endTime != null, AlarmData::getAlarmTime, endTime)
|
|
|
+ .and(StrUtil.isNotBlank(keyword), w -> w.like(AlarmData::getDeviceCode, keyword)
|
|
|
+ .or().like(AlarmData::getWarningType, keyword)
|
|
|
+ .or().like(AlarmData::getWarningCode, keyword))
|
|
|
+ .orderByDesc(AlarmData::getAlarmTime);
|
|
|
+ List<AlarmData> alarms = alarmDataService.list(wrapper);
|
|
|
+ List<WaterAlarmOutDTO> rows = buildLedgerVoList(alarms);
|
|
|
+ return rows.stream()
|
|
|
+ .filter(row -> displayStatus == null || displayStatus.equals(row.getDisplayStatus()))
|
|
|
+ .filter(row -> deviceAlarmStatus == null || deviceAlarmStatus.equals(row.getDeviceAlarmStatus()))
|
|
|
+ .collect(Collectors.toList());
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 报警记录 -> 台账出参:补充设备报警状态与后端推导的报警展示状态。
|
|
|
+ *
|
|
|
+ * <p>展示状态口径:存在关联工单即“已转工单”;否则报警记录已处理或审核结论为误报即“已解除”;
|
|
|
+ * 其余为“待审核”。展示状态不替代设备报警状态。</p>
|
|
|
+ */
|
|
|
+ private List<WaterAlarmOutDTO> buildLedgerVoList(List<AlarmData> alarms) {
|
|
|
+ if (CollUtil.isEmpty(alarms)) {
|
|
|
+ return new ArrayList<>();
|
|
|
+ }
|
|
|
+ List<String> alarmIds = alarms.stream().map(AlarmData::getId).collect(Collectors.toList());
|
|
|
+ Map<String, EquipmentBase> eqMap = loadEquipmentCodeMap(alarms.stream()
|
|
|
+ .map(AlarmData::getDeviceCode)
|
|
|
+ .filter(StrUtil::isNotBlank)
|
|
|
+ .collect(Collectors.toSet()));
|
|
|
+ Map<String, WorkOrder> orderMap = loadWorkOrderMapByAlarmIds(alarmIds);
|
|
|
+ Map<String, AlarmAudit> latestAuditMap = loadLatestAuditMap(alarmIds);
|
|
|
+ Map<String, EquipmentStatus> statusMap = loadStatusMap(eqMap.values());
|
|
|
+ List<WaterAlarmOutDTO> vos = new ArrayList<>();
|
|
|
+ for (AlarmData alarm : alarms) {
|
|
|
+ WaterAlarmOutDTO vo = BeanUtil.copyProperties(alarm, WaterAlarmOutDTO.class);
|
|
|
+ EquipmentBase eq = alarm.getDeviceCode() == null ? null : eqMap.get(alarm.getDeviceCode());
|
|
|
+ if (eq != null) {
|
|
|
+ vo.setEquipmentId(eq.getEquipmentId());
|
|
|
+ if (StrUtil.isBlank(vo.getDeviceName())) {
|
|
|
+ vo.setDeviceName(eq.getEquipmentName());
|
|
|
+ }
|
|
|
+ vo.setEquipmentLocation(eq.getEquipmentLocation());
|
|
|
+ if (eq.getLongitude() != null) {
|
|
|
+ vo.setLongitude(eq.getLongitude().toPlainString());
|
|
|
+ }
|
|
|
+ if (eq.getLatitude() != null) {
|
|
|
+ vo.setLatitude(eq.getLatitude().toPlainString());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ vo.setAlarmLevelText(formatAlarmLevel(alarm.getAlarmLevel()));
|
|
|
+ vo.setAlarmStatusText(alarm.getAlarmStatus() != null && alarm.getAlarmStatus() == 0 ? "待处理" : "已处理");
|
|
|
+ WorkOrder order = alarm.getId() == null ? null : orderMap.get(alarm.getId());
|
|
|
+ if (order != null) {
|
|
|
+ vo.setOrderNo(order.getOrderNo());
|
|
|
+ vo.setOrderStatus(order.getOrderStatus());
|
|
|
+ }
|
|
|
+ int deviceAlarm = resolveDeviceAlarmStatus(alarm, eq, statusMap, latestAuditMap.get(alarm.getId()));
|
|
|
+ vo.setDeviceAlarmStatus(deviceAlarm);
|
|
|
+ vo.setDeviceAlarmStatusText(deviceAlarm == 1 ? "报警中" : "正常");
|
|
|
+ int display = resolveDisplayStatus(alarm, order, latestAuditMap.get(alarm.getId()));
|
|
|
+ vo.setDisplayStatus(display);
|
|
|
+ vo.setDisplayStatusText(displayStatusText(display));
|
|
|
+ vos.add(vo);
|
|
|
+ }
|
|
|
+ return vos;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 设备报警状态:以设备状态表为准;无状态记录时回退到报警记录是否未处理,
|
|
|
+ * 但经审核判定为误报解除的报警不再视为设备报警中。
|
|
|
+ */
|
|
|
+ private int resolveDeviceAlarmStatus(AlarmData alarm, EquipmentBase eq,
|
|
|
+ Map<String, EquipmentStatus> statusMap, AlarmAudit audit) {
|
|
|
+ if (eq != null && eq.getEquipmentId() != null) {
|
|
|
+ EquipmentStatus status = statusMap.get(eq.getEquipmentId());
|
|
|
+ if (status != null && status.getAlarmStatus() != null) {
|
|
|
+ return status.getAlarmStatus();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (audit != null && (Integer.valueOf(2).equals(audit.getAuditResult())
|
|
|
+ || Integer.valueOf(2).equals(audit.getAuditAction()))) {
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ return alarm.getAlarmStatus() != null && alarm.getAlarmStatus() == 0 ? 1 : 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 报警展示状态推导:
|
|
|
+ * 关联工单未取消 -> 已转工单;否则报警记录已处理或最新审核为误报 -> 已解除;其余 -> 待审核。
|
|
|
+ * 工单已取消代表处置已撤销,按报警事实自身归档为已解除,展示口径由后端统一。
|
|
|
+ */
|
|
|
+ private int resolveDisplayStatus(AlarmData alarm, WorkOrder order, AlarmAudit audit) {
|
|
|
+ boolean orderAlive = order != null && !Integer.valueOf(7).equals(order.getOrderStatus());
|
|
|
+ if (orderAlive) {
|
|
|
+ return DISPLAY_TRANSFERRED;
|
|
|
+ }
|
|
|
+ boolean alarmHandled = alarm.getAlarmStatus() != null && alarm.getAlarmStatus() == 1;
|
|
|
+ boolean falseAlarm = audit != null && Integer.valueOf(2).equals(audit.getAuditResult());
|
|
|
+ return alarmHandled || falseAlarm ? DISPLAY_RELEASED : DISPLAY_PENDING_AUDIT;
|
|
|
+ }
|
|
|
+
|
|
|
+ private String displayStatusText(int displayStatus) {
|
|
|
+ switch (displayStatus) {
|
|
|
+ case DISPLAY_TRANSFERRED:
|
|
|
+ return "已转工单";
|
|
|
+ case DISPLAY_RELEASED:
|
|
|
+ return "已解除";
|
|
|
+ default:
|
|
|
+ return "待审核";
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 报警ID -> 最新审核记录
|
|
|
+ */
|
|
|
+ private Map<String, AlarmAudit> loadLatestAuditMap(List<String> alarmIds) {
|
|
|
+ if (CollUtil.isEmpty(alarmIds)) {
|
|
|
+ return Collections.emptyMap();
|
|
|
+ }
|
|
|
+ List<AlarmAudit> audits = alarmAuditMapper.selectList(new LambdaQueryWrapper<AlarmAudit>()
|
|
|
+ .in(AlarmAudit::getAlarmId, alarmIds)
|
|
|
+ .orderByDesc(AlarmAudit::getAuditId));
|
|
|
+ return audits.stream()
|
|
|
+ .collect(Collectors.toMap(AlarmAudit::getAlarmId, Function.identity(), (a, b) -> a));
|
|
|
+ }
|
|
|
+
|
|
|
+ private Map<String, EquipmentStatus> loadStatusMap(Collection<EquipmentBase> devices) {
|
|
|
+ List<String> equipmentIds = devices.stream()
|
|
|
+ .map(EquipmentBase::getEquipmentId)
|
|
|
+ .filter(StrUtil::isNotBlank)
|
|
|
+ .distinct()
|
|
|
+ .collect(Collectors.toList());
|
|
|
+ if (equipmentIds.isEmpty()) {
|
|
|
+ return Collections.emptyMap();
|
|
|
+ }
|
|
|
+ return equipmentStatusMapper.selectList(new LambdaQueryWrapper<EquipmentStatus>()
|
|
|
+ .in(EquipmentStatus::getEquipmentId, equipmentIds)).stream()
|
|
|
+ .collect(Collectors.toMap(EquipmentStatus::getEquipmentId, Function.identity(), (a, b) -> a));
|
|
|
+ }
|
|
|
+
|
|
|
+ // ------------------------------------------------------------------
|
|
|
+ // 报警管理态势统计
|
|
|
+ // ------------------------------------------------------------------
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public AlarmDashboardOutDTO getAlarmDashboard(int days) {
|
|
|
+ int trendDays = days > 0 ? days : 7;
|
|
|
+ AlarmDashboardOutDTO dashboard = new AlarmDashboardOutDTO();
|
|
|
+ Set<String> waterCodes = resolveWaterDeviceCodes();
|
|
|
+ if (waterCodes.isEmpty()) {
|
|
|
+ dashboard.setTrend(emptyTrend(trendDays));
|
|
|
+ return dashboard;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 台账全量口径与列表一致:调用同一推导逻辑,避免统计与列表两套口径漂移
|
|
|
+ List<WaterAlarmOutDTO> rows = buildLedgerVoList(alarmDataService.list(
|
|
|
+ new LambdaQueryWrapper<AlarmData>()
|
|
|
+ .in(AlarmData::getDeviceCode, waterCodes)
|
|
|
+ .orderByDesc(AlarmData::getAlarmTime)));
|
|
|
+
|
|
|
+ dashboard.setTotalCount(rows.size());
|
|
|
+ dashboard.setPendingAuditCount(countDisplayStatus(rows, DISPLAY_PENDING_AUDIT));
|
|
|
+ dashboard.setTransferredCount(countDisplayStatus(rows, DISPLAY_TRANSFERRED));
|
|
|
+ dashboard.setReleasedCount(countDisplayStatus(rows, DISPLAY_RELEASED));
|
|
|
+ dashboard.setAlarmingDeviceCount(rows.stream()
|
|
|
+ .filter(row -> Integer.valueOf(1).equals(row.getDeviceAlarmStatus()))
|
|
|
+ .map(WaterAlarmOutDTO::getDeviceCode)
|
|
|
+ .filter(StrUtil::isNotBlank)
|
|
|
+ .distinct()
|
|
|
+ .count());
|
|
|
+
|
|
|
+ dashboard.setTrend(buildTrend(rows, trendDays));
|
|
|
+ dashboard.setWarningTypeRatio(buildRatio(rows, WaterAlarmOutDTO::getWarningType, "未分类"));
|
|
|
+ dashboard.setAlarmLevelRatio(buildRatio(rows,
|
|
|
+ row -> formatAlarmLevel(row.getAlarmLevel()), "未知等级"));
|
|
|
+ dashboard.setDeviceTypeRatio(buildDeviceTypeRatio(rows, loadEquipmentCodeMap(rows.stream()
|
|
|
+ .map(WaterAlarmOutDTO::getDeviceCode)
|
|
|
+ .filter(StrUtil::isNotBlank)
|
|
|
+ .collect(Collectors.toSet()))));
|
|
|
+ return dashboard;
|
|
|
+ }
|
|
|
+
|
|
|
+ private long countDisplayStatus(List<WaterAlarmOutDTO> rows, int displayStatus) {
|
|
|
+ return rows.stream().filter(row -> Integer.valueOf(displayStatus).equals(row.getDisplayStatus())).count();
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 报警趋势:按自然日分桶,区间内无报警的日期补 0,保证图表横轴连续。
|
|
|
+ */
|
|
|
+ private List<AlarmDashboardOutDTO.TrendItem> buildTrend(List<WaterAlarmOutDTO> rows, int days) {
|
|
|
+ LocalDate today = LocalDate.now();
|
|
|
+ LocalDate from = today.minusDays(days - 1L);
|
|
|
+ Map<String, AlarmDashboardOutDTO.TrendItem> byDate = new LinkedHashMap<>();
|
|
|
+ for (int offset = 0; offset < days; offset++) {
|
|
|
+ AlarmDashboardOutDTO.TrendItem item = new AlarmDashboardOutDTO.TrendItem();
|
|
|
+ item.setDate(from.plusDays(offset).toString());
|
|
|
+ byDate.put(item.getDate(), item);
|
|
|
+ }
|
|
|
+ for (WaterAlarmOutDTO row : rows) {
|
|
|
+ if (row.getAlarmTime() == null) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ AlarmDashboardOutDTO.TrendItem item = byDate.get(row.getAlarmTime().toLocalDate().toString());
|
|
|
+ if (item == null) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ item.setCount(item.getCount() + 1);
|
|
|
+ if (row.getAlarmLevel() != null && row.getAlarmLevel() <= 2) {
|
|
|
+ item.setHighLevelCount(item.getHighLevelCount() + 1);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return new ArrayList<>(byDate.values());
|
|
|
+ }
|
|
|
+
|
|
|
+ private List<AlarmDashboardOutDTO.TrendItem> emptyTrend(int days) {
|
|
|
+ List<AlarmDashboardOutDTO.TrendItem> empty = new ArrayList<>();
|
|
|
+ LocalDate from = LocalDate.now().minusDays(days - 1L);
|
|
|
+ for (int offset = 0; offset < days; offset++) {
|
|
|
+ AlarmDashboardOutDTO.TrendItem item = new AlarmDashboardOutDTO.TrendItem();
|
|
|
+ item.setDate(from.plusDays(offset).toString());
|
|
|
+ empty.add(item);
|
|
|
+ }
|
|
|
+ return empty;
|
|
|
+ }
|
|
|
+
|
|
|
+ private List<AlarmDashboardOutDTO.RatioItem> buildRatio(List<WaterAlarmOutDTO> rows,
|
|
|
+ Function<WaterAlarmOutDTO, String> classify,
|
|
|
+ String fallbackName) {
|
|
|
+ Map<String, Long> grouped = new LinkedHashMap<>();
|
|
|
+ for (WaterAlarmOutDTO row : rows) {
|
|
|
+ String name = classify.apply(row);
|
|
|
+ String key = StrUtil.isBlank(name) ? fallbackName : name;
|
|
|
+ grouped.merge(key, 1L, Long::sum);
|
|
|
+ }
|
|
|
+ return grouped.entrySet().stream()
|
|
|
+ .sorted(Map.Entry.<String, Long>comparingByValue().reversed())
|
|
|
+ .map(entry -> {
|
|
|
+ AlarmDashboardOutDTO.RatioItem item = new AlarmDashboardOutDTO.RatioItem();
|
|
|
+ item.setName(entry.getKey());
|
|
|
+ item.setCount(entry.getValue());
|
|
|
+ return item;
|
|
|
+ })
|
|
|
+ .collect(Collectors.toList());
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 设备分类占比取自报警所属设备在设备类别表中的真实类型名称,未知类型归入“未分类”。
|
|
|
+ */
|
|
|
+ private List<AlarmDashboardOutDTO.RatioItem> buildDeviceTypeRatio(List<WaterAlarmOutDTO> rows,
|
|
|
+ Map<String, EquipmentBase> eqMap) {
|
|
|
+ List<String> typeIds = eqMap.values().stream()
|
|
|
+ .map(EquipmentBase::getEquipmentTypeId)
|
|
|
+ .filter(StrUtil::isNotBlank)
|
|
|
+ .distinct()
|
|
|
+ .collect(Collectors.toList());
|
|
|
+ Map<String, String> typeNames = typeIds.isEmpty() ? Collections.emptyMap()
|
|
|
+ : equipmentTypeMapper.selectBatchIds(typeIds).stream()
|
|
|
+ .collect(Collectors.toMap(EquipmentType::getId, EquipmentType::getTypeName, (a, b) -> a));
|
|
|
+ return buildRatio(rows, row -> {
|
|
|
+ EquipmentBase eq = row.getDeviceCode() == null ? null : eqMap.get(row.getDeviceCode());
|
|
|
+ return eq == null ? null : typeNames.get(eq.getEquipmentTypeId());
|
|
|
+ }, "未分类");
|
|
|
+ }
|
|
|
+
|
|
|
/**
|
|
|
* 报警记录 -> 出参(填充设备名称/位置/经纬度及关联工单)
|
|
|
*/
|