using Newtonsoft.Json; using Newtonsoft.Json.Linq; using SWS.CAD.Models; using SWS.CAD.Models.NoEntity; using SWS.Commons; using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Net; using System.Net.Http; using System.Security.Policy; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Web; namespace SWS.CAD.Services { public class AnnexesService : HttpService { public AnnexesService() : base() { } /// /// 查询文件实体 /// /// public async Task GetAnnexesFile(string folderId) { var res = await this.GetAsync($"AnnexesApi/GetFileEntity?projectId={GlobalObject.curProject.ProjectId}&folderId={folderId}"); if (res.code == 200) { return res.data; } else { return null;//ERROR INFO } } /// /// 上传本地文件到server /// /// 完整的路径 /// 带后缀 /// 返回新的一个folder ID public async Task UploadFile(string fullFilePath, string fileName) { using (var stream = new FileStream(fullFilePath, FileMode.Open, FileAccess.Read)) { var res = await this.PostFileAsync($"AnnexesApi/UploadFile", stream, fileName); return res;//new Folder Id } } /// /// 下载文件 /// /// 文件下载地址 /// 本地保存路径 /// 进度报告接口(可选) /// 取消令牌(可选) /// 返回空字符串认为是OK的 public async Task DownloadFile( string savePath, string fileId, IProgress progress = null, CancellationToken cancellationToken = default) { try { var p = Path.GetDirectoryName(savePath); if (!Directory.Exists(p)) Directory.CreateDirectory(p); string url = $"AnnexesApi/DownFile?fileId={fileId}"; // 发送请求并获取响应 using (var response = await GlobalObject.client.GetAsync( url, HttpCompletionOption.ResponseHeadersRead, cancellationToken)) { if (response.StatusCode != HttpStatusCode.OK) { string errorMsg = $"服务器地址 [{url}] 文件下载失败, 返回HTTP代码:" + response.StatusCode; LoggerHelper.Current.Error(errorMsg); throw new HttpRequestException(errorMsg); } response.EnsureSuccessStatusCode(); // 确保响应成功 var result = await response.Content.ReadAsStringAsync(); learunHttpRes resultObj = null; try { resultObj = JsonConvert.DeserializeObject>(result); } catch (JsonException) { //对下载文件来说,如果正常的话,这里反而是合理的,因为返回的就是stream的东西,不能被解析为learunHttpRes await HandleStreamAsync(); return ""; } if (resultObj.code != 200) { switch (resultObj.code) { case 400: case 500: return resultObj.info.ToString(); //业务错误,不是http本质错误 default: string errorMsg = $"服务器地址 [{url}] Get失败, 返回自定义代码:" + resultObj.code; LoggerHelper.Current.Error(errorMsg); throw new HttpRequestException(errorMsg); } } else { await HandleStreamAsync(); return ""; } async Task HandleStreamAsync() { #region core // 获取文件总大小(可能为 null) var totalBytes = response.Content.Headers.ContentLength; // 创建文件流 using (var contentStream = await response.Content.ReadAsStreamAsync()) using (var fileStream = new FileStream( savePath, FileMode.Create, FileAccess.Write, FileShare.None, bufferSize: 8192, useAsync: true)) { var buffer = new byte[8192]; var totalBytesRead = 0L; var bytesRead = 0; // 分块读取并写入文件 while ((bytesRead = await contentStream.ReadAsync( buffer, 0, buffer.Length, cancellationToken)) > 0) { await fileStream.WriteAsync( buffer, 0, bytesRead, cancellationToken); totalBytesRead += bytesRead; // 报告进度(如果有总大小) if (totalBytes.HasValue) { var percent = (double)totalBytesRead / totalBytes.Value * 100; progress?.Report(percent); } } } #endregion } } } catch (HttpRequestException ex) { return ex.Message; //throw new Exception($"下载请求失败: {ex.Message}"); } catch (TaskCanceledException ex2) { return ex2.Message; // 取消操作时删除已下载的部分文件 //if (File.Exists(savePath)) File.Delete(savePath); //throw; } catch (Exception ex3) { return ex3.Message; //throw new Exception($"下载失败: {ex.Message}"); } } } }