382 lines
13 KiB
C#
382 lines
13 KiB
C#
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; }
|
||
}
|