using Furion; using Furion.DependencyInjection; using Furion.DynamicApiController; using Furion.FriendlyException; using GDZZ.Core.Entity; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Options; using SqlSugar; using System.Collections.Generic; using System.IO; using System.Text; using System.Threading.Tasks; using System.Web; using Yitter.IdGenerator; namespace GDZZ.Core.Service; /// /// 文件服务 /// [ApiDescriptionSettings(Name = "File", Order = 100)] public class SysFileService : ISysFileService, IDynamicApiController, ITransient { private readonly SqlSugarRepository _sysFileInfoRep; // 文件信息表仓储 private readonly UploadFileOptions _options; public SysFileService(SqlSugarRepository sysFileInfoRep, IOptions options) { _sysFileInfoRep = sysFileInfoRep; _options = options.Value; } /// /// 分页获取文件列表 /// /// /// [HttpGet("/sysFileInfo/page")] public async Task QueryFileInfoPageList([FromQuery] FileInput input) { var fileBucket = !string.IsNullOrEmpty(input.FileBucket?.Trim()); var fileOriginName = !string.IsNullOrEmpty(input.FileOriginName?.Trim()); var files = await _sysFileInfoRep.AsQueryable() .WhereIF(input.FileLocation > 0, u => u.FileLocation == input.FileLocation) .WhereIF(!string.IsNullOrWhiteSpace(input.FileBucket), u => u.FileBucket.Contains(input.FileBucket.Trim())) .WhereIF(!string.IsNullOrWhiteSpace(input.FileOriginName), u => u.FileOriginName.Contains(input.FileOriginName.Trim())) .Select() .ToPagedListAsync(input.PageNo, input.PageSize); return files.XnPagedResult(); } /// /// 获取文件列表 /// /// /// [HttpGet("/sysFileInfo/list")] public async Task> GetFileInfoList([FromQuery] FileOutput input) { return await _sysFileInfoRep.ToListAsync(); } /// /// 删除文件 /// /// /// [HttpPost("/sysFileInfo/delete")] public async Task DeleteFileInfo(DeleteFileInfoInput input) { var file = await _sysFileInfoRep.FirstOrDefaultAsync(u => u.Id == input.Id); if (file != null) { await _sysFileInfoRep.DeleteAsync(file); var filePath = Path.Combine(App.WebHostEnvironment.WebRootPath, file.FileBucket, file.FileObjectName); if (File.Exists(filePath)) File.Delete(filePath); } } /// /// 获取文件详情 /// /// /// [HttpGet("/sysFileInfo/detail")] public async Task GetFileInfo([FromQuery] QueryFileInoInput input) { var file = await _sysFileInfoRep.FirstOrDefaultAsync(u => u.Id == input.Id); if (file == null) throw Oops.Oh(ErrorCode.D8000); return file; } /// /// 预览文件 /// /// /// [HttpGet("/sysFileInfo/preview")] public async Task PreviewFileInfo([FromQuery] QueryFileInoInput input) { return await DownloadFileInfo(input); } /// /// 上传文件 /// /// /// [HttpPost("/sysFileInfo/upload")] public async Task UploadFileDefault(IFormFile file) { // 可以读取系统配置来决定将文件存储到什么地方 await UploadFile(file, _options.Default.path, FileLocation.LOCAL); } /// /// 下载文件 /// /// /// [HttpGet("/sysFileInfo/download")] public async Task DownloadFileInfo([FromQuery] QueryFileInoInput input) { var file = await GetFileInfo(input); var filePath = Path.Combine(App.WebHostEnvironment.WebRootPath, file.FilePath, file.FileObjectName); var fileName = HttpUtility.UrlEncode(file.FileOriginName, Encoding.GetEncoding("UTF-8")); var result = new FileStreamResult(new FileStream(filePath, FileMode.Open), "application/octet-stream") { FileDownloadName = fileName }; return result; } /// /// 上传头像 /// /// /// [HttpPost("/sysFileInfo/uploadAvatar")] public async Task UploadFileAvatar(IFormFile file) { return await UploadFile(file, _options.Avatar.path); } /// /// 上传文档 /// /// /// [HttpPost("/sysFileInfo/uploadDocument")] public async Task UploadFileDocument(IFormFile file) { await UploadFile(file, _options.Document.path); } /// /// 上传富文本图片 /// /// /// [HttpPost("/sysFileInfo/uploadEditor")] public async Task UploadFileEditor(IFormFile file) { var id = await UploadFile(file, _options.Editor.path, FileLocation.LOCAL); var fileInfo = _sysFileInfoRep.Single(id); return Path.Combine(fileInfo.FilePath, fileInfo.FileObjectName); } /// /// 上传商店图片 /// /// /// [HttpPost("/sysFileInfo/uploadShop")] public async Task UploadFileShop(IFormFile file) { await UploadFile(file, _options.Shop.path); } /// /// 上传文件 /// /// /// /// private static async Task UploadFile(IFormFile file, string pathType) { var filePath = Path.Combine(App.WebHostEnvironment.WebRootPath, pathType); if (!Directory.Exists(filePath)) Directory.CreateDirectory(filePath); var fileSizeKb = (long)(file.Length / 1024.0); // 文件大小KB var originalFilename = file.FileName; // 文件原始名称 var fileSuffix = Path.GetExtension(file.FileName).ToLower(); // 文件后缀 // 先存库获取Id var id = YitIdHelper.NextId(); var newFile = new SysFile { Id=id, FileLocation = (int)FileLocation.LOCAL, FileBucket = FileLocation.LOCAL.ToString(), FileObjectName = $"{id}{fileSuffix}", FileOriginName = originalFilename, FileSuffix = fileSuffix.TrimStart('.'), FileSizeKb = fileSizeKb.ToString(), FilePath = pathType }; newFile = await App.GetService().Insertable(newFile).ExecuteReturnEntityAsync(); using (var stream = File.Create(Path.Combine(filePath, newFile.FileObjectName))) { await file.CopyToAsync(stream); } return newFile.Id; // 返回文件唯一标识 } /// /// 上传文件 /// /// 文件 /// 存储路径 /// 文件存储位置 /// private static async Task UploadFile(IFormFile file, string pathType, FileLocation fileLocation) { var fileSizeKb = (long)(file.Length / 1024.0); // 文件大小KB var originalFilename = file.FileName; // 文件原始名称 var fileSuffix = Path.GetExtension(file.FileName).ToLower(); // 文件后缀 // 先存库获取Id var id = YitIdHelper.NextId(); var newFile = new SysFile { Id = id, FileLocation = (int)FileLocation.LOCAL, FileBucket = FileLocation.LOCAL.ToString(), FileObjectName = $"{YitIdHelper.NextId()}{fileSuffix}", FileOriginName = originalFilename, FileSuffix = fileSuffix.TrimStart('.'), FileSizeKb = fileSizeKb.ToString(), FilePath = pathType }; newFile = await App.GetService().Insertable(newFile).ExecuteReturnEntityAsync(); var finalName = newFile.FileObjectName; // 生成文件的最终名称 if (fileLocation == FileLocation.LOCAL) // 本地存储 { var filePath = Path.Combine(App.WebHostEnvironment.WebRootPath, pathType); if (!Directory.Exists(filePath)) Directory.CreateDirectory(filePath); using (var stream = File.Create(Path.Combine(filePath, finalName))) { await file.CopyToAsync(stream); } } else if (fileLocation == FileLocation.ALIYUN) // 阿里云OSS { var filePath = pathType + finalName; OSSClientUtil.DeletefileCode(filePath); var stream = file.OpenReadStream(); OSSClientUtil.PushMedia(stream, filePath); } newFile.FileObjectName = finalName; return newFile.Id; // 返回文件唯一标识 } }