using AmtScanner.Api.Models; using AmtScanner.Api.Services; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.SignalR; using System.Collections.Concurrent; namespace AmtScanner.Api.Controllers; [ApiController] [Route("api/[controller]")] public class ScanController : ControllerBase { private readonly IAmtScannerService _scannerService; private readonly IHubContext _hubContext; private readonly ILogger _logger; // 存储扫描进度状态 private static readonly ConcurrentDictionary _scanStatuses = new(); public ScanController( IAmtScannerService scannerService, IHubContext hubContext, ILogger logger) { _scannerService = scannerService; _hubContext = hubContext; _logger = logger; } [HttpPost("start")] public async Task>> StartScan([FromBody] ScanRequest request) { var taskId = Guid.NewGuid().ToString(); _logger.LogInformation("Starting scan task: {TaskId}", taskId); // 初始化扫描状态 _scanStatuses[taskId] = new ScanStatusInfo { TaskId = taskId, Status = "running", ScannedCount = 0, TotalCount = 0, FoundDevices = 0 }; // Start scan in background _ = Task.Run(async () => { var progress = new Progress(async p => { // 更新状态存储 if (_scanStatuses.TryGetValue(taskId, out var status)) { status.ScannedCount = p.ScannedCount; status.TotalCount = p.TotalCount; status.FoundDevices = p.FoundDevices; status.CurrentIp = p.CurrentIp; } await _hubContext.Clients.All.SendAsync("ReceiveScanProgress", p); }); try { await _scannerService.ScanNetworkAsync( taskId, request.NetworkSegment, request.SubnetMask, progress ); // 更新状态为完成 if (_scanStatuses.TryGetValue(taskId, out var status)) { status.Status = "completed"; } // Send completion notification _logger.LogInformation("Scan task {TaskId} completed", taskId); await _hubContext.Clients.All.SendAsync("ScanCompleted", new { taskId }); } catch (Exception ex) { // 更新状态为错误 if (_scanStatuses.TryGetValue(taskId, out var status)) { status.Status = "error"; status.Error = ex.Message; } _logger.LogError(ex, "Error in scan task {TaskId}", taskId); await _hubContext.Clients.All.SendAsync("ScanError", new { taskId, error = ex.Message }); } }); return Ok(ApiResponse.Success(new ScanStartResponse { TaskId = taskId }, "扫描任务已启动")); } [HttpGet("status/{taskId}")] public ActionResult> GetScanStatus(string taskId) { if (_scanStatuses.TryGetValue(taskId, out var status)) { return Ok(ApiResponse.Success(status)); } return Ok(ApiResponse.Fail(404, "扫描任务不存在")); } [HttpPost("cancel/{taskId}")] public ActionResult> CancelScan(string taskId) { _scannerService.CancelScan(taskId); // 更新状态为已取消 if (_scanStatuses.TryGetValue(taskId, out var status)) { status.Status = "cancelled"; } return Ok(ApiResponse.Success(null, "扫描任务已取消")); } } public class ScanStartResponse { public string TaskId { get; set; } = string.Empty; } public class ScanStatusInfo { public string TaskId { get; set; } = string.Empty; public string Status { get; set; } = "idle"; // idle, running, completed, cancelled, error public int ScannedCount { get; set; } public int TotalCount { get; set; } public int FoundDevices { get; set; } public string? CurrentIp { get; set; } public string? Error { get; set; } } public class ScanRequest { public string NetworkSegment { get; set; } = string.Empty; public string SubnetMask { get; set; } = string.Empty; }