356 changed files with 45330 additions and 136 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 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>
|
||||
|
|
||||
|
|
||||
|
/// <summary>
|
||||
|
///
|
||||
|
/// </summary>
|
||||
|
|
||||
|
|
||||
|
|
||||
|
/// <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