package com.mes.device.controller; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.fasterxml.jackson.databind.ObjectMapper; import com.mes.device.entity.DeviceConfig; import com.mes.device.request.DeviceConfigRequest; import com.mes.device.service.DeviceConfigService; import com.mes.device.vo.DeviceConfigVO; import com.mes.device.vo.StatisticsVO; import com.mes.vo.Result; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiParam; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; import javax.validation.Valid; import java.util.List; import java.util.Map; /** * 设备配置管理控制器 * * @author mes * @since 2024-10-30 */ @Slf4j @RestController @RequestMapping("device/config") @Api(tags = "设备配置管理") public class DeviceConfigController { @Autowired private DeviceConfigService deviceConfigService; @Autowired private ObjectMapper objectMapper; /** * 创建设备配置 */ @PostMapping("/devices") @ApiOperation("创建设备配置") public Result createDevice( @Valid @RequestBody DeviceConfig deviceConfig) { try { boolean success = deviceConfigService.createDevice(deviceConfig); if (success) { // 创建成功后,重新获取设备对象 DeviceConfig created = deviceConfigService.getDeviceByCode(deviceConfig.getDeviceCode()); return Result.success(created); } else { return Result.error("设备配置已存在"); } } catch (Exception e) { log.error("创建设备配置失败", e); return Result.error("创建设备配置失败"); } } /** * 更新设备配置 */ @PostMapping("/devices/update") @ApiOperation("更新设备配置") public Result updateDevice( @Valid @RequestBody DeviceConfigRequest request) { try { DeviceConfig deviceConfig; Object deviceConfigObj = request.getDeviceConfig(); // 如果 deviceConfig 是 Map 类型(JSON 反序列化后的 LinkedHashMap),需要转换为 DeviceConfig if (deviceConfigObj instanceof Map) { deviceConfig = objectMapper.convertValue(deviceConfigObj, DeviceConfig.class); } else if (deviceConfigObj instanceof DeviceConfig) { deviceConfig = (DeviceConfig) deviceConfigObj; } else { log.error("不支持的 deviceConfig 类型: {}", deviceConfigObj != null ? deviceConfigObj.getClass() : "null"); return Result.error("设备配置数据格式错误"); } deviceConfig.setId(request.getDeviceId()); boolean success = deviceConfigService.updateDevice(deviceConfig); if (success) { // 更新成功后,重新获取设备对象 DeviceConfig updated = deviceConfigService.getDeviceById(request.getDeviceId()); return Result.success(updated); } else { return Result.error("设备配置不存在"); } } catch (Exception e) { log.error("更新设备配置失败", e); return Result.error("更新设备配置失败: " + e.getMessage()); } } /** * 删除设备配置 */ @PostMapping("/devices/delete") @ApiOperation("删除设备配置") public Result deleteDevice( @Valid @RequestBody DeviceConfigRequest request) { try { deviceConfigService.deleteDevice(request.getDeviceId()); return Result.success(null); } catch (Exception e) { log.error("删除设备配置失败", e); return Result.error("删除设备配置失败"); } } /** * 根据ID获取设备配置 */ @PostMapping("/devices/detail") @ApiOperation("获取设备配置详情") public Result getDeviceById( @Valid @RequestBody DeviceConfigRequest request) { try { DeviceConfig device = deviceConfigService.getDeviceById(request.getDeviceId()); return Result.success(device); } catch (Exception e) { log.error("获取设备配置失败", e); return Result.error("获取设备配置失败"); } } /** * 分页查询设备配置列表 */ @PostMapping("/devices/list") @ApiOperation("分页查询设备配置") public Result> getDeviceList( @Valid @RequestBody DeviceConfigRequest request) { try { Page pageResult = deviceConfigService.getDeviceList( request.getProjectId(), request.getDeviceType(), request.getDeviceStatus(), request.getKeyword(), request.getPage() != null ? request.getPage() : 1, request.getSize() != null ? request.getSize() : 10); return Result.success(pageResult); } catch (Exception e) { log.error("查询设备配置列表失败", e); return Result.error("查询设备配置列表失败"); } } /** * 启用设备 */ @PostMapping("/devices/enable") @ApiOperation("启用设备") public Result enableDevice( @Valid @RequestBody DeviceConfigRequest request) { try { deviceConfigService.enableDevice(request.getDeviceId()); return Result.success(null); } catch (Exception e) { log.error("启用设备失败", e); return Result.error("启用设备失败"); } } /** * 禁用设备 */ @PostMapping("/devices/disable") @ApiOperation("禁用设备") public Result disableDevice( @Valid @RequestBody DeviceConfigRequest request) { try { deviceConfigService.disableDevice(request.getDeviceId()); return Result.success(null); } catch (Exception e) { log.error("禁用设备失败", e); return Result.error("禁用设备失败"); } } /** * 批量启用设备 */ @PostMapping("/devices/batch-enable") @ApiOperation("批量启用设备") public Result batchEnableDevices( @Valid @RequestBody DeviceConfigRequest request) { try { deviceConfigService.batchEnableDevices(request.getDeviceIds()); return Result.success(null); } catch (Exception e) { log.error("批量启用设备失败", e); return Result.error("批量启用设备失败"); } } /** * 批量禁用设备 */ @PostMapping("/devices/batch-disable") @ApiOperation("批量禁用设备") public Result batchDisableDevices( @Valid @RequestBody DeviceConfigRequest request) { try { deviceConfigService.batchDisableDevices(request.getDeviceIds()); return Result.success(null); } catch (Exception e) { log.error("批量禁用设备失败", e); return Result.error("批量禁用设备失败"); } } /** * 获取设备统计信息 */ @PostMapping("/statistics/devices") @ApiOperation("获取设备统计信息") public Result getDeviceStatistics( @ApiParam("设备配置请求") @RequestBody(required = false) DeviceConfigRequest request) { try { StatisticsVO.DeviceStatistics statistics = deviceConfigService.getDeviceStatistics(request != null ? request.getProjectId() : null); return Result.success(statistics); } catch (Exception e) { log.error("获取设备统计信息失败", e); return Result.error("获取设备统计信息失败"); } } /** * 检查设备编码是否已存在 */ @PostMapping("/devices/check-code") @ApiOperation("检查设备编码") public Result checkDeviceCodeExists( @ApiParam("设备配置请求") @RequestBody DeviceConfigRequest request) { try { boolean exists = deviceConfigService.isDeviceCodeExists(request.getDeviceCode(), request.getDeviceId()); return Result.success(exists); } catch (Exception e) { log.error("检查设备编码失败", e); return Result.error("检查设备编码失败"); } } /** * 获取设备类型列表 */ @PostMapping("/devices/types") @ApiOperation("获取设备类型列表") public Result> getDeviceTypes(@RequestBody(required = false) Map request) { try { List deviceTypes = deviceConfigService.getAllDeviceTypes(); return Result.success(deviceTypes); } catch (Exception e) { log.error("获取设备类型列表失败", e); return Result.error("获取设备类型列表失败"); } } /** * 获取设备状态列表 */ @PostMapping("/devices/statuses") @ApiOperation("获取设备状态列表") public Result> getDeviceStatuses(@RequestBody(required = false) Map request) { try { List deviceStatuses = deviceConfigService.getAllDeviceStatuses(); return Result.success(deviceStatuses); } catch (Exception e) { log.error("获取设备状态列表失败", e); return Result.error("获取设备状态列表失败"); } } /** * 获取设备配置树结构 */ @PostMapping("/devices/tree") @ApiOperation("获取设备配置树结构") public Result> getDeviceTree( @ApiParam("设备配置请求") @RequestBody(required = false) DeviceConfigRequest request) { try { List treeData = deviceConfigService.getDeviceTree(request != null ? request.getProjectId() : null); return Result.success(treeData); } catch (Exception e) { log.error("获取设备配置树结构失败", e); return Result.error("获取设备配置树结构失败"); } } /** * 设备健康检查 */ @PostMapping("/devices/health-check") @ApiOperation("设备健康检查") public Result performHealthCheck( @Valid @RequestBody DeviceConfigRequest request) { try { DeviceConfigVO.HealthCheckResult result = deviceConfigService.performHealthCheck(request.getDeviceId()); return Result.success(result); } catch (Exception e) { log.error("设备健康检查失败", e); return Result.error("设备健康检查失败"); } } /** * 测试设备PLC连接 * 支持两种方式: * 1. 传入 deviceId,根据已保存的设备配置测试 * 2. 直接传入 plcIp / plcPort / timeout 进行一次性测试 */ @PostMapping("/devices/test-connection") @ApiOperation("测试设备PLC连接") public Result testDeviceConnection(@RequestBody Map body) { try { String plcIp = null; Integer plcPort = null; Integer timeoutMs = null; // 优先根据 deviceId 读取已保存配置 Object deviceIdObj = body.get("deviceId"); if (deviceIdObj != null) { Long deviceId = deviceIdObj instanceof Number ? ((Number) deviceIdObj).longValue() : Long.parseLong(deviceIdObj.toString()); DeviceConfig device = deviceConfigService.getDeviceById(deviceId); if (device == null) { return Result.error("设备不存在: " + deviceId); } plcIp = device.getPlcIp(); plcPort = device.getPlcPort(); timeoutMs = 3000; } else { // 直接从请求体中获取测试参数 Object ipObj = body.get("plcIp"); Object portObj = body.get("plcPort"); Object timeoutObj = body.get("timeout"); if (ipObj != null) { plcIp = String.valueOf(ipObj); } if (portObj instanceof Number) { plcPort = ((Number) portObj).intValue(); } else if (portObj != null) { plcPort = Integer.parseInt(portObj.toString()); } if (timeoutObj instanceof Number) { timeoutMs = ((Number) timeoutObj).intValue() * 1000; } else if (timeoutObj != null) { timeoutMs = Integer.parseInt(timeoutObj.toString()) * 1000; } } if (plcIp == null || plcIp.trim().isEmpty()) { return Result.error("PLC IP不能为空"); } if (plcPort == null || plcPort <= 0 || plcPort > 65535) { plcPort = 102; } if (timeoutMs == null || timeoutMs <= 0) { timeoutMs = 3000; } boolean ok = testTcpConnection(plcIp, plcPort, timeoutMs); if (ok) { String msg = String.format("连接测试成功:%s:%d", plcIp, plcPort); log.info(msg); return Result.success(msg); } else { String msg = String.format("连接测试失败:%s:%d", plcIp, plcPort); log.warn(msg); return Result.error(msg); } } catch (Exception e) { log.error("设备PLC连接测试失败", e); return Result.error("连接测试异常: " + e.getMessage()); } } private boolean testTcpConnection(String ip, int port, int timeoutMs) { java.net.Socket socket = null; try { socket = new java.net.Socket(); socket.connect(new java.net.InetSocketAddress(ip, port), timeoutMs); return true; } catch (Exception e) { log.warn("TCP连接测试失败: {}:{}, err={}", ip, port, e.getMessage()); return false; } finally { if (socket != null) { try { socket.close(); } catch (Exception ignore) { } } } } }