using AmtScanner.Api.Data; using AmtScanner.Api.Services; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; namespace AmtScanner.Api.Controllers; [ApiController] [Route("api/[controller]")] public class PowerController : ControllerBase { private readonly AppDbContext _context; private readonly IAmtPowerService _powerService; private readonly ICredentialService _credentialService; private readonly ILogger _logger; public PowerController( AppDbContext context, IAmtPowerService powerService, ICredentialService credentialService, ILogger logger) { _context = context; _powerService = powerService; _credentialService = credentialService; _logger = logger; } /// /// 获取设备电源状态 /// [HttpGet("{deviceId}/state")] public async Task> GetPowerState(long deviceId) { var device = await _context.AmtDevices.FindAsync(deviceId); if (device == null) { return NotFound(new { error = "设备不存在" }); } var credential = await _credentialService.GetDefaultCredentialAsync(); if (credential == null) { return BadRequest(new { error = "没有配置默认凭据" }); } var openPorts = new List(); if (device.AmtOnline) { // 检测可用端口 openPorts = await DetectOpenPortsAsync(device.IpAddress); } if (openPorts.Count == 0) { return Ok(new PowerStateResponse { DeviceId = deviceId, IpAddress = device.IpAddress, Success = false, Error = "设备离线或AMT端口不可用" }); } // 解密密码 var decryptedPassword = _credentialService.DecryptPassword(credential.Password); var result = await _powerService.GetPowerStateAsync( device.IpAddress, credential.Username, decryptedPassword, openPorts); return Ok(new PowerStateResponse { DeviceId = deviceId, IpAddress = device.IpAddress, Success = result.Success, PowerState = result.PowerState, PowerStateText = result.PowerStateText, Error = result.Error }); } /// /// 开机 /// [HttpPost("{deviceId}/power-on")] public async Task> PowerOn(long deviceId) { return await ExecutePowerAction(deviceId, PowerAction.PowerOn); } /// /// 关机(优雅关机) /// [HttpPost("{deviceId}/power-off")] public async Task> PowerOff(long deviceId) { return await ExecutePowerAction(deviceId, PowerAction.GracefulOff); } /// /// 强制关机 /// [HttpPost("{deviceId}/force-off")] public async Task> ForceOff(long deviceId) { return await ExecutePowerAction(deviceId, PowerAction.PowerOff); } /// /// 重启(优雅重启) /// [HttpPost("{deviceId}/restart")] public async Task> Restart(long deviceId) { return await ExecutePowerAction(deviceId, PowerAction.GracefulReset); } /// /// 强制重启 /// [HttpPost("{deviceId}/force-restart")] public async Task> ForceRestart(long deviceId) { return await ExecutePowerAction(deviceId, PowerAction.Reset); } /// /// 电源循环(硬重启) /// [HttpPost("{deviceId}/power-cycle")] public async Task> PowerCycle(long deviceId) { return await ExecutePowerAction(deviceId, PowerAction.PowerCycle); } private async Task> ExecutePowerAction(long deviceId, PowerAction action) { var device = await _context.AmtDevices.FindAsync(deviceId); if (device == null) { return NotFound(new { error = "设备不存在" }); } var credential = await _credentialService.GetDefaultCredentialAsync(); if (credential == null) { return BadRequest(new { error = "没有配置默认凭据" }); } // 检测可用端口 var openPorts = await DetectOpenPortsAsync(device.IpAddress); if (openPorts.Count == 0) { return Ok(new PowerActionResponse { DeviceId = deviceId, IpAddress = device.IpAddress, Action = action.ToString(), Success = false, Error = "AMT端口不可用" }); } // 解密密码 var decryptedPassword = _credentialService.DecryptPassword(credential.Password); var result = await _powerService.ChangePowerStateAsync( device.IpAddress, credential.Username, decryptedPassword, openPorts, action); return Ok(new PowerActionResponse { DeviceId = deviceId, IpAddress = device.IpAddress, Action = action.ToString(), Success = result.Success, Message = result.Message, Error = result.Error }); } private async Task> DetectOpenPortsAsync(string ipAddress) { var openPorts = new List(); int[] amtPorts = { 16992, 16993 }; foreach (var port in amtPorts) { try { using var client = new System.Net.Sockets.TcpClient(); var connectTask = client.ConnectAsync(ipAddress, port); if (await Task.WhenAny(connectTask, Task.Delay(1000)) == connectTask) { if (client.Connected) { openPorts.Add(port); } } } catch { // 端口不可用 } } return openPorts; } } public class PowerStateResponse { public long DeviceId { get; set; } public string IpAddress { get; set; } = string.Empty; public bool Success { get; set; } public int PowerState { get; set; } public string PowerStateText { get; set; } = string.Empty; public string? Error { get; set; } } public class PowerActionResponse { public long DeviceId { get; set; } public string IpAddress { get; set; } = string.Empty; public string Action { get; set; } = string.Empty; public bool Success { get; set; } public string Message { get; set; } = string.Empty; public string? Error { get; set; } }