Browse Source
* Upgrade abp framework to 6.0.2. * Update dapr package. * Update agile-config package. * Update stack-exchange-redis package. * Remove versions manager. * Add packages manager.pull/748/head
124 changed files with 4324 additions and 2040 deletions
@ -1,19 +1,19 @@ |
|||||
<Project Sdk="Microsoft.NET.Sdk"> |
<Project Sdk="Microsoft.NET.Sdk"> |
||||
|
|
||||
<Import Project="..\..\..\configureawait.props" /> |
<Import Project="..\..\..\configureawait.props" /> |
||||
<Import Project="..\..\..\common.props" /> |
<Import Project="..\..\..\common.props" /> |
||||
|
|
||||
<PropertyGroup> |
<PropertyGroup> |
||||
<TargetFramework>net6.0</TargetFramework> |
<TargetFramework>net6.0</TargetFramework> |
||||
<RootNamespace /> |
<RootNamespace /> |
||||
</PropertyGroup> |
</PropertyGroup> |
||||
|
|
||||
<ItemGroup> |
<ItemGroup> |
||||
<PackageReference Include="Volo.Abp.AspNetCore.Mvc" Version="$(VoloAbpPackageVersion)" /> |
<PackageReference Include="Volo.Abp.AspNetCore.Mvc" Version="$(VoloAbpPackageVersion)" /> |
||||
</ItemGroup> |
</ItemGroup> |
||||
|
|
||||
<ItemGroup> |
<ItemGroup> |
||||
<ProjectReference Include="..\LINGYUN.Abp.CachingManagement.Application.Contracts\LINGYUN.Abp.CachingManagement.Application.Contracts.csproj" /> |
<ProjectReference Include="..\LINGYUN.Abp.CachingManagement.Application.Contracts\LINGYUN.Abp.CachingManagement.Application.Contracts.csproj" /> |
||||
</ItemGroup> |
</ItemGroup> |
||||
|
|
||||
</Project> |
</Project> |
||||
|
|||||
@ -1,7 +1,8 @@ |
|||||
{ |
{ |
||||
"profiles": { |
"profiles": { |
||||
"LINGYUN.Abp.Cli": { |
"LINGYUN.Abp.Cli": { |
||||
"commandName": "Project" |
"commandName": "Project", |
||||
|
"commandLineArgs": "help create" |
||||
} |
} |
||||
} |
} |
||||
} |
} |
||||
@ -1,15 +1,15 @@ |
|||||
<Project Sdk="Microsoft.NET.Sdk"> |
<Project Sdk="Microsoft.NET.Sdk"> |
||||
|
|
||||
<Import Project="..\..\..\configureawait.props" /> |
<Import Project="..\..\..\configureawait.props" /> |
||||
<Import Project="..\..\..\common.props" /> |
<Import Project="..\..\..\common.props" /> |
||||
|
|
||||
<PropertyGroup> |
<PropertyGroup> |
||||
<TargetFramework>net6.0</TargetFramework> |
<TargetFramework>net6.0</TargetFramework> |
||||
<RootNamespace /> |
<RootNamespace /> |
||||
</PropertyGroup> |
</PropertyGroup> |
||||
|
|
||||
<ItemGroup> |
<ItemGroup> |
||||
<PackageReference Include="Volo.Abp.EntityFrameworkCore" Version="$(VoloAbpPackageVersion)" /> |
<PackageReference Include="Volo.Abp.EntityFrameworkCore" Version="$(VoloAbpPackageVersion)" /> |
||||
</ItemGroup> |
</ItemGroup> |
||||
|
|
||||
</Project> |
</Project> |
||||
|
|||||
@ -1,20 +1,20 @@ |
|||||
<Project Sdk="Microsoft.NET.Sdk"> |
<Project Sdk="Microsoft.NET.Sdk"> |
||||
|
|
||||
<Import Project="..\..\..\configureawait.props" /> |
<Import Project="..\..\..\configureawait.props" /> |
||||
<Import Project="..\..\..\common.props" /> |
<Import Project="..\..\..\common.props" /> |
||||
|
|
||||
<PropertyGroup> |
<PropertyGroup> |
||||
<TargetFramework>net6.0</TargetFramework> |
<TargetFramework>net6.0</TargetFramework> |
||||
<RootNamespace /> |
<RootNamespace /> |
||||
<Description>Cap分布式事件总线</Description> |
<Description>Cap分布式事件总线</Description> |
||||
<GenerateDocumentationFile>true</GenerateDocumentationFile> |
<GenerateDocumentationFile>true</GenerateDocumentationFile> |
||||
<DocumentationFile>$(SolutionDir)modules\common\LINGYUN.Abp.EventBus.CAP\LINGYUN.Abp.EventBus.CAP.xml</DocumentationFile> |
<DocumentationFile>$(SolutionDir)modules\common\LINGYUN.Abp.EventBus.CAP\LINGYUN.Abp.EventBus.CAP.xml</DocumentationFile> |
||||
</PropertyGroup> |
</PropertyGroup> |
||||
|
|
||||
<ItemGroup> |
<ItemGroup> |
||||
<PackageReference Include="DotNetCore.CAP" Version="$(DotNetCoreCAPPackageVersion)" /> |
<PackageReference Include="DotNetCore.CAP" Version="$(DotNetCoreCAPPackageVersion)" /> |
||||
<PackageReference Include="Volo.Abp.EventBus" Version="$(VoloAbpPackageVersion)" /> |
<PackageReference Include="Volo.Abp.EventBus" Version="$(VoloAbpPackageVersion)" /> |
||||
<PackageReference Include="Volo.Abp.Json" Version="$(VoloAbpPackageVersion)" /> |
<PackageReference Include="Volo.Abp.Json" Version="$(VoloAbpPackageVersion)" /> |
||||
</ItemGroup> |
</ItemGroup> |
||||
|
|
||||
</Project> |
</Project> |
||||
|
|||||
@ -1,16 +1,16 @@ |
|||||
<Project Sdk="Microsoft.NET.Sdk"> |
<Project Sdk="Microsoft.NET.Sdk"> |
||||
|
|
||||
<Import Project="..\..\..\configureawait.props" /> |
<Import Project="..\..\..\configureawait.props" /> |
||||
<Import Project="..\..\..\common.props" /> |
<Import Project="..\..\..\common.props" /> |
||||
|
|
||||
<PropertyGroup> |
<PropertyGroup> |
||||
<TargetFramework>net6.0</TargetFramework> |
<TargetFramework>net6.0</TargetFramework> |
||||
<RootNamespace /> |
<RootNamespace /> |
||||
</PropertyGroup> |
</PropertyGroup> |
||||
|
|
||||
<ItemGroup> |
<ItemGroup> |
||||
<ProjectReference Include="..\..\common\LINGYUN.Abp.Wrapper\LINGYUN.Abp.Wrapper.csproj" /> |
<ProjectReference Include="..\..\common\LINGYUN.Abp.Wrapper\LINGYUN.Abp.Wrapper.csproj" /> |
||||
<ProjectReference Include="..\LINGYUN.Abp.Dapr.Actors.AspNetCore\LINGYUN.Abp.Dapr.Actors.AspNetCore.csproj" /> |
<ProjectReference Include="..\LINGYUN.Abp.Dapr.Actors.AspNetCore\LINGYUN.Abp.Dapr.Actors.AspNetCore.csproj" /> |
||||
</ItemGroup> |
</ItemGroup> |
||||
|
|
||||
</Project> |
</Project> |
||||
|
|||||
@ -1,16 +1,16 @@ |
|||||
<Project Sdk="Microsoft.NET.Sdk"> |
<Project Sdk="Microsoft.NET.Sdk"> |
||||
|
|
||||
<Import Project="..\..\..\configureawait.props" /> |
<Import Project="..\..\..\configureawait.props" /> |
||||
<Import Project="..\..\..\common.props" /> |
<Import Project="..\..\..\common.props" /> |
||||
|
|
||||
<PropertyGroup> |
<PropertyGroup> |
||||
<TargetFramework>net6.0</TargetFramework> |
<TargetFramework>net6.0</TargetFramework> |
||||
<RootNamespace /> |
<RootNamespace /> |
||||
</PropertyGroup> |
</PropertyGroup> |
||||
|
|
||||
<ItemGroup> |
<ItemGroup> |
||||
<PackageReference Include="Dapr.Actors.AspNetCore" Version="$(DaprPackageVersion)" /> |
<PackageReference Include="Dapr.Actors.AspNetCore" Version="$(DaprPackageVersion)" /> |
||||
<PackageReference Include="Volo.Abp.AspNetCore" Version="$(VoloAbpPackageVersion)" /> |
<PackageReference Include="Volo.Abp.AspNetCore" Version="$(VoloAbpPackageVersion)" /> |
||||
</ItemGroup> |
</ItemGroup> |
||||
|
|
||||
</Project> |
</Project> |
||||
|
|||||
@ -1,15 +1,15 @@ |
|||||
<Project Sdk="Microsoft.NET.Sdk"> |
<Project Sdk="Microsoft.NET.Sdk"> |
||||
|
|
||||
<Import Project="..\..\..\configureawait.props" /> |
<Import Project="..\..\..\configureawait.props" /> |
||||
<Import Project="..\..\..\common.props" /> |
<Import Project="..\..\..\common.props" /> |
||||
|
|
||||
<PropertyGroup> |
<PropertyGroup> |
||||
<TargetFramework>net6.0</TargetFramework> |
<TargetFramework>net6.0</TargetFramework> |
||||
<RootNamespace /> |
<RootNamespace /> |
||||
</PropertyGroup> |
</PropertyGroup> |
||||
|
|
||||
<ItemGroup> |
<ItemGroup> |
||||
<PackageReference Include="Dapr.Actors" Version="$(DaprPackageVersion)" /> |
<PackageReference Include="Dapr.Actors" Version="$(DaprPackageVersion)" /> |
||||
<PackageReference Include="Volo.Abp.Http.Client" Version="$(VoloAbpPackageVersion)" /> |
<PackageReference Include="Volo.Abp.Http.Client" Version="$(VoloAbpPackageVersion)" /> |
||||
</ItemGroup> |
</ItemGroup> |
||||
</Project> |
</Project> |
||||
|
|||||
@ -1,16 +1,16 @@ |
|||||
<Project Sdk="Microsoft.NET.Sdk"> |
<Project Sdk="Microsoft.NET.Sdk"> |
||||
|
|
||||
<Import Project="..\..\..\configureawait.props" /> |
<Import Project="..\..\..\configureawait.props" /> |
||||
<Import Project="..\..\..\common.props" /> |
<Import Project="..\..\..\common.props" /> |
||||
|
|
||||
<PropertyGroup> |
<PropertyGroup> |
||||
<TargetFramework>net6.0</TargetFramework> |
<TargetFramework>net6.0</TargetFramework> |
||||
<RootNamespace /> |
<RootNamespace /> |
||||
</PropertyGroup> |
</PropertyGroup> |
||||
|
|
||||
<ItemGroup> |
<ItemGroup> |
||||
<ProjectReference Include="..\..\common\LINGYUN.Abp.Wrapper\LINGYUN.Abp.Wrapper.csproj" /> |
<ProjectReference Include="..\..\common\LINGYUN.Abp.Wrapper\LINGYUN.Abp.Wrapper.csproj" /> |
||||
<ProjectReference Include="..\LINGYUN.Abp.Dapr.Client\LINGYUN.Abp.Dapr.Client.csproj" /> |
<ProjectReference Include="..\LINGYUN.Abp.Dapr.Client\LINGYUN.Abp.Dapr.Client.csproj" /> |
||||
</ItemGroup> |
</ItemGroup> |
||||
|
|
||||
</Project> |
</Project> |
||||
|
|||||
@ -1,19 +1,19 @@ |
|||||
<Project Sdk="Microsoft.NET.Sdk"> |
<Project Sdk="Microsoft.NET.Sdk"> |
||||
|
|
||||
<Import Project="..\..\..\configureawait.props" /> |
<Import Project="..\..\..\configureawait.props" /> |
||||
<Import Project="..\..\..\common.props" /> |
<Import Project="..\..\..\common.props" /> |
||||
|
|
||||
<PropertyGroup> |
<PropertyGroup> |
||||
<TargetFramework>net6.0</TargetFramework> |
<TargetFramework>net6.0</TargetFramework> |
||||
<RootNamespace /> |
<RootNamespace /> |
||||
</PropertyGroup> |
</PropertyGroup> |
||||
|
|
||||
<ItemGroup> |
<ItemGroup> |
||||
<PackageReference Include="Volo.Abp.Http.Client" Version="$(VoloAbpPackageVersion)" /> |
<PackageReference Include="Volo.Abp.Http.Client" Version="$(VoloAbpPackageVersion)" /> |
||||
</ItemGroup> |
</ItemGroup> |
||||
|
|
||||
<ItemGroup> |
<ItemGroup> |
||||
<ProjectReference Include="..\LINGYUN.Abp.Dapr\LINGYUN.Abp.Dapr.csproj" /> |
<ProjectReference Include="..\LINGYUN.Abp.Dapr\LINGYUN.Abp.Dapr.csproj" /> |
||||
</ItemGroup> |
</ItemGroup> |
||||
|
|
||||
</Project> |
</Project> |
||||
|
|||||
@ -1,16 +1,16 @@ |
|||||
<Project Sdk="Microsoft.NET.Sdk"> |
<Project Sdk="Microsoft.NET.Sdk"> |
||||
|
|
||||
<Import Project="..\..\..\configureawait.props" /> |
<Import Project="..\..\..\configureawait.props" /> |
||||
<Import Project="..\..\..\common.props" /> |
<Import Project="..\..\..\common.props" /> |
||||
|
|
||||
<PropertyGroup> |
<PropertyGroup> |
||||
<TargetFramework>net6.0</TargetFramework> |
<TargetFramework>net6.0</TargetFramework> |
||||
<RootNamespace /> |
<RootNamespace /> |
||||
</PropertyGroup> |
</PropertyGroup> |
||||
|
|
||||
<ItemGroup> |
<ItemGroup> |
||||
<PackageReference Include="Volo.Abp.Json" Version="$(VoloAbpPackageVersion)" /> |
<PackageReference Include="Volo.Abp.Json" Version="$(VoloAbpPackageVersion)" /> |
||||
<PackageReference Include="Dapr.Client" Version="$(DaprPackageVersion)" /> |
<PackageReference Include="Dapr.Client" Version="$(DaprPackageVersion)" /> |
||||
</ItemGroup> |
</ItemGroup> |
||||
|
|
||||
</Project> |
</Project> |
||||
|
|||||
@ -1,21 +1,21 @@ |
|||||
<Project Sdk="Microsoft.NET.Sdk"> |
<Project Sdk="Microsoft.NET.Sdk"> |
||||
|
|
||||
<Import Project="..\..\..\configureawait.props" /> |
<Import Project="..\..\..\configureawait.props" /> |
||||
<Import Project="..\..\..\common.props" /> |
<Import Project="..\..\..\common.props" /> |
||||
|
|
||||
<PropertyGroup> |
<PropertyGroup> |
||||
<TargetFramework>net6.0</TargetFramework> |
<TargetFramework>net6.0</TargetFramework> |
||||
<RootNamespace /> |
<RootNamespace /> |
||||
</PropertyGroup> |
</PropertyGroup> |
||||
|
|
||||
<ItemGroup> |
<ItemGroup> |
||||
<PackageReference Include="Volo.Abp.Threading" Version="$(VoloAbpPackageVersion)" /> |
<PackageReference Include="Volo.Abp.Threading" Version="$(VoloAbpPackageVersion)" /> |
||||
<PackageReference Include="Volo.Abp.DistributedLocking.Abstractions" Version="$(VoloAbpPackageVersion)" /> |
<PackageReference Include="Volo.Abp.DistributedLocking.Abstractions" Version="$(VoloAbpPackageVersion)" /> |
||||
<PackageReference Include="Microsoft.Bcl.AsyncInterfaces" Version="$(MicrosoftPackageVersion)" /> |
<PackageReference Include="Microsoft.Bcl.AsyncInterfaces" Version="$(MicrosoftPackageVersion)" /> |
||||
</ItemGroup> |
</ItemGroup> |
||||
|
|
||||
<ItemGroup> |
<ItemGroup> |
||||
<ProjectReference Include="..\LINGYUN.Abp.Dapr\LINGYUN.Abp.Dapr.csproj" /> |
<ProjectReference Include="..\LINGYUN.Abp.Dapr\LINGYUN.Abp.Dapr.csproj" /> |
||||
</ItemGroup> |
</ItemGroup> |
||||
|
|
||||
</Project> |
</Project> |
||||
|
|||||
@ -1,20 +1,20 @@ |
|||||
<Project Sdk="Microsoft.NET.Sdk"> |
<Project Sdk="Microsoft.NET.Sdk"> |
||||
|
|
||||
<Import Project="..\..\..\configureawait.props" /> |
<Import Project="..\..\..\configureawait.props" /> |
||||
<Import Project="..\..\..\common.props" /> |
<Import Project="..\..\..\common.props" /> |
||||
|
|
||||
<PropertyGroup> |
<PropertyGroup> |
||||
<TargetFramework>net6.0</TargetFramework> |
<TargetFramework>net6.0</TargetFramework> |
||||
<LangVersion>9.0</LangVersion> |
<LangVersion>9.0</LangVersion> |
||||
<RootNamespace /> |
<RootNamespace /> |
||||
</PropertyGroup> |
</PropertyGroup> |
||||
|
|
||||
<ItemGroup> |
<ItemGroup> |
||||
<PackageReference Include="Volo.Abp.EntityFrameworkCore" Version="$(VoloAbpPackageVersion)" /> |
<PackageReference Include="Volo.Abp.EntityFrameworkCore" Version="$(VoloAbpPackageVersion)" /> |
||||
</ItemGroup> |
</ItemGroup> |
||||
|
|
||||
<ItemGroup> |
<ItemGroup> |
||||
<ProjectReference Include="..\LINGYUN.Abp.DataProtection\LINGYUN.Abp.DataProtection.csproj" /> |
<ProjectReference Include="..\LINGYUN.Abp.DataProtection\LINGYUN.Abp.DataProtection.csproj" /> |
||||
</ItemGroup> |
</ItemGroup> |
||||
|
|
||||
</Project> |
</Project> |
||||
|
|||||
@ -1,20 +1,20 @@ |
|||||
<Project Sdk="Microsoft.NET.Sdk"> |
<Project Sdk="Microsoft.NET.Sdk"> |
||||
|
|
||||
<Import Project="..\..\..\configureawait.props" /> |
<Import Project="..\..\..\configureawait.props" /> |
||||
<Import Project="..\..\..\common.props" /> |
<Import Project="..\..\..\common.props" /> |
||||
|
|
||||
<PropertyGroup> |
<PropertyGroup> |
||||
<TargetFramework>net6.0</TargetFramework> |
<TargetFramework>net6.0</TargetFramework> |
||||
<RootNamespace /> |
<RootNamespace /> |
||||
</PropertyGroup> |
</PropertyGroup> |
||||
|
|
||||
<ItemGroup> |
<ItemGroup> |
||||
<PackageReference Include="Volo.Abp.Ddd.Application" Version="$(VoloAbpPackageVersion)" /> |
<PackageReference Include="Volo.Abp.Ddd.Application" Version="$(VoloAbpPackageVersion)" /> |
||||
</ItemGroup> |
</ItemGroup> |
||||
|
|
||||
<ItemGroup> |
<ItemGroup> |
||||
<ProjectReference Include="..\LINGYUN.Abp.IdentityServer.Application.Contracts\LINGYUN.Abp.IdentityServer.Application.Contracts.csproj" /> |
<ProjectReference Include="..\LINGYUN.Abp.IdentityServer.Application.Contracts\LINGYUN.Abp.IdentityServer.Application.Contracts.csproj" /> |
||||
<ProjectReference Include="..\LINGYUN.Abp.IdentityServer.Domain\LINGYUN.Abp.IdentityServer.Domain.csproj" /> |
<ProjectReference Include="..\LINGYUN.Abp.IdentityServer.Domain\LINGYUN.Abp.IdentityServer.Domain.csproj" /> |
||||
</ItemGroup> |
</ItemGroup> |
||||
|
|
||||
</Project> |
</Project> |
||||
|
|||||
@ -1,23 +1,23 @@ |
|||||
<Project Sdk="Microsoft.NET.Sdk"> |
<Project Sdk="Microsoft.NET.Sdk"> |
||||
|
|
||||
<Import Project="..\..\..\configureawait.props" /> |
<Import Project="..\..\..\configureawait.props" /> |
||||
<Import Project="..\..\..\common.props" /> |
<Import Project="..\..\..\common.props" /> |
||||
|
|
||||
<PropertyGroup> |
<PropertyGroup> |
||||
<TargetFramework>net6.0</TargetFramework> |
<TargetFramework>net6.0</TargetFramework> |
||||
<RootNamespace /> |
<RootNamespace /> |
||||
</PropertyGroup> |
</PropertyGroup> |
||||
|
|
||||
<ItemGroup> |
<ItemGroup> |
||||
<None Remove="LINGYUN\Abp\IdentityServer\LinkUser\Localization\*.json" /> |
<None Remove="LINGYUN\Abp\IdentityServer\LinkUser\Localization\*.json" /> |
||||
</ItemGroup> |
</ItemGroup> |
||||
|
|
||||
<ItemGroup> |
<ItemGroup> |
||||
<EmbeddedResource Include="LINGYUN\Abp\IdentityServer\LinkUser\Localization\*.json" /> |
<EmbeddedResource Include="LINGYUN\Abp\IdentityServer\LinkUser\Localization\*.json" /> |
||||
</ItemGroup> |
</ItemGroup> |
||||
|
|
||||
<ItemGroup> |
<ItemGroup> |
||||
<PackageReference Include="Volo.Abp.IdentityServer.Domain" Version="$(VoloAbpPackageVersion)" /> |
<PackageReference Include="Volo.Abp.IdentityServer.Domain" Version="$(VoloAbpPackageVersion)" /> |
||||
</ItemGroup> |
</ItemGroup> |
||||
|
|
||||
</Project> |
</Project> |
||||
|
|||||
@ -1,15 +1,15 @@ |
|||||
<Project Sdk="Microsoft.NET.Sdk"> |
<Project Sdk="Microsoft.NET.Sdk"> |
||||
|
|
||||
<Import Project="..\..\..\common.props" /> |
<Import Project="..\..\..\common.props" /> |
||||
<Import Project="..\..\..\configureawait.props" /> |
<Import Project="..\..\..\configureawait.props" /> |
||||
|
|
||||
<PropertyGroup> |
<PropertyGroup> |
||||
<TargetFramework>net6.0</TargetFramework> |
<TargetFramework>net6.0</TargetFramework> |
||||
<RootNamespace /> |
<RootNamespace /> |
||||
</PropertyGroup> |
</PropertyGroup> |
||||
|
|
||||
<ItemGroup> |
<ItemGroup> |
||||
<PackageReference Include="Volo.Abp.AspNetCore" Version="$(VoloAbpPackageVersion)" /> |
<PackageReference Include="Volo.Abp.AspNetCore" Version="$(VoloAbpPackageVersion)" /> |
||||
</ItemGroup> |
</ItemGroup> |
||||
|
|
||||
</Project> |
</Project> |
||||
|
|||||
@ -1,19 +1,19 @@ |
|||||
<Project Sdk="Microsoft.NET.Sdk"> |
<Project Sdk="Microsoft.NET.Sdk"> |
||||
|
|
||||
<Import Project="..\..\..\configureawait.props" /> |
<Import Project="..\..\..\configureawait.props" /> |
||||
<Import Project="..\..\..\common.props" /> |
<Import Project="..\..\..\common.props" /> |
||||
|
|
||||
<PropertyGroup> |
<PropertyGroup> |
||||
<TargetFramework>net6.0</TargetFramework> |
<TargetFramework>net6.0</TargetFramework> |
||||
<RootNamespace /> |
<RootNamespace /> |
||||
</PropertyGroup> |
</PropertyGroup> |
||||
|
|
||||
<ItemGroup> |
<ItemGroup> |
||||
<PackageReference Include="Volo.Abp.EntityFrameworkCore" Version="$(VoloAbpPackageVersion)" /> |
<PackageReference Include="Volo.Abp.EntityFrameworkCore" Version="$(VoloAbpPackageVersion)" /> |
||||
</ItemGroup> |
</ItemGroup> |
||||
|
|
||||
<ItemGroup> |
<ItemGroup> |
||||
<ProjectReference Include="..\LINGYUN.Abp.LocalizationManagement.Domain\LINGYUN.Abp.LocalizationManagement.Domain.csproj" /> |
<ProjectReference Include="..\LINGYUN.Abp.LocalizationManagement.Domain\LINGYUN.Abp.LocalizationManagement.Domain.csproj" /> |
||||
</ItemGroup> |
</ItemGroup> |
||||
|
|
||||
</Project> |
</Project> |
||||
|
|||||
@ -1,16 +1,16 @@ |
|||||
<Project Sdk="Microsoft.NET.Sdk"> |
<Project Sdk="Microsoft.NET.Sdk"> |
||||
|
|
||||
<Import Project="..\..\..\configureawait.props" /> |
<Import Project="..\..\..\configureawait.props" /> |
||||
<Import Project="..\..\..\common.props" /> |
<Import Project="..\..\..\common.props" /> |
||||
|
|
||||
<PropertyGroup> |
<PropertyGroup> |
||||
<TargetFramework>net6.0</TargetFramework> |
<TargetFramework>net6.0</TargetFramework> |
||||
<RootNamespace /> |
<RootNamespace /> |
||||
</PropertyGroup> |
</PropertyGroup> |
||||
|
|
||||
<ItemGroup> |
<ItemGroup> |
||||
<ProjectReference Include="..\..\localization\LINGYUN.Abp.AspNetCore.Mvc.Localization\LINGYUN.Abp.AspNetCore.Mvc.Localization.csproj" /> |
<ProjectReference Include="..\..\localization\LINGYUN.Abp.AspNetCore.Mvc.Localization\LINGYUN.Abp.AspNetCore.Mvc.Localization.csproj" /> |
||||
<ProjectReference Include="..\LINGYUN.Abp.LocalizationManagement.Application.Contracts\LINGYUN.Abp.LocalizationManagement.Application.Contracts.csproj" /> |
<ProjectReference Include="..\LINGYUN.Abp.LocalizationManagement.Application.Contracts\LINGYUN.Abp.LocalizationManagement.Application.Contracts.csproj" /> |
||||
</ItemGroup> |
</ItemGroup> |
||||
|
|
||||
</Project> |
</Project> |
||||
|
|||||
@ -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" |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -1,19 +1,19 @@ |
|||||
<Project Sdk="Microsoft.NET.Sdk"> |
<Project Sdk="Microsoft.NET.Sdk"> |
||||
|
|
||||
<Import Project="..\..\..\configureawait.props" /> |
<Import Project="..\..\..\configureawait.props" /> |
||||
<Import Project="..\..\..\common.props" /> |
<Import Project="..\..\..\common.props" /> |
||||
|
|
||||
<PropertyGroup> |
<PropertyGroup> |
||||
<TargetFramework>net6.0</TargetFramework> |
<TargetFramework>net6.0</TargetFramework> |
||||
<RootNamespace /> |
<RootNamespace /> |
||||
</PropertyGroup> |
</PropertyGroup> |
||||
|
|
||||
<ItemGroup> |
<ItemGroup> |
||||
<PackageReference Include="Volo.Abp.EntityFrameworkCore" Version="$(VoloAbpPackageVersion)" /> |
<PackageReference Include="Volo.Abp.EntityFrameworkCore" Version="$(VoloAbpPackageVersion)" /> |
||||
</ItemGroup> |
</ItemGroup> |
||||
|
|
||||
<ItemGroup> |
<ItemGroup> |
||||
<ProjectReference Include="..\LINGYUN.Abp.TextTemplating.Domain\LINGYUN.Abp.TextTemplating.Domain.csproj" /> |
<ProjectReference Include="..\LINGYUN.Abp.TextTemplating.Domain\LINGYUN.Abp.TextTemplating.Domain.csproj" /> |
||||
</ItemGroup> |
</ItemGroup> |
||||
|
|
||||
</Project> |
</Project> |
||||
|
|||||
Some files were not shown because too many files changed in this diff
Loading…
Reference in new issue