committed by
GitHub
214 changed files with 27053 additions and 13790 deletions
@ -0,0 +1,119 @@ |
|||
|
|||
Microsoft Visual Studio Solution File, Format Version 12.00 |
|||
# Visual Studio Version 17 |
|||
VisualStudioVersion = 17.2.32630.192 |
|||
MinimumVisualStudioVersion = 10.0.40219.1 |
|||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "host", "host", "{DB7C4A00-8538-4C69-BC14-6D680A22287E}" |
|||
EndProject |
|||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{013E1408-EDF4-4394-95E6-AFF0F7E81CAF}" |
|||
EndProject |
|||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{B8FE9F89-1CBC-49F8-A888-1600C7A6F60A}" |
|||
EndProject |
|||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Lion.AbpPro.LanguageManagement.Application", "src\Lion.AbpPro.LanguageManagement.Application\Lion.AbpPro.LanguageManagement.Application.csproj", "{0960777B-0375-440D-AFD3-CD12F8B67ED2}" |
|||
EndProject |
|||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Lion.AbpPro.LanguageManagement.Application.Contracts", "src\Lion.AbpPro.LanguageManagement.Application.Contracts\Lion.AbpPro.LanguageManagement.Application.Contracts.csproj", "{E7ACD36D-7BFA-4E31-9E30-855E938A040B}" |
|||
EndProject |
|||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Lion.AbpPro.LanguageManagement.Domain", "src\Lion.AbpPro.LanguageManagement.Domain\Lion.AbpPro.LanguageManagement.Domain.csproj", "{53DBEDC9-C4CB-4118-ABE4-F2E792BE74BF}" |
|||
EndProject |
|||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Lion.AbpPro.LanguageManagement.Domain.Shared", "src\Lion.AbpPro.LanguageManagement.Domain.Shared\Lion.AbpPro.LanguageManagement.Domain.Shared.csproj", "{B98CE0C0-AEC1-4FC0-ACE2-6E06C4093444}" |
|||
EndProject |
|||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Lion.AbpPro.LanguageManagement.EntityFrameworkCore", "src\Lion.AbpPro.LanguageManagement.EntityFrameworkCore\Lion.AbpPro.LanguageManagement.EntityFrameworkCore.csproj", "{EFBB8E00-5B36-440C-AC3D-6095A937D784}" |
|||
EndProject |
|||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Lion.AbpPro.LanguageManagement.HttpApi.Client", "src\Lion.AbpPro.LanguageManagement.HttpApi.Client\Lion.AbpPro.LanguageManagement.HttpApi.Client.csproj", "{5C109B06-59A5-4B6E-8909-AED8FD7F80E3}" |
|||
EndProject |
|||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Lion.AbpPro.LanguageManagement.HttpApi", "src\Lion.AbpPro.LanguageManagement.HttpApi\Lion.AbpPro.LanguageManagement.HttpApi.csproj", "{3870F577-A49E-48D1-8CB0-7B73E11CE68D}" |
|||
EndProject |
|||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Lion.AbpPro.LanguageManagement.Domain.Tests", "test\Lion.AbpPro.LanguageManagement.Domain.Tests\Lion.AbpPro.LanguageManagement.Domain.Tests.csproj", "{81D1D5F8-2CAA-48D4-9AEF-F94F27EB913A}" |
|||
EndProject |
|||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Lion.AbpPro.LanguageManagement.EntityFrameworkCore.Tests", "test\Lion.AbpPro.LanguageManagement.EntityFrameworkCore.Tests\Lion.AbpPro.LanguageManagement.EntityFrameworkCore.Tests.csproj", "{4BE100BB-D519-41A9-8265-054A436CDACF}" |
|||
EndProject |
|||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Lion.AbpPro.LanguageManagement.TestBase", "test\Lion.AbpPro.LanguageManagement.TestBase\Lion.AbpPro.LanguageManagement.TestBase.csproj", "{B7C25B05-818B-48B6-9919-47BCA07C01BC}" |
|||
EndProject |
|||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Lion.AbpPro.LanguageManagement.HttpApi.Host", "host\Lion.AbpPro.LanguageManagement.HttpApi.Host\Lion.AbpPro.LanguageManagement.HttpApi.Host.csproj", "{DD712B57-563F-46E4-91D0-7239C60F5AE6}" |
|||
EndProject |
|||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Lion.AbpPro.LanguageManagement.Application.Tests", "test\Lion.AbpPro.LanguageManagement.Application.Tests\Lion.AbpPro.LanguageManagement.Application.Tests.csproj", "{7C4EE2EC-8793-4A96-817C-83318C0D5DCD}" |
|||
EndProject |
|||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "0.Solution Items", "0.Solution Items", "{A1585563-E304-4C1A-982F-EFB9A17212B4}" |
|||
ProjectSection(SolutionItems) = preProject |
|||
Directory.Build.Lion.targets = Directory.Build.Lion.targets |
|||
Directory.Build.Microsoft.targets = Directory.Build.Microsoft.targets |
|||
Directory.Build.targets = Directory.Build.targets |
|||
Directory.Build.Volo.targets = Directory.Build.Volo.targets |
|||
EndProjectSection |
|||
EndProject |
|||
Global |
|||
GlobalSection(SolutionConfigurationPlatforms) = preSolution |
|||
Debug|Any CPU = Debug|Any CPU |
|||
Release|Any CPU = Release|Any CPU |
|||
EndGlobalSection |
|||
GlobalSection(ProjectConfigurationPlatforms) = postSolution |
|||
{0960777B-0375-440D-AFD3-CD12F8B67ED2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
|||
{0960777B-0375-440D-AFD3-CD12F8B67ED2}.Debug|Any CPU.Build.0 = Debug|Any CPU |
|||
{0960777B-0375-440D-AFD3-CD12F8B67ED2}.Release|Any CPU.ActiveCfg = Release|Any CPU |
|||
{0960777B-0375-440D-AFD3-CD12F8B67ED2}.Release|Any CPU.Build.0 = Release|Any CPU |
|||
{E7ACD36D-7BFA-4E31-9E30-855E938A040B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
|||
{E7ACD36D-7BFA-4E31-9E30-855E938A040B}.Debug|Any CPU.Build.0 = Debug|Any CPU |
|||
{E7ACD36D-7BFA-4E31-9E30-855E938A040B}.Release|Any CPU.ActiveCfg = Release|Any CPU |
|||
{E7ACD36D-7BFA-4E31-9E30-855E938A040B}.Release|Any CPU.Build.0 = Release|Any CPU |
|||
{53DBEDC9-C4CB-4118-ABE4-F2E792BE74BF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
|||
{53DBEDC9-C4CB-4118-ABE4-F2E792BE74BF}.Debug|Any CPU.Build.0 = Debug|Any CPU |
|||
{53DBEDC9-C4CB-4118-ABE4-F2E792BE74BF}.Release|Any CPU.ActiveCfg = Release|Any CPU |
|||
{53DBEDC9-C4CB-4118-ABE4-F2E792BE74BF}.Release|Any CPU.Build.0 = Release|Any CPU |
|||
{B98CE0C0-AEC1-4FC0-ACE2-6E06C4093444}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
|||
{B98CE0C0-AEC1-4FC0-ACE2-6E06C4093444}.Debug|Any CPU.Build.0 = Debug|Any CPU |
|||
{B98CE0C0-AEC1-4FC0-ACE2-6E06C4093444}.Release|Any CPU.ActiveCfg = Release|Any CPU |
|||
{B98CE0C0-AEC1-4FC0-ACE2-6E06C4093444}.Release|Any CPU.Build.0 = Release|Any CPU |
|||
{EFBB8E00-5B36-440C-AC3D-6095A937D784}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
|||
{EFBB8E00-5B36-440C-AC3D-6095A937D784}.Debug|Any CPU.Build.0 = Debug|Any CPU |
|||
{EFBB8E00-5B36-440C-AC3D-6095A937D784}.Release|Any CPU.ActiveCfg = Release|Any CPU |
|||
{EFBB8E00-5B36-440C-AC3D-6095A937D784}.Release|Any CPU.Build.0 = Release|Any CPU |
|||
{5C109B06-59A5-4B6E-8909-AED8FD7F80E3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
|||
{5C109B06-59A5-4B6E-8909-AED8FD7F80E3}.Debug|Any CPU.Build.0 = Debug|Any CPU |
|||
{5C109B06-59A5-4B6E-8909-AED8FD7F80E3}.Release|Any CPU.ActiveCfg = Release|Any CPU |
|||
{5C109B06-59A5-4B6E-8909-AED8FD7F80E3}.Release|Any CPU.Build.0 = Release|Any CPU |
|||
{3870F577-A49E-48D1-8CB0-7B73E11CE68D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
|||
{3870F577-A49E-48D1-8CB0-7B73E11CE68D}.Debug|Any CPU.Build.0 = Debug|Any CPU |
|||
{3870F577-A49E-48D1-8CB0-7B73E11CE68D}.Release|Any CPU.ActiveCfg = Release|Any CPU |
|||
{3870F577-A49E-48D1-8CB0-7B73E11CE68D}.Release|Any CPU.Build.0 = Release|Any CPU |
|||
{81D1D5F8-2CAA-48D4-9AEF-F94F27EB913A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
|||
{81D1D5F8-2CAA-48D4-9AEF-F94F27EB913A}.Debug|Any CPU.Build.0 = Debug|Any CPU |
|||
{81D1D5F8-2CAA-48D4-9AEF-F94F27EB913A}.Release|Any CPU.ActiveCfg = Release|Any CPU |
|||
{81D1D5F8-2CAA-48D4-9AEF-F94F27EB913A}.Release|Any CPU.Build.0 = Release|Any CPU |
|||
{4BE100BB-D519-41A9-8265-054A436CDACF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
|||
{4BE100BB-D519-41A9-8265-054A436CDACF}.Debug|Any CPU.Build.0 = Debug|Any CPU |
|||
{4BE100BB-D519-41A9-8265-054A436CDACF}.Release|Any CPU.ActiveCfg = Release|Any CPU |
|||
{4BE100BB-D519-41A9-8265-054A436CDACF}.Release|Any CPU.Build.0 = Release|Any CPU |
|||
{B7C25B05-818B-48B6-9919-47BCA07C01BC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
|||
{B7C25B05-818B-48B6-9919-47BCA07C01BC}.Debug|Any CPU.Build.0 = Debug|Any CPU |
|||
{B7C25B05-818B-48B6-9919-47BCA07C01BC}.Release|Any CPU.ActiveCfg = Release|Any CPU |
|||
{B7C25B05-818B-48B6-9919-47BCA07C01BC}.Release|Any CPU.Build.0 = Release|Any CPU |
|||
{DD712B57-563F-46E4-91D0-7239C60F5AE6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
|||
{DD712B57-563F-46E4-91D0-7239C60F5AE6}.Debug|Any CPU.Build.0 = Debug|Any CPU |
|||
{DD712B57-563F-46E4-91D0-7239C60F5AE6}.Release|Any CPU.ActiveCfg = Release|Any CPU |
|||
{DD712B57-563F-46E4-91D0-7239C60F5AE6}.Release|Any CPU.Build.0 = Release|Any CPU |
|||
{7C4EE2EC-8793-4A96-817C-83318C0D5DCD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
|||
{7C4EE2EC-8793-4A96-817C-83318C0D5DCD}.Debug|Any CPU.Build.0 = Debug|Any CPU |
|||
{7C4EE2EC-8793-4A96-817C-83318C0D5DCD}.Release|Any CPU.ActiveCfg = Release|Any CPU |
|||
{7C4EE2EC-8793-4A96-817C-83318C0D5DCD}.Release|Any CPU.Build.0 = Release|Any CPU |
|||
EndGlobalSection |
|||
GlobalSection(SolutionProperties) = preSolution |
|||
HideSolutionNode = FALSE |
|||
EndGlobalSection |
|||
GlobalSection(NestedProjects) = preSolution |
|||
{0960777B-0375-440D-AFD3-CD12F8B67ED2} = {013E1408-EDF4-4394-95E6-AFF0F7E81CAF} |
|||
{E7ACD36D-7BFA-4E31-9E30-855E938A040B} = {013E1408-EDF4-4394-95E6-AFF0F7E81CAF} |
|||
{53DBEDC9-C4CB-4118-ABE4-F2E792BE74BF} = {013E1408-EDF4-4394-95E6-AFF0F7E81CAF} |
|||
{B98CE0C0-AEC1-4FC0-ACE2-6E06C4093444} = {013E1408-EDF4-4394-95E6-AFF0F7E81CAF} |
|||
{EFBB8E00-5B36-440C-AC3D-6095A937D784} = {013E1408-EDF4-4394-95E6-AFF0F7E81CAF} |
|||
{5C109B06-59A5-4B6E-8909-AED8FD7F80E3} = {013E1408-EDF4-4394-95E6-AFF0F7E81CAF} |
|||
{3870F577-A49E-48D1-8CB0-7B73E11CE68D} = {013E1408-EDF4-4394-95E6-AFF0F7E81CAF} |
|||
{81D1D5F8-2CAA-48D4-9AEF-F94F27EB913A} = {B8FE9F89-1CBC-49F8-A888-1600C7A6F60A} |
|||
{4BE100BB-D519-41A9-8265-054A436CDACF} = {B8FE9F89-1CBC-49F8-A888-1600C7A6F60A} |
|||
{B7C25B05-818B-48B6-9919-47BCA07C01BC} = {B8FE9F89-1CBC-49F8-A888-1600C7A6F60A} |
|||
{DD712B57-563F-46E4-91D0-7239C60F5AE6} = {DB7C4A00-8538-4C69-BC14-6D680A22287E} |
|||
{7C4EE2EC-8793-4A96-817C-83318C0D5DCD} = {B8FE9F89-1CBC-49F8-A888-1600C7A6F60A} |
|||
EndGlobalSection |
|||
GlobalSection(ExtensibilityGlobals) = postSolution |
|||
SolutionGuid = {9FB64593-B84A-4E0E-94F4-756EE90A01E8} |
|||
EndGlobalSection |
|||
EndGlobal |
|||
@ -0,0 +1,10 @@ |
|||
namespace Lion.AbpPro.LanguageManagement.Controllers |
|||
{ |
|||
public class HomeController : AbpController |
|||
{ |
|||
public ActionResult Index() |
|||
{ |
|||
return Redirect("~/swagger"); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,18 @@ |
|||
FROM mcr.microsoft.com/dotnet/core/aspnet:3.0-buster-slim AS base |
|||
WORKDIR /app |
|||
EXPOSE 80 |
|||
|
|||
FROM mcr.microsoft.com/dotnet/core/sdk:3.0-buster AS build |
|||
WORKDIR /src |
|||
COPY . . |
|||
WORKDIR /src/templates/service/host/Lion.AbpPro.LanguageManagement.HttpApi.Host |
|||
RUN dotnet restore -nowarn:msb3202,nu1503 |
|||
RUN dotnet build --no-restore -c Release -o /app |
|||
|
|||
FROM build AS publish |
|||
RUN dotnet publish --no-restore -c Release -o /app |
|||
|
|||
FROM base AS final |
|||
WORKDIR /app |
|||
COPY --from=publish /app . |
|||
ENTRYPOINT ["dotnet", "Lion.AbpPro.LanguageManagement.HttpApi.Host.dll"] |
|||
@ -0,0 +1,18 @@ |
|||
namespace Lion.AbpPro.LanguageManagement.EntityFrameworkCore |
|||
{ |
|||
public class LanguageManagementHttpApiHostMigrationsDbContext : AbpDbContext<LanguageManagementHttpApiHostMigrationsDbContext> |
|||
{ |
|||
public LanguageManagementHttpApiHostMigrationsDbContext(DbContextOptions<LanguageManagementHttpApiHostMigrationsDbContext> options) |
|||
: base(options) |
|||
{ |
|||
|
|||
} |
|||
|
|||
protected override void OnModelCreating(ModelBuilder modelBuilder) |
|||
{ |
|||
base.OnModelCreating(modelBuilder); |
|||
|
|||
modelBuilder.ConfigureLanguageManagement(); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,23 @@ |
|||
namespace Lion.AbpPro.LanguageManagement.EntityFrameworkCore |
|||
{ |
|||
public class LanguageManagementHttpApiHostMigrationsDbContextFactory : IDesignTimeDbContextFactory<LanguageManagementHttpApiHostMigrationsDbContext> |
|||
{ |
|||
public LanguageManagementHttpApiHostMigrationsDbContext CreateDbContext(string[] args) |
|||
{ |
|||
var configuration = BuildConfiguration(); |
|||
|
|||
var builder = new DbContextOptionsBuilder<LanguageManagementHttpApiHostMigrationsDbContext>() |
|||
.UseMySql(configuration.GetConnectionString("LanguageManagement"), MySqlServerVersion.LatestSupportedServerVersion); |
|||
return new LanguageManagementHttpApiHostMigrationsDbContext(builder.Options); |
|||
} |
|||
|
|||
private static IConfigurationRoot BuildConfiguration() |
|||
{ |
|||
var builder = new ConfigurationBuilder() |
|||
.SetBasePath(Directory.GetCurrentDirectory()) |
|||
.AddJsonFile("appsettings.json", optional: false); |
|||
|
|||
return builder.Build(); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,3 @@ |
|||
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd"> |
|||
<ConfigureAwait ContinueOnCapturedContext="false" /> |
|||
</Weavers> |
|||
@ -0,0 +1,30 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> |
|||
<!-- This file was generated by Fody. Manual changes to this file will be lost when your project is rebuilt. --> |
|||
<xs:element name="Weavers"> |
|||
<xs:complexType> |
|||
<xs:all> |
|||
<xs:element name="ConfigureAwait" minOccurs="0" maxOccurs="1"> |
|||
<xs:complexType> |
|||
<xs:attribute name="ContinueOnCapturedContext" type="xs:boolean" /> |
|||
</xs:complexType> |
|||
</xs:element> |
|||
</xs:all> |
|||
<xs:attribute name="VerifyAssembly" type="xs:boolean"> |
|||
<xs:annotation> |
|||
<xs:documentation>'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed.</xs:documentation> |
|||
</xs:annotation> |
|||
</xs:attribute> |
|||
<xs:attribute name="VerifyIgnoreCodes" type="xs:string"> |
|||
<xs:annotation> |
|||
<xs:documentation>A comma-separated list of error codes that can be safely ignored in assembly verification.</xs:documentation> |
|||
</xs:annotation> |
|||
</xs:attribute> |
|||
<xs:attribute name="GenerateXsd" type="xs:boolean"> |
|||
<xs:annotation> |
|||
<xs:documentation>'false' to turn off automatic generation of the XML Schema file.</xs:documentation> |
|||
</xs:annotation> |
|||
</xs:attribute> |
|||
</xs:complexType> |
|||
</xs:element> |
|||
</xs:schema> |
|||
@ -0,0 +1,39 @@ |
|||
// Global using directives
|
|||
|
|||
global using System; |
|||
global using System.Collections.Generic; |
|||
global using System.IO; |
|||
global using System.Linq; |
|||
global using Lion.AbpPro.LanguageManagement.EntityFrameworkCore; |
|||
global using Microsoft.AspNetCore.Authentication.JwtBearer; |
|||
global using Microsoft.AspNetCore.Builder; |
|||
global using Microsoft.AspNetCore.Cors; |
|||
global using Microsoft.AspNetCore.DataProtection; |
|||
global using Microsoft.AspNetCore.Hosting; |
|||
global using Microsoft.AspNetCore.Mvc; |
|||
global using Microsoft.EntityFrameworkCore; |
|||
global using Microsoft.EntityFrameworkCore.Design; |
|||
global using Microsoft.Extensions.Configuration; |
|||
global using Microsoft.Extensions.DependencyInjection; |
|||
global using Microsoft.Extensions.Hosting; |
|||
global using Microsoft.OpenApi.Models; |
|||
global using Serilog; |
|||
global using Serilog.Events; |
|||
global using StackExchange.Redis; |
|||
global using Volo.Abp; |
|||
global using Volo.Abp.AspNetCore.Mvc; |
|||
global using Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy; |
|||
global using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared; |
|||
global using Volo.Abp.AspNetCore.Serilog; |
|||
global using Volo.Abp.AuditLogging.EntityFrameworkCore; |
|||
global using Volo.Abp.Autofac; |
|||
global using Volo.Abp.Caching; |
|||
global using Volo.Abp.Caching.StackExchangeRedis; |
|||
global using Volo.Abp.EntityFrameworkCore; |
|||
global using Volo.Abp.EntityFrameworkCore.MySQL; |
|||
global using Volo.Abp.Localization; |
|||
global using Volo.Abp.Modularity; |
|||
global using Volo.Abp.PermissionManagement.EntityFrameworkCore; |
|||
global using Volo.Abp.SettingManagement.EntityFrameworkCore; |
|||
global using Volo.Abp.Swashbuckle; |
|||
global using Volo.Abp.VirtualFileSystem; |
|||
@ -0,0 +1,194 @@ |
|||
namespace Lion.AbpPro.LanguageManagement |
|||
{ |
|||
[DependsOn( |
|||
typeof(LanguageManagementApplicationModule), |
|||
typeof(LanguageManagementEntityFrameworkCoreModule), |
|||
typeof(LanguageManagementHttpApiModule), |
|||
typeof(AbpAspNetCoreMvcUiMultiTenancyModule), |
|||
typeof(AbpAutofacModule), |
|||
typeof(AbpCachingStackExchangeRedisModule), |
|||
typeof(AbpEntityFrameworkCoreMySQLModule), |
|||
typeof(AbpAuditLoggingEntityFrameworkCoreModule), |
|||
typeof(AbpPermissionManagementEntityFrameworkCoreModule), |
|||
typeof(AbpSettingManagementEntityFrameworkCoreModule), |
|||
typeof(AbpAspNetCoreSerilogModule), |
|||
typeof(AbpSwashbuckleModule) |
|||
)] |
|||
public class LanguageManagementHttpApiHostModule : AbpModule |
|||
{ |
|||
private const string DefaultCorsPolicyName = "Default"; |
|||
|
|||
public override void ConfigureServices(ServiceConfigurationContext context) |
|||
{ |
|||
context.Services.AddAlwaysAllowAuthorization(); |
|||
ConfigureSwaggerServices(context); |
|||
ConfigureCache(context); |
|||
ConfigureCors(context); |
|||
ConfigureDB(); |
|||
ConfigureLocalization(); |
|||
ConfigureVirtualFileSystem(context); |
|||
} |
|||
|
|||
public override void OnApplicationInitialization(ApplicationInitializationContext context) |
|||
{ |
|||
var app = context.GetApplicationBuilder(); |
|||
var env = context.GetEnvironment(); |
|||
|
|||
if (env.IsDevelopment()) |
|||
{ |
|||
app.UseDeveloperExceptionPage(); |
|||
} |
|||
else |
|||
{ |
|||
app.UseErrorPage(); |
|||
app.UseHsts(); |
|||
} |
|||
|
|||
app.UseHttpsRedirection(); |
|||
app.UseCorrelationId(); |
|||
app.UseStaticFiles(); |
|||
app.UseRouting(); |
|||
app.UseCors(DefaultCorsPolicyName); |
|||
app.UseAuthentication(); |
|||
app.UseAbpRequestLocalization(); |
|||
app.UseAuthorization(); |
|||
app.UseSwagger(); |
|||
app.UseAbpSwaggerUI(options => |
|||
{ |
|||
options.SwaggerEndpoint("/swagger/v1/swagger.json", "Support APP API"); |
|||
|
|||
var configuration = context.GetConfiguration(); |
|||
options.OAuthClientId(configuration["AuthServer:SwaggerClientId"]); |
|||
options.OAuthClientSecret(configuration["AuthServer:SwaggerClientSecret"]); |
|||
options.OAuthScopes("LanguageManagement"); |
|||
}); |
|||
app.UseAuditing(); |
|||
app.UseAbpSerilogEnrichers(); |
|||
app.UseConfiguredEndpoints(); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 配置跨域
|
|||
/// </summary>
|
|||
/// <param name="context"></param>
|
|||
private void ConfigureCors(ServiceConfigurationContext context) |
|||
{ |
|||
var configuration = context.Services.GetConfiguration(); |
|||
context.Services.AddCors(options => |
|||
{ |
|||
options.AddPolicy(DefaultCorsPolicyName, builder => |
|||
{ |
|||
builder |
|||
.WithOrigins( |
|||
configuration["App:CorsOrigins"] |
|||
.Split(",", StringSplitOptions.RemoveEmptyEntries) |
|||
.Select(o => o.RemovePostFix("/")) |
|||
.ToArray() |
|||
) |
|||
.WithAbpExposedHeaders() |
|||
.SetIsOriginAllowedToAllowWildcardSubdomains() |
|||
.AllowAnyHeader() |
|||
.AllowAnyMethod() |
|||
.AllowCredentials(); |
|||
}); |
|||
}); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 配置SwaggerUI
|
|||
/// </summary>
|
|||
/// <param name="context"></param>
|
|||
private static void ConfigureSwaggerServices(ServiceConfigurationContext context) |
|||
{ |
|||
context.Services.AddSwaggerGen( |
|||
options => |
|||
{ |
|||
options.SwaggerDoc("v1", new OpenApiInfo {Title = "LanguageManagement API", Version = "v1"}); |
|||
|
|||
options.DocInclusionPredicate((docName, description) => true); |
|||
|
|||
#region 添加token
|
|||
|
|||
options.AddSecurityDefinition(JwtBearerDefaults.AuthenticationScheme, new OpenApiSecurityScheme() |
|||
{ |
|||
Description = "请输入Token", |
|||
Name = "Authorization", |
|||
In = ParameterLocation.Header, |
|||
Type = SecuritySchemeType.Http, |
|||
Scheme = JwtBearerDefaults.AuthenticationScheme, |
|||
BearerFormat = "JWT" |
|||
}); |
|||
options.AddSecurityRequirement(new OpenApiSecurityRequirement |
|||
{ |
|||
{ |
|||
new OpenApiSecurityScheme |
|||
{ |
|||
Reference = new OpenApiReference |
|||
{ |
|||
Type = ReferenceType.SecurityScheme, Id = "Bearer" |
|||
} |
|||
}, |
|||
new List<string>() |
|||
} |
|||
}); |
|||
|
|||
#endregion
|
|||
}); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Redis缓存
|
|||
/// </summary>
|
|||
/// <param name="context"></param>
|
|||
private void ConfigureCache(ServiceConfigurationContext context) |
|||
{ |
|||
var hostingEnvironment = context.Services.GetHostingEnvironment(); |
|||
var configuration = context.Services.GetConfiguration(); |
|||
Configure<AbpDistributedCacheOptions>(options => { options.KeyPrefix = "LanguageManagement:"; }); |
|||
|
|||
if (!hostingEnvironment.IsDevelopment()) |
|||
{ |
|||
var redis = ConnectionMultiplexer.Connect(configuration["Redis:Configuration"]); |
|||
context.Services |
|||
.AddDataProtection() |
|||
.PersistKeysToStackExchangeRedis(redis, "LanguageManagement-Protection-Keys"); |
|||
} |
|||
} |
|||
|
|||
private void ConfigureDB() |
|||
{ |
|||
Configure<AbpDbContextOptions>(options => { options.UseMySQL(); }); |
|||
} |
|||
|
|||
/// <summary>
|
|||
///配置本地化
|
|||
/// </summary>
|
|||
private void ConfigureLocalization() |
|||
{ |
|||
Configure<AbpLocalizationOptions>(options => |
|||
{ |
|||
options.Languages.Add(new LanguageInfo("cs", "cs", "Čeština")); |
|||
options.Languages.Add(new LanguageInfo("en", "en", "English")); |
|||
options.Languages.Add(new LanguageInfo("en-GB", "en-GB", "English (UK)")); |
|||
options.Languages.Add(new LanguageInfo("fr", "fr", "Français")); |
|||
options.Languages.Add(new LanguageInfo("hu", "hu", "Magyar")); |
|||
options.Languages.Add(new LanguageInfo("pt-BR", "pt-BR", "Português")); |
|||
options.Languages.Add(new LanguageInfo("ru", "ru", "Русский")); |
|||
options.Languages.Add(new LanguageInfo("tr", "tr", "Türkçe")); |
|||
options.Languages.Add(new LanguageInfo("zh-Hans", "zh-Hans", "简体中文")); |
|||
options.Languages.Add(new LanguageInfo("zh-Hant", "zh-Hant", "繁體中文")); |
|||
}); |
|||
} |
|||
/// <summary>
|
|||
/// 配置虚拟文件系统
|
|||
/// </summary>
|
|||
/// <param name="context"></param>
|
|||
private void ConfigureVirtualFileSystem(ServiceConfigurationContext context) |
|||
{ |
|||
Configure<AbpVirtualFileSystemOptions>(options => |
|||
{ |
|||
options.FileSets.AddEmbedded<LanguageManagementHttpApiHostModule>(); |
|||
}); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,41 @@ |
|||
<Project Sdk="Microsoft.NET.Sdk.Web"> |
|||
|
|||
|
|||
<PropertyGroup> |
|||
<TargetFramework>net7.0</TargetFramework> |
|||
<RootNamespace>Lion.AbpPro.LanguageManagement</RootNamespace> |
|||
<PreserveCompilationReferences>true</PreserveCompilationReferences> |
|||
<UserSecretsId>Lion.AbpPro.LanguageManagement-c2d31439-b723-48e2-b061-5ebd7aeb6010</UserSecretsId> |
|||
</PropertyGroup> |
|||
|
|||
<ItemGroup> |
|||
<PackageReference Include="Serilog.AspNetCore" /> |
|||
<PackageReference Include="Serilog.Sinks.Async" /> |
|||
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" /> |
|||
<PackageReference Include="Microsoft.AspNetCore.DataProtection.StackExchangeRedis" /> |
|||
<PackageReference Include="Volo.Abp.Autofac" /> |
|||
<PackageReference Include="Volo.Abp.Caching.StackExchangeRedis" /> |
|||
<PackageReference Include="Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy" /> |
|||
<PackageReference Include="Volo.Abp.EntityFrameworkCore.MySQL" /> |
|||
<PackageReference Include="Volo.Abp.AspNetCore.Serilog" /> |
|||
<PackageReference Include="Volo.Abp.Swashbuckle" /> |
|||
<PackageReference Include="Volo.Abp.PermissionManagement.EntityFrameworkCore" /> |
|||
<PackageReference Include="Volo.Abp.SettingManagement.EntityFrameworkCore" /> |
|||
<PackageReference Include="Volo.Abp.AuditLogging.EntityFrameworkCore" /> |
|||
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" /> |
|||
</ItemGroup> |
|||
|
|||
<ItemGroup> |
|||
<ProjectReference Include="..\..\src\Lion.AbpPro.LanguageManagement.HttpApi\Lion.AbpPro.LanguageManagement.HttpApi.csproj" /> |
|||
<ProjectReference Include="..\..\src\Lion.AbpPro.LanguageManagement.Application\Lion.AbpPro.LanguageManagement.Application.csproj" /> |
|||
<ProjectReference Include="..\..\src\Lion.AbpPro.LanguageManagement.EntityFrameworkCore\Lion.AbpPro.LanguageManagement.EntityFrameworkCore.csproj" /> |
|||
</ItemGroup> |
|||
|
|||
<ItemGroup> |
|||
<Compile Remove="Logs\**" /> |
|||
<Content Remove="Logs\**" /> |
|||
<EmbeddedResource Remove="Logs\**" /> |
|||
<None Remove="Logs\**" /> |
|||
</ItemGroup> |
|||
|
|||
</Project> |
|||
@ -0,0 +1,187 @@ |
|||
// <auto-generated />
|
|||
using System; |
|||
using Lion.AbpPro.LanguageManagement.EntityFrameworkCore; |
|||
using Microsoft.EntityFrameworkCore; |
|||
using Microsoft.EntityFrameworkCore.Infrastructure; |
|||
using Microsoft.EntityFrameworkCore.Migrations; |
|||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion; |
|||
using Volo.Abp.EntityFrameworkCore; |
|||
|
|||
#nullable disable |
|||
|
|||
namespace Lion.AbpPro.LanguageManagement.Migrations |
|||
{ |
|||
[DbContext(typeof(LanguageManagementHttpApiHostMigrationsDbContext))] |
|||
[Migration("20230318020647_Init")] |
|||
partial class Init |
|||
{ |
|||
/// <inheritdoc />
|
|||
protected override void BuildTargetModel(ModelBuilder modelBuilder) |
|||
{ |
|||
#pragma warning disable 612, 618
|
|||
modelBuilder |
|||
.HasAnnotation("_Abp_DatabaseProvider", EfCoreDatabaseProvider.MySql) |
|||
.HasAnnotation("ProductVersion", "7.0.2") |
|||
.HasAnnotation("Relational:MaxIdentifierLength", 64); |
|||
|
|||
modelBuilder.Entity("Lion.AbpPro.LanguageManagement.LanguageTexts.Aggregates.LanguageText", b => |
|||
{ |
|||
b.Property<Guid>("Id") |
|||
.ValueGeneratedOnAdd() |
|||
.HasColumnType("char(36)"); |
|||
|
|||
b.Property<string>("ConcurrencyStamp") |
|||
.IsConcurrencyToken() |
|||
.HasMaxLength(40) |
|||
.HasColumnType("varchar(40)") |
|||
.HasColumnName("ConcurrencyStamp"); |
|||
|
|||
b.Property<DateTime>("CreationTime") |
|||
.HasColumnType("datetime(6)") |
|||
.HasColumnName("CreationTime"); |
|||
|
|||
b.Property<Guid?>("CreatorId") |
|||
.HasColumnType("char(36)") |
|||
.HasColumnName("CreatorId"); |
|||
|
|||
b.Property<string>("CultureName") |
|||
.IsRequired() |
|||
.HasMaxLength(128) |
|||
.HasColumnType("varchar(128)") |
|||
.HasComment("语言名称"); |
|||
|
|||
b.Property<Guid?>("DeleterId") |
|||
.HasColumnType("char(36)") |
|||
.HasColumnName("DeleterId"); |
|||
|
|||
b.Property<DateTime?>("DeletionTime") |
|||
.HasColumnType("datetime(6)") |
|||
.HasColumnName("DeletionTime"); |
|||
|
|||
b.Property<string>("ExtraProperties") |
|||
.HasColumnType("longtext") |
|||
.HasColumnName("ExtraProperties"); |
|||
|
|||
b.Property<bool>("IsDeleted") |
|||
.ValueGeneratedOnAdd() |
|||
.HasColumnType("tinyint(1)") |
|||
.HasDefaultValue(false) |
|||
.HasColumnName("IsDeleted"); |
|||
|
|||
b.Property<DateTime?>("LastModificationTime") |
|||
.HasColumnType("datetime(6)") |
|||
.HasColumnName("LastModificationTime"); |
|||
|
|||
b.Property<Guid?>("LastModifierId") |
|||
.HasColumnType("char(36)") |
|||
.HasColumnName("LastModifierId"); |
|||
|
|||
b.Property<string>("Name") |
|||
.IsRequired() |
|||
.HasMaxLength(256) |
|||
.HasColumnType("varchar(256)") |
|||
.HasComment("名称"); |
|||
|
|||
b.Property<string>("ResourceName") |
|||
.IsRequired() |
|||
.HasMaxLength(128) |
|||
.HasColumnType("varchar(128)") |
|||
.HasComment("资源名称"); |
|||
|
|||
b.Property<Guid?>("TenantId") |
|||
.HasColumnType("char(36)") |
|||
.HasColumnName("TenantId"); |
|||
|
|||
b.Property<string>("Value") |
|||
.IsRequired() |
|||
.HasMaxLength(256) |
|||
.HasColumnType("varchar(256)") |
|||
.HasComment("值"); |
|||
|
|||
b.HasKey("Id"); |
|||
|
|||
b.HasIndex("TenantId", "ResourceName", "CultureName"); |
|||
|
|||
b.ToTable("AbpLanguageTexts", (string)null); |
|||
}); |
|||
|
|||
modelBuilder.Entity("Lion.AbpPro.LanguageManagement.Languages.Aggregates.Language", b => |
|||
{ |
|||
b.Property<Guid>("Id") |
|||
.ValueGeneratedOnAdd() |
|||
.HasColumnType("char(36)"); |
|||
|
|||
b.Property<string>("ConcurrencyStamp") |
|||
.IsConcurrencyToken() |
|||
.HasMaxLength(40) |
|||
.HasColumnType("varchar(40)") |
|||
.HasColumnName("ConcurrencyStamp"); |
|||
|
|||
b.Property<DateTime>("CreationTime") |
|||
.HasColumnType("datetime(6)") |
|||
.HasColumnName("CreationTime"); |
|||
|
|||
b.Property<Guid?>("CreatorId") |
|||
.HasColumnType("char(36)") |
|||
.HasColumnName("CreatorId"); |
|||
|
|||
b.Property<string>("CultureName") |
|||
.IsRequired() |
|||
.HasMaxLength(128) |
|||
.HasColumnType("varchar(128)") |
|||
.HasComment("语言名称"); |
|||
|
|||
b.Property<Guid?>("DeleterId") |
|||
.HasColumnType("char(36)") |
|||
.HasColumnName("DeleterId"); |
|||
|
|||
b.Property<DateTime?>("DeletionTime") |
|||
.HasColumnType("datetime(6)") |
|||
.HasColumnName("DeletionTime"); |
|||
|
|||
b.Property<string>("DisplayName") |
|||
.IsRequired() |
|||
.HasMaxLength(128) |
|||
.HasColumnType("varchar(128)") |
|||
.HasComment("显示名称"); |
|||
|
|||
b.Property<string>("ExtraProperties") |
|||
.HasColumnType("longtext") |
|||
.HasColumnName("ExtraProperties"); |
|||
|
|||
b.Property<string>("FlagIcon") |
|||
.IsRequired() |
|||
.HasColumnType("longtext") |
|||
.HasComment("图标"); |
|||
|
|||
b.Property<bool>("IsDeleted") |
|||
.ValueGeneratedOnAdd() |
|||
.HasColumnType("tinyint(1)") |
|||
.HasDefaultValue(false) |
|||
.HasColumnName("IsDeleted"); |
|||
|
|||
b.Property<bool>("IsEnabled") |
|||
.HasColumnType("tinyint(1)"); |
|||
|
|||
b.Property<DateTime?>("LastModificationTime") |
|||
.HasColumnType("datetime(6)") |
|||
.HasColumnName("LastModificationTime"); |
|||
|
|||
b.Property<Guid?>("LastModifierId") |
|||
.HasColumnType("char(36)") |
|||
.HasColumnName("LastModifierId"); |
|||
|
|||
b.Property<string>("UiCultureName") |
|||
.IsRequired() |
|||
.HasMaxLength(128) |
|||
.HasColumnType("varchar(128)") |
|||
.HasComment("Ui语言名称"); |
|||
|
|||
b.HasKey("Id"); |
|||
|
|||
b.ToTable("AbpLanguages", (string)null); |
|||
}); |
|||
#pragma warning restore 612, 618
|
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,97 @@ |
|||
using System; |
|||
using Microsoft.EntityFrameworkCore.Migrations; |
|||
|
|||
#nullable disable |
|||
|
|||
namespace Lion.AbpPro.LanguageManagement.Migrations |
|||
{ |
|||
/// <inheritdoc />
|
|||
public partial class Init : Migration |
|||
{ |
|||
/// <inheritdoc />
|
|||
protected override void Up(MigrationBuilder migrationBuilder) |
|||
{ |
|||
migrationBuilder.AlterDatabase() |
|||
.Annotation("MySql:CharSet", "utf8mb4"); |
|||
|
|||
migrationBuilder.CreateTable( |
|||
name: "AbpLanguages", |
|||
columns: table => new |
|||
{ |
|||
Id = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci"), |
|||
CultureName = table.Column<string>(type: "varchar(128)", maxLength: 128, nullable: false, comment: "语言名称") |
|||
.Annotation("MySql:CharSet", "utf8mb4"), |
|||
UiCultureName = table.Column<string>(type: "varchar(128)", maxLength: 128, nullable: false, comment: "Ui语言名称") |
|||
.Annotation("MySql:CharSet", "utf8mb4"), |
|||
DisplayName = table.Column<string>(type: "varchar(128)", maxLength: 128, nullable: false, comment: "显示名称") |
|||
.Annotation("MySql:CharSet", "utf8mb4"), |
|||
FlagIcon = table.Column<string>(type: "longtext", nullable: false, comment: "图标") |
|||
.Annotation("MySql:CharSet", "utf8mb4"), |
|||
IsEnabled = table.Column<bool>(type: "tinyint(1)", nullable: false), |
|||
ExtraProperties = table.Column<string>(type: "longtext", nullable: true) |
|||
.Annotation("MySql:CharSet", "utf8mb4"), |
|||
ConcurrencyStamp = table.Column<string>(type: "varchar(40)", maxLength: 40, nullable: true) |
|||
.Annotation("MySql:CharSet", "utf8mb4"), |
|||
CreationTime = table.Column<DateTime>(type: "datetime(6)", nullable: false), |
|||
CreatorId = table.Column<Guid>(type: "char(36)", nullable: true, collation: "ascii_general_ci"), |
|||
LastModificationTime = table.Column<DateTime>(type: "datetime(6)", nullable: true), |
|||
LastModifierId = table.Column<Guid>(type: "char(36)", nullable: true, collation: "ascii_general_ci"), |
|||
IsDeleted = table.Column<bool>(type: "tinyint(1)", nullable: false, defaultValue: false), |
|||
DeleterId = table.Column<Guid>(type: "char(36)", nullable: true, collation: "ascii_general_ci"), |
|||
DeletionTime = table.Column<DateTime>(type: "datetime(6)", nullable: true) |
|||
}, |
|||
constraints: table => |
|||
{ |
|||
table.PrimaryKey("PK_AbpLanguages", x => x.Id); |
|||
}) |
|||
.Annotation("MySql:CharSet", "utf8mb4"); |
|||
|
|||
migrationBuilder.CreateTable( |
|||
name: "AbpLanguageTexts", |
|||
columns: table => new |
|||
{ |
|||
Id = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci"), |
|||
TenantId = table.Column<Guid>(type: "char(36)", nullable: true, collation: "ascii_general_ci"), |
|||
ResourceName = table.Column<string>(type: "varchar(128)", maxLength: 128, nullable: false, comment: "资源名称") |
|||
.Annotation("MySql:CharSet", "utf8mb4"), |
|||
CultureName = table.Column<string>(type: "varchar(128)", maxLength: 128, nullable: false, comment: "语言名称") |
|||
.Annotation("MySql:CharSet", "utf8mb4"), |
|||
Name = table.Column<string>(type: "varchar(256)", maxLength: 256, nullable: false, comment: "名称") |
|||
.Annotation("MySql:CharSet", "utf8mb4"), |
|||
Value = table.Column<string>(type: "varchar(256)", maxLength: 256, nullable: false, comment: "值") |
|||
.Annotation("MySql:CharSet", "utf8mb4"), |
|||
ExtraProperties = table.Column<string>(type: "longtext", nullable: true) |
|||
.Annotation("MySql:CharSet", "utf8mb4"), |
|||
ConcurrencyStamp = table.Column<string>(type: "varchar(40)", maxLength: 40, nullable: true) |
|||
.Annotation("MySql:CharSet", "utf8mb4"), |
|||
CreationTime = table.Column<DateTime>(type: "datetime(6)", nullable: false), |
|||
CreatorId = table.Column<Guid>(type: "char(36)", nullable: true, collation: "ascii_general_ci"), |
|||
LastModificationTime = table.Column<DateTime>(type: "datetime(6)", nullable: true), |
|||
LastModifierId = table.Column<Guid>(type: "char(36)", nullable: true, collation: "ascii_general_ci"), |
|||
IsDeleted = table.Column<bool>(type: "tinyint(1)", nullable: false, defaultValue: false), |
|||
DeleterId = table.Column<Guid>(type: "char(36)", nullable: true, collation: "ascii_general_ci"), |
|||
DeletionTime = table.Column<DateTime>(type: "datetime(6)", nullable: true) |
|||
}, |
|||
constraints: table => |
|||
{ |
|||
table.PrimaryKey("PK_AbpLanguageTexts", x => x.Id); |
|||
}) |
|||
.Annotation("MySql:CharSet", "utf8mb4"); |
|||
|
|||
migrationBuilder.CreateIndex( |
|||
name: "IX_AbpLanguageTexts_TenantId_ResourceName_CultureName", |
|||
table: "AbpLanguageTexts", |
|||
columns: new[] { "TenantId", "ResourceName", "CultureName" }); |
|||
} |
|||
|
|||
/// <inheritdoc />
|
|||
protected override void Down(MigrationBuilder migrationBuilder) |
|||
{ |
|||
migrationBuilder.DropTable( |
|||
name: "AbpLanguages"); |
|||
|
|||
migrationBuilder.DropTable( |
|||
name: "AbpLanguageTexts"); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,184 @@ |
|||
// <auto-generated />
|
|||
using System; |
|||
using Lion.AbpPro.LanguageManagement.EntityFrameworkCore; |
|||
using Microsoft.EntityFrameworkCore; |
|||
using Microsoft.EntityFrameworkCore.Infrastructure; |
|||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion; |
|||
using Volo.Abp.EntityFrameworkCore; |
|||
|
|||
#nullable disable |
|||
|
|||
namespace Lion.AbpPro.LanguageManagement.Migrations |
|||
{ |
|||
[DbContext(typeof(LanguageManagementHttpApiHostMigrationsDbContext))] |
|||
partial class LanguageManagementHttpApiHostMigrationsDbContextModelSnapshot : ModelSnapshot |
|||
{ |
|||
protected override void BuildModel(ModelBuilder modelBuilder) |
|||
{ |
|||
#pragma warning disable 612, 618
|
|||
modelBuilder |
|||
.HasAnnotation("_Abp_DatabaseProvider", EfCoreDatabaseProvider.MySql) |
|||
.HasAnnotation("ProductVersion", "7.0.2") |
|||
.HasAnnotation("Relational:MaxIdentifierLength", 64); |
|||
|
|||
modelBuilder.Entity("Lion.AbpPro.LanguageManagement.LanguageTexts.Aggregates.LanguageText", b => |
|||
{ |
|||
b.Property<Guid>("Id") |
|||
.ValueGeneratedOnAdd() |
|||
.HasColumnType("char(36)"); |
|||
|
|||
b.Property<string>("ConcurrencyStamp") |
|||
.IsConcurrencyToken() |
|||
.HasMaxLength(40) |
|||
.HasColumnType("varchar(40)") |
|||
.HasColumnName("ConcurrencyStamp"); |
|||
|
|||
b.Property<DateTime>("CreationTime") |
|||
.HasColumnType("datetime(6)") |
|||
.HasColumnName("CreationTime"); |
|||
|
|||
b.Property<Guid?>("CreatorId") |
|||
.HasColumnType("char(36)") |
|||
.HasColumnName("CreatorId"); |
|||
|
|||
b.Property<string>("CultureName") |
|||
.IsRequired() |
|||
.HasMaxLength(128) |
|||
.HasColumnType("varchar(128)") |
|||
.HasComment("语言名称"); |
|||
|
|||
b.Property<Guid?>("DeleterId") |
|||
.HasColumnType("char(36)") |
|||
.HasColumnName("DeleterId"); |
|||
|
|||
b.Property<DateTime?>("DeletionTime") |
|||
.HasColumnType("datetime(6)") |
|||
.HasColumnName("DeletionTime"); |
|||
|
|||
b.Property<string>("ExtraProperties") |
|||
.HasColumnType("longtext") |
|||
.HasColumnName("ExtraProperties"); |
|||
|
|||
b.Property<bool>("IsDeleted") |
|||
.ValueGeneratedOnAdd() |
|||
.HasColumnType("tinyint(1)") |
|||
.HasDefaultValue(false) |
|||
.HasColumnName("IsDeleted"); |
|||
|
|||
b.Property<DateTime?>("LastModificationTime") |
|||
.HasColumnType("datetime(6)") |
|||
.HasColumnName("LastModificationTime"); |
|||
|
|||
b.Property<Guid?>("LastModifierId") |
|||
.HasColumnType("char(36)") |
|||
.HasColumnName("LastModifierId"); |
|||
|
|||
b.Property<string>("Name") |
|||
.IsRequired() |
|||
.HasMaxLength(256) |
|||
.HasColumnType("varchar(256)") |
|||
.HasComment("名称"); |
|||
|
|||
b.Property<string>("ResourceName") |
|||
.IsRequired() |
|||
.HasMaxLength(128) |
|||
.HasColumnType("varchar(128)") |
|||
.HasComment("资源名称"); |
|||
|
|||
b.Property<Guid?>("TenantId") |
|||
.HasColumnType("char(36)") |
|||
.HasColumnName("TenantId"); |
|||
|
|||
b.Property<string>("Value") |
|||
.IsRequired() |
|||
.HasMaxLength(256) |
|||
.HasColumnType("varchar(256)") |
|||
.HasComment("值"); |
|||
|
|||
b.HasKey("Id"); |
|||
|
|||
b.HasIndex("TenantId", "ResourceName", "CultureName"); |
|||
|
|||
b.ToTable("AbpLanguageTexts", (string)null); |
|||
}); |
|||
|
|||
modelBuilder.Entity("Lion.AbpPro.LanguageManagement.Languages.Aggregates.Language", b => |
|||
{ |
|||
b.Property<Guid>("Id") |
|||
.ValueGeneratedOnAdd() |
|||
.HasColumnType("char(36)"); |
|||
|
|||
b.Property<string>("ConcurrencyStamp") |
|||
.IsConcurrencyToken() |
|||
.HasMaxLength(40) |
|||
.HasColumnType("varchar(40)") |
|||
.HasColumnName("ConcurrencyStamp"); |
|||
|
|||
b.Property<DateTime>("CreationTime") |
|||
.HasColumnType("datetime(6)") |
|||
.HasColumnName("CreationTime"); |
|||
|
|||
b.Property<Guid?>("CreatorId") |
|||
.HasColumnType("char(36)") |
|||
.HasColumnName("CreatorId"); |
|||
|
|||
b.Property<string>("CultureName") |
|||
.IsRequired() |
|||
.HasMaxLength(128) |
|||
.HasColumnType("varchar(128)") |
|||
.HasComment("语言名称"); |
|||
|
|||
b.Property<Guid?>("DeleterId") |
|||
.HasColumnType("char(36)") |
|||
.HasColumnName("DeleterId"); |
|||
|
|||
b.Property<DateTime?>("DeletionTime") |
|||
.HasColumnType("datetime(6)") |
|||
.HasColumnName("DeletionTime"); |
|||
|
|||
b.Property<string>("DisplayName") |
|||
.IsRequired() |
|||
.HasMaxLength(128) |
|||
.HasColumnType("varchar(128)") |
|||
.HasComment("显示名称"); |
|||
|
|||
b.Property<string>("ExtraProperties") |
|||
.HasColumnType("longtext") |
|||
.HasColumnName("ExtraProperties"); |
|||
|
|||
b.Property<string>("FlagIcon") |
|||
.IsRequired() |
|||
.HasColumnType("longtext") |
|||
.HasComment("图标"); |
|||
|
|||
b.Property<bool>("IsDeleted") |
|||
.ValueGeneratedOnAdd() |
|||
.HasColumnType("tinyint(1)") |
|||
.HasDefaultValue(false) |
|||
.HasColumnName("IsDeleted"); |
|||
|
|||
b.Property<bool>("IsEnabled") |
|||
.HasColumnType("tinyint(1)"); |
|||
|
|||
b.Property<DateTime?>("LastModificationTime") |
|||
.HasColumnType("datetime(6)") |
|||
.HasColumnName("LastModificationTime"); |
|||
|
|||
b.Property<Guid?>("LastModifierId") |
|||
.HasColumnType("char(36)") |
|||
.HasColumnName("LastModifierId"); |
|||
|
|||
b.Property<string>("UiCultureName") |
|||
.IsRequired() |
|||
.HasMaxLength(128) |
|||
.HasColumnType("varchar(128)") |
|||
.HasComment("Ui语言名称"); |
|||
|
|||
b.HasKey("Id"); |
|||
|
|||
b.ToTable("AbpLanguages", (string)null); |
|||
}); |
|||
#pragma warning restore 612, 618
|
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,47 @@ |
|||
namespace Lion.AbpPro.LanguageManagement |
|||
{ |
|||
public class Program |
|||
{ |
|||
public static int Main(string[] args) |
|||
{ |
|||
Log.Logger = new LoggerConfiguration() |
|||
#if DEBUG
|
|||
.MinimumLevel.Debug() |
|||
#else
|
|||
.MinimumLevel.Information() |
|||
#endif
|
|||
.MinimumLevel.Override("Microsoft", LogEventLevel.Information) |
|||
.Enrich.FromLogContext() |
|||
.WriteTo.Async(c => c.File("Logs/logs.txt")) |
|||
#if DEBUG
|
|||
.WriteTo.Async(c => c.Console()) |
|||
#endif
|
|||
.CreateLogger(); |
|||
|
|||
try |
|||
{ |
|||
Log.Information("Starting web host."); |
|||
CreateHostBuilder(args).Build().Run(); |
|||
return 0; |
|||
} |
|||
catch (Exception ex) |
|||
{ |
|||
Log.Fatal(ex, "Host terminated unexpectedly!"); |
|||
return 1; |
|||
} |
|||
finally |
|||
{ |
|||
Log.CloseAndFlush(); |
|||
} |
|||
} |
|||
|
|||
internal static IHostBuilder CreateHostBuilder(string[] args) => |
|||
Host.CreateDefaultBuilder(args) |
|||
.ConfigureWebHostDefaults(webBuilder => |
|||
{ |
|||
webBuilder.UseStartup<Startup>(); |
|||
}) |
|||
.UseAutofac() |
|||
.UseSerilog(); |
|||
} |
|||
} |
|||
@ -0,0 +1,27 @@ |
|||
{ |
|||
"iisSettings": { |
|||
"windowsAuthentication": false, |
|||
"anonymousAuthentication": true, |
|||
"iisExpress": { |
|||
"applicationUrl": "https://localhost:44333", |
|||
"sslPort": 44333 |
|||
} |
|||
}, |
|||
"profiles": { |
|||
"IIS Express": { |
|||
"commandName": "IISExpress", |
|||
"launchBrowser": true, |
|||
"environmentVariables": { |
|||
"ASPNETCORE_ENVIRONMENT": "Development" |
|||
} |
|||
}, |
|||
"Lion.AbpPro.LanguageManagement.HttpApi.Host": { |
|||
"commandName": "Project", |
|||
"launchBrowser": true, |
|||
"applicationUrl": "https://localhost:44333", |
|||
"environmentVariables": { |
|||
"ASPNETCORE_ENVIRONMENT": "Development" |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,15 @@ |
|||
namespace Lion.AbpPro.LanguageManagement |
|||
{ |
|||
public class Startup |
|||
{ |
|||
public void ConfigureServices(IServiceCollection services) |
|||
{ |
|||
services.AddApplication<LanguageManagementHttpApiHostModule>(); |
|||
} |
|||
|
|||
public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILoggerFactory loggerFactory) |
|||
{ |
|||
app.InitializeApplication(); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,13 @@ |
|||
{ |
|||
"App": { |
|||
"CorsOrigins": "https://*.LanguageManagement.com,http://localhost:4200,http://localhost:44307,https://localhost:44307" |
|||
}, |
|||
"ConnectionStrings": { |
|||
"Default": "Data Source=localhost;Port=3306;Database=LionAbpProDB;uid=root;pwd=1q2w3E*;charset=utf8mb4;Allow User Variables=true;AllowLoadLocalInfile=true", |
|||
"LanguageManagement": "Data Source=localhost;Database=LanguageManagement;uid=root;pwd=1q2w3E*;charset=utf8mb4;Allow User Variables=true;AllowLoadLocalInfile=true" |
|||
}, |
|||
"Redis": { |
|||
"Configuration": "localhost,password=1q2w3E*", |
|||
"DatabaseId": 1 |
|||
} |
|||
} |
|||
@ -0,0 +1,3 @@ |
|||
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd"> |
|||
<ConfigureAwait ContinueOnCapturedContext="false" /> |
|||
</Weavers> |
|||
@ -0,0 +1,30 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> |
|||
<!-- This file was generated by Fody. Manual changes to this file will be lost when your project is rebuilt. --> |
|||
<xs:element name="Weavers"> |
|||
<xs:complexType> |
|||
<xs:all> |
|||
<xs:element name="ConfigureAwait" minOccurs="0" maxOccurs="1"> |
|||
<xs:complexType> |
|||
<xs:attribute name="ContinueOnCapturedContext" type="xs:boolean" /> |
|||
</xs:complexType> |
|||
</xs:element> |
|||
</xs:all> |
|||
<xs:attribute name="VerifyAssembly" type="xs:boolean"> |
|||
<xs:annotation> |
|||
<xs:documentation>'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed.</xs:documentation> |
|||
</xs:annotation> |
|||
</xs:attribute> |
|||
<xs:attribute name="VerifyIgnoreCodes" type="xs:string"> |
|||
<xs:annotation> |
|||
<xs:documentation>A comma-separated list of error codes that can be safely ignored in assembly verification.</xs:documentation> |
|||
</xs:annotation> |
|||
</xs:attribute> |
|||
<xs:attribute name="GenerateXsd" type="xs:boolean"> |
|||
<xs:annotation> |
|||
<xs:documentation>'false' to turn off automatic generation of the XML Schema file.</xs:documentation> |
|||
</xs:annotation> |
|||
</xs:attribute> |
|||
</xs:complexType> |
|||
</xs:element> |
|||
</xs:schema> |
|||
@ -0,0 +1,18 @@ |
|||
// Global using directives
|
|||
|
|||
global using System; |
|||
global using System.Collections.Generic; |
|||
global using System.Linq; |
|||
global using System.Text; |
|||
global using System.Threading; |
|||
global using System.Threading.Tasks; |
|||
global using Lion.AbpPro.Core; |
|||
global using Lion.AbpPro.LanguageManagement.Localization; |
|||
global using Volo.Abp.Application; |
|||
global using Volo.Abp.Application.Dtos; |
|||
global using Volo.Abp.Application.Services; |
|||
global using Volo.Abp.Authorization; |
|||
global using Volo.Abp.Authorization.Permissions; |
|||
global using Volo.Abp.Localization; |
|||
global using Volo.Abp.Modularity; |
|||
global using Volo.Abp.Reflection; |
|||
@ -0,0 +1,12 @@ |
|||
namespace Lion.AbpPro.LanguageManagement |
|||
{ |
|||
[DependsOn( |
|||
typeof(LanguageManagementDomainSharedModule), |
|||
typeof(AbpDddApplicationContractsModule), |
|||
typeof(AbpAuthorizationModule) |
|||
)] |
|||
public class LanguageManagementApplicationContractsModule : AbpModule |
|||
{ |
|||
|
|||
} |
|||
} |
|||
@ -0,0 +1,17 @@ |
|||
using Microsoft.Extensions.Logging; |
|||
using Volo.Abp; |
|||
|
|||
namespace Lion.AbpPro.LanguageManagement; |
|||
|
|||
public class LanguageManagementApplicationException : BusinessException |
|||
{ |
|||
public LanguageManagementApplicationException( |
|||
string code = null, |
|||
string message = null, |
|||
string details = null, |
|||
Exception innerException = null, |
|||
LogLevel logLevel = LogLevel.Warning) |
|||
: base(code, message, details, innerException, logLevel) |
|||
{ |
|||
} |
|||
} |
|||
@ -0,0 +1,30 @@ |
|||
using System.ComponentModel.DataAnnotations; |
|||
|
|||
namespace Lion.AbpPro.LanguageManagement.LanguageTexts; |
|||
|
|||
/// <summary>
|
|||
/// 创建语言文本
|
|||
/// </summary>
|
|||
public class CreateLanguageTextInput |
|||
{ |
|||
/// <summary>
|
|||
/// 资源名称
|
|||
/// </summary>
|
|||
[Required(ErrorMessage = "资源名称不能为空")] |
|||
public string ResourceName { get; set; } |
|||
/// <summary>
|
|||
/// 语言名称
|
|||
/// </summary>
|
|||
[Required(ErrorMessage = "语言名称不能为空")] |
|||
public string CultureName { get; set; } |
|||
/// <summary>
|
|||
/// 名称
|
|||
/// </summary>
|
|||
[Required(ErrorMessage = "名称不能为空")] |
|||
public string Name { get; set; } |
|||
/// <summary>
|
|||
/// 值
|
|||
/// </summary>
|
|||
[Required(ErrorMessage = "值不能为空")] |
|||
public string Value { get; set; } |
|||
} |
|||
@ -0,0 +1,28 @@ |
|||
namespace Lion.AbpPro.LanguageManagement.LanguageTexts; |
|||
|
|||
|
|||
/// <summary>
|
|||
/// 语言文本
|
|||
/// </summary>
|
|||
public interface ILanguageTextAppService : IApplicationService |
|||
{ |
|||
/// <summary>
|
|||
/// 获取所有资源
|
|||
/// </summary>
|
|||
Task<List<FromSelector<string, string>>> AllResourceListAsync(); |
|||
|
|||
/// <summary>
|
|||
/// 分页查询语言文本
|
|||
/// </summary>
|
|||
Task<PagedResultDto<PageLanguageTextOutput>> PageAsync(PageLanguageTextInput input); |
|||
|
|||
/// <summary>
|
|||
/// 创建语言文本
|
|||
/// </summary>
|
|||
Task CreateAsync(CreateLanguageTextInput input); |
|||
|
|||
/// <summary>
|
|||
/// 编辑语言文本
|
|||
/// </summary>
|
|||
Task UpdateAsync(UpdateLanguageTextInput input); |
|||
} |
|||
@ -0,0 +1,24 @@ |
|||
namespace Lion.AbpPro.LanguageManagement.LanguageTexts; |
|||
|
|||
/// <summary>
|
|||
/// 创建语言文本
|
|||
/// </summary>
|
|||
public class PageLanguageTextInput : PagingBase |
|||
{ |
|||
|
|||
/// <summary>
|
|||
/// 语言
|
|||
/// </summary>
|
|||
public string CultureName { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 资源
|
|||
/// </summary>
|
|||
public string ResourceName { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 查询条件 name or value
|
|||
/// </summary>
|
|||
public string Filter { get; set; } |
|||
|
|||
} |
|||
@ -0,0 +1,22 @@ |
|||
namespace Lion.AbpPro.LanguageManagement.LanguageTexts; |
|||
|
|||
/// <summary>
|
|||
/// 创建语言文本
|
|||
/// </summary>
|
|||
public class PageLanguageTextOutput |
|||
{ |
|||
/// <summary>
|
|||
/// 资源名称
|
|||
/// </summary>
|
|||
public string ResourceName { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 名称
|
|||
/// </summary>
|
|||
public string Name { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 值
|
|||
/// </summary>
|
|||
public string Value { get; set; } |
|||
} |
|||
@ -0,0 +1,33 @@ |
|||
using System.ComponentModel.DataAnnotations; |
|||
|
|||
namespace Lion.AbpPro.LanguageManagement.LanguageTexts; |
|||
|
|||
/// <summary>
|
|||
/// 删除语言文本
|
|||
/// </summary>
|
|||
public class UpdateLanguageTextInput |
|||
{ |
|||
/// <summary>
|
|||
/// 资源名称
|
|||
/// </summary>
|
|||
[Required(ErrorMessage = "资源名称不能为空")] |
|||
public string ResourceName { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 语言名称
|
|||
/// </summary>
|
|||
[Required(ErrorMessage = "语言名称不能为空")] |
|||
public string CultureName { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 名称
|
|||
/// </summary>
|
|||
[Required(ErrorMessage = "名称不能为空")] |
|||
public string Name { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 值
|
|||
/// </summary>
|
|||
[Required(ErrorMessage = "值不能为空")] |
|||
public string Value { get; set; } |
|||
} |
|||
@ -0,0 +1,34 @@ |
|||
using System.ComponentModel.DataAnnotations; |
|||
|
|||
namespace Lion.AbpPro.LanguageManagement.Languages; |
|||
|
|||
/// <summary>
|
|||
/// 创建语言
|
|||
/// </summary>
|
|||
public class CreateLanguageInput |
|||
{ |
|||
/// <summary>
|
|||
/// 语言名称
|
|||
/// </summary>
|
|||
[Required(ErrorMessage = "语言名称不能为空")] |
|||
public string CultureName { get; set; } |
|||
/// <summary>
|
|||
/// Ui语言名称
|
|||
/// </summary>
|
|||
[Required(ErrorMessage = "Ui语言名称不能为空")] |
|||
public string UiCultureName { get; set; } |
|||
/// <summary>
|
|||
/// 显示名称
|
|||
/// </summary>
|
|||
[Required(ErrorMessage = "显示名称不能为空")] |
|||
public string DisplayName { get; set; } |
|||
/// <summary>
|
|||
/// 图标
|
|||
/// </summary>
|
|||
public string FlagIcon { get; set; } |
|||
/// <summary>
|
|||
/// 是否启用
|
|||
/// </summary>
|
|||
[Required(ErrorMessage = "是否启用不能为空")] |
|||
public bool IsEnabled { get; set; } |
|||
} |
|||
@ -0,0 +1,12 @@ |
|||
namespace Lion.AbpPro.LanguageManagement.Languages; |
|||
|
|||
/// <summary>
|
|||
/// 删除语言
|
|||
/// </summary>
|
|||
public class DeleteLanguageInput |
|||
{ |
|||
/// <summary>
|
|||
/// 语言Id
|
|||
/// </summary>
|
|||
public Guid Id { get; set; } |
|||
} |
|||
@ -0,0 +1,39 @@ |
|||
namespace Lion.AbpPro.LanguageManagement.Languages; |
|||
|
|||
|
|||
/// <summary>
|
|||
/// 语言
|
|||
/// </summary>
|
|||
public interface ILanguageAppService : IApplicationService |
|||
{ |
|||
|
|||
/// <summary>
|
|||
/// 获取所有语言
|
|||
/// </summary>
|
|||
Task<List<PageLanguageOutput>> AllListAsync(); |
|||
|
|||
/// <summary>
|
|||
/// 分页查询语言
|
|||
/// </summary>
|
|||
Task<PagedResultDto<PageLanguageOutput>> PageAsync(PageLanguageInput input); |
|||
|
|||
/// <summary>
|
|||
/// 创建语言
|
|||
/// </summary>
|
|||
Task CreateAsync(CreateLanguageInput input); |
|||
|
|||
/// <summary>
|
|||
/// 编辑语言
|
|||
/// </summary>
|
|||
Task UpdateAsync(UpdateLanguageInput input); |
|||
|
|||
/// <summary>
|
|||
/// 删除语言
|
|||
/// </summary>
|
|||
Task DeleteAsync(DeleteLanguageInput input); |
|||
|
|||
/// <summary>
|
|||
/// 设置默认语言
|
|||
/// </summary>
|
|||
Task SetDefaultAsync(IdInput input); |
|||
} |
|||
@ -0,0 +1,9 @@ |
|||
namespace Lion.AbpPro.LanguageManagement.Languages; |
|||
|
|||
/// <summary>
|
|||
/// 创建语言
|
|||
/// </summary>
|
|||
public class PageLanguageInput : PagingBase |
|||
{ |
|||
public string Filter { get; set; } |
|||
} |
|||
@ -0,0 +1,43 @@ |
|||
namespace Lion.AbpPro.LanguageManagement.Languages; |
|||
|
|||
/// <summary>
|
|||
/// 创建语言
|
|||
/// </summary>
|
|||
public class PageLanguageOutput |
|||
{ |
|||
/// <summary>
|
|||
/// 语言Id
|
|||
/// </summary>
|
|||
public Guid Id { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 语言名称
|
|||
/// </summary>
|
|||
public string CultureName { get; set; } |
|||
/// <summary>
|
|||
/// Ui语言名称
|
|||
/// </summary>
|
|||
public string UiCultureName { get; set; } |
|||
/// <summary>
|
|||
/// 显示名称
|
|||
/// </summary>
|
|||
public string DisplayName { get; set; } |
|||
/// <summary>
|
|||
/// 图标
|
|||
/// </summary>
|
|||
public string FlagIcon { get; set; } |
|||
/// <summary>
|
|||
/// 是否启用
|
|||
/// </summary>
|
|||
public bool IsEnabled { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 创建时间
|
|||
/// </summary>
|
|||
public DateTime CreationTime { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 是否是默认语言
|
|||
/// </summary>
|
|||
public bool IsDefault { get; set; } |
|||
} |
|||
@ -0,0 +1,39 @@ |
|||
using System.ComponentModel.DataAnnotations; |
|||
|
|||
namespace Lion.AbpPro.LanguageManagement.Languages; |
|||
|
|||
/// <summary>
|
|||
/// 删除语言
|
|||
/// </summary>
|
|||
public class UpdateLanguageInput |
|||
{ |
|||
/// <summary>
|
|||
/// 语言Id
|
|||
/// </summary>
|
|||
public Guid Id { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 语言名称
|
|||
/// </summary>
|
|||
[Required(ErrorMessage = "语言名称不能为空")] |
|||
public string CultureName { get; set; } |
|||
/// <summary>
|
|||
/// Ui语言名称
|
|||
/// </summary>
|
|||
[Required(ErrorMessage = "Ui语言名称不能为空")] |
|||
public string UiCultureName { get; set; } |
|||
/// <summary>
|
|||
/// 显示名称
|
|||
/// </summary>
|
|||
[Required(ErrorMessage = "显示名称不能为空")] |
|||
public string DisplayName { get; set; } |
|||
/// <summary>
|
|||
/// 图标
|
|||
/// </summary>
|
|||
public string FlagIcon { get; set; } |
|||
/// <summary>
|
|||
/// 是否启用
|
|||
/// </summary>
|
|||
[Required(ErrorMessage = "是否启用不能为空")] |
|||
public bool IsEnabled { get; set; } |
|||
} |
|||
@ -0,0 +1,17 @@ |
|||
<Project Sdk="Microsoft.NET.Sdk"> |
|||
|
|||
<PropertyGroup> |
|||
<TargetFramework>net7.0</TargetFramework> |
|||
<RootNamespace>Lion.AbpPro.LanguageManagement</RootNamespace> |
|||
</PropertyGroup> |
|||
|
|||
<ItemGroup> |
|||
<PackageReference Include="Volo.Abp.Ddd.Application.Contracts" /> |
|||
<PackageReference Include="Volo.Abp.Authorization" /> |
|||
</ItemGroup> |
|||
|
|||
<ItemGroup> |
|||
<ProjectReference Include="..\Lion.AbpPro.LanguageManagement.Domain.Shared\Lion.AbpPro.LanguageManagement.Domain.Shared.csproj" /> |
|||
</ItemGroup> |
|||
|
|||
</Project> |
|||
@ -0,0 +1,28 @@ |
|||
namespace Lion.AbpPro.LanguageManagement.Permissions |
|||
{ |
|||
public class LanguageManagementPermissionDefinitionProvider : PermissionDefinitionProvider |
|||
{ |
|||
public override void Define(IPermissionDefinitionContext context) |
|||
{ |
|||
var abpIdentityGroup = context.GetGroup("AbpIdentity"); |
|||
// var languageManagement = context.AddGroup(LanguageManagementPermissions.GroupName, L("Permission:LanguageManagement"));
|
|||
|
|||
|
|||
var languages = abpIdentityGroup.AddPermission(LanguageManagementPermissions.Languages.Default, L("Permission:Languages")); |
|||
languages.AddChild(LanguageManagementPermissions.Languages.Create, L("Permission:Create")); |
|||
languages.AddChild(LanguageManagementPermissions.Languages.Edit, L("Permission:Edit")); |
|||
languages.AddChild(LanguageManagementPermissions.Languages.Delete, L("Permission:Delete")); |
|||
languages.AddChild(LanguageManagementPermissions.Languages.ChangeDefault, L("Permission:LanguagesChangeDefault")); |
|||
|
|||
|
|||
var languageTexts = abpIdentityGroup.AddPermission(LanguageManagementPermissions.LanguageTexts.Default, L("Permission:LanguageTexts")); |
|||
languageTexts.AddChild(LanguageManagementPermissions.LanguageTexts.Edit, L("Permission:Edit")); |
|||
languageTexts.AddChild(LanguageManagementPermissions.LanguageTexts.Create, L("Permission:Create")); |
|||
} |
|||
|
|||
private static LocalizableString L(string name) |
|||
{ |
|||
return LocalizableString.Create<LanguageManagementResource>(name); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,36 @@ |
|||
namespace Lion.AbpPro.LanguageManagement.Permissions |
|||
{ |
|||
public class LanguageManagementPermissions |
|||
{ |
|||
public static string[] GetAll() |
|||
{ |
|||
return ReflectionHelper.GetPublicConstantsRecursively(typeof(LanguageManagementPermissions)); |
|||
} |
|||
|
|||
|
|||
//public const string GroupName = "LanguageManagement";
|
|||
public const string GroupName = "AbpIdentity"; |
|||
|
|||
public class LanguageTexts |
|||
{ |
|||
public const string Default = "AbpIdentity.LanguageTexts"; |
|||
|
|||
public const string Create = "AbpIdentity.LanguageTexts.Create"; |
|||
|
|||
public const string Edit = "AbpIdentity.LanguageTexts.Edit"; |
|||
} |
|||
|
|||
public class Languages |
|||
{ |
|||
public const string Default = "AbpIdentity.Languages"; |
|||
|
|||
public const string Edit = "AbpIdentity.Languages.Edit"; |
|||
|
|||
public const string Create = "AbpIdentity.Languages.Create"; |
|||
|
|||
public const string ChangeDefault = "AbpIdentity.Languages.ChangeDefault"; |
|||
|
|||
public const string Delete = "AbpIdentity.Languages.Delete"; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,3 @@ |
|||
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd"> |
|||
<ConfigureAwait ContinueOnCapturedContext="false" /> |
|||
</Weavers> |
|||
@ -0,0 +1,30 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> |
|||
<!-- This file was generated by Fody. Manual changes to this file will be lost when your project is rebuilt. --> |
|||
<xs:element name="Weavers"> |
|||
<xs:complexType> |
|||
<xs:all> |
|||
<xs:element name="ConfigureAwait" minOccurs="0" maxOccurs="1"> |
|||
<xs:complexType> |
|||
<xs:attribute name="ContinueOnCapturedContext" type="xs:boolean" /> |
|||
</xs:complexType> |
|||
</xs:element> |
|||
</xs:all> |
|||
<xs:attribute name="VerifyAssembly" type="xs:boolean"> |
|||
<xs:annotation> |
|||
<xs:documentation>'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed.</xs:documentation> |
|||
</xs:annotation> |
|||
</xs:attribute> |
|||
<xs:attribute name="VerifyIgnoreCodes" type="xs:string"> |
|||
<xs:annotation> |
|||
<xs:documentation>A comma-separated list of error codes that can be safely ignored in assembly verification.</xs:documentation> |
|||
</xs:annotation> |
|||
</xs:attribute> |
|||
<xs:attribute name="GenerateXsd" type="xs:boolean"> |
|||
<xs:annotation> |
|||
<xs:documentation>'false' to turn off automatic generation of the XML Schema file.</xs:documentation> |
|||
</xs:annotation> |
|||
</xs:attribute> |
|||
</xs:complexType> |
|||
</xs:element> |
|||
</xs:schema> |
|||
@ -0,0 +1,26 @@ |
|||
// Global using directives
|
|||
|
|||
global using System.Collections.Generic; |
|||
global using System.Globalization; |
|||
global using System.Linq; |
|||
global using System.Threading; |
|||
global using System.Threading.Tasks; |
|||
global using AutoMapper; |
|||
global using Lion.AbpPro.Core; |
|||
global using Lion.AbpPro.LanguageManagement.Languages.Aggregates; |
|||
global using Lion.AbpPro.LanguageManagement.Localization; |
|||
global using Lion.AbpPro.LanguageManagement.Permissions; |
|||
global using Microsoft.AspNetCore.Authorization; |
|||
global using Microsoft.Extensions.DependencyInjection; |
|||
global using Microsoft.Extensions.Localization; |
|||
global using Microsoft.Extensions.Options; |
|||
global using Volo.Abp; |
|||
global using Volo.Abp.Application; |
|||
global using Volo.Abp.Application.Dtos; |
|||
global using Volo.Abp.Application.Services; |
|||
global using Volo.Abp.AutoMapper; |
|||
global using Volo.Abp.Json; |
|||
global using Volo.Abp.Localization; |
|||
global using Volo.Abp.Localization.External; |
|||
global using Volo.Abp.Modularity; |
|||
global using Volo.Abp.SettingManagement; |
|||
@ -0,0 +1,11 @@ |
|||
namespace Lion.AbpPro.LanguageManagement |
|||
{ |
|||
public abstract class LanguageManagementAppService : ApplicationService |
|||
{ |
|||
protected LanguageManagementAppService() |
|||
{ |
|||
LocalizationResource = typeof(LanguageManagementResource); |
|||
ObjectMapperContext = typeof(LanguageManagementApplicationModule); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,15 @@ |
|||
using Lion.AbpPro.LanguageManagement.Languages; |
|||
using Lion.AbpPro.LanguageManagement.LanguageTexts; |
|||
|
|||
namespace Lion.AbpPro.LanguageManagement |
|||
{ |
|||
public class LanguageManagementApplicationAutoMapperProfile : Profile |
|||
{ |
|||
public LanguageManagementApplicationAutoMapperProfile() |
|||
{ |
|||
CreateMap<LanguageDto, PageLanguageOutput>(); |
|||
CreateMap<Language, PageLanguageOutput>(); |
|||
CreateMap<LanguageTextDto, PageLanguageTextOutput>(); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,20 @@ |
|||
namespace Lion.AbpPro.LanguageManagement |
|||
{ |
|||
[DependsOn( |
|||
typeof(LanguageManagementDomainModule), |
|||
typeof(LanguageManagementApplicationContractsModule), |
|||
typeof(AbpDddApplicationModule), |
|||
typeof(AbpAutoMapperModule) |
|||
)] |
|||
public class LanguageManagementApplicationModule : AbpModule |
|||
{ |
|||
public override void ConfigureServices(ServiceConfigurationContext context) |
|||
{ |
|||
context.Services.AddAutoMapperObjectMapper<LanguageManagementApplicationModule>(); |
|||
Configure<AbpAutoMapperOptions>(options => |
|||
{ |
|||
options.AddMaps<LanguageManagementApplicationModule>(validate: true); |
|||
}); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,162 @@ |
|||
namespace Lion.AbpPro.LanguageManagement.LanguageTexts; |
|||
|
|||
/// <summary>
|
|||
/// 语言文本
|
|||
/// </summary>
|
|||
[Authorize] |
|||
public class LanguageTextAppService : ApplicationService, ILanguageTextAppService |
|||
{ |
|||
private readonly ILanguageTextManager _languageTextManager; |
|||
private readonly IStringLocalizerFactory _stringLocalizerFactory; |
|||
private readonly ILocalizationHelper _localizationHelper; |
|||
|
|||
public LanguageTextAppService( |
|||
ILanguageTextManager languageTextManager, |
|||
IStringLocalizerFactory stringLocalizerFactory, |
|||
IOptions<AbpLocalizationOptions> localizationOptions, |
|||
IExternalLocalizationStore externalLocalizationStore, |
|||
ILocalizationHelper localizationHelper) |
|||
{ |
|||
_languageTextManager = languageTextManager; |
|||
_stringLocalizerFactory = stringLocalizerFactory; |
|||
_localizationHelper = localizationHelper; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 获取所有资源
|
|||
/// </summary>
|
|||
public async Task<List<FromSelector<string, string>>> AllResourceListAsync() |
|||
{ |
|||
var result = new List<FromSelector<string, string>>(); |
|||
foreach (var item in await _localizationHelper.GetAllResourceName()) |
|||
{ |
|||
result.Add(new FromSelector<string, string>(item, item)); |
|||
} |
|||
|
|||
return result; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 分页查询语言文本
|
|||
/// </summary>
|
|||
public async Task<PagedResultDto<PageLanguageTextOutput>> PageAsync(PageLanguageTextInput input) |
|||
{ |
|||
if (!CultureHelper.IsValidCultureCode(input.CultureName)) |
|||
{ |
|||
throw new LanguageManagementApplicationException(LanguageManagementErrorCodes.CultureNotValid); |
|||
} |
|||
|
|||
var list = await FindLocalizationsAsync(input.CultureName); |
|||
|
|||
var queryable = list |
|||
.AsQueryable() |
|||
.WhereIf(input.ResourceName.IsNotNullOrWhiteSpace(), e => e.ResourceName == input.ResourceName) |
|||
.WhereIf(input.Filter.IsNotNullOrWhiteSpace(), e => e.Name.Contains(input.Filter) || e.Value.Contains(input.Filter)); |
|||
var result = new PagedResultDto<PageLanguageTextOutput> |
|||
{ |
|||
Items = queryable.OrderBy(e => e.Name).PageBy(input.SkipCount, input.PageSize).ToList(), |
|||
TotalCount = queryable.Count() |
|||
}; |
|||
|
|||
return result; |
|||
} |
|||
|
|||
protected virtual async Task<List<PageLanguageTextOutput>> FindLocalizationsAsync(string cultureName) |
|||
{ |
|||
var list = new List<PageLanguageTextOutput>(); |
|||
using (CultureHelper.Use(cultureName)) |
|||
{ |
|||
foreach (var resource in await _localizationHelper.GetAllResourceName()) |
|||
{ |
|||
var localizer = await _stringLocalizerFactory.CreateByResourceNameOrNullAsync(resource); |
|||
if (localizer != null) |
|||
{ |
|||
foreach (var localizedString in await localizer.GetAllStringsAsync(false, false, true)) |
|||
{ |
|||
var item = new PageLanguageTextOutput |
|||
{ |
|||
//CultureName = resource.DefaultCultureName,
|
|||
ResourceName = resource, |
|||
Name = localizedString.Name, |
|||
Value = localizedString.Value |
|||
}; |
|||
if (list.Contains(item)) continue; |
|||
list.Add(item); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
return list; |
|||
} |
|||
|
|||
|
|||
/// <summary>
|
|||
/// 创建语言文本
|
|||
/// </summary>
|
|||
[Authorize(LanguageManagementPermissions.LanguageTexts.Create)] |
|||
public async Task CreateAsync(CreateLanguageTextInput input) |
|||
{ |
|||
var localizedString = await GetLocalizedStringAsync(input.ResourceName, input.CultureName, input.Name); |
|||
if (localizedString != null && localizedString.Value == input.Value) |
|||
{ |
|||
throw new LanguageManagementApplicationException(LanguageManagementErrorCodes.LanguageTextExist).WithData("Name", input.Name); |
|||
} |
|||
|
|||
await _languageTextManager.CreateAsync( |
|||
GuidGenerator.Create(), |
|||
input.CultureName, |
|||
input.ResourceName, |
|||
input.Name, |
|||
input.Value |
|||
); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 编辑语言文本
|
|||
/// </summary>
|
|||
[Authorize(LanguageManagementPermissions.LanguageTexts.Edit)] |
|||
public async Task UpdateAsync(UpdateLanguageTextInput input) |
|||
{ |
|||
var localizedString = await GetLocalizedStringAsync(input.ResourceName, input.CultureName, input.Name); |
|||
if (localizedString == null) throw new LanguageManagementApplicationException(LanguageManagementErrorCodes.ResourceNotFound); |
|||
if (localizedString.Value == input.Value) return; |
|||
|
|||
await _languageTextManager.UpdateAsync( |
|||
input.CultureName, |
|||
input.ResourceName, |
|||
input.Name, |
|||
input.Value |
|||
); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 获取执行语言
|
|||
/// </summary>
|
|||
protected virtual async Task<LocalizedString> GetLocalizedStringAsync(string resourceName, string cultureName, string name) |
|||
{ |
|||
using (CultureHelper.Use(cultureName)) |
|||
{ |
|||
if (!(await _localizationHelper.IsValidResourceName(resourceName))) |
|||
|
|||
{ |
|||
throw new LanguageManagementApplicationException(LanguageManagementErrorCodes.ResourceNotFound); |
|||
} |
|||
|
|||
|
|||
var localizer = await _stringLocalizerFactory.CreateByResourceNameOrNullAsync(resourceName); |
|||
|
|||
if (localizer == null) |
|||
{ |
|||
throw new LanguageManagementApplicationException(LanguageManagementErrorCodes.ResourceNotFound); |
|||
} |
|||
|
|||
var localizedStrings = await localizer.GetAllStringsAsync(); |
|||
|
|||
var localizedString = localizedStrings.FirstOrDefault(e => e.Name == name); |
|||
|
|||
|
|||
return localizedString; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,94 @@ |
|||
namespace Lion.AbpPro.LanguageManagement.Languages; |
|||
|
|||
/// <summary>
|
|||
/// 语言
|
|||
/// </summary>
|
|||
[Authorize] |
|||
public class LanguageAppService : ApplicationService, ILanguageAppService |
|||
{ |
|||
private readonly ILanguageManager _languageManager; |
|||
private readonly ISettingManager _settingManager; |
|||
|
|||
public LanguageAppService(ILanguageManager languageManager, ISettingManager settingManager) |
|||
{ |
|||
_languageManager = languageManager; |
|||
_settingManager = settingManager; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 获取所有语言
|
|||
/// </summary>
|
|||
public async Task<List<PageLanguageOutput>> AllListAsync() |
|||
{ |
|||
var languages = await _languageManager.ListAsync(); |
|||
var list = ObjectMapper.Map<List<Language>, List<PageLanguageOutput>>(languages); |
|||
return list; |
|||
} |
|||
|
|||
|
|||
/// <summary>
|
|||
/// 分页查询语言
|
|||
/// </summary>
|
|||
public async Task<PagedResultDto<PageLanguageOutput>> PageAsync(PageLanguageInput input) |
|||
{ |
|||
var result = new PagedResultDto<PageLanguageOutput>(); |
|||
var totalCount = await _languageManager.CountAsync(input.Filter); |
|||
result.TotalCount = totalCount; |
|||
if (totalCount <= 0) return result; |
|||
var list = await _languageManager.GetListAsync(input.PageSize, input.SkipCount, input.Filter); |
|||
result.Items = ObjectMapper.Map<List<LanguageDto>, List<PageLanguageOutput>>(list); |
|||
return result; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 创建语言
|
|||
/// </summary>
|
|||
[Authorize(LanguageManagementPermissions.Languages.Create)] |
|||
public Task CreateAsync(CreateLanguageInput input) |
|||
{ |
|||
return _languageManager.CreateAsync( |
|||
GuidGenerator.Create(), |
|||
input.CultureName, |
|||
input.UiCultureName, |
|||
input.DisplayName, |
|||
input.FlagIcon, |
|||
input.IsEnabled |
|||
); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 编辑语言
|
|||
/// </summary>
|
|||
[Authorize(LanguageManagementPermissions.Languages.Edit)] |
|||
public Task UpdateAsync(UpdateLanguageInput input) |
|||
{ |
|||
return _languageManager.UpdateAsync( |
|||
input.Id, |
|||
input.CultureName, |
|||
input.UiCultureName, |
|||
input.DisplayName, |
|||
input.FlagIcon, |
|||
input.IsEnabled |
|||
); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 删除语言
|
|||
/// </summary>
|
|||
[Authorize(LanguageManagementPermissions.Languages.Delete)] |
|||
public Task DeleteAsync(DeleteLanguageInput input) |
|||
{ |
|||
return _languageManager.DeleteAsync(input.Id); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 设置默认语言
|
|||
/// </summary>
|
|||
[Authorize(LanguageManagementPermissions.Languages.ChangeDefault)] |
|||
public async Task SetDefaultAsync(IdInput input) |
|||
{ |
|||
var language = await _languageManager.GetAsync(input.Id); |
|||
await _settingManager.SetForCurrentTenantAsync(LanguageManagementConsts.SettingDefaultLanguage, language.CultureName + ";" + language.UiCultureName, false); |
|||
await _languageManager.SetDefaultAsync(input.Id); |
|||
} |
|||
} |
|||
@ -0,0 +1,15 @@ |
|||
<Project Sdk="Microsoft.NET.Sdk"> |
|||
|
|||
<PropertyGroup> |
|||
<TargetFramework>net7.0</TargetFramework> |
|||
<RootNamespace>Lion.AbpPro.LanguageManagement</RootNamespace> |
|||
</PropertyGroup> |
|||
|
|||
<ItemGroup> |
|||
<PackageReference Include="Volo.Abp.AutoMapper" /> |
|||
<PackageReference Include="Volo.Abp.Ddd.Application" /> |
|||
<ProjectReference Include="..\Lion.AbpPro.LanguageManagement.Application.Contracts\Lion.AbpPro.LanguageManagement.Application.Contracts.csproj" /> |
|||
<ProjectReference Include="..\Lion.AbpPro.LanguageManagement.Domain\Lion.AbpPro.LanguageManagement.Domain.csproj" /> |
|||
</ItemGroup> |
|||
|
|||
</Project> |
|||
@ -0,0 +1,3 @@ |
|||
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd"> |
|||
<ConfigureAwait ContinueOnCapturedContext="false" /> |
|||
</Weavers> |
|||
@ -0,0 +1,30 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> |
|||
<!-- This file was generated by Fody. Manual changes to this file will be lost when your project is rebuilt. --> |
|||
<xs:element name="Weavers"> |
|||
<xs:complexType> |
|||
<xs:all> |
|||
<xs:element name="ConfigureAwait" minOccurs="0" maxOccurs="1"> |
|||
<xs:complexType> |
|||
<xs:attribute name="ContinueOnCapturedContext" type="xs:boolean" /> |
|||
</xs:complexType> |
|||
</xs:element> |
|||
</xs:all> |
|||
<xs:attribute name="VerifyAssembly" type="xs:boolean"> |
|||
<xs:annotation> |
|||
<xs:documentation>'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed.</xs:documentation> |
|||
</xs:annotation> |
|||
</xs:attribute> |
|||
<xs:attribute name="VerifyIgnoreCodes" type="xs:string"> |
|||
<xs:annotation> |
|||
<xs:documentation>A comma-separated list of error codes that can be safely ignored in assembly verification.</xs:documentation> |
|||
</xs:annotation> |
|||
</xs:attribute> |
|||
<xs:attribute name="GenerateXsd" type="xs:boolean"> |
|||
<xs:annotation> |
|||
<xs:documentation>'false' to turn off automatic generation of the XML Schema file.</xs:documentation> |
|||
</xs:annotation> |
|||
</xs:attribute> |
|||
</xs:complexType> |
|||
</xs:element> |
|||
</xs:schema> |
|||
@ -0,0 +1,14 @@ |
|||
// Global using directives
|
|||
|
|||
global using System; |
|||
global using System.Collections.Generic; |
|||
global using System.Runtime.Serialization; |
|||
global using Lion.AbpPro.LanguageManagement.Localization; |
|||
global using Microsoft.Extensions.Logging; |
|||
global using Volo.Abp; |
|||
global using Volo.Abp.Localization; |
|||
global using Volo.Abp.Localization.ExceptionHandling; |
|||
global using Volo.Abp.Modularity; |
|||
global using Volo.Abp.Validation; |
|||
global using Volo.Abp.Validation.Localization; |
|||
global using Volo.Abp.VirtualFileSystem; |
|||
@ -0,0 +1,16 @@ |
|||
namespace Lion.AbpPro.LanguageManagement |
|||
{ |
|||
public class LanguageManagementConsts |
|||
{ |
|||
/// <summary>名称空间</summary>
|
|||
public const string NameSpace = "Lion.AbpPro.LanguageManagement"; |
|||
|
|||
/// <summary>默认语言</summary>
|
|||
public const string DefaultCultureName = "zh-Hans"; |
|||
|
|||
/// <summary>
|
|||
/// setting默认语言配置
|
|||
/// </summary>
|
|||
public const string SettingDefaultLanguage = "Abp.Localization.DefaultLanguage"; |
|||
} |
|||
} |
|||
@ -0,0 +1,17 @@ |
|||
using Microsoft.Extensions.Logging; |
|||
using Volo.Abp; |
|||
|
|||
namespace Lion.AbpPro.LanguageManagement; |
|||
|
|||
public class LanguageManagementDomainException : BusinessException |
|||
{ |
|||
public LanguageManagementDomainException( |
|||
string code = null, |
|||
string message = null, |
|||
string details = null, |
|||
Exception innerException = null, |
|||
LogLevel logLevel = LogLevel.Warning) |
|||
: base(code, message, details, innerException, logLevel) |
|||
{ |
|||
} |
|||
} |
|||
@ -0,0 +1,32 @@ |
|||
using Lion.AbpPro.Core; |
|||
|
|||
namespace Lion.AbpPro.LanguageManagement |
|||
{ |
|||
[DependsOn( |
|||
typeof(AbpValidationModule), |
|||
typeof(LionAbpProCoreModule) |
|||
)] |
|||
public class LanguageManagementDomainSharedModule : AbpModule |
|||
{ |
|||
public override void ConfigureServices(ServiceConfigurationContext context) |
|||
{ |
|||
Configure<AbpVirtualFileSystemOptions>(options => |
|||
{ |
|||
options.FileSets.AddEmbedded<LanguageManagementDomainSharedModule>(); |
|||
}); |
|||
|
|||
Configure<AbpLocalizationOptions>(options => |
|||
{ |
|||
options.Resources |
|||
.Add<LanguageManagementResource>(LanguageManagementConsts.DefaultCultureName) |
|||
.AddBaseTypes(typeof(AbpValidationResource)) |
|||
.AddVirtualJson("/Localization/LanguageManagement"); |
|||
}); |
|||
|
|||
Configure<AbpExceptionLocalizationOptions>(options => |
|||
{ |
|||
options.MapCodeNamespace(LanguageManagementConsts.NameSpace, typeof(LanguageManagementResource)); |
|||
}); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,12 @@ |
|||
namespace Lion.AbpPro.LanguageManagement |
|||
{ |
|||
public static class LanguageManagementErrorCodes |
|||
{ |
|||
public const string CultureNotValid = LanguageManagementConsts.NameSpace + ":100001"; |
|||
public const string ResourceNotFound = LanguageManagementConsts.NameSpace + ":100002"; |
|||
public const string LanguageNotFound = LanguageManagementConsts.NameSpace + ":100003"; |
|||
public const string LanguageExist = LanguageManagementConsts.NameSpace + ":100004"; |
|||
public const string LanguageTextNotFound = LanguageManagementConsts.NameSpace + ":100005"; |
|||
public const string LanguageTextExist = LanguageManagementConsts.NameSpace + ":100006"; |
|||
} |
|||
} |
|||
@ -0,0 +1,16 @@ |
|||
namespace Lion.AbpPro.LanguageManagement.LanguageTexts; |
|||
|
|||
public class LanguageTextCacheItem |
|||
{ |
|||
public Dictionary<string, string> Dictionary { get; set; } |
|||
|
|||
public LanguageTextCacheItem() |
|||
{ |
|||
this.Dictionary = new Dictionary<string, string>(); |
|||
} |
|||
|
|||
public static string CalculateCacheKey(string resourceName, string cultureName) |
|||
{ |
|||
return resourceName + "_" + cultureName; |
|||
} |
|||
} |
|||
@ -0,0 +1,35 @@ |
|||
namespace Lion.AbpPro.LanguageManagement.LanguageTexts; |
|||
|
|||
public class LanguageTextDto |
|||
{ |
|||
/// <summary>
|
|||
/// 主键Id
|
|||
/// </summary>
|
|||
public Guid Id { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 创建时间
|
|||
/// </summary>
|
|||
public DateTime CreationTime { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 资源名称
|
|||
/// </summary>
|
|||
public string ResourceName { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 语言名称
|
|||
/// </summary>
|
|||
public string CultureName { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 名称
|
|||
/// </summary>
|
|||
public string Name { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 值
|
|||
/// </summary>
|
|||
public string Value { get; set; } |
|||
|
|||
} |
|||
@ -0,0 +1,44 @@ |
|||
namespace Lion.AbpPro.LanguageManagement.Languages; |
|||
|
|||
public class LanguageDto |
|||
{ |
|||
/// <summary>
|
|||
/// 主键Id
|
|||
/// </summary>
|
|||
public Guid Id { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 创建时间
|
|||
/// </summary>
|
|||
public DateTime CreationTime { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 语言名称
|
|||
/// </summary>
|
|||
public string CultureName { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// Ui语言名称
|
|||
/// </summary>
|
|||
public string UiCultureName { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 显示名称
|
|||
/// </summary>
|
|||
public string DisplayName { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 图标
|
|||
/// </summary>
|
|||
public string FlagIcon { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 是否启用
|
|||
/// </summary>
|
|||
public bool IsEnabled { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 是否默认语言
|
|||
/// </summary>
|
|||
public bool IsDefault { get; set; } |
|||
} |
|||
@ -0,0 +1,16 @@ |
|||
namespace Lion.AbpPro.LanguageManagement.Languages; |
|||
|
|||
public class LanguageListCacheItem |
|||
{ |
|||
public List<LanguageInfo> Languages { get; set; } |
|||
|
|||
public LanguageListCacheItem(List<LanguageInfo> languages) |
|||
{ |
|||
this.Languages = languages; |
|||
} |
|||
|
|||
public static string CalculateCacheKey() |
|||
{ |
|||
return "AllLanguages"; |
|||
} |
|||
} |
|||
@ -0,0 +1,24 @@ |
|||
<Project Sdk="Microsoft.NET.Sdk"> |
|||
|
|||
<PropertyGroup> |
|||
<TargetFramework>net7.0</TargetFramework> |
|||
<RootNamespace>Lion.AbpPro.LanguageManagement</RootNamespace> |
|||
<GenerateEmbeddedFilesManifest>true</GenerateEmbeddedFilesManifest> |
|||
</PropertyGroup> |
|||
|
|||
<ItemGroup> |
|||
<PackageReference Include="Volo.Abp.Validation" /> |
|||
</ItemGroup> |
|||
|
|||
<ItemGroup> |
|||
<PackageReference Include="Microsoft.Extensions.FileProviders.Embedded" /> |
|||
</ItemGroup> |
|||
<ItemGroup> |
|||
<ProjectReference Include="..\..\..\..\frameworks\src\Lion.AbpPro.Core\Lion.AbpPro.Core.csproj" /> |
|||
</ItemGroup> |
|||
<ItemGroup> |
|||
<EmbeddedResource Include="Localization\LanguageManagement\*.json" /> |
|||
<Content Remove="Localization\LanguageManagement\*.json" /> |
|||
</ItemGroup> |
|||
|
|||
</Project> |
|||
@ -0,0 +1,7 @@ |
|||
{ |
|||
"culture": "ar", |
|||
"texts": { |
|||
"ManageYourProfile": "إدارة ملفى", |
|||
"SamplePageMessage": "صفحة نموذجية للوحدة النمطية LanguageManagement" |
|||
} |
|||
} |
|||
@ -0,0 +1,7 @@ |
|||
{ |
|||
"culture": "cs", |
|||
"texts": { |
|||
"ManageYourProfile": "Spravovat profil", |
|||
"SamplePageMessage": "Ukázková stránka pro modul LanguageManagement" |
|||
} |
|||
} |
|||
@ -0,0 +1,7 @@ |
|||
{ |
|||
"culture": "de-DE", |
|||
"texts": { |
|||
"ManageYourProfile": "Verwalten Sie Ihr Profil", |
|||
"SamplePageMessage": "Eine Beispielseite für das Modul LanguageManagementModul" |
|||
} |
|||
} |
|||
@ -0,0 +1,7 @@ |
|||
{ |
|||
"culture": "en-GB", |
|||
"texts": { |
|||
"ManageYourProfile": "Manage your profile", |
|||
"SamplePageMessage": "A sample page for the LanguageManagement module" |
|||
} |
|||
} |
|||
@ -0,0 +1,20 @@ |
|||
{ |
|||
"culture": "en", |
|||
"texts": { |
|||
"ManageYourProfile": "Manage your profile", |
|||
"SamplePageMessage": "A sample page for the LanguageManagement module", |
|||
"Permission:LanguageManagement": "LanguageManagement", |
|||
"Permission:Languages": "Languages", |
|||
"Permission:LanguageTexts": "LanguageText", |
|||
"Permission:Create": "Create", |
|||
"Permission:Update": "Update", |
|||
"Permission:Delete": "Delete", |
|||
"Permission:LanguagesChangeDefault": "Change Default Language", |
|||
"Lion.AbpPro.LanguageManagement:100001": "The selected culture is not valid! Make sure you enter a valid culture name", |
|||
"Lion.AbpPro.LanguageManagement:100002": "Language resources not found", |
|||
"Lion.AbpPro.LanguageManagement:100003": "Language not found", |
|||
"Lion.AbpPro.LanguageManagement:100004": "Language exists", |
|||
"Lion.AbpPro.LanguageManagement:100005": "'{Name}' not found", |
|||
"Lion.AbpPro.LanguageManagement:100006": "'{Name}'exists" |
|||
} |
|||
} |
|||
@ -0,0 +1,7 @@ |
|||
{ |
|||
"culture": "es", |
|||
"texts": { |
|||
"ManageYourProfile": "Gestiona tu perfil", |
|||
"SamplePageMessage": "Una página de ejemplo para el módulo LanguageManagement " |
|||
} |
|||
} |
|||
@ -0,0 +1,7 @@ |
|||
{ |
|||
"culture": "fr", |
|||
"texts": { |
|||
"ManageYourProfile": "Gérer votre profil", |
|||
"SamplePageMessage": "Exemple de page pour le module LanguageManagement" |
|||
} |
|||
} |
|||
@ -0,0 +1,7 @@ |
|||
{ |
|||
"culture": "hu", |
|||
"texts": { |
|||
"ManageYourProfile": "Kezelje a profilját", |
|||
"SamplePageMessage": "Mintaoldal a LanguageManagement modulhoz" |
|||
} |
|||
} |
|||
@ -0,0 +1,7 @@ |
|||
{ |
|||
"culture": "nl", |
|||
"texts": { |
|||
"ManageYourProfile": "Beheer uw profiel", |
|||
"SamplePageMessage": "Een voorbeeldpagina voor de LanguageManagement module" |
|||
} |
|||
} |
|||
@ -0,0 +1,6 @@ |
|||
{ |
|||
"culture": "pl-PL", |
|||
"texts": { |
|||
|
|||
} |
|||
} |
|||
@ -0,0 +1,6 @@ |
|||
{ |
|||
"culture": "pt-BR", |
|||
"texts": { |
|||
|
|||
} |
|||
} |
|||
@ -0,0 +1,6 @@ |
|||
{ |
|||
"culture": "sl", |
|||
"texts": { |
|||
"ManageYourProfile": "Upravljajte svojim profilom" |
|||
} |
|||
} |
|||
@ -0,0 +1,7 @@ |
|||
{ |
|||
"culture": "tr", |
|||
"texts": { |
|||
"ManageYourProfile": "Profil yönetimi", |
|||
"SamplePageMessage": "LanguageManagement modulünden örnek bir sayfa" |
|||
} |
|||
} |
|||
@ -0,0 +1,6 @@ |
|||
{ |
|||
"culture": "vi", |
|||
"texts": { |
|||
|
|||
} |
|||
} |
|||
@ -0,0 +1,20 @@ |
|||
{ |
|||
"culture": "zh-Hans", |
|||
"texts": { |
|||
"ManageYourProfile": "管理个人资料", |
|||
"SamplePageMessage": "LanguageManagement模块的示例页面", |
|||
"Permission:LanguageManagement": "语言管理", |
|||
"Permission:Languages": "语言", |
|||
"Permission:LanguageTexts": "语言文本", |
|||
"Permission:Create": "创建", |
|||
"Permission:Update": "编辑", |
|||
"Permission:Delete": "删除", |
|||
"Permission:LanguagesChangeDefault": "修改默认语言", |
|||
"Lion.AbpPro.LanguageManagement:100001": "所选区域性无效!确保输入有效的区域性名称", |
|||
"Lion.AbpPro.LanguageManagement:100002": "语言资源未找到", |
|||
"Lion.AbpPro.LanguageManagement:100003": "语言未找到", |
|||
"Lion.AbpPro.LanguageManagement:100004": "语言已存在", |
|||
"Lion.AbpPro.LanguageManagement:100005": "'{Name}'未找到", |
|||
"Lion.AbpPro.LanguageManagement:100006": "'{Name}'已存在" |
|||
} |
|||
} |
|||
@ -0,0 +1,6 @@ |
|||
{ |
|||
"culture": "zh-Hant", |
|||
"texts": { |
|||
"ManageYourProfile": "管理個人資料" |
|||
} |
|||
} |
|||
@ -0,0 +1,8 @@ |
|||
namespace Lion.AbpPro.LanguageManagement.Localization |
|||
{ |
|||
[LocalizationResourceName("LanguageManagement")] |
|||
public class LanguageManagementResource |
|||
{ |
|||
|
|||
} |
|||
} |
|||
@ -0,0 +1,10 @@ |
|||
namespace Lion.AbpPro.LanguageManagement; |
|||
|
|||
public static class AbpLocalizationOptionsExtensions |
|||
{ |
|||
public static AbpLocalizationOptions AddDynamicResource(this AbpLocalizationOptions localizationOptions) |
|||
{ |
|||
localizationOptions.GlobalContributors.Add<DynamicLocalizationResourceContributor>(); |
|||
return localizationOptions; |
|||
} |
|||
} |
|||
@ -0,0 +1,51 @@ |
|||
using Lion.AbpPro.LanguageManagement.Languages; |
|||
using Volo.Abp.SettingManagement; |
|||
|
|||
namespace Lion.AbpPro.LanguageManagement.Data; |
|||
|
|||
public class LanguageManagementDataSeedContributor : ITransientDependency, IDataSeedContributor |
|||
{ |
|||
private readonly ILanguageRepository _languageRepository; |
|||
private readonly AbpLocalizationOptions _localizationOptions; |
|||
private readonly IDataFilter<ISoftDelete> _softDeleteFilter; |
|||
private readonly IGuidGenerator _guidGenerator; |
|||
private readonly ISettingManager _settingManager; |
|||
public LanguageManagementDataSeedContributor( |
|||
ILanguageRepository languageRepository, |
|||
IOptions<AbpLocalizationOptions> localizationOptions, |
|||
IDataFilter<ISoftDelete> softDeleteFilter, |
|||
IGuidGenerator guidGenerator, |
|||
ISettingManager settingManager) |
|||
{ |
|||
_languageRepository = languageRepository; |
|||
_softDeleteFilter = softDeleteFilter; |
|||
_guidGenerator = guidGenerator; |
|||
_settingManager = settingManager; |
|||
_localizationOptions = localizationOptions.Value; |
|||
} |
|||
|
|||
public async Task SeedAsync(DataSeedContext context) |
|||
{ |
|||
var defaultLanguage = await _settingManager.GetOrNullDefaultAsync(LanguageManagementConsts.SettingDefaultLanguage); |
|||
using (_softDeleteFilter.Disable()) |
|||
{ |
|||
var languages = await _languageRepository.GetListAsync(); |
|||
foreach (var language in _localizationOptions.Languages) |
|||
{ |
|||
if (!languages.Any(e => e.CultureName == language.CultureName && e.UiCultureName == language.UiCultureName)) |
|||
{ |
|||
var isDefault = language.CultureName == defaultLanguage; |
|||
await _languageRepository.InsertAsync( |
|||
new Language( |
|||
_guidGenerator.Create(), |
|||
language.CultureName, |
|||
language.UiCultureName, |
|||
language.DisplayName, |
|||
language.FlagIcon, |
|||
true, |
|||
isDefault)); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,28 @@ |
|||
using Lion.AbpPro.LanguageManagement.Languages; |
|||
|
|||
namespace Lion.AbpPro.LanguageManagement; |
|||
|
|||
[Dependency(ReplaceServices = true)] |
|||
public class DatabaseLanguageProvider : ILanguageProvider, ITransientDependency |
|||
{ |
|||
private readonly ILanguageManager _languageManager; |
|||
private readonly IDistributedCache<LanguageListCacheItem> _distributedCache; |
|||
private readonly IObjectMapper _objectMapper; |
|||
|
|||
public DatabaseLanguageProvider(ILanguageManager languageManager, IDistributedCache<LanguageListCacheItem> distributedCache, IObjectMapper objectMapper) |
|||
{ |
|||
_languageManager = languageManager; |
|||
_distributedCache = distributedCache; |
|||
_objectMapper = objectMapper; |
|||
} |
|||
|
|||
public virtual async Task<IReadOnlyList<LanguageInfo>> GetLanguagesAsync() |
|||
{ |
|||
var result = await _distributedCache.GetOrAddAsync(LanguageListCacheItem.CalculateCacheKey(), async () => |
|||
{ |
|||
var languages = await _languageManager.ListAsync(true); |
|||
return new LanguageListCacheItem(_objectMapper.Map<List<Language>, List<LanguageInfo>>(languages)); |
|||
}); |
|||
return result.Languages; |
|||
} |
|||
} |
|||
@ -0,0 +1,38 @@ |
|||
namespace Lion.AbpPro.LanguageManagement; |
|||
|
|||
public class DynamicLocalizationResourceContributor : ILocalizationResourceContributor |
|||
{ |
|||
private IDynamicResourceLocalizer DynamicResourceLocalizer; |
|||
private LocalizationResourceBase Resource; |
|||
|
|||
public bool IsDynamic => true; |
|||
|
|||
public void Initialize(LocalizationResourceInitializationContext context) |
|||
{ |
|||
Resource = context.Resource; |
|||
DynamicResourceLocalizer = context.ServiceProvider.GetRequiredService<IDynamicResourceLocalizer>(); |
|||
} |
|||
|
|||
public LocalizedString GetOrNull(string cultureName, string name) |
|||
{ |
|||
return DynamicResourceLocalizer.GetOrNull(Resource, cultureName, name); |
|||
} |
|||
|
|||
public void Fill(string cultureName, Dictionary<string, LocalizedString> dictionary) |
|||
{ |
|||
DynamicResourceLocalizer.Fill(Resource, cultureName, dictionary); |
|||
} |
|||
|
|||
public Task FillAsync(string cultureName, Dictionary<string, LocalizedString> dictionary) |
|||
{ |
|||
DynamicResourceLocalizer.Fill(Resource, cultureName, dictionary); |
|||
return Task.CompletedTask; |
|||
} |
|||
|
|||
public async Task<IEnumerable<string>> GetSupportedCulturesAsync() |
|||
{ |
|||
// TODO
|
|||
await Task.CompletedTask; |
|||
return null; |
|||
} |
|||
} |
|||
@ -0,0 +1,54 @@ |
|||
using Lion.AbpPro.LanguageManagement.LanguageTexts; |
|||
|
|||
namespace Lion.AbpPro.LanguageManagement; |
|||
|
|||
/// <summary>
|
|||
/// 动态资源
|
|||
/// </summary>
|
|||
public class DynamicResourceLocalizer : IDynamicResourceLocalizer, ISingletonDependency |
|||
{ |
|||
private readonly ILanguageTextManager _languageTextManager; |
|||
private readonly IDistributedCache<LanguageTextCacheItem> _distributedCache; |
|||
|
|||
public DynamicResourceLocalizer(ILanguageTextManager languageTextManager, IDistributedCache<LanguageTextCacheItem> distributedCache) |
|||
{ |
|||
_languageTextManager = languageTextManager; |
|||
_distributedCache = distributedCache; |
|||
} |
|||
|
|||
public LocalizedString GetOrNull(LocalizationResourceBase resource, string cultureName, string name) |
|||
{ |
|||
var languageText = GetCacheLanguageText(resource, cultureName).GetAwaiter().GetResult(); |
|||
var value = languageText.Dictionary.GetOrDefault(name); |
|||
if (value == null) return null; |
|||
return new LocalizedString(name, value); |
|||
} |
|||
|
|||
public void Fill(LocalizationResourceBase resource, string cultureName, Dictionary<string, LocalizedString> dictionary) |
|||
{ |
|||
var languageText = GetCacheLanguageText(resource, cultureName).GetAwaiter().GetResult(); |
|||
foreach (var keyValuePair in languageText.Dictionary) |
|||
{ |
|||
dictionary[keyValuePair.Key] = new LocalizedString(keyValuePair.Key, keyValuePair.Value); |
|||
} |
|||
} |
|||
|
|||
protected virtual async Task<LanguageTextCacheItem> GetCacheLanguageText(LocalizationResourceBase resource, string cultureName) |
|||
{ |
|||
var result = await _distributedCache.GetOrAddAsync(LanguageTextCacheItem.CalculateCacheKey(resource.ResourceName, cultureName), |
|||
async () => await CreateCacheLanguageText(resource, cultureName)); |
|||
return result; |
|||
} |
|||
|
|||
protected virtual async Task<LanguageTextCacheItem> CreateCacheLanguageText(LocalizationResourceBase resource, string cultureName) |
|||
{ |
|||
var languageTexts = await _languageTextManager.FindAsync(cultureName, resource.ResourceName); |
|||
var result = new LanguageTextCacheItem(); |
|||
foreach (var languageText in languageTexts) |
|||
{ |
|||
result.Dictionary[languageText.Name] = languageText.Value; |
|||
} |
|||
|
|||
return result; |
|||
} |
|||
} |
|||
@ -0,0 +1,3 @@ |
|||
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd"> |
|||
<ConfigureAwait ContinueOnCapturedContext="false" /> |
|||
</Weavers> |
|||
@ -0,0 +1,30 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> |
|||
<!-- This file was generated by Fody. Manual changes to this file will be lost when your project is rebuilt. --> |
|||
<xs:element name="Weavers"> |
|||
<xs:complexType> |
|||
<xs:all> |
|||
<xs:element name="ConfigureAwait" minOccurs="0" maxOccurs="1"> |
|||
<xs:complexType> |
|||
<xs:attribute name="ContinueOnCapturedContext" type="xs:boolean" /> |
|||
</xs:complexType> |
|||
</xs:element> |
|||
</xs:all> |
|||
<xs:attribute name="VerifyAssembly" type="xs:boolean"> |
|||
<xs:annotation> |
|||
<xs:documentation>'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed.</xs:documentation> |
|||
</xs:annotation> |
|||
</xs:attribute> |
|||
<xs:attribute name="VerifyIgnoreCodes" type="xs:string"> |
|||
<xs:annotation> |
|||
<xs:documentation>A comma-separated list of error codes that can be safely ignored in assembly verification.</xs:documentation> |
|||
</xs:annotation> |
|||
</xs:attribute> |
|||
<xs:attribute name="GenerateXsd" type="xs:boolean"> |
|||
<xs:annotation> |
|||
<xs:documentation>'false' to turn off automatic generation of the XML Schema file.</xs:documentation> |
|||
</xs:annotation> |
|||
</xs:attribute> |
|||
</xs:complexType> |
|||
</xs:element> |
|||
</xs:schema> |
|||
@ -0,0 +1,36 @@ |
|||
// Global using directives
|
|||
|
|||
global using System; |
|||
global using System.Collections.Generic; |
|||
global using System.ComponentModel.DataAnnotations; |
|||
global using System.Linq; |
|||
global using System.Threading; |
|||
global using System.Threading.Tasks; |
|||
global using AutoMapper; |
|||
global using Lion.AbpPro.Core; |
|||
global using Lion.AbpPro.LanguageManagement.Languages.Aggregates; |
|||
global using Lion.AbpPro.LanguageManagement.LanguageTexts.Aggregates; |
|||
global using Microsoft.Extensions.DependencyInjection; |
|||
global using Microsoft.Extensions.Localization; |
|||
global using Microsoft.Extensions.Logging; |
|||
global using Microsoft.Extensions.Options; |
|||
global using Volo.Abp; |
|||
global using Volo.Abp.AutoMapper; |
|||
global using Volo.Abp.Caching; |
|||
global using Volo.Abp.Data; |
|||
global using Volo.Abp.DependencyInjection; |
|||
global using Volo.Abp.Domain; |
|||
global using Volo.Abp.Domain.Entities.Auditing; |
|||
global using Volo.Abp.Domain.Entities.Events; |
|||
global using Volo.Abp.Domain.Repositories; |
|||
global using Volo.Abp.Domain.Services; |
|||
global using Volo.Abp.EventBus; |
|||
global using Volo.Abp.EventBus.Distributed; |
|||
global using Volo.Abp.Guids; |
|||
global using Volo.Abp.Localization; |
|||
global using Volo.Abp.Localization.External; |
|||
global using Volo.Abp.Modularity; |
|||
global using Volo.Abp.MultiTenancy; |
|||
global using Volo.Abp.ObjectMapping; |
|||
global using Volo.Abp.Settings; |
|||
global using Volo.Abp.Uow; |
|||
@ -0,0 +1,8 @@ |
|||
namespace Lion.AbpPro.LanguageManagement; |
|||
|
|||
public interface IDynamicResourceLocalizer |
|||
{ |
|||
LocalizedString GetOrNull(LocalizationResourceBase resource, string cultureName, string name); |
|||
|
|||
void Fill(LocalizationResourceBase resource, string cultureName, Dictionary<string, LocalizedString> dictionary); |
|||
} |
|||
@ -0,0 +1,18 @@ |
|||
namespace Lion.AbpPro.LanguageManagement; |
|||
|
|||
public interface ILocalizationHelper |
|||
{ |
|||
/// <summary>
|
|||
/// 资源是否有效
|
|||
/// </summary>
|
|||
Task<bool> IsValidResourceName(string resourceName); |
|||
|
|||
/// <summary>
|
|||
/// 获取所有资源名
|
|||
/// </summary>
|
|||
Task<List<string>> GetAllResourceName(); |
|||
|
|||
IStringLocalizer GetLocalizer(LocalizationResource resource); |
|||
IStringLocalizer GetLocalizer(string recourseName); |
|||
LocalizationResource GetLocalizationResource(string resourceName); |
|||
} |
|||
@ -0,0 +1,11 @@ |
|||
namespace Lion.AbpPro.LanguageManagement |
|||
{ |
|||
public static class LanguageManagementDbProperties |
|||
{ |
|||
public static string DbTablePrefix { get; set; } = "Abp"; |
|||
|
|||
public static string DbSchema { get; set; } = null; |
|||
|
|||
public const string ConnectionStringName = "LanguageManagement"; |
|||
} |
|||
} |
|||
@ -0,0 +1,15 @@ |
|||
using Lion.AbpPro.LanguageManagement.Languages; |
|||
using Lion.AbpPro.LanguageManagement.LanguageTexts; |
|||
|
|||
namespace Lion.AbpPro.LanguageManagement |
|||
{ |
|||
public class LanguageManagementDomainAutoMapperProfile : Profile |
|||
{ |
|||
public LanguageManagementDomainAutoMapperProfile() |
|||
{ |
|||
CreateMap<Language, LanguageDto>(); |
|||
CreateMap<LanguageText, LanguageTextDto>(); |
|||
CreateMap<Language, LanguageInfo>(); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,26 @@ |
|||
using Volo.Abp.SettingManagement; |
|||
|
|||
namespace Lion.AbpPro.LanguageManagement |
|||
{ |
|||
[DependsOn( |
|||
typeof(AbpDddDomainModule), |
|||
typeof(LanguageManagementDomainSharedModule), |
|||
typeof(AbpCachingModule), |
|||
typeof(AbpAutoMapperModule), |
|||
typeof(AbpSettingManagementDomainModule) |
|||
)] |
|||
public class LanguageManagementDomainModule : AbpModule |
|||
{ |
|||
public override void ConfigureServices(ServiceConfigurationContext context) |
|||
{ |
|||
Configure<AbpLocalizationOptions>(options => |
|||
{ |
|||
options.AddDynamicResource(); |
|||
}); |
|||
Configure<AbpAutoMapperOptions>(options => |
|||
{ |
|||
options.AddMaps<LanguageManagementDomainModule>(); |
|||
}); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,31 @@ |
|||
using IObjectMapper = Volo.Abp.ObjectMapping.IObjectMapper; |
|||
|
|||
namespace Lion.AbpPro.LanguageManagement |
|||
{ |
|||
public abstract class LanguageManagementDomainService : DomainService |
|||
{ |
|||
protected Type ObjectMapperContext { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 工作单元管理器
|
|||
/// </summary>
|
|||
protected IUnitOfWorkManager UnitOfWorkManager => |
|||
LazyServiceProvider.LazyGetRequiredService<IUnitOfWorkManager>(); |
|||
|
|||
/// <summary>
|
|||
/// 分布式事件总线
|
|||
/// </summary>
|
|||
protected IDistributedEventBus DistributedEventBus => |
|||
LazyServiceProvider.LazyGetRequiredService<IDistributedEventBus>(); |
|||
|
|||
/// <summary>
|
|||
/// 对象映射器
|
|||
/// </summary>
|
|||
protected IObjectMapper ObjectMapper => LazyServiceProvider.LazyGetService<IObjectMapper>( |
|||
provider => |
|||
ObjectMapperContext == null |
|||
? provider.GetRequiredService<IObjectMapper>() |
|||
: (IObjectMapper)provider.GetRequiredService( |
|||
typeof(IObjectMapper<>).MakeGenericType(ObjectMapperContext))); |
|||
} |
|||
} |
|||
@ -0,0 +1,102 @@ |
|||
namespace Lion.AbpPro.LanguageManagement.LanguageTexts.Aggregates; |
|||
|
|||
public class LanguageText : FullAuditedAggregateRoot<Guid>, IMultiTenant |
|||
{ |
|||
private LanguageText() |
|||
{ |
|||
} |
|||
|
|||
|
|||
public LanguageText( |
|||
Guid id, |
|||
string cultureName, |
|||
string resourceName, |
|||
string name, |
|||
string value, |
|||
Guid? tenantId = null |
|||
) : base(id) |
|||
{ |
|||
SetResourceName(resourceName); |
|||
SetCultureName(cultureName); |
|||
SetName(name); |
|||
SetValue(value); |
|||
TenantId = tenantId; |
|||
} |
|||
|
|||
public Guid? TenantId { get; private set; } |
|||
|
|||
/// <summary>
|
|||
/// 语言名称
|
|||
/// </summary>
|
|||
public string CultureName { get; private set; } |
|||
|
|||
|
|||
/// <summary>
|
|||
/// 资源名称
|
|||
/// </summary>
|
|||
public string ResourceName { get; private set; } |
|||
|
|||
|
|||
/// <summary>
|
|||
/// 名称
|
|||
/// </summary>
|
|||
public string Name { get; private set; } |
|||
|
|||
/// <summary>
|
|||
/// 值
|
|||
/// </summary>
|
|||
public string Value { get; private set; } |
|||
|
|||
|
|||
/// <summary>
|
|||
/// 设置资源名称
|
|||
/// </summary>
|
|||
private void SetResourceName(string resourceName) |
|||
{ |
|||
Guard.NotNullOrWhiteSpace(resourceName, nameof(resourceName), 128); |
|||
ResourceName = resourceName; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 设置语言名称
|
|||
/// </summary>
|
|||
private void SetCultureName(string cultureName) |
|||
{ |
|||
Guard.NotNullOrWhiteSpace(cultureName, nameof(cultureName), 128); |
|||
CultureName = cultureName; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 设置名称
|
|||
/// </summary>
|
|||
private void SetName(string name) |
|||
{ |
|||
Guard.NotNullOrWhiteSpace(name, nameof(name), 256); |
|||
Name = name; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 设置值
|
|||
/// </summary>
|
|||
private void SetValue(string value) |
|||
{ |
|||
Guard.NotNullOrWhiteSpace(value, nameof(value), 256); |
|||
Value = value; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 更新语言文本
|
|||
/// </summary>
|
|||
public void Update( |
|||
string cultureName, |
|||
string resourceName, |
|||
string name, |
|||
string value |
|||
) |
|||
{ |
|||
SetResourceName(resourceName); |
|||
SetCultureName(cultureName); |
|||
SetName(name); |
|||
SetValue(value); |
|||
} |
|||
} |
|||
@ -0,0 +1,16 @@ |
|||
namespace Lion.AbpPro.LanguageManagement.LanguageTexts.Caches; |
|||
|
|||
public class LanguageTexCacheInvalidator : ILocalEventHandler<EntityChangedEventData<LanguageText>>, ITransientDependency |
|||
{ |
|||
private readonly IDistributedCache<LanguageTextCacheItem> _distributedCache; |
|||
|
|||
public LanguageTexCacheInvalidator(IDistributedCache<LanguageTextCacheItem> distributedCache) |
|||
{ |
|||
_distributedCache = distributedCache; |
|||
} |
|||
|
|||
public virtual async Task HandleEventAsync(EntityChangedEventData<LanguageText> eventData) |
|||
{ |
|||
await _distributedCache.RemoveAsync(LanguageTextCacheItem.CalculateCacheKey(eventData.Entity.ResourceName, eventData.Entity.CultureName)); |
|||
} |
|||
} |
|||
@ -0,0 +1,48 @@ |
|||
namespace Lion.AbpPro.LanguageManagement.LanguageTexts; |
|||
|
|||
public interface ILanguageTextManager |
|||
{ |
|||
/// <summary>
|
|||
/// 查询语言文本
|
|||
/// </summary>
|
|||
/// <param name="cultureName">语言</param>
|
|||
/// <param name="resourceName">资源名称</param>
|
|||
/// <param name="filter">筛选条件:name or value</param>
|
|||
/// <param name="maxResultCount">返回最大条数</param>
|
|||
/// <param name="skipCount">跳过条数</param>
|
|||
Task<List<LanguageTextDto>> ListAsync(string cultureName, string resourceName, string filter = null, int maxResultCount = 10, int skipCount = 0); |
|||
|
|||
/// <summary>
|
|||
/// 查询语言文本数量
|
|||
/// </summary>
|
|||
/// <param name="cultureName">语言</param>
|
|||
/// <param name="resourceName">资源名称</param>
|
|||
/// <param name="filter">筛选条件:name or value</param>
|
|||
Task<long> CountAsync(string cultureName, string resourceName, string filter = null); |
|||
|
|||
/// <summary>
|
|||
/// 创建语言文本
|
|||
/// </summary>
|
|||
Task<LanguageTextDto> CreateAsync(Guid id, string cultureName, string resourceName, string name, string value); |
|||
|
|||
/// <summary>
|
|||
/// 更新语言文本
|
|||
/// </summary>
|
|||
/// <param name="cultureName">语言</param>
|
|||
/// <param name="resourceName">资源名称</param>
|
|||
/// <param name="name">键</param>
|
|||
/// <param name="value">值</param>
|
|||
Task<LanguageTextDto> UpdateAsync(string cultureName, string resourceName, string name, string value); |
|||
|
|||
/// <summary>
|
|||
/// 删除语言文本
|
|||
/// </summary>
|
|||
Task DeleteAsync(Guid id); |
|||
|
|||
/// <summary>
|
|||
/// 根据资源名称和语言名称查询语言文本
|
|||
/// </summary>
|
|||
/// <param name="cultureName">语言</param>
|
|||
/// <param name="resourceName">资源名称</param>
|
|||
Task<List<LanguageTextDto>> FindAsync(string cultureName, string resourceName); |
|||
} |
|||
@ -0,0 +1,36 @@ |
|||
namespace Lion.AbpPro.LanguageManagement.LanguageTexts; |
|||
|
|||
public interface ILanguageTextRepository : IBasicRepository<LanguageText, Guid> |
|||
{ |
|||
/// <summary>
|
|||
/// 查询语言文本
|
|||
/// </summary>
|
|||
/// <param name="cultureName">语言</param>
|
|||
/// <param name="resourceName">资源名称</param>
|
|||
/// <param name="filter">筛选条件:name or value</param>
|
|||
/// <param name="maxResultCount">返回最大条数</param>
|
|||
/// <param name="skipCount">跳过条数</param>
|
|||
Task<List<LanguageText>> ListAsync(string cultureName, string resourceName, string filter = null, int maxResultCount = 10, int skipCount = 0); |
|||
|
|||
/// <summary>
|
|||
/// 查询语言文本数量
|
|||
/// </summary>
|
|||
/// <param name="cultureName">语言</param>
|
|||
/// <param name="resourceName">资源名称</param>
|
|||
/// <param name="filter">筛选条件:name or value</param>
|
|||
Task<long> CountAsync(string cultureName, string resourceName, string filter = null); |
|||
|
|||
/// <summary>
|
|||
/// 查询语言文本
|
|||
/// </summary>
|
|||
Task<List<LanguageText>> FindAsync(string cultureName, string resourceName); |
|||
|
|||
/// <summary>
|
|||
/// 查询语言文本
|
|||
/// </summary>
|
|||
/// <param name="cultureName">语言</param>
|
|||
/// <param name="resourceName">资源名称</param>
|
|||
/// <param name="name">名称</param>
|
|||
Task<LanguageText> FindAsync(string cultureName, string resourceName, string name); |
|||
|
|||
} |
|||
@ -0,0 +1,97 @@ |
|||
namespace Lion.AbpPro.LanguageManagement.LanguageTexts; |
|||
|
|||
public class LanguageTextManager : LanguageManagementDomainService, ILanguageTextManager |
|||
{ |
|||
private readonly ILanguageTextRepository _languageTextRepository; |
|||
private readonly IObjectMapper _objectMapper; |
|||
|
|||
public LanguageTextManager(ILanguageTextRepository languageTextRepository, IObjectMapper objectMapper) |
|||
{ |
|||
_languageTextRepository = languageTextRepository; |
|||
_objectMapper = objectMapper; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 查询语言文本
|
|||
/// </summary>
|
|||
/// <param name="cultureName">语言</param>
|
|||
/// <param name="resourceName">资源名称</param>
|
|||
/// <param name="filter">筛选条件:name or value</param>
|
|||
/// <param name="maxResultCount">返回最大条数</param>
|
|||
/// <param name="skipCount">跳过条数</param>
|
|||
public async Task<List<LanguageTextDto>> ListAsync(string cultureName, string resourceName, string filter = null, int maxResultCount = 10, int skipCount = 0) |
|||
{ |
|||
var list = await _languageTextRepository.ListAsync(cultureName, resourceName, filter, maxResultCount, skipCount); |
|||
return ObjectMapper.Map<List<LanguageText>, List<LanguageTextDto>>(list); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 查询语言文本数量
|
|||
/// </summary>
|
|||
/// <param name="cultureName">语言</param>
|
|||
/// <param name="resourceName">资源名称</param>
|
|||
/// <param name="filter">筛选条件:name or value</param>
|
|||
public async Task<long> CountAsync(string cultureName, string resourceName, string filter = null) |
|||
{ |
|||
return await _languageTextRepository.CountAsync(cultureName, resourceName, filter); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 创建语言文本
|
|||
/// </summary>
|
|||
public async Task<LanguageTextDto> CreateAsync(Guid id, string cultureName, string resourceName, string name, string value) |
|||
{ |
|||
var entity = await _languageTextRepository.FindAsync(cultureName, resourceName, name); |
|||
if (entity != null) |
|||
{ |
|||
throw new LanguageManagementDomainException(LanguageManagementErrorCodes.LanguageTextExist).WithData("Name", name); |
|||
} |
|||
|
|||
entity = new LanguageText(id, cultureName, resourceName, name, value, CurrentTenant.Id); |
|||
entity = await _languageTextRepository.InsertAsync(entity); |
|||
return _objectMapper.Map<LanguageText, LanguageTextDto>(entity); |
|||
} |
|||
|
|||
|
|||
/// <summary>
|
|||
/// 更新语言文本
|
|||
/// </summary>
|
|||
/// <param name="cultureName">语言</param>
|
|||
/// <param name="resourceName">资源名称</param>
|
|||
/// <param name="name">键</param>
|
|||
/// <param name="value">值</param>
|
|||
public async Task<LanguageTextDto> UpdateAsync(string cultureName, string resourceName, string name, string value) |
|||
{ |
|||
var entity = await _languageTextRepository.FindAsync(cultureName, resourceName, name); |
|||
if (entity == null) |
|||
{ |
|||
entity = new LanguageText(GuidGenerator.Create(), cultureName, resourceName, name, value, CurrentTenant.Id); |
|||
await _languageTextRepository.InsertAsync(entity); |
|||
} |
|||
|
|||
entity.Update(cultureName, resourceName, name, value); |
|||
entity = await _languageTextRepository.UpdateAsync(entity); |
|||
return _objectMapper.Map<LanguageText, LanguageTextDto>(entity); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 删除语言文本
|
|||
/// </summary>
|
|||
public async Task DeleteAsync(Guid id) |
|||
{ |
|||
var entity = await _languageTextRepository.FindAsync(id); |
|||
if (entity == null) throw new LanguageManagementDomainException(LanguageManagementErrorCodes.LanguageNotFound); |
|||
await _languageTextRepository.DeleteAsync(entity); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 根据资源名称和语言名称查询语言文本
|
|||
/// </summary>
|
|||
/// <param name="cultureName">语言</param>
|
|||
/// <param name="resourceName">资源名称</param>
|
|||
public virtual async Task<List<LanguageTextDto>> FindAsync(string cultureName, string resourceName) |
|||
{ |
|||
var languageTexts = await _languageTextRepository.FindAsync(cultureName, resourceName); |
|||
return _objectMapper.Map<List<LanguageText>, List<LanguageTextDto>>(languageTexts); |
|||
} |
|||
} |
|||
@ -0,0 +1,124 @@ |
|||
namespace Lion.AbpPro.LanguageManagement.Languages.Aggregates; |
|||
|
|||
public class Language : FullAuditedAggregateRoot<Guid>, ILanguageInfo |
|||
{ |
|||
private Language() |
|||
{ |
|||
} |
|||
|
|||
|
|||
public Language( |
|||
Guid id, |
|||
string cultureName, |
|||
string uiCultureName, |
|||
string displayName, |
|||
string flagIcon, |
|||
bool isEnabled, |
|||
bool isDefault |
|||
) : base(id) |
|||
{ |
|||
SetCultureName(cultureName); |
|||
SetUiCultureName(uiCultureName); |
|||
SetDisplayName(displayName); |
|||
SetFlagIcon(flagIcon); |
|||
SetEnabled(isEnabled); |
|||
SetDefault(isDefault); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 语言名称
|
|||
/// </summary>
|
|||
public string CultureName { get; private set; } |
|||
|
|||
/// <summary>
|
|||
/// Ui语言名称
|
|||
/// </summary>
|
|||
public string UiCultureName { get; private set; } |
|||
|
|||
/// <summary>
|
|||
/// 显示名称
|
|||
/// </summary>
|
|||
public string DisplayName { get; private set; } |
|||
|
|||
/// <summary>
|
|||
/// 图标
|
|||
/// </summary>
|
|||
public string FlagIcon { get; private set; } |
|||
|
|||
/// <summary>
|
|||
/// 是否启用
|
|||
/// </summary>
|
|||
public bool IsEnabled { get; private set; } |
|||
|
|||
/// <summary>
|
|||
/// 是否默认语言
|
|||
/// </summary>
|
|||
public bool IsDefault { get; private set; } |
|||
|
|||
/// <summary>
|
|||
/// 设置语言名称
|
|||
/// </summary>
|
|||
private void SetCultureName(string cultureName) |
|||
{ |
|||
Guard.NotNullOrWhiteSpace(cultureName, nameof(cultureName), 128, 0); |
|||
CultureName = cultureName; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 设置Ui语言名称
|
|||
/// </summary>
|
|||
private void SetUiCultureName(string uiCultureName) |
|||
{ |
|||
Guard.NotNullOrWhiteSpace(uiCultureName, nameof(uiCultureName), 128, 0); |
|||
UiCultureName = uiCultureName; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 设置显示名称
|
|||
/// </summary>
|
|||
private void SetDisplayName(string displayName) |
|||
{ |
|||
Guard.NotNullOrWhiteSpace(displayName, nameof(displayName), 128, 0); |
|||
DisplayName = displayName; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 设置图标
|
|||
/// </summary>
|
|||
private void SetFlagIcon(string flagIcon) |
|||
{ |
|||
Guard.Length(flagIcon, nameof(flagIcon), 128, 0); |
|||
FlagIcon = flagIcon; |
|||
} |
|||
|
|||
private void SetEnabled(bool isEnabled) |
|||
{ |
|||
IsEnabled = isEnabled; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 更新语言
|
|||
/// </summary>
|
|||
public void Update( |
|||
string cultureName, |
|||
string uiCultureName, |
|||
string displayName, |
|||
string flagIcon, |
|||
bool isEnabled = true, |
|||
bool isDefault = false |
|||
) |
|||
{ |
|||
SetCultureName(cultureName); |
|||
SetUiCultureName(uiCultureName); |
|||
SetDisplayName(displayName); |
|||
SetFlagIcon(flagIcon); |
|||
SetEnabled(isEnabled); |
|||
SetDefault(isDefault); |
|||
} |
|||
|
|||
|
|||
public void SetDefault(bool isDefault) |
|||
{ |
|||
IsDefault = isDefault; |
|||
} |
|||
} |
|||
Some files were not shown because too many files changed in this diff
Loading…
Reference in new issue