123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265 |
- using FileStorage.Extensions;
- using Microsoft.AspNetCore.StaticFiles;
- using Microsoft.Extensions.Logging;
- using Microsoft.Extensions.Options;
- using XF.Domain.Dependency;
- using XF.Domain.Exceptions;
- namespace FileStorage;
- public class DefaultFileStorage : IFileStorage, IScopeDependency
- {
- private readonly IFileMetadataRepository _fileMetadataRepository;
- private readonly IOptionsSnapshot<StorageConfiguration> _fileUploadOptions;
- private readonly ILogger<DefaultFileStorage> _logger;
- public DefaultFileStorage(IFileMetadataRepository fileMetadataRepository, IOptionsSnapshot<StorageConfiguration> optionsSnapshot, ILogger<DefaultFileStorage> logger)
- {
- _fileMetadataRepository = fileMetadataRepository;
- _fileUploadOptions = optionsSnapshot;
- _logger = logger;
- }
- /// <summary>
- /// 本地上传
- /// </summary>
- /// <param name="fileName"></param>
- /// <param name="length"></param>
- /// <param name="extraInfo"></param>
- /// <param name="fileData"></param>
- /// <param name="client"></param>
- /// <param name="isVerification">是否验证文件格式</param>
- /// <returns></returns>
- public async Task<FileMetadata> UploadAsync(string fileName, long length, string extraInfo, Stream fileData, string client, bool? isVerification)
- {
- if (fileName == null)
- {
- fileName = "unkown";
- }
- fileName = fileName.Replace("<", "").Replace(">", "").Replace(" ", "");
- var rv = UploadLoca(fileName, length, extraInfo, fileData, client, isVerification);
- if (!string.IsNullOrEmpty(rv))
- {
- FileMetadata fileModel = new FileMetadata();
- fileModel.Client = client;
- fileModel.FileName = fileName;
- var ext = string.Empty;
- if (string.IsNullOrEmpty(fileName) == false)
- {
- var dotPos = fileName.LastIndexOf('.');
- ext = fileName[(dotPos + 1)..];
- }
- fileModel.FileExt = ext;
- fileModel.Path = rv;
- fileModel.Length = length;
- fileModel.SaveMode = _fileUploadOptions.Value.Impt;
- fileModel.ExtraInfo = extraInfo;
- fileModel.UploadTime = DateTime.Now;
- await _fileMetadataRepository.AddAsync(fileModel);
- return fileModel;
- }
- return null;
- }
- public async Task<Uri> GetFileUrlAsync(string id, string clientId)
- {
- var fileMetadata = await _fileMetadataRepository.GetAsync(x => x.Id == id && x.Client == clientId);
- if (fileMetadata != null)
- {
- long sTime = (long)(DateTime.Now.AddHours(1).ToUniversalTime() - new DateTime(1970, 1, 1, 0, 0, 0)).TotalSeconds;
- string encryptText = clientId + "|" + sTime + "|" + id;
- var signatureText = DESExtensions.Encrypt(encryptText);
- return new Uri("/file/files?id=" + id + "&expires=" + sTime + "&clientid=" + clientId + "&signature=" + signatureText);
- //return new Uri(_fileUploadOptions.Value.Local.VisDomain+fileMetadata.Path);
- }
- throw new UserFriendlyException("无权限访问");
- }
- public async Task<Uri> GetFileUrlIndefinitelyAsync(string id, string clientId)
- {
- var fileMetadata = await _fileMetadataRepository.GetAsync(x => x.Id == id && x.Client == clientId);
- if (fileMetadata != null)
- {
- long sTime = (long)(DateTime.Now.AddHours(1).ToUniversalTime() - new DateTime(1970, 1, 1, 0, 0, 0)).TotalSeconds;
- string encryptText = clientId + "|" + sTime + "|" + id;
- var signatureText = DESExtensions.Encrypt(encryptText);
- return new Uri("/file/files_indefinitely?id=" + id + "&expires=" + sTime + "&clientid=" + clientId + "&signature=" + signatureText);
- }
- throw new UserFriendlyException("无权限访问");
- }
- public (Stream stream, string contentType, string fileName) DownLoadFile(string id, string clientId)
- {
- var fileMetadata = _fileMetadataRepository.Get(x => x.Id == id && x.Client == clientId);
- if (fileMetadata != null)
- {
- string filePath = Path.Combine(Directory.GetCurrentDirectory(), fileMetadata.Path);
- var contentType = TaskGetFileContentTypeAsync(fileMetadata.Path);
- var stream = File.OpenRead(filePath);
- return (stream, contentType, fileMetadata.FileName);
- }
- throw new UserFriendlyException("无权限访问");
- }
- public async Task<bool> DelFileAsync(string id, string clientId)
- {
- var fileMetadata = await _fileMetadataRepository.GetAsync(x => x.Id == id && x.Client == clientId);
- if (fileMetadata != null)
- {
- string filePath = Path.Combine(Directory.GetCurrentDirectory(), fileMetadata.Path);
- await _fileMetadataRepository.RemoveAsync(id);
- File.Delete(filePath);
- return true;
- }
- return false;
- }
- public async Task<string> GetFilePathAsync(string id, string clientId)
- {
- var fileMetadata = await _fileMetadataRepository.GetAsync(x => x.Id == id && x.Client == clientId);
- return fileMetadata?.Path!;
- }
- public async Task<string> GetFilePath(string id, string expires, string clientId, string signature)
- {
- string decryptText = DESExtensions.Decrypt(signature);
- if (!string.IsNullOrEmpty(decryptText))
- {
- string[] paramData = decryptText.Split('|');
- if (id != paramData[2] || clientId != paramData[0] || expires != paramData[1])
- throw UserFriendlyException.SameMessage("参数不合法");
- if (long.Parse(paramData[1]) < ((long)(DateTime.Now.ToUniversalTime() - new DateTime(1970, 1, 1, 0, 0, 0)).TotalSeconds))
- throw UserFriendlyException.SameMessage("链接已过期");
- var fileMetadata = await _fileMetadataRepository.GetAsync(x => x.Id == id && x.Client == clientId);
- if (fileMetadata == null)
- throw UserFriendlyException.SameMessage("无权限访问");
- return GetFullPath(fileMetadata.Path);
- }
- throw UserFriendlyException.SameMessage("无权限访问");
- }
- public async Task<string> GetFilePathIndefinitely(string id, string expires, string clientId, string signature)
- {
- string decryptText = DESExtensions.Decrypt(signature);
- if (!string.IsNullOrEmpty(decryptText))
- {
- string[] paramData = decryptText.Split('|');
- if (id != paramData[2] || clientId != paramData[0] || expires != paramData[1])
- throw UserFriendlyException.SameMessage("参数不合法");
- var fileMetadata = await _fileMetadataRepository.GetAsync(x => x.Id == id && x.Client == clientId);
- if (fileMetadata == null)
- throw UserFriendlyException.SameMessage("无权限访问");
- return GetFullPath(fileMetadata.Path);
- }
- throw UserFriendlyException.SameMessage("无权限访问");
- }
- private string TaskGetFileContentTypeAsync(string fileName)
- {
- string suffix = Path.GetExtension(fileName);
- var provider = new FileExtensionContentTypeProvider();
- var contentType = provider.Mappings[suffix];
- return contentType;
- }
- private string UploadLoca(string fileName, long length, string extraInfo, Stream fileData, string client, bool? isVerification)
- {
- var settings = _fileUploadOptions.Value.Local;
- string groupDir = "";
- if (settings != null)
- {
- groupDir = settings.Path;
- }
- if (string.IsNullOrEmpty(groupDir))
- {
- groupDir = "uploads";
- }
- string sub = DateTime.Now.ToString("yyyyMMdd");
- groupDir = Path.Combine(groupDir, client, sub);
- string pathHeader = groupDir;
- string fulldir = GetFullPath(pathHeader);
- _logger.LogInformation("路径:"+fulldir);
- if (!Directory.Exists(fulldir))
- {
- Directory.CreateDirectory(fulldir);
- }
- _logger.LogInformation("已执行");
- var ext = string.Empty;
- if (!string.IsNullOrEmpty(fileName))
- {
- var dotPos = fileName.LastIndexOf('.');
- if (dotPos == 0)
- {
- throw UserFriendlyException.SameMessage("文件没有格式,请重新上传文件");
- }
- ext = fileName.Substring(dotPos + 1);
- }
- if (isVerification.HasValue && isVerification == true)
- {
- //TODO验证文件格式
- var extList = new List<string>();
- extList.Add("txt");
- extList.Add("xls");
- extList.Add("xlsx");
- extList.Add("jpg");
- extList.Add("jpeg");
- extList.Add("png");
- extList.Add("doc");
- extList.Add("docx");
- extList.Add("rar");
- extList.Add("pdf");
- extList.Add("mp3");
- extList.Add("zip");
- extList.Add("wmv");
- extList.Add("mp4");
- extList.Add("svg");
- extList.Add("avi");
- //extList.Add("m4a");
- if (!extList.Contains(ext))
- {
- // throw UserFriendlyException.SameMessage("文件格式不正确,只能上传【doc,rar,jpg,pdf,mp3,xls,xlsx,zip,docx,wmv,mp4.png,svg,avijpeg.m4a.txt】格式文件");
- throw UserFriendlyException.SameMessage("文件格式不正确,只能上传【doc,rar,jpg,pdf,mp3,xls,xlsx,zip,docx,wmv,mp4.png,svg,avi,jpeg,txt】格式文件");
- }
- }
- var filename = $"{Guid.NewGuid().ToString().Replace("-", string.Empty)}.{ext}";
- var fullPath = Path.Combine(fulldir, filename);
- using (var fileStream = File.Create(fullPath))
- {
- fileData.CopyTo(fileStream);
- }
- fileData.Dispose();
- return (Path.Combine(pathHeader, filename));
- }
- private string GetFullPath(string path)
- {
- string rv = "";
- if (path.StartsWith("."))
- {
- rv = Path.Combine(Directory.GetCurrentDirectory(), path);
- }
- else
- {
- rv = path;
- }
- rv = Path.GetFullPath(rv);
- return rv;
- }
- }
|