This commit is contained in:
2026-03-30 11:07:30 +08:00
parent 2c44b3a4b2
commit d4a8e71733
74 changed files with 1751 additions and 421 deletions

View File

@@ -1,4 +1,9 @@
using Microsoft.AspNetCore.Hosting;
using System.Net.Http.Headers;
using System.Net.Http.Json;
using System.Text.Json;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using StopShopping.Services.Extensions;
using StopShopping.Services.Models;
@@ -9,50 +14,66 @@ namespace StopShopping.Services.Implementions;
public class FileService : IFileService
{
public FileService(IOptions<AppOptions> appOptions,
IWebHostEnvironment webHostEnvironment)
public FileService(
IHttpClientFactory httpClientFactory,
IOptions<AppOptions> options,
ILogger<FileService> logger)
{
_appOptions = appOptions.Value;
_env = webHostEnvironment;
_fileClient = httpClientFactory.CreateClient(Consts.FILE_API_CLIENT_NAME);
_options = options.Value;
_logger = logger;
}
private readonly AppOptions _appOptions;
private readonly IWebHostEnvironment _env;
private readonly HttpClient _fileClient;
private readonly AppOptions _options;
private readonly ILogger<FileService> _logger;
public async Task<ApiResponse<FileUpload>> UploadFileAsync(UploadParams payload)
private const string UPLOAD_PATH = "/upload";
public async Task<ApiResponse<FileUploadResp>> UploadFileAsync(UploadParams payload)
{
var newName = Guid.NewGuid().ToString("N").ToLower();
var extension = Path.GetExtension(payload.File!.FileName);
var newFullName = $"{newName}{extension}";
var relativeToRootPath = GetRelativeToRootPath(payload.Scences, newFullName);
var targetPath = Path.Combine(_env.WebRootPath, GetRelativeToRootPath(payload.Scences));
if (!Directory.Exists(targetPath))
try
{
Directory.CreateDirectory(targetPath);
var formData = new MultipartFormDataContent
{
{ new StringContent(((int)payload.Scences).ToString()), nameof(payload.Scences) },
};
var fileContent = new StreamContent(payload.File!.OpenReadStream());
fileContent.Headers.ContentType = new MediaTypeHeaderValue(payload.File.ContentType);
formData.Add(fileContent, nameof(payload.File), payload.File.FileName);
var resp = await _fileClient.PostAsync(UPLOAD_PATH, formData);
if (resp.IsSuccessStatusCode)
{
var deserialized = await resp.Content.ReadFromJsonAsync<ApiResponse<FileUploadResp>>();
if (null == deserialized)
throw new JsonException("上传失败");
return deserialized;
}
else
{
var deserialized = await resp.Content.ReadFromJsonAsync<ProblemDetails>();
if (null == deserialized)
throw new BadHttpRequestException("上传失败", (int)resp.StatusCode);
throw new BadHttpRequestException(
deserialized.Title ?? deserialized.Detail ?? "上传失败",
deserialized.Status ?? StatusCodes.Status400BadRequest);
}
}
using var file = new FileStream(
Path.Combine(_env.WebRootPath, relativeToRootPath),
FileMode.CreateNew,
FileAccess.Write);
await payload.File.CopyToAsync(file);
FileUpload result = new()
catch (Exception e)
{
NewName = newFullName,
Url = GetFileUrl(payload.Scences, newFullName)
};
return new ApiResponse<FileUpload>(result);
_logger.LogError(e, "上传失败");
throw;
}
}
public string GetFileUrl(UploadScences scences, string fileName)
{
var relativeToRootPath = GetRelativeToRootPath(scences, fileName);
return $"{_appOptions.DomainPath}/{relativeToRootPath.Replace(Path.DirectorySeparatorChar, '/')}";
return string.IsNullOrWhiteSpace(fileName)
? ""
: $"{_options.FileApiDomain}/{GetRelativeToRootPath(scences, fileName)
.Replace(Path.DirectorySeparatorChar, '/')}";
}
private string GetRelativeToRootPath(UploadScences scences, string fileName = "")