using Furion.DatabaseAccessor.Extensions;
using Microsoft.Extensions.Options;
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.Processing;
using YBEE.EQM.Core;
namespace YBEE.EQM.Application;
///
/// 资源文件管理服务
///
public class ResourceFileService : IResourceFileService, ITransient
{
private readonly IRepository _rep;
private readonly EqmSiteOptions _eqmSiteOptions;
private readonly string[] _thumbImageTypes = { ".png", ".jpg", "jpeg", ".gif", ".bmp" };
public ResourceFileService(IRepository rep, IOptions options)
{
_rep = rep;
_eqmSiteOptions = options.Value;
}
///
/// 上传文件
///
///
///
public async Task Upload([FromForm] UploadResourceFileInput input)
{
var savePath = Path.Combine(input.Type.ToString(), input.SourceId.ToString());
var saveRoot = Path.Combine(_eqmSiteOptions.ResourceFileRoot, savePath);
if (!Directory.Exists(saveRoot))
{
Directory.CreateDirectory(saveRoot);
}
var extName = Path.GetExtension(input.File.FileName);
var fileNameGuid = Guid.NewGuid().ToString("N");
var fileName = fileNameGuid + extName;
using var stream = File.Create(Path.Combine(saveRoot, fileName));
await input.File.CopyToAsync(stream);
await stream.FlushAsync();
var reqFileName = !string.IsNullOrEmpty(input.FileName?.Trim());
var saveFileName = reqFileName ? input.FileName : input.File.FileName;
// 生成缩略图
AddResourceFileInput thumbItem = null;
if (_thumbImageTypes.Any(t => t == extName.ToLower()))
{
BinaryReader r = new(stream);
r.BaseStream.Seek(0, SeekOrigin.Begin);
var bs = r.ReadBytes((int)r.BaseStream.Length);
using MemoryStream ms = new(bs);
Image imageFrom = Image.Load(ms);
var thumbFileName = fileNameGuid + "_thumb" + extName;
// 源图宽度及高度
int imageFromWidth = imageFrom.Width;
int imageFromHeight = imageFrom.Height;
int width = 240;
int height = (int)Math.Ceiling(width * (imageFromHeight * 1.0 / imageFromWidth));
if (imageFromHeight > imageFromWidth)
{
height = 240;
width = (int)Math.Ceiling(height * (imageFromWidth * 1.0 / imageFromHeight));
}
var thumbPath = Path.Combine(saveRoot, thumbFileName);
imageFrom.Mutate(x => x.Resize(width, height));
imageFrom.Save(thumbPath);
imageFrom.Dispose();
thumbItem = input.Adapt();
thumbItem.FileName = saveFileName.Replace(extName, $"_thumb{extName}");
thumbItem.FilePath = Path.Combine(savePath, thumbFileName);
thumbItem.FileSize = new FileInfo(thumbPath).Length;
thumbItem.FileExtName = extName;
}
AddResourceFileInput item = input.Adapt();
item.FileName = saveFileName;
item.FilePath = Path.Combine(savePath, fileName);
item.FileSize = input.File.Length;
item.FileExtName = extName;
return await Add(item, thumbItem);
}
///
/// 添加资源文件
///
///
/// 缩略图
///
public async Task Add(AddResourceFileInput input, AddResourceFileInput thumbInput = null)
{
var item = input.Adapt();
await _rep.InsertAsync(item);
var ret = item.Adapt();
if (thumbInput != null)
{
var thumbItem = thumbInput.Adapt();
await _rep.InsertAsync(thumbItem);
ret.ThumbResourceFile = thumbItem.Adapt();
}
return ret;
}
///
/// 删除资源文件
///
///
///
public async Task Del(BaseId input)
{
var item = await _rep.FirstOrDefaultAsync(t => t.Id == input.Id) ?? throw Oops.Oh(ErrorCode.E2001);
var fpath = Path.Combine(_eqmSiteOptions.ResourceFileRoot, item.FilePath);
if (File.Exists(fpath))
{
File.Delete(fpath);
}
await item.DeleteAsync();
}
///
/// 根据ID获取资源详细
///
///
///
public async Task GetById(long id)
{
var item = await _rep.FirstOrDefaultAsync(t => t.Id == id) ?? throw Oops.Oh(ErrorCode.E2001);
return item.Adapt();
}
///
/// 根据类型和源ID获取资源列表
///
///
///
///
public async Task> GetListBySourceId(ResourceFileType type, long sourceId)
{
var items = await _rep.DetachedEntities.Where(t => t.Type == type && t.SourceId == sourceId).ProjectToType().ToListAsync();
return items;
}
}