| | |
| | | import com.mes.device.vo.DeviceConfigVO; |
| | | import com.mes.device.vo.StatisticsVO; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.apache.commons.lang3.StringUtils; |
| | | import org.springframework.stereotype.Service; |
| | | |
| | | import java.io.IOException; |
| | |
| | | public class DeviceConfigServiceImpl extends ServiceImpl<DeviceConfigMapper, DeviceConfig> implements DeviceConfigService { |
| | | |
| | | private final ObjectMapper objectMapper = new ObjectMapper(); |
| | | private static final TypeReference<Map<String, Object>> MAP_TYPE = new TypeReference<Map<String, Object>>() {}; |
| | | |
| | | @Override |
| | | public boolean createDevice(DeviceConfig deviceConfig) { |
| | | try { |
| | | // 若未传则生成设备编码 |
| | | String code = StringUtils.trimToEmpty(deviceConfig.getDeviceCode()); |
| | | if (StringUtils.isBlank(code)) { |
| | | code = generateDeviceCode(); |
| | | deviceConfig.setDeviceCode(code); |
| | | } else { |
| | | deviceConfig.setDeviceCode(code); |
| | | } |
| | | |
| | | // 检查设备编号是否已存在 |
| | | if (isDeviceCodeExists(deviceConfig.getDeviceCode(), null)) { |
| | | log.warn("设备编号已存在: {}", deviceConfig.getDeviceCode()); |
| | | return false; |
| | | if (isDeviceCodeExists(code, null)) { |
| | | log.warn("设备编号已存在: {}", code); |
| | | throw new IllegalArgumentException("设备编码已存在"); |
| | | } |
| | | |
| | | // 兼容旧字段:统一将 device_id 填为 deviceCode,避免非空/唯一约束问题 |
| | | deviceConfig.setDeviceId(code); |
| | | |
| | | // 项目ID未传则使用默认项目(单项目场景可用),避免非空约束 |
| | | if (deviceConfig.getProjectId() == null) { |
| | | deviceConfig.setProjectId(1L); |
| | | } |
| | | |
| | | // 初始化设备状态为离线 |
| | |
| | | return result; |
| | | } catch (Exception e) { |
| | | log.error("创建设备配置失败", e); |
| | | return false; |
| | | throw e; |
| | | } |
| | | } |
| | | |
| | |
| | | if (isDeviceCodeExists(deviceConfig.getDeviceCode(), deviceConfig.getId())) { |
| | | log.warn("设备编号已存在: {}", deviceConfig.getDeviceCode()); |
| | | return false; |
| | | } |
| | | |
| | | // 同步 device_id 与 deviceCode,保持一致 |
| | | if (StringUtils.isNotBlank(deviceConfig.getDeviceCode())) { |
| | | deviceConfig.setDeviceId(deviceConfig.getDeviceCode().trim()); |
| | | } |
| | | |
| | | // 若项目ID缺失,使用默认项目 |
| | | if (deviceConfig.getProjectId() == null) { |
| | | deviceConfig.setProjectId(1L); |
| | | } |
| | | |
| | | boolean result = updateById(deviceConfig); |
| | |
| | | |
| | | // 设备类型过滤 |
| | | if (deviceType != null && !deviceType.trim().isEmpty()) { |
| | | String convertedDeviceType = convertDeviceTypeFromString(deviceType); |
| | | if (convertedDeviceType != null) { |
| | | wrapper.eq(DeviceConfig::getDeviceType, convertedDeviceType); |
| | | } |
| | | wrapper.eq(DeviceConfig::getDeviceType, deviceType.trim()); |
| | | } |
| | | |
| | | // 设备状态过滤 |
| | |
| | | vo.setStatus(getStatusName(device.getStatus())); |
| | | vo.setDeviceStatus(convertStatusToCode(device.getStatus())); |
| | | vo.setDescription(device.getDescription()); |
| | | vo.setLocation("默认位置"); // TODO: 从扩展参数或关联表中获取 |
| | | vo.setLocation(extractLocationFromDevice(device)); |
| | | vo.setCreatedTime(device.getCreatedTime()); |
| | | vo.setUpdatedTime(device.getUpdatedTime()); |
| | | vo.setProjectId(device.getProjectId()); |
| | |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 字符串转换为设备类型 |
| | | */ |
| | | private String convertDeviceTypeFromString(String deviceType) { |
| | | if (deviceType == null) return null; |
| | | |
| | | switch (deviceType.trim().toLowerCase()) { |
| | | case "load_vehicle": |
| | | case "上大车": |
| | | case "1": |
| | | return DeviceConfig.DeviceType.LOAD_VEHICLE; |
| | | case "large_glass": |
| | | case "大理片": |
| | | case "2": |
| | | return DeviceConfig.DeviceType.LARGE_GLASS; |
| | | case "glass_storage": |
| | | case "玻璃存储": |
| | | case "3": |
| | | return DeviceConfig.DeviceType.GLASS_STORAGE; |
| | | default: |
| | | return null; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 字符串转换为状态 |
| | |
| | | |
| | | @Override |
| | | public boolean isDeviceCodeExists(String deviceCode, Long excludeId) { |
| | | if (StringUtils.isBlank(deviceCode)) { |
| | | return false; |
| | | } |
| | | String trimmed = deviceCode.trim(); |
| | | |
| | | LambdaQueryWrapper<DeviceConfig> wrapper = new LambdaQueryWrapper<>(); |
| | | wrapper.eq(DeviceConfig::getDeviceCode, deviceCode); |
| | | wrapper.eq(DeviceConfig::getDeviceCode, trimmed); |
| | | wrapper.eq(DeviceConfig::getIsDeleted, 0); |
| | | |
| | | if (excludeId != null) { |
| | |
| | | } |
| | | |
| | | return count(wrapper) > 0; |
| | | } |
| | | |
| | | /** |
| | | * 简单的设备编码生成器:DEV_前缀 |
| | | */ |
| | | private String generateDeviceCode() { |
| | | Long maxNo = getBaseMapper().selectMaxDeviceCodeNumber(); |
| | | long next = (maxNo == null ? 0 : maxNo) + 1; |
| | | // 左侧补零到6位,例如 DEV_000123 |
| | | return String.format("DEV_%06d", next); |
| | | } |
| | | |
| | | @Override |
| | |
| | | } |
| | | |
| | | // 设备类型过滤 |
| | | if (deviceType != null && !deviceType.trim().isEmpty()) { |
| | | String convertedDeviceType = convertDeviceTypeFromString(deviceType); |
| | | if (convertedDeviceType != null) { |
| | | wrapper.eq(DeviceConfig::getDeviceType, convertedDeviceType); |
| | | } |
| | | } |
| | | if (deviceType != null && !deviceType.trim().isEmpty()) { |
| | | wrapper.eq(DeviceConfig::getDeviceType, deviceType.trim()); |
| | | } |
| | | |
| | | // 设备状态过滤 |
| | | if (deviceStatus != null && !deviceStatus.trim().isEmpty()) { |
| | |
| | | |
| | | @Override |
| | | public List<String> getAllDeviceTypes() { |
| | | List<String> deviceTypes = new ArrayList<>(); |
| | | deviceTypes.add("PLC设备"); |
| | | deviceTypes.add("传感器设备"); |
| | | deviceTypes.add("执行器设备"); |
| | | deviceTypes.add("人机界面设备"); |
| | | try { |
| | | // 从数据库中查询所有已存在的设备类型(去重) |
| | | LambdaQueryWrapper<DeviceConfig> wrapper = new LambdaQueryWrapper<>(); |
| | | wrapper.select(DeviceConfig::getDeviceType); |
| | | wrapper.eq(DeviceConfig::getIsDeleted, 0); |
| | | wrapper.isNotNull(DeviceConfig::getDeviceType); |
| | | wrapper.ne(DeviceConfig::getDeviceType, ""); |
| | | |
| | | List<DeviceConfig> devices = list(wrapper); |
| | | List<String> 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<String> 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 |
| | |
| | | return new ArrayList<>(); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 从设备扩展参数中提取位置信息 |
| | | */ |
| | | private String extractLocationFromDevice(DeviceConfig device) { |
| | | if (device == null) { |
| | | return "默认位置"; |
| | | } |
| | | try { |
| | | // 优先从extraParams中获取 |
| | | if (device.getExtraParams() != null && !device.getExtraParams().trim().isEmpty()) { |
| | | Map<String, Object> 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<String, Object> 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 "默认位置"; |
| | | } |
| | | } |