198 lines
7.4 KiB
C#
Raw Normal View History

2025-08-15 16:34:31 +08:00
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using SWS.CAD.Helper;
using SWS.CAD.Models;
using SWS.CAD.Models.NoEntity;
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()
{
}
/// <summary>
/// 查询文件实体
/// </summary>
/// <returns></returns>
public async Task<annexesfile> GetAnnexesFile(string folderId)
{
var res = await this.GetAsync<annexesfile>($"AnnexesApi/GetFileEntity?projectId={GlobalObject.curProject.ProjectId}&folderId={folderId}");
if (res.code == 200)
{
return res.data;
}
else
{
return null;//ERROR INFO
}
}
/// <summary>
/// 上传本地文件到server
/// </summary>
/// <param name="fullFilePath">完整的路径</param>
/// <param name="fileName">带后缀</param>
/// <returns>返回新的一个folder ID</returns>
public async Task<string> UploadFile(string fullFilePath, string fileName)
{
using (var stream = new FileStream(fullFilePath, FileMode.Open, FileAccess.Read))
{
var res = await this.PostFileAsync<string>($"AnnexesApi/UploadFile", stream, fileName);
return res;//new Folder Id
}
}
/// <summary>
/// 下载文件
/// </summary>
/// <param name="url">文件下载地址</param>
/// <param name="savePath">本地保存路径</param>
/// <param name="progress">进度报告接口(可选)</param>
/// <param name="cancellationToken">取消令牌(可选)</param>
/// <returns>返回空字符串认为是OK的</returns>
public async Task<string> DownloadFile(
string savePath, string fileId,
IProgress<double> 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<object> resultObj = null;
try
{
resultObj = JsonConvert.DeserializeObject<learunHttpRes<object>>(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}");
}
}
}
}