Files
Ayay/SHH.CameraDashboard/Services/WebApis/CameraReps/CameraRepository.cs
2026-01-01 22:40:32 +08:00

106 lines
5.2 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.
namespace SHH.CameraDashboard;
public partial class CameraRepository
{
#region GetListByAddressAsync
/// <summary>
/// [新增] 动态检测方法。
/// 专门用于向导界面,根据临时输入的 IP 地址和端口号来获取摄像头列表。
/// </summary>
/// <param name="ipAddress">目标服务器的 IP 地址。</param>
/// <param name="port">目标服务器的端口号。</param>
/// <param name="pageName">调用此方法的页面或步骤名称,用于日志记录。</param>
/// <returns>
/// 一个异步任务,其结果包含一个 <see cref="WebApiCameraModel"/> 对象的列表。
/// - 如果成功获取到列表,返回该列表(可能为空)。
/// - 如果获取过程中发生任何异常(如网络错误、服务器无响应等),返回 <c>null</c>。
/// </returns>
public async Task<List<WebApiCameraModel>?> GetListByAddressAsync(string ipAddress, string port, string pageName)
{
// 1. 统一管理并拼接请求 URL
// 在这里将基础地址与 API 路径组合ViewModel 无需关心具体的路由细节。
// WebApiRoutes.Cameras.Root 是一个假设的常量,例如 "/api/Cameras"。
string requestUrl = $"http://{ipAddress}:{port}{WebApiRoutes.Cameras.Root}";
try
{
// 2. 调用底层的 WebApiService 发送 GET 请求
// 传入 "Wizard" 相关的模块名,便于在日志中区分请求来源。
string jsonResponse = await WebApiService.Instance.GetAsync(requestUrl, moduleName: $"摄像头列表-{pageName}", default, true);
// 3. 使用 JsonHelper 进行反序列化
// 利用 JsonHelper 的防御性实现,即使 JSON 格式错误或内容为 "null",也不会抛出异常。
var cameraList = JsonHelper.Deserialize<List<WebApiCameraModel>>(jsonResponse);
// 4. 确保返回的列表不为 null
// 如果反序列化结果为 null例如API 返回 "null"),则返回一个空列表,
// 这样调用方可以安全地遍历,而无需进行 null 检查。
return cameraList ?? new List<WebApiCameraModel>();
}
catch (Exception)
{
// 5. 捕获所有异常
// 在动态检测阶段,网络不通、服务器宕机等都是预期内的情况。
// 返回 null 作为明确的失败信号ViewModel 可以据此向用户显示“连接失败”等提示。
return null;
}
}
#endregion
#region ControlPowerAsync
/// <summary>
/// 调用服务端的接口来控制指定摄像头的启停状态(开机/关机)。
/// </summary>
/// <param name="ipAddress">目标服务器的 IP 地址。</param>
/// <param name="port">目标服务器的端口号。</param>
/// <param name="cameraId">要控制的摄像头的唯一ID。</param>
/// <param name="enable">true 表示开机false 表示关机。</param>
/// <param name="pageName">调用此方法的页面或功能名称,用于日志记录。</param>
/// <returns>
/// 一个异步任务,其结果为一个布尔值:
/// - <c>true</c>表示操作成功HTTP 响应为 200 OK
/// - <c>false</c>:表示操作失败(如网络错误、服务器返回 4xx/5xx 错误等)。
/// </returns>
public async Task<bool> ControlPowerAsync(long cameraId, bool enable, string pageName)
{
var useServiceNode = AppGlobal.UseServiceNode;
if (useServiceNode == null)
return false;
var ipAddress = useServiceNode.ServiceNodeIp;
var port = useServiceNode.ServiceNodePort;
// 1. 拼接请求 URL
// 将控制参数cameraId 和 enable作为 URL 的一部分发送。
string requestUrl = $"http://{ipAddress}:{port}/api/Cameras/{cameraId}/power?enabled={enable}";
try
{
// 2. 调用底层服务发送 POST 请求
// 关键点:
// a. 即使服务端不关心请求体Body`PostAsync` 方法也要求一个非 null 的 JSON 字符串。
// 因此,我们传入一个空的 JSON 对象 "{}" 作为占位符。
// b. 我们不检查响应内容,因为如果请求失败(例如,服务器返回 404 Not Found 或 500 Internal Server Error
// `WebApiService` 会抛出异常。
await WebApiService.Instance.PostAsync(requestUrl, "{}", moduleName: $"设备启停-{pageName}");
// 3. 如果代码执行到这里,说明请求成功且没有抛出异常。
return true;
}
catch (Exception ex)
{
// 4. 捕获所有可能发生的异常
// 这包括网络连接问题、DNS解析失败、服务器无响应或返回错误状态码等。
// 记录异常信息到调试输出,以便于排查问题。
System.Diagnostics.Debug.WriteLine($"控制摄像头电源失败 [IP: {ipAddress}, CameraId: {cameraId}]: {ex.Message}");
// 返回 false 通知调用方操作已失败。
return false;
}
}
#endregion
}