using AmtScanner.Api.Data; using AmtScanner.Api.Models; using AmtScanner.Api.Services; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; namespace AmtScanner.Api.Controllers; [ApiController] [Route("api/amt-pending-devices")] [Authorize] public class AmtPendingDevicesController : ControllerBase { private readonly AppDbContext _db; private readonly IAmtWsmanService _wsmanService; private readonly ILogger _logger; public AmtPendingDevicesController(AppDbContext db, IAmtWsmanService wsmanService, ILogger logger) { _db = db; _wsmanService = wsmanService; _logger = logger; } /// /// 获取待接管设备列表 /// [HttpGet] public async Task GetList([FromQuery] int page = 1, [FromQuery] int pageSize = 20, [FromQuery] bool? isTakenOver = null) { var query = _db.AmtPendingDevices_new.AsQueryable(); if (isTakenOver.HasValue) { query = query.Where(d => d.IsTakenOver == isTakenOver.Value); } var total = await query.CountAsync(); var items = await query .OrderByDescending(d => d.CreatedAt) .Skip((page - 1) * pageSize) .Take(pageSize) .ToListAsync(); return Ok(ApiResponse.Success(new { items, total, page, pageSize })); } /// /// 手动添加设备 /// [HttpPost] public async Task AddDevice([FromBody] AddPendingDeviceRequest request) { // 检查IP是否已存在 var existing = await _db.AmtPendingDevices_new .FirstOrDefaultAsync(d => d.IpAddress == request.IpAddress); if (existing != null) { return BadRequest(ApiResponse.Fail(400, $"IP地址 {request.IpAddress} 已存在")); } var device = new AmtPendingDevice_new { IpAddress = request.IpAddress, SubnetMask = request.SubnetMask, Gateway = request.Gateway, AmtUsername = request.AmtUsername, AmtPassword = request.AmtPassword, Source = "manual", CreatedAt = DateTime.UtcNow, UpdatedAt = DateTime.UtcNow }; _db.AmtPendingDevices_new.Add(device); await _db.SaveChangesAsync(); return Ok(ApiResponse.Success(device, "添加成功")); } /// /// 批量添加设备 /// [HttpPost("batch")] public async Task BatchAddDevices([FromBody] List requests) { var added = 0; var skipped = 0; foreach (var request in requests) { var existing = await _db.AmtPendingDevices_new .FirstOrDefaultAsync(d => d.IpAddress == request.IpAddress); if (existing != null) { skipped++; continue; } var device = new AmtPendingDevice_new { IpAddress = request.IpAddress, SubnetMask = request.SubnetMask, Gateway = request.Gateway, AmtUsername = request.AmtUsername, AmtPassword = request.AmtPassword, Source = "manual", CreatedAt = DateTime.UtcNow, UpdatedAt = DateTime.UtcNow }; _db.AmtPendingDevices_new.Add(device); added++; } await _db.SaveChangesAsync(); return Ok(ApiResponse.Success(new { added, skipped }, $"成功添加 {added} 个设备,跳过 {skipped} 个已存在的设备")); } /// /// 更新设备凭据 /// [HttpPut("{id}/credentials")] public async Task UpdateCredentials(int id, [FromBody] UpdateCredentialsRequest request) { var device = await _db.AmtPendingDevices_new.FindAsync(id); if (device == null) { return NotFound(ApiResponse.Fail(404, "设备不存在")); } device.AmtUsername = request.AmtUsername; device.AmtPassword = request.AmtPassword; device.UpdatedAt = DateTime.UtcNow; await _db.SaveChangesAsync(); return Ok(ApiResponse.Success(device, "凭据更新成功")); } /// /// 批量更新设备凭据 /// [HttpPut("batch-credentials")] public async Task BatchUpdateCredentials([FromBody] BatchUpdateCredentialsRequest request) { var devices = await _db.AmtPendingDevices_new .Where(d => request.DeviceIds.Contains(d.Id)) .ToListAsync(); foreach (var device in devices) { device.AmtUsername = request.AmtUsername; device.AmtPassword = request.AmtPassword; device.UpdatedAt = DateTime.UtcNow; } await _db.SaveChangesAsync(); return Ok(ApiResponse.Success(null, $"已更新 {devices.Count} 个设备的凭据")); } /// /// 接管设备(获取UUID并移动到正式表) /// [HttpPost("{id}/takeover")] public async Task TakeoverDevice(int id) { var pendingDevice = await _db.AmtPendingDevices_new.FindAsync(id); if (pendingDevice == null) { return NotFound(ApiResponse.Fail(404, "设备不存在")); } if (string.IsNullOrEmpty(pendingDevice.AmtUsername) || string.IsNullOrEmpty(pendingDevice.AmtPassword)) { return BadRequest(ApiResponse.Fail(400, "请先配置AMT凭据")); } // 获取UUID var uuid = await _wsmanService.GetUuidAsync( pendingDevice.IpAddress, pendingDevice.AmtUsername, pendingDevice.AmtPassword); if (string.IsNullOrEmpty(uuid)) { return BadRequest(ApiResponse.Fail(400, "无法获取设备UUID,请检查凭据是否正确")); } // 检查UUID是否已存在 var existingDevice = await _db.AmtDevices_new.FindAsync(uuid); if (existingDevice != null) { // 更新已存在的设备 existingDevice.IpAddress = pendingDevice.IpAddress; existingDevice.SubnetMask = pendingDevice.SubnetMask; existingDevice.Gateway = pendingDevice.Gateway; existingDevice.AmtUsername = pendingDevice.AmtUsername; existingDevice.AmtPassword = pendingDevice.AmtPassword; existingDevice.AmtVersion = pendingDevice.AmtVersion; existingDevice.UpdatedAt = DateTime.UtcNow; } else { // 创建新设备 var newDevice = new AmtDevice_new { Uuid = uuid, IpAddress = pendingDevice.IpAddress, SubnetMask = pendingDevice.SubnetMask, Gateway = pendingDevice.Gateway, AmtUsername = pendingDevice.AmtUsername, AmtPassword = pendingDevice.AmtPassword, AmtVersion = pendingDevice.AmtVersion, CreatedAt = DateTime.UtcNow, UpdatedAt = DateTime.UtcNow }; _db.AmtDevices_new.Add(newDevice); } // 标记待接管设备为已接管 pendingDevice.IsTakenOver = true; pendingDevice.UpdatedAt = DateTime.UtcNow; await _db.SaveChangesAsync(); return Ok(ApiResponse.Success(new { uuid }, "设备接管成功")); } /// /// 批量接管设备 /// [HttpPost("batch-takeover")] public async Task BatchTakeover([FromBody] BatchTakeoverRequest request) { var results = new List(); var devices = await _db.AmtPendingDevices_new .Where(d => request.DeviceIds.Contains(d.Id) && !d.IsTakenOver) .ToListAsync(); foreach (var device in devices) { var result = new TakeoverResult { DeviceId = device.Id, IpAddress = device.IpAddress }; if (string.IsNullOrEmpty(device.AmtUsername) || string.IsNullOrEmpty(device.AmtPassword)) { result.Success = false; result.Message = "未配置凭据"; results.Add(result); continue; } try { var uuid = await _wsmanService.GetUuidAsync(device.IpAddress, device.AmtUsername, device.AmtPassword); if (string.IsNullOrEmpty(uuid)) { result.Success = false; result.Message = "无法获取UUID"; results.Add(result); continue; } // 检查UUID是否已存在 var existingDevice = await _db.AmtDevices_new.FindAsync(uuid); if (existingDevice != null) { existingDevice.IpAddress = device.IpAddress; existingDevice.SubnetMask = device.SubnetMask; existingDevice.Gateway = device.Gateway; existingDevice.AmtUsername = device.AmtUsername; existingDevice.AmtPassword = device.AmtPassword; existingDevice.AmtVersion = device.AmtVersion; existingDevice.UpdatedAt = DateTime.UtcNow; } else { var newDevice = new AmtDevice_new { Uuid = uuid, IpAddress = device.IpAddress, SubnetMask = device.SubnetMask, Gateway = device.Gateway, AmtUsername = device.AmtUsername, AmtPassword = device.AmtPassword, AmtVersion = device.AmtVersion, CreatedAt = DateTime.UtcNow, UpdatedAt = DateTime.UtcNow }; _db.AmtDevices_new.Add(newDevice); } device.IsTakenOver = true; device.UpdatedAt = DateTime.UtcNow; result.Success = true; result.Uuid = uuid; result.Message = "接管成功"; } catch (Exception ex) { result.Success = false; result.Message = ex.Message; _logger.LogError(ex, "接管设备 {Ip} 失败", device.IpAddress); } results.Add(result); } await _db.SaveChangesAsync(); var successCount = results.Count(r => r.Success); var failCount = results.Count(r => !r.Success); return Ok(ApiResponse.Success(new { results, successCount, failCount })); } /// /// 删除待接管设备 /// [HttpDelete("{id}")] public async Task DeleteDevice(int id) { var device = await _db.AmtPendingDevices_new.FindAsync(id); if (device == null) { return NotFound(ApiResponse.Fail(404, "设备不存在")); } _db.AmtPendingDevices_new.Remove(device); await _db.SaveChangesAsync(); return Ok(ApiResponse.Success(null, "删除成功")); } } public class AddPendingDeviceRequest { public string IpAddress { get; set; } = string.Empty; public string? SubnetMask { get; set; } public string? Gateway { get; set; } public string? AmtUsername { get; set; } public string? AmtPassword { get; set; } } public class UpdateCredentialsRequest { public string AmtUsername { get; set; } = string.Empty; public string AmtPassword { get; set; } = string.Empty; } public class BatchUpdateCredentialsRequest { public List DeviceIds { get; set; } = new(); public string AmtUsername { get; set; } = string.Empty; public string AmtPassword { get; set; } = string.Empty; } public class BatchTakeoverRequest { public List DeviceIds { get; set; } = new(); } public class TakeoverResult { public int DeviceId { get; set; } public string IpAddress { get; set; } = string.Empty; public bool Success { get; set; } public string? Uuid { get; set; } public string? Message { get; set; } }