using AmtScanner.Api.Data; using AmtScanner.Api.Models; using AmtScanner.Api.Services; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; namespace AmtScanner.Api.Controllers; /// /// 远程桌面控制器 /// [ApiController] [Route("api/remote-desktop")] public class RemoteDesktopController : ControllerBase { private readonly ILogger _logger; private readonly GuacamoleService _guacamoleService; private readonly AppDbContext _db; private readonly IConfiguration _config; public RemoteDesktopController( ILogger logger, GuacamoleService guacamoleService, AppDbContext db, IConfiguration config) { _logger = logger; _guacamoleService = guacamoleService; _db = db; _config = config; } /// /// 连接到设备的远程桌面 (RDP) /// [HttpPost("connect/rdp")] public async Task ConnectRdp([FromBody] RdpConnectRequest request) { if (string.IsNullOrEmpty(request.Hostname)) { return BadRequest(ApiResponse.Fail(400, "主机地址不能为空")); } try { var connectionName = $"RDP-{request.Hostname}-{DateTime.Now:yyyyMMddHHmmss}"; var connectionId = await _guacamoleService.CreateRdpConnectionAsync( connectionName, request.Hostname, request.Username ?? "", request.Password ?? "", request.Port); if (string.IsNullOrEmpty(connectionId)) { return BadRequest(ApiResponse.Fail(500, "创建远程连接失败,请检查 Guacamole 服务是否正常")); } var connectionUrl = await _guacamoleService.GetConnectionUrlAsync(connectionId); return Ok(ApiResponse.Success(new { connectionId, connectionUrl, guacamoleUrl = _config["Guacamole:BaseUrl"] ?? "http://localhost:8080/guacamole" })); } catch (Exception ex) { _logger.LogError(ex, "创建 RDP 连接失败"); return BadRequest(ApiResponse.Fail(500, $"创建连接失败: {ex.Message}")); } } /// /// 连接到设备的远程桌面 (VNC) /// [HttpPost("connect/vnc")] public async Task ConnectVnc([FromBody] VncConnectRequest request) { if (string.IsNullOrEmpty(request.Hostname)) { return BadRequest(ApiResponse.Fail(400, "主机地址不能为空")); } try { var connectionName = $"VNC-{request.Hostname}-{DateTime.Now:yyyyMMddHHmmss}"; var connectionId = await _guacamoleService.CreateVncConnectionAsync( connectionName, request.Hostname, request.Password ?? "", request.Port); if (string.IsNullOrEmpty(connectionId)) { return BadRequest(ApiResponse.Fail(500, "创建远程连接失败,请检查 Guacamole 服务是否正常")); } var connectionUrl = await _guacamoleService.GetConnectionUrlAsync(connectionId); return Ok(ApiResponse.Success(new { connectionId, connectionUrl, guacamoleUrl = _config["Guacamole:BaseUrl"] ?? "http://localhost:8080/guacamole" })); } catch (Exception ex) { _logger.LogError(ex, "创建 VNC 连接失败"); return BadRequest(ApiResponse.Fail(500, $"创建连接失败: {ex.Message}")); } } /// /// 通过设备 UUID 连接远程桌面 /// [HttpPost("connect/device/{uuid}")] public async Task ConnectByDevice(string uuid, [FromBody] DeviceConnectRequest request) { // 先查找 Agent 设备 var agentDevice = await _db.AgentDevices_new.FirstOrDefaultAsync(d => d.Uuid == uuid); if (agentDevice != null) { var connectionName = $"RDP-{agentDevice.Hostname ?? agentDevice.IpAddress}-{DateTime.Now:yyyyMMddHHmmss}"; var connectionId = await _guacamoleService.CreateRdpConnectionAsync( connectionName, agentDevice.IpAddress, request.Username ?? "", request.Password ?? "", request.Port > 0 ? request.Port : 3389); if (string.IsNullOrEmpty(connectionId)) { return BadRequest(ApiResponse.Fail(500, "创建远程连接失败")); } var connectionUrl = await _guacamoleService.GetConnectionUrlAsync(connectionId); return Ok(ApiResponse.Success(new { connectionId, connectionUrl, deviceName = agentDevice.Hostname ?? agentDevice.IpAddress, guacamoleUrl = _config["Guacamole:BaseUrl"] ?? "http://localhost:8080/guacamole" })); } // 再查找 AMT 设备 var amtDevice = await _db.AmtDevices_new.FirstOrDefaultAsync(d => d.Uuid == uuid); if (amtDevice != null) { var connectionName = $"RDP-{amtDevice.Hostname ?? amtDevice.IpAddress}-{DateTime.Now:yyyyMMddHHmmss}"; var connectionId = await _guacamoleService.CreateRdpConnectionAsync( connectionName, amtDevice.IpAddress, request.Username ?? "", request.Password ?? "", request.Port > 0 ? request.Port : 3389); if (string.IsNullOrEmpty(connectionId)) { return BadRequest(ApiResponse.Fail(500, "创建远程连接失败")); } var connectionUrl = await _guacamoleService.GetConnectionUrlAsync(connectionId); return Ok(ApiResponse.Success(new { connectionId, connectionUrl, deviceName = amtDevice.Hostname ?? amtDevice.IpAddress, guacamoleUrl = _config["Guacamole:BaseUrl"] ?? "http://localhost:8080/guacamole" })); } return NotFound(ApiResponse.Fail(404, "设备不存在")); } /// /// 断开连接(删除 Guacamole 连接) /// [HttpDelete("disconnect/{connectionId}")] public async Task Disconnect(string connectionId) { var result = await _guacamoleService.DeleteConnectionAsync(connectionId); if (result) { return Ok(ApiResponse.Success("连接已断开")); } else { return BadRequest(ApiResponse.Fail(500, "断开连接失败")); } } /// /// 获取所有远程连接 /// [HttpGet("connections")] public async Task GetConnections() { var connections = await _guacamoleService.GetConnectionsAsync(); return Ok(ApiResponse.Success(connections)); } /// /// 获取 Guacamole 配置信息 /// [HttpGet("config")] public IActionResult GetConfig() { return Ok(ApiResponse.Success(new { guacamoleUrl = _config["Guacamole:BaseUrl"] ?? "http://localhost:8080/guacamole", enabled = !string.IsNullOrEmpty(_config["Guacamole:BaseUrl"]) })); } } public class RdpConnectRequest { public string Hostname { get; set; } = ""; public string? Username { get; set; } public string? Password { get; set; } public int Port { get; set; } = 3389; } public class VncConnectRequest { public string Hostname { get; set; } = ""; public string? Password { get; set; } public int Port { get; set; } = 5900; } public class DeviceConnectRequest { public string? Username { get; set; } public string? Password { get; set; } public int Port { get; set; } = 3389; public string Protocol { get; set; } = "rdp"; // rdp 或 vnc }