using Newtonsoft.Json;
using System;
using System.IO;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using HandyControl.Tools.Extension;
using SparkClient.Model.Common;
using SparkClient.Model.Entity.ApiEntity;
namespace SparkClient.Model.Services
{
///
/// SOC 客户端服务类,用于与远程服务器进行交互,包括启动图片收集任务、获取图片、获取采集状态等操作。
///
public class SOCClientService
{
// Log地址
private const string LogFilePath = @"..\..\..\Resource\Document\log.txt";
private static readonly Dictionary StatusDescriptions = new Dictionary
{
{ "S000", "成功" },
{ "S001", "采图正在进行中" },
{ "S002", "缓存图片被清理(读取不够及时)" },
{ "S003", "无法向单片机发送指令" },
{ "S004", "单片机访问超时" },
{ "S005", "单片机返回错误码" },
{ "P001", "未找到切工仪" },
{ "P002", "算法调用失败" }
};
///
/// 基础URL,用于构建完整的API请求地址。
///
private readonly string _baseUrl;
///
/// 认证令牌,用于HTTP请求的认证。
///
private readonly string _authToken;
///
/// 构造函数,初始化基础URL和认证令牌。
///
/// 基础URL
/// 认证令牌
public SOCClientService(string baseUrl, string authToken)
{
_baseUrl = baseUrl;
_authToken = authToken;
}
///
/// 发送GET请求的通用方法。
///
/// 请求的完整URL
/// HTTP响应
private async Task SendGetRequestAsync(string url)
{
using (var client = new HttpClient())
{
client.DefaultRequestHeaders.Add("Authorization", "Basic " + _authToken);
return await client.GetAsync(url);
}
}
///
/// 启动图片收集任务。
///
/// 光照级别
/// 任务状态
public async Task CollectImagesAsync(int lightLevel)
{
string url = $"{_baseUrl}/collect_images?light_level={lightLevel}";
var response = await SendGetRequestAsync(url);
if (response.IsSuccessStatusCode)
{
var jsonResponse = await response.Content.ReadAsStringAsync();
var result = JsonConvert.DeserializeObject(jsonResponse);
return result.Status;
}
else
{
return "collect_images_Error: " + (int)response.StatusCode;
}
}
///
/// 获取指定索引的图片。
///
/// 图片索引
/// 图片的字节数组
public async Task> RetrieveImageAsync(string savePath)
{
List imageNames = new List();
// 读取图片接口
int imageIndex = 0;
while (true)
{
string url = $"{_baseUrl}/retrieve_image/{imageIndex}";
var response = await SendGetRequestAsync(url);
int status = (int)response.StatusCode;
if (status == 200)
{
byte[] imageBytes = await response.Content.ReadAsByteArrayAsync();
string fileName = Path.Combine(savePath, $"image_{imageIndex}.bmp");
// 图片名称List
imageNames.Add(Path.GetFileName(fileName));
// 保存图片
await File.WriteAllBytesAsync(fileName, imageBytes);
imageIndex++;
}
else if (status == 425)
{
await Task.Delay(1000);
}
else if (status == 410)
{
imageIndex++;
}
else if (status == 404)
{
return imageNames;
}
}
}
///
/// 获取图片采集状态。
///
/// 采集状态
public async Task CollectStatusAsync()
{
string url = $"{_baseUrl}/collect_status";
var response = await SendGetRequestAsync(url);
if (response.IsSuccessStatusCode)
{
var jsonResponse = await response.Content.ReadAsStringAsync();
var result = JsonConvert.DeserializeObject(jsonResponse);
return result.Status;
}
else
{
return "collect_status_Error: " + (int)response.StatusCode;
}
}
///
/// 处理图片收集、保存和状态检查。
///
/// 光照级别
/// 图片保存路径
/// 操作结果
public async Task ProcessImageCollectionAsync(int lightLevel, string savePath)
{
try
{
// 清理 savePath 文件夹
if (Directory.Exists(savePath))
{
Directory.Delete(savePath, true);
}
Directory.CreateDirectory(savePath);
// 启动任务接口
string startStatus = await CollectImagesAsync(lightLevel);
// 成功
if (startStatus != StatusCodes.Success)
{
// 启动任务失败
return new SocResultEntity { Status = startStatus, Images = new List() };
}
// 读取图片接口
List imageNames = await RetrieveImageAsync(savePath);
if (imageNames.Count != 0)
{
// 采集状态接口
string acquisitionStatus = await CollectStatusAsync();
// 成功
if (acquisitionStatus != StatusCodes.Success)
{
// 采集状态失败
return new SocResultEntity { Status = acquisitionStatus, Images = new List() };
}
}
// 按下载时间排序图片名称
return new SocResultEntity { Status = StatusCodes.Success, Images = imageNames };
}
catch (Exception e)
{
// 日志记录
// logger.Error(e, "发生异常");
string logMessage = $"[{DateTime.Now:yyyy-MM-dd HH:mm:ss.fff}] 发生异常: {e.Message}{Environment.NewLine}";
File.AppendAllText(LogFilePath, logMessage);
return new SocResultEntity { Status = StatusCodes.DeviceNotFound, Images = new List() };
}
}
///
/// 根据状态码获取相应的描述信息。
/// 如果状态码在预定义的状态字典中存在,则返回对应的描述信息;
/// 否则返回“未知状态: [状态码]”。
///
/// 状态码。
/// 状态描述信息。
private string GetDescription(string status)
{
if (StatusDescriptions.TryGetValue(status, out string description))
{
return description;
}
return "未知状态: " + status;
}
}
///
/// 响应状态类,用于解析服务器返回的状态信息。
///
public class ResponseStatus
{
///
/// 状态码
///
public string Status { get; set; }
///
/// 状态消息
///
public string Message { get; set; }
}
}