commit ef69cb5d5bd12c55e19f11989c55dc2230c6616f
Author: 易大师 <156663459@qq.com>
Date: Fri Jan 29 13:00:03 2021 +0800
first commit init
diff --git a/.dockerignore b/.dockerignore
new file mode 100644
index 0000000..3729ff0
--- /dev/null
+++ b/.dockerignore
@@ -0,0 +1,25 @@
+**/.classpath
+**/.dockerignore
+**/.env
+**/.git
+**/.gitignore
+**/.project
+**/.settings
+**/.toolstarget
+**/.vs
+**/.vscode
+**/*.*proj.user
+**/*.dbmdl
+**/*.jfm
+**/azds.yaml
+**/bin
+**/charts
+**/docker-compose*
+**/Dockerfile*
+**/node_modules
+**/npm-debug.log
+**/obj
+**/secrets.dev.yaml
+**/values.dev.yaml
+LICENSE
+README.md
\ No newline at end of file
diff --git a/.docs/contents/.vuepress/config.js b/.docs/contents/.vuepress/config.js
new file mode 100644
index 0000000..982fb80
--- /dev/null
+++ b/.docs/contents/.vuepress/config.js
@@ -0,0 +1,46 @@
+module.exports = {
+ title: 'New_College',
+ 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: '社区', link: '/QQ/' },
+ { text: '接口API', link: 'http://apk.neters.club' },
+ { text: '管理后台', link: 'http://vueadmin.neters.club' },
+ { text: 'Github', link: 'https://github.com/anjoy8/New_College' },
+ ],
+ 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
new file mode 100644
index 0000000..e1bf0f7
Binary files /dev/null and b/.docs/contents/.vuepress/public/bcvphomelogo.png differ
diff --git a/.docs/contents/.vuepress/public/favicon.ico b/.docs/contents/.vuepress/public/favicon.ico
new file mode 100644
index 0000000..68062fe
Binary files /dev/null and b/.docs/contents/.vuepress/public/favicon.ico differ
diff --git a/.docs/contents/Contribution/README.md b/.docs/contents/Contribution/README.md
new file mode 100644
index 0000000..492e70b
--- /dev/null
+++ b/.docs/contents/Contribution/README.md
@@ -0,0 +1,84 @@
+# 贡献
+
+
+欢迎一起完善文档,
+参与打赏的小可爱名单如下(单位:元),你们的贡献是我继续的动力:
+(2020年8月6日 10点47分)
+
+
+|序号|微信昵称|助力值|备注|
+|-|-|-|-|
+|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||
+
+
+
+
+
+
+## 参与贡献的开源项目
+
+如果帮忙以前完善文档,可以在这里留下你的开源项目,做推广。
+
+```
+1、https://github.com/GeorGeWzw/Sukt.Core(作者:kawhi)
+2、https://github.com/wmowm/Gourd(作者:提伯斯)
+3、https://github.com/GeorGeWzw/Destiny.Core.Flow(作者:大黄瓜|kawhi)备注:重写的Identity的用户角色
+
+
+```
\ No newline at end of file
diff --git a/.docs/contents/PressureTest/README.md b/.docs/contents/PressureTest/README.md
new file mode 100644
index 0000000..5a5247c
--- /dev/null
+++ b/.docs/contents/PressureTest/README.md
@@ -0,0 +1,54 @@
+# 框架压测报告
+
+
+## 1、测试工具
+使用 `JMeter` 进行压力测试。
+测试时间:2020年7月1日 13点14分。
+服务器报告:
+
+
+
+
+## 2、测试准备
+因为 `JMeter` 是使用 `JAVA` 写的,所以使用 `JMeter` 之前,先安装 `JAVA` 环境。
+安装好后,在 `bin` 文件夹下,点击 `jmeter.bat` 启动程序。
+启动之后会有两个窗口,一个cmd窗口,一个JMeter的 GUI。前面不要忽略CMD窗口的提示信息,不要关闭它。
+
+## 3、配置数据
+本地发布后的 `windows` 环境,直接用 `kestrel` 启动。
+线程数:100
+循环数:10000
+HTTP默认值:协议:`http`;服务器或IP:`localhost`;端口号:`8081`;
+HTTP请求:方法:GET;路径:`/api/blog/ApacheTestUpdate`
+HTTP信息请求管理器:无
+响应断言:无
+
+
+
+## 项目配置
+目前采用 `New_College` 默认的配置,
+开启了内存 `AOP` 和日志 `AOP`,
+其他的都是默认的,然后也把任务调度也关闭了,
+最后注意要把 `IP限流`给关闭,不然压测没效果,因为限流了:
+
+
+
+## 压测结果
+1、为了显示正确性,我用动图,来显示日志生成情况,整个阶段无任何异常:
+
+
+
+
+2、内存方面,`100*10000` 的压测过程中,项目保证所占内存在 `160~220m` 之间:
+
+
+
+## 压测配置文件下载
+ [配置文件](https://img.neters.club/doc/new_collegetest.jmx)
+ 下载后,导入到工具里,可以直接测试,察看结果树。
+
+ ## Docker 镜像
+ 已经提交到 `docker hub` 自行拉取操作即可:
+ ```
+ docker pull laozhangisphi/apkimg:latest
+ ```
\ No newline at end of file
diff --git a/.docs/contents/QQ/README.md b/.docs/contents/QQ/README.md
new file mode 100644
index 0000000..485261c
--- /dev/null
+++ b/.docs/contents/QQ/README.md
@@ -0,0 +1,11 @@
+## QQ 群
+
+
+
+
+
+## 微信公众号
+
+
+
+
diff --git a/.docs/contents/README.md b/.docs/contents/README.md
new file mode 100644
index 0000000..e7e1b12
--- /dev/null
+++ b/.docs/contents/README.md
@@ -0,0 +1,14 @@
+---
+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-老张的哲学
+---
\ No newline at end of file
diff --git a/.docs/contents/Update/README.md b/.docs/contents/Update/README.md
new file mode 100644
index 0000000..b8cdfca
--- /dev/null
+++ b/.docs/contents/Update/README.md
@@ -0,0 +1,121 @@
+
+## 更新日志
+
+### 2020-08-06
+
+项目更新:更新项目模板 `Update New_College.Webapi.Template.2.2.0.nupkg` 。
+> 1、根据解决方案名,来自动导入model;
+> 2、单独封装服务扩展层 `New_College.Extensions` ;
+> 3、代码生成器,支持控制器文件的生成;
+> 4、弱化仓储层,用泛型仓储基类注入服务;
+
+
+
+
+### 2020-08-01
+
+> 重大结构更新:弱化仓储层,通过泛型仓储基类,来实现仓储服务注入,并去掉`New_College.IRepository` 接口层;
+
+### 2020-07-03
+
+> 更新:`DbFirstController` 生成四层文件,目前新增支持 `控制器Controller` 文件的输出;
+
+
+### 2020-06-22
+
+> 项目更新:将服务扩展和自定义中间件,单独封装一层 `New_College.Extensions` ,更解耦。
+
+
+
+### 2020-06-08
+
+> 简单项目更新:生成数据库表结构的时候,利用反射机制,自动生成固定命名空间 `New_College.Model.Models` 下的全部实体.
+> 同时判断表是否存在,如果存在下次不再重复生成。
+
+
+### 2020-06-06
+
+项目更新:更新项目模板 `Update New_College.Webapi.Template.2.1.0.nupkg` [1a726f8](https://github.com/anjoy8/New_College/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/New_College/commit/102c6d6bfcafd06bf5241844759dea5e7a6815da)
+> 注意:`T4` 模板不能此功能,一次只能一个数据库,且只能 `SqlServer`
+
+
+### 2020-05-07
+> 重大内容更新:更新项目模板 `Update New_College.Webapi.Template.2.1.0.nupkg` [7f64fde](https://github.com/anjoy8/New_College/commit/7f64fde5507f7a8572372dcadb6af5110bd37d68)
+
+
+### 2020-05-06
+> 重大内容更新:优化Log4Net使用方案,完美配合 `NetCore` 官方的 `ILogger`, [ecaffb6](https://github.com/anjoy8/New_College/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 New_College.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
new file mode 100644
index 0000000..adcccf9
--- /dev/null
+++ b/.docs/contents/guide/README.md
@@ -0,0 +1,89 @@
+# J 介绍
+
+最新的前后端完全分离框架【 ASP.NET Core 3.1 Api + Vue 2.x + ele】。
+ASP.NET Core 3.1 教程,前后端分离的后端接口,vue教程的姊妹篇。
+BCVP(New_College&Vue Project)开箱即用的企业级前后端分离【 .NET Core3.1 Api + Vue 2.x + RBAC】权限框架。
+
+## 你能得到什么?
+1、从 0 到 1 快速入门 ASP.NET Core 框架。
+2、掌握开发中的常用知识点,为跨平台、微服务打好基础。
+3、下载即用,简单高效开发属于自己公司项目,配置简单,功能完善。
+
+
+
+## 功能与进度
+
+- [√] 采用仓储+服务+接口的形式封装框架;
+- [√] 使用Swagger做api文档;
+- [√] 使用MiniProfiler做接口性能分析;
+- [√] 使用Automapper做Dto处理;
+- [√] 接入SqlSugar ORM,封装数据库操作;
+- [√] 项目启动,自动生成seed种子数据;
+- [√] 提供五种日志输出;
+- [√] 支持自由切换多种数据库,Sqlite/SqlServer/MySql/PostgreSQL/Oracle;
+- [√] 异步async/await开发;
+- [√] 支持事务;
+- [√] AutoFac接入做依赖注入;
+- [√] 支持AOP切面编程;
+- [√] 支持CORS跨域;
+- [√] 支持T4代码模板,自动生成每层代码;
+- [√] 支持一键创建自己项目;
+- [√] 封装 JWT 自定义策略授权;
+- [√] 使用Log4Net日志框架+自定义日志输出;
+- [√] 使用SingleR推送日志信息到管理后台;
+- [√] 搭配前端Blog项目,vue开发;
+- [√] 搭配一个Admin管理后台,用vue+ele开发;
+- [√] IdentityServer4 认证;
+- [√] API 限速;
+- [√] 作业调度 Quartz.net;
+- [√] Sqlsugar 读写分离;
+- [ ] Redis 队列;
+- [ ] 支付;
+- [ ] 数据部门权限;
+
+
+
+## 它是如何工作的?
+
+这是一个基于 ASP.NET Core 3.1 的 api 项目,配合搭建 VUE 实现前后端分离工程。
+
+**************************************************************
+系统环境
+
+> windows 10、SQL server 2012、Visual Studio 2017、Windows Server 2008 R2
+
+后端技术:
+
+> 1、ASP.NET Core 3.1 API
+ 2、Swagger 前后端文档说明,基于RESTful风格编写接口
+ 3、Repository + Service 仓储模式编程
+ 4、Async和Await 异步编程
+ 5、CORS 简单的跨域解决方案
+ 6、AOP基于切面编程技术
+ 7、Autofac 轻量级IoC和DI依赖注入
+ 8、Vue 本地代理跨域方案,Nginx跨域代理
+ 9、JWT权限验证
+10、Filter 过滤器
+11、Middleware 中间件
+12、AutoMapper 自动对象映射
+13、Redis
+
+
+数据库技术
+
+> SqlSugar 轻量级ORM框架,CodeFirst
+ T4 模板生成框架结构
+ 支持SqlServer、Mysql、Sqlite、Oracle、Pgql数据库
+ 支持多库操作
+
+
+
+
+前端技术
+
+> Vue 2.x 框架全家桶 Vue2 + VueRouter2 + Webpack + Axios + vue-cli + vuex
+ElementUI 基于Vue 2.0的组件库
+Nuxt.js服务端渲染SSR
+
+
+
diff --git a/.docs/contents/guide/cheat-sheet.md b/.docs/contents/guide/cheat-sheet.md
new file mode 100644
index 0000000..6f6dd6a
--- /dev/null
+++ b/.docs/contents/guide/cheat-sheet.md
@@ -0,0 +1,580 @@
+# Z 主要知识点
+
+
+
+## AOP
+
+本项目多处采用面向切面编程思想——AOP,除了广义上的过滤器和中间件以外,主要通过动态代理的形式来实现AOP编程思想,主要的案例共有四个,分别是:
+1、服务日志AOP;
+2、服务InMemory缓存AOP;
+3、服务Redis缓存AOP;
+4、服务事务AOP;
+
+
+具体的代码可以在 `New_College\New_College\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` 文件,
+操作类地址在:`\New_College.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` 项目等一起,使用一个统一的认证中心。
+
+具体的代码参考:`.\New_College\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 {
+ {
+ "new_college.api","ApiResource id"
+ }
+ }
+ }
+ }
+ });
+
+```
+
+然后在 `IdentityServer4` 项目中,做指定的修改,配置 `8081` 的回调地址:
+
+```
+ new Client {
+ ClientId = "blogadminjs",
+ ClientName = "Blog.Admin JavaScript Client",
+ AllowedGrantTypes = GrantTypes.Implicit,
+ AllowAccessTokensViaBrowser = true,
+
+ RedirectUris =
+ {
+ "http://vueadmin.neters.club/callback",
+ // 这里要配置回调地址
+ "http://localhost:8081/oauth2-redirect.html"
+ },
+ PostLogoutRedirectUris = { "http://vueadmin.neters.club" },
+ AllowedCorsOrigins = { "http://vueadmin.neters.club" },
+
+ AllowedScopes = {
+ IdentityServerConstants.StandardScopes.OpenId,
+ IdentityServerConstants.StandardScopes.Profile,
+ "roles",
+ "new_college.api"
+ }
+ },
+
+```
+
+然后再 `Swagger` 中,配置登录授权:
+
+
+
+
+## Authorization-JWT
+
+如果你不想使用 `IdentityServer4` 的话,也可以使用 `JWT` 认证,同样是是`New_College\New_College\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` 模型的传输转换,具体的用法,可以查看:
+`New_College\New_College\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();` 具体代码 `New_College\New_College\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, "New_College.Services.dll");
+ var repositoryDllFile = Path.Combine(basePath, "New_College.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("New_College.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 —— 测试注入,【暂时无用】;
+```
+文件地址在 `.\New_College\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` 模板 `.\New_College.FrameWork` 层,目的是可以一键生成项目模板代码。
+1、需要在 `DbHelper.ttinclude` 中配置连接数据库连接字符串;
+2、针对每一层的代码,就去指定的 `.tt` 模板,直接 `CTRL+S` 保存即可;
+
+> 注意,目前的代码是 `SqlServer` 版本的,其他数据库版本的,可以去群文件查看。
+
+
+## Test-xUnit
+
+项目简单使用了单元测试,通过 `xUnit` 组件,具体的可以查看 `New_College.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
+
+
+项目中封装了获取用户信息的代码:
+在 `.\New_College.Common\HttpContextUser` 文件夹下 `AspNetUser.cs` 实现类和 `IUser.cs` 接口。
+
+如果使用,首先需要注册相应的服务,参见:`.\New_College\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
new file mode 100644
index 0000000..3119a36
--- /dev/null
+++ b/.docs/contents/guide/function-sheet.md
@@ -0,0 +1,471 @@
+# H 核心功能一览表
+
+## 一、表结构解析
+
+`New_College` 项目共包含四部分的数据库表结构,分别是:用户角色管理部分、接口菜单权限管理部分、博客文章管理部分、以及其他不重要部分。
+> 注意:目前不提供与维护数据库数据,直接通过 `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、全部请求与响应日志
+
+ 开启方式:appsettings.json -> Middlewar -> RequestResponseLog 节点为true。
+ 文件路径:web目录下,Log/RequestIpInfoLog.log。
+ 功能描述:记录项目启动后客户端所有的请求和响应日志,包括url参数、body以及相应json。
+
+
+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:8081;
+ 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\New_College\.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:8081;
+ 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:8081;
+ 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:8081;
+ 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:8081;
+ 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:8081;
+ 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
new file mode 100644
index 0000000..f6dd463
--- /dev/null
+++ b/.docs/contents/guide/getting-started.md
@@ -0,0 +1,125 @@
+# K 快速上手
+注意
+
+请确保你的 `Visual Studio 2019` 版本 >= `16.4`。
+
+
+## 下载
+Github(国际) 下载 [https://github.com/anjoy8/New_College](https://github.com/anjoy8/New_College)
+
+Gitee(国内) 下载 [https://gitee.com/laozhangIsPhi/New_College](https://gitee.com/laozhangIsPhi/New_College)
+
+
+## 编译与运行
+1、拿到项目后,双击 `New_College.sln` 解决方案;
+2、首先 `F6` 编译,看是否有错误;
+3、然后 `F5` 运行,调起 `8081` 端口,浏览器查看效果;
+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、打开 `New_College` 项目下的 `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、在 `New_College` 层下的 `program.cs` 文件中,将 `8081`端口,修改为自己想要的端口号;
+2、或者在 `launchSettings.json` 中设置;
+
+## 如何项目重命名
+1、双击项目根目录下的 `CreateYourProject.bat` 批处理文件;
+2、根据提示,输入自己想要的项目名称即可;
+3、在根目录会有一个 `.1YourProject` 文件夹,里边即你的项目;
+
+
+## 新增实体模块后如何迁移到数据库
+1、在 `New_College.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` 模板来生成,在 `New_College.FrameWork` 层,使用方法: [9757999.html](https://www.cnblogs.com/laozhang-is-phi/p/9757999.html#autoid-4-3-0) ;
+> 注意:这种方案,目前默认的只能是 `SqlServer` ,其他类型的数据库,可以看上边文章中的代码,或者群文件里对应的代码。
+
+2、也可以通过 `Sqlsugar` 所带的方法来实现 `DbFirst`,具体查看 `Controller` 层下的 `DbFirstController.cs`;
+
+3、总体操作过程,可以参考我的视频:[av77612407](https://www.bilibili.com/video/av77612407?p=2) ;
+
+
+## 发布与部署
+1、双击项目根目录下的 `New_College.Publish.bat`批处理文件;
+2、执行完成后,根目录会有一个`.PublishFiles` 文件夹,就是发布后的项目;
+
+
+## 如何更新项目模板
+1、着急的话自己打包,不着急就提 `issue`,等我更新;
+2、我的开源项目中,有个模板项目 `BlogCoreTempl` [地址](https://github.com/anjoy8/BlogCoreTempl),下载下来;
+3、下载最新的 `New_College` 源代码;
+4、将源代码拷贝到模板项目的 `content` 文件夹下;
+5、双击 `Package.bat` 文件,就生成了最新的模板了;
+
diff --git a/.docs/package.json b/.docs/package.json
new file mode 100644
index 0000000..3f0483b
--- /dev/null
+++ b/.docs/package.json
@@ -0,0 +1,12 @@
+{
+ "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/.editorconfig b/.editorconfig
new file mode 100644
index 0000000..7711e94
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,4 @@
+[*.cs]
+
+# IDE0005: Using 指令是不需要的。
+dotnet_diagnostic.IDE0005.severity = warning
diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml
new file mode 100644
index 0000000..7c3b424
--- /dev/null
+++ b/.github/FUNDING.yml
@@ -0,0 +1,12 @@
+# These are supported funding model platforms
+
+github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
+patreon: # Replace with a single Patreon username
+open_collective: # Replace with a single Open Collective username
+ko_fi: # Replace with a single Ko-fi username
+tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
+community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
+liberapay: # Replace with a single Liberapay username
+issuehunt: # Replace with a single IssueHunt username
+otechie: # Replace with a single Otechie username
+custom: http://apk.neters.club/laozhangisphigood.jpg
diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml
new file mode 100644
index 0000000..80815c1
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/config.yml
@@ -0,0 +1,22 @@
+blank_issues_enabled: false
+contact_links:
+ - name: 🚨 Bug report | Bug 提交
+ url: https://github.com/anjoy8/New_College/issues/new
+ about: |
+ Please report bugs here.
+ 请在此提交 Bug。
+ - name: 🙋 Feature request | 新功能提案
+ url: https://github.com/anjoy8/New_College/issues/new
+ about: |
+ Please request features here.
+ 请在此提交新功能提案。
+ - name: 🤔 Consulting from the New_College team | 咨询 作者
+ url: https://github.com/anjoy8/New_College/issues/new
+ about: |
+ Get technical support, project audits, app deployments, and custom development from the core New_College team.
+ 咨询核心 New_College 团队以获得技术支持,项目审核,应用程序部署以及自定义开发等方面上的帮助。
+ - name: ❗️ All other issues | 其他问题
+ url: https://github.com/anjoy8/New_College/issues/new
+ about: |
+ Please create all other issues here.
+ 请在此创建其他类型问题。
\ No newline at end of file
diff --git a/.github/workflows/dotnetcore.yml b/.github/workflows/dotnetcore.yml
new file mode 100644
index 0000000..b72c6aa
--- /dev/null
+++ b/.github/workflows/dotnetcore.yml
@@ -0,0 +1,17 @@
+name: .NET Core
+
+on: [push]
+
+jobs:
+ build:
+
+ runs-on: ubuntu-latest
+
+ steps:
+ - uses: actions/checkout@v1
+ - name: Setup .NET Core
+ uses: actions/setup-dotnet@v1
+ with:
+ dotnet-version: 3.1.100
+ - name: Build with dotnet
+ run: dotnet build --configuration Release
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..832276b
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,353 @@
+## Ignore Visual Studio temporary files, build results, and
+## files generated by popular Visual Studio add-ons.
+##
+## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
+
+# User-specific files
+*.rsuser
+*.suo
+*.user
+*.userosscache
+*.sln.docstates
+
+# User-specific files (MonoDevelop/Xamarin Studio)
+*.userprefs
+
+# Build results
+[Dd]ebug/
+[Dd]ebugPublic/
+[Rr]elease/
+[Rr]eleases/
+x64/
+x86/
+[Aa][Rr][Mm]/
+[Aa][Rr][Mm]64/
+bld/
+[Bb]in/
+[Oo]bj/
+[Ll]og/
+
+# Visual Studio 2015/2017 cache/options directory
+.vs/
+# Uncomment if you have tasks that create the project's static files in wwwroot
+#wwwroot/
+
+# Visual Studio 2017 auto generated files
+Generated\ Files/
+
+# MSTest test Results
+[Tt]est[Rr]esult*/
+[Bb]uild[Ll]og.*
+
+# NUNIT
+*.VisualState.xml
+TestResult.xml
+
+# Build Results of an ATL Project
+[Dd]ebugPS/
+[Rr]eleasePS/
+dlldata.c
+
+# Benchmark Results
+BenchmarkDotNet.Artifacts/
+
+# .NET Core
+project.lock.json
+project.fragment.lock.json
+artifacts/
+
+# StyleCop
+StyleCopReport.xml
+
+# Files built by Visual Studio
+*_i.c
+*_p.c
+*_h.h
+*.ilk
+*.meta
+*.obj
+*.iobj
+*.pch
+*.pdb
+*.ipdb
+*.pgc
+*.pgd
+*.rsp
+*.sbr
+*.tlb
+*.tli
+*.tlh
+*.tmp
+*.tmp_proj
+*_wpftmp.csproj
+*.log
+*.vspscc
+*.vssscc
+.builds
+*.pidb
+*.svclog
+*.scc
+
+# Chutzpah Test files
+_Chutzpah*
+
+# Visual C++ cache files
+ipch/
+*.aps
+*.ncb
+*.opendb
+*.opensdf
+*.sdf
+*.cachefile
+*.VC.db
+*.VC.VC.opendb
+
+# Visual Studio profiler
+*.psess
+*.vsp
+*.vspx
+*.sap
+
+# Visual Studio Trace Files
+*.e2e
+
+# TFS 2012 Local Workspace
+$tf/
+
+# Guidance Automation Toolkit
+*.gpState
+
+# ReSharper is a .NET coding add-in
+_ReSharper*/
+*.[Rr]e[Ss]harper
+*.DotSettings.user
+
+# JustCode is a .NET coding add-in
+.JustCode
+
+# TeamCity is a build add-in
+_TeamCity*
+
+# DotCover is a Code Coverage Tool
+*.dotCover
+
+# AxoCover is a Code Coverage Tool
+.axoCover/*
+!.axoCover/settings.json
+
+# Visual Studio code coverage results
+*.coverage
+*.coveragexml
+
+# NCrunch
+_NCrunch_*
+.*crunch*.local.xml
+nCrunchTemp_*
+
+# MightyMoose
+*.mm.*
+AutoTest.Net/
+
+# Web workbench (sass)
+.sass-cache/
+
+# Installshield output folder
+[Ee]xpress/
+
+# DocProject is a documentation generator add-in
+DocProject/buildhelp/
+DocProject/Help/*.HxT
+DocProject/Help/*.HxC
+DocProject/Help/*.hhc
+DocProject/Help/*.hhk
+DocProject/Help/*.hhp
+DocProject/Help/Html2
+DocProject/Help/html
+
+# Click-Once directory
+publish/
+
+# Publish Web Output
+*.[Pp]ublish.xml
+*.azurePubxml
+# Note: Comment the next line if you want to checkin your web deploy settings,
+# but database connection strings (with potential passwords) will be unencrypted
+*.pubxml
+*.publishproj
+
+# Microsoft Azure Web App publish settings. Comment the next line if you want to
+# checkin your Azure Web App publish settings, but sensitive information contained
+# in these scripts will be unencrypted
+PublishScripts/
+
+# NuGet Packages
+*.nupkg
+# The packages folder can be ignored because of Package Restore
+**/[Pp]ackages/*
+# except build/, which is used as an MSBuild target.
+!**/[Pp]ackages/build/
+# Uncomment if necessary however generally it will be regenerated when needed
+#!**/[Pp]ackages/repositories.config
+# NuGet v3's project.json files produces more ignorable files
+*.nuget.props
+*.nuget.targets
+
+# Microsoft Azure Build Output
+csx/
+*.build.csdef
+
+# Microsoft Azure Emulator
+ecf/
+rcf/
+
+# Windows Store app package directories and files
+AppPackages/
+BundleArtifacts/
+Package.StoreAssociation.xml
+_pkginfo.txt
+*.appx
+
+# Visual Studio cache files
+# files ending in .cache can be ignored
+*.[Cc]ache
+# but keep track of directories ending in .cache
+!?*.[Cc]ache/
+
+# Others
+ClientBin/
+~$*
+*~
+*.dbmdl
+*.dbproj.schemaview
+*.jfm
+*.pfx
+*.publishsettings
+orleans.codegen.cs
+
+# Including strong name files can present a security risk
+# (https://github.com/github/gitignore/pull/2483#issue-259490424)
+#*.snk
+
+# Since there are multiple workflows, uncomment next line to ignore bower_components
+# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
+#bower_components/
+# ASP.NET Core default setup: bower directory is configured as wwwroot/lib/ and bower restore is true
+**/wwwroot/lib/
+
+# RIA/Silverlight projects
+Generated_Code/
+
+# Backup & report files from converting an old project file
+# to a newer Visual Studio version. Backup files are not needed,
+# because we have git ;-)
+_UpgradeReport_Files/
+Backup*/
+UpgradeLog*.XML
+UpgradeLog*.htm
+ServiceFabricBackup/
+*.rptproj.bak
+
+# SQL Server files
+*.mdf
+*.ldf
+*.ndf
+
+# Business Intelligence projects
+*.rdl.data
+*.bim.layout
+*.bim_*.settings
+*.rptproj.rsuser
+
+# Microsoft Fakes
+FakesAssemblies/
+
+# GhostDoc plugin setting file
+*.GhostDoc.xml
+
+# Node.js Tools for Visual Studio
+.ntvs_analysis.dat
+node_modules/
+
+# Visual Studio 6 build log
+*.plg
+
+# Visual Studio 6 workspace options file
+*.opt
+
+# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
+*.vbw
+
+# Visual Studio LightSwitch build output
+**/*.HTMLClient/GeneratedArtifacts
+**/*.DesktopClient/GeneratedArtifacts
+**/*.DesktopClient/ModelManifest.xml
+**/*.Server/GeneratedArtifacts
+**/*.Server/ModelManifest.xml
+_Pvt_Extensions
+
+# Paket dependency manager
+.paket/paket.exe
+paket-files/
+
+# FAKE - F# Make
+.fake/
+
+# JetBrains Rider
+.idea/
+*.sln.iml
+
+# CodeRush personal settings
+.cr/personal
+
+# Python Tools for Visual Studio (PTVS)
+__pycache__/
+*.pyc
+
+# Cake - Uncomment if you are using it
+# tools/**
+# !tools/packages.config
+
+# Tabs Studio
+*.tss
+
+# Telerik's JustMock configuration file
+*.jmconfig
+
+# BizTalk build output
+*.btp.cs
+*.btm.cs
+*.odx.cs
+*.xsd.cs
+
+# OpenCover UI analysis results
+OpenCover/
+
+# Azure Stream Analytics local run output
+ASALocalRun/
+
+# MSBuild Binary and Structured Log
+*.binlog
+
+# NVidia Nsight GPU debugger configuration file
+*.nvuser
+
+# MFractors (Xamarin productivity tool) working folder
+.mfractor/
+
+# Local History for Visual Studio
+.localhistory/
+
+# BeatPulse healthcheck temp database
+healthchecksdb
+
+
+# wwwroot/images
+*images/
+.1YourProject
+.PublishFiles
+!.template.config/*.nupkg
+!New_College.Webapi.Template.*.nupkg
+New_College/WMBlog.db
+.docs/contents/.vuepress/dist/*
+New_College/New_College*.xml
+New_College.Api/WMBlog.db
diff --git a/CreateYourProject.bat b/CreateYourProject.bat
new file mode 100644
index 0000000..eb904eb
--- /dev/null
+++ b/CreateYourProject.bat
@@ -0,0 +1,23 @@
+color 3
+
+dotnet new -i .template.config\New_College.Webapi.Template.2.1.0.nupkg
+
+set /p OP=Please set your project name(for example:Baidu.Api):
+
+md .1YourProject
+
+cd .1YourProject
+
+dotnet new blogcoretpl -n %OP%
+
+cd ../
+
+
+echo "Create Successfully!!!! ^ please see the folder .1YourProject"
+
+dotnet new -u New_College.Webapi.Template
+
+
+echo "Delete Template Successfully"
+
+pause
\ No newline at end of file
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..261eeb9
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,201 @@
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
diff --git a/New_College.AdminMvc/New_College.AdminMvc.csproj b/New_College.AdminMvc/New_College.AdminMvc.csproj
new file mode 100644
index 0000000..92605c5
--- /dev/null
+++ b/New_College.AdminMvc/New_College.AdminMvc.csproj
@@ -0,0 +1,7 @@
+
+
+
+ netcoreapp3.1
+
+
+
diff --git a/New_College.AdminMvc/Program.cs b/New_College.AdminMvc/Program.cs
new file mode 100644
index 0000000..1397a74
--- /dev/null
+++ b/New_College.AdminMvc/Program.cs
@@ -0,0 +1,20 @@
+using Microsoft.AspNetCore.Hosting;
+using Microsoft.Extensions.Hosting;
+
+namespace New_College.AdminMvc
+{
+ public class Program
+ {
+ public static void Main(string[] args)
+ {
+ CreateHostBuilder(args).Build().Run();
+ }
+
+ public static IHostBuilder CreateHostBuilder(string[] args) =>
+ Host.CreateDefaultBuilder(args)
+ .ConfigureWebHostDefaults(webBuilder =>
+ {
+ webBuilder.UseStartup();
+ });
+ }
+}
diff --git a/New_College.AdminMvc/Properties/launchSettings.json b/New_College.AdminMvc/Properties/launchSettings.json
new file mode 100644
index 0000000..f53df01
--- /dev/null
+++ b/New_College.AdminMvc/Properties/launchSettings.json
@@ -0,0 +1,27 @@
+{
+ "iisSettings": {
+ "windowsAuthentication": false,
+ "anonymousAuthentication": true,
+ "iisExpress": {
+ "applicationUrl": "http://localhost:51491",
+ "sslPort": 0
+ }
+ },
+ "profiles": {
+ "IIS Express": {
+ "commandName": "IISExpress",
+ "launchBrowser": true,
+ "environmentVariables": {
+ "ASPNETCORE_ENVIRONMENT": "Development"
+ }
+ },
+ "New_College.AdminMvc": {
+ "commandName": "Project",
+ "launchBrowser": true,
+ "applicationUrl": "http://localhost:5000",
+ "environmentVariables": {
+ "ASPNETCORE_ENVIRONMENT": "Development"
+ }
+ }
+ }
+}
diff --git a/New_College.AdminMvc/Startup.cs b/New_College.AdminMvc/Startup.cs
new file mode 100644
index 0000000..13a4baa
--- /dev/null
+++ b/New_College.AdminMvc/Startup.cs
@@ -0,0 +1,42 @@
+using Microsoft.AspNetCore.Builder;
+using Microsoft.AspNetCore.Hosting;
+using Microsoft.AspNetCore.Http;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Hosting;
+
+namespace New_College.AdminMvc
+{
+ public class Startup
+ {
+ /**
+ *┌──────────────────────────────────────────────────────────────┐
+ *│ 描 述:当前项目为空,只是模拟一个MVC客户端
+ *│ 作 者:anson zhang
+ *└──────────────────────────────────────────────────────────────┘
+ */
+ // This method gets called by the runtime. Use this method to add services to the container.
+ // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
+ public void ConfigureServices(IServiceCollection services)
+ {
+ }
+
+ // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
+ public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
+ {
+ if (env.IsDevelopment())
+ {
+ app.UseDeveloperExceptionPage();
+ }
+
+ app.UseRouting();
+
+ app.UseEndpoints(endpoints =>
+ {
+ endpoints.MapGet("/", async context =>
+ {
+ await context.Response.WriteAsync("Hello World!");
+ });
+ });
+ }
+ }
+}
diff --git a/New_College.AdminMvc/appsettings.Development.json b/New_College.AdminMvc/appsettings.Development.json
new file mode 100644
index 0000000..8983e0f
--- /dev/null
+++ b/New_College.AdminMvc/appsettings.Development.json
@@ -0,0 +1,9 @@
+{
+ "Logging": {
+ "LogLevel": {
+ "Default": "Information",
+ "Microsoft": "Warning",
+ "Microsoft.Hosting.Lifetime": "Information"
+ }
+ }
+}
diff --git a/New_College.AdminMvc/appsettings.json b/New_College.AdminMvc/appsettings.json
new file mode 100644
index 0000000..d9d9a9b
--- /dev/null
+++ b/New_College.AdminMvc/appsettings.json
@@ -0,0 +1,10 @@
+{
+ "Logging": {
+ "LogLevel": {
+ "Default": "Information",
+ "Microsoft": "Warning",
+ "Microsoft.Hosting.Lifetime": "Information"
+ }
+ },
+ "AllowedHosts": "*"
+}
diff --git a/New_College.Api/.config/dotnet-tools.json b/New_College.Api/.config/dotnet-tools.json
new file mode 100644
index 0000000..c6f5df7
--- /dev/null
+++ b/New_College.Api/.config/dotnet-tools.json
@@ -0,0 +1,12 @@
+{
+ "version": 1,
+ "isRoot": true,
+ "tools": {
+ "dotnet-ef": {
+ "version": "3.1.9",
+ "commands": [
+ "dotnet-ef"
+ ]
+ }
+ }
+}
\ No newline at end of file
diff --git a/New_College.Api/Controllers/Back/AutoController.cs b/New_College.Api/Controllers/Back/AutoController.cs
new file mode 100644
index 0000000..ed39c17
--- /dev/null
+++ b/New_College.Api/Controllers/Back/AutoController.cs
@@ -0,0 +1,183 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Mvc;
+using New_College.IRepository;
+using New_College.IServices;
+using New_College.Model;
+
+namespace New_College.Api.Controllers.Back
+{
+ [Route("api/[controller]/[action]")]
+ [ApiController]
+ public class AutoController : ControllerBase
+ {
+ private readonly ITest_CycleTimeInfoServices test_CycleTimeInfoServices;
+ private readonly ID_LongIdMapServices d_LongIdMapServices;
+ private readonly IT_LongIdMapServices t_LongIdMapServices;
+ private readonly IT_EnrollmentPlaneServices t_EnrollmentPlaneServices;
+ private readonly ID_UniversityServices d_UniversityServices;
+ private readonly ID_MajorSalaryServices d_MajorSalaryServices;
+
+ public AutoController(ITest_CycleTimeInfoServices ITest_CycleTimeInfoServices
+ , ID_LongIdMapServices ID_LongIdMapServices
+ , IT_LongIdMapServices IT_LongIdMapServices
+ , IT_EnrollmentPlaneServices IT_EnrollmentPlaneServices
+ , ID_UniversityServices ID_UniversityServices
+ , ID_MajorSalaryServices ID_MajorSalaryServices)
+ {
+
+ test_CycleTimeInfoServices = ITest_CycleTimeInfoServices;
+ d_LongIdMapServices = ID_LongIdMapServices;
+ t_LongIdMapServices = IT_LongIdMapServices;
+ t_EnrollmentPlaneServices = IT_EnrollmentPlaneServices;
+ d_UniversityServices = ID_UniversityServices;
+ d_MajorSalaryServices = ID_MajorSalaryServices;
+ }
+ #region old
+ /////
+ ///// 生成周期
+ /////
+ /////
+ //[HttpPost]
+ //public async Task> AutoCycleTime()
+ //{
+ // var result = await test_CycleTimeInfoServices.AutoCycleTime();
+ // return new MessageModel()
+ // {
+ // success = result,
+ // response = result,
+ // msg = result == true ? "成功" : "失败"
+ // };
+ //}
+
+ /////
+ /////
+ /////
+ /////
+ //[HttpPost]
+ //public async Task> Import()
+ //{
+ // var result = await d_LongIdMapServices.Import();
+ // return new MessageModel()
+ // {
+ // success = true,
+ // msg = "成功",
+ // response = result
+ // };
+ //}
+ #endregion
+
+ #region new T
+ /////
+ ///// EnrollmentBatch
+ /////
+ /////
+ //[HttpPost]
+ //public async Task> ImportEnrollmentBatch()
+ //{
+ // return new MessageModel()
+ // {
+ // success = true,
+ // msg = "成功",
+ // response = await t_LongIdMapServices.ImportEnrollmentBatch()
+ // };
+ //}
+
+ /////
+ ///// EnrollmentPlane
+ /////
+ /////
+ //[HttpPost]
+ //public async Task> ImportEnrollmentPlane()
+ //{
+ // return new MessageModel()
+ // {
+ // success = true,
+ // msg = "成功",
+ // response = await t_LongIdMapServices.ImportEnrollmentPlane()
+ // };
+ //}
+
+ /////
+ ///// EnrollmentPlanedesc
+ /////
+ /////
+ //[HttpPost]
+ //public async Task> ImportEnrollmentPlanedesc()
+ //{
+ // return new MessageModel()
+ // {
+ // success = true,
+ // msg = "成功",
+ // response = await t_LongIdMapServices.ImportEnrollmentPlanedesc()
+ // };
+ //}
+
+ /////
+ ///// Batchline
+ /////
+ /////
+ //[HttpPost]
+ //public async Task> ImportBatchline()
+ //{
+ // return new MessageModel()
+ // {
+ // success = true,
+ // msg = "成功",
+ // response = await t_LongIdMapServices.ImportBatchline()
+ // };
+ //}
+
+ /////
+ ///// BatchTypeInfo
+ /////
+ /////
+ //[HttpPost]
+ //public async Task> ImportBatchTypeInfo()
+ //{
+ // return new MessageModel()
+ // {
+ // success = true,
+ // msg = "成功",
+ // response = await t_LongIdMapServices.ImportBatchTypeInfo()
+ // };
+ //}
+ #endregion
+
+ /////
+ ///// 2019上海招生分数更新
+ /////
+ /////
+ //[HttpPost]
+ //public async Task> Import()
+ //{
+ // var result = await t_EnrollmentPlaneServices.Import();
+ // return new MessageModel() { success = true };
+ //}
+
+ /////
+ ///// 下载图片
+ /////
+ /////
+ //[HttpPost]
+ //public async Task> SaveImg()
+ //{
+ // var result = await d_UniversityServices.SaveImg();
+ // return new MessageModel() { success = true, msg = "成功" };
+ //}
+
+
+ /////
+ ///// 专业薪酬
+ /////
+ /////
+ //[HttpPost]
+ //public async Task Import()
+ //{
+ // return await d_MajorSalaryServices.Import();
+ //}
+ }
+}
diff --git a/New_College.Api/Controllers/Back/CustomerController.cs b/New_College.Api/Controllers/Back/CustomerController.cs
new file mode 100644
index 0000000..2c79b8d
--- /dev/null
+++ b/New_College.Api/Controllers/Back/CustomerController.cs
@@ -0,0 +1,33 @@
+using Microsoft.AspNetCore.Mvc;
+using New_College.IServices;
+using New_College.Model;
+using New_College.Model.ViewModels;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+
+namespace New_College.Api.Controllers.Back
+{
+ [Route("api/back/[controller]/[action]")]
+ [ApiController]
+ //[Authorize]
+ public class CustomerController : ControllerBase
+ {
+ private readonly IV_CustomerInfoServices v_CustomerInfoServices;
+ public CustomerController(IV_CustomerInfoServices IV_CustomerInfoServices)
+ {
+ v_CustomerInfoServices = IV_CustomerInfoServices;
+ }
+ ///
+ /// 获取分页
+ ///
+ ///
+ ///
+ [HttpGet]
+ public async Task>> GetCustomerInfoListByPage([FromQuery] CustomerSeachQuery query)
+ {
+ return await v_CustomerInfoServices.GetCustomerInfoListByPage(query);
+ }
+ }
+}
diff --git a/New_College.Api/Controllers/Back/ExaminationPolicyController.cs b/New_College.Api/Controllers/Back/ExaminationPolicyController.cs
new file mode 100644
index 0000000..07259ef
--- /dev/null
+++ b/New_College.Api/Controllers/Back/ExaminationPolicyController.cs
@@ -0,0 +1,80 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Mvc;
+using New_College.IServices;
+using New_College.Model;
+using New_College.Model.ViewModels;
+
+namespace New_College.Api.Controllers.Back
+{
+ [Route("api/back/[controller]/[action]")]
+ [ApiController]
+ [Authorize]
+ public class ExaminationPolicyController : ControllerBase
+ {
+ private readonly IV_ExaminationPolicyServices iV_ExaminationPolicyServices;
+ public ExaminationPolicyController(IV_ExaminationPolicyServices IV_ExaminationPolicyServices)
+ {
+ iV_ExaminationPolicyServices = IV_ExaminationPolicyServices;
+ }
+
+ ///
+ /// 获取分页
+ ///
+ ///
+ ///
+ [HttpGet]
+ public async Task>> GetExaminationPolicyByPage([FromQuery] ExaminationPolicySearchQuery query)
+ {
+ return await iV_ExaminationPolicyServices.GetExaminationPolicyByPage(query);
+ }
+
+ ///
+ /// 获取单个
+ ///
+ ///
+ ///
+ [HttpGet]
+ public async Task> GetExaminationPolicyOne([FromQuery] IdQuery query)
+ {
+ return await iV_ExaminationPolicyServices.GetExaminationPolicyOne(query);
+ }
+
+ ///
+ /// 添加
+ ///
+ ///
+ ///
+ [HttpPost]
+ public async Task> AddExaminationPolicy([FromBody] ExaminationPolicyQuery query)
+ {
+ return await iV_ExaminationPolicyServices.AddExaminationPolicy(query);
+ }
+
+ ///
+ /// 修改
+ ///
+ ///
+ ///
+ [HttpPut]
+ public async Task> UpdateExaminationPolicy(ExaminationPolicyQuery query)
+ {
+ return await iV_ExaminationPolicyServices.UpdateExaminationPolicy(query);
+ }
+
+ ///
+ /// 删除
+ ///
+ ///
+ ///
+ [HttpPost]
+ public async Task> DeleteExaminationPolicy([FromBody] IdQuery query)
+ {
+ return await iV_ExaminationPolicyServices.DeleteExaminationPolicy(query);
+ }
+ }
+}
diff --git a/New_College.Api/Controllers/Back/OrderInfoController.cs b/New_College.Api/Controllers/Back/OrderInfoController.cs
new file mode 100644
index 0000000..85d553a
--- /dev/null
+++ b/New_College.Api/Controllers/Back/OrderInfoController.cs
@@ -0,0 +1,43 @@
+using Microsoft.AspNetCore.Mvc;
+using New_College.IServices;
+using New_College.Model;
+using New_College.Model.ViewModels;
+using System.Threading.Tasks;
+
+namespace New_College.Api.Controllers.Back
+{
+ [Route("api/back/[controller]/[action]")]
+ [ApiController]
+ public class OrderInfoController : ControllerBase
+ {
+ private readonly IV_OrderInfoServices v_OrderInfoServices;
+ private readonly IV_VipCardTypeServices iV_VipCardTypeServices;
+ public OrderInfoController(IV_OrderInfoServices IV_OrderInfoServices, IV_VipCardTypeServices IV_VipCardTypeServices)
+ {
+ v_OrderInfoServices = IV_OrderInfoServices;
+ iV_VipCardTypeServices = IV_VipCardTypeServices;
+ }
+
+ ///
+ /// 获取分页
+ ///
+ ///
+ ///
+ [HttpGet]
+ public async Task>> GetVipCardInfoByPage([FromQuery] SearchOrderQuery query)
+ {
+ return await v_OrderInfoServices.GetOrderInfoByPage(query);
+ }
+
+ ///
+ /// 获取分页
+ ///
+ ///
+ ///
+ [HttpGet]
+ public async Task>> GetOrderInfoList([FromQuery] SearchOrderQuery query)
+ {
+ return await v_OrderInfoServices.GetOrderInfoByPage(query);
+ }
+ }
+}
diff --git a/New_College.Api/Controllers/Back/VipCardController.cs b/New_College.Api/Controllers/Back/VipCardController.cs
new file mode 100644
index 0000000..ad19718
--- /dev/null
+++ b/New_College.Api/Controllers/Back/VipCardController.cs
@@ -0,0 +1,102 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Mvc;
+using New_College.IServices;
+using New_College.Model;
+using New_College.Model.Models;
+using New_College.Model.ViewModels;
+using New_College.Model.ViewModels.Query;
+
+namespace New_College.Api.Controllers.Back
+{
+ [Route("api/back/[controller]/[action]")]
+ [ApiController]
+ public class VipCardController : ControllerBase
+ {
+ private readonly IV_VipCardInfoServices iV_VipCardInfoServices;
+ private readonly IV_VipCardTypeServices iV_VipCardTypeServices;
+ private readonly IV_OrderInfoServices iV_OrderInfoServices;
+ public VipCardController(IV_VipCardInfoServices IV_VipCardInfoServices, IV_VipCardTypeServices IV_VipCardTypeServices, IV_OrderInfoServices IV_OrderInfoServices)
+ {
+ iV_VipCardInfoServices = IV_VipCardInfoServices;
+ iV_VipCardTypeServices = IV_VipCardTypeServices;
+ iV_OrderInfoServices= IV_OrderInfoServices;
+ }
+ ///
+ /// 生成卡信息
+ ///
+ ///
+ ///
+ [HttpPost]
+ public async Task>> AutoVipCardInfo([FromBody] AutoVipInfoQuery query)
+ {
+ return await iV_VipCardInfoServices.AutoVipCardInfo(query);
+ }
+ ///
+ /// 获取分页
+ ///
+ ///
+ ///
+ [HttpGet]
+ public async Task>> GetVipCardInfoByPage([FromQuery] VipCardInfoSearchQuery query)
+ {
+ return await iV_VipCardInfoServices.GetVipCardInfoByPage(query);
+ }
+
+ ///
+ /// 获取单个
+ ///
+ ///
+ ///
+ [HttpGet]
+ public async Task> GetVipCardInfoOne([FromQuery] IdQuery query)
+ {
+ return await iV_VipCardInfoServices.GetVipCardInfoOne(query);
+ }
+
+ ///
+ /// 添加
+ ///
+ ///
+ ///
+ [HttpPost]
+ public async Task> AddVipCardInfo([FromBody] VipCardInfoQuery query)
+ {
+ return await iV_VipCardInfoServices.AddVipCardInfo(query);
+ }
+
+ ///
+ /// 修改
+ ///
+ ///
+ ///
+ [HttpPut]
+ public async Task> UpdateVipCardInfo(VipCardInfoQuery query)
+ {
+ return await iV_VipCardInfoServices.UpdateVipCardInfo(query);
+ }
+
+ ///
+ /// 删除
+ ///
+ ///
+ ///
+ [HttpPost]
+ public async Task> DeleteVipCardInfo([FromBody] IdQuery query)
+ {
+ return await iV_VipCardInfoServices.DeleteVipCardInfo(query);
+ }
+ ///
+ /// 获取vipcardTypeList
+ ///
+ ///
+ [HttpPost]
+ public async Task> GetVipCardType()
+ {
+ return await iV_VipCardTypeServices.GetVipCardType();
+ }
+ }
+}
diff --git a/New_College.Api/Controllers/BlogController.cs b/New_College.Api/Controllers/BlogController.cs
new file mode 100644
index 0000000..a2ccf4b
--- /dev/null
+++ b/New_College.Api/Controllers/BlogController.cs
@@ -0,0 +1,336 @@
+using System;
+using System.Collections.Generic;
+using System.Linq.Expressions;
+using System.Threading.Tasks;
+using New_College.Common.Helper;
+using New_College.IServices;
+using New_College.Model;
+using New_College.Model.Models;
+using New_College.Model.ViewModels;
+using New_College.SwaggerHelper;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.Extensions.Logging;
+using StackExchange.Profiling;
+using static New_College.Extensions.CustomApiVersion;
+
+namespace New_College.Controllers
+{
+ ///
+ /// 博客管理
+ ///
+ [Produces("application/json")]
+ [Route("api/Blog")]
+ public class BlogController : Controller
+ {
+ readonly IBlogArticleServices _blogArticleServices;
+ private readonly ILogger _logger;
+
+ ///
+ /// 构造函数
+ ///
+ ///
+ ///
+ public BlogController(IBlogArticleServices blogArticleServices, ILogger logger)
+ {
+ _blogArticleServices = blogArticleServices;
+ _logger = logger;
+ }
+
+
+ ///
+ /// 获取博客列表【无权限】
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ [HttpGet]
+ public async Task>> Get(int id, int page = 1, string bcategory = "技术博文", string key = "")
+ {
+ int intPageSize = 6;
+ if (string.IsNullOrEmpty(key) || string.IsNullOrWhiteSpace(key))
+ {
+ key = "";
+ }
+
+ Expression> whereExpression = a => (a.bcategory == bcategory && a.IsDeleted == false) && ((a.btitle != null && a.btitle.Contains(key)) || (a.bcontent != null && a.bcontent.Contains(key)));
+
+ var pageModelBlog = await _blogArticleServices.QueryPage(whereExpression, page, intPageSize, " bID desc ");
+
+ using (MiniProfiler.Current.Step("获取成功后,开始处理最终数据"))
+ {
+ foreach (var item in pageModelBlog.data)
+ {
+ if (!string.IsNullOrEmpty(item.bcontent))
+ {
+ item.bRemark = (HtmlHelper.ReplaceHtmlTag(item.bcontent)).Length >= 200 ? (HtmlHelper.ReplaceHtmlTag(item.bcontent)).Substring(0, 200) : (HtmlHelper.ReplaceHtmlTag(item.bcontent));
+ int totalLength = 500;
+ if (item.bcontent.Length > totalLength)
+ {
+ item.bcontent = item.bcontent.Substring(0, totalLength);
+ }
+ }
+ }
+ }
+
+ return new MessageModel>()
+ {
+ success = true,
+ msg = "获取成功",
+ response = new PageModel()
+ {
+ page = page,
+ dataCount = pageModelBlog.dataCount,
+ data = pageModelBlog.data,
+ pageCount = pageModelBlog.pageCount,
+ }
+ };
+ }
+
+
+ ///
+ /// 获取博客详情
+ ///
+ ///
+ ///
+ [HttpGet("{id}")]
+ [Authorize(Policy = "Scope_BlogModule_Policy")]
+ public async Task> Get(int id)
+ {
+ return new MessageModel()
+ {
+ msg = "获取成功",
+ success = true,
+ response = await _blogArticleServices.GetBlogDetails(id)
+ };
+ }
+
+
+ ///
+ /// 获取详情【无权限】
+ ///
+ ///
+ ///
+ [HttpGet]
+ [Route("DetailNuxtNoPer")]
+ public async Task> DetailNuxtNoPer(int id)
+ {
+ _logger.LogInformation("xxxxxxxxxxxxxxxxxxx");
+ return new MessageModel()
+ {
+ msg = "获取成功",
+ success = true,
+ response = await _blogArticleServices.GetBlogDetails(id)
+ };
+ }
+
+ [HttpGet]
+ [Route("GoUrl")]
+ public async Task GoUrl(int id)
+ {
+ var response = await _blogArticleServices.QueryById(id);
+ if (response != null && response.bsubmitter.IsNotEmptyOrNull())
+ {
+ response.btraffic += 1;
+ await _blogArticleServices.Update(response);
+ return Redirect(response.bsubmitter);
+ }
+
+ return null;
+ }
+
+ [HttpGet]
+ [Route("GetBlogsByTypesForMVP")]
+ public async Task>> GetBlogsByTypesForMVP(string types = "", int id = 0)
+ {
+ if (types.IsNotEmptyOrNull())
+ {
+ var blogs = await _blogArticleServices.Query(d => d.bcategory != null && types.Contains(d.bcategory) && d.IsDeleted == false);
+ return new MessageModel>()
+ {
+ msg = "获取成功",
+ success = true,
+ response = blogs
+ };
+ }
+
+ return new MessageModel>() { };
+ }
+
+ [HttpGet]
+ [Route("GetBlogByIdForMVP")]
+ public async Task> GetBlogByIdForMVP(int id = 0)
+ {
+ if (id > 0)
+ {
+ return new MessageModel()
+ {
+ msg = "获取成功",
+ success = true,
+ response = await _blogArticleServices.QueryById(id)
+ };
+ }
+
+ return new MessageModel() { };
+ }
+
+ ///
+ /// 获取博客测试信息 v2版本
+ ///
+ ///
+ [HttpGet]
+ ////MVC自带特性 对 api 进行组管理
+ //[ApiExplorerSettings(GroupName = "v2")]
+ ////路径 如果以 / 开头,表示绝对路径,反之相对 controller 的想u地路径
+ //[Route("/api/v2/blog/Blogtest")]
+ //和上边的版本控制以及路由地址都是一样的
+
+ [CustomRoute(ApiVersions.V2, "Blogtest")]
+ public MessageModel V2_Blogtest()
+ {
+ return new MessageModel()
+ {
+ msg = "获取成功",
+ success = true,
+ response = "我是第二版的博客信息"
+ };
+ }
+
+ ///
+ /// 添加博客【无权限】
+ ///
+ ///
+ ///
+ [HttpPost]
+ [Authorize(Policy = "Scope_BlogModule_Policy")]
+ public async Task> Post([FromBody] BlogArticle blogArticle)
+ {
+ var data = new MessageModel();
+
+ blogArticle.bCreateTime = DateTime.Now;
+ blogArticle.bUpdateTime = DateTime.Now;
+ blogArticle.IsDeleted = false;
+ blogArticle.bcategory = "技术博文";
+
+ var id = (await _blogArticleServices.Add(blogArticle));
+ data.success = id > 0;
+ if (data.success)
+ {
+ data.response = id.ObjToString();
+ data.msg = "添加成功";
+ }
+
+ return data;
+ }
+
+
+ ///
+ ///
+ ///
+ ///
+ ///
+ [HttpPost]
+ [Route("AddForMVP")]
+ [Authorize(Permissions.Name)]
+ public async Task> AddForMVP([FromBody] BlogArticle blogArticle)
+ {
+ var data = new MessageModel();
+
+ blogArticle.bCreateTime = DateTime.Now;
+ blogArticle.bUpdateTime = DateTime.Now;
+ blogArticle.IsDeleted = false;
+
+ var id = (await _blogArticleServices.Add(blogArticle));
+ data.success = id > 0;
+ if (data.success)
+ {
+ data.response = id.ObjToString();
+ data.msg = "添加成功";
+ }
+
+ return data;
+ }
+ ///
+ /// 更新博客信息
+ ///
+ ///
+ ///
+ // PUT: api/User/5
+ [HttpPut]
+ [Route("Update")]
+ [Authorize(Permissions.Name)]
+ public async Task> Put([FromBody] BlogArticle BlogArticle)
+ {
+ var data = new MessageModel();
+ if (BlogArticle != null && BlogArticle.bID > 0)
+ {
+ var model = await _blogArticleServices.QueryById(BlogArticle.bID);
+
+ if (model != null)
+ {
+ model.btitle = BlogArticle.btitle;
+ model.bcategory = BlogArticle.bcategory;
+ model.bsubmitter = BlogArticle.bsubmitter;
+ model.bcontent = BlogArticle.bcontent;
+ model.btraffic = BlogArticle.btraffic;
+
+ data.success = await _blogArticleServices.Update(model);
+ if (data.success)
+ {
+ data.msg = "更新成功";
+ data.response = BlogArticle?.bID.ObjToString();
+ }
+ }
+
+ }
+
+ return data;
+ }
+
+
+
+ ///
+ /// 删除博客
+ ///
+ ///
+ ///
+ [HttpDelete]
+ [Authorize(Permissions.Name)]
+ [Route("Delete")]
+ public async Task> Delete(int id)
+ {
+ var data = new MessageModel();
+ if (id > 0)
+ {
+ var blogArticle = await _blogArticleServices.QueryById(id);
+ blogArticle.IsDeleted = true;
+ data.success = await _blogArticleServices.Update(blogArticle);
+ if (data.success)
+ {
+ data.msg = "删除成功";
+ data.response = blogArticle?.bID.ObjToString();
+ }
+ }
+
+ return data;
+ }
+ ///
+ /// apache jemeter 压力测试
+ /// 更新接口
+ ///
+ ///
+ [HttpGet]
+ [Route("ApacheTestUpdate")]
+ public async Task> ApacheTestUpdate()
+ {
+ return new MessageModel()
+ {
+ success = true,
+ msg = "更新成功",
+ response = await _blogArticleServices.Update(new { bsubmitter = $"laozhang{DateTime.Now.Millisecond}", bID = 1 })
+ };
+ }
+ }
+}
\ No newline at end of file
diff --git a/New_College.Api/Controllers/DbFirst/DbFirstController.cs b/New_College.Api/Controllers/DbFirst/DbFirstController.cs
new file mode 100644
index 0000000..9083bcf
--- /dev/null
+++ b/New_College.Api/Controllers/DbFirst/DbFirstController.cs
@@ -0,0 +1,133 @@
+using New_College.Common;
+using New_College.Common.DB;
+using New_College.Model;
+using New_College.Model.Seed;
+using Microsoft.AspNetCore.Hosting;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.Extensions.Hosting;
+using SqlSugar;
+using System.Linq;
+
+namespace New_College.Controllers
+{
+ [Route("api/[controller]/[action]")]
+ [ApiController]
+ //[Authorize(Permissions.Name)]
+ public class DbFirstController : ControllerBase
+ {
+ private readonly SqlSugarClient _sqlSugarClient;
+ private readonly IWebHostEnvironment Env;
+
+ ///
+ /// 构造函数
+ ///
+ public DbFirstController(ISqlSugarClient sqlSugarClient, IWebHostEnvironment env)
+ {
+ _sqlSugarClient = sqlSugarClient as SqlSugarClient;
+ Env = env;
+ }
+
+ ///
+ /// 获取 整体框架 文件
+ ///
+ ///
+ [HttpGet]
+ public MessageModel GetFrameFiles()
+ {
+ var data = new MessageModel() { success = true, msg = "" };
+ data.response += @"file path is:C:\my-file\}";
+ var isMuti = Appsettings.app(new string[] { "MutiDBEnabled" }).ObjToBool();
+ if (Env.IsDevelopment())
+ {
+ data.response += $"Controller层生成:{FrameSeed.CreateControllers(_sqlSugarClient)} || ";
+
+ BaseDBConfig.MutiConnectionString.Item1.ToList().ForEach(m =>
+ {
+ _sqlSugarClient.ChangeDatabase(m.ConnId.ToLower());
+ data.response += $"库{m.ConnId}-Model层生成:{FrameSeed.CreateModels(_sqlSugarClient, m.ConnId, isMuti)} || ";
+ data.response += $"库{m.ConnId}-IRepositorys层生成:{FrameSeed.CreateIRepositorys(_sqlSugarClient, m.ConnId, isMuti)} || ";
+ data.response += $"库{m.ConnId}-IServices层生成:{FrameSeed.CreateIServices(_sqlSugarClient, m.ConnId, isMuti)} || ";
+ data.response += $"库{m.ConnId}-Repository层生成:{FrameSeed.CreateRepository(_sqlSugarClient, m.ConnId, isMuti)} || ";
+ data.response += $"库{m.ConnId}-Services层生成:{FrameSeed.CreateServices(_sqlSugarClient, m.ConnId, isMuti)} || ";
+ });
+
+ // 切回主库
+ _sqlSugarClient.ChangeDatabase(MainDb.CurrentDbConnId.ToLower());
+ }
+ else
+ {
+ data.success = false;
+ data.msg = "当前不处于开发模式,代码生成不可用!";
+ }
+
+ return data;
+ }
+
+ ///
+ /// 根据数据库表名 生成整体框架
+ /// 仅针对通过CodeFirst生成表的情况
+ ///
+ /// 数据库链接名称
+ /// 需要生成的表名
+ ///
+ [HttpPost]
+ public MessageModel GetFrameFilesByTableNames([FromBody]string[] tableNames, [FromQuery]string ConnID = null)
+ {
+ ConnID = ConnID == null ? MainDb.CurrentDbConnId.ToLower() : ConnID;
+
+ var isMuti = Appsettings.app(new string[] { "MutiDBEnabled" }).ObjToBool();
+ var data = new MessageModel() { success = true, msg = "" };
+ if (Env.IsDevelopment())
+ {
+
+ data.response += $"库{ConnID}-IRepositorys层生成:{FrameSeed.CreateIRepositorys(_sqlSugarClient, ConnID, isMuti, tableNames)} || ";
+ data.response += $"库{ConnID}-IServices层生成:{FrameSeed.CreateIServices(_sqlSugarClient, ConnID, isMuti, tableNames)} || ";
+ data.response += $"库{ConnID}-Repository层生成:{FrameSeed.CreateRepository(_sqlSugarClient, ConnID, isMuti, tableNames)} || ";
+ data.response += $"库{ConnID}-Services层生成:{FrameSeed.CreateServices(_sqlSugarClient, ConnID, isMuti, tableNames)} || ";
+ }
+ else
+ {
+ data.success = false;
+ data.msg = "当前不处于开发模式,代码生成不可用!";
+ }
+
+ return data;
+ }
+
+ ///
+ /// DbFrist 根据数据库表名 生成整体框架,包含Model层
+ ///
+ /// 数据库链接名称
+ /// 需要生成的表名
+ ///
+ [HttpPost]
+ public MessageModel GetAllFrameFilesByTableNames([FromBody]string[] tableNames, [FromQuery]string ConnID = null)
+ {
+ ConnID = ConnID == null ? MainDb.CurrentDbConnId.ToLower() : ConnID;
+
+ var isMuti = Appsettings.app(new string[] { "MutiDBEnabled" }).ObjToBool();
+ var data = new MessageModel() { success = true, msg = "" };
+ if (Env.IsDevelopment())
+ {
+ _sqlSugarClient.ChangeDatabase(ConnID.ToLower());
+ data.response += $"Controller层生成:{FrameSeed.CreateControllers(_sqlSugarClient, ConnID, isMuti, tableNames)} || ";
+ data.response += $"库{ConnID}-Model层生成:{FrameSeed.CreateModels(_sqlSugarClient, ConnID, isMuti, tableNames)} || ";
+ data.response += $"库{ConnID}-IRepositorys层生成:{FrameSeed.CreateIRepositorys(_sqlSugarClient, ConnID, isMuti, tableNames)} || ";
+ data.response += $"库{ConnID}-IServices层生成:{FrameSeed.CreateIServices(_sqlSugarClient, ConnID, isMuti, tableNames)} || ";
+ data.response += $"库{ConnID}-Repository层生成:{FrameSeed.CreateRepository(_sqlSugarClient, ConnID, isMuti, tableNames)} || ";
+ data.response += $"库{ConnID}-Services层生成:{FrameSeed.CreateServices(_sqlSugarClient, ConnID, isMuti, tableNames)} || ";
+ // 切回主库
+ _sqlSugarClient.ChangeDatabase(MainDb.CurrentDbConnId.ToLower());
+ }
+ else
+ {
+ data.success = false;
+ data.msg = "当前不处于开发模式,代码生成不可用!";
+ }
+
+ return data;
+ }
+
+
+ }
+}
\ No newline at end of file
diff --git a/New_College.Api/Controllers/DbFirst/MigrateController.cs b/New_College.Api/Controllers/DbFirst/MigrateController.cs
new file mode 100644
index 0000000..2476e46
--- /dev/null
+++ b/New_College.Api/Controllers/DbFirst/MigrateController.cs
@@ -0,0 +1,191 @@
+using New_College.Common.Helper;
+using New_College.IRepository.UnitOfWork;
+using New_College.IServices;
+using New_College.Model;
+using New_College.Model.Models;
+using Microsoft.AspNetCore.Hosting;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.Extensions.Hosting;
+using Newtonsoft.Json;
+using System;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace New_College.Controllers
+{
+ [Route("api/[controller]/[action]")]
+ [ApiController]
+ //[Authorize(Permissions.Name)]
+ public class MigrateController : ControllerBase
+ {
+ private readonly IUnitOfWork _unitOfWork;
+ private readonly IRoleModulePermissionServices _roleModulePermissionServices;
+ private readonly IUserRoleServices _userRoleServices;
+ private readonly IRoleServices _roleServices;
+ private readonly IPermissionServices _permissionServices;
+ private readonly IModuleServices _moduleServices;
+ private readonly IWebHostEnvironment _env;
+
+ public MigrateController(IUnitOfWork unitOfWork,
+ IRoleModulePermissionServices roleModulePermissionServices,
+ IUserRoleServices userRoleServices,
+ IRoleServices roleServices,
+ IPermissionServices permissionServices,
+ IModuleServices moduleServices,
+ IWebHostEnvironment env)
+ {
+ _unitOfWork = unitOfWork;
+ _roleModulePermissionServices = roleModulePermissionServices;
+ _userRoleServices = userRoleServices;
+ _roleServices = roleServices;
+ _permissionServices = permissionServices;
+ _moduleServices = moduleServices;
+ _env = env;
+ }
+
+ ///
+ /// 获取权限部分Map数据(从库)
+ /// 迁移到新库(主库)
+ ///
+ ///
+ [HttpGet]
+ public async Task> DataMigrateFromOld2New()
+ {
+ var data = new MessageModel() { success = true, msg = "" };
+ if (_env.IsDevelopment())
+ {
+ try
+ {
+ // 获取权限集合数据
+ var rmps = await _roleModulePermissionServices.GetRMPMaps();
+ // 当然,你可以做个where查询
+ //rmps = rmps.Where(d => d.ModuleId > 88).ToList();
+
+ // 开启事务,保证数据一致性
+ _unitOfWork.BeginTran();
+
+ var rid = 0;
+ var pid = 0;
+ var mid = 0;
+ var rpmid = 0;
+
+ // 注意信息的完整性,不要重复添加,确保主库没有要添加的数据
+ foreach (var item in rmps)
+ {
+ // 角色信息,防止重复添加,做了判断
+ if (item.Role != null)
+ {
+ var isExit = (await _roleServices.Query(d => d.Name == item.Role.Name && d.IsDeleted == false)).FirstOrDefault();
+ if (isExit == null)
+ {
+ rid = await _roleServices.Add(item.Role);
+ Console.WriteLine($"Role Added:{item.Role.Name}");
+ }
+ else
+ {
+ rid = isExit.Id;
+ }
+ }
+
+ // 菜单
+ if (item.Permission != null)
+ {
+ pid = await _permissionServices.Add(item.Permission);
+ Console.WriteLine($"Permission Added:{item.Permission.Name}");
+ }
+
+ // 接口
+ if (item.Module != null)
+ {
+ mid = await _moduleServices.Add(item.Module);
+ Console.WriteLine($"Module Added:{item.Module.LinkUrl}");
+ }
+
+ // 关系
+ if (rid > 0 && pid > 0 && mid > 0)
+ {
+ rpmid = await _roleModulePermissionServices.Add(new RoleModulePermission()
+ {
+ IsDeleted = false,
+ CreateTime = DateTime.Now,
+ ModifyTime = DateTime.Now,
+ ModuleId = mid,
+ PermissionId = pid,
+ RoleId = rid,
+ });
+ Console.WriteLine($"RMP Added:{rpmid}");
+ }
+
+ }
+
+
+ _unitOfWork.CommitTran();
+
+ data.success = true;
+ data.msg = "导入成功!";
+ }
+ catch (Exception)
+ {
+ _unitOfWork.RollbackTran();
+
+ }
+ }
+ else
+ {
+ data.success = false;
+ data.msg = "当前不处于开发模式,代码生成不可用!";
+ }
+
+ return data;
+ }
+
+
+ ///
+ /// 权限数据库导出tsv
+ ///
+ ///
+ [HttpGet]
+ public async Task> SaveData2TsvAsync()
+ {
+ var data = new MessageModel() { success = true, msg = "" };
+ if (_env.IsDevelopment())
+ {
+ try
+ {
+ // 取出数据,序列化,自己可以处理判空
+ var rolesJson = JsonConvert.SerializeObject(await _roleServices.Query(d => d.IsDeleted == false));
+ FileHelper.WriteFile(Path.Combine(_env.WebRootPath, "BlogCore.Data.json", "Role_New.tsv"), rolesJson, Encoding.UTF8);
+
+
+ var permissionsJson = JsonConvert.SerializeObject(await _permissionServices.Query(d => d.IsDeleted == false));
+ FileHelper.WriteFile(Path.Combine(_env.WebRootPath, "BlogCore.Data.json", "Permission_New.tsv"), permissionsJson, Encoding.UTF8);
+
+
+ var modulesJson = JsonConvert.SerializeObject(await _moduleServices.Query(d => d.IsDeleted == false));
+ FileHelper.WriteFile(Path.Combine(_env.WebRootPath, "BlogCore.Data.json", "Modules_New.tsv"), modulesJson, Encoding.UTF8);
+
+
+ var rmpsJson = JsonConvert.SerializeObject(await _roleModulePermissionServices.Query(d => d.IsDeleted == false));
+ FileHelper.WriteFile(Path.Combine(_env.WebRootPath, "BlogCore.Data.json", "RoleModulePermission_New.tsv"), rmpsJson, Encoding.UTF8);
+ }
+ catch (Exception)
+ {
+ }
+
+
+ data.success = true;
+ data.msg = "生成成功!";
+ }
+ else
+ {
+ data.success = false;
+ data.msg = "当前不处于开发模式,代码生成不可用!";
+ }
+
+ return data;
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/New_College.Api/Controllers/Front/CustomerController.cs b/New_College.Api/Controllers/Front/CustomerController.cs
new file mode 100644
index 0000000..bb009b5
--- /dev/null
+++ b/New_College.Api/Controllers/Front/CustomerController.cs
@@ -0,0 +1,199 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Mvc;
+using New_College.AuthHelper.OverWrite;
+using New_College.IServices;
+using New_College.Model;
+using New_College.Model.Request;
+using New_College.Model.ViewModels;
+
+namespace New_College.Api.Controllers.Front
+{
+ [Route("api/front/[controller]/[action]")]
+ [ApiController]
+ [Authorize(Roles = "users")]
+ public class CustomerController : ControllerBase
+ {
+ private readonly IV_CustomerInfoServices _services;
+ public CustomerController(IV_CustomerInfoServices IV_CustomerInfoServices)
+ {
+ _services = IV_CustomerInfoServices;
+ }
+
+
+ ///
+ /// 获取微信openid
+ ///
+ ///
+ ///
+ [HttpPost]
+ [AllowAnonymous]
+ public MessageModel GetWeixinAuthinfo(WeixinLogin login)
+ {
+ var response = new CustomerInfoResult();
+ try
+ {
+ var result = _services.AuthCode2Session(login.code);
+ if (result.openid != "" && result.openid != null)
+ {
+ var loginstatus = _services.Logined(new LoginQuery() { openId = result.openid }).Result;
+ if (loginstatus.Item1)
+ {
+ response = loginstatus.Item2;
+ }
+ else
+ {
+ var save = _services.CustomerSave(new DecryptUserInfoRequest() { openid = result.openid }).Result;
+ response.OpenId = result.openid;
+ response.Id = save;
+ }
+ TokenModelJwt tokenModel = new TokenModelJwt { Uid = response.Id, Role = "users" };
+ response.Token = JwtHelper.IssueJwt(tokenModel);
+ return new MessageModel()
+ {
+ success = true,
+ msg = "success",
+ response = response
+ };
+ }
+ else
+ {
+ return new MessageModel()
+ {
+ success = false,
+ response = response
+ };
+ }
+ }
+ catch (Exception ex)
+ {
+ return new MessageModel()
+ {
+ msg = ex.ToString(),
+ success = false,
+ response = response
+ };
+ }
+ }
+
+
+
+
+
+ ///
+ /// 解密手机号同时保存用户信息
+ ///
+ ///
+ ///
+ [HttpPost]
+ public async Task> WeixinDecryptUserInfo(DecryptUserInfoRequest request)
+ {
+ var phoneinfo = _services.GetWeixinPhone(new GetPhoneInfo()
+ {
+
+ encryptedData = request.encryptedData,
+ iv = request.iv,
+ openid = request.openid,
+ session_key = request.session_key
+ });
+ request.phone = phoneinfo;
+ var customerinfo = (await _services.Query(e => e.OpenId == request.openid)).FirstOrDefault();
+ customerinfo.AvatarUrl = request.avatarUrl;
+ customerinfo.NickName = request.nickName;
+ customerinfo.Gender = request.gender;
+ customerinfo.Phone = phoneinfo;
+ var result = await _services.Update(customerinfo);
+ return new MessageModel()
+ {
+ msg = result ? "修改成功" : "保存失败",
+ response = result,
+ success = result
+ };
+
+ }
+
+
+
+
+ ///
+ ///用户获取用户信息有OpenId 调用此接口
+ ///
+ ///
+ ///
+ [HttpGet]
+ public async Task> GetUserInfo([FromQuery] LoginQuery query)
+ {
+ var result = await _services.GetUserInfo(query);
+ return new MessageModel()
+ {
+ response = result.Item2,
+ success = result.Item1,
+ msg = result.Item1 ? "登陆成功" : "用户不存在"
+ };
+ }
+
+
+
+
+
+
+ ///
+ /// 更改分数
+ ///
+ ///
+ ///
+ [HttpPost]
+ public async Task> UpdateScore(UpdateScoreQuery query)
+ {
+ var result = await _services.UpdateScore(query);
+ if (result.Id > 0)
+ {
+ var token = JwtHelper.IssueJwt(new TokenModelJwt() { Uid = result.Id, Role = "学生" });
+ result.Token = token;
+ }
+ return new MessageModel()
+ {
+ success = result.Status == 1,
+ msg = result.Status == 1 ? "修改成功" : "修改失败",
+ response = result
+ };
+ }
+
+ ///
+ /// 完善用户信息
+ ///
+ ///
+ ///
+ [HttpPost]
+ public async Task> UpdateCustomer(CustomerUpdateQuery query)
+ {
+ var result = await _services.UpdateCustomer(query);
+ if (result.Id > 0)
+ {
+ var token = JwtHelper.IssueJwt(new TokenModelJwt() { Uid = result.Id, Role = "学生" });
+ result.Token = token;
+ }
+ return new MessageModel()
+ {
+ success = result.Status == 1,
+ msg = result.Status == 1 ? "成功" : "失败",
+ response = result
+ };
+ }
+
+ ///
+ /// 根绝Id获取用户信息
+ ///
+ ///
+ ///
+ [HttpGet]
+ public async Task> GetCustomerInfoById([FromQuery] IdQuery query)
+ {
+ return await _services.GetCustomerInfoById(query);
+ }
+ }
+}
diff --git a/New_College.Api/Controllers/Front/ExaminationPolicyController.cs b/New_College.Api/Controllers/Front/ExaminationPolicyController.cs
new file mode 100644
index 0000000..525da47
--- /dev/null
+++ b/New_College.Api/Controllers/Front/ExaminationPolicyController.cs
@@ -0,0 +1,37 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Mvc;
+using New_College.AuthHelper.OverWrite;
+using New_College.IServices;
+using New_College.Model;
+using New_College.Model.ViewModels;
+
+namespace New_College.Api.Controllers.Front
+{
+ [Route("api/front/[controller]/[action]")]
+ [ApiController]
+ [Authorize]
+ public class ExaminationPolicyController : ControllerBase
+ {
+ private readonly IV_ExaminationPolicyServices iV_ExaminationPolicyServices;
+ public ExaminationPolicyController(IV_ExaminationPolicyServices IV_ExaminationPolicyServices)
+ {
+ iV_ExaminationPolicyServices = IV_ExaminationPolicyServices;
+ }
+
+ ///
+ /// 获取考试时间
+ ///
+ ///
+ ///
+ [HttpGet]
+ public async Task> GetExaminationPolicyDetail([FromQuery] ExaminationPolicyAreaQuery query)
+ {
+ return await iV_ExaminationPolicyServices.GetExaminationPolicyDetail(query);
+ }
+ }
+}
diff --git a/New_College.Api/Controllers/Front/LibraryController.cs b/New_College.Api/Controllers/Front/LibraryController.cs
new file mode 100644
index 0000000..1ddf48d
--- /dev/null
+++ b/New_College.Api/Controllers/Front/LibraryController.cs
@@ -0,0 +1,334 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Mvc;
+using New_College.IServices;
+using New_College.Model;
+using New_College.Model.ViewModels;
+
+
+namespace New_College.Api.Controllers.Front
+{
+ [Route("api/front/[controller]/[action]")]
+ [ApiController]
+ public class LibraryController : ControllerBase
+ {
+ private readonly ID_LongIdMapServices iD_LongIdMapServices;
+ public LibraryController(ID_LongIdMapServices ID_LongIdMapServices)
+ {
+ iD_LongIdMapServices = ID_LongIdMapServices;
+ }
+
+ ///
+ /// 获取院校库
+ ///
+ ///
+ ///
+ [HttpGet]
+ public async Task>> GetUniversitys([FromQuery] UniversityQuery query)
+ {
+ var result = await iD_LongIdMapServices.GetUniversitys(query);
+ if (result.data == null || result.data.Count <= 0)
+ {
+ return new MessageModel>()
+ {
+ success = false,
+ msg = "获取失败",
+ };
+ }
+ else
+ {
+ return new MessageModel>()
+ {
+ success = true,
+ msg = "获取成功",
+ response = result
+ };
+
+ }
+
+ }
+
+ ///
+ /// 专业库 一级二级列表
+ ///
+ ///
+ ///
+ [HttpGet]
+ public async Task>> uniGetMajorInfo([FromQuery] MajorcategoryQuery query)
+ {
+ var result = await iD_LongIdMapServices.uniGetMajorInfo(query);
+ return new MessageModel>()
+ {
+ success = result.Count <= 0 ? false : true,
+ msg = result.Count <= 0 ? "获取失败" : "获取成功",
+ response = result
+ };
+ }
+
+ ///
+ /// 获取推荐职业
+ ///
+ ///
+ [HttpGet]
+ public async Task>> GetRecommendOccupation()
+ {
+ var result = await iD_LongIdMapServices.GetRecommendOccupation();
+ return new MessageModel>()
+ {
+ success = result.Count <= 0 ? false : true,
+ msg = result.Count <= 0 ? "获取失败" : "获取成功",
+ response = result
+ };
+ }
+
+ ///
+ /// 职业库 一级二级列表
+ ///
+ ///
+ [HttpGet]
+ public async Task>> uniGetOccupationInfo()
+ {
+ var result = await iD_LongIdMapServices.uniGetOccupationInfo();
+ return new MessageModel>()
+ {
+ success = result.Count <= 0 ? false : true,
+ msg = result.Count <= 0 ? "获取失败" : "获取成功",
+ response = result
+ };
+ }
+
+ ///
+ /// 获取职业第三级
+ ///
+ ///
+ ///
+ [HttpGet]
+ public async Task>> GetOccupationThree([FromQuery] IdQuery query)
+ {
+ return await iD_LongIdMapServices.GetOccupationThree(query);
+ }
+
+ ///
+ /// 院校详情
+ ///
+ ///
+ ///
+ [HttpGet]
+ public async Task> GetUniversityDetails([FromQuery] IdQuery query)
+ {
+ var result = await iD_LongIdMapServices.GetUniversityDetails(query);
+ return new MessageModel()
+ {
+ success = result.Status == 1 ? true : false,
+ msg = result.Status == 1 ? "获取成功" : "获取失败",
+ response = result
+ };
+ }
+
+ ///
+ /// 获取专业介绍
+ ///
+ ///
+ ///
+ [HttpGet]
+ public async Task> GetMajorDetail([FromQuery] MajorQuery query)
+ {
+ var result = await iD_LongIdMapServices.GetMajorDetail(query);
+ return new MessageModel()
+ {
+ success = result.id > 0 ? true : false,
+ msg = result.id > 0 ? "获取成功" : "获取失败",
+ response = result
+ };
+ }
+
+ ///
+ /// 相关院校
+ ///
+ ///
+ ///
+ [HttpGet]
+ public async Task>> GetRelevantSchool([FromQuery] MajorSchoolQuery query)
+ {
+ var result = await iD_LongIdMapServices.GetRelevantSchool(query);
+ return new MessageModel>()
+ {
+ success = (result.data == null || result.data.Count <= 0) == true ? false : true,
+ msg = (result.data == null || result.data.Count <= 0) == true ? "获取失败" : "获取成功",
+ response = result
+ };
+ }
+
+ ///
+ /// 获取专业就业前景
+ ///
+ ///
+ ///
+ [HttpGet]
+ public async Task> GetCareerProspects([FromQuery] MajorCareerQuery query)
+ {
+ var result = await iD_LongIdMapServices.GetCareerProspects(query);
+ return new MessageModel()
+ {
+ success = true,
+ msg = "获取成功",
+ response = result
+ };
+ }
+
+ ///
+ /// 获取第三级
+ ///
+ ///
+ ///
+ [HttpGet]
+ public async Task>> uniGetMajorThree([FromQuery] ManageMajorQuery query)
+ {
+ return await iD_LongIdMapServices.uniGetMajorThree(query);
+ }
+
+ ///
+ /// 根据标签推荐专业
+ ///
+ ///
+ ///
+ [HttpGet]
+ public async Task>> GetMajorThreeByTag([FromQuery] MajorThreeByTagQuery query)
+ {
+ return await iD_LongIdMapServices.GetMajorThreeByTag(query);
+ }
+
+ ///
+ /// 获取职业详情-职业介绍
+ ///
+ ///
+ [HttpGet]
+ public async Task> GetRecommendIntroduce([FromQuery] IdQuery query)
+ {
+ var result = await iD_LongIdMapServices.GetRecommendIntroduce(query);
+ return new MessageModel()
+ {
+ success = result.Status == 1 ? true : false,
+ msg = result.Status == 1 ? "获取成功" : "获取失败",
+ response = result
+ };
+ }
+
+ ///
+ /// 院校相关专业专用
+ ///
+ ///
+ ///
+ [HttpGet]
+ public async Task>> GetUniversityMajor([FromQuery] IdQuery query)
+ {
+ var result = await iD_LongIdMapServices.GetUniversityMajor(query);
+ return new MessageModel>()
+ {
+ success = true,
+ msg = "获取成功",
+ response = result
+ };
+ }
+
+ ///
+ /// 查学校省份的 年份批次
+ ///
+ ///
+ ///
+ [HttpGet]
+ public async Task> GetBatchYearBySchoolId([FromQuery] PlanYearQuery query)
+ {
+ var result = await iD_LongIdMapServices.GetBatchYearBySchoolId(query);
+ return new MessageModel()
+ {
+ success = result != null,
+ msg = result != null ? "获取成功" : "获取失败",
+ response = result
+ };
+ }
+
+ ///
+ /// 获取招生计划 院校详情
+ ///
+ ///
+ ///
+ [HttpGet]
+ public async Task>> GetPlanBySchollId([FromQuery] PlanQuery query)
+ {
+ var result = await iD_LongIdMapServices.GetPlanBySchollId(query);
+ if (result == null || result.Count() <= 0)
+ {
+ return new MessageModel>()
+ {
+ success = false,
+ msg = "获取失败"
+ };
+ }
+ else
+ {
+ return new MessageModel>()
+ {
+ success = true,
+ msg = "获取成功",
+ response = result
+ };
+ }
+ }
+
+ ///
+ /// 获取院校排名
+ ///
+ ///
+ ///
+ [HttpGet]
+ public async Task>> GetUniversityRank([FromQuery] UniversityRankQuery query)
+ {
+ var result = await iD_LongIdMapServices.GetUniversityRank(query);
+ return new MessageModel>()
+ {
+ success = result.Count > 0,
+ msg = result.Count > 0 ? "获取成功" : "获取失败",
+ response = result
+ };
+ }
+
+ ///
+ /// 专业搜索
+ ///
+ ///
+ ///
+ [HttpGet]
+ public async Task>> uniGetSearchMajor([FromQuery] NameBaseQuery query)
+ {
+ return await iD_LongIdMapServices.uniGetSearchMajor(query);
+ }
+
+ ///
+ /// 获取招生简章列表
+ ///
+ ///
+ ///
+ [HttpGet]
+ public async Task>> GetRequestEnrollmentinproductionResult([FromQuery] UniversityIdQuery query)
+ {
+ return await iD_LongIdMapServices.GetRequestEnrollmentinproductionResult(query);
+ }
+
+
+ ///
+ /// 获取招生简介详情
+ ///
+ ///
+ ///
+ [HttpGet]
+ public async Task> GetRequestEnrollmentinproductionDetailResult([FromQuery] StringIdQuery query)
+ {
+ return await iD_LongIdMapServices.GetRequestEnrollmentinproductionDetailResult(query);
+ }
+ }
+}
diff --git a/New_College.Api/Controllers/Front/MajorSalaryController.cs b/New_College.Api/Controllers/Front/MajorSalaryController.cs
new file mode 100644
index 0000000..0851dec
--- /dev/null
+++ b/New_College.Api/Controllers/Front/MajorSalaryController.cs
@@ -0,0 +1,33 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Mvc;
+using New_College.IServices;
+using New_College.Model;
+using New_College.Model.ViewModels;
+
+namespace New_College.Api.Controllers.Front
+{
+ [Route("api/front/[controller]/[action]")]
+ [ApiController]
+ public class MajorSalaryController : ControllerBase
+ {
+ private readonly ID_MajorSalaryServices iD_MajorSalaryServices;
+ public MajorSalaryController(ID_MajorSalaryServices ID_MajorSalaryServices)
+ {
+ iD_MajorSalaryServices = ID_MajorSalaryServices;
+ }
+
+ ///
+ /// 获取高薪推荐
+ ///
+ ///
+ [HttpGet]
+ public async Task>> GetMajorSalaryResult([FromQuery] MajorSalaryQuery query)
+ {
+ return await iD_MajorSalaryServices.GetMajorSalaryResult(query);
+ }
+ }
+}
diff --git a/New_College.Api/Controllers/Front/OrderController.cs b/New_College.Api/Controllers/Front/OrderController.cs
new file mode 100644
index 0000000..fd9e908
--- /dev/null
+++ b/New_College.Api/Controllers/Front/OrderController.cs
@@ -0,0 +1,39 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Mvc;
+using New_College.IServices;
+using New_College.Model;
+using New_College.Model.ViewModels;
+
+namespace New_College.Api.Controllers.Front
+{
+ [Route("api/front/[controller]/[action]")]
+ [ApiController]
+ public class OrderController : ControllerBase
+ {
+ private readonly IV_OrderInfoServices v_OrderInfoServices;
+ public OrderController(IV_OrderInfoServices IV_OrderInfoServices)
+ {
+ v_OrderInfoServices = IV_OrderInfoServices;
+ }
+
+ ///
+ /// 下订单
+ ///
+ ///
+ [HttpPost]
+ public async Task> CreateOrder(UniOrderQuery query)
+ {
+ var result = await v_OrderInfoServices.CreateOrder(query);
+ return new MessageModel()
+ {
+ success = result.success,
+ msg = result.msg,
+ response = result
+ };
+ }
+ }
+}
diff --git a/New_College.Api/Controllers/Front/RegionController.cs b/New_College.Api/Controllers/Front/RegionController.cs
new file mode 100644
index 0000000..6336681
--- /dev/null
+++ b/New_College.Api/Controllers/Front/RegionController.cs
@@ -0,0 +1,43 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Mvc;
+using New_College.IServices;
+using New_College.Model;
+using New_College.Model.ViewModels;
+
+namespace New_College.Api.Controllers.Front
+{
+ [Route("api/front/[controller]/[action]")]
+ [ApiController]
+ public class RegionController : ControllerBase
+ {
+ private readonly ISysRegionServices sysRegionServices;
+ public RegionController(ISysRegionServices ISysRegionServices)
+ {
+ sysRegionServices = ISysRegionServices;
+ }
+
+ ///
+ /// 获取省市区
+ ///
+ ///
+ ///
+ [HttpGet]
+ public async Task>> GetRegionList([FromQuery] SysRegionQuery query)
+ {
+ List list = new List() { };
+ list.Add(new SysRegionResult() { Id = 0, Code = "0", Name = "全国" });
+ var result = await sysRegionServices.GetRegionList(query);
+ list.AddRange(result);
+ return new MessageModel>()
+ {
+ success = true,
+ msg = "成功",
+ response = list
+ };
+ }
+ }
+}
diff --git a/New_College.Api/Controllers/Front/TestController.cs b/New_College.Api/Controllers/Front/TestController.cs
new file mode 100644
index 0000000..edc0096
--- /dev/null
+++ b/New_College.Api/Controllers/Front/TestController.cs
@@ -0,0 +1,325 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Mvc;
+using New_College.IServices;
+using New_College.Model;
+using New_College.Model.ViewModels;
+
+namespace New_College.Api.Controllers.Front
+{
+ [Route("api/front/[controller]/[action]")]
+ [ApiController]
+
+ public class TestController : ControllerBase
+ {
+ private readonly ITest_CategoryInfoServices test_CategoryInfoServices;
+ private readonly ITest_QuestionInfoServices test_QuestionInfoServices;
+ private readonly IV_SubjectSelectServices v_SubjectSelectServices;
+ private readonly ITest_PsychMeasurementInfoServices test_PsychMeasurementInfoServices;
+ private readonly IT_EnrollmentPlanedescServices t_EnrollmentPlanedescServices;
+
+ public TestController(ITest_CategoryInfoServices ITest_CategoryInfoServices
+ , ITest_QuestionInfoServices ITest_QuestionInfoServices
+ , ITest_PsychMeasurementInfoServices ITest_PsychMeasurementInfoServices
+ , IV_SubjectSelectServices IV_SubjectSelectServices
+ , IT_EnrollmentPlanedescServices IT_EnrollmentPlanedescServices)
+ {
+ test_CategoryInfoServices = ITest_CategoryInfoServices;
+ test_QuestionInfoServices = ITest_QuestionInfoServices;
+ test_PsychMeasurementInfoServices = ITest_PsychMeasurementInfoServices;
+ v_SubjectSelectServices = IV_SubjectSelectServices;
+ t_EnrollmentPlanedescServices = IT_EnrollmentPlanedescServices;
+ }
+
+ ///
+ /// 获取分类 根绝type
+ ///
+ ///
+ [HttpGet]
+ public async Task>> GetCateSelectByType([FromQuery] CategoryInfoQuery query)
+ {
+ var result = await test_CategoryInfoServices.GetCateSelectByType(query);
+ return new MessageModel>()
+ {
+ success = true,
+ msg = "获取成功",
+ response = result
+ };
+ }
+
+ ///
+ /// 获取个人某个维度测评结果
+ ///
+ ///
+ ///
+ [HttpGet]
+ [Authorize]
+ public async Task>> GetPsychListByCateAndCustomerId([FromQuery] PsychMeasurementQuery query)
+ {
+ var result = await test_PsychMeasurementInfoServices.GetPsychListByCateAndCustomerId(query);
+ return new MessageModel>()
+ {
+ msg = "获取成功",
+ success = true,
+ response = result
+ };
+ }
+
+ ///
+ /// 获取测评状态
+ ///
+ ///
+ ///
+ [HttpGet]
+ [Authorize]
+ public async Task> GetTestStatus([FromQuery] CategoryStatusQuery query)
+ {
+ var result = await test_CategoryInfoServices.GetTestStatus(query);
+ return new MessageModel()
+ {
+ msg = "获取成功",
+ success = true,
+ response = result
+ };
+ }
+
+ ///
+ /// 获取问题
+ ///
+ ///
+ ///
+ [HttpGet]
+ [Authorize]
+ public async Task>> GetQuestion([FromQuery] appQuestionQuery query)
+ {
+ var result = await test_QuestionInfoServices.GetQuestion(query);
+ return new MessageModel>()
+ {
+ success = true,
+ msg = "获取成功",
+ response = result
+ };
+ }
+
+ ///
+ /// 获取mbti试题
+ ///
+ ///
+ [HttpGet]
+ [Authorize]
+ public async Task>> GetQuestionMBTI()
+ {
+ var result = await test_QuestionInfoServices.GetQuestionMBTI();
+ return new MessageModel>()
+ {
+ success = true,
+ msg = "获取成功",
+ response = result
+ };
+ }
+
+ ///
+ /// 提交
+ ///
+ ///
+ [HttpPost]
+ [Authorize]
+ public async Task> SavePsych([FromBody] SavePsychQuery query)
+ {
+ var result = await test_PsychMeasurementInfoServices.SavePsych(query);
+ return new MessageModel()
+ {
+ success = result,
+ msg = result == true ? "提交成功" : "提交失败",
+ response = result
+ };
+ }
+
+ ///
+ /// 提交 霍兰德和MBTI
+ ///
+ ///
+ ///
+ [HttpPost]
+ [Authorize]
+ public async Task> SaveHolland(SaveHollandQuery query)
+ {
+ var result = await test_PsychMeasurementInfoServices.SaveHolland(query);
+ return new MessageModel()
+ {
+ success = result,
+ msg = result == true ? "提交成功" : "提交失败",
+ response = result
+ };
+ }
+
+ ///
+ /// 获取学生发展
+ ///
+ ///
+ ///
+ [HttpGet]
+ [Authorize]
+ public async Task> GetPsychDetail([FromQuery] ResultLookQuery query)
+ {
+ var result = await test_PsychMeasurementInfoServices.GetPsychDetail(query);
+ return new MessageModel()
+ {
+ success = true,
+ msg = "获取成功",
+ response = result
+ };
+ }
+
+ ///
+ /// 获取霍兰德测评结果
+ ///
+ ///
+ ///
+ [HttpGet]
+ [Authorize]
+ public async Task> GetHollandResult([FromQuery] ResultLookQuery query)
+ {
+ var result = await test_PsychMeasurementInfoServices.GetHollandResult(query);
+ return new MessageModel()
+ {
+ success = true,
+ msg = "获取成功",
+ response = result
+ };
+ }
+
+ ///
+ /// 获取MBTI测评结果
+ ///
+ ///
+ ///
+ [HttpGet]
+ [Authorize]
+ public async Task> GetMBTIResult([FromQuery] ResultLookQuery query)
+ {
+ var result = await test_PsychMeasurementInfoServices.GetMBTIResult(query);
+ return new MessageModel()
+ {
+ success = true,
+ msg = "获取成功",
+ response = result
+ };
+ }
+
+
+ ///
+ /// 学科探索 结果
+ ///
+ ///
+ ///
+ [HttpGet]
+ [Authorize]
+ public async Task> SubjectChartRadar([FromQuery] ResultLookQuery query)
+ {
+ return await test_PsychMeasurementInfoServices.SubjectChartRadar(query);
+ }
+
+ ///
+ /// 传入用户Id 获取霍兰德测评状态
+ ///
+ ///
+ ///
+ [HttpGet]
+ [Authorize]
+ public async Task> GetHollandStatus([FromQuery] IdQuery query)
+ {
+ return await test_PsychMeasurementInfoServices.GetHollandStatus(query);
+ }
+
+ ///
+ /// 传入用户Id 获取学科探索测评状态
+ ///
+ ///
+ ///
+ [HttpGet]
+ [Authorize]
+ public async Task> GetSubjectSelectStatus([FromQuery] IdQuery query)
+ {
+ return await test_PsychMeasurementInfoServices.GetSubjectSelectStatus(query);
+ }
+
+
+ ///
+ /// 获取我的自选科目
+ ///
+ ///
+ ///
+ [HttpGet]
+ [Authorize]
+ public async Task> GetSubjectSelect([FromQuery] IdQuery query)
+ {
+ return await v_SubjectSelectServices.GetSubjectSelect(query);
+ }
+
+ ///
+ /// 保存我的选科
+ ///
+ ///
+ ///
+ [HttpPost]
+ [Authorize]
+ public async Task> SaveSubjectSelect([FromBody] SubjectSelectQuery query)
+ {
+ return await v_SubjectSelectServices.SaveSubjectSelect(query);
+ }
+
+ ///
+ /// 根据标签推荐选科
+ ///
+ ///
+ ///
+ [HttpGet]
+ [Authorize]
+ public async Task> GetSubjectSelectByTag([FromQuery] ByTagSubjectSelectQuery query)
+ {
+ return await t_EnrollmentPlanedescServices.GetSubjectSelectByTag(query);
+ }
+
+ ///
+ /// 获取测评最新周期Id
+ ///
+ ///
+ ///
+ [HttpGet]
+ [Authorize]
+ public async Task> GetReportCycleInfo([FromQuery] IdQuery query)
+ {
+ return await test_PsychMeasurementInfoServices.GetReportCycleInfo(query);
+ }
+
+ ///
+ /// 获取三种推荐选科
+ ///
+ ///
+ ///
+ [HttpGet]
+ //[Authorize]
+ public async Task>> GetSubjectSelectResult([FromQuery] NewSubjectQuery query)
+ {
+ return await test_PsychMeasurementInfoServices.GetSubjectSelectResult(query);
+ }
+
+
+ ///
+ /// 根绝霍兰德获取推荐选科
+ ///
+ ///
+ ///
+ [HttpGet]
+ //[Authorize]
+ public async Task> GetHollandSubject([FromQuery]HollandSubjectQuery query)
+ {
+ return await test_PsychMeasurementInfoServices.GetHollandSubject(query);
+ }
+ }
+}
diff --git a/New_College.Api/Controllers/Front/UniversityCollectionController.cs b/New_College.Api/Controllers/Front/UniversityCollectionController.cs
new file mode 100644
index 0000000..30ca777
--- /dev/null
+++ b/New_College.Api/Controllers/Front/UniversityCollectionController.cs
@@ -0,0 +1,93 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Mvc;
+using New_College.IServices;
+using New_College.Model;
+using New_College.Model.ViewModels;
+namespace New_College.Api.Controllers.Front
+{
+ [Route("api/front/[controller]/[action]")]
+ [ApiController]
+ [Authorize]
+ public class UniversityCollectionController : ControllerBase
+ {
+ private readonly ID_UniversityCollectionServices d_UniversityCollectionServices;
+ private readonly ID_UniversityServices d_UniversityServices;
+ public UniversityCollectionController(ID_UniversityCollectionServices ID_UniversityCollectionServices
+ , ID_UniversityServices ID_UniversityServices)
+ {
+ d_UniversityCollectionServices = ID_UniversityCollectionServices;
+ d_UniversityServices = ID_UniversityServices;
+ }
+
+ ///
+ /// 获取收藏和对比
+ ///
+ ///
+ ///
+ [HttpGet]
+ public async Task>> GetUniversityCollection([FromQuery] UniversityCollectionQuery query)
+ {
+ return await d_UniversityCollectionServices.GetUniversityCollection(query);
+ }
+
+ ///
+ /// 删除
+ ///
+ ///
+ ///
+ [HttpPost]
+ public async Task> DeleteCollection(UniversityCollectionAddQuery query)
+ {
+ return await d_UniversityCollectionServices.DeleteCollection(query);
+ }
+
+ ///
+ /// 添加收藏、对比
+ ///
+ ///
+ ///
+ [HttpPost]
+ public async Task> AddCollection([FromBody] UniversityCollectionAddQuery query)
+ {
+ return await d_UniversityCollectionServices.AddCollection(query);
+ }
+
+ ///
+ /// 获取院校对比结果 传Ids
+ ///
+ ///
+ [HttpPost]
+ public async Task>> GetUniversityContrasts([FromBody] IdQuery query)
+ {
+ return await d_UniversityCollectionServices.GetUniversityContrasts(query);
+ }
+
+ ///
+ /// 获取搜索学校
+ ///
+ ///
+ ///
+ [HttpGet]
+ public async Task>> GetUniversitList([FromQuery] NameQuery query)
+ {
+ return await d_UniversityServices.GetUniversitList(query);
+ }
+
+
+ ///
+ /// 报告 获取我喜欢的院校
+ ///
+ ///
+ ///
+ [HttpGet]
+ public async Task>> GetUniversityMap([FromQuery] IdQuery query)
+ {
+ return await d_UniversityCollectionServices.GetUniversityMap(query);
+ }
+ }
+}
diff --git a/New_College.Api/Controllers/Front/VipController.cs b/New_College.Api/Controllers/Front/VipController.cs
new file mode 100644
index 0000000..ec0374b
--- /dev/null
+++ b/New_College.Api/Controllers/Front/VipController.cs
@@ -0,0 +1,68 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Mvc;
+using New_College.IServices;
+using New_College.Model;
+using New_College.Model.ViewModels;
+
+namespace New_College.Api.Controllers.Front
+{
+ [Route("api/front/[controller]/[action]")]
+ [ApiController]
+
+ public class VipController : ControllerBase
+ {
+ private readonly IV_VipCardTypeServices v_VipCardTypeServices;
+ private readonly IV_VipCardInfoServices v_VipCardInfoServices;
+ public VipController(IV_VipCardTypeServices IV_VipCardTypeServices,
+ IV_VipCardInfoServices IV_VipCardInfoServices)
+ {
+ v_VipCardTypeServices = IV_VipCardTypeServices;
+ v_VipCardInfoServices = IV_VipCardInfoServices;
+ }
+
+ ///
+ /// 获取Vip卡列表
+ ///
+ ///
+ [HttpGet]
+ public async Task>> GetVipCardTypeList()
+ {
+ var result = await v_VipCardTypeServices.GetVipCardTypeList();
+ return new MessageModel>()
+ {
+ success = true,
+ msg = "获取成功",
+ response = result
+ };
+ }
+
+ ///
+ /// 绑定卡
+ ///
+ ///
+ ///
+ [HttpPost]
+ [Authorize]
+ public async Task> BindCardInfo(VipCardQuery query)
+ {
+ return await v_VipCardInfoServices.BindCardInfo(query);
+ }
+
+ ///
+ /// 获取vip信息 传用户Id
+ ///
+ ///
+ ///
+ [HttpGet]
+ [Authorize]
+ public async Task> GetVipInfo([FromQuery] IdQuery query)
+ {
+ return await v_VipCardInfoServices.GetVipInfo(query);
+ }
+ }
+}
diff --git a/New_College.Api/Controllers/Front/VolunteerController.cs b/New_College.Api/Controllers/Front/VolunteerController.cs
new file mode 100644
index 0000000..85c210c
--- /dev/null
+++ b/New_College.Api/Controllers/Front/VolunteerController.cs
@@ -0,0 +1,259 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Mvc;
+using New_College.Model;
+using New_College.Model.ViewModels;
+using New_College.IServices;
+
+namespace New_College.Api.Controllers.Front
+{
+ [Route("api/front/[controller]/[action]")]
+ [ApiController]
+ public class VolunteerController : ControllerBase
+ {
+ private readonly IT_EnrollmentPlanedescServices t_EnrollmentPlanedescServices;
+ private readonly ID_MajorClassServices d_MajorClassServices;
+ public VolunteerController(IT_EnrollmentPlanedescServices IT_EnrollmentPlanedescServices
+ , ID_MajorClassServices ID_MajorClassServices)
+ {
+ t_EnrollmentPlanedescServices = IT_EnrollmentPlanedescServices;
+ d_MajorClassServices = ID_MajorClassServices;
+ }
+ ///
+ /// 专业分类列表(二级) 传Id 1本科 2 专科
+ ///
+ ///
+ ///
+ [HttpGet]
+ public async Task>> GetMajorClassListByType([FromQuery] IdQuery query)
+ {
+ var result = await d_MajorClassServices.GetMajorClassListByType(query);
+ return new MessageModel>()
+ {
+ success = result.Count > 0,
+ msg = result.Count > 0 ? "获取成功" : "获取失败",
+ response = result
+ };
+ }
+
+ ///
+ /// 根据分数获取个性推荐学校
+ ///
+ ///
+ ///
+ [HttpGet]
+ public async Task>> GetRecommendUniversity([FromQuery] RecommendUniversityQuery query)
+ {
+ var result = await t_EnrollmentPlanedescServices.GetRecommendUniversity(query);
+ return new MessageModel>()
+ {
+ response = result,
+ success = true,
+ msg = "获取成功"
+ };
+ }
+
+ ///
+ /// 懒人模式
+ /// 办学性质
+ /// 高校级别
+ /// 专业ids
+ ///
+ ///
+ ///
+ [HttpPost]
+ public async Task>> GetEnrollmentLazyByPage([FromBody] LazyEnrollmentPlaneQuery query)
+ {
+ return await t_EnrollmentPlanedescServices.GetEnrollmentLazyByPage(query);
+ }
+
+ ///
+ /// 根据计划Ids 获取招生计划
+ ///
+ ///
+ ///
+ [HttpPost]
+ public async Task>> GetPlanByUniversity([FromBody] PlanDetailQuery query)
+ {
+ return await t_EnrollmentPlanedescServices.GetPlanByUniversity(query);
+ }
+
+ ///
+ /// 根据年份省份获取批次
+ ///
+ ///
+ [HttpGet]
+ public async Task>> GetBatchByAreaAndYear([FromQuery] BatchQuery query)
+ {
+ return await t_EnrollmentPlanedescServices.GetBatchByAreaAndYear(query);
+ }
+
+ ///
+ /// 冲稳保获取推荐学校专业
+ ///
+ ///
+ ///
+ [HttpPost]
+ public async Task>> GetEnrollmentCWBByPage([FromBody] CWBEnrollmentPlaneQuery query)
+ {
+ return await t_EnrollmentPlanedescServices.GetEnrollmentCWBByPage(query);
+ }
+
+ ///
+ /// 冲稳保详情
+ ///
+ ///
+ ///
+ [HttpPost]
+ public async Task>> GetCWBUniversityDetail([FromBody] CWBUniversityDetailQuery query)
+ {
+ return await t_EnrollmentPlanedescServices.GetCWBUniversityDetail(query);
+ }
+
+ ///
+ /// 霍兰德推荐学校专业
+ ///
+ ///
+ ///
+ [HttpPost]
+ public async Task>> GetEnrollmentTagByPage([FromBody] TagEnrollmentPlaneQuery query)
+ {
+ return await t_EnrollmentPlanedescServices.GetEnrollmentTagByPage(query);
+ }
+
+ ///
+ /// 获取分析结果录取概率 获取之后保存一下
+ ///
+ ///
+ ///
+ [HttpGet]
+ public async Task> GetUniversityProbability([FromQuery] UniversityProbabilityQuery query)
+ {
+ return await t_EnrollmentPlanedescServices.GetUniversityProbability(query);
+ }
+
+ ///
+ /// 获取概率历史记录列表
+ ///
+ ///
+ [HttpGet]
+ public async Task>> GetProbabilityResult([FromQuery] ProbabilityQuery query)
+ {
+ return await t_EnrollmentPlanedescServices.GetProbabilityResult(query);
+ }
+
+ ///
+ /// 保存志愿表
+ ///
+ ///
+ ///
+ [HttpPost]
+ public async Task> SaveVolunteerTable([FromBody] VolunteerTableQuery query)
+ {
+ return await t_EnrollmentPlanedescServices.SaveVolunteerTable(query);
+ }
+
+ ///
+ /// 获取个人志愿列表 传Id
+ ///
+ ///
+ ///
+ [HttpGet]
+ public async Task>> GetVolunteerTableList([FromQuery] IdQuery query)
+ {
+ return await t_EnrollmentPlanedescServices.GetVolunteerTableList(query);
+ }
+
+ ///
+ /// 获取志愿表详情 传Id
+ ///
+ ///
+ ///
+ [HttpGet]
+ public async Task>> GetVolunteerTableDetail([FromQuery] IdQuery query)
+ {
+ return await t_EnrollmentPlanedescServices.GetVolunteerTableDetail(query);
+ }
+
+ ///
+ /// 删除志愿表
+ ///
+ ///
+ ///
+ [HttpPost]
+ public async Task> DeleteVolunteerTable([FromBody] IdQuery query)
+ {
+ return await t_EnrollmentPlanedescServices.DeleteVolunteerTable(query);
+ }
+
+ /////
+ ///// 保存志愿表 霍兰德专用 弃用
+ /////
+ /////
+ /////
+ //[HttpPost]
+ //public async Task> SaveHollandVolunteer([FromBody] HollandVolunteerTableQuery query)
+ //{
+ // return await t_EnrollmentPlanedescServices.SaveHollandVolunteer(query);
+ //}
+
+ ///
+ /// 获取一键生成的志愿表
+ ///
+ ///
+ ///
+ [HttpPost]
+ public async Task>> GetAutoVolunteerTableDetail([FromBody] VolunteerTableQuery query)
+ {
+ return await t_EnrollmentPlanedescServices.GetAutoVolunteerTableDetail(query);
+ }
+
+ ///
+ /// 获取霍兰德一键生成的志愿表
+ ///
+ ///
+ ///
+ [HttpPost]
+ public async Task>> GetHollandVolunteerTableDetail([FromBody] HollandVolunteerTableQuery query)
+ {
+ return await t_EnrollmentPlanedescServices.GetHollandVolunteerTableDetail(query);
+ }
+
+
+ ///
+ /// 获取喜欢的院校
+ ///
+ ///
+ ///
+ [HttpGet]
+ public async Task>> GetLikeSchoolMajor([FromQuery] IdQuery query)
+ {
+ return await t_EnrollmentPlanedescServices.GetLikeSchoolMajor(query);
+ }
+
+ ///
+ /// 专业规划
+ ///
+ ///
+ [HttpGet]
+ public async Task>> GetMajorPlanClaim([FromQuery] CustomerQuery query)
+ {
+ return await t_EnrollmentPlanedescServices.GetMajorPlanClaim(query);
+ }
+
+
+ ///
+ /// 获取批次
+ ///
+ ///
+ ///
+ [HttpPost]
+ public async Task>> GetBatchByYearArea([FromBody] YearAreaQuery query)
+ {
+ return await t_EnrollmentPlanedescServices.GetBatchByYearArea(query);
+ }
+ }
+}
diff --git a/New_College.Api/Controllers/Front/WeixinPayController.cs b/New_College.Api/Controllers/Front/WeixinPayController.cs
new file mode 100644
index 0000000..5a256f0
--- /dev/null
+++ b/New_College.Api/Controllers/Front/WeixinPayController.cs
@@ -0,0 +1,343 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Net.Http;
+using System.Text;
+using System.Threading.Tasks;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.Extensions.Logging;
+using New_College.Common;
+using New_College.IRepository;
+using New_College.IServices;
+using New_College.Model;
+using New_College.Model.Models;
+using New_College.Model.ViewModels;
+
+namespace New_College.Api.Controllers.Front
+{
+ [Route("api/front/[controller]/[action]")]
+ [ApiController]
+ [Authorize]
+ public class WeixinPayController : ControllerBase
+ {
+ private readonly IV_OrderInfoRepository v_OrderInfoRepository;
+ private readonly IV_CustomerInfoRepository v_CustomerInfoRepository;
+ private readonly IV_VipCardInfoRepository v_VipCardInfoRepository;
+ private readonly IV_VipCardTypeRepository v_VipCardTypeRepository;
+
+ private readonly ILogger logger;
+ public WeixinPayController(IV_OrderInfoRepository IV_OrderInfoRepository
+ , IV_CustomerInfoRepository IV_CustomerInfoRepository
+ , IV_VipCardInfoRepository IV_VipCardInfoRepository
+ , IV_VipCardTypeRepository IV_VipCardTypeRepository
+ , ILogger loggers)
+ {
+ v_OrderInfoRepository = IV_OrderInfoRepository;
+ v_CustomerInfoRepository = IV_CustomerInfoRepository;
+ v_VipCardInfoRepository = IV_VipCardInfoRepository;
+ v_VipCardTypeRepository = IV_VipCardTypeRepository;
+ logger = loggers;
+ }
+
+ ///
+ /// 下订单
+ ///
+ ///
+ [HttpPost]
+ public async Task UnifiedOrder(UnifiedOrderQuery query)
+ {
+ var resp = new WeixinPayResult();
+ try
+ {
+ Random rd = new Random();
+ //HttpContext.GetClientUserIp();
+ //外部商户订单号
+ var payNum = DateTime.Now.ToString("yyyyMMddHHmmss") + rd.Next(0, 1000).ToString().PadLeft(3, '0');
+ var data = new WxPayData();
+ data.SetValue("body", "壹志愿好帮手VIP购买");
+ data.SetValue("out_trade_no", payNum);
+ data.SetValue("detail", "志愿好帮手VIP卡购买");
+ data.SetValue("total_fee", Convert.ToInt32(query.total_fee * 100));
+ data.SetValue("time_start", DateTime.Now.ToString("yyyyMMddHHmmss"));
+ //data.SetValue("time_expire", DateTime.Now.AddMinutes(10).ToString("yyyyMMddHHmmss"));
+ data.SetValue("notify_url", WeixinConfig.NotifyUrl);
+ //data.SetValue("goods_tag", "test");
+ data.SetValue("trade_type", "JSAPI");
+ data.SetValue("openid", query.Phone);
+ //可以将用户Id和订单Id同时封装在attach中
+ data.SetValue("attach", string.Format("{0}|{1}", query.Phone, payNum));
+ WxPayData result = UnifiedOrder(data);
+ if (!result.IsSet("appid") || !result.IsSet("prepay_id") || result.GetValue("prepay_id").ToString() == "")
+ {
+ resp.err_code_des = result.GetValue("err_code_des").ToString();
+ resp.err_code = result.GetValue("err_code").ToString();
+ resp.result_code = result.GetValue("result_code").ToString();
+ return resp;
+ }
+ else
+ {
+ resp.nonce_str = result.GetValue("nonce_str").ToString();
+ resp.appid = result.GetValue("appid").ToString();
+ resp.mchi_id = result.GetValue("mch_id").ToString();
+ resp.result_code = result.GetValue("result_code").ToString();
+ resp.prepay_id = "prepay_id=" + result.GetValue("prepay_id").ToString();
+ //resp.code_url = result.GetValue("code_url").ToString();
+ resp.trade_type = result.GetValue("trade_type").ToString();
+ var signType = "MD5";
+ var timeStamp = ((DateTime.Now.Ticks - TimeZone.CurrentTimeZone.ToLocalTime(new DateTime(1970, 1, 1)).Ticks) / 10000).ToString();
+ WxPayData applet = new WxPayData();
+ applet.SetValue("appId", resp.appid);
+ applet.SetValue("nonceStr", resp.nonce_str);
+ applet.SetValue("package", resp.prepay_id);
+ applet.SetValue("signType", signType);
+ applet.SetValue("timeStamp", timeStamp);
+ resp.sign = applet.MakeSign();
+ resp.timeStamp = timeStamp;
+ //NLogHelper.WriteInfo("Signurl" + Newtonsoft.Json.JsonConvert.SerializeObject(resp), DevAuthorNameEnum.Michael, false);
+ // WebHookHelper.WebHookmarkdownSend("Signurl" + Newtonsoft.Json.JsonConvert.SerializeObject(resp));
+ var customer = await v_CustomerInfoRepository.Query(x => x.OpenId == query.Phone && x.IsDelete == false);
+ if (customer.Count <= 0)
+ return new WeixinPayResult() { err_code_des = "用户出现错误" };
+ //添加一张卡
+ var cardtype = await v_VipCardTypeRepository.QueryById(query.CardTypeId);
+ if (cardtype == null)
+ return new WeixinPayResult() { err_code_des = "卡出现错误" };
+ var code = RadomHelper.GetGuid();
+ var addcard = await v_VipCardInfoRepository.Add(new V_VipCardInfo()
+ {
+ CardTypeId = query.CardTypeId,
+ CardTypeName = cardtype.Name,
+ Code = code,
+ IsBind = 1,
+ Money = query.total_fee,
+ Day = cardtype.Day,
+ EndTime = DateTime.Now.AddDays(cardtype.Day)
+ });
+ var baseResult = await v_OrderInfoRepository.Add(new V_OrderInfo
+ {
+ out_trade_no = payNum,
+ // PayType = 2,
+ CardTypeId = query.CardTypeId,
+ // Status = 1,
+ CustomerId = customer.FirstOrDefault().Id,
+ Price = query.total_fee,
+ PayPrice = query.total_fee,
+ Name = "壹志愿好帮手VIP购买",
+ CardNo = code,
+ CardId = addcard
+ });
+ if (baseResult > 0)
+ {
+ //订单号
+ applet.SetValue("orderid", baseResult);
+ resp.orderid = baseResult.ToString();
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ //WebHookHelper.WebHookmarkdownSend(ex.ToString());
+
+ //NLogHelper.WriteError(ex, DevAuthorNameEnum.Michael, false);
+ }
+ return resp;
+ }
+
+
+ ///
+ /// 支付返回值
+ ///
+ ///
+ [HttpPost]
+ public async Task PayNotify()
+ {
+ logger.LogInformation("开始回调PayNotify");
+
+ WxPayData res = new WxPayData();
+
+ //接收从微信后台POST过来的数据
+ //转换数据格式并验证签名
+ WxPayData data = new WxPayData();
+ using (var reader = new StreamReader(Request.Body))
+ {
+ var builder = reader.ReadToEnd();
+ //WebHookHelper.WebHookmarkdownSend(builder.ToString());
+ try
+ {
+ data.FromXml(builder.ToString());
+ }
+ catch (Exception ex)
+ {
+ //若签名错误,则立即返回结果给微信支付后台
+
+ res.SetValue("return_code", "FAIL");
+ res.SetValue("return_msg", ex.Message);
+ // NLogHelper.WriteError("Sign check error : " + res.ToXml(), DevAuthorNameEnum.Michael, false);
+ //WebHookHelper.WebHookmarkdownSend(string.Format("return_msg:{0}", ex.Message));
+ return Content(res.ToXml(), "text/xml");
+ }
+
+ };
+ // WebHookHelper.WebHookmarkdownSend("Check sign success");
+ //检查支付结果中transaction_id是否存在
+ if (!data.IsSet("transaction_id"))
+ {
+ //若transaction_id不存在,则立即返回结果给微信支付后台
+ res.SetValue("return_code", "FAIL");
+ res.SetValue("return_msg", "支付结果中微信订单号不存在");
+ //WebHookHelper.WebHookmarkdownSend("支付结果中微信订单号不存在");
+ return Content(res.ToXml(), "text/xml");
+ }
+ // 执行订单状态操作
+ string out_trade_no = data.GetValue("out_trade_no").ToString();
+ logger.LogInformation("开始回调PayNotify"+ out_trade_no);
+ var info = await v_OrderInfoRepository.Query(x => x.out_trade_no == out_trade_no);
+ if (info.Count <= 0)
+ {
+ res.SetValue("return_code", "FAIL");
+ res.SetValue("return_msg", "在自有平台未找到该订单号");
+ //WebHookHelper.WebHookmarkdownSend("支付结果中微信订单号不存在");
+ return Content(res.ToXml(), "text/xml");
+ }
+ var oneinfo = info.FirstOrDefault();
+ oneinfo.Status = EnumOrderType.payoff;
+ var rep = await v_OrderInfoRepository.Update(oneinfo);
+ if (rep)
+ {
+ //修改用户信息 修改为VIp
+ var customerinfo = await v_CustomerInfoRepository.QueryById(oneinfo.CustomerId);
+ customerinfo.IsVIP = true;
+ customerinfo.VipCode = oneinfo.CardNo;
+ await v_CustomerInfoRepository.Update(customerinfo);
+ //支付成功后根据用户code找到对应用户修改vip 状态
+ res.SetValue("return_code", "SUCCESS");
+ res.SetValue("return_msg", "OK");
+ }
+ else
+ {
+ // string attach = data.GetValue("attach").ToString();
+ // WebHookHelper.WebHookmarkdownSend(attach);
+ res.SetValue("return_code", "FAIL");
+ res.SetValue("return_msg", "在自有平台未找到该订单号");
+ }
+
+ return Content(res.ToXml(), "text/xml");
+ }
+
+
+ /**
+ *
+ * 统一下单
+ * @param WxPaydata inputObj 提交给统一下单API的参数
+ * @param int timeOut 超时时间
+ * @throws WePayException
+ * @return 成功时返回,其他抛异常
+ */
+ public static WxPayData UnifiedOrder(WxPayData inputObj, int timeOut = 60)
+ {
+ string url = "https://api.mch.weixin.qq.com/pay/unifiedorder";
+ //检测必填参数
+ if (!inputObj.IsSet("out_trade_no"))
+ {
+ throw new Exception("缺少统一支付接口必填参数out_trade_no!");
+ }
+ else if (!inputObj.IsSet("body"))
+ {
+ throw new Exception("缺少统一支付接口必填参数body!");
+ }
+ else if (!inputObj.IsSet("total_fee"))
+ {
+ throw new Exception("缺少统一支付接口必填参数total_fee!");
+ }
+ else if (!inputObj.IsSet("trade_type"))
+ {
+ throw new Exception("缺少统一支付接口必填参数trade_type!");
+ }
+
+ //关联参数
+ if (inputObj.GetValue("trade_type").ToString() == "JSAPI" && !inputObj.IsSet("openid"))
+ {
+ throw new Exception("统一支付接口中,缺少必填参数openid!trade_type为JSAPI时,openid为必填参数!");
+ }
+ if (inputObj.GetValue("trade_type").ToString() == "NATIVE" && !inputObj.IsSet("product_id"))
+ {
+ throw new Exception("统一支付接口中,缺少必填参数product_id!trade_type为JSAPI时,product_id为必填参数!");
+ }
+
+ //异步通知url未设置,则使用配置文件中的url
+ if (!inputObj.IsSet("notify_url"))
+ {
+ inputObj.SetValue("notify_url", WeixinConfig.NotifyUrl);//异步通知url
+ }
+
+ inputObj.SetValue("appid", WeixinConfig.Appid);//公众账号ID
+ inputObj.SetValue("mch_id", WeixinConfig.MCHID);//商户号
+ inputObj.SetValue("spbill_create_ip", WePayConfig.IP);//终端ip
+ inputObj.SetValue("nonce_str", GenerateNonceStr());//随机字符串
+
+ //签名
+ inputObj.SetValue("sign", inputObj.MakeSign());
+ string xml = inputObj.ToXml();
+
+ var start = DateTime.Now;
+
+ // Log.Info("XcxPayApi", "UnfiedOrder request : " + xml);
+ string response = HttpPost(xml, url, "application/xml", timeOut);
+ //Log.Info("XcxPayApi", "UnfiedOrder response : " + response);
+ // WebHookHelper.WebHookmarkdownSend(response);
+
+ var end = DateTime.Now;
+ int timeCost = (int)((end - start).TotalMilliseconds);
+
+ WxPayData result = new WxPayData();
+ result.FromXml(response);
+ // ReportCostTime(url, timeCost, result);//测速上报网络不好时使用
+ return result;
+ }
+ ///
+ /// 生成随机数
+ ///
+ ///
+ public static string GenerateNonceStr()
+ {
+ return Guid.NewGuid().ToString().Replace("-", "");
+ }
+ ///
+ /// POST请求
+ ///
+ ///
+ ///
+ /// application/xml、application/json、application/text、application/x-www-form-urlencoded
+ ///
+ ///
+ ///
+ public static string HttpPost(string postData, string url, string contentType = null, int timeOut = 30, Dictionary headers = null)
+ {
+ postData = postData ?? "";
+
+ var httpClientHandler = new HttpClientHandler
+ {
+ ServerCertificateCustomValidationCallback = (message, certificate2, arg3, arg4) => true
+ };
+ using (HttpClient httpClient = new HttpClient(httpClientHandler))
+ {
+ if (headers != null)
+ {
+ foreach (var header in headers)
+ httpClient.DefaultRequestHeaders.Add(header.Key, header.Value);
+ }
+ using (HttpContent client = new StringContent(postData, Encoding.UTF8))
+ {
+ if (contentType != null)
+ client.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue(contentType);
+
+ HttpResponseMessage response = httpClient.PostAsync(url, client).Result;
+ return response.Content.ReadAsStringAsync().Result;
+ }
+ }
+ }
+ }
+}
diff --git a/New_College.Api/Controllers/HealthCheckController.cs b/New_College.Api/Controllers/HealthCheckController.cs
new file mode 100644
index 0000000..8d4fc3a
--- /dev/null
+++ b/New_College.Api/Controllers/HealthCheckController.cs
@@ -0,0 +1,22 @@
+using Microsoft.AspNetCore.Mvc;
+
+namespace New_College.Controllers
+{
+ ///
+ /// 健康检查
+ ///
+ [Route("[controller]")]
+ [ApiController]
+ public class HealthCheckController : ControllerBase
+ {
+ ///
+ /// 健康检查接口
+ ///
+ ///
+ [HttpGet]
+ public IActionResult Get()
+ {
+ return Ok();
+ }
+ }
+}
\ No newline at end of file
diff --git a/New_College.Api/Controllers/ImgController.cs b/New_College.Api/Controllers/ImgController.cs
new file mode 100644
index 0000000..54ace19
--- /dev/null
+++ b/New_College.Api/Controllers/ImgController.cs
@@ -0,0 +1,194 @@
+using System;
+using System.IO;
+using System.Linq;
+using System.Threading.Tasks;
+using New_College.Model;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Hosting;
+using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Mvc;
+using New_College.Common;
+
+namespace New_College.Controllers
+{
+ ///
+ /// 图片管理
+ ///
+ [Route("api/[controller]")]
+ [ApiController]
+
+ public class ImgController : Controller
+ {
+ // GET: api/Download
+ ///
+ /// 下载图片(支持中文字符)
+ ///
+ ///
+ ///
+ [HttpGet]
+ [Authorize]
+ [Route("/images/Down/Pic")]
+ public FileStreamResult DownImg([FromServices]IWebHostEnvironment environment)
+ {
+ string foldername = "";
+ string filepath = Path.Combine(environment.WebRootPath, foldername, "测试下载中文名称的图片.png");
+ var stream = System.IO.File.OpenRead(filepath);
+ string fileExt = ".jpg"; // 这里可以写一个获取文件扩展名的方法,获取扩展名
+ //获取文件的ContentType
+ var provider = new Microsoft.AspNetCore.StaticFiles.FileExtensionContentTypeProvider();
+ var memi = provider.Mappings[fileExt];
+ var fileName = Path.GetFileName(filepath);
+
+
+ return File(stream, memi, fileName);
+ }
+
+ ///
+ /// 上传图片,多文件,可以使用 postman 测试,
+ /// 如果是单文件,可以 参数写 IFormFile file1
+ ///
+ ///
+ ///
+ [HttpPost]
+ [Authorize]
+ [Route("/images/Upload/Pic")]
+ public async Task> InsertPicture([FromServices]IWebHostEnvironment environment)
+ {
+ var data = new MessageModel();
+ string path = string.Empty;
+ string foldername = "images";
+ IFormFileCollection files = null;
+
+ try
+ {
+ files = Request.Form.Files;
+ }
+ catch (Exception)
+ {
+ files = null;
+ }
+
+ if (files == null || !files.Any()) { data.msg = "请选择上传的文件。"; return data; }
+ //格式限制
+ var allowType = new string[] { "image/jpg", "image/png", "image/jpeg" };
+
+ string folderpath = Path.Combine(environment.WebRootPath, foldername);
+ if (!Directory.Exists(folderpath))
+ {
+ Directory.CreateDirectory(folderpath);
+ }
+
+ if (files.Any(c => allowType.Contains(c.ContentType)))
+ {
+ if (files.Sum(c => c.Length) <= 1024 * 1024 * 4)
+ {
+ //foreach (var file in files)
+ var file = files.FirstOrDefault();
+ string strpath = Path.Combine(foldername, DateTime.Now.ToString("MMddHHmmss") + file.FileName);
+ path = Path.Combine(environment.WebRootPath, strpath);
+
+ using (var stream = new FileStream(path, FileMode.OpenOrCreate, FileAccess.ReadWrite))
+ {
+ await file.CopyToAsync(stream);
+ }
+
+ data = new MessageModel()
+ {
+ response = strpath,
+ msg = "上传成功",
+ success = true,
+ };
+ return data;
+ }
+ else
+ {
+ data.msg = "图片过大";
+ return data;
+ }
+ }
+ else
+
+ {
+ data.msg = "图片格式错误";
+ return data;
+ }
+ }
+
+
+ // POST: api/Img
+ [HttpPost]
+ public void Post([FromBody] object formdata)
+ {
+ }
+
+ // PUT: api/Img/5
+ [HttpPut("{id}")]
+ public void Put(int id, [FromBody] string value)
+ {
+ }
+
+ // DELETE: api/ApiWithActions/5
+ [HttpDelete("{id}")]
+ public void Delete(int id)
+ {
+ }
+
+
+ ///
+ /// 上传图片
+ ///
+ ///
+ ///
+ [HttpPost("UploadImg")]
+ public async Task> UploadImg([FromServices] IWebHostEnvironment environment)
+ {
+ var data = new MessageModel();
+ var file = Request.Form.Files.First();
+ if (file == null) { data.msg = "请选择上传的文件。"; return data; }
+ var path = environment.WebRootPath;
+ string urlPath = $"/Content/Upload/";
+ string DirectoryName = Path.GetDirectoryName(path + urlPath);
+ if (!Directory.Exists(DirectoryName))
+ Directory.CreateDirectory(DirectoryName);
+ var reportImage = "";
+ if (file.Length > 0)
+ {
+ var fileName = DateTime.Now.ToString("yyyyMMddHHssfff") +
+ Path.GetExtension(file.FileName);
+ using (var stream = new FileStream(path + urlPath + fileName, FileMode.OpenOrCreate, FileAccess.ReadWrite))
+ {
+ await file.CopyToAsync(stream);
+ }
+ var newimg = path + urlPath + fileName;
+ var picfullname = string.Format("{0}{1}", DateTime.Now.ToString("yyyyMMddHHssfff"), ".JPEG");
+ reportImage = AliYunOssHelper.UploadFile(picfullname, newimg);
+ if (string.IsNullOrWhiteSpace(reportImage))
+ {
+ return new MessageModel()
+ {
+ response = reportImage,
+ msg = "上传失败",
+ success = false,
+ };
+ }
+ data = new MessageModel()
+ {
+ response = reportImage,
+ msg = "上传成功",
+ success = true,
+ };
+ if (System.IO.File.Exists(path + urlPath + fileName))//判断文件是否存在bai
+ {
+ System.IO.File.Delete(path + urlPath + fileName);
+ }
+ return data;
+ }
+ else
+ {
+
+ }
+ return data;
+ }
+ }
+
+}
diff --git a/New_College.Api/Controllers/LoginController.cs b/New_College.Api/Controllers/LoginController.cs
new file mode 100644
index 0000000..de3bc1f
--- /dev/null
+++ b/New_College.Api/Controllers/LoginController.cs
@@ -0,0 +1,299 @@
+using System;
+using System.Collections.Generic;
+using System.IdentityModel.Tokens.Jwt;
+using System.Linq;
+using System.Security.Claims;
+using System.Threading.Tasks;
+using New_College.AuthHelper;
+using New_College.AuthHelper.OverWrite;
+using New_College.Common.Helper;
+using New_College.IServices;
+using New_College.Model;
+using New_College.Model.ViewModels;
+using Microsoft.AspNetCore.Authentication.JwtBearer;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Mvc;
+
+namespace New_College.Controllers
+{
+ ///
+ /// 登录管理【无权限】
+ ///
+ [Produces("application/json")]
+ [Route("api/Login")]
+ [AllowAnonymous]
+ public class LoginController : Controller
+ {
+ readonly ISysUserInfoServices _sysUserInfoServices;
+ readonly IUserRoleServices _userRoleServices;
+ readonly IRoleServices _roleServices;
+ readonly PermissionRequirement _requirement;
+ private readonly IRoleModulePermissionServices _roleModulePermissionServices;
+
+
+ ///
+ /// 构造函数注入
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public LoginController(ISysUserInfoServices sysUserInfoServices, IUserRoleServices userRoleServices, IRoleServices roleServices, PermissionRequirement requirement, IRoleModulePermissionServices roleModulePermissionServices)
+ {
+ this._sysUserInfoServices = sysUserInfoServices;
+ this._userRoleServices = userRoleServices;
+ this._roleServices = roleServices;
+ _requirement = requirement;
+ _roleModulePermissionServices = roleModulePermissionServices;
+ }
+
+
+ #region 获取token的第1种方法
+ ///
+ /// 获取JWT的方法1
+ ///
+ ///
+ ///
+ ///
+ [HttpGet]
+ [Route("Token")]
+ public async Task> GetJwtStr(string name, string pass)
+ {
+ string jwtStr = string.Empty;
+ bool suc = false;
+ //这里就是用户登陆以后,通过数据库去调取数据,分配权限的操作
+
+ var user = await _sysUserInfoServices.GetUserRoleNameStr(name, MD5Helper.MD5Encrypt32(pass));
+ if (user != null)
+ {
+
+ TokenModelJwt tokenModel = new TokenModelJwt { Uid = 1, Role = user };
+
+ jwtStr = JwtHelper.IssueJwt(tokenModel);
+ suc = true;
+ }
+ else
+ {
+ jwtStr = "login fail!!!";
+ }
+
+ return new MessageModel()
+ {
+ success = suc,
+ msg = suc ? "获取成功" : "获取失败",
+ response = jwtStr
+ };
+ }
+
+
+ ///
+ /// 获取JWT的方法2:给Nuxt提供
+ ///
+ ///
+ ///
+ ///
+ [HttpGet]
+ [Route("GetTokenNuxt")]
+ public MessageModel GetJwtStrForNuxt(string name, string pass)
+ {
+ string jwtStr = string.Empty;
+ bool suc = false;
+ //这里就是用户登陆以后,通过数据库去调取数据,分配权限的操作
+ //这里直接写死了
+ if (name == "admins" && pass == "admins")
+ {
+ TokenModelJwt tokenModel = new TokenModelJwt
+ {
+ Uid = 1,
+ Role = "Admin"
+ };
+
+ jwtStr = JwtHelper.IssueJwt(tokenModel);
+ suc = true;
+ }
+ else
+ {
+ jwtStr = "login fail!!!";
+ }
+ var result = new
+ {
+ data = new { success = suc, token = jwtStr }
+ };
+
+ return new MessageModel()
+ {
+ success = suc,
+ msg = suc ? "获取成功" : "获取失败",
+ response = jwtStr
+ };
+ }
+ #endregion
+
+
+
+ ///
+ /// 获取JWT的方法3:整个系统主要方法
+ ///
+ ///
+ ///
+ ///
+ [HttpGet]
+ [Route("JWTToken3.0")]
+ public async Task> GetJwtToken3(string name = "", string pass = "")
+ {
+ string jwtStr = string.Empty;
+
+ if (string.IsNullOrEmpty(name) || string.IsNullOrEmpty(pass))
+ {
+ return new MessageModel()
+ {
+ success = false,
+ msg = "用户名或密码不能为空",
+ };
+ }
+
+ pass = MD5Helper.MD5Encrypt32(pass);
+
+ var user = await _sysUserInfoServices.Query(d => d.uLoginName == name && d.uLoginPWD == pass && d.tdIsDelete == false);
+ if (user.Count > 0)
+ {
+ var userRoles = await _sysUserInfoServices.GetUserRoleNameStr(name, pass);
+ //如果是基于用户的授权策略,这里要添加用户;如果是基于角色的授权策略,这里要添加角色
+ var claims = new List {
+ new Claim(ClaimTypes.Name, name),
+ new Claim(JwtRegisteredClaimNames.Jti, user.FirstOrDefault().uID.ToString()),
+ new Claim(ClaimTypes.Expiration, DateTime.Now.AddSeconds(_requirement.Expiration.TotalSeconds).ToString()) };
+ claims.AddRange(userRoles.Split(',').Select(s => new Claim(ClaimTypes.Role, s)));
+
+
+ // ids4和jwt切换
+ // jwt
+ if (!Permissions.IsUseIds4)
+ {
+ var data = await _roleModulePermissionServices.RoleModuleMaps();
+ var list = (from item in data
+ where item.IsDeleted == false
+ orderby item.Id
+ select new PermissionItem
+ {
+ Url = item.Module?.LinkUrl,
+ Role = item.Role?.Name.ObjToString(),
+ }).ToList();
+
+ _requirement.Permissions = list;
+ }
+
+ var token = JwtToken.BuildJwtToken(claims.ToArray(), _requirement);
+ return new MessageModel()
+ {
+ success = true,
+ msg = "获取成功",
+ response = token
+ };
+ }
+ else
+ {
+ return new MessageModel()
+ {
+ success = false,
+ msg = "认证失败",
+ };
+ }
+ }
+
+ ///
+ /// 请求刷新Token(以旧换新)
+ ///
+ ///
+ ///
+ [HttpGet]
+ [Route("RefreshToken")]
+ public async Task> RefreshToken(string token = "")
+ {
+ string jwtStr = string.Empty;
+
+ if (string.IsNullOrEmpty(token))
+ {
+ return new MessageModel()
+ {
+ success = false,
+ msg = "token无效,请重新登录!",
+ };
+ }
+ var tokenModel = JwtHelper.SerializeJwt(token);
+ if (tokenModel != null && tokenModel.Uid > 0)
+ {
+ var user = await _sysUserInfoServices.QueryById(tokenModel.Uid);
+ if (user != null)
+ {
+ var userRoles = await _sysUserInfoServices.GetUserRoleNameStr(user.uLoginName, user.uLoginPWD);
+ //如果是基于用户的授权策略,这里要添加用户;如果是基于角色的授权策略,这里要添加角色
+ var claims = new List {
+ new Claim(ClaimTypes.Name, user.uLoginName),
+ new Claim(JwtRegisteredClaimNames.Jti, tokenModel.Uid.ObjToString()),
+ new Claim(ClaimTypes.Expiration, DateTime.Now.AddSeconds(_requirement.Expiration.TotalSeconds).ToString()) };
+ claims.AddRange(userRoles.Split(',').Select(s => new Claim(ClaimTypes.Role, s)));
+
+ //用户标识
+ var identity = new ClaimsIdentity(JwtBearerDefaults.AuthenticationScheme);
+ identity.AddClaims(claims);
+
+ var refreshToken = JwtToken.BuildJwtToken(claims.ToArray(), _requirement);
+ return new MessageModel()
+ {
+ success = true,
+ msg = "获取成功",
+ response = refreshToken
+ };
+ }
+ }
+
+ return new MessageModel()
+ {
+ success = false,
+ msg = "认证失败!",
+ };
+ }
+
+ ///
+ /// 获取JWT的方法4:给 JSONP 测试
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ [HttpGet]
+ [Route("jsonp")]
+ public void Getjsonp(string callBack, long id = 1, string sub = "Admin", int expiresSliding = 30, int expiresAbsoulute = 30)
+ {
+ TokenModelJwt tokenModel = new TokenModelJwt
+ {
+ Uid = id,
+ Role = sub
+ };
+
+ string jwtStr = JwtHelper.IssueJwt(tokenModel);
+
+ string response = string.Format("\"value\":\"{0}\"", jwtStr);
+ string call = callBack + "({" + response + "})";
+ Response.WriteAsync(call);
+ }
+
+
+ ///
+ /// 测试 MD5 加密字符串
+ ///
+ ///
+ ///
+ [HttpGet]
+ [Route("Md5Password")]
+ public string Md5Password(string password = "")
+ {
+ return MD5Helper.MD5Encrypt32(password);
+ }
+ }
+}
\ No newline at end of file
diff --git a/New_College.Api/Controllers/ModuleController.cs b/New_College.Api/Controllers/ModuleController.cs
new file mode 100644
index 0000000..80c9310
--- /dev/null
+++ b/New_College.Api/Controllers/ModuleController.cs
@@ -0,0 +1,140 @@
+using System;
+using System.Linq.Expressions;
+using System.Threading.Tasks;
+using New_College.Common.HttpContextUser;
+using New_College.IServices;
+using New_College.Model;
+using New_College.Model.Models;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Mvc;
+
+namespace New_College.Controllers
+{
+ ///
+ /// 接口管理
+ ///
+ [Route("api/[controller]/[action]")]
+ [ApiController]
+ [Authorize(Permissions.Name)]
+ public class ModuleController : ControllerBase
+ {
+ readonly IModuleServices _moduleServices;
+ readonly IUser _user;
+
+
+ public ModuleController(IModuleServices moduleServices, IUser user)
+ {
+ _moduleServices = moduleServices;
+ _user = user;
+ }
+
+ ///
+ /// 获取全部接口api
+ ///
+ ///
+ ///
+ ///
+ // GET: api/User
+ [HttpGet]
+ public async Task>> Get(int page = 1, string key = "")
+ {
+ if (string.IsNullOrEmpty(key) || string.IsNullOrWhiteSpace(key))
+ {
+ key = "";
+ }
+ int intPageSize = 50;
+
+ Expression> whereExpression = a => a.IsDeleted != true && (a.Name != null && a.Name.Contains(key));
+
+ var data = await _moduleServices.QueryPage(whereExpression, page, intPageSize, " Id desc ");
+
+ return new MessageModel>()
+ {
+ msg = "获取成功",
+ success = data.dataCount >= 0,
+ response = data
+ };
+
+ }
+
+ // GET: api/User/5
+ [HttpGet("{id}")]
+ public string Get(string id)
+ {
+ return "value";
+ }
+
+ ///
+ /// 添加一条接口信息
+ ///
+ ///
+ ///
+ // POST: api/User
+ [HttpPost]
+ public async Task> Post([FromBody] Modules module)
+ {
+ var data = new MessageModel();
+
+ module.CreateId = _user.ID;
+ module.CreateBy = _user.Name;
+
+ var id = (await _moduleServices.Add(module));
+ data.success = id > 0;
+ if (data.success)
+ {
+ data.response = id.ObjToString();
+ data.msg = "添加成功";
+ }
+
+ return data;
+ }
+
+ ///
+ /// 更新接口信息
+ ///
+ ///
+ ///
+ // PUT: api/User/5
+ [HttpPut]
+ public async Task> Put([FromBody] Modules module)
+ {
+ var data = new MessageModel();
+ if (module != null && module.Id > 0)
+ {
+ data.success = await _moduleServices.Update(module);
+ if (data.success)
+ {
+ data.msg = "更新成功";
+ data.response = module?.Id.ObjToString();
+ }
+ }
+
+ return data;
+ }
+
+ ///
+ /// 删除一条接口
+ ///
+ ///
+ ///
+ // DELETE: api/ApiWithActions/5
+ [HttpDelete]
+ public async Task> Delete(int id)
+ {
+ var data = new MessageModel();
+ if (id > 0)
+ {
+ var userDetail = await _moduleServices.QueryById(id);
+ userDetail.IsDeleted = true;
+ data.success = await _moduleServices.Update(userDetail);
+ if (data.success)
+ {
+ data.msg = "删除成功";
+ data.response = userDetail?.Id.ObjToString();
+ }
+ }
+
+ return data;
+ }
+ }
+}
diff --git a/New_College.Api/Controllers/MonitorController.cs b/New_College.Api/Controllers/MonitorController.cs
new file mode 100644
index 0000000..dae182a
--- /dev/null
+++ b/New_College.Api/Controllers/MonitorController.cs
@@ -0,0 +1,132 @@
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.IO;
+using System.Linq;
+using System.Runtime.InteropServices;
+using System.Text;
+using New_College.Common.Helper;
+using New_College.Common.LogHelper;
+using New_College.Hubs;
+using New_College.Middlewares;
+using New_College.Model;
+using New_College.Model.ViewModels;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Hosting;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.AspNetCore.SignalR;
+using Newtonsoft.Json;
+
+namespace New_College.Controllers
+{
+ [Route("api/[Controller]/[action]")]
+ [ApiController]
+ [AllowAnonymous]
+ public class MonitorController : Controller
+ {
+ private readonly IHubContext _hubContext;
+ private readonly IWebHostEnvironment _env;
+
+ public MonitorController(IHubContext hubContext, IWebHostEnvironment env)
+ {
+ _hubContext = hubContext;
+ _env = env;
+ }
+
+ ///
+ /// 服务器配置信息
+ ///
+ ///
+ [HttpGet]
+ public MessageModel Server()
+ {
+ return new MessageModel()
+ {
+ msg = "获取成功",
+ success = true,
+ response = new ServerViewModel()
+ {
+ EnvironmentName = _env.EnvironmentName,
+ OSArchitecture = RuntimeInformation.OSArchitecture.ObjToString(),
+ ContentRootPath = _env.ContentRootPath,
+ WebRootPath = _env.WebRootPath,
+ FrameworkDescription = RuntimeInformation.FrameworkDescription,
+ MemoryFootprint = (Process.GetCurrentProcess().WorkingSet64 / 1048576).ToString("N2") + " MB",
+ WorkingTime = DateHelper.TimeSubTract(DateTime.Now, Process.GetCurrentProcess().StartTime)
+ }
+ };
+ }
+
+
+ ///
+ /// SignalR send data
+ ///
+ ///
+ // GET: api/Logs
+ [HttpGet]
+ public MessageModel> Get()
+ {
+
+ _hubContext.Clients.All.SendAsync("ReceiveUpdate", LogLock.GetLogData()).Wait();
+
+ return new MessageModel>()
+ {
+ msg = "获取成功",
+ success = true,
+ response = null
+ };
+ }
+
+
+
+ [HttpGet]
+ public MessageModel GetRequestApiinfoByWeek()
+ {
+ return new MessageModel()
+ {
+ msg = "获取成功",
+ success = true,
+ response = LogLock.RequestApiinfoByWeek()
+ };
+ }
+
+ [HttpGet]
+ public MessageModel GetAccessApiByDate()
+ {
+ return new MessageModel