committed by
GitHub
124 changed files with 4324 additions and 2040 deletions
@ -1,7 +1,8 @@ |
|||
{ |
|||
"profiles": { |
|||
"LINGYUN.Abp.Cli": { |
|||
"commandName": "Project" |
|||
"commandName": "Project", |
|||
"commandLineArgs": "help create" |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,12 @@ |
|||
{ |
|||
"profiles": { |
|||
"LINGYUN.Abp.OssManagement.Tencent": { |
|||
"commandName": "Project", |
|||
"launchBrowser": true, |
|||
"environmentVariables": { |
|||
"ASPNETCORE_ENVIRONMENT": "Development" |
|||
}, |
|||
"applicationUrl": "https://localhost:58740;http://localhost:58741" |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,11 @@ |
|||
using System.ComponentModel.DataAnnotations; |
|||
using Volo.Abp.Validation; |
|||
|
|||
namespace LINGYUN.Platform.Packages; |
|||
|
|||
public class PackageBlobDownloadInput |
|||
{ |
|||
[Required] |
|||
[DynamicMaxLength(typeof(PackageBlobConsts), nameof(PackageBlobConsts.MaxNameLength))] |
|||
public string Name { get; set; } |
|||
} |
|||
@ -0,0 +1,21 @@ |
|||
using System; |
|||
using Volo.Abp.Application.Dtos; |
|||
using Volo.Abp.Data; |
|||
|
|||
namespace LINGYUN.Platform.Packages; |
|||
|
|||
public class PackageBlobDto : CreationAuditedEntityDto<int>, IHasExtraProperties |
|||
{ |
|||
public string Name { get; set; } |
|||
public string Url { get; set; } |
|||
public long? Size { get; set; } |
|||
public string Summary { get; set; } |
|||
public DateTime CreatedAt { get; set; } |
|||
public DateTime? UpdatedAt { get; set; } |
|||
public string License { get; set; } |
|||
public string Authors { get; set; } |
|||
public string SHA256 { get; set; } |
|||
public string ContentType { get; set; } |
|||
public int DownloadCount { get; set; } |
|||
public ExtraPropertyDictionary ExtraProperties { get; set; } |
|||
} |
|||
@ -0,0 +1,11 @@ |
|||
using System.ComponentModel.DataAnnotations; |
|||
using Volo.Abp.Validation; |
|||
|
|||
namespace LINGYUN.Platform.Packages; |
|||
|
|||
public class PackageBlobRemoveDto |
|||
{ |
|||
[Required] |
|||
[DynamicMaxLength(typeof(PackageBlobConsts), nameof(PackageBlobConsts.MaxNameLength))] |
|||
public string Name { get; set; } |
|||
} |
|||
@ -0,0 +1,36 @@ |
|||
using System; |
|||
using System.ComponentModel.DataAnnotations; |
|||
using Volo.Abp.Auditing; |
|||
using Volo.Abp.Content; |
|||
using Volo.Abp.Validation; |
|||
|
|||
namespace LINGYUN.Platform.Packages; |
|||
|
|||
public class PackageBlobUploadDto |
|||
{ |
|||
[Required] |
|||
[DynamicMaxLength(typeof(PackageBlobConsts), nameof(PackageBlobConsts.MaxNameLength))] |
|||
public string Name { get; set; } |
|||
|
|||
public long? Size { get; set; } |
|||
|
|||
[DynamicMaxLength(typeof(PackageBlobConsts), nameof(PackageBlobConsts.MaxSummaryLength))] |
|||
public string Summary { get; set; } |
|||
|
|||
[DynamicMaxLength(typeof(PackageBlobConsts), nameof(PackageBlobConsts.MaxContentTypeLength))] |
|||
public string ContentType { get; set; } |
|||
|
|||
public DateTime CreatedAt { get; set; } |
|||
|
|||
public DateTime? UpdatedAt { get; set; } |
|||
|
|||
[DynamicMaxLength(typeof(PackageBlobConsts), nameof(PackageBlobConsts.MaxLicenseLength))] |
|||
public string License { get; set; } |
|||
|
|||
[DynamicMaxLength(typeof(PackageBlobConsts), nameof(PackageBlobConsts.MaxAuthorsLength))] |
|||
public string Authors { get; set; } |
|||
|
|||
[Required] |
|||
[DisableAuditing] |
|||
public IRemoteStreamContent File { get; set; } |
|||
} |
|||
@ -0,0 +1,19 @@ |
|||
using System.ComponentModel.DataAnnotations; |
|||
using Volo.Abp.Validation; |
|||
|
|||
namespace LINGYUN.Platform.Packages; |
|||
public class PackageCreateDto : PackageCreateOrUpdateDto |
|||
{ |
|||
/// <summary>
|
|||
/// 名称
|
|||
/// </summary>
|
|||
[Required] |
|||
[DynamicMaxLength(typeof(PackageConsts), nameof(PackageConsts.MaxNameLength))] |
|||
public string Name { get; set; } |
|||
/// <summary>
|
|||
/// 版本
|
|||
/// </summary>
|
|||
[Required] |
|||
[DynamicMaxLength(typeof(PackageConsts), nameof(PackageConsts.MaxVersionLength))] |
|||
public string Version { get; set; } |
|||
} |
|||
@ -0,0 +1,28 @@ |
|||
using System.ComponentModel.DataAnnotations; |
|||
using Volo.Abp.Validation; |
|||
|
|||
namespace LINGYUN.Platform.Packages; |
|||
|
|||
public abstract class PackageCreateOrUpdateDto |
|||
{ |
|||
/// <summary>
|
|||
/// 版本说明
|
|||
/// </summary>
|
|||
[Required] |
|||
[DynamicMaxLength(typeof(PackageConsts), nameof(PackageConsts.MaxNoteLength))] |
|||
public string Note { get; set; } |
|||
/// <summary>
|
|||
/// 描述
|
|||
/// </summary>
|
|||
[DynamicMaxLength(typeof(PackageConsts), nameof(PackageConsts.MaxDescriptionLength))] |
|||
public string Description { get; set; } |
|||
/// <summary>
|
|||
/// 强制更新
|
|||
/// </summary>
|
|||
public bool ForceUpdate { get; set; } |
|||
|
|||
[DynamicMaxLength(typeof(PackageConsts), nameof(PackageConsts.MaxAuthorsLength))] |
|||
public string Authors { get; set; } |
|||
|
|||
public PackageLevel Level { get; set; } |
|||
} |
|||
@ -0,0 +1,46 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using Volo.Abp.Application.Dtos; |
|||
using Volo.Abp.Domain.Entities; |
|||
|
|||
namespace LINGYUN.Platform.Packages; |
|||
|
|||
public class PackageDto : ExtensibleAuditedEntityDto<Guid>, IHasConcurrencyStamp |
|||
{ |
|||
public string ConcurrencyStamp { get; set; } |
|||
/// <summary>
|
|||
/// 名称
|
|||
/// </summary>
|
|||
public string Name { get; set; } |
|||
/// <summary>
|
|||
/// 版本说明
|
|||
/// </summary>
|
|||
public string Note { get; set; } |
|||
/// <summary>
|
|||
/// 版本
|
|||
/// </summary>
|
|||
public string Version { get; set; } |
|||
/// <summary>
|
|||
/// 描述
|
|||
/// </summary>
|
|||
public string Description { get; set; } |
|||
/// <summary>
|
|||
/// 强制更新
|
|||
/// </summary>
|
|||
public bool ForceUpdate { get; set; } |
|||
|
|||
public string Authors { get; set; } |
|||
|
|||
public PackageLevel Level { get; set; } |
|||
|
|||
public List<PackageBlobDto> Blobs { get; set; } = new List<PackageBlobDto>(); |
|||
|
|||
public static PackageDto None() |
|||
{ |
|||
return new PackageDto |
|||
{ |
|||
Level = PackageLevel.None, |
|||
Blobs = new List<PackageBlobDto>() |
|||
}; |
|||
} |
|||
} |
|||
@ -0,0 +1,11 @@ |
|||
using System.ComponentModel.DataAnnotations; |
|||
using Volo.Abp.Validation; |
|||
|
|||
namespace LINGYUN.Platform.Packages; |
|||
|
|||
public class PackageGetLatestInput |
|||
{ |
|||
[Required] |
|||
[DynamicMaxLength(typeof(PackageBlobConsts), nameof(PackageBlobConsts.MaxNameLength))] |
|||
public string Name { get; set; } |
|||
} |
|||
@ -0,0 +1,26 @@ |
|||
using Volo.Abp.Application.Dtos; |
|||
using Volo.Abp.Validation; |
|||
|
|||
namespace LINGYUN.Platform.Packages; |
|||
|
|||
public class PackageGetPagedListInput : PagedAndSortedResultRequestDto |
|||
{ |
|||
public string Filter { get; set; } |
|||
|
|||
[DynamicMaxLength(typeof(PackageConsts), nameof(PackageConsts.MaxNameLength))] |
|||
public string Name { get; set; } |
|||
|
|||
[DynamicMaxLength(typeof(PackageConsts), nameof(PackageConsts.MaxNoteLength))] |
|||
public string Note { get; set; } |
|||
|
|||
[DynamicMaxLength(typeof(PackageConsts), nameof(PackageConsts.MaxVersionLength))] |
|||
public string Version { get; set; } |
|||
|
|||
[DynamicMaxLength(typeof(PackageConsts), nameof(PackageConsts.MaxDescriptionLength))] |
|||
public string Description { get; set; } |
|||
|
|||
public bool? ForceUpdate { get; set; } |
|||
|
|||
[DynamicMaxLength(typeof(PackageConsts), nameof(PackageConsts.MaxAuthorsLength))] |
|||
public string Authors { get; set; } |
|||
} |
|||
@ -0,0 +1,8 @@ |
|||
using Volo.Abp.Domain.Entities; |
|||
|
|||
namespace LINGYUN.Platform.Packages; |
|||
|
|||
public class PackageUpdateDto : PackageCreateOrUpdateDto, IHasConcurrencyStamp |
|||
{ |
|||
public string ConcurrencyStamp { get; set; } |
|||
} |
|||
@ -0,0 +1,29 @@ |
|||
using System; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.Application.Services; |
|||
using Volo.Abp.Content; |
|||
|
|||
namespace LINGYUN.Platform.Packages; |
|||
|
|||
public interface IPackageAppService : |
|||
ICrudAppService< |
|||
PackageDto, |
|||
Guid, |
|||
PackageGetPagedListInput, |
|||
PackageCreateDto, |
|||
PackageUpdateDto> |
|||
{ |
|||
Task<PackageDto> GetLatestAsync(PackageGetLatestInput input); |
|||
|
|||
Task<PackageBlobDto> UploadBlobAsync( |
|||
Guid id, |
|||
PackageBlobUploadDto input); |
|||
|
|||
Task RemoveBlobAsync( |
|||
Guid id, |
|||
PackageBlobRemoveDto input); |
|||
|
|||
Task<IRemoteStreamContent> DownloadBlobAsync( |
|||
Guid id, |
|||
PackageBlobDownloadInput input); |
|||
} |
|||
@ -1,33 +0,0 @@ |
|||
using System.ComponentModel.DataAnnotations; |
|||
|
|||
namespace LINGYUN.Platform.Versions |
|||
{ |
|||
public class VersionCreateDto |
|||
{ |
|||
/// <summary>
|
|||
/// 标题
|
|||
/// </summary>
|
|||
[Required] |
|||
[StringLength(AppVersionConsts.MaxTitleLength)] |
|||
public string Title { get; set; } |
|||
/// <summary>
|
|||
/// 版本号
|
|||
/// </summary>
|
|||
[Required] |
|||
[StringLength(AppVersionConsts.MaxVersionLength)] |
|||
public string Version { get; set; } |
|||
/// <summary>
|
|||
/// 描述
|
|||
/// </summary>
|
|||
[StringLength(AppVersionConsts.MaxDescriptionLength)] |
|||
public string Description { get; set; } |
|||
/// <summary>
|
|||
/// 适应平台
|
|||
/// </summary>
|
|||
public PlatformType PlatformType { get; set; } = PlatformType.None; |
|||
/// <summary>
|
|||
/// 重要级别
|
|||
/// </summary>
|
|||
public ImportantLevel Level { get; set; } = ImportantLevel.Low; |
|||
} |
|||
} |
|||
@ -1,13 +0,0 @@ |
|||
using System.ComponentModel.DataAnnotations; |
|||
|
|||
namespace LINGYUN.Platform.Versions |
|||
{ |
|||
public class VersionDeleteDto |
|||
{ |
|||
[Required] |
|||
[StringLength(AppVersionConsts.MaxVersionLength)] |
|||
public string Version { get; set; } |
|||
|
|||
public PlatformType PlatformType { get; set; } |
|||
} |
|||
} |
|||
@ -1,34 +0,0 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using Volo.Abp.Application.Dtos; |
|||
|
|||
namespace LINGYUN.Platform.Versions |
|||
{ |
|||
public class VersionDto : EntityDto<Guid> |
|||
{ |
|||
/// <summary>
|
|||
/// 创建日期
|
|||
/// </summary>
|
|||
public DateTime CreationTime { get; set; } |
|||
/// <summary>
|
|||
/// 标题
|
|||
/// </summary>
|
|||
public string Title { get; set; } |
|||
/// <summary>
|
|||
/// 版本号
|
|||
/// </summary>
|
|||
public string Version { get; set; } |
|||
/// <summary>
|
|||
/// 描述
|
|||
/// </summary>
|
|||
public string Description { get; set; } |
|||
/// <summary>
|
|||
/// 重要级别
|
|||
/// </summary>
|
|||
public ImportantLevel Level { get; set; } |
|||
/// <summary>
|
|||
/// 文件列表
|
|||
/// </summary>
|
|||
public List<VersionFileDto> Files { get; set; } = new List<VersionFileDto>(); |
|||
} |
|||
} |
|||
@ -1,51 +0,0 @@ |
|||
using Newtonsoft.Json; |
|||
using System; |
|||
using System.ComponentModel.DataAnnotations; |
|||
|
|||
namespace LINGYUN.Platform.Versions |
|||
{ |
|||
public class VersionFileCreateDto |
|||
{ |
|||
[Required] |
|||
public Guid VersionId { get; set; } |
|||
|
|||
[Required] |
|||
[StringLength(AppVersionConsts.MaxVersionLength)] |
|||
public string Version { get; set; } |
|||
/// <summary>
|
|||
/// 文件路径
|
|||
/// </summary>
|
|||
[StringLength(VersionFileConsts.MaxPathLength)] |
|||
public string FilePath { get; set; } |
|||
/// <summary>
|
|||
/// 文件名称
|
|||
/// </summary>
|
|||
[Required] |
|||
[StringLength(VersionFileConsts.MaxNameLength)] |
|||
public string FileName { get; set; } |
|||
/// <summary>
|
|||
/// 文件版本
|
|||
/// </summary>
|
|||
[Required] |
|||
[StringLength(VersionFileConsts.MaxVersionLength)] |
|||
public string FileVersion { get; set; } |
|||
/// <summary>
|
|||
/// 当前字节数
|
|||
/// </summary>
|
|||
[Required] |
|||
public int CurrentByte { get; set; } |
|||
/// <summary>
|
|||
/// 最大字节数
|
|||
/// </summary>
|
|||
[Required] |
|||
public int TotalByte { get; set; } |
|||
/// <summary>
|
|||
/// 文件类型
|
|||
/// </summary>
|
|||
public FileType FileType { get; set; } |
|||
/// <summary>
|
|||
/// 文件指纹
|
|||
/// </summary>
|
|||
public string SHA256 { get; set; } |
|||
} |
|||
} |
|||
@ -1,15 +0,0 @@ |
|||
using System; |
|||
using System.ComponentModel.DataAnnotations; |
|||
|
|||
namespace LINGYUN.Platform.Versions |
|||
{ |
|||
public class VersionFileDeleteDto |
|||
{ |
|||
[Required] |
|||
public Guid VersionId { get; set; } |
|||
|
|||
[Required] |
|||
[StringLength(VersionFileConsts.MaxNameLength)] |
|||
public string FileName { get; set; } |
|||
} |
|||
} |
|||
@ -1,33 +0,0 @@ |
|||
using Newtonsoft.Json; |
|||
|
|||
namespace LINGYUN.Platform.Versions |
|||
{ |
|||
public class VersionFileDto |
|||
{ |
|||
/// <summary>
|
|||
/// 文件路径
|
|||
/// </summary>
|
|||
public string Path { get; set; } |
|||
/// <summary>
|
|||
/// 文件名称
|
|||
/// </summary>
|
|||
public string Name { get; set; } |
|||
/// <summary>
|
|||
/// 文件版本
|
|||
/// </summary>
|
|||
public string Version { get; set; } |
|||
/// <summary>
|
|||
/// 文件SHA256编码
|
|||
/// </summary>
|
|||
public string SHA256 { get; set; } |
|||
/// <summary>
|
|||
/// 文件大小
|
|||
/// 单位b
|
|||
/// </summary>
|
|||
public long Size { get; set; } |
|||
/// <summary>
|
|||
/// 文件类型
|
|||
/// </summary>
|
|||
public FileType FileType { get; set; } |
|||
} |
|||
} |
|||
@ -1,24 +0,0 @@ |
|||
using System.ComponentModel.DataAnnotations; |
|||
|
|||
namespace LINGYUN.Platform.Versions |
|||
{ |
|||
public class VersionFileGetDto |
|||
{ |
|||
public PlatformType PlatformType { get; set; } = PlatformType.None; |
|||
|
|||
[Required] |
|||
[StringLength(AppVersionConsts.MaxVersionLength)] |
|||
public string Version { get; set; } |
|||
|
|||
[StringLength(VersionFileConsts.MaxPathLength)] |
|||
public string FilePath { get; set; } |
|||
|
|||
[Required] |
|||
[StringLength(VersionFileConsts.MaxNameLength)] |
|||
public string FileName { get; set; } |
|||
|
|||
[Required] |
|||
[StringLength(VersionFileConsts.MaxVersionLength)] |
|||
public string FileVersion { get; set; } |
|||
} |
|||
} |
|||
@ -1,9 +0,0 @@ |
|||
using System; |
|||
using Volo.Abp.Application.Dtos; |
|||
|
|||
namespace LINGYUN.Platform.Versions |
|||
{ |
|||
public class VersionGetByIdDto : EntityDto<Guid> |
|||
{ |
|||
} |
|||
} |
|||
@ -1,10 +0,0 @@ |
|||
using Volo.Abp.Application.Dtos; |
|||
|
|||
namespace LINGYUN.Platform.Versions |
|||
{ |
|||
public class VersionGetByPagedDto : PagedAndSortedResultRequestDto |
|||
{ |
|||
public string Filter { get; set; } |
|||
public PlatformType PlatformType { get; set; } = PlatformType.None; |
|||
} |
|||
} |
|||
@ -1,27 +0,0 @@ |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.Application.Dtos; |
|||
using Volo.Abp.Application.Services; |
|||
|
|||
namespace LINGYUN.Platform.Versions |
|||
{ |
|||
public interface IVersionAppService : IApplicationService |
|||
{ |
|||
Task<VersionDto> GetLastestAsync(PlatformType platformType); |
|||
|
|||
Task<PagedResultDto<VersionDto>> GetAsync(VersionGetByPagedDto versionGetByPaged); |
|||
|
|||
Task<VersionDto> GetAsync(VersionGetByIdDto versionGetById); |
|||
|
|||
Task<VersionDto> CreateAsync(VersionCreateDto versionCreate); |
|||
|
|||
Task DeleteAsync(VersionDeleteDto versionDelete); |
|||
|
|||
Task AppendFileAsync(VersionFileCreateDto versionFileCreate); |
|||
|
|||
Task RemoveFileAsync(VersionFileDeleteDto versionFileDelete); |
|||
|
|||
Task RemoveAllFileAsync(VersionGetByIdDto versionGetById); |
|||
|
|||
Task DownloadFileAsync(VersionFileGetDto versionFileGet); |
|||
} |
|||
} |
|||
@ -0,0 +1,187 @@ |
|||
using LINGYUN.Platform.Permissions; |
|||
using Microsoft.AspNetCore.Authorization; |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp; |
|||
using Volo.Abp.Application.Dtos; |
|||
using Volo.Abp.Content; |
|||
using Volo.Abp.Data; |
|||
|
|||
namespace LINGYUN.Platform.Packages; |
|||
|
|||
public class PackageAppService : PlatformApplicationServiceBase, IPackageAppService |
|||
{ |
|||
private readonly IPackageBlobManager _blobManager; |
|||
private readonly IPackageRepository _packageRepository; |
|||
|
|||
public PackageAppService( |
|||
IPackageBlobManager blobManager, |
|||
IPackageRepository packageRepository) |
|||
{ |
|||
_blobManager = blobManager; |
|||
_packageRepository = packageRepository; |
|||
} |
|||
|
|||
public async virtual Task<PackageDto> GetLatestAsync(PackageGetLatestInput input) |
|||
{ |
|||
var package = await _packageRepository.FindLatestAsync(input.Name); |
|||
|
|||
return package == null ? PackageDto.None() : ObjectMapper.Map<Package, PackageDto>(package); |
|||
} |
|||
|
|||
[Authorize(PlatformPermissions.Package.Create)] |
|||
public async virtual Task<PackageDto> CreateAsync(PackageCreateDto input) |
|||
{ |
|||
var package = await _packageRepository.FindLatestAsync(input.Name); |
|||
if (package != null) |
|||
{ |
|||
if (string.Compare(input.Version, package.Version, StringComparison.CurrentCultureIgnoreCase) <= 0) |
|||
{ |
|||
throw new BusinessException(PlatformErrorCodes.PackageVersionDegraded) |
|||
.WithData(nameof(Package.Name), input.Name) |
|||
.WithData(nameof(Package.Version), input.Version); |
|||
} |
|||
} |
|||
|
|||
package = new Package( |
|||
GuidGenerator.Create(), |
|||
input.Name, |
|||
input.Note, |
|||
input.Version, |
|||
input.Description, |
|||
CurrentTenant.Id); |
|||
|
|||
UpdateByInput(package, input); |
|||
|
|||
package = await _packageRepository.InsertAsync(package); |
|||
|
|||
await CurrentUnitOfWork.SaveChangesAsync(); |
|||
|
|||
return ObjectMapper.Map<Package, PackageDto>(package); |
|||
} |
|||
|
|||
[Authorize(PlatformPermissions.Package.Delete)] |
|||
public async virtual Task DeleteAsync(Guid id) |
|||
{ |
|||
await _packageRepository.DeleteAsync(id); |
|||
|
|||
await CurrentUnitOfWork.SaveChangesAsync(); |
|||
} |
|||
|
|||
[Authorize(PlatformPermissions.Package.ManageBlobs)] |
|||
public async virtual Task<PackageBlobDto> UploadBlobAsync( |
|||
Guid id, |
|||
PackageBlobUploadDto input) |
|||
{ |
|||
var package = await _packageRepository.GetAsync(id); |
|||
|
|||
var packageBlob = package.FindBlob(input.Name); |
|||
|
|||
if (packageBlob == null) |
|||
{ |
|||
packageBlob = package.CreateBlob( |
|||
input.Name, |
|||
input.CreatedAt, |
|||
input.UpdatedAt, |
|||
input.Size ?? input.File.ContentLength, |
|||
input.Summary); |
|||
|
|||
await _blobManager.SaveBlobAsync(package, packageBlob, input.File.GetStream()); |
|||
} |
|||
|
|||
await _packageRepository.UpdateAsync(package); |
|||
|
|||
await CurrentUnitOfWork.SaveChangesAsync(); |
|||
|
|||
return ObjectMapper.Map<PackageBlob, PackageBlobDto>(packageBlob); |
|||
} |
|||
|
|||
[Authorize(PlatformPermissions.Package.ManageBlobs)] |
|||
public async virtual Task RemoveBlobAsync( |
|||
Guid id, |
|||
PackageBlobRemoveDto input) |
|||
{ |
|||
var package = await _packageRepository.GetAsync(id); |
|||
|
|||
var packageBlob = package.FindBlob(input.Name); |
|||
|
|||
await _blobManager.RemoveBlobAsync(package, packageBlob); |
|||
|
|||
package.RemoveBlob(input.Name); |
|||
|
|||
await CurrentUnitOfWork.SaveChangesAsync(); |
|||
} |
|||
|
|||
public async virtual Task<IRemoteStreamContent> DownloadBlobAsync(Guid id, PackageBlobDownloadInput input) |
|||
{ |
|||
var package = await _packageRepository.GetAsync(id); |
|||
var packageBlob = package.FindBlob(input.Name); |
|||
|
|||
var stream = await _blobManager.DownloadBlobAsync(package, packageBlob); |
|||
|
|||
return new RemoteStreamContent(stream, packageBlob.Name, packageBlob.ContentType); |
|||
} |
|||
|
|||
public async virtual Task<PackageDto> GetAsync(Guid id) |
|||
{ |
|||
var package = await _packageRepository.GetAsync(id); |
|||
|
|||
return ObjectMapper.Map<Package, PackageDto>(package); |
|||
} |
|||
|
|||
[Authorize(PlatformPermissions.Package.Default)] |
|||
public async virtual Task<PagedResultDto<PackageDto>> GetListAsync(PackageGetPagedListInput input) |
|||
{ |
|||
var filter = new PackageFilter( |
|||
input.Filter, input.Name, input.Note, input.Version, |
|||
input.Description, input.ForceUpdate, input.Authors); |
|||
|
|||
var specification = new PackageSpecification(filter); |
|||
|
|||
var totalCount = await _packageRepository.GetCountAsync(specification); |
|||
var entities = await _packageRepository.GetListAsync(specification); |
|||
|
|||
return new PagedResultDto<PackageDto>( |
|||
totalCount, |
|||
ObjectMapper.Map<List<Package>, List<PackageDto>>(entities)); |
|||
} |
|||
|
|||
[Authorize(PlatformPermissions.Package.Update)] |
|||
public async virtual Task<PackageDto> UpdateAsync(Guid id, PackageUpdateDto input) |
|||
{ |
|||
var package = await _packageRepository.GetAsync(id); |
|||
|
|||
UpdateByInput(package, input); |
|||
|
|||
package.SetConcurrencyStampIfNotNull(input.ConcurrencyStamp); |
|||
|
|||
package = await _packageRepository.UpdateAsync(package); |
|||
|
|||
await CurrentUnitOfWork.SaveChangesAsync(); |
|||
|
|||
return ObjectMapper.Map<Package, PackageDto>(package); |
|||
} |
|||
|
|||
protected virtual void UpdateByInput(Package entity, PackageCreateOrUpdateDto input) |
|||
{ |
|||
if (!string.Equals(entity.Note, input.Note, StringComparison.CurrentCultureIgnoreCase)) |
|||
{ |
|||
entity.SetNote(input.Note); |
|||
} |
|||
|
|||
if (!string.Equals(entity.Authors, input.Authors, StringComparison.CurrentCultureIgnoreCase)) |
|||
{ |
|||
entity.Authors = Check.Length(input.Authors, nameof(Package.Authors), PackageConsts.MaxAuthorsLength); |
|||
} |
|||
|
|||
if (!string.Equals(entity.Description, input.Description, StringComparison.CurrentCultureIgnoreCase)) |
|||
{ |
|||
entity.Description = Check.Length(input.Description, nameof(Package.Description), PackageConsts.MaxDescriptionLength); |
|||
} |
|||
|
|||
entity.ForceUpdate = input.ForceUpdate; |
|||
entity.Level = input.Level; |
|||
} |
|||
} |
|||
@ -1,103 +0,0 @@ |
|||
using LINGYUN.Platform.Permissions; |
|||
using Microsoft.AspNetCore.Authorization; |
|||
using System.Collections.Generic; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp; |
|||
using Volo.Abp.Application.Dtos; |
|||
|
|||
namespace LINGYUN.Platform.Versions |
|||
{ |
|||
[Authorize(PlatformPermissions.AppVersion.Default)] |
|||
public class VersionAppService : PlatformApplicationServiceBase, IVersionAppService |
|||
{ |
|||
private readonly VersionManager _versionManager; |
|||
public VersionAppService( |
|||
VersionManager versionManager) |
|||
{ |
|||
_versionManager = versionManager; |
|||
} |
|||
|
|||
[Authorize(PlatformPermissions.AppVersion.FileManager.Create)] |
|||
public async virtual Task AppendFileAsync(VersionFileCreateDto versionFileCreate) |
|||
{ |
|||
await _versionManager.AppendFileAsync(versionFileCreate.VersionId, |
|||
versionFileCreate.SHA256, versionFileCreate.FileName, versionFileCreate.FileVersion, |
|||
versionFileCreate.TotalByte, versionFileCreate.FilePath, versionFileCreate.FileType); |
|||
} |
|||
|
|||
[Authorize(PlatformPermissions.AppVersion.Create)] |
|||
public async virtual Task<VersionDto> CreateAsync(VersionCreateDto versionCreate) |
|||
{ |
|||
if (await _versionManager.ExistsAsync(versionCreate.PlatformType,versionCreate.Version)) |
|||
{ |
|||
throw new UserFriendlyException("VersionAlreadyExists"); |
|||
} |
|||
var version = new AppVersion(GuidGenerator.Create(), versionCreate.Title, |
|||
versionCreate.Version, versionCreate.PlatformType, CurrentTenant.Id) |
|||
{ |
|||
Description = versionCreate.Description, |
|||
Level = versionCreate.Level |
|||
}; |
|||
|
|||
await _versionManager.CreateAsync(version); |
|||
|
|||
return ObjectMapper.Map<AppVersion, VersionDto>(version); |
|||
} |
|||
|
|||
[Authorize(PlatformPermissions.AppVersion.Delete)] |
|||
public async virtual Task DeleteAsync(VersionDeleteDto versionDelete) |
|||
{ |
|||
var version = await _versionManager.GetByVersionAsync(versionDelete.PlatformType, versionDelete.Version); |
|||
if (version != null) |
|||
{ |
|||
await _versionManager.DeleteAsync(version.Id); |
|||
} |
|||
} |
|||
|
|||
|
|||
public async virtual Task<PagedResultDto<VersionDto>> GetAsync(VersionGetByPagedDto versionGetByPaged) |
|||
{ |
|||
var versionCount = await _versionManager.GetCountAsync(versionGetByPaged.PlatformType, versionGetByPaged.Filter); |
|||
var versions = await _versionManager.GetPagedListAsync(versionGetByPaged.PlatformType, versionGetByPaged.Filter, |
|||
versionGetByPaged.Sorting, true, |
|||
versionGetByPaged.SkipCount, versionGetByPaged.MaxResultCount); |
|||
|
|||
return new PagedResultDto<VersionDto>(versionCount, |
|||
ObjectMapper.Map<List<AppVersion>, List<VersionDto>>(versions)); |
|||
} |
|||
|
|||
|
|||
public async virtual Task<VersionDto> GetAsync(VersionGetByIdDto versionGetById) |
|||
{ |
|||
var version = await _versionManager.GetByIdAsync(versionGetById.Id); |
|||
|
|||
return ObjectMapper.Map<AppVersion, VersionDto>(version); |
|||
} |
|||
|
|||
public async virtual Task<VersionDto> GetLastestAsync(PlatformType platformType) |
|||
{ |
|||
var version = await _versionManager.GetLatestAsync(platformType); |
|||
|
|||
return ObjectMapper.Map<AppVersion, VersionDto>(version); |
|||
} |
|||
|
|||
[Authorize(PlatformPermissions.AppVersion.FileManager.Delete)] |
|||
public async virtual Task RemoveAllFileAsync(VersionGetByIdDto versionGetById) |
|||
{ |
|||
await _versionManager.RemoveAllFileAsync(versionGetById.Id); |
|||
} |
|||
|
|||
[Authorize(PlatformPermissions.AppVersion.FileManager.Delete)] |
|||
public async virtual Task RemoveFileAsync(VersionFileDeleteDto versionFileDelete) |
|||
{ |
|||
await _versionManager.RemoveFileAsync(versionFileDelete.VersionId, versionFileDelete.FileName); |
|||
} |
|||
|
|||
public virtual Task DownloadFileAsync(VersionFileGetDto versionFileGet) |
|||
{ |
|||
// TODO: 是否需要定义此接口用于 abp-definition-api ?
|
|||
// overrided implement HttpContext.Response.Body.Write(Stream fileStream)
|
|||
return Task.CompletedTask; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,11 @@ |
|||
namespace LINGYUN.Platform.Packages; |
|||
public static class PackageBlobConsts |
|||
{ |
|||
public static int MaxNameLength { get; set; } = 255; |
|||
public static int MaxUrlLength { get; set; } = 512; |
|||
public static int MaxContentTypeLength { get; set; } = 256; |
|||
public static int MaxSummaryLength { get; set; } = 1024; |
|||
public static int MaxLicenseLength { get; set; } = 1024; |
|||
public static int MaxAuthorsLength { get; set; } = 100; |
|||
public static int MaxSHA256Length { get; set; } = 256; |
|||
} |
|||
@ -0,0 +1,10 @@ |
|||
namespace LINGYUN.Platform.Packages; |
|||
public static class PackageConsts |
|||
{ |
|||
public static int MaxNameLength { get; set; } = 255; |
|||
public static int MaxNoteLength { get; set; } = 1024; |
|||
public static int MaxVersionLength { get; set; } = 30; |
|||
public static int MaxDescriptionLength { get; set; } = 255; |
|||
public static int MaxPlatformLength { get; set; } = 20; |
|||
public static int MaxAuthorsLength { get; set; } = 100; |
|||
} |
|||
@ -0,0 +1,24 @@ |
|||
using System; |
|||
using Volo.Abp.EventBus; |
|||
using Volo.Abp.MultiTenancy; |
|||
|
|||
namespace LINGYUN.Platform.Packages; |
|||
|
|||
[EventName("platform.packages")] |
|||
public class PackageEto : IMultiTenant |
|||
{ |
|||
public Guid? TenantId { get; set; } |
|||
/// <summary>
|
|||
/// 名称
|
|||
/// </summary>
|
|||
public string Name { get; set; } |
|||
/// <summary>
|
|||
/// 版本
|
|||
/// </summary>
|
|||
public string Version { get; set; } |
|||
/// <summary>
|
|||
/// 强制更新
|
|||
/// </summary>
|
|||
public bool ForceUpdate { get; set; } |
|||
public PackageLevel Level { get; set; } |
|||
} |
|||
@ -0,0 +1,17 @@ |
|||
namespace LINGYUN.Platform.Packages; |
|||
|
|||
public enum PackageLevel |
|||
{ |
|||
/// <summary>
|
|||
/// 无需更新
|
|||
/// </summary>
|
|||
None = -1, |
|||
/// <summary>
|
|||
/// 资源
|
|||
/// </summary>
|
|||
Resource = 0, |
|||
/// <summary>
|
|||
/// 整体
|
|||
/// </summary>
|
|||
Full = 1 |
|||
} |
|||
@ -1,14 +0,0 @@ |
|||
namespace LINGYUN.Platform.Versions |
|||
{ |
|||
public static class AppVersionConsts |
|||
{ |
|||
public const int MaxTitleLength = 50; |
|||
|
|||
public const int MaxVersionLength = 20; |
|||
|
|||
public const int MaxDescriptionLength = 2048; |
|||
|
|||
public const int DefaultVersionFileLimitLength = 200; |
|||
public const string DefaultAllowVersionFileExtensions = "dll,zip,rar,txt,log,xml,config,json,jpeg,jpg,png,bmp,ico,xlsx,xltx,xls,xlt,docs,dots,doc,dot,pptx,potx,ppt,pot,chm"; |
|||
} |
|||
} |
|||
@ -1,33 +0,0 @@ |
|||
using System; |
|||
using Volo.Abp.MultiTenancy; |
|||
|
|||
namespace LINGYUN.Platform.Versions |
|||
{ |
|||
public class AppVersionEto : IMultiTenant |
|||
{ |
|||
/// <summary>
|
|||
/// 租户标识
|
|||
/// </summary>
|
|||
public Guid? TenantId { get; set; } |
|||
/// <summary>
|
|||
/// 标题
|
|||
/// </summary>
|
|||
public string Title { get; set; } |
|||
/// <summary>
|
|||
/// 版本号
|
|||
/// </summary>
|
|||
public string Version { get; set; } |
|||
/// <summary>
|
|||
/// 描述
|
|||
/// </summary>
|
|||
public string Description { get; set; } |
|||
/// <summary>
|
|||
/// 重要级别
|
|||
/// </summary>
|
|||
public ImportantLevel Level { get; set; } |
|||
/// <summary>
|
|||
/// 文件数量
|
|||
/// </summary>
|
|||
public int FileCount { get; set; } |
|||
} |
|||
} |
|||
@ -1,21 +0,0 @@ |
|||
namespace LINGYUN.Platform.Versions |
|||
{ |
|||
/// <summary>
|
|||
/// 文件类型
|
|||
/// </summary>
|
|||
public enum FileType |
|||
{ |
|||
/// <summary>
|
|||
/// 普通文件流
|
|||
/// </summary>
|
|||
Stream = 0, |
|||
/// <summary>
|
|||
/// 压缩文件
|
|||
/// </summary>
|
|||
Zip = 1, |
|||
/// <summary>
|
|||
/// 脚本文件
|
|||
/// </summary>
|
|||
Scripts = 2 |
|||
} |
|||
} |
|||
@ -1,11 +0,0 @@ |
|||
using System.IO; |
|||
using System.Threading.Tasks; |
|||
|
|||
namespace LINGYUN.Platform.Versions |
|||
{ |
|||
public interface IVersionFileManager |
|||
{ |
|||
Task<string> SaveFileAsync(string version, string filePath, string fileName, string fileVersion, byte[] data); |
|||
Task<Stream> DownloadFileAsync(PlatformType platformType, string version, string filePath, string fileName, string fileVersion); |
|||
} |
|||
} |
|||
@ -1,22 +0,0 @@ |
|||
namespace LINGYUN.Platform.Versions |
|||
{ |
|||
public enum ImportantLevel |
|||
{ |
|||
/// <summary>
|
|||
/// 未定义
|
|||
/// </summary>
|
|||
None = -1, |
|||
/// <summary>
|
|||
/// 低
|
|||
/// </summary>
|
|||
Low = 0, |
|||
/// <summary>
|
|||
/// 高
|
|||
/// </summary>
|
|||
High = 1, |
|||
/// <summary>
|
|||
/// 重要
|
|||
/// </summary>
|
|||
Matter |
|||
} |
|||
} |
|||
@ -1,13 +0,0 @@ |
|||
namespace LINGYUN.Platform.Versions |
|||
{ |
|||
public static class VersionFileConsts |
|||
{ |
|||
public const int MaxNameLength = 255; |
|||
|
|||
public const int MaxPathLength = 255; |
|||
|
|||
public const int MaxVersionLength = 20; |
|||
|
|||
public const int MaxSHA256Length = 65; |
|||
} |
|||
} |
|||
@ -0,0 +1,20 @@ |
|||
using System.IO; |
|||
using Volo.Abp.DependencyInjection; |
|||
|
|||
namespace LINGYUN.Platform.Packages; |
|||
|
|||
public class FileSystemPackageBlobNormalizer : IPackageBlobNormalizer, ISingletonDependency |
|||
{ |
|||
public FileSystemPackageBlobNormalizer() |
|||
{ |
|||
|
|||
} |
|||
|
|||
public string Normalize(Package package, PackageBlob blob) |
|||
{ |
|||
var pk = package.Name; |
|||
var pv = package.Version; |
|||
|
|||
return Path.Combine(pk, "v" + pv, "blobs", blob.Name); |
|||
} |
|||
} |
|||
@ -0,0 +1,25 @@ |
|||
using System.IO; |
|||
using System.Threading; |
|||
using System.Threading.Tasks; |
|||
|
|||
namespace LINGYUN.Platform.Packages; |
|||
|
|||
public interface IPackageBlobManager |
|||
{ |
|||
Task RemoveBlobAsync( |
|||
Package package, |
|||
PackageBlob packageBlob, |
|||
CancellationToken cancellationToken = default); |
|||
|
|||
Task SaveBlobAsync( |
|||
Package package, |
|||
PackageBlob packageBlob, |
|||
Stream stream, |
|||
bool overrideExisting = true, |
|||
CancellationToken cancellationToken = default); |
|||
|
|||
Task<Stream> DownloadBlobAsync( |
|||
Package package, |
|||
PackageBlob packageBlob, |
|||
CancellationToken cancellationToken = default); |
|||
} |
|||
@ -0,0 +1,6 @@ |
|||
namespace LINGYUN.Platform.Packages; |
|||
|
|||
public interface IPackageBlobNormalizer |
|||
{ |
|||
string Normalize(Package package, PackageBlob blob); |
|||
} |
|||
@ -0,0 +1,32 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Threading; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.Domain.Repositories; |
|||
using Volo.Abp.Specifications; |
|||
|
|||
namespace LINGYUN.Platform.Packages; |
|||
|
|||
public interface IPackageRepository : IBasicRepository<Package, Guid> |
|||
{ |
|||
Task<Package> FindByNameAsync( |
|||
string name, |
|||
bool includeDetails = true, |
|||
CancellationToken cancellationToken = default); |
|||
|
|||
Task<Package> FindLatestAsync( |
|||
string name, |
|||
bool includeDetails = true, |
|||
CancellationToken cancellationToken = default); |
|||
|
|||
Task<int> GetCountAsync( |
|||
Specification<Package> specification, |
|||
CancellationToken cancellationToken = default); |
|||
|
|||
Task<List<Package>> GetListAsync( |
|||
Specification<Package> specification, |
|||
string sorting = $"{nameof(Package.Version)} DESC", |
|||
int skipCount = 0, |
|||
int maxResultCount = 10, |
|||
CancellationToken cancellationToken = default); |
|||
} |
|||
@ -0,0 +1,114 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Collections.ObjectModel; |
|||
using System.Linq; |
|||
using System.Reflection.Emit; |
|||
using Volo.Abp; |
|||
using Volo.Abp.Data; |
|||
using Volo.Abp.Domain.Entities.Auditing; |
|||
using Volo.Abp.MultiTenancy; |
|||
|
|||
namespace LINGYUN.Platform.Packages; |
|||
|
|||
public class Package : FullAuditedAggregateRoot<Guid>, IMultiTenant |
|||
{ |
|||
public virtual Guid? TenantId { get; protected set; } |
|||
/// <summary>
|
|||
/// 名称
|
|||
/// </summary>
|
|||
public virtual string Name { get; protected set; } |
|||
/// <summary>
|
|||
/// 版本说明
|
|||
/// </summary>
|
|||
public virtual string Note { get; protected set; } |
|||
/// <summary>
|
|||
/// 版本
|
|||
/// </summary>
|
|||
public virtual string Version { get; protected set; } |
|||
/// <summary>
|
|||
/// 描述
|
|||
/// </summary>
|
|||
public virtual string Description { get; set; } |
|||
/// <summary>
|
|||
/// 强制更新
|
|||
/// </summary>
|
|||
public virtual bool ForceUpdate { get; set; } |
|||
|
|||
public virtual string Authors { get; set; } |
|||
|
|||
public virtual PackageLevel Level { get; set; } |
|||
|
|||
public virtual ICollection<PackageBlob> Blobs { get; protected set; } |
|||
|
|||
protected Package() |
|||
{ |
|||
Blobs = new Collection<PackageBlob>(); |
|||
ExtraProperties = new ExtraPropertyDictionary(); |
|||
this.SetDefaultsForExtraProperties(); |
|||
} |
|||
|
|||
public Package( |
|||
Guid id, |
|||
string name, |
|||
string note, |
|||
string version, |
|||
string description = null, |
|||
Guid? tenantId = null) |
|||
: base(id) |
|||
{ |
|||
Name = Check.NotNullOrWhiteSpace(name, nameof(name), PackageConsts.MaxNameLength); |
|||
Note = Check.NotNullOrWhiteSpace(note, nameof(note), PackageConsts.MaxNoteLength); |
|||
Version = Check.NotNullOrWhiteSpace(version, nameof(version), PackageConsts.MaxVersionLength); |
|||
|
|||
Description = Check.Length(description, nameof(description), PackageConsts.MaxDescriptionLength); |
|||
TenantId = tenantId; |
|||
|
|||
Level = PackageLevel.None; |
|||
Blobs = new Collection<PackageBlob>(); |
|||
ExtraProperties = new ExtraPropertyDictionary(); |
|||
this.SetDefaultsForExtraProperties(); |
|||
} |
|||
|
|||
public void SetNote(string note) |
|||
{ |
|||
Note = Check.NotNullOrWhiteSpace(note, nameof(note), PackageConsts.MaxNoteLength); |
|||
} |
|||
|
|||
public PackageBlob CreateBlob( |
|||
string name, |
|||
DateTime createdAt, |
|||
DateTime? updatedAt = null, |
|||
long? size = null, |
|||
string summary = null) |
|||
{ |
|||
var findBlob = FindBlob(name); |
|||
if (findBlob == null) |
|||
{ |
|||
findBlob = new PackageBlob( |
|||
Id, |
|||
name, |
|||
createdAt, |
|||
updatedAt, |
|||
size, |
|||
summary, |
|||
TenantId); |
|||
Blobs.Add(findBlob); |
|||
} |
|||
return findBlob; |
|||
} |
|||
|
|||
public PackageBlob FindBlob(string name) |
|||
{ |
|||
return Blobs.FirstOrDefault(x => x.Name == name); |
|||
} |
|||
|
|||
public void RemoveBlob(string name) |
|||
{ |
|||
Blobs.RemoveAll(x => x.Name == name); |
|||
} |
|||
|
|||
public void ClearBlob() |
|||
{ |
|||
Blobs.Clear(); |
|||
} |
|||
} |
|||
@ -0,0 +1,64 @@ |
|||
using System; |
|||
using Volo.Abp; |
|||
using Volo.Abp.Data; |
|||
using Volo.Abp.Domain.Entities.Auditing; |
|||
using Volo.Abp.MultiTenancy; |
|||
|
|||
namespace LINGYUN.Platform.Packages; |
|||
|
|||
public class PackageBlob : CreationAuditedEntity<int>, IMultiTenant, IHasExtraProperties |
|||
{ |
|||
public virtual Guid? TenantId { get; protected set; } |
|||
public virtual Guid PackageId { get; private set; } |
|||
public virtual Package Package { get; private set; } |
|||
public virtual string Name { get; protected set; } |
|||
public virtual string Url { get; protected set; } |
|||
public virtual long? Size { get; protected set; } |
|||
public virtual string Summary { get; protected set; } |
|||
public virtual DateTime CreatedAt { get; protected set; } |
|||
public virtual DateTime? UpdatedAt { get; protected set; } |
|||
public virtual string License { get; set; } |
|||
public virtual string Authors { get; set; } |
|||
public virtual string ContentType { get; set; } |
|||
public virtual string SHA256 { get; set; } |
|||
public virtual int DownloadCount { get; protected set; } |
|||
public virtual ExtraPropertyDictionary ExtraProperties { get; set; } |
|||
|
|||
protected PackageBlob() |
|||
{ |
|||
ExtraProperties = new ExtraPropertyDictionary(); |
|||
this.SetDefaultsForExtraProperties(); |
|||
} |
|||
|
|||
internal PackageBlob( |
|||
Guid packageId, |
|||
string name, |
|||
DateTime createdAt, |
|||
DateTime? updatedAt = null, |
|||
long? size = null, |
|||
string summary = null, |
|||
Guid? tenantId = null) |
|||
{ |
|||
PackageId = packageId; |
|||
Name = Check.NotNullOrWhiteSpace(name, nameof(name), PackageBlobConsts.MaxNameLength); |
|||
CreatedAt = createdAt; |
|||
UpdatedAt = updatedAt; |
|||
Size = size; |
|||
Summary = Check.Length(summary, nameof(summary), PackageBlobConsts.MaxSummaryLength); |
|||
TenantId = tenantId; |
|||
DownloadCount = 0; |
|||
|
|||
ExtraProperties = new ExtraPropertyDictionary(); |
|||
this.SetDefaultsForExtraProperties(); |
|||
} |
|||
|
|||
public void SetUrl(string url) |
|||
{ |
|||
Url = Check.NotNullOrWhiteSpace(url, nameof(url), PackageBlobConsts.MaxUrlLength); |
|||
} |
|||
|
|||
public void Download() |
|||
{ |
|||
DownloadCount += 1; |
|||
} |
|||
} |
|||
@ -0,0 +1,94 @@ |
|||
using System; |
|||
using System.IO; |
|||
using System.Security.Cryptography; |
|||
using System.Threading; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.BlobStoring; |
|||
using Volo.Abp.DependencyInjection; |
|||
using Volo.Abp.Domain.Services; |
|||
|
|||
namespace LINGYUN.Platform.Packages; |
|||
|
|||
[Dependency(TryRegister = true)] |
|||
public class PackageBlobManager : DomainService, IPackageBlobManager, ITransientDependency |
|||
{ |
|||
protected IPackageBlobNormalizer BlobNormalizer { get; } |
|||
protected IBlobContainer<PackageContainer> PackageContainer { get; } |
|||
|
|||
public PackageBlobManager( |
|||
IPackageBlobNormalizer blobNormalizer, |
|||
IBlobContainer<PackageContainer> packageContainer) |
|||
{ |
|||
BlobNormalizer = blobNormalizer; |
|||
PackageContainer = packageContainer; |
|||
} |
|||
|
|||
public async virtual Task RemoveBlobAsync( |
|||
Package package, |
|||
PackageBlob packageBlob, |
|||
CancellationToken cancellationToken = default) |
|||
{ |
|||
var blobName = BlobNormalizer.Normalize(package, packageBlob); |
|||
|
|||
await RemoveBlobAsync(blobName); |
|||
} |
|||
|
|||
public async virtual Task<Stream> DownloadBlobAsync( |
|||
Package package, |
|||
PackageBlob packageBlob, |
|||
CancellationToken cancellationToken = default) |
|||
{ |
|||
packageBlob.Download(); |
|||
|
|||
return await DownloadFromBlobAsync(package, packageBlob); |
|||
} |
|||
|
|||
public async virtual Task SaveBlobAsync( |
|||
Package package, |
|||
PackageBlob packageBlob, |
|||
Stream stream, |
|||
bool overrideExisting = true, |
|||
CancellationToken cancellationToken = default) |
|||
{ |
|||
var blobName = BlobNormalizer.Normalize(package, packageBlob); |
|||
|
|||
await SaveToBlobAsync(blobName, stream, overrideExisting, cancellationToken); |
|||
|
|||
stream.Seek(0, SeekOrigin.Begin); |
|||
packageBlob.SHA256 = ComputeHash(stream); |
|||
packageBlob.SetUrl($"api/platform/packages/{packageBlob.PackageId}/blob/{packageBlob.Name}"); |
|||
} |
|||
|
|||
protected async virtual Task<Stream> DownloadFromBlobAsync( |
|||
Package package, |
|||
PackageBlob packageBlob, |
|||
CancellationToken cancellationToken = default) |
|||
{ |
|||
var blobName = BlobNormalizer.Normalize(package, packageBlob); |
|||
|
|||
return await PackageContainer.GetAsync(blobName); |
|||
} |
|||
|
|||
protected async virtual Task SaveToBlobAsync( |
|||
string blobName, |
|||
Stream stream, |
|||
bool overrideExisting = true, |
|||
CancellationToken cancellationToken = default) |
|||
{ |
|||
await PackageContainer.SaveAsync(blobName, stream, overrideExisting, cancellationToken); |
|||
} |
|||
|
|||
protected async virtual Task RemoveBlobAsync( |
|||
string blobName, |
|||
CancellationToken cancellationToken = default) |
|||
{ |
|||
await PackageContainer.DeleteAsync(blobName, cancellationToken); |
|||
} |
|||
|
|||
protected virtual string ComputeHash(Stream stream) |
|||
{ |
|||
using var sha256 = SHA256.Create(); |
|||
var checkHash = sha256.ComputeHash(stream); |
|||
return BitConverter.ToString(checkHash).Replace("-", string.Empty); |
|||
} |
|||
} |
|||
@ -0,0 +1,8 @@ |
|||
using Volo.Abp.BlobStoring; |
|||
|
|||
namespace LINGYUN.Platform.Packages; |
|||
|
|||
[BlobContainerName("packages")] |
|||
public class PackageContainer |
|||
{ |
|||
} |
|||
@ -0,0 +1,36 @@ |
|||
namespace LINGYUN.Platform.Packages; |
|||
|
|||
public class PackageFilter |
|||
{ |
|||
public string Filter { get; set; } |
|||
|
|||
public string Name { get; set; } |
|||
|
|||
public string Note { get; set; } |
|||
|
|||
public string Version { get; set; } |
|||
|
|||
public string Description { get; set; } |
|||
|
|||
public bool? ForceUpdate { get; set; } |
|||
|
|||
public string Authors { get; set; } |
|||
|
|||
public PackageFilter( |
|||
string filter = null, |
|||
string name = null, |
|||
string note = null, |
|||
string version = null, |
|||
string description = null, |
|||
bool? forceUpdate = null, |
|||
string authors = null) |
|||
{ |
|||
Filter = filter; |
|||
Name = name; |
|||
Note = note; |
|||
Version = version; |
|||
Description = description; |
|||
ForceUpdate = forceUpdate; |
|||
Authors = authors; |
|||
} |
|||
} |
|||
@ -0,0 +1,31 @@ |
|||
using System; |
|||
using System.Linq.Expressions; |
|||
using Volo.Abp.Specifications; |
|||
|
|||
namespace LINGYUN.Platform.Packages; |
|||
|
|||
public class PackageSpecification : Specification<Package> |
|||
{ |
|||
protected PackageFilter Filter { get; } |
|||
|
|||
public PackageSpecification(PackageFilter filter) |
|||
{ |
|||
Filter = filter; |
|||
} |
|||
|
|||
public override Expression<Func<Package, bool>> ToExpression() |
|||
{ |
|||
Expression<Func<Package, bool>> expression = (p) => true; |
|||
|
|||
return expression |
|||
.AndIf(!Filter.Name.IsNullOrWhiteSpace(), x => x.Name == Filter.Name) |
|||
.AndIf(!Filter.Note.IsNullOrWhiteSpace(), x => x.Note == Filter.Note) |
|||
.AndIf(!Filter.Version.IsNullOrWhiteSpace(), x => x.Version == Filter.Version) |
|||
.AndIf(!Filter.Description.IsNullOrWhiteSpace(), x => x.Description == Filter.Description) |
|||
.AndIf(!Filter.Authors.IsNullOrWhiteSpace(), x => x.Authors == Filter.Authors) |
|||
.AndIf(Filter.ForceUpdate.HasValue, x => x.ForceUpdate == Filter.ForceUpdate) |
|||
.AndIf(!Filter.Filter.IsNullOrWhiteSpace(), x => x.Name.Contains(Filter.Filter) || |
|||
x.Note.Contains(Filter.Filter) || x.Version.Contains(Filter.Filter) || |
|||
x.Description.Contains(Filter.Filter) || x.Authors.Contains(Filter.Filter)); |
|||
} |
|||
} |
|||
@ -1,116 +0,0 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using Volo.Abp.Domain.Entities.Auditing; |
|||
using Volo.Abp.MultiTenancy; |
|||
|
|||
namespace LINGYUN.Platform.Versions |
|||
{ |
|||
/// <summary>
|
|||
/// 应用版本号
|
|||
/// </summary>
|
|||
public class AppVersion : FullAuditedAggregateRoot<Guid>, IMultiTenant |
|||
{ |
|||
/// <summary>
|
|||
/// 租户标识
|
|||
/// </summary>
|
|||
public virtual Guid? TenantId { get; protected set; } |
|||
/// <summary>
|
|||
/// 标题
|
|||
/// </summary>
|
|||
public virtual string Title { get; protected set; } |
|||
/// <summary>
|
|||
/// 版本号
|
|||
/// </summary>
|
|||
public virtual string Version { get; protected set; } |
|||
/// <summary>
|
|||
/// 描述
|
|||
/// </summary>
|
|||
public virtual string Description { get; set; } |
|||
/// <summary>
|
|||
/// 重要级别
|
|||
/// </summary>
|
|||
public virtual ImportantLevel Level { get; set; } |
|||
/// <summary>
|
|||
/// 适应平台
|
|||
/// </summary>
|
|||
public virtual PlatformType PlatformType { get; protected set; } |
|||
/// <summary>
|
|||
/// 版本文件列表
|
|||
/// </summary>
|
|||
public virtual ICollection<VersionFile> Files { get; protected set; } |
|||
|
|||
protected AppVersion() |
|||
{ |
|||
Files = new List<VersionFile>(); |
|||
} |
|||
|
|||
public AppVersion(Guid id, string title, string version, PlatformType platformType = PlatformType.None, Guid? tenantId = null) |
|||
{ |
|||
Id = id; |
|||
Title = title; |
|||
Version = version; |
|||
TenantId = tenantId; |
|||
PlatformType = platformType; |
|||
Level = ImportantLevel.Low; |
|||
} |
|||
|
|||
public void AppendFile(string name, string version, long size, string sha256, |
|||
string filePath = "", FileType fileType = FileType.Stream) |
|||
{ |
|||
if (!FileExists(name)) |
|||
{ |
|||
var versionFile = new VersionFile(name, version, size, sha256, fileType, TenantId) |
|||
{ |
|||
Path = filePath |
|||
}; |
|||
Files.Add(versionFile); |
|||
} |
|||
} |
|||
|
|||
public void RemoveFile(string name) |
|||
{ |
|||
Files.RemoveAll(x => x.Name.Equals(name)); |
|||
} |
|||
|
|||
public void RemoveAllFile() |
|||
{ |
|||
Files.Clear(); |
|||
} |
|||
|
|||
public void ChangeFileVersion(string name, string version, long size, string sha256) |
|||
{ |
|||
if (FileExists(name)) |
|||
{ |
|||
var file = FindFile(name); |
|||
file.ChangeVersion(version, size, sha256); |
|||
} |
|||
} |
|||
|
|||
public VersionFile FindFile(string name) |
|||
{ |
|||
return Files.Where(x => x.Name.Equals(name)).FirstOrDefault(); |
|||
} |
|||
|
|||
public VersionFile FindFile(string path, string name) |
|||
{ |
|||
return Files.Where(x => x.Path.Equals(path) && x.Name.Equals(name)).FirstOrDefault(); |
|||
} |
|||
|
|||
public VersionFile FindFile(string path, string name, string version) |
|||
{ |
|||
return Files.Where(x => x.Path.Equals(path) && x.Name.Equals(name) && x.Version.Equals(version)) |
|||
.FirstOrDefault(); |
|||
} |
|||
|
|||
public bool FileExists(string name) |
|||
{ |
|||
// TODO: Windows file system ?
|
|||
//if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
|
|||
//{
|
|||
// return Files.Any(x => x.Name.Equals(name, StringComparison.CurrentCultureIgnoreCase));
|
|||
//}
|
|||
return Files.Any(x => x.Name.Equals(name)); |
|||
} |
|||
} |
|||
} |
|||
@ -1,21 +0,0 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Threading; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.Domain.Repositories; |
|||
|
|||
namespace LINGYUN.Platform.Versions |
|||
{ |
|||
public interface IVersionRepository : IBasicRepository<AppVersion, Guid> |
|||
{ |
|||
Task<bool> ExistsAsync(PlatformType platformType, string version, CancellationToken cancellationToken = default); |
|||
|
|||
Task<AppVersion> GetByVersionAsync(PlatformType platformType, string version, CancellationToken cancellationToken = default); |
|||
|
|||
Task<long> GetCountAsync(PlatformType platformType, string filter = "", CancellationToken cancellationToken = default); |
|||
|
|||
Task<List<AppVersion>> GetPagedListAsync(PlatformType platformType, string filter = "", string soring = nameof(AppVersion.CreationTime), bool includeDetails = true, int skipCount = 1, int maxResultCount = 10, CancellationToken cancellationToken = default); |
|||
|
|||
Task<AppVersion> GetLatestVersionAsync(PlatformType platformType, CancellationToken cancellationToken = default); |
|||
} |
|||
} |
|||
@ -1,9 +0,0 @@ |
|||
using Volo.Abp.BlobStoring; |
|||
|
|||
namespace LINGYUN.Platform.Versions |
|||
{ |
|||
[BlobContainerName("app-platform-version")] |
|||
public class VersionContainer |
|||
{ |
|||
} |
|||
} |
|||
@ -1,102 +0,0 @@ |
|||
using System; |
|||
using Volo.Abp.Domain.Entities.Auditing; |
|||
using Volo.Abp.IO; |
|||
using Volo.Abp.MultiTenancy; |
|||
|
|||
namespace LINGYUN.Platform.Versions |
|||
{ |
|||
public class VersionFile : AuditedEntity<int>, IMultiTenant |
|||
{ |
|||
/// <summary>
|
|||
/// 租户标识
|
|||
/// </summary>
|
|||
public virtual Guid? TenantId { get; protected set; } |
|||
/// <summary>
|
|||
/// 文件路径
|
|||
/// </summary>
|
|||
public virtual string Path { get; set; } |
|||
/// <summary>
|
|||
/// 文件名称
|
|||
/// </summary>
|
|||
public virtual string Name { get; protected set; } |
|||
/// <summary>
|
|||
/// 文件版本
|
|||
/// </summary>
|
|||
public virtual string Version { get; protected set; } |
|||
/// <summary>
|
|||
/// 文件大小
|
|||
/// 单位b
|
|||
/// </summary>
|
|||
public virtual long Size { get; protected set; } |
|||
/// <summary>
|
|||
/// 文件类型
|
|||
/// </summary>
|
|||
public virtual FileType FileType { get; protected set; } |
|||
/// <summary>
|
|||
/// 文件SHA256编码
|
|||
/// </summary>
|
|||
public virtual string SHA256 { get; protected set; } |
|||
/// <summary>
|
|||
/// 下载次数
|
|||
/// </summary>
|
|||
public virtual int DownloadCount { get; protected set; } |
|||
/// <summary>
|
|||
/// 应用版本标识
|
|||
/// </summary>
|
|||
public virtual Guid AppVersionId { get; protected set; } |
|||
/// <summary>
|
|||
/// 所属应用版本号
|
|||
/// </summary>
|
|||
public virtual AppVersion AppVersion { get; protected set; } |
|||
protected VersionFile() |
|||
{ |
|||
|
|||
} |
|||
|
|||
public VersionFile(string name, string version, long size, string sha256, FileType fileType = FileType.Stream, Guid? tenantId = null) |
|||
{ |
|||
Name = name; |
|||
FileType = fileType; |
|||
TenantId = tenantId; |
|||
ChangeVersion(version, size, sha256); |
|||
} |
|||
|
|||
public void ChangeVersion(string version, long size, string sha256) |
|||
{ |
|||
Size = size; |
|||
SHA256 = sha256; |
|||
Version = version; |
|||
} |
|||
|
|||
public void Download() |
|||
{ |
|||
DownloadCount += 1; |
|||
} |
|||
|
|||
public static string NormalizeBlobName(string appVersion, string fileName, string fileVersion, |
|||
string filePath = "") |
|||
{ |
|||
var fileNameWithNotExten = fileName; |
|||
// 取出文件扩展名
|
|||
var fileExten = FileHelper.GetExtension(fileName); |
|||
if (!fileExten.IsNullOrWhiteSpace()) |
|||
{ |
|||
// 取出不带扩展名的文件名
|
|||
fileNameWithNotExten = fileName.Replace(fileExten, ""); |
|||
// 去掉最后一位扩展名符号
|
|||
fileNameWithNotExten = fileNameWithNotExten.Remove(fileNameWithNotExten.Length - 1); |
|||
} |
|||
// 转换不受支持的符号
|
|||
fileNameWithNotExten = fileNameWithNotExten.Replace(".", "-"); |
|||
|
|||
//路径存储模式 如果传递了绝对路径,需要计算短路径
|
|||
if (!filePath.IsNullOrWhiteSpace()) |
|||
{ |
|||
return $"{appVersion}/{filePath.Md5()}/{fileNameWithNotExten}/{fileVersion}/{fileName}"; |
|||
} |
|||
// 最终文件名为 应用版本号/文件名(不带扩展名)/文件版本/文件名
|
|||
// 例: 1.0.0.0/test-upload-text-file/1.0.0.0/test-upload-text-file.text
|
|||
return $"{appVersion}/{fileNameWithNotExten}/{fileVersion}/{fileName}"; |
|||
} |
|||
} |
|||
} |
|||
@ -1,153 +0,0 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.IO; |
|||
using System.Security.Cryptography; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp; |
|||
using Volo.Abp.BlobStoring; |
|||
using Volo.Abp.DependencyInjection; |
|||
using Volo.Abp.Domain.Services; |
|||
using Volo.Abp.Uow; |
|||
|
|||
namespace LINGYUN.Platform.Versions |
|||
{ |
|||
[Dependency(Microsoft.Extensions.DependencyInjection.ServiceLifetime.Transient)] |
|||
[ExposeServices(typeof(IVersionFileManager), typeof(VersionManager))] |
|||
public class VersionManager : DomainService, IVersionFileManager |
|||
{ |
|||
protected IVersionRepository VersionRepository { get; } |
|||
protected IBlobContainer<VersionContainer> VersionBlobContainer { get; } |
|||
|
|||
public VersionManager( |
|||
IBlobContainer<VersionContainer> container, |
|||
IVersionRepository versionRepository) |
|||
{ |
|||
VersionBlobContainer = container; |
|||
VersionRepository = versionRepository; |
|||
} |
|||
|
|||
public async virtual Task<bool> ExistsAsync(PlatformType platformType, string version) |
|||
{ |
|||
return await VersionRepository.ExistsAsync(platformType, version); |
|||
} |
|||
|
|||
public async virtual Task<AppVersion> GetByIdAsync(Guid id) |
|||
{ |
|||
return await VersionRepository.GetAsync(id); |
|||
} |
|||
|
|||
public async virtual Task<AppVersion> GetByVersionAsync(PlatformType platformType, string version) |
|||
{ |
|||
return await VersionRepository.GetByVersionAsync(platformType, version); |
|||
} |
|||
|
|||
public async virtual Task<long> GetCountAsync(PlatformType platformType, string filter) |
|||
{ |
|||
return await VersionRepository.GetCountAsync(platformType, filter); |
|||
} |
|||
|
|||
public async virtual Task<List<AppVersion>> GetPagedListAsync(PlatformType platformType, string filter = "", string soring = nameof(AppVersion.CreationTime), bool includeDetails = true, int skipCount = 1, int maxResultCount = 10) |
|||
{ |
|||
return await VersionRepository.GetPagedListAsync(platformType, filter, soring, includeDetails, skipCount, maxResultCount); |
|||
} |
|||
|
|||
[UnitOfWork] |
|||
public async virtual Task CreateAsync(AppVersion version) |
|||
{ |
|||
await VersionRepository.InsertAsync(version); |
|||
} |
|||
|
|||
|
|||
[UnitOfWork] |
|||
public async virtual Task UpdateAsync(AppVersion version) |
|||
{ |
|||
await VersionRepository.UpdateAsync(version); |
|||
} |
|||
|
|||
[UnitOfWork] |
|||
public async virtual Task DeleteAsync(Guid id) |
|||
{ |
|||
await RemoveAllFileAsync(id); |
|||
await VersionRepository.DeleteAsync(id); |
|||
} |
|||
|
|||
public async virtual Task<AppVersion> GetLatestAsync(PlatformType platformType) |
|||
{ |
|||
return await VersionRepository.GetLatestVersionAsync(platformType); |
|||
} |
|||
|
|||
public async virtual Task<Stream> DownloadFileAsync(PlatformType platformType, string version, string filePath, string fileName, string fileVersion) |
|||
{ |
|||
var appVersion = await GetByVersionAsync(platformType, version); |
|||
var versionFile = appVersion.FindFile(filePath, fileName, fileVersion); |
|||
if (versionFile == null) |
|||
{ |
|||
throw new BusinessException(PlatformErrorCodes.VersionFileNotFound) |
|||
.WithData("FileName", fileName) |
|||
.WithData("FileVersion", fileVersion); |
|||
} |
|||
versionFile.Download(); |
|||
return await VersionBlobContainer.GetAsync( |
|||
VersionFile.NormalizeBlobName(version, versionFile.Name, versionFile.Version, versionFile.Path)); |
|||
} |
|||
|
|||
public async virtual Task<Stream> GetFileAsync(VersionFile versionFile) |
|||
{ |
|||
versionFile.Download(); |
|||
return await VersionBlobContainer.GetAsync( |
|||
VersionFile.NormalizeBlobName(versionFile.AppVersion.Version, versionFile.Name, versionFile.Version, versionFile.Path)); |
|||
} |
|||
|
|||
public async virtual Task<string> SaveFileAsync(string version, string filePath, string fileName, string fileVersion, byte[] data) |
|||
{ |
|||
// 计算指纹
|
|||
var sha256 = SHA256.Create(); |
|||
var checkHash = sha256.ComputeHash(data); |
|||
var sha256Hash = BitConverter.ToString(checkHash).Replace("-", string.Empty); |
|||
|
|||
await VersionBlobContainer |
|||
.SaveAsync(VersionFile.NormalizeBlobName(version, fileName, fileVersion, filePath), data, true); |
|||
|
|||
return sha256Hash; |
|||
} |
|||
|
|||
[UnitOfWork] |
|||
public async virtual Task AppendFileAsync(Guid versionId, string fileSha256, |
|||
string fileName, string fileVersion, |
|||
long fileSize, string filePath = "", |
|||
FileType fileType = FileType.Stream) |
|||
{ |
|||
var appVersion = await VersionRepository.GetAsync(versionId); |
|||
if (appVersion.FileExists(fileName)) |
|||
{ |
|||
appVersion.RemoveFile(fileName); |
|||
} |
|||
appVersion.AppendFile(fileName, fileVersion, fileSize, fileSha256, filePath, fileType); |
|||
} |
|||
|
|||
[UnitOfWork] |
|||
public async virtual Task RemoveFileAsync(Guid versionId, string fileName) |
|||
{ |
|||
var appVersion = await VersionRepository.GetAsync(versionId); |
|||
var versionFile = appVersion.FindFile(fileName); |
|||
if (versionFile != null) |
|||
{ |
|||
await VersionBlobContainer |
|||
.DeleteAsync(VersionFile.NormalizeBlobName(appVersion.Version, versionFile.Name, versionFile.Version)); |
|||
appVersion.RemoveFile(fileName); |
|||
} |
|||
} |
|||
|
|||
[UnitOfWork] |
|||
public async virtual Task RemoveAllFileAsync(Guid versionId) |
|||
{ |
|||
var appVersion = await VersionRepository.GetAsync(versionId); |
|||
foreach (var versionFile in appVersion.Files) |
|||
{ |
|||
await VersionBlobContainer |
|||
.DeleteAsync(VersionFile.NormalizeBlobName(appVersion.Version, versionFile.Name, versionFile.Version)); |
|||
} |
|||
appVersion.RemoveAllFile(); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,32 @@ |
|||
using Volo.Abp.Specifications; |
|||
|
|||
namespace System.Linq.Expressions; |
|||
|
|||
internal static class ExpressionFuncExtensions |
|||
{ |
|||
public static Expression<Func<T, bool>> AndIf<T>( |
|||
this Expression<Func<T, bool>> first, |
|||
bool condition, |
|||
Expression<Func<T, bool>> second) |
|||
{ |
|||
if (condition) |
|||
{ |
|||
return ExpressionFuncExtender.And(first, second); |
|||
} |
|||
|
|||
return first; |
|||
} |
|||
|
|||
public static Expression<Func<T, bool>> OrIf<T>( |
|||
this Expression<Func<T, bool>> first, |
|||
bool condition, |
|||
Expression<Func<T, bool>> second) |
|||
{ |
|||
if (condition) |
|||
{ |
|||
return ExpressionFuncExtender.Or(first, second); |
|||
} |
|||
|
|||
return first; |
|||
} |
|||
} |
|||
@ -0,0 +1,80 @@ |
|||
using LINGYUN.Platform.EntityFrameworkCore; |
|||
using Microsoft.EntityFrameworkCore; |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Linq.Dynamic.Core; |
|||
using System.Threading; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.Domain.Repositories.EntityFrameworkCore; |
|||
using Volo.Abp.EntityFrameworkCore; |
|||
using Volo.Abp.Specifications; |
|||
|
|||
namespace LINGYUN.Platform.Packages; |
|||
public class EfCorePackageRepository : |
|||
EfCoreRepository<PlatformDbContext, Package, Guid>, |
|||
IPackageRepository |
|||
{ |
|||
public EfCorePackageRepository( |
|||
IDbContextProvider<PlatformDbContext> dbContextProvider) |
|||
: base(dbContextProvider) |
|||
{ |
|||
} |
|||
|
|||
public async virtual Task<Package> FindByNameAsync( |
|||
string name, |
|||
bool includeDetails = true, |
|||
CancellationToken cancellationToken = default) |
|||
{ |
|||
return await (await GetDbSetAsync()) |
|||
.IncludeDetails(includeDetails) |
|||
.Where(x => x.Name == name) |
|||
.OrderByDescending(x => x.Version) |
|||
.FirstOrDefaultAsync(GetCancellationToken(cancellationToken)); |
|||
} |
|||
|
|||
public async virtual Task<Package> FindLatestAsync( |
|||
string name, |
|||
bool includeDetails = true, |
|||
CancellationToken cancellationToken = default) |
|||
{ |
|||
return await (await GetDbSetAsync()) |
|||
.IncludeDetails(includeDetails) |
|||
.Where(x => x.Name == name) |
|||
.OrderByDescending(x => x.Version) |
|||
.FirstOrDefaultAsync(GetCancellationToken(cancellationToken)); |
|||
} |
|||
|
|||
public async virtual Task<int> GetCountAsync( |
|||
Specification<Package> specification, |
|||
CancellationToken cancellationToken = default) |
|||
{ |
|||
return await (await GetDbSetAsync()) |
|||
.Where(specification.ToExpression()) |
|||
.CountAsync(GetCancellationToken(cancellationToken)); |
|||
} |
|||
|
|||
public async virtual Task<List<Package>> GetListAsync( |
|||
Specification<Package> specification, |
|||
string sorting = $"{nameof(Package.Version)} DESC", |
|||
int skipCount = 0, |
|||
int maxResultCount = 10, |
|||
CancellationToken cancellationToken = default) |
|||
{ |
|||
if (sorting.IsNullOrWhiteSpace()) |
|||
{ |
|||
sorting = $"{nameof(Package.Version)} DESC"; |
|||
} |
|||
|
|||
return await (await GetDbSetAsync()) |
|||
.Where(specification.ToExpression()) |
|||
.OrderBy(sorting) |
|||
.PageBy(skipCount, maxResultCount) |
|||
.ToListAsync(GetCancellationToken(cancellationToken)); |
|||
} |
|||
|
|||
public async override Task<IQueryable<Package>> WithDetailsAsync() |
|||
{ |
|||
return (await GetQueryableAsync()).IncludeDetails(); |
|||
} |
|||
} |
|||
@ -1,68 +0,0 @@ |
|||
using LINGYUN.Platform.EntityFrameworkCore; |
|||
using Microsoft.EntityFrameworkCore; |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Linq.Dynamic.Core; |
|||
using System.Threading; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.DependencyInjection; |
|||
using Volo.Abp.Domain.Repositories.EntityFrameworkCore; |
|||
using Volo.Abp.EntityFrameworkCore; |
|||
|
|||
namespace LINGYUN.Platform.Versions |
|||
{ |
|||
public class EfCoreVersionRepository : EfCoreRepository<IPlatformDbContext, AppVersion, Guid>, IVersionRepository, ITransientDependency |
|||
{ |
|||
public EfCoreVersionRepository( |
|||
IDbContextProvider<IPlatformDbContext> dbContextProvider) |
|||
: base(dbContextProvider) |
|||
{ |
|||
} |
|||
|
|||
public async virtual Task<long> GetCountAsync(PlatformType platformType, string filter = "", CancellationToken cancellationToken = default) |
|||
{ |
|||
return await (await GetDbSetAsync()) |
|||
.Where(x => (platformType | x.PlatformType) == x.PlatformType) |
|||
.WhereIf(!filter.IsNullOrWhiteSpace(), x => x.Version.Contains(filter) || x.Title.Contains(filter)) |
|||
.LongCountAsync(GetCancellationToken(cancellationToken)); |
|||
} |
|||
|
|||
public async virtual Task<List<AppVersion>> GetPagedListAsync(PlatformType platformType, string filter = "", string soring = nameof(AppVersion.CreationTime), bool includeDetails = true, int skipCount = 1, int maxResultCount = 10, CancellationToken cancellationToken = default) |
|||
{ |
|||
return await (await GetDbSetAsync()) |
|||
.IncludeIf(includeDetails, x => x.Files) |
|||
.Where(x => (platformType | x.PlatformType) == x.PlatformType) |
|||
.WhereIf(!filter.IsNullOrWhiteSpace(), x => x.Version.Contains(filter) || x.Title.Contains(filter)) |
|||
.OrderBy($"{nameof(AppVersion.CreationTime)} DESC") |
|||
.ThenBy(soring ?? nameof(AppVersion.Version)) |
|||
.PageBy(skipCount, maxResultCount) |
|||
.ToListAsync(GetCancellationToken(cancellationToken)); |
|||
} |
|||
|
|||
|
|||
public async virtual Task<bool> ExistsAsync(PlatformType platformType, string version, CancellationToken cancellationToken = default) |
|||
{ |
|||
return await (await GetDbSetAsync()) |
|||
.AnyAsync(x => (platformType | x.PlatformType) == x.PlatformType && x.Version.Equals(version), GetCancellationToken(cancellationToken)); |
|||
} |
|||
|
|||
public async virtual Task<AppVersion> GetByVersionAsync(PlatformType platformType, string version, CancellationToken cancellationToken = default) |
|||
{ |
|||
return await (await GetDbSetAsync()) |
|||
.Include(x => x.Files) |
|||
.Where(x => (platformType | x.PlatformType) == x.PlatformType && x.Version.Equals(version)) |
|||
.FirstOrDefaultAsync(GetCancellationToken(cancellationToken)); |
|||
} |
|||
|
|||
public async virtual Task<AppVersion> GetLatestVersionAsync(PlatformType platformType, CancellationToken cancellationToken = default) |
|||
{ |
|||
return await (await GetDbSetAsync()) |
|||
.Include(x => x.Files) |
|||
.Where(x => (platformType | x.PlatformType) == x.PlatformType) |
|||
.OrderBy($"{nameof(AppVersion.CreationTime)} DESC") |
|||
.ThenBy(nameof(AppVersion.Version)) |
|||
.FirstOrDefaultAsync(GetCancellationToken(cancellationToken)); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,97 @@ |
|||
using LINGYUN.Platform.Permissions; |
|||
using Microsoft.AspNetCore.Authorization; |
|||
using Microsoft.AspNetCore.Mvc; |
|||
using System; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp; |
|||
using Volo.Abp.Application.Dtos; |
|||
using Volo.Abp.Content; |
|||
|
|||
namespace LINGYUN.Platform.Packages; |
|||
|
|||
[RemoteService(Name = PlatformRemoteServiceConsts.RemoteServiceName)] |
|||
[Area("platform")] |
|||
[Route("api/platform/packages")] |
|||
public class PackageController : PlatformControllerBase, IPackageAppService |
|||
{ |
|||
private readonly IPackageAppService _service; |
|||
|
|||
public PackageController(IPackageAppService service) |
|||
{ |
|||
_service = service; |
|||
} |
|||
|
|||
[HttpPost] |
|||
[Authorize(PlatformPermissions.Package.Create)] |
|||
public virtual Task<PackageDto> CreateAsync(PackageCreateDto input) |
|||
{ |
|||
return _service.CreateAsync(input); |
|||
} |
|||
|
|||
[HttpDelete] |
|||
[Route("{id}")] |
|||
[Authorize(PlatformPermissions.Package.Delete)] |
|||
public virtual Task DeleteAsync(Guid id) |
|||
{ |
|||
return _service.DeleteAsync(id); |
|||
} |
|||
|
|||
[HttpPost] |
|||
[Route("{id}/blob")] |
|||
[Authorize(PlatformPermissions.Package.ManageBlobs)] |
|||
public virtual Task<PackageBlobDto> UploadBlobAsync( |
|||
Guid id, |
|||
[FromForm] PackageBlobUploadDto input) |
|||
{ |
|||
return _service.UploadBlobAsync(id, input); |
|||
} |
|||
|
|||
[HttpDelete] |
|||
[Route("{id}/blob/{Name}")] |
|||
[Authorize(PlatformPermissions.Package.ManageBlobs)] |
|||
public virtual Task RemoveBlobAsync( |
|||
Guid id, |
|||
PackageBlobRemoveDto input) |
|||
{ |
|||
return _service.RemoveBlobAsync(id, input); |
|||
} |
|||
|
|||
[HttpGet] |
|||
[Route("{id}/blob/{Name}")] |
|||
[AllowAnonymous] |
|||
public virtual Task<IRemoteStreamContent> DownloadBlobAsync(Guid id, PackageBlobDownloadInput input) |
|||
{ |
|||
return _service.DownloadBlobAsync(id, input); |
|||
} |
|||
|
|||
[HttpGet] |
|||
[Route("{id}")] |
|||
[AllowAnonymous] |
|||
public virtual Task<PackageDto> GetAsync(Guid id) |
|||
{ |
|||
return _service.GetAsync(id); |
|||
} |
|||
|
|||
[HttpGet] |
|||
[Route("{Name}/latest")] |
|||
[AllowAnonymous] |
|||
public virtual Task<PackageDto> GetLatestAsync(PackageGetLatestInput input) |
|||
{ |
|||
return _service.GetLatestAsync(input); |
|||
} |
|||
|
|||
[HttpGet] |
|||
[Authorize(PlatformPermissions.Package.Default)] |
|||
public virtual Task<PagedResultDto<PackageDto>> GetListAsync(PackageGetPagedListInput input) |
|||
{ |
|||
return _service.GetListAsync(input); |
|||
} |
|||
|
|||
[HttpPut] |
|||
[Route("{id}")] |
|||
[Authorize(PlatformPermissions.Package.Update)] |
|||
public virtual Task<PackageDto> UpdateAsync(Guid id, PackageUpdateDto input) |
|||
{ |
|||
return _service.UpdateAsync(id, input); |
|||
} |
|||
} |
|||
@ -1,224 +0,0 @@ |
|||
using LINGYUN.Platform.Permissions; |
|||
using LINGYUN.Platform.Settings; |
|||
using Microsoft.AspNetCore.Authorization; |
|||
using Microsoft.AspNetCore.Http; |
|||
using Microsoft.AspNetCore.Mvc; |
|||
using Microsoft.AspNetCore.StaticFiles; |
|||
using System; |
|||
using System.ComponentModel.DataAnnotations; |
|||
using System.IO; |
|||
using System.Linq; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp; |
|||
using Volo.Abp.Application.Dtos; |
|||
using Volo.Abp.IO; |
|||
using Volo.Abp.Settings; |
|||
|
|||
namespace LINGYUN.Platform.Versions |
|||
{ |
|||
[RemoteService(Name = PlatformRemoteServiceConsts.RemoteServiceName)] |
|||
[Area("platform")] |
|||
[Route("api/platform/version")] |
|||
public class VersionController : PlatformControllerBase, IVersionAppService |
|||
{ |
|||
private readonly IVersionFileManager _versionFileManager; |
|||
private readonly IVersionAppService _versionAppService; |
|||
|
|||
public VersionController( |
|||
IVersionAppService versionAppService, |
|||
IVersionFileManager versionFileManager) |
|||
{ |
|||
_versionAppService = versionAppService; |
|||
_versionFileManager = versionFileManager; |
|||
} |
|||
|
|||
[HttpPost] |
|||
[Route("file/append")] |
|||
[RequestSizeLimit(200_000_000)] |
|||
public async virtual Task AppendFileAsync([FromQuery] VersionFileCreateDto versionFileCreate) |
|||
{ |
|||
// 检查文件大小
|
|||
var fileSizeLimited = await SettingProvider |
|||
.GetAsync(PlatformSettingNames.AppVersion.VersionFileLimitLength, AppVersionConsts.DefaultVersionFileLimitLength); |
|||
if (fileSizeLimited * 1024 * 1024 < versionFileCreate.TotalByte) |
|||
{ |
|||
throw new UserFriendlyException(L["UploadFileSizeBeyondLimit", fileSizeLimited]); |
|||
} |
|||
// 采用分块模式上传文件
|
|||
|
|||
// 保存分块到临时目录
|
|||
var fileName = versionFileCreate.FileName; |
|||
// 文件扩展名
|
|||
var fileExtensionName = FileHelper.GetExtension(fileName); |
|||
var fileAllowExtension = await SettingProvider |
|||
.GetOrNullAsync(PlatformSettingNames.AppVersion.AllowVersionFileExtensions); |
|||
if (fileAllowExtension.IsNullOrWhiteSpace()) |
|||
{ |
|||
fileAllowExtension = AppVersionConsts.DefaultAllowVersionFileExtensions; |
|||
} |
|||
// 检查文件扩展名
|
|||
if (!fileAllowExtension.Split(',').Any(fe => fe.Equals(fileExtensionName, StringComparison.CurrentCultureIgnoreCase))) |
|||
{ |
|||
throw new UserFriendlyException(L["NotAllowedFileExtensionName", fileExtensionName]); |
|||
} |
|||
// 当前计算机临时目录
|
|||
var tempFilePath = Environment.GetFolderPath(Environment.SpecialFolder.Templates); |
|||
// 以上传的文件名创建一个临时目录
|
|||
tempFilePath = Path.Combine(tempFilePath, "lingyun-platform", Path.GetFileNameWithoutExtension(fileName)); |
|||
// 以上传的分片索引创建临时文件
|
|||
var tempSavedFile = Path.Combine(tempFilePath, $"{versionFileCreate.CurrentByte}.{fileExtensionName}"); |
|||
if (!Directory.Exists(tempFilePath)) |
|||
{ |
|||
// 临时目录不存在则创建
|
|||
Directory.CreateDirectory(tempFilePath); |
|||
} |
|||
try |
|||
{ |
|||
if (HttpContext.RequestAborted.IsCancellationRequested) |
|||
{ |
|||
// 如果取消请求,删除临时目录
|
|||
Directory.Delete(tempFilePath, true); |
|||
return; |
|||
} |
|||
// 保存临时文件
|
|||
using (var fs = new FileStream(tempSavedFile, FileMode.Create, FileAccess.Write)) |
|||
{ |
|||
// 写入当前分片文件
|
|||
await Request.Body.CopyToAsync(fs); |
|||
} |
|||
|
|||
if (versionFileCreate.CurrentByte == versionFileCreate.TotalByte) |
|||
{ |
|||
// 合并文件
|
|||
var mergeSavedFile = Path.Combine(tempFilePath, $"{fileName}"); |
|||
// 获取并排序所有分片文件
|
|||
var mergeFiles = Directory.GetFiles(tempFilePath).OrderBy(f => f.Length).ThenBy(f => f); |
|||
// 创建临时合并文件
|
|||
using (var mergeSavedFileStream = new FileStream(mergeSavedFile, FileMode.Create)) |
|||
{ |
|||
foreach (var mergeFile in mergeFiles) |
|||
{ |
|||
// 读取当前文件字节
|
|||
var mergeFileBytes = await FileHelper.ReadAllBytesAsync(mergeFile); |
|||
// 写入到合并文件流
|
|||
await mergeSavedFileStream.WriteAsync(mergeFileBytes,0, mergeFileBytes.Length); |
|||
// 删除已参与合并的临时文件分片
|
|||
FileHelper.DeleteIfExists(mergeFile); |
|||
} |
|||
// 上传最终合并的文件并取得SHA256指纹
|
|||
var fileData = await mergeSavedFileStream.GetAllBytesAsync(); |
|||
versionFileCreate.SHA256 = await _versionFileManager.SaveFileAsync(versionFileCreate.Version, |
|||
versionFileCreate.FilePath, versionFileCreate.FileName, versionFileCreate.FileVersion, fileData); |
|||
} |
|||
// 添加到版本信息
|
|||
await _versionAppService.AppendFileAsync(versionFileCreate); |
|||
// 文件保存之后删除临时文件目录
|
|||
Directory.Delete(tempFilePath, true); |
|||
} |
|||
} |
|||
catch |
|||
{ |
|||
// 发生异常删除临时文件目录
|
|||
Directory.Delete(tempFilePath, true); |
|||
throw; |
|||
} |
|||
} |
|||
|
|||
[HttpPost] |
|||
public async virtual Task<VersionDto> CreateAsync(VersionCreateDto versionCreate) |
|||
{ |
|||
return await _versionAppService.CreateAsync(versionCreate); |
|||
} |
|||
|
|||
[HttpDelete] |
|||
public async virtual Task DeleteAsync(VersionDeleteDto versionDelete) |
|||
{ |
|||
await _versionAppService.DeleteAsync(versionDelete); |
|||
} |
|||
|
|||
[HttpGet] |
|||
public async virtual Task<PagedResultDto<VersionDto>> GetAsync(VersionGetByPagedDto versionGetByPaged) |
|||
{ |
|||
return await _versionAppService.GetAsync(versionGetByPaged); |
|||
} |
|||
|
|||
[HttpGet] |
|||
[Route("{Id}")] |
|||
public async virtual Task<VersionDto> GetAsync(VersionGetByIdDto versionGetById) |
|||
{ |
|||
return await _versionAppService.GetAsync(versionGetById); |
|||
} |
|||
|
|||
[HttpGet] |
|||
[Route("lastest")] |
|||
public async virtual Task<VersionDto> GetLastestAsync([Required] PlatformType platformType) |
|||
{ |
|||
return await _versionAppService.GetLastestAsync(platformType); |
|||
} |
|||
|
|||
[HttpDelete] |
|||
[Route("file/clean")] |
|||
public async virtual Task RemoveAllFileAsync(VersionGetByIdDto versionGetById) |
|||
{ |
|||
await _versionAppService.RemoveAllFileAsync(versionGetById); |
|||
} |
|||
|
|||
[HttpDelete] |
|||
[Route("file/remove")] |
|||
public async virtual Task RemoveFileAsync(VersionFileDeleteDto versionFileDelete) |
|||
{ |
|||
await _versionAppService.RemoveFileAsync(versionFileDelete); |
|||
} |
|||
|
|||
[HttpGet] |
|||
[Route("file/download")] |
|||
[Authorize(PlatformPermissions.AppVersion.FileManager.Download)] |
|||
public async virtual Task DownloadFileAsync(VersionFileGetDto versionFileGet) |
|||
{ |
|||
// 分块模式下载文件
|
|||
|
|||
// 得到文件流
|
|||
var fileStream = await _versionFileManager.DownloadFileAsync( |
|||
versionFileGet.PlatformType, versionFileGet.Version, versionFileGet.FilePath, |
|||
versionFileGet.FileName, versionFileGet.FileVersion); |
|||
// 得到文件扩展名
|
|||
var fileExt = Path.GetExtension(versionFileGet.FileName); |
|||
var provider = new FileExtensionContentTypeProvider(); |
|||
// Http响应标头的文件类型
|
|||
string memi = provider.Mappings[fileExt]; |
|||
using (Response.Body) |
|||
{ |
|||
// Http响应标头的文件类型
|
|||
Response.ContentType = memi; |
|||
// 文件大小
|
|||
byte[] contentBytes = await fileStream.GetAllBytesAsync(); |
|||
long contentLength = contentBytes.Length; |
|||
// 指定响应内容大小
|
|||
Response.ContentLength = contentLength; |
|||
// 单个分块大小 2MB
|
|||
int bufferSize = 2 * 1024 * 1024; |
|||
// 分块总数
|
|||
int contentByteCount = Math.DivRem(contentBytes.Length, bufferSize, out int modResult); |
|||
for (int index = 0; index < contentByteCount; index++) |
|||
{ |
|||
// 当前分页传输字节
|
|||
byte[] currentTransferBytes = new byte[bufferSize]; |
|||
if (index == contentByteCount - 1) |
|||
{ |
|||
// 最后一个分块和余数大小一起传输
|
|||
if (modResult > 0) |
|||
{ |
|||
currentTransferBytes = new byte[bufferSize + modResult]; |
|||
} |
|||
} |
|||
// 复制文件流中的当前分块区段
|
|||
Array.Copy(contentBytes, index * bufferSize, currentTransferBytes, 0, currentTransferBytes.Length); |
|||
// 写入响应流
|
|||
await Response.Body.WriteAsync(currentTransferBytes, 0, currentTransferBytes.Length); |
|||
// 清空缓冲区
|
|||
await Response.Body.FlushAsync(); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,12 @@ |
|||
{ |
|||
"profiles": { |
|||
"LINGYUN.Abp.MultiTenancy.Saas": { |
|||
"commandName": "Project", |
|||
"launchBrowser": true, |
|||
"environmentVariables": { |
|||
"ASPNETCORE_ENVIRONMENT": "Development" |
|||
}, |
|||
"applicationUrl": "https://localhost:58776;http://localhost:58777" |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,3 @@ |
|||
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd"> |
|||
<ConfigureAwait ContinueOnCapturedContext="false" /> |
|||
</Weavers> |
|||
@ -0,0 +1,20 @@ |
|||
<Project Sdk="Microsoft.NET.Sdk"> |
|||
|
|||
<Import Project="..\..\..\configureawait.props" /> |
|||
<Import Project="..\..\..\common.props" /> |
|||
|
|||
<PropertyGroup> |
|||
<TargetFramework>net6.0</TargetFramework> |
|||
<RootNamespace /> |
|||
</PropertyGroup> |
|||
|
|||
<ItemGroup> |
|||
<PackageReference Include="Senparc.Weixin.MP" Version="16.18.9" /> |
|||
<PackageReference Include="Volo.Abp.AspNetCore.Mvc" Version="$(VoloAbpPackageVersion)" /> |
|||
</ItemGroup> |
|||
|
|||
<ItemGroup> |
|||
<ProjectReference Include="..\LINGYUN.Abp.WeChat.Official\LINGYUN.Abp.WeChat.Official.csproj" /> |
|||
</ItemGroup> |
|||
|
|||
</Project> |
|||
@ -0,0 +1,9 @@ |
|||
using Volo.Abp.Modularity; |
|||
|
|||
namespace LINGYUN.Abp.WeChat.Official.Senparc; |
|||
|
|||
[DependsOn(typeof(AbpWeChatOfficialModule))] |
|||
public class AbpWeChatOfficialSenparcModule : AbpModule |
|||
{ |
|||
|
|||
} |
|||
@ -0,0 +1,81 @@ |
|||
using Microsoft.AspNetCore.Mvc; |
|||
using Senparc.NeuChar.MessageHandlers; |
|||
using Senparc.Weixin.MP; |
|||
using Senparc.Weixin.MP.Entities.Request; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.AspNetCore.Mvc; |
|||
|
|||
namespace LINGYUN.Abp.WeChat.Official.Senparc; |
|||
|
|||
[Area("wechat-official")] |
|||
[Route("api/wechat/official")] |
|||
public class WeChatOfficialController : AbpControllerBase |
|||
{ |
|||
private readonly AbpWeChatOfficialOptionsFactory _optionsFactory; |
|||
|
|||
public WeChatOfficialController(AbpWeChatOfficialOptionsFactory optionsFactory) |
|||
{ |
|||
_optionsFactory = optionsFactory; |
|||
} |
|||
|
|||
|
|||
|
|||
/// <summary>
|
|||
/// 微信后台验证地址(使用Get),微信后台的“接口配置信息”的Url填写如:http://weixin.senparc.com/weixin
|
|||
/// </summary>
|
|||
[HttpGet] |
|||
public async Task<IActionResult> Get(PostModel postModel, string echostr) |
|||
{ |
|||
var options = await _optionsFactory.CreateAsync(); |
|||
if (CheckSignature.Check(postModel.Signature, postModel.Timestamp, postModel.Nonce, options.Token)) |
|||
{ |
|||
return Content(echostr); //返回随机字符串则表示验证通过
|
|||
} |
|||
else |
|||
{ |
|||
return Content( |
|||
"failed:" + postModel.Signature + "," + |
|||
CheckSignature.GetSignature(postModel.Timestamp, postModel.Nonce, options.Token) + "。" + |
|||
"如果你在浏览器中看到这句话,说明此地址可以被作为微信公众账号后台的Url,请注意保持Token一致。"); |
|||
} |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 用户发送消息后,微信平台自动Post一个请求到这里,并等待响应XML。
|
|||
/// </summary>
|
|||
[HttpPost] |
|||
public async Task<IActionResult> Post(PostModel postModel) |
|||
{ |
|||
var options = await _optionsFactory.CreateAsync(); |
|||
if (!CheckSignature.Check(postModel.Signature, postModel.Timestamp, postModel.Nonce, options.Token)) |
|||
{ |
|||
return Content("参数错误!"); |
|||
} |
|||
|
|||
postModel.Token = options.Token;//根据自己后台的设置保持一致
|
|||
postModel.EncodingAESKey = options.EncodingAESKey;//根据自己后台的设置保持一致
|
|||
postModel.AppId = options.AppId;//根据自己后台的设置保持一致
|
|||
|
|||
//自定义MessageHandler,对微信请求的详细判断操作都在这里面。
|
|||
var messageHandler = new WeChatOfficialMessageHandler(Request.Body, postModel);//接收消息
|
|||
|
|||
#region 设置消息去重设置 + 优先调用同步、异步方法设置
|
|||
|
|||
/* 如果需要添加消息去重功能,只需打开OmitRepeatedMessage功能,SDK会自动处理。 |
|||
* 收到重复消息通常是因为微信服务器没有及时收到响应,会持续发送2-5条不等的相同内容的 RequestMessage */ |
|||
messageHandler.OmitRepeatedMessage = true;//默认已经是开启状态,此处仅作为演示,也可以设置为 false 在本次请求中停用此功能
|
|||
|
|||
//当同步方法被重写,且异步方法未被重写时,尝试调用同步方法
|
|||
messageHandler.DefaultMessageHandlerAsyncEvent = DefaultMessageHandlerAsyncEvent.SelfSynicMethod; |
|||
|
|||
#endregion
|
|||
|
|||
messageHandler.SaveRequestMessageLog();//记录 Request 日志(可选)
|
|||
|
|||
await messageHandler.ExecuteAsync(HttpContext.RequestAborted);//执行微信处理过程(关键,第二步)
|
|||
|
|||
messageHandler.SaveResponseMessageLog();//记录 Response 日志(可选)
|
|||
|
|||
return Ok(); |
|||
} |
|||
} |
|||
@ -0,0 +1,7 @@ |
|||
using Senparc.Weixin.MP.MessageContexts; |
|||
|
|||
namespace LINGYUN.Abp.WeChat.Official.Senparc; |
|||
|
|||
public class WeChatOfficialMessageContext : DefaultMpMessageContext |
|||
{ |
|||
} |
|||
@ -0,0 +1,30 @@ |
|||
using Senparc.NeuChar.App.AppStore; |
|||
using Senparc.NeuChar.Entities; |
|||
using Senparc.Weixin.MP.Entities; |
|||
using Senparc.Weixin.MP.Entities.Request; |
|||
using Senparc.Weixin.MP.MessageHandlers; |
|||
using System; |
|||
using System.IO; |
|||
|
|||
namespace LINGYUN.Abp.WeChat.Official.Senparc; |
|||
|
|||
public class WeChatOfficialMessageHandler : MessageHandler<WeChatOfficialMessageContext> |
|||
{ |
|||
public WeChatOfficialMessageHandler( |
|||
Stream inputStream, |
|||
PostModel postModel, |
|||
int maxRecordCount = 0, |
|||
bool onlyAllowEncryptMessage = false, |
|||
DeveloperInfo developerInfo = null, |
|||
IServiceProvider serviceProvider = null) |
|||
: base(inputStream, postModel, maxRecordCount, onlyAllowEncryptMessage, developerInfo, serviceProvider) |
|||
{ |
|||
} |
|||
|
|||
public override IResponseMessageBase DefaultResponseMessage(IRequestMessageBase requestMessage) |
|||
{ |
|||
var responseMessage = base.CreateResponseMessage<ResponseMessageText>(); |
|||
responseMessage.Content = $"这条消息来自DefaultResponseMessage。\r\n您收到这条消息,表明该公众号没有对【{requestMessage.MsgType}】类型做处理。"; |
|||
return responseMessage; |
|||
} |
|||
} |
|||
@ -0,0 +1,934 @@ |
|||
// <auto-generated />
|
|||
using System; |
|||
using LY.MicroService.PlatformManagement.EntityFrameworkCore; |
|||
using Microsoft.EntityFrameworkCore; |
|||
using Microsoft.EntityFrameworkCore.Infrastructure; |
|||
using Microsoft.EntityFrameworkCore.Migrations; |
|||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion; |
|||
using Volo.Abp.EntityFrameworkCore; |
|||
|
|||
#nullable disable |
|||
|
|||
namespace LY.MicroService.PlatformManagement.Migrations |
|||
{ |
|||
[DbContext(typeof(PlatformManagementMigrationsDbContext))] |
|||
[Migration("20221212081339_Add-Package-Manager")] |
|||
partial class AddPackageManager |
|||
{ |
|||
protected override void BuildTargetModel(ModelBuilder modelBuilder) |
|||
{ |
|||
#pragma warning disable 612, 618
|
|||
modelBuilder |
|||
.HasAnnotation("_Abp_DatabaseProvider", EfCoreDatabaseProvider.MySql) |
|||
.HasAnnotation("ProductVersion", "6.0.11") |
|||
.HasAnnotation("Relational:MaxIdentifierLength", 64); |
|||
|
|||
modelBuilder.Entity("LINGYUN.Platform.Datas.Data", b => |
|||
{ |
|||
b.Property<Guid>("Id") |
|||
.ValueGeneratedOnAdd() |
|||
.HasColumnType("char(36)"); |
|||
|
|||
b.Property<string>("Code") |
|||
.IsRequired() |
|||
.HasMaxLength(1024) |
|||
.HasColumnType("varchar(1024)") |
|||
.HasColumnName("Code"); |
|||
|
|||
b.Property<string>("ConcurrencyStamp") |
|||
.IsConcurrencyToken() |
|||
.HasMaxLength(40) |
|||
.HasColumnType("varchar(40)") |
|||
.HasColumnName("ConcurrencyStamp"); |
|||
|
|||
b.Property<DateTime>("CreationTime") |
|||
.HasColumnType("datetime(6)") |
|||
.HasColumnName("CreationTime"); |
|||
|
|||
b.Property<Guid?>("CreatorId") |
|||
.HasColumnType("char(36)") |
|||
.HasColumnName("CreatorId"); |
|||
|
|||
b.Property<Guid?>("DeleterId") |
|||
.HasColumnType("char(36)") |
|||
.HasColumnName("DeleterId"); |
|||
|
|||
b.Property<DateTime?>("DeletionTime") |
|||
.HasColumnType("datetime(6)") |
|||
.HasColumnName("DeletionTime"); |
|||
|
|||
b.Property<string>("Description") |
|||
.HasMaxLength(1024) |
|||
.HasColumnType("varchar(1024)") |
|||
.HasColumnName("Description"); |
|||
|
|||
b.Property<string>("DisplayName") |
|||
.IsRequired() |
|||
.HasMaxLength(128) |
|||
.HasColumnType("varchar(128)") |
|||
.HasColumnName("DisplayName"); |
|||
|
|||
b.Property<string>("ExtraProperties") |
|||
.HasColumnType("longtext") |
|||
.HasColumnName("ExtraProperties"); |
|||
|
|||
b.Property<bool>("IsDeleted") |
|||
.ValueGeneratedOnAdd() |
|||
.HasColumnType("tinyint(1)") |
|||
.HasDefaultValue(false) |
|||
.HasColumnName("IsDeleted"); |
|||
|
|||
b.Property<bool>("IsStatic") |
|||
.HasColumnType("tinyint(1)"); |
|||
|
|||
b.Property<DateTime?>("LastModificationTime") |
|||
.HasColumnType("datetime(6)") |
|||
.HasColumnName("LastModificationTime"); |
|||
|
|||
b.Property<Guid?>("LastModifierId") |
|||
.HasColumnType("char(36)") |
|||
.HasColumnName("LastModifierId"); |
|||
|
|||
b.Property<string>("Name") |
|||
.IsRequired() |
|||
.HasMaxLength(30) |
|||
.HasColumnType("varchar(30)") |
|||
.HasColumnName("Name"); |
|||
|
|||
b.Property<Guid?>("ParentId") |
|||
.HasColumnType("char(36)"); |
|||
|
|||
b.Property<Guid?>("TenantId") |
|||
.HasColumnType("char(36)") |
|||
.HasColumnName("TenantId"); |
|||
|
|||
b.HasKey("Id"); |
|||
|
|||
b.HasIndex("Name"); |
|||
|
|||
b.ToTable("AppPlatformDatas", (string)null); |
|||
}); |
|||
|
|||
modelBuilder.Entity("LINGYUN.Platform.Datas.DataItem", b => |
|||
{ |
|||
b.Property<Guid>("Id") |
|||
.ValueGeneratedOnAdd() |
|||
.HasColumnType("char(36)"); |
|||
|
|||
b.Property<bool>("AllowBeNull") |
|||
.ValueGeneratedOnAdd() |
|||
.HasColumnType("tinyint(1)") |
|||
.HasDefaultValue(true); |
|||
|
|||
b.Property<string>("ConcurrencyStamp") |
|||
.IsConcurrencyToken() |
|||
.HasMaxLength(40) |
|||
.HasColumnType("varchar(40)") |
|||
.HasColumnName("ConcurrencyStamp"); |
|||
|
|||
b.Property<DateTime>("CreationTime") |
|||
.HasColumnType("datetime(6)") |
|||
.HasColumnName("CreationTime"); |
|||
|
|||
b.Property<Guid?>("CreatorId") |
|||
.HasColumnType("char(36)") |
|||
.HasColumnName("CreatorId"); |
|||
|
|||
b.Property<Guid>("DataId") |
|||
.HasColumnType("char(36)"); |
|||
|
|||
b.Property<string>("DefaultValue") |
|||
.HasMaxLength(128) |
|||
.HasColumnType("varchar(128)") |
|||
.HasColumnName("DefaultValue"); |
|||
|
|||
b.Property<Guid?>("DeleterId") |
|||
.HasColumnType("char(36)") |
|||
.HasColumnName("DeleterId"); |
|||
|
|||
b.Property<DateTime?>("DeletionTime") |
|||
.HasColumnType("datetime(6)") |
|||
.HasColumnName("DeletionTime"); |
|||
|
|||
b.Property<string>("Description") |
|||
.HasMaxLength(1024) |
|||
.HasColumnType("varchar(1024)") |
|||
.HasColumnName("Description"); |
|||
|
|||
b.Property<string>("DisplayName") |
|||
.IsRequired() |
|||
.HasMaxLength(128) |
|||
.HasColumnType("varchar(128)") |
|||
.HasColumnName("DisplayName"); |
|||
|
|||
b.Property<string>("ExtraProperties") |
|||
.HasColumnType("longtext") |
|||
.HasColumnName("ExtraProperties"); |
|||
|
|||
b.Property<bool>("IsDeleted") |
|||
.ValueGeneratedOnAdd() |
|||
.HasColumnType("tinyint(1)") |
|||
.HasDefaultValue(false) |
|||
.HasColumnName("IsDeleted"); |
|||
|
|||
b.Property<bool>("IsStatic") |
|||
.HasColumnType("tinyint(1)"); |
|||
|
|||
b.Property<DateTime?>("LastModificationTime") |
|||
.HasColumnType("datetime(6)") |
|||
.HasColumnName("LastModificationTime"); |
|||
|
|||
b.Property<Guid?>("LastModifierId") |
|||
.HasColumnType("char(36)") |
|||
.HasColumnName("LastModifierId"); |
|||
|
|||
b.Property<string>("Name") |
|||
.IsRequired() |
|||
.HasMaxLength(30) |
|||
.HasColumnType("varchar(30)") |
|||
.HasColumnName("Name"); |
|||
|
|||
b.Property<Guid?>("TenantId") |
|||
.HasColumnType("char(36)") |
|||
.HasColumnName("TenantId"); |
|||
|
|||
b.Property<int>("ValueType") |
|||
.HasColumnType("int"); |
|||
|
|||
b.HasKey("Id"); |
|||
|
|||
b.HasIndex("DataId"); |
|||
|
|||
b.HasIndex("Name"); |
|||
|
|||
b.ToTable("AppPlatformDataItems", (string)null); |
|||
}); |
|||
|
|||
modelBuilder.Entity("LINGYUN.Platform.Layouts.Layout", b => |
|||
{ |
|||
b.Property<Guid>("Id") |
|||
.ValueGeneratedOnAdd() |
|||
.HasColumnType("char(36)"); |
|||
|
|||
b.Property<string>("ConcurrencyStamp") |
|||
.IsConcurrencyToken() |
|||
.HasMaxLength(40) |
|||
.HasColumnType("varchar(40)") |
|||
.HasColumnName("ConcurrencyStamp"); |
|||
|
|||
b.Property<DateTime>("CreationTime") |
|||
.HasColumnType("datetime(6)") |
|||
.HasColumnName("CreationTime"); |
|||
|
|||
b.Property<Guid?>("CreatorId") |
|||
.HasColumnType("char(36)") |
|||
.HasColumnName("CreatorId"); |
|||
|
|||
b.Property<Guid>("DataId") |
|||
.HasColumnType("char(36)"); |
|||
|
|||
b.Property<Guid?>("DeleterId") |
|||
.HasColumnType("char(36)") |
|||
.HasColumnName("DeleterId"); |
|||
|
|||
b.Property<DateTime?>("DeletionTime") |
|||
.HasColumnType("datetime(6)") |
|||
.HasColumnName("DeletionTime"); |
|||
|
|||
b.Property<string>("Description") |
|||
.HasColumnType("longtext"); |
|||
|
|||
b.Property<string>("DisplayName") |
|||
.IsRequired() |
|||
.HasMaxLength(128) |
|||
.HasColumnType("varchar(128)") |
|||
.HasColumnName("DisplayName"); |
|||
|
|||
b.Property<string>("ExtraProperties") |
|||
.HasColumnType("longtext") |
|||
.HasColumnName("ExtraProperties"); |
|||
|
|||
b.Property<string>("Framework") |
|||
.IsRequired() |
|||
.HasMaxLength(64) |
|||
.HasColumnType("varchar(64)") |
|||
.HasColumnName("Framework"); |
|||
|
|||
b.Property<bool>("IsDeleted") |
|||
.ValueGeneratedOnAdd() |
|||
.HasColumnType("tinyint(1)") |
|||
.HasDefaultValue(false) |
|||
.HasColumnName("IsDeleted"); |
|||
|
|||
b.Property<DateTime?>("LastModificationTime") |
|||
.HasColumnType("datetime(6)") |
|||
.HasColumnName("LastModificationTime"); |
|||
|
|||
b.Property<Guid?>("LastModifierId") |
|||
.HasColumnType("char(36)") |
|||
.HasColumnName("LastModifierId"); |
|||
|
|||
b.Property<string>("Name") |
|||
.IsRequired() |
|||
.HasMaxLength(64) |
|||
.HasColumnType("varchar(64)") |
|||
.HasColumnName("Name"); |
|||
|
|||
b.Property<string>("Path") |
|||
.HasMaxLength(255) |
|||
.HasColumnType("varchar(255)") |
|||
.HasColumnName("Path"); |
|||
|
|||
b.Property<string>("Redirect") |
|||
.HasMaxLength(255) |
|||
.HasColumnType("varchar(255)") |
|||
.HasColumnName("Redirect"); |
|||
|
|||
b.Property<Guid?>("TenantId") |
|||
.HasColumnType("char(36)") |
|||
.HasColumnName("TenantId"); |
|||
|
|||
b.HasKey("Id"); |
|||
|
|||
b.ToTable("AppPlatformLayouts", (string)null); |
|||
}); |
|||
|
|||
modelBuilder.Entity("LINGYUN.Platform.Menus.Menu", b => |
|||
{ |
|||
b.Property<Guid>("Id") |
|||
.ValueGeneratedOnAdd() |
|||
.HasColumnType("char(36)"); |
|||
|
|||
b.Property<string>("Code") |
|||
.IsRequired() |
|||
.HasMaxLength(23) |
|||
.HasColumnType("varchar(23)") |
|||
.HasColumnName("Code"); |
|||
|
|||
b.Property<string>("Component") |
|||
.IsRequired() |
|||
.HasMaxLength(255) |
|||
.HasColumnType("varchar(255)") |
|||
.HasColumnName("Component"); |
|||
|
|||
b.Property<string>("ConcurrencyStamp") |
|||
.IsConcurrencyToken() |
|||
.HasMaxLength(40) |
|||
.HasColumnType("varchar(40)") |
|||
.HasColumnName("ConcurrencyStamp"); |
|||
|
|||
b.Property<DateTime>("CreationTime") |
|||
.HasColumnType("datetime(6)") |
|||
.HasColumnName("CreationTime"); |
|||
|
|||
b.Property<Guid?>("CreatorId") |
|||
.HasColumnType("char(36)") |
|||
.HasColumnName("CreatorId"); |
|||
|
|||
b.Property<Guid?>("DeleterId") |
|||
.HasColumnType("char(36)") |
|||
.HasColumnName("DeleterId"); |
|||
|
|||
b.Property<DateTime?>("DeletionTime") |
|||
.HasColumnType("datetime(6)") |
|||
.HasColumnName("DeletionTime"); |
|||
|
|||
b.Property<string>("Description") |
|||
.HasColumnType("longtext"); |
|||
|
|||
b.Property<string>("DisplayName") |
|||
.IsRequired() |
|||
.HasMaxLength(128) |
|||
.HasColumnType("varchar(128)") |
|||
.HasColumnName("DisplayName"); |
|||
|
|||
b.Property<string>("ExtraProperties") |
|||
.HasColumnType("longtext") |
|||
.HasColumnName("ExtraProperties"); |
|||
|
|||
b.Property<string>("Framework") |
|||
.IsRequired() |
|||
.HasMaxLength(64) |
|||
.HasColumnType("varchar(64)") |
|||
.HasColumnName("Framework"); |
|||
|
|||
b.Property<bool>("IsDeleted") |
|||
.ValueGeneratedOnAdd() |
|||
.HasColumnType("tinyint(1)") |
|||
.HasDefaultValue(false) |
|||
.HasColumnName("IsDeleted"); |
|||
|
|||
b.Property<bool>("IsPublic") |
|||
.HasColumnType("tinyint(1)"); |
|||
|
|||
b.Property<DateTime?>("LastModificationTime") |
|||
.HasColumnType("datetime(6)") |
|||
.HasColumnName("LastModificationTime"); |
|||
|
|||
b.Property<Guid?>("LastModifierId") |
|||
.HasColumnType("char(36)") |
|||
.HasColumnName("LastModifierId"); |
|||
|
|||
b.Property<Guid>("LayoutId") |
|||
.HasColumnType("char(36)"); |
|||
|
|||
b.Property<string>("Name") |
|||
.IsRequired() |
|||
.HasMaxLength(64) |
|||
.HasColumnType("varchar(64)") |
|||
.HasColumnName("Name"); |
|||
|
|||
b.Property<Guid?>("ParentId") |
|||
.HasColumnType("char(36)"); |
|||
|
|||
b.Property<string>("Path") |
|||
.HasMaxLength(255) |
|||
.HasColumnType("varchar(255)") |
|||
.HasColumnName("Path"); |
|||
|
|||
b.Property<string>("Redirect") |
|||
.HasMaxLength(255) |
|||
.HasColumnType("varchar(255)") |
|||
.HasColumnName("Redirect"); |
|||
|
|||
b.Property<Guid?>("TenantId") |
|||
.HasColumnType("char(36)") |
|||
.HasColumnName("TenantId"); |
|||
|
|||
b.HasKey("Id"); |
|||
|
|||
b.ToTable("AppPlatformMenus", (string)null); |
|||
}); |
|||
|
|||
modelBuilder.Entity("LINGYUN.Platform.Menus.RoleMenu", b => |
|||
{ |
|||
b.Property<Guid>("Id") |
|||
.ValueGeneratedOnAdd() |
|||
.HasColumnType("char(36)"); |
|||
|
|||
b.Property<DateTime>("CreationTime") |
|||
.HasColumnType("datetime(6)") |
|||
.HasColumnName("CreationTime"); |
|||
|
|||
b.Property<Guid?>("CreatorId") |
|||
.HasColumnType("char(36)") |
|||
.HasColumnName("CreatorId"); |
|||
|
|||
b.Property<DateTime?>("LastModificationTime") |
|||
.HasColumnType("datetime(6)") |
|||
.HasColumnName("LastModificationTime"); |
|||
|
|||
b.Property<Guid?>("LastModifierId") |
|||
.HasColumnType("char(36)") |
|||
.HasColumnName("LastModifierId"); |
|||
|
|||
b.Property<Guid>("MenuId") |
|||
.HasColumnType("char(36)"); |
|||
|
|||
b.Property<string>("RoleName") |
|||
.IsRequired() |
|||
.HasMaxLength(256) |
|||
.HasColumnType("varchar(256)") |
|||
.HasColumnName("RoleName"); |
|||
|
|||
b.Property<bool>("Startup") |
|||
.HasColumnType("tinyint(1)"); |
|||
|
|||
b.Property<Guid?>("TenantId") |
|||
.HasColumnType("char(36)") |
|||
.HasColumnName("TenantId"); |
|||
|
|||
b.HasKey("Id"); |
|||
|
|||
b.HasIndex("RoleName", "MenuId"); |
|||
|
|||
b.ToTable("AppPlatformRoleMenus", (string)null); |
|||
}); |
|||
|
|||
modelBuilder.Entity("LINGYUN.Platform.Menus.UserFavoriteMenu", b => |
|||
{ |
|||
b.Property<Guid>("Id") |
|||
.ValueGeneratedOnAdd() |
|||
.HasColumnType("char(36)"); |
|||
|
|||
b.Property<string>("AliasName") |
|||
.HasMaxLength(128) |
|||
.HasColumnType("varchar(128)") |
|||
.HasColumnName("AliasName"); |
|||
|
|||
b.Property<string>("Color") |
|||
.HasMaxLength(30) |
|||
.HasColumnType("varchar(30)") |
|||
.HasColumnName("Color"); |
|||
|
|||
b.Property<DateTime>("CreationTime") |
|||
.HasColumnType("datetime(6)") |
|||
.HasColumnName("CreationTime"); |
|||
|
|||
b.Property<Guid?>("CreatorId") |
|||
.HasColumnType("char(36)") |
|||
.HasColumnName("CreatorId"); |
|||
|
|||
b.Property<string>("DisplayName") |
|||
.IsRequired() |
|||
.HasMaxLength(128) |
|||
.HasColumnType("varchar(128)") |
|||
.HasColumnName("DisplayName"); |
|||
|
|||
b.Property<string>("Framework") |
|||
.IsRequired() |
|||
.HasMaxLength(64) |
|||
.HasColumnType("varchar(64)") |
|||
.HasColumnName("Framework"); |
|||
|
|||
b.Property<string>("Icon") |
|||
.HasMaxLength(512) |
|||
.HasColumnType("varchar(512)") |
|||
.HasColumnName("Icon"); |
|||
|
|||
b.Property<DateTime?>("LastModificationTime") |
|||
.HasColumnType("datetime(6)") |
|||
.HasColumnName("LastModificationTime"); |
|||
|
|||
b.Property<Guid?>("LastModifierId") |
|||
.HasColumnType("char(36)") |
|||
.HasColumnName("LastModifierId"); |
|||
|
|||
b.Property<Guid>("MenuId") |
|||
.HasColumnType("char(36)"); |
|||
|
|||
b.Property<string>("Name") |
|||
.IsRequired() |
|||
.HasMaxLength(64) |
|||
.HasColumnType("varchar(64)") |
|||
.HasColumnName("Name"); |
|||
|
|||
b.Property<string>("Path") |
|||
.IsRequired() |
|||
.HasMaxLength(255) |
|||
.HasColumnType("varchar(255)") |
|||
.HasColumnName("Path"); |
|||
|
|||
b.Property<Guid?>("TenantId") |
|||
.HasColumnType("char(36)") |
|||
.HasColumnName("TenantId"); |
|||
|
|||
b.Property<Guid>("UserId") |
|||
.HasColumnType("char(36)"); |
|||
|
|||
b.HasKey("Id"); |
|||
|
|||
b.HasIndex("UserId", "MenuId"); |
|||
|
|||
b.ToTable("AppPlatformUserFavoriteMenus", (string)null); |
|||
}); |
|||
|
|||
modelBuilder.Entity("LINGYUN.Platform.Menus.UserMenu", b => |
|||
{ |
|||
b.Property<Guid>("Id") |
|||
.ValueGeneratedOnAdd() |
|||
.HasColumnType("char(36)"); |
|||
|
|||
b.Property<DateTime>("CreationTime") |
|||
.HasColumnType("datetime(6)") |
|||
.HasColumnName("CreationTime"); |
|||
|
|||
b.Property<Guid?>("CreatorId") |
|||
.HasColumnType("char(36)") |
|||
.HasColumnName("CreatorId"); |
|||
|
|||
b.Property<DateTime?>("LastModificationTime") |
|||
.HasColumnType("datetime(6)") |
|||
.HasColumnName("LastModificationTime"); |
|||
|
|||
b.Property<Guid?>("LastModifierId") |
|||
.HasColumnType("char(36)") |
|||
.HasColumnName("LastModifierId"); |
|||
|
|||
b.Property<Guid>("MenuId") |
|||
.HasColumnType("char(36)"); |
|||
|
|||
b.Property<bool>("Startup") |
|||
.HasColumnType("tinyint(1)"); |
|||
|
|||
b.Property<Guid?>("TenantId") |
|||
.HasColumnType("char(36)") |
|||
.HasColumnName("TenantId"); |
|||
|
|||
b.Property<Guid>("UserId") |
|||
.HasColumnType("char(36)"); |
|||
|
|||
b.HasKey("Id"); |
|||
|
|||
b.HasIndex("UserId", "MenuId"); |
|||
|
|||
b.ToTable("AppPlatformUserMenus", (string)null); |
|||
}); |
|||
|
|||
modelBuilder.Entity("LINGYUN.Platform.Packages.Package", b => |
|||
{ |
|||
b.Property<Guid>("Id") |
|||
.ValueGeneratedOnAdd() |
|||
.HasColumnType("char(36)"); |
|||
|
|||
b.Property<string>("Authors") |
|||
.HasMaxLength(100) |
|||
.HasColumnType("varchar(100)") |
|||
.HasColumnName("Authors"); |
|||
|
|||
b.Property<string>("ConcurrencyStamp") |
|||
.IsConcurrencyToken() |
|||
.HasMaxLength(40) |
|||
.HasColumnType("varchar(40)") |
|||
.HasColumnName("ConcurrencyStamp"); |
|||
|
|||
b.Property<DateTime>("CreationTime") |
|||
.HasColumnType("datetime(6)") |
|||
.HasColumnName("CreationTime"); |
|||
|
|||
b.Property<Guid?>("CreatorId") |
|||
.HasColumnType("char(36)") |
|||
.HasColumnName("CreatorId"); |
|||
|
|||
b.Property<Guid?>("DeleterId") |
|||
.HasColumnType("char(36)") |
|||
.HasColumnName("DeleterId"); |
|||
|
|||
b.Property<DateTime?>("DeletionTime") |
|||
.HasColumnType("datetime(6)") |
|||
.HasColumnName("DeletionTime"); |
|||
|
|||
b.Property<string>("Description") |
|||
.HasMaxLength(255) |
|||
.HasColumnType("varchar(255)") |
|||
.HasColumnName("Description"); |
|||
|
|||
b.Property<string>("ExtraProperties") |
|||
.HasColumnType("longtext") |
|||
.HasColumnName("ExtraProperties"); |
|||
|
|||
b.Property<bool>("ForceUpdate") |
|||
.HasColumnType("tinyint(1)"); |
|||
|
|||
b.Property<bool>("IsDeleted") |
|||
.ValueGeneratedOnAdd() |
|||
.HasColumnType("tinyint(1)") |
|||
.HasDefaultValue(false) |
|||
.HasColumnName("IsDeleted"); |
|||
|
|||
b.Property<DateTime?>("LastModificationTime") |
|||
.HasColumnType("datetime(6)") |
|||
.HasColumnName("LastModificationTime"); |
|||
|
|||
b.Property<Guid?>("LastModifierId") |
|||
.HasColumnType("char(36)") |
|||
.HasColumnName("LastModifierId"); |
|||
|
|||
b.Property<int>("Level") |
|||
.HasColumnType("int"); |
|||
|
|||
b.Property<string>("Name") |
|||
.IsRequired() |
|||
.HasMaxLength(255) |
|||
.HasColumnType("varchar(255)") |
|||
.HasColumnName("Name"); |
|||
|
|||
b.Property<string>("Note") |
|||
.IsRequired() |
|||
.HasMaxLength(1024) |
|||
.HasColumnType("varchar(1024)") |
|||
.HasColumnName("Note"); |
|||
|
|||
b.Property<Guid?>("TenantId") |
|||
.HasColumnType("char(36)") |
|||
.HasColumnName("TenantId"); |
|||
|
|||
b.Property<string>("Version") |
|||
.IsRequired() |
|||
.HasMaxLength(30) |
|||
.HasColumnType("varchar(30)") |
|||
.HasColumnName("Version"); |
|||
|
|||
b.HasKey("Id"); |
|||
|
|||
b.HasIndex("Name", "Version"); |
|||
|
|||
b.ToTable("AppPlatformPackages", (string)null); |
|||
}); |
|||
|
|||
modelBuilder.Entity("LINGYUN.Platform.Packages.PackageBlob", b => |
|||
{ |
|||
b.Property<int>("Id") |
|||
.ValueGeneratedOnAdd() |
|||
.HasColumnType("int"); |
|||
|
|||
b.Property<string>("Authors") |
|||
.HasMaxLength(100) |
|||
.HasColumnType("varchar(100)") |
|||
.HasColumnName("Authors"); |
|||
|
|||
b.Property<string>("ContentType") |
|||
.HasMaxLength(256) |
|||
.HasColumnType("varchar(256)") |
|||
.HasColumnName("ContentType"); |
|||
|
|||
b.Property<DateTime>("CreatedAt") |
|||
.HasColumnType("datetime(6)"); |
|||
|
|||
b.Property<DateTime>("CreationTime") |
|||
.HasColumnType("datetime(6)") |
|||
.HasColumnName("CreationTime"); |
|||
|
|||
b.Property<Guid?>("CreatorId") |
|||
.HasColumnType("char(36)") |
|||
.HasColumnName("CreatorId"); |
|||
|
|||
b.Property<int>("DownloadCount") |
|||
.HasColumnType("int"); |
|||
|
|||
b.Property<string>("License") |
|||
.HasMaxLength(1024) |
|||
.HasColumnType("varchar(1024)") |
|||
.HasColumnName("License"); |
|||
|
|||
b.Property<string>("Name") |
|||
.IsRequired() |
|||
.HasMaxLength(255) |
|||
.HasColumnType("varchar(255)") |
|||
.HasColumnName("Name"); |
|||
|
|||
b.Property<Guid>("PackageId") |
|||
.HasColumnType("char(36)"); |
|||
|
|||
b.Property<string>("SHA256") |
|||
.HasMaxLength(256) |
|||
.HasColumnType("varchar(256)") |
|||
.HasColumnName("SHA256"); |
|||
|
|||
b.Property<long?>("Size") |
|||
.HasColumnType("bigint"); |
|||
|
|||
b.Property<string>("Summary") |
|||
.HasMaxLength(1024) |
|||
.HasColumnType("varchar(1024)") |
|||
.HasColumnName("Summary"); |
|||
|
|||
b.Property<Guid?>("TenantId") |
|||
.HasColumnType("char(36)") |
|||
.HasColumnName("TenantId"); |
|||
|
|||
b.Property<DateTime?>("UpdatedAt") |
|||
.HasColumnType("datetime(6)"); |
|||
|
|||
b.Property<string>("Url") |
|||
.HasMaxLength(512) |
|||
.HasColumnType("varchar(512)") |
|||
.HasColumnName("Url"); |
|||
|
|||
b.HasKey("Id"); |
|||
|
|||
b.HasIndex("PackageId", "Name"); |
|||
|
|||
b.ToTable("AppPlatformPackageBlobs", (string)null); |
|||
}); |
|||
|
|||
modelBuilder.Entity("LINGYUN.Platform.Versions.AppVersion", b => |
|||
{ |
|||
b.Property<Guid>("Id") |
|||
.ValueGeneratedOnAdd() |
|||
.HasColumnType("char(36)"); |
|||
|
|||
b.Property<string>("ConcurrencyStamp") |
|||
.IsConcurrencyToken() |
|||
.HasMaxLength(40) |
|||
.HasColumnType("varchar(40)") |
|||
.HasColumnName("ConcurrencyStamp"); |
|||
|
|||
b.Property<DateTime>("CreationTime") |
|||
.HasColumnType("datetime(6)") |
|||
.HasColumnName("CreationTime"); |
|||
|
|||
b.Property<Guid?>("CreatorId") |
|||
.HasColumnType("char(36)") |
|||
.HasColumnName("CreatorId"); |
|||
|
|||
b.Property<Guid?>("DeleterId") |
|||
.HasColumnType("char(36)") |
|||
.HasColumnName("DeleterId"); |
|||
|
|||
b.Property<DateTime?>("DeletionTime") |
|||
.HasColumnType("datetime(6)") |
|||
.HasColumnName("DeletionTime"); |
|||
|
|||
b.Property<string>("Description") |
|||
.HasMaxLength(2048) |
|||
.HasColumnType("varchar(2048)") |
|||
.HasColumnName("Description"); |
|||
|
|||
b.Property<string>("ExtraProperties") |
|||
.HasColumnType("longtext") |
|||
.HasColumnName("ExtraProperties"); |
|||
|
|||
b.Property<bool>("IsDeleted") |
|||
.ValueGeneratedOnAdd() |
|||
.HasColumnType("tinyint(1)") |
|||
.HasDefaultValue(false) |
|||
.HasColumnName("IsDeleted"); |
|||
|
|||
b.Property<DateTime?>("LastModificationTime") |
|||
.HasColumnType("datetime(6)") |
|||
.HasColumnName("LastModificationTime"); |
|||
|
|||
b.Property<Guid?>("LastModifierId") |
|||
.HasColumnType("char(36)") |
|||
.HasColumnName("LastModifierId"); |
|||
|
|||
b.Property<int>("Level") |
|||
.HasColumnType("int"); |
|||
|
|||
b.Property<int>("PlatformType") |
|||
.HasColumnType("int"); |
|||
|
|||
b.Property<Guid?>("TenantId") |
|||
.HasColumnType("char(36)") |
|||
.HasColumnName("TenantId"); |
|||
|
|||
b.Property<string>("Title") |
|||
.IsRequired() |
|||
.HasMaxLength(50) |
|||
.HasColumnType("varchar(50)") |
|||
.HasColumnName("Title"); |
|||
|
|||
b.Property<string>("Version") |
|||
.IsRequired() |
|||
.HasMaxLength(20) |
|||
.HasColumnType("varchar(20)") |
|||
.HasColumnName("Version"); |
|||
|
|||
b.HasKey("Id"); |
|||
|
|||
b.HasIndex("Version"); |
|||
|
|||
b.ToTable("AppPlatformVersion", (string)null); |
|||
}); |
|||
|
|||
modelBuilder.Entity("LINGYUN.Platform.Versions.VersionFile", b => |
|||
{ |
|||
b.Property<int>("Id") |
|||
.ValueGeneratedOnAdd() |
|||
.HasColumnType("int"); |
|||
|
|||
b.Property<Guid>("AppVersionId") |
|||
.HasColumnType("char(36)"); |
|||
|
|||
b.Property<DateTime>("CreationTime") |
|||
.HasColumnType("datetime(6)") |
|||
.HasColumnName("CreationTime"); |
|||
|
|||
b.Property<Guid?>("CreatorId") |
|||
.HasColumnType("char(36)") |
|||
.HasColumnName("CreatorId"); |
|||
|
|||
b.Property<int>("DownloadCount") |
|||
.HasColumnType("int"); |
|||
|
|||
b.Property<int>("FileType") |
|||
.HasColumnType("int"); |
|||
|
|||
b.Property<DateTime?>("LastModificationTime") |
|||
.HasColumnType("datetime(6)") |
|||
.HasColumnName("LastModificationTime"); |
|||
|
|||
b.Property<Guid?>("LastModifierId") |
|||
.HasColumnType("char(36)") |
|||
.HasColumnName("LastModifierId"); |
|||
|
|||
b.Property<string>("Name") |
|||
.IsRequired() |
|||
.HasMaxLength(255) |
|||
.HasColumnType("varchar(255)") |
|||
.HasColumnName("Name"); |
|||
|
|||
b.Property<string>("Path") |
|||
.HasMaxLength(255) |
|||
.HasColumnType("varchar(255)") |
|||
.HasColumnName("Path"); |
|||
|
|||
b.Property<string>("SHA256") |
|||
.IsRequired() |
|||
.HasMaxLength(65) |
|||
.HasColumnType("varchar(65)") |
|||
.HasColumnName("SHA256"); |
|||
|
|||
b.Property<long>("Size") |
|||
.HasColumnType("bigint"); |
|||
|
|||
b.Property<Guid?>("TenantId") |
|||
.HasColumnType("char(36)") |
|||
.HasColumnName("TenantId"); |
|||
|
|||
b.Property<string>("Version") |
|||
.IsRequired() |
|||
.HasMaxLength(20) |
|||
.HasColumnType("varchar(20)") |
|||
.HasColumnName("Version"); |
|||
|
|||
b.HasKey("Id"); |
|||
|
|||
b.HasIndex("AppVersionId"); |
|||
|
|||
b.HasIndex("Path", "Name", "Version") |
|||
.IsUnique(); |
|||
|
|||
b.ToTable("AppPlatformVersionFile", (string)null); |
|||
}); |
|||
|
|||
modelBuilder.Entity("LINGYUN.Platform.Datas.DataItem", b => |
|||
{ |
|||
b.HasOne("LINGYUN.Platform.Datas.Data", null) |
|||
.WithMany("Items") |
|||
.HasForeignKey("DataId") |
|||
.OnDelete(DeleteBehavior.Cascade) |
|||
.IsRequired(); |
|||
}); |
|||
|
|||
modelBuilder.Entity("LINGYUN.Platform.Packages.PackageBlob", b => |
|||
{ |
|||
b.HasOne("LINGYUN.Platform.Packages.Package", "Package") |
|||
.WithMany("Blobs") |
|||
.HasForeignKey("PackageId") |
|||
.OnDelete(DeleteBehavior.Cascade) |
|||
.IsRequired(); |
|||
|
|||
b.Navigation("Package"); |
|||
}); |
|||
|
|||
modelBuilder.Entity("LINGYUN.Platform.Versions.VersionFile", b => |
|||
{ |
|||
b.HasOne("LINGYUN.Platform.Versions.AppVersion", "AppVersion") |
|||
.WithMany("Files") |
|||
.HasForeignKey("AppVersionId") |
|||
.OnDelete(DeleteBehavior.Cascade) |
|||
.IsRequired(); |
|||
|
|||
b.Navigation("AppVersion"); |
|||
}); |
|||
|
|||
modelBuilder.Entity("LINGYUN.Platform.Datas.Data", b => |
|||
{ |
|||
b.Navigation("Items"); |
|||
}); |
|||
|
|||
modelBuilder.Entity("LINGYUN.Platform.Packages.Package", b => |
|||
{ |
|||
b.Navigation("Blobs"); |
|||
}); |
|||
|
|||
modelBuilder.Entity("LINGYUN.Platform.Versions.AppVersion", b => |
|||
{ |
|||
b.Navigation("Files"); |
|||
}); |
|||
#pragma warning restore 612, 618
|
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,110 @@ |
|||
using System; |
|||
using Microsoft.EntityFrameworkCore.Metadata; |
|||
using Microsoft.EntityFrameworkCore.Migrations; |
|||
|
|||
#nullable disable |
|||
|
|||
namespace LY.MicroService.PlatformManagement.Migrations |
|||
{ |
|||
public partial class AddPackageManager : Migration |
|||
{ |
|||
protected override void Up(MigrationBuilder migrationBuilder) |
|||
{ |
|||
migrationBuilder.CreateTable( |
|||
name: "AppPlatformPackages", |
|||
columns: table => new |
|||
{ |
|||
Id = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci"), |
|||
TenantId = table.Column<Guid>(type: "char(36)", nullable: true, collation: "ascii_general_ci"), |
|||
Name = table.Column<string>(type: "varchar(255)", maxLength: 255, nullable: false) |
|||
.Annotation("MySql:CharSet", "utf8mb4"), |
|||
Note = table.Column<string>(type: "varchar(1024)", maxLength: 1024, nullable: false) |
|||
.Annotation("MySql:CharSet", "utf8mb4"), |
|||
Version = table.Column<string>(type: "varchar(30)", maxLength: 30, nullable: false) |
|||
.Annotation("MySql:CharSet", "utf8mb4"), |
|||
Description = table.Column<string>(type: "varchar(255)", maxLength: 255, nullable: true) |
|||
.Annotation("MySql:CharSet", "utf8mb4"), |
|||
ForceUpdate = table.Column<bool>(type: "tinyint(1)", nullable: false), |
|||
Authors = table.Column<string>(type: "varchar(100)", maxLength: 100, nullable: true) |
|||
.Annotation("MySql:CharSet", "utf8mb4"), |
|||
Level = table.Column<int>(type: "int", nullable: false), |
|||
ExtraProperties = table.Column<string>(type: "longtext", nullable: true) |
|||
.Annotation("MySql:CharSet", "utf8mb4"), |
|||
ConcurrencyStamp = table.Column<string>(type: "varchar(40)", maxLength: 40, nullable: true) |
|||
.Annotation("MySql:CharSet", "utf8mb4"), |
|||
CreationTime = table.Column<DateTime>(type: "datetime(6)", nullable: false), |
|||
CreatorId = table.Column<Guid>(type: "char(36)", nullable: true, collation: "ascii_general_ci"), |
|||
LastModificationTime = table.Column<DateTime>(type: "datetime(6)", nullable: true), |
|||
LastModifierId = table.Column<Guid>(type: "char(36)", nullable: true, collation: "ascii_general_ci"), |
|||
IsDeleted = table.Column<bool>(type: "tinyint(1)", nullable: false, defaultValue: false), |
|||
DeleterId = table.Column<Guid>(type: "char(36)", nullable: true, collation: "ascii_general_ci"), |
|||
DeletionTime = table.Column<DateTime>(type: "datetime(6)", nullable: true) |
|||
}, |
|||
constraints: table => |
|||
{ |
|||
table.PrimaryKey("PK_AppPlatformPackages", x => x.Id); |
|||
}) |
|||
.Annotation("MySql:CharSet", "utf8mb4"); |
|||
|
|||
migrationBuilder.CreateTable( |
|||
name: "AppPlatformPackageBlobs", |
|||
columns: table => new |
|||
{ |
|||
Id = table.Column<int>(type: "int", nullable: false) |
|||
.Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn), |
|||
TenantId = table.Column<Guid>(type: "char(36)", nullable: true, collation: "ascii_general_ci"), |
|||
PackageId = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci"), |
|||
Name = table.Column<string>(type: "varchar(255)", maxLength: 255, nullable: false) |
|||
.Annotation("MySql:CharSet", "utf8mb4"), |
|||
Url = table.Column<string>(type: "varchar(512)", maxLength: 512, nullable: true) |
|||
.Annotation("MySql:CharSet", "utf8mb4"), |
|||
Size = table.Column<long>(type: "bigint", nullable: true), |
|||
Summary = table.Column<string>(type: "varchar(1024)", maxLength: 1024, nullable: true) |
|||
.Annotation("MySql:CharSet", "utf8mb4"), |
|||
CreatedAt = table.Column<DateTime>(type: "datetime(6)", nullable: false), |
|||
UpdatedAt = table.Column<DateTime>(type: "datetime(6)", nullable: true), |
|||
License = table.Column<string>(type: "varchar(1024)", maxLength: 1024, nullable: true) |
|||
.Annotation("MySql:CharSet", "utf8mb4"), |
|||
Authors = table.Column<string>(type: "varchar(100)", maxLength: 100, nullable: true) |
|||
.Annotation("MySql:CharSet", "utf8mb4"), |
|||
ContentType = table.Column<string>(type: "varchar(256)", maxLength: 256, nullable: true) |
|||
.Annotation("MySql:CharSet", "utf8mb4"), |
|||
SHA256 = table.Column<string>(type: "varchar(256)", maxLength: 256, nullable: true) |
|||
.Annotation("MySql:CharSet", "utf8mb4"), |
|||
DownloadCount = table.Column<int>(type: "int", nullable: false), |
|||
CreationTime = table.Column<DateTime>(type: "datetime(6)", nullable: false), |
|||
CreatorId = table.Column<Guid>(type: "char(36)", nullable: true, collation: "ascii_general_ci") |
|||
}, |
|||
constraints: table => |
|||
{ |
|||
table.PrimaryKey("PK_AppPlatformPackageBlobs", x => x.Id); |
|||
table.ForeignKey( |
|||
name: "FK_AppPlatformPackageBlobs_AppPlatformPackages_PackageId", |
|||
column: x => x.PackageId, |
|||
principalTable: "AppPlatformPackages", |
|||
principalColumn: "Id", |
|||
onDelete: ReferentialAction.Cascade); |
|||
}) |
|||
.Annotation("MySql:CharSet", "utf8mb4"); |
|||
|
|||
migrationBuilder.CreateIndex( |
|||
name: "IX_AppPlatformPackageBlobs_PackageId_Name", |
|||
table: "AppPlatformPackageBlobs", |
|||
columns: new[] { "PackageId", "Name" }); |
|||
|
|||
migrationBuilder.CreateIndex( |
|||
name: "IX_AppPlatformPackages_Name_Version", |
|||
table: "AppPlatformPackages", |
|||
columns: new[] { "Name", "Version" }); |
|||
} |
|||
|
|||
protected override void Down(MigrationBuilder migrationBuilder) |
|||
{ |
|||
migrationBuilder.DropTable( |
|||
name: "AppPlatformPackageBlobs"); |
|||
|
|||
migrationBuilder.DropTable( |
|||
name: "AppPlatformPackages"); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,771 @@ |
|||
// <auto-generated />
|
|||
using System; |
|||
using LY.MicroService.PlatformManagement.EntityFrameworkCore; |
|||
using Microsoft.EntityFrameworkCore; |
|||
using Microsoft.EntityFrameworkCore.Infrastructure; |
|||
using Microsoft.EntityFrameworkCore.Migrations; |
|||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion; |
|||
using Volo.Abp.EntityFrameworkCore; |
|||
|
|||
#nullable disable |
|||
|
|||
namespace LY.MicroService.PlatformManagement.Migrations |
|||
{ |
|||
[DbContext(typeof(PlatformManagementMigrationsDbContext))] |
|||
[Migration("20221213005241_Remove-Versions")] |
|||
partial class RemoveVersions |
|||
{ |
|||
protected override void BuildTargetModel(ModelBuilder modelBuilder) |
|||
{ |
|||
#pragma warning disable 612, 618
|
|||
modelBuilder |
|||
.HasAnnotation("_Abp_DatabaseProvider", EfCoreDatabaseProvider.MySql) |
|||
.HasAnnotation("ProductVersion", "6.0.11") |
|||
.HasAnnotation("Relational:MaxIdentifierLength", 64); |
|||
|
|||
modelBuilder.Entity("LINGYUN.Platform.Datas.Data", b => |
|||
{ |
|||
b.Property<Guid>("Id") |
|||
.ValueGeneratedOnAdd() |
|||
.HasColumnType("char(36)"); |
|||
|
|||
b.Property<string>("Code") |
|||
.IsRequired() |
|||
.HasMaxLength(1024) |
|||
.HasColumnType("varchar(1024)") |
|||
.HasColumnName("Code"); |
|||
|
|||
b.Property<string>("ConcurrencyStamp") |
|||
.IsConcurrencyToken() |
|||
.HasMaxLength(40) |
|||
.HasColumnType("varchar(40)") |
|||
.HasColumnName("ConcurrencyStamp"); |
|||
|
|||
b.Property<DateTime>("CreationTime") |
|||
.HasColumnType("datetime(6)") |
|||
.HasColumnName("CreationTime"); |
|||
|
|||
b.Property<Guid?>("CreatorId") |
|||
.HasColumnType("char(36)") |
|||
.HasColumnName("CreatorId"); |
|||
|
|||
b.Property<Guid?>("DeleterId") |
|||
.HasColumnType("char(36)") |
|||
.HasColumnName("DeleterId"); |
|||
|
|||
b.Property<DateTime?>("DeletionTime") |
|||
.HasColumnType("datetime(6)") |
|||
.HasColumnName("DeletionTime"); |
|||
|
|||
b.Property<string>("Description") |
|||
.HasMaxLength(1024) |
|||
.HasColumnType("varchar(1024)") |
|||
.HasColumnName("Description"); |
|||
|
|||
b.Property<string>("DisplayName") |
|||
.IsRequired() |
|||
.HasMaxLength(128) |
|||
.HasColumnType("varchar(128)") |
|||
.HasColumnName("DisplayName"); |
|||
|
|||
b.Property<string>("ExtraProperties") |
|||
.HasColumnType("longtext") |
|||
.HasColumnName("ExtraProperties"); |
|||
|
|||
b.Property<bool>("IsDeleted") |
|||
.ValueGeneratedOnAdd() |
|||
.HasColumnType("tinyint(1)") |
|||
.HasDefaultValue(false) |
|||
.HasColumnName("IsDeleted"); |
|||
|
|||
b.Property<bool>("IsStatic") |
|||
.HasColumnType("tinyint(1)"); |
|||
|
|||
b.Property<DateTime?>("LastModificationTime") |
|||
.HasColumnType("datetime(6)") |
|||
.HasColumnName("LastModificationTime"); |
|||
|
|||
b.Property<Guid?>("LastModifierId") |
|||
.HasColumnType("char(36)") |
|||
.HasColumnName("LastModifierId"); |
|||
|
|||
b.Property<string>("Name") |
|||
.IsRequired() |
|||
.HasMaxLength(30) |
|||
.HasColumnType("varchar(30)") |
|||
.HasColumnName("Name"); |
|||
|
|||
b.Property<Guid?>("ParentId") |
|||
.HasColumnType("char(36)"); |
|||
|
|||
b.Property<Guid?>("TenantId") |
|||
.HasColumnType("char(36)") |
|||
.HasColumnName("TenantId"); |
|||
|
|||
b.HasKey("Id"); |
|||
|
|||
b.HasIndex("Name"); |
|||
|
|||
b.ToTable("AppPlatformDatas", (string)null); |
|||
}); |
|||
|
|||
modelBuilder.Entity("LINGYUN.Platform.Datas.DataItem", b => |
|||
{ |
|||
b.Property<Guid>("Id") |
|||
.ValueGeneratedOnAdd() |
|||
.HasColumnType("char(36)"); |
|||
|
|||
b.Property<bool>("AllowBeNull") |
|||
.ValueGeneratedOnAdd() |
|||
.HasColumnType("tinyint(1)") |
|||
.HasDefaultValue(true); |
|||
|
|||
b.Property<string>("ConcurrencyStamp") |
|||
.IsConcurrencyToken() |
|||
.HasMaxLength(40) |
|||
.HasColumnType("varchar(40)") |
|||
.HasColumnName("ConcurrencyStamp"); |
|||
|
|||
b.Property<DateTime>("CreationTime") |
|||
.HasColumnType("datetime(6)") |
|||
.HasColumnName("CreationTime"); |
|||
|
|||
b.Property<Guid?>("CreatorId") |
|||
.HasColumnType("char(36)") |
|||
.HasColumnName("CreatorId"); |
|||
|
|||
b.Property<Guid>("DataId") |
|||
.HasColumnType("char(36)"); |
|||
|
|||
b.Property<string>("DefaultValue") |
|||
.HasMaxLength(128) |
|||
.HasColumnType("varchar(128)") |
|||
.HasColumnName("DefaultValue"); |
|||
|
|||
b.Property<Guid?>("DeleterId") |
|||
.HasColumnType("char(36)") |
|||
.HasColumnName("DeleterId"); |
|||
|
|||
b.Property<DateTime?>("DeletionTime") |
|||
.HasColumnType("datetime(6)") |
|||
.HasColumnName("DeletionTime"); |
|||
|
|||
b.Property<string>("Description") |
|||
.HasMaxLength(1024) |
|||
.HasColumnType("varchar(1024)") |
|||
.HasColumnName("Description"); |
|||
|
|||
b.Property<string>("DisplayName") |
|||
.IsRequired() |
|||
.HasMaxLength(128) |
|||
.HasColumnType("varchar(128)") |
|||
.HasColumnName("DisplayName"); |
|||
|
|||
b.Property<string>("ExtraProperties") |
|||
.HasColumnType("longtext") |
|||
.HasColumnName("ExtraProperties"); |
|||
|
|||
b.Property<bool>("IsDeleted") |
|||
.ValueGeneratedOnAdd() |
|||
.HasColumnType("tinyint(1)") |
|||
.HasDefaultValue(false) |
|||
.HasColumnName("IsDeleted"); |
|||
|
|||
b.Property<bool>("IsStatic") |
|||
.HasColumnType("tinyint(1)"); |
|||
|
|||
b.Property<DateTime?>("LastModificationTime") |
|||
.HasColumnType("datetime(6)") |
|||
.HasColumnName("LastModificationTime"); |
|||
|
|||
b.Property<Guid?>("LastModifierId") |
|||
.HasColumnType("char(36)") |
|||
.HasColumnName("LastModifierId"); |
|||
|
|||
b.Property<string>("Name") |
|||
.IsRequired() |
|||
.HasMaxLength(30) |
|||
.HasColumnType("varchar(30)") |
|||
.HasColumnName("Name"); |
|||
|
|||
b.Property<Guid?>("TenantId") |
|||
.HasColumnType("char(36)") |
|||
.HasColumnName("TenantId"); |
|||
|
|||
b.Property<int>("ValueType") |
|||
.HasColumnType("int"); |
|||
|
|||
b.HasKey("Id"); |
|||
|
|||
b.HasIndex("DataId"); |
|||
|
|||
b.HasIndex("Name"); |
|||
|
|||
b.ToTable("AppPlatformDataItems", (string)null); |
|||
}); |
|||
|
|||
modelBuilder.Entity("LINGYUN.Platform.Layouts.Layout", b => |
|||
{ |
|||
b.Property<Guid>("Id") |
|||
.ValueGeneratedOnAdd() |
|||
.HasColumnType("char(36)"); |
|||
|
|||
b.Property<string>("ConcurrencyStamp") |
|||
.IsConcurrencyToken() |
|||
.HasMaxLength(40) |
|||
.HasColumnType("varchar(40)") |
|||
.HasColumnName("ConcurrencyStamp"); |
|||
|
|||
b.Property<DateTime>("CreationTime") |
|||
.HasColumnType("datetime(6)") |
|||
.HasColumnName("CreationTime"); |
|||
|
|||
b.Property<Guid?>("CreatorId") |
|||
.HasColumnType("char(36)") |
|||
.HasColumnName("CreatorId"); |
|||
|
|||
b.Property<Guid>("DataId") |
|||
.HasColumnType("char(36)"); |
|||
|
|||
b.Property<Guid?>("DeleterId") |
|||
.HasColumnType("char(36)") |
|||
.HasColumnName("DeleterId"); |
|||
|
|||
b.Property<DateTime?>("DeletionTime") |
|||
.HasColumnType("datetime(6)") |
|||
.HasColumnName("DeletionTime"); |
|||
|
|||
b.Property<string>("Description") |
|||
.HasColumnType("longtext"); |
|||
|
|||
b.Property<string>("DisplayName") |
|||
.IsRequired() |
|||
.HasMaxLength(128) |
|||
.HasColumnType("varchar(128)") |
|||
.HasColumnName("DisplayName"); |
|||
|
|||
b.Property<string>("ExtraProperties") |
|||
.HasColumnType("longtext") |
|||
.HasColumnName("ExtraProperties"); |
|||
|
|||
b.Property<string>("Framework") |
|||
.IsRequired() |
|||
.HasMaxLength(64) |
|||
.HasColumnType("varchar(64)") |
|||
.HasColumnName("Framework"); |
|||
|
|||
b.Property<bool>("IsDeleted") |
|||
.ValueGeneratedOnAdd() |
|||
.HasColumnType("tinyint(1)") |
|||
.HasDefaultValue(false) |
|||
.HasColumnName("IsDeleted"); |
|||
|
|||
b.Property<DateTime?>("LastModificationTime") |
|||
.HasColumnType("datetime(6)") |
|||
.HasColumnName("LastModificationTime"); |
|||
|
|||
b.Property<Guid?>("LastModifierId") |
|||
.HasColumnType("char(36)") |
|||
.HasColumnName("LastModifierId"); |
|||
|
|||
b.Property<string>("Name") |
|||
.IsRequired() |
|||
.HasMaxLength(64) |
|||
.HasColumnType("varchar(64)") |
|||
.HasColumnName("Name"); |
|||
|
|||
b.Property<string>("Path") |
|||
.HasMaxLength(255) |
|||
.HasColumnType("varchar(255)") |
|||
.HasColumnName("Path"); |
|||
|
|||
b.Property<string>("Redirect") |
|||
.HasMaxLength(255) |
|||
.HasColumnType("varchar(255)") |
|||
.HasColumnName("Redirect"); |
|||
|
|||
b.Property<Guid?>("TenantId") |
|||
.HasColumnType("char(36)") |
|||
.HasColumnName("TenantId"); |
|||
|
|||
b.HasKey("Id"); |
|||
|
|||
b.ToTable("AppPlatformLayouts", (string)null); |
|||
}); |
|||
|
|||
modelBuilder.Entity("LINGYUN.Platform.Menus.Menu", b => |
|||
{ |
|||
b.Property<Guid>("Id") |
|||
.ValueGeneratedOnAdd() |
|||
.HasColumnType("char(36)"); |
|||
|
|||
b.Property<string>("Code") |
|||
.IsRequired() |
|||
.HasMaxLength(23) |
|||
.HasColumnType("varchar(23)") |
|||
.HasColumnName("Code"); |
|||
|
|||
b.Property<string>("Component") |
|||
.IsRequired() |
|||
.HasMaxLength(255) |
|||
.HasColumnType("varchar(255)") |
|||
.HasColumnName("Component"); |
|||
|
|||
b.Property<string>("ConcurrencyStamp") |
|||
.IsConcurrencyToken() |
|||
.HasMaxLength(40) |
|||
.HasColumnType("varchar(40)") |
|||
.HasColumnName("ConcurrencyStamp"); |
|||
|
|||
b.Property<DateTime>("CreationTime") |
|||
.HasColumnType("datetime(6)") |
|||
.HasColumnName("CreationTime"); |
|||
|
|||
b.Property<Guid?>("CreatorId") |
|||
.HasColumnType("char(36)") |
|||
.HasColumnName("CreatorId"); |
|||
|
|||
b.Property<Guid?>("DeleterId") |
|||
.HasColumnType("char(36)") |
|||
.HasColumnName("DeleterId"); |
|||
|
|||
b.Property<DateTime?>("DeletionTime") |
|||
.HasColumnType("datetime(6)") |
|||
.HasColumnName("DeletionTime"); |
|||
|
|||
b.Property<string>("Description") |
|||
.HasColumnType("longtext"); |
|||
|
|||
b.Property<string>("DisplayName") |
|||
.IsRequired() |
|||
.HasMaxLength(128) |
|||
.HasColumnType("varchar(128)") |
|||
.HasColumnName("DisplayName"); |
|||
|
|||
b.Property<string>("ExtraProperties") |
|||
.HasColumnType("longtext") |
|||
.HasColumnName("ExtraProperties"); |
|||
|
|||
b.Property<string>("Framework") |
|||
.IsRequired() |
|||
.HasMaxLength(64) |
|||
.HasColumnType("varchar(64)") |
|||
.HasColumnName("Framework"); |
|||
|
|||
b.Property<bool>("IsDeleted") |
|||
.ValueGeneratedOnAdd() |
|||
.HasColumnType("tinyint(1)") |
|||
.HasDefaultValue(false) |
|||
.HasColumnName("IsDeleted"); |
|||
|
|||
b.Property<bool>("IsPublic") |
|||
.HasColumnType("tinyint(1)"); |
|||
|
|||
b.Property<DateTime?>("LastModificationTime") |
|||
.HasColumnType("datetime(6)") |
|||
.HasColumnName("LastModificationTime"); |
|||
|
|||
b.Property<Guid?>("LastModifierId") |
|||
.HasColumnType("char(36)") |
|||
.HasColumnName("LastModifierId"); |
|||
|
|||
b.Property<Guid>("LayoutId") |
|||
.HasColumnType("char(36)"); |
|||
|
|||
b.Property<string>("Name") |
|||
.IsRequired() |
|||
.HasMaxLength(64) |
|||
.HasColumnType("varchar(64)") |
|||
.HasColumnName("Name"); |
|||
|
|||
b.Property<Guid?>("ParentId") |
|||
.HasColumnType("char(36)"); |
|||
|
|||
b.Property<string>("Path") |
|||
.HasMaxLength(255) |
|||
.HasColumnType("varchar(255)") |
|||
.HasColumnName("Path"); |
|||
|
|||
b.Property<string>("Redirect") |
|||
.HasMaxLength(255) |
|||
.HasColumnType("varchar(255)") |
|||
.HasColumnName("Redirect"); |
|||
|
|||
b.Property<Guid?>("TenantId") |
|||
.HasColumnType("char(36)") |
|||
.HasColumnName("TenantId"); |
|||
|
|||
b.HasKey("Id"); |
|||
|
|||
b.ToTable("AppPlatformMenus", (string)null); |
|||
}); |
|||
|
|||
modelBuilder.Entity("LINGYUN.Platform.Menus.RoleMenu", b => |
|||
{ |
|||
b.Property<Guid>("Id") |
|||
.ValueGeneratedOnAdd() |
|||
.HasColumnType("char(36)"); |
|||
|
|||
b.Property<DateTime>("CreationTime") |
|||
.HasColumnType("datetime(6)") |
|||
.HasColumnName("CreationTime"); |
|||
|
|||
b.Property<Guid?>("CreatorId") |
|||
.HasColumnType("char(36)") |
|||
.HasColumnName("CreatorId"); |
|||
|
|||
b.Property<DateTime?>("LastModificationTime") |
|||
.HasColumnType("datetime(6)") |
|||
.HasColumnName("LastModificationTime"); |
|||
|
|||
b.Property<Guid?>("LastModifierId") |
|||
.HasColumnType("char(36)") |
|||
.HasColumnName("LastModifierId"); |
|||
|
|||
b.Property<Guid>("MenuId") |
|||
.HasColumnType("char(36)"); |
|||
|
|||
b.Property<string>("RoleName") |
|||
.IsRequired() |
|||
.HasMaxLength(256) |
|||
.HasColumnType("varchar(256)") |
|||
.HasColumnName("RoleName"); |
|||
|
|||
b.Property<bool>("Startup") |
|||
.HasColumnType("tinyint(1)"); |
|||
|
|||
b.Property<Guid?>("TenantId") |
|||
.HasColumnType("char(36)") |
|||
.HasColumnName("TenantId"); |
|||
|
|||
b.HasKey("Id"); |
|||
|
|||
b.HasIndex("RoleName", "MenuId"); |
|||
|
|||
b.ToTable("AppPlatformRoleMenus", (string)null); |
|||
}); |
|||
|
|||
modelBuilder.Entity("LINGYUN.Platform.Menus.UserFavoriteMenu", b => |
|||
{ |
|||
b.Property<Guid>("Id") |
|||
.ValueGeneratedOnAdd() |
|||
.HasColumnType("char(36)"); |
|||
|
|||
b.Property<string>("AliasName") |
|||
.HasMaxLength(128) |
|||
.HasColumnType("varchar(128)") |
|||
.HasColumnName("AliasName"); |
|||
|
|||
b.Property<string>("Color") |
|||
.HasMaxLength(30) |
|||
.HasColumnType("varchar(30)") |
|||
.HasColumnName("Color"); |
|||
|
|||
b.Property<DateTime>("CreationTime") |
|||
.HasColumnType("datetime(6)") |
|||
.HasColumnName("CreationTime"); |
|||
|
|||
b.Property<Guid?>("CreatorId") |
|||
.HasColumnType("char(36)") |
|||
.HasColumnName("CreatorId"); |
|||
|
|||
b.Property<string>("DisplayName") |
|||
.IsRequired() |
|||
.HasMaxLength(128) |
|||
.HasColumnType("varchar(128)") |
|||
.HasColumnName("DisplayName"); |
|||
|
|||
b.Property<string>("Framework") |
|||
.IsRequired() |
|||
.HasMaxLength(64) |
|||
.HasColumnType("varchar(64)") |
|||
.HasColumnName("Framework"); |
|||
|
|||
b.Property<string>("Icon") |
|||
.HasMaxLength(512) |
|||
.HasColumnType("varchar(512)") |
|||
.HasColumnName("Icon"); |
|||
|
|||
b.Property<DateTime?>("LastModificationTime") |
|||
.HasColumnType("datetime(6)") |
|||
.HasColumnName("LastModificationTime"); |
|||
|
|||
b.Property<Guid?>("LastModifierId") |
|||
.HasColumnType("char(36)") |
|||
.HasColumnName("LastModifierId"); |
|||
|
|||
b.Property<Guid>("MenuId") |
|||
.HasColumnType("char(36)"); |
|||
|
|||
b.Property<string>("Name") |
|||
.IsRequired() |
|||
.HasMaxLength(64) |
|||
.HasColumnType("varchar(64)") |
|||
.HasColumnName("Name"); |
|||
|
|||
b.Property<string>("Path") |
|||
.IsRequired() |
|||
.HasMaxLength(255) |
|||
.HasColumnType("varchar(255)") |
|||
.HasColumnName("Path"); |
|||
|
|||
b.Property<Guid?>("TenantId") |
|||
.HasColumnType("char(36)") |
|||
.HasColumnName("TenantId"); |
|||
|
|||
b.Property<Guid>("UserId") |
|||
.HasColumnType("char(36)"); |
|||
|
|||
b.HasKey("Id"); |
|||
|
|||
b.HasIndex("UserId", "MenuId"); |
|||
|
|||
b.ToTable("AppPlatformUserFavoriteMenus", (string)null); |
|||
}); |
|||
|
|||
modelBuilder.Entity("LINGYUN.Platform.Menus.UserMenu", b => |
|||
{ |
|||
b.Property<Guid>("Id") |
|||
.ValueGeneratedOnAdd() |
|||
.HasColumnType("char(36)"); |
|||
|
|||
b.Property<DateTime>("CreationTime") |
|||
.HasColumnType("datetime(6)") |
|||
.HasColumnName("CreationTime"); |
|||
|
|||
b.Property<Guid?>("CreatorId") |
|||
.HasColumnType("char(36)") |
|||
.HasColumnName("CreatorId"); |
|||
|
|||
b.Property<DateTime?>("LastModificationTime") |
|||
.HasColumnType("datetime(6)") |
|||
.HasColumnName("LastModificationTime"); |
|||
|
|||
b.Property<Guid?>("LastModifierId") |
|||
.HasColumnType("char(36)") |
|||
.HasColumnName("LastModifierId"); |
|||
|
|||
b.Property<Guid>("MenuId") |
|||
.HasColumnType("char(36)"); |
|||
|
|||
b.Property<bool>("Startup") |
|||
.HasColumnType("tinyint(1)"); |
|||
|
|||
b.Property<Guid?>("TenantId") |
|||
.HasColumnType("char(36)") |
|||
.HasColumnName("TenantId"); |
|||
|
|||
b.Property<Guid>("UserId") |
|||
.HasColumnType("char(36)"); |
|||
|
|||
b.HasKey("Id"); |
|||
|
|||
b.HasIndex("UserId", "MenuId"); |
|||
|
|||
b.ToTable("AppPlatformUserMenus", (string)null); |
|||
}); |
|||
|
|||
modelBuilder.Entity("LINGYUN.Platform.Packages.Package", b => |
|||
{ |
|||
b.Property<Guid>("Id") |
|||
.ValueGeneratedOnAdd() |
|||
.HasColumnType("char(36)"); |
|||
|
|||
b.Property<string>("Authors") |
|||
.HasMaxLength(100) |
|||
.HasColumnType("varchar(100)") |
|||
.HasColumnName("Authors"); |
|||
|
|||
b.Property<string>("ConcurrencyStamp") |
|||
.IsConcurrencyToken() |
|||
.HasMaxLength(40) |
|||
.HasColumnType("varchar(40)") |
|||
.HasColumnName("ConcurrencyStamp"); |
|||
|
|||
b.Property<DateTime>("CreationTime") |
|||
.HasColumnType("datetime(6)") |
|||
.HasColumnName("CreationTime"); |
|||
|
|||
b.Property<Guid?>("CreatorId") |
|||
.HasColumnType("char(36)") |
|||
.HasColumnName("CreatorId"); |
|||
|
|||
b.Property<Guid?>("DeleterId") |
|||
.HasColumnType("char(36)") |
|||
.HasColumnName("DeleterId"); |
|||
|
|||
b.Property<DateTime?>("DeletionTime") |
|||
.HasColumnType("datetime(6)") |
|||
.HasColumnName("DeletionTime"); |
|||
|
|||
b.Property<string>("Description") |
|||
.HasMaxLength(255) |
|||
.HasColumnType("varchar(255)") |
|||
.HasColumnName("Description"); |
|||
|
|||
b.Property<string>("ExtraProperties") |
|||
.HasColumnType("longtext") |
|||
.HasColumnName("ExtraProperties"); |
|||
|
|||
b.Property<bool>("ForceUpdate") |
|||
.HasColumnType("tinyint(1)"); |
|||
|
|||
b.Property<bool>("IsDeleted") |
|||
.ValueGeneratedOnAdd() |
|||
.HasColumnType("tinyint(1)") |
|||
.HasDefaultValue(false) |
|||
.HasColumnName("IsDeleted"); |
|||
|
|||
b.Property<DateTime?>("LastModificationTime") |
|||
.HasColumnType("datetime(6)") |
|||
.HasColumnName("LastModificationTime"); |
|||
|
|||
b.Property<Guid?>("LastModifierId") |
|||
.HasColumnType("char(36)") |
|||
.HasColumnName("LastModifierId"); |
|||
|
|||
b.Property<int>("Level") |
|||
.HasColumnType("int"); |
|||
|
|||
b.Property<string>("Name") |
|||
.IsRequired() |
|||
.HasMaxLength(255) |
|||
.HasColumnType("varchar(255)") |
|||
.HasColumnName("Name"); |
|||
|
|||
b.Property<string>("Note") |
|||
.IsRequired() |
|||
.HasMaxLength(1024) |
|||
.HasColumnType("varchar(1024)") |
|||
.HasColumnName("Note"); |
|||
|
|||
b.Property<Guid?>("TenantId") |
|||
.HasColumnType("char(36)") |
|||
.HasColumnName("TenantId"); |
|||
|
|||
b.Property<string>("Version") |
|||
.IsRequired() |
|||
.HasMaxLength(30) |
|||
.HasColumnType("varchar(30)") |
|||
.HasColumnName("Version"); |
|||
|
|||
b.HasKey("Id"); |
|||
|
|||
b.HasIndex("Name", "Version"); |
|||
|
|||
b.ToTable("AppPlatformPackages", (string)null); |
|||
}); |
|||
|
|||
modelBuilder.Entity("LINGYUN.Platform.Packages.PackageBlob", b => |
|||
{ |
|||
b.Property<int>("Id") |
|||
.ValueGeneratedOnAdd() |
|||
.HasColumnType("int"); |
|||
|
|||
b.Property<string>("Authors") |
|||
.HasMaxLength(100) |
|||
.HasColumnType("varchar(100)") |
|||
.HasColumnName("Authors"); |
|||
|
|||
b.Property<string>("ContentType") |
|||
.HasMaxLength(256) |
|||
.HasColumnType("varchar(256)") |
|||
.HasColumnName("ContentType"); |
|||
|
|||
b.Property<DateTime>("CreatedAt") |
|||
.HasColumnType("datetime(6)"); |
|||
|
|||
b.Property<DateTime>("CreationTime") |
|||
.HasColumnType("datetime(6)") |
|||
.HasColumnName("CreationTime"); |
|||
|
|||
b.Property<Guid?>("CreatorId") |
|||
.HasColumnType("char(36)") |
|||
.HasColumnName("CreatorId"); |
|||
|
|||
b.Property<int>("DownloadCount") |
|||
.HasColumnType("int"); |
|||
|
|||
b.Property<string>("ExtraProperties") |
|||
.HasColumnType("longtext") |
|||
.HasColumnName("ExtraProperties"); |
|||
|
|||
b.Property<string>("License") |
|||
.HasMaxLength(1024) |
|||
.HasColumnType("varchar(1024)") |
|||
.HasColumnName("License"); |
|||
|
|||
b.Property<string>("Name") |
|||
.IsRequired() |
|||
.HasMaxLength(255) |
|||
.HasColumnType("varchar(255)") |
|||
.HasColumnName("Name"); |
|||
|
|||
b.Property<Guid>("PackageId") |
|||
.HasColumnType("char(36)"); |
|||
|
|||
b.Property<string>("SHA256") |
|||
.HasMaxLength(256) |
|||
.HasColumnType("varchar(256)") |
|||
.HasColumnName("SHA256"); |
|||
|
|||
b.Property<long?>("Size") |
|||
.HasColumnType("bigint"); |
|||
|
|||
b.Property<string>("Summary") |
|||
.HasMaxLength(1024) |
|||
.HasColumnType("varchar(1024)") |
|||
.HasColumnName("Summary"); |
|||
|
|||
b.Property<Guid?>("TenantId") |
|||
.HasColumnType("char(36)") |
|||
.HasColumnName("TenantId"); |
|||
|
|||
b.Property<DateTime?>("UpdatedAt") |
|||
.HasColumnType("datetime(6)"); |
|||
|
|||
b.Property<string>("Url") |
|||
.HasMaxLength(512) |
|||
.HasColumnType("varchar(512)") |
|||
.HasColumnName("Url"); |
|||
|
|||
b.HasKey("Id"); |
|||
|
|||
b.HasIndex("PackageId", "Name"); |
|||
|
|||
b.ToTable("AppPlatformPackageBlobs", (string)null); |
|||
}); |
|||
|
|||
modelBuilder.Entity("LINGYUN.Platform.Datas.DataItem", b => |
|||
{ |
|||
b.HasOne("LINGYUN.Platform.Datas.Data", null) |
|||
.WithMany("Items") |
|||
.HasForeignKey("DataId") |
|||
.OnDelete(DeleteBehavior.Cascade) |
|||
.IsRequired(); |
|||
}); |
|||
|
|||
modelBuilder.Entity("LINGYUN.Platform.Packages.PackageBlob", b => |
|||
{ |
|||
b.HasOne("LINGYUN.Platform.Packages.Package", "Package") |
|||
.WithMany("Blobs") |
|||
.HasForeignKey("PackageId") |
|||
.OnDelete(DeleteBehavior.Cascade) |
|||
.IsRequired(); |
|||
|
|||
b.Navigation("Package"); |
|||
}); |
|||
|
|||
modelBuilder.Entity("LINGYUN.Platform.Datas.Data", b => |
|||
{ |
|||
b.Navigation("Items"); |
|||
}); |
|||
|
|||
modelBuilder.Entity("LINGYUN.Platform.Packages.Package", b => |
|||
{ |
|||
b.Navigation("Blobs"); |
|||
}); |
|||
#pragma warning restore 612, 618
|
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,118 @@ |
|||
using System; |
|||
using Microsoft.EntityFrameworkCore.Metadata; |
|||
using Microsoft.EntityFrameworkCore.Migrations; |
|||
|
|||
#nullable disable |
|||
|
|||
namespace LY.MicroService.PlatformManagement.Migrations |
|||
{ |
|||
public partial class RemoveVersions : Migration |
|||
{ |
|||
protected override void Up(MigrationBuilder migrationBuilder) |
|||
{ |
|||
migrationBuilder.DropTable( |
|||
name: "AppPlatformVersionFile"); |
|||
|
|||
migrationBuilder.DropTable( |
|||
name: "AppPlatformVersion"); |
|||
|
|||
migrationBuilder.AddColumn<string>( |
|||
name: "ExtraProperties", |
|||
table: "AppPlatformPackageBlobs", |
|||
type: "longtext", |
|||
nullable: true) |
|||
.Annotation("MySql:CharSet", "utf8mb4"); |
|||
} |
|||
|
|||
protected override void Down(MigrationBuilder migrationBuilder) |
|||
{ |
|||
migrationBuilder.DropColumn( |
|||
name: "ExtraProperties", |
|||
table: "AppPlatformPackageBlobs"); |
|||
|
|||
migrationBuilder.CreateTable( |
|||
name: "AppPlatformVersion", |
|||
columns: table => new |
|||
{ |
|||
Id = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci"), |
|||
ConcurrencyStamp = table.Column<string>(type: "varchar(40)", maxLength: 40, nullable: true) |
|||
.Annotation("MySql:CharSet", "utf8mb4"), |
|||
CreationTime = table.Column<DateTime>(type: "datetime(6)", nullable: false), |
|||
CreatorId = table.Column<Guid>(type: "char(36)", nullable: true, collation: "ascii_general_ci"), |
|||
DeleterId = table.Column<Guid>(type: "char(36)", nullable: true, collation: "ascii_general_ci"), |
|||
DeletionTime = table.Column<DateTime>(type: "datetime(6)", nullable: true), |
|||
Description = table.Column<string>(type: "varchar(2048)", maxLength: 2048, nullable: true) |
|||
.Annotation("MySql:CharSet", "utf8mb4"), |
|||
ExtraProperties = table.Column<string>(type: "longtext", nullable: true) |
|||
.Annotation("MySql:CharSet", "utf8mb4"), |
|||
IsDeleted = table.Column<bool>(type: "tinyint(1)", nullable: false, defaultValue: false), |
|||
LastModificationTime = table.Column<DateTime>(type: "datetime(6)", nullable: true), |
|||
LastModifierId = table.Column<Guid>(type: "char(36)", nullable: true, collation: "ascii_general_ci"), |
|||
Level = table.Column<int>(type: "int", nullable: false), |
|||
PlatformType = table.Column<int>(type: "int", nullable: false), |
|||
TenantId = table.Column<Guid>(type: "char(36)", nullable: true, collation: "ascii_general_ci"), |
|||
Title = table.Column<string>(type: "varchar(50)", maxLength: 50, nullable: false) |
|||
.Annotation("MySql:CharSet", "utf8mb4"), |
|||
Version = table.Column<string>(type: "varchar(20)", maxLength: 20, nullable: false) |
|||
.Annotation("MySql:CharSet", "utf8mb4") |
|||
}, |
|||
constraints: table => |
|||
{ |
|||
table.PrimaryKey("PK_AppPlatformVersion", x => x.Id); |
|||
}) |
|||
.Annotation("MySql:CharSet", "utf8mb4"); |
|||
|
|||
migrationBuilder.CreateTable( |
|||
name: "AppPlatformVersionFile", |
|||
columns: table => new |
|||
{ |
|||
Id = table.Column<int>(type: "int", nullable: false) |
|||
.Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn), |
|||
AppVersionId = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci"), |
|||
CreationTime = table.Column<DateTime>(type: "datetime(6)", nullable: false), |
|||
CreatorId = table.Column<Guid>(type: "char(36)", nullable: true, collation: "ascii_general_ci"), |
|||
DownloadCount = table.Column<int>(type: "int", nullable: false), |
|||
FileType = table.Column<int>(type: "int", nullable: false), |
|||
LastModificationTime = table.Column<DateTime>(type: "datetime(6)", nullable: true), |
|||
LastModifierId = table.Column<Guid>(type: "char(36)", nullable: true, collation: "ascii_general_ci"), |
|||
Name = table.Column<string>(type: "varchar(255)", maxLength: 255, nullable: false) |
|||
.Annotation("MySql:CharSet", "utf8mb4"), |
|||
Path = table.Column<string>(type: "varchar(255)", maxLength: 255, nullable: true) |
|||
.Annotation("MySql:CharSet", "utf8mb4"), |
|||
SHA256 = table.Column<string>(type: "varchar(65)", maxLength: 65, nullable: false) |
|||
.Annotation("MySql:CharSet", "utf8mb4"), |
|||
Size = table.Column<long>(type: "bigint", nullable: false), |
|||
TenantId = table.Column<Guid>(type: "char(36)", nullable: true, collation: "ascii_general_ci"), |
|||
Version = table.Column<string>(type: "varchar(20)", maxLength: 20, nullable: false) |
|||
.Annotation("MySql:CharSet", "utf8mb4") |
|||
}, |
|||
constraints: table => |
|||
{ |
|||
table.PrimaryKey("PK_AppPlatformVersionFile", x => x.Id); |
|||
table.ForeignKey( |
|||
name: "FK_AppPlatformVersionFile_AppPlatformVersion_AppVersionId", |
|||
column: x => x.AppVersionId, |
|||
principalTable: "AppPlatformVersion", |
|||
principalColumn: "Id", |
|||
onDelete: ReferentialAction.Cascade); |
|||
}) |
|||
.Annotation("MySql:CharSet", "utf8mb4"); |
|||
|
|||
migrationBuilder.CreateIndex( |
|||
name: "IX_AppPlatformVersion_Version", |
|||
table: "AppPlatformVersion", |
|||
column: "Version"); |
|||
|
|||
migrationBuilder.CreateIndex( |
|||
name: "IX_AppPlatformVersionFile_AppVersionId", |
|||
table: "AppPlatformVersionFile", |
|||
column: "AppVersionId"); |
|||
|
|||
migrationBuilder.CreateIndex( |
|||
name: "IX_AppPlatformVersionFile_Path_Name_Version", |
|||
table: "AppPlatformVersionFile", |
|||
columns: new[] { "Path", "Name", "Version" }, |
|||
unique: true); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,105 @@ |
|||
using LINGYUN.Abp.OssManagement; |
|||
using LINGYUN.Platform.Packages; |
|||
using System; |
|||
using System.IO; |
|||
using System.Threading; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.BlobStoring; |
|||
using Volo.Abp.Content; |
|||
using Volo.Abp.Data; |
|||
using Volo.Abp.DependencyInjection; |
|||
|
|||
namespace LY.MicroService.PlatformManagement.Packages; |
|||
|
|||
/// <summary>
|
|||
/// 使用Oss模块管理包二进制文件
|
|||
/// </summary>
|
|||
[Dependency(ReplaceServices = true)] |
|||
[ExposeServices( |
|||
typeof(IPackageBlobManager), |
|||
typeof(PackageBlobManager), |
|||
typeof(PackageBlobOssManager))] |
|||
public class PackageBlobOssManager : PackageBlobManager, ITransientDependency |
|||
{ |
|||
protected IOssObjectAppService ObjectAppService { get; } |
|||
|
|||
public PackageBlobOssManager( |
|||
IPackageBlobNormalizer blobNormalizer, |
|||
IBlobContainer<PackageContainer> packageContainer, |
|||
IOssObjectAppService objectAppService) |
|||
: base(blobNormalizer, packageContainer) |
|||
{ |
|||
ObjectAppService = objectAppService; |
|||
} |
|||
|
|||
public async override Task RemoveBlobAsync( |
|||
Package package, |
|||
PackageBlob packageBlob, |
|||
CancellationToken cancellationToken = default) |
|||
{ |
|||
var blobName = BlobNormalizer.Normalize(package, packageBlob); |
|||
var bucket = BlobContainerNameAttribute.GetContainerName<PackageContainer>(); |
|||
var path = blobName.Replace(packageBlob.Name, ""); |
|||
path.RemovePostFix(Path.PathSeparator.ToString()); |
|||
|
|||
var input = new GetOssObjectInput |
|||
{ |
|||
Bucket = bucket, |
|||
Path = path, |
|||
Object = packageBlob.Name |
|||
}; |
|||
await ObjectAppService.DeleteAsync(input); |
|||
} |
|||
|
|||
protected async override Task<Stream> DownloadFromBlobAsync( |
|||
Package package, |
|||
PackageBlob packageBlob, |
|||
CancellationToken cancellationToken = default) |
|||
{ |
|||
var blobName = BlobNormalizer.Normalize(package, packageBlob); |
|||
var bucket = BlobContainerNameAttribute.GetContainerName<PackageContainer>(); |
|||
var path = blobName.Replace(packageBlob.Name, ""); |
|||
path.RemovePostFix(Path.PathSeparator.ToString()); |
|||
|
|||
var input = new GetOssObjectInput |
|||
{ |
|||
Bucket = bucket, |
|||
Path = path, |
|||
Object = packageBlob.Name |
|||
}; |
|||
var ossContent = await ObjectAppService.GetContentAsync(input); |
|||
return ossContent.GetStream(); |
|||
} |
|||
|
|||
public async override Task SaveBlobAsync( |
|||
Package package, |
|||
PackageBlob packageBlob, |
|||
Stream stream, |
|||
bool overrideExisting = true, |
|||
CancellationToken cancellationToken = default) |
|||
{ |
|||
var blobName = BlobNormalizer.Normalize(package, packageBlob); |
|||
var bucket = BlobContainerNameAttribute.GetContainerName<PackageContainer>(); |
|||
var path = blobName.Replace(packageBlob.Name, ""); |
|||
|
|||
var input = new CreateOssObjectInput |
|||
{ |
|||
Bucket = bucket, |
|||
Path = path, |
|||
FileName= packageBlob.Name, |
|||
Overwrite= overrideExisting, |
|||
File = new RemoteStreamContent(stream, packageBlob.Name, packageBlob.ContentType) |
|||
}; |
|||
|
|||
var ossObject = await ObjectAppService.CreateAsync(input); |
|||
|
|||
if (!ossObject.MD5.IsNullOrWhiteSpace()) |
|||
{ |
|||
packageBlob.SetProperty("md5", ossObject.MD5); |
|||
} |
|||
|
|||
stream.Seek(0, SeekOrigin.Begin); |
|||
packageBlob.SHA256 = ComputeHash(stream); |
|||
packageBlob.SetUrl($"api/platform/packages/{packageBlob.PackageId}/blob/{packageBlob.Name}"); |
|||
} |
|||
} |
|||
Loading…
Reference in new issue