331 changed files with 44993 additions and 0 deletions
@ -0,0 +1 @@ |
|||
**/wwwroot/libs/** linguist-vendored |
@ -0,0 +1,265 @@ |
|||
## Ignore Visual Studio temporary files, build results, and |
|||
## files generated by popular Visual Studio add-ons. |
|||
|
|||
# User-specific files |
|||
*.suo |
|||
*.user |
|||
*.userosscache |
|||
*.sln.docstates |
|||
|
|||
# User-specific files (MonoDevelop/Xamarin Studio) |
|||
*.userprefs |
|||
|
|||
# Build results |
|||
[Dd]ebug/ |
|||
[Dd]ebugPublic/ |
|||
[Rr]elease/ |
|||
[Rr]eleases/ |
|||
x64/ |
|||
x86/ |
|||
bld/ |
|||
[Bb]in/ |
|||
[Oo]bj/ |
|||
[Ll]og/ |
|||
|
|||
# Visual Studio 2015 cache/options directory |
|||
.vs/ |
|||
# Uncomment if you have tasks that create the project's static files in wwwroot |
|||
#wwwroot/ |
|||
|
|||
# MSTest test Results |
|||
[Tt]est[Rr]esult*/ |
|||
[Bb]uild[Ll]og.* |
|||
|
|||
# NUNIT |
|||
*.VisualState.xml |
|||
TestResult.xml |
|||
|
|||
# Build Results of an ATL Project |
|||
[Dd]ebugPS/ |
|||
[Rr]eleasePS/ |
|||
dlldata.c |
|||
|
|||
# DNX |
|||
project.lock.json |
|||
artifacts/ |
|||
|
|||
*_i.c |
|||
*_p.c |
|||
*_i.h |
|||
*.ilk |
|||
*.meta |
|||
*.obj |
|||
*.pch |
|||
*.pdb |
|||
*.pgc |
|||
*.pgd |
|||
*.rsp |
|||
*.sbr |
|||
*.tlb |
|||
*.tli |
|||
*.tlh |
|||
*.tmp |
|||
*.tmp_proj |
|||
*.log |
|||
*.vspscc |
|||
*.vssscc |
|||
.builds |
|||
*.pidb |
|||
*.svclog |
|||
*.scc |
|||
|
|||
# Chutzpah Test files |
|||
_Chutzpah* |
|||
|
|||
# Visual C++ cache files |
|||
ipch/ |
|||
*.aps |
|||
*.ncb |
|||
*.opendb |
|||
*.opensdf |
|||
*.sdf |
|||
*.cachefile |
|||
*.VC.db |
|||
*.VC.VC.opendb |
|||
|
|||
# Visual Studio profiler |
|||
*.psess |
|||
*.vsp |
|||
*.vspx |
|||
*.sap |
|||
|
|||
# TFS 2012 Local Workspace |
|||
$tf/ |
|||
|
|||
# Guidance Automation Toolkit |
|||
*.gpState |
|||
|
|||
# ReSharper is a .NET coding add-in |
|||
_ReSharper*/ |
|||
*.[Rr]e[Ss]harper |
|||
*.DotSettings.user |
|||
|
|||
# JustCode is a .NET coding add-in |
|||
.JustCode |
|||
|
|||
# TeamCity is a build add-in |
|||
_TeamCity* |
|||
|
|||
# DotCover is a Code Coverage Tool |
|||
*.dotCover |
|||
|
|||
# NCrunch |
|||
_NCrunch_* |
|||
.*crunch*.local.xml |
|||
nCrunchTemp_* |
|||
|
|||
# MightyMoose |
|||
*.mm.* |
|||
AutoTest.Net/ |
|||
|
|||
# Web workbench (sass) |
|||
.sass-cache/ |
|||
|
|||
# Installshield output folder |
|||
[Ee]xpress/ |
|||
|
|||
# DocProject is a documentation generator add-in |
|||
DocProject/buildhelp/ |
|||
DocProject/Help/*.HxT |
|||
DocProject/Help/*.HxC |
|||
DocProject/Help/*.hhc |
|||
DocProject/Help/*.hhk |
|||
DocProject/Help/*.hhp |
|||
DocProject/Help/Html2 |
|||
DocProject/Help/html |
|||
|
|||
# Click-Once directory |
|||
publish/ |
|||
|
|||
# Publish Web Output |
|||
*.[Pp]ublish.xml |
|||
*.azurePubxml |
|||
# TODO: Comment the next line if you want to checkin your web deploy settings |
|||
# but database connection strings (with potential passwords) will be unencrypted |
|||
*.pubxml |
|||
*.publishproj |
|||
|
|||
# Microsoft Azure Web App publish settings. Comment the next line if you want to |
|||
# checkin your Azure Web App publish settings, but sensitive information contained |
|||
# in these scripts will be unencrypted |
|||
PublishScripts/ |
|||
|
|||
# NuGet Packages |
|||
*.nupkg |
|||
# The packages folder can be ignored because of Package Restore |
|||
**/packages/* |
|||
# except build/, which is used as an MSBuild target. |
|||
!**/packages/build/ |
|||
# Uncomment if necessary however generally it will be regenerated when needed |
|||
#!**/packages/repositories.config |
|||
# NuGet v3's project.json files produces more ignoreable files |
|||
*.nuget.props |
|||
*.nuget.targets |
|||
|
|||
# Microsoft Azure Build Output |
|||
csx/ |
|||
*.build.csdef |
|||
|
|||
# Microsoft Azure Emulator |
|||
ecf/ |
|||
rcf/ |
|||
|
|||
# Windows Store app package directories and files |
|||
AppPackages/ |
|||
BundleArtifacts/ |
|||
Package.StoreAssociation.xml |
|||
_pkginfo.txt |
|||
|
|||
# Visual Studio cache files |
|||
# files ending in .cache can be ignored |
|||
*.[Cc]ache |
|||
# but keep track of directories ending in .cache |
|||
!*.[Cc]ache/ |
|||
|
|||
# Others |
|||
ClientBin/ |
|||
~$* |
|||
*~ |
|||
*.dbmdl |
|||
*.dbproj.schemaview |
|||
*.pfx |
|||
*.publishsettings |
|||
node_modules/ |
|||
orleans.codegen.cs |
|||
|
|||
# Since there are multiple workflows, uncomment next line to ignore bower_components |
|||
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) |
|||
#bower_components/ |
|||
|
|||
# RIA/Silverlight projects |
|||
Generated_Code/ |
|||
|
|||
# Backup & report files from converting an old project file |
|||
# to a newer Visual Studio version. Backup files are not needed, |
|||
# because we have git ;-) |
|||
_UpgradeReport_Files/ |
|||
Backup*/ |
|||
UpgradeLog*.XML |
|||
UpgradeLog*.htm |
|||
|
|||
# SQL Server files |
|||
*.mdf |
|||
*.ldf |
|||
|
|||
# Business Intelligence projects |
|||
*.rdl.data |
|||
*.bim.layout |
|||
*.bim_*.settings |
|||
|
|||
# Microsoft Fakes |
|||
FakesAssemblies/ |
|||
|
|||
# GhostDoc plugin setting file |
|||
*.GhostDoc.xml |
|||
|
|||
# Node.js Tools for Visual Studio |
|||
.ntvs_analysis.dat |
|||
|
|||
# Visual Studio 6 build log |
|||
*.plg |
|||
|
|||
# Visual Studio 6 workspace options file |
|||
*.opt |
|||
|
|||
# Visual Studio LightSwitch build output |
|||
**/*.HTMLClient/GeneratedArtifacts |
|||
**/*.DesktopClient/GeneratedArtifacts |
|||
**/*.DesktopClient/ModelManifest.xml |
|||
**/*.Server/GeneratedArtifacts |
|||
**/*.Server/ModelManifest.xml |
|||
_Pvt_Extensions |
|||
|
|||
# Paket dependency manager |
|||
.paket/paket.exe |
|||
paket-files/ |
|||
|
|||
# FAKE - F# Make |
|||
.fake/ |
|||
|
|||
# JetBrains Rider |
|||
.idea/ |
|||
*.sln.iml |
|||
|
|||
# Dy_Exchange |
|||
src/Dy_Exchange.Web/Logs/* |
|||
src/Dy_Exchange.Web/Logs/* |
|||
src/Dy_Exchange.AuthServer/Logs/* |
|||
src/Dy_Exchange.HttpApi.Host/Logs/* |
|||
src/Dy_Exchange.HttpApi.HostWithIds/Logs/* |
|||
src/Dy_Exchange.DbMigrator/Logs/* |
|||
src/Dy_Exchange.Blazor.Server/Logs/* |
|||
src/Dy_Exchange.Blazor.Server.Tiered/Logs/* |
|||
|
|||
# Use abp install-libs to restore. |
|||
**/wwwroot/libs/* |
@ -0,0 +1,5 @@ |
|||
{ |
|||
"singleQuote": true, |
|||
"useTabs": false, |
|||
"tabWidth": 4 |
|||
} |
@ -0,0 +1,102 @@ |
|||
|
|||
Microsoft Visual Studio Solution File, Format Version 12.00 |
|||
# Visual Studio Version 17 |
|||
VisualStudioVersion = 17.10.35013.160 |
|||
MinimumVisualStudioVersion = 10.0.40219.1 |
|||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Dy_Exchange.Domain", "src\Dy_Exchange.Domain\Dy_Exchange.Domain.csproj", "{554AD327-6DBA-4F8F-96F8-81CE7A0C863F}" |
|||
EndProject |
|||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Dy_Exchange.Application", "src\Dy_Exchange.Application\Dy_Exchange.Application.csproj", "{1A94A50E-06DC-43C1-80B5-B662820EC3EB}" |
|||
EndProject |
|||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Dy_Exchange.EntityFrameworkCore", "src\Dy_Exchange.EntityFrameworkCore\Dy_Exchange.EntityFrameworkCore.csproj", "{C956DD76-69C8-4A9C-83EA-D17DF83340FD}" |
|||
EndProject |
|||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{CA9AC87F-097E-4F15-8393-4BC07735A5B0}" |
|||
EndProject |
|||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Dy_Exchange.Domain.Shared", "src\Dy_Exchange.Domain.Shared\Dy_Exchange.Domain.Shared.csproj", "{42F719ED-8413-4895-B5B4-5AB56079BC66}" |
|||
EndProject |
|||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Dy_Exchange.Application.Contracts", "src\Dy_Exchange.Application.Contracts\Dy_Exchange.Application.Contracts.csproj", "{520659C8-C734-4298-A3DA-B539DB9DFC0B}" |
|||
EndProject |
|||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Dy_Exchange.HttpApi", "src\Dy_Exchange.HttpApi\Dy_Exchange.HttpApi.csproj", "{4164BDF7-F527-4E85-9CE6-E3C2D7426A27}" |
|||
EndProject |
|||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Dy_Exchange.HttpApi.Client", "src\Dy_Exchange.HttpApi.Client\Dy_Exchange.HttpApi.Client.csproj", "{3B5A0094-670D-4BB1-BFDD-61B88A8773DC}" |
|||
EndProject |
|||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Dy_Exchange.Web", "src\Dy_Exchange.Web\Dy_Exchange.Web.csproj", "{6FE54035-9C11-4702-A5E2-D16F23101468}" |
|||
EndProject |
|||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Dy_Exchange.AuthServer", "src\Dy_Exchange.AuthServer\Dy_Exchange.AuthServer.csproj", "{073C361E-B8F4-49F5-93CC-72A3FF49C026}" |
|||
EndProject |
|||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Dy_Exchange.HttpApi.Host", "src\Dy_Exchange.HttpApi.Host\Dy_Exchange.HttpApi.Host.csproj", "{E6D5BF0E-DE92-4D82-A352-EF04B37CB11C}" |
|||
EndProject |
|||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Dy_Exchange.DbMigrator", "src\Dy_Exchange.DbMigrator\Dy_Exchange.DbMigrator.csproj", "{AA94D832-1CCC-4715-95A9-A483F23A1A5D}" |
|||
EndProject |
|||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "host", "host", "{A17E14E2-9727-4AD8-865B-6355732A7960}" |
|||
EndProject |
|||
Global |
|||
GlobalSection(SolutionConfigurationPlatforms) = preSolution |
|||
Debug|Any CPU = Debug|Any CPU |
|||
Release|Any CPU = Release|Any CPU |
|||
EndGlobalSection |
|||
GlobalSection(ProjectConfigurationPlatforms) = postSolution |
|||
{554AD327-6DBA-4F8F-96F8-81CE7A0C863F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
|||
{554AD327-6DBA-4F8F-96F8-81CE7A0C863F}.Debug|Any CPU.Build.0 = Debug|Any CPU |
|||
{554AD327-6DBA-4F8F-96F8-81CE7A0C863F}.Release|Any CPU.ActiveCfg = Release|Any CPU |
|||
{554AD327-6DBA-4F8F-96F8-81CE7A0C863F}.Release|Any CPU.Build.0 = Release|Any CPU |
|||
{1A94A50E-06DC-43C1-80B5-B662820EC3EB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
|||
{1A94A50E-06DC-43C1-80B5-B662820EC3EB}.Debug|Any CPU.Build.0 = Debug|Any CPU |
|||
{1A94A50E-06DC-43C1-80B5-B662820EC3EB}.Release|Any CPU.ActiveCfg = Release|Any CPU |
|||
{1A94A50E-06DC-43C1-80B5-B662820EC3EB}.Release|Any CPU.Build.0 = Release|Any CPU |
|||
{C956DD76-69C8-4A9C-83EA-D17DF83340FD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
|||
{C956DD76-69C8-4A9C-83EA-D17DF83340FD}.Debug|Any CPU.Build.0 = Debug|Any CPU |
|||
{C956DD76-69C8-4A9C-83EA-D17DF83340FD}.Release|Any CPU.ActiveCfg = Release|Any CPU |
|||
{C956DD76-69C8-4A9C-83EA-D17DF83340FD}.Release|Any CPU.Build.0 = Release|Any CPU |
|||
{42F719ED-8413-4895-B5B4-5AB56079BC66}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
|||
{42F719ED-8413-4895-B5B4-5AB56079BC66}.Debug|Any CPU.Build.0 = Debug|Any CPU |
|||
{42F719ED-8413-4895-B5B4-5AB56079BC66}.Release|Any CPU.ActiveCfg = Release|Any CPU |
|||
{42F719ED-8413-4895-B5B4-5AB56079BC66}.Release|Any CPU.Build.0 = Release|Any CPU |
|||
{520659C8-C734-4298-A3DA-B539DB9DFC0B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
|||
{520659C8-C734-4298-A3DA-B539DB9DFC0B}.Debug|Any CPU.Build.0 = Debug|Any CPU |
|||
{520659C8-C734-4298-A3DA-B539DB9DFC0B}.Release|Any CPU.ActiveCfg = Release|Any CPU |
|||
{520659C8-C734-4298-A3DA-B539DB9DFC0B}.Release|Any CPU.Build.0 = Release|Any CPU |
|||
{4164BDF7-F527-4E85-9CE6-E3C2D7426A27}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
|||
{4164BDF7-F527-4E85-9CE6-E3C2D7426A27}.Debug|Any CPU.Build.0 = Debug|Any CPU |
|||
{4164BDF7-F527-4E85-9CE6-E3C2D7426A27}.Release|Any CPU.ActiveCfg = Release|Any CPU |
|||
{4164BDF7-F527-4E85-9CE6-E3C2D7426A27}.Release|Any CPU.Build.0 = Release|Any CPU |
|||
{3B5A0094-670D-4BB1-BFDD-61B88A8773DC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
|||
{3B5A0094-670D-4BB1-BFDD-61B88A8773DC}.Debug|Any CPU.Build.0 = Debug|Any CPU |
|||
{3B5A0094-670D-4BB1-BFDD-61B88A8773DC}.Release|Any CPU.ActiveCfg = Release|Any CPU |
|||
{3B5A0094-670D-4BB1-BFDD-61B88A8773DC}.Release|Any CPU.Build.0 = Release|Any CPU |
|||
{6FE54035-9C11-4702-A5E2-D16F23101468}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
|||
{6FE54035-9C11-4702-A5E2-D16F23101468}.Debug|Any CPU.Build.0 = Debug|Any CPU |
|||
{6FE54035-9C11-4702-A5E2-D16F23101468}.Release|Any CPU.ActiveCfg = Release|Any CPU |
|||
{6FE54035-9C11-4702-A5E2-D16F23101468}.Release|Any CPU.Build.0 = Release|Any CPU |
|||
{073C361E-B8F4-49F5-93CC-72A3FF49C026}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
|||
{073C361E-B8F4-49F5-93CC-72A3FF49C026}.Debug|Any CPU.Build.0 = Debug|Any CPU |
|||
{073C361E-B8F4-49F5-93CC-72A3FF49C026}.Release|Any CPU.ActiveCfg = Release|Any CPU |
|||
{073C361E-B8F4-49F5-93CC-72A3FF49C026}.Release|Any CPU.Build.0 = Release|Any CPU |
|||
{E6D5BF0E-DE92-4D82-A352-EF04B37CB11C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
|||
{E6D5BF0E-DE92-4D82-A352-EF04B37CB11C}.Debug|Any CPU.Build.0 = Debug|Any CPU |
|||
{E6D5BF0E-DE92-4D82-A352-EF04B37CB11C}.Release|Any CPU.ActiveCfg = Release|Any CPU |
|||
{E6D5BF0E-DE92-4D82-A352-EF04B37CB11C}.Release|Any CPU.Build.0 = Release|Any CPU |
|||
{AA94D832-1CCC-4715-95A9-A483F23A1A5D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
|||
{AA94D832-1CCC-4715-95A9-A483F23A1A5D}.Debug|Any CPU.Build.0 = Debug|Any CPU |
|||
{AA94D832-1CCC-4715-95A9-A483F23A1A5D}.Release|Any CPU.ActiveCfg = Release|Any CPU |
|||
{AA94D832-1CCC-4715-95A9-A483F23A1A5D}.Release|Any CPU.Build.0 = Release|Any CPU |
|||
EndGlobalSection |
|||
GlobalSection(SolutionProperties) = preSolution |
|||
HideSolutionNode = FALSE |
|||
EndGlobalSection |
|||
GlobalSection(NestedProjects) = preSolution |
|||
{554AD327-6DBA-4F8F-96F8-81CE7A0C863F} = {CA9AC87F-097E-4F15-8393-4BC07735A5B0} |
|||
{1A94A50E-06DC-43C1-80B5-B662820EC3EB} = {CA9AC87F-097E-4F15-8393-4BC07735A5B0} |
|||
{C956DD76-69C8-4A9C-83EA-D17DF83340FD} = {CA9AC87F-097E-4F15-8393-4BC07735A5B0} |
|||
{42F719ED-8413-4895-B5B4-5AB56079BC66} = {CA9AC87F-097E-4F15-8393-4BC07735A5B0} |
|||
{520659C8-C734-4298-A3DA-B539DB9DFC0B} = {CA9AC87F-097E-4F15-8393-4BC07735A5B0} |
|||
{4164BDF7-F527-4E85-9CE6-E3C2D7426A27} = {CA9AC87F-097E-4F15-8393-4BC07735A5B0} |
|||
{3B5A0094-670D-4BB1-BFDD-61B88A8773DC} = {CA9AC87F-097E-4F15-8393-4BC07735A5B0} |
|||
{6FE54035-9C11-4702-A5E2-D16F23101468} = {A17E14E2-9727-4AD8-865B-6355732A7960} |
|||
{073C361E-B8F4-49F5-93CC-72A3FF49C026} = {A17E14E2-9727-4AD8-865B-6355732A7960} |
|||
{E6D5BF0E-DE92-4D82-A352-EF04B37CB11C} = {A17E14E2-9727-4AD8-865B-6355732A7960} |
|||
{AA94D832-1CCC-4715-95A9-A483F23A1A5D} = {CA9AC87F-097E-4F15-8393-4BC07735A5B0} |
|||
EndGlobalSection |
|||
GlobalSection(ExtensibilityGlobals) = postSolution |
|||
SolutionGuid = {28315BFD-90E7-4E14-A2EA-F3D23AF4126F} |
|||
EndGlobalSection |
|||
EndGlobal |
@ -0,0 +1,23 @@ |
|||
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation"> |
|||
<s:Boolean x:Key="/Default/CodeEditing/Intellisense/CodeCompletion/IntelliSenseCompletingCharacters/CSharpCompletingCharacters/UpgradedFromVSSettings/@EntryValue">True</s:Boolean> |
|||
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=EnforceDoWhileStatementBraces/@EntryIndexedValue">WARNING</s:String> |
|||
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=EnforceFixedStatementBraces/@EntryIndexedValue">WARNING</s:String> |
|||
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=EnforceForeachStatementBraces/@EntryIndexedValue">WARNING</s:String> |
|||
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=EnforceForStatementBraces/@EntryIndexedValue">WARNING</s:String> |
|||
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=EnforceIfStatementBraces/@EntryIndexedValue">WARNING</s:String> |
|||
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=EnforceLockStatementBraces/@EntryIndexedValue">WARNING</s:String> |
|||
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=EnforceUsingStatementBraces/@EntryIndexedValue">WARNING</s:String> |
|||
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=EnforceWhileStatementBraces/@EntryIndexedValue">WARNING</s:String> |
|||
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpCodeStyle/BRACES_FOR_FOR/@EntryValue">Required</s:String> |
|||
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpCodeStyle/BRACES_FOR_FOREACH/@EntryValue">Required</s:String> |
|||
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpCodeStyle/BRACES_FOR_IFELSE/@EntryValue">Required</s:String> |
|||
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpCodeStyle/BRACES_FOR_WHILE/@EntryValue">Required</s:String> |
|||
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpCodeStyle/BRACES_REDUNDANT/@EntryValue">False</s:Boolean> |
|||
<s:Boolean x:Key="/Default/CodeStyle/Generate/=Implementations/@KeyIndexDefined">True</s:Boolean> |
|||
<s:String x:Key="/Default/CodeStyle/Generate/=Implementations/Options/=Async/@EntryIndexedValue">False</s:String> |
|||
<s:String x:Key="/Default/CodeStyle/Generate/=Implementations/Options/=Mutable/@EntryIndexedValue">False</s:String> |
|||
<s:Boolean x:Key="/Default/CodeStyle/Generate/=Overrides/@KeyIndexDefined">True</s:Boolean> |
|||
<s:String x:Key="/Default/CodeStyle/Generate/=Overrides/Options/=Async/@EntryIndexedValue">False</s:String> |
|||
<s:String x:Key="/Default/CodeStyle/Generate/=Overrides/Options/=Mutable/@EntryIndexedValue">False</s:String> |
|||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=SQL/@EntryIndexedValue">SQL</s:String> |
|||
</wpf:ResourceDictionary> |
@ -0,0 +1,5 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
<configuration> |
|||
<packageSources> |
|||
</packageSources> |
|||
</configuration> |
@ -0,0 +1,19 @@ |
|||
<Project> |
|||
<PropertyGroup> |
|||
<LangVersion>latest</LangVersion> |
|||
<Version>1.0.0</Version> |
|||
<NoWarn>$(NoWarn);CS1591</NoWarn> |
|||
<AbpProjectType>app</AbpProjectType> |
|||
</PropertyGroup> |
|||
|
|||
<Target Name="NoWarnOnRazorViewImportedTypeConflicts" BeforeTargets="RazorCoreCompile"> |
|||
<PropertyGroup> |
|||
<NoWarn>$(NoWarn);0436</NoWarn> |
|||
</PropertyGroup> |
|||
</Target> |
|||
|
|||
<ItemGroup> |
|||
<Content Remove="$(UserProfile)\.nuget\packages\*\*\contentFiles\any\*\*.abppkg*.json" /> |
|||
</ItemGroup> |
|||
|
|||
</Project> |
@ -0,0 +1,10 @@ |
|||
using System; |
|||
using Volo.Abp.Application.Dtos; |
|||
|
|||
namespace WinIn.FasterZ.Inventory.AppBase.FasterBaseDto; |
|||
|
|||
[Serializable] |
|||
public class FasterAuditedEntityBaseDto<TPrimaryKey> : AuditedEntityDto<TPrimaryKey> |
|||
{ |
|||
public string ConcurrencyStamp { get; set; } = string.Empty; |
|||
} |
@ -0,0 +1,10 @@ |
|||
using System; |
|||
|
|||
namespace WinIn.FasterZ.Inventory.AppBase.FasterBaseDto; |
|||
|
|||
public class FasterCreateUpdateBaseDto |
|||
{ |
|||
public Guid Id { get; set; } |
|||
|
|||
public string ConcurrencyStamp { get; set; } = string.Empty; |
|||
} |
@ -0,0 +1,8 @@ |
|||
using System.Collections.Generic; |
|||
|
|||
namespace WinIn.FasterZ.Inventory.AppBase.Filters; |
|||
|
|||
public class Condition |
|||
{ |
|||
public List<Filter> Filters { get; set; } = new List<Filter>(); |
|||
} |
@ -0,0 +1,62 @@ |
|||
using System.ComponentModel; |
|||
|
|||
namespace WinIn.FasterZ.Inventory.AppBase.Filters; |
|||
|
|||
/// <summary>
|
|||
/// 过滤条件
|
|||
/// </summary>
|
|||
public enum EnumFilterAction |
|||
{ |
|||
/// <summary>
|
|||
/// equal
|
|||
/// </summary>
|
|||
[Description("等于")] Equal = 0, |
|||
|
|||
/// <summary>
|
|||
/// Not equal
|
|||
/// </summary>
|
|||
[Description("不等于")] NotEqual = 1, |
|||
|
|||
/// <summary>
|
|||
/// Bigger
|
|||
/// </summary>
|
|||
[Description("大于")] BiggerThan = 2, |
|||
|
|||
/// <summary>
|
|||
/// Smaller
|
|||
/// </summary>
|
|||
[Description("小于")] SmallThan = 3, |
|||
|
|||
/// <summary>
|
|||
/// Bigger or equal
|
|||
/// </summary>
|
|||
[Description("大于等于")] BiggerThanOrEqual = 4, |
|||
|
|||
/// <summary>
|
|||
/// Small or equal
|
|||
/// </summary>
|
|||
[Description("小于等于")] SmallThanOrEqual = 5, |
|||
|
|||
/// <summary>
|
|||
/// Like
|
|||
/// </summary>
|
|||
[Description("类似于")] Like = 6, |
|||
|
|||
/// <summary>
|
|||
/// Not like
|
|||
/// </summary>
|
|||
[Description("不类似于")] NotLike = 7, |
|||
|
|||
/// <summary>
|
|||
/// Contained in
|
|||
/// List<string > items = new List<string>();
|
|||
/// string value = JsonSerializer.Serialize(items);//转成Json字符串
|
|||
/// FilterCondition filterCondition = new FilterCondition() { Column = "Name", Value = value, Action = EnumFilterAction.In, Logic = EnumFilterLogic.And };
|
|||
/// </summary>
|
|||
[Description("包含于")] In = 8, |
|||
|
|||
/// <summary>
|
|||
/// Not contained in
|
|||
/// </summary>
|
|||
[Description("不包含于")] NotIn = 9, |
|||
} |
@ -0,0 +1,17 @@ |
|||
namespace WinIn.FasterZ.Inventory.AppBase.Filters; |
|||
|
|||
/// <summary>
|
|||
/// 过滤逻辑
|
|||
/// </summary>
|
|||
public enum EnumFilterLogic |
|||
{ |
|||
/// <summary>
|
|||
/// 与
|
|||
/// </summary>
|
|||
And = 0, |
|||
|
|||
/// <summary>
|
|||
/// 或
|
|||
/// </summary>
|
|||
Or = 1 |
|||
} |
@ -0,0 +1,40 @@ |
|||
namespace WinIn.FasterZ.Inventory.AppBase.Filters; |
|||
|
|||
public class Filter |
|||
{ |
|||
public Filter() |
|||
{ |
|||
Logic = "And"; |
|||
} |
|||
|
|||
public Filter(string column, string value, |
|||
string action = "==", |
|||
string logic = "And") |
|||
{ |
|||
Column = column; |
|||
Action = action; |
|||
Value = value; |
|||
Logic = logic; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 过滤条件之间的逻辑关系:AND和OR
|
|||
/// </summary>
|
|||
public string? Logic { get; set; } = "And"; |
|||
|
|||
/// <summary>
|
|||
/// 过滤条件中使用的数据列
|
|||
/// </summary>
|
|||
public string? Column { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 过滤条件中的操作:==,!=,>,<,>=,<=,In,NotIn,Like,NotLike
|
|||
/// Equal、NotEqual、BiggerThan、SmallThan、BiggerThanOrEqual、SmallThanOrEqual、In、NotIn
|
|||
/// </summary>
|
|||
public string? Action { get; set; } = "=="; |
|||
|
|||
/// <summary>
|
|||
/// 过滤条件中的操作的值
|
|||
/// </summary>
|
|||
public string? Value { get; set; } |
|||
} |
@ -0,0 +1,370 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Globalization; |
|||
using System.Linq; |
|||
using System.Linq.Expressions; |
|||
using System.Text.Json; |
|||
using Volo.Abp; |
|||
|
|||
namespace WinIn.FasterZ.Inventory.AppBase.Filters; |
|||
|
|||
public static class FilterExtensions |
|||
{ |
|||
public static Expression<Func<T, bool>> ToLambda<T>(this string jsonFilter) |
|||
{ |
|||
if (string.IsNullOrWhiteSpace(jsonFilter)) |
|||
{ |
|||
return p => true; |
|||
} |
|||
|
|||
var filterConditions = JsonSerializer.Deserialize<List<Filter>>(jsonFilter); |
|||
return filterConditions.ToLambda<T>(); |
|||
} |
|||
|
|||
public static Expression<Func<T, bool>> ToLambda<T>(this Filter filter) |
|||
{ |
|||
var filterConditions = new List<Filter> { filter }; |
|||
return filterConditions.ToLambda<T>(); |
|||
} |
|||
|
|||
public static Expression<Func<T, bool>> ToLambda<T>(this List<Filter> filterConditionList) |
|||
{ |
|||
Expression<Func<T, bool>> condition = null; |
|||
try |
|||
{ |
|||
if (!filterConditionList.Any()) |
|||
{ |
|||
//创建默认表达式
|
|||
return p => true; |
|||
} |
|||
|
|||
foreach (var filterCondition in filterConditionList) |
|||
{ |
|||
var tempCondition = CreateLambda<T>(filterCondition); |
|||
if (condition == null) |
|||
{ |
|||
condition = tempCondition; |
|||
} |
|||
else |
|||
{ |
|||
condition = filterCondition.Logic switch |
|||
{ |
|||
"And" => condition.And(tempCondition), |
|||
"Or" => condition.Or(tempCondition), |
|||
_ => condition |
|||
}; |
|||
} |
|||
} |
|||
} |
|||
catch (Exception ex) |
|||
{ |
|||
throw new Exception($"获取筛选条件异常:{ex.Message}"); |
|||
} |
|||
|
|||
return condition; |
|||
} |
|||
|
|||
private static Expression<Func<T, bool>> CreateLambda<T>(Filter filter) |
|||
{ |
|||
Expression<Func<T, bool>> expression = p => false; |
|||
try |
|||
{ |
|||
var parameter = Expression.Parameter(typeof(T), "p"); //创建参数p
|
|||
var member = Expression.PropertyOrField(parameter, filter.Column); //创建表达式中的属性或字段
|
|||
|
|||
ConstantExpression constant = null; |
|||
//var propertyType = member.Type; //取属性类型,常量constant按此类型进行转换
|
|||
//constant = Expression.Constant(filterCondition.Value);//创建常数
|
|||
|
|||
if (filter.Action != "In" && filter.Action != "NotIn") |
|||
{ |
|||
constant = CreateConstantExpression(member.Type, filter.Value); |
|||
} |
|||
|
|||
switch (filter.Action.ToLower()) |
|||
{ |
|||
case "==": |
|||
expression = Expression.Lambda<Func<T, bool>>(Expression.Equal(member, constant), parameter); |
|||
break; |
|||
|
|||
case "!=": |
|||
expression = Expression.Lambda<Func<T, bool>>(Expression.NotEqual(member, constant), parameter); |
|||
break; |
|||
|
|||
case ">": |
|||
expression = Expression.Lambda<Func<T, bool>>(Expression.GreaterThan(member, constant), parameter); |
|||
break; |
|||
|
|||
case "<": |
|||
expression = Expression.Lambda<Func<T, bool>>(Expression.LessThan(member, constant), parameter); |
|||
break; |
|||
|
|||
case ">=": |
|||
expression = |
|||
Expression.Lambda<Func<T, bool>>(Expression.GreaterThanOrEqual(member, constant), parameter); |
|||
break; |
|||
|
|||
case "<=": |
|||
expression = |
|||
Expression.Lambda<Func<T, bool>>(Expression.LessThanOrEqual(member, constant), parameter); |
|||
break; |
|||
|
|||
case "like": |
|||
expression = GetExpressionLikeMethod<T>("Contains", filter); |
|||
break; |
|||
|
|||
case "notlike": |
|||
expression = GetExpressionNotLikeMethod<T>("Contains", filter); |
|||
break; |
|||
|
|||
case "in": |
|||
expression = GetExpressionInMethod<T>("Contains", member.Type, filter); |
|||
break; |
|||
|
|||
case "notin": |
|||
expression = GetExpressionNotInMethod<T>("Contains", member.Type, filter); |
|||
break; |
|||
} |
|||
} |
|||
catch (Exception ex) |
|||
{ |
|||
throw new UserFriendlyException(ex.Message); |
|||
} |
|||
|
|||
return expression; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// </summary>
|
|||
/// <param name="propertyType"></param>
|
|||
/// <param name="value"></param>
|
|||
/// <returns></returns>
|
|||
private static ConstantExpression CreateConstantExpression(Type propertyType, string value) |
|||
{ |
|||
ConstantExpression constant = null; |
|||
try |
|||
{ |
|||
if (propertyType.IsGenericType && |
|||
propertyType.GetGenericTypeDefinition() == typeof(Nullable<>)) |
|||
{ |
|||
|
|||
var objValue = Convert.ChangeType(ChangeTypeReturnValue(value, propertyType.GetGenericArguments()[0]), |
|||
propertyType.GetGenericArguments()[0], |
|||
CultureInfo.InvariantCulture); |
|||
|
|||
constant = Expression.Constant(objValue, propertyType); |
|||
} |
|||
else if (propertyType.IsEnum) |
|||
{ |
|||
var enumValue = (Enum)Enum.Parse(propertyType, value, true); |
|||
constant = Expression.Constant(enumValue, propertyType); |
|||
} |
|||
else |
|||
{ |
|||
constant = propertyType.Name switch |
|||
{ |
|||
"Guid" => Expression.Constant(Guid.Parse(value)), |
|||
_ => Expression.Constant(Convert.ChangeType(value, propertyType, CultureInfo.InvariantCulture)) |
|||
}; |
|||
} |
|||
} |
|||
catch (Exception ex) |
|||
{ |
|||
throw new Exception($"获取ConstantExpression异常:{ex.Message}"); |
|||
} |
|||
|
|||
return constant; |
|||
} |
|||
|
|||
private static Expression<Func<T, bool>> GetExpressionLikeMethod<T>(string methodName, Filter filter) |
|||
{ |
|||
var parameterExpression = Expression.Parameter(typeof(T), "p"); |
|||
// MethodCallExpression methodExpression = GetMethodExpression(methodName, filterCondition.Column, filterCondition.Value, parameterExpression);
|
|||
var methodExpression = GetMethodExpression(methodName, filter.Column, filter.Value, |
|||
parameterExpression); |
|||
return Expression.Lambda<Func<T, bool>>(methodExpression, parameterExpression); |
|||
} |
|||
|
|||
private static Expression<Func<T, bool>> GetExpressionNotLikeMethod<T>(string methodName, Filter filter) |
|||
{ |
|||
var parameterExpression = Expression.Parameter(typeof(T), "p"); |
|||
var methodExpression = GetMethodExpression(methodName, filter.Column, filter.Value, |
|||
parameterExpression); |
|||
var notMethodExpression = Expression.Not(methodExpression); |
|||
return Expression.Lambda<Func<T, bool>>(notMethodExpression, parameterExpression); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 生成guidList.Contains(p=>p.GUId);
|
|||
/// 除String类型,其他类型涉及到类型转换.如GUID
|
|||
/// </summary>
|
|||
/// <typeparam name="T"></typeparam>
|
|||
/// <param name="methodName">Contains</param>
|
|||
/// <param name="propertyType">PropertyType/typeof(GUId)</param>
|
|||
/// <param name="filter">PropertyName/PropertyValue</param>
|
|||
/// <returns></returns>
|
|||
private static Expression<Func<T, bool>> GetExpressionInMethod<T>(string methodName, Type propertyType, |
|||
Filter filter) |
|||
{ |
|||
var parameterExpression = Expression.Parameter(typeof(T), "p"); |
|||
var lstType = typeof(List<>).MakeGenericType(propertyType); |
|||
|
|||
//转换枚举
|
|||
//if (propertyType.IsEnum)
|
|||
//{
|
|||
// var valueArrayStrings = JsonSerializer.Deserialize<List<string>>(filter.Value);
|
|||
// List<object> newValues = new List<object>();
|
|||
|
|||
// var enumValues = propertyType.GetEnumValues();
|
|||
|
|||
// foreach (var valueArray in valueArrayStrings)
|
|||
// {
|
|||
// foreach (var enumValue in enumValues)
|
|||
// {
|
|||
// if (enumValue.ToString() == valueArray)
|
|||
// {
|
|||
// newValues.Add(enumValue);
|
|||
// break;
|
|||
// }
|
|||
// }
|
|||
// }
|
|||
// var newValue = JsonSerializer.Serialize(newValues);
|
|||
// filter.Value = newValue;
|
|||
//}
|
|||
|
|||
var propertyValue = JsonSerializer.Deserialize($"{filter.Value}", lstType); |
|||
if (propertyValue != null) |
|||
{ |
|||
var methodExpression = GetListMethodExpression(methodName, propertyType, filter.Column, propertyValue, |
|||
parameterExpression); |
|||
var expression = Expression.Lambda<Func<T, bool>>(methodExpression, parameterExpression); |
|||
return expression; |
|||
} |
|||
|
|||
return p => false; |
|||
} |
|||
|
|||
private static Expression<Func<T, bool>> GetExpressionNotInMethod<T>(string methodName, Type propertyType, |
|||
Filter filter) |
|||
{ |
|||
var parameterExpression = Expression.Parameter(typeof(T), "p"); |
|||
var lstType = typeof(List<>).MakeGenericType(propertyType); |
|||
var propertyValue = JsonSerializer.Deserialize(filter.Value, lstType); |
|||
if (propertyValue != null) |
|||
{ |
|||
var methodExpression = GetListMethodExpression(methodName, propertyType, filter.Column, propertyValue, |
|||
parameterExpression); |
|||
var notMethodExpression = Expression.Not(methodExpression); |
|||
return Expression.Lambda<Func<T, bool>>(notMethodExpression, parameterExpression); |
|||
} |
|||
|
|||
return p => false; |
|||
} |
|||
|
|||
private static MethodCallExpression GetListMethodExpression(string methodName, Type propertyType, |
|||
string propertyName, object propertyValue, ParameterExpression parameterExpression) |
|||
{ |
|||
var propertyExpression = Expression.Property(parameterExpression, propertyName); //p.GUID
|
|||
var type = typeof(List<>).MakeGenericType(propertyType); |
|||
var method = type.GetMethod(methodName); //获取 List.Contains()
|
|||
var someValue = Expression.Constant(propertyValue); //Value
|
|||
return Expression.Call(someValue, method, propertyExpression); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 生成类似于p=>p.Code.Contains("xxx");的lambda表达式
|
|||
/// parameterExpression标识p,propertyName表示values,propertyValue表示"Code",methodName表示Contains
|
|||
/// 仅处理p的属性类型为string这种情况
|
|||
/// </summary>
|
|||
/// <param name="methodName"></param>
|
|||
/// <param name="propertyName"></param>
|
|||
/// <param name="propertyValue"></param>
|
|||
/// <param name="parameterExpression"></param>
|
|||
/// <returns></returns>
|
|||
private static MethodCallExpression GetMethodExpression(string methodName, string propertyName, |
|||
string propertyValue, ParameterExpression parameterExpression) |
|||
{ |
|||
var propertyExpression = Expression.Property(parameterExpression, propertyName); |
|||
var method = typeof(string).GetMethod(methodName, new[] { typeof(string) }); |
|||
var someValue = Expression.Constant(propertyValue, typeof(string)); |
|||
return Expression.Call(propertyExpression, method, someValue); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 默认True条件
|
|||
/// </summary>
|
|||
/// <typeparam name="T"></typeparam>
|
|||
/// <returns></returns>
|
|||
public static Expression<Func<T, bool>> True<T>() |
|||
{ |
|||
return f => true; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 默认False条件
|
|||
/// </summary>
|
|||
/// <typeparam name="T"></typeparam>
|
|||
/// <returns></returns>
|
|||
public static Expression<Func<T, bool>> False<T>() |
|||
{ |
|||
return f => false; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 拼接 OR 条件
|
|||
/// </summary>
|
|||
/// <typeparam name="T"></typeparam>
|
|||
/// <param name="exp"></param>
|
|||
/// <param name="condition"></param>
|
|||
/// <returns></returns>
|
|||
private static Expression<Func<T, bool>> Or<T>(this Expression<Func<T, bool>> exp, |
|||
Expression<Func<T, bool>> condition) |
|||
{ |
|||
var inv = Expression.Invoke(condition, exp.Parameters); |
|||
return Expression.Lambda<Func<T, bool>>(Expression.Or(exp.Body, inv), exp.Parameters); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 拼接And条件
|
|||
/// </summary>
|
|||
/// <typeparam name="T"></typeparam>
|
|||
/// <param name="exp"></param>
|
|||
/// <param name="condition"></param>
|
|||
/// <returns></returns>
|
|||
private static Expression<Func<T, bool>> And<T>(this Expression<Func<T, bool>> exp, |
|||
Expression<Func<T, bool>> condition) |
|||
{ |
|||
var inv = Expression.Invoke(condition, exp.Parameters); |
|||
return Expression.Lambda<Func<T, bool>>(Expression.And(exp.Body, inv), exp.Parameters); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 转换传入的值,并将正确的值传出(解决 enum,guid)
|
|||
/// </summary>
|
|||
/// <param name="value"></param>
|
|||
/// <param name="type"></param>
|
|||
/// <returns></returns>
|
|||
public static object ChangeTypeReturnValue(object value, Type type) |
|||
{ |
|||
if (value == null && type.IsGenericType) return Activator.CreateInstance(type); |
|||
if (value == null) return null; |
|||
if (type == value.GetType()) return value; |
|||
if (type.IsEnum) |
|||
{ |
|||
if (value is string) |
|||
return Enum.Parse(type, value as string); |
|||
else |
|||
return Enum.ToObject(type, value); |
|||
} |
|||
if (!type.IsInterface && type.IsGenericType) |
|||
{ |
|||
Type innerType = type.GetGenericArguments()[0]; |
|||
object innerValue = ChangeTypeReturnValue(value, innerType); |
|||
return Activator.CreateInstance(type, new object[] { innerValue }); |
|||
} |
|||
if (value is string && type == typeof(Guid)) return new Guid(value as string); |
|||
if (value is string && type == typeof(Version)) return new Version(value as string); |
|||
if (!(value is IConvertible)) return value; |
|||
return Convert.ChangeType(value, type); |
|||
} |
|||
} |
@ -0,0 +1,12 @@ |
|||
using Volo.Abp.Application.Dtos; |
|||
using WinIn.FasterZ.Inventory.AppBase.Filters; |
|||
|
|||
namespace WinIn.FasterZ.Inventory.AppBase; |
|||
|
|||
public interface ISfsRequest : IPagedAndSortedResultRequest |
|||
{ |
|||
/// <summary>
|
|||
/// 条件
|
|||
/// </summary>
|
|||
public Condition Condition { get; set; } |
|||
} |
@ -0,0 +1,57 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Threading; |
|||
using System.Threading.Tasks; |
|||
using Microsoft.AspNetCore.Mvc; |
|||
using Volo.Abp.Application.Dtos; |
|||
using Volo.Abp.Application.Services; |
|||
|
|||
namespace WinIn.FasterZ.Inventory.AppBase; |
|||
|
|||
public interface |
|||
IZbxBase<TEntityDto, in TPagedAndSortedResultRequestDto, in TKey, TCreateInput, in TUpdateInput> : |
|||
ICrudAppService<TEntityDto, TPagedAndSortedResultRequestDto, TKey, TCreateInput, TUpdateInput> |
|||
{ |
|||
Task<PagedResultDto<TEntityDto>> GetPageListByFilterAsync(SfsRequestInputBase sfsRequestInputBase, |
|||
bool includeDetails = false, CancellationToken cancellationToken = default); |
|||
|
|||
/// <summary>
|
|||
/// 【基础】-【导出Excel】【有筛选条件】
|
|||
/// </summary>
|
|||
/// <param name="sfsRequestInputBase">查询条件</param>
|
|||
/// <param name="isRedundance">是否冗余主表数据</param>
|
|||
/// <param name="isDetailExport">是否导出子表</param>
|
|||
/// <param name="userId">用户ID</param>
|
|||
/// <returns></returns>
|
|||
Task<IActionResult> ExportToExcelAsync(SfsRequestInputBase sfsRequestInputBase, bool isRedundance, Guid userId, |
|||
bool isDetailExport = true); |
|||
|
|||
/// <summary>
|
|||
/// 【基础】-【分页查询】【有筛选条件】
|
|||
/// </summary>
|
|||
/// <param name="sfsRequestInputBase"></param>
|
|||
/// <param name="includeDetails"></param>
|
|||
/// <param name="cancellationToken"></param>
|
|||
/// <returns></returns>
|
|||
Task<List<TEntityDto>> GetAllListAsync(); |
|||
|
|||
/// <summary>
|
|||
/// 【基础】-【批量】-【新增】
|
|||
/// </summary>
|
|||
/// <param name="inputList"></param>
|
|||
/// <returns></returns>
|
|||
Task<List<TEntityDto>> CreateManyAsync(List<TCreateInput> inputList); |
|||
|
|||
/// <summary>
|
|||
/// 【基础】-【批量】-【删除】
|
|||
/// </summary>
|
|||
/// <param name="keyList"></param>
|
|||
/// <returns></returns>
|
|||
Task DeleteAsync(IEnumerable<TPagedAndSortedResultRequestDto> keyList); |
|||
|
|||
/// <summary>
|
|||
/// 【基础】-【获取数据】
|
|||
/// </summary>
|
|||
/// <returns></returns>
|
|||
Task<TEntityDto> GetCacheByIdAsync(TPagedAndSortedResultRequestDto id); |
|||
} |
@ -0,0 +1,12 @@ |
|||
using Volo.Abp.Application.Dtos; |
|||
using WinIn.FasterZ.Inventory.AppBase.Filters; |
|||
|
|||
namespace WinIn.FasterZ.Inventory.AppBase; |
|||
|
|||
public class SfsRequestInputBase : PagedAndSortedResultRequestDto, ISfsRequest |
|||
{ |
|||
/// <summary>
|
|||
/// 条件
|
|||
/// </summary>
|
|||
public Condition Condition { get; set; } = new(); |
|||
} |
@ -0,0 +1,22 @@ |
|||
using System.Collections.Generic; |
|||
|
|||
namespace WinIn.FasterZ.Inventory.AppBase.TableColumnTypeDto |
|||
{ |
|||
public class AllTableColumnTypeDto |
|||
{ |
|||
/// <summary>
|
|||
/// 列属性类别
|
|||
/// </summary>
|
|||
public List<ColumnType> ColumnsTypes { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// C R U S G
|
|||
/// </summary>
|
|||
public string DtoType { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// Dto名称
|
|||
/// </summary>
|
|||
public string? DtoName { get; set; } |
|||
} |
|||
} |
@ -0,0 +1,31 @@ |
|||
using System.ComponentModel.DataAnnotations; |
|||
|
|||
namespace WinIn.FasterZ.Inventory.AppBase.TableColumnTypeDto |
|||
{ |
|||
public class ColumnType |
|||
{ |
|||
/// <summary>
|
|||
/// 列名
|
|||
/// </summary>
|
|||
[Display(Name = "列名")] |
|||
public string Z_ColumnName { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 后端类型
|
|||
/// </summary>
|
|||
[Display(Name = "后端类型")] |
|||
public string Z_ColumnType { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 基础类型
|
|||
/// </summary>
|
|||
[Display(Name = "基础类型")] |
|||
public string Z_ColumnBaseType { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 是否是枚举
|
|||
/// </summary>
|
|||
[Display(Name = "是否是枚举")] |
|||
public bool IsEnum { get; set; } |
|||
} |
|||
} |
@ -0,0 +1,33 @@ |
|||
using System; |
|||
using Dy_Exchange.Enums; |
|||
|
|||
namespace WinIn.FasterZ.Inventory.AppBaseBusiness.ExportCustomUserSetting.Dtos; |
|||
|
|||
[Serializable] |
|||
public class CreateUpdateExportCustomUserSettingDto |
|||
{ |
|||
/// <summary>
|
|||
/// 用户ID
|
|||
/// </summary>
|
|||
public Guid? ExportUserId { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 用户姓名
|
|||
/// </summary>
|
|||
public string? ExportUserName { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 列名
|
|||
/// </summary>
|
|||
public string? ExportColumnName { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 表名
|
|||
/// </summary>
|
|||
public string? ExportTableName { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 导出设置项
|
|||
/// </summary>
|
|||
public Enum_ExportCustomUserSetting CustomUserSetting { get; set; } |
|||
} |
@ -0,0 +1,38 @@ |
|||
using System; |
|||
using Dy_Exchange.Enums; |
|||
using Volo.Abp.Application.Dtos; |
|||
|
|||
namespace WinIn.FasterZ.Inventory.AppBaseBusiness.ExportCustomUserSetting.Dtos |
|||
{ |
|||
/// <summary>
|
|||
/// 用户个型导出配置
|
|||
/// </summary>
|
|||
[Serializable] |
|||
public class ExportCustomUserSettingDto : AuditedEntityDto<Guid> |
|||
{ |
|||
/// <summary>
|
|||
/// 用户ID
|
|||
/// </summary>
|
|||
public Guid? ExportUserId { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 用户姓名
|
|||
/// </summary>
|
|||
public string? ExportUserName { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 列名
|
|||
/// </summary>
|
|||
public string? ExportColumnName { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 表名
|
|||
/// </summary>
|
|||
public string? ExportTableName { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 导出设置项
|
|||
/// </summary>
|
|||
public Enum_ExportCustomUserSetting CustomUserSetting { get; set; } |
|||
} |
|||
} |
@ -0,0 +1,35 @@ |
|||
using System; |
|||
using Dy_Exchange.Enums; |
|||
using Volo.Abp.Application.Dtos; |
|||
|
|||
namespace WinIn.FasterZ.Inventory.AppBaseBusiness.ExportCustomUserSetting.Dtos |
|||
{ |
|||
[Serializable] |
|||
public class ExportCustomUserSettingGetListInput : PagedAndSortedResultRequestDto |
|||
{ |
|||
/// <summary>
|
|||
/// 用户ID
|
|||
/// </summary>
|
|||
public Guid? ExportUserId { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 用户姓名
|
|||
/// </summary>
|
|||
public string? ExportUserName { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 列名
|
|||
/// </summary>
|
|||
public string? ExportColumnName { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 表名
|
|||
/// </summary>
|
|||
public string? ExportTableName { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 导出设置项
|
|||
/// </summary>
|
|||
public Enum_ExportCustomUserSetting? CustomUserSetting { get; set; } |
|||
} |
|||
} |
@ -0,0 +1,24 @@ |
|||
using System; |
|||
using Volo.Abp.Application.Services; |
|||
using WinIn.FasterZ.Inventory.AppBaseBusiness.ExportCustomUserSetting.Dtos; |
|||
|
|||
namespace WinIn.FasterZ.Inventory.AppBaseBusiness.ExportCustomUserSetting |
|||
{ |
|||
/// <summary>
|
|||
/// 用户个型导出配置
|
|||
/// </summary>
|
|||
public interface IExportCustomUserSettingAppService : |
|||
ICrudAppService< |
|||
ExportCustomUserSettingDto, |
|||
Guid, |
|||
ExportCustomUserSettingGetListInput, |
|||
CreateUpdateExportCustomUserSettingDto, |
|||
CreateUpdateExportCustomUserSettingDto> |
|||
{ |
|||
///// <summary>
|
|||
///// 根据用户和表名获取个性化导出
|
|||
///// </summary>
|
|||
///// <returns></returns>
|
|||
//Task<List<ExportCustomUserSettingDto>> GetByUserIdAndExportTableNameAsync(Guid userId, string exportTableName);
|
|||
} |
|||
} |
@ -0,0 +1,26 @@ |
|||
<Project Sdk="Microsoft.NET.Sdk"> |
|||
|
|||
<Import Project="..\..\common.props" /> |
|||
|
|||
<PropertyGroup> |
|||
<TargetFrameworks>netstandard2.0;netstandard2.1;net7.0</TargetFrameworks> |
|||
<Nullable>enable</Nullable> |
|||
<RootNamespace>Dy_Exchange</RootNamespace> |
|||
</PropertyGroup> |
|||
|
|||
<ItemGroup> |
|||
<ProjectReference Include="..\Dy_Exchange.Domain.Shared\Dy_Exchange.Domain.Shared.csproj" /> |
|||
</ItemGroup> |
|||
|
|||
<ItemGroup> |
|||
<PackageReference Include="Microsoft.AspNetCore.Mvc.Core" Version="2.2.5" /> |
|||
<PackageReference Include="Volo.Abp.ObjectExtending" Version="7.3.2" /> |
|||
<PackageReference Include="Volo.Abp.Account.Application.Contracts" Version="7.3.2" /> |
|||
<PackageReference Include="Volo.Abp.Identity.Application.Contracts" Version="7.3.2" /> |
|||
<PackageReference Include="Volo.Abp.PermissionManagement.Application.Contracts" Version="7.3.2" /> |
|||
<PackageReference Include="Volo.Abp.TenantManagement.Application.Contracts" Version="7.3.2" /> |
|||
<PackageReference Include="Volo.Abp.FeatureManagement.Application.Contracts" Version="7.3.2" /> |
|||
<PackageReference Include="Volo.Abp.SettingManagement.Application.Contracts" Version="7.3.2" /> |
|||
</ItemGroup> |
|||
|
|||
</Project> |
@ -0,0 +1,28 @@ |
|||
using Volo.Abp.Account; |
|||
using Volo.Abp.FeatureManagement; |
|||
using Volo.Abp.Identity; |
|||
using Volo.Abp.Modularity; |
|||
using Volo.Abp.ObjectExtending; |
|||
using Volo.Abp.PermissionManagement; |
|||
using Volo.Abp.SettingManagement; |
|||
using Volo.Abp.TenantManagement; |
|||
|
|||
namespace Dy_Exchange; |
|||
|
|||
[DependsOn( |
|||
typeof(Dy_ExchangeDomainSharedModule), |
|||
typeof(AbpAccountApplicationContractsModule), |
|||
typeof(AbpFeatureManagementApplicationContractsModule), |
|||
typeof(AbpIdentityApplicationContractsModule), |
|||
typeof(AbpPermissionManagementApplicationContractsModule), |
|||
typeof(AbpSettingManagementApplicationContractsModule), |
|||
typeof(AbpTenantManagementApplicationContractsModule), |
|||
typeof(AbpObjectExtendingModule) |
|||
)] |
|||
public class Dy_ExchangeApplicationContractsModule : AbpModule |
|||
{ |
|||
public override void PreConfigureServices(ServiceConfigurationContext context) |
|||
{ |
|||
Dy_ExchangeDtoExtensions.Configure(); |
|||
} |
|||
} |
@ -0,0 +1,28 @@ |
|||
using Volo.Abp.Identity; |
|||
using Volo.Abp.ObjectExtending; |
|||
using Volo.Abp.Threading; |
|||
|
|||
namespace Dy_Exchange; |
|||
|
|||
public static class Dy_ExchangeDtoExtensions |
|||
{ |
|||
private static readonly OneTimeRunner OneTimeRunner = new OneTimeRunner(); |
|||
|
|||
public static void Configure() |
|||
{ |
|||
OneTimeRunner.Run(() => |
|||
{ |
|||
/* You can add extension properties to DTOs |
|||
* defined in the depended modules. |
|||
* |
|||
* Example: |
|||
* |
|||
* ObjectExtensionManager.Instance |
|||
* .AddOrUpdateProperty<IdentityRoleDto, string>("Title"); |
|||
* |
|||
* See the documentation for more: |
|||
* https://docs.abp.io/en/abp/latest/Object-Extensions
|
|||
*/ |
|||
}); |
|||
} |
|||
} |
@ -0,0 +1,25 @@ |
|||
using Dy_Exchange.Localization; |
|||
using Volo.Abp.Authorization.Permissions; |
|||
using Volo.Abp.Localization; |
|||
|
|||
namespace Dy_Exchange.Permissions; |
|||
|
|||
public class Dy_ExchangePermissionDefinitionProvider : PermissionDefinitionProvider |
|||
{ |
|||
public override void Define(IPermissionDefinitionContext context) |
|||
{ |
|||
var myGroup = context.AddGroup(Dy_ExchangePermissions.GroupName); |
|||
//Define your own permissions here. Example:
|
|||
//myGroup.AddPermission(Dy_ExchangePermissions.MyPermission1, L("Permission:MyPermission1"));
|
|||
|
|||
var dataExchangeInterfaceConfigPermission = myGroup.AddPermission(Dy_ExchangePermissions.DataExchangeInterfaceConfig.Default, L("Permission:DataExchangeInterfaceConfig")); |
|||
dataExchangeInterfaceConfigPermission.AddChild(Dy_ExchangePermissions.DataExchangeInterfaceConfig.Create, L("Permission:Create")); |
|||
dataExchangeInterfaceConfigPermission.AddChild(Dy_ExchangePermissions.DataExchangeInterfaceConfig.Update, L("Permission:Update")); |
|||
dataExchangeInterfaceConfigPermission.AddChild(Dy_ExchangePermissions.DataExchangeInterfaceConfig.Delete, L("Permission:Delete")); |
|||
} |
|||
|
|||
private static LocalizableString L(string name) |
|||
{ |
|||
return LocalizableString.Create<Dy_ExchangeResource>(name); |
|||
} |
|||
} |
@ -0,0 +1,29 @@ |
|||
namespace Dy_Exchange.Permissions; |
|||
|
|||
public static class Dy_ExchangePermissions |
|||
{ |
|||
public const string GroupName = "Dy_Exchange"; |
|||
|
|||
//Add your own permission names. Example:
|
|||
//public const string MyPermission1 = GroupName + ".MyPermission1";
|
|||
/// <summary>
|
|||
///
|
|||
/// </summary>
|
|||
public class ExportCustomUserSetting |
|||
{ |
|||
public const string Default = GroupName + ".ExportCustomUserSetting"; |
|||
public const string Update = Default + ".Update"; |
|||
public const string Create = Default + ".Create"; |
|||
public const string Delete = Default + ".Delete"; |
|||
} |
|||
/// <summary>
|
|||
///
|
|||
/// </summary>
|
|||
public class DataExchangeInterfaceConfig |
|||
{ |
|||
public const string Default = GroupName + ".DataExchangeInterfaceConfig"; |
|||
public const string Update = Default + ".Update"; |
|||
public const string Create = Default + ".Create"; |
|||
public const string Delete = Default + ".Delete"; |
|||
} |
|||
} |
@ -0,0 +1,39 @@ |
|||
using System; |
|||
using System.ComponentModel; |
|||
using WinIn.FasterZ.Inventory.AppBase.FasterBaseDto; |
|||
|
|||
namespace Dy_Exchange.Z_Business.Dtos; |
|||
|
|||
[Serializable] |
|||
public class CreateUpdateDataExchangeInterfaceConfigDto: FasterCreateUpdateBaseDto |
|||
{ |
|||
/// <summary>
|
|||
///
|
|||
/// </summary>
|
|||
[DisplayName("DataExchangeInterfaceConfigName")] |
|||
public string? Name { get; set; } |
|||
|
|||
/// <summary>
|
|||
///
|
|||
/// </summary>
|
|||
[DisplayName("DataExchangeInterfaceConfigCode")] |
|||
public string? Code { get; set; } |
|||
|
|||
/// <summary>
|
|||
///
|
|||
/// </summary>
|
|||
[DisplayName("DataExchangeInterfaceConfigActive")] |
|||
public bool Active { get; set; } |
|||
|
|||
/// <summary>
|
|||
///
|
|||
/// </summary>
|
|||
[DisplayName("DataExchangeInterfaceConfigLevel")] |
|||
public int Level { get; set; } |
|||
|
|||
/// <summary>
|
|||
///
|
|||
/// </summary>
|
|||
[DisplayName("DataExchangeInterfaceConfigRemark")] |
|||
public string? Remark { get; set; } |
|||
} |
@ -0,0 +1,48 @@ |
|||
using System; |
|||
using Volo.Abp.Application.Dtos; |
|||
|
|||
namespace Dy_Exchange.Z_Business.Dtos; |
|||
|
|||
/// <summary>
|
|||
///
|
|||
/// </summary>
|
|||
[Serializable] |
|||
public class DataExchangeInterfaceConfigDto : AuditedEntityDto<Guid> |
|||
{ |
|||
|
|||
/// <summary>
|
|||
///
|
|||
/// </summary>
|
|||
public string? Name { get; set; } |
|||
|
|||
/// <summary>
|
|||
///
|
|||
/// </summary>
|
|||
public string? Code { get; set; } |
|||
|
|||
/// <summary>
|
|||
///
|
|||
/// </summary>
|
|||
public bool Active { get; set; } |
|||
|
|||
/// <summary>
|
|||
///
|
|||
/// </summary>
|
|||
public int Level { get; set; } |
|||
|
|||
/// <summary>
|
|||
///
|
|||
/// </summary>
|
|||
public string? ExtraProperties { get; set; } |
|||
|
|||
/// <summary>
|
|||
///
|
|||
/// </summary>
|
|||
public string? ConcurrencyStamp { get; set; } |
|||
|
|||
|
|||
/// <summary>
|
|||
///
|
|||
/// </summary>
|
|||
public string? Remark { get; set; } |
|||
} |
@ -0,0 +1,21 @@ |
|||
using System; |
|||
using Dy_Exchange.Z_Business.Dtos; |
|||
using Volo.Abp.Application.Dtos; |
|||
using Volo.Abp.Application.Services; |
|||
|
|||
namespace Dy_Exchange.Z_Business; |
|||
|
|||
|
|||
/// <summary>
|
|||
///
|
|||
/// </summary>
|
|||
public interface IDataExchangeInterfaceConfigAppService : |
|||
ICrudAppService< |
|||
DataExchangeInterfaceConfigDto, |
|||
Guid, |
|||
PagedAndSortedResultRequestDto, |
|||
CreateUpdateDataExchangeInterfaceConfigDto, |
|||
CreateUpdateDataExchangeInterfaceConfigDto> |
|||
{ |
|||
|
|||
} |
@ -0,0 +1,27 @@ |
|||
using System.Linq.Expressions; |
|||
|
|||
namespace WinIn.FasterZ.Inventory.AppBase.Extensions |
|||
{ |
|||
public static class ExpressionExtensions |
|||
{ |
|||
public static string GetMemberName(Expression expression) |
|||
{ |
|||
if (expression is MemberExpression member) |
|||
{ |
|||
return member.Member.Name; |
|||
} |
|||
|
|||
if (expression is MethodCallExpression method) |
|||
{ |
|||
return method.Method.Name; |
|||
} |
|||
|
|||
if (expression is UnaryExpression unary) |
|||
{ |
|||
return GetMemberName(unary); |
|||
} |
|||
|
|||
return null; |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,54 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.ComponentModel.DataAnnotations; |
|||
using System.Linq; |
|||
using System.Linq.Dynamic.Core; |
|||
using System.Linq.Expressions; |
|||
using System.Reflection; |
|||
|
|||
namespace WinIn.FasterZ.Inventory.AppBase.Extensions |
|||
{ |
|||
public static class ObjectExpressionExtensions |
|||
{ |
|||
public static IQueryable<TEntity> WhereByKey<TEntity, TModel>(this IQueryable<TEntity> source, TModel model) |
|||
{ |
|||
if (model == null) |
|||
{ |
|||
return null; |
|||
} |
|||
|
|||
var modelType = model.GetType(); |
|||
var properties = modelType.GetProperties().Where(o => o.GetCustomAttribute<KeyAttribute>() != null).ToList(); |
|||
if (properties.Any()) |
|||
{ |
|||
foreach (var property in properties) |
|||
{ |
|||
var propertyName = property.Name; |
|||
var propertyValue = property.GetValue(model, null); |
|||
source = source.Where($"{propertyName} == @0", propertyValue); |
|||
} |
|||
|
|||
return source; |
|||
} |
|||
|
|||
return null; |
|||
} |
|||
|
|||
public static List<IGrouping<object, T>> GroupByKey<T>(this IQueryable<T> source) |
|||
{ |
|||
var properties = typeof(T).GetProperties().Where(o => o.GetCustomAttribute<KeyAttribute>() != null).ToList(); |
|||
var names = string.Join(",", properties.Select(o => o.Name)); |
|||
return source.AsQueryable().GroupBy($"new ({names})").ToDynamicList<IGrouping<object, T>>(); |
|||
} |
|||
|
|||
public static Expression<Func<TEntity, bool>> GetExpressionByProperty<TEntity>(this Type type, string propertyName, |
|||
string propertyValue) |
|||
{ |
|||
var o = Expression.Parameter(type, "p"); |
|||
var memberExpression = Expression.Property(o, propertyName); |
|||
var body = Expression.Call(typeof(string).GetMethod("Contains", new[] { typeof(string) }), memberExpression); |
|||
var predicate = Expression.Lambda<Func<TEntity, bool>>(body, o); |
|||
return predicate; |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,119 @@ |
|||
using System; |
|||
using System.Collections; |
|||
using System.Collections.Generic; |
|||
using System.Reflection; |
|||
using Omu.ValueInjecter; |
|||
using Omu.ValueInjecter.Injections; |
|||
using Volo.Abp; |
|||
|
|||
namespace WinIn.FasterZ.Wms.AppBase.Extensions |
|||
{ |
|||
/// <summary>
|
|||
/// 对象映射
|
|||
/// </summary>
|
|||
public static class ObjectMapperExtensions |
|||
{ |
|||
/// <summary>
|
|||
/// 从模型更新实体
|
|||
/// </summary>
|
|||
public static T FromObject<T>(this T to, object from) |
|||
{ |
|||
try |
|||
{ |
|||
to.InjectFrom<DeepInjectionForUpdate>(from); |
|||
return to; |
|||
} |
|||
catch (Exception ex) |
|||
{ |
|||
throw new UserFriendlyException($"{from.GetType().FullName}映射到${typeof(T).FullName}时失败:{ex.Message},{ex}"); |
|||
} |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 从实体创建模型
|
|||
/// </summary>
|
|||
/// <typeparam name="T"></typeparam>
|
|||
/// <param name="from"></param>
|
|||
/// <returns></returns>
|
|||
public static T ToObject<T>(this object from) |
|||
{ |
|||
try |
|||
{ |
|||
if (typeof(T).IsGenericType && typeof(T).IsAssignableTo(typeof(IList)) && from is IList list) |
|||
{ |
|||
var toListType = typeof(T); |
|||
var elementType = typeof(T).GetGenericArguments()[0]; |
|||
var toList = (IList)Activator.CreateInstance(typeof(T))!; |
|||
var fromList = list; |
|||
foreach (var item in fromList) |
|||
{ |
|||
toList.Add(Activator.CreateInstance(elementType).InjectFrom<DeepInjection>(item)); |
|||
} |
|||
|
|||
return (T)toList; |
|||
} |
|||
|
|||
return (T)Activator.CreateInstance<T>().InjectFrom<DeepInjection>(from); |
|||
} |
|||
catch (Exception ex) |
|||
{ |
|||
throw new UserFriendlyException($"{from.GetType().FullName}映射到${typeof(T).FullName}时失败:{ex.Message},{ex}"); |
|||
} |
|||
} |
|||
|
|||
private class DeepInjection : LoopInjection |
|||
{ |
|||
protected override bool MatchTypes(Type sourceType, Type targetType) |
|||
{ |
|||
if (sourceType != typeof(string) && |
|||
targetType != typeof(string) && |
|||
sourceType.IsGenericType && |
|||
targetType.IsGenericType && |
|||
sourceType.IsAssignableTo(typeof(IEnumerable)) && |
|||
sourceType.IsAssignableTo(typeof(IEnumerable)) |
|||
) |
|||
{ |
|||
return true; |
|||
} |
|||
|
|||
return base.MatchTypes(sourceType, targetType); |
|||
} |
|||
|
|||
protected override void SetValue(object source, object target, PropertyInfo sp, PropertyInfo tp) |
|||
{ |
|||
if (sp.PropertyType != typeof(string) && |
|||
sp.PropertyType != typeof(string) && |
|||
sp.PropertyType.IsAssignableTo(typeof(IList)) && |
|||
tp.PropertyType.IsAssignableTo(typeof(IList))) |
|||
{ |
|||
var targetGenericType = tp.PropertyType.GetGenericArguments()[0]; |
|||
var listType = typeof(List<>).MakeGenericType(targetGenericType); |
|||
var addMethod = listType.GetMethod("Add"); |
|||
var list = Activator.CreateInstance(listType); |
|||
var sourceList = (IList)sp.GetValue(source); |
|||
foreach (var item in sourceList) |
|||
{ |
|||
addMethod.Invoke(list, new[] { Activator.CreateInstance(targetGenericType).FromObject(item) }); |
|||
} |
|||
|
|||
tp.SetValue(target, list); |
|||
return; |
|||
} |
|||
|
|||
base.SetValue(source, target, sp, tp); |
|||
} |
|||
} |
|||
|
|||
private class DeepInjectionForUpdate : DeepInjection |
|||
{ |
|||
protected override void SetValue(object source, object target, PropertyInfo sp, PropertyInfo tp) |
|||
{ |
|||
//if (tp.GetCustomAttribute<IgnoreUpdateAttribute>() != null)
|
|||
//{
|
|||
// return;
|
|||
//}
|
|||
base.SetValue(source, target, sp, tp); |
|||
} |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,17 @@ |
|||
using System; |
|||
using System.Security.Cryptography; |
|||
using System.Text; |
|||
|
|||
namespace WinIn.FasterZ.Inventory.AppBase.Extensions |
|||
{ |
|||
public static class StringExtensions |
|||
{ |
|||
public static string Md5(this string input) |
|||
{ |
|||
using (var md5 = MD5.Create()) |
|||
{ |
|||
return BitConverter.ToString(md5.ComputeHash(Encoding.ASCII.GetBytes(input))).Replace("-", ""); |
|||
} |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,899 @@ |
|||
using System; |
|||
using System.Collections; |
|||
using System.Collections.Generic; |
|||
using System.IO; |
|||
using System.Linq; |
|||
using System.Linq.Dynamic.Core; |
|||
using System.Linq.Expressions; |
|||
using System.Threading; |
|||
using System.Threading.Tasks; |
|||
using AutoMapper; |
|||
using Dy_Exchange.Enums; |
|||
using Dy_Exchange.Localization; |
|||
using Microsoft.AspNetCore.Authorization; |
|||
using Microsoft.AspNetCore.Mvc; |
|||
using Microsoft.EntityFrameworkCore; |
|||
using Microsoft.Extensions.Caching.Distributed; |
|||
using Microsoft.Extensions.Localization; |
|||
using NPOI.SS.UserModel; |
|||
using NPOI.XSSF.UserModel; |
|||
using Volo.Abp; |
|||
using Volo.Abp.Application.Dtos; |
|||
using Volo.Abp.Application.Services; |
|||
using Volo.Abp.Caching; |
|||
using Volo.Abp.Domain.Entities; |
|||
using Volo.Abp.Domain.Entities.Auditing; |
|||
using Volo.Abp.Domain.Repositories; |
|||
using WinIn.FasterZ.Inventory.AppBase; |
|||
using WinIn.FasterZ.Inventory.AppBase.Filters; |
|||
using WinIn.FasterZ.Inventory.AppBase.TableColumnTypeDto; |
|||
using WinIn.FasterZ.Wms.AppBase.Extensions; |
|||
using WinIn.FasterZ.Wms.AppBaseBusiness.ExportCustomUserSetting; |
|||
|
|||
#pragma warning disable CS8602 // Dereference of a possibly null reference.
|
|||
|
|||
namespace WinIn.FasterZ.Wms.AppBase; |
|||
|
|||
[Route("Api/[controller]")]
|
|||
public class ZbxBase<TEntity, TEntityDto, TKey, TPagedAndSortedResultRequestDto, TCreateInput, TUpdateInput> : |
|||
CrudAppService<TEntity, TEntityDto, TKey, |
|||
TPagedAndSortedResultRequestDto, TCreateInput, TUpdateInput>, |
|||
IZbxBase<TEntityDto, TKey, TPagedAndSortedResultRequestDto, TCreateInput, TUpdateInput> |
|||
where TEntity : class, IEntity<TKey> |
|||
where TEntityDto : IEntityDto<TKey> |
|||
{ |
|||
#region 定义
|
|||
|
|||
/// <summary>
|
|||
/// redis缓存时间 分钟
|
|||
/// </summary>
|
|||
private const int CacheMinute = 30; |
|||
|
|||
private readonly IRepository<TEntity, TKey> _repository; |
|||
|
|||
private IMapper _mapper; |
|||
|
|||
private IStringLocalizer<Dy_ExchangeResource> Localizer => |
|||
LazyServiceProvider.LazyGetRequiredService<IStringLocalizer<Dy_ExchangeResource>>(); |
|||
|
|||
private ExportCustomUserSettingAppService ExportCustomUserSettingAppService => |
|||
LazyServiceProvider.LazyGetRequiredService<ExportCustomUserSettingAppService>(); |
|||
|
|||
private IDistributedCache<TEntity> Cache => |
|||
LazyServiceProvider.LazyGetRequiredService<IDistributedCache<TEntity>>(); |
|||
|
|||
#endregion
|
|||
|
|||
/// <summary>
|
|||
/// 构造方法
|
|||
/// </summary>
|
|||
/// <param name="repository"></param>
|
|||
protected ZbxBase(IRepository<TEntity, TKey> repository) : base(repository) |
|||
{ |
|||
_repository = repository; |
|||
} |
|||
|
|||
#region 公开接口
|
|||
|
|||
#region 单体操作
|
|||
|
|||
/// <summary>
|
|||
/// 【基础】-【新增】
|
|||
/// </summary>
|
|||
/// <param name="input"></param>
|
|||
/// <returns></returns>
|
|||
[HttpPost("Base/Create")] |
|||
[Authorize] |
|||
public override async Task<TEntityDto> CreateAsync(TCreateInput input) |
|||
{ |
|||
await CheckCreatePolicyAsync().ConfigureAwait(false); |
|||
|
|||
var entity = input!.ToObject<TEntity>(); |
|||
|
|||
//判断id是否是00000-0000 如果是则赋值
|
|||
var mainId = (Guid)entity.GetType().GetProperty("Id")?.GetValue(entity)!; |
|||
if (mainId == Guid.Empty) |
|||
{ |
|||
mainId = Guid.NewGuid(); |
|||
entity.GetType().GetProperty("Id")?.SetValue(entity, mainId); |
|||
} |
|||
|
|||
#region 给所有字表的 Id和MasterId赋值 否则默认的会是000000-000-....的id 插入时会报错
|
|||
|
|||
var propertyInfos = entity.GetType().GetProperties(); |
|||
foreach (var propertyInfo in propertyInfos) |
|||
{ |
|||
//判断是否是List集合
|
|||
if (propertyInfo.Name == "Details" |
|||
&& propertyInfo.PropertyType.IsGenericType |
|||
&& propertyInfo.PropertyType.GetGenericTypeDefinition() == typeof(List<>)) |
|||
{ |
|||
var listProperty = typeof(TEntity).GetProperty("Details"); |
|||
|
|||
// 获取 List 的元素类型
|
|||
if (listProperty != null) |
|||
{ |
|||
var listItemType = listProperty.PropertyType.GetGenericArguments()[0]; |
|||
|
|||
// 获取元素类型的 ID 属性
|
|||
var detailIdProperty = listItemType.GetProperty("Id"); |
|||
var masterIdProperty = listItemType.GetProperty("MasterId"); |
|||
|
|||
if (detailIdProperty != null) |
|||
{ |
|||
// 获取 List 属性的值
|
|||
var list = (IList)listProperty.GetValue(entity); |
|||
|
|||
// 遍历 List 集合中的每个元素,给 ID 属性赋值
|
|||
if (list != null) |
|||
{ |
|||
foreach (var item in list) |
|||
{ |
|||
if ((Guid)detailIdProperty.GetValue(item)! == Guid.Empty) |
|||
{ |
|||
detailIdProperty.SetValue(item, Guid.NewGuid()); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
if (masterIdProperty != null) |
|||
{ |
|||
// 获取 List 属性的值
|
|||
var list = (IList)listProperty.GetValue(entity); |
|||
|
|||
// 遍历 List 集合中的每个元素,给 ID 属性赋值
|
|||
if (list != null) |
|||
{ |
|||
foreach (var item in list) |
|||
{ |
|||
masterIdProperty.SetValue(item, mainId); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
#endregion
|
|||
|
|||
TryToSetTenantId(entity); |
|||
await Repository.InsertAsync(entity, true).ConfigureAwait(false); |
|||
|
|||
return await MapToGetOutputDtoAsync(entity).ConfigureAwait(false); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 【基础】-【删除】
|
|||
/// </summary>
|
|||
/// <param name="id"></param>
|
|||
/// <returns></returns>
|
|||
[HttpDelete("Base/Delete")] |
|||
[Authorize] |
|||
public override async Task DeleteAsync(TKey id) |
|||
{ |
|||
await CheckDeletePolicyAsync().ConfigureAwait(false); |
|||
|
|||
await _repository.DeleteAsync(id, true).ConfigureAwait(false); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 【基础】-【修改】
|
|||
/// </summary>
|
|||
/// <param name="id"></param>
|
|||
/// <param name="input"></param>
|
|||
/// <returns></returns>
|
|||
[HttpPut("Base/Update")] |
|||
[Authorize] |
|||
public override async Task<TEntityDto> UpdateAsync(TKey id, TUpdateInput input) |
|||
{ |
|||
await CheckUpdatePolicyAsync().ConfigureAwait(true); |
|||
var entity = await GetEntityByIdAsync(id).ConfigureAwait(true); |
|||
|
|||
//当一条库存的一部分被人修改了 数据无法提交 例如库存10个 修改了其中4个 这时乐观锁就被修改了 会抛出异常
|
|||
if (entity.GetType().GetProperty("ConcurrencyStamp").GetValue(entity).ToString() != |
|||
input.GetType().GetProperty("ConcurrencyStamp").GetValue(input).ToString()) |
|||
{ |
|||
throw new UserFriendlyException($"您操作的数据已经被修改:\r\n" + |
|||
$"已经由【{Newtonsoft.Json.JsonConvert.SerializeObject(entity)}】\r\n" + |
|||
$"变更为【{Newtonsoft.Json.JsonConvert.SerializeObject(input)}】\r\n"); |
|||
} |
|||
|
|||
Type? inputDetailDtoType = null; |
|||
Type? entityDetailType = null; |
|||
var inputDetailDtoTypeFlag = false; //input是否有子集合Details
|
|||
var entityDetailTypeFlag = false; //entity是否有子集合Details
|
|||
|
|||
var entityProperties = entity.GetType().GetProperties(); |
|||
var inputProperties = input.GetType().GetProperties(); |
|||
|
|||
//InputDto的
|
|||
foreach (var propertyInfo in inputProperties) |
|||
{ |
|||
if (propertyInfo.Name == "Details" |
|||
&& propertyInfo.PropertyType.IsGenericType |
|||
&& propertyInfo.PropertyType.GetGenericTypeDefinition() == typeof(List<>)) |
|||
{ |
|||
var listProperty = typeof(TUpdateInput).GetProperty("Details"); |
|||
if (listProperty != null) |
|||
{ |
|||
inputDetailDtoType = listProperty.PropertyType.GetGenericArguments()[0]; |
|||
inputDetailDtoTypeFlag = true; |
|||
} |
|||
} |
|||
} |
|||
|
|||
if (inputDetailDtoTypeFlag) |
|||
{ |
|||
//实体的
|
|||
foreach (var propertyInfo in entityProperties) |
|||
{ |
|||
//判断是否是List集合
|
|||
if (propertyInfo.Name == "Details" |
|||
&& propertyInfo.PropertyType.IsGenericType |
|||
&& propertyInfo.PropertyType.GetGenericTypeDefinition() == typeof(List<>)) |
|||
{ |
|||
var listProperty = typeof(TEntity).GetProperty("Details"); |
|||
// 获取 List 的元素类型
|
|||
if (listProperty != null) |
|||
{ |
|||
entityDetailType = listProperty.PropertyType.GetGenericArguments()[0]; |
|||
entityDetailTypeFlag = true; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
if (inputDetailDtoTypeFlag && entityDetailTypeFlag) |
|||
{ |
|||
var config = new MapperConfiguration(cfg => |
|||
{ |
|||
// 动态创建映射关系
|
|||
cfg.CreateMap(typeof(TEntityDto), typeof(TEntity)); |
|||
cfg.CreateMap(typeof(TUpdateInput), typeof(TEntity)); |
|||
cfg.CreateMap(inputDetailDtoType, entityDetailType); |
|||
}); |
|||
_mapper = new Mapper(config); |
|||
} |
|||
else |
|||
{ |
|||
var config = new MapperConfiguration(cfg => |
|||
{ |
|||
// 动态创建映射关系
|
|||
//todo 这里先要判断ID是否是000000-000000
|
|||
cfg.CreateMap(typeof(TEntityDto), typeof(TEntity)); |
|||
cfg.CreateMap(typeof(TUpdateInput), typeof(TEntity)) |
|||
.ForMember("Id", opt => opt.Ignore()) |
|||
.ForMember("ConcurrencyStamp", opt => opt.Ignore()); |
|||
}); |
|||
_mapper = new Mapper(config); |
|||
} |
|||
|
|||
MapProperties(input, entity); |
|||
//entity.GetType().GetProperty("Id")?.SetValue(entity,id);
|
|||
await ReMoveCaCheAsync(id).ConfigureAwait(false); |
|||
await _repository.UpdateAsync(entity, true).ConfigureAwait(true); |
|||
|
|||
|
|||
return await MapToGetOutputDtoAsync(entity).ConfigureAwait(false); |
|||
} |
|||
|
|||
#endregion
|
|||
|
|||
#region 批量操作
|
|||
|
|||
/// <summary>
|
|||
/// 【基础】-【批量】-【新增】
|
|||
/// </summary>
|
|||
/// <param name="inputList"></param>
|
|||
/// <returns></returns>
|
|||
[HttpPost("Base/Create-Many")] |
|||
[Authorize] |
|||
public async Task<List<TEntityDto>> CreateManyAsync(List<TCreateInput> inputList) |
|||
{ |
|||
var dtoList = new List<TEntityDto>(); |
|||
|
|||
foreach (var input in inputList) |
|||
{ |
|||
dtoList.Add(await CreateAsync(input).ConfigureAwait(false)); |
|||
} |
|||
|
|||
return dtoList; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 【基础】-【批量】-【删除】
|
|||
/// </summary>
|
|||
/// <param name="keyList"></param>
|
|||
/// <returns></returns>
|
|||
[HttpDelete("Base/Delete-Many")] |
|||
[Authorize] |
|||
public async Task DeleteAsync(IEnumerable<TKey> keyList) |
|||
{ |
|||
await _repository.DeleteManyAsync(keyList.AsEnumerable(), true).ConfigureAwait(false); |
|||
} |
|||
|
|||
#endregion
|
|||
|
|||
/// <summary>
|
|||
/// 【基础】-【分页查询】【有筛选条件】
|
|||
/// </summary>
|
|||
/// <param name="sfsRequestInputBase"></param>
|
|||
/// <param name="includeDetails"></param>
|
|||
/// <param name="cancellationToken"></param>
|
|||
/// <returns></returns>
|
|||
[HttpPost("Base/Get-List-Page-By-Filter")] |
|||
[Authorize] |
|||
public virtual async Task<PagedResultDto<TEntityDto>> GetPageListByFilterAsync( |
|||
SfsRequestInputBase sfsRequestInputBase, |
|||
bool includeDetails = false, CancellationToken cancellationToken = default) |
|||
{ |
|||
await CheckGetListPolicyAsync(); |
|||
|
|||
var expression = sfsRequestInputBase.Condition.Filters?.Count > 0 |
|||
? sfsRequestInputBase.Condition.Filters.ToLambda<TEntity>() |
|||
: p => true; |
|||
|
|||
var resultEntities = await GetQueryListAsync(expression, sfsRequestInputBase.SkipCount, |
|||
sfsRequestInputBase.MaxResultCount, |
|||
sfsRequestInputBase.Sorting, includeDetails, cancellationToken); |
|||
|
|||
var resultDtos = ObjectMapper.Map<List<TEntity>, List<TEntityDto>>(resultEntities); |
|||
|
|||
//获取总数
|
|||
var totalCount = await GetCountAsync(expression, cancellationToken); |
|||
|
|||
return new PagedResultDto<TEntityDto>(totalCount, resultDtos); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 【基础】-【获取所有数据】
|
|||
/// </summary>
|
|||
/// <param name="sfsRequestInputBase"></param>
|
|||
/// <param name="includeDetails"></param>
|
|||
/// <param name="cancellationToken"></param>
|
|||
/// <returns></returns>
|
|||
[HttpPost("Base/Get-All-List")] |
|||
[Authorize] |
|||
public virtual async Task<List<TEntityDto>> GetAllListAsync() |
|||
{ |
|||
await CheckGetListPolicyAsync(); |
|||
|
|||
var entities = await _repository.GetListAsync(); |
|||
|
|||
return await MapToGetListOutputDtosAsync(entities); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 【基础】-【导出Excel】【有筛选条件】
|
|||
/// </summary>
|
|||
/// <param name="sfsRequestInputBase">查询条件</param>
|
|||
/// <param name="isRedundance">是否冗余主表数据</param>
|
|||
/// <param name="isDetailExport">是否导出子表</param>
|
|||
/// <param name="userId">用户ID</param>
|
|||
/// <returns></returns>
|
|||
[HttpPost("Base/Export-To-Excel")] |
|||
[Authorize] |
|||
public virtual async Task<IActionResult> ExportToExcelAsync(SfsRequestInputBase sfsRequestInputBase, |
|||
bool isRedundance, Guid userId, bool isDetailExport = true) |
|||
{ |
|||
var isHasDetail = false; //是否包含从表
|
|||
|
|||
var data = (await GetPageListByFilterAsync(sfsRequestInputBase, true)).Items; |
|||
|
|||
var fileStream = new MemoryStream(); //文件流
|
|||
IWorkbook workbook = new XSSFWorkbook(); |
|||
var sheet = workbook.CreateSheet(Localizer[typeof(TEntity).Name]); |
|||
var splitDetailsColumnNumber = 1; //分割主表和从表的列数量
|
|||
var excelDetailsCellStyle = SetExcelDetailsCellStyle(workbook); //子表单元格样式
|
|||
var excelSplitCellStyle = SetSplitCellStyle(workbook); //分割单元格样式
|
|||
var excelOnlyMainCellStyle = SetExcelOnlyMainCellStyle(workbook); |
|||
var excelHeadCellStyle = SetExcelHeadCellStyle(workbook); |
|||
|
|||
// 获取主表的属性 创建主表 表头
|
|||
var mainAllProperties = typeof(TEntityDto).GetProperties(); |
|||
var mainProperties = mainAllProperties.Where(p => p.Name != "Details").ToArray(); //去除details属性否则导出时会带出来
|
|||
|
|||
#region 用户个性导出 主表
|
|||
|
|||
//获取个性导出的字段
|
|||
var mainUserColumn = |
|||
await ExportCustomUserSettingAppService.GetByUserIdAndExportTableNameAsync(userId, typeof(TEntity).Name); |
|||
|
|||
if (mainUserColumn.Any(p => p.CustomUserSetting == Enum_ExportCustomUserSetting.Yes)) |
|||
{ |
|||
var showUserColumn = mainUserColumn.Where(p => p.CustomUserSetting == Enum_ExportCustomUserSetting.Yes) |
|||
.Select(p => p.ExportColumnName?.ToLower()).Aggregate((a, b) => a + " " + b)?.Split(' ').ToList(); |
|||
|
|||
mainProperties = mainProperties.Where(p => showUserColumn.Contains(p.Name.ToLower())).ToArray(); |
|||
} |
|||
|
|||
#endregion
|
|||
|
|||
var headerRow = sheet.CreateRow(0); //标头列
|
|||
for (var i = 0; i < mainProperties.Length; i++) |
|||
{ |
|||
var englishName = mainProperties[i].Name; |
|||
//本地化
|
|||
var localizerName = Localizer[typeof(TEntity).Name + englishName]; |
|||
var headCell = headerRow.CreateCell(i); |
|||
headCell.SetCellValue(localizerName); |
|||
headCell.CellStyle = excelHeadCellStyle; |
|||
} |
|||
|
|||
// 获取从表的属性 创建从表 表头
|
|||
var detailProperties = typeof(TEntityDto).GetProperty("Details")?.PropertyType.GetGenericArguments()[0] |
|||
.GetProperties(); |
|||
|
|||
if (detailProperties != null) |
|||
{ |
|||
isHasDetail = true; |
|||
if (!isDetailExport) //是否要导出子表
|
|||
{ |
|||
isHasDetail = false; |
|||
} |
|||
|
|||
if (isHasDetail) |
|||
{ |
|||
headerRow.CreateCell(mainProperties.Length).SetCellValue("---【分割】---"); |
|||
|
|||
#region 用户个性导出 从表
|
|||
|
|||
//获取个性导出的字段
|
|||
var detailDtoName = mainAllProperties.First(p => p.Name == "Details"); |
|||
var detailUserColumn = await ExportCustomUserSettingAppService.GetByUserIdAndExportTableNameAsync( |
|||
userId, detailDtoName.PropertyType.GenericTypeArguments.First().Name.Replace("Dto", "")); |
|||
var detailNotShowUserColumn = detailUserColumn |
|||
.Where(p => p.CustomUserSetting == Enum_ExportCustomUserSetting.No).Select(p => p.ExportColumnName) |
|||
.ToList(); |
|||
if (detailUserColumn.Any()) |
|||
{ |
|||
detailProperties = detailProperties.Where(p => !detailNotShowUserColumn.Contains(p.Name)).ToArray(); |
|||
} |
|||
|
|||
#endregion
|
|||
|
|||
for (var i = 0; i < detailProperties.Length; i++) |
|||
{ |
|||
headerRow.CreateCell(mainProperties.Length + splitDetailsColumnNumber + i) |
|||
.SetCellValue(detailProperties[i].Name); |
|||
var headCell = headerRow.GetCell(mainProperties.Length + splitDetailsColumnNumber + i); |
|||
headCell.CellStyle = excelHeadCellStyle; |
|||
} |
|||
} |
|||
} |
|||
|
|||
// 填充数据行
|
|||
var rowIndex = 1; |
|||
foreach (var mainDto in data) |
|||
{ |
|||
if (isHasDetail) |
|||
{ |
|||
// 获取从表数据
|
|||
var detailsIndex = mainAllProperties.FindIndex(p => p.Name == "Details"); |
|||
// 子表
|
|||
var detailList = (IEnumerable<object>)mainAllProperties[detailsIndex].GetValue(mainDto); |
|||
var startMainRowIndex = rowIndex; |
|||
for (var datailCount = 0; datailCount < detailList.Count(); datailCount++) |
|||
{ |
|||
var dataRow = sheet.CreateRow(rowIndex); |
|||
|
|||
if (isRedundance) |
|||
{ |
|||
// 填充主表数据
|
|||
for (var i = 0; i < mainProperties.Length; i++) |
|||
{ |
|||
var value = mainProperties[i].GetValue(mainDto); |
|||
dataRow.CreateCell(i).SetCellValue(value?.ToString()); |
|||
} |
|||
} |
|||
else |
|||
{ |
|||
if (datailCount == 0) |
|||
{ |
|||
// 填充主表数据
|
|||
for (var i = 0; i < mainProperties.Length; i++) |
|||
{ |
|||
var value = mainProperties[i].GetValue(mainDto); |
|||
dataRow.CreateCell(i).SetCellValue(value?.ToString()); |
|||
} |
|||
} |
|||
} |
|||
|
|||
rowIndex++; |
|||
} |
|||
|
|||
var overMainRowIndex = rowIndex; |
|||
foreach (var detail in detailList) |
|||
{ |
|||
if (startMainRowIndex <= overMainRowIndex) |
|||
{ |
|||
//填充子表数据
|
|||
var detailRow = sheet.GetRow(startMainRowIndex); |
|||
|
|||
var splitCell = detailRow.CreateCell(mainProperties.Length); |
|||
splitCell.CellStyle = excelSplitCellStyle; |
|||
|
|||
for (var i = 0; i < detailProperties.Length; i++) |
|||
{ |
|||
var value = detailProperties[i].GetValue(detail); |
|||
detailRow.CreateCell(mainProperties.Length + splitDetailsColumnNumber + i) |
|||
.SetCellValue(value?.ToString()); |
|||
var detailCell = detailRow.GetCell(mainProperties.Length + splitDetailsColumnNumber + i); |
|||
detailCell.CellStyle = excelDetailsCellStyle; |
|||
} |
|||
} |
|||
|
|||
startMainRowIndex++; |
|||
} |
|||
} |
|||
else |
|||
{ |
|||
var dataRow = sheet.CreateRow(rowIndex); |
|||
// 填充主表数据
|
|||
for (var i = 0; i < mainProperties.Length; i++) |
|||
{ |
|||
var value = mainProperties[i].GetValue(mainDto); |
|||
dataRow.CreateCell(i).SetCellValue(value?.ToString()); |
|||
} |
|||
|
|||
if (rowIndex % 2 == 0) |
|||
{ |
|||
dataRow.RowStyle = excelOnlyMainCellStyle; |
|||
} |
|||
} |
|||
|
|||
//添加1个空行将2条数据分割开
|
|||
rowIndex++; |
|||
} |
|||
|
|||
#region 自动调整列宽
|
|||
|
|||
// 自动调整列宽 注意:这个影响性能 会遍历所有行 并且找出宽度最大值
|
|||
//sheet.AutoSizeColumn(i);
|
|||
if (isHasDetail) |
|||
{ |
|||
for (var i = 0; i < mainProperties.Length + splitDetailsColumnNumber + detailProperties.Length; i++) |
|||
{ |
|||
var colWidth = Math.Max(sheet.GetColumnWidth(i) + 150, 265 * 15); |
|||
if (colWidth > 255 * 256) //excel列有最大宽度限制
|
|||
{ |
|||
colWidth = 6000; |
|||
} |
|||
|
|||
sheet.SetColumnWidth(i, colWidth); |
|||
sheet.SetColumnWidth(mainProperties.Length, 3600); |
|||
} |
|||
} |
|||
else |
|||
{ |
|||
for (var i = 0; i < mainProperties.Length; i++) |
|||
{ |
|||
var colWidth = Math.Max(sheet.GetColumnWidth(i) + 150, 265 * 15); |
|||
if (colWidth > 255 * 256) //excel列有最大宽度限制
|
|||
{ |
|||
colWidth = 6000; |
|||
} |
|||
|
|||
sheet.SetColumnWidth(i, colWidth); |
|||
} |
|||
} |
|||
|
|||
#endregion
|
|||
|
|||
// 保存Excel文件到MemoryStream
|
|||
workbook.Write(fileStream, true); |
|||
fileStream.Position = 0; |
|||
|
|||
// 创建FileContentResult返回Excel文件
|
|||
var fileContentResult = new FileContentResult(fileStream.ToArray(), |
|||
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet") |
|||
{ |
|||
FileDownloadName = Localizer[typeof(TEntity).Name] + ".xlsx" |
|||
}; |
|||
|
|||
await Task.CompletedTask; |
|||
|
|||
return fileContentResult; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 【基础】-【获取 增 改 查基础的Dto中属性的数据类型】
|
|||
/// </summary>
|
|||
/// <returns></returns>
|
|||
[HttpPost("Base/Get-Dto-Column-Type")] |
|||
[Authorize] |
|||
public virtual async Task<List<AllTableColumnTypeDto>> GetDtoColumnTypeAsync() |
|||
{ |
|||
var tableColumnTypeDtos = new List<AllTableColumnTypeDto> |
|||
{ |
|||
GetTableColumnTypeByTable(typeof(TEntity), "S"), |
|||
GetTableColumnTypeByTable(typeof(TCreateInput), "C"), |
|||
GetTableColumnTypeByTable(typeof(TUpdateInput), "U"), |
|||
GetTableColumnTypeByTable(typeof(TEntity), "G") |
|||
}; |
|||
|
|||
await Task.CompletedTask; |
|||
return tableColumnTypeDtos; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 【基础】-【获取数据】-【缓存中读取】
|
|||
/// </summary>
|
|||
/// <returns></returns>
|
|||
[HttpPost("Base/Get-Cache-By-Id/{id}")] |
|||
[Authorize] |
|||
public virtual async Task<TEntityDto> GetCacheByIdAsync(TKey id) |
|||
{ |
|||
var entity = await Cache.GetOrAddAsync( |
|||
$"{typeof(TEntityDto).Name}:{id}".ToString(), |
|||
async () => await GetEntityByIdAsync(id), GetCacheTime); |
|||
|
|||
var dto = ObjectMapper.Map<TEntity, TEntityDto>(entity!); |
|||
return dto; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 【基础】-【获取数据】
|
|||
/// </summary>
|
|||
/// <param name="id"></param>
|
|||
/// <returns></returns>
|
|||
[HttpPost("Base/Get-By-Id/{id}")] |
|||
[Authorize] |
|||
public override Task<TEntityDto> GetAsync(TKey id) |
|||
{ |
|||
return base.GetAsync(id); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 【基础】-【获取数据】
|
|||
/// </summary>
|
|||
/// <param name="input"></param>
|
|||
/// <returns></returns>
|
|||
[HttpPost("Base/Get-List")] |
|||
[Authorize] |
|||
public override Task<PagedResultDto<TEntityDto>> GetListAsync(TPagedAndSortedResultRequestDto input) |
|||
{ |
|||
return base.GetListAsync(input); |
|||
} |
|||
|
|||
#endregion
|
|||
|
|||
#region 私有处理
|
|||
|
|||
/// <summary>
|
|||
/// 清除缓存
|
|||
/// </summary>
|
|||
/// <param name="id"></param>
|
|||
/// <returns></returns>
|
|||
protected async Task ReMoveCaCheAsync(TKey id) |
|||
{ |
|||
await Cache.RemoveAsync(id?.ToString()); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 按表达式条件获取分页列表
|
|||
/// </summary>
|
|||
/// <param name="expression"></param>
|
|||
/// <param name="skipCount"></param>
|
|||
/// <param name="maxResultCount"></param>
|
|||
/// <param name="sorting"></param>
|
|||
/// <param name="includeDetails"></param>
|
|||
/// <param name="cancellationToken"></param>
|
|||
/// <returns></returns>
|
|||
private async Task<List<TEntity>> GetQueryListAsync(Expression<Func<TEntity, bool>> expression, |
|||
int skipCount, int maxResultCount, string sorting, |
|||
bool includeDetails = false, CancellationToken cancellationToken = default) |
|||
{ |
|||
var query = await Repository.WithDetailsAsync(); |
|||
//var query = await Repository.GetQueryableAsync();
|
|||
|
|||
var entities = query.Where(expression); |
|||
entities = GetSortingQueryable(entities, sorting); |
|||
var str = entities.ToQueryString(); |
|||
|
|||
Console.WriteLine("---------查询开始---------"); |
|||
Console.WriteLine(); |
|||
Console.WriteLine(str); |
|||
Console.WriteLine(); |
|||
Console.WriteLine("---------查询结束---------"); |
|||
|
|||
var result = entities.Skip(skipCount).Take(maxResultCount).ToList(); |
|||
|
|||
return result; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 设置排序
|
|||
/// </summary>
|
|||
/// <param name="entities"></param>
|
|||
/// <param name="sorting"></param>
|
|||
/// <returns></returns>
|
|||
private IQueryable<TEntity> GetSortingQueryable(IQueryable<TEntity> entities, string sorting) |
|||
{ |
|||
if (string.IsNullOrEmpty(sorting)) |
|||
{ |
|||
var createTimePropertyInfo = typeof(TEntity).GetProperty(nameof(AuditedEntity.CreationTime)); |
|||
if (createTimePropertyInfo != null) |
|||
{ |
|||
entities = entities.OrderBy(nameof(AuditedEntity.CreationTime) + " DESC"); |
|||
} |
|||
else |
|||
{ |
|||
entities = entities.OrderBy("Id DESC"); |
|||
} |
|||
} |
|||
else |
|||
{ |
|||
entities = entities.OrderBy(sorting); |
|||
} |
|||
|
|||
return entities; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 获取Dto的属性名字和数据类型
|
|||
/// </summary>
|
|||
/// <param name="dtoType"></param>
|
|||
/// <param name="strDtoType"></param>
|
|||
/// <returns></returns>
|
|||
private AllTableColumnTypeDto GetTableColumnTypeByTable(Type dtoType, string strDtoType) |
|||
{ |
|||
var gDto = new AllTableColumnTypeDto |
|||
{ |
|||
DtoType = strDtoType, |
|||
DtoName = dtoType.FullName, |
|||
ColumnsTypes = new List<ColumnType>() |
|||
}; |
|||
var propertyInfos = dtoType.GetProperties(); |
|||
foreach (var propertyInfo in propertyInfos) |
|||
{ |
|||
var columnType = new ColumnType(); |
|||
columnType.IsEnum = false; |
|||
if (propertyInfo.PropertyType.GenericTypeArguments.Length > 0) |
|||
{ |
|||
if (propertyInfo.PropertyType.GenericTypeArguments[0].IsEnum) |
|||
{ |
|||
columnType.IsEnum = true; |
|||
} |
|||
|
|||
columnType.Z_ColumnBaseType = propertyInfo.PropertyType.GenericTypeArguments[0].FullName!; |
|||
} |
|||
else |
|||
{ |
|||
columnType.Z_ColumnBaseType = propertyInfo.PropertyType.FullName!; |
|||
} |
|||
|
|||
columnType.Z_ColumnName = propertyInfo.Name; |
|||
columnType.Z_ColumnType = propertyInfo.PropertyType.Name; |
|||
|
|||
|
|||
gDto.ColumnsTypes.Add(columnType); |
|||
} |
|||
|
|||
return gDto; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 【记录数量查询】【有筛选条件】
|
|||
/// </summary>
|
|||
/// <param name="expression"></param>
|
|||
/// <param name="cancellationToken"></param>
|
|||
/// <returns></returns>
|
|||
private async Task<long> GetCountAsync(Expression<Func<TEntity, bool>> expression, |
|||
CancellationToken cancellationToken = default) |
|||
{ |
|||
var count = await _repository.LongCountAsync(expression, cancellationToken); |
|||
|
|||
return count; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 获取缓存redis时间
|
|||
/// </summary>
|
|||
/// <returns></returns>
|
|||
private static DistributedCacheEntryOptions GetCacheTime() |
|||
{ |
|||
var random = new Random(); |
|||
//解决雪崩 添加随机缓存时间
|
|||
var time = CacheMinute + random.Next(10, 30); |
|||
return new DistributedCacheEntryOptions |
|||
{ |
|||
AbsoluteExpiration = DateTimeOffset.Now.AddMinutes(time) |
|||
}; |
|||
} |
|||
|
|||
|
|||
#region Excel导出的样式设置
|
|||
|
|||
/// <summary>
|
|||
/// 导出设置子表单元格样式
|
|||
/// </summary>
|
|||
/// <param name="workbook"></param>
|
|||
/// <returns></returns>
|
|||
private static ICellStyle SetExcelDetailsCellStyle(IWorkbook workbook) |
|||
{ |
|||
var cellStyle = workbook.CreateCellStyle(); |
|||
cellStyle.FillBackgroundColor = IndexedColors.Grey25Percent.Index; |
|||
cellStyle.FillForegroundColor = IndexedColors.Grey25Percent.Index; |
|||
cellStyle.FillPattern = FillPattern.SolidForeground; |
|||
return cellStyle; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 导出设置只有主表时的交替行 单元格样式
|
|||
/// </summary>
|
|||
/// <param name="workbook"></param>
|
|||
/// <returns></returns>
|
|||
private static ICellStyle SetExcelOnlyMainCellStyle(IWorkbook workbook) |
|||
{ |
|||
var cellStyle = workbook.CreateCellStyle(); |
|||
cellStyle.FillBackgroundColor = IndexedColors.Grey25Percent.Index; |
|||
cellStyle.FillForegroundColor = IndexedColors.Grey25Percent.Index; |
|||
cellStyle.FillPattern = FillPattern.SolidForeground; |
|||
return cellStyle; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 设置分割单元格的样式
|
|||
/// </summary>
|
|||
/// <param name="workbook"></param>
|
|||
/// <returns></returns>
|
|||
private static ICellStyle SetSplitCellStyle(IWorkbook workbook) |
|||
{ |
|||
var cellStyle = workbook.CreateCellStyle(); |
|||
cellStyle.BorderLeft = BorderStyle.MediumDashed; |
|||
cellStyle.BorderRight = BorderStyle.MediumDashed; |
|||
cellStyle.LeftBorderColor = IndexedColors.BrightGreen.Index; |
|||
cellStyle.RightBorderColor = IndexedColors.Grey25Percent.Index; |
|||
cellStyle.FillBackgroundColor = IndexedColors.White.Index; |
|||
cellStyle.FillForegroundColor = IndexedColors.White.Index; |
|||
cellStyle.FillPattern = FillPattern.ThickVerticalBands; |
|||
return cellStyle; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 导出设置表头单元格样式
|
|||
/// </summary>
|
|||
/// <param name="workbook"></param>
|
|||
/// <returns></returns>
|
|||
private static ICellStyle SetExcelHeadCellStyle(IWorkbook workbook) |
|||
{ |
|||
var cellStyle = workbook.CreateCellStyle(); |
|||
cellStyle.FillBackgroundColor = IndexedColors.LightOrange.Index; |
|||
cellStyle.FillForegroundColor = IndexedColors.LightOrange.Index; |
|||
cellStyle.FillPattern = FillPattern.SolidForeground; |
|||
return cellStyle; |
|||
} |
|||
|
|||
public static void MapProperties<TSrc, TDest>(TSrc source, TDest destination) |
|||
{ |
|||
if (source == null || destination == null) |
|||
{ |
|||
throw new ArgumentNullException("Source and destination objects must not be null."); |
|||
} |
|||
|
|||
var sourceType = typeof(TSrc); |
|||
var destType = typeof(TDest); |
|||
|
|||
var sourceProperties = sourceType.GetProperties(); |
|||
var destProperties = destType.GetProperties(); |
|||
|
|||
foreach (var sourceProperty in sourceProperties) |
|||
{ |
|||
var destProperty = Array.Find(destProperties, |
|||
p => p.Name == sourceProperty.Name && p.PropertyType == sourceProperty.PropertyType); |
|||
|
|||
if (destProperty != null && destProperty.CanWrite && destProperty.Name != "Id" && |
|||
destProperty.Name != "ConcurrencyStamp") |
|||
{ |
|||
var value = sourceProperty.GetValue(source); |
|||
destProperty.SetValue(destination, value); |
|||
} |
|||
} |
|||
} |
|||
|
|||
#endregion
|
|||
|
|||
#endregion
|
|||
} |
@ -0,0 +1,52 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Threading.Tasks; |
|||
using Microsoft.AspNetCore.Mvc; |
|||
using Volo.Abp.Application.Services; |
|||
using WinIn.FasterZ.Inventory.AppBaseBusiness.ExportCustomUserSetting; |
|||
using WinIn.FasterZ.Inventory.AppBaseBusiness.ExportCustomUserSetting.Dtos; |
|||
|
|||
|
|||
namespace WinIn.FasterZ.Wms.AppBaseBusiness.ExportCustomUserSetting |
|||
{ |
|||
using Dy_Exchange.Permissions; |
|||
using WinIn.FasterZ.Wms.AppBase; |
|||
|
|||
/// <summary>
|
|||
/// 用户个型导出配置
|
|||
/// </summary>
|
|||
public class ExportCustomUserSettingAppService : CrudAppService<Inventory.AppBaseBusiness.ExportCustomUserSetting.ExportCustomUserSetting, ExportCustomUserSettingDto, Guid, |
|||
ExportCustomUserSettingGetListInput, CreateUpdateExportCustomUserSettingDto, |
|||
CreateUpdateExportCustomUserSettingDto>, |
|||
IExportCustomUserSettingAppService |
|||
{ |
|||
private readonly IExportCustomUserSettingRepository _repository; |
|||
|
|||
public ExportCustomUserSettingAppService(IExportCustomUserSettingRepository repository) : base(repository) |
|||
{ |
|||
_repository = repository; |
|||
} |
|||
|
|||
protected override string GetPolicyName { get; set; } = Dy_ExchangePermissions.ExportCustomUserSetting.Default; |
|||
protected override string GetListPolicyName { get; set; } = Dy_ExchangePermissions.ExportCustomUserSetting.Default; |
|||
protected override string CreatePolicyName { get; set; } = Dy_ExchangePermissions.ExportCustomUserSetting.Create; |
|||
protected override string UpdatePolicyName { get; set; } = Dy_ExchangePermissions.ExportCustomUserSetting.Update; |
|||
protected override string DeletePolicyName { get; set; } = Dy_ExchangePermissions.ExportCustomUserSetting.Delete; |
|||
|
|||
/// <summary>
|
|||
/// 根据用户和表名获取个性化导出
|
|||
/// </summary>
|
|||
/// <returns></returns>
|
|||
[HttpPost("get-by-user-and-table-name")] |
|||
public virtual async Task<List<ExportCustomUserSettingDto>> GetByUserIdAndExportTableNameAsync(Guid userId, |
|||
string exportTableName) |
|||
{ |
|||
var entitys = |
|||
await _repository.GetListAsync(p => p.ExportUserId == userId && p.ExportTableName == exportTableName); |
|||
|
|||
return ObjectMapper.Map<List<Inventory.AppBaseBusiness.ExportCustomUserSetting.ExportCustomUserSetting>, List<ExportCustomUserSettingDto>>(entitys); |
|||
} |
|||
|
|||
} |
|||
} |
@ -0,0 +1,27 @@ |
|||
<Project Sdk="Microsoft.NET.Sdk"> |
|||
|
|||
<Import Project="..\..\common.props" /> |
|||
|
|||
<PropertyGroup> |
|||
<TargetFramework>net7.0</TargetFramework> |
|||
<Nullable>enable</Nullable> |
|||
<RootNamespace>Dy_Exchange</RootNamespace> |
|||
</PropertyGroup> |
|||
|
|||
<ItemGroup> |
|||
<ProjectReference Include="..\Dy_Exchange.Domain\Dy_Exchange.Domain.csproj" /> |
|||
<ProjectReference Include="..\Dy_Exchange.Application.Contracts\Dy_Exchange.Application.Contracts.csproj" /> |
|||
</ItemGroup> |
|||
|
|||
<ItemGroup> |
|||
<PackageReference Include="NPOI" Version="2.7.1" /> |
|||
<PackageReference Include="ValueInjecter" Version="3.2.0" /> |
|||
<PackageReference Include="Volo.Abp.Account.Application" Version="7.3.2" /> |
|||
<PackageReference Include="Volo.Abp.Identity.Application" Version="7.3.2" /> |
|||
<PackageReference Include="Volo.Abp.PermissionManagement.Application" Version="7.3.2" /> |
|||
<PackageReference Include="Volo.Abp.TenantManagement.Application" Version="7.3.2" /> |
|||
<PackageReference Include="Volo.Abp.FeatureManagement.Application" Version="7.3.2" /> |
|||
<PackageReference Include="Volo.Abp.SettingManagement.Application" Version="7.3.2" /> |
|||
</ItemGroup> |
|||
|
|||
</Project> |
@ -0,0 +1,17 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Text; |
|||
using Dy_Exchange.Localization; |
|||
using Volo.Abp.Application.Services; |
|||
|
|||
namespace Dy_Exchange; |
|||
|
|||
/* Inherit your application services from this class. |
|||
*/ |
|||
public abstract class Dy_ExchangeAppService : ApplicationService |
|||
{ |
|||
protected Dy_ExchangeAppService() |
|||
{ |
|||
LocalizationResource = typeof(Dy_ExchangeResource); |
|||
} |
|||
} |
@ -0,0 +1,17 @@ |
|||
using Dy_Exchange.Z_Business; |
|||
using Dy_Exchange.Z_Business.Dtos; |
|||
using AutoMapper; |
|||
|
|||
namespace Dy_Exchange; |
|||
|
|||
public class Dy_ExchangeApplicationAutoMapperProfile : Profile |
|||
{ |
|||
public Dy_ExchangeApplicationAutoMapperProfile() |
|||
{ |
|||
/* You can configure your AutoMapper mapping configuration here. |
|||
* Alternatively, you can split your mapping configurations |
|||
* into multiple profile classes for a better organization. */ |
|||
CreateMap<DataExchangeInterfaceConfig, DataExchangeInterfaceConfigDto>(); |
|||
CreateMap<CreateUpdateDataExchangeInterfaceConfigDto, DataExchangeInterfaceConfig>(MemberList.Source); |
|||
} |
|||
} |
@ -0,0 +1,31 @@ |
|||
using Volo.Abp.Account; |
|||
using Volo.Abp.AutoMapper; |
|||
using Volo.Abp.FeatureManagement; |
|||
using Volo.Abp.Identity; |
|||
using Volo.Abp.Modularity; |
|||
using Volo.Abp.PermissionManagement; |
|||
using Volo.Abp.SettingManagement; |
|||
using Volo.Abp.TenantManagement; |
|||
|
|||
namespace Dy_Exchange; |
|||
|
|||
[DependsOn( |
|||
typeof(Dy_ExchangeDomainModule), |
|||
typeof(AbpAccountApplicationModule), |
|||
typeof(Dy_ExchangeApplicationContractsModule), |
|||
typeof(AbpIdentityApplicationModule), |
|||
typeof(AbpPermissionManagementApplicationModule), |
|||
typeof(AbpTenantManagementApplicationModule), |
|||
typeof(AbpFeatureManagementApplicationModule), |
|||
typeof(AbpSettingManagementApplicationModule) |
|||
)] |
|||
public class Dy_ExchangeApplicationModule : AbpModule |
|||
{ |
|||
public override void ConfigureServices(ServiceConfigurationContext context) |
|||
{ |
|||
Configure<AbpAutoMapperOptions>(options => |
|||
{ |
|||
options.AddMaps<Dy_ExchangeApplicationModule>(); |
|||
}); |
|||
} |
|||
} |
@ -0,0 +1,2 @@ |
|||
using System.Runtime.CompilerServices; |
|||
[assembly:InternalsVisibleToAttribute("Dy_Exchange.Application.Tests")] |
@ -0,0 +1,30 @@ |
|||
using System; |
|||
using Dy_Exchange.Permissions; |
|||
using Dy_Exchange.Z_Business.Dtos; |
|||
using Volo.Abp.Application.Dtos; |
|||
using Volo.Abp.Application.Services; |
|||
using WinIn.FasterZ.Wms.AppBase; |
|||
|
|||
namespace Dy_Exchange.Z_Business; |
|||
|
|||
|
|||
/// <summary>
|
|||
///
|
|||
/// </summary>
|
|||
public class DataExchangeInterfaceConfigAppService : ZbxBase<DataExchangeInterfaceConfig, DataExchangeInterfaceConfigDto, Guid, PagedAndSortedResultRequestDto, CreateUpdateDataExchangeInterfaceConfigDto, CreateUpdateDataExchangeInterfaceConfigDto>, |
|||
IDataExchangeInterfaceConfigAppService |
|||
{ |
|||
protected override string GetPolicyName { get; set; } = Dy_ExchangePermissions.DataExchangeInterfaceConfig.Default; |
|||
protected override string GetListPolicyName { get; set; } = Dy_ExchangePermissions.DataExchangeInterfaceConfig.Default; |
|||
protected override string CreatePolicyName { get; set; } = Dy_ExchangePermissions.DataExchangeInterfaceConfig.Create; |
|||
protected override string UpdatePolicyName { get; set; } = Dy_ExchangePermissions.DataExchangeInterfaceConfig.Update; |
|||
protected override string DeletePolicyName { get; set; } = Dy_ExchangePermissions.DataExchangeInterfaceConfig.Delete; |
|||
|
|||
private readonly IDataExchangeInterfaceConfigRepository _repository; |
|||
|
|||
public DataExchangeInterfaceConfigAppService(IDataExchangeInterfaceConfigRepository repository) : base(repository) |
|||
{ |
|||
_repository = repository; |
|||
} |
|||
|
|||
} |
@ -0,0 +1,56 @@ |
|||
<Project Sdk="Microsoft.NET.Sdk.Web"> |
|||
|
|||
<Import Project="..\..\common.props" /> |
|||
|
|||
<PropertyGroup> |
|||
<TargetFramework>net7.0</TargetFramework> |
|||
<Nullable>enable</Nullable> |
|||
<RootNamespace>Dy_Exchange</RootNamespace> |
|||
<AssetTargetFallback>$(AssetTargetFallback);portable-net45+win8+wp8+wpa81;</AssetTargetFallback> |
|||
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects> |
|||
<GenerateBindingRedirectsOutputType>true</GenerateBindingRedirectsOutputType> |
|||
<GenerateRuntimeConfigurationFiles>true</GenerateRuntimeConfigurationFiles> |
|||
<MvcRazorExcludeRefAssembliesFromPublish>false</MvcRazorExcludeRefAssembliesFromPublish> |
|||
<PreserveCompilationReferences>true</PreserveCompilationReferences> |
|||
<UserSecretsId>Dy_Exchange-4681b4fd-151f-4221-84a4-929d86723e4c</UserSecretsId> |
|||
</PropertyGroup> |
|||
|
|||
<ItemGroup> |
|||
<Compile Remove="Logs\**" /> |
|||
<Content Remove="Logs\**" /> |
|||
<EmbeddedResource Remove="Logs\**" /> |
|||
<None Remove="Logs\**" /> |
|||
</ItemGroup> |
|||
|
|||
<ItemGroup> |
|||
<None Update="Pages\**\*.js"> |
|||
<CopyToOutputDirectory>Always</CopyToOutputDirectory> |
|||
</None> |
|||
<None Update="Pages\**\*.css"> |
|||
<CopyToOutputDirectory>Always</CopyToOutputDirectory> |
|||
</None> |
|||
</ItemGroup> |
|||
|
|||
<ItemGroup> |
|||
<PackageReference Include="Serilog.AspNetCore" Version="5.0.0" /> |
|||
<PackageReference Include="Serilog.Sinks.Async" Version="1.5.0" /> |
|||
<PackageReference Include="Microsoft.AspNetCore.DataProtection.StackExchangeRedis" Version="7.0.0" /> |
|||
<PackageReference Include="DistributedLock.Redis" Version="1.0.2" /> |
|||
</ItemGroup> |
|||
|
|||
<ItemGroup> |
|||
<PackageReference Include="Volo.Abp.AspNetCore.Mvc.UI.Theme.LeptonXLite" Version="2.3.*-*" /> |
|||
</ItemGroup> |
|||
|
|||
<ItemGroup> |
|||
<PackageReference Include="Volo.Abp.Autofac" Version="7.3.2" /> |
|||
<PackageReference Include="Volo.Abp.Caching.StackExchangeRedis" Version="7.3.2" /> |
|||
<PackageReference Include="Volo.Abp.DistributedLocking" Version="7.3.2" /> |
|||
<PackageReference Include="Volo.Abp.AspNetCore.Serilog" Version="7.3.2" /> |
|||
<PackageReference Include="Volo.Abp.Account.Web.OpenIddict" Version="7.3.2" /> |
|||
<PackageReference Include="Volo.Abp.Account.Application" Version="7.3.2" /> |
|||
<PackageReference Include="Volo.Abp.Account.HttpApi" Version="7.3.2" /> |
|||
<ProjectReference Include="..\Dy_Exchange.EntityFrameworkCore\Dy_Exchange.EntityFrameworkCore.csproj" /> |
|||
</ItemGroup> |
|||
|
|||
</Project> |
@ -0,0 +1,194 @@ |
|||
using System; |
|||
using System.IO; |
|||
using System.Linq; |
|||
using Localization.Resources.AbpUi; |
|||
using Medallion.Threading; |
|||
using Medallion.Threading.Redis; |
|||
using Microsoft.AspNetCore.Builder; |
|||
using Microsoft.AspNetCore.Cors; |
|||
using Microsoft.AspNetCore.DataProtection; |
|||
using Microsoft.Extensions.DependencyInjection; |
|||
using Microsoft.Extensions.Hosting; |
|||
using Dy_Exchange.EntityFrameworkCore; |
|||
using Dy_Exchange.Localization; |
|||
using Dy_Exchange.MultiTenancy; |
|||
using StackExchange.Redis; |
|||
using Volo.Abp; |
|||
using Volo.Abp.Account; |
|||
using Volo.Abp.Account.Web; |
|||
using Volo.Abp.AspNetCore.Mvc.UI; |
|||
using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap; |
|||
using Volo.Abp.AspNetCore.Mvc.UI.Bundling; |
|||
using Volo.Abp.AspNetCore.Mvc.UI.Theme.LeptonXLite; |
|||
using Volo.Abp.AspNetCore.Mvc.UI.Theme.LeptonXLite.Bundling; |
|||
using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared; |
|||
using Volo.Abp.AspNetCore.Serilog; |
|||
using Volo.Abp.Auditing; |
|||
using Volo.Abp.Autofac; |
|||
using Volo.Abp.BackgroundJobs; |
|||
using Volo.Abp.Caching; |
|||
using Volo.Abp.Caching.StackExchangeRedis; |
|||
using Volo.Abp.DistributedLocking; |
|||
using Volo.Abp.Localization; |
|||
using Volo.Abp.Modularity; |
|||
using Volo.Abp.UI.Navigation.Urls; |
|||
using Volo.Abp.UI; |
|||
using Volo.Abp.VirtualFileSystem; |
|||
|
|||
namespace Dy_Exchange; |
|||
|
|||
[DependsOn( |
|||
typeof(AbpAutofacModule), |
|||
typeof(AbpCachingStackExchangeRedisModule), |
|||
typeof(AbpDistributedLockingModule), |
|||
typeof(AbpAccountWebOpenIddictModule), |
|||
typeof(AbpAccountApplicationModule), |
|||
typeof(AbpAccountHttpApiModule), |
|||
typeof(AbpAspNetCoreMvcUiLeptonXLiteThemeModule), |
|||
typeof(Dy_ExchangeEntityFrameworkCoreModule), |
|||
typeof(AbpAspNetCoreSerilogModule) |
|||
)] |
|||
public class Dy_ExchangeAuthServerModule : AbpModule |
|||
{ |
|||
public override void PreConfigureServices(ServiceConfigurationContext context) |
|||
{ |
|||
PreConfigure<OpenIddictBuilder>(builder => |
|||
{ |
|||
builder.AddValidation(options => |
|||
{ |
|||
options.AddAudiences("Dy_Exchange"); |
|||
options.UseLocalServer(); |
|||
options.UseAspNetCore(); |
|||
}); |
|||
}); |
|||
} |
|||
|
|||
public override void ConfigureServices(ServiceConfigurationContext context) |
|||
{ |
|||
var hostingEnvironment = context.Services.GetHostingEnvironment(); |
|||
var configuration = context.Services.GetConfiguration(); |
|||
|
|||
Configure<AbpLocalizationOptions>(options => |
|||
{ |
|||
options.Resources |
|||
.Get<Dy_ExchangeResource>() |
|||
.AddBaseTypes( |
|||
typeof(AbpUiResource) |
|||
); |
|||
}); |
|||
|
|||
Configure<AbpBundlingOptions>(options => |
|||
{ |
|||
options.StyleBundles.Configure( |
|||
LeptonXLiteThemeBundles.Styles.Global, |
|||
bundle => |
|||
{ |
|||
bundle.AddFiles("/global-styles.css"); |
|||
} |
|||
); |
|||
}); |
|||
|
|||
Configure<AbpAuditingOptions>(options => |
|||
{ |
|||
//options.IsEnabledForGetRequests = true;
|
|||
options.ApplicationName = "AuthServer"; |
|||
}); |
|||
|
|||
if (hostingEnvironment.IsDevelopment()) |
|||
{ |
|||
Configure<AbpVirtualFileSystemOptions>(options => |
|||
{ |
|||
options.FileSets.ReplaceEmbeddedByPhysical<Dy_ExchangeDomainSharedModule>(Path.Combine(hostingEnvironment.ContentRootPath, $"..{Path.DirectorySeparatorChar}Dy_Exchange.Domain.Shared")); |
|||
options.FileSets.ReplaceEmbeddedByPhysical<Dy_ExchangeDomainModule>(Path.Combine(hostingEnvironment.ContentRootPath, $"..{Path.DirectorySeparatorChar}Dy_Exchange.Domain")); |
|||
}); |
|||
} |
|||
|
|||
Configure<AppUrlOptions>(options => |
|||
{ |
|||
options.Applications["MVC"].RootUrl = configuration["App:SelfUrl"]; |
|||
options.RedirectAllowedUrls.AddRange(configuration["App:RedirectAllowedUrls"]?.Split(',') ?? Array.Empty<string>()); |
|||
|
|||
options.Applications["Angular"].RootUrl = configuration["App:ClientUrl"]; |
|||
options.Applications["Angular"].Urls[AccountUrlNames.PasswordReset] = "account/reset-password"; |
|||
}); |
|||
|
|||
Configure<AbpBackgroundJobOptions>(options => |
|||
{ |
|||
options.IsJobExecutionEnabled = false; |
|||
}); |
|||
|
|||
Configure<AbpDistributedCacheOptions>(options => |
|||
{ |
|||
options.KeyPrefix = "Dy_Exchange:"; |
|||
}); |
|||
|
|||
var dataProtectionBuilder = context.Services.AddDataProtection().SetApplicationName("Dy_Exchange"); |
|||
if (!hostingEnvironment.IsDevelopment()) |
|||
{ |
|||
var redis = ConnectionMultiplexer.Connect(configuration["Redis:Configuration"]); |
|||
dataProtectionBuilder.PersistKeysToStackExchangeRedis(redis, "Dy_Exchange-Protection-Keys"); |
|||
} |
|||
|
|||
context.Services.AddSingleton<IDistributedLockProvider>(sp => |
|||
{ |
|||
var connection = ConnectionMultiplexer |
|||
.Connect(configuration["Redis:Configuration"]); |
|||
return new RedisDistributedSynchronizationProvider(connection.GetDatabase()); |
|||
}); |
|||
|
|||
context.Services.AddCors(options => |
|||
{ |
|||
options.AddDefaultPolicy(builder => |
|||
{ |
|||
builder |
|||
.WithOrigins( |
|||
configuration["App:CorsOrigins"]? |
|||
.Split(",", StringSplitOptions.RemoveEmptyEntries) |
|||
.Select(o => o.RemovePostFix("/")) |
|||
.ToArray() ?? Array.Empty<string>() |
|||
) |
|||
.WithAbpExposedHeaders() |
|||
.SetIsOriginAllowedToAllowWildcardSubdomains() |
|||
.AllowAnyHeader() |
|||
.AllowAnyMethod() |
|||
.AllowCredentials(); |
|||
}); |
|||
}); |
|||
} |
|||
|
|||
public override void OnApplicationInitialization(ApplicationInitializationContext context) |
|||
{ |
|||
var app = context.GetApplicationBuilder(); |
|||
var env = context.GetEnvironment(); |
|||
|
|||
if (env.IsDevelopment()) |
|||
{ |
|||
app.UseDeveloperExceptionPage(); |
|||
} |
|||
|
|||
app.UseAbpRequestLocalization(); |
|||
|
|||
if (!env.IsDevelopment()) |
|||
{ |
|||
app.UseErrorPage(); |
|||
} |
|||
|
|||
app.UseCorrelationId(); |
|||
app.UseStaticFiles(); |
|||
app.UseRouting(); |
|||
app.UseCors(); |
|||
app.UseAuthentication(); |
|||
app.UseAbpOpenIddictValidation(); |
|||
|
|||
if (MultiTenancyConsts.IsEnabled) |
|||
{ |
|||
app.UseMultiTenancy(); |
|||
} |
|||
|
|||
app.UseUnitOfWork(); |
|||
app.UseAuthorization(); |
|||
app.UseAuditing(); |
|||
app.UseAbpSerilogEnrichers(); |
|||
app.UseConfiguredEndpoints(); |
|||
} |
|||
} |
@ -0,0 +1,10 @@ |
|||
using Volo.Abp.Ui.Branding; |
|||
using Volo.Abp.DependencyInjection; |
|||
|
|||
namespace Dy_Exchange; |
|||
|
|||
[Dependency(ReplaceServices = true)] |
|||
public class Dy_ExchangeBrandingProvider : DefaultBrandingProvider |
|||
{ |
|||
public override string AppName => "Dy_Exchange"; |
|||
} |
@ -0,0 +1,115 @@ |
|||
@page |
|||
@using Microsoft.AspNetCore.Http.Extensions |
|||
@using Microsoft.AspNetCore.Mvc.Localization |
|||
@using Dy_Exchange.Pages |
|||
@using Dy_Exchange.Localization |
|||
@using Volo.Abp.Users |
|||
@using Volo.Abp.AspNetCore.Mvc.UI.Theming |
|||
@using Volo.Abp.Ui.Branding |
|||
@model IndexModel |
|||
@inject IHtmlLocalizer<Dy_ExchangeResource> L |
|||
@inject ICurrentUser CurrentUser |
|||
@inject IBrandingProvider BrandingProvider |
|||
@inject ITheme Theme |
|||
|
|||
@{ |
|||
Layout = Theme.GetEmptyLayout(); |
|||
} |
|||
|
|||
<div class="d-flex align-items-center" style="min-height: 100vh;"> |
|||
<div class="container"> |
|||
<abp-row> |
|||
<div class="col mx-auto account-column"> |
|||
<div class="account-brand p-4 text-center mb-1"> |
|||
@if (!BrandingProvider.LogoUrl.IsNullOrEmpty()) |
|||
{ |
|||
<a class="navbar-brand" href="~/" alt="@BrandingProvider.AppName"></a> |
|||
} |
|||
else |
|||
{ |
|||
<h1>@BrandingProvider.AppName</h1> |
|||
} |
|||
</div> |
|||
<abp-card> |
|||
<abp-card-body> |
|||
<div class="container"> |
|||
<abp-row> |
|||
<abp-column size="_9"> |
|||
|
|||
<div class="d-flex align-items-center"> |
|||
<div class="me-3 p-2"> |
|||
<i class="fa fa-user d-block" style="font-size: 10em; color: #12b900"></i> |
|||
</div> |
|||
<div class="p2"> |
|||
@if (CurrentUser.IsAuthenticated) |
|||
{ |
|||
<span class="fs-16"> |
|||
@L["Welcome"] <span class="fw-7">@CurrentUser.UserName</span> |
|||
</span> |
|||
<span class="fs-14 d-block text-dark-800 opacity-75 mb-1">@CurrentUser.Email</span> |
|||
<div class="d-grid gap-2"> |
|||
<a abp-button="Outline_Primary" asp-controller="Manage" asp-action="Index" asp-area="Account">@L["MyAccount"]</a> |
|||
<a abp-button="Primary" asp-controller="Logout" asp-action="Index" asp-area="Account">@L["Logout"]</a> |
|||
</div> |
|||
} |
|||
else |
|||
{ |
|||
<a abp-button="Primary" asp-controller="Login" asp-action="Index" asp-area="Account">@L["Login"]</a> |
|||
} |
|||
</div> |
|||
|
|||
</div> |
|||
</abp-column> |
|||
<abp-column size="_3"> |
|||
<div class="ml-auto p-2 float-end"> |
|||
<abp-dropdown> |
|||
<abp-dropdown-button text="@Model.CurrentLanguage" /> |
|||
@if (@Model.Languages != null) |
|||
{ |
|||
<abp-dropdown-menu> |
|||
@foreach (var language in Model.Languages) |
|||
{ |
|||
var languageUrl = Url.Content($"~/Abp/Languages/Switch?culture={language.CultureName}&uiCulture={language.UiCultureName}&returnUrl={System.Net.WebUtility.UrlEncode(Request.GetEncodedPathAndQuery())}"); |
|||
<abp-dropdown-item href="@languageUrl">@language.DisplayName</abp-dropdown-item> |
|||
} |
|||
</abp-dropdown-menu> |
|||
} |
|||
</abp-dropdown> |
|||
</div> |
|||
</abp-column> |
|||
</abp-row> |
|||
<hr class="m-4" /> |
|||
<abp-row> |
|||
@if (Model.Applications != null) |
|||
{ |
|||
foreach (var application in Model.Applications) |
|||
{ |
|||
<abp-column size-md="@Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Grid.ColumnSize._4" class="mb-2"> |
|||
<abp-card> |
|||
<abp-card-body> |
|||
|
|||
@if (!application.LogoUri.IsNullOrEmpty()) |
|||
{ |
|||
<div class="mx-auto"> |
|||
<img src="@application.LogoUri" style="height:64px" class="mb-3"/> |
|||
</div> |
|||
} |
|||
|
|||
<h4>@application.DisplayName</h4> |
|||
<span class="text-muted">@application.ClientUri</span> |
|||
<div class="mt-1"> |
|||
<a abp-button="@Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Button.AbpButtonType.Outline_Secondary" href="@application.ClientUri">@L["Visit"]</a> |
|||
</div> |
|||
</abp-card-body> |
|||
</abp-card> |
|||
</abp-column> |
|||
} |
|||
} |
|||
</abp-row> |
|||
</div> |
|||
</abp-card-body> |
|||
</abp-card> |
|||
</div> |
|||
</abp-row> |
|||
</div> |
|||
</div> |
@ -0,0 +1,35 @@ |
|||
using System.Collections.Generic; |
|||
using System.Globalization; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.AspNetCore.Mvc.UI.RazorPages; |
|||
using Volo.Abp.Localization; |
|||
using Volo.Abp.OpenIddict.Applications; |
|||
|
|||
namespace Dy_Exchange.Pages; |
|||
|
|||
public class IndexModel : AbpPageModel |
|||
{ |
|||
public List<OpenIddictApplication>? Applications { get; protected set; } |
|||
|
|||
public IReadOnlyList<LanguageInfo>? Languages { get; protected set; } |
|||
|
|||
public string? CurrentLanguage { get; protected set; } |
|||
|
|||
protected IOpenIddictApplicationRepository OpenIdApplicationRepository { get; } |
|||
|
|||
protected ILanguageProvider LanguageProvider { get; } |
|||
|
|||
public IndexModel(IOpenIddictApplicationRepository openIdApplicationRepository, ILanguageProvider languageProvider) |
|||
{ |
|||
OpenIdApplicationRepository = openIdApplicationRepository; |
|||
LanguageProvider = languageProvider; |
|||
} |
|||
|
|||
public async Task OnGetAsync() |
|||
{ |
|||
Applications = await OpenIdApplicationRepository.GetListAsync(); |
|||
|
|||
Languages = await LanguageProvider.GetLanguagesAsync(); |
|||
CurrentLanguage = CultureInfo.CurrentCulture.DisplayName; |
|||
} |
|||
} |
@ -0,0 +1,4 @@ |
|||
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers |
|||
@addTagHelper *, Volo.Abp.AspNetCore.Mvc.UI |
|||
@addTagHelper *, Volo.Abp.AspNetCore.Mvc.UI.Bootstrap |
|||
@addTagHelper *, Volo.Abp.AspNetCore.Mvc.UI.Bundling |
@ -0,0 +1,56 @@ |
|||
using System; |
|||
using System.Threading.Tasks; |
|||
using Microsoft.AspNetCore.Builder; |
|||
using Microsoft.Extensions.DependencyInjection; |
|||
using Microsoft.Extensions.Hosting; |
|||
using Serilog; |
|||
using Serilog.Events; |
|||
|
|||
namespace Dy_Exchange; |
|||
|
|||
public class Program |
|||
{ |
|||
public async static Task<int> Main(string[] args) |
|||
{ |
|||
Log.Logger = new LoggerConfiguration() |
|||
#if DEBUG
|
|||
.MinimumLevel.Debug() |
|||
#else
|
|||
.MinimumLevel.Information() |
|||
#endif
|
|||
.MinimumLevel.Override("Microsoft", LogEventLevel.Information) |
|||
.MinimumLevel.Override("Microsoft.EntityFrameworkCore", LogEventLevel.Warning) |
|||
.Enrich.FromLogContext() |
|||
.WriteTo.Async(c => c.File("Logs/logs.txt")) |
|||
.WriteTo.Async(c => c.Console()) |
|||
.CreateLogger(); |
|||
|
|||
try |
|||
{ |
|||
Log.Information("Starting Dy_Exchange.AuthServer."); |
|||
var builder = WebApplication.CreateBuilder(args); |
|||
builder.Host.AddAppSettingsSecretsJson() |
|||
.UseAutofac() |
|||
.UseSerilog(); |
|||
await builder.AddApplicationAsync<Dy_ExchangeAuthServerModule>(); |
|||
var app = builder.Build(); |
|||
await app.InitializeApplicationAsync(); |
|||
await app.RunAsync(); |
|||
return 0; |
|||
} |
|||
catch (Exception ex) |
|||
{ |
|||
if (ex is HostAbortedException) |
|||
{ |
|||
throw; |
|||
} |
|||
|
|||
Log.Fatal(ex, "Dy_Exchange.AuthServer terminated unexpectedly!"); |
|||
return 1; |
|||
} |
|||
finally |
|||
{ |
|||
Log.CloseAndFlush(); |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,27 @@ |
|||
{ |
|||
"iisSettings": { |
|||
"windowsAuthentication": false, |
|||
"anonymousAuthentication": true, |
|||
"iisExpress": { |
|||
"applicationUrl": "https://localhost:44365", |
|||
"sslPort": 44365 |
|||
} |
|||
}, |
|||
"profiles": { |
|||
"IIS Express": { |
|||
"commandName": "IISExpress", |
|||
"launchBrowser": true, |
|||
"environmentVariables": { |
|||
"ASPNETCORE_ENVIRONMENT": "Development" |
|||
} |
|||
}, |
|||
"Dy_Exchange.AuthServer": { |
|||
"commandName": "Project", |
|||
"launchBrowser": true, |
|||
"applicationUrl": "https://localhost:44365", |
|||
"environmentVariables": { |
|||
"ASPNETCORE_ENVIRONMENT": "Development" |
|||
} |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,11 @@ |
|||
module.exports = { |
|||
aliases: { |
|||
|
|||
}, |
|||
clean: [ |
|||
|
|||
], |
|||
mappings: { |
|||
|
|||
} |
|||
}; |
@ -0,0 +1,2 @@ |
|||
{ |
|||
} |
@ -0,0 +1,17 @@ |
|||
{ |
|||
"App": { |
|||
"SelfUrl": "https://localhost:44365", |
|||
"ClientUrl": "http://localhost:4200", |
|||
"CorsOrigins": "https://*.Dy_Exchange.com,http://localhost:4200,https://localhost:44318,https://localhost:44363", |
|||
"RedirectAllowedUrls": "http://localhost:4200,https://localhost:44376,https://localhost:44318,https://localhost:44328" |
|||
}, |
|||
"ConnectionStrings": { |
|||
"Default": "Server=(LocalDb)\\MSSQLLocalDB;Database=Dy_Exchange;Trusted_Connection=True;TrustServerCertificate=True" |
|||
}, |
|||
"Redis": { |
|||
"Configuration": "127.0.0.1" |
|||
}, |
|||
"StringEncryption": { |
|||
"DefaultPassPhrase": "OntiKHsbiQj6FTce" |
|||
} |
|||
} |
@ -0,0 +1,2 @@ |
|||
{ |
|||
} |
File diff suppressed because it is too large
@ -0,0 +1,8 @@ |
|||
{ |
|||
"version": "1.0.0", |
|||
"name": "my-app-authserver", |
|||
"private": true, |
|||
"dependencies": { |
|||
"@abp/aspnetcore.mvc.ui.theme.leptonxlite": "~2.3.1" |
|||
} |
|||
} |
@ -0,0 +1,18 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
<configuration> |
|||
<location path="." inheritInChildApplications="false"> |
|||
<system.webServer> |
|||
<handlers> |
|||
<add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModuleV2" resourceType="Unspecified" /> |
|||
</handlers> |
|||
<aspNetCore processPath="dotnet" arguments=".\Dy_Exchange.AuthServer.dll" stdoutLogEnabled="false" stdoutLogFile=".\Logs\stdout" hostingModel="inprocess" /> |
|||
</system.webServer> |
|||
</location> |
|||
<system.webServer> |
|||
<httpProtocol> |
|||
<customHeaders> |
|||
<remove name="x-powered-by" /> |
|||
</customHeaders> |
|||
</httpProtocol> |
|||
</system.webServer> |
|||
</configuration> |
@ -0,0 +1,6 @@ |
|||
/* Your Global Styles */ |
|||
|
|||
:root .lpx-brand-logo { |
|||
--lpx-logo: url('/images/logo/leptonx/logo-light.png'); |
|||
--lpx-logo-icon: url('/images/logo/leptonx/logo-light-thumbnail.png'); |
|||
} |
After Width: | Height: | Size: 17 KiB |
After Width: | Height: | Size: 46 KiB |
After Width: | Height: | Size: 13 KiB |
After Width: | Height: | Size: 38 KiB |
@ -0,0 +1,51 @@ |
|||
using System.Threading; |
|||
using System.Threading.Tasks; |
|||
using Microsoft.Extensions.Configuration; |
|||
using Microsoft.Extensions.DependencyInjection; |
|||
using Microsoft.Extensions.Hosting; |
|||
using Dy_Exchange.Data; |
|||
using Serilog; |
|||
using Volo.Abp; |
|||
using Volo.Abp.Data; |
|||
|
|||
namespace Dy_Exchange.DbMigrator; |
|||
|
|||
public class DbMigratorHostedService : IHostedService |
|||
{ |
|||
private readonly IHostApplicationLifetime _hostApplicationLifetime; |
|||
private readonly IConfiguration _configuration; |
|||
|
|||
public DbMigratorHostedService(IHostApplicationLifetime hostApplicationLifetime, IConfiguration configuration) |
|||
{ |
|||
_hostApplicationLifetime = hostApplicationLifetime; |
|||
_configuration = configuration; |
|||
} |
|||
|
|||
public async Task StartAsync(CancellationToken cancellationToken) |
|||
{ |
|||
using (var application = await AbpApplicationFactory.CreateAsync<Dy_ExchangeDbMigratorModule>(options => |
|||
{ |
|||
options.Services.ReplaceConfiguration(_configuration); |
|||
options.UseAutofac(); |
|||
options.Services.AddLogging(c => c.AddSerilog()); |
|||
options.AddDataMigrationEnvironment(); |
|||
})) |
|||
{ |
|||
await application.InitializeAsync(); |
|||
|
|||
await application |
|||
.ServiceProvider |
|||
.GetRequiredService<Dy_ExchangeDbMigrationService>() |
|||
.MigrateAsync(); |
|||
|
|||
await application.ShutdownAsync(); |
|||
|
|||
_hostApplicationLifetime.StopApplication(); |
|||
} |
|||
} |
|||
|
|||
public Task StopAsync(CancellationToken cancellationToken) |
|||
{ |
|||
return Task.CompletedTask; |
|||
} |
|||
} |
@ -0,0 +1,46 @@ |
|||
<Project Sdk="Microsoft.NET.Sdk"> |
|||
|
|||
<Import Project="..\..\common.props" /> |
|||
|
|||
<PropertyGroup> |
|||
<OutputType>Exe</OutputType> |
|||
<TargetFramework>net7.0</TargetFramework> |
|||
<Nullable>enable</Nullable> |
|||
</PropertyGroup> |
|||
|
|||
<ItemGroup> |
|||
<None Remove="appsettings.json" /> |
|||
<Content Include="appsettings.json"> |
|||
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory> |
|||
<CopyToOutputDirectory>Always</CopyToOutputDirectory> |
|||
</Content> |
|||
<None Remove="appsettings.secrets.json" /> |
|||
<Content Include="appsettings.secrets.json"> |
|||
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory> |
|||
<CopyToOutputDirectory>Always</CopyToOutputDirectory> |
|||
</Content> |
|||
</ItemGroup> |
|||
|
|||
<ItemGroup> |
|||
<PackageReference Include="Serilog.Extensions.Logging" Version="3.1.0" /> |
|||
<PackageReference Include="Serilog.Sinks.Async" Version="1.5.0" /> |
|||
<PackageReference Include="Serilog.Sinks.File" Version="5.0.0" /> |
|||
<PackageReference Include="Serilog.Sinks.Console" Version="4.0.1" /> |
|||
<PackageReference Include="Microsoft.Extensions.Hosting" Version="7.0.0" /> |
|||
</ItemGroup> |
|||
|
|||
<ItemGroup> |
|||
<PackageReference Include="Volo.Abp.Autofac" Version="7.3.2" /> |
|||
<PackageReference Include="Volo.Abp.Caching.StackExchangeRedis" Version="7.3.2" /> |
|||
<ProjectReference Include="..\Dy_Exchange.Application.Contracts\Dy_Exchange.Application.Contracts.csproj" /> |
|||
<ProjectReference Include="..\Dy_Exchange.EntityFrameworkCore\Dy_Exchange.EntityFrameworkCore.csproj" /> |
|||
</ItemGroup> |
|||
|
|||
<ItemGroup> |
|||
<Compile Remove="Logs\**" /> |
|||
<Content Remove="Logs\**" /> |
|||
<EmbeddedResource Remove="Logs\**" /> |
|||
<None Remove="Logs\**" /> |
|||
</ItemGroup> |
|||
|
|||
</Project> |
@ -0,0 +1,21 @@ |
|||
using Dy_Exchange.EntityFrameworkCore; |
|||
using Volo.Abp.Autofac; |
|||
using Volo.Abp.Caching; |
|||
using Volo.Abp.Caching.StackExchangeRedis; |
|||
using Volo.Abp.Modularity; |
|||
|
|||
namespace Dy_Exchange.DbMigrator; |
|||
|
|||
[DependsOn( |
|||
typeof(AbpAutofacModule), |
|||
typeof(AbpCachingStackExchangeRedisModule), |
|||
typeof(Dy_ExchangeEntityFrameworkCoreModule), |
|||
typeof(Dy_ExchangeApplicationContractsModule) |
|||
)] |
|||
public class Dy_ExchangeDbMigratorModule : AbpModule |
|||
{ |
|||
public override void ConfigureServices(ServiceConfigurationContext context) |
|||
{ |
|||
Configure<AbpDistributedCacheOptions>(options => { options.KeyPrefix = "Dy_Exchange:"; }); |
|||
} |
|||
} |
@ -0,0 +1,41 @@ |
|||
using System.IO; |
|||
using System.Threading.Tasks; |
|||
using Microsoft.Extensions.Configuration; |
|||
using Microsoft.Extensions.DependencyInjection; |
|||
using Microsoft.Extensions.Hosting; |
|||
using Microsoft.Extensions.Logging; |
|||
using Serilog; |
|||
using Serilog.Events; |
|||
|
|||
namespace Dy_Exchange.DbMigrator; |
|||
|
|||
class Program |
|||
{ |
|||
static async Task Main(string[] args) |
|||
{ |
|||
Log.Logger = new LoggerConfiguration() |
|||
.MinimumLevel.Information() |
|||
.MinimumLevel.Override("Microsoft", LogEventLevel.Warning) |
|||
.MinimumLevel.Override("Volo.Abp", LogEventLevel.Warning) |
|||
#if DEBUG
|
|||
.MinimumLevel.Override("Dy_Exchange", LogEventLevel.Debug) |
|||
#else
|
|||
.MinimumLevel.Override("Dy_Exchange", LogEventLevel.Information) |
|||
#endif
|
|||
.Enrich.FromLogContext() |
|||
.WriteTo.Async(c => c.File("Logs/logs.txt")) |
|||
.WriteTo.Async(c => c.Console()) |
|||
.CreateLogger(); |
|||
|
|||
await CreateHostBuilder(args).RunConsoleAsync(); |
|||
} |
|||
|
|||
public static IHostBuilder CreateHostBuilder(string[] args) => |
|||
Host.CreateDefaultBuilder(args) |
|||
.AddAppSettingsSecretsJson() |
|||
.ConfigureLogging((context, logging) => logging.ClearProviders()) |
|||
.ConfigureServices((hostContext, services) => |
|||
{ |
|||
services.AddHostedService<DbMigratorHostedService>(); |
|||
}); |
|||
} |
@ -0,0 +1,30 @@ |
|||
{ |
|||
"ConnectionStrings": { |
|||
"Default": "Server=(LocalDb)\\MSSQLLocalDB;Database=Dy_Exchange;Trusted_Connection=True;TrustServerCertificate=True" |
|||
}, |
|||
"Redis": { |
|||
"Configuration": "127.0.0.1" |
|||
}, |
|||
"OpenIddict": { |
|||
"Applications": { |
|||
"Dy_Exchange_Web": { |
|||
"ClientId": "Dy_Exchange_Web", |
|||
"ClientSecret": "1q2w3e*", |
|||
"RootUrl": "https://localhost:44376" |
|||
}, |
|||
"Dy_Exchange_App": { |
|||
"ClientId": "Dy_Exchange_App", |
|||
"RootUrl": "http://localhost:4200" |
|||
}, |
|||
"Dy_Exchange_BlazorServerTiered": { |
|||
"ClientId": "Dy_Exchange_BlazorServerTiered", |
|||
"ClientSecret": "1q2w3e*", |
|||
"RootUrl": "https://localhost:44328" |
|||
}, |
|||
"Dy_Exchange_Swagger": { |
|||
"ClientId": "Dy_Exchange_Swagger", |
|||
"RootUrl": "https://localhost:44363" |
|||
} |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,2 @@ |
|||
{ |
|||
} |
@ -0,0 +1,32 @@ |
|||
<Project Sdk="Microsoft.NET.Sdk"> |
|||
|
|||
<Import Project="..\..\common.props" /> |
|||
|
|||
<PropertyGroup> |
|||
<TargetFrameworks>netstandard2.0;netstandard2.1;net7.0</TargetFrameworks> |
|||
<Nullable>enable</Nullable> |
|||
<RootNamespace>Dy_Exchange</RootNamespace> |
|||
<GenerateEmbeddedFilesManifest>true</GenerateEmbeddedFilesManifest> |
|||
</PropertyGroup> |
|||
|
|||
<ItemGroup> |
|||
<PackageReference Include="Volo.Abp.Identity.Domain.Shared" Version="7.3.2" /> |
|||
<PackageReference Include="Volo.Abp.BackgroundJobs.Domain.Shared" Version="7.3.2" /> |
|||
<PackageReference Include="Volo.Abp.AuditLogging.Domain.Shared" Version="7.3.2" /> |
|||
<PackageReference Include="Volo.Abp.TenantManagement.Domain.Shared" Version="7.3.2" /> |
|||
<PackageReference Include="Volo.Abp.FeatureManagement.Domain.Shared" Version="7.3.2" /> |
|||
<PackageReference Include="Volo.Abp.PermissionManagement.Domain.Shared" Version="7.3.2" /> |
|||
<PackageReference Include="Volo.Abp.SettingManagement.Domain.Shared" Version="7.3.2" /> |
|||
<PackageReference Include="Volo.Abp.OpenIddict.Domain.Shared" Version="7.3.2" /> |
|||
</ItemGroup> |
|||
|
|||
<ItemGroup> |
|||
<EmbeddedResource Include="Localization\Dy_Exchange\*.json" /> |
|||
<Content Remove="Localization\Dy_Exchange\*.json" /> |
|||
</ItemGroup> |
|||
|
|||
<ItemGroup> |
|||
<PackageReference Include="Microsoft.Extensions.FileProviders.Embedded" Version="7.0.0" /> |
|||
</ItemGroup> |
|||
|
|||
</Project> |
@ -0,0 +1,6 @@ |
|||
namespace Dy_Exchange; |
|||
|
|||
public static class Dy_ExchangeDomainErrorCodes |
|||
{ |
|||
/* You can add your business exception error codes here, as constants */ |
|||
} |
@ -0,0 +1,58 @@ |
|||
using Dy_Exchange.Localization; |
|||
using Volo.Abp.AuditLogging; |
|||
using Volo.Abp.BackgroundJobs; |
|||
using Volo.Abp.FeatureManagement; |
|||
using Volo.Abp.Identity; |
|||
using Volo.Abp.Localization; |
|||
using Volo.Abp.Localization.ExceptionHandling; |
|||
using Volo.Abp.Modularity; |
|||
using Volo.Abp.OpenIddict; |
|||
using Volo.Abp.PermissionManagement; |
|||
using Volo.Abp.SettingManagement; |
|||
using Volo.Abp.TenantManagement; |
|||
using Volo.Abp.Validation.Localization; |
|||
using Volo.Abp.VirtualFileSystem; |
|||
|
|||
namespace Dy_Exchange; |
|||
|
|||
[DependsOn( |
|||
typeof(AbpAuditLoggingDomainSharedModule), |
|||
typeof(AbpBackgroundJobsDomainSharedModule), |
|||
typeof(AbpFeatureManagementDomainSharedModule), |
|||
typeof(AbpIdentityDomainSharedModule), |
|||
typeof(AbpOpenIddictDomainSharedModule), |
|||
typeof(AbpPermissionManagementDomainSharedModule), |
|||
typeof(AbpSettingManagementDomainSharedModule), |
|||
typeof(AbpTenantManagementDomainSharedModule) |
|||
)] |
|||
public class Dy_ExchangeDomainSharedModule : AbpModule |
|||
{ |
|||
public override void PreConfigureServices(ServiceConfigurationContext context) |
|||
{ |
|||
Dy_ExchangeGlobalFeatureConfigurator.Configure(); |
|||
Dy_ExchangeModuleExtensionConfigurator.Configure(); |
|||
} |
|||
|
|||
public override void ConfigureServices(ServiceConfigurationContext context) |
|||
{ |
|||
Configure<AbpVirtualFileSystemOptions>(options => |
|||
{ |
|||
options.FileSets.AddEmbedded<Dy_ExchangeDomainSharedModule>(); |
|||
}); |
|||
|
|||
Configure<AbpLocalizationOptions>(options => |
|||
{ |
|||
options.Resources |
|||
.Add<Dy_ExchangeResource>("en") |
|||
.AddBaseTypes(typeof(AbpValidationResource)) |
|||
.AddVirtualJson("/Localization/Dy_Exchange"); |
|||
|
|||
options.DefaultResourceType = typeof(Dy_ExchangeResource); |
|||
}); |
|||
|
|||
Configure<AbpExceptionLocalizationOptions>(options => |
|||
{ |
|||
options.MapCodeNamespace("Dy_Exchange", typeof(Dy_ExchangeResource)); |
|||
}); |
|||
} |
|||
} |
@ -0,0 +1,22 @@ |
|||
using Volo.Abp.Threading; |
|||
|
|||
namespace Dy_Exchange; |
|||
|
|||
public static class Dy_ExchangeGlobalFeatureConfigurator |
|||
{ |
|||
private static readonly OneTimeRunner OneTimeRunner = new OneTimeRunner(); |
|||
|
|||
public static void Configure() |
|||
{ |
|||
OneTimeRunner.Run(() => |
|||
{ |
|||
/* You can configure (enable/disable) global features of the used modules here. |
|||
* |
|||
* YOU CAN SAFELY DELETE THIS CLASS AND REMOVE ITS USAGES IF YOU DON'T NEED TO IT! |
|||
* |
|||
* Please refer to the documentation to lear more about the Global Features System: |
|||
* https://docs.abp.io/en/abp/latest/Global-Features
|
|||
*/ |
|||
}); |
|||
} |
|||
} |
@ -0,0 +1,73 @@ |
|||
using System.ComponentModel.DataAnnotations; |
|||
using Volo.Abp.Identity; |
|||
using Volo.Abp.ObjectExtending; |
|||
using Volo.Abp.Threading; |
|||
|
|||
namespace Dy_Exchange; |
|||
|
|||
public static class Dy_ExchangeModuleExtensionConfigurator |
|||
{ |
|||
private static readonly OneTimeRunner OneTimeRunner = new OneTimeRunner(); |
|||
|
|||
public static void Configure() |
|||
{ |
|||
OneTimeRunner.Run(() => |
|||
{ |
|||
ConfigureExistingProperties(); |
|||
ConfigureExtraProperties(); |
|||
}); |
|||
} |
|||
|
|||
private static void ConfigureExistingProperties() |
|||
{ |
|||
/* You can change max lengths for properties of the |
|||
* entities defined in the modules used by your application. |
|||
* |
|||
* Example: Change user and role name max lengths |
|||
|
|||
IdentityUserConsts.MaxNameLength = 99; |
|||
IdentityRoleConsts.MaxNameLength = 99; |
|||
|
|||
* Notice: It is not suggested to change property lengths |
|||
* unless you really need it. Go with the standard values wherever possible. |
|||
* |
|||
* If you are using EF Core, you will need to run the add-migration command after your changes. |
|||
*/ |
|||
} |
|||
|
|||
private static void ConfigureExtraProperties() |
|||
{ |
|||
/* You can configure extra properties for the |
|||
* entities defined in the modules used by your application. |
|||
* |
|||
* This class can be used to define these extra properties |
|||
* with a high level, easy to use API. |
|||
* |
|||
* Example: Add a new property to the user entity of the identity module |
|||
|
|||
ObjectExtensionManager.Instance.Modules() |
|||
.ConfigureIdentity(identity => |
|||
{ |
|||
identity.ConfigureUser(user => |
|||
{ |
|||
user.AddOrUpdateProperty<string>( //property type: string
|
|||
"SocialSecurityNumber", //property name
|
|||
property => |
|||
{ |
|||
//validation rules
|
|||
property.Attributes.Add(new RequiredAttribute()); |
|||
property.Attributes.Add(new StringLengthAttribute(64) {MinimumLength = 4}); |
|||
|
|||
property.Configuration[IdentityModuleExtensionConsts.ConfigurationNames.AllowUserToEdit] = true; |
|||
|
|||
//...other configurations for this property
|
|||
} |
|||
); |
|||
}); |
|||
}); |
|||
|
|||
* See the documentation for more: |
|||
* https://docs.abp.io/en/abp/latest/Module-Entity-Extensions
|
|||
*/ |
|||
} |
|||
} |
@ -0,0 +1,13 @@ |
|||
using System.ComponentModel.DataAnnotations; |
|||
|
|||
namespace Dy_Exchange.Enums; |
|||
|
|||
/// <summary>
|
|||
/// 用户自定义导出设置
|
|||
/// </summary>
|
|||
public enum Enum_ExportCustomUserSetting |
|||
{ |
|||
[Display(Name = "未定义")] None = 0, |
|||
[Display(Name = "导出")] Yes = 1, |
|||
[Display(Name = "不导出")] No = 2 |
|||
} |
@ -0,0 +1,30 @@ |
|||
{ |
|||
"culture": "ar", |
|||
"texts": { |
|||
"Menu:Home": "الصفحة الرئيسية", |
|||
"LongWelcomeMessage": "مرحبا بكم في التطبيق. هذا مشروع بدء تشغيل يعتمد على إطار عمل ABP. لمزيد من المعلومات ، يرجى زيارة abp.io.", |
|||
"Permission:DataExchangeInterfaceConfig": "DataExchangeInterfaceConfig", |
|||
"Permission:Create": "Create", |
|||
"Permission:Update": "Update", |
|||
"Permission:Delete": "Delete", |
|||
"Menu:DataExchangeInterfaceConfig": "MenuDataExchangeInterfaceConfig", |
|||
"DataExchangeInterfaceConfig": "DataExchangeInterfaceConfig", |
|||
"DataExchangeInterfaceConfigId": "DataExchangeInterfaceConfigId", |
|||
"DataExchangeInterfaceConfigName": "DataExchangeInterfaceConfigName", |
|||
"DataExchangeInterfaceConfigCode": "DataExchangeInterfaceConfigCode", |
|||
"DataExchangeInterfaceConfigActive": "DataExchangeInterfaceConfigActive", |
|||
"DataExchangeInterfaceConfigLevel": "DataExchangeInterfaceConfigLevel", |
|||
"DataExchangeInterfaceConfigExtraProperties": "DataExchangeInterfaceConfigExtraProperties", |
|||
"DataExchangeInterfaceConfigConcurrencyStamp": "DataExchangeInterfaceConfigConcurrencyStamp", |
|||
"DataExchangeInterfaceConfigCreationTime": "DataExchangeInterfaceConfigCreationTime", |
|||
"DataExchangeInterfaceConfigCreatorId": "DataExchangeInterfaceConfigCreatorId", |
|||
"DataExchangeInterfaceConfigLastModificationTime": "DataExchangeInterfaceConfigLastModificationTime", |
|||
"DataExchangeInterfaceConfigLastModifierId": "DataExchangeInterfaceConfigLastModifierId", |
|||
"DataExchangeInterfaceConfigRemark": "DataExchangeInterfaceConfigRemark", |
|||
"CreateDataExchangeInterfaceConfig": "CreateDataExchangeInterfaceConfig", |
|||
"EditDataExchangeInterfaceConfig": "EditDataExchangeInterfaceConfig", |
|||
"DataExchangeInterfaceConfigDeletionConfirmationMessage": "Are you sure to delete the dataExchangeInterfaceConfig {0}?", |
|||
"SuccessfullyDeleted": "Successfully deleted", |
|||
"TableFilter": "TableFilter" |
|||
} |
|||
} |
@ -0,0 +1,8 @@ |
|||
{ |
|||
"culture": "cs", |
|||
"texts": { |
|||
"Menu:Home": "Úvod", |
|||
"Welcome": "Vítejte", |
|||
"LongWelcomeMessage": "Vítejte v aplikaci. Toto je startovací projekt založený na ABP frameworku. Pro více informací, navštivte abp.io." |
|||
} |
|||
} |
@ -0,0 +1,8 @@ |
|||
{ |
|||
"culture": "de", |
|||
"texts": { |
|||
"Menu:Home": "Home", |
|||
"Welcome": "Willkommen", |
|||
"LongWelcomeMessage": "Willkommen bei der Anwendung. Dies ist ein Startup-Projekt, das auf dem ABP-Framework basiert. Weitere Informationen finden Sie unter abp.io." |
|||
} |
|||
} |
@ -0,0 +1,8 @@ |
|||
{ |
|||
"culture": "en-GB", |
|||
"texts": { |
|||
"Menu:Home": "Home", |
|||
"Welcome": "Welcome", |
|||
"LongWelcomeMessage": "Welcome to the application. This is a startup project based on the ABP framework. For more information, visit abp.io." |
|||
} |
|||
} |
@ -0,0 +1,8 @@ |
|||
{ |
|||
"culture": "en", |
|||
"texts": { |
|||
"Menu:Home": "Home", |
|||
"Welcome": "Welcome", |
|||
"LongWelcomeMessage": "Welcome to the application. This is a startup project based on the ABP framework. For more information, visit abp.io." |
|||
} |
|||
} |
@ -0,0 +1,8 @@ |
|||
{ |
|||
"culture": "es", |
|||
"texts": { |
|||
"Menu:Home": "Inicio", |
|||
"Welcome": "Bienvenido", |
|||
"LongWelcomeMessage": "Bienvenido a la aplicación, este es un proyecto base basado en el framework ABP. Para más información, visita abp.io." |
|||
} |
|||
} |
@ -0,0 +1,8 @@ |
|||
{ |
|||
"culture": "fi", |
|||
"texts": { |
|||
"Menu:Home": "Koti", |
|||
"Welcome": "Tervetuloa", |
|||
"LongWelcomeMessage": "Tervetuloa sovellukseen. Tämä on ABP-kehykseen perustuva käynnistysprojekti. Lisätietoja on osoitteessa abp.io." |
|||
} |
|||
} |
@ -0,0 +1,8 @@ |
|||
{ |
|||
"culture": "fr", |
|||
"texts": { |
|||
"Menu:Home": "Accueil", |
|||
"Welcome": "Bienvenue", |
|||
"LongWelcomeMessage": "Bienvenue dans l'application. Il s'agit d'un projet de démarrage basé sur le framework ABP. Pour plus d'informations, visitez abp.io." |
|||
} |
|||
} |
@ -0,0 +1,8 @@ |
|||
{ |
|||
"culture": "hi", |
|||
"texts": { |
|||
"Menu:Home": "घर", |
|||
"Welcome": "स्वागत हे", |
|||
"LongWelcomeMessage": "आवेदन करने के लिए आपका स्वागत है। यह एबीपी ढांचे पर आधारित एक स्टार्टअप परियोजना है। अधिक जानकारी के लिए, abp.io पर जाएं।" |
|||
} |
|||
} |
@ -0,0 +1,8 @@ |
|||
{ |
|||
"culture": "hr", |
|||
"texts": { |
|||
"Menu:Home": "Početna", |
|||
"Welcome": "Dobrodošli", |
|||
"LongWelcomeMessage": "Dobrodošli u aplikaciju. Ovo je startup projekt temeljen na ABP framework-u. Za više informacija posjetite abp.io." |
|||
} |
|||
} |
@ -0,0 +1,8 @@ |
|||
{ |
|||
"culture": "hu", |
|||
"texts": { |
|||
"Menu:Home": "Kezdőlap", |
|||
"Welcome": "Üdvözlöm", |
|||
"LongWelcomeMessage": "Üdvözöljük az alkalmazásban. Ez egy ABP keretrendszeren alapuló startup projekt. További információkért látogasson el az abp.io oldalra." |
|||
} |
|||
} |
@ -0,0 +1,8 @@ |
|||
{ |
|||
"culture": "is", |
|||
"texts": { |
|||
"Menu:Home": "Heim", |
|||
"Welcome": "Velkomin", |
|||
"LongWelcomeMessage": "Verið velkomin í forritið. Þetta er startup verkefni sem byggir á ABP. Nánari upplýsingar er að finna á abp.io." |
|||
} |
|||
} |
@ -0,0 +1,8 @@ |
|||
{ |
|||
"culture": "it", |
|||
"texts": { |
|||
"Menu:Home": "Home", |
|||
"Welcome": "Benvenuto", |
|||
"LongWelcomeMessage": "Benvenuto nell'applicazione. Questo è un progetto di avvio basato sul framework ABP. Per ulteriori informazioni, visita abp.io." |
|||
} |
|||
} |
@ -0,0 +1,8 @@ |
|||
{ |
|||
"culture": "nl", |
|||
"texts": { |
|||
"Menu:Home": "Home", |
|||
"Welcome": "Welkom", |
|||
"LongWelcomeMessage": "Welkom bij de applicatie. Dit is een startup-project gebaseerd op het ABP-framework. Bezoek abp.io voor meer informatie." |
|||
} |
|||
} |
@ -0,0 +1,8 @@ |
|||
{ |
|||
"culture": "pl-PL", |
|||
"texts": { |
|||
"Menu:Home": "Home", |
|||
"Welcome": "Witaj", |
|||
"LongWelcomeMessage": "Witaj w aplikacji. To jest inicjalny projekt bazujący na ABP framework. Po więcej informacji odwiedź stronę abp.io." |
|||
} |
|||
} |
@ -0,0 +1,8 @@ |
|||
{ |
|||
"culture": "pt-BR", |
|||
"texts": { |
|||
"Menu:Home": "Principal", |
|||
"Welcome": "Seja bem-vindo!", |
|||
"LongWelcomeMessage": "Bem-vindo a esta aplicação. Este é um projeto inicial baseado no ABP framework. Para mais informações, visite abp.io." |
|||
} |
|||
} |
@ -0,0 +1,8 @@ |
|||
{ |
|||
"culture": "ro-RO", |
|||
"texts": { |
|||
"Menu:Home": "Acasă", |
|||
"Welcome": "Bun venit", |
|||
"LongWelcomeMessage": "Bun venit la aplicaţie. Acesta este un proiect de pornire bazat pe framework-ul ABP. Pentru mai multe informaţii, vizitaţi, visit abp.io." |
|||
} |
|||
} |
@ -0,0 +1,8 @@ |
|||
{ |
|||
"culture": "ru", |
|||
"texts": { |
|||
"Menu:Home": "Главная", |
|||
"Welcome": "Добро пожаловать", |
|||
"LongWelcomeMessage": "Добро пожаловать в приложение. Этот запущенный проект основан на фреймворке ABP. Для получения дополнительной информации посетите сайт abp.io." |
|||
} |
|||
} |
@ -0,0 +1,8 @@ |
|||
{ |
|||
"culture": "sk", |
|||
"texts": { |
|||
"Menu:Home": "Domov", |
|||
"Welcome": "Vitajte", |
|||
"LongWelcomeMessage": "Vitajte v aplikácii. Toto je štartovací projekt založený na ABP frameworku. Viac informácií nájdete na stránke abp.io." |
|||
} |
|||
} |
@ -0,0 +1,8 @@ |
|||
{ |
|||
"culture": "sl", |
|||
"texts": { |
|||
"Menu:Home": "Domov", |
|||
"Welcome": "Dobrodošli", |
|||
"LongWelcomeMessage": "Dobrodošli v aplikaciji. To je začetni projekt na osnovi okolja ABP. Za več informacij obiščite abp.io." |
|||
} |
|||
} |
@ -0,0 +1,8 @@ |
|||
{ |
|||
"culture": "tr", |
|||
"texts": { |
|||
"Menu:Home": "Ana sayfa", |
|||
"Welcome": "Hoşgeldiniz", |
|||
"LongWelcomeMessage": "Uygulamaya hoşgeldiniz. Bu, ABP framework'ü üzerine bina edilmiş bir başlangıç projesidir. Daha fazla bilgi için abp.io adresini ziyaret edebilirsiniz." |
|||
} |
|||
} |
@ -0,0 +1,8 @@ |
|||
{ |
|||
"culture": "vi", |
|||
"texts": { |
|||
"Menu:Home": "Trang chủ", |
|||
"Welcome": "Chào mừng bạn", |
|||
"LongWelcomeMessage": "Chào mừng bạn đến ứng dụng. Đây là một dự án khởi nghiệp dựa trên khung ABP. Để biết thêm thông tin, hãy truy cập abp.io." |
|||
} |
|||
} |
@ -0,0 +1,8 @@ |
|||
{ |
|||
"culture": "zh-Hans", |
|||
"texts": { |
|||
"Menu:Home": "首页", |
|||
"Welcome": "欢迎", |
|||
"LongWelcomeMessage": "欢迎来到该应用程序. 这是一个基于ABP框架的启动项目. 有关更多信息, 请访问 abp.io." |
|||
} |
|||
} |
@ -0,0 +1,8 @@ |
|||
{ |
|||
"culture": "zh-Hant", |
|||
"texts": { |
|||
"Menu:Home": "首頁", |
|||
"Welcome": "歡迎", |
|||
"LongWelcomeMessage": "歡迎來到此應用程式. 這是一個基於ABP框架的起始專案. 有關更多訊息, 請瀏覽 abp.io." |
|||
} |
|||
} |
@ -0,0 +1,9 @@ |
|||
using Volo.Abp.Localization; |
|||
|
|||
namespace Dy_Exchange.Localization; |
|||
|
|||
[LocalizationResourceName("Dy_Exchange")] |
|||
public class Dy_ExchangeResource |
|||
{ |
|||
|
|||
} |
Some files were not shown because too many files changed in this diff
Loading…
Reference in new issue