diff --git a/Readme.md b/Readme.md
index 6eddf0a8..1d5fd136 100644
--- a/Readme.md
+++ b/Readme.md
@@ -1,88 +1,62 @@
-[Abp Vnext Pro](https://github.com/WangJunZzz/abp-vnext-pro) 的 Vue 实现版本
-开箱即用的中后台前端/设计解决方案
+ [Abp Vnext Pro](https://github.com/WangJunZzz/abp-vnext-pro) 的 Vue3 实现版本 开箱即用的中后台前端/设计解决方案
+
-### 知识点
+### 说明
+
+- main分支为主要开发分支,后续都基于此分支维护,该分支前端基于vue3.0,Typescript,如果要使用Vue请切换到Vue2分支。
- .Net Core5.0
-- Abp Vnext 4.x ,
-- Ant Design, Vue2.x
-- Mysql,Redis,Hangfire,ES(日志可选),Nocas(可选,选择nocas分支),RabbitMq(未集成,计划中)
+- Abp Vnext 4.2 ,
+- Ant Design, Vben Admin [前端文档](https://vvbin.cn/doc-next/)
+- Mysql,Redis,Hangfire,ES(日志可选)
- 微服务架构设计, DDD 实践
- 容器化 CI CD
- Xunit 单元测试
-### 系统功能
-
-- 用户管理
-- 角色管理
-- 设置管理
-- 字典管理
-- 后台作业
-- ES 日志
-- 暂时不支持多租户管理(后续考虑)
-
### 对接思路
- 前端
- 通过 token 调用 /api/abp/application-configuration 获取应用级别信息,包括权限,多语言,保存在 Store 中;
- 多语言基于前端,后端 Api 的多语言基于 abp 自带的;
- - 菜单权限封装,在 route/config.js 下配置菜单,属性 meta.policy 不传或者等于\*代表不验证权限
- - 按钮权限,在 utils/permission.js 下,isGranted('策略名'),例如:v-if="isGranted('AbpIdentity.Roles.Create')"
+ - 配置菜单,属性 meta.policy 不传代表不验证权限
+ - 按钮权限,v-auth 例如:v-auth=('AbpIdentity.Roles.Create')
- 后端
- 项目不一定要基于 IdentityServer4,所以新增了一个登陆方法,生成 Token.
- - 集成 ES 日志
- - 集成 Redis
- - 集成 Hangfire
- - 集成 SettingUI
+ - IdentityServer4的已经独立出来,也会开源。
### 使用
-#### clone
-
-```bash
-$ git clone https://github.com/WangJunZzz/abp-vnext-pro
-```
-
-#### 后端
-
-- 修改 Mysql,Redis 连接字符串
-- 迁移数据:执行 Zzz.DbMigrator
-
-#### 前端
-
-```bash
-- yarn or npm i
-- npm run dev
-```
-
-#### 该项目也是一个模板项目
-
-- 本地安装
-
-```bash
-# 在cotnent目录下执行
- dotnet new -i .\content
-```
-
-- 新建项目
-
-```bash
-dotnet new Zzz --name 你的项目名称(不支持名词xxx.xxx,只支持一级)
-```
+- 下载代码生成器,Git仓库(https://github.com/WangJunZzz/abp-vnext-pro-gui)
+
+ 
+
+- 下载模板之后再当前项目src\AbpVnextPro.GUI\bin\Debug\net5.0-windows\decompression可以看到生成的源码
+- 启动
+ - 前端yarn
+
+ - 后端修改mysql和redis连接字符串
+
+ - 执行tools下的迁移控制台程序
+
+ - 启动host下httpapi.host即可
+
+ - host下的public可以忽略,这个用来做暴露第三方接口的,通过id4授权。
+
+
#### 参与贡献
diff --git a/content/aspnetcore/.gitignore b/content/aspnetcore/.gitignore
new file mode 100644
index 00000000..abbca74d
--- /dev/null
+++ b/content/aspnetcore/.gitignore
@@ -0,0 +1,265 @@
+## Ignore Visual Studio temporary files, build results, and
+## files generated by popular Visual Studio add-ons.
+
+# User-specific files
+*.suo
+*.user
+*.userosscache
+*.sln.docstates
+
+# User-specific files (MonoDevelop/Xamarin Studio)
+*.userprefs
+
+# Build results
+[Dd]ebug/
+[Dd]ebugPublic/
+[Rr]elease/
+[Rr]eleases/
+x64/
+x86/
+bld/
+[Bb]in/
+[Oo]bj/
+[Ll]og/
+
+# Visual Studio 2015 cache/options directory
+.vs/
+# Uncomment if you have tasks that create the project's static files in wwwroot
+#wwwroot/
+
+# MSTest test Results
+[Tt]est[Rr]esult*/
+[Bb]uild[Ll]og.*
+
+# NUNIT
+*.VisualState.xml
+TestResult.xml
+
+# Build Results of an ATL Project
+[Dd]ebugPS/
+[Rr]eleasePS/
+dlldata.c
+
+# DNX
+project.lock.json
+artifacts/
+
+*_i.c
+*_p.c
+*_i.h
+*.ilk
+*.meta
+*.obj
+*.pch
+*.pdb
+*.pgc
+*.pgd
+*.rsp
+*.sbr
+*.tlb
+*.tli
+*.tlh
+*.tmp
+*.tmp_proj
+*.log
+*.vspscc
+*.vssscc
+.builds
+*.pidb
+*.svclog
+*.scc
+
+# Chutzpah Test files
+_Chutzpah*
+
+# Visual C++ cache files
+ipch/
+*.aps
+*.ncb
+*.opendb
+*.opensdf
+*.sdf
+*.cachefile
+*.VC.db
+*.VC.VC.opendb
+
+# Visual Studio profiler
+*.psess
+*.vsp
+*.vspx
+*.sap
+
+# TFS 2012 Local Workspace
+$tf/
+
+# Guidance Automation Toolkit
+*.gpState
+
+# ReSharper is a .NET coding add-in
+_ReSharper*/
+*.[Rr]e[Ss]harper
+*.DotSettings.user
+
+# JustCode is a .NET coding add-in
+.JustCode
+
+# TeamCity is a build add-in
+_TeamCity*
+
+# DotCover is a Code Coverage Tool
+*.dotCover
+
+# NCrunch
+_NCrunch_*
+.*crunch*.local.xml
+nCrunchTemp_*
+
+# MightyMoose
+*.mm.*
+AutoTest.Net/
+
+# Web workbench (sass)
+.sass-cache/
+
+# Installshield output folder
+[Ee]xpress/
+
+# DocProject is a documentation generator add-in
+DocProject/buildhelp/
+DocProject/Help/*.HxT
+DocProject/Help/*.HxC
+DocProject/Help/*.hhc
+DocProject/Help/*.hhk
+DocProject/Help/*.hhp
+DocProject/Help/Html2
+DocProject/Help/html
+
+# Click-Once directory
+publish/
+
+# Publish Web Output
+*.[Pp]ublish.xml
+*.azurePubxml
+# TODO: Comment the next line if you want to checkin your web deploy settings
+# but database connection strings (with potential passwords) will be unencrypted
+*.pubxml
+*.publishproj
+
+# Microsoft Azure Web App publish settings. Comment the next line if you want to
+# checkin your Azure Web App publish settings, but sensitive information contained
+# in these scripts will be unencrypted
+PublishScripts/
+
+# NuGet Packages
+*.nupkg
+# The packages folder can be ignored because of Package Restore
+**/packages/*
+# except build/, which is used as an MSBuild target.
+!**/packages/build/
+# Uncomment if necessary however generally it will be regenerated when needed
+#!**/packages/repositories.config
+# NuGet v3's project.json files produces more ignoreable files
+*.nuget.props
+*.nuget.targets
+
+# Microsoft Azure Build Output
+csx/
+*.build.csdef
+
+# Microsoft Azure Emulator
+ecf/
+rcf/
+
+# Windows Store app package directories and files
+AppPackages/
+BundleArtifacts/
+Package.StoreAssociation.xml
+_pkginfo.txt
+
+# Visual Studio cache files
+# files ending in .cache can be ignored
+*.[Cc]ache
+# but keep track of directories ending in .cache
+!*.[Cc]ache/
+
+# Others
+ClientBin/
+~$*
+*~
+*.dbmdl
+*.dbproj.schemaview
+*.pfx
+*.publishsettings
+node_modules/
+orleans.codegen.cs
+
+# Since there are multiple workflows, uncomment next line to ignore bower_components
+# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
+#bower_components/
+
+# RIA/Silverlight projects
+Generated_Code/
+
+# Backup & report files from converting an old project file
+# to a newer Visual Studio version. Backup files are not needed,
+# because we have git ;-)
+_UpgradeReport_Files/
+Backup*/
+UpgradeLog*.XML
+UpgradeLog*.htm
+
+# SQL Server files
+*.mdf
+*.ldf
+
+# Business Intelligence projects
+*.rdl.data
+*.bim.layout
+*.bim_*.settings
+
+# Microsoft Fakes
+FakesAssemblies/
+
+# GhostDoc plugin setting file
+*.GhostDoc.xml
+
+# Node.js Tools for Visual Studio
+.ntvs_analysis.dat
+
+# Visual Studio 6 build log
+*.plg
+
+# Visual Studio 6 workspace options file
+*.opt
+
+# Visual Studio LightSwitch build output
+**/*.HTMLClient/GeneratedArtifacts
+**/*.DesktopClient/GeneratedArtifacts
+**/*.DesktopClient/ModelManifest.xml
+**/*.Server/GeneratedArtifacts
+**/*.Server/ModelManifest.xml
+_Pvt_Extensions
+
+# Paket dependency manager
+.paket/paket.exe
+paket-files/
+
+# FAKE - F# Make
+.fake/
+
+# JetBrains Rider
+.idea/
+*.sln.iml
+
+# TemplateManagement
+content/src/TemplateManagement.Web/Logs/*
+content/src/TemplateManagement.Web.Host/Logs/*
+content/src/TemplateManagement.IdentityServer/Logs/*
+content/src/TemplateManagement.HttpApi.Host/Logs/*
+content/src/TemplateManagement.HttpApi.Host/Logs/*
+content/src/TemplateManagement.DbMigrator/Logs/*
+/content/aspnetcore/src/TemplateManagement.HttpApi.Host/App_Data
+.vscode/
+.idea/
+/aspnetcore/host/CompanyName.ProjectName.HttpApi.Host/logs
+/host/CompanyName.ProjectName.HttpApi.Host/logs
diff --git a/content/aspnetcore/.prettierrc b/content/aspnetcore/.prettierrc
deleted file mode 100644
index 56af76bd..00000000
--- a/content/aspnetcore/.prettierrc
+++ /dev/null
@@ -1,5 +0,0 @@
-{
- "singleQuote": true,
- "useTabs": false,
- "tabWidth": 4
-}
diff --git a/content/aspnetcore/CompanyName.ProjectName.sln b/content/aspnetcore/CompanyName.ProjectName.sln
new file mode 100644
index 00000000..476ecd13
--- /dev/null
+++ b/content/aspnetcore/CompanyName.ProjectName.sln
@@ -0,0 +1,141 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 16
+VisualStudioVersion = 16.0.31105.61
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{89D5BC7F-D114-439A-AC67-769337099E76}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "host", "host", "{CD48FBEA-0B6B-4E68-8E46-0680DAFF98A5}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tools", "tools", "{5578AB16-AFEE-4E14-8C8D-D4E5C346233F}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{BD109692-20BF-44ED-BFAA-533B40B1DAB7}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CompanyName.ProjectName.Application", "src\CompanyName.ProjectName.Application\CompanyName.ProjectName.Application.csproj", "{1F0143A4-8B93-4A55-B331-1B74AB828188}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CompanyName.ProjectName.Application.Contracts", "src\CompanyName.ProjectName.Application.Contracts\CompanyName.ProjectName.Application.Contracts.csproj", "{54B2220C-8B33-41F3-94C7-499F540BBA28}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CompanyName.ProjectName.Domain", "src\CompanyName.ProjectName.Domain\CompanyName.ProjectName.Domain.csproj", "{567B7829-C8C7-49F3-8E37-68792338E53C}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CompanyName.ProjectName.Domain.Shared", "src\CompanyName.ProjectName.Domain.Shared\CompanyName.ProjectName.Domain.Shared.csproj", "{4CC4BE56-AA1D-47F6-8626-E737296938E3}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CompanyName.ProjectName.EntityFrameworkCore", "src\CompanyName.ProjectName.EntityFrameworkCore\CompanyName.ProjectName.EntityFrameworkCore.csproj", "{1EEED09F-F2CE-45C1-AC13-C437D6DCCC89}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CompanyName.ProjectName.EntityFrameworkCore.DbMigrations", "src\CompanyName.ProjectName.EntityFrameworkCore.DbMigrations\CompanyName.ProjectName.EntityFrameworkCore.DbMigrations.csproj", "{93239C2D-4555-4328-9744-76EA9DF389F6}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CompanyName.ProjectName.HttpApi", "src\CompanyName.ProjectName.HttpApi\CompanyName.ProjectName.HttpApi.csproj", "{F5A9225F-7F9D-4C89-AC39-BAC0D4239C39}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CompanyName.ProjectName.HttpApi.Client", "src\CompanyName.ProjectName.HttpApi.Client\CompanyName.ProjectName.HttpApi.Client.csproj", "{CF67F74D-C460-4A22-86E9-001E8D76B3BB}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CompanyName.ProjectName.DbMigrator", "tools\CompanyName.ProjectName.DbMigrator\CompanyName.ProjectName.DbMigrator.csproj", "{EA0E224A-1D62-4E63-B9FE-56F225463519}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CompanyName.ProjectName.Application.Tests", "test\CompanyName.ProjectName.Application.Tests\CompanyName.ProjectName.Application.Tests.csproj", "{BD47E3FB-D80E-4D0C-8F0B-22130C0A6132}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CompanyName.ProjectName.Domain.Tests", "test\CompanyName.ProjectName.Domain.Tests\CompanyName.ProjectName.Domain.Tests.csproj", "{B1AF3A73-9229-4803-9F8F-0A9076883B73}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CompanyName.ProjectName.EntityFrameworkCore.Tests", "test\CompanyName.ProjectName.EntityFrameworkCore.Tests\CompanyName.ProjectName.EntityFrameworkCore.Tests.csproj", "{02DF9409-5200-45B0-9786-B18261ACC459}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CompanyName.ProjectName.HttpApi.Client.ConsoleTestApp", "test\CompanyName.ProjectName.HttpApi.Client.ConsoleTestApp\CompanyName.ProjectName.HttpApi.Client.ConsoleTestApp.csproj", "{D49278D0-BE89-4F91-AB14-D52B88ACEDC3}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CompanyName.ProjectName.TestBase", "test\CompanyName.ProjectName.TestBase\CompanyName.ProjectName.TestBase.csproj", "{A0970646-66C1-410E-A79E-9543EF44C26F}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CompanyName.ProjectName.HttpApi.Host", "host\CompanyName.ProjectName.HttpApi.Host\CompanyName.ProjectName.HttpApi.Host.csproj", "{83C944A1-F73D-4DC5-8045-E07F31D90B8D}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CompanyName.ProjectName.PublicApi.Host", "host\CompanyName.ProjectName.PublicApi.Host\CompanyName.ProjectName.PublicApi.Host.csproj", "{14FD618E-EF80-4061-B517-F926C8190A9D}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {1F0143A4-8B93-4A55-B331-1B74AB828188}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {1F0143A4-8B93-4A55-B331-1B74AB828188}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {1F0143A4-8B93-4A55-B331-1B74AB828188}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {1F0143A4-8B93-4A55-B331-1B74AB828188}.Release|Any CPU.Build.0 = Release|Any CPU
+ {54B2220C-8B33-41F3-94C7-499F540BBA28}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {54B2220C-8B33-41F3-94C7-499F540BBA28}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {54B2220C-8B33-41F3-94C7-499F540BBA28}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {54B2220C-8B33-41F3-94C7-499F540BBA28}.Release|Any CPU.Build.0 = Release|Any CPU
+ {567B7829-C8C7-49F3-8E37-68792338E53C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {567B7829-C8C7-49F3-8E37-68792338E53C}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {567B7829-C8C7-49F3-8E37-68792338E53C}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {567B7829-C8C7-49F3-8E37-68792338E53C}.Release|Any CPU.Build.0 = Release|Any CPU
+ {4CC4BE56-AA1D-47F6-8626-E737296938E3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {4CC4BE56-AA1D-47F6-8626-E737296938E3}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {4CC4BE56-AA1D-47F6-8626-E737296938E3}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {4CC4BE56-AA1D-47F6-8626-E737296938E3}.Release|Any CPU.Build.0 = Release|Any CPU
+ {1EEED09F-F2CE-45C1-AC13-C437D6DCCC89}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {1EEED09F-F2CE-45C1-AC13-C437D6DCCC89}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {1EEED09F-F2CE-45C1-AC13-C437D6DCCC89}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {1EEED09F-F2CE-45C1-AC13-C437D6DCCC89}.Release|Any CPU.Build.0 = Release|Any CPU
+ {93239C2D-4555-4328-9744-76EA9DF389F6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {93239C2D-4555-4328-9744-76EA9DF389F6}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {93239C2D-4555-4328-9744-76EA9DF389F6}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {93239C2D-4555-4328-9744-76EA9DF389F6}.Release|Any CPU.Build.0 = Release|Any CPU
+ {F5A9225F-7F9D-4C89-AC39-BAC0D4239C39}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {F5A9225F-7F9D-4C89-AC39-BAC0D4239C39}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {F5A9225F-7F9D-4C89-AC39-BAC0D4239C39}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {F5A9225F-7F9D-4C89-AC39-BAC0D4239C39}.Release|Any CPU.Build.0 = Release|Any CPU
+ {CF67F74D-C460-4A22-86E9-001E8D76B3BB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {CF67F74D-C460-4A22-86E9-001E8D76B3BB}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {CF67F74D-C460-4A22-86E9-001E8D76B3BB}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {CF67F74D-C460-4A22-86E9-001E8D76B3BB}.Release|Any CPU.Build.0 = Release|Any CPU
+ {EA0E224A-1D62-4E63-B9FE-56F225463519}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {EA0E224A-1D62-4E63-B9FE-56F225463519}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {EA0E224A-1D62-4E63-B9FE-56F225463519}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {EA0E224A-1D62-4E63-B9FE-56F225463519}.Release|Any CPU.Build.0 = Release|Any CPU
+ {BD47E3FB-D80E-4D0C-8F0B-22130C0A6132}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {BD47E3FB-D80E-4D0C-8F0B-22130C0A6132}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {BD47E3FB-D80E-4D0C-8F0B-22130C0A6132}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {BD47E3FB-D80E-4D0C-8F0B-22130C0A6132}.Release|Any CPU.Build.0 = Release|Any CPU
+ {B1AF3A73-9229-4803-9F8F-0A9076883B73}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {B1AF3A73-9229-4803-9F8F-0A9076883B73}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {B1AF3A73-9229-4803-9F8F-0A9076883B73}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {B1AF3A73-9229-4803-9F8F-0A9076883B73}.Release|Any CPU.Build.0 = Release|Any CPU
+ {02DF9409-5200-45B0-9786-B18261ACC459}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {02DF9409-5200-45B0-9786-B18261ACC459}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {02DF9409-5200-45B0-9786-B18261ACC459}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {02DF9409-5200-45B0-9786-B18261ACC459}.Release|Any CPU.Build.0 = Release|Any CPU
+ {D49278D0-BE89-4F91-AB14-D52B88ACEDC3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {D49278D0-BE89-4F91-AB14-D52B88ACEDC3}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {D49278D0-BE89-4F91-AB14-D52B88ACEDC3}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {D49278D0-BE89-4F91-AB14-D52B88ACEDC3}.Release|Any CPU.Build.0 = Release|Any CPU
+ {A0970646-66C1-410E-A79E-9543EF44C26F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {A0970646-66C1-410E-A79E-9543EF44C26F}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {A0970646-66C1-410E-A79E-9543EF44C26F}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {A0970646-66C1-410E-A79E-9543EF44C26F}.Release|Any CPU.Build.0 = Release|Any CPU
+ {83C944A1-F73D-4DC5-8045-E07F31D90B8D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {83C944A1-F73D-4DC5-8045-E07F31D90B8D}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {83C944A1-F73D-4DC5-8045-E07F31D90B8D}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {83C944A1-F73D-4DC5-8045-E07F31D90B8D}.Release|Any CPU.Build.0 = Release|Any CPU
+ {14FD618E-EF80-4061-B517-F926C8190A9D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {14FD618E-EF80-4061-B517-F926C8190A9D}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {14FD618E-EF80-4061-B517-F926C8190A9D}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {14FD618E-EF80-4061-B517-F926C8190A9D}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(NestedProjects) = preSolution
+ {1F0143A4-8B93-4A55-B331-1B74AB828188} = {89D5BC7F-D114-439A-AC67-769337099E76}
+ {54B2220C-8B33-41F3-94C7-499F540BBA28} = {89D5BC7F-D114-439A-AC67-769337099E76}
+ {567B7829-C8C7-49F3-8E37-68792338E53C} = {89D5BC7F-D114-439A-AC67-769337099E76}
+ {4CC4BE56-AA1D-47F6-8626-E737296938E3} = {89D5BC7F-D114-439A-AC67-769337099E76}
+ {1EEED09F-F2CE-45C1-AC13-C437D6DCCC89} = {89D5BC7F-D114-439A-AC67-769337099E76}
+ {93239C2D-4555-4328-9744-76EA9DF389F6} = {89D5BC7F-D114-439A-AC67-769337099E76}
+ {F5A9225F-7F9D-4C89-AC39-BAC0D4239C39} = {89D5BC7F-D114-439A-AC67-769337099E76}
+ {CF67F74D-C460-4A22-86E9-001E8D76B3BB} = {89D5BC7F-D114-439A-AC67-769337099E76}
+ {EA0E224A-1D62-4E63-B9FE-56F225463519} = {5578AB16-AFEE-4E14-8C8D-D4E5C346233F}
+ {BD47E3FB-D80E-4D0C-8F0B-22130C0A6132} = {BD109692-20BF-44ED-BFAA-533B40B1DAB7}
+ {B1AF3A73-9229-4803-9F8F-0A9076883B73} = {BD109692-20BF-44ED-BFAA-533B40B1DAB7}
+ {02DF9409-5200-45B0-9786-B18261ACC459} = {BD109692-20BF-44ED-BFAA-533B40B1DAB7}
+ {D49278D0-BE89-4F91-AB14-D52B88ACEDC3} = {BD109692-20BF-44ED-BFAA-533B40B1DAB7}
+ {A0970646-66C1-410E-A79E-9543EF44C26F} = {BD109692-20BF-44ED-BFAA-533B40B1DAB7}
+ {83C944A1-F73D-4DC5-8045-E07F31D90B8D} = {CD48FBEA-0B6B-4E68-8E46-0680DAFF98A5}
+ {14FD618E-EF80-4061-B517-F926C8190A9D} = {CD48FBEA-0B6B-4E68-8E46-0680DAFF98A5}
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {09E984DB-3FDA-4D86-954E-4C5197470D3F}
+ EndGlobalSection
+EndGlobal
diff --git a/content/aspnetcore/NuGet.Config b/content/aspnetcore/NuGet.Config
index 1dcaa402..0d5eaacd 100644
--- a/content/aspnetcore/NuGet.Config
+++ b/content/aspnetcore/NuGet.Config
@@ -1,6 +1,10 @@
+
+
+
+
-
+
\ No newline at end of file
diff --git a/content/aspnetcore/Zzz.sln b/content/aspnetcore/Zzz.sln
deleted file mode 100644
index 0c30763a..00000000
--- a/content/aspnetcore/Zzz.sln
+++ /dev/null
@@ -1,130 +0,0 @@
-
-Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio Version 16
-VisualStudioVersion = 16.0.29020.237
-MinimumVisualStudioVersion = 10.0.40219.1
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Zzz.Domain", "src\Zzz.Domain\Zzz.Domain.csproj", "{554AD327-6DBA-4F8F-96F8-81CE7A0C863F}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Zzz.Application", "src\Zzz.Application\Zzz.Application.csproj", "{1A94A50E-06DC-43C1-80B5-B662820EC3EB}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Zzz.EntityFrameworkCore", "src\Zzz.EntityFrameworkCore\Zzz.EntityFrameworkCore.csproj", "{C956DD76-69C8-4A9C-83EA-D17DF83340FD}"
-EndProject
-Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{CA9AC87F-097E-4F15-8393-4BC07735A5B0}"
-EndProject
-Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{04DBDB01-70F4-4E06-B468-8F87850B22BE}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Zzz.Application.Tests", "test\Zzz.Application.Tests\Zzz.Application.Tests.csproj", "{50B2631D-129C-47B3-A587-029CCD6099BC}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Zzz.EntityFrameworkCore.DbMigrations", "src\Zzz.EntityFrameworkCore.DbMigrations\Zzz.EntityFrameworkCore.DbMigrations.csproj", "{0372FA84-C517-4EB3-9A9F-B9ACAC0CA5E0}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Zzz.Domain.Shared", "src\Zzz.Domain.Shared\Zzz.Domain.Shared.csproj", "{42F719ED-8413-4895-B5B4-5AB56079BC66}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Zzz.Application.Contracts", "src\Zzz.Application.Contracts\Zzz.Application.Contracts.csproj", "{520659C8-C734-4298-A3DA-B539DB9DFC0B}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Zzz.HttpApi", "src\Zzz.HttpApi\Zzz.HttpApi.csproj", "{4164BDF7-F527-4E85-9CE6-E3C2D7426A27}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Zzz.HttpApi.Client", "src\Zzz.HttpApi.Client\Zzz.HttpApi.Client.csproj", "{3B5A0094-670D-4BB1-BFDD-61B88A8773DC}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Zzz.EntityFrameworkCore.Tests", "test\Zzz.EntityFrameworkCore.Tests\Zzz.EntityFrameworkCore.Tests.csproj", "{1FE30EB9-74A9-47F5-A9F6-7B1FAB672D81}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Zzz.TestBase", "test\Zzz.TestBase\Zzz.TestBase.csproj", "{91853F21-9CD9-4132-BC29-A7D5D84FFFE7}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Zzz.Domain.Tests", "test\Zzz.Domain.Tests\Zzz.Domain.Tests.csproj", "{E512F4D9-9375-480F-A2F6-A46509F9D824}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Zzz.DbMigrator", "src\Zzz.DbMigrator\Zzz.DbMigrator.csproj", "{AA94D832-1CCC-4715-95A9-A483F23A1A5D}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Zzz.HttpApi.Host", "src\Zzz.HttpApi.Host\Zzz.HttpApi.Host.csproj", "{748584B1-BA69-4F6A-81AA-F4BDE6BCE29D}"
-EndProject
-Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{B1908A16-8033-4AE4-9E3D-63B0BE57C0AB}"
- ProjectSection(SolutionItems) = preProject
- common.props = common.props
- NuGet.Config = NuGet.Config
- ..\..\Readme.md = ..\..\Readme.md
- EndProjectSection
-EndProject
-Global
- GlobalSection(SolutionConfigurationPlatforms) = preSolution
- Debug|Any CPU = Debug|Any CPU
- Release|Any CPU = Release|Any CPU
- EndGlobalSection
- GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {554AD327-6DBA-4F8F-96F8-81CE7A0C863F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {554AD327-6DBA-4F8F-96F8-81CE7A0C863F}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {554AD327-6DBA-4F8F-96F8-81CE7A0C863F}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {554AD327-6DBA-4F8F-96F8-81CE7A0C863F}.Release|Any CPU.Build.0 = Release|Any CPU
- {1A94A50E-06DC-43C1-80B5-B662820EC3EB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {1A94A50E-06DC-43C1-80B5-B662820EC3EB}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {1A94A50E-06DC-43C1-80B5-B662820EC3EB}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {1A94A50E-06DC-43C1-80B5-B662820EC3EB}.Release|Any CPU.Build.0 = Release|Any CPU
- {C956DD76-69C8-4A9C-83EA-D17DF83340FD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {C956DD76-69C8-4A9C-83EA-D17DF83340FD}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {C956DD76-69C8-4A9C-83EA-D17DF83340FD}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {C956DD76-69C8-4A9C-83EA-D17DF83340FD}.Release|Any CPU.Build.0 = Release|Any CPU
- {50B2631D-129C-47B3-A587-029CCD6099BC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {50B2631D-129C-47B3-A587-029CCD6099BC}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {50B2631D-129C-47B3-A587-029CCD6099BC}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {50B2631D-129C-47B3-A587-029CCD6099BC}.Release|Any CPU.Build.0 = Release|Any CPU
- {0372FA84-C517-4EB3-9A9F-B9ACAC0CA5E0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {0372FA84-C517-4EB3-9A9F-B9ACAC0CA5E0}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {0372FA84-C517-4EB3-9A9F-B9ACAC0CA5E0}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {0372FA84-C517-4EB3-9A9F-B9ACAC0CA5E0}.Release|Any CPU.Build.0 = Release|Any CPU
- {42F719ED-8413-4895-B5B4-5AB56079BC66}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {42F719ED-8413-4895-B5B4-5AB56079BC66}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {42F719ED-8413-4895-B5B4-5AB56079BC66}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {42F719ED-8413-4895-B5B4-5AB56079BC66}.Release|Any CPU.Build.0 = Release|Any CPU
- {520659C8-C734-4298-A3DA-B539DB9DFC0B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {520659C8-C734-4298-A3DA-B539DB9DFC0B}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {520659C8-C734-4298-A3DA-B539DB9DFC0B}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {520659C8-C734-4298-A3DA-B539DB9DFC0B}.Release|Any CPU.Build.0 = Release|Any CPU
- {4164BDF7-F527-4E85-9CE6-E3C2D7426A27}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {4164BDF7-F527-4E85-9CE6-E3C2D7426A27}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {4164BDF7-F527-4E85-9CE6-E3C2D7426A27}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {4164BDF7-F527-4E85-9CE6-E3C2D7426A27}.Release|Any CPU.Build.0 = Release|Any CPU
- {3B5A0094-670D-4BB1-BFDD-61B88A8773DC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {3B5A0094-670D-4BB1-BFDD-61B88A8773DC}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {3B5A0094-670D-4BB1-BFDD-61B88A8773DC}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {3B5A0094-670D-4BB1-BFDD-61B88A8773DC}.Release|Any CPU.Build.0 = Release|Any CPU
- {1FE30EB9-74A9-47F5-A9F6-7B1FAB672D81}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {1FE30EB9-74A9-47F5-A9F6-7B1FAB672D81}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {1FE30EB9-74A9-47F5-A9F6-7B1FAB672D81}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {1FE30EB9-74A9-47F5-A9F6-7B1FAB672D81}.Release|Any CPU.Build.0 = Release|Any CPU
- {91853F21-9CD9-4132-BC29-A7D5D84FFFE7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {91853F21-9CD9-4132-BC29-A7D5D84FFFE7}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {91853F21-9CD9-4132-BC29-A7D5D84FFFE7}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {91853F21-9CD9-4132-BC29-A7D5D84FFFE7}.Release|Any CPU.Build.0 = Release|Any CPU
- {E512F4D9-9375-480F-A2F6-A46509F9D824}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {E512F4D9-9375-480F-A2F6-A46509F9D824}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {E512F4D9-9375-480F-A2F6-A46509F9D824}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {E512F4D9-9375-480F-A2F6-A46509F9D824}.Release|Any CPU.Build.0 = Release|Any CPU
- {AA94D832-1CCC-4715-95A9-A483F23A1A5D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {AA94D832-1CCC-4715-95A9-A483F23A1A5D}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {AA94D832-1CCC-4715-95A9-A483F23A1A5D}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {AA94D832-1CCC-4715-95A9-A483F23A1A5D}.Release|Any CPU.Build.0 = Release|Any CPU
- {748584B1-BA69-4F6A-81AA-F4BDE6BCE29D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {748584B1-BA69-4F6A-81AA-F4BDE6BCE29D}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {748584B1-BA69-4F6A-81AA-F4BDE6BCE29D}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {748584B1-BA69-4F6A-81AA-F4BDE6BCE29D}.Release|Any CPU.Build.0 = Release|Any CPU
- EndGlobalSection
- GlobalSection(SolutionProperties) = preSolution
- HideSolutionNode = FALSE
- EndGlobalSection
- GlobalSection(NestedProjects) = preSolution
- {554AD327-6DBA-4F8F-96F8-81CE7A0C863F} = {CA9AC87F-097E-4F15-8393-4BC07735A5B0}
- {1A94A50E-06DC-43C1-80B5-B662820EC3EB} = {CA9AC87F-097E-4F15-8393-4BC07735A5B0}
- {C956DD76-69C8-4A9C-83EA-D17DF83340FD} = {CA9AC87F-097E-4F15-8393-4BC07735A5B0}
- {50B2631D-129C-47B3-A587-029CCD6099BC} = {04DBDB01-70F4-4E06-B468-8F87850B22BE}
- {0372FA84-C517-4EB3-9A9F-B9ACAC0CA5E0} = {CA9AC87F-097E-4F15-8393-4BC07735A5B0}
- {42F719ED-8413-4895-B5B4-5AB56079BC66} = {CA9AC87F-097E-4F15-8393-4BC07735A5B0}
- {520659C8-C734-4298-A3DA-B539DB9DFC0B} = {CA9AC87F-097E-4F15-8393-4BC07735A5B0}
- {4164BDF7-F527-4E85-9CE6-E3C2D7426A27} = {CA9AC87F-097E-4F15-8393-4BC07735A5B0}
- {3B5A0094-670D-4BB1-BFDD-61B88A8773DC} = {CA9AC87F-097E-4F15-8393-4BC07735A5B0}
- {1FE30EB9-74A9-47F5-A9F6-7B1FAB672D81} = {04DBDB01-70F4-4E06-B468-8F87850B22BE}
- {91853F21-9CD9-4132-BC29-A7D5D84FFFE7} = {04DBDB01-70F4-4E06-B468-8F87850B22BE}
- {E512F4D9-9375-480F-A2F6-A46509F9D824} = {04DBDB01-70F4-4E06-B468-8F87850B22BE}
- {AA94D832-1CCC-4715-95A9-A483F23A1A5D} = {CA9AC87F-097E-4F15-8393-4BC07735A5B0}
- {748584B1-BA69-4F6A-81AA-F4BDE6BCE29D} = {CA9AC87F-097E-4F15-8393-4BC07735A5B0}
- EndGlobalSection
- GlobalSection(ExtensibilityGlobals) = postSolution
- SolutionGuid = {28315BFD-90E7-4E14-A2EA-F3D23AF4126F}
- EndGlobalSection
-EndGlobal
diff --git a/content/aspnetcore/Zzz.sln.DotSettings b/content/aspnetcore/Zzz.sln.DotSettings
deleted file mode 100644
index cb0b2c91..00000000
--- a/content/aspnetcore/Zzz.sln.DotSettings
+++ /dev/null
@@ -1,23 +0,0 @@
-
- True
- WARNING
- WARNING
- WARNING
- WARNING
- WARNING
- WARNING
- WARNING
- WARNING
- Required
- Required
- Required
- Required
- False
- True
- False
- False
- True
- False
- False
- SQL
-
\ No newline at end of file
diff --git a/content/aspnetcore/host/CompanyName.ProjectName.HttpApi.Host/CompanyName.ProjectName.HttpApi.Host.csproj b/content/aspnetcore/host/CompanyName.ProjectName.HttpApi.Host/CompanyName.ProjectName.HttpApi.Host.csproj
new file mode 100644
index 00000000..5c49978b
--- /dev/null
+++ b/content/aspnetcore/host/CompanyName.ProjectName.HttpApi.Host/CompanyName.ProjectName.HttpApi.Host.csproj
@@ -0,0 +1,80 @@
+
+
+
+
+
+ net5.0
+ CompanyNameProjectName
+ true
+ CompanyNameProjectName-4681b4fd-151f-4221-84a4-929d86723e4c
+
+
+
+ bin\Debug\net5.0\
+ bin\Debug\net5.0\CompanyNameProjectName.HttpApi.Host.xml
+
+
+
+ bin\Debug\net5.0\
+ bin\Debug\net5.0\CompanyNameProjectName.HttpApi.Host.xml
+
+
+
+
+ en
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Always
+
+
+
+
+
+
+
+
+
+
diff --git a/content/aspnetcore/host/CompanyName.ProjectName.HttpApi.Host/CompanyNameProjectNameBrandingProvider.cs b/content/aspnetcore/host/CompanyName.ProjectName.HttpApi.Host/CompanyNameProjectNameBrandingProvider.cs
new file mode 100644
index 00000000..a18a72ec
--- /dev/null
+++ b/content/aspnetcore/host/CompanyName.ProjectName.HttpApi.Host/CompanyNameProjectNameBrandingProvider.cs
@@ -0,0 +1,11 @@
+using Volo.Abp.DependencyInjection;
+using Volo.Abp.Ui.Branding;
+
+namespace CompanyNameProjectName
+{
+ [Dependency(ReplaceServices = true)]
+ public class CompanyNameProjectNameBrandingProvider : DefaultBrandingProvider
+ {
+ public override string AppName => "CompanyNameProjectName";
+ }
+}
diff --git a/content/aspnetcore/host/CompanyName.ProjectName.HttpApi.Host/CompanyNameProjectNameHttpApiHostModule.cs b/content/aspnetcore/host/CompanyName.ProjectName.HttpApi.Host/CompanyNameProjectNameHttpApiHostModule.cs
new file mode 100644
index 00000000..3ef36dfb
--- /dev/null
+++ b/content/aspnetcore/host/CompanyName.ProjectName.HttpApi.Host/CompanyNameProjectNameHttpApiHostModule.cs
@@ -0,0 +1,387 @@
+using Hangfire;
+using Hangfire.Redis;
+using Microsoft.AspNetCore.Authentication.JwtBearer;
+using Microsoft.AspNetCore.Builder;
+using Microsoft.AspNetCore.Cors;
+using Microsoft.Extensions.Configuration;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Hosting;
+using Microsoft.IdentityModel.Tokens;
+using Microsoft.OpenApi.Models;
+using Serilog;
+using Swashbuckle.AspNetCore.SwaggerUI;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using Volo.Abp;
+using Volo.Abp.Account.Web;
+using Volo.Abp.AspNetCore.Authentication.JwtBearer;
+using Volo.Abp.AspNetCore.ExceptionHandling;
+using Volo.Abp.AspNetCore.MultiTenancy;
+using Volo.Abp.AspNetCore.Mvc;
+using Volo.Abp.AspNetCore.Mvc.UI.Bundling;
+using Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic;
+using Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Bundling;
+using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared;
+using Volo.Abp.AspNetCore.Serilog;
+using Volo.Abp.Auditing;
+using Volo.Abp.Autofac;
+using Volo.Abp.BackgroundJobs;
+using Volo.Abp.Hangfire;
+using Volo.Abp.Localization;
+using Volo.Abp.Modularity;
+using Volo.Abp.Settings;
+using Volo.Abp.Swashbuckle;
+using Volo.Abp.UI.Navigation.Urls;
+using Volo.Abp.VirtualFileSystem;
+using CompanyNameProjectName.EntityFrameworkCore;
+using CompanyNameProjectName.Extensions;
+using CompanyNameProjectName.Extensions.Filters;
+using CompanyNameProjectName.Options;
+using Volo.Abp.Identity;
+
+namespace CompanyNameProjectName
+{
+ [DependsOn(
+ typeof(CompanyNameProjectNameHttpApiModule),
+ typeof(AbpAutofacModule),
+ typeof(AbpAspNetCoreMultiTenancyModule),
+ typeof(CompanyNameProjectNameApplicationModule),
+ typeof(CompanyNameProjectNameEntityFrameworkCoreDbMigrationsModule),
+ typeof(AbpAspNetCoreMvcUiBasicThemeModule),
+ typeof(AbpAspNetCoreAuthenticationJwtBearerModule),
+ typeof(AbpAccountWebIdentityServerModule),
+ typeof(AbpAspNetCoreSerilogModule),
+ typeof(AbpSwashbuckleModule),
+ typeof(AbpHangfireModule)
+ )]
+ public class CompanyNameProjectNameHttpApiHostModule : AbpModule
+ {
+ private const string DefaultCorsPolicyName = "Default";
+
+ public override void OnPreApplicationInitialization(ApplicationInitializationContext context)
+ {
+ // 应用程序初始化的时候注册hangfire
+ var app = context.GetApplicationBuilder();
+ app.ApplicationServices.GetService().Get(LocalizationSettingNames.DefaultLanguage).DefaultValue = "zh-Hans";
+ app.UseHangfireDashboard("/hangfire", new DashboardOptions()
+ {
+ Authorization = new[] { new CustomHangfireAuthorizeFilter() }
+ });
+ context.ServiceProvider.CreateRecurringJob();
+ }
+
+ public override void ConfigureServices(ServiceConfigurationContext context)
+ {
+ var configuration = context.Services.GetConfiguration();
+ ConfigureOptions(context);
+ ConfigureBundles();
+ ConfigureUrls(configuration);
+ ConfigureConventionalControllers();
+ ConfigureJwtAuthentication(context, configuration);
+ ConfigureLocalization();
+ ConfigureVirtualFileSystem(context);
+ ConfigureCors(context, configuration);
+ ConfigureSwaggerServices(context);
+ ConfigureAbpExcepotions(context);
+ ConfigureCache(context.Services);
+ ConfigureAuditLog();
+ ConfigureHangfire(context.Services);
+ }
+
+ public override void OnApplicationInitialization(ApplicationInitializationContext context)
+ {
+ var app = context.GetApplicationBuilder();
+ var env = context.GetEnvironment();
+
+ if (env.IsDevelopment())
+ {
+ app.UseDeveloperExceptionPage();
+ }
+
+ app.UseAbpRequestLocalization();
+
+ if (!env.IsDevelopment())
+ {
+ app.UseErrorPage();
+ }
+
+ app.UseCorrelationId();
+ app.UseVirtualFiles();
+ app.UseRouting();
+ app.UseCors(DefaultCorsPolicyName);
+ app.UseAuthentication();
+ app.UseJwtTokenMiddleware();
+
+ //if (MultiTenancyConsts.IsEnabled)
+ //{
+ // app.UseMultiTenancy();
+ //}
+
+ //app.UseIdentityServer();
+ app.UseAuthorization();
+
+ app.UseSwagger();
+ app.UseAbpSwaggerUI(c =>
+ {
+ c.SwaggerEndpoint("/swagger/v1/swagger.json", "CompanyNameProjectName API");
+ c.DefaultModelExpandDepth(-2);
+ c.DocExpansion(DocExpansion.None);
+ });
+
+ app.UseAuditing();
+ app.UseAbpSerilogEnrichers();
+ app.UseSerilogRequestLogging(opts =>
+ {
+ opts.EnrichDiagnosticContext = SerilogToEsExtensions.EnrichFromRequest;
+ });
+ app.UseConfiguredEndpoints();
+
+
+ }
+
+ #region 私有方法
+ ///
+ /// 配置options
+ ///
+ ///
+ private void ConfigureOptions(ServiceConfigurationContext context)
+ {
+ context.Services.Configure(context.Services.GetConfiguration().GetSection("Jwt"));
+ }
+
+
+ ///
+ /// 审计日志
+ ///
+ private void ConfigureAuditLog()
+ {
+ Configure(options =>
+ {
+ options.IsEnabled = false; //Disables the auditing system
+ });
+ }
+
+ ///
+ /// Redis缓存
+ ///
+ ///
+ private void ConfigureCache(IServiceCollection services)
+ {
+ var redisConnectionString = services.GetConfiguration().GetSection("Cache:Redis:ConnectionString").Value;
+ var redisDatabaseId = Convert.ToInt32(services.GetConfiguration().GetSection("Cache:Redis:DatabaseId").Value);
+ services.AddStackExchangeRedisCache(options =>
+ {
+ options.Configuration = redisConnectionString + ",defaultdatabase=" + redisDatabaseId;
+ });
+ }
+
+
+ ///
+ /// 异常处理
+ ///
+ ///
+ private void ConfigureAbpExcepotions(ServiceConfigurationContext context)
+ {
+ // dev环境显示异常具体信息
+ if (context.Services.GetHostingEnvironment().IsDevelopment())
+ {
+ context.Services.Configure(options =>
+ {
+ options.SendExceptionsDetailsToClients = true;
+ });
+ }
+ }
+
+
+ private void ConfigureBundles()
+ {
+ Configure(options =>
+ {
+ options.StyleBundles.Configure(
+ BasicThemeBundles.Styles.Global,
+ bundle => { bundle.AddFiles("/global-styles.css"); }
+ );
+ });
+ }
+
+
+ private void ConfigureUrls(IConfiguration configuration)
+ {
+ Configure(options =>
+ {
+ options.Applications["MVC"].RootUrl = configuration["App:SelfUrl"];
+ });
+ }
+
+ ///
+ /// 配置虚拟文件系统
+ ///
+ ///
+ private void ConfigureVirtualFileSystem(ServiceConfigurationContext context)
+ {
+ Configure(options =>
+ {
+ options.FileSets.AddEmbedded();
+ });
+ }
+
+ ///
+ /// 映射Controller
+ ///
+ private void ConfigureConventionalControllers()
+ {
+ Configure(options =>
+ {
+ options.ConventionalControllers.Create(typeof(CompanyNameProjectNameApplicationModule).Assembly);
+ });
+
+ }
+
+ ///
+ /// 配置JWT
+ ///
+ ///
+ ///
+ private void ConfigureJwtAuthentication(ServiceConfigurationContext context, IConfiguration configuration)
+ {
+ context.Services.AddAuthentication(options =>
+ {
+ options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
+ options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
+ })
+ .AddJwtBearer(options =>
+ {
+ options.TokenValidationParameters = new Microsoft.IdentityModel.Tokens.TokenValidationParameters()
+ {
+ // 是否开启签名认证
+ ValidateIssuerSigningKey = true,
+ ValidateIssuer = true,
+ ValidateAudience = true,
+ ValidateLifetime = true,
+ //ClockSkew = TimeSpan.Zero,
+ ValidIssuer = configuration["Jwt:Issuer"],
+ ValidAudience = configuration["Jwt:Audience"],
+ IssuerSigningKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(configuration["Jwt:SecurityKey"]))
+ };
+ });
+ }
+
+ ///
+ /// 配置SwaggerUI
+ ///
+ ///
+ private static void ConfigureSwaggerServices(ServiceConfigurationContext context)
+ {
+ context.Services.AddSwaggerGen(
+ options =>
+ {
+ options.SwaggerDoc("v1", new OpenApiInfo { Title = "CompanyNameProjectName API", Version = "v1" });
+
+ options.DocInclusionPredicate((docName, description) => true);
+ options.EnableAnnotations();// 启用注解
+ // 加载xml文件,不然不会显示备注
+ //var xmlapppath = Path.Combine(AppContext.BaseDirectory, "CompanyNameProjectName.Application.xml");
+ //var xmlContractspath = Path.Combine(AppContext.BaseDirectory, "CompanyNameProjectName.Application.Contracts.xml");
+ //var xmlapipath = Path.Combine(AppContext.BaseDirectory, "CompanyNameProjectName.HttpApi.Host.xml");
+ //options.IncludeXmlComments(xmlapppath, true);
+ //options.IncludeXmlComments(xmlContractspath, true);
+ //options.IncludeXmlComments(xmlapipath, true);
+
+ //options.OperationFilter();
+ options.DocumentFilter();
+ // 在swaggerui界面添加token认证
+ options.AddSecurityDefinition(JwtBearerDefaults.AuthenticationScheme, new OpenApiSecurityScheme()
+ {
+ Description = "Please enter into field the word 'Bearer' followed by a space and the JWT value",
+ Name = "Authorization",
+ In = ParameterLocation.Header,
+ Type = SecuritySchemeType.Http,
+ Scheme = JwtBearerDefaults.AuthenticationScheme,
+ BearerFormat = "JWT"
+ });
+ options.AddSecurityRequirement(new OpenApiSecurityRequirement
+ {
+ {
+ new OpenApiSecurityScheme
+ {
+ Reference = new OpenApiReference { Type = ReferenceType.SecurityScheme, Id = "Bearer"
+ }
+ },
+ new List()
+ }
+ });
+ });
+ }
+
+ ///
+ ///配置本地化
+ ///
+ private void ConfigureLocalization()
+ {
+ Configure(options =>
+ {
+ options.Languages.Add(new LanguageInfo("en", "en", "English"));
+ options.Languages.Add(new LanguageInfo("zh-Hans", "zh-Hans", "简体中文"));
+ });
+ }
+
+ ///
+ /// 配置跨域
+ ///
+ ///
+ ///
+ private void ConfigureCors(ServiceConfigurationContext context, IConfiguration configuration)
+ {
+ context.Services.AddCors(options =>
+ {
+ options.AddPolicy(DefaultCorsPolicyName, builder =>
+ {
+ builder
+ .WithOrigins(
+ configuration["App:CorsOrigins"]
+ .Split(",", StringSplitOptions.RemoveEmptyEntries)
+ .Select(o => o.RemovePostFix("/"))
+ .ToArray()
+ )
+ .WithAbpExposedHeaders()
+ .SetIsOriginAllowedToAllowWildcardSubdomains()
+ .AllowAnyHeader()
+ .AllowAnyMethod()
+ .AllowCredentials();
+ });
+ });
+ }
+
+
+ ///
+ /// 配置Hangfire服务
+ ///
+ ///
+ private void ConfigureHangfire(IServiceCollection services)
+ {
+ Configure(options =>
+ {
+ options.IsJobExecutionEnabled = false;
+ });
+
+ var redisConnectionString = services.GetConfiguration().GetSection("Cache:Redis:ConnectionString").Value;
+ var redisDatabaseId = Convert.ToInt32(services.GetConfiguration().GetSection("Cache:Redis:DatabaseId").Value);
+
+ // 启用Hangfire 并使用Redis作为持久化
+ services.AddHangfire(config =>
+ {
+ config.UseRedisStorage(redisConnectionString, new RedisStorageOptions { Db = redisDatabaseId });
+ });
+
+ JobStorage.Current = new RedisStorage(redisConnectionString, new RedisStorageOptions { Db = redisDatabaseId });
+ }
+
+
+
+ #endregion
+
+ }
+}
diff --git a/content/aspnetcore/host/CompanyName.ProjectName.HttpApi.Host/Controllers/HomeController.cs b/content/aspnetcore/host/CompanyName.ProjectName.HttpApi.Host/Controllers/HomeController.cs
new file mode 100644
index 00000000..41fe48be
--- /dev/null
+++ b/content/aspnetcore/host/CompanyName.ProjectName.HttpApi.Host/Controllers/HomeController.cs
@@ -0,0 +1,13 @@
+using Microsoft.AspNetCore.Mvc;
+using Volo.Abp.AspNetCore.Mvc;
+
+namespace CompanyNameProjectName.Controllers
+{
+ public class HomeController : AbpController
+ {
+ public ActionResult Index()
+ {
+ return Redirect("~/swagger/index.html");
+ }
+ }
+}
diff --git a/content/aspnetcore/host/CompanyName.ProjectName.HttpApi.Host/Dockerfile b/content/aspnetcore/host/CompanyName.ProjectName.HttpApi.Host/Dockerfile
new file mode 100644
index 00000000..46d94190
--- /dev/null
+++ b/content/aspnetcore/host/CompanyName.ProjectName.HttpApi.Host/Dockerfile
@@ -0,0 +1,17 @@
+FROM mcr.microsoft.com/dotnet/aspnet:5.0
+
+# Ŀ¼
+RUN mkdir /apps
+
+COPY . /apps
+
+# ùĿ¼
+WORKDIR /apps
+
+# ¶80˿
+EXPOSE 80
+
+# û
+ENV ASPNETCORE_ENVIRONMENT=Development
+
+ENTRYPOINT ["dotnet", "CompanyNameProjectName.HttpApi.Host.dll"]
\ No newline at end of file
diff --git a/content/aspnetcore/host/CompanyName.ProjectName.HttpApi.Host/Extensions/Filters/CustomHangfireAuthorizeFilter.cs b/content/aspnetcore/host/CompanyName.ProjectName.HttpApi.Host/Extensions/Filters/CustomHangfireAuthorizeFilter.cs
new file mode 100644
index 00000000..2b33ea50
--- /dev/null
+++ b/content/aspnetcore/host/CompanyName.ProjectName.HttpApi.Host/Extensions/Filters/CustomHangfireAuthorizeFilter.cs
@@ -0,0 +1,16 @@
+using Hangfire.Dashboard;
+using Microsoft.Extensions.DependencyInjection;
+using Volo.Abp.Users;
+
+namespace CompanyNameProjectName.Extensions.Filters
+{
+ public class CustomHangfireAuthorizeFilter : IDashboardAuthorizationFilter
+ {
+ public bool Authorize(DashboardContext context)
+ {
+ //var currentUser = context.GetHttpContext().RequestServices.GetRequiredService();
+ //return currentUser.IsAuthenticated;
+ return true;
+ }
+ }
+}
diff --git a/content/aspnetcore/host/CompanyName.ProjectName.HttpApi.Host/Extensions/Filters/HiddenAbpDefaultApiFilter.cs b/content/aspnetcore/host/CompanyName.ProjectName.HttpApi.Host/Extensions/Filters/HiddenAbpDefaultApiFilter.cs
new file mode 100644
index 00000000..028a8a76
--- /dev/null
+++ b/content/aspnetcore/host/CompanyName.ProjectName.HttpApi.Host/Extensions/Filters/HiddenAbpDefaultApiFilter.cs
@@ -0,0 +1,55 @@
+using Microsoft.AspNetCore.Mvc.ApiExplorer;
+using Microsoft.OpenApi.Models;
+using Swashbuckle.AspNetCore.SwaggerGen;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Reflection;
+using System.Threading.Tasks;
+
+namespace CompanyNameProjectName.Extensions.Filters
+{
+ ///
+ /// 在使用nswag的时候,原生默认的api导致生产的代理类存在问题
+ /// 所有隐藏原生的api,重写路由
+ ///
+ public class HiddenAbpDefaultApiFilter : IDocumentFilter
+ {
+ public void Apply(OpenApiDocument swaggerDoc, DocumentFilterContext context)
+ {
+
+ foreach (ApiDescription apiDescription in context.ApiDescriptions)
+ {
+ if (apiDescription.TryGetMethodInfo(out MethodInfo method))
+ {
+ string key = "/" + apiDescription.RelativePath;
+ var reuslt = IsHidden(key);
+ if(reuslt) swaggerDoc.Paths.Remove(key);
+ }
+ }
+ }
+
+ private bool IsHidden(string key)
+ {
+ var list = GetHiddenAbpDefaultApiList();
+ foreach (var item in list)
+ {
+ if (key.Contains(item)) return true;
+ }
+ return false;
+ }
+
+ private List GetHiddenAbpDefaultApiList()
+ {
+ return new List() {
+ "/api/abp/multi-tenancy/tenants",
+ "/api/account",
+ "/api/feature-management/features",
+ "/api/permission-management/permissions",
+ "/api/identity/my-profile",
+ "/api/identity",
+ "/api/multi-tenancy/tenants"
+ };
+ }
+ }
+}
diff --git a/content/aspnetcore/host/CompanyName.ProjectName.HttpApi.Host/Extensions/Filters/SwaggerTagsFilter.cs b/content/aspnetcore/host/CompanyName.ProjectName.HttpApi.Host/Extensions/Filters/SwaggerTagsFilter.cs
new file mode 100644
index 00000000..46638c45
--- /dev/null
+++ b/content/aspnetcore/host/CompanyName.ProjectName.HttpApi.Host/Extensions/Filters/SwaggerTagsFilter.cs
@@ -0,0 +1,36 @@
+using Microsoft.AspNetCore.Mvc.Controllers;
+using Microsoft.OpenApi.Models;
+using Swashbuckle.AspNetCore.SwaggerGen;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+
+namespace CompanyNameProjectName.Extensions.Filters
+{
+ ///
+ /// 把abp vnext 提供的api 归档
+ ///
+ public class SwaggerTagsFilter : IOperationFilter
+ {
+ public const string DefaultTagName = "ABP Vnext 默认 Api";
+
+ public void Apply(OpenApiOperation operation, OperationFilterContext context)
+ {
+ var tag = GetChineseTag(context.ApiDescription.ActionDescriptor as ControllerActionDescriptor);
+ if (null != tag)
+ operation.Tags = new List { tag };
+ }
+
+ private static OpenApiTag GetChineseTag(ControllerActionDescriptor description)
+ {
+ if (null != description?.ControllerTypeInfo?.Namespace)
+ {
+ if (description.ControllerTypeInfo.Namespace.StartsWith("Volo.Abp") || description.ControllerTypeInfo.Namespace.StartsWith("Pages.Abp.MultiTenancy"))
+ return new OpenApiTag { Name = DefaultTagName };
+ return null;
+ }
+ return null;
+ }
+ }
+}
diff --git a/content/aspnetcore/host/CompanyName.ProjectName.HttpApi.Host/Extensions/RecurringJobsExtensions.cs b/content/aspnetcore/host/CompanyName.ProjectName.HttpApi.Host/Extensions/RecurringJobsExtensions.cs
new file mode 100644
index 00000000..12f41d70
--- /dev/null
+++ b/content/aspnetcore/host/CompanyName.ProjectName.HttpApi.Host/Extensions/RecurringJobsExtensions.cs
@@ -0,0 +1,16 @@
+using Hangfire;
+using Microsoft.Extensions.DependencyInjection;
+using System;
+using CompanyNameProjectName.Jobs;
+
+namespace CompanyNameProjectName.Extensions
+{
+ public static class RecurringJobsExtensions
+ {
+ public static void CreateRecurringJob(this IServiceProvider service)
+ {
+ var job = service.GetService();
+ RecurringJob.AddOrUpdate("测试Job", () => job.ExecuteAsync(), CronTypeHelper.Minute(1));
+ }
+ }
+}
diff --git a/content/aspnetcore/host/CompanyName.ProjectName.HttpApi.Host/Extensions/SerilogToEsExtensions.cs b/content/aspnetcore/host/CompanyName.ProjectName.HttpApi.Host/Extensions/SerilogToEsExtensions.cs
new file mode 100644
index 00000000..da35c080
--- /dev/null
+++ b/content/aspnetcore/host/CompanyName.ProjectName.HttpApi.Host/Extensions/SerilogToEsExtensions.cs
@@ -0,0 +1,135 @@
+using Microsoft.AspNetCore.Http;
+using Microsoft.Extensions.Configuration;
+using Serilog;
+using Serilog.Exceptions;
+using Serilog.Exceptions.Core;
+using Serilog.Sinks.Elasticsearch;
+using System;
+using System.IO;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace CompanyNameProjectName.Extensions
+{
+ public static class SerilogToEsExtensions
+ {
+
+ public static void SetSerilogConfiguration(LoggerConfiguration loggerConfiguration, IConfiguration configuration)
+ {
+ // 默认读取 configuration 中 "Serilog" 节点下的配置
+ loggerConfiguration.ReadFrom.Configuration(configuration)
+ .Enrich.WithExceptionDetails()
+ .Enrich.WithExceptionDetails(new DestructuringOptionsBuilder()
+ .WithDefaultDestructurers()
+ )
+ .Enrich.FromLogContext()
+ .WriteTo.Console()
+ .WriteTo.File("logs/logs.txt", rollingInterval: RollingInterval.Day);
+
+ var writeToElasticSearch = configuration.GetValue("LogToElasticSearch:Enabled", false);
+
+ // LogToElasticSearch:Enabled = true 才输出至ES
+ if (!writeToElasticSearch)
+ return;
+
+ var applicationName = "CompanyNameProjectName.HttpApi.Host";
+
+ var esUrl = configuration["LogToElasticSearch:ElasticSearch:Url"];
+ // 需要设置ES URL
+ if (string.IsNullOrEmpty(esUrl))
+ return;
+
+
+ var indexFormat = configuration["LogToElasticSearch:ElasticSearch:IndexFormat"];
+
+ // 需要设置ES URL
+ if (string.IsNullOrEmpty(indexFormat))
+ return;
+
+ var esUserName = configuration["LogToElasticSearch:ElasticSearch:UserName"];
+ var esPassword = configuration["LogToElasticSearch:ElasticSearch:Password"];
+
+ loggerConfiguration.Enrich.FromLogContext().Enrich.WithExceptionDetails().WriteTo.Elasticsearch(BuildElasticSearchSinkOptions(esUrl, indexFormat, esUserName, esPassword));
+ loggerConfiguration.Enrich.WithProperty("Application", applicationName);
+ }
+
+ // 创建Es连接
+ private static ElasticsearchSinkOptions BuildElasticSearchSinkOptions(
+ string url,
+ string indexFormat,
+ string userName,
+ string password)
+ {
+ if (string.IsNullOrEmpty(userName))
+ {
+ return new ElasticsearchSinkOptions(new Uri(url))
+ {
+ AutoRegisterTemplate = true,
+ AutoRegisterTemplateVersion = AutoRegisterTemplateVersion.ESv7,
+ IndexFormat = indexFormat
+ };
+ }
+
+ return new ElasticsearchSinkOptions(new Uri(url))
+ {
+ AutoRegisterTemplate = true,
+ AutoRegisterTemplateVersion = AutoRegisterTemplateVersion.ESv7,
+ IndexFormat = indexFormat,
+ ModifyConnectionSettings = x => x.BasicAuthentication(userName, password)
+ };
+ }
+
+ public static void EnrichFromRequest(IDiagnosticContext diagnosticContext, HttpContext httpContext)
+ {
+ var request = httpContext.Request;
+
+ // 为每个请求都设置通用的属性
+ diagnosticContext.Set("Host", request.Host);
+ diagnosticContext.Set("Protocol", request.Protocol);
+ diagnosticContext.Set("Scheme", request.Scheme);
+ diagnosticContext.Set("RemoteIpAddress", httpContext.Connection.RemoteIpAddress);
+ // 如果要记录 Request Body 或 Response Body
+ // 参考 https://stackoverflow.com/questions/60076922/serilog-logging-web-api-methods-adding-context-properties-inside-middleware
+ string requestBody = ReadRequestBody(httpContext.Request).Result;
+ if (!string.IsNullOrEmpty(requestBody))
+ {
+ diagnosticContext.Set("RequestBody", requestBody);
+ }
+
+ // string responseBody = ReadResponseBody(httpContext.Response).Result;
+ // if (!string.IsNullOrEmpty(responseBody))
+ // {
+ // diagnosticContext.Set("ResponseBody", requestBody);
+ // }
+
+ if (request.QueryString.HasValue)
+ {
+ diagnosticContext.Set("QueryString", request.QueryString.Value);
+ }
+
+ }
+
+ private static async Task ReadRequestBody(HttpRequest request)
+ {
+ HttpRequestRewindExtensions.EnableBuffering(request);
+
+ var body = request.Body;
+ var buffer = new byte[Convert.ToInt32(request.ContentLength)];
+ await request.Body.ReadAsync(buffer, 0, buffer.Length);
+ string requestBody = Encoding.UTF8.GetString(buffer);
+ body.Seek(0, SeekOrigin.Begin);
+ request.Body = body;
+
+ return $"{requestBody}";
+ }
+
+ private static async Task ReadResponseBody(HttpResponse response)
+ {
+ response.Body.Seek(0, SeekOrigin.Begin);
+ string responseBody = await new StreamReader(response.Body).ReadToEndAsync();
+ response.Body.Seek(0, SeekOrigin.Begin);
+
+ return $"{responseBody}";
+ }
+ }
+}
diff --git a/content/aspnetcore/host/CompanyName.ProjectName.HttpApi.Host/Program.cs b/content/aspnetcore/host/CompanyName.ProjectName.HttpApi.Host/Program.cs
new file mode 100644
index 00000000..a013a614
--- /dev/null
+++ b/content/aspnetcore/host/CompanyName.ProjectName.HttpApi.Host/Program.cs
@@ -0,0 +1,35 @@
+using System;
+using Microsoft.AspNetCore.Hosting;
+using Microsoft.Extensions.Configuration;
+using Microsoft.Extensions.Hosting;
+using Serilog;
+using Serilog.Events;
+using CompanyNameProjectName.Extensions;
+
+namespace CompanyNameProjectName
+{
+ public class Program
+ {
+ public static void Main(string[] args)
+ {
+ CreateHostBuilder(args).Build().Run();
+ }
+
+ public static IHostBuilder CreateHostBuilder(string[] args) =>
+ Microsoft.Extensions.Hosting.Host.CreateDefaultBuilder(args)
+ .ConfigureWebHostDefaults(webBuilder =>
+ {
+ webBuilder.UseStartup();
+ })
+ //.ConfigureAppConfiguration((context, builder) => {
+ // // 配置nacos
+ // builder.AddNacosConfiguration(builder.Build().GetSection("NacosConfig"));
+ //})
+ .UseSerilog((context, loggerConfiguration) =>
+ {
+ SerilogToEsExtensions.SetSerilogConfiguration(
+ loggerConfiguration,
+ context.Configuration);
+ }).UseAutofac();
+ }
+}
diff --git a/content/aspnetcore/host/CompanyName.ProjectName.HttpApi.Host/Properties/launchSettings.json b/content/aspnetcore/host/CompanyName.ProjectName.HttpApi.Host/Properties/launchSettings.json
new file mode 100644
index 00000000..3a553ed9
--- /dev/null
+++ b/content/aspnetcore/host/CompanyName.ProjectName.HttpApi.Host/Properties/launchSettings.json
@@ -0,0 +1,13 @@
+{
+ "profiles": {
+ "CompanyNameProjectName.HttpApi.Host": {
+ "commandName": "Project",
+ "launchBrowser": true,
+ "launchUrl": "swagger/index.html",
+ "environmentVariables": {
+ "ASPNETCORE_ENVIRONMENT": "Development"
+ },
+ "applicationUrl": "http://localhost:50010/"
+ }
+ }
+}
\ No newline at end of file
diff --git a/content/aspnetcore/host/CompanyName.ProjectName.HttpApi.Host/Startup.cs b/content/aspnetcore/host/CompanyName.ProjectName.HttpApi.Host/Startup.cs
new file mode 100644
index 00000000..8e9e5680
--- /dev/null
+++ b/content/aspnetcore/host/CompanyName.ProjectName.HttpApi.Host/Startup.cs
@@ -0,0 +1,20 @@
+using Microsoft.AspNetCore.Builder;
+using Microsoft.AspNetCore.Hosting;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Logging;
+
+namespace CompanyNameProjectName
+{
+ public class Startup
+ {
+ public void ConfigureServices(IServiceCollection services)
+ {
+ services.AddApplication();
+ }
+
+ public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILoggerFactory loggerFactory)
+ {
+ app.InitializeApplication();
+ }
+ }
+}
diff --git a/content/aspnetcore/host/CompanyName.ProjectName.HttpApi.Host/appsettings.Ali.json b/content/aspnetcore/host/CompanyName.ProjectName.HttpApi.Host/appsettings.Ali.json
new file mode 100644
index 00000000..cf517529
--- /dev/null
+++ b/content/aspnetcore/host/CompanyName.ProjectName.HttpApi.Host/appsettings.Ali.json
@@ -0,0 +1,61 @@
+{
+ "App": {
+ "SelfUrl": "https://localhost:44363",
+ "CorsOrigins": "https://*.CompanyNameProjectName.com,http://localhost:8083,http://localhost:8081,https://localhost:44307,"
+ },
+ "StringEncryption": {
+ "DefaultPassPhrase": "MY2bTgp2iaHUEp66"
+ },
+ "Settings": {
+ "Abp.Mailing.Smtp.Host": "127.0.0.1",
+ "Abp.Mailing.Smtp.Port": "25",
+ "Abp.Mailing.Smtp.UserName": "",
+ "Abp.Mailing.Smtp.Password": "",
+ "Abp.Mailing.Smtp.Domain": "",
+ "Abp.Mailing.Smtp.EnableSsl": "false",
+ "Abp.Mailing.Smtp.UseDefaultCredentials": "true",
+ "Abp.Mailing.DefaultFromAddress": "noreply@abp.io",
+ "Abp.Mailing.DefaultFromDisplayName": "ABP application"
+ },
+ "Serilog": {
+ "MinimumLevel": {
+ "Default": "Information",
+ "Override": {
+ "Microsoft": "Information",
+ "Microsoft.AspNetCore": "Information",
+ "System": "Warning",
+ "Microsoft.Hosting.Lifetime": "Information",
+ "Microsoft.AspNetCore.Routing": "Information",
+ "Microsoft.AspNetCore.Hosting.Diagnostics": "Error"
+ }
+ }
+ },
+ "ConnectionStrings": {
+ "Default": "Data Source=mysql.development.cn;Database=CompanyNameProjectName;uid=root;pwd=mysql@;charset=utf8mb4;Allow User Variables=true;AllowLoadLocalInfile=true"
+ },
+ "Cache": {
+ "Redis": {
+ "ConnectionString": "redis.development.yhglobal.cn,password=OD5VbzIuAWsHOZV5ncYx9xaDsAMsKXn7",
+ "DatabaseId": 231
+ }
+ },
+ "AuthServer": {
+ "Authority": "https://localhost:44363",
+ "RequireHttpsMetadata": "false"
+ },
+ "Jwt": {
+ "Audience": "http://localhost:5010", //ͻ˱ʶ
+ "SecurityKey": "dzehzRz9a8asdfasfdadfasdfasdfafsdadfasbasdf=",
+ "Issuer": "CompanyNameProjectName", //ǩ
+ "ExpirationTime": 2 //ʱ hour
+ },
+ "LogToElasticSearch": {
+ "Enabled": "true",
+ "ElasticSearch": {
+ "Url": "http://es.cn",
+ "IndexFormat": "CompanyNameProjectName.admin.api.dev-{0:yyyy.MM.dd}",
+ "UserName": "CompanyNameProjectName",
+ "Password": "TCYobkZxWu0ELYZY"
+ }
+ }
+}
\ No newline at end of file
diff --git a/content/aspnetcore/host/CompanyName.ProjectName.HttpApi.Host/appsettings.Staging.json b/content/aspnetcore/host/CompanyName.ProjectName.HttpApi.Host/appsettings.Staging.json
new file mode 100644
index 00000000..cf517529
--- /dev/null
+++ b/content/aspnetcore/host/CompanyName.ProjectName.HttpApi.Host/appsettings.Staging.json
@@ -0,0 +1,61 @@
+{
+ "App": {
+ "SelfUrl": "https://localhost:44363",
+ "CorsOrigins": "https://*.CompanyNameProjectName.com,http://localhost:8083,http://localhost:8081,https://localhost:44307,"
+ },
+ "StringEncryption": {
+ "DefaultPassPhrase": "MY2bTgp2iaHUEp66"
+ },
+ "Settings": {
+ "Abp.Mailing.Smtp.Host": "127.0.0.1",
+ "Abp.Mailing.Smtp.Port": "25",
+ "Abp.Mailing.Smtp.UserName": "",
+ "Abp.Mailing.Smtp.Password": "",
+ "Abp.Mailing.Smtp.Domain": "",
+ "Abp.Mailing.Smtp.EnableSsl": "false",
+ "Abp.Mailing.Smtp.UseDefaultCredentials": "true",
+ "Abp.Mailing.DefaultFromAddress": "noreply@abp.io",
+ "Abp.Mailing.DefaultFromDisplayName": "ABP application"
+ },
+ "Serilog": {
+ "MinimumLevel": {
+ "Default": "Information",
+ "Override": {
+ "Microsoft": "Information",
+ "Microsoft.AspNetCore": "Information",
+ "System": "Warning",
+ "Microsoft.Hosting.Lifetime": "Information",
+ "Microsoft.AspNetCore.Routing": "Information",
+ "Microsoft.AspNetCore.Hosting.Diagnostics": "Error"
+ }
+ }
+ },
+ "ConnectionStrings": {
+ "Default": "Data Source=mysql.development.cn;Database=CompanyNameProjectName;uid=root;pwd=mysql@;charset=utf8mb4;Allow User Variables=true;AllowLoadLocalInfile=true"
+ },
+ "Cache": {
+ "Redis": {
+ "ConnectionString": "redis.development.yhglobal.cn,password=OD5VbzIuAWsHOZV5ncYx9xaDsAMsKXn7",
+ "DatabaseId": 231
+ }
+ },
+ "AuthServer": {
+ "Authority": "https://localhost:44363",
+ "RequireHttpsMetadata": "false"
+ },
+ "Jwt": {
+ "Audience": "http://localhost:5010", //ͻ˱ʶ
+ "SecurityKey": "dzehzRz9a8asdfasfdadfasdfasdfafsdadfasbasdf=",
+ "Issuer": "CompanyNameProjectName", //ǩ
+ "ExpirationTime": 2 //ʱ hour
+ },
+ "LogToElasticSearch": {
+ "Enabled": "true",
+ "ElasticSearch": {
+ "Url": "http://es.cn",
+ "IndexFormat": "CompanyNameProjectName.admin.api.dev-{0:yyyy.MM.dd}",
+ "UserName": "CompanyNameProjectName",
+ "Password": "TCYobkZxWu0ELYZY"
+ }
+ }
+}
\ No newline at end of file
diff --git a/content/aspnetcore/host/CompanyName.ProjectName.HttpApi.Host/appsettings.json b/content/aspnetcore/host/CompanyName.ProjectName.HttpApi.Host/appsettings.json
new file mode 100644
index 00000000..2350b5cf
--- /dev/null
+++ b/content/aspnetcore/host/CompanyName.ProjectName.HttpApi.Host/appsettings.json
@@ -0,0 +1,61 @@
+{
+ "App": {
+ "SelfUrl": "https://localhost:44363",
+ "CorsOrigins": "https://*.CompanyNameProjectName.com,http://localhost:8083,http://localhost:3100,https://localhost:44307,"
+ },
+ "StringEncryption": {
+ "DefaultPassPhrase": "MY2bTgp2iaHUEp66"
+ },
+ "Settings": {
+ "Abp.Mailing.Smtp.Host": "127.0.0.1",
+ "Abp.Mailing.Smtp.Port": "25",
+ "Abp.Mailing.Smtp.UserName": "",
+ "Abp.Mailing.Smtp.Password": "",
+ "Abp.Mailing.Smtp.Domain": "",
+ "Abp.Mailing.Smtp.EnableSsl": "false",
+ "Abp.Mailing.Smtp.UseDefaultCredentials": "true",
+ "Abp.Mailing.DefaultFromAddress": "noreply@abp.io",
+ "Abp.Mailing.DefaultFromDisplayName": "ABP application"
+ },
+ "Serilog": {
+ "MinimumLevel": {
+ "Default": "Information",
+ "Override": {
+ "Microsoft": "Information",
+ "Microsoft.AspNetCore": "Information",
+ "System": "Warning",
+ "Microsoft.Hosting.Lifetime": "Information",
+ "Microsoft.AspNetCore.Routing": "Information",
+ "Microsoft.AspNetCore.Hosting.Diagnostics": "Error"
+ }
+ }
+ },
+ "ConnectionStrings": {
+ "Default": "Data Source=mysql.platform.development.cn;Database=CompanyNameProjectName;uid=root;pwd=mysql@dmin;charset=utf8mb4;Allow User Variables=true;AllowLoadLocalInfile=true"
+ },
+ "Cache": {
+ "Redis": {
+ "ConnectionString": "redis.platform.development.cn,password=OD5VbzIuAWsHOZV5ncYx9xaDsAMsKXn7",
+ "DatabaseId": 234
+ }
+ },
+ "AuthServer": {
+ "Authority": "https://localhost:44363",
+ "RequireHttpsMetadata": "false"
+ },
+ "Jwt": {
+ "Audience": "http://localhost:5010", //ͻ˱ʶ
+ "SecurityKey": "dzehzRz9a8asdfasfdadfasdfasdfafsdadfasbasdf=",
+ "Issuer": "CompanyNameProjectName", //ǩ
+ "ExpirationTime": 24 //ʱ hour
+ },
+ "LogToElasticSearch": {
+ "Enabled": "true",
+ "ElasticSearch": {
+ "Url": "http://es.cn",
+ "IndexFormat": "CompanyNameProjectName.admin.api.dev-{0:yyyy.MM.dd}",
+ "UserName": "CompanyNameProjectName",
+ "Password": "TCYobkZxWu0ELYZY"
+ }
+ }
+}
\ No newline at end of file
diff --git a/content/aspnetcore/src/Zzz.HttpApi.Host/tempkey.jwk b/content/aspnetcore/host/CompanyName.ProjectName.HttpApi.Host/tempkey.jwk
similarity index 100%
rename from content/aspnetcore/src/Zzz.HttpApi.Host/tempkey.jwk
rename to content/aspnetcore/host/CompanyName.ProjectName.HttpApi.Host/tempkey.jwk
diff --git a/content/aspnetcore/host/CompanyName.ProjectName.HttpApi.Host/tempkey.rsa b/content/aspnetcore/host/CompanyName.ProjectName.HttpApi.Host/tempkey.rsa
new file mode 100644
index 00000000..b6c224c4
--- /dev/null
+++ b/content/aspnetcore/host/CompanyName.ProjectName.HttpApi.Host/tempkey.rsa
@@ -0,0 +1 @@
+{"KeyId":"5eb863b25811a7099f9bc925c0fdf680","Parameters":{"D":"gqn7NAeMkug4twJJHFz/qPseDzQCx7R+6Maj649xrG4vPsMANV9mfR78Er2SuHUS0ZihM2MQEILI5Sf41Uuubv8swCNSE3Dw7GQrBIbTAJ7BZKbQMVgtGkMDtHrtri6d9cOi3EOTSJINICk9r80M49oBMOZihEKascfBSIUYVQvWLEMYfryEiDeFUPbobr10OxF5tZ1unvEKgZe190BdNKWQuFhJelcgsZumjEYNsOz5DHrK73WLhfTy01DmsTKx8i1XVnLtq6W89MqAhMZP9QO9Vj8lR0ANnmdOsY6hJfwUbXiI36t4V9rAZvXR5ESorjb4mnXzT6QPuOfy1fbdSQ==","DP":"ItYIpEqw6aDjDc/swDifUe0Dq6yl4yim3UyQ4B9NBPQR5M6b7D3vbCnvwql4zJK4s+0N4lRViBtkF+20Td1yc2v8S+THCYZCVxCf2e9Q7Ff/sKecJ9/JmdzHkztCfs0xb+4X3CPEQP+JIYtMGmwOLQgE5XgmUYKr0ahZDhYTCwE=","DQ":"v35mgxfyF/nwnWwWlR9cF3mg0v7SyPfKkwdxGaVnGH6G8nPWpPlO+zueflA5QDXEwGtk/1k3PAzI/OLUwJiKBubx/UMhsqt5+/bKTrFDNHxLANCvGNZggMZIzFZBYRucuXRZbiBe5qpCkKkniUct7w6jd/V1mnsESiJZ7btcxU0=","Exponent":"AQAB","InverseQ":"Vbg2a+wtaYvhTV8AzqJsVvaz0kfC4HFbmwEgA8+BAbS3GEoS3RHFSfB3DHndpnNihIg72DctDNLmV2GMMiTu18uyI+7AUaYNR836fByxptfyhPtSQfw4kINZ3V0GWKJGCompanyNameProjectName5NAOct4/FpRl8xliHetayCfUIuK9jwk0z9i6V6bA=","Modulus":"xlzmN1sBi2V1971MsPD5MTND9dAGncIzYqxa3H+9jx1mNDivY6JgKijUWm5a3D2Y1UPMB3kx6qUf3iH6pZHjq5bk938qRhxrPy9muW55U03HTiW4V5/ga0+OqXj5Tj4lz+29OiQHPErxLRgfXT+WBgrGb75ElzkHajKpJnPgzAZuarlUCwupJNQlav/crwOFrgkhGsnaOW13M8htiSLZozw5lxkbhYIei7YTTQZ3l6rVH1dPL8CvzRJJOTwbnU8k0sUmWiuOhrLzuinlr6uuOTocAVgbj943/witVFtN5B0yhetxEVgFCwxRDTOO1EKVHFtCiAyZBUOlK4gwZ+SbGQ==","P":"7dFfbAkZSdx/ieSMYJHoY1DKC4dLg80RObEEmuJ72MaVJLTtFuBPoRpYOrMUNuupIyPjZZsW8fHRlPRhKW7xFv+Q2aDudh1UaJzFZs3xYKoiXTU/j0B3TB3nrifVLMqsS+8kHOWOojwA4dMjI6GCYCpKmYVvMOE1cuJrQ9EYxoM=","Q":"1YdN8mLchLVoTEwD34Pi3T2U7EjjBDgDCzhjl7x5FBG73TyKMz1n7/KXkXcJ2rqIAsnLqCWpYUeRcWl+IQEQxFKoMwkvmQ33lRkOE0SBZ+FnUAMivRyxOD5qM9z4ccqx0ga4ZRgb1lR85f7VYtMSfIosOuSFxWAbV1e29utxhTM="}}
\ No newline at end of file
diff --git a/content/aspnetcore/host/CompanyName.ProjectName.PublicApi.Host/App_Data/logs/logs20210411.txt b/content/aspnetcore/host/CompanyName.ProjectName.PublicApi.Host/App_Data/logs/logs20210411.txt
new file mode 100644
index 00000000..83e403e2
--- /dev/null
+++ b/content/aspnetcore/host/CompanyName.ProjectName.PublicApi.Host/App_Data/logs/logs20210411.txt
@@ -0,0 +1,89 @@
+2021-04-11 22:11:50.691 +08:00 [INF] User profile is available. Using 'C:\Users\wangjun\AppData\Local\ASP.NET\DataProtection-Keys' as key repository and Windows DPAPI to encrypt keys at rest.
+2021-04-11 22:11:50.873 +08:00 [INF] Loaded ABP modules:
+2021-04-11 22:11:50.875 +08:00 [INF] - Volo.Abp.Localization.AbpLocalizationAbstractionsModule
+2021-04-11 22:11:50.875 +08:00 [INF] - Volo.Abp.Validation.AbpValidationAbstractionsModule
+2021-04-11 22:11:50.876 +08:00 [INF] - Volo.Abp.ObjectExtending.AbpObjectExtendingModule
+2021-04-11 22:11:50.876 +08:00 [INF] - Volo.Abp.Uow.AbpUnitOfWorkModule
+2021-04-11 22:11:50.878 +08:00 [INF] - Volo.Abp.Data.AbpDataModule
+2021-04-11 22:11:50.879 +08:00 [INF] - Volo.Abp.VirtualFileSystem.AbpVirtualFileSystemModule
+2021-04-11 22:11:50.880 +08:00 [INF] - Volo.Abp.Security.AbpSecurityModule
+2021-04-11 22:11:50.880 +08:00 [INF] - Volo.Abp.MultiTenancy.AbpMultiTenancyModule
+2021-04-11 22:11:50.881 +08:00 [INF] - Volo.Abp.Settings.AbpSettingsModule
+2021-04-11 22:11:50.890 +08:00 [INF] - Volo.Abp.Localization.AbpLocalizationModule
+2021-04-11 22:11:50.891 +08:00 [INF] - Volo.Abp.Timing.AbpTimingModule
+2021-04-11 22:11:50.891 +08:00 [INF] - Volo.Abp.Json.AbpJsonModule
+2021-04-11 22:11:50.893 +08:00 [INF] - Volo.Abp.Threading.AbpThreadingModule
+2021-04-11 22:11:50.893 +08:00 [INF] - Volo.Abp.Auditing.AbpAuditingModule
+2021-04-11 22:11:50.894 +08:00 [INF] - Volo.Abp.Http.AbpHttpAbstractionsModule
+2021-04-11 22:11:50.894 +08:00 [INF] - Volo.Abp.Minify.AbpMinifyModule
+2021-04-11 22:11:50.895 +08:00 [INF] - Volo.Abp.Http.AbpHttpModule
+2021-04-11 22:11:50.895 +08:00 [INF] - Volo.Abp.Authorization.AbpAuthorizationModule
+2021-04-11 22:11:50.896 +08:00 [INF] - Volo.Abp.Validation.AbpValidationModule
+2021-04-11 22:11:50.897 +08:00 [INF] - Volo.Abp.ExceptionHandling.AbpExceptionHandlingModule
+2021-04-11 22:11:50.898 +08:00 [INF] - Volo.Abp.AspNetCore.AbpAspNetCoreModule
+2021-04-11 22:11:50.899 +08:00 [INF] - Volo.Abp.ApiVersioning.AbpApiVersioningAbstractionsModule
+2021-04-11 22:11:50.900 +08:00 [INF] - Volo.Abp.Application.AbpDddApplicationContractsModule
+2021-04-11 22:11:50.900 +08:00 [INF] - Volo.Abp.AspNetCore.Mvc.AbpAspNetCoreMvcContractsModule
+2021-04-11 22:11:50.902 +08:00 [INF] - Volo.Abp.UI.AbpUiModule
+2021-04-11 22:11:50.903 +08:00 [INF] - Volo.Abp.UI.Navigation.AbpUiNavigationModule
+2021-04-11 22:11:50.903 +08:00 [INF] - Volo.Abp.GlobalFeatures.AbpGlobalFeaturesModule
+2021-04-11 22:11:50.904 +08:00 [INF] - Volo.Abp.EventBus.AbpEventBusModule
+2021-04-11 22:11:50.905 +08:00 [INF] - Volo.Abp.Guids.AbpGuidsModule
+2021-04-11 22:11:50.906 +08:00 [INF] - Volo.Abp.ObjectMapping.AbpObjectMappingModule
+2021-04-11 22:11:50.907 +08:00 [INF] - Volo.Abp.Specifications.AbpSpecificationsModule
+2021-04-11 22:11:50.908 +08:00 [INF] - Volo.Abp.Domain.AbpDddDomainModule
+2021-04-11 22:11:50.909 +08:00 [INF] - Volo.Abp.Features.AbpFeaturesModule
+2021-04-11 22:11:50.910 +08:00 [INF] - Volo.Abp.Application.AbpDddApplicationModule
+2021-04-11 22:11:50.913 +08:00 [INF] - Volo.Abp.AspNetCore.Mvc.AbpAspNetCoreMvcModule
+2021-04-11 22:11:50.915 +08:00 [INF] - Volo.Abp.Castle.AbpCastleCoreModule
+2021-04-11 22:11:50.916 +08:00 [INF] - Volo.Abp.Autofac.AbpAutofacModule
+2021-04-11 22:11:50.918 +08:00 [INF] - Volo.Abp.AuditLogging.AbpAuditLoggingDomainSharedModule
+2021-04-11 22:11:50.919 +08:00 [INF] - Volo.Abp.BackgroundJobs.AbpBackgroundJobsDomainSharedModule
+2021-04-11 22:11:50.920 +08:00 [INF] - Volo.Abp.FeatureManagement.AbpFeatureManagementDomainSharedModule
+2021-04-11 22:11:50.921 +08:00 [INF] - Volo.Abp.Users.AbpUsersDomainSharedModule
+2021-04-11 22:11:50.923 +08:00 [INF] - Volo.Abp.Identity.AbpIdentityDomainSharedModule
+2021-04-11 22:11:50.926 +08:00 [INF] - Volo.Abp.IdentityServer.AbpIdentityServerDomainSharedModule
+2021-04-11 22:11:50.928 +08:00 [INF] - Volo.Abp.PermissionManagement.AbpPermissionManagementDomainSharedModule
+2021-04-11 22:11:50.928 +08:00 [INF] - Volo.Abp.SettingManagement.AbpSettingManagementDomainSharedModule
+2021-04-11 22:11:50.929 +08:00 [INF] - Volo.Abp.TenantManagement.AbpTenantManagementDomainSharedModule
+2021-04-11 22:11:50.931 +08:00 [INF] - EasyAbp.Abp.SettingUi.SettingUiDomainSharedModule
+2021-04-11 22:11:50.932 +08:00 [INF] - CompanyNameProjectName.CompanyNameProjectNameDomainSharedModule
+2021-04-11 22:11:50.933 +08:00 [INF] - Volo.Abp.Users.AbpUsersAbstractionModule
+2021-04-11 22:11:50.935 +08:00 [INF] - Volo.Abp.PermissionManagement.AbpPermissionManagementApplicationContractsModule
+2021-04-11 22:11:50.936 +08:00 [INF] - Volo.Abp.Identity.AbpIdentityApplicationContractsModule
+2021-04-11 22:11:50.937 +08:00 [INF] - Volo.Abp.Account.AbpAccountApplicationContractsModule
+2021-04-11 22:11:50.938 +08:00 [INF] - Volo.Abp.FeatureManagement.AbpFeatureManagementApplicationContractsModule
+2021-04-11 22:11:50.941 +08:00 [INF] - Volo.Abp.TenantManagement.AbpTenantManagementApplicationContractsModule
+2021-04-11 22:11:50.943 +08:00 [INF] - EasyAbp.Abp.SettingUi.SettingUiApplicationContractsModule
+2021-04-11 22:11:50.945 +08:00 [INF] - CompanyNameProjectName.CompanyNameProjectNameApplicationContractsModule
+2021-04-11 22:11:50.946 +08:00 [INF] - Volo.Abp.Http.Client.AbpHttpClientModule
+2021-04-11 22:11:50.958 +08:00 [INF] - Volo.Abp.Account.AbpAccountHttpApiClientModule
+2021-04-11 22:11:50.959 +08:00 [INF] - Volo.Abp.Identity.AbpIdentityHttpApiClientModule
+2021-04-11 22:11:50.960 +08:00 [INF] - Volo.Abp.PermissionManagement.AbpPermissionManagementHttpApiClientModule
+2021-04-11 22:11:50.962 +08:00 [INF] - Volo.Abp.TenantManagement.AbpTenantManagementHttpApiClientModule
+2021-04-11 22:11:50.964 +08:00 [INF] - Volo.Abp.FeatureManagement.AbpFeatureManagementHttpApiClientModule
+2021-04-11 22:11:50.965 +08:00 [INF] - CompanyNameProjectName.CompanyNameProjectNameHttpApiClientModule
+2021-04-11 22:11:50.966 +08:00 [INF] - CompanyNameProjectName.PublicApi.CompanyNameProjectNamePublicApiModule
+2021-04-11 22:11:51.566 +08:00 [INF] Initialized all ABP modules.
+2021-04-11 22:11:51.601 +08:00 [INF] Now listening on: http://localhost:50011
+2021-04-11 22:11:51.602 +08:00 [INF] Application started. Press Ctrl+C to shut down.
+2021-04-11 22:11:51.604 +08:00 [INF] Hosting environment: Development
+2021-04-11 22:11:51.605 +08:00 [INF] Content root path: E:\study\github\abp-vnext-pro-t\aspnetcore\host\CompanyName.ProjectName.PublicApi.Host
+2021-04-11 22:11:56.709 +08:00 [INF] Request starting HTTP/1.1 GET http://localhost:50011/swagger - -
+2021-04-11 22:11:56.830 +08:00 [INF] Request finished HTTP/1.1 GET http://localhost:50011/swagger - - - 301 0 - 125.7433ms
+2021-04-11 22:11:56.851 +08:00 [INF] Request starting HTTP/1.1 GET http://localhost:50011/swagger/index.html - -
+2021-04-11 22:11:56.947 +08:00 [INF] Request finished HTTP/1.1 GET http://localhost:50011/swagger/index.html - - - 200 - text/html;charset=utf-8 95.4839ms
+2021-04-11 22:11:59.147 +08:00 [INF] Request starting HTTP/1.1 GET http://localhost:50011/swagger/swagger-ui-bundle.js - -
+2021-04-11 22:11:59.149 +08:00 [INF] Request starting HTTP/1.1 GET http://localhost:50011/swagger/swagger-ui-standalone-preset.js - -
+2021-04-11 22:11:59.151 +08:00 [INF] Request starting HTTP/1.1 GET http://localhost:50011/swagger/swagger-ui.css - -
+2021-04-11 22:11:59.201 +08:00 [INF] Sending file. Request path: '/swagger-ui.css'. Physical path: 'N/A'
+2021-04-11 22:11:59.204 +08:00 [INF] Sending file. Request path: '/swagger-ui-standalone-preset.js'. Physical path: 'N/A'
+2021-04-11 22:11:59.206 +08:00 [INF] Sending file. Request path: '/swagger-ui-bundle.js'. Physical path: 'N/A'
+2021-04-11 22:11:59.210 +08:00 [INF] Request finished HTTP/1.1 GET http://localhost:50011/swagger/swagger-ui.css - - - 200 142933 text/css 58.5102ms
+2021-04-11 22:11:59.210 +08:00 [INF] Request finished HTTP/1.1 GET http://localhost:50011/swagger/swagger-ui-standalone-preset.js - - - 200 311804 application/javascript 61.1681ms
+2021-04-11 22:11:59.212 +08:00 [INF] Request finished HTTP/1.1 GET http://localhost:50011/swagger/swagger-ui-bundle.js - - - 200 986342 application/javascript 64.4272ms
+2021-04-11 22:11:59.412 +08:00 [INF] Request starting HTTP/1.1 GET http://localhost:50011/swagger/v1/swagger.json - -
+2021-04-11 22:11:59.437 +08:00 [INF] Request starting HTTP/1.1 GET http://localhost:50011/swagger/favicon-32x32.png - -
+2021-04-11 22:11:59.439 +08:00 [INF] Sending file. Request path: '/favicon-32x32.png'. Physical path: 'N/A'
+2021-04-11 22:11:59.441 +08:00 [INF] Request finished HTTP/1.1 GET http://localhost:50011/swagger/favicon-32x32.png - - - 200 628 image/png 3.5332ms
+2021-04-11 22:11:59.474 +08:00 [INF] Request finished HTTP/1.1 GET http://localhost:50011/swagger/v1/swagger.json - - - 200 - application/json;charset=utf-8 61.8611ms
diff --git a/content/aspnetcore/host/CompanyName.ProjectName.PublicApi.Host/CompanyName.ProjectName.PublicApi.Host.csproj b/content/aspnetcore/host/CompanyName.ProjectName.PublicApi.Host/CompanyName.ProjectName.PublicApi.Host.csproj
new file mode 100644
index 00000000..cec65294
--- /dev/null
+++ b/content/aspnetcore/host/CompanyName.ProjectName.PublicApi.Host/CompanyName.ProjectName.PublicApi.Host.csproj
@@ -0,0 +1,44 @@
+
+
+
+
+
+ net5.0
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/content/aspnetcore/host/CompanyName.ProjectName.PublicApi.Host/CompanyNameProjectNamePublicApiConsts.cs b/content/aspnetcore/host/CompanyName.ProjectName.PublicApi.Host/CompanyNameProjectNamePublicApiConsts.cs
new file mode 100644
index 00000000..54ff8111
--- /dev/null
+++ b/content/aspnetcore/host/CompanyName.ProjectName.PublicApi.Host/CompanyNameProjectNamePublicApiConsts.cs
@@ -0,0 +1,14 @@
+namespace CompanyNameProjectName.PublicApi.Host
+{
+ public class CompanyNameProjectNamePublicApiConsts
+ {
+ public const string Policy_Read = "Policy_Read";
+
+ public const string Policy_Write = "Policy_Write";
+
+
+ public const string Scope_Read = "CompanyNameProjectNamePublicApi.Read";
+
+ public const string Scope_Write = "CompanyNameProjectNamePublicApi.Write";
+ }
+}
diff --git a/content/aspnetcore/host/CompanyName.ProjectName.PublicApi.Host/CompanyNameProjectNamePublicApiModule.cs b/content/aspnetcore/host/CompanyName.ProjectName.PublicApi.Host/CompanyNameProjectNamePublicApiModule.cs
new file mode 100644
index 00000000..fb7a3de1
--- /dev/null
+++ b/content/aspnetcore/host/CompanyName.ProjectName.PublicApi.Host/CompanyNameProjectNamePublicApiModule.cs
@@ -0,0 +1,90 @@
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Builder;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Hosting;
+using Microsoft.IdentityModel.Logging;
+using Microsoft.OpenApi.Models;
+using Serilog;
+using System;
+using Volo.Abp;
+using Volo.Abp.AspNetCore.Mvc;
+using Volo.Abp.Autofac;
+using Volo.Abp.Modularity;
+using CompanyNameProjectName.Extensions;
+using CompanyNameProjectName.PublicApi.Host;
+
+namespace CompanyNameProjectName.PublicApi
+{
+ [DependsOn(
+ typeof(AbpAspNetCoreMvcModule),
+ typeof(AbpAutofacModule),
+ typeof(CompanyNameProjectNameHttpApiClientModule)
+ )]
+ public class CompanyNameProjectNamePublicApiModule : AbpModule
+ {
+ public override void ConfigureServices(ServiceConfigurationContext context)
+ {
+ ConfigureSwagger(context);
+ ConfigureAuthentication(context);
+ }
+
+ public override void OnApplicationInitialization(ApplicationInitializationContext context)
+ {
+ var app = context.GetApplicationBuilder();
+ var env = context.GetEnvironment();
+ if (env.IsDevelopment())
+ {
+ app.UseDeveloperExceptionPage();
+ app.UseSwagger();
+ app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "CompanyNameProjectName.PublicApi.Host v1"));
+ }
+
+ app.UseAuthentication();
+ app.UseRouting();
+ app.UseAuthorization();
+ app.UseSerilogRequestLogging(opts =>
+ {
+ opts.EnrichDiagnosticContext = SerilogToEsExtensions.EnrichFromRequest;
+ });
+ app.UseConfiguredEndpoints();
+ }
+
+ private void ConfigureAuthentication(ServiceConfigurationContext context)
+ {
+ var configuration = context.Services.GetConfiguration();
+ IdentityModelEventSource.ShowPII = true;
+ context.Services.AddAuthentication("Bearer")
+ .AddJwtBearer("Bearer", options =>
+ {
+ //token颁发者
+ options.Authority = configuration["AuthServer:Authority"];
+ options.Audience = configuration["AuthServer:ApiName"];
+ options.RequireHttpsMetadata = Convert.ToBoolean(configuration["AuthServer:RequireHttpsMetadata"]);
+ });
+
+ context.Services.AddAuthorization(options =>
+ {
+ // 为了掩饰 分读写权限
+ options.AddPolicy(CompanyNameProjectNamePublicApiConsts.Policy_Read, builder =>
+ builder.RequireScope(new string[] {
+ CompanyNameProjectNamePublicApiConsts.Scope_Read })
+ );
+
+ options.AddPolicy(CompanyNameProjectNamePublicApiConsts.Policy_Write, builder =>
+ builder.RequireScope(new string[] {
+ CompanyNameProjectNamePublicApiConsts.Scope_Write })
+ );
+ });
+ }
+
+ private void ConfigureSwagger(ServiceConfigurationContext context)
+ {
+ var services = context.Services;
+
+ services.AddSwaggerGen(c =>
+ {
+ c.SwaggerDoc("v1", new OpenApiInfo { Title = "CompanyNameProjectName.PublicApi.Host", Version = "v1" });
+ });
+ }
+ }
+}
diff --git a/content/aspnetcore/host/CompanyName.ProjectName.PublicApi.Host/Controllers/SampleController.cs b/content/aspnetcore/host/CompanyName.ProjectName.PublicApi.Host/Controllers/SampleController.cs
new file mode 100644
index 00000000..09bbe22b
--- /dev/null
+++ b/content/aspnetcore/host/CompanyName.ProjectName.PublicApi.Host/Controllers/SampleController.cs
@@ -0,0 +1,38 @@
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.Extensions.Configuration;
+using System.Threading.Tasks;
+using Volo.Abp.AspNetCore.Mvc;
+
+namespace CompanyNameProjectName.PublicApi.Host.Controllers
+{
+ [Route("api/[controller]")]
+ [ApiController]
+ public class SampleController : AbpController
+ {
+ private readonly IConfiguration _configuration;
+
+ public SampleController(
+ IConfiguration configuration)
+ {
+ _configuration = configuration;
+
+ }
+
+ [HttpGet("write")]
+ [Authorize(Policy = CompanyNameProjectNamePublicApiConsts.Policy_Write)]
+ public async Task WriteAsync()
+ {
+ await Task.CompletedTask;
+ return Ok("Write权限通过");
+ }
+
+ [HttpGet("read")]
+ [Authorize(Policy = CompanyNameProjectNamePublicApiConsts.Policy_Read)]
+ public async Task ReadAsync()
+ {
+ await Task.CompletedTask;
+ return Ok("Read权限通过");
+ }
+ }
+}
diff --git a/content/aspnetcore/host/CompanyName.ProjectName.PublicApi.Host/Extensions/SerilogToEsExtensions.cs b/content/aspnetcore/host/CompanyName.ProjectName.PublicApi.Host/Extensions/SerilogToEsExtensions.cs
new file mode 100644
index 00000000..1d5837c3
--- /dev/null
+++ b/content/aspnetcore/host/CompanyName.ProjectName.PublicApi.Host/Extensions/SerilogToEsExtensions.cs
@@ -0,0 +1,135 @@
+using Microsoft.AspNetCore.Http;
+using Microsoft.Extensions.Configuration;
+using Serilog;
+using Serilog.Exceptions;
+using Serilog.Exceptions.Core;
+using Serilog.Sinks.Elasticsearch;
+using System;
+using System.IO;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace CompanyNameProjectName.Extensions
+{
+ public static class SerilogToEsExtensions
+ {
+
+ public static void SetSerilogConfiguration(LoggerConfiguration loggerConfiguration, IConfiguration configuration)
+ {
+ // 默认读取 configuration 中 "Serilog" 节点下的配置
+ loggerConfiguration.ReadFrom.Configuration(configuration)
+ .Enrich.WithExceptionDetails()
+ .Enrich.WithExceptionDetails(new DestructuringOptionsBuilder()
+ .WithDefaultDestructurers()
+ )
+ .Enrich.FromLogContext()
+ .WriteTo.Console()
+ .WriteTo.File("App_Data/logs/logs.txt", rollingInterval: RollingInterval.Day);
+
+ var writeToElasticSearch = configuration.GetValue("LogToElasticSearch:Enabled", false);
+
+ // LogToElasticSearch:Enabled = true 才输出至ES
+ if (!writeToElasticSearch)
+ return;
+
+ var applicationName = "CompanyNameProjectName.HttpApi.Host";
+
+ var esUrl = configuration["LogToElasticSearch:ElasticSearch:Url"];
+ // 需要设置ES URL
+ if (string.IsNullOrEmpty(esUrl))
+ return;
+
+
+ var indexFormat = configuration["LogToElasticSearch:ElasticSearch:IndexFormat"];
+
+ // 需要设置ES URL
+ if (string.IsNullOrEmpty(indexFormat))
+ return;
+
+ var esUserName = configuration["LogToElasticSearch:ElasticSearch:UserName"];
+ var esPassword = configuration["LogToElasticSearch:ElasticSearch:Password"];
+
+ loggerConfiguration.Enrich.FromLogContext().Enrich.WithExceptionDetails().WriteTo.Elasticsearch(BuildElasticSearchSinkOptions(esUrl, indexFormat, esUserName, esPassword));
+ loggerConfiguration.Enrich.WithProperty("Application", applicationName);
+ }
+
+ // 创建Es连接
+ private static ElasticsearchSinkOptions BuildElasticSearchSinkOptions(
+ string url,
+ string indexFormat,
+ string userName,
+ string password)
+ {
+ if (string.IsNullOrEmpty(userName))
+ {
+ return new ElasticsearchSinkOptions(new Uri(url))
+ {
+ AutoRegisterTemplate = true,
+ AutoRegisterTemplateVersion = AutoRegisterTemplateVersion.ESv7,
+ IndexFormat = indexFormat
+ };
+ }
+
+ return new ElasticsearchSinkOptions(new Uri(url))
+ {
+ AutoRegisterTemplate = true,
+ AutoRegisterTemplateVersion = AutoRegisterTemplateVersion.ESv7,
+ IndexFormat = indexFormat,
+ ModifyConnectionSettings = x => x.BasicAuthentication(userName, password)
+ };
+ }
+
+ public static void EnrichFromRequest(IDiagnosticContext diagnosticContext, HttpContext httpContext)
+ {
+ var request = httpContext.Request;
+
+ // 为每个请求都设置通用的属性
+ diagnosticContext.Set("Host", request.Host);
+ diagnosticContext.Set("Protocol", request.Protocol);
+ diagnosticContext.Set("Scheme", request.Scheme);
+ diagnosticContext.Set("RemoteIpAddress", httpContext.Connection.RemoteIpAddress);
+ // 如果要记录 Request Body 或 Response Body
+ // 参考 https://stackoverflow.com/questions/60076922/serilog-logging-web-api-methods-adding-context-properties-inside-middleware
+ string requestBody = ReadRequestBody(httpContext.Request).Result;
+ if (!string.IsNullOrEmpty(requestBody))
+ {
+ diagnosticContext.Set("RequestBody", requestBody);
+ }
+
+ // string responseBody = ReadResponseBody(httpContext.Response).Result;
+ // if (!string.IsNullOrEmpty(responseBody))
+ // {
+ // diagnosticContext.Set("ResponseBody", requestBody);
+ // }
+
+ if (request.QueryString.HasValue)
+ {
+ diagnosticContext.Set("QueryString", request.QueryString.Value);
+ }
+
+ }
+
+ private static async Task ReadRequestBody(HttpRequest request)
+ {
+ HttpRequestRewindExtensions.EnableBuffering(request);
+
+ var body = request.Body;
+ var buffer = new byte[Convert.ToInt32(request.ContentLength)];
+ await request.Body.ReadAsync(buffer, 0, buffer.Length);
+ string requestBody = Encoding.UTF8.GetString(buffer);
+ body.Seek(0, SeekOrigin.Begin);
+ request.Body = body;
+
+ return $"{requestBody}";
+ }
+
+ private static async Task ReadResponseBody(HttpResponse response)
+ {
+ response.Body.Seek(0, SeekOrigin.Begin);
+ string responseBody = await new StreamReader(response.Body).ReadToEndAsync();
+ response.Body.Seek(0, SeekOrigin.Begin);
+
+ return $"{responseBody}";
+ }
+ }
+}
diff --git a/content/aspnetcore/host/CompanyName.ProjectName.PublicApi.Host/Program.cs b/content/aspnetcore/host/CompanyName.ProjectName.PublicApi.Host/Program.cs
new file mode 100644
index 00000000..208f24b8
--- /dev/null
+++ b/content/aspnetcore/host/CompanyName.ProjectName.PublicApi.Host/Program.cs
@@ -0,0 +1,33 @@
+using Microsoft.AspNetCore.Hosting;
+using Microsoft.Extensions.Configuration;
+using Microsoft.Extensions.Hosting;
+using Serilog;
+using CompanyNameProjectName.Extensions;
+
+namespace CompanyNameProjectName.PublicApi.Host
+{
+ public class Program
+ {
+ public static void Main(string[] args)
+ {
+ CreateHostBuilder(args).Build().Run();
+ }
+
+ public static IHostBuilder CreateHostBuilder(string[] args) =>
+ Microsoft.Extensions.Hosting.Host.CreateDefaultBuilder(args)
+ .ConfigureWebHostDefaults(webBuilder =>
+ {
+ webBuilder.UseStartup();
+ })
+ //.ConfigureAppConfiguration((context, builder) => {
+ // // nacos
+ // builder.AddNacosConfiguration(builder.Build().GetSection("NacosConfig"));
+ //})
+ .UseSerilog((context, loggerConfiguration) =>
+ {
+ SerilogToEsExtensions.SetSerilogConfiguration(
+ loggerConfiguration,
+ context.Configuration);
+ }).UseAutofac();
+ }
+}
diff --git a/content/aspnetcore/host/CompanyName.ProjectName.PublicApi.Host/Properties/launchSettings.json b/content/aspnetcore/host/CompanyName.ProjectName.PublicApi.Host/Properties/launchSettings.json
new file mode 100644
index 00000000..a1b1cbb6
--- /dev/null
+++ b/content/aspnetcore/host/CompanyName.ProjectName.PublicApi.Host/Properties/launchSettings.json
@@ -0,0 +1,16 @@
+{
+ "$schema": "http://json.schemastore.org/launchsettings.json",
+
+ "profiles": {
+ "CompanyNameProjectName.PublicApi.Host": {
+ "commandName": "Project",
+ "dotnetRunMessages": "true",
+ "launchBrowser": true,
+ "launchUrl": "swagger",
+ "applicationUrl": "http://localhost:50011",
+ "environmentVariables": {
+ "ASPNETCORE_ENVIRONMENT": "Development"
+ }
+ }
+ }
+}
diff --git a/content/aspnetcore/host/CompanyName.ProjectName.PublicApi.Host/Startup.cs b/content/aspnetcore/host/CompanyName.ProjectName.PublicApi.Host/Startup.cs
new file mode 100644
index 00000000..df72dcee
--- /dev/null
+++ b/content/aspnetcore/host/CompanyName.ProjectName.PublicApi.Host/Startup.cs
@@ -0,0 +1,19 @@
+using Microsoft.AspNetCore.Builder;
+using Microsoft.AspNetCore.Hosting;
+using Microsoft.Extensions.DependencyInjection;
+
+namespace CompanyNameProjectName.PublicApi.Host
+{
+ public class Startup
+ {
+ public void ConfigureServices(IServiceCollection services)
+ {
+ services.AddApplication();
+ }
+
+ public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
+ {
+ app.InitializeApplication();
+ }
+ }
+}
diff --git a/content/aspnetcore/host/CompanyName.ProjectName.PublicApi.Host/appsettings.Staging.json b/content/aspnetcore/host/CompanyName.ProjectName.PublicApi.Host/appsettings.Staging.json
new file mode 100644
index 00000000..4ea98df0
--- /dev/null
+++ b/content/aspnetcore/host/CompanyName.ProjectName.PublicApi.Host/appsettings.Staging.json
@@ -0,0 +1,29 @@
+{
+ "Logging": {
+ "LogLevel": {
+ "Default": "Information",
+ "Microsoft": "Warning",
+ "Microsoft.Hosting.Lifetime": "Information"
+ }
+ },
+ "AllowedHosts": "*",
+ "LogToElasticSearch": {
+ "Enabled": "true",
+ "ElasticSearch": {
+ "Url": "http://es.platform.cn",
+ "IndexFormat": "CompanyNameProjectName.public.api.dev-{0:yyyy.MM.dd}",
+ "UserName": "erp",
+ "Password": "TCYobkZxWu0ELYZY"
+ }
+ },
+ "AuthServer": {
+ "Authority": "http://sts.vnext.identity.development.cn",
+ "RequireHttpsMetadata": "false",
+ "ApiName": "CompanyNameProjectNamePublicApi"
+ },
+ "RemoteServices": {
+ "CompanyNameProjectName": {
+ "BaseUrl": "http://localhost:50000/"
+ }
+ }
+}
\ No newline at end of file
diff --git a/content/aspnetcore/host/CompanyName.ProjectName.PublicApi.Host/appsettings.json b/content/aspnetcore/host/CompanyName.ProjectName.PublicApi.Host/appsettings.json
new file mode 100644
index 00000000..4ea98df0
--- /dev/null
+++ b/content/aspnetcore/host/CompanyName.ProjectName.PublicApi.Host/appsettings.json
@@ -0,0 +1,29 @@
+{
+ "Logging": {
+ "LogLevel": {
+ "Default": "Information",
+ "Microsoft": "Warning",
+ "Microsoft.Hosting.Lifetime": "Information"
+ }
+ },
+ "AllowedHosts": "*",
+ "LogToElasticSearch": {
+ "Enabled": "true",
+ "ElasticSearch": {
+ "Url": "http://es.platform.cn",
+ "IndexFormat": "CompanyNameProjectName.public.api.dev-{0:yyyy.MM.dd}",
+ "UserName": "erp",
+ "Password": "TCYobkZxWu0ELYZY"
+ }
+ },
+ "AuthServer": {
+ "Authority": "http://sts.vnext.identity.development.cn",
+ "RequireHttpsMetadata": "false",
+ "ApiName": "CompanyNameProjectNamePublicApi"
+ },
+ "RemoteServices": {
+ "CompanyNameProjectName": {
+ "BaseUrl": "http://localhost:50000/"
+ }
+ }
+}
\ No newline at end of file
diff --git a/content/aspnetcore/host/CompanyName.ProjectName.PublicApi.Host/tempkey.jwk b/content/aspnetcore/host/CompanyName.ProjectName.PublicApi.Host/tempkey.jwk
new file mode 100644
index 00000000..2c548378
--- /dev/null
+++ b/content/aspnetcore/host/CompanyName.ProjectName.PublicApi.Host/tempkey.jwk
@@ -0,0 +1 @@
+{"alg":"RS256","d":"lNH0OzXPRnDsV767u7a3LZCHUTUVfyvDOPqKBWjVKs03hHvpbPm6xxyJxR_2MDUFaDxHmVKjXZxOPZFuAiKbKWXNsjmpirtF2U42TjjnCvEb2Nb-G6SIC_JeaNo8kV3OUE4UzFWw_rpTF6CKpGdOhCVDAPdyGU-9GM7h6bcFLg3jbThUC7CrYSl57bQswUhiXwYxiA20dXkwh0sDSIMXlZOfurWz8w0etYQq1LTSIlhpZ021x4csQyTQM2X0rFVZnS8f75oDyYBI0E9xU9ogC9LpaxrPBnxNhqXQ8LnTgK_5Nmi3m-GLKxC6ImGxItQlV7pf5iP8E1lEQ3U63dvabQ","dp":"LbtXHqBYBs3VapOkZIrXAJrNux9fAqrq_2FDjiHxL76uXlTk2rq0Em-aVkQv9M-QzzaJNR-r1fSIscibQvS1VhWMha3-vR04pAy7KvA1T9bfZa7QWiAN-Po1IDH7hPe1U9Du2prJ9XPjaHLDffvI_bMfFdSdxZeaghivyh92K6U","dq":"pHr9BRS6ArlmPqSwmw2eQhcVsDAfOu22WEK7wD26wDRG4riV4uJticVQOHCpwTn0-5kCcp2LfBhX0uanFTh5dGT62B1Ib6DKpjT39hcSF1V1-GJl0fyrmvXku7cyeRTqooLCHrXovZ4EV0uDRAeAkZ03BCpTW5MxGqKA7doWWOE","e":"AQAB","kid":"9F6E0CA233DC806A58A0821E58521B17","kty":"RSA","n":"pEaiCVTAe6F6hBpi6ozmA3let7sBJwGcKoo1Vm0t1EvqiMLsBuU1lB9pVUzxPb8zFpAKpgrgpA58u7Pv0erZ_9_zRYAQ2jxglp9bPJmTtga2cY-emPzl_0cDgsTTYiTh4c9btgB2eYgLAyaAeM9K82vblTs-0HPK7o7zQJvX6-iv_-B8XY7DLOHwAp_Ua_DiAwx4sarULRpCPULD2HHtFl990NpunCj1Bo1kcZcF9SKQxM9KM2UEd5P6GbQJjkU549tO2kK22oHNJz1krbDyfLC0G8VWFN6Z-fb44hoerHpILyQvdpCTdarJG3JUlkhsCLx8FAYqz5cuQ5KhQ8YWiQ","p":"1mrTYqHNXPY5XlbKtUyn-GoMDLGdzGNxCuIzfUMOIhACSh-h7gsvv5msOiPKZLiRB0b1Qu_v_H2KGNu4Rb209jMbyYrLfo1rh4QIfetFx3K-oJ86Evs0EZXQf-RgY2WdPVJar1YgBKYqM-gLJh4XGnwdBxBdqgU0AfaVkiwuEBs","q":"xCJwPOWJ6NaHwEGBc7tncSghuFUIUu8psDlUc-78ClrOi_WII7y0Q0-kLB_COdmlxhVOO58bLDZZL8PBFH4q_Mm9qFHVSBxLJ97AoQxVxed31Eqq6SG_3iv4LqKI6EKk9nLLBKh3L1sn0nafHORfNp4vtCNJSZatkCbh5I0GRis","qi":"ud4nssqZ00XTbkObwyoWEHMzgYQifdBInXk_j6KRaKt_fPYzxVWnHoVAaLSgKJTU1aqxiJHd3Mb5sCvM_W-MocKAeWxeGij0R-kv16El8eTNgsukcr3mdAOeaUsZlVuXOeO9ol-e6VOTIziIqLJmTjflruh0ZskDUw0AJ8xVIro"}
\ No newline at end of file
diff --git a/content/aspnetcore/src/CompanyName.ProjectName.Application.Contracts/CompanyName.ProjectName.Application.Contracts.csproj b/content/aspnetcore/src/CompanyName.ProjectName.Application.Contracts/CompanyName.ProjectName.Application.Contracts.csproj
new file mode 100644
index 00000000..45a3a91c
--- /dev/null
+++ b/content/aspnetcore/src/CompanyName.ProjectName.Application.Contracts/CompanyName.ProjectName.Application.Contracts.csproj
@@ -0,0 +1,39 @@
+
+
+
+
+
+ netstandard2.1
+ CompanyNameProjectName
+
+
+
+ bin\Debug\netstandard2.1\CompanyNameProjectName.Application.Contracts.xml
+ bin\Debug\netstandard2.1\
+
+
+
+ bin\Debug\netstandard2.1\
+ bin\Debug\netstandard2.1\CompanyNameProjectName.Application.Contracts.xml
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/content/aspnetcore/src/CompanyName.ProjectName.Application.Contracts/CompanyNameProjectNameApplicationContractsModule.cs b/content/aspnetcore/src/CompanyName.ProjectName.Application.Contracts/CompanyNameProjectNameApplicationContractsModule.cs
new file mode 100644
index 00000000..5e1e66a0
--- /dev/null
+++ b/content/aspnetcore/src/CompanyName.ProjectName.Application.Contracts/CompanyNameProjectNameApplicationContractsModule.cs
@@ -0,0 +1,28 @@
+using Volo.Abp.Account;
+using Volo.Abp.FeatureManagement;
+using Volo.Abp.Identity;
+using Volo.Abp.Modularity;
+using Volo.Abp.ObjectExtending;
+using Volo.Abp.PermissionManagement;
+using Volo.Abp.TenantManagement;
+
+namespace CompanyNameProjectName
+{
+ [DependsOn(
+ typeof(CompanyNameProjectNameDomainSharedModule),
+ typeof(AbpAccountApplicationContractsModule),
+ typeof(AbpFeatureManagementApplicationContractsModule),
+ typeof(AbpIdentityApplicationContractsModule),
+ typeof(AbpPermissionManagementApplicationContractsModule),
+ typeof(AbpTenantManagementApplicationContractsModule),
+ typeof(AbpObjectExtendingModule),
+ typeof(EasyAbp.Abp.SettingUi.SettingUiApplicationContractsModule)
+ )]
+ public class CompanyNameProjectNameApplicationContractsModule : AbpModule
+ {
+ public override void PreConfigureServices(ServiceConfigurationContext context)
+ {
+ CompanyNameProjectNameDtoExtensions.Configure();
+ }
+ }
+}
diff --git a/content/aspnetcore/src/CompanyName.ProjectName.Application.Contracts/CompanyNameProjectNameDtoExtensions.cs b/content/aspnetcore/src/CompanyName.ProjectName.Application.Contracts/CompanyNameProjectNameDtoExtensions.cs
new file mode 100644
index 00000000..28210f1f
--- /dev/null
+++ b/content/aspnetcore/src/CompanyName.ProjectName.Application.Contracts/CompanyNameProjectNameDtoExtensions.cs
@@ -0,0 +1,27 @@
+using Volo.Abp.Threading;
+
+namespace CompanyNameProjectName
+{
+ public static class CompanyNameProjectNameDtoExtensions
+ {
+ private static readonly OneTimeRunner OneTimeRunner = new OneTimeRunner();
+
+ public static void Configure()
+ {
+ OneTimeRunner.Run(() =>
+ {
+ /* You can add extension properties to Dtos
+ * defined in the depended modules.
+ *
+ * Example:
+ *
+ * ObjectExtensionManager.Instance
+ * .AddOrUpdateProperty("Title");
+ *
+ * See the documentation for more:
+ * https://docs.abp.io/en/abp/latest/Object-Extensions
+ */
+ });
+ }
+ }
+}
\ No newline at end of file
diff --git a/content/aspnetcore/src/CompanyName.ProjectName.Application.Contracts/Jobs/IRecurringJob.cs b/content/aspnetcore/src/CompanyName.ProjectName.Application.Contracts/Jobs/IRecurringJob.cs
new file mode 100644
index 00000000..70b979cb
--- /dev/null
+++ b/content/aspnetcore/src/CompanyName.ProjectName.Application.Contracts/Jobs/IRecurringJob.cs
@@ -0,0 +1,14 @@
+using System.Threading.Tasks;
+using Volo.Abp.DependencyInjection;
+
+namespace CompanyNameProjectName.Jobs
+{
+ public interface IRecurringJob : ITransientDependency
+ {
+ ///
+ /// 执行任务
+ ///
+ ///
+ Task ExecuteAsync();
+ }
+}
diff --git a/content/aspnetcore/src/CompanyName.ProjectName.Application.Contracts/Options/JwtOptions.cs b/content/aspnetcore/src/CompanyName.ProjectName.Application.Contracts/Options/JwtOptions.cs
new file mode 100644
index 00000000..d3e4a05e
--- /dev/null
+++ b/content/aspnetcore/src/CompanyName.ProjectName.Application.Contracts/Options/JwtOptions.cs
@@ -0,0 +1,17 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace CompanyNameProjectName.Options
+{
+ public class JwtOptions
+ {
+ public int ExpirationTime { get; set; }
+
+ public string Audience { get; set; }
+
+ public string SecurityKey { get; set; }
+
+ public string Issuer { get; set; }
+ }
+}
diff --git a/content/aspnetcore/src/CompanyName.ProjectName.Application.Contracts/Pages/Dtos/CustomeRequestDto.cs b/content/aspnetcore/src/CompanyName.ProjectName.Application.Contracts/Pages/Dtos/CustomeRequestDto.cs
new file mode 100644
index 00000000..5c0d6c1b
--- /dev/null
+++ b/content/aspnetcore/src/CompanyName.ProjectName.Application.Contracts/Pages/Dtos/CustomeRequestDto.cs
@@ -0,0 +1,15 @@
+namespace CompanyNameProjectName.Pages.Dtos
+{
+ public class CustomeRequestDto
+ {
+ ///
+ /// 当前页面
+ ///
+ public int pageIndex { get; set; } = 1;
+
+ ///
+ /// 每页多少条
+ ///
+ public int PageSize { get; set; } = 10;
+ }
+}
diff --git a/content/aspnetcore/src/CompanyName.ProjectName.Application.Contracts/Permissions/CompanyNameProjectNamePermissionDefinitionProvider.cs b/content/aspnetcore/src/CompanyName.ProjectName.Application.Contracts/Permissions/CompanyNameProjectNamePermissionDefinitionProvider.cs
new file mode 100644
index 00000000..d38481e2
--- /dev/null
+++ b/content/aspnetcore/src/CompanyName.ProjectName.Application.Contracts/Permissions/CompanyNameProjectNamePermissionDefinitionProvider.cs
@@ -0,0 +1,23 @@
+using CompanyNameProjectName.Localization;
+using Volo.Abp.Authorization.Permissions;
+using Volo.Abp.Localization;
+
+namespace CompanyNameProjectName.Permissions
+{
+ public class CompanyNameProjectNamePermissionDefinitionProvider : PermissionDefinitionProvider
+ {
+ public override void Define(IPermissionDefinitionContext context)
+ {
+
+
+ //Define your own permissions here. Example:
+ //myGroup.AddPermission(CompanyNameProjectNamePermissions.MyPermission1, L("Permission:MyPermission1"));
+
+ }
+
+ private static LocalizableString L(string name)
+ {
+ return LocalizableString.Create(name);
+ }
+ }
+}
diff --git a/content/aspnetcore/src/CompanyName.ProjectName.Application.Contracts/Permissions/CompanyNameProjectNamePermissions.cs b/content/aspnetcore/src/CompanyName.ProjectName.Application.Contracts/Permissions/CompanyNameProjectNamePermissions.cs
new file mode 100644
index 00000000..c4bc8cc9
--- /dev/null
+++ b/content/aspnetcore/src/CompanyName.ProjectName.Application.Contracts/Permissions/CompanyNameProjectNamePermissions.cs
@@ -0,0 +1,24 @@
+namespace CompanyNameProjectName.Permissions
+{
+ public static class CompanyNameProjectNamePermissions
+ {
+ public const string GroupName = "CompanyNameProjectName";
+
+ //Add your own permission names. Example:
+ //public const string MyPermission1 = GroupName + ".MyPermission1";
+
+ public const string DicGroupName = "Dic";
+
+ ///
+ /// 字典权限
+ ///
+ public static class Dic
+ {
+ public const string Default = GroupName + ".Dic";
+ public const string Query = Default + ".Query";
+ public const string Create = Default + ".Create";
+ public const string Update = Default + ".Update";
+ public const string Delete = Default + ".Delete";
+ }
+ }
+}
\ No newline at end of file
diff --git a/content/aspnetcore/src/CompanyName.ProjectName.Application.Contracts/Roles/Dtos/GetRoleListInput.cs b/content/aspnetcore/src/CompanyName.ProjectName.Application.Contracts/Roles/Dtos/GetRoleListInput.cs
new file mode 100644
index 00000000..76d12864
--- /dev/null
+++ b/content/aspnetcore/src/CompanyName.ProjectName.Application.Contracts/Roles/Dtos/GetRoleListInput.cs
@@ -0,0 +1,12 @@
+using CompanyNameProjectName.Pages.Dtos;
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace CompanyNameProjectName.Roles.Dtos
+{
+ public class GetRoleListInput : CustomeRequestDto
+ {
+ public string filter { get; set; }
+ }
+}
diff --git a/content/aspnetcore/src/CompanyName.ProjectName.Application.Contracts/Roles/Dtos/UpdateRoleInput.cs b/content/aspnetcore/src/CompanyName.ProjectName.Application.Contracts/Roles/Dtos/UpdateRoleInput.cs
new file mode 100644
index 00000000..d29eeb86
--- /dev/null
+++ b/content/aspnetcore/src/CompanyName.ProjectName.Application.Contracts/Roles/Dtos/UpdateRoleInput.cs
@@ -0,0 +1,12 @@
+using System;
+using Volo.Abp.Identity;
+
+namespace CompanyNameProjectName.Roles.Dtos
+{
+ public class UpdateRoleInput
+ {
+ public Guid RoleId { get; set; }
+
+ public IdentityRoleUpdateDto RoleInfo { get; set; }
+ }
+}
diff --git a/content/aspnetcore/src/CompanyName.ProjectName.Application.Contracts/Roles/Dtos/UpdateRolePermissionsDto.cs b/content/aspnetcore/src/CompanyName.ProjectName.Application.Contracts/Roles/Dtos/UpdateRolePermissionsDto.cs
new file mode 100644
index 00000000..05cf84d7
--- /dev/null
+++ b/content/aspnetcore/src/CompanyName.ProjectName.Application.Contracts/Roles/Dtos/UpdateRolePermissionsDto.cs
@@ -0,0 +1,16 @@
+using System.ComponentModel.DataAnnotations;
+using Volo.Abp.PermissionManagement;
+
+namespace CompanyNameProjectName.Roles.Dtos
+{
+ public class UpdateRolePermissionsDto
+ {
+ [Required]
+ public string ProviderName { get; set; }
+
+ [Required]
+ public string ProviderKey { get; set; }
+
+ public UpdatePermissionsDto UpdatePermissionsDto { get; set; }
+ }
+}
diff --git a/content/aspnetcore/src/CompanyName.ProjectName.Application.Contracts/Users/Dtos/GetUserListInput.cs b/content/aspnetcore/src/CompanyName.ProjectName.Application.Contracts/Users/Dtos/GetUserListInput.cs
new file mode 100644
index 00000000..bbae0158
--- /dev/null
+++ b/content/aspnetcore/src/CompanyName.ProjectName.Application.Contracts/Users/Dtos/GetUserListInput.cs
@@ -0,0 +1,12 @@
+using CompanyNameProjectName.Pages.Dtos;
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace CompanyNameProjectName.Users.Dtos
+{
+ public class GetUserListInput: CustomeRequestDto
+ {
+ public string filter { get; set; }
+ }
+}
diff --git a/content/aspnetcore/src/CompanyName.ProjectName.Application.Contracts/Users/Dtos/GetUsersInput.cs b/content/aspnetcore/src/CompanyName.ProjectName.Application.Contracts/Users/Dtos/GetUsersInput.cs
new file mode 100644
index 00000000..1c5ebbdf
--- /dev/null
+++ b/content/aspnetcore/src/CompanyName.ProjectName.Application.Contracts/Users/Dtos/GetUsersInput.cs
@@ -0,0 +1,8 @@
+using Volo.Abp.Application.Dtos;
+
+namespace CompanyNameProjectName.Dtos.Users
+{
+ public class GetUsersInput : PagedAndSortedResultRequestDto
+ {
+ }
+}
diff --git a/content/aspnetcore/src/CompanyName.ProjectName.Application.Contracts/Users/Dtos/LoginInputDto.cs b/content/aspnetcore/src/CompanyName.ProjectName.Application.Contracts/Users/Dtos/LoginInputDto.cs
new file mode 100644
index 00000000..d5784fc8
--- /dev/null
+++ b/content/aspnetcore/src/CompanyName.ProjectName.Application.Contracts/Users/Dtos/LoginInputDto.cs
@@ -0,0 +1,35 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.DataAnnotations;
+
+namespace CompanyNameProjectName.Dtos.Users
+{
+ ///
+ /// 登录
+ ///
+ public class LoginInputDto : IValidatableObject
+ {
+ ///
+ /// 用户名或者邮箱
+ ///
+ public string Name { get; set; }
+
+ ///
+ /// 密码
+ ///
+ public string Password { get; set; }
+
+ public IEnumerable Validate(ValidationContext validationContext)
+ {
+ if (Name.IsNullOrWhiteSpace())
+ {
+ yield return new ValidationResult("Email can not be null", new[] { "Email" });
+ }
+
+ if (Password.IsNullOrWhiteSpace())
+ {
+ yield return new ValidationResult("Password can not be null", new[] { "Password" });
+ }
+ }
+ }
+}
diff --git a/content/aspnetcore/src/CompanyName.ProjectName.Application.Contracts/Users/Dtos/LoginOutputDto.cs b/content/aspnetcore/src/CompanyName.ProjectName.Application.Contracts/Users/Dtos/LoginOutputDto.cs
new file mode 100644
index 00000000..931284d2
--- /dev/null
+++ b/content/aspnetcore/src/CompanyName.ProjectName.Application.Contracts/Users/Dtos/LoginOutputDto.cs
@@ -0,0 +1,20 @@
+using System;
+
+namespace CompanyNameProjectName.Dtos.Users
+{
+ public class LoginOutputDto
+ {
+ public Guid Id { get; set; }
+
+ public string Name { get; set; }
+
+ public string UserName { get; set; }
+
+ public string Token { get; set; }
+
+ ///
+ /// 过期时间
+ ///
+ public DateTime Expiration { get; set; }
+ }
+}
diff --git a/content/aspnetcore/src/CompanyName.ProjectName.Application.Contracts/Users/Dtos/UpdateUserInput.cs b/content/aspnetcore/src/CompanyName.ProjectName.Application.Contracts/Users/Dtos/UpdateUserInput.cs
new file mode 100644
index 00000000..74115af1
--- /dev/null
+++ b/content/aspnetcore/src/CompanyName.ProjectName.Application.Contracts/Users/Dtos/UpdateUserInput.cs
@@ -0,0 +1,14 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using Volo.Abp.Identity;
+
+namespace CompanyNameProjectName.Users.Dtos
+{
+ public class UpdateUserInput
+ {
+ public Guid UserId { get; set; }
+
+ public IdentityUserUpdateDto UserInfo { get; set; }
+ }
+}
diff --git a/content/aspnetcore/src/CompanyName.ProjectName.Application.Contracts/Users/ILoginAppService.cs b/content/aspnetcore/src/CompanyName.ProjectName.Application.Contracts/Users/ILoginAppService.cs
new file mode 100644
index 00000000..de53e104
--- /dev/null
+++ b/content/aspnetcore/src/CompanyName.ProjectName.Application.Contracts/Users/ILoginAppService.cs
@@ -0,0 +1,12 @@
+using CompanyNameProjectName.Dtos.Users;
+using System.Threading.Tasks;
+using Volo.Abp.Application.Services;
+
+
+namespace CompanyNameProjectName.Users
+{
+ public interface ILoginAppService: IApplicationService
+ {
+ Task PostAsync(LoginInputDto input);
+ }
+}
diff --git a/content/aspnetcore/src/CompanyName.ProjectName.Application/CompanyName.ProjectName.Application.csproj b/content/aspnetcore/src/CompanyName.ProjectName.Application/CompanyName.ProjectName.Application.csproj
new file mode 100644
index 00000000..8fb12d25
--- /dev/null
+++ b/content/aspnetcore/src/CompanyName.ProjectName.Application/CompanyName.ProjectName.Application.csproj
@@ -0,0 +1,43 @@
+
+
+
+
+
+ net5.0
+ CompanyNameProjectName
+
+
+
+ bin\Debug\net5.0\CompanyNameProjectName.Application.xml
+ bin\Debug\net5.0\
+
+
+
+ bin\Debug\net5.0\
+ bin\Debug\net5.0\CompanyNameProjectName.Application.xml
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/content/aspnetcore/src/CompanyName.ProjectName.Application/CompanyNameProjectNameAppService.cs b/content/aspnetcore/src/CompanyName.ProjectName.Application/CompanyNameProjectNameAppService.cs
new file mode 100644
index 00000000..800f3a9f
--- /dev/null
+++ b/content/aspnetcore/src/CompanyName.ProjectName.Application/CompanyNameProjectNameAppService.cs
@@ -0,0 +1,18 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using CompanyNameProjectName.Localization;
+using Volo.Abp.Application.Services;
+
+namespace CompanyNameProjectName
+{
+ /* Inherit your application services from this class.
+ */
+ public abstract class CompanyNameProjectNameAppService : ApplicationService
+ {
+ protected CompanyNameProjectNameAppService()
+ {
+ LocalizationResource = typeof(CompanyNameProjectNameResource);
+ }
+ }
+}
diff --git a/content/aspnetcore/src/CompanyName.ProjectName.Application/CompanyNameProjectNameApplicationAutoMapperProfile.cs b/content/aspnetcore/src/CompanyName.ProjectName.Application/CompanyNameProjectNameApplicationAutoMapperProfile.cs
new file mode 100644
index 00000000..0b3c68f1
--- /dev/null
+++ b/content/aspnetcore/src/CompanyName.ProjectName.Application/CompanyNameProjectNameApplicationAutoMapperProfile.cs
@@ -0,0 +1,18 @@
+using AutoMapper;
+using CompanyNameProjectName.Dtos.Users;
+using Volo.Abp.Identity;
+
+namespace CompanyNameProjectName
+{
+ public class CompanyNameProjectNameApplicationAutoMapperProfile : Profile
+ {
+ public CompanyNameProjectNameApplicationAutoMapperProfile()
+ {
+ /* You can configure your AutoMapper mapping configuration here.
+ * Alternatively, you can split your mapping configurations
+ * into multiple profile classes for a better organization. */
+
+ CreateMap();
+ }
+ }
+}
diff --git a/content/aspnetcore/src/CompanyName.ProjectName.Application/CompanyNameProjectNameApplicationModule.cs b/content/aspnetcore/src/CompanyName.ProjectName.Application/CompanyNameProjectNameApplicationModule.cs
new file mode 100644
index 00000000..82a1051b
--- /dev/null
+++ b/content/aspnetcore/src/CompanyName.ProjectName.Application/CompanyNameProjectNameApplicationModule.cs
@@ -0,0 +1,32 @@
+using Volo.Abp.Account;
+using Volo.Abp.AutoMapper;
+using Volo.Abp.FeatureManagement;
+using Volo.Abp.Identity;
+using Volo.Abp.Modularity;
+using Volo.Abp.PermissionManagement;
+using Volo.Abp.TenantManagement;
+
+namespace CompanyNameProjectName
+{
+ [DependsOn(
+ typeof(CompanyNameProjectNameDomainModule),
+ typeof(AbpAccountApplicationModule),
+ typeof(CompanyNameProjectNameApplicationContractsModule),
+ typeof(AbpIdentityApplicationModule),
+ typeof(AbpPermissionManagementApplicationModule),
+ typeof(AbpTenantManagementApplicationModule),
+ typeof(AbpFeatureManagementApplicationModule),
+ typeof(EasyAbp.Abp.SettingUi.SettingUiApplicationModule)
+ )]
+ public class CompanyNameProjectNameApplicationModule : AbpModule
+ {
+ public override void ConfigureServices(ServiceConfigurationContext context)
+ {
+
+ Configure(options =>
+ {
+ options.AddMaps();
+ });
+ }
+ }
+}
diff --git a/content/aspnetcore/src/CompanyName.ProjectName.Application/Jobs/Helpers/CronTypeHelper.cs b/content/aspnetcore/src/CompanyName.ProjectName.Application/Jobs/Helpers/CronTypeHelper.cs
new file mode 100644
index 00000000..0a6fa341
--- /dev/null
+++ b/content/aspnetcore/src/CompanyName.ProjectName.Application/Jobs/Helpers/CronTypeHelper.cs
@@ -0,0 +1,81 @@
+using Hangfire;
+using System;
+
+namespace CompanyNameProjectName.Jobs
+{
+ ///
+ /// Cron类型
+ ///
+ public static class CronTypeHelper
+ {
+ ///
+ /// 周期性为分钟的任务
+ ///
+ /// 执行周期的间隔,默认为每分钟一次
+ ///
+ public static string Minute(int interval = 1)
+ {
+ return "1 0/" + interval.ToString() + " * * * ? ";
+ }
+
+ ///
+ /// 周期性为小时的任务
+ ///
+ /// 第几分钟开始,默认为第一分钟
+ /// 执行周期的间隔,默认为每小时一次
+ ///
+ public static string Hour(int minute = 1, int interval = 1)
+ {
+ return "1 " + minute + " 0/" + interval.ToString() + " * * ? ";
+ }
+
+ ///
+ /// 周期性为天的任务
+ ///
+ /// 第几小时开始,默认从1点开始
+ /// 第几分钟开始,默认从第1分钟开始
+ /// 执行周期的间隔,默认为每天一次
+ ///
+ public static string Day(int hour = 1, int minute = 1, int interval = 1)
+ {
+ return "1 " + minute.ToString() + " " + hour.ToString() + " 1/" + interval.ToString() + " * ? ";
+ }
+
+ ///
+ /// 周期性为周的任务
+ ///
+ /// 星期几开始,默认从星期一点开始
+ /// 第几小时开始,默认从1点开始
+ /// 第几分钟开始,默认从第1分钟开始
+ ///
+ public static string Week(DayOfWeek dayOfWeek = DayOfWeek.Monday, int hour = 1, int minute = 1)
+ {
+ return Cron.Weekly(dayOfWeek, hour, minute);
+ }
+
+ ///
+ /// 周期性为月的任务
+ ///
+ /// 几号开始,默认从一号开始
+ /// 第几小时开始,默认从1点开始
+ /// 第几分钟开始,默认从第1分钟开始
+ ///
+ public static string Month(int day = 1, int hour = 1, int minute = 1)
+ {
+ return Cron.Monthly(day, hour, minute);
+ }
+
+ ///
+ /// 周期性为年的任务
+ ///
+ /// 几月开始,默认从一月开始
+ /// 几号开始,默认从一号开始
+ /// 第几小时开始,默认从1点开始
+ /// 第几分钟开始,默认从第1分钟开始
+ ///
+ public static string Year(int month = 1, int day = 1, int hour = 1, int minute = 1)
+ {
+ return Cron.Yearly(month, day, hour, minute);
+ }
+ }
+}
diff --git a/content/aspnetcore/src/CompanyName.ProjectName.Application/Jobs/TestJob.cs b/content/aspnetcore/src/CompanyName.ProjectName.Application/Jobs/TestJob.cs
new file mode 100644
index 00000000..529bca15
--- /dev/null
+++ b/content/aspnetcore/src/CompanyName.ProjectName.Application/Jobs/TestJob.cs
@@ -0,0 +1,14 @@
+using Serilog;
+using System.Threading.Tasks;
+
+namespace CompanyNameProjectName.Jobs
+{
+ public class TestJob : IRecurringJob
+ {
+ public async Task ExecuteAsync()
+ {
+ await Task.CompletedTask;
+ Log.Information("TestJob");
+ }
+ }
+}
diff --git a/content/aspnetcore/src/CompanyName.ProjectName.Application/Properties/AssemblyInfo.cs b/content/aspnetcore/src/CompanyName.ProjectName.Application/Properties/AssemblyInfo.cs
new file mode 100644
index 00000000..b406fea5
--- /dev/null
+++ b/content/aspnetcore/src/CompanyName.ProjectName.Application/Properties/AssemblyInfo.cs
@@ -0,0 +1,2 @@
+using System.Runtime.CompilerServices;
+[assembly:InternalsVisibleToAttribute("CompanyNameProjectName.Application.Tests")]
diff --git a/content/aspnetcore/src/CompanyName.ProjectName.Application/Roles/RoleAppService.cs b/content/aspnetcore/src/CompanyName.ProjectName.Application/Roles/RoleAppService.cs
new file mode 100644
index 00000000..d8961712
--- /dev/null
+++ b/content/aspnetcore/src/CompanyName.ProjectName.Application/Roles/RoleAppService.cs
@@ -0,0 +1,86 @@
+using CompanyNameProjectName.Roles.Dtos;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Mvc;
+using Swashbuckle.AspNetCore.Annotations;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Volo.Abp.Application.Dtos;
+using Volo.Abp.Application.Services;
+using Volo.Abp.Identity;
+using Volo.Abp.PermissionManagement;
+
+namespace CompanyNameProjectName.Roles
+{
+ public class RoleAppService : ApplicationService
+ {
+ private readonly IIdentityRoleAppService _identityRoleAppService;
+ private readonly IPermissionAppService _permissionAppService;
+ protected IIdentityRoleRepository _roleRepository;
+ public RoleAppService(IIdentityRoleAppService identityRoleAppService, IPermissionAppService permissionAppService, IIdentityRoleRepository roleRepository)
+ {
+ _identityRoleAppService = identityRoleAppService;
+ _permissionAppService = permissionAppService;
+ _roleRepository = roleRepository;
+ }
+
+ [HttpPost]
+ [SwaggerOperation(summary: "获取所有角色", Tags = new[] { "Role" })]
+ public async Task> AllListAsync()
+ {
+ List source = await _roleRepository.GetListAsync().ConfigureAwait(continueOnCapturedContext: false);
+ return new ListResultDto(base.ObjectMapper.Map, List>(source));
+ //return await _identityRoleAppService.GetAllListAsync();
+ }
+
+ [HttpPost]
+ [SwaggerOperation(summary: "分页获取角色列表", Tags = new[] { "Role" })]
+ public async Task> ListAsync(GetRoleListInput input)
+ {
+ var request = new GetIdentityRolesInput();
+ request.Filter = input.filter?.Trim();
+ request.MaxResultCount = input.PageSize;
+ request.SkipCount = (input.pageIndex - 1) * input.PageSize;
+ return await _identityRoleAppService.GetListAsync(request);
+ }
+
+ [Authorize("AbpIdentity.Roles.Create")]
+ [HttpPost]
+ [SwaggerOperation(summary: "创建角色", Tags = new[] { "Role" })]
+ public async Task CreateAsync(IdentityRoleCreateDto input)
+ {
+ return await _identityRoleAppService.CreateAsync(input);
+ }
+
+ [Authorize("AbpIdentity.Roles.Update")]
+ [HttpPost]
+ [SwaggerOperation(summary: "更新角色", Tags = new[] { "Role" })]
+ public async Task UpdateAsync(UpdateRoleInput input)
+ {
+ return await _identityRoleAppService.UpdateAsync(input.RoleId, input.RoleInfo);
+ }
+
+ [Authorize("AbpIdentity.Roles.Delete")]
+ [SwaggerOperation(summary: "删除角色", Tags = new[] { "Role" })]
+ public async Task DeleteAsync(Guid id)
+ {
+ await _identityRoleAppService.DeleteAsync(id);
+ }
+
+ [SwaggerOperation(summary: "获取角色权限", Tags = new[] { "Role" })]
+ public async Task GetPermissionAsync(string providerName, string providerKey)
+ {
+ return await _permissionAppService.GetAsync(providerName, providerKey);
+ }
+
+ [SwaggerOperation(summary: "修改角色权限", Tags = new[] { "Role" })]
+ [HttpPost]
+ [Authorize("AbpIdentity.Roles.ManagePermissions")]
+ public async Task UpdatePermissionAsync(UpdateRolePermissionsDto input)
+ {
+ await _permissionAppService.UpdateAsync(input.ProviderName, input.ProviderKey, input.UpdatePermissionsDto);
+ }
+ }
+}
diff --git a/content/aspnetcore/src/CompanyName.ProjectName.Application/Users/LoginAppService.cs b/content/aspnetcore/src/CompanyName.ProjectName.Application/Users/LoginAppService.cs
new file mode 100644
index 00000000..a5fc3689
--- /dev/null
+++ b/content/aspnetcore/src/CompanyName.ProjectName.Application/Users/LoginAppService.cs
@@ -0,0 +1,97 @@
+using CompanyNameProjectName.Dtos.Users;
+using CompanyNameProjectName.Options;
+using IdentityModel;
+using Microsoft.Extensions.Options;
+using Microsoft.IdentityModel.Tokens;
+using Swashbuckle.AspNetCore.Annotations;
+using System;
+using System.Collections.Generic;
+using System.IdentityModel.Tokens.Jwt;
+using System.Linq;
+using System.Security.Claims;
+using System.Text;
+using System.Threading.Tasks;
+using Volo.Abp;
+using Volo.Abp.Application.Services;
+using Volo.Abp.Identity;
+
+namespace CompanyNameProjectName.Users
+{
+
+ public class LoginAppService : ApplicationService, ILoginAppService
+ {
+ private readonly IdentityUserManager _userManager;
+ private readonly JwtOptions _jwtOptions;
+ private readonly Microsoft.AspNetCore.Identity.SignInManager _signInManager;
+
+ public LoginAppService(
+ IdentityUserManager userManager,
+ IOptionsSnapshot jwtOptions,
+ Microsoft.AspNetCore.Identity.SignInManager signInManager)
+ {
+ _userManager = userManager;
+ _jwtOptions = jwtOptions.Value;
+ _signInManager = signInManager;
+ }
+
+
+ [SwaggerOperation(summary: "登录", Tags = new[] { "Login" })]
+ public async Task PostAsync(LoginInputDto input)
+ {
+ var result = await _signInManager.PasswordSignInAsync(input.Name, input.Password, false, true);
+ if (!result.Succeeded) throw new BusinessException("Login Faild");
+
+ var user = await _userManager.FindByNameAsync(input.Name);
+ if (user != null)
+ {
+
+ if (user == null) throw new BusinessException("Login Faild");
+ var roles = await _userManager.GetRolesAsync(user);
+ if (roles == null || roles.Count == 0) throw new BusinessException("Login Faild");
+ var token = GenerateJwt(user, roles.ToList());
+ var loginOutputDto = ObjectMapper.Map(user);
+ loginOutputDto.Token = token;
+ loginOutputDto.Expiration = DateTime.Now.AddHours(_jwtOptions.ExpirationTime);
+ return loginOutputDto;
+ }
+ throw new BusinessException("Login Faild");
+ }
+
+ ///
+ /// 生成jwt token
+ ///
+ ///
+ ///
+ ///
+ private string GenerateJwt(IdentityUser user, List roles)
+ {
+ var dateNow = DateTime.Now;
+ var expirationTime = dateNow + TimeSpan.FromHours(_jwtOptions.ExpirationTime);
+ var key = Encoding.ASCII.GetBytes(_jwtOptions.SecurityKey);
+
+ var claims = new List {
+ new Claim(JwtClaimTypes.Audience, _jwtOptions.Audience),
+ new Claim(JwtClaimTypes.Issuer, _jwtOptions.Issuer),
+ new Claim(JwtClaimTypes.Subject, user.Id.ToString()),
+ new Claim(JwtClaimTypes.Name, user.Name),
+ new Claim(JwtClaimTypes.Email, user.Email),
+ new Claim("TenantId", user.TenantId.ToString())
+ };
+
+ foreach (var item in roles)
+ {
+ claims.Add(new Claim(JwtClaimTypes.Role, item));
+ }
+ var tokenDescriptor = new SecurityTokenDescriptor()
+ {
+ Subject = new ClaimsIdentity(claims),
+ Expires = expirationTime,
+ SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256Signature)
+ };
+ var handler = new JwtSecurityTokenHandler();
+ var token = handler.CreateToken(tokenDescriptor);
+ return handler.WriteToken(token);
+
+ }
+ }
+}
diff --git a/content/aspnetcore/src/CompanyName.ProjectName.Application/Users/UserAppService.cs b/content/aspnetcore/src/CompanyName.ProjectName.Application/Users/UserAppService.cs
new file mode 100644
index 00000000..48f15312
--- /dev/null
+++ b/content/aspnetcore/src/CompanyName.ProjectName.Application/Users/UserAppService.cs
@@ -0,0 +1,69 @@
+using CompanyNameProjectName.Users.Dtos;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Mvc;
+using Swashbuckle.AspNetCore.Annotations;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Volo.Abp.Application.Dtos;
+using Volo.Abp.Application.Services;
+using Volo.Abp.Identity;
+
+namespace CompanyNameProjectName.Users
+{
+ public class UserAppService : ApplicationService
+ {
+ private readonly IIdentityUserAppService _identityUserAppService;
+
+ public UserAppService(IIdentityUserAppService identityUserAppService)
+ {
+ _identityUserAppService = identityUserAppService;
+ }
+
+ [SwaggerOperation(summary: "分页获取用户信息", Tags = new[] { "User" })]
+ [Authorize("AbpIdentity.Users")]
+ [HttpPost]
+ public async Task> ListAsync(GetUserListInput input)
+ {
+ var request = new GetIdentityUsersInput();
+ request.Filter = input.filter?.Trim();
+ request.MaxResultCount = input.PageSize;
+ request.SkipCount = (input.pageIndex - 1) * input.PageSize;
+ request.Sorting= " LastModificationTime desc";
+ return await _identityUserAppService.GetListAsync(request);
+ }
+
+ [SwaggerOperation(summary: "创建用户", Tags = new[] { "User" })]
+ [Authorize("AbpIdentity.Users.Create")]
+ [HttpPost]
+ public async Task CreateAsync(IdentityUserCreateDto input)
+ {
+ return await _identityUserAppService.CreateAsync(input);
+ }
+
+ [SwaggerOperation(summary: "更新用户", Tags = new[] { "User" })]
+ [Authorize("AbpIdentity.Users.Update")]
+ [HttpPost]
+ public virtual async Task UpdateAsync(UpdateUserInput input)
+ {
+ return await _identityUserAppService.UpdateAsync(input.UserId,input.UserInfo);
+ }
+
+ [SwaggerOperation(summary: "删除用户", Tags = new[] { "User" })]
+ [Authorize("AbpIdentity.Users.Delete")]
+ public virtual async Task DeleteAsync(Guid id)
+ {
+ await _identityUserAppService.DeleteAsync(id);
+ }
+
+ [SwaggerOperation(summary: "获取用户角色", Tags = new[] { "User" })]
+ [Authorize("AbpIdentity.Users")]
+ [HttpPost("/api/app/user/role/{userId}")]
+ public async Task> GetRoleByUserId(Guid userId)
+ {
+ return await _identityUserAppService.GetRolesAsync(userId);
+ }
+ }
+}
diff --git a/content/aspnetcore/src/CompanyName.ProjectName.Domain.Shared/CompanyName.ProjectName.Domain.Shared.csproj b/content/aspnetcore/src/CompanyName.ProjectName.Domain.Shared/CompanyName.ProjectName.Domain.Shared.csproj
new file mode 100644
index 00000000..a28bbfe5
--- /dev/null
+++ b/content/aspnetcore/src/CompanyName.ProjectName.Domain.Shared/CompanyName.ProjectName.Domain.Shared.csproj
@@ -0,0 +1,48 @@
+
+
+
+
+
+ netstandard2.1
+ CompanyNameProjectName
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/content/aspnetcore/src/CompanyName.ProjectName.Domain.Shared/CompanyNameProjectNameDomainErrorCodes.cs b/content/aspnetcore/src/CompanyName.ProjectName.Domain.Shared/CompanyNameProjectNameDomainErrorCodes.cs
new file mode 100644
index 00000000..0df0026c
--- /dev/null
+++ b/content/aspnetcore/src/CompanyName.ProjectName.Domain.Shared/CompanyNameProjectNameDomainErrorCodes.cs
@@ -0,0 +1,7 @@
+namespace CompanyNameProjectName
+{
+ public static class CompanyNameProjectNameDomainErrorCodes
+ {
+ /* You can add your business exception error codes here, as constants */
+ }
+}
diff --git a/content/aspnetcore/src/CompanyName.ProjectName.Domain.Shared/CompanyNameProjectNameDomainSharedModule.cs b/content/aspnetcore/src/CompanyName.ProjectName.Domain.Shared/CompanyNameProjectNameDomainSharedModule.cs
new file mode 100644
index 00000000..42946bab
--- /dev/null
+++ b/content/aspnetcore/src/CompanyName.ProjectName.Domain.Shared/CompanyNameProjectNameDomainSharedModule.cs
@@ -0,0 +1,62 @@
+using Volo.Abp.AuditLogging;
+using Volo.Abp.BackgroundJobs;
+using Volo.Abp.FeatureManagement;
+using Volo.Abp.Identity;
+using Volo.Abp.IdentityServer;
+using Volo.Abp.Localization;
+using Volo.Abp.Localization.ExceptionHandling;
+using Volo.Abp.Modularity;
+using Volo.Abp.PermissionManagement;
+using Volo.Abp.SettingManagement;
+using Volo.Abp.TenantManagement;
+using Volo.Abp.Validation.Localization;
+using Volo.Abp.VirtualFileSystem;
+using CompanyNameProjectName.Localization;
+
+namespace CompanyNameProjectName
+{
+ [DependsOn(
+ typeof(AbpAuditLoggingDomainSharedModule),
+ typeof(AbpBackgroundJobsDomainSharedModule),
+ typeof(AbpFeatureManagementDomainSharedModule),
+ typeof(AbpIdentityDomainSharedModule),
+ typeof(AbpIdentityServerDomainSharedModule),
+ typeof(AbpPermissionManagementDomainSharedModule),
+ typeof(AbpSettingManagementDomainSharedModule),
+ typeof(AbpTenantManagementDomainSharedModule),
+ typeof(EasyAbp.Abp.SettingUi.SettingUiDomainSharedModule)
+ )]
+ public class CompanyNameProjectNameDomainSharedModule : AbpModule
+ {
+ public override void PreConfigureServices(ServiceConfigurationContext context)
+ {
+ CompanyNameProjectNameGlobalFeatureConfigurator.Configure();
+ CompanyNameProjectNameModuleExtensionConfigurator.Configure();
+ }
+
+ public override void ConfigureServices(ServiceConfigurationContext context)
+ {
+ Configure(options =>
+ {
+ options.FileSets.AddEmbedded();
+ });
+
+
+ Configure(options =>
+ {
+ // 设置默认语言
+ options.Resources
+ .Add("zh-Hans")
+ .AddBaseTypes(typeof(AbpValidationResource))
+ .AddVirtualJson("/Localization/CompanyNameProjectName");
+
+ options.DefaultResourceType = typeof(CompanyNameProjectNameResource);
+ });
+
+ Configure(options =>
+ {
+ options.MapCodeNamespace("CompanyNameProjectName", typeof(CompanyNameProjectNameResource));
+ });
+ }
+ }
+}
diff --git a/content/aspnetcore/src/CompanyName.ProjectName.Domain.Shared/CompanyNameProjectNameGlobalFeatureConfigurator.cs b/content/aspnetcore/src/CompanyName.ProjectName.Domain.Shared/CompanyNameProjectNameGlobalFeatureConfigurator.cs
new file mode 100644
index 00000000..3fee0856
--- /dev/null
+++ b/content/aspnetcore/src/CompanyName.ProjectName.Domain.Shared/CompanyNameProjectNameGlobalFeatureConfigurator.cs
@@ -0,0 +1,23 @@
+using Volo.Abp.Threading;
+
+namespace CompanyNameProjectName
+{
+ public static class CompanyNameProjectNameGlobalFeatureConfigurator
+ {
+ private static readonly OneTimeRunner OneTimeRunner = new OneTimeRunner();
+
+ public static void Configure()
+ {
+ OneTimeRunner.Run(() =>
+ {
+ /* You can configure (enable/disable) global features of the used modules here.
+ *
+ * YOU CAN SAFELY DELETE THIS CLASS AND REMOVE ITS USAGES IF YOU DON'T NEED TO IT!
+ *
+ * Please refer to the documentation to lear more about the Global Features System:
+ * https://docs.abp.io/en/abp/latest/Global-Features
+ */
+ });
+ }
+ }
+}
diff --git a/content/aspnetcore/src/CompanyName.ProjectName.Domain.Shared/CompanyNameProjectNameModuleExtensionConfigurator.cs b/content/aspnetcore/src/CompanyName.ProjectName.Domain.Shared/CompanyNameProjectNameModuleExtensionConfigurator.cs
new file mode 100644
index 00000000..bcd89cd6
--- /dev/null
+++ b/content/aspnetcore/src/CompanyName.ProjectName.Domain.Shared/CompanyNameProjectNameModuleExtensionConfigurator.cs
@@ -0,0 +1,72 @@
+using System.ComponentModel.DataAnnotations;
+using Volo.Abp.Identity;
+using Volo.Abp.ObjectExtending;
+using Volo.Abp.Threading;
+
+namespace CompanyNameProjectName
+{
+ public static class CompanyNameProjectNameModuleExtensionConfigurator
+ {
+ private static readonly OneTimeRunner OneTimeRunner = new OneTimeRunner();
+
+ public static void Configure()
+ {
+ OneTimeRunner.Run(() =>
+ {
+ ConfigureExistingProperties();
+ ConfigureExtraProperties();
+ });
+ }
+
+ private static void ConfigureExistingProperties()
+ {
+ /* You can change max lengths for properties of the
+ * entities defined in the modules used by your application.
+ *
+ * Example: Change user and role name max lengths
+
+ IdentityUserConsts.MaxNameLength = 99;
+ IdentityRoleConsts.MaxNameLength = 99;
+
+ * Notice: It is not suggested to change property lengths
+ * unless you really need it. Go with the standard values wherever possible.
+ *
+ * If you are using EF Core, you will need to run the add-migration command after your changes.
+ */
+ }
+
+ private static void ConfigureExtraProperties()
+ {
+ /* You can configure extra properties for the
+ * entities defined in the modules used by your application.
+ *
+ * This class can be used to define these extra properties
+ * with a high level, easy to use API.
+ *
+ * Example: Add a new property to the user entity of the identity module
+
+ ObjectExtensionManager.Instance.Modules()
+ .ConfigureIdentity(identity =>
+ {
+ identity.ConfigureUser(user =>
+ {
+ user.AddOrUpdateProperty( //property type: string
+ "SocialSecurityNumber", //property name
+ property =>
+ {
+ //validation rules
+ property.Attributes.Add(new RequiredAttribute());
+ property.Attributes.Add(new StringLengthAttribute(64) {MinimumLength = 4});
+
+ //...other configurations for this property
+ }
+ );
+ });
+ });
+
+ * See the documentation for more:
+ * https://docs.abp.io/en/latest/Module-Entity-Extensions
+ */
+ }
+ }
+}
diff --git a/content/aspnetcore/src/CompanyName.ProjectName.Domain.Shared/Localization/CompanyNameProjectName/en.json b/content/aspnetcore/src/CompanyName.ProjectName.Domain.Shared/Localization/CompanyNameProjectName/en.json
new file mode 100644
index 00000000..f4104af3
--- /dev/null
+++ b/content/aspnetcore/src/CompanyName.ProjectName.Domain.Shared/Localization/CompanyNameProjectName/en.json
@@ -0,0 +1,11 @@
+{
+ "culture": "en",
+ "texts": {
+ "Menu:Home": "Home",
+ "Welcome": "Welcome",
+ "LongWelcomeMessage": "Welcome to the application. This is a startup project based on the ABP framework. For more information, visit abp.io.",
+ "DataExistence": "Existence",
+ "DataNotExistence": "Not Existence",
+ "TestSettings": "TestSettings"
+ }
+}
diff --git a/content/aspnetcore/src/CompanyName.ProjectName.Domain.Shared/Localization/CompanyNameProjectName/zh-Hans.json b/content/aspnetcore/src/CompanyName.ProjectName.Domain.Shared/Localization/CompanyNameProjectName/zh-Hans.json
new file mode 100644
index 00000000..38b71c33
--- /dev/null
+++ b/content/aspnetcore/src/CompanyName.ProjectName.Domain.Shared/Localization/CompanyNameProjectName/zh-Hans.json
@@ -0,0 +1,12 @@
+{
+ "culture": "zh-Hans",
+ "texts": {
+ "Menu:Home": "首页",
+ "Welcome": "欢迎",
+ "LongWelcomeMessage": "欢迎来到该应用程序. 这是一个基于ABP框架的启动项目. 有关更多信息, 请访问 abp.io.",
+ "DataExistence": "已存在",
+ "DataNotExistence": "不存在",
+ "Permission:Query": "查询",
+ "TestSettings": "测试Settings"
+ }
+}
\ No newline at end of file
diff --git a/content/aspnetcore/src/CompanyName.ProjectName.Domain.Shared/Localization/CompanyNameProjectNameResource.cs b/content/aspnetcore/src/CompanyName.ProjectName.Domain.Shared/Localization/CompanyNameProjectNameResource.cs
new file mode 100644
index 00000000..40bb1f6f
--- /dev/null
+++ b/content/aspnetcore/src/CompanyName.ProjectName.Domain.Shared/Localization/CompanyNameProjectNameResource.cs
@@ -0,0 +1,10 @@
+using Volo.Abp.Localization;
+
+namespace CompanyNameProjectName.Localization
+{
+ [LocalizationResourceName("CompanyNameProjectName")]
+ public class CompanyNameProjectNameResource
+ {
+
+ }
+}
\ No newline at end of file
diff --git a/content/aspnetcore/src/CompanyName.ProjectName.Domain.Shared/MultiTenancy/MultiTenancyConsts.cs b/content/aspnetcore/src/CompanyName.ProjectName.Domain.Shared/MultiTenancy/MultiTenancyConsts.cs
new file mode 100644
index 00000000..8dee5ec9
--- /dev/null
+++ b/content/aspnetcore/src/CompanyName.ProjectName.Domain.Shared/MultiTenancy/MultiTenancyConsts.cs
@@ -0,0 +1,11 @@
+namespace CompanyNameProjectName.MultiTenancy
+{
+ public static class MultiTenancyConsts
+ {
+ /* Enable/disable multi-tenancy easily in a single point.
+ * If you will never need to multi-tenancy, you can remove
+ * related modules and code parts, including this file.
+ */
+ public const bool IsEnabled = false;
+ }
+}
diff --git a/content/aspnetcore/src/CompanyName.ProjectName.Domain/CompanyName.ProjectName.Domain.csproj b/content/aspnetcore/src/CompanyName.ProjectName.Domain/CompanyName.ProjectName.Domain.csproj
new file mode 100644
index 00000000..c20c6ec7
--- /dev/null
+++ b/content/aspnetcore/src/CompanyName.ProjectName.Domain/CompanyName.ProjectName.Domain.csproj
@@ -0,0 +1,33 @@
+
+
+
+
+
+ net5.0
+ CompanyNameProjectName
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/content/aspnetcore/src/CompanyName.ProjectName.Domain/CompanyNameProjectNameConsts.cs b/content/aspnetcore/src/CompanyName.ProjectName.Domain/CompanyNameProjectNameConsts.cs
new file mode 100644
index 00000000..7619949b
--- /dev/null
+++ b/content/aspnetcore/src/CompanyName.ProjectName.Domain/CompanyNameProjectNameConsts.cs
@@ -0,0 +1,11 @@
+namespace CompanyNameProjectName
+{
+ public static class CompanyNameProjectNameConsts
+ {
+ public const string DbTablePrefix = "App";
+
+ public const string DbSchema = null;
+
+ public const string CompanyNameProjectNameDbTablePrefix = "CompanyNameProjectName";
+ }
+}
diff --git a/content/aspnetcore/src/CompanyName.ProjectName.Domain/CompanyNameProjectNameDomainModule.cs b/content/aspnetcore/src/CompanyName.ProjectName.Domain/CompanyNameProjectNameDomainModule.cs
new file mode 100644
index 00000000..bef2be23
--- /dev/null
+++ b/content/aspnetcore/src/CompanyName.ProjectName.Domain/CompanyNameProjectNameDomainModule.cs
@@ -0,0 +1,49 @@
+using Microsoft.Extensions.Caching.Distributed;
+using System;
+using Volo.Abp.AuditLogging;
+using Volo.Abp.BackgroundJobs;
+using Volo.Abp.Caching;
+using Volo.Abp.FeatureManagement;
+using Volo.Abp.Identity;
+using Volo.Abp.IdentityServer;
+using Volo.Abp.Modularity;
+using Volo.Abp.MultiTenancy;
+using Volo.Abp.PermissionManagement.Identity;
+using Volo.Abp.PermissionManagement.IdentityServer;
+using Volo.Abp.SettingManagement;
+using Volo.Abp.TenantManagement;
+using CompanyNameProjectName.MultiTenancy;
+
+namespace CompanyNameProjectName
+{
+ [DependsOn(
+ typeof(CompanyNameProjectNameDomainSharedModule),
+ typeof(AbpAuditLoggingDomainModule),
+ typeof(AbpBackgroundJobsDomainModule),
+ typeof(AbpFeatureManagementDomainModule),
+ typeof(AbpIdentityDomainModule),
+ typeof(AbpPermissionManagementDomainIdentityModule),
+ typeof(AbpIdentityServerDomainModule),
+ typeof(AbpPermissionManagementDomainIdentityServerModule),
+ typeof(AbpSettingManagementDomainModule),
+ typeof(AbpTenantManagementDomainModule),
+ typeof(EasyAbp.Abp.SettingUi.SettingUiDomainModule),
+ typeof(AbpCachingModule)
+ )]
+ public class CompanyNameProjectNameDomainModule : AbpModule
+ {
+ public override void ConfigureServices(ServiceConfigurationContext context)
+ {
+ Configure(options =>
+ {
+ options.IsEnabled = MultiTenancyConsts.IsEnabled;
+ });
+
+ // 设置全局默认缓存时间
+ //Configure(option =>
+ //{
+ // option.GlobalCacheEntryOptions.SetSlidingExpiration(TimeSpan.FromSeconds(7200));
+ //});
+ }
+ }
+}
diff --git a/content/aspnetcore/src/CompanyName.ProjectName.Domain/Data/CompanyNameProjectNameDbMigrationService.cs b/content/aspnetcore/src/CompanyName.ProjectName.Domain/Data/CompanyNameProjectNameDbMigrationService.cs
new file mode 100644
index 00000000..8e19c277
--- /dev/null
+++ b/content/aspnetcore/src/CompanyName.ProjectName.Domain/Data/CompanyNameProjectNameDbMigrationService.cs
@@ -0,0 +1,93 @@
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using Microsoft.Extensions.Logging;
+using Microsoft.Extensions.Logging.Abstractions;
+using Volo.Abp.Data;
+using Volo.Abp.DependencyInjection;
+using Volo.Abp.MultiTenancy;
+using Volo.Abp.TenantManagement;
+
+namespace CompanyNameProjectName.Data
+{
+ public class CompanyNameProjectNameDbMigrationService : ITransientDependency
+ {
+ public ILogger Logger { get; set; }
+
+ private readonly IDataSeeder _dataSeeder;
+ private readonly IEnumerable _dbSchemaMigrators;
+ private readonly ITenantRepository _tenantRepository;
+ private readonly ICurrentTenant _currentTenant;
+
+ public CompanyNameProjectNameDbMigrationService(
+ IDataSeeder dataSeeder,
+ IEnumerable dbSchemaMigrators,
+ ITenantRepository tenantRepository,
+ ICurrentTenant currentTenant)
+ {
+ _dataSeeder = dataSeeder;
+ _dbSchemaMigrators = dbSchemaMigrators;
+ _tenantRepository = tenantRepository;
+ _currentTenant = currentTenant;
+
+ Logger = NullLogger.Instance;
+ }
+
+ public async Task MigrateAsync()
+ {
+ Logger.LogInformation("Started database migrations...");
+
+ await MigrateDatabaseSchemaAsync();
+ await SeedDataAsync();
+
+ Logger.LogInformation($"Successfully completed host database migrations.");
+
+ var tenants = await _tenantRepository.GetListAsync(includeDetails: true);
+
+ var migratedDatabaseSchemas = new HashSet();
+ foreach (var tenant in tenants)
+ {
+ using (_currentTenant.Change(tenant.Id))
+ {
+ if (tenant.ConnectionStrings.Any())
+ {
+ var tenantConnectionStrings = tenant.ConnectionStrings
+ .Select(x => x.Value)
+ .ToList();
+
+ if (!migratedDatabaseSchemas.IsSupersetOf(tenantConnectionStrings))
+ {
+ await MigrateDatabaseSchemaAsync(tenant);
+
+ migratedDatabaseSchemas.AddIfNotContains(tenantConnectionStrings);
+ }
+ }
+
+ await SeedDataAsync(tenant);
+ }
+
+ Logger.LogInformation($"Successfully completed {tenant.Name} tenant database migrations.");
+ }
+
+ Logger.LogInformation("Successfully completed database migrations.");
+ }
+
+ private async Task MigrateDatabaseSchemaAsync(Tenant tenant = null)
+ {
+ Logger.LogInformation(
+ $"Migrating schema for {(tenant == null ? "host" : tenant.Name + " tenant")} database...");
+
+ foreach (var migrator in _dbSchemaMigrators)
+ {
+ await migrator.MigrateAsync();
+ }
+ }
+
+ private async Task SeedDataAsync(Tenant tenant = null)
+ {
+ Logger.LogInformation($"Executing {(tenant == null ? "host" : tenant.Name + " tenant")} database seed...");
+
+ await _dataSeeder.SeedAsync(tenant?.Id);
+ }
+ }
+}
diff --git a/content/aspnetcore/src/CompanyName.ProjectName.Domain/Data/ICompanyNameProjectNameDbSchemaMigrator.cs b/content/aspnetcore/src/CompanyName.ProjectName.Domain/Data/ICompanyNameProjectNameDbSchemaMigrator.cs
new file mode 100644
index 00000000..0c3707a3
--- /dev/null
+++ b/content/aspnetcore/src/CompanyName.ProjectName.Domain/Data/ICompanyNameProjectNameDbSchemaMigrator.cs
@@ -0,0 +1,9 @@
+using System.Threading.Tasks;
+
+namespace CompanyNameProjectName.Data
+{
+ public interface ICompanyNameProjectNameDbSchemaMigrator
+ {
+ Task MigrateAsync();
+ }
+}
diff --git a/content/aspnetcore/src/CompanyName.ProjectName.Domain/Data/NullCompanyNameProjectNameDbSchemaMigrator.cs b/content/aspnetcore/src/CompanyName.ProjectName.Domain/Data/NullCompanyNameProjectNameDbSchemaMigrator.cs
new file mode 100644
index 00000000..b565ff34
--- /dev/null
+++ b/content/aspnetcore/src/CompanyName.ProjectName.Domain/Data/NullCompanyNameProjectNameDbSchemaMigrator.cs
@@ -0,0 +1,16 @@
+using System.Threading.Tasks;
+using Volo.Abp.DependencyInjection;
+
+namespace CompanyNameProjectName.Data
+{
+ /* This is used if database provider does't define
+ * ICompanyNameProjectNameDbSchemaMigrator implementation.
+ */
+ public class NullCompanyNameProjectNameDbSchemaMigrator : ICompanyNameProjectNameDbSchemaMigrator, ITransientDependency
+ {
+ public Task MigrateAsync()
+ {
+ return Task.CompletedTask;
+ }
+ }
+}
\ No newline at end of file
diff --git a/content/aspnetcore/src/CompanyName.ProjectName.Domain/Properties/AssemblyInfo.cs b/content/aspnetcore/src/CompanyName.ProjectName.Domain/Properties/AssemblyInfo.cs
new file mode 100644
index 00000000..799212d5
--- /dev/null
+++ b/content/aspnetcore/src/CompanyName.ProjectName.Domain/Properties/AssemblyInfo.cs
@@ -0,0 +1,3 @@
+using System.Runtime.CompilerServices;
+[assembly:InternalsVisibleToAttribute("CompanyNameProjectName.Domain.Tests")]
+[assembly:InternalsVisibleToAttribute("CompanyNameProjectName.TestBase")]
diff --git a/content/aspnetcore/src/CompanyName.ProjectName.Domain/Settings/CompanyNameProjectNameSettingDefinitionProvider.cs b/content/aspnetcore/src/CompanyName.ProjectName.Domain/Settings/CompanyNameProjectNameSettingDefinitionProvider.cs
new file mode 100644
index 00000000..b79d7e94
--- /dev/null
+++ b/content/aspnetcore/src/CompanyName.ProjectName.Domain/Settings/CompanyNameProjectNameSettingDefinitionProvider.cs
@@ -0,0 +1,32 @@
+
+using Volo.Abp.Localization;
+using Volo.Abp.Settings;
+using CompanyNameProjectName.Localization;
+
+namespace CompanyNameProjectName.Settings
+{
+ public class CompanyNameProjectNameSettingDefinitionProvider : SettingDefinitionProvider
+ {
+
+
+ public override void Define(ISettingDefinitionContext context)
+ {
+ //Define your own settings here. Example:
+ //context.Add(new SettingDefinition(CompanyNameProjectNameSettings.MySetting1));
+ context.Add(
+ new SettingDefinition(
+ name:"测试",
+ defaultValue:"test",
+ displayName: L("TestSettings")
+ ).WithProviders(
+ DefaultValueSettingValueProvider.ProviderName,
+ GlobalSettingValueProvider.ProviderName)
+ );;
+ }
+
+ private static LocalizableString L(string name)
+ {
+ return LocalizableString.Create(name);
+ }
+ }
+}
diff --git a/content/aspnetcore/src/CompanyName.ProjectName.Domain/Settings/CompanyNameProjectNameSettings.cs b/content/aspnetcore/src/CompanyName.ProjectName.Domain/Settings/CompanyNameProjectNameSettings.cs
new file mode 100644
index 00000000..b05a939f
--- /dev/null
+++ b/content/aspnetcore/src/CompanyName.ProjectName.Domain/Settings/CompanyNameProjectNameSettings.cs
@@ -0,0 +1,10 @@
+namespace CompanyNameProjectName.Settings
+{
+ public static class CompanyNameProjectNameSettings
+ {
+ private const string Prefix = "CompanyNameProjectName";
+
+ //Add your own setting names here. Example:
+ //public const string MySetting1 = Prefix + ".MySetting1";
+ }
+}
\ No newline at end of file
diff --git a/content/aspnetcore/src/CompanyName.ProjectName.Domain/Users/Aggregates/AppUser.cs b/content/aspnetcore/src/CompanyName.ProjectName.Domain/Users/Aggregates/AppUser.cs
new file mode 100644
index 00000000..d0a9d527
--- /dev/null
+++ b/content/aspnetcore/src/CompanyName.ProjectName.Domain/Users/Aggregates/AppUser.cs
@@ -0,0 +1,63 @@
+using System;
+using Volo.Abp.Domain.Entities.Auditing;
+using Volo.Abp.Users;
+
+namespace CompanyNameProjectName.Users
+{
+ /* This entity shares the same table/collection ("AbpUsers" by default) with the
+ * IdentityUser entity of the Identity module.
+ *
+ * - You can define your custom properties into this class.
+ * - You never create or delete this entity, because it is Identity module's job.
+ * - You can query users from database with this entity.
+ * - You can update values of your custom properties.
+ */
+ public class AppUser : FullAuditedAggregateRoot, IUser
+ {
+ #region Base properties
+
+ /* These properties are shared with the IdentityUser entity of the Identity module.
+ * Do not change these properties through this class. Instead, use Identity module
+ * services (like IdentityUserManager) to change them.
+ * So, this properties are designed as read only!
+ */
+
+ public virtual Guid? TenantId { get; private set; }
+
+ public virtual string UserName { get; private set; }
+
+ public virtual string Name { get; private set; }
+
+ public virtual string Surname { get; private set; }
+
+ public virtual string Email { get; private set; }
+
+ public virtual bool EmailConfirmed { get; private set; }
+
+ public virtual string PhoneNumber { get; private set; }
+
+ public virtual bool PhoneNumberConfirmed { get; private set; }
+
+ #endregion
+
+ /* Add your own properties here. Example:
+ *
+ * public string MyProperty { get; set; }
+ *
+ * If you add a property and using the EF Core, remember these;
+ *
+ * 1. Update CompanyNameProjectNameDbContext.OnModelCreating
+ * to configure the mapping for your new property
+ * 2. Update CompanyNameProjectNameEfCoreEntityExtensionMappings to extend the IdentityUser entity
+ * and add your new property to the migration.
+ * 3. Use the Add-Migration to add a new database migration.
+ * 4. Run the .DbMigrator project (or use the Update-Database command) to apply
+ * schema change to the database.
+ */
+
+ private AppUser()
+ {
+
+ }
+ }
+}
diff --git a/content/aspnetcore/src/CompanyName.ProjectName.EntityFrameworkCore.DbMigrations/CompanyName.ProjectName.EntityFrameworkCore.DbMigrations.csproj b/content/aspnetcore/src/CompanyName.ProjectName.EntityFrameworkCore.DbMigrations/CompanyName.ProjectName.EntityFrameworkCore.DbMigrations.csproj
new file mode 100644
index 00000000..ff519185
--- /dev/null
+++ b/content/aspnetcore/src/CompanyName.ProjectName.EntityFrameworkCore.DbMigrations/CompanyName.ProjectName.EntityFrameworkCore.DbMigrations.csproj
@@ -0,0 +1,22 @@
+
+
+
+
+
+ net5.0
+ CompanyNameProjectName
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/content/aspnetcore/src/CompanyName.ProjectName.EntityFrameworkCore.DbMigrations/EntityFrameworkCore/CompanyNameProjectNameEntityFrameworkCoreDbMigrationsModule.cs b/content/aspnetcore/src/CompanyName.ProjectName.EntityFrameworkCore.DbMigrations/EntityFrameworkCore/CompanyNameProjectNameEntityFrameworkCoreDbMigrationsModule.cs
new file mode 100644
index 00000000..06e809b3
--- /dev/null
+++ b/content/aspnetcore/src/CompanyName.ProjectName.EntityFrameworkCore.DbMigrations/EntityFrameworkCore/CompanyNameProjectNameEntityFrameworkCoreDbMigrationsModule.cs
@@ -0,0 +1,16 @@
+using Microsoft.Extensions.DependencyInjection;
+using Volo.Abp.Modularity;
+
+namespace CompanyNameProjectName.EntityFrameworkCore
+{
+ [DependsOn(
+ typeof(CompanyNameProjectNameEntityFrameworkCoreModule)
+ )]
+ public class CompanyNameProjectNameEntityFrameworkCoreDbMigrationsModule : AbpModule
+ {
+ public override void ConfigureServices(ServiceConfigurationContext context)
+ {
+ context.Services.AddAbpDbContext();
+ }
+ }
+}
diff --git a/content/aspnetcore/src/CompanyName.ProjectName.EntityFrameworkCore.DbMigrations/EntityFrameworkCore/CompanyNameProjectNameMigrationsDbContext.cs b/content/aspnetcore/src/CompanyName.ProjectName.EntityFrameworkCore.DbMigrations/EntityFrameworkCore/CompanyNameProjectNameMigrationsDbContext.cs
new file mode 100644
index 00000000..27c5292d
--- /dev/null
+++ b/content/aspnetcore/src/CompanyName.ProjectName.EntityFrameworkCore.DbMigrations/EntityFrameworkCore/CompanyNameProjectNameMigrationsDbContext.cs
@@ -0,0 +1,46 @@
+using Microsoft.EntityFrameworkCore;
+using Volo.Abp.AuditLogging.EntityFrameworkCore;
+using Volo.Abp.BackgroundJobs.EntityFrameworkCore;
+using Volo.Abp.EntityFrameworkCore;
+using Volo.Abp.FeatureManagement.EntityFrameworkCore;
+using Volo.Abp.Identity.EntityFrameworkCore;
+using Volo.Abp.PermissionManagement.EntityFrameworkCore;
+using Volo.Abp.SettingManagement.EntityFrameworkCore;
+using Volo.Abp.TenantManagement.EntityFrameworkCore;
+
+namespace CompanyNameProjectName.EntityFrameworkCore
+{
+ /* This DbContext is only used for database migrations.
+ * It is not used on runtime. See CompanyNameProjectNameDbContext for the runtime DbContext.
+ * It is a unified model that includes configuration for
+ * all used modules and your application.
+ */
+ public class CompanyNameProjectNameMigrationsDbContext : AbpDbContext
+ {
+ public CompanyNameProjectNameMigrationsDbContext(DbContextOptions options)
+ : base(options)
+ {
+
+ }
+
+ protected override void OnModelCreating(ModelBuilder builder)
+ {
+ base.OnModelCreating(builder);
+
+ /* Include modules to your migration db context */
+
+ builder.ConfigurePermissionManagement();
+ builder.ConfigureSettingManagement();
+ builder.ConfigureBackgroundJobs();
+ builder.ConfigureAuditLogging();
+ builder.ConfigureIdentity();
+ //builder.ConfigureIdentityServer();
+ builder.ConfigureFeatureManagement();
+ builder.ConfigureTenantManagement();
+
+ /* Configure your own tables/entities inside the ConfigureCompanyNameProjectName method */
+
+ builder.ConfigureCompanyNameProjectName();
+ }
+ }
+}
\ No newline at end of file
diff --git a/content/aspnetcore/src/CompanyName.ProjectName.EntityFrameworkCore.DbMigrations/EntityFrameworkCore/CompanyNameProjectNameMigrationsDbContextFactory.cs b/content/aspnetcore/src/CompanyName.ProjectName.EntityFrameworkCore.DbMigrations/EntityFrameworkCore/CompanyNameProjectNameMigrationsDbContextFactory.cs
new file mode 100644
index 00000000..63d109d6
--- /dev/null
+++ b/content/aspnetcore/src/CompanyName.ProjectName.EntityFrameworkCore.DbMigrations/EntityFrameworkCore/CompanyNameProjectNameMigrationsDbContextFactory.cs
@@ -0,0 +1,49 @@
+using System;
+using System.IO;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Design;
+using Microsoft.Extensions.Configuration;
+using Pomelo.EntityFrameworkCore.MySql.Infrastructure;
+
+namespace CompanyNameProjectName.EntityFrameworkCore
+{
+ /* This class is needed for EF Core console commands
+ * (like Add-Migration and Update-Database commands) */
+ public class CompanyNameProjectNameMigrationsDbContextFactory : IDesignTimeDbContextFactory
+ {
+ public CompanyNameProjectNameMigrationsDbContext CreateDbContext(string[] args)
+ {
+ CompanyNameProjectNameEfCoreEntityExtensionMappings.Configure();
+
+ var configuration = BuildConfiguration();
+
+ //var builder = new DbContextOptionsBuilder()
+ // .UseSqlServer(configuration.GetConnectionString("Default"));
+ var builder = new DbContextOptionsBuilder()
+ .UseMySql(configuration.GetConnectionString("Default"), new MySqlServerVersion(new Version(5, 7)), mySqlOptions => mySqlOptions
+ .CharSetBehavior(CharSetBehavior.NeverAppend));
+
+ return new CompanyNameProjectNameMigrationsDbContext(builder.Options);
+ }
+
+ //private static IConfigurationRoot BuildConfiguration()
+ //{
+ // var builder = new ConfigurationBuilder()
+ // .SetBasePath(Path.Combine(Directory.GetCurrentDirectory(), "../CompanyNameProjectName.DbMigrator/"))
+ // .AddJsonFile("appsettings.json", optional: false);
+
+ // return builder.Build();
+ //}
+
+ private static IConfigurationRoot BuildConfiguration()
+ {
+ var path = Directory.GetParent(Directory.GetParent(Directory.GetCurrentDirectory()).FullName).FullName;
+ var builder = new ConfigurationBuilder()
+ .SetBasePath(Path.Combine(path, "tools", "CompanyName.ProjectName.DbMigrator"))
+ .AddJsonFile("appsettings.json", optional: true)
+ .AddEnvironmentVariables();
+ return builder.Build();
+ }
+
+ }
+}
diff --git a/content/aspnetcore/src/CompanyName.ProjectName.EntityFrameworkCore.DbMigrations/EntityFrameworkCore/EntityFrameworkCoreCompanyNameProjectNameDbSchemaMigrator.cs b/content/aspnetcore/src/CompanyName.ProjectName.EntityFrameworkCore.DbMigrations/EntityFrameworkCore/EntityFrameworkCoreCompanyNameProjectNameDbSchemaMigrator.cs
new file mode 100644
index 00000000..d6a41459
--- /dev/null
+++ b/content/aspnetcore/src/CompanyName.ProjectName.EntityFrameworkCore.DbMigrations/EntityFrameworkCore/EntityFrameworkCoreCompanyNameProjectNameDbSchemaMigrator.cs
@@ -0,0 +1,35 @@
+using System;
+using System.Threading.Tasks;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.Extensions.DependencyInjection;
+using CompanyNameProjectName.Data;
+using Volo.Abp.DependencyInjection;
+
+namespace CompanyNameProjectName.EntityFrameworkCore
+{
+ public class EntityFrameworkCoreCompanyNameProjectNameDbSchemaMigrator
+ : ICompanyNameProjectNameDbSchemaMigrator, ITransientDependency
+ {
+ private readonly IServiceProvider _serviceProvider;
+
+ public EntityFrameworkCoreCompanyNameProjectNameDbSchemaMigrator(
+ IServiceProvider serviceProvider)
+ {
+ _serviceProvider = serviceProvider;
+ }
+
+ public async Task MigrateAsync()
+ {
+ /* We intentionally resolving the CompanyNameProjectNameMigrationsDbContext
+ * from IServiceProvider (instead of directly injecting it)
+ * to properly get the connection string of the current tenant in the
+ * current scope.
+ */
+
+ await _serviceProvider
+ .GetRequiredService()
+ .Database
+ .MigrateAsync();
+ }
+ }
+}
\ No newline at end of file
diff --git a/content/aspnetcore/src/CompanyName.ProjectName.EntityFrameworkCore.DbMigrations/Migrations/20210417141408_Init.Designer.cs b/content/aspnetcore/src/CompanyName.ProjectName.EntityFrameworkCore.DbMigrations/Migrations/20210417141408_Init.Designer.cs
new file mode 100644
index 00000000..f1a12228
--- /dev/null
+++ b/content/aspnetcore/src/CompanyName.ProjectName.EntityFrameworkCore.DbMigrations/Migrations/20210417141408_Init.Designer.cs
@@ -0,0 +1,1277 @@
+//
+using System;
+using CompanyNameProjectName.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Migrations;
+using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
+using Volo.Abp.EntityFrameworkCore;
+
+namespace CompanyNameProjectName.Migrations
+{
+ [DbContext(typeof(CompanyNameProjectNameMigrationsDbContext))]
+ [Migration("20210417141408_Init")]
+ partial class Init
+ {
+ protected override void BuildTargetModel(ModelBuilder modelBuilder)
+ {
+#pragma warning disable 612, 618
+ modelBuilder
+ .HasAnnotation("_Abp_DatabaseProvider", EfCoreDatabaseProvider.MySql)
+ .HasAnnotation("Relational:MaxIdentifierLength", 64)
+ .HasAnnotation("ProductVersion", "5.0.5");
+
+ modelBuilder.Entity("Volo.Abp.AuditLogging.AuditLog", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("char(36)");
+
+ b.Property("ApplicationName")
+ .HasMaxLength(96)
+ .HasColumnType("varchar(96)")
+ .HasColumnName("ApplicationName");
+
+ b.Property("BrowserInfo")
+ .HasMaxLength(512)
+ .HasColumnType("varchar(512)")
+ .HasColumnName("BrowserInfo");
+
+ b.Property("ClientId")
+ .HasMaxLength(64)
+ .HasColumnType("varchar(64)")
+ .HasColumnName("ClientId");
+
+ b.Property("ClientIpAddress")
+ .HasMaxLength(64)
+ .HasColumnType("varchar(64)")
+ .HasColumnName("ClientIpAddress");
+
+ b.Property("ClientName")
+ .HasMaxLength(128)
+ .HasColumnType("varchar(128)")
+ .HasColumnName("ClientName");
+
+ b.Property("Comments")
+ .HasMaxLength(256)
+ .HasColumnType("varchar(256)")
+ .HasColumnName("Comments");
+
+ b.Property("ConcurrencyStamp")
+ .IsConcurrencyToken()
+ .HasMaxLength(40)
+ .HasColumnType("varchar(40)")
+ .HasColumnName("ConcurrencyStamp");
+
+ b.Property("CorrelationId")
+ .HasMaxLength(64)
+ .HasColumnType("varchar(64)")
+ .HasColumnName("CorrelationId");
+
+ b.Property("Exceptions")
+ .HasMaxLength(4000)
+ .HasColumnType("longtext")
+ .HasColumnName("Exceptions");
+
+ b.Property("ExecutionDuration")
+ .HasColumnType("int")
+ .HasColumnName("ExecutionDuration");
+
+ b.Property("ExecutionTime")
+ .HasColumnType("datetime(6)");
+
+ b.Property("ExtraProperties")
+ .HasColumnType("longtext")
+ .HasColumnName("ExtraProperties");
+
+ b.Property("HttpMethod")
+ .HasMaxLength(16)
+ .HasColumnType("varchar(16)")
+ .HasColumnName("HttpMethod");
+
+ b.Property("HttpStatusCode")
+ .HasColumnType("int")
+ .HasColumnName("HttpStatusCode");
+
+ b.Property("ImpersonatorTenantId")
+ .HasColumnType("char(36)")
+ .HasColumnName("ImpersonatorTenantId");
+
+ b.Property("ImpersonatorUserId")
+ .HasColumnType("char(36)")
+ .HasColumnName("ImpersonatorUserId");
+
+ b.Property("TenantId")
+ .HasColumnType("char(36)")
+ .HasColumnName("TenantId");
+
+ b.Property("TenantName")
+ .HasColumnType("longtext");
+
+ b.Property("Url")
+ .HasMaxLength(256)
+ .HasColumnType("varchar(256)")
+ .HasColumnName("Url");
+
+ b.Property("UserId")
+ .HasColumnType("char(36)")
+ .HasColumnName("UserId");
+
+ b.Property("UserName")
+ .HasMaxLength(256)
+ .HasColumnType("varchar(256)")
+ .HasColumnName("UserName");
+
+ b.HasKey("Id");
+
+ b.HasIndex("TenantId", "ExecutionTime");
+
+ b.HasIndex("TenantId", "UserId", "ExecutionTime");
+
+ b.ToTable("AbpAuditLogs");
+ });
+
+ modelBuilder.Entity("Volo.Abp.AuditLogging.AuditLogAction", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("char(36)");
+
+ b.Property("AuditLogId")
+ .HasColumnType("char(36)")
+ .HasColumnName("AuditLogId");
+
+ b.Property("ExecutionDuration")
+ .HasColumnType("int")
+ .HasColumnName("ExecutionDuration");
+
+ b.Property("ExecutionTime")
+ .HasColumnType("datetime(6)")
+ .HasColumnName("ExecutionTime");
+
+ b.Property("ExtraProperties")
+ .HasColumnType("longtext")
+ .HasColumnName("ExtraProperties");
+
+ b.Property("MethodName")
+ .HasMaxLength(128)
+ .HasColumnType("varchar(128)")
+ .HasColumnName("MethodName");
+
+ b.Property("Parameters")
+ .HasMaxLength(2000)
+ .HasColumnType("varchar(2000)")
+ .HasColumnName("Parameters");
+
+ b.Property("ServiceName")
+ .HasMaxLength(256)
+ .HasColumnType("varchar(256)")
+ .HasColumnName("ServiceName");
+
+ b.Property("TenantId")
+ .HasColumnType("char(36)")
+ .HasColumnName("TenantId");
+
+ b.HasKey("Id");
+
+ b.HasIndex("AuditLogId");
+
+ b.HasIndex("TenantId", "ServiceName", "MethodName", "ExecutionTime");
+
+ b.ToTable("AbpAuditLogActions");
+ });
+
+ modelBuilder.Entity("Volo.Abp.AuditLogging.EntityChange", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("char(36)");
+
+ b.Property("AuditLogId")
+ .HasColumnType("char(36)")
+ .HasColumnName("AuditLogId");
+
+ b.Property("ChangeTime")
+ .HasColumnType("datetime(6)")
+ .HasColumnName("ChangeTime");
+
+ b.Property("ChangeType")
+ .HasColumnType("tinyint unsigned")
+ .HasColumnName("ChangeType");
+
+ b.Property("EntityId")
+ .IsRequired()
+ .HasMaxLength(128)
+ .HasColumnType("varchar(128)")
+ .HasColumnName("EntityId");
+
+ b.Property("EntityTenantId")
+ .HasColumnType("char(36)");
+
+ b.Property("EntityTypeFullName")
+ .IsRequired()
+ .HasMaxLength(128)
+ .HasColumnType("varchar(128)")
+ .HasColumnName("EntityTypeFullName");
+
+ b.Property("ExtraProperties")
+ .HasColumnType("longtext")
+ .HasColumnName("ExtraProperties");
+
+ b.Property("TenantId")
+ .HasColumnType("char(36)")
+ .HasColumnName("TenantId");
+
+ b.HasKey("Id");
+
+ b.HasIndex("AuditLogId");
+
+ b.HasIndex("TenantId", "EntityTypeFullName", "EntityId");
+
+ b.ToTable("AbpEntityChanges");
+ });
+
+ modelBuilder.Entity("Volo.Abp.AuditLogging.EntityPropertyChange", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("char(36)");
+
+ b.Property("EntityChangeId")
+ .HasColumnType("char(36)");
+
+ b.Property("NewValue")
+ .HasMaxLength(512)
+ .HasColumnType("varchar(512)")
+ .HasColumnName("NewValue");
+
+ b.Property("OriginalValue")
+ .HasMaxLength(512)
+ .HasColumnType("varchar(512)")
+ .HasColumnName("OriginalValue");
+
+ b.Property("PropertyName")
+ .IsRequired()
+ .HasMaxLength(128)
+ .HasColumnType("varchar(128)")
+ .HasColumnName("PropertyName");
+
+ b.Property("PropertyTypeFullName")
+ .IsRequired()
+ .HasMaxLength(64)
+ .HasColumnType("varchar(64)")
+ .HasColumnName("PropertyTypeFullName");
+
+ b.Property("TenantId")
+ .HasColumnType("char(36)")
+ .HasColumnName("TenantId");
+
+ b.HasKey("Id");
+
+ b.HasIndex("EntityChangeId");
+
+ b.ToTable("AbpEntityPropertyChanges");
+ });
+
+ modelBuilder.Entity("Volo.Abp.BackgroundJobs.BackgroundJobRecord", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("char(36)");
+
+ b.Property("ConcurrencyStamp")
+ .IsConcurrencyToken()
+ .HasMaxLength(40)
+ .HasColumnType("varchar(40)")
+ .HasColumnName("ConcurrencyStamp");
+
+ b.Property("CreationTime")
+ .HasColumnType("datetime(6)")
+ .HasColumnName("CreationTime");
+
+ b.Property("ExtraProperties")
+ .HasColumnType("longtext")
+ .HasColumnName("ExtraProperties");
+
+ b.Property("IsAbandoned")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("tinyint(1)")
+ .HasDefaultValue(false);
+
+ b.Property("JobArgs")
+ .IsRequired()
+ .HasMaxLength(1048576)
+ .HasColumnType("longtext");
+
+ b.Property("JobName")
+ .IsRequired()
+ .HasMaxLength(128)
+ .HasColumnType("varchar(128)");
+
+ b.Property("LastTryTime")
+ .HasColumnType("datetime(6)");
+
+ b.Property("NextTryTime")
+ .HasColumnType("datetime(6)");
+
+ b.Property("Priority")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("tinyint unsigned")
+ .HasDefaultValue((byte)15);
+
+ b.Property("TryCount")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("smallint")
+ .HasDefaultValue((short)0);
+
+ b.HasKey("Id");
+
+ b.HasIndex("IsAbandoned", "NextTryTime");
+
+ b.ToTable("AbpBackgroundJobs");
+ });
+
+ modelBuilder.Entity("Volo.Abp.FeatureManagement.FeatureValue", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("char(36)");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasMaxLength(128)
+ .HasColumnType("varchar(128)");
+
+ b.Property("ProviderKey")
+ .HasMaxLength(64)
+ .HasColumnType("varchar(64)");
+
+ b.Property("ProviderName")
+ .HasMaxLength(64)
+ .HasColumnType("varchar(64)");
+
+ b.Property("Value")
+ .IsRequired()
+ .HasMaxLength(128)
+ .HasColumnType("varchar(128)");
+
+ b.HasKey("Id");
+
+ b.HasIndex("Name", "ProviderName", "ProviderKey");
+
+ b.ToTable("AbpFeatureValues");
+ });
+
+ modelBuilder.Entity("Volo.Abp.Identity.IdentityClaimType", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("char(36)");
+
+ b.Property("ConcurrencyStamp")
+ .IsConcurrencyToken()
+ .HasMaxLength(40)
+ .HasColumnType("varchar(40)")
+ .HasColumnName("ConcurrencyStamp");
+
+ b.Property("Description")
+ .HasMaxLength(256)
+ .HasColumnType("varchar(256)");
+
+ b.Property("ExtraProperties")
+ .HasColumnType("longtext")
+ .HasColumnName("ExtraProperties");
+
+ b.Property("IsStatic")
+ .HasColumnType("tinyint(1)");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasMaxLength(256)
+ .HasColumnType("varchar(256)");
+
+ b.Property("Regex")
+ .HasMaxLength(512)
+ .HasColumnType("varchar(512)");
+
+ b.Property("RegexDescription")
+ .HasMaxLength(128)
+ .HasColumnType("varchar(128)");
+
+ b.Property("Required")
+ .HasColumnType("tinyint(1)");
+
+ b.Property("ValueType")
+ .HasColumnType("int");
+
+ b.HasKey("Id");
+
+ b.ToTable("AbpClaimTypes");
+ });
+
+ modelBuilder.Entity("Volo.Abp.Identity.IdentityLinkUser", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("char(36)");
+
+ b.Property("SourceTenantId")
+ .HasColumnType("char(36)");
+
+ b.Property("SourceUserId")
+ .HasColumnType("char(36)");
+
+ b.Property("TargetTenantId")
+ .HasColumnType("char(36)");
+
+ b.Property("TargetUserId")
+ .HasColumnType("char(36)");
+
+ b.HasKey("Id");
+
+ b.HasIndex("SourceUserId", "SourceTenantId", "TargetUserId", "TargetTenantId")
+ .IsUnique();
+
+ b.ToTable("AbpLinkUsers");
+ });
+
+ modelBuilder.Entity("Volo.Abp.Identity.IdentityRole", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("char(36)");
+
+ b.Property("ConcurrencyStamp")
+ .IsConcurrencyToken()
+ .HasMaxLength(40)
+ .HasColumnType("varchar(40)")
+ .HasColumnName("ConcurrencyStamp");
+
+ b.Property("ExtraProperties")
+ .HasColumnType("longtext")
+ .HasColumnName("ExtraProperties");
+
+ b.Property("IsDefault")
+ .HasColumnType("tinyint(1)")
+ .HasColumnName("IsDefault");
+
+ b.Property("IsPublic")
+ .HasColumnType("tinyint(1)")
+ .HasColumnName("IsPublic");
+
+ b.Property("IsStatic")
+ .HasColumnType("tinyint(1)")
+ .HasColumnName("IsStatic");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasMaxLength(256)
+ .HasColumnType("varchar(256)");
+
+ b.Property("NormalizedName")
+ .IsRequired()
+ .HasMaxLength(256)
+ .HasColumnType("varchar(256)");
+
+ b.Property("TenantId")
+ .HasColumnType("char(36)")
+ .HasColumnName("TenantId");
+
+ b.HasKey("Id");
+
+ b.HasIndex("NormalizedName");
+
+ b.ToTable("AbpRoles");
+ });
+
+ modelBuilder.Entity("Volo.Abp.Identity.IdentityRoleClaim", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("char(36)");
+
+ b.Property("ClaimType")
+ .IsRequired()
+ .HasMaxLength(256)
+ .HasColumnType("varchar(256)");
+
+ b.Property("ClaimValue")
+ .HasMaxLength(1024)
+ .HasColumnType("varchar(1024)");
+
+ b.Property("RoleId")
+ .HasColumnType("char(36)");
+
+ b.Property("TenantId")
+ .HasColumnType("char(36)")
+ .HasColumnName("TenantId");
+
+ b.HasKey("Id");
+
+ b.HasIndex("RoleId");
+
+ b.ToTable("AbpRoleClaims");
+ });
+
+ modelBuilder.Entity("Volo.Abp.Identity.IdentitySecurityLog", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("char(36)");
+
+ b.Property("Action")
+ .HasMaxLength(96)
+ .HasColumnType("varchar(96)");
+
+ b.Property("ApplicationName")
+ .HasMaxLength(96)
+ .HasColumnType("varchar(96)");
+
+ b.Property("BrowserInfo")
+ .HasMaxLength(512)
+ .HasColumnType("varchar(512)");
+
+ b.Property("ClientId")
+ .HasMaxLength(64)
+ .HasColumnType("varchar(64)");
+
+ b.Property("ClientIpAddress")
+ .HasMaxLength(64)
+ .HasColumnType("varchar(64)");
+
+ b.Property("ConcurrencyStamp")
+ .IsConcurrencyToken()
+ .HasMaxLength(40)
+ .HasColumnType("varchar(40)")
+ .HasColumnName("ConcurrencyStamp");
+
+ b.Property("CorrelationId")
+ .HasMaxLength(64)
+ .HasColumnType("varchar(64)");
+
+ b.Property("CreationTime")
+ .HasColumnType("datetime(6)");
+
+ b.Property("ExtraProperties")
+ .HasColumnType("longtext")
+ .HasColumnName("ExtraProperties");
+
+ b.Property("Identity")
+ .HasMaxLength(96)
+ .HasColumnType("varchar(96)");
+
+ b.Property("TenantId")
+ .HasColumnType("char(36)")
+ .HasColumnName("TenantId");
+
+ b.Property("TenantName")
+ .HasMaxLength(64)
+ .HasColumnType("varchar(64)");
+
+ b.Property("UserId")
+ .HasColumnType("char(36)");
+
+ b.Property("UserName")
+ .HasMaxLength(256)
+ .HasColumnType("varchar(256)");
+
+ b.HasKey("Id");
+
+ b.HasIndex("TenantId", "Action");
+
+ b.HasIndex("TenantId", "ApplicationName");
+
+ b.HasIndex("TenantId", "Identity");
+
+ b.HasIndex("TenantId", "UserId");
+
+ b.ToTable("AbpSecurityLogs");
+ });
+
+ modelBuilder.Entity("Volo.Abp.Identity.IdentityUser", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("char(36)");
+
+ b.Property("AccessFailedCount")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int")
+ .HasDefaultValue(0)
+ .HasColumnName("AccessFailedCount");
+
+ b.Property("ConcurrencyStamp")
+ .IsConcurrencyToken()
+ .HasMaxLength(40)
+ .HasColumnType("varchar(40)")
+ .HasColumnName("ConcurrencyStamp");
+
+ b.Property("CreationTime")
+ .HasColumnType("datetime(6)")
+ .HasColumnName("CreationTime");
+
+ b.Property("CreatorId")
+ .HasColumnType("char(36)")
+ .HasColumnName("CreatorId");
+
+ b.Property("DeleterId")
+ .HasColumnType("char(36)")
+ .HasColumnName("DeleterId");
+
+ b.Property("DeletionTime")
+ .HasColumnType("datetime(6)")
+ .HasColumnName("DeletionTime");
+
+ b.Property("Email")
+ .IsRequired()
+ .HasMaxLength(256)
+ .HasColumnType("varchar(256)")
+ .HasColumnName("Email");
+
+ b.Property("EmailConfirmed")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("tinyint(1)")
+ .HasDefaultValue(false)
+ .HasColumnName("EmailConfirmed");
+
+ b.Property("ExtraProperties")
+ .HasColumnType("longtext")
+ .HasColumnName("ExtraProperties");
+
+ b.Property("IsDeleted")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("tinyint(1)")
+ .HasDefaultValue(false)
+ .HasColumnName("IsDeleted");
+
+ b.Property("IsExternal")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("tinyint(1)")
+ .HasDefaultValue(false)
+ .HasColumnName("IsExternal");
+
+ b.Property("LastModificationTime")
+ .HasColumnType("datetime(6)")
+ .HasColumnName("LastModificationTime");
+
+ b.Property("LastModifierId")
+ .HasColumnType("char(36)")
+ .HasColumnName("LastModifierId");
+
+ b.Property("LockoutEnabled")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("tinyint(1)")
+ .HasDefaultValue(false)
+ .HasColumnName("LockoutEnabled");
+
+ b.Property("LockoutEnd")
+ .HasColumnType("datetime(6)");
+
+ b.Property("Name")
+ .HasMaxLength(64)
+ .HasColumnType("varchar(64)")
+ .HasColumnName("Name");
+
+ b.Property("NormalizedEmail")
+ .IsRequired()
+ .HasMaxLength(256)
+ .HasColumnType("varchar(256)")
+ .HasColumnName("NormalizedEmail");
+
+ b.Property("NormalizedUserName")
+ .IsRequired()
+ .HasMaxLength(256)
+ .HasColumnType("varchar(256)")
+ .HasColumnName("NormalizedUserName");
+
+ b.Property("PasswordHash")
+ .HasMaxLength(256)
+ .HasColumnType("varchar(256)")
+ .HasColumnName("PasswordHash");
+
+ b.Property("PhoneNumber")
+ .HasMaxLength(16)
+ .HasColumnType("varchar(16)")
+ .HasColumnName("PhoneNumber");
+
+ b.Property("PhoneNumberConfirmed")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("tinyint(1)")
+ .HasDefaultValue(false)
+ .HasColumnName("PhoneNumberConfirmed");
+
+ b.Property("SecurityStamp")
+ .IsRequired()
+ .HasMaxLength(256)
+ .HasColumnType("varchar(256)")
+ .HasColumnName("SecurityStamp");
+
+ b.Property("Surname")
+ .HasMaxLength(64)
+ .HasColumnType("varchar(64)")
+ .HasColumnName("Surname");
+
+ b.Property("TenantId")
+ .HasColumnType("char(36)")
+ .HasColumnName("TenantId");
+
+ b.Property("TwoFactorEnabled")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("tinyint(1)")
+ .HasDefaultValue(false)
+ .HasColumnName("TwoFactorEnabled");
+
+ b.Property("UserName")
+ .IsRequired()
+ .HasMaxLength(256)
+ .HasColumnType("varchar(256)")
+ .HasColumnName("UserName");
+
+ b.HasKey("Id");
+
+ b.HasIndex("Email");
+
+ b.HasIndex("NormalizedEmail");
+
+ b.HasIndex("NormalizedUserName");
+
+ b.HasIndex("UserName");
+
+ b.ToTable("AbpUsers");
+ });
+
+ modelBuilder.Entity("Volo.Abp.Identity.IdentityUserClaim", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("char(36)");
+
+ b.Property("ClaimType")
+ .IsRequired()
+ .HasMaxLength(256)
+ .HasColumnType("varchar(256)");
+
+ b.Property("ClaimValue")
+ .HasMaxLength(1024)
+ .HasColumnType("varchar(1024)");
+
+ b.Property("TenantId")
+ .HasColumnType("char(36)")
+ .HasColumnName("TenantId");
+
+ b.Property("UserId")
+ .HasColumnType("char(36)");
+
+ b.HasKey("Id");
+
+ b.HasIndex("UserId");
+
+ b.ToTable("AbpUserClaims");
+ });
+
+ modelBuilder.Entity("Volo.Abp.Identity.IdentityUserLogin", b =>
+ {
+ b.Property("UserId")
+ .HasColumnType("char(36)");
+
+ b.Property("LoginProvider")
+ .HasMaxLength(64)
+ .HasColumnType("varchar(64)");
+
+ b.Property("ProviderDisplayName")
+ .HasMaxLength(128)
+ .HasColumnType("varchar(128)");
+
+ b.Property("ProviderKey")
+ .IsRequired()
+ .HasMaxLength(196)
+ .HasColumnType("varchar(196)");
+
+ b.Property("TenantId")
+ .HasColumnType("char(36)")
+ .HasColumnName("TenantId");
+
+ b.HasKey("UserId", "LoginProvider");
+
+ b.HasIndex("LoginProvider", "ProviderKey");
+
+ b.ToTable("AbpUserLogins");
+ });
+
+ modelBuilder.Entity("Volo.Abp.Identity.IdentityUserOrganizationUnit", b =>
+ {
+ b.Property("OrganizationUnitId")
+ .HasColumnType("char(36)");
+
+ b.Property("UserId")
+ .HasColumnType("char(36)");
+
+ b.Property("CreationTime")
+ .HasColumnType("datetime(6)")
+ .HasColumnName("CreationTime");
+
+ b.Property("CreatorId")
+ .HasColumnType("char(36)")
+ .HasColumnName("CreatorId");
+
+ b.Property("TenantId")
+ .HasColumnType("char(36)")
+ .HasColumnName("TenantId");
+
+ b.HasKey("OrganizationUnitId", "UserId");
+
+ b.HasIndex("UserId", "OrganizationUnitId");
+
+ b.ToTable("AbpUserOrganizationUnits");
+ });
+
+ modelBuilder.Entity("Volo.Abp.Identity.IdentityUserRole", b =>
+ {
+ b.Property("UserId")
+ .HasColumnType("char(36)");
+
+ b.Property("RoleId")
+ .HasColumnType("char(36)");
+
+ b.Property("TenantId")
+ .HasColumnType("char(36)")
+ .HasColumnName("TenantId");
+
+ b.HasKey("UserId", "RoleId");
+
+ b.HasIndex("RoleId", "UserId");
+
+ b.ToTable("AbpUserRoles");
+ });
+
+ modelBuilder.Entity("Volo.Abp.Identity.IdentityUserToken", b =>
+ {
+ b.Property("UserId")
+ .HasColumnType("char(36)");
+
+ b.Property("LoginProvider")
+ .HasMaxLength(64)
+ .HasColumnType("varchar(64)");
+
+ b.Property("Name")
+ .HasMaxLength(128)
+ .HasColumnType("varchar(128)");
+
+ b.Property("TenantId")
+ .HasColumnType("char(36)")
+ .HasColumnName("TenantId");
+
+ b.Property("Value")
+ .HasColumnType("longtext");
+
+ b.HasKey("UserId", "LoginProvider", "Name");
+
+ b.ToTable("AbpUserTokens");
+ });
+
+ modelBuilder.Entity("Volo.Abp.Identity.OrganizationUnit", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("char(36)");
+
+ b.Property("Code")
+ .IsRequired()
+ .HasMaxLength(95)
+ .HasColumnType("varchar(95)")
+ .HasColumnName("Code");
+
+ b.Property("ConcurrencyStamp")
+ .IsConcurrencyToken()
+ .HasMaxLength(40)
+ .HasColumnType("varchar(40)")
+ .HasColumnName("ConcurrencyStamp");
+
+ b.Property("CreationTime")
+ .HasColumnType("datetime(6)")
+ .HasColumnName("CreationTime");
+
+ b.Property("CreatorId")
+ .HasColumnType("char(36)")
+ .HasColumnName("CreatorId");
+
+ b.Property("DeleterId")
+ .HasColumnType("char(36)")
+ .HasColumnName("DeleterId");
+
+ b.Property("DeletionTime")
+ .HasColumnType("datetime(6)")
+ .HasColumnName("DeletionTime");
+
+ b.Property("DisplayName")
+ .IsRequired()
+ .HasMaxLength(128)
+ .HasColumnType("varchar(128)")
+ .HasColumnName("DisplayName");
+
+ b.Property("ExtraProperties")
+ .HasColumnType("longtext")
+ .HasColumnName("ExtraProperties");
+
+ b.Property("IsDeleted")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("tinyint(1)")
+ .HasDefaultValue(false)
+ .HasColumnName("IsDeleted");
+
+ b.Property("LastModificationTime")
+ .HasColumnType("datetime(6)")
+ .HasColumnName("LastModificationTime");
+
+ b.Property("LastModifierId")
+ .HasColumnType("char(36)")
+ .HasColumnName("LastModifierId");
+
+ b.Property("ParentId")
+ .HasColumnType("char(36)");
+
+ b.Property("TenantId")
+ .HasColumnType("char(36)")
+ .HasColumnName("TenantId");
+
+ b.HasKey("Id");
+
+ b.HasIndex("Code");
+
+ b.HasIndex("ParentId");
+
+ b.ToTable("AbpOrganizationUnits");
+ });
+
+ modelBuilder.Entity("Volo.Abp.Identity.OrganizationUnitRole", b =>
+ {
+ b.Property("OrganizationUnitId")
+ .HasColumnType("char(36)");
+
+ b.Property("RoleId")
+ .HasColumnType("char(36)");
+
+ b.Property("CreationTime")
+ .HasColumnType("datetime(6)")
+ .HasColumnName("CreationTime");
+
+ b.Property("CreatorId")
+ .HasColumnType("char(36)")
+ .HasColumnName("CreatorId");
+
+ b.Property