Browse Source

增加文件MD5指纹功能(配置及验证)

LionelZhao 2 years ago
parent
commit
0e1690eece

+ 2 - 1
Admin.NET/Admin.NET.Application/Configuration/OSS.json

@@ -4,7 +4,8 @@
     "Upload": {
         "Path": "Upload/{yyyy}/{MM}/{dd}", // 文件上传目录
         "MaxSize": 1048576,
-        "ContentType": [ "image/jpg", "image/png", "image/jpeg", "image/gif", "image/bmp", "text/plain", "application/pdf", "application/msword", "application/vnd.ms-excel", "application/vnd.ms-powerpoint", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", "application/vnd.openxmlformats-officedocument.wordprocessingml.document" ]
+        "ContentType": [ "image/jpg", "image/png", "image/jpeg", "image/gif", "image/bmp", "text/plain", "application/pdf", "application/msword", "application/vnd.ms-excel", "application/vnd.ms-powerpoint", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", "application/vnd.openxmlformats-officedocument.wordprocessingml.document" ],
+        "IsEnableMd5": true
     },
     "OSSProvider": {
         "IsEnable": false,

+ 8 - 1
Admin.NET/Admin.NET.Core/Entity/SysFile.cs

@@ -32,7 +32,7 @@ public class SysFile : EntityBase
 
     /// <summary>
     /// 文件名称(上传时名称)
-    /// </summary>文件名称
+    /// </summary>
     [SugarColumn(ColumnDescription = "文件名称", Length = 128)]
     [MaxLength(128)]
     public string? FileName { get; set; }
@@ -71,4 +71,11 @@ public class SysFile : EntityBase
     [SugarColumn(ColumnDescription = "外链地址", Length = 128)]
     [MaxLength(128)]
     public string? Url { get; set; }
+
+    /// <summary>
+    /// 文件MD5指纹
+    /// </summary>
+    [SugarColumn(ColumnDescription = "文件MD5指纹", Length = 128)]
+    [MaxLength(128)]
+    public string? FileMd5 { get; set; }
 }

+ 6 - 0
Admin.NET/Admin.NET.Core/Enum/ErrorCodeEnum.cs

@@ -400,6 +400,12 @@ public enum ErrorCodeEnum
     [ErrorCodeItemMetadata("文件后缀错误")]
     D8003,
 
+    /// <summary>
+    /// 文件已存在
+    /// </summary>
+    [ErrorCodeItemMetadata("文件已存在")]
+    D8004,
+
     /// <summary>
     /// 已存在同名或同编码参数配置
     /// </summary>

+ 6 - 0
Admin.NET/Admin.NET.Core/Option/UploadOptions.cs

@@ -28,4 +28,10 @@ public sealed class UploadOptions : IConfigurableOptions
     /// 上传格式
     /// </summary>
     public List<string> ContentType { get; set; }
+
+    /// <summary>
+    /// 启用文件MD5指纹
+    /// </summary>
+    /// <remarks>启用文件MD5后,上传时后验证是否重复文件,重复文件无法上传。</remarks>
+    public bool IsEnableMd5 { get; set; }
 }

+ 12 - 0
Admin.NET/Admin.NET.Core/Service/File/SysFileService.cs

@@ -7,6 +7,7 @@
 // 软件按“原样”提供,不提供任何形式的明示或暗示的保证,包括但不限于对适销性、适用性和非侵权的保证。
 // 在任何情况下,作者或版权持有人均不对任何索赔、损害或其他责任负责,无论是因合同、侵权或其他方式引起的,与软件或其使用或其他交易有关。
 
+using Aliyun.OSS.Util;
 using Furion.VirtualFileServer;
 using OnceMi.AspNetCore.OSS;
 
@@ -163,6 +164,16 @@ public class SysFileService : IDynamicApiController, ITransient
     {
         if (file == null) throw Oops.Oh(ErrorCodeEnum.D8000);
 
+        string? fileMd5 = null;
+        if (_uploadOptions.IsEnableMd5)
+        {
+            using var fileStream = file.OpenReadStream();
+            // 利用阿里云SDK库计算Md5(库来自OnceMi.AspNetCore.OSS引用的Aliyun.OSS.SDK)
+            fileMd5 = OssUtils.ComputeContentMd5(fileStream, fileStream.Length);
+
+            if (await _sysFileRep.IsAnyAsync(q => q.FileMd5 == fileMd5)) throw Oops.Oh(ErrorCodeEnum.D8004);
+        }
+
         var path = savePath;
         if (string.IsNullOrWhiteSpace(savePath))
         {
@@ -206,6 +217,7 @@ public class SysFileService : IDynamicApiController, ITransient
             Suffix = suffix,
             SizeKb = sizeKb.ToString(),
             FilePath = path,
+            FileMd5 = fileMd5,
         };
 
         var finalName = newFile.Id + suffix; // 文件最终名称