Browse Source

新增oss上传配置ossconfig.json
新增oss服务AddOSS方法
新增文件服务FileService

zhontai 2 years ago
parent
commit
03c18dc610

+ 3 - 0
src/hosts/ZhonTai.Host/Configs/ossconfig.Development.json

@@ -0,0 +1,3 @@
+{
+  
+}

+ 71 - 0
src/hosts/ZhonTai.Host/Configs/ossconfig.json

@@ -0,0 +1,71 @@
+{
+  //文件存储供应商
+  "Provider": "Minio",
+  "OSSConfigs": [
+    //Minio
+    {
+      "Provider": "Minio",
+      "Endpoint": "127.0.0.1:9006",
+      "Region": "",
+      "AccessKey": "minio",
+      "SecretKey": "minio",
+      "IsEnableHttps": false,
+      "IsEnableCache": true,
+      "BucketName": "admin",
+      "Url": "", //文件外链
+      "Enable": false
+    },
+    //阿里云
+    {
+      "Provider": "Aliyun",
+      "Endpoint": "oss-cn-shenzhen.aliyuncs.com",
+      "Region": "",
+      "AccessKey": "",
+      "SecretKey": "",
+      "IsEnableHttps": true,
+      "IsEnableCache": true,
+      "BucketName": "admin",
+      "Url": "",
+      "Enable": false
+    },
+    //腾讯云
+    {
+      "Provider": "QCloud",
+      "Endpoint": "", //AppId
+      "Region": "",
+      "AccessKey": "",
+      "SecretKey": "",
+      "IsEnableHttps": true,
+      "IsEnableCache": true,
+      "BucketName": "admin",
+      "Url": "",
+      "Enable": false
+    },
+    //七牛
+    {
+      "Provider": "Qiniu",
+      "Endpoint": "",
+      "Region": "",
+      "AccessKey": "",
+      "SecretKey": "",
+      "IsEnableHttps": true,
+      "IsEnableCache": true,
+      "BucketName": "admin",
+      "Url": "",
+      "Enable": false
+    },
+    //华为云
+    {
+      "Provider": "HuaweiCloud",
+      "Endpoint": "",
+      "Region": "",
+      "AccessKey": "",
+      "SecretKey": "",
+      "IsEnableHttps": true,
+      "IsEnableCache": true,
+      "BucketName": "admin",
+      "Url": "",
+      "Enable": false
+    }
+  ]
+}

+ 4 - 1
src/hosts/ZhonTai.Host/Program.cs

@@ -5,6 +5,7 @@ using ZhonTai;
 using ZhonTai.Admin.Core;
 using ZhonTai.Admin.Core.Configs;
 using ZhonTai.Admin.Core.Consts;
+using ZhonTai.Admin.Core.Extensions;
 using ZhonTai.Admin.Core.Startup;
 using ZhonTai.Admin.Tools.TaskScheduler;
 using ZhonTai.ApiUI;
@@ -37,6 +38,8 @@ new HostApp(new HostAppOptions
             //模块任务处理器
             options.TaskHandler = new TaskHandler(options.FreeSql);
         });
+
+        context.Services.AddOSS();
     },
 	//配置后置中间件
 	ConfigurePostMiddleware = context =>
@@ -58,7 +61,7 @@ new HostApp(new HostAppOptions
                 });
             });
 		}
-		#endregion
+        #endregion
 	}
 }).Run(args);
 

+ 29 - 0
src/platform/ZhonTai.Admin/Core/Configs/OSSConfig.cs

@@ -0,0 +1,29 @@
+using OnceMi.AspNetCore.OSS;
+using System.Collections.Generic;
+
+namespace ZhonTai.Admin.Core.Configs;
+
+public class OSSOptions
+{
+    public OSSProvider Provider { get; set; } = OSSProvider.Minio;
+    public string Endpoint { get; set; }
+    public string AccessKey { get; set; }
+    public string SecretKey { get; set; }
+    public string Region { get; set; }
+    public string SessionToken { get; set; }
+    public bool IsEnableHttps { get; set; } = true;
+    public bool IsEnableCache { get; set; }
+    public string BucketName { get; set; } = "admin";
+    public string Url { get; set; }
+    public bool Enable { get; set; } = false;
+}
+
+/// <summary>
+/// OSS配置
+/// </summary>
+public class OSSConfig
+{
+    public OSSProvider Provider { get; set; } = OSSProvider.Minio;
+
+    public List<OSSOptions> OSSConfigs { get; set; }
+}

+ 6 - 0
src/platform/ZhonTai.Admin/Core/Extensions/ApplicationBuilderExtensions.cs

@@ -0,0 +1,6 @@
+namespace ZhonTai.Admin.Core.Extensions;
+
+public static class ApplicationBuilderExtensions
+{
+    
+}

+ 76 - 0
src/platform/ZhonTai.Admin/Core/Extensions/ServiceCollectionExtensions.cs

@@ -0,0 +1,76 @@
+using Microsoft.AspNetCore.Hosting;
+using Microsoft.Extensions.Configuration;
+using Microsoft.Extensions.DependencyInjection;
+using Minio;
+using OnceMi.AspNetCore.OSS;
+using ZhonTai.Admin.Core.Configs;
+using ZhonTai.Common.Helpers;
+using OSSOptions = ZhonTai.Admin.Core.Configs.OSSOptions;
+
+namespace ZhonTai.Admin.Core.Extensions;
+
+public static class ServiceCollectionExtensions
+{
+    private static void CreateBucketName(IOSSServiceFactory oSSServiceFactory, OSSOptions oSSOptions)
+    {
+        var oSSService = oSSServiceFactory.Create(oSSOptions.Provider.ToString());
+        if (!oSSService.BucketExistsAsync(oSSOptions.BucketName).Result)
+        {
+            oSSService.CreateBucketAsync(oSSOptions.BucketName).Wait();
+        }
+
+        //设置Minio存储桶权限
+        if (oSSOptions.Provider == OSSProvider.Minio)
+        {
+            var bucketName = oSSOptions.BucketName;
+            var minioClient = new MinioClient()
+                .WithEndpoint(oSSOptions.Endpoint)
+                .WithCredentials(oSSOptions.AccessKey, oSSOptions.SecretKey);
+
+            if (oSSOptions.Region.NotNull())
+            {
+                minioClient.WithRegion(oSSOptions.Region);
+            }
+
+            minioClient = minioClient.Build();
+            //查看存储桶权限
+            //var policy = minioClient.GetPolicyAsync(new GetPolicyArgs().WithBucket(bucketName)).Result;
+            //设置存储桶权限,存储桶内的所有文件可以通过链接永久访问
+            var policy = $@"{{""Version"":""2012-10-17"",""Statement"":[{{""Effect"":""Allow"",""Principal"":{{""AWS"":[""*""]}},""Action"":[""s3:GetBucketLocation""],""Resource"":[""arn:aws:s3:::{bucketName}""]}},{{""Effect"":""Allow"",""Principal"":{{""AWS"":[""*""]}},""Action"":[""s3:GetObject""],""Resource"":[""arn:aws:s3:::{bucketName}/*.*""]}}]}}";
+            var setPolicyArgs = new SetPolicyArgs().WithBucket(bucketName).WithPolicy(policy);
+            minioClient.SetPolicyAsync(setPolicyArgs).Wait();
+        }
+    }
+
+    public static IServiceCollection AddOSS(this IServiceCollection services)
+    {
+        var env = services.BuildServiceProvider().GetRequiredService<IWebHostEnvironment>();
+        var oSSConfigRoot = ConfigHelper.Load("ossconfig", env.EnvironmentName, true);
+        services.Configure<OSSConfig>(oSSConfigRoot);
+
+        var oSSConfig = oSSConfigRoot.Get<OSSConfig>();
+        if (oSSConfig.OSSConfigs?.Count > 0)
+        {
+            foreach (var oSSOptions in oSSConfig.OSSConfigs)
+            {
+                if (oSSOptions.Enable)
+                {
+                    services.AddOSSService(oSSOptions.Provider.ToString(), option =>
+                    {
+                        option.Provider = oSSOptions.Provider;
+                        option.Endpoint = oSSOptions.Endpoint;
+                        option.AccessKey = oSSOptions.AccessKey;
+                        option.SecretKey = oSSOptions.SecretKey;
+                        option.IsEnableHttps = oSSOptions.IsEnableHttps;
+                        option.IsEnableCache = oSSOptions.IsEnableCache;
+                    });
+
+                    var oSSServiceFactory = services.BuildServiceProvider().GetRequiredService<IOSSServiceFactory>();
+                    CreateBucketName(oSSServiceFactory, oSSOptions);
+                }
+            }
+        }
+
+        return services;
+    }
+}

+ 8 - 1
src/platform/ZhonTai.Admin/Domain/File/FileEntity.cs

@@ -13,7 +13,7 @@ namespace ZhonTai.Admin.Domain.File;
 public partial class FileEntity : EntityBase
 {
     /// <summary>
-    /// 数据库
+    /// OSS供应商
     /// </summary>
     [Column(MapType = typeof(string), StringLength = 50)]
     public OSSProvider? Provider { get; set; }
@@ -64,4 +64,11 @@ public partial class FileEntity : EntityBase
     /// </summary>
     [Column(StringLength = 500)]
     public string LinkUrl { get; }
+
+
+    /// <summary>
+    /// md5码,防止上传重复文件
+    /// </summary>
+    [Column(StringLength = 50)]
+    public string Md5 { get; set; } = string.Empty;
 }

+ 11 - 0
src/platform/ZhonTai.Admin/Repositories/File/FileRepository.cs

@@ -0,0 +1,11 @@
+using ZhonTai.Admin.Core.Db.Transaction;
+using ZhonTai.Admin.Domain.File;
+
+namespace ZhonTai.Admin.Repositories;
+
+public class FileRepository : AdminRepositoryBase<FileEntity>, IFileRepository
+{
+    public FileRepository(UnitOfWorkManagerCloud uowm) : base(uowm)
+    {
+    }
+}

+ 9 - 0
src/platform/ZhonTai.Admin/Services/File/Dto/FileAddInput.cs

@@ -0,0 +1,9 @@
+namespace ZhonTai.Admin.Services.File.Dto;
+
+/// <summary>
+/// 添加
+/// </summary>
+public class FileAddInput
+{
+   
+}

+ 6 - 0
src/platform/ZhonTai.Admin/Services/File/Dto/FileGetOutput.cs

@@ -0,0 +1,6 @@
+
+namespace ZhonTai.Admin.Services.File.Dto;
+
+public class FileGetOutput : FileUpdateInput
+{
+}

+ 9 - 0
src/platform/ZhonTai.Admin/Services/File/Dto/FileGetPageDto.cs

@@ -0,0 +1,9 @@
+namespace ZhonTai.Admin.Domain.File.Dto;
+
+public partial class FileGetPageDto
+{
+    /// <summary>
+    /// 文件名
+    /// </summary>
+    public string FileName { get; set; }
+}

+ 44 - 0
src/platform/ZhonTai.Admin/Services/File/Dto/FileGetPageOutput.cs

@@ -0,0 +1,44 @@
+using OnceMi.AspNetCore.OSS;
+using System;
+using ZhonTai.Admin.Core.Attributes;
+
+namespace ZhonTai.Admin.Services.File.Dto;
+
+public class FileGetPageOutput
+{
+    /// <summary>
+    /// OSS供应商
+    /// </summary>
+    public OSSProvider? Provider { get; set; }
+
+    /// <summary>
+    /// 存储桶名称
+    /// </summary>
+    public string BucketName { get; set; }
+
+    /// <summary>
+    /// 文件Guid
+    /// </summary>
+    [OrderGuid]
+    public Guid FileGuid { get; set; }
+
+    /// <summary>
+    /// 文件名
+    /// </summary>
+    public string FileName { get; set; }
+
+    /// <summary>
+    /// 文件扩展名
+    /// </summary>
+    public string Extension { get; set; }
+
+    /// <summary>
+    /// 文件大小格式化
+    /// </summary>
+    public string SizeFormat { get; }
+
+    /// <summary>
+    /// 链接地址
+    /// </summary>
+    public string LinkUrl { get; }
+}

+ 15 - 0
src/platform/ZhonTai.Admin/Services/File/Dto/FileUpdateInput.cs

@@ -0,0 +1,15 @@
+using System.ComponentModel.DataAnnotations;
+
+namespace ZhonTai.Admin.Services.File.Dto;
+
+/// <summary>
+/// 修改
+/// </summary>
+public partial class FileUpdateInput : FileAddInput
+{
+    /// <summary>
+    /// 文件Id
+    /// </summary>
+    [Required(ErrorMessage = "请选择文件")]
+    public string Id { get; set; }
+}

+ 52 - 0
src/platform/ZhonTai.Admin/Services/File/FileService.cs

@@ -0,0 +1,52 @@
+using System.Threading.Tasks;
+using ZhonTai.Admin.Core.Dto;
+using ZhonTai.Admin.Services.File.Dto;
+using ZhonTai.DynamicApi;
+using ZhonTai.DynamicApi.Attributes;
+using Microsoft.AspNetCore.Mvc;
+using ZhonTai.Admin.Core.Consts;
+using ZhonTai.Admin.Domain.File.Dto;
+using ZhonTai.Admin.Domain.File;
+
+namespace ZhonTai.Admin.Services.File;
+
+/// <summary>
+/// 文件服务
+/// </summary>
+[DynamicApi(Area = AdminConsts.AreaName)]
+public class FileService : BaseService, IFileService, IDynamicApi
+{
+    private IFileRepository _fileRepository => LazyGetRequiredService<IFileRepository>();
+
+    public FileService()
+    {
+
+    }
+
+    /// <summary>
+    /// 查询文件列表
+    /// </summary>
+    /// <param name="input"></param>
+    /// <returns></returns>
+    [HttpPost]
+    public async Task<PageOutput<FileGetPageOutput>> GetPageAsync(PageInput<FileGetPageDto> input)
+    {
+        var fileName = input.Filter?.FileName;
+
+        var list = await _fileRepository.Select
+        .WhereDynamicFilter(input.DynamicFilter)
+        .WhereIf(fileName.NotNull(), a => a.FileName.Contains(fileName))
+        .Count(out var total)
+        .OrderByDescending(true, c => c.Id)
+        .Page(input.CurrentPage, input.PageSize)
+        .ToListAsync<FileGetPageOutput>();
+
+        var data = new PageOutput<FileGetPageOutput>()
+        {
+            List = list,
+            Total = total
+        };
+
+        return data;
+    }
+}

+ 14 - 0
src/platform/ZhonTai.Admin/Services/File/IFileService.cs

@@ -0,0 +1,14 @@
+using System.Threading.Tasks;
+using ZhonTai.Admin.Core.Dto;
+using ZhonTai.Admin.Domain.File.Dto;
+using ZhonTai.Admin.Services.File.Dto;
+
+namespace ZhonTai.Admin.Services.File;
+
+/// <summary>
+/// 文件接口
+/// </summary>
+public interface IFileService
+{
+    Task<PageOutput<FileGetPageOutput>> GetPageAsync(PageInput<FileGetPageDto> input);
+}

+ 83 - 1
src/platform/ZhonTai.Admin/ZhonTai.Admin.xml

@@ -656,6 +656,11 @@
             刷新有效期(分钟)
             </summary>
         </member>
+        <member name="T:ZhonTai.Admin.Core.Configs.OSSConfig">
+            <summary>
+            OSS配置
+            </summary>
+        </member>
         <member name="T:ZhonTai.Admin.Core.Configs.UploadConfig">
             <summary>
             上传配置
@@ -2059,7 +2064,7 @@
         </member>
         <member name="P:ZhonTai.Admin.Domain.File.FileEntity.Provider">
             <summary>
-            数据库
+            OSS供应商
             </summary>
         </member>
         <member name="P:ZhonTai.Admin.Domain.File.FileEntity.BucketName">
@@ -2102,6 +2107,16 @@
             链接地址
             </summary>
         </member>
+        <member name="P:ZhonTai.Admin.Domain.File.FileEntity.Md5">
+            <summary>
+            md5码,防止上传重复文件
+            </summary>
+        </member>
+        <member name="P:ZhonTai.Admin.Domain.File.Dto.FileGetPageDto.FileName">
+            <summary>
+            文件名
+            </summary>
+        </member>
         <member name="P:ZhonTai.Admin.Domain.LogGetPageDto.CreatedUserName">
             <summary>
             创建者
@@ -4254,6 +4269,73 @@
             文档接口
             </summary>
         </member>
+        <member name="T:ZhonTai.Admin.Services.File.Dto.FileAddInput">
+            <summary>
+            添加
+            </summary>
+        </member>
+        <member name="P:ZhonTai.Admin.Services.File.Dto.FileGetPageOutput.Provider">
+            <summary>
+            OSS供应商
+            </summary>
+        </member>
+        <member name="P:ZhonTai.Admin.Services.File.Dto.FileGetPageOutput.BucketName">
+            <summary>
+            存储桶名称
+            </summary>
+        </member>
+        <member name="P:ZhonTai.Admin.Services.File.Dto.FileGetPageOutput.FileGuid">
+            <summary>
+            文件Guid
+            </summary>
+        </member>
+        <member name="P:ZhonTai.Admin.Services.File.Dto.FileGetPageOutput.FileName">
+            <summary>
+            文件名
+            </summary>
+        </member>
+        <member name="P:ZhonTai.Admin.Services.File.Dto.FileGetPageOutput.Extension">
+            <summary>
+            文件扩展名
+            </summary>
+        </member>
+        <member name="P:ZhonTai.Admin.Services.File.Dto.FileGetPageOutput.SizeFormat">
+            <summary>
+            文件大小格式化
+            </summary>
+        </member>
+        <member name="P:ZhonTai.Admin.Services.File.Dto.FileGetPageOutput.LinkUrl">
+            <summary>
+            链接地址
+            </summary>
+        </member>
+        <member name="T:ZhonTai.Admin.Services.File.Dto.FileUpdateInput">
+            <summary>
+            修改
+            </summary>
+        </member>
+        <member name="P:ZhonTai.Admin.Services.File.Dto.FileUpdateInput.Id">
+            <summary>
+            文件Id
+            </summary>
+        </member>
+        <member name="T:ZhonTai.Admin.Services.File.FileService">
+            <summary>
+            文件服务
+            </summary>
+        </member>
+        <member name="M:ZhonTai.Admin.Services.File.FileService.GetPageAsync(ZhonTai.Admin.Core.Dto.PageInput{ZhonTai.Admin.Domain.File.Dto.FileGetPageDto})">
+            <summary>
+            查询文件列表
+            </summary>
+            <param name="input"></param>
+            <returns></returns>
+        </member>
+        <member name="T:ZhonTai.Admin.Services.File.IFileService">
+            <summary>
+            文件接口
+            </summary>
+        </member>
         <member name="T:ZhonTai.Admin.Services.LoginLog.Dto.LoginLogAddInput">
             <summary>
             添加