// namespace SafeCampus.System; /// /// /// public class FileService : DbRepository, IFileService { private readonly IConfigService _configService; public FileService(IConfigService configService) { _configService = configService; } /// public async Task> Page(FilePageInput input) { var query = Context.Queryable().WhereIF(!string.IsNullOrEmpty(input.Engine), it => it.Engine == input.Engine)//根据关键字查询 .WhereIF(!string.IsNullOrEmpty(input.SearchKey), it => it.Name.Contains(input.SearchKey))//根据关键字查询 .OrderByIF(!string.IsNullOrEmpty(input.SortField), $"{input.SortField} {input.SortOrder}")//排序 .OrderBy(it => it.Id); var pageInfo = await query.ToPagedListAsync(input.PageNum, input.PageSize);//分页 return pageInfo; } /// public async Task UploadFile(string engine, IFormFile file) { return await StorageFile(engine, file); } /// public async Task Delete(BaseIdListInput input) { var ids = input.Ids;//获取ID await DeleteByIdsAsync(ids.Cast().ToArray());//根据ID删除数据库 } /// public FileStreamResult GetFileStreamResult(string path, string fileName, bool isPathFolder = false) { if (isPathFolder) path = path.CombinePath(fileName); fileName = HttpUtility.UrlEncode(fileName, Encoding.GetEncoding("UTF-8"));//文件名转utf8不然前端下载会乱码 //文件转流 var result = new FileStreamResult(new FileStream(path, FileMode.Open), "application/octet-stream") { FileDownloadName = fileName }; return result; } public async Task GetFileStreamResultFromMinio(string objectName, string fileName) { var minioService = App.GetService(); var stream = await minioService.DownloadFileAsync(objectName); fileName = HttpUtility.UrlEncode(fileName, Encoding.GetEncoding("UTF-8"));//文件名转utf8不然前端下载会乱码 //文件转流 var result = new FileStreamResult(stream, "application/octet-stream") { FileDownloadName = fileName }; return result; } /// public FileStreamResult GetFileStreamResult(byte[] byteArray, string fileName) { fileName = HttpUtility.UrlEncode(fileName, Encoding.GetEncoding("UTF-8"));//文件名转utf8不然前端下载会乱码 //文件转流 var result = new FileStreamResult(new MemoryStream(byteArray), "application/octet-stream") { FileDownloadName = fileName }; return result; } /// public async Task Download(BaseIdInput input) { var devFile = await GetByIdAsync(input.Id); if (devFile != null) { if (devFile.Engine == SysDictConst.FILE_ENGINE_LOCAL) return GetFileStreamResult(devFile.StoragePath, devFile.Name); if (devFile.Engine == SysDictConst.FILE_ENGINE_MINIO) return await GetFileStreamResultFromMinio(devFile.ObjName, devFile.Name); return null; } return null; } #region 方法 /// /// 存储文件 /// /// /// private async Task StorageFile(string engine, IFormFile file) { var bucketName = string.Empty;// 存储桶名称 var storageUrl = string.Empty;// 定义存储的url,本地文件返回文件实际路径,其他引擎返回网络地址 var objName = string.Empty;// 定义存储的url,本地文件返回文件实际路径,其他引擎返回网络地址 var objectId = CommonUtils.GetSingleId();//生成id switch (engine) { //存储本地 case SysDictConst.FILE_ENGINE_LOCAL: bucketName = "defaultBucketName";// 存储桶名称 storageUrl = await StorageLocal(objectId, file); break; //存储本地 case SysDictConst.FILE_ENGINE_MINIO: var config = await _configService.GetByConfigKey(CateGoryConst.CONFIG_FILE_MINIO, SysConfigConst.FILE_MINIO_DEFAULT_BUCKET_NAME); if (config != null) { bucketName = config.ConfigValue;// 存储桶名称 (objName, storageUrl) = await StorageMinio(objectId, file); } break; default: throw Oops.Bah("不支持的文件引擎"); } var fileSizeKb = (long)(file.Length / 1024.0);// 文件大小KB var fileSuffix = Path.GetExtension(file.FileName).ToLower();// 文件后缀 var devFile = new SysFile { Id = objectId, Engine = engine, Bucket = bucketName, Name = file.FileName, Suffix = fileSuffix.Split(".")[1], ObjName = objName, SizeKb = fileSizeKb, SizeInfo = GetSizeInfo(fileSizeKb), StoragePath = storageUrl }; if (engine != CateGoryConst.CONFIG_FILE_LOCAL)//如果不是本地,设置下载地址 { devFile.DownloadPath = storageUrl; } //如果是图片,生成缩略图 if (IsPic(fileSuffix)) { //$"data:image/png;base64," + imgByte; await using var fileStream = file.OpenReadStream();//获取文件流 var image = SKImage.FromEncodedData(fileStream);//获取图片 var bmp = SKBitmap.FromImage(image); var thubnail = bmp.GetPicThumbnail(100, 100);//压缩图片 var thubnailBase64 = ImageUtil.ImgToBase64String(thubnail);//转base64 devFile.Thumbnail = "data:image/png;base64," + thubnailBase64; } await InsertAsync(devFile); return objectId; } /// /// 存储本地文件 /// /// /// private async Task StorageLocal(long fileId, IFormFile file) { string uploadFileFolder; var configKey = string.Empty; //判断是windows还是linux if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) { configKey = SysConfigConst.FILE_LOCAL_FOLDER_FOR_UNIX;//Linux } else if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { configKey = SysConfigConst.FILE_LOCAL_FOLDER_FOR_WINDOWS;//Windows } //获取路径配置 var config = await _configService.GetByConfigKey(CateGoryConst.CONFIG_FILE_LOCAL, configKey); if (config != null) { uploadFileFolder = config.ConfigValue;//赋值路径 var now = DateTime.Now.ToString("d"); var filePath = Path.Combine(uploadFileFolder, now); if (!Directory.Exists(filePath))//如果不存在就创建文件夹 Directory.CreateDirectory(filePath); var fileSuffix = Path.GetExtension(file.FileName).ToLower();// 文件后缀 var fileObjectName = $"{fileId}{fileSuffix}";//存储后的文件名 var fileName = Path.Combine(filePath, fileObjectName);//获取文件全路局 fileName = fileName.Replace("\\", "/");//格式化一系 //存储文件 using (var stream = File.Create(Path.Combine(filePath, fileObjectName))) { await file.CopyToAsync(stream); } return fileName; } throw Oops.Oh("文件存储路径未配置"); } /// /// 存储到minio /// /// /// /// private async Task<(string objName, string downloadUrl)> StorageMinio(long fileId, IFormFile file) { var minioService = App.GetService(); var now = DateTime.Now.ToString("d"); var fileSuffix = Path.GetExtension(file.FileName).ToLower();// 文件后缀 var fileObjectName = $"{now}/{fileId}{fileSuffix}";//存储后的文件名 var downloadUrl = await minioService.PutObjectAsync(fileObjectName, file); return (fileObjectName, downloadUrl); } /// /// 获取文件大小 /// /// /// private string GetSizeInfo(long fileSizeKb) { var b = fileSizeKb * 1024; const int mb = 1024 * 1024; const int kb = 1024; if (b / mb >= 1) { return Math.Round(b / (float)mb, 2) + "MB"; } if (b / kb >= 1) { return Math.Round(b / (float)kb, 2) + "KB"; } if (b == 0) { return "0B"; } return null; } /// /// 判断是否是图片 /// /// 后缀名 /// private bool IsPic(string suffix) { //图片后缀名列表 var pics = new[] { ".png", ".bmp", ".gif", ".jpg", ".jpeg", ".psd" }; if (pics.Contains(suffix)) return true; return false; } #endregion 方法 }