diff --git a/Model/Services/SOCClientService.cs b/Model/Services/SOCClientService.cs index dffd822..85436fe 100644 --- a/Model/Services/SOCClientService.cs +++ b/Model/Services/SOCClientService.cs @@ -1,23 +1,62 @@ 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; namespace SparkClient.Model.Services { + /// + /// SOC 客户端服务类,用于与远程服务器进行交互,包括启动图片收集任务、获取图片、获取采集状态等操作。 + /// public class SOCClientService { + // Log地址 + private const string LogFilePath = @"..\..\..\Resource\Document\log.txt"; + // Log格式 + private const string LogMessageFormat = "[{0:yyyy-MM-dd HH:mm:ss.fff}] 发生异常: {1}{2}"; + + 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请求方法 + /// + /// 发送GET请求的通用方法。 + /// + /// 请求的完整URL + /// HTTP响应 private async Task SendGetRequestAsync(string url) { using (var client = new HttpClient()) @@ -27,7 +66,11 @@ namespace SparkClient.Model.Services } } - // 1. 启动图片收集任务 + /// + /// 启动图片收集任务。 + /// + /// 光照级别 + /// 任务状态 public async Task CollectImagesAsync(int lightLevel) { string url = $"{_baseUrl}/collect_images?light_level={lightLevel}"; @@ -41,27 +84,55 @@ namespace SparkClient.Model.Services } else { - return "Error: " + response.StatusCode; + return "collect_images_Error: " + (int)response.StatusCode; } } - // 2. 获取图片 - public async Task RetrieveImageAsync(int index) + /// + /// 获取指定索引的图片。 + /// + /// 图片索引 + /// 图片的字节数组 + public async Task> RetrieveImageAsync(string savePath) { - string url = $"{_baseUrl}/retrieve_image/{index}"; - var response = await SendGetRequestAsync(url); - - if (response.IsSuccessStatusCode) - { - return await response.Content.ReadAsByteArrayAsync(); - } - else + List imageNames = new List(); + // 读取图片接口 + int imageIndex = 0; + while (true) { - throw new Exception("Error retrieving image: " + response.StatusCode); + 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; + } } } - // 3. 获取采集状态 + /// + /// 获取图片采集状态。 + /// + /// 采集状态 public async Task CollectStatusAsync() { string url = $"{_baseUrl}/collect_status"; @@ -75,14 +146,95 @@ namespace SparkClient.Model.Services } else { - return "Error: " + response.StatusCode; + 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 != "S000") + { + // 启动任务失败 + return JsonConvert.SerializeObject(new { status = startStatus, images = new List() }); + } + + // 读取图片接口 + List imageNames = await RetrieveImageAsync(savePath); + if (imageNames.Count != 0) + { + // 采集状态接口 + string acquisitionStatus = await CollectStatusAsync(); + if (acquisitionStatus != "S000") + { + // 采集状态失败 + return JsonConvert.SerializeObject(new { status = acquisitionStatus, images = new List() }); + + } + } + // 按下载时间排序图片名称 + return JsonConvert.SerializeObject(new { status = "S000", 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 JsonConvert.SerializeObject(new { status = "P001", 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; } } } diff --git a/Model/Services/StatusCodes.cs b/Model/Services/StatusCodes.cs new file mode 100644 index 0000000..f7209bd --- /dev/null +++ b/Model/Services/StatusCodes.cs @@ -0,0 +1,32 @@ +namespace SparkClient.Model.Common +{ + /// + /// 存储状态码及其描述信息的常量类。 + /// + public static class StatusCodes + { + // 成功 + public const string S000 = "S000"; + + // 采图正在进行中 + public const string S001 = "S001"; + + // 缓存图片被清理(读取不够及时) + public const string S002 = "S002"; + + // 无法向单片机发送指令 + public const string S003 = "S003"; + + // 单片机访问超时 + public const string S004 = "S004"; + + // 单片机返回错误码 + public const string S005 = "S005"; + + // 未找到切工仪 + public const string P001 = "P001"; + + // 算法调用失败 + public const string P002 = "P002"; + } +} \ No newline at end of file diff --git a/Resource/Document/log.txt b/Resource/Document/log.txt new file mode 100644 index 0000000..ea7f075 --- /dev/null +++ b/Resource/Document/log.txt @@ -0,0 +1,7 @@ +[2024-12-05 16:21:22.627] 发生异常: 由于目标计算机积极拒绝,无法连接。 (localhost:5000) +[2024-12-05 16:42:38.854] 发生异常: 由于目标计算机积极拒绝,无法连接。 (localhost:5000) +[2024-12-05 16:42:49.827] 发生异常: 由于目标计算机积极拒绝,无法连接。 (localhost:5000) +[2024-12-05 16:50:48.304] 发生异常: 由于目标计算机积极拒绝,无法连接。 (localhost:5000) +[2024-12-05 16:50:56.037] 发生异常: 由于目标计算机积极拒绝,无法连接。 (localhost:5000) +[2024-12-05 16:51:04.013] 发生异常: 由于目标计算机积极拒绝,无法连接。 (localhost:5000) +[2024-12-05 16:58:31.184] 发生异常: 由于目标计算机积极拒绝,无法连接。 (localhost:5000) diff --git a/SparkClient.csproj b/SparkClient.csproj index fd168fe..afdda84 100644 --- a/SparkClient.csproj +++ b/SparkClient.csproj @@ -30,6 +30,9 @@ Always + + PreserveNewest + @@ -100,4 +103,9 @@ + + + + + diff --git a/SparkClient.sln.DotSettings.user b/SparkClient.sln.DotSettings.user index 15908bb..f3fef9c 100644 --- a/SparkClient.sln.DotSettings.user +++ b/SparkClient.sln.DotSettings.user @@ -7,6 +7,8 @@ ForceIncluded ForceIncluded ForceIncluded + ForceIncluded + ForceIncluded ForceIncluded ForceIncluded ForceIncluded