Browse Source

add versionfile field platform and path

pull/27/head
cKey 5 years ago
parent
commit
a1eb68c594
  1. 13
      aspnet-core/modules/platform/LINGYUN.Platform.Application.Contracts/LINGYUN/Platform/Versions/Dto/VersionCreateDto.cs
  2. 8
      aspnet-core/modules/platform/LINGYUN.Platform.Application.Contracts/LINGYUN/Platform/Versions/Dto/VersionDeleteDto.cs
  3. 6
      aspnet-core/modules/platform/LINGYUN.Platform.Application.Contracts/LINGYUN/Platform/Versions/Dto/VersionFileCreateDto.cs
  4. 5
      aspnet-core/modules/platform/LINGYUN.Platform.Application.Contracts/LINGYUN/Platform/Versions/Dto/VersionFileDeleteDto.cs
  5. 15
      aspnet-core/modules/platform/LINGYUN.Platform.Application.Contracts/LINGYUN/Platform/Versions/Dto/VersionFileGetDto.cs
  6. 1
      aspnet-core/modules/platform/LINGYUN.Platform.Application.Contracts/LINGYUN/Platform/Versions/Dto/VersionGetByPagedDto.cs
  7. 2
      aspnet-core/modules/platform/LINGYUN.Platform.Application.Contracts/LINGYUN/Platform/Versions/IVersionAppService.cs
  8. 16
      aspnet-core/modules/platform/LINGYUN.Platform.Application/LINGYUN/Platform/Versions/VersionAppService.cs
  9. 2
      aspnet-core/modules/platform/LINGYUN.Platform.Domain.Shared/LINGYUN/Platform/PlatformType.cs
  10. 4
      aspnet-core/modules/platform/LINGYUN.Platform.Domain.Shared/LINGYUN/Platform/Versions/IVersionFileManager.cs
  11. 8
      aspnet-core/modules/platform/LINGYUN.Platform.Domain.Shared/LINGYUN/Platform/Versions/VersionFileConsts.cs
  12. 28
      aspnet-core/modules/platform/LINGYUN.Platform.Domain/LINGYUN/Platform/Versions/AppVersion.cs
  13. 10
      aspnet-core/modules/platform/LINGYUN.Platform.Domain/LINGYUN/Platform/Versions/IVersionRepository.cs
  14. 13
      aspnet-core/modules/platform/LINGYUN.Platform.Domain/LINGYUN/Platform/Versions/VersionFile.cs
  15. 40
      aspnet-core/modules/platform/LINGYUN.Platform.Domain/LINGYUN/Platform/Versions/VersionManager.cs
  16. 17
      aspnet-core/modules/platform/LINGYUN.Platform.Domain/System/StringExtensions.cs
  17. 7
      aspnet-core/modules/platform/LINGYUN.Platform.EntityFrameworkCore/LINGYUN/Platform/EntityFrameworkCore/PlatformDbContextModelBuilderExtensions.cs
  18. 17
      aspnet-core/modules/platform/LINGYUN.Platform.EntityFrameworkCore/LINGYUN/Platform/Versions/EfCoreVersionRepository.cs
  19. 16
      aspnet-core/modules/platform/LINGYUN.Platform.HttpApi/LINGYUN/Platform/Versions/VersionController.cs
  20. 406
      aspnet-core/services/platform/LINGYUN.Platform.HttpApi.Host/Migrations/20200724092022_Add-Version-File-Field-Path-And-Platform-Type.Designer.cs
  21. 52
      aspnet-core/services/platform/LINGYUN.Platform.HttpApi.Host/Migrations/20200724092022_Add-Version-File-Field-Path-And-Platform-Type.cs
  22. 11
      aspnet-core/services/platform/LINGYUN.Platform.HttpApi.Host/Migrations/PlatformHttpApiHostMigrationsDbContextModelSnapshot.cs

13
aspnet-core/modules/platform/LINGYUN.Platform.Application.Contracts/LINGYUN/Platform/Versions/Dto/VersionCreateDto.cs

@ -1,4 +1,4 @@
using System.Collections.Generic; using System.ComponentModel.DataAnnotations;
namespace LINGYUN.Platform.Versions namespace LINGYUN.Platform.Versions
{ {
@ -7,20 +7,27 @@ namespace LINGYUN.Platform.Versions
/// <summary> /// <summary>
/// 标题 /// 标题
/// </summary> /// </summary>
[Required]
[StringLength(AppVersionConsts.MaxTitleLength)]
public string Title { get; set; } public string Title { get; set; }
/// <summary> /// <summary>
/// 版本号 /// 版本号
/// </summary> /// </summary>
[Required]
[StringLength(AppVersionConsts.MaxVersionLength)]
public string Version { get; set; } public string Version { get; set; }
/// <summary> /// <summary>
/// 描述 /// 描述
/// </summary> /// </summary>
[StringLength(AppVersionConsts.MaxDescriptionLength)]
public string Description { get; set; } public string Description { get; set; }
/// <summary> /// <summary>
/// 适应平台
/// </summary>
public PlatformType PlatformType { get; set; } = PlatformType.None;
/// <summary>
/// 重要级别 /// 重要级别
/// </summary> /// </summary>
public ImportantLevel Level { get; set; } = ImportantLevel.Low; public ImportantLevel Level { get; set; } = ImportantLevel.Low;
public List<VersionFileDto> VersionFiles { get; set; } = new List<VersionFileDto>();
} }
} }

8
aspnet-core/modules/platform/LINGYUN.Platform.Application.Contracts/LINGYUN/Platform/Versions/Dto/VersionDeleteDto.cs

@ -1,7 +1,13 @@
namespace LINGYUN.Platform.Versions using System.ComponentModel.DataAnnotations;
namespace LINGYUN.Platform.Versions
{ {
public class VersionDeleteDto public class VersionDeleteDto
{ {
[Required]
[StringLength(AppVersionConsts.MaxVersionLength)]
public string Version { get; set; } public string Version { get; set; }
public PlatformType PlatformType { get; set; }
} }
} }

6
aspnet-core/modules/platform/LINGYUN.Platform.Application.Contracts/LINGYUN/Platform/Versions/Dto/VersionFileCreateDto.cs

@ -10,8 +10,14 @@ namespace LINGYUN.Platform.Versions
public Guid VersionId { get; set; } public Guid VersionId { get; set; }
[Required] [Required]
[StringLength(AppVersionConsts.MaxVersionLength)]
public string Version { get; set; } public string Version { get; set; }
/// <summary> /// <summary>
/// 文件路径
/// </summary>
[StringLength(VersionFileConsts.MaxPathLength)]
public string FilePath { get; set; }
/// <summary>
/// 文件名称 /// 文件名称
/// </summary> /// </summary>
[Required] [Required]

5
aspnet-core/modules/platform/LINGYUN.Platform.Application.Contracts/LINGYUN/Platform/Versions/Dto/VersionFileDeleteDto.cs

@ -1,10 +1,15 @@
using System; using System;
using System.ComponentModel.DataAnnotations;
namespace LINGYUN.Platform.Versions namespace LINGYUN.Platform.Versions
{ {
public class VersionFileDeleteDto public class VersionFileDeleteDto
{ {
[Required]
public Guid VersionId { get; set; } public Guid VersionId { get; set; }
[Required]
[StringLength(VersionFileConsts.MaxNameLength)]
public string FileName { get; set; } public string FileName { get; set; }
} }
} }

15
aspnet-core/modules/platform/LINGYUN.Platform.Application.Contracts/LINGYUN/Platform/Versions/Dto/VersionFileGetDto.cs

@ -1,11 +1,24 @@
using System; using System.ComponentModel.DataAnnotations;
namespace LINGYUN.Platform.Versions namespace LINGYUN.Platform.Versions
{ {
public class VersionFileGetDto public class VersionFileGetDto
{ {
public PlatformType PlatformType { get; set; } = PlatformType.None;
[Required]
[StringLength(AppVersionConsts.MaxVersionLength)]
public string Version { get; set; } public string Version { get; set; }
[StringLength(VersionFileConsts.MaxPathLength)]
public string FilePath { get; set; }
[Required]
[StringLength(VersionFileConsts.MaxNameLength)]
public string FileName { get; set; } public string FileName { get; set; }
[Required]
[StringLength(VersionFileConsts.MaxVersionLength)]
public string FileVersion { get; set; } public string FileVersion { get; set; }
} }
} }

1
aspnet-core/modules/platform/LINGYUN.Platform.Application.Contracts/LINGYUN/Platform/Versions/Dto/VersionGetByPagedDto.cs

@ -5,5 +5,6 @@ namespace LINGYUN.Platform.Versions
public class VersionGetByPagedDto : PagedAndSortedResultRequestDto public class VersionGetByPagedDto : PagedAndSortedResultRequestDto
{ {
public string Filter { get; set; } public string Filter { get; set; }
public PlatformType PlatformType { get; set; } = PlatformType.None;
} }
} }

2
aspnet-core/modules/platform/LINGYUN.Platform.Application.Contracts/LINGYUN/Platform/Versions/IVersionAppService.cs

@ -6,7 +6,7 @@ namespace LINGYUN.Platform.Versions
{ {
public interface IVersionAppService : IApplicationService public interface IVersionAppService : IApplicationService
{ {
Task<VersionDto> GetLastestAsync(); Task<VersionDto> GetLastestAsync(PlatformType platformType);
Task<PagedResultDto<VersionDto>> GetAsync(VersionGetByPagedDto versionGetByPaged); Task<PagedResultDto<VersionDto>> GetAsync(VersionGetByPagedDto versionGetByPaged);

16
aspnet-core/modules/platform/LINGYUN.Platform.Application/LINGYUN/Platform/Versions/VersionAppService.cs

@ -18,17 +18,17 @@ namespace LINGYUN.Platform.Versions
{ {
await _versionManager.AppendFileAsync(versionFileCreate.VersionId, await _versionManager.AppendFileAsync(versionFileCreate.VersionId,
versionFileCreate.SHA256, versionFileCreate.FileName, versionFileCreate.FileVersion, versionFileCreate.SHA256, versionFileCreate.FileName, versionFileCreate.FileVersion,
versionFileCreate.TotalByte, versionFileCreate.FileType); versionFileCreate.TotalByte, versionFileCreate.FilePath, versionFileCreate.FileType);
} }
public virtual async Task<VersionDto> CreateAsync(VersionCreateDto versionCreate) public virtual async Task<VersionDto> CreateAsync(VersionCreateDto versionCreate)
{ {
if (await _versionManager.ExistsAsync(versionCreate.Version)) if (await _versionManager.ExistsAsync(versionCreate.PlatformType,versionCreate.Version))
{ {
throw new UserFriendlyException("VersionAlreadyExists"); throw new UserFriendlyException("VersionAlreadyExists");
} }
var version = new AppVersion(GuidGenerator.Create(), versionCreate.Title, var version = new AppVersion(GuidGenerator.Create(), versionCreate.Title,
versionCreate.Version, CurrentTenant.Id) versionCreate.Version, versionCreate.PlatformType, CurrentTenant.Id)
{ {
Description = versionCreate.Description, Description = versionCreate.Description,
Level = versionCreate.Level Level = versionCreate.Level
@ -41,7 +41,7 @@ namespace LINGYUN.Platform.Versions
public virtual async Task DeleteAsync(VersionDeleteDto versionDelete) public virtual async Task DeleteAsync(VersionDeleteDto versionDelete)
{ {
var version = await _versionManager.GetByVersionAsync(versionDelete.Version); var version = await _versionManager.GetByVersionAsync(versionDelete.PlatformType, versionDelete.Version);
if (version != null) if (version != null)
{ {
await _versionManager.DeleteAsync(version.Id); await _versionManager.DeleteAsync(version.Id);
@ -50,8 +50,8 @@ namespace LINGYUN.Platform.Versions
public virtual async Task<PagedResultDto<VersionDto>> GetAsync(VersionGetByPagedDto versionGetByPaged) public virtual async Task<PagedResultDto<VersionDto>> GetAsync(VersionGetByPagedDto versionGetByPaged)
{ {
var versionCount = await _versionManager.GetCountAsync(versionGetByPaged.Filter); var versionCount = await _versionManager.GetCountAsync(versionGetByPaged.PlatformType, versionGetByPaged.Filter);
var versions = await _versionManager.GetPagedListAsync(versionGetByPaged.Filter, var versions = await _versionManager.GetPagedListAsync(versionGetByPaged.PlatformType, versionGetByPaged.Filter,
versionGetByPaged.Sorting, true, versionGetByPaged.Sorting, true,
versionGetByPaged.SkipCount, versionGetByPaged.MaxResultCount); versionGetByPaged.SkipCount, versionGetByPaged.MaxResultCount);
@ -66,9 +66,9 @@ namespace LINGYUN.Platform.Versions
return ObjectMapper.Map<AppVersion, VersionDto>(version); return ObjectMapper.Map<AppVersion, VersionDto>(version);
} }
public virtual async Task<VersionDto> GetLastestAsync() public virtual async Task<VersionDto> GetLastestAsync(PlatformType platformType)
{ {
var version = await _versionManager.GetLatestAsync(); var version = await _versionManager.GetLatestAsync(platformType);
return ObjectMapper.Map<AppVersion, VersionDto>(version); return ObjectMapper.Map<AppVersion, VersionDto>(version);
} }

2
aspnet-core/modules/platform/LINGYUN.Platform.Domain.Shared/LINGYUN/Platform/PlatformType.cs

@ -39,7 +39,7 @@ namespace LINGYUN.Platform
/// <summary> /// <summary>
/// Web通用 /// Web通用
/// </summary> /// </summary>
Web = WebForm | WebMvc, Web = WebForm | WebMvc | WebMvvm,
/// <summary> /// <summary>
/// Android /// Android
/// </summary> /// </summary>

4
aspnet-core/modules/platform/LINGYUN.Platform.Domain.Shared/LINGYUN/Platform/Versions/IVersionFileManager.cs

@ -5,7 +5,7 @@ namespace LINGYUN.Platform.Versions
{ {
public interface IVersionFileManager public interface IVersionFileManager
{ {
Task<string> AppendFileAsync(string version, string fileName, string fileVersion, byte[] data); Task<string> SaveFileAsync(string version, string filePath, string fileName, string fileVersion, byte[] data);
Task<Stream> GetFileAsync(string version, string fileName, string fileVersion); Task<Stream> DownloadFileAsync(PlatformType platformType, string version, string filePath, string fileName, string fileVersion);
} }
} }

8
aspnet-core/modules/platform/LINGYUN.Platform.Domain.Shared/LINGYUN/Platform/Versions/VersionFileConsts.cs

@ -1,13 +1,11 @@
using System; namespace LINGYUN.Platform.Versions
using System.Collections.Generic;
using System.Text;
namespace LINGYUN.Platform.Versions
{ {
public static class VersionFileConsts public static class VersionFileConsts
{ {
public const int MaxNameLength = 255; public const int MaxNameLength = 255;
public const int MaxPathLength = 255;
public const int MaxVersionLength = 20; public const int MaxVersionLength = 20;
public const int MaxSHA256Length = 65; public const int MaxSHA256Length = 65;

28
aspnet-core/modules/platform/LINGYUN.Platform.Domain/LINGYUN/Platform/Versions/AppVersion.cs

@ -32,6 +32,10 @@ namespace LINGYUN.Platform.Versions
/// </summary> /// </summary>
public virtual ImportantLevel Level { get; set; } public virtual ImportantLevel Level { get; set; }
/// <summary> /// <summary>
/// 适应平台
/// </summary>
public virtual PlatformType PlatformType { get; protected set; }
/// <summary>
/// 版本文件列表 /// 版本文件列表
/// </summary> /// </summary>
public virtual ICollection<VersionFile> Files { get; protected set; } public virtual ICollection<VersionFile> Files { get; protected set; }
@ -41,20 +45,26 @@ namespace LINGYUN.Platform.Versions
Files = new List<VersionFile>(); Files = new List<VersionFile>();
} }
public AppVersion(Guid id, string title, string version, Guid? tenantId = null) public AppVersion(Guid id, string title, string version, PlatformType platformType = PlatformType.None, Guid? tenantId = null)
{ {
Id = id; Id = id;
Title = title; Title = title;
Version = version; Version = version;
TenantId = tenantId; TenantId = tenantId;
PlatformType = platformType;
Level = ImportantLevel.Low; Level = ImportantLevel.Low;
} }
public void AppendFile(string name, string version, long size, string sha256, FileType fileType = FileType.Stream) public void AppendFile(string name, string version, long size, string sha256,
string filePath = "", FileType fileType = FileType.Stream)
{ {
if (!FileExists(name)) if (!FileExists(name))
{ {
Files.Add(new VersionFile(name, version, size, sha256, fileType, TenantId)); var versionFile = new VersionFile(name, version, size, sha256, fileType, TenantId)
{
Path = filePath
};
Files.Add(versionFile);
} }
} }
@ -82,6 +92,18 @@ namespace LINGYUN.Platform.Versions
return Files.Where(x => x.Name.Equals(name)).FirstOrDefault(); 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) public bool FileExists(string name)
{ {
// TODO: Windows file system ? // TODO: Windows file system ?

10
aspnet-core/modules/platform/LINGYUN.Platform.Domain/LINGYUN/Platform/Versions/IVersionRepository.cs

@ -8,14 +8,14 @@ namespace LINGYUN.Platform.Versions
{ {
public interface IVersionRepository : IBasicRepository<AppVersion, Guid> public interface IVersionRepository : IBasicRepository<AppVersion, Guid>
{ {
Task<bool> ExistsAsync(string version, CancellationToken cancellationToken = default); Task<bool> ExistsAsync(PlatformType platformType, string version, CancellationToken cancellationToken = default);
Task<AppVersion> GetByVersionAsync(string version, CancellationToken cancellationToken = default); Task<AppVersion> GetByVersionAsync(PlatformType platformType, string version, CancellationToken cancellationToken = default);
Task<long> GetCountAsync(string filter = "", CancellationToken cancellationToken = default); Task<long> GetCountAsync(PlatformType platformType, string filter = "", CancellationToken cancellationToken = default);
Task<List<AppVersion>> GetPagedListAsync(string filter = "", string soring = nameof(AppVersion.CreationTime), bool includeDetails = true, int skipCount = 1, int maxResultCount = 10, 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(CancellationToken cancellationToken = default); Task<AppVersion> GetLatestVersionAsync(PlatformType platformType, CancellationToken cancellationToken = default);
} }
} }

13
aspnet-core/modules/platform/LINGYUN.Platform.Domain/LINGYUN/Platform/Versions/VersionFile.cs

@ -14,6 +14,10 @@ namespace LINGYUN.Platform.Versions
/// </summary> /// </summary>
public virtual Guid? TenantId { get; protected set; } public virtual Guid? TenantId { get; protected set; }
/// <summary> /// <summary>
/// 文件路径
/// </summary>
public virtual string Path { get; set; }
/// <summary>
/// 文件名称 /// 文件名称
/// </summary> /// </summary>
public virtual string Name { get; protected set; } public virtual string Name { get; protected set; }
@ -71,7 +75,8 @@ namespace LINGYUN.Platform.Versions
DownloadCount += 1; DownloadCount += 1;
} }
public static string NormalizeBlobName(string appVersion, string fileName, string fileVersion) public static string NormalizeBlobName(string appVersion, string fileName, string fileVersion,
string filePath = "")
{ {
var fileNameWithNotExten = fileName; var fileNameWithNotExten = fileName;
// 取出文件扩展名 // 取出文件扩展名
@ -85,6 +90,12 @@ namespace LINGYUN.Platform.Versions
} }
// 转换不受支持的符号 // 转换不受支持的符号
fileNameWithNotExten = fileNameWithNotExten.Replace(".", "-"); fileNameWithNotExten = fileNameWithNotExten.Replace(".", "-");
//路径存储模式 如果传递了绝对路径,需要计算短路径
if (!filePath.IsNullOrWhiteSpace())
{
return $"{appVersion}/{filePath.GetHash()}/{fileNameWithNotExten}/{fileVersion}/{fileName}";
}
// 最终文件名为 应用版本号/文件名(不带扩展名)/文件版本/文件名 // 最终文件名为 应用版本号/文件名(不带扩展名)/文件版本/文件名
// 例: 1.0.0.0/test-upload-text-file/1.0.0.0/test-upload-text-file.text // 例: 1.0.0.0/test-upload-text-file/1.0.0.0/test-upload-text-file.text
return $"{appVersion}/{fileNameWithNotExten}/{fileVersion}/{fileName}"; return $"{appVersion}/{fileNameWithNotExten}/{fileVersion}/{fileName}";

40
aspnet-core/modules/platform/LINGYUN.Platform.Domain/LINGYUN/Platform/Versions/VersionManager.cs

@ -25,9 +25,9 @@ namespace LINGYUN.Platform.Versions
VersionRepository = versionRepository; VersionRepository = versionRepository;
} }
public virtual async Task<bool> ExistsAsync(string version) public virtual async Task<bool> ExistsAsync(PlatformType platformType, string version)
{ {
return await VersionRepository.ExistsAsync(version); return await VersionRepository.ExistsAsync(platformType, version);
} }
public virtual async Task<AppVersion> GetByIdAsync(Guid id) public virtual async Task<AppVersion> GetByIdAsync(Guid id)
@ -35,19 +35,19 @@ namespace LINGYUN.Platform.Versions
return await VersionRepository.GetAsync(id); return await VersionRepository.GetAsync(id);
} }
public virtual async Task<AppVersion> GetByVersionAsync(string version) public virtual async Task<AppVersion> GetByVersionAsync(PlatformType platformType, string version)
{ {
return await VersionRepository.GetByVersionAsync(version); return await VersionRepository.GetByVersionAsync(platformType, version);
} }
public virtual async Task<long> GetCountAsync(string filter) public virtual async Task<long> GetCountAsync(PlatformType platformType, string filter)
{ {
return await VersionRepository.GetCountAsync(filter); return await VersionRepository.GetCountAsync(platformType, filter);
} }
public virtual async Task<List<AppVersion>> GetPagedListAsync(string filter = "", string soring = nameof(AppVersion.CreationTime), bool includeDetails = true, int skipCount = 1, int maxResultCount = 10) public virtual async 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(filter, soring, includeDetails, skipCount, maxResultCount); return await VersionRepository.GetPagedListAsync(platformType, filter, soring, includeDetails, skipCount, maxResultCount);
} }
[UnitOfWork] [UnitOfWork]
@ -70,22 +70,26 @@ namespace LINGYUN.Platform.Versions
await VersionRepository.DeleteAsync(id); await VersionRepository.DeleteAsync(id);
} }
public virtual async Task<AppVersion> GetLatestAsync() public virtual async Task<AppVersion> GetLatestAsync(PlatformType platformType)
{ {
return await VersionRepository.GetLatestVersionAsync(); return await VersionRepository.GetLatestVersionAsync(platformType);
} }
public virtual async Task<Stream> GetFileAsync(string version, string fileName, string fileVersion) public virtual async 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);
versionFile.Download();
return await VersionBlobContainer.GetAsync( return await VersionBlobContainer.GetAsync(
VersionFile.NormalizeBlobName(version, fileName, fileVersion)); VersionFile.NormalizeBlobName(version, versionFile.Name, versionFile.Version, versionFile.Path));
} }
public virtual async Task<Stream> GetFileAsync(VersionFile versionFile) public virtual async Task<Stream> GetFileAsync(VersionFile versionFile)
{ {
return await GetFileAsync(versionFile.AppVersion.Version, versionFile.Name, versionFile.Version); return await DownloadFileAsync(versionFile.AppVersion.PlatformType, versionFile.AppVersion.Version, versionFile.Path,
versionFile.Name, versionFile.Version);
} }
public virtual async Task<string> AppendFileAsync(string version, string fileName, string fileVersion, byte[] data) public virtual async Task<string> SaveFileAsync(string version, string filePath, string fileName, string fileVersion, byte[] data)
{ {
// 计算指纹 // 计算指纹
var sha256 = new SHA256Managed(); var sha256 = new SHA256Managed();
@ -93,21 +97,23 @@ namespace LINGYUN.Platform.Versions
var sha256Hash = BitConverter.ToString(checkHash).Replace("-", string.Empty); var sha256Hash = BitConverter.ToString(checkHash).Replace("-", string.Empty);
await VersionBlobContainer await VersionBlobContainer
.SaveAsync(VersionFile.NormalizeBlobName(version, fileName, fileVersion), data, true); .SaveAsync(VersionFile.NormalizeBlobName(version, fileName, fileVersion, filePath), data, true);
return sha256Hash; return sha256Hash;
} }
[UnitOfWork] [UnitOfWork]
public virtual async Task AppendFileAsync(Guid versionId, string fileSha256, public virtual async Task AppendFileAsync(Guid versionId, string fileSha256,
string fileName, string fileVersion, long fileSize, FileType fileType = FileType.Stream) string fileName, string fileVersion,
long fileSize, string filePath = "",
FileType fileType = FileType.Stream)
{ {
var appVersion = await VersionRepository.GetAsync(versionId); var appVersion = await VersionRepository.GetAsync(versionId);
if (appVersion.FileExists(fileName)) if (appVersion.FileExists(fileName))
{ {
appVersion.RemoveFile(fileName); appVersion.RemoveFile(fileName);
} }
appVersion.AppendFile(fileName, fileVersion, fileSize, fileSha256, fileType); appVersion.AppendFile(fileName, fileVersion, fileSize, fileSha256, filePath, fileType);
} }
[UnitOfWork] [UnitOfWork]

17
aspnet-core/modules/platform/LINGYUN.Platform.Domain/System/StringExtensions.cs

@ -0,0 +1,17 @@
using System.Security.Cryptography;
using System.Text;
namespace System
{
public static class StringExtensions
{
public static string GetHash(this string str)
{
using (var sha = new SHA1Managed())
{
var hashBytes = sha.ComputeHash(Encoding.UTF8.GetBytes(str));
return BitConverter.ToString(hashBytes).Replace("-", string.Empty);
}
}
}
}

7
aspnet-core/modules/platform/LINGYUN.Platform.EntityFrameworkCore/LINGYUN/Platform/EntityFrameworkCore/PlatformDbContextModelBuilderExtensions.cs

@ -128,10 +128,15 @@ namespace LINGYUN.Platform.EntityFrameworkCore
.HasColumnName(nameof(VersionFile.Version)) .HasColumnName(nameof(VersionFile.Version))
.HasMaxLength(VersionFileConsts.MaxVersionLength); .HasMaxLength(VersionFileConsts.MaxVersionLength);
x.Property(p => p.Path)
.HasColumnName(nameof(VersionFile.Path))
.HasMaxLength(VersionFileConsts.MaxPathLength);
x.ConfigureAudited(); x.ConfigureAudited();
x.ConfigureMultiTenant(); x.ConfigureMultiTenant();
x.HasIndex(i => new { i.Name, i.Version }); x.HasIndex(i => new { i.Path, i.Name, i.Version }).IsUnique();
}); });
} }
} }

17
aspnet-core/modules/platform/LINGYUN.Platform.EntityFrameworkCore/LINGYUN/Platform/Versions/EfCoreVersionRepository.cs

@ -20,17 +20,19 @@ namespace LINGYUN.Platform.Versions
{ {
} }
public virtual async Task<long> GetCountAsync(string filter = "", CancellationToken cancellationToken = default) public virtual async Task<long> GetCountAsync(PlatformType platformType, string filter = "", CancellationToken cancellationToken = default)
{ {
return await DbSet return await DbSet
.Where(x => (platformType | x.PlatformType) == x.PlatformType)
.WhereIf(!filter.IsNullOrWhiteSpace(), x => x.Version.Contains(filter) || x.Title.Contains(filter)) .WhereIf(!filter.IsNullOrWhiteSpace(), x => x.Version.Contains(filter) || x.Title.Contains(filter))
.LongCountAsync(GetCancellationToken(cancellationToken)); .LongCountAsync(GetCancellationToken(cancellationToken));
} }
public virtual async Task<List<AppVersion>> GetPagedListAsync(string filter = "", string soring = nameof(AppVersion.CreationTime), bool includeDetails = true, int skipCount = 1, int maxResultCount = 10, CancellationToken cancellationToken = default) public virtual async 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 DbSet return await DbSet
.IncludeIf(includeDetails, x => x.Files) .IncludeIf(includeDetails, x => x.Files)
.Where(x => (platformType | x.PlatformType) == x.PlatformType)
.WhereIf(!filter.IsNullOrWhiteSpace(), x => x.Version.Contains(filter) || x.Title.Contains(filter)) .WhereIf(!filter.IsNullOrWhiteSpace(), x => x.Version.Contains(filter) || x.Title.Contains(filter))
.OrderBy(soring ?? "") // TODO: 排序待优化 .OrderBy(soring ?? "") // TODO: 排序待优化
.Page(skipCount, maxResultCount) .Page(skipCount, maxResultCount)
@ -38,24 +40,25 @@ namespace LINGYUN.Platform.Versions
} }
public virtual async Task<bool> ExistsAsync(string version, CancellationToken cancellationToken = default) public virtual async Task<bool> ExistsAsync(PlatformType platformType, string version, CancellationToken cancellationToken = default)
{ {
return await DbSet return await DbSet
.AnyAsync(x => x.Version.Equals(version), GetCancellationToken(cancellationToken)); .AnyAsync(x => (platformType | x.PlatformType) == x.PlatformType && x.Version.Equals(version), GetCancellationToken(cancellationToken));
} }
public virtual async Task<AppVersion> GetByVersionAsync(string version, CancellationToken cancellationToken = default) public virtual async Task<AppVersion> GetByVersionAsync(PlatformType platformType, string version, CancellationToken cancellationToken = default)
{ {
return await DbSet return await DbSet
.Include(x => x.Files) .Include(x => x.Files)
.Where(x => x.Version.Equals(version)) .Where(x => (platformType | x.PlatformType) == x.PlatformType && x.Version.Equals(version))
.FirstOrDefaultAsync(GetCancellationToken(cancellationToken)); .FirstOrDefaultAsync(GetCancellationToken(cancellationToken));
} }
public virtual async Task<AppVersion> GetLatestVersionAsync(CancellationToken cancellationToken = default) public virtual async Task<AppVersion> GetLatestVersionAsync(PlatformType platformType, CancellationToken cancellationToken = default)
{ {
return await DbSet return await DbSet
.Include(x => x.Files) .Include(x => x.Files)
.Where(x => (platformType | x.PlatformType) == x.PlatformType)
.OrderByDescending(x => x.CreationTime) .OrderByDescending(x => x.CreationTime)
.FirstOrDefaultAsync(GetCancellationToken(cancellationToken)); .FirstOrDefaultAsync(GetCancellationToken(cancellationToken));
} }

16
aspnet-core/modules/platform/LINGYUN.Platform.HttpApi/LINGYUN/Platform/Versions/VersionController.cs

@ -3,6 +3,7 @@ using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.StaticFiles; using Microsoft.AspNetCore.StaticFiles;
using System; using System;
using System.ComponentModel.DataAnnotations;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
@ -15,7 +16,7 @@ namespace LINGYUN.Platform.Versions
{ {
[Area("platform")] [Area("platform")]
[Route("api/platform/version")] [Route("api/platform/version")]
public class VersionController : PlatformControllerBase public class VersionController : PlatformControllerBase, IVersionAppService
{ {
private readonly IVersionFileManager _versionFileManager; private readonly IVersionFileManager _versionFileManager;
private readonly IVersionAppService _versionAppService; private readonly IVersionAppService _versionAppService;
@ -102,8 +103,8 @@ namespace LINGYUN.Platform.Versions
} }
// 上传最终合并的文件并取得SHA256指纹 // 上传最终合并的文件并取得SHA256指纹
var fileData = await mergeSavedFileStream.GetAllBytesAsync(); var fileData = await mergeSavedFileStream.GetAllBytesAsync();
versionFileCreate.SHA256 = await _versionFileManager.AppendFileAsync(versionFileCreate.Version, versionFileCreate.SHA256 = await _versionFileManager.SaveFileAsync(versionFileCreate.Version,
versionFileCreate.FileName, versionFileCreate.FileVersion, fileData); versionFileCreate.FilePath, versionFileCreate.FileName, versionFileCreate.FileVersion, fileData);
} }
// 添加到版本信息 // 添加到版本信息
await _versionAppService.AppendFileAsync(versionFileCreate); await _versionAppService.AppendFileAsync(versionFileCreate);
@ -146,9 +147,9 @@ namespace LINGYUN.Platform.Versions
[HttpGet] [HttpGet]
[Route("lastest")] [Route("lastest")]
public virtual async Task<VersionDto> GetLastestAsync() public virtual async Task<VersionDto> GetLastestAsync([Required] PlatformType platformType)
{ {
return await _versionAppService.GetLastestAsync(); return await _versionAppService.GetLastestAsync(platformType);
} }
[HttpDelete] [HttpDelete]
@ -172,8 +173,9 @@ namespace LINGYUN.Platform.Versions
// 分块模式下载文件 // 分块模式下载文件
// 得到文件流 // 得到文件流
var fileStream = await _versionFileManager.GetFileAsync( var fileStream = await _versionFileManager.DownloadFileAsync(
versionFileGet.Version, versionFileGet.FileName, versionFileGet.FileVersion); versionFileGet.PlatformType, versionFileGet.Version, versionFileGet.FilePath,
versionFileGet.FileName, versionFileGet.FileVersion);
// 得到文件扩展名 // 得到文件扩展名
var fileExt = Path.GetExtension(versionFileGet.FileName); var fileExt = Path.GetExtension(versionFileGet.FileName);
var provider = new FileExtensionContentTypeProvider(); var provider = new FileExtensionContentTypeProvider();

406
aspnet-core/services/platform/LINGYUN.Platform.HttpApi.Host/Migrations/20200724092022_Add-Version-File-Field-Path-And-Platform-Type.Designer.cs

@ -0,0 +1,406 @@
// <auto-generated />
using System;
using LINGYUN.Platform.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Volo.Abp.EntityFrameworkCore;
namespace LINGYUN.Platform.Migrations
{
[DbContext(typeof(PlatformHttpApiHostMigrationsDbContext))]
[Migration("20200724092022_Add-Version-File-Field-Path-And-Platform-Type")]
partial class AddVersionFileFieldPathAndPlatformType
{
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("_Abp_DatabaseProvider", EfCoreDatabaseProvider.MySql)
.HasAnnotation("ProductVersion", "3.1.5")
.HasAnnotation("Relational:MaxIdentifierLength", 64);
modelBuilder.Entity("LINGYUN.Platform.Routes.RoleRoute", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
b.Property<DateTime>("CreationTime")
.HasColumnType("datetime(6)");
b.Property<Guid?>("CreatorId")
.HasColumnType("char(36)");
b.Property<Guid?>("DeleterId")
.HasColumnType("char(36)");
b.Property<DateTime?>("DeletionTime")
.HasColumnType("datetime(6)");
b.Property<bool>("IsDeleted")
.HasColumnType("tinyint(1)");
b.Property<DateTime?>("LastModificationTime")
.HasColumnType("datetime(6)");
b.Property<Guid?>("LastModifierId")
.HasColumnType("char(36)");
b.Property<string>("RoleName")
.IsRequired()
.HasColumnName("RoleName")
.HasColumnType("varchar(256) CHARACTER SET utf8mb4")
.HasMaxLength(256);
b.Property<Guid>("RouteId")
.HasColumnType("char(36)");
b.Property<Guid?>("TenantId")
.HasColumnName("TenantId")
.HasColumnType("char(36)");
b.HasKey("Id");
b.HasIndex("RoleName", "RouteId");
b.ToTable("AppPlatformRoleRoute");
});
modelBuilder.Entity("LINGYUN.Platform.Routes.Route", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("char(36)");
b.Property<bool>("AlwaysShow")
.HasColumnType("tinyint(1)");
b.Property<string>("Code")
.IsRequired()
.HasColumnName("Code")
.HasColumnType("varchar(95) CHARACTER SET utf8mb4")
.HasMaxLength(95);
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken()
.HasColumnName("ConcurrencyStamp")
.HasColumnType("varchar(40) CHARACTER SET utf8mb4")
.HasMaxLength(40);
b.Property<DateTime>("CreationTime")
.HasColumnName("CreationTime")
.HasColumnType("datetime(6)");
b.Property<Guid?>("CreatorId")
.HasColumnName("CreatorId")
.HasColumnType("char(36)");
b.Property<Guid?>("DeleterId")
.HasColumnName("DeleterId")
.HasColumnType("char(36)");
b.Property<DateTime?>("DeletionTime")
.HasColumnName("DeletionTime")
.HasColumnType("datetime(6)");
b.Property<string>("Description")
.HasColumnName("Description")
.HasColumnType("varchar(255) CHARACTER SET utf8mb4")
.HasMaxLength(255);
b.Property<string>("DisplayName")
.IsRequired()
.HasColumnName("DisplayName")
.HasColumnType("varchar(128) CHARACTER SET utf8mb4")
.HasMaxLength(128);
b.Property<string>("ExtraProperties")
.HasColumnName("ExtraProperties")
.HasColumnType("longtext CHARACTER SET utf8mb4");
b.Property<string>("FullName")
.HasColumnName("FullName")
.HasColumnType("varchar(128) CHARACTER SET utf8mb4")
.HasMaxLength(128);
b.Property<string>("Icon")
.HasColumnName("Icon")
.HasColumnType("varchar(128) CHARACTER SET utf8mb4")
.HasMaxLength(128);
b.Property<bool>("IsDeleted")
.ValueGeneratedOnAdd()
.HasColumnName("IsDeleted")
.HasColumnType("tinyint(1)")
.HasDefaultValue(false);
b.Property<bool>("IsMenu")
.HasColumnType("tinyint(1)");
b.Property<bool>("IsPublic")
.HasColumnType("tinyint(1)");
b.Property<bool>("IsSideBar")
.HasColumnType("tinyint(1)");
b.Property<bool>("IsStatic")
.HasColumnType("tinyint(1)");
b.Property<bool>("IsToolBar")
.HasColumnType("tinyint(1)");
b.Property<DateTime?>("LastModificationTime")
.HasColumnName("LastModificationTime")
.HasColumnType("datetime(6)");
b.Property<Guid?>("LastModifierId")
.HasColumnName("LastModifierId")
.HasColumnType("char(36)");
b.Property<string>("LinkUrl")
.IsRequired()
.HasColumnName("LinkUrl")
.HasColumnType("varchar(255) CHARACTER SET utf8mb4")
.HasMaxLength(255);
b.Property<string>("Name")
.IsRequired()
.HasColumnName("Name")
.HasColumnType("varchar(64) CHARACTER SET utf8mb4")
.HasMaxLength(64);
b.Property<Guid?>("ParentId")
.HasColumnType("char(36)");
b.Property<int>("PlatformType")
.HasColumnType("int");
b.Property<Guid?>("TenantId")
.HasColumnName("TenantId")
.HasColumnType("char(36)");
b.HasKey("Id");
b.HasIndex("Code");
b.HasIndex("ParentId");
b.ToTable("AppPlatformRoute");
});
modelBuilder.Entity("LINGYUN.Platform.Routes.UserRoute", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
b.Property<DateTime>("CreationTime")
.HasColumnType("datetime(6)");
b.Property<Guid?>("CreatorId")
.HasColumnType("char(36)");
b.Property<Guid?>("DeleterId")
.HasColumnType("char(36)");
b.Property<DateTime?>("DeletionTime")
.HasColumnType("datetime(6)");
b.Property<bool>("IsDeleted")
.HasColumnType("tinyint(1)");
b.Property<DateTime?>("LastModificationTime")
.HasColumnType("datetime(6)");
b.Property<Guid?>("LastModifierId")
.HasColumnType("char(36)");
b.Property<Guid>("RouteId")
.HasColumnType("char(36)");
b.Property<Guid?>("TenantId")
.HasColumnName("TenantId")
.HasColumnType("char(36)");
b.Property<Guid>("UserId")
.HasColumnType("char(36)");
b.HasKey("Id");
b.HasIndex("UserId", "RouteId");
b.ToTable("AppPlatformUserRoute");
});
modelBuilder.Entity("LINGYUN.Platform.Versions.AppVersion", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("char(36)");
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken()
.HasColumnName("ConcurrencyStamp")
.HasColumnType("varchar(40) CHARACTER SET utf8mb4")
.HasMaxLength(40);
b.Property<DateTime>("CreationTime")
.HasColumnName("CreationTime")
.HasColumnType("datetime(6)");
b.Property<Guid?>("CreatorId")
.HasColumnName("CreatorId")
.HasColumnType("char(36)");
b.Property<Guid?>("DeleterId")
.HasColumnName("DeleterId")
.HasColumnType("char(36)");
b.Property<DateTime?>("DeletionTime")
.HasColumnName("DeletionTime")
.HasColumnType("datetime(6)");
b.Property<string>("Description")
.HasColumnName("Description")
.HasColumnType("longtext CHARACTER SET utf8mb4")
.HasMaxLength(2048);
b.Property<string>("ExtraProperties")
.HasColumnName("ExtraProperties")
.HasColumnType("longtext CHARACTER SET utf8mb4");
b.Property<bool>("IsDeleted")
.ValueGeneratedOnAdd()
.HasColumnName("IsDeleted")
.HasColumnType("tinyint(1)")
.HasDefaultValue(false);
b.Property<DateTime?>("LastModificationTime")
.HasColumnName("LastModificationTime")
.HasColumnType("datetime(6)");
b.Property<Guid?>("LastModifierId")
.HasColumnName("LastModifierId")
.HasColumnType("char(36)");
b.Property<int>("Level")
.HasColumnType("int");
b.Property<int>("PlatformType")
.HasColumnType("int");
b.Property<Guid?>("TenantId")
.HasColumnName("TenantId")
.HasColumnType("char(36)");
b.Property<string>("Title")
.IsRequired()
.HasColumnName("Title")
.HasColumnType("varchar(50) CHARACTER SET utf8mb4")
.HasMaxLength(50);
b.Property<string>("Version")
.IsRequired()
.HasColumnName("Version")
.HasColumnType("varchar(20) CHARACTER SET utf8mb4")
.HasMaxLength(20);
b.HasKey("Id");
b.HasIndex("Version");
b.ToTable("AppPlatformVersion");
});
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")
.HasColumnName("CreationTime")
.HasColumnType("datetime(6)");
b.Property<Guid?>("CreatorId")
.HasColumnName("CreatorId")
.HasColumnType("char(36)");
b.Property<int>("DownloadCount")
.HasColumnType("int");
b.Property<int>("FileType")
.HasColumnType("int");
b.Property<DateTime?>("LastModificationTime")
.HasColumnName("LastModificationTime")
.HasColumnType("datetime(6)");
b.Property<Guid?>("LastModifierId")
.HasColumnName("LastModifierId")
.HasColumnType("char(36)");
b.Property<string>("Name")
.IsRequired()
.HasColumnName("Name")
.HasColumnType("varchar(255) CHARACTER SET utf8mb4")
.HasMaxLength(255);
b.Property<string>("Path")
.HasColumnName("Path")
.HasColumnType("varchar(255) CHARACTER SET utf8mb4")
.HasMaxLength(255);
b.Property<string>("SHA256")
.IsRequired()
.HasColumnName("SHA256")
.HasColumnType("varchar(65) CHARACTER SET utf8mb4")
.HasMaxLength(65);
b.Property<long>("Size")
.HasColumnType("bigint");
b.Property<Guid?>("TenantId")
.HasColumnName("TenantId")
.HasColumnType("char(36)");
b.Property<string>("Version")
.IsRequired()
.HasColumnName("Version")
.HasColumnType("varchar(20) CHARACTER SET utf8mb4")
.HasMaxLength(20);
b.HasKey("Id");
b.HasIndex("AppVersionId");
b.HasIndex("Path", "Name", "Version")
.IsUnique();
b.ToTable("AppPlatformVersionFile");
});
modelBuilder.Entity("LINGYUN.Platform.Routes.Route", b =>
{
b.HasOne("LINGYUN.Platform.Routes.Route", null)
.WithMany()
.HasForeignKey("ParentId");
});
modelBuilder.Entity("LINGYUN.Platform.Versions.VersionFile", b =>
{
b.HasOne("LINGYUN.Platform.Versions.AppVersion", "AppVersion")
.WithMany("Files")
.HasForeignKey("AppVersionId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
#pragma warning restore 612, 618
}
}
}

52
aspnet-core/services/platform/LINGYUN.Platform.HttpApi.Host/Migrations/20200724092022_Add-Version-File-Field-Path-And-Platform-Type.cs

@ -0,0 +1,52 @@
using Microsoft.EntityFrameworkCore.Migrations;
namespace LINGYUN.Platform.Migrations
{
public partial class AddVersionFileFieldPathAndPlatformType : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropIndex(
name: "IX_AppPlatformVersionFile_Name_Version",
table: "AppPlatformVersionFile");
migrationBuilder.AddColumn<string>(
name: "Path",
table: "AppPlatformVersionFile",
maxLength: 255,
nullable: true);
migrationBuilder.AddColumn<int>(
name: "PlatformType",
table: "AppPlatformVersion",
nullable: false,
defaultValue: 0);
migrationBuilder.CreateIndex(
name: "IX_AppPlatformVersionFile_Path_Name_Version",
table: "AppPlatformVersionFile",
columns: new[] { "Path", "Name", "Version" },
unique: true);
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropIndex(
name: "IX_AppPlatformVersionFile_Path_Name_Version",
table: "AppPlatformVersionFile");
migrationBuilder.DropColumn(
name: "Path",
table: "AppPlatformVersionFile");
migrationBuilder.DropColumn(
name: "PlatformType",
table: "AppPlatformVersion");
migrationBuilder.CreateIndex(
name: "IX_AppPlatformVersionFile_Name_Version",
table: "AppPlatformVersionFile",
columns: new[] { "Name", "Version" });
}
}
}

11
aspnet-core/services/platform/LINGYUN.Platform.HttpApi.Host/Migrations/PlatformHttpApiHostMigrationsDbContextModelSnapshot.cs

@ -286,6 +286,9 @@ namespace LINGYUN.Platform.Migrations
b.Property<int>("Level") b.Property<int>("Level")
.HasColumnType("int"); .HasColumnType("int");
b.Property<int>("PlatformType")
.HasColumnType("int");
b.Property<Guid?>("TenantId") b.Property<Guid?>("TenantId")
.HasColumnName("TenantId") .HasColumnName("TenantId")
.HasColumnType("char(36)"); .HasColumnType("char(36)");
@ -346,6 +349,11 @@ namespace LINGYUN.Platform.Migrations
.HasColumnType("varchar(255) CHARACTER SET utf8mb4") .HasColumnType("varchar(255) CHARACTER SET utf8mb4")
.HasMaxLength(255); .HasMaxLength(255);
b.Property<string>("Path")
.HasColumnName("Path")
.HasColumnType("varchar(255) CHARACTER SET utf8mb4")
.HasMaxLength(255);
b.Property<string>("SHA256") b.Property<string>("SHA256")
.IsRequired() .IsRequired()
.HasColumnName("SHA256") .HasColumnName("SHA256")
@ -369,7 +377,8 @@ namespace LINGYUN.Platform.Migrations
b.HasIndex("AppVersionId"); b.HasIndex("AppVersionId");
b.HasIndex("Name", "Version"); b.HasIndex("Path", "Name", "Version")
.IsUnique();
b.ToTable("AppPlatformVersionFile"); b.ToTable("AppPlatformVersionFile");
}); });

Loading…
Cancel
Save