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 logger) : IQiniuService { private readonly OptionGlobalDAO _optionGlobalDAO = optionGlobalDAO; private readonly UploadManager _uploadManager = new UploadManager(); private readonly ILogger _logger = logger; /// /// 检查文件的字节大小是否符合要求 /// /// /// public async Task CheckFileBytesSize(byte[] fileBytes) { if (fileBytes == null || fileBytes.Length == 0) { return new UploadResult { Success = false, Message = "文件字节数据不能为空" }; } double MaxFileSize = await _optionGlobalDAO.FindAndReturnOption("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 InitQiniuSetting() { QiniuSettings? qiniuSettings = await _optionGlobalDAO.FindAndReturnOption("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 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 // 默认未删除 }; } } }