2025-12-26 03:18:21 +08:00
|
|
|
|
using Microsoft.AspNetCore.Http;
|
|
|
|
|
|
using Microsoft.AspNetCore.Mvc;
|
|
|
|
|
|
|
|
|
|
|
|
namespace SHH.CameraSdk;
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 视频源实时状态监控 API 控制器
|
|
|
|
|
|
/// 核心功能:提供相机设备遥测数据查询、单设备详情查询、设备截图获取接口
|
|
|
|
|
|
/// 适用场景:Web 监控大屏、移动端状态查询、第三方系统集成
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
[ApiController]
|
|
|
|
|
|
[Route("api/[controller]")]
|
|
|
|
|
|
public class MonitorController : ControllerBase
|
|
|
|
|
|
{
|
|
|
|
|
|
#region --- 依赖注入 (Dependency Injection) ---
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary> 相机管理器实例:提供设备状态与遥测数据访问能力 </summary>
|
|
|
|
|
|
private readonly CameraManager _cameraManager;
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 构造函数:通过依赖注入获取 CameraManager 实例
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="cameraManager">相机管理器</param>
|
|
|
|
|
|
public MonitorController(CameraManager cameraManager)
|
|
|
|
|
|
{
|
|
|
|
|
|
_cameraManager = cameraManager;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
|
|
#region --- API 接口定义 (API Endpoints) ---
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 获取全量相机实时遥测数据快照(支持跨域)
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <remarks>
|
|
|
|
|
|
/// 返回数据包含:设备ID、名称、IP地址、运行状态、在线状态、实时FPS、累计帧数、健康度评分、最后错误信息
|
|
|
|
|
|
/// 适用场景:监控大屏首页数据看板
|
|
|
|
|
|
/// [cite: 191, 194]
|
|
|
|
|
|
/// </remarks>
|
|
|
|
|
|
/// <returns>200 OK + 遥测数据列表</returns>
|
|
|
|
|
|
[HttpGet("dashboard")]
|
|
|
|
|
|
public IActionResult GetDashboard()
|
|
|
|
|
|
{
|
|
|
|
|
|
var telemetrySnapshot = _cameraManager.GetTelemetrySnapshot();
|
|
|
|
|
|
return Ok(telemetrySnapshot);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 获取指定相机的详细运行指标
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="id">相机设备唯一标识</param>
|
|
|
|
|
|
/// <returns>200 OK + 设备详情 | 404 Not Found</returns>
|
|
|
|
|
|
[HttpGet("{id}")]
|
|
|
|
|
|
public IActionResult GetDeviceDetail(long id)
|
|
|
|
|
|
{
|
|
|
|
|
|
// 查询指定设备
|
|
|
|
|
|
var device = _cameraManager.GetDevice(id);
|
|
|
|
|
|
// 设备不存在返回 404
|
|
|
|
|
|
if (device == null) return NotFound($"设备 ID: {id} 不存在");
|
|
|
|
|
|
|
|
|
|
|
|
// 构造设备详情返回对象
|
|
|
|
|
|
var deviceDetail = new
|
|
|
|
|
|
{
|
|
|
|
|
|
device.Id,
|
|
|
|
|
|
device.Status,
|
|
|
|
|
|
device.IsOnline,
|
|
|
|
|
|
device.RealFps,
|
|
|
|
|
|
device.TotalFrames,
|
|
|
|
|
|
device.Config.Name,
|
|
|
|
|
|
device.Config.IpAddress
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
return Ok(deviceDetail);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 获取指定相机的实时截图
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="id">相机设备唯一标识</param>
|
|
|
|
|
|
/// <returns>200 OK + JPEG 图片流 | 504 Gateway Timeout</returns>
|
|
|
|
|
|
[HttpGet("snapshot/{id}")]
|
|
|
|
|
|
public async Task<IActionResult> GetSnapshot(long id)
|
|
|
|
|
|
{
|
|
|
|
|
|
// 调用截图协调器获取实时截图,设置 2 秒超时
|
|
|
|
|
|
// 超时保护:避免 HTTP 线程因设备异常长时间挂起
|
|
|
|
|
|
var imageBytes = await SnapshotCoordinator.Instance.RequestSnapshotAsync(id, 2000);
|
|
|
|
|
|
|
|
|
|
|
|
// 截图超时或设备无响应,返回 504 超时状态码
|
|
|
|
|
|
if (imageBytes == null)
|
|
|
|
|
|
{
|
|
|
|
|
|
return StatusCode(StatusCodes.Status504GatewayTimeout, "截图请求超时或设备未响应");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 返回 JPEG 格式图片流,支持浏览器直接预览
|
|
|
|
|
|
return File(imageBytes, "image/jpeg");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-12-26 12:15:10 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 获取指定相机的诊断信息(含审计日志)
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="id">相机设备唯一标识</param>
|
|
|
|
|
|
/// <returns>200 OK + 诊断信息 | 404 Not Found</returns>
|
|
|
|
|
|
[HttpGet("diagnose/{id}")]
|
|
|
|
|
|
public IActionResult GetDeviceDiagnostic(long id)
|
|
|
|
|
|
{
|
|
|
|
|
|
var device = _cameraManager.GetDevice(id);
|
|
|
|
|
|
if (device == null) return NotFound();
|
|
|
|
|
|
|
|
|
|
|
|
return Ok(new
|
|
|
|
|
|
{
|
|
|
|
|
|
Id = device.Id,
|
|
|
|
|
|
Status = device.Status.ToString(),
|
|
|
|
|
|
RealFps = device.RealFps,
|
|
|
|
|
|
TotalFrames = device.TotalFrames,
|
|
|
|
|
|
// 关键:将 BaseVideoSource 中的日志列表返回给前端
|
|
|
|
|
|
// 注意:属性名 AuditLogs 会被序列化为 auditLogs (首字母小写),符合前端预期
|
|
|
|
|
|
AuditLogs = device.GetAuditLogs()
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-12-26 03:18:21 +08:00
|
|
|
|
#endregion
|
|
|
|
|
|
}
|