Pārlūkot izejas kodu

初始化中间件服务

devin.zhu@doverfs.com 1 gadu atpakaļ
revīzija
708bc75a11
64 mainītis faili ar 2743 papildinājumiem un 0 dzēšanām
  1. 25 0
      IMES-Middleware-Platform/.dockerignore
  2. 63 0
      IMES-Middleware-Platform/.gitattributes
  3. 400 0
      IMES-Middleware-Platform/.gitignore
  4. 37 0
      IMES-Middleware-Platform/IMES-Middleware-Platform.sln
  5. 21 0
      IMES-Middleware-Platform/LICENSE
  6. 27 0
      IMES-Middleware-Platform/README.md
  7. 18 0
      IMES-Middleware-Platform/build/pkg.props
  8. 3 0
      IMES-Middleware-Platform/src/Directory.Build.props
  9. 5 0
      IMES-Middleware-Platform/src/hosts/IMES-Middleware-Platform.Host/.config/dotnet-tools.json
  10. 8 0
      IMES-Middleware-Platform/src/hosts/IMES-Middleware-Platform.Host/Configs/appconfig.Development.json
  11. 113 0
      IMES-Middleware-Platform/src/hosts/IMES-Middleware-Platform.Host/Configs/appconfig.json
  12. 2 0
      IMES-Middleware-Platform/src/hosts/IMES-Middleware-Platform.Host/Configs/cacheconfig.Development.json
  13. 13 0
      IMES-Middleware-Platform/src/hosts/IMES-Middleware-Platform.Host/Configs/cacheconfig.json
  14. 1 0
      IMES-Middleware-Platform/src/hosts/IMES-Middleware-Platform.Host/Configs/createdbsql.txt
  15. 6 0
      IMES-Middleware-Platform/src/hosts/IMES-Middleware-Platform.Host/Configs/dbconfig.Development.json
  16. 89 0
      IMES-Middleware-Platform/src/hosts/IMES-Middleware-Platform.Host/Configs/dbconfig.json
  17. 2 0
      IMES-Middleware-Platform/src/hosts/IMES-Middleware-Platform.Host/Configs/jwtconfig.Development.json
  18. 12 0
      IMES-Middleware-Platform/src/hosts/IMES-Middleware-Platform.Host/Configs/jwtconfig.json
  19. 3 0
      IMES-Middleware-Platform/src/hosts/IMES-Middleware-Platform.Host/Configs/ossconfig.Development.json
  20. 91 0
      IMES-Middleware-Platform/src/hosts/IMES-Middleware-Platform.Host/Configs/ossconfig.json
  21. 2 0
      IMES-Middleware-Platform/src/hosts/IMES-Middleware-Platform.Host/Configs/ratelimitconfig.Development.json
  22. 33 0
      IMES-Middleware-Platform/src/hosts/IMES-Middleware-Platform.Host/Configs/ratelimitconfig.json
  23. 2 0
      IMES-Middleware-Platform/src/hosts/IMES-Middleware-Platform.Host/Configs/uploadconfig.Development.json
  24. 38 0
      IMES-Middleware-Platform/src/hosts/IMES-Middleware-Platform.Host/Configs/uploadconfig.json
  25. 14 0
      IMES-Middleware-Platform/src/hosts/IMES-Middleware-Platform.Host/Dockerfile
  26. 51 0
      IMES-Middleware-Platform/src/hosts/IMES-Middleware-Platform.Host/IMES-Middleware-Platform.Host.csproj
  27. 6 0
      IMES-Middleware-Platform/src/hosts/IMES-Middleware-Platform.Host/InitData/App/app_module.json
  28. 7 0
      IMES-Middleware-Platform/src/hosts/IMES-Middleware-Platform.Host/InitData/App/app_module.tenant.json
  29. 69 0
      IMES-Middleware-Platform/src/hosts/IMES-Middleware-Platform.Host/Program.cs
  30. 29 0
      IMES-Middleware-Platform/src/hosts/IMES-Middleware-Platform.Host/Properties/launchSettings.json
  31. 9 0
      IMES-Middleware-Platform/src/hosts/IMES-Middleware-Platform.Host/appsettings.Development.json
  32. 60 0
      IMES-Middleware-Platform/src/hosts/IMES-Middleware-Platform.Host/appsettings.json
  33. 61 0
      IMES-Middleware-Platform/src/hosts/IMES-Middleware-Platform.Host/nlog.config
  34. 3 0
      IMES-Middleware-Platform/src/hosts/IMES-Middleware-Platform.Host/wwwroot/swagger/mini-profiler.css
  35. 2 0
      IMES-Middleware-Platform/src/hosts/IMES-Middleware-Platform.Host/wwwroot/swagger/mini-profiler.js
  36. 17 0
      IMES-Middleware-Platform/src/platform/IMES-Middleware-Platform.Api/Core/Attributes/AppTransactionAttribute.cs
  37. 13 0
      IMES-Middleware-Platform/src/platform/IMES-Middleware-Platform.Api/Core/Consts/ApiConsts.cs
  38. 18 0
      IMES-Middleware-Platform/src/platform/IMES-Middleware-Platform.Api/Core/Consts/CacheKeys.cs
  39. 16 0
      IMES-Middleware-Platform/src/platform/IMES-Middleware-Platform.Api/Core/Consts/DbKeys.cs
  40. 18 0
      IMES-Middleware-Platform/src/platform/IMES-Middleware-Platform.Api/Core/Handlers/AppCustomTaskHandler.cs
  41. 14 0
      IMES-Middleware-Platform/src/platform/IMES-Middleware-Platform.Api/Core/Repositories/AppRepositoryBase.cs
  42. 13 0
      IMES-Middleware-Platform/src/platform/IMES-Middleware-Platform.Api/Domain/Module/Dto/ModuleGetPageDto.cs
  43. 11 0
      IMES-Middleware-Platform/src/platform/IMES-Middleware-Platform.Api/Domain/Module/IModuleRepository.cs
  44. 20 0
      IMES-Middleware-Platform/src/platform/IMES-Middleware-Platform.Api/Domain/Module/ModuleEntity.cs
  45. 23 0
      IMES-Middleware-Platform/src/platform/IMES-Middleware-Platform.Api/Domain/Module/Output/ModuleDataOutput.cs
  46. 27 0
      IMES-Middleware-Platform/src/platform/IMES-Middleware-Platform.Api/IMES-Middleware-Platform.Api.csproj
  47. 238 0
      IMES-Middleware-Platform/src/platform/IMES-Middleware-Platform.Api/IMES-Middleware-Platform.Api.xml
  48. 211 0
      IMES-Middleware-Platform/src/platform/IMES-Middleware-Platform.Api/IMES_Middleware_Platform.Api.xml
  49. 27 0
      IMES-Middleware-Platform/src/platform/IMES-Middleware-Platform.Api/Repositories/CustomGenerateData.cs
  50. 90 0
      IMES-Middleware-Platform/src/platform/IMES-Middleware-Platform.Api/Repositories/CustomSyncData.cs
  51. 16 0
      IMES-Middleware-Platform/src/platform/IMES-Middleware-Platform.Api/Repositories/Module/ModuleRepository.cs
  52. 28 0
      IMES-Middleware-Platform/src/platform/IMES-Middleware-Platform.Api/Services/Module/IModuleService.cs
  53. 13 0
      IMES-Middleware-Platform/src/platform/IMES-Middleware-Platform.Api/Services/Module/Input/ModuleAddInput.cs
  54. 23 0
      IMES-Middleware-Platform/src/platform/IMES-Middleware-Platform.Api/Services/Module/Input/ModuleUpdateInput.cs
  55. 127 0
      IMES-Middleware-Platform/src/platform/IMES-Middleware-Platform.Api/Services/Module/ModuleService.cs
  56. 11 0
      IMES-Middleware-Platform/src/platform/IMES-Middleware-Platform.Api/Services/Module/Output/ModuleGetOutput.cs
  57. 18 0
      IMES-Middleware-Platform/src/platform/IMES-Middleware-Platform.Api/Services/Module/Output/ModuleListOutput.cs
  58. 207 0
      IMES-Middleware-Platform/src/tests/IMES-Middleware-Platform.Tests/BaseControllerTest.cs
  59. 40 0
      IMES-Middleware-Platform/src/tests/IMES-Middleware-Platform.Tests/BaseTest.cs
  60. 71 0
      IMES-Middleware-Platform/src/tests/IMES-Middleware-Platform.Tests/Controllers/ModuleControllerTest.cs
  61. 23 0
      IMES-Middleware-Platform/src/tests/IMES-Middleware-Platform.Tests/IMES-Middleware-Platform.Tests.csproj
  62. 28 0
      IMES-Middleware-Platform/src/tests/IMES-Middleware-Platform.Tests/Repositories/ModuelRepositoryTest.cs
  63. 29 0
      IMES-Middleware-Platform/src/tests/IMES-Middleware-Platform.Tests/ResultOutput.cs
  64. 28 0
      IMES-Middleware-Platform/src/tests/IMES-Middleware-Platform.Tests/Services/ModuleServiceTest.cs

+ 25 - 0
IMES-Middleware-Platform/.dockerignore

@@ -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

+ 63 - 0
IMES-Middleware-Platform/.gitattributes

@@ -0,0 +1,63 @@
+###############################################################################
+# Set default behavior to automatically normalize line endings.
+###############################################################################
+* text=auto
+
+###############################################################################
+# Set default behavior for command prompt diff.
+#
+# This is need for earlier builds of msysgit that does not have it on by
+# default for csharp files.
+# Note: This is only used by command line
+###############################################################################
+#*.cs     diff=csharp
+
+###############################################################################
+# Set the merge driver for project and solution files
+#
+# Merging from the command prompt will add diff markers to the files if there
+# are conflicts (Merging from VS is not affected by the settings below, in VS
+# the diff markers are never inserted). Diff markers may cause the following 
+# file extensions to fail to load in VS. An alternative would be to treat
+# these files as binary and thus will always conflict and require user
+# intervention with every merge. To do so, just uncomment the entries below
+###############################################################################
+#*.sln       merge=binary
+#*.csproj    merge=binary
+#*.vbproj    merge=binary
+#*.vcxproj   merge=binary
+#*.vcproj    merge=binary
+#*.dbproj    merge=binary
+#*.fsproj    merge=binary
+#*.lsproj    merge=binary
+#*.wixproj   merge=binary
+#*.modelproj merge=binary
+#*.sqlproj   merge=binary
+#*.wwaproj   merge=binary
+
+###############################################################################
+# behavior for image files
+#
+# image files are treated as binary by default.
+###############################################################################
+#*.jpg   binary
+#*.png   binary
+#*.gif   binary
+
+###############################################################################
+# diff behavior for common document formats
+# 
+# Convert binary document formats to text before diffing them. This feature
+# is only available from the command line. Turn it on by uncommenting the 
+# entries below.
+###############################################################################
+#*.doc   diff=astextplain
+#*.DOC   diff=astextplain
+#*.docx  diff=astextplain
+#*.DOCX  diff=astextplain
+#*.dot   diff=astextplain
+#*.DOT   diff=astextplain
+#*.pdf   diff=astextplain
+#*.PDF   diff=astextplain
+#*.rtf   diff=astextplain
+#*.RTF   diff=astextplain

+ 400 - 0
IMES-Middleware-Platform/.gitignore

@@ -0,0 +1,400 @@
+## 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
+
+**/wwwroot/upload

+ 37 - 0
IMES-Middleware-Platform/IMES-Middleware-Platform.sln

@@ -0,0 +1,37 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 17
+VisualStudioVersion = 17.5.33424.131
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "IMES-Middleware-Platform.Host", "src\hosts\IMES-Middleware-Platform.Host\IMES-Middleware-Platform.Host.csproj", "{748033B7-70FA-49C1-AF78-739BF97EFB7E}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "IMES-Middleware-Platform.Api", "src\platform\IMES-Middleware-Platform.Api\IMES-Middleware-Platform.Api.csproj", "{B2726C3E-88A0-46B5-99B0-0E2868CD0648}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "IMES-Middleware-Platform.Tests", "src\tests\IMES-Middleware-Platform.Tests\IMES-Middleware-Platform.Tests.csproj", "{D0878ED0-BC11-46DA-BE26-0003E879048D}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Any CPU = Debug|Any CPU
+		Release|Any CPU = Release|Any CPU
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{748033B7-70FA-49C1-AF78-739BF97EFB7E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{748033B7-70FA-49C1-AF78-739BF97EFB7E}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{748033B7-70FA-49C1-AF78-739BF97EFB7E}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{748033B7-70FA-49C1-AF78-739BF97EFB7E}.Release|Any CPU.Build.0 = Release|Any CPU
+		{B2726C3E-88A0-46B5-99B0-0E2868CD0648}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{B2726C3E-88A0-46B5-99B0-0E2868CD0648}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{B2726C3E-88A0-46B5-99B0-0E2868CD0648}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{B2726C3E-88A0-46B5-99B0-0E2868CD0648}.Release|Any CPU.Build.0 = Release|Any CPU
+		{D0878ED0-BC11-46DA-BE26-0003E879048D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{D0878ED0-BC11-46DA-BE26-0003E879048D}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{D0878ED0-BC11-46DA-BE26-0003E879048D}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{D0878ED0-BC11-46DA-BE26-0003E879048D}.Release|Any CPU.Build.0 = Release|Any CPU
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+	GlobalSection(ExtensibilityGlobals) = postSolution
+		SolutionGuid = {8CC68056-E583-4E31-AA47-D4C998714DBA}
+	EndGlobalSection
+EndGlobal

+ 21 - 0
IMES-Middleware-Platform/LICENSE

@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2020 imes_middleware_platform
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.

+ 27 - 0
IMES-Middleware-Platform/README.md

@@ -0,0 +1,27 @@
+
+一个基于.Net Core开发的权限管理系统,后续会增加更多实用的功能。
+
+### 在线体验
+演示地址:https://www.admin.imes_middleware_platform.net/
+
+文档地址:https://www.imes_middleware_platform.net/
+
+*********************************************************
+### 项目下载后,直接编译运行项目
+```
+Ctrl + F5
+```
+
+#### Tips:
+
+
+
+```
+如果你想换数据库,修改Admin.Core项目下的 configs/dbconfig.Development.json 文件
+
+  //数据库类型
+  "type": 0,
+  //连接字符串
+  "connectionString": ""
+
+```

+ 18 - 0
IMES-Middleware-Platform/build/pkg.props

@@ -0,0 +1,18 @@
+<Project>
+  <PropertyGroup>
+    <Version>3.7.0</Version>
+	<TargetFramework>net7.0</TargetFramework>
+	<GeneratePackageOnBuild>false</GeneratePackageOnBuild>
+	<GenerateDocumentationFile>true</GenerateDocumentationFile>
+	<Authors>xiaoxue</Authors>
+	<Company>zhontai</Company>
+	<PackageZhonTaiVersion>3.7.0</PackageZhonTaiVersion>
+	<PackageFreeSqlVersion>3.2.698</PackageFreeSqlVersion>
+	<PackageLicenseExpression>MIT</PackageLicenseExpression>
+	<PackageProjectUrl>https://admin.zhontai.net</PackageProjectUrl>
+	<RepositoryUrl>https://github.com/zhontai/Admin.Core</RepositoryUrl>
+	<RepositoryType>git</RepositoryType>
+	<PackageTags>ZhonTai Admin Api;MVC;WebApi;HttpApi;Api;</PackageTags>
+	<NoWarn>1701;1702;1591</NoWarn>
+  </PropertyGroup>
+</Project>

+ 3 - 0
IMES-Middleware-Platform/src/Directory.Build.props

@@ -0,0 +1,3 @@
+<Project>
+	<Import Project="..\build\pkg.props" />
+</Project>

+ 5 - 0
IMES-Middleware-Platform/src/hosts/IMES-Middleware-Platform.Host/.config/dotnet-tools.json

@@ -0,0 +1,5 @@
+{
+  "version": 1,
+  "isRoot": true,
+  "tools": {}
+}

+ 8 - 0
IMES-Middleware-Platform/src/hosts/IMES-Middleware-Platform.Host/Configs/appconfig.Development.json

@@ -0,0 +1,8 @@
+{
+  //跨域地址
+  "corUrls": [ ],
+  "IdentityServer": {
+    //地址
+    "url": "https://localhost:5000"
+  }
+}

+ 113 - 0
IMES-Middleware-Platform/src/hosts/IMES-Middleware-Platform.Host/Configs/appconfig.json

@@ -0,0 +1,113 @@
+{
+  //应用程序类型Controllers ControllersWithViews MVC
+  "appType": "Controllers",
+  //Api地址
+  "urls": [ "http://*:8008" ],
+  //跨域地址
+  "corUrls": [],
+  //程序集名称
+  "assemblyNames": [ "IMES_Middleware_Platform.Api" ],
+  //租户
+  "tenant": true,
+  //分布式事务唯一标识app,为空则不生成分布式事务表
+  "distributeKey": "",
+  //验证
+  "validate": {
+    //登录
+    "login": false,
+    //权限
+    "permission": false,
+    //数据权限
+    "dataPermission": true
+  },
+  //Swagger接口文档,访问路径/swagger
+  "swagger": {
+    //启用
+    "enable": true,
+    //启用枚举架构过滤器
+    "enableEnumSchemaFilter": true,
+    //启用接口排序文档过滤器
+    "enableOrderTagsDocumentFilter": true,
+    //启用枚举属性名
+    "enableJsonStringEnumConverter": false,
+    //启用SchemaId命名空间
+    "enableSchemaIdNamespace": false,
+    //程序集列表,用于启用SchemaId命名空间
+    "assemblyNameList": [],
+    //路由前缀,如配置微服务文档地址:doc/module/swagger
+    "routePrefix": "middle/swagger",
+    //地址
+    "url": "http://localhost:8008",
+    //项目列表
+    "projects": [
+      {
+        "name": "IMES_Middleware_Platform",
+        "code": "app",
+        "version": "v3.7.0",
+        "description": "IMES_Middleware_Platform"
+      }
+    ]
+  },
+  //新版接口文档展示
+  "apiUI": {
+    //启用
+    "enable": true,
+    //路由前缀,如配置微服务文档地址:doc/module
+    "routePrefix": "middle",
+    //页脚
+    "footer": {
+      "enable": false,
+      "content": "Copyright<a-icon type=\"copyright\" /> 2022-<a target=\"_blank\" href=\"https://www.zhontai.net\">中台Admin</a>"
+    }
+  },
+  //MiniProfiler性能分析器
+  "miniProfiler": false,
+  //统一认证授权服务器
+  "identityServer": {
+    //启用
+    "enable": false,
+    //地址,开发认证地址前往appconfig.Development.json修改
+    "url": "https://localhost:5000",
+    //启用Https
+    "requireHttpsMetadata": true,
+    //受众
+    "audience": "admin.server.api"
+  },
+  //面向切面编程
+  "aop": {
+    //事物
+    "transaction": true
+  },
+  //日志
+  "log": {
+    //操作日志
+    "operation": false
+  },
+  //限流
+  "rateLimit": false,
+  //验证码
+  "varifyCode": {
+    //启用
+    "enable": true,
+    //字体列表
+    "fonts": [ "Times New Roman", "Verdana", "Arial", "Gungsuh", "Impact" ]
+  },
+  //默认密码
+  "defaultPassword": "111111",
+  //动态api
+  "dynamicApi": {
+    //结果格式化
+    "formatResult": true
+  },
+  //实现标准标识密码哈希
+  "passwordHasher": false,
+  //最大请求大小byte
+  "maxRequestBodySize": 104857600,
+  //健康检查
+  "healthChecks": {
+    //启用
+    "enable": true,
+    //访问路径
+    "path": "/app/health"
+  }
+}

+ 2 - 0
IMES-Middleware-Platform/src/hosts/IMES-Middleware-Platform.Host/Configs/cacheconfig.Development.json

@@ -0,0 +1,2 @@
+{
+}

+ 13 - 0
IMES-Middleware-Platform/src/hosts/IMES-Middleware-Platform.Host/Configs/cacheconfig.json

@@ -0,0 +1,13 @@
+{
+  //缓存类型 Memory = 0,Redis = 1
+  "type": "Memory",
+  //限流缓存类型 Memory = 0,Redis = 1
+  "typeRateLimit": "Memory",
+  //Redis配置
+  "redis": {
+    //连接字符串
+    "connectionString": "127.0.0.1:6379,password=,defaultDatabase=0",
+    //限流连接字符串
+    "connectionStringRateLimit": "127.0.0.1:6379,password=,defaultDatabase=0"
+  }
+}

+ 1 - 0
IMES-Middleware-Platform/src/hosts/IMES-Middleware-Platform.Host/Configs/createdbsql.txt

@@ -0,0 +1 @@
+

+ 6 - 0
IMES-Middleware-Platform/src/hosts/IMES-Middleware-Platform.Host/Configs/dbconfig.Development.json

@@ -0,0 +1,6 @@
+{
+  //监听所有操作
+  "monitorCommand": false,
+  //监听Curd操作
+  "curd": true
+}

+ 89 - 0
IMES-Middleware-Platform/src/hosts/IMES-Middleware-Platform.Host/Configs/dbconfig.json

@@ -0,0 +1,89 @@
+{
+  //数据库注册键
+  "key": "appdb",
+  //程序集名称,自动获取实体表,为空则通过ConfigureFreeSql自定义配置
+  "assemblyNames": [ "IMES_Middleware_Platform.Api" ],
+
+  //监听所有操作
+  "monitorCommand": false,
+  //监听Curd操作
+  "curd": true,
+  //监听同步结构脚本
+  "syncStructureSql": false,
+  //监听同步数据Curd操作
+  "syncDataCurd": false,
+
+  //建库
+  "createDb": false,
+  //SqlServer,PostgreSQL,Oracle,OdbcOracle,OdbcSqlServer,OdbcMySql,OdbcPostgreSQL,Odbc,OdbcDameng,MsAccess
+  //建库连接字符串
+  //MySql "Server=localhost; Port=3306; Database=mysql; Uid=root; Pwd=pwd; Charset=utf8mb4;"
+  //SqlServer "Data Source=.;User Id=sa;Password=pwd;Initial Catalog=master;TrustServerCertificate=true;Pooling=true;Min Pool Size=1"
+  //PostgreSQL "Host=localhost;Port=5432;Username=postgres;Password=; Database=postgres;Pooling=true;Minimum Pool Size=1"
+  //Oracle "user id=SYS;password=pwd; data source=//127.0.0.1:1521/XE;Pooling=true;Min Pool Size=1"
+  "createDbConnectionString": "Server=localhost; Port=3306; Database=mysql; Uid=root; Pwd=pwd; Charset=utf8mb4;",
+  //建库脚本,复杂建库脚本可放到createdbsql.txt中
+  //MySql "CREATE DATABASE `appdb` CHARACTER SET 'utf8mb4' COLLATE 'utf8mb4_general_ci'"
+  //SqlServer "CREATE DATABASE [appdb]"
+  //PostgreSQL "CREATE DATABASE \"appdb\" WITH ENCODING = 'UTF8'"
+  "createDbSql": "CREATE DATABASE `appdb` CHARACTER SET 'utf8mb4' COLLATE 'utf8mb4_general_ci'",
+
+  //同步结构
+  "syncStructure": false,
+  //同步数据
+  "syncData": false,
+  //同步更新数据
+  "sysUpdateData": false,
+  //同步所有表["ad_dict_type", "ad_dict", "ad_user",  "ad_user_staff", "ad_org", "ad_role", "ad_api", "ad_view", "ad_permission", "ad_permission_api", "ad_user_role", "ad_user_org", "ad_role_permission", "ad_tenant", "ad_tenant_permission"]
+  //同步指定表["ad_api", "ad_view", "ad_permission", "ad_permission_api"]
+  //同步数据包含表,指定表同步,不填同步所有表
+  "syncDataIncludeTables": [],
+  //同步排除表["ad_user"]
+  //同步数据排除表,指定表不同步
+  "syncDataExcludeTables": [],
+  //同步数据操作用户
+  "syncDataUser": {
+    "id": 161223411986501,
+    "userName": "admin",
+    "tenantId": 161223412138053
+  },
+
+  //项目初始化不开启生成数据,发布生产环境前,如果开发环境有配置数据需要更新数据包,可以开启生成数据包,使用完记得关闭
+  //开启生成数据前先关闭syncStructure syncData createDb
+  //生成数据
+  "generateData": false,
+
+  //数据库配置 https://github.com/dotnetcore/FreeSql/wiki/入门
+  //连接字符串语法 https://www.connectionstrings.com
+  //数据库类型 MySql = 0, SqlServer = 1, PostgreSQL = 2, Oracle = 3, Sqlite = 4, OdbcOracle = 5, OdbcSqlServer = 6, OdbcMySql = 7, OdbcPostgreSQL = 8, Odbc = 9, OdbcDameng = 10, MsAccess = 11, Dameng = 12, OdbcKingbaseES = 13, ShenTong = 14, KingbaseES = 15, Firebird = 16
+  "type": "MySql",
+
+  //连接字符串
+  //MySql "Server=localhost; Port=3306; Database=appdb; Uid=root; Pwd=pwd; Charset=utf8mb4;"
+  //SqlServer "Data Source=.;Integrated Security=True;Initial Catalog=appdb;Pooling=true;Min Pool Size=1"
+  //PostgreSQL "Host=localhost;Port=5432;Username=postgres;Password=; Database=appdb;Pooling=true;Minimum Pool Size=1"
+  //Sqlite "Data Source=|DataDirectory|\\appdb.db; Pooling=true;Min Pool Size=1"
+  //"Oracle" "user id=SYS;password=pwd; data source=//127.0.0.1:1521/XE;Pooling=true;Min Pool Size=1",
+  "connectionString": "Server=localhost; Port=3306; Database=appdb; Uid=root; Pwd=pwd; Charset=utf8mb4;",
+
+  //指定程序集
+  //FreeSql.MySql.MySqlProvider`1,FreeSql.Provider.MySqlConnector
+  "providerType": "",
+
+  //读写分离从库列表
+  "slaveList": [
+    //{
+    //  //权重
+    //  "Weight": 1,
+    //  //连接字符串
+    //  "ConnectionString": "Data Source=|DataDirectory|\\appdb.db; Pooling=true;Min Pool Size=1"
+    //}
+  ],
+
+  //多数据库
+  //Core/Consts定义DbKeys枚举
+  //使用仓储访问 public ModuleRepository(UnitOfWorkManagerCloud muowm) : base(DbKeys.AppDb, muowm)
+  //使用FreeSqlCloud访问  freeSqlCloud.Use(DbKeys.AppDb);
+  "dbs": [
+  ]
+}

+ 2 - 0
IMES-Middleware-Platform/src/hosts/IMES-Middleware-Platform.Host/Configs/jwtconfig.Development.json

@@ -0,0 +1,2 @@
+{
+}

+ 12 - 0
IMES-Middleware-Platform/src/hosts/IMES-Middleware-Platform.Host/Configs/jwtconfig.json

@@ -0,0 +1,12 @@
+{
+  //发行者
+  "issuer": "http://127.0.0.1:8000",
+  //订阅者
+  "audience": "http://127.0.0.1:8000",
+  //密钥
+  "securityKey": "73c50ca4-f5e4-11ed-a709-5254008978e9",
+  //有效期(分钟) 120 = 2小时
+  "expires": 120,
+  //刷新有效期(分钟) 1440 = 1天
+  "refreshExpires": 1440
+}

+ 3 - 0
IMES-Middleware-Platform/src/hosts/IMES-Middleware-Platform.Host/Configs/ossconfig.Development.json

@@ -0,0 +1,3 @@
+{
+  
+}

+ 91 - 0
IMES-Middleware-Platform/src/hosts/IMES-Middleware-Platform.Host/Configs/ossconfig.json

@@ -0,0 +1,91 @@
+{
+  //本地上传配置
+  "LocalUploadConfig": {
+    //上传目录
+    "Directory": "upload",
+    //日期目录
+    "DateTimeDirectory": "yyyy/MM/dd",
+    "Md5": false,
+    //文件最大大小byte
+    "MaxSize": 104857600,
+    //包含文件拓展名
+    "IncludeExtension": [],
+    //排除文件拓展名
+    "ExcludeExtension": [ ".exe", ".dll", ".jar" ]
+  },
+  //文件存储供应商
+  "Provider": "Minio",
+  //OSS配置列表
+  "OSSConfigs": [
+    //Minio
+    {
+      "Provider": "Minio",
+      "Endpoint": "127.0.0.1:9006",
+      "Region": "",
+      "AccessKey": "minio",
+      "SecretKey": "minio",
+      "IsEnableHttps": false,
+      "IsEnableCache": true,
+      "BucketName": "admin",
+      "Url": "", //文件外链
+      "Md5": false,
+      "Enable": false
+    },
+    //阿里云
+    {
+      "Provider": "Aliyun",
+      "Endpoint": "oss-cn-shenzhen.aliyuncs.com",
+      "Region": "",
+      "AccessKey": "",
+      "SecretKey": "",
+      "IsEnableHttps": true,
+      "IsEnableCache": true,
+      "BucketName": "admin",
+      "Url": "",
+      "Md5": false,
+      "Enable": false
+    },
+    //腾讯云
+    {
+      "Provider": "QCloud",
+      "Endpoint": "", //AppId
+      "Region": "",
+      "AccessKey": "",
+      "SecretKey": "",
+      "IsEnableHttps": true,
+      "IsEnableCache": true,
+      "BucketName": "admin",
+      "Url": "",
+      "Md5": false,
+      "Enable": false
+    },
+    //七牛
+    {
+      "Provider": "Qiniu",
+      "Endpoint": "",
+      "Region": "",
+      "AccessKey": "",
+      "SecretKey": "",
+      "IsEnableHttps": true,
+      "IsEnableCache": true,
+      "BucketName": "admin",
+      "Url": "",
+      "Md5": false,
+      "Enable": false
+    },
+    //华为云
+    {
+      "Provider": "HuaweiCloud",
+      "Endpoint": "",
+      "Region": "",
+      "AccessKey": "",
+      "SecretKey": "",
+      "IsEnableHttps": true,
+      "IsEnableCache": true,
+      "BucketName": "admin",
+      "Url": "",
+      "Md5": false,
+      "Enable": false
+    }
+  ]
+}

+ 2 - 0
IMES-Middleware-Platform/src/hosts/IMES-Middleware-Platform.Host/Configs/ratelimitconfig.Development.json

@@ -0,0 +1,2 @@
+{
+}

+ 33 - 0
IMES-Middleware-Platform/src/hosts/IMES-Middleware-Platform.Host/Configs/ratelimitconfig.json

@@ -0,0 +1,33 @@
+{
+  /*
+  https://github.com/stefanprodan/AspNetCoreRateLimit/wiki/IpRateLimitMiddleware
+  https://github.com/stefanprodan/AspNetCoreRateLimit/wiki/Using-Redis-as-a-distributed-counter-store
+  */
+  "IpRateLimiting": {
+    "EnableEndpointRateLimiting": true,
+    "StackBlockedRequests": false,
+    "RealIpHeader": "X-Real-IP",
+    "ClientIdHeader": "X-ClientId",
+    "IpWhitelist": [], // "127.0.0.1"
+    "EndpointWhitelist": [ "get:/api/admin/auth/refresh" ], // "get:/api/a", "*:/api/b"
+    "ClientWhitelist": [],
+    "HttpStatusCode": 429,
+    "QuotaExceededResponse": {
+      "Content": "{{\"code\":429,\"msg\":\"访问过于频繁!\"}}",
+      "ContentType": "application/json",
+      "StatusCode": 429
+    },
+    "GeneralRules": [
+      {
+        "Endpoint": "*",
+        "Period": "1s",
+        "Limit": 3
+      },
+      {
+        "Endpoint": "*",
+        "Period": "10m",
+        "Limit": 200
+      }
+    ]
+  }
+}

+ 2 - 0
IMES-Middleware-Platform/src/hosts/IMES-Middleware-Platform.Host/Configs/uploadconfig.Development.json

@@ -0,0 +1,2 @@
+{
+}

+ 38 - 0
IMES-Middleware-Platform/src/hosts/IMES-Middleware-Platform.Host/Configs/uploadconfig.json

@@ -0,0 +1,38 @@
+{
+  //头像
+  "avatar": {
+    //上传路径 D:/upload/admin/avatar
+    "uploadPath": "../upload/admin/avatar",
+    //请求路径
+    "requestPath": "/upload/admin/avatar",
+
+    //路径日期格式 yyyy/MM/dd
+    "dateTimeFormat": "",
+    //{用户编号}
+    "format": "{Id}",
+    //图片大小不超过 1M = 1 * 1024 * 1024
+    "maxSize": 1048576,
+    //最大允许上传张数,-1不限制
+    "limit": 1,
+    //图片格式
+    "contentType": [ "image/jpg", "image/png", "image/jpeg", "image/gif" ]
+  },
+  //文档图片
+  "document": {
+    //上传路径 D:/upload/admin/document
+    "uploadPath": "../upload/admin/document",
+    //请求路径
+    "requestPath": "/images",
+
+    //路径日期格式 yyyy/MM/dd
+    "dateTimeFormat": "",
+    //{文档编号}
+    "format": "{Id}",
+    //图片大小不超过 1M = 1 * 1024 * 1024
+    "maxSize": 1048576,
+    //最大允许上传张数,-1不限制
+    "limit": -1,
+    //图片格式
+    "contentType": [ "image/jpg", "image/png", "image/jpeg", "image/gif" ]
+  }
+}

+ 14 - 0
IMES-Middleware-Platform/src/hosts/IMES-Middleware-Platform.Host/Dockerfile

@@ -0,0 +1,14 @@
+FROM mcr.microsoft.com/dotnet/sdk:7.0 AS publish
+WORKDIR /src
+COPY ["/src/hosts/IMES_Middleware_Platform.Host/IMES_Middleware_Platform.Host.csproj", "/src/hosts/IMES_Middleware_Platform.Host/IMES_Middleware_Platform.Host.csproj"]
+RUN dotnet restore "/src/hosts/IMES_Middleware_Platform.Host/IMES_Middleware_Platform.Host.csproj" -nowarn:NETSDK1138
+COPY . .
+WORKDIR "/src/src/hosts/IMES_Middleware_Platform.Host"
+ENV NUGET_XMLDOC_MODE none
+RUN dotnet publish "IMES_Middleware_Platform.Host.csproj" -nowarn:NETSDK1138 -c Release -o /app
+
+FROM mcr.microsoft.com/dotnet/aspnet:7.0 AS final
+WORKDIR /app
+COPY --from=publish /app .
+EXPOSE 8000
+ENTRYPOINT ["dotnet", "IMES_Middleware_Platform.Host.dll"]

+ 51 - 0
IMES-Middleware-Platform/src/hosts/IMES-Middleware-Platform.Host/IMES-Middleware-Platform.Host.csproj

@@ -0,0 +1,51 @@
+<Project Sdk="Microsoft.NET.Sdk.Web">
+	<PropertyGroup>
+		<TargetFramework>net7.0</TargetFramework>
+		<Description>IMES_Middleware_Platform接口宿主</Description>
+	</PropertyGroup>
+
+	<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
+		<DocumentationFile></DocumentationFile>
+		<NoWarn>1701;1702;1591</NoWarn>
+	</PropertyGroup>
+
+	<ItemGroup>
+	  <Content Include="Configs\createdbsql.txt">
+	    <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+	  </Content>
+	</ItemGroup>
+
+	<ItemGroup>
+		<PackageReference Include="FreeSql.Provider.MySql" Version="$(PackageFreeSqlVersion)" />
+		<PackageReference Include="SkiaSharp.NativeAssets.Linux.NoDependencies" Version="2.88.3" />
+	</ItemGroup>
+	
+	<ItemGroup>
+		<ProjectReference Include="..\..\platform\IMES-Middleware-Platform.Api\IMES-Middleware-Platform.Api.csproj" />
+	</ItemGroup>
+
+	<ItemGroup>
+		<InternalsVisibleTo Include="IMES_Middleware_Platform.Tests" />
+	</ItemGroup>
+	<ItemGroup>
+		<PackageReference Include="ZhonTai.ApiUI" Version="$(PackageZhonTaiVersion)" />
+	</ItemGroup>
+	<ItemGroup>
+		<Content Update="wwwroot\*\*">
+			<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+		</Content>
+		<Content Update="wwwroot\*\*\*\*">
+			<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+		</Content>
+		<Content Update="wwwroot\*\*\*\*\*">
+			<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+		</Content>
+	</ItemGroup>
+
+    <Target Name="AfterTargetsPublish" AfterTargets="Publish">
+		<ItemGroup>
+			<PackageReferenceFiles Include="*\*\*\*.xml" />
+		</ItemGroup>
+		<Copy SourceFiles="@(PackageReferenceFiles)" DestinationFolder="$(PublishDir)" />
+	</Target>
+</Project>

+ 6 - 0
IMES-Middleware-Platform/src/hosts/IMES-Middleware-Platform.Host/InitData/App/app_module.json

@@ -0,0 +1,6 @@
+[
+  {
+    "id": 278518195769413,
+    "name": "module"
+  }
+]

+ 7 - 0
IMES-Middleware-Platform/src/hosts/IMES-Middleware-Platform.Host/InitData/App/app_module.tenant.json

@@ -0,0 +1,7 @@
+[
+  {
+    "id": 278518195769413,
+    "tenantId": 161223412138053,
+    "name": "module"
+  }
+]

+ 69 - 0
IMES-Middleware-Platform/src/hosts/IMES-Middleware-Platform.Host/Program.cs

@@ -0,0 +1,69 @@
+using IMES_Middleware_Platform.Api.Core.Consts;
+using Microsoft.AspNetCore.Builder;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Hosting;
+using ZhonTai;
+using ZhonTai.Admin.Core;
+using ZhonTai.Admin.Core.Configs;
+using ZhonTai.Admin.Core.Db;
+using ZhonTai.Admin.Core.Startup;
+using ZhonTai.ApiUI;
+using ZhonTai.Common.Helpers;
+using AdminDbkeys = ZhonTai.Admin.Core.Consts.DbKeys;
+using AdminSubscribeNames = ZhonTai.Admin.Core.Consts.SubscribeNames;
+
+new HostApp(new HostAppOptions()
+{
+    //配置前置服务
+    ConfigurePreServices = context =>
+    {
+        var dbConfig = ConfigHelper.Get<DbConfig>("dbconfig", context.Environment.EnvironmentName);
+        if (dbConfig.Key.NotNull())
+        {
+            DbKeys.AppDb = dbConfig.Key;
+        }
+        AdminDbkeys.AppDb = DbKeys.AppDb;
+        AdminSubscribeNames.SmsSingleSend = "app.smsSingleSend";
+    },
+    //配置后置服务
+    ConfigurePostServices = context =>
+    {
+    },
+    //配置FreeSql
+    ConfigureFreeSql = (freeSql, dbConfig) =>
+    {
+    },
+    //配置Autofac容器
+    ConfigureAutofacContainer = (builder, context) =>
+    {
+
+    },
+    //配置Mvc
+    ConfigureMvcBuilder = (builder, context) =>
+    {
+    },
+    //配置后置中间件
+    ConfigurePostMiddleware = context =>
+    {
+        var app = context.App;
+        var env = app.Environment;
+        var appConfig = app.Services.GetService<AppConfig>();
+
+        #region 新版Api文档
+        if (env.IsDevelopment() || appConfig.ApiUI.Enable)
+        {
+            app.UseApiUI(options =>
+            {
+                options.RoutePrefix = appConfig.ApiUI.RoutePrefix;
+                var routePath = options.RoutePrefix.NotNull() ? $"{options.RoutePrefix}/" : "";
+                appConfig.Swagger.Projects?.ForEach(project =>
+                {
+                    options.SwaggerEndpoint($"/{routePath}swagger/{project.Code.ToLower()}/swagger.json", project.Name);
+                });
+            });
+        }
+        #endregion
+    }
+}).Run(args);
+
+public partial class Program { }

+ 29 - 0
IMES-Middleware-Platform/src/hosts/IMES-Middleware-Platform.Host/Properties/launchSettings.json

@@ -0,0 +1,29 @@
+{
+  "iisSettings": {
+    "windowsAuthentication": false,
+    "anonymousAuthentication": true,
+    "iisExpress": {
+      "applicationUrl": "http://localhost:8000"
+    }
+  },
+  "profiles": {
+    "IMES_Middleware_Platform.Host": {
+      "commandName": "Project",
+      "launchBrowser": true,
+      "dotnetRunMessages": true,
+      "launchUrl": "app",
+      "environmentVariables": {
+        "ASPNETCORE_ENVIRONMENT": "Development"
+      },
+      "applicationUrl": "http://localhost:8000"
+    },
+    "IIS Express": {
+      "commandName": "IISExpress",
+      "launchBrowser": true,
+      "launchUrl": "app",
+      "environmentVariables": {
+        "ASPNETCORE_ENVIRONMENT": "Development"
+      }
+    }
+  }
+}

+ 9 - 0
IMES-Middleware-Platform/src/hosts/IMES-Middleware-Platform.Host/appsettings.Development.json

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

+ 60 - 0
IMES-Middleware-Platform/src/hosts/IMES-Middleware-Platform.Host/appsettings.json

@@ -0,0 +1,60 @@
+{
+  "Logging": {
+    "LogLevel": {
+      "Default": "Information",
+      "Microsoft": "Warning",
+      "Microsoft.AspNetCore": "Warning",
+      "Microsoft.Hosting.Lifetime": "Information",
+      "Microsoft.Extensions.Diagnostics.HealthChecks": "Warning"
+    }
+  },
+  "AllowedHosts": "*",
+  "CAP": {
+    "RabbitMq": {
+      "HostName": "",
+      "Port": 5672,
+      "UserName": "",
+      "Password": ""
+    }
+  },
+  "SlideCaptcha": {
+    "ExpirySeconds": 300, // 缓存过期时长
+    "StoreageKeyPrefix": "app:captcha:", // 缓存前缀
+    "Tolerant": 0.02, // 容错值(校验时用,缺口位置与实际滑动位置匹配容错范围)
+    "Backgrounds": [ // 背景图配置
+      {
+        "Type": "file",
+        "Data": "wwwroot/captcha/jigsaw/backgrounds/1.jpg"
+      },
+      {
+        "Type": "file",
+        "Data": "wwwroot/captcha/jigsaw/backgrounds/2.jpg"
+      },
+      {
+        "Type": "file",
+        "Data": "wwwroot/captcha/jigsaw/backgrounds/3.jpg"
+      },
+      {
+        "Type": "file",
+        "Data": "wwwroot/captcha/jigsaw/backgrounds/4.jpg"
+      },
+      {
+        "Type": "file",
+        "Data": "wwwroot/captcha/jigsaw/backgrounds/5.jpg"
+      }
+    ],
+    // Templates不配置,则使用默认模板
+    "Templates": [
+      //{
+      //  "Slider": {
+      //    "Type": "file",
+      //    "Data": "wwwroot/captcha/jigsaw/templates/1/transparent.png"
+      //  },
+      //  "Hole": {
+      //    "Type": "file",
+      //    "Data": "wwwroot/captcha/jigsaw/templates/1/dark.png"
+      //  }
+      //}
+    ]
+  }
+}

+ 61 - 0
IMES-Middleware-Platform/src/hosts/IMES-Middleware-Platform.Host/nlog.config

@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 配置文档 https://nlog-project.org/config -->
+<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" autoReload="true" internalLogLevel="Info">
+  <!-- 启用.net core的核心布局渲染器 -->
+  <extensions>
+    <add assembly="NLog.Web.AspNetCore" />
+  </extensions>
+  <!-- 写入日志的目标配置 archiveAboveSize="102400" maxArchiveDays="60" -->
+  <targets>
+	<!-- 跟踪  -->
+	<target xsi:type="File" name="trace" fileName="../logs/trace-${shortdate}.log" layout="${longdate}|${event-properties:item=EventId_Id}|${uppercase:${level}}|${logger}|${message} ${exception:format=tostring}|url: ${aspnet-request-url}|action: ${aspnet-mvc-action}" />
+	<!-- 调试  -->
+    <target xsi:type="File" name="debug" fileName="../logs/debug-${shortdate}.log" layout="${longdate}|${event-properties:item=EventId_Id}|${uppercase:${level}}|${logger}|${message} ${exception:format=tostring}|url: ${aspnet-request-url}|action: ${aspnet-mvc-action}" />
+	<!-- 信息  -->
+	<target xsi:type="File" name="info" fileName="../logs/info-${shortdate}.log" layout="${longdate} | ${event-properties:item=EventId_Id} | ${uppercase:${level}} | ${logger} | url: ${aspnet-request-url} | action: ${aspnet-mvc-action} | ${newline}${message} ${exception:format=tostring}${newline}" />
+	<!-- 警告  -->
+    <target xsi:type="File" name="warn" fileName="../logs/warn-${shortdate}.log" layout="${longdate}|${event-properties:item=EventId_Id}|${uppercase:${level}}|${logger}|${message} ${exception:format=tostring}|url: ${aspnet-request-url}|action: ${aspnet-mvc-action}" />
+    <!-- 错误  -->
+    <target xsi:type="File" name="error" fileName="../logs/error-${shortdate}.log" layout="${longdate}|${event-properties:item=EventId_Id}|${uppercase:${level}}|${logger}|${message} ${exception:format=tostring}|url: ${aspnet-request-url}|action: ${aspnet-mvc-action}" />
+    <!-- 控制台  -->
+    <target xsi:type="Console" name="console" layout="${message}" />
+	<!-- 数据库  https://github.com/NLog/NLog/wiki/Database-target -->
+	<target name="db" xsi:type="Database" connectionString="Data Source=|DataDirectory|\\admindb.db; Pooling=true;Min Pool Size=1" dbProvider="System.Data.SQLite.SQLiteConnection, System.Data.SQLite">
+		<commandText>
+			INSERT INTO "ad_log"("Id", "Logged", "Level", "Message", "Logger", "Properties", "Callsite", "Exception") VALUES(@Id, @Logged, @Level, @Message, @Logger, @Properties, @Callsite, @Exception)
+		</commandText>
+		<!-- 自定义主键  -->
+		<parameter name="@Id" layout="${event-properties:id}" />
+		<parameter name="@Logged" layout="${date}" />
+		<parameter name="@Level" layout="${level}" />
+		<parameter name="@Message" layout="${message}" />
+		<parameter name="@Logger" layout="${logger}" />
+		<!-- 自定义属性  -->
+		<parameter name="@properties" layout="${all-event-properties:separator=|}" />
+		<parameter name="@Callsite" layout="${callsite}" />
+		<parameter name="@Exception" layout="${exception:tostring}" />
+	</target>
+  </targets>
+  <!-- 映射规则 -->
+  <rules>
+	<!--跳过不重要的微软日志-->
+	<logger name="Microsoft.*" maxlevel="Debug" final="true" />
+	<logger name="Microsoft.AspNetCore.*" maxlevel="Info" final="true" />
+	<!--跳过不重要的CAP日志-->
+	<logger name="DotNetCore.CAP.*" maxlevel="Debug" final="true" />
+	<!-- 数据库  -->
+	<logger name="db" writeTo="db" />
+	<!-- 命令台  -->
+	<logger name="*" minlevel="Trace" writeTo="console" />
+	<!-- 跟踪  -->
+	<logger name="*" minlevel="Trace" maxlevel="Trace" writeTo="trace" />
+	<!-- 调试  -->
+	<logger name="*" minlevel="Debug" maxlevel="Debug" writeTo="debug" />
+	<!-- 信息  -->
+	<logger name="*" minlevel="Info" maxlevel="Info" writeTo="info" />
+    <!-- 警告  -->
+    <logger name="*" minlevel="Info" maxlevel="Warn" writeTo="warn" />
+    <!-- 错误  -->
+    <logger name="*" minlevel="Error" maxlevel="Fatal" writeTo="error" />
+  </rules>
+</nlog>

+ 3 - 0
IMES-Middleware-Platform/src/hosts/IMES-Middleware-Platform.Host/wwwroot/swagger/mini-profiler.css

@@ -0,0 +1,3 @@
+.mp-results{
+    display: block!important;
+}

+ 2 - 0
IMES-Middleware-Platform/src/hosts/IMES-Middleware-Platform.Host/wwwroot/swagger/mini-profiler.js

@@ -0,0 +1,2 @@
+//在路由中调试获取新版脚本 var script = MiniProfiler.Current.RenderIncludes(Request.HttpContext);
+document.write('<script async="async" id="mini-profiler" src="/mini-profiler-resources/includes.min.js?v=4.2.22+4563a9e1ab" data-version="4.2.22+4563a9e1ab" data-path="/mini-profiler-resources/" data-current-id="17d6dc2f-274b-4044-9d5c-f8bd229cdfd1" data-ids="c31e5864-5463-4d93-b0a5-62fa55bec631,2bab71ec-5f6f-4112-a7df-b214c13ee32b,d5bc51f5-5b0d-4971-bde8-0a339fafd68c,41130f68-5e18-4fe3-a6ad-eab5bf8ee473,83b6b654-a7b4-4b62-9b1b-0a43bc333ff2,116b78d8-cc84-473d-bc97-52bb80609e6e,7703d982-2bdb-4564-b689-453c2781f2e1,14e29678-0477-403b-ad82-87918f255d7f,18ab017e-a66d-438d-be1c-b67499d85c64,842fcd4f-a77d-46e2-9476-795743b86bef,b463870a-896c-408b-bac5-9af967a292ac,af01c39e-a23d-4b74-8fdc-201209245b14,576e8a42-eac2-4884-9c4a-e2d632155464,57572c02-be2d-4c37-ab36-19f07b11e47e,b10692ae-409c-43fe-b6f8-a4c48346eda6,17d6dc2f-274b-4044-9d5c-f8bd229cdfd1" data-position="Left"" data-scheme="Light" data-authorized="true" data-max-traces="15" data-toggle-shortcut="Alt+P" data-trivial-milliseconds="2.0" data-ignored-duplicate-execute-types="Open,OpenAsync,Close,CloseAsync"></script>');

+ 17 - 0
IMES-Middleware-Platform/src/platform/IMES-Middleware-Platform.Api/Core/Attributes/AppTransactionAttribute.cs

@@ -0,0 +1,17 @@
+using IMES_Middleware_Platform.Api.Core.Consts;
+using System;
+using ZhonTai.Admin.Core.Attributes;
+
+namespace IMES_Middleware_Platform.Api.Core.Attributes
+{
+    /// <summary>
+    /// 启用事物
+    /// </summary>
+    [AttributeUsage(AttributeTargets.Method, Inherited = true)]
+    public class AppTransactionAttribute : TransactionAttribute
+    {
+        public AppTransactionAttribute() : base(DbKeys.AppDb)
+        {
+        }
+    }
+}

+ 13 - 0
IMES-Middleware-Platform/src/platform/IMES-Middleware-Platform.Api/Core/Consts/ApiConsts.cs

@@ -0,0 +1,13 @@
+namespace IMES_Middleware_Platform.Api.Core.Consts
+{
+    /// <summary>
+    /// 接口常量
+    /// </summary>
+    public static partial class ApiConsts
+    {
+        /// <summary>
+        /// 默认域
+        /// </summary>
+        public const string AreaName = "app";
+    }
+}

+ 18 - 0
IMES-Middleware-Platform/src/platform/IMES-Middleware-Platform.Api/Core/Consts/CacheKeys.cs

@@ -0,0 +1,18 @@
+using System.ComponentModel;
+using ZhonTai.Admin.Core.Attributes;
+
+namespace IMES_Middleware_Platform.Api.Core.Consts
+{
+    /// <summary>
+    /// 缓存键
+    /// </summary>
+    [ScanCacheKeys]
+    public static partial class CacheKeys
+    {
+        /// <summary>
+        /// 模块缓存键 module:action:{id}
+        /// </summary>
+        [Description("模块缓存键")]
+        public const string ModuleActionKey = "module:action:";
+    }
+}

+ 16 - 0
IMES-Middleware-Platform/src/platform/IMES-Middleware-Platform.Api/Core/Consts/DbKeys.cs

@@ -0,0 +1,16 @@
+using System.ComponentModel;
+
+namespace IMES_Middleware_Platform.Api.Core.Consts
+{
+    /// <summary>
+    /// 数据库键名
+    /// </summary>
+    public class DbKeys
+    {
+        /// <summary>
+        /// 数据库注册键
+        /// </summary>
+        [Description("数据库注册键")]
+        public static string AppDb { get; set; } = "appdb";
+    }
+}

+ 18 - 0
IMES-Middleware-Platform/src/platform/IMES-Middleware-Platform.Api/Core/Handlers/AppCustomTaskHandler.cs

@@ -0,0 +1,18 @@
+using FreeScheduler;
+using System;
+
+namespace IMES_Middleware_Platform.Api.Core.Handlers
+{
+    /// <summary>
+    /// 模块自定义任务处理器
+    /// </summary>
+    public class AppCustomTaskHandler : ITaskIntervalCustomHandler
+    {
+        public TimeSpan? NextDelay(TaskInfo task)
+        {
+            //利用 cron 功能库解析 task.IntervalArgument 得到下一次执行时间
+            //与当前时间相减,得到 TimeSpan,若返回 null 则任务完成
+            return TimeSpan.FromSeconds(5);
+        }
+    }
+}

+ 14 - 0
IMES-Middleware-Platform/src/platform/IMES-Middleware-Platform.Api/Core/Repositories/AppRepositoryBase.cs

@@ -0,0 +1,14 @@
+using IMES_Middleware_Platform.Api.Core.Consts;
+using ZhonTai.Admin.Core.Db.Transaction;
+using ZhonTai.Admin.Core.Repositories;
+
+namespace IMES_Middleware_Platform.Api.Core.Repositories
+{
+    public class AppRepositoryBase<TEntity> : RepositoryBase<TEntity> where TEntity : class
+    {
+        public AppRepositoryBase(UnitOfWorkManagerCloud uowm) : base(DbKeys.AppDb, uowm)
+        {
+
+        }
+    }
+}

+ 13 - 0
IMES-Middleware-Platform/src/platform/IMES-Middleware-Platform.Api/Domain/Module/Dto/ModuleGetPageDto.cs

@@ -0,0 +1,13 @@
+namespace IMES_Middleware_Platform.Api.Domain.Module.Dto
+{
+    /// <summary>
+    /// 模块分页
+    /// </summary>
+    public partial class ModuleGetPageDto
+    {
+        /// <summary>
+        /// 名称
+        /// </summary>
+        public string Name { get; set; }
+    }
+}

+ 11 - 0
IMES-Middleware-Platform/src/platform/IMES-Middleware-Platform.Api/Domain/Module/IModuleRepository.cs

@@ -0,0 +1,11 @@
+using ZhonTai.Admin.Core.Repositories;
+
+namespace IMES_Middleware_Platform.Api.Domain.Module
+{
+    /// <summary>
+    /// Ä£¿é²Ö´¢½Ó¿Ú
+    /// </summary>
+    public interface IModuleRepository : IRepositoryBase<ModuleEntity>
+    {
+    }
+}

+ 20 - 0
IMES-Middleware-Platform/src/platform/IMES-Middleware-Platform.Api/Domain/Module/ModuleEntity.cs

@@ -0,0 +1,20 @@
+using FreeSql.DataAnnotations;
+using System;
+using ZhonTai.Admin.Core.Entities;
+
+namespace IMES_Middleware_Platform.Api.Domain.Module
+{
+    /// <summary>
+    /// 模块
+    /// </summary>
+    [Table(Name = "app_module")]
+    [Index("idx_{tablename}_01", nameof(TenantId) + "," + nameof(Name), true)]
+    public partial class ModuleEntity : EntityTenant
+    {
+        /// <summary>
+        /// 名称
+        /// </summary>
+        [Column(StringLength = 50)]
+        public string Name { get; set; }
+    }
+}

+ 23 - 0
IMES-Middleware-Platform/src/platform/IMES-Middleware-Platform.Api/Domain/Module/Output/ModuleDataOutput.cs

@@ -0,0 +1,23 @@
+namespace IMES_Middleware_Platform.Api.Domain.Module.Output
+{
+    /// <summary>
+    /// 模块导出
+    /// </summary>
+    public partial class ModuleDataOutput
+    {
+        /// <summary>
+        /// 租户Id
+        /// </summary>
+        public long? TenantId { get; set; }
+
+        /// <summary>
+        /// 用户Id
+        /// </summary>
+        public long Id { get; set; }
+
+        /// <summary>
+        /// 名称
+        /// </summary>
+        public string Name { get; set; }
+    }
+}

+ 27 - 0
IMES-Middleware-Platform/src/platform/IMES-Middleware-Platform.Api/IMES-Middleware-Platform.Api.csproj

@@ -0,0 +1,27 @@
+<Project Sdk="Microsoft.NET.Sdk">
+	<PropertyGroup>
+		<Description>IMES_Middleware_Platform接口库</Description>
+	</PropertyGroup>
+
+	<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
+		<DocumentationFile>IMES_Middleware_Platform.Api.xml</DocumentationFile>
+		<NoWarn>1701;1702;1591</NoWarn>
+	</PropertyGroup>
+
+	<ItemGroup>
+		<PackageReference Include="ZhonTai.Admin" Version="$(PackageZhonTaiVersion)">
+			<CopyToOutputDirectory>*\*\*.xml</CopyToOutputDirectory>
+		</PackageReference>
+	</ItemGroup>
+
+	<ItemGroup>
+	  <Folder Include="Repositories\Module\" />
+	</ItemGroup>
+
+	<Target Name="AfterTargetsBuild" AfterTargets="Build">
+		<ItemGroup>
+			<PackageReferenceFiles Condition="'%(PackageReference.CopyToOutputDirectory)' != ''" Include="$(NugetPackageRoot)\$([MSBuild]::Escape('%(PackageReference.Identity)').ToLower())\%(PackageReference.Version)\%(PackageReference.CopyToOutputDirectory)" />
+		</ItemGroup>
+		<Copy Condition="'%(PackageReference.CopyToOutputDirectory)' != ''" SourceFiles="@(PackageReferenceFiles)" DestinationFolder="./../../hosts/IMES_Middleware_Platform.Host/$(OutDir)" />
+	</Target>
+</Project>

+ 238 - 0
IMES-Middleware-Platform/src/platform/IMES-Middleware-Platform.Api/IMES-Middleware-Platform.Api.xml

@@ -0,0 +1,238 @@
+<?xml version="1.0"?>
+<doc>
+    <assembly>
+        <name>IMES_Middleware_Platform.Api</name>
+    </assembly>
+    <members>
+        <member name="T:IMES_Middleware_Platform.Api.Core.Attributes.AppTransactionAttribute">
+            <summary>
+            启用事物
+            </summary>
+        </member>
+        <member name="T:IMES_Middleware_Platform.Api.Core.Consts.ApiConsts">
+            <summary>
+            接口常量
+            </summary>
+        </member>
+        <member name="F:IMES_Middleware_Platform.Api.Core.Consts.ApiConsts.AreaName">
+            <summary>
+            默认域
+            </summary>
+        </member>
+        <member name="T:IMES_Middleware_Platform.Api.Core.Consts.CacheKeys">
+            <summary>
+            缓存键
+            </summary>
+        </member>
+        <member name="F:IMES_Middleware_Platform.Api.Core.Consts.CacheKeys.ModuleActionKey">
+            <summary>
+            模块缓存键 module:action:{id}
+            </summary>
+        </member>
+        <member name="T:IMES_Middleware_Platform.Api.Core.Consts.DbKeys">
+            <summary>
+            数据库键名
+            </summary>
+        </member>
+        <member name="P:IMES_Middleware_Platform.Api.Core.Consts.DbKeys.AppDb">
+            <summary>
+            数据库注册键
+            </summary>
+        </member>
+        <member name="T:IMES_Middleware_Platform.Api.Core.Consts.TaskNames">
+            <summary>
+            任务名
+            </summary>
+        </member>
+        <member name="F:IMES_Middleware_Platform.Api.Core.Consts.TaskNames.ModuleTaskName">
+            <summary>
+            模块任务名
+            </summary>
+        </member>
+        <member name="T:IMES_Middleware_Platform.Api.Core.Handlers.AppCustomTaskHandler">
+            <summary>
+            模块自定义任务处理器
+            </summary>
+        </member>
+        <member name="T:IMES_Middleware_Platform.Api.Core.Handlers.AppTaskHandler">
+            <summary>
+            模块任务处理器
+            </summary>
+        </member>
+        <member name="M:IMES_Middleware_Platform.Api.Core.Handlers.AppTaskHandler.ModuleTask(FreeScheduler.TaskInfo)">
+            <summary>
+            模块任务
+            </summary>
+            <param name="task"></param>
+        </member>
+        <member name="T:IMES_Middleware_Platform.Api.Domain.Module.Dto.ModuleGetPageDto">
+            <summary>
+            模块分页
+            </summary>
+        </member>
+        <member name="P:IMES_Middleware_Platform.Api.Domain.Module.Dto.ModuleGetPageDto.Name">
+            <summary>
+            名称
+            </summary>
+        </member>
+        <member name="T:IMES_Middleware_Platform.Api.Domain.Module.IModuleRepository">
+            <summary>
+            模块仓储接口
+            </summary>
+        </member>
+        <member name="T:IMES_Middleware_Platform.Api.Domain.Module.ModuleEntity">
+            <summary>
+            模块
+            </summary>
+        </member>
+        <member name="P:IMES_Middleware_Platform.Api.Domain.Module.ModuleEntity.Name">
+            <summary>
+            名称
+            </summary>
+        </member>
+        <member name="T:IMES_Middleware_Platform.Api.Domain.Module.Output.ModuleDataOutput">
+            <summary>
+            模块导出
+            </summary>
+        </member>
+        <member name="P:IMES_Middleware_Platform.Api.Domain.Module.Output.ModuleDataOutput.TenantId">
+            <summary>
+            租户Id
+            </summary>
+        </member>
+        <member name="P:IMES_Middleware_Platform.Api.Domain.Module.Output.ModuleDataOutput.Id">
+            <summary>
+            用户Id
+            </summary>
+        </member>
+        <member name="P:IMES_Middleware_Platform.Api.Domain.Module.Output.ModuleDataOutput.Name">
+            <summary>
+            名称
+            </summary>
+        </member>
+        <member name="T:IMES_Middleware_Platform.Api.Repositories.ModuleRepository">
+            <summary>
+            模块仓储
+            </summary>
+        </member>
+        <member name="T:IMES_Middleware_Platform.Api.Services.Module.IModuleService">
+            <summary>
+            模块接口
+            </summary>
+        </member>
+        <member name="T:IMES_Middleware_Platform.Api.Services.Module.Input.ModuleAddInput">
+            <summary>
+            添加模块
+            </summary>
+        </member>
+        <member name="P:IMES_Middleware_Platform.Api.Services.Module.Input.ModuleAddInput.Name">
+            <summary>
+            名称
+            </summary>
+        </member>
+        <member name="T:IMES_Middleware_Platform.Api.Services.Module.Input.ModuleUpdateInput">
+            <summary>
+            修改模块
+            </summary>
+        </member>
+        <member name="P:IMES_Middleware_Platform.Api.Services.Module.Input.ModuleUpdateInput.Id">
+            <summary>
+            编号
+            </summary>
+        </member>
+        <member name="P:IMES_Middleware_Platform.Api.Services.Module.Input.ModuleUpdateInput.Version">
+            <summary>
+            版本
+            </summary>
+        </member>
+        <member name="T:IMES_Middleware_Platform.Api.Services.Module.ModuleService">
+            <summary>
+            模块服务
+            </summary>
+        </member>
+        <member name="M:IMES_Middleware_Platform.Api.Services.Module.ModuleService.GetAsync(System.Int64)">
+            <summary>
+            查询模块
+            </summary>
+            <param name="id"></param>
+            <returns></returns>
+        </member>
+        <member name="M:IMES_Middleware_Platform.Api.Services.Module.ModuleService.GetPageAsync(ZhonTai.Admin.Core.Dto.PageInput{IMES_Middleware_Platform.Api.Domain.Module.Dto.ModuleGetPageDto})">
+            <summary>
+            查询分页
+            </summary>
+            <param name="input"></param>
+            <returns></returns>
+        </member>
+        <member name="M:IMES_Middleware_Platform.Api.Services.Module.ModuleService.AddAsync(IMES_Middleware_Platform.Api.Services.Module.Input.ModuleAddInput)">
+            <summary>
+            新增
+            </summary>
+            <param name="input"></param>
+            <returns></returns>
+        </member>
+        <member name="M:IMES_Middleware_Platform.Api.Services.Module.ModuleService.UpdateAsync(IMES_Middleware_Platform.Api.Services.Module.Input.ModuleUpdateInput)">
+            <summary>
+            修改
+            </summary>
+            <param name="input"></param>
+            <returns></returns>
+        </member>
+        <member name="M:IMES_Middleware_Platform.Api.Services.Module.ModuleService.DeleteAsync(System.Int64)">
+            <summary>
+            彻底删除
+            </summary>
+            <param name="id"></param>
+            <returns></returns>
+        </member>
+        <member name="M:IMES_Middleware_Platform.Api.Services.Module.ModuleService.SoftDeleteAsync(System.Int64)">
+            <summary>
+            删除
+            </summary>
+            <param name="id"></param>
+            <returns></returns>
+        </member>
+        <member name="M:IMES_Middleware_Platform.Api.Services.Module.ModuleService.BatchSoftDeleteAsync(System.Int64[])">
+            <summary>
+            批量删除
+            </summary>
+            <param name="ids"></param>
+            <returns></returns>
+        </member>
+        <member name="M:IMES_Middleware_Platform.Api.Services.Module.ModuleService.ExecuteTask">
+            <summary>
+            执行任务
+            </summary>
+            <returns></returns>
+        </member>
+        <member name="T:IMES_Middleware_Platform.Api.Services.Module.Output.ModuleGetOutput">
+            <summary>
+            模块
+            </summary>
+        </member>
+        <member name="T:IMES_Middleware_Platform.Api.Services.Module.Output.ModuleListOutput">
+            <summary>
+            模块列表
+            </summary>
+        </member>
+        <member name="P:IMES_Middleware_Platform.Api.Services.Module.Output.ModuleListOutput.Id">
+            <summary>
+            主键
+            </summary>
+        </member>
+        <member name="P:IMES_Middleware_Platform.Api.Services.Module.Output.ModuleListOutput.Name">
+            <summary>
+            名称
+            </summary>
+        </member>
+        <member name="M:ZhonTai.Admin.Repositories.CustomSyncData.InitModuleAsync(IFreeSql,FreeSql.IRepositoryUnitOfWork,ZhonTai.Admin.Core.Configs.DbConfig)">
+            <summary>
+            初始化模块
+            </summary>
+            <param name="db"></param>
+            <param name="unitOfWork"></param>
+            <param name="dbConfig"></param>
+            <returns></returns>
+        </member>
+    </members>
+</doc>

+ 211 - 0
IMES-Middleware-Platform/src/platform/IMES-Middleware-Platform.Api/IMES_Middleware_Platform.Api.xml

@@ -0,0 +1,211 @@
+<?xml version="1.0"?>
+<doc>
+    <assembly>
+        <name>IMES-Middleware-Platform.Api</name>
+    </assembly>
+    <members>
+        <member name="T:IMES_Middleware_Platform.Api.Core.Attributes.AppTransactionAttribute">
+            <summary>
+            启用事物
+            </summary>
+        </member>
+        <member name="T:IMES_Middleware_Platform.Api.Core.Consts.ApiConsts">
+            <summary>
+            接口常量
+            </summary>
+        </member>
+        <member name="F:IMES_Middleware_Platform.Api.Core.Consts.ApiConsts.AreaName">
+            <summary>
+            默认域
+            </summary>
+        </member>
+        <member name="T:IMES_Middleware_Platform.Api.Core.Consts.CacheKeys">
+            <summary>
+            缓存键
+            </summary>
+        </member>
+        <member name="F:IMES_Middleware_Platform.Api.Core.Consts.CacheKeys.ModuleActionKey">
+            <summary>
+            模块缓存键 module:action:{id}
+            </summary>
+        </member>
+        <member name="T:IMES_Middleware_Platform.Api.Core.Consts.DbKeys">
+            <summary>
+            数据库键名
+            </summary>
+        </member>
+        <member name="P:IMES_Middleware_Platform.Api.Core.Consts.DbKeys.AppDb">
+            <summary>
+            数据库注册键
+            </summary>
+        </member>
+        <member name="T:IMES_Middleware_Platform.Api.Core.Handlers.AppCustomTaskHandler">
+            <summary>
+            模块自定义任务处理器
+            </summary>
+        </member>
+        <member name="T:IMES_Middleware_Platform.Api.Domain.Module.Dto.ModuleGetPageDto">
+            <summary>
+            模块分页
+            </summary>
+        </member>
+        <member name="P:IMES_Middleware_Platform.Api.Domain.Module.Dto.ModuleGetPageDto.Name">
+            <summary>
+            名称
+            </summary>
+        </member>
+        <member name="T:IMES_Middleware_Platform.Api.Domain.Module.IModuleRepository">
+            <summary>
+            模块仓储接口
+            </summary>
+        </member>
+        <member name="T:IMES_Middleware_Platform.Api.Domain.Module.ModuleEntity">
+            <summary>
+            模块
+            </summary>
+        </member>
+        <member name="P:IMES_Middleware_Platform.Api.Domain.Module.ModuleEntity.Name">
+            <summary>
+            名称
+            </summary>
+        </member>
+        <member name="T:IMES_Middleware_Platform.Api.Domain.Module.Output.ModuleDataOutput">
+            <summary>
+            模块导出
+            </summary>
+        </member>
+        <member name="P:IMES_Middleware_Platform.Api.Domain.Module.Output.ModuleDataOutput.TenantId">
+            <summary>
+            租户Id
+            </summary>
+        </member>
+        <member name="P:IMES_Middleware_Platform.Api.Domain.Module.Output.ModuleDataOutput.Id">
+            <summary>
+            用户Id
+            </summary>
+        </member>
+        <member name="P:IMES_Middleware_Platform.Api.Domain.Module.Output.ModuleDataOutput.Name">
+            <summary>
+            名称
+            </summary>
+        </member>
+        <member name="T:IMES_Middleware_Platform.Api.Repositories.ModuleRepository">
+            <summary>
+            模块仓储
+            </summary>
+        </member>
+        <member name="T:IMES_Middleware_Platform.Api.Services.Module.IModuleService">
+            <summary>
+            模块接口
+            </summary>
+        </member>
+        <member name="T:IMES_Middleware_Platform.Api.Services.Module.Input.ModuleAddInput">
+            <summary>
+            添加模块
+            </summary>
+        </member>
+        <member name="P:IMES_Middleware_Platform.Api.Services.Module.Input.ModuleAddInput.Name">
+            <summary>
+            名称
+            </summary>
+        </member>
+        <member name="T:IMES_Middleware_Platform.Api.Services.Module.Input.ModuleUpdateInput">
+            <summary>
+            修改模块
+            </summary>
+        </member>
+        <member name="P:IMES_Middleware_Platform.Api.Services.Module.Input.ModuleUpdateInput.Id">
+            <summary>
+            编号
+            </summary>
+        </member>
+        <member name="P:IMES_Middleware_Platform.Api.Services.Module.Input.ModuleUpdateInput.Version">
+            <summary>
+            版本
+            </summary>
+        </member>
+        <member name="T:IMES_Middleware_Platform.Api.Services.Module.ModuleService">
+            <summary>
+            模块服务
+            </summary>
+        </member>
+        <member name="M:IMES_Middleware_Platform.Api.Services.Module.ModuleService.GetAsync(System.Int64)">
+            <summary>
+            查询模块
+            </summary>
+            <param name="id"></param>
+            <returns></returns>
+        </member>
+        <member name="M:IMES_Middleware_Platform.Api.Services.Module.ModuleService.GetPageAsync(ZhonTai.Admin.Core.Dto.PageInput{IMES_Middleware_Platform.Api.Domain.Module.Dto.ModuleGetPageDto})">
+            <summary>
+            查询分页
+            </summary>
+            <param name="input"></param>
+            <returns></returns>
+        </member>
+        <member name="M:IMES_Middleware_Platform.Api.Services.Module.ModuleService.AddAsync(IMES_Middleware_Platform.Api.Services.Module.Input.ModuleAddInput)">
+            <summary>
+            新增
+            </summary>
+            <param name="input"></param>
+            <returns></returns>
+        </member>
+        <member name="M:IMES_Middleware_Platform.Api.Services.Module.ModuleService.UpdateAsync(IMES_Middleware_Platform.Api.Services.Module.Input.ModuleUpdateInput)">
+            <summary>
+            修改
+            </summary>
+            <param name="input"></param>
+            <returns></returns>
+        </member>
+        <member name="M:IMES_Middleware_Platform.Api.Services.Module.ModuleService.DeleteAsync(System.Int64)">
+            <summary>
+            彻底删除
+            </summary>
+            <param name="id"></param>
+            <returns></returns>
+        </member>
+        <member name="M:IMES_Middleware_Platform.Api.Services.Module.ModuleService.SoftDeleteAsync(System.Int64)">
+            <summary>
+            删除
+            </summary>
+            <param name="id"></param>
+            <returns></returns>
+        </member>
+        <member name="M:IMES_Middleware_Platform.Api.Services.Module.ModuleService.BatchSoftDeleteAsync(System.Int64[])">
+            <summary>
+            批量删除
+            </summary>
+            <param name="ids"></param>
+            <returns></returns>
+        </member>
+        <member name="T:IMES_Middleware_Platform.Api.Services.Module.Output.ModuleGetOutput">
+            <summary>
+            模块
+            </summary>
+        </member>
+        <member name="T:IMES_Middleware_Platform.Api.Services.Module.Output.ModuleListOutput">
+            <summary>
+            模块列表
+            </summary>
+        </member>
+        <member name="P:IMES_Middleware_Platform.Api.Services.Module.Output.ModuleListOutput.Id">
+            <summary>
+            主键
+            </summary>
+        </member>
+        <member name="P:IMES_Middleware_Platform.Api.Services.Module.Output.ModuleListOutput.Name">
+            <summary>
+            名称
+            </summary>
+        </member>
+        <member name="M:ZhonTai.Admin.Repositories.CustomSyncData.InitModuleAsync(IFreeSql,FreeSql.IRepositoryUnitOfWork,ZhonTai.Admin.Core.Configs.DbConfig)">
+            <summary>
+            初始化模块
+            </summary>
+            <param name="db"></param>
+            <param name="unitOfWork"></param>
+            <param name="dbConfig"></param>
+            <returns></returns>
+        </member>
+    </members>
+</doc>

+ 27 - 0
IMES-Middleware-Platform/src/platform/IMES-Middleware-Platform.Api/Repositories/CustomGenerateData.cs

@@ -0,0 +1,27 @@
+using IMES_Middleware_Platform.Api.Domain.Module;
+using System.Linq;
+using System.Threading.Tasks;
+using ZhonTai.Admin.Core.Configs;
+using ZhonTai.Admin.Core.Db.Data;
+using ZhonTai.Admin.Domain.Tenant;
+
+namespace ZhonTai.Admin.Repositories
+{
+    public class CustomGenerateData : GenerateData, IGenerateData
+    {
+        public virtual async Task GenerateDataAsync(IFreeSql db, AppConfig appConfig)
+        {
+            var isTenant = appConfig.Tenant;
+
+            var modules = await db.Queryable<ModuleEntity>().ToListAsync();
+
+            if (isTenant)
+            {
+                var tenantIds = await db.Queryable<TenantEntity>().ToListAsync(a => a.Id);
+                SaveDataToJsonFile<ModuleEntity>(modules.Where(a => tenantIds.Contains(a.TenantId.Value)));
+            }
+
+            SaveDataToJsonFile<ModuleEntity>(modules, isTenant, path: "InitData/App");
+        }
+    }
+}

+ 90 - 0
IMES-Middleware-Platform/src/platform/IMES-Middleware-Platform.Api/Repositories/CustomSyncData.cs

@@ -0,0 +1,90 @@
+using FreeSql;
+using IMES_Middleware_Platform.Api.Domain.Module;
+using System;
+using System.Linq;
+using System.Threading.Tasks;
+using ZhonTai.Admin.Core.Configs;
+using ZhonTai.Admin.Core.Db.Data;
+
+namespace ZhonTai.Admin.Repositories
+{
+    public class CustomSyncData : SyncData, ISyncData
+    {
+        /// <summary>
+        /// 初始化模块
+        /// </summary>
+        /// <param name="db"></param>
+        /// <param name="unitOfWork"></param>
+        /// <param name="dbConfig"></param>
+        /// <returns></returns>
+        private async Task InitModuleAsync(IFreeSql db, IRepositoryUnitOfWork unitOfWork, DbConfig dbConfig)
+        {
+            var tableName = GetTableName<ModuleEntity>();
+            try
+            {
+                if (!IsSyncData(tableName, dbConfig))
+                {
+                    return;
+                }
+
+                var rep = db.GetRepository<ModuleEntity>();
+                rep.UnitOfWork = unitOfWork;
+
+                //数据列表
+                var dataList = GetData<ModuleEntity>(path: "InitData/App");
+
+                if (!(dataList?.Length > 0))
+                {
+                    Console.WriteLine($"table: {tableName} import data []");
+                    return;
+                }
+
+                //查询
+                var ids = dataList.Select(e => e.Id).ToList();
+                var recordList = await rep.Where(a => ids.Contains(a.Id)).ToListAsync();
+
+                //新增
+                var recordIds = recordList.Select(a => a.Id).ToList();
+                var insertDataList = dataList.Where(a => !recordIds.Contains(a.Id));
+                if (insertDataList.Any())
+                {
+                    await rep.InsertAsync(insertDataList);
+                }
+
+                //修改
+                if (dbConfig.SysUpdateData && recordList?.Count > 0)
+                {
+                    var updateDataList = dataList.Where(a => recordIds.Contains(a.Id));
+                    await rep.UpdateAsync(updateDataList);
+                }
+
+                Console.WriteLine($"table: {tableName} sync data succeed");
+            }
+            catch (Exception ex)
+            {
+                var msg = $"table: {tableName} sync data failed.\n{ex.Message}";
+                Console.WriteLine(msg);
+                throw new Exception(msg);
+            }
+        }
+
+        public virtual async Task SyncDataAsync(IFreeSql db, DbConfig dbConfig = null, AppConfig appConfig = null)
+        {
+            using var unitOfWork = db.CreateUnitOfWork();
+
+            try
+            {
+                var isTenant = appConfig.Tenant;
+
+                await InitModuleAsync(db, unitOfWork, dbConfig);
+
+                unitOfWork.Commit();
+            }
+            catch (Exception)
+            {
+                unitOfWork.Rollback();
+                throw;
+            }
+        }
+    }
+}

+ 16 - 0
IMES-Middleware-Platform/src/platform/IMES-Middleware-Platform.Api/Repositories/Module/ModuleRepository.cs

@@ -0,0 +1,16 @@
+using IMES_Middleware_Platform.Api.Core.Repositories;
+using IMES_Middleware_Platform.Api.Domain.Module;
+using ZhonTai.Admin.Core.Db.Transaction;
+
+namespace IMES_Middleware_Platform.Api.Repositories
+{
+    /// <summary>
+    /// Ä£¿é²Ö´¢
+    /// </summary>
+    public class ModuleRepository : AppRepositoryBase<ModuleEntity>, IModuleRepository
+    {
+        public ModuleRepository(UnitOfWorkManagerCloud uowm) : base(uowm)
+        {
+        }
+    }
+}

+ 28 - 0
IMES-Middleware-Platform/src/platform/IMES-Middleware-Platform.Api/Services/Module/IModuleService.cs

@@ -0,0 +1,28 @@
+using IMES_Middleware_Platform.Api.Domain.Module.Dto;
+using IMES_Middleware_Platform.Api.Services.Module.Input;
+using IMES_Middleware_Platform.Api.Services.Module.Output;
+using System.Threading.Tasks;
+using ZhonTai.Admin.Core.Dto;
+
+namespace IMES_Middleware_Platform.Api.Services.Module
+{
+    /// <summary>
+    /// 模块接口
+    /// </summary>
+    public interface IModuleService
+    {
+        Task<ModuleGetOutput> GetAsync(long id);
+
+        Task<PageOutput<ModuleListOutput>> GetPageAsync(PageInput<ModuleGetPageDto> input);
+
+        Task<long> AddAsync(ModuleAddInput input);
+
+        Task UpdateAsync(ModuleUpdateInput input);
+
+        Task DeleteAsync(long id);
+
+        Task SoftDeleteAsync(long id);
+
+        Task BatchSoftDeleteAsync(long[] ids);
+    }
+}

+ 13 - 0
IMES-Middleware-Platform/src/platform/IMES-Middleware-Platform.Api/Services/Module/Input/ModuleAddInput.cs

@@ -0,0 +1,13 @@
+namespace IMES_Middleware_Platform.Api.Services.Module.Input
+{
+    /// <summary>
+    /// 添加模块
+    /// </summary>
+    public class ModuleAddInput
+    {
+        /// <summary>
+        /// 名称
+        /// </summary>
+        public string Name { get; set; }
+    }
+}

+ 23 - 0
IMES-Middleware-Platform/src/platform/IMES-Middleware-Platform.Api/Services/Module/Input/ModuleUpdateInput.cs

@@ -0,0 +1,23 @@
+using System.ComponentModel.DataAnnotations;
+using ZhonTai.Admin.Core.Validators;
+
+namespace IMES_Middleware_Platform.Api.Services.Module.Input
+{
+    /// <summary>
+    /// 修改模块
+    /// </summary>
+    public partial class ModuleUpdateInput : ModuleAddInput
+    {
+        /// <summary>
+        /// 编号
+        /// </summary>
+        [Required]
+        [ValidateRequired("请选择模块")]
+        public long Id { get; set; }
+
+        /// <summary>
+        /// 版本
+        /// </summary>
+        public long Version { get; set; }
+    }
+}

+ 127 - 0
IMES-Middleware-Platform/src/platform/IMES-Middleware-Platform.Api/Services/Module/ModuleService.cs

@@ -0,0 +1,127 @@
+using IMES_Middleware_Platform.Api.Core.Consts;
+using IMES_Middleware_Platform.Api.Domain.Module;
+using IMES_Middleware_Platform.Api.Domain.Module.Dto;
+using IMES_Middleware_Platform.Api.Services.Module.Input;
+using IMES_Middleware_Platform.Api.Services.Module.Output;
+using Microsoft.AspNetCore.Mvc;
+using System.Threading.Tasks;
+using ZhonTai;
+using ZhonTai.Admin.Core.Dto;
+using ZhonTai.Admin.Services;
+using ZhonTai.DynamicApi;
+using ZhonTai.DynamicApi.Attributes;
+
+namespace IMES_Middleware_Platform.Api.Services.Module
+{
+    /// <summary>
+    /// 模块服务
+    /// </summary>
+    [Order(1010)]
+    [DynamicApi(Area = ApiConsts.AreaName)]
+    public class ModuleService : BaseService, IModuleService, IDynamicApi
+    {
+        private IModuleRepository _moduleRepository => LazyGetRequiredService<IModuleRepository>();
+
+        public ModuleService()
+        {
+        }
+
+        /// <summary>
+        /// 查询模块
+        /// </summary>
+        /// <param name="id"></param>
+        /// <returns></returns>
+        public async Task<ModuleGetOutput> GetAsync(long id)
+        {
+            var result = await _moduleRepository.GetAsync<ModuleGetOutput>(id);
+            return result;
+        }
+
+        /// <summary>
+        /// 查询分页
+        /// </summary>
+        /// <param name="input"></param>
+        /// <returns></returns>
+        [HttpPost]
+        public async Task<PageOutput<ModuleListOutput>> GetPageAsync(PageInput<ModuleGetPageDto> input)
+        {
+            var key = input.Filter?.Name;
+
+            var list = await _moduleRepository.Select
+            .WhereIf(key.NotNull(), a => a.Name.Contains(key))
+            .Count(out var total)
+            .OrderByDescending(true, c => c.Id)
+            .Page(input.CurrentPage, input.PageSize)
+            .ToListAsync<ModuleListOutput>();
+
+            var data = new PageOutput<ModuleListOutput>()
+            {
+                List = list,
+                Total = total
+            };
+
+            return data;
+        }
+
+        /// <summary>
+        /// 新增
+        /// </summary>
+        /// <param name="input"></param>
+        /// <returns></returns>
+        public async Task<long> AddAsync(ModuleAddInput input)
+        {
+            var entity = Mapper.Map<ModuleEntity>(input);
+            await _moduleRepository.InsertAsync(entity);
+
+            return entity.Id;
+        }
+
+        /// <summary>
+        /// 修改
+        /// </summary>
+        /// <param name="input"></param>
+        /// <returns></returns>
+        public async Task UpdateAsync(ModuleUpdateInput input)
+        {
+            var entity = await _moduleRepository.GetAsync(input.Id);
+            if (!(entity?.Id > 0))
+            {
+                throw ResultOutput.Exception("模块不存在");
+            }
+
+            Mapper.Map(input, entity);
+            await _moduleRepository.UpdateAsync(entity);
+        }
+
+        /// <summary>
+        /// 彻底删除
+        /// </summary>
+        /// <param name="id"></param>
+        /// <returns></returns>
+        public async Task DeleteAsync(long id)
+        {
+            await _moduleRepository.DeleteAsync(m => m.Id == id);
+        }
+
+        /// <summary>
+        /// 删除
+        /// </summary>
+        /// <param name="id"></param>
+        /// <returns></returns>
+        public async Task SoftDeleteAsync(long id)
+        {
+            await _moduleRepository.SoftDeleteAsync(id);
+        }
+
+        /// <summary>
+        /// 批量删除
+        /// </summary>
+        /// <param name="ids"></param>
+        /// <returns></returns>
+        public async Task BatchSoftDeleteAsync(long[] ids)
+        {
+            await _moduleRepository.SoftDeleteAsync(ids);
+        }
+
+    }
+}

+ 11 - 0
IMES-Middleware-Platform/src/platform/IMES-Middleware-Platform.Api/Services/Module/Output/ModuleGetOutput.cs

@@ -0,0 +1,11 @@
+using IMES_Middleware_Platform.Api.Services.Module.Input;
+
+namespace IMES_Middleware_Platform.Api.Services.Module.Output
+{
+    /// <summary>
+    /// 模块
+    /// </summary>
+    public class ModuleGetOutput : ModuleUpdateInput
+    {
+    }
+}

+ 18 - 0
IMES-Middleware-Platform/src/platform/IMES-Middleware-Platform.Api/Services/Module/Output/ModuleListOutput.cs

@@ -0,0 +1,18 @@
+namespace IMES_Middleware_Platform.Api.Services.Module.Output
+{
+    /// <summary>
+    /// 模块列表
+    /// </summary>
+    public class ModuleListOutput
+    {
+        /// <summary>
+        /// 主键
+        /// </summary>
+        public long Id { get; set; }
+
+        /// <summary>
+        /// 名称
+        /// </summary>
+        public string Name { get; set; }
+    }
+}

+ 207 - 0
IMES-Middleware-Platform/src/tests/IMES-Middleware-Platform.Tests/BaseControllerTest.cs

@@ -0,0 +1,207 @@
+using Newtonsoft.Json;
+using Newtonsoft.Json.Linq;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Net;
+using System.Net.Http;
+using System.Net.Http.Headers;
+using System.Text;
+using System.Threading.Tasks;
+using Xunit;
+using ZhonTai;
+using ZhonTai.Admin.Core.Configs;
+using ZhonTai.Admin.Core.Consts;
+using ZhonTai.Admin.Core.Enums;
+using ZhonTai.Admin.Services.Auth.Dto;
+using ZhonTai.Admin.Tools.Cache;
+using ZhonTai.Admin.Tools.Captcha;
+
+namespace IMES_Middleware_Platform.Tests
+{
+    /// <summary>
+    /// Api测试基础
+    /// </summary>
+    public class BaseControllerTest : BaseTest
+    {
+        private readonly ICacheTool _cache;
+        private readonly ICaptchaTool _captcha;
+        private readonly AppConfig _appConfig;
+
+        protected BaseControllerTest()
+        {
+            _cache = GetService<ICacheTool>();
+            _captcha = GetService<ICaptchaTool>();
+            _appConfig = GetService<AppConfig>();
+        }
+
+        public static HttpContent GetHttpContent(object input, string contentType = "application/json;charset=UTF-8", ContentTypeEnum contentTypeEnum = ContentTypeEnum.Json)
+        {
+            // HttpContent httpContent = new StringContent(JsonConvert.SerializeObject(input));
+            var content = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(input));
+            HttpContent httpContent;
+            if (contentTypeEnum == ContentTypeEnum.FormData)
+            {
+                httpContent = new FormUrlEncodedContent(JsonConvert.DeserializeObject<Dictionary<string, string>>(JsonConvert.SerializeObject(input)));
+            }
+            else
+            {
+                httpContent = new ByteArrayContent(content);
+            }
+            httpContent.Headers.ContentType = MediaTypeHeaderValue.Parse(contentType);
+            return httpContent;
+        }
+
+        public static HttpContent GetHttpContent(object input, ContentTypeEnum contentTypeEnum)
+        {
+            var contentType = contentTypeEnum switch
+            {
+                ContentTypeEnum.Json => "application/json;charset=UTF-8",
+                ContentTypeEnum.FormData => "application/x-www-form-urlencoded;charset=UTF-8",
+                _ => string.Empty
+            };
+            return GetHttpContent(input, contentType, contentTypeEnum);
+        }
+
+        public async Task<T> GetResult<T>(string apiPath, object input = null, bool checkStatus = true)
+        {
+            await Login();
+            if (input != null)
+            {
+                var queryParams = ToParams(input);
+                apiPath = apiPath.IndexOf('?') > -1 ? $"{apiPath}&{queryParams}" : $"{apiPath}?{queryParams}";
+            }
+            var res = await Client.GetAsync(apiPath);
+            if (checkStatus)
+            {
+                Assert.Equal(HttpStatusCode.OK, res.StatusCode);
+            }
+            var content = await res.Content.ReadAsStringAsync();
+            return content.NotNull() ? JsonConvert.DeserializeObject<T>(content) : default;
+        }
+
+        public async Task<T> PostResult<T>(string apiPath, object input = null, bool checkStatus = true, string contentType = "application/json;charset=UTF-8")
+        {
+            await Login();
+            var res = await Client.PostAsync(apiPath, GetHttpContent(input, contentType));
+            if (checkStatus)
+            {
+                Assert.Equal(HttpStatusCode.OK, res.StatusCode);
+            }
+            var content = await res.Content.ReadAsStringAsync();
+            return content.NotNull() ? JsonConvert.DeserializeObject<T>(content) : default;
+        }
+
+        public async Task<string> PostResultAndGetContent(string apiPath, object input = null, bool checkStatus = true, string contentType = "application/json;charset=UTF-8")
+        {
+            //application/json;charset=UTF-8
+            //application/x-www-form-urlencoded;charset=UTF-8
+            await Login();
+            var res = await Client.PostAsync(apiPath, GetHttpContent(input, contentType));
+            if (checkStatus)
+            {
+                Assert.Equal(HttpStatusCode.OK, res.StatusCode);
+            }
+            var content = await res.Content.ReadAsStringAsync();
+            return content;
+        }
+
+        public async Task<T> PutResult<T>(string apiPath, object input = null, bool checkStatus = true, string contentType = "application/json;charset=UTF-8")
+        {
+            await Login();
+            var res = await Client.PutAsync(apiPath, GetHttpContent(input, contentType));
+            if (checkStatus)
+            {
+                Assert.Equal(HttpStatusCode.OK, res.StatusCode);
+            }
+            var content = await res.Content.ReadAsStringAsync();
+            return content.NotNull() ? JsonConvert.DeserializeObject<T>(content) : default;
+        }
+
+        public async Task<T> DeleteResult<T>(string apiPath, object input = null, bool checkStatus = true)
+        {
+            await Login();
+            if (input != null)
+            {
+                var queryParams = ToParams(input);
+                apiPath = apiPath.IndexOf('?') > -1 ? $"{apiPath}&{queryParams}" : $"{apiPath}?{queryParams}";
+            }
+            var res = await Client.DeleteAsync(apiPath);
+            if (checkStatus)
+            {
+                Assert.Equal(HttpStatusCode.OK, res.StatusCode);
+            }
+            var content = await res.Content.ReadAsStringAsync();
+            return content.NotNull() ? JsonConvert.DeserializeObject<T>(content) : default;
+        }
+
+        public async Task<ResultOutput<dynamic>> GetResult(string apiPath, object input = null, bool checkStatus = true)
+        {
+            return await GetResult<ResultOutput<dynamic>>(apiPath, input, checkStatus);
+        }
+
+        public async Task<ResultOutput<dynamic>> PostResult(string apiPath, object input = null, bool checkStatus = true, string contentType = "application/json;charset=UTF-8")
+        {
+            return await PostResult<ResultOutput<dynamic>>(apiPath, input, checkStatus, contentType);
+        }
+
+        public async Task<ResultOutput<dynamic>> PutResult(string apiPath, object input = null, bool checkStatus = true, string contentType = "application/json;charset=UTF-8")
+        {
+            return await PutResult<ResultOutput<dynamic>>(apiPath, input, checkStatus, contentType);
+        }
+
+        public async Task<ResultOutput<dynamic>> DeleteResult(string apiPath, object input = null, bool checkStatus = true)
+        {
+            return await DeleteResult<ResultOutput<dynamic>>(apiPath, input, checkStatus);
+        }
+
+        public async Task Login(AuthLoginInput input = null)
+        {
+            var authorization = Client.DefaultRequestHeaders.FirstOrDefault(a => a.Key == "Authorization");
+            if (authorization.Key != null)
+            {
+                return;
+            }
+
+            if (input == null)
+            {
+                input = new AuthLoginInput()
+                {
+                    UserName = "admin",
+                    Password = "111111"
+                };
+            }
+
+            //Client.DefaultRequestHeaders.Connection.Add("keep-alive");
+            Client.DefaultRequestHeaders.Add("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36");
+
+            var result = await Client.PostAsync($"/api/admin/auth/login", GetHttpContent(input));
+            var content = await result.Content.ReadAsStringAsync();
+            var jObject = JsonConvert.DeserializeObject<JObject>(content);
+            var token = jObject["data"]["token"];
+
+            Client.DefaultRequestHeaders.Add("Authorization", $"Bearer {token}");
+        }
+
+        public static string ToParams(object source)
+        {
+            var stringBuilder = new StringBuilder(string.Empty);
+            if (source == null)
+            {
+                return "";
+            }
+
+            var entries = from PropertyDescriptor property in TypeDescriptor.GetProperties(source)
+                          let value = property.GetValue(source)
+                          where value != null
+                          select (property.Name, value);
+
+            foreach (var (name, value) in entries)
+            {
+                stringBuilder.Append(WebUtility.UrlEncode(name) + "=" + WebUtility.UrlEncode(value + "") + "&");
+            }
+
+            return stringBuilder.ToString().Trim('&');
+        }
+    }
+}

+ 40 - 0
IMES-Middleware-Platform/src/tests/IMES-Middleware-Platform.Tests/BaseTest.cs

@@ -0,0 +1,40 @@
+using Microsoft.AspNetCore.Mvc.Testing;
+using Microsoft.AspNetCore.TestHost;
+using Microsoft.Extensions.DependencyInjection;
+using System;
+using System.Net.Http;
+using ZhonTai.Admin.Core.Configs;
+using ZhonTai.Common.Helpers;
+
+namespace IMES_Middleware_Platform.Tests
+{
+    /// <summary>
+    /// 测试基础
+    /// </summary>
+    public class BaseTest
+    {
+        protected AppConfig AppConfig { get; }
+        protected TestServer Server { get; }
+        protected HttpClient Client { get; }
+        protected IServiceProvider ServiceProvider { get; }
+
+        protected BaseTest()
+        {
+            AppConfig = ConfigHelper.Get<AppConfig>("appconfig") ?? new AppConfig();
+            var application = new WebApplicationFactory<Program>();
+            Client = application.CreateClient();
+            Server = application.Server;
+            ServiceProvider = Server.Services;
+        }
+
+        public T GetService<T>()
+        {
+            return ServiceProvider.GetService<T>();
+        }
+
+        public T GetRequiredService<T>()
+        {
+            return ServiceProvider.GetRequiredService<T>();
+        }
+    }
+}

+ 71 - 0
IMES-Middleware-Platform/src/tests/IMES-Middleware-Platform.Tests/Controllers/ModuleControllerTest.cs

@@ -0,0 +1,71 @@
+using IMES_Middleware_Platform.Api.Domain.Module.Dto;
+using IMES_Middleware_Platform.Api.Services.Module.Input;
+using IMES_Middleware_Platform.Api.Services.Module.Output;
+using System.Threading.Tasks;
+using Xunit;
+using ZhonTai.Admin.Core.Dto;
+
+namespace IMES_Middleware_Platform.Tests.Controllers
+{
+    /// <summary>
+    /// 模块Api测试
+    /// </summary>
+    public class ModuleControllerTest : BaseControllerTest
+    {
+        public ModuleControllerTest() : base()
+        {
+        }
+
+        [Fact]
+        public async Task Add()
+        {
+            var input = new ModuleAddInput
+            {
+                Name = "new-module"
+            };
+
+            var res = await PostResult($"/api/app/module/add", input);
+            Assert.True(res.Success);
+        }
+
+        [Fact]
+        public async Task Update()
+        {
+            var output = await GetResult<ResultOutput<ModuleGetOutput>>("/api/app/module/get?id=278518195769413");
+            var res = await PutResult($"/api/app/module/update", output.Data);
+            Assert.True(res.Success);
+        }
+
+        [Fact]
+        public async Task Get()
+        {
+            var res = await GetResult<ResultOutput<ModuleGetOutput>>("/api/app/module/get?id=278518195769413");
+            Assert.True(res.Success);
+        }
+
+        [Fact]
+        public async Task GetPage()
+        {
+            await Login();
+            var input = new PageInput<ModuleGetPageDto>
+            {
+                CurrentPage = 1,
+                PageSize = 20,
+                Filter = new ModuleGetPageDto
+                {
+                    Name = "module"
+                }
+            };
+
+            var res = await PostResult($"/api/app/module/get-page", input);
+            Assert.True(res.Success);
+        }
+
+        [Fact]
+        public async Task Delete()
+        {
+            var res = await DeleteResult($"/api/app/module/soft-delete?{ToParams(new { id = 278551714857029 })}");
+            Assert.True(res.Success);
+        }
+    }
+}

+ 23 - 0
IMES-Middleware-Platform/src/tests/IMES-Middleware-Platform.Tests/IMES-Middleware-Platform.Tests.csproj

@@ -0,0 +1,23 @@
+<Project Sdk="Microsoft.NET.Sdk">
+	<PropertyGroup>
+		<Description>IMES_Middleware_Platform测试库</Description>
+		<TargetFramework>net7.0</TargetFramework>
+		<IsPackable>false</IsPackable>
+	</PropertyGroup>
+
+  <ItemGroup>
+    <PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" Version="7.0.9" />
+    <PackageReference Include="Microsoft.AspNetCore.TestHost" Version="7.0.9" />
+    <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.6.3" />
+    <PackageReference Include="xunit" Version="2.5.0" />
+    <PackageReference Include="xunit.runner.visualstudio" Version="2.5.0">
+      <PrivateAssets>all</PrivateAssets>
+      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
+    </PackageReference>
+  </ItemGroup>
+
+  <ItemGroup>
+    <ProjectReference Include="..\..\hosts\IMES-Middleware-Platform.Host\IMES-Middleware-Platform.Host.csproj" />
+  </ItemGroup>
+
+</Project>

+ 28 - 0
IMES-Middleware-Platform/src/tests/IMES-Middleware-Platform.Tests/Repositories/ModuelRepositoryTest.cs

@@ -0,0 +1,28 @@
+using IMES_Middleware_Platform.Api.Domain.Module;
+using Xunit;
+
+namespace IMES_Middleware_Platform.Tests.Repositories
+{
+    /// <summary>
+    /// 模块仓储测试
+    /// </summary>
+    public class ModuelRepositoryTest : BaseTest
+    {
+        private readonly IModuleRepository _moduleRepository;
+
+        public ModuelRepositoryTest()
+        {
+            _moduleRepository = GetService<IModuleRepository>();
+        }
+
+        [Fact]
+        public async void GetAsync()
+        {
+            var name = "module";
+            var module = await _moduleRepository.Select.DisableGlobalFilter("Tenant")
+                .Where(a => a.Name == name).ToOneAsync();
+            Assert.Equal(name, module?.Name);
+
+        }
+    }
+}

+ 29 - 0
IMES-Middleware-Platform/src/tests/IMES-Middleware-Platform.Tests/ResultOutput.cs

@@ -0,0 +1,29 @@
+namespace IMES_Middleware_Platform.Tests
+{
+    /// <summary>
+    /// 返回结果
+    /// </summary>
+    /// <typeparam name="T"></typeparam>
+    public class ResultOutput<T>
+    {
+        /// <summary>
+        /// 是否成功标记
+        /// </summary>
+        public bool Success { get; set; }
+
+        /// <summary>
+        /// 状态码
+        /// </summary>
+        public string Code { get; set; }
+
+        /// <summary>
+        /// 消息
+        /// </summary>
+        public string Msg { get; set; }
+
+        /// <summary>
+        /// 数据
+        /// </summary>
+        public T Data { get; set; }
+    }
+}

+ 28 - 0
IMES-Middleware-Platform/src/tests/IMES-Middleware-Platform.Tests/Services/ModuleServiceTest.cs

@@ -0,0 +1,28 @@
+using IMES_Middleware_Platform.Api.Domain.Module.Dto;
+using IMES_Middleware_Platform.Api.Services.Module;
+using Xunit;
+using ZhonTai.Admin.Core.Dto;
+
+namespace IMES_Middleware_Platform.Tests.Services
+{
+    /// <summary>
+    /// 模块服务测试
+    /// </summary>
+    public class ModuleServiceTest : BaseTest
+    {
+        private readonly IModuleService _moduleService;
+
+        public ModuleServiceTest()
+        {
+            _moduleService = GetService<IModuleService>();
+        }
+
+        [Fact]
+        public async void GetPageAsync()
+        {
+            var input = new PageInput<ModuleGetPageDto>() { };
+            var output = await _moduleService.GetPageAsync(input);
+            Assert.True(output?.Total >= 0);
+        }
+    }
+}