Browse Source

feat: 完善文件模块

feat/cap 9.0.6.11
Hanpaopao 2 years ago
parent
commit
62fcb7cbbd
  1. 2
      aspnet-core/Directory.Build.Volo.targets
  2. 38
      aspnet-core/modules/FileManagement/src/Lion.AbpPro.FileManagement.Application.Contracts/Files/CreateFileObjectInput.cs
  3. 9
      aspnet-core/modules/FileManagement/src/Lion.AbpPro.FileManagement.Application.Contracts/Files/GetFileObjectInput.cs
  4. 44
      aspnet-core/modules/FileManagement/src/Lion.AbpPro.FileManagement.Application.Contracts/Files/GetFileObjectOutput.cs
  5. 6
      aspnet-core/modules/FileManagement/src/Lion.AbpPro.FileManagement.Application.Contracts/Files/IFileAppService.cs
  6. 27
      aspnet-core/modules/FileManagement/src/Lion.AbpPro.FileManagement.Application.Contracts/Files/PageFileObjectOutput.cs
  7. 43
      aspnet-core/modules/FileManagement/src/Lion.AbpPro.FileManagement.Application.Contracts/Files/UpdateFileInput.cs
  8. 2
      aspnet-core/modules/FileManagement/src/Lion.AbpPro.FileManagement.Application.Contracts/Files/UploadFileObjectOutput.cs
  9. 9
      aspnet-core/modules/FileManagement/src/Lion.AbpPro.FileManagement.Application.Contracts/Permissions/FileManagementPermissionDefinitionProvider.cs
  10. 8
      aspnet-core/modules/FileManagement/src/Lion.AbpPro.FileManagement.Application.Contracts/Permissions/FileManagementPermissions.cs
  11. 1
      aspnet-core/modules/FileManagement/src/Lion.AbpPro.FileManagement.Application/FileManagementApplicationAutoMapperProfile.cs
  12. 80
      aspnet-core/modules/FileManagement/src/Lion.AbpPro.FileManagement.Application/Files/FileAppService.cs
  13. 3
      aspnet-core/modules/FileManagement/src/Lion.AbpPro.FileManagement.Application/GlobalUsings.cs
  14. 15
      aspnet-core/modules/FileManagement/src/Lion.AbpPro.FileManagement.Domain.Shared/FileManagementConsts.cs
  15. 4
      aspnet-core/modules/FileManagement/src/Lion.AbpPro.FileManagement.Domain.Shared/FileManagementDomainSharedModule.cs
  16. 4
      aspnet-core/modules/FileManagement/src/Lion.AbpPro.FileManagement.Domain.Shared/FileManagementErrorCodes.cs
  17. 19
      aspnet-core/modules/FileManagement/src/Lion.AbpPro.FileManagement.Domain.Shared/Files/FileObjectDto.cs
  18. 45
      aspnet-core/modules/FileManagement/src/Lion.AbpPro.FileManagement.Domain.Shared/Files/SizeHelper.cs
  19. 8
      aspnet-core/modules/FileManagement/src/Lion.AbpPro.FileManagement.Domain.Shared/Localization/FileManagement/en.json
  20. 8
      aspnet-core/modules/FileManagement/src/Lion.AbpPro.FileManagement.Domain.Shared/Localization/FileManagement/zh-Hans.json
  21. 3
      aspnet-core/modules/FileManagement/src/Lion.AbpPro.FileManagement.Domain/FileManagementDomainModule.cs
  22. 6
      aspnet-core/modules/FileManagement/src/Lion.AbpPro.FileManagement.Domain/Files/AbpProFileManagementContainer.cs
  23. 13
      aspnet-core/modules/FileManagement/src/Lion.AbpPro.FileManagement.Domain/Files/DomainFileManagementException.cs
  24. 39
      aspnet-core/modules/FileManagement/src/Lion.AbpPro.FileManagement.Domain/Files/FileManager.cs
  25. 67
      aspnet-core/modules/FileManagement/src/Lion.AbpPro.FileManagement.Domain/Files/FileObject.cs
  26. 38
      aspnet-core/modules/FileManagement/src/Lion.AbpPro.FileManagement.Domain/Files/FileObjectManager.cs
  27. 5
      aspnet-core/modules/FileManagement/src/Lion.AbpPro.FileManagement.Domain/Files/IFileObjectRepository.cs
  28. 2
      aspnet-core/modules/FileManagement/src/Lion.AbpPro.FileManagement.Domain/GlobalUsings.cs
  29. 7
      aspnet-core/modules/FileManagement/src/Lion.AbpPro.FileManagement.Domain/Lion.AbpPro.FileManagement.Domain.csproj
  30. 30
      aspnet-core/modules/FileManagement/src/Lion.AbpPro.FileManagement.Domain/Provider/DatabaseFileProvider.cs
  31. 6
      aspnet-core/modules/FileManagement/src/Lion.AbpPro.FileManagement.Domain/Provider/IFileProvider.cs
  32. 3
      aspnet-core/modules/FileManagement/src/Lion.AbpPro.FileManagement.EntityFrameworkCore/EntityFrameworkCore/FileManagementDbContextModelCreatingExtensions.cs
  33. 24
      aspnet-core/modules/FileManagement/src/Lion.AbpPro.FileManagement.EntityFrameworkCore/EntityFrameworkCore/Files/EfCoreFileObjectRepository.cs
  34. 13
      aspnet-core/modules/FileManagement/src/Lion.AbpPro.FileManagement.HttpApi/Files/FileController.cs
  35. 19
      aspnet-core/services/host/Lion.AbpPro.HttpApi.Host/AbpProHttpApiHostModule.Configure.cs
  36. 5
      aspnet-core/services/host/Lion.AbpPro.HttpApi.Host/AbpProHttpApiHostModule.cs
  37. 1
      aspnet-core/services/host/Lion.AbpPro.HttpApi.Host/Lion.AbpPro.HttpApi.Host.csproj
  38. 6
      aspnet-core/services/host/Lion.AbpPro.HttpApi.Host/appsettings.json
  39. 2
      aspnet-core/services/src/Lion.AbpPro.DbMigrator/appsettings.json
  40. 2163
      aspnet-core/services/src/Lion.AbpPro.EntityFrameworkCore/Migrations/20250219151836_1.0.3.Designer.cs
  41. 57
      aspnet-core/services/src/Lion.AbpPro.EntityFrameworkCore/Migrations/20250219151836_1.0.3.cs
  42. 16
      aspnet-core/services/src/Lion.AbpPro.EntityFrameworkCore/Migrations/AbpProDbContextModelSnapshot.cs

2
aspnet-core/Directory.Build.Volo.targets

@ -10,6 +10,8 @@
<PackageReference Update="Volo.Abp.Identity.AspNetCore" Version="9.0.4"/>
<PackageReference Update="Volo.Abp.Caching" Version="9.0.4"/>
<PackageReference Update="Volo.Abp.BlobStoring.Aliyun" Version="9.0.4"/>
<PackageReference Update="Volo.Abp.BlobStoring" Version="9.0.4"/>
<PackageReference Update="Volo.Abp.BlobStoring.FileSystem" Version="9.0.4"/>
<PackageReference Update="Volo.Abp.BackgroundJobs" Version="9.0.4"/>
<PackageReference Update="Volo.Abp.Authorization.Abstractions" Version="9.0.4"/>
<PackageReference Update="Volo.Abp.BackgroundJobs.HangFire" Version="9.0.4"/>

38
aspnet-core/modules/FileManagement/src/Lion.AbpPro.FileManagement.Application.Contracts/Files/CreateFileObjectInput.cs

@ -1,38 +0,0 @@
namespace Lion.AbpPro.FileManagement.Files;
/// <summary>
/// 创建文件
/// </summary>
public class CreateFileObjectInput
{
/// <summary>
/// 文件Provider
/// </summary>
[Required(ErrorMessage = "文件Provider不能为空")]
public string ProviderKey { get; set; }
/// <summary>
/// 文件扩展名
/// </summary>
[Required(ErrorMessage = "文件扩展名不能为空")]
public string FileExtension { get; set; }
/// <summary>
/// 二进制数据
/// </summary>
[Required(ErrorMessage = "二进制数据不能为空")]
public long Bytes { get; set; }
/// <summary>
/// 文件大小
/// </summary>
[Required(ErrorMessage = "文件大小不能为空")]
public long FileSize { get; set; }
/// <summary>
/// 文件名称
/// </summary>
[Required(ErrorMessage = "文件名称不能为空")]
public string ContentType { get; set; }
/// <summary>
/// 文件名称
/// </summary>
[Required(ErrorMessage = "文件名称不能为空")]
public string FileName { get; set; }
}

9
aspnet-core/modules/FileManagement/src/Lion.AbpPro.FileManagement.Application.Contracts/Files/GetFileObjectInput.cs

@ -1,9 +0,0 @@
namespace Lion.AbpPro.FileManagement.Files;
public class GetFileObjectInput
{
/// <summary>
/// 文件Id
/// </summary>
public Guid Id { get; set; }
}

44
aspnet-core/modules/FileManagement/src/Lion.AbpPro.FileManagement.Application.Contracts/Files/GetFileObjectOutput.cs

@ -1,44 +0,0 @@
namespace Lion.AbpPro.FileManagement.Files;
public class GetFileObjectOutput
{
/// <summary>
/// 文件Id
/// </summary>
public Guid Id { get; set; }
/// <summary>
/// 文件Provider
/// </summary>
public string ProviderKey { get; set; }
/// <summary>
/// 文件扩展名
/// </summary>
public string FileExtension { get; set; }
/// <summary>
/// 二进制数据
/// </summary>
public byte[] Bytes { get; set; }
/// <summary>
/// 文件大小
/// </summary>
public long FileSize { get; set; }
/// <summary>
/// 文件名称
/// </summary>
public string ContentType { get; set; }
/// <summary>
/// 文件名称
/// </summary>
public string FileName { get; set; }
/// <summary>
/// 创建时间
/// </summary>
public DateTime CreationTime { get; set; }
}

6
aspnet-core/modules/FileManagement/src/Lion.AbpPro.FileManagement.Application.Contracts/Files/IFileAppService.cs

@ -2,6 +2,7 @@ using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Application.Services;
using Volo.Abp.Content;
namespace Lion.AbpPro.FileManagement.Files;
@ -18,17 +19,16 @@ public interface IFileAppService : IApplicationService
/// <summary>
/// 上传文件
/// </summary>
Task<List<UploadOutput>> UploadAsync(List<IFormFile> files);
Task UploadAsync(List<IFormFile> files);
/// <summary>
/// 删除文件
/// </summary>
Task DeleteAsync(DeleteFileObjectInput input);
Task<GetFileObjectOutput> GetAsync(GetFileObjectInput input);
/// <summary>
/// 下载文件
/// </summary>
Task<FileContentResult> DownloadAsync(DownloadFileObjectInput input);
Task<RemoteStreamContent> DownloadAsync(DownloadFileObjectInput input);
}

27
aspnet-core/modules/FileManagement/src/Lion.AbpPro.FileManagement.Application.Contracts/Files/PageFileObjectOutput.cs

@ -9,39 +9,26 @@ public class PageFileObjectOutput
/// 文件Id
/// </summary>
public Guid Id { get; set; }
/// <summary>
/// 文件Provider
/// </summary>
public string ProviderKey { get; set; }
/// <summary>
/// 文件扩展名
/// </summary>
public string FileExtension { get; set; }
// /// <summary>
// /// 二进制数据
// /// </summary>
// public byte[] Bytes { get; set; }
/// <summary>
/// 文件大小
/// </summary>
public long FileSize { get; set; }
public string BeautifySize => SizeHelper.BeautifySize(FileSize);
/// <summary>
/// 文件名称
/// </summary>
public string ContentType { get; set; }
/// <summary>
/// 文件名称
/// </summary>
public string FileName { get; set; }
/// <summary>
/// 创建时间
/// </summary>
public DateTime CreationTime { get; set; }
public DateTime CreationTime { get; set; }
}

43
aspnet-core/modules/FileManagement/src/Lion.AbpPro.FileManagement.Application.Contracts/Files/UpdateFileInput.cs

@ -1,43 +0,0 @@
namespace Lion.AbpPro.FileManagement.Files;
/// <summary>
/// 更新文件
/// </summary>
public class UpdateFileInput
{
/// <summary>
/// 文件Id
/// </summary>
public Guid Id { get; set; }
/// <summary>
/// 文件Provider
/// </summary>
[Required(ErrorMessage = "文件Provider不能为空")]
public string ProviderKey { get; set; }
/// <summary>
/// 文件扩展名
/// </summary>
[Required(ErrorMessage = "文件扩展名不能为空")]
public string FileExtension { get; set; }
/// <summary>
/// 二进制数据
/// </summary>
[Required(ErrorMessage = "二进制数据不能为空")]
public long Bytes { get; set; }
/// <summary>
/// 文件大小
/// </summary>
[Required(ErrorMessage = "文件大小不能为空")]
public long FileSize { get; set; }
/// <summary>
/// 文件名称
/// </summary>
[Required(ErrorMessage = "文件名称不能为空")]
public string ContentType { get; set; }
/// <summary>
/// 文件名称
/// </summary>
[Required(ErrorMessage = "文件名称不能为空")]
public string FileName { get; set; }
}

2
aspnet-core/modules/FileManagement/src/Lion.AbpPro.FileManagement.Application.Contracts/Files/UploadOutput.cs → aspnet-core/modules/FileManagement/src/Lion.AbpPro.FileManagement.Application.Contracts/Files/UploadFileObjectOutput.cs

@ -1,6 +1,6 @@
namespace Lion.AbpPro.FileManagement.Files;
public class UploadOutput
public class UploadFileObjectOutput
{
public Guid Id { get; set; }

9
aspnet-core/modules/FileManagement/src/Lion.AbpPro.FileManagement.Application.Contracts/Permissions/FileManagementPermissionDefinitionProvider.cs

@ -4,10 +4,11 @@ public class FileManagementPermissionDefinitionProvider : PermissionDefinitionPr
{
public override void Define(IPermissionDefinitionContext context)
{
var abpIdentityGroup = context.GetGroup("AbpIdentity");
var fileManagement = abpIdentityGroup.AddPermission(FileManagementPermissions.FileManagement.Default,
L("Permission:FileManagement"));
var fileManagementGroup = context.AddGroup(FileManagementPermissions.GroupName, L("Permission:FileManagement"));
var filePermission = fileManagementGroup.AddPermission(FileManagementPermissions.FileManagement.Default, L("Permission:FileManagement:File"));
filePermission.AddChild(FileManagementPermissions.FileManagement.Upload, L("Permission:FileManagement:File:Upload"));
filePermission.AddChild(FileManagementPermissions.FileManagement.Download, L("Permission:FileManagement:File:Download"));
filePermission.AddChild(FileManagementPermissions.FileManagement.Delete, L("Permission:FileManagement:File:Delete"));
}
private static LocalizableString L(string name)

8
aspnet-core/modules/FileManagement/src/Lion.AbpPro.FileManagement.Application.Contracts/Permissions/FileManagementPermissions.cs

@ -2,14 +2,16 @@ namespace Lion.AbpPro.FileManagement.Permissions;
public class FileManagementPermissions
{
public const string GroupName = "AbpIdentity";
public const string GroupName = "FileManagement";
public static class FileManagement
{
public const string Default = GroupName + ".FileManagement";
public const string Default = GroupName + ".File";
public const string Upload = Default + ".Upload";
public const string Down = Default + ".Down";
public const string Download = Default + ".Download";
public const string Delete = Default + ".Delete";
}
public static string[] GetAll()
{
return ReflectionHelper.GetPublicConstantsRecursively(typeof(FileManagementPermissions));

1
aspnet-core/modules/FileManagement/src/Lion.AbpPro.FileManagement.Application/FileManagementApplicationAutoMapperProfile.cs

@ -7,6 +7,5 @@ public class FileManagementApplicationAutoMapperProfile : Profile
public FileManagementApplicationAutoMapperProfile()
{
CreateMap<Files.FileObjectDto, PageFileObjectOutput>();
CreateMap<Files.FileObjectDto, GetFileObjectOutput>();
}
}

80
aspnet-core/modules/FileManagement/src/Lion.AbpPro.FileManagement.Application/Files/FileAppService.cs

@ -1,23 +1,20 @@
using Lion.AbpPro.FileManagement.Provider;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
namespace Lion.AbpPro.FileManagement.Files;
/// <summary>
/// 文件
/// </summary>
[Authorize]
[Authorize(FileManagementPermissions.FileManagement.Default)]
public class FileAppService : ApplicationService, IFileAppService
{
private readonly FileObjectManager _fileObjectManager;
private readonly IFileProvider _fileProvider;
private readonly FileManager _fileManager;
private readonly IBlobContainer<AbpProFileManagementContainer> _blobContainer;
public FileAppService(FileObjectManager fileObjectManager, IFileProvider fileProvider)
public FileAppService(FileObjectManager fileObjectManager, IBlobContainer<AbpProFileManagementContainer> blobContainer, FileManager fileManager)
{
_fileObjectManager = fileObjectManager;
_fileProvider = fileProvider;
_blobContainer = blobContainer;
_fileManager = fileManager;
}
/// <summary>
@ -34,71 +31,34 @@ public class FileAppService : ApplicationService, IFileAppService
return result;
}
public async Task<List<UploadOutput>> UploadAsync(List<IFormFile> files)
[Authorize(FileManagementPermissions.FileManagement.Upload)]
public async Task UploadAsync(List<IFormFile> files)
{
var result = new List<UploadOutput>();
foreach (var formFile in files)
{
try
{
var item = new UploadOutput();
// 获取文件的二进制数据
using var memoryStream = new MemoryStream();
await formFile.CopyToAsync(memoryStream);
var fileBytes = memoryStream.ToArray();
// 这里可以对 fileBytes 进行后续处理,例如保存到数据库或文件系统等
// 示例:将文件保存到数据库
var updateResult = await _fileProvider.UploadAsync(new UpdateDto()
{
FileName = formFile.FileName,
Bytes = fileBytes,
ContentType = formFile.ContentType,
FileSize = formFile.Length
});
result.Add(new UploadOutput()
{
Id = updateResult.Id,
Name = updateResult.FileName,
Path = updateResult.FilePath,
Success = true
});
}
catch (Exception e)
{
Logger.LogError(e, "上传文件失败");
result.Add(new UploadOutput()
{
Id = Guid.Empty,
Name = formFile.FileName,
Path = string.Empty,
Success = false
});
}
// 获取文件的二进制数据
using var memoryStream = new MemoryStream();
await formFile.CopyToAsync(memoryStream);
var fileBytes = memoryStream.ToArray();
await _fileManager.CreateAsync(GuidGenerator.Create(), formFile.FileName, formFile.Length, formFile.ContentType, fileBytes, true);
}
return result;
}
/// <summary>
/// 删除文件
/// </summary>
[Authorize(FileManagementPermissions.FileManagement.Delete)]
public Task DeleteAsync(DeleteFileObjectInput input)
{
return _fileObjectManager.DeleteAsync(input.Id);
}
public async Task<GetFileObjectOutput> GetAsync(GetFileObjectInput input)
{
var file = await _fileObjectManager.GetAsync(input.Id);
return ObjectMapper.Map<FileObjectDto, GetFileObjectOutput>(file);
return _fileManager.DeleteAsync(input.Id);
}
public async Task<FileContentResult> DownloadAsync(DownloadFileObjectInput input)
[Authorize(FileManagementPermissions.FileManagement.Download)]
public async Task<RemoteStreamContent> DownloadAsync(DownloadFileObjectInput input)
{
var file = await _fileObjectManager.GetAsync(input.Id);
return new Microsoft.AspNetCore.Mvc.FileContentResult(file.Bytes, file.ContentType);
var fileObject = await _fileObjectManager.GetAsync(input.Id);
var file = await _blobContainer.GetAsync(input.Id.ToString());
return new RemoteStreamContent(file, fileObject.FileName, fileObject.ContentType);
}
}

3
aspnet-core/modules/FileManagement/src/Lion.AbpPro.FileManagement.Application/GlobalUsings.cs

@ -6,10 +6,13 @@ global using AutoMapper;
global using Lion.AbpPro.FileManagement.Localization;
global using Lion.AbpPro.FileManagement.Permissions;
global using Microsoft.AspNetCore.Authorization;
global using Microsoft.AspNetCore.Http;
global using Microsoft.Extensions.Configuration;
global using Microsoft.Extensions.DependencyInjection;
global using Volo.Abp.Application;
global using Volo.Abp.Application.Dtos;
global using Volo.Abp.Application.Services;
global using Volo.Abp.AutoMapper;
global using Volo.Abp.BlobStoring;
global using Volo.Abp.Content;
global using Volo.Abp.Modularity;

15
aspnet-core/modules/FileManagement/src/Lion.AbpPro.FileManagement.Domain.Shared/FileManagementConsts.cs

@ -0,0 +1,15 @@
namespace Lion.AbpPro.FileManagement
{
public class FileManagementConsts
{
/// <summary>名称空间</summary>
public const string NameSpace = "Lion.AbpPro.FileManagement";
/// <summary>默认语言</summary>
public const string DefaultCultureName = "zh-Hans";
public const int Kilobyte = 1024;
public const int Megabyte = Kilobyte * 1024;
public const long Gigabyte = Megabyte * 1024;
public const long Terabyte = Gigabyte * 1024;
}
}

4
aspnet-core/modules/FileManagement/src/Lion.AbpPro.FileManagement.Domain.Shared/FileManagementDomainSharedModule.cs

@ -15,11 +15,11 @@ public class FileManagementDomainSharedModule : AbpModule
Configure<AbpLocalizationOptions>(options =>
{
options.Resources
.Add<FileManagementResource>("en")
.Add<FileManagementResource>(FileManagementConsts.DefaultCultureName)
.AddBaseTypes(typeof(AbpValidationResource))
.AddVirtualJson("/Localization/FileManagement");
});
Configure<AbpExceptionLocalizationOptions>(options => { options.MapCodeNamespace("FileManagement", typeof(FileManagementResource)); });
Configure<AbpExceptionLocalizationOptions>(options => { options.MapCodeNamespace(FileManagementConsts.NameSpace, typeof(FileManagementResource)); });
}
}

4
aspnet-core/modules/FileManagement/src/Lion.AbpPro.FileManagement.Domain.Shared/FileManagementErrorCodes.cs

@ -2,5 +2,7 @@ namespace Lion.AbpPro.FileManagement;
public static class FileManagementErrorCodes
{
//Add your business exception error codes here...
public const string FileAlreadyExist = FileManagementConsts.NameSpace + ":100001";
public const string FileNotFound = FileManagementConsts.NameSpace + ":100002";
}

19
aspnet-core/modules/FileManagement/src/Lion.AbpPro.FileManagement.Domain.Shared/Files/FileObjectDto.cs

@ -3,7 +3,7 @@ namespace Lion.AbpPro.FileManagement.Files;
/// <summary>
/// 文件
/// </summary>
public class FileObjectDto
public class FileObjectDto
{
/// <summary>
/// 主键Id
@ -13,29 +13,18 @@ public class FileObjectDto
/// <summary>
/// 创建时间
/// </summary>
public DateTime CreationTime { get; set; }
public DateTime CreationTime { get; set; }
/// <summary>
/// 文件Provider
/// </summary>
public string ProviderKey { get; set; }
/// <summary>
/// 文件扩展名
/// </summary>
public string FileExtension { get; set; }
/// <summary>
/// 二进制数据
/// </summary>
public byte[] Bytes { get; set; }
/// <summary>
/// 文件大小
/// </summary>
public long FileSize { get; set; }
/// <summary>
/// 文件名称
/// </summary>
public string ContentType { get; set; }
/// <summary>
/// 文件名称
/// </summary>

45
aspnet-core/modules/FileManagement/src/Lion.AbpPro.FileManagement.Domain.Shared/Files/SizeHelper.cs

@ -0,0 +1,45 @@
namespace Lion.AbpPro.FileManagement.Files;
public static class SizeHelper
{
public static string BeautifySize(long size)
{
if (size == 0 || size == 1)
{
return $"{size} Byte";
}
if (size >= FileManagementConsts.Terabyte)
{
var fixedSize = ((float)size / (float)FileManagementConsts.Terabyte);
return $"{FormatSize(fixedSize)} TB";
}
if (size >= FileManagementConsts.Gigabyte)
{
var fixedSize = ((float)size / (float)FileManagementConsts.Gigabyte);
return $"{FormatSize(fixedSize)} GB";
}
if (size >= FileManagementConsts.Megabyte)
{
var fixedSize = ((float)size / (float)FileManagementConsts.Megabyte);
return $"{FormatSize(fixedSize)} MB";
}
if (size >= FileManagementConsts.Kilobyte)
{
var fixedSize = ((float)size / (float)FileManagementConsts.Kilobyte);
return $"{FormatSize(fixedSize)} KB";
}
return $"{size} B";
}
public static string FormatSize(float size)
{
var s = $"{size:0.00}";
return s.EndsWith("00") ? ((int)size).ToString() : s;
}
}

8
aspnet-core/modules/FileManagement/src/Lion.AbpPro.FileManagement.Domain.Shared/Localization/FileManagement/en.json

@ -4,7 +4,11 @@
"MyAccount": "My account",
"SamplePageMessage": "A sample page for the FileManagement module",
"Permission:FileManagement": "FileManagement",
"Permission:Upload": "Upload",
"Permission:Down": "Down"
"Permission:FileManagement:File": "FileManagement",
"Permission:FileManagement:File:Upload": "Upload",
"Permission:FileManagement:File:Download": "Download",
"Permission:FileManagement:File:Delete": "Delete",
"FileManagement:100001": "FileAlreadyExist",
"FileManagement:100002": "FileNotFound"
}
}

8
aspnet-core/modules/FileManagement/src/Lion.AbpPro.FileManagement.Domain.Shared/Localization/FileManagement/zh-Hans.json

@ -4,7 +4,11 @@
"MyAccount": "我的账户",
"SamplePageMessage": "FileManagement模块的示例页面",
"Permission:FileManagement": "文件管理",
"Permission:Upload": "上传",
"Permission:Down": "下载"
"Permission:FileManagement:File": "文件管理",
"Permission:FileManagement:File:Upload": "上传",
"Permission:FileManagement:File:Download": "下载",
"Permission:FileManagement:File:Delete": "删除",
"FileManagement:100001": "文件已经存在",
"FileManagement:100002": "文件未找到"
}
}

3
aspnet-core/modules/FileManagement/src/Lion.AbpPro.FileManagement.Domain/FileManagementDomainModule.cs

@ -5,7 +5,8 @@ namespace Lion.AbpPro.FileManagement;
[DependsOn(
typeof(AbpDddDomainModule),
typeof(AbpAutoMapperModule),
typeof(FileManagementDomainSharedModule)
typeof(FileManagementDomainSharedModule),
typeof(AbpBlobStoringModule)
)]
public class FileManagementDomainModule : AbpModule
{

6
aspnet-core/modules/FileManagement/src/Lion.AbpPro.FileManagement.Domain/Files/AbpProFileManagementContainer.cs

@ -0,0 +1,6 @@
namespace Lion.AbpPro.FileManagement.Files;
[BlobContainerName("abp-file-management")]
public class AbpProFileManagementContainer
{
}

13
aspnet-core/modules/FileManagement/src/Lion.AbpPro.FileManagement.Domain/Files/DomainFileManagementException.cs

@ -0,0 +1,13 @@
namespace Lion.AbpPro.FileManagement.Files
{
public class DomainFileManagementException : BusinessException
{
public DomainFileManagementException(string code = null, string message = null, string details = null, Exception innerException = null,
LogLevel logLevel = LogLevel.Warning) : base(code, message, details,
innerException,
logLevel
)
{
}
}
}

39
aspnet-core/modules/FileManagement/src/Lion.AbpPro.FileManagement.Domain/Files/FileManager.cs

@ -0,0 +1,39 @@
namespace Lion.AbpPro.FileManagement.Files;
public class FileManager : DomainService
{
private readonly IBlobContainer<AbpProFileManagementContainer> _blobContainer;
private readonly FileObjectManager _fileObjectManager;
public FileManager(IBlobContainer<AbpProFileManagementContainer> blobContainer, FileObjectManager fileObjectManager)
{
_blobContainer = blobContainer;
_fileObjectManager = fileObjectManager;
}
/// <summary>
/// 创建文件
/// </summary>
public virtual async Task<FileObjectDto> CreateAsync(
Guid id,
string fileName,
long fileSize,
string contentType,
byte[] content,
bool overwrite = false
)
{
var entity = await _fileObjectManager.CreateAsync(id, fileName, fileSize, contentType, content, overwrite);
await _blobContainer.SaveAsync(id.ToString(), content, true);
return entity;
}
/// <summary>
/// 删除文件
/// </summary>
public virtual async Task DeleteAsync(Guid id)
{
await _fileObjectManager.DeleteAsync(id);
await _blobContainer.DeleteAsync(id.ToString());
}
}

67
aspnet-core/modules/FileManagement/src/Lion.AbpPro.FileManagement.Domain/Files/FileObject.cs

@ -1,3 +1,4 @@
using JetBrains.Annotations;
using Lion.AbpPro.Core;
namespace Lion.AbpPro.FileManagement.Files;
@ -7,20 +8,14 @@ namespace Lion.AbpPro.FileManagement.Files;
/// </summary>
public class FileObject : FullAuditedAggregateRoot<Guid>, IMultiTenant
{
public FileObject(
Guid id,
string providerKey,
byte[] bytes,
string fileName,
long fileSize,
string contentType,
string fileName,
Guid? tenantId = null
) : base(id)
{
SetProviderKey(providerKey);
SetBytes(bytes);
SetFileSize(fileSize);
SetContentType(contentType);
SetFileName(fileName);
@ -34,70 +29,27 @@ public class FileObject : FullAuditedAggregateRoot<Guid>, IMultiTenant
/// </summary>
public string FileName { get; private set; }
/// <summary>
/// 文件名称
/// </summary>
public string ContentType { get; private set; }
/// <summary>
/// 文件大小
/// </summary>
public long FileSize { get; private set; }
/// <summary>
/// 文件扩展名
/// </summary>
public string FileExtension { get; private set; }
/// <summary>
/// 二进制数据
/// 文件类型
/// </summary>
public byte[] Bytes { get; private set; }
/// <summary>
/// 文件Provider
/// </summary>
public string ProviderKey { get; private set; }
/// <summary>
/// 设置文件Provider
/// </summary>
private void SetProviderKey(string providerKey)
{
Guard.NotNullOrWhiteSpace(providerKey, nameof(providerKey), 128, 0);
ProviderKey = providerKey;
}
/// <summary>
/// 设置文件扩展名
/// </summary>
private void SetFileExtension(string fileExtension)
{
Guard.NotNullOrWhiteSpace(fileExtension, nameof(fileExtension), 36, 0);
FileExtension = fileExtension;
}
public string ContentType { get; private set; }
/// <summary>
/// 设置二进制数据
/// </summary>
private void SetBytes(byte[] bytes)
{
Bytes = bytes;
}
/// <summary>
/// 设置文件大小
/// </summary>
private void SetFileSize(long fileSize)
public void SetFileSize(long fileSize)
{
FileSize = fileSize;
}
/// <summary>
/// 设置文件名称
/// 设置文件类型
/// </summary>
private void SetContentType(string contentType)
{
@ -111,7 +63,6 @@ public class FileObject : FullAuditedAggregateRoot<Guid>, IMultiTenant
private void SetFileName(string fileName)
{
Guard.NotNullOrWhiteSpace(fileName, nameof(fileName), 128, 0);
SetFileExtension(Path.GetExtension(fileName));
FileName = fileName;
}
@ -119,17 +70,11 @@ public class FileObject : FullAuditedAggregateRoot<Guid>, IMultiTenant
/// 更新文件
/// </summary>
public void Update(
string providerKey,
string fileExtension,
byte[] bytes,
long fileSize,
string contentType,
string fileName
)
{
SetProviderKey(providerKey);
SetFileExtension(fileExtension);
SetBytes(bytes);
SetFileSize(fileSize);
SetContentType(contentType);
SetFileName(fileName);

38
aspnet-core/modules/FileManagement/src/Lion.AbpPro.FileManagement.Domain/Files/FileObjectManager.cs

@ -8,16 +8,19 @@ public class FileObjectManager : DomainService
private readonly IObjectMapper _objectMapper;
private readonly ICurrentTenant _currentTenant;
public FileObjectManager(IFileObjectRepository iIFileObjectRepository, IObjectMapper objectMapper, ICurrentTenant currentTenant)
public FileObjectManager(IFileObjectRepository fileObjectRepository,
IObjectMapper objectMapper,
ICurrentTenant currentTenant)
{
_fileObjectRepository = iIFileObjectRepository;
_fileObjectRepository = fileObjectRepository;
_objectMapper = objectMapper;
_currentTenant = currentTenant;
}
public async Task<List<FileObjectDto>> GetListAsync(string fileName, DateTime? startDateTime = null, DateTime? endDateTime = null, int maxResultCount = 10, int skipCount = 0)
{
return await _fileObjectRepository.GetListAsync(fileName, startDateTime, endDateTime, maxResultCount, skipCount);
var list = await _fileObjectRepository.GetListAsync(fileName, startDateTime, endDateTime, maxResultCount, skipCount);
return _objectMapper.Map<List<FileObject>, List<FileObjectDto>>(list);
}
public async Task<long> GetCountAsync(string fileName, DateTime? startDateTime = null, DateTime? endDateTime = null)
@ -31,14 +34,29 @@ public class FileObjectManager : DomainService
public async Task<FileObjectDto> CreateAsync(
Guid id,
string fileName,
byte[] bytes,
long fileSize,
string contentType,
string providerKey
byte[] content,
bool overwrite = false
)
{
var entity = new FileObject(id, providerKey, bytes, fileSize, contentType, fileName, _currentTenant.Id);
entity = await _fileObjectRepository.InsertAsync(entity);
var entity = await _fileObjectRepository.FindAsync(fileName);
if (entity != null)
{
if (!overwrite)
{
throw new DomainFileManagementException(FileManagementErrorCodes.FileAlreadyExist);
}
entity.SetFileSize(fileSize);
await _fileObjectRepository.UpdateAsync(entity);
}
else
{
entity = new FileObject(id, fileName, fileSize, contentType);
await _fileObjectRepository.InsertAsync(entity);
}
return _objectMapper.Map<FileObject, FileObjectDto>(entity);
}
@ -49,17 +67,17 @@ public class FileObjectManager : DomainService
public async Task DeleteAsync(Guid id)
{
var entity = await _fileObjectRepository.FindAsync(id);
if (entity == null) throw new UserFriendlyException($"文件不存在");
if (entity == null) throw new DomainFileManagementException(FileManagementErrorCodes.FileNotFound);
await _fileObjectRepository.DeleteAsync(entity);
}
/// <summary>
/// 删除文件
/// 获取文件
/// </summary>
public async Task<FileObjectDto> GetAsync(Guid id)
{
var entity = await _fileObjectRepository.FindAsync(id);
if (entity == null) throw new UserFriendlyException($"文件不存在");
if (entity == null) throw new DomainFileManagementException(FileManagementErrorCodes.FileNotFound);
return _objectMapper.Map<FileObject, FileObjectDto>(entity);
}
}

5
aspnet-core/modules/FileManagement/src/Lion.AbpPro.FileManagement.Domain/Files/IFileObjectRepository.cs

@ -2,7 +2,10 @@ namespace Lion.AbpPro.FileManagement.Files;
public interface IFileObjectRepository : IBasicRepository<FileObject, Guid>
{
Task<List<FileObjectDto>> GetListAsync(string fileName, DateTime? startDateTime = null, DateTime? endDateTime = null, int maxResultCount = 10, int skipCount = 0);
Task<List<FileObject>> GetListAsync(string fileName, DateTime? startDateTime = null, DateTime? endDateTime = null, int maxResultCount = 10, int skipCount = 0);
Task<long> GetCountAsync(string fileName, DateTime? startDateTime = null, DateTime? endDateTime = null);
Task<FileObject> FindAsync(string fileName);
}

2
aspnet-core/modules/FileManagement/src/Lion.AbpPro.FileManagement.Domain/GlobalUsings.cs

@ -6,11 +6,13 @@ global using System.Diagnostics;
global using System.IO;
global using System.Linq;
global using System.Runtime.InteropServices;
global using System.Runtime.Serialization;
global using System.Threading;
global using System.Threading.Tasks;
global using Microsoft.Extensions.Logging;
global using Microsoft.Extensions.Logging.Abstractions;
global using Volo.Abp;
global using Volo.Abp.BlobStoring;
global using Volo.Abp.Data;
global using Volo.Abp.DependencyInjection;
global using Volo.Abp.Domain;

7
aspnet-core/modules/FileManagement/src/Lion.AbpPro.FileManagement.Domain/Lion.AbpPro.FileManagement.Domain.csproj

@ -7,9 +7,10 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Volo.Abp.Ddd.Domain" />
<PackageReference Include="Volo.Abp.AutoMapper" />
<ProjectReference Include="..\Lion.AbpPro.FileManagement.Domain.Shared\Lion.AbpPro.FileManagement.Domain.Shared.csproj" />
<PackageReference Include="Volo.Abp.Ddd.Domain"/>
<PackageReference Include="Volo.Abp.AutoMapper"/>
<PackageReference Include="Volo.Abp.BlobStoring"/>
<ProjectReference Include="..\Lion.AbpPro.FileManagement.Domain.Shared\Lion.AbpPro.FileManagement.Domain.Shared.csproj"/>
</ItemGroup>
</Project>

30
aspnet-core/modules/FileManagement/src/Lion.AbpPro.FileManagement.Domain/Provider/DatabaseFileProvider.cs

@ -1,30 +0,0 @@
using Lion.AbpPro.FileManagement.Files;
using Volo.Abp.Guids;
namespace Lion.AbpPro.FileManagement.Provider;
public class DatabaseFileProvider : IFileProvider, ITransientDependency
{
public const string Name = nameof(DatabaseFileProvider);
private readonly FileObjectManager _fileObjectManager;
private readonly IGuidGenerator _guidGenerator;
public DatabaseFileProvider(FileObjectManager fileObjectManager, IGuidGenerator guidGenerator)
{
_fileObjectManager = fileObjectManager;
_guidGenerator = guidGenerator;
}
public async Task<UpdateResult> UploadAsync(UpdateDto input)
{
var id = _guidGenerator.Create();
var fileName = id + "_" + input.FileName;
await _fileObjectManager.CreateAsync(id, fileName, input.Bytes, input.FileSize, input.ContentType, Name);
return new UpdateResult()
{
Id = id,
FileName = fileName,
FilePath = fileName
};
}
}

6
aspnet-core/modules/FileManagement/src/Lion.AbpPro.FileManagement.Domain/Provider/IFileProvider.cs

@ -1,6 +0,0 @@
namespace Lion.AbpPro.FileManagement.Provider;
public interface IFileProvider
{
Task<UpdateResult> UploadAsync(UpdateDto input);
}

3
aspnet-core/modules/FileManagement/src/Lion.AbpPro.FileManagement.EntityFrameworkCore/EntityFrameworkCore/FileManagementDbContextModelCreatingExtensions.cs

@ -11,9 +11,6 @@ public static class FileManagementDbContextModelCreatingExtensions
builder.Entity<FileObject>(b =>
{
b.ToTable(FileManagementDbProperties.DbTablePrefix + "FileObjects");
b.Property(e => e.ProviderKey).IsRequired().HasMaxLength(128).HasComment("文件Provider");
b.Property(e => e.FileExtension).IsRequired().HasMaxLength(36).HasComment("文件扩展名");
b.Property(e => e.Bytes).HasComment("二进制数据");
b.Property(e => e.FileSize).HasComment("文件大小");
b.Property(e => e.ContentType).IsRequired().HasMaxLength(128).HasComment("文件名称");
b.Property(e => e.FileName).IsRequired().HasMaxLength(128).HasComment("文件名称");

24
aspnet-core/modules/FileManagement/src/Lion.AbpPro.FileManagement.EntityFrameworkCore/EntityFrameworkCore/Files/EfCoreFileObjectRepository.cs

@ -8,7 +8,7 @@ namespace Lion.AbpPro.FileManagement.EntityFrameworkCore.Files;
/// <summary>
/// 文件 仓储Ef core 实现
/// </summary>
public class EfCoreFileObjectRepository :
public class EfCoreFileObjectRepository :
EfCoreRepository<FileManagementDbContext, FileObject, Guid>,
IFileObjectRepository
{
@ -16,34 +16,28 @@ public class EfCoreFileObjectRepository :
{
}
public async Task<List<FileObjectDto>> GetListAsync(string fileName, DateTime? startDateTime = null, DateTime? endDateTime = null,int maxResultCount = 10, int skipCount = 0)
public async Task<List<FileObject>> GetListAsync(string fileName, DateTime? startDateTime = null, DateTime? endDateTime = null, int maxResultCount = 10, int skipCount = 0)
{
return await (await GetDbSetAsync())
.WhereIf(fileName.IsNotNullOrWhiteSpace(),e=>e.FileName.Contains(fileName))
.WhereIf(fileName.IsNotNullOrWhiteSpace(), e => e.FileName.Contains(fileName))
.WhereIf(startDateTime.HasValue, e => e.CreationTime >= startDateTime.Value)
.WhereIf(endDateTime.HasValue, e => e.CreationTime <= endDateTime.Value)
.OrderByDescending(e => e.CreationTime)
.PageBy(skipCount, maxResultCount)
.Select(e => new FileObjectDto
{
Id = e.Id,
CreationTime = e.CreationTime,
FileName = e.FileName,
FileSize = e.FileSize,
FileExtension = e.FileExtension,
ContentType = e.ContentType,
ProviderKey = e.ProviderKey
}) // 选择指定字段
.ToListAsync();
}
public async Task<long> GetCountAsync(string fileName, DateTime? startDateTime = null, DateTime? endDateTime = null)
{
return await (await GetDbSetAsync())
.WhereIf(fileName.IsNotNullOrWhiteSpace(),e=>e.FileName.Contains(fileName))
.WhereIf(fileName.IsNotNullOrWhiteSpace(), e => e.FileName.Contains(fileName))
.WhereIf(startDateTime.HasValue, e => e.CreationTime >= startDateTime.Value)
.WhereIf(endDateTime.HasValue, e => e.CreationTime <= endDateTime.Value)
.CountAsync();
}
public async Task<FileObject> FindAsync(string fileName)
{
return await (await GetDbSetAsync()).FirstOrDefaultAsync(e => e.FileName == fileName);
}
}

13
aspnet-core/modules/FileManagement/src/Lion.AbpPro.FileManagement.HttpApi/Files/FileController.cs

@ -1,4 +1,5 @@
using Microsoft.AspNetCore.Http;
using Volo.Abp.Content;
namespace Lion.AbpPro.FileManagement.Files;
@ -21,9 +22,9 @@ public class FileController : AbpController, IFileAppService
[HttpPost("Upload")]
[SwaggerOperation(summary: "上传文件", Tags = new[] { "Files" })]
public async Task<List<UploadOutput>> UploadAsync(List<IFormFile> files)
public async Task UploadAsync(List<IFormFile> files)
{
return await _fileAppService.UploadAsync(files);
await _fileAppService.UploadAsync(files);
}
@ -34,16 +35,10 @@ public class FileController : AbpController, IFileAppService
await _fileAppService.DeleteAsync(input);
}
[HttpPost("Get")]
[SwaggerOperation(summary: "获取文件", Tags = new[] { "Files" })]
public Task<GetFileObjectOutput> GetAsync(GetFileObjectInput input)
{
return _fileAppService.GetAsync(input);
}
[HttpPost("Download")]
[SwaggerOperation(summary: "下载文件", Tags = new[] { "Files" })]
public Task<FileContentResult> DownloadAsync(DownloadFileObjectInput input)
public Task<RemoteStreamContent> DownloadAsync(DownloadFileObjectInput input)
{
return _fileAppService.DownloadAsync(input);
}

19
aspnet-core/services/host/Lion.AbpPro.HttpApi.Host/AbpProHttpApiHostModule.Configure.cs

@ -1,5 +1,7 @@
using Medallion.Threading;
using Medallion.Threading.Redis;
using Volo.Abp.BlobStoring;
using Volo.Abp.BlobStoring.FileSystem;
namespace Lion.AbpPro;
@ -287,4 +289,21 @@ public partial class AbpProHttpApiHostModule
return new RedisDistributedSynchronizationProvider(connection.GetDatabase());
});
}
/// <summary>
/// 配置blob设置
/// </summary>
private void ConfigureBlobStorage()
{
Configure<AbpBlobStoringOptions>(options =>
{
options.Containers.ConfigureDefault(container =>
{
container.UseFileSystem(fileSystem =>
{
fileSystem.BasePath = "C:\\my-files";
});
});
});
}
}

5
aspnet-core/services/host/Lion.AbpPro.HttpApi.Host/AbpProHttpApiHostModule.cs

@ -1,3 +1,4 @@
using Volo.Abp.BlobStoring.FileSystem;
using Volo.Abp.DistributedLocking;
namespace Lion.AbpPro
@ -15,7 +16,8 @@ namespace Lion.AbpPro
typeof(AbpProCapEntityFrameworkCoreModule),
typeof(AbpAspNetCoreMvcUiBasicThemeModule),
typeof(AbpCachingStackExchangeRedisModule),
typeof(AbpDistributedLockingModule)
typeof(AbpDistributedLockingModule),
typeof(AbpBlobStoringFileSystemModule)
//typeof(AbpBackgroundJobsHangfireModule)
)]
public partial class AbpProHttpApiHostModule : AbpModule
@ -41,6 +43,7 @@ namespace Lion.AbpPro
ConfigureAuditLog(context);
ConfigurationSignalR(context);
ConfigurationMultiTenancy();
ConfigureBlobStorage();
}
public override void OnApplicationInitialization(ApplicationInitializationContext context)

1
aspnet-core/services/host/Lion.AbpPro.HttpApi.Host/Lion.AbpPro.HttpApi.Host.csproj

@ -42,6 +42,7 @@
<PackageReference Include="Volo.Abp.BackgroundJobs.HangFire" />
<PackageReference Include="Volo.Abp.DistributedLocking"/>
<PackageReference Include="DistributedLock.Redis"/>
<PackageReference Include="Volo.Abp.BlobStoring.FileSystem" />
</ItemGroup>
<ItemGroup>

6
aspnet-core/services/host/Lion.AbpPro.HttpApi.Host/appsettings.json

@ -34,16 +34,16 @@
"CorsOrigins": "https://*.AbpPro.com,http://localhost:4200,http://localhost:3100"
},
"ConnectionStrings": {
"Default": "Data Source=localhost;Port=3306;Database=LionAbpPro9;uid=root;pwd=1q2w3E*;charset=utf8mb4;Allow User Variables=true;AllowLoadLocalInfile=true"
"Default": "Data Source=localhost;Port=3306;Database=LionAbpPro91;uid=root;pwd=1q2w3E*;charset=utf8mb4;Allow User Variables=true;AllowLoadLocalInfile=true"
},
"Hangfire": {
"Redis": {
"Host": "localhost:localhost,password=1q2w3E*",
"DB": "2"
"DB": "3"
}
},
"Redis": {
"Configuration": "localhost:6379,password=1q2w3E*,defaultdatabase=5"
"Configuration": "localhost:6379,password=1q2w3E*,defaultdatabase=3"
},
"Jwt": {
"Audience": "Lion.AbpPro",

2
aspnet-core/services/src/Lion.AbpPro.DbMigrator/appsettings.json

@ -1,5 +1,5 @@
{
"ConnectionStrings": {
"Default": "Data Source=localhost;Port=3306;Database=LionAbpPro9;uid=root;pwd=1q2w3E*;charset=utf8mb4;Allow User Variables=true;AllowLoadLocalInfile=true"
"Default": "Data Source=localhost;Port=3306;Database=LionAbpPro91;uid=root;pwd=1q2w3E*;charset=utf8mb4;Allow User Variables=true;AllowLoadLocalInfile=true"
}
}

2163
aspnet-core/services/src/Lion.AbpPro.EntityFrameworkCore/Migrations/20250219151836_1.0.3.Designer.cs

File diff suppressed because it is too large

57
aspnet-core/services/src/Lion.AbpPro.EntityFrameworkCore/Migrations/20250219151836_1.0.3.cs

@ -0,0 +1,57 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace Lion.AbpPro.Migrations
{
/// <inheritdoc />
public partial class _103 : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "Bytes",
table: "AbpFileObjects");
migrationBuilder.DropColumn(
name: "FileExtension",
table: "AbpFileObjects");
migrationBuilder.DropColumn(
name: "ProviderKey",
table: "AbpFileObjects");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<byte[]>(
name: "Bytes",
table: "AbpFileObjects",
type: "longblob",
nullable: true,
comment: "二进制数据");
migrationBuilder.AddColumn<string>(
name: "FileExtension",
table: "AbpFileObjects",
type: "varchar(36)",
maxLength: 36,
nullable: false,
defaultValue: "",
comment: "文件扩展名")
.Annotation("MySql:CharSet", "utf8mb4");
migrationBuilder.AddColumn<string>(
name: "ProviderKey",
table: "AbpFileObjects",
type: "varchar(128)",
maxLength: 128,
nullable: false,
defaultValue: "",
comment: "文件Provider")
.Annotation("MySql:CharSet", "utf8mb4");
}
}
}

16
aspnet-core/services/src/Lion.AbpPro.EntityFrameworkCore/Migrations/AbpProDbContextModelSnapshot.cs

@ -146,10 +146,6 @@ namespace Lion.AbpPro.Migrations
b.Property<Guid>("Id")
.HasColumnType("char(36)");
b.Property<byte[]>("Bytes")
.HasColumnType("longblob")
.HasComment("二进制数据");
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken()
.IsRequired()
@ -184,12 +180,6 @@ namespace Lion.AbpPro.Migrations
.HasColumnType("longtext")
.HasColumnName("ExtraProperties");
b.Property<string>("FileExtension")
.IsRequired()
.HasMaxLength(36)
.HasColumnType("varchar(36)")
.HasComment("文件扩展名");
b.Property<string>("FileName")
.IsRequired()
.HasMaxLength(128)
@ -214,12 +204,6 @@ namespace Lion.AbpPro.Migrations
.HasColumnType("char(36)")
.HasColumnName("LastModifierId");
b.Property<string>("ProviderKey")
.IsRequired()
.HasMaxLength(128)
.HasColumnType("varchar(128)")
.HasComment("文件Provider");
b.Property<Guid?>("TenantId")
.HasColumnType("char(36)")
.HasColumnName("TenantId");

Loading…
Cancel
Save