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; using StopShopping.Services.Models.Req; using StopShopping.Services.Models.Resp; namespace StopShopping.Services.Implementions; public class FileService : IFileService { public FileService( IHttpClientFactory httpClientFactory, IOptions options, ILogger logger) { _fileClient = httpClientFactory.CreateClient(Consts.FILE_API_CLIENT_NAME); _options = options.Value; _logger = logger; } private readonly HttpClient _fileClient; private readonly AppOptions _options; private readonly ILogger _logger; private const string UPLOAD_PATH = "/upload"; public async Task> UploadFileAsync(UploadParams payload) { try { 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>(); if (null == deserialized) throw new JsonException("上传失败"); return deserialized; } else { var deserialized = await resp.Content.ReadFromJsonAsync(); if (null == deserialized) throw new BadHttpRequestException("上传失败", (int)resp.StatusCode); throw new BadHttpRequestException( deserialized.Title ?? deserialized.Detail ?? "上传失败", deserialized.Status ?? StatusCodes.Status400BadRequest); } } catch (Exception e) { _logger.LogError(e, "上传失败"); throw; } } public string GetFileUrl(UploadScences scences, string fileName) { return string.IsNullOrWhiteSpace(fileName) ? "" : $"{_options.FileApiDomain}/{GetRelativeToRootPath(scences, fileName) .Replace(Path.DirectorySeparatorChar, '/')}"; } private string GetRelativeToRootPath(UploadScences scences, string fileName = "") { return Path.Combine( "images", scences.GetTargetDirectory(), fileName); } }