This commit is contained in:
wyw 2026-04-07 13:47:52 +08:00
commit 57557d81a4
203 changed files with 38837 additions and 0 deletions

25
.dockerignore Normal file
View File

@ -0,0 +1,25 @@
**/.classpath
**/.dockerignore
**/.env
**/.git
**/.gitignore
**/.project
**/.settings
**/.toolstarget
**/.vs
**/.vscode
**/*.*proj.user
**/*.dbmdl
**/*.jfm
**/azds.yaml
**/bin
**/charts
**/docker-compose*
**/Dockerfile*
**/node_modules
**/npm-debug.log
**/obj
**/secrets.dev.yaml
**/values.dev.yaml
LICENSE
README.md

398
.gitignore vendored Normal file
View File

@ -0,0 +1,398 @@
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
##
## Get latest from https://github.com/github/gitignore/blob/main/VisualStudio.gitignore
# User-specific files
*.rsuser
*.suo
*.user
*.userosscache
*.sln.docstates
# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs
# Mono auto generated files
mono_crash.*
# Build results
[Dd]ebug/
[Dd]ebugPublic/
[Rr]elease/
[Rr]eleases/
x64/
x86/
[Ww][Ii][Nn]32/
[Aa][Rr][Mm]/
[Aa][Rr][Mm]64/
bld/
[Bb]in/
[Oo]bj/
[Ll]og/
[Ll]ogs/
# Visual Studio 2015/2017 cache/options directory
.vs/
# Uncomment if you have tasks that create the project's static files in wwwroot
#wwwroot/
# Visual Studio 2017 auto generated files
Generated\ Files/
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
# NUnit
*.VisualState.xml
TestResult.xml
nunit-*.xml
# Build Results of an ATL Project
[Dd]ebugPS/
[Rr]eleasePS/
dlldata.c
# Benchmark Results
BenchmarkDotNet.Artifacts/
# .NET Core
project.lock.json
project.fragment.lock.json
artifacts/
# ASP.NET Scaffolding
ScaffoldingReadMe.txt
# StyleCop
StyleCopReport.xml
# Files built by Visual Studio
*_i.c
*_p.c
*_h.h
*.ilk
*.meta
*.obj
*.iobj
*.pch
*.pdb
*.ipdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*_wpftmp.csproj
*.log
*.tlog
*.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
# Visual Studio Trace Files
*.e2e
# TFS 2012 Local Workspace
$tf/
# Guidance Automation Toolkit
*.gpState
# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
*.DotSettings.user
# TeamCity is a build add-in
_TeamCity*
# DotCover is a Code Coverage Tool
*.dotCover
# AxoCover is a Code Coverage Tool
.axoCover/*
!.axoCover/settings.json
# Coverlet is a free, cross platform Code Coverage Tool
coverage*.json
coverage*.xml
coverage*.info
# Visual Studio code coverage results
*.coverage
*.coveragexml
# 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
# Note: 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
# NuGet Symbol Packages
*.snupkg
# The packages folder can be ignored because of Package Restore
**/[Pp]ackages/*
# except build/, which is used as an MSBuild target.
!**/[Pp]ackages/build/
# Uncomment if necessary however generally it will be regenerated when needed
#!**/[Pp]ackages/repositories.config
# NuGet v3's project.json files produces more ignorable 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
*.appx
*.appxbundle
*.appxupload
# 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
*.jfm
*.pfx
*.publishsettings
orleans.codegen.cs
# Including strong name files can present a security risk
# (https://github.com/github/gitignore/pull/2483#issue-259490424)
#*.snk
# 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
ServiceFabricBackup/
*.rptproj.bak
# SQL Server files
*.mdf
*.ldf
*.ndf
# Business Intelligence projects
*.rdl.data
*.bim.layout
*.bim_*.settings
*.rptproj.rsuser
*- [Bb]ackup.rdl
*- [Bb]ackup ([0-9]).rdl
*- [Bb]ackup ([0-9][0-9]).rdl
# Microsoft Fakes
FakesAssemblies/
# GhostDoc plugin setting file
*.GhostDoc.xml
# Node.js Tools for Visual Studio
.ntvs_analysis.dat
node_modules/
# Visual Studio 6 build log
*.plg
# Visual Studio 6 workspace options file
*.opt
# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
*.vbw
# Visual Studio 6 auto-generated project file (contains which files were open etc.)
*.vbp
# Visual Studio 6 workspace and project file (working project files containing files to include in project)
*.dsw
*.dsp
# Visual Studio 6 technical files
*.ncb
*.aps
# 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/
# CodeRush personal settings
.cr/personal
# Python Tools for Visual Studio (PTVS)
__pycache__/
*.pyc
# Cake - Uncomment if you are using it
# tools/**
# !tools/packages.config
# Tabs Studio
*.tss
# Telerik's JustMock configuration file
*.jmconfig
# BizTalk build output
*.btp.cs
*.btm.cs
*.odx.cs
*.xsd.cs
# OpenCover UI analysis results
OpenCover/
# Azure Stream Analytics local run output
ASALocalRun/
# MSBuild Binary and Structured Log
*.binlog
# NVidia Nsight GPU debugger configuration file
*.nvuser
# MFractors (Xamarin productivity tool) working folder
.mfractor/
# Local History for Visual Studio
.localhistory/
# Visual Studio History (VSHistory) files
.vshistory/
# BeatPulse healthcheck temp database
healthchecksdb
# Backup folder for Package Reference Convert tool in Visual Studio 2017
MigrationBackup/
# Ionide (cross platform F# VS Code tools) working folder
.ionide/
# Fody - auto-generated XML schema
FodyWeavers.xsd
# VS Code files for those working on multiple tools
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json
*.code-workspace
# Local History for Visual Studio Code
.history/
# Windows Installer files from build outputs
*.cab
*.msi
*.msix
*.msm
*.msp
# JetBrains Rider
*.sln.iml

36
APT.API/APT.API.csproj Normal file
View File

@ -0,0 +1,36 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<AspNetCoreHostingModel>InProcess</AspNetCoreHostingModel>
<DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
</PropertyGroup>
<ItemGroup>
<Compile Remove="LogAttribute.cs" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Autofac" Version="5.1.2" />
<PackageReference Include="Autofac.Extensions.DependencyInjection" Version="6.0.0" />
<PackageReference Include="Autofac.Extras.DynamicProxy" Version="5.0.0" />
<PackageReference Include="Castle.Core" Version="4.4.1" />
<PackageReference Include="Microsoft.AspNetCore.App" />
<PackageReference Include="Microsoft.AspNetCore.Razor.Design" Version="2.2.0" PrivateAssets="All" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="5.0.2">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="5.0.2" />
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.10.9" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\APT.DAL.Data\APT.DAL.Data.csproj" />
<ProjectReference Include="..\APT.Domain\APT.Domain.csproj" />
<ProjectReference Include="..\APT.Infrastructure.Api\APT.Infrastructure.Api.csproj" />
<ProjectReference Include="..\APT.Infrastructure.Core\APT.Infrastructure.Core.csproj" />
<ProjectReference Include="..\APT.Infrastructure.EF\APT.Infrastructure.EF.csproj" />
</ItemGroup>
</Project>

61
APT.API/APT.API.sln Normal file
View File

@ -0,0 +1,61 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.29806.167
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "APT.API", "APT.API.csproj", "{34B722F6-F94F-4013-A4B1-90883AFD9827}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "APT.DAL.Data", "..\APT.DAL.Data\APT.DAL.Data.csproj", "{416E9E2B-95BC-49FE-8E71-B8D362C5E4A1}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "APT.Domain", "..\APT.Domain\APT.Domain.csproj", "{930AFFDA-4BFE-423F-9F27-62919F09E7F0}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "APT.Infrastructure.Api", "..\APT.Infrastructure.Api\APT.Infrastructure.Api.csproj", "{F6A879CE-7319-479C-BA24-BF9DCB71A9A5}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "APT.Infrastructure.Core", "..\APT.Infrastructure.Core\APT.Infrastructure.Core.csproj", "{E93B3210-F2BC-49F5-91A6-5804839FE1DA}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "APT.Infrastructure.EF", "..\APT.Infrastructure.EF\APT.Infrastructure.EF.csproj", "{AAABC7E2-A68E-4F92-9D96-9E3FD874421B}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "APT.Migrations", "..\APT.Migrations\APT.Migrations.csproj", "{68FD728E-A9FE-4E1F-A4BE-EC0642B9C15B}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{34B722F6-F94F-4013-A4B1-90883AFD9827}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{34B722F6-F94F-4013-A4B1-90883AFD9827}.Debug|Any CPU.Build.0 = Debug|Any CPU
{34B722F6-F94F-4013-A4B1-90883AFD9827}.Release|Any CPU.ActiveCfg = Release|Any CPU
{34B722F6-F94F-4013-A4B1-90883AFD9827}.Release|Any CPU.Build.0 = Release|Any CPU
{416E9E2B-95BC-49FE-8E71-B8D362C5E4A1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{416E9E2B-95BC-49FE-8E71-B8D362C5E4A1}.Debug|Any CPU.Build.0 = Debug|Any CPU
{416E9E2B-95BC-49FE-8E71-B8D362C5E4A1}.Release|Any CPU.ActiveCfg = Release|Any CPU
{416E9E2B-95BC-49FE-8E71-B8D362C5E4A1}.Release|Any CPU.Build.0 = Release|Any CPU
{930AFFDA-4BFE-423F-9F27-62919F09E7F0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{930AFFDA-4BFE-423F-9F27-62919F09E7F0}.Debug|Any CPU.Build.0 = Debug|Any CPU
{930AFFDA-4BFE-423F-9F27-62919F09E7F0}.Release|Any CPU.ActiveCfg = Release|Any CPU
{930AFFDA-4BFE-423F-9F27-62919F09E7F0}.Release|Any CPU.Build.0 = Release|Any CPU
{F6A879CE-7319-479C-BA24-BF9DCB71A9A5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F6A879CE-7319-479C-BA24-BF9DCB71A9A5}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F6A879CE-7319-479C-BA24-BF9DCB71A9A5}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F6A879CE-7319-479C-BA24-BF9DCB71A9A5}.Release|Any CPU.Build.0 = Release|Any CPU
{E93B3210-F2BC-49F5-91A6-5804839FE1DA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E93B3210-F2BC-49F5-91A6-5804839FE1DA}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E93B3210-F2BC-49F5-91A6-5804839FE1DA}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E93B3210-F2BC-49F5-91A6-5804839FE1DA}.Release|Any CPU.Build.0 = Release|Any CPU
{AAABC7E2-A68E-4F92-9D96-9E3FD874421B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{AAABC7E2-A68E-4F92-9D96-9E3FD874421B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{AAABC7E2-A68E-4F92-9D96-9E3FD874421B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{AAABC7E2-A68E-4F92-9D96-9E3FD874421B}.Release|Any CPU.Build.0 = Release|Any CPU
{68FD728E-A9FE-4E1F-A4BE-EC0642B9C15B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{68FD728E-A9FE-4E1F-A4BE-EC0642B9C15B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{68FD728E-A9FE-4E1F-A4BE-EC0642B9C15B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{68FD728E-A9FE-4E1F-A4BE-EC0642B9C15B}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {5040CE81-F008-43D7-AEFC-DF1FE1F5CEB6}
EndGlobalSection
EndGlobal

View File

@ -0,0 +1,54 @@
using APT.Infrastructure.Core;
using Microsoft.AspNetCore.Mvc.Filters;
using System;
using System.Diagnostics;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
namespace APT.Infrastructure.Api.WebFilters
{
//public class WebApiTrackerAttribute : System.Web.Http.Filters.ActionFilterAttribute
//{
// public bool AllowMultiple => true;
// //public Task<HttpResponseMessage> ExecuteActionFilterAsync(HttpActionContext actionContext, CancellationToken cancellationToken, Func<Task<HttpResponseMessage>> continuation)
// //{
// // throw new NotImplementedException();
// //}
// //public Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
// //{
// // throw new NotImplementedException();
// // var s = 1;
// //}
// public override void OnActionExecuting(HttpActionContext actionContext)
// {
// LoggerManager.GetLogger().Info("11111111111");
// base.OnActionExecuting(actionContext);
// }
// public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
// {
// LoggerManager.GetLogger().Info("2222222222222");
// base.OnActionExecuted(actionExecutedContext);
// }
// public override Task OnActionExecutingAsync(HttpActionContext actionContext, CancellationToken cancellationToken)
// {
// LoggerManager.GetLogger().Info("2222222222222");
// return base.OnActionExecutingAsync(actionContext, cancellationToken);
// }
// public override Task OnActionExecutedAsync(HttpActionExecutedContext actionExecutedContext, CancellationToken cancellationToken)
// {
// LoggerManager.GetLogger().Info("11111111111");
// return base.OnActionExecutedAsync(actionExecutedContext, cancellationToken);
// }
//}
}

View File

@ -0,0 +1,44 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Autofac;
using APT.Infrastructure.Core;
using APT.Infrastructure.EF;
using Microsoft.Extensions.Logging;
using APT.Infrastructure.Core.Refctor;
using System.Reflection;
using Autofac.Extras.DynamicProxy;
using APT.Infrastructure.Api;
namespace APT.API
{
public static class DIConfig
{
public static void RegisterComponents(this ContainerBuilder builder)
{
ReflectHelper.GetClassMethodAttr(typeof(EfDbContext));
builder.RegisterType<EFDbContextLoggerProvider>().As<ILoggerProvider>().SingleInstance();
builder.RegisterType<LoggerFactory>().As<ILoggerFactory>().SingleInstance();
builder.RegisterType<EfDbContext>().PropertiesAutowired();
//builder.RegisterType<MigrationContext>().PropertiesAutowired();
builder.RegisterType<Repository>().As<IRepository>().InstancePerLifetimeScope();
builder.RegisterType<CommonService>().As<ICommonService>().InstancePerLifetimeScope();
builder.RegisterType(typeof(DomainServiceBase)).As(typeof(IDomainService)).InstancePerLifetimeScope();
builder.RegisterType<EfDbContext>().As<IUnitOfWork>().InstancePerLifetimeScope()
.PropertiesAutowired();
//builder.RegisterType<MigrationContext>().As<IUnitOfWork>().InstancePerLifetimeScope()
// .PropertiesAutowired();
builder.RegisterType<LogInterceptor>();
Assembly service = Assembly.Load("APT.API");
//Assembly iservice = Assembly.Load("APT.API.IService");
builder.RegisterAssemblyTypes(service).AsImplementedInterfaces()
.InstancePerLifetimeScope()
.EnableInterfaceInterceptors().InterceptedBy(typeof(LogInterceptor));
}
}
}

View File

@ -0,0 +1,66 @@
using System;
using System.Collections.Generic;
using System.Net.Http;
using APT.Infrastructure.Api;
using APT.Infrastructure.EF;
using Microsoft.Extensions.Configuration;
namespace APT.API
{
public class CombindedConnectionGenerator : IConnectionGenerator
{
static Lazy<Random> random = new Lazy<Random>();
private readonly IConfiguration configuration;
public string TenantKey => "";
public CombindedConnectionGenerator(IConfiguration configuration)
{
this.configuration = configuration;
}
public string GetConnection(TenantOption option, TenantInfo tenantInfo)
{
return tenantInfo.Conn;
//var webapiUrl = "http://localhost:5001/api/DbConfigs";
//var httpResponseMsg = new HttpResponseMessage();
//using (var httpClient = new HttpClient())
//{
// httpResponseMsg = httpClient.GetAsync(webapiUrl).Result;
// var retrnUrl = httpResponseMsg.Content.ReadAsStringAsync().Result;
// dynamic urls = Newtonsoft.Json.JsonConvert.DeserializeObject<dynamic>(retrnUrl);
// if (urls != null)
// {
// List<dynamic> connList = new List<dynamic>();
// foreach (dynamic url in urls)
// {
// if (url.name == span)
// {
// connList.Add(url.conn);
// }
// }
// if (connList.Count > 0)
// {
// var mod = (random.Value.Next(100) % connList.Count);
// return connList[mod];
// }
// }
//}
//if (span.Length > 4 && int.TryParse(span[5].ToString(), out var number))
//{
//var mod = (random.Value.Next(1000) % 3)+1;
// return configuration.GetConnectionString($"{option.ConnectionPrefix}{mod}");
//}
throw new NotSupportedException("ÅäÖÃÐÅÏ¢²»´æÔÚ");
}//
public bool MatchTenantKey(string tenantKey)
{
return true;
}
}
}

View File

@ -0,0 +1,15 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using APT.Infrastructure.Core;
using Microsoft.AspNetCore.Mvc;
namespace APT.API
{
[Log]
public class AptController : ControllerBase
{
}
}

View File

@ -0,0 +1,311 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Threading.Tasks;
using APT.Domain;
using APT.Infrastructure.Api.WebFilters;
using APT.Infrastructure.Core;
using APT.Infrastructure.EF;
using APT.Infrastructure.EF.Infrastructure;
using Microsoft.AspNetCore.Mvc;
using APT.Infrastructure.Api;
namespace APT.API
{
public class ValuesController : CommonApiController
{
private readonly EfDbContext efDbContext;
public ValuesController(EfDbContext storeDbContext)
{
this.efDbContext = storeDbContext;
//this.storeDbContext.Database.EnsureCreated();
//this.storeDbContext.Database.Migrate();
}
[HttpGet, Route("api/values")]
public JsonActionResult<IEnumerable<APT_Test_User>> Get()
{
var commonService = ServiceLocator.Instance.GetService<ICommonService>();
////////return commonService.UnitWork();
//var param = new CodeRuleParam()
//{
// CodeType = 1014,
// OrgId = new Guid("b043b28b-bbc3-c452-6052-4fba1457abfa"),
// Count = 1,
//};
////var xx = commonService.GetRuleCodes(param);
var codeRule = new T_PF_CODE_RULE_SERIAL()
{
ID = Guid.NewGuid(),
CODE_TYPE = 3500,
ORG_ID = new Guid("b043b28b-bbc3-c452-6052-4fba1457abfa")
};
this.efDbContext.AddEntity(codeRule);
this.efDbContext.SaveChanges();
var db = this.efDbContext.GetEntity<T_PF_CODE_RULE_SERIAL>(t => t.CODE_TYPE == 3500, null);
//EfDbContext dbContext = new EfDbContext("User ID=postgres;Password=123456;Host=localhost;Port=5432;Database=Infracture_Test;CommandTimeout=1024;");
//var dbs = dbContext.GetEntity<T_PF_CODE_RULE_SERIAL>(t => t.CODE_TYPE == 3500, null);
////Expression<Func<T_PF_CODE_RULE_SERIAL, bool>> expression = t => t.ORG_ID == param.OrgId
//// && t.CODE_TYPE == 1038;
////expression = expression.And(t => t.DATE_VALUE == "20191016");
////var pageFilter = new BasePageFilter(1, 1);
////pageFilter.Sort = "NUM";
////pageFilter.Order = DbOrder.DESC;
////var maxDbCodeRuleSerial = this.GetOrderPageEntities<T_PF_CODE_RULE_SERIAL>(expression, pageFilter);
//ServiceLocator serviceLocator = ServiceLocator.Instance;
//var _connectionResolver = serviceLocator.GetService<IConnectionResolver>();
//var x1 = commonService.GetEntity<T_PF_CODE_RULE_SERIAL>(t => t.CODE_TYPE == 3500);
//x1.MODIFY_TIME = DateTime.Now;
//this.UpdateEntity(x1);
////x1.STATUS = 2;
////var x2 = commonService.GetEntity<T_PF_CODE_RULE_SERIAL>(t => t.CODE_TYPE == 3500 &&
//// t.ORG_ID == param.OrgId && t.STATUS == 0 && t.ID != x1.ID);
////x2.STATUS = 2;
////this.UpdateEntity(x2);
////Dictionary<string, object> bodyParams = new Dictionary<string, object>();
////bodyParams.Add("sn", "L1002497A000052");
////bodyParams.Add("stationId", "FinallyFunctionTest");
////Dictionary<string, string> headParams = new Dictionary<string, string>();
////headParams.Add("Access-Token", "D2B471BAA84582052F9AD2EE49FFB3EE");
////var ret = WebUtils.ExecuteByResolving<ExtTestResultModel>("http://172.20.8.29:9001/api/TestData/GetTestData",
//// bodyParams, string.Empty, SendType.Get, headParams);
//var sttr = WitEntities(null, new KeywordFilter());
//return sttr;
var entity = new TestNoneBaseModel
{
ID = "Test",
Name = "Test"
};
var entities = new List<TestNoneBaseModel>
{
new TestNoneBaseModel
{
ID = "Test1",
Name = "Test1"
},
new TestNoneBaseModel
{
ID = "Test2",
Name = "Test2"
}
};
//var str = commonService.AddAndGetEntity_noneBase<TestNoneBaseModel>(entity);
//commonService.AddEntities_noneBase(entities);
var str1 = commonService.GetEntity_noneBase<TestNoneBaseModel>(o => o.ID == "Test");
var strall = commonService.GetEntities_noneBase<TestNoneBaseModel>(o => o.ID.StartsWith("Test"));
return null;
}
[HttpGet, Route("api/asynctest")]
public async Task<JsonActionResult<bool>> asynctest(string id)
{
return await SafeExecuteAsync<bool>(async () =>
{
await GetAsync();
return true;
});
}
private async Task GetAsync()
{
await this.GetPageEntitiesSync<T_PF_CODE_RULE_SERIAL>(t => t.CODE_TYPE == 3500, null);
return;
}
[HttpGet, Route("api/test")]
public ActionResult<bool> test()
{
var commonService = ServiceLocator.Instance.GetService<ICommonService>();
////////return commonService.UnitWork();
//var param = new CodeRuleParam()
//{
// CodeType = 1014,
// OrgId = new Guid("b043b28b-bbc3-c452-6052-4fba1457abfa"),
// Count = 1,
//};
////var xx = commonService.GetRuleCodes(param);
var codeRule = new T_PF_CODE_RULE_SERIAL()
{
ID = Guid.NewGuid(),
CODE_TYPE = 3700,
ORG_ID = new Guid("b043b28b-bbc3-c452-6052-4fba1457abfa")
};
var codeRule1 = new T_PF_CODE_RULE_SERIAL()
{
ID = Guid.NewGuid(),
CODE_TYPE = 3700,
ORG_ID = new Guid("b043b28b-bbc3-c452-6052-4fba1457abfa")
};
commonService.UnifiedCommit(() =>
{
commonService.AddEntityNoCommit(codeRule);
commonService.AddEntityNoCommit(codeRule1);
});
//this.efDbContext.AddEntity(codeRule);
//this.efDbContext.SaveChanges();
var db = this.efDbContext.GetEntity<T_PF_CODE_RULE_SERIAL>(t => t.ID == codeRule.ID, null);
return true;
}
//[HttpGet]
//[Route("api/testError")]
//public JsonActionResult<bool> testError()
//{
// return SafeExecute<bool>(()=>{
// ThrowError("100000",100,200);
// return true;
// });
//}
///// <summary>
///// 查询
///// </summary>
///// <param name="filter"></param>
///// <returns></returns>
//[HttpPost]
//[Route("api/users")]
//public IActionResult Entities([FromBody]KeywordFilter filter)
//{
// return Ok(WitEntities(null, filter));
//}
///// <summary>
///// 查询
///// </summary>
///// <param name="filter"></param>
///// <returns></returns>
/////
//[HttpPost, Route("OrderEntities")]
//public JsonActionResult<IEnumerable<APT_Test_User>> OrderEntities([FromBody]KeywordFilter filter)
//{
// return WitOrderEntities(null, filter);
//}
///// <summary>
///// 查询
///// </summary>
///// <param name="pageFilter"></param>
///// <returns></returns>
//[HttpPost, Route("Paged")]
//public PagedActionResult<APT_Test_User> Paged([FromBody]KeywordPageFilter pageFilter)
//{
// return WitPaged(null, pageFilter);
//}
///// <summary>
///// 查询
///// </summary>
///// <param name="pageFilter"></param>
///// <returns></returns>
//[HttpPost, Route("OrderPaged")]
//public async Task<PagedActionResult<APT_Test_User>> OrderPaged([FromBody]KeywordPageFilter pageFilter)
//{
// return await WitOrderPagedSync(null, pageFilter);
//}
///// <summary>
///// 删除
///// </summary>
///// <param name="id"></param>
///// <returns></returns>
//[HttpGet, Route("Delete")]
//public JsonActionResult<bool> Delete(string id)
//{
// return WitRealDelete(id);
//}
///// <summary>
///// 更新
///// </summary>
///// <param name="id"></param>
///// <returns></returns>
//[HttpPost, Route("Update")]
//public JsonActionResult<bool> Update([FromBody]APT_Test_User entity)
//{
// return WitUpdate(entity);
//}
///// <summary>
///// 批量删除
///// </summary>
///// <param name="ids"></param>
///// <returns></returns>
//[HttpGet, Route("BatchDelete")]
//public JsonActionResult<bool> BatchDelete(string ids)
//{
// return WitRealBatchDelete(ids);
//}
///// <summary>
///// 获得单条实体数据
///// </summary>
///// <param name="filter"></param>
///// <returns></returns>
//[HttpPost, Route("Get")]
//public JsonActionResult<APT_Test_User> Get([FromBody] KeywordFilter filter)
//{
// return WitEntity(null, filter);
//}
}
public class ExtTestResultModel
{
public int code { get; set; }
public bool success { get; set; }
public string message { get; set; }
public ICollection<ExtTestResultDataModel> data { get; set; }
}
public class ExtTestResultDataModel
{
public string WORKORDER_ID { get; set; }
public string STATION_ID { get; set; }
public ICollection<ExtTestResultTestDataModel> TestDataModels { get; set; }
}
public class ExtTestResultTestDataModel
{
public string SN { get; set; }
public string MAC { get; set; }
public DateTime TEST_TIME { get; set; }
public string TEST_STATE { get; set; }
public string PRODUCT_ID { get; set; }
public string WORKORDER_ID { get; set; }
public string STATION_ID { get; set; }
public ICollection<ExtTestResultTestDataParamModel> ParamList { get; set; }
}
public class ExtTestResultTestDataParamModel
{
public string PARAM_ID { get; set; }
public string PARAM_NAME { get; set; }
public string PARAM_VALUE { get; set; }
public string LIMIT_MIN_VALUE { get; set; }
public string LIMIT_MAX_VALUE { get; set; }
}
}

28
APT.API/Dockerfile Normal file
View File

@ -0,0 +1,28 @@
#See https://aka.ms/containerfastmode to understand how Visual Studio uses this Dockerfile to build your images for faster debugging.
FROM mcr.microsoft.com/dotnet/core/aspnet:3.1-buster-slim AS base
WORKDIR /app
EXPOSE 80
FROM mcr.microsoft.com/dotnet/core/sdk:3.1-buster AS build
WORKDIR /src
COPY ["APT.API/APT.API.csproj", "APT.API/"]
COPY ["APT.Domain/APT.Domain.csproj", "APT.Domain/"]
COPY ["APT.Infrastructure.EF/APT.Infrastructure.EF.csproj", "APT.Infrastructure.EF/"]
COPY ["APT.Infrastructure.Core/APT.Infrastructure.Core.csproj", "APT.Infrastructure.Core/"]
COPY ["Apt.Infrastructure.Utility/APT.Infrastructure.Utility.csproj", "Apt.Infrastructure.Utility/"]
COPY ["APT.Infrastructure.Api/APT.Infrastructure.Api.csproj", "APT.Infrastructure.Api/"]
COPY ["APT.DAL.Data/APT.DAL.Data.csproj", "APT.DAL.Data/"]
COPY ["APT.Migrations/APT.Migrations.csproj", "APT.Migrations/"]
RUN dotnet restore "APT.API/APT.API.csproj"
COPY . .
WORKDIR "/src/APT.API"
RUN dotnet build "APT.API.csproj" -c Release -o /app/build
FROM build AS publish
RUN dotnet publish "APT.API.csproj" -c Release -o /app/publish
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "APT.API.dll"]

13
APT.API/ILogTest.cs Normal file
View File

@ -0,0 +1,13 @@
using Autofac.Extras.DynamicProxy;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace APT.API
{
[Intercept(typeof(LogInterceptor))]
public interface ILogTest
{
}
}

50
APT.API/LogAttribute.cs Normal file
View File

@ -0,0 +1,50 @@
using APT.Infrastructure.Core;
using log4net;
using Microsoft.AspNetCore.Mvc.Controllers;
using Microsoft.AspNetCore.Mvc.Filters;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Web.Mvc;
namespace APT.API
{
public class LogAttribute : Attribute, IAsyncActionFilter
{
/// <summary>
/// 添加操作日志 liyouming
/// </summary>
/// <param name="context"></param>
/// <param name="next"></param>
/// <returns></returns>
public async Task OnActionExecutionAsync(Microsoft.AspNetCore.Mvc.Filters.ActionExecutingContext context, ActionExecutionDelegate next)
{
string actionArguments = context.ActionArguments.ToJson();
var resultContext = await next();
string url = resultContext.HttpContext.Request.Host + resultContext.HttpContext.Request.Path + resultContext.HttpContext.Request.QueryString;
string method = resultContext.HttpContext.Request.Method;
dynamic result = resultContext.Result.GetType().Name == "EmptyResult" ? new { Value = "EmptyResult" } : resultContext.Result as dynamic;
var userHeads = resultContext.HttpContext.Request.Headers;
var userid = string.Empty;
var username = string.Empty;
if (userHeads.ContainsKey("userid"))
{
userid = userHeads["userid"].ToString();
}
if (userHeads.ContainsKey("username"))
{
username = userHeads["username"].ToString();
}
string response = JsonConvert.SerializeObject(result.Value);
var str = $"用户ID:[{userid}],姓名:[{username}],api地址[{url}],方法:[{method}],接口参数:[{actionArguments}],应答:[{response}]";
LoggerManager.GetLogger("SQLLog").Info(str);
await next.Invoke();
}
}
}

28
APT.API/LogInterceptor.cs Normal file
View File

@ -0,0 +1,28 @@
using Autofac.Extras.DynamicProxy;
using Castle.DynamicProxy;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace APT.API
{
[Intercept(typeof(LogInterceptor))]
public class LogInterceptor: IInterceptor
{
public void Intercept(IInvocation invocation)
{
try
{
invocation.Proceed();
var s = invocation.Method.Name;
//LogManager.logger.Info(invocation.Method.Name);
}
catch (Exception ex)
{
var s = invocation.Method.Name;
//Dapper.Logger.LogHelper.logger.Error(invocation.Method.Name + " " + ex.ToString());
}
}
}
}

19
APT.API/Program.cs Normal file
View File

@ -0,0 +1,19 @@
using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Hosting;
using Autofac.Extensions.DependencyInjection;
namespace APT.API
{
public class Program
{
public static void Main(string[] args)
{
CreateWebHostBuilder(args).Build().Run();
}
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.ConfigureServices(services => services.AddAutofac())
.UseStartup<Startup>();
}
}

View File

@ -0,0 +1,36 @@
{
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:57773",
"sslPort": 0
}
},
"$schema": "http://json.schemastore.org/launchsettings.json",
"profiles": {
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"launchUrl": "api/values",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"APT.API": {
"commandName": "Project",
"launchBrowser": true,
"launchUrl": "api/values",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
},
"applicationUrl": "http://localhost:5000"
},
"Docker": {
"commandName": "Docker",
"launchBrowser": true,
"launchUrl": "{Scheme}://{ServiceHost}:{ServicePort}/api/values",
"publishAllPorts": true
}
}
}

122
APT.API/Startup.cs Normal file
View File

@ -0,0 +1,122 @@
using Autofac;
using APT.Infrastructure.Core;
using APT.Infrastructure.Core.Utils;
using APT.Infrastructure.EF;
using log4net;
using log4net.Config;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using System.IO;
using APT.Infrastructure.Api.WebFilters;
using Autofac.Extras.DynamicProxy;
using APT.Infrastructure.EF.Infrastructure;
using APT.Infrastructure.EF.Extensions;
using APT.Infrastructure.Api;
using ConfigurationManager = APT.Infrastructure.Api.ConfigurationManager;
namespace APT.API
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
var repository = LogManager.GetRepository
(System.Reflection.Assembly.GetEntryAssembly());
var fileInfo = new FileInfo("log4net.config");
if (!fileInfo.Exists)
fileInfo = new FileInfo(Path.Combine(System.AppContext.BaseDirectory, "log4net.config"));
XmlConfigurator.Configure(repository, fileInfo);
ConfigurationManager.Register(configuration);
InitUtils.Init();
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddScoped<TenantInfo>();
services.AddScoped<IConnectionResolver, HttpHeaderSqlConnectionResolver>();
services.AddScoped<IConnectionGenerator, CombindedConnectionGenerator>();
//services.AddPostgrePerConnection<EfDbContext>(settings =>
//{
// settings.ConnectionPrefix = "postgre_store";
//});
services.AddMvc(t=> {
t.EnableEndpointRouting = false;
});
// services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
services.TryAddSingleton<IHttpContextAccessor, HttpContextAccessor>();
//UpdateDatabase();
}
void setupDb(TenantSettings<EfDbContext> settings)
{
//settings.ConnectionPrefix = "de";
//settings.DbContextSetup = (serviceProvider, connectionString, optionsBuilder) =>
//{
// var tenant = serviceProvider.GetService<TenantInfo>();
// optionsBuilder
// .UseLazyLoadingProxies(false)
// .UseNpgsql(connectionString, builder =>
// {
// // not necessary, if you are not using the table or schema
// builder.TenantBuilderSetup(serviceProvider, settings, tenant);
// });
//};
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseMiddleware<TenantInfoMiddleware>();
Infrastructure.Api.HttpContext.Register(app.ApplicationServices.
GetRequiredService<IHttpContextAccessor>()
);
app.Use(next => context => {
context.Request.EnableBuffering();
return next(context);
});
app.UseHttpsRedirection();
app.UseMvc();
}
private static void UpdateDatabase()
{
//using (var context = new MigrationContext())
//{
// context.Database.Migrate();
//}
}
public virtual void ConfigureContainer(ContainerBuilder builder)
{
builder.RegisterComponents();
//var builders = new ConfigurationBuilder()
//.AddJsonFile("appsettings.json");
//ConfigurationHelper.Configuration = builders.Build();
}
}
}

View File

@ -0,0 +1,9 @@
{
"Logging": {
"LogLevel": {
"Default": "Debug",
"System": "Information",
"Microsoft": "Information"
}
}
}

32
APT.API/appsettings.json Normal file
View File

@ -0,0 +1,32 @@
{
"ConnectionStrings": {
//"default": "Data Source=172.20.8.76:1521/DB1;User ID=\"dbo\";Password=mssdev"
//"default": "Database=Test1;Data Source=localhost;Port=3306;User Id=root;Password=123456;TreatTinyAsBoolean=true;",
//"default": "Data Source=172.20.8.76:1521/DB1;User Id=\"dbo\";Password=mssdev;Pooling=false;PERSIST SECURITY INFO=True;"
//"default": "Data Source=172.20.10.173;Initial Catalog=DBTest;User ID=sa;Password=Ldx123456"
//"default": "User ID=postgres;Password=123456;Host=172.20.8.48;Port=5432;Database=mes;CommandTimeout=1024;",
"default": "User ID=postgres;Password=123456;Host=localhost;Port=5432;Database=Infracture_Test;CommandTimeout=1024;",
"postgre_store1": "Server=127.0.0.1;Port=5432;Database=testdb1;User Id=postgres;Password=123456;",
"postgre_store2": "Server=127.0.0.1;Port=5432;Database=testdb2;User Id=postgres;Password=123456;",
"postgre_store3": "Server=127.0.0.1;Port=5432;Database=testdb3;User Id=postgres;Password=123456;"
},
"AppSettings": {
"DataBaseType": "postgresql",
"isSqlLog": "true",
"ConnApiUrl": "http://172.20.8.48/GetConn",
"ConnDataKey": "optenergy"
},
"AllowedHosts": "*",
"InflexdbConfig": {
"Url": "http://192.168.2.98:8087/",
"UserName": "optuser",
"PassWord": "optienergy",
"DbName": "opt",
"LogDbName": "OPTiEnergyLog",
"AppOnline": "optAppOnline"
}
}

39
APT.API/log4net.config Normal file
View File

@ -0,0 +1,39 @@
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<!-- This section contains the log4net configuration settings -->
<log4net>
<appender name="ConsoleAppender" type="log4net.Appender.ConsoleAppender">
<layout type="log4net.Layout.PatternLayout" value="%date [%thread] %-5level %logger - %message%newline" />
</appender>
<appender name="FileAppender" type="log4net.Appender.FileAppender">
<file value="log-file.log" />
<appendToFile value="true" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date [%thread] %-5level %logger [%property{NDC}] - %message%newline" />
</layout>
</appender>
<appender name="RollingLogFileAppender" type="log4net.Appender.RollingFileAppender">
<file value="logfile/" />
<appendToFile value="true" />
<rollingStyle value="Composite" />
<staticLogFileName value="false" />
<datePattern value="yyyyMMdd'.log'" />
<maxSizeRollBackups value="10" />
<maximumFileSize value="1MB" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date [%thread] %-5level %logger [%property{NDC}] - %message%newline" />
</layout>
</appender>
<!-- Setup the root category, add the appenders and set the default level -->
<root>
<level value="ALL" />
<appender-ref ref="ConsoleAppender" />
<appender-ref ref="FileAppender" />
<appender-ref ref="RollingLogFileAppender" />
</root>
</log4net>
</configuration>

View File

@ -0,0 +1,16 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.1</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="5.0.2" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="5.0.2" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\APT.Domain\APT.Domain.csproj" />
</ItemGroup>
</Project>

27
APT.DAL.Data/CourseMap.cs Normal file
View File

@ -0,0 +1,27 @@
using APT.Domain;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
using System;
using System.Collections.Generic;
using System.Text;
namespace APT.DAL.Data
{
public class CourseMap : IEntityTypeConfiguration<APT_Test_Course>
{
public CourseMap(ModelBuilder builder)
{
builder.Entity<APT_Test_Course>()
.HasOne(o => o.TestUser)
.WithMany()
.HasForeignKey(o => o.UserID);
}
public virtual void Configure(EntityTypeBuilder<APT_Test_Course> builder)
{
builder.HasOne(o => o.TestUser)
.WithMany()
.HasForeignKey(o => o.UserID);
}
}
}

27
APT.DAL.Data/PhoneMap.cs Normal file
View File

@ -0,0 +1,27 @@
using APT.Domain;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
using System;
using System.Collections.Generic;
using System.Text;
namespace APT.DAL.Data
{
public class PhoneMap : IEntityTypeConfiguration<APT_Test_Phone>
{
//public PhoneMap(ModelBuilder builder)
//{
// builder.Entity<APT_Test_Phone>()
// .HasOne(o => o.TestUser)
// .WithMany()
// .HasForeignKey(o => o.TestUser_ID);
//}
public virtual void Configure(EntityTypeBuilder<APT_Test_Phone> builder)
{
builder.HasOne(o => o.Nav_TestUser)
.WithMany()
.HasForeignKey(o => o.TestUser_ID);
}
}
}

View File

@ -0,0 +1,16 @@
using APT.Domain;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
using System;
using System.Collections.Generic;
using System.Text;
namespace APT.DAL.Data
{
public class TestNoneBaseMap : IEntityTypeConfiguration<TestNoneBaseModel>
{
public virtual void Configure(EntityTypeBuilder<TestNoneBaseModel> builder)
{
}
}
}

40
APT.DAL.Data/UserMap.cs Normal file
View File

@ -0,0 +1,40 @@
using APT.Domain;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
using System;
using System.Collections.Generic;
using System.Text;
namespace APT.DAL.Data
{
public class UserMap : IEntityTypeConfiguration<APT_Test_User>
{
//public UserMap(ModelBuilder builder)
//{
// builder.Entity<APT_Test_User>(c =>
// {
// c.HasMany(o => o.TestPhones)
// .WithOne(o => o.TestUser)
// .HasForeignKey(o => o.TestUser_ID);
// c.HasMany(o => o.Courses)
// .WithOne(o => o.TestUser)
// .HasForeignKey(o => o.UserID);
// });
// builder.Entity<APT_Test_User>().Property(t => t.IS_DELETED).HasColumnType("bit(1)");
//}
public virtual void Configure(EntityTypeBuilder<APT_Test_User> builder)
{
//builder.HasMany(o => o.TestPhones)
//.WithOne(o => o.Nav_TestUser)
//.HasForeignKey(o => o.TestUser_ID);
builder.HasMany(o => o.Courses)
.WithOne(o => o.TestUser)
.HasForeignKey(o => o.UserID);
}
}
}

View File

@ -0,0 +1,15 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.1</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="5.0.2" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\APT.Infrastructure.EF\APT.Infrastructure.EF.csproj" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,22 @@
using APT.Infrastructure.Core;
using System;
using System.Collections.Generic;
using System.Text;
namespace APT.Domain
{
public class APT_Test_Course : MesEntityBase
{
public string Name { get; set; }
public string TeacherName { get; set; }
public string ClassTime { get; set; }
public int Score { get; set; }
public Guid UserID { get; set; }
public virtual APT_Test_User TestUser { get; set; }
}
}

View File

@ -0,0 +1,22 @@
using APT.Infrastructure.Core;
using System;
using System.Collections.Generic;
using System.Text;
namespace APT.Domain
{
public class APT_Test_Phone : MesEntityBase
{
public string Brand { get; set; }
public string Model { get; set; }
public decimal Price { get; set; }
public Guid TestUser_ID { get; set; }
public int? Number { get; set; }
public virtual APT_Test_User Nav_TestUser { get; set; }
}
}

View File

@ -0,0 +1,18 @@
using APT.Infrastructure.Core;
using System.Collections.Generic;
namespace APT.Domain
{
public class APT_Test_User : MesEntityBase
{
public string Country { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
/// public virtual ICollection<APT_Test_Phone> TestPhones { get; set; }
public virtual ICollection<APT_Test_Course> Courses { get; set; }
}
}

15
APT.Domain/ModelBase.cs Normal file
View File

@ -0,0 +1,15 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace APT.Domain
{
public class EntityBase
{
public Guid ID { get; set; } = Guid.NewGuid();
public DateTime CreatedTime { get; set; } = DateTime.Now;
public DateTime LastUpdated { get; set; } = DateTime.Now;
}
}

View File

@ -0,0 +1,13 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace APT.Domain
{
public class TestNoneBaseModel
{
public string ID { get; set; }
public string Name { get; set; }
}
}

73
APT.Frame.sln Normal file
View File

@ -0,0 +1,73 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.30011.22
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "APT.API", "APT.API\APT.API.csproj", "{F87A3F72-7E1A-4F63-BE31-6F88199945F0}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "APT.DAL.Data", "APT.DAL.Data\APT.DAL.Data.csproj", "{8A846A4E-70E7-410B-BEC9-DA625E0A0B06}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "APT.Domain", "APT.Domain\APT.Domain.csproj", "{25554D0A-39CA-4E43-B514-ECC66C5A124F}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "APT.Infrastructure.Api", "APT.Infrastructure.Api\APT.Infrastructure.Api.csproj", "{0F778BA2-640D-4DBA-BF17-DBFE40D94C81}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "APT.Infrastructure.Core", "APT.Infrastructure.Core\APT.Infrastructure.Core.csproj", "{783359E8-9993-42E4-8CD9-D6D3C52B0085}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "APT.Infrastructure.EF", "APT.Infrastructure.EF\APT.Infrastructure.EF.csproj", "{AC74146E-9B8D-4B92-8096-E37E13A498E0}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "APT.Migrations", "APT.Migrations\APT.Migrations.csproj", "{CE1F054B-F743-4581-903A-2E5E1D99DC51}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "APT.Infrastructure.Utility", "Apt.Infrastructure.Utility\APT.Infrastructure.Utility.csproj", "{960E5BF4-8B74-4E81-91D8-ADCA8ABED8E1}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "APT.Infrastructure.Redis", "APT.Infrastructure.Redis\APT.Infrastructure.Redis.csproj", "{BD1F2435-9879-4F57-A3B2-5D61D1817CD5}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{F87A3F72-7E1A-4F63-BE31-6F88199945F0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F87A3F72-7E1A-4F63-BE31-6F88199945F0}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F87A3F72-7E1A-4F63-BE31-6F88199945F0}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F87A3F72-7E1A-4F63-BE31-6F88199945F0}.Release|Any CPU.Build.0 = Release|Any CPU
{8A846A4E-70E7-410B-BEC9-DA625E0A0B06}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{8A846A4E-70E7-410B-BEC9-DA625E0A0B06}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8A846A4E-70E7-410B-BEC9-DA625E0A0B06}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8A846A4E-70E7-410B-BEC9-DA625E0A0B06}.Release|Any CPU.Build.0 = Release|Any CPU
{25554D0A-39CA-4E43-B514-ECC66C5A124F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{25554D0A-39CA-4E43-B514-ECC66C5A124F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{25554D0A-39CA-4E43-B514-ECC66C5A124F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{25554D0A-39CA-4E43-B514-ECC66C5A124F}.Release|Any CPU.Build.0 = Release|Any CPU
{0F778BA2-640D-4DBA-BF17-DBFE40D94C81}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{0F778BA2-640D-4DBA-BF17-DBFE40D94C81}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0F778BA2-640D-4DBA-BF17-DBFE40D94C81}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0F778BA2-640D-4DBA-BF17-DBFE40D94C81}.Release|Any CPU.Build.0 = Release|Any CPU
{783359E8-9993-42E4-8CD9-D6D3C52B0085}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{783359E8-9993-42E4-8CD9-D6D3C52B0085}.Debug|Any CPU.Build.0 = Debug|Any CPU
{783359E8-9993-42E4-8CD9-D6D3C52B0085}.Release|Any CPU.ActiveCfg = Release|Any CPU
{783359E8-9993-42E4-8CD9-D6D3C52B0085}.Release|Any CPU.Build.0 = Release|Any CPU
{AC74146E-9B8D-4B92-8096-E37E13A498E0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{AC74146E-9B8D-4B92-8096-E37E13A498E0}.Debug|Any CPU.Build.0 = Debug|Any CPU
{AC74146E-9B8D-4B92-8096-E37E13A498E0}.Release|Any CPU.ActiveCfg = Release|Any CPU
{AC74146E-9B8D-4B92-8096-E37E13A498E0}.Release|Any CPU.Build.0 = Release|Any CPU
{CE1F054B-F743-4581-903A-2E5E1D99DC51}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{CE1F054B-F743-4581-903A-2E5E1D99DC51}.Debug|Any CPU.Build.0 = Debug|Any CPU
{CE1F054B-F743-4581-903A-2E5E1D99DC51}.Release|Any CPU.ActiveCfg = Release|Any CPU
{CE1F054B-F743-4581-903A-2E5E1D99DC51}.Release|Any CPU.Build.0 = Release|Any CPU
{960E5BF4-8B74-4E81-91D8-ADCA8ABED8E1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{960E5BF4-8B74-4E81-91D8-ADCA8ABED8E1}.Debug|Any CPU.Build.0 = Debug|Any CPU
{960E5BF4-8B74-4E81-91D8-ADCA8ABED8E1}.Release|Any CPU.ActiveCfg = Release|Any CPU
{960E5BF4-8B74-4E81-91D8-ADCA8ABED8E1}.Release|Any CPU.Build.0 = Release|Any CPU
{BD1F2435-9879-4F57-A3B2-5D61D1817CD5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{BD1F2435-9879-4F57-A3B2-5D61D1817CD5}.Debug|Any CPU.Build.0 = Debug|Any CPU
{BD1F2435-9879-4F57-A3B2-5D61D1817CD5}.Release|Any CPU.ActiveCfg = Release|Any CPU
{BD1F2435-9879-4F57-A3B2-5D61D1817CD5}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {309AAC7D-8F7A-4037-A847-A42A651A48B6}
EndGlobalSection
EndGlobal

View File

@ -0,0 +1,31 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.1</TargetFramework>
<Version>2.0.2.52</Version>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<AssemblyVersion>2.0.0.52</AssemblyVersion>
<FileVersion>2.0.0.52</FileVersion>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<DocumentationFile>.\APT.Infrastructure.Api.xml</DocumentationFile>
<WarningLevel>3</WarningLevel>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Autofac" Version="5.1.2" />
<PackageReference Include="Autofac.Extensions.DependencyInjection" Version="6.0.0" />
<PackageReference Include="CSRedisCore" Version="3.6.5" />
<PackageReference Include="Fleck" Version="1.1.0" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.Core" Version="2.2.5" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="5.0.2" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="5.0.2" />
<PackageReference Include="StackExchange.Redis" Version="2.1.58" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\APT.Infrastructure.Core\APT.Infrastructure.Core.csproj" />
</ItemGroup>
</Project>

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,202 @@
using APT.Infrastructure.Api.Model;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Mvc;
using System;
using System.Linq;
using System.Linq.Expressions;
using System.Security.Claims;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using APT.Infrastructure.Core;
namespace APT.Infrastructure.Api
{
//[Log]
public abstract class BaseApiController : ControllerBase
{
/// <summary>
/// 抛出错误
/// </summary>
/// <param name="code"></param>
protected void ThrowError(string code, params object [] objs)
{
LibMessageUtils.ThrowError(code,objs);
}
/// <summary>
/// 为 基础操作 提供统一的返回格式包含try / catch操作。
/// </summary>
/// <typeparam name="TResult">返回值类型</typeparam>
/// <param name="execAction"></param>
/// <returns></returns>
protected virtual JsonActionResult<TResult> SafeExecute<TResult>(Func<TResult> execAction, int retryTime = 0)
{
var result = new JsonActionResult<TResult>();
try
{
result.Data = execAction();
}
catch (CodeException ex)
{
LoggerManager.GetLogger().Error(ex.ToString());
result.IsSuccessful = false;
result.ErrorMessage = GetErrorMsg(ex);
result.Code = ex.Code;
}
catch (Exception ex)
{
if (NeedRetryExceptions.RetryExceptions().Any(o => ex.Message.Contains(o)) && retryTime <= 3 && retryTime > 0)
{
retryTime += 1;
Thread.Sleep(5000);
return this.SafeExecute(execAction, retryTime);
}
var errMsg = LogHelper.GetCurSourceFileName() + " - " + LogHelper.GetLineNum() + ":" + ex.Message;
LoggerManager.GetLogger().Error(errMsg);
result.IsSuccessful = false;
result.ErrorMessage = errMsg;
}
return result;
}
/// <summary>
/// 为 基础操作 提供统一的返回格式包含try / catch操作。
/// </summary>
/// <typeparam name="TResult">返回值类型</typeparam>
/// <param name="execAction"></param>
/// <returns></returns>
protected virtual async Task<JsonActionResult<TResult>> SafeExecuteAsync<TResult>(Func<Task<TResult>> execAction, int retryTime = 0)
{
var result = new JsonActionResult<TResult>();
try
{
result.Data = await execAction();
}
catch (CodeException ex)
{
LoggerManager.GetLogger().Error(ex.ToString());
result.IsSuccessful = false;
result.ErrorMessage = GetErrorMsg(ex);
result.Code = ex.Code;
}
catch (Exception ex)
{
if (NeedRetryExceptions.RetryExceptions().Any(o => ex.Message.Contains(o)) && retryTime <= 3 && retryTime >0)
{
retryTime += 1;
Thread.Sleep(5000);
return await this.SafeExecuteAsync(execAction, retryTime);
}
var errMsg = LogHelper.GetCurSourceFileName() + " - " + LogHelper.GetLineNum() + ":" + ex.Message;
LoggerManager.GetLogger().Error(errMsg);
result.IsSuccessful = false;
result.ErrorMessage = errMsg;
}
return result;
}
protected string GetErrorMsg(Exception ex)
{
string innerError = string.Empty;
GetInnerErrorMsg(ex.InnerException, ref innerError);
return ex.Message + (!string.IsNullOrEmpty(innerError) ? (",报错明细:" + innerError) : string.Empty);
}
private void GetInnerErrorMsg(Exception ex, ref string error)
{
if (ex == null) return;
error = ex.Message;
GetInnerErrorMsg(ex.InnerException, ref error);
}
/// <summary>
/// 为 基础操作 提供统一的返回格式包含try / catch操作。
/// </summary>
/// <typeparam name="TResult">返回值类型</typeparam>
/// <param name="execAction"></param>
/// <returns></returns>
protected JsonActionResult<TResult> SafeJsonExecute<TResult>(Action<JsonActionResult<TResult>> execAction)
{
var result = new JsonActionResult<TResult>();
try
{
execAction(result);
}
catch (CodeException ex)
{
LoggerManager.GetLogger().Error(ex.ToString());
result.IsSuccessful = false;
result.ErrorMessage = GetErrorMsg(ex);
result.Code = ex.Code;
}
catch (Exception ex)
{
var errMsg = LogHelper.GetCurSourceFileName() + " - " + LogHelper.GetLineNum() + ":" + ex.Message;
LoggerManager.GetLogger().Error(errMsg);
result.IsSuccessful = false;
result.ErrorMessage = errMsg;
}
return result;
}
/// <summary>
/// 为取 分页数据 提供统一的返回格式包含try / catch操作。
/// </summary>
/// <typeparam name="TResult">返回值类型</typeparam>
/// <param name="execAction"></param>
/// <returns></returns>
protected PagedActionResult<TResult> SafeGetPagedData<TResult>(Action<PagedActionResult<TResult>> execAction)
{
var result = new PagedActionResult<TResult>();
try
{
execAction(result);
}
catch (CodeException ex)
{
LoggerManager.GetLogger().Error(ex.ToString());
result.IsSuccessful = false;
result.ErrorMessage = GetErrorMsg(ex);
result.Code = ex.Code;
}
catch (Exception ex)
{
var errMsg = LogHelper.GetCurSourceFileName() + " - " + LogHelper.GetLineNum() + ":" + ex.Message;
LoggerManager.GetLogger().Error(errMsg);
result.IsSuccessful = false;
result.ErrorMessage = errMsg;
}
return result;
}
/// <summary>
/// 根据Request中的QueryString获得Linq表达式
/// </summary>
/// <typeparam name="TEntity">实体对象</typeparam>
/// <returns></returns>
protected Expression<Func<TEntity, bool>> GetExpressionFromQueryString<TEntity>()
{
Expression<Func<TEntity, bool>> expr = null;
var queryPairs = Request.Query.ToDictionary(q => q.Key, q => q.Value).Where(q => q.Key.Equals("$format") == false);
if (queryPairs.Count() > 0)
{
var filterGroup = new FilterGroup();
foreach (var pairItem in queryPairs)
{
filterGroup.Rules.Add(new FilterRule(pairItem.Key, pairItem.Value));
}
expr = filterGroup.BuildExpression<TEntity>(null);
}
return expr;
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,9 @@
namespace APT.Infrastructure.Api
{
/// <summary>
/// 依赖注入接口只有实现该接口才可以被注册到IoC容器中
/// </summary>
public interface IDependency
{
}
}

View File

@ -0,0 +1,74 @@
using Autofac;
using Autofac.Extensions.DependencyInjection;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using APT.Infrastructure.Core;
namespace APT.Infrastructure.Api
{
/// <summary>
/// 服务对象定位器
/// </summary>
public sealed class ServiceLocator
{
#region fields
#endregion
private IServiceProvider _autofacServiceProvider = null;
#region ctor.
private ServiceLocator()
{
ContainerBuilder builder = new ContainerBuilder();
builder.RegisterModule<DefaultAutofacModuleRegister>();
var AutofacContainer = builder.Build();
_autofacServiceProvider = new AutofacServiceProvider(AutofacContainer);
}
#endregion
#region properties
#region Instance
private static readonly ServiceLocator s_Instance = new ServiceLocator();
/// <summary>
/// 服务对象定位器实例
/// </summary>
public static ServiceLocator Instance
{
get { return s_Instance; }
}
#endregion
#endregion
#region methods
/// <summary>
/// 获取泛型服务对象
/// </summary>
/// <typeparam name="T">服务对象的类型</typeparam>
/// <returns></returns>
///
public T GetService<T>()
{
if (HttpContext.Current != null && HttpContext.Current.RequestServices != null)
return (T)HttpContext.Current.RequestServices.GetService(typeof(T));
if (_autofacServiceProvider != null)
return (T)_autofacServiceProvider.GetService(typeof(T));
return default(T);
}
#endregion
}
}

View File

@ -0,0 +1,73 @@
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Primitives;
using System;
using System.Collections.Generic;
namespace APT.Infrastructure.Api
{
public class ConfigurationSectionExtension : IConfigurationSection, IConfiguration
{
private readonly string sectionKey;
private IConfiguration configuration;
public string Key
{
get;
}
public string Path
{
get;
}
public string Value
{
get;
set;
}
public string this[string key]
{
get
{
string enviromentValue = GetEnviromentValue(key);
if (string.IsNullOrEmpty(enviromentValue))
{
return configuration.GetSection(sectionKey)[key];
}
return enviromentValue;
}
set
{
configuration.GetSection(sectionKey)[key] = value;
}
}
public ConfigurationSectionExtension(string sectionKey, IConfiguration configuration)
{
this.sectionKey = sectionKey;
this.configuration = configuration;
}
public IEnumerable<IConfigurationSection> GetChildren()
{
throw new NotImplementedException();
}
public IChangeToken GetReloadToken()
{
throw new NotImplementedException();
}
public IConfigurationSection GetSection(string key)
{
throw new NotImplementedException();
}
protected virtual string GetEnviromentValue(string key)
{
return System.Environment.GetEnvironmentVariable(key);
}
}
}

View File

@ -0,0 +1,19 @@
using Microsoft.AspNetCore.Http;
using System;
using System.Collections.Generic;
using System.Text;
namespace APT.Infrastructure.Api
{
public static class HttpContext
{
private static IHttpContextAccessor contextAccessor;
public static Microsoft.AspNetCore.Http.HttpContext Current => contextAccessor?.HttpContext;
public static void Register(IHttpContextAccessor httpContextAccessor)
{
contextAccessor = httpContextAccessor;
}
}
}

View File

@ -0,0 +1,43 @@
using APT.Infrastructure.Core;
using log4net;
using Microsoft.AspNetCore.Mvc.Filters;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace APT.Infrastructure.Api
{
public class RootOrgAttribute : Attribute, IAsyncActionFilter
{
/// <summary>
/// 添加根节点过滤
/// </summary>
/// <param name="context"></param>
/// <param name="next"></param>
/// <returns></returns>
public async Task OnActionExecutionAsync(Microsoft.AspNetCore.Mvc.Filters.ActionExecutingContext context, ActionExecutionDelegate next)
{
try
{
var s = context.HttpContext.Request.Headers["RootOrgId"].ToString();
if (!string.IsNullOrEmpty(s))
{
AppContext.CurrentSession.RootOrgId = new Guid(s);
}
}
catch (Exception ex)
{
LoggerManager.GetLogger().Error(Infrastructure.Core.LogHelper.GetCurSourceFileName() + " - " + LogHelper.GetLineNum() + ":" + ex.Message);
//throw;
}
finally
{
await next.Invoke();
}
}
}
}

View File

@ -0,0 +1,301 @@
using APT.Infrastructure.Api.Redis;
using APT.Infrastructure.Core;
using Fleck;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
namespace APT.Infrastructure.Api
{
/// <summary>
/// webSocket 服务帮助类
/// </summary>
public static class WebSocketServiceHelper
{
private static List<WebSocketClientInfo> _clientInfos;
public static List<WebSocketClientInfo> ClintInfos
{
get
{
if (_clientInfos == null)
_clientInfos = new List<WebSocketClientInfo>();
return _clientInfos;
}
}
public static List<Guid> UserIds
{
get
{
return ClintInfos.Where(t => t.UserId != null).Select(t => t.UserId.Value).ToList();
}
}
/// <summary>
/// 初始化WebSocket服务
/// </summary>
/// <param name="port"></param>
/// <param name="onOpen"></param>
/// <param name="onClose"></param>
/// <param name="onMessage"></param>
public static void InitService(int port,
Func<WebSocketClientInfo, WebSocketResponseInfo>
onOpen,
Func<WebSocketClientInfo, WebSocketRequestInfo, WebSocketResponseInfo>
onMessage,
Action<Guid, WebSocketClientInfo>
onClose)
{
FleckLog.Level = LogLevel.Debug;
var server = new WebSocketServer("ws://0.0.0.0:" + (port == 0 ? 8181 : port));
server.Start(socket =>
{
socket.OnOpen = () =>
{
WebSocketClientInfo webSocketClientInfo = new WebSocketClientInfo();
webSocketClientInfo.WebSocketConnection = socket;
ClintInfos.Add(webSocketClientInfo);
if (onOpen != null)
{
var ret = onOpen(webSocketClientInfo);
if (ret != null)
socket.Send(JsonConvert.SerializeObject(ret));
}
};
socket.OnClose = () =>
{
var info = ClintInfos.FirstOrDefault(t => t.WebSocketConnection == socket);
if (info != null)
ClintInfos.Remove(info);
if (onClose != null && info?.UserId != null)
onClose(info.UserId.Value, info);
};
socket.OnMessage = message =>
{
var info = ClintInfos.FirstOrDefault(t => t.WebSocketConnection == socket);
if (info != null)
{
try
{
var requestInfo = JsonConvert.DeserializeObject<WebSocketRequestInfo>(message);
if (requestInfo != null)
{
if (string.Compare(requestInfo.TypeCode, "P0001", true) == 0)//登入
{
if (!string.IsNullOrEmpty(requestInfo.Data))
{
var loginInfo = JsonConvert.DeserializeObject<WebSocketRequestLoginInfo>(requestInfo.Data);
if (loginInfo != null)
{
info.Tenant = loginInfo.Tenant;
info.UserId = loginInfo.UserId;
info.DbConn = GetDbConn(info.Tenant);
info.UserName = loginInfo.UserName;
info.ClientType = (WebSocketClientTypeEnum)loginInfo.ClientType;
}
}
}
if (onMessage != null)
{
var ret = onMessage(info, requestInfo);
if (ret != null)
socket.Send(JsonConvert.SerializeObject(ret));
}
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
};
});
}
/// <summary>
/// 发生消息到所有用户
/// </summary>
/// <param name="responseInfo"></param>
public static void SendToAll(WebSocketResponseInfo responseInfo)
{
SendToAll(responseInfo, null);
}
/// <summary>
/// 发生消息到所有用户
/// </summary>
/// <param name="responseInfo"></param>
/// <param name="checkClientInfoFunc">检查客户端有效性</param>
public static void SendToAll(WebSocketResponseInfo responseInfo, Func<WebSocketClientInfo, bool> checkClientInfoFunc = null)
{
if (responseInfo == null) return;
List<WebSocketResponseInfo> webSocketResponseInfos = new List<WebSocketResponseInfo>();
webSocketResponseInfos.Add(responseInfo);
SendToAll(webSocketResponseInfos, checkClientInfoFunc);
}
/// <summary>
/// 发送信息到所有用户
/// </summary>
/// <param name="responseInfos"></param>
public static void SendToAll(List<WebSocketResponseInfo> responseInfos)
{
SendToAll(responseInfos, null);
}
/// <summary>
/// 发送信息到所有用户
/// </summary>
/// <param name="responseInfos"></param>
/// <param name="checkClientInfoFunc">检查客户端有效性</param>
public static void SendToAll(List<WebSocketResponseInfo> responseInfos, Func<WebSocketClientInfo, bool> checkClientInfoFunc = null)
{
if (responseInfos == null || !responseInfos.Any() || !ClintInfos.Any()) return;
ClintInfos.ForEach(t =>
{
if (checkClientInfoFunc != null)
{
if (!checkClientInfoFunc(t))
return;
}
if (t.WebSocketConnection != null)
{
responseInfos.ForEach(t1 =>
{
t.WebSocketConnection.Send(JsonConvert.SerializeObject(t1));
});
}
});
}
/// <summary>
/// 发送消息到指定用户
/// </summary>
/// <param name="userId"></param>
/// <param name="responseInfo"></param>
public static void SendToUser(Guid userId, WebSocketResponseInfo responseInfo)
{
if (responseInfo == null) return;
List<WebSocketResponseUserInfo> responseUseInfos = new List<WebSocketResponseUserInfo>();
WebSocketResponseUserInfo info = new WebSocketResponseUserInfo();
info.UserId = userId;
info.Data = responseInfo.Data;
info.TypeCode = responseInfo.TypeCode;
responseUseInfos.Add(info);
SendToUser(responseUseInfos);
}
/// <summary>
/// 发送消息到指定用户
/// </summary>
/// <param name="responseUseInfos"></param>
public static void SendToUser(List<WebSocketResponseUserInfo> responseUseInfos)
{
if (responseUseInfos == null || !responseUseInfos.Any()) return;
responseUseInfos.ForEach(t =>
{
if (t.UserId != null)
{
var userClientInfo = ClintInfos?.Where(t1 => t1.UserId == t.UserId && t1.WebSocketConnection != null).ToList();
userClientInfo.ForEach(t1 =>
{
t1.WebSocketConnection.Send(JsonConvert.SerializeObject(t));
});
}
});
}
public static string GetDbConn(string tenantName)
{
//redis取數據
var deskey = ConfigurationManager.AppSettings["ConnDataKey"];
if (string.IsNullOrEmpty(deskey))
deskey = "optenergy2021001";
var tenantKey = ConfigurationManager.AppSettings["TenantConnKey"] + tenantName;
if (CsRedisManager.KeyExists(tenantKey))
{
var conns = CsRedisManager.StringGet(tenantKey);
var retConn = conns == "null" ? null : EncryptHelper.AesDecrypt(conns, deskey); ;
return retConn;
}
else
{
var url = ConfigurationManager.AppSettings["ConnApiUrl"];
if (!string.IsNullOrEmpty(url))
{
var deData = WebUtils.Get(url, "code", tenantName, "");
//LoggerManager.GetLogger().Info($"TenantData:{deData}");
return EncryptHelper.AesDecrypt(deData, deskey);
}
}
return ConfigurationManager.ConnectionStrings["default"];
}
}
public enum WebSocketClientTypeEnum
{
WEB后台 = 0,
= 1,
APP = 2,
= 99,
}
public class WebSocketClientInfo
{
public IWebSocketConnection WebSocketConnection { get; set; }
public Guid? UserId { get; set; }
public string UserName { get; set; }
public string Tenant { get; set; }
public string DbConn { get; set; }
public Guid? OrgId { get; set; }
public WebSocketClientTypeEnum ClientType { get; set; }
}
public class WebSocketRequestInfo
{
public WebSocketRequestInfo()
{
this.TypeCode = "U0000";
}
public string TypeCode { get; set; }
public string Tenant { get; set; }
public string Data { get; set; }
}
public class WebSocketResponseInfo
{
public WebSocketResponseInfo()
{
this.TypeCode = "U0000";
}
public string TypeCode { get; set; }
public object Data { get; set; }
}
public class WebSocketResponseUserInfo : WebSocketResponseInfo
{
public Guid? UserId { get; set; }
}
public class WebSocketRequestLoginInfo
{
public Guid? UserId { get; set; }
public string UserName { get; set; }
public string Tenant { get; set; }
public string DbConn { get; set; }
public Guid? OrgId { get; set; }
public int ClientType { get; set; }
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,18 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace APT.Infrastructure.Api.Model
{
public static class NeedRetryExceptions
{
public static List<string> RetryExceptions()
{
return new List<string>()
{
"transient failure",
"EntityFrameworkCore"
};
}
}
}

View File

@ -0,0 +1,50 @@
using System;
using System.Collections.Generic;
using System.Dynamic;
namespace APT.Infrastructure.Api
{
public class TenantInfo: DynamicObject
{
public string Name { get; set; }
public string Conn { get; set; }
public bool IsPresent { get; set; }
public bool IsWrite { get; set; }
public object Generator { get; set; }
public dynamic Container { get; set; } = new ExpandoObject();
Dictionary<string, object> dictionary = new Dictionary<string, object>();
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
return dictionary.TryGetValue(binder.Name, out result);
}
public override bool TrySetMember(SetMemberBinder binder, object value)
{
dictionary[binder.Name] = value;
return true;
}
public override bool TrySetIndex(SetIndexBinder binder, object[] indexes, object value)
{
if (!(indexes?.Length > 0))
return false;
dictionary[indexes[0].ToString()] = value;
return true;
}
public override bool TryGetIndex(GetIndexBinder binder, object[] indexes, out object result)
{
result = null;
if (!(indexes?.Length > 0))
return false;
result = dictionary[indexes[0].ToString()];
return true;
}
}
}

View File

@ -0,0 +1,509 @@
using APT.Infrastructure.Core;
using CSRedis;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
namespace APT.Infrastructure.Api.Redis
{
public class CsRedisManager
{
static CSRedisClient redisManger = null;
public static CSRedisClient GetClient()
{
return redisManger;
}
static JsonSerializerSettings _jsonSetting;
public static string ConvertJson<T>(T value)
{
string result = value is string ? value.ToString() : JsonConvert.SerializeObject(value, _jsonSetting);
return result;
}
static CsRedisManager()
{
_jsonSetting = new JsonSerializerSettings();
_jsonSetting.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
RedisOption option = ConfigurationManager.RedisOption;
if (option != null)
{
//SysCustomKey = option.RedisPrefixKey;
//RedisConnectionString = option.RedisConnectionString;
//RedisPwd = option.RedisConnectionPwd;
}
else
{
throw new Exception($"未加载redis.json文件");
}
redisManger = new CSRedisClient(option.RedisConnectionString); //Redis的连接字符串
}
/// <summary>
/// TradeManageMessage 和 TradeManageMessage:MQ队列
/// </summary>
/// <returns></returns>
public static bool EnQeenTradeManageMessage(string value)
{
try
{
LoggerManager.GetLogger("redis").Info("yinzhou--EnQeenTradeManageMessage:" + value);
//从头部插入
GetClient().LPush("TradeManageMessage", value);
GetClient().LPush("TradeManageMessage:MQ", value);
return true;
}
catch (Exception e)
{
LoggerManager.GetLogger("redis").Error($"EnQeenTradeManageMessage:key=TradeManageMessage:MQ,value={value},错误信息:{e}");
return false;
}
}
/// <summary>
/// TradeManageMessage 和 TradeManageMessage:MQ队列
/// </summary>
/// <returns></returns>
public static bool EnQeenTradeManageMessage<T>(T value)
{
try
{
//从头部插入
GetClient().LPush("TradeManageMessage", value);
GetClient().LPush("TradeManageMessage:MQ", value);
return true;
}
catch (Exception e)
{
LoggerManager.GetLogger("redis").Error($"EnQeenTradeManageMessage:key=TradeManageMessage:MQ,value={value},错误信息:{e}");
return false;
}
}
public static bool EnQueen(string key, string value)
{
try
{
//从头部插入
GetClient().LPush(key, value);
return true;
}
catch (Exception e)
{
LoggerManager.GetLogger("redis").Error($"EnQueen:key={key},value={value},错误信息:{e}");
return false;
}
}
public static string DeQueen(string key)
{
string result = "";
try
{
//从尾部取值
result = GetClient().RPop(key);
return result;
}
catch (Exception e)
{
LoggerManager.GetLogger("redis").Error($"DeQueen:key={key},错误信息:{e}");
return result;
}
}
//redis订阅模式
public static void Sub(string key, Action<string> action)
{
GetClient().Subscribe((key, msg => action(msg.Body)));
}
public static string[] DeQueenAll(string key)
{
string[] result = { };
try
{
long len = GetClient().LLen(key);
//取出指定数量数据
result = GetClient().LRange(key, 0, len - 1);
//删除指定数据
bool res = GetClient().LTrim(key, len, -1);
return result;
}
catch (Exception e)
{
LoggerManager.GetLogger("redis").Error($"DeQueen:key={key},错误信息:{e}");
return result;
}
}
public static bool EnQueen<T>(string key, T value)
{
try
{
//从头部插入
long len = GetClient().LPush(key, value);
if (len > 0)
return true;
else
return false;
}
catch (Exception e)
{
LoggerManager.GetLogger("redis").Error($"EnQueenObj:key={key},value={value},错误信息:{e}");
return false;
}
}
public static T DeQueen<T>(string key)
{
T result = default(T);
try
{
//从尾部取值
result = GetClient().RPop<T>(key);
return result;
}
catch (Exception e)
{
LoggerManager.GetLogger("redis").Error($"DeQueen:key={key},错误信息:{e}");
return result;
}
}
/// <summary>
/// 设置hash值
/// </summary>
/// <param name="key"></param>
/// <param name="field"></param>
/// <param name="value"></param>
/// <returns></returns>
public static bool SetHash(string key, string field, string value)
{
try
{
GetClient().HSet(key, field, value);
return true;
}
catch (Exception e)
{
LoggerManager.GetLogger("redis").Error($"SetHash:key={key},value={value},错误信息:{e}");
return false;
}
}
/// <summary>
/// 根据表名键名获取hash值
/// </summary>
/// <param name="key">表名</param>
/// <param name="field">键名</param>
/// <returns></returns>
public static string GetHash(string key, string field)
{
string result = "";
try
{
result = GetClient().HGet(key, field);
return result;
}
catch (Exception e)
{
LoggerManager.GetLogger("redis").Error($"GetHash:key={key},错误信息:{e}");
return result;
}
}
/// <summary>
/// 获取指定key中所有字段
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
public static Dictionary<string, string> GetHashAll(string key)
{
try
{
var result = GetClient().HGetAll(key);
return result;
}
catch (Exception e)
{
LoggerManager.GetLogger("redis").Error($"GetHash:key={key},错误信息:{e}");
return new Dictionary<string, string>();
}
}
/// <summary>
/// 根据表名键名删除hash值
/// </summary>
/// <param name="key">表名</param>
/// <param name="field">键名</param>
/// <returns></returns>
public static long DeleteHash(string key, string field)
{
long result = 0;
try
{
result = GetClient().HDel(key, field);
return result;
}
catch (Exception e)
{
LoggerManager.GetLogger("redis").Error($"GetHash:key={key}", e);
throw new Exception($"redis error:DeleteHash: key ={ key },错误信息:{e}");
}
}
// <summary>
/// 保存单个key value
/// </summary>
/// <param name="key">Redis Key</param>
/// <param name="value">保存的值</param>
/// <param name="expiry">过期时间</param>
/// <returns></returns>
public static async Task<bool> StringSetAsync<T>(string key, T value, int expiry = -1)
{
try
{
string json = ConvertJson(value);
var result = await GetClient().SetAsync(key, json, expiry);
return result;
}
catch (Exception e)
{
LoggerManager.GetLogger("redis").Error($"StringSetAsync:key={key}", e);
throw new Exception($"redis error:StringSetAsync: key ={ key },错误信息:{e}");
}
}
/// <summary>
/// 保存一个对象
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="key"></param>
/// <param name="obj"></param>
/// <param name="expiry"></param>
/// <returns></returns>
public static bool StringSet<T>(string key, T obj, int expiry = -1)
{
try
{
string json = ConvertJson(obj);
var result = GetClient().Set(key, json, expiry);
return result;
}
catch (Exception e)
{
LoggerManager.GetLogger("redis").Error($"StringSet:key={key},错误信息:{e}");
throw new Exception($"redis error:StringSet: key ={ key },错误信息:{e}");
}
}
/// <summary>
/// 获取单个key的值
/// </summary>
/// <param name="key">Redis Key</param>
/// <returns></returns>
public static async Task<string> StringGetAsync(string key)
{
try
{
var result = await GetClient().GetAsync(key);
return result;
}
catch (Exception e)
{
LoggerManager.GetLogger("redis").Error($"StringGetAsync:key={key},错误信息:{e}");
throw new Exception($"redis error:StringGetAsync: key ={ key },错误信息:{e}");
}
}
public static string StringGet(string key)
{
try
{
var result = GetClient().Get(key);
return result;
}
catch (Exception e)
{
LoggerManager.GetLogger("redis").Error($"StringGet:key={key},错误信息:{e}");
throw new Exception($"redis error:StringGet: key ={ key },错误信息:{e}");
}
}
public static async Task<T> StringGetAsync<T>(string key)
{
try
{
var result = await GetClient().GetAsync<T>(key);
return result;
}
catch (Exception e)
{
LoggerManager.GetLogger("redis").Error($"StringGetAsync:key={key},错误信息:{e}");
throw new Exception($"redis error:StringGetAsync: key ={ key },错误信息:{e}");
}
}
public static T StringGet<T>(string key)
{
try
{
var result = GetClient().Get<T>(key);
return result;
}
catch (Exception e)
{
LoggerManager.GetLogger("redis").Error($"StringGet:key={key},错误信息:{e}");
throw new Exception($"redis error:StringGet: key ={ key },错误信息:{e}");
}
}
/// <summary>
/// 删除单个key
/// </summary>
/// <param name="key">redis key</param>
/// <returns>是否删除成功</returns>
public static bool KeyDelete(string key)
{
try
{
var result = GetClient().Del(key);
return true;
}
catch (Exception e)
{
LoggerManager.GetLogger("redis").Error($"StringGet:key={key},错误信息:{e}");
throw new Exception($"redis error:KeyDelete: key ={ key },错误信息:{e}");
}
}
public static async Task<bool> KeyDeleteAsync(string key)
{
try
{
var result = await GetClient().DelAsync(key);
return true;
}
catch (Exception e)
{
LoggerManager.GetLogger("redis").Error($"StringGet:key={key},错误信息:{e}");
throw new Exception($"redis error:KeyDeleteAsync: key ={ key },错误信息:{e}");
}
}
/// <summary>
/// 判断key是否存储
/// </summary>
/// <param name="key">redis key</param>
/// <returns></returns>
public static bool KeyExists(string key)
{
return GetClient().Exists(key);
}
public static async Task<bool> KeyExistsAsync(string key)
{
return await GetClient().ExistsAsync(key);
}
/// <summary>
/// 获取list的redis
/// </summary>
/// <param name="orgid"></param>
/// <returns></returns>
public static Dictionary<string, string> GetListKeys(Guid orgid)
{
return GetClient().HGetAll("opt_list_" + orgid);
}
/// <summary>
/// 删除list中的某张表数据
/// </summary>
/// <param name="orgid"></param>
/// <param name="name"></param>
/// <returns></returns>
public static bool DeleteListKeys(Guid orgid, string name)
{
if (GetClient().HExists("opt_list_" + orgid, name))
{
GetClient().HDel("opt_list_" + orgid, name);
}
return true;
}
/// <summary>
/// 是否存在
/// </summary>
/// <param name="orgid"></param>
/// <param name="name"></param>
/// <returns></returns>
public static bool ExistsListKeys(Guid orgid, string name)
{
return GetClient().HExists("opt_list_" + orgid, name);
}
/// <summary>
/// 获取list中表的rediskey
/// </summary>
/// <param name="orgid"></param>
/// <param name="name"></param>
/// <returns></returns>
public static string GetListKey(Guid orgid, string name)
{
return GetClient().HGet("opt_list_" + orgid, name);
}
//private object deleteCache( Method method, Object[] args)
//{
// object flag = false;
// String fieldkey = parseKey(method, args);
// try
// {
// if (fieldkey.equals(""))
// {
// cacheClient.del(cache.key());
// }
// else
// {
// cacheClient.hdel(cache.key(), fieldkey);
// }
// flag = true;
// }
// catch (Exception e)
// {
// //System.out.println(e.getMessage());
// flag = false;
// }
// return flag;
//}
/**
* field
* @param key
* @param method
* @param args
* @return
* @throws Exception
*/
// public string parseKey(Method method, Object[] args)
// {
// string fieldKey = "";
// for (int i = 0; i < method.getParameters().length; i++)
// {
// Parameter p = method.getParameters()[i];
// FieldAnnotation f = p.getAnnotation(FieldAnnotation.class);
// if(f!=null) {
// fieldKey+=args[i].toString()+":";
// }else {
// FieldOnlyKeyAnnotation fo = p.getAnnotation(FieldOnlyKeyAnnotation.class);
// if(fo != null) {
// fieldKey+=args[i].toString();
//}
// }
// }
// return fieldKey;
// }
}
}

View File

@ -0,0 +1,175 @@
using StackExchange.Redis;
using System;
using System.Collections.Concurrent;
using System.Threading;
namespace APT.Infrastructure.Api
{
public class RedisConfig
{
//系统自定义Key前缀
public static string SysCustomKey = "";
//"127.0.0.1:6379,allowadmin=true
private static string RedisConnectionString = "192.168.0.167:6340,allowadmin=true";
private static string RedisPwd = "redis123";
private static readonly ConcurrentDictionary<string, ConnectionMultiplexer> ConnectionCache = new ConcurrentDictionary<string, ConnectionMultiplexer>();
private static readonly object Locker = new object();
private static ConnectionMultiplexer _instance;
static RedisConfig()
{
RedisOption option = ConfigurationManager.RedisOption;
if (option != null)
{
SysCustomKey = option.RedisPrefixKey;
RedisConnectionString = option.RedisConnectionString;
RedisPwd = option.RedisConnectionPwd;
}
else
{
throw new Exception($"未加载redis.json文件");
}
}
/// <summary>
/// 单例获取
/// </summary>
public static ConnectionMultiplexer Instance
{
get
{
if (_instance == null)
{
lock (Locker)
{
if (_instance == null || !_instance.IsConnected)
{
try
{
_instance = GetManager();
}
catch (Exception ex)
{
throw new Exception("初始化Redis缓存错误," + ex.Message);
}
}
}
}
return _instance;
}
}
/// <summary>
/// 缓存获取
/// </summary>
/// <param name="connectionString"></param>
/// <returns></returns>
public static ConnectionMultiplexer GetConnectionMultiplexer(string connectionString)
{
if (!ConnectionCache.ContainsKey(connectionString))
{
ConnectionCache[connectionString] = GetManager(connectionString);
}
return ConnectionCache[connectionString];
}
/// <summary>
///
/// </summary>
/// <param name="connectionString"></param>
/// <returns></returns>
private static ConnectionMultiplexer GetManager(string connectionString = null)
{
connectionString = connectionString ?? RedisConnectionString;
var options = ConfigurationOptions.Parse(connectionString);
//options.ClientName = "root";
//options.AbortOnConnectFail = false;
options.Password = RedisPwd;
options.ConnectTimeout = 15000;
options.SyncTimeout = 5000;
options.ResponseTimeout = 15000;
options.AbortOnConnectFail = false;
options.AllowAdmin = true;
var connect = ConnectionMultiplexer.Connect(options);
//注册如下事件
connect.ConnectionFailed += MuxerConnectionFailed;
connect.ConnectionRestored += MuxerConnectionRestored;
connect.ErrorMessage += MuxerErrorMessage;
connect.ConfigurationChanged += MuxerConfigurationChanged;
connect.HashSlotMoved += MuxerHashSlotMoved;
connect.InternalError += MuxerInternalError;
return connect;
}
#region
/// <summary>
/// 配置更改时
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private static void MuxerConfigurationChanged(object sender, EndPointEventArgs e)
{
System.Console.WriteLine("Configuration changed: " + e.EndPoint);
}
/// <summary>
/// 发生错误时
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private static void MuxerErrorMessage(object sender, RedisErrorEventArgs e)
{
System.Console.WriteLine("ErrorMessage: " + e.Message);
}
/// <summary>
/// 重新建立连接之前的错误
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private static void MuxerConnectionRestored(object sender, ConnectionFailedEventArgs e)
{
System.Console.WriteLine("ConnectionRestored: " + e.EndPoint);
}
/// <summary>
/// 连接失败 如果重新连接成功你将不会收到这个通知
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private static void MuxerConnectionFailed(object sender, ConnectionFailedEventArgs e)
{
System.Console.WriteLine("重新连接Endpoint failed: " + e.EndPoint + ", " + e.FailureType + (e.Exception == null ? "" : (", " + e.Exception.Message)));
}
/// <summary>
/// 更改集群
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private static void MuxerHashSlotMoved(object sender, HashSlotMovedEventArgs e)
{
System.Console.WriteLine("HashSlotMoved:NewEndPoint" + e.NewEndPoint + ", OldEndPoint" + e.OldEndPoint);
}
/// <summary>
/// redis类库错误
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private static void MuxerInternalError(object sender, InternalErrorEventArgs e)
{
System.Console.WriteLine("InternalError:Message" + e.Exception.Message);
}
#endregion
}
}

View File

@ -0,0 +1,42 @@
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Configuration.Json;
using Microsoft.Extensions.FileProviders;
using System;
using System.Collections.Generic;
using System.Text;
namespace APT.Infrastructure.Api
{
public static class RedisConfigurationExtensions
{
public static IConfigurationBuilder AddRedisFile(this IConfigurationBuilder builder, string path)
{
return AddRedisFile(builder, provider: null, path: path, optional: false, reloadOnChange: false);
}
public static IConfigurationBuilder AddRedisFile(this IConfigurationBuilder builder, string path, bool optional)
{
return AddRedisFile(builder, provider: null, path: path, optional: optional, reloadOnChange: false);
}
public static IConfigurationBuilder AddRedisFile(this IConfigurationBuilder builder, string path, bool optional, bool reloadOnChange)
{
return AddRedisFile(builder, provider: null, path: path, optional: optional, reloadOnChange: reloadOnChange);
}
public static IConfigurationBuilder AddRedisFile(this IConfigurationBuilder builder, IFileProvider provider, string path, bool optional, bool reloadOnChange)
{
var source = new JsonConfigurationSource()
{
FileProvider = provider,
Path = path,
Optional = optional,
ReloadOnChange = reloadOnChange
};
builder.Add(source);
//AppConfig.Configuration = builder.Build();
//AppConfig.RedisOption = AppConfig.Configuration.GetSection("RedisConfig").Get<RedisOption>();
return builder;
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,24 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace APT.Infrastructure.Api
{
public class RedisOption
{
/// <summary>
/// Redis服务器
/// </summary>
public string RedisConnectionString { get; set; }
/// <summary>
/// Redis密码
/// </summary>
public string RedisConnectionPwd { get; set; }
/// <summary>
/// 系统自定义Key前缀
/// </summary>
public string RedisPrefixKey { get; set; }
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,803 @@
using APT.Infrastructure.Core;
using Microsoft.Data.SqlClient;
using Microsoft.EntityFrameworkCore.Storage;
//using MySql.Data.MySqlClient;
//using Npgsql;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Data.Common;
using System.Linq;
using System.Text;
namespace APT.Infrastructure.Api
{
/// <summary>
/// 领域服务基类
/// </summary>
/// <typeparam name="TRepository">领域实体仓储对象</typeparam>
/// <typeparam name="TEntity">领域实体</typeparam>
/// <typeparam name="TKey">领域实体主键类型</typeparam>
public class DomainServiceBase : IDomainService
{
private IUnitOfWork _unitOfWork;
public DomainServiceBase(IUnitOfWork unitOfWork)
{
_unitOfWork = unitOfWork;
}
#region properties
protected IUnitOfWork UnitOfWork { get { return _unitOfWork; } }
#endregion
#region methods
public void ThrowError(string code, params object[] objs)
{
LibMessageUtils.ThrowError(code, objs);
}
/// <summary>
/// 对数据库执行给定的 DDL/DML 命令。
/// </summary>
/// <param name="sql">命令字符串</param>
/// <param name="parameters">参数</param>
/// <returns>受影响的行数</returns>
public int ExecuteSqlCommand(string sql, params object[] parameters)
{
return this.UnitOfWork.ExecuteSqlCommand(sql, parameters);
}
/// <summary>
/// 对数据库执行给定的 DDL/DML 命令。
/// </summary>
/// <param name="transactionalBehavior">事务行为</param>
/// <param name="sql">命令字符串</param>
/// <param name="parameters">参数</param>
/// <returns>受影响的行数</returns>
public int ExecuteSqlCommand(TransactionalBehavior transactionalBehavior, string sql, params object[] parameters)
{
return this.UnitOfWork.ExecuteSqlCommand(transactionalBehavior, sql, parameters);
}
/// <summary>
/// 对数据库执行给定的 DDL/DML 命令返回reader。
/// </summary>
/// <param name="sql">命令字符串</param>
/// <param name="readerAction">reader委托</param>
public void ExecuteReader(string sql, ReaderColumn[] readerColumns, Action<DbDataReader> readerAction)
{
this.UnitOfWork.ExecuteReader(sql, readerColumns, readerAction);
}
/// <summary>
/// 对数据库执行给定的 DDL/DML 命令返回reader。
/// </summary>
/// <param name="sql">命令字符串</param>
/// <param name="parameters">参数</param>
/// <param name="readerAction">reader委托</param>
public void ExecuteReader(string sql, ReaderColumn[] readerColumns, DbParameter[] parameters, Action<DbDataReader> readerAction)
{
this.UnitOfWork.ExecuteReader(sql, readerColumns,parameters, readerAction);
}
/// <summary>
/// 对数据库执行给定的 DDL/DML 命令返回reader。
/// </summary>
/// <param name="commandType">命令类型</param>
/// <param name="sql">命令字符串</param>
/// <param name="parameters">参数</param>
/// <param name="readerAction">reader委托</param>
public void ExecuteReader(CommandType commandType, string sql, ReaderColumn[] readerColumns, DbParameter[] parameters, Action<DbDataReader> readerAction)
{
this.UnitOfWork.ExecuteReader(commandType, sql,readerColumns, parameters, readerAction);
}
/// <summary>
/// 创建一个原始 SQL 查询,该查询将返回给定泛型类型的元素。
/// </summary>
/// <typeparam name="TElement">查询所返回对象的类型</typeparam>
/// <param name="sql">SQL 查询字符串</param>
/// <param name="parameters">要应用于 SQL 查询字符串的参数</param>
/// <returns></returns>
//public IEnumerable<TElement> SqlQuery<TElement>(string sql, params object[] parameters)
//{
// return this.UnitOfWork.SqlQuery<TElement>(sql, parameters);
//}
/// <summary>
/// 创建一个原始 SQL 查询,该查询将返回给定类型的元素。
/// </summary>
/// <param name="elementType">查询所返回对象的类型</param>
/// <param name="sql">SQL 查询字符串</param>
/// <param name="parameters">要应用于 SQL 查询字符串的参数</param>
/// <returns></returns>
public IEnumerable SqlQuery(Type elementType, string sql, ReaderColumn[] readerColumns, params Object[] parameters)
{
return this.UnitOfWork.SqlQuery(elementType, sql, readerColumns, parameters);
}
/// <summary>
/// 获取数据库连接对象
/// </summary>
/// <param name="dataBaseType">数据库类型</param>
/// <param name="connString">连接字符串</param>
public DbConnection InitDbConnection(DataBaseType dataBaseType, string connString)
{
var conn = GetDbConnection(dataBaseType, connString);
if (conn == null)
throw new Exception("连接失败");
return conn;
}
/// <summary>
/// 对数据库执行给定的 DDL/DML 命令。
/// </summary>
/// <param name="commandType">命令类型</param>
/// <param name="sql">命令字符串</param>
/// <param name="parameters">参数</param>
/// <returns></returns>
public int ExecuteNonQuery(CommandType commandType, string sql, ReaderColumn[] readerColumns, DbParameter[] parameters)
{
return this.UnitOfWork.ExecuteNonQuery(commandType, sql, readerColumns, parameters);
}
/// <summary>
/// 根据数据库连接对数据库执行给定的 DDL/DML 命令。
/// </summary>
/// <param name="dataBaseType">数据库类型</param>
/// <param name="connString">连接字符串</param>
/// <param name="commandType">sql 类型</param>
/// <param name="sql">sql</param>
/// <param name="dbParameters">参数</param>
public void ExecuteNonQueryByConn(DataBaseType dataBaseType, string connString, CommandType commandType, string sql, DbParameter[] dbParameters)
{
var conn = GetDbConnection(dataBaseType, connString);
ExecuteNonQueryByConn(dataBaseType, conn, commandType, sql, dbParameters);
}
public void ExecuteNonQueryByConn(DataBaseType dataBaseType, DbConnection conn, CommandType commandType, string sql, DbParameter[] dbParameters, bool close = true)
{
try
{
if (conn.State == ConnectionState.Closed)
conn.Open();
if (conn != null)
{
var cmd = GetDbCommand(dataBaseType, conn, sql, dbParameters);
if (cmd != null)
{
cmd.CommandType = commandType;
cmd.ExecuteNonQuery();
}
}
}
finally
{
if (close && conn != null)
conn.Dispose();
}
}
/// <summary>
/// 根据数据库连接对数据库执行给定的 DDL/DML 命令获取Reader。
/// </summary>
/// <param name="dataBaseType">数据库类型</param>
/// <param name="connString">连接字符串</param>
/// <param name="commandType">sql 类型</param>
/// <param name="sql">sql</param>
/// <param name="dbParameters">参数</param>
/// <param name="readerAction">执行委托</param>
public void ExecuteReaderByConn(DataBaseType dataBaseType, string connString, CommandType commandType,
string sql, DbParameter[] dbParameters, Action<DbDataReader> readerAction)
{
var conn = GetDbConnection(dataBaseType, connString);
try
{
conn.Open();
if (conn != null)
{
var cmd = GetDbCommand(dataBaseType, conn, sql, dbParameters);
if (cmd != null)
{
cmd.CommandType = commandType;
using (var reader = cmd.ExecuteReader())
{
if (readerAction != null)
readerAction(reader);
}
}
}
}
finally
{
if (conn != null)
conn.Dispose();
}
}
/// <summary>
/// 执行查询,并返回查询所返回的结果集中第一行的第一列。 所有其他的列和行将被忽略。
/// </summary>
/// <param name="dataBaseType">数据库类型</param>
/// <param name="connString">连接字符串</param>
/// <param name="commandType">sql 类型</param>
/// <param name="sql">sql</param>
/// <param name="dbParameters">参数</param>
public object ExecuteScalarByConn(DataBaseType dataBaseType, string connString, CommandType commandType, string sql, DbParameter[] dbParameters)
{
var conn = GetDbConnection(dataBaseType, connString);
try
{
conn.Open();
if (conn != null)
{
var cmd = GetDbCommand(dataBaseType, conn, sql, dbParameters);
if (cmd != null)
{
cmd.CommandType = commandType;
var ret = cmd.ExecuteScalar();
return ret;
}
}
}
finally
{
if (conn != null)
conn.Dispose();
}
return null;
}
/// <summary>
/// 执行查询,并返回查询所返回的结果集中第一行的第一列。 所有其他的列和行将被忽略。
/// </summary>
/// <param name="dataBaseType">数据库类型</param>
/// <param name="conn">数据库连接对象</param>
/// <param name="commandType">sql 类型</param>
/// <param name="sql">sql</param>
/// <param name="close">是否自动关闭连接</param>
/// <param name="dbParameters">参数</param>
public object ExecuteScalarByConn(DataBaseType dataBaseType, DbConnection conn, CommandType commandType,
string sql, bool close = true, params DbParameter[] dbParameters)
{
//var conn = GetDbConnection(dataBaseType, connString);
if (conn == null)
throw new Exception("数据库连接对象不能为空");
try
{
if (conn.State == ConnectionState.Closed)
conn.Open();
if (conn != null)
{
var cmd = GetDbCommand(dataBaseType, conn, sql, dbParameters);
if (cmd != null)
{
cmd.CommandType = commandType;
var ret = cmd.ExecuteScalar();
return ret;
}
}
}
finally
{
if (close)
{
if (conn != null)
conn.Dispose();
}
}
return null;
}
/// <summary>
/// 根据数据库连接对数据库执行给定的 DDL/DML 命令获取Reader。
/// </summary>
/// <param name="dataBaseType">数据库类型</param>
/// <param name="conn">连接对象</param>
/// <param name="commandType">指令类型</param>
/// <param name="sql">SQL语句</param>
/// <param name="dbParameters">参数</param>
/// <param name="readerAction">委托</param>
/// <param name="close">是否自动关闭连接</param>
public void ExecuteReaderByConn(DataBaseType dataBaseType, DbConnection conn, CommandType commandType,
string sql, DbParameter[] dbParameters, Action<DbDataReader> readerAction, bool close = true)
{
//var conn = GetDbConnection(dataBaseType, connString);
try
{
if (conn.State == ConnectionState.Closed)
conn.Open();
if (conn != null)
{
var cmd = GetDbCommand(dataBaseType, conn, sql, dbParameters);
if (cmd != null)
{
cmd.CommandType = commandType;
using (var reader = cmd.ExecuteReader())
{
if (readerAction != null)
readerAction(reader);
}
}
}
}
finally
{
if (close)
{
if (conn != null)
conn.Dispose();
}
}
}
/// <summary>
/// 根据数据库连接对数据库执行给定的 DDL/DML 命令获取Reader。
/// </summary>
/// <param name="dataBaseType">数据库类型</param>
/// <param name="connString">连接字符串</param>
/// <param name="commandType">sql 类型</param>
/// <param name="sql">sql</param>
/// <param name="dbParameters">参数</param>
/// <param name="pageIndex">分页索引 从1开始</param>
/// <param name="pageLimit">每页条数 必填</param>
/// <param name="readerAction">执行委托</param>
public void ExecuteReaderPageByConn(DataBaseType dataBaseType, string connString, CommandType commandType,
string sql, DbParameter[] dbParameters, int pageIndex, int pageLimit, Action<DbDataReader> readerAction)
{
if (pageLimit == 0)
throw new Exception("请填写每页条数");
if (pageIndex <= 0)
pageIndex = 1;
int start = (pageIndex - 1) * pageLimit;
int end = pageIndex * pageLimit;
if (dataBaseType == DataBaseType.Oracle)
{
sql = string.Format(@"SELECT* FROM(SELECT A.*, ROWNUM RN FROM({0}) A WHERE ROWNUM <= {2}) WHERE RN >= {1}", sql, start, end);
}
else if (dataBaseType == DataBaseType.Postgresql)
{
sql = $"{sql} LIMIT {pageLimit} OFFSET {start}";
}
else
{
throw new Exception("不支持的数据库类型");
}
var conn = GetDbConnection(dataBaseType, connString);
try
{
conn.Open();
if (conn != null)
{
var cmd = GetDbCommand(dataBaseType, conn, sql, dbParameters);
if (cmd != null)
{
cmd.CommandType = commandType;
using (var reader = cmd.ExecuteReader())
{
if (readerAction != null)
readerAction(reader);
}
}
}
}
finally
{
if (conn != null)
conn.Dispose();
}
}
/// <summary>
/// 根据数据库连接对数据库执行给定的 DDL/DML 命令获取Reader。
/// </summary>
/// <param name="dataBaseType">数据库类型</param>
/// <param name="conn">连接对象</param>
/// <param name="commandType">sql 类型</param>
/// <param name="sql">sql</param>
/// <param name="dbParameters">参数</param>
/// <param name="pageIndex">分页索引 从1开始</param>
/// <param name="pageLimit">每页条数 必填</param>
/// <param name="readerAction">执行委托</param>
/// <param name="close">是否自动关闭连接</param>
public void ExecuteReaderPageByConn(DataBaseType dataBaseType, DbConnection conn, CommandType commandType,
string sql, DbParameter[] dbParameters, int pageIndex, int pageLimit, Action<DbDataReader> readerAction
, bool close = true)
{
if (conn == null)
throw new Exception("数据库连接对象不能为空");
if (pageLimit == 0)
throw new Exception("请填写每页条数");
if (pageIndex <= 0)
pageIndex = 1;
int start = (pageIndex - 1) * pageLimit;
int end = pageIndex * pageLimit;
if (dataBaseType == DataBaseType.Oracle)
{
if (pageIndex <= 0)
pageIndex = 1;
sql = string.Format(@"SELECT* FROM(SELECT A.*, ROWNUM RN FROM({0}) A WHERE ROWNUM <= {2}) WHERE RN >= {1}", sql, start, end);
}
else if (dataBaseType == DataBaseType.Postgresql)
{
sql = $"{sql} LIMIT {pageLimit} OFFSET {start}";
}
else
{
throw new Exception("不支持的数据库类型");
}
//var conn = GetDbConnection(dataBaseType, connString);
try
{
if (conn.State == ConnectionState.Closed)
conn.Open();
if (conn != null)
{
var cmd = GetDbCommand(dataBaseType, conn, sql, dbParameters);
if (cmd != null)
{
cmd.CommandType = commandType;
using (var reader = cmd.ExecuteReader())
{
if (readerAction != null)
readerAction(reader);
}
}
}
}
finally
{
if (close)
{
if (conn != null)
conn.Dispose();
}
}
}
/// <summary>
/// 根据数据库连接对数据库执行给定的 DDL/DML 命令获取数据总条数。
/// </summary>
/// <param name="dataBaseType">数据库类型</param>
/// <param name="connString">连接字符串</param>
/// <param name="commandType">sql 类型</param>
/// <param name="sql">sql</param>
/// <param name="dbParameters">参数</param>
/// <returns>数据总条数</returns>
public int GetSqlCountByConn(DataBaseType dataBaseType, string connString, CommandType commandType,
string sql, DbParameter[] dbParameters)
{
if (dataBaseType == DataBaseType.Oracle)
{
sql = string.Format(@"SELECT Max(RN) As SQLCOUNT FROM(SELECT A.*, ROWNUM RN FROM({0}) A )", sql);
}
else if (dataBaseType == DataBaseType.Postgresql)
{
sql = $"SELECT COUNT(1) FROM({sql}) A";
}
else
{
throw new Exception("不支持的数据库类型");
}
int result = 0;
var conn = GetDbConnection(dataBaseType, connString);
try
{
conn.Open();
if (conn != null)
{
var cmd = GetDbCommand(dataBaseType, conn, sql, dbParameters);
if (cmd != null)
{
cmd.CommandType = commandType;
using (var reader = cmd.ExecuteReader())
{
while (reader.Read())
{
object tmp = reader.GetValue(0);
if (tmp != null)
result = Convert.ToInt32(tmp);
}
}
}
}
}
finally
{
if (conn != null)
conn.Dispose();
}
return result;
}
private const string RuleCode_ORACLE_SQL = @"select a.ID,a.serial,b.TAKE_RETAIN_MIN,a.ROW_VERSION from t_pf_code_rule_serial a
inner join T_PF_CODE_RULE b on a.code_type = b.code_type and a.org_id = b.org_id
and b.ENABLE_STATUS = 0
where a.CODE_TYPE = '{0}' and rownum <= '{1}' and (b.IS_IGNORE_DATE = 1 or(b.IS_IGNORE_DATE = 0 and a.DATE_VALUE = '{2}'))
and a.Org_Id = '{3}' and
a.STATUS = 0
order by a.num ";
private const string RuleCode_MYSQL_SQL = @"select a.ID,a.serial,b.TAKE_RETAIN_MIN,a.ROW_VERSION from t_pf_code_rule_serial a
inner join T_PF_CODE_RULE b on a.code_type = b.code_type and a.org_id = b.org_id
and b.ENABLE_STATUS = 0
where a.CODE_TYPE = '{0}' and (b.IS_IGNORE_DATE = 1 or(b.IS_IGNORE_DATE = 0 and a.DATE_VALUE = '{2}'))
and a.Org_Id = '{3}' and
a.STATUS = 0
order by a.num limit {1}";
private const string RuleCode_SQL_SERVER_SQL = @"select top {1} a.ID,a.serial,b.TAKE_RETAIN_MIN,a.ROW_VERSION from t_pf_code_rule_serial a
inner join T_PF_CODE_RULE b on a.code_type = b.code_type and a.org_id = b.org_id
and b.ENABLE_STATUS = 0
where a.CODE_TYPE = '{0}' and (b.IS_IGNORE_DATE = 1 or(b.IS_IGNORE_DATE = 0 and a.DATE_VALUE = '{2}'))
and a.Org_Id = '{3}' and
a.STATUS = 0
order by a.num ";
private const string RuleCode_POSTGRESQL_SQL = @"select a.""ID"",a.""SERIAL"",b.""TAKE_RETAIN_MIN"",a.""ROW_VERSION""
from ""T_PF_CODE_RULE_SERIAL"" a
inner join ""T_PF_CODE_RULE"" b on a.""CODE_TYPE""=b.""CODE_TYPE"" and a.""ORG_ID""=b.""ORG_ID""
and b.""ENABLE_STATUS""=0
where a.""CODE_TYPE""='{0}' and (b.""IS_IGNORE_DATE"" =true or (b.""IS_IGNORE_DATE""=false and a.""DATE_VALUE""='{2}'))
and a.""ORG_ID""='{3}' and
a.""STATUS""='0'
order by a.""NUM"" Limit {1};";
public string GetRuleCodes(CodeRuleParam param)
{
if (param == null || param.Count == 0) return null;
var dataBaseType = this.UnitOfWork.GetDataBaseType();
string orgId = string.Empty;
string codeRuleSql = string.Empty;
string updateSql = string.Empty;
if (param.OrgId.HasValue)
{
switch (dataBaseType)
{
case DataBaseType.Oracle:
{
orgId = BitConverter.ToString(param.OrgId.Value.ToByteArray()).Replace("-", "");
codeRuleSql = RuleCode_ORACLE_SQL;
}
break;
case DataBaseType.MySQL:
{
codeRuleSql = RuleCode_MYSQL_SQL;
orgId = param.OrgId.Value.ToString().ToLower();
}
break;
case DataBaseType.Postgresql:
{
codeRuleSql = RuleCode_POSTGRESQL_SQL;
orgId = param.OrgId.Value.ToString().ToLower();
}
break;
default:
{
codeRuleSql = RuleCode_SQL_SERVER_SQL;
orgId = param.OrgId.Value.ToString().ToUpper();
}
break;
}
}
var conn = GetDbConnection(dataBaseType, this.UnitOfWork.ConnectionString);
try
{
string date = param.Time.ToString("yyyyMMdd");
string sql = string.Format(codeRuleSql, param.CodeType, param.Count, date, orgId);
List<RuleCodeInfo> ruleCodeInfos = new List<RuleCodeInfo>();
this.ExecuteReaderByConn(dataBaseType, conn, CommandType.Text, sql, null, (reader) =>
{
while (reader.Read())
{
RuleCodeInfo info = new RuleCodeInfo();
var obj = reader.GetValue(0);
if (obj != null && obj != DBNull.Value)
{
if (obj is byte[])
{
var blob = obj as byte[];
info.ID = BitConverter.ToString(blob).Replace("-", "");
}
else
{
info.ID = Convert.ToString(obj);
}
}
info.Serial = LibUtils.ToString(reader.GetValue(1));// reader.GetString(0);
info.TaskTimeMin = LibUtils.ToInt(reader.GetValue(2));
info.RowVersion = LibUtils.ToInt(reader.GetValue(3));
ruleCodeInfos.Add(info);
}
}, false);
if (ruleCodeInfos.Count < param.Count)
throw new Exception("流水码[" + param.CodeType + "]不足,请联系系统管理员");
if (param.IsUpdate)
{
List<string> updateSqls = new List<string>();
List<RuleCodeInfo> tempInfos = new List<RuleCodeInfo>();
if (dataBaseType == DataBaseType.Postgresql)
{
StringBuilder updates = new StringBuilder();
foreach (var item in ruleCodeInfos)
updates.Append(string.Format(" ('{0}',{1}),", item.ID, item.RowVersion));
updates.Length--;
updateSqls.Add("create temp table \"T_PF_CODE_RULE_SERIAL_TEMP\" (\"ID\" uuid,\"ROW_VERSION\" integer) ;");
updateSqls.Add(string.Format("insert into \"T_PF_CODE_RULE_SERIAL_TEMP\" values {0}; ", updates.ToString()));
var firstItem = ruleCodeInfos.FirstOrDefault();
var takeTime = DateTime.Now;
var releaseTime = DateTime.Now.AddMinutes(firstItem.TaskTimeMin == 0 ? 20 : firstItem.TaskTimeMin);
var takeTimeStr = dataBaseType == DataBaseType.Oracle ?
("to_date('" + takeTime.ToString("yyyy/MM/dd HH:mm:ss") + "','yyyy-mm-dd hh24-mi-ss')") :
("'" + takeTime.ToString("yyyy-MM-dd HH:mm:ss") + "'");
var releaseTimeStr = dataBaseType == DataBaseType.Oracle ?
("to_date('" + releaseTime.ToString("yyyy/MM/dd HH:mm:ss") + "','yyyy-mm-dd hh24-mi-ss')") :
("'" + releaseTime.ToString("yyyy-MM-dd HH:mm:ss") + "'");
updateSqls.Add(string.Format(@"Update {4}T_PF_CODE_RULE_SERIAL{4} set {4}STATUS{4}='{0}',{4}TAKE_TIME{4}={1},
{4}ROW_VERSION{4}={4}ROW_VERSION{4}+1,
{4}RELEASE_TIME{4}={2} where exists (select 1 from ""T_PF_CODE_RULE_SERIAL_TEMP"" a where a.""ID""= ""T_PF_CODE_RULE_SERIAL"".""ID""
and a.""ROW_VERSION""=""T_PF_CODE_RULE_SERIAL"".""ROW_VERSION"") and {4}STATUS{4}='0';",
1, takeTimeStr, releaseTimeStr, string.Empty, (dataBaseType == DataBaseType.Postgresql ? "\"" : string.Empty)));
}
else if (dataBaseType == DataBaseType.Oracle)
{
//创建临时表
//CREATE GLOBAL TEMPORARY TABLE T_PF_CODE_RULE_SERIAL_TEMP
//(ID RAW(16),ROW_VERSION NUMBER(10))
//ON COMMIT PRESERVE ROWS;
StringBuilder updates = new StringBuilder();
foreach (var item in ruleCodeInfos)
updates.Append(string.Format(" into T_PF_CODE_RULE_SERIAL_TEMP(ID,ROW_VERSION) values ('{0}')", item.ID, item.RowVersion));
updateSqls.Add(string.Format("insert /*+ nologging */ all {0} SELECT 1 FROM DUAL; ", updates.ToString()));
var firstItem = ruleCodeInfos.FirstOrDefault();
var takeTime = DateTime.Now;
var releaseTime = DateTime.Now.AddMinutes(firstItem.TaskTimeMin == 0 ? 20 : firstItem.TaskTimeMin);
var takeTimeStr = "to_date('" + takeTime.ToString("yyyy/MM/dd HH:mm:ss") + "','yyyy-mm-dd hh24-mi-ss')";
var releaseTimeStr = "to_date('" + releaseTime.ToString("yyyy/MM/dd HH:mm:ss") + "','yyyy-mm-dd hh24-mi-ss')";
updateSqls.Add(string.Format(@"Update T_PF_CODE_RULE_SERIAL set STATUS={0},TAKE_TIME={1},RELEASE_TIME={2},ROW_VERSION=ROW_VERSION+1 where exists (select 1 from T_PF_CODE_RULE_SERIAL_TEMP a where a.Id= T_PF_CODE_RULE_SERIAL.Id and a.ROW_VERSION=T_PF_CODE_RULE_SERIAL.ROW_VERSION) and STATUS='0';",
1, takeTimeStr, releaseTimeStr));
}
else
{
foreach (var item in ruleCodeInfos)
{
tempInfos.Add(item);
if (tempInfos.Count >= 100)
{
DoGetUpdateCodeRuleSql(dataBaseType, tempInfos, updateSqls);
tempInfos.Clear();
}
}
DoGetUpdateCodeRuleSql(dataBaseType, tempInfos, updateSqls);
}
StringBuilder sb = new StringBuilder();
if (dataBaseType != DataBaseType.Postgresql)
sb.AppendLine("begin");
foreach (var str in updateSqls)
sb.AppendLine(str);
if (dataBaseType != DataBaseType.Postgresql)
sb.AppendLine("end;");
this.ExecuteNonQueryByConn(dataBaseType, conn, CommandType.Text, sb.ToString(), null, false);
//this.ExecuteNonQuery(CommandType.Text, sb.ToString(), null);
}
return string.Join(",", ruleCodeInfos.Select(t => t.Serial).ToList());
}
finally
{
if (conn != null)
conn.Dispose();
}
}
private void DoGetUpdateCodeRuleSql(DataBaseType dataBaseType, List<RuleCodeInfo> infos, List<string> updateSqls)
{
if (!infos.Any()) return;
StringBuilder stringBuilder = new StringBuilder();
foreach (var item in infos)
{
stringBuilder.Append("'" + item.ID + "'");
stringBuilder.Append(",");
}
stringBuilder.Length--;
var firstItem = infos.FirstOrDefault();
var takeTime = DateTime.Now;
var releaseTime = DateTime.Now.AddMinutes(firstItem.TaskTimeMin == 0 ? 20 : firstItem.TaskTimeMin);
var takeTimeStr = dataBaseType == DataBaseType.Oracle ?
("to_date('" + takeTime.ToString("yyyy/MM/dd HH:mm:ss") + "','yyyy-mm-dd hh24-mi-ss')") :
("'" + takeTime.ToString("yyyy-MM-dd HH:mm:ss") + "'");
var releaseTimeStr = dataBaseType == DataBaseType.Oracle ?
("to_date('" + releaseTime.ToString("yyyy/MM/dd HH:mm:ss") + "','yyyy-mm-dd hh24-mi-ss')") :
("'" + releaseTime.ToString("yyyy-MM-dd HH:mm:ss") + "'");
updateSqls.Add(string.Format(@"Update {4}T_PF_CODE_RULE_SERIAL{4} set {4}STATUS{4}='{0}',{4}TAKE_TIME{4}={1},
{4}ROW_VERSION{4}={4}ROW_VERSION{4}+1,
{4}RELEASE_TIME{4}={2} where {4}ID{4} in ({3}) and {4}STATUS{4}='0';",
1, takeTimeStr, releaseTimeStr, stringBuilder.ToString(), (dataBaseType == DataBaseType.Postgresql ? "\"" : string.Empty)));
}
class RuleCodeInfo
{
public string ID { get; set; }
public string Serial { get; set; }
public int TaskTimeMin { get; set; }
public int RowVersion { get; set; }
}
#endregion
#region
private DbConnection GetDbConnection(DataBaseType dataBaseType, string connString)
{
switch (dataBaseType)
{
//case DataBaseType.Oracle:
// return new OracleConnection(connString);
//case DataBaseType.MySQL:
// return new MySqlConnection(connString);
//case DataBaseType.Postgresql:
// return new NpgsqlConnection(connString);
}
return new SqlConnection(connString);
}
private DbCommand GetDbCommand(DataBaseType dataBaseType, DbConnection conn, string sql, DbParameter[] dbParameters)
{
DbCommand command = null;
switch (dataBaseType)
{
case DataBaseType.Oracle:
//command = new OracleCommand(sql, conn as OracleConnection);
break;
//case DataBaseType.MySQL:
// command = new MySqlCommand(sql, conn as MySqlConnection);
// break;
case DataBaseType.SQL:
command = new SqlCommand(sql, conn as SqlConnection);
break;
case DataBaseType.Postgresql:
//command = new NpgsqlCommand(sql, conn as NpgsqlConnection);
break;
}
if (dbParameters != null && dbParameters.Length > 0)
{
foreach (var item in dbParameters)
{
if (item.Value == null)
item.Value = DBNull.Value;
command.Parameters.Add(item);
}
}
return command;
}
#endregion
}
}

View File

@ -0,0 +1,571 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Threading.Tasks;
using APT.Infrastructure.Core;
namespace APT.Infrastructure.Api
{
/// <summary>
/// 通用接口,可以调用基类方法
/// </summary>
/// <typeparam name="TEntity"></typeparam>
public partial interface ICommonService : IDomainService
{
IUnitOfWork UnitWork();
#region
/// <summary>
/// 查询实体
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="id"></param>
/// <param name="paths"></param>
/// <returns></returns>
T GetEntity<T>(string id, params string[] paths) where T : MesEntityBase, new();
/// <summary>
/// 查询实体
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="id"></param>
/// <param name="paths"></param>
/// <returns></returns>
T GetEntity<T>(Guid id, params string[] paths) where T : MesEntityBase, new();
/// <summary>
/// 查询实体
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="expression"></param>
/// <param name="paths"></param>
/// <returns></returns>
T GetEntity<T>(Expression<Func<T, bool>> expression, params string[] paths) where T : MesEntityBase, new();
/// <summary>
/// 查询实体
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="expression"></param>
/// <param name="paths"></param>
/// <returns></returns>
T GetEntity<T>(Expression<Func<T, bool>> expression, BaseFilter fiter, params string[] paths) where T : MesEntityBase, new();
/// <summary>
/// 查询实体
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="expression"></param>
/// <param name="paths"></param>
/// <returns></returns>
T GetEntity<T>(Expression<Func<T, bool>> expression, BaseFilter fiter, bool isTracking = false, params string[] paths) where T : MesEntityBase, new();
T GetEntityByRedis<T>(string key, Guid orgid)
where T : MesEntityBase, new();
T GetEntityByRedis<T>(Guid key, Guid orgid)
where T : MesEntityBase, new();
List<T> GetEntitiesByRedis<T>(BaseFilter filter) where T : MesEntityBase, new();
List<T> GetEntitiesByGroupRedis<T>(BaseFilter filter, string groupValue) where T : MesEntityBase, new();
List<T> GetEntitiesByRedis<T>(Expression<Func<T, bool>> expression, BaseFilter filter) where T : MesEntityBase, new();
List<T> GetEntitiesTableByRedis<T>(Expression<Func<T, bool>> expression, BaseFilter filter,
params string[] paths) where T : MesEntityBase, new();
List<T> GetEntitiesByRedis<T>(Expression<Func<T, bool>> expression, BaseFilter filter, string groupValue,
params string[] paths) where T : MesEntityBase, new();
PagedResultDto<T> GetOrderPageByRedis<T>(Expression<Func<T, bool>> expression, BasePageFilter pageFilter,
params string[] paths) where T : MesEntityBase, new();
IEnumerable<T> GetEntities<T>(Expression<Func<T, bool>> expression,
params string[] paths) where T : MesEntityBase, new();
IEnumerable<T> GetEntities<T>(Expression<Func<T, bool>> expression,
bool isTracking = false, params string[] paths) where T : MesEntityBase, new();
IEnumerable<T> GetEntities<T>(Expression<Func<T, bool>> expression, BaseFilter filter,
bool isTracking = false, params string[] paths) where T : MesEntityBase, new();
/// <summary>
/// 获取所有数据
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="expression"></param>
/// <param name="filter"></param>
/// <param name="paths"></param>
/// <returns></returns>
IEnumerable<T> GetEntities<T>(Expression<Func<T, bool>> expression, BaseFilter filter, params string[] paths) where T : MesEntityBase, new();
/// <summary>
/// 获取所有数据
/// </summary>
/// <typeparam name="T">类型</typeparam>
/// <param name="orderBy">排序</param>
/// <param name="expression">lambd表达式</param>
/// <param name="filter">过滤器</param>
/// <param name="paths">需要关联查询的数据</param>
/// <returns></returns>
/// <summary>
/// 获取所有数据
/// </summary>
/// <typeparam name="T">类型</typeparam>
/// <param name="orderBy">排序</param>
/// <param name="expression">lambd表达式</param>
/// <param name="filter">过滤器</param>
/// <param name="paths">需要关联查询的数据</param>
/// <returns></returns>
IEnumerable<T> GetOrderEntities<T>(Expression<Func<T, bool>> expression,
BaseFilter filter, Action<IOrderable<T>> orderBy, params string[] paths) where T : MesEntityBase, new();
/// <summary>
/// 获取所有数据
/// </summary>
/// <typeparam name="T">类型</typeparam>
/// <param name="expression">lambd表达式</param>
/// <param name="filter">过滤器</param>
/// <param name="paths">需要关联查询的数据</param>
/// <returns></returns>
IEnumerable<T> GetOrderEntities<T>(Expression<Func<T, bool>> expression, BaseFilter filter, params string[] paths) where T : MesEntityBase, new();
/// <summary>
/// 排序获取数据
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="expression"></param>
/// <param name="sort"></param>
/// <param name="order"></param>
/// <param name="filter"></param>
/// <param name="paths"></param>
/// <returns></returns>
IEnumerable<T> GetOrderEntities<T>(Expression<Func<T, bool>> expression, BaseFilter filter, string sort, string order, params string[] paths) where T : MesEntityBase, new();
/// <summary>
/// 排序获取数据
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="expression"></param>
/// <param name="sort"></param>
/// <param name="order"></param>
/// <param name="filter"></param>
/// <param name="paths"></param>
/// <returns></returns>
IEnumerable<T> GetOrderEntities<T>(Expression<Func<T, bool>> expression, BaseFilter filter, Dictionary<string, string> orders, params string[] paths) where T : MesEntityBase, new();
IEnumerable<T> GetOrderEntities<T>(Expression<Func<T, bool>> expression, BaseFilter filter,
bool isTracking = false, params string[] paths) where T : MesEntityBase, new();
IEnumerable<T> GetOrderEntities<T>(Expression<Func<T, bool>> expression,
BaseFilter filter, Action<IOrderable<T>> orderBy, bool isTracking = false, params string[] paths) where T : MesEntityBase, new();
IEnumerable<T> GetOrderEntities<T>(Expression<Func<T, bool>> expression,
BaseFilter filter, Dictionary<string, string> orders, Action<IOrderable<T>> orderBy, bool isTracking = false, params string[] paths) where T : MesEntityBase, new();
PagedResultDto<T> GetPageEntities<T>(Expression<Func<T, bool>> expression, BasePageFilter pageFilter,
params string[] paths) where T : MesEntityBase, new();
IEnumerable<TreeNode<T>> GetTreeOrderEntities<T>(Expression<Func<T, bool>> expression, BaseFilter filter, bool isTracking,
params string[] paths) where T : TreeEntityBase<T>, new();
PagedResultDto<T> GetOrderPageEntities<T>(Expression<Func<T, bool>> expression, BasePageFilter pageFilter,
params string[] paths) where T : MesEntityBase, new();
PagedResultDto<T> GetOrderPageEntities<T>(Expression<Func<T, bool>> expression, BasePageFilter pageFilter,
int pageSize, int startIndex,
params string[] paths) where T : MesEntityBase, new();
PagedResultDto<T> GetOrderPageEntities<T>(Expression<Func<T, bool>> expression, BasePageFilter pageFilter,
int pageSize, int startIndex, bool isTracking = false,
params string[] paths) where T : MesEntityBase, new();
PagedResultDto<T> GetOrderPageEntities<T>(Expression<Func<T, bool>> expression, BasePageFilter pageFilter,
Dictionary<string, string> orders,
int pageSize, int startIndex, bool isTracking = false,
params string[] paths) where T : MesEntityBase, new();
IEnumerable<T> GetTree<T>(string id, bool containCurrent = true, BaseFilter filter = null,
params string[] paths) where T : TreeEntityBase<T>, new();
PagedResultDto<T> GetOrderPageEntities<T>(Expression<Func<T, bool>> expression, BasePageFilter pageFilter,
Dictionary<string, string> orders,
int pageSize, int startIndex, Action<IOrderable<T>> orderBy, bool isTracking = false,
params string[] paths) where T : MesEntityBase, new();
PagedResultDto<T> GetOrderPageEntities<T>(Expression<Func<T, bool>> expression, BasePageFilter pageFilter, string[] selectField,
params string[] paths) where T : MesEntityBase, new();
//
Task<PagedResultDto<T>> GetOrderPageEntitiesSync<T>(Expression<Func<T, bool>> expression, BasePageFilter pageFilter,
params string[] paths) where T : MesEntityBase, new();
Task<PagedResultDto<T>> GetOrderPageEntitiesSync<T>(Expression<Func<T, bool>> expression, BasePageFilter pageFilter,
int pageSize, int startIndex,
params string[] paths) where T : MesEntityBase, new();
Task<PagedResultDto<T>> GetOrderPageEntitiesSync<T>(Expression<Func<T, bool>> expression, BasePageFilter pageFilter,
int pageSize, int startIndex, bool isTracking = false,
params string[] paths) where T : MesEntityBase, new();
Task<PagedResultDto<T>> GetOrderPageEntitiesSync<T>(Expression<Func<T, bool>> expression, BasePageFilter pageFilter,
Dictionary<string, string> orders,
int pageSize, int startIndex, bool isTracking = false,
params string[] paths) where T : MesEntityBase, new();
Task<PagedResultDto<T>> GetOrderPageEntitiesSync<T>(Expression<Func<T, bool>> expression, BasePageFilter pageFilter,
Dictionary<string, string> orders,
int pageSize, int startIndex, Action<IOrderable<T>> orderBy, bool isTracking = false,
params string[] paths) where T : MesEntityBase, new();
int Count<T>(Expression<Func<T, bool>> expression, BaseFilter filter) where T : MesEntityBase, new();
bool IsAny<T>(Expression<Func<T, bool>> expression, BaseFilter filter) where T : MesEntityBase, new();
int Count<T>(Expression<Func<T, bool>> expression) where T : MesEntityBase, new();
#endregion
/// <summary>
/// 添加实体
/// </summary>
/// <param name="entity"></param>
/// <returns></returns>
bool AddEntity<T>(T entity) where T : MesEntityBase, new();
T AddAndGetEntity<T>(T entity) where T : MesEntityBase, new();
/// <summary>
/// 删除实体
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
bool DeleteEntity<T>(Guid id) where T : MesEntityBase, new();
/// <summary>
/// 删除实体
/// </summary>
/// <param name="expression"></param>
/// <returns></returns>
bool DeleteEntity<T>(Expression<Func<T, bool>> expression) where T : MesEntityBase, new();
/// <summary>
/// 删除实体
/// </summary>
/// <param name="entity"></param>
/// <returns></returns>
bool DeleteEntity<T>(IEnumerable<T> entity) where T : MesEntityBase, new();
/// <summary>
/// 删除实体
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="entity"></param>
/// <returns></returns>
bool DeleteEntity<T>(T entity) where T : MesEntityBase, new();
/// <summary>
/// 逻辑批量删除
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="ids"></param>
/// <returns></returns>
bool BantchDeleteEntity<T>(List<Guid> ids) where T : MesEntityBase, new();
/// 更新实体
/// </summary>
/// <param name="entity"></param>
/// <returns></returns>
bool UpdateEntity<T>(T entity) where T : MesEntityBase, new();
/// <summary>
/// 按字段更新数据
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="entity"></param>
/// <param name="updateField"></param>
/// <returns></returns>
bool UpdateEntity<T>(T entity, params string[] updateField) where T : MesEntityBase, new();
/// <summary>
///根据字段批量更新实体
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="entities"></param>
/// <param name="updateField"></param>
/// <returns></returns>
bool BantchUpdateEntity<T>(IEnumerable<T> entities, params string[] updateField) where T : MesEntityBase, new();
/// <summary>
/// 批量添加实体
/// </summary>
/// <param name="entities">实体集合</param>
/// <returns></returns>
bool BantchAddEntity<T>(IEnumerable<T> entities) where T : MesEntityBase, new();
/// <summary>
/// 批量更新实体
/// </summary>
/// <param name="entities">实体集</param>
/// <returns></returns>
bool BantchUpdateEntity<T>(IEnumerable<T> entities) where T : MesEntityBase, new();
/// <summary>
/// 批量保存实体
/// </summary>
/// <param name="entities">批量保存</param>
/// <returns></returns>
bool BantchSaveEntity<T>(IEnumerable<T> entities) where T : MesEntityBase, new();
#region
/// <summary>
/// 添加实体
/// </summary>
/// <param name="entity"></param>
/// <returns></returns>
bool TreeAddEntity<T>(T entity) where T : TreeEntityBase<T>, new();
T TreeAddAndGetEntity<T>(T entity) where T : MesEntityBase, new();
/// <summary>
/// 删除实体
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
bool TreeDeleteEntity<T>(Guid id) where T : TreeEntityBase<T>, new();
/// <summary>
/// 删除实体
/// </summary>
/// <param name="expression"></param>
/// <returns></returns>
bool TreeDeleteEntity<T>(Expression<Func<T, bool>> expression) where T : TreeEntityBase<T>, new();
/// <summary>
/// 删除实体
/// </summary>
/// <param name="entity"></param>
/// <returns></returns>
bool TreeDeleteEntity<T>(IEnumerable<T> entity) where T : TreeEntityBase<T>, new();
/// <summary>
/// 删除实体
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="entity"></param>
/// <returns></returns>
bool TreeDeleteEntity<T>(T entity) where T : TreeEntityBase<T>, new();
/// <summary>
/// 逻辑批量删除
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="ids"></param>
/// <returns></returns>
bool TreeBantchDeleteEntity<T>(List<Guid> ids) where T : TreeEntityBase<T>, new();
/// <summary>
/// 更新实体
/// </summary>
/// <param name="entity"></param>
/// <returns></returns>
bool TreeUpdateEntity<T>(T entity) where T : TreeEntityBase<T>, new();
/// <summary>
/// 批量添加实体
/// </summary>
/// <param name="entities">实体集合</param>
/// <returns></returns>
bool TreeBantchAddEntity<T>(IEnumerable<T> entities) where T : TreeEntityBase<T>, new();
/// <summary>
/// 批量更新实体
/// </summary>
/// <param name="entities">实体集</param>
/// <returns></returns>
bool TreeBantchUpdateEntity<T>(IEnumerable<T> entities) where T : TreeEntityBase<T>, new();
/// <summary>
/// 批量保存实体
/// </summary>
/// <param name="entities">批量保存</param>
/// <returns></returns>
bool TreeBantchSaveEntity<T>(IEnumerable<T> entities) where T : TreeEntityBase<T>, new();
/// <summary>
/// 批量添加实体
/// </summary>
/// <param name="entities">实体集合</param>
/// <returns></returns>
public bool TreeBantchAddEntityNoCommit<T>(IEnumerable<T> entities) where T : TreeEntityBase<T>, new()
{
return this.BantchAddEntityNoCommit<T>(entities);
}
/// <summary>
/// 添加实体
/// </summary>
/// <param name="entity"></param>
/// <returns></returns>
public bool TreeAddEntityNoCommit<T>(T entity) where T : TreeEntityBase<T>, new()
{
return this.AddEntityNoCommit<T>(entity);
}
public T TreeAddAndGetEntityNoCommit<T>(T entity) where T : MesEntityBase, new()
{
return this.AddAndGetEntityNoCommit<T>(entity);
}
T AddAndGetEntityNoCommit<T>(T entity) where T : MesEntityBase, new();
/// <summary>
/// 删除实体
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
bool TreeDeleteEntityNoCommit<T>(Guid id) where T : TreeEntityBase<T>, new();
/// <summary>
/// 删除实体
/// </summary>
/// <param name="expression"></param>
/// <returns></returns>
bool TreeDeleteEntityNoCommit<T>(Expression<Func<T, bool>> expression) where T : TreeEntityBase<T>, new();
/// <summary>
/// 删除实体
/// </summary>
/// <param name="entity"></param>
/// <returns></returns>
bool TreeDeleteEntityNoCommit<T>(IEnumerable<T> entity) where T : TreeEntityBase<T>, new();
/// <summary>
/// 删除实体
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="entity"></param>
/// <returns></returns>
bool TreeDeleteEntityNoCommit<T>(T entity) where T : TreeEntityBase<T>, new();
/// <summary>
/// 逻辑批量删除
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="ids"></param>
/// <returns></returns>
bool TreeBantchDeleteEntityNoCommit<T>(List<Guid> ids) where T : TreeEntityBase<T>, new();
/// <summary>
/// 更新实体
/// </summary>
/// <param name="entity"></param>
/// <returns></returns>
bool TreeUpdateEntityNoCommit<T>(T entity) where T : TreeEntityBase<T>, new();
/// <summary>
/// 批量更新实体
/// </summary>
/// <param name="entities">实体集</param>
/// <returns></returns>
bool TreeBantchUpdateEntityNoCommit<T>(IEnumerable<T> entities) where T : TreeEntityBase<T>, new();
/// <summary>
/// 批量保存实体
/// </summary>
/// <param name="entities">批量保存</param>
/// <returns></returns>
bool TreeBantchSaveEntityNoCommit<T>(IEnumerable<T> entities) where T : TreeEntityBase<T>, new();
#endregion
T AddAndGetEntity_noneBase<T>(T entity) where T : class;
void AddEntities_noneBase<T>(IEnumerable<T> entities) where T : class;
void UpdateEntities_noneBase<T>(IEnumerable<T> entities) where T : class;
T GetEntity_noneBase<T>(Expression<Func<T, bool>> expressions) where T : class;
List<T> GetEntities_noneBase<T>(Expression<Func<T, bool>> expressions) where T : class;
bool DeleteEntity_noneBase<T>(Expression<Func<T, bool>> expression) where T : class;
bool AddEntityNoCommit<T>(T entity) where T : MesEntityBase, new();
bool BantchAddEntityNoCommit<T>(IEnumerable<T> entities) where T : MesEntityBase, new();
/// <summary>
/// 逻辑删除
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
bool DeleteEntityNoCommit<T>(Guid id) where T : MesEntityBase, new();
/// <summary>
/// 逻辑删除
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
bool DeleteEntityNoCommit<T>(Expression<Func<T, bool>> predicate) where T : MesEntityBase, new();
/// <summary>
/// 逻辑删除
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
bool DeleteEntityNoCommit<T>(IEnumerable<T> entities) where T : MesEntityBase, new();
/// <summary>
/// 逻辑批量删除
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="ids"></param>
/// <returns></returns>
bool BantchDeleteEntityNoCommit<T>(List<Guid> ids) where T : MesEntityBase, new();
/// <summary>
/// 逻辑删除
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
bool DeleteEntityNoCommit<T>(T entity) where T : MesEntityBase, new();
/// <summary>
/// 更新
/// </summary>
/// <param name="entity">实体</param>
/// <returns>是否成功</returns>
bool UpdateEntityNoCommit<T>(T entity) where T : MesEntityBase, new();
/// <summary>
/// 批量更新
/// </summary>
/// <param name="entities">实体集合</param>
/// <returns>是否成功</returns>
bool BantchUpdateEntityNoCommit<T>(IEnumerable<T> entities) where T : MesEntityBase, new();
/// <summary>
/// 更新
/// </summary>
/// <param name="entity">实体</param>
/// <returns>是否成功</returns>
bool UpdateEntityNoCommit<T>(T entity, params string[] updateField) where T : MesEntityBase, new();
/// <summary>
/// 批量更新
/// </summary>
/// <param name="entities">实体集合</param>
/// <returns>是否成功</returns>
bool BantchUpdateEntityNoCommit<T>(IEnumerable<T> entities, params string[] updateField) where T : MesEntityBase, new();
/// <summary>
/// 批量更新(新增和保存一起)速度慢
/// </summary>
/// <param name="entities">实体集合</param>
/// <returns>是否成功</returns>
bool BantchSaveEntityNoCommit<T>(IEnumerable<T> entities) where T : MesEntityBase, new();
/// <summary>
/// 统一提交
/// </summary>
/// <param name="comitAction">数据库方法</param>
void UnifiedCommit(Action comitAction);
#region Db连接提交
void AddEntityByConn<T>(T entity, string conn) where T : MesEntityBase, new();
void UpdateEntitiesByConn<T>(IEnumerable<T> entities, string conn) where T : MesEntityBase, new();
void UpdateEntityByConn<T>(T entity, string conn, params string[] updateField) where T : MesEntityBase, new();
void DeleteEntityByConn<T>(Expression<Func<T, bool>> expression, string conn) where T : MesEntityBase, new();
void DeleteEntityByConn<T>(T entity, string conn) where T : MesEntityBase, new();
void DeleteEntityByConn<T>(Guid id, string conn) where T : MesEntityBase, new();
void DeleteEntitiesByConn<T>(IEnumerable<T> entities, string conn) where T : MesEntityBase, new();
void AddEntitiesByConn<T>(IEnumerable<T> entities, string conn) where T : MesEntityBase, new();
void UpdateEntitiesByConn<T>(IEnumerable<T> entities, string conn, params string[] updateField) where T : MesEntityBase, new();
#endregion
#region
void AddEntityByTenant<T>(T entity, string Tenant) where T : MesEntityBase, new();
void UpdateEntitiesByTenant<T>(IEnumerable<T> entities, string Tenant) where T : MesEntityBase, new();
void UpdateEntityByTenant<T>(T entity, string Tenant, params string[] updateField) where T : MesEntityBase, new();
void DeleteEntityByTenant<T>(Expression<Func<T, bool>> expression, string Tenant) where T : MesEntityBase, new();
void DeleteEntityByTenant<T>(T entity, string Tenant) where T : MesEntityBase, new();
void DeleteEntityByTenant<T>(Guid id, string Tenant) where T : MesEntityBase, new();
void DeleteEntitiesByTenant<T>(IEnumerable<T> entities, string Tenant) where T : MesEntityBase, new();
void AddEntitiesByTenant<T>(IEnumerable<T> entities, string Tenant) where T : MesEntityBase, new();
void UpdateEntitiesByTenant<T>(IEnumerable<T> entities, string Tenant, params string[] updateField) where T : MesEntityBase, new();
#endregion
}
}

View File

@ -0,0 +1,215 @@
using Microsoft.EntityFrameworkCore.Storage;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Data.Common;
using System.Linq.Expressions;
using APT.Infrastructure.Core;
namespace APT.Infrastructure.Api
{
/// <summary>
/// 领域服务接口
/// </summary>
/// <typeparam name="TRepository"></typeparam>
/// <typeparam name="TEntity"></typeparam>
/// <typeparam name="TKey"></typeparam>
public interface IDomainService : IDependInject
{
/// <summary>
/// 对数据库执行给定的 DDL/DML 命令。
/// </summary>
/// <param name="sql">命令字符串</param>
/// <param name="parameters">参数</param>
/// <returns>受影响的行数</returns>
int ExecuteSqlCommand(string sql, params object[] parameters);
/// <summary>
/// 对数据库执行给定的 DDL/DML 命令。
/// </summary>
/// <param name="transactionalBehavior">事务行为</param>
/// <param name="sql">命令字符串</param>
/// <param name="parameters">参数</param>
/// <returns>受影响的行数</returns>
int ExecuteSqlCommand(TransactionalBehavior transactionalBehavior, string sql, params object[] parameters);
/// <summary>
/// 对数据库执行给定的 DDL/DML 命令返回reader。
/// </summary>
/// <param name="sql">命令字符串</param>
/// <param name="readerAction">reader委托</param>
void ExecuteReader(string sql, ReaderColumn[] readerColumns, Action<DbDataReader> readerAction);
/// <summary>
/// 对数据库执行给定的 DDL/DML 命令返回reader。
/// </summary>
/// <param name="sql">命令字符串</param>
/// <param name="parameters">参数</param>
/// <param name="readerAction">reader委托</param>
void ExecuteReader(string sql, ReaderColumn[] readerColumns, DbParameter[] parameters, Action<DbDataReader> readerAction);
/// <summary>
/// 对数据库执行给定的 DDL/DML 命令返回reader。
/// </summary>
/// <param name="commandType">命令类型</param>
/// <param name="sql">命令字符串</param>
/// <param name="parameters">参数</param>
/// <param name="readerAction">reader委托</param>
void ExecuteReader(CommandType commandType, string sql, ReaderColumn[] readerColumns, DbParameter[] parameters, Action<DbDataReader> readerAction);
/// <summary>
/// 创建一个原始 SQL 查询,该查询将返回给定泛型类型的元素。
/// </summary>
/// <typeparam name="TElement">查询所返回对象的类型</typeparam>
/// <param name="sql">SQL 查询字符串</param>
/// <param name="parameters">要应用于 SQL 查询字符串的参数</param>
/// <returns></returns>
//IEnumerable<TElement> SqlQuery<TElement>(string sql, params object[] parameters);
/// <summary>
/// 创建一个原始 SQL 查询,该查询将返回给定类型的元素。
/// </summary>
/// <param name="elementType">查询所返回对象的类型</param>
/// <param name="sql">SQL 查询字符串</param>
/// <param name="parameters">要应用于 SQL 查询字符串的参数</param>
/// <returns></returns>
IEnumerable SqlQuery(Type elementType, string sql, ReaderColumn[] readerColumns, params Object[] parameters);
/// <summary>
/// 对数据库执行给定的 DDL/DML 命令。
/// </summary>
/// <param name="commandType">命令类型</param>
/// <param name="sql">命令字符串</param>
/// <param name="parameters">参数</param>
/// <returns></returns>
int ExecuteNonQuery(CommandType commandType, string sql, ReaderColumn[] readerColumns, DbParameter[] parameters);
/// <summary>
/// 获取数据库连接对象
/// </summary>
/// <param name="dataBaseType">数据库类型</param>
/// <param name="connString">连接字符串</param>
DbConnection InitDbConnection(DataBaseType dataBaseType, string connString);
/// <summary>
/// 执行查询,并返回查询所返回的结果集中第一行的第一列。 所有其他的列和行将被忽略。
/// </summary>
/// <param name="dataBaseType">数据库类型</param>
/// <param name="connString">连接字符串</param>
/// <param name="commandType">sql 类型</param>
/// <param name="sql">sql</param>
/// <param name="dbParameters">参数</param>
object ExecuteScalarByConn(DataBaseType dataBaseType, string connString, CommandType commandType,
string sql, DbParameter[] dbParameters);
/// <summary>
/// 执行查询,并返回查询所返回的结果集中第一行的第一列。 所有其他的列和行将被忽略。
/// </summary>
/// <param name="dataBaseType">数据库类型</param>
/// <param name="conn">数据库连接对象</param>
/// <param name="commandType">sql 类型</param>
/// <param name="sql">sql</param>
/// <param name="dbParameters">参数</param>
/// <param name="close">是否关闭连接</param>
object ExecuteScalarByConn(DataBaseType dataBaseType, DbConnection conn, CommandType commandType,
string sql, bool close = true, params DbParameter[] dbParameters);
/// <summary>
/// 根据数据库连接对数据库执行给定的 DDL/DML 命令获取Reader。
/// </summary>
/// <param name="dataBaseType">数据库类型</param>
/// <param name="conn">连接对象</param>
/// <param name="commandType">sql 类型</param>
/// <param name="sql">sql</param>
/// <param name="dbParameters">参数</param>
/// <param name="pageIndex">分页索引 从1开始</param>
/// <param name="pageLimit">每页条数 必填</param>
/// <param name="readerAction">执行委托</param>
/// <param name="close">是否关闭连接</param>
void ExecuteReaderPageByConn(DataBaseType dataBaseType, DbConnection conn, CommandType commandType,
string sql, DbParameter[] dbParameters, int pageIndex, int pageLimit, Action<DbDataReader> readerAction
, bool close = true);
/// <summary>
/// 根据数据库连接对数据库执行给定的 DDL/DML 命令获取Reader。
/// </summary>
/// <param name="dataBaseType">数据库类型</param>
/// <param name="conn">连接对象</param>
/// <param name="commandType">指令类型</param>
/// <param name="sql">SQL语句</param>
/// <param name="dbParameters">参数</param>
/// <param name="close">是否关闭连接</param>
/// <param name="readerAction">委托</param>
void ExecuteReaderByConn(DataBaseType dataBaseType, DbConnection conn, CommandType commandType, string sql,
DbParameter[] dbParameters, Action<DbDataReader> readerAction, bool close = true);
/// <summary>
/// 根据数据库连接对数据库执行给定的 DDL/DML 命令。
/// </summary>
/// <param name="dataBaseType">数据库类型</param>
/// <param name="connString">连接字符串</param>
/// <param name="commandType">sql 类型</param>
/// <param name="sql">sql</param>
/// <param name="dbParameters">参数</param>
void ExecuteNonQueryByConn(DataBaseType dataBaseType, string connString, CommandType commandType,
string sql, DbParameter[] dbParameters);
/// <summary>
/// 根据数据库连接对数据库执行给定的 DDL/DML 命令。
/// </summary>
/// <param name="dataBaseType">数据库类型</param>
/// <param name="connString">连接字符串</param>
/// <param name="commandType">sql 类型</param>
/// <param name="sql">sql</param>
/// <param name="dbParameters">参数</param>
void ExecuteNonQueryByConn(DataBaseType dataBaseType, DbConnection conn, CommandType commandType, string sql,
DbParameter[] dbParameters, bool close = true);
/// <summary>
/// 根据数据库连接对数据库执行给定的 DDL/DML 命令获取Reader。
/// </summary>
/// <param name="dataBaseType">数据库类型</param>
/// <param name="connString">连接字符串</param>
/// <param name="commandType">sql 类型</param>
/// <param name="sql">sql</param>
/// <param name="dbParameters">参数</param>
/// <param name="readerAction">执行委托</param>
void ExecuteReaderByConn(DataBaseType dataBaseType, string connString, CommandType commandType, string sql,
DbParameter[] dbParameters, Action<DbDataReader> readerAction);
/// <summary>
/// 根据数据库连接对数据库执行给定的 DDL/DML 命令获取Reader。
/// </summary>
/// <param name="dataBaseType">数据库类型</param>
/// <param name="connString">连接字符串</param>
/// <param name="commandType">sql 类型</param>
/// <param name="sql">sql</param>
/// <param name="dbParameters">参数</param>
/// <param name="pageIndex">分页索引 从1开始</param>
/// <param name="pageLimit">每页条数 必填</param>
/// <param name="readerAction">执行委托</param>
void ExecuteReaderPageByConn(DataBaseType dataBaseType, string connString, CommandType commandType,
string sql, DbParameter[] dbParameters, int pageIndex, int pageLimit, Action<DbDataReader> readerAction);
/// <summary>
/// 根据数据库连接对数据库执行给定的 DDL/DML 命令获取数据总条数。
/// </summary>
/// <param name="dataBaseType">数据库类型</param>
/// <param name="connString">连接字符串</param>
/// <param name="commandType">sql 类型</param>
/// <param name="sql">sql</param>
/// <param name="dbParameters">参数</param>
/// <returns>数据总条数</returns>
int GetSqlCountByConn(DataBaseType dataBaseType, string connString, CommandType commandType,
string sql, DbParameter[] dbParameters);
string GetRuleCodes(CodeRuleParam param);
}
}

View File

@ -0,0 +1,114 @@
using System;
using APT.Infrastructure.Core;
namespace APT.Infrastructure.Api
{
[Serializable]
public static class AppContext
{
#region fields
private static SysPermission _sysPermission = new SysPermission();
#endregion
#region ctor.
static AppContext()
{
}
#endregion
#region properties
private static ISessionProvider GetSessionProvider()
{
ISessionProvider sessionProvider =null;
try
{
sessionProvider = ServiceLocator.Instance.GetService<ISessionProvider>();
}
catch { }
if (null == sessionProvider)
{
sessionProvider = new SimpleSession();
}
return sessionProvider;
}
/// <summary>
/// 当前会话
/// </summary>
public static ISession CurrentSession
{
get
{
var session= GetSessionProvider();
return session.GetSession();
}
}
/// <summary>
/// 日志记录器
/// </summary>
public static ILog4netLogger Logger
{
get
{
return LoggerManager.GetLogger();
}
}
/// <summary>
/// 是否使用Redis
/// </summary>
public static bool IsRedis
{
get;set;
}
/// <summary>
/// 微信Token
/// </summary>
public static WeixinToken WxToken { get; set; }
/// <summary>
/// 部门ID
/// </summary>
public static Guid? DepartmentID { get; set; }
/// <summary>
///自定义变量1
/// </summary>
public static string CustomVariable1 { get; set; }
/// <summary>
/// 自定义变量2
/// </summary>
public static string CustomVariable2 { get; set; }
/// <summary>
/// 自定义变量3
/// </summary>
public static string CustomVariable3 { get; set; }
/// <summary>
/// 自定义变量4
/// </summary>
public static string CustomVariable4{ get; set; }
/// <summary>
/// 自定义变量5
/// </summary>
public static string CustomVariable5 { get; set; }
/// <summary>
/// 权限缓存
/// </summary>
public static SysPermission SysPermission
{
get { return _sysPermission; }
set { _sysPermission = value; }
}
#endregion
}
}

View File

@ -0,0 +1,93 @@
using Microsoft.EntityFrameworkCore.Internal;
using Microsoft.Extensions.Configuration;
using System.Linq;
using APT.Infrastructure.Core;
namespace APT.Infrastructure.Api
{
public static class ConfigurationManager
{
public static IConfiguration Configuration
{
get;
private set;
}
public static IConfigurationSection AppSettings { get; set; }
public static IConfigurationSection WexinSettings { get; set; }
public static IConfigurationSection ConnectionStrings { get; set; }
public static IConfigurationSection RedisStrings { get; set; }
public static IConfigurationSection InfluxDbStrings { get; set; }
public static void Register(IConfiguration configuration)
{
Configuration = configuration;
AppSettings = Configuration.GetSection("AppSettings");
RedisStrings = Configuration.GetSection("RedisConfig");
InfluxDbStrings = Configuration.GetSection("InflexdbConfig");
ConnectionStrings = Configuration.GetSection("ConnectionStrings");
WexinSettings = Configuration.GetSection("WexinSettings");
}
public static bool IsRedis
{
get
{
return LibUtils.ToBoolean(RedisStrings["IsRedis"]);
}
}
private static InfluxDbOption _option;
public static InfluxDbOption InfluxDbOption
{
get
{
if (_option == null)
{
_option = new InfluxDbOption();
var s = InfluxDbStrings.GetChildren();
_option.Url = s.Any(i => i.Key == "Url") ? s.FirstOrDefault(i => i.Key == "Url").Value : "";
_option.UserName = s.Any(i => i.Key == "UserName") ? s.FirstOrDefault(i => i.Key == "UserName").Value : "";
_option.PassWord = s.Any(i => i.Key == "PassWord") ? s.FirstOrDefault(i => i.Key == "PassWord").Value : "";
_option.SrcTagDbName = s.Any(i => i.Key == "SrcTagDbName") ? s.FirstOrDefault(i => i.Key == "SrcTagDbName").Value : "";
_option.CorrectWaring = s.Any(i => i.Key == "CorrectWaring") ? s.FirstOrDefault(i => i.Key == "CorrectWaring").Value : "";
_option.LogDbName = s.Any(i => i.Key == "LogDbName") ? s.FirstOrDefault(i => i.Key == "LogDbName").Value : "";
_option.MaxDemandDbName = s.Any(i => i.Key == "MaxDemandDbName") ? s.FirstOrDefault(i => i.Key == "MaxDemandDbName").Value : "";
_option.DosageDbName = s.Any(i => i.Key == "DosageDbName") ? s.FirstOrDefault(i => i.Key == "DosageDbName").Value : "";
_option.EnergyValDbName = s.Any(i => i.Key == "EnergyValDbName") ? s.FirstOrDefault(i => i.Key == "EnergyValDbName").Value : "";
_option.AppOnline = s.Any(i => i.Key == "AppOnline") ? s.FirstOrDefault(i => i.Key == "AppOnline").Value : "";
}
return _option;
}
}
private static RedisOption _redisPotion;
public static RedisOption RedisOption
{
get
{
if (_redisPotion == null)
{
var s = RedisStrings.GetChildren();
var conn = s.Any(i => i.Key == "RedisConnectionString") ? s.FirstOrDefault(i => i.Key == "RedisConnectionString").Value : "";
var pwd = s.Any(i => i.Key == "RedisConnectionPwd") ? s.FirstOrDefault(i => i.Key == "RedisConnectionPwd").Value : "";
var pKey = s.Any(i => i.Key == "RedisPrefixKey") ? s.FirstOrDefault(i => i.Key == "RedisPrefixKey").Value : "";
_redisPotion= new RedisOption()
{
RedisConnectionString = conn,
RedisConnectionPwd = pwd,
RedisPrefixKey = pKey
};
}
return _redisPotion;
}
}
}
}

View File

@ -0,0 +1,22 @@
using Autofac;
using System;
using System.Linq;
using System.Collections.Generic;
using System.Reflection;
using System.Text;
using APT.Infrastructure.Core;
namespace APT.Infrastructure.Api
{
public class DefaultAutofacModuleRegister : Autofac.Module
{
protected override void Load(ContainerBuilder builder)
{
Assembly[] assemblies = System.IO.Directory.GetFiles(
System.AppContext.BaseDirectory, "APT.*.dll").
Select(m => Assembly.LoadFrom(m)).ToArray();
builder.RegisterAssemblyTypes(assemblies).
Where(t => typeof(IDependInject).IsAssignableFrom(t)).AsImplementedInterfaces().
InstancePerLifetimeScope();
}
}
}

View File

@ -0,0 +1,86 @@
using System;
using System.Collections.Generic;
using System.Dynamic;
using System.Linq;
using System.Text;
using Microsoft.Extensions.Configuration;
namespace APT.Infrastructure.Api
{
public static class InfluxDbHelper
{
//private static InfluxDbClient _influxDbClient;
//public static InfluxDbClient InfluxDbClient
//{
// get
// {
// if (_influxDbClient == null)
// {
// _influxDbClient = new InfluxDbClient(ConfigurationManager.InfluxDbOption.Url,
// ConfigurationManager.InfluxDbOption.UserName, ConfigurationManager.InfluxDbOption.PassWord, InfluxDbVersion.Latest);
// }
// return _influxDbClient;
// }
//}
public static string SrcTagDbName
{
get
{
return ConfigurationManager.InfluxDbOption.SrcTagDbName;
}
}
public static string CorrectWaring
{
get
{
return ConfigurationManager.InfluxDbOption.CorrectWaring;
}
}
public static string InfluxLogDbName
{
get
{
return ConfigurationManager.InfluxDbOption.LogDbName;
}
}
public static string MaxDemandDbName
{
get
{
return ConfigurationManager.InfluxDbOption.MaxDemandDbName;
}
}
public static string DosageDbName
{
get
{
return ConfigurationManager.InfluxDbOption.DosageDbName;
}
}
public static string EnergyValDbName
{
get
{
return ConfigurationManager.InfluxDbOption.EnergyValDbName;
}
}
public static string AppOnline
{
get
{
return ConfigurationManager.InfluxDbOption.AppOnline;
}
}
}
}

View File

@ -0,0 +1,89 @@
using System;
using System.Collections.Generic;
using System.Dynamic;
using System.Linq;
using System.Text;
using Microsoft.Extensions.Configuration;
namespace APT.Infrastructure.Api
{
//public static class ConfigurationHelper
//{
// public static IConfigurationRoot Configuration { get; set; }
// private static InfluxDbOption _option;
// public static InfluxDbOption InfluxDbOption
// {
// get
// {
// if (_option == null)
// {
// _option = new InfluxDbOption();
// var s = Configuration.GetSection("InflexdbConfig").GetChildren();
// _option.Url= s.Any(i => i.Key == "Url") ? s.FirstOrDefault(i => i.Key == "Url").Value : "";
// _option.UserName = s.Any(i => i.Key == "UserName") ? s.FirstOrDefault(i => i.Key == "UserName").Value : "";
// _option.PassWord = s.Any(i => i.Key == "PassWord") ? s.FirstOrDefault(i => i.Key == "PassWord").Value : "";
// _option. = s.Any(i => i.Key == "") ? s.FirstOrDefault(i => i.Key == "").Value : "";
// _option.LogDbName = s.Any(i => i.Key == "LogDbName") ? s.FirstOrDefault(i => i.Key == "LogDbName").Value : "";
// _option.DosageDbName = s.Any(i => i.Key == "DosageDbName") ? s.FirstOrDefault(i => i.Key == "DosageDbName").Value : "";
// _option. = s.Any(i => i.Key == "EnergyValDbName") ? s.FirstOrDefault(i => i.Key == "EnergyValDbName").Value : "";
// }
// return _option;
// }
// }
//}
public class InfluxDbOption
{
/// <summary>
/// 地址
/// </summary>
public string Url { get; set; }
/// <summary>
/// 用户
/// </summary>
public string UserName { get; set; }
/// <summary>
/// 密码
/// </summary>
public string PassWord { get; set; }
/// <summary>
/// 源标签历史数据
/// </summary>
public string SrcTagDbName { get; set; }
/// <summary>
/// 纠错数据表
/// </summary>
public string CorrectWaring { get; set; }
/// <summary>
/// Log
/// </summary>
public string LogDbName { get; set; }
/// <summary>
///
/// </summary>
public string MaxDemandDbName { get; set; }
/// <summary>
/// 用量
/// </summary>
public string DosageDbName { get; set; }
/// <summary>
/// 价格
/// </summary>
public string EnergyValDbName { get; set; }
/// <summary>
/// 价格
/// </summary>
public string AppOnline { get; set; }
}
}

View File

@ -0,0 +1,99 @@
using System;
using APT.Infrastructure.Core;
namespace APT.Infrastructure.Api
{
public static class LibMessageUtils
{
public static void AddError(string message)
{
AddMessage(EFMessageType.Error, string.Empty, message);
}
public static void AddError(string code, params object[] objs)
{
AddMessage(EFMessageType.Error, code, GetMessage(code, objs));
}
public static void AddWarning(string message)
{
AddMessage(EFMessageType.Warning, string.Empty, message);
}
public static void AddWarning(string code, params object[] objs)
{
AddMessage(EFMessageType.Warning, code, GetMessage(code, objs));
}
public static void AddInfo(string message)
{
AddMessage(EFMessageType.Info, string.Empty, message);
}
public static void AddInfo(string code, params object[] objs)
{
AddMessage(EFMessageType.Info, code, GetMessage(code, objs));
}
public static string GetMessage(string code,params object[] objs)
{
var foramt = LibMessageFormatManager.Instance.
GetMessageFormat(code, "");//多语言暂不支持
return string.Format(foramt, objs);
}
public static void AddMessage(EFMessageType type, string message)
{
AddMessage(type, string.Empty, message);
}
public static void ThrowError(string code, params object[] objs)
{
string m = GetMessage(code, objs);
throw new CodeException(code, m);
}
//public static void ThrowUpdateRowVersionError(string code, params object[] objs)
//{
// string m = GetMessage(code, objs);
// throw new EFUpdateRowVersionException(code, m);
//}
//public static void ThrowFieldUniqueError(string code, string field, params object[] objs)
//{
// string m = GetMessage(code, objs);
// throw new EFFieldUniqueException(code, field, m);
//}
public static void AddMessage(EFMessageType type, string code, string message)
{
var messageM = GetMessageManage();
if (messageM == null) throw new Exception("ILibMessageManager is null");
messageM.AddMessage(type, code, message);
}
public static void AddMessage(EFApiActionMessage message)
{
var messageM = GetMessageManage();
if (messageM == null) throw new Exception("ILibMessageManager is null");
messageM.AddMessage(message);
}
public static void StoreMessage<T>(EFApiActionResult<T> ret)
{
var messageM = GetMessageManage();
if (messageM == null) return;
messageM.StoreMessage(ret);
}
private static ILibMessageManager GetMessageManage()
{
ILibMessageManager clientFactory = null;
try
{
if (HttpContext.Current != null && HttpContext.Current.RequestServices != null)
clientFactory = (ILibMessageManager)HttpContext.Current.RequestServices.GetService(typeof(ILibMessageManager));
}
catch { }
return clientFactory;
}
}
}

View File

@ -0,0 +1,38 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.1</TargetFramework>
<AssemblyVersion>2.1.2.65</AssemblyVersion>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<Version>2.1.2.65</Version>
<FileVersion>2.1.2.65</FileVersion>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<DocumentationFile>.\APT.Infrastructure.Core.xml</DocumentationFile>
</PropertyGroup>
<ItemGroup>
<Folder Include="EF\" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Castle.Core" Version="4.4.1" />
<PackageReference Include="log4net" Version="2.0.8" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.Abstractions" Version="2.2.0" />
<PackageReference Include="Microsoft.CSharp" Version="4.7.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="5.0.2" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Apt.Infrastructure.Utility\APT.Infrastructure.Utility.csproj" />
</ItemGroup>
<ItemGroup>
<Reference Include="Microsoft.Extensions.Configuration.Abstractions">
<HintPath>C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.extensions.configuration.abstractions\2.2.0\lib\netstandard2.0\Microsoft.Extensions.Configuration.Abstractions.dll</HintPath>
</Reference>
</ItemGroup>
</Project>

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,45 @@
using System;
using System.Linq.Expressions;
namespace APT.Infrastructure.Core
{
/// <summary>
/// 排序规范
/// </summary>
/// <typeparam name="T"></typeparam>
public interface IOrderable<T>
{
/// <summary>
/// 递增
/// </summary>
/// <typeparam name="TKey"></typeparam>
/// <param name="keySelector"></param>
/// <returns></returns>
IOrderable<T> Asc<TKey>(global::System.Linq.Expressions.Expression<Func<T, TKey>> keySelector);
/// <summary>
/// 然后递增
/// </summary>
/// <typeparam name="TKey"></typeparam>
/// <param name="keySelector"></param>
/// <returns></returns>
IOrderable<T> ThenAsc<TKey>(Expression<Func<T, TKey>> keySelector);
/// <summary>
/// 递减
/// </summary>
/// <typeparam name="TKey"></typeparam>
/// <param name="keySelector"></param>
/// <returns></returns>
IOrderable<T> Desc<TKey>(global::System.Linq.Expressions.Expression<Func<T, TKey>> keySelector);
/// <summary>
/// 然后递减
/// </summary>
/// <typeparam name="TKey"></typeparam>
/// <param name="keySelector"></param>
/// <returns></returns>
IOrderable<T> ThenDesc<TKey>(Expression<Func<T, TKey>> keySelector);
/// <summary>
/// 排序后的结果集
/// </summary>
global::System.Linq.IQueryable<T> Queryable { get; }
}
}

View File

@ -0,0 +1,222 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Threading.Tasks;
namespace APT.Infrastructure.Core
{
public interface IRepository : IDependInject
{
#region properties
/// <summary>
/// 获取 当前单元操作对象
/// </summary>
IUnitOfWork UnitOfWork { get; }
#endregion
#region methods
void AddEntity<T>(T entity, bool isSave = true) where T : MesEntityBase, new();
T AddAndGetEntity<T>(T entity, bool isSave = true) where T : MesEntityBase, new();
void AddEntities<T>(IEnumerable<T> entities, bool isSave = true) where T : MesEntityBase, new();
void DeleteEntity<T>(T entity, bool isSave = true) where T : MesEntityBase, new();
void DeleteEntity<T>(Guid key, bool isSave = true) where T : MesEntityBase, new();
void DeleteEntity<T>(Expression<Func<T, bool>> predicate, bool isSave = true) where T : MesEntityBase, new();
void DeleteEntities<T>(IEnumerable<T> entities, bool isSave = true) where T : MesEntityBase, new();
bool UpdateEntity<T>(T entity, bool isSave = true, params string[] updateField) where T : MesEntityBase, new();
void UpdateEntities<T>(IEnumerable<T> entities, bool isSave = true, params string[] updateField) where T : MesEntityBase, new();
void SaveEntities<T>(IEnumerable<T> entities, bool isSave = true) where T : MesEntityBase, new();
T GetEntity<T>(Guid id, params string[] paths)
where T : MesEntityBase, new();
T GetEntity<T>(Expression<Func<T, bool>> expression, BaseFilter filter, params string[] paths)
where T : MesEntityBase, new();
T GetEntity<T>(Expression<Func<T, bool>> expression, BaseFilter filter, bool isTracking = true, params string[] paths)
where T : MesEntityBase, new();
T GetEntityByRedis<T>(string key, Guid orgid) where T : MesEntityBase, new();
Task<List<T>> GetEntitiesByRedis<T>(BaseFilter filter) where T : MesEntityBase, new();
List<T> GetEntitiesByRedis<T>(Expression<Func<T, bool>> expression, BaseFilter filter) where T : MesEntityBase, new();
Task<List<T>> GetEntitiesTableByRedis<T>(Expression<Func<T, bool>> expression, BaseFilter filter,
params string[] paths) where T : MesEntityBase, new();
Task<List<T>> GetEntitiesByRedis<T>(Expression<Func<T, bool>> expression, BaseFilter filter, string groupValue,
params string[] paths) where T : MesEntityBase, new();
PagedResultDto<T> GetOrderPageByRedis<T>(Expression<Func<T, bool>> expression, BasePageFilter pageFilter,
params string[] paths) where T : MesEntityBase, new();
T GetEntityByRedis<T>(Guid key, Guid orgid) where T : MesEntityBase, new();
Task<List<T>> GetEntitiesByGroupRedis<T>(BaseFilter filter, string groupValue) where T : MesEntityBase, new();
IEnumerable<T> GetEntities<T>(Expression<Func<T, bool>> expression, BaseFilter filter,
params string[] paths) where T : MesEntityBase, new();
IEnumerable<T> GetEntities<T>(Expression<Func<T, bool>> expression, BaseFilter filter,
bool isTracking = true, params string[] paths) where T : MesEntityBase, new();
IEnumerable<T> GetOrderEntities<T>(Expression<Func<T, bool>> expression, BaseFilter filter,
params string[] paths) where T : MesEntityBase, new();
IEnumerable<T> GetOrderEntities<T>(Expression<Func<T, bool>> expression, BaseFilter filter,
bool isTracking = true, params string[] paths) where T : MesEntityBase, new();
IEnumerable<T> GetOrderEntities<T>(Expression<Func<T, bool>> expression, BaseFilter filter, Dictionary<string, string> orders,
bool isTracking = true, params string[] paths) where T : MesEntityBase, new();
IEnumerable<T> GetOrderEntities<T>(Expression<Func<T, bool>> expression, BaseFilter filter, Dictionary<string, string> orders,
Action<IOrderable<T>> orderBy,
bool isTracking = true, params string[] paths) where T : MesEntityBase, new();
PagedResultDto<T> GetPageEntities<T>(Expression<Func<T, bool>> expression, BasePageFilter pageFilter,
params string[] paths) where T : MesEntityBase, new();
PagedResultDto<T> GetOrderPageEntities<T>(Expression<Func<T, bool>> expression, BasePageFilter pageFilter,
params string[] paths) where T : MesEntityBase, new();
PagedResultDto<T> GetOrderPageEntities<T>(Expression<Func<T, bool>> expression, BasePageFilter pageFilter,
int pageSize, int startIndex,
params string[] paths) where T : MesEntityBase, new();
PagedResultDto<T> GetOrderPageEntities<T>(Expression<Func<T, bool>> expression, BasePageFilter pageFilter,
int pageSize, int startIndex, bool isTracking = true,
params string[] paths) where T : MesEntityBase, new();
PagedResultDto<T> GetOrderPageEntities<T>(Expression<Func<T, bool>> expression, BasePageFilter pageFilter,
Dictionary<string, string> orders,
int pageSize, int startIndex, bool isTracking = true,
params string[] paths) where T : MesEntityBase, new();
IEnumerable<TreeNode<T>> GetTreeOrderEntities<T>(Expression<Func<T, bool>> expression, BaseFilter filter, bool isTracking = true,
params string[] paths) where T : TreeEntityBase<T>, new();
IEnumerable<T> GetTree<T>(string id, bool containCurrent = true, BaseFilter filter = null,
params string[] paths) where T : TreeEntityBase<T>, new();
PagedResultDto<T> GetOrderPageEntities<T>(Expression<Func<T, bool>> expression, BasePageFilter pageFilter,
Dictionary<string, string> orders,
int pageSize, int startIndex, Action<IOrderable<T>> orderBy, bool isTracking = true,
params string[] paths) where T : MesEntityBase, new();
//
PagedResultDto<T> GetOrderPageEntities<T>(Expression<Func<T, bool>> expression, BasePageFilter pageFilter,
string[] selectField, params string[] paths) where T : MesEntityBase, new();
Task<PagedResultDto<T>> GetOrderPageEntitiesSync<T>(Expression<Func<T, bool>> expression, BasePageFilter pageFilter,
params string[] paths) where T : MesEntityBase, new();
Task<PagedResultDto<T>> GetOrderPageEntitiesSync<T>(Expression<Func<T, bool>> expression, BasePageFilter pageFilter,
int pageSize, int startIndex,
params string[] paths) where T : MesEntityBase, new();
Task<PagedResultDto<T>> GetOrderPageEntitiesSync<T>(Expression<Func<T, bool>> expression, BasePageFilter pageFilter,
int pageSize, int startIndex, bool isTracking = true,
params string[] paths) where T : MesEntityBase, new();
Task<PagedResultDto<T>> GetOrderPageEntitiesSync<T>(Expression<Func<T, bool>> expression, BasePageFilter pageFilter,
Dictionary<string, string> orders,
int pageSize, int startIndex, bool isTracking = true,
params string[] paths) where T : MesEntityBase, new();
Task<PagedResultDto<T>> GetOrderPageEntitiesSync<T>(Expression<Func<T, bool>> expression, BasePageFilter pageFilter,
Dictionary<string, string> orders,
int pageSize, int startIndex, Action<IOrderable<T>> orderBy, bool isTracking = true,
params string[] paths) where T : MesEntityBase, new();
int GetCount<T>(Expression<Func<T, bool>> expression, BaseFilter filter) where T : MesEntityBase, new();
bool IsAny<T>(Expression<Func<T, bool>> expression, BaseFilter filter) where T : MesEntityBase, new();
#endregion
/// <summary>
/// 填充系统参数
/// </summary>
/// <param name="entities"></param>
/// <param name="filter"></param>
/// <param name="includes"></param>
void FillGetEntitySysParam<T>(IEnumerable<T> entities, BaseFilter filter, string[] includes);
T AddAndGetEntity_noneBase<T>(T entity) where T : class;
void AddEntities_noneBase<T>(IEnumerable<T> entities) where T : class;
T GetEntity_noneBase<T>(Expression<Func<T, bool>> expressions) where T : class;
List<T> GetEntities_noneBase<T>(Expression<Func<T, bool>> expressions) where T : class;
void UpdateEntities_noneBase<T>(IEnumerable<T> entities) where T : class;
void DeleteEntity_noneBase<T>(Expression<Func<T, bool>> expression) where T : class;
#region nocomit
void AddEntityNoCommit<T>(T entity) where T : MesEntityBase, new();
void AddEntitiesNoCommit<T>(IEnumerable<T> entities) where T : MesEntityBase, new();
void UpdateEntitiesNoCommit<T>(IEnumerable<T> entities) where T : MesEntityBase, new();
bool UpdateEntityNoCommit<T>(T entity, params string[] updateField) where T : MesEntityBase, new();
void UpdateEntitiesNoCommit<T>(IEnumerable<T> entities, params string[] updateField) where T : MesEntityBase, new();
void DeleteEntityNoCommit<T>(Expression<Func<T, bool>> expression) where T : MesEntityBase, new();
void DeleteEntityNoCommit<T>(T entity) where T : MesEntityBase, new();
void DeleteEntityNoCommit<T>(Guid id) where T : MesEntityBase, new();
void DeleteEntitiesNoCommit<T>(IEnumerable<T> entities) where T : MesEntityBase, new();
void SaveEntitiesNoCommit<T>(IEnumerable<T> entities) where T : MesEntityBase, new();
T AddAndGetEntityNoCommit<T>(T entity) where T : MesEntityBase, new();
void AddEntityByConn<T>(T entity, string conn) where T : MesEntityBase, new();
void UpdateEntitiesByConn<T>(IEnumerable<T> entities, string conn) where T : MesEntityBase, new();
void UpdateEntityByConn<T>(T entity, string conn, params string[] updateField) where T : MesEntityBase, new();
void DeleteEntityByConn<T>(Expression<Func<T, bool>> expression, string conn) where T : MesEntityBase, new();
void DeleteEntityByConn<T>(T entity, string conn) where T : MesEntityBase, new();
void DeleteEntityByConn<T>(Guid id, string conn) where T : MesEntityBase, new();
void DeleteEntitiesByConn<T>(IEnumerable<T> entities, string conn) where T : MesEntityBase, new();
void AddEntitiesByConn<T>(IEnumerable<T> entities, string conn) where T : MesEntityBase, new();
void UpdateEntitiesByConn<T>(IEnumerable<T> entities, string conn, params string[] updateField) where T : MesEntityBase, new();
//Tenant
void AddEntityByTenant<T>(T entity, string Tenant) where T : MesEntityBase, new();
void UpdateEntitiesByTenant<T>(IEnumerable<T> entities, string Tenant) where T : MesEntityBase, new();
void UpdateEntityByTenant<T>(T entity, string Tenant, params string[] updateField) where T : MesEntityBase, new();
void DeleteEntityByTenant<T>(Expression<Func<T, bool>> expression, string Tenant) where T : MesEntityBase, new();
void DeleteEntityByTenant<T>(T entity, string Tenant) where T : MesEntityBase, new();
void DeleteEntityByTenant<T>(Guid id, string Tenant) where T : MesEntityBase, new();
void DeleteEntitiesByTenant<T>(IEnumerable<T> entities, string Tenant) where T : MesEntityBase, new();
void AddEntitiesByTenant<T>(IEnumerable<T> entities, string Tenant) where T : MesEntityBase, new();
void UpdateEntitiesByTenant<T>(IEnumerable<T> entities, string Tenant, params string[] updateField) where T : MesEntityBase, new();
#endregion
}
}

View File

@ -0,0 +1,120 @@
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Threading.Tasks;
namespace APT.Infrastructure.Core
{
/// <summary>
/// 异步泛型主键实体仓储接口
/// </summary>
/// <typeparam name="TEntity">实体类型</typeparam>
/// <typeparam name="TKey">实体主键类型</typeparam>
public interface IRepositoryAsync<TEntity, in TKey> where TEntity : EntityBase<TKey>
{
/// <summary>
/// 异步插入实体
/// </summary>
/// <param name="entity">实体对象</param>
/// <returns>操作影响的行数</returns>
Task<int> AddAsync(TEntity entity);
/// <summary>
/// 异步批量插入实体
/// </summary>
/// <param name="entities">实体对象集合</param>
/// <returns>操作影响的行数</returns>
Task<int> AddAsync(IEnumerable<TEntity> entities);
/// <summary>
/// 异步删除实体
/// </summary>
/// <param name="entity">实体对象</param>
/// <returns>操作影响的行数</returns>
Task<int> DeleteAsync(TEntity entity);
/// <summary>
/// 异步删除指定编号的实体
/// </summary>
/// <param name="key">实体编号</param>
/// <returns>操作影响的行数</returns>
Task<int> DeleteAsync(TKey key);
/// <summary>
/// 异步删除所有符合特定条件的实体
/// </summary>
/// <param name="predicate">查询条件谓语表达式</param>
/// <returns>操作影响的行数</returns>
Task<int> DeleteAsync(Expression<Func<TEntity, bool>> predicate);
/// <summary>
/// 异步批量删除删除实体
/// </summary>
/// <param name="entities">实体对象集合</param>
/// <returns>操作影响的行数</returns>
Task<int> DeleteAsync(IEnumerable<TEntity> entities);
/// <summary>
/// 异步更新实体对象
/// </summary>
/// <param name="entity">实体对象</param>
/// <returns>操作影响的行数</returns>
Task<int> UpdateAsync(TEntity entity);
/// <summary>
/// 异步批量更新实体对象
/// </summary>
/// <param name="entities">实体对象集合</param>
/// <returns>操作影响的行数</returns>
Task<int> UpdateAsync(IEnumerable<TEntity> entities);
/// <summary>
/// 批量更新
/// </summary>
/// <param name="predicate">查询条件谓语表达式</param>
/// <param name="updateExpression">更新表达式</param>
/// <returns>操作影响的行数</returns>
Task<int> UpdateAsync(Expression<Func<TEntity, bool>> predicate, Expression<Func<TEntity, TEntity>> updateExpression);
/// <summary>
/// 异步获取指定主键的实体
/// </summary>
/// <param name="key">实体主键</param>
/// <returns>符合主键的实体不存在时返回null</returns>
Task<TEntity> GetByKeyAsync(TKey key);
/// <summary>
/// 异步获取符合条件的实体
/// </summary>
/// <param name="predicate">查询条件谓语表达式</param>
/// <returns>符合条件的实体不存在时返回null</returns>
Task<TEntity> GetAsync(Expression<Func<TEntity, bool>> predicate);
/// <summary>
/// 异步获取记录数
/// </summary>
/// <returns></returns>
Task<int> CountAsync();
/// <summary>
/// 异步获取符合条件的记录数
/// </summary>
/// <param name="predicate">查询条件谓语表达式</param>
/// <returns></returns>
Task<int> CountAsync(Expression<Func<TEntity, bool>> predicate = null);
/// <summary>
/// 异步是否存在符合条件的记录
/// </summary>
/// <param name="predicate">查询条件谓语表达式</param>
/// <returns></returns>
Task<bool> ExistsAsync(Expression<Func<TEntity, bool>> predicate);
}
public interface IRepositoryAsync<TEntity> : IRepositoryAsync<TEntity, Guid> where TEntity : EntityBase<Guid>
{
}
public interface IIntRepositoryAsync<TEntity> : IRepositoryAsync<TEntity, int> where TEntity : EntityBase<int>
{
}
}

View File

@ -0,0 +1,10 @@
namespace APT.Infrastructure.Core
{
/// <summary>
/// 泛型时间戳接口
/// </summary>
public interface IRowVersion
{
int ROW_VERSION { get; set; }
}
}

View File

@ -0,0 +1,221 @@

using Microsoft.EntityFrameworkCore.Storage;
using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Data;
using System.Data.Common;
using System.Linq.Expressions;
using System.Threading;
using System.Threading.Tasks;
namespace APT.Infrastructure.Core
{
public interface IUnitOfWork : IDependInject
{
#region methods
string ConnectionString { get; }
/// <summary>
/// 对数据库执行给定的 DDL/DML 命令。
/// </summary>
/// <param name="sql">命令字符串</param>
/// <param name="parameters">参数</param>
/// <returns>受影响的行数</returns>
int ExecuteSqlCommand(string sql, params object[] parameters);
/// <summary>
/// 对数据库执行给定的 DDL/DML 命令。
/// </summary>
/// <param name="transactionalBehavior">事务行为</param>
/// <param name="sql">命令字符串</param>
/// <param name="parameters">参数</param>
/// <returns>受影响的行数</returns>
int ExecuteSqlCommand(TransactionalBehavior transactionalBehavior, string sql, params object[] parameters);
/// <summary>
/// 对数据库执行给定的 DDL/DML 命令返回reader。
/// </summary>
/// <param name="sql">命令字符串</param>
/// <param name="readerAction">reader委托</param>
void ExecuteReader(string sql, ReaderColumn[] readerColumns, Action<DbDataReader> readerAction);
/// <summary>
/// 对数据库执行给定的 DDL/DML 命令返回reader。
/// </summary>
/// <param name="sql">命令字符串</param>
/// <param name="parameters">参数</param>
/// <param name="readerAction">reader委托</param>
void ExecuteReader(string sql, ReaderColumn[] readerColumns, DbParameter[] parameters, Action<DbDataReader> readerAction);
/// <summary>
/// 对数据库执行给定的 DDL/DML 命令返回reader。
/// </summary>
/// <param name="commandType">命令类型</param>
/// <param name="sql">命令字符串</param>
/// <param name="parameters">参数</param>
/// <param name="readerAction">reader委托</param>
void ExecuteReader(CommandType commandType, string sql, ReaderColumn[] readerColumns, DbParameter[] parameters, Action<DbDataReader> readerAction);
/// <summary>
/// 对数据库执行给定的 DDL/DML 命令。
/// </summary>
/// <param name="commandType">命令类型</param>
/// <param name="sql">命令字符串</param>
/// <param name="parameters">参数</param>
/// <returns></returns>
int ExecuteNonQuery(CommandType commandType, string sql, ReaderColumn[] readerColumns, DbParameter[] parameters);
/// <summary>
/// 创建一个原始 SQL 查询,该查询将返回给定类型的元素。
/// </summary>
/// <param name="elementType">查询所返回对象的类型</param>
/// <param name="sql">SQL 查询字符串</param>
/// <param name="parameters">要应用于 SQL 查询字符串的参数</param>
/// <returns></returns>
IEnumerable SqlQuery(Type elementType, string sql, ReaderColumn[] readerColumns, params Object[] parameters);
/// <summary>
/// 提交当前单元操作的更改。
/// </summary>
/// <returns>操作影响的行数</returns>
int SaveChanges();
/// <summary>
/// 执行数据sql语句
/// </summary>
/// <returns>执行数据sql语句</returns>
Task<int> ExecuteSqlCommandAsync(TransactionalBehavior transactionalBehavior, string sql, params object[] parameters);
/// <summary>
/// 异步提交当前单元操作的更改。
/// </summary>
/// <returns>操作影响的行数</returns>
Task<int> SaveChangesAsync(CancellationToken cancellationToken = default(CancellationToken));
/// <summary>
/// 开启事务
/// </summary>
void BeginTransaction();
/// <summary>
/// 提交事务
/// </summary>
void CommitTransaction();
/// <summary>
/// 回滚事务
/// </summary>
void RollbackTransaction();
T AddEntity<T>(T entity) where T : class;
void AddEntities<T>(IEnumerable<T> entities) where T : class;
public void UpdateEntity<T>(T entity) where T : class;
void UpdateEntities<T>(IEnumerable<T> entities) where T : class;
void UpdateEntities<T>(IEnumerable<T> entities, params string[] updateField) where T : class;
void DeleteEntities<T>(IEnumerable<T> entities) where T : class;
DataBaseType GetDataBaseType();
T GetEntity<T>(Expression<Func<T, bool>> expression, string[] selectField = null, params string[] paths) where T : class;
T GetEntity<T>(Expression<Func<T, bool>> expression, string[] selectField = null, bool isTracking = true, params string[] paths) where T : class;
T GetEntity<T>(Expression<Func<T, bool>> expression, Dictionary<string, DbOrder> orders, string[] selectField,
bool isTracking = true, params string[] paths) where T : class;
int GetCount<T>(Expression<Func<T, bool>> expression) where T : class;
IEnumerable<T> GetEntities<T>(Expression<Func<T, bool>> expression, string[] selectField = null, params string[] paths) where T : class;
IEnumerable<T> GetEntities<T>(Expression<Func<T, bool>> expression, string[] selectField = null, bool isTracking = true, params string[] paths) where T : class;
IEnumerable<T> GetOrderEntities<T>(Expression<Func<T, bool>> expression,
Dictionary<string, DbOrder> orders, string[] selectField = null,
params string[] paths) where T : class;
IEnumerable<T> GetOrderEntities<T>(Expression<Func<T, bool>> expression, Dictionary<string, DbOrder> orders, string[] selectField = null,
bool isTracking = true, params string[] paths) where T : class;
IEnumerable<T> GetOrderEntities<T>(Expression<Func<T, bool>> expression, Dictionary<string, DbOrder> orders,
Action<IOrderable<T>> orderBy, string[] selectField,
bool isTracking = true, params string[] paths) where T : class;
PagedResultDto<T> GetOrderPageEntities<T>(Expression<Func<T, bool>> expression, Dictionary<string, DbOrder> orders, string[] selectField,
int pageSize, int startIndex,
params string[] paths) where T : class;
PagedResultDto<T> GetOrderPageEntities<T>(Expression<Func<T, bool>> expression, Dictionary<string, DbOrder> orders, string[] selectField,
int pageSieze, int startIndex, bool isTracking = true,
params string[] paths) where T : class;
PagedResultDto<T> GetOrderPageEntities<T>(Expression<Func<T, bool>> expression, Dictionary<string, DbOrder> orders,
int pageSieze, int startIndex, Action<IOrderable<T>> orderBy, bool isTracking = true,
params string[] paths) where T : class;
PagedResultDto<T> GetOrderPageEntities<T>(Expression<Func<T, bool>> expression, Dictionary<string, DbOrder> orders, string[] selectField,
int pageSize, int startIndex, Action<IOrderable<T>> orderBy, bool isTracking = true,
params string[] paths) where T : class;
//
Task<PagedResultDto<T>> GetOrderPageEntitiesSync<T>(Expression<Func<T, bool>> expression, Dictionary<string, DbOrder> orders,
int pageSize, int startIndex,
params string[] paths) where T : class;
Task<PagedResultDto<T>> GetOrderPageEntitiesSync<T>(Expression<Func<T, bool>> expression, Dictionary<string, DbOrder> orders,
int pageSieze, int startIndex, bool isTracking = true,
params string[] paths) where T : class;
Task<PagedResultDto<T>> GetOrderPageEntitiesSync<T>(Expression<Func<T, bool>> expression, Dictionary<string, DbOrder> orders,
int pageSieze, int startIndex, Action<IOrderable<T>> orderBy, bool isTracking = true,
params string[] paths) where T : class;
PagedResultDto<T> GetPageEntities<T>(Expression<Func<T, bool>> expression, Dictionary<string, DbOrder> orders, string[] selectField,
int pageSieze, int startIndex, Action<IOrderable<T>> orderBy, bool isTracking = true,
params string[] paths) where T : class;
/// <summary>
/// 根据表名获取表数据结构
/// </summary>
/// <param name="tableName"></param>
/// <returns></returns>
EFModelTable GetModelTable(string tableName);
/// <summary>
/// 根据表名、字段名称获取字段结构
/// </summary>
/// <param name="tableName"></param>
/// <param name="fieldName"></param>
/// <returns></returns>
EFModelField GetModelField(string tableName, string fieldName);
/// <summary>
/// 根据表名,导航名称获取外键信息
/// </summary>
/// <param name="tableName"></param>
/// <param name="navName"></param>
/// <returns></returns>
EFModelForeignKey GetModelForeignKey(string tableName, string navName);
/// <summary>
/// 获取所有外键信息
/// </summary>
/// <param name="tableName"></param>
/// <returns></returns>
List<EFModelForeignKey> GetModelForeignKey(string tableName);
/// <summary>
/// 根据表名ID字段名称获取外键信息
/// </summary>
/// <param name="tableName"></param>
/// <param name="idFieldName"></param>
/// <returns></returns>
EFModelForeignKey GetModelForeignKeyById(string tableName, string idFieldName);
public IEnumerable<TreeNode<T>> GetTreeOrderEntities<T>(Expression<Func<T, bool>> expression, BaseFilter filter,
Expression<Func<T, bool>> orgExpression, out List<T> resultList, bool isTracking = true,
params string[] paths) where T : TreeEntityBase<T>, new();
#endregion
}
}

View File

@ -0,0 +1,83 @@
using System;
using System.Linq;
using System.Linq.Expressions;
namespace APT.Infrastructure.Core
{
/// <summary>
/// Linq架构里对集合排序实现
/// </summary>
/// <typeparam name="T"></typeparam>
public class Orderable<T> : IOrderable<T>
{
private IQueryable<T> _queryable;
/// <summary>
/// 排序后的结果集
/// </summary>
/// <param name="enumerable"></param>
public Orderable(IQueryable<T> enumerable)
{
_queryable = enumerable;
}
/// <summary>
/// 排序之后的结果集
/// </summary>
public IQueryable<T> Queryable
{
get { return _queryable; }
}
/// <summary>
/// 递增
/// </summary>
/// <typeparam name="TKey"></typeparam>
/// <param name="keySelector"></param>
/// <returns></returns>
public IOrderable<T> Asc<TKey>(Expression<Func<T, TKey>> keySelector)
{
_queryable = (_queryable as IOrderedQueryable<T>)
.OrderBy(keySelector);
return this;
}
/// <summary>
/// 然后递增
/// </summary>
/// <typeparam name="TKey"></typeparam>
/// <param name="keySelector"></param>
/// <returns></returns>
public IOrderable<T> ThenAsc<TKey>(Expression<Func<T, TKey>> keySelector)
{
_queryable = (_queryable as IOrderedQueryable<T>)
.ThenBy(keySelector);
return this;
}
/// <summary>
/// 递减
/// </summary>
/// <typeparam name="TKey"></typeparam>
/// <param name="keySelector"></param>
/// <returns></returns>
public IOrderable<T> Desc<TKey>(Expression<Func<T, TKey>> keySelector)
{
_queryable = _queryable
.OrderByDescending(keySelector);
return this;
}
/// <summary>
/// 然后递减
/// </summary>
/// <typeparam name="TKey"></typeparam>
/// <param name="keySelector"></param>
/// <returns></returns>
public IOrderable<T> ThenDesc<TKey>(Expression<Func<T, TKey>> keySelector)
{
_queryable = (_queryable as IOrderedQueryable<T>)
.ThenByDescending(keySelector);
return this;
}
}
}

View File

@ -0,0 +1,30 @@
using System;
namespace APT.Infrastructure.Core
{
/// <summary>
/// DateTime 扩展类
/// </summary>
public static class DateTimeExtensions
{
/// <summary>
/// 将当前DateTime值转换成yyyy-MM-dd字符串。
/// </summary>
/// <param name="datetime"></param>
/// <returns></returns>
public static string ToDateString(this DateTime datetime)
{
return datetime.ToString("yyyy-MM-dd");
}
/// <summary>
/// 将当前DateTime值星期几中文字符串。
/// </summary>
/// <param name="datetime"></param>
/// <returns></returns>
public static string ToDayOfWeekString(this DateTime datetime)
{
return datetime.ToString("dddd", new System.Globalization.CultureInfo("zh-CN"));
}
}
}

View File

@ -0,0 +1,75 @@
using System;
using System.ComponentModel;
using System.Collections.Generic;
using System.Linq;
namespace APT.Infrastructure.Core
{
/// <summary>
/// 类型<see cref="Enum"/>扩展方法类
/// </summary>
public static class EnumExtensions
{
/// <summary>
/// 获取枚举值<see cref="DescriptionAttribute"/>值
/// </summary>
/// <param name="enumeration">枚举值</param>
/// <returns></returns>
public static String GetDescription(this Enum enumeration)
{
if (enumeration == null)
return String.Empty;
var enumType = enumeration.GetType();
var fi = enumType.GetField(Enum.GetName(enumType, enumeration));
var descAttr = (DescriptionAttribute)Attribute.GetCustomAttribute(fi, typeof(DescriptionAttribute));
return descAttr == null || String.IsNullOrEmpty(descAttr.Description) ? enumeration.ToString() : descAttr.Description;
}
/// <summary>
/// 将一个或多个枚举常数的名称或数字值的字符串表示转换成等效的枚举对象。 用于指示转换是否成功的返回值。
/// </summary>
/// <typeparam name="TEnum">要将 value 转换为的枚举类型。</typeparam>
/// <param name="value"> 要转换的枚举名称或基础值的字符串表示形式。</param>
/// <param name="defaultValue">默认值</param>
/// <returns>如果 value 参数成功转换,则返回类型为 TEnum 的一个对象,其值由 value 表示;否则为 defaultValue。</returns>
public static TEnum ToEnum<TEnum>(this String value, TEnum defaultValue) where TEnum : struct
{
if (String.IsNullOrEmpty(value))
return defaultValue;
TEnum result;
bool parseResult = Enum.TryParse<TEnum>(value, out result);
return parseResult ? result : defaultValue;
}
}
public class CommonEqualityComparer<T, V> : IEqualityComparer<T>
{
private Func<T, V> keySelector;
public CommonEqualityComparer(Func<T, V> keySelector)
{
this.keySelector = keySelector;
}
public bool Equals(T x, T y)
{
return EqualityComparer<V>.Default.Equals(keySelector(x), keySelector(y));
}
public int GetHashCode(T obj)
{
return EqualityComparer<V>.Default.GetHashCode(keySelector(obj));
}
}
public static class DistinctExtensions
{
public static IEnumerable<T> Distinct<T, V>(this IEnumerable<T> source, Func<T, V> keySelector)
{
return source.Distinct(new CommonEqualityComparer<T, V>(keySelector));
}
}
}

View File

@ -0,0 +1,34 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
namespace APT.Infrastructure.Core.Extensions
{
public static class QueryableExtensions
{
public static IQueryable<T> OrderByName<T>(this IQueryable<T> queryable, string propertyName, bool desc = false)
{
return QueryableHelper<T>.OrderBy(queryable, propertyName, desc);
}
static class QueryableHelper<T>
{
private static Dictionary<string, LambdaExpression> cache = new Dictionary<string, LambdaExpression>();
public static IQueryable<T> OrderBy(IQueryable<T> queryable, string propertyName, bool desc)
{
dynamic keySelector = GetLambdaExpression(propertyName);
return desc ? Queryable.OrderByDescending(queryable, keySelector) : Queryable.OrderBy(queryable, keySelector);
}
private static LambdaExpression GetLambdaExpression(string propertyName)
{
if (cache.ContainsKey(propertyName)) return cache[propertyName];
var param = Expression.Parameter(typeof(T));
var body = Expression.Property(param, propertyName);
var keySelector = Expression.Lambda(body, param);
cache[propertyName] = keySelector;
return keySelector;
}
}
}
}

View File

@ -0,0 +1,80 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
namespace APT.Infrastructure.Core
{
/// <summary>
/// Expression表达式扩展操作类
/// </summary>
public static class ExpressionExtensions
{
/// <summary>
/// 以特定的条件运行组合两个Expression表达式
/// </summary>
/// <typeparam name="T">表达式的主实体类型</typeparam>
/// <param name="first">第一个Expression表达式</param>
/// <param name="second">要组合的Expression表达式</param>
/// <param name="merge">组合条件运算方式</param>
/// <returns>组合后的表达式</returns>
public static Expression<T> Compose<T>(this Expression<T> first, Expression<T> second, Func<Expression, Expression, Expression> merge)
{
Dictionary<ParameterExpression, ParameterExpression> map =
first.Parameters.Select((f, i) => new { f, s = second.Parameters[i] }).ToDictionary(p => p.s, p => p.f);
Expression secondBody = ParameterRebinder.ReplaceParameters(map, second.Body);
return Expression.Lambda<T>(merge(first.Body, secondBody), first.Parameters);
}
/// <summary>
/// 以 Expression.AndAlso 组合两个Expression表达式
/// </summary>
/// <typeparam name="T">表达式的主实体类型</typeparam>
/// <param name="first">第一个Expression表达式</param>
/// <param name="second">要组合的Expression表达式</param>
/// <returns>组合后的表达式</returns>
public static Expression<Func<T, bool>> And<T>(this Expression<Func<T, bool>> first, Expression<Func<T, bool>> second)
{
return first.Compose(second, Expression.AndAlso);
}
/// <summary>
/// 以 Expression.OrElse 组合两个Expression表达式
/// </summary>
/// <typeparam name="T">表达式的主实体类型</typeparam>
/// <param name="first">第一个Expression表达式</param>
/// <param name="second">要组合的Expression表达式</param>
/// <returns>组合后的表达式</returns>
public static Expression<Func<T, bool>> Or<T>(this Expression<Func<T, bool>> first, Expression<Func<T, bool>> second)
{
return first.Compose(second, Expression.OrElse);
}
private class ParameterRebinder : ExpressionVisitor
{
private readonly Dictionary<ParameterExpression, ParameterExpression> _map;
private ParameterRebinder(Dictionary<ParameterExpression, ParameterExpression> map)
{
_map = map ?? new Dictionary<ParameterExpression, ParameterExpression>();
}
public static Expression ReplaceParameters(Dictionary<ParameterExpression, ParameterExpression> map, Expression exp)
{
return new ParameterRebinder(map).Visit(exp);
}
protected override Expression VisitParameter(ParameterExpression node)
{
ParameterExpression replacement;
if (_map.TryGetValue(node, out replacement))
{
node = replacement;
}
return base.VisitParameter(node);
}
}
}
}

View File

@ -0,0 +1,45 @@
using System;
using System.Linq.Expressions;
namespace APT.Infrastructure.Core
{
/// <summary>
/// 类型<see cref="APT.Core.Filter.FilterGroup"/>扩展方法类
/// </summary>
public static class FilterGroupExtensions
{
/// <summary>
/// 生成条件表达式
/// </summary>
/// <typeparam name="T">类型</typeparam>
/// <param name="group">条件组</param>
/// <returns></returns>
public static Expression<Func<T, bool>> BuildExpression<T>(this FilterGroup group, IUnitOfWork unitOfWork)
{
return FilterHelper.GetExpression<T>(group, unitOfWork);
}
/// <summary>
/// 生成条件表达式
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="rule"></param>
/// <returns></returns>
public static Expression<Func<T, bool>> BuildExpression<T>(this FilterRule rule)
{
return FilterHelper.GetExpression<T>(rule);
}
/// <summary>
/// 生成条件表达式
/// </summary>
/// <typeparam name="T">类型</typeparam>
/// <param name="group">条件组</param>
/// <returns></returns>
public static Expression<Func<T, bool>> BuildExpression<T>(this BaseFilter filter, IUnitOfWork unitOfWork)
{
//var expression = FilterHelper.GetExpression<T>(filter.FilterRule);
return FilterHelper.GetExpression<T>(filter.FilterGroup, unitOfWork);
}
}
}

View File

@ -0,0 +1,34 @@
using System;
namespace APT.Infrastructure.Core
{
/// <summary>
/// 类型<see cref="System.Int32"/>扩展方法类
/// </summary>
public static class Int32Extensions
{
/// <summary>
/// 返回一个新字符串,该字符串通过在此实例中的字符左侧填充指定的 Unicode 字符来达到指定的总长度,从而使这些字符右对齐。
/// </summary>
/// <param name="source"></param>
/// <param name="totalWidth"></param>
/// <param name="paddingChar"></param>
/// <returns></returns>
public static String PadLeft(this Int32 source, int totalWidth, char paddingChar)
{
return source.ToString().PadLeft(totalWidth, paddingChar);
}
/// <summary>
/// 返回一个新字符串,该字符串通过在此字符串中的字符右侧填充指定的 Unicode 字符来达到指定的总长度,从而使这些字符左对齐。
/// </summary>
/// <param name="source"></param>
/// <param name="totalWidth"></param>
/// <param name="paddingChar"></param>
/// <returns></returns>
public static String PadRight(this Int32 source, int totalWidth, char paddingChar)
{
return source.ToString().PadRight(totalWidth, paddingChar);
}
}
}

View File

@ -0,0 +1,37 @@
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Text;
namespace APT.Infrastructure.Core
{
public static class JsonExtensions
{
/// <summary>
/// 把对象序列化成Json字符串格式
/// </summary>
/// <param name="obj"></param>
/// <returns></returns>
public static string ToJson(this object obj)
{
JsonSerializerSettings settings = new JsonSerializerSettings();
settings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
settings.NullValueHandling = NullValueHandling.Ignore;
settings.DateFormatString = "yyyy-MM-dd HH:mm:ss";
return JsonConvert.SerializeObject(obj, settings);
}
/// <summary>
/// 把Json字符串转换为强类型对象
/// </summary>
public static T DeserializeObject<T>(this string json)
{
return JsonConvert.DeserializeObject<T>(json);
}
public static JObject ToJObject(this string Json)
{
return Json == null ? JObject.Parse("{}") : JObject.Parse(Json.Replace("&nbsp;", ""));
}
}
}

View File

@ -0,0 +1,67 @@
using System;
using System.Collections.Generic;
using System.Diagnostics.Contracts;
using System.Linq;
namespace APT.Infrastructure.Core
{
/// <summary>
/// Linq 拓展方法类
/// </summary>
public static class LinqExtensions
{
public static void ForEach<T>(this IEnumerable<T> source, Action<T> action)
{
Contract.Requires(action != null);
foreach (var element in source)
action(element);
}
public class DGroupBy<T> : IGrouping<object[], T>
{
private List<T> _innerlist = new List<T>();
private object[] _key;
public DGroupBy(object[] key) { _key = key; }
public object[] Key
{
get { return _key; }
}
public void Add(T value)
{
_innerlist.Add(value);
}
public IEnumerator<T> GetEnumerator()
{
return this._innerlist.GetEnumerator();
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return this._innerlist.GetEnumerator();
}
}
public static IEnumerable<IGrouping<object[], T>> DynamicGroupBy<T>(this IEnumerable<T> data, string[] keys)
{
List<DGroupBy<T>> list = new List<DGroupBy<T>>();
foreach (var item in data.Select(x => new {
k = keys.Select(y => x.GetType().GetProperty(y).GetValue(x, null)).ToArray(),
v = x
}))
{
DGroupBy<T> existing = list.SingleOrDefault(x => x.Key.Zip(item.k, (a, b) => a.Equals(b)).All(y => y));
if (existing == null)
{
existing = new DGroupBy<T>(item.k);
list.Add(existing);
}
existing.Add(item.v);
}
return list;
}
}
}

View File

@ -0,0 +1,57 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Diagnostics.Contracts;
namespace APT.Infrastructure.Core
{
public static class QueryableOrderExtension
{
public static IQueryable<T> SetQueryableOrder<T>(this IQueryable<T> query, string sort, string order, bool isThen = false)
{
if (string.IsNullOrEmpty(sort))
throw new Exception("必须指定排序字段!");
//PropertyInfo sortProperty = typeof(T).GetProperty(sort, BindingFlags.Public | BindingFlags.Instance | BindingFlags.IgnoreCase);
//if (sortProperty == null)
// throw new Exception("查询对象中不存在排序字段" + sort + "");
ParameterExpression param = Expression.Parameter(typeof(T), "t");
Expression body = param;
if (Nullable.GetUnderlyingType(body.Type) != null)
body = Expression.Property(body, "Value");
body = GetPropertyLambdaExpression(body, sort);
LambdaExpression keySelectorLambda = Expression.Lambda(body, param);
if (string.IsNullOrEmpty(order))
order = "ASC";
string queryMethod = isThen ? order.ToUpper() == "DESC" ? "ThenByDescending" : "ThenBy" : order.ToUpper() == "DESC" ? "OrderByDescending" : "OrderBy";
query = query.Provider.CreateQuery<T>(Expression.Call(typeof(Queryable), queryMethod,
new Type[] { typeof(T), body.Type },
query.Expression,
Expression.Quote(keySelectorLambda)));
return query;
}
private static Expression GetPropertyLambdaExpression(Expression body, string fileName)
{
string[] propertyNames = fileName.Split('.');
Type type = body.Type;
foreach (string propertyName in propertyNames)
{
PropertyInfo property = type.GetProperty(propertyName);
//Contract.Assume(property != null);
if (property == null)
{
throw new Exception($"类型{type.Name}不存在属性{propertyName}");
}
type = property.PropertyType;
body = Expression.MakeMemberAccess(body, property);
}
return body;
}
}
}

View File

@ -0,0 +1,78 @@
using System;
using System.Text;
namespace APT.Infrastructure.Core
{
/// <summary>
/// 类型<see cref="System.Random"/>扩展方法类
/// </summary>
public static class RandomExtensions
{
static char[] _numberPattern = new char[] { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' };
static char[] _letterPattern = new char[] { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L','M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z' };
static char[] _letterAndNumberPattern = new char[] { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P','Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z' };
/// <summary>
/// 获取指定的长度的随机数字字符串
/// </summary>
/// <param name="random"></param>
/// <param name="length">要获取随机数长度</param>
/// <returns>指定长度的随机数字符串</returns>
public static string NextNumberString(this Random random, int length)
{
if (length < 0)
throw new ArgumentOutOfRangeException("length");
int n = _numberPattern.Length;
StringBuilder randomBuilder = new StringBuilder();
for (int i = 0; i < length; i++)
{
int rnd = random.Next(0, n);
randomBuilder.Append(_numberPattern[rnd]);
}
return randomBuilder.ToString();
}
/// <summary>
/// 获取指定的长度的随机字母字符串
/// </summary>
/// <param name="random"></param>
/// <param name="length">要获取随机数长度</param>
/// <returns>指定长度的随机字母组成字符串</returns>
public static string NextLetterString(this Random random, int length)
{
if (length < 0)
{
throw new ArgumentOutOfRangeException("length");
}
int n = _letterPattern.Length;
StringBuilder randomBuilder = new StringBuilder();
for (int i = 0; i < length; i++)
{
int rnd = random.Next(0, n);
randomBuilder.Append(_letterPattern[rnd]);
}
return randomBuilder.ToString();
}
/// <summary>
/// 获取指定的长度的随机字母和数字字符串
/// </summary>
/// <param name="random"></param>
/// <param name="length">要获取随机数长度</param>
/// <returns>指定长度的随机字母和数字组成字符串</returns>
public static string NextLetterAndNumberString(this Random random, int length)
{
if (length < 0)
throw new ArgumentOutOfRangeException("length");
int n = _letterAndNumberPattern.Length;
StringBuilder randomBuilder = new StringBuilder();
for (int i = 0; i < length; i++)
{
int rnd = random.Next(0, n);
randomBuilder.Append(_letterAndNumberPattern[rnd]);
}
return randomBuilder.ToString();
}
}
}

View File

@ -0,0 +1,167 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Reflection;
namespace APT.Infrastructure.Core
{
/// <summary>
/// 类型<see cref="Type"/>扩展方法类
/// </summary>
public static class TypeExtensions
{
public static object GetListObject(this Type p_Type)
{
Assembly _Assembly = Assembly.Load("mscorlib");
Type _TypeList = _Assembly.GetType("System.Collections.Generic.List`1[[" + p_Type.FullName + "," + p_Type.Assembly.FullName + "]]");
object _List = System.Activator.CreateInstance(_TypeList);
return _List;
}
/// <summary>
/// 判断类型是否为Nullable类型
/// </summary>
/// <param name="type"> 要处理的类型 </param>
/// <returns> 是返回True不是返回False </returns>
public static bool IsNullableType(this Type type)
{
return ((type != null) && type.IsGenericType) && (type.GetGenericTypeDefinition().Equals(typeof(Nullable<>)));
}
/// <summary>
/// 由类型的Nullable类型返回实际类型
/// </summary>
/// <param name="type"> 要处理的类型对象 </param>
/// <returns> </returns>
public static Type GetNonNummableType(this Type type)
{
if (IsNullableType(type))
{
return type.GetGenericArguments()[0];
}
return type;
}
/// <summary>
/// 通过类型转换器获取Nullable类型的基础类型
/// </summary>
/// <param name="type"> 要处理的类型对象 </param>
/// <returns> </returns>
public static Type GetUnNullableType(this Type type)
{
if (IsNullableType(type))
{
NullableConverter nullableConverter = new NullableConverter(type);
return nullableConverter.UnderlyingType;
}
return type;
}
/// <summary>
/// 获取成员元数据的Description特性描述信息
/// </summary>
/// <param name="member">成员元数据对象</param>
/// <param name="inherit">是否搜索成员的继承链以查找描述特性</param>
/// <returns>返回Description特性描述信息如不存在则返回成员的名称</returns>
public static string ToDescription(this MemberInfo member, bool inherit = false)
{
DescriptionAttribute desc = member.GetAttribute<DescriptionAttribute>(inherit);
return desc == null ? member.Name : desc.Description;
}
/// <summary>
/// 检查指定指定类型成员中是否存在指定的Attribute特性
/// </summary>
/// <typeparam name="T">要检查的Attribute特性类型</typeparam>
/// <param name="memberInfo">要检查的类型成员</param>
/// <param name="inherit">是否从继承中查找</param>
/// <returns>是否存在</returns>
public static bool ExistsAttribute<T>(this MemberInfo memberInfo, bool inherit = false) where T : Attribute
{
return memberInfo.GetCustomAttributes(typeof(T), inherit).Any(m => (m as T) != null);
}
/// <summary>
/// 从类型成员获取指定Attribute特性
/// </summary>
/// <typeparam name="T">Attribute特性类型</typeparam>
/// <param name="memberInfo">类型类型成员</param>
/// <param name="inherit">是否从继承中查找</param>
/// <returns>存在返回第一个不存在返回null</returns>
public static T GetAttribute<T>(this MemberInfo memberInfo, bool inherit = false) where T : Attribute
{
var descripts = memberInfo.GetCustomAttributes(typeof(T), inherit);
return descripts.FirstOrDefault() as T;
}
/// <summary>
/// 从类型成员获取指定Attribute特性
/// </summary>
/// <typeparam name="T">Attribute特性类型</typeparam>
/// <param name="memberInfo">类型类型成员</param>
/// <param name="inherit">是否从继承中查找</param>
/// <returns>返回所有指定Attribute特性的数组</returns>
public static T[] GetAttributes<T>(this MemberInfo memberInfo, bool inherit = false) where T : Attribute
{
return memberInfo.GetCustomAttributes(typeof(T), inherit).Cast<T>().ToArray();
}
/// <summary>
/// 判断类型是否为集合类型
/// </summary>
/// <param name="type">要处理的类型</param>
/// <returns>是返回True不是返回False</returns>
public static bool IsEnumerable(this Type type)
{
if (type == typeof(string))
{
return false;
}
return typeof(IEnumerable).IsAssignableFrom(type);
}
/// <summary>
/// 判断当前泛型类型是否可由指定类型的实例填充
/// </summary>
/// <param name="genericType">泛型类型</param>
/// <param name="type">指定类型</param>
/// <returns></returns>
public static bool IsGenericAssignableFrom(this Type genericType, Type type)
{
if (genericType == null || type == null)
{
return false;
}
if (!genericType.IsGenericType)
{
throw new ArgumentException("该功能只支持泛型类型的调用,非泛型类型可使用 IsAssignableFrom 方法。");
}
List<Type> allOthers = new List<Type> { type };
if (genericType.IsInterface)
{
allOthers.AddRange(type.GetInterfaces());
}
foreach (var other in allOthers)
{
Type cur = other;
while (cur != null)
{
if (cur.IsGenericType)
{
cur = cur.GetGenericTypeDefinition();
}
if (cur.IsSubclassOf(genericType) || cur == genericType)
{
return true;
}
cur = cur.BaseType;
}
}
return false;
}
}
}

View File

@ -0,0 +1,683 @@
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Net.Security;
using System.Reflection;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Threading.Tasks;
namespace APT.Infrastructure.Core
{
public class ApiHelper
{
public static int URL_TIMEOUT = 60000 * 120;//2个小时
private static string ApiByGet(string url, IDictionary<string, object> parameters, string token, IDictionary<string, string> headParams)
{
HttpWebResponse response = HttpWebResponseUtility.CreateGetHttpResponseByParams(url, parameters, URL_TIMEOUT, "", null, token, headParams);
var sr = new System.IO.StreamReader(response.GetResponseStream());
string content = sr.ReadToEnd(); //这里的content就是网页内容了
sr.Close();
return content;
}
private static string ApiByPost(string url, IDictionary<string, object> parameters, string token, IDictionary<string, string> headParams = null)
{
HttpWebResponse response = HttpWebResponseUtility.CreateApiPostHttpResponse(url, parameters, URL_TIMEOUT, "", Encoding.UTF8, null, token, headParams);
var sr = new System.IO.StreamReader(response.GetResponseStream());
string content = sr.ReadToEnd(); //这里的content就是网页内容了
sr.Close();
return content;
}
private static string ApiSend(ApiBody body)
{
var response = HttpWebResponseUtility.CreatePostHttpResponseByJson(body.ApiUrl, body.SendObj != null ? JsonConvert.SerializeObject(body.SendObj) : string.Empty,
URL_TIMEOUT, "", null, body.Token, body.HeadParams);
if (response != null)
{
var sr = new System.IO.StreamReader(response.GetResponseStream());
string content = sr.ReadToEnd(); //这里的content就是网页内容了
sr.Close();
System.Diagnostics.Debug.WriteLine(content);
return content;
}
else
{
return "";
}
}
public static byte[] ApiPicture(ApiBody body)
{
var response = HttpWebResponseUtility.CreatePostHttpResponseByJson(body.ApiUrl, body.SendObj != null ? JsonConvert.SerializeObject(body.SendObj) : string.Empty,
URL_TIMEOUT, "", null, body.Token, body.HeadParams);
if (response != null)
{
//获取HTTP返回数据
using (Stream sr = response.GetResponseStream())
{
byte[] img = new byte[response.ContentLength];
sr.Read(img, 0, (int)response.ContentLength);//这里获取之后
sr.Close();
sr.Dispose();
return img;
}
response.Close();
}
else
{
return null;
}
}
public static T GetApiData<T>(ApiBody body)
{
int totalCount = 0;
var ret = GetApiData<T>(body, ref totalCount);
return ret;
}
public static T GetApiData<T>(ApiBody body, ref int totalCount)
{
string msg = string.Empty;
var ret = GetApiData<T>(body, ref totalCount, ref msg);
return ret;
}
public static string GetApiData(ApiBody body, ref string msg)
{
string returns = string.Empty;
//参数
if (body.SendType == SendType.Get)
{
if (body.SendObj != null)
body.Params = GetParameters(body.SendObj);
returns = ApiByGet(body.ApiUrl, body.Params, body.Token, body.HeadParams);
}
else if (body.SendType == SendType.Post)
{
if (body.Params != null && body.Params.Any())
returns = ApiByPost(body.ApiUrl, body.Params, body.Token, body.HeadParams);
else
returns = ApiSend(body);
}
LoggerManager.GetLogger().Info($"请求接口:{body.ApiUrl},返回:{returns}");
if (!string.IsNullOrEmpty(returns))
{
if (body.ResolvingResult)
{
return returns;
}
else
{
var s = Newtonsoft.Json.JsonConvert.DeserializeObject(returns);
var obj = JObject.Parse(s.ToString());
var result = Convert.ToBoolean(obj["IsSuccessful"]);
if (result)
{
return obj["Data"] == null ? "" : obj["Data"].ToString();
}
else
{
if (obj["ErrorMessage"] != null)
msg = obj["ErrorMessage"].ToString();
}
}
}
return "";
}
public static T GetApiData<T>(ApiBody body, ref int totalCount, ref string msg)
{
string returns = string.Empty;
//参数
if (body.SendType == SendType.Get)
{
if (body.SendObj != null)
body.Params = GetParameters(body.SendObj);
returns = ApiByGet(body.ApiUrl, body.Params, body.Token, body.HeadParams);
}
else if (body.SendType == SendType.Post)
{
if (body.Params != null && body.Params.Any())
returns = ApiByPost(body.ApiUrl, body.Params, body.Token, body.HeadParams);
else
returns = ApiSend(body);
}
LoggerManager.GetLogger().Info($"请求接口:{body.ApiUrl},返回:{returns}");
if (!string.IsNullOrEmpty(returns))
{
if (body.ResolvingResult)
{
try
{
var t = JsonConvert.DeserializeObject<T>(returns);
return t;
}
catch (Exception ex)
{
return default(T);
}
}
else
{
var s = Newtonsoft.Json.JsonConvert.DeserializeObject(returns);
var obj = JObject.Parse(s.ToString());
var result = Convert.ToBoolean(obj["IsSuccessful"]);
if (result)
{
if (obj["Data"].ToString() != "[]")
{
totalCount = obj["TotalCount"] == null ? 0 : Convert.ToInt32(obj["TotalCount"]);
try
{
var t = JsonConvert.DeserializeObject<T>(obj["Data"].ToString());
return t;
}
catch (Exception ex)
{
return default(T);
}
}
}
else
{
if (obj["ErrorMessage"] != null)
msg = obj["ErrorMessage"].ToString();
}
}
}
return default(T);
}
public static bool GetApiData(ApiBody body, ref int totalCount, ref string msg)
{
string returns = string.Empty;
if (body.SendType == SendType.Get)
{
//参数
if (body.SendObj != null)
body.Params = GetParameters(body.SendObj);
returns = ApiByGet(body.ApiUrl, body.Params, body.Token, body.HeadParams);
}
else if (body.SendType == SendType.Post)
{
if (body.Params != null && body.Params.Any())
returns = ApiByPost(body.ApiUrl, body.Params, body.Token);
else
returns = ApiSend(body);
}
var result = false;
if (!string.IsNullOrEmpty(returns))
{
var s = Newtonsoft.Json.JsonConvert.DeserializeObject(returns);
var obj = JObject.Parse(s.ToString());
result = Convert.ToBoolean(obj["IsSuccessful"]);
if (result && obj["Data"].ToString() != "[]")
{
totalCount = obj["TotalCount"] == null ? 0 : Convert.ToInt32(obj["TotalCount"]);
}
if (obj["ErrorMessage"] != null)
msg = obj["ErrorMessage"].ToString();
}
return result;
}
public static bool GetApiData(ApiBody body, ref int totalCount)
{
string msg = string.Empty;
return GetApiData(body, ref totalCount, ref msg);
}
public static IDictionary<string, object> GetParameters(object obj)
{
IDictionary<string, object> Params = new Dictionary<string, object>();
if (obj != null)
{
var type = obj.GetType();
PropertyInfo[] properties = type.GetProperties().Where(p => !p.GetMethod.IsVirtual).ToArray();
foreach (PropertyInfo info in properties)
{
try
{
var value = GetObjectPropertyValue(obj, info.Name).ToString();
if (value == "APT.Infrastructure.Core.FilterGroup" || value.StartsWith("System.Collections.Generic.List"))
{
continue;
}
Params.Add(info.Name, value);
}
catch (Exception ex)
{
throw new Exception(ex.Message);
}
}
}
return Params;
}
public static IDictionary<string, object> NewGetPrarams(object obj)
{
IDictionary<string, object> Params = new Dictionary<string, object>();
if (obj != null)
{
var type = obj.GetType();
PropertyInfo[] properties = type.GetProperties();
foreach (PropertyInfo info in properties)
{
try
{
Params.Add(info.Name, GetObjectPropertyValue(obj, info.Name));
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine(ex.Message);
}
}
}
return Params;
}
public static object GetObjectPropertyValue(object obj, string propertyname)
{
var t = obj.GetType();
PropertyInfo property = t.GetProperty(propertyname);
if (property == null) return string.Empty;
object o = property.GetValue(obj, null);
if (o == null) return string.Empty;
return o;
}
}
public class ApiBody
{
public ApiBody()
{
this.HeadParams = new Dictionary<string, string>();
}
public string ApiUrl { get; set; }
public IDictionary<string, object> Params { get; set; }
public SendType SendType { get; set; }
public Object SendObj { get; set; }
public bool ResolvingResult { get; set; }
public string Token { get; set; }
public IDictionary<string, string> HeadParams { get; set; }
}
public class PagedList<T> : List<T>, IEnumerable<T>
{
public PagedList(IEnumerable<T> currentPageItems, int pageIndex, int pageSize, int totalItemCount)
{
this.AddRange(currentPageItems);
this.CurrentPageIndex = pageIndex;
this.PageSize = pageSize;
this.TotalPageCount = totalItemCount;
}
public int CurrentPageIndex { get; set; }
public int PageSize { get; set; }
public int TotalPageCount { get; }
}
public enum SendType
{
Get,
Post,
Put,
Delete
}
public class HttpWebResponseUtility
{
private static readonly string DefaultUserAgent = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2; SV1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)";
/// <summary>
/// 创建GET方式的HTTP请求
/// </summary>
/// <param name="url">请求的URL</param>
/// <param name="timeout">请求的超时时间</param>
/// <param name="userAgent">请求的客户端浏览器信息,可以为空</param>
/// <param name="cookies">随同HTTP请求发送的Cookie信息如果不需要身份验证可以为空</param>
/// <returns></returns>
public static HttpWebResponse CreateGetHttpResponse(string url, int? timeout, string userAgent, CookieCollection cookies)
{
if (string.IsNullOrEmpty(url))
{
throw new ArgumentNullException("url");
}
HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;
request.Method = "GET";
request.UserAgent = DefaultUserAgent;
if (!string.IsNullOrEmpty(userAgent))
{
request.UserAgent = userAgent;
}
if (timeout.HasValue)
{
request.Timeout = timeout.Value;
}
if (cookies != null)
{
request.CookieContainer = new CookieContainer();
request.CookieContainer.Add(cookies);
}
return request.GetResponse() as HttpWebResponse;
}
/// <summary>
/// 创建GET方式的HTTP请求
/// </summary>
/// <param name="url">请求的URL</param>
/// <param name="timeout">请求的超时时间</param>
/// <param name="userAgent">请求的客户端浏览器信息,可以为空</param>
/// <param name="cookies">随同HTTP请求发送的Cookie信息如果不需要身份验证可以为空</param>
/// <returns></returns>
public static HttpWebResponse CreateGetHttpResponseByParams(string url, IDictionary<string, object> parameters, int? timeout, string userAgent, CookieCollection cookies, string token, IDictionary<string, string> headParams)
{
if (string.IsNullOrEmpty(url))
{
throw new ArgumentNullException("url");
}
if (!(parameters == null || parameters.Count == 0))
{
int i = 0;
foreach (string key in parameters.Keys)
{
if (i > 0)
{
url += string.Format("&{0}={1}", key, parameters[key]);
}
else
{
url += string.Format("?{0}={1}", key, parameters[key]);
}
i++;
}
}
HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;
request.Method = "GET";
request.UserAgent = DefaultUserAgent;
if (!string.IsNullOrEmpty(token))
request.Headers.Add("Authorization", "Bearer " + token);
if (headParams != null && headParams.Any())
headParams.ForEach(t =>
{
request.Headers.Add(t.Key, t.Value);
});
if (!string.IsNullOrEmpty(userAgent))
{
request.UserAgent = userAgent;
}
if (timeout.HasValue)
{
request.Timeout = timeout.Value;
}
if (cookies != null)
{
request.CookieContainer = new CookieContainer();
request.CookieContainer.Add(cookies);
}
return request.GetResponse() as HttpWebResponse;
}
public static HttpWebResponse CreatePostHttpResponseByJson(string url, string json, int? timeout, string userAgent, CookieCollection cookies, string token, IDictionary<string, string> headParams)
{
if (string.IsNullOrEmpty(url))
{
throw new ArgumentNullException("url");
}
byte[] bytes = null;
if (!string.IsNullOrEmpty(json))
bytes = Encoding.UTF8.GetBytes(json);
HttpWebRequest request = null;
//如果是发送HTTPS请求
if (url.StartsWith("https", StringComparison.OrdinalIgnoreCase))
{
ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(CheckValidationResult);
request = WebRequest.Create(url) as HttpWebRequest;
request.ProtocolVersion = HttpVersion.Version10;
}
else
{
request = WebRequest.Create(url) as HttpWebRequest;
}
request.Method = "POST";
request.ContentType = "application/json";
if (!string.IsNullOrEmpty(token))
request.Headers.Add("Authorization", "Bearer " + token);
if (headParams != null && headParams.Any())
headParams.ForEach(t =>
{
request.Headers.Add(t.Key, t.Value);
});
if (!string.IsNullOrEmpty(userAgent))
{
request.UserAgent = userAgent;
}
else
{
request.UserAgent = DefaultUserAgent;
}
if (timeout.HasValue)
{
request.Timeout = timeout.Value;
}
if (cookies != null)
{
request.CookieContainer = new CookieContainer();
request.CookieContainer.Add(cookies);
}
if (bytes != null)
{
using (Stream stream = request.GetRequestStream())
{
stream.Write(bytes, 0, bytes.Length);
}
}
return request.GetResponse() as HttpWebResponse;
}
/// <summary>
/// 创建POST方式的HTTP请求
/// </summary>
/// <param name="url">请求的URL</param>
/// <param name="parameters">随同请求POST的参数名称及参数值字典</param>
/// <param name="timeout">请求的超时时间</param>
/// <param name="userAgent">请求的客户端浏览器信息,可以为空</param>
/// <param name="requestEncoding">发送HTTP请求时所用的编码</param>
/// <param name="cookies">随同HTTP请求发送的Cookie信息如果不需要身份验证可以为空</param>
/// <returns></returns>
public static HttpWebResponse CreatePostHttpResponse(string url, IDictionary<string, string> parameters, int? timeout, string userAgent, Encoding requestEncoding, CookieCollection cookies)
{
if (string.IsNullOrEmpty(url))
{
throw new ArgumentNullException("url");
}
if (requestEncoding == null)
{
throw new ArgumentNullException("requestEncoding");
}
HttpWebRequest request = null;
//如果是发送HTTPS请求
if (url.StartsWith("https", StringComparison.OrdinalIgnoreCase))
{
ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(CheckValidationResult);
request = WebRequest.Create(url) as HttpWebRequest;
request.ProtocolVersion = HttpVersion.Version10;
}
else
{
request = WebRequest.Create(url) as HttpWebRequest;
}
//request.Method = "POST";
//request.ContentType = "application/x-www-form-urlencoded";
request.Method = "GET";
//request.ContentType = "application/x-www-form-urlencoded";
if (!string.IsNullOrEmpty(userAgent))
{
request.UserAgent = userAgent;
}
else
{
request.UserAgent = DefaultUserAgent;
}
if (timeout.HasValue)
{
request.Timeout = timeout.Value;
}
if (cookies != null)
{
request.CookieContainer = new CookieContainer();
request.CookieContainer.Add(cookies);
}
//如果需要POST数据
if (!(parameters == null || parameters.Count == 0))
{
StringBuilder buffer = new StringBuilder();
int i = 0;
foreach (string key in parameters.Keys)
{
if (i > 0)
{
buffer.AppendFormat("&{0}={1}", key, parameters[key]);
}
else
{
buffer.AppendFormat("{0}={1}", key, parameters[key]);
}
i++;
}
byte[] data = requestEncoding.GetBytes(buffer.ToString());
using (Stream stream = request.GetRequestStream())
{
stream.Write(data, 0, data.Length);
}
}
return request.GetResponse() as HttpWebResponse;
}
/// <summary>
/// 创建POST方式的HTTP请求
/// </summary>
/// <param name="url">请求的URL</param>
/// <param name="parameters">随同请求POST的参数名称及参数值字典</param>
/// <param name="timeout">请求的超时时间</param>
/// <param name="userAgent">请求的客户端浏览器信息,可以为空</param>
/// <param name="requestEncoding">发送HTTP请求时所用的编码</param>
/// <param name="cookies">随同HTTP请求发送的Cookie信息如果不需要身份验证可以为空</param>
/// <returns></returns>
public static HttpWebResponse CreateApiPostHttpResponse(string url, IDictionary<string, object> parameters, int? timeout, string userAgent, Encoding requestEncoding, CookieCollection cookies, string token, IDictionary<string, string> headParams = null)
{
if (string.IsNullOrEmpty(url))
{
throw new ArgumentNullException("url");
}
if (requestEncoding == null)
{
throw new ArgumentNullException("requestEncoding");
}
HttpWebRequest request = null;
//如果是发送HTTPS请求
if (url.StartsWith("https", StringComparison.OrdinalIgnoreCase))
{
ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(CheckValidationResult);
request = WebRequest.Create(url) as HttpWebRequest;
request.ProtocolVersion = HttpVersion.Version10;
}
else
{
request = WebRequest.Create(url) as HttpWebRequest;
}
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
if (!string.IsNullOrEmpty(token))
request.Headers.Add("Authorization", "Bearer " + token);
if (headParams != null)
{
foreach (var header in headParams)
{
request.Headers.Add(header.Key, header.Value);
}
}
if (!string.IsNullOrEmpty(userAgent))
{
request.UserAgent = userAgent;
}
else
{
request.UserAgent = DefaultUserAgent;
}
if (timeout.HasValue)
{
request.Timeout = timeout.Value;
}
if (cookies != null)
{
request.CookieContainer = new CookieContainer();
request.CookieContainer.Add(cookies);
}
//如果需要POST数据
if (!(parameters == null || parameters.Count == 0))
{
StringBuilder buffer = new StringBuilder();
int i = 0;
foreach (string key in parameters.Keys)
{
if (i > 0)
{
buffer.AppendFormat("&{0}={1}", key, parameters[key]);
}
else
{
buffer.AppendFormat("{0}={1}", key, parameters[key]);
}
i++;
}
byte[] data = requestEncoding.GetBytes(buffer.ToString());
using (Stream stream = request.GetRequestStream())
{
stream.Write(data, 0, data.Length);
}
}
return request.GetResponse() as HttpWebResponse;
}
public static async Task<string> DoPostTask(string url, IDictionary<string, string> paramsa)
{
var handler = new HttpClientHandler() { AutomaticDecompression = DecompressionMethods.GZip };
using (var http = new HttpClient(handler))
{
var content = new FormUrlEncodedContent(paramsa);
var response = await http.PostAsync(url, content);
response.EnsureSuccessStatusCode();
return await response.Content.ReadAsStringAsync();
}
}
private static bool CheckValidationResult(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors errors)
{
return true; //总是接受
}
}
}

View File

@ -0,0 +1,78 @@
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Linq.Expressions;
using System.Reflection;
using System.Runtime.Serialization.Formatters.Binary;
using System.Security.Cryptography;
using System.Text;
namespace APT.Infrastructure.Core
{
public static class CloneExtends
{
public static T DeepCloneObject<T>(this T t) where T : class
{
JsonSerializerSettings js = new JsonSerializerSettings();
js.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
var obj = JsonConvert.SerializeObject(t,js);
return JsonConvert.DeserializeObject<T>(obj);
}
}
public static class EncryptHelper
{
/// <summary>
/// AES 加密
/// </summary>
/// <param name="str">明文(待加密)</param>
/// <param name="key">密文</param>
/// <returns></returns>
public static string AesEncrypt(string str, string key)
{
if (string.IsNullOrEmpty(str)) return null;
Byte[] toEncryptArray = Encoding.UTF8.GetBytes(str);
RijndaelManaged rm = new RijndaelManaged
{
Key = Encoding.UTF8.GetBytes(key),
Mode = CipherMode.ECB,
Padding = PaddingMode.PKCS7
};
ICryptoTransform cTransform = rm.CreateEncryptor();
Byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);
return Convert.ToBase64String(resultArray);
}
/// <summary>
/// AES 解密
/// </summary>
/// <param name="str">明文(待解密)</param>
/// <param name="key">密文</param>
/// <returns></returns>
public static string AesDecrypt(string str, string key)
{
if (string.IsNullOrEmpty(str)) return null;
Byte[] toEncryptArray = Convert.FromBase64String(str);
RijndaelManaged rm = new RijndaelManaged
{
Key = Encoding.UTF8.GetBytes(key),
Mode = CipherMode.ECB,
Padding = PaddingMode.PKCS7
};
ICryptoTransform cTransform = rm.CreateDecryptor();
Byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);
return Encoding.UTF8.GetString(resultArray);
}
}
}

View File

@ -0,0 +1,369 @@

using System;
using System.Collections.Generic;
using System.Diagnostics.Contracts;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Threading;
namespace APT.Infrastructure.Core
{
/// <summary>
/// 查询表达式辅助操作类
/// </summary>
public static class FilterHelper
{
#region fields
private static readonly Dictionary<FilterOperate, Func<Expression, Expression, Expression>> ExpressionDict;
#endregion
#region ctor.
private static MethodInfo _methodInfo;
private static MethodInfo MethodInfo
{
get
{
if (_methodInfo == null)
_methodInfo = typeof(String).GetMethod("CompareTo", new Type[] { typeof(String) });
return _methodInfo;
}
}
static FilterHelper()
{
ExpressionDict = new Dictionary<FilterOperate, Func<Expression, Expression, Expression>>
{
{FilterOperate.Equal, Expression.Equal},
{FilterOperate.NotEqual, Expression.NotEqual},
{FilterOperate.LessThan,(left,right)=>{
if (left.Type == typeof(string))
{
return Expression.LessThan(
Expression.Call(
left,
MethodInfo,
right),
Expression.Constant(0, typeof(Int32)) //比较String.CompareTo的返回结果和0来实现>=的效果
);
}
else
return Expression.LessThan(left,right); }
},
{FilterOperate.LessThanOrEqual,(left,right)=>{
if (left.Type == typeof(string))
{
return Expression.LessThanOrEqual(
Expression.Call(
left,
MethodInfo,
right),
Expression.Constant(0, typeof(Int32)) //比较String.CompareTo的返回结果和0来实现>=的效果
);
}
else
return Expression.LessThanOrEqual(left,right); }
},
{FilterOperate.GreaterThan,(left,right)=>{
if (left.Type == typeof(string))
{
return Expression.GreaterThan(
Expression.Call(
left,
MethodInfo,
right),
Expression.Constant(0, typeof(Int32)) //比较String.CompareTo的返回结果和0来实现>=的效果
);
}
else
return Expression.GreaterThan(left,right); }
},
{FilterOperate.GreaterThanOrEqual, (left,right)=>{
if (left.Type == typeof(string))
{
return Expression.GreaterThanOrEqual(
Expression.Call(
left,
MethodInfo,
right),
Expression.Constant(0, typeof(Int32)) //比较String.CompareTo的返回结果和0来实现>=的效果
);
}
else
return Expression.GreaterThanOrEqual(left,right);
} },
{FilterOperate.StartsWith, (left, right) =>
{
if (left.Type != typeof(string))
{
throw new NotSupportedException("“StartsWith”比较方式只支持字符串类型的数据");
}
return Expression.Call(left, typeof(string).GetMethod("StartsWith", new[] { typeof(string) }), right);
}
},
{FilterOperate.EndsWith, (left, right) =>
{
if (left.Type != typeof(string))
{
throw new NotSupportedException("“EndsWith”比较方式只支持字符串类型的数据");
}
return Expression.Call(left, typeof(string).GetMethod("EndsWith", new[] { typeof(string) }), right);
}
},
{FilterOperate.Contains, (left, right) =>
{
if (left.Type != typeof(string))
{
throw new NotSupportedException("“Contains”比较方式只支持字符串类型的数据");
}
return Expression.Call(left, typeof(string).GetMethod("Contains", new[] { typeof(string) }), right);
}
},
};
}
#endregion
#region methods
/// <summary>
/// 获取指定查询条件组的查询表达式
/// </summary>
/// <typeparam name="T">表达式实体类型</typeparam>
/// <param name="group">查询条件组如果为null则直接返回 true 表达式</param>
public static Expression<Func<T, bool>> GetExpression<T>(FilterGroup group, IUnitOfWork unitOfWork)
{
ParameterExpression param = Expression.Parameter(typeof(T), "m");
ResetGroupByAcronym<T>(group);
Expression body = GetExpressionBody(param, group, unitOfWork);
Expression<Func<T, bool>> expression = Expression.Lambda<Func<T, bool>>(body, param);
return expression;
}
private static void GetAcronymFeild(Type type, string[] array, int index, ref string acronymFeild)
{
var p = type.GetProperty(array[index]);
if (p != null && index == array.Length - 1)
{
AcronymFieldAttribute acronymAttr = null;
object[] attrs = p.GetCustomAttributes(typeof(AcronymFieldAttribute), true);
if (attrs.Length == 1)
acronymAttr = (AcronymFieldAttribute)attrs[0];
if (acronymAttr == null || string.IsNullOrEmpty(acronymAttr.AcronymFieldName)) return;
var acronymP = type.GetProperty(acronymAttr.AcronymFieldName);
if (acronymP == null) return;
array[array.Length - 1] = acronymP.Name;
acronymFeild = string.Join(".", array);
}
else if (p != null)
GetAcronymFeild(p.PropertyType, array, index + 1, ref acronymFeild);
}
private static void ResetGroupByAcronym<T>(FilterGroup group)
{
if (!group.IsAnd || group.Rules.Count == 1 && group.Groups.Count == 0)
{
List<FilterRule> filterRules = new List<FilterRule>();
foreach (var r in group.Rules)
{
var fs = r.Field.Split('.');
string acronymFeild = string.Empty;
GetAcronymFeild(typeof(T), fs, 0, ref acronymFeild);
if (!string.IsNullOrEmpty(acronymFeild))
filterRules.Add(new FilterRule()
{
Field = acronymFeild,
Operate = r.Operate,
Value = r.Value,
IsSysParamRule = r.IsSysParamRule,
});
}
if (filterRules.Any())
{
filterRules.ForEach(t => group.Rules.Add(t));
group.IsAnd = false;
}
}
if (group.Groups.Any())
foreach (var g in group.Groups)
ResetGroupByAcronym<T>(g);
}
/// <summary>
/// 获取指定查询条件的查询表达式
/// </summary>
/// <typeparam name="T">表达式实体类型</typeparam>
/// <param name="rule">查询条件如果为null则直接返回 true 表达式</param>
/// <returns></returns>
public static Expression<Func<T, bool>> GetExpression<T>(FilterRule rule = null)
{
ParameterExpression param = Expression.Parameter(typeof(T), "m");
Expression body = GetExpressionBody(param, rule);
Expression<Func<T, bool>> expression = Expression.Lambda<Func<T, bool>>(body, param);
return expression;
}
private static Expression GetExpressionBody(ParameterExpression param, FilterGroup group, IUnitOfWork unitOfWork)
{
Contract.Requires(param != null);
//如果无条件或条件为空,直接返回 true表达式
if (group == null || (group.Rules.Count == 0 && group.Groups.Count == 0))
{
return Expression.Constant(true);
}
var rules = group.Rules.Where(t => !t.IsSysParamRule).ToList();
var sysRules = group.Rules.Where(t => t.IsSysParamRule).ToList();
List<Expression> bodys = new List<Expression>();
if (rules.Any())
bodys.AddRange(rules.Select(rule => GetExpressionBody(param, rule)));
if (sysRules.Any())
{
if (unitOfWork == null) throw new Exception("参数异常");
Expression<Func<T_PF_PARAM, bool>> predicate = null;
if (group.IsAnd)
predicate = t => true;
else
predicate = t => false;
foreach (var item in sysRules)
{
Expression<Func<T_PF_PARAM, bool>> expression = null;
if (item.Operate == FilterOperate.Equal)
expression = t => t.CODE == item.Field && t.VALUE == item.Value.ToString();
else if (item.Operate == FilterOperate.Contains)
expression = t => t.CODE == item.Field && t.VALUE.Contains(item.Value.ToString());
else if (item.Operate == FilterOperate.GreaterThan)
expression = t => t.CODE == item.Field && string.Compare(t.VALUE, item.Value.ToString()) > 0;
else if (item.Operate == FilterOperate.GreaterThanOrEqual)
expression = t => t.CODE == item.Field && string.Compare(t.VALUE, item.Value.ToString()) >= 0;
else if (item.Operate == FilterOperate.LessThan)
expression = t => t.CODE == item.Field && string.Compare(t.VALUE, item.Value.ToString()) < 0;
else if (item.Operate == FilterOperate.LessThanOrEqual)
expression = t => t.CODE == item.Field && string.Compare(t.VALUE, item.Value.ToString()) <= 0;
else
throw new Exception("系统参数不支持该种类型的条件");
if (group.IsAnd)
predicate = predicate.And(expression);
else
predicate = predicate.Or(expression);
}
var ids = unitOfWork.GetEntities<T_PF_PARAM>(predicate, null, false).Select(t => t.ENTITY_ID.Value).ToList();
FilterGroup sysParamGroup = new FilterGroup(false);
if (ids.Any())
{
if (ids.Count >= 1210)//通过实测如果参数大于1210时会发生EF框架栈溢出暂时无解决方案。
throw new Exception("系统参数获取到的参数超过最大限制,不允许使用该功能");
foreach (var item in ids)
sysParamGroup.Rules.Add(new FilterRule("ID", item, FilterOperate.Equal));
}
else
{
sysParamGroup.Rules.Add(new FilterRule("ID", Guid.Empty, FilterOperate.Equal));
}
group.Groups.Add(sysParamGroup);
}
bodys.AddRange(group.Groups.Select(subGroup => GetExpressionBody(param, subGroup, unitOfWork)));
return group.IsAnd ? bodys.Aggregate(Expression.AndAlso) : bodys.Aggregate(Expression.OrElse);
}
private static Expression GetExpressionBody(ParameterExpression param, FilterRule rule)
{
//if (rule == null || rule.Value == null || string.IsNullOrEmpty(rule.Value.ToString()))
//{
// return Expression.Constant(true);
//}
LambdaExpression expression = GetPropertyLambdaExpression(param, rule);
Expression constant = ChangeTypeToExpression(rule, expression.Body.Type);
var expressionChange = ExpressionDict[rule.Operate];
return expressionChange(expression.Body, constant);
}
private static LambdaExpression GetPropertyLambdaExpression(ParameterExpression param, FilterRule rule)
{
string[] propertyNames = rule.Field.Split('.');
Expression propertyAccess = param;
Type type = param.Type;
foreach (string propertyName in propertyNames)
{
PropertyInfo property = type.GetProperty(propertyName);
if (property != null)
{
//Contract.Assume(property != null);
type = property.PropertyType;
propertyAccess = Expression.MakeMemberAccess(propertyAccess, property);
}
}
return Expression.Lambda(propertyAccess, param);
}
private static Expression ChangeTypeToExpression(FilterRule rule, Type conversionType)
{
Type elementType = conversionType.GetUnNullableType();
object value = null;
switch (elementType.Name.ToUpper())
{
case "GUID":
{
if (rule.Value != null && !string.IsNullOrEmpty(rule.Value.ToString()) && rule.Value.ToString().ToLower() != "null")
{
value = Guid.Parse(rule.Value.ToString());
}
//else
//{
// return Expression.Constant(null, typeof(Guid?));
//}
break;
}
default:
{
//if (rule.Value.ToString() == "null")
//{
// rule.Value = null;
//}
value = ConvertHelper.ChangeType(rule.Value, elementType);
break;
}
}
return Expression.Constant(value, conversionType);
}
#endregion
public static class ConvertHelper
{
#region = ChangeType =
public static object ChangeType(object obj, Type conversionType)
{
return ChangeType(obj, conversionType, Thread.CurrentThread.CurrentCulture);
}
public static object ChangeType(object obj, Type conversionType, IFormatProvider provider)
{
#region Nullable
if (obj != null && obj.ToString().ToLower() == "null") return null;
Type nullableType = Nullable.GetUnderlyingType(conversionType);
if (nullableType != null)
{
if (obj == null)
{
return null;
}
return Convert.ChangeType(obj, nullableType, provider);
}
#endregion
if (typeof(System.Enum).IsAssignableFrom(conversionType))
{
return Enum.Parse(conversionType, obj.ToString());
}
return Convert.ChangeType(obj, conversionType, provider);
}
#endregion
}
}
}

View File

@ -0,0 +1,109 @@
using System;
using System.ComponentModel;
using System.Security.Cryptography;
using System.Text;
namespace APT.Infrastructure.Core
{
/// <summary>
/// Hash工具类
/// </summary>
public static class HashUtil
{
/// <summary>
/// 计算字符串MD5值
/// </summary>
/// <param name="source">要计算的值</param>
/// <returns></returns>
public static string GetMD5(string source)
{
byte[] bytes = Encoding.UTF8.GetBytes(source);
return GetMD5(bytes);
}
/// <summary>
/// 计算byte数组MD5值
/// </summary>
/// <param name="bytes">要计算的byte数组</param>
/// <returns></returns>
public static string GetMD5(byte[] bytes)
{
StringBuilder builder = new StringBuilder();
MD5 hash = new MD5CryptoServiceProvider();
bytes = hash.ComputeHash(bytes);
foreach (byte b in bytes)
{
builder.AppendFormat("{0:X2}", b);
}
return builder.ToString();
}
/// <summary>
/// 产生随机字串,可用来自动生成密码,默认长度8位16进制
/// </summary>
/// <param name="len">长度</param>
/// <param name="type">字串类型 0 字母 1 数字 2 大写字母 3 小写字母 4 十六进制字母 5 混合</param>
/// <param name="addChars">额外字符</param>
/// <returns></returns>
public static string rand_string(int len = 8, RandomTypeEnum type = RandomTypeEnum.Hex, string addChars = "")
{
string chars = "";
switch (type) {
case RandomTypeEnum.Alphabet:
chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"+addChars;
break;
case RandomTypeEnum.Number:
chars = "0123456789";
break;
case RandomTypeEnum.Uppercase:
chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"+addChars;
break;
case RandomTypeEnum.Lowercase:
chars = "abcdefghijklmnopqrstuvwxyz"+ addChars;
break;
case RandomTypeEnum.Hex:
chars = "0123456789ABCDEF"+addChars;
break;
default :
// 默认去掉了容易混淆的字符oOLl和数字01要添加请使用addChars参数
chars = "ABCDEFGHIJKMNPQRSTUVWXYZabcdefghijkmnpqrstuvwxyz23456789"+ addChars;
break;
}
char[] constant = chars.ToCharArray();
System.Text.StringBuilder newRandom = new System.Text.StringBuilder(constant.Length);
Random rd = new Random();
for (int i = 0; i < len; i++)
{
newRandom.Append(constant[rd.Next(constant.Length)]);
}
return newRandom.ToString();
}
}
/// <summary>
/// 随机数类型
/// </summary>
public enum RandomTypeEnum
{
[Description("字母")]
Alphabet = 0,
[Description("数字")]
Number = 1,
[Description("大写字母")]
Uppercase = 2,
[Description("小写字母")]
Lowercase = 3,
[Description("十六进制字母")]
Hex = 4,
[Description("混合")]
Mix = 5
}
}

View File

@ -0,0 +1,181 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace APT.Infrastructure.Core
{
public static class LibUtils
{
/// <summary>
/// 转为字符串
/// </summary>
/// <param name="obj"></param>
/// <returns></returns>
public static string ToString(object obj)
{
if (obj == null||obj==DBNull.Value) return string.Empty;
return obj.ToString();
}
/// <summary>
/// 转为整数
/// </summary>
/// <param name="obj"></param>
/// <returns></returns>
public static int ToInt(object obj)
{
if (obj == null || obj == DBNull.Value) return 0;
try
{
return Convert.ToInt32(obj.ToString());
}
catch
{
}
return 0;
}
/// <summary>
/// 转为Decimal
/// </summary>
/// <param name="obj"></param>
/// <returns></returns>
public static decimal ToDecimal(object obj)
{
if (obj == null || obj == DBNull.Value) return 0;
try
{
return Convert.ToDecimal(obj.ToString());
}
catch
{
}
return 0;
}
/// <summary>
/// 转为日期
/// </summary>
/// <param name="obj"></param>
/// <returns></returns>
public static DateTime? ToDateTime(object obj)
{
if (obj == null || obj == DBNull.Value) return null;
try
{
return Convert.ToDateTime(obj.ToString());
}
catch
{
}
return null;
}
/// <summary>
/// 转为Guid
/// </summary>
/// <param name="obj"></param>
/// <returns></returns>
public static Guid? ToGuid(object obj)
{
if (obj == null || obj == DBNull.Value) return null;
try
{
return new Guid(obj.ToString());
}
catch
{
}
return null;
}
/// <summary>
/// 转为布尔类型
/// </summary>
/// <param name="obj"></param>
/// <returns></returns>
public static bool ToBoolean(object obj)
{
if (obj == null || obj == DBNull.Value) return false;
try
{
return Convert.ToBoolean(obj);
}
catch
{
string str = LibUtils.ToString(obj);
if (string.Compare(str, "是", true) == 0)
return true;
}
return false;
}
/// <summary>
/// 比较两个指定的 System.String 对象(其中忽略或考虑其大小写),并返回一个整数
/// </summary>
/// <param name="objA"></param>
/// <param name="objB"></param>
/// <param name="ignoreCase">是否忽略大小写</param>
/// <returns></returns>
public static int Compare(object objA, object objB, bool ignoreCase = true)
{
if (objA == null || objB == null) return 0;
return string.Compare(ToString(objA), ToString(objB), ignoreCase);
}
/// <summary>
/// 保留指定小数点位数
/// </summary>
/// <param name="qty"></param>
/// <param name="len"></param>
/// <param name="type"></param>
/// <returns></returns>
public static decimal Round(decimal qty,int len, LibRoundTypeEnum type)
{
if (type == LibRoundTypeEnum.)
{
if (len != 0)
{
var s = qty.ToString().Split('.');
if (s.Length >= 2)
{
var x = s[1].PadRight(6, '0');
qty = Convert.ToDecimal(s[0] + "." + x.Substring(0, len));
}
}
else
qty = Math.Ceiling(qty);
return qty;
}
else if (type == LibRoundTypeEnum.)
{
if (len != 0)
{
var s = qty.ToString().Split('.');
if (s.Length >= 2)
{
var x = s[1].PadRight(6, '0');
qty = Convert.ToDecimal(s[0] + "." + x.Substring(0, len));
if (x[len] != '0')
qty += 1 / (decimal)Math.Pow(10, len);
}
}
else
{
qty = Math.Floor(qty);
}
return qty;
}
return Math.Round(qty, len, MidpointRounding.AwayFromZero);
}
}
}

View File

@ -0,0 +1,121 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
namespace APT.Infrastructure.Core.Refctor
{
public class FuctionAttrDesc
{
public Guid ID { get; set; }
public string FuncName { get; set; }
public string AttrName { get; set; }
public List<ParmaterModel> Parmaters { get; set; }
}
public class ParmaterModel
{
public Guid ID { get; set; }
public string ParmaterName { get; set; }
public string ParmaterType { get; set; }
public string ParmaterAttr { get; set; }
}
public static class ReflectHelper
{
public static Type FindTypeInCurrentDomain(string typeName)
{
Type type = null;
//如果该类型已经装载
type = Type.GetType(typeName);
if (type != null)
{
return type;
}
//在EntryAssembly中查找
if (Assembly.GetEntryAssembly() != null)
{
type = Assembly.GetEntryAssembly().GetType(typeName);
if (type != null)
{
return type;
}
}
//在CurrentDomain的所有Assembly中查找
Assembly[] assemblyArray = AppDomain.CurrentDomain.GetAssemblies();
int assemblyArrayLength = assemblyArray.Length;
for (int i = 0; i < assemblyArrayLength; ++i)
{
type = assemblyArray[i].GetType(typeName);
if (type != null)
{
return type;
}
}
for (int i = 0; (i < assemblyArrayLength); ++i)
{
Type[] typeArray = assemblyArray[i].GetTypes();
int typeArrayLength = typeArray.Length;
for (int j = 0; j < typeArrayLength; ++j)
{
if (typeArray[j].Name.Equals(typeName))
{
return typeArray[j];
}
}
}
return type;
}
public static List<FuctionAttrDesc> GetClassMethodAttr(Type type)
{
List<FuctionAttrDesc> fads = new List<FuctionAttrDesc>();
MethodInfo[] properties = type.GetMethods();
if (properties.Any())
{
foreach (var p in properties)
{
object[] attrs = p.GetCustomAttributes(typeof(FuctionDescAttribute), true);
if (attrs.Length == 1)
{
var param = p.GetParameters();
var s = (FuctionDescAttribute)attrs[0];
FuctionAttrDesc fad = new FuctionAttrDesc();
fad.AttrName = s.FucName;
fad.FuncName = p.Name;
fad.Parmaters = new List<ParmaterModel>();
if (param.Length != s.ParamterDesc.Length)
{
//throw new Exception("参数个数不匹配");
}
for (var n = 0; n < param.Length; n++)
{
ParmaterModel mode = new ParmaterModel();
mode.ParmaterName = param[n].Name;
mode.ParmaterType = param[n].ParameterType.Name;
if (s.ParamterDesc.Length >= n + 1)
{
mode.ParmaterAttr = s.ParamterDesc[n];
}
fad.Parmaters.Add(mode);
}
fads.Add(fad);
}
}
}
return fads;
}
}
}

View File

@ -0,0 +1,100 @@
using System;
using System.Globalization;
using System.Text;
namespace APT.Infrastructure.Core
{
/// <summary>
/// 工具类
/// </summary>
public static class Util
{
/// <summary>
/// 新建一个 <see cref="Guid"/>与<see cref="DateTime"/>混合构成的适用于DB的可排序的<see cref="Guid"/>
/// </summary>
/// <returns>Comb Guid数据</returns>
public static Guid NewID()
{
byte[] guidArray = Guid.NewGuid().ToByteArray();
DateTime dtBase = new DateTime(1900, 1, 1);
DateTime dtNow = DateTime.Now;
//获取用于生成byte字符串的天数与毫秒数
TimeSpan days = new TimeSpan(dtNow.Ticks - dtBase.Ticks);
TimeSpan msecs = new TimeSpan(dtNow.Ticks - (new DateTime(dtNow.Year, dtNow.Month, dtNow.Day).Ticks));
//转换成byte数组
//注意SqlServer的时间计数只能精确到1/300秒
byte[] daysArray = BitConverter.GetBytes(days.Days);
byte[] msecsArray = BitConverter.GetBytes((long)(msecs.TotalMilliseconds / 3.333333));
//反转字节以符合SqlServer的排序
Array.Reverse(daysArray);
Array.Reverse(msecsArray);
//把字节复制到Guid中
Array.Copy(daysArray, daysArray.Length - 2, guidArray, guidArray.Length - 6, 2);
Array.Copy(msecsArray, msecsArray.Length - 4, guidArray, guidArray.Length - 4, 4);
return new Guid(guidArray);
}
/// <summary>
/// 加密密码
/// </summary>
/// <returns></returns>
public static string EncryptPassword(string userCode, string password)
{
var fixedMark = "-_-APT-_-";
String sourceString = string.Concat(fixedMark, userCode.ToUpper(), password);
return HashUtil.GetMD5(sourceString);
}
/// <summary>
/// 获取指定日期,在为一年中为第几周
/// </summary>
/// <param name="dt">指定时间</param>
/// <reutrn>返回第几周</reutrn>
public static int GetWeekOfYear(DateTime dt)
{
GregorianCalendar gc = new GregorianCalendar();
int weekOfYear = gc.GetWeekOfYear(dt, CalendarWeekRule.FirstDay, DayOfWeek.Monday);
return weekOfYear;
}
/// <summary>
///
/// </summary>
/// <param name="str"></param>
/// <returns></returns>
public static string UrlEncode(string str)
{
StringBuilder sb = new StringBuilder();
byte[] byStr = System.Text.Encoding.UTF8.GetBytes(str); //默认是System.Text.Encoding.Default.GetBytes(str)
for (int i = 0; i < byStr.Length; i++)
{
sb.Append(@"%" + Convert.ToString(byStr[i], 16));
}
return (sb.ToString());
}
/// <summary>
/// 判断byte数组是否相等
/// </summary>
/// <param name="bt1"></param>
/// <param name="bt2"></param>
/// <returns></returns>
public static bool CompareArray(byte[] bt1, byte[] bt2)
{
var len1 = bt1.Length;
var len2 = bt2.Length;
if (len1 != len2)
{
return false;
}
for (var i = 0; i < len1; i++)
{
if (bt1[i] != bt2[i])
return false;
}
return true;
}
}
}

View File

@ -0,0 +1,318 @@
using System.Collections.Generic;
namespace APT.Infrastructure.Core
{
public class WebUtils
{
/// <summary>
/// 通过唯一编号获得数据表
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="url"></param>
/// <param name="id"></param>
/// <returns></returns>
public static T Get<T>(string url, string id, string token, string tenant = "")
{
BaseFilter baseFilter = new BaseFilter();
baseFilter.FilterGroup.Rules.Add(new FilterRule("ID", id));
return Get<T>(url, baseFilter, token, SendType.Post, tenant);
}
public static T Get<T>(string url, string key, string value, string token = "", string tenant = "")
{
return Get<T>(url + $"?{key}={value}", token, tenant);
}
public static string Get(string url, string key, string value, string token = "", string tenant = "")
{
return Get(url + $"?{key}={value}", token, tenant);
}
public static string Get(string url, string token, string tenant = "")
{
var body = new ApiBody();
body.SendType = SendType.Get;
body.ApiUrl = url;
body.SendObj = null;
body.Token = token;
body.ResolvingResult = false;
if (!string.IsNullOrEmpty(tenant))
body.HeadParams.Add("Tenant", tenant);
var msg = "";
var result = ApiHelper.GetApiData(body, ref msg);
return result;
}
public static T Get<T>(string url, string token, string tenant = "")
{
var body = new ApiBody();
body.SendType = SendType.Get;
body.ApiUrl = url;
body.SendObj = null;
body.Token = token;
body.ResolvingResult = false;
if (!string.IsNullOrEmpty(tenant))
body.HeadParams.Add("Tenant", tenant);
int totalCount = 0;
var result = ApiHelper.GetApiData<T>(body, ref totalCount);
return result;
}
/// <summary>
/// 通过过滤条件获取一条数据
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="url"></param>
/// <param name="filter"></param>
/// <param name="isResolvingResult">是否直接转换对象</param>
/// <returns></returns>
public static T Get<T>(string url, BaseFilter filter, string token, SendType type = SendType.Post,
string tenant = "", bool isResolvingResult = false)
{
var body = new ApiBody();
body.SendType = type;
body.ApiUrl = url;
body.SendObj = filter;
body.Token = token;
body.ResolvingResult = isResolvingResult;
if (!string.IsNullOrEmpty(tenant))
body.HeadParams.Add("Tenant", tenant);
int totalCount = 0;
var result = ApiHelper.GetApiData<T>(body, ref totalCount);
return result;
}
public static bool Save<T>(string url, T t, string token, string tenant = "")
{
string msg = string.Empty;
return Save<T>(url, t, token, ref msg, tenant);
}
public static bool Save<T>(string url, T t, string token, ref string msg, string tenant = "")
{
var body = new ApiBody();
body.SendType = SendType.Post;
body.ApiUrl = url;
body.SendObj = t;
body.Token = token;
if (!string.IsNullOrEmpty(tenant))
body.HeadParams.Add("Tenant", tenant);
int totalCount = 0;
var result = ApiHelper.GetApiData(body, ref totalCount, ref msg);
return result;
}
/// <summary>
/// 执行某个接口
/// </summary>
/// <param name="url"></param>
/// <param name="filter"></param>
/// <returns></returns>
public static bool Do(string url, BaseFilter filter, string token, SendType type = SendType.Post, string tenant = "")
{
string ms = string.Empty;
return Do(url, filter, token, ref ms, type, tenant);
}
public static bool Do(string url, BaseFilter filter, string token, ref string msg, SendType type = SendType.Post, string tenant = "")
{
var body = new ApiBody();
body.SendType = type;
body.ApiUrl = url;
body.SendObj = filter;
body.Token = token;
if (!string.IsNullOrEmpty(tenant))
body.HeadParams.Add("Tenant", tenant);
int totalCount = 0;
var result = ApiHelper.GetApiData(body, ref totalCount, ref msg);
return result;
}
/// <summary>
///
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="url"></param>
/// <param name="id"></param>
/// <returns></returns>
public static bool Delete(string url, string id, string token, string tenant = "")
{
var body = new ApiBody();
body.SendType = SendType.Get;
body.ApiUrl = url;
body.Token = token;
if (!string.IsNullOrEmpty(tenant))
body.HeadParams.Add("Tenant", tenant);
IDictionary<string, object> parameters = new Dictionary<string, object>();
body.Params = parameters;
parameters.Add("id", id);
int totalCount = 0;
var result = ApiHelper.GetApiData(body, ref totalCount);
return result;
}
public static bool BatchDelete<T>(string url, string[] id, string token, string tenant = "")
{
var body = new ApiBody();
var sendStr = string.Join(",", id);
body.SendType = SendType.Get;
body.ApiUrl = url;
body.Token = token;
if (!string.IsNullOrEmpty(tenant))
body.HeadParams.Add("Tenant", tenant);
IDictionary<string, object> parameters = new Dictionary<string, object>();
parameters.Add("ids", sendStr);
body.Params = parameters;
int totalCount = 0;
var result = ApiHelper.GetApiData(body, ref totalCount);
return result;
}
public static List<T> List<T>(string url, BaseFilter filter, string token,
SendType type = SendType.Post, string tenant = "")
{
int totalCount = 0;
return List<T>(url, filter, ref totalCount, token, type, tenant);
}
public static List<T> List<T>(string url, BaseFilter filter, ref int totalCount,
string token, SendType type = SendType.Post, string tenant = "")
{
var body = new ApiBody();
body.SendType = type;
body.ApiUrl = url;
body.SendObj = filter;
body.Token = token;
if (!string.IsNullOrEmpty(tenant))
body.HeadParams.Add("Tenant", tenant);
var result = ApiHelper.GetApiData<List<T>>(body, ref totalCount);
return result;
}
public static PagedList<T> PageList<T>(string url, BasePageFilter filter,
string token, SendType type = SendType.Post, string tenant = "")
{
var startIndex = filter.PageIndex > 0 ? filter.PageIndex : filter.Start / filter.Limit + 1;
var body = new ApiBody();
body.SendType = type;
body.ApiUrl = url;
body.SendObj = filter;
body.Token = token;
if (!string.IsNullOrEmpty(tenant))
body.HeadParams.Add("Tenant", tenant);
int totalCount = 0;
var result = ApiHelper.GetApiData<List<T>>(body, ref totalCount);
PagedList<T> pageList = null;
if (result != null)
pageList = new PagedList<T>(result, startIndex, filter.Limit, totalCount);
return pageList;
}
/// <summary>
/// 通过过滤条件获取一条数据
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="url"></param>
/// <param name="filter"></param>
/// <returns></returns>
public static T Execute<T>(string url, object sendObj, string token,
SendType type = SendType.Post, IDictionary<string, string> headParams = null,
bool isResolvingResult = false, string tenant = "")
{
var body = new ApiBody();
body.SendType = type;
body.ApiUrl = url;
body.SendObj = sendObj;
body.Token = token;
body.HeadParams = headParams;
body.ResolvingResult = isResolvingResult;
if (!string.IsNullOrEmpty(tenant))
body.HeadParams.Add("Tenant", tenant);
int totalCount = 0;
var result = ApiHelper.GetApiData<T>(body, ref totalCount);
return result;
}
/// <summary>
/// 获取二进制图片
/// </summary>
/// <param name="url"></param>
/// <param name="sendObj"></param>
/// <param name="token"></param>
/// <param name="type"></param>
/// <param name="headParams"></param>
/// <param name="isResolvingResult"></param>
/// <param name="tenant"></param>
/// <returns></returns>
public static byte[] GetPicture(string url, object sendObj, string token,
SendType type = SendType.Post, IDictionary<string, string> headParams = null,
bool isResolvingResult = false, string tenant = "")
{
var body = new ApiBody();
body.SendType = type;
body.ApiUrl = url;
body.SendObj = sendObj;
body.Token = token;
body.HeadParams = headParams;
body.ResolvingResult = isResolvingResult;
if (!string.IsNullOrEmpty(tenant))
body.HeadParams.Add("Tenant", tenant);
var result = ApiHelper.ApiPicture(body);
return result;
}
/// <summary>
/// isResolvingResult=true
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="url"></param>
/// <param name="sendObj"></param>
/// <param name="token"></param>
/// <param name="type"></param>
/// <param name="headParams"></param>
/// <returns></returns>
public static T ExecuteByResolving<T>(string url, object sendObj, string token, SendType type = SendType.Post,
IDictionary<string, string> headParams = null, string tenant = "")
{
return Execute<T>(url, sendObj, token, type, headParams, true, tenant);
}
/// <summary>
///
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="url"></param>
/// <param name="bodyParams"></param>
/// <param name="token"></param>
/// <param name="type"></param>
/// <param name="headParams"></param>
/// <param name="isResolvingResult"></param>
/// <returns></returns>
public static T Execute<T>(string url, IDictionary<string, object> bodyParams,
string token, SendType type = SendType.Post, IDictionary<string, string> headParams = null,
bool isResolvingResult = false, string tenant = "")
{
var body = new ApiBody();
body.SendType = type;
body.ApiUrl = url;
body.Params = bodyParams;
body.HeadParams = headParams;
body.ResolvingResult = isResolvingResult;
body.Token = token;
if (!string.IsNullOrEmpty(tenant))
body.HeadParams.Add("Tenant", tenant);
int totalCount = 0;
var result = ApiHelper.GetApiData<T>(body, ref totalCount);
return result;
}
/// <summary>
/// isResolvingResult=true
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="url"></param>
/// <param name="bodyParams"></param>
/// <param name="token"></param>
/// <param name="type"></param>
/// <param name="headParams"></param>
/// <returns></returns>
public static T ExecuteByResolving<T>(string url, IDictionary<string, object> bodyParams,
string token, SendType type = SendType.Post, IDictionary<string, string> headParams = null, string tenant = "")
{
return Execute<T>(url, bodyParams, token, type, headParams, true, tenant);
}
}
}

View File

@ -0,0 +1,16 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace APT.Infrastructure.Core
{
public interface ILibMessageManager
{
void AddMessage(EFMessageType type, string message);
void AddMessage(EFMessageType type, string code, string message);
void AddMessage(EFApiActionMessage message);
void StoreMessage<T>(EFApiActionResult<T> ret);
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,105 @@
using System;
namespace APT.Infrastructure.Core
{
/// <summary>
/// 日志记录器
/// </summary>
public interface ILog4netLogger : IDependInject
{
/// <summary>
/// 写入<see cref="LogLevel.Debug"/>日志消息
/// </summary>
/// <param name="message">日志消息</param>
void Debug(object message);
/// <summary>
/// 写入<see cref="LogLevel.Debug"/>格式化日志消息
/// </summary>
/// <param name="format">日志消息格式</param>
/// <param name="args">格式化参数</param>
void Debug(string format, params object[] args);
/// <summary>
/// 写入<see cref="LogLevel.Info"/>日志消息
/// </summary>
/// <param name="message">日志消息</param>
void Info(object message);
/// <summary>
/// 写入格式化日志消息
/// </summary>
/// <param name="format">日志消息格式</param>
/// <param name="args">格式化参数</param>
void Info(string format, params object[] args);
/// <summary>
/// 写入日志消息
/// </summary>
/// <param name="message">日志消息</param>
void Warn(object message);
/// <summary>
/// 写入格式化日志消息
/// </summary>
/// <param name="format">日志消息格式</param>
/// <param name="args">格式化参数</param>
void Warn(string format, params object[] args);
/// <summary>
/// 写入<see cref="LogLevel.Error"/>日志消息
/// </summary>
/// <param name="message">日志消息</param>
void Error(object message);
/// <summary>
/// 写入<see cref="LogLevel.Error"/>格式化日志消息
/// </summary>
/// <param name="format">日志消息格式</param>
/// <param name="args">格式化参数</param>
void Error(string format, params object[] args);
/// <summary>
/// 写入<see cref="LogLevel.Error"/>日志消息,并记录异常
/// </summary>
/// <param name="message">日志消息</param>
/// <param name="exception">异常</param>
void Error(object message, Exception exception);
/// <summary>
/// 写入<see cref="LogLevel.Error"/>格式化日志消息,并记录异常
/// </summary>
/// <param name="format">日志消息格式</param>
/// <param name="exception">异常</param>
/// <param name="args">格式化参数</param>
void Error(string format, Exception exception, params object[] args);
/// <summary>
/// 写入<see cref="LogLevel.Fatal"/>日志消息
/// </summary>
/// <param name="message">日志消息</param>
void Fatal(object message);
/// <summary>
/// 写入<see cref="LogLevel.Fatal"/>格式化日志消息
/// </summary>
/// <param name="format">日志消息格式</param>
/// <param name="args">格式化参数</param>
void Fatal(string format, params object[] args);
/// <summary>
/// 写入<see cref="LogLevel.Fatal"/>日志消息,并记录异常
/// </summary>
/// <param name="message">日志消息</param>
/// <param name="exception">异常</param>
void Fatal(object message, Exception exception);
/// <summary>
/// 写入<see cref="LogLevel.Fatal"/>格式化日志消息,并记录异常
/// </summary>
/// <param name="format">日志消息格式</param>
/// <param name="exception">异常</param>
/// <param name="args">格式化参数</param>
void Fatal(string format, Exception exception, params object[] args);
}
}

View File

@ -0,0 +1,96 @@
using log4net;
using System;
using System.Reflection;
namespace APT.Infrastructure.Core
{
/// <summary>
/// log4net日志记录器
/// </summary>
public class Log4netLogger : ILog4netLogger
{
private readonly log4net.ILog _logger;
#region ctor.
public Log4netLogger(string name)
{
_logger = LogManager.GetLogger(Assembly.GetEntryAssembly(), name);
}
#endregion
#region ILog
public void Debug(object message)
{
_logger.Debug(message);
}
public void Debug(string format, params object[] args)
{
_logger.DebugFormat(format, args);
}
public void Info(object message)
{
_logger.Info(message);
}
public void Info(string format, params object[] args)
{
_logger.InfoFormat(format, args);
}
public void Warn(object message)
{
_logger.Warn(message);
}
public void Warn(string format, params object[] args)
{
_logger.WarnFormat(format, args);
}
public void Error(object message)
{
_logger.Error(message);
}
public void Error(string format, params object[] args)
{
_logger.ErrorFormat(format, args);
}
public void Error(object message, Exception exception)
{
_logger.Error(message, exception);
}
public void Error(string format, Exception exception, params object[] args)
{
_logger.ErrorFormat(format, exception, args);
}
public void Fatal(object message)
{
_logger.Fatal(message);
}
public void Fatal(string format, params object[] args)
{
_logger.FatalFormat(format, args);
}
public void Fatal(object message, Exception exception)
{
_logger.Fatal(message, exception);
}
public void Fatal(string format, Exception exception, params object[] args)
{
_logger.FatalFormat(format, exception, args);
}
#endregion
}
}

View File

@ -0,0 +1,85 @@
using APT.Infrastructure.Core;
using log4net;
using Microsoft.AspNetCore.Mvc.Filters;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace APT.Infrastructure.Core
{
public class LogAttribute : Attribute, IAsyncActionFilter
{
/// <summary>
/// 添加操作日志 liyouming
/// </summary>
/// <param name="context"></param>
/// <param name="next"></param>
/// <returns></returns>
public async Task OnActionExecutionAsync(Microsoft.AspNetCore.Mvc.Filters.ActionExecutingContext context, ActionExecutionDelegate next)
{
try
{
string actionArguments = context.ActionArguments.ToJson();
var resultContext = await next();
string url = resultContext.HttpContext.Request.Host + resultContext.HttpContext.Request.Path + resultContext.HttpContext.Request.QueryString;
string method = resultContext.HttpContext.Request.Method;
dynamic result = resultContext.Result.GetType().Name == "EmptyResult" ? new { Value = "EmptyResult" } : resultContext.Result as dynamic;
var userHeads = resultContext.HttpContext.Request.Headers;
var userid = string.Empty;
var username = string.Empty;
if (userHeads.ContainsKey("userid"))
{
userid = userHeads["userid"].ToString();
}
if (userHeads.ContainsKey("username"))
{
username = userHeads["username"].ToString();
}
string response = JsonConvert.SerializeObject(result.Value);
//var str = $"用户ID:[{userid}],姓名:[{username}],api地址[{url}],方法:[{method}],接口参数:[{actionArguments}],应答:[{response}]";
//var points = new Point
//{
// Name = "ApiLog",
// Timestamp = DateTime.Now,
// Tags = new Dictionary<string, object>()
//{
// { "Id", Guid.NewGuid()}
//},
// Fields = new Dictionary<string, object>()
//{
// { "UserId", userid },
// { "UserName", username },
// { "ApiUrl", url },
// { "Method", method },
// { "ActionArguments", actionArguments },
// { "Response", response }
//},
//};
LoggerManager.GetLogger().Info("时序数据库开始写入数据");
//var ret = await InfluxDbHelper.InfluxDbClient.Client.WriteAsync(points, InfluxDbHelper.InfluxLogDbName);
//LoggerManager.GetLogger().Info("时序数据库插入结果:" + ret.Success);
}
catch (Exception ex)
{
LoggerManager.GetLogger().Error(Infrastructure.Core.LogHelper.GetCurSourceFileName() + " - " + LogHelper.GetLineNum() + ":" + ex.Message);
//throw;
}
finally
{
await next.Invoke();
}
}
}
}

View File

@ -0,0 +1,21 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace APT.Infrastructure.Core
{
public static class LogHelper
{
/// /// 取得当前源码的哪一行 /// ///
public static int GetLineNum()
{ System.Diagnostics.StackTrace st = new System.Diagnostics.StackTrace(1, true); return st.GetFrame(0).GetFileLineNumber(); }
/// /// 取当前源码的源文件名 /// ///
public static string GetCurSourceFileName()
{ System.Diagnostics.StackTrace st = new System.Diagnostics.StackTrace(1, true); return st.GetFrame(0).GetFileName(); }
}
}

View File

@ -0,0 +1,35 @@
using System.Collections.Concurrent;
namespace APT.Infrastructure.Core
{
/// <summary>
/// Logger管理器
/// </summary>
public static class LoggerManager
{
private static readonly ConcurrentDictionary<string, ILog4netLogger> Loggers;
private static readonly object LockObj = new object();
static LoggerManager()
{
Loggers = new ConcurrentDictionary<string, ILog4netLogger>();
}
public static ILog4netLogger GetLogger()
{
return GetLogger("Application");
}
public static ILog4netLogger GetLogger(string name)
{
ILog4netLogger logger;
if (Loggers.TryGetValue(name, out logger))
{
return logger;
}
logger = new Log4netLogger(name);
Loggers[name] = logger;
return logger;
}
}
}

View File

@ -0,0 +1,891 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
namespace APT.Infrastructure.Core
{
[AttributeUsage(AttributeTargets.Class, Inherited = true)]
public class UnionKeyAttribute : Attribute
{
private string _unionKey = string.Empty;
public string UnionKey
{
get { return _unionKey; }
}
public UnionKeyAttribute(string unionKey)
{
_unionKey = unionKey;
}
}
[AttributeUsage(AttributeTargets.Property, Inherited = true)]
public class CUniqueAttribute : Attribute
{
private string _displayName = string.Empty;
private bool _isCheckOrg = false;
private bool _isCheckEmpty = true;
public string DisplayName
{
get { return _displayName; }
}
public bool IsCheckOrg
{
get { return _isCheckOrg; }
}
public bool IsCheckEmpty
{
get { return _isCheckEmpty; }
}
public CUniqueAttribute()
: this(string.Empty)
{
}
public CUniqueAttribute(bool isCheckOrg)
: this(string.Empty, isCheckOrg)
{
}
public CUniqueAttribute(string displayName)
: this(displayName, false)
{
}
public CUniqueAttribute(string displayName, bool isCheckOrg)
: this(displayName, isCheckOrg, true)
{
}
public CUniqueAttribute(string displayName, bool isCheckOrg, bool isCheckEmpty)
: base()
{
_displayName = displayName;
_isCheckOrg = isCheckOrg;
_isCheckEmpty = isCheckEmpty;
}
}
/// <summary>
/// 枚举属性
/// </summary>
[AttributeUsage(AttributeTargets.Property, Inherited = true)]
public class EnumNameAttribute : Attribute
{
private string _enumName = string.Empty;
public string EnumName
{
get { return _enumName; }
}
public EnumNameAttribute(string enumName)
: base()
{
_enumName = enumName;
}
}
/// <summary>
/// 枚举项排序索引小标 属性
/// </summary>
[AttributeUsage(AttributeTargets.All, Inherited = true)]
public class EnumSortIndexAttribute : Attribute
{
private int _sortIndex = 0;
public int SortIndex
{
get { return _sortIndex; }
}
public EnumSortIndexAttribute()
: base()
{
}
public EnumSortIndexAttribute(int sortIndex)
: base()
{
_sortIndex = sortIndex;
}
}
/// <summary>
/// 枚举项排序索引小标 属性
/// </summary>
[AttributeUsage(AttributeTargets.All, Inherited = true)]
public class IgnoreT4Attribute : Attribute
{
public IgnoreT4Attribute()
: base()
{
}
}
[AttributeUsage(AttributeTargets.All, Inherited = true)]
public class DataRuleFieldAttribute : Attribute
{
private string _fileName = "";
public DataRuleFieldAttribute(string fileName)
: base()
{
_fileName = fileName;
}
public string FileName { get { return _fileName; } }
}
/// <summary>
/// 枚举属性
/// </summary>
[AttributeUsage(AttributeTargets.Property, Inherited = true)]
public class CodeRuleAttribute : Attribute
{
private int[] _codeRuleTypes = null;
private bool _isCheckState = true;
public bool IsCheckState { get { return _isCheckState; } }
public int[] CodeRuleTypes
{
get { return _codeRuleTypes; }
}
public CodeRuleAttribute(params int[] codeRuleTypes)
: this(true, codeRuleTypes)
{
}
public CodeRuleAttribute(bool isCheckState, params int[] codeRuleTypes)
: base()
{
_isCheckState = isCheckState;
_codeRuleTypes = codeRuleTypes;
}
}
/// <summary>
/// 数据记录
/// </summary>
[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = true)]
public sealed class DataRecordAttribute : Attribute
{
/// <summary>
/// 数据记录
/// </summary>
/// <param name="direction">数据方向</param>
public DataRecordAttribute(DataDirection direction)
{
Direction = direction;
}
/// <summary>
/// 数据方向
/// </summary>
public DataDirection Direction { get; set; }
}
public class OperateCodeAttribute : Attribute
{
/// <summary>
/// 初始化一个<see cref="OperateCodeAttribute"/>类型的新实例
/// </summary>
public OperateCodeAttribute(String code)
{
Code = code;
}
/// <summary>
/// 获取 操作符
/// </summary>
public String Code { get; private set; }
}
/// <summary>
/// 首字母简称属性
/// </summary>
[AttributeUsage(AttributeTargets.Property, Inherited = true)]
public class AcronymFieldAttribute : Attribute
{
private string _acronymFieldName = null;
public string AcronymFieldName
{
get { return _acronymFieldName; }
}
public AcronymFieldAttribute(string acronymFieldName)
: base()
{
_acronymFieldName = acronymFieldName;
}
}
/// <summary>
/// 编辑表单显示字段属性
/// 用于定义字段是否显示在编辑表单中
/// </summary>
[AttributeUsage(AttributeTargets.Property, Inherited = true)]
public class FormFieldEditAttribute : Attribute
{
private string _displayName;
private int _num;
/// <summary>
/// 字段显示文本
/// </summary>
[Description("字段显示文本")]
public string DisplayName { get { return _displayName; } }
/// <summary>
/// 顺序索引
/// </summary>
[Description("顺序索引")]
public int Num { get { return _num; } }
/// <summary>
///
/// </summary>
/// <param name="diplayName">字段显示文本</param>
/// <param name="num">顺序索引</param>
public FormFieldEditAttribute(string diplayName, int num)
: base()
{
_displayName = diplayName;
_num = num;
}
/// <summary>
///
/// </summary>
/// <param name="diplayName">字段显示文本</param>
public FormFieldEditAttribute(string diplayName)
: this(diplayName, 0)
{
}
public FormFieldEditAttribute()
: this(string.Empty)
{
}
}
/// <summary>
/// 列表表单显示字段属性
/// 用于定义字段是否显示在列表表单中
/// </summary>
[AttributeUsage(AttributeTargets.Property, Inherited = true)]
public class FormFieldTableAttribute : Attribute
{
private string _displayName;
private int _num;
/// <summary>
/// 字段显示文本
/// </summary>
[Description("字段显示文本")]
public string DisplayName { get { return _displayName; } }
/// <summary>
/// 顺序索引
/// </summary>
[Description("顺序索引")]
public int Num { get { return _num; } }
/// <summary>
///
/// </summary>
/// <param name="diplayName">字段显示文本</param>
/// <param name="num">顺序索引</param>
public FormFieldTableAttribute(string displayName, int num)
: base()
{
_displayName = displayName;
_num = num;
}
/// <summary>
///
/// </summary>
/// <param name="diplayName">字段显示文本</param>
public FormFieldTableAttribute(string displayName)
: this(displayName, 0)
{
}
public FormFieldTableAttribute(int num)
: this(string.Empty, num)
{
}
public FormFieldTableAttribute()
: this(string.Empty)
{
}
}
/// <summary>
/// 树表单显示字段属性
/// 用于定义字段是否显示在树表单中
/// </summary>
[AttributeUsage(AttributeTargets.Property, Inherited = true)]
public class FormFieldTreeAttribute : Attribute
{
private string _displayName;
private int _num;
/// <summary>
/// 字段显示文本
/// </summary>
[Description("字段显示文本")]
public string DisplayName { get { return _displayName; } }
/// <summary>
/// 顺序索引
/// </summary>
[Description("顺序索引")]
public int Num { get { return _num; } }
/// <summary>
///
/// </summary>
/// <param name="diplayName">字段显示文本</param>
/// <param name="num">顺序索引</param>
public FormFieldTreeAttribute(string displayName, int num)
: base()
{
_displayName = displayName;
_num = num;
}
/// <summary>
///
/// </summary>
/// <param name="diplayName">字段显示文本</param>
public FormFieldTreeAttribute(string displayName)
: this(displayName, 0)
{
}
public FormFieldTreeAttribute(int num)
: this(string.Empty, num)
{
}
public FormFieldTreeAttribute()
: this(string.Empty)
{
}
}
/// <summary>
/// 列表单显示查询字段属性
/// 用于定义字段是否显示在列表表单查询中
/// </summary>
[AttributeUsage(AttributeTargets.Property, Inherited = true)]
public class FormFieldQueryAttribute : Attribute
{
private string _displayName;
private int _num;
/// <summary>
/// 字段显示文本
/// </summary>
[Description("字段显示文本")]
public string DisplayName { get { return _displayName; } }
/// <summary>
/// 顺序索引
/// </summary>
[Description("顺序索引")]
public int Num { get { return _num; } }
/// <summary>
///
/// </summary>
/// <param name="diplayName">字段显示文本</param>
public FormFieldQueryAttribute(string displayName, int num)
: base()
{
_displayName = displayName;
_num = num;
}
/// <summary>
///
/// </summary>
/// <param name="diplayName">字段显示文本</param>
public FormFieldQueryAttribute(string displayName)
: this(displayName, 0)
{
}
public FormFieldQueryAttribute(int num)
: this(string.Empty, num)
{
}
public FormFieldQueryAttribute()
: this(string.Empty)
{
}
}
/// <summary>
/// 编辑表单显示字段属性
/// 用于定义字段是否显示在编辑表单中
/// </summary>
[AttributeUsage(AttributeTargets.Class, Inherited = true)]
public class FormClassEditAttribute : Attribute
{
private string _displayName;
/// <summary>
/// 字段显示文本
/// </summary>
[Description("字段显示文本")]
public string DisplayName { get { return _displayName; } }
/// <summary>
///
/// </summary>
/// <param name="diplayName">字段显示文本</param>
public FormClassEditAttribute(string diplayName)
: base()
{
_displayName = diplayName;
}
public FormClassEditAttribute()
: this(string.Empty)
{
}
}
/// <summary>
/// 列表表单显示字段属性
/// 用于定义字段是否显示在列表表单中
/// </summary>
[AttributeUsage(AttributeTargets.Class, Inherited = true)]
public class FormClassTableAttribute : Attribute
{
private string _displayName;
/// <summary>
/// 字段显示文本
/// </summary>
[Description("字段显示文本")]
public string DisplayName { get { return _displayName; } }
/// <summary>
///
/// </summary>
/// <param name="diplayName">字段显示文本</param>
public FormClassTableAttribute(string displayName)
: base()
{
_displayName = displayName;
}
public FormClassTableAttribute()
: this(string.Empty)
{
}
}
/// <summary>
/// 树表单显示字段属性
/// 用于定义字段是否显示在树表单中
/// </summary>
[AttributeUsage(AttributeTargets.Class, Inherited = true)]
public class FormClassTreeAttribute : Attribute
{
private string _displayName;
/// <summary>
/// 字段显示文本
/// </summary>
[Description("字段显示文本")]
public string DisplayName { get { return _displayName; } }
/// <summary>
///
/// </summary>
/// <param name="diplayName">字段显示文本</param>
public FormClassTreeAttribute(string displayName)
: base()
{
_displayName = displayName;
}
public FormClassTreeAttribute()
: this(string.Empty)
{
}
}
/// <summary>
/// 字段长度属性
/// </summary>
[AttributeUsage(AttributeTargets.Property, Inherited = true)]
public class DataFieldLengthAttribute : Attribute
{
private int _length = 0;
/// <summary>
/// 字段长度
/// </summary>
[Description("字段长度")]
public int Length
{
get { return _length; }
}
/// <summary>
///
/// </summary>
/// <param name="length">字段长度</param>
public DataFieldLengthAttribute(int length)
: base()
{
_length = length;
}
}
/// <summary>
/// 字段忽略属性
/// </summary>
[AttributeUsage(AttributeTargets.Property, Inherited = true)]
public class DataFieldIngoreAttribute : Attribute
{
public DataFieldIngoreAttribute()
: base()
{
}
}
/// <summary>
/// 类索引属性
/// 用于联合索引
/// </summary>
[AttributeUsage(AttributeTargets.Class, Inherited = true, AllowMultiple = true)]
public class DataClassIndexAttribute : Attribute
{
private string[] _fields = null;
bool _isUnique = false;
/// <summary>
/// 索引字段列表
/// </summary>
[Description("索引字段列表")]
public string[] Fields
{
get { return _fields; }
}
/// <summary>
/// 是否唯一索引
/// </summary>
[Description("是否唯一索引")]
public bool IsUnique { get { return _isUnique; } }
/// <summary>
///
/// </summary>
/// <param name="fields">索引字段列表</param>
/// <param name="isUnique">是否唯一索引</param>
public DataClassIndexAttribute(string[] fields, bool isUnique)
: base()
{
if (fields == null || fields.Length == 0) throw new Exception("参数异常");
_fields = fields;
_isUnique = isUnique;
}
/// <summary>
///
/// </summary>
/// <param name="fields">索引字段列表</param>
public DataClassIndexAttribute(string[] fields)
: this(fields, false)
{
}
}
/// <summary>
/// 字段索引属性
/// </summary>
[AttributeUsage(AttributeTargets.Property, Inherited = true)]
public class DataFieldIndexAttribute : Attribute
{
bool _isUnique = false;
string[] _fields = null;
/// <summary>
/// 是否唯一索引
/// </summary>
[Description("是否唯一索引")]
public bool IsUnique { get { return _isUnique; } }
[Description("是否唯一索引")]
public string[] Fields { get { return _fields; } }
/// <summary>
///
/// </summary>
/// <param name="isUnique">是否唯一索引</param>
public DataFieldIndexAttribute(bool isUnique,params string[] fields)
: base()
{
_isUnique = isUnique;
_fields = fields;
}
public DataFieldIndexAttribute()
: this(false)
{
}
}
/// <summary>
/// 字段必填属性
/// </summary>
[AttributeUsage(AttributeTargets.Property, Inherited = true)]
public class DataFieldRequireAttribute : Attribute
{
private bool _isRequire = true;
/// <summary>
/// 是否必填
/// </summary>
public bool IsRequire
{
get { return _isRequire; }
}
/// <summary>
///
/// </summary>
/// <param name="isRequire">是否必填</param>
public DataFieldRequireAttribute(bool isRequire)
: base()
{
_isRequire = isRequire;
}
public DataFieldRequireAttribute()
: this(true)
{
}
}
/// <summary>
/// 字段外键属性
/// 在外键ID字段上使用
/// </summary>
[AttributeUsage(AttributeTargets.Property, Inherited = true)]
public class DataFieldForeignKeyAttribute : Attribute
{
private string _navFieldName = null;
private string _masterFieldName = string.Empty;
private bool _isOneOnOne = false;
/// <summary>
/// 导航字段名称
/// </summary>
[Description("导航字段名称")]
public string NavFieldName
{
get { return _navFieldName; }
}
/// <summary>
/// 主表导航字段名称
/// </summary>
[Description("主表导航字段名称")]
public string MasterFieldName
{
get { return _masterFieldName; }
}
/// <summary>
/// 主表导航字段名称
/// </summary>
[Description("是否一对一")]
public bool IsOneOnOne
{
get { return _isOneOnOne; }
}
/// <summary>
///
/// </summary>
/// <param name="navFieldName">导航字段名称</param>
/// <param name="masterFieldName">主表导航字段名称</param>
/// <param name="isOneOnOne">是否1对1</param>
public DataFieldForeignKeyAttribute(string navFieldName, string masterFieldName, bool isOneOnOne = false)
: base()
{
if (string.IsNullOrEmpty(navFieldName)) throw new Exception("参数异常");
_navFieldName = navFieldName;
_masterFieldName = masterFieldName;
_isOneOnOne = isOneOnOne;
}
/// <summary>
///
/// </summary>
/// <param name="navFieldName">导航字段名称</param>
/// <param name="isOneOnOne">是否1对1</param>
public DataFieldForeignKeyAttribute(string navFieldName, bool isOneOnOne = false)
: this(navFieldName, string.Empty, isOneOnOne)
{
}
}
/// <summary>
/// 字段外键属性
/// 在主表的外键导航属性上使用
/// </summary>
[AttributeUsage(AttributeTargets.Property, Inherited = true)]
public class DataFieldForeignKeyForMasterAttribute : Attribute
{
private string _navFieldName = null;
private string _idFieldName = null;
private bool _isOneOnOne = false;
/// <summary>
/// 导航字段名称
/// </summary>
[Description("导航字段名称")]
public string NavFieldName
{
get { return _navFieldName; }
}
/// <summary>
/// ID字段名称
/// </summary>
[Description("ID字段名称")]
public string IdFieldName
{
get { return _idFieldName; }
}
/// <summary>
/// 主表导航字段名称
/// </summary>
[Description("是否一对一")]
public bool IsOneOnOne
{
get { return _isOneOnOne; }
}
/// <summary>
///
/// </summary>
/// <param name="idFieldName">ID字段名称</param>
/// <param name="navFieldName">导航字段名称</param>
/// <param name="isOneOnOne">是否一对一</param>
public DataFieldForeignKeyForMasterAttribute(string idFieldName, string navFieldName, bool isOneOnOne = false)
: base()
{
if (string.IsNullOrEmpty(idFieldName)) throw new Exception("参数异常");
_navFieldName = navFieldName;
_idFieldName = idFieldName;
_isOneOnOne = isOneOnOne;
}
/// <summary>
///
/// </summary>
/// <param name="idFieldName">ID字段名称</param>
/// <param name="isOneOnOne">是否一对一</param>
public DataFieldForeignKeyForMasterAttribute(string idFieldName, bool isOneOnOne = false)
: this(idFieldName, string.Empty, isOneOnOne)
{
}
}
/// <summary>
///获取方法的描述
/// </summary>
[AttributeUsage(AttributeTargets.Method, Inherited = true)]
public class FuctionDescAttribute : Attribute
{
private string _fucName = null;
private string[] _paramterDesc ;
/// <summary>
/// 导航字段名称
/// </summary>
[Description("函数名")]
public string FucName
{
get { return _fucName; }
}
/// <summary>
/// 参数说明
/// </summary>
[Description("参数说明")]
public string[] ParamterDesc
{
get { return _paramterDesc; }
}
/// <summary>
/// 构造函数
/// </summary>
/// <param name="fucName">方法描述</param>
/// <param name="paramterDesc">参数描述</param>
public FuctionDescAttribute(string fucName, params string[] paramterDesc)
: base()
{
_fucName = fucName;
_paramterDesc = paramterDesc;
}
}
/// <summary>
/// 字段外键属性
/// 在外键ID字段上使用
/// </summary>
[AttributeUsage(AttributeTargets.Property, Inherited = true)]
public class UnionForeignKeyAttribute : Attribute
{
private string _unionKeyName = null;
private string _masterFieldName = string.Empty;
/// <summary>
/// 导航字段名称
/// </summary>
[Description("导航字段名称")]
public string UnionKeyName
{
get { return _unionKeyName; }
}
/// <summary>
/// 主表导航字段名称
/// </summary>
[Description("主表导航字段名称")]
public string MasterFieldName
{
get { return _masterFieldName; }
}
/// <summary>
///
/// </summary>
/// <param name="navFieldName">导航字段名称</param>
/// <param name="masterFieldName">主表导航字段名称</param>
public UnionForeignKeyAttribute(string unionKeyName, string masterFieldName)
: base()
{
if (string.IsNullOrEmpty(unionKeyName)) throw new Exception("参数异常");
_unionKeyName = unionKeyName;
_masterFieldName = masterFieldName;
}
/// <summary>
///
/// </summary>
/// <param name="navFieldName">导航字段名称</param>
public UnionForeignKeyAttribute(string navFieldName)
: this(navFieldName, string.Empty)
{
}
}
}

View File

@ -0,0 +1,160 @@
using System;
using System.Collections.Generic;
using System.Linq;
namespace APT.Infrastructure.Core
{
/// <summary>
/// 基础过滤器
/// </summary>
public class BaseFilter
{
public BaseFilter(Guid? orgId, FilterOrgTypeEnum orgType)
{
this.OrgId = orgId;
FilterGroup = new FilterGroup();
Include = new List<string>();
Orders = new List<DataOrder>();
SelectField = new List<string>();
OrgRule = new List<Guid>();
this.OrgType = orgType;
Level = -1;//无限
}
public BaseFilter(Guid? orgId)
{
OrgId = orgId;
FilterGroup = new FilterGroup();
Include = new List<string>();
SelectField = new List<string>();
Orders = new List<DataOrder>();
DataRule = new List<string>();
OrgRule = new List<Guid>();
this.OrgType = FilterOrgTypeEnum.;
Level = -1;//无限级
}
public BaseFilter()
{
FilterGroup = new FilterGroup();
Include = new List<string>();
Orders = new List<DataOrder>();
SelectField = new List<string>();
DataRule = new List<string>();
OrgRule = new List<Guid>();
this.OrgType = FilterOrgTypeEnum.;
Level = -1;//无限级
}
public Guid GetOrgId()
{
return OrgId ?? Guid.Empty;
}
/// <summary>
/// 菜单参数
/// </summary>
public string MenuParameter { get; set; }
/// <summary>
/// 组织类型
/// </summary>
public FilterOrgTypeEnum OrgType { get; set; }
/// <summary>
/// 是否加载全部数据
/// </summary>
public bool All { get; set; }
/// <summary>
/// 公司编号
/// </summary>
public Guid? OrgId { get; set; }
/// <summary>
/// 数据层级
/// </summary>
public int Level { get; set; }
/// <summary>
/// 树结构是否加载上级数据
/// </summary>
public bool IsParentData { get; set; }
/// <summary>
/// 是否不跟踪
/// </summary>
public bool IsNoTranking { get; set; }
/// <summary>
/// 是否查询多个库
/// </summary>
public bool IsMultipleDb { get; set; }
/// <summary>
/// 知否指定数据库
/// </summary>
public bool IsSpecifyDb { get; set; }
/// <summary>
/// 指定数据库连接
/// </summary>
public string SpecifyDbConn{ get; set; }
/// <summary>
/// 指定租户
/// </summary>
public string SpecifyTenant { get; set; }
/// <summary>
/// 授权组织编号,多个可以逗号隔开
/// 本组织可以查询授权组织数据
/// </summary>
public string AuthOrgCodes { get; set; }
/// <summary>窗体模板ID</summary>
public Guid? FormId { get; set; }
/// <summary>
/// 排序字段
/// </summary>
public string Sort { get; set; }
/// <summary>
/// 排序方式
/// </summary>
public DbOrder Order { get; set; }
/// <summary>
/// 过滤条件
/// </summary>
public FilterGroup FilterGroup { get; set; }
/// <summary>
/// 关联表
/// </summary>
public ICollection<string> Include { get; set; }
/// <summary>
/// 查询/更新字段
/// </summary>
public ICollection<string> SelectField { get; set; }
/// <summary>
/// 多字段排序
/// </summary>
public ICollection<DataOrder> Orders { get; set; }
/// <summary>
/// 数据权限
/// </summary>
public ICollection<string> DataRule { get; set; }
/// <summary>
/// 组织权限
/// </summary>
public List<Guid> OrgRule { get; set; }
/// <summary>
/// 是否忽略数据权限
/// </summary>
public bool IgnoreDataRule { get; set; }
/// <summary>
/// 是否忽略组织权限
/// </summary>
public bool IgnoreOrgRule { get; set; } = true;
/// <summary>
/// 树选择的ID
/// </summary>
public ICollection<string> TreeSelected { get; set; }
}
}

View File

@ -0,0 +1,46 @@
namespace APT.Infrastructure.Core
{
/// <summary>
/// 分页条件
/// </summary>
public class BasePageFilter : BaseFilter
{
/// <summary>
/// 获取第Start+1页的数据
/// </summary>
public int Start
{
get
{
return (PageIndex - 1) * Limit;
}
}
/// <summary>
/// 每一个分页获取的条数
/// </summary>
public int Limit { get; set; }
/// <summary>
/// 第几页
/// </summary>
public int PageIndex { get; set; }
/// <summary>
/// 是否查询所有数据
/// </summary>
public bool IsAllLoad { get; set; }
public BasePageFilter()
{
}
public BasePageFilter(int PageIndex, int PageSize)
{
this.PageIndex = PageIndex;
this.Limit = PageSize;
}
}
}

View File

@ -0,0 +1,38 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace APT.Infrastructure.Core
{
public class CodeException: Exception
{
public string _code = null;
public string Code
{
get { return _code; }
set { _code = value; }
}
public CodeException()
{
}
public CodeException(string message) : this(string.Empty, message, null)
{
}
public CodeException(string code, string message):this(code,message,null)
{
}
public CodeException(string message, Exception innerException):this(string.Empty,message,innerException)
{
}
public CodeException(string code, string message, Exception innerException)
:base(message,innerException)
{
this._code = code;
}
}
}

View File

@ -0,0 +1,24 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace APT.Infrastructure.Core
{
public class CodeRuleParam
{
public CodeRuleParam()
{
this.IsUpdate = true;
this.Time = DateTime.Now;
}
public Guid? OrgId { get; set; }
public int CodeType { get; set; }
public int Count { get; set; }
public bool IsUpdate { get; set; }
public DateTime Time { get; set; }
}
}

View File

@ -0,0 +1,27 @@
using System;
namespace APT.Infrastructure.Core
{
/// <summary>
/// 排序条件
/// </summary>
public class DataOrder
{
/// <summary>
/// 获取或设置 字段名称
/// </summary>
public String Field { get; set; }
/// <summary>
/// 获取或设置 过滤值
/// </summary>
public DbOrder Order { get; set; }
}
}

Some files were not shown because too many files have changed in this diff Show More