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; } } }