using Fw.Utility.UnifyResponse; using Hotline.Caching.Interfaces; using Hotline.Settings; using Hotline.Share.Dtos.File; using Hotline.Share.Enums.Article; using Hotline.Share.Tools; using Microsoft.Extensions.Logging; using Renci.SshNet; using System; using System.Collections.Generic; using System.Linq; using System.Net.Http.Headers; using System.Runtime.InteropServices.JavaScript; using System.Security.Policy; using System.Text; using System.Text.RegularExpressions; using System.Threading.Tasks; using XF.Domain.Dependency; namespace Hotline.File; public class FileDomainService : IFileDomainService, IScopeDependency { private readonly ISystemSettingCacheManager _setting; private readonly ILogger _logger; private readonly IFileRepository _fileRepository; private readonly ISystemLogRepository _systemLogRepository; public FileDomainService(ISystemSettingCacheManager setting, ILogger logger, IFileRepository fileRepository, ISystemLogRepository systemLogRepository) { _setting = setting; _logger = logger; _fileRepository = fileRepository; _systemLogRepository = systemLogRepository; } /// /// 下载网络文件并上传到文件服务器, 返回 File.Id /// /// /// /// /// public async Task GetNetworkFileAsync(string file, string key, CancellationToken cancellationToken = default) { try { var fileBytes = await DownloadFileToMemoryAsync(file); if (fileBytes is null) return string.Empty; var uploadUrl = _setting.FileServerUrl + "/file/upload?source=hotline"; var match = Regex.Match(file, "[^/]+\\.[a-zA-Z0-9]+$").Value; var resultJson = await UploadFileFromMemoryAsync(fileBytes, match, uploadUrl); var result = resultJson.FromJson>(); var fileSplit = match.Split('.'); var entity = new File() { Key = key, Additions = result.Result.Id, FileName = result.Result.FileName, Path = result.Result.Path, AllPath = file, Type = fileSplit[1], Name = fileSplit[0], }; entity.Id = await _fileRepository.AddAsync(entity); return entity.Id; } catch (Exception e) { var message = $"下载网络文件并上传到文件服务器失败: {e.Message}"; _logger.LogError(message + e.ToJson()); _systemLogRepository.Add("下载网络附件", key, message); } return string.Empty; } /// /// 下载文件, 返回字节 /// /// /// private async Task DownloadFileToMemoryAsync(string url) { #if DEBUG var uri = new Uri(url); var _sshClient = new SshClient("171.94.154.2", 22, "root", "ZGbyy@2024!"); _sshClient.Connect(); var forwardedPort = new ForwardedPortLocal("127.0.0.1", 8090, uri.Host, (uint)uri.Port); _sshClient.AddForwardedPort(forwardedPort); forwardedPort.Start(); url = "http://127.0.0.1:8090" + uri.AbsolutePath; #endif try { using var client = new HttpClient(); HttpResponseMessage response = await client.GetAsync(url); response.EnsureSuccessStatusCode(); return await response.Content.ReadAsByteArrayAsync(); } catch (Exception e) { _logger.LogError("保存第三方系统的文件失败:" + e.Message); } finally { #if DEBUG if (_sshClient.IsConnected) { _sshClient.Disconnect(); } #endif } return null; } public async Task UploadFileFromMemoryAsync(byte[] fileBytes, string fileName, string uploadUrl, string contentType = "image/jpeg") { using HttpClient client = new HttpClient(); using var multipartContent = new MultipartFormDataContent(); var fileContent = new ByteArrayContent(fileBytes); fileContent.Headers.ContentType = MediaTypeHeaderValue.Parse(contentType); multipartContent.Add(fileContent, "fileData", fileName); HttpResponseMessage response = await client.PostAsync(uploadUrl, multipartContent); response.EnsureSuccessStatusCode(); var result = await response.Content.ReadAsStringAsync(); return result; } public async Task UploadFileFromMemoryAsync(Stream fileStream, string fileName, EFileType fileType) { var fileByte = await fileStream.ToByteArrayAsync(); var uploadUrl = _setting.FileServerUrl + "/file/upload?source=hotline"; return (await UploadFileFromMemoryAsync(fileByte, fileName, uploadUrl, fileType.GetContentType())).FromJson>().Result; } }