serverRoom/backend-csharp/AmtScanner.Api/Controllers/AmtPendingDevicesController.cs

382 lines
13 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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<AmtPendingDevicesController> _logger;
public AmtPendingDevicesController(AppDbContext db, IAmtWsmanService wsmanService, ILogger<AmtPendingDevicesController> logger)
{
_db = db;
_wsmanService = wsmanService;
_logger = logger;
}
/// <summary>
/// 获取待接管设备列表
/// </summary>
[HttpGet]
public async Task<IActionResult> 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<object>.Success(new { items, total, page, pageSize }));
}
/// <summary>
/// 手动添加设备
/// </summary>
[HttpPost]
public async Task<IActionResult> AddDevice([FromBody] AddPendingDeviceRequest request)
{
// 检查IP是否已存在
var existing = await _db.AmtPendingDevices_new
.FirstOrDefaultAsync(d => d.IpAddress == request.IpAddress);
if (existing != null)
{
return BadRequest(ApiResponse<object>.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<object>.Success(device, "添加成功"));
}
/// <summary>
/// 批量添加设备
/// </summary>
[HttpPost("batch")]
public async Task<IActionResult> BatchAddDevices([FromBody] List<AddPendingDeviceRequest> 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<object>.Success(new { added, skipped }, $"成功添加 {added} 个设备,跳过 {skipped} 个已存在的设备"));
}
/// <summary>
/// 更新设备凭据
/// </summary>
[HttpPut("{id}/credentials")]
public async Task<IActionResult> UpdateCredentials(int id, [FromBody] UpdateCredentialsRequest request)
{
var device = await _db.AmtPendingDevices_new.FindAsync(id);
if (device == null)
{
return NotFound(ApiResponse<object>.Fail(404, "设备不存在"));
}
device.AmtUsername = request.AmtUsername;
device.AmtPassword = request.AmtPassword;
device.UpdatedAt = DateTime.UtcNow;
await _db.SaveChangesAsync();
return Ok(ApiResponse<object>.Success(device, "凭据更新成功"));
}
/// <summary>
/// 批量更新设备凭据
/// </summary>
[HttpPut("batch-credentials")]
public async Task<IActionResult> 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<object>.Success(null, $"已更新 {devices.Count} 个设备的凭据"));
}
/// <summary>
/// 接管设备获取UUID并移动到正式表
/// </summary>
[HttpPost("{id}/takeover")]
public async Task<IActionResult> TakeoverDevice(int id)
{
var pendingDevice = await _db.AmtPendingDevices_new.FindAsync(id);
if (pendingDevice == null)
{
return NotFound(ApiResponse<object>.Fail(404, "设备不存在"));
}
if (string.IsNullOrEmpty(pendingDevice.AmtUsername) || string.IsNullOrEmpty(pendingDevice.AmtPassword))
{
return BadRequest(ApiResponse<object>.Fail(400, "请先配置AMT凭据"));
}
// 获取UUID
var uuid = await _wsmanService.GetUuidAsync(
pendingDevice.IpAddress,
pendingDevice.AmtUsername,
pendingDevice.AmtPassword);
if (string.IsNullOrEmpty(uuid))
{
return BadRequest(ApiResponse<object>.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<object>.Success(new { uuid }, "设备接管成功"));
}
/// <summary>
/// 批量接管设备
/// </summary>
[HttpPost("batch-takeover")]
public async Task<IActionResult> BatchTakeover([FromBody] BatchTakeoverRequest request)
{
var results = new List<TakeoverResult>();
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<object>.Success(new { results, successCount, failCount }));
}
/// <summary>
/// 删除待接管设备
/// </summary>
[HttpDelete("{id}")]
public async Task<IActionResult> DeleteDevice(int id)
{
var device = await _db.AmtPendingDevices_new.FindAsync(id);
if (device == null)
{
return NotFound(ApiResponse<object>.Fail(404, "设备不存在"));
}
_db.AmtPendingDevices_new.Remove(device);
await _db.SaveChangesAsync();
return Ok(ApiResponse<object>.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<int> DeviceIds { get; set; } = new();
public string AmtUsername { get; set; } = string.Empty;
public string AmtPassword { get; set; } = string.Empty;
}
public class BatchTakeoverRequest
{
public List<int> 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; }
}