mirror of
https://github.com/anjoy8/Blog.Core.git
synced 2024-09-20 23:48:27 +08:00
feat:将官方文档迁移到新库
This commit is contained in:
parent
c93c3eb44b
commit
1b3ab297f3
2
.docs/README.md
Normal file
2
.docs/README.md
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
BlogCore官方文档仓库地址已经迁移到:
|
||||||
|
https://gitee.com/laozhangIsPhi/Blog.Core.E-Book
|
|
@ -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'
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
Binary file not shown.
Before Width: | Height: | Size: 5.5 KiB |
Binary file not shown.
Before Width: | Height: | Size: 1.5 KiB |
|
@ -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||
|
|
||||||
|
|
||||||
|
|
|
@ -1,80 +0,0 @@
|
||||||
# 框架压测报告
|
|
||||||
|
|
||||||
|
|
||||||
## 1、测试工具
|
|
||||||
使用 `JMeter` 进行压力测试。
|
|
||||||
测试时间:2021年1月21日 09点38分。
|
|
||||||
服务器报告:
|
|
||||||
<img src="https://img.neters.club/doc/report.png" />
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## 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信息请求管理器:无
|
|
||||||
响应断言:无
|
|
||||||
|
|
||||||
<img src="https://img.neters.club/doc/config.png" />
|
|
||||||
|
|
||||||
## 4、项目初始化
|
|
||||||
目前采用 `Blog.Core` 默认的配置,
|
|
||||||
只开启了内存 `AOP` ,
|
|
||||||
其他的都是默认的,然后也把任务调度也关闭了,
|
|
||||||
最后注意要把 `IP限流`给关闭,不然压测没效果,因为限流了:
|
|
||||||
<img src="https://img.neters.club/doc/init.png" />
|
|
||||||
|
|
||||||
|
|
||||||
## 5、压测过程
|
|
||||||
|
|
||||||
##### 第一阶段
|
|
||||||
|
|
||||||
<img src="https://img.neters.club/doc/test01.png" />
|
|
||||||
|
|
||||||
|
|
||||||
##### 第二阶段
|
|
||||||
|
|
||||||
<img src="https://img.neters.club/doc/test02.png" />
|
|
||||||
|
|
||||||
|
|
||||||
##### 第三阶段
|
|
||||||
|
|
||||||
<img src="https://img.neters.club/doc/test03.png" />
|
|
||||||
|
|
||||||
|
|
||||||
##### 第四阶段(压测后,检测内存是否降低,20m后)
|
|
||||||
<img src="https://img.neters.club/doc/test04.png" />
|
|
||||||
|
|
||||||
|
|
||||||
##### 第五阶段(停止压测1h后)
|
|
||||||
<img src="https://img.neters.club/doc/test_05.png" />
|
|
||||||
|
|
||||||
|
|
||||||
## 6、测试结果
|
|
||||||
内存方面,`100*1000` 的 **压测过程中** (写操作),项目保证所占内存在 `350m~500m` 之间
|
|
||||||
然后停止一个小时后,内存将为`150m~200m`:
|
|
||||||
|
|
||||||
<img src="https://img.neters.club/doc/test04.png" />
|
|
||||||
|
|
||||||
<img src="https://img.neters.club/doc/test_05.png" />
|
|
||||||
|
|
||||||
|
|
||||||
## 7、压测配置文件下载
|
|
||||||
[配置文件](https://img.neters.club/doc/blogcore_blog_ApacheTestUpdate.jmx)
|
|
||||||
下载后,导入到工具里,可以直接测试,察看结果树。
|
|
||||||
|
|
||||||
## 8、Docker 镜像
|
|
||||||
已经提交到 `docker hub` 自行拉取操作即可:
|
|
||||||
```
|
|
||||||
docker pull laozhangisphi/apkimg:latest
|
|
||||||
```
|
|
|
@ -1,18 +0,0 @@
|
||||||
## 开源社区
|
|
||||||
|
|
||||||
<img src="http://apk.neters.club/.doc/bcvphomelogo.png" alt="bcvp" width="200" >
|
|
||||||
|
|
||||||
[https://github.com/BaseCoreVueProject/Home](https://github.com/BaseCoreVueProject/Home)
|
|
||||||
|
|
||||||
Base netCore (Vue) Project Team,
|
|
||||||
基于Net/Core 和Vue(react/ng),快速搭建 MVC & SPA 及微服务应用
|
|
||||||
如果你有关于dotNet/core 的,不错的,可以正常运行,且一年内维护的,均可以加入。
|
|
||||||
唯一宗旨:我们来自社区,服务社区,反哺社区。
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## 微信公众号
|
|
||||||
|
|
||||||
<img src="https://img.neters.club/doc/WeChat%20Screenshot_20200624194936.png" alt="公众号" width="600" >
|
|
||||||
|
|
||||||
|
|
|
@ -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
|
|
||||||
---
|
|
|
@ -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<T>`, [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限流,防止过多刷数据
|
|
|
@ -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 实现认证中心;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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` 包:
|
|
||||||
```
|
|
||||||
<PackageReference Include="AspNetCoreRateLimit" Version="3.0.5" />
|
|
||||||
```
|
|
||||||
|
|
||||||
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<string, string> {
|
|
||||||
{
|
|
||||||
"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` 中,配置登录授权:
|
|
||||||
|
|
||||||
<img src="http://apk.neters.club/images/20200507213830.png" alt="swagger" width="600" >
|
|
||||||
|
|
||||||
|
|
||||||
## 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
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// 配置构造函数,用来创建关系映射
|
|
||||||
/// </summary>
|
|
||||||
public CustomProfile()
|
|
||||||
{
|
|
||||||
CreateMap<BlogArticle, BlogViewModels>();
|
|
||||||
CreateMap<BlogViewModels, BlogArticle>();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// 比如如何使用
|
|
||||||
models = _mapper.Map<BlogViewModels>(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、引用依赖包:
|
|
||||||
```
|
|
||||||
<PackageReference Include="Autofac.Extensions.DependencyInjection" Version="5.0.1" />
|
|
||||||
<PackageReference Include="Autofac.Extras.DynamicProxy" Version="4.5.0" />
|
|
||||||
|
|
||||||
```
|
|
||||||
主要是第一个 `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<AdvertisementServices>().As<IAdvertisementServices>();
|
|
||||||
|
|
||||||
|
|
||||||
#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<Type>();
|
|
||||||
if (Appsettings.app(new string[] { "AppSettings", "RedisCachingAOP", "Enabled" }).ObjToBool())
|
|
||||||
{
|
|
||||||
builder.RegisterType<BlogRedisCacheAOP>();
|
|
||||||
cacheType.Add(typeof(BlogRedisCacheAOP));
|
|
||||||
}
|
|
||||||
if (Appsettings.app(new string[] { "AppSettings", "MemoryCachingAOP", "Enabled" }).ObjToBool())
|
|
||||||
{
|
|
||||||
builder.RegisterType<BlogCacheAOP>();
|
|
||||||
cacheType.Add(typeof(BlogCacheAOP));
|
|
||||||
}
|
|
||||||
if (Appsettings.app(new string[] { "AppSettings", "TranAOP", "Enabled" }).ObjToBool())
|
|
||||||
{
|
|
||||||
builder.RegisterType<BlogTranAOP>();
|
|
||||||
cacheType.Add(typeof(BlogTranAOP));
|
|
||||||
}
|
|
||||||
if (Appsettings.app(new string[] { "AppSettings", "LogAOP", "Enabled" }).ObjToBool())
|
|
||||||
{
|
|
||||||
builder.RegisterType<BlogLogAOP>();
|
|
||||||
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<IHttpContextAccessor, HttpContextAccessor>();
|
|
||||||
// 注入权限处理器
|
|
||||||
services.AddScoped<IAuthorizationHandler, PermissionHandler>();
|
|
||||||
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<T>` 接口,实现对日志的管控,引用 `nuget` 包 `Microsoft.Extensions.Logging.Log4Net.AspNetCore`:
|
|
||||||
Program.cs
|
|
||||||
```
|
|
||||||
webBuilder
|
|
||||||
.UseStartup<Startup>()
|
|
||||||
.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<UserController> 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` 管理器中,搜索到:
|
|
||||||
<img src="http://apk.neters.club/images/20200507223058.png" alt="nuget" width="600" >
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## 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<string> GetUserInfoFromToken(string ClaimType);`:
|
|
||||||
|
|
||||||
```
|
|
||||||
public string GetToken()
|
|
||||||
{
|
|
||||||
return _accessor.HttpContext.Request.Headers["Authorization"].ObjToString().Replace("Bearer ", "");
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<string> 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<string>() { };
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
```
|
|
|
@ -1,471 +0,0 @@
|
||||||
# H 核心功能一览表
|
|
||||||
|
|
||||||
## 一、表结构解析
|
|
||||||
|
|
||||||
`Blog.Core` 项目共包含四部分的数据库表结构,分别是:用户角色管理部分、接口菜单权限管理部分、博客文章管理部分、以及其他不重要部分。
|
|
||||||
> 注意:目前不提供与维护数据库数据,直接通过 `SeedData` 生成种子数据;
|
|
||||||
|
|
||||||
### 1、用户角色管理部分[必须]
|
|
||||||
主要是三个表:分别对应用户表(sysUserInfo)、角色表(Role)、用户角色关系表(UserRole)。
|
|
||||||
|
|
||||||
<img src="http://img.neters.club/doc/usermanager.png" alt="usermanager" >
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### 2、接口菜单权限管理部分[必须]
|
|
||||||
|
|
||||||
主要是四个表:分别对应接口表(Module)、菜单表(Permission)、接口菜单关系表(ModulePermission)暂时没用到、角色接口菜单关系表(RoleModulePermission)。
|
|
||||||
|
|
||||||
<img src="http://img.neters.club/doc/permissionmanager.png" alt="permissionmanager" >
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### 3、博客文章管理部分[可选]
|
|
||||||
主要是三个表:分别对应博客表(BlogArticle)、Bug专题表(Topic)、Bug内容表(TopicDetail)。
|
|
||||||
|
|
||||||
<img src="http://img.neters.club/doc/blogmanager.png" alt="blogmanager" >
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### 4、其他不重要部分
|
|
||||||
|
|
||||||
主要是三个表:分别对应Job调度表(TasksQz)、密码库表(PasswordLib)、操作日志表(OperateLog)、广告表(Advertisement)、公告表(Guestbook)。
|
|
||||||
|
|
||||||
<img src="http://img.neters.club/doc/othersmanager.png" alt="othersmanager" >
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## 二、日志记录
|
|
||||||
|
|
||||||
本框架涵盖了不同领域的日志记录,共五个,分别是:
|
|
||||||
|
|
||||||
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 )
|
|
||||||
|
|
||||||
|
|
||||||
## 三、控制台信息展示
|
|
||||||
|
|
||||||
<img src="https://img.neters.club/doc/2020-05-09_182758.png" alt="配置" width="800" >
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## 四、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;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
```
|
|
|
@ -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` 文件,就生成了最新的模板了;
|
|
||||||
|
|
|
@ -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"
|
|
||||||
}
|
|
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -358,3 +358,4 @@ Blog.Core.Api/wwwroot/ui/
|
||||||
Blog.Core.Api/Logs
|
Blog.Core.Api/Logs
|
||||||
*.db
|
*.db
|
||||||
/Blog.Core.Api/WMBlog.db-journal
|
/Blog.Core.Api/WMBlog.db-journal
|
||||||
|
.docs/.vuepress/dist/
|
||||||
|
|
Loading…
Reference in New Issue
Block a user