diff --git a/.docs/README.md b/.docs/README.md
new file mode 100644
index 00000000..c7aaa452
--- /dev/null
+++ b/.docs/README.md
@@ -0,0 +1,2 @@
+BlogCore官方文档仓库地址已经迁移到:
+https://gitee.com/laozhangIsPhi/Blog.Core.E-Book
\ No newline at end of file
diff --git a/.docs/contents/.vuepress/config.js b/.docs/contents/.vuepress/config.js
deleted file mode 100644
index 6cb23754..00000000
--- a/.docs/contents/.vuepress/config.js
+++ /dev/null
@@ -1,46 +0,0 @@
-module.exports = {
- title: 'Blog.Core',
- description: 'Hello, 欢迎使用前后端分离之 ASP.NET Core 后端全家桶框架!',
- base : '/.doc/',
- head: [
- ['link', {
- rel: 'icon',
- href: `/favicon.ico`
- }]
- ],
- dest: './contents/.vuepress/dist',
- ga: '',
- evergreen: true,
- themeConfig: {
- nav: [
- { text: '首页', link: '/' },
- { text: '指南', link: '/guide/' },
- { text: '更新日志', link: '/Update/' },
- { text: '压测', link: '/PressureTest/' },
- { text: '参与贡献', link: '/Contribution/' },
- { text: 'BCVP社区', link: '/QQ/' },
- { text: '接口API', link: 'http://apk.neters.club' },
- { text: '管理后台', link: 'http://vueadmin.neters.club' },
- { text: 'Github', link: 'https://github.com/anjoy8/Blog.Core' },
- ],
- sidebarDepth: 2,
- sidebar: {
- '/guide/': getGuideSidebar('Guide'),
- }
- }
-}
-
-function getGuideSidebar (groupA) {
- return [
- {
- title: groupA,
- collapsable: false,
- children: [
- '',
- 'getting-started',
- 'function-sheet',
- 'cheat-sheet'
- ]
- }
- ]
- }
\ No newline at end of file
diff --git a/.docs/contents/.vuepress/public/bcvphomelogo.png b/.docs/contents/.vuepress/public/bcvphomelogo.png
deleted file mode 100644
index e1bf0f79..00000000
Binary files a/.docs/contents/.vuepress/public/bcvphomelogo.png and /dev/null differ
diff --git a/.docs/contents/.vuepress/public/favicon.ico b/.docs/contents/.vuepress/public/favicon.ico
deleted file mode 100644
index 68062fe0..00000000
Binary files a/.docs/contents/.vuepress/public/favicon.ico and /dev/null differ
diff --git a/.docs/contents/Contribution/README.md b/.docs/contents/Contribution/README.md
deleted file mode 100644
index a29822b4..00000000
--- a/.docs/contents/Contribution/README.md
+++ /dev/null
@@ -1,143 +0,0 @@
-# 贡献
-
-
-欢迎一起完善文档,
-参与打赏的小可爱名单如下(单位:元),你们的贡献是我继续的动力:
-(2021年9月9日 13点53分)
-
-
-|序号|微信昵称|助力值|备注|
-|-|-|-|-|
-|01|排 * * 瓜|100||
-|02|船 * * 长|100||
-|03|二 * * 生|1||
-|04||1|未留微信号|
-|05|旭 * * 光|10||
-|06||12.66|未留微信号|
-|07|Ro * * st|10||
-|08|陈 * * 朝|10||
-|09|勇 * * 勇|10||
-|10|袁 * * 嘉|10||
-|11|En * * us|20||
-|12|风 * * 在|18||
-|13|林 * * 杰|10||
-|14|枫 * * 叶|10||
-|15|火 * * 鸟 |50||
-|16|阿 * * 福|10||
-|17||20|未留微信号|
-|18|Er * * or|100|未留微信号|
-|19|陶 * * ve|20||
-|20|熊 * * 育|50||
-|21|点 * * 痕|20||
-|22|夏 * * 目|20||
-|23|CL * * L|50||
-|24|rm * * rf|100||
-|25|Je * * ca|30|搜不到微信号|
-|26|W * * 生|50||
-|27|鹏 * * 郎|20||
-|28|ws * * ai|10||
-|29|逐 * * 梦|20||
-|30|Jo * * aH|10||
-|31|Do * * n|10||
-|32|灰 * * 白|50||
-|33|Ne * * er|100||
-|34|Ar * * as|10||
-|35|吉 * * 祥|36||
-|36|ma * * y|10||
-|37|Yu * * ic|30||
-|38|亡 * * 死|30||
-|39|板 * * 根|20||
-|40|-- * * -|100|未留微信号|
-|41|t * * |20||
-|42|王 * * 聪 |10|未留微信号|
-|43|哈 * * 方|50||
-|44|le * * on|30||
-|45|李 * * |10||
-|46|不 * * 染|10|未留微信号|
-|47|林 * * LIN|10||
-|48|阿 * * 奇|30||
-|49|哒 * * 哒|10||
-|50|王 * * 龙|100||
-|51|Ja * * Tu|100||
-|52|it * * hi|100||
-|53|沙 * * 锋|50|未留微信号|
-|54|Ba * * ai|10||
-|55|古 * * 桐|10||
-|56|小 * * 柜|20||
-|57|rm * * rf|100||
-|58|高 * * 源|10||
-|59|Qq * * 80|10|未留微信号|
-|60|如 * * 寄|20||
-|61|大 * * 灰|10|未留微信号|
-|62|包 * * 华|10|微信号错误|
-|63|西 * * 5°|30||
-|64|王 * * 粮|20||
-|65|Q1 * * ..|30||
-|66|Le * * ry|100||
-|67|bo * * t|30||
-|68|早 * * 蛋|10||
-|69|罗 * * 啊|10||
-|70|40 * * er|30||
-|71|胡 * * 运|30||
-|72|昌 * * 进|5||
-|73|甲 * * 学|15||
-|74|小 * * 走|100||
-|75|啊 * * 辉|50||
-|76|D * * W|100||
-|77|简 * * 简|99||
-|78|空 * * 空|101||
-|79|朱 * * 傻|20||
-|80|Mr * * hi|50||
-|81|王 * * 飞|110||
-|82|Mr * * nn|20|微信号未搜到|
-|83|蓝 * * 兴|30||
-|84|Et * * ng|100||
-|85|Ke * * on|10||
-|86|几 * * 己|20||
-|87|张 * * 群|20||
-|88|睡 * * 鱼|30||
-|89|Mr * * 宋|50||
-|90|布 * * 布|10||
-|91|s * * s|6.6||
-|92|V * * V|50||
-|93|o**o|50||
-|94|书**6|6.6||
-|95|精**E|50||
-|96|有**幸|10||
-|97|r**y|10||
-|98|v**c|5||
-|99|j**n|20||
-|100|贾**琪|100||
-|101|a**s|20||
-|102|狂**牛|10||
-|103|风**宜|10||
-|104|鸠**夜|5||
-|105|大**灰|15||
-|106|不**懂|100||
-|107|圣**旨|50||
-|108|A**n|50||
-|109|薛**猫|100||
-|110|岁**叁|10||
-|111|K**g|100||
-|112|琛**田|30||
-|113|L**s|20||
-|114|小**哥|10||
-|115|G**e|10||
-|116|s**o|30||
-|117|大**白|50||
-|118|星**星|20||
-|119|沙**锋|200||
-|120|词**意|11||
-|121|A**N|20||
-|122|像**恋|10||
-|123|M**o|10||
-|124|风**虹|50||
-|125|健**诚|10||
-|126|**|5||
-|127|何**玖|6.66||
-|128|A**g|10||
-|129|高**广|20||
-|130|吴**杰|0.01||
-|131|刘**标|0.01||
-
-
diff --git a/.docs/contents/PressureTest/README.md b/.docs/contents/PressureTest/README.md
deleted file mode 100644
index af2a2e93..00000000
--- a/.docs/contents/PressureTest/README.md
+++ /dev/null
@@ -1,80 +0,0 @@
-# 框架压测报告
-
-
-## 1、测试工具
-使用 `JMeter` 进行压力测试。
-测试时间:2021年1月21日 09点38分。
-服务器报告:
-
-
-
-
-## 2、测试准备
-因为 `JMeter` 是使用 `JAVA` 写的,所以使用 `JMeter` 之前,先安装 `JAVA` 环境。
-安装好后,在 `bin` 文件夹下,点击 `jmeter.bat` 启动程序。
-启动之后会有两个窗口,一个`cmd`窗口,一个`JMeter`的 `GUI`。前面不要忽略`CMD`窗口的提示信息,不要关闭它。
-注意:使用`API`模式,不要使用`GUI`模式。
-
-
-## 3、测试配置
-本地发布后的 `windows` 环境,直接用 `kestrel` 启动。
-线程数:100
-循环数:1000
-HTTP默认值:协议:`http`;服务器或IP:`localhost`;端口号:`9291`;
-HTTP请求:方法:GET;路径:`/api/blog/ApacheTestUpdate`
-HTTP信息请求管理器:无
-响应断言:无
-
-
-
-## 4、项目初始化
-目前采用 `Blog.Core` 默认的配置,
-只开启了内存 `AOP` ,
-其他的都是默认的,然后也把任务调度也关闭了,
-最后注意要把 `IP限流`给关闭,不然压测没效果,因为限流了:
-
-
-
-## 5、压测过程
-
-##### 第一阶段
-
-
-
-
-##### 第二阶段
-
-
-
-
-##### 第三阶段
-
-
-
-
-##### 第四阶段(压测后,检测内存是否降低,20m后)
-
-
-
-##### 第五阶段(停止压测1h后)
-
-
-
-## 6、测试结果
-内存方面,`100*1000` 的 **压测过程中** (写操作),项目保证所占内存在 `350m~500m` 之间
-然后停止一个小时后,内存将为`150m~200m`:
-
-
-
-
-
-
-## 7、压测配置文件下载
- [配置文件](https://img.neters.club/doc/blogcore_blog_ApacheTestUpdate.jmx)
- 下载后,导入到工具里,可以直接测试,察看结果树。
-
-## 8、Docker 镜像
- 已经提交到 `docker hub` 自行拉取操作即可:
- ```
- docker pull laozhangisphi/apkimg:latest
- ```
diff --git a/.docs/contents/QQ/README.md b/.docs/contents/QQ/README.md
deleted file mode 100644
index 31b7f909..00000000
--- a/.docs/contents/QQ/README.md
+++ /dev/null
@@ -1,18 +0,0 @@
-## 开源社区
-
-
-
-[https://github.com/BaseCoreVueProject/Home](https://github.com/BaseCoreVueProject/Home)
-
-Base netCore (Vue) Project Team,
-基于Net/Core 和Vue(react/ng),快速搭建 MVC & SPA 及微服务应用
-如果你有关于dotNet/core 的,不错的,可以正常运行,且一年内维护的,均可以加入。
-唯一宗旨:我们来自社区,服务社区,反哺社区。
-
-
-
-## 微信公众号
-
-
-
-
diff --git a/.docs/contents/README.md b/.docs/contents/README.md
deleted file mode 100644
index 597f16d9..00000000
--- a/.docs/contents/README.md
+++ /dev/null
@@ -1,14 +0,0 @@
----
-home: true
-heroImage: /bcvphomelogo.png
-actionText: 快速上手 →
-actionLink: /guide/
-features:
-- title: 详尽的文档
- details: 通过详细的文章和视频讲解,将知识点各个击破,入门ASP.Net Core不再难
-- title: 强大的社区
- details: 通过 QQ 群,和数千位同业大佬一起切磋交流。
-- title: 丰富的内容
- details: 框架涵盖ASP.Net Core开发中常见的基本知识点,不仅适合初学者入门,同时也适用于企业级别的开发。
-footer: MIT Licensed | Copyright © 2018-2020-老张的哲学 Powered by VUEPRESS on CentOS 7.6
----
\ No newline at end of file
diff --git a/.docs/contents/Update/README.md b/.docs/contents/Update/README.md
deleted file mode 100644
index 870f98ec..00000000
--- a/.docs/contents/Update/README.md
+++ /dev/null
@@ -1,198 +0,0 @@
-
-## 更新日志
-
-
-### 2021-08-21
-
-重要功能增加:项目增加 `Apollo` 配置中心;
-
-### 2021-08-03
-
-重要功能增加:项目增加 `ES` 搜索,增加 `Serilog` 使用 `tcp` 的方式自定义格式化,写入 `elk` 的实现;
-
-### 2021-06-28
-
-功能增加:项目增加 `nacos` 配置,支持将项目注册到 `nacos` 服务中心,搭建微服务之子服务;
-
-### 2021-06-04
-
-小功能更新:执行的时候,将 `Sql` 日志输出到控制台,方便查看,支持配置文件关闭;
-
-### 2021-05-01
-
-组件更新:多项日志中间件,由自写组件,转为使用`serilog`组件记录日志;
-
-### 2021-03-03
-
-项目目录调整:新增测试文件夹和模板文件夹;
-
-### 2021-02-09
-
-重大项目更新:新增建行聚合支付;
-
-### 2021-01-11
-
-更新:优化任务调度功能,新增暂停和停止;
-
-### 2020-12-02
-
-更新:新增调用`MongoDB`功能,功能可用待完善中;
-
-
-### 2020-11-19
-> 重大内容更新:更新项目模板 `Update Blog.Core.Webapi.Template.2.5.2.nupkg`
-> 主要内容:1、泛型主键;2、通过测试中间件;3、`RabbitMQ`消息队列
-
-
-### 2020-11-18
-
-项目更新:新增`RabbitMQ`消息队列和`EventBus`事件总线,功能可用待完善。
-
-
-### 2020-11-11
-
-项目重大更新:更新至`.NET 5.0`。
-
-
-### 2020-11-05
-
-项目更新:增加`测试用户`中间件,通过一键操作可以跳过权限限制,方便调试,文章[使用测试用户中间件](http://apk.neters.club/api/Blog/GoUrl?id=156)。
-
-
-
-### 2020-10-11
-
-项目更新:设计泛型主键功能,可以在项目初始化的时候设计主键类型。
-
-
-
-### 2020-09-18
-
-项目更新:更新项目模板 `Update Blog.Core.Webapi.Template.2.2.3.nupkg` 。
-> 1、增加 `Redis` 消息队列功能;
-
-
-
-### 2020-09-04
-
-项目更新:增加 `Redis` 消息队列功能;
-
-
-### 2020-08-06
-
-项目更新:更新项目模板 `Update Blog.Core.Webapi.Template.2.2.0.nupkg` 。
-> 1、根据解决方案名,来自动导入model;
-> 2、单独封装服务扩展层 `Blog.Core.Extensions` ;
-> 3、代码生成器,支持控制器文件的生成;
-> 4、弱化仓储层,用泛型仓储基类注入服务;
-
-
-
-
-### 2020-08-01
-
-> 重大结构更新:弱化仓储层,通过泛型仓储基类,来实现仓储服务注入,并去掉`Blog.Core.IRepository` 接口层;
-
-### 2020-07-03
-
-> 更新:`DbFirstController` 生成四层文件,目前新增支持 `控制器Controller` 文件的输出;
-
-
-### 2020-06-22
-
-> 项目更新:将服务扩展和自定义中间件,单独封装一层 `Blog.Core.Extensions` ,更解耦。
-
-
-
-### 2020-06-08
-
-> 简单项目更新:生成数据库表结构的时候,利用反射机制,自动生成固定命名空间 `Blog.Core.Model.Models` 下的全部实体.
-> 同时判断表是否存在,如果存在下次不再重复生成。
-
-
-### 2020-06-06
-
-项目更新:更新项目模板 `Update Blog.Core.Webapi.Template.2.1.0.nupkg` [1a726f8](https://github.com/anjoy8/Blog.Core/commit/1a726f890e527c978982071462e82db4478632f0),更新项目即可 。
-> 1、配置内容展示到控制台;
-> 2、简化封装 `Startup.cs` 类文件;
-> 3、`DbFirst` 模式支持多库模式;
-> 4、`Log4net` 讲异常和 `Info` 分开;
-> 5、修复 `BlogLogAop` 偶尔卡顿问题;
-> 6、将生成种子数据和任务调度功能,封装到中间件;
-> 7、获取当前项目在服务器中的运行信息;
-> 8、删除所有的不需要的 `using` 指令;
-
-
-
-
-### 2020-05-29
-项目启动开启 `QuzrtzNet` 调度任务,并且在 `Admin` 后台管理中配置操作界面;
-> 内容更新:封装生成种子数据的入口方法;
-
-
-
-### 2020-05-12
-修复:支持多库模式下,生成项目模板代码 `DbFirstController` [102c6d6](https://github.com/anjoy8/Blog.Core/commit/102c6d6bfcafd06bf5241844759dea5e7a6815da)
-> 注意:`T4` 模板不能此功能,一次只能一个数据库,且只能 `SqlServer`
-
-
-### 2020-05-07
-> 重大内容更新:更新项目模板 `Update Blog.Core.Webapi.Template.2.1.0.nupkg` [7f64fde](https://github.com/anjoy8/Blog.Core/commit/7f64fde5507f7a8572372dcadb6af5110bd37d68)
-
-
-### 2020-05-06
-> 重大内容更新:优化Log4Net使用方案,完美配合 `NetCore` 官方的 `ILogger`, [ecaffb6](https://github.com/anjoy8/Blog.Core/commit/ecaffb66bdf10a90c087d01e6e817e54f23a97d4)
-
-
-### 2020-05-01
-
-> 重要内容更新:配合Admin全部完成按钮级别权限,更新初始化种子数据
-
-### 2020-04-27
-
-增加功能:配合前端Admin,增加页面 `KeepAlive` 功能;
-增加功能:增加 `Sql` 语句查询Demo,支持返回 `DataTable`;
-
-
-### 2020-04-25
-
-增加功能:`Http api` 接口调用,满足微服务需求
-> 重要内容更新:优化 `Appsettings.app()` 方法,通过官方 `IConfiguration` 接口来获取DBS连接字符串;
-> 优化 `BlogLogAOP.cs`
-
-
-### 2020-04-15
-
-> 重大内容更新:更新项目模板 `Update Blog.Core.Webapi.Template.1.11.30.nupkg`
-
-
-### 2020-04-14
-> 重大内容更新:主分支,可以通过配置,一键切换JWT和Ids4认证授权模式
-
-
-### 2020-03-30
-> 重大内容更新:统一所有接口返回格式
-
-
-### 2020-03-25
-增加功能:支持读写分离(目前是三种模式:单库、多库、读写分离)
-> 重大BUG更新:系统登录接口,未对用户软删除进行判断,现已修复
-> API: /api/login/GetJwtToken3
-> Code: await _sysUserInfoServices.Query(d => d.uLoginName == name && d.uLoginPWD == pass && d.tdIsDelete == false);
-
-
-
-### 2020-03-18
-增加功能:创建 Quartz.net 任务调度服务
-
-
-### 2020-01-09
-增加功能:项目迁移到IdentityServer4,统一授权认证中心
-
-
-### 2020-01-05
-增加功能:设计一个简单的中间件,可以查看所有已经注入的服务
-
-
-### 2020-01-04
-增加功能:Ip限流,防止过多刷数据
diff --git a/.docs/contents/guide/README.md b/.docs/contents/guide/README.md
deleted file mode 100644
index 30950e0c..00000000
--- a/.docs/contents/guide/README.md
+++ /dev/null
@@ -1,121 +0,0 @@
-# W 文档指南
-## 亮点与优势
-
-Blog.Core 是一个开箱即用的企业级权限管理应用框架。
-采用最新的前后端完全分离技术【 ASP.NET Core Api 5.0 + Vue 2.x 】。
-并结合 `IdentityServer4` ,可快速解决多客户端和多资源服务的统一认证与鉴权的问题。
-
-## 其他资料
-
-博客园,早期架构搭建:[博客园](https://www.cnblogs.com/laozhang-is-phi/p/9495618.html)
-公众号,后期调整:[文章](https://mvp.neters.club/MVP_aspnetcore_2020/2020)
-视频:[B站](https://www.bilibili.com/video/BV1vC4y1p7Za)
-
-
-## 配套站点
-
-本资源服务器,配合多个项目,构建前后端权限一体化平台,前端用 `VUE` 框架。
-前端-客户端:[预览](https://vueadmin.neters.club/)、[源码](https://github.com/anjoy8/Blog.Admin)
-前端-管理后台:[预览](http://vueblog.neters.club/)、[源码](https://github.com/anjoy8/Blog.Vue)
-认证平台:[预览](https://ids.neters.club/)、[源码](https://github.com/anjoy8/Blog.IdentityServer)
-
-
-### 为什么选择 ASPNET.Core
-1、【开源】`ASPNET.NET Core` 是由 `Microsoft` 和 `.NET` 社区在 `GitHub` 上开源并维护的一个跨平台(支持 Windows、macOS 和 Linux)的新一代高性能框架,
-拥有十分广泛的社区与支持者,可用于构建web应用、物联网IOT应用和移动端应用。
-2、【高效】Asp.net core(.net core)来源于.net,很容易迁移,而且也很容易上手,
-但是又是不同的一个框架,除了上述对.net开发者十分友好以外,相对于之前的.net项目,速度上有巨大的改进,
-相比与原来的`Web(.net framework 4.6)`程序性能提升了`2300%`。跟`python`、`java`等相同环境比较,性能都要优越,
-参考[www.techempower.com](https://www.techempower.com/benchmarks/)。
-3、【跨平台】可以在`Windows`、`Mac`和`Linux`构建和运行跨平台的`Asp.Net Core`应用。
-4、【云原生】在云原生领域拥有天然的优势,搭配Azure云服务,配合K8s,更好的实现分布式应用,以及微服务应用。
-5、【微服务】`ASP.NET Core`尤其适用于微服务架构,也就是说ASP.NET Core不仅适合于中小型项目而且还特别适合于大型,超大型项目。
-6、【大公司】目前国内采用`ASP.NET Core`的大公司比如腾讯、网易,国际的有Bing,GoDaddy,Stackoverflow,Adobe,Microsoft
-7、【总结来说】,`java`支持的,`ASPNET.Core`都支持,而且更轻量级、更高效跨,并且对.net开发者十分友好,微服务案例成熟。
-
-
-
-### 框架功能点
-1、丰富完整的接口文档,在查看的基础上,可以模拟前端调用,更方便。
-2、采用多层开发,隔离性更好,封装更完善。
-3、基于项目模板,可以一键创建自己的项目。
-4、搭配代码生成器,实现快速开发,节省成本。
-5、项目集成多库模式以及读写分离模式,可以同时处理多个数据库的不同模块,更快更安全。
-6、集成统一认证平台 `IdentityServer4` ,实现多个项目的统一认证管理,解决了之前一个项目,
-一套用户的弊端,更适用微服务的开发。
-7、丰富的审计日志处理,方便线上项目快速定位异常点。
-8、支持自由切换多种数据库,Sqlite/SqlServer/MySql/PostgreSQL/Oracle;
-9、支持 `Docker` 容器化开发,可以搭配 k8s 更好的实现微服务。
-
-
-### 应用领域
-1、【对接第三方api】项目通过`webapi`,可以快速对接第三方`api`服务,实现业务逻辑。
-2、【前后端分离】 采用的是`API`+前端的完全分离的开发模式,满足平时开发的所有需求,
-你可以对接任何的自定义前端项目:无论是微信小程序,还是授权APP,无论是PC网页,
-还是手机H5。
-3、【多项目】同时框架还集成了一套鉴权平台,采用IdentityServer4,可以快速的实现多个客户端的认证与授权服务,
-从而大大的减少了平时的工作量,可以快速的进行产品迭代。
-4、【微服务】当然,因为采用的是API模式,所以同样适用于微服务项目,实现高并发的产品需求。
-
-
-
-### 市场前景
-1、前后端分离模式已经是目前的主流开发模式,框架已经是一套可行的方案,开箱即用。
-2、拥有几十篇技术文档和3000人的技术社区,方便快捷的解决问题。
-3、目前已经有超过20多家公司在生产环境中使用,当然实际中更多,具体查看 [点击查看使用的情况](https://github.com/anjoy8/Blog.Core/issues/75)。
-4、同时可以搭配自己的业务,实现微服务的开发,在大数据高并发中,占有更好的优势。
-5、本项目直接作者由微软MVP“老张的哲学”出品,并长久维护,不会断更,有保障。
-
-
-
-## 功能与进度
-
-框架模块:
-- [√] 采用`仓储+服务+接口`的形式封装框架;
-- [√] 异步 async/await 开发;
-- [√] 接入国产数据库ORM组件 —— SqlSugar,封装数据库操作;
-- [√] 支持自由切换多种数据库,MySql/SqlServer/Sqlite/Oracle/Postgresql/达梦/人大金仓;
-- [√] 实现项目启动,自动生成种子数据 ✨;
-- [√] 五种日志记录,审计/异常/请求响应/服务操作/Sql记录等;
-- [√] 支持项目事务处理(若要分布式,用cap即可)✨;
-- [√] 设计4种 AOP 切面编程,功能涵盖:日志、缓存、审计、事务 ✨;
-- [√] 支持 T4 代码模板,自动生成每层代码;
-- [√] 或使用 DbFirst 一键创建自己项目的四层文件(支持多库);
-- [√] 封装`Blog.Core.Webapi.Template`项目模板,一键重建自己的项目 ✨;
-- [√] 搭配多个前端案例供参考和借鉴:Blog.Vue、Blog.Admin、Nuxt.tbug、Blog.Mvp.Blazor ✨;
-- [√] 统一集成 IdentityServer4 认证 ✨;
-
-组件模块:
-- [√] 提供 Redis 做缓存处理;
-- [√] 使用 Swagger 做api文档;
-- [√] 使用 MiniProfiler 做接口性能分析 ✨;
-- [√] 使用 Automapper 处理对象映射;
-- [√] 使用 AutoFac 做依赖注入容器,并提供批量服务注入 ✨;
-- [√] 支持 CORS 跨域;
-- [√] 封装 JWT 自定义策略授权;
-- [√] 使用 Log4Net 日志框架,集成原生 ILogger 接口做日志记录;
-- [√] 使用 SignalR 双工通讯 ✨;
-- [√] 添加 IpRateLimiting 做 API 限流处理;
-- [√] 使用 Quartz.net 做任务调度(目前单机多任务,集群调度暂不支持);
-- [√] 支持 数据库`读写分离`和多库操作 ✨;
-- [√] 新增 Redis 消息队列 ✨;
-- [√] 新增 RabbitMQ 消息队列 ✨;
-- [√] 新增 EventBus 事件总线 ✨;
-- [√] 新增 实现聚合支付;
-- [ ] 计划 - 数据部门权限;
-- [ ] 计划 - ES 搜索;
-
-微服务模块:
-- [√] 可配合 Docker 实现容器化;
-- [√] 可配合 Jenkins 实现CI / CD;
-- [√] 可配合 Consul 实现服务发现;
-- [√] 可配合 Ocelot 实现网关处理;
-- [√] 可配合 Nginx 实现负载均衡;
-- [√] 可配合 Ids4 实现认证中心;
-
-
-
-
-
-
-
diff --git a/.docs/contents/guide/cheat-sheet.md b/.docs/contents/guide/cheat-sheet.md
deleted file mode 100644
index 36f95e36..00000000
--- a/.docs/contents/guide/cheat-sheet.md
+++ /dev/null
@@ -1,580 +0,0 @@
-# Z 主要知识点
-
-
-
-## AOP
-
-本项目多处采用面向切面编程思想——AOP,除了广义上的过滤器和中间件以外,主要通过动态代理的形式来实现AOP编程思想,主要的案例共有四个,分别是:
-1、服务日志AOP;
-2、服务InMemory缓存AOP;
-3、服务Redis缓存AOP;
-4、服务事务AOP;
-
-
-具体的代码可以在 `Blog.Core\Blog.Core\AOP` 文件夹下查看。
-
-与此同时,多个AOP也设置了阀门来控制是否开启,具体的可以查看 `appsettings.json` 中的:
-
-```
- "AppSettings": {
- "RedisCachingAOP": {
- "Enabled": false,
- "ConnectionString": "127.0.0.1:6319"
- },
- "MemoryCachingAOP": {
- "Enabled": true
- },
- "LogAOP": {
- "Enabled": false
- },
- "TranAOP": {
- "Enabled": false
- },
- "SqlAOP": {
- "Enabled": false
- }
- },
-
-```
-
-## Appsettings
-
-整个系统通过一个封装的操作类 `Appsettings.cs` 来控制配置文件 `appsettings.json` 文件,
-操作类地址在:`\Blog.Core.Common\Helper` 文件夹下。
-具体的使用方法是:
-
-```
-Appsettings.app(new string[] { "AppSettings", "RedisCachingAOP", "Enabled" })
-
-// 里边的参数,按照 appsettings.json 中设置的层级顺序来写,可以获取到指定的任意内容。
-
-```
-
-
-
-## AspNetCoreRateLimit
-
-系统使用 `AspNetCoreRateLimit` 组件来实现ip限流:
-1、添加 `nuget` 包:
-```
-
-```
-
-2、注入服务 `IpPolicyRateLimitSetup.cs`
-```
-services.AddIpPolicyRateLimitSetup(Configuration);
-```
-
-3、配置中间件
-```
- // Ip限流,尽量放管道外层
- app.UseIpRateLimiting();
-```
-
-4、配置数据
-
-具体的内容,自行百度即可
-```
- "IpRateLimiting": {
- "EnableEndpointRateLimiting": true,
- "StackBlockedRequests": false,
- "RealIpHeader": "X-Real-IP",
- "ClientIdHeader": "X-ClientId",
- "HttpStatusCode": 429,//返回状态码
- "GeneralRules": [//规则,结尾一定要带*
- {
- "Endpoint": "*",
- "Period": "1m",
- "Limit": 120
- },
- {
- "Endpoint": "*:/api/blog*",
- "Period": "1m",
- "Limit": 30
- }
- ]
-
- }
-```
-
-
-
-## Async-Await
-
-整个系统采用 async/await 异步编程,符合主流的开发模式,
-特别是对多线程开发很友好。
-
-
-
-## Authorization-Ids4
-
-本系统 v2.0 版本(目前的系统已经集成 `ids4` 和 `jwt`,并且可以自由切换),已经支持了统一授权认证,和 `blog` 项目、`Admin` 项目、`DDD` 项目等一起,使用一个统一的认证中心。
-
-具体的代码参考:`.\Blog.Core\Extensions` 文件夹下的 `Authorization_Ids4Setup.cs` ,注意需要引用指定的 `nuget` 包,核心代码如下:
-
-```
- //【认证】
- services.AddAuthentication(o =>
- {
- o.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
- o.DefaultChallengeScheme = nameof(ApiResponseHandler);
- o.DefaultForbidScheme = nameof(ApiResponseHandler);
- })
- // 2.添加Identityserver4认证
- .AddIdentityServerAuthentication(options =>
- {
- options.Authority = Appsettings.app(new string[] { "Startup", "IdentityServer4", "AuthorizationUrl" });
- options.RequireHttpsMetadata = false;
- options.ApiName = Appsettings.app(new string[] { "Startup", "IdentityServer4", "ApiName" });
- options.SupportedTokens = IdentityServer4.AccessTokenValidation.SupportedTokens.Jwt;
- options.ApiSecret = "api_secret";
-
- })
-
-
-```
-
-### 如何在Swagger中配置Ids4?
-很简单,直接在 `SwaggerSetup.cs` 中直接接入 `oauth、Implicit` 即可:
-
-```
- //接入identityserver4
- c.AddSecurityDefinition("oauth2", new OpenApiSecurityScheme
- {
- Type = SecuritySchemeType.OAuth2,
- Flows = new OpenApiOAuthFlows
- {
- Implicit = new OpenApiOAuthFlow
- {
- AuthorizationUrl = new Uri($"{Appsettings.app(new string[] { "Startup", "IdentityServer4", "AuthorizationUrl" })}/connect/authorize"),
- Scopes = new Dictionary {
- {
- "blog.core.api","ApiResource id"
- }
- }
- }
- }
- });
-
-```
-
-然后在 `IdentityServer4` 项目中,做指定的修改,配置 `9291` 的回调地址:
-
-```
- new Client {
- ClientId = "blogadminjs",
- ClientName = "Blog.Admin JavaScript Client",
- AllowedGrantTypes = GrantTypes.Implicit,
- AllowAccessTokensViaBrowser = true,
-
- RedirectUris =
- {
- "http://vueadmin.neters.club/callback",
- // 这里要配置回调地址
- "http://localhost:9291/oauth2-redirect.html"
- },
- PostLogoutRedirectUris = { "http://vueadmin.neters.club" },
- AllowedCorsOrigins = { "http://vueadmin.neters.club" },
-
- AllowedScopes = {
- IdentityServerConstants.StandardScopes.OpenId,
- IdentityServerConstants.StandardScopes.Profile,
- "roles",
- "blog.core.api"
- }
- },
-
-```
-
-然后再 `Swagger` 中,配置登录授权:
-
-
-
-
-## Authorization-JWT
-
-如果你不想使用 `IdentityServer4` 的话,也可以使用 `JWT` 认证,同样是是`Blog.Core\Blog.Core\Extensions` 文件夹下的 `AuthorizationSetup.cs` 中有关认证的部分:
-
-```
- 1.添加JwtBearer认证服务
-.AddJwtBearer(o =>
-{
- o.TokenValidationParameters = tokenValidationParameters;
- o.Events = new JwtBearerEvents
- {
- OnAuthenticationFailed = context =>
- {
- // 如果过期,则把<是否过期>添加到,返回头信息中
- if (context.Exception.GetType() == typeof(SecurityTokenExpiredException))
- {
- context.Response.Headers.Add("Token-Expired", "true");
- }
- return Task.CompletedTask;
- }
- };
-})
-
-```
-
-
-## AutoMapper
-
-使用 `AutoMapper` 组件来实现 `Dto` 模型的传输转换,具体的用法,可以查看:
-`Blog.Core\Blog.Core\Extensions` 文件夹下的 `AutoMapperSetup.cs` 扩展类,
-通过引用 `AutoMapper` 和 `AutoMapper.Extensions.Microsoft.DependencyInjection` 两个 `nuget` 包,并设置指定的 `profile` 文件,来实现模型转换控制。
-
-```
-// 比如如何定义:
- public class CustomProfile : Profile
- {
- ///
- /// 配置构造函数,用来创建关系映射
- ///
- public CustomProfile()
- {
- CreateMap();
- CreateMap();
- }
- }
-
-
-// 比如如何使用
-models = _mapper.Map(blogArticle);
-
-```
-
-具体的查看项目中代码即可。
-
-
-
-
-## CORS
-
-在线项目使用的是 `nginx` 跨域代理,但是同时也是支持 `CORS` 代理:
-1、注入服务 `services.AddCorsSetup();` 具体代码 `Blog.Core\Blog.Core\Extensions` 文件夹下的 `CorsSetup.cs` 扩展类;
-2、配置中间件 `app.UseCors("LimitRequests");` ,要注意中间件顺序;
-3、配置自己项目的前端端口,通过在 `appsettings.json` 文件中配置自己的前端项目 `ip:端口` ,来实现跨域:
-
-```
- "Startup": {
- "Cors": {
- "IPs": "http://127.0.0.1:2364,http://localhost:2364,http://localhost:8080,http://localhost:8021,http://localhost:1818"
- }
- },
-
-```
-
-
-## DI-AutoFac
-
-项目使用了依赖注入,除了原生的依赖注入以外,更多的使用的是第三方组件 `Autofac` :
-1、引用依赖包:
-```
-
-
-
-```
-主要是第一个 `nuget` 包,下边的是为了实现动态代理 `AOP` 操作;
-
-2、项目之间采用引用解耦的方式,通过反射来注入服务层和仓储层的程序集 `dll` 来实现批量注入,更方便,以后每次新增和修改 `Service` 层和 `Repository` 层,只需要 `F6` 编译一下即可,具体代码查看 `Startup.cs`:
-
-```
-
-
- // 注意在CreateDefaultBuilder中,添加Autofac服务工厂
- public void ConfigureContainer(ContainerBuilder builder)
- {
- var basePath = Microsoft.DotNet.PlatformAbstractions.ApplicationEnvironment.ApplicationBasePath;
- //builder.RegisterType().As();
-
-
- #region 带有接口层的服务注入
-
-
- var servicesDllFile = Path.Combine(basePath, "Blog.Core.Services.dll");
- var repositoryDllFile = Path.Combine(basePath, "Blog.Core.Repository.dll");
-
- if (!(File.Exists(servicesDllFile) && File.Exists(repositoryDllFile)))
- {
- throw new Exception("Repository.dll和service.dll 丢失,因为项目解耦了,所以需要先F6编译,再F5运行,请检查 bin 文件夹,并拷贝。");
- }
-
-
-
- // AOP 开关,如果想要打开指定的功能,只需要在 appsettigns.json 对应对应 true 就行。
- var cacheType = new List();
- if (Appsettings.app(new string[] { "AppSettings", "RedisCachingAOP", "Enabled" }).ObjToBool())
- {
- builder.RegisterType();
- cacheType.Add(typeof(BlogRedisCacheAOP));
- }
- if (Appsettings.app(new string[] { "AppSettings", "MemoryCachingAOP", "Enabled" }).ObjToBool())
- {
- builder.RegisterType();
- cacheType.Add(typeof(BlogCacheAOP));
- }
- if (Appsettings.app(new string[] { "AppSettings", "TranAOP", "Enabled" }).ObjToBool())
- {
- builder.RegisterType();
- cacheType.Add(typeof(BlogTranAOP));
- }
- if (Appsettings.app(new string[] { "AppSettings", "LogAOP", "Enabled" }).ObjToBool())
- {
- builder.RegisterType();
- cacheType.Add(typeof(BlogLogAOP));
- }
-
- // 获取 Service.dll 程序集服务,并注册
- var assemblysServices = Assembly.LoadFrom(servicesDllFile);
- builder.RegisterAssemblyTypes(assemblysServices)
- .AsImplementedInterfaces()
- .InstancePerDependency()
- .EnableInterfaceInterceptors()//引用Autofac.Extras.DynamicProxy;
- .InterceptedBy(cacheType.ToArray());//允许将拦截器服务的列表分配给注册。
-
- // 获取 Repository.dll 程序集服务,并注册
- var assemblysRepository = Assembly.LoadFrom(repositoryDllFile);
- builder.RegisterAssemblyTypes(assemblysRepository)
- .AsImplementedInterfaces()
- .InstancePerDependency();
-
- #endregion
-
- #region 没有接口层的服务层注入
-
- //因为没有接口层,所以不能实现解耦,只能用 Load 方法。
- //注意如果使用没有接口的服务,并想对其使用 AOP 拦截,就必须设置为虚方法
- //var assemblysServicesNoInterfaces = Assembly.Load("Blog.Core.Services");
- //builder.RegisterAssemblyTypes(assemblysServicesNoInterfaces);
-
- #endregion
-
- #region 没有接口的单独类 class 注入
-
- //只能注入该类中的虚方法
- builder.RegisterAssemblyTypes(Assembly.GetAssembly(typeof(Love)))
- .EnableClassInterceptors()
- .InterceptedBy(cacheType.ToArray());
-
- #endregion
-
-
- // 这里和注入没关系,只是获取注册列表,请忽略
- tsDIAutofac.AddRange(assemblysServices.GetTypes().ToList());
- tsDIAutofac.AddRange(assemblysRepository.GetTypes().ToList());
- }
-
-```
-
-3、然后 `Program.cs` 中也要加一句话:` .UseServiceProviderFactory(new AutofacServiceProviderFactory()) //<--NOTE THIS `
-
-
-
-## DI-NetCore
-
-除了主要的 `Autofac` 依赖注入以外,也减少的使用了原生的依赖注入方式,很简单,比如这样的:
-```
-
- services.AddSingleton();
- // 注入权限处理器
- services.AddScoped();
- services.AddSingleton(permissionRequirement);
-```
-
-
-## Filter
-
-项目中一共有四个过滤器
-```
-1、GlobalAuthorizeFilter.cs —— 全局授权配置,添加后,就可以不用在每一个控制器上添加 [Authorize] 特性,但是3.1版本好像有些问题,【暂时放弃使用】;
-2、GlobalExceptionFilter.cs —— 全局异常处理,实现 actionContext 级别的异常日志收集;
-3、GlobalRoutePrefixFilter.cs —— 全局路由前缀公约,统计在路由上加上前缀;
-4、UseServiceDIAttribute.cs —— 测试注入,【暂时无用】;
-```
-文件地址在 `.\Blog.Core\Filter` 文件夹下,其中核心的是 `2` 个,重点使用的是 `1` 个 —— 全局异常错误日志 `GlobalExceptionsFilter`:
-通过注册在 `MVC` 服务 `services.AddControllers()` 中,实现全局异常过滤:
-```
- services.AddControllers(o =>
- {
- // 全局异常过滤
- o.Filters.Add(typeof(GlobalExceptionsFilter));
- // 全局路由权限公约
- //o.Conventions.Insert(0, new GlobalRouteAuthorizeConvention());
- // 全局路由前缀,统一修改路由
- o.Conventions.Insert(0, new GlobalRoutePrefixFilter(new RouteAttribute(RoutePrefix.Name)));
- })
-```
-
-
-
-## Framework
-
-项目采用 `服务+仓储+接口` 的多层结构,使用依赖注入,并且通过解耦项目,较完整的实现了 `DIP` 原则:
-高层模块不应该依赖于底层模块,二者都应该依赖于抽象。
-抽象不应该依赖于细节,细节应该依赖于抽象。
-
-同时项目也封装了:
-`CodeFirst` 初始化数据库以及数据;
-`DbFirst` 根据数据库(支持多库),生成多层代码,算是简单代码生成器;
-其他功能,[核心功能与进度](http://apk.neters.club/.doc/guide/#%E5%8A%9F%E8%83%BD%E4%B8%8E%E8%BF%9B%E5%BA%A6)
-
-
-
-
-## Log
-
-通过集成 `Log4Net` 组件,完美配合 `NetCore` 官方的 `ILogger` 接口,实现对日志的管控,引用 `nuget` 包 `Microsoft.Extensions.Logging.Log4Net.AspNetCore`:
-Program.cs
-```
- webBuilder
- .UseStartup()
- .ConfigureLogging((hostingContext, builder) =>
- {
- //该方法需要引入Microsoft.Extensions.Logging名称空间
- builder.AddFilter("System", LogLevel.Error); //过滤掉系统默认的一些日志
- builder.AddFilter("Microsoft", LogLevel.Error);//过滤掉系统默认的一些日志
-
- //添加Log4Net
- //var path = Directory.GetCurrentDirectory() + "\\log4net.config";
- //不带参数:表示log4net.config的配置文件就在应用程序根目录下,也可以指定配置文件的路径
- //需要添加nuget包:Microsoft.Extensions.Logging.Log4Net.AspNetCore
- builder.AddLog4Net();
- });
-
-```
-
-然后直接在需要的地方注入使用,比如在控制器中
-` public UserController(ILogger logger)`
-
-然后就可以使用了。
-
-> 注意:日志 其实是分为两部分的:
-> netcore输出(控制台、输出窗口等) 和 `ILogger` 持久化
-> 两者对应配置也不一样,就比如上边的过滤,是针对日志持久化的,如果想要对控制台进行控制,需要配置 `appsettings.json` 中的 `Logging` 节点
-
-
-## MemoryCache
-
-精力有限,还是更新中...
-如果你愿意帮忙,可以直接在GitHub中,提交pull request,
-我会在后边的贡献者页面里,列出你的名字和项目地址做推广
-
-## Middleware
-
-精力有限,还是更新中...
-如果你愿意帮忙,可以直接在GitHub中,提交pull request,
-我会在后边的贡献者页面里,列出你的名字和项目地址做推广
-## MiniProfiler
-
-精力有限,还是更新中...
-如果你愿意帮忙,可以直接在GitHub中,提交pull request,
-我会在后边的贡献者页面里,列出你的名字和项目地址做推广
-
-## publish
-精力有限,还是更新中...
-如果你愿意帮忙,可以直接在GitHub中,提交pull request,
-我会在后边的贡献者页面里,列出你的名字和项目地址做推广
-
-
-## Redis
-
-精力有限,还是更新中...
-如果你愿意帮忙,可以直接在GitHub中,提交pull request,
-我会在后边的贡献者页面里,列出你的名字和项目地址做推广
-## Repository
-精力有限,还是更新中...
-如果你愿意帮忙,可以直接在GitHub中,提交pull request,
-我会在后边的贡献者页面里,列出你的名字和项目地址做推广
-## SeedData
-
-精力有限,还是更新中...
-如果你愿意帮忙,可以直接在GitHub中,提交pull request,
-我会在后边的贡献者页面里,列出你的名字和项目地址做推广
-## SignalR
-
-精力有限,还是更新中...
-如果你愿意帮忙,可以直接在GitHub中,提交pull request,
-我会在后边的贡献者页面里,列出你的名字和项目地址做推广
-## SqlSugar
-
-精力有限,还是更新中...
-如果你愿意帮忙,可以直接在GitHub中,提交pull request,
-我会在后边的贡献者页面里,列出你的名字和项目地址做推广
-## SqlSugar-Codefirst&DataSeed
-
-精力有限,还是更新中...
-如果你愿意帮忙,可以直接在GitHub中,提交pull request,
-我会在后边的贡献者页面里,列出你的名字和项目地址做推广
-## SqlSugar-SqlAOP
-
-精力有限,还是更新中...
-如果你愿意帮忙,可以直接在GitHub中,提交pull request,
-我会在后边的贡献者页面里,列出你的名字和项目地址做推广
-## Swagger
-
-精力有限,还是更新中...
-如果你愿意帮忙,可以直接在GitHub中,提交pull request,
-我会在后边的贡献者页面里,列出你的名字和项目地址做推广
-## T4
-
-项目集成 `T4` 模板 `.\Blog.Core.FrameWork` 层,目的是可以一键生成项目模板代码。
-1、需要在 `DbHelper.ttinclude` 中配置连接数据库连接字符串;
-2、针对每一层的代码,就去指定的 `.tt` 模板,直接 `CTRL+S` 保存即可;
-
-> 注意,目前的代码是 `SqlServer` 版本的,其他数据库版本的,可以去群文件查看。
-
-
-## Test-xUnit
-
-项目简单使用了单元测试,通过 `xUnit` 组件,具体的可以查看 `Blog.Core.Tests` 层相关代码。
-目前单元测试用例还比较少,大家可以自行添加。
-
-
-## Temple-Nuget
-
-本项目封装了 `Nuget` 自定义模板,你可以根据这个模板,一键创建自己的项目名,具体的操作,可以双击项目根目录下的 `CreateYourProject.bat` ,可以参考 [#如何项目重命名](http://apk.neters.club/.doc/guide/getting-started.html#%E5%A6%82%E4%BD%95%E9%A1%B9%E7%9B%AE%E9%87%8D%E5%91%BD%E5%90%8D)
-
-同时,你也可以再 `Nuget` 管理器中,搜索到:
-
-
-
-
-## UserInfo
-
-
-项目中封装了获取用户信息的代码:
-在 `.\Blog.Core.Common\HttpContextUser` 文件夹下 `AspNetUser.cs` 实现类和 `IUser.cs` 接口。
-
-如果使用,首先需要注册相应的服务,参见:`.\Blog.Core\Extensions` 文件夹下的 `HttpContextSetup.cs`;
-然后,就直接在控制器构造函数中,注入接口 `IUser` 即可;
-
-> `注意`:
-> 1、如果要想获取指定的服务,必须登录,也就是必须要在 `Header` 中传递有效 `Token` ,这是肯定的。
-> 2、如果要获取用户信息,一定要在中间件 `app.UseAuthentication()` 之后(不要问为什么),控制器肯定在它之后,所以能获取到;
-> 3、`【并不是】`一定需要添加 `[Authorize]` 特性,如果你加了这个特性,可以直接获取,但是如果不加,可以从我的 `AspNetUser.cs` 方法中,有一个直接从 `Header` 中解析的方法 `List GetUserInfoFromToken(string ClaimType);`:
-
-```
- public string GetToken()
- {
- return _accessor.HttpContext.Request.Headers["Authorization"].ObjToString().Replace("Bearer ", "");
- }
-
- public List GetUserInfoFromToken(string ClaimType)
- {
-
- var jwtHandler = new JwtSecurityTokenHandler();
- if (!string.IsNullOrEmpty(GetToken()))
- {
- JwtSecurityToken jwtToken = jwtHandler.ReadJwtToken(GetToken());
-
- return (from item in jwtToken.Claims
- where item.Type == ClaimType
- select item.Value).ToList();
- }
- else
- {
- return new List() { };
- }
- }
-
-```
diff --git a/.docs/contents/guide/function-sheet.md b/.docs/contents/guide/function-sheet.md
deleted file mode 100644
index d81ad13f..00000000
--- a/.docs/contents/guide/function-sheet.md
+++ /dev/null
@@ -1,471 +0,0 @@
-# H 核心功能一览表
-
-## 一、表结构解析
-
-`Blog.Core` 项目共包含四部分的数据库表结构,分别是:用户角色管理部分、接口菜单权限管理部分、博客文章管理部分、以及其他不重要部分。
-> 注意:目前不提供与维护数据库数据,直接通过 `SeedData` 生成种子数据;
-
-### 1、用户角色管理部分[必须]
-主要是三个表:分别对应用户表(sysUserInfo)、角色表(Role)、用户角色关系表(UserRole)。
-
-
-
-
-
-### 2、接口菜单权限管理部分[必须]
-
-主要是四个表:分别对应接口表(Module)、菜单表(Permission)、接口菜单关系表(ModulePermission)暂时没用到、角色接口菜单关系表(RoleModulePermission)。
-
-
-
-
-
-
-### 3、博客文章管理部分[可选]
-主要是三个表:分别对应博客表(BlogArticle)、Bug专题表(Topic)、Bug内容表(TopicDetail)。
-
-
-
-
-
-
-### 4、其他不重要部分
-
-主要是三个表:分别对应Job调度表(TasksQz)、密码库表(PasswordLib)、操作日志表(OperateLog)、广告表(Advertisement)、公告表(Guestbook)。
-
-
-
-
-
-
-
-
-## 二、日志记录
-
-本框架涵盖了不同领域的日志记录,共五个,分别是:
-
-1、全局异常日志
-
- 开启方式:无需操作。
- 文件路径:web目录下,Log/GlobalExcepLogs_{日期}.log。
- 功能描述:记录项目启动后出现的所有异常日志,不包括中间件中异常。
-
-
-2、IP 请求日志
-
- 开启方式:无需操作。
- 文件路径:web目录下,Log/RequestIpInfoLog.log。
- 功能描述:记录项目启动后客户端请求的ip和接口信息。
- 举例来说:
- {"Ip":"xxx.xx.xx.x","Url":"/api/values","Datetime":"2020-01-06 18:02:19","Date":"2020-01-06","Week":"周一"}
-
-
-3、用户API访问日志
-
- 开启方式:appsettings.json -> Middlewar -> RecordAccessLogs 节点为true。
- 文件路径:web目录下,Log/RecordAccessLogs_{日期}.log。
- 功能描述:记录项目启动后客户端所有的API访问日志,包括参数、body以及用户信息。
-
-
-4、服务层请求响应AOP日志
-
- 开启方式:appsettings.json -> AppSettings -> LogAOP 节点为true。
- 文件路径:web目录下,Log/AOPLog.log。
- 功能描述:记录项目启动请求api后,所有的service层日志,包括方法名、参数、响应结果或用户(非必须)。
-
-
-5、数据库操作日志
-
- 开启方式:appsettings.json -> AppSettings -> SqlAOP 节点为true。
- 文件路径:web目录下,Log/SqlLog.log。
- 功能描述:记录项目启动请求api并访问service后,所有的db操作日志,包括Sql参数与Sql语句。
- 举例来说:
- --------------------------------
- 1/6/2020 6:13:04 PM|
- 【SQL参数】:@bID0:1
- 【SQL语句】:SELECT `bID`,`bsubmitter`,`btitle`,`bcategory`,`bcontent`,`btraffic`,`bcommentNum`,`bUpdateTime`,`bCreateTime`,`bRemark`,`IsDeleted` FROM `BlogArticle` WHERE ( `bID` = @bID0 )
-
-
- ## 三、控制台信息展示
-
-
-
-
-
- ## 四、Nginx一览表
-
-
-
-```
-#user nobody;
-worker_processes 1;
-
-#error_log logs/error.log;
-#error_log logs/error.log notice;
-#error_log logs/error.log info;
-
-#pid logs/nginx.pid;
-events {
- worker_connections 1024;
-}
-
-http {
- include mime.types;
- default_type application/octet-stream;
- server_names_hash_bucket_size 64;
-
- #log_format main '$remote_addr - $remote_user [$time_local] "$request" '
- # '$status $body_bytes_sent "$http_referer" '
- # '"$http_user_agent" "$http_x_forwarded_for"';
-
- #access_log logs/access.log main;
- sendfile on;
- #tcp_nopush on;
-
- #keepalive_timeout 0;
- keepalive_timeout 600;
- proxy_read_timeout 600;
- proxy_send_timeout 600;
-
- proxy_buffer_size 128k;
- proxy_buffers 32 32k;
- proxy_busy_buffers_size 128k;
-
- #gzip on;
-
- ######################################################################
- server {
- listen 80;
- server_name www.neters.club;
-
- #charset koi8-r;
-
- #access_log logs/host.access.log main;
- location / {
- root C:\code\Code\Neters\home;
- index index.html index.htm;
- }
- }
-
- server {
- listen 80;
- server_name neters.club;
-
- #charset koi8-r;
-
- #access_log logs/host.access.log main;
- location / {
- root C:\code\Code\Neters\home;
-
- index index.html index.htm;
- }
- }
-
- server {
- listen 80;
- server_name ids.neters.club;
- rewrite ^(.*)$ https://$host$1 permanent;#把http的域名请求转成https,第二种写法在此节的末端
-
- #charset koi8-r;
-
- #access_log logs/host.access.log main;
- location / {
- #proxy_pass http://localhost:5004;
- root html;
- index index.html index.htm;
- }
- }
-
- server {
- listen 443 ssl;
- server_name ids.neters.club; #网站域名,和80端口保持一致
- ssl on;
- ssl_certificate 1_ids.neters.club_bundle.crt; #证书公钥
- ssl_certificate_key 2_ids.neters.club.key; #证书私钥
- ssl_session_cache shared:SSL:1m;
- ssl_session_timeout 5m;
- ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
- ssl_ciphers ECDH:AESGCM:HIGH:!RC4:!DH:!MD5:!3DES:!aNULL:!eNULL;
- ssl_prefer_server_ciphers on;
-
- error_page 497 https://$host$uri?$args;
-
- location / {
- proxy_pass http://localhost:5004;
- proxy_redirect off;
- proxy_set_header Host $http_host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
-
- proxy_set_header Cookie $http_cookie;
- #proxy_cookie_path
- chunked_transfer_encoding off;
- }
- }
-
- server {
- listen 80;
- server_name apk.neters.club;
-
- #charset koi8-r;
-
- #access_log logs/host.access.log main;
- location / {
- root html;
- proxy_pass http://localhost:9291;
- proxy_http_version 1.1;
- proxy_set_header Upgrade $http_upgrade;
- proxy_set_header Connection keep-alive;
- proxy_set_header Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_cache_bypass $http_upgrade;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
-
- index index.html index.htm;
- }
-
- location /.doc/ {
- proxy_pass http://docs.neters.club/;
- }
- }
-
- server {
- listen 80;
- server_name docs.neters.club;
-
- location / {
- root C:\code\Code\Blog.Core\.docs\contents\.vuepress\dist;
- index index.html index.htm;
- }
- }
-
- server {
- listen 80;
- server_name vueadmin.neters.club;
-
- location / {
- try_files $uri $uri/ /index.html;
- root C:\code\Code\Blog.Admin\distis;
- #proxy_pass http://localhost:2364;
- index index.html index.htm;
- }
-
- location /api/ {
- rewrite ^.+apb/?(.*)$ /$1 break;
- include uwsgi_params;
- proxy_pass http://localhost:9291;
- proxy_http_version 1.1;
- proxy_set_header Upgrade $http_upgrade;
- #proxy_set_header Connection "upgrade";
- #proxy_set_header Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- }
-
- location /api2/ {
- rewrite ^.+apb/?(.*)$ /$1 break;
- include uwsgi_params;
- proxy_pass http://localhost:9291;
- proxy_http_version 1.1;
- proxy_set_header Upgrade $http_upgrade;
- proxy_set_header Connection "upgrade";
- proxy_set_header Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- }
-
- location /images/ {
- include uwsgi_params;
- proxy_pass http://localhost:9291;
- proxy_http_version 1.1;
- proxy_set_header Upgrade $http_upgrade;
- #proxy_set_header Connection "upgrade";
- #proxy_set_header Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- }
- location /.doc/ {
- proxy_pass http://docsadmin.neters.club/;
- }
-
- error_page 404 /404.html;
-
- # redirect server error pages to the static page /50x.html
- #
- error_page 500 502 503 504 /50x.html;
- location = /50x.html {
- root html;
- }
- }
-
- server {
- listen 80;
- server_name docsadmin.neters.club;
-
- location / {
- root C:\code\Code\Blog.Admin\.doc\contents\.vuepress\dist;
- index index.html index.htm;
- }
- }
-
-
- server {
- listen 80;
- server_name ddd.neters.club;
- location / {
- proxy_pass http://localhost:4773;
- index index.php index.html index.htm;
- proxy_set_header Upgrade $http_upgrade;
- proxy_set_header Connection keep-alive;
- proxy_set_header Host $host;
- proxy_cache_bypass $http_upgrade;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto $scheme;
-
- }
- }
-
-
- server {
- listen 80;
- server_name ask.neters.club;
-
- #charset koi8-r;
-
- #access_log logs/host.access.log main;
- location / {
- root html;
- proxy_pass http://localhost:5020;
- proxy_http_version 1.1;
- proxy_set_header Upgrade $http_upgrade;
- #proxy_set_header Connection "upgrade";
- #proxy_set_header Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- index index.html index.htm;
- }
- }
-
-
- server {
- listen 80;
- server_name vueblog.neters.club;
-
- location / {
- try_files $uri $uri/ /index.html;
- root C:\code\Code\Blog.Vue\dist;
- index index.html index.htm;
- }
-
-
- location /api {
- rewrite ^.+apb/?(.*)$ /$1 break;
- include uwsgi_params;
- proxy_pass http://localhost:9291;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- }
-
-
- location /images {
- include uwsgi_params;
- proxy_pass http://localhost:9291;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- }
-
- error_page 404 /404.html;
-
- # redirect server error pages to the static page /50x.html
- #
- error_page 500 502 503 504 /50x.html;
- location = /50x.html {
- root html;
- }
- }
-
- upstream nodenuxt {
- server 127.0.0.1:3089; # nuxt 项目监听PC端端口
- keepalive 64;
- }
- server {
- listen 80;
- server_name tibug.neters.club;
-
- location / {
- proxy_http_version 1.1;
- proxy_set_header Upgrade $http_upgrade;
- proxy_set_header Connection "upgrade";
- proxy_set_header Host $host;
- proxy_set_header X-Nginx-Proxy true;
- proxy_cache_bypass $http_upgrade;
- proxy_pass http://nodenuxt;
- }
-
- error_page 500 502 503 504 /50x.html;
- location = /50x.html {
- root html;
- }
- }
-
- server {
- listen 80;
- server_name jwt.neters.club;
-
- location / {
- root C:\code\Code\jwttoken;
- index index.html index.htm;
- }
-
- error_page 404 /404.html;
-
- # redirect server error pages to the static page /50x.html
- #
- error_page 500 502 503 504 /50x.html;
- location = /50x.html {
- root html;
- }
- }
-}
-
-```
-> 这里说明下,我的 `Nginx` 文件中,`Ids4` 项目强制使用 `Https` ,采用的是直接跳转,这也是一个办法,当然还有第二种办法(感谢 `tibos`):
-```
-server {
- listen 80;
- server_name admin.wmowm.com;
- location / {
- proxy_pass http://localhost:9002;
- index index.php index.html index.htm;
- proxy_set_header Upgrade $http_upgrade;
- proxy_set_header Connection keep-alive;
- proxy_set_header Host $host;
- proxy_cache_bypass $http_upgrade;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto $scheme;
-
- }
-}
-
-server {
- listen 443 ssl;#监听443端口(https默认端口)
- server_name admin.wmowm.com; #填写绑定证书的域名
- ssl_certificate /etc/nginx/conf.d/key/admin.wm.crt;#填写你的证书所在的位置
- ssl_certificate_key /etc/nginx/conf.d/key/admin.wm.key;#填写你的key所在的位置
- ssl_session_timeout 5m;
- ssl_protocols TLSv1 TLSv1.1 TLSv1.2; #按照这个协议配置
- ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;#按照这个套件配置
- ssl_prefer_server_ciphers on;
- location / {
- proxy_pass http://localhost:9002;
- index index.php index.html index.htm;
- proxy_set_header Upgrade $http_upgrade;
- proxy_set_header Connection keep-alive;
- proxy_set_header Host $host;
- proxy_cache_bypass $http_upgrade;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto $scheme;
- }
-
-}
-```
\ No newline at end of file
diff --git a/.docs/contents/guide/getting-started.md b/.docs/contents/guide/getting-started.md
deleted file mode 100644
index 9c4f6b0d..00000000
--- a/.docs/contents/guide/getting-started.md
+++ /dev/null
@@ -1,132 +0,0 @@
-# K 快速上手
-注意
-
-请确保你的 `Visual Studio 2019` 版本 >= `16.8.2`。
-并安装 `.NET 5.0 SDK`
-
-
-## 下载
-Github(国际) 下载 [https://github.com/anjoy8/Blog.Core](https://github.com/anjoy8/Blog.Core)
-
-Gitee(国内) 下载 [https://gitee.com/laozhangIsPhi/Blog.Core](https://gitee.com/laozhangIsPhi/Blog.Core)
-
-
-## 编译与运行
-1、拿到项目后,双击 `Blog.Core.sln` 解决方案;
-2、首先 `F6` 编译,看是否有错误;
-3、然后 `F5` 运行,调起 `9291` 端口,浏览器查看效果;
-4、因为系统默认的是 `sqlite` 数据库,如果你想换其他数据库,请看下边;
-5、注意:本系统是直接自动生成数据库和数据的,不用手动创建数据库;
-
-
-
-
-## CodeFirst 与 DbFirst
-1、项目同时支持两个常见开发模式:`CodeFirst` 和 `DbFirst`;
-2、首先 如果你是第一次下载我的项目,肯定是想要浏览效果和直接使用对应的权限相关的内容,这个时候肯定需要用到数据库表结构,那就肯定需要 `CodeFirst` ,只需要在`appsettings.json` 里配置好数据库连接字符串(下文会说到如何配置),就能正确运行;
-3、浏览器查看效果,或者配合 `Admin` 项目查看效果后,如果感觉项目可行,并打算在此基础上二次开发,那肯定会在你刚刚创建的数据库种去创建新的表结构,这个时候就需要使用 `DbFirst` 模式,来生成四层项目问题:Model+Service+Repository等;
-4、你可以使用T4模板,但是我更建议使用 `/api/DbFirst/GetFrameFiles` 接口来生成,不仅支持多种类型的数据库,还支持同时多库模式的输出;
-5、如果你不想用我的表结构和实体类,在项目启动的时候,把配置文件的 `SeedDBEnabled`节点设置成False即可,然后配置对应的你自己的数据库连接字符串,比如是商城的,然后使用 `/api/DbFirst/GetFrameFiles` 接口来生成你的数据库四层类文件;
-
-
-
-## 如何配置数据库连接字符串
-
-1、打开 `Blog.Core` 项目下的 `appsettings.json` 文件;
-2、修改 `DBS` 字节内容,配置对应的连接字符串,注意`DBType`对应不同的数据库类型;
-3、把你想要运行的数据库 `Enabled` 为 `true` 即可,其他都要设置 `false`;
-4、然后 `MainDB` 设置为下边你使用的指定 `ConnId`:
-
-```
- "MainDB": "WMBLOG_MSSQL", //当前项目的主库,所对应的连接字符串的Enabled必须为true
- "MutiDBEnabled": false, //是否开启多库
- "DBS": [
- {
- "ConnId": "WMBLOG_SQLITE",
- "DBType": 2,// sqlite数据库
- "Enabled": true,// 设置为true,启用1
- "Connection": "WMBlog.db" //只写数据库名就行
- },
- {
- "ConnId": "WMBLOG_MSSQL",
- "DBType": 1,// sqlserver数据库
- "Enabled": true,// 设置为true,启用2
- "Connection": "Server=.;Database=WMBlogDB;User ID=sa;Password=123;",
- "ProviderName": "System.Data.SqlClient"
- },
- {
- "ConnId": "WMBLOG_MYSQL",
- "DBType": 0,// mysql
- "Enabled": false,// false 不启用
- "Connection": "Server=localhost; Port=3306;Stmt=; Database=wmblogdb; Uid=root; Pwd=456;"
- },
- {
- "ConnId": "WMBLOG_ORACLE",
- "DBType": 3,// Oracle
- "Enabled": false,// 不启用
- "Connection": "Provider=OraOLEDB.Oracle; Data Source=WMBlogDB; User Id=sss; Password=789;"
- }
- ],
-```
-
-
-5、如果你想多库操作,需要配置
-```
- a:MainDB 设置为主库的 ConnId;
- b:MutiDBEnabled设置为true,
- c:把下边想要连接的多个连接字符串都设置为true
-```
-
-## 如何配置项目端口号
-1、在 `Blog.Core` 层下的 `program.cs` 文件中,将 `9291`端口,修改为自己想要的端口号;
-2、或者在 `launchSettings.json` 中设置(`注意,如果仅仅修改这里,publish后,端口访问无效`);
-
-## 如何项目重命名
-1、双击项目根目录下的 `CreateYourProject.bat` 批处理文件;
-2、根据提示,`在Dos窗口内`输入自己想要的项目名称即可;
-3、在根目录会有一个 `.1YourProject` 文件夹,里边即你的项目;
-
-
-## 新增实体模块后如何迁移到数据库
-1、在 `Blog.Core.Model` 项目目录下的 `Seed` 文件夹下,找到 `DBSeed` 类;
-2、根据提示,找到生成table的地方 `myContext.CreateTableByEntity`;
-3、添加进去你新增的实体类,当然也可以用下边的单独写法;
-4、编译项目,没错后,运行,则数据库更新完毕;
-
-
-## 新增实体,如何进行增删改查CURD操作
-1、随便找一个含有业务逻辑的 `controller` 参考一下即可;
-2、主要 `api` 是通过 `Service` 服务层提供业务逻辑;
-3、然后服务层通过 `Repository` 仓储层封装持久化操作;
-4、每一个表基本上对应一个仓储类,基本的操作都封装到了 `BaseRepository.cs` 基类仓储中;
-5、添加完业务逻辑,记得要 `F6` 重新编译一下,因为项目间引用解耦了;
-6、项目已经自动注入了,直接在控制器使用对应的服务层接口就行: `IxxxxService` ;
-
-
-## 新增数据库表,如何反向生成四层文件
-1、可以通过 `T4` 模板来生成,在 `Blog.Core.FrameWork` 层,使用方法: [9757999.html](https://www.cnblogs.com/laozhang-is-phi/p/9757999.html#autoid-4-3-0) ;
-> 注意:这种方案,目前默认的只能是 `SqlServer` ,其他类型的数据库,可以看上边文章中的代码,或者群文件里对应的代码。
-
-> 1、修改`DbHelper.ttinclude`文件中的连接字符串,注意是`SqlServer`的: public static readonly string ConnectionString;
-> 2、然后去各个层模板文件,点击`Ctrl+S`;
-> 3、就会在对应的层内,看到新文件,比如:Blog.Core.Model/Model_NEW
-
-
-
-2、也可以通过 `Sqlsugar` 所带的方法来实现 `DbFirst`,具体查看 `Controller` 层下的 `DbFirstController.cs`;
-
-3、总体操作过程,可以参考我的视频:[av77612407](https://www.bilibili.com/video/av77612407?p=2) ;
-
-
-## 发布与部署
-1、双击项目根目录下的 `Blog.Core.Publish.bat`批处理文件;
-2、执行完成后,根目录会有一个`.PublishFiles` 文件夹,就是发布后的项目;
-
-
-## 如何更新项目模板
-1、着急的话自己打包,不着急就提 `issue`,等我更新;
-2、我的开源项目中,有个模板项目 `BlogCoreTempl` [地址](https://github.com/anjoy8/BlogCoreTempl),下载下来;
-3、下载最新的 `Blog.Core` 源代码;
-4、将源代码拷贝到模板项目的 `content` 文件夹下;
-5、双击 `Package.bat` 文件,就生成了最新的模板了;
-
diff --git a/.docs/package.json b/.docs/package.json
deleted file mode 100644
index 3f0483bf..00000000
--- a/.docs/package.json
+++ /dev/null
@@ -1,12 +0,0 @@
-{
- "name": "BCVP",
- "version": "1.0.0",
- "description": "",
- "main": "index.js",
- "scripts": {
- "test": "echo \"Error: no test specified\" && exit 1"
- },
- "keywords": [],
- "author": "",
- "license": "ISC"
-}
diff --git a/.gitignore b/.gitignore
index de419c90..97072da3 100644
--- a/.gitignore
+++ b/.gitignore
@@ -358,3 +358,4 @@ Blog.Core.Api/wwwroot/ui/
Blog.Core.Api/Logs
*.db
/Blog.Core.Api/WMBlog.db-journal
+.docs/.vuepress/dist/