136 lines
5.3 KiB
C#

using LMS.Common.Extensions;
using LMS.DAO.OptionDAO;
using LMS.Repository.DB;
using LMS.Repository.FileUpload;
using Microsoft.Extensions.Logging;
using Qiniu.Http;
using Qiniu.IO;
using Qiniu.IO.Model;
using Qiniu.Util;
using System.Security.Cryptography;
using static LMS.Repository.DTO.FileUploadDto;
namespace LMS.Tools.FileTool
{
public class QiniuService(OptionGlobalDAO optionGlobalDAO, ILogger<QiniuService> logger) : IQiniuService
{
private readonly OptionGlobalDAO _optionGlobalDAO = optionGlobalDAO;
private readonly UploadManager _uploadManager = new UploadManager();
private readonly ILogger<QiniuService> _logger = logger;
/// <summary>
/// 检查文件的字节大小是否符合要求
/// </summary>
/// <param name="fileBytes"></param>
/// <returns></returns>
public async Task<UploadResult> CheckFileBytesSize(byte[] fileBytes)
{
if (fileBytes == null || fileBytes.Length == 0)
{
return new UploadResult
{
Success = false,
Message = "文件字节数据不能为空"
};
}
double MaxFileSize = await _optionGlobalDAO.FindAndReturnOption<double>("SYS_MaxUploadFileSize");
if (fileBytes.Length > MaxFileSize * 1024 * 1024)
{
return new UploadResult
{
Success = false,
Message = $"文件大小不能超过 {MaxFileSize}MB"
};
}
return new UploadResult { Success = true, Message = string.Empty };
}
public string ComputeSHA1Hash(byte[] data)
{
var hash = SHA1.HashData(data);
return Convert.ToHexString(hash).ToLower();
}
public string GenerateFileKey(long userId, string fileName)
{
var date = DateTime.Now.ToString("yyyyMMdd");
//var extension = Path.GetExtension(fileName);
return $"user/{userId}/{date}/{fileName}";
}
public async Task<QiniuSettings> InitQiniuSetting()
{
QiniuSettings? qiniuSettings = await _optionGlobalDAO.FindAndReturnOption<QiniuSettings>("SYS_QiniuSetting");
if (qiniuSettings == null || string.IsNullOrEmpty(qiniuSettings.AccessKey) || string.IsNullOrEmpty(qiniuSettings.SecretKey) || string.IsNullOrEmpty(qiniuSettings.BucketName) || string.IsNullOrEmpty(qiniuSettings.Domain))
{
throw new Exception("七牛云配置不完整,请检查配置,请联系管理员");
}
return qiniuSettings;
}
public string GeneratePolicy(QiniuSettings qiniuSettings)
{
Mac mac = new(qiniuSettings.AccessKey, qiniuSettings.SecretKey);
var putPolicy = new PutPolicy
{
Scope = qiniuSettings.BucketName
};
if (qiniuSettings.DeleteDay != null)
{
putPolicy.DeleteAfterDays = qiniuSettings.DeleteDay.Value; // 设置过期时间
}
putPolicy.SetExpires(3600);
string token = Auth.CreateUploadToken(mac, putPolicy.ToJsonString());
return token;
}
public string BuildFileUrl(string domain, string fileKey)
{
return $"{domain}/{fileKey}";
}
public async Task<FileUploads> UploadFileToQiNiu(byte[] fileBytes, long userId, string fileName, string fileKey)
{
QiniuSettings qiniuSettings = await InitQiniuSetting();
string token = GeneratePolicy(qiniuSettings);
string hash = ComputeSHA1Hash(fileBytes);
HttpResult uploadResult;
_logger.LogInformation("开始上传文件, 用户ID: {userId}, 文件名: {fileName}, 文件大小: {fileLength} 字节, 文件Key: {fileKey}", userId, fileName, fileBytes.Length, fileKey);
using (var stream = new MemoryStream(fileBytes))
{
uploadResult = await _uploadManager.UploadStreamAsync(stream, fileKey, token);
}
// 8. 检查上传结果
if (uploadResult.Code != 200)
{
_logger.LogError("文件上传失败, 上传用户ID: {userId}, 错误信息: {error}", userId, uploadResult.Text);
throw new Exception(uploadResult.Text);
}
var qiniuUrl = BuildFileUrl(qiniuSettings.Domain, fileKey);
_logger.LogInformation("文件上传成功, 上传用户ID: {userId}, 文件Key: {fileKey},文件链接: {url}", userId, fileKey, qiniuUrl);
return new FileUploads
{
UserId = userId,
FileName = fileName,
FileKey = fileKey,
FileSize = fileBytes.Length,
ContentType = "application/octet-stream",
Hash = hash,
QiniuUrl = qiniuUrl,
UploadTime = DateTime.Now,
Status = "active",
CreatedAt = DateTime.Now,
DeleteTime = qiniuSettings.DeleteDay != null ? BeijingTimeExtension.GetBeijingTime().AddDays((double)qiniuSettings.DeleteDay) : DateTime.MaxValue // 默认未删除
};
}
}
}