package com.mes.device.service.impl; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.ObjectMapper; import com.mes.device.entity.DeviceConfig; import com.mes.device.mapper.DeviceConfigMapper; import com.mes.device.service.DeviceConfigService; import com.mes.device.vo.DeviceConfigVO; import com.mes.device.vo.StatisticsVO; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import java.io.IOException; import java.time.LocalDateTime; import java.util.*; import java.util.stream.Collectors; /** * 设备配置服务实现类 * @author huang */ @Slf4j @Service public class DeviceConfigServiceImpl extends ServiceImpl implements DeviceConfigService { private final ObjectMapper objectMapper = new ObjectMapper(); private static final TypeReference> MAP_TYPE = new TypeReference>() {}; @Override public boolean createDevice(DeviceConfig deviceConfig) { try { // 检查设备编号是否已存在 if (isDeviceCodeExists(deviceConfig.getDeviceCode(), null)) { log.warn("设备编号已存在: {}", deviceConfig.getDeviceCode()); return false; } // 初始化设备状态为离线 if (deviceConfig.getStatus() == null) { deviceConfig.setStatus("离线"); } boolean result = save(deviceConfig); if (result) { log.info("创建设备配置成功: {}", deviceConfig.getDeviceCode()); } return result; } catch (Exception e) { log.error("创建设备配置失败", e); return false; } } @Override public boolean updateDevice(DeviceConfig deviceConfig) { try { // 检查设备编号是否已存在(排除当前设备) if (isDeviceCodeExists(deviceConfig.getDeviceCode(), deviceConfig.getId())) { log.warn("设备编号已存在: {}", deviceConfig.getDeviceCode()); return false; } boolean result = updateById(deviceConfig); if (result) { log.info("更新设备配置成功: {}", deviceConfig.getDeviceCode()); } return result; } catch (Exception e) { log.error("更新设备配置失败", e); return false; } } @Override public boolean deleteDevice(Long id) { try { boolean result = removeById(id); if (result) { log.info("删除设备配置成功: {}", id); } return result; } catch (Exception e) { log.error("删除设备配置失败", e); return false; } } @Override public DeviceConfig getDeviceById(Long id) { return getById(id); } @Override public DeviceConfig getDeviceByCode(String deviceCode) { LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); wrapper.eq(DeviceConfig::getDeviceCode, deviceCode); wrapper.eq(DeviceConfig::getIsDeleted, 0); return getOne(wrapper); } @Override public List getDeviceList(Long projectId, String deviceType, String status) { LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); if (projectId != null) { wrapper.eq(DeviceConfig::getProjectId, projectId); } if (deviceType != null && !deviceType.isEmpty()) { wrapper.eq(DeviceConfig::getDeviceType, deviceType); } if (status != null && !status.isEmpty()) { wrapper.eq(DeviceConfig::getStatus, status); } wrapper.eq(DeviceConfig::getIsDeleted, 0); wrapper.orderByDesc(DeviceConfig::getCreatedTime); return list(wrapper); } @Override public Page getDeviceList(Long projectId, String deviceType, String deviceStatus, String keyword, Integer page, Integer size) { // 创建分页对象 Page pageQuery = new Page<>(page != null ? page : 1, size != null ? size : 10); // 构建查询条件 LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); if (projectId != null) { wrapper.eq(DeviceConfig::getProjectId, projectId); } // 设备类型过滤 if (deviceType != null && !deviceType.trim().isEmpty()) { wrapper.eq(DeviceConfig::getDeviceType, deviceType.trim()); } // 设备状态过滤 if (deviceStatus != null && !deviceStatus.trim().isEmpty()) { String convertedStatus = convertStatusFromString(deviceStatus); if (convertedStatus != null) { wrapper.eq(DeviceConfig::getStatus, convertedStatus); } } // 关键词搜索 if (keyword != null && !keyword.trim().isEmpty()) { wrapper.and(w -> w .like(DeviceConfig::getDeviceName, keyword) .or().like(DeviceConfig::getDeviceCode, keyword) .or().like(DeviceConfig::getDescription, keyword)); } wrapper.eq(DeviceConfig::getIsDeleted, 0); wrapper.orderByDesc(DeviceConfig::getCreatedTime); // 执行分页查询 Page result = page(pageQuery, wrapper); // 转换为VO对象 List voList = result.getRecords().stream().map(device -> { DeviceConfigVO.DeviceInfo vo = new DeviceConfigVO.DeviceInfo(); vo.setId(device.getId()); vo.setDeviceName(device.getDeviceName()); vo.setDeviceCode(device.getDeviceCode()); vo.setDeviceType(getDeviceTypeName(device.getDeviceType())); vo.setPlcIp(device.getPlcIp()); vo.setPlcPort(device.getPlcPort()); vo.setPlcType(device.getPlcType()); vo.setModuleName(device.getModuleName()); vo.setIsPrimary(device.getIsPrimary()); vo.setEnabled(Boolean.TRUE.equals(device.getEnabled())); vo.setIsEnabled(Boolean.TRUE.equals(device.getEnabled())); vo.setStatus(getStatusName(device.getStatus())); vo.setDeviceStatus(convertStatusToCode(device.getStatus())); vo.setLastHeartbeat(device.getUpdatedTime()); vo.setLocation("默认位置"); vo.setDescription(device.getDescription()); vo.setCreatedTime(device.getCreatedTime()); vo.setUpdatedTime(device.getUpdatedTime()); vo.setProjectId(device.getProjectId()); return vo; }).collect(Collectors.toList()); // 创建返回的Page对象 Page pageResult = new Page<>(result.getCurrent(), result.getSize(), result.getTotal()); pageResult.setRecords(voList); return pageResult; } @Override public List getDeviceVOList(Long projectId, String deviceType, String status) { List deviceList = getDeviceList(projectId, deviceType, status); return deviceList.stream().map(device -> { DeviceConfigVO.DeviceInfo vo = new DeviceConfigVO.DeviceInfo(); vo.setId(device.getId()); vo.setDeviceName(device.getDeviceName()); vo.setDeviceCode(device.getDeviceCode()); vo.setDeviceType(getDeviceTypeName(device.getDeviceType())); vo.setPlcIp(device.getPlcIp()); vo.setPlcPort(device.getPlcPort()); vo.setPlcType(device.getPlcType()); vo.setModuleName(device.getModuleName()); vo.setIsPrimary(device.getIsPrimary()); vo.setEnabled(Boolean.TRUE.equals(device.getEnabled())); vo.setIsEnabled(Boolean.TRUE.equals(device.getEnabled())); vo.setStatus(getStatusName(device.getStatus())); vo.setDeviceStatus(convertStatusToCode(device.getStatus())); vo.setDescription(device.getDescription()); vo.setLocation(extractLocationFromDevice(device)); vo.setCreatedTime(device.getCreatedTime()); vo.setUpdatedTime(device.getUpdatedTime()); vo.setProjectId(device.getProjectId()); return vo; }).collect(Collectors.toList()); } /** * 获取设备类型名称 */ private String getDeviceTypeName(String deviceType) { if (deviceType == null) return "未知设备"; // 直接返回设备类型值,因为实体类中已经使用中文类型 return deviceType; } /** * 获取设备状态名称 */ private String getStatusName(String status) { if (status == null) return "未知状态"; // 直接返回状态值,因为实体类中已经使用中文状态 return status; } /** * 将中文状态转换为前端使用的状态编码 */ private String convertStatusToCode(String status) { if (status == null) return "UNKNOWN"; switch (status) { case "在线": return "ONLINE"; case "离线": return "OFFLINE"; case "维护中": case "维护": return "MAINTENANCE"; case "故障": return "FAULT"; default: return status.toUpperCase(); } } /** * 更新单个设备启用状态 */ private boolean updateDeviceEnabledState(Long id, boolean enabled) { try { DeviceConfig device = getById(id); if (device == null) { log.warn("设备不存在: {}", id); return false; } device.setEnabled(enabled); device.setStatus(enabled ? DeviceConfig.Status.ONLINE : DeviceConfig.Status.OFFLINE); boolean result = updateById(device); if (result) { log.info("更新设备启用状态成功: {} -> {}", id, enabled); } return result; } catch (Exception e) { log.error("更新设备启用状态失败", e); return false; } } /** * 批量更新设备启用状态 */ private boolean batchUpdateDeviceEnabledState(List ids, boolean enabled) { if (ids == null || ids.isEmpty()) { return false; } try { LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); wrapper.in(DeviceConfig::getId, ids); DeviceConfig updateEntity = new DeviceConfig(); updateEntity.setEnabled(enabled); updateEntity.setStatus(enabled ? DeviceConfig.Status.ONLINE : DeviceConfig.Status.OFFLINE); boolean result = update(updateEntity, wrapper); if (result) { log.info("批量更新设备启用状态成功: {} 个设备 -> {}", ids.size(), enabled); } return result; } catch (Exception e) { log.error("批量更新设备启用状态失败", e); return false; } } /** * 字符串转换为状态 */ private String convertStatusFromString(String deviceStatus) { if (deviceStatus == null) return null; switch (deviceStatus.trim().toLowerCase()) { case "online": case "在线": case "1": return "在线"; case "offline": case "离线": case "2": return "离线"; case "maintenance": case "维护": case "维护中": case "3": return "维护中"; case "fault": case "故障": case "4": return "故障"; default: return null; } } @Override public boolean isDeviceCodeExists(String deviceCode, Long excludeId) { LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); wrapper.eq(DeviceConfig::getDeviceCode, deviceCode); wrapper.eq(DeviceConfig::getIsDeleted, 0); if (excludeId != null) { wrapper.ne(DeviceConfig::getId, excludeId); } return count(wrapper) > 0; } @Override public boolean updateDeviceStatus(Long id, String status) { try { DeviceConfig device = getById(id); if (device == null) { log.warn("设备不存在: {}", id); return false; } device.setStatus(status); boolean result = updateById(device); if (result) { log.info("更新设备状态成功: {} -> {}", id, status); } return result; } catch (Exception e) { log.error("更新设备状态失败", e); return false; } } @Override public boolean batchUpdateDeviceStatus(List ids, String status) { try { LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); wrapper.in(DeviceConfig::getId, ids); DeviceConfig updateEntity = new DeviceConfig(); updateEntity.setStatus(status); boolean result = update(updateEntity, wrapper); if (result) { log.info("批量更新设备状态成功: {} 个设备 -> {}", ids.size(), status); } return result; } catch (Exception e) { log.error("批量更新设备状态失败", e); return false; } } @Override public Map getExtraParams(Long id) { try { DeviceConfig device = getById(id); if (device == null || device.getExtraParams() == null) { return new HashMap<>(); } return objectMapper.readValue(device.getExtraParams(), new TypeReference>() {}); } catch (IOException e) { log.error("解析设备扩展参数失败", e); return new HashMap<>(); } } @Override public boolean updateExtraParams(Long id, Map extraParams) { try { DeviceConfig device = getById(id); if (device == null) { log.warn("设备不存在: {}", id); return false; } String extraParamsJson = objectMapper.writeValueAsString(extraParams); device.setExtraParams(extraParamsJson); boolean result = updateById(device); if (result) { log.info("更新设备扩展参数成功: {}", id); } return result; } catch (IOException e) { log.error("序列化设备扩展参数失败", e); return false; } } @Override public int getOnlineDeviceCount(Long projectId) { // 简化实现,实际项目中可能需要根据项目ID过滤 LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); wrapper.eq(DeviceConfig::getStatus, "在线"); wrapper.eq(DeviceConfig::getIsDeleted, 0); if (projectId != null) { wrapper.eq(DeviceConfig::getProjectId, projectId); } return (int) count(wrapper); } @Override public StatisticsVO.DeviceStatistics getDeviceStatistics(Long projectId) { try { // 设备总数 LambdaQueryWrapper totalWrapper = new LambdaQueryWrapper<>(); totalWrapper.eq(DeviceConfig::getIsDeleted, 0); if (projectId != null) { totalWrapper.eq(DeviceConfig::getProjectId, projectId); } int totalDevices = (int) count(totalWrapper); // 在线设备数 LambdaQueryWrapper onlineWrapper = new LambdaQueryWrapper<>(); onlineWrapper.eq(DeviceConfig::getStatus, "在线"); onlineWrapper.eq(DeviceConfig::getIsDeleted, 0); if (projectId != null) { onlineWrapper.eq(DeviceConfig::getProjectId, projectId); } int onlineDevices = (int) count(onlineWrapper); // 离线设备数 LambdaQueryWrapper offlineWrapper = new LambdaQueryWrapper<>(); offlineWrapper.eq(DeviceConfig::getStatus, "离线"); offlineWrapper.eq(DeviceConfig::getIsDeleted, 0); if (projectId != null) { offlineWrapper.eq(DeviceConfig::getProjectId, projectId); } int offlineDevices = (int) count(offlineWrapper); // 活跃设备数(在线设备) int activeDevices = onlineDevices; int inactiveDevices = offlineDevices; // 维护中设备数 LambdaQueryWrapper maintenanceWrapper = new LambdaQueryWrapper<>(); maintenanceWrapper.eq(DeviceConfig::getStatus, "维护中"); maintenanceWrapper.eq(DeviceConfig::getIsDeleted, 0); if (projectId != null) { maintenanceWrapper.eq(DeviceConfig::getProjectId, projectId); } int maintenanceDevices = (int) count(maintenanceWrapper); // 故障设备数 LambdaQueryWrapper faultWrapper = new LambdaQueryWrapper<>(); faultWrapper.eq(DeviceConfig::getStatus, "故障"); faultWrapper.eq(DeviceConfig::getIsDeleted, 0); if (projectId != null) { faultWrapper.eq(DeviceConfig::getProjectId, projectId); } int faultDevices = (int) count(faultWrapper); // 计算设备可用性 double deviceAvailability = totalDevices > 0 ? (double) activeDevices / totalDevices * 100 : 0.0; // 计算平均正常运行时间(模拟值) double averageUptime = 95.5; // 默认值,实际应用中可以基于历史数据计算 // 获取设备类型统计 List deviceTypeStats = getDeviceTypeStatistics(projectId); // 创建设备统计对象 StatisticsVO.DeviceStatistics deviceStatistics = new StatisticsVO.DeviceStatistics( totalDevices, onlineDevices, offlineDevices, activeDevices, inactiveDevices, faultDevices, maintenanceDevices, deviceTypeStats.size(), deviceAvailability, averageUptime, new Date(), deviceTypeStats ); log.info("获取设备统计信息成功: 总设备数={}, 在线设备数={}, 可用性={}%", totalDevices, onlineDevices, String.format("%.2f", deviceAvailability)); return deviceStatistics; } catch (Exception e) { log.error("获取设备统计信息失败", e); // 返回默认统计信息 return new StatisticsVO.DeviceStatistics(0, 0, 0, 0, 0, 0, 0, 0, 0.0, 0.0, new Date(), new ArrayList<>()); } } /** * 获取设备类型统计信息 */ private List getDeviceTypeStatistics(Long projectId) { try { List deviceTypeStats = new ArrayList<>(); // 获取所有设备类型 List deviceTypeNames = getAllDeviceTypes(); for (String deviceTypeName : deviceTypeNames) { // 总数 LambdaQueryWrapper totalWrapper = new LambdaQueryWrapper<>(); totalWrapper.eq(DeviceConfig::getDeviceType, deviceTypeName); totalWrapper.eq(DeviceConfig::getIsDeleted, 0); if (projectId != null) { totalWrapper.eq(DeviceConfig::getProjectId, projectId); } Integer totalCount = Math.toIntExact(count(totalWrapper)); // 在线数 LambdaQueryWrapper onlineWrapper = new LambdaQueryWrapper<>(); onlineWrapper.eq(DeviceConfig::getDeviceType, deviceTypeName); onlineWrapper.eq(DeviceConfig::getStatus, "在线"); onlineWrapper.eq(DeviceConfig::getIsDeleted, 0); if (projectId != null) { onlineWrapper.eq(DeviceConfig::getProjectId, projectId); } Integer onlineCount = Math.toIntExact(count(onlineWrapper)); // 离线数 LambdaQueryWrapper offlineWrapper = new LambdaQueryWrapper<>(); offlineWrapper.eq(DeviceConfig::getDeviceType, deviceTypeName); offlineWrapper.eq(DeviceConfig::getStatus, "离线"); offlineWrapper.eq(DeviceConfig::getIsDeleted, 0); if (projectId != null) { offlineWrapper.eq(DeviceConfig::getProjectId, projectId); } Integer offlineCount = Math.toIntExact(count(offlineWrapper)); // 可用性 double availability = totalCount > 0 ? (double) onlineCount / totalCount * 100 : 0.0; deviceTypeStats.add(new StatisticsVO.DeviceTypeStatistics( deviceTypeName, totalCount, onlineCount, offlineCount, availability )); } return deviceTypeStats; } catch (Exception e) { log.error("获取设备类型统计失败", e); return new ArrayList<>(); } } @Override public Long getDeviceCount(Long projectId, String deviceType, String deviceStatus, String keyword) { try { LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); if (projectId != null) { wrapper.eq(DeviceConfig::getProjectId, projectId); } // 设备类型过滤 if (deviceType != null && !deviceType.trim().isEmpty()) { wrapper.eq(DeviceConfig::getDeviceType, deviceType.trim()); } // 设备状态过滤 if (deviceStatus != null && !deviceStatus.trim().isEmpty()) { String convertedStatus = convertStatusFromString(deviceStatus); if (convertedStatus != null) { wrapper.eq(DeviceConfig::getStatus, convertedStatus); } } // 关键词搜索 if (keyword != null && !keyword.trim().isEmpty()) { wrapper.and(w -> w .like(DeviceConfig::getDeviceName, keyword) .or().like(DeviceConfig::getDeviceCode, keyword) .or().like(DeviceConfig::getDescription, keyword)); } wrapper.eq(DeviceConfig::getIsDeleted, 0); return (long) count(wrapper); } catch (Exception e) { log.error("获取设备总数失败", e); return 0L; } } @Override public List getAllDeviceTypes() { try { // 从数据库中查询所有已存在的设备类型(去重) LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); wrapper.select(DeviceConfig::getDeviceType); wrapper.eq(DeviceConfig::getIsDeleted, 0); wrapper.isNotNull(DeviceConfig::getDeviceType); wrapper.ne(DeviceConfig::getDeviceType, ""); List devices = list(wrapper); List deviceTypes = devices.stream() .map(DeviceConfig::getDeviceType) .filter(Objects::nonNull) .filter(type -> !type.trim().isEmpty()) .distinct() .sorted() .collect(Collectors.toList()); // 如果数据库中没有设备类型,返回默认类型 if (deviceTypes.isEmpty()) { deviceTypes.add(DeviceConfig.DeviceType.LOAD_VEHICLE); deviceTypes.add(DeviceConfig.DeviceType.LARGE_GLASS); deviceTypes.add(DeviceConfig.DeviceType.WORKSTATION_SCANNER); deviceTypes.add(DeviceConfig.DeviceType.WORKSTATION_TRANSFER); } return deviceTypes; } catch (Exception e) { log.error("获取设备类型列表失败", e); // 异常时返回默认类型 List defaultTypes = new ArrayList<>(); defaultTypes.add(DeviceConfig.DeviceType.LOAD_VEHICLE); defaultTypes.add(DeviceConfig.DeviceType.LARGE_GLASS); defaultTypes.add(DeviceConfig.DeviceType.WORKSTATION_SCANNER); defaultTypes.add(DeviceConfig.DeviceType.WORKSTATION_TRANSFER); return defaultTypes; } } @Override public List getAllDeviceStatuses() { List deviceStatuses = new ArrayList<>(); deviceStatuses.add("在线"); deviceStatuses.add("离线"); deviceStatuses.add("维护中"); deviceStatuses.add("故障"); return deviceStatuses; } @Override public boolean enableDevice(Long id) { return updateDeviceEnabledState(id, true); } @Override public boolean disableDevice(Long id) { return updateDeviceEnabledState(id, false); } @Override public boolean batchEnableDevices(List deviceIds) { return batchUpdateDeviceEnabledState(deviceIds, true); } @Override public boolean batchDisableDevices(List deviceIds) { return batchUpdateDeviceEnabledState(deviceIds, false); } @Override public DeviceConfigVO.HealthCheckResult performHealthCheck(Long id) { try { DeviceConfig device = getById(id); if (device == null) { log.warn("设备不存在: {}", id); DeviceConfigVO.HealthCheckResult result = new DeviceConfigVO.HealthCheckResult(); result.setIsHealthy(false); result.setOverallStatus("设备不存在"); result.setCheckTime(LocalDateTime.now()); return result; } // 简化的健康检查逻辑 boolean isHealthy = true; List issues = new ArrayList<>(); // 检查IP和端口配置 if (device.getPlcIp() == null || device.getPlcIp().trim().isEmpty()) { isHealthy = false; issues.add("IP地址配置缺失"); } if (device.getPlcPort() == null || device.getPlcPort() <= 0) { isHealthy = false; issues.add("端口配置无效"); } // 检查设备状态 if (device.getStatus() != null && device.getStatus().equals(DeviceConfig.Status.FAULT)) { isHealthy = false; issues.add("设备状态异常"); } String message = isHealthy ? "设备运行正常" : String.join(";", issues); log.info("设备健康检查完成: {} - {}", id, message); DeviceConfigVO.HealthCheckResult result = new DeviceConfigVO.HealthCheckResult(); result.setIsHealthy(isHealthy); result.setOverallStatus(message); result.setCheckTime(LocalDateTime.now()); return result; } catch (Exception e) { log.error("设备健康检查失败: {}", id, e); DeviceConfigVO.HealthCheckResult result = new DeviceConfigVO.HealthCheckResult(); result.setIsHealthy(false); result.setOverallStatus("健康检查失败: " + e.getMessage()); result.setCheckTime(LocalDateTime.now()); return result; } } @Override public List getDeviceTree(Long projectId) { try { List devices = getDeviceList(projectId, null, null); return devices.stream().map(device -> { DeviceConfigVO.DeviceTreeNode node = new DeviceConfigVO.DeviceTreeNode(); node.setId(device.getId()); node.setLabel(device.getDeviceName() + " (" + device.getDeviceCode() + ")"); node.setType("device"); node.setStatus(getStatusName(device.getStatus())); // 将额外信息放入data对象 Map data = new HashMap<>(); data.put("deviceId", device.getId()); data.put("deviceCode", device.getDeviceCode()); data.put("deviceType", getDeviceTypeName(device.getDeviceType())); node.setData(data); node.setChildren(null); // 设备节点没有子节点 return node; }).collect(Collectors.toList()); } catch (Exception e) { log.error("获取设备树结构失败", e); return new ArrayList<>(); } } /** * 从设备扩展参数中提取位置信息 */ private String extractLocationFromDevice(DeviceConfig device) { if (device == null) { return "默认位置"; } try { // 优先从extraParams中获取 if (device.getExtraParams() != null && !device.getExtraParams().trim().isEmpty()) { Map extraParams = objectMapper.readValue(device.getExtraParams(), MAP_TYPE); Object location = extraParams.get("location"); if (location != null) { return String.valueOf(location); } } // 从configJson中获取 if (device.getConfigJson() != null && !device.getConfigJson().trim().isEmpty()) { Map configJson = objectMapper.readValue(device.getConfigJson(), MAP_TYPE); Object location = configJson.get("location"); if (location != null) { return String.valueOf(location); } } } catch (Exception e) { log.warn("解析设备位置信息失败, deviceId={}", device.getId(), e); } return "默认位置"; } }